]> git.saurik.com Git - apple/javascriptcore.git/commitdiff
JavaScriptCore-7601.1.46.3.tar.gz master ios-90 v7601.1.46.3
authorApple <opensource@apple.com>
Wed, 5 Aug 2015 00:41:38 +0000 (00:41 +0000)
committerApple <opensource@apple.com>
Wed, 5 Aug 2015 00:41:38 +0000 (00:41 +0000)
1847 files changed:
API/JSAPIWrapperObject.h
API/JSAPIWrapperObject.mm
API/JSBase.cpp
API/JSBase.h
API/JSCallbackConstructor.cpp
API/JSCallbackConstructor.h
API/JSCallbackFunction.cpp
API/JSCallbackObject.cpp
API/JSCallbackObject.h
API/JSCallbackObjectFunctions.h
API/JSClassRef.cpp
API/JSClassRef.h
API/JSContext.h
API/JSContext.mm
API/JSContextRef.cpp
API/JSContextRef.h
API/JSContextRefInspectorSupport.h [new file with mode: 0644]
API/JSManagedValue.h
API/JSManagedValue.mm
API/JSObjectRef.cpp
API/JSProfilerPrivate.cpp
API/JSRemoteInspector.cpp [new file with mode: 0644]
API/JSRemoteInspector.h [new file with mode: 0644]
API/JSRetainPtr.h
API/JSScriptRef.cpp
API/JSStringRef.cpp
API/JSStringRefCF.cpp
API/JSValue.h
API/JSValue.mm
API/JSValueRef.cpp
API/JSValueRef.h
API/JSVirtualMachine.h
API/JSVirtualMachine.mm
API/JSVirtualMachineInternal.h
API/JSWeakObjectMapRefInternal.h
API/JSWeakObjectMapRefPrivate.cpp
API/JSWrapperMap.mm
API/ObjCCallbackFunction.h
API/ObjCCallbackFunction.mm
API/ObjcRuntimeExtras.h
API/OpaqueJSString.cpp
API/OpaqueJSString.h
API/WebKitAvailability.h
API/tests/CompareAndSwapTest.cpp [new file with mode: 0644]
API/tests/CompareAndSwapTest.h [new file with mode: 0644]
API/tests/DateTests.mm
API/tests/ExecutionTimeLimitTest.cpp [new file with mode: 0644]
API/tests/ExecutionTimeLimitTest.h [new file with mode: 0644]
API/tests/GlobalContextWithFinalizerTest.cpp [new file with mode: 0644]
API/tests/GlobalContextWithFinalizerTest.h [new file with mode: 0644]
API/tests/Regress141275.h [new file with mode: 0644]
API/tests/Regress141275.mm [new file with mode: 0644]
API/tests/testapi.c
API/tests/testapi.js
API/tests/testapi.mm
CMakeLists.txt
ChangeLog
ChangeLog-2014-10-07 [new file with mode: 0644]
ChangeLog-2015-07-23 [new file with mode: 0644]
Configurations/Base.xcconfig
Configurations/CompileRuntimeToLLVMIR.xcconfig
Configurations/DebugRelease.xcconfig
Configurations/FeatureDefines.xcconfig
Configurations/JSC.xcconfig
Configurations/JavaScriptCore.xcconfig
Configurations/LLVMForJSC.xcconfig
Configurations/ToolExecutable.xcconfig
Configurations/Version.xcconfig
Configurations/iOS.xcconfig [deleted file]
DerivedSources.make
Info.plist
JavaScriptCore.order
JavaScriptCore.vcxproj/JavaScriptCore.proj
JavaScriptCore.vcxproj/JavaScriptCore.sln
JavaScriptCore.vcxproj/JavaScriptCore.submit.sln
JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
JavaScriptCore.vcxproj/JavaScriptCoreCommon.props
JavaScriptCore.vcxproj/JavaScriptCoreDLL.cpp [new file with mode: 0644]
JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make
JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj
JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd
JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd
JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make
JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj
JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl
JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make
JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj
JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.pl
JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj
JavaScriptCore.vcxproj/build-generated-files.pl
JavaScriptCore.vcxproj/copy-files.cmd
JavaScriptCore.vcxproj/jsc/DLLLauncherMain.cpp [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/DLLLauncherWinCairo.props [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/jsc.vcxproj
JavaScriptCore.vcxproj/jsc/jscCommon.props
JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/jscLauncherPostBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/jscLauncherPreBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/jscLauncherPreLink.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd
JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj
JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj
JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props
JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj [new file with mode: 0644]
JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPostBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreLink.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd
JavaScriptCore.vcxproj/testapi/testapi.vcxproj
JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters
JavaScriptCore.vcxproj/testapi/testapiCommon.props
JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props
JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj [new file with mode: 0644]
JavaScriptCore.vcxproj/testapi/testapiLauncherPostBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testapi/testapiLauncherPreBuild.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testapi/testapiLauncherPreLink.cmd [new file with mode: 0644]
JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd
JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd
JavaScriptCore.xcodeproj/project.pbxproj
KeywordLookupGenerator.py
PlatformEfl.cmake
PlatformGTK.cmake
PlatformMac.cmake [new file with mode: 0644]
PlatformWin.cmake [new file with mode: 0644]
UpdateContents.py [new file with mode: 0644]
assembler/ARM64Assembler.h
assembler/ARMAssembler.h
assembler/ARMv7Assembler.cpp [deleted file]
assembler/ARMv7Assembler.h
assembler/AbortReason.h
assembler/AbstractMacroAssembler.h
assembler/AssemblerBuffer.h
assembler/LinkBuffer.cpp
assembler/LinkBuffer.h
assembler/MacroAssembler.h
assembler/MacroAssemblerARM.cpp
assembler/MacroAssemblerARM.h
assembler/MacroAssemblerARM64.h
assembler/MacroAssemblerARMv7.cpp
assembler/MacroAssemblerARMv7.h
assembler/MacroAssemblerCodeRef.h
assembler/MacroAssemblerMIPS.h
assembler/MacroAssemblerSH4.h
assembler/MacroAssemblerX86.h
assembler/MacroAssemblerX86Common.cpp
assembler/MacroAssemblerX86Common.h
assembler/MacroAssemblerX86_64.h
assembler/X86Assembler.h
bindings/ScriptFunctionCall.cpp
bindings/ScriptFunctionCall.h
bindings/ScriptValue.cpp
bindings/ScriptValue.h
build-symbol-table-index.py
build-symbol-table-index.sh [deleted file]
builtins/Array.prototype.js
builtins/ArrayConstructor.js [new file with mode: 0644]
builtins/ArrayIterator.prototype.js [new file with mode: 0644]
builtins/BuiltinExecutables.cpp
builtins/BuiltinExecutables.h
builtins/BuiltinNames.h
builtins/GlobalObject.js [new file with mode: 0644]
builtins/Iterator.prototype.js [new file with mode: 0644]
builtins/ObjectConstructor.js [new file with mode: 0644]
builtins/Operations.Promise.js [new file with mode: 0644]
builtins/Promise.prototype.js
builtins/PromiseConstructor.js [new file with mode: 0644]
builtins/StringConstructor.js [new file with mode: 0644]
builtins/StringIterator.prototype.js [new file with mode: 0644]
bytecode/ArrayProfile.cpp
bytecode/ArrayProfile.h
bytecode/ByValInfo.h
bytecode/BytecodeBasicBlock.cpp
bytecode/BytecodeIntrinsicRegistry.cpp [new file with mode: 0644]
bytecode/BytecodeIntrinsicRegistry.h [new file with mode: 0644]
bytecode/BytecodeKills.h [new file with mode: 0644]
bytecode/BytecodeList.json
bytecode/BytecodeLivenessAnalysis.cpp
bytecode/BytecodeLivenessAnalysis.h
bytecode/BytecodeLivenessAnalysisInlines.h
bytecode/BytecodeUseDef.h
bytecode/CallEdge.cpp [new file with mode: 0644]
bytecode/CallEdge.h [new file with mode: 0644]
bytecode/CallLinkInfo.cpp
bytecode/CallLinkInfo.h
bytecode/CallLinkStatus.cpp
bytecode/CallLinkStatus.h
bytecode/CallVariant.cpp [new file with mode: 0644]
bytecode/CallVariant.h [new file with mode: 0644]
bytecode/CodeBlock.cpp
bytecode/CodeBlock.h
bytecode/CodeBlockJettisoningWatchpoint.cpp
bytecode/CodeBlockJettisoningWatchpoint.h
bytecode/CodeOrigin.cpp
bytecode/CodeOrigin.h
bytecode/ComplexGetStatus.cpp [new file with mode: 0644]
bytecode/ComplexGetStatus.h [new file with mode: 0644]
bytecode/ConstantStructureCheck.cpp [new file with mode: 0644]
bytecode/ConstantStructureCheck.h [new file with mode: 0644]
bytecode/DFGExitProfile.cpp
bytecode/DFGExitProfile.h
bytecode/DataFormat.h
bytecode/DeferredCompilationCallback.cpp
bytecode/DeferredCompilationCallback.h
bytecode/DeferredSourceDump.cpp [new file with mode: 0644]
bytecode/DeferredSourceDump.h [new file with mode: 0644]
bytecode/EvalCodeCache.h
bytecode/ExecutionCounter.cpp
bytecode/ExecutionCounter.h
bytecode/ExitKind.cpp
bytecode/ExitKind.h
bytecode/FullBytecodeLiveness.h
bytecode/GetByIdStatus.cpp
bytecode/GetByIdStatus.h
bytecode/GetByIdVariant.cpp
bytecode/GetByIdVariant.h
bytecode/HandlerInfo.h
bytecode/Instruction.h
bytecode/LLIntCallLinkInfo.h
bytecode/LazyOperandValueProfile.cpp
bytecode/LazyOperandValueProfile.h
bytecode/ObjectAllocationProfile.h
bytecode/Operands.h
bytecode/OperandsInlines.h
bytecode/PolymorphicGetByIdList.cpp
bytecode/PolymorphicGetByIdList.h
bytecode/PolymorphicPutByIdList.cpp
bytecode/PolymorphicPutByIdList.h
bytecode/PreciseJumpTargets.cpp
bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp [deleted file]
bytecode/ProfiledCodeBlockJettisoningWatchpoint.h [deleted file]
bytecode/PutByIdStatus.cpp
bytecode/PutByIdStatus.h
bytecode/PutByIdVariant.cpp
bytecode/PutByIdVariant.h
bytecode/SamplingTool.h
bytecode/SpecialPointer.h
bytecode/SpeculatedType.cpp
bytecode/SpeculatedType.h
bytecode/StructureSet.cpp [new file with mode: 0644]
bytecode/StructureSet.h
bytecode/StructureStubClearingWatchpoint.cpp
bytecode/StructureStubClearingWatchpoint.h
bytecode/StructureStubInfo.cpp
bytecode/StructureStubInfo.h
bytecode/ToThisStatus.cpp [new file with mode: 0644]
bytecode/ToThisStatus.h [new file with mode: 0644]
bytecode/TrackedReferences.cpp [new file with mode: 0644]
bytecode/TrackedReferences.h [new file with mode: 0644]
bytecode/TypeLocation.h [new file with mode: 0644]
bytecode/UnlinkedCodeBlock.cpp
bytecode/UnlinkedCodeBlock.h
bytecode/UnlinkedInstructionStream.cpp
bytecode/UnlinkedInstructionStream.h
bytecode/ValueRecovery.cpp
bytecode/ValueRecovery.h
bytecode/VariableWatchpointSet.h [deleted file]
bytecode/VariableWatchpointSetInlines.h [deleted file]
bytecode/VariableWriteFireDetail.cpp [new file with mode: 0644]
bytecode/VariableWriteFireDetail.h [new file with mode: 0644]
bytecode/VirtualRegister.cpp [new file with mode: 0644]
bytecode/VirtualRegister.h
bytecode/Watchpoint.cpp
bytecode/Watchpoint.h
bytecompiler/BytecodeGenerator.cpp
bytecompiler/BytecodeGenerator.h
bytecompiler/Label.h
bytecompiler/NodesCodegen.cpp
bytecompiler/RegisterID.h
bytecompiler/StaticPropertyAnalysis.h
config.h
copy-llvm-ir-to-derived-sources.sh
create-llvm-ir-from-source-file.py [new file with mode: 0644]
create-symbol-table-index.py [new file with mode: 0755]
create_hash_table
create_jit_stubs [deleted file]
create_regex_tables
debugger/Breakpoint.h
debugger/Debugger.cpp
debugger/Debugger.h
debugger/DebuggerActivation.cpp [deleted file]
debugger/DebuggerActivation.h [deleted file]
debugger/DebuggerCallFrame.cpp
debugger/DebuggerCallFrame.h
debugger/DebuggerEvalEnabler.h [new file with mode: 0644]
debugger/DebuggerScope.cpp [new file with mode: 0644]
debugger/DebuggerScope.h [new file with mode: 0644]
dfg/DFGAbstractHeap.cpp
dfg/DFGAbstractHeap.h
dfg/DFGAbstractInterpreter.h
dfg/DFGAbstractInterpreterInlines.h
dfg/DFGAbstractValue.cpp
dfg/DFGAbstractValue.h
dfg/DFGAdjacencyList.h
dfg/DFGAllocator.h
dfg/DFGAnalysis.h
dfg/DFGArgumentPosition.h
dfg/DFGArgumentsEliminationPhase.cpp [new file with mode: 0644]
dfg/DFGArgumentsEliminationPhase.h [new file with mode: 0644]
dfg/DFGArgumentsSimplificationPhase.cpp [deleted file]
dfg/DFGArgumentsSimplificationPhase.h [deleted file]
dfg/DFGArgumentsUtilities.cpp [new file with mode: 0644]
dfg/DFGArgumentsUtilities.h [new file with mode: 0644]
dfg/DFGArithMode.h
dfg/DFGArrayMode.cpp
dfg/DFGArrayMode.h
dfg/DFGArrayifySlowPathGenerator.h
dfg/DFGAtTailAbstractState.cpp
dfg/DFGAtTailAbstractState.h
dfg/DFGAvailability.h
dfg/DFGAvailabilityMap.cpp [new file with mode: 0644]
dfg/DFGAvailabilityMap.h [new file with mode: 0644]
dfg/DFGBackwardsPropagationPhase.cpp
dfg/DFGBasicBlock.cpp
dfg/DFGBasicBlock.h
dfg/DFGBasicBlockInlines.h
dfg/DFGBinarySwitch.cpp [deleted file]
dfg/DFGBinarySwitch.h [deleted file]
dfg/DFGBlockMap.h [new file with mode: 0644]
dfg/DFGBlockMapInlines.h [new file with mode: 0644]
dfg/DFGBlockSet.cpp [new file with mode: 0644]
dfg/DFGBlockSet.h [new file with mode: 0644]
dfg/DFGBlockSetInlines.h [new file with mode: 0644]
dfg/DFGBlockWorklist.cpp [new file with mode: 0644]
dfg/DFGBlockWorklist.h [new file with mode: 0644]
dfg/DFGBranchDirection.h
dfg/DFGByteCodeParser.cpp
dfg/DFGByteCodeParser.h
dfg/DFGCFAPhase.cpp
dfg/DFGCFGSimplificationPhase.cpp
dfg/DFGCPSRethreadingPhase.cpp
dfg/DFGCSEPhase.cpp
dfg/DFGCSEPhase.h
dfg/DFGCallArrayAllocatorSlowPathGenerator.h
dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h [new file with mode: 0644]
dfg/DFGCapabilities.cpp
dfg/DFGCapabilities.h
dfg/DFGCleanUpPhase.cpp [new file with mode: 0644]
dfg/DFGCleanUpPhase.h [new file with mode: 0644]
dfg/DFGClobberSet.cpp
dfg/DFGClobberSet.h
dfg/DFGClobberize.cpp
dfg/DFGClobberize.h
dfg/DFGCombinedLiveness.cpp [new file with mode: 0644]
dfg/DFGCombinedLiveness.h [new file with mode: 0644]
dfg/DFGCommon.cpp
dfg/DFGCommon.h
dfg/DFGCommonData.cpp
dfg/DFGCommonData.h
dfg/DFGConstantFoldingPhase.cpp
dfg/DFGConstantHoistingPhase.cpp [new file with mode: 0644]
dfg/DFGConstantHoistingPhase.h [new file with mode: 0644]
dfg/DFGCriticalEdgeBreakingPhase.cpp
dfg/DFGDCEPhase.cpp
dfg/DFGDesiredIdentifiers.cpp
dfg/DFGDesiredIdentifiers.h
dfg/DFGDesiredStructureChains.cpp [deleted file]
dfg/DFGDesiredStructureChains.h [deleted file]
dfg/DFGDesiredWatchpoints.cpp
dfg/DFGDesiredWatchpoints.h
dfg/DFGDesiredWeakReferences.cpp
dfg/DFGDesiredWeakReferences.h
dfg/DFGDisassembler.cpp
dfg/DFGDisassembler.h
dfg/DFGDoesGC.cpp [new file with mode: 0644]
dfg/DFGDoesGC.h [new file with mode: 0644]
dfg/DFGDominators.cpp
dfg/DFGDominators.h
dfg/DFGDriver.cpp
dfg/DFGEdge.cpp
dfg/DFGEdge.h
dfg/DFGEdgeDominates.h
dfg/DFGEpoch.cpp [new file with mode: 0644]
dfg/DFGEpoch.h [new file with mode: 0644]
dfg/DFGFiltrationResult.h
dfg/DFGFixupPhase.cpp
dfg/DFGFlushFormat.cpp
dfg/DFGFlushFormat.h
dfg/DFGFlushedAt.cpp
dfg/DFGFlushedAt.h
dfg/DFGForAllKills.h [new file with mode: 0644]
dfg/DFGFrozenValue.cpp [new file with mode: 0644]
dfg/DFGFrozenValue.h [new file with mode: 0644]
dfg/DFGFunctionWhitelist.cpp
dfg/DFGGenerationInfo.h
dfg/DFGGraph.cpp
dfg/DFGGraph.h
dfg/DFGHeapLocation.cpp [new file with mode: 0644]
dfg/DFGHeapLocation.h [new file with mode: 0644]
dfg/DFGInPlaceAbstractState.cpp
dfg/DFGInPlaceAbstractState.h
dfg/DFGInsertOSRHintsForUpdate.cpp [new file with mode: 0644]
dfg/DFGInsertOSRHintsForUpdate.h [new file with mode: 0644]
dfg/DFGInsertionSet.h
dfg/DFGIntegerCheckCombiningPhase.cpp
dfg/DFGIntegerRangeOptimizationPhase.cpp [new file with mode: 0644]
dfg/DFGIntegerRangeOptimizationPhase.h [new file with mode: 0644]
dfg/DFGInvalidationPointInjectionPhase.cpp
dfg/DFGJITCode.cpp
dfg/DFGJITCode.h
dfg/DFGJITCompiler.cpp
dfg/DFGJITCompiler.h
dfg/DFGJITFinalizer.cpp
dfg/DFGJITFinalizer.h
dfg/DFGLICMPhase.cpp
dfg/DFGLazyJSValue.cpp
dfg/DFGLazyJSValue.h
dfg/DFGLazyNode.cpp [new file with mode: 0644]
dfg/DFGLazyNode.h [new file with mode: 0644]
dfg/DFGLivenessAnalysisPhase.cpp
dfg/DFGLoopPreHeaderCreationPhase.cpp
dfg/DFGMayExit.cpp [new file with mode: 0644]
dfg/DFGMayExit.h [new file with mode: 0644]
dfg/DFGMinifiedGraph.cpp [new file with mode: 0644]
dfg/DFGMinifiedGraph.h
dfg/DFGMinifiedID.h
dfg/DFGMinifiedNode.cpp
dfg/DFGMinifiedNode.h
dfg/DFGMovHintRemovalPhase.cpp [new file with mode: 0644]
dfg/DFGMovHintRemovalPhase.h [new file with mode: 0644]
dfg/DFGNaiveDominators.cpp [new file with mode: 0644]
dfg/DFGNaiveDominators.h [new file with mode: 0644]
dfg/DFGNaturalLoops.cpp
dfg/DFGNaturalLoops.h
dfg/DFGNode.cpp
dfg/DFGNode.h
dfg/DFGNodeFlags.cpp
dfg/DFGNodeFlags.h
dfg/DFGNodeOrigin.h
dfg/DFGNodeType.h
dfg/DFGOSRAvailabilityAnalysisPhase.cpp
dfg/DFGOSRAvailabilityAnalysisPhase.h
dfg/DFGOSREntry.cpp
dfg/DFGOSREntry.h
dfg/DFGOSRExit.h
dfg/DFGOSRExitBase.cpp
dfg/DFGOSRExitBase.h
dfg/DFGOSRExitCompiler.cpp
dfg/DFGOSRExitCompiler.h
dfg/DFGOSRExitCompiler32_64.cpp
dfg/DFGOSRExitCompiler64.cpp
dfg/DFGOSRExitCompilerCommon.cpp
dfg/DFGOSRExitCompilerCommon.h
dfg/DFGOSRExitFuzz.cpp [new file with mode: 0644]
dfg/DFGOSRExitFuzz.h [new file with mode: 0644]
dfg/DFGOSRExitPreparation.cpp
dfg/DFGObjectAllocationSinkingPhase.cpp [new file with mode: 0644]
dfg/DFGObjectAllocationSinkingPhase.h [new file with mode: 0644]
dfg/DFGObjectMaterializationData.cpp [new file with mode: 0644]
dfg/DFGObjectMaterializationData.h [new file with mode: 0644]
dfg/DFGOperations.cpp
dfg/DFGOperations.h
dfg/DFGPhantomInsertionPhase.cpp [new file with mode: 0644]
dfg/DFGPhantomInsertionPhase.h [new file with mode: 0644]
dfg/DFGPhase.cpp
dfg/DFGPhase.h
dfg/DFGPhiChildren.cpp [new file with mode: 0644]
dfg/DFGPhiChildren.h [new file with mode: 0644]
dfg/DFGPlan.cpp
dfg/DFGPlan.h
dfg/DFGPrePostNumbering.cpp [new file with mode: 0644]
dfg/DFGPrePostNumbering.h [new file with mode: 0644]
dfg/DFGPreciseLocalClobberize.h [new file with mode: 0644]
dfg/DFGPredictionPropagationPhase.cpp
dfg/DFGPromoteHeapAccess.h [new file with mode: 0644]
dfg/DFGPromotedHeapLocation.cpp [new file with mode: 0644]
dfg/DFGPromotedHeapLocation.h [new file with mode: 0644]
dfg/DFGPureValue.cpp [new file with mode: 0644]
dfg/DFGPureValue.h [new file with mode: 0644]
dfg/DFGPutStackSinkingPhase.cpp [new file with mode: 0644]
dfg/DFGPutStackSinkingPhase.h [new file with mode: 0644]
dfg/DFGResurrectionForValidationPhase.cpp [deleted file]
dfg/DFGResurrectionForValidationPhase.h [deleted file]
dfg/DFGSSACalculator.cpp [new file with mode: 0644]
dfg/DFGSSACalculator.h [new file with mode: 0644]
dfg/DFGSSAConversionPhase.cpp
dfg/DFGSSAConversionPhase.h
dfg/DFGSSALoweringPhase.cpp
dfg/DFGSafeToExecute.h
dfg/DFGScoreBoard.h
dfg/DFGSlowPathGenerator.h
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT.h
dfg/DFGSpeculativeJIT32_64.cpp
dfg/DFGSpeculativeJIT64.cpp
dfg/DFGStackLayoutPhase.cpp
dfg/DFGStaticExecutionCountEstimationPhase.cpp
dfg/DFGStoreBarrierElisionPhase.cpp [deleted file]
dfg/DFGStoreBarrierElisionPhase.h [deleted file]
dfg/DFGStoreBarrierInsertionPhase.cpp [new file with mode: 0644]
dfg/DFGStoreBarrierInsertionPhase.h [new file with mode: 0644]
dfg/DFGStrengthReductionPhase.cpp
dfg/DFGStructureAbstractValue.cpp [new file with mode: 0644]
dfg/DFGStructureAbstractValue.h
dfg/DFGStructureClobberState.h [new file with mode: 0644]
dfg/DFGStructureRegistrationPhase.cpp [new file with mode: 0644]
dfg/DFGStructureRegistrationPhase.h [new file with mode: 0644]
dfg/DFGTierUpCheckInjectionPhase.cpp
dfg/DFGToFTLDeferredCompilationCallback.cpp
dfg/DFGToFTLDeferredCompilationCallback.h
dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp
dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h
dfg/DFGTransition.cpp [new file with mode: 0644]
dfg/DFGTransition.h [new file with mode: 0644]
dfg/DFGTypeCheckHoistingPhase.cpp
dfg/DFGUnificationPhase.cpp
dfg/DFGUseKind.cpp
dfg/DFGUseKind.h
dfg/DFGValidate.cpp
dfg/DFGValidate.h
dfg/DFGValueRecoveryOverride.h [deleted file]
dfg/DFGValueSource.cpp
dfg/DFGValueSource.h
dfg/DFGValueStrength.cpp [new file with mode: 0644]
dfg/DFGValueStrength.h [new file with mode: 0644]
dfg/DFGVarargsForwardingPhase.cpp [new file with mode: 0644]
dfg/DFGVarargsForwardingPhase.h [new file with mode: 0644]
dfg/DFGVariableAccessData.cpp
dfg/DFGVariableAccessData.h
dfg/DFGVariableAccessDataDump.cpp
dfg/DFGVariableAccessDataDump.h
dfg/DFGVariableEvent.cpp
dfg/DFGVariableEvent.h
dfg/DFGVariableEventStream.cpp
dfg/DFGVariableEventStream.h
dfg/DFGVirtualRegisterAllocationPhase.cpp
dfg/DFGWatchpointCollectionPhase.cpp
dfg/DFGWorklist.cpp
dfg/DFGWorklist.h
disassembler/ARM64/A64DOpcode.cpp
disassembler/ARM64/A64DOpcode.h
disassembler/ARM64Disassembler.cpp
disassembler/ARMv7/ARMv7DOpcode.cpp
disassembler/ARMv7/ARMv7DOpcode.h
disassembler/Disassembler.cpp
disassembler/Disassembler.h
features.json [new file with mode: 0644]
ftl/FTLAbbreviatedTypes.h
ftl/FTLAbbreviations.h
ftl/FTLAbstractHeap.cpp
ftl/FTLAbstractHeap.h
ftl/FTLAbstractHeapRepository.cpp
ftl/FTLAbstractHeapRepository.h
ftl/FTLCapabilities.cpp
ftl/FTLCompile.cpp
ftl/FTLExitArgument.cpp
ftl/FTLExitArgumentForOperand.cpp
ftl/FTLExitPropertyValue.cpp [new file with mode: 0644]
ftl/FTLExitPropertyValue.h [new file with mode: 0644]
ftl/FTLExitTimeObjectMaterialization.cpp [new file with mode: 0644]
ftl/FTLExitTimeObjectMaterialization.h [new file with mode: 0644]
ftl/FTLExitValue.cpp
ftl/FTLExitValue.h
ftl/FTLFail.cpp
ftl/FTLForOSREntryJITCode.cpp
ftl/FTLInlineCacheDescriptor.h
ftl/FTLInlineCacheSize.cpp
ftl/FTLInlineCacheSize.h
ftl/FTLIntrinsicRepository.h
ftl/FTLJITCode.cpp
ftl/FTLJITCode.h
ftl/FTLJITFinalizer.cpp
ftl/FTLJITFinalizer.h
ftl/FTLJSCall.cpp
ftl/FTLJSCall.h
ftl/FTLJSCallBase.cpp [new file with mode: 0644]
ftl/FTLJSCallBase.h [new file with mode: 0644]
ftl/FTLJSCallVarargs.cpp [new file with mode: 0644]
ftl/FTLJSCallVarargs.h [new file with mode: 0644]
ftl/FTLLink.cpp
ftl/FTLLowerDFGToLLVM.cpp
ftl/FTLLowerDFGToLLVM.h
ftl/FTLOSREntry.cpp
ftl/FTLOSRExit.cpp
ftl/FTLOSRExit.h
ftl/FTLOSRExitCompiler.cpp
ftl/FTLOperations.cpp [new file with mode: 0644]
ftl/FTLOperations.h [new file with mode: 0644]
ftl/FTLOutput.cpp
ftl/FTLOutput.h
ftl/FTLSlowPathCall.cpp
ftl/FTLSlowPathCall.h
ftl/FTLState.cpp
ftl/FTLState.h
ftl/FTLSwitchCase.h
ftl/FTLUnwindInfo.cpp
ftl/FTLUnwindInfo.h
ftl/FTLWeight.h
generate-js-builtins
heap/BlockAllocator.cpp [deleted file]
heap/BlockAllocator.h [deleted file]
heap/CodeBlockSet.cpp
heap/CodeBlockSet.h
heap/CopiedBlock.h
heap/CopiedBlockInlines.h
heap/CopiedSpace.cpp
heap/CopiedSpace.h
heap/CopiedSpaceInlines.h
heap/CopyToken.h
heap/CopyWorkList.h
heap/CopyWriteBarrier.h
heap/DelayedReleaseScope.h [deleted file]
heap/EdenGCActivityCallback.h
heap/FullGCActivityCallback.cpp
heap/FullGCActivityCallback.h
heap/GCActivityCallback.h
heap/GCLogging.cpp
heap/GCLogging.h
heap/GCSegmentedArray.h
heap/GCSegmentedArrayInlines.h
heap/GCThread.cpp
heap/GCThread.h
heap/GCThreadSharedData.cpp
heap/GCThreadSharedData.h
heap/Handle.h
heap/HandleBlock.h
heap/HandleBlockInlines.h
heap/HandleSet.cpp
heap/HandleStack.h
heap/Heap.cpp
heap/Heap.h
heap/HeapBlock.h [deleted file]
heap/HeapInlines.h
heap/HeapStatistics.cpp
heap/HeapTimer.cpp
heap/HeapVerifier.cpp [new file with mode: 0644]
heap/HeapVerifier.h [new file with mode: 0644]
heap/IncrementalSweeper.cpp
heap/IncrementalSweeper.h
heap/ListableHandler.h
heap/MachineStackMarker.cpp
heap/MachineStackMarker.h
heap/MarkStack.cpp
heap/MarkStack.h
heap/MarkedAllocator.cpp
heap/MarkedAllocator.h
heap/MarkedBlock.cpp
heap/MarkedBlock.h
heap/MarkedBlockSet.h
heap/MarkedSpace.cpp
heap/MarkedSpace.h
heap/Region.h [deleted file]
heap/SlotVisitor.cpp
heap/SlotVisitor.h
heap/SlotVisitorInlines.h
heap/Strong.h
heap/SuperRegion.cpp [deleted file]
heap/SuperRegion.h [deleted file]
heap/WeakBlock.cpp
heap/WeakBlock.h
heap/WeakSet.cpp
heap/WeakSet.h
heap/WriteBarrierBuffer.cpp
heap/WriteBarrierBuffer.h
inspector/ConsoleMessage.cpp
inspector/ConsoleMessage.h
inspector/ContentSearchUtilities.cpp
inspector/ContentSearchUtilities.h
inspector/IdentifiersFactory.cpp
inspector/IdentifiersFactory.h
inspector/InjectedScript.cpp
inspector/InjectedScript.h
inspector/InjectedScriptBase.cpp
inspector/InjectedScriptBase.h
inspector/InjectedScriptHost.cpp
inspector/InjectedScriptHost.h
inspector/InjectedScriptManager.cpp
inspector/InjectedScriptManager.h
inspector/InjectedScriptModule.cpp
inspector/InjectedScriptModule.h
inspector/InjectedScriptSource.js
inspector/InspectorAgentBase.h
inspector/InspectorAgentRegistry.cpp
inspector/InspectorAgentRegistry.h
inspector/InspectorBackendDispatcher.cpp
inspector/InspectorBackendDispatcher.h
inspector/InspectorEnvironment.h
inspector/InspectorFrontendChannel.h
inspector/InspectorProtocolTypes.h [new file with mode: 0644]
inspector/InspectorTypeBuilder.h [deleted file]
inspector/InspectorValues.cpp
inspector/InspectorValues.h
inspector/JSConsoleClient.cpp [deleted file]
inspector/JSConsoleClient.h [deleted file]
inspector/JSGlobalObjectConsoleClient.cpp [new file with mode: 0644]
inspector/JSGlobalObjectConsoleClient.h [new file with mode: 0644]
inspector/JSGlobalObjectInspectorController.cpp
inspector/JSGlobalObjectInspectorController.h
inspector/JSGlobalObjectScriptDebugServer.cpp
inspector/JSGlobalObjectScriptDebugServer.h
inspector/JSInjectedScriptHost.cpp
inspector/JSInjectedScriptHost.h
inspector/JSInjectedScriptHostPrototype.cpp
inspector/JSInjectedScriptHostPrototype.h
inspector/JSJavaScriptCallFrame.cpp
inspector/JSJavaScriptCallFrame.h
inspector/JSJavaScriptCallFramePrototype.cpp
inspector/JSJavaScriptCallFramePrototype.h
inspector/JavaScriptCallFrame.cpp
inspector/JavaScriptCallFrame.h
inspector/ScriptArguments.cpp
inspector/ScriptArguments.h
inspector/ScriptCallFrame.cpp
inspector/ScriptCallFrame.h
inspector/ScriptCallStack.cpp
inspector/ScriptCallStack.h
inspector/ScriptCallStackFactory.cpp
inspector/ScriptCallStackFactory.h
inspector/ScriptDebugListener.h
inspector/ScriptDebugServer.cpp
inspector/ScriptDebugServer.h
inspector/agents/InspectorAgent.cpp
inspector/agents/InspectorAgent.h
inspector/agents/InspectorConsoleAgent.cpp
inspector/agents/InspectorConsoleAgent.h
inspector/agents/InspectorDebuggerAgent.cpp
inspector/agents/InspectorDebuggerAgent.h
inspector/agents/InspectorProfilerAgent.cpp [deleted file]
inspector/agents/InspectorProfilerAgent.h [deleted file]
inspector/agents/InspectorRuntimeAgent.cpp
inspector/agents/InspectorRuntimeAgent.h
inspector/agents/JSGlobalObjectConsoleAgent.cpp
inspector/agents/JSGlobalObjectConsoleAgent.h
inspector/agents/JSGlobalObjectDebuggerAgent.cpp
inspector/agents/JSGlobalObjectDebuggerAgent.h
inspector/agents/JSGlobalObjectProfilerAgent.cpp [deleted file]
inspector/agents/JSGlobalObjectProfilerAgent.h [deleted file]
inspector/agents/JSGlobalObjectRuntimeAgent.cpp
inspector/agents/JSGlobalObjectRuntimeAgent.h
inspector/augmentable/AlternateDispatchableAgent.h [new file with mode: 0644]
inspector/augmentable/AugmentableInspectorController.h [new file with mode: 0644]
inspector/augmentable/AugmentableInspectorControllerClient.h [new file with mode: 0644]
inspector/protocol/ApplicationCache.json [new file with mode: 0644]
inspector/protocol/CSS.json [new file with mode: 0644]
inspector/protocol/Console.json
inspector/protocol/DOM.json [new file with mode: 0644]
inspector/protocol/DOMDebugger.json [new file with mode: 0644]
inspector/protocol/DOMStorage.json [new file with mode: 0644]
inspector/protocol/Database.json [new file with mode: 0644]
inspector/protocol/Debugger.json
inspector/protocol/IndexedDB.json [new file with mode: 0644]
inspector/protocol/Inspector.json [new file with mode: 0644]
inspector/protocol/InspectorDomain.json [deleted file]
inspector/protocol/LayerTree.json [new file with mode: 0644]
inspector/protocol/Network.json [new file with mode: 0644]
inspector/protocol/OverlayTypes.json [new file with mode: 0644]
inspector/protocol/Page.json [new file with mode: 0644]
inspector/protocol/Profiler.json [deleted file]
inspector/protocol/Replay.json [new file with mode: 0644]
inspector/protocol/Runtime.json
inspector/protocol/Timeline.json [new file with mode: 0644]
inspector/protocol/Worker.json [new file with mode: 0644]
inspector/remote/RemoteInspector.h
inspector/remote/RemoteInspector.mm
inspector/remote/RemoteInspectorConstants.h
inspector/remote/RemoteInspectorDebuggable.cpp
inspector/remote/RemoteInspectorDebuggable.h
inspector/remote/RemoteInspectorDebuggableConnection.h
inspector/remote/RemoteInspectorDebuggableConnection.mm
inspector/remote/RemoteInspectorXPCConnection.h
inspector/remote/RemoteInspectorXPCConnection.mm
inspector/scripts/CodeGeneratorInspector.py [deleted file]
inspector/scripts/CodeGeneratorInspectorStrings.py [deleted file]
inspector/scripts/codegen/__init__.py [new file with mode: 0644]
inspector/scripts/codegen/cpp_generator.py [new file with mode: 0644]
inspector/scripts/codegen/cpp_generator_templates.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_protocol_types_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_cpp_protocol_types_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_js_backend_commands.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_configuration_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_configuration_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_conversion_helpers.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_internal_header.py [new file with mode: 0755]
inspector/scripts/codegen/generate_objc_protocol_types_implementation.py [new file with mode: 0755]
inspector/scripts/codegen/generator.py [new file with mode: 0755]
inspector/scripts/codegen/generator_templates.py [new file with mode: 0644]
inspector/scripts/codegen/models.py [new file with mode: 0755]
inspector/scripts/codegen/objc_generator.py [new file with mode: 0755]
inspector/scripts/codegen/objc_generator_templates.py [new file with mode: 0755]
inspector/scripts/generate-inspector-protocol-bindings.py [new file with mode: 0755]
inspector/scripts/tests/commands-with-async-attribute.json [new file with mode: 0644]
inspector/scripts/tests/commands-with-optional-call-return-parameters.json [new file with mode: 0644]
inspector/scripts/tests/domains-with-varying-command-sizes.json [new file with mode: 0644]
inspector/scripts/tests/enum-values.json [new file with mode: 0644]
inspector/scripts/tests/events-with-optional-parameters.json [new file with mode: 0644]
inspector/scripts/tests/expected/commands-with-async-attribute.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/enum-values.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/events-with-optional-parameters.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-domain-availability.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-duplicate-command-call-parameter-names.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-duplicate-command-return-parameter-names.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-duplicate-event-parameter-names.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-duplicate-type-declarations.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-duplicate-type-member-names.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-enum-with-no-values.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-string-typed-optional-parameter-flag.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-string-typed-optional-type-member.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-type-declaration-using-type-reference.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-type-with-lowercase-name.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-declaration.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-member.json-error [new file with mode: 0644]
inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/same-type-id-different-domain.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/type-declaration-array-type.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/type-declaration-enum-type.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/type-declaration-object-type.json-result [new file with mode: 0644]
inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result [new file with mode: 0644]
inspector/scripts/tests/fail-on-domain-availability.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-duplicate-command-call-parameter-names.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-duplicate-command-return-parameter-names.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-duplicate-event-parameter-names.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-duplicate-type-declarations.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-duplicate-type-member-names.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-enum-with-no-values.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-string-typed-optional-parameter-flag.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-string-typed-optional-type-member.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-type-declaration-using-type-reference.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-type-with-lowercase-name.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-unknown-type-reference-in-type-declaration.json [new file with mode: 0644]
inspector/scripts/tests/fail-on-unknown-type-reference-in-type-member.json [new file with mode: 0644]
inspector/scripts/tests/generate-domains-with-feature-guards.json [new file with mode: 0644]
inspector/scripts/tests/same-type-id-different-domain.json [new file with mode: 0644]
inspector/scripts/tests/shadowed-optional-type-setters.json [new file with mode: 0644]
inspector/scripts/tests/type-declaration-aliased-primitive-type.json [new file with mode: 0644]
inspector/scripts/tests/type-declaration-array-type.json [new file with mode: 0644]
inspector/scripts/tests/type-declaration-enum-type.json [new file with mode: 0644]
inspector/scripts/tests/type-declaration-object-type.json [new file with mode: 0644]
inspector/scripts/tests/type-requiring-runtime-casts.json [new file with mode: 0644]
interpreter/CallFrame.cpp
interpreter/CallFrame.h
interpreter/CallFrameClosure.h
interpreter/CallFrameInlines.h
interpreter/Interpreter.cpp
interpreter/Interpreter.h
interpreter/JSStack.cpp
interpreter/JSStack.h
interpreter/ProtoCallFrame.cpp
interpreter/ProtoCallFrame.h
interpreter/Register.h
interpreter/StackVisitor.cpp
interpreter/StackVisitor.h
interpreter/VMEntryRecord.h [new file with mode: 0644]
interpreter/VMInspector.cpp [deleted file]
interpreter/VMInspector.h [deleted file]
jit/AccessorCallJITStubRoutine.h
jit/ArityCheckFailReturnThunks.cpp
jit/AssemblyHelpers.cpp
jit/AssemblyHelpers.h
jit/BinarySwitch.cpp [new file with mode: 0644]
jit/BinarySwitch.h [new file with mode: 0644]
jit/CCallHelpers.h
jit/ClosureCallStubRoutine.cpp [deleted file]
jit/ClosureCallStubRoutine.h [deleted file]
jit/CompactJITCodeMap.h
jit/ExecutableAllocationFuzz.cpp [new file with mode: 0644]
jit/ExecutableAllocationFuzz.h [new file with mode: 0644]
jit/ExecutableAllocator.cpp
jit/ExecutableAllocator.h
jit/ExecutableAllocatorFixedVMPool.cpp
jit/GPRInfo.h
jit/JIT.cpp
jit/JIT.h
jit/JITCall.cpp
jit/JITCall32_64.cpp
jit/JITCode.cpp
jit/JITCode.h
jit/JITCompilationEffort.h
jit/JITExceptions.cpp
jit/JITExceptions.h
jit/JITInlines.h
jit/JITOpcodes.cpp
jit/JITOpcodes32_64.cpp
jit/JITOperations.cpp
jit/JITOperations.h
jit/JITPropertyAccess.cpp
jit/JITPropertyAccess32_64.cpp
jit/JITStubRoutine.h
jit/JITStubs.h
jit/JITStubsARM.h
jit/JITStubsARMv7.h
jit/JITStubsX86.h
jit/JITStubsX86Common.h
jit/JITStubsX86_64.h
jit/JITThunks.cpp
jit/JITThunks.h
jit/JITToDFGDeferredCompilationCallback.cpp
jit/JITToDFGDeferredCompilationCallback.h
jit/JITWriteBarrier.h
jit/JSInterfaceJIT.h
jit/PolymorphicCallStubRoutine.cpp [new file with mode: 0644]
jit/PolymorphicCallStubRoutine.h [new file with mode: 0644]
jit/RegisterSet.cpp
jit/Repatch.cpp
jit/Repatch.h
jit/SetupVarargsFrame.cpp [new file with mode: 0644]
jit/SetupVarargsFrame.h [new file with mode: 0644]
jit/SlowPathCall.h
jit/SpecializedThunkJIT.h
jit/ThunkGenerators.cpp
jit/ThunkGenerators.h
jsc.cpp
llint/LLIntData.cpp
llint/LLIntOfflineAsmConfig.h
llint/LLIntOffsetsExtractor.cpp
llint/LLIntSlowPaths.cpp
llint/LLIntSlowPaths.h
llint/LLIntThunks.cpp
llint/LLIntThunks.h
llint/LowLevelInterpreter.asm
llint/LowLevelInterpreter.cpp
llint/LowLevelInterpreter32_64.asm
llint/LowLevelInterpreter64.asm
llvm/InitializeLLVM.cpp
llvm/InitializeLLVM.h
llvm/InitializeLLVMLinux.cpp
llvm/InitializeLLVMMac.cpp [new file with mode: 0644]
llvm/InitializeLLVMMac.mm [deleted file]
llvm/InitializeLLVMPOSIX.cpp
llvm/InitializeLLVMPOSIX.h
llvm/InitializeLLVMWin.cpp
llvm/LLVMAPI.cpp
llvm/LLVMAPI.h
llvm/LLVMAPIFunctions.h
llvm/LLVMHeaders.h
llvm/library/LLVMExports.cpp
llvm/library/LLVMOverrides.cpp
llvm/library/LLVMTrapCallback.h
llvm/library/libllvmForJSC.version [new file with mode: 0644]
offlineasm/arm.rb
offlineasm/arm64.rb
offlineasm/ast.rb
offlineasm/backends.rb
offlineasm/cloop.rb
offlineasm/generate_offset_extractor.rb
offlineasm/instructions.rb
offlineasm/mips.rb
offlineasm/parser.rb
offlineasm/settings.rb
offlineasm/sh4.rb
offlineasm/transform.rb
offlineasm/x86.rb
parser/ASTBuilder.h
parser/Keywords.table
parser/Lexer.cpp
parser/Lexer.h
parser/NodeConstructors.h
parser/NodeInfo.h [deleted file]
parser/Nodes.cpp
parser/Nodes.h
parser/Parser.cpp
parser/Parser.h
parser/ParserArena.cpp
parser/ParserArena.h
parser/ParserError.h
parser/ParserFunctionInfo.h [new file with mode: 0644]
parser/ParserModes.h
parser/ParserTokens.h
parser/SourceCode.h
parser/SourceProvider.cpp
parser/SourceProvider.h
parser/SourceProviderCache.h
parser/SourceProviderCacheItem.h
parser/SyntaxChecker.h
postprocess-headers.sh
profiler/LegacyProfiler.cpp
profiler/LegacyProfiler.h
profiler/Profile.cpp
profiler/Profile.h
profiler/ProfileGenerator.cpp
profiler/ProfileGenerator.h
profiler/ProfileNode.cpp
profiler/ProfileNode.h
profiler/ProfilerBytecodeSequence.cpp
profiler/ProfilerCompilation.cpp
profiler/ProfilerCompilation.h
profiler/ProfilerDatabase.cpp
replay/EmptyInputCursor.h
replay/EncodedValue.cpp
replay/EncodedValue.h
replay/InputCursor.h
replay/JSInputs.json
replay/NondeterministicInput.h
replay/scripts/CodeGeneratorReplayInputs.py
replay/scripts/CodeGeneratorReplayInputsTemplates.py
replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error
replay/scripts/tests/expected/fail-on-no-inputs.json-error [deleted file]
replay/scripts/tests/expected/fail-on-no-types.json-error [deleted file]
replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.h
replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.cpp
replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.h
replay/scripts/tests/fail-on-c-style-enum-no-storage.json
replay/scripts/tests/fail-on-duplicate-enum-type.json
replay/scripts/tests/fail-on-duplicate-input-names.json
replay/scripts/tests/fail-on-duplicate-type-names.json
replay/scripts/tests/fail-on-enum-type-missing-values.json
replay/scripts/tests/fail-on-missing-input-member-name.json
replay/scripts/tests/fail-on-missing-input-name.json
replay/scripts/tests/fail-on-missing-input-queue.json
replay/scripts/tests/fail-on-missing-type-mode.json
replay/scripts/tests/fail-on-missing-type-name.json
replay/scripts/tests/fail-on-no-inputs.json [deleted file]
replay/scripts/tests/fail-on-no-types.json [deleted file]
replay/scripts/tests/fail-on-unknown-input-queue.json
replay/scripts/tests/fail-on-unknown-member-type.json
replay/scripts/tests/fail-on-unknown-type-mode.json
replay/scripts/tests/generate-enum-encoding-helpers-with-guarded-values.json
replay/scripts/tests/generate-enum-encoding-helpers.json
replay/scripts/tests/generate-enum-with-guard.json
replay/scripts/tests/generate-enums-with-same-base-name.json
replay/scripts/tests/generate-event-loop-shape-types.json
replay/scripts/tests/generate-input-with-guard.json
replay/scripts/tests/generate-input-with-vector-members.json
replay/scripts/tests/generate-inputs-with-flags.json
replay/scripts/tests/generate-memoized-type-modes.json
runtime/Arguments.cpp [deleted file]
runtime/Arguments.h [deleted file]
runtime/ArgumentsIteratorConstructor.cpp [deleted file]
runtime/ArgumentsIteratorConstructor.h [deleted file]
runtime/ArgumentsIteratorPrototype.cpp [deleted file]
runtime/ArgumentsIteratorPrototype.h [deleted file]
runtime/ArgumentsMode.h [new file with mode: 0644]
runtime/ArrayBuffer.cpp
runtime/ArrayBufferNeuteringWatchpoint.cpp
runtime/ArrayBufferNeuteringWatchpoint.h
runtime/ArrayBufferView.h
runtime/ArrayConstructor.cpp
runtime/ArrayConstructor.h
runtime/ArrayConventions.h
runtime/ArrayIteratorConstructor.cpp [deleted file]
runtime/ArrayIteratorConstructor.h [deleted file]
runtime/ArrayIteratorPrototype.cpp
runtime/ArrayIteratorPrototype.h
runtime/ArrayPrototype.cpp
runtime/ArrayPrototype.h
runtime/BasicBlockLocation.cpp [new file with mode: 0644]
runtime/BasicBlockLocation.h [new file with mode: 0644]
runtime/BooleanConstructor.cpp
runtime/BooleanObject.cpp
runtime/BooleanPrototype.cpp
runtime/BooleanPrototype.h
runtime/BundlePath.cpp [new file with mode: 0644]
runtime/BundlePath.h [new file with mode: 0644]
runtime/BundlePath.mm [new file with mode: 0644]
runtime/CallData.cpp
runtime/CallData.h
runtime/ClassInfo.h
runtime/ClonedArguments.cpp [new file with mode: 0644]
runtime/ClonedArguments.h [new file with mode: 0644]
runtime/CodeCache.cpp
runtime/CodeCache.h
runtime/CommonIdentifiers.cpp
runtime/CommonIdentifiers.h
runtime/CommonSlowPaths.cpp
runtime/CommonSlowPaths.h
runtime/Completion.cpp
runtime/Completion.h
runtime/ConsoleClient.cpp
runtime/ConsoleClient.h
runtime/ConsolePrototype.cpp
runtime/ConsoleTypes.h
runtime/ConstantMode.cpp [new file with mode: 0644]
runtime/ConstantMode.h
runtime/ConstructData.h
runtime/ControlFlowProfiler.cpp [new file with mode: 0644]
runtime/ControlFlowProfiler.h [new file with mode: 0644]
runtime/CustomGetterSetter.cpp
runtime/CustomGetterSetter.h
runtime/DataView.cpp
runtime/DataView.h
runtime/DateConstructor.cpp
runtime/DateConstructor.h
runtime/DateConversion.h
runtime/DateInstance.cpp
runtime/DateInstance.h
runtime/DateInstanceCache.h
runtime/DatePrototype.cpp
runtime/DatePrototype.h
runtime/DirectArguments.cpp [new file with mode: 0644]
runtime/DirectArguments.h [new file with mode: 0644]
runtime/DirectArgumentsOffset.cpp [new file with mode: 0644]
runtime/DirectArgumentsOffset.h [new file with mode: 0644]
runtime/EnumerationMode.h [new file with mode: 0644]
runtime/Error.cpp
runtime/Error.h
runtime/ErrorConstructor.cpp
runtime/ErrorConstructor.h
runtime/ErrorInstance.cpp
runtime/ErrorInstance.h
runtime/ErrorPrototype.cpp
runtime/ErrorPrototype.h
runtime/Exception.cpp [new file with mode: 0644]
runtime/Exception.h [new file with mode: 0644]
runtime/ExceptionFuzz.cpp [new file with mode: 0644]
runtime/ExceptionFuzz.h [new file with mode: 0644]
runtime/ExceptionHelpers.cpp
runtime/ExceptionHelpers.h
runtime/Executable.cpp
runtime/Executable.h
runtime/FunctionConstructor.cpp
runtime/FunctionConstructor.h
runtime/FunctionHasExecutedCache.cpp [new file with mode: 0644]
runtime/FunctionHasExecutedCache.h [new file with mode: 0644]
runtime/FunctionPrototype.cpp
runtime/FunctionPrototype.h
runtime/FunctionRareData.cpp [new file with mode: 0644]
runtime/FunctionRareData.h [new file with mode: 0644]
runtime/GenericArguments.h [new file with mode: 0644]
runtime/GenericArgumentsInlines.h [new file with mode: 0644]
runtime/GenericOffset.h [new file with mode: 0644]
runtime/GenericTypedArrayView.h
runtime/GenericTypedArrayViewInlines.h
runtime/GetterSetter.cpp
runtime/GetterSetter.h
runtime/Identifier.cpp
runtime/Identifier.h
runtime/IdentifierInlines.h
runtime/IndexingHeader.h
runtime/IndexingType.h
runtime/InferredValue.cpp [new file with mode: 0644]
runtime/InferredValue.h [new file with mode: 0644]
runtime/InitializeThreading.h
runtime/IntendedStructureChain.cpp
runtime/IntendedStructureChain.h
runtime/InternalFunction.cpp
runtime/InternalFunction.h
runtime/IntlObject.cpp [new file with mode: 0644]
runtime/IntlObject.h [new file with mode: 0644]
runtime/Intrinsic.h
runtime/IterationStatus.h [new file with mode: 0644]
runtime/IteratorOperations.cpp [new file with mode: 0644]
runtime/IteratorOperations.h [new file with mode: 0644]
runtime/IteratorPrototype.cpp [new file with mode: 0644]
runtime/IteratorPrototype.h [new file with mode: 0644]
runtime/JSAPIValueWrapper.cpp
runtime/JSAPIValueWrapper.h
runtime/JSActivation.cpp [deleted file]
runtime/JSActivation.h [deleted file]
runtime/JSArgumentsIterator.cpp [deleted file]
runtime/JSArgumentsIterator.h [deleted file]
runtime/JSArray.cpp
runtime/JSArray.h
runtime/JSArrayBuffer.cpp
runtime/JSArrayBuffer.h
runtime/JSArrayBufferConstructor.cpp
runtime/JSArrayBufferPrototype.cpp
runtime/JSArrayBufferView.cpp
runtime/JSArrayBufferView.h
runtime/JSArrayIterator.cpp
runtime/JSArrayIterator.h
runtime/JSBoundFunction.cpp
runtime/JSBoundFunction.h
runtime/JSCInlines.h
runtime/JSCJSValue.cpp
runtime/JSCJSValue.h
runtime/JSCJSValueInlines.h
runtime/JSCallee.cpp [new file with mode: 0644]
runtime/JSCallee.h [new file with mode: 0644]
runtime/JSCatchScope.cpp [new file with mode: 0644]
runtime/JSCatchScope.h [new file with mode: 0644]
runtime/JSCell.cpp
runtime/JSCell.h
runtime/JSCellInlines.h
runtime/JSConsole.cpp
runtime/JSDataView.cpp
runtime/JSDataViewPrototype.cpp
runtime/JSDataViewPrototype.h
runtime/JSDateMath.cpp
runtime/JSDateMath.h
runtime/JSDestructibleObject.h
runtime/JSEnvironmentRecord.cpp [new file with mode: 0644]
runtime/JSEnvironmentRecord.h [new file with mode: 0644]
runtime/JSFunction.cpp
runtime/JSFunction.h
runtime/JSFunctionInlines.h
runtime/JSFunctionNameScope.cpp [new file with mode: 0644]
runtime/JSFunctionNameScope.h [new file with mode: 0644]
runtime/JSGenericTypedArrayView.h
runtime/JSGenericTypedArrayViewInlines.h
runtime/JSGlobalObject.cpp
runtime/JSGlobalObject.h
runtime/JSGlobalObjectDebuggable.cpp
runtime/JSGlobalObjectDebuggable.h
runtime/JSGlobalObjectFunctions.cpp
runtime/JSGlobalObjectFunctions.h
runtime/JSJob.cpp [new file with mode: 0644]
runtime/JSJob.h [new file with mode: 0644]
runtime/JSLexicalEnvironment.cpp [new file with mode: 0644]
runtime/JSLexicalEnvironment.h [new file with mode: 0644]
runtime/JSLock.cpp
runtime/JSLock.h
runtime/JSMap.cpp
runtime/JSMap.h
runtime/JSMapIterator.cpp
runtime/JSMapIterator.h
runtime/JSNameScope.cpp
runtime/JSNameScope.h
runtime/JSNotAnObject.cpp
runtime/JSNotAnObject.h
runtime/JSONObject.cpp
runtime/JSONObject.h
runtime/JSObject.cpp
runtime/JSObject.h
runtime/JSPromise.cpp
runtime/JSPromise.h
runtime/JSPromiseConstructor.cpp
runtime/JSPromiseConstructor.h
runtime/JSPromiseDeferred.cpp
runtime/JSPromiseDeferred.h
runtime/JSPromiseFunctions.cpp [deleted file]
runtime/JSPromiseFunctions.h [deleted file]
runtime/JSPromisePrototype.cpp
runtime/JSPromisePrototype.h
runtime/JSPromiseReaction.cpp [deleted file]
runtime/JSPromiseReaction.h [deleted file]
runtime/JSPropertyNameEnumerator.cpp [new file with mode: 0644]
runtime/JSPropertyNameEnumerator.h [new file with mode: 0644]
runtime/JSPropertyNameIterator.cpp [deleted file]
runtime/JSPropertyNameIterator.h [deleted file]
runtime/JSProxy.cpp
runtime/JSProxy.h
runtime/JSScope.cpp
runtime/JSScope.h
runtime/JSSegmentedVariableObject.cpp
runtime/JSSegmentedVariableObject.h
runtime/JSSet.cpp
runtime/JSSet.h
runtime/JSSetIterator.cpp
runtime/JSSetIterator.h
runtime/JSString.cpp
runtime/JSString.h
runtime/JSStringBuilder.h
runtime/JSStringIterator.cpp [new file with mode: 0644]
runtime/JSStringIterator.h [new file with mode: 0644]
runtime/JSStringJoiner.cpp
runtime/JSStringJoiner.h
runtime/JSSymbolTableObject.cpp
runtime/JSSymbolTableObject.h
runtime/JSTemplateRegistryKey.cpp [new file with mode: 0644]
runtime/JSTemplateRegistryKey.h [new file with mode: 0644]
runtime/JSType.h
runtime/JSTypeInfo.h
runtime/JSTypedArrayConstructors.cpp
runtime/JSTypedArrayPrototypes.cpp
runtime/JSTypedArrays.cpp
runtime/JSVariableObject.cpp [deleted file]
runtime/JSVariableObject.h [deleted file]
runtime/JSWeakMap.cpp
runtime/JSWeakMap.h
runtime/JSWeakSet.cpp [new file with mode: 0644]
runtime/JSWeakSet.h [new file with mode: 0644]
runtime/JSWithScope.cpp
runtime/JSWithScope.h
runtime/JSWrapperObject.cpp
runtime/JSWrapperObject.h
runtime/LiteralParser.cpp
runtime/LiteralParser.h
runtime/Lookup.cpp
runtime/Lookup.h
runtime/MapConstructor.cpp
runtime/MapData.cpp [deleted file]
runtime/MapData.h
runtime/MapDataInlines.h [new file with mode: 0644]
runtime/MapIteratorConstructor.cpp [deleted file]
runtime/MapIteratorConstructor.h [deleted file]
runtime/MapIteratorPrototype.cpp
runtime/MapPrototype.cpp
runtime/MathCommon.cpp [new file with mode: 0644]
runtime/MathCommon.h [new file with mode: 0644]
runtime/MathObject.cpp
runtime/MathObject.h
runtime/NameConstructor.cpp [deleted file]
runtime/NameConstructor.h [deleted file]
runtime/NameInstance.cpp [deleted file]
runtime/NameInstance.h [deleted file]
runtime/NamePrototype.cpp [deleted file]
runtime/NamePrototype.h [deleted file]
runtime/NativeErrorConstructor.cpp
runtime/NativeErrorConstructor.h
runtime/NativeErrorPrototype.h
runtime/NullGetterFunction.cpp [new file with mode: 0644]
runtime/NullGetterFunction.h [new file with mode: 0644]
runtime/NullSetterFunction.cpp [new file with mode: 0644]
runtime/NullSetterFunction.h [new file with mode: 0644]
runtime/NumberConstructor.cpp
runtime/NumberConstructor.h
runtime/NumberObject.cpp
runtime/NumberObject.h
runtime/NumberPrototype.cpp
runtime/NumberPrototype.h
runtime/NumericStrings.h
runtime/ObjectConstructor.cpp
runtime/ObjectConstructor.h
runtime/ObjectPrototype.cpp
runtime/ObjectPrototype.h
runtime/Operations.cpp
runtime/Operations.h
runtime/Options.cpp
runtime/Options.h
runtime/PrivateName.h
runtime/PropertyDescriptor.cpp
runtime/PropertyDescriptor.h
runtime/PropertyMapHashTable.h
runtime/PropertyName.h
runtime/PropertyNameArray.cpp [deleted file]
runtime/PropertyNameArray.h
runtime/PropertySlot.h
runtime/PropertyTable.cpp
runtime/Protect.h
runtime/PrototypeMap.cpp
runtime/PrototypeMap.h
runtime/PutPropertySlot.h
runtime/RegExp.cpp
runtime/RegExp.h
runtime/RegExpCache.h
runtime/RegExpCachedResult.cpp
runtime/RegExpCachedResult.h
runtime/RegExpConstructor.cpp
runtime/RegExpConstructor.h
runtime/RegExpMatchesArray.cpp
runtime/RegExpMatchesArray.h
runtime/RegExpObject.cpp
runtime/RegExpObject.h
runtime/RegExpPrototype.cpp
runtime/RegExpPrototype.h
runtime/RuntimeFlags.h [new file with mode: 0644]
runtime/RuntimeType.cpp [new file with mode: 0644]
runtime/RuntimeType.h [new file with mode: 0644]
runtime/ScopeOffset.cpp [new file with mode: 0644]
runtime/ScopeOffset.h [new file with mode: 0644]
runtime/ScopedArguments.cpp [new file with mode: 0644]
runtime/ScopedArguments.h [new file with mode: 0644]
runtime/ScopedArgumentsTable.cpp [new file with mode: 0644]
runtime/ScopedArgumentsTable.h [new file with mode: 0644]
runtime/SetConstructor.cpp
runtime/SetIteratorConstructor.cpp [deleted file]
runtime/SetIteratorConstructor.h [deleted file]
runtime/SetIteratorPrototype.cpp
runtime/SetPrototype.cpp
runtime/SmallStrings.cpp
runtime/SmallStrings.h
runtime/SparseArrayValueMap.cpp
runtime/SparseArrayValueMap.h
runtime/StrictEvalActivation.cpp
runtime/StrictEvalActivation.h
runtime/StringConstructor.cpp
runtime/StringConstructor.h
runtime/StringIteratorPrototype.cpp [new file with mode: 0644]
runtime/StringIteratorPrototype.h [new file with mode: 0644]
runtime/StringObject.cpp
runtime/StringObject.h
runtime/StringPrototype.cpp
runtime/StringPrototype.h
runtime/StringRecursionChecker.h
runtime/Structure.cpp
runtime/Structure.h
runtime/StructureChain.cpp
runtime/StructureChain.h
runtime/StructureIDTable.cpp
runtime/StructureIDTable.h
runtime/StructureInlines.h
runtime/StructureRareData.cpp
runtime/StructureRareData.h
runtime/StructureTransitionTable.h
runtime/Symbol.cpp [new file with mode: 0644]
runtime/Symbol.h [new file with mode: 0644]
runtime/SymbolConstructor.cpp [new file with mode: 0644]
runtime/SymbolConstructor.h [new file with mode: 0644]
runtime/SymbolObject.cpp [new file with mode: 0644]
runtime/SymbolObject.h [new file with mode: 0644]
runtime/SymbolPrototype.cpp [new file with mode: 0644]
runtime/SymbolPrototype.h [new file with mode: 0644]
runtime/SymbolTable.cpp
runtime/SymbolTable.h
runtime/TemplateRegistry.cpp [new file with mode: 0644]
runtime/TemplateRegistry.h [new file with mode: 0644]
runtime/TemplateRegistryKey.h [new file with mode: 0644]
runtime/TestRunnerUtils.h
runtime/Tracing.d
runtime/Tracing.h
runtime/TypeLocationCache.cpp [new file with mode: 0644]
runtime/TypeLocationCache.h [new file with mode: 0644]
runtime/TypeProfiler.cpp [new file with mode: 0644]
runtime/TypeProfiler.h [new file with mode: 0644]
runtime/TypeProfilerLog.cpp [new file with mode: 0644]
runtime/TypeProfilerLog.h [new file with mode: 0644]
runtime/TypeSet.cpp [new file with mode: 0644]
runtime/TypeSet.h [new file with mode: 0644]
runtime/TypedArrayBase.h
runtime/TypeofType.cpp [new file with mode: 0644]
runtime/TypeofType.h [new file with mode: 0644]
runtime/VM.cpp
runtime/VM.h
runtime/VMEntryScope.cpp
runtime/VMEntryScope.h
runtime/VarOffset.cpp [new file with mode: 0644]
runtime/VarOffset.h [new file with mode: 0644]
runtime/Watchdog.cpp
runtime/Watchdog.h
runtime/WatchdogMac.cpp
runtime/WatchdogNone.cpp
runtime/WeakGCMap.h
runtime/WeakGCMapInlines.h [new file with mode: 0644]
runtime/WeakMapConstructor.cpp
runtime/WeakMapData.cpp
runtime/WeakMapData.h
runtime/WeakMapPrototype.cpp
runtime/WeakSetConstructor.cpp [new file with mode: 0644]
runtime/WeakSetConstructor.h [new file with mode: 0644]
runtime/WeakSetPrototype.cpp [new file with mode: 0644]
runtime/WeakSetPrototype.h [new file with mode: 0644]
runtime/WriteBarrier.h
testRegExp.cpp
tested-symbols.symlst [new file with mode: 0644]
tests/controlFlowProfiler.yaml [new file with mode: 0644]
tests/controlFlowProfiler/brace-location.js [new file with mode: 0644]
tests/controlFlowProfiler/conditional-expression.js [new file with mode: 0644]
tests/controlFlowProfiler/driver/driver.js [new file with mode: 0644]
tests/controlFlowProfiler/if-statement.js [new file with mode: 0644]
tests/controlFlowProfiler/loop-statements.js [new file with mode: 0644]
tests/controlFlowProfiler/switch-statements.js [new file with mode: 0644]
tests/controlFlowProfiler/test-jit.js [new file with mode: 0644]
tests/exceptionFuzz.yaml
tests/exceptionFuzz/3d-cube.js
tests/exceptionFuzz/date-format-xparb.js
tests/exceptionFuzz/earley-boyer.js
tests/executableAllocationFuzz.yaml [new file with mode: 0644]
tests/executableAllocationFuzz/v8-raytrace.js [new file with mode: 0644]
tests/mozilla/ecma/Date/15.9.1.1-1.js
tests/mozilla/ecma/Date/15.9.1.1-2.js
tests/mozilla/ecma/Date/15.9.2.1.js
tests/mozilla/ecma/Date/15.9.2.2-1.js
tests/mozilla/ecma/Date/15.9.2.2-2.js
tests/mozilla/ecma/Date/15.9.2.2-3.js
tests/mozilla/ecma/Date/15.9.2.2-4.js
tests/mozilla/ecma/Date/15.9.2.2-5.js
tests/mozilla/ecma/Date/15.9.2.2-6.js
tests/mozilla/ecma_3/Unicode/uc-003.js
tests/mozilla/js1_2/function/tostring-1.js
tests/mozilla/mozilla-tests.yaml
tests/stress/activation-sink-default-value.js [new file with mode: 0644]
tests/stress/activation-sink-osrexit-default-value.js [new file with mode: 0644]
tests/stress/activation-sink-osrexit.js [new file with mode: 0644]
tests/stress/activation-sink.js [new file with mode: 0644]
tests/stress/add-overflows-after-not-equal.js [new file with mode: 0644]
tests/stress/arguments-bizarre-behavior.js [new file with mode: 0644]
tests/stress/arguments-bizarre-behaviour-disable-enumerability.js [new file with mode: 0644]
tests/stress/arguments-callee-uninitialized.js [new file with mode: 0644]
tests/stress/arguments-captured.js [new file with mode: 0644]
tests/stress/arguments-custom-properties-gc.js [new file with mode: 0644]
tests/stress/arguments-exit-fixed.js [new file with mode: 0644]
tests/stress/arguments-exit-strict-mode-fixed.js [new file with mode: 0644]
tests/stress/arguments-exit-strict-mode.js [new file with mode: 0644]
tests/stress/arguments-exit.js [new file with mode: 0644]
tests/stress/arguments-inlined-exit-strict-mode-fixed.js [new file with mode: 0644]
tests/stress/arguments-inlined-exit-strict-mode.js [new file with mode: 0644]
tests/stress/arguments-inlined-exit.js [new file with mode: 0644]
tests/stress/arguments-interference-cfg.js [new file with mode: 0644]
tests/stress/arguments-interference.js [new file with mode: 0644]
tests/stress/arguments-iterator.js [new file with mode: 0644]
tests/stress/arith-add-with-constants.js [new file with mode: 0644]
tests/stress/arith-modulo-node-behaviors.js [new file with mode: 0644]
tests/stress/arith-mul-with-constants.js [new file with mode: 0644]
tests/stress/array-copywithin.js [new file with mode: 0644]
tests/stress/array-fill-put-by-val.js [new file with mode: 0644]
tests/stress/array-filter-put-by-val-direct.js [new file with mode: 0644]
tests/stress/array-find-does-not-lookup-twice.js [new file with mode: 0644]
tests/stress/array-from-abs-and-floor.js [new file with mode: 0644]
tests/stress/array-from-put-by-val-direct.js [new file with mode: 0644]
tests/stress/array-from-set-length.js [new file with mode: 0644]
tests/stress/array-from-with-accessors.js [new file with mode: 0644]
tests/stress/array-from-with-iterable.js [new file with mode: 0644]
tests/stress/array-from-with-iterator.js [new file with mode: 0644]
tests/stress/array-iterators-next-with-call.js [new file with mode: 0644]
tests/stress/array-iterators-next.js [new file with mode: 0644]
tests/stress/array-length-array-storage-plain-object.js [new file with mode: 0644]
tests/stress/array-length-plain-object.js [new file with mode: 0644]
tests/stress/array-map-put-by-val-direct.js [new file with mode: 0644]
tests/stress/arrayify-to-structure-contradiction.js [new file with mode: 0644]
tests/stress/assignment-in-function-call-bracket-node.js [new file with mode: 0644]
tests/stress/branch-may-exit-due-to-object-or-other-use-kind.js [new file with mode: 0644]
tests/stress/builtin-function-is-construct-type-none.js [new file with mode: 0644]
tests/stress/cached-prototype-setter.js [new file with mode: 0644]
tests/stress/call-forward-varargs-for-inlined-escaped-arguments.js [new file with mode: 0644]
tests/stress/call-varargs-length-effects.js [new file with mode: 0644]
tests/stress/call-varargs-with-different-arguments-length-after-warmup.js [new file with mode: 0644]
tests/stress/class-syntax-derived-default-constructor.js [new file with mode: 0644]
tests/stress/class-syntax-no-loop-tdz.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz-in-catch.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz-in-conditional.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz-in-eval.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz-in-loop.js [new file with mode: 0644]
tests/stress/class-syntax-no-tdz.js [new file with mode: 0644]
tests/stress/class-syntax-tdz-in-catch.js [new file with mode: 0644]
tests/stress/class-syntax-tdz-in-conditional.js [new file with mode: 0644]
tests/stress/class-syntax-tdz-in-eval.js [new file with mode: 0644]
tests/stress/class-syntax-tdz-in-loop.js [new file with mode: 0644]
tests/stress/class-syntax-tdz.js [new file with mode: 0644]
tests/stress/cloned-arguments-get-by-val-double-array.js [new file with mode: 0644]
tests/stress/cloned-arguments-should-visit-callee-during-gc.js [new file with mode: 0644]
tests/stress/closure-call-exit.js [new file with mode: 0644]
tests/stress/construct-forward-varargs-for-inlined-escaped-arguments.js [new file with mode: 0644]
tests/stress/construct-varargs-inline-smaller-Foo.js [new file with mode: 0644]
tests/stress/construct-varargs-inline.js [new file with mode: 0644]
tests/stress/construct-varargs-no-inline.js [new file with mode: 0644]
tests/stress/constructor-with-return.js [new file with mode: 0644]
tests/stress/create-this-with-callee-variants.js [new file with mode: 0644]
tests/stress/custom-iterators.js [new file with mode: 0644]
tests/stress/dead-get-closure-var.js [new file with mode: 0644]
tests/stress/dead-osr-entry-value.js [new file with mode: 0644]
tests/stress/dead-speculating-argument-use.js [new file with mode: 0644]
tests/stress/destructuring-assignment-accepts-iterables.js [new file with mode: 0644]
tests/stress/dfg-put-by-val-direct-with-edge-numbers.js [new file with mode: 0644]
tests/stress/dfg-rare-data.js [new file with mode: 0644]
tests/stress/dfg-to-primitive-pass-symbol.js [new file with mode: 0644]
tests/stress/disable-function-dot-arguments.js [new file with mode: 0644]
tests/stress/double-rep-with-non-cell.js [new file with mode: 0644]
tests/stress/double-rep-with-null.js [new file with mode: 0644]
tests/stress/double-rep-with-undefined.js [new file with mode: 0644]
tests/stress/elidable-new-object-roflcopter-then-exit.js [new file with mode: 0644]
tests/stress/elide-new-object-dag-then-exit.js [new file with mode: 0644]
tests/stress/empty_eos_regex_split.js [new file with mode: 0644]
tests/stress/equality-type-checking.js [new file with mode: 0644]
tests/stress/equals-masquerader.js
tests/stress/escape-object-in-diamond-then-exit.js [new file with mode: 0644]
tests/stress/eval-script-contains-null-character.js [new file with mode: 0644]
tests/stress/exception-in-to-property-key-should-be-handled-early-in-object-methods.js [new file with mode: 0644]
tests/stress/exception-in-to-property-key-should-be-handled-early.js [new file with mode: 0644]
tests/stress/exit-from-getter.js [new file with mode: 0644]
tests/stress/exit-from-setter.js [new file with mode: 0644]
tests/stress/fold-based-on-int32-proof-mul-branch.js [new file with mode: 0644]
tests/stress/fold-based-on-int32-proof-mul.js [new file with mode: 0644]
tests/stress/fold-based-on-int32-proof-or-zero.js [new file with mode: 0644]
tests/stress/fold-based-on-int32-proof.js [new file with mode: 0644]
tests/stress/fold-load-varargs-arity-check-fail-barely.js [new file with mode: 0644]
tests/stress/fold-load-varargs-arity-check-fail.js [new file with mode: 0644]
tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js [new file with mode: 0644]
tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js [new file with mode: 0644]
tests/stress/fold-profiled-call-to-call.js [new file with mode: 0644]
tests/stress/fold-typed-array-properties.js
tests/stress/for-in-array-mode.js [new file with mode: 0644]
tests/stress/for-in-base-reassigned-later-and-change-structure.js [new file with mode: 0644]
tests/stress/for-in-base-reassigned-later.js [new file with mode: 0644]
tests/stress/for-in-base-reassigned.js [new file with mode: 0644]
tests/stress/for-in-capture-string-loop-var.js [new file with mode: 0644]
tests/stress/for-in-delete-during-iteration.js [new file with mode: 0644]
tests/stress/for-in-modify-int-loop-var.js [new file with mode: 0644]
tests/stress/for-in-modify-string-loop-var.js [new file with mode: 0644]
tests/stress/for-in-prototype.js [new file with mode: 0644]
tests/stress/for-in-proxy-target-changed-structure.js [new file with mode: 0644]
tests/stress/for-in-proxy.js [new file with mode: 0644]
tests/stress/for-in-shadow-prototype-property.js [new file with mode: 0644]
tests/stress/for-in-string.js [new file with mode: 0644]
tests/stress/for-in-tests.js [new file with mode: 0644]
tests/stress/for-in-typed-array.js [new file with mode: 0644]
tests/stress/forward-varargs-for-inlined-escaped-arguments.js [new file with mode: 0644]
tests/stress/freeze_leek.js [new file with mode: 0644]
tests/stress/ftl-arithcos.js
tests/stress/ftl-checkin-variable.js [new file with mode: 0644]
tests/stress/ftl-checkin.js [new file with mode: 0644]
tests/stress/ftl-getmyargumentslength-inline.js [new file with mode: 0644]
tests/stress/ftl-in-overflow.js [new file with mode: 0644]
tests/stress/ftl-library-exception.js [new file with mode: 0644]
tests/stress/ftl-library-inline-gettimezoneoffset.js [new file with mode: 0644]
tests/stress/ftl-library-inlining-exceptions-dataview.js [new file with mode: 0644]
tests/stress/ftl-library-inlining-exceptions.js [new file with mode: 0644]
tests/stress/ftl-library-inlining-loops.js [new file with mode: 0644]
tests/stress/ftl-library-inlining-random.js [new file with mode: 0644]
tests/stress/ftl-library-substring.js [new file with mode: 0644]
tests/stress/ftl-switch-string-slow-duplicate-cases.js [new file with mode: 0644]
tests/stress/function-expression-exit.js [new file with mode: 0644]
tests/stress/function-name-scope.js [new file with mode: 0644]
tests/stress/function-reentry-infer-on-self.js [new file with mode: 0644]
tests/stress/function-sinking-no-double-allocate.js [new file with mode: 0644]
tests/stress/function-sinking-osrexit.js [new file with mode: 0644]
tests/stress/function-sinking-put.js [new file with mode: 0644]
tests/stress/get-argument-by-val-in-inlined-varargs-call-out-of-bounds.js [new file with mode: 0644]
tests/stress/get-argument-by-val-safe-in-inlined-varargs-call-out-of-bounds.js [new file with mode: 0644]
tests/stress/get-by-val-out-of-bounds-basics.js [new file with mode: 0644]
tests/stress/get-declared-unpassed-argument-in-direct-arguments.js [new file with mode: 0644]
tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js [new file with mode: 0644]
tests/stress/get-local-elimination.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-creates-arguments.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-for-inlined-escaped-arguments.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-out-of-bounds.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-safe-out-of-bounds.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-safe-wrap-around.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js [new file with mode: 0644]
tests/stress/get-my-argument-by-val-wrap-around.js [new file with mode: 0644]
tests/stress/get-stack-identity-due-to-sinking.js [new file with mode: 0644]
tests/stress/get-stack-mapping-with-dead-get-stack.js [new file with mode: 0644]
tests/stress/get-stack-mapping.js [new file with mode: 0644]
tests/stress/global-environment-does-not-trap-unscopables.js [new file with mode: 0644]
tests/stress/goofy-function-reentry-incorrect-inference.js [new file with mode: 0644]
tests/stress/has-custom-properties.js [new file with mode: 0644]
tests/stress/infer-constant-global-property.js [new file with mode: 0644]
tests/stress/infer-constant-property.js [new file with mode: 0644]
tests/stress/infer-uninitialized-closure-var.js [new file with mode: 0644]
tests/stress/initialize_functions_after_arguments.js [new file with mode: 0644]
tests/stress/inline-call-that-doesnt-use-all-args.js [new file with mode: 0644]
tests/stress/inline-varargs-get-arguments.js [new file with mode: 0644]
tests/stress/int32array-transition-on-nan.js [new file with mode: 0644]
tests/stress/iterator-functions.js [new file with mode: 0644]
tests/stress/iterator-names.js [new file with mode: 0644]
tests/stress/iterator-prototype.js [new file with mode: 0644]
tests/stress/iterator-return-beyond-multiple-iteration-scopes.js [new file with mode: 0644]
tests/stress/iterators-shape.js [new file with mode: 0644]
tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js [new file with mode: 0644]
tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js [new file with mode: 0644]
tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js [new file with mode: 0644]
tests/stress/liveness-pruning-needed-for-osr-availability-eager.js [new file with mode: 0644]
tests/stress/liveness-pruning-needed-for-osr-availability.js [new file with mode: 0644]
tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js [new file with mode: 0644]
tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js [new file with mode: 0644]
tests/stress/load-varargs-elimination-bounds-check-barely.js [new file with mode: 0644]
tests/stress/load-varargs-elimination-bounds-check.js [new file with mode: 0644]
tests/stress/load-varargs-then-inlined-call-and-exit-strict.js [new file with mode: 0644]
tests/stress/load-varargs-then-inlined-call-and-exit.js [new file with mode: 0644]
tests/stress/load-varargs-then-inlined-call-exit-in-foo.js [new file with mode: 0644]
tests/stress/load-varargs-then-inlined-call-inlined.js [new file with mode: 0644]
tests/stress/load-varargs-then-inlined-call.js [new file with mode: 0644]
tests/stress/logical-not-masquerades.js [new file with mode: 0644]
tests/stress/many-sunken-locals.js [new file with mode: 0644]
tests/stress/map-constructor-adder.js [new file with mode: 0644]
tests/stress/map-constructor.js [new file with mode: 0644]
tests/stress/map-iterators-next.js [new file with mode: 0644]
tests/stress/materialize-past-butterfly-allocation.js [new file with mode: 0644]
tests/stress/materialize-past-put-structure.js [new file with mode: 0644]
tests/stress/math-abs-positive.js [new file with mode: 0644]
tests/stress/math-clz32-basics.js [new file with mode: 0644]
tests/stress/math-log-basics.js [new file with mode: 0644]
tests/stress/math-log-with-constants.js [new file with mode: 0644]
tests/stress/math-pow-basics.js [new file with mode: 0644]
tests/stress/math-pow-becomes-custom-function.js [new file with mode: 0644]
tests/stress/math-pow-integer-exponent-fastpath.js [new file with mode: 0644]
tests/stress/math-pow-nan-behaviors.js [new file with mode: 0644]
tests/stress/math-pow-with-constants.js [new file with mode: 0644]
tests/stress/math-pow-with-never-NaN-exponent.js [new file with mode: 0644]
tests/stress/math-round-arith-rounding-mode.js [new file with mode: 0644]
tests/stress/math-round-basics.js [new file with mode: 0644]
tests/stress/math-sqrt-basics-disable-architecture-specific-optimizations.js [new file with mode: 0644]
tests/stress/math-sqrt-basics.js [new file with mode: 0644]
tests/stress/misc-is-object-or-null.js [new file with mode: 0644]
tests/stress/modify-map-during-iteration.js [new file with mode: 0644]
tests/stress/modify-set-during-iteration.js [new file with mode: 0644]
tests/stress/multi-get-by-offset-dce.js [new file with mode: 0644]
tests/stress/multi-put-by-offset-multiple-transitions.js [new file with mode: 0644]
tests/stress/new-array-storage-array-with-size.js
tests/stress/new-array-then-exit.js [new file with mode: 0644]
tests/stress/new-largeish-contiguous-array-with-size.js [new file with mode: 0644]
tests/stress/no-abc-skippy-loop.js [new file with mode: 0644]
tests/stress/no-abc-skippy-paired-loop.js [new file with mode: 0644]
tests/stress/object-allocation-sinking-with-uninitialized-property-on-one-path.js [new file with mode: 0644]
tests/stress/object-escapes-in-loop.js [new file with mode: 0644]
tests/stress/object-freeze-accept-non-object.js [new file with mode: 0644]
tests/stress/object-get-own-property-descriptor-perform-to-object.js [new file with mode: 0644]
tests/stress/object-get-own-property-names-perform-to-object.js [new file with mode: 0644]
tests/stress/object-get-own-property-symbols-perform-to-object.js [new file with mode: 0644]
tests/stress/object-get-own-property-symbols.js [new file with mode: 0644]
tests/stress/object-get-prototype-of-perform-to-object.js [new file with mode: 0644]
tests/stress/object-is-extensible-accept-non-object.js [new file with mode: 0644]
tests/stress/object-is-frozen-accept-non-object.js [new file with mode: 0644]
tests/stress/object-is-sealed-accept-non-object.js [new file with mode: 0644]
tests/stress/object-keys-perform-to-object.js [new file with mode: 0644]
tests/stress/object-prevent-extensions-accept-non-object.js [new file with mode: 0644]
tests/stress/object-seal-accept-non-object.js [new file with mode: 0644]
tests/stress/obviously-elidable-new-object-then-exit.js [new file with mode: 0644]
tests/stress/op-push-name-scope-crashes-profiler.js [new file with mode: 0644]
tests/stress/other-is-object-or-null.js [new file with mode: 0644]
tests/stress/phantom-direct-arguments-clobber-argument-count.js [new file with mode: 0644]
tests/stress/phantom-direct-arguments-clobber-callee.js [new file with mode: 0644]
tests/stress/phantom-inadequacy.js [new file with mode: 0644]
tests/stress/poly-call-exit-this.js [new file with mode: 0644]
tests/stress/poly-call-exit.js [new file with mode: 0644]
tests/stress/poly-chain-getter.js [new file with mode: 0644]
tests/stress/poly-chain-setter.js [new file with mode: 0644]
tests/stress/poly-chain-then-getter.js [new file with mode: 0644]
tests/stress/poly-chain-then-setter.js [new file with mode: 0644]
tests/stress/poly-getter-combo.js [new file with mode: 0644]
tests/stress/poly-getter-then-chain.js [new file with mode: 0644]
tests/stress/poly-getter-then-self.js [new file with mode: 0644]
tests/stress/poly-self-getter.js [new file with mode: 0644]
tests/stress/poly-self-then-getter.js [new file with mode: 0644]
tests/stress/poly-setter-combo.js [new file with mode: 0644]
tests/stress/poly-setter-then-self.js [new file with mode: 0644]
tests/stress/proto-setter.js [new file with mode: 0644]
tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js [new file with mode: 0644]
tests/stress/put-by-id-build-list-order-recurse.js [new file with mode: 0644]
tests/stress/put-by-id-direct-should-be-done-for-non-index-property.js [new file with mode: 0644]
tests/stress/put-by-id-on-new-object-after-prototype-transition-non-strict.js [new file with mode: 0644]
tests/stress/put-by-id-on-new-object-after-prototype-transition-strict.js [new file with mode: 0644]
tests/stress/put-by-id-strict-build-list-order.js [new file with mode: 0644]
tests/stress/put-by-val-out-of-bounds-basics.js [new file with mode: 0644]
tests/stress/put-local-conservative.js [new file with mode: 0644]
tests/stress/raise-error-in-iterator-close.js [new file with mode: 0644]
tests/stress/real-forward-varargs-for-inlined-escaped-arguments.js [new file with mode: 0644]
tests/stress/recursive_property_redefine_during_inline_caching.js [new file with mode: 0644]
tests/stress/regress-141883.js [new file with mode: 0644]
tests/stress/remove-phantom-after-setlocal.js [new file with mode: 0644]
tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js [new file with mode: 0644]
tests/stress/repeated-arity-check-fail.js
tests/stress/reserved-word-with-escape.js [new file with mode: 0644]
tests/stress/rest-elements.js [new file with mode: 0644]
tests/stress/scoped-arguments-array-length.js [new file with mode: 0644]
tests/stress/scoped-then-direct-arguments-get-by-val-in-baseline.js [new file with mode: 0644]
tests/stress/set-constructor-adder.js [new file with mode: 0644]
tests/stress/set-constructor.js [new file with mode: 0644]
tests/stress/set-iterators-next.js [new file with mode: 0644]
tests/stress/simplify-varargs-mandatory-minimum-smaller-than-limit.js [new file with mode: 0644]
tests/stress/singleton-scope-then-overwrite.js [new file with mode: 0644]
tests/stress/singleton-scope-then-realloc-and-overwrite.js [new file with mode: 0644]
tests/stress/singleton-scope-then-realloc.js [new file with mode: 0644]
tests/stress/sink-arguments-past-invalid-check-dfg.js [new file with mode: 0644]
tests/stress/sink-arguments-past-invalid-check-int32-dfg.js [new file with mode: 0644]
tests/stress/sink-arguments-past-invalid-check-int32.js [new file with mode: 0644]
tests/stress/sink-arguments-past-invalid-check-sneakier.js [new file with mode: 0644]
tests/stress/sink-arguments-past-invalid-check.js [new file with mode: 0644]
tests/stress/sink-function-past-invalid-check-sneakier.js [new file with mode: 0644]
tests/stress/sink-function-past-invalid-check-sneaky.js [new file with mode: 0644]
tests/stress/sink-object-past-invalid-check-int32.js [new file with mode: 0644]
tests/stress/sink-object-past-invalid-check-sneakier.js [new file with mode: 0644]
tests/stress/sink-object-past-invalid-check-sneaky.js [new file with mode: 0644]
tests/stress/sink-object-past-invalid-check.js [new file with mode: 0644]
tests/stress/sink_checkstructure.js [new file with mode: 0644]
tests/stress/sort-array-with-undecided.js [new file with mode: 0644]
tests/stress/sparse_splice.js [new file with mode: 0644]
tests/stress/static-function-delete.js [new file with mode: 0644]
tests/stress/static-function-put.js [new file with mode: 0644]
tests/stress/static-getter-delete.js [new file with mode: 0644]
tests/stress/static-getter-descriptors.js [new file with mode: 0644]
tests/stress/static-getter-enumeration.js [new file with mode: 0644]
tests/stress/static-getter-get.js [new file with mode: 0644]
tests/stress/static-getter-in-names.js [new file with mode: 0644]
tests/stress/static-getter-names.js [new file with mode: 0644]
tests/stress/static-getter-put.js [new file with mode: 0644]
tests/stress/string-from-code-point.js [new file with mode: 0644]
tests/stress/string-iterators.js [new file with mode: 0644]
tests/stress/string-raw.js [new file with mode: 0644]
tests/stress/sub-overflows-after-not-equal.js [new file with mode: 0644]
tests/stress/switch-typeof-indirect.js [new file with mode: 0644]
tests/stress/switch-typeof-slightly-indirect.js [new file with mode: 0644]
tests/stress/switch-typeof.js [new file with mode: 0644]
tests/stress/symbol-and-string-constructor.js [new file with mode: 0644]
tests/stress/symbol-define-property.js [new file with mode: 0644]
tests/stress/symbol-registry.js [new file with mode: 0644]
tests/stress/symbol-seal-and-freeze.js [new file with mode: 0644]
tests/stress/symbol-with-json.js [new file with mode: 0644]
tests/stress/tagged-templates-identity.js [new file with mode: 0644]
tests/stress/tagged-templates-raw-strings.js [new file with mode: 0644]
tests/stress/tagged-templates-syntax.js [new file with mode: 0644]
tests/stress/tagged-templates-template-object.js [new file with mode: 0644]
tests/stress/tagged-templates-this.js [new file with mode: 0644]
tests/stress/tagged-templates.js [new file with mode: 0644]
tests/stress/template-literal-line-terminators.js [new file with mode: 0644]
tests/stress/template-literal-syntax.js [new file with mode: 0644]
tests/stress/template-literal.js [new file with mode: 0644]
tests/stress/throw-from-ftl-in-loop.js [new file with mode: 0644]
tests/stress/throw-from-ftl.js [new file with mode: 0644]
tests/stress/toprimitive-speculated-types.js [new file with mode: 0644]
tests/stress/trailing-comma-in-patterns.js [new file with mode: 0644]
tests/stress/type-of-functions-and-objects.js [new file with mode: 0644]
tests/stress/typed-array-byte-offset.js [new file with mode: 0644]
tests/stress/typed-array-get-by-val-profiling.js [new file with mode: 0644]
tests/stress/typed-array-put-by-val-profiling.js [new file with mode: 0644]
tests/stress/typeof-symbol.js [new file with mode: 0644]
tests/stress/unscopables.js [new file with mode: 0644]
tests/stress/values-unscopables.js [new file with mode: 0644]
tests/stress/varargs-closure-inlined-exit-strict-mode.js [new file with mode: 0644]
tests/stress/varargs-closure-inlined-exit.js [new file with mode: 0644]
tests/stress/varargs-exit.js [new file with mode: 0644]
tests/stress/varargs-inlined-exit.js [new file with mode: 0644]
tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js [new file with mode: 0644]
tests/stress/varargs-inlined-simple-exit-aliasing-weird.js [new file with mode: 0644]
tests/stress/varargs-inlined-simple-exit-aliasing.js [new file with mode: 0644]
tests/stress/varargs-inlined-simple-exit.js [new file with mode: 0644]
tests/stress/varargs-inlining-underflow.js [new file with mode: 0644]
tests/stress/varargs-then-slow-call.js [new file with mode: 0644]
tests/stress/varargs-too-few-arguments.js [new file with mode: 0644]
tests/stress/varargs-varargs-closure-inlined-exit.js [new file with mode: 0644]
tests/stress/varargs-varargs-inlined-exit-strict-mode.js [new file with mode: 0644]
tests/stress/varargs-varargs-inlined-exit.js [new file with mode: 0644]
tests/stress/weak-map-constructor-adder.js [new file with mode: 0644]
tests/stress/weak-map-constructor.js [new file with mode: 0644]
tests/stress/weak-set-constructor-adder.js [new file with mode: 0644]
tests/stress/weak-set-constructor.js [new file with mode: 0644]
tests/stress/weird-getter-counter.js [new file with mode: 0644]
tests/stress/weird-put-stack-varargs.js [new file with mode: 0644]
tests/stress/weird-setter-counter-syntactic.js [new file with mode: 0644]
tests/stress/weird-setter-counter.js [new file with mode: 0644]
tests/typeProfiler.yaml [new file with mode: 0644]
tests/typeProfiler/basic.js [new file with mode: 0644]
tests/typeProfiler/captured.js [new file with mode: 0644]
tests/typeProfiler/classes.js [new file with mode: 0644]
tests/typeProfiler/dfg-jit-optimizations.js [new file with mode: 0644]
tests/typeProfiler/dictionary-mode.js [new file with mode: 0644]
tests/typeProfiler/driver/driver.js [new file with mode: 0644]
tests/typeProfiler/inheritance.js [new file with mode: 0644]
tests/typeProfiler/loop.js [new file with mode: 0644]
tests/typeProfiler/optional-fields.js [new file with mode: 0644]
tests/typeProfiler/overflow.js [new file with mode: 0644]
tests/typeProfiler/return.js [new file with mode: 0644]
tests/typeProfiler/symbol.js [new file with mode: 0644]
tools/CodeProfile.cpp
tools/CodeProfile.h
tools/CodeProfiling.cpp
tools/FunctionOverrides.cpp [new file with mode: 0644]
tools/FunctionOverrides.h [new file with mode: 0644]
tools/JSDollarVM.cpp [new file with mode: 0644]
tools/JSDollarVM.h [new file with mode: 0644]
tools/JSDollarVMPrototype.cpp [new file with mode: 0644]
tools/JSDollarVMPrototype.h [new file with mode: 0644]
yarr/RegularExpression.cpp
yarr/Yarr.h
yarr/YarrCanonicalizeUCS2.cpp
yarr/YarrCanonicalizeUCS2.h
yarr/YarrInterpreter.cpp
yarr/YarrInterpreter.h
yarr/YarrJIT.cpp
yarr/YarrPattern.cpp
yarr/YarrPattern.h

index 90903977179cfdb1bcfc72c0ad23745659d0a9db..14194b6f9b081ef02bc8838efe7077b0b73c0baa 100644 (file)
@@ -45,8 +45,6 @@ public:
     void setWrappedObject(void*);
 
 protected:
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-    
     JSAPIWrapperObject(VM&, Structure*);
 
 private:
index 897e96f44e0f41c391bb8d660ef730740efcc1ed..ef54602a4a2f6451086683581292c4c0432b9d5e 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "JSAPIWrapperObject.h"
 
-#include "DelayedReleaseScope.h"
 #include "JSCInlines.h"
 #include "JSCallbackObject.h"
 #include "JSVirtualMachineInternal.h"
@@ -68,7 +67,7 @@ bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::
 
 namespace JSC {
     
-template <> const ClassInfo JSCallbackObject<JSAPIWrapperObject>::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject<JSAPIWrapperObject>::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
 
 template<> const bool JSCallbackObject<JSAPIWrapperObject>::needsDestruction = true;
 
@@ -99,7 +98,6 @@ void JSAPIWrapperObject::setWrappedObject(void* wrappedObject)
 void JSAPIWrapperObject::visitChildren(JSCell* cell, JSC::SlotVisitor& visitor)
 {
     JSAPIWrapperObject* thisObject = JSC::jsCast<JSAPIWrapperObject*>(cell);
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
     Base::visitChildren(cell, visitor);
 
     if (thisObject->wrappedObject())
index 31bdf2b94d487a3d13a2ef3344f0f01447b25778..3c5594b670bed7926b44c145a51bd17be729d00a 100644 (file)
@@ -30,6 +30,8 @@
 #include "APICast.h"
 #include "CallFrame.h"
 #include "Completion.h"
+#include "Exception.h"
+#include "GCActivityCallback.h"
 #include "InitializeThreading.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
@@ -60,14 +62,14 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
 
     // evaluate sets "this" to the global object if it is NULL
     JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
-    SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+    SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
 
-    JSValue evaluationException;
-    JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException);
+    NakedPtr<Exception> evaluationException;
+    JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, evaluationException);
 
     if (evaluationException) {
         if (exception)
-            *exception = toRef(exec, evaluationException);
+            *exception = toRef(exec, evaluationException->value());
 #if ENABLE(REMOTE_INSPECTOR)
         // FIXME: If we have a debugger attached we could learn about ParseError exceptions through
         // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The
@@ -97,7 +99,7 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
 
     startingLineNumber = std::max(1, startingLineNumber);
 
-    SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+    SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
     
     JSValue syntaxException;
     bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
@@ -106,7 +108,8 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
         if (exception)
             *exception = toRef(exec, syntaxException);
 #if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, syntaxException);
+        Exception* exception = Exception::create(exec->vm(), syntaxException);
+        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
 #endif
         return false;
     }
@@ -138,7 +141,8 @@ void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
     }
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
-    exec->vm().heap.reportExtraMemoryCost(size);
+
+    exec->vm().heap.deprecatedReportExtraMemory(size);
 }
 
 extern "C" JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);
index 7d0ea3a53d43c21d89d3a8b03831cba1d487ef53..4c9608828ef094ce2fb8c70b09344b4d9b173962 100644 (file)
@@ -84,11 +84,6 @@ typedef struct OpaqueJSValue* JSObjectRef;
 #define JS_EXPORT
 #endif /* defined(JS_NO_EXPORT) */
 
-/* JS tests uses WTF but has no config.h, so we need to set the export defines here. */
-#ifndef WTF_EXPORT_PRIVATE
-#define WTF_EXPORT_PRIVATE JS_EXPORT
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -141,11 +136,7 @@ JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
 
 /* Enable the Objective-C API for platforms with a modern runtime. */
 #if !defined(JSC_OBJC_API_ENABLED)
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
 #define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
-#else
-#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
-#endif
 #endif
 
 #endif /* JSBase_h */
index b5aeee418ca064e0adfe5e6d28fd6d681ee23598..65e66dc13f170562ab8e43fde8a57db04f621469 100644 (file)
@@ -37,7 +37,7 @@
 
 namespace JSC {
 
-const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
+const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
 
 JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
     : JSDestructibleObject(globalObject->vm(), structure)
index d2792f8691b34668bc5e7bb391305373b8f761a8..f178936e00cb0f2522a2f8d0208836a816f654cd 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
 class JSCallbackConstructor : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
 
     static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback) 
     {
@@ -56,7 +57,6 @@ public:
 protected:
     JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback);
     void finishCreation(JSGlobalObject*, JSClassRef);
-    static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
 
 private:
     friend struct APICallbackFunction;
index afdac63550de8d02097fe2e7b263e5ab69dcc603..047fcd01c228c6c0637466f9362a0fced4d48418 100644 (file)
@@ -42,7 +42,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCallbackFunction);
 
-const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
+const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
 
 JSCallbackFunction::JSCallbackFunction(VM& vm, Structure* structure, JSObjectCallAsFunctionCallback callback)
     : InternalFunction(vm, structure)
index 53e51e7b882f97c2471188701d3fc19a461378ee..02b38fde75eb2492c7941cd3c9c4324e3f90b428 100644 (file)
@@ -34,8 +34,8 @@
 namespace JSC {
 
 // Define the two types of JSCallbackObjects we support.
-template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
-template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
 
 template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction = true;
 template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false;
@@ -61,15 +61,4 @@ Structure* JSCallbackObject<JSGlobalObject>::createStructure(VM& vm, JSGlobalObj
     return Structure::create(vm, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), info()); 
 }
 
-void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)
-{
-    JSClassRef jsClass = static_cast<JSClassRef>(context);
-    JSObjectRef thisRef = toRef(static_cast<JSObject*>(handle.get().asCell()));
-    
-    for (; jsClass; jsClass = jsClass->parentClass)
-        if (JSObjectFinalizeCallback finalize = jsClass->finalize)
-            finalize(thisRef);
-    WeakSet::deallocate(WeakImpl::asWeakImpl(handle.slot()));
-}
-    
 } // namespace JSC
index 9c925886d748d69533de3a2199cd844a7e909a66..33b4262e620174cd7bcd471c50a693a9f40b4a05 100644 (file)
 #include "JSObjectRef.h"
 #include "JSValueRef.h"
 #include "JSObject.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 
-struct JSCallbackObjectData : WeakHandleOwner {
+struct JSCallbackObjectData {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
     JSCallbackObjectData(void* privateData, JSClassRef jsClass)
         : privateData(privateData)
         , jsClass(jsClass)
@@ -42,7 +43,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
         JSClassRetain(jsClass);
     }
     
-    virtual ~JSCallbackObjectData()
+    ~JSCallbackObjectData()
     {
         JSClassRelease(jsClass);
     }
@@ -57,7 +58,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
     void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
     {
         if (!m_privateProperties)
-            m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
+            m_privateProperties = std::make_unique<JSPrivatePropertyMap>();
         m_privateProperties->setPrivateProperty(vm, owner, propertyName, value);
     }
     
@@ -106,11 +107,10 @@ struct JSCallbackObjectData : WeakHandleOwner {
         }
 
     private:
-        typedef HashMap<RefPtr<StringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
+        typedef HashMap<RefPtr<UniquedStringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
         PrivatePropertyMap m_propertyMap;
     };
-    OwnPtr<JSPrivatePropertyMap> m_privateProperties;
-    virtual void finalize(Handle<Unknown>, void*) override;
+    std::unique_ptr<JSPrivatePropertyMap> m_privateProperties;
 };
 
     
@@ -125,6 +125,9 @@ protected:
 
 public:
     typedef Parent Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames | TypeOfShouldCallGetCallData;
+
+    ~JSCallbackObject();
 
     static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data)
     {
@@ -168,9 +171,6 @@ public:
 
     using Parent::methodTable;
 
-protected:
-    static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
-
 private:
     static String className(const JSObject*);
 
@@ -196,8 +196,6 @@ private:
     {
         JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
         ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), JSCallbackObject<Parent>::info());
-        COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-        ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
         Parent::visitChildren(thisObject, visitor);
         thisObject->m_callbackObjectData->visitChildren(visitor);
     }
@@ -214,7 +212,7 @@ private:
     static EncodedJSValue staticFunctionGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     static EncodedJSValue callbackGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
 
-    OwnPtr<JSCallbackObjectData> m_callbackObjectData;
+    std::unique_ptr<JSCallbackObjectData> m_callbackObjectData;
 };
 
 } // namespace JSC
index 58c4eb5da6254d74018593e40e83fb74cc3cd1fc..280fa404764fd703ad20a2ec293d8cd9a1afc640 100644 (file)
@@ -58,19 +58,31 @@ inline JSCallbackObject<Parent>* JSCallbackObject<Parent>::asCallbackObject(Enco
 template <class Parent>
 JSCallbackObject<Parent>::JSCallbackObject(ExecState* exec, Structure* structure, JSClassRef jsClass, void* data)
     : Parent(exec->vm(), structure)
-    , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass)))
+    , m_callbackObjectData(std::make_unique<JSCallbackObjectData>(data, jsClass))
 {
 }
 
+extern const GlobalObjectMethodTable javaScriptCoreAPIGlobalObjectMethodTable;
+
 // Global object constructor.
 // FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
 template <class Parent>
 JSCallbackObject<Parent>::JSCallbackObject(VM& vm, JSClassRef jsClass, Structure* structure)
-    : Parent(vm, structure)
-    , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
+    : Parent(vm, structure, &javaScriptCoreAPIGlobalObjectMethodTable)
+    , m_callbackObjectData(std::make_unique<JSCallbackObjectData>(nullptr, jsClass))
 {
 }
 
+template <class Parent>
+JSCallbackObject<Parent>::~JSCallbackObject()
+{
+    JSObjectRef thisRef = toRef(static_cast<JSObject*>(this));
+    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
+        if (JSObjectFinalizeCallback finalize = jsClass->finalize)
+            finalize(thisRef);
+    }
+}
+    
 template <class Parent>
 void JSCallbackObject<Parent>::finishCreation(ExecState* exec)
 {
@@ -107,13 +119,6 @@ void JSCallbackObject<Parent>::init(ExecState* exec)
         JSObjectInitializeCallback initialize = initRoutines[i];
         initialize(toRef(exec), toRef(this));
     }
-
-    for (JSClassRef jsClassPtr = classRef(); jsClassPtr; jsClassPtr = jsClassPtr->parentClass) {
-        if (jsClassPtr->finalize) {
-            WeakSet::allocate(this, m_callbackObjectData.get(), classRef());
-            break;
-        }
-    }
 }
 
 template <class Parent>
@@ -265,6 +270,9 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
             
             if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
                 if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+                    PropertySlot getSlot(thisObject);
+                    if (Parent::getOwnPropertySlot(thisObject, exec, propertyName, getSlot))
+                        return Parent::put(thisObject, exec, propertyName, value, slot);
                     if (entry->attributes & kJSPropertyAttributeReadOnly)
                         return;
                     thisObject->JSCallbackObject<Parent>::putDirect(exec->vm(), propertyName, value); // put as override property
@@ -516,8 +524,10 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe
             for (iterator it = staticValues->begin(); it != end; ++it) {
                 StringImpl* name = it->key.get();
                 StaticValueEntry* entry = it->value.get();
-                if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
-                    propertyNames.add(Identifier(exec, name));
+                if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || mode.includeDontEnumProperties())) {
+                    ASSERT(!name->isSymbol());
+                    propertyNames.add(Identifier::fromString(exec, String(name)));
+                }
             }
         }
         
@@ -527,8 +537,10 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe
             for (iterator it = staticFunctions->begin(); it != end; ++it) {
                 StringImpl* name = it->key.get();
                 StaticFunctionEntry* entry = it->value.get();
-                if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
-                    propertyNames.add(Identifier(exec, name));
+                if (!(entry->attributes & kJSPropertyAttributeDontEnum) || mode.includeDontEnumProperties()) {
+                    ASSERT(!name->isSymbol());
+                    propertyNames.add(Identifier::fromString(exec, String(name)));
+                }
             }
         }
     }
index 452412e33f5f3ee76cd11e9342af79837810008a..e0dbe60437da0d7ea61c2783a0c6dc094781b9e7 100644 (file)
@@ -62,7 +62,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
     initializeThreading();
 
     if (const JSStaticValue* staticValue = definition->staticValues) {
-        m_staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable);
+        m_staticValues = std::make_unique<OpaqueJSClassStaticValuesTable>();
         while (staticValue->name) {
             String valueName = String::fromUTF8(staticValue->name);
             if (!valueName.isNull())
@@ -72,7 +72,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
     }
 
     if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
-        m_staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable);
+        m_staticFunctions = std::make_unique<OpaqueJSClassStaticFunctionsTable>();
         while (staticFunction->name) {
             String functionName = String::fromUTF8(staticFunction->name);
             if (!functionName.isNull())
@@ -108,12 +108,12 @@ OpaqueJSClass::~OpaqueJSClass()
         JSClassRelease(prototypeClass);
 }
 
-PassRefPtr<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClassDefinition* definition)
+Ref<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClassDefinition* definition)
 {
-    return adoptRef(new OpaqueJSClass(definition, 0));
+    return adoptRef(*new OpaqueJSClass(definition, 0));
 }
 
-PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
+Ref<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
 {
     JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy.
 
@@ -124,7 +124,7 @@ PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientD
     // We are supposed to use JSClassRetain/Release but since we know that we currently have
     // the only reference to this class object we cheat and use a RefPtr instead.
     RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
-    return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
+    return adoptRef(*new OpaqueJSClass(&definition, protoClass.get()));
 }
 
 OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsClass)
index 926f082bf9176606f36e52093e8cc5d39bd92ebb..fa024d344f46c51bad20e1540fafe92aa5acc195 100644 (file)
@@ -85,8 +85,8 @@ public:
 };
 
 struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
-    static PassRefPtr<OpaqueJSClass> create(const JSClassDefinition*);
-    static PassRefPtr<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
+    static Ref<OpaqueJSClass> create(const JSClassDefinition*);
+    static Ref<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
     JS_EXPORT_PRIVATE ~OpaqueJSClass();
     
     String className();
@@ -120,8 +120,8 @@ private:
 
     // Strings in these data members should not be put into any AtomicStringTable.
     String m_className;
-    OwnPtr<OpaqueJSClassStaticValuesTable> m_staticValues;
-    OwnPtr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
+    std::unique_ptr<OpaqueJSClassStaticValuesTable> m_staticValues;
+    std::unique_ptr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
 };
 
 #endif // JSClassRef_h
index d9dcc21e84c37ae7d9ed61c4bc663f6613f94e4c..7095f91bb14bff107d4d550db0f236dc7f102103 100644 (file)
  that reference a particular JSContext have been deallocated the JSContext
  will be deallocated unless it has been previously retained.
 */
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
 NS_CLASS_AVAILABLE(10_9, 7_0)
-#else
-OBJC_VISIBLE
-#endif
 @interface JSContext : NSObject
 
 /*!
index 701bdd1728315af619f021df171621b717a816f5..b3a4b7ad3e1b58d9da9191857f3d92df3edfb8c0 100644 (file)
     if (!name)
         return nil;
 
-    return [(NSString *)JSStringCopyCFString(kCFAllocatorDefault, name) autorelease];
+    return (NSString *)adoptCF(JSStringCopyCFString(kCFAllocatorDefault, name)).autorelease();
 }
 
 - (void)setName:(NSString *)name
index 637b99d2814317f69b49219053c49ba7c2cc4adc..4976c29aeeef91393bb0a8729e500647264c1f79 100644 (file)
@@ -35,6 +35,7 @@
 #include "JSGlobalObject.h"
 #include "JSObject.h"
 #include "JSCInlines.h"
+#include "RuntimeFlags.h"
 #include "SourceProvider.h"
 #include "StackVisitor.h"
 #include <wtf/text/StringBuilder.h>
 #if ENABLE(REMOTE_INSPECTOR)
 #include "JSGlobalObjectDebuggable.h"
 #include "JSGlobalObjectInspectorController.h"
+#include "JSRemoteInspector.h"
+#endif
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "JSContextRefInspectorSupport.h"
 #endif
 
 #if OS(DARWIN)
@@ -53,6 +59,15 @@ static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500;
 
 using namespace JSC;
 
+static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject* globalObject)
+{
+    RuntimeFlags runtimeFlags = JSGlobalObject::javaScriptRuntimeFlags(globalObject);
+    runtimeFlags.setPromiseDisabled(true);
+    return runtimeFlags;
+}
+
+const GlobalObjectMethodTable JSC::javaScriptCoreAPIGlobalObjectMethodTable = { &JSGlobalObject::allowsAccessFrom, &JSGlobalObject::supportsProfiling, &JSGlobalObject::supportsRichSourceInfo, &JSGlobalObject::shouldInterruptScript, &javaScriptRuntimeFlags, nullptr, &JSGlobalObject::shouldInterruptScriptBeforeTimeout };
+
 // From the API's perspective, a context group remains alive iff
 //     (a) it has been JSContextGroupRetained
 //     OR
@@ -61,7 +76,7 @@ using namespace JSC;
 JSContextGroupRef JSContextGroupCreate()
 {
     initializeThreading();
-    return toRef(VM::createContextGroup().leakRef());
+    return toRef(&VM::createContextGroup().leakRef());
 }
 
 JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -86,28 +101,38 @@ static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, vo
     return callback(contextRef, callbackData);
 }
 
+static void createWatchdogIfNeeded(VM& vm)
+{
+    if (!vm.watchdog) {
+        vm.watchdog = std::make_unique<Watchdog>();
+
+        // The LLINT peeks into the Watchdog object directly. In order to do that,
+        // the LLINT assumes that the internal shape of a std::unique_ptr is the
+        // same as a plain C++ pointer, and loads the address of Watchdog from it.
+        RELEASE_ASSERT(*reinterpret_cast<Watchdog**>(&vm.watchdog) == vm.watchdog.get());
+    }
+}
+
 void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* callbackData)
 {
     VM& vm = *toJS(group);
     JSLockHolder locker(&vm);
-    if (!vm.watchdog)
-        vm.watchdog = std::make_unique<Watchdog>();
+    createWatchdogIfNeeded(vm);
     Watchdog& watchdog = *vm.watchdog;
     if (callback) {
         void* callbackPtr = reinterpret_cast<void*>(callback);
-        watchdog.setTimeLimit(vm, limit, internalScriptTimeoutCallback, callbackPtr, callbackData);
+        watchdog.setTimeLimit(vm, std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(limit)), internalScriptTimeoutCallback, callbackPtr, callbackData);
     } else
-        watchdog.setTimeLimit(vm, limit);
+        watchdog.setTimeLimit(vm, std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(limit)));
 }
 
 void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group)
 {
     VM& vm = *toJS(group);
     JSLockHolder locker(&vm);
-    if (!vm.watchdog)
-        vm.watchdog = std::make_unique<Watchdog>();
+    createWatchdogIfNeeded(vm);
     Watchdog& watchdog = *vm.watchdog;
-    watchdog.setTimeLimit(vm, std::numeric_limits<double>::infinity());
+    watchdog.setTimeLimit(vm, std::chrono::microseconds::max());
 }
 
 // From the API's perspective, a global context remains alive iff it has been JSGlobalContextRetained.
@@ -134,10 +159,13 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
     RefPtr<VM> vm = group ? PassRefPtr<VM>(toJS(group)) : VM::createContextGroup();
 
     JSLockHolder locker(vm.get());
-    vm->makeUsableFromMultipleThreads();
 
     if (!globalObjectClass) {
-        JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));
+        JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()), &javaScriptCoreAPIGlobalObjectMethodTable);
+#if ENABLE(REMOTE_INSPECTOR)
+        if (JSRemoteInspectorGetInspectionEnabledByDefault())
+            globalObject->setRemoteDebuggingEnabled(true);
+#endif
         return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
     }
 
@@ -147,6 +175,10 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
     if (!prototype)
         prototype = jsNull();
     globalObject->resetPrototype(*vm, prototype);
+#if ENABLE(REMOTE_INSPECTOR)
+    if (JSRemoteInspectorGetInspectionEnabledByDefault())
+        globalObject->setRemoteDebuggingEnabled(true);
+#endif
     return JSGlobalContextRetain(toGlobalRef(exec));
 }
 
@@ -404,4 +436,19 @@ void JSGlobalContextSetDebuggerRunLoop(JSGlobalContextRef ctx, CFRunLoopRef runL
     UNUSED_PARAM(runLoop);
 #endif
 }
+#endif // USE(CF)
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+Inspector::AugmentableInspectorController* JSGlobalContextGetAugmentableInspectorController(JSGlobalContextRef ctx)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
+    ExecState* exec = toJS(ctx);
+    JSLockHolder lock(exec);
+
+    return &exec->vmEntryGlobalObject()->inspectorController();
+}
 #endif
index cb25c0007d57858b11b3d82beb37bc60e9b80d5f..0c800bced4a6ab9dc7dabaadd3a6ebe6b7f5f0f3 100644 (file)
@@ -48,7 +48,7 @@ extern "C" {
  synchronization is required.
 @result The created JSContextGroup.
 */
-JS_EXPORT JSContextGroupRef JSContextGroupCreate() CF_AVAILABLE(10_6, 7_0);
+JS_EXPORT JSContextGroupRef JSContextGroupCreate(void) CF_AVAILABLE(10_6, 7_0);
 
 /*!
 @function
diff --git a/API/JSContextRefInspectorSupport.h b/API/JSContextRefInspectorSupport.h
new file mode 100644 (file)
index 0000000..a09d828
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSContextRefInspectorSupport_h
+#define JSContextRefInspectorSupport_h
+
+#ifndef __cplusplus
+#error Requires C++ Support.
+#endif
+
+#include <JavaScriptCore/JSContextRefPrivate.h>
+
+namespace Inspector {
+class AugmentableInspectorController;
+}
+
+extern "C" {
+JS_EXPORT Inspector::AugmentableInspectorController* JSGlobalContextGetAugmentableInspectorController(JSGlobalContextRef);
+}
+
+#endif // JSContextRefInspectorSupport_h
index 86658465d559b03f71c06c12173fabfb028c48fc..97764eead378365b1019c1e6fd1e0d387cb5f5a2 100644 (file)
  Objective-C heap object, as this can very easily create a reference cycle, 
  keeping the entire JSContext alive.
 */ 
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
 NS_CLASS_AVAILABLE(10_9, 7_0)
-#else
-OBJC_VISIBLE
-#endif
 @interface JSManagedValue : NSObject
 
 /*!
index 953cb5fbdaac136e651b29ccf58e7d74398fc90e..a72d19b1bfb099b16ed90ace1a133a1b8383a156 100644 (file)
@@ -37,6 +37,7 @@
 #import "WeakHandleOwner.h"
 #import "ObjcRuntimeExtras.h"
 #import "JSCInlines.h"
+#import <wtf/spi/cocoa/NSMapTableSPI.h>
 
 class JSManagedValueHandleOwner : public JSC::WeakHandleOwner {
 public:
index dfad3bd7b476135f47890b6e5be63562624e552f..faf38ff8c23e9df08a0300a5941e17a3546d7eb4 100644 (file)
@@ -34,6 +34,7 @@
 #include "CopiedSpaceInlines.h"
 #include "DateConstructor.h"
 #include "ErrorConstructor.h"
+#include "Exception.h"
 #include "FunctionConstructor.h"
 #include "Identifier.h"
 #include "InitializeThreading.h"
 
 using namespace JSC;
 
+enum class ExceptionStatus {
+    DidThrow,
+    DidNotThrow
+};
+
+static ExceptionStatus handleExceptionIfNeeded(ExecState* exec, JSValueRef* returnedExceptionRef)
+{
+    if (exec->hadException()) {
+        Exception* exception = exec->exception();
+        if (returnedExceptionRef)
+            *returnedExceptionRef = toRef(exec, exception->value());
+        exec->clearException();
+#if ENABLE(REMOTE_INSPECTOR)
+        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+#endif
+        return ExceptionStatus::DidThrow;
+    }
+    return ExceptionStatus::DidNotThrow;
+}
+
 JSClassRef JSClassCreate(const JSClassDefinition* definition)
 {
     initializeThreading();
@@ -140,24 +161,16 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
     JSLockHolder locker(exec);
 
     startingLineNumber = std::max(1, startingLineNumber);
-    Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier(exec, "anonymous");
+    Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier::fromString(exec, "anonymous");
     
     MarkedArgumentBuffer args;
     for (unsigned i = 0; i < parameterCount; i++)
         args.append(jsString(exec, parameterNames[i]->string()));
     args.append(jsString(exec, body->string()));
 
-    JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
     return toRef(result);
 }
 
@@ -180,16 +193,8 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
     } else
         result = constructEmptyArray(exec, 0);
 
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
 
     return toRef(result);
 }
@@ -208,16 +213,8 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
         argList.append(toJS(exec, arguments[i]));
 
     JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), argList);
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
 
     return toRef(result);
 }
@@ -235,16 +232,8 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
     Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
     JSObject* result = ErrorInstance::create(exec, errorStructure, message);
 
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
 
     return toRef(result);
 }
@@ -263,16 +252,8 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
         argList.append(toJS(exec, arguments[i]));
 
     JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(),  argList);
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
     
     return toRef(result);
 }
@@ -339,15 +320,7 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
     JSObject* jsObject = toJS(object);
 
     JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->vm()));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
     return toRef(exec, jsValue);
 }
 
@@ -372,15 +345,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
         jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
     }
 
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
 }
 
 JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
@@ -395,15 +360,7 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
     JSObject* jsObject = toJS(object);
 
     JSValue jsValue = jsObject->get(exec, propertyIndex);
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
     return toRef(exec, jsValue);
 }
 
@@ -421,15 +378,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
     JSValue jsValue = toJS(exec, value);
     
     jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
 }
 
 bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
@@ -444,15 +393,7 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
     JSObject* jsObject = toJS(object);
 
     bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->vm()));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
     return result;
 }
 
@@ -616,16 +557,8 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
         return 0;
 
     JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
     return result;
 }
 
@@ -657,16 +590,8 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
     for (size_t i = 0; i < argumentCount; i++)
         argList.append(toJS(exec, arguments[i]));
     JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         result = 0;
-    }
     return result;
 }
 
@@ -698,7 +623,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
     JSObject* jsObject = toJS(object);
     JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(vm);
     PropertyNameArray array(vm);
-    jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties);
+    jsObject->methodTable()->getPropertyNames(jsObject, exec, array, EnumerationMode());
 
     size_t size = array.size();
     propertyNames->array.reserveInitialCapacity(size);
index 2a5ec2c823901ed9e1bbd824cfa9c63f8a823686..ac112ae6effcc5662aec20f4c8f400d4647d30a7 100644 (file)
@@ -34,7 +34,11 @@ using namespace JSC;
 
 void JSStartProfiling(JSContextRef ctx, JSStringRef title)
 {
-    LegacyProfiler::profiler()->startProfiling(toJS(ctx), title->string());
+    // Use an independent stopwatch for API-initiated profiling, since the user will expect it
+    // to be relative to when their command was issued.
+    RefPtr<Stopwatch> stopwatch = Stopwatch::create();
+    stopwatch->start();
+    LegacyProfiler::profiler()->startProfiling(toJS(ctx), title->string(), stopwatch.release());
 }
 
 void JSEndProfiling(JSContextRef ctx, JSStringRef title)
diff --git a/API/JSRemoteInspector.cpp b/API/JSRemoteInspector.cpp
new file mode 100644 (file)
index 0000000..faebc5d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSRemoteInspector.h"
+
+#include "JSGlobalObjectConsoleClient.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+#include "RemoteInspector.h"
+#endif
+
+using namespace Inspector;
+
+static bool remoteInspectionEnabledByDefault = true;
+
+void JSRemoteInspectorDisableAutoStart(void)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+    RemoteInspector::startDisabled();
+#endif
+}
+
+void JSRemoteInspectorStart(void)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+    RemoteInspector::singleton();
+#endif
+}
+
+void JSRemoteInspectorSetParentProcessInformation(pid_t pid, const UInt8* auditData, size_t auditLength)
+{
+#if ENABLE(REMOTE_INSPECTOR)
+    RetainPtr<CFDataRef> auditDataRef = adoptCF(CFDataCreate(kCFAllocatorDefault, auditData, auditLength));
+    RemoteInspector::singleton().setParentProcessInformation(pid, auditDataRef);
+#else
+    UNUSED_PARAM(pid);
+    UNUSED_PARAM(auditData);
+    UNUSED_PARAM(auditLength);
+#endif
+}
+
+void JSRemoteInspectorSetLogToSystemConsole(bool logToSystemConsole)
+{
+    JSGlobalObjectConsoleClient::setLogToSystemConsole(logToSystemConsole);
+}
+
+bool JSRemoteInspectorGetInspectionEnabledByDefault(void)
+{
+    return remoteInspectionEnabledByDefault;
+}
+
+void JSRemoteInspectorSetInspectionEnabledByDefault(bool enabledByDefault)
+{
+    remoteInspectionEnabledByDefault = enabledByDefault;
+}
diff --git a/API/JSRemoteInspector.h b/API/JSRemoteInspector.h
new file mode 100644 (file)
index 0000000..2bde479
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSRemoteInspector_h
+#define JSRemoteInspector_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <JavaScriptCore/WebKitAvailability.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JS_EXPORT void JSRemoteInspectorDisableAutoStart(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorStart(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorSetParentProcessInformation(pid_t, const uint8_t* auditData, size_t auditLength) CF_AVAILABLE(10_11, 9_0);
+
+JS_EXPORT void JSRemoteInspectorSetLogToSystemConsole(bool) CF_AVAILABLE(10_11, 9_0);
+
+JS_EXPORT bool JSRemoteInspectorGetInspectionEnabledByDefault(void) CF_AVAILABLE(10_11, 9_0);
+JS_EXPORT void JSRemoteInspectorSetInspectionEnabledByDefault(bool) CF_AVAILABLE(10_11, 9_0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSRemoteInspector_h */
index f23e32fcb7a416682c5251bd797aed7b01226f44..262c4d53aa0585fb5eab44f257813293a01b575b 100644 (file)
@@ -75,6 +75,16 @@ private:
     T m_ptr;
 };
 
+inline JSRetainPtr<JSStringRef> adopt(JSStringRef o)
+{
+    return JSRetainPtr<JSStringRef>(Adopt, o);
+}
+
+inline JSRetainPtr<JSGlobalContextRef> adopt(JSGlobalContextRef o)
+{
+    return JSRetainPtr<JSGlobalContextRef>(Adopt, o);
+}
+
 template<typename T> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr& o)
     : m_ptr(o.m_ptr)
 {
index 1e872c7c0b56c347db0bc838be333a51dea2a161..a7baf144a2c5b958b033afa87f4afe96c63def13 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "APICast.h"
 #include "Completion.h"
+#include "Exception.h"
 #include "JSBasePrivate.h"
 #include "VM.h"
 #include "JSScriptRefPrivate.h"
@@ -40,9 +41,9 @@ using namespace JSC;
 
 struct OpaqueJSScript : public SourceProvider {
 public:
-    static WTF::PassRefPtr<OpaqueJSScript> create(VM* vm, const String& url, int startingLineNumber, const String& source)
+    static WTF::RefPtr<OpaqueJSScript> create(VM* vm, const String& url, int startingLineNumber, const String& source)
     {
-        return WTF::adoptRef(new OpaqueJSScript(vm, url, startingLineNumber, source));
+        return WTF::adoptRef(*new OpaqueJSScript(vm, url, startingLineNumber, source));
     }
 
     virtual const String& source() const override
@@ -68,7 +69,10 @@ private:
 
 static bool parseScript(VM* vm, const SourceCode& source, ParserError& error)
 {
-    return JSC::parse<JSC::ProgramNode>(vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
+    return !!JSC::parse<JSC::ProgramNode>(
+        vm, source, 0, Identifier(), JSParserBuiltinMode::NotBuiltin, 
+        JSParserStrictMode::NotStrict, JSParserCodeType::Program, 
+        error);
 }
 
 extern "C" {
@@ -84,15 +88,15 @@ JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef context
 
     startingLineNumber = std::max(1, startingLineNumber);
 
-    RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
+    RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
 
     ParserError error;
     if (!parseScript(vm, SourceCode(result), error)) {
         if (errorMessage)
-            *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+            *errorMessage = OpaqueJSString::create(error.message()).leakRef();
         if (errorLine)
-            *errorLine = error.m_line;
-        return 0;
+            *errorLine = error.line();
+        return nullptr;
     }
 
     return result.release().leakRef();
@@ -105,15 +109,15 @@ JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef
 
     startingLineNumber = std::max(1, startingLineNumber);
 
-    RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, source->string());
+    RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, source->string());
 
     ParserError error;
     if (!parseScript(vm, SourceCode(result), error)) {
         if (errorMessage)
-            *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+            *errorMessage = OpaqueJSString::create(error.message()).leakRef();
         if (errorLine)
-            *errorLine = error.m_line;
-        return 0;
+            *errorLine = error.line();
+        return nullptr;
     }
 
     return result.release().leakRef();
@@ -139,12 +143,12 @@ JSValueRef JSScriptEvaluate(JSContextRef context, JSScriptRef script, JSValueRef
         RELEASE_ASSERT_NOT_REACHED();
         return 0;
     }
-    JSValue internalException;
+    NakedPtr<Exception> internalException;
     JSValue thisValue = thisValueRef ? toJS(exec, thisValueRef) : jsUndefined();
-    JSValue result = evaluate(exec, SourceCode(script), thisValue, &internalException);
+    JSValue result = evaluate(exec, SourceCode(script), thisValue, internalException);
     if (internalException) {
         if (exception)
-            *exception = toRef(exec, internalException);
+            *exception = toRef(exec, internalException->value());
         return 0;
     }
     ASSERT(result);
index f31ed3dca7ec288fe36b78464dcca0251246a59e..c9b380ce654159d3cd11ebe259046bc691ed0ffa 100644 (file)
@@ -37,7 +37,7 @@ using namespace WTF::Unicode;
 JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
 {
     initializeThreading();
-    return OpaqueJSString::create(chars, numChars).leakRef();
+    return &OpaqueJSString::create(chars, numChars).leakRef();
 }
 
 JSStringRef JSStringCreateWithUTF8CString(const char* string)
@@ -51,12 +51,12 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string)
         const LChar* stringStart = reinterpret_cast<const LChar*>(string);
         if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length, &sourceIsAllASCII)) {
             if (sourceIsAllASCII)
-                return OpaqueJSString::create(stringStart, length).leakRef();
-            return OpaqueJSString::create(buffer.data(), p - buffer.data()).leakRef();
+                return &OpaqueJSString::create(stringStart, length).leakRef();
+            return &OpaqueJSString::create(buffer.data(), p - buffer.data()).leakRef();
         }
     }
 
-    return OpaqueJSString::create().leakRef();
+    return &OpaqueJSString::create().leakRef();
 }
 
 JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars)
@@ -78,11 +78,15 @@ void JSStringRelease(JSStringRef string)
 
 size_t JSStringGetLength(JSStringRef string)
 {
+    if (!string)
+        return 0;
     return string->length();
 }
 
 const JSChar* JSStringGetCharactersPtr(JSStringRef string)
 {
+    if (!string)
+        return nullptr;
     return string->characters();
 }
 
@@ -94,7 +98,7 @@ size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
 
 size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
 {
-    if (!bufferSize)
+    if (!string || !buffer || !bufferSize)
         return 0;
 
     char* destination = buffer;
index 1d306082d7d56df02a3d4517df22034bf084fad1..05872593f6dbb9a853a8161a69bbdf742a2333a3 100644 (file)
@@ -41,23 +41,23 @@ JSStringRef JSStringCreateWithCFString(CFStringRef string)
     // it can hold.  (<rdar://problem/6806478>)
     size_t length = CFStringGetLength(string);
     if (!length)
-        return OpaqueJSString::create(reinterpret_cast<const LChar*>(""), 0).leakRef();
+        return &OpaqueJSString::create(reinterpret_cast<const LChar*>(""), 0).leakRef();
 
     Vector<LChar, 1024> lcharBuffer(length);
     CFIndex usedBufferLength;
     CFIndex convertedSize = CFStringGetBytes(string, CFRangeMake(0, length), kCFStringEncodingISOLatin1, 0, false, lcharBuffer.data(), length, &usedBufferLength);
     if (static_cast<size_t>(convertedSize) == length && static_cast<size_t>(usedBufferLength) == length)
-        return OpaqueJSString::create(lcharBuffer.data(), length).leakRef();
+        return &OpaqueJSString::create(lcharBuffer.data(), length).leakRef();
 
     auto buffer = std::make_unique<UniChar[]>(length);
     CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
     static_assert(sizeof(UniChar) == sizeof(UChar), "UniChar and UChar must be same size");
-    return OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef();
+    return &OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef();
 }
 
 CFStringRef JSStringCopyCFString(CFAllocatorRef allocator, JSStringRef string)
 {
-    if (!string->length())
+    if (!string || !string->length())
         return CFSTR("");
 
     if (string->is8Bit())
index c5a824db0b9f8ee6f06bfb153a50eb0dc14644ce..803d10513a827eab82385b93c7533b74e6a7c8c6 100644 (file)
  from a different JSVirtualMachine will result in an Objective-C exception
  being raised.
 */
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
 NS_CLASS_AVAILABLE(10_9, 7_0)
-#else
-OBJC_VISIBLE
-#endif
 @interface JSValue : NSObject
 
 /*!
@@ -380,19 +376,19 @@ OBJC_VISIBLE
 @method
 @abstract Check if a JSValue corresponds to the JavaScript value <code>undefined</code>.
 */ 
-- (BOOL)isUndefined;
+@property (readonly) BOOL isUndefined;
 
 /*!
 @method
 @abstract Check if a JSValue corresponds to the JavaScript value <code>null</code>.
 */
-- (BOOL)isNull;
+@property (readonly) BOOL isNull;
 
 /*!
 @method
 @abstract Check if a JSValue is a boolean.
 */
-- (BOOL)isBoolean;
+@property (readonly) BOOL isBoolean;
 
 /*!
 @method
@@ -401,19 +397,31 @@ OBJC_VISIBLE
  Semantically all numbers behave like doubles except in special cases like bit
  operations. 
 */
-- (BOOL)isNumber;
+@property (readonly) BOOL isNumber;
 
 /*!
 @method
 @abstract Check if a JSValue is a string.
 */
-- (BOOL)isString;
+@property (readonly) BOOL isString;
 
 /*!
 @method
 @abstract Check if a JSValue is an object.
 */
-- (BOOL)isObject;
+@property (readonly) BOOL isObject;
+
+/*!
+@method
+@abstract Check if a JSValue is an array.
+*/ 
+@property (readonly) BOOL isArray NS_AVAILABLE(10_11, 9_0);
+
+/*!
+@method
+@abstract Check if a JSValue is a date.
+*/ 
+@property (readonly) BOOL isDate NS_AVAILABLE(10_11, 9_0);
 
 /*!
 @method
index 11019ad4298ae39a3fed1a1cc79fa3fa5946e3d4..11be6b667155dc01d1e857ef9a3ea0ca0931b6e0 100644 (file)
@@ -28,6 +28,7 @@
 #import "APICast.h"
 #import "DateInstance.h"
 #import "Error.h"
+#import "Exception.h"
 #import "JavaScriptCore.h"
 #import "JSContextInternal.h"
 #import "JSVirtualMachineInternal.h"
@@ -41,8 +42,8 @@
 #import <wtf/HashMap.h>
 #import <wtf/HashSet.h>
 #import <wtf/ObjcRuntimeExtras.h>
+#import <wtf/SpinLock.h>
 #import <wtf/Vector.h>
-#import <wtf/TCSpinLock.h>
 #import <wtf/text/WTFString.h>
 #import <wtf/text/StringHash.h>
 
@@ -356,6 +357,16 @@ NSString * const JSPropertyDescriptorSetKey = @"set";
     return JSValueIsObject([_context JSGlobalContextRef], m_value);
 }
 
+- (BOOL)isArray
+{
+    return JSValueIsArray([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isDate
+{
+    return JSValueIsDate([_context JSGlobalContextRef], m_value);
+}
+
 - (BOOL)isEqualToObject:(id)value
 {
     return JSValueIsStrictEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value));
@@ -635,9 +646,10 @@ JSContainerConvertor::Task JSContainerConvertor::take()
 }
 
 #if ENABLE(REMOTE_INSPECTOR)
-static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exception)
+static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue exceptionValue)
 {
     JSC::ExecState* exec = toJS(context);
+    JSC::Exception* exception = JSC::Exception::create(exec->vm(), exceptionValue);
     exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
 }
 #endif
@@ -767,9 +779,9 @@ id valueToString(JSGlobalContextRef context, JSValueRef value, JSValueRef* excep
         return nil;
     }
 
-    NSString *stringNS = CFBridgingRelease(JSStringCopyCFString(kCFAllocatorDefault, jsstring));
+    RetainPtr<CFStringRef> stringCF = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, jsstring));
     JSStringRelease(jsstring);
-    return stringNS;
+    return (NSString *)stringCF.autorelease();
 }
 
 id valueToDate(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
@@ -1102,7 +1114,7 @@ static StructHandlers* createStructHandlerMap()
 
 static StructTagHandler* handerForStructTag(const char* encodedType)
 {
-    static SpinLock handerForStructTagLock = SPINLOCK_INITIALIZER;
+    static StaticSpinLock handerForStructTagLock;
     SpinLockHolder lockHolder(&handerForStructTagLock);
 
     static StructHandlers* structHandlers = createStructHandlerMap();
index a0be8f07f7fc4f10fd691987489c57a5b66f5df3..54405e2af597c248236def769e8bbc6028979d26 100644 (file)
 #include "JSValueRef.h"
 
 #include "APICast.h"
+#include "DateInstance.h"
+#include "Exception.h"
 #include "JSAPIWrapperObject.h"
+#include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSCallbackObject.h"
 #include "JSGlobalObject.h"
 #include "JSONObject.h"
 #include "JSString.h"
 #include "LiteralParser.h"
-#include "JSCInlines.h"
 #include "Protect.h"
-
+#include <algorithm>
 #include <wtf/Assertions.h>
 #include <wtf/text/StringHash.h>
 #include <wtf/text/WTFString.h>
 
-#include <algorithm> // for std::min
-
 #if PLATFORM(MAC)
 #include <mach-o/dyld.h>
 #endif
 
 using namespace JSC;
 
+enum class ExceptionStatus {
+    DidThrow,
+    DidNotThrow
+};
+
+static ExceptionStatus handleExceptionIfNeeded(ExecState* exec, JSValueRef* returnedExceptionRef)
+{
+    if (exec->hadException()) {
+        Exception* exception = exec->exception();
+        if (returnedExceptionRef)
+            *returnedExceptionRef = toRef(exec, exception->value());
+        exec->clearException();
+#if ENABLE(REMOTE_INSPECTOR)
+        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exception);
+#endif
+        return ExceptionStatus::DidThrow;
+    }
+    return ExceptionStatus::DidNotThrow;
+}
+
 #if PLATFORM(MAC)
 static bool evernoteHackNeeded()
 {
@@ -98,8 +118,7 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isUndefined();
+    return toJS(exec, value).isUndefined();
 }
 
 bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
@@ -111,8 +130,7 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isNull();
+    return toJS(exec, value).isNull();
 }
 
 bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
@@ -124,8 +142,7 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isBoolean();
+    return toJS(exec, value).isBoolean();
 }
 
 bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
@@ -137,8 +154,7 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isNumber();
+    return toJS(exec, value).isNumber();
 }
 
 bool JSValueIsString(JSContextRef ctx, JSValueRef value)
@@ -150,8 +166,7 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isString();
+    return toJS(exec, value).isString();
 }
 
 bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
@@ -163,8 +178,31 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    JSValue jsValue = toJS(exec, value);
-    return jsValue.isObject();
+    return toJS(exec, value).isObject();
+}
+
+bool JSValueIsArray(JSContextRef ctx, JSValueRef value)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    ExecState* exec = toJS(ctx);
+    JSLockHolder locker(exec);
+
+    return toJS(exec, value).inherits(JSArray::info());
+}
+
+bool JSValueIsDate(JSContextRef ctx, JSValueRef value)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    ExecState* exec = toJS(ctx);
+    JSLockHolder locker(exec);
+
+    return toJS(exec, value).inherits(DateInstance::info());
 }
 
 bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
@@ -207,15 +245,8 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
     JSValue jsB = toJS(exec, b);
 
     bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
+    
     return result;
 }
 
@@ -249,15 +280,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
     if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
         return false;
     bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-    }
+    handleExceptionIfNeeded(exec, exception);
     return result;
 }
 
@@ -318,7 +341,7 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
 
-    return toRef(exec, jsString(exec, string->string()));
+    return toRef(exec, jsString(exec, string ? string->string() : String()));
 }
 
 JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
@@ -351,16 +374,8 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig
     String result = JSONStringify(exec, value, indent);
     if (exception)
         *exception = 0;
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         return 0;
-    }
     return OpaqueJSString::create(result).leakRef();
 }
 
@@ -389,16 +404,8 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
     JSValue jsValue = toJS(exec, value);
 
     double number = jsValue.toNumber(exec);
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         number = PNaN;
-    }
     return number;
 }
 
@@ -414,16 +421,8 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
     JSValue jsValue = toJS(exec, value);
     
     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec)));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
-        stringRef.clear();
-    }
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
+        stringRef = nullptr;
     return stringRef.release().leakRef();
 }
 
@@ -439,16 +438,8 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
     JSValue jsValue = toJS(exec, value);
     
     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
-    if (exec->hadException()) {
-        JSValue exceptionValue = exec->exception();
-        if (exception)
-            *exception = toRef(exec, exceptionValue);
-        exec->clearException();
-#if ENABLE(REMOTE_INSPECTOR)
-        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
-#endif
+    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
         objectRef = 0;
-    }
     return objectRef;
 }
 
index 538e6e0deb57ace254d218bdde8e6340c34b7f43..9c4fa58cdf9889e030f6a1a6d13dabc02dd77597 100644 (file)
@@ -129,6 +129,24 @@ JS_EXPORT bool JSValueIsObject(JSContextRef ctx, JSValueRef value);
 */
 JS_EXPORT bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass);
 
+/*!
+@function
+@abstract       Tests whether a JavaScript value is an array.
+@param ctx      The execution context to use.
+@param value    The JSValue to test.
+@result         true if value is an array, otherwise false.
+*/
+JS_EXPORT bool JSValueIsArray(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+
+/*!
+@function
+@abstract       Tests whether a JavaScript value is a date.
+@param ctx      The execution context to use.
+@param value    The JSValue to test.
+@result         true if value is a date, otherwise false.
+*/
+JS_EXPORT bool JSValueIsDate(JSContextRef ctx, JSValueRef value) CF_AVAILABLE(10_11, 9_0);
+
 /* Comparing values */
 
 /*!
index dc9becbab112a6087b86533b2ea19cc5f0e5ccf0..ccf9264d53c7fb3ecbeabf534cef6535f05f5ffd 100644 (file)
  virtual machine, with concurrent JavaScript execution supported by allocating
  separate instances of JSVirtualMachine.
 */
-#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
 NS_CLASS_AVAILABLE(10_9, 7_0)
-#else
-OBJC_VISIBLE
-#endif
 @interface JSVirtualMachine : NSObject
 
 /*!
index 26e709ae16e7b5fe84f39b31c441534a5d79003c..d4995ad925a3152f8f2e02de0bab3494af285a1c 100644 (file)
@@ -37,6 +37,7 @@
 #import "SlotVisitorInlines.h"
 #import <mutex>
 #import <wtf/NeverDestroyed.h>
+#import <wtf/spi/cocoa/NSMapTableSPI.h>
 
 static NSMapTable *globalWrapperCache = 0;
 
index 009d8e4e5d4b560866704569d67773584be68cbf..5a4fbefa5e0197beddb780d404efb000d1affe0a 100644 (file)
@@ -36,6 +36,8 @@ class SlotVisitor;
 }
 
 #if defined(__OBJC__)
+@class NSMapTable;
+
 @interface JSVirtualMachine(Internal)
 
 JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *);
index f7b91da51d326db2a45f677ebfef6f7f0ec5b770..9037947d7fd4f859aa98d477b5d54aa8a9211899 100644 (file)
@@ -41,9 +41,9 @@ typedef JSC::WeakGCMap<void*, JSC::JSObject> WeakMapType;
 
 struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
 public:
-    static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
+    static Ref<OpaqueJSWeakObjectMap> create(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
     {
-        return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
+        return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback));
     }
 
     WeakMapType& map() { return m_map; }
@@ -54,8 +54,9 @@ public:
     }
 
 private:
-    OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
-        : m_data(data)
+    OpaqueJSWeakObjectMap(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
+        : m_map(vm)
+        , m_data(data)
         , m_callback(callback)
     {
     }
index 446cf90135161ec24eb8eb5db12f934132fac754..925c00f0b14203be2429cea57c63a581cb685f8d 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSWeakObjectMapRefInternal.h"
 #include "JSCInlines.h"
 #include "Weak.h"
+#include "WeakGCMapInlines.h"
 #include <wtf/HashMap.h>
 #include <wtf/text/StringHash.h>
 
@@ -46,7 +47,7 @@ JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData
 {
     ExecState* exec = toJS(context);
     JSLockHolder locker(exec);
-    RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback);
+    RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback);
     exec->lexicalGlobalObject()->registerWeakMap(map.get());
     return map.get();
 }
index 069de826729ab1c100ce3fc2d59be308bd1b5dbe..2cb0ec1d4bfc72c30a26547965edd903e9943bfa 100644 (file)
 
 #import "APICast.h"
 #import "JSAPIWrapperObject.h"
+#import "JSCInlines.h"
 #import "JSCallbackObject.h"
 #import "JSContextInternal.h"
 #import "JSWrapperMap.h"
 #import "ObjCCallbackFunction.h"
 #import "ObjcRuntimeExtras.h"
-#import "JSCInlines.h"
 #import "WeakGCMap.h"
-#import <wtf/TCSpinLock.h>
-#import <wtf/Vector.h>
+#import "WeakGCMapInlines.h"
 #import <wtf/HashSet.h>
+#import <wtf/Vector.h>
+#import <wtf/spi/cocoa/NSMapTableSPI.h>
 
 #include <mach-o/dyld.h>
 
@@ -107,7 +108,7 @@ static bool constructorHasInstance(JSContextRef ctx, JSObjectRef constructorRef,
     return JSC::JSObject::defaultHasInstance(exec, instance, constructor->get(exec, exec->propertyNames().prototype));
 }
 
-static JSObjectRef makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)
+static JSC::JSObject* makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)
 {
     JSC::ExecState* exec = toJS(ctx);
     JSC::JSLockHolder locker(exec);
@@ -118,33 +119,33 @@ static JSObjectRef makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedO
     if (JSC::JSObject* prototype = jsClass->prototype(exec))
         object->setPrototype(exec->vm(), prototype);
 
-    return toRef(object);
+    return object;
 }
 
 // Make an object that is in all ways a completely vanilla JavaScript object,
 // other than that it has a native brand set that will be displayed by the default
 // Object.prototype.toString conversion.
-static JSValue *objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0)
+static JSC::JSObject *objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0)
 {
     JSClassDefinition definition;
     definition = kJSClassDefinitionEmpty;
     definition.className = [brand UTF8String];
     JSClassRef classRef = JSClassCreate(&definition);
-    JSObjectRef result = makeWrapper([context JSGlobalContextRef], classRef, cls);
+    JSC::JSObject* result = makeWrapper([context JSGlobalContextRef], classRef, cls);
     JSClassRelease(classRef);
-    return [JSValue valueWithJSValueRef:result inContext:context];
+    return result;
 }
 
-static JSValue *constructorWithCustomBrand(JSContext *context, NSString *brand, Class cls)
+static JSC::JSObject *constructorWithCustomBrand(JSContext *context, NSString *brand, Class cls)
 {
     JSClassDefinition definition;
     definition = kJSClassDefinitionEmpty;
     definition.className = [brand UTF8String];
     definition.hasInstance = constructorHasInstance;
     JSClassRef classRef = JSClassCreate(&definition);
-    JSObjectRef result = makeWrapper([context JSGlobalContextRef], classRef, cls);
+    JSC::JSObject* result = makeWrapper([context JSGlobalContextRef], classRef, cls);
     JSClassRelease(classRef);
-    return [JSValue valueWithJSValueRef:result inContext:context];
+    return result;
 }
 
 // Look for @optional properties in the prototype containing a selector to property
@@ -364,8 +365,8 @@ static void copyPrototypeProperties(JSContext *context, Class objcClass, Protoco
 }
 
 - (id)initWithContext:(JSContext *)context forClass:(Class)cls;
-- (JSValue *)wrapperForObject:(id)object;
-- (JSValue *)constructor;
+- (JSC::JSObject *)wrapperForObject:(id)object;
+- (JSC::JSObject *)constructor;
 - (JSC::JSObject *)prototype;
 
 @end
@@ -396,7 +397,7 @@ static void copyPrototypeProperties(JSContext *context, Class objcClass, Protoco
     [super dealloc];
 }
 
-static JSValue *allocateConstructorForCustomClass(JSContext *context, const char* className, Class cls)
+static JSC::JSObject* allocateConstructorForCustomClass(JSContext *context, const char* className, Class cls)
 {
     if (!supportsInitMethodConstructors())
         return constructorWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
@@ -443,7 +444,7 @@ static JSValue *allocateConstructorForCustomClass(JSContext *context, const char
         }
 
         JSObjectRef method = objCCallbackFunctionForInit(context, cls, initProtocol, initMethod, types);
-        return [JSValue valueWithJSValueRef:method inContext:context];
+        return toJS(method);
     }
     return constructorWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls);
 }
@@ -456,36 +457,32 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
 
     ASSERT(!m_constructor || !m_prototype);
     ASSERT((m_class == [NSObject class]) == !superClassInfo);
+
+    JSC::JSObject* jsPrototype = m_prototype.get();
+    JSC::JSObject* jsConstructor = m_constructor.get();
+
     if (!superClassInfo) {
         JSContextRef cContext = [m_context JSGlobalContextRef];
         JSValue *constructor = m_context[@"Object"];
-        if (!m_constructor)
-            m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
+        if (!jsConstructor)
+            jsConstructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
 
-        if (!m_prototype) {
+        if (!jsPrototype) {
             JSValue *prototype = constructor[@"prototype"];
-            m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
+            jsPrototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
         }
     } else {
         const char* className = class_getName(m_class);
 
         // Create or grab the prototype/constructor pair.
-        JSValue *prototype;
-        JSValue *constructor;
-        if (m_prototype)
-            prototype = [JSValue valueWithJSValueRef:toRef(m_prototype.get()) inContext:m_context];
-        else
-            prototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]);
-
-        if (m_constructor)
-            constructor = [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context];
-        else
-            constructor = allocateConstructorForCustomClass(m_context, className, m_class);
+        if (!jsPrototype)
+            jsPrototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]);
 
-        JSContextRef cContext = [m_context JSGlobalContextRef];
-        m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
-        m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
+        if (!jsConstructor)
+            jsConstructor = allocateConstructorForCustomClass(m_context, className, m_class);
 
+        JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:m_context];
+        JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:m_context];
         putNonEnumerable(prototype, @"constructor", constructor);
         putNonEnumerable(constructor, @"prototype", prototype);
 
@@ -497,12 +494,15 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
 
         // Set [Prototype].
         JSC::JSObject* superClassPrototype = [superClassInfo prototype];
-        JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(m_prototype.get()), toRef(superClassPrototype));
+        JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype));
     }
-    return ConstructorPrototypePair(m_constructor.get(), m_prototype.get());
+
+    m_prototype = jsPrototype;
+    m_constructor = jsConstructor;
+    return ConstructorPrototypePair(jsConstructor, jsPrototype);
 }
 
-- (JSValue *)wrapperForObject:(id)object
+- (JSC::JSObject*)wrapperForObject:(id)object
 {
     ASSERT([object isKindOfClass:m_class]);
     ASSERT(m_block == [object isKindOfClass:getNSBlockClass()]);
@@ -512,24 +512,24 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
             JSValue *prototype = [JSValue valueWithNewObjectInContext:m_context];
             putNonEnumerable(constructor, @"prototype", prototype);
             putNonEnumerable(prototype, @"constructor", constructor);
-            return constructor;
+            return toJS(method);
         }
     }
 
     JSC::JSObject* prototype = [self prototype];
 
-    JSObjectRef wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);
-    JSObjectSetPrototype([m_context JSGlobalContextRef], wrapper, toRef(prototype));
-    return [JSValue valueWithJSValueRef:wrapper inContext:m_context];
+    JSC::JSObject* wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);
+    JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(wrapper), toRef(prototype));
+    return wrapper;
 }
 
-- (JSValue *)constructor
+- (JSC::JSObject*)constructor
 {
     JSC::JSObject* constructor = m_constructor.get();
     if (!constructor)
         constructor = [self allocateConstructorAndPrototype].first;
     ASSERT(!!constructor);
-    return [JSValue valueWithJSValueRef:toRef(constructor) inContext:m_context];
+    return constructor;
 }
 
 - (JSC::JSObject*)prototype
@@ -546,7 +546,7 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
 @implementation JSWrapperMap {
     JSContext *m_context;
     NSMutableDictionary *m_classMap;
-    JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;
+    std::unique_ptr<JSC::WeakGCMap<id, JSC::JSObject>> m_cachedJSWrappers;
     NSMapTable *m_cachedObjCWrappers;
 }
 
@@ -559,7 +559,9 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
     NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
     NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
     m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-    
+
+    m_cachedJSWrappers = std::make_unique<JSC::WeakGCMap<id, JSC::JSObject>>(toJS([context JSGlobalContextRef])->vm());
+
     m_context = context;
     m_classMap = [[NSMutableDictionary alloc] init];
     return self;
@@ -590,16 +592,15 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
 
 - (JSValue *)jsWrapperForObject:(id)object
 {
-    JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
+    JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object);
     if (jsWrapper)
         return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
 
-    JSValue *wrapper;
     if (class_isMetaClass(object_getClass(object)))
-        wrapper = [[self classInfoForClass:(Class)object] constructor];
+        jsWrapper = [[self classInfoForClass:(Class)object] constructor];
     else {
         JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]];
-        wrapper = [classInfo wrapperForObject:object];
+        jsWrapper = [classInfo wrapperForObject:object];
     }
 
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105891
@@ -607,10 +608,8 @@ typedef std::pair<JSC::JSObject*, JSC::JSObject*> ConstructorPrototypePair;
     // (1) For immortal objects JSValues will effectively leak and this results in error output being logged - we should avoid adding associated objects to immortal objects.
     // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects,
     //     but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
-    JSC::ExecState* exec = toJS([m_context JSGlobalContextRef]);
-    jsWrapper = toJS(exec, valueInternalValue(wrapper)).toObject(exec);
-    m_cachedJSWrappers.set(object, jsWrapper);
-    return wrapper;
+    m_cachedJSWrappers->set(object, jsWrapper);
+    return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
 }
 
 - (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value
@@ -648,6 +647,11 @@ NS_ROOT_CLASS @interface JSExport <JSExport>
 
 bool supportsInitMethodConstructors()
 {
+#if PLATFORM(APPLETV)
+    // There are no old clients on Apple TV, so there's no need for backwards compatibility.
+    return true;
+#endif
+
     static int32_t versionOfLinkTimeLibrary = 0;
     if (!versionOfLinkTimeLibrary)
         versionOfLinkTimeLibrary = NSVersionOfLinkTimeLibrary("JavaScriptCore");
index 046bf650dd0e1d9c80d133a5c4d852c6a08bbfda..adb167c7631700cf165f762915dd8015a19f8bed 100644 (file)
@@ -48,7 +48,7 @@ class ObjCCallbackFunction : public InternalFunction {
 public:
     typedef InternalFunction Base;
 
-    static ObjCCallbackFunction* create(VM&, JSGlobalObject*, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl>);
+    static ObjCCallbackFunction* create(VM&, JSGlobalObject*, const String& name, std::unique_ptr<ObjCCallbackFunctionImpl>);
     static void destroy(JSCell*);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -62,7 +62,7 @@ public:
     ObjCCallbackFunctionImpl* impl() const { return m_impl.get(); }
 
 protected:
-    ObjCCallbackFunction(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, JSObjectCallAsConstructorCallback, PassOwnPtr<ObjCCallbackFunctionImpl>);
+    ObjCCallbackFunction(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, JSObjectCallAsConstructorCallback, std::unique_ptr<ObjCCallbackFunctionImpl>);
 
 private:
     static CallType getCallData(JSCell*, CallData&);
@@ -73,7 +73,7 @@ private:
 
     JSObjectCallAsFunctionCallback m_functionCallback;
     JSObjectCallAsConstructorCallback m_constructCallback;
-    OwnPtr<ObjCCallbackFunctionImpl> m_impl;
+    std::unique_ptr<ObjCCallbackFunctionImpl> m_impl;
 };
 
 } // namespace JSC
index c62b7319dafa6ce050cf43cc7ebc58cf8675bc7f..bba9294d306aaaa2cbd1a0d4daeaeeeb8c08e20d 100644 (file)
@@ -30,7 +30,6 @@
 
 #import "APICallbackFunction.h"
 #import "APICast.h"
-#import "DelayedReleaseScope.h"
 #import "Error.h"
 #import "JSCJSValueInlines.h"
 #import "JSCell.h"
@@ -48,7 +47,7 @@ public:
     virtual ~CallbackArgument();
     virtual void set(NSInvocation *, NSInteger, JSContext *, JSValueRef, JSValueRef*) = 0;
 
-    OwnPtr<CallbackArgument> m_next;
+    std::unique_ptr<CallbackArgument> m_next;
 };
 
 CallbackArgument::~CallbackArgument()
@@ -100,24 +99,17 @@ class CallbackArgumentId : public CallbackArgument {
 class CallbackArgumentOfClass : public CallbackArgument {
 public:
     CallbackArgumentOfClass(Class cls)
-        : CallbackArgument()
-        , m_class(cls)
+        : m_class(cls)
     {
-        [m_class retain];
     }
 
 private:
-    virtual ~CallbackArgumentOfClass()
-    {
-        [m_class release];
-    }
-
     virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
     {
         JSGlobalContextRef contextRef = [context JSGlobalContextRef];
 
         id object = tryUnwrapObjcObject(contextRef, argument);
-        if (object && [object isKindOfClass:m_class]) {
+        if (object && [object isKindOfClass:m_class.get()]) {
             [invocation setArgument:&object atIndex:argumentNumber];
             return;
         }
@@ -131,7 +123,7 @@ private:
         *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("Argument does not match Objective-C Class")));
     }
 
-    Class m_class;
+    RetainPtr<Class> m_class;
 };
 
 class CallbackArgumentNSNumber : public CallbackArgument {
@@ -197,34 +189,34 @@ private:
 
 class ArgumentTypeDelegate {
 public:
-    typedef CallbackArgument* ResultType;
+    typedef std::unique_ptr<CallbackArgument> ResultType;
 
     template<typename T>
     static ResultType typeInteger()
     {
-        return new CallbackArgumentInteger<T>;
+        return std::make_unique<CallbackArgumentInteger<T>>();
     }
 
     template<typename T>
     static ResultType typeDouble()
     {
-        return new CallbackArgumentDouble<T>;
+        return std::make_unique<CallbackArgumentDouble<T>>();
     }
 
     static ResultType typeBool()
     {
-        return new CallbackArgumentBoolean;
+        return std::make_unique<CallbackArgumentBoolean>();
     }
 
     static ResultType typeVoid()
     {
         RELEASE_ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 
     static ResultType typeId()
     {
-        return new CallbackArgumentId;
+        return std::make_unique<CallbackArgumentId>();
     }
 
     static ResultType typeOfClass(const char* begin, const char* end)
@@ -232,35 +224,35 @@ public:
         StringRange copy(begin, end);
         Class cls = objc_getClass(copy);
         if (!cls)
-            return 0;
+            return nullptr;
 
         if (cls == [JSValue class])
-            return new CallbackArgumentJSValue;
+            return std::make_unique<CallbackArgumentJSValue>();
         if (cls == [NSString class])
-            return new CallbackArgumentNSString;
+            return std::make_unique<CallbackArgumentNSString>();
         if (cls == [NSNumber class])
-            return new CallbackArgumentNSNumber;
+            return std::make_unique<CallbackArgumentNSNumber>();
         if (cls == [NSDate class])
-            return new CallbackArgumentNSDate;
+            return std::make_unique<CallbackArgumentNSDate>();
         if (cls == [NSArray class])
-            return new CallbackArgumentNSArray;
+            return std::make_unique<CallbackArgumentNSArray>();
         if (cls == [NSDictionary class])
-            return new CallbackArgumentNSDictionary;
+            return std::make_unique<CallbackArgumentNSDictionary>();
 
-        return new CallbackArgumentOfClass(cls);
+        return std::make_unique<CallbackArgumentOfClass>(cls);
     }
 
     static ResultType typeBlock(const char*, const char*)
     {
-        return nil;
+        return nullptr;
     }
 
     static ResultType typeStruct(const char* begin, const char* end)
     {
         StringRange copy(begin, end);
         if (NSInvocation *invocation = valueToTypeInvocationFor(copy))
-            return new CallbackArgumentStruct(invocation, copy);
-        return 0;
+            return std::make_unique<CallbackArgumentStruct>(invocation, copy);
+        return nullptr;
     }
 };
 
@@ -336,51 +328,51 @@ private:
 
 class ResultTypeDelegate {
 public:
-    typedef CallbackResult* ResultType;
+    typedef std::unique_ptr<CallbackResult> ResultType;
 
     template<typename T>
     static ResultType typeInteger()
     {
-        return new CallbackResultNumeric<T>;
+        return std::make_unique<CallbackResultNumeric<T>>();
     }
 
     template<typename T>
     static ResultType typeDouble()
     {
-        return new CallbackResultNumeric<T>;
+        return std::make_unique<CallbackResultNumeric<T>>();
     }
 
     static ResultType typeBool()
     {
-        return new CallbackResultBoolean;
+        return std::make_unique<CallbackResultBoolean>();
     }
 
     static ResultType typeVoid()
     {
-        return new CallbackResultVoid;
+        return std::make_unique<CallbackResultVoid>();
     }
 
     static ResultType typeId()
     {
-        return new CallbackResultId();
+        return std::make_unique<CallbackResultId>();
     }
 
     static ResultType typeOfClass(const char*, const char*)
     {
-        return new CallbackResultId();
+        return std::make_unique<CallbackResultId>();
     }
 
     static ResultType typeBlock(const char*, const char*)
     {
-        return new CallbackResultId();
+        return std::make_unique<CallbackResultId>();
     }
 
     static ResultType typeStruct(const char* begin, const char* end)
     {
         StringRange copy(begin, end);
         if (NSInvocation *invocation = typeToValueInvocationFor(copy))
-            return new CallbackResultStruct(invocation, copy);
-        return 0;
+            return std::make_unique<CallbackResultStruct>(invocation, copy);
+        return nullptr;
     }
 };
 
@@ -395,12 +387,12 @@ namespace JSC {
 
 class ObjCCallbackFunctionImpl {
 public:
-    ObjCCallbackFunctionImpl(NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr<CallbackArgument> arguments, PassOwnPtr<CallbackResult> result)
+    ObjCCallbackFunctionImpl(NSInvocation *invocation, CallbackType type, Class instanceClass, std::unique_ptr<CallbackArgument> arguments, std::unique_ptr<CallbackResult> result)
         : m_type(type)
-        , m_instanceClass([instanceClass retain])
+        , m_instanceClass(instanceClass)
         , m_invocation(invocation)
-        , m_arguments(arguments)
-        , m_result(result)
+        , m_arguments(WTF::move(arguments))
+        , m_result(WTF::move(result))
     {
         ASSERT((type != CallbackInstanceMethod && type != CallbackInitMethod) || instanceClass);
     }
@@ -411,7 +403,7 @@ public:
         // -retainArguments on m_invocation (and we don't want to do so).
         if (m_type == CallbackBlock || m_type == CallbackClassMethod)
             heap.releaseSoon(adoptNS([m_invocation.get() target]));
-        [m_instanceClass release];
+        m_instanceClass = nil;
     }
 
     JSValueRef call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
@@ -427,7 +419,7 @@ public:
         case CallbackBlock:
             return [m_invocation target];
         case CallbackInitMethod:
-            return m_instanceClass;
+            return m_instanceClass.get();
         default:
             return nil;
         }
@@ -442,10 +434,10 @@ public:
 
 private:
     CallbackType m_type;
-    Class m_instanceClass;
+    RetainPtr<Class> m_instanceClass;
     RetainPtr<NSInvocation> m_invocation;
-    OwnPtr<CallbackArgument> m_arguments;
-    OwnPtr<CallbackResult> m_result;
+    std::unique_ptr<CallbackArgument> m_arguments;
+    std::unique_ptr<CallbackResult> m_result;
 };
 
 static JSValueRef objCCallbackFunctionCallAsFunction(JSContextRef callerContext, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -483,8 +475,8 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont
     CallbackData callbackData;
     JSValueRef result;
     @autoreleasepool {
-        [context beginCallbackWithData:&callbackData calleeValue:constructor thisValue:nil argumentCount:argumentCount arguments:arguments];
-        result = impl->call(context, NULL, argumentCount, arguments, exception);
+        [context beginCallbackWithData:&callbackData calleeValue:constructor thisValue:nullptr argumentCount:argumentCount arguments:arguments];
+        result = impl->call(context, nullptr, argumentCount, arguments, exception);
         if (context.exception)
             *exception = valueInternalValue(context.exception);
         [context endCallbackWithData:&callbackData];
@@ -492,28 +484,28 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont
 
     JSGlobalContextRef contextRef = [context JSGlobalContextRef];
     if (*exception)
-        return 0;
+        return nullptr;
 
     if (!JSValueIsObject(contextRef, result)) {
         *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("Objective-C blocks called as constructors must return an object.")));
-        return 0;
+        return nullptr;
     }
     return (JSObjectRef)result;
 }
 
-const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) };
+const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) };
 
-ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
+ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, std::unique_ptr<ObjCCallbackFunctionImpl> impl)
     : Base(vm, globalObject->objcCallbackFunctionStructure())
     , m_functionCallback(functionCallback)
     , m_constructCallback(constructCallback)
-    , m_impl(impl)
+    , m_impl(WTF::move(impl))
 {
 }
 
-ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
+ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, const String& name, std::unique_ptr<ObjCCallbackFunctionImpl> impl)
 {
-    ObjCCallbackFunction* function = new (NotNull, allocateCell<ObjCCallbackFunction>(vm.heap)) ObjCCallbackFunction(vm, globalObject, objCCallbackFunctionCallAsFunction, objCCallbackFunctionCallAsConstructor, impl);
+    ObjCCallbackFunction* function = new (NotNull, allocateCell<ObjCCallbackFunction>(vm.heap)) ObjCCallbackFunction(vm, globalObject, objCCallbackFunctionCallAsFunction, objCCallbackFunctionCallAsConstructor, WTF::move(impl));
     function->finishCreation(vm, name);
     return function;
 }
@@ -544,7 +536,7 @@ ConstructType ObjCCallbackFunction::getConstructData(JSCell* cell, ConstructData
 String ObjCCallbackFunctionImpl::name()
 {
     if (m_type == CallbackInitMethod)
-        return class_getName(m_instanceClass);
+        return class_getName(m_instanceClass.get());
     // FIXME: Maybe we could support having the selector as the name of the non-init 
     // functions to make it a bit more user-friendly from the JS side?
     return "";
@@ -560,7 +552,7 @@ JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisOb
     case CallbackInitMethod: {
         RELEASE_ASSERT(!thisObject);
         target = [m_instanceClass alloc];
-        if (!target || ![target isKindOfClass:m_instanceClass]) {
+        if (!target || ![target isKindOfClass:m_instanceClass.get()]) {
             *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("self type check failed for Objective-C instance method")));
             return JSValueMakeUndefined(contextRef);
         }
@@ -570,7 +562,7 @@ JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisOb
     }
     case CallbackInstanceMethod: {
         target = tryUnwrapObjcObject(contextRef, thisObject);
-        if (!target || ![target isKindOfClass:m_instanceClass]) {
+        if (!target || ![target isKindOfClass:m_instanceClass.get()]) {
             *exception = toRef(JSC::createTypeError(toJS(contextRef), ASCIILiteral("self type check failed for Objective-C instance method")));
             return JSValueMakeUndefined(contextRef);
         }
@@ -621,7 +613,7 @@ static bool blockSignatureContainsClass()
     return containsClass;
 }
 
-inline bool skipNumber(const char*& position)
+static inline bool skipNumber(const char*& position)
 {
     if (!isASCIIDigit(*position))
         return false;
@@ -632,13 +624,13 @@ inline bool skipNumber(const char*& position)
 static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, const char* signatureWithObjcClasses)
 {
     if (!signatureWithObjcClasses)
-        return nil;
+        return nullptr;
 
     const char* position = signatureWithObjcClasses;
 
-    OwnPtr<CallbackResult> result = adoptPtr(parseObjCType<ResultTypeDelegate>(position));
+    auto result = parseObjCType<ResultTypeDelegate>(position);
     if (!result || !skipNumber(position))
-        return nil;
+        return nullptr;
 
     switch (type) {
     case CallbackInitMethod:
@@ -646,35 +638,36 @@ static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvoc
     case CallbackClassMethod:
         // Methods are passed two implicit arguments - (id)self, and the selector.
         if ('@' != *position++ || !skipNumber(position) || ':' != *position++ || !skipNumber(position))
-            return nil;
+            return nullptr;
         break;
     case CallbackBlock:
         // Blocks are passed one implicit argument - the block, of type "@?".
         if (('@' != *position++) || ('?' != *position++) || !skipNumber(position))
-            return nil;
+            return nullptr;
         // Only allow arguments of type 'id' if the block signature contains the NS type information.
         if ((!blockSignatureContainsClass() && strchr(position, '@')))
-            return nil;
+            return nullptr;
         break;
     }
 
-    OwnPtr<CallbackArgument> arguments = 0;
-    OwnPtr<CallbackArgument>* nextArgument = &arguments;
+    std::unique_ptr<CallbackArgument> arguments;
+    auto* nextArgument = &arguments;
     unsigned argumentCount = 0;
     while (*position) {
-        OwnPtr<CallbackArgument> argument = adoptPtr(parseObjCType<ArgumentTypeDelegate>(position));
+        auto argument = parseObjCType<ArgumentTypeDelegate>(position);
         if (!argument || !skipNumber(position))
-            return nil;
+            return nullptr;
 
-        *nextArgument = argument.release();
+        *nextArgument = WTF::move(argument);
         nextArgument = &(*nextArgument)->m_next;
         ++argumentCount;
     }
 
     JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
     JSC::JSLockHolder locker(exec);
-    OwnPtr<JSC::ObjCCallbackFunctionImpl> impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(invocation, type, instanceClass, arguments.release(), result.release()));
-    return toRef(JSC::ObjCCallbackFunction::create(exec->vm(), exec->lexicalGlobalObject(), impl->name(), impl.release()));
+    auto impl = std::make_unique<JSC::ObjCCallbackFunctionImpl>(invocation, type, instanceClass, WTF::move(arguments), WTF::move(result));
+    const String& name = impl->name();
+    return toRef(JSC::ObjCCallbackFunction::create(exec->vm(), exec->lexicalGlobalObject(), name, WTF::move(impl)));
 }
 
 JSObjectRef objCCallbackFunctionForInit(JSContext *context, Class cls, Protocol *protocol, SEL sel, const char* types)
@@ -688,8 +681,8 @@ JSObjectRef objCCallbackFunctionForMethod(JSContext *context, Class cls, Protoco
 {
     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:types]];
     [invocation setSelector:sel];
-    // We need to retain the target Class because m_invocation doesn't retain it
-    // by default (and we don't want it to).
+    // We need to retain the target Class because m_invocation doesn't retain it by default (and we don't want it to).
+    // FIXME: What releases it?
     if (!isInstanceMethod)
         [invocation setTarget:[cls retain]];
     return objCCallbackFunctionForInvocation(context, invocation, isInstanceMethod ? CallbackInstanceMethod : CallbackClassMethod, isInstanceMethod ? cls : nil, _protocol_getMethodTypeEncoding(protocol, sel, YES, isInstanceMethod));
@@ -698,7 +691,7 @@ JSObjectRef objCCallbackFunctionForMethod(JSContext *context, Class cls, Protoco
 JSObjectRef objCCallbackFunctionForBlock(JSContext *context, id target)
 {
     if (!_Block_has_signature(target))
-        return 0;
+        return nullptr;
     const char* signature = _Block_signature(target);
     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:signature]];
 
index c85bc9225167dc9d84d0f880bcb81bd420efda4c..128df5c905db610ad82c7392210cf91159b34108 100644 (file)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
+#import <objc/Protocol.h>
 #import <objc/runtime.h>
 #import <wtf/HashSet.h>
 #import <wtf/Vector.h>
@@ -163,7 +164,7 @@ typename DelegateType::ResultType parseObjCType(const char*& position)
     case 'l':
         return DelegateType::template typeInteger<long>();
     case 'q':
-        return DelegateType::template typeDouble<unsigned long long>();
+        return DelegateType::template typeDouble<long long>();
     case 'C':
         return DelegateType::template typeInteger<unsigned char>();
     case 'I':
index bf48d69d1832c68ac09fd1c5535c369a1b28b237..07a79ad99e6dc7f31c5f8fbaa9241ef12fea24d3 100644 (file)
 
 #include "CallFrame.h"
 #include "Identifier.h"
+#include "IdentifierInlines.h"
 #include "JSGlobalObject.h"
 #include <wtf/text/StringView.h>
 
 using namespace JSC;
 
-PassRefPtr<OpaqueJSString> OpaqueJSString::create(const String& string)
+RefPtr<OpaqueJSString> OpaqueJSString::create(const String& string)
 {
     if (string.isNull())
         return nullptr;
@@ -56,32 +57,26 @@ OpaqueJSString::~OpaqueJSString()
 
 String OpaqueJSString::string() const
 {
-    if (!this)
-        return String();
-
     // Return a copy of the wrapped string, because the caller may make it an Identifier.
     return m_string.isolatedCopy();
 }
 
 Identifier OpaqueJSString::identifier(VM* vm) const
 {
-    if (!this || m_string.isNull())
+    if (m_string.isNull())
         return Identifier();
 
     if (m_string.isEmpty())
         return Identifier(Identifier::EmptyIdentifier);
 
     if (m_string.is8Bit())
-        return Identifier(vm, m_string.characters8(), m_string.length());
+        return Identifier::fromString(vm, m_string.characters8(), m_string.length());
 
-    return Identifier(vm, m_string.characters16(), m_string.length());
+    return Identifier::fromString(vm, m_string.characters16(), m_string.length());
 }
 
 const UChar* OpaqueJSString::characters()
 {
-    if (!this)
-        return nullptr;
-
     // m_characters is put in a local here to avoid an extra atomic load.
     UChar* characters = m_characters;
     if (characters)
index 8fd90aed8a647d5830c88de30abf672521885c0b..208131b3b4158e7c6fcfde91e46c3577897adc66 100644 (file)
@@ -36,29 +36,29 @@ namespace JSC {
 }
 
 struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
-    static PassRefPtr<OpaqueJSString> create()
+    static Ref<OpaqueJSString> create()
     {
-        return adoptRef(new OpaqueJSString);
+        return adoptRef(*new OpaqueJSString);
     }
 
-    static PassRefPtr<OpaqueJSString> create(const LChar* characters, unsigned length)
+    static Ref<OpaqueJSString> create(const LChar* characters, unsigned length)
     {
-        return adoptRef(new OpaqueJSString(characters, length));
+        return adoptRef(*new OpaqueJSString(characters, length));
     }
 
-    static PassRefPtr<OpaqueJSString> create(const UChar* characters, unsigned length)
+    static Ref<OpaqueJSString> create(const UChar* characters, unsigned length)
     {
-        return adoptRef(new OpaqueJSString(characters, length));
+        return adoptRef(*new OpaqueJSString(characters, length));
     }
 
-    JS_EXPORT_PRIVATE static PassRefPtr<OpaqueJSString> create(const String&);
+    JS_EXPORT_PRIVATE static RefPtr<OpaqueJSString> create(const String&);
 
     JS_EXPORT_PRIVATE ~OpaqueJSString();
 
-    bool is8Bit() { return this ? m_string.is8Bit() : false; }
-    const LChar* characters8() { return this ? m_string.characters8() : nullptr; }
-    const UChar* characters16() { return this ? m_string.characters16() : nullptr; }
-    unsigned length() { return this ? m_string.length() : 0; }
+    bool is8Bit() { return m_string.is8Bit(); }
+    const LChar* characters8() { return m_string.characters8(); }
+    const UChar* characters16() { return m_string.characters16(); }
+    unsigned length() { return m_string.length(); }
 
     const UChar* characters();
 
index 24695ed9a8bec99daf204f0310264709f6f693bd..250d4108e930d5dd4c01a9e8e39a9f675ad4ed9e 100644 (file)
 #include <AvailabilityMacros.h>
 #include <CoreFoundation/CoreFoundation.h>
 
-#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100
 /* To support availability macros that mention newer OS X versions when building on older OS X versions,
    we provide our own definitions of the underlying macros that the availability macros expand to. We're
    free to expand the macros as no-ops since frameworks built on older OS X versions only ship bundled with
    an application rather than as part of the system.
 */
 
-#ifndef __NSi_10_10
-#define __NSi_10_10 introduced=10.0
+#ifndef __NSi_10_10 // Building from trunk rather than SDK.
+#define __NSi_10_10 introduced=10.0 // Use 10.0 to indicate that everything is available.
+#endif
+
+#ifndef __NSi_10_11 // Building from trunk rather than SDK.
+#define __NSi_10_11 introduced=10.0 // Use 10.0 to indicate that everything is available.
 #endif
 
 #ifndef __AVAILABILITY_INTERNAL__MAC_10_9
@@ -58,7 +62,7 @@
 #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER
 #endif
 
-#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 */
+#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 101100 */
 
 #else
 #define CF_AVAILABLE(_mac, _ios)
diff --git a/API/tests/CompareAndSwapTest.cpp b/API/tests/CompareAndSwapTest.cpp
new file mode 100644 (file)
index 0000000..c78d47d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CompareAndSwapTest.h"
+
+#include <stdio.h>
+#include <wtf/Atomics.h>
+#include <wtf/Threading.h>
+
+class Bitmap {
+public:
+    Bitmap() { clearAll(); }
+
+    inline void clearAll();
+    inline bool concurrentTestAndSet(size_t n);
+    inline size_t numBits() const { return words * wordSize; }
+
+private:
+    static const size_t Size = 4096*10;
+
+    static const unsigned wordSize = sizeof(uint8_t) * 8;
+    static const unsigned words = (Size + wordSize - 1) / wordSize;
+    static const uint8_t one = 1;
+
+    uint8_t bits[words];
+};
+
+inline void Bitmap::clearAll()
+{
+    memset(&bits, 0, sizeof(bits));
+}
+
+inline bool Bitmap::concurrentTestAndSet(size_t n)
+{
+    uint8_t mask = one << (n % wordSize);
+    size_t index = n / wordSize;
+    uint8_t* wordPtr = &bits[index];
+    uint8_t oldValue;
+    do {
+        oldValue = *wordPtr;
+        if (oldValue & mask)
+            return true;
+    } while (!WTF::weakCompareAndSwap(wordPtr, oldValue, oldValue | mask));
+    return false;
+}
+
+struct Data {
+    Bitmap* bitmap;
+    int id;
+    int numThreads;
+};
+
+static void setBitThreadFunc(void* p)
+{
+    Data* data = reinterpret_cast<Data*>(p);
+    Bitmap* bitmap = data->bitmap;
+    size_t numBits = bitmap->numBits();
+
+    // The computed start index here is heuristic that seems to maximize (anecdotally)
+    // the chance for the CAS issue to manifest.
+    size_t start = (numBits * (data->numThreads - data->id)) / data->numThreads;
+
+    printf("   started Thread %d\n", data->id);
+    for (size_t i = start; i < numBits; i++)
+        while (!bitmap->concurrentTestAndSet(i)) { }
+    for (size_t i = 0; i < start; i++)
+        while (!bitmap->concurrentTestAndSet(i)) { }
+
+    printf("   finished Thread %d\n", data->id);
+}
+
+void testCompareAndSwap()
+{
+    Bitmap bitmap;
+    const int numThreads = 5;
+    ThreadIdentifier threadIDs[numThreads];
+    Data data[numThreads];
+
+    WTF::initializeThreading();
+    
+    printf("Starting %d threads for CompareAndSwap test.  Test should complete without hanging.\n", numThreads);
+    for (int i = 0; i < numThreads; i++) {
+        data[i].bitmap = &bitmap;
+        data[i].id = i;
+        data[i].numThreads = numThreads;
+        std::function<void()> threadFunc = std::bind(setBitThreadFunc, &data[i]);
+        threadIDs[i] = createThread("setBitThreadFunc", threadFunc);
+    }
+
+    printf("Waiting for %d threads to join\n", numThreads);
+    for (int i = 0; i < numThreads; i++)
+        waitForThreadCompletion(threadIDs[i]);
+
+    printf("PASS: CompareAndSwap test completed without a hang\n");
+}
diff --git a/API/tests/CompareAndSwapTest.h b/API/tests/CompareAndSwapTest.h
new file mode 100644 (file)
index 0000000..73fa0de
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CompareAndSwapTest_h
+#define CompareAndSwapTest_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Regression test for webkit.org/b/142513 */
+void testCompareAndSwap();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CompareAndSwapTest_h */
index b4bc9ec98cd37cc12adc844eefb8523c72b3e95e..e2837a63320b7b971f175fe343a4a4797e8417ef 100644 (file)
@@ -37,11 +37,7 @@ extern "C" void checkResult(NSString *description, bool passed);
 + (void) roundTripThroughObjCDateTest;
 @end
 
-#if (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000) || (TARGET_OS_MAC && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
 static unsigned unitFlags = NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;
-#else
-static unsigned unitFlags = NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit;
-#endif
 
 @implementation DateTests
 + (void) NSDateToJSDateTest
diff --git a/API/tests/ExecutionTimeLimitTest.cpp b/API/tests/ExecutionTimeLimitTest.cpp
new file mode 100644 (file)
index 0000000..6ff98d4
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ExecutionTimeLimitTest.h"
+
+#if OS(DARWIN)
+
+#include "JSContextRefPrivate.h"
+#include "JavaScriptCore.h"
+
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+static JSGlobalContextRef context = nullptr;
+
+static double currentCPUTime()
+{
+    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+    thread_basic_info_data_t info;
+    
+    /* Get thread information */
+    mach_port_t threadPort = mach_thread_self();
+    thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount);
+    mach_port_deallocate(mach_task_self(), threadPort);
+    
+    double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
+    time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
+    
+    return time;
+}
+
+static JSValueRef currentCPUTimeAsJSFunctionCallback(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    UNUSED_PARAM(functionObject);
+    UNUSED_PARAM(thisObject);
+    UNUSED_PARAM(argumentCount);
+    UNUSED_PARAM(arguments);
+    UNUSED_PARAM(exception);
+    
+    ASSERT(JSContextGetGlobalContext(ctx) == context);
+    return JSValueMakeNumber(ctx, currentCPUTime());
+}
+
+bool shouldTerminateCallbackWasCalled = false;
+static bool shouldTerminateCallback(JSContextRef ctx, void* context)
+{
+    UNUSED_PARAM(ctx);
+    UNUSED_PARAM(context);
+    shouldTerminateCallbackWasCalled = true;
+    return true;
+}
+
+bool cancelTerminateCallbackWasCalled = false;
+static bool cancelTerminateCallback(JSContextRef ctx, void* context)
+{
+    UNUSED_PARAM(ctx);
+    UNUSED_PARAM(context);
+    cancelTerminateCallbackWasCalled = true;
+    return false;
+}
+
+int extendTerminateCallbackCalled = 0;
+static bool extendTerminateCallback(JSContextRef ctx, void* context)
+{
+    UNUSED_PARAM(context);
+    extendTerminateCallbackCalled++;
+    if (extendTerminateCallbackCalled == 1) {
+        JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
+        JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
+        return false;
+    }
+    return true;
+}
+
+
+int testExecutionTimeLimit()
+{
+    context = JSGlobalContextCreateInGroup(nullptr, nullptr);
+
+    JSContextGroupRef contextGroup = JSContextGetGroup(context);
+    JSObjectRef globalObject = JSContextGetGlobalObject(context);
+    ASSERT(JSValueIsObject(context, globalObject));
+
+    JSValueRef v = nullptr;
+    JSValueRef exception = nullptr;
+    bool failed = false;
+
+    JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime");
+    JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTimeAsJSFunctionCallback);
+    JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, nullptr);
+    JSStringRelease(currentCPUTimeStr);
+    
+    /* Test script timeout: */
+    JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0);
+    {
+        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+        double startTime;
+        double endTime;
+        exception = nullptr;
+        shouldTerminateCallbackWasCalled = false;
+        startTime = currentCPUTime();
+        v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+        endTime = currentCPUTime();
+        
+        if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
+            printf("PASS: script timed out as expected.\n");
+        else {
+            if (!((endTime - startTime) < .150f))
+                printf("FAIL: script did not time out as expected.\n");
+            if (!shouldTerminateCallbackWasCalled)
+                printf("FAIL: script timeout callback was not called.\n");
+            failed = true;
+        }
+        
+        if (!exception) {
+            printf("FAIL: TerminatedExecutionException was not thrown.\n");
+            failed = true;
+        }
+    }
+    
+    /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */
+    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0);
+    {
+        const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }";
+        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+        double startTime;
+        double endTime;
+        exception = nullptr;
+        shouldTerminateCallbackWasCalled = false;
+        startTime = currentCPUTime();
+        v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+        endTime = currentCPUTime();
+        
+        if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) {
+            if (!((endTime - startTime) < .150f))
+                printf("FAIL: script did not time out as expected.\n");
+            if (!shouldTerminateCallbackWasCalled)
+                printf("FAIL: script timeout callback was not called.\n");
+            failed = true;
+        }
+        
+        if (exception)
+            printf("PASS: TerminatedExecutionException was not catchable as expected.\n");
+        else {
+            printf("FAIL: TerminatedExecutionException was caught.\n");
+            failed = true;
+        }
+    }
+    
+    /* Test script timeout with no callback: */
+    JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, 0, 0);
+    {
+        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+        double startTime;
+        double endTime;
+        exception = nullptr;
+        startTime = currentCPUTime();
+        v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+        endTime = currentCPUTime();
+        
+        if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
+            printf("PASS: script timed out as expected when no callback is specified.\n");
+        else {
+            if (!((endTime - startTime) < .150f))
+                printf("FAIL: script did not time out as expected when no callback is specified.\n");
+            failed = true;
+        }
+        
+        if (!exception) {
+            printf("FAIL: TerminatedExecutionException was not thrown.\n");
+            failed = true;
+        }
+    }
+    
+    /* Test script timeout cancellation: */
+    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0);
+    {
+        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+        double startTime;
+        double endTime;
+        exception = nullptr;
+        startTime = currentCPUTime();
+        v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+        endTime = currentCPUTime();
+        
+        if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception)
+            printf("PASS: script timeout was cancelled as expected.\n");
+        else {
+            if (((endTime - startTime) < .150) || exception)
+                printf("FAIL: script timeout was not cancelled.\n");
+            if (!cancelTerminateCallbackWasCalled)
+                printf("FAIL: script timeout callback was not called.\n");
+            failed = true;
+        }
+        
+        if (exception) {
+            printf("FAIL: Unexpected TerminatedExecutionException thrown.\n");
+            failed = true;
+        }
+    }
+    
+    /* Test script timeout extension: */
+    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0);
+    {
+        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } ";
+        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+        double startTime;
+        double endTime;
+        double deltaTime;
+        exception = nullptr;
+        startTime = currentCPUTime();
+        v = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
+        endTime = currentCPUTime();
+        deltaTime = endTime - startTime;
+        
+        if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception)
+            printf("PASS: script timeout was extended as expected.\n");
+        else {
+            if (deltaTime < .200f)
+                printf("FAIL: script timeout was not extended as expected.\n");
+            else if (deltaTime >= .500f)
+                printf("FAIL: script did not timeout.\n");
+            
+            if (extendTerminateCallbackCalled < 1)
+                printf("FAIL: script timeout callback was not called.\n");
+            if (extendTerminateCallbackCalled < 2)
+                printf("FAIL: script timeout callback was not called after timeout extension.\n");
+            
+            if (!exception)
+                printf("FAIL: TerminatedExecutionException was not thrown during timeout extension test.\n");
+            
+            failed = true;
+        }
+    }
+
+    JSGlobalContextRelease(context);
+    return failed;
+}
+
+#endif // OS(DARWIN)
diff --git a/API/tests/ExecutionTimeLimitTest.h b/API/tests/ExecutionTimeLimitTest.h
new file mode 100644 (file)
index 0000000..8294a86
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ExecutionTimeLimitTest_h
+#define ExecutionTimeLimitTest_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Returns 1 if failures were encountered.  Else, returns 0. */
+int testExecutionTimeLimit();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ExecutionTimeLimitTest_h */
diff --git a/API/tests/GlobalContextWithFinalizerTest.cpp b/API/tests/GlobalContextWithFinalizerTest.cpp
new file mode 100644 (file)
index 0000000..7023bc3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GlobalContextWithFinalizerTest.h"
+
+#include "JavaScriptCore.h"
+#include <wtf/DataLog.h>
+
+static bool failed = true;
+
+static void finalize(JSObjectRef)
+{
+    failed = false;
+}
+
+int testGlobalContextWithFinalizer()
+{
+    JSClassDefinition def = kJSClassDefinitionEmpty;
+    def.className = "testClass";
+    def.finalize = finalize;
+    JSClassRef classRef = JSClassCreate(&def);
+    
+    JSGlobalContextRef ref = JSGlobalContextCreateInGroup(nullptr, classRef);
+    JSGlobalContextRelease(ref);
+    JSClassRelease(classRef);
+
+    if (failed)
+        printf("FAIL: JSGlobalContextRef did not call its JSClassRef finalizer.\n");
+    else
+        printf("PASS: JSGlobalContextRef called its JSClassRef finalizer as expected.\n");
+
+    return failed;
+}
diff --git a/API/tests/GlobalContextWithFinalizerTest.h b/API/tests/GlobalContextWithFinalizerTest.h
new file mode 100644 (file)
index 0000000..55b439f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GlobalContextWithFinalizerTest_h
+#define GlobalContextWithFinalizerTest_h
+
+#include "JSContextRefPrivate.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Returns 1 if failures were encountered.  Else, returns 0. */
+int testGlobalContextWithFinalizer();
+    
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* GlobalContextWithFinalizerTest_h */
diff --git a/API/tests/Regress141275.h b/API/tests/Regress141275.h
new file mode 100644 (file)
index 0000000..bf3492a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+void runRegress141275();
+
+#endif // JSC_OBJC_API_ENABLED
+
diff --git a/API/tests/Regress141275.mm b/API/tests/Regress141275.mm
new file mode 100644 (file)
index 0000000..18e186a
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "Regress141275.h"
+
+#import <Foundation/Foundation.h>
+#import <objc/objc.h>
+#import <objc/runtime.h>
+
+#if JSC_OBJC_API_ENABLED
+
+extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+
+extern int failed;
+
+static const NSUInteger scriptToEvaluate = 50;
+
+@interface JSTEvaluator : NSObject
+- (instancetype)initWithScript:(NSString*)script;
+
+- (void)insertSignPostWithCompletion:(void(^)(NSError* error))completionHandler;
+
+- (void)evaluateScript:(NSString*)script completion:(void(^)(NSError* error))completionHandler;
+- (void)evaluateBlock:(void(^)(JSContext* context))evaluationBlock completion:(void(^)(NSError* error))completionHandler;
+
+- (void)waitForTasksDoneAndReportResults;
+@end
+
+
+static const NSString* JSTEvaluatorThreadContextKey = @"JSTEvaluatorThreadContextKey";
+
+/*
+ * A JSTEvaluatorThreadContext is kept in the thread dictionary of threads used by JSEvaluator.
+ *
+ * This includes the run loop thread, and any threads used by _jsSourcePerformQueue to execute a task.
+ */
+@interface JSTEvaluatorThreadContext : NSObject
+@property (weak) JSTEvaluator* evaluator;
+@property (strong) JSContext* jsContext;
+@end
+
+@implementation JSTEvaluatorThreadContext
+@end
+
+
+/*!
+ * A JSTEvaluatorTask is a single task to be executed.
+ *
+ * JSTEvaluator keeps a list of pending tasks. The run loop thread is repsonsible for feeding pending tasks to the _jsSourcePerformQueue, while respecting sign posts.
+ */
+@interface JSTEvaluatorTask : NSObject
+
+@property (nonatomic, copy) void (^evaluateBlock)(JSContext* jsContext);
+@property (nonatomic, copy) void (^completionHandler)(NSError* error);
+@property (nonatomic, copy) NSError* error;
+
++ (instancetype)evaluatorTaskWithEvaluateBlock:(void (^)(JSContext*))block completionHandler:(void (^)(NSError* error))completionBlock;
+
+@end
+
+@implementation JSTEvaluatorTask
+
++ (instancetype)evaluatorTaskWithEvaluateBlock:(void (^)(JSContext*))evaluationBlock completionHandler:(void (^)(NSError* error))completionHandler
+{
+    JSTEvaluatorTask* task = [self new];
+    task.evaluateBlock = evaluationBlock;
+    task.completionHandler = completionHandler;
+    return task;
+}
+
+@end
+
+@implementation JSTEvaluator {
+    dispatch_queue_t _jsSourcePerformQueue;
+    dispatch_semaphore_t _allScriptsDone;
+    CFRunLoopRef _jsThreadRunLoop;
+    CFRunLoopSourceRef _jsThreadRunLoopSource;
+    JSContext* _jsContext;
+    NSMutableArray* __pendingTasks;
+}
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        _jsSourcePerformQueue = dispatch_queue_create("JSTEval", DISPATCH_QUEUE_CONCURRENT);
+
+        _allScriptsDone = dispatch_semaphore_create(0);
+
+        _jsContext = [JSContext new];
+        _jsContext.name = @"JSTEval";
+        __pendingTasks = [NSMutableArray new];
+
+        NSThread* jsThread = [[NSThread alloc] initWithTarget:self selector:@selector(_jsThreadMain) object:nil];
+        [jsThread setName:@"JSTEval"];
+        [jsThread start];
+
+    }
+    return self;
+}
+
+- (instancetype)initWithScript:(NSString*)script
+{
+    self = [self init];
+    if (self) {
+        __block NSError* scriptError = nil;
+        dispatch_semaphore_t dsema = dispatch_semaphore_create(0);
+        [self evaluateScript:script
+            completion:^(NSError* error) {
+                scriptError = error;
+                dispatch_semaphore_signal(dsema);
+            }];
+        dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
+    }
+    return self;
+}
+
+- (void)_accessPendingTasksWithBlock:(void(^)(NSMutableArray* pendingTasks))block
+{
+    @synchronized(self) {
+        block(__pendingTasks);
+        if (__pendingTasks.count > 0) {
+            if (_jsThreadRunLoop && _jsThreadRunLoopSource) {
+                CFRunLoopSourceSignal(_jsThreadRunLoopSource);
+                CFRunLoopWakeUp(_jsThreadRunLoop);
+            }
+        }
+    }
+}
+
+- (void)insertSignPostWithCompletion:(void(^)(NSError* error))completionHandler
+{
+    [self _accessPendingTasksWithBlock:^(NSMutableArray* pendingTasks) {
+        JSTEvaluatorTask* task = [JSTEvaluatorTask evaluatorTaskWithEvaluateBlock:nil
+            completionHandler:completionHandler];
+
+        [pendingTasks addObject:task];
+    }];
+}
+
+- (void)evaluateScript:(NSString*)script completion:(void(^)(NSError* error))completionHandler
+{
+    [self evaluateBlock:^(JSContext* context) {
+        [context evaluateScript:script];
+    } completion:completionHandler];
+}
+
+- (void)evaluateBlock:(void(^)(JSContext* context))evaluationBlock completion:(void(^)(NSError* error))completionHandler
+{
+    NSParameterAssert(evaluationBlock != nil);
+    [self _accessPendingTasksWithBlock:^(NSMutableArray* pendingTasks) {
+        JSTEvaluatorTask* task = [JSTEvaluatorTask evaluatorTaskWithEvaluateBlock:evaluationBlock
+            completionHandler:completionHandler];
+
+        [pendingTasks addObject:task];
+    }];
+}
+
+- (void)waitForTasksDoneAndReportResults
+{
+    NSString* passFailString = @"PASSED";
+
+    if (!dispatch_semaphore_wait(_allScriptsDone, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC))) {
+        int totalScriptsRun = [_jsContext[@"counter"] toInt32];
+
+        if (totalScriptsRun != scriptToEvaluate) {
+            passFailString = @"FAILED";
+            failed = 1;
+        }
+
+        NSLog(@"  Ran a total of %d scripts: %@", totalScriptsRun, passFailString);
+    } else {
+        passFailString = @"FAILED";
+        failed = 1;
+        NSLog(@"  Error, timeout waiting for all tasks to complete: %@", passFailString);
+    }
+}
+
+static void __JSTRunLoopSourceScheduleCallBack(void* info, CFRunLoopRef rl, CFStringRef)
+{
+    @autoreleasepool {
+        [(__bridge JSTEvaluator*)info _sourceScheduledOnRunLoop:rl];
+    }
+}
+
+static void __JSTRunLoopSourcePerformCallBack(void* info )
+{
+    @autoreleasepool {
+        [(__bridge JSTEvaluator*)info _sourcePerform];
+    }
+}
+
+static void __JSTRunLoopSourceCancelCallBack(void* info, CFRunLoopRef rl, CFStringRef)
+{
+    @autoreleasepool {
+        [(__bridge JSTEvaluator*)info _sourceCanceledOnRunLoop:rl];
+    }
+}
+
+- (void)_jsThreadMain
+{
+    @autoreleasepool {
+        const CFIndex kRunLoopSourceContextVersion = 0;
+        CFRunLoopSourceContext sourceContext = {
+            kRunLoopSourceContextVersion, (__bridge void*)(self),
+            NULL, NULL, NULL, NULL, NULL,
+            __JSTRunLoopSourceScheduleCallBack,
+            __JSTRunLoopSourceCancelCallBack,
+            __JSTRunLoopSourcePerformCallBack
+        };
+
+        @synchronized(self) {
+            _jsThreadRunLoop = CFRunLoopGetCurrent();
+            CFRetain(_jsThreadRunLoop);
+
+            _jsThreadRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sourceContext);
+            CFRunLoopAddSource(_jsThreadRunLoop, _jsThreadRunLoopSource, kCFRunLoopDefaultMode);
+        }
+
+        CFRunLoopRun();
+
+        @synchronized(self) {
+            NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
+            [threadDict removeObjectForKey:threadDict[JSTEvaluatorThreadContextKey]];
+
+            CFRelease(_jsThreadRunLoopSource);
+            _jsThreadRunLoopSource = NULL;
+
+            CFRelease(_jsThreadRunLoop);
+            _jsThreadRunLoop = NULL;
+
+            __pendingTasks = nil;
+        }
+    }
+}
+
+- (void)_sourceScheduledOnRunLoop:(CFRunLoopRef)runLoop
+{
+    UNUSED_PARAM(runLoop);
+    assert([[[NSThread currentThread] name] isEqualToString:@"JSTEval"]);
+
+    // Wake up the run loop in case requests were submitted prior to the
+    // run loop & run loop source getting created.
+    CFRunLoopSourceSignal(_jsThreadRunLoopSource);
+    CFRunLoopWakeUp(_jsThreadRunLoop);
+}
+
+- (void)_setupEvaluatorThreadContextIfNeeded
+{
+    NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
+    JSTEvaluatorThreadContext* context = threadDict[JSTEvaluatorThreadContextKey];
+    // The evaluator may be other evualuator, or nil if this thread has not been used before. Eaither way take ownership.
+    if (context.evaluator != self) {
+        context = [JSTEvaluatorThreadContext new];
+        context.evaluator = self;
+        threadDict[JSTEvaluatorThreadContextKey] = context;
+    }
+}
+
+- (void)_callCompletionHandler:(void(^)(NSError* error))completionHandler ifNeededWithError:(NSError*)error
+{
+    if (completionHandler) {
+        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            completionHandler(error);
+        });
+    }
+}
+
+- (void)_sourcePerform
+{
+    assert([[[NSThread currentThread] name] isEqualToString:@"JSTEval"]);
+
+    __block NSArray* tasks = nil;
+    [self _accessPendingTasksWithBlock:^(NSMutableArray* pendingTasks) {
+        // No signpost, take all tasks.
+        tasks = [pendingTasks copy];
+        [pendingTasks removeAllObjects];
+    }];
+
+    if (tasks.count > 0) {
+        for (JSTEvaluatorTask* task in tasks) {
+            dispatch_block_t block = ^{
+                NSError* error = nil;
+                if (task.evaluateBlock) {
+                    [self _setupEvaluatorThreadContextIfNeeded];
+                    task.evaluateBlock(_jsContext);
+                    if (_jsContext.exception) {
+                        NSLog(@"Did fail on JSContext: %@", _jsContext.name);
+                        NSDictionary* userInfo = @{ NSLocalizedDescriptionKey : [_jsContext.exception[@"message"] toString] };
+                        error = [NSError errorWithDomain:@"JSTEvaluator" code:1 userInfo:userInfo];
+                        _jsContext.exception = nil;
+                    }
+                }
+                [self _callCompletionHandler:task.completionHandler ifNeededWithError:error];
+            };
+
+            if (task.evaluateBlock)
+                dispatch_async(_jsSourcePerformQueue, block);
+            else
+                dispatch_barrier_async(_jsSourcePerformQueue, block);
+        }
+
+        dispatch_barrier_sync(_jsSourcePerformQueue, ^{
+            if ([_jsContext[@"counter"] toInt32] == scriptToEvaluate)
+                dispatch_semaphore_signal(_allScriptsDone);
+        });
+    }
+}
+
+- (void)_sourceCanceledOnRunLoop:(CFRunLoopRef)runLoop
+{
+    UNUSED_PARAM(runLoop);
+    assert([[[NSThread currentThread] name] isEqualToString:@"JSTEval"]);
+
+    @synchronized(self) {
+        assert(_jsThreadRunLoop);
+        assert(_jsThreadRunLoopSource);
+
+        CFRunLoopRemoveSource(_jsThreadRunLoop, _jsThreadRunLoopSource, kCFRunLoopDefaultMode);
+        CFRunLoopStop(_jsThreadRunLoop);
+    }
+}
+
+@end
+
+void runRegress141275()
+{
+    // Test that we can execute the same script from multiple threads with a shared context.
+    // See <https://webkit.org/b/141275>
+    NSLog(@"TEST: Testing multiple threads executing the same script with a shared context");
+
+    @autoreleasepool {
+        JSTEvaluator* evaluator = [[JSTEvaluator alloc] initWithScript:@"this['counter'] = 0;"];
+
+        void (^showErrorIfNeeded)(NSError* error) = ^(NSError* error) {
+            if (error) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    NSLog(@"Error: %@", error);
+                });
+            }
+        };
+
+        [evaluator evaluateBlock:^(JSContext* context) {
+            JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+        } completion:showErrorIfNeeded];
+
+        [evaluator evaluateBlock:^(JSContext* context) {
+            context[@"wait"] = ^{
+                [NSThread sleepForTimeInterval:0.01];
+            };
+        } completion:^(NSError* error) {
+            if (error) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    NSLog(@"Error: %@", error);
+                });
+            }
+            for (unsigned i = 0; i < scriptToEvaluate; i++)
+                [evaluator evaluateScript:@"this['counter']++; this['wait']();" completion:showErrorIfNeeded];
+        }];
+
+        [evaluator waitForTasksDoneAndReportResults];
+    }
+}
+
+#endif // JSC_OBJC_API_ENABLED
index 60d7dc0b593f00d6c7d8652917e6627df3789eb7..fc4914b7ab69527095ef0e658a4b342f590495d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2015 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
 
-#if OS(DARWIN)
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <sys/time.h>
-#endif
-
 #if OS(WINDOWS)
 #include <windows.h>
 #endif
 
+#include "CompareAndSwapTest.h"
 #include "CustomGlobalObjectClassTest.h"
+#include "GlobalContextWithFinalizerTest.h"
+
+#if OS(DARWIN)
+#include "ExecutionTimeLimitTest.h"
+#endif
 
 #if JSC_OBJC_API_ENABLED
 void testObjectiveCAPI(void);
@@ -84,11 +84,13 @@ static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue
     size_t jsSize = JSStringGetMaximumUTF8CStringSize(valueAsString);
     char* jsBuffer = (char*)malloc(jsSize);
     JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
-    
+
     unsigned i;
     for (i = 0; jsBuffer[i]; i++) {
         if (jsBuffer[i] != expectedValue[i]) {
             fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]);
+            fprintf(stderr, "value: %s\n", jsBuffer);
+            fprintf(stderr, "expectedValue: %s\n", expectedValue);
             failed = 1;
         }
     }
@@ -123,7 +125,11 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa
     }
     
     if (jsLength != (size_t)cfLength) {
-        fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
+#if OS(WINDOWS)
+        fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%Iu) != cfLength(%Iu)\n", jsLength, (size_t)cfLength);
+#else
+        fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%zu) != cfLength(%zu)\n", jsLength, (size_t)cfLength);
+#endif
         failed = 1;
     }
 
@@ -954,6 +960,7 @@ static JSStaticValue globalObject_staticValues[] = {
 
 static JSStaticFunction globalObject_staticFunctions[] = {
     { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
+    { "globalStaticFunction2", globalObject_call, kJSPropertyAttributeNone },
     { "gc", functionGC, kJSPropertyAttributeNone },
     { 0, 0, 0 }
 };
@@ -1108,77 +1115,27 @@ static void checkConstnessInJSObjectNames()
     val.name = "something";
 }
 
-#if OS(DARWIN)
-static double currentCPUTime()
-{
-    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
-    thread_basic_info_data_t info;
-
-    /* Get thread information */
-    mach_port_t threadPort = mach_thread_self();
-    thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount);
-    mach_port_deallocate(mach_task_self(), threadPort);
-    
-    double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
-    time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
-    
-    return time;
-}
-
-static JSValueRef currentCPUTime_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
-    UNUSED_PARAM(functionObject);
-    UNUSED_PARAM(thisObject);
-    UNUSED_PARAM(argumentCount);
-    UNUSED_PARAM(arguments);
-    UNUSED_PARAM(exception);
-
-    ASSERT(JSContextGetGlobalContext(ctx) == context);
-    return JSValueMakeNumber(ctx, currentCPUTime());
-}
-
-bool shouldTerminateCallbackWasCalled = false;
-static bool shouldTerminateCallback(JSContextRef ctx, void* context)
-{
-    UNUSED_PARAM(ctx);
-    UNUSED_PARAM(context);
-    shouldTerminateCallbackWasCalled = true;
-    return true;
-}
-
-bool cancelTerminateCallbackWasCalled = false;
-static bool cancelTerminateCallback(JSContextRef ctx, void* context)
-{
-    UNUSED_PARAM(ctx);
-    UNUSED_PARAM(context);
-    cancelTerminateCallbackWasCalled = true;
-    return false;
-}
-
-int extendTerminateCallbackCalled = 0;
-static bool extendTerminateCallback(JSContextRef ctx, void* context)
-{
-    UNUSED_PARAM(context);
-    extendTerminateCallbackCalled++;
-    if (extendTerminateCallbackCalled == 1) {
-        JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
-        JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
-        return false;
-    }
-    return true;
-}
-#endif /* OS(DARWIN) */
-
 
 int main(int argc, char* argv[])
 {
 #if OS(WINDOWS)
+#if defined(_M_X64) || defined(__x86_64__)
+    // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+    // if the feature has been disabled in firmware. This causes us to crash
+    // in some of the math functions. For now, we disable those optimizations
+    // because Microsoft is not going to fix the problem in VS2013.
+    // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+    _set_FMA3_enable(0);
+#endif
+
     // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
     // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
     // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
     ::SetErrorMode(0);
 #endif
 
+    testCompareAndSwap();
+
 #if JSC_OBJC_API_ENABLED
     testObjectiveCAPI();
 #endif
@@ -1292,6 +1249,8 @@ int main(int argc, char* argv[])
 
     ASSERT(!JSValueIsBoolean(context, NULL));
     ASSERT(!JSValueIsObject(context, NULL));
+    ASSERT(!JSValueIsArray(context, NULL));
+    ASSERT(!JSValueIsDate(context, NULL));
     ASSERT(!JSValueIsString(context, NULL));
     ASSERT(!JSValueIsNumber(context, NULL));
     ASSERT(!JSValueIsUndefined(context, NULL));
@@ -1452,8 +1411,10 @@ int main(int argc, char* argv[])
     } else
         printf("PASS: Correctly serialised with indent of 4.\n");
     JSStringRelease(str);
-    JSStringRef src = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
-    JSValueRef unstringifiableObj = JSEvaluateScript(context, src, NULL, NULL, 1, NULL);
+
+    str = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
+    JSValueRef unstringifiableObj = JSEvaluateScript(context, str, NULL, NULL, 1, NULL);
+    JSStringRelease(str);
     
     str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0);
     if (str) {
@@ -1636,7 +1597,7 @@ int main(int argc, char* argv[])
     ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
     ASSERT(JSValueIsObject(context, exception));
     v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
-    assertEqualsAsNumber(v, 1);
+    assertEqualsAsNumber(v, 2);
     JSStringRelease(functionBody);
     JSStringRelease(line);
 
@@ -1646,7 +1607,7 @@ int main(int argc, char* argv[])
     ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, -42, &exception));
     ASSERT(JSValueIsObject(context, exception));
     v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
-    assertEqualsAsNumber(v, 1);
+    assertEqualsAsNumber(v, 2);
     JSStringRelease(functionBody);
     JSStringRelease(line);
 
@@ -1656,7 +1617,7 @@ int main(int argc, char* argv[])
     ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
     ASSERT(JSValueIsObject(context, exception));
     v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
-    assertEqualsAsNumber(v, 2);
+    assertEqualsAsNumber(v, 3);
     JSStringRelease(functionBody);
     JSStringRelease(line);
 
@@ -1690,7 +1651,7 @@ int main(int argc, char* argv[])
     JSStringRelease(functionBody);
     
     string = JSValueToStringCopy(context, function, NULL);
-    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}");
+    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {\nreturn foo;\n}");
     JSStringRelease(string);
 
     JSStringRef print = JSStringCreateWithUTF8CString("print");
@@ -1821,6 +1782,16 @@ int main(int argc, char* argv[])
     ASSERT(JSValueIsEqual(context, v, o, NULL));
     JSStringRelease(script);
 
+    script = JSStringCreateWithUTF8CString("[ ]");
+    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+    ASSERT(JSValueIsArray(context, v));
+    JSStringRelease(script);
+
+    script = JSStringCreateWithUTF8CString("new Date");
+    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+    ASSERT(JSValueIsDate(context, v));
+    JSStringRelease(script);
+
     exception = NULL;
     script = JSStringCreateWithUTF8CString("rreturn Array;");
     JSStringRef sourceURL = JSStringCreateWithUTF8CString("file:///foo/bar.js");
@@ -1878,158 +1849,32 @@ int main(int argc, char* argv[])
         free(scriptUTF8);
     }
 
-#if OS(DARWIN)
-    JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime");
-    JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTime_callAsFunction);
-    JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, NULL); 
-    JSStringRelease(currentCPUTimeStr);
-
-    /* Test script timeout: */
-    JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0);
-    {
-        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
-        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
-        double startTime;
-        double endTime;
-        exception = NULL;
-        shouldTerminateCallbackWasCalled = false;
-        startTime = currentCPUTime();
-        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
-        endTime = currentCPUTime();
-
-        if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
-            printf("PASS: script timed out as expected.\n");
-        else {
-            if (!((endTime - startTime) < .150f))
-                printf("FAIL: script did not timed out as expected.\n");
-            if (!shouldTerminateCallbackWasCalled)
-                printf("FAIL: script timeout callback was not called.\n");
-            failed = true;
-        }
-
-        if (!exception) {
-            printf("FAIL: TerminatedExecutionException was not thrown.\n");
-            failed = true;
-        }
-    }
-
-    /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */
-    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0);
-    {
-        const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }";
-        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
-        double startTime;
-        double endTime;
-        exception = NULL;
-        shouldTerminateCallbackWasCalled = false;
-        startTime = currentCPUTime();
-        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
-        endTime = currentCPUTime();
-
-        if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) {
-            if (!((endTime - startTime) < .150f))
-                printf("FAIL: script did not timed out as expected.\n");
-            if (!shouldTerminateCallbackWasCalled)
-                printf("FAIL: script timeout callback was not called.\n");
-            failed = true;
-        }
-
-        if (exception)
-            printf("PASS: TerminatedExecutionException was not catchable as expected.\n");
-        else {
-            printf("FAIL: TerminatedExecutionException was caught.\n");
-            failed = true;
-        }
-    }
-
-    /* Test script timeout with no callback: */
-    JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, 0, 0);
+    // Check Promise is not exposed.
     {
-        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
-        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
-        double startTime;
-        double endTime;
-        exception = NULL;
-        startTime = currentCPUTime();
-        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
-        endTime = currentCPUTime();
-
-        if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
-            printf("PASS: script timed out as expected when no callback is specified.\n");
-        else {
-            if (!((endTime - startTime) < .150f))
-                printf("FAIL: script did not timed out as expected when no callback is specified.\n");
-            failed = true;
-        }
-
-        if (!exception) {
-            printf("FAIL: TerminatedExecutionException was not thrown.\n");
-            failed = true;
-        }
-    }
-
-    /* Test script timeout cancellation: */
-    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0);
-    {
-        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
-        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
-        double startTime;
-        double endTime;
-        exception = NULL;
-        startTime = currentCPUTime();
-        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
-        endTime = currentCPUTime();
-
-        if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception)
-            printf("PASS: script timeout was cancelled as expected.\n");
-        else {
-            if (((endTime - startTime) < .150) || exception)
-                printf("FAIL: script timeout was not cancelled.\n");
-            if (!cancelTerminateCallbackWasCalled)
-                printf("FAIL: script timeout callback was not called.\n");
-            failed = true;
+        JSObjectRef globalObject = JSContextGetGlobalObject(context);
+        {
+            JSStringRef promiseProperty = JSStringCreateWithUTF8CString("Promise");
+            ASSERT(!JSObjectHasProperty(context, globalObject, promiseProperty));
+            JSStringRelease(promiseProperty);
         }
-
-        if (exception) {
-            printf("FAIL: Unexpected TerminatedExecutionException thrown.\n");
-            failed = true;
+        {
+            JSStringRef script = JSStringCreateWithUTF8CString("typeof Promise");
+            JSStringRef undefined = JSStringCreateWithUTF8CString("undefined");
+            JSValueRef value = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
+            ASSERT(JSValueIsString(context, value));
+            JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
+            ASSERT(JSStringIsEqual(valueAsString, undefined));
+            JSStringRelease(valueAsString);
+            JSStringRelease(undefined);
+            JSStringRelease(script);
         }
+        printf("PASS: Promise is not exposed under JSContext API.\n");
     }
 
-    /* Test script timeout extension: */
-    JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0);
-    {
-        const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } ";
-        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
-        double startTime;
-        double endTime;
-        double deltaTime;
-        exception = NULL;
-        startTime = currentCPUTime();
-        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
-        endTime = currentCPUTime();
-        deltaTime = endTime - startTime;
-
-        if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception)
-            printf("PASS: script timeout was extended as expected.\n");
-        else {
-            if (deltaTime < .200f)
-                printf("FAIL: script timeout was not extended as expected.\n");
-            else if (deltaTime >= .500f)
-                printf("FAIL: script did not timeout.\n");
-
-            if (extendTerminateCallbackCalled < 1)
-                printf("FAIL: script timeout callback was not called.\n");
-            if (extendTerminateCallbackCalled < 2)
-                printf("FAIL: script timeout callback was not called after timeout extension.\n");
-
-            if (!exception)
-                printf("FAIL: TerminatedExecutionException was not thrown during timeout extension test.\n");
-
-            failed = true;
-        }
-    }
+#if OS(DARWIN)
+    failed = testExecutionTimeLimit() || failed;
 #endif /* OS(DARWIN) */
+    failed = testGlobalContextWithFinalizer() || failed;
 
     // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
     function = NULL;
@@ -2121,3 +1966,10 @@ static char* createStringWithContentsOfFile(const char* fileName)
     
     return buffer;
 }
+
+#if OS(WINDOWS)
+extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
+{
+    return main(argc, const_cast<char**>(argv));
+}
+#endif
index f9cc7b411a37d00a022eb8d8dcbf3c518bbfd922..88d3701c21e05866a7a20a1aef22cb0fb283c4f6 100644 (file)
@@ -74,6 +74,20 @@ function globalStaticFunction()
 
 shouldBe("globalStaticValue", 3);
 shouldBe("globalStaticFunction()", 4);
+shouldBe("this.globalStaticFunction()", 4);
+
+function globalStaticFunction2() {
+    return 10;
+}
+shouldBe("globalStaticFunction2();", 10);
+this.globalStaticFunction2 = function() { return 20; }
+shouldBe("globalStaticFunction2();", 20);
+shouldBe("this.globalStaticFunction2();", 20);
+
+function iAmNotAStaticFunction() { return 10; }
+shouldBe("iAmNotAStaticFunction();", 10);
+this.iAmNotAStaticFunction = function() { return 20; }
+shouldBe("iAmNotAStaticFunction();", 20);
 
 shouldBe("typeof MyObject", "function"); // our object implements 'call'
 MyObject.cantFind = 1;
index 724867c6400e5876fd479234dd80c7d7e0e701c0..01bb7d76b33fc64fd6585aa121936d79b82fd9d5 100644 (file)
@@ -28,6 +28,7 @@
 #import "CurrentThisInsideBlockGetterTest.h"
 #import "DateTests.h"
 #import "JSExportTests.h"
+#import "Regress141275.h"
 #import "Regress141809.h"
 
 #import <pthread.h>
@@ -483,10 +484,35 @@ static void* threadMain(void* contextPtr)
     pthread_exit(nullptr);
 }
 
-void testObjectiveCAPI()
+// This test is flaky. Since GC marks C stack and registers as roots conservatively,
+// objects not referenced logically can be accidentally marked and alive.
+// To avoid this situation as possible as we can,
+// 1. run this test first before stack is polluted,
+// 2. extract this test as a function to suppress stack height.
+static void testWeakValue()
 {
-    NSLog(@"Testing Objective-C API");
+    @autoreleasepool {
+        JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
+        TestObject *testObject = [TestObject testObject];
+        JSManagedValue *weakValue;
+        @autoreleasepool {
+            JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+            context[@"testObject"] = testObject;
+            weakValue = [[JSManagedValue alloc] initWithValue:context[@"testObject"]];
+        }
+
+        @autoreleasepool {
+            JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+            context[@"testObject"] = testObject;
+            JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+            checkResult(@"weak value == nil", ![weakValue value]);
+            checkResult(@"root is still alive", !context[@"testObject"].isUndefined);
+        }
+    }
+}
 
+static void testObjectiveCAPIMain()
+{
     @autoreleasepool {
         JSVirtualMachine* vm = [[JSVirtualMachine alloc] init];
         JSContext* context = [[JSContext alloc] initWithVirtualMachine:vm];
@@ -496,7 +522,7 @@ void testObjectiveCAPI()
     @autoreleasepool {
         JSContext *context = [[JSContext alloc] init];
         JSValue *result = [context evaluateScript:@"2 + 2"];
-        checkResult(@"2 + 2", [result isNumber] && [result toInt32] == 4);
+        checkResult(@"2 + 2", result.isNumber && [result toInt32] == 4);
     }
 
     @autoreleasepool {
@@ -509,19 +535,38 @@ void testObjectiveCAPI()
         JSContext *context = [[JSContext alloc] init];
         context[@"message"] = @"Hello";
         JSValue *result = [context evaluateScript:@"message + ', World!'"];
-        checkResult(@"Hello, World!", [result isString] && [result isEqualToObject:@"Hello, World!"]);
+        checkResult(@"Hello, World!", result.isString && [result isEqualToObject:@"Hello, World!"]);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        checkResult(@"Promise is not exposed", [context[@"Promise"] isUndefined]);
+        JSValue *result = [context evaluateScript:@"typeof Promise"];
+        checkResult(@"typeof Promise is 'undefined'", result.isString && [result isEqualToObject:@"undefined"]);
     }
 
     @autoreleasepool {
         JSContext *context = [[JSContext alloc] init];
         JSValue *result = [context evaluateScript:@"({ x:42 })"];
-        checkResult(@"({ x:42 })", [result isObject] && [result[@"x"] isEqualToObject:@42]);
+        checkResult(@"({ x:42 })", result.isObject && [result[@"x"] isEqualToObject:@42]);
         id obj = [result toObject];
         checkResult(@"Check dictionary literal", [obj isKindOfClass:[NSDictionary class]]);
         id num = (NSDictionary *)obj[@"x"];
         checkResult(@"Check numeric literal", [num isKindOfClass:[NSNumber class]]);
     }
 
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *result = [context evaluateScript:@"[ ]"];
+        checkResult(@"[ ]", result.isArray);
+    }
+
+    @autoreleasepool {
+        JSContext *context = [[JSContext alloc] init];
+        JSValue *result = [context evaluateScript:@"new Date"];
+        checkResult(@"new Date", result.isDate);
+    }
+
     @autoreleasepool {
         JSCollection* myPrivateProperties = [[JSCollection alloc] init];
 
@@ -543,11 +588,11 @@ void testObjectiveCAPI()
             JSValue *myNumber = [myPrivateProperties valueForKey:@"my_number"];
             JSValue *definitelyNull = [myPrivateProperties valueForKey:@"definitely_null"];
             JSValue *notSureIfUndefined = [myPrivateProperties valueForKey:@"not_sure_if_undefined"];
-            checkResult(@"is_ham is true", [isHam isBoolean] && [isHam toBool]);
-            checkResult(@"message is hello!", [message isString] && [@"hello!" isEqualToString:[message toString]]);
-            checkResult(@"my_number is 42", [myNumber isNumber] && [myNumber toInt32] == 42);
-            checkResult(@"definitely_null is null", [definitelyNull isNull]);
-            checkResult(@"not_sure_if_undefined is undefined", [notSureIfUndefined isUndefined]);
+            checkResult(@"is_ham is true", isHam.isBoolean && [isHam toBool]);
+            checkResult(@"message is hello!", message.isString && [@"hello!" isEqualToString:[message toString]]);
+            checkResult(@"my_number is 42", myNumber.isNumber && [myNumber toInt32] == 42);
+            checkResult(@"definitely_null is null", definitelyNull.isNull);
+            checkResult(@"not_sure_if_undefined is undefined", notSureIfUndefined.isUndefined);
         }
 
         checkResult(@"is_ham is nil", ![myPrivateProperties valueForKey:@"is_ham"]);
@@ -633,7 +678,7 @@ void testObjectiveCAPI()
         JSContext *context = [[JSContext alloc] init];
         __block bool emptyExceptionSourceURL = false;
         context.exceptionHandler = ^(JSContext *, JSValue *exception) {
-            emptyExceptionSourceURL = [exception[@"sourceURL"] isUndefined];
+            emptyExceptionSourceURL = exception[@"sourceURL"].isUndefined;
         };
         [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
         checkResult(@"evaluteScript: exception has no sourceURL", emptyExceptionSourceURL);
@@ -694,7 +739,7 @@ void testObjectiveCAPI()
                 return result; \
             })"];
         JSValue *result = [mulAddFunction callWithArguments:@[ @[ @2, @4, @8 ], @{ @"x":@0.5, @"y":@42 } ]];
-        checkResult(@"mulAddFunction", [result isObject] && [[result toString] isEqual:@"43,44,46"]);
+        checkResult(@"mulAddFunction", result.isObject && [[result toString] isEqual:@"43,44,46"]);
     }
 
     @autoreleasepool {
@@ -719,7 +764,7 @@ void testObjectiveCAPI()
         checkResult(@"array.length after put to maxLength + 1", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
 
         if (sizeof(NSUInteger) == 8)
-            checkResult(@"valueAtIndex:0 is undefined", [[array valueAtIndex:0] isUndefined]);
+            checkResult(@"valueAtIndex:0 is undefined", [array valueAtIndex:0].isUndefined);
         else
             checkResult(@"valueAtIndex:0", [[array valueAtIndex:0] toInt32] == 24);
         checkResult(@"valueAtIndex:lowIndex", [[array valueAtIndex:lowIndex] toInt32] == 42);
@@ -843,7 +888,7 @@ void testObjectiveCAPI()
         context[@"testObjectA"] = testObject;
         context[@"testObjectB"] = testObject;
         JSValue *result = [context evaluateScript:@"testObjectA == testObjectB"];
-        checkResult(@"testObjectA == testObjectB", [result isBoolean] && [result toBool]);
+        checkResult(@"testObjectA == testObjectB", result.isBoolean && [result toBool]);
     }
 
     @autoreleasepool {
@@ -863,7 +908,7 @@ void testObjectiveCAPI()
         context[@"testObject"] = testObject;
         context[@"mul"] = ^(int x, int y){ return x * y; };
         JSValue *result = [context evaluateScript:@"mul(testObject.six, 7)"];
-        checkResult(@"mul(testObject.six, 7)", [result isNumber] && [result toInt32] == 42);
+        checkResult(@"mul(testObject.six, 7)", result.isNumber && [result toInt32] == 42);
     }
 
     @autoreleasepool {
@@ -894,7 +939,7 @@ void testObjectiveCAPI()
         TestObject* testObject = [TestObject testObject];
         context[@"testObject"] = testObject;
         JSValue *result = [context evaluateScript:@"testObject.getString()"];
-        checkResult(@"testObject.getString()", [result isString] && [result toInt32] == 42);
+        checkResult(@"testObject.getString()", result.isString && [result toInt32] == 42);
     }
 
     @autoreleasepool {
@@ -910,7 +955,7 @@ void testObjectiveCAPI()
         TestObject* testObject = [TestObject testObject];
         context[@"testObject"] = testObject;
         JSValue *result = [context evaluateScript:@"testObject.getString.call(testObject)"];
-        checkResult(@"testObject.getString.call(testObject)", [result isString] && [result toInt32] == 42);
+        checkResult(@"testObject.getString.call(testObject)", result.isString && [result toInt32] == 42);
     }
 
     @autoreleasepool {
@@ -927,9 +972,9 @@ void testObjectiveCAPI()
         TestObject* testObject = [TestObject testObject];
         context[@"testObject"] = testObject;
         JSValue *result = [context evaluateScript:@"var result = 0; testObject.callback(function(x){ result = x; }); result"];
-        checkResult(@"testObject.callback", [result isNumber] && [result toInt32] == 42);
+        checkResult(@"testObject.callback", result.isNumber && [result toInt32] == 42);
         result = [context evaluateScript:@"testObject.bogusCallback"];
-        checkResult(@"testObject.bogusCallback == undefined", [result isUndefined]);
+        checkResult(@"testObject.bogusCallback == undefined", result.isUndefined);
     }
 
     @autoreleasepool {
@@ -937,7 +982,7 @@ void testObjectiveCAPI()
         TestObject *testObject = [TestObject testObject];
         context[@"testObject"] = testObject;
         JSValue *result = [context evaluateScript:@"Function.prototype.toString.call(testObject.callback)"];
-        checkResult(@"Function.prototype.toString", !context.exception && ![result isUndefined]);
+        checkResult(@"Function.prototype.toString", !context.exception && !result.isUndefined);
     }
 
     @autoreleasepool {
@@ -1018,13 +1063,13 @@ void testObjectiveCAPI()
 
         @autoreleasepool {
             JSValue *result = [context evaluateScript:@"testXYZ.onclick"];
-            checkResult(@"onclick still around after GC", !([result isNull] || [result isUndefined]));
+            checkResult(@"onclick still around after GC", !(result.isNull || result.isUndefined));
         }
 
 
         @autoreleasepool {
             JSValue *result = [context evaluateScript:@"testXYZ.weakOnclick"];
-            checkResult(@"weakOnclick not around after GC", [result isNull] || [result isUndefined]);
+            checkResult(@"weakOnclick not around after GC", result.isNull || result.isUndefined);
         }
 
         @autoreleasepool {
@@ -1043,25 +1088,6 @@ void testObjectiveCAPI()
         }
     }
 
-    @autoreleasepool {
-        JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
-        TestObject *testObject = [TestObject testObject];
-        JSManagedValue *weakValue;
-        @autoreleasepool {
-            JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
-            context[@"testObject"] = testObject;
-            weakValue = [[JSManagedValue alloc] initWithValue:context[@"testObject"]];
-        }
-
-        @autoreleasepool {
-            JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
-            context[@"testObject"] = testObject;
-            JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
-            checkResult(@"weak value == nil", ![weakValue value]);
-            checkResult(@"root is still alive", ![context[@"testObject"] isUndefined]);
-        }
-    }
-
     @autoreleasepool {
         JSContext *context = [[JSContext alloc] init];
         TinyDOMNode *root = [[TinyDOMNode alloc] initWithVirtualMachine:context.virtualMachine];
@@ -1088,7 +1114,7 @@ void testObjectiveCAPI()
         JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
 
         JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
-        checkResult(@"My custom property == 42", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
+        checkResult(@"My custom property == 42", myCustomProperty.isNumber && [myCustomProperty toInt32] == 42);
     }
 
     @autoreleasepool {
@@ -1120,7 +1146,7 @@ void testObjectiveCAPI()
         JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
 
         JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
-        checkResult(@"duplicate calls to addManagedReference don't cause things to die", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
+        checkResult(@"duplicate calls to addManagedReference don't cause things to die", myCustomProperty.isNumber && [myCustomProperty toInt32] == 42);
     }
 
     @autoreleasepool {
@@ -1209,7 +1235,7 @@ void testObjectiveCAPI()
             NSLog(@"I'm intentionally not returning anything.");
         };
         JSValue *result = [context evaluateScript:@"new MyClass()"];
-        checkResult(@"result === undefined", [result isUndefined]);
+        checkResult(@"result === undefined", result.isUndefined);
         checkResult(@"exception.message is correct'", context.exception 
             && [@"Objective-C blocks called as constructors must return an object." isEqualToString:[context.exception[@"message"] toString]]);
     }
@@ -1331,7 +1357,7 @@ void testObjectiveCAPI()
             return [[UnexportedObject alloc] init];
         };
         JSValue *result = [context evaluateScript:@"(makeObject() instanceof UnexportedObject)"];
-        checkResult(@"makeObject() instanceof UnexportedObject", [result isBoolean] && [result toBool]);
+        checkResult(@"makeObject() instanceof UnexportedObject", result.isBoolean && [result toBool]);
     }
 
     @autoreleasepool {
@@ -1386,9 +1412,49 @@ void testObjectiveCAPI()
     currentThisInsideBlockGetterTest();
     runDateTests();
     runJSExportTests();
+    runRegress141275();
     runRegress141809();
 }
 
+@protocol NumberProtocol <JSExport>
+
+@property (nonatomic) NSInteger number;
+
+@end
+
+@interface NumberObject : NSObject <NumberProtocol>
+
+@property (nonatomic) NSInteger number;
+
+@end
+
+@implementation NumberObject
+
+@end
+
+// Check that negative NSIntegers retain the correct value when passed into JS code.
+static void checkNegativeNSIntegers()
+{
+    NumberObject *container = [[NumberObject alloc] init];
+    container.number = -1;
+    JSContext *context = [[JSContext alloc] init];
+    context[@"container"] = container;
+    NSString *jsID = @"var getContainerNumber = function() { return container.number }";
+    [context evaluateScript:jsID];
+    JSValue *jsFunction = context[@"getContainerNumber"];
+    JSValue *result = [jsFunction callWithArguments:@[]];
+    
+    checkResult(@"Negative number maintained its original value", [[result toString] isEqualToString:@"-1"]);
+}
+
+void testObjectiveCAPI()
+{
+    NSLog(@"Testing Objective-C API");
+    checkNegativeNSIntegers();
+    testWeakValue();
+    testObjectiveCAPIMain();
+}
+
 #else
 
 void testObjectiveCAPI()
index cc45c2fdb1e036fca41e4b9126c7d110df921feb..8ae8665a831cc043378267eb81c48b74521b737e 100644 (file)
@@ -15,6 +15,8 @@ set(JavaScriptCore_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/debugger"
     "${JAVASCRIPTCORE_DIR}/inspector"
     "${JAVASCRIPTCORE_DIR}/inspector/agents"
+    "${JAVASCRIPTCORE_DIR}/inspector/augmentable"
+    "${JAVASCRIPTCORE_DIR}/inspector/remote"
     "${JAVASCRIPTCORE_DIR}/interpreter"
     "${JAVASCRIPTCORE_DIR}/jit"
     "${JAVASCRIPTCORE_DIR}/llint"
@@ -26,9 +28,15 @@ set(JavaScriptCore_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/tools"
     "${JAVASCRIPTCORE_DIR}/yarr"
     "${WTF_DIR}"
+    "${DERIVED_SOURCES_DIR}"
+    "${DERIVED_SOURCES_DIR}/ForwardingHeaders"
     "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}"
+    "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector"
     "${CMAKE_SOURCE_DIR}/Source"
-    ${ICU_INCLUDE_DIRS}
+)
+
+set(JavaScriptCore_SYSTEM_INCLUDE_DIRECTORIES
+    "${ICU_INCLUDE_DIRS}"
 )
 
 set(JavaScriptCore_SOURCES
@@ -47,8 +55,11 @@ set(JavaScriptCore_SOURCES
     API/JSWeakObjectMapRefPrivate.cpp
     API/OpaqueJSString.cpp
 
+    assembler/ARMAssembler.cpp
     assembler/LinkBuffer.cpp
     assembler/MacroAssembler.cpp
+    assembler/MacroAssemblerARM.cpp
+    assembler/MacroAssemblerARMv7.cpp
     assembler/MacroAssemblerX86Common.cpp
 
     bindings/ScriptFunctionCall.cpp
@@ -60,16 +71,22 @@ set(JavaScriptCore_SOURCES
     bytecode/ArrayAllocationProfile.cpp
     bytecode/ArrayProfile.cpp
     bytecode/BytecodeBasicBlock.cpp
+    bytecode/BytecodeIntrinsicRegistry.cpp
     bytecode/BytecodeLivenessAnalysis.cpp
+    bytecode/CallEdge.cpp
     bytecode/CallLinkInfo.cpp
     bytecode/CallLinkStatus.cpp
+    bytecode/CallVariant.cpp
     bytecode/CodeBlock.cpp
     bytecode/CodeBlockHash.cpp
     bytecode/CodeBlockJettisoningWatchpoint.cpp
     bytecode/CodeOrigin.cpp
     bytecode/CodeType.cpp
+    bytecode/ComplexGetStatus.cpp
+    bytecode/ConstantStructureCheck.cpp
     bytecode/DFGExitProfile.cpp
     bytecode/DeferredCompilationCallback.cpp
+    bytecode/DeferredSourceDump.cpp
     bytecode/ExecutionCounter.cpp
     bytecode/ExitKind.cpp
     bytecode/ExitingJITType.cpp
@@ -83,73 +100,88 @@ set(JavaScriptCore_SOURCES
     bytecode/PolymorphicGetByIdList.cpp
     bytecode/PolymorphicPutByIdList.cpp
     bytecode/PreciseJumpTargets.cpp
-    bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp
     bytecode/PutByIdStatus.cpp
     bytecode/PutByIdVariant.cpp
     bytecode/ReduceWhitespace.cpp
     bytecode/SamplingTool.cpp
     bytecode/SpecialPointer.cpp
     bytecode/SpeculatedType.cpp
+    bytecode/StructureSet.cpp
     bytecode/StructureStubClearingWatchpoint.cpp
     bytecode/StructureStubInfo.cpp
+    bytecode/ToThisStatus.cpp
+    bytecode/TrackedReferences.cpp
     bytecode/UnlinkedCodeBlock.cpp
     bytecode/UnlinkedInstructionStream.cpp
     bytecode/ValueRecovery.cpp
+    bytecode/VariableWriteFireDetail.cpp
+    bytecode/VirtualRegister.cpp
     bytecode/Watchpoint.cpp
 
     bytecompiler/BytecodeGenerator.cpp
     bytecompiler/NodesCodegen.cpp
 
     debugger/Debugger.cpp
-    debugger/DebuggerActivation.cpp
     debugger/DebuggerCallFrame.cpp
+    debugger/DebuggerScope.cpp
 
     dfg/DFGAbstractHeap.cpp
     dfg/DFGAbstractValue.cpp
-    dfg/DFGArgumentsSimplificationPhase.cpp
+    dfg/DFGArgumentsEliminationPhase.cpp
+    dfg/DFGArgumentsUtilities.cpp
     dfg/DFGArithMode.cpp
     dfg/DFGArrayMode.cpp
     dfg/DFGAtTailAbstractState.cpp
     dfg/DFGAvailability.cpp
+    dfg/DFGAvailabilityMap.cpp
     dfg/DFGBackwardsPropagationPhase.cpp
     dfg/DFGBasicBlock.cpp
-    dfg/DFGBinarySwitch.cpp
     dfg/DFGBlockInsertionSet.cpp
+    dfg/DFGBlockSet.cpp
+    dfg/DFGBlockWorklist.cpp
     dfg/DFGByteCodeParser.cpp
     dfg/DFGCFAPhase.cpp
     dfg/DFGCFGSimplificationPhase.cpp
     dfg/DFGCPSRethreadingPhase.cpp
     dfg/DFGCSEPhase.cpp
     dfg/DFGCapabilities.cpp
+    dfg/DFGCleanUpPhase.cpp
     dfg/DFGClobberSet.cpp
     dfg/DFGClobberize.cpp
+    dfg/DFGCombinedLiveness.cpp
     dfg/DFGCommon.cpp
     dfg/DFGCommonData.cpp
     dfg/DFGCompilationKey.cpp
     dfg/DFGCompilationMode.cpp
     dfg/DFGConstantFoldingPhase.cpp
+    dfg/DFGConstantHoistingPhase.cpp
     dfg/DFGCriticalEdgeBreakingPhase.cpp
     dfg/DFGDCEPhase.cpp
     dfg/DFGDesiredIdentifiers.cpp
-    dfg/DFGDesiredStructureChains.cpp
     dfg/DFGDesiredTransitions.cpp
     dfg/DFGDesiredWatchpoints.cpp
     dfg/DFGDesiredWeakReferences.cpp
     dfg/DFGDesiredWriteBarriers.cpp
     dfg/DFGDisassembler.cpp
+    dfg/DFGDoesGC.cpp
     dfg/DFGDominators.cpp
     dfg/DFGDriver.cpp
     dfg/DFGEdge.cpp
+    dfg/DFGEpoch.cpp
     dfg/DFGFailedFinalizer.cpp
     dfg/DFGFinalizer.cpp
     dfg/DFGFixupPhase.cpp
     dfg/DFGFlushFormat.cpp
     dfg/DFGFlushedAt.cpp
+    dfg/DFGFrozenValue.cpp
     dfg/DFGFunctionWhitelist.cpp
     dfg/DFGGraph.cpp
     dfg/DFGGraphSafepoint.cpp
+    dfg/DFGHeapLocation.cpp
     dfg/DFGInPlaceAbstractState.cpp
+    dfg/DFGInsertOSRHintsForUpdate.cpp
     dfg/DFGIntegerCheckCombiningPhase.cpp
+    dfg/DFGIntegerRangeOptimizationPhase.cpp
     dfg/DFGInvalidationPointInjectionPhase.cpp
     dfg/DFGJITCode.cpp
     dfg/DFGJITCompiler.cpp
@@ -157,10 +189,15 @@ set(JavaScriptCore_SOURCES
     dfg/DFGJumpReplacement.cpp
     dfg/DFGLICMPhase.cpp
     dfg/DFGLazyJSValue.cpp
+    dfg/DFGLazyNode.cpp
     dfg/DFGLivenessAnalysisPhase.cpp
     dfg/DFGLongLivedState.cpp
     dfg/DFGLoopPreHeaderCreationPhase.cpp
+    dfg/DFGMayExit.cpp
+    dfg/DFGMinifiedGraph.cpp
     dfg/DFGMinifiedNode.cpp
+    dfg/DFGMovHintRemovalPhase.cpp
+    dfg/DFGNaiveDominators.cpp
     dfg/DFGNaturalLoops.cpp
     dfg/DFGNode.cpp
     dfg/DFGNodeFlags.cpp
@@ -173,14 +210,23 @@ set(JavaScriptCore_SOURCES
     dfg/DFGOSRExitCompiler32_64.cpp
     dfg/DFGOSRExitCompiler64.cpp
     dfg/DFGOSRExitCompilerCommon.cpp
+    dfg/DFGOSRExitFuzz.cpp
     dfg/DFGOSRExitJumpPlaceholder.cpp
     dfg/DFGOSRExitPreparation.cpp
+    dfg/DFGObjectAllocationSinkingPhase.cpp
+    dfg/DFGObjectMaterializationData.cpp
     dfg/DFGOperations.cpp
+    dfg/DFGPhantomInsertionPhase.cpp
     dfg/DFGPhase.cpp
+    dfg/DFGPhiChildren.cpp
     dfg/DFGPlan.cpp
+    dfg/DFGPrePostNumbering.cpp
     dfg/DFGPredictionInjectionPhase.cpp
     dfg/DFGPredictionPropagationPhase.cpp
-    dfg/DFGResurrectionForValidationPhase.cpp
+    dfg/DFGPromotedHeapLocation.cpp
+    dfg/DFGPureValue.cpp
+    dfg/DFGPutStackSinkingPhase.cpp
+    dfg/DFGSSACalculator.cpp
     dfg/DFGSSAConversionPhase.cpp
     dfg/DFGSSALoweringPhase.cpp
     dfg/DFGSafepoint.cpp
@@ -189,16 +235,21 @@ set(JavaScriptCore_SOURCES
     dfg/DFGSpeculativeJIT64.cpp
     dfg/DFGStackLayoutPhase.cpp
     dfg/DFGStaticExecutionCountEstimationPhase.cpp
-    dfg/DFGStoreBarrierElisionPhase.cpp
+    dfg/DFGStoreBarrierInsertionPhase.cpp
     dfg/DFGStrengthReductionPhase.cpp
+    dfg/DFGStructureAbstractValue.cpp
+    dfg/DFGStructureRegistrationPhase.cpp
     dfg/DFGThreadData.cpp
     dfg/DFGThunks.cpp
     dfg/DFGTierUpCheckInjectionPhase.cpp
+    dfg/DFGTransition.cpp
     dfg/DFGTypeCheckHoistingPhase.cpp
     dfg/DFGUnificationPhase.cpp
     dfg/DFGUseKind.cpp
     dfg/DFGValidate.cpp
     dfg/DFGValueSource.cpp
+    dfg/DFGValueStrength.cpp
+    dfg/DFGVarargsForwardingPhase.cpp
     dfg/DFGVariableAccessData.cpp
     dfg/DFGVariableAccessDataDump.cpp
     dfg/DFGVariableEvent.cpp
@@ -207,14 +258,16 @@ set(JavaScriptCore_SOURCES
     dfg/DFGWatchpointCollectionPhase.cpp
     dfg/DFGWorklist.cpp
 
-    disassembler/ARMv7/ARMv7DOpcode.cpp
+    disassembler/ARM64Disassembler.cpp
     disassembler/ARMv7Disassembler.cpp
     disassembler/Disassembler.cpp
     disassembler/LLVMDisassembler.cpp
-    disassembler/UDis86Disassembler.cpp
     disassembler/X86Disassembler.cpp
 
-    heap/BlockAllocator.cpp
+    disassembler/ARM64/A64DOpcode.cpp
+
+    disassembler/ARMv7/ARMv7DOpcode.cpp
+
     heap/CodeBlockSet.cpp
     heap/ConservativeRoots.cpp
     heap/CopiedSpace.cpp
@@ -231,6 +284,7 @@ set(JavaScriptCore_SOURCES
     heap/Heap.cpp
     heap/HeapStatistics.cpp
     heap/HeapTimer.cpp
+    heap/HeapVerifier.cpp
     heap/IncrementalSweeper.cpp
     heap/JITStubRoutineSet.cpp
     heap/MachineStackMarker.cpp
@@ -239,7 +293,6 @@ set(JavaScriptCore_SOURCES
     heap/MarkedBlock.cpp
     heap/MarkedSpace.cpp
     heap/SlotVisitor.cpp
-    heap/SuperRegion.cpp
     heap/Weak.cpp
     heap/WeakBlock.cpp
     heap/WeakHandleOwner.cpp
@@ -249,6 +302,7 @@ set(JavaScriptCore_SOURCES
 
     inspector/ConsoleMessage.cpp
     inspector/ContentSearchUtilities.cpp
+    inspector/EventLoop.cpp
     inspector/IdentifiersFactory.cpp
     inspector/InjectedScript.cpp
     inspector/InjectedScriptBase.cpp
@@ -258,6 +312,9 @@ set(JavaScriptCore_SOURCES
     inspector/InspectorAgentRegistry.cpp
     inspector/InspectorBackendDispatcher.cpp
     inspector/InspectorValues.cpp
+    inspector/JSGlobalObjectConsoleClient.cpp
+    inspector/JSGlobalObjectInspectorController.cpp
+    inspector/JSGlobalObjectScriptDebugServer.cpp
     inspector/JSInjectedScriptHost.cpp
     inspector/JSInjectedScriptHostPrototype.cpp
     inspector/JSJavaScriptCallFrame.cpp
@@ -268,11 +325,14 @@ set(JavaScriptCore_SOURCES
     inspector/ScriptCallStack.cpp
     inspector/ScriptCallStackFactory.cpp
     inspector/ScriptDebugServer.cpp
+
     inspector/agents/InspectorAgent.cpp
     inspector/agents/InspectorConsoleAgent.cpp
     inspector/agents/InspectorDebuggerAgent.cpp
-    inspector/agents/InspectorProfilerAgent.cpp
     inspector/agents/InspectorRuntimeAgent.cpp
+    inspector/agents/JSGlobalObjectConsoleAgent.cpp
+    inspector/agents/JSGlobalObjectDebuggerAgent.cpp
+    inspector/agents/JSGlobalObjectRuntimeAgent.cpp
 
     interpreter/AbstractPC.cpp
     interpreter/CallFrame.cpp
@@ -280,12 +340,12 @@ set(JavaScriptCore_SOURCES
     interpreter/JSStack.cpp
     interpreter/ProtoCallFrame.cpp
     interpreter/StackVisitor.cpp
-    interpreter/VMInspector.cpp
 
     jit/AccessorCallJITStubRoutine.cpp
-    jit/AssemblyHelpers.cpp
     jit/ArityCheckFailReturnThunks.cpp
-    jit/ClosureCallStubRoutine.cpp
+    jit/AssemblyHelpers.cpp
+    jit/BinarySwitch.cpp
+    jit/ExecutableAllocationFuzz.cpp
     jit/ExecutableAllocator.cpp
     jit/ExecutableAllocatorFixedVMPool.cpp
     jit/GCAwareJITStubRoutine.cpp
@@ -308,11 +368,13 @@ set(JavaScriptCore_SOURCES
     jit/JITStubs.cpp
     jit/JITThunks.cpp
     jit/JITToDFGDeferredCompilationCallback.cpp
+    jit/PolymorphicCallStubRoutine.cpp
     jit/Reg.cpp
     jit/RegisterPreservationWrapperGenerator.cpp
     jit/RegisterSet.cpp
     jit/Repatch.cpp
     jit/ScratchRegisterAllocator.cpp
+    jit/SetupVarargsFrame.cpp
     jit/TempRegisterSet.cpp
     jit/ThunkGenerators.cpp
 
@@ -342,21 +404,35 @@ set(JavaScriptCore_SOURCES
     profiler/ProfilerOriginStack.cpp
     profiler/ProfilerProfiledBytecodes.cpp
 
+    tools/CodeProfile.cpp
+    tools/CodeProfiling.cpp
+    tools/FunctionOverrides.cpp
+    tools/JSDollarVM.cpp
+    tools/JSDollarVMPrototype.cpp
+
+    yarr/RegularExpression.cpp
+    yarr/YarrCanonicalizeUCS2.cpp
+    yarr/YarrInterpreter.cpp
+    yarr/YarrJIT.cpp
+    yarr/YarrPattern.cpp
+    yarr/YarrSyntaxChecker.cpp
+)
+
+set(JavaScriptCore_RUNTIME_SOURCES
     runtime/ArgList.cpp
-    runtime/Arguments.cpp
-    runtime/ArgumentsIteratorConstructor.cpp
-    runtime/ArgumentsIteratorPrototype.cpp
     runtime/ArrayBuffer.cpp
     runtime/ArrayBufferNeuteringWatchpoint.cpp
     runtime/ArrayBufferView.cpp
     runtime/ArrayConstructor.cpp
-    runtime/ArrayIteratorConstructor.cpp
     runtime/ArrayIteratorPrototype.cpp
     runtime/ArrayPrototype.cpp
+    runtime/BasicBlockLocation.cpp
     runtime/BooleanConstructor.cpp
     runtime/BooleanObject.cpp
     runtime/BooleanPrototype.cpp
+    runtime/BundlePath.cpp
     runtime/CallData.cpp
+    runtime/ClonedArguments.cpp
     runtime/CodeCache.cpp
     runtime/CodeSpecializationKind.cpp
     runtime/CommonIdentifiers.cpp
@@ -366,34 +442,43 @@ set(JavaScriptCore_SOURCES
     runtime/Completion.cpp
     runtime/ConsoleClient.cpp
     runtime/ConsolePrototype.cpp
+    runtime/ConstantMode.cpp
     runtime/ConstructData.cpp
+    runtime/ControlFlowProfiler.cpp
     runtime/CustomGetterSetter.cpp
     runtime/DataView.cpp
-    runtime/DataView.h
     runtime/DateConstructor.cpp
     runtime/DateConversion.cpp
     runtime/DateInstance.cpp
     runtime/DatePrototype.cpp
+    runtime/DirectArguments.cpp
+    runtime/DirectArgumentsOffset.cpp
     runtime/DumpContext.cpp
     runtime/Error.cpp
     runtime/ErrorConstructor.cpp
     runtime/ErrorHandlingScope.cpp
     runtime/ErrorInstance.cpp
     runtime/ErrorPrototype.cpp
+    runtime/Exception.cpp
+    runtime/ExceptionFuzz.cpp
     runtime/ExceptionHelpers.cpp
     runtime/Executable.cpp
     runtime/FunctionConstructor.cpp
     runtime/FunctionExecutableDump.cpp
+    runtime/FunctionHasExecutedCache.cpp
     runtime/FunctionPrototype.cpp
+    runtime/FunctionRareData.cpp
     runtime/GetterSetter.cpp
     runtime/Identifier.cpp
     runtime/IndexingType.cpp
+    runtime/InferredValue.cpp
     runtime/InitializeThreading.cpp
     runtime/IntendedStructureChain.cpp
     runtime/InternalFunction.cpp
+    runtime/IntlObject.cpp
+    runtime/IteratorOperations.cpp
+    runtime/IteratorPrototype.cpp
     runtime/JSAPIValueWrapper.cpp
-    runtime/JSActivation.cpp
-    runtime/JSArgumentsIterator.cpp
     runtime/JSArray.cpp
     runtime/JSArrayBuffer.cpp
     runtime/JSArrayBufferConstructor.cpp
@@ -402,14 +487,21 @@ set(JavaScriptCore_SOURCES
     runtime/JSArrayIterator.cpp
     runtime/JSBoundFunction.cpp
     runtime/JSCJSValue.cpp
+    runtime/JSCallee.cpp
+    runtime/JSCatchScope.cpp
     runtime/JSCell.cpp
     runtime/JSConsole.cpp
     runtime/JSDataView.cpp
     runtime/JSDataViewPrototype.cpp
     runtime/JSDateMath.cpp
+    runtime/JSEnvironmentRecord.cpp
     runtime/JSFunction.cpp
+    runtime/JSFunctionNameScope.cpp
     runtime/JSGlobalObject.cpp
+    runtime/JSGlobalObjectDebuggable.cpp
     runtime/JSGlobalObjectFunctions.cpp
+    runtime/JSJob.cpp
+    runtime/JSLexicalEnvironment.cpp
     runtime/JSLock.cpp
     runtime/JSMap.cpp
     runtime/JSMapIterator.cpp
@@ -420,39 +512,37 @@ set(JavaScriptCore_SOURCES
     runtime/JSPromise.cpp
     runtime/JSPromiseConstructor.cpp
     runtime/JSPromiseDeferred.cpp
-    runtime/JSPromiseFunctions.cpp
-    runtime/JSPromiseReaction.cpp
     runtime/JSPromisePrototype.cpp
-    runtime/JSPropertyNameIterator.cpp
+    runtime/JSPropertyNameEnumerator.cpp
     runtime/JSProxy.cpp
     runtime/JSScope.cpp
     runtime/JSSegmentedVariableObject.cpp
     runtime/JSSet.cpp
     runtime/JSSetIterator.cpp
     runtime/JSString.cpp
+    runtime/JSStringIterator.cpp
     runtime/JSStringJoiner.cpp
     runtime/JSSymbolTableObject.cpp
+    runtime/JSTemplateRegistryKey.cpp
     runtime/JSTypedArrayConstructors.cpp
     runtime/JSTypedArrayPrototypes.cpp
     runtime/JSTypedArrays.cpp
-    runtime/JSVariableObject.cpp
     runtime/JSWeakMap.cpp
+    runtime/JSWeakSet.cpp
     runtime/JSWithScope.cpp
     runtime/JSWrapperObject.cpp
     runtime/LiteralParser.cpp
     runtime/Lookup.cpp
     runtime/MapConstructor.cpp
-    runtime/MapData.cpp
-    runtime/MapIteratorConstructor.cpp
     runtime/MapIteratorPrototype.cpp
     runtime/MapPrototype.cpp
+    runtime/MathCommon.cpp
     runtime/MathObject.cpp
     runtime/MemoryStatistics.cpp
-    runtime/NameConstructor.cpp
-    runtime/NameInstance.cpp
-    runtime/NamePrototype.cpp
     runtime/NativeErrorConstructor.cpp
     runtime/NativeErrorPrototype.cpp
+    runtime/NullGetterFunction.cpp
+    runtime/NullSetterFunction.cpp
     runtime/NumberConstructor.cpp
     runtime/NumberObject.cpp
     runtime/NumberPrototype.cpp
@@ -461,7 +551,6 @@ set(JavaScriptCore_SOURCES
     runtime/Operations.cpp
     runtime/Options.cpp
     runtime/PropertyDescriptor.cpp
-    runtime/PropertyNameArray.cpp
     runtime/PropertySlot.cpp
     runtime/PropertyTable.cpp
     runtime/PrototypeMap.cpp
@@ -472,9 +561,12 @@ set(JavaScriptCore_SOURCES
     runtime/RegExpMatchesArray.cpp
     runtime/RegExpObject.cpp
     runtime/RegExpPrototype.cpp
+    runtime/RuntimeType.cpp
     runtime/SamplingCounter.cpp
+    runtime/ScopeOffset.cpp
+    runtime/ScopedArguments.cpp
+    runtime/ScopedArgumentsTable.cpp
     runtime/SetConstructor.cpp
-    runtime/SetIteratorConstructor.cpp
     runtime/SetIteratorPrototype.cpp
     runtime/SetPrototype.cpp
     runtime/SimpleTypedArrayController.cpp
@@ -482,6 +574,7 @@ set(JavaScriptCore_SOURCES
     runtime/SparseArrayValueMap.cpp
     runtime/StrictEvalActivation.cpp
     runtime/StringConstructor.cpp
+    runtime/StringIteratorPrototype.cpp
     runtime/StringObject.cpp
     runtime/StringPrototype.cpp
     runtime/StringRecursionChecker.cpp
@@ -489,32 +582,39 @@ set(JavaScriptCore_SOURCES
     runtime/StructureChain.cpp
     runtime/StructureIDTable.cpp
     runtime/StructureRareData.cpp
+    runtime/Symbol.cpp
+    runtime/SymbolConstructor.cpp
+    runtime/SymbolObject.cpp
+    runtime/SymbolPrototype.cpp
     runtime/SymbolTable.cpp
+    runtime/TemplateRegistry.cpp
     runtime/TestRunnerUtils.cpp
+    runtime/TypeLocationCache.cpp
+    runtime/TypeProfiler.cpp
+    runtime/TypeProfilerLog.cpp
+    runtime/TypeSet.cpp
     runtime/TypedArrayController.cpp
     runtime/TypedArrayType.cpp
+    runtime/TypeofType.cpp
     runtime/VM.cpp
     runtime/VMEntryScope.cpp
+    runtime/VarOffset.cpp
     runtime/Watchdog.cpp
     runtime/WatchdogNone.cpp
     runtime/WeakMapConstructor.cpp
     runtime/WeakMapData.cpp
     runtime/WeakMapPrototype.cpp
+    runtime/WeakSetConstructor.cpp
+    runtime/WeakSetPrototype.cpp
+)
 
-    tools/CodeProfile.cpp
-    tools/CodeProfiling.cpp
-
-    yarr/RegularExpression.cpp
-    yarr/YarrCanonicalizeUCS2.cpp
-    yarr/YarrInterpreter.cpp
-    yarr/YarrJIT.cpp
-    yarr/YarrPattern.cpp
-    yarr/YarrSyntaxChecker.cpp
+list(APPEND JavaScriptCore_SOURCES
+    ${JavaScriptCore_RUNTIME_SOURCES}
 )
 
 set(JavaScriptCore_LUT_FILES
     runtime/ArrayConstructor.cpp
-    runtime/ArrayPrototype.cpp
+    runtime/ArrayIteratorPrototype.cpp
     runtime/BooleanPrototype.cpp
     runtime/DateConstructor.cpp
     runtime/DatePrototype.cpp
@@ -524,14 +624,15 @@ set(JavaScriptCore_LUT_FILES
     runtime/JSONObject.cpp
     runtime/JSPromiseConstructor.cpp
     runtime/JSPromisePrototype.cpp
-    runtime/NamePrototype.cpp
     runtime/NumberConstructor.cpp
     runtime/NumberPrototype.cpp
     runtime/ObjectConstructor.cpp
     runtime/RegExpConstructor.cpp
-    runtime/RegExpObject.cpp
     runtime/RegExpPrototype.cpp
     runtime/StringConstructor.cpp
+    runtime/StringIteratorPrototype.cpp
+    runtime/SymbolConstructor.cpp
+    runtime/SymbolPrototype.cpp
 )
 
 set(JavaScriptCore_LIBRARIES
@@ -539,7 +640,7 @@ set(JavaScriptCore_LIBRARIES
     ${ICU_I18N_LIBRARIES}
 )
 
-if (WTF_USE_UDIS86)
+if (USE_UDIS86)
     set(UDIS_GEN_DEP
         disassembler/udis86/ud_opcode.py
         disassembler/udis86/ud_optable.py
@@ -559,6 +660,8 @@ if (WTF_USE_UDIS86)
         ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/udis86_itab.h
     )
     list(APPEND JavaScriptCore_SOURCES
+        disassembler/UDis86Disassembler.cpp
+
         disassembler/udis86/udis86.c
         disassembler/udis86/udis86_decode.c
         disassembler/udis86/udis86_input.c
@@ -569,13 +672,6 @@ if (WTF_USE_UDIS86)
     )
 endif ()
 
-# We cannot check for RUBY_FOUND because it is set only when the full package is installed and
-# the only thing we need is the interpreter. Unlike Python, cmake does not provide a macro
-# for finding the only Ruby interpreter.
-if (NOT RUBY_EXECUTABLE)
-    message(FATAL_ERROR "The Ruby interpreter is needed to generate LLInt files.")
-endif ()
-
 set(LLINT_ASM
     llint/LowLevelInterpreter.asm
     llint/LowLevelInterpreter32_64.asm
@@ -584,11 +680,13 @@ set(LLINT_ASM
 
 set(OFFLINE_ASM
     offlineasm/arm.rb
+    offlineasm/arm64.rb
     offlineasm/ast.rb
     offlineasm/backends.rb
     offlineasm/cloop.rb
     offlineasm/config.rb
     offlineasm/instructions.rb
+    offlineasm/mips.rb
     offlineasm/offsets.rb
     offlineasm/opt.rb
     offlineasm/parser.rb
@@ -596,6 +694,7 @@ set(OFFLINE_ASM
     offlineasm/risc.rb
     offlineasm/self_hash.rb
     offlineasm/settings.rb
+    offlineasm/sh4.rb
     offlineasm/transform.rb
     offlineasm/x86.rb
 )
@@ -635,21 +734,41 @@ target_link_libraries(LLIntOffsetsExtractor WTF)
 # LLIntOffsetsExtractor matches, no output is generated. To make this target consistent and avoid
 # running this command for every build, we artificially update LLIntAssembly.h's mtime (using touch)
 # after every asm.rb run.
+if (MSVC)
+    set(LLIntOutput LowLevelInterpreterWin.asm)
+else ()
+    set(LLIntOutput LLIntAssembly.h)
+endif ()
+
 add_custom_command(
-    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
+    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${LLIntOutput}
     MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/offlineasm/asm.rb
     DEPENDS LLIntOffsetsExtractor ${LLINT_ASM} ${OFFLINE_ASM} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InitBytecodes.asm
-    COMMAND ${RUBY_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/offlineasm/asm.rb -I${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/ ${JAVASCRIPTCORE_DIR}/llint/LowLevelInterpreter.asm $<TARGET_FILE:LLIntOffsetsExtractor> ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
-    COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
+    COMMAND ${RUBY_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/offlineasm/asm.rb -I${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/ ${JAVASCRIPTCORE_DIR}/llint/LowLevelInterpreter.asm $<TARGET_FILE:LLIntOffsetsExtractor> ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${LLIntOutput}
+    COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${LLIntOutput}
     VERBATIM)
 
 # The explanation for not making LLIntAssembly.h part of the OBJECT_DEPENDS property of some of
 # the .cpp files below is similar to the one in the previous comment. However, since these .cpp
 # files are used to build JavaScriptCore itself, we can just add LLIntAssembly.h to JSC_HEADERS
 # since it is used in the add_library() call at the end of this file.
-list(APPEND JavaScriptCore_HEADERS
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
-)
+if (MSVC)
+    enable_language(ASM_MASM)
+    list(APPEND JavaScriptCore_SOURCES
+        ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm
+    )
+    # Win32 needs /safeseh with assembly, but Win64 does not.
+    if (CMAKE_SIZEOF_VOID_P EQUAL 4)
+        set_source_files_properties(${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm
+            PROPERTIES COMPILE_FLAGS  "/safeseh"
+        )
+    endif ()
+else ()
+    list(APPEND JavaScriptCore_HEADERS
+        ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
+    )
+endif ()
+
 list(APPEND JavaScriptCore_SOURCES
     llint/LLIntCLoop.cpp
     llint/LLIntData.cpp
@@ -683,14 +802,50 @@ if (ENABLE_FTL_JIT)
         COMMAND ${CMAKE_COMMAND} -E touch ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WebKitLLVMLibraryToken.h
         VERBATIM)
 
+    if (ENABLE_FTL_NATIVE_CALL_INLINING)
+        function(JOIN VALUES GLUE OUTPUT)
+            string(REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
+            set(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
+        endfunction()
+
+        JOIN("${JavaScriptCore_INCLUDE_DIRECTORIES}" " -I" JSC_INCLUDES)
+
+        set(LLVM_BITCODE_FILES)
+
+        foreach (_file ${JavaScriptCore_RUNTIME_SOURCES})
+            get_filename_component(_name ${_file} NAME_WE)
+            add_custom_command(
+                OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/runtime/${_name}.bc
+                COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create-llvm-ir-from-source-file.py ${_file} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${CLANG_EXE} "${JSC_INCLUDES}"
+                WORKING_DIRECTORY "${JAVASCRIPTCORE_DIR}"
+                VERBATIM)
+
+            ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/ftl/FTLState.cpp ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/runtime/${_name}.bc)
+            list(APPEND LLVM_BITCODE_FILES
+                ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/runtime/${_name}.bc
+            )
+        endforeach ()
+
+        get_filename_component(LLVM_BINS ${LLVM_CONFIG_EXE} PATH)
+
+        add_custom_command(
+            OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InlineRuntimeSymbolTable.h
+            MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create-symbol-table-index.py
+            DEPENDS ${LLVM_BITCODE_FILES}
+            COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create-symbol-table-index.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${JAVASCRIPTCORE_DIR} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR} ${LLVM_BINS}
+            WORKING_DIRECTORY "${JAVASCRIPTCORE_DIR}"
+            VERBATIM)
+
+        ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/ftl/FTLState.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InlineRuntimeSymbolTable.h)
+    endif ()
+
     WEBKIT_WRAP_SOURCELIST(${llvmForJSC_SOURCES})
     add_library(llvmForJSC SHARED ${llvmForJSC_SOURCES} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WebKitLLVMLibraryToken.h)
-    target_link_libraries(llvmForJSC ${LLVM_STATIC_LIBRARIES} "pthread" "dl")
+    target_link_libraries(llvmForJSC ${LLVM_STATIC_LIBRARIES} "pthread" "dl" -Wl,--version-script=${JAVASCRIPTCORE_DIR}/llvm/library/libllvmForJSC.version)
 
     # Added extra items for JavaScriptCore
-    list(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
+    list(APPEND JavaScriptCore_SYSTEM_INCLUDE_DIRECTORIES
         ${LLVM_INCLUDE_DIRS}
-        ${LIBCXXABI_INCLUDE_DIRS}
     )
 
     list(APPEND JavaScriptCore_SOURCES
@@ -711,7 +866,9 @@ if (ENABLE_FTL_JIT)
         ftl/FTLDataSection.cpp
         ftl/FTLExitArgument.cpp
         ftl/FTLExitArgumentForOperand.cpp
+        ftl/FTLExitPropertyValue.cpp
         ftl/FTLExitThunkGenerator.cpp
+        ftl/FTLExitTimeObjectMaterialization.cpp
         ftl/FTLExitValue.cpp
         ftl/FTLFail.cpp
         ftl/FTLForOSREntryJITCode.cpp
@@ -720,12 +877,15 @@ if (ENABLE_FTL_JIT)
         ftl/FTLJITCode.cpp
         ftl/FTLJITFinalizer.cpp
         ftl/FTLJSCall.cpp
+        ftl/FTLJSCallBase.cpp
+        ftl/FTLJSCallVarargs.cpp
         ftl/FTLLink.cpp
         ftl/FTLLocation.cpp
         ftl/FTLLowerDFGToLLVM.cpp
         ftl/FTLOSREntry.cpp
-        ftl/FTLOSRExitCompiler.cpp
         ftl/FTLOSRExit.cpp
+        ftl/FTLOSRExitCompiler.cpp
+        ftl/FTLOperations.cpp
         ftl/FTLOutput.cpp
         ftl/FTLRecoveryOpcode.cpp
         ftl/FTLRegisterAtOffset.cpp
@@ -769,7 +929,6 @@ set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
     debugger
     heap
     inspector
-    inspector/agents
     interpreter
     jit
     llint
@@ -779,35 +938,72 @@ set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
     yarr
 
     collector/handles
+
+    inspector/agents
+    inspector/augmentable
+    inspector/remote
+
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
 )
 
 set(JavaScriptCore_FORWARDING_HEADERS_FILES
+    API/APICallbackFunction.h
     API/APICast.h
+    API/JSAPIWrapperObject.h
     API/JSBase.h
+    API/JSBasePrivate.h
     API/JSCTestRunnerUtils.h
+    API/JSCallbackConstructor.h
+    API/JSCallbackFunction.h
+    API/JSCallbackObject.h
+    API/JSCallbackObjectFunctions.h
+    API/JSClassRef.h
+    API/JSContext.h
+    API/JSContextInternal.h
+    API/JSContextPrivate.h
     API/JSContextRef.h
+    API/JSContextRefInternal.h
     API/JSContextRefPrivate.h
+    API/JSExport.h
+    API/JSManagedValue.h
+    API/JSManagedValueInternal.h
     API/JSObjectRef.h
     API/JSObjectRefPrivate.h
+    API/JSProfilerPrivate.h
     API/JSRetainPtr.h
     API/JSScriptRefPrivate.h
     API/JSStringRef.h
     API/JSStringRefBSTR.h
     API/JSStringRefCF.h
+    API/JSStringRefPrivate.h
+    API/JSValue.h
+    API/JSValueInternal.h
     API/JSValueRef.h
+    API/JSVirtualMachine.h
+    API/JSVirtualMachineInternal.h
     API/JSWeakObjectMapRefInternal.h
     API/JSWeakObjectMapRefPrivate.h
+    API/JSWrapperMap.h
     API/JavaScript.h
     API/JavaScriptCore.h
+    API/ObjcRuntimeExtras.h
     API/OpaqueJSString.h
     API/WebKitAvailability.h
 
     assembler/LinkBuffer.h
     assembler/MacroAssembler.h
     assembler/MacroAssemblerCodeRef.h
-    assembler/MacroAssemblerCodeRef.h
+
+    inspector/augmentable/AugmentableInspectorController.h
+
+    inspector/remote/RemoteInspector.h
+    inspector/remote/RemoteInspectorConstants.h
+    inspector/remote/RemoteInspectorDebuggable.h
+    inspector/remote/RemoteInspectorDebuggableConnection.h
+    inspector/remote/RemoteInspectorXPCConnection.h
+
     jit/GPRInfo.h
+
     runtime/VM.h
 
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
@@ -832,6 +1028,7 @@ ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/yarr/YarrPattern.cpp ${DERIV
 add_custom_command(
     OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
     MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/KeywordLookupGenerator.py
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/parser/Keywords.table
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/KeywordLookupGenerator.py ${CMAKE_CURRENT_SOURCE_DIR}/parser/Keywords.table > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
     VERBATIM)
 ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/parser/Lexer.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h)
@@ -841,57 +1038,97 @@ ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/parser/Lexer.cpp ${DERIVED_S
 
 set(JavaScriptCore_INSPECTOR_SCRIPTS_DIR "${JAVASCRIPTCORE_DIR}/inspector/scripts")
 
+set(JavaScriptCore_INSPECTOR_PROTOCOL_SCRIPTS
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/generate-inspector-protocol-bindings.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/cpp_generator.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/cpp_generator_templates.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_js_backend_commands.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_backend_dispatcher_header.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_backend_dispatcher_implementation.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_frontend_dispatcher_header.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_frontend_dispatcher_implementation.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_protocol_types_header.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generate_cpp_protocol_types_implementation.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generator.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/generator_templates.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/__init__.py
+    ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/codegen/models.py
+)
+
 set(JavaScriptCore_INSPECTOR_DOMAINS
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/ApplicationCache.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMStorage.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Database.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Debugger.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/GenericTypes.json
-    ${JAVASCRIPTCORE_DIR}/inspector/protocol/InspectorDomain.json
-    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Profiler.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Inspector.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/LayerTree.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Network.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/OverlayTypes.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Page.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Runtime.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Timeline.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Worker.json
 )
 
+if (ENABLE_INDEXED_DATABASE)
+    list(APPEND JavaScriptCore_INSPECTOR_DOMAINS
+        ${JAVASCRIPTCORE_DIR}/inspector/protocol/IndexedDB.json
+    )
+endif ()
+
+if (ENABLE_WEB_REPLAY)
+    list(APPEND JavaScriptCore_INSPECTOR_DOMAINS
+        ${JAVASCRIPTCORE_DIR}/inspector/protocol/Replay.json
+    )
+endif ()
+
 add_custom_command(
-    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJS.json
+    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/CombinedDomains.json
     MAIN_DEPENDENCY ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/generate-combined-inspector-json.py
     DEPENDS ${JavaScriptCore_INSPECTOR_DOMAINS}
-    COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/generate-combined-inspector-json.py ${JavaScriptCore_INSPECTOR_DOMAINS} > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJS.json
+    COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/generate-combined-inspector-json.py ${JavaScriptCore_INSPECTOR_DOMAINS} > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/CombinedDomains.json
     VERBATIM)
 
 # Inspector Backend Dispatchers, Frontend Dispatchers, Type Builders
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_WEBINSPECTORUI_DIR}/UserInterface/Protocol)
+file(MAKE_DIRECTORY ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector)
 add_custom_command(
-    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.cpp
-           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.h
-           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.cpp
-           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.h
-           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.cpp
-           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.h
-           ${DERIVED_SOURCES_WEBINSPECTORUI_DIR}/UserInterface/Protocol/InspectorJSBackendCommands.js
-    MAIN_DEPENDENCY ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJS.json
-    DEPENDS ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/CodeGeneratorInspector.py
-            ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/CodeGeneratorInspectorStrings.py
-    COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/CodeGeneratorInspector.py ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJS.json --output_h_dir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" --output_cpp_dir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" --output_js_dir "${DERIVED_SOURCES_WEBINSPECTORUI_DIR}/UserInterface/Protocol" --output_type JavaScript --write_always && mkdir -p ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector && cp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector
+    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorBackendDispatchers.cpp
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorBackendDispatchers.h
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorFrontendDispatchers.cpp
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorFrontendDispatchers.h
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorProtocolObjects.cpp
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorProtocolObjects.h
+           ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorBackendCommands.js
+    MAIN_DEPENDENCY ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/CombinedDomains.json
+    DEPENDS ${JavaScriptCore_INSPECTOR_PROTOCOL_SCRIPTS}
+    COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/generate-inspector-protocol-bindings.py --outputDir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector" --framework JavaScriptCore ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/CombinedDomains.json
     VERBATIM)
 
 # JSCBuiltins
-file(GLOB JSCBuiltins_js_files "${CMAKE_CURRENT_SOURCE_DIR}/builtins/*.js")
 add_custom_command(
    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
    MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins
-   DEPENDS ${JSCBuiltins_js_files}
-   COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins ${JSCBuiltins_js_files} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp
+   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/builtins
+   COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins --input-directory ${CMAKE_CURRENT_SOURCE_DIR}/builtins --output ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp
    VERBATIM)
 
 list(APPEND JavaScriptCore_SOURCES
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.cpp
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.cpp
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.cpp
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorBackendDispatchers.cpp
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorFrontendDispatchers.cpp
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorProtocolObjects.cpp
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp
 )
 
 list(APPEND JavaScriptCore_HEADERS
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.h
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.h
-    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.h
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorBackendDispatchers.h
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorFrontendDispatchers.h
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector/InspectorProtocolObjects.h
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
 )
 
@@ -924,34 +1161,16 @@ if (ENABLE_WEB_REPLAY)
 endif ()
 
 if (WTF_CPU_ARM)
-    list(APPEND JavaScriptCore_SOURCES
-        assembler/ARMAssembler.cpp
-        assembler/ARMv7Assembler.cpp
-        assembler/MacroAssemblerARM.cpp
-    )
-    if (MSVC AND ENABLE_JIT)
-        add_custom_command(
-            OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
-            MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_jit_stubs
-            DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubsARM.h
-            DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp
-            COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_jit_stubs --prefix=MSVC --header ${JAVASCRIPTCORE_DIR}/jit/JITStubsARM.h ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp > ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
-            VERBATIM)
-
-        add_custom_command(
-            OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
-            MAIN_DEPENDENCY ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
-            COMMAND armasm -nologo ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
-            VERBATIM)
-
-        list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj)
-    endif ()
+elseif (WTF_CPU_ARM64)
+elseif (WTF_CPU_HPPA)
+elseif (WTF_CPU_PPC)
+elseif (WTF_CPU_PPC64)
+elseif (WTF_CPU_PPC64LE)
+elseif (WTF_CPU_S390)
+elseif (WTF_CPU_S390X)
 elseif (WTF_CPU_MIPS)
 elseif (WTF_CPU_SH4)
 elseif (WTF_CPU_X86)
-    list(APPEND JavaScriptCore_SOURCES
-        assembler/MacroAssemblerX86Common.cpp
-    )
 elseif (WTF_CPU_X86_64)
     if (MSVC AND ENABLE_JIT)
         add_custom_command(
@@ -962,9 +1181,6 @@ elseif (WTF_CPU_X86_64)
 
         list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/JITStubsMSVC64.obj)
     endif ()
-    list(APPEND JavaScriptCore_SOURCES
-        assembler/MacroAssemblerX86Common.cpp
-    )
 else ()
     message(FATAL_ERROR "Unknown CPU")
 endif ()
@@ -979,12 +1195,11 @@ add_subdirectory(shell)
 
 WEBKIT_WRAP_SOURCELIST(${JavaScriptCore_SOURCES})
 include_directories(${JavaScriptCore_INCLUDE_DIRECTORIES})
-add_definitions(-DSTATICALLY_LINKED_WITH_WTF)
+include_directories(SYSTEM ${JavaScriptCore_SYSTEM_INCLUDE_DIRECTORIES})
 add_library(JavaScriptCore ${JavaScriptCore_LIBRARY_TYPE} ${JavaScriptCore_HEADERS} ${JavaScriptCore_SOURCES})
 target_link_libraries(JavaScriptCore ${JavaScriptCore_LIBRARIES})
 set_target_properties(JavaScriptCore PROPERTIES COMPILE_DEFINITIONS "BUILDING_JavaScriptCore")
 set_target_properties(JavaScriptCore PROPERTIES FOLDER "JavaScriptCore")
-set_target_properties(JavaScriptCore PROPERTIES LINK_INTERFACE_LIBRARIES "")
 
 if (JavaScriptCore_OUTPUT_NAME)
     set_target_properties(JavaScriptCore PROPERTIES OUTPUT_NAME ${JavaScriptCore_OUTPUT_NAME})
@@ -999,3 +1214,5 @@ endif ()
 if (ENABLE_FTL_JIT)
     add_dependencies(JavaScriptCore llvmForJSC)
 endif ()
+
+
index 8abbeb783acef4f219bb2d779b43bf50ff2f43a7..1622ee2fc6eb7acbac221ddfba738d76e95fbaaf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2015-07-27  Babak Shafiei  <bshafiei@apple.com>
+2015-07-31  Lucas Forschler  <lforschler@apple.com>
 
-        Roll out r182829.
+        Merge r187579
 
-2015-07-08  Matthew Hanson  <matthew_hanson@apple.com>
+    2015-07-29  Filip Pizlo  <fpizlo@apple.com>
 
-        Merge r183128. rdar://problem/21716620
+            DFG::ArgumentsEliminationPhase should emit a PutStack for all of the GetStacks that the ByteCodeParser emitted
+            https://bugs.webkit.org/show_bug.cgi?id=147433
+            rdar://problem/21668986
 
-    2015-04-22  Mark Lam  <mark.lam@apple.com>
-
-            SparseArrayEntry's write barrier owner should be the SparseArrayValueMap.
-            https://bugs.webkit.org/show_bug.cgi?id=144067
-
-            Reviewed by Michael Saboff.
-
-            Currently, there are a few places where the JSObject that owns the
-            SparseArrayValueMap is designated as the owner of the SparseArrayEntry
-            write barrier.  This is a bug and can result in the GC collecting the
-            SparseArrayEntry even though it is being referenced by the
-            SparseArrayValueMap.  This patch fixes the bug.
-
-            * runtime/JSObject.cpp:
-            (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
-            (JSC::JSObject::putIndexedDescriptor):
-            * tests/stress/sparse-array-entry-update-144067.js: Added.
-            (useMemoryToTriggerGCs):
-            (foo):
-
-2015-07-08  Matthew Hanson  <matthew_hanson@apple.com>
-
-        Merge r182829. rdar://problem/21716511
-
-    2015-04-14  Chris Dumez  <cdumez@apple.com>
-
-            Regression(r180020): Web Inspector crashes on pages that have a stylesheet with an invalid MIME type
-            https://bugs.webkit.org/show_bug.cgi?id=143745
-            <rdar://problem/20243916>
-
-            Reviewed by Joseph Pecoraro.
-
-            Add assertion in ContentSearchUtilities::findMagicComment() to make
-            sure the content String is not null or we would crash in
-            JSC::Yarr::interpret() later.
-
-            * inspector/ContentSearchUtilities.cpp:
-            (Inspector::ContentSearchUtilities::findMagicComment):
-
-2015-03-06  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r180234
-
-    2015-02-17  Filip Pizlo  <fpizlo@apple.com>
-
-            Throwing from an FTL call IC slow path may result in tag registers being clobbered on 64-bit CPUs
-            https://bugs.webkit.org/show_bug.cgi?id=141717
-            rdar://problem/19863382
-
-            Reviewed by Geoffrey Garen.
-
-            The best solution is to ensure that the engine catching an exception restores tag registers.
-
-            Each of these new test cases reliably crashed prior to this patch and they don't crash at all now.
-
-            * jit/JITOpcodes.cpp:
-            (JSC::JIT::emit_op_catch):
-            * llint/LowLevelInterpreter.asm:
-            * llint/LowLevelInterpreter64.asm:
-            * tests/stress/throw-from-ftl-call-ic-slow-path-cells.js: Added.
-            * tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js: Added.
-            * tests/stress/throw-from-ftl-call-ic-slow-path.js: Added.
-
-2015-03-06  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r181030
-
-    2015-03-04  Filip Pizlo  <fpizlo@apple.com>
-
-            [FTL] inlined GetMyArgumentByVal with no arguments passed causes instant crash
-            https://bugs.webkit.org/show_bug.cgi?id=141180
-            rdar://problem/19677552
+            Reviewed by Mark Lam.
 
-            Reviewed by Benjamin Poulain.
+            Ideally, the ByteCodeParser would only emit SetArgument nodes for named arguments.  But
+            currently that's not what it does - it emits a SetArgument for every argument that a varargs
+            call may pass.  Each SetArgument gets turned into a GetStack.  This means that if
+            ArgumentsEliminationPhase optimizes away PutStacks for those varargs arguments that didn't
+            get passed or used, we get degenerate IR where we have a GetStack of something that didn't
+            have a PutStack.
 
-            If we do a GetMyArgumentByVal on an inlined call frame that has no arguments, then the
-            bounds check already terminates execution. This means we can skip the part where we
-            previously did an out-of-bound array access on the inlined call frame arguments vector.
+            This fixes the bug by removing the code to optimize away PutStacks in
+            ArgumentsEliminationPhase.
 
-            * ftl/FTLLowerDFGToLLVM.cpp:
-            (JSC::FTL::LowerDFGToLLVM::safelyInvalidateAfterTermination):
-            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
-            (JSC::FTL::LowerDFGToLLVM::terminate):
-            (JSC::FTL::LowerDFGToLLVM::didAlreadyTerminate):
-            (JSC::FTL::LowerDFGToLLVM::crash):
-            * tests/stress/get-my-argument-by-val-inlined-no-formal-parameters.js: Added.
-            (foo):
+            * dfg/DFGArgumentsEliminationPhase.cpp:
+            * tests/stress/varargs-inlining-underflow.js: Added.
+            (baz):
             (bar):
-
-2015-03-04  Matthew Hanson  <matthew_hanson@apple.com>
-
-        Merge r180101. rdar://problem/19913017
-
-    2015-02-13  Joseph Pecoraro  <pecoraro@apple.com>
-
-            JSContext Inspector: Do not stash console messages for non-debuggable JSContext
-            https://bugs.webkit.org/show_bug.cgi?id=141589
-
-            Reviewed by Timothy Hatcher.
-
-            Consider developer extras disabled for JSContext inspection if the
-            RemoteInspector server is not enabled (typically a non-debuggable
-            process rejected by webinspectord) or if remote debugging on the
-            JSContext was explicitly disabled via SPI.
-
-            When developer extras are disabled, console message will not be stashed.
-
-            * inspector/JSGlobalObjectInspectorController.cpp:
-            (Inspector::JSGlobalObjectInspectorController::developerExtrasEnabled):
-            * inspector/JSGlobalObjectInspectorController.h:
-
-2015-02-26  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r180452
-
-    2015-02-20  Mark Lam  <mark.lam@apple.com>
-
-            [JSObjCClassInfo reallocateConstructorAndOrPrototype] should also reallocate super class prototype chain.
-            <https://webkit.org/b/141809>
-
-            Reviewed by Geoffrey Garen.
-
-            A ObjC class that implement the JSExport protocol will have a JS prototype
-            chain and constructor automatically synthesized for its JS wrapper object.
-            However, if there are no more instances of that ObjC class reachable by a
-            JS GC root scan, then its synthesized prototype chain and constructors may
-            be released by the GC.  If a new instance of that ObjC class is subsequently
-            instantiated, then [JSObjCClassInfo reallocateConstructorAndOrPrototype]
-            should re-construct the prototype chain and constructor (if they were
-            previously released).  However, the current implementation only
-            re-constructs the immediate prototype, but not every other prototype
-            object upstream in the prototype chain.
-
-            To fix this, we do the following:
-            1. We no longer allocate the JSObjCClassInfo's prototype and constructor
-               eagerly.  Hence, -initWithContext:forClass: will no longer call
-               -allocateConstructorAndPrototypeWithSuperClassInfo:.
-            2. Instead, we'll always access the prototype and constructor thru
-               accessor methods.  The accessor methods will call
-               -allocateConstructorAndPrototype: if needed.
-            3. -allocateConstructorAndPrototype: will fetch the needed superClassInfo
-               from the JSWrapperMap itself.  This makes it so that we no longer
-               need to pass the superClassInfo all over.
-            4. -allocateConstructorAndPrototype: will get the super class prototype
-               by invoking -prototype: on the superClassInfo, thereby allowing the
-               super class to allocate its prototype and constructor if needed and
-               fixing the issue in this bug.
-
-            5. Also removed the GC warning comments, and ensured that needed JS
-               objects are kept alive by having a local var pointing to it from the
-               stack (which makes a GC root).
-
-            * API/JSWrapperMap.mm:
-            (-[JSObjCClassInfo initWithContext:forClass:]):
-            (-[JSObjCClassInfo allocateConstructorAndPrototype]):
-            (-[JSObjCClassInfo wrapperForObject:]):
-            (-[JSObjCClassInfo constructor]):
-            (-[JSObjCClassInfo prototype]):
-            (-[JSWrapperMap classInfoForClass:]):
-            (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]): Deleted.
-            (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): Deleted.
-            (-[JSObjCClassInfo reallocateConstructorAndOrPrototype]): Deleted.
-            * API/tests/Regress141809.h: Added.
-            * API/tests/Regress141809.mm: Added.
-            (-[TestClassB name]):
-            (-[TestClassC name]):
-            (runRegress141809):
-            * API/tests/testapi.mm:
-            * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2015-02-25  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge patch for r180247 and r180249.
-
-    2015-02-20  Michael Saboff  <msaboff@apple.com>
-
-            CrashTracer: DFG_CRASH beneath JSC::FTL::LowerDFGToLLVM::compileNode
-            https://bugs.webkit.org/show_bug.cgi?id=141730
-
-            Reviewed by Geoffrey Garen.
-
-            Added a new failure handler, loweringFailed(), to LowerDFGToLLVM that reports failures
-            while processing DFG lowering.  For debug builds, the failures are logged identical
-            to the way the DFG_CRASH() reports them.  For release builds, the failures are reported
-            and that FTL compilation is terminated, but the process is allowed to continue.
-            Wrapped calls to loweringFailed() in a macro LOWERING_FAILED so the function and
-            line number are reported at the point of the inconsistancy.
-
-            Converted instances of DFG_CRASH to LOWERING_FAILED.
-
-            * dfg/DFGPlan.cpp:
-            (JSC::DFG::Plan::compileInThreadImpl): Added lowerDFGToLLVM() failure check that
-            will fail the FTL compile.
-
-            * ftl/FTLLowerDFGToLLVM.cpp:
-            (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
-            Added new member variable, m_loweringSucceeded, to stop compilation on the first
-            reported failure.
-
-            * ftl/FTLLowerDFGToLLVM.cpp:
-            (JSC::FTL::LowerDFGToLLVM::lower):
-            * ftl/FTLLowerDFGToLLVM.h:
-            Added check for compilation failures and now report those failures via a boolean
-            return value.
-
-            * ftl/FTLLowerDFGToLLVM.cpp:
-            (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
-            (JSC::FTL::LowerDFGToLLVM::compileNode):
-            (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
-            (JSC::FTL::LowerDFGToLLVM::compilePhi):
-            (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
-            (JSC::FTL::LowerDFGToLLVM::compileValueRep):
-            (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
-            (JSC::FTL::LowerDFGToLLVM::compilePutLocal):
-            (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
-            (JSC::FTL::LowerDFGToLLVM::compileArithMul):
-            (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
-            (JSC::FTL::LowerDFGToLLVM::compileArithMod):
-            (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
-            (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
-            (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
-            (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
-            (JSC::FTL::LowerDFGToLLVM::compileGetById):
-            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
-            (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
-            (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
-            (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
-            (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
-            (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
-            (JSC::FTL::LowerDFGToLLVM::compileNewArray):
-            (JSC::FTL::LowerDFGToLLVM::compileToString):
-            (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
-            (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-            (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-            (JSC::FTL::LowerDFGToLLVM::compileSwitch):
-            (JSC::FTL::LowerDFGToLLVM::compare):
-            (JSC::FTL::LowerDFGToLLVM::boolify):
-            (JSC::FTL::LowerDFGToLLVM::opposite):
-            (JSC::FTL::LowerDFGToLLVM::lowJSValue):
-            (JSC::FTL::LowerDFGToLLVM::speculate):
-            (JSC::FTL::LowerDFGToLLVM::isArrayType):
-            (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
-            (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
-            (JSC::FTL::LowerDFGToLLVM::setInt52):
-            Changed DFG_CRASH() to LOWERING_FAILED().  Updated related control flow as appropriate.
-
-            (JSC::FTL::LowerDFGToLLVM::loweringFailed): New error reporting member function.
-
-2015-02-25  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r180516.
-
-    2015-02-23  Matthew Mirman  <mmirman@apple.com>
-
-            r9 is volatile on ARMv7 for iOS 3 and up. 
-            https://bugs.webkit.org/show_bug.cgi?id=141489
-            rdar://problem/19432916
-
-            Reviewed by Michael Saboff.
-
-            * jit/RegisterSet.cpp: 
-            (JSC::RegisterSet::calleeSaveRegisters): removed r9 from the list of ARMv7 callee save registers.
-            * tests/stress/regress-141489.js: Added.
             (foo):
 
-2015-02-20  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r180237
-
-    2015-02-17  Filip Pizlo  <fpizlo@apple.com>
-
-            StackLayoutPhase should use CodeBlock::usesArguments rather than FunctionExecutable::usesArguments
-            https://bugs.webkit.org/show_bug.cgi?id=141721
-            rdar://problem/17198633
-
-            Reviewed by Michael Saboff.
-
-            I've seen cases where the two are out of sync.  We know we can trust the CodeBlock::usesArguments because
-            we use it everywhere else.
-
-            No test because I could never reproduce the crash.
-
-            * dfg/DFGGraph.h:
-            (JSC::DFG::Graph::usesArguments):
-            * dfg/DFGStackLayoutPhase.cpp:
-            (JSC::DFG::StackLayoutPhase::run):
-
-2015-02-20  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r178224.
-
-    2015-01-09  Joseph Pecoraro  <pecoraro@apple.com>
-
-            Web Inspector: Uncaught Exception in ProbeManager deleting breakpoint
-            https://bugs.webkit.org/show_bug.cgi?id=140279
-            rdar://problem/19422299
-
-            Reviewed by Oliver Hunt.
-
-            * runtime/MapData.cpp:
-            (JSC::MapData::replaceAndPackBackingStore):
-            The cell table also needs to have its values fixed.
-
-2015-02-20  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge patch for rdar://problem/19828630.
-
-    2015-02-13  Filip Pizlo  <fpizlo@apple.com>
-
-            Effectful calls to length should only happen once on the varargs path.
-            rdar://problem/19828518
-
-            Reviewed by Michael Saboff.
-
-            * interpreter/Interpreter.cpp:
-            (JSC::sizeFrameForVarargs):
-            (JSC::loadVarargs):
-            * runtime/VM.cpp:
-            (JSC::VM::VM):
-            * runtime/VM.h:
-
-2015-02-10  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r179576, r179648.
-
-    2015-02-04  Mark Lam  <mark.lam@apple.com>
-
-            r179576 introduce a deadlock potential during GC thread suspension.
-            <https://webkit.org/b/141268>
-
-            Reviewed by Michael Saboff.
-
-            http://trac.webkit.org/r179576 introduced a potential for deadlocking.
-            In the GC thread suspension loop, we currently delete
-            MachineThreads::Thread that we detect to be invalid.  This is unsafe
-            because we may have already suspended some threads, and one of those
-            suspended threads may still be holding the C heap lock which we need
-            for deleting the invalid thread.
-
-            The fix is to put the invalid threads in a separate toBeDeleted list,
-            and delete them only after GC has resumed all threads.
-
-            * heap/MachineStackMarker.cpp:
-            (JSC::MachineThreads::removeCurrentThread):
-            - Undo refactoring removeThreadWithLockAlreadyAcquired() out of
-            removeCurrentThread() since it is no longer needed.
-
-            (JSC::MachineThreads::tryCopyOtherThreadStacks):
-            - Put invalid Threads on a threadsToBeDeleted list, and delete those
-            Threads only after all threads have been resumed.
-
-            (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired): Deleted.
-            * heap/MachineStackMarker.h:
-
-    2015-02-03  Mark Lam  <mark.lam@apple.com>
-
-            Workaround a thread library bug where thread destructors may not get called.
-            <https://webkit.org/b/141209>
-
-            Reviewed by Michael Saboff.
-
-            There's a bug where thread destructors may not get called.  As far as
-            we know, this only manifests on darwin ports.  We will work around this
-            by checking at GC time if the platform thread is still valid.  If not,
-            we'll purge it from the VM's registeredThreads list before proceeding
-            with thread scanning activity.
-
-            Note: it is important that we do this invalid thread detection during
-            suspension, because the validity (and liveness) of the other thread is
-            only guaranteed while it is suspended.
-
-            * API/tests/testapi.mm:
-            (threadMain):
-            - Added a test to enter the VM from another thread before we GC on
-              the main thread.
-
-            * heap/MachineStackMarker.cpp:
-            (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired):
-            (JSC::MachineThreads::removeCurrentThread):
-            - refactored removeThreadWithLockAlreadyAcquired() out from
-              removeCurrentThread() so that we can also call it for purging invalid
-              threads.
-            (JSC::suspendThread):
-            - Added a return status to tell if the suspension succeeded or not.
-            (JSC::MachineThreads::tryCopyOtherThreadStacks):
-            - Check if the suspension failed, and purge the thread if we can't
-              suspend it.  Failure to suspend implies that the thread has
-              terminated without calling its destructor.
-            * heap/MachineStackMarker.h:
-
-2015-02-10  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r179187.
-
-    2015-01-27  Csaba Osztrogonác  <ossy@webkit.org>
-
-            [ARM] Typo fix after r176083
-            https://bugs.webkit.org/show_bug.cgi?id=140937
-
-            Reviewed by Anders Carlsson.
-
-            * assembler/ARMv7Assembler.h:
-            (JSC::ARMv7Assembler::ldrh):
-
-2015-02-10  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r176083.
-
-    2014-11-13  Benjamin Poulain  <benjamin@webkit.org>
-
-            ARMv7(s) Assembler: LDRH with immediate offset is loading from the wrong offset
-            https://bugs.webkit.org/show_bug.cgi?id=136914
-
-            Reviewed by Michael Saboff.
-
-            TLDR: the immediate offset of half-word load was divided by 2.
-
-            Story time: So I started getting those weird reports of :nth-child() behaving bizarrely
-            on ARMv7 and ARMv7s. To make things worse, the behavior changes depending on style updates.
-
-            I started looking the disassembly on the tests cases...
-
-            The first thing I noticed was that the computation of An+B looked wrong. For example,
-            in the case of n+6, the instruction should have been:
-                subs r1, r1, #6
-            but was
-                subs r1, r1, #2
-
-            After spending a lot of time trying to find the error in the assembler, I discovered
-            the problem was not real, but just a bug in the disassembler.
-            This is the first fix: ARMv7DOpcodeAddSubtractImmediate3's immediate3() was truncating
-            the value to 2 bits instead of 3 bits.
-
-            The disassembler being fixed, I still have no lead on the weird bug. Some disassembly later,
-            I realize the LDRH instruction is not decoded at all. The reason is that both LDRH and STRH
-            were under the umbrella ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord but the pattern
-            only matched SRTH.
-
-            I fix that next, ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord is split into
-            ARMv7DOpcodeStoreRegisterImmediateHalfWord and ARMv7DOpcodeLoadRegisterImmediateHalfWord,
-            each with their own pattern and their instruction group.
-
-            Now that I can see the LDRHs correctly, there is something fishy about them, their offset
-            is way too small for the data I load.
-
-            This time, looking at the binary, the generated code is indeed incorrect. It turns out that
-            the ARMv7 assembler shifted the offset of half-word load as if they were byte load: divided by 4.
-            As a result, all the load of half-words with more than zero offset were loading
-            values with a smaller offset than what they should have.
-
-            That being fixed, I dump the assembly: still wrong. I am ready to throw my keyboard through
-            my screen at that point.
-
-            Looking at the disassembler, there is yet again a bug. The computation of the scale() adjustment
-            of the offset was incorrect for anything but word loads.
-            I replaced it by a switch-case to make it explicit.
-
-            STRH is likely incorrect too. I'll fix that in a follow up, I want to survey all the 16 bits cases
-            that are not directly used by the CSS JIT.
-
-            * assembler/ARMv7Assembler.h:
-            (JSC::ARMv7Assembler::ldrh):
-            Fix the immediate scaling. Add an assertion to make sure the alignment of the input is correct.
-
-            * disassembler/ARMv7/ARMv7DOpcode.cpp:
-            (JSC::ARMv7Disassembler::ARMv7DOpcodeLoadStoreRegisterImmediate::scale):
-            Fix the scaling code. Just hardcode instruction-to-scale table.
-
-            * disassembler/ARMv7/ARMv7DOpcode.h:
-            (JSC::ARMv7Disassembler::ARMv7DOpcodeAddSubtractImmediate3::immediate3):
-            The mask for a 3 bits immediate is not 3 :)
-
-            (JSC::ARMv7Disassembler::ARMv7DOpcodeLoadStoreRegisterImmediate::scale): Deleted.
-
-2015-02-05  Lucas Forschler  <lforschler@apple.com>
+2015-07-24  Matthew Hanson  <matthew_hanson@apple.com>
 
-        Merge r178953
+        Merge r187139. rdar://problem/21847618
 
-    2015-01-21  Joseph Pecoraro  <pecoraro@apple.com>
+    2015-07-21  Filip Pizlo  <fpizlo@apple.com>
 
-            Web Inspector: ASSERT expanding objects in console PrimitiveBindingTraits<T>::assertValueHasExpectedType
-            https://bugs.webkit.org/show_bug.cgi?id=140746
+            Unreviewed, fix a lot of tests. Need to initialize WTF threading sooner.
 
-            Reviewed by Timothy Hatcher.
-
-            * inspector/InjectedScriptSource.js:
-            Do not add impure properties to the descriptor object that will
-            eventually be sent to the frontend.
-
-2015-02-05  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r178768
-
-    2015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
-
-            Web Inspector: Expanding event objects in console shows undefined for most values, it should have real values
-            https://bugs.webkit.org/show_bug.cgi?id=137306
-
-            Reviewed by Timothy Hatcher.
-
-            Provide another optional parameter to getProperties, to gather a list
-            of all own and getter properties.
-
-            * inspector/InjectedScript.cpp:
-            (Inspector::InjectedScript::getProperties):
-            * inspector/InjectedScript.h:
-            * inspector/InjectedScriptSource.js:
-            * inspector/agents/InspectorRuntimeAgent.cpp:
-            (Inspector::InspectorRuntimeAgent::getProperties):
-            * inspector/agents/InspectorRuntimeAgent.h:
-            * inspector/protocol/Runtime.json:
-
-2015-02-04  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r179329
-
-    2015-01-13  Geoffrey Garen  <ggaren@apple.com>
-
-            Out of bounds access in BytecodeGenerator::emitGetById under DotAccessorNode::emitBytecode
-            https://bugs.webkit.org/show_bug.cgi?id=140397
-
-            Reviewed by Geoffrey Garen.
-
-            Patch by Alexey Proskuryakov.
-
-            Reviewed, performance tested, and ChangeLogged by Geoffrey Garen.
-
-            No performance change.
-
-            No test, since this is a small past-the-end read, which is very
-            difficult to turn into a reproducible failing test -- and existing tests
-            crash reliably using ASan.
-
-            * bytecompiler/NodesCodegen.cpp:
-            (JSC::BracketAccessorNode::emitBytecode):
-            (JSC::DotAccessorNode::emitBytecode):
-            (JSC::FunctionCallBracketNode::emitBytecode):
-            (JSC::PostfixNode::emitResolve):
-            (JSC::DeleteBracketNode::emitBytecode):
-            (JSC::DeleteDotNode::emitBytecode):
-            (JSC::PrefixNode::emitResolve):
-            (JSC::UnaryOpNode::emitBytecode):
-            (JSC::BitwiseNotNode::emitBytecode):
-            (JSC::BinaryOpNode::emitBytecode):
-            (JSC::EqualNode::emitBytecode):
-            (JSC::StrictEqualNode::emitBytecode):
-            (JSC::ThrowableBinaryOpNode::emitBytecode):
-            (JSC::AssignDotNode::emitBytecode):
-            (JSC::AssignBracketNode::emitBytecode): Use RefPtr in more places. Any
-            register used across a call to a function that might allocate a new
-            temporary register must be held in a RefPtr.
-
-2015-02-04  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r178311
-
-    2015-01-12  Geoffrey Garen  <ggaren@apple.com>
-
-            Out of bounds read in IdentifierArena::makeIdentifier
-            https://bugs.webkit.org/show_bug.cgi?id=140376
-
-            Patch by Alexey Proskuryakov.
-
-            Reviewed and ChangeLogged by Geoffrey Garen.
-
-            No test, since this is a small past-the-end read, which is very
-            difficult to turn into a reproducible failing test -- and existing tests
-            crash reliably using ASan.
-
-            * parser/ParserArena.h:
-            (JSC::IdentifierArena::makeIdentifier):
-            (JSC::IdentifierArena::makeIdentifierLCharFromUChar): Check for a
-            zero-length string input, like we do in the literal parser, since it is
-            not valid to dereference characters in a zero-length string.
-
-            A zero-length string is allowed in JavaScript -- for example, "".
-
-2015-01-28  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r178364
-
-    2015-01-12  Michael Saboff  <msaboff@apple.com>
-
-            Local JSArray* "keys" in objectConstructorKeys() is not marked during garbage collection
-            https://bugs.webkit.org/show_bug.cgi?id=140348
-
-            Reviewed by Mark Lam.
-
-            We used to read registers in MachineThreads::gatherFromCurrentThread(), but that is too late
-            because those registers may have been spilled on the stack and replaced with other values by
-            the time we call down to gatherFromCurrentThread().
-
-            Now we get the register contents at the same place that we demarcate the current top of
-            stack using the address of a local variable, in Heap::markRoots().  The register contents
-            buffer is passed along with the demarcation pointer.  These need to be done at this level 
-            in the call tree and no lower, as markRoots() calls various functions that visit object
-            pointers that may be latter proven dead.  Any of those pointers that are left on the
-            stack or in registers could be incorrectly marked as live if we scan the stack contents
-            from a called function or one of its callees.  The stack demarcation pointer and register
-            saving need to be done in the same function so that we have a consistent stack, active
-            and spilled registers.
-
-            Because we don't want to make unnecessary calls to get the register contents, we use
-            a macro to allocated, and possibly align, the register structure and get the actual
-            register contents.
-
-
-            * heap/Heap.cpp:
-            (JSC::Heap::markRoots):
-            (JSC::Heap::gatherStackRoots):
-            * heap/Heap.h:
-            * heap/MachineStackMarker.cpp:
-            (JSC::MachineThreads::gatherFromCurrentThread):
-            (JSC::MachineThreads::gatherConservativeRoots):
-            * heap/MachineStackMarker.h:
-
-2015-01-27  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r177455
-
-    2014-12-17  Chris Dumez  <cdumez@apple.com>
-
-            [iOS] Make it possible to toggle FeatureCounter support at runtime
-            https://bugs.webkit.org/show_bug.cgi?id=139688
-            <rdar://problem/19266254>
-
-            Reviewed by Andreas Kling.
-
-            Stop linking against AppSupport framework as the functionality is no
-            longer in WTF (it was moved to WebCore).
-
-            * Configurations/JavaScriptCore.xcconfig:
-
-2015-01-26  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r177328
-
-    2014-12-15  Chris Dumez  <cdumez@apple.com>
-
-            [iOS] Add feature counting support
-            https://bugs.webkit.org/show_bug.cgi?id=139652
-            <rdar://problem/19255690>
-
-            Reviewed by Gavin Barraclough.
-
-            Link against AppSupport framework on iOS as we need it to implement
-            the new FeatureCounter API in WTF.
-
-            * Configurations/JavaScriptCore.xcconfig:
-
-2015-01-21  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r176972.
-
-    2014-12-08  Mark Lam  <mark.lam@apple.com>
-
-            CFA wrongly assumes that a speculation for SlowPutArrayStorageShape disallows ArrayStorageShape arrays.
-            <https://webkit.org/b/139327>
-
-            Reviewed by Michael Saboff.
-
-            The code generator and runtime slow paths expects otherwise.  This patch fixes
-            CFA to match the code generator's expectation.
-
-            * dfg/DFGArrayMode.h:
-            (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
-            (JSC::DFG::ArrayMode::arrayModesWithIndexingShapes):
-
-2015-01-20  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r171691.
-
-    2014-07-28  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-            REGRESSION: JSObjectSetPrototype() does not work on result of JSGetGlobalObject()
-            https://bugs.webkit.org/show_bug.cgi?id=135322
-
-            Reviewed by Oliver Hunt.
-
-            The prototype chain of the JSProxy object should match that of the JSGlobalObject. 
-
-            This is a separate but related issue with JSObjectSetPrototype which doesn't correctly 
-            account for JSProxies. I also audited the rest of the C API to check that we correctly 
-            handle JSProxies in all other situations where we expect a JSCallbackObject of some sort
-            and found some SPI calls (JSObject*PrivateProperty) that didn't behave correctly when 
-            passed a JSProxy.
-
-            I also added some new tests for these cases.
-
-            * API/JSObjectRef.cpp:
-            (JSObjectSetPrototype):
-            (JSObjectGetPrivateProperty):
-            (JSObjectSetPrivateProperty):
-            (JSObjectDeletePrivateProperty):
-            * API/JSWeakObjectMapRefPrivate.cpp:
-            * API/tests/CustomGlobalObjectClassTest.c:
-            (globalObjectSetPrototypeTest):
-            (globalObjectPrivatePropertyTest):
-            * API/tests/CustomGlobalObjectClassTest.h:
-            * API/tests/testapi.c:
+            * jsc.cpp:
             (main):
 
-2015-01-11  Mark Lam  <mark.lam@apple.com>
-
-        Update WebKit branch to build with newer LLVM.
-        <https://webkit.org/b/140341>
-
-        Reviewed by Filip Pizlo.
-
-        * Configurations/LLVMForJSC.xcconfig:
-        - Add the ability to pick up LLVM_LIBS_iphoneos from AspenLLVM.xcconfig.
-        * llvm/LLVMAPIFunctions.h:
-        - Removed some erroneous and unused APIs.
-        * llvm/library/LLVMExports.cpp:
-        (initializeAndGetJSCLLVMAPI):
-        - Removed an unneeded option that is also not supported by the new LLVM.
-
-2014-12-10  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r176803.
-
-    2014-12-04  Oliver Hunt  <oliver@apple.com>
-
-            Serialization of MapData object provides unsafe access to internal types
-            https://bugs.webkit.org/show_bug.cgi?id=138653
-
-            Reviewed by Geoffrey Garen.
-
-            Converting these ASSERTs into RELEASE_ASSERTs, as it is now obvious
-            that despite trying hard to be safe in all cases it's simply to easy
-            to use an iterator in an unsafe state.
-
-            * runtime/MapData.h:
-            (JSC::MapData::const_iterator::key):
-            (JSC::MapData::const_iterator::value):
-
-2014-09-15  Babak Shafiei  <bshafiei@apple.com>
-
-        <rdar://problem/18327341> Disable Web Timing on this branch.
-
-        Reviewed originally by Sam Weinig.
-
-        Disable:
-        - WEB_TIMING
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-08-03  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge patch for <rdar://problem/17887398>.
-    2014-07-30  Filip Pizlo  <fpizlo@apple.com>
-
-            NewFunctionExpression and NewFunctionNoCheck should setHaveStructures(true)
-            https://bugs.webkit.org/show_bug.cgi?id=135430
-
-            Reviewed by Mark Hahnenberg.
-
-            * dfg/DFGAbstractInterpreterInlines.h:
-            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-            * tests/stress/new-function-expression-has-structures.js: Added.
-            (foo.f):
-            (foo.f.prototype.f):
-            (foo):  
-
-2014-08-03  Babak Shafiei  <bshafiei@apple.com>
-
-        Merge r171949.
-
-    2014-08-01  Csaba Osztrogonác  <ossy@webkit.org>
-
-            URTBF after r171946 to fix non-Apple builds.
-
-            * bytecode/InlineCallFrameSet.cpp:
+2015-07-23  Lucas Forschler  <lforschler@apple.com>
 
-2014-08-03  Babak Shafiei  <bshafiei@apple.com>
+        Merge r187125
 
-        Merge r171946.
+    2015-07-21  Filip Pizlo  <fpizlo@apple.com>
 
-    2014-08-01  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-            CodeBlock fails to visit the Executables of its InlineCallFrames
-            https://bugs.webkit.org/show_bug.cgi?id=135471
+            Fixed VM pool allocation should have a reserve for allocations that cannot fail
+            https://bugs.webkit.org/show_bug.cgi?id=147154
+            rdar://problem/21847618
 
             Reviewed by Geoffrey Garen.
 
-            CodeBlock needs to visit its InlineCallFrames' owner Executables. If it doesn't, they 
-            can be prematurely collected and cause crashes.
-
-            * bytecode/CodeBlock.cpp:
-            (JSC::CodeBlock::stronglyVisitStrongReferences):
-            * bytecode/CodeOrigin.h:
-            (JSC::InlineCallFrame::visitAggregate):
-            * bytecode/InlineCallFrameSet.cpp:
-            (JSC::InlineCallFrameSet::visitAggregate):
-            * bytecode/InlineCallFrameSet.h:
-
-2014-07-29  Matthew Hanson  <matthew_hanson@apple.com>
-
-        Merge r171689. <rdar://problem/17844890>
-
-    2014-07-28  Filip Pizlo  <fpizlo@apple.com>
-    
-            Make sure that we don't use non-speculative BooleanToNumber for a speculative Branch
-            https://bugs.webkit.org/show_bug.cgi?id=135350
-            <rdar://problem/17509889>
-    
-            Reviewed by Mark Hahnenberg and Oliver Hunt.
-            
-            If we have an exiting node that uses a conversion node, then that exiting node
-            needs to have a Phantom after it for the the original node. But we can't do that
-            for Branch because https://bugs.webkit.org/show_bug.cgi?id=126778.
-    
-            * dfg/DFGFixupPhase.cpp:
-            (JSC::DFG::FixupPhase::fixupNode):
-            (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
-            * tests/stress/branch-check-int32-on-boolean-to-number-untyped.js: Added.
-            (foo):
-            (test):
-            * tests/stress/branch-check-number-on-boolean-to-number-untyped.js: Added.
-            (foo):
-            (test):
-    
-2014-07-29  Matthew Hanson  <matthew_hanson@apple.com>
-
-        Merge r171688. <rdar://problem/17364180>
-
-    2014-07-28  Joseph Pecoraro  <pecoraro@apple.com>
-    
-            JSContext Inspector: crash when using step-into
-            https://bugs.webkit.org/show_bug.cgi?id=135345
-    
-            Reviewed by Timothy Hatcher.
-    
-            * inspector/agents/InspectorDebuggerAgent.cpp:
-            (Inspector::InspectorDebuggerAgent::stepInto):
-            Null check m_listener since it may not be set.
-    
-2014-07-25  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171578
-
-    2014-07-24  Brent Fulgham  <bfulgham@apple.com>
-
-            [Win] Correct build order in JavaScriptCore.submit.sln
-            https://bugs.webkit.org/show_bug.cgi?id=135282
-            <rdar://problem/17805592>
-
-            Unreviewed build fix.
-
-            * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: Correct build order
-            such that LLIntDesiredOffset is built prior to the rest of JSC.
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171564
-
-    2014-07-24  Mark Lam  <mark.lam@apple.com>
-
-            JSWrapperMap's jsWrapperForObject() needs to keep weak prototype and constructors from being GCed.
-            <https://webkit.org/b/135258>
-
-            Reviewed by Mark Hahnenberg.
-
-            Where needed, we cache the prototype object pointer in a stack local var.
-            This allows it to be scanned by the GC, and hence be kept alive until
-            we use it.  The constructor object will in turn be kept alive by the
-            prototype object.
-
-            Also added some comments to warn against future code additions that could
-            regress this issue.
-
-            * API/JSWrapperMap.mm:
-            (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]):
-            (-[JSObjCClassInfo reallocateConstructorAndOrPrototype]):
-            (-[JSObjCClassInfo wrapperForObject:]):
-            (-[JSObjCClassInfo constructor]):
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171558
-
-    2014-07-24  Joseph Pecoraro  <pecoraro@apple.com>
-
-            JSLock release should only modify the AtomicStringTable if it modified in acquire
-            https://bugs.webkit.org/show_bug.cgi?id=135143
-
-            Reviewed by Darin Adler.
-
-            * runtime/JSLock.cpp:
-            (JSC::JSLock::JSLock):
-            Initialize the member variable to nullptr.
-
-            (JSC::JSLock::willDestroyVM):
-            Update style to use nullptr instead of 0.
-
-            (JSC::JSLock::willReleaseLock):
-            We should only reset the thread data's atomic string table if
-            didAcquireLock changed it. m_entryAtomicStringTable will have
-            been set by didAcquireLock if it changed, or nullptr if it didn't.
-            This way we are sure we are balanced, regardless of m_vm changes.
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171543
-
-    2014-07-24  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-            Creating a JSGlobalObject with a custom JSClassRef results in a JSProxy with the wrong prototype
-            https://bugs.webkit.org/show_bug.cgi?id=135250
-
-            Reviewed by Geoffrey Garen.
-
-            JSGlobalObject::resetPrototype (which is called from JSGlobalContextCreateInGroup) doesn't change its 
-            JSProxy's prototype as well. This results in a JSProxy where no properties in the original prototype 
-            chain (as created from the JSClassRef hierarchy) are accessible. Changing resetPrototype to also change
-            the JSProxy's prototype fixes the issue.
-
-            * API/JSValueRef.cpp:
-            (JSValueIsObjectOfClass): Also fixed a bug where a JSProxy for a JSGlobalObject with a custom JSClassRef
-            would claim it wasn't of the specified class, even if the target was of the specified class.
-            * API/tests/CustomGlobalObjectClassTest.c: Added.
-            (jsDoSomething):
-            (customGlobalObjectClassTest):
-            * API/tests/CustomGlobalObjectClassTest.h: Added.
-            * API/tests/testapi.c:
-            (assertTrue):
+            This adds the notion of a JIT pool reserve fraction. Some fraction, currently 1/4, of
+            the JIT pool is reserved for allocations that cannot fail. It makes sense to make this
+            a fraction rather than a constant because each allocation that can fail may cause some
+            number of allocations that cannot fail (for example, the OSR exit thunks that we
+            compile when we exit from some CodeBlock cannot fail).
+
+            I've tested this by adding a test mode where we artificially limit the JIT pool size.
+            Prior to the fix, we had >20 failures. Now we have none.
+
+            * heap/GCLogging.cpp:
+            (WTF::printInternal): I needed a dump method on Options members when debugging this.
+            * heap/GCLogging.h:
+            * jit/ExecutableAllocator.h: Raise the ARM64 limit to 32MB because 16MB is cutting it too close.
+            * jit/ExecutableAllocatorFixedVMPool.cpp:
+            (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): Add the ability to artificially limit JIT pool size for testing.
+            (JSC::ExecutableAllocator::memoryPressureMultiplier): Implement the reserve when computing memory pressure for JIT tier-up heuristics.
+            (JSC::ExecutableAllocator::allocate): Implement the reserve when allocating can-fail things.
+            * jsc.cpp: Rewire some options parsing so that CommandLine happens before we create the JIT pool.
             (main):
-            * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
-            * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters:
-            * JavaScriptCore.xcodeproj/project.pbxproj:
-            * runtime/JSGlobalObject.cpp:
-            (JSC::JSGlobalObject::resetPrototype):
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171395
-
-    2014-07-22  Brent Fulgham  <bfulgham@apple.com>
-
-            Build fix for non-clang compile.
-
-            * jsc.cpp:
-            (WTF::RuntimeArray::put): Remove incorrect return statement
-            I added.
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171393
-
-    2014-07-22  Brent Fulgham  <bfulgham@apple.com>
-
-            Build fix for non-clang compile.
-
-            * jsc.cpp:
-            (WTF::RuntimeArray::deleteProperty): Need (fake) return
-            value when NO_RETURN_DUE_TO_CRASH is not defined.
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171390
-
-    2014-07-22  Mark Lam  <mark.lam@apple.com>
-
-            Array.concat() should work on runtime arrays too.
-            <https://webkit.org/b/135179>
-
-            Reviewed by Geoffrey Garen.
-
-            * jsc.cpp:
-            (WTF::RuntimeArray::create):
-            (WTF::RuntimeArray::~RuntimeArray):
-            (WTF::RuntimeArray::destroy):
-            (WTF::RuntimeArray::getOwnPropertySlot):
-            (WTF::RuntimeArray::getOwnPropertySlotByIndex):
-            (WTF::RuntimeArray::put):
-            (WTF::RuntimeArray::deleteProperty):
-            (WTF::RuntimeArray::getLength):
-            (WTF::RuntimeArray::createPrototype):
-            (WTF::RuntimeArray::createStructure):
-            (WTF::RuntimeArray::finishCreation):
-            (WTF::RuntimeArray::RuntimeArray):
-            (WTF::RuntimeArray::lengthGetter):
-            (GlobalObject::finishCreation):
-            (functionCreateRuntimeArray):
-            - Added support to create a runtime array for testing purpose.
-            * runtime/ArrayPrototype.cpp:
-            (JSC::getLength):
-            - Added fast case for when the array object is a JSArray.
-            (JSC::arrayProtoFuncJoin):
-            - Added a needed but missing exception check.
-            (JSC::arrayProtoFuncConcat):
-            - Use getLength() to compute the array length instead of assuming that
-              the array is a JSArray instance.
-            * tests/stress/regexp-matches-array.js: Added.
-            (testArrayConcat):
-            * tests/stress/runtime-array.js: Added.
-            (testArrayConcat):
-
-2014-07-24  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171328
-
-    2014-07-21  Mark Lam  <mark.lam@apple.com>
-
-            Refactor ArrayPrototype to use getLength() and putLength() utility functions.
-            https://bugs.webkit.org/show_bug.cgi?id=135139.
-
-            Reviewed by Oliver Hunt.
-
-            - Specialize putProperty() to putLength() because it is only used for setting
-              the length property.
-            - Added a getLength() utility function to get the value of the length property.
-            - Use these getLength() and putLength() functions instead of the existing code
-              to get and put the length property.  Less code to read, easier to understand.
-
-            * runtime/ArrayPrototype.cpp:
-            (JSC::getLength):
-            (JSC::putLength):
-            (JSC::arrayProtoFuncToString):
-            (JSC::arrayProtoFuncToLocaleString):
-            (JSC::arrayProtoFuncJoin):
-            (JSC::arrayProtoFuncPop):
-            (JSC::arrayProtoFuncPush):
-            (JSC::arrayProtoFuncReverse):
-            (JSC::arrayProtoFuncShift):
-            (JSC::arrayProtoFuncSlice):
-            (JSC::arrayProtoFuncSort):
-            (JSC::arrayProtoFuncSplice):
-            (JSC::arrayProtoFuncUnShift):
-            (JSC::arrayProtoFuncReduce):
-            (JSC::arrayProtoFuncReduceRight):
-            (JSC::arrayProtoFuncIndexOf):
-            (JSC::arrayProtoFuncLastIndexOf):
-            (JSC::putProperty): Deleted.
-
-2014-07-23  Matthew Hanson  <matthew_hanson@apple.com>
-
-        Merge r171474 (rollout r171367 from trunk)
-
-2014-07-23  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171367
-
-    2014-07-22  Joseph Pecoraro  <pecoraro@apple.com>
-
-            JSLock release should only modify the AtomicStringTable if it modified in acquire
-            https://bugs.webkit.org/show_bug.cgi?id=135143
-
-            Reviewed by Pratik Solanki.
-
-            * runtime/JSLock.cpp:
-            (JSC::JSLock::willDestroyVM):
-            (JSC::JSLock::willReleaseLock):
-            Only set the AtomicStringTable when there was a VM, to balance JSLock::didAcquireLock.
-
-2014-07-23  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171355
-
-    2014-07-21  Sam Weinig  <sam@webkit.org>
-
-            [Cocoa] WKScriptMessageHandlers don't seem to function properly after navigating
-            https://bugs.webkit.org/show_bug.cgi?id=135148
-
-            Reviewed by Geoffrey Garen.
-
-            * runtime/CommonIdentifiers.h:
-            Add a common identifier for the string "webkit".
-
-2014-07-23  Lucas Forschler  <lforschler@apple.com>
-
-        Merge r171354
-
-    2014-07-22  Filip Pizlo  <fpizlo@apple.com>
-
-            ASSERTION FAILED: info.spillFormat() & DataFormatJS in JSC::DFG::SpeculativeJIT::fillSpeculateCell
-            https://bugs.webkit.org/show_bug.cgi?id=135155
-            <rdar://problem/17763909>
-
-            Reviewed by Oliver Hunt.
-
-            The DFG fillSpeculate code paths all need to be mindful of the fact that they may be stumbling upon a
-            contradiction, and that this is OK. In this case, we were speculating cell on an int.
-
-            * dfg/DFGSpeculativeJIT64.cpp:
-            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-            * tests/stress/regress-135155.js: Added.
-            (run.t.length):
-            (run):
-
-2014-07-22 Dana Burkart <dburkart@apple.com>
-    
-        Merge r171228.
-
-    2014-07-18  Filip Pizlo  <fpizlo@apple.com>
-
-            Fix cloop build.
-
-            * jsc.cpp:
-            (jscmain):
-
-2014-07-22 Dana Burkart <dburkart@apple.com>
-    
-        Merge r171213.
-
-    2014-07-15  Filip Pizlo  <fpizlo@apple.com>
-
-            Need ability to fuzz exception throwing
-            https://bugs.webkit.org/show_bug.cgi?id=134945
-            <rdar://problem/17722027>
-
-            Reviewed by Sam Weinig.
-            
-            Adds the ability to instrument exception checks, and to force some random
-            exception check to artificially throw an exception. Also adds new tests that
-            are suitable for testing this. Note that this is closely tied to the Tools
-            directory changes that are also part of this changeset.
-            
-            This also fixes an activation tear-off bug that arises if we ever throw an
-            exception from operationOptimize, or if due to some other bug it's only due
-            to the operationOptimize exception check that we realize that there is an
-            exception to be thrown.
-
-            * dfg/DFGJITCompiler.h:
-            (JSC::DFG::JITCompiler::fastExceptionCheck):
-            * ftl/FTLIntrinsicRepository.h:
-            * ftl/FTLLowerDFGToLLVM.cpp:
-            (JSC::FTL::LowerDFGToLLVM::callCheck):
-            * interpreter/Interpreter.cpp:
-            (JSC::unwindCallFrame):
-            * jit/AssemblyHelpers.cpp:
-            (JSC::AssemblyHelpers::callExceptionFuzz):
-            (JSC::AssemblyHelpers::emitExceptionCheck):
-            * jit/AssemblyHelpers.h:
-            (JSC::AssemblyHelpers::emitExceptionCheck): Deleted.
-            * jit/JIT.cpp:
-            (JSC::JIT::privateCompileMainPass):
-            * jit/JITOpcodes.cpp:
-            (JSC::JIT::emit_op_enter):
-            * jit/JITOperations.cpp:
-            (JSC::numberOfExceptionFuzzChecks):
-            * jit/JITOperations.h:
-            * jsc.cpp:
+            (CommandLine::parseArguments):
             (jscmain):
+            * runtime/Options.cpp: 
+            (JSC::OptionRange::dump): I needed a dump method on Options members when debugging this.
+            (JSC::Options::initialize): This can now be called more than once.
             * runtime/Options.h:
-            * runtime/TestRunnerUtils.h:
-            * tests/exceptionFuzz.yaml: Added.
-            * tests/exceptionFuzz: Added.
-            * tests/exceptionFuzz/3d-cube.js: Added.
-            * tests/exceptionFuzz/date-format-xparb.js: Added.
-            * tests/exceptionFuzz/earley-boyer.js: Added.
-
-2014-07-22 Dana Burkart <dburkart@apple.com>
-    
-        Merge r171204.
-
-    2014-07-17  Joseph Pecoraro  <pecoraro@apple.com>
-
-            Follow-up fix to r171195 to prevent ASSERT in fast/profiler/profile-with-no-title.html
-
-            Rubber-stamped by Alexey Proskuryakov.
-
-            Null / empty titles should be fine. Tests pass in release builds
-            which allowed empty titles, and it looks like the LegacyProfiler
-            stopProfiling handles empty titles as expected already.
-
-            * profiler/LegacyProfiler.cpp:
-            (JSC::LegacyProfiler::startProfiling):
-
-2014-07-22 Dana Burkart <dburkart@apple.com>
-    
-        Merge r171190.
-
-    2014-07-16  Filip Pizlo  <fpizlo@apple.com>
-
-            DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw
-            https://bugs.webkit.org/show_bug.cgi?id=134988
-            <rdar://problem/17706349>
-
-            Reviewed by Oliver Hunt.
-            
-            Luckily, we also don't need this optimization to be super powerful: the only place
-            where it really matters is for getting rid of the redundancy between op_enter and
-            op_init_lazy_reg, and in that case, there is a small set of possible nodes between the
-            two things. This change updates the store eliminator to know about only that small,
-            obviously safe, set of nodes over which we can store-eliminate.
-            
-            This shouldn't have any performance impact in the DFG because this optimization kicks
-            in relatively rarely already. And once we tier up into the FTL, we get a much better
-            store elimination over LLVM IR, so this really shouldn't matter at all.
-            
-            The tricky part of this patch is that there is a close relative of this optimization,
-            for uncaptured variables that got flushed. This happens for arguments to inlined calls.
-            I make this work by splitting it into two different store eliminators.
-            
-            Note that in the process of crafting the tests, I realized that we were incorrectly
-            DCEing NewArrayWithSize. That's not cool, since that can throw an exception for
-            negative array sizes. If we ever did want to DCE this node, we'd need to lower the node
-            to a check node followed by the actual allocation.
-
-            * dfg/DFGCSEPhase.cpp:
-            (JSC::DFG::CSEPhase::uncapturedSetLocalStoreElimination):
-            (JSC::DFG::CSEPhase::capturedSetLocalStoreElimination):
-            (JSC::DFG::CSEPhase::setLocalStoreElimination):
-            (JSC::DFG::CSEPhase::performNodeCSE):
-            (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
-            * dfg/DFGNodeType.h:
-            * tests/stress/capture-escape-and-throw.js: Added.
-            (foo.f):
-            (foo):
-            * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
-            (foo):
-            (bar):
-
-2014-07-17  Dean Jackson  <dino@apple.com>
-
-        <rdar://problem/17675068> Disable some features on this branch.
-
-        Reviewed originally by Simon Fraser.
-
-        Disable:
-        - CSS_EXCLUSIONS
-        - CSS_GRID_LAYOUT
-        - INPUT_TYPE_COLOR
-        - INPUT_TYPE_COLOR_POPUP
-        - CANVAS_PATH
-        - CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED
-        - INDIE_UI
-        - SHARED_WORKERS
-        - NAVIGATOR_HWCONCURRENCY
-        - GAMEPAD
-        - PICTURE_SIZES
-        - CSS3_CONDITIONAL_RULES
-        - WILL_REVEAL_EDGE_EVENTS
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-07-15  Benjamin Poulain  <benjamin@webkit.org>
-
-        Reduce the overhead of updating the AssemblerBuffer
-        https://bugs.webkit.org/show_bug.cgi?id=134659
-
-        Reviewed by Gavin Barraclough.
-
-        In r164548, the linker was changed to allow the LinkBuffer to survive its MacroAssembler.
-        That feature is useful for JSC to get offsets inside a linked buffer in order to jump directly
-        there.
-
-        On ARM, we use branch compaction and we need to keep the "compaction offset" somewher to be able
-        to get the real address of a lable. That is done by reusing the memory of AssemblerData.
-
-        To share the memory between LinkBuffer and the Assembler, r164548 moved the AssemblerData into
-        a ref-counted object. Unfortunately, the extra complexity related to the new AssemblerData was enough
-        to make clang give up a bunch of optimizations.
-
-        This patch solve (some of) the problems by making AssemblerBuffer and AssemblerData super low overhead structures.
-        In particular, the grow() function becomes 8 Thumb instructions, which is easily inlined everywhere it is used.
-
-        Instead of sharing ownership between the Assembler and LinkBuffer, LinkBuffer now takes full ownership of
-        the AssemblerData. I feel this is also safer since LinkBuffer is reusing the AssemblerData is a very
-        specific way that would make it unusable for the Assembler.
-
-        -- Technical details --
-
-        From LinkBuffer, we don't want to ever access the Assembler after releasing its buffer (or writting anything
-        into it really). This was obviously already the case, but that was hard to prove from LinkBuffer::copyCompactAndLinkCode().
-        To make this easier to work with, I changed all the assembler specific function to be static. This way we know
-        exactly what code access the Assembler instance. The code that does access the instance is then moved
-        at the beginning, before we modify anything.
-
-        The function recordLinkOffsets() that was on the MacroAssembler and copied in Assembler was moved directly
-        to LinkBuffer. This make the modification of AssemblerData completely explicit, and that code is specific
-        to LinkBuffer anyway (see LinkBuffer::executableOffsetFor()).
-
-        -- Perf impact --
-
-        This does not put us exactly at before r164548 due to the missing inline buffer. Still, it is very close.
-        On ARMv7, this reduces the time spent in Assembler by half. On the CSS JIT, this reduces the compilation
-        time by ~20%.
-
-        I could not measure any difference on x86_64.
-
-        * assembler/ARM64Assembler.h:
-        (JSC::ARM64Assembler::jumpSizeDelta):
-        (JSC::ARM64Assembler::canCompact):
-        (JSC::ARM64Assembler::computeJumpType):
-        (JSC::ARM64Assembler::link):
-        (JSC::ARM64Assembler::recordLinkOffsets): Deleted.
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::ifThenElseConditionBit):
-        (JSC::ARMv7Assembler::ifThenElse):
-        (JSC::ARMv7Assembler::jumpSizeDelta):
-        (JSC::ARMv7Assembler::canCompact):
-        (JSC::ARMv7Assembler::computeJumpType):
-        (JSC::ARMv7Assembler::link):
-        (JSC::ARMv7Assembler::linkJumpT1):
-        (JSC::ARMv7Assembler::linkJumpT3):
-        (JSC::ARMv7Assembler::linkConditionalJumpT4):
-        (JSC::ARMv7Assembler::linkConditionalBX):
-        (JSC::ARMv7Assembler::recordLinkOffsets): Deleted.
-        * assembler/AssemblerBuffer.h:
-        (JSC::AssemblerData::AssemblerData):
-        (JSC::AssemblerData::operator=):
-        (JSC::AssemblerData::~AssemblerData):
-        (JSC::AssemblerData::buffer):
-        (JSC::AssemblerData::capacity):
-        (JSC::AssemblerData::grow):
-        (JSC::AssemblerBuffer::AssemblerBuffer):
-        (JSC::AssemblerBuffer::isAvailable):
-        (JSC::AssemblerBuffer::data):
-        (JSC::AssemblerBuffer::releaseAssemblerData):
-        (JSC::AssemblerBuffer::putIntegral):
-        (JSC::AssemblerBuffer::putIntegralUnchecked):
-        (JSC::AssemblerBuffer::append):
-        (JSC::AssemblerBuffer::grow):
-        (JSC::AssemblerBuffer::~AssemblerBuffer): Deleted.
-        (JSC::AssemblerBuffer::storage): Deleted.
-        * assembler/LinkBuffer.cpp:
-        (JSC::recordLinkOffsets):
-        (JSC::LinkBuffer::copyCompactAndLinkCode):
-        * assembler/LinkBuffer.h:
-        (JSC::LinkBuffer::LinkBuffer):
-        (JSC::LinkBuffer::executableOffsetFor):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::canCompact):
-        (JSC::MacroAssemblerARM64::computeJumpType):
-        (JSC::MacroAssemblerARM64::jumpSizeDelta):
-        (JSC::MacroAssemblerARM64::link):
-        (JSC::MacroAssemblerARM64::recordLinkOffsets): Deleted.
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::canCompact):
-        (JSC::MacroAssemblerARMv7::computeJumpType):
-        (JSC::MacroAssemblerARMv7::jumpSizeDelta):
-        (JSC::MacroAssemblerARMv7::link):
-        (JSC::MacroAssemblerARMv7::recordLinkOffsets): Deleted.
-
-2014-07-15  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Stores to PropertyTable use the Structure as the owner
-        https://bugs.webkit.org/show_bug.cgi?id=134595
-
-        Reviewed by Darin Adler.
-
-        Since PropertyTable is the object that does the marking of these references, it should be the owner.
-
-        Also removed some unused parameters to other methods that historically used the Structure as the owner.
-
-        * runtime/JSPropertyNameIterator.h:
-        (JSC::StructureRareData::setEnumerationCache):
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncToString):
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::copy):
-        * runtime/PropertyTable.cpp:
-        (JSC::PropertyTable::clone):
-        (JSC::PropertyTable::PropertyTable):
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::materializePropertyMap):
-        (JSC::Structure::addPropertyTransition):
-        (JSC::Structure::changePrototypeTransition):
-        (JSC::Structure::despecifyFunctionTransition):
-        (JSC::Structure::attributeChangeTransition):
-        (JSC::Structure::toDictionaryTransition):
-        (JSC::Structure::preventExtensionsTransition):
-        (JSC::Structure::takePropertyTableOrCloneIfPinned):
-        (JSC::Structure::nonPropertyTransition):
-        (JSC::Structure::copyPropertyTable):
-        (JSC::Structure::copyPropertyTableForPinning):
-        (JSC::Structure::putSpecificValue):
-        * runtime/Structure.h:
-        (JSC::Structure::setObjectToStringValue):
-        (JSC::Structure::setPreviousID):
-        * runtime/StructureInlines.h:
-        (JSC::Structure::setEnumerationCache):
-        * runtime/StructureRareData.h:
-        * runtime/StructureRareDataInlines.h:
-        (JSC::StructureRareData::setPreviousID):
-        (JSC::StructureRareData::setObjectToStringValue):
-
-2014-07-15  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        ScriptExecutable::forEachCodeBlock can dereference null CodeBlocks
-        https://bugs.webkit.org/show_bug.cgi?id=134928
-
-        Reviewed by Andreas Kling.
-
-        * bytecode/CodeBlock.h:
-        (JSC::ScriptExecutable::forEachCodeBlock): Check for null CodeBlocks before calling forEachRelatedCodeBlock.
-
-2014-07-15  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        Buildfix if LLINT_SLOW_PATH_TRACING is enabled
-        https://bugs.webkit.org/show_bug.cgi?id=133790
-
-        Reviewed by Mark Lam.
-
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-
-2014-07-14  Filip Pizlo  <fpizlo@apple.com>
-
-        Allow for Int52Rep to see things other than Int32, and make this testable
-        https://bugs.webkit.org/show_bug.cgi?id=134873
-        <rdar://problem/17641915>
-
-        Reviewed by Geoffrey Garen and Mark Hahnenberg.
-        
-        A major premise of our type inference is that prediction propagation can say whatever it
-        wants and we'll still have valid IR after Fixup. This previously didn't work with Int52s.
-        We required some kind of agreement between prediction propagation and fixup over which
-        data flow paths were Int52 and which weren't.
-        
-        It turns out that we basically had such an agreement, with the exception of code that was
-        unreachable due to ForceOSRExit. Then, fixup and prediction propagation would disagree. It
-        might be nice to fix that bug - but it's only in the case of Int52 that such a thing would
-        be a bug! Normally, we allow sloppiness in prediction propagation.
-        
-        This patch allows us to be sloppy with Int52 prediction propagation by giving Int52Rep the
-        ability to see inputs other than Int32. This fixes the particular ForceOSRExit bug (see
-        int52-force-osr-exit-path.js for the reduced test case). To make sure that the newly
-        empowered Int52Rep is actually correct - in case we end up using it on paths other than
-        ForceOSRExit - this patch introduces an internal intrinsic called fiatInt52() that forces
-        us to attempt Int52 conversion on the input. This patch adds a bunch of tests that stress
-        this intrinsic. This means that we're now stressing Int52Rep more so than ever before!
-        
-        Note that it would still be a bug for prediction propagation to ever cause us to create an
-        Int52Rep node for a non-Int32 input. But, this will now be a performance bug, rather than
-        a crash bug.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGAbstractValue.cpp:
-        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-        * dfg/DFGGraph.h:
-        (JSC::DFG::Graph::isMachineIntConstant):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::isMachineIntConstant):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGOperations.cpp:
-        * dfg/DFGOperations.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::speculate):
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::callOperation):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::convertMachineInt):
-        (JSC::DFG::SpeculativeJIT::speculateMachineInt):
-        (JSC::DFG::SpeculativeJIT::speculateDoubleRepMachineInt):
-        * dfg/DFGStrengthReductionPhase.cpp:
-        (JSC::DFG::StrengthReductionPhase::handleNode):
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        (JSC::DFG::isNumerical):
-        (JSC::DFG::isDouble):
-        * dfg/DFGValidate.cpp:
-        (JSC::DFG::Validate::validate):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
-        (JSC::FTL::LowerDFGToLLVM::doubleToInt32):
-        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
-        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
-        (JSC::FTL::LowerDFGToLLVM::doubleToStrictInt52):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt):
-        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepMachineInt):
-        * jit/JITOperations.h:
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionIdentity):
-        * runtime/Intrinsic.h:
-        * runtime/JSCJSValue.h:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::tryConvertToInt52):
-        (JSC::isInt52):
-        (JSC::JSValue::isMachineInt):
-        * tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js: Added.
-        (foo):
-        * tests/stress/dead-fiat-double-to-int52.js: Added.
-        (foo):
-        * tests/stress/dead-fiat-int32-to-int52.js: Added.
-        (foo):
-        * tests/stress/dead-fiat-value-to-int52-double-path.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/dead-fiat-value-to-int52.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/fiat-double-to-int52-then-exit-not-int52.js: Added.
-        (foo):
-        * tests/stress/fiat-double-to-int52-then-fail-to-fold.js: Added.
-        (foo):
-        * tests/stress/fiat-double-to-int52-then-fold.js: Added.
-        (foo):
-        * tests/stress/fiat-double-to-int52.js: Added.
-        (foo):
-        * tests/stress/fiat-int32-to-int52.js: Added.
-        (foo):
-        * tests/stress/fiat-value-to-int52-double-path.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/fiat-value-to-int52-then-exit-not-double.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/fiat-value-to-int52-then-exit-not-int52.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/fiat-value-to-int52-then-fail-to-fold.js: Added.
-        (foo):
-        * tests/stress/fiat-value-to-int52-then-fold.js: Added.
-        (foo):
-        * tests/stress/fiat-value-to-int52.js: Added.
-        (foo):
-        (bar):
-        * tests/stress/int52-force-osr-exit-path.js: Added.
-        (foo):
-
-2014-07-14  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Flattening dictionaries with oversize backing stores can cause crashes
-        https://bugs.webkit.org/show_bug.cgi?id=134906
-
-        Reviewed by Filip Pizlo.
-
-        The collector expects any pointers into CopiedSpace passed to copyLater are within 32 KB 
-        of the CopiedBlock header. This was always the case except for when flattening a dictionary 
-        caused the size of the Butterfly to decrease. This was equivalent to moving the base of the 
-        Butterfly to higher addresses. If the object was reduced sufficiently in size, the base 
-        would no longer be within the first 32 KB of the CopiedBlock and the next collection would 
-        choke on the Butterfly pointer.
-
-        This patch fixes this issue by detect this situation during flattening and memmove-ing 
-        the Butterfly down to where the old base was.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::shiftButterflyAfterFlattening):
-        * runtime/JSObject.h:
-        (JSC::JSObject::butterflyPreCapacity):
-        (JSC::JSObject::butterflyTotalSize):
-        * runtime/Structure.cpp:
-        (JSC::Structure::flattenDictionaryStructure):
-        * tests/stress/flatten-oversize-dictionary-object.js: Added.
-        (foo):
-
-2014-07-14  Benjamin Poulain  <benjamin@webkit.org>
-
-        Remove some dead code from FTLJITFinalizer
-        https://bugs.webkit.org/show_bug.cgi?id=134874
-
-        Reviewed by Geoffrey Garen.
-
-        Not sure what that code was for...but it does not do anything :)
-
-        * ftl/FTLJITFinalizer.cpp:
-        (JSC::FTL::JITFinalizer::finalizeFunction):
-        The pointer of the label is computed but never used.
-
-        * ftl/FTLJITFinalizer.h:
-        * ftl/FTLLink.cpp:
-        (JSC::FTL::link):
-        The label is never set to anything.
-
-2014-07-14  Bear Travis  <betravis@adobe.com>
-
-        [Feature Queries] Enable Feature Queries on Mac
-        https://bugs.webkit.org/show_bug.cgi?id=134404
-
-        Reviewed by Antti Koivisto.
-
-        Enable Feature Queries on Mac and resume running the
-        feature tests.
-
-        * Configurations/FeatureDefines.xcconfig: Turn on
-        ENABLE_CSS3_CONDITIONAL_RULES.
-
-2014-07-11  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Debugger Pause button does not work
-        https://bugs.webkit.org/show_bug.cgi?id=134785
-
-        Reviewed by Timothy Hatcher.
-
-        * CMakeLists.txt:
-        * DerivedSources.make:
-        Minification strips the sourceURL command. Add it back with minification.
-
-2014-07-11  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win] Enable DFG JIT.
-        https://bugs.webkit.org/show_bug.cgi?id=123615
-
-        Reviewed by Mark Lam.
-
-        When the return type of a JIT generated function call is larger than 64-bit (e.g. SlowPathReturnType),
-        the normal call() implementation cannot be used on 64-bit Windows, because the 64-bit Windows ABI is different in this case.
-        Also, when generating calls with double arguments, we need to make sure the arguments are put in the correct registers,
-        since the register allocation differs on 64-bit Windows.
-
-        * assembler/MacroAssemblerX86_64.h:
-        (JSC::MacroAssemblerX86_64::callWithSlowPathReturnType): Added method to handle function calls where the return value type size is larger than 64-bit.
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState): Move arguments to correct registers when there are floating point arguments.
-        (JSC::CCallHelpers::setupArgumentsWithExecStateForCallWithSlowPathReturnType): Added method.
-        * jit/JIT.h:
-        (JSC::JIT::appendCallWithSlowPathReturnType): Added method.
-        * jit/JITInlines.h:
-        (JSC::JIT::appendCallWithExceptionCheckAndSlowPathReturnType): Added method.
-        (JSC::JIT::callOperation): Call new method.
-
-2014-07-09  Benjamin Poulain  <benjamin@webkit.org>
-
-        Use 16bits instructions for push/pop on ARMv7 when possible
-        https://bugs.webkit.org/show_bug.cgi?id=134753
-
-        Reviewed by Geoffrey Garen.
-
-        The patch r170839 mixed the code for push/pop pair and single push/pop.
-        That part was reverted in r170909.
-
-        This patch puts the code back but specialized for single push/pop.
-
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::pop):
-        (JSC::ARMv7Assembler::push):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::pop):
-        (JSC::MacroAssemblerARMv7::push):
-
-2014-07-09  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Remove uses of 'bash' in build system
-        https://bugs.webkit.org/show_bug.cgi?id=134782
-        <rdar://problem/17615533>
-
-        Reviewed by Dean Jackson.
-
-        Remove uses of 'bash' by replacing Windows-specific bash scripts
-        with Perl equivalents.
-
-        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make:
-        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters:
-        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd:
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make:
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj:
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh.
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Removed.
-        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make:
-        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj:
-        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh.
-        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Removed.
-        * JavaScriptCore.vcxproj/build-generated-files.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/build-generated-files.sh.
-        * JavaScriptCore.vcxproj/build-generated-files.sh: Removed.
-        * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd:
-        * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd:
-        * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd:
-
-2014-07-09  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Remove use of 'grep' in build steps
-        https://bugs.webkit.org/show_bug.cgi?id=134770
-        <rdar://problem/17608783>
-
-        Reviewed by Tim Horton.
-
-        Replace uses of the grep command in Windows builds with the equivalent
-        Perl program.
-
-        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd:
-        * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd:
-        * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd:
-        * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd:
-
-2014-07-08  Benjamin Poulain  <benjamin@webkit.org>
-
-        Restore the assertion changed with 170839
-
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::pop):
-        (JSC::ARMv7Assembler::push):
-        Revert the Assembler part of 170839. The assertions do not match both encoding.
-
-        I'll add specific version of push and pop instead.
-
-2014-07-08  Jon Honeycutt  <jhoneycutt@apple.com>
-
-        RemoteInspector::shared() should not call WTF::initializeMainThread()
-        <https://bugs.webkit.org/show_bug.cgi?id=134747>
-        <rdar://problem/17161482>
-
-        Reviewed by Joseph Pecoraro.
-
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::shared):
-        Don't call WTF::initializeMainThread(). WTF threading is initialized by
-        JSC::initializeThreading().
-
-2014-07-08  Andreas Kling  <akling@apple.com>
-
-        VM::lastCachedString should be a Strong, not a Weak.
-        <https://webkit.org/b/134746>
-
-        Using Weak<JSString> for this regressed some of our bindings perf tests
-        due to Weak having to allocate a new WeakImpl every time the last cached
-        string changed. Make it a Strong instead should make that problem go away.
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/JSString.cpp:
-        (JSC::jsStringWithCacheSlowCase):
-        * runtime/VM.h:
-
-2014-07-07  Benjamin Poulain  <bpoulain@apple.com>
-
-        Fix the build after r170876
-
-        * assembler/LinkBuffer.cpp:
-        (JSC::LinkBuffer::linkCode):
-
-2014-07-07  Benjamin Poulain  <benjamin@webkit.org>
-
-        LinkBuffer should not keep a reference to the MacroAssembler
-        https://bugs.webkit.org/show_bug.cgi?id=134668
-
-        Reviewed by Geoffrey Garen.
-
-        In FTL, the LinkBuffer can outlive the MacroAssembler that was used for code generation.
-        When that happens, the pointer m_assembler points to released memory. That was not causing
-        issues because the attribute is not used after linking, but that was not particularily
-        future proof.
-
-        This patch refactors LinkBuffer to avoid any lifetime risk. The MacroAssembler is now passed
-        as a reference, it is used for linking but no reference is ever stored with the LinkBuffer.
-
-        While fixing the call sites to use a reference, I also discovered LinkBuffer.h was included
-        everywhere. I refactored some #include to avoid that.
-
-        * assembler/LinkBuffer.cpp:
-        (JSC::LinkBuffer::copyCompactAndLinkCode):
-        (JSC::LinkBuffer::linkCode):
-        * assembler/LinkBuffer.h:
-        (JSC::LinkBuffer::LinkBuffer):
-        * bytecode/Watchpoint.cpp:
-        * dfg/DFGDisassembler.cpp:
-        * dfg/DFGDisassembler.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::link):
-        (JSC::DFG::JITCompiler::linkFunction):
-        * dfg/DFGOSRExitCompiler.cpp:
-        * dfg/DFGPlan.cpp:
-        * dfg/DFGThunks.cpp:
-        (JSC::DFG::osrExitGenerationThunkGenerator):
-        (JSC::DFG::osrEntryThunkGenerator):
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::generateICFastPath):
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        * ftl/FTLJSCall.cpp:
-        * ftl/FTLJSCall.h:
-        * ftl/FTLLink.cpp:
-        (JSC::FTL::link):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub):
-        * ftl/FTLThunks.cpp:
-        (JSC::FTL::osrExitGenerationThunkGenerator):
-        (JSC::FTL::slowPathCallThunkGenerator):
-        * jit/ArityCheckFailReturnThunks.cpp:
-        (JSC::ArityCheckFailReturnThunks::returnPCsFor):
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompile):
-        * jit/JITCall.cpp:
-        (JSC::JIT::privateCompileClosureCall):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::privateCompileClosureCall):
-        * jit/JITDisassembler.cpp:
-        * jit/JITDisassembler.h:
-        * jit/JITOpcodes.cpp:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::stringGetByValStubGenerator):
-        (JSC::JIT::privateCompileGetByVal):
-        (JSC::JIT::privateCompilePutByVal):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::stringGetByValStubGenerator):
-        * jit/RegisterPreservationWrapperGenerator.cpp:
-        (JSC::generateRegisterPreservationWrapper):
-        (JSC::registerRestorationThunkGenerator):
-        * jit/Repatch.cpp:
-        (JSC::generateByIdStub):
-        (JSC::tryCacheGetByID):
-        (JSC::emitPutReplaceStub):
-        (JSC::emitPutTransitionStub):
-        (JSC::tryRepatchIn):
-        (JSC::linkClosureCall):
-        * jit/SpecializedThunkJIT.h:
-        (JSC::SpecializedThunkJIT::finalize):
-        * jit/ThunkGenerators.cpp:
-        (JSC::throwExceptionFromCallSlowPathGenerator):
-        (JSC::linkForThunkGenerator):
-        (JSC::linkClosureCallForThunkGenerator):
-        (JSC::virtualForThunkGenerator):
-        (JSC::nativeForGenerator):
-        (JSC::arityFixup):
-        * llint/LLIntThunks.cpp:
-        (JSC::LLInt::generateThunkWithJumpTo):
-        * yarr/YarrJIT.cpp:
-        (JSC::Yarr::YarrGenerator::compile):
-
-2014-07-07  Andreas Kling  <akling@apple.com>
-
-        Fast path for jsStringWithCache() when asked for the same string repeatedly.
-        <https://webkit.org/b/134635>
-
-        Reviewed by Darin Adler.
-
-        Follow-up to r170818 addressing a review comment by Geoff Garen.
-
-        * runtime/JSString.cpp:
-        (JSC::jsStringWithCacheSlowCase):
-
-2014-07-07  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Add missing ENABLE(FTL_JIT) guards
-        https://bugs.webkit.org/show_bug.cgi?id=134680
-
-        Reviewed by Darin Adler.
-
-        * ftl/FTLDWARFDebugLineInfo.cpp:
-        * ftl/FTLDWARFDebugLineInfo.h:
-        * ftl/FTLGeneratedFunction.h:
-
-2014-07-07  Zan Dobersek  <zdobersek@igalia.com>
-
-        Enable ARMv7 disassembler for the GTK port
-        https://bugs.webkit.org/show_bug.cgi?id=134676
-
-        Reviewed by Benjamin Poulain.
-
-        * CMakeLists.txt: Add ARMv7DOpcode.cpp file to the build.
-        * disassembler/ARMv7/ARMv7DOpcode.cpp: Include the string.h header for strlen().
-
-2014-07-06  Benjamin Poulain  <benjamin@webkit.org>
-
-        [ARMv7] Use 16 bits instructions for push/pop when possible
-        https://bugs.webkit.org/show_bug.cgi?id=134656
-
-        Reviewed by Andreas Kling.
-
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::pop):
-        (JSC::ARMv7Assembler::push):
-        (JSC::ARMv7Assembler::ARMInstructionFormatter::oneWordOp7Imm9):
-        Add the 16 bits version of push and pop.
-
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::pop):
-        (JSC::MacroAssemblerARMv7::push):
-        Use the new push/pop instead of a regular load/store.
-
-        * disassembler/ARMv7/ARMv7DOpcode.cpp:
-        (JSC::ARMv7Disassembler::ARMv7DOpcode::appendRegisterList):
-        * disassembler/ARMv7/ARMv7DOpcode.h:
-        (JSC::ARMv7Disassembler::ARMv7DOpcodeMiscPushPop::registerMask):
-        Fix the disassembler for push/pop:
-        -The register mask was on 7 bits for some reason.
-        -The code printing the registers was comparing a register ID with a register
-         mask.
-
-2014-07-06  Yoav Weiss  <yoav@yoav.ws>
-
-        Turn on img@sizes compile flag
-        https://bugs.webkit.org/show_bug.cgi?id=134634
-
-        Reviewed by Benjamin Poulain.
-
-        * Configurations/FeatureDefines.xcconfig: Moved compile flag to alphabetical order.
-
-2014-07-06  Daewoong Jang  <daewoong.jang@navercorp.com>
-
-        Flags value of SourceCodeKey should be unique for each case.
-        https://bugs.webkit.org/show_bug.cgi?id=134435
-
-        Reviewed by Darin Adler.
-
-        Different combinations of CodeType and JSParserStrictness could generate same m_flags value because
-        the value of CodeType and the value of JSParserStrictness shares a bit inside m_flags member variable.
-        Shift the value of CodeType one bit farther to the left so those values don't overlap.
-
-        * runtime/CodeCache.h:
-        (JSC::SourceCodeKey::SourceCodeKey):
-
-2014-07-04  Andreas Kling  <akling@apple.com>
-
-        Fast path for jsStringWithCache() when asked for the same string repeatedly.
-        <https://webkit.org/b/134635>
-
-        Also moved the whole thing from WebCore to JavaScriptCore since it
-        makes more sense here, and inline the lightweight checks, leaving only
-        the hashmap stuff out of line.
-
-        Reviewed by Darin Adler.
-
-        * runtime/JSString.cpp:
-        (JSC::jsStringWithCacheSlowCase):
-        * runtime/JSString.h:
-        (JSC::jsStringWithCache):
-        * runtime/VM.h:
-
-2014-07-03  Daniel Bates  <dabates@apple.com>
-
-        Add WTF::move()
-        https://bugs.webkit.org/show_bug.cgi?id=134500
-
-        Rubber-stamped by Anders Carlsson.
-
-        Substitute WTF::move() for std::move().
-
-        * bytecode/CodeBlock.h:
-        * bytecode/UnlinkedCodeBlock.cpp:
-        * bytecompiler/BytecodeGenerator.cpp:
-        * dfg/DFGGraph.cpp:
-        * dfg/DFGJITCompiler.cpp:
-        * dfg/DFGStackLayoutPhase.cpp:
-        * dfg/DFGWorklist.cpp:
-        * heap/DelayedReleaseScope.h:
-        * heap/HeapInlines.h:
-        [...]
-
-2014-07-03  Filip Pizlo  <fpizlo@apple.com>
-
-        SSA DCE should process blocks in forward order
-        https://bugs.webkit.org/show_bug.cgi?id=134611
-
-        Reviewed by Andreas Kling.
-
-        * dfg/DFGDCEPhase.cpp:
-        (JSC::DFG::DCEPhase::run):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
-        * tests/stress/dead-value-with-mov-hint-in-another-block.js: Added.
-        (foo):
-
-2014-07-03  Filip Pizlo  <fpizlo@apple.com>
-
-        JSActivation::symbolTablePut() should invalidate variable watchpoints
-        https://bugs.webkit.org/show_bug.cgi?id=134602
-
-        Reviewed by Oliver Hunt.
-        
-        Usually stores to captured variables cause us to invalidate the variable watchpoint because CodeBlock does so
-        during linking - we essentially assume that if it's at all possible for an inner function to store to a
-        variable we declare then this variable cannot be a constant. But this misses the dynamic store case, i.e.
-        JSActivation::symbolTablePut(). Part of the problem here is that JSActivation duplicates
-        JSSymbolTableObject's symbolTablePut() logic, which did have the invalidation. This patch keeps that code
-        duplicated, but fixes JSActivation::symbolTablePut() to do the right thing.
-
-        * runtime/JSActivation.cpp:
-        (JSC::JSActivation::symbolTablePut):
-        * runtime/JSSymbolTableObject.h:
-        (JSC::symbolTablePut):
-        * tests/stress/constant-closure-var-with-dynamic-invalidation.js: Added.
-        (.):
-
-2014-07-01  Mark Lam  <mark.lam@apple.com>
-
-        Debugger's breakpoint list should not be a Vector.
-        <https://webkit.org/b/134514>
-
-        Reviewed by Geoffrey Garen.
-
-        The debugger currently stores breakpoint data as entries in a Vector (see
-        BreakpointsInLine).  It also keeps a fast map look up of breakpoint IDs to
-        the breakpoint data (see m_breakpointIDToBreakpoint).  Because a Vector can
-        compact or reallocate its backing store, this can causes all sorts of havoc.
-        The m_breakpointIDToBreakpoint map assumes that the breakpoint data doesn't
-        move in memory.
-
-        The fix is to replace the BreakpointsInLine Vector with a BreakpointsList
-        doubly linked list.
-
-        * debugger/Breakpoint.h:
-        (JSC::Breakpoint::Breakpoint):
-        (JSC::BreakpointsList::~BreakpointsList):
-        * debugger/Debugger.cpp:
-        (JSC::Debugger::setBreakpoint):
-        (JSC::Debugger::removeBreakpoint):
-        (JSC::Debugger::hasBreakpoint):
-        * debugger/Debugger.h:
-
-2014-06-30  Michael Saboff  <msaboff@apple.com>
-
-        Add option to run-jsc-stress-testes to filter out tests that use large heaps
-        https://bugs.webkit.org/show_bug.cgi?id=134458
-
-        Reviewed by Filip Pizlo.
-
-        Added test to skip js1_5/Regress/regress-159334.js when testing on a memory limited device.
-
-        * tests/mozilla/mozilla-tests.yaml:
-
-2014-06-30  Daniel Bates  <dabates@apple.com>
-
-        Avoid copying closed variables vector; actually use move semantics
-
-        Rubber-stamped by Oliver Hunt.
-
-        Currently we always copy the closed variables vector passed by Parser::closedVariables()
-        to ProgramNode::setClosedVariables() because these member functions return and take a const
-        rvalue reference, respectively. Instead, these member functions should take an return a non-
-        constant rvalue reference so that we actually move the closed variables vector from the Parser
-        object to the Node object.
-
-        * parser/Nodes.cpp:
-        (JSC::ProgramNode::setClosedVariables): Remove const qualifier for argument.
-        * parser/Nodes.h:
-        (JSC::ScopeNode::setClosedVariables): Ditto.
-        * parser/Parser.h:
-        (JSC::Parser::closedVariables): Remove const qualifier on return type.
-        (JSC::parse): Remove extraneous call to std::move(). Calling std::move() is unnecessary here
-        because Parser::closedVariables() returns an rvalue reference.
-
-2014-06-30  Joseph Pecoraro  <pecoraro@apple.com>
-
-        JSContext Inspection: Provide a way to use a non-Main RunLoop for Inspector JavaScript Evaluations
-        https://bugs.webkit.org/show_bug.cgi?id=134371
-
-        Reviewed by Timothy Hatcher.
-
-        * API/JSContextPrivate.h:
-        * API/JSContext.mm:
-        (-[JSContext _debuggerRunLoop]):
-        (-[JSContext _setDebuggerRunLoop:]):
-        Private API for setting the CFRunLoop for a debugger to evaluate in.
-        
-        * API/JSContextRefInternal.h: Added.
-        * API/JSContextRef.cpp:
-        (JSGlobalContextGetDebuggerRunLoop):
-        (JSGlobalContextSetDebuggerRunLoop):
-        Internal API for setting a CFRunLoop on a JSContextRef.
-        Set this on the debuggable.
-        
-        * inspector/remote/RemoteInspectorDebuggable.h:
-        * inspector/remote/RemoteInspectorDebuggableConnection.h:
-        (Inspector::RemoteInspectorBlock::RemoteInspectorBlock):
-        (Inspector::RemoteInspectorBlock::~RemoteInspectorBlock):
-        (Inspector::RemoteInspectorBlock::operator=):
-        (Inspector::RemoteInspectorBlock::operator()):
-        Moved into the header.
-
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::inspectorDebuggable):
-        Lets store the RunLoop on the debuggable instead of this core
-        platform agnostic class, so expose the debuggable.
-
-        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
-        (Inspector::RemoteInspectorHandleRunSourceGlobal):
-        (Inspector::RemoteInspectorQueueTaskOnGlobalQueue):
-        (Inspector::RemoteInspectorInitializeGlobalQueue):
-        Rename the global functions for clarity.
-
-        (Inspector::RemoteInspectorHandleRunSourceWithInfo):
-        Handler for private run loops.
-
-        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
-        (Inspector::RemoteInspectorDebuggableConnection::~RemoteInspectorDebuggableConnection):
-        (Inspector::RemoteInspectorDebuggableConnection::dispatchAsyncOnDebuggable):
-        (Inspector::RemoteInspectorDebuggableConnection::setupRunLoop):
-        (Inspector::RemoteInspectorDebuggableConnection::teardownRunLoop):
-        (Inspector::RemoteInspectorDebuggableConnection::queueTaskOnPrivateRunLoop):
-        Setup and teardown and use private run loop sources if the debuggable needs it.
-
-2014-06-30  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Add missing ENABLE(DFG_JIT) guards
-        https://bugs.webkit.org/show_bug.cgi?id=134444
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGFunctionWhitelist.cpp:
-        * dfg/DFGFunctionWhitelist.h:
-
-2014-06-29  Yoav Weiss  <yoav@yoav.ws>
-
-        Add support for HTMLImageElement's sizes attribute
-        https://bugs.webkit.org/show_bug.cgi?id=133620
-
-        Reviewed by Dean Jackson.
-
-        Added an ENABLE_PICTURE_SIZES compile flag.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-06-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Don't fold a UInt32ToNumber with DoOverflow to Identity since that would result in an Identity that takes an Int32 and returns a DoubleRep
-        https://bugs.webkit.org/show_bug.cgi?id=134412
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::setReplacement):
-        * dfg/DFGStrengthReductionPhase.cpp:
-        (JSC::DFG::StrengthReductionPhase::handleNode):
-        * dfg/DFGValidate.cpp:
-        (JSC::DFG::Validate::validate):
-        * tests/stress/uint32-to-number-fold-constant-with-do-overflow.js: Added.
-        (foo):
-        (bar):
-        (baz):
-
-2014-06-27  Peyton Randolph  <prandolph@apple.com>
-
-         Add feature flag for link long-press gesture.                                                                   
-         https://bugs.webkit.org/show_bug.cgi?id=134262                                                                  
-                                                                                                                         
-         Reviewed by Enrica Casucci.                                                                                     
-                                                                                                                         
-         * Configurations/FeatureDefines.xcconfig:                                                                       
-         Add ENABLE_LINK_LONG_PRESS. 
-
-2014-06-27  László Langó  <llango.u-szeged@partner.samsung.com>
-
-        [JavaScriptCore] FTL buildfix for EFL platform.
-        https://bugs.webkit.org/show_bug.cgi?id=133546
-
-        Reviewed by Darin Adler.
-
-        * ftl/FTLAbstractHeap.cpp:
-        (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::forStackmaps):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::opposite):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub):
-        * ftl/FTLStackMaps.cpp:
-        (JSC::FTL::StackMaps::Constant::dump):
-        * llvm/InitializeLLVMPOSIX.cpp:
-        (JSC::initializeLLVMPOSIX):
-
-2014-06-26  Benjamin Poulain  <benjamin@webkit.org>
-
-        iOS 8 beta 2 ES6 'Set' clear() broken
-        https://bugs.webkit.org/show_bug.cgi?id=134346
-
-        Reviewed by Oliver Hunt.
-
-        The object map was not cleared :(.
-
-        Kudos to Ashley Gullen for tracking this and making a regression test.
-        Credit to Oliver for finding the missing code.
-
-        * runtime/MapData.h:
-        (JSC::MapData::clear):
-
-2014-06-25  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Expose Cache Information to WinLauncher
-        https://bugs.webkit.org/show_bug.cgi?id=134318
-
-        Reviewed by Dean Jackson.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add missing
-        MemoryStatistics files to the WIndows build.
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-
-2014-06-26  David Kilzer  <ddkilzer@apple.com>
-
-        DFG::FunctionWhitelist::parseFunctionNamesInFile does not close file
-        <http://webkit.org/b/134343>
-        <rdar://problem/17459487>
-
-        Reviewed by Michael Saboff.
-
-        * dfg/DFGFunctionWhitelist.cpp:
-        (JSC::DFG::FunctionWhitelist::parseFunctionNamesInFile):
-        Close the file handle, and log an error on failure.
-
-2014-06-25  Dana Burkart  <dburkart@apple.com>
-
-        Add support for 5-tuple versioning.
-
-        Reviewed by David Farler.
-
-        * Configurations/Version.xcconfig:
-
-2014-06-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix.
-
-        Unreviewed.
-
-        * runtime/JSDateMath.cpp:
-        (JSC::parseDateFromNullTerminatedCharacters):
-        * runtime/VM.cpp:
-        (JSC::VM::resetDateCache): Use std::numeric_limits instead of QNaN
-        constant since that constant doesn't exist anymore.
-
-2014-06-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Unreviewed, rolling out r166876.
-
-        Caused some ECMA test262 failures
-
-        Reverted changeset:
-
-        "Date object needs to check for ES5 15.9.1.14 TimeClip limit."
-        https://bugs.webkit.org/show_bug.cgi?id=131248
-        http://trac.webkit.org/changeset/166876
-
-2014-06-25  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Unreviewed gardening.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Update to
-        put various files in proper IDE categories.
-
-2014-06-25  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win64] ASM LLINT is not enabled.
-        https://bugs.webkit.org/show_bug.cgi?id=130638
-
-        This patch adds a new LLINT assembler backend for Win64, and implements it.
-        It makes adjustments to follow the Win64 ABI spec. where it's found to be needed.
-        Also, LLINT and JIT is enabled for Win64.
-
-        Reviewed by Mark Lam.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Added JITStubsMSVC64.asm.
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
-        * JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props: Increased stack size to avoid stack overflow in tests.
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Generate assembler source file for Win64.
-        * assembler/MacroAssemblerX86_64.h: 
-        (JSC::MacroAssemblerX86_64::call): Follow Win64 ABI spec.
-        * jit/JITStubsMSVC64.asm: Added.
-        * jit/Repatch.cpp:
-        (JSC::emitPutTransitionStub): Compile fix.
-        * jit/ThunkGenerators.cpp:
-        (JSC::nativeForGenerator): Follow Win64 ABI spec.
-        * llint/LLIntData.cpp:
-        (JSC::LLInt::Data::performAssertions): Ditto.
-        * llint/LLIntOfflineAsmConfig.h: Enable new llint backend for Win64.
-        * llint/LowLevelInterpreter.asm: Implement new Win64 backend, and follow Win64 ABI spec.
-        * llint/LowLevelInterpreter64.asm: Ditto.
-        * offlineasm/asm.rb: Compile fix.
-        * offlineasm/backends.rb: Add new llint backend for Win64.
-        * offlineasm/settings.rb: Compile fix.
-        * offlineasm/x86.rb: Implement new llint Win64 backend.
-
-2014-06-25  Laszlo Gombos  <l.gombos@samsung.com>
-
-        Remove build guard for progress element
-        https://bugs.webkit.org/show_bug.cgi?id=134292
-
-        Reviewed by Benjamin Poulain.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-06-24  Michael Saboff  <msaboff@apple.com>
-
-        Add support routines to provide descriptive JavaScript backtraces
-        https://bugs.webkit.org/show_bug.cgi?id=134278
-
-        Reviewed by Mark Lam.
-
-        * interpreter/CallFrame.cpp:
-        (JSC::CallFrame::dump):
-        (JSC::CallFrame::describeFrame):
-        * interpreter/CallFrame.h:
-        * runtime/JSCJSValue.cpp:
-        (JSC::JSValue::dumpForBacktrace):
-        * runtime/JSCJSValue.h:
-
-2014-06-24  Brady Eidson  <beidson@apple.com>
-
-        Enable GAMEPAD in the Mac build, but disabled at runtime.
-        https://bugs.webkit.org/show_bug.cgi?id=134255
-
-        Reviewed by Dean Jackson.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-        * runtime/JSObject.h: Export JSObject::removeDirect() to allow disabling
-          functions at runtime.
-
-2014-06-24  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        REGRESSION (r169703): Invalid cast in JSC::asGetterSetter / JSC::JSObject::defineOwnNonIndexProperty
-        https://bugs.webkit.org/show_bug.cgi?id=134046
-
-        Reviewed by Filip Pizlo.
-
-        * runtime/GetterSetter.h:
-        (JSC::asGetterSetter):
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::defineOwnNonIndexProperty): We need to check for a CustomGetterSetter here as well as
-        a normal GetterSetter. If we encounter a CustomGetterSetter, we delete it, create a new normal GetterSetter,
-        and insert it like normal. We also need to check for CustomAccessors when checking for unconfigurable properties.
-
-2014-06-24  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] MSVC mishandles enums in bitfields
-        https://bugs.webkit.org/show_bug.cgi?id=134237
-
-        Reviewed by Michael Saboff.
-
-        Replace uses of enum types in bit fields with unsigned to
-        avoid losing a bit to hold the sign value. This can result
-        in Windows interpreting the value of the field improperly.
-
-        * bytecode/StructureStubInfo.h:
-        * parser/Nodes.h:
-
-2014-06-23  Andreas Kling  <akling@apple.com>
-
-        Inline the UnlinkedInstructionStream::Reader logic.
-        <https://webkit.org/b/134203>
-
-        This class is only used by CodeBlock to unpack the unlinked instructions,
-        and we were spending 0.5% of total time on PLT calling Reader::next().
-        Move the logic to the header file and mark it ALWAYS_INLINE.
-
-        Reviewed by Geoffrey Garen.
-
-        * bytecode/UnlinkedInstructionStream.cpp:
-        * bytecode/UnlinkedInstructionStream.h:
-        (JSC::UnlinkedInstructionStream::Reader::Reader):
-        (JSC::UnlinkedInstructionStream::Reader::read8):
-        (JSC::UnlinkedInstructionStream::Reader::read32):
-        (JSC::UnlinkedInstructionStream::Reader::next):
-
-2014-06-20  Sam Weinig  <sam@webkit.org>
-
-        Remove static tables for bindings that use eager reification
-        https://bugs.webkit.org/show_bug.cgi?id=134126
-
-        Reviewed by Oliver Hunt.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::putDirectCustomAccessor):
-        * runtime/Structure.h:
-        (JSC::Structure::setHasCustomGetterSetterProperties):
-        Change setHasCustomGetterSetterProperties to behave like setHasGetterSetterProperties, and set
-        the m_hasReadOnlyOrGetterSetterPropertiesExcludingProto bit if the property is not __proto__.
-        Without this, JSObject::put() won't think there are any setters on the prototype chain of an
-        object that has no static lookup table and uses eagerly reified custom getter/setter properties.
-
-2014-06-21  Brady Eidson  <beidson@apple.com>
-
-        Gamepad API - Deprecate the existing implementation
-        https://bugs.webkit.org/show_bug.cgi?id=134108
-
-        Reviewed by Timothy Hatcher.
-
-        -Add new "GAMEPAD_DEPRECATED" build flag, moving the existing implementation to use it
-        -Move some implementation files into a "deprecated" subdirectory.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-06-21  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r170244.
-        https://bugs.webkit.org/show_bug.cgi?id=134157
-
-        GTK/EFL bindings generator works differently, making this
-        patch not work there.  Will fix entire patch after a rollout.
-        (Requested by bradee-oh on #webkit).
-
-        Reverted changeset:
-
-        "Gamepad API - Deprecate the existing implementation"
-        https://bugs.webkit.org/show_bug.cgi?id=134108
-        http://trac.webkit.org/changeset/170244
-
-2014-06-21  Brady Eidson  <beidson@apple.com>
-
-        Gamepad API - Deprecate the existing implementation
-        https://bugs.webkit.org/show_bug.cgi?id=134108
-
-        Reviewed by Timothy Hatcher.
-
-        -Add new "GAMEPAD_DEPRECATED" build flag, moving the existing implementation to use it
-        -Add the "Deprecated" suffix to some implementation files
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-06-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        Removing PAGE_VISIBILITY_API compile guard.
-        https://bugs.webkit.org/show_bug.cgi?id=133844
-
-        Reviewed by Gavin Barraclough.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-06-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        ARM traditional buildfix after r169942.
-        https://bugs.webkit.org/show_bug.cgi?id=134100
-
-        Reviewed by Zoltan Herczeg.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::abortWithReason): Added.
-
-2014-06-20  Andreas Kling  <akling@apple.com>
-
-        [Cocoa] Release freed up blocks from the JS heap after simulated memory pressure.
-        <https://webkit.org/b/134112>
-
-        Reviewed by Mark Hahnenberg.
-
-        * heap/BlockAllocator.h:
-
-2014-06-19  Alex Christensen  <achristensen@webkit.org>
-
-        Unreviewed fix after r170130.
-
-        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj:
-        Corrected directory so it can find common.props when opening Visual Studio.
-
-2014-06-19  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
-
-        Remove ENABLE(LLINT) and ENABLE(LLINT_C_LOOP) guards
-        https://bugs.webkit.org/show_bug.cgi?id=130389
-
-        Reviewed by Mark Lam.
-
-        Removed ENABLE(LLINT) since we always build with it, and changed ENABLE(LLINT_C_LOOP)
-        into !ENABLE(JIT) since they are mutually exclusive.
-
-        * CMakeLists.txt:
-        * assembler/MacroAssemblerCodeRef.h:
-        (JSC::MacroAssemblerCodePtr::createLLIntCodePtr):
-        (JSC::MacroAssemblerCodeRef::createLLIntCodeRef):
-        * assembler/MaxFrameExtentForSlowPathCall.h:
-        * bytecode/CallLinkStatus.cpp:
-        (JSC::CallLinkStatus::computeFromLLInt):
-        * bytecode/CodeBlock.cpp:
-        (JSC::dumpStructure):
-        (JSC::CodeBlock::printGetByIdCacheStatus):
-        (JSC::CodeBlock::printCallOp):
-        (JSC::CodeBlock::CodeBlock):
-        (JSC::CodeBlock::~CodeBlock):
-        (JSC::CodeBlock::propagateTransitions):
-        (JSC::CodeBlock::finalizeUnconditionally):
-        (JSC::CodeBlock::unlinkCalls):
-        (JSC::CodeBlock::unlinkIncomingCalls):
-        (JSC::CodeBlock::linkIncomingCall):
-        (JSC::CodeBlock::frameRegisterCount):
-        * bytecode/CodeBlock.h:
-        * bytecode/GetByIdStatus.cpp:
-        (JSC::GetByIdStatus::computeFromLLInt):
-        * bytecode/Opcode.h:
-        (JSC::padOpcodeName):
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeFromLLInt):
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::emitCall):
-        (JSC::BytecodeGenerator::emitConstruct):
-        * heap/Heap.cpp:
-        (JSC::Heap::gatherJSStackRoots):
-        * interpreter/Interpreter.cpp:
-        (JSC::Interpreter::initialize):
-        (JSC::Interpreter::isOpcode):
-        * interpreter/Interpreter.h:
-        (JSC::Interpreter::getOpcodeID):
-        * interpreter/JSStack.cpp:
-        (JSC::JSStack::JSStack):
-        (JSC::JSStack::committedByteCount):
-        * interpreter/JSStack.h:
-        * interpreter/JSStackInlines.h:
-        (JSC::JSStack::ensureCapacityFor):
-        (JSC::JSStack::topOfFrameFor):
-        (JSC::JSStack::setStackLimit):
-        * jit/ExecutableAllocatorFixedVMPool.cpp:
-        (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
-        * jit/JIT.h:
-        (JSC::JIT::compileCTINativeCall):
-        * jit/JITExceptions.h:
-        * jit/JITThunks.cpp:
-        (JSC::JITThunks::ctiNativeCall):
-        (JSC::JITThunks::ctiNativeConstruct):
-        * llint/LLIntCLoop.cpp:
-        * llint/LLIntCLoop.h:
-        * llint/LLIntData.cpp:
-        (JSC::LLInt::initialize):
-        (JSC::LLInt::Data::performAssertions):
-        * llint/LLIntData.h:
-        (JSC::LLInt::Data::performAssertions): Deleted.
-        * llint/LLIntEntrypoint.cpp:
-        * llint/LLIntEntrypoint.h:
-        * llint/LLIntExceptions.cpp:
-        * llint/LLIntExceptions.h:
-        * llint/LLIntOfflineAsmConfig.h:
-        * llint/LLIntOffsetsExtractor.cpp:
-        (JSC::LLIntOffsetsExtractor::dummy):
-        * llint/LLIntOpcode.h:
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * llint/LLIntSlowPaths.h:
-        * llint/LLIntThunks.cpp:
-        * llint/LLIntThunks.h:
-        * llint/LowLevelInterpreter.cpp:
-        * llint/LowLevelInterpreter.h:
-        * runtime/CommonSlowPaths.cpp:
-        * runtime/CommonSlowPaths.h:
-        * runtime/ErrorHandlingScope.cpp:
-        (JSC::ErrorHandlingScope::ErrorHandlingScope):
-        (JSC::ErrorHandlingScope::~ErrorHandlingScope):
-        * runtime/Executable.cpp:
-        (JSC::setupLLInt):
-        * runtime/InitializeThreading.cpp:
-        (JSC::initializeThreading):
-        * runtime/JSCJSValue.h:
-        * runtime/JSCJSValueInlines.h:
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        (JSC::sanitizeStackForVM):
-        * runtime/VM.h:
-        (JSC::VM::canUseJIT): Deleted.
-
-2014-06-18  Alex Christensen  <achristensen@webkit.org>
-
-        Add FTL to Windows build.
-        https://bugs.webkit.org/show_bug.cgi?id=134015
-
-        Reviewed by Filip Pizlo.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        Added ftl source files.
-        * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
-        Added ftl and llvm directories to include path.
-        * JavaScriptCore.vcxproj/libllvmForJSC: Added.
-        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.props: Added.
-        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj: Added.
-        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj.filters: Added.
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
-        MSVC doesn't like to divide by zero while compiling.  Use std::nan instead.
-        * llvm/InitializeLLVMWin.cpp: Added.
-        (JSC::initializeLLVMImpl):
-        Implemented dynamic loading and linking for Windows.
-
-2014-06-18  Alex Christensen  <achristensen@webkit.org>
-
-        Unreviewed build fix after r170107.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileArithMod):
-        Use non-template sub for armv7s.
-
-2014-06-18  David Kilzer  <ddkilzer@apple.com>
-
-        -[JSContext setName:] leaks NSString
-        <http://webkit.org/b/134038>
-
-        Reviewed by Joseph Pecoraro.
-
-        Fixes the following static analyzer warning:
-
-            JavaScriptCore/API/JSContext.mm:200:73: warning: Potential leak of an object
-                JSStringRef nameJS = name ? JSStringCreateWithCFString((CFStringRef)[name copy]) : nullptr;
-                                                                                    ^
-
-        * API/JSContext.mm:
-        (-[JSContext setName:]): Autorelease the copy of |name|.
-
-2014-06-18  Mark Lam  <mark.lam@apple.com>
-
-        DFGGraph::m_doubleConstantMap will not map 0 values correctly.
-        <https://webkit.org/b/133994>
-
-        Reviewed by Geoffrey Garen.
-
-        DFGGraph::m_doubleConstantsMap should not use a double as a key to its HashMap,
-        because it means two unfortunate things:
-        - It will probably break for zero.
-        - It will think that -0 is the same as +0 under some circumstances, size
-          -0==+0 even though they are distinct values (for example 1/-0 != 1/+0).
-
-        The fix is to use std::unordered_map which does not require special empty
-        and deleted values, and to use the raw bits instead of the double value as
-        the key.
-
-        * dfg/DFGGraph.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
-
-2014-06-18  Alex Christensen  <achristensen@webkit.org>
-
-        Remove duplicate code using sdiv.
-        https://bugs.webkit.org/show_bug.cgi?id=133764
-
-        Reviewed by Daniel Bates.
-
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::sdiv):
-        Make sdiv a template to match arm64.
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileArithDiv):
-        (JSC::DFG::SpeculativeJIT::compileArithMod):
-        Remove duplicate code that was identical except for sdiv not being a template.
-
-2014-06-17  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r170082.
-        https://bugs.webkit.org/show_bug.cgi?id=134006
-
-        Breaks build. (Requested by mlam on #webkit).
-
-        Reverted changeset:
-
-        "DFGGraph::m_doubleConstantMap will not map 0 values
-        correctly."
-        https://bugs.webkit.org/show_bug.cgi?id=133994
-        http://trac.webkit.org/changeset/170082
-
-2014-06-17  Mark Lam  <mark.lam@apple.com>
-
-        DFGGraph::m_doubleConstantMap will not map 0 values correctly.
-        <https://webkit.org/b/133994>
-
-        Reviewed by Geoffrey Garen.
-
-        DFGGraph::m_doubleConstantsMap should not use a double as a key to its HashMap,
-        because it means two unfortunate things:
-        - It will probably break for zero.
-        - It will think that -0 is the same as +0 under some circumstances, size
-          -0==+0 even though they are distinct values (for example 1/-0 != 1/+0).
-
-        The fix is to use std::unordered_map which does not require special empty
-        and deleted values, and to use the raw bits instead of the double value as
-        the key.
-
-        * dfg/DFGGraph.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
-
-2014-06-17  Oliver Hunt  <oliver@apple.com>
-
-        Fix error messages for incorrect hex literals
-        https://bugs.webkit.org/show_bug.cgi?id=133998
-
-        Reviewed by Mark Lam.
-
-        Ensure that the error messages for bogus hex literals actually
-        make sense.
-
-        * parser/Lexer.cpp:
-        (JSC::Lexer<T>::lex):
-        * parser/ParserTokens.h:
-
-2014-06-17  Matthew Mirman  <mmirman@apple.com>
-
-        Fixes bug where building JSC sometimes crashes at build-symbol-table-index.py. Also adds licenses. 
-        https://bugs.webkit.org/show_bug.cgi?id=133814
-
-        Reviewed by Filip Pizlo.
-        
-        Adds the "shopt -s nullglob" line necessary to prevent the loop in the shell 
-        script from using "*.o" as a file when no other files in the directory exist. 
-        
-        * build-symbol-table-index.sh: Added license.
-        * copy-llvm-ir-to-derived-sources.sh: Added license and "shopt -s nullglob" line.
-
-2014-06-16  Sam Weinig  <sam@webkit.org>
-
-        Move forward declaration of bindings static functions into their implementation files
-        https://bugs.webkit.org/show_bug.cgi?id=133943
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/CommonIdentifiers.h:
-        Add a few identifiers that are needed by the DOM.
-
-2014-06-16  Mark Lam  <mark.lam@apple.com>
-
-        Parser statementDepth accounting needs to account for when a function body excludes its braces.
-        <https://webkit.org/b/133832>
-
-        Reviewed by Oliver Hunt.
-
-        In some cases (e.g. when a Function object is instantiated from a string), the
-        function body source may not include its braces.  The parser needs to account
-        for this when calculating its statementDepth.
-
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::generateFunctionCodeBlock):
-        (JSC::UnlinkedFunctionExecutable::codeBlockFor):
-        * bytecode/UnlinkedCodeBlock.h:
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::parseStatement):
-        - Also fixed the error message for declaring nested functions in strict mode
-          to be more accurate.
-        * parser/Parser.h:
-        (JSC::Parser<LexerType>::parse):
-        (JSC::parse):
-        * runtime/Executable.cpp:
-        (JSC::ScriptExecutable::newCodeBlockFor):
-
-2014-06-16  Juergen Ributzka  <juergen@apple.com>
-
-        Change the order of the alias analysis passes to align with the opt pipeline of LLVM
-        https://bugs.webkit.org/show_bug.cgi?id=133753
-
-        Reviewed by Geoffrey Garen.
-
-        The order in which the alias analysis passes are added affects also the
-        order in which they are utilized. Change the order to align with the
-        one use by LLVM itself. The last alias analysis pass added will be
-        evaluated first. With this change we first perform a basic alias
-        analysis and then use the type-based alias analysis (if required).
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::compile):
-
-2014-06-16  Juergen Ributzka  <juergen@apple.com>
-
-        Fix the arguments passed to the LLVM dylib
-        https://bugs.webkit.org/show_bug.cgi?id=133757
-
-        Reviewed by Geoffrey Garen.
-
-        The LLVM command line argument parser assumes that the first argument
-        is the program name. We need to add a fake program name, otherwise the
-        first argument will be parsed as program name and ignored.
-
-        * llvm/library/LLVMExports.cpp:
-        (initializeAndGetJSCLLVMAPI):
-
-2014-06-16  Michael Saboff  <msaboff@apple.com>
-
-        Convert ASSERT in inlineFunctionForCapabilityLevel to early return
-        https://bugs.webkit.org/show_bug.cgi?id=133903
-
-        Reviewed by Mark Hahnenberg.
-
-        Hardened code by Converting ASSERT to return CannotCompile.
-
-        * dfg/DFGCapabilities.h:
-        (JSC::DFG::inlineFunctionForCapabilityLevel):
-
-2014-06-13  Sam Weinig  <sam@webkit.org>
-
-        Store DOM constants directly in the JS object rather than jumping through a custom accessor
-        https://bugs.webkit.org/show_bug.cgi?id=133898
-
-        Reviewed by Oliver Hunt.
-
-        * runtime/Lookup.h:
-        (JSC::HashTableValue::attributes):
-        Switch attributes to be stored as an unsigned rather than an unsigned char, since there is no difference in memory use
-        and will make adding more flags possibles.
-
-        (JSC::HashTableValue::propertyGetter):
-        (JSC::HashTableValue::propertyPutter):
-        Change assertion to use BuiltinOrFunctionOrConstant.
-
-        (JSC::HashTableValue::constantInteger):
-        Added.
-
-        (JSC::getStaticPropertySlot):
-        (JSC::getStaticValueSlot):
-        Use PropertySlot::setValue() for constants during static lookup.
-
-        (JSC::reifyStaticProperties):
-        Put the constant directly on the object when eagerly reifying.
-
-        * runtime/PropertySlot.h:
-        Add ConstantInteger flag and BuiltinOrFunctionOrConstant helper.
-
-2014-06-14  Michael Saboff  <msaboff@apple.com>
-
-        operationCreateArguments could cause a GC during OSR exit
-        https://bugs.webkit.org/show_bug.cgi?id=133905
-
-        Reviewed by Filip Pizlo.
-
-        Defer GC via new wrapper functions for operationCreateArguments and operationCreateInlinedArguments
-        for use by OSR exit stubs.
-
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor):
-        * dfg/DFGOperations.cpp:
-        * dfg/DFGOperations.h:
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-
-2014-06-13  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        OSR exit should barrier the Executables for all InlineCallFrames, not just those on the stack at the time of exit
-        https://bugs.webkit.org/show_bug.cgi?id=133880
-
-        Reviewed by Filip Pizlo.
-
-        We could have exited due to a value received from an inlined block that's no longer on 
-        the stack, so we should just barrier all InlineCallFrames.
-
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::adjustAndJumpToTarget):
-
-2014-06-13  Alex Christensen  <achristensen@webkit.org>
-
-        Make css jit compile for armv7.
-        https://bugs.webkit.org/show_bug.cgi?id=133596
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/MacroAssembler.h:
-        Use branchPtr on ARM_THUMB2.
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::addPtrNoFlags):
-        (JSC::MacroAssemblerARMv7::or32):
-        (JSC::MacroAssemblerARMv7::test32):
-        (JSC::MacroAssemblerARMv7::branch):
-        (JSC::MacroAssemblerARMv7::branchPtr):
-        Added macros necessary for css jit.
-
-2014-06-13  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix ARMv7.
-
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::abortWithReason):
-
-2014-06-12  Filip Pizlo  <fpizlo@apple.com>
-
-        Even better diagnostics from DFG traps
-        https://bugs.webkit.org/show_bug.cgi?id=133836
-
-        Reviewed by Oliver Hunt.
-        
-        We now stuff the DFG::NodeType into a register before bailing. Also made the
-        DFGBailed abort reason a bit more specific. As planned, the new abort reasons use
-        different numbers than any previous abort reasons.
-
-        * assembler/AbortReason.h:
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::abortWithReason):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::abortWithReason):
-        * assembler/MacroAssemblerX86.h:
-        (JSC::MacroAssemblerX86::abortWithReason):
-        * assembler/MacroAssemblerX86_64.h:
-        (JSC::MacroAssemblerX86_64::abortWithReason):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
-        (JSC::DFG::SpeculativeJIT::bail):
-        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
-        * dfg/DFGSpeculativeJIT.h:
-
-2014-06-12  Simon Fraser  <simon.fraser@apple.com>
-
-        Fix assertions under JSC::setNeverInline() when running js tests in WebKitTestRunner
-        https://bugs.webkit.org/show_bug.cgi?id=133840
-
-        Reviewed by Filip Pizlo.
-        
-        Fix ASSERT(exec->vm().currentThreadIsHoldingAPILock()); under JSC::setNeverInline()
-        when running DFG tests.
-
-        * API/JSCTestRunnerUtils.cpp:
-        (JSC::numberOfDFGCompiles):
-        (JSC::setNeverInline):
-
-2014-06-12  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Avoid fork bomb during build
-        https://bugs.webkit.org/show_bug.cgi?id=133837
-        <rdar://problem/17296034>
-
-        Reviewed by Tim Horton.
-
-        * JavaScriptCore.vcxproj/build-generated-files.sh: Use a
-        reasonable default value when the 'num-cpus' script is not available.
-
-2014-06-12  Mark Lam  <mark.lam@apple.com>
-
-        Remove some dead / unused code.
-        <https://webkit.org/b/133828>
-
-        Reviewed by Filip Pizlo.
-
-        * builtins/BuiltinExecutables.cpp:
-        (JSC::BuiltinExecutables::createBuiltinExecutable):
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
-        * bytecode/UnlinkedCodeBlock.h:
-        (JSC::UnlinkedFunctionExecutable::create):
-        * bytecompiler/BytecodeGenerator.h:
-        (JSC::BytecodeGenerator::makeFunction):
-        * parser/Parser.h:
-        (JSC::DepthManager::DepthManager): Deleted.
-        (JSC::DepthManager::~DepthManager): Deleted.
-        * runtime/CodeCache.cpp:
-        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
-
-2014-06-12  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Move structureHasRareData out of TypeInfo
-        https://bugs.webkit.org/show_bug.cgi?id=133800
-
-        Reviewed by Andreas Kling.
-
-        StructureHasRareData was originally put in TypeInfo to avoid making Structure bigger, 
-        but we have a few spare bits in Structure so it would be nice to remove this hack.
-
-        * runtime/JSTypeInfo.h:
-        (JSC::TypeInfo::newImpurePropertyFiresWatchpoints):
-        (JSC::TypeInfo::structureHasRareData): Deleted.
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::allocateRareData):
-        (JSC::Structure::cloneRareDataFrom):
-        * runtime/Structure.h:
-        (JSC::Structure::previousID):
-        (JSC::Structure::objectToStringValue):
-        (JSC::Structure::setObjectToStringValue):
-        (JSC::Structure::setPreviousID):
-        (JSC::Structure::clearPreviousID):
-        (JSC::Structure::previous):
-        (JSC::Structure::rareData):
-        * runtime/StructureInlines.h:
-        (JSC::Structure::setEnumerationCache):
-        (JSC::Structure::enumerationCache):
-
-2014-06-12  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
-
-        Allow enum guards to be generated from the replay json files
-        https://bugs.webkit.org/show_bug.cgi?id=133399
-
-        Reviewed by Csaba Osztrogonác.
-
-        * replay/scripts/CodeGeneratorReplayInputs.py:
-        (Type.__init__):
-        (InputsModel.parse_type_with_framework_name):
-        (Generator.generate_header):
-        (Generator.generate_implementation):
-        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp: Added.
-        (Test::HandleWheelEvent::HandleWheelEvent):
-        (Test::HandleWheelEvent::~HandleWheelEvent):
-        (JSC::InputTraits<Test::HandleWheelEvent>::type):
-        (JSC::InputTraits<Test::HandleWheelEvent>::encode):
-        (JSC::InputTraits<Test::HandleWheelEvent>::decode):
-        (JSC::EncodingTraits<WebCore::PlatformWheelEventPhase>::encodeValue):
-        (JSC::EncodingTraits<WebCore::PlatformWheelEventPhase>::decodeValue):
-        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h: Added.
-        (JSC::InputTraits<Test::HandleWheelEvent>::queue):
-        (Test::HandleWheelEvent::platformEvent):
-        * replay/scripts/tests/generate-enum-with-guard.json: Added.
-
-2014-06-12  Carlos Garcia Campos  <cgarcia@igalia.com>
-
-        Unreviewed. Fix GTK+ build after r169823.
-
-        Include StructureInlines.h in a few more files to fix linking
-        issues due to JSC::Structure::get undefined symbol.
-
-        * runtime/ArrayIteratorConstructor.cpp:
-        * runtime/ArrayIteratorPrototype.cpp:
-        * runtime/JSConsole.cpp:
-        * runtime/JSMapIterator.cpp:
-        * runtime/JSSet.cpp:
-        * runtime/JSSetIterator.cpp:
-        * runtime/JSWeakMap.cpp:
-        * runtime/MapIteratorPrototype.cpp:
-        * runtime/MapPrototype.cpp:
-        * runtime/SetIteratorPrototype.cpp:
-        * runtime/SetPrototype.cpp:
-        * runtime/WeakMapPrototype.cpp:
-
-2014-06-12  Csaba Osztrogonác  <ossy@webkit.org>
-
-        [EFL] One more URTBF after r169823 to make ARM64 build happy too.
-
-        * runtime/JSMap.cpp:
-
-2014-06-11  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Inline caching should try to flatten uncacheable dictionaries
-        https://bugs.webkit.org/show_bug.cgi?id=133683
-
-        Reviewed by Geoffrey Garen.
-
-        There exists a body of JS code that deletes properties off of objects (especially function/constructor objects), 
-        which puts them into an uncacheable dictionary state. This prevents all future inline caching for these objects. 
-        If properties are deleted out of the object during its initialization, we can enable caching for that object by 
-        attempting to flatten it when we see we're trying to do inline caching with that object. We then record that we 
-        performed this flattening optimization in the object's Structure. If it ever re-enters the uncacheable dictionary 
-        state then we can just give up on caching that object.
-
-        In refactoring some of the code in tryCacheGetById and tryBuildGetByIdList to reduce some duplication, I added
-        the InlineCacheAction enum, a new way to indicate the success or failure of an inline caching attempt. I changed
-        the other inline caching functions to return this enum rather than the opaque booleans that we were previously 
-        returning.
-
-        * jit/Repatch.cpp:
-        (JSC::actionForCell):
-        (JSC::tryCacheGetByID):
-        (JSC::repatchGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::buildGetByIDList):
-        (JSC::tryCachePutByID):
-        (JSC::repatchPutByID):
-        (JSC::tryBuildPutByIdList):
-        (JSC::buildPutByIdList):
-        (JSC::tryRepatchIn):
-        (JSC::repatchIn):
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::flattenDictionaryStructure):
-        * runtime/Structure.h:
-        (JSC::Structure::hasBeenFlattenedBefore):
-
-2014-06-11  Csaba Osztrogonác  <ossy@webkit.org>
-
-        [EFL] URTBF after r169823.
-
-        * bindings/ScriptValue.cpp: Missing include added.
-
-2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
-
-        Remove an unnecessary asObject(this) call inside JSObject::fastGetOwnPropertySlot.
-
-        Rubber-stamped by Andreas Kling.
-
-        * runtime/JSObject.h:
-        (JSC::JSObject::fastGetOwnPropertySlot):
-
-2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
-
-        Turning on DUMP_PROPERTYMAP_STATS causes a build failure
-        https://bugs.webkit.org/show_bug.cgi?id=133673
-
-        Reviewed by Andreas Kling.
-
-        Rewrote the property map statistics code because the old code wasn't building,
-        and it was also mixing numbers for lookups and insertions/removals.
-
-        New logging code records the number of calls to PropertyTable::find (finds) and
-        PropertyTable::get/PropertyTable::findWithString separately so that we can quantify
-        the number of probing during updates and lookups.
-
-        * jsc.cpp:
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::find):
-        (JSC::PropertyTable::get):
-        (JSC::PropertyTable::findWithString):
-        (JSC::PropertyTable::add):
-        (JSC::PropertyTable::remove):
-        (JSC::PropertyTable::reinsert):
-        (JSC::PropertyTable::rehash):
-        * runtime/Structure.cpp:
-        (JSC::PropertyMapStatisticsExitLogger::PropertyMapStatisticsExitLogger):
-        (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger):
-
-2014-06-11  Andreas Kling  <akling@apple.com>
-
-        Always inline JSValue::get() and Structure::get().
-        <https://webkit.org/b/133755>
-
-        Reviewed by Ryosuke Niwa.
-
-        These functions get really hot, so ask the compiler to be more
-        aggressive about inlining them.
-
-        ~28% speed-up on Ryosuke's microbenchmark for accessing nextSibling
-        through GetByVal.
-
-        * runtime/JSArrayIterator.cpp:
-        * runtime/JSCJSValue.cpp:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::get):
-        * runtime/JSPromiseDeferred.cpp:
-        * runtime/StructureInlines.h:
-        (JSC::Structure::get):
-
-2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
-
-        Structure::get should instantiate DeferGC only when materializing property map
-        https://bugs.webkit.org/show_bug.cgi?id=133727
-
-        Rubber-stamped by Andreas Kling.
-
-        Make materializePropertyMapIfNecessary always inline.
-
-        This is ~12% improvement on the microbenchmark attached in the bug.
-
-        * runtime/Structure.h:
-        (JSC::Structure::materializePropertyMapIfNecessary):
-        (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
-
-2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
-
-        Structure::get should instantiate DeferGC only when materializing property map
-        https://bugs.webkit.org/show_bug.cgi?id=133727
-
-        Reviewed by Geoffrey Garen.
-
-        DeferGC instances in Structure::get was added in http://trac.webkit.org/r157539 in order to avoid
-        collecting the property table newly created by materializePropertyMapIfNecessary since GC can happen
-        when GCSafeConcurrentJITLocker goes out of scope.
-
-        However, always instantiating DeferGC inside Structure::get introduced a new performance bottleneck
-        in JSObject::getPropertySlot because frequently incrementing and decrementing a counter in vm.m_heap
-        and running a release assertion inside Heap::incrementDeferralDepth() is expensive.
-
-        Work around this by instantiating DeferGC only when we're actually calling materializePropertyMap,
-        and immediately storing a pointer to the newly created property table in the stack before DeferGC
-        goes out of scope so that the property table will be marked.
-
-        This shows 13-16% improvement on the microbenchmark attached in the bug.
-
-        * runtime/JSCJSValue.cpp:
-        * runtime/JSObject.h:
-        (JSC::JSObject::fastGetOwnPropertySlot):
-        * runtime/Structure.h:
-        (JSC::Structure::materializePropertyMapIfNecessary):
-        * runtime/StructureInlines.h:
-        (JSC::Structure::get):
-
-2014-06-11  Andreas Kling  <akling@apple.com>
-
-        Some JSValue::get() micro-optimzations.
-        <https://webkit.org/b/133739>
-
-        Tighten some of the property lookup code to improve performance of the
-        eagerly reified prototype attributes:
-
-        - Instead of converting the property name to an integer at every step
-          in the prototype chain, move that to a separate pass at the end
-          since it should be a rare case.
-
-        - Cache the StructureIDTable in a local instead of fetching it from
-          the Heap on every step.
-
-        - Make fillCustomGetterPropertySlot inline. It was out-of-lined based
-          on the assumption that clients would mostly be cacheable GetByIds,
-          and it gets pretty hot (~1%) in GetByVal.
-
-        - Pass the Structure directly to fillCustomGetterPropertySlot instead
-          of refetching it from the StructureIDTable.
-
-        Reviewed by Geoff Garen.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::fillCustomGetterPropertySlot): Deleted.
-        * runtime/JSObject.h:
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-        (JSC::JSObject::fillCustomGetterPropertySlot):
-        (JSC::JSObject::getOwnPropertySlot):
-        (JSC::JSObject::fastGetOwnPropertySlot):
-        (JSC::JSObject::getPropertySlot):
-        (JSC::JSObject::getOwnPropertySlotSlow): Deleted.
-
-2014-06-10  Sam Weinig  <sam@webkit.org>
-
-        Don't create a HashTable for JSObjects that use eager reification
-        https://bugs.webkit.org/show_bug.cgi?id=133705
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/Lookup.h:
-        (JSC::reifyStaticProperties):
-        Add a version of reifyStaticProperties that takes an array of HashTableValues
-        rather than a HashTable.
-
-2014-06-10  Filip Pizlo  <fpizlo@apple.com>
-
-        Prediction propagator should make sure everyone knows that a variable that is in an argument position where other versions of that variable are not MachineInts cannot possibly be flushed as Int52
-        https://bugs.webkit.org/show_bug.cgi?id=133698
-
-        Reviewed by Geoffrey Garen and Mark Hahnenberg.
-
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate): Use the new utility to figure out if a variable could ever represent an Int52.
-        * dfg/DFGVariableAccessData.cpp:
-        (JSC::DFG::VariableAccessData::couldRepresentInt52): Add a new utility to detect early on if a variable could possibly be Int52.
-        (JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
-        (JSC::DFG::VariableAccessData::flushFormat):
-        * dfg/DFGVariableAccessData.h:
-        * tests/stress/int52-inlined-call-argument.js: Added.
-        (foo):
-        (bar):
-
-2014-06-10  Mark Lam  <mark.lam@apple.com>
-
-        Assertion failure at JSC::Structure::checkOffsetConsistency() const + 234.
-        <https://webkit.org/b/133356>
-
-        Reviewed by Mark Hahnenberg.
-
-        The root cause of this issue is that a nonPropertyTransition can transition
-        a pinned dictionary structure to an unpinned dictionary structure.  The new
-        structure will get a copy of the property table from the original structure.
-        However, when a GC occurs, the property table in the new structure will be
-        cleared because it is unpinned.  This leads to complications in subsequent
-        derivative structures when flattening occurs, which eventually leads to the
-        assertion failure in this bug.
-
-        The fix is to ensure that the new dictionary structure generated by the
-        nonPropertyTransition will have a copy of its predecessor's property table
-        and is pinned.
-
-        * runtime/Structure.cpp:
-        (JSC::Structure::nonPropertyTransition):
-
-2014-06-10  Michael Saboff  <msaboff@apple.com>
-
-        In a certain app state, Array.prototype.filter() returns incorrect results
-        https://bugs.webkit.org/show_bug.cgi?id=133577
-
-        Reviewed by Oliver Hunt.
-
-        Fixed the LLInt processing of op_put_by_val_direct to have the same hole check as op_put_by_val.
-
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-
-2014-06-09  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Global HashTables contain references to atomic StringImpls
-        https://bugs.webkit.org/show_bug.cgi?id=133661
-
-        Reviewed by Geoffrey Garen.
-
-        This was a long-standing bug revealed by bug 133558. The issue is that the global static HashTables 
-        cache their set of keys as StringImpls that are associated with a particular VM.  This is obviously 
-        incompatible with using multiple VMs on multiple threads (e.g. when using workers). The fix is to 
-        change the "keys" field of the static HashTables to be char** instead of StringImpl**.
-
-        * runtime/JSObject.cpp:
-        (JSC::getClassPropertyNames):
-        * runtime/Lookup.cpp:
-        (JSC::HashTable::createTable):
-        (JSC::HashTable::deleteTable):
-        * runtime/Lookup.h:
-        (JSC::HashTable::ConstIterator::key):
-        (JSC::HashTable::entry):
-
-2014-06-09  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Build fix after r169703
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2014-06-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Eagerly reify DOM prototype attributes
-        https://bugs.webkit.org/show_bug.cgi?id=133558
-
-        Reviewed by Oliver Hunt.
-
-        This allows us to get rid of a lot of the additional overhead of pushing DOM attributes up into the prototype. 
-        By eagerly reifying the custom getters and setters into the actual JSObject we avoid having to override 
-        getOwnPropertySlot for all of the DOM prototypes, which is a lot of the overhead of doing property lookups on 
-        DOM wrappers.
-
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * llint/LLIntData.cpp:
-        (JSC::LLInt::Data::performAssertions):
-        * llint/LowLevelInterpreter.asm:
-        * runtime/BatchedTransitionOptimizer.h:
-        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
-        * runtime/CustomGetterSetter.cpp: Added.
-        (JSC::callCustomSetter):
-        * runtime/CustomGetterSetter.h: Added.
-        (JSC::CustomGetterSetter::create):
-        (JSC::CustomGetterSetter::getter):
-        (JSC::CustomGetterSetter::setter):
-        (JSC::CustomGetterSetter::createStructure):
-        (JSC::CustomGetterSetter::CustomGetterSetter):
-        * runtime/JSCJSValue.cpp:
-        (JSC::JSValue::putToPrimitive):
-        * runtime/JSCJSValue.h:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::isCustomGetterSetter):
-        * runtime/JSCell.h:
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::isCustomGetterSetter):
-        (JSC::JSCell::canUseFastGetOwnProperty):
-        * runtime/JSFunction.cpp:
-        (JSC::JSFunction::isHostOrBuiltinFunction): Deleted.
-        (JSC::JSFunction::isBuiltinFunction): Deleted.
-        * runtime/JSFunction.h:
-        * runtime/JSFunctionInlines.h: Inlined some random functions that appeared hot during profiling.
-        (JSC::JSFunction::isBuiltinFunction):
-        (JSC::JSFunction::isHostOrBuiltinFunction):
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::put):
-        (JSC::JSObject::putDirectCustomAccessor):
-        (JSC::JSObject::fillGetterPropertySlot):
-        (JSC::JSObject::fillCustomGetterPropertySlot):
-        (JSC::JSObject::getOwnPropertySlotSlow): Deleted.
-        * runtime/JSObject.h:
-        (JSC::JSObject::hasCustomGetterSetterProperties):
-        (JSC::JSObject::convertToDictionary):
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-        (JSC::JSObject::getOwnPropertySlotSlow): Inlined because it looked hot during profiling.
-        (JSC::JSObject::putOwnDataProperty):
-        (JSC::JSObject::putDirect):
-        (JSC::JSObject::putDirectWithoutTransition):
-        * runtime/JSType.h:
-        * runtime/Lookup.h:
-        (JSC::reifyStaticProperties):
-        * runtime/PropertyDescriptor.h:
-        (JSC::PropertyDescriptor::PropertyDescriptor):
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::nextOutOfLineStorageCapacity): Deleted.
-        (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Deleted.
-        (JSC::Structure::get): Deleted.
-        * runtime/Structure.h:
-        (JSC::Structure::hasCustomGetterSetterProperties):
-        (JSC::Structure::setHasCustomGetterSetterProperties):
-        * runtime/StructureInlines.h:
-        (JSC::Structure::get): Inlined due to hotness.
-        (JSC::nextOutOfLineStorageCapacity): Inlined due to hotness.
-        (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Inlined due to hotness.
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        * runtime/VM.h:
-        * runtime/WriteBarrier.h:
-        (JSC::WriteBarrierBase<Unknown>::isCustomGetterSetter):
-
-2014-06-07  Mark Lam  <mark.lam@apple.com>
-
-        Structure should initialize its previousID in its constructor.
-        <https://webkit.org/b/133606>
-
-        Reviewed by Mark Hahnenberg.
-
-        Currently, the Structure constructor that takes a previous structure will
-        initialize its previousID to point to the previous structure's previousID.
-        This is incorrect.  However, the caller of the Structure::create() factory
-        method (which instantiated the Structure) will later call setPreviousID()
-        to set the previousID to the correct previous structure.  This makes the
-        code confusing to read and more error prone in that the structure relies
-        on client code to fix its invalid previousID.
-
-        This patch fixes this by making the Structure constructor initialize
-        previousID correctly.
-
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::addPropertyTransition):
-        (JSC::Structure::nonPropertyTransition):
-        * runtime/Structure.h:
-        * runtime/StructureInlines.h:
-        (JSC::Structure::create):
-
-2014-06-06  Andreas Kling  <akling@apple.com>
-
-        Indexed getters should return values directly on the PropertySlot.
-        <https://webkit.org/b/133586>
-
-        Remove PropertySlot's custom index mode.
-
-        Reviewed by Darin Adler.
-
-        * runtime/JSObject.h:
-        (JSC::PropertySlot::getValue):
-        * runtime/PropertySlot.h:
-        (JSC::PropertySlot::setCustomIndex): Deleted.
-
-2014-06-04  Timothy Horton  <timothy_horton@apple.com>
-
-        iOS Debug build fix
-
-        Rubber-stamped by Filip Pizlo.
-
-        * Configurations/LLVMForJSC.xcconfig:
-        Dead-code strip the llvmForJSC library unconditionally, to work around <rdar://problem/16920916>.
-
-2014-06-04  Oliver Hunt  <oliver@apple.com>
-
-        ArrayIterator should not be exposed in Safari 8
-        https://bugs.webkit.org/show_bug.cgi?id=133494
-
-        Reviewed by Michael Saboff.
-
-        Separate out types that require constructor objects, and don't
-        include the iterator types in that list.
-
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        * runtime/JSGlobalObject.h:
-
-2014-06-04  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG::Safepoint::begin() should set m_didCallBegin before releasing the rightToRun lock, because otherwise, Safepoint::checkLivenessAndVisitChildren() may assert due to a race
-        https://bugs.webkit.org/show_bug.cgi?id=133525
-        <rdar://problem/16790296>
-
-        Reviewed by Oliver Hunt.
-
-        * dfg/DFGSafepoint.cpp:
-        (JSC::DFG::Safepoint::begin):
-
-2014-06-03  Filip Pizlo  <fpizlo@apple.com>
-
-        LLVM soft-linking should be truly fail-silent
-        https://bugs.webkit.org/show_bug.cgi?id=133482
-
-        Reviewed by Mark Lam.
-
-        * llvm/InitializeLLVMPOSIX.cpp:
-        (JSC::initializeLLVMPOSIX): Missing return statement in the dlsym() returning null case.
-
-2014-06-03  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        REGRESSION(r169092 and r169102): Skip failing JSC tests poperly on non-x86 Darwin platforms
-        https://bugs.webkit.org/show_bug.cgi?id=133149
-
-        Reviewed by Csaba Osztrogonác.
-
-        * tests/mozilla/mozilla-tests.yaml: Skip js1_5/Regress/regress-159334.js only if the architecture isn't x86 and the host is Darwin.
-
-2014-05-31  Anders Carlsson  <andersca@apple.com>
-
-        Add a LazyNeverDestroyed class template and use it
-        https://bugs.webkit.org/show_bug.cgi?id=133425
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGFunctionWhitelist.cpp:
-        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
-        * dfg/DFGFunctionWhitelist.h:
-
-2014-05-28  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG::DCEPhase inserts into an insertion set in reverse, causing hilarious basic block corruption if you kill a lot of NewArrays
-        https://bugs.webkit.org/show_bug.cgi?id=133368
-
-        Reviewed by Mark Lam.
-
-        * dfg/DFGDCEPhase.cpp:
-        (JSC::DFG::DCEPhase::fixupBlock): Loop in the right order so that we insert in the right order.
-        * tests/stress/new-array-dead.js: Added.
-        (foo):
-
-2014-05-28  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix not-x86 32-bit.
-
-        * llint/LowLevelInterpreter32_64.asm:
-
-2014-05-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Arrayify neglects to inform the clobberizer that it might fire watchpoints
-        https://bugs.webkit.org/show_bug.cgi?id=133340
-
-        Reviewed by Mark Lam.
-
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize): Be honest.
-        * llint/LowLevelInterpreter32_64.asm: Profile the object, not its structure.
-        * tests/stress/arrayify-fires-watchpoint.js: Added.
-        (foo):
-        (test):
-        (makeObjectArray):
-        * tests/stress/arrayify-structure-bad-test.js: Added.
-        (foo):
-        (test):
-
-2014-05-27  Jon Lee  <jonlee@apple.com>
-
-        Update ENABLE(MEDIA_SOURCE) on Mac
-        https://bugs.webkit.org/show_bug.cgi?id=133141
-
-        Reviewed by Darin Adler.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-05-27  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Remove BLOB guards
-        https://bugs.webkit.org/show_bug.cgi?id=132863
-
-        Reviewed by Csaba Osztrogonác.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-05-27  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
-
-        Allow building CMake based ports with WEB_REPLAY
-        https://bugs.webkit.org/show_bug.cgi?id=133154
-
-        Reviewed by Csaba Osztrogonác.
-
-        * CMakeLists.txt:
-
-2014-05-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Latest emscripten life benchmark is 4x slower because the DFG doesn't realize that arithmetic on booleans is a thing
-        https://bugs.webkit.org/show_bug.cgi?id=133136
-
-        Reviewed by Oliver Hunt.
-        
-        Some key concepts:
-
-        - Except for the prediction propagation and type fixup phases, which are super early in
-          the pipeline, nobody has to know about the fact that booleans may flow into numerical
-          operations because there will just be a BooleanToNumber node that will take a value
-          and, if that value is a boolean, will convert it to the equivalent numerical value. It
-          will have a BooleanUse mode where it will also speculate that the input is a boolean
-          but it can also do UntypedUse in which case it will pass through any non-booleans.
-          This operation is very easy to model in all of the compiler tiers.
-
-        - No changes to the baseline JIT. The Baseline JIT will still believe that boolean
-          inputs require taking the slow path and it will still report that it took slow path
-          for any such operations.  The DFG will now be smart enough to ignore baseline JIT slow
-          path profiling on operations that were known to have had boolean inputs.  That's a
-          little quirky, but it's probably easier than modifying the baseline JIT to track
-          booleans correctly.
-        
-        4.1x speed-up on the emscripten "life" benchmark. Up to 10x speed-up on microbenchmarks.
-
-        * bytecode/SpeculatedType.h:
-        (JSC::isInt32OrBooleanSpeculation):
-        (JSC::isInt32SpeculationForArithmetic):
-        (JSC::isInt32OrBooleanSpeculationForArithmetic):
-        (JSC::isInt32OrBooleanSpeculationExpectingDefined):
-        (JSC::isInt52Speculation):
-        (JSC::isMachineIntSpeculation):
-        (JSC::isFullNumberOrBooleanSpeculation):
-        (JSC::isFullNumberOrBooleanSpeculationExpectingDefined):
-        (JSC::isInt32SpeculationExpectingDefined): Deleted.
-        (JSC::isMachineIntSpeculationExpectingDefined): Deleted.
-        (JSC::isMachineIntSpeculationForArithmetic): Deleted.
-        (JSC::isBytecodeNumberSpeculationExpectingDefined): Deleted.
-        (JSC::isFullNumberSpeculationExpectingDefined): Deleted.
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGAllocator.h:
-        (JSC::DFG::Allocator<T>::indexOf):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::makeSafe):
-        (JSC::DFG::ByteCodeParser::makeDivSafe):
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::performNodeCSE):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGCommon.h:
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::fixIntConvertingEdge):
-        (JSC::DFG::FixupPhase::fixIntOrBooleanEdge):
-        (JSC::DFG::FixupPhase::fixDoubleOrBooleanEdge):
-        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
-        (JSC::DFG::FixupPhase::fixIntEdge): Deleted.
-        * dfg/DFGGraph.h:
-        (JSC::DFG::Graph::addSpeculationMode):
-        (JSC::DFG::Graph::valueAddSpeculationMode):
-        (JSC::DFG::Graph::arithAddSpeculationMode):
-        (JSC::DFG::Graph::addShouldSpeculateInt32):
-        (JSC::DFG::Graph::mulShouldSpeculateInt32):
-        (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
-        (JSC::DFG::Graph::negateShouldSpeculateInt32):
-        (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
-        (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
-        (JSC::DFG::Graph::mulImmediateShouldSpeculateInt32): Deleted.
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::sawBooleans):
-        (JSC::DFG::Node::shouldSpeculateInt32OrBoolean):
-        (JSC::DFG::Node::shouldSpeculateInt32ForArithmetic):
-        (JSC::DFG::Node::shouldSpeculateInt32OrBooleanForArithmetic):
-        (JSC::DFG::Node::shouldSpeculateInt32OrBooleanExpectingDefined):
-        (JSC::DFG::Node::shouldSpeculateMachineInt):
-        (JSC::DFG::Node::shouldSpeculateDouble):
-        (JSC::DFG::Node::shouldSpeculateNumberOrBoolean):
-        (JSC::DFG::Node::shouldSpeculateNumberOrBooleanExpectingDefined):
-        (JSC::DFG::Node::shouldSpeculateNumber):
-        (JSC::DFG::Node::canSpeculateInt32):
-        (JSC::DFG::Node::canSpeculateInt52):
-        (JSC::DFG::Node::sourceFor):
-        (JSC::DFG::Node::shouldSpeculateInt32ExpectingDefined): Deleted.
-        (JSC::DFG::Node::shouldSpeculateMachineIntForArithmetic): Deleted.
-        (JSC::DFG::Node::shouldSpeculateMachineIntExpectingDefined): Deleted.
-        (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic): Deleted.
-        (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined): Deleted.
-        * dfg/DFGNodeFlags.cpp:
-        (JSC::DFG::dumpNodeFlags):
-        * dfg/DFGNodeFlags.h:
-        (JSC::DFG::nodeMayOverflow):
-        (JSC::DFG::nodeMayNegZero):
-        (JSC::DFG::nodeCanSpeculateInt32):
-        (JSC::DFG::nodeCanSpeculateInt52):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::run):
-        (JSC::DFG::PredictionPropagationPhase::propagateToFixpoint):
-        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
-        (JSC::FTL::LowerDFGToLLVM::compileBooleanToNumber):
-        * runtime/JSCJSValue.h:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::asInt32ForArithmetic):
-        * tests/stress/max-boolean-exit.js: Added.
-        (foo):
-        (test):
-        * tests/stress/mul-boolean-exit.js: Added.
-        (foo):
-        (test):
-        * tests/stress/plus-boolean-exit.js: Added.
-        (foo):
-        (test):
-        * tests/stress/plus-boolean-or-double.js: Added.
-        (foo):
-        (test):
-        * tests/stress/plus-boolean-or-int.js: Added.
-        (foo):
-        (test):
-
-2014-05-26  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
-
-        Remove dead code from VM.cpp
-        https://bugs.webkit.org/show_bug.cgi?id=133284
-
-        Reviewed by Darin Adler.
-
-        This workaround was added in r127505. Since the clang is the
-        only used compiler in this case, this workaround is obsolete.
-
-        * runtime/VM.cpp:
-        (JSC::enableAssembler):
-
-2014-05-26  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        JSC CLoop warning fix
-        https://bugs.webkit.org/show_bug.cgi?id=133259
-
-        Reviewed by Darin Adler.
-
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-
-2014-05-24  Andreas Kling  <akling@apple.com>
-
-        Object.prototype.toString() should use cached strings for null/undefined.
-        <https://webkit.org/b/133261>
-
-        Normally, when calling Object.prototype.toString() on a regular object,
-        we'd cache the result of the stringification on the object's structure,
-        making repeated calls fast.
-
-        For null and undefined, we were not as smart. We'd instead construct a
-        new string with either "[object Null]" or "[object Undefined]" each time.
-
-        This was exposed by Dromaeo's JS library tests, where some prototype.js
-        subtests generate millions of strings this way.
-
-        This patch adds two VM-permanent cached strings to the SmallStrings.
-        Looks like ~10% speed-up on Dromaeo/jslib-traverse-prototype.html
-
-        Reviewed by Darin Adler.
-
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncToString):
-        * runtime/SmallStrings.cpp:
-        (JSC::SmallStrings::SmallStrings):
-        (JSC::SmallStrings::initializeCommonStrings):
-        (JSC::SmallStrings::visitStrongReferences):
-        * runtime/SmallStrings.h:
-        (JSC::SmallStrings::nullObjectString):
-        (JSC::SmallStrings::undefinedObjectString):
-
-2014-05-23  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Remove operationCallGetter
-
-        Rubber stamped by Filip Pizlo.
-
-        Nobody calls this function.
-
-        * JavaScriptCore.order:
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-
-2014-05-23  Andreas Kling  <akling@apple.com>
-
-        Templatize GC's destructor invocation for dtor type.
-        <https://webkit.org/b/133231>
-
-        Get rid of a branch in callDestructor() by templatizing it for
-        the DestructorType. Removed JSCell::methodTableForDestruction()
-        since this was the only call site and it was jumping through
-        a bunch of unnecessary hoops.
-
-        Reviewed by Geoffrey Garen.
-
-        * heap/MarkedBlock.cpp:
-        (JSC::MarkedBlock::callDestructor):
-        (JSC::MarkedBlock::specializedSweep):
-        * heap/MarkedBlock.h:
-        * runtime/JSCell.h:
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::methodTableForDestruction): Deleted.
-
-2014-05-23  Andreas Kling  <akling@apple.com>
-
-        Support inline caching of RegExpMatchesArray.length
-        <https://webkit.org/b/133234>
-
-        Give RegExpMatchesArray.length the same treatment as JSArray in
-        repatch so we don't have to go out of line on every access.
-
-        ~13% speed-up on Octane/regexp.
-
-        Reviewed by Geoffrey Garen.
-
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        * runtime/RegExpMatchesArray.h:
-        (JSC::isRegExpMatchesArray):
-
-2014-05-22  Mark Lam  <mark.lam@apple.com>
-
-        REGRESSION(r154797): Debugger crashes when stepping over an uncaught exception.
-        <https://webkit.org/b/133182>
-
-        Reviewed by Oliver Hunt.
-
-        Before r154797, we used to clear the VM exception before calling into the
-        debugger.  After r154797, we don't.  This patch will restore this clearing
-        of the exception before calling into the debugger.
-
-        Also added assertions after returning from calls into the debugger to
-        ensure that the debugger did not introduce any exceptions.
-
-        * interpreter/Interpreter.cpp:
-        (JSC::unwindCallFrame):
-        (JSC::Interpreter::unwind):
-        (JSC::Interpreter::debug):
-        - Fixed the assertion here.  Interpreter::debug() should never be called
-          with a pending exception.  Debugger callbacks for exceptions should be
-          handled by Interpreter::unwind() and Interpreter::unwindCallFrame().
-
-2014-05-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Store barrier elision should run after DCE in both the DFG path and the FTL path
-        https://bugs.webkit.org/show_bug.cgi?id=129718
-
-        Rubber stamped by Mark Hahnenberg.
-
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::compileInThreadImpl):
-
-2014-05-21  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
-
-        [EFL] Add include path of compact_unwind_encoding.h if FTL JIT is enabled
-        https://bugs.webkit.org/show_bug.cgi?id=132907
-
-        Reviewed by Gyuyoung Kim.
-
-        * CMakeLists.txt:
-
-2014-05-16  Martin Robinson  <mrobinson@igalia.com>
-
-        [CMake] Improve handling of LIB_INSTALL_DIR, EXEC_INSTALL_DIR, and LIBEXEC_INSTALL_DIR
-        https://bugs.webkit.org/show_bug.cgi?id=132819
-
-        Reviewed by Carlos Garcia Campos.
-
-        * javascriptcoregtk.pc.in: Instead of using the special pkg-config variables,
-        use the common CMake ones directly.
-
-2014-05-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, roll out http://trac.webkit.org/changeset/169159.
-        
-        This was a unilateral change and wasn't properly reviewed.
-
-        * tests/mozilla/mozilla-tests.yaml:
-
-2014-05-21  Antoine Quint  <graouts@webkit.org>
-
-        Array.prototype.find and findIndex should skip holes
-        https://bugs.webkit.org/show_bug.cgi?id=132658
-
-        Reviewed by Geoffrey Garen.
-
-        Skip holes in the array when iterating such that callback isn't called.
-
-        * builtins/Array.prototype.js:
-        (find):
-        (findIndex):
-
-2014-05-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
-
-        REGRESSION(r169092 and r169102): Skip failing JSC tests on ARM64 properly
-        https://bugs.webkit.org/show_bug.cgi?id=133149
-
-        Reviewed by Csaba Osztrogonác.
-
-        * tests/mozilla/mozilla-tests.yaml:
-
-2014-05-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Rolled out <http://trac.webkit.org/changeset/166184>
-        https://bugs.webkit.org/show_bug.cgi?id=133144
-
-        Reviewed by Gavin Barraclough.
-
-        It caused a performance regression.
-
-        * heap/BlockAllocator.cpp:
-        (JSC::BlockAllocator::blockFreeingThreadStartFunc):
-
-2014-05-20  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG prediction propagation should agree with fixup phase over the return type of GetByVal
-        https://bugs.webkit.org/show_bug.cgi?id=133134
-
-        Reviewed by Mark Hahnenberg.
-        
-        Make prediction propagator use ArrayMode refinement to decide the return type.
-        
-        Also introduce a heap prediction intrinsic that allows us to test weird corner cases
-        like this. The only way we'll see a mismatch like this in the real world is probably
-        through a gnarly race condition.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::setHeapPrediction):
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionFalse1):
-        (functionFalse2):
-        (functionUndefined1):
-        (functionUndefined2):
-        (functionFalse): Deleted.
-        (functionOtherFalse): Deleted.
-        (functionUndefined): Deleted.
-        * runtime/Intrinsic.h:
-        * tests/stress/get-by-val-double-predicted-int.js: Added.
-        (foo):
-
-2014-05-20  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Watchdog timer should be lazily allocated
-        https://bugs.webkit.org/show_bug.cgi?id=133135
-
-        Reviewed by Geoffrey Garen.
-
-        We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired. 
-        There is no reason to do this checking if we never activated the Watchdog, which can only be done through 
-        JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit. 
-
-        By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use 
-        these two API functions (which is true of most clients).
-
-        * API/JSContextRef.cpp:
-        (JSContextGroupSetExecutionTimeLimit):
-        (JSContextGroupClearExecutionTimeLimit):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * interpreter/Interpreter.cpp:
-        (JSC::Interpreter::execute):
-        (JSC::Interpreter::executeCall):
-        (JSC::Interpreter::executeConstruct):
-        * jit/JITOpcodes.cpp:
-        (JSC::JIT::emit_op_loop_hint):
-        (JSC::JIT::emitSlow_op_loop_hint):
-        * jit/JITOperations.cpp:
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * runtime/VM.h:
-        * runtime/Watchdog.cpp:
-        (JSC::Watchdog::Scope::Scope): Deleted.
-        (JSC::Watchdog::Scope::~Scope): Deleted.
-        * runtime/Watchdog.h:
-        (JSC::Watchdog::Scope::Scope):
-        (JSC::Watchdog::Scope::~Scope):
-
-2014-05-19  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSArray::shiftCountWith* could be more efficient
-        https://bugs.webkit.org/show_bug.cgi?id=133011
-
-        Reviewed by Geoffrey Garen.
-
-        Our current implementations of shiftCountWithAnyIndexingType and shiftCountWithArrayStorage 
-        are scared of the presence of any holes in the array. We can mitigate this somewhat by enabling 
-        them to correctly handle holes, thus avoiding the slowest of slow paths in most cases.
-
-        * runtime/ArrayStorage.h:
-        (JSC::ArrayStorage::indexingHeader):
-        (JSC::ArrayStorage::length):
-        (JSC::ArrayStorage::hasHoles):
-        * runtime/IndexingHeader.h:
-        (JSC::IndexingHeader::publicLength):
-        (JSC::IndexingHeader::from):
-        * runtime/JSArray.cpp:
-        (JSC::JSArray::shiftCountWithArrayStorage):
-        (JSC::JSArray::shiftCountWithAnyIndexingType):
-        (JSC::JSArray::unshiftCountWithArrayStorage):
-        * runtime/JSArray.h:
-        (JSC::JSArray::shiftCountForShift):
-        (JSC::JSArray::shiftCountForSplice):
-        (JSC::JSArray::shiftCount):
-        * runtime/Structure.cpp:
-        (JSC::Structure::holesRequireSpecialBehavior):
-        * runtime/Structure.h:
-
-2014-05-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Test gardening: skip some failing tests on not-X86.
-
-        * tests/mozilla/mozilla-tests.yaml:
-
-2014-05-19  Mark Lam  <mark.lam@apple.com>
-
-        operationOptimize() should defer the GC for a while.
-        <https://webkit.org/b/133103>
-
-        Reviewed by Filip Pizlo.
-
-        Currently, operationOptimize() only defers the GC until its end.  As a result,
-        a GC may be triggered just before we return from operationOptimize(), and it may
-        jettison the optimize codeBlock that we're planning to OSR enter into when we
-        return from this function.  This is because the OSR entry on-ramp code hasn't
-        been executed yet, and hence, there is not yet a reference to this new codeBlock
-        from the stack, and there won't be until we've had a chance to return out of
-        operationOptimize() to run the OSR entry on-ramp code.
-
-        This issue is now fixed by using DeferGCForAWhile instead of DeferGC.  This
-        ensures that the GC will be deferred until after the OSR entry on-ramp can be
-        executed.
-
-        * jit/JITOperations.cpp:
-
-2014-05-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Take care of some ARM64 test failures
-        https://bugs.webkit.org/show_bug.cgi?id=133090
-
-        Reviewed by Geoffrey Garen.
-        
-        Constant blinding on ARM64 cannot use the scratch register.
-
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::convertInt32ToDouble):
-        (JSC::MacroAssembler::branchPtr):
-        (JSC::MacroAssembler::storePtr):
-        (JSC::MacroAssembler::store64):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::scratchRegisterForBlinding):
-
-2014-05-19  Tanay C  <tanay.c@samsung.com>
-
-        Removing some check-webkit-style warnings from ./dfg
-        https://bugs.webkit.org/show_bug.cgi?id=132854
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGAbstractInterpreter.h:
-        * dfg/DFGAbstractValue.h:
-        * dfg/DFGBlockInsertionSet.h:
-        * dfg/DFGCommonData.h:
-        * dfg/DFGDominators.h:
-        * dfg/DFGGraph.h:
-        * dfg/DFGInPlaceAbstractState.h:
-        * dfg/DFGPredictionPropagationPhase.h:
-
-2014-05-18  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, remove bogus comment. We already made the FTL use our calling convention.
-        That was a long time ago.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileReturn):
-
-2014-05-18  Rik Cabanier  <cabanier@adobe.com>
-
-        support for navigator.hardwareConcurrency
-        https://bugs.webkit.org/show_bug.cgi?id=132588
-
-        Reviewed by Filip Pizlo.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-05-16  Michael Saboff  <msaboff@apple.com>
-
-        Crash in JSC::Yarr::YarrGenerator<(JSC::Yarr::YarrJITCompileMode)0>::generatePatternCharacterFixed() due to WTF::CrashOnOverflow::overflowed + 9
-        https://bugs.webkit.org/show_bug.cgi?id=133009
-
-        Reviewed by Oliver Hunt.
-
-        If we determine that any alternative requires a minumum match size greater than
-        INT_MAX, we handle the match in the interpreter.
-
-        Check to see if the pattern has unsigned lengths before invoking YARR JIT.
-        * runtime/RegExp.cpp:
-        (JSC::RegExp::compile):
-        (JSC::RegExp::compileMatchOnly):
-
-        * tests/stress/large-regexp.js: New test added.
-
-        Set m_containsUnsignedLengthPattern flag if any alternative's minimum length
-        doesn't fit in an int.
-        * yarr/YarrPattern.cpp:
-        (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
-
-        Clear new m_containsUnsignedLengthPattern flag.
-        * yarr/YarrPattern.cpp:
-        (JSC::Yarr::YarrPattern::YarrPattern):
-        * yarr/YarrPattern.h:
-        (JSC::Yarr::YarrPattern::reset):
-        (JSC::Yarr::YarrPattern::containsUnsignedLengthPattern):
-
-2014-05-15  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSDOMWindow should not claim HasImpureGetOwnPropertySlot
-        https://bugs.webkit.org/show_bug.cgi?id=132918
-
-        Reviewed by Geoffrey Garen.
-
-        * jit/Repatch.cpp:
-        (JSC::tryRepatchIn): We forgot to check for watchpoints when repatching "in".
-
-2014-05-15  Alex Christensen  <achristensen@webkit.org>
-
-        Add pointer lock to features without enabling it.
-        https://bugs.webkit.org/show_bug.cgi?id=132961
-
-        Reviewed by Sam Weinig.
-
-        * Configurations/FeatureDefines.xcconfig:
-        Added ENABLE_POINTER_LOCK to list of features.
-
-2014-05-14  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Inline caching for proxies clobbers baseGPR too early
-        https://bugs.webkit.org/show_bug.cgi?id=132916
-
-        Reviewed by Filip Pizlo.
-
-        We clobber baseGPR prior to the Structure checks, so if any of the checks fail then the slow path 
-        gets the target of the proxy rather than the proxy itself. We need to delay the clobbering of baseGPR 
-        until we know the inline cache is going to succeed.
-
-        * jit/Repatch.cpp:
-        (JSC::generateByIdStub):
-
-2014-05-14  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Unreviewed build fix.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: This solution
-        was missing commands to build LLInt portions of JSC.
-        * llint/LLIntData.cpp: 64-bit build fix.
-
-2014-05-14  Martin Hodovan <mhodovan.u-szeged@partner.samsung.com>
-
-        ARM Traditional buildfix after r168776.
-        https://bugs.webkit.org/show_bug.cgi?id=132903
-
-        Reviewed by Darin Adler.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::abortWithReason): Added.
-
-2014-05-14  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Remove CSS_STICKY_POSITION guards
-        https://bugs.webkit.org/show_bug.cgi?id=132676
-
-        Reviewed by Simon Fraser.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-05-13  Filip Pizlo  <fpizlo@apple.com>
-
-        JIT breakpoints should be more informative
-        https://bugs.webkit.org/show_bug.cgi?id=132882
-
-        Reviewed by Oliver Hunt.
-        
-        Introduce the notion of an AbortReason, which is a nice enumeration of coded assertion
-        failure names. This means that all you need to figure out why the JIT SIGTRAP'd is to look
-        at that platform's abort reason register (r11 on X86-64 for example).
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * assembler/AbortReason.h: Added.
-        * assembler/AbstractMacroAssembler.h:
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::abortWithReason):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::abortWithReason):
-        * assembler/MacroAssemblerX86.h:
-        (JSC::MacroAssemblerX86::abortWithReason):
-        * assembler/MacroAssemblerX86_64.h:
-        (JSC::MacroAssemblerX86_64::abortWithReason):
-        * dfg/DFGSlowPathGenerator.h:
-        (JSC::DFG::SlowPathGenerator::generate):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::bail):
-        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
-        (JSC::DFG::SpeculativeJIT::compileMakeRope):
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGThunks.cpp:
-        (JSC::DFG::osrEntryThunkGenerator):
-        * jit/AssemblyHelpers.cpp:
-        (JSC::AssemblyHelpers::jitAssertIsInt32):
-        (JSC::AssemblyHelpers::jitAssertIsJSInt32):
-        (JSC::AssemblyHelpers::jitAssertIsJSNumber):
-        (JSC::AssemblyHelpers::jitAssertIsJSDouble):
-        (JSC::AssemblyHelpers::jitAssertIsCell):
-        (JSC::AssemblyHelpers::jitAssertTagsInPlace):
-        (JSC::AssemblyHelpers::jitAssertHasValidCallFrame):
-        (JSC::AssemblyHelpers::jitAssertIsNull):
-        (JSC::AssemblyHelpers::jitAssertArgumentCountSane):
-        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::checkStackPointerAlignment):
-        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): Deleted.
-        * jit/JIT.h:
-        * jit/JITArithmetic.cpp:
-        (JSC::JIT::emitSlow_op_div):
-        * jit/JITOpcodes.cpp:
-        (JSC::JIT::emitSlow_op_loop_hint):
-        * jit/JITOpcodes32_64.cpp:
-        (JSC::JIT::privateCompileCTINativeCall):
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emit_op_get_by_val):
-        (JSC::JIT::compileGetDirectOffset):
-        (JSC::JIT::addStructureTransitionCheck): Deleted.
-        (JSC::JIT::testPrototype): Deleted.
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emit_op_get_by_val):
-        (JSC::JIT::compileGetDirectOffset):
-        * jit/RegisterPreservationWrapperGenerator.cpp:
-        (JSC::generateRegisterRestoration):
-        * jit/Repatch.cpp:
-        (JSC::addStructureTransitionCheck):
-        (JSC::linkClosureCall):
-        * jit/ThunkGenerators.cpp:
-        (JSC::emitPointerValidation):
-        (JSC::nativeForGenerator):
-        * yarr/YarrJIT.cpp:
-        (JSC::Yarr::YarrGenerator::generate):
-
-2014-05-13  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win] Enum type with value zero is compatible with void*, potential cause of crashes.
-        https://bugs.webkit.org/show_bug.cgi?id=132772
-
-        Reviewed by Geoffrey Garen.
-
-        Using the MSVC compiler, an instance of an enum type with value zero, is compatible with void* (see bug 132683 for a code example).
-        This has caused crashes on Windows on two occasions (bug 132683, and bug 121001).
-        This patch tries to prevent these type of crashes by using a type with explicit constructors instead of void*.
-        The void* parameter in the loadDouble and storeDouble methods are replaced with TrustedImmPtr.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::loadDouble):
-        (JSC::MacroAssemblerARM::storeDouble):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::loadDouble):
-        (JSC::MacroAssemblerARM64::storeDouble):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::loadDouble):
-        (JSC::MacroAssemblerARMv7::storeDouble):
-        * assembler/MacroAssemblerMIPS.h:
-        (JSC::MacroAssemblerMIPS::loadDouble):
-        (JSC::MacroAssemblerMIPS::storeDouble):
-        * assembler/MacroAssemblerSH4.h:
-        (JSC::MacroAssemblerSH4::loadDouble):
-        (JSC::MacroAssemblerSH4::storeDouble):
-        * assembler/MacroAssemblerX86.h:
-        (JSC::MacroAssemblerX86::storeDouble):
-        * assembler/MacroAssemblerX86Common.h:
-        (JSC::MacroAssemblerX86Common::absDouble):
-        (JSC::MacroAssemblerX86Common::negateDouble):
-        (JSC::MacroAssemblerX86Common::loadDouble):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::silentFill):
-        (JSC::DFG::compileClampDoubleToByte):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * jit/AssemblyHelpers.cpp:
-        (JSC::AssemblyHelpers::purifyNaN):
-        * jit/JITInlines.h:
-        (JSC::JIT::emitLoadDouble):
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emitFloatTypedArrayGetByVal):
-        * jit/ThunkGenerators.cpp:
-        (JSC::floorThunkGenerator):
-        (JSC::roundThunkGenerator):
-        (JSC::powThunkGenerator):
-
-2014-05-12  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r168642.
-        https://bugs.webkit.org/show_bug.cgi?id=132839
-
-        Broke ARM build (Requested by jpfau on #webkit).
-
-        Reverted changeset:
-
-        "[Win] Enum type with value zero is compatible with void*,
-        potential cause of crashes."
-        https://bugs.webkit.org/show_bug.cgi?id=132772
-        http://trac.webkit.org/changeset/168642
-
-2014-05-12  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win] Enum type with value zero is compatible with void*, potential cause of crashes.
-        https://bugs.webkit.org/show_bug.cgi?id=132772
-
-        Reviewed by Geoffrey Garen.
-
-        Using the MSVC compiler, an instance of an enum type with value zero, is compatible with void* (see bug 132683 for a code example).
-        This has caused crashes on Windows on two occasions (bug 132683, and bug 121001).
-        This patch tries to prevent these type of crashes by using a type with explicit constructors instead of void*.
-        The void* parameter in the loadDouble and storeDouble methods are replaced with TrustedImmPtr.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::loadDouble):
-        (JSC::MacroAssemblerARM::storeDouble):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::loadDouble):
-        (JSC::MacroAssemblerARM64::storeDouble):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::loadDouble):
-        (JSC::MacroAssemblerARMv7::storeDouble):
-        * assembler/MacroAssemblerMIPS.h:
-        (JSC::MacroAssemblerMIPS::loadDouble):
-        (JSC::MacroAssemblerMIPS::storeDouble):
-        * assembler/MacroAssemblerSH4.h:
-        (JSC::MacroAssemblerSH4::loadDouble):
-        (JSC::MacroAssemblerSH4::storeDouble):
-        * assembler/MacroAssemblerX86.h:
-        (JSC::MacroAssemblerX86::storeDouble):
-        * assembler/MacroAssemblerX86Common.h:
-        (JSC::MacroAssemblerX86Common::absDouble):
-        (JSC::MacroAssemblerX86Common::negateDouble):
-        (JSC::MacroAssemblerX86Common::loadDouble):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::silentFill):
-        (JSC::DFG::compileClampDoubleToByte):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * jit/AssemblyHelpers.cpp:
-        (JSC::AssemblyHelpers::purifyNaN):
-        * jit/JITInlines.h:
-        (JSC::JIT::emitLoadDouble):
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emitFloatTypedArrayGetByVal):
-        * jit/ThunkGenerators.cpp:
-        (JSC::floorThunkGenerator):
-        (JSC::roundThunkGenerator):
-        (JSC::powThunkGenerator):
-
-2014-05-12  Andreas Kling  <akling@apple.com>
-
-        0.4% of PLT3 in JSCell::structure() below JSObject::visitChildren().
-        <https://webkit.org/b/132828>
-        <rdar://problem/16886285>
-
-        Reviewed by Michael Saboff.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::visitButterfly):
-        (JSC::JSObject::visitChildren):
-
-            Use JSCell::structure(VM&) to reduce the number of hoops we jump
-            through to find Structures during marking.
-
-2014-05-12  László Langó  <llango.u-szeged@partner.samsung.com>
-
-        [cmake] Add missing FTL source files to the build system.
-
-        Reviewed by Csaba Osztrogonác.
-
-        * CMakeLists.txt:
-
-2014-05-09  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Allow Remote Inspector to entitlement check UIProcess through WebProcess
-        https://bugs.webkit.org/show_bug.cgi?id=132409
-
-        Reviewed by Timothy Hatcher.
-
-        Proxy applications are applications which hold WebViews for other
-        applications. The WebProcess (Web Content Service) is a proxy application.
-        For legacy reasons we were supporting a scenario where proxy applications
-        could potentially host WebViews for more then one other application. That
-        was never the case for WebProcess and it is now a scenario we don't need
-        to worry about supporting.
-
-        With this change, a proxy application more naturally only holds WebViews
-        for a single parent / host application. The proxy process can set the
-        parent pid / audit_token data on the RemoteInspector singleton, and
-        that data will be sent on to webinspectord later on to be validated.
-        In the WebProcess<->UIProcess relationship that information is known
-        and set immediately. In the Legacy iOS case that information is set
-        soon after, but not immediately known at the point the WebView is created.
-
-        This allows us to simplify the RemoteInspectorDebuggable interface.
-        We no longer need a pid per-Debuggable.
-
-        * inspector/remote/RemoteInspector.h:
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::RemoteInspector):
-        (Inspector::RemoteInspector::setParentProcessInformation):
-        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
-        (Inspector::RemoteInspector::listingForDebuggable):
-        (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage):
-        Handle new proxy application setup message, and provide an API
-        for a proxy application to set the parent process information.
-
-        * inspector/remote/RemoteInspectorConstants.h:
-        New setup and response message for proxy applications to pass
-        their parent / host application information to webinspectord.
-
-        * inspector/remote/RemoteInspectorDebuggable.cpp:
-        (Inspector::RemoteInspectorDebuggable::info):
-        * inspector/remote/RemoteInspectorDebuggable.h:
-        (Inspector::RemoteInspectorDebuggableInfo::RemoteInspectorDebuggableInfo):
-        (Inspector::RemoteInspectorDebuggableInfo::hasParentProcess): Deleted.
-        pid per debuggable is no longer needed.
-
-2014-05-09  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSDOMWindow should disable property caching after a certain point
-        https://bugs.webkit.org/show_bug.cgi?id=132751
-
-        Reviewed by Filip Pizlo.
-
-        This is part of removing HasImpureGetOwnPropertySlot from JSDOMWindow. After the lookup in the static 
-        hash table for JSDOMWindow fails we want to disable property caching even if the code that follows thinks 
-        that it has provided a cacheable value.
-
-        * runtime/PropertySlot.h:
-        (JSC::PropertySlot::PropertySlot):
-        (JSC::PropertySlot::isCacheable):
-        (JSC::PropertySlot::disableCaching):
-
-2014-05-09  Andreas Kling  <akling@apple.com>
-
-        8.8% spent in Object.prototype.hasOwnProperty() on sbperftest.
-        <https://webkit.org/b/132749>
-
-        Leverage the fast-resolve-to-AtomicString optimization for JSRopeString
-        in Object.prototype.* by using JSString::toIdentifier() in the cases where
-        we are converting JSString -> String -> Identifier.
-
-        This brings time spent in hasOwnProperty() from 8.8% to 1.3% on
-        "The Great HTML5 Gaming Performance Test: 2014 edition"
-        <http://www.scirra.com/demos/c2/sbperftest/>
-
-        Reviewed by Oliver Hunt.
-
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncHasOwnProperty):
-        (JSC::objectProtoFuncDefineGetter):
-        (JSC::objectProtoFuncDefineSetter):
-        (JSC::objectProtoFuncLookupGetter):
-        (JSC::objectProtoFuncLookupSetter):
-
-2014-05-08  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSDOMWindow should have a WatchpointSet to fire on window close
-        https://bugs.webkit.org/show_bug.cgi?id=132721
-
-        Reviewed by Filip Pizlo.
-
-        This patch allows us to reset the inline caches that assumed they could skip 
-        the first part of JSDOMWindow::getOwnPropertySlot that checks if the window has 
-        been closed. This is part of getting rid of HasImpureGetOwnPropertySlot on JSDOMWindow.
-
-        PropertySlot now accepts a WatchpointSet which the inline cache code can look for
-        to see if it should create a new Watchpoint for that particular inline cache site.
-
-        * bytecode/Watchpoint.h:
-        * jit/Repatch.cpp:
-        (JSC::generateByIdStub):
-        (JSC::tryBuildGetByIDList):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * runtime/PropertySlot.h:
-        (JSC::PropertySlot::PropertySlot):
-        (JSC::PropertySlot::watchpointSet):
-        (JSC::PropertySlot::setWatchpointSet):
-
-2014-05-09  Tanay C  <tanay.c@samsung.com>
-
-        Fix build warning (uninitialized variable) in DFGFixupPhase.cpp 
-        https://bugs.webkit.org/show_bug.cgi?id=132331
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-
-2014-05-09  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win] Crash when enabling DFG JIT.
-        https://bugs.webkit.org/show_bug.cgi?id=132683
-
-        Reviewed by Geoffrey Garen.
-
-        On windows, using register GPRInfo::regT0 as parameter to e.g. JIT::storeDouble(..., GPRInfo::regT0)),
-        results in a call to JIT::storeDouble(FPRegisterID src, const void* address),
-        where the address parameter gets the value of GPRInfo::regT0, which is 0 (eax on Windows).
-        This causes the register to be written to address 0, hence the crash.
-
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit): Use address in regT0 as parameter.
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit): Ditto.
-
-2014-05-09  Martin Hodovan <mhodovan.u-szeged@partner.samsung.com>
-
-        REGRESSION(r167094): JSC crashes on ARM Traditional
-        https://bugs.webkit.org/show_bug.cgi?id=132738
-
-        Reviewed by Zoltan Herczeg.
-
-        PC is two instructions ahead of the current instruction
-        on ARM Traditional, so the distance is 8 bytes not 2.
-
-        * llint/LowLevelInterpreter.asm:
-
-2014-05-09  Alberto Garcia  <berto@igalia.com>
-
-        jsmin.py license header confusing, mentions non-free license
-        https://bugs.webkit.org/show_bug.cgi?id=123665
-
-        Reviewed by Darin Adler.
-
-        Pull the most recent version from upstream, which has a clear
-        license.
-
-        * inspector/scripts/jsmin.py:
-
-2014-05-08  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Base case for get-by-id inline cache doesn't check for HasImpureGetOwnPropertySlot
-        https://bugs.webkit.org/show_bug.cgi?id=132695
-
-        Reviewed by Filip Pizlo.
-
-        We check in the case where we're accessing something other than the base object (e.g. the prototype), 
-        but we fail to do so for the base object.
-
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        * jsc.cpp: Added some infrastructure to support this test. We don't currently trigger this bug anywhere in WebKit
-        because all of the values that are returned that could be impure are set to uncacheable anyways.
-        (WTF::ImpureGetter::ImpureGetter):
-        (WTF::ImpureGetter::createStructure):
-        (WTF::ImpureGetter::create):
-        (WTF::ImpureGetter::finishCreation):
-        (WTF::ImpureGetter::getOwnPropertySlot):
-        (WTF::ImpureGetter::visitChildren):
-        (WTF::ImpureGetter::setDelegate):
-        (GlobalObject::finishCreation):
-        (functionCreateImpureGetter):
-        (functionSetImpureGetterDelegate):
-        * tests/stress/impure-get-own-property-slot-inline-cache.js: Added.
-        (foo):
-
-2014-05-08  Filip Pizlo  <fpizlo@apple.com>
-
-        deleteAllCompiledCode() shouldn't use the suspension worklist
-        https://bugs.webkit.org/show_bug.cgi?id=132708
-
-        Reviewed by Mark Hahnenberg.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::isStillValid):
-        * heap/Heap.cpp:
-        (JSC::Heap::deleteAllCompiledCode):
-
-2014-05-08  Filip Pizlo  <fpizlo@apple.com>
-
-        SSA conversion should delete PhantomLocals for captured variables
-        https://bugs.webkit.org/show_bug.cgi?id=132693
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGCommon.cpp:
-        (JSC::DFG::startCrashing): Parallel JIT and a JIT bug means that we man dump IR in parallel. This is the workaround. This patch uses it in all of the places where we dump IR and crash.
-        * dfg/DFGCommon.h:
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge): Use the workaround.
-        * dfg/DFGLivenessAnalysisPhase.cpp:
-        (JSC::DFG::LivenessAnalysisPhase::run): Use the workaround.
-        * dfg/DFGSSAConversionPhase.cpp:
-        (JSC::DFG::SSAConversionPhase::run): Fix the bug - it's true that PhantomLocal for captured variables doesn't need anything done to it, but it's wrong that we didn't delete it outright.
-        * dfg/DFGValidate.cpp: Use the workaround.
-        * tests/stress/phantom-local-captured-but-not-flushed-to-ssa.js: Added.
-        (foo):
-        (bar):
-
-2014-05-07  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r168451.
-        https://bugs.webkit.org/show_bug.cgi?id=132670
-
-        Not a speed-up, just do what other compilers do. (Requested by
-        kling on #webkit).
-
-        Reverted changeset:
-
-        "[X86] Emit BT instruction for single-bit tests."
-        https://bugs.webkit.org/show_bug.cgi?id=132650
-        http://trac.webkit.org/changeset/168451
-
-2014-05-07  Filip Pizlo  <fpizlo@apple.com>
-
-        Make Executable::clearCode() actually clear all of the entrypoints, and
-        clean up some other FTL-related calling convention stuff.
-        <rdar://problem/16720172>
-
-        Rubber stamped by Mark Hahnenberg.
-
-        * dfg/DFGOperations.cpp:
-        * dfg/DFGOperations.h:
-        * dfg/DFGWorklist.cpp:
-        (JSC::DFG::Worklist::Worklist):
-        (JSC::DFG::Worklist::finishCreation):
-        (JSC::DFG::Worklist::create):
-        (JSC::DFG::ensureGlobalDFGWorklist):
-        (JSC::DFG::ensureGlobalFTLWorklist):
-        * dfg/DFGWorklist.h:
-        * heap/CodeBlockSet.cpp:
-        (JSC::CodeBlockSet::dump):
-        * heap/CodeBlockSet.h:
-        * runtime/Executable.cpp:
-        (JSC::ExecutableBase::clearCode):
-
-2014-05-07  Andreas Kling  <akling@apple.com>
-
-        [X86] Emit BT instruction for single-bit tests.
-        <https://webkit.org/b/132650>
-
-        Implement test-bit-and-branch slightly more efficiently by using
-        BT + JC/JNC instead of TEST + JZ/JNZ when we're only testing for
-        a single bit.
-
-        Reviewed by Michael Saboff.
-
-        * assembler/MacroAssemblerX86Common.h:
-        (JSC::MacroAssemblerX86Common::singleBitIndex):
-        (JSC::MacroAssemblerX86Common::branchTest32):
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::bt_i8r):
-        (JSC::X86Assembler::bt_i8m):
-
-2014-05-07  Mark Lam  <mark.lam@apple.com>
-
-        REGRESSION(r166678): Dromaeo/cssquery-dojo.html crashes regularly.
-        <https://webkit.org/b/131356>
-
-        Reviewed by Geoffrey Garen.
-
-        The issue is that GC needs to be made aware of writes to m_inferredValue
-        in the VariableWatchpointSet, but was not.  As a result, if a JSCell*
-        is written to a VariableWatchpointSet m_inferredValue, and that JSCell
-        does not survive an eden GC shortly after, we will end up with a stale
-        JSCell pointer left in the m_inferredValue.
-
-        This issue can be detected more easily by running Dromaeo/cssquery-dojo.html
-        using DumpRenderTree with the VM heap in zombie mode.
-
-        The fix is to change VariableWatchpointSet m_inferredValue to type
-        WriteBarrier<Unknown> and ensure that VariableWatchpointSet::notifyWrite()
-        is executed by all the execution engines so that the WriteBarrier semantics
-        are honored.
-
-        We still check if the value to be written is the same as the one in the
-        inferredValue.  We'll by-pass calling the slow path notifyWrite() if the
-        values are the same.        
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::CodeBlock):
-        - need to pass the symbolTable to prepareToWatch() because it will be needed
-          for instantiating the VariableWatchpointSet in prepareToWatch().
-
-        * bytecode/VariableWatchpointSet.h:
-        (JSC::VariableWatchpointSet::VariableWatchpointSet):
-        - VariableWatchpointSet now tracks its owner symbol table for its m_inferredValue
-          write barrier, and yes, m_inferredValue is now of type WriteBarrier<Unknown>.
-        (JSC::VariableWatchpointSet::inferredValue):
-        (JSC::VariableWatchpointSet::invalidate):
-        (JSC::VariableWatchpointSet::finalizeUnconditionally):
-        (JSC::VariableWatchpointSet::addressOfInferredValue):
-        (JSC::VariableWatchpointSet::notifyWrite): Deleted.
-        * bytecode/VariableWatchpointSetInlines.h: Added.
-        (JSC::VariableWatchpointSet::notifyWrite):
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::cellConstant):
-        - Added an assert in case we try to make constants of zombified JSCells again.
-
-        * dfg/DFGOperations.cpp:
-        * dfg/DFGOperations.h:
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::callOperation):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        - We now let the slow path handle the cases when the VariableWatchpointSet is
-          in state ClearWatchpoint and IsWatched, and the slow path will ensure that
-          we handle the needed write barrier semantics correctly.
-          We will by-pass the slow path if the value being written is the same as the
-          inferred value.
-
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNotifyWrite):
-        - Let the slow path handle the cases when the VariableWatchpointSet is
-          in state ClearWatchpoint and IsWatched.
-          We will by-pass the slow path if the value being written is the same as the
-          inferred value.
-
-        * heap/Heap.cpp:
-        (JSC::Zombify::operator()):
-        - Use a different value for the zombified bits (to distinguish it from 0xbbadbeef
-          which is used everywhere else).
-        * heap/Heap.h:
-        (JSC::Heap::isZombified):
-        - Provide a convenience test function to check if JSCells are zombified.  This is
-          currently only used in an assertion in the DFG bytecode parser, but the intent
-          it that we'll apply this test in other strategic places later to help with early
-          detection of usage of GC'ed objects when we run in zombie mode.
-
-        * jit/JITOpcodes.cpp:
-        (JSC::JIT::emitSlow_op_captured_mov):
-        * jit/JITOperations.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emitNotifyWrite):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emitNotifyWrite):
-        (JSC::JIT::emitSlow_op_put_to_scope):
-        - Let the slow path for notifyWrite handle the cases when the VariableWatchpointSet
-          is in state ClearWatchpoint and IsWatched.
-          We will by-pass the slow path if the value being written is the same as the
-          inferred value.
-        
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-        - Let the slow path for notifyWrite handle the cases when the VariableWatchpointSet
-          is in state ClearWatchpoint and IsWatched.
-          We will by-pass the slow path if the value being written is the same as the
-          inferred value.
-        
-        * runtime/CommonSlowPaths.cpp:
-
-        * runtime/JSCJSValue.h: Fixed some typos in the comments.
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::addGlobalVar):
-        (JSC::JSGlobalObject::addFunction):
-        * runtime/JSSymbolTableObject.h:
-        (JSC::symbolTablePut):
-        (JSC::symbolTablePutWithAttributes):
-        * runtime/SymbolTable.cpp:
-        (JSC::SymbolTableEntry::prepareToWatch):
-        (JSC::SymbolTableEntry::notifyWriteSlow):
-        * runtime/SymbolTable.h:
-        (JSC::SymbolTableEntry::notifyWrite):
-
-2014-05-06  Michael Saboff  <msaboff@apple.com>
-
-        Unreviewd build fix for C-LOOP after r168396.
-
-        * runtime/TestRunnerUtils.cpp:
-        (JSC::optimizeNextInvocation): Wrapped actual call inside #if ENABLE(JIT)
-
-2014-05-06  Michael Saboff  <msaboff@apple.com>
-
-        Add test for deleteAllCompiledCode
-        https://bugs.webkit.org/show_bug.cgi?id=132632
-
-        Reviewed by Phil Pizlo.
-
-        Added two new hooks to jsc, one to call Heap::deleteAllCompiledCode() and
-        the other to call CodeBlock::optimizeNextInvocation().  Used these two hooks
-        to write a test that will queue up loads of DFG compiles and then call
-        Heap::deleteAllCompiledCode() to make sure that it can handle compiled
-        code as well as code being compiled.
-
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionDeleteAllCompiledCode):
-        (functionOptimizeNextInvocation):
-        * runtime/TestRunnerUtils.cpp:
-        (JSC::optimizeNextInvocation):
-        * runtime/TestRunnerUtils.h:
-        * tests/stress/deleteAllCompiledCode.js: Added.
-        (functionList):
-        (runTest):
-
-2014-05-06  Andreas Kling  <akling@apple.com>
-
-        JSString::toAtomicString() should return AtomicString.
-        <https://webkit.org/b/132627>
-
-        Remove premature optimization where I was trying to avoid refcount
-        churn when returning an already atomicized String.
-
-        Instead of using reinterpret_cast to mangle the String member into
-        a const AtomicString& return value, just return AtomicString.
-
-        Reviewed by Geoff Garen.
-
-        * runtime/JSString.h:
-        (JSC::JSString::toAtomicString):
-
-2014-05-06  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Roll out r167889
-
-        Rubber stamped by Geoff Garen.
-
-        It broke some websites.
-
-        * runtime/JSPropertyNameIterator.cpp:
-        (JSC::JSPropertyNameIterator::create):
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::hasDeletedOffset):
-        (JSC::PropertyTable::hadDeletedOffset): Deleted.
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::materializePropertyMap):
-        (JSC::Structure::removePropertyTransition):
-        (JSC::Structure::changePrototypeTransition):
-        (JSC::Structure::despecifyFunctionTransition):
-        (JSC::Structure::attributeChangeTransition):
-        (JSC::Structure::toDictionaryTransition):
-        (JSC::Structure::preventExtensionsTransition):
-        (JSC::Structure::addPropertyWithoutTransition):
-        (JSC::Structure::removePropertyWithoutTransition):
-        (JSC::Structure::pin):
-        (JSC::Structure::pinAndPreventTransitions): Deleted.
-        * runtime/Structure.h:
-        * runtime/StructureInlines.h:
-        (JSC::Structure::setEnumerationCache):
-        (JSC::Structure::propertyTable):
-        (JSC::Structure::checkOffsetConsistency):
-        (JSC::Structure::hadDeletedOffsets): Deleted.
-        * tests/stress/for-in-after-delete.js:
-        (foo): Deleted.
-
-2014-05-05  Andreas Kling  <akling@apple.com>
-
-        Fix debug build.
-
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::fastGetOwnProperty):
-
-2014-05-05  Andreas Kling  <akling@apple.com>
-
-        Optimize GetByVal when subscript is a rope string.
-        <https://webkit.org/b/132590>
-
-        Use JSString::toIdentifier() in the various GetByVal implementations
-        to try and avoid allocating extra strings.
-
-        Added canUseFastGetOwnProperty() and wrap calls to fastGetOwnProperty()
-        in that, to avoid calling JSString::value() which always resolves ropes
-        into new strings and de-optimizes subsequent toIdentifier() calls.
-
-        My iMac says ~9% progression on Dromaeo/dom-attr.html
-
-        Reviewed by Phil Pizlo.
-
-        * dfg/DFGOperations.cpp:
-        * jit/JITOperations.cpp:
-        (JSC::getByVal):
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::getByVal):
-        * runtime/JSCell.h:
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::fastGetOwnProperty):
-        (JSC::JSCell::canUseFastGetOwnProperty):
-
-2014-05-05  Andreas Kling  <akling@apple.com>
-
-        REGRESSION (r168256): ASSERTION FAILED: (buffer + m_length) == position loading vanityfair.com article.
-        <https://webkit.org/b/168256>
-        <rdar://problem/16816316>
-
-        Make resolveRopeSlowCase8() behave like its 16-bit counterpart and not
-        clear the fibers. The caller takes care of this.
-
-        Test: fast/dom/getElementById-with-rope-string-arg.html
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/JSString.cpp:
-        (JSC::JSRopeString::resolveRopeSlowCase8):
-
-2014-05-05  Michael Saboff  <msaboff@apple.com>
-
-        REGRESSION: RELEASE_ASSERT in CodeBlock::baselineVersion @ cnn.com
-        https://bugs.webkit.org/show_bug.cgi?id=132581
-
-        Reviewed by Filip Pizlo.
-
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::isStillValid): Check that the alternative codeBlock we
-        started compiling for is still the same at the end of compilation.
-        Also did some minor restructuring.
-
-2014-05-05  Andreas Kling  <akling@apple.com>
-
-        Optimize PutByVal when subscript is a rope string.
-        <https://webkit.org/b/132572>
-
-        Add a JSString::toIdentifier() that is smarter when the JSString is
-        really a rope string. Use this in baseline & DFG's PutByVal to avoid
-        allocating new StringImpls that we immediately deduplicate anyway.
-
-        Reviewed by Antti Koivisto.
-
-        * dfg/DFGOperations.cpp:
-        (JSC::DFG::operationPutByValInternal):
-        * jit/JITOperations.cpp:
-        * runtime/JSString.h:
-        (JSC::JSString::toIdentifier):
-
-2014-05-05  Andreas Kling  <akling@apple.com>
-
-        Remove two now-incorrect assertions after r168256.
-
-        * runtime/JSString.cpp:
-        (JSC::JSRopeString::resolveRopeSlowCase8):
-        (JSC::JSRopeString::resolveRopeSlowCase):
-
-2014-05-04  Andreas Kling  <akling@apple.com>
-
-        Optimize JSRopeString for resolving directly to AtomicString.
-        <https://webkit.org/b/132548>
-
-        If we know that the JSRopeString we are resolving is going to be used
-        as an AtomicString, we can try to avoid creating a new string.
-
-        We do this by first resolving the rope into a stack buffer, and using
-        that buffer as a key into the AtomicString table. If there is already
-        an AtomicString with the same characters, we reuse that instead of
-        constructing a new StringImpl.
-
-        JSString gains these two public functions:
-
-        - AtomicString toAtomicString()
-
-            Returns an AtomicString, tries to avoid allocating a new string
-            if possible.
-
-        - AtomicStringImpl* toExistingAtomicString()
-
-            Returns a non-null AtomicStringImpl* if one already exists in the
-            AtomicString table. If none is found, the rope is left unresolved.
-
-        Reviewed by Filip Pizlo.
-
-        * runtime/JSString.cpp:
-        (JSC::JSRopeString::resolveRopeInternal8):
-        (JSC::JSRopeString::resolveRopeInternal16):
-        (JSC::JSRopeString::resolveRopeToAtomicString):
-        (JSC::JSRopeString::clearFibers):
-        (JSC::JSRopeString::resolveRopeToExistingAtomicString):
-        (JSC::JSRopeString::resolveRope):
-        (JSC::JSRopeString::outOfMemory):
-        * runtime/JSString.h:
-        (JSC::JSString::toAtomicString):
-        (JSC::JSString::toExistingAtomicString):
-
-2014-05-04  Andreas Kling  <akling@apple.com>
-
-        Unreviewed, rolling out r168254.
-
-        Very crashy on debug JSC tests.
-
-        Reverted changeset:
-
-        "jsSubstring() should be lazy"
-        https://bugs.webkit.org/show_bug.cgi?id=132556
-        http://trac.webkit.org/changeset/168254
-
-2014-05-04  Filip Pizlo  <fpizlo@apple.com>
-
-        jsSubstring() should be lazy
-        https://bugs.webkit.org/show_bug.cgi?id=132556
-
-        Reviewed by Andreas Kling.
-        
-        jsSubstring() is now lazy by using a special rope that is a substring instead of a
-        concatenation. To make this patch super simple, we require that a substring's base is
-        never a rope. Hence, when resolving a rope, we either go down a non-recursive substring
-        path, or we go down a concatenation path which may see exactly one level of substrings in
-        its fibers.
-        
-        This is up to a 50% speed-up on microbenchmarks and a 10% speed-up on Octane/regexp.
-
-        * heap/MarkedBlock.cpp:
-        (JSC::MarkedBlock::specializedSweep):
-        * runtime/JSString.cpp:
-        (JSC::JSRopeString::visitFibers):
-        (JSC::JSRopeString::resolveRope):
-        (JSC::JSRopeString::resolveRopeSlowCase8):
-        (JSC::JSRopeString::resolveRopeSlowCase):
-        (JSC::JSRopeString::outOfMemory):
-        * runtime/JSString.h:
-        (JSC::JSRopeString::finishCreation):
-        (JSC::JSRopeString::append):
-        (JSC::JSRopeString::create):
-        (JSC::JSRopeString::offsetOfFibers):
-        (JSC::JSRopeString::fiber):
-        (JSC::JSRopeString::substringBase):
-        (JSC::JSRopeString::substringOffset):
-        (JSC::JSRopeString::substringSentinel):
-        (JSC::JSRopeString::isSubstring):
-        (JSC::jsSubstring):
-        * runtime/RegExpMatchesArray.cpp:
-        (JSC::RegExpMatchesArray::reifyAllProperties):
-        * runtime/StringPrototype.cpp:
-        (JSC::stringProtoFuncSubstring):
-
-2014-05-02  Michael Saboff  <msaboff@apple.com>
-
-        "arm64 function not 4-byte aligned" warnings when building JSC
-        https://bugs.webkit.org/show_bug.cgi?id=132495
-
-        Reviewed by Geoffrey Garen.
-
-        Added ".align 4" for both ARM Thumb2 and ARM 64 to silence the linker.
-
-        * llint/LowLevelInterpreter.cpp:
-
-2014-05-02  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Fix cloop build after r168178
-
-        * bytecode/CodeBlock.cpp:
-
-2014-05-01  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Add a DFG function whitelist
-        https://bugs.webkit.org/show_bug.cgi?id=132437
-
-        Reviewed by Geoffrey Garen.
-
-        Often times when debugging, using bytecode ranges isn't enough to narrow down to the 
-        particular DFG block that's causing issues. This patch adds the ability to whitelist 
-        specific functions specified in a file to enable further filtering without having to recompile.
-
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGCapabilities.cpp:
-        (JSC::DFG::isSupported):
-        (JSC::DFG::mightInlineFunctionForCall):
-        (JSC::DFG::mightInlineFunctionForClosureCall):
-        (JSC::DFG::mightInlineFunctionForConstruct):
-        * dfg/DFGFunctionWhitelist.cpp: Added.
-        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
-        (JSC::DFG::FunctionWhitelist::FunctionWhitelist):
-        (JSC::DFG::FunctionWhitelist::parseFunctionNamesInFile):
-        (JSC::DFG::FunctionWhitelist::contains):
-        * dfg/DFGFunctionWhitelist.h: Added.
-        * runtime/Options.cpp:
-        (JSC::parse):
-        (JSC::Options::dumpOption):
-        * runtime/Options.h:
-
-2014-05-02  Filip Pizlo  <fpizlo@apple.com>
-
-        DFGAbstractInterpreter should not claim Int52 arithmetic creates Int52s
-        https://bugs.webkit.org/show_bug.cgi?id=132446
-
-        Reviewed by Mark Hahnenberg.
-        
-        Basically any arithmetic operation can turn an Int52 into an Int32 or vice-versa, and
-        our modeling of Int52Rep nodes is such that they can have either Int32 or Int52 type
-        to indicate a bound on the value. This is useful for knowing, for example, that
-        Int52Rep(Int32:) returns a value that cannot be outside the Int32 range. Also,
-        ValueRep(Int52Rep:) uses this to determine whether it may return a double or an int.
-        But this means that all arithmetic operations must be careful to note that they may
-        turn Int32 inputs into an Int52 output or vice-versa, as these new tests show.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::makeSafe):
-        * tests/stress/int52-ai-add-then-filter-int32.js: Added.
-        (foo):
-        * tests/stress/int52-ai-mul-and-clean-neg-zero-then-filter-int32.js: Added.
-        (foo):
-        * tests/stress/int52-ai-mul-then-filter-int32-directly.js: Added.
-        (foo):
-        * tests/stress/int52-ai-mul-then-filter-int32.js: Added.
-        (foo):
-        * tests/stress/int52-ai-neg-then-filter-int32.js: Added.
-        (foo):
-        * tests/stress/int52-ai-sub-then-filter-int32.js: Added.
-        (foo):
-
-2014-05-01  Geoffrey Garen  <ggaren@apple.com>
-
-        JavaScriptCore fails to build with some versions of clang
-        https://bugs.webkit.org/show_bug.cgi?id=132436
-
-        Reviewed by Anders Carlsson.
-
-        * runtime/ArgumentsIteratorConstructor.cpp: Since we call
-        putDirectWithoutTransition, and it calls putWillGrowOutOfLineStorage,
-        and both are marked inline, it's valid for the compiler to decide
-        to inline both and emit neither in the binary. Therefore, we need
-        both inline definitions to be available in the translation unit at
-        compile time, or we'll try to link against a function that doesn't exist.
-
-2014-05-01  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167964.
-        https://bugs.webkit.org/show_bug.cgi?id=132431
-
-        Memory improvements should not regress memory usage (Requested
-        by olliej on #webkit).
-
-        Reverted changeset:
-
-        "Don't hold on to parameter BindingNodes forever"
-        https://bugs.webkit.org/show_bug.cgi?id=132360
-        http://trac.webkit.org/changeset/167964
-
-2014-05-01  Filip Pizlo  <fpizlo@apple.com>
-
-        Fix trivial debug-only race-that-crashes in CallLinkStatus and explain why the remaining races are totally awesome
-        https://bugs.webkit.org/show_bug.cgi?id=132427
-
-        Reviewed by Mark Hahnenberg.
-
-        * bytecode/CallLinkStatus.cpp:
-        (JSC::CallLinkStatus::computeFor):
-
-2014-04-30  Simon Fraser  <simon.fraser@apple.com>
-
-        Remove ENABLE_PLUGIN_PROXY_FOR_VIDEO
-        https://bugs.webkit.org/show_bug.cgi?id=132396
-
-        Reviewed by Eric Carlson.
-
-        Remove ENABLE_PLUGIN_PROXY_FOR_VIDEO and related code.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-04-30  Filip Pizlo  <fpizlo@apple.com>
-
-        Argument flush formats should not be presumed to be JSValue since 'this' is weird
-        https://bugs.webkit.org/show_bug.cgi?id=132404
-
-        Reviewed by Michael Saboff.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Don't assume that arguments are flushed as JSValue. Use the logic for locals instead.
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile): SetArgument "changes" the format because before this we wouldn't know we had arguments.
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile): Ditto.
-        * dfg/DFGValueSource.cpp:
-        (JSC::DFG::ValueSource::dumpInContext): Make this easier to dump.
-        * dfg/DFGValueSource.h:
-        (JSC::DFG::ValueSource::operator!): Make this easier to dump because Operands<T> uses T::operator!().
-        * ftl/FTLOSREntry.cpp:
-        (JSC::FTL::prepareOSREntry): This had a useful assertion for everything except 'this'.
-        * tests/stress/strict-to-this-int.js: Added.
-        (foo):
-        (Number.prototype.valueOf):
-        (test):
-
-2014-04-29  Oliver Hunt  <oliver@apple.com>
-
-        Don't hold on to parameterBindingNodes forever
-        https://bugs.webkit.org/show_bug.cgi?id=132360
-
-        Reviewed by Geoffrey Garen.
-
-        Don't keep the parameter nodes anymore. Instead we store the
-        original parameter string and reparse whenever we actually
-        need them. Because we only actually need them for compilation
-        this only results in a single extra parse.
-
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::generateFunctionCodeBlock):
-        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
-        (JSC::UnlinkedFunctionExecutable::visitChildren):
-        (JSC::UnlinkedFunctionExecutable::finishCreation):
-        (JSC::UnlinkedFunctionExecutable::paramString):
-        (JSC::UnlinkedFunctionExecutable::parameters):
-        (JSC::UnlinkedFunctionExecutable::parameterCount): Deleted.
-        * bytecode/UnlinkedCodeBlock.h:
-        (JSC::UnlinkedFunctionExecutable::create):
-        (JSC::UnlinkedFunctionExecutable::parameterCount):
-        (JSC::UnlinkedFunctionExecutable::parameters): Deleted.
-        (JSC::UnlinkedFunctionExecutable::finishCreation): Deleted.
-        * parser/ASTBuilder.h:
-        (JSC::ASTBuilder::ASTBuilder):
-        (JSC::ASTBuilder::setFunctionBodyParameters):
-        * parser/Nodes.h:
-        (JSC::FunctionBodyNode::parametersStartOffset):
-        (JSC::FunctionBodyNode::parametersEndOffset):
-        (JSC::FunctionBodyNode::setParameterLocation):
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::parseFunctionInfo):
-        (JSC::parseParameters):
-        * parser/Parser.h:
-        (JSC::parse):
-        * parser/SourceCode.h:
-        (JSC::SourceCode::subExpression):
-        * parser/SyntaxChecker.h:
-        (JSC::SyntaxChecker::setFunctionBodyParameters):
-
-2014-04-29  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSProxies should be cacheable
-        https://bugs.webkit.org/show_bug.cgi?id=132351
-
-        Reviewed by Geoffrey Garen.
-
-        Whenever we encounter a proxy in an inline cache we should try to cache on the 
-        proxy's target instead of giving up.
-
-        This patch adds support for a simple "recursive" inline cache if the base object
-        we're accessing is a pure forwarding proxy. JSGlobalObject and its subclasses 
-        are the only ones to benefit from this right now.
-
-        This is performance neutral on the benchmarks we track. Currently we won't
-        cache on JSDOMWindow due to HasImpureGetOwnPropertySlot, but this issue will be fixed soon.
-
-        * jit/Repatch.cpp:
-        (JSC::generateByIdStub):
-        (JSC::tryBuildGetByIDList):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionCreateProxy):
-        * runtime/IntendedStructureChain.cpp:
-        (JSC::IntendedStructureChain::isNormalized):
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::isProxy):
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::finishCreation):
-        * runtime/JSProxy.h:
-        (JSC::JSProxy::createStructure):
-        (JSC::JSProxy::targetOffset):
-        * runtime/JSType.h:
-        * runtime/Operations.h:
-        (JSC::isPrototypeChainNormalized):
-        * runtime/Structure.h:
-        (JSC::Structure::isProxy):
-        * tests/stress/proxy-inline-cache.js: Added.
-        (cacheOnTarget.getX):
-        (cacheOnTarget):
-        (cacheOnPrototypeOfTarget.getX):
-        (cacheOnPrototypeOfTarget):
-        (dontCacheOnProxyInPrototypeChain.getX):
-        (dontCacheOnProxyInPrototypeChain):
-        (dontCacheOnTargetOfProxyInPrototypeChainOfTarget.getX):
-        (dontCacheOnTargetOfProxyInPrototypeChainOfTarget):
-
-2014-04-29  Filip Pizlo  <fpizlo@apple.com>
-
-        Use LLVM as a backend for the fourth-tier DFG JIT (a.k.a. the FTL JIT)
-        https://bugs.webkit.org/show_bug.cgi?id=112840
-
-        Rubber stamped by Geoffrey Garen.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-04-29  Geoffrey Garen  <ggaren@apple.com>
-
-        String.prototype.trim removes U+200B from strings.
-        https://bugs.webkit.org/show_bug.cgi?id=130184
-
-        Reviewed by Michael Saboff.
-
-        * runtime/StringPrototype.cpp:
-        (JSC::trimString):
-        (JSC::isTrimWhitespace): Deleted.
-
-2014-04-29  Mark Lam  <mark.lam@apple.com>
-
-        Zombifying sweep should ignore retired blocks.
-        <https://webkit.org/b/132344>
-
-        Reviewed by Mark Hahnenberg.
-
-        By definition, retired blocks do not have "dead" objects, or at least
-        none that we know of yet until the next marking phase has been run
-        over it.  So, we should not be sweeping them (even for zombie mode).
-
-        * heap/Heap.cpp:
-        (JSC::Heap::zombifyDeadObjects):
-        * heap/MarkedSpace.cpp:
-        (JSC::MarkedSpace::zombifySweep):
-        * heap/MarkedSpace.h:
-        (JSC::ZombifySweep::operator()):
-
-2014-04-29  Mark Lam  <mark.lam@apple.com>
-
-        Fix bit rot in zombie mode heap code.
-        <https://webkit.org/b/132342>
-
-        Reviewed by Mark Hahnenberg.
-
-        Need to enter a DelayedReleaseScope before doing a sweep.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::zombifyDeadObjects):
-
-2014-04-29  Tomas Popela  <tpopela@redhat.com>
-
-        LLINT loadisFromInstruction doesn't need special case for big endians
-        https://bugs.webkit.org/show_bug.cgi?id=132330
-
-        Reviewed by Mark Lam.
-
-        The change introduced in r167076 was wrong. We should not apply the offset
-        adjustment on loadisFromInstruction usage as the instruction
-        (UnlinkedInstruction) is declared as an union (i.e. with the int32_t
-        operand variable). The offset of the other union members will be the
-        same as the offset of the first one, that is 0. The behavior here is the
-        same on little and big endian architectures. Thus we don't need
-        special case for big endians.
-
-        * llint/LowLevelInterpreter.asm:
-
-2014-04-28  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Simplify tryCacheGetById
-        https://bugs.webkit.org/show_bug.cgi?id=132314
-
-        Reviewed by Oliver Hunt and Filip Pizlo.
-
-        This is neutral across all benchmarks we track, although it looks like a wee 0.5% progression on sunspider.
-
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID): If we fail to cache on self, we just repatch to call tryBuildGetByIDList next time.
-
-2014-04-28  Michael Saboff  <msaboff@apple.com>
-
-        REGRESSION(r153142) ASSERT from CodeBlock::dumpBytecode dumping String Switch Jump Tables
-        https://bugs.webkit.org/show_bug.cgi?id=132315
-
-        Reviewed by Mark Hahnenberg.
-
-        Used the StringImpl version of utf8() instead of creating a String first.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::dumpBytecode):
-
-2014-04-28  Filip Pizlo  <fpizlo@apple.com>
-
-        The LLInt is awesome and it should get more of the action.
-
-        Rubber stamped by Geoffrey Garen.
-        
-        5% speed-up on JSBench and no meaningful regressions.  Should be a PLT/DYE speed-up also.
-
-        * runtime/Options.h:
-
-2014-04-27  Filip Pizlo  <fpizlo@apple.com>
-
-        GC should be able to remove things from the DFG worklist and cancel on-going compilations if it knows that the compilation would already be invalidated
-        https://bugs.webkit.org/show_bug.cgi?id=132166
-
-        Reviewed by Oliver Hunt and Mark Hahnenberg.
-        
-        The GC can aid type inference by removing structures that are dead and jettisoning
-        code that relies on those structures. This can dramatically accelerate type inference
-        for some tricky programs.
-        
-        Unfortunately, we previously pinned any structures that enqueued compilations depended
-        on. This means that if you're on a machine that only runs a single compilation thread
-        and where compilations are relatively slow, you have a high chance of large numbers of
-        structures being pinned during any GC since the compilation queue is likely to be full
-        of random stuff.
-        
-        This comprehensively fixes this issue by allowing the GC to remove compilation plans
-        if the things they depend on are dead, and to even cancel safepointed compilations.
-        
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
-        (JSC::CodeBlock::isKnownToBeLiveDuringGC):
-        (JSC::CodeBlock::finalizeUnconditionally):
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan): Deleted.
-        * dfg/DFGDesiredIdentifiers.cpp:
-        (JSC::DFG::DesiredIdentifiers::DesiredIdentifiers):
-        * dfg/DFGDesiredIdentifiers.h:
-        * dfg/DFGDesiredWatchpoints.h:
-        * dfg/DFGDesiredWeakReferences.cpp:
-        (JSC::DFG::DesiredWeakReferences::DesiredWeakReferences):
-        * dfg/DFGDesiredWeakReferences.h:
-        * dfg/DFGGraphSafepoint.cpp:
-        (JSC::DFG::GraphSafepoint::GraphSafepoint):
-        * dfg/DFGGraphSafepoint.h:
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::Plan):
-        (JSC::DFG::Plan::compileInThread):
-        (JSC::DFG::Plan::compileInThreadImpl):
-        (JSC::DFG::Plan::notifyCompiling):
-        (JSC::DFG::Plan::notifyCompiled):
-        (JSC::DFG::Plan::notifyReady):
-        (JSC::DFG::Plan::checkLivenessAndVisitChildren):
-        (JSC::DFG::Plan::isKnownToBeLiveDuringGC):
-        (JSC::DFG::Plan::cancel):
-        (JSC::DFG::Plan::visitChildren): Deleted.
-        * dfg/DFGPlan.h:
-        * dfg/DFGSafepoint.cpp:
-        (JSC::DFG::Safepoint::Result::~Result):
-        (JSC::DFG::Safepoint::Result::didGetCancelled):
-        (JSC::DFG::Safepoint::Safepoint):
-        (JSC::DFG::Safepoint::~Safepoint):
-        (JSC::DFG::Safepoint::checkLivenessAndVisitChildren):
-        (JSC::DFG::Safepoint::isKnownToBeLiveDuringGC):
-        (JSC::DFG::Safepoint::cancel):
-        (JSC::DFG::Safepoint::visitChildren): Deleted.
-        * dfg/DFGSafepoint.h:
-        (JSC::DFG::Safepoint::Result::Result):
-        * dfg/DFGWorklist.cpp:
-        (JSC::DFG::Worklist::compilationState):
-        (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
-        (JSC::DFG::Worklist::removeAllReadyPlansForVM):
-        (JSC::DFG::Worklist::completeAllReadyPlansForVM):
-        (JSC::DFG::Worklist::visitWeakReferences):
-        (JSC::DFG::Worklist::removeDeadPlans):
-        (JSC::DFG::Worklist::runThread):
-        (JSC::DFG::Worklist::visitChildren): Deleted.
-        * dfg/DFGWorklist.h:
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::compile):
-        * ftl/FTLCompile.h:
-        * heap/CodeBlockSet.cpp:
-        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
-        * heap/Heap.cpp:
-        (JSC::Heap::markRoots):
-        (JSC::Heap::visitCompilerWorklistWeakReferences):
-        (JSC::Heap::removeDeadCompilerWorklistEntries):
-        (JSC::Heap::visitWeakHandles):
-        (JSC::Heap::collect):
-        (JSC::Heap::visitCompilerWorklists): Deleted.
-        * heap/Heap.h:
-
-2014-04-28  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Deleting properties poisons objects
-        https://bugs.webkit.org/show_bug.cgi?id=131551
-
-        Reviewed by Oliver Hunt.
-
-        This is ~3% progression on Dromaeo with a ~6% progression on the jslib portion of Dromaeo in particular.
-
-        * runtime/JSPropertyNameIterator.cpp:
-        (JSC::JSPropertyNameIterator::create):
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::hasDeletedOffset):
-        (JSC::PropertyTable::hadDeletedOffset): If we ever had deleted properties we can no longer cache offsets when 
-        iterating properties because we're required to iterate properties in insertion order.
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::materializePropertyMap): We now re-use deleted properties when materializing the property map.
-        (JSC::Structure::removePropertyTransition): We allow up to 5 deletes for a particular path through the tree of 
-        Structure transitions. After that, we convert to an uncacheable dictionary like we used to. We don't cache 
-        delete transitions, but we allow transitioning from them.
-        (JSC::Structure::changePrototypeTransition):
-        (JSC::Structure::despecifyFunctionTransition):
-        (JSC::Structure::attributeChangeTransition):
-        (JSC::Structure::toDictionaryTransition):
-        (JSC::Structure::preventExtensionsTransition):
-        (JSC::Structure::addPropertyWithoutTransition):
-        (JSC::Structure::removePropertyWithoutTransition):
-        (JSC::Structure::pin): Now does only what it says it does--marks the property table as pinned.
-        (JSC::Structure::pinAndPreventTransitions): More descriptive version of what the old pin() was doing.
-        * runtime/Structure.h:
-        * runtime/StructureInlines.h:
-        (JSC::Structure::setEnumerationCache):
-        (JSC::Structure::hadDeletedOffsets):
-        (JSC::Structure::propertyTable):
-        (JSC::Structure::checkOffsetConsistency): Rearranged variables to be more sensible.
-        * tests/stress/for-in-after-delete.js: Added.
-        (foo):
-
-2014-04-25  Andreas Kling  <akling@apple.com>
-
-        Inline (C++) GetByVal with numeric indices more aggressively.
-        <https://webkit.org/b/132218>
-
-        We were already inlining the string indexed GetByVal path pretty well,
-        while the path for numeric indices got neglected. No more!
-
-        ~9.5% improvement on Dromaeo/dom-traverse.html on my MBP:
-
-            Before: 199.50 runs/s
-             After: 218.58 runs/s
-
-        Reviewed by Phil Pizlo.
-
-        * dfg/DFGOperations.cpp:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::get):
-
-            ALWAYS_INLINE all the things.
-
-        * runtime/JSObject.h:
-        (JSC::JSObject::getPropertySlot):
-
-            Avoid fetching the Structure more than once. We have the same
-            optimization in the string-indexed code path.
-
-2014-04-25  Oliver Hunt  <oliver@apple.com>
-
-        Need earlier cell test
-        https://bugs.webkit.org/show_bug.cgi?id=132211
-
-        Reviewed by Mark Lam.
-
-        Move cell test to before the function call repatch
-        location, as the repatch logic for 32bit assumes that the
-        caller will already have performed a cell check.
-
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileOpCall):
-
-2014-04-25  Andreas Kling  <akling@apple.com>
-
-        Un-fast-allocate JSGlobalObjectRareData because Windows doesn't build and I'm not in the mood.
-
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::JSGlobalObjectRareData::JSGlobalObjectRareData):
-        (JSC::JSGlobalObject::JSGlobalObjectRareData::~JSGlobalObjectRareData): Deleted.
-
-2014-04-25  Andreas Kling  <akling@apple.com>
-
-        Windows build fix attempt.
-
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::JSGlobalObjectRareData::~JSGlobalObjectRareData):
-
-2014-04-25  Mark Lam  <mark.lam@apple.com>
-
-        Refactor debugging code to use BreakpointActions instead of Vector<ScriptBreakpointAction>.
-        <https://webkit.org/b/132201>
-
-        Reviewed by Joseph Pecoraro.
-
-        BreakpointActions is Vector<ScriptBreakpointAction>.  Let's just consistently use
-        BreakpointActions everywhere.
-
-        * inspector/ScriptBreakpoint.h:
-        (Inspector::ScriptBreakpoint::ScriptBreakpoint):
-        * inspector/ScriptDebugServer.cpp:
-        (Inspector::ScriptDebugServer::setBreakpoint):
-        (Inspector::ScriptDebugServer::getActionsForBreakpoint):
-        * inspector/ScriptDebugServer.h:
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol):
-        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
-        (Inspector::InspectorDebuggerAgent::setBreakpoint):
-        (Inspector::InspectorDebuggerAgent::removeBreakpoint):
-        * inspector/agents/InspectorDebuggerAgent.h:
-
-2014-04-24  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG worklist scanning should not treat the key as a separate entity
-        https://bugs.webkit.org/show_bug.cgi?id=132167
-
-        Reviewed by Mark Hahnenberg.
-        
-        This simplifies the interface to the GC and will enable more optimizations.
-
-        * dfg/DFGCompilationKey.cpp:
-        (JSC::DFG::CompilationKey::visitChildren): Deleted.
-        * dfg/DFGCompilationKey.h:
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::visitChildren):
-        * dfg/DFGWorklist.cpp:
-        (JSC::DFG::Worklist::visitChildren):
-
-2014-04-25  Oliver Hunt  <oliver@apple.com>
-
-        Remove unused parameter from codeblock linking function
-        https://bugs.webkit.org/show_bug.cgi?id=132199
-
-        Reviewed by Anders Carlsson.
-
-        No change in behaviour. This is just a small change to make it
-        slightly easier to reason about what the offsets in UnlinkedFunctionExecutable
-        actually mean.
-
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::UnlinkedFunctionExecutable::link):
-        * bytecode/UnlinkedCodeBlock.h:
-        * runtime/Executable.cpp:
-        (JSC::ProgramExecutable::initializeGlobalProperties):
-
-2014-04-25  Andreas Kling  <akling@apple.com>
-
-        Mark some things with WTF_MAKE_FAST_ALLOCATED.
-        <https://webkit.org/b/132198>
-
-        Use FastMalloc for more things.
-
-        Reviewed by Anders Carlsson.
-
-        * builtins/BuiltinExecutables.h:
-        * heap/GCThreadSharedData.h:
-        * inspector/JSConsoleClient.h:
-        * inspector/agents/InspectorAgent.h:
-        * runtime/CodeCache.h:
-        * runtime/JSGlobalObject.h:
-        * runtime/Lookup.cpp:
-        (JSC::HashTable::createTable):
-        (JSC::HashTable::deleteTable):
-        * runtime/WeakGCMap.h:
-
-2014-04-25  Antoine Quint  <graouts@webkit.org>
-
-        Implement Array.prototype.find()
-        https://bugs.webkit.org/show_bug.cgi?id=130966
-
-        Reviewed by Oliver Hunt.
-
-        Implement Array.prototype.find() and Array.prototype.findIndex() as proposed in the Harmony spec.
-
-        * builtins/Array.prototype.js:
-        (find):
-        (findIndex):
-        * runtime/ArrayPrototype.cpp:
-
-2014-04-24  Brady Eidson  <beidson@apple.com>
-
-        Rename "IMAGE_CONTROLS" feature to "SERVICE_CONTROLS"
-        https://bugs.webkit.org/show_bug.cgi?id=132155
-
-        Reviewed by Tim Horton.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-04-24  Michael Saboff  <msaboff@apple.com>
-
-        REGRESSION: Apparent hang of PCE.js Mac OS System 7.0.1 on ARM64 devices
-        https://bugs.webkit.org/show_bug.cgi?id=132147
-
-        Reviewed by Mark Lam.
-
-        Fixed or64(), eor32( ) and eor64() to use "src" register when we have a valid logicalImm.
-
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::or64):
-        (JSC::MacroAssemblerARM64::xor32):
-        (JSC::MacroAssemblerARM64::xor64):
-        * tests/stress/regress-132147.js: Added test.
-
-2014-04-24  Mark Lam  <mark.lam@apple.com>
-
-        Make slowPathAllocsBetweenGCs a runtime option.
-        <https://webkit.org/b/132137>
-
-        Reviewed by Mark Hahnenberg.
-
-        This will make it easier to more casually run tests with this configuration
-        as well as to reproduce issues (instead of requiring a code mod and rebuild).
-        We will now take --slowPathAllocsBetweenGCs=N where N is the number of
-        slow path allocations before we trigger a collection.
-
-        The option defaults to 0, which is reserved to mean that we will not trigger
-        any collections there.
-
-        * heap/Heap.h:
-        * heap/MarkedAllocator.cpp:
-        (JSC::MarkedAllocator::doTestCollectionsIfNeeded):
-        (JSC::MarkedAllocator::allocateSlowCase):
-        * heap/MarkedAllocator.h:
-        * runtime/Options.h:
-
-2014-04-23  Mark Lam  <mark.lam@apple.com>
-
-        The GC should only resume compiler threads that it suspended in the same GC pass.
-        <https://webkit.org/b/132088>
-
-        Reviewed by Mark Hahnenberg.
-
-        Previously, this scenario can occur:
-        1. Thread 1 starts a GC and tries to suspend DFG worklist threads.  However,
-           no worklists were created yet at the that time.
-        2. Thread 2 starts to compile some functions and creates a DFG worklist, and
-           acquires the worklist thread's lock.
-        3. Thread 1's GC completes and tries to resume suspended DFG worklist thread.
-           This time, it sees the worklist created by Thread 2 and ends up unlocking
-           the worklist thread's lock that is supposedly held by Thread 2.
-        Thereafter, chaos ensues.
-
-        The fix is to cache the worklists that were actually suspended by each GC pass,
-        and only resume those when the GC is done.
-
-        This issue was discovered by enabling COLLECT_ON_EVERY_ALLOCATION and running
-        the fast/workers layout tests.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::visitCompilerWorklists):
-        (JSC::Heap::deleteAllCompiledCode):
-        (JSC::Heap::suspendCompilerThreads):
-        (JSC::Heap::resumeCompilerThreads):
-        * heap/Heap.h:
-
-2014-04-23  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Arguments::copyBackingStore needs to update m_registers in tandem with m_registerArray
-        https://bugs.webkit.org/show_bug.cgi?id=132079
-
-        Reviewed by Michael Saboff.
-
-        Since we're moving the register backing store, we don't want to leave a dangling pointer into a random CopiedBlock.
-
-        Also added a test that previously triggered this bug.
-
-        * runtime/Arguments.cpp:
-        (JSC::Arguments::copyBackingStore): D'oh!
-        * tests/stress/arguments-copy-register-array-backing-store.js: Added.
-        (foo):
-        (bar):
-
-2014-04-23  Mark Rowe  <mrowe@apple.com>
-
-        [Mac] REGRESSION (r164823): Building JavaScriptCore creates files under /tmp/JavaScriptCore.dst
-        <https://webkit.org/b/132053>
-
-        Reviewed by Dan Bernstein.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Don't try to create a symlink at /usr/local/bin/jsc inside
-        the DSTROOT unless we're building to the deployment location. Also remove the unnecessary -x argument
-        from /bin/sh since that generates unnecessary output.
-
-2014-04-22  Mark Lam  <mark.lam@apple.com>
-
-        DFG::Worklist should acquire the m_lock before iterating DFG plans.
-        <https://webkit.org/b/132032>
-
-        Reviewed by Filip Pizlo.
-
-        Currently, there's a rightToRun mechanism that ensures that no compilation
-        threads are running when the GC is iterating through the DFG worklists.
-        However, this does not prevent a Worker thread from doing a DFG compilation
-        and modifying the plans in the worklists thereby invalidating the plan
-        iterator that the GC is using.  This patch fixes the issue by acquiring
-        the worklist m_lock before iterating the worklist plans.
-
-        This issue was uncovered by running the fast/workers layout tests with
-        COLLECT_ON_EVERY_ALLOCATION enabled.
-
-        * dfg/DFGWorklist.cpp:
-        (JSC::DFG::Worklist::isActiveForVM):
-        (JSC::DFG::Worklist::visitChildren):
-
-2014-04-22  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Support Python 2.7 in Cygwin
-        https://bugs.webkit.org/show_bug.cgi?id=132023
-
-        Reviewed by Michael Saboff.
-
-        * DerivedSources.make: Use a conditional variable to define
-        the path to Python/Perl.
-
-2014-04-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Switch the LLVMForJSC target to using the LLVM in /usr/local rather than /usr/local/LLVMForJavaScriptCore on iOS
-        https://bugs.webkit.org/show_bug.cgi?id=130867
-        <rdar://problem/16432456> 
-
-        Reviewed by Mark Hahnenberg.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/LLVMForJSC.xcconfig:
-
-2014-04-22  Alex Christensen  <achristensen@webkit.org>
-
-        [Win] Unreviewed build fix after my r167666.
-
-        * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
-        Added ../../../ again to include headers in Source/JavaScriptCore.
-
-2014-04-22  Alex Christensen  <achristensen@webkit.org>
-
-        Removed old stdbool and inttypes headers.
-        https://bugs.webkit.org/show_bug.cgi?id=131966
-
-        Reviewed by Brent Fulgham.
-
-        * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
-        * JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props:
-        Removed references to os-win32 directory.
-        * os-win32: Removed.
-        * os-win32/inttypes.h: Removed.
-        * os-win32/stdbool.h: Removed.
-
-2014-04-21  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG::clobberize() should honestly admit that profiler and debugger nodes are effectful
-        https://bugs.webkit.org/show_bug.cgi?id=131971
-        <rdar://problem/16676511>
-
-        Reviewed by Mark Lam.
-
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-
-2014-04-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Switch statements that skip the baseline JIT should work
-        https://bugs.webkit.org/show_bug.cgi?id=131965
-
-        Reviewed by Mark Hahnenberg.
-
-        * bytecode/JumpTable.h:
-        (JSC::SimpleJumpTable::ensureCTITable):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
-        * jit/JITOpcodes.cpp:
-        (JSC::JIT::emit_op_switch_imm):
-        (JSC::JIT::emit_op_switch_char):
-        * jit/JITOpcodes32_64.cpp:
-        (JSC::JIT::emit_op_switch_imm):
-        (JSC::JIT::emit_op_switch_char):
-        * tests/stress/inline-llint-with-switch.js: Added.
-        (foo):
-        (bar):
-        (test):
-
-2014-04-21  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Arguments objects shouldn't need a destructor
-        https://bugs.webkit.org/show_bug.cgi?id=131899
-
-        Reviewed by Oliver Hunt.
-
-        This patch rids Arguments objects of their destructors. It does this by 
-        switching their backing stores to use CopiedSpace rather than malloc memory.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Fix the code emitted for inline
-        Arguments allocation so that it only emits an extra write for strict mode code rather
-        than unconditionally.
-        * heap/CopyToken.h: New CopyTokens for the two different types of Arguments backing stores.
-        * runtime/Arguments.cpp:
-        (JSC::Arguments::visitChildren): We need to tell the collector to copy the back stores now.
-        (JSC::Arguments::copyBackingStore): Do the actual copying of the backing stores.
-        (JSC::Arguments::deletePropertyByIndex): Update all the accesses to SlowArgumentData and m_registerArray.
-        (JSC::Arguments::deleteProperty):
-        (JSC::Arguments::defineOwnProperty):
-        (JSC::Arguments::allocateRegisterArray):
-        (JSC::Arguments::tearOff):
-        (JSC::Arguments::destroy): Deleted. We don't need the destructor any more.
-        * runtime/Arguments.h:
-        (JSC::Arguments::registerArraySizeInBytes):
-        (JSC::Arguments::SlowArgumentData::SlowArgumentData): Switch SlowArgumentData to being allocated
-        in CopiedSpace. Now the SlowArgumentData and its backing store are a single contiguous CopiedSpace
-        allocation.
-        (JSC::Arguments::SlowArgumentData::slowArguments):
-        (JSC::Arguments::SlowArgumentData::bytecodeToMachineCaptureOffset):
-        (JSC::Arguments::SlowArgumentData::setBytecodeToMachineCaptureOffset):
-        (JSC::Arguments::SlowArgumentData::sizeForNumArguments):
-        (JSC::Arguments::Arguments):
-        (JSC::Arguments::allocateSlowArguments):
-        (JSC::Arguments::tryDeleteArgument):
-        (JSC::Arguments::isDeletedArgument):
-        (JSC::Arguments::isArgument):
-        (JSC::Arguments::argument):
-        (JSC::Arguments::finishCreation):
-        * runtime/SymbolTable.h:
-
-2014-04-21  Eric Carlson  <eric.carlson@apple.com>
-
-        [Mac] implement WebKitDataCue
-        https://bugs.webkit.org/show_bug.cgi?id=131799
-
-        Reviewed by Dean Jackson.
-
-        * Configurations/FeatureDefines.xcconfig: Define ENABLE_DATACUE_VALUE.
-
-2014-04-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed test gardening, run the repeat-out-of-bounds tests again.
-
-        * tests/stress/float32-repeat-out-of-bounds.js:
-        * tests/stress/int8-repeat-out-of-bounds.js:
-
-2014-04-21  Filip Pizlo  <fpizlo@apple.com>
-
-        OSR exit should know about Int52 and Double constants
-        https://bugs.webkit.org/show_bug.cgi?id=131945
-
-        Reviewed by Oliver Hunt.
-        
-        The DFG OSR exit machinery's ignorance would lead to some constants becoming
-        jsUndefined() after OSR exit.
-        
-        The FTL OSR exit machinery's ignorance just meant that we would sometimes use a
-        stackmap constant rather than baking the constant into the OSRExit data structure.
-        So, not a big deal, but worth fixing.
-        
-        Also added some helpful hacks to jsc.cpp for testing such OSR exit pathologies.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * dfg/DFGMinifiedNode.h:
-        (JSC::DFG::belongsInMinifiedGraph):
-        (JSC::DFG::MinifiedNode::hasConstantNumber):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionOtherFalse):
-        (functionUndefined):
-        * runtime/Intrinsic.h:
-        * tests/stress/fold-to-double-constant-then-exit.js: Added.
-        (foo):
-        * tests/stress/fold-to-int52-constant-then-exit.js: Added.
-        (foo):
-
-2014-04-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Provide feedback when we encounter an unrecognied node in the FTL backend.
-
-        Rubber stamped by Alexey Proskuryakov.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-
-2014-04-21  Andreas Kling  <akling@apple.com>
-
-        Move the JSString cache from DOMWrapperWorld to VM.
-        <https://webkit.org/b/131940>
-
-        Reviewed by Geoff Garen.
-
-        * runtime/VM.h:
-
-2014-04-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Take block execution count estimates into account when voting double
-        https://bugs.webkit.org/show_bug.cgi?id=131906
-
-        Reviewed by Geoffrey Garen.
-        
-        This was a drama in three acts.
-        
-        Act I: Slurp in BasicBlock::executionCount and use it as a weight when counting the
-            number of uses of a variable that want double or non-double. Easy as pie. This
-            gave me a huge speed-up on FloatMM and a huge slow-down on basically everything
-            else.
-        
-        Act II: Realize that there were some programs where our previous double voting was
-            just on the edge of disaster and making it more precise tipped it over. In
-            particular, if you had an integer variable that would infrequently be used in a
-            computation that resulted in a variable that was frequently used as an array index,
-            the outer infrequentness would be the thing we'd use in the vote. So, an array
-            index would become double. We fix this by reviving global backwards propagation
-            and introducing the concept of ReallyWantsInt, which is used just for array
-            indices. Any variable transitively flagged as ReallyWantsInt will never be forced
-            double. We need that flag to be separate from UsedAsInt, since UsedAsInt needs to
-            be set in bitops for RageConversion but using it for double forcing is too much.
-            Basically, it's cheaper to have to convert a double to an int for a bitop than it
-            is to convert a double to an int for an array index; also a variable being used as
-            an array index is a much stronger hint that it ought to be an int. This recovered
-            performance on everything except programs that used FTL OSR entry.
-        
-        Act III: Realize that OSR entrypoint creation creates blocks that have NaN execution
-            count, which then completely pollutes the weighting - essentially all votes go
-            NaN. Fix this with some surgical defenses. Basically, any client of execution
-            counts should allow for them to be NaN and shouldn't completely fall off a cliff
-            when it happens.
-        
-        This is awesome. 75% speed-up on FloatMM. 11% speed-up on audio-dft. This leads to
-        7% speed-up on AsmBench and 2% speed-up on Kraken.
-
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGBackwardsPropagationPhase.cpp:
-        (JSC::DFG::BackwardsPropagationPhase::run):
-        (JSC::DFG::BackwardsPropagationPhase::propagate):
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::dumpBlockHeader):
-        * dfg/DFGGraph.h:
-        (JSC::DFG::Graph::voteNode):
-        (JSC::DFG::Graph::voteChildren):
-        * dfg/DFGNodeFlags.cpp:
-        (JSC::DFG::dumpNodeFlags):
-        * dfg/DFGNodeFlags.h:
-        * dfg/DFGOSREntrypointCreationPhase.cpp:
-        (JSC::DFG::OSREntrypointCreationPhase::run):
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::compileInThreadImpl):
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
-        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
-        * dfg/DFGVariableAccessData.cpp: Added.
-        (JSC::DFG::VariableAccessData::VariableAccessData):
-        (JSC::DFG::VariableAccessData::mergeIsCaptured):
-        (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox):
-        (JSC::DFG::VariableAccessData::predict):
-        (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction):
-        (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
-        (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
-        (JSC::DFG::VariableAccessData::mergeDoubleFormatState):
-        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
-        (JSC::DFG::VariableAccessData::flushFormat):
-        * dfg/DFGVariableAccessData.h:
-        (JSC::DFG::VariableAccessData::vote):
-        (JSC::DFG::VariableAccessData::VariableAccessData): Deleted.
-        (JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
-        (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox): Deleted.
-        (JSC::DFG::VariableAccessData::predict): Deleted.
-        (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction): Deleted.
-        (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): Deleted.
-        (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat): Deleted.
-        (JSC::DFG::VariableAccessData::mergeDoubleFormatState): Deleted.
-        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat): Deleted.
-        (JSC::DFG::VariableAccessData::flushFormat): Deleted.
-
-2014-04-21  Michael Saboff  <msaboff@apple.com>
-
-        REGRESSION(r167591): ARM64 and ARM traditional builds broken
-        https://bugs.webkit.org/show_bug.cgi?id=131935
-
-        Reviewed by Mark Hahnenberg.
-
-        Added store8(TrustedImm32, MacroAssembler::Address) to the ARM traditional and ARM64
-        macro assemblers.  Added a new test for the original patch.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::store8):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::store8):
-        * tests/stress/dfg-create-arguments-inline-alloc.js: New test.
-
-2014-04-21  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Inline allocate Arguments objects in the DFG
-        https://bugs.webkit.org/show_bug.cgi?id=131897
-
-        Reviewed by Geoffrey Garen.
-
-        Many libraries/frameworks depend on the arguments object for overloaded API entry points. 
-        This is the first step to making Arguments fast(er). We'll duplicate the logic in Arguments::create 
-        for now and take the slow path for complicated cases like slow arguments, tearing off for strict mode, etc.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::emitAllocateArguments):
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * runtime/Arguments.h:
-        (JSC::Arguments::offsetOfActivation):
-        (JSC::Arguments::offsetOfOverrodeLength):
-        (JSC::Arguments::offsetOfIsStrictMode):
-        (JSC::Arguments::offsetOfRegisterArray):
-        (JSC::Arguments::offsetOfCallee):
-        (JSC::Arguments::allocationSize):
-
-2014-04-20  Andreas Kling  <akling@apple.com>
-
-        Speed up jsStringWithCache() through WeakGCMap inlining.
-        <https://webkit.org/b/131923>
-
-        Always inline WeakGCMap::add() but move the slow garbage collecting
-        path out-of-line.
-
-        Reviewed by Darin Adler.
-
-        * runtime/WeakGCMap.h:
-        (JSC::WeakGCMap::add):
-        (JSC::WeakGCMap::gcMap):
-
-2014-04-20  László Langó  <llango.u-szeged@partner.samsung.com>
-
-        JavaScriptCore: ARM build fix after r167094.
-        https://bugs.webkit.org/show_bug.cgi?id=131612
-
-        Reviewed by Michael Saboff.
-
-        After r167094 there are many build errors on ARM like these:
-
-            /tmp/ccgtHRno.s:370: Error: invalid constant (425a) after fixup
-            /tmp/ccgtHRno.s:374: Error: invalid constant (426e) after fixup
-            /tmp/ccgtHRno.s:378: Error: invalid constant (4282) after fixup
-            /tmp/ccgtHRno.s:382: Error: invalid constant (4296) after fixup
-
-        Problem is caused by the wrong generated assembly like:
-            "\tmov r2, (" LOCAL_LABEL_STRING(llint_op_strcat) " - " LOCAL_LABEL_STRING(relativePCBase) ")\n" // /home/webkit/WebKit/Source/JavaScriptCore/llint/LowLevelInterpreter.asm:741
-
-        `mov` can only move 8 bit immediate, but not every constant fit into 8 bit. Clang converts
-        the mov to a single movw or a movw and a movt, depending on the immediate, but binutils doesn't.
-        Add a new ARM specific offline assembler instruction (`mvlbl`) for the following llint_entry
-        use case: move rn, (label1-label2) which is translated to movw and movt.
-
-        * llint/LowLevelInterpreter.asm:
-        * offlineasm/arm.rb:
-        * offlineasm/instructions.rb:
-
-2014-04-20  Csaba Osztrogonác  <ossy@webkit.org>
-
-        [ARM] Unreviewed build fix after r167336.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::branchAdd32):
-
-2014-04-20  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167501.
-        https://bugs.webkit.org/show_bug.cgi?id=131913
-
-        It broke DYEBench (Requested by mhahnenberg on #webkit).
-
-        Reverted changeset:
-
-        "Deleting properties poisons objects"
-        https://bugs.webkit.org/show_bug.cgi?id=131551
-        http://trac.webkit.org/changeset/167501
-
-2014-04-19  Filip Pizlo  <fpizlo@apple.com>
-
-        It should be OK to store new fields into objects that have no prototypes
-        https://bugs.webkit.org/show_bug.cgi?id=131905
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
-        * tests/stress/put-by-id-transition-null-prototype.js: Added.
-        (foo):
-
-2014-04-19  Benjamin Poulain  <bpoulain@apple.com>
-
-        Make the CSS JIT compile for ARM64
-        https://bugs.webkit.org/show_bug.cgi?id=131834
-
-        Reviewed by Gavin Barraclough.
-
-        Extend the ARM64 MacroAssembler to support the code generation required by
-        the CSS JIT.
-
-        * assembler/MacroAssembler.h:
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::addPtrNoFlags):
-        (JSC::MacroAssemblerARM64::or32):
-        (JSC::MacroAssemblerARM64::branchPtr):
-        (JSC::MacroAssemblerARM64::test32):
-        (JSC::MacroAssemblerARM64::branch):
-        * assembler/MacroAssemblerX86Common.h:
-        (JSC::MacroAssemblerX86Common::test32):
-
-2014-04-19  Andreas Kling  <akling@apple.com>
-
-        Two little shortcuts to the JSType.
-        <https://webkit.org/b/131896>
-
-        Tweak two sites that take the long road through JSCell::structure()->typeInfo()
-        to look at data that's already in JSCell::type().
-
-        Reviewed by Darin Adler.
-
-        * runtime/NameInstance.h:
-        (JSC::isName):
-        * runtime/NumberPrototype.cpp:
-        (JSC::toThisNumber):
-
-2014-04-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Make it easier to check if an integer sum would overflow
-        https://bugs.webkit.org/show_bug.cgi?id=131900
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGOperations.cpp:
-        * runtime/Operations.h:
-        (JSC::jsString):
-
-2014-04-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Address some feedback on https://bugs.webkit.org/show_bug.cgi?id=130684.
-
-        * dfg/DFGOperations.cpp:
-        * runtime/JSString.h:
-        (JSC::JSRopeString::RopeBuilder::append):
-
-2014-04-18  Mark Lam  <mark.lam@apple.com>
-
-        REGRESSION(r164205): WebKit crash @StructureIDTable::get.
-        <https://webkit.org/b/130539>
-
-        Reviewed by Geoffrey Garen.
-
-        prepareOSREntry() prepares for OSR entry by first copying the local var
-        values from the baseline frame to a scartch buffer, which is then used
-        to fill in the locals in their new position in the DFG frame.  Unfortunately,
-        prepareOSREntry() was using the DFG frame's frameRegisterCount as the frame
-        size of the baseline frame.  As a result, some values of locals in the
-        baseline frame were not saved off, and the DFG frame may get initialized
-        with random content that happened to be in the uninitialized (and possibly
-        unallocated) portions of the scratch buffer.
-
-        The fix is to use OSREntryData::m_expectedValues.numberOfLocals() as the
-        number of locals in the baseline frame that we want to copy to the scratch
-        buffer.
-
-        Note: osrEntryThunkGenerator() is expecting the DFG frameRegisterCount
-        at offset 0 in the scratch buffer.  So, we continue to write that value
-        there, not the baseline frame size.
-
-        * dfg/DFGOSREntry.cpp:
-        (JSC::DFG::prepareOSREntry):
-
-2014-04-18  Timothy Hatcher  <timothy@apple.com>
-
-        Web Inspector: Move InspectorProfilerAgent to JavaScriptCore
-        https://bugs.webkit.org/show_bug.cgi?id=131673
-
-        Passes existing profiler and inspector tests.
-
-        Reviewed by Joseph Pecoraro.
-
-        * CMakeLists.txt:
-        * DerivedSources.make:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * inspector/JSConsoleClient.cpp:
-        (Inspector::JSConsoleClient::JSConsoleClient):
-        (Inspector::JSConsoleClient::profile):
-        (Inspector::JSConsoleClient::profileEnd):
-        (Inspector::JSConsoleClient::count): Deleted.
-        * inspector/JSConsoleClient.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        * inspector/agents/InspectorProfilerAgent.cpp: Added.
-        (Inspector::InspectorProfilerAgent::InspectorProfilerAgent):
-        (Inspector::InspectorProfilerAgent::~InspectorProfilerAgent):
-        (Inspector::InspectorProfilerAgent::addProfile):
-        (Inspector::InspectorProfilerAgent::createProfileHeader):
-        (Inspector::InspectorProfilerAgent::enable):
-        (Inspector::InspectorProfilerAgent::disable):
-        (Inspector::InspectorProfilerAgent::getUserInitiatedProfileName):
-        (Inspector::InspectorProfilerAgent::getProfileHeaders):
-        (Inspector::buildInspectorObject):
-        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
-        (Inspector::InspectorProfilerAgent::getCPUProfile):
-        (Inspector::InspectorProfilerAgent::removeProfile):
-        (Inspector::InspectorProfilerAgent::reset):
-        (Inspector::InspectorProfilerAgent::didCreateFrontendAndBackend):
-        (Inspector::InspectorProfilerAgent::willDestroyFrontendAndBackend):
-        (Inspector::InspectorProfilerAgent::start):
-        (Inspector::InspectorProfilerAgent::stop):
-        (Inspector::InspectorProfilerAgent::setRecordingProfile):
-        (Inspector::InspectorProfilerAgent::startProfiling):
-        (Inspector::InspectorProfilerAgent::stopProfiling):
-        * inspector/agents/InspectorProfilerAgent.h: Added.
-        * inspector/agents/JSGlobalObjectProfilerAgent.cpp: Copied from Source/WebCore/inspector/ScriptProfile.idl.
-        (Inspector::JSGlobalObjectProfilerAgent::JSGlobalObjectProfilerAgent):
-        (Inspector::JSGlobalObjectProfilerAgent::profilingGlobalExecState):
-        * inspector/agents/JSGlobalObjectProfilerAgent.h: Copied from Source/WebCore/inspector/ScriptProfile.idl.
-        * inspector/protocol/Profiler.json: Renamed from Source/WebCore/inspector/protocol/Profiler.json.
-        * profiler/Profile.h:
-        * runtime/ConsoleClient.h:
-
-2014-04-18  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167527.
-        https://bugs.webkit.org/show_bug.cgi?id=131883
-
-        Broke 32-bit build (Requested by ap on #webkit).
-
-        Reverted changeset:
-
-        "[Mac] implement WebKitDataCue"
-        https://bugs.webkit.org/show_bug.cgi?id=131799
-        http://trac.webkit.org/changeset/167527
-
-2014-04-18  Eric Carlson  <eric.carlson@apple.com>
-
-        [Mac] implement WebKitDataCue
-        https://bugs.webkit.org/show_bug.cgi?id=131799
-
-        Reviewed by Dean Jackson.
-
-        * Configurations/FeatureDefines.xcconfig: Define ENABLE_DATACUE_VALUE.
-
-2014-04-18  Filip Pizlo  <fpizlo@apple.com>
-
-        Actually address Mark's review feedback.
-
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::handleExitCounts):
-
-2014-04-18  Filip Pizlo  <fpizlo@apple.com>
-
-        Options::maximumExecutionCountsBetweenCheckpoints() should be higher for DFG->FTL tier-up but the same for other tier-ups
-        https://bugs.webkit.org/show_bug.cgi?id=131850
-
-        Reviewed by Mark Hahnenberg.
-        
-        Templatize ExecutionCounter to allow for two different styles of calculating the
-        checkpoint threshold.
-        
-        Appears to be a slight speed-up on DYEBench.
-
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::llintExecuteCounter):
-        (JSC::CodeBlock::offsetOfJITExecuteCounter):
-        (JSC::CodeBlock::offsetOfJITExecutionActiveThreshold):
-        (JSC::CodeBlock::offsetOfJITExecutionTotalCount):
-        (JSC::CodeBlock::jitExecuteCounter):
-        * bytecode/ExecutionCounter.cpp:
-        (JSC::ExecutionCounter<countingVariant>::ExecutionCounter):
-        (JSC::ExecutionCounter<countingVariant>::forceSlowPathConcurrently):
-        (JSC::ExecutionCounter<countingVariant>::checkIfThresholdCrossedAndSet):
-        (JSC::ExecutionCounter<countingVariant>::setNewThreshold):
-        (JSC::ExecutionCounter<countingVariant>::deferIndefinitely):
-        (JSC::applyMemoryUsageHeuristics):
-        (JSC::applyMemoryUsageHeuristicsAndConvertToInt):
-        (JSC::ExecutionCounter<countingVariant>::hasCrossedThreshold):
-        (JSC::ExecutionCounter<countingVariant>::setThreshold):
-        (JSC::ExecutionCounter<countingVariant>::reset):
-        (JSC::ExecutionCounter<countingVariant>::dump):
-        (JSC::ExecutionCounter::ExecutionCounter): Deleted.
-        (JSC::ExecutionCounter::forceSlowPathConcurrently): Deleted.
-        (JSC::ExecutionCounter::checkIfThresholdCrossedAndSet): Deleted.
-        (JSC::ExecutionCounter::setNewThreshold): Deleted.
-        (JSC::ExecutionCounter::deferIndefinitely): Deleted.
-        (JSC::ExecutionCounter::applyMemoryUsageHeuristics): Deleted.
-        (JSC::ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt): Deleted.
-        (JSC::ExecutionCounter::hasCrossedThreshold): Deleted.
-        (JSC::ExecutionCounter::setThreshold): Deleted.
-        (JSC::ExecutionCounter::reset): Deleted.
-        (JSC::ExecutionCounter::dump): Deleted.
-        * bytecode/ExecutionCounter.h:
-        (JSC::formattedTotalExecutionCount):
-        (JSC::ExecutionCounter::maximumExecutionCountsBetweenCheckpoints):
-        (JSC::ExecutionCounter::clippedThreshold):
-        (JSC::ExecutionCounter::formattedTotalCount): Deleted.
-        * dfg/DFGJITCode.h:
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::handleExitCounts):
-        * llint/LowLevelInterpreter.asm:
-        * runtime/Options.h:
-
-2014-04-17  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Deleting properties poisons objects
-        https://bugs.webkit.org/show_bug.cgi?id=131551
-
-        Reviewed by Geoffrey Garen.
-
-        This is ~3% progression on Dromaeo with a ~6% progression on the jslib portion of Dromaeo in particular.
-
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::materializePropertyMap): We now re-use deleted properties when materializing the property map.
-        (JSC::Structure::removePropertyTransition): We allow up to 5 deletes for a particular path through the tree of 
-        Structure transitions. After that, we convert to an uncacheable dictionary like we used to. We don't cache 
-        delete transitions, but we allow transitioning from them.
-        (JSC::Structure::changePrototypeTransition):
-        (JSC::Structure::despecifyFunctionTransition):
-        (JSC::Structure::attributeChangeTransition):
-        (JSC::Structure::toDictionaryTransition):
-        (JSC::Structure::preventExtensionsTransition):
-        (JSC::Structure::addPropertyWithoutTransition):
-        (JSC::Structure::removePropertyWithoutTransition):
-        (JSC::Structure::pin): Now does only what it says it does--marks the property table as pinned.
-        (JSC::Structure::pinAndPreventTransitions): More descriptive version of what the old pin() was doing.
-        * runtime/Structure.h:
-        * runtime/StructureInlines.h:
-        (JSC::Structure::checkOffsetConsistency): Rearranged variables to be more sensible.
-
-2014-04-17  Filip Pizlo  <fpizlo@apple.com>
-
-        InlineCallFrameSet should be refcounted
-        https://bugs.webkit.org/show_bug.cgi?id=131829
-
-        Reviewed by Geoffrey Garen.
-        
-        And DFG::Plan should hold a ref to it. Previously it was owned by Graph until it
-        became owned by JITCode. Except that if we're "failing" to compile, JITCode may die.
-        Even as it dies, the GC may still want to scan the DFG::Plan, which leads to scanning
-        the DesiredWriteBarriers, which leads to scanning the InlineCallFrameSet.
-        
-        So, just make the darn thing refcounted.
-
-        * bytecode/InlineCallFrameSet.h:
-        * dfg/DFGArgumentsSimplificationPhase.cpp:
-        (JSC::DFG::ArgumentsSimplificationPhase::run):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
-        * dfg/DFGCommonData.h:
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::Graph):
-        (JSC::DFG::Graph::requiredRegisterCountForExit):
-        * dfg/DFGGraph.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::link):
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::Plan):
-        * dfg/DFGPlan.h:
-        * dfg/DFGStackLayoutPhase.cpp:
-        (JSC::DFG::StackLayoutPhase::run):
-        * ftl/FTLFail.cpp:
-        (JSC::FTL::fail):
-        * ftl/FTLLink.cpp:
-        (JSC::FTL::link):
-
-2014-04-17  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL::fail() should manage memory "correctly"
-        https://bugs.webkit.org/show_bug.cgi?id=131823
-        <rdar://problem/16384297>
-
-        Reviewed by Oliver Hunt.
-
-        * ftl/FTLFail.cpp:
-        (JSC::FTL::fail):
-
-2014-04-17  Filip Pizlo  <fpizlo@apple.com>
-
-        Prediction propagator should correctly model Int52s flowing through arguments
-        https://bugs.webkit.org/show_bug.cgi?id=131822
-        <rdar://problem/16641408>
-
-        Reviewed by Oliver Hunt.
-
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * tests/stress/int52-argument.js: Added.
-        (foo):
-        * tests/stress/int52-variable.js: Added.
-        (foo):
-
-2014-04-17  Filip Pizlo  <fpizlo@apple.com>
-
-        REGRESSION: ASSERT(!typeInfo().hasImpureGetOwnPropertySlot() || typeInfo().newImpurePropertyFiresWatchpoints()) on jquery tests
-        https://bugs.webkit.org/show_bug.cgi?id=131798
-
-        Reviewed by Alexey Proskuryakov.
-        
-        Some day, we will fix https://bugs.webkit.org/show_bug.cgi?id=131810 and some version
-        of this assertion can return. For now, it's not clear that the assertion is guarding
-        any truly undesirable behavior - so it should just go away and be replaced with a
-        FIXME.
-
-        * bytecode/GetByIdStatus.cpp:
-        (JSC::GetByIdStatus::computeForStubInfo):
-        * runtime/Structure.h:
-        (JSC::Structure::takesSlowPathInDFGForImpureProperty):
-
-2014-04-17  David Kilzer  <ddkilzer@apple.com>
-
-        Blind attempt to fix Windows build after r166837
-        <http://webkit.org/b/131246>
-
-        Hoping to fix this build error:
-
-            warning MSB8027: Two or more files with the name of GCLogging.cpp will produce outputs to the same location. This can lead to an incorrect build result.  The files involved are ..\heap\GCLogging.cpp, ..\heap\GCLogging.cpp.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Fix copy-paste
-        boo-boo by changing the GCLogging.cpp ClCompile entry to a
-        GCLogging.h ClInclude entry.
-
-2014-04-16  Filip Pizlo  <fpizlo@apple.com>
-
-        AI for GetLocal should match the DFG backend, and in this case, the best way to do that is to get rid of the "exit if empty prediction" thing since it's a vestige of a time long gone
-        https://bugs.webkit.org/show_bug.cgi?id=131764
-
-        Reviewed by Geoffrey Garen.
-        
-        The attached test case can be made to not crash by deleting old code. It used to be
-        the case that the DFG needed empty prediction guards, for shady reasons. We fixed that
-        long ago. At this point, these guards just make life difficult. So get rid of them.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * tests/stress/bug-131764.js: Added.
-        (test1):
-        (test2):
-
-2014-04-17  Darin Adler  <darin@apple.com>
-
-        Add separate flag for IndexedDatabase in workers since the current implementation is not threadsafe
-        https://bugs.webkit.org/show_bug.cgi?id=131785
-        rdar://problem/16003108
-
-        Reviewed by Brady Eidson.
-
-        * Configurations/FeatureDefines.xcconfig: Added INDEXED_DATABASE_IN_WORKERS.
-
-2014-04-16  Alexey Proskuryakov  <ap@apple.com>
-
-        Build fix after http://trac.webkit.org/changeset/167416 (Sink NaN sanitization)
-
-        * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::speculate):
-
-2014-04-16  Filip Pizlo  <fpizlo@apple.com>
-
-        Extra error reporting for invalid value conversions
-        https://bugs.webkit.org/show_bug.cgi?id=131786
-
-        Rubber stamped by Ryosuke Niwa.
-
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-
-2014-04-16  Filip Pizlo  <fpizlo@apple.com>
-
-        Sink NaN sanitization to uses and remove it when it's unnecessary
-        https://bugs.webkit.org/show_bug.cgi?id=131419
-
-        Reviewed by Oliver Hunt.
-        
-        This moves NaN purification to stores that could see an impure NaN.
-        
-        5% speed-up on AsmBench, 50% speed-up on AsmBench/n-body. It is a regression on FloatMM
-        though, because of the other bug that causes that benchmark to box doubles in a loop.
-
-        * bytecode/SpeculatedType.h:
-        (JSC::isInt32SpeculationForArithmetic):
-        (JSC::isMachineIntSpeculationForArithmetic):
-        (JSC::isDoubleSpeculation):
-        (JSC::isDoubleSpeculationForArithmetic):
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGAbstractValue.cpp:
-        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-        * dfg/DFGInPlaceAbstractState.cpp:
-        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileValueRep):
-        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
-        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
-        * runtime/PureNaN.h:
-        * tests/stress/float32-array-nan-inlined.js: Added.
-        (foo):
-        (test):
-        * tests/stress/float32-array-nan.js: Added.
-        (foo):
-        (test):
-        * tests/stress/float64-array-nan-inlined.js: Added.
-        (foo):
-        (isBigEndian):
-        (test):
-        * tests/stress/float64-array-nan.js: Added.
-        (foo):
-        (isBigEndian):
-        (test):
-
-2014-04-16  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Unreviewed Windows gardening. Restrict our new 'isinf' check
-        to 32-bit builds, and revise the comment to explain what we are
-        doing.
-
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::isMachineInt): Provide motivation for the new
-        'isinf' check for our 32-bit code path.
-
-2014-04-16  Juergen Ributzka  <juergen@apple.com>
-
-        Allocate the data section on the heap again for FTL on ARM64
-        https://bugs.webkit.org/show_bug.cgi?id=130156
-
-        Reviewed by Geoffrey Garen and Filip Pizlo.
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::mmAllocateDataSection):
-        * ftl/FTLDataSection.cpp:
-        (JSC::FTL::DataSection::DataSection):
-        (JSC::FTL::DataSection::~DataSection):
-        * ftl/FTLDataSection.h:
-
-2014-04-16  Mark Lam  <mark.lam@apple.com>
-
-        Crash in CodeBlock::setOptimizationThresholdBasedOnCompilationResult() when the debugger activates.
-        <https://webkit.org/b/131747>
-
-        Reviewed by Filip Pizlo.
-
-        When the debugger is about to activate (e.g. enter stepping mode), it first
-        waits for all DFG compilations to complete.  However, when the DFG completes,
-        if compilation is successful, it will install a new DFG codeBlock.  The
-        CodeBlock installation process is required to register codeBlocks with the
-        debugger.  Debugger::registerCodeBlock() will eventually call
-        CodeBlock::setSteppingMode() which may jettison the DFG codeBlock that we're
-        trying to install.  Thereafter, chaos ensues.
-
-        This jettison'ing only happens because the debugger currently set its
-        m_steppingMode flag before waiting for compilation to complete.  The fix is
-        simply to set that flag only after compilation is complete.
-
-        * debugger/Debugger.cpp:
-        (JSC::Debugger::setSteppingMode):
-        (JSC::Debugger::registerCodeBlock):
-
-2014-04-16  Filip Pizlo  <fpizlo@apple.com>
-
-        Discern between NaNs that would be safe to tag and NaNs that need some purification before tagging
-        https://bugs.webkit.org/show_bug.cgi?id=131420
-
-        Reviewed by Oliver Hunt.
-        
-        Rationalizes our handling of NaNs. We now have the notion of pureNaN(), or PNaN, which
-        replaces QNaN and represents a "safe" NaN for our tagging purposes. NaN purification now
-        goes through the purifyNaN() API.
-        
-        SpeculatedType and its clients can now distinguish between a PureNaN and an ImpureNaN.
-        
-        Prediction propagator is made slightly more cautious when dealing with NaNs. It doesn't
-        have to be too cautious since most prediction-based logic only cares about whether or not
-        a value could be an integer.
-        
-        AI is made much more cautious when dealing with NaNs. We don't yet introduce ImpureNaN
-        anywhere in the compiler, but when we do, we ought to be able to trust AI to propagate it
-        soundly and precisely.
-        
-        No performance change because this just unblocks
-        https://bugs.webkit.org/show_bug.cgi?id=131419.
-
-        * API/JSValueRef.cpp:
-        (JSValueMakeNumber):
-        (JSValueToNumber):
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/SpeculatedType.cpp:
-        (JSC::dumpSpeculation):
-        (JSC::speculationFromValue):
-        (JSC::typeOfDoubleSum):
-        (JSC::typeOfDoubleDifference):
-        (JSC::typeOfDoubleProduct):
-        (JSC::polluteDouble):
-        (JSC::typeOfDoubleQuotient):
-        (JSC::typeOfDoubleMinMax):
-        (JSC::typeOfDoubleNegation):
-        (JSC::typeOfDoubleAbs):
-        (JSC::typeOfDoubleFRound):
-        (JSC::typeOfDoubleBinaryOp):
-        (JSC::typeOfDoubleUnaryOp):
-        * bytecode/SpeculatedType.h:
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleInlining):
-        (JSC::DFG::ByteCodeParser::parseCodeBlock):
-        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
-        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
-        * dfg/DFGInPlaceAbstractState.cpp:
-        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
-        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
-        (JSC::DFG::createPreHeader):
-        * dfg/DFGNode.h:
-        (JSC::DFG::BranchTarget::BranchTarget):
-        * dfg/DFGOSREntrypointCreationPhase.cpp:
-        (JSC::DFG::OSREntrypointCreationPhase::run):
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
-        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
-        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGVariableAccessData.h:
-        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
-        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
-        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
-        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
-        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
-        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
-        (JSC::FTL::LowerDFGToLLVM::allocateJSArray):
-        * ftl/FTLValueFormat.cpp:
-        (JSC::FTL::reboxAccordingToFormat):
-        * jit/AssemblyHelpers.cpp:
-        (JSC::AssemblyHelpers::purifyNaN):
-        (JSC::AssemblyHelpers::sanitizeDouble): Deleted.
-        * jit/AssemblyHelpers.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emitFloatTypedArrayGetByVal):
-        * runtime/DateConstructor.cpp:
-        (JSC::constructDate):
-        * runtime/DateInstanceCache.h:
-        (JSC::DateInstanceData::DateInstanceData):
-        (JSC::DateInstanceCache::reset):
-        * runtime/ExceptionHelpers.cpp:
-        (JSC::TerminatedExecutionError::defaultValue):
-        * runtime/JSArray.cpp:
-        (JSC::JSArray::setLength):
-        (JSC::JSArray::pop):
-        (JSC::JSArray::shiftCountWithAnyIndexingType):
-        (JSC::JSArray::sortVector):
-        (JSC::JSArray::compactForSorting):
-        * runtime/JSArray.h:
-        (JSC::JSArray::create):
-        (JSC::JSArray::tryCreateUninitialized):
-        * runtime/JSCJSValue.cpp:
-        (JSC::JSValue::toNumberSlowCase):
-        * runtime/JSCJSValue.h:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::jsNaN):
-        (JSC::JSValue::JSValue):
-        (JSC::JSValue::getPrimitiveNumber):
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::parseInt):
-        (JSC::jsStrDecimalLiteral):
-        (JSC::toDouble):
-        (JSC::jsToNumber):
-        (JSC::parseFloat):
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::createInitialDouble):
-        (JSC::JSObject::convertUndecidedToDouble):
-        (JSC::JSObject::convertInt32ToDouble):
-        (JSC::JSObject::deletePropertyByIndex):
-        (JSC::JSObject::ensureLengthSlow):
-        * runtime/MathObject.cpp:
-        (JSC::mathProtoFuncMax):
-        (JSC::mathProtoFuncMin):
-        * runtime/PureNaN.h: Added.
-        (JSC::pureNaN):
-        (JSC::isImpureNaN):
-        (JSC::purifyNaN):
-        * runtime/TypedArrayAdaptors.h:
-        (JSC::FloatTypedArrayAdaptor::toJSValue):
-
-2014-04-16  Juergen Ributzka  <juergen@apple.com>
-
-        Enable system library calls in FTL for ARM64
-        https://bugs.webkit.org/show_bug.cgi?id=130154
-
-        Reviewed by Geoffrey Garen and Filip Pizlo.
-
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::doubleRem):
-        (JSC::FTL::Output::doubleSin):
-        (JSC::FTL::Output::doubleCos):
-
-2014-04-16  peavo@outlook.com  <peavo@outlook.com>
-
-        Fix JSC Debug Regressions on Windows
-        https://bugs.webkit.org/show_bug.cgi?id=131182
-
-        Reviewed by Brent Fulgham.
-
-        The cast static_cast<int64_t>(number) in JSValue::isMachineInt() can generate a floating point error,
-        and set the st floating point register tags, if the value of the number parameter is infinite.
-        If the st floating point register tags are not cleared, this can cause strange floating point behavior later on.
-        This can be avoided by checking for infinity first.
-
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::isMachineInt): Avoid floating point error by checking for infinity first.
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions): Re-enable jit for Windows.
-
-2014-04-16  Oliver Hunt  <oliver@apple.com>
-
-        Simple ES6 feature:Array.prototype.fill
-        https://bugs.webkit.org/show_bug.cgi?id=131703
-
-        Reviewed by David Hyatt.
-
-        Add support for Array.prototype.fill
-
-        * builtins/Array.prototype.js:
-        (fill):
-        * runtime/ArrayPrototype.cpp:
-
-2014-04-16  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        [WebKit] Cleanup the build from uninitialized variable in JavaScriptCore
-        https://bugs.webkit.org/show_bug.cgi?id=131728
-
-        Reviewed by Darin Adler.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::genericConvertDoubleToContiguous): Add a RELEASE_ASSERT on the 
-        path we expect to never take. Also shut up confused compilers about uninitialized things.
-
-2014-04-16  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, ARMv7 build fix after r167336.
-
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::branchAdd32):
-
-2014-04-16  Gabor Rapcsanyi  <rgabor@webkit.org>
-
-        Unreviewed, ARM64 buildfix after r167336.
-
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::branchAdd32): Add missing function.
-
-2014-04-15  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, add the obvious thing that marks MakeRope as exiting since it can exit.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-
-2014-04-15  Filip Pizlo  <fpizlo@apple.com>
-
-        compileMakeRope does not emit necessary bounds checks
-        https://bugs.webkit.org/show_bug.cgi?id=130684
-        <rdar://problem/16398388>
-
-        Reviewed by Oliver Hunt.
-        
-        Add string length bounds checks in a bunch of places. We should never allow a string
-        to have a length greater than 2^31-1 because it's not clear that the language has
-        semantics for it and because there is code that assumes that this cannot happen.
-        
-        Also add a bunch of tests to that effect to cover the various ways in which this was
-        previously allowed to happen.
-
-        * dfg/DFGOperations.cpp:
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMakeRope):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
-        * runtime/JSString.cpp:
-        (JSC::JSRopeString::RopeBuilder::expand):
-        * runtime/JSString.h:
-        (JSC::JSString::create):
-        (JSC::JSRopeString::RopeBuilder::append):
-        (JSC::JSRopeString::RopeBuilder::release):
-        (JSC::JSRopeString::append):
-        * runtime/Operations.h:
-        (JSC::jsString):
-        (JSC::jsStringFromRegisterArray):
-        (JSC::jsStringFromArguments):
-        * runtime/StringPrototype.cpp:
-        (JSC::stringProtoFuncIndexOf):
-        (JSC::stringProtoFuncSlice):
-        (JSC::stringProtoFuncSubstring):
-        (JSC::stringProtoFuncToLowerCase):
-        * tests/stress/make-large-string-jit-strcat.js: Added.
-        (foo):
-        * tests/stress/make-large-string-jit.js: Added.
-        (foo):
-        * tests/stress/make-large-string-strcat.js: Added.
-        * tests/stress/make-large-string.js: Added.
-
-2014-04-15  Julien Brianceau  <jbriance@cisco.com>
-
-        Remove invalid sh4 specific code in JITInlines header.
-        https://bugs.webkit.org/show_bug.cgi?id=131692
-
-        Reviewed by Geoffrey Garen.
-
-        * jit/JITInlines.h:
-        (JSC::JIT::callOperation): Prototype is not F_JITOperation_EJJZ
-        anymore since r160244, so the sh4 specific code is invalid now
-        and has to be removed.
-
-2014-04-15  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Fix precedence issue in JSCell:setRemembered
-
-        Rubber stamped by Filip Pizlo.
-
-        * runtime/JSCell.h:
-        (JSC::JSCell::setRemembered):
-
-2014-04-15  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Objective-C API external object graphs don't handle generational collection properly
-        https://bugs.webkit.org/show_bug.cgi?id=131634
-
-        Reviewed by Geoffrey Garen.
-
-        If the set of Objective-C objects transitively reachable through an object changes, we 
-        need to update the set of opaque roots accordingly. If we don't, the next EdenCollection 
-        won't rescan the external object graph, which would lead us to consider a newly allocated 
-        JSManagedValue to be dead.
-
-        * API/JSBase.cpp:
-        (JSSynchronousEdenCollectForDebugging):
-        * API/JSVirtualMachine.mm:
-        (-[JSVirtualMachine initWithContextGroupRef:]):
-        (-[JSVirtualMachine dealloc]):
-        (-[JSVirtualMachine isOldExternalObject:]):
-        (-[JSVirtualMachine addExternalRememberedObject:]):
-        (-[JSVirtualMachine addManagedReference:withOwner:]):
-        (-[JSVirtualMachine removeManagedReference:withOwner:]):
-        (-[JSVirtualMachine externalRememberedSet]):
-        (scanExternalObjectGraph):
-        (scanExternalRememberedSet):
-        * API/JSVirtualMachineInternal.h:
-        * API/tests/testapi.mm:
-        * heap/Heap.cpp:
-        (JSC::Heap::markRoots):
-        * heap/Heap.h:
-        (JSC::Heap::slotVisitor):
-        * heap/SlotVisitor.h:
-        * heap/SlotVisitorInlines.h:
-        (JSC::SlotVisitor::containsOpaqueRoot):
-        (JSC::SlotVisitor::containsOpaqueRootTriState):
-
-2014-04-15  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG IR should keep the data flow of doubles and int52's separate from the data flow of JSValue's
-        https://bugs.webkit.org/show_bug.cgi?id=131423
-
-        Reviewed by Geoffrey Garen.
-        
-        This introduces more static typing into DFG IR. Previously we just had the notion of
-        JSValues and Storage. This was weird because doubles weren't always convertible to
-        JSValues, and Int52s weren't always convertible to either doubles or JSValues. We would
-        sort of insert explicit conversion nodes just for the places where we knew that an
-        implicit conversion wouldn't have been possible -- but there was no hard and fast rule so
-        we'd get bugs from forgetting to do the right conversion.
-        
-        This patch introduces a hard and fast rule: doubles can never be implicitly converted to
-        anything but doubles, and likewise Int52's can never be implicitly converted. Conversion
-        nodes are used for all of the conversions. Int52Rep, DoubleRep, and ValueRep are the
-        conversions. They are like Identity but return the same value using a different
-        representation. Likewise, constants may now be represented using either JSConstant,
-        Int52Constant, or DoubleConstant. UseKinds have been adjusted accordingly, as well.
-        Int52RepUse and DoubleRepUse are node uses that mean "the node must be of Int52 (or
-        Double) type". They don't imply checks. There is also DoubleRepRealUse, which means that
-        we speculate DoubleReal and expect Double representation.
-        
-        In addition to simplifying a bunch of rules in the IR and making the IR more verifiable,
-        this also makes it easier to introduce optimizations in the future. It's now possible for
-        AI to model when/how conversion take place. For example if doing a conversion results in
-        NaN sanitization, then AI can model this and can allow us to sink sanitizations. That's
-        what https://bugs.webkit.org/show_bug.cgi?id=131419 will be all about.
-        
-        This was a big change, so I had to do some interesting things, like finally get rid of
-        the DFG's weird variadic template macro hacks and use real C++11 variadic templates. Also
-        the ByteCodeParser no longer emits Identity nodes since that was always pointless.
-        
-        No performance change because this mostly just rationalizes preexisting behavior.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * assembler/MacroAssemblerX86.h:
-        * bytecode/CodeBlock.cpp:
-        * bytecode/CodeBlock.h:
-        * dfg/DFGAbstractInterpreter.h:
-        (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
-        (JSC::DFG::AbstractInterpreter::setConstant):
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGAbstractValue.cpp:
-        (JSC::DFG::AbstractValue::set):
-        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
-        (JSC::DFG::AbstractValue::checkConsistency):
-        * dfg/DFGAbstractValue.h:
-        * dfg/DFGBackwardsPropagationPhase.cpp:
-        (JSC::DFG::BackwardsPropagationPhase::propagate):
-        * dfg/DFGBasicBlock.h:
-        * dfg/DFGBasicBlockInlines.h:
-        (JSC::DFG::BasicBlock::appendNode):
-        (JSC::DFG::BasicBlock::appendNonTerminal):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::constantCSE):
-        (JSC::DFG::CSEPhase::performNodeCSE):
-        (JSC::DFG::CSEPhase::int32ToDoubleCSE): Deleted.
-        * dfg/DFGCapabilities.h:
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        * dfg/DFGDCEPhase.cpp:
-        (JSC::DFG::DCEPhase::fixupBlock):
-        * dfg/DFGEdge.h:
-        (JSC::DFG::Edge::willNotHaveCheck):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::run):
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::fixupGetAndSetLocalsInBlock):
-        (JSC::DFG::FixupPhase::observeUseKindOnNode):
-        (JSC::DFG::FixupPhase::fixIntEdge):
-        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
-        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
-        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
-        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-        (JSC::DFG::FixupPhase::addRequiredPhantom):
-        (JSC::DFG::FixupPhase::addPhantomsIfNecessary):
-        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
-        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock): Deleted.
-        * dfg/DFGFlushFormat.h:
-        (JSC::DFG::resultFor):
-        (JSC::DFG::useKindFor):
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::dump):
-        * dfg/DFGGraph.h:
-        (JSC::DFG::Graph::addNode):
-        * dfg/DFGInPlaceAbstractState.cpp:
-        (JSC::DFG::InPlaceAbstractState::initialize):
-        * dfg/DFGInsertionSet.h:
-        (JSC::DFG::InsertionSet::insertNode):
-        (JSC::DFG::InsertionSet::insertConstant):
-        (JSC::DFG::InsertionSet::insertConstantForUse):
-        * dfg/DFGIntegerCheckCombiningPhase.cpp:
-        (JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
-        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):
-        * dfg/DFGNode.cpp:
-        (JSC::DFG::Node::convertToIdentity):
-        (WTF::printInternal):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::Node):
-        (JSC::DFG::Node::setResult):
-        (JSC::DFG::Node::result):
-        (JSC::DFG::Node::isConstant):
-        (JSC::DFG::Node::hasConstant):
-        (JSC::DFG::Node::convertToConstant):
-        (JSC::DFG::Node::valueOfJSConstant):
-        (JSC::DFG::Node::hasResult):
-        (JSC::DFG::Node::hasInt32Result):
-        (JSC::DFG::Node::hasInt52Result):
-        (JSC::DFG::Node::hasNumberResult):
-        (JSC::DFG::Node::hasDoubleResult):
-        (JSC::DFG::Node::hasJSResult):
-        (JSC::DFG::Node::hasBooleanResult):
-        (JSC::DFG::Node::hasStorageResult):
-        (JSC::DFG::Node::defaultUseKind):
-        (JSC::DFG::Node::defaultEdge):
-        (JSC::DFG::Node::convertToIdentity): Deleted.
-        * dfg/DFGNodeFlags.cpp:
-        (JSC::DFG::dumpNodeFlags):
-        * dfg/DFGNodeFlags.h:
-        (JSC::DFG::canonicalResultRepresentation):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGResurrectionForValidationPhase.cpp:
-        (JSC::DFG::ResurrectionForValidationPhase::run):
-        * dfg/DFGSSAConversionPhase.cpp:
-        (JSC::DFG::SSAConversionPhase::run):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
-        (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
-        (JSC::DFG::SpeculativeJIT::silentFill):
-        (JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
-        (JSC::DFG::JSValueRegsTemporary::~JSValueRegsTemporary):
-        (JSC::DFG::JSValueRegsTemporary::regs):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
-        (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
-        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
-        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
-        (JSC::DFG::SpeculativeJIT::compileValueRep):
-        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
-        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
-        (JSC::DFG::SpeculativeJIT::compileAdd):
-        (JSC::DFG::SpeculativeJIT::compileArithSub):
-        (JSC::DFG::SpeculativeJIT::compileArithNegate):
-        (JSC::DFG::SpeculativeJIT::compileArithMul):
-        (JSC::DFG::SpeculativeJIT::compileArithDiv):
-        (JSC::DFG::SpeculativeJIT::compileArithMod):
-        (JSC::DFG::SpeculativeJIT::compare):
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        (JSC::DFG::SpeculativeJIT::speculateNumber):
-        (JSC::DFG::SpeculativeJIT::speculateDoubleReal):
-        (JSC::DFG::SpeculativeJIT::speculate):
-        (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): Deleted.
-        (JSC::DFG::SpeculativeJIT::speculateMachineInt): Deleted.
-        (JSC::DFG::SpeculativeJIT::speculateRealNumber): Deleted.
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::allocate):
-        (JSC::DFG::SpeculativeJIT::use):
-        (JSC::DFG::SpeculativeJIT::boxDouble):
-        (JSC::DFG::SpeculativeJIT::spill):
-        (JSC::DFG::SpeculativeJIT::jsValueResult):
-        (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
-        (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
-        (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
-        (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillJSValue):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
-        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillJSValue):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
-        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
-        * dfg/DFGStrengthReductionPhase.cpp:
-        (JSC::DFG::StrengthReductionPhase::handleNode):
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        (JSC::DFG::shouldNotHaveTypeCheck):
-        (JSC::DFG::mayHaveTypeCheck):
-        (JSC::DFG::isNumerical):
-        (JSC::DFG::isDouble):
-        (JSC::DFG::isCell):
-        (JSC::DFG::usesStructure):
-        (JSC::DFG::useKindForResult):
-        * dfg/DFGValidate.cpp:
-        (JSC::DFG::Validate::validate):
-        * dfg/DFGVariadicFunction.h: Removed.
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
-        (JSC::FTL::LowerDFGToLLVM::compilePhi):
-        (JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
-        (JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
-        (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
-        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
-        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
-        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
-        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
-        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
-        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
-        (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
-        (JSC::FTL::LowerDFGToLLVM::compileArithMod):
-        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
-        (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
-        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
-        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::compare):
-        (JSC::FTL::LowerDFGToLLVM::boolify):
-        (JSC::FTL::LowerDFGToLLVM::lowInt52):
-        (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
-        (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
-        (JSC::FTL::LowerDFGToLLVM::lowDouble):
-        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
-        (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
-        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
-        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal):
-        (JSC::FTL::LowerDFGToLLVM::compileInt52ToValue): Deleted.
-        (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble): Deleted.
-        (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue): Deleted.
-        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber): Deleted.
-        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt): Deleted.
-        * ftl/FTLValueFormat.cpp:
-        (JSC::FTL::reboxAccordingToFormat):
-        * jit/AssemblyHelpers.cpp:
-        (JSC::AssemblyHelpers::sanitizeDouble):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::boxDouble):
-
-2014-04-15  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167199 and r167251.
-        https://bugs.webkit.org/show_bug.cgi?id=131678
-
-        Caused a DYEBench regression and does not seem to improve perf
-        on relevant websites (Requested by rniwa on #webkit).
-
-        Reverted changesets:
-
-        "Rewrite Function.bind as a builtin"
-        https://bugs.webkit.org/show_bug.cgi?id=131083
-        http://trac.webkit.org/changeset/167199
-
-        "Update test result"
-        http://trac.webkit.org/changeset/167251
-
-2014-04-14  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167272.
-        https://bugs.webkit.org/show_bug.cgi?id=131666
-
-        Broke multiple tests (Requested by ap on #webkit).
-
-        Reverted changeset:
-
-        "Function.bind itself is too slow"
-        https://bugs.webkit.org/show_bug.cgi?id=131636
-        http://trac.webkit.org/changeset/167272
-
-2014-04-14  Geoffrey Garen  <ggaren@apple.com>
-
-        ASSERT when firing low memory warning
-        https://bugs.webkit.org/show_bug.cgi?id=131659
-
-        Reviewed by Mark Hahnenberg.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::deleteAllCompiledCode): Allow deleteAllCompiledCode to be
-        called when no GC is happening because that is what we do when a low
-        memory warning fires, and it is harmless.
-
-2014-04-14  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        emit_op_put_by_id should not emit a write barrier that filters on value
-        https://bugs.webkit.org/show_bug.cgi?id=131654
-
-        Reviewed by Filip Pizlo.
-
-        The 32-bit implementation does this, and it can cause crashes if we later repatch the 
-        code to allocate and store new Butterflies.
-
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emitWriteBarrier): We also weren't verifying that the base was a cell on 
-        32-bit if we were passed ShouldFilterBase. I also took the liberty of sinking the tag 
-        load down into the if statement so that we don't do it if we're not filtering on the value.
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emit_op_put_by_id):
-
-2014-04-14  Oliver Hunt  <oliver@apple.com>
-
-        Function.bind itself is too slow
-        https://bugs.webkit.org/show_bug.cgi?id=131636
-
-        Reviewed by Geoffrey Garen.
-
-        Rather than forcing creation of an activation, we now store
-        bound function properties directly on the returned closure.
-        This is necessary to deal with code that creates many function
-        bindings, but does not call them very often.
-
-        This is a 60% speed up in the included js/regress test.
-
-        * builtins/BuiltinExecutables.cpp:
-        (JSC::BuiltinExecutables::createBuiltinExecutable):
-        * builtins/Function.prototype.js:
-        (bind.bindingFunction):
-        (bind.else.switch.case.1.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
-        (bind.else.switch.case.1.bindingFunction):
-        (bind.else.switch.case.2.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
-        (bind.else.switch.case.2.bindingFunction):
-        (bind.else.switch.case.3.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
-        (bind.else.switch.case.3.bindingFunction):
-        (bind.else.switch.bindingFunction):
-        (bind):
-        (bind.else.switch.case.1.bindingFunction.oversizedCall): Deleted.
-        (bind.else.switch.case.2.bindingFunction.oversizedCall): Deleted.
-        (bind.else.switch.case.3.bindingFunction.oversizedCall): Deleted.
-        * runtime/CommonIdentifiers.h:
-
-2014-04-14  Julien Brianceau  <jbriance@cisco.com>
-
-        [sh4] Allow use of SubImmediates in LLINT.
-        https://bugs.webkit.org/show_bug.cgi?id=131608
-
-        Reviewed by Mark Lam.
-
-        Allow use of SubImmediates with const pool so the sh4 architecture can
-        share the arm path for setEntryAddress macro. It reduces architecture
-        specific code and lead to a more optimal generated code for sh4.
-
-        * llint/LowLevelInterpreter.asm:
-        * offlineasm/sh4.rb:
-
-2014-04-14  Andreas Kling  <akling@apple.com>
-
-        Array.prototype.concat should allocate output storage only once.
-        <https://webkit.org/b/131609>
-
-        Do a first pass across 'this' and any arguments to compute the
-        final size of the resulting array from Array.prototype.concat.
-        This avoids having to grow the output incrementally as we go.
-
-        This also includes two other micro-optimizations:
-
-        - Mark getProperty() with ALWAYS_INLINE.
-
-        - Use JSArray::length() instead of taking the generic property
-          lookup path when we know an argument is an Array.
-
-        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
-
-        Reviewed by Oliver & Darin.
-
-        * runtime/ArrayPrototype.cpp:
-        (JSC::getProperty):
-        (JSC::arrayProtoFuncConcat):
-
-2014-04-14  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r167249.
-        https://bugs.webkit.org/show_bug.cgi?id=131621
-
-        broke 3 tests on cloop (Requested by kling on #webkit).
-
-        Reverted changeset:
-
-        "Array.prototype.concat should allocate output storage only
-        once."
-        https://bugs.webkit.org/show_bug.cgi?id=131609
-        http://trac.webkit.org/changeset/167249
-
-2014-04-14  Alex Christensen  <achristensen@webkit.org>
-
-        Fixed potential integer truncation.
-        https://bugs.webkit.org/show_bug.cgi?id=131615
-
-        Reviewed by Darin Adler.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::fillNops):
-        Truncate the size_t to an unsigned after it is limited to 15 instead of before.
-
-2014-04-14  Andreas Kling  <akling@apple.com>
-
-        Array.prototype.concat should allocate output storage only once.
-        <https://webkit.org/b/131609>
-
-        Do a first pass across 'this' and any arguments to compute the
-        final size of the resulting array from Array.prototype.concat.
-        This avoids having to grow the output incrementally as we go.
-
-        This also includes two other micro-optimizations:
-
-        - Mark getProperty() with ALWAYS_INLINE.
-
-        - Use JSArray::length() instead of taking the generic property
-          lookup path when we know an argument is an Array.
-
-        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
-
-        Reviewed by Darin Adler.
-
-        * runtime/ArrayPrototype.cpp:
-        (JSC::getProperty):
-        (JSC::arrayProtoFuncConcat):
-
-2014-04-14  Benjamin Poulain  <benjamin@webkit.org>
-
-        [JSC] Improve the call site of string comparison in some hot path
-        https://bugs.webkit.org/show_bug.cgi?id=131605
-
-        Reviewed by Darin Adler.
-
-        When resolved, the String of a JSString is never null. It can be empty but not null.
-        The null value is reserved for ropes but those would be resolved when getting the value.
-
-        Consequently, we should use the equal() operation that do not handle null values.
-        Using the StringImpl directly is already common in StringPrototype but it was not used here for some reason.
-
-        * jit/JITOperations.cpp:
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::equalSlowCaseInline):
-        (JSC::JSValue::strictEqualSlowCaseInline):
-        (JSC::JSValue::pureStrictEqual):
-
-2014-04-08  Oliver Hunt  <oliver@apple.com>
-
-        Rewrite Function.bind as a builtin
-        https://bugs.webkit.org/show_bug.cgi?id=131083
-
-        Reviewed by Geoffrey Garen.
-
-        This change removes the existing function.bind implementation
-        entirely so JSBoundFunction is no more.
-
-        Instead we just return a regular JS closure with a few
-        private properties hanging off it that allow us to perform
-        the necessary bound function fakery.  While most of this is
-        simple, a couple of key changes:
-
-        - The parser and lexer now directly track whether they're
-          parsing code for call or construct and convert the private
-          name @IsConstructor into TRUETOK or FALSETOK as appropriate.
-          This automatically gives us the ability to vary behaviour
-          from within the builtin. It also leaves a lot of headroom
-          for trivial future improvements.
-        - The instanceof operator now uses the prototypeForHasInstance
-          private name, and we have a helper function to ensure that
-          all objects that need to can update their magical 'prototype'
-          property pair correctly.
-
-        * API/JSScriptRef.cpp:
-        (parseScript):
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * builtins/BuiltinExecutables.cpp:
-        (JSC::BuiltinExecutables::createBuiltinExecutable):
-        * builtins/Function.prototype.js:
-        (bind.bindingFunction):
-        (bind.else.bindingFunction):
-        (bind):
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::generateFunctionCodeBlock):
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::InstanceOfNode::emitBytecode):
-        * interpreter/Interpreter.cpp:
-        * parser/Lexer.cpp:
-        (JSC::Lexer<T>::Lexer):
-        (JSC::Lexer<LChar>::parseIdentifier):
-        (JSC::Lexer<UChar>::parseIdentifier):
-        * parser/Lexer.h:
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::Parser):
-        (JSC::Parser<LexerType>::parseInner):
-        * parser/Parser.h:
-        (JSC::parse):
-        * parser/ParserModes.h:
-        * runtime/CodeCache.cpp:
-        (JSC::CodeCache::getGlobalCodeBlock):
-        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
-        * runtime/CommonIdentifiers.h:
-        * runtime/Completion.cpp:
-        (JSC::checkSyntax):
-        * runtime/Executable.cpp:
-        (JSC::ProgramExecutable::checkSyntax):
-        * runtime/FunctionPrototype.cpp:
-        (JSC::FunctionPrototype::addFunctionProperties):
-        (JSC::functionProtoFuncBind): Deleted.
-        * runtime/JSBoundFunction.cpp: Removed.
-        * runtime/JSBoundFunction.h: Removed.
-        * runtime/JSFunction.cpp:
-        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
-        (JSC::RetrieveCallerFunctionFunctor::operator()):
-        (JSC::retrieveCallerFunction):
-        (JSC::JSFunction::getOwnPropertySlot):
-        (JSC::JSFunction::defineOwnProperty):
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::globalFuncSetTypeErrorAccessor):
-        * runtime/JSGlobalObjectFunctions.h:
-        * runtime/JSObject.h:
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-
-2014-04-12  Filip Pizlo  <fpizlo@apple.com>
-
-        Math.fround() should be an intrinsic
-        https://bugs.webkit.org/show_bug.cgi?id=131583
-
-        Reviewed by Geoffrey Garen.
-        
-        Makes programs that use Math.fround() run up to 6x faster.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::performNodeCSE):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileArithFRound):
-        * runtime/Intrinsic.h:
-        * runtime/MathObject.cpp:
-        (JSC::MathObject::finishCreation):
-
-2014-04-12  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should use stackmap register liveness
-        https://bugs.webkit.org/show_bug.cgi?id=130791
-
-        Reviewed by Goeffrey Garen.
-        
-        Enable the stackmap register liveness support by fixing the two last bugs:
-        
-        - If everything is dead after the patchpoint - a good possibility for a put_by_id -
-          then we shouldn't crash due to a null scratch buffer.
-        
-        - Always consider callee-saves as if they were live. More precisely, we should
-          consider those callee-saves that are not saved by the enclosing function to be live.
-          For now we do the much simpler thing and consider callee-saves to be always live
-          since it has minimal impact on the scratch register allocator. It will know not to
-          preserve those for calls, anyway.
-        
-        I tried writing a test for the null scratch buffer thing, but failed. I will land the
-        test anyway since it seems useful.
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::usedRegistersFor):
-        * jit/ScratchRegisterAllocator.cpp:
-        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall):
-        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall):
-        * runtime/Options.h:
-        * tests/stress/repeated-put-by-id-reallocating-transition.js: Added.
-        (foo):
-
-2014-04-11  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG::FixupPhase should insert conversion nodes after the rest of fixup so that we know how the types settled
-        https://bugs.webkit.org/show_bug.cgi?id=131424
-
-        Reviewed by Geoffrey Garen.
-        
-        This defers type conversion injection until we've decided on types. This makes the
-        process of deciding types a bit more flexible - for example we can naturally fixpoint
-        and change our minds. Only when things are settled do we actually insert conversions.
-        
-        This is a necessary prerequisite for keeping double, int52, and JSValue data flow
-        separate. A SetLocal/GetLocal will appear to be JSValue until we fixpoint and realize
-        that there are typed uses. If we were eagerly inserting type conversions then we would
-        first insert a to/from-JSValue conversion in some cases only to then replace it by
-        the other conversions. It's probably trivial to remove those redundant conversions later
-        but I think it's better if we don't insert them to begin with.
-
-        * bytecode/CodeOrigin.h:
-        (JSC::CodeOrigin::operator!):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::run):
-        (JSC::DFG::FixupPhase::fixupBlock):
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
-        (JSC::DFG::FixupPhase::fixEdge):
-        (JSC::DFG::FixupPhase::fixIntEdge):
-        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
-        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
-        (JSC::DFG::FixupPhase::addRequiredPhantom):
-        (JSC::DFG::FixupPhase::addPhantomsIfNecessary):
-        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
-        (JSC::DFG::FixupPhase::observeUntypedEdge): Deleted.
-        (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock): Deleted.
-        (JSC::DFG::FixupPhase::injectInt32ToDoubleNode): Deleted.
-
-2014-04-11  Brian J. Burg  <burg@cs.washington.edu>
-
-        Web Replay: code generator should consider enclosing class when computing duplicate type names
-        https://bugs.webkit.org/show_bug.cgi?id=131554
-
-        Reviewed by Timothy Hatcher.
-
-        We need to prepend an enum's enclosing class, if any, so that multiple enums with the same name
-        can coexist without triggering a "duplicate types" error. Now, such enums must be referenced
-        by the enclosing class and enum name.
-
-        Added tests for the new syntax, and rebaselined one test to reflect a previous patch's change.
-
-        * replay/scripts/CodeGeneratorReplayInputs.py:
-        (Type.type_name): Prepend the enclosing class name.
-        (Type.type_name.is):
-        * replay/scripts/tests/expected/fail-on-duplicate-enum-type.json-error: Added.
-        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp: Added.
-        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h: Added.
-        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h: Rebaseline.
-        * replay/scripts/tests/fail-on-duplicate-enum-type.json: Added.
-        * replay/scripts/tests/generate-enums-with-same-base-name.json: Added.
-
-2014-04-11  Gavin Barraclough  <baraclough@apple.com>
-
-        Rollout - Rewrite Function.bind as a builtin
-        https://bugs.webkit.org/show_bug.cgi?id=131083
-
-        Unreviewed.
-
-        Rolling out r167020 while investigating a performance regression.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeConstructor):
-        * API/JSScriptRef.cpp:
-        (parseScript):
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * builtins/BuiltinExecutables.cpp:
-        (JSC::BuiltinExecutables::createBuiltinExecutable):
-        * builtins/Function.prototype.js:
-        (apply):
-        (bind.bindingFunction): Deleted.
-        (bind.else.bindingFunction): Deleted.
-        (bind): Deleted.
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::generateFunctionCodeBlock):
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::InstanceOfNode::emitBytecode):
-        * interpreter/Interpreter.cpp:
-        * parser/Lexer.cpp:
-        (JSC::Lexer<T>::Lexer):
-        (JSC::Lexer<LChar>::parseIdentifier):
-        (JSC::Lexer<UChar>::parseIdentifier):
-        * parser/Lexer.h:
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::Parser):
-        (JSC::Parser<LexerType>::parseInner):
-        * parser/Parser.h:
-        (JSC::parse):
-        * parser/ParserModes.h:
-        * runtime/ArgumentsIteratorConstructor.cpp:
-        (JSC::ArgumentsIteratorConstructor::finishCreation):
-        * runtime/ArrayConstructor.cpp:
-        (JSC::ArrayConstructor::finishCreation):
-        * runtime/BooleanConstructor.cpp:
-        (JSC::BooleanConstructor::finishCreation):
-        * runtime/CodeCache.cpp:
-        (JSC::CodeCache::getGlobalCodeBlock):
-        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
-        * runtime/CommonIdentifiers.h:
-        * runtime/Completion.cpp:
-        (JSC::checkSyntax):
-        * runtime/DateConstructor.cpp:
-        (JSC::DateConstructor::finishCreation):
-        * runtime/ErrorConstructor.cpp:
-        (JSC::ErrorConstructor::finishCreation):
-        * runtime/Executable.cpp:
-        (JSC::ProgramExecutable::checkSyntax):
-        * runtime/FunctionConstructor.cpp:
-        (JSC::FunctionConstructor::finishCreation):
-        * runtime/FunctionPrototype.cpp:
-        (JSC::FunctionPrototype::addFunctionProperties):
-        (JSC::functionProtoFuncBind):
-        * runtime/JSArrayBufferConstructor.cpp:
-        (JSC::JSArrayBufferConstructor::finishCreation):
-        * runtime/JSBoundFunction.cpp: Added.
-        (JSC::boundFunctionCall):
-        (JSC::boundFunctionConstruct):
-        (JSC::JSBoundFunction::create):
-        (JSC::JSBoundFunction::destroy):
-        (JSC::JSBoundFunction::customHasInstance):
-        (JSC::JSBoundFunction::JSBoundFunction):
-        (JSC::JSBoundFunction::finishCreation):
-        (JSC::JSBoundFunction::visitChildren):
-        * runtime/JSBoundFunction.h: Added.
-        (JSC::JSBoundFunction::targetFunction):
-        (JSC::JSBoundFunction::boundThis):
-        (JSC::JSBoundFunction::boundArgs):
-        (JSC::JSBoundFunction::createStructure):
-        * runtime/JSFunction.cpp:
-        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
-        (JSC::RetrieveCallerFunctionFunctor::operator()):
-        (JSC::retrieveCallerFunction):
-        (JSC::JSFunction::getOwnPropertySlot):
-        (JSC::JSFunction::getOwnNonIndexPropertyNames):
-        (JSC::JSFunction::put):
-        (JSC::JSFunction::defineOwnProperty):
-        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
-        (JSC::JSGenericTypedArrayViewConstructor<ViewClass>::finishCreation):
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::globalFuncSetTypeErrorAccessor): Deleted.
-        * runtime/JSGlobalObjectFunctions.h:
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::putDirectPrototypeProperty): Deleted.
-        (JSC::JSObject::putDirectPrototypePropertyWithoutTransitions): Deleted.
-        * runtime/JSObject.h:
-        * runtime/JSPromiseConstructor.cpp:
-        (JSC::JSPromiseConstructor::finishCreation):
-        * runtime/MapConstructor.cpp:
-        (JSC::MapConstructor::finishCreation):
-        * runtime/MapIteratorConstructor.cpp:
-        (JSC::MapIteratorConstructor::finishCreation):
-        * runtime/NameConstructor.cpp:
-        (JSC::NameConstructor::finishCreation):
-        * runtime/NativeErrorConstructor.cpp:
-        (JSC::NativeErrorConstructor::finishCreation):
-        * runtime/NumberConstructor.cpp:
-        (JSC::NumberConstructor::finishCreation):
-        * runtime/ObjectConstructor.cpp:
-        (JSC::ObjectConstructor::finishCreation):
-        * runtime/RegExpConstructor.cpp:
-        (JSC::RegExpConstructor::finishCreation):
-        * runtime/SetConstructor.cpp:
-        (JSC::SetConstructor::finishCreation):
-        * runtime/SetIteratorConstructor.cpp:
-        (JSC::SetIteratorConstructor::finishCreation):
-        * runtime/StringConstructor.cpp:
-        (JSC::StringConstructor::finishCreation):
-        * runtime/WeakMapConstructor.cpp:
-        (JSC::WeakMapConstructor::finishCreation):
-
-2014-04-11  David Kilzer  <ddkilzer@apple.com>
-
-        [ASan] Build broke because libCompileRuntimeToLLVMIR.a links to libclang_rt.asan_osx_dynamic.dylib
-        <http://webkit.org/b/131556>
-        <rdar://problem/16591856>
-
-        Reviewed by Brent Fulgham.
-
-        * Configurations/CompileRuntimeToLLVMIR.xcconfig: Clear
-        OTHER_LDFLAGS so the ASan build does not try to link to
-        libclang_rt.asan_osx_dynamic.dylib.
-
-2014-04-11  Mark Lam  <mark.lam@apple.com>
-
-        JSMainThreadExecState::call() should clear exceptions before returning.
-        <https://webkit.org/b/131530>
-
-        Reviewed by Geoffrey Garen.
-
-        Added a version of JSC::call() that return any uncaught exception instead
-        of leaving it pending in the VM.
-
-        As part of this change, I updated various parts of the code base to use the
-        new API as needed.
-
-        * bindings/ScriptFunctionCall.cpp:
-        (Deprecated::ScriptFunctionCall::call):
-        - ScriptFunctionCall::call() is only used by the inspector to inject scripts.
-          The injected scripts that will include Inspector scripts that should catch
-          and handle any exceptions that were thrown.  We should not be seeing any
-          exceptions returned from this call.  However, we do have checks for
-          exceptions in case there are bugs in the Inspector scripts which allowed
-          the exception to leak through.  Hence, it is proper to clear the exception
-          here, and only record the fact that an exception was seen (if present).
-
-        * bindings/ScriptFunctionCall.h:
-        * inspector/InspectorEnvironment.h:
-        * runtime/CallData.cpp:
-        (JSC::call):
-        * runtime/CallData.h:
-
-2014-04-11  Oliver Hunt  <oliver@apple.com>
-
-        Add BuiltinLog function to make debugging builtins easier
-        https://bugs.webkit.org/show_bug.cgi?id=131550
-
-        Reviewed by Andreas Kling.
-
-        Add a logging function that builtins can use for debugging.
-
-        * runtime/CommonIdentifiers.h:
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::globalFuncBuiltinLog):
-        * runtime/JSGlobalObjectFunctions.h:
-
-2014-04-11  Julien Brianceau  <jbriance@cisco.com>
-
-        Fix LLInt for sh4 architecture (broken since C stack merge).
-        https://bugs.webkit.org/show_bug.cgi?id=131532
-
-        Reviewed by Mark Lam.
-
-        This patch fixes build and also implements sh4 parts for initPCRelative and
-        setEntryAddress macros introduced in http://trac.webkit.org/changeset/167094.
-
-        * llint/LowLevelInterpreter.asm:
-        * llint/LowLevelInterpreter32_64.asm:
-        * offlineasm/instructions.rb:
-        * offlineasm/sh4.rb:
-
-2014-04-10  Michael Saboff  <msaboff@apple.com>
-
-        Crash beneath DFG JIT code @ video.disney.com
-        https://bugs.webkit.org/show_bug.cgi?id=131447
-
-        Reviewed by Geoffrey Garen.
-
-        The 32-bit path of speculateMisc() uses an 'is not int32' check followed by
-        'tag not less than Undefined' check.  The first check was incorrectly elided if we
-        knew that the value *was* an int32, when it should have been elided if we already
-        knew that the value *was not* an int32.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::speculateMisc):
-        * tests/stress/test-spec-misc.js: Added test.
-        (getX):
-        (foo):
-        (bar):
-
-2014-04-08  Filip Pizlo  <fpizlo@apple.com>
-
-        Make room for additional types in SpeculatedType.h
-        https://bugs.webkit.org/show_bug.cgi?id=131422
-
-        Reviewed by Sam Weinig.
-        
-        This'll make it easier to add DoubleHeavyNaN and DoubleEmptyNaN.
-
-        * bytecode/SpeculatedType.h:
-
-2014-04-10  Alex Christensen  <achristensen@webkit.org>
-
-        Compile fix for Win64.
-        https://bugs.webkit.org/show_bug.cgi?id=131508
-
-        Reviewed by Geoffrey Garen.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::fillNops):
-        Added unsigned template parameter to distinguish between size_t and unsigned long.
-
-2014-04-10  Michael Saboff  <msaboff@apple.com>
-
-        LLInt interpreter code should be generated as part of one function
-        https://bugs.webkit.org/show_bug.cgi?id=131205
-
-        Reviewed by Mark Lam.
-
-        Changed the generation of llint opcodes so that they are all part of the same
-        global function, llint_entry.  That function is used to fill in an entry point
-        table that includes each of the opcodes and helpers.
-
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh:
-        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Added appropriate use of new -I option to offline assembler and offset
-        generator scripts.
-
-        * llint/LowLevelInterpreter.asm:
-        * llint/LowLevelInterpreter.cpp:
-        * llint/LowLevelInterpreter.h:
-        * offlineasm/arm.rb:
-        * offlineasm/arm64.rb:
-        * offlineasm/asm.rb:
-        * offlineasm/ast.rb:
-        * offlineasm/backends.rb:
-        * offlineasm/cloop.rb:
-        * offlineasm/generate_offset_extractor.rb:
-        * offlineasm/instructions.rb:
-        * offlineasm/parser.rb:
-        * offlineasm/registers.rb:
-        * offlineasm/self_hash.rb:
-        * offlineasm/settings.rb:
-        * offlineasm/transform.rb:
-        * offlineasm/x86.rb:
-        Added a new "global" keyword to the offline assembler that denotes a label that
-        should be exported.  Added opcode and operand support to get the absolute
-        address of a local label using position independent calculations.  Updated the
-        offline assembler to handle included files, both when generating the checksum
-        as well as including files from other than the local directory via a newly
-        added -I option.  The offline assembler now automatically determines external
-        functions by keeping track of referenced functions that are defined within the
-        assembly source.  This is used both for choosing the correct macro for external
-        references as well as generating the needed EXTERN directives for masm.
-        Updated the generation of the masm only .sym file to be written once at the end
-        of the offline assembler.
-
-        * assembler/MacroAssemblerCodeRef.h:
-        (JSC::MacroAssemblerCodePtr::createLLIntCodePtr):
-        (JSC::MacroAssemblerCodeRef::createLLIntCodeRef):
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::dumpBytecode):
-        (JSC::CodeBlock::CodeBlock):
-        * bytecode/GetByIdStatus.cpp:
-        (JSC::GetByIdStatus::computeFromLLInt):
-        * bytecode/Opcode.h:
-        (JSC::padOpcodeName):
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeFromLLInt):
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompileMainPass):
-        * jit/JITStubs.h:
-        * llint/LLIntCLoop.cpp:
-        (JSC::LLInt::initialize):
-        * llint/LLIntData.h:
-        (JSC::LLInt::getCodeFunctionPtr):
-        (JSC::LLInt::getOpcode): Deleted.
-        (JSC::LLInt::getCodePtr): Deleted.
-        * llint/LLIntOpcode.h:
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * llint/LLIntThunks.cpp:
-        (JSC::LLInt::functionForCallEntryThunkGenerator):
-        (JSC::LLInt::functionForConstructEntryThunkGenerator):
-        (JSC::LLInt::functionForCallArityCheckThunkGenerator):
-        (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
-        (JSC::LLInt::evalEntryThunkGenerator):
-        (JSC::LLInt::programEntryThunkGenerator):
-        * llint/LLIntThunks.h:
-        Changed references to llint helpers to go through the entry point table populated
-        by llint_entry.  Added helpers to OpcodeID enum for all builds.
-
-        * bytecode/BytecodeList.json:
-        * generate-bytecode-files:
-        * llint/LLIntCLoop.cpp:
-        (JSC::LLInt::CLoop::initialize):
-        Reordered sections to match the order that the functions are added to the entry point
-        table.  Added new "asmPrefix" property for symbols that have one name but are generated
-        with a prefix, e.g. op_enter -> llint_op_enter.  Eliminated the "emitDefineID" property
-        as we are using enums for all bytecode references.  Changed the C Loop only
-        llint_c_loop_init to llint_entry.
-
-2014-04-10  Matthew Mirman  <mmirman@apple.com>
-
-        WIP for inlining C++.  Added a build target to produce LLVM IR.
-        https://bugs.webkit.org/show_bug.cgi?id=130523
-
-        Reviewed by Mark Rowe.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * build-symbol-table-index.py: Added.
-        * build-symbol-table-index.sh: Added.
-        * Configurations/CompileRuntimeToLLVMIR.xcconfig: Added.
-        * copy-llvm-ir-to-derived-sources.sh: Added.
-
-2014-04-10  Brian J. Burg  <burg@cs.washington.edu>
-
-        Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
-        https://bugs.webkit.org/show_bug.cgi?id=131341
-
-        Reviewed by Timothy Hatcher.
-
-        Add support for encoding/decoding unsigned long with EncodedValue.
-        It is a distinct type from uint32_t and uint64_t.
-
-        * replay/EncodedValue.cpp:
-        (JSC::EncodedValue::convertTo<unsigned long>):
-        * replay/EncodedValue.h:
-
-2014-04-10  Mark Lam  <mark.lam@apple.com>
-
-        LLINT loadisFromInstruction should handle the big endian case.
-        <https://webkit.org/b/131495>
-
-        Reviewed by Mark Hahnenberg.
-
-        The LLINT loadisFromInstruction macro aims to load the least significant
-        32-bit word from the 64-bit bytecode instruction stream and sign extend
-        it.  For big endian machines, the current implementation would load the
-        wrong 32-bit word.
-
-        Without this fix, the JSC tests will crash on big endian machines.
-        Thanks to Tomas Popela for diagnosing this issue.
-
-        * llint/LowLevelInterpreter.asm:
-
-2014-04-09  Mark Lam  <mark.lam@apple.com>
-
-        Temporarily disable the JIT for the Windows port.
-        <https://webkit.org/b/131470>
-
-        Reviewed by Brent Fulgham.
-
-        This is a temporary stop gap measure to green the Windows bots until
-        we have a fix for https://webkit.org/b/131182.
-
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-
-2014-04-09  Juergen Ributzka  <juergen@apple.com>
-
-        [FTL] Emit multibyte NOPs on X86-64
-        https://bugs.webkit.org/show_bug.cgi?id=131394
-
-        Reviewed by Michael Saboff.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::fillNops):
-
-2014-04-09  Julien Brianceau  <jbriance@cisco.com>
-
-        Get rid of JITOperationWrappers.h header file.
-        https://bugs.webkit.org/show_bug.cgi?id=131450
-
-        Reviewed by Michael Saboff.
-
-        JITOperationWrappers header file contains architecture specific code that is
-        not needed anymore, so get rid of it.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGOperations.cpp:
-        * jit/JITOperationWrappers.h: Removed.
-        * jit/JITOperations.cpp:
-
-2014-04-09  Mark Lam  <mark.lam@apple.com>
-
-        Ensure that LLINT accessing of the ProtoCallFrame is big endian friendly.
-        <https://webkit.org/b/131449>
-
-        Reviewed by Mark Hahnenberg.
-
-        Change ProtoCallFrame::paddedArgCount to be of type uint32_t.  The argCount
-        that it pads is of type int anyway.  It doesn't need to be 64 bit.  This
-        also makes it work with the LLINT which is loading it with a loadi
-        instruction.
-
-        We should add the PayLoadOffset to ProtoCallFrame::argCountAndCodeOriginValue
-        when loading the argCount.
-
-        The paddedArgCount issue was causing failures when running the JSC tests on a
-        64-bit big endian machine.  In this case, the paddedArgCount in the
-        ProtoCallFrame has the value 2.  However, because the paddedArgCount was stored
-        as a 64-bit size_t and the LLINT was loading only the low address 32-bits of
-        that field, the LLINT got a value of 0 instead of the expected 2.  With this
-        patch, we now have a matching store and load of a 32-bit value, and endianness
-        no longer comes into play.
-
-        As for ProtoCallFrame::argCountAndCodeOriginValue, the argCount is stored in
-        the payload field of the Register.  In the definition of EncodedValueDescriptor,
-        We already ensure that that the payload is in the least significant 32-bits for
-        little endian machines, and in the most significant 32-bits for big endian
-        machines.  This means that there is no endianness bug when loading this value
-        using loadi.  However, adding the PayLoadOffset clarifies the intent of the
-        code to load the payload part of the Register value.
-
-        * interpreter/ProtoCallFrame.h:
-        (JSC::ProtoCallFrame::setPaddedArgCount):
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-
-2014-04-08  Oliver Hunt  <oliver@apple.com>
-
-        Rewrite Function.bind as a builtin
-        https://bugs.webkit.org/show_bug.cgi?id=131083
-
-        Reviewed by Geoffrey Garen.
-
-        This change removes the existing function.bind implementation
-        entirely so JSBoundFunction is no more.
-
-        Instead we just return a regular JS closure with a few
-        private properties hanging off it that allow us to perform
-        the necessary bound function fakery.  While most of this is
-        simple, a couple of key changes:
-
-        - The parser and lexer now directly track whether they're
-          parsing code for call or construct and convert the private
-          name @IsConstructor into TRUETOK or FALSETOK as appropriate.
-          This automatically gives us the ability to vary behaviour
-          from within the builtin. It also leaves a lot of headroom
-          for trivial future improvements.
-        - The instanceof operator now uses the prototypeForHasInstance
-          private name, and we have a helper function to ensure that
-          all objects that need to can update their magical 'prototype'
-          property pair correctly.
-
-        * API/JSScriptRef.cpp:
-        (parseScript):
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * builtins/BuiltinExecutables.cpp:
-        (JSC::BuiltinExecutables::createBuiltinExecutable):
-        * builtins/Function.prototype.js:
-        (bind.bindingFunction):
-        (bind.else.bindingFunction):
-        (bind):
-        * bytecode/UnlinkedCodeBlock.cpp:
-        (JSC::generateFunctionCodeBlock):
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::InstanceOfNode::emitBytecode):
-        * interpreter/Interpreter.cpp:
-        * parser/Lexer.cpp:
-        (JSC::Lexer<T>::Lexer):
-        (JSC::Lexer<LChar>::parseIdentifier):
-        (JSC::Lexer<UChar>::parseIdentifier):
-        * parser/Lexer.h:
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::Parser):
-        (JSC::Parser<LexerType>::parseInner):
-        * parser/Parser.h:
-        (JSC::parse):
-        * parser/ParserModes.h:
-        * runtime/CodeCache.cpp:
-        (JSC::CodeCache::getGlobalCodeBlock):
-        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
-        * runtime/CommonIdentifiers.h:
-        * runtime/Completion.cpp:
-        (JSC::checkSyntax):
-        * runtime/Executable.cpp:
-        (JSC::ProgramExecutable::checkSyntax):
-        * runtime/FunctionPrototype.cpp:
-        (JSC::FunctionPrototype::addFunctionProperties):
-        (JSC::functionProtoFuncBind): Deleted.
-        * runtime/JSBoundFunction.cpp: Removed.
-        * runtime/JSBoundFunction.h: Removed.
-        * runtime/JSFunction.cpp:
-        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
-        (JSC::RetrieveCallerFunctionFunctor::operator()):
-        (JSC::retrieveCallerFunction):
-        (JSC::JSFunction::getOwnPropertySlot):
-        (JSC::JSFunction::defineOwnProperty):
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::globalFuncSetTypeErrorAccessor):
-        * runtime/JSGlobalObjectFunctions.h:
-        * runtime/JSObject.h:
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-
-2014-04-08  Jon Lee  <jonlee@apple.com>
-
-        Turn MSE on by default
-        https://bugs.webkit.org/show_bug.cgi?id=131313
-        <rdar://problem/16525223>
-
-        Reviewed by Jer Noble.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-04-08  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Prevent deadlocks receiving WIRPermissionDenied message
-        https://bugs.webkit.org/show_bug.cgi?id=131406
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/remote/RemoteInspector.h:
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::stop):
-        (Inspector::RemoteInspector::stopInternal):
-        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
-        Provide a way to stop externally and a path to stop when in
-        the middle of handling a message already with the locked mutex.
-
-        * inspector/remote/RemoteInspectorXPCConnection.h:
-        * inspector/remote/RemoteInspectorXPCConnection.mm:
-        (Inspector::RemoteInspectorXPCConnection::close):
-        (Inspector::RemoteInspectorXPCConnection::closeFromMessage):
-        Provide a way to close externally and a path to close when in
-        the middle of handling a message already with a mutex.
-
-2014-04-08  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Address stale FIXMEs concerning console in JSContext inspection
-        https://bugs.webkit.org/show_bug.cgi?id=131398
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/InjectedScriptSource.js:
-        The console object can be deleted from a page or JSContext,
-        so keep code that expects that it could have been deleted
-        to be resilient in those cases.
-
-        * inspector/JSGlobalObjectScriptDebugServer.h:
-        * inspector/agents/JSGlobalObjectDebuggerAgent.h:
-        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
-        Change the FIXMEs to NOTEs that explain why these functions
-        have empty implementations for JSContext inspection.
-
-2014-04-08  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix a goofy assertion to fix debug.
-
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::isSetter):
-        (JSC::PutByIdAccess::oldStructure):
-        (JSC::PutByIdAccess::chain):
-        (JSC::PutByIdAccess::stubRoutine):
-        (JSC::PutByIdAccess::customSetter):
-
-2014-04-08  Filip Pizlo  <fpizlo@apple.com>
-
-        Fail silently if the LLVM dylib isn't found
-        https://bugs.webkit.org/show_bug.cgi?id=131385
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::compileInThreadImpl):
-        * llvm/InitializeLLVM.cpp:
-        (JSC::initializeLLVM):
-        * llvm/InitializeLLVM.h:
-        * llvm/InitializeLLVMPOSIX.cpp:
-        (JSC::initializeLLVMPOSIX):
-
-2014-04-07  Filip Pizlo  <fpizlo@apple.com>
-
-        Repatch should support setters and plant calls to them directly
-        https://bugs.webkit.org/show_bug.cgi?id=130750
-
-        Reviewed by Geoffrey Garen.
-        
-        All of the infrastructure was in place so this just enables setter optimization.
-        
-        This is a 12x speed-up on setter microbenchmarks. This is a 1% speed-up on Octane.
-
-        * bytecode/PolymorphicPutByIdList.cpp:
-        (JSC::PutByIdAccess::visitWeak):
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::setter):
-        (JSC::PutByIdAccess::customSetter): Deleted.
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeForStubInfo):
-        * jit/Repatch.cpp:
-        (JSC::toString):
-        (JSC::kindFor):
-        (JSC::customFor):
-        (JSC::generateByIdStub):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::put):
-        * runtime/Lookup.h:
-        (JSC::putEntry):
-        * runtime/PutPropertySlot.h:
-        (JSC::PutPropertySlot::setCacheableSetter):
-        (JSC::PutPropertySlot::isCacheableSetter):
-        (JSC::PutPropertySlot::isCacheableCustom):
-        (JSC::PutPropertySlot::setCacheableCustomProperty): Deleted.
-        (JSC::PutPropertySlot::isCacheableCustomProperty): Deleted.
-        * tests/stress/setter.js: Added.
-        (foo):
-
-2014-04-07  Filip Pizlo  <fpizlo@apple.com>
-
-        Setters are just getters that take an extra argument and don't return a value
-        https://bugs.webkit.org/show_bug.cgi?id=131336
-
-        Reviewed by Geoffrey Garen.
-        
-        Other than that, they're totally the same thing.
-        
-        This isn't as dumb as it sounds.        
-
-        Most of the work in calling an accessor has to do with emitting the necessary checks for
-        figuring out whether we're calling the accessor we expected, followed by the boilerplate
-        needed for setting up a call inside of a stub. It makes sense for the code to be totally
-        common.
-
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::storeValue):
-        (JSC::AssemblyHelpers::moveTrustedValue):
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupResults):
-        * jit/Repatch.cpp:
-        (JSC::kindFor):
-        (JSC::customFor):
-        (JSC::generateByIdStub):
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        (JSC::generateGetByIdStub): Deleted.
-        (JSC::emitCustomSetterStub): Deleted.
-        * runtime/JSCJSValue.h:
-        (JSC::JSValue::asValue):
-        * runtime/PutPropertySlot.h:
-        (JSC::PutPropertySlot::cachedOffset):
-
-2014-04-07  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Hang in debuggable application after receiving WIRPermissionDenied
-        https://bugs.webkit.org/show_bug.cgi?id=131321
-
-        Reviewed by Mark Rowe.
-
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
-        Avoid attempting to take the same lock twice. Move the received message
-        lock grab after the WIRPermissionDenied branch, which takes the lock
-        inside RemoteInspector::stop.
-
-2014-04-07  Filip Pizlo  <fpizlo@apple.com>
-
-        Make it possible to disable some of the FTL's more interesting features
-        https://bugs.webkit.org/show_bug.cgi?id=131312
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleGetById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        (JSC::DFG::ByteCodeParser::parse):
-        * runtime/Options.h:
-
-2014-04-04  Mark Lam  <mark.lam@apple.com>
-
-        Date object needs to check for ES5 15.9.1.14 TimeClip limit.
-        <https://webkit.org/b/131248>
-
-        Reviewed by Mark Hahnenberg.
-
-        The current Date object code does not adequately check for the ES5
-        15.9.1.14 TimeClip limit.  As a result, some calculations can underflow
-        / overflow and produce unexpected results.
-
-        For example, we were getting an assertion failure in
-        WTF::equivalentYearForDST() due int underflows in this function, which
-        in turn were due to an int overflow in WTF::msToYear().
-
-        This patch adds the needed checks, and adds some assertions to ensure
-        that the used values are sane.
-
-        The changes have no noticeable impact on benchmark results.
-
-        * runtime/DateConstructor.cpp:
-        (JSC::callDate):
-        * runtime/JSDateMath.cpp:
-        (JSC::localTimeOffset):
-        (JSC::gregorianDateTimeToMS):
-        (JSC::msToGregorianDateTime):
-        (JSC::parseDateFromNullTerminatedCharacters):
-        (JSC::parseDate):
-        * runtime/JSDateMath.h:
-        - parseDateFromNullTerminatedCharacters() does not need to be public.
-          Made it a static function.
-        * runtime/VM.cpp:
-        (JSC::VM::resetDateCache):
-        - Changed cachedDateStringValue to use std::numeric_limits<double>::quiet_NaN()
-          to be consistent with other Date code.
-
-2014-04-06  Csaba Osztrogonác  <ossy@webkit.org>
-
-        Unreviewed speculative 32-bit buildfix after r166837.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::updateObjectCounts):
-
-2014-04-06  Dan Bernstein  <mitz@apple.com>
-
-        32-bit build fix.
-
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::setInputCursor):
-
-2014-04-04  Brian J. Burg  <burg@cs.washington.edu>
-
-        Enable WEB_REPLAY for PLATFORM(MAC)
-        https://bugs.webkit.org/show_bug.cgi?id=130700
-
-        Reviewed by Timothy Hatcher.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-04-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Add missing files from r166837
-
-        * heap/GCLogging.cpp: Added.
-        (JSC::GCLogging::levelAsString):
-        (JSC::LoggingFunctor::LoggingFunctor):
-        (JSC::LoggingFunctor::~LoggingFunctor):
-        (JSC::LoggingFunctor::operator()):
-        (JSC::LoggingFunctor::log):
-        (JSC::LoggingFunctor::reviveCells):
-        (JSC::LoggingFunctor::returnValue):
-        (JSC::GCLogging::dumpObjectGraph):
-        * heap/GCLogging.h: Added.
-
-2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Enhanced GC logging
-        https://bugs.webkit.org/show_bug.cgi?id=131246
-
-        Reviewed by Geoff Garen.
-
-        Getting data on the state of the JSC Heap at runtime is currently in a sad state. 
-        The OBJECT_MARK_LOGGING macro enables some basic GC logging, but it requires a full 
-        recompile to turn it on. It would be nice if we could runtime enable our GC logging 
-        infrastructure while incurring minimal cost when it is disabled. 
-
-        It would also be nice to get a complete view of the Heap. Currently OBJECT_MARK_LOGGING 
-        provides us with the discovered roots along with parent-child relationships as objects 
-        are scanned. However, once an object is scanned it will never be declared as the child 
-        of another object during that collection. This gives us a tree-like view of the 
-        Heap (i.e. each scanned node only reports having a single parent), where the actual 
-        Heap can be an arbitrary graph.
-
-        This patch replaces OBJECT_MARK_LOGGING and gives us these nice to haves. First it enhances 
-        our logGC() runtime Option by changing it to be a tri-state value of None, Basic, or Verbose 
-        logging levels. None means no logging is done, Basic is what logGC() = true would have done 
-        prior to this patch, and Verbose logs all object relationships.
-
-        JSCell has new dump/dumpToStream methods, the latter of which is "virtual" to allow 
-        subclasses to override the default string representation that will be dumped. These 
-        methods allow JSCells to be dumped using the standard dataLog() calls similar to much of
-        the logging infrastructure in our compilers.
-
-        This patch also adds a GCLogging class that handles dumping the relationships between objects.
-        It does this by using the pre-existing visitChildren virtual methods to obtain the immediate
-        children of each live cell at the end of garbage collection.
-
-        This change meets our goal of being neutral on the benchmarks we track.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * heap/GCLogging.cpp: Added.
-        (JSC::GCLogging::levelAsString):
-        (JSC::LoggingFunctor::LoggingFunctor):
-        (JSC::LoggingFunctor::operator()):
-        (JSC::LoggingFunctor::log):
-        (JSC::LoggingFunctor::reviveCells):
-        (JSC::LoggingFunctor::returnValue):
-        (JSC::GCLogging::dumpObjectGraph):
-        * heap/GCLogging.h: Added.
-        * heap/GCSegmentedArray.h:
-        (JSC::GCSegmentedArray::begin):
-        (JSC::GCSegmentedArray::end):
-        * heap/Heap.cpp:
-        (JSC::Heap::markRoots):
-        (JSC::Heap::visitSmallStrings):
-        (JSC::Heap::visitConservativeRoots):
-        (JSC::Heap::visitCompilerWorklists):
-        (JSC::Heap::visitProtectedObjects):
-        (JSC::Heap::visitTempSortVectors):
-        (JSC::Heap::visitArgumentBuffers):
-        (JSC::Heap::visitException):
-        (JSC::Heap::visitStrongHandles):
-        (JSC::Heap::visitHandleStack):
-        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
-        (JSC::Heap::visitWeakHandles):
-        (JSC::Heap::updateObjectCounts):
-        (JSC::Heap::collect):
-        (JSC::Heap::didFinishCollection):
-        * heap/Heap.h:
-        * heap/MarkStack.h:
-        * heap/SlotVisitor.cpp:
-        (JSC::SlotVisitor::dump):
-        * heap/SlotVisitor.h:
-        (JSC::SlotVisitor::markStack):
-        * heap/SlotVisitorInlines.h:
-        (JSC::SlotVisitor::internalAppend):
-        * runtime/ClassInfo.h:
-        * runtime/JSCell.cpp:
-        (JSC::JSCell::dump):
-        (JSC::JSCell::dumpToStream):
-        (JSC::JSCell::className):
-        * runtime/JSCell.h:
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::visitChildren):
-        * runtime/JSString.cpp:
-        (JSC::JSString::dumpToStream):
-        (JSC::JSString::visitChildren):
-        * runtime/JSString.h:
-        (JSC::JSString::length):
-        (JSC::JSRopeString::RopeBuilder::length):
-        * runtime/Options.cpp:
-        (JSC::parse):
-        (JSC::Options::setOption):
-        (JSC::Options::dumpOption):
-        * runtime/Options.h:
-
-2014-04-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Remove bogus ASSERT in -JSVirtualMachine scanObjectGraph
-        https://bugs.webkit.org/show_bug.cgi?id=131251
-
-        Reviewed by Geoffrey Garen.
-
-        * API/JSVirtualMachine.mm:
-        (scanExternalObjectGraph):
-        * API/tests/testapi.mm:
-
-2014-04-03  Brian J. Burg  <burg@cs.washington.edu>
-
-        Web Inspector: hook up probe samples to TimelineAgent's records
-        https://bugs.webkit.org/show_bug.cgi?id=131127
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/ScriptDebugListener.h: Add a proper forward declaration for ScriptBreakpointAction.
-
-2014-04-04  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r166820.
-        https://bugs.webkit.org/show_bug.cgi?id=131256
-
-        Broke builds. (Requested by bdash on #webkit).
-
-        Reverted changeset:
-
-        "WIP for inlining C++.  Added a build target to produce llvm
-        ir."
-        https://bugs.webkit.org/show_bug.cgi?id=130523
-        http://trac.webkit.org/changeset/166820
-
-2014-04-04  Matthew Mirman  <mmirman@apple.com>
-
-        WIP for inlining C++.  Added a build target to produce llvm ir.
-        https://bugs.webkit.org/show_bug.cgi?id=130523
-
-        Reviewed by Filip Pizlo.
-
-        The llvm ir gets placed JavaScriptCoreRuntimeToLLVMir.build with the extension .o
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * build_index.py: Added.
-        * Configurations/CompileRuntimeToLLVMir.xcconfig: Added.
-
-2014-04-04  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Log JS Exceptions to System Console if JavaScriptCoreOutputConsoleMessagesToSystemConsole enabled
-        https://bugs.webkit.org/show_bug.cgi?id=131241
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-        Log the exception to the system console if system console output is enabled.
-
-2014-04-04  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Provide a way for JSContext console to log to system console
-        https://bugs.webkit.org/show_bug.cgi?id=131050
-
-        Reviewed by Timothy Hatcher.
-
-        Applications often re-expose some log -> NSLog functionality.
-        We already have the capability ourselves, which includes extra
-        information such as sourceURL:line:column, all arguments instead
-        of just one argument, and backtrace information on console.trace.
-        Therefore it would be convenient if developers could just use
-        the built-in console.log and get rich output in both the inspector
-        and the console, without writing their own logger.
-
-        The logging will be enabled in debug builds by default, and can be enabled
-        otherwise by setting a user default before creating the first context.
-        
-        For example, in the application itself:
-
-            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"JavaScriptCoreOutputConsoleMessagesToSystemConsole"];
-
-        Or from outside the application:
-        
-            shell> defaults write <app-bundle-identifier> JavaScriptCoreOutputConsoleMessagesToSystemConsole -bool YES
-
-        * inspector/JSConsoleClient.h:
-        * inspector/JSConsoleClient.cpp:
-        (Inspector::JSConsoleClient::logToSystemConsole):
-        (Inspector::JSConsoleClient::setLogToSystemConsole):
-        (Inspector::JSConsoleClient::initializeLogToSystemConsole):
-        (Inspector::JSConsoleClient::JSConsoleClient):
-        Global setting for logging to system console. Enabled on
-        debug builds, and by a user default on supported platforms.
-
-        (Inspector::JSConsoleClient::messageWithTypeAndLevel):
-        Log to system console when the static setting is enabled.
-
-        * runtime/ConsoleClient.h:
-        * runtime/ConsoleClient.cpp:
-        (JSC::appendURLAndPosition):
-        (JSC::appendMessagePrefix):
-        (JSC::ConsoleClient::printConsoleMessage):
-        (JSC::ConsoleClient::printConsoleMessageWithArguments):
-        Clean up printing. Build strings and use WTFLogAlways instead of printf
-        for consistant logging.
-
-        * runtime/ConsoleClient.cpp:
-        (JSC::ConsoleClient::printConsoleMessageWithArguments):
-        Clean up printing. If there is no source URL, don't print a leading colon.
-
-2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Use JSCell::indexingType instead of Structure::indexingType wherever possible
-        https://bugs.webkit.org/show_bug.cgi?id=131230
-
-        Reviewed by Mark Lam.
-
-        Avoid the indirection through the Structure.
-
-        * bytecode/ArrayAllocationProfile.cpp:
-        (JSC::ArrayAllocationProfile::updateIndexingType):
-        * bytecode/ArrayAllocationProfile.h:
-        (JSC::ArrayAllocationProfile::selectIndexingType):
-        * heap/HeapStatistics.cpp:
-        (JSC::StorageStatistics::operator()):
-        * runtime/ArrayPrototype.cpp:
-        (JSC::attemptFastSort):
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::objectPrototypeIsSane):
-        (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
-        (JSC::JSGlobalObject::stringPrototypeChainIsSane):
-        * runtime/JSPropertyNameIterator.cpp:
-        (JSC::JSPropertyNameIterator::create):
-
-2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Use JSCell::type instead of TypeInfo::type wherever possible
-        https://bugs.webkit.org/show_bug.cgi?id=131229
-
-        Reviewed by Michael Saboff.
-
-        Avoid going through the Structure and reifying the TypeInfo.
-
-        * runtime/Executable.h:
-        (JSC::ExecutableBase::isEvalExecutable):
-        (JSC::ExecutableBase::isProgramExecutable):
-
-2014-04-03  Andreas Kling  <akling@apple.com>
-
-        Fast-path for casting JS wrappers to JSNode.
-        <https://webkit.org/b/131196>
-
-        Allow code outside of JSC (well, WebCore) to extend the JSType spectrum
-        a little bit. We do this by exposing a LastJSCObjectType constant so
-        WebCore can encode its own wrapper types after that.
-
-        Reviewed by Mark Hahnenberg and Geoff Garen.
-
-        * runtime/JSType.h:
-
-            Added LastJSCObjectType for use by WebCore.
-
-        * runtime/JSObject.h:
-        (JSC::JSObject::isVariableObject):
-
-            Updated since this can no longer assume that types >= VariableObjectType
-            are all variable objects.
-
-2014-04-03  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        All Heap::writeBarriers should be inline
-        https://bugs.webkit.org/show_bug.cgi?id=131197
-
-        Reviewed by Mark Lam.
-
-        One is in a JSCellInlines.h, another is in Heap.cpp. These are all critical 
-        enough and small enough to belong in HeapInlines.h. Also added the proper 
-        ENABLE(GGC) ifdefs to minimize the cost of C++ barriers for !ENABLE(GGC) builds.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::writeBarrier): Deleted.
-        * heap/Heap.h:
-        * heap/HeapInlines.h:
-        (JSC::Heap::writeBarrier):
-        * runtime/JSCellInlines.h:
-        (JSC::Heap::writeBarrier): Deleted.
-
-2014-04-03  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: JSContext inspection provide a way to opt-out of including Native Call Stacks in Exception traces reported to Web Inspector
-        https://bugs.webkit.org/show_bug.cgi?id=131186
-
-        Reviewed by Geoffrey Garen.
-
-        * API/JSContextPrivate.h:
-        * API/JSContext.mm:
-        (-[JSContext _includesNativeCallStackWhenReportingExceptions]):
-        (-[JSContext _setIncludesNativeCallStackWhenReportingExceptions:]):
-        JSContext ObjC SPI to opt-out of including native call stacks in exceptions.
-
-        * API/JSContextRefPrivate.h:
-        * API/JSContextRef.cpp:
-        (JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions):
-        (JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions):
-        JSContext C SPI to opt-out of including native call stacks in exceptions.
-
-        * inspector/JSGlobalObjectInspectorController.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-        Only include the native call stack if the setting is enabled. It is enabled by default.
-
-2014-04-03  Mark Lam  <mark.lam@apple.com>
-
-        Fix bit rot in ARMv7 JIT probe mechanism.
-        <https://webkit.org/b/131167>
-
-        Reviewed by Geoffrey Garen.
-
-        1. The macro assembler does not support pushing the SP register.  Worked
-           around this by pushing the LR register as a placeholder, and then
-           writing the original SP value to that slot.
-        2. The CPUState field in the ProbeContext needs to be aligned on a 4
-           byte boundary, not an 8 byte boundary.
-
-        * assembler/MacroAssemblerARMv7.cpp:
-        (JSC::MacroAssemblerARMv7::probe):
-        * jit/JITStubsARMv7.h:
-
-2014-04-02  Mark Lam  <mark.lam@apple.com>
-
-        ARMv7 compare32() should not use TST to do CMP's job.
-        <https://webkit.org/b/131146>
-
-        Reviewed by Geoffrey Garen.
-
-        The ARMv7 implementation of "compare32(RegisterID left, TrustedImm32 right)"
-        was using "tst reg, reg" to implement "cmp reg, #0".  Unfortunately, the tst
-        instruction doesn't set the Overflow (V) flag and this results in random
-        results depending on whether there was a preceeding instruction that did set
-        the Overflow (V) flag.  This issue was causing emscripten-cube2hash to run
-        with a lot of OSR exits where not expected as well as producing wrong results.
-
-        The fix is to use "cmp reg, #0" to do the job properly.
-
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::compare32):
-
-2014-04-02  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        CodeBlockSet should be generational
-        https://bugs.webkit.org/show_bug.cgi?id=127152
-
-        Reviewed by Geoffrey Garen.
-
-        During EdenCollections we now only visit those CodeBlocks that:
-        a) Are new since the last collection if they were somehow otherwise reachable.
-        b) Are reachable from an Executable that is part of the remembered set.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::CodeBlock): Initialize uninitialized variables.
-        (JSC::CodeBlock::visitAggregate): Move the addition of the weak reference harvester after the
-        shouldImmediatelyAssumeLivenessDuringScan check since it's redundant if we assume liveness.
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::forEachRelatedCodeBlock): Executes a functor for each CodeBlock reachable from the current CodeBlock (including this).
-        We use this to clear marks for the CodeBlocks of remembered Executables (see: CodeBlockSet::clearMarksForEdenCollection).
-        (JSC::CodeBlockSet::mark): Also check the set of new CodeBlocks for memebership when doing conservative scanning.
-        (JSC::ScriptExecutable::forEachCodeBlock): Executes a functor for each of this Executable's CodeBlocks.
-        * heap/CodeBlockSet.cpp:
-        (JSC::CodeBlockSet::~CodeBlockSet):
-        (JSC::CodeBlockSet::add):
-        (JSC::CodeBlockSet::promoteYoungCodeBlocks): Moves all CodeBlocks currently in the set of new CodeBlocks into 
-        the set of old CodeBlocks.
-        (JSC::CodeBlockSet::clearMarksForFullCollection): Clears the marks for all CodeBlocks.
-        (JSC::CodeBlockSet::clearMarksForEdenCollection): Clears the marks for CodeBlocks owned by Executables in the 
-        remembered set. When an Executable is added to the remembered set it's typically because we need to do something 
-        with its CodeBlock.
-        (JSC::CodeBlockSet::clearMarks):
-        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): Fixpoints over either just the new CodeBlocks or all CodeBlocks
-        to determine which CodeBlocks are dead and eagerly finalizes/deletes them.
-        (JSC::CodeBlockSet::remove):
-        (JSC::CodeBlockSet::traceMarked): Iterate only the currently executing CodeBlocks instead of all CodeBlocks.
-        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks): Clear m_mayBeExecuting for all currently executing 
-        CodeBlocks because we no longer always do this at the beginning of EdenCollections.
-        * heap/CodeBlockSet.h:
-        (JSC::CodeBlockSet::iterate):
-        * heap/Heap.cpp:
-        (JSC::Heap::markRoots):
-        (JSC::Heap::deleteAllCompiledCode):
-        (JSC::Heap::deleteUnmarkedCompiledCode):
-        * runtime/Executable.cpp:
-        (JSC::ScriptExecutable::installCode): Write barrier code on installation. We do this due to the following situation:
-        a) A CodeBlock is created and is compiled on a DFG worker thread.
-        b) No GC happens.
-        c) The CodeBlock has finished being compiled and is installed in the Executable.
-        d) The function never executes before the next GC.
-        e) The next GC needs needs to visit the new CodeBlock but the Executable won't be revisited unless 
-            it's added to the remembered set.
-
-2014-04-02  Mark Lam  <mark.lam@apple.com>
-
-        Added some more dataLog info for OSR exits.
-        <https://webkit.org/b/131120>
-
-        Reviewed by Michael Saboff.
-
-        Adding info about the OSR exit index, the bytecode index of the bytecode
-        that is OSR exiting, and the reason for the OSR exit.  This change is
-        for debugging code which only comes into play when we use the
-        --printEachOSRExit option.
-
-        * dfg/DFGOSRExit.h:
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOperations.cpp:
-
-2014-04-02  Martin Robinson  <mrobinson@igalia.com>
-
-        REGRESSION(r165704): [GTK] Inspector resources not correctly generated
-        https://bugs.webkit.org/show_bug.cgi?id=130343
-
-        Reviewed by Gustavo Noronha Silva.
-
-        * CMakeLists.txt: We generate the inspector JavaScript file into a directory like the one
-        in which it should be distributed. This allows us to more easily package it for GTK+.
-
-2014-04-01  Timothy Hatcher  <timothy@apple.com>
-
-        Remove HeapProfiler from the Web Inspector protocol.
-
-        https://bugs.webkit.org/show_bug.cgi?id=131070
-
-        Reviewed by Joseph Pecoraro.
-
-        * inspector/agents/InspectorConsoleAgent.h:
-        * inspector/agents/JSGlobalObjectConsoleAgent.cpp:
-        (Inspector::JSGlobalObjectConsoleAgent::addInspectedHeapObject): Deleted.
-        * inspector/agents/JSGlobalObjectConsoleAgent.h:
-        * inspector/protocol/Console.json:
-
-2014-03-31  Simon Fraser  <simon.fraser@apple.com>
-
-        Enable WEB_TIMING on Mac and iOS
-        https://bugs.webkit.org/show_bug.cgi?id=128064
-
-        Reviewed by Sam Weinig, Brent Fulgham.
-
-        Enable WEB_TIMING.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-03-31  Michael Saboff  <msaboff@apple.com>
-
-        REGRESSION(r166415): JSObject{Get,Set}Private() don't work with proxies objects
-        https://bugs.webkit.org/show_bug.cgi?id=130992
-
-        Reviewed by Mark Hahnenberg.
-
-        Forward JSObjectGetPrivate() and JSObjectSetPrivate() to the wrapped object.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectGetPrivate):
-        (JSObjectSetPrivate):
-        * API/tests/testapi.c:
-        (main): Added new test case to validate we are properly foarwarding.
-
-2014-03-31  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Improve GC_LOGGING
-        https://bugs.webkit.org/show_bug.cgi?id=130988
-
-        Reviewed by Geoffrey Garen.
-
-        GC_LOGGING can be useful for diagnosing where we're spending our time during collection, 
-        but it doesn't distinguish between Eden and Full collections in the data it gathers. This
-        patch updates it so that it can. It also adds the process ID to the beginning of each line 
-        of input to be able to distinguish between the output of multiple processes exiting at the 
-        same time.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::collect):
-
-2014-03-31  Dean Jackson  <dino@apple.com>
-
-        Remove WEB_ANIMATIONS
-        https://bugs.webkit.org/show_bug.cgi?id=130989
-
-        Reviewed by Simon Fraser.
-
-        Remove this feature flag until we plan to implement.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-03-31  Filip Pizlo  <fpizlo@apple.com>
-
-        More validation for FTL inline caches
-        https://bugs.webkit.org/show_bug.cgi?id=130948
-
-        Reviewed by Geoffrey Garen.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleGetById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        * runtime/Options.h:
-
-2014-03-31  Filip Pizlo  <fpizlo@apple.com>
-
-        LLVM IR for store barriers should be nicely arranged and they don't need exception checks
-        https://bugs.webkit.org/show_bug.cgi?id=130950
-
-        Reviewed by Mark Hahnenberg.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
-
-2014-03-31  Raphael Kubo da Costa  <raphael.kubo.da.costa@intel.com>
-
-        [CMake] Stop checking for WTF_USE_ICU_UNICODE.
-        https://bugs.webkit.org/show_bug.cgi?id=130965
-
-        Reviewed by Martin Robinson.
-
-        This is somewhat of a follow-up to r162782, which got rid of
-        WTF_USE_ICU_UNICODE in CMake but did not remove the check in JSC's
-        CMakeLists.txt. This meant the includes and libraries were not
-        being properly included since then.
-
-        * CMakeLists.txt:
-
-2014-03-31  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
-
-        Remove hostThisRegister() and hostThisValue()
-        https://bugs.webkit.org/show_bug.cgi?id=130895
-
-        Reviewed by Geoffrey Garen.
-
-        Removed hostThisRegister() and hostThisValue() and instead use thisArgumentOffset() and thisValue() respectively.
-
-        * API/APICallbackFunction.h:
-        (JSC::APICallbackFunction::call):
-        * API/JSCallbackObjectFunctions.h:
-        (JSC::JSCallbackObject<Parent>::call):
-        * dfg/DFGOSREntry.cpp:
-        (JSC::DFG::prepareOSREntry):
-        * inspector/JSInjectedScriptHostPrototype.cpp:
-        (Inspector::jsInjectedScriptHostPrototypeAttributeEvaluate):
-        (Inspector::jsInjectedScriptHostPrototypeFunctionInternalConstructorName):
-        (Inspector::jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection):
-        (Inspector::jsInjectedScriptHostPrototypeFunctionType):
-        (Inspector::jsInjectedScriptHostPrototypeFunctionFunctionDetails):
-        (Inspector::jsInjectedScriptHostPrototypeFunctionGetInternalProperties):
-        * inspector/JSJavaScriptCallFramePrototype.cpp:
-        (Inspector::jsJavaScriptCallFramePrototypeFunctionEvaluate):
-        (Inspector::jsJavaScriptCallFramePrototypeFunctionScopeType):
-        (Inspector::jsJavaScriptCallFrameAttributeCaller):
-        (Inspector::jsJavaScriptCallFrameAttributeSourceID):
-        (Inspector::jsJavaScriptCallFrameAttributeLine):
-        (Inspector::jsJavaScriptCallFrameAttributeColumn):
-        (Inspector::jsJavaScriptCallFrameAttributeFunctionName):
-        (Inspector::jsJavaScriptCallFrameAttributeScopeChain):
-        (Inspector::jsJavaScriptCallFrameAttributeThisObject):
-        (Inspector::jsJavaScriptCallFrameAttributeType):
-        * interpreter/CallFrame.h:
-        (JSC::ExecState::hostThisRegister): Deleted.
-        (JSC::ExecState::hostThisValue): Deleted.
-        * runtime/Arguments.cpp:
-        (JSC::argumentsFuncIterator):
-        * 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::arrayProtoFuncReduce):
-        (JSC::arrayProtoFuncReduceRight):
-        (JSC::arrayProtoFuncIndexOf):
-        (JSC::arrayProtoFuncLastIndexOf):
-        (JSC::arrayProtoFuncValues):
-        (JSC::arrayProtoFuncEntries):
-        (JSC::arrayProtoFuncKeys):
-        * runtime/BooleanPrototype.cpp:
-        (JSC::booleanProtoFuncToString):
-        (JSC::booleanProtoFuncValueOf):
-        * runtime/ConsolePrototype.cpp:
-        (JSC::consoleLogWithLevel):
-        (JSC::consoleProtoFuncClear):
-        (JSC::consoleProtoFuncDir):
-        (JSC::consoleProtoFuncDirXML):
-        (JSC::consoleProtoFuncTable):
-        (JSC::consoleProtoFuncTrace):
-        (JSC::consoleProtoFuncAssert):
-        (JSC::consoleProtoFuncCount):
-        (JSC::consoleProtoFuncProfile):
-        (JSC::consoleProtoFuncProfileEnd):
-        (JSC::consoleProtoFuncTime):
-        (JSC::consoleProtoFuncTimeEnd):
-        (JSC::consoleProtoFuncTimeStamp):
-        (JSC::consoleProtoFuncGroup):
-        (JSC::consoleProtoFuncGroupCollapsed):
-        (JSC::consoleProtoFuncGroupEnd):
-        * runtime/DatePrototype.cpp:
-        (JSC::formateDateInstance):
-        (JSC::dateProtoFuncToISOString):
-        (JSC::dateProtoFuncToLocaleString):
-        (JSC::dateProtoFuncToLocaleDateString):
-        (JSC::dateProtoFuncToLocaleTimeString):
-        (JSC::dateProtoFuncGetTime):
-        (JSC::dateProtoFuncGetFullYear):
-        (JSC::dateProtoFuncGetUTCFullYear):
-        (JSC::dateProtoFuncGetMonth):
-        (JSC::dateProtoFuncGetUTCMonth):
-        (JSC::dateProtoFuncGetDate):
-        (JSC::dateProtoFuncGetUTCDate):
-        (JSC::dateProtoFuncGetDay):
-        (JSC::dateProtoFuncGetUTCDay):
-        (JSC::dateProtoFuncGetHours):
-        (JSC::dateProtoFuncGetUTCHours):
-        (JSC::dateProtoFuncGetMinutes):
-        (JSC::dateProtoFuncGetUTCMinutes):
-        (JSC::dateProtoFuncGetSeconds):
-        (JSC::dateProtoFuncGetUTCSeconds):
-        (JSC::dateProtoFuncGetMilliSeconds):
-        (JSC::dateProtoFuncGetUTCMilliseconds):
-        (JSC::dateProtoFuncGetTimezoneOffset):
-        (JSC::dateProtoFuncSetTime):
-        (JSC::setNewValueFromTimeArgs):
-        (JSC::setNewValueFromDateArgs):
-        (JSC::dateProtoFuncSetYear):
-        (JSC::dateProtoFuncGetYear):
-        (JSC::dateProtoFuncToJSON):
-        * runtime/ErrorPrototype.cpp:
-        (JSC::errorProtoFuncToString):
-        * runtime/FunctionPrototype.cpp:
-        (JSC::functionProtoFuncToString):
-        (JSC::functionProtoFuncBind):
-        * runtime/NamePrototype.cpp:
-        (JSC::privateNameProtoFuncToString):
-        * runtime/NumberPrototype.cpp:
-        (JSC::numberProtoFuncToExponential):
-        (JSC::numberProtoFuncToFixed):
-        (JSC::numberProtoFuncToPrecision):
-        (JSC::numberProtoFuncClz):
-        (JSC::numberProtoFuncToString):
-        (JSC::numberProtoFuncToLocaleString):
-        (JSC::numberProtoFuncValueOf):
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncValueOf):
-        (JSC::objectProtoFuncHasOwnProperty):
-        (JSC::objectProtoFuncIsPrototypeOf):
-        (JSC::objectProtoFuncDefineGetter):
-        (JSC::objectProtoFuncDefineSetter):
-        (JSC::objectProtoFuncLookupGetter):
-        (JSC::objectProtoFuncLookupSetter):
-        (JSC::objectProtoFuncPropertyIsEnumerable):
-        (JSC::objectProtoFuncToLocaleString):
-        (JSC::objectProtoFuncToString):
-        * runtime/RegExpPrototype.cpp:
-        (JSC::regExpProtoFuncTest):
-        (JSC::regExpProtoFuncExec):
-        (JSC::regExpProtoFuncCompile):
-        (JSC::regExpProtoFuncToString):
-        * runtime/StringPrototype.cpp:
-        (JSC::stringProtoFuncReplace):
-        (JSC::stringProtoFuncToString):
-        (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::stringProtoFuncTrim):
-        (JSC::stringProtoFuncTrimLeft):
-        (JSC::stringProtoFuncTrimRight):
-
-2014-03-28  Filip Pizlo  <fpizlo@apple.com>
-
-        Land the stackmap register liveness glue with the uses of the liveness disabled
-        https://bugs.webkit.org/show_bug.cgi?id=130924
-
-        Reviewed by Oliver Hunt.
-        
-        Add the liveness and fix other bugs I found.
-
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeFor):
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::usedRegistersFor):
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        * ftl/FTLSlowPathCall.cpp:
-        * ftl/FTLSlowPathCallKey.cpp:
-        (JSC::FTL::SlowPathCallKey::dump):
-        * ftl/FTLSlowPathCallKey.h:
-        (JSC::FTL::SlowPathCallKey::SlowPathCallKey):
-        (JSC::FTL::SlowPathCallKey::argumentRegisters):
-        (JSC::FTL::SlowPathCallKey::withCallTarget):
-        * ftl/FTLStackMaps.cpp:
-        (JSC::FTL::StackMaps::Record::locationSet):
-        (JSC::FTL::StackMaps::Record::liveOutsSet):
-        (JSC::FTL::StackMaps::Record::usedRegisterSet):
-        * ftl/FTLStackMaps.h:
-        * ftl/FTLThunks.cpp:
-        (JSC::FTL::registerClobberCheck):
-        (JSC::FTL::slowPathCallThunkGenerator):
-        * jit/RegisterSet.cpp:
-        (JSC::RegisterSet::stackRegisters):
-        (JSC::RegisterSet::reservedHardwareRegisters):
-        (JSC::RegisterSet::runtimeRegisters):
-        (JSC::RegisterSet::specialRegisters):
-        (JSC::RegisterSet::dump):
-        * jit/RegisterSet.h:
-        (JSC::RegisterSet::RegisterSet):
-        (JSC::RegisterSet::setAny):
-        (JSC::RegisterSet::setMany):
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        (JSC::tryCachePutByID):
-        (JSC::tryRepatchIn):
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-        * runtime/Options.h:
-
-2014-03-28  Mark Lam  <mark.lam@apple.com>
-
-        mandreel throws a checksum error on 32-bit x86.
-        <https://webkit.org/b/125706>
-
-        Reviewed by Filip Pizlo.
-
-        The 32-bit DFG can emit code that loads double constants from its
-        CodeBlock's m_constantRegisters vector.  The emitted instruction will
-        embed the address of the constant from the vector's backing store.
-        Subsequently, while inserting new constants, the DFG may resize the
-        vector, thereby reallocating the backing store.  This renders the
-        previously embedded constant addresses stale.
-
-        The fix is to use a dedicated doubles constant pool stored in the DFG
-        CommonData instead.  This constant pool won't be reallocated, and
-        hence will not manifest this issue.
-
-        * dfg/DFGCommonData.h:
-        * dfg/DFGGraph.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::link):
-        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
-        * dfg/DFGJITCompiler.h:
-        (JSC::DFG::JITCompiler::addressOfDoubleConstant): Deleted.
-
-2014-03-28  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: console.warn is showing as error instead of warning
-        https://bugs.webkit.org/show_bug.cgi?id=130921
-
-        Reviewed by Timothy Hatcher.
-
-        * runtime/ConsolePrototype.cpp:
-        (JSC::consoleProtoFuncWarn):
-        console.warn should be MessageLevel Warning, not Error.
-
-2014-03-28  Oliver Hunt  <oliver@apple.com>
-
-        Fix cloop build.
-
-        * bytecode/BytecodeList.json:
-
-2014-03-28  Michael Saboff  <msaboff@apple.com>
-
-        Unreviewed, rolling r166248 back in.
-
-        Turns out r166070 didn't cause a 2% performance loss in page load times
-
-        Reverted changeset:
-
-        Unreviewed, rolling out r166126.
-        Rollout r166126 in prepartion to roll out prerequisite r166070
-
-2014-03-27  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r166376.
-        https://bugs.webkit.org/show_bug.cgi?id=130887
-
-        This was a misguided optimization. (Requested by kling on
-        #webkit).
-
-        Reverted changeset:
-
-        "Avoid fetching JSObject::structure() repeatedly in
-        putDirectInternal."
-        https://bugs.webkit.org/show_bug.cgi?id=130857
-        http://trac.webkit.org/changeset/166376
-
-2014-03-27  Oliver Hunt  <oliver@apple.com>
-
-        Support spread operand in |new| expressions
-        https://bugs.webkit.org/show_bug.cgi?id=130877
-
-        Reviewed by Michael Saboff.
-
-        Add support for the spread operator being applied in
-        |new| expressions.  This required adding support for
-        a new opcode, op_construct_varargs.  This is a relatively
-        simple refactoring of the call_varargs implementation.
-
-        * bytecode/BytecodeList.json:
-        * bytecode/BytecodeUseDef.h:
-        (JSC::computeUsesForBytecodeOffset):
-        (JSC::computeDefsForBytecodeOffset):
-        * bytecode/CallLinkInfo.cpp:
-        (JSC::CallLinkInfo::unlink):
-        * bytecode/CallLinkInfo.h:
-        (JSC::CallLinkInfo::callTypeFor):
-        (JSC::CallLinkInfo::specializationKind):
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::dumpBytecode):
-        (JSC::CodeBlock::CodeBlock):
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::emitCallVarargs):
-        (JSC::BytecodeGenerator::emitConstructVarargs):
-        (JSC::BytecodeGenerator::emitConstruct):
-        * bytecompiler/BytecodeGenerator.h:
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompileMainPass):
-        (JSC::JIT::privateCompileSlowCases):
-        * jit/JIT.h:
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::compileOpCallSlowCase):
-        (JSC::JIT::emit_op_construct_varargs):
-        (JSC::JIT::emitSlow_op_construct_varargs):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::emitSlow_op_construct_varargs):
-        (JSC::JIT::emit_op_construct_varargs):
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::compileOpCallSlowCase):
-        * jit/JITOperations.cpp:
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * llint/LLIntSlowPaths.h:
-        * llint/LowLevelInterpreter.asm:
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::parseMemberExpression):
-
-2014-03-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Revert http://trac.webkit.org/changeset/166386 because it broke builds.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/LLVMForJSC.xcconfig:
-
-2014-03-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, skip this test for now.
-
-        * tests/stress/recurse-infinitely-on-getter.js:
-
-2014-03-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Switch the LLVMForJSC target to using the LLVM in /usr/local rather than /usr/local/LLVMForJavaScriptCore on iOS
-        https://bugs.webkit.org/show_bug.cgi?id=130867
-        <rdar://problem/16432456> 
-
-        Reviewed by Mark Hahnenberg.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/LLVMForJSC.xcconfig:
-
-2014-03-27  Andreas Kling  <akling@apple.com>
-
-        Avoid fetching JSObject::structure() repeatedly in putDirectInternal.
-        <https://webkit.org/b/130857>
-
-        Use the cached Structure* instead of re-fetching it over and over since
-        that's a non-trivial operation these days.
-
-        Reviewed by Mark Hahnenberg.
-
-        * runtime/JSObject.h:
-        (JSC::JSObject::putDirectInternal):
-
-2014-03-27  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Check the remembered set bit faster
-        https://bugs.webkit.org/show_bug.cgi?id=130860
-
-        Reviewed by Oliver Hunt.
-
-        Currently we look up the remembered set bit in the MarkedBlock in C++ code, but 
-        that bit is also stored in the object. We should look it up there whenever possible.
-
-        * heap/CopiedBlockInlines.h:
-        (JSC::CopiedBlock::shouldReportLiveBytes):
-        * heap/Heap.cpp:
-        (JSC::Heap::addToRememberedSet):
-        * heap/Heap.h:
-        * heap/HeapInlines.h: Removed.
-        * heap/SlotVisitorInlines.h:
-        (JSC::SlotVisitor::reportExtraMemoryUsage):
-
-2014-03-27  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Provide SPI to disallow remote inspection of a JSContext
-        https://bugs.webkit.org/show_bug.cgi?id=130853
-
-        Reviewed by Timothy Hatcher.
-
-        * API/JSContextPrivate.h: Added.
-        * API/JSContext.mm:
-        (-[JSContext _remoteInspectionEnabled]):
-        (-[JSContext _setRemoteInspectionEnabled:]):
-        ObjC SPI to enable/disable remote inspection.
-
-        * API/JSContextRefPrivate.h:
-        * API/JSContextRef.cpp:
-        (JSGlobalContextGetRemoteInspectionEnabled):
-        (JSGlobalContextSetRemoteInspectionEnabled):
-        C SPI to enable/disable remote inspection.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Add new private header, and export as a private header.
-
-2014-03-27  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Clean up questionable style in ScriptExecutable::prepareForExecutionImpl
-        https://bugs.webkit.org/show_bug.cgi?id=130845
-
-        Reviewed by Filip Pizlo.
-
-        There was a hack added to make sure C Loop LLInt worked which included overriding the 
-        global Options::useLLInt setting, which makes no sense to do here. We should put the 
-        update of the global setting in Options::recomputeDependentOptions along with the other 
-        execution engine flags.
-
-        * runtime/Executable.cpp:
-        (JSC::ScriptExecutable::prepareForExecutionImpl):
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-
-2014-03-26  Filip Pizlo  <fpizlo@apple.com>
-
-        Enable LLVM stackmap liveOuts computation
-        https://bugs.webkit.org/show_bug.cgi?id=130821
-
-        Reviewed by Andy Estes and Sam Weinig.
-
-        * ftl/FTLStackMaps.cpp:
-        (JSC::FTL::StackMaps::Record::dump):
-        * llvm/library/LLVMExports.cpp:
-        (initializeAndGetJSCLLVMAPI):
-
-2014-03-26  Filip Pizlo  <fpizlo@apple.com>
-
-        Parse stackmaps liveOuts
-        https://bugs.webkit.org/show_bug.cgi?id=130801
-
-        Reviewed by Geoffrey Garen.
-        
-        This just adds the code to parse them but doesn't do anything with them, yet.
-
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::forStackmaps):
-        * ftl/FTLLocation.h:
-        (JSC::FTL::Location::forRegister):
-        (JSC::FTL::Location::forIndirect):
-        * ftl/FTLStackMaps.cpp:
-        (JSC::FTL::StackMaps::Location::parse):
-        (JSC::FTL::StackMaps::Location::dump):
-        (JSC::FTL::StackMaps::LiveOut::parse):
-        (JSC::FTL::StackMaps::LiveOut::dump):
-        (JSC::FTL::StackMaps::Record::parse):
-        (JSC::FTL::StackMaps::Record::dump):
-        * ftl/FTLStackMaps.h:
-
-2014-03-26  Mark Lam  <mark.lam@apple.com>
-
-        Build fix after r166307.
-
-        Not reviewed.
-
-        * runtime/JSCell.h:
-        - The inline function isAPIValueWrapper() should not be exported.  This
-          was causing a linkage error when building for 32-bit x86 on Mac.
-
-2014-03-26  Filip Pizlo  <fpizlo@apple.com>
-
-        Reasoning about DWARF register numbers should be moved out of FTL::Location
-        https://bugs.webkit.org/show_bug.cgi?id=130792
-
-        Reviewed by Oliver Hunt.
-        
-        Moving this code makes it possible for things other than FTL::Location to reason about
-        DWARF register encoding. This refactoring also appears to reduce some code duplication
-        and makes FTLLocation.cpp cleaner.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        * ftl/FTLDWARFRegister.cpp: Added.
-        (JSC::FTL::DWARFRegister::reg):
-        (JSC::FTL::DWARFRegister::dump):
-        * ftl/FTLDWARFRegister.h: Added.
-        (JSC::FTL::DWARFRegister::DWARFRegister):
-        (JSC::FTL::DWARFRegister::dwarfRegNum):
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::dump):
-        (JSC::FTL::Location::isGPR):
-        (JSC::FTL::Location::gpr):
-        (JSC::FTL::Location::isFPR):
-        (JSC::FTL::Location::fpr):
-        * ftl/FTLLocation.h:
-        (JSC::FTL::Location::hasDwarfReg):
-        (JSC::FTL::Location::dwarfReg):
-
-2014-03-26  Brent Fulgham  <bfulgham@apple.com>
-
-        Unreviewed build fix.
-
-        * runtime/JSCell.h: VS2013 confused about argument type.
-
-2014-03-26  Zoltan Horvath  <zoltan@webkit.org>
-
-        [CSS Shapes] Remove shape-inside support
-        https://bugs.webkit.org/show_bug.cgi?id=130698
-
-        Reviewed by David Hyatt.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-03-26  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
-
-        Rename hasFastArrayStorage to be more appropriate
-        https://bugs.webkit.org/show_bug.cgi?id=130773
-
-        Reviewed by Filip Pizlo.
-
-        * dfg/DFGArrayMode.cpp:
-        (JSC::DFG::ArrayMode::alreadyChecked):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGWatchpointCollectionPhase.cpp:
-        (JSC::DFG::WatchpointCollectionPhase::handle):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNewArray):
-        (JSC::FTL::LowerDFGToLLVM::compileNewArrayBuffer):
-        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
-        * runtime/ButterflyInlines.h:
-        (JSC::Butterfly::unshift):
-        (JSC::Butterfly::shift):
-        * runtime/IndexingHeaderInlines.h:
-        (JSC::IndexingHeader::preCapacity):
-        * runtime/IndexingType.h:
-        (JSC::hasArrayStorage):
-        (JSC::hasAnyArrayStorage):
-        (JSC::hasFastArrayStorage): Deleted.
-        * runtime/JSArray.cpp:
-        (JSC::JSArray::sortVector):
-        (JSC::JSArray::compactForSorting):
-        * runtime/JSArray.h:
-        (JSC::JSArray::create):
-        (JSC::JSArray::tryCreateUninitialized):
-        * runtime/JSGlobalObject.cpp:
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
-        * runtime/JSObject.h:
-        (JSC::JSObject::ensureArrayStorage):
-        (JSC::JSObject::arrayStorage):
-        * runtime/StructureTransitionTable.h:
-        (JSC::newIndexingType):
-
-2014-03-26  Zan Dobersek  <zdobersek@igalia.com>
-
-        Unreviewed. Removing the remaining Automake cruft.
-
-        * GNUmakefile.list.am: Removed.
-
-2014-03-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Arguments simplification phase should be fine with marking the arguments local itself as an arguments alias
-        https://bugs.webkit.org/show_bug.cgi?id=130764
-        <rdar://problem/16304788>
-
-        Reviewed by Sam Weinig.
-        
-        Being an arguments alias just means that your OSR exit recovery should attempt arguments
-        creation. This is true of arguments locals. We had special cases that tried to make it not
-        true of arguments locals. The only consequence of those special cases was to cause crashes
-        in case of arguments that are also captured variables (i.e. we have SlowArguments). This
-        change just removes those special cases.
-        
-        This change means that the FTL will now see SetLocals with a FlushedArguments format.
-        Previously you wouldn't see them because previously only non-captured variable would be
-        arguments aliases, and non-captured variables get completely SSAified - i.e. no SetLocals
-        left. Adding handling for FlushedArguments is a benign and simple change since its
-        behavior is identical to FlushedJSValue for that code's purposes.
-
-        * dfg/DFGArgumentsSimplificationPhase.cpp:
-        (JSC::DFG::ArgumentsSimplificationPhase::run):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
-        * tests/stress/captured-arguments-variable.js: Added.
-        (foo):
-        (noInline):
-
-2014-03-25  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Add HeapInlines
-        https://bugs.webkit.org/show_bug.cgi?id=130759
-
-        Reviewed by Filip Pizlo.
-
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * heap/Heap.cpp:
-        (JSC::MarkedBlockSnapshotFunctor::MarkedBlockSnapshotFunctor):
-        (JSC::MarkedBlockSnapshotFunctor::operator()):
-        * heap/Heap.h: Also reindented while we're here.
-        (JSC::Heap::writeBarrierBuffer):
-        (JSC::Heap::vm):
-        (JSC::Heap::objectSpace):
-        (JSC::Heap::machineThreads):
-        (JSC::Heap::operationInProgress):
-        (JSC::Heap::allocatorForObjectWithoutDestructor):
-        (JSC::Heap::allocatorForObjectWithNormalDestructor):
-        (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor):
-        (JSC::Heap::storageAllocator):
-        (JSC::Heap::notifyIsSafeToCollect):
-        (JSC::Heap::isSafeToCollect):
-        (JSC::Heap::handleSet):
-        (JSC::Heap::handleStack):
-        (JSC::Heap::lastFullGCLength):
-        (JSC::Heap::lastEdenGCLength):
-        (JSC::Heap::increaseLastFullGCLength):
-        (JSC::Heap::sizeBeforeLastEdenCollection):
-        (JSC::Heap::sizeAfterLastEdenCollection):
-        (JSC::Heap::sizeBeforeLastFullCollection):
-        (JSC::Heap::sizeAfterLastFullCollection):
-        (JSC::Heap::jitStubRoutines):
-        (JSC::Heap::isDeferred):
-        (JSC::Heap::structureIDTable):
-        (JSC::Heap::removeCodeBlock):
-        * heap/HeapInlines.h: Added.
-        (JSC::Heap::shouldCollect):
-        (JSC::Heap::isBusy):
-        (JSC::Heap::isCollecting):
-        (JSC::Heap::heap):
-        (JSC::Heap::isLive):
-        (JSC::Heap::isInRememberedSet):
-        (JSC::Heap::isMarked):
-        (JSC::Heap::testAndSetMarked):
-        (JSC::Heap::setMarked):
-        (JSC::Heap::isWriteBarrierEnabled):
-        (JSC::Heap::writeBarrier):
-        (JSC::Heap::reportExtraMemoryCost):
-        (JSC::Heap::forEachProtectedCell):
-        (JSC::Heap::forEachCodeBlock):
-        (JSC::Heap::allocateWithNormalDestructor):
-        (JSC::Heap::allocateWithImmortalStructureDestructor):
-        (JSC::Heap::allocateWithoutDestructor):
-        (JSC::Heap::tryAllocateStorage):
-        (JSC::Heap::tryReallocateStorage):
-        (JSC::Heap::ascribeOwner):
-        (JSC::Heap::blockAllocator):
-        (JSC::Heap::releaseSoon):
-        (JSC::Heap::incrementDeferralDepth):
-        (JSC::Heap::decrementDeferralDepth):
-        (JSC::Heap::collectIfNecessaryOrDefer):
-        (JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
-        (JSC::Heap::markListSet):
-        * runtime/JSCInlines.h:
-
-2014-03-25  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG::ByteCodeParser::SetMode should distinguish between setting immediately without a flush and setting immediately with a flush
-        https://bugs.webkit.org/show_bug.cgi?id=130760
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::setLocal):
-        (JSC::DFG::ByteCodeParser::setArgument):
-        (JSC::DFG::ByteCodeParser::handleInlining):
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * tests/stress/assign-argument-in-inlined-call.js: Added.
-        (f1):
-        (getF2Arguments):
-        (f2):
-        (f3):
-        * tests/stress/assign-captured-argument-in-inlined-call.js: Added.
-        (f1):
-        (f2):
-        (f3):
-
-2014-03-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Fix 32-bit getter call alignment.
-
-        Reviewed by Mark Hahnenberg.
-
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub):
-
-2014-03-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Repatch should plant calls to getters directly rather than through a C helper
-        https://bugs.webkit.org/show_bug.cgi?id=129589
-
-        Reviewed by Mark Hahnenberg.
-        
-        As the title says. All of the superstructure for this was already in place, so now it
-        was just a matter of actually emitting the call.
-        
-        8x speed-up for getter microbenchmarks. 
-
-        * CMakeLists.txt:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/PolymorphicGetByIdList.h:
-        (JSC::GetByIdAccess::doesCalls):
-        * jit/AccessorCallJITStubRoutine.cpp: Added.
-        (JSC::AccessorCallJITStubRoutine::AccessorCallJITStubRoutine):
-        (JSC::AccessorCallJITStubRoutine::~AccessorCallJITStubRoutine):
-        (JSC::AccessorCallJITStubRoutine::visitWeak):
-        * jit/AccessorCallJITStubRoutine.h: Added.
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::storeCell):
-        * jit/GCAwareJITStubRoutine.h:
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub):
-        * runtime/GetterSetter.h:
-        (JSC::GetterSetter::offsetOfGetter):
-        (JSC::GetterSetter::offsetOfSetter):
-
-2014-03-25  Michael Saboff  <msaboff@apple.com>
-
-        Unreviewed, rolling out r166126.
-
-        Rollout r166126 in prepartion to roll out prerequisite r166070
-
-        Reverted changeset:
-
-        "toThis() on a JSWorkerGlobalScope should return a JSProxy and
-        not undefined"
-        https://bugs.webkit.org/show_bug.cgi?id=130554
-        http://trac.webkit.org/changeset/166126
-
-2014-03-25  Oliver Hunt  <oliver@apple.com>
-
-        AST incorrectly conflates readable and writable locations
-        https://bugs.webkit.org/show_bug.cgi?id=130734
-
-        Reviewed by Filip Pizlo.
-
-        We need to distinguish between "locations" that are valid for reading
-        and writing, vs those that may only be written.
-
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::ForInNode::emitBytecode):
-        (JSC::ForOfNode::emitBytecode):
-        * parser/Nodes.h:
-        (JSC::ExpressionNode::isAssignmentLocation):
-
-2014-03-24  Oliver Hunt  <oliver@apple.com>
-
-        ASSERTION FAILED in Parser: dst != localReg
-        https://bugs.webkit.org/show_bug.cgi?id=130710
-
-        Reviewed by Filip Pizlo.
-
-        Just make sure we don't try to write to a captured constant,
-        following the change to track captured variables separately.
-
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::PostfixNode::emitResolve):
-        (JSC::PrefixNode::emitResolve):
-
-2014-03-25  Martin Robinson  <mrobinson@igalia.com>
-
-        [GTK] Remove the autotools build
-        https://bugs.webkit.org/show_bug.cgi?id=130717
-
-        Reviewed by Anders Carlsson.
-
-        * GNUmakefile.am: Removed.
-        * config.h: Remove references to the autotools configure file.
-
-2014-03-24  Filip Pizlo  <fpizlo@apple.com>
-
-        More scaffolding for a stub routine to have a stub recursively embedded inside it
-        https://bugs.webkit.org/show_bug.cgi?id=130770
-
-        Reviewed by Oliver Hunt.
-
-        * bytecode/CallLinkInfo.cpp:
-        (JSC::CallLinkInfo::unlink): VM& argument is superfluous.
-        (JSC::CallLinkInfo::visitWeak): Factor this out, it used to be in CodeBlock::finalizeUnconditionally().
-        * bytecode/CallLinkInfo.h:
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::finalizeUnconditionally): Factor out some functionality into CallLinkInfo::visitWeak(), and make sure we pass RepatchBuffer& in more places.
-        (JSC::CodeBlock::unlinkCalls):
-        (JSC::CodeBlock::unlinkIncomingCalls):
-        * bytecode/PolymorphicGetByIdList.cpp: Pass RepatchBuffer& through and call JITStubRoutine::visitWeak().
-        (JSC::GetByIdAccess::visitWeak):
-        (JSC::PolymorphicGetByIdList::visitWeak):
-        * bytecode/PolymorphicGetByIdList.h:
-        * bytecode/PolymorphicPutByIdList.cpp: Pass RepatchBuffer& through and call JITStubRoutine::visitWeak().
-        (JSC::PutByIdAccess::visitWeak):
-        (JSC::PolymorphicPutByIdList::visitWeak):
-        * bytecode/PolymorphicPutByIdList.h:
-        * bytecode/StructureStubInfo.cpp: Pass RepatchBuffer& through.
-        (JSC::StructureStubInfo::visitWeakReferences):
-        * bytecode/StructureStubInfo.h:
-        * jit/ClosureCallStubRoutine.cpp: isClosureCall is unused.
-        (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
-        * jit/GCAwareJITStubRoutine.cpp:
-        (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
-        (JSC::createJITStubRoutine):
-        * jit/GCAwareJITStubRoutine.h: Make it easier to construct one of these.
-        (JSC::GCAwareJITStubRoutine::isClosureCall): Deleted.
-        * jit/JITStubRoutine.cpp:
-        (JSC::JITStubRoutine::visitWeak): This will allow future JITStubRoutine subclasses to have stubs recursively embedded inside them.
-        * jit/JITStubRoutine.h:
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub): Fix a possible GC bug where we weren't making the stub routine GC aware.
-        (JSC::emitCustomSetterStub): Clean up some code.
-
-2014-03-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Safari crashes in JavaScriptCore: JSC::JSObject::growOutOfLineStorage
-        when WebKit is compiled with fcatch-undefined-behavior
-        https://bugs.webkit.org/show_bug.cgi?id=130652
-
-        Reviewed by Mark Hahnenberg.
-
-        Use a static member function because the butterfly we pass in might be
-        NULL, and passing NULL to a member function is undefined behavior.
-
-        Stylistically, I think this new way reads a little more clearly, since it
-        matches createOrGrowArrayRight, and it helps to convey that m_butterfly
-        might not exist yet.
-
-        * runtime/Butterfly.h:
-        * runtime/ButterflyInlines.h:
-        (JSC::Butterfly::createOrGrowPropertyStorage): Renamed from growPropertyStorage
-        because we might create. Split out the create path to avoid using NULL
-        in a member function expression.
-
-        Removed some unused versions of this function.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::growOutOfLineStorage): Updated for interface change.
-
-2014-03-24  Oliver Hunt  <oliver@apple.com>
-
-        Strict mode destructuring assignment crashes the parser.
-        https://bugs.webkit.org/show_bug.cgi?id=130538
-
-        Reviewed by Michael Saboff.
-
-        The SyntaxChecker mode always return 1 for success, except
-        for a small subset of functions where we needed exact information.
-        This ends up just being a poor design decision as it means
-        the parser can get confused between a function return 1, and
-        the Resolve constant which was also 1. So we now use a unique
-        type for every creation method.
-
-        * parser/SyntaxChecker.h:
-        (JSC::SyntaxChecker::createSourceElements):
-        (JSC::SyntaxChecker::createFunctionBody):
-        (JSC::SyntaxChecker::createArguments):
-        (JSC::SyntaxChecker::createSpreadExpression):
-        (JSC::SyntaxChecker::createArgumentsList):
-        (JSC::SyntaxChecker::createPropertyList):
-        (JSC::SyntaxChecker::createElementList):
-        (JSC::SyntaxChecker::createFormalParameterList):
-        (JSC::SyntaxChecker::createClause):
-        (JSC::SyntaxChecker::createClauseList):
-        (JSC::SyntaxChecker::createFuncDeclStatement):
-        (JSC::SyntaxChecker::createBlockStatement):
-        (JSC::SyntaxChecker::createExprStatement):
-        (JSC::SyntaxChecker::createIfStatement):
-        (JSC::SyntaxChecker::createForLoop):
-        (JSC::SyntaxChecker::createForInLoop):
-        (JSC::SyntaxChecker::createForOfLoop):
-        (JSC::SyntaxChecker::createEmptyStatement):
-        (JSC::SyntaxChecker::createVarStatement):
-        (JSC::SyntaxChecker::createReturnStatement):
-        (JSC::SyntaxChecker::createBreakStatement):
-        (JSC::SyntaxChecker::createContinueStatement):
-        (JSC::SyntaxChecker::createTryStatement):
-        (JSC::SyntaxChecker::createSwitchStatement):
-        (JSC::SyntaxChecker::createWhileStatement):
-        (JSC::SyntaxChecker::createWithStatement):
-        (JSC::SyntaxChecker::createDoWhileStatement):
-        (JSC::SyntaxChecker::createLabelStatement):
-        (JSC::SyntaxChecker::createThrowStatement):
-        (JSC::SyntaxChecker::createDebugger):
-        (JSC::SyntaxChecker::createConstStatement):
-        (JSC::SyntaxChecker::appendConstDecl):
-        (JSC::SyntaxChecker::combineCommaNodes):
-        (JSC::SyntaxChecker::operatorStackPop):
-
-2014-03-24  Brent Fulgham  <bfulgham@apple.com>
-
-        Activate WebVTT Tests Once Merging is Complete
-        https://bugs.webkit.org/show_bug.cgi?id=130420
-
-        Reviewed by Eric Carlson.
-
-        * Configurations/FeatureDefines.xcconfig: Turn on ENABLE(WEBVTT_REGIONS)
-
-2014-03-24  Andreas Kling  <akling@apple.com>
-
-        Stop pulling in all the macro assemblers from VM.h
-        <https://webkit.org/b/130691>
-
-        Remove #include of "GPRInfo.h". This breaks WebCore's dependency
-        on macro assemblers headers and removes 8 includes from every
-        .cpp file in the JS bindings.
-
-        Reviewed by Geoff Garen.
-
-        * runtime/VM.h:
-
-2014-03-24  Gavin Barraclough  <barraclough@apple.com>
-
-        Add support for thread QoS
-        https://bugs.webkit.org/show_bug.cgi?id=130688
-
-        Reviewed by Andreas Kling.
-
-        * heap/BlockAllocator.cpp:
-        (JSC::BlockAllocator::blockFreeingThreadStartFunc):
-            - block freeing is a utility activity.
-
-2014-03-24  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix CLOOP build.
-
-        * bytecode/CallLinkStatus.cpp:
-        (JSC::CallLinkStatus::computeFor):
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::printCallOp):
-        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
-        (JSC::CodeBlock::resetStubDuringGCInternal): Deleted.
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::callLinkInfosEnd): Deleted.
-
-2014-03-24  Gabor Rapcsanyi  <rgabor@webkit.org>
-
-        [ARM64] GNU assembler doesn't work with LLInt arm64 backend.
-        https://bugs.webkit.org/show_bug.cgi?id=130453
-        
-        Reviewed by Filip Pizlo.
-
-        Change fp and lr to x29 and x30. Add both operand kinds to emitARM64()
-        at sxtw and uxtw instructions.
-
-        * offlineasm/arm64.rb:
-
-2014-03-23  Hyowon Kim  <hw1008.kim@samsung.com>
-
-        Move all EFL typedefs into EflTypedefs.h.
-        https://bugs.webkit.org/show_bug.cgi?id=130511
-
-        Reviewed by Gyuyoung Kim
-
-        * heap/HeapTimer.h: Remove EFL typedefs.
-
-2014-03-23  Filip Pizlo  <fpizlo@apple.com>
-
-        Gotta grow the locals vectors if we are about to do SetLocals beyond the bytecode's numCalleeRegisters
-        https://bugs.webkit.org/show_bug.cgi?id=130650
-        <rdar://problem/16122966>
-
-        Reviewed by Michael Saboff.
-        
-        Previously, it was only in the case of inlining that we would do SetLocal's beyond the
-        previously established numLocals limit. But then we added generalized op_call_varargs
-        handling, which results in us emitting SetLocals that didn't previously exist in the
-        bytecode.
-        
-        This factors out the inliner's ensureLocals loop and calls it from op_call_varargs.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::ensureLocals):
-        (JSC::DFG::ByteCodeParser::handleInlining):
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        (JSC::DFG::ByteCodeParser::parse):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub): Make this do alignment correctly.
-        * runtime/Options.h:
-        * tests/stress/call-varargs-from-inlined-code.js: Added.
-        * tests/stress/call-varargs-from-inlined-code-with-odd-number-of-arguments.js: Added.
-
-2014-03-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, adjust sizes for ARM64.
-
-        * ftl/FTLInlineCacheSize.cpp:
-        (JSC::FTL::sizeOfCall):
-
-2014-03-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Protect the silent spiller/filler's desire to fill Int32Constants by making sure that we don't mark something as having a Int32 register format if it's a non-Int32 constant
-        https://bugs.webkit.org/show_bug.cgi?id=130649
-        <rdar://problem/16399949>
-
-        Reviewed by Andreas Kling.
-
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
-        * tests/stress/fuzz-bug-16399949.js: Added.
-        (tryItOut.f):
-        (tryItOut):
-
-2014-03-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Call linking slow paths should be passed a CallLinkInfo* directly so that you can create a call IC without adding it to any CodeBlocks
-        https://bugs.webkit.org/show_bug.cgi?id=130644
-
-        Reviewed by Andreas Kling.
-        
-        This is conceptually a really simple change but it involves the following:
-        
-        - The inline part of the call IC stuffs a pointer to the CallLinkInfo into regT2.
-        
-        - CodeBlock uses a Bag of CallLinkInfos instead of a Vector.
-        
-        - Remove the significance of a CallLinkInfo's index. This means that DFG::JITCode no
-          longer has a vector of slow path counts that shadows the CallLinkInfo vector.
-        
-        - Make CallLinkInfo have its own slowPathCount, which counts actual slow path executions
-          and not all relinking.
-        
-        This makes planting JS->JS calls inside other inline caches or stubs a lot easier, since
-        the CallLinkInfo and the call IC slow paths no longer rely on the call being associated
-        with a op_call/op_construct instruction and a machine code return PC within such an
-        instruction.
-
-        * bytecode/CallLinkInfo.h:
-        (JSC::getCallLinkInfoCodeOrigin):
-        * bytecode/CallLinkStatus.cpp:
-        (JSC::CallLinkStatus::computeFor):
-        (JSC::CallLinkStatus::computeDFGStatuses):
-        * bytecode/CallLinkStatus.h:
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::printCallOp):
-        (JSC::CodeBlock::dumpBytecode):
-        (JSC::CodeBlock::finalizeUnconditionally):
-        (JSC::CodeBlock::getCallLinkInfoMap):
-        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
-        (JSC::CodeBlock::addCallLinkInfo):
-        (JSC::CodeBlock::unlinkCalls):
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::stubInfoBegin):
-        (JSC::CodeBlock::stubInfoEnd):
-        (JSC::CodeBlock::callLinkInfosBegin):
-        (JSC::CodeBlock::callLinkInfosEnd):
-        (JSC::CodeBlock::byValInfo):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleCall):
-        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
-        * dfg/DFGJITCode.h:
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::link):
-        * dfg/DFGJITCompiler.h:
-        (JSC::DFG::JITCompiler::addJSCall):
-        (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::reifyInlinedCallFrames):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::emitCall):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::emitCall):
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        * ftl/FTLInlineCacheSize.cpp:
-        (JSC::FTL::sizeOfCall):
-        * ftl/FTLJSCall.cpp:
-        (JSC::FTL::JSCall::JSCall):
-        (JSC::FTL::JSCall::emit):
-        (JSC::FTL::JSCall::link):
-        * ftl/FTLJSCall.h:
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompileMainPass):
-        (JSC::JIT::privateCompileSlowCases):
-        (JSC::JIT::privateCompile):
-        * jit/JIT.h:
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::compileOpCallSlowCase):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::compileOpCallSlowCase):
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-        (JSC::operationLinkFor):
-        (JSC::operationVirtualFor):
-        (JSC::operationLinkClosureCallFor):
-        * jit/Repatch.cpp:
-        (JSC::linkClosureCall):
-        * jit/ThunkGenerators.cpp:
-        (JSC::slowPathFor):
-        (JSC::virtualForThunkGenerator):
-        * tests/stress/eval-that-is-not-eval.js: Added.
-
-2014-03-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix mispelled test name.
-
-        * tests/stress/constand-folding-osr-exit.js: Removed.
-        * tests/stress/constant-folding-osr-exit.js: Copied from Source/JavaScriptCore/tests/stress/constand-folding-osr-exit.js.
-
-2014-03-22  Andreas Kling  <akling@apple.com>
-
-        CREATE_DOM_WRAPPER doesn't need the ExecState.
-        <https://webkit.org/b/130648>
-
-        Add a fast path from JSGlobalObject to the VM so we don't have
-        to dance via the Heap.
-
-        Reviewed by Darin Adler.
-
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::JSGlobalObject):
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::vm):
-
-2014-03-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix FTL build.
-
-        * ftl/FTLJITFinalizer.cpp:
-
-2014-03-22  Michael Saboff  <msaboff@apple.com>
-
-        toThis() on a JSWorkerGlobalScope should return a JSProxy and not undefined
-        https://bugs.webkit.org/show_bug.cgi?id=130554
-
-        Reviewed by Geoffrey Garen.
-
-        Fixed toThis() on WorkerGlobalScope to return a JSProxy instead of the JSGlobalObject.
-        Did some cleanup as well.  Moved the setting of the thisObject in a JSGlobalObject to
-        happen in finishCreation() so that it will also happen for other derived classes including
-        JSWorkerGlobalScopeBase.
-
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreateInGroup):
-        * jsc.cpp:
-        (GlobalObject::create):
-        * API/tests/testapi.c:
-        (globalObject_initialize): Eliminated ASSERT that the global object we are creating matches
-        the result from JSContextGetGlobalObject() as that will return the proxy.       
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::init): Removed thisValue parameter and the call to setGlobalThis() since
-        we now call setGlobalThis in finishCreation().
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::finishCreation):
-        (JSC::JSGlobalObject::setGlobalThis): Made this a private method.
-
-2014-03-22  Andreas Kling  <akling@apple.com>
-
-        Fix debug build.
-
-        * bytecode/CodeBlock.cpp:
-        * runtime/Executable.cpp:
-
-2014-03-22  Andreas Kling  <akling@apple.com>
-
-        Cut down on JSC profiler includes in WebCore & co.
-        <https://webkit.org/b/130637>
-
-        Most of WebKit was pulling in JSC's profiler headers via VM.h.
-
-        Reviewed by Darin Adler.
-
-        * dfg/DFGDisassembler.cpp:
-        * dfg/DFGDisassembler.h:
-        * dfg/DFGJITFinalizer.cpp:
-        * jsc.cpp:
-        * runtime/VM.cpp:
-        * runtime/VM.h:
-
-2014-03-22  Landry Breuil <landry@openbsd.org>
-
-        Use pthread_stackseg_np() to find the stack bounds on OpenBSD.
-        https://bugs.webkit.org/show_bug.cgi?id=129965
-
-        Reviewed By Anders Carlsson.
-
-2014-03-21  Mark Lam  <mark.lam@apple.com>
-
-        Crash when BytecodeGenerator::emitJump calls Label::bind on null pointer.
-        <https://webkit.org/b/124508>
-
-        Reviewed by Oliver Hunt.
-
-        The issue is that BreakNode::emitBytecode() is holding onto a LabelScope
-        pointer from the BytecodeGenerator's m_localScopes vector, and then it
-        calls emitPopScopes().  emitPopScopes() may do finally clause handling
-        which will require the m_localScopes to be cloned so that it can change
-        the local scopes for the finally block, and then restore it after
-        handling the finally clause.  These modifications of the m_localScopes
-        vector will result in the LabelScope pointer in BreakNode::emitBytecode()
-        becoming stale, thereby causing the crash.
-
-        The same issue applies to the ContinueNode as well.
-
-        The fix is to use the existing LabelScopePtr abstraction instead of raw
-        LabelScope pointers.  The LabelScopePtr is resilient to the underlying
-        vector re-allocating its backing store.
-
-        I also changed the LabelScopePtr constructor that takes a LabelScopeStore
-        to expect a reference to the owner store instead of a pointer because the
-        owner store should never be a null pointer.
-
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::newLabelScope):
-        (JSC::BytecodeGenerator::breakTarget):
-        (JSC::BytecodeGenerator::continueTarget):
-        * bytecompiler/BytecodeGenerator.h:
-        * bytecompiler/LabelScope.h:
-        (JSC::LabelScopePtr::LabelScopePtr):
-        (JSC::LabelScopePtr::operator bool):
-        (JSC::LabelScopePtr::null):
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::ContinueNode::trivialTarget):
-        (JSC::ContinueNode::emitBytecode):
-        (JSC::BreakNode::trivialTarget):
-        (JSC::BreakNode::emitBytecode):
-
-2014-03-21  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        6% SunSpider commandline regression due to r165940
-        https://bugs.webkit.org/show_bug.cgi?id=130617
-
-        Reviewed by Michael Saboff.
-
-        In GCActivityCallback::didAllocate, lastGCLength() returns 0 if we've never collected 
-        before. Some of the benchmarks are never running a single EdenCollection, which causes 
-        them to repeatedly call scheduleTimer with a newDelay of 0. This defeats our timer 
-        slop heuristic, causing us to invoke CFRunLoopTimerSetNextFireDate a couple orders of 
-        magnitude more than we normally would.
-
-        The fix is to seed the last GC lengths in Heap with a non-zero length so that our heuristic works.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::Heap):
-
-2014-03-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Constants folded by DFG::ByteCodeParser should not be dead.
-        https://bugs.webkit.org/show_bug.cgi?id=130576
-
-        Reviewed by Mark Hahnenberg.
-        
-        This fixes bugs in the ByteCodeParser's constant folder by removing that constant folder. This
-        reduces the number of folders in JSC from fourish to just threeish (parser, DFG AI, and one
-        or more folders in LLVM). Doing so has no performance impact since the other constant folders
-        already subsume this one.
-        
-        Also added a test case for the specific bug that instigated this.
-
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::getJSConstantForValue):
-        (JSC::DFG::ByteCodeParser::getJSConstant):
-        (JSC::DFG::ByteCodeParser::inferredConstant):
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGNode.h:
-        * dfg/DFGNodeFlags.h:
-        * tests/stress/constand-folding-osr-exit.js: Added.
-        (foo):
-        (test):
-        (.var):
-
-2014-03-21  Mark Lam  <mark.lam@apple.com>
-
-        StackLayoutPhase should find the union'ed calleeVariable before accessing its machineLocal.
-        <https://webkit.org/b/130566>
-
-        Reviewed by Filip Pizlo.
-
-        * dfg/DFGStackLayoutPhase.cpp:
-        (JSC::DFG::StackLayoutPhase::run):
-
-2014-03-20  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should correctly compile GetByVal on Uint32Array that claims to return non-int32 values
-        https://bugs.webkit.org/show_bug.cgi?id=130562
-        <rdar://problem/16382842>
-
-        Reviewed by Geoffrey Garen.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
-        * tests/stress/uint32array-unsigned-load.js: Added.
-        (foo):
-
-2014-03-20  Brian Burg  <bburg@apple.com>
-
-        Web Inspector: add frontend controller and models for replay sessions
-        https://bugs.webkit.org/show_bug.cgi?id=130145
-
-        Reviewed by Joseph Pecoraro.
-
-        * inspector/scripts/CodeGeneratorInspector.py: Add the conditional Replay domain.
-
-2014-03-20  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL ValueToInt32 mishandles the constant case, and by the way, there is a constant case that the FTL sees
-        https://bugs.webkit.org/show_bug.cgi?id=130546
-        <rdar://problem/16383308>
-
-        Reviewed by Mark Hahnenberg.
-        
-        Make AI do a better job of folding this.
-        
-        Also made the FTL backend be more tolerant of data representations. In this case it
-        didn't know that "constant" was a valid representation. There is a finite set of
-        possible representations, but broadly, we don't write code that presumes anything
-        about the representation of an input; that's what methods like lowJSValue() are for.
-        ValueToInt32 was previously not relying on those methods at all because it had some
-        hacks. Now, those hacks are just a fast-path optimization but ultimately we fall down
-        to lowJSValue().
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
-        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
-        * tests/stress/value-to-int32-undefined-constant.js: Added.
-        (foo):
-        * tests/stress/value-to-int32-undefined.js: Added.
-        (foo):
-
-2014-03-20  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Add some assertions back
-        https://bugs.webkit.org/show_bug.cgi?id=130531
-
-        Reviewed by Geoffrey Garen.
-
-        We removed a useful set of assertions for verifying that MarkedBlocks were 
-        in the state that we expected them to be in after clearing marks in the Heap. 
-        We should add these back to catch bugs earlier.
-
-        * heap/MarkedBlock.h:
-        * heap/MarkedSpace.cpp:
-        (JSC::VerifyMarkedOrRetired::operator()):
-        (JSC::MarkedSpace::clearMarks):
-
-2014-03-20  Filip Pizlo  <fpizlo@apple.com>
-
-        Implement stackmap header version check and support new stackmap formats
-        https://bugs.webkit.org/show_bug.cgi?id=130535
-        <rdar://problem/16164284>
-
-        Reviewed by Geoffrey Garen.
-        
-        Add the notion of versioning so that LLVMers can happily implement new stackmap formats
-        without worrying about WebKit getting version-locked to LLVM. In the future, we will have
-        to implement parsing for a new LLVM stackmap format before it lands in LLVM, or we'll have
-        to have a "max usable LLVM revision" limit. But, thanks to versioning, we'll always be
-        happy to move backward in time to older versions of LLVM.
-
-        * ftl/FTLStackMaps.cpp:
-        (JSC::FTL::readObject):
-        (JSC::FTL::StackMaps::Constant::parse):
-        (JSC::FTL::StackMaps::StackSize::parse):
-        (JSC::FTL::StackMaps::Location::parse):
-        (JSC::FTL::StackMaps::Record::parse):
-        (JSC::FTL::StackMaps::parse):
-        (JSC::FTL::StackMaps::dump):
-        (JSC::FTL::StackMaps::dumpMultiline):
-        * ftl/FTLStackMaps.h:
-
-2014-03-20  Filip Pizlo  <fpizlo@apple.com>
-
-        Crash beneath operationTearOffActivation running this JS compression demo
-        https://bugs.webkit.org/show_bug.cgi?id=130295
-        <rdar://problem/16332337>
-
-        Reviewed by Oliver Hunt.
-        
-        Make sure that we flush things as if we were at a terminal, if we are at a block with
-        no forward edges. This fixes infinitely loopy code with captured variables.
-
-        Make sure that the CFG simplifier adds explicit flushes whenever it jettisons a block.
-        
-        Make it so that NodeIsFlushed is a thing. Previously only SSA used it and it computed
-        it by itself. Now it's an artifact of CPS rethreading.
-        
-        Add a bunch of tests. All of them previously either crashed or returned bad output due
-        to memory corruption.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::isCaptured):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::flushForTerminal):
-        (JSC::DFG::ByteCodeParser::flushForReturn):
-        (JSC::DFG::ByteCodeParser::flushIfTerminal):
-        (JSC::DFG::ByteCodeParser::branchData):
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGCFGSimplificationPhase.cpp:
-        (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
-        * dfg/DFGCPSRethreadingPhase.cpp:
-        (JSC::DFG::CPSRethreadingPhase::run):
-        (JSC::DFG::CPSRethreadingPhase::computeIsFlushed):
-        (JSC::DFG::CPSRethreadingPhase::addFlushedLocalOp):
-        (JSC::DFG::CPSRethreadingPhase::addFlushedLocalEdge):
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::performNodeCSE):
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::clearFlagsOnAllNodes):
-        * dfg/DFGGraph.h:
-        * dfg/DFGNode.h:
-        * dfg/DFGNodeFlags.cpp:
-        (JSC::DFG::dumpNodeFlags):
-        * dfg/DFGNodeFlags.h:
-        * dfg/DFGSSAConversionPhase.cpp:
-        (JSC::DFG::SSAConversionPhase::run):
-        * tests/stress/activation-test-loop.js: Added.
-        (Inner.this.doStuff):
-        (Inner):
-        (foo.inner.isDone):
-        (foo):
-        * tests/stress/inferred-infinite-loop-that-uses-captured-variables.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-        * tests/stress/infinite-loop-that-uses-captured-variables-before-throwing.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-        * tests/stress/infinite-loop-that-uses-captured-variables-but-they-do-not-escape.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-        * tests/stress/infinite-loop-that-uses-captured-variables-with-osr-entry.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-        * tests/stress/infinite-loop-that-uses-captured-variables.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-        * tests/stress/tricky-indirectly-inferred-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
-        (bar):
-        (fuzz):
-        (foo.f):
-        (foo):
-        * tests/stress/tricky-inferred-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
-        (bar):
-        (foo.f):
-        (foo):
-        * tests/stress/tricky-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
-        (bar):
-        (foo.f):
-        (foo):
-        * tests/stress/tricky-infinite-loop-that-uses-captured-variables.js: Added.
-        (bar):
-        (foo):
-        (noInline):
-
-2014-03-20  Oliver Hunt  <oliver@apple.com>
-
-        Incorrect behavior when mutating a typed array during set.
-        https://bugs.webkit.org/show_bug.cgi?id=130428
-
-        Reviewed by Geoffrey Garen.
-
-        This fixes a null derefence that occurs if a typed array
-        is mutated during the set() operation. The patch gets rid
-        of the "Quickly" version of setIndex that is assigning
-        JSValues of unknown type, as the numeric conversion can trigger
-        side effects that lead to neutering, and so we deref null.
-
-        * runtime/JSGenericTypedArrayView.h:
-        (JSC::JSGenericTypedArrayView::setIndex):
-        * runtime/JSGenericTypedArrayViewInlines.h:
-        (JSC::JSGenericTypedArrayView<Adaptor>::set):
-        (JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):
-
-2014-03-20  Gavin Barraclough  <barraclough@apple.com>
-
-        Remove IdentifierTable typedef, isIdentifier()
-        https://bugs.webkit.org/show_bug.cgi?id=130533
-
-        Rubber stamped by Geoff Garen.
-
-        Code should use AtomicStringTable, isAtomic() directly.
-
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::~OpaqueJSClass):
-        (OpaqueJSClassContextData::OpaqueJSClassContextData):
-        (OpaqueJSClass::className):
-        * API/JSClassRef.h:
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationFromCell):
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::BytecodeGenerator):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileIn):
-        (JSC::DFG::SpeculativeJIT::speculateStringIdentAndLoadStorage):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::speculateStringIdent):
-        * heap/Heap.cpp:
-        (JSC::Heap::collect):
-        * interpreter/CallFrame.h:
-        (JSC::ExecState::atomicStringTable):
-        * parser/ASTBuilder.h:
-        (JSC::ASTBuilder::addVar):
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::createBindingPattern):
-        * runtime/Completion.cpp:
-        (JSC::checkSyntax):
-        (JSC::evaluate):
-        * runtime/Identifier.cpp:
-        (JSC::Identifier::checkCurrentAtomicStringTable):
-        * runtime/Identifier.h:
-        (JSC::Identifier::Identifier):
-        * runtime/IdentifierInlines.h:
-        (JSC::Identifier::add):
-        * runtime/JSCJSValue.cpp:
-        (JSC::JSValue::dumpInContext):
-        * runtime/JSLock.cpp:
-        (JSC::JSLock::didAcquireLock):
-        (JSC::JSLock::willReleaseLock):
-        (JSC::JSLock::DropAllLocks::DropAllLocks):
-        (JSC::JSLock::DropAllLocks::~DropAllLocks):
-        * runtime/JSLock.h:
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::find):
-        (JSC::PropertyTable::get):
-        (JSC::PropertyTable::findWithString):
-        * runtime/PropertyName.h:
-        (JSC::PropertyName::PropertyName):
-        * runtime/PropertyNameArray.cpp:
-        (JSC::PropertyNameArray::add):
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        (JSC::VM::~VM):
-        * runtime/VM.h:
-        (JSC::VM::atomicStringTable):
-
-2014-03-20  Gavin Barraclough  <barraclough@apple.com>
-
-        Merge AtomicString, Identifier
-        https://bugs.webkit.org/show_bug.cgi?id=128624
-
-        Reviewed by Geoff Garen.
-
-        WTF::StringImpl currently supports two uniquing mechanism - AtomicString and
-        Identifer - that is one too many.
-
-        Remove Identifier in favour of AtomicString. Identifier had two interesting
-        mechanisms that we preserve.
-
-        (1) JSC API VMs each get their own string table, switch the string table on
-            API entry/exit.
-        (2) JSC caches a pointer to the string table on the VM to avoid a thread
-            specific access. Adds a new AtomicString::add method to support this.
-
-        * API/JSAPIWrapperObject.mm:
-            - updated includes.
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-            - added IdentifierInlines.h.
-        * inspector/JSInjectedScriptHostPrototype.cpp:
-        * inspector/JSJavaScriptCallFramePrototype.cpp:
-            - updated includes.
-        * interpreter/CallFrame.h:
-        (JSC::ExecState::atomicStringTable):
-            - added, used via AtomicString::add to avoid thread-specific access.
-        * runtime/ConsolePrototype.cpp:
-            - updated includes.
-        * runtime/Identifier.cpp:
-        (JSC::Identifier::add):
-        (JSC::Identifier::add8):
-            - vm->smallStrings.singleCharacterStringRep now returns Atomic strings, use AtomicString::add.
-        * runtime/Identifier.h:
-        (JSC::Identifier::Identifier):
-            - added ASSERTS.
-        (JSC::Identifier::add):
-            - vm->smallStrings.singleCharacterStringRep now returns Atomic strings, use AtomicString::add.
-        * runtime/IdentifierInlines.h: Added.
-        (JSC::Identifier::add):
-            - moved from Identifier.h, use AtomicString::add.
-        * runtime/JSCInlines.h:
-            - added IdentifierInlines.h.
-        * runtime/JSLock.h:
-            - removed IdentifierTable.
-        * runtime/PropertyNameArray.cpp:
-            - updated includes.
-        * runtime/SmallStrings.cpp:
-        (JSC::SmallStringsStorage::SmallStringsStorage):
-            - ensure all single character strings are Atomic.
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-            - instantiate CommonIdentifiers with the correct AtomicStringTable set on thread data.
-        * runtime/VM.h:
-        (JSC::VM::atomicStringTable):
-            - added, used via AtomicString::add to avoid thread-specific access.
-
-2014-03-20  Gabor Rapcsanyi  <rgabor@webkit.org>
-
-        [ARM64] Fix assembler build issues and add cacheFlush support for Linux
-        https://bugs.webkit.org/show_bug.cgi?id=130502
-
-        Reviewed by Michael Saboff.
-
-        Add limits.h for INT_MIN in ARM64Assembler(). Delete shouldBlindForSpecificArch(uintptr_t)
-        because on ARM64 uint64_t and uintptr_t is the same with GCC and Clang as well.
-        Add cacheFlush support for Linux.
-
-        * assembler/ARM64Assembler.h:
-        (JSC::ARM64Assembler::linuxPageFlush):
-        (JSC::ARM64Assembler::cacheFlush):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::shouldBlindForSpecificArch):
-
-2014-03-19  Gavin Barraclough  <barraclough@apple.com>
-
-        https://bugs.webkit.org/show_bug.cgi?id=130494
-        EmptyUnique strings are Identifiers/Atomic
-
-        Reviewed by Geoff Garen.
-
-        EmptyUnique strings should set the Identifier/Atomic flag.
-
-        This fixes an unreproducible bug we believe exists in Identifier handling.
-        Expected behaviour is that while Identifiers may reference EmptyUniques
-        (StringImpls allocated as UIDs for PrivateNames), these are not created
-        through the main Identifier constructor, the Identifier flag is not set
-        on PrivateNames, and we should never lookup EmptyUnique strings in the
-        IdentifierTable.
-
-        Unfortunately that was happening. Some tables used to implement property
-        access in the JIT hold StringImpl*s, and turn these back into Identifiers
-        using the identfiier constructor. Since the code generator will now plant
-        by-id (cachable) accesses to PrivateNames we can end up passing an
-        EmptyUnique to Identifier::add, potentially leading to PrivateNames being
-        uniqued together (though hard to prove, since the hash codes are random).
-
-        * runtime/PropertyName.h:
-        (JSC::PropertyName::PropertyName):
-        (JSC::PropertyName::uid):
-        (JSC::PropertyName::publicName):
-        (JSC::PropertyName::asIndex):
-            - PropertyName assumed that PrivateNames are not Identifiers - instead check isEmptyUnique().
-        * runtime/Structure.cpp:
-        (JSC::Structure::getPropertyNamesFromStructure):
-            - Structure assumed that PrivateNames are not Identifiers - instead check isEmptyUnique().
-
-2014-03-19  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, revert the DFGCommon.h change in r165938. It was not intentional.
-
-        * dfg/DFGCommon.h:
-
-2014-03-19  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        GC timer should intelligently choose between EdenCollections and FullCollections
-        https://bugs.webkit.org/show_bug.cgi?id=128261
-
-        Reviewed by Geoffrey Garen.
-
-        Most of the GCs while browsing the web are due to the GC timer. Currently the GC timer 
-        always does FullCollections. To reduce the impact of the GC timer on the system this patch
-        changes Heap so that it has two timers, one for each type of collection. The FullCollection
-        timer is notified at the end of EdenCollections how much the Heap has grown since the last 
-        FullCollection and when somebody notifies the Heap of abandoned memory (which usually wouldn't 
-        be detected by an EdenCollection).
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * heap/EdenGCActivityCallback.cpp: Added.
-        (JSC::EdenGCActivityCallback::EdenGCActivityCallback):
-        (JSC::EdenGCActivityCallback::doCollection):
-        (JSC::EdenGCActivityCallback::lastGCLength):
-        (JSC::EdenGCActivityCallback::deathRate):
-        (JSC::EdenGCActivityCallback::gcTimeSlice):
-        * heap/EdenGCActivityCallback.h: Added.
-        (JSC::GCActivityCallback::createEdenTimer):
-        * heap/FullGCActivityCallback.cpp: Added.
-        (JSC::FullGCActivityCallback::FullGCActivityCallback):
-        (JSC::FullGCActivityCallback::doCollection):
-        (JSC::FullGCActivityCallback::lastGCLength):
-        (JSC::FullGCActivityCallback::deathRate):
-        (JSC::FullGCActivityCallback::gcTimeSlice):
-        * heap/FullGCActivityCallback.h: Added.
-        (JSC::GCActivityCallback::createFullTimer):
-        * heap/GCActivityCallback.cpp:
-        (JSC::GCActivityCallback::GCActivityCallback):
-        (JSC::GCActivityCallback::doWork):
-        (JSC::GCActivityCallback::scheduleTimer):
-        (JSC::GCActivityCallback::cancelTimer):
-        (JSC::GCActivityCallback::didAllocate):
-        (JSC::GCActivityCallback::willCollect):
-        (JSC::GCActivityCallback::cancel):
-        * heap/GCActivityCallback.h:
-        * heap/Heap.cpp:
-        (JSC::Heap::Heap):
-        (JSC::Heap::reportAbandonedObjectGraph):
-        (JSC::Heap::didAbandon):
-        (JSC::Heap::collectAllGarbage):
-        (JSC::Heap::collect):
-        (JSC::Heap::willStartCollection):
-        (JSC::Heap::updateAllocationLimits):
-        (JSC::Heap::didFinishCollection):
-        (JSC::Heap::setFullActivityCallback):
-        (JSC::Heap::setEdenActivityCallback):
-        (JSC::Heap::fullActivityCallback):
-        (JSC::Heap::edenActivityCallback):
-        (JSC::Heap::setGarbageCollectionTimerEnabled):
-        (JSC::Heap::didAllocate):
-        (JSC::Heap::shouldDoFullCollection):
-        * heap/Heap.h:
-        (JSC::Heap::lastFullGCLength):
-        (JSC::Heap::lastEdenGCLength):
-        (JSC::Heap::increaseLastFullGCLength):
-        (JSC::Heap::sizeBeforeLastEdenCollection):
-        (JSC::Heap::sizeAfterLastEdenCollection):
-        (JSC::Heap::sizeBeforeLastFullCollection):
-        (JSC::Heap::sizeAfterLastFullCollection):
-        * heap/HeapOperation.h:
-        * heap/HeapStatistics.cpp:
-        (JSC::HeapStatistics::showObjectStatistics):
-        * heap/HeapTimer.cpp:
-        (JSC::HeapTimer::timerDidFire):
-        * jsc.cpp:
-        (functionFullGC):
-        (functionEdenGC):
-        * runtime/Options.h:
-
-2014-03-19  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r165926.
-        https://bugs.webkit.org/show_bug.cgi?id=130488
-
-        broke the iOS build (Requested by estes on #webkit).
-
-        Reverted changeset:
-
-        "GC timer should intelligently choose between EdenCollections
-        and FullCollections"
-        https://bugs.webkit.org/show_bug.cgi?id=128261
-        http://trac.webkit.org/changeset/165926
-
-2014-03-13  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        GC timer should intelligently choose between EdenCollections and FullCollections
-        https://bugs.webkit.org/show_bug.cgi?id=128261
-
-        Reviewed by Geoffrey Garen.
-
-        Most of the GCs while browsing the web are due to the GC timer. Currently the GC timer 
-        always does FullCollections. To reduce the impact of the GC timer on the system this patch
-        changes Heap so that it has two timers, one for each type of collection. The FullCollection
-        timer is notified at the end of EdenCollections how much the Heap has grown since the last 
-        FullCollection and when somebody notifies the Heap of abandoned memory (which wouldn't be 
-        detected by an EdenCollection).
-
-        * heap/GCActivityCallback.cpp:
-        (JSC::GCActivityCallback::GCActivityCallback):
-        (JSC::GCActivityCallback::doWork):
-        (JSC::FullGCActivityCallback::FullGCActivityCallback):
-        (JSC::FullGCActivityCallback::doCollection):
-        (JSC::EdenGCActivityCallback::EdenGCActivityCallback):
-        (JSC::EdenGCActivityCallback::doCollection):
-        (JSC::GCActivityCallback::scheduleTimer):
-        (JSC::GCActivityCallback::cancelTimer):
-        (JSC::GCActivityCallback::didAllocate):
-        (JSC::GCActivityCallback::willCollect):
-        (JSC::GCActivityCallback::cancel):
-        * heap/GCActivityCallback.h:
-        (JSC::GCActivityCallback::GCActivityCallback):
-        (JSC::GCActivityCallback::createFullTimer):
-        (JSC::GCActivityCallback::createEdenTimer):
-        * heap/Heap.cpp:
-        (JSC::Heap::Heap):
-        (JSC::Heap::didAbandon):
-        (JSC::Heap::willStartCollection):
-        (JSC::Heap::updateAllocationLimits):
-        (JSC::Heap::setFullActivityCallback):
-        (JSC::Heap::setEdenActivityCallback):
-        (JSC::Heap::fullActivityCallback):
-        (JSC::Heap::edenActivityCallback):
-        (JSC::Heap::setGarbageCollectionTimerEnabled):
-        (JSC::Heap::didAllocate):
-        * heap/Heap.h:
-        * heap/HeapTimer.cpp:
-        (JSC::HeapTimer::timerDidFire):
-
-2014-03-19  Filip Pizlo  <fpizlo@apple.com>
-
-        REGRESSION(r165459): It broke 109 jsc stress test on ARM Thumb2 and Mac 32 bit
-        https://bugs.webkit.org/show_bug.cgi?id=130134
-
-        Reviewed by Mark Hahnenberg.
-
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode): Can't do some optimizations if you don't have a lot of registers.
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById): Move stuff around before going into the IC code to ensure that we give the IC code the invariants it needs. This only happens in case of GetByIdFlush, where we are forced into using weird combinations of registers because the results have to be in t0/t1.
-        (JSC::DFG::SpeculativeJIT::compile): For a normal GetById, the register allocator should just do the right thing so nobody has to move anything around.
-        * jit/JITInlineCacheGenerator.cpp:
-        (JSC::JITGetByIdGenerator::JITGetByIdGenerator): Assert the things we want.
-        * jit/JITInlineCacheGenerator.h:
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub): Remove a previous incomplete hack to try to work around the DFG's problem.
-
-2014-03-19  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Normalize some of the older JSC options
-        https://bugs.webkit.org/show_bug.cgi?id=128753
-
-        Reviewed by Michael Saboff.
-
-        * runtime/Options.cpp:
-        (JSC::Options::initialize):
-
-2014-03-12  Mark Lam  <mark.lam@apple.com>
-
-        Update type of local vars to match the type of String length.
-        <https://webkit.org/b/130077>
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/JSStringJoiner.cpp:
-        (JSC::JSStringJoiner::join):
-
-2014-03-18  Filip Pizlo  <fpizlo@apple.com>
-
-        Get rid of Flush in SSA
-        https://bugs.webkit.org/show_bug.cgi?id=130440
-
-        Reviewed by Sam Weinig.
-        
-        This is basically a red patch. We used to use backwards flow for determining what was
-        flushed, until it became clear that this doesn't make sense. Now the Flush nodes don't
-        accomplish anything. Keeping them around in SSA can only make things hard.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGBasicBlock.cpp:
-        (JSC::DFG::BasicBlock::SSAData::SSAData):
-        * dfg/DFGBasicBlock.h:
-        * dfg/DFGFlushLivenessAnalysisPhase.cpp: Removed.
-        * dfg/DFGFlushLivenessAnalysisPhase.h: Removed.
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::dump):
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::compileInThreadImpl):
-        * dfg/DFGSSAConversionPhase.cpp:
-        (JSC::DFG::SSAConversionPhase::run):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-
-2014-03-18  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix iOS production build.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2014-03-18  Michael Saboff  <msaboff@apple.com>
-
-        Update RegExp Tracing code
-        https://bugs.webkit.org/show_bug.cgi?id=130381
-
-        Reviewed by Andreas Kling.
-
-        Updated the regular expression tracing code for 8/16 bit JIT as
-        well as match only entry points.  Also added average string length
-        metric.
-
-        * runtime/RegExp.cpp:
-        (JSC::RegExp::RegExp):
-        (JSC::RegExp::match):
-        (JSC::RegExp::printTraceData):
-        * runtime/RegExp.h:
-        * runtime/VM.cpp:
-        (JSC::VM::addRegExpToTrace):
-        (JSC::VM::dumpRegExpTrace):
-        * runtime/VM.h:
-        * yarr/YarrJIT.h:
-        (JSC::Yarr::YarrCodeBlock::get8BitMatchOnlyAddr):
-        (JSC::Yarr::YarrCodeBlock::get16BitMatchOnlyAddr):
-        (JSC::Yarr::YarrCodeBlock::get8BitMatchAddr):
-        (JSC::Yarr::YarrCodeBlock::get16BitMatchAddr):
-
-2014-03-17  Filip Pizlo  <fpizlo@apple.com>
-
-        Add CompareStrictEq(StringIdent:, NotStringVar:) and CompareStrictEq(String:, Untyped:)
-        https://bugs.webkit.org/show_bug.cgi?id=130300
-
-        Reviewed by Mark Hahnenberg.
-        
-        We can quickly strictly compare StringIdent's to NotStringVar's and String's to Untyped's.
-        This makes the DFG aware of this.
-        
-        Also adds StringIdent-to-StringIdent and StringIdent-to-NotStringVar strict comparisons to
-        the FTL. Also adds StringIdent-to-StringIdent non-strict comparisons to the FTL.
-        
-        This also gives the DFG some abstractions for checking something is a cell or is other.
-        This made this patch easier to write and also simplified a bunch of other stuff.
-        
-        1% speed-up on Octane.
-
-        * assembler/AbstractMacroAssembler.h:
-        (JSC::AbstractMacroAssembler::JumpList::JumpList):
-        * bytecode/SpeculatedType.h:
-        (JSC::isNotStringVarSpeculation):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::childFor):
-        (JSC::DFG::Node::shouldSpeculateNotStringVar):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileIn):
-        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
-        (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
-        (JSC::DFG::SpeculativeJIT::compileInstanceOf):
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        (JSC::DFG::SpeculativeJIT::compileBooleanCompare):
-        (JSC::DFG::SpeculativeJIT::compileStringEquality):
-        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
-        (JSC::DFG::SpeculativeJIT::compileStringIdentEquality):
-        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
-        (JSC::DFG::SpeculativeJIT::compileStringZeroLength):
-        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
-        (JSC::DFG::SpeculativeJIT::speculateString):
-        (JSC::DFG::SpeculativeJIT::speculateStringIdentAndLoadStorage):
-        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
-        (JSC::DFG::SpeculativeJIT::speculateNotCell):
-        (JSC::DFG::SpeculativeJIT::speculateOther):
-        (JSC::DFG::SpeculativeJIT::speculate):
-        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
-        (JSC::DFG::SpeculativeJIT::emitSwitchString):
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::blessedBooleanResult):
-        (JSC::DFG::SpeculativeJIT::unblessedBooleanResult):
-        (JSC::DFG::SpeculativeJIT::booleanResult):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
-        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
-        (JSC::DFG::SpeculativeJIT::emitCall):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::branchIsCell):
-        (JSC::DFG::branchNotCell):
-        (JSC::DFG::SpeculativeJIT::branchIsOther):
-        (JSC::DFG::SpeculativeJIT::branchNotOther):
-        (JSC::DFG::SpeculativeJIT::moveTrueTo):
-        (JSC::DFG::SpeculativeJIT::moveFalseTo):
-        (JSC::DFG::SpeculativeJIT::blessBoolean):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
-        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
-        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
-        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        (JSC::DFG::SpeculativeJIT::branchIsCell):
-        (JSC::DFG::SpeculativeJIT::branchNotCell):
-        (JSC::DFG::SpeculativeJIT::branchIsOther):
-        (JSC::DFG::SpeculativeJIT::branchNotOther):
-        (JSC::DFG::SpeculativeJIT::moveTrueTo):
-        (JSC::DFG::SpeculativeJIT::moveFalseTo):
-        (JSC::DFG::SpeculativeJIT::blessBoolean):
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::lowString):
-        (JSC::FTL::LowerDFGToLLVM::lowStringIdent):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateString):
-        (JSC::FTL::LowerDFGToLLVM::speculateStringIdent):
-        (JSC::FTL::LowerDFGToLLVM::speculateNotStringVar):
-        * runtime/JSCJSValue.h:
-        * tests/stress/string-ident-to-not-string-var-equality.js: Added.
-        (foo):
-        (bar):
-        (test):
-
-2014-03-18  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Add Copyright to framework.sb
-        https://bugs.webkit.org/show_bug.cgi?id=130413
-
-        Reviewed by Timothy Hatcher.
-
-        Other sb files got the copyright. Follow suit.
-
-        * framework.sb:
-
-2014-03-18  Matthew Mirman  <mmirman@apple.com>
-
-        Removed extra parens from if statement in a preprocessor define.
-        https://bugs.webkit.org/show_bug.cgi?id=130408
-
-        Reviewed by Filip Pizlo.
-
-        * parser/Parser.cpp:
-
-2014-03-18  Filip Pizlo  <fpizlo@apple.com>
-
-        More FTL enabling.
-
-        Rubber stamped by Dan Bernstein and Mark Hahnenberg.
-
-        * Configurations/FeatureDefines.xcconfig:
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::compile):
-
-2014-03-17  Michael Saboff  <msaboff@apple.com>
-
-        V8 regexp spends most of its time in operationGetById
-        https://bugs.webkit.org/show_bug.cgi?id=130380
-
-        Reviewed by Filip Pizlo.
-
-        Added String.length case to tryCacheGetByID that will only help the BaseLine JIT.
-        When V8 regexp is run from the command line, this nets a 2% performance improvement.
-        When the test is run for a longer amount of time, there is much less benefit as the
-        DFG will emit the appropriate code for String.length.  This does remove
-        operationGetById as the hottest function whne run from the command line.
-
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-
-2014-03-17  Andreas Kling  <akling@apple.com>
-
-        Add one-deep cache to opaque roots hashset.
-        <https://webkit.org/b/130357>
-
-        The vast majority of WebCore JS wrappers will have their Document*
-        as the root(). This change adds a simple optimization where we cache
-        the last lookup and avoid going to the hashset for repeated queries.
-
-        Looks like 0.4% progression on DYEB on my MBP.
-
-        Reviewed by Mark Hahnenberg.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * heap/OpaqueRootSet.h: Added.
-        (JSC::OpaqueRootSet::OpaqueRootSet):
-        (JSC::OpaqueRootSet::contains):
-        (JSC::OpaqueRootSet::isEmpty):
-        (JSC::OpaqueRootSet::clear):
-        (JSC::OpaqueRootSet::add):
-        (JSC::OpaqueRootSet::size):
-        (JSC::OpaqueRootSet::begin):
-        (JSC::OpaqueRootSet::end):
-        * heap/SlotVisitor.h:
-
-2014-03-17  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Implement Math.hypot
-        https://bugs.webkit.org/show_bug.cgi?id=129486
-
-        Reviewed by Darin Adler.
-
-        * runtime/MathObject.cpp:
-        (JSC::MathObject::finishCreation):
-        (JSC::mathProtoFuncHypot):
-
-2014-03-17  Zsolt Borbely  <borbezs@inf.u-szeged.hu>
-
-        Fix the !ENABLE(PROMISES) build
-        https://bugs.webkit.org/show_bug.cgi?id=130328
-
-        Reviewed by Darin Adler.
-
-        Add missing ENABLE(PROMISES) guards.
-
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::reset):
-        (JSC::JSGlobalObject::visitChildren):
-        * runtime/JSGlobalObject.h:
-        * runtime/JSPromiseDeferred.cpp:
-        * runtime/JSPromiseDeferred.h:
-        * runtime/JSPromiseReaction.cpp:
-        * runtime/JSPromiseReaction.h:
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        * runtime/VM.h:
-
-2014-03-16  Andreas Kling  <akling@apple.com>
-
-        REGRESSION(r165703): JSC tests crashing in StringImpl::destroy().
-        <https://webkit.org/b/130304>
-
-        Reviewed by Anders Carlsson.
-
-        Unreviewed, restoring the old behavior of OpaqueJSString::identifier()
-        that doesn't put a potentially unwanted string into the Identifier table.
-
-        * API/OpaqueJSString.cpp:
-        (OpaqueJSString::identifier):
-
-2014-03-16  Brian Burg  <bburg@apple.com>
-
-        Web Inspector: generated backend commands should reflect build system ENABLE settings
-        https://bugs.webkit.org/show_bug.cgi?id=130111
-
-        Reviewed by Timothy Hatcher.
-
-        * CMakeLists.txt:
-
-        Combine only the Inspector domains listed in INSPECTOR_DOMAINS,
-        instead of globbing any .json file.
-
-        * DerivedSources.make:
-
-        Force the combined inspector protocol file to be regenerated if
-        the content or list of domains itself changes.
-
-2014-03-16  Brian Burg  <bburg@apple.com>
-
-        Web Inspector: vended backend commands file should be generated as part of the build
-        https://bugs.webkit.org/show_bug.cgi?id=130110
-
-        Reviewed by Timothy Hatcher.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Copy InspectorJSBackendCommands.js to the
-        private headers directory.
-
-2014-03-16  Darin Adler  <darin@apple.com>
-
-        Remove all uses of deprecatedCharacters from JavaScriptCore
-        https://bugs.webkit.org/show_bug.cgi?id=130304
-
-        Reviewed by Anders Carlsson.
-
-        * API/JSValueRef.cpp:
-        (JSValueMakeFromJSONString): Use characters16 in the 16-bit code path.
-        * API/OpaqueJSString.cpp:
-        (OpaqueJSString::~OpaqueJSString): Use characters 16 in the 16-bit code path.
-        (OpaqueJSString::identifier): Get rid of custom Identifier constructor, and
-        juse use the standard one that takes a String.
-        (OpaqueJSString::characters): Use getCharactersWithUpconvert instead of a
-        hand-written alternative.
-
-        * bindings/ScriptValue.cpp:
-        (Deprecated::jsToInspectorValue): Create InspectorString from String directly
-        instead of involving a character pointer. Use the String from Identifier
-        directly instead of making a new String.
-
-        * inspector/ContentSearchUtilities.cpp:
-        (Inspector::ContentSearchUtilities::createSearchRegexSource): Use StringBuilder
-        instead of building a String a character at a time. This is still a very slow
-        way to do this. Also use strchr to search for a character instead of building
-        a String every time just to use find on it.
-
-        * inspector/InspectorValues.cpp:
-        (Inspector::doubleQuoteString): Remove unnecessary trip through a
-        character pointer. This is still a really slow way to do this.
-        (Inspector::InspectorValue::parseJSON): Use StringView::upconvertedCharacters
-        instead of String::deprecatedCharacters. Still slow to always upconvert.
-
-        * runtime/DateConstructor.cpp: Removed unneeded include.
-        * runtime/DatePrototype.cpp: Ditto.
-
-        * runtime/Identifier.h: Removed deprecatedCharacters function.
-
-        * runtime/JSGlobalObjectFunctions.cpp:
-        (JSC::encode): Added a type cast to avoid ambiguity with the two character-
-        appending functions from JSStringBuilder. Removed unneeded code duplicating
-        what JSStringBuilder already does in its character append function.
-        (JSC::decode): Deleted code that creates a JSStringBuilder that is never used.
-        (JSC::parseIntOverflow): Changed lengths to unsigned. Made only the overload that
-        is used outside this file have external linkage. Added a new overload that takes
-        a StringView.
-        (JSC::parseInt): Use StringView::substring to call parseIntOverflow.
-        (JSC::globalFuncEscape): Use JSBuilder::append in a more efficient way for a
-        single character.
-
-        * runtime/JSGlobalObjectFunctions.h: Removed unused overloads of parseIntOverflow.
-
-        * runtime/JSStringBuilder.h: Marked this "lightly deprecated".
-        (JSC::JSStringBuilder::append): Overloaded for better speed with 8-bit characters.
-        Made one overload private. Fixed a performance bug where we would reserve capacity
-        in the 8-bit buffer but then append to the 16-bit buffer.
-
-        * runtime/ObjectPrototype.cpp: Removed unneeded include.
-
-        * runtime/StringPrototype.cpp:
-        (JSC::stringProtoFuncFontsize): Use StringView::getCharactersWithUpconvert.
-        (JSC::stringProtoFuncLink): Ditto.
-
-2014-03-15  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL ArrayifyToStructure shouldn't fail every time that it actually arrayifies
-        https://bugs.webkit.org/show_bug.cgi?id=130296
-
-        Reviewed by Andreas Kling.
-        
-        During the 32-bit structure ID work, the second load of the structure was removed.
-        That's wrong. The whole point of loading the structure ID again is that the structure
-        ID would have been changed by the arrayification call, and we're verifying that the
-        arrayification succeeded in changing the structure. If we check the old structure - as
-        the code was doing after the 32-bit structure ID work - then this check is guaranteed
-        to fail, causing a significant performance regression.
-        
-        It's actually amazing that the regression wasn't bigger. The reason is that if FTL
-        code pathologically exits but the equivalent DFG code doesn't, then the exponential
-        backoff almost perfectly guarantees that we just end up in the DFG. For this code, at
-        the time at least, the DFG wasn't much slower so this didn't cause too much pain.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
-
-2014-03-15  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should support CheckHasInstance/InstanceOf
-        https://bugs.webkit.org/show_bug.cgi?id=130285
-
-        Reviewed by Sam Weinig.
-        
-        Fairly straightforward; I also discovered an inaccurate FIXME in the process.
-
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * ftl/FTLAbstractHeapRepository.h:
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileCheckHasInstance):
-        (JSC::FTL::LowerDFGToLLVM::compileInstanceOf):
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::phi):
-        * tests/stress/instanceof.js: Added.
-        * tests/stress/instanceof-not-cell.js: Added.
-
-2014-03-15  Michael Saboff  <msaboff@apple.com>
-
-        It should be possible to adjust DFG and FTL compiler thread priorities
-        https://bugs.webkit.org/show_bug.cgi?id=130288
-
-        Reviewed by Filip Pizlo.
-
-        Added ability to change thread priorities relative to its current priority.
-        Created options to adjust the priority of the DFG and FTL compilation work thread
-        pools.  For two core systems, there might be three runnable threads, the main thread,
-        the DFG compilation thread and the FTL compilation thread.  With the same priority,
-        the scheduler is free to schedule whatever thread it wants.  By lowering the
-        compilation threads, the main thread can run.  Further tests may suggest better values
-        for the new options, priorityDeltaOfDFGCompilerThreads and priorityDeltaOfFTLCompilerThreads.
-
-        For a two-core device, this change has a net positive improvement of 1-3% across
-        SunSpider, Octane, Kraken and AsmBench.
-
-        * dfg/DFGWorklist.cpp:
-        (JSC::DFG::Worklist::finishCreation):
-        (JSC::DFG::Worklist::create):
-        (JSC::DFG::ensureGlobalDFGWorklist):
-        (JSC::DFG::ensureGlobalFTLWorklist):
-        * dfg/DFGWorklist.h:
-        * runtime/Options.cpp:
-        (JSC::computePriorityDeltaOfWorkerThreads):
-        * runtime/Options.h:
-
-2014-03-15  David Kilzer  <ddkilzer@apple.com>
-
-        [iOS] Define SYSTEM_VERSION_PREFIX consistently
-        <http://webkit.org/b/130293>
-        <rdar://problem/15926359>
-
-        Reviewed by Dan Bernstein.
-
-        * Configurations/Version.xcconfig:
-        (SYSTEM_VERSION_PREFIX_iphoneos): Sync with
-        Source/WebKit/mac/Version.xcconfig.
-
-2014-03-15  David Kilzer  <ddkilzer@apple.com>
-
-        Fix build: using integer absolute value function 'abs' when argument is of floating point type
-        <http://webkit.org/b/130286>
-
-        Reviewed by Filip Pizlo.
-
-        Fixes the following build failure using trunk clang:
-
-            JavaScriptCore/assembler/MacroAssembler.h:992:17: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
-                    value = abs(value);
-                            ^
-            JavaScriptCore/assembler/MacroAssembler.h:992:17: note: use function 'fabs' instead
-                    value = abs(value);
-                            ^~~
-                            fabs
-
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::shouldBlindDouble): Switch from abs() to
-        fabs().
-
-2014-03-14  Oliver Hunt  <oliver@apple.com>
-
-        Reinstate intialiser syntax in for-in loops
-        https://bugs.webkit.org/show_bug.cgi?id=130269
-
-        Reviewed by Michael Saboff.
-
-        Disallowing the initialiser broke some sites so this patch re-allows
-        the syntax.  We still disallow the syntax in 'of' and pattern based
-        enumeration.
-
-        * parser/ASTBuilder.h:
-        (JSC::ASTBuilder::isBindingNode):
-        * parser/Parser.cpp:
-        (JSC::Parser<LexerType>::parseVarDeclarationList):
-        (JSC::Parser<LexerType>::parseForStatement):
-        * parser/SyntaxChecker.h:
-        (JSC::SyntaxChecker::operatorStackPop):
-
-2014-03-14  Mark Lam  <mark.lam@apple.com>
-
-        Accessing __lookupGetter__ and __lookupSetter__ should not crash the VM when undefined.
-        <https://webkit.org/b/130279>
-
-        Reviewed by Filip Pizlo.
-
-        If neither the getter nor setter are defined, accessing __lookupGetter__
-        and __lookupSetter__ will return undefined as expected.  However, if the
-        getter is defined but the setter is not, accessing __lookupSetter__ will
-        crash the VM.  Similarly, accessing __lookupGetter__ when only the setter
-        is defined will crash the VM.
-
-        The reason is because objectProtoFuncLookupGetter() and
-        objectProtoFuncLookupSetter() did not check if the getter and setter
-        value is non-null before returning it as an EncodedJSValue.  The fix is
-        to add the appropriate null checks.
-
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncLookupGetter):
-        (JSC::objectProtoFuncLookupSetter):
-
-2014-03-14  Mark Rowe  <mrowe@apple.com>
-
-        Fix the production build.
-
-        Don't rely on USE_INTERNAL_SDK being set for the Production configuration since UseInternalSDK.xcconfig won't
-        be at the expected relative path when working from installed source.
-
-        * Configurations/Base.xcconfig:
-
-2014-03-14  Maciej Stachowiak  <mjs@apple.com>
-
-        Replace "Apple Computer, Inc." with "Apple Inc." in copyright headers
-        https://bugs.webkit.org/show_bug.cgi?id=130276
-        <rdar://problem/16266927>
-
-        Reviewed by Simon Fraser.
-
-        * API/APICast.h:
-        * API/JSBase.cpp:
-        * API/JSBase.h:
-        * API/JSBasePrivate.h:
-        * API/JSCallbackConstructor.cpp:
-        * API/JSCallbackConstructor.h:
-        * API/JSCallbackFunction.cpp:
-        * API/JSCallbackFunction.h:
-        * API/JSCallbackObject.cpp:
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        * API/JSClassRef.cpp:
-        * API/JSClassRef.h:
-        * API/JSContextRef.cpp:
-        * API/JSContextRef.h:
-        * API/JSContextRefPrivate.h:
-        * API/JSObjectRef.cpp:
-        * API/JSObjectRef.h:
-        * API/JSProfilerPrivate.cpp:
-        * API/JSProfilerPrivate.h:
-        * API/JSRetainPtr.h:
-        * API/JSStringRef.cpp:
-        * API/JSStringRef.h:
-        * API/JSStringRefBSTR.cpp:
-        * API/JSStringRefBSTR.h:
-        * API/JSStringRefCF.cpp:
-        * API/JSStringRefCF.h:
-        * API/JSValueRef.cpp:
-        * API/JSValueRef.h:
-        * API/JavaScript.h:
-        * API/JavaScriptCore.h:
-        * API/OpaqueJSString.cpp:
-        * API/OpaqueJSString.h:
-        * API/tests/JSNode.c:
-        * API/tests/JSNode.h:
-        * API/tests/JSNodeList.c:
-        * API/tests/JSNodeList.h:
-        * API/tests/Node.c:
-        * API/tests/Node.h:
-        * API/tests/NodeList.c:
-        * API/tests/NodeList.h:
-        * API/tests/minidom.c:
-        * API/tests/minidom.js:
-        * API/tests/testapi.c:
-        * API/tests/testapi.js:
-        * DerivedSources.make:
-        * bindings/ScriptValue.cpp:
-        * bytecode/CodeBlock.cpp:
-        * bytecode/CodeBlock.h:
-        * bytecode/EvalCodeCache.h:
-        * bytecode/Instruction.h:
-        * bytecode/JumpTable.cpp:
-        * bytecode/JumpTable.h:
-        * bytecode/Opcode.cpp:
-        * bytecode/Opcode.h:
-        * bytecode/SamplingTool.cpp:
-        * bytecode/SamplingTool.h:
-        * bytecode/SpeculatedType.cpp:
-        * bytecode/SpeculatedType.h:
-        * bytecode/ValueProfile.h:
-        * bytecompiler/BytecodeGenerator.cpp:
-        * bytecompiler/BytecodeGenerator.h:
-        * bytecompiler/Label.h:
-        * bytecompiler/LabelScope.h:
-        * bytecompiler/RegisterID.h:
-        * debugger/DebuggerCallFrame.cpp:
-        * debugger/DebuggerCallFrame.h:
-        * dfg/DFGDesiredStructureChains.cpp:
-        * dfg/DFGDesiredStructureChains.h:
-        * heap/GCActivityCallback.cpp:
-        * heap/GCActivityCallback.h:
-        * inspector/ConsoleMessage.cpp:
-        * inspector/ConsoleMessage.h:
-        * inspector/IdentifiersFactory.cpp:
-        * inspector/IdentifiersFactory.h:
-        * inspector/InjectedScriptManager.cpp:
-        * inspector/InjectedScriptManager.h:
-        * inspector/InjectedScriptSource.js:
-        * inspector/ScriptBreakpoint.h:
-        * inspector/ScriptDebugListener.h:
-        * inspector/ScriptDebugServer.cpp:
-        * inspector/ScriptDebugServer.h:
-        * inspector/agents/InspectorAgent.cpp:
-        * inspector/agents/InspectorAgent.h:
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        * inspector/agents/InspectorDebuggerAgent.h:
-        * interpreter/Interpreter.cpp:
-        * interpreter/Interpreter.h:
-        * interpreter/JSStack.cpp:
-        * interpreter/JSStack.h:
-        * interpreter/Register.h:
-        * jit/CompactJITCodeMap.h:
-        * jit/JITStubs.cpp:
-        * jit/JITStubs.h:
-        * jit/JITStubsARM.h:
-        * jit/JITStubsARMv7.h:
-        * jit/JITStubsX86.h:
-        * jit/JITStubsX86_64.h:
-        * os-win32/stdbool.h:
-        * parser/SourceCode.h:
-        * parser/SourceProvider.h:
-        * profiler/LegacyProfiler.cpp:
-        * profiler/LegacyProfiler.h:
-        * profiler/ProfileNode.cpp:
-        * profiler/ProfileNode.h:
-        * runtime/ArrayBufferView.cpp:
-        * runtime/ArrayBufferView.h:
-        * runtime/BatchedTransitionOptimizer.h:
-        * runtime/CallData.h:
-        * runtime/ConstructData.h:
-        * runtime/DumpContext.cpp:
-        * runtime/DumpContext.h:
-        * runtime/ExceptionHelpers.cpp:
-        * runtime/ExceptionHelpers.h:
-        * runtime/InitializeThreading.cpp:
-        * runtime/InitializeThreading.h:
-        * runtime/IntegralTypedArrayBase.h:
-        * runtime/IntendedStructureChain.cpp:
-        * runtime/IntendedStructureChain.h:
-        * runtime/JSActivation.cpp:
-        * runtime/JSActivation.h:
-        * runtime/JSExportMacros.h:
-        * runtime/JSGlobalObject.cpp:
-        * runtime/JSNotAnObject.cpp:
-        * runtime/JSNotAnObject.h:
-        * runtime/JSPropertyNameIterator.cpp:
-        * runtime/JSPropertyNameIterator.h:
-        * runtime/JSSegmentedVariableObject.cpp:
-        * runtime/JSSegmentedVariableObject.h:
-        * runtime/JSSymbolTableObject.cpp:
-        * runtime/JSSymbolTableObject.h:
-        * runtime/JSTypeInfo.h:
-        * runtime/JSVariableObject.cpp:
-        * runtime/JSVariableObject.h:
-        * runtime/PropertyTable.cpp:
-        * runtime/PutPropertySlot.h:
-        * runtime/SamplingCounter.cpp:
-        * runtime/SamplingCounter.h:
-        * runtime/Structure.cpp:
-        * runtime/Structure.h:
-        * runtime/StructureChain.cpp:
-        * runtime/StructureChain.h:
-        * runtime/StructureInlines.h:
-        * runtime/StructureTransitionTable.h:
-        * runtime/SymbolTable.cpp:
-        * runtime/SymbolTable.h:
-        * runtime/TypedArrayBase.h:
-        * runtime/TypedArrayType.cpp:
-        * runtime/TypedArrayType.h:
-        * runtime/VM.cpp:
-        * runtime/VM.h:
-        * yarr/RegularExpression.cpp:
-        * yarr/RegularExpression.h:
-
-2014-03-14  Filip Pizlo  <fpizlo@apple.com>
-
-        Final FTL iOS build magic
-        https://bugs.webkit.org/show_bug.cgi?id=130281
-
-        Reviewed by Michael Saboff.
-
-        * Configurations/Base.xcconfig: For now our LLVM headers are in /usr/local/LLVMForJavaScriptCore/include, which is the same as OS X.
-        * Configurations/LLVMForJSC.xcconfig: We need to be more careful about how we specify library paths if we want to get the prioritzation right. Also we need protobuf because things. :-/
-
-2014-03-14  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Gracefully handle nil name -[JSContext setName:]
-        https://bugs.webkit.org/show_bug.cgi?id=130262
-
-        Reviewed by Mark Hahnenberg.
-
-        * API/JSContext.mm:
-        (-[JSContext setName:]):
-        Gracefully handle nil input.
-
-        * API/tests/testapi.c:
-        (globalContextNameTest):
-        * API/tests/testapi.mm:
-        Test for nil / NULL names in the ObjC and C APIs.
-
-2014-03-11  Oliver Hunt  <oliver@apple.com>
-
-        Improve dom error messages
-        https://bugs.webkit.org/show_bug.cgi?id=130103
-
-        Reviewed by Andreas Kling.
-
-        Add new helper function.
-
-        * runtime/Error.h:
-        (JSC::throwVMTypeError):
-
-2014-03-14  László Langó  <llango.u-szeged@partner.samsung.com>
-
-        Remove unused method declaration.
-        https://bugs.webkit.org/show_bug.cgi?id=130238
-
-        Reviewed by Filip Pizlo.
-
-        The implementation of CallFrame::dumpCaller was removed in
-        http://trac.webkit.org/changeset/153183, but the declaration of it was not.
-
-        * interpreter/CallFrame.h:
-        Remove CallFrame::dumpCaller() method declaration.
-
-2014-03-12  Sergio Villar Senin  <svillar@igalia.com>
-
-        Rename DEFINE_STATIC_LOCAL to DEPRECATED_DEFINE_STATIC_LOCAL
-        https://bugs.webkit.org/show_bug.cgi?id=129612
-
-        Reviewed by Darin Adler.
-
-        For new code use static NeverDestroyed<T> instead.
-
-        * API/JSAPIWrapperObject.mm:
-        (jsAPIWrapperObjectHandleOwner):
-        * API/JSManagedValue.mm:
-        (managedValueHandleOwner):
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        (Inspector::objectGroupForBreakpointAction):
-        * inspector/scripts/CodeGeneratorInspectorStrings.py:
-        * interpreter/JSStack.cpp:
-        (JSC::stackStatisticsMutex):
-        * jit/ExecutableAllocator.cpp:
-        (JSC::DemandExecutableAllocator::allocators):
-
-2014-03-12  Gavin Barraclough  <barraclough@apple.com>
-
-        Reduce memory use for static property maps
-        https://bugs.webkit.org/show_bug.cgi?id=129986
-
-        Reviewed by Andreas Kling.
-
-        Static property tables are currently duplicated on first use from read-only memory into dirty memory
-        in every process, and since the entries are large (48 bytes) and the tables can be unusually sparse
-        (we use a custom hash table without a rehash) a lot of memory may be wasted.
-
-        First, reduce the size of the hashtable. Instead of storing values in the table the hashtable maps
-        from string hashes to indicies into a densely packed array of values. Compute the index table at
-        compile time as a part of the derived sources step, such that this may be read-only data.
-
-        Second, don't copy all data from the HashTableValue array into a HashEntry objects. Instead refer
-        directly to the HashTableValue entries. The only data that needs to be allocated at runtime are the
-        keys, which are Identifiers.
-
-        * create_hash_table:
-            - emit the hash table index into the derived source (we were calculating this already to ensure chaining does not get too deep).
-        * parser/Lexer.cpp:
-        (JSC::Lexer<LChar>::parseIdentifier):
-        (JSC::Lexer<UChar>::parseIdentifier):
-        (JSC::Lexer<T>::parseIdentifierSlowCase):
-            - HashEntry -> HashTableValue.
-        * parser/Lexer.h:
-        (JSC::Keywords::getKeyword):
-            - HashEntry -> HashTableValue.
-        * runtime/ClassInfo.h:
-            - removed HashEntry.
-        * runtime/JSObject.cpp:
-        (JSC::getClassPropertyNames):
-            - use HashTable::ConstIterator.
-        (JSC::JSObject::put):
-        (JSC::JSObject::deleteProperty):
-        (JSC::JSObject::findPropertyHashEntry):
-            - HashEntry -> HashTableValue.
-        (JSC::JSObject::reifyStaticFunctionsForDelete):
-            - changed HashTable::ConstIterator interface.
-        * runtime/JSObject.h:
-            - HashEntry -> HashTableValue.
-        * runtime/Lookup.cpp:
-        (JSC::HashTable::createTable):
-            - table -> keys, keys array is now densely packed.
-        (JSC::HashTable::deleteTable):
-            - table -> keys.
-        (JSC::setUpStaticFunctionSlot):
-            - HashEntry -> HashTableValue.
-        * runtime/Lookup.h:
-        (JSC::HashTableValue::builtinGenerator):
-        (JSC::HashTableValue::function):
-        (JSC::HashTableValue::functionLength):
-        (JSC::HashTableValue::propertyGetter):
-        (JSC::HashTableValue::propertyPutter):
-        (JSC::HashTableValue::lexerValue):
-            - added accessor methods from HashEntry.
-        (JSC::HashTable::copy):
-            - fields changed.
-        (JSC::HashTable::initializeIfNeeded):
-            - table -> keys.
-        (JSC::HashTable::entry):
-            - HashEntry -> HashTableValue.
-        (JSC::HashTable::ConstIterator::ConstIterator):
-            - iterate packed value array, so no need to skipInvalidKeys().
-        (JSC::HashTable::ConstIterator::value):
-        (JSC::HashTable::ConstIterator::key):
-        (JSC::HashTable::ConstIterator::operator->):
-            - accessors now get HashTableValue/StringImpl* separately.
-        (JSC::HashTable::ConstIterator::operator++):
-            - iterate packed value array, so no need to skipInvalidKeys().
-        (JSC::HashTable::end):
-            - end is now size of dense not sparse array.
-        (JSC::getStaticPropertySlot):
-        (JSC::getStaticFunctionSlot):
-        (JSC::getStaticValueSlot):
-        (JSC::putEntry):
-        (JSC::lookupPut):
-            - HashEntry -> HashTableValue.
-
-2014-03-13  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix Mac no-FTL build.
-
-        * llvm/library/LLVMExports.cpp:
-        (initializeAndGetJSCLLVMAPI):
-
-2014-03-13  Juergen Ributzka  <juergen@apple.com>
-
-        Only export initializeAndGetJSCLLVMAPI from libllvmForJSC.dylib
-        https://bugs.webkit.org/show_bug.cgi?id=130224
-
-        Reviewed by Filip Pizlo.
-
-        This limits the exported symbols to only initializeAndGetJSCLLVMAPI from
-        the LLVM dylib. This allows the dylib to be safely used with other LLVM
-        dylibs on the same system. It also reduces the dynamic linking overhead
-        and also reduces the size by 6MB, because the linker can now dead strip
-        many unused functions.
-
-        * Configurations/LLVMForJSC.xcconfig:
-
-2014-03-13  Andreas Kling  <akling@apple.com>
-
-        VM::discardAllCode() should clear the RegExp cache.
-        <https://webkit.org/b/130144>
-
-        Reviewed by Michael Saboff.
-
-        * runtime/VM.cpp:
-        (JSC::VM::discardAllCode):
-
-2014-03-13  Andreas Kling  <akling@apple.com>
-
-        Revert "Short-circuit JSGlobalObjectInspectorController when not inspecting."
-        <https://webkit.org/b/129995>
-
-        This code path is not taken anymore on DYEB, and I can't explain why
-        it was showing up in my profiles. Backing it out per JoePeck's suggestion.
-
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-
-2014-03-13  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should support IsBlah
-        https://bugs.webkit.org/show_bug.cgi?id=130202
-
-        Reviewed by Geoffrey Garen.
-
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileIsUndefined):
-        (JSC::FTL::LowerDFGToLLVM::compileIsBoolean):
-        (JSC::FTL::LowerDFGToLLVM::compileIsNumber):
-        (JSC::FTL::LowerDFGToLLVM::compileIsString):
-        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
-        (JSC::FTL::LowerDFGToLLVM::compileIsFunction):
-        (JSC::FTL::LowerDFGToLLVM::compileStoreBarrier):
-        (JSC::FTL::LowerDFGToLLVM::compileStoreBarrierWithNullCheck):
-        (JSC::FTL::LowerDFGToLLVM::isNotCellOrMisc):
-        (JSC::FTL::LowerDFGToLLVM::isNumber):
-        (JSC::FTL::LowerDFGToLLVM::isNotNumber):
-        (JSC::FTL::LowerDFGToLLVM::isBoolean):
-        * ftl/FTLOSRExitCompiler.cpp:
-        * tests/stress/is-undefined-exit-on-masquerader.js: Added.
-        (bar):
-        (foo):
-        (test):
-        * tests/stress/is-undefined-jettison-on-masquerader.js: Added.
-        (foo):
-        (test):
-        * tests/stress/is-undefined-masquerader.js: Added.
-        (foo):
-        (test):
-
-2014-03-13  Mark Lam  <mark.lam@apple.com>
-
-        JS benchmarks crash with a bus error on 32-bit x86.
-        <https://webkit.org/b/130203>
-
-        Reviewed by Geoffrey Garen.
-
-        The issue is that generateGetByIdStub() can potentially use the same register
-        for the JSValue base register and the target tag register.  After loading the
-        tag value into the target tag register, the JSValue base address is lost.
-        The code then proceeds to load the payload value using the base register, and
-        this results in a crash.
-
-        The fix is to check if the base register is the same as the target tag register.
-        If so, we should make a copy the base register first before loading the tag
-        value, and use the copy to load the payload value instead.
-
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub):
-
-2014-03-12  Filip Pizlo  <fpizlo@apple.com>
-
-        WebKit shouldn't crash on uniprocessor machines
-        https://bugs.webkit.org/show_bug.cgi?id=130176
-
-        Reviewed by Michael Saboff.
-        
-        Previously the math for computing the number of JIT compiler threads would come up with
-        zero threads on uniprocessor machines, and then the Worklist code would assert.
-
-        * runtime/Options.cpp:
-        (JSC::computeNumberOfWorkerThreads):
-        * runtime/Options.h:
-
-2014-03-13  Radu Stavila  <stavila@adobe.com>
-
-        Webkit not building on XCode 5.1 due to garbage collection no longer being supported
-        https://bugs.webkit.org/show_bug.cgi?id=130087
-
-        Reviewed by Mark Rowe.
-
-        Disable garbage collection on macosx when not using internal SDK.
-
-        * Configurations/Base.xcconfig:
-
-2014-03-10  Darin Adler  <darin@apple.com>
-
-        Avoid copy-prone idiom "for (auto item : collection)"
-        https://bugs.webkit.org/show_bug.cgi?id=129990
-
-        Reviewed by Geoffrey Garen.
-
-        * heap/CodeBlockSet.h:
-        (JSC::CodeBlockSet::iterate): Use auto& to be sure we don't copy by accident.
-        * inspector/ScriptDebugServer.cpp:
-        (Inspector::ScriptDebugServer::dispatchBreakpointActionLog): Use auto* to
-        make explicit that we are iterating through pointers.
-        (Inspector::ScriptDebugServer::dispatchBreakpointActionSound): Ditto.
-        (Inspector::ScriptDebugServer::dispatchBreakpointActionProbe): Ditto.
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        (Inspector::InspectorDebuggerAgent::removeBreakpoint): Use auto&, and also
-        get rid of an unneeded local variable.
-
-2014-03-13  Brian Burg  <bburg@apple.com>
-
-        Web Inspector: Remove unused callId parameter from evaluateInWebInspector
-        https://bugs.webkit.org/show_bug.cgi?id=129744
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/agents/InspectorAgent.cpp:
-        (Inspector::InspectorAgent::enable):
-        (Inspector::InspectorAgent::evaluateForTestInFrontend):
-        * inspector/agents/InspectorAgent.h:
-        * inspector/protocol/InspectorDomain.json:
-
-2014-03-11  Filip Pizlo  <fpizlo@apple.com>
-
-        ASSERTION FAILED: node->op() == Phi || node->op() == SetArgument
-        https://bugs.webkit.org/show_bug.cgi?id=130069
-
-        Reviewed by Geoffrey Garen.
-        
-        This was a great assertion, and it represents our strictest interpretation of the rules of
-        our intermediate representation. However, fixing DCE to actually preserve the relevant
-        property would be hard, and it wouldn't have an observable effect right now because nobody
-        actually uses the propery of CPS that this assertion is checking for.
-        
-        In particular, we do always require, and rely on, the fact that non-captured variables
-        have variablesAtTail refer to the last interesting use of the variable: a SetLocal if the
-        block assigns to the variable, a GetLocal if it only reads from it, and a Flush,
-        PhantomLocal, or Phi otherwise. We do preserve this property successfully and DCE was not
-        broken in this regard. But, in the strictest sense, CPS also means that for captured
-        variables, variablesAtTail also continues to point to the last relevant use of the
-        variable. In particular, if there are multiple GetLocals, then it should point to the last
-        one. This is hard for DCE to preserve. Also, nobody relies on variablesAtTail for captured
-        variables, except to check the VariableAccessData; but in that case, we don't really need
-        the *last* relevant use of the variable - any node that mentions the same variable will do
-        just fine.
-        
-        So, this change loosens the assertion and adds a detailed FIXME describing what we would
-        have to do if we wanted to preserve the more strict property.
-        
-        This also makes changes to various debug printing paths so that validation doesn't crash
-        during graph dump. This also adds tests for the interesting cases of DCE failing to
-        preserve CPS in the strictest sense. This also attempts to win the record for longest test
-        name.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::hashAsStringIfPossible):
-        (JSC::CodeBlock::dumpAssumingJITType):
-        * bytecode/CodeBlock.h:
-        * bytecode/CodeOrigin.cpp:
-        (JSC::InlineCallFrame::hashAsStringIfPossible):
-        (JSC::InlineCallFrame::dumpBriefFunctionInformation):
-        * bytecode/CodeOrigin.h:
-        * dfg/DFGCPSRethreadingPhase.cpp:
-        (JSC::DFG::CPSRethreadingPhase::run):
-        * dfg/DFGDCEPhase.cpp:
-        (JSC::DFG::DCEPhase::cleanVariables):
-        * dfg/DFGInPlaceAbstractState.cpp:
-        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
-        * runtime/FunctionExecutableDump.cpp:
-        (JSC::FunctionExecutableDump::dump):
-        * tests/stress/dead-access-to-captured-variable-preceded-by-a-live-store-in-function-with-multiple-basic-blocks.js: Added.
-        (foo):
-        * tests/stress/dead-access-to-captured-variable-preceded-by-a-live-store.js: Added.
-        (foo):
-
-2014-03-12  Brian Burg  <bburg@apple.com>
-
-        Web Replay: add infrastructure for memoizing nondeterministic DOM APIs
-        https://bugs.webkit.org/show_bug.cgi?id=129445
-
-        Reviewed by Timothy Hatcher.
-
-        There was a bug in the replay inputs code generator that would include
-        headers for definitions of enum classes, even though they can be safely
-        forward-declared.
-
-        * replay/scripts/CodeGeneratorReplayInputs.py:
-        (Generator.generate_includes): Only include for copy constructor if the
-        type is a heavy scalar (i.e., String, URL), not a normal scalar
-        (i.e., int, double, enum classes).
-
-        (Generator.generate_type_forward_declarations): Forward-declare scalars
-        that are enums or enum classes.
-
-2014-03-12  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Disable REMOTE_INSPECTOR in earlier OS X releases
-        https://bugs.webkit.org/show_bug.cgi?id=130118
-
-        Reviewed by Timothy Hatcher.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-03-12  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Hang in Remote Inspection triggering breakpoint from console
-        https://bugs.webkit.org/show_bug.cgi?id=130032
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/EventLoop.h:
-        * inspector/EventLoop.cpp:
-        (Inspector::EventLoop::remoteInspectorRunLoopMode):
-        (Inspector::EventLoop::cycle):
-        Expose the run loop mode name so it can be used if needed by others.
-
-        * inspector/remote/RemoteInspectorDebuggableConnection.h:
-        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
-        (Inspector::RemoteInspectorBlock::RemoteInspectorBlock):
-        (Inspector::RemoteInspectorBlock::~RemoteInspectorBlock):
-        (Inspector::RemoteInspectorBlock::operator=):
-        (Inspector::RemoteInspectorBlock::operator()):
-        (Inspector::RemoteInspectorQueueTask):
-        Instead of a dispatch_queue, have our own static Vector of debugger tasks.
-
-        (Inspector::RemoteInspectorHandleRunSource):
-        (Inspector::RemoteInspectorInitializeQueue):
-        Initialize the static queue and run loop source. When the run loop source
-        fires, it will exhaust the queue of debugger messages.
-
-        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
-        (Inspector::RemoteInspectorDebuggableConnection::~RemoteInspectorDebuggableConnection):
-        When we get a debuggable connection add a run loop source for inspector commands.
-
-        (Inspector::RemoteInspectorDebuggableConnection::dispatchAsyncOnDebuggable):
-        (Inspector::RemoteInspectorDebuggableConnection::sendMessageToBackend):
-        Enqueue blocks on our Vector instead of our dispatch_queue.
-
-2014-03-12  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r165482.
-        https://bugs.webkit.org/show_bug.cgi?id=130157
-
-        Broke the windows build; "error C2466: cannot allocate an
-        array of constant size 0" (Requested by jernoble on #webkit).
-
-        Reverted changeset:
-
-        "Reduce memory use for static property maps"
-        https://bugs.webkit.org/show_bug.cgi?id=129986
-        http://trac.webkit.org/changeset/165482
-
-2014-03-12  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Remove HandleSet::m_nextToFinalize
-        https://bugs.webkit.org/show_bug.cgi?id=130109
-
-        Reviewed by Mark Lam.
-
-        This is a remnant of when HandleSet contained things that needed to be finalized. 
-
-        * heap/HandleSet.cpp:
-        (JSC::HandleSet::HandleSet):
-        (JSC::HandleSet::writeBarrier):
-        * heap/HandleSet.h:
-        (JSC::HandleSet::allocate):
-        (JSC::HandleSet::deallocate):
-
-2014-03-12  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Layout Test fast/workers/worker-gc.html is failing
-        https://bugs.webkit.org/show_bug.cgi?id=130135
-
-        Reviewed by Geoffrey Garen.
-
-        When removing MarkedBlocks, we always expect them to be in the MarkedAllocator's 
-        main list of blocks, i.e. not in the retired list. When shutting down the VM this
-        wasn't always the case which was causing ASSERTs to fire. We should rearrange things 
-        so that allocators are notified with lastChanceToFinalize. This will give them 
-        the chance to move their retired blocks back into the main list before removing them all.
-
-        * heap/MarkedAllocator.cpp:
-        (JSC::LastChanceToFinalize::operator()):
-        (JSC::MarkedAllocator::lastChanceToFinalize):
-        * heap/MarkedAllocator.h:
-        * heap/MarkedSpace.cpp:
-        (JSC::LastChanceToFinalize::operator()):
-        (JSC::MarkedSpace::lastChanceToFinalize):
-
-2014-03-12  Gavin Barraclough  <barraclough@apple.com>
-
-        Reduce memory use for static property maps
-        https://bugs.webkit.org/show_bug.cgi?id=129986
-
-        Reviewed by Andreas Kling.
-
-        Static property tables are currently duplicated on first use from read-only memory into dirty memory
-        in every process, and since the entries are large (48 bytes) and the tables can be unusually sparse
-        (we use a custom hash table without a rehash) a lot of memory may be wasted.
-
-        First, reduce the size of the hashtable. Instead of storing values in the table the hashtable maps
-        from string hashes to indicies into a densely packed array of values. Compute the index table at
-        compile time as a part of the derived sources step, such that this may be read-only data.
-
-        Second, don't copy all data from the HashTableValue array into a HashEntry objects. Instead refer
-        directly to the HashTableValue entries. The only data that needs to be allocated at runtime are the
-        keys, which are Identifiers.
-
-        * create_hash_table:
-            - emit the hash table index into the derived source (we were calculating this already to ensure chaining does not get too deep).
-        * parser/Lexer.cpp:
-        (JSC::Lexer<LChar>::parseIdentifier):
-        (JSC::Lexer<UChar>::parseIdentifier):
-        (JSC::Lexer<T>::parseIdentifierSlowCase):
-            - HashEntry -> HashTableValue.
-        * parser/Lexer.h:
-        (JSC::Keywords::getKeyword):
-            - HashEntry -> HashTableValue.
-        * runtime/ClassInfo.h:
-            - removed HashEntry.
-        * runtime/JSObject.cpp:
-        (JSC::getClassPropertyNames):
-            - use HashTable::ConstIterator.
-        (JSC::JSObject::put):
-        (JSC::JSObject::deleteProperty):
-        (JSC::JSObject::findPropertyHashEntry):
-            - HashEntry -> HashTableValue.
-        (JSC::JSObject::reifyStaticFunctionsForDelete):
-            - changed HashTable::ConstIterator interface.
-        * runtime/JSObject.h:
-            - HashEntry -> HashTableValue.
-        * runtime/Lookup.cpp:
-        (JSC::HashTable::createTable):
-            - table -> keys, keys array is now densely packed.
-        (JSC::HashTable::deleteTable):
-            - table -> keys.
-        (JSC::setUpStaticFunctionSlot):
-            - HashEntry -> HashTableValue.
-        * runtime/Lookup.h:
-        (JSC::HashTableValue::builtinGenerator):
-        (JSC::HashTableValue::function):
-        (JSC::HashTableValue::functionLength):
-        (JSC::HashTableValue::propertyGetter):
-        (JSC::HashTableValue::propertyPutter):
-        (JSC::HashTableValue::lexerValue):
-            - added accessor methods from HashEntry.
-        (JSC::HashTable::copy):
-            - fields changed.
-        (JSC::HashTable::initializeIfNeeded):
-            - table -> keys.
-        (JSC::HashTable::entry):
-            - HashEntry -> HashTableValue.
-        (JSC::HashTable::ConstIterator::ConstIterator):
-            - iterate packed value array, so no need to skipInvalidKeys().
-        (JSC::HashTable::ConstIterator::value):
-        (JSC::HashTable::ConstIterator::key):
-        (JSC::HashTable::ConstIterator::operator->):
-            - accessors now get HashTableValue/StringImpl* separately.
-        (JSC::HashTable::ConstIterator::operator++):
-            - iterate packed value array, so no need to skipInvalidKeys().
-        (JSC::HashTable::end):
-            - end is now size of dense not sparse array.
-        (JSC::getStaticPropertySlot):
-        (JSC::getStaticFunctionSlot):
-        (JSC::getStaticValueSlot):
-        (JSC::putEntry):
-        (JSC::lookupPut):
-            - HashEntry -> HashTableValue.
-
-2014-03-11  Filip Pizlo  <fpizlo@apple.com>
-
-        It should be possible to build WebKit with FTL on iOS
-        https://bugs.webkit.org/show_bug.cgi?id=130116
-
-        Reviewed by Dan Bernstein.
-
-        * Configurations/Base.xcconfig:
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        GetById list caching should use something object-oriented rather than PolymorphicAccessStructureList
-        https://bugs.webkit.org/show_bug.cgi?id=129778
-
-        Reviewed by Geoffrey Garen.
-        
-        Also deduplicate the GetById getter call caching. Also add some small tests for
-        get stubs.
-        
-        This change reduces the amount of code involved in GetById access caching and it
-        creates data structures that can serve as an elegant scaffold for introducing other
-        kinds of caches or improving current caching styles. It will definitely make getter
-        performance improvements easier to implement.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::printGetByIdCacheStatus):
-        * bytecode/GetByIdStatus.cpp:
-        (JSC::GetByIdStatus::computeForStubInfo):
-        * bytecode/PolymorphicGetByIdList.cpp: Added.
-        (JSC::GetByIdAccess::GetByIdAccess):
-        (JSC::GetByIdAccess::~GetByIdAccess):
-        (JSC::GetByIdAccess::fromStructureStubInfo):
-        (JSC::GetByIdAccess::visitWeak):
-        (JSC::PolymorphicGetByIdList::PolymorphicGetByIdList):
-        (JSC::PolymorphicGetByIdList::from):
-        (JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList):
-        (JSC::PolymorphicGetByIdList::currentSlowPathTarget):
-        (JSC::PolymorphicGetByIdList::addAccess):
-        (JSC::PolymorphicGetByIdList::isFull):
-        (JSC::PolymorphicGetByIdList::isAlmostFull):
-        (JSC::PolymorphicGetByIdList::didSelfPatching):
-        (JSC::PolymorphicGetByIdList::visitWeak):
-        * bytecode/PolymorphicGetByIdList.h: Added.
-        (JSC::GetByIdAccess::GetByIdAccess):
-        (JSC::GetByIdAccess::isSet):
-        (JSC::GetByIdAccess::operator!):
-        (JSC::GetByIdAccess::type):
-        (JSC::GetByIdAccess::structure):
-        (JSC::GetByIdAccess::chain):
-        (JSC::GetByIdAccess::chainCount):
-        (JSC::GetByIdAccess::stubRoutine):
-        (JSC::GetByIdAccess::doesCalls):
-        (JSC::PolymorphicGetByIdList::isEmpty):
-        (JSC::PolymorphicGetByIdList::size):
-        (JSC::PolymorphicGetByIdList::at):
-        (JSC::PolymorphicGetByIdList::operator[]):
-        * bytecode/StructureStubInfo.cpp:
-        (JSC::StructureStubInfo::deref):
-        (JSC::StructureStubInfo::visitWeakReferences):
-        * bytecode/StructureStubInfo.h:
-        (JSC::isGetByIdAccess):
-        (JSC::StructureStubInfo::initGetByIdList):
-        * jit/Repatch.cpp:
-        (JSC::generateGetByIdStub):
-        (JSC::tryCacheGetByID):
-        (JSC::patchJumpToGetByIdStub):
-        (JSC::tryBuildGetByIDList):
-        (JSC::tryBuildPutByIdList):
-        * tests/stress/getter.js: Added.
-        (foo):
-        (.o):
-        * tests/stress/polymorphic-prototype-accesses.js: Added.
-        (Foo):
-        (Bar):
-        (foo):
-        * tests/stress/prototype-getter.js: Added.
-        (Foo):
-        (foo):
-        * tests/stress/simple-prototype-accesses.js: Added.
-        (Foo):
-        (foo):
-
-2014-03-11  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        MarkedBlocks that are "full enough" shouldn't be swept after EdenCollections
-        https://bugs.webkit.org/show_bug.cgi?id=129920
-
-        Reviewed by Geoffrey Garen.
-
-        This patch introduces the notion of "retiring" MarkedBlocks. We retire a MarkedBlock
-        when the amount of free space in a MarkedBlock drops below a certain threshold.
-        Retired blocks are not considered for sweeping.
-
-        This is profitable because it reduces churn during sweeping. To build a free list, 
-        we have to scan through each cell in a block. After a collection, all objects that 
-        are live in the block will remain live until the next FullCollection, at which time
-        we un-retire all previously retired blocks. Thus, a small number of objects in a block
-        that die during each EdenCollection could cause us to do a disproportiante amount of 
-        sweeping for how much free memory we get back.
-
-        This patch looks like a consistent ~2% progression on boyer and is neutral everywhere else.
-
-        * heap/Heap.h:
-        (JSC::Heap::didRetireBlockWithFreeListSize):
-        * heap/MarkedAllocator.cpp:
-        (JSC::MarkedAllocator::tryAllocateHelper):
-        (JSC::MarkedAllocator::removeBlock):
-        (JSC::MarkedAllocator::reset):
-        * heap/MarkedAllocator.h:
-        (JSC::MarkedAllocator::MarkedAllocator):
-        (JSC::MarkedAllocator::forEachBlock):
-        * heap/MarkedBlock.cpp:
-        (JSC::MarkedBlock::sweepHelper):
-        (JSC::MarkedBlock::clearMarksWithCollectionType):
-        (JSC::MarkedBlock::didRetireBlock):
-        * heap/MarkedBlock.h:
-        (JSC::MarkedBlock::willRemoveBlock):
-        (JSC::MarkedBlock::isLive):
-        * heap/MarkedSpace.cpp:
-        (JSC::MarkedSpace::clearNewlyAllocated):
-        (JSC::MarkedSpace::clearMarks):
-        * runtime/Options.h:
-
-2014-03-11  Andreas Kling  <akling@apple.com>
-
-        Streamline PropertyTable for lookup-only access.
-        <https://webkit.org/b/130060>
-
-        The PropertyTable lookup algorithm was written to support both read
-        and write access. This wasn't actually needed in most places.
-
-        This change adds a PropertyTable::get() that just returns the value
-        type (instead of an insertion iterator.) It also adds an early return
-        for empty tables.
-
-        Finally, up the minimum table capacity from 8 to 16. It was lowered
-        to 8 in order to save memory, but that was before PropertyTables were
-        GC allocated. Nowadays we don't have nearly as many tables, since all
-        the unpinned transitions die off.
-
-        Reviewed by Darin Adler.
-
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::get):
-        * runtime/Structure.cpp:
-        (JSC::Structure::despecifyDictionaryFunction):
-        (JSC::Structure::attributeChangeTransition):
-        (JSC::Structure::get):
-        (JSC::Structure::despecifyFunction):
-        * runtime/StructureInlines.h:
-        (JSC::Structure::get):
-
-2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        REGRESSION(r165407): DoYouEvenBench crashes in DRT
-        https://bugs.webkit.org/show_bug.cgi?id=130066
-
-        Reviewed by Geoffrey Garen.
-
-        The baseline JIT does a conditional store barrier for the put_by_id, but we need 
-        an unconditional store barrier so that we cover the butterfly case as well in emitPutTransitionStub.
-
-        * jit/JIT.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emit_op_put_by_id):
-        (JSC::JIT::emitWriteBarrier):
-
-2014-03-10  Mark Lam  <mark.lam@apple.com>
-
-        Resurrect bit-rotted JIT::probe() mechanism.
-        <https://webkit.org/b/130067>
-
-        Reviewed by Geoffrey Garen.
-
-        * jit/JITStubs.cpp:
-        - Added the needed #include <wtf/InlineASM.h>.
-
-2014-03-10  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Fix typo in EXCLUDED_SOURCE_FILE_NAMES_iphoneos.
-
-        Rubber-stamped by Dan Bernstein.
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2014-03-10  Mark Lam  <mark.lam@apple.com>
-
-        r165414 broke the 32-bit x86 tests: ASSERTION FAILED: result != InvalidIndex @ GPRInfo.h:330.
-        <https://webkit.org/b/130065>
-
-        Reviewed by Michael Saboff.
-
-        There is code in ScratchRegisterAllocator.cpp that is relying on GPRInfo::toIndex()
-        being able to return InvalidIndex.  Hence, the assertion is invalid.  Ditto for
-        FPRInfo::toIndex().
-
-        The fix is to remove the "result != InvalidIndex" assertions.
-
-        * jit/FPRInfo.h:
-        (JSC::FPRInfo::toIndex):
-        * jit/GPRInfo.h:
-        (JSC::GPRInfo::toIndex):
-
-2014-03-10  Mark Lam  <mark.lam@apple.com>
-
-        Crash on a stack overflow on 32-bit x86 in http/tests/websocket/tests/hybi/workers/no-onmessage-in-sync-op.html.
-        <https://webkit.org/b/129955>
-
-        Reviewed by Geoffrey Garen.
-
-        The 32-bit x86 version of getHostCallReturnValue() was leaking 16 bytes
-        stack memory every time it was called.  This is now fixed.
-
-        * jit/JITOperations.cpp:
-
-2014-03-10  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Better JSContext API for named evaluations (other than //# sourceURL)
-        https://bugs.webkit.org/show_bug.cgi?id=129911
-
-        Reviewed by Geoffrey Garen.
-
-        * API/JSBase.h:
-        * API/JSContext.h:
-        * API/JSContext.mm:
-        (-[JSContext evaluateScript:]):
-        (-[JSContext evaluateScript:withSourceURL:]):
-        Add new evaluateScript:withSourceURL:.
-
-        * API/tests/testapi.c:
-        (main):
-        * API/tests/testapi.mm:
-        (testObjectiveCAPI):
-        Add tests for sourceURL in evaluate APIs. It should
-        affect the exception objects.
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        Repatch should save and restore all used registers - not just temp ones - when making a call
-        https://bugs.webkit.org/show_bug.cgi?id=130041
-
-        Reviewed by Geoffrey Garen and Mark Hahnenberg.
-        
-        The save/restore code was written back when the only client was the DFG, which only uses a
-        subset of hardware registers: the "temp" registers in our lingo. But the FTL may use many
-        other registers, especially on ARM64. The fact that Repatch doesn't know to save those can
-        lead to data corruption on ARM64. 
-
-        * jit/RegisterSet.cpp:
-        (JSC::RegisterSet::calleeSaveRegisters):
-        (JSC::RegisterSet::numberOfSetGPRs):
-        (JSC::RegisterSet::numberOfSetFPRs):
-        * jit/RegisterSet.h:
-        * jit/Repatch.cpp:
-        (JSC::storeToWriteBarrierBuffer):
-        (JSC::emitPutTransitionStub):
-        * jit/ScratchRegisterAllocator.cpp:
-        (JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
-        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
-        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
-        (JSC::ScratchRegisterAllocator::usedRegistersForCall):
-        (JSC::ScratchRegisterAllocator::desiredScratchBufferSizeForCall):
-        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall):
-        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall):
-        * jit/ScratchRegisterAllocator.h:
-
-2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Remove ConditionalStore barrier
-        https://bugs.webkit.org/show_bug.cgi?id=130040
-
-        Reviewed by Geoffrey Garen.
-
-        ConditionalStoreBarrier was created when barriers were much more expensive. Now that 
-        they're cheap(er), we can get rid of them. This also allows us to get rid of the write 
-        barrier logic in emitPutTransitionStub because we always will have executed a write barrier 
-        on the base object in the case where we are allocating and storing a new Butterfly into it. 
-        Previously, a ConditionalStoreBarrier might or might not have barrier-ed the base object, 
-        so we'd have to emit a write barrier in the transition case.
-
-        This is performance neutral on the benchmarks we track.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::insertStoreBarrier):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::isStoreBarrier):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileStoreBarrier):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        * jit/Repatch.cpp:
-        (JSC::emitPutTransitionStub):
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG and FTL should know that comparing anything to Misc is cheap and easy
-        https://bugs.webkit.org/show_bug.cgi?id=130001
-
-        Reviewed by Geoffrey Garen.
-        
-        - Expand CompareStrictEq(Misc:, Misc:) to work for cases where either side of the
-          comparison is just Untyped:.
-        
-        - This obviates the need for CompareStrictEqConstant, so remove it.
-        
-        - FTL had a thing called "Nully" which is really "Other". Rename it and add
-          OtherUse.
-        
-        9% speed-up on box2d.
-
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::isBinaryUseKind):
-        (JSC::DFG::Node::shouldSpeculateOther):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
-        (JSC::DFG::SpeculativeJIT::compare):
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
-        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
-        (JSC::FTL::LowerDFGToLLVM::isNotOther):
-        (JSC::FTL::LowerDFGToLLVM::isOther):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
-        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
-        (JSC::FTL::LowerDFGToLLVM::speculateOther):
-        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
-        * tests/stress/compare-strict-eq-integer-to-misc.js: Added.
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, remove unintended change.
-
-        * dfg/DFGDriver.cpp:
-        (JSC::DFG::compileImpl):
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        jsc commandline shouldn't have a "console" because that confuses some tests into thinking
-        that they're running in the browser.
-
-        Rubber stamped by Mark Hahnenberg.
-
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-
-2014-03-10  Filip Pizlo  <fpizlo@apple.com>
-
-        Out-line ScratchRegisterAllocator
-
-        Rubber stamped by Mark Hahnenberg.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGDriver.cpp:
-        (JSC::DFG::compileImpl):
-        * jit/ScratchRegisterAllocator.cpp: Added.
-        (JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
-        (JSC::ScratchRegisterAllocator::~ScratchRegisterAllocator):
-        (JSC::ScratchRegisterAllocator::lock):
-        (JSC::ScratchRegisterAllocator::allocateScratch):
-        (JSC::ScratchRegisterAllocator::allocateScratchGPR):
-        (JSC::ScratchRegisterAllocator::allocateScratchFPR):
-        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
-        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
-        (JSC::ScratchRegisterAllocator::desiredScratchBufferSize):
-        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
-        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
-        * jit/ScratchRegisterAllocator.h:
-
-2014-03-10  Brent Fulgham  <bfulgham@apple.com>
-
-        [Win] Pass environment to Pre-Build, Pre-link, and Post-Build Stages.
-        https://bugs.webkit.org/show_bug.cgi?id=130023
-
-        Reviewed by Dean Jackson.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.proj: Avoid trailing backslashes in
-        path names to avoid accidental escaping of later string substitutions.
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for testb_i8r when register is accumulator.
-        <https://webkit.org/b/130026>
-
-        Generate the shorthand version of "test al, imm" when possible.
-
-        Reviewed by Michael Saboff.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::testb_i8r):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for sub_ir when register is accumulator.
-        <https://webkit.org/b/130025>
-
-        Generate the shorthand version of "sub eax, imm" when possible.
-
-        Reviewed by Michael Saboff.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::subl_ir):
-        (JSC::X86Assembler::subq_ir):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for add_ir when register is accumulator.
-        <https://webkit.org/b/130024>
-
-        Generate the shorthand version of "add eax, imm" when possible.
-
-        Reviewed by Michael Saboff.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::addl_ir):
-        (JSC::X86Assembler::addq_ir):
-
-2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        writeBarrier in emitPutReplaceStub is unnecessary
-        https://bugs.webkit.org/show_bug.cgi?id=130030
-
-        Reviewed by Filip Pizlo.
-
-        We already emit write barriers for each put-by-id when they're first compiled, so it's 
-        redundant to emit a write barrier as part of the repatched code.
-
-        * jit/Repatch.cpp:
-        (JSC::emitPutReplaceStub):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for xor_ir when register is accumulator.
-        <https://webkit.org/b/130008>
-
-        Generate the shorthand version of "xor eax, imm" when possible.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::xorl_ir):
-        (JSC::X86Assembler::xorq_ir):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for or_ir when register is accumulator.
-        <https://webkit.org/b/130007>
-
-        Generate the shorthand version of "or eax, imm" when possible.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::orl_ir):
-        (JSC::X86Assembler::orq_ir):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for test_ir when register is accumulator.
-        <https://webkit.org/b/130006>
-
-        Generate the shorthand version of "test eax, imm" when possible.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::testl_i32r):
-        (JSC::X86Assembler::testq_i32r):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for cmp_ir when register is accumulator.
-        <https://webkit.org/b/130005>
-
-        Generate the shorthand version of "cmp eax, imm" when possible.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::cmpl_ir):
-        (JSC::X86Assembler::cmpq_ir):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for store64(imm, address) when imm fits in 32 bits.
-        <https://webkit.org/b/130002>
-
-        Generate this:
-
-            mov [address], imm32
-
-        Instead of this:
-
-            mov scratchRegister, imm32
-            mov [address], scratchRegister
-
-        For store64(imm, address) where the 64-bit immediate can be passed as
-        a sign-extended 32-bit value.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/MacroAssemblerX86_64.h:
-        (CAN_SIGN_EXTEND_32_64):
-        (JSC::MacroAssemblerX86_64::store64):
-
-2014-03-10  Andreas Kling  <akling@apple.com>
-
-        [X86_64] Smaller code for xchg_rr when one register is accumulator.
-        <https://webkit.org/b/130004>
-
-        Generate the 1-byte version of "xchg eax, reg" when possible.
-
-        Reviewed by Benjamin Poulain.
-
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::xchgl_rr):
-        (JSC::X86Assembler::xchgq_rr):
-
-2014-03-09  Filip Pizlo  <fpizlo@apple.com>
-
-        GPRInfo::toIndex should return InvalidIndex for non-temp registers on ARM64
-        https://bugs.webkit.org/show_bug.cgi?id=129998
-
-        Reviewed by Geoffrey Garen.
-        
-        Not only is that the established contract, but this is used to signal to
-        ScratchRegisterAllocator that the register doesn't need locking since it isn't a register
-        that this allocator would use. In the FTL, we may have an inline cache where LLVM had used
-        some non-temp register (i.e. a register that JSC itself wouldn't have used). This is totally
-        fine but previously it would have led to either an assertion failure, or data corruption, in
-        the ScratchRegisterAllocator.
-
-        * jit/GPRInfo.h:
-        (JSC::GPRInfo::toIndex):
-
-2014-03-09  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL fails the new equals-masquerader strictEqualConstant test
-        https://bugs.webkit.org/show_bug.cgi?id=129996
-
-        Reviewed by Mark Lam.
-        
-        It turns out that the FTL was trying to do the masquerading stuff for ===null. But
-        that's wrong since none of the other engines do it. The DFG even had an ancient
-        FIXME about doing it - but that doesn't make sense since the LLInt and baseline JIT
-        don't do it and JSValue::strictEqual() doesn't do it.
-        
-        Remove the FIXME and remove the extra checks in the FTL.
-        
-        This is a glorious patch: nothing but red and it fixes a test failure.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
-
-2014-03-09  Andreas Kling  <akling@apple.com>
-
-        Short-circuit JSGlobalObjectInspectorController when not inspecting.
-        <https://webkit.org/b/129995>
-
-        Add an early return in reportAPIException() when the console agent
-        is disabled. This avoids expensive symbolication during exceptions
-        if there's nobody expecting the fancy backtrace anyway.
-
-        ~2% progression on DYEB on my MBP.
-
-        Reviewed by Geoff Garen.
-
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-
-2014-03-09  Andreas Kling  <akling@apple.com>
-
-        Inline the trivial parts of GC deferral.
-        <https://webkit.org/b/129984>
-
-        Made most of the functions called by the DeferGC RAII object inline
-        to avoid function call overhead.
-
-        Looks like ~1% progression on DYEB.
-
-        Reviewed by Geoffrey Garen.
-
-        * heap/Heap.cpp:
-        * heap/Heap.h:
-        (JSC::Heap::incrementDeferralDepth):
-        (JSC::Heap::decrementDeferralDepth):
-        (JSC::Heap::collectIfNecessaryOrDefer):
-        (JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
-
-2014-03-08  Mark Lam  <mark.lam@apple.com>
-
-        32-bit x86 handleUncaughtException returns to wrong location after a stack overflow.
-        <https://webkit.org/b/129969>
-
-        Reviewed by Geoffrey Garen.
-
-        The 32-bit version of handleUncaughtException was missing the handling of an
-        edge case for stack overflows where the current frame may already be the
-        sentinel frame.  This edge case was handled in the 64-bit version.  The fix
-        is to bring the 32-bit version up to parity.
-
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompile):
-        * llint/LowLevelInterpreter32_64.asm:
-
-2014-03-07  Mark Lam  <mark.lam@apple.com>
-
-        Fix bugs in 32-bit Structure implementation.
-        <https://webkit.org/b/129947>
-
-        Reviewed by Mark Hahnenberg.
-
-        Added the loading of the Structure (from the JSCell) before use that was
-        missing in a few places.  Also added more test cases to equals-masquerader.js.
-
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * llint/LowLevelInterpreter32_64.asm:
-        * tests/stress/equals-masquerader.js:
-        (equalsNull):
-        (notEqualsNull):
-        (strictEqualsNull):
-        (strictNotEqualsNull):
-        (equalsUndefined):
-        (notEqualsUndefined):
-        (strictEqualsUndefined):
-        (strictNotEqualsUndefined):
-        (isFalsey):
-        (test):
-
-2014-03-07  Andrew Trick  <atrick@apple.com>
-
-        Temporarily disable repeat-out-of-bounds stress tests pending fix for 129953.
-        https://bugs.webkit.org/show_bug.cgi?id=129954
-
-        Reviewed by Filip Pizlo.
-
-        * tests/stress/float32-repeat-out-of-bounds.js:
-        * tests/stress/int8-repeat-out-of-bounds.js:
-
-2014-03-07  Michael Saboff  <msaboff@apple.com>
-
-        .cfi directives in LowLevelInterpreter.cpp are providing no benefit
-        https://bugs.webkit.org/show_bug.cgi?id=129945
-
-        Reviewed by Mark Lam.
-
-        Removed .cfi directive.  Verified that stack traces didn't regress in crash reporter
-        or in lldb.
-
-        * llint/LowLevelInterpreter.cpp:
-
-2014-03-07  Oliver Hunt  <oliver@apple.com>
-
-        Continue hangs when performing for-of over arguments
-        https://bugs.webkit.org/show_bug.cgi?id=129915
-
-        Reviewed by Geoffrey Garen.
-
-        Put the continue label in the right place
-
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::emitEnumeration):
-
-2014-03-07  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win64] Compile error after r165128.
-        https://bugs.webkit.org/show_bug.cgi?id=129807
-
-        Reviewed by Mark Lam.
-
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: 
-        Check platform environment variable to determine if an assembler file should be generated.
-
-2014-03-07  Michael Saboff  <msaboff@apple.com>
-
-        Clarify how we deal with "special" registers
-        https://bugs.webkit.org/show_bug.cgi?id=129806
-
-        Already reviewed change being relanded.
-
-        Relanding change set r165196 as it wasn't responsible for the breakage reported in
-        https://bugs.webkit.org/show_bug.cgi?id=129822.  That appears to be a build or
-
-        Reviewed by Michael Saboff.
-        configuration issue.
-
-        * assembler/ARM64Assembler.h:
-        (JSC::ARM64Assembler::lastRegister):
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::nextRegister):
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::restoreInto):
-        * ftl/FTLSaveRestore.cpp:
-        (JSC::FTL::saveAllRegisters):
-        (JSC::FTL::restoreAllRegisters):
-        * ftl/FTLSlowPathCall.cpp:
-        * jit/RegisterSet.cpp:
-        (JSC::RegisterSet::reservedHardwareRegisters):
-        (JSC::RegisterSet::runtimeRegisters):
-        (JSC::RegisterSet::specialRegisters):
-        (JSC::RegisterSet::calleeSaveRegisters):
-        * jit/RegisterSet.h:
-
-2014-03-07  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Move GCActivityCallback to heap
-        https://bugs.webkit.org/show_bug.cgi?id=129457
-
-        Reviewed by Geoffrey Garen.
-
-        All the other GC timer related stuff is there already.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * heap/GCActivityCallback.cpp: Copied from Source/JavaScriptCore/runtime/GCActivityCallback.cpp.
-        * heap/GCActivityCallback.h: Copied from Source/JavaScriptCore/runtime/GCActivityCallback.h.
-        * runtime/GCActivityCallback.cpp: Removed.
-        * runtime/GCActivityCallback.h: Removed.
-
-2014-03-07  Andrew Trick  <atrick@apple.com>
-
-        Correct a comment typo from:
-        FLT should call fmod directly on platforms where LLVM cannot relocate the libcall
-        https://bugs.webkit.org/show_bug.cgi?id=129865
-
-        Reviewed by Mark Lam.
-
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::doubleRem):
-
-2014-03-07  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Use OwnPtr in StructureIDTable
-        https://bugs.webkit.org/show_bug.cgi?id=129828
-
-        Reviewed by Geoffrey Garen.
-
-        This reduces the amount of boilerplate and fixes a memory leak.
-
-        * runtime/StructureIDTable.cpp:
-        (JSC::StructureIDTable::StructureIDTable):
-        (JSC::StructureIDTable::resize):
-        (JSC::StructureIDTable::flushOldTables):
-        (JSC::StructureIDTable::allocateID):
-        (JSC::StructureIDTable::deallocateID):
-        * runtime/StructureIDTable.h:
-        (JSC::StructureIDTable::table):
-        (JSC::StructureIDTable::get):
-
-2014-03-07  Andrew Trick  <atrick@apple.com>
-
-        FLT should call fmod directly on platforms where LLVM cannot relocate the libcall
-        https://bugs.webkit.org/show_bug.cgi?id=129865
-
-        Reviewed by Filip Pizlo.
-
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::doubleRem):
-
-2014-03-06  Filip Pizlo  <fpizlo@apple.com>
-
-        If the FTL is build-time enabled then it should be run-time enabled.
-
-        Rubber stamped by Geoffrey Garen.
-
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-        * runtime/Options.h:
-
-2014-03-06  Joseph Pecoraro  <pecoraro@apple.com>
-
-        [OS X] Web Inspector: Allow Apps using JavaScriptCore to access "com.apple.webinspector" mach port
-        https://bugs.webkit.org/show_bug.cgi?id=129852
-
-        Reviewed by Geoffrey Garen.
-
-        * framework.sb: Added.
-        Sandbox extension to allow access to "com.apple.webinspector".
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Add a Copy Resources build phase and include framework.sb.
-
-        * Configurations/JavaScriptCore.xcconfig:
-        Do not copy framework.sb on iOS.
-
-2014-03-06  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSGlobalContextRelease incorrectly handles saving/restoring IdentifierTable
-        https://bugs.webkit.org/show_bug.cgi?id=129858
-
-        Reviewed by Mark Lam.
-
-        It was correct (but really ugly) prior to the combining of APIEntryShim and JSLock, 
-        but now it ends up overwriting the IdentifierTable that JSLock just restored.
-
-        * API/JSContextRef.cpp:
-        (JSGlobalContextRelease):
-
-2014-03-06  Oliver Hunt  <oliver@apple.com>
-
-        Fix FTL build.
-
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-
-2014-03-06  Brent Fulgham  <bfulgham@apple.com>
-
-        Unreviewed build fix after r165128.
-
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: The SEH flag was not getting set when
-        performing 'Production' and 'DebugSuffix' type builds.
-
-2014-03-06  Julien Brianceau  <jbriance@cisco.com>
-
-        Unreviewed, fix style in my previous commit.
-        https://bugs.webkit.org/show_bug.cgi?id=129833
-
-        * runtime/JSConsole.cpp:
-
-2014-03-06  Julien Brianceau  <jbriance@cisco.com>
-
-        Build fix: add missing include in JSConole.cpp.
-        https://bugs.webkit.org/show_bug.cgi?id=129833
-
-        Reviewed by Oliver Hunt.
-
-        * runtime/JSConsole.cpp:
-
-2014-03-06  Oliver Hunt  <oliver@apple.com>
-
-        Fix ARMv7
-
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-
-2014-03-06  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r165196.
-        http://trac.webkit.org/changeset/165196
-        https://bugs.webkit.org/show_bug.cgi?id=129822
-
-        broke arm64 on hardware (Requested by bfulgham on #webkit).
-
-        * assembler/ARM64Assembler.h:
-        (JSC::ARM64Assembler::lastRegister):
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::isStackRelated):
-        (JSC::MacroAssembler::firstRealRegister):
-        (JSC::MacroAssembler::nextRegister):
-        (JSC::MacroAssembler::secondRealRegister):
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::restoreInto):
-        * ftl/FTLSaveRestore.cpp:
-        (JSC::FTL::saveAllRegisters):
-        (JSC::FTL::restoreAllRegisters):
-        * ftl/FTLSlowPathCall.cpp:
-        * jit/RegisterSet.cpp:
-        (JSC::RegisterSet::specialRegisters):
-        (JSC::RegisterSet::calleeSaveRegisters):
-        * jit/RegisterSet.h:
-
-2014-03-06  Mark Lam  <mark.lam@apple.com>
-
-        REGRESSION(r165205): broke the CLOOP build (Requested by smfr on #webkit).
-        <https://webkit.org/b/129813>
-
-        Reviewed by Michael Saboff.
-
-        Fixed broken C loop LLINT build.
-
-        * llint/LowLevelInterpreter.cpp:
-        (JSC::CLoop::execute):
-        * offlineasm/cloop.rb:
-
-2014-03-03  Oliver Hunt  <oliver@apple.com>
-
-        Support caching of custom setters
-        https://bugs.webkit.org/show_bug.cgi?id=129519
-
-        Reviewed by Filip Pizlo.
-
-        This patch adds caching of assignment to properties that
-        are backed by C functions. This provides most of the leg
-        work required to start supporting setters, and resolves
-        the remaining regressions from moving DOM properties up
-        the prototype chain.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/PolymorphicPutByIdList.cpp:
-        (JSC::PutByIdAccess::visitWeak):
-        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
-        (JSC::PolymorphicPutByIdList::from):
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::transition):
-        (JSC::PutByIdAccess::replace):
-        (JSC::PutByIdAccess::customSetter):
-        (JSC::PutByIdAccess::isCustom):
-        (JSC::PutByIdAccess::oldStructure):
-        (JSC::PutByIdAccess::chain):
-        (JSC::PutByIdAccess::stubRoutine):
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeForStubInfo):
-        (JSC::PutByIdStatus::computeFor):
-        (JSC::PutByIdStatus::dump):
-        * bytecode/PutByIdStatus.h:
-        (JSC::PutByIdStatus::PutByIdStatus):
-        (JSC::PutByIdStatus::takesSlowPath):
-        (JSC::PutByIdStatus::makesCalls):
-        * bytecode/StructureStubInfo.h:
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::emitPutById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGCommon.h:
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::hasIdentifier):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileIn):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-        * jit/JITInlineCacheGenerator.cpp:
-        (JSC::JITByIdGenerator::JITByIdGenerator):
-        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
-        * jit/JITInlineCacheGenerator.h:
-        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::emitCustomSetterStub):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * jit/SpillRegistersMode.h: Added.
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * runtime/Lookup.h:
-        (JSC::putEntry):
-        * runtime/PutPropertySlot.h:
-        (JSC::PutPropertySlot::setCacheableCustomProperty):
-        (JSC::PutPropertySlot::customSetter):
-        (JSC::PutPropertySlot::isCacheablePut):
-        (JSC::PutPropertySlot::isCacheableCustomProperty):
-        (JSC::PutPropertySlot::cachedOffset):
-
-2014-03-06  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL arity fixup should work on ARM64
-        https://bugs.webkit.org/show_bug.cgi?id=129810
-
-        Reviewed by Michael Saboff.
-        
-        - Using regT5 to pass the thunk return address to arityFixup is shady since that's a
-          callee-save.
-        
-        - The FTL path was assuming X86 conventions for where SP points at the top of the prologue.
-        
-        This makes some more tests pass.
-
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::compileFunction):
-        * ftl/FTLLink.cpp:
-        (JSC::FTL::link):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::prologueStackPointerDelta):
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompile):
-        * jit/ThunkGenerators.cpp:
-        (JSC::arityFixup):
-        * llint/LowLevelInterpreter64.asm:
-        * offlineasm/arm64.rb:
-        * offlineasm/x86.rb: In addition to the t7 change, make t6 agree with GPRInfo.h.
-
-2014-03-06  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Fix write barriers in Repatch.cpp for !ENABLE(DFG_JIT) platforms after r165128
-        https://bugs.webkit.org/show_bug.cgi?id=129760
-
-        Reviewed by Geoffrey Garen.
-
-        r165128 disabled the write barrier fast path for inline caches on !ENABLE(DFG_JIT) platforms. 
-        The fix is to refactor the write barrier code into AssemblyHelpers and use that everywhere.
-
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::checkMarkByte):
-        * jit/JIT.h:
-        * jit/JITPropertyAccess.cpp:
-        * jit/Repatch.cpp:
-        (JSC::writeBarrier):
-
-2014-03-06  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Expose the console object in JSContexts to interact with Web Inspector
-        https://bugs.webkit.org/show_bug.cgi?id=127944
-
-        Reviewed by Geoffrey Garen.
-
-        Always expose the Console object in JSContexts, just like we
-        do for web pages. The default behavior will route to an
-        attached JSContext inspector. This can be overriden by
-        setting the ConsoleClient on the JSGlobalObject, which WebCore
-        does to get slightly different behavior.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Update build systems.
-
-        * API/tests/testapi.js:
-        * API/tests/testapi.mm:
-        Test that "console" exists in C and ObjC contexts.
-
-        * runtime/ConsoleClient.cpp: Added.
-        (JSC::ConsoleClient::printURLAndPosition):
-        (JSC::ConsoleClient::printMessagePrefix):
-        (JSC::ConsoleClient::printConsoleMessage):
-        (JSC::ConsoleClient::printConsoleMessageWithArguments):
-        (JSC::ConsoleClient::internalMessageWithTypeAndLevel):
-        (JSC::ConsoleClient::logWithLevel):
-        (JSC::ConsoleClient::clear):
-        (JSC::ConsoleClient::dir):
-        (JSC::ConsoleClient::dirXML):
-        (JSC::ConsoleClient::table):
-        (JSC::ConsoleClient::trace):
-        (JSC::ConsoleClient::assertCondition):
-        (JSC::ConsoleClient::group):
-        (JSC::ConsoleClient::groupCollapsed):
-        (JSC::ConsoleClient::groupEnd):
-        * runtime/ConsoleClient.h: Added.
-        (JSC::ConsoleClient::~ConsoleClient):
-        New private interface for handling the console object's methods.
-        A lot of the methods funnel through messageWithTypeAndLevel.
-
-        * runtime/ConsoleTypes.h: Renamed from Source/JavaScriptCore/inspector/ConsoleTypes.h.
-        Moved to JSC namespace.
-
-        * runtime/JSGlobalObject.cpp:
-        (JSC::JSGlobalObject::JSGlobalObject):
-        (JSC::JSGlobalObject::init):
-        (JSC::JSGlobalObject::reset):
-        (JSC::JSGlobalObject::visitChildren):
-        Create the "console" object when initializing the environment.
-        Also set the default console client to be the JS context inspector.
-
-        * runtime/JSGlobalObject.h:
-        (JSC::JSGlobalObject::setConsoleClient):
-        (JSC::JSGlobalObject::consoleClient):
-        Ability to change the console client, so WebCore can set a custom client.
-
-        * runtime/ConsolePrototype.cpp: Added.
-        (JSC::ConsolePrototype::finishCreation):
-        (JSC::valueToStringWithUndefinedOrNullCheck):
-        (JSC::consoleLogWithLevel):
-        (JSC::consoleProtoFuncDebug):
-        (JSC::consoleProtoFuncError):
-        (JSC::consoleProtoFuncLog):
-        (JSC::consoleProtoFuncWarn):
-        (JSC::consoleProtoFuncClear):
-        (JSC::consoleProtoFuncDir):
-        (JSC::consoleProtoFuncDirXML):
-        (JSC::consoleProtoFuncTable):
-        (JSC::consoleProtoFuncTrace):
-        (JSC::consoleProtoFuncAssert):
-        (JSC::consoleProtoFuncCount):
-        (JSC::consoleProtoFuncProfile):
-        (JSC::consoleProtoFuncProfileEnd):
-        (JSC::consoleProtoFuncTime):
-        (JSC::consoleProtoFuncTimeEnd):
-        (JSC::consoleProtoFuncTimeStamp):
-        (JSC::consoleProtoFuncGroup):
-        (JSC::consoleProtoFuncGroupCollapsed):
-        (JSC::consoleProtoFuncGroupEnd):
-        * runtime/ConsolePrototype.h: Added.
-        (JSC::ConsolePrototype::create):
-        (JSC::ConsolePrototype::createStructure):
-        (JSC::ConsolePrototype::ConsolePrototype):
-        Define the console object interface. Parse out required / expected
-        arguments and throw expcetions when methods are misused.
-
-        * runtime/JSConsole.cpp: Added.
-        * runtime/JSConsole.h: Added.
-        (JSC::JSConsole::createStructure):
-        (JSC::JSConsole::create):
-        (JSC::JSConsole::JSConsole):
-        Empty "console" object. Everything is in the prototype.
-
-        * inspector/JSConsoleClient.cpp: Added.
-        (Inspector::JSConsoleClient::JSGlobalObjectConsole):
-        (Inspector::JSConsoleClient::count):
-        (Inspector::JSConsoleClient::profile):
-        (Inspector::JSConsoleClient::profileEnd):
-        (Inspector::JSConsoleClient::time):
-        (Inspector::JSConsoleClient::timeEnd):
-        (Inspector::JSConsoleClient::timeStamp):
-        (Inspector::JSConsoleClient::warnUnimplemented):
-        (Inspector::JSConsoleClient::internalAddMessage):
-        * inspector/JSConsoleClient.h: Added.
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        (Inspector::JSGlobalObjectInspectorController::consoleClient):
-        * inspector/JSGlobalObjectInspectorController.h:
-        Default JSContext ConsoleClient implementation. Handle nearly
-        everything exception profile/profileEnd and timeStamp.
-
-2014-03-06  Andreas Kling  <akling@apple.com>
-
-        Drop unlinked function code on memory pressure.
-        <https://webkit.org/b/129789>
-
-        Make VM::discardAllCode() also drop UnlinkedFunctionCodeBlocks that
-        are not currently being compiled.
-
-        4.5 MB progression on Membuster.
-
-        Reviewed by Geoffrey Garen.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::deleteAllUnlinkedFunctionCode):
-        * heap/Heap.h:
-        * runtime/VM.cpp:
-        (JSC::VM::discardAllCode):
-
-2014-03-06  Filip Pizlo  <fpizlo@apple.com>
-
-        Clarify how we deal with "special" registers
-        https://bugs.webkit.org/show_bug.cgi?id=129806
-
-        Reviewed by Michael Saboff.
-        
-        Previously we had two different places that defined what "stack" registers are, a thing
-        called "specialRegisters" that had unclear meaning, and a really weird "firstRealRegister"/
-        "secondRealRegister"/"nextRegister" idiom in MacroAssembler that appeared to only be used by
-        one place and had a baked-in notion of what it meant for a register to be "real" or not.
-        
-        It's not cool to use words like "real" and "special" to describe registers, especially if you
-        fail to qualify what that means. This originally made sense on X86 - "real" registers were
-        the ones that weren't "stack related" (so "real" was the opposite of "stack"). But on ARM64,
-        you also have to worry about the LR register, which we'd want to say is "not real" but it's
-        also not a "stack" register. This got super confusing.
-        
-        So, this patch removes any mention of "real" registers, consolidates the knowledge of what is
-        a "stack" register, and uses the word special only in places where it's clearly defined and
-        where no better word comes to mind.
-        
-        This cleans up the code and fixes what seems like it was probably a harmless ARM64 bug: the
-        Reg and RegisterSet data structures would sometimes think that FP was Q0. Somehow this
-        magically didn't break anything because you never need to save/restore either FP or Q0, but
-        it was still super weird.
-
-        * assembler/ARM64Assembler.h:
-        (JSC::ARM64Assembler::lastRegister):
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::nextRegister):
-        * ftl/FTLLocation.cpp:
-        (JSC::FTL::Location::restoreInto):
-        * ftl/FTLSaveRestore.cpp:
-        (JSC::FTL::saveAllRegisters):
-        (JSC::FTL::restoreAllRegisters):
-        * ftl/FTLSlowPathCall.cpp:
-        * jit/RegisterSet.cpp:
-        (JSC::RegisterSet::reservedHardwareRegisters):
-        (JSC::RegisterSet::runtimeRegisters):
-        (JSC::RegisterSet::specialRegisters):
-        (JSC::RegisterSet::calleeSaveRegisters):
-        * jit/RegisterSet.h:
-
-2014-03-06  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, fix build.
-
-        * disassembler/ARM64Disassembler.cpp:
-
-2014-03-06  Filip Pizlo  <fpizlo@apple.com>
-
-        Use the LLVM disassembler on ARM64 if we are enabling the FTL
-        https://bugs.webkit.org/show_bug.cgi?id=129785
-
-        Reviewed by Geoffrey Garen.
-        
-        Our disassembler can't handle some of the code sequences that LLVM emits. LLVM's disassembler
-        is strictly more capable at this point. Use it if it's available.
-
-        * disassembler/ARM64Disassembler.cpp:
-        (JSC::tryToDisassemble):
-
-2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Reduce RWI message frequency
-        https://bugs.webkit.org/show_bug.cgi?id=129767
-
-        Reviewed by Timothy Hatcher.
-
-        This used to be 0.2s and changed by accident to 0.02s.
-
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::pushListingSoon):
-
-2014-03-05  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r165141, r165157, and r165158.
-        http://trac.webkit.org/changeset/165141
-        http://trac.webkit.org/changeset/165157
-        http://trac.webkit.org/changeset/165158
-        https://bugs.webkit.org/show_bug.cgi?id=129772
-
-        "broke ftl" (Requested by olliej_ on #webkit).
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/PolymorphicPutByIdList.cpp:
-        (JSC::PutByIdAccess::visitWeak):
-        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
-        (JSC::PolymorphicPutByIdList::from):
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::transition):
-        (JSC::PutByIdAccess::replace):
-        (JSC::PutByIdAccess::oldStructure):
-        (JSC::PutByIdAccess::chain):
-        (JSC::PutByIdAccess::stubRoutine):
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeForStubInfo):
-        (JSC::PutByIdStatus::computeFor):
-        (JSC::PutByIdStatus::dump):
-        * bytecode/PutByIdStatus.h:
-        (JSC::PutByIdStatus::PutByIdStatus):
-        (JSC::PutByIdStatus::takesSlowPath):
-        * bytecode/StructureStubInfo.h:
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::emitPutById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGCommon.h:
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::hasIdentifier):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileIn):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-        * jit/JITInlineCacheGenerator.cpp:
-        (JSC::JITByIdGenerator::JITByIdGenerator):
-        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
-        * jit/JITInlineCacheGenerator.h:
-        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * jit/SpillRegistersMode.h: Removed.
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * runtime/Lookup.h:
-        (JSC::putEntry):
-        * runtime/PutPropertySlot.h:
-        (JSC::PutPropertySlot::isCacheable):
-        (JSC::PutPropertySlot::cachedOffset):
-
-2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Prevent possible deadlock in view indication
-        https://bugs.webkit.org/show_bug.cgi?id=129766
-
-        Reviewed by Geoffrey Garen.
-
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::receivedIndicateMessage):
-
-2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSObject::fastGetOwnPropertySlot does a slow check for OverridesGetOwnPropertySlot
-        https://bugs.webkit.org/show_bug.cgi?id=129754
-
-        Reviewed by Geoffrey Garen.
-
-        InlineTypeFlags are stored in JSCell, so we can just load those instead of going through the TypeInfo.
-
-        * runtime/JSCell.h:
-        (JSC::JSCell::inlineTypeFlags):
-        * runtime/JSObject.h:
-        (JSC::JSObject::fastGetOwnPropertySlot):
-        * runtime/JSTypeInfo.h:
-        (JSC::TypeInfo::TypeInfo):
-        (JSC::TypeInfo::overridesGetOwnPropertySlot):
-
-2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: ASSERTION FAILED: m_javaScriptBreakpoints.isEmpty()
-        https://bugs.webkit.org/show_bug.cgi?id=129763
-
-        Reviewed by Geoffrey Garen.
-
-        Clear the list of all breakpoints, including unresolved breakpoints.
-
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
-
-2014-03-05  Mark Lam  <mark.lam@apple.com>
-
-        llint_slow_path_check_has_instance() should not adjust PC before accessing operands.
-        <https://webkit.org/b/129768>
-
-        Reviewed by Mark Hahnenberg.
-
-        When evaluating "a instanceof b" where b is an object that ImplementsHasInstance
-        and OverridesHasInstance (e.g. a bound function), the LLINT will take the slow
-        path llint_slow_path_check_has_instance(), and execute a code path that does the
-        following:
-        1. Adjusts the byte code PC to the jump target PC.
-        2. For the purpose of storing the result, get the result registerIndex from the
-           1st operand using the PC as if the PC is still pointing to op_check_has_instance
-           bytecode.
-
-        The result is that whatever value resides after where the jump target PC is will
-        be used as a result register value.  Depending on what that value is, the result
-        can be:
-        1. the code coincidently works correctly
-        2. memory corruption
-        3. crashes
-
-        The fix is to only adjust the byte code PC after we have stored the result.
-        
-        * llint/LLIntSlowPaths.cpp:
-        (llint_slow_path_check_has_instance):
-
-2014-03-05  Ryosuke Niwa  <rniwa@webkit.org>
-
-        Another build fix attempt after r165141.
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-
-2014-03-05  Ryosuke Niwa  <rniwa@webkit.org>
-
-        FTL build fix attempt after r165141.
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-
-2014-03-05  Gavin Barraclough  <barraclough@apple.com>
-
-        https://bugs.webkit.org/show_bug.cgi?id=128625
-        Add fast mapping from StringImpl to JSString
-
-        Unreviewed roll-out.
-
-        Reverting r164347, r165054, r165066 - not clear the performance tradeoff was right.
-
-        * runtime/JSString.cpp:
-        * runtime/JSString.h:
-        * runtime/VM.cpp:
-        (JSC::VM::createLeaked):
-        * runtime/VM.h:
-
-2014-03-03  Oliver Hunt  <oliver@apple.com>
-
-        Support caching of custom setters
-        https://bugs.webkit.org/show_bug.cgi?id=129519
-
-        Reviewed by Filip Pizlo.
-
-        This patch adds caching of assignment to properties that
-        are backed by C functions. This provides most of the leg
-        work required to start supporting setters, and resolves
-        the remaining regressions from moving DOM properties up
-        the prototype chain.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/PolymorphicPutByIdList.cpp:
-        (JSC::PutByIdAccess::visitWeak):
-        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
-        (JSC::PolymorphicPutByIdList::from):
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::transition):
-        (JSC::PutByIdAccess::replace):
-        (JSC::PutByIdAccess::customSetter):
-        (JSC::PutByIdAccess::isCustom):
-        (JSC::PutByIdAccess::oldStructure):
-        (JSC::PutByIdAccess::chain):
-        (JSC::PutByIdAccess::stubRoutine):
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeForStubInfo):
-        (JSC::PutByIdStatus::computeFor):
-        (JSC::PutByIdStatus::dump):
-        * bytecode/PutByIdStatus.h:
-        (JSC::PutByIdStatus::PutByIdStatus):
-        (JSC::PutByIdStatus::takesSlowPath):
-        (JSC::PutByIdStatus::makesCalls):
-        * bytecode/StructureStubInfo.h:
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::emitPutById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGCommon.h:
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::hasIdentifier):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileIn):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::cachedGetById):
-        (JSC::DFG::SpeculativeJIT::cachedPutById):
-        (JSC::DFG::SpeculativeJIT::compile):
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-        * jit/JITInlineCacheGenerator.cpp:
-        (JSC::JITByIdGenerator::JITByIdGenerator):
-        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
-        * jit/JITInlineCacheGenerator.h:
-        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_put_by_id):
-        * jit/Repatch.cpp:
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::emitCustomSetterStub):
-        (JSC::tryCachePutByID):
-        (JSC::tryBuildPutByIdList):
-        * jit/SpillRegistersMode.h: Added.
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * runtime/Lookup.h:
-        (JSC::putEntry):
-        * runtime/PutPropertySlot.h:
-        (JSC::PutPropertySlot::setCacheableCustomProperty):
-        (JSC::PutPropertySlot::customSetter):
-        (JSC::PutPropertySlot::isCacheablePut):
-        (JSC::PutPropertySlot::isCacheableCustomProperty):
-        (JSC::PutPropertySlot::cachedOffset):
-
-2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        JSCell::m_gcData should encode its information differently
-        https://bugs.webkit.org/show_bug.cgi?id=129741
-
-        Reviewed by Geoffrey Garen.
-
-        We want to keep track of three GC states for an object:
-
-        1. Not marked (which implies not in the remembered set)
-        2. Marked but not in the remembered set
-        3. Marked and in the remembered set
-        
-        Currently we only indicate marked vs. not marked in JSCell::m_gcData. During a write 
-        barrier, we only want to take the slow path if the object being stored to is in state #2. 
-        We'd like to make the test for state #2 as fast as possible, which means making it a 
-        compare against 0.
-
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::osrWriteBarrier):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::checkMarkByte):
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::allocateCell):
-        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
-        * heap/Heap.cpp:
-        (JSC::Heap::clearRememberedSet):
-        (JSC::Heap::addToRememberedSet):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::checkMarkByte):
-        * jit/JIT.h:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::checkMarkByte):
-        (JSC::JIT::emitWriteBarrier):
-        * jit/Repatch.cpp:
-        (JSC::writeBarrier):
-        * llint/LowLevelInterpreter.asm:
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-        * runtime/JSCell.h:
-        (JSC::JSCell::mark):
-        (JSC::JSCell::remember):
-        (JSC::JSCell::forget):
-        (JSC::JSCell::isMarked):
-        (JSC::JSCell::isRemembered):
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::JSCell):
-        * runtime/StructureIDBlob.h:
-        (JSC::StructureIDBlob::StructureIDBlob):
-
-2014-03-05  Filip Pizlo  <fpizlo@apple.com>
-
-        More FTL ARM fixes
-        https://bugs.webkit.org/show_bug.cgi?id=129755
-
-        Reviewed by Geoffrey Garen.
-        
-        - Be more defensive about inline caches that have degenerate chains.
-        
-        - Temporarily switch to allocating all MCJIT memory in the executable pool on non-x86
-          platforms. The bug tracking the real fix is: https://bugs.webkit.org/show_bug.cgi?id=129756
-        
-        - Don't even emit intrinsic declarations on non-x86 platforms.
-        
-        - More debug printing support.
-        
-        - Don't use vmCall() in the prologue. This should have crashed on all platforms all the time
-          but somehow it gets lucky on x86.
-
-        * bytecode/GetByIdStatus.cpp:
-        (JSC::GetByIdStatus::appendVariant):
-        (JSC::GetByIdStatus::computeForChain):
-        (JSC::GetByIdStatus::computeForStubInfo):
-        * bytecode/GetByIdStatus.h:
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::appendVariant):
-        (JSC::PutByIdStatus::computeForStubInfo):
-        * bytecode/PutByIdStatus.h:
-        * bytecode/StructureSet.h:
-        (JSC::StructureSet::overlaps):
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::mmAllocateDataSection):
-        * ftl/FTLDataSection.cpp:
-        (JSC::FTL::DataSection::DataSection):
-        (JSC::FTL::DataSection::~DataSection):
-        * ftl/FTLDataSection.h:
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::lower):
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::doubleSin):
-        (JSC::FTL::Output::doubleCos):
-        * runtime/JSCJSValue.cpp:
-        (JSC::JSValue::dumpInContext):
-        * runtime/JSCell.h:
-        (JSC::JSCell::structureID):
-
-2014-03-05  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win32][LLINT] Crash when running JSC stress tests.
-        https://bugs.webkit.org/show_bug.cgi?id=129429
-
-        On Windows the reserved stack space consists of committed memory, a guard page, and uncommitted memory,
-        where the guard page is a barrier between committed and uncommitted memory.
-        When data from the guard page is read or written, the guard page is moved, and memory is committed.
-        This is how the system grows the stack.
-        When using the C stack on Windows we need to precommit the needed stack space.
-        Otherwise we might crash later if we access uncommitted stack memory.
-        This can happen if we allocate stack space larger than the page guard size (4K).
-        The system does not get the chance to move the guard page, and commit more memory,
-        and we crash if uncommitted memory is accessed.
-        The MSVC compiler fixes this by inserting a call to the _chkstk() function,
-        when needed, see http://support.microsoft.com/kb/100775.
-
-        Reviewed by Geoffrey Garen.
-
-        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Enable LLINT.
-        * jit/Repatch.cpp:
-        (JSC::writeBarrier): Compile fix when DFG_JIT is not enabled.
-        * offlineasm/x86.rb: Compile fix, and small simplification.
-        * runtime/VM.cpp:
-        (JSC::preCommitStackMemory): Added function to precommit stack memory.
-        (JSC::VM::updateStackLimit): Call function to precommit stack memory when stack limit is updated.
-
-2014-03-05  Michael Saboff  <msaboff@apple.com>
-
-        JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
-        https://bugs.webkit.org/show_bug.cgi?id=129746
-
-        Reviewed by Filip Pizlo.
-
-        Changed to use a union to manually assemble or disassemble the various types
-        from / to the corresponding bytes.  All memory access is now done using
-        byte accesses.
-
-        * runtime/JSDataViewPrototype.cpp:
-        (JSC::getData):
-        (JSC::setData):
-
-2014-03-05  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL loadStructure always generates invalid IR
-        https://bugs.webkit.org/show_bug.cgi?id=129747
-
-        Reviewed by Mark Hahnenberg.
-
-        As the comment at the top of FTL::Output states, the FTL doesn't use LLVM's notion
-        of pointers. LLVM's notion of pointers tries to model C, in the sense that you have
-        to have a pointer to a type, and you can only load things of that type from that
-        pointer. Pointer arithmetic is basically not possible except through the bizarre
-        getelementptr operator. This doesn't fit with how the JS object model works since
-        the JS object model doesn't consist of nice and tidy C types placed in C arrays.
-        Also, it would be impossible to use getelementptr and LLVM pointers for accessing
-        any of JSC's C or C++ objects unless we went through the exercise of redeclaring
-        all of our fundamental data structures in LLVM IR as LLVM types. Clang could do
-        this for us, but that would require that to use the FTL, JSC itself would have to
-        be compiled with clang. Worse, it would have to be compiled with a clang that uses
-        a version of LLVM that is compatible with the one against which the FTL is linked.
-        Yuck!
-
-        The solution is to NEVER use LLVM pointers. This has always been the case in the
-        FTL. But it causes some confusion.
-        
-        Not using LLVM pointers means that if the FTL has a "pointer", it's actually a
-        pointer-wide integer (m_out.intPtr in FTL-speak). The act of "loading" and
-        "storing" from or to a pointer involves first bitcasting the intPtr to a real LLVM
-        pointer that has the type that we want. The load and store operations over pointers
-        are called Output::load* and Output::store*, where * is one of "8", "16", "32",
-        "64", "Ptr", "Float", or "Double.
-        
-        There is unavoidable confusion here. It would be bizarre for the FTL to call its
-        "pointer-wide integers" anything other than "pointers", since they are, in all
-        respects that we care about, simply pointers. But they are *not* LLVM pointers and
-        they never will be that.
-        
-        There is one exception to this "no pointers" rule. The FTL does use actual LLVM
-        pointers for refering to LLVM alloca's - i.e. local variables. To try to reduce
-        confusion, we call these "references". So an "FTL reference" is actually an "LLVM
-        pointer", while an "FTL pointer" is actually an "LLVM integer". FTL references have
-        methods for access called Output::get and Output::set. These lower to LLVM load
-        and store, since FTL references are just LLVM pointers.
-        
-        This confusion appears to have led to incorrect code in loadStructure().
-        loadStructure() was using get() and set() to access FTL pointers. But those methods
-        don't work on FTL pointers and never will, since they are for FTL references.
-        
-        The worst part of this is that it was previously impossible to have test coverage
-        for the relevant path (MasqueradesAsUndefined) without writing a DRT test. This
-        patch fixes this by introducing a Masquerader object to jsc.cpp.
-        
-        * ftl/FTLAbstractHeapRepository.h: Add an abstract heap for the structure table.
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::loadStructure): This was wrong.
-        * ftl/FTLOutput.h: Add a comment to disuade people from using get() and set().
-        * jsc.cpp: Give us the power to test for MasqueradesAsUndefined.
-        (WTF::Masquerader::Masquerader):
-        (WTF::Masquerader::create):
-        (WTF::Masquerader::createStructure):
-        (GlobalObject::finishCreation):
-        (functionMakeMasquerader):
-        * tests/stress/equals-masquerader.js: Added.
-        (foo):
-        (test):
-
-2014-03-05  Anders Carlsson  <andersca@apple.com>
-
-        Tweak after r165109 to avoid extra copies
-        https://bugs.webkit.org/show_bug.cgi?id=129745
-
-        Reviewed by Geoffrey Garen.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::visitProtectedObjects):
-        (JSC::Heap::visitTempSortVectors):
-        (JSC::Heap::clearRememberedSet):
-        * heap/Heap.h:
-        (JSC::Heap::forEachProtectedCell):
-
-2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        DFGStoreBarrierElisionPhase should should GCState directly instead of m_gcClobberSet when calling writesOverlap()
-        https://bugs.webkit.org/show_bug.cgi?id=129717
-
-        Reviewed by Filip Pizlo.
-
-        * dfg/DFGStoreBarrierElisionPhase.cpp:
-        (JSC::DFG::StoreBarrierElisionPhase::StoreBarrierElisionPhase):
-        (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC):
-
-2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Use range-based loops where possible in Heap methods
-        https://bugs.webkit.org/show_bug.cgi?id=129513
-
-        Reviewed by Mark Lam.
-
-        Replace old school iterator based loops with the new range-based loop hotness
-        for a better tomorrow.
-
-        * heap/CodeBlockSet.cpp:
-        (JSC::CodeBlockSet::~CodeBlockSet):
-        (JSC::CodeBlockSet::clearMarks):
-        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
-        (JSC::CodeBlockSet::traceMarked):
-        * heap/Heap.cpp:
-        (JSC::Heap::visitProtectedObjects):
-        (JSC::Heap::visitTempSortVectors):
-        (JSC::Heap::clearRememberedSet):
-        * heap/Heap.h:
-        (JSC::Heap::forEachProtectedCell):
-
-2014-03-04  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
-        https://bugs.webkit.org/show_bug.cgi?id=129563
-
-        Reviewed by Geoffrey Garen.
-        
-        Rolling this back in after fixing an assertion failure. speculateMisc() should have
-        said DFG_TYPE_CHECK instead of typeCheck.
-        
-        This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
-        when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
-        user of this was EarleyBoyer, and in that benchmark what it was really doing was
-        comparing undefined, null, and booleans to each other.
-        
-        This also adds support for miscellaneous things that I needed to make my various test
-        cases work. This includes comparison over booleans and the various Throw-related node
-        types.
-        
-        This also improves constant folding of CompareStrictEq and CompareEq.
-        
-        Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
-        based on profiling, which caused some downstream badness. We don't actually support
-        compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
-        emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
-        shouldn't factor out the bounds check since the access is not InBounds but then the
-        backend would ignore the flag and assume that the bounds check was already emitted.
-        This showed up on an existing test but I added a test for this explicitly to have more
-        certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
-        that we'll have a bounds check anyway.
-        
-        This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
-        general progressions across the board. No speed-up yet on EarleyBoyer, since there is
-        still a lot more coverage work to be done there.
-
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationToAbbreviatedString):
-        (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
-        (JSC::valuesCouldBeEqual):
-        * bytecode/SpeculatedType.h:
-        (JSC::isMiscSpeculation):
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGArrayMode.cpp:
-        (JSC::DFG::ArrayMode::refine):
-        * dfg/DFGArrayMode.h:
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::shouldSpeculateMisc):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        (JSC::DFG::SpeculativeJIT::speculateMisc):
-        (JSC::DFG::SpeculativeJIT::speculate):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::compileThrow):
-        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
-        (JSC::FTL::LowerDFGToLLVM::isMisc):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
-        * tests/stress/float32-array-out-of-bounds.js: Added.
-        * tests/stress/weird-equality-folding-cases.js: Added.
-
-2014-03-04  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r165085.
-        http://trac.webkit.org/changeset/165085
-        https://bugs.webkit.org/show_bug.cgi?id=129729
-
-        Broke imported/w3c/html-templates/template-element/template-
-        content.html (Requested by ap on #webkit).
-
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationToAbbreviatedString):
-        * bytecode/SpeculatedType.h:
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGArrayMode.cpp:
-        (JSC::DFG::ArrayMode::refine):
-        * dfg/DFGArrayMode.h:
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::shouldSpeculateBoolean):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        (JSC::DFG::SpeculativeJIT::speculate):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        * dfg/DFGSpeculativeJIT64.cpp:
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        * tests/stress/float32-array-out-of-bounds.js: Removed.
-        * tests/stress/weird-equality-folding-cases.js: Removed.
-
-2014-03-04  Brian Burg  <bburg@apple.com>
-
-        Inspector does not restore breakpoints after a page reload
-        https://bugs.webkit.org/show_bug.cgi?id=129655
-
-        Reviewed by Joseph Pecoraro.
-
-        Fix a regression introduced by r162096 that erroneously removed
-        the inspector backend's mapping of files to breakpoints whenever the
-        global object was cleared.
-
-        The inspector's breakpoint mappings should only be cleared when the
-        debugger agent is disabled or destroyed. We should only clear the
-        debugger's breakpoint state when the global object is cleared.
-
-        To make it clearer what state is being cleared, the two cases have
-        been split into separate methods.
-
-        * inspector/agents/InspectorDebuggerAgent.cpp:
-        (Inspector::InspectorDebuggerAgent::disable):
-        (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
-        (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
-        (Inspector::InspectorDebuggerAgent::didClearGlobalObject):
-        * inspector/agents/InspectorDebuggerAgent.h:
-
-2014-03-04  Andreas Kling  <akling@apple.com>
-
-        Streamline JSValue::get().
-        <https://webkit.org/b/129720>
-
-        Fetch each Structure and VM only once when walking the prototype chain
-        in JSObject::getPropertySlot(), then pass it along to the functions
-        we call from there, so they don't have to re-fetch it.
-
-        Reviewed by Geoff Garen.
-
-        * runtime/JSObject.h:
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-        (JSC::JSObject::fastGetOwnPropertySlot):
-        (JSC::JSObject::getPropertySlot):
-
-2014-03-01  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
-        https://bugs.webkit.org/show_bug.cgi?id=129563
-
-        Reviewed by Geoffrey Garen.
-        
-        This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
-        when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
-        user of this was EarleyBoyer, and in that benchmark what it was really doing was
-        comparing undefined, null, and booleans to each other.
-        
-        This also adds support for miscellaneous things that I needed to make my various test
-        cases work. This includes comparison over booleans and the various Throw-related node
-        types.
-        
-        This also improves constant folding of CompareStrictEq and CompareEq.
-        
-        Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
-        based on profiling, which caused some downstream badness. We don't actually support
-        compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
-        emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
-        shouldn't factor out the bounds check since the access is not InBounds but then the
-        backend would ignore the flag and assume that the bounds check was already emitted.
-        This showed up on an existing test but I added a test for this explicitly to have more
-        certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
-        that we'll have a bounds check anyway.
-        
-        This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
-        general progressions across the board. No speed-up yet on EarleyBoyer, since there is
-        still a lot more coverage work to be done there.
-
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationToAbbreviatedString):
-        (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
-        (JSC::valuesCouldBeEqual):
-        * bytecode/SpeculatedType.h:
-        (JSC::isMiscSpeculation):
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::shouldSpeculateMisc):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::SafeToExecuteEdge::operator()):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::compileStrictEq):
-        (JSC::DFG::SpeculativeJIT::speculateMisc):
-        (JSC::DFG::SpeculativeJIT::speculate):
-        * dfg/DFGSpeculativeJIT.h:
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
-        * dfg/DFGUseKind.cpp:
-        (WTF::printInternal):
-        * dfg/DFGUseKind.h:
-        (JSC::DFG::typeFilterFor):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
-        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
-        (JSC::FTL::LowerDFGToLLVM::compileThrow):
-        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
-        (JSC::FTL::LowerDFGToLLVM::isMisc):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
-        * tests/stress/float32-array-out-of-bounds.js: Added.
-        * tests/stress/weird-equality-folding-cases.js: Added.
-
-2014-03-04  Andreas Kling  <akling@apple.com>
-
-        Spam static branch prediction hints on JS bindings.
-        <https://webkit.org/b/129703>
-
-        Add LIKELY hint to jsDynamicCast since it's always used in a context
-        where we expect it to succeed and takes an error path when it doesn't.
-
-        Reviewed by Geoff Garen.
-
-        * runtime/JSCell.h:
-        (JSC::jsDynamicCast):
-
-2014-03-04  Andreas Kling  <akling@apple.com>
-
-        Get to Structures more efficiently in JSCell::methodTable().
-        <https://webkit.org/b/129702>
-
-        In JSCell::methodTable(), get the VM once and pass that along to
-        structure(VM&) instead of using the heavier structure().
-
-        In JSCell::methodTable(VM&), replace calls to structure() with
-        calls to structure(VM&).
-
-        Reviewed by Mark Hahnenberg.
-
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::methodTable):
-
-2014-03-04  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Listen for the XPC_ERROR_CONNECTION_INVALID event to deref
-        https://bugs.webkit.org/show_bug.cgi?id=129697
-
-        Reviewed by Timothy Hatcher.
-
-        * inspector/remote/RemoteInspectorXPCConnection.mm:
-        (Inspector::RemoteInspectorXPCConnection::RemoteInspectorXPCConnection):
-        (Inspector::RemoteInspectorXPCConnection::handleEvent):
-
-2014-03-04  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Merge API shims and JSLock
-        https://bugs.webkit.org/show_bug.cgi?id=129650
-
-        Reviewed by Mark Lam.
-
-        JSLock is now taking on all of APIEntryShim's responsibilities since there is never a reason 
-        to take just the JSLock. Ditto for DropAllLocks and APICallbackShim.
-
-        * API/APICallbackFunction.h:
-        (JSC::APICallbackFunction::call):
-        (JSC::APICallbackFunction::construct):
-        * API/APIShims.h: Removed.
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        (JSGarbageCollect):
-        (JSReportExtraMemoryCost):
-        (JSSynchronousGarbageCollectForDebugging):
-        * API/JSCallbackConstructor.cpp:
-        * API/JSCallbackFunction.cpp:
-        * API/JSCallbackObjectFunctions.h:
-        (JSC::JSCallbackObject<Parent>::init):
-        (JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
-        (JSC::JSCallbackObject<Parent>::put):
-        (JSC::JSCallbackObject<Parent>::putByIndex):
-        (JSC::JSCallbackObject<Parent>::deleteProperty):
-        (JSC::JSCallbackObject<Parent>::construct):
-        (JSC::JSCallbackObject<Parent>::customHasInstance):
-        (JSC::JSCallbackObject<Parent>::call):
-        (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
-        (JSC::JSCallbackObject<Parent>::getStaticValue):
-        (JSC::JSCallbackObject<Parent>::callbackGetter):
-        * API/JSContext.mm:
-        (-[JSContext setException:]):
-        (-[JSContext wrapperForObjCObject:]):
-        (-[JSContext wrapperForJSObject:]):
-        * API/JSContextRef.cpp:
-        (JSContextGroupRelease):
-        (JSContextGroupSetExecutionTimeLimit):
-        (JSContextGroupClearExecutionTimeLimit):
-        (JSGlobalContextCreateInGroup):
-        (JSGlobalContextRetain):
-        (JSGlobalContextRelease):
-        (JSContextGetGlobalObject):
-        (JSContextGetGlobalContext):
-        (JSGlobalContextCopyName):
-        (JSGlobalContextSetName):
-        * API/JSManagedValue.mm:
-        (-[JSManagedValue value]):
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeConstructor):
-        (JSObjectMakeFunction):
-        (JSObjectMakeArray):
-        (JSObjectMakeDate):
-        (JSObjectMakeError):
-        (JSObjectMakeRegExp):
-        (JSObjectGetPrototype):
-        (JSObjectSetPrototype):
-        (JSObjectHasProperty):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectGetPrivateProperty):
-        (JSObjectSetPrivateProperty):
-        (JSObjectDeletePrivateProperty):
-        (JSObjectIsFunction):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        (JSObjectCopyPropertyNames):
-        (JSPropertyNameArrayRelease):
-        (JSPropertyNameAccumulatorAddName):
-        * API/JSScriptRef.cpp:
-        * API/JSValue.mm:
-        (isDate):
-        (isArray):
-        (containerValueToObject):
-        (valueToArray):
-        (valueToDictionary):
-        (objectToValue):
-        * API/JSValueRef.cpp:
-        (JSValueGetType):
-        (JSValueIsUndefined):
-        (JSValueIsNull):
-        (JSValueIsBoolean):
-        (JSValueIsNumber):
-        (JSValueIsString):
-        (JSValueIsObject):
-        (JSValueIsObjectOfClass):
-        (JSValueIsEqual):
-        (JSValueIsStrictEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueMakeUndefined):
-        (JSValueMakeNull):
-        (JSValueMakeBoolean):
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        (JSValueMakeFromJSONString):
-        (JSValueCreateJSONString):
-        (JSValueToBoolean):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        (JSValueProtect):
-        (JSValueUnprotect):
-        * API/JSVirtualMachine.mm:
-        (-[JSVirtualMachine addManagedReference:withOwner:]):
-        (-[JSVirtualMachine removeManagedReference:withOwner:]):
-        * API/JSWeakObjectMapRefPrivate.cpp:
-        * API/JSWrapperMap.mm:
-        (constructorHasInstance):
-        (makeWrapper):
-        (tryUnwrapObjcObject):
-        * API/ObjCCallbackFunction.mm:
-        (JSC::objCCallbackFunctionCallAsFunction):
-        (JSC::objCCallbackFunctionCallAsConstructor):
-        (objCCallbackFunctionForInvocation):
-        * CMakeLists.txt:
-        * ForwardingHeaders/JavaScriptCore/APIShims.h: Removed.
-        * GNUmakefile.list.am:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGWorklist.cpp:
-        * heap/DelayedReleaseScope.h:
-        (JSC::DelayedReleaseScope::~DelayedReleaseScope):
-        * heap/HeapTimer.cpp:
-        (JSC::HeapTimer::timerDidFire):
-        (JSC::HeapTimer::timerEvent):
-        * heap/IncrementalSweeper.cpp:
-        * inspector/InjectedScriptModule.cpp:
-        (Inspector::InjectedScriptModule::ensureInjected):
-        * jsc.cpp:
-        (jscmain):
-        * runtime/GCActivityCallback.cpp:
-        (JSC::DefaultGCActivityCallback::doWork):
-        * runtime/JSGlobalObjectDebuggable.cpp:
-        (JSC::JSGlobalObjectDebuggable::connect):
-        (JSC::JSGlobalObjectDebuggable::disconnect):
-        (JSC::JSGlobalObjectDebuggable::dispatchMessageFromRemoteFrontend):
-        * runtime/JSLock.cpp:
-        (JSC::JSLock::lock):
-        (JSC::JSLock::didAcquireLock):
-        (JSC::JSLock::unlock):
-        (JSC::JSLock::willReleaseLock):
-        (JSC::JSLock::DropAllLocks::DropAllLocks):
-        (JSC::JSLock::DropAllLocks::~DropAllLocks):
-        * runtime/JSLock.h:
-        * testRegExp.cpp:
-        (realMain):
-
-2014-03-04  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r164812.
-        http://trac.webkit.org/changeset/164812
-        https://bugs.webkit.org/show_bug.cgi?id=129699
-
-        it made things run slower (Requested by pizlo on #webkit).
-
-        * interpreter/Interpreter.cpp:
-        (JSC::Interpreter::execute):
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        * runtime/BatchedTransitionOptimizer.h:
-        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
-        (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
-
-2014-03-02  Filip Pizlo  <fpizlo@apple.com>
-
-        GetMyArgumentByVal in FTL
-        https://bugs.webkit.org/show_bug.cgi?id=128850
-
-        Reviewed by Oliver Hunt.
-        
-        This would have been easy if the OSR exit compiler's arity checks hadn't been wrong.
-        They checked arity by doing "exec->argumentCount == codeBlock->numParameters", which
-        caused it to think that the arity check had failed if the caller had passed more
-        arguments than needed. This would cause the call frame copying to sort of go into
-        reverse (because the amount-by-which-we-failed-arity would have opposite sign,
-        throwing off a bunch of math) and the stack would end up being corrupted.
-        
-        The bug was revealed by two existing tests although as far as I could tell, neither
-        test was intending to cover this case directly. So, I added a new test.
-
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
-        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
-        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated):
-        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub):
-        * ftl/FTLState.h:
-        * tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js: Added.
-        * tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js: Added.
-        * tests/stress/ftl-get-my-argument-by-val-inlined.js: Added.
-        * tests/stress/ftl-get-my-argument-by-val.js: Added.
-
-2014-03-04  Zan Dobersek  <zdobersek@igalia.com>
-
-        [GTK] Build the Udis86 disassembler
-        https://bugs.webkit.org/show_bug.cgi?id=129679
-
-        Reviewed by Michael Saboff.
-
-        * GNUmakefile.am: Generate the Udis86-related derived sources. Distribute the required files.
-        * GNUmakefile.list.am: Add the Udis86 disassembler files to the build.
-
-2014-03-04  Andreas Kling  <akling@apple.com>
-
-        Fix too-narrow assertion I added in r165054.
-
-        It's okay for a 1-character string to come in here. This will happen
-        if the VM small string optimization doesn't apply (ch > 0xFF)
-
-        * runtime/JSString.h:
-        (JSC::jsStringWithWeakOwner):
-
-2014-03-04  Andreas Kling  <akling@apple.com>
-
-        Micro-optimize Strings in JS bindings.
-        <https://webkit.org/b/129673>
-
-        Make jsStringWithWeakOwner() take a StringImpl& instead of a String.
-        This avoids branches in length() and operator[].
-
-        Also call JSString::create() directly instead of jsString() and just
-        assert that the string length is >1. This way we don't duplicate the
-        optimizations for empty and single-character strings.
-
-        Reviewed by Ryosuke Niwa.
-
-        * runtime/JSString.h:
-        (JSC::jsStringWithWeakOwner):
-
-2014-03-04  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
-
-        Implement Number.prototype.clz()
-        https://bugs.webkit.org/show_bug.cgi?id=129479
-
-        Reviewed by Oliver Hunt.
-
-        Implemented Number.prototype.clz() as specified in the ES6 standard.
-
-        * runtime/NumberPrototype.cpp:
-        (JSC::numberProtoFuncClz):
-
-2014-03-03  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Avoid too early deref caused by RemoteInspectorXPCConnection::close
-        https://bugs.webkit.org/show_bug.cgi?id=129631
-
-        Reviewed by Timothy Hatcher.
-
-        Avoid deref() too early if a client calls close(). The xpc_connection_close
-        will cause another XPC_ERROR event to come in from the queue, deref then.
-        Likewise, protect multithreaded access to m_client. If a client calls
-        close() we want to immediately clear the pointer to prevent calls to it.
-
-        Overall the multi-threading aspects of RemoteInspectorXPCConnection are
-        growing too complicated for probably little benefit. We may want to
-        clean this up later.
-
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::xpcConnectionFailed):
-        * inspector/remote/RemoteInspectorXPCConnection.h:
-        * inspector/remote/RemoteInspectorXPCConnection.mm:
-        (Inspector::RemoteInspectorXPCConnection::RemoteInspectorXPCConnection):
-        (Inspector::RemoteInspectorXPCConnection::close):
-        (Inspector::RemoteInspectorXPCConnection::closeOnQueue):
-        (Inspector::RemoteInspectorXPCConnection::deserializeMessage):
-        (Inspector::RemoteInspectorXPCConnection::handleEvent):
-        (Inspector::RemoteInspectorXPCConnection::sendMessage):
-
-2014-03-03  Michael Saboff  <msaboff@apple.com>
-
-        AbstractMacroAssembler::CachedTempRegister should start out invalid
-        https://bugs.webkit.org/show_bug.cgi?id=129657
-
-        Reviewed by Filip Pizlo.
-
-        * assembler/AbstractMacroAssembler.h:
-        (JSC::AbstractMacroAssembler::AbstractMacroAssembler):
-        - Invalidate all cached registers in constructor as we don't know the
-          contents of any register at the entry to the code we are going to
-          generate.
-
-2014-03-03  Andreas Kling  <akling@apple.com>
-
-        StructureOrOffset should be fastmalloced.
-        <https://webkit.org/b/129640>
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/StructureIDTable.h:
-
-2014-03-03  Michael Saboff  <msaboff@apple.com>
-
-        Crash in JIT code while watching a video @ storyboard.tumblr.com
-        https://bugs.webkit.org/show_bug.cgi?id=129635
-
-        Reviewed by Filip Pizlo.
-
-        Clear m_set before we set bits in the TempRegisterSet(const RegisterSet& other)
-        construtor.
-
-        * jit/TempRegisterSet.cpp:
-        (JSC::TempRegisterSet::TempRegisterSet): Clear map before setting it.
-        * jit/TempRegisterSet.h:
-        (JSC::TempRegisterSet::TempRegisterSet): Use new clearAll() helper.
-        (JSC::TempRegisterSet::clearAll): New private helper.
-
-2014-03-03  Benjamin Poulain  <benjamin@webkit.org>
-
-        [x86] Improve code generation of byte test
-        https://bugs.webkit.org/show_bug.cgi?id=129597
-
-        Reviewed by Geoffrey Garen.
-
-        When possible, test the 8 bit register to itself instead of comparing it
-        to a literal.
-
-        * assembler/MacroAssemblerX86Common.h:
-        (JSC::MacroAssemblerX86Common::test32):
-
-2014-03-03  Mark Lam  <mark.lam@apple.com>
-
-        Web Inspector: debugger statements do not break.
-        <https://webkit.org/b/129524>
-
-        Reviewed by Geoff Garen.
-
-        Since we no longer call op_debug hooks unless there is a debugger request
-        made on the CodeBlock, the op_debug for the debugger statement never gets
-        serviced.
-
-        With this fix, we check in the CodeBlock constructor if any debugger
-        statements are present.  If so, we set a m_hasDebuggerStatement flag that
-        causes the CodeBlock to show as having debugger requests.  Hence,
-        breaking at debugger statements is now restored.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::CodeBlock):
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::hasDebuggerRequests):
-        (JSC::CodeBlock::clearDebuggerRequests):
-
-2014-03-03  Mark Lam  <mark.lam@apple.com>
-
-        ASSERTION FAILED: m_numBreakpoints >= numBreakpoints when deleting breakpoints.
-        <https://webkit.org/b/129393>
-
-        Reviewed by Geoffrey Garen.
-
-        The issue manifests because the debugger will iterate all CodeBlocks in
-        the heap when setting / clearing breakpoints, but it is possible for a
-        CodeBlock to have been instantiate but is not yet registered with the
-        debugger.  This can happen because of the following:
-
-        1. DFG worklist compilation is still in progress, and the target
-           codeBlock is not ready for installation in its executable yet.
-
-        2. DFG compilation failed and we have a codeBlock that will never be
-           installed in its executable, and the codeBlock has not been cleaned
-           up by the GC yet.
-
-        The code for installing the codeBlock in its executable is the same code
-        that registers it with the debugger.  Hence, these codeBlocks are not
-        registered with the debugger, and any pending breakpoints that would map
-        to that CodeBlock is as yet unset or will never be set.  As such, an
-        attempt to remove a breakpoint in that CodeBlock will fail that assertion.
-
-        To fix this, we do the following:
-
-        1. We'll eagerly clean up any zombie CodeBlocks due to failed DFG / FTL
-           compilation.  This is achieved by providing a
-           DeferredCompilationCallback::compilationDidComplete() that does this
-           clean up, and have all sub classes call it at the end of their
-           compilationDidComplete() methods.
-
-        2. Before the debugger or profiler iterates CodeBlocks in the heap, they
-           will wait for all compilations to complete before proceeding.  This
-           ensures that:
-           1. any zombie CodeBlocks would have been cleaned up, and won't be
-              seen by the debugger or profiler.
-           2. all CodeBlocks that the debugger and profiler needs to operate on
-              will be "ready" for whatever needs to be done to them e.g.
-              jettison'ing of DFG codeBlocks.
-
-        * bytecode/DeferredCompilationCallback.cpp:
-        (JSC::DeferredCompilationCallback::compilationDidComplete):
-        * bytecode/DeferredCompilationCallback.h:
-        - Provide default implementation method to clean up zombie CodeBlocks.
-
-        * debugger/Debugger.cpp:
-        (JSC::Debugger::forEachCodeBlock):
-        - Utility function to iterate CodeBlocks.  It ensures that all compilations
-          are complete before proceeding.
-        (JSC::Debugger::setSteppingMode):
-        (JSC::Debugger::toggleBreakpoint):
-        (JSC::Debugger::recompileAllJSFunctions):
-        (JSC::Debugger::clearBreakpoints):
-        (JSC::Debugger::clearDebuggerRequests):
-        - Use the utility iterator function.
-
-        * debugger/Debugger.h:
-        * dfg/DFGOperations.cpp:
-        - Added an assert to ensure that zombie CodeBlocks will be imminently cleaned up.
-
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
-        - Remove unneeded code (that was not the best solution anyway) for ensuring
-          that we don't generate new DFG codeBlocks after enabling the debugger or
-          profiler.  Now that we wait for compilations to complete before proceeding
-          with debugger and profiler work, this scenario will never happen.
-
-        * dfg/DFGToFTLDeferredCompilationCallback.cpp:
-        (JSC::DFG::ToFTLDeferredCompilationCallback::compilationDidComplete):
-        - Call the super class method to clean up zombie codeBlocks.
-
-        * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp:
-        (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete):
-        - Call the super class method to clean up zombie codeBlocks.
-
-        * heap/CodeBlockSet.cpp:
-        (JSC::CodeBlockSet::remove):
-        * heap/CodeBlockSet.h:
-        * heap/Heap.h:
-        (JSC::Heap::removeCodeBlock):
-        - New method to remove a codeBlock from the codeBlock set.
-
-        * jit/JITOperations.cpp:
-        - Added an assert to ensure that zombie CodeBlocks will be imminently cleaned up.
-
-        * jit/JITToDFGDeferredCompilationCallback.cpp:
-        (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete):
-        - Call the super class method to clean up zombie codeBlocks.
-
-        * runtime/VM.cpp:
-        (JSC::VM::waitForCompilationsToComplete):
-        - Renamed from prepareToDiscardCode() to be clearer about what it does.
-
-        (JSC::VM::discardAllCode):
-        (JSC::VM::releaseExecutableMemory):
-        (JSC::VM::setEnabledProfiler):
-        - Wait for compilation to complete before enabling the profiler.
-
-        * runtime/VM.h:
-
-2014-03-03  Brian Burg  <bburg@apple.com>
-
-        Another unreviewed build fix attempt for Windows after r164986.
-
-        We never told Visual Studio to copy over the web replay code generator scripts
-        and the generated headers for JavaScriptCore replay inputs as if they were
-        private headers.
-
-        * JavaScriptCore.vcxproj/copy-files.cmd:
-
-2014-03-03  Brian Burg  <bburg@apple.com>
-
-        Web Replay: upstream input storage, capture/replay machinery, and inspector domain
-        https://bugs.webkit.org/show_bug.cgi?id=128782
-
-        Reviewed by Timothy Hatcher.
-
-        Alter the replay inputs code generator so that it knows when it is necessary to
-        to include headers for HEAVY_SCALAR types such as WTF::String and WebCore::URL.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * replay/scripts/CodeGeneratorReplayInputs.py:
-        (Framework.fromString):
-        (Frameworks): Add WTF as an allowed framework for code generation.
-        (Generator.generate_includes): Include headers for HEAVY_SCALAR types in the header file.
-        (Generator.generate_includes.declaration):
-        (Generator.generate_includes.or):
-        (Generator.generate_type_forward_declarations): Skip HEAVY_SCALAR types.
-
-2014-03-02  Filip Pizlo  <fpizlo@apple.com>
-
-        PolymorphicPutByIdList should have a simpler construction API with basically a single entrypoint
-        https://bugs.webkit.org/show_bug.cgi?id=129591
-
-        Reviewed by Michael Saboff.
-
-        * bytecode/PolymorphicPutByIdList.cpp:
-        (JSC::PutByIdAccess::fromStructureStubInfo): This function can figure out the slow path target for itself.
-        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList): This constuctor should be private, only from() should call it.
-        (JSC::PolymorphicPutByIdList::from):
-        * bytecode/PolymorphicPutByIdList.h:
-        (JSC::PutByIdAccess::stubRoutine):
-        * jit/Repatch.cpp:
-        (JSC::tryBuildPutByIdList): Don't pass the slow path target since it can be derived from the stubInfo.
-
-2014-03-02  Filip Pizlo  <fpizlo@apple.com>
-
-        Debugging improvements from my gbemu investigation session
-        https://bugs.webkit.org/show_bug.cgi?id=129599
-
-        Reviewed by Mark Lam.
-        
-        Various improvements from when I was investigating bug 129411.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::optimizationThresholdScalingFactor): Make the dataLog() statement print the actual multiplier.
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionDescribe): Make describe() return a string rather than printing the string.
-        (functionDescribeArray): Like describe(), but prints details about arrays.
-
-2014-02-25  Andreas Kling  <akling@apple.com>
-
-        JSDOMWindow::commonVM() should return a reference.
-        <https://webkit.org/b/129293>
-
-        Added a DropAllLocks constructor that takes VM& without null checks.
-
-        Reviewed by Geoff Garen.
-
-2014-03-02  Mark Lam  <mark.lam@apple.com>
-
-        CodeBlock::hasDebuggerRequests() should returning a bool instead of an int.
-        <https://webkit.org/b/129584>
-
-        Reviewed by Darin Adler.
-
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::hasDebuggerRequests):
-
-2014-03-02  Mark Lam  <mark.lam@apple.com>
-
-        Clean up use of Options::enableConcurrentJIT().
-        <https://webkit.org/b/129582>
-
-        Reviewed by Filip Pizlo.
-
-        DFG Driver was conditionally checking Options::enableConcurrentJIT()
-        only if ENABLE(CONCURRENT_JIT).  Otherwise, it bypasses it with a local
-        enableConcurrentJIT set to false.
-
-        Instead we should configure Options::enableConcurrentJIT() to be false
-        in Options.cpp if !ENABLE(CONCURRENT_JIT), and DFG Driver should always
-        check Options::enableConcurrentJIT().  This makes the code read a little
-        cleaner.
-
-        * dfg/DFGDriver.cpp:
-        (JSC::DFG::compileImpl):
-        * runtime/Options.cpp:
-        (JSC::recomputeDependentOptions):
-
-2014-03-01  Filip Pizlo  <fpizlo@apple.com>
-
-        This shouldn't have been a layout test since it runs only under jsc. Moving it to JSC
-        stress tests.
-
-        * tests/stress/generational-opaque-roots.js: Copied from LayoutTests/js/script-tests/generational-opaque-roots.js.
-
-2014-03-01  Andreas Kling  <akling@apple.com>
-
-        JSCell::fastGetOwnProperty() should get the Structure more efficiently.
-        <https://webkit.org/b/129560>
-
-        Now that structure() is nontrivial and we have a faster structure(VM&),
-        make use of that in fastGetOwnProperty() since we already have VM.
-
-        Reviewed by Sam Weinig.
-
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::fastGetOwnProperty):
-
-2014-03-01  Andreas Kling  <akling@apple.com>
-
-        Avoid going through ExecState for VM when we already have it (in some places.)
-        <https://webkit.org/b/129554>
-
-        Tweak some places that jump through unnecessary hoops to get the VM.
-        There are many more like this.
-
-        Reviewed by Sam Weinig.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::putByIndexBeyondVectorLength):
-        (JSC::JSObject::putDirectIndexBeyondVectorLength):
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncToString):
-
-2014-02-28  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should support PhantomArguments
-        https://bugs.webkit.org/show_bug.cgi?id=113986
-
-        Reviewed by Oliver Hunt.
-        
-        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
-        object into the FTL's OSR exit compiler.
-        
-        This isn't a speed-up yet, since there is still more to be done to fully support
-        all of the arguments craziness that our varargs benchmarks do.
-
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
-        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
-        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
-        * dfg/DFGOSRExitCompilerCommon.h:
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLExitValue.cpp:
-        (JSC::FTL::ExitValue::dumpInContext):
-        * ftl/FTLExitValue.h:
-        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
-        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
-        (JSC::FTL::ExitValue::valueFormat):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
-        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
-        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
-        * tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js: Added.
-        * tests/stress/trivially-foldable-reflective-arguments-access.js: Added.
-
-2014-02-28  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, uncomment some code. It wasn't meant to be commented in the first place.
-
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
-
-2014-02-28  Andreas Kling  <akling@apple.com>
-
-        JSObject::findPropertyHashEntry() should take VM instead of ExecState.
-        <https://webkit.org/b/129529>
-
-        Callers already have VM in a local, and findPropertyHashEntry() only
-        uses the VM, no need to go all the way through ExecState.
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::put):
-        (JSC::JSObject::deleteProperty):
-        (JSC::JSObject::findPropertyHashEntry):
-        * runtime/JSObject.h:
-
-2014-02-28  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Deadlock remotely inspecting iOS Simulator
-        https://bugs.webkit.org/show_bug.cgi?id=129511
-
-        Reviewed by Timothy Hatcher.
-
-        Avoid synchronous setup. Do it asynchronously, and let
-        the RemoteInspector singleton know later if it failed.
-
-        * inspector/remote/RemoteInspector.h:
-        * inspector/remote/RemoteInspector.mm:
-        (Inspector::RemoteInspector::setupFailed):
-        * inspector/remote/RemoteInspectorDebuggableConnection.h:
-        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
-        (Inspector::RemoteInspectorDebuggableConnection::setup):
-
-2014-02-28  Oliver Hunt  <oliver@apple.com>
-
-        REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
-        https://bugs.webkit.org/show_bug.cgi?id=129488
-
-        Reviewed by Mark Lam.
-
-        Whoops, modify the right register.
-
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileLoadVarargs):
-
-2014-02-28  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should be able to call sin/cos directly on platforms where the intrinsic is busted
-        https://bugs.webkit.org/show_bug.cgi?id=129503
-
-        Reviewed by Mark Lam.
-
-        * ftl/FTLIntrinsicRepository.h:
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::doubleSin):
-        (JSC::FTL::Output::doubleCos):
-        (JSC::FTL::Output::intrinsicOrOperation):
-
-2014-02-28  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Fix !ENABLE(GGC) builds
-
-        * heap/Heap.cpp:
-        (JSC::Heap::markRoots):
-        (JSC::Heap::gatherJSStackRoots): Also fix one of the names of the GC phases.
-
-2014-02-27  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Clean up Heap::collect and Heap::markRoots
-        https://bugs.webkit.org/show_bug.cgi?id=129464
-
-        Reviewed by Geoffrey Garen.
-
-        These functions have built up a lot of cruft recently. 
-        We should do a bit of cleanup to make them easier to grok.
-
-        * heap/Heap.cpp:
-        (JSC::Heap::finalizeUnconditionalFinalizers):
-        (JSC::Heap::gatherStackRoots):
-        (JSC::Heap::gatherJSStackRoots):
-        (JSC::Heap::gatherScratchBufferRoots):
-        (JSC::Heap::clearLivenessData):
-        (JSC::Heap::visitSmallStrings):
-        (JSC::Heap::visitConservativeRoots):
-        (JSC::Heap::visitCompilerWorklists):
-        (JSC::Heap::markProtectedObjects):
-        (JSC::Heap::markTempSortVectors):
-        (JSC::Heap::markArgumentBuffers):
-        (JSC::Heap::visitException):
-        (JSC::Heap::visitStrongHandles):
-        (JSC::Heap::visitHandleStack):
-        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
-        (JSC::Heap::converge):
-        (JSC::Heap::visitWeakHandles):
-        (JSC::Heap::clearRememberedSet):
-        (JSC::Heap::updateObjectCounts):
-        (JSC::Heap::resetVisitors):
-        (JSC::Heap::markRoots):
-        (JSC::Heap::copyBackingStores):
-        (JSC::Heap::deleteUnmarkedCompiledCode):
-        (JSC::Heap::collect):
-        (JSC::Heap::collectIfNecessaryOrDefer):
-        (JSC::Heap::suspendCompilerThreads):
-        (JSC::Heap::willStartCollection):
-        (JSC::Heap::deleteOldCode):
-        (JSC::Heap::flushOldStructureIDTables):
-        (JSC::Heap::flushWriteBarrierBuffer):
-        (JSC::Heap::stopAllocation):
-        (JSC::Heap::reapWeakHandles):
-        (JSC::Heap::sweepArrayBuffers):
-        (JSC::Heap::snapshotMarkedSpace):
-        (JSC::Heap::deleteSourceProviderCaches):
-        (JSC::Heap::notifyIncrementalSweeper):
-        (JSC::Heap::rememberCurrentlyExecutingCodeBlocks):
-        (JSC::Heap::resetAllocators):
-        (JSC::Heap::updateAllocationLimits):
-        (JSC::Heap::didFinishCollection):
-        (JSC::Heap::resumeCompilerThreads):
-        * heap/Heap.h:
-
-2014-02-27  Ryosuke Niwa  <rniwa@webkit.org>
-
-        indexOf and lastIndexOf shouldn't resolve ropes when needle is longer than haystack
-        https://bugs.webkit.org/show_bug.cgi?id=129466
-
-        Reviewed by Michael Saboff.
-
-        Refactored the code to avoid calling JSString::value when needle is longer than haystack.
-
-        * runtime/StringPrototype.cpp:
-        (JSC::stringProtoFuncIndexOf):
-        (JSC::stringProtoFuncLastIndexOf):
-
-2014-02-27  Timothy Hatcher  <timothy@apple.com>
-
-        Improve how ContentSearchUtilities::lineEndings works by supporting the three common line endings.
-
-        https://bugs.webkit.org/show_bug.cgi?id=129458
-
-        Reviewed by Joseph Pecoraro.
-
-        * inspector/ContentSearchUtilities.cpp:
-        (Inspector::ContentSearchUtilities::textPositionFromOffset): Remove assumption about line ending length.
-        (Inspector::ContentSearchUtilities::getRegularExpressionMatchesByLines): Remove assumption about
-        line ending type and don't try to strip the line ending. Use size_t
-        (Inspector::ContentSearchUtilities::lineEndings): Use findNextLineStart to find the lines.
-        This will include the line ending in the lines, but that is okay.
-        (Inspector::ContentSearchUtilities::buildObjectForSearchMatch): Use size_t.
-        (Inspector::ContentSearchUtilities::searchInTextByLines): Modernize.
-
-2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
-
-        [Mac] Warning: Multiple build commands for output file GCSegmentedArray and InspectorAgent
-        https://bugs.webkit.org/show_bug.cgi?id=129446
-
-        Reviewed by Timothy Hatcher.
-
-        Remove duplicate header entries in Copy Header build phase.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2014-02-27  Oliver Hunt  <oliver@apple.com>
-
-        Whoops, include all of last patch.
-
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileLoadVarargs):
-
-2014-02-27  Oliver Hunt  <oliver@apple.com>
-
-        Slow cases for function.apply and function.call should not require vm re-entry
-        https://bugs.webkit.org/show_bug.cgi?id=129454
-
-        Reviewed by Geoffrey Garen.
-
-        Implement call and apply using builtins. Happily the use
-        of @call and @apply don't perform function equality checks
-        and just plant direct var_args calls. This did expose a few
-        codegen issues, but they're all covered by existing tests
-        once call and apply are implemented in JS.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * builtins/Function.prototype.js: Added.
-        (call):
-        (apply):
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::CallFunctionCallDotNode::emitBytecode):
-        (JSC::ApplyFunctionCallDotNode::emitBytecode):
-        * dfg/DFGCapabilities.cpp:
-        (JSC::DFG::capabilityLevel):
-        * interpreter/Interpreter.cpp:
-        (JSC::sizeFrameForVarargs):
-        (JSC::loadVarargs):
-        * interpreter/Interpreter.h:
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileLoadVarargs):
-        * parser/ASTBuilder.h:
-        (JSC::ASTBuilder::makeFunctionCallNode):
-        * parser/Lexer.cpp:
-        (JSC::isSafeBuiltinIdentifier):
-        * runtime/CommonIdentifiers.h:
-        * runtime/FunctionPrototype.cpp:
-        (JSC::FunctionPrototype::addFunctionProperties):
-        * runtime/JSObject.cpp:
-        (JSC::JSObject::putDirectBuiltinFunction):
-        (JSC::JSObject::putDirectBuiltinFunctionWithoutTransition):
-        * runtime/JSObject.h:
-
-2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: Better name for RemoteInspectorDebuggableConnection dispatch queue
-        https://bugs.webkit.org/show_bug.cgi?id=129443
-
-        Reviewed by Timothy Hatcher.
-
-        This queue is specific to the JSContext debuggable connections,
-        there is no XPC involved. Give it a better name.
-
-        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
-        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
-
-2014-02-27  David Kilzer  <ddkilzer@apple.com>
-
-        Remove jsc symlink if it already exists
-
-        This is a follow-up fix for:
-
-        Create symlink to /usr/local/bin/jsc during installation
-        <http://webkit.org/b/129399>
-        <rdar://problem/16168734>
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        (Create /usr/local/bin/jsc symlink): If a jsc symlink already
-        exists where we're about to create the symlink, remove the old
-        one first.
-
-2014-02-27  Michael Saboff  <msaboff@apple.com>
-
-        Unreviewed build fix for Mac tools after r164814
-
-        * Configurations/ToolExecutable.xcconfig:
-        - Added JavaScriptCore.framework/PrivateHeaders to ToolExecutable include path.
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        - Changed productName to testRegExp for testRegExp target.
-
-2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: JSContext inspection should report exceptions in the console
-        https://bugs.webkit.org/show_bug.cgi?id=128776
-
-        Reviewed by Timothy Hatcher.
-
-        When JavaScript API functions have an exception, let the inspector
-        know so it can log the JavaScript and Native backtrace that caused
-        the exception.
-
-        Include some clean up of ConsoleMessage and ScriptCallStack construction.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectMakeArray):
-        (JSObjectMakeDate):
-        (JSObjectMakeError):
-        (JSObjectMakeRegExp):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * API/JSValue.mm:
-        (reportExceptionToInspector):
-        (valueToArray):
-        (valueToDictionary):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueCreateJSONString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        When seeing an exception, let the inspector know there was an exception.
-
-        * inspector/JSGlobalObjectInspectorController.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-        Log API exceptions by also grabbing the native backtrace.
-
-        * inspector/ScriptCallStack.h:
-        * inspector/ScriptCallStack.cpp:
-        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
-        (Inspector::ScriptCallStack::append):
-        Minor extensions to ScriptCallStack to make it easier to work with.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        Provide better default information if the first call frame was native.
-
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::extractSourceInformationFromException):
-        (Inspector::createScriptCallStackFromException):
-        Perform the handling here of inserting a fake call frame for exceptions
-        if there was no call stack (e.g. a SyntaxError) or if the first call
-        frame had no information.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        * inspector/ConsoleMessage.h:
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::createScriptCallStackForConsole):
-        * inspector/ScriptCallStackFactory.h:
-        * inspector/agents/InspectorConsoleAgent.cpp:
-        (Inspector::InspectorConsoleAgent::enable):
-        (Inspector::InspectorConsoleAgent::addMessageToConsole):
-        (Inspector::InspectorConsoleAgent::count):
-        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
-        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
-        ConsoleMessage cleanup.
-
-2014-02-27  David Kilzer  <ddkilzer@apple.com>
-
-        Create symlink to /usr/local/bin/jsc during installation
-        <http://webkit.org/b/129399>
-        <rdar://problem/16168734>
-
-        Reviewed by Dan Bernstein.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        - Add "Create /usr/local/bin/jsc symlink" build phase script to
-          create the symlink during installation.
-
-2014-02-27  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
-
-        Math.{max, min}() must not return after first NaN value
-        https://bugs.webkit.org/show_bug.cgi?id=104147
-
-        Reviewed by Oliver Hunt.
-
-        According to the spec, ToNumber going to be called on each argument
-        even if a `NaN` value was already found
-
-        * runtime/MathObject.cpp:
-        (JSC::mathProtoFuncMax):
-        (JSC::mathProtoFuncMin):
-
-2014-02-27  Gergo Balogh  <gbalogh.u-szeged@partner.samsung.com>
-
-        JSType upper limit (0xff) assertion can be removed.
-        https://bugs.webkit.org/show_bug.cgi?id=129424
-
-        Reviewed by Geoffrey Garen.
-
-        * runtime/JSTypeInfo.h:
-        (JSC::TypeInfo::TypeInfo):
-
-2014-02-26  Michael Saboff  <msaboff@apple.com>
-
-        Auto generate bytecode information for bytecode parser and LLInt
-        https://bugs.webkit.org/show_bug.cgi?id=129181
-
-        Reviewed by Mark Lam.
-
-        Added new bytecode/BytecodeList.json that contains a list of bytecodes and related
-        helpers.  It also includes bytecode length and other information used to generate files.
-        Added a new generator, generate-bytecode-files that generates Bytecodes.h and InitBytecodes.asm
-        in DerivedSources/JavaScriptCore/.
-
-        Added the generation of these files to the "DerivedSource" build step.
-        Slighty changed the build order, since the Bytecodes.h file is needed by
-        JSCLLIntOffsetsExtractor.  Moved the offline assembly to a separate step since it needs
-        to be run after JSCLLIntOffsetsExtractor.
-
-        Made related changes to OPCODE macros and their use.
-
-        Added JavaScriptCore.framework/PrivateHeaders to header file search path for building
-        jsc to resolve Mac build issue.
-
-        * CMakeLists.txt:
-        * Configurations/JSC.xcconfig:
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.vcxproj/copy-files.cmd:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/Opcode.h:
-        (JSC::padOpcodeName):
-        * llint/LLIntCLoop.cpp:
-        (JSC::LLInt::CLoop::initialize):
-        * llint/LLIntCLoop.h:
-        * llint/LLIntData.cpp:
-        (JSC::LLInt::initialize):
-        * llint/LLIntOpcode.h:
-        * llint/LowLevelInterpreter.asm:
-
-2014-02-27  Julien Brianceau   <jbriance@cisco.com>
-
-        Fix 32-bit V_JITOperation_EJ callOperation introduced in r162652.
-        https://bugs.webkit.org/show_bug.cgi?id=129420
-
-        Reviewed by Geoffrey Garen.
-
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::callOperation): Payload and tag are swapped.
-        Also, EABI_32BIT_DUMMY_ARG is missing for arm EABI and mips.
-
-2014-02-27  Filip Pizlo  <fpizlo@apple.com>
-
-        Octane/closure thrashes between flattening dictionaries during global object initialization in a global eval
-        https://bugs.webkit.org/show_bug.cgi?id=129435
-
-        Reviewed by Oliver Hunt.
-        
-        This is a 5-10% speed-up on Octane/closure.
-
-        * interpreter/Interpreter.cpp:
-        (JSC::Interpreter::execute):
-        * jsc.cpp:
-        (GlobalObject::finishCreation):
-        (functionClearCodeCache):
-        * runtime/BatchedTransitionOptimizer.h:
-        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
-        (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
-
-2014-02-27  Alexey Proskuryakov  <ap@apple.com>
-
-        Added svn:ignore to two directories, so that .pyc files don't show up as unversioned.
-
-        * inspector/scripts: Added property svn:ignore.
-        * replay/scripts: Added property svn:ignore.
-
-2014-02-27  Gabor Rapcsanyi  <rgabor@webkit.org>
-
-        r164764 broke the ARM build
-        https://bugs.webkit.org/show_bug.cgi?id=129415
-
-        Reviewed by Zoltan Herczeg.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::moveWithPatch): Change reinterpret_cast to static_cast.
-        (JSC::MacroAssemblerARM::canJumpReplacePatchableBranch32WithPatch): Add missing function.
-        (JSC::MacroAssemblerARM::startOfPatchableBranch32WithPatchOnAddress): Add missing function.
-        (JSC::MacroAssemblerARM::revertJumpReplacementToPatchableBranch32WithPatch): Add missing function.
-
-2014-02-27  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        r164764 broke the ARM build
-        https://bugs.webkit.org/show_bug.cgi?id=129415
-
-        Reviewed by Geoffrey Garen.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::moveWithPatch):
-
-2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        r164764 broke the ARM build
-        https://bugs.webkit.org/show_bug.cgi?id=129415
-
-        Reviewed by Geoffrey Garen.
-
-        * assembler/MacroAssemblerARM.h:
-        (JSC::MacroAssemblerARM::branch32WithPatch): Missing this function.
-
-2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        EFL build fix
-
-        * dfg/DFGSpeculativeJIT32_64.cpp: Remove unused variables.
-        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
-
-2014-02-25  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Make JSCells have 32-bit Structure pointers
-        https://bugs.webkit.org/show_bug.cgi?id=123195
-
-        Reviewed by Filip Pizlo.
-
-        This patch changes JSCells such that they no longer have a full 64-bit Structure
-        pointer in their header. Instead they now have a 32-bit index into
-        a per-VM table of Structure pointers. 32-bit platforms still use normal Structure
-        pointers.
-
-        This change frees up an additional 32 bits of information in our object headers.
-        We then use this extra space to store the indexing type of the object, the JSType
-        of the object, some various type flags, and garbage collection data (e.g. mark bit).
-        Because this inline type information is now faster to read, it pays for the slowdown 
-        incurred by having to perform an extra indirection through the StructureIDTable.
-
-        This patch also threads a reference to the current VM through more of the C++ runtime
-        to offset the cost of having to look up the VM to get the actual Structure pointer.
-
-        * API/JSContext.mm:
-        (-[JSContext setException:]):
-        (-[JSContext wrapperForObjCObject:]):
-        (-[JSContext wrapperForJSObject:]):
-        * API/JSContextRef.cpp:
-        (JSContextGroupRelease):
-        (JSGlobalContextRelease):
-        * API/JSObjectRef.cpp:
-        (JSObjectIsFunction):
-        (JSObjectCopyPropertyNames):
-        * API/JSValue.mm:
-        (containerValueToObject):
-        * API/JSWrapperMap.mm:
-        (tryUnwrapObjcObject):
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * assembler/AbstractMacroAssembler.h:
-        * assembler/MacroAssembler.h:
-        (JSC::MacroAssembler::patchableBranch32WithPatch):
-        (JSC::MacroAssembler::patchableBranch32):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::branchPtrWithPatch):
-        (JSC::MacroAssemblerARM64::patchableBranch32WithPatch):
-        (JSC::MacroAssemblerARM64::canJumpReplacePatchableBranch32WithPatch):
-        (JSC::MacroAssemblerARM64::startOfPatchableBranch32WithPatchOnAddress):
-        (JSC::MacroAssemblerARM64::revertJumpReplacementToPatchableBranch32WithPatch):
-        * assembler/MacroAssemblerARMv7.h:
-        (JSC::MacroAssemblerARMv7::store8):
-        (JSC::MacroAssemblerARMv7::branch32WithPatch):
-        (JSC::MacroAssemblerARMv7::patchableBranch32WithPatch):
-        (JSC::MacroAssemblerARMv7::canJumpReplacePatchableBranch32WithPatch):
-        (JSC::MacroAssemblerARMv7::startOfPatchableBranch32WithPatchOnAddress):
-        (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranch32WithPatch):
-        * assembler/MacroAssemblerX86.h:
-        (JSC::MacroAssemblerX86::branch32WithPatch):
-        (JSC::MacroAssemblerX86::canJumpReplacePatchableBranch32WithPatch):
-        (JSC::MacroAssemblerX86::startOfPatchableBranch32WithPatchOnAddress):
-        (JSC::MacroAssemblerX86::revertJumpReplacementToPatchableBranch32WithPatch):
-        * assembler/MacroAssemblerX86_64.h:
-        (JSC::MacroAssemblerX86_64::store32):
-        (JSC::MacroAssemblerX86_64::moveWithPatch):
-        (JSC::MacroAssemblerX86_64::branch32WithPatch):
-        (JSC::MacroAssemblerX86_64::canJumpReplacePatchableBranch32WithPatch):
-        (JSC::MacroAssemblerX86_64::startOfBranch32WithPatchOnRegister):
-        (JSC::MacroAssemblerX86_64::startOfPatchableBranch32WithPatchOnAddress):
-        (JSC::MacroAssemblerX86_64::revertJumpReplacementToPatchableBranch32WithPatch):
-        * assembler/RepatchBuffer.h:
-        (JSC::RepatchBuffer::startOfPatchableBranch32WithPatchOnAddress):
-        (JSC::RepatchBuffer::revertJumpReplacementToPatchableBranch32WithPatch):
-        * assembler/X86Assembler.h:
-        (JSC::X86Assembler::revertJumpTo_movq_i64r):
-        (JSC::X86Assembler::revertJumpTo_movl_i32r):
-        * bytecode/ArrayProfile.cpp:
-        (JSC::ArrayProfile::computeUpdatedPrediction):
-        * bytecode/ArrayProfile.h:
-        (JSC::ArrayProfile::ArrayProfile):
-        (JSC::ArrayProfile::addressOfLastSeenStructureID):
-        (JSC::ArrayProfile::observeStructure):
-        * bytecode/CodeBlock.h:
-        (JSC::CodeBlock::heap):
-        * bytecode/UnlinkedCodeBlock.h:
-        * debugger/Debugger.h:
-        * dfg/DFGAbstractHeap.h:
-        * dfg/DFGArrayifySlowPathGenerator.h:
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGJITCompiler.h:
-        (JSC::DFG::JITCompiler::branchWeakStructure):
-        (JSC::DFG::JITCompiler::branchStructurePtr):
-        * dfg/DFGOSRExitCompiler32_64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOSRExitCompiler64.cpp:
-        (JSC::DFG::OSRExitCompiler::compileExit):
-        * dfg/DFGOSRExitCompilerCommon.cpp:
-        (JSC::DFG::osrWriteBarrier):
-        (JSC::DFG::adjustAndJumpToTarget):
-        * dfg/DFGOperations.cpp:
-        (JSC::DFG::putByVal):
-        * dfg/DFGSpeculativeJIT.cpp:
-        (JSC::DFG::SpeculativeJIT::checkArray):
-        (JSC::DFG::SpeculativeJIT::arrayify):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
-        (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
-        (JSC::DFG::SpeculativeJIT::compileInstanceOf):
-        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
-        (JSC::DFG::SpeculativeJIT::speculateObject):
-        (JSC::DFG::SpeculativeJIT::speculateFinalObject):
-        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
-        (JSC::DFG::SpeculativeJIT::speculateString):
-        (JSC::DFG::SpeculativeJIT::speculateStringObject):
-        (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
-        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
-        (JSC::DFG::SpeculativeJIT::emitSwitchString):
-        (JSC::DFG::SpeculativeJIT::genericWriteBarrier):
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT.h:
-        (JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
-        (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
-        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
-        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
-        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
-        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
-        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
-        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
-        (JSC::DFG::SpeculativeJIT::compile):
-        (JSC::DFG::SpeculativeJIT::writeBarrier):
-        * dfg/DFGWorklist.cpp:
-        * ftl/FTLAbstractHeapRepository.cpp:
-        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
-        * ftl/FTLAbstractHeapRepository.h:
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
-        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
-        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
-        (JSC::FTL::LowerDFGToLLVM::compileToString):
-        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
-        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
-        (JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
-        (JSC::FTL::LowerDFGToLLVM::allocateCell):
-        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
-        (JSC::FTL::LowerDFGToLLVM::isObject):
-        (JSC::FTL::LowerDFGToLLVM::isString):
-        (JSC::FTL::LowerDFGToLLVM::isArrayType):
-        (JSC::FTL::LowerDFGToLLVM::hasClassInfo):
-        (JSC::FTL::LowerDFGToLLVM::isType):
-        (JSC::FTL::LowerDFGToLLVM::speculateStringOrStringObject):
-        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForCell):
-        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
-        (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
-        (JSC::FTL::LowerDFGToLLVM::loadMarkByte):
-        (JSC::FTL::LowerDFGToLLVM::loadStructure):
-        (JSC::FTL::LowerDFGToLLVM::weakStructure):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileStub):
-        * ftl/FTLOutput.h:
-        (JSC::FTL::Output::store8):
-        * heap/GCAssertions.h:
-        * heap/Heap.cpp:
-        (JSC::Heap::getConservativeRegisterRoots):
-        (JSC::Heap::collect):
-        (JSC::Heap::writeBarrier):
-        * heap/Heap.h:
-        (JSC::Heap::structureIDTable):
-        * heap/MarkedSpace.h:
-        (JSC::MarkedSpace::forEachBlock):
-        * heap/SlotVisitorInlines.h:
-        (JSC::SlotVisitor::internalAppend):
-        * jit/AssemblyHelpers.h:
-        (JSC::AssemblyHelpers::branchIfCellNotObject):
-        (JSC::AssemblyHelpers::genericWriteBarrier):
-        (JSC::AssemblyHelpers::emitLoadStructure):
-        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
-        * jit/JIT.h:
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::privateCompileClosureCall):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::emit_op_ret_object_or_this):
-        (JSC::JIT::compileOpCall):
-        (JSC::JIT::privateCompileClosureCall):
-        * jit/JITInlineCacheGenerator.cpp:
-        (JSC::JITByIdGenerator::generateFastPathChecks):
-        * jit/JITInlineCacheGenerator.h:
-        * jit/JITInlines.h:
-        (JSC::JIT::emitLoadCharacterString):
-        (JSC::JIT::checkStructure):
-        (JSC::JIT::emitJumpIfCellNotObject):
-        (JSC::JIT::emitAllocateJSObject):
-        (JSC::JIT::emitArrayProfilingSiteWithCell):
-        (JSC::JIT::emitArrayProfilingSiteForBytecodeIndexWithCell):
-        (JSC::JIT::branchStructure):
-        (JSC::branchStructure):
-        * jit/JITOpcodes.cpp:
-        (JSC::JIT::emit_op_check_has_instance):
-        (JSC::JIT::emit_op_instanceof):
-        (JSC::JIT::emit_op_is_undefined):
-        (JSC::JIT::emit_op_is_string):
-        (JSC::JIT::emit_op_ret_object_or_this):
-        (JSC::JIT::emit_op_to_primitive):
-        (JSC::JIT::emit_op_jeq_null):
-        (JSC::JIT::emit_op_jneq_null):
-        (JSC::JIT::emit_op_get_pnames):
-        (JSC::JIT::emit_op_next_pname):
-        (JSC::JIT::emit_op_eq_null):
-        (JSC::JIT::emit_op_neq_null):
-        (JSC::JIT::emit_op_to_this):
-        (JSC::JIT::emitSlow_op_to_this):
-        * jit/JITOpcodes32_64.cpp:
-        (JSC::JIT::emit_op_check_has_instance):
-        (JSC::JIT::emit_op_instanceof):
-        (JSC::JIT::emit_op_is_undefined):
-        (JSC::JIT::emit_op_is_string):
-        (JSC::JIT::emit_op_to_primitive):
-        (JSC::JIT::emit_op_jeq_null):
-        (JSC::JIT::emit_op_jneq_null):
-        (JSC::JIT::emitSlow_op_eq):
-        (JSC::JIT::emitSlow_op_neq):
-        (JSC::JIT::compileOpStrictEq):
-        (JSC::JIT::emit_op_eq_null):
-        (JSC::JIT::emit_op_neq_null):
-        (JSC::JIT::emit_op_get_pnames):
-        (JSC::JIT::emit_op_next_pname):
-        (JSC::JIT::emit_op_to_this):
-        * jit/JITOperations.cpp:
-        * jit/JITPropertyAccess.cpp:
-        (JSC::JIT::stringGetByValStubGenerator):
-        (JSC::JIT::emit_op_get_by_val):
-        (JSC::JIT::emitSlow_op_get_by_val):
-        (JSC::JIT::emit_op_get_by_pname):
-        (JSC::JIT::emit_op_put_by_val):
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emitLoadWithStructureCheck):
-        (JSC::JIT::emitSlow_op_get_from_scope):
-        (JSC::JIT::emitSlow_op_put_to_scope):
-        (JSC::JIT::checkMarkWord):
-        (JSC::JIT::emitWriteBarrier):
-        (JSC::JIT::addStructureTransitionCheck):
-        (JSC::JIT::emitIntTypedArrayGetByVal):
-        (JSC::JIT::emitFloatTypedArrayGetByVal):
-        (JSC::JIT::emitIntTypedArrayPutByVal):
-        (JSC::JIT::emitFloatTypedArrayPutByVal):
-        * jit/JITPropertyAccess32_64.cpp:
-        (JSC::JIT::stringGetByValStubGenerator):
-        (JSC::JIT::emit_op_get_by_val):
-        (JSC::JIT::emitSlow_op_get_by_val):
-        (JSC::JIT::emit_op_put_by_val):
-        (JSC::JIT::emit_op_get_by_id):
-        (JSC::JIT::emit_op_get_by_pname):
-        (JSC::JIT::emitLoadWithStructureCheck):
-        * jit/JSInterfaceJIT.h:
-        (JSC::JSInterfaceJIT::emitJumpIfNotType):
-        * jit/Repatch.cpp:
-        (JSC::repatchByIdSelfAccess):
-        (JSC::addStructureTransitionCheck):
-        (JSC::replaceWithJump):
-        (JSC::generateProtoChainAccessStub):
-        (JSC::tryCacheGetByID):
-        (JSC::tryBuildGetByIDList):
-        (JSC::writeBarrier):
-        (JSC::emitPutReplaceStub):
-        (JSC::emitPutTransitionStub):
-        (JSC::tryBuildPutByIdList):
-        (JSC::tryRepatchIn):
-        (JSC::linkClosureCall):
-        (JSC::resetGetByID):
-        (JSC::resetPutByID):
-        * jit/SpecializedThunkJIT.h:
-        (JSC::SpecializedThunkJIT::loadJSStringArgument):
-        (JSC::SpecializedThunkJIT::loadArgumentWithSpecificClass):
-        * jit/ThunkGenerators.cpp:
-        (JSC::virtualForThunkGenerator):
-        (JSC::arrayIteratorNextThunkGenerator):
-        * jit/UnusedPointer.h:
-        * llint/LowLevelInterpreter.asm:
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-        * runtime/Arguments.cpp:
-        (JSC::Arguments::createStrictModeCallerIfNecessary):
-        (JSC::Arguments::createStrictModeCalleeIfNecessary):
-        * runtime/Arguments.h:
-        (JSC::Arguments::createStructure):
-        * runtime/ArrayPrototype.cpp:
-        (JSC::shift):
-        (JSC::unshift):
-        (JSC::arrayProtoFuncToString):
-        (JSC::arrayProtoFuncPop):
-        (JSC::arrayProtoFuncReverse):
-        (JSC::performSlowSort):
-        (JSC::arrayProtoFuncSort):
-        (JSC::arrayProtoFuncSplice):
-        (JSC::arrayProtoFuncUnShift):
-        * runtime/CommonSlowPaths.cpp:
-        (JSC::SLOW_PATH_DECL):
-        * runtime/Executable.h:
-        (JSC::ExecutableBase::isFunctionExecutable):
-        (JSC::ExecutableBase::clearCodeVirtual):
-        (JSC::ScriptExecutable::unlinkCalls):
-        * runtime/GetterSetter.cpp:
-        (JSC::callGetter):
-        (JSC::callSetter):
-        * runtime/InitializeThreading.cpp:
-        * runtime/JSArray.cpp:
-        (JSC::JSArray::unshiftCountSlowCase):
-        (JSC::JSArray::setLength):
-        (JSC::JSArray::pop):
-        (JSC::JSArray::push):
-        (JSC::JSArray::shiftCountWithArrayStorage):
-        (JSC::JSArray::shiftCountWithAnyIndexingType):
-        (JSC::JSArray::unshiftCountWithArrayStorage):
-        (JSC::JSArray::unshiftCountWithAnyIndexingType):
-        (JSC::JSArray::sortNumericVector):
-        (JSC::JSArray::sortNumeric):
-        (JSC::JSArray::sortCompactedVector):
-        (JSC::JSArray::sort):
-        (JSC::JSArray::sortVector):
-        (JSC::JSArray::fillArgList):
-        (JSC::JSArray::copyToArguments):
-        (JSC::JSArray::compactForSorting):
-        * runtime/JSCJSValueInlines.h:
-        (JSC::JSValue::toThis):
-        (JSC::JSValue::put):
-        (JSC::JSValue::putByIndex):
-        (JSC::JSValue::equalSlowCaseInline):
-        * runtime/JSCell.cpp:
-        (JSC::JSCell::put):
-        (JSC::JSCell::putByIndex):
-        (JSC::JSCell::deleteProperty):
-        (JSC::JSCell::deletePropertyByIndex):
-        * runtime/JSCell.h:
-        (JSC::JSCell::clearStructure):
-        (JSC::JSCell::mark):
-        (JSC::JSCell::isMarked):
-        (JSC::JSCell::structureIDOffset):
-        (JSC::JSCell::typeInfoFlagsOffset):
-        (JSC::JSCell::typeInfoTypeOffset):
-        (JSC::JSCell::indexingTypeOffset):
-        (JSC::JSCell::gcDataOffset):
-        * runtime/JSCellInlines.h:
-        (JSC::JSCell::JSCell):
-        (JSC::JSCell::finishCreation):
-        (JSC::JSCell::type):
-        (JSC::JSCell::indexingType):
-        (JSC::JSCell::structure):
-        (JSC::JSCell::visitChildren):
-        (JSC::JSCell::isObject):
-        (JSC::JSCell::isString):
-        (JSC::JSCell::isGetterSetter):
-        (JSC::JSCell::isProxy):
-        (JSC::JSCell::isAPIValueWrapper):
-        (JSC::JSCell::setStructure):
-        (JSC::JSCell::methodTable):
-        (JSC::Heap::writeBarrier):
-        * runtime/JSDataView.cpp:
-        (JSC::JSDataView::createStructure):
-        * runtime/JSDestructibleObject.h:
-        (JSC::JSCell::classInfo):
-        * runtime/JSFunction.cpp:
-        (JSC::JSFunction::getOwnNonIndexPropertyNames):
-        (JSC::JSFunction::put):
-        (JSC::JSFunction::defineOwnProperty):
-        * runtime/JSGenericTypedArrayView.h:
-        (JSC::JSGenericTypedArrayView::createStructure):
-        * runtime/JSObject.cpp:
-        (JSC::getCallableObjectSlow):
-        (JSC::JSObject::copyButterfly):
-        (JSC::JSObject::visitButterfly):
-        (JSC::JSFinalObject::visitChildren):
-        (JSC::JSObject::getOwnPropertySlotByIndex):
-        (JSC::JSObject::put):
-        (JSC::JSObject::putByIndex):
-        (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
-        (JSC::JSObject::enterDictionaryIndexingMode):
-        (JSC::JSObject::notifyPresenceOfIndexedAccessors):
-        (JSC::JSObject::createInitialIndexedStorage):
-        (JSC::JSObject::createInitialUndecided):
-        (JSC::JSObject::createInitialInt32):
-        (JSC::JSObject::createInitialDouble):
-        (JSC::JSObject::createInitialContiguous):
-        (JSC::JSObject::createArrayStorage):
-        (JSC::JSObject::convertUndecidedToInt32):
-        (JSC::JSObject::convertUndecidedToDouble):
-        (JSC::JSObject::convertUndecidedToContiguous):
-        (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
-        (JSC::JSObject::convertUndecidedToArrayStorage):
-        (JSC::JSObject::convertInt32ToDouble):
-        (JSC::JSObject::convertInt32ToContiguous):
-        (JSC::JSObject::convertInt32ToArrayStorage):
-        (JSC::JSObject::genericConvertDoubleToContiguous):
-        (JSC::JSObject::convertDoubleToArrayStorage):
-        (JSC::JSObject::convertContiguousToArrayStorage):
-        (JSC::JSObject::ensureInt32Slow):
-        (JSC::JSObject::ensureDoubleSlow):
-        (JSC::JSObject::ensureContiguousSlow):
-        (JSC::JSObject::ensureArrayStorageSlow):
-        (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
-        (JSC::JSObject::switchToSlowPutArrayStorage):
-        (JSC::JSObject::setPrototype):
-        (JSC::JSObject::setPrototypeWithCycleCheck):
-        (JSC::JSObject::putDirectNonIndexAccessor):
-        (JSC::JSObject::deleteProperty):
-        (JSC::JSObject::hasOwnProperty):
-        (JSC::JSObject::deletePropertyByIndex):
-        (JSC::JSObject::getPrimitiveNumber):
-        (JSC::JSObject::hasInstance):
-        (JSC::JSObject::getPropertySpecificValue):
-        (JSC::JSObject::getPropertyNames):
-        (JSC::JSObject::getOwnPropertyNames):
-        (JSC::JSObject::getOwnNonIndexPropertyNames):
-        (JSC::JSObject::seal):
-        (JSC::JSObject::freeze):
-        (JSC::JSObject::preventExtensions):
-        (JSC::JSObject::reifyStaticFunctionsForDelete):
-        (JSC::JSObject::removeDirect):
-        (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
-        (JSC::JSObject::putByIndexBeyondVectorLength):
-        (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
-        (JSC::JSObject::putDirectIndexBeyondVectorLength):
-        (JSC::JSObject::getNewVectorLength):
-        (JSC::JSObject::countElements):
-        (JSC::JSObject::increaseVectorLength):
-        (JSC::JSObject::ensureLengthSlow):
-        (JSC::JSObject::growOutOfLineStorage):
-        (JSC::JSObject::getOwnPropertyDescriptor):
-        (JSC::putDescriptor):
-        (JSC::JSObject::defineOwnNonIndexProperty):
-        * runtime/JSObject.h:
-        (JSC::getJSFunction):
-        (JSC::JSObject::getArrayLength):
-        (JSC::JSObject::getVectorLength):
-        (JSC::JSObject::putByIndexInline):
-        (JSC::JSObject::canGetIndexQuickly):
-        (JSC::JSObject::getIndexQuickly):
-        (JSC::JSObject::tryGetIndexQuickly):
-        (JSC::JSObject::getDirectIndex):
-        (JSC::JSObject::canSetIndexQuickly):
-        (JSC::JSObject::canSetIndexQuicklyForPutDirect):
-        (JSC::JSObject::setIndexQuickly):
-        (JSC::JSObject::initializeIndex):
-        (JSC::JSObject::hasSparseMap):
-        (JSC::JSObject::inSparseIndexingMode):
-        (JSC::JSObject::getDirect):
-        (JSC::JSObject::getDirectOffset):
-        (JSC::JSObject::isSealed):
-        (JSC::JSObject::isFrozen):
-        (JSC::JSObject::flattenDictionaryObject):
-        (JSC::JSObject::ensureInt32):
-        (JSC::JSObject::ensureDouble):
-        (JSC::JSObject::ensureContiguous):
-        (JSC::JSObject::rageEnsureContiguous):
-        (JSC::JSObject::ensureArrayStorage):
-        (JSC::JSObject::arrayStorage):
-        (JSC::JSObject::arrayStorageOrNull):
-        (JSC::JSObject::ensureLength):
-        (JSC::JSObject::currentIndexingData):
-        (JSC::JSObject::getHolyIndexQuickly):
-        (JSC::JSObject::currentRelevantLength):
-        (JSC::JSObject::isGlobalObject):
-        (JSC::JSObject::isVariableObject):
-        (JSC::JSObject::isStaticScopeObject):
-        (JSC::JSObject::isNameScopeObject):
-        (JSC::JSObject::isActivationObject):
-        (JSC::JSObject::isErrorInstance):
-        (JSC::JSObject::inlineGetOwnPropertySlot):
-        (JSC::JSObject::fastGetOwnPropertySlot):
-        (JSC::JSObject::getPropertySlot):
-        (JSC::JSObject::putDirectInternal):
-        (JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
-        * runtime/JSPropertyNameIterator.h:
-        (JSC::JSPropertyNameIterator::createStructure):
-        * runtime/JSProxy.cpp:
-        (JSC::JSProxy::getOwnPropertySlot):
-        (JSC::JSProxy::getOwnPropertySlotByIndex):
-        (JSC::JSProxy::put):
-        (JSC::JSProxy::putByIndex):
-        (JSC::JSProxy::defineOwnProperty):
-        (JSC::JSProxy::deleteProperty):
-        (JSC::JSProxy::deletePropertyByIndex):
-        (JSC::JSProxy::getPropertyNames):
-        (JSC::JSProxy::getOwnPropertyNames):
-        * runtime/JSScope.cpp:
-        (JSC::JSScope::objectAtScope):
-        * runtime/JSString.h:
-        (JSC::JSString::createStructure):
-        (JSC::isJSString):
-        * runtime/JSType.h:
-        * runtime/JSTypeInfo.h:
-        (JSC::TypeInfo::TypeInfo):
-        (JSC::TypeInfo::isObject):
-        (JSC::TypeInfo::structureIsImmortal):
-        (JSC::TypeInfo::zeroedGCDataOffset):
-        (JSC::TypeInfo::inlineTypeFlags):
-        * runtime/MapData.h:
-        * runtime/ObjectConstructor.cpp:
-        (JSC::objectConstructorGetOwnPropertyNames):
-        (JSC::objectConstructorKeys):
-        (JSC::objectConstructorDefineProperty):
-        (JSC::defineProperties):
-        (JSC::objectConstructorSeal):
-        (JSC::objectConstructorFreeze):
-        (JSC::objectConstructorIsSealed):
-        (JSC::objectConstructorIsFrozen):
-        * runtime/ObjectPrototype.cpp:
-        (JSC::objectProtoFuncDefineGetter):
-        (JSC::objectProtoFuncDefineSetter):
-        (JSC::objectProtoFuncToString):
-        * runtime/Operations.cpp:
-        (JSC::jsTypeStringForValue):
-        (JSC::jsIsObjectType):
-        * runtime/Operations.h:
-        (JSC::normalizePrototypeChainForChainAccess):
-        (JSC::normalizePrototypeChain):
-        * runtime/PropertyMapHashTable.h:
-        (JSC::PropertyTable::createStructure):
-        * runtime/RegExp.h:
-        (JSC::RegExp::createStructure):
-        * runtime/SparseArrayValueMap.h:
-        * runtime/Structure.cpp:
-        (JSC::Structure::Structure):
-        (JSC::Structure::~Structure):
-        (JSC::Structure::prototypeChainMayInterceptStoreTo):
-        * runtime/Structure.h:
-        (JSC::Structure::id):
-        (JSC::Structure::idBlob):
-        (JSC::Structure::objectInitializationFields):
-        (JSC::Structure::structureIDOffset):
-        * runtime/StructureChain.h:
-        (JSC::StructureChain::createStructure):
-        * runtime/StructureIDTable.cpp: Added.
-        (JSC::StructureIDTable::StructureIDTable):
-        (JSC::StructureIDTable::~StructureIDTable):
-        (JSC::StructureIDTable::resize):
-        (JSC::StructureIDTable::flushOldTables):
-        (JSC::StructureIDTable::allocateID):
-        (JSC::StructureIDTable::deallocateID):
-        * runtime/StructureIDTable.h: Added.
-        (JSC::StructureIDTable::base):
-        (JSC::StructureIDTable::get):
-        * runtime/SymbolTable.h:
-        * runtime/TypedArrayType.cpp:
-        (JSC::typeForTypedArrayType):
-        * runtime/TypedArrayType.h:
-        * runtime/WeakMapData.h:
-
-2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
-
-        Unconditional logging in compileFTLOSRExit
-        https://bugs.webkit.org/show_bug.cgi?id=129407
-
-        Reviewed by Michael Saboff.
-
-        This was causing tests to fail with the FTL enabled.
-
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileFTLOSRExit):
-
-2014-02-26  Oliver Hunt  <oliver@apple.com>
-
-        Remove unused access types
-        https://bugs.webkit.org/show_bug.cgi?id=129385
-
-        Reviewed by Filip Pizlo.
-
-        Remove unused cruft.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::printGetByIdCacheStatus):
-        * bytecode/StructureStubInfo.cpp:
-        (JSC::StructureStubInfo::deref):
-        * bytecode/StructureStubInfo.h:
-        (JSC::isGetByIdAccess):
-        (JSC::isPutByIdAccess):
-
-2014-02-26  Oliver Hunt  <oliver@apple.com>
-
-        Function.prototype.apply has a bad time with the spread operator
-        https://bugs.webkit.org/show_bug.cgi?id=129381
-
-        Reviewed by Mark Hahnenberg.
-
-        Make sure our apply logic handle the spread operator correctly.
-        To do this we simply emit the enumeration logic that we'd normally
-        use for other enumerations, but only store the first two results
-        to registers.  Then perform a varargs call.
-
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::ApplyFunctionCallDotNode::emitBytecode):
-
-2014-02-26  Mark Lam  <mark.lam@apple.com>
-
-        Compilation policy management belongs in operationOptimize(), not the DFG Driver.
-        <https://webkit.org/b/129355>
-
-        Reviewed by Filip Pizlo.
-
-        By compilation policy, I mean the rules for determining whether to
-        compile, when to compile, when to attempt compilation again, etc.  The
-        few of these policy decisions that were previously being made in the
-        DFG driver are now moved to operationOptimize() where we keep the rest
-        of the policy logic.  Decisions that are based on the capabilities
-        supported by the DFG are moved to DFG capabiliityLevel().
-
-        I've run the following benchmarks:
-        1. the collection of jsc benchmarks on the jsc executable vs. its
-           baseline.
-        2. Octane 2.0 in browser without the WebInspector.
-        3. Octane 2.0 in browser with the WebInspector open and a breakpoint
-           set somewhere where it won't break.
-
-        In all of these, the results came out to be a wash as expected.
-
-        * dfg/DFGCapabilities.cpp:
-        (JSC::DFG::isSupported):
-        (JSC::DFG::mightCompileEval):
-        (JSC::DFG::mightCompileProgram):
-        (JSC::DFG::mightCompileFunctionForCall):
-        (JSC::DFG::mightCompileFunctionForConstruct):
-        (JSC::DFG::mightInlineFunctionForCall):
-        (JSC::DFG::mightInlineFunctionForClosureCall):
-        (JSC::DFG::mightInlineFunctionForConstruct):
-        * dfg/DFGCapabilities.h:
-        * dfg/DFGDriver.cpp:
-        (JSC::DFG::compileImpl):
-        * jit/JITOperations.cpp:
-
-2014-02-26  Mark Lam  <mark.lam@apple.com>
-
-        ASSERTION FAILED: m_heap->vm()->currentThreadIsHoldingAPILock() in inspector-protocol/*.
-        <https://webkit.org/b/129364>
-
-        Reviewed by Alexey Proskuryakov.
-
-        InjectedScriptModule::ensureInjected() needs an APIEntryShim.
-
-        * inspector/InjectedScriptModule.cpp:
-        (Inspector::InjectedScriptModule::ensureInjected):
-        - Added the needed but missing APIEntryShim. 
-
-2014-02-25  Mark Lam  <mark.lam@apple.com>
-
-        Web Inspector: CRASH when evaluating in console of JSContext RWI with disabled breakpoints.
-        <https://webkit.org/b/128766>
-
-        Reviewed by Geoffrey Garen.
-
-        Make the JSLock::grabAllLocks() work the same way as for the C loop LLINT.
-        The reasoning is that we don't know of any clients that need unordered
-        re-entry into the VM from different threads. So, we're enforcing ordered
-        re-entry i.e. we must re-grab locks in the reverse order of dropping locks.
-
-        The crash in this bug happened because we were allowing unordered re-entry,
-        and the following type of scenario occurred:
-
-        1. Thread T1 locks the VM, and enters the VM to execute some JS code.
-        2. On entry, T1 detects that VM::m_entryScope is null i.e. this is the
-           first time it entered the VM.
-           T1 sets VM::m_entryScope to T1's entryScope.
-        3. T1 drops all locks.
-
-        4. Thread T2 locks the VM, and enters the VM to execute some JS code.
-           On entry, T2 sees that VM::m_entryScope is NOT null, and therefore
-           does not set the entryScope.
-        5. T2 drops all locks.
-
-        6. T1 re-grabs locks.
-        7. T1 returns all the way out of JS code. On exit from the outer most
-           JS function, T1 clears VM::m_entryScope (because T1 was the one who
-           set it).
-        8. T1 unlocks the VM.
-
-        9. T2 re-grabs locks.
-        10. T2 proceeds to execute some code and expects VM::m_entryScope to be
-            NOT null, but it turns out to be null. Assertion failures and
-            crashes ensue.
-
-        With ordered re-entry, at step 6, T1 will loop and yield until T2 exits
-        the VM. Hence, the issue will no longer manifest.
-
-        * runtime/JSLock.cpp:
-        (JSC::JSLock::dropAllLocks):
-        (JSC::JSLock::grabAllLocks):
-        * runtime/JSLock.h:
-        (JSC::JSLock::DropAllLocks::dropDepth):
-
-2014-02-25  Mark Lam  <mark.lam@apple.com>
-
-        Need to initialize VM stack data even when the VM is on an exclusive thread.
-        <https://webkit.org/b/129265>
-
-        Not reviewed.
-
-        Relanding r164627 now that <https://webkit.org/b/129341> is fixed.
-
-        * API/APIShims.h:
-        (JSC::APIEntryShim::APIEntryShim):
-        (JSC::APICallbackShim::shouldDropAllLocks):
-        * heap/MachineStackMarker.cpp:
-        (JSC::MachineThreads::addCurrentThread):
-        * runtime/JSLock.cpp:
-        (JSC::JSLockHolder::JSLockHolder):
-        (JSC::JSLockHolder::init):
-        (JSC::JSLockHolder::~JSLockHolder):
-        (JSC::JSLock::JSLock):
-        (JSC::JSLock::setExclusiveThread):
-        (JSC::JSLock::lock):
-        (JSC::JSLock::unlock):
-        (JSC::JSLock::currentThreadIsHoldingLock):
-        (JSC::JSLock::dropAllLocks):
-        (JSC::JSLock::grabAllLocks):
-        * runtime/JSLock.h:
-        (JSC::JSLock::hasExclusiveThread):
-        (JSC::JSLock::exclusiveThread):
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        * runtime/VM.h:
-        (JSC::VM::hasExclusiveThread):
-        (JSC::VM::exclusiveThread):
-        (JSC::VM::setExclusiveThread):
-        (JSC::VM::currentThreadIsHoldingAPILock):
-
-2014-02-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Inline caching in the FTL on ARM64 should "work"
-        https://bugs.webkit.org/show_bug.cgi?id=129334
-
-        Reviewed by Mark Hahnenberg.
-        
-        Gets us to the point where simple tests that use inline caching are passing.
-
-        * assembler/LinkBuffer.cpp:
-        (JSC::LinkBuffer::copyCompactAndLinkCode):
-        (JSC::LinkBuffer::shrink):
-        * ftl/FTLInlineCacheSize.cpp:
-        (JSC::FTL::sizeOfGetById):
-        (JSC::FTL::sizeOfPutById):
-        (JSC::FTL::sizeOfCall):
-        * ftl/FTLOSRExitCompiler.cpp:
-        (JSC::FTL::compileFTLOSRExit):
-        * ftl/FTLThunks.cpp:
-        (JSC::FTL::osrExitGenerationThunkGenerator):
-        * jit/GPRInfo.h:
-        * offlineasm/arm64.rb:
-
-2014-02-25  Commit Queue  <commit-queue@webkit.org>
-
-        Unreviewed, rolling out r164627.
-        http://trac.webkit.org/changeset/164627
-        https://bugs.webkit.org/show_bug.cgi?id=129325
-
-        Broke SubtleCrypto tests (Requested by ap on #webkit).
-
-        * API/APIShims.h:
-        (JSC::APIEntryShim::APIEntryShim):
-        (JSC::APICallbackShim::shouldDropAllLocks):
-        * heap/MachineStackMarker.cpp:
-        (JSC::MachineThreads::addCurrentThread):
-        * runtime/JSLock.cpp:
-        (JSC::JSLockHolder::JSLockHolder):
-        (JSC::JSLockHolder::init):
-        (JSC::JSLockHolder::~JSLockHolder):
-        (JSC::JSLock::JSLock):
-        (JSC::JSLock::lock):
-        (JSC::JSLock::unlock):
-        (JSC::JSLock::currentThreadIsHoldingLock):
-        (JSC::JSLock::dropAllLocks):
-        (JSC::JSLock::grabAllLocks):
-        * runtime/JSLock.h:
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        * runtime/VM.h:
-        (JSC::VM::currentThreadIsHoldingAPILock):
-
-2014-02-25  Filip Pizlo  <fpizlo@apple.com>
-
-        ARM64 rshift64 should be an arithmetic shift
-        https://bugs.webkit.org/show_bug.cgi?id=129323
-
-        Reviewed by Mark Hahnenberg.
-
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::rshift64):
-
-2014-02-25  Sergio Villar Senin  <svillar@igalia.com>
-
-        [CSS Grid Layout] Add ENABLE flag
-        https://bugs.webkit.org/show_bug.cgi?id=129153
-
-        Reviewed by Simon Fraser.
-
-        * Configurations/FeatureDefines.xcconfig: added ENABLE_CSS_GRID_LAYOUT feature flag.
-
-2014-02-25  Michael Saboff  <msaboff@apple.com>
-
-        JIT Engines use the wrong stack limit for stack checks
-        https://bugs.webkit.org/show_bug.cgi?id=129314
-
-        Reviewed by Filip Pizlo.
-
-        Change the Baseline and DFG code to use VM::m_stackLimit for stack limit checks.
-
-        * dfg/DFGJITCompiler.cpp:
-        (JSC::DFG::JITCompiler::compileFunction):
-        * jit/JIT.cpp:
-        (JSC::JIT::privateCompile):
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileLoadVarargs):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileLoadVarargs):
-        * runtime/VM.h:
-        (JSC::VM::addressOfStackLimit):
-
-2014-02-25  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, roll out http://trac.webkit.org/changeset/164493.
-        
-        It causes crashes, apparently because it's removing too many barriers. I will investigate
-        later.
-
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationToAbbreviatedString):
-        * bytecode/SpeculatedType.h:
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::insertStoreBarrier):
-        * dfg/DFGNode.h:
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
-        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
-        (JSC::FTL::LowerDFGToLLVM::isNotNully):
-        (JSC::FTL::LowerDFGToLLVM::isNully):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
-        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
-
-2014-02-24  Oliver Hunt  <oliver@apple.com>
-
-        Fix build.
-
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-
-2014-02-24  Oliver Hunt  <oliver@apple.com>
-
-        Spread operator has a bad time when applied to call function
-        https://bugs.webkit.org/show_bug.cgi?id=128853
-
-        Reviewed by Geoffrey Garen.
-
-        Follow on from the previous patch the added an extra slot to
-        op_call_varargs (and _call, _call_eval, _construct).  We now
-        use the slot as an offset to in effect act as a 'slice' on
-        the spread subject.  This allows us to automatically retain
-        all our existing argument and array optimisatons.  Most of
-        this patch is simply threading the offset around.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::dumpBytecode):
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::emitCall):
-        (JSC::BytecodeGenerator::emitCallVarargs):
-        * bytecompiler/BytecodeGenerator.h:
-        * bytecompiler/NodesCodegen.cpp:
-        (JSC::getArgumentByVal):
-        (JSC::CallFunctionCallDotNode::emitBytecode):
-        (JSC::ApplyFunctionCallDotNode::emitBytecode):
-        * interpreter/Interpreter.cpp:
-        (JSC::sizeFrameForVarargs):
-        (JSC::loadVarargs):
-        * interpreter/Interpreter.h:
-        * jit/CCallHelpers.h:
-        (JSC::CCallHelpers::setupArgumentsWithExecState):
-        * jit/JIT.h:
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileLoadVarargs):
-        * jit/JITInlines.h:
-        (JSC::JIT::callOperation):
-        * jit/JITOperations.cpp:
-        * jit/JITOperations.h:
-        * llint/LLIntSlowPaths.cpp:
-        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
-        * runtime/Arguments.cpp:
-        (JSC::Arguments::copyToArguments):
-        * runtime/Arguments.h:
-        * runtime/JSArray.cpp:
-        (JSC::JSArray::copyToArguments):
-        * runtime/JSArray.h:
-
-2014-02-24  Mark Lam  <mark.lam@apple.com>
-
-        Need to initialize VM stack data even when the VM is on an exclusive thread.
-        <https://webkit.org/b/129265>
-
-        Reviewed by Geoffrey Garen.
-
-        We check VM::exclusiveThread as an optimization to forego the need to do
-        JSLock locking. However, we recently started piggy backing on JSLock's
-        lock() and unlock() to initialize VM stack data (stackPointerAtVMEntry
-        and lastStackTop) to appropriate values for the current thread. This is
-        needed because we may be acquiring the lock to enter the VM on a different
-        thread.
-
-        As a result, we ended up not initializing the VM stack data when
-        VM::exclusiveThread causes us to bypass the locking activity. Even though
-        the VM::exclusiveThread will not have to deal with the VM being entered
-        on a different thread, it still needs to initialize the VM stack data.
-        The VM relies on that data being initialized properly once it has been
-        entered.
-
-        With this fix, we push the check for exclusiveThread down into the JSLock,
-        and handle the bypassing of unneeded locking activity there while still
-        executing the necessary the VM stack data initialization.
-
-        * API/APIShims.h:
-        (JSC::APIEntryShim::APIEntryShim):
-        (JSC::APICallbackShim::shouldDropAllLocks):
-        * heap/MachineStackMarker.cpp:
-        (JSC::MachineThreads::addCurrentThread):
-        * runtime/JSLock.cpp:
-        (JSC::JSLockHolder::JSLockHolder):
-        (JSC::JSLockHolder::init):
-        (JSC::JSLockHolder::~JSLockHolder):
-        (JSC::JSLock::JSLock):
-        (JSC::JSLock::setExclusiveThread):
-        (JSC::JSLock::lock):
-        (JSLock::unlock):
-        (JSLock::currentThreadIsHoldingLock):
-        (JSLock::dropAllLocks):
-        (JSLock::grabAllLocks):
-        * runtime/JSLock.h:
-        (JSC::JSLock::exclusiveThread):
-        * runtime/VM.cpp:
-        (JSC::VM::VM):
-        * runtime/VM.h:
-        (JSC::VM::exclusiveThread):
-        (JSC::VM::setExclusiveThread):
-        (JSC::VM::currentThreadIsHoldingAPILock):
-
-2014-02-24  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL should do polymorphic PutById inlining
-        https://bugs.webkit.org/show_bug.cgi?id=129210
-
-        Reviewed by Mark Hahnenberg and Oliver Hunt.
-        
-        This makes PutByIdStatus inform us about polymorphic cases by returning an array of
-        PutByIdVariants. The DFG now has a node called MultiPutByOffset that indicates a
-        selection of multiple inlined PutByIdVariants.
-        
-        MultiPutByOffset is almost identical to MultiGetByOffset, which we added in
-        http://trac.webkit.org/changeset/164207.
-        
-        This also does some FTL refactoring to make MultiPutByOffset share code with some nodes
-        that generate similar code.
-        
-        1% speed-up on V8v7 due to splay improving by 6.8%. Splay does the thing where it
-        sometimes swaps field insertion order, creating fake polymorphism.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bytecode/PutByIdStatus.cpp:
-        (JSC::PutByIdStatus::computeFromLLInt):
-        (JSC::PutByIdStatus::computeFor):
-        (JSC::PutByIdStatus::computeForStubInfo):
-        (JSC::PutByIdStatus::dump):
-        * bytecode/PutByIdStatus.h:
-        (JSC::PutByIdStatus::PutByIdStatus):
-        (JSC::PutByIdStatus::isSimple):
-        (JSC::PutByIdStatus::numVariants):
-        (JSC::PutByIdStatus::variants):
-        (JSC::PutByIdStatus::at):
-        (JSC::PutByIdStatus::operator[]):
-        * bytecode/PutByIdVariant.cpp: Added.
-        (JSC::PutByIdVariant::dump):
-        (JSC::PutByIdVariant::dumpInContext):
-        * bytecode/PutByIdVariant.h: Added.
-        (JSC::PutByIdVariant::PutByIdVariant):
-        (JSC::PutByIdVariant::replace):
-        (JSC::PutByIdVariant::transition):
-        (JSC::PutByIdVariant::kind):
-        (JSC::PutByIdVariant::isSet):
-        (JSC::PutByIdVariant::operator!):
-        (JSC::PutByIdVariant::structure):
-        (JSC::PutByIdVariant::oldStructure):
-        (JSC::PutByIdVariant::newStructure):
-        (JSC::PutByIdVariant::structureChain):
-        (JSC::PutByIdVariant::offset):
-        * dfg/DFGAbstractInterpreterInlines.h:
-        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
-        (JSC::DFG::ByteCodeParser::handleGetById):
-        (JSC::DFG::ByteCodeParser::emitPutById):
-        (JSC::DFG::ByteCodeParser::handlePutById):
-        (JSC::DFG::ByteCodeParser::parseBlock):
-        * dfg/DFGCSEPhase.cpp:
-        (JSC::DFG::CSEPhase::checkStructureElimination):
-        (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
-        (JSC::DFG::CSEPhase::putStructureStoreElimination):
-        (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
-        (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
-        * dfg/DFGClobberize.h:
-        (JSC::DFG::clobberize):
-        * dfg/DFGConstantFoldingPhase.cpp:
-        (JSC::DFG::ConstantFoldingPhase::foldConstants):
-        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        * dfg/DFGGraph.cpp:
-        (JSC::DFG::Graph::dump):
-        * dfg/DFGGraph.h:
-        * dfg/DFGNode.cpp:
-        (JSC::DFG::MultiPutByOffsetData::writesStructures):
-        (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::convertToPutByOffset):
-        (JSC::DFG::Node::hasMultiPutByOffsetData):
-        (JSC::DFG::Node::multiPutByOffsetData):
-        * dfg/DFGNodeType.h:
-        * dfg/DFGPredictionPropagationPhase.cpp:
-        (JSC::DFG::PredictionPropagationPhase::propagate):
-        * dfg/DFGSafeToExecute.h:
-        (JSC::DFG::safeToExecute):
-        * dfg/DFGSpeculativeJIT32_64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGSpeculativeJIT64.cpp:
-        (JSC::DFG::SpeculativeJIT::compile):
-        * dfg/DFGTypeCheckHoistingPhase.cpp:
-        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
-        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileNode):
-        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
-        (JSC::FTL::LowerDFGToLLVM::compileAllocatePropertyStorage):
-        (JSC::FTL::LowerDFGToLLVM::compileReallocatePropertyStorage):
-        (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
-        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
-        (JSC::FTL::LowerDFGToLLVM::compilePutByOffset):
-        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
-        (JSC::FTL::LowerDFGToLLVM::loadProperty):
-        (JSC::FTL::LowerDFGToLLVM::storeProperty):
-        (JSC::FTL::LowerDFGToLLVM::addressOfProperty):
-        (JSC::FTL::LowerDFGToLLVM::storageForTransition):
-        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorage):
-        (JSC::FTL::LowerDFGToLLVM::reallocatePropertyStorage):
-        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
-        * tests/stress/fold-multi-put-by-offset-to-put-by-offset.js: Added.
-        * tests/stress/multi-put-by-offset-reallocation-butterfly-cse.js: Added.
-        * tests/stress/multi-put-by-offset-reallocation-cases.js: Added.
-
-2014-02-24  peavo@outlook.com  <peavo@outlook.com>
-
-        JSC regressions after r164494
-        https://bugs.webkit.org/show_bug.cgi?id=129272
-
-        Reviewed by Mark Lam.
-
-        * offlineasm/x86.rb: Only avoid reverse opcode (fdivr) for Windows.
-
-2014-02-24  Tamas Gergely  <tgergely.u-szeged@partner.samsung.com>
-
-        Code cleanup: remove leftover ENABLE(WORKERS) macros and support.
-        https://bugs.webkit.org/show_bug.cgi?id=129255
-
-        Reviewed by Csaba Osztrogonác.
-
-        ENABLE_WORKERS macro was removed in r159679.
-        Support is now also removed from xcconfig files.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-02-24  David Kilzer  <ddkilzer@apple.com>
-
-        Remove redundant setting in FeatureDefines.xcconfig
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-02-23  Sam Weinig  <sam@webkit.org>
-
-        Update FeatureDefines.xcconfig
-
-        Rubber-stamped by Anders Carlsson.
-
-        * Configurations/FeatureDefines.xcconfig:
-
-2014-02-23  Dean Jackson  <dino@apple.com>
-
-        Sort the project file with sort-Xcode-project-file.
-
-        Rubber-stamped by Sam Weinig.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2014-02-23  Sam Weinig  <sam@webkit.org>
-
-        Move telephone number detection behind its own ENABLE macro
-        https://bugs.webkit.org/show_bug.cgi?id=129236
-
-        Reviewed by Dean Jackson.
-
-        * Configurations/FeatureDefines.xcconfig:
-        Add ENABLE_TELEPHONE_NUMBER_DETECTION.
-
-2014-02-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Refine DFG+FTL inlining and compilation limits
-        https://bugs.webkit.org/show_bug.cgi?id=129212
-
-        Reviewed by Mark Hahnenberg.
-        
-        Allow larger functions to be DFG-compiled. Institute a limit on FTL compilation,
-        and set that limit quite high. Institute a limit on inlining-into. The idea here is
-        that large functions tend to be autogenerated, and code generators like emscripten
-        appear to leave few inlining opportunities anyway. Also, we don't want the code
-        size explosion that we would risk if we allowed compilation of a large function and
-        then inlined a ton of stuff into it.
-        
-        This is a 0.5% speed-up on Octane v2 and almost eliminates the typescript
-        regression. This is a 9% speed-up on AsmBench.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::noticeIncomingCall):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleInlining):
-        * dfg/DFGCapabilities.h:
-        (JSC::DFG::isSmallEnoughToInlineCodeInto):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLState.h:
-        (JSC::FTL::shouldShowDisassembly):
-        * runtime/Options.h:
-
-2014-02-22  Dan Bernstein  <mitz@apple.com>
-
-        REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
-        https://bugs.webkit.org/show_bug.cgi?id=129227
-
-        Reviewed by Eric Carlson.
-
-        Reverted r164507.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectMakeArray):
-        (JSObjectMakeDate):
-        (JSObjectMakeError):
-        (JSObjectMakeRegExp):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * API/JSValue.mm:
-        (valueToArray):
-        (valueToDictionary):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueCreateJSONString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        * inspector/ConsoleMessage.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        * inspector/JSGlobalObjectInspectorController.h:
-        * inspector/ScriptCallStack.cpp:
-        * inspector/ScriptCallStack.h:
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::createScriptCallStackForConsole):
-        (Inspector::createScriptCallStackFromException):
-        * inspector/ScriptCallStackFactory.h:
-        * inspector/agents/InspectorConsoleAgent.cpp:
-        (Inspector::InspectorConsoleAgent::enable):
-        (Inspector::InspectorConsoleAgent::addMessageToConsole):
-        (Inspector::InspectorConsoleAgent::count):
-        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
-        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
-
-2014-02-22  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Remove some unreachable code (-Wunreachable-code)
-        https://bugs.webkit.org/show_bug.cgi?id=129220
-
-        Reviewed by Eric Carlson.
-
-        * API/tests/testapi.c:
-        (EvilExceptionObject_convertToType):
-        * disassembler/udis86/udis86_decode.c:
-        (decode_operand):
-
-2014-02-22  Filip Pizlo  <fpizlo@apple.com>
-
-        Unreviewed, ARMv7 build fix.
-
-        * assembler/ARMv7Assembler.h:
-
-2014-02-21  Filip Pizlo  <fpizlo@apple.com>
-
-        It should be possible for a LinkBuffer to outlive the MacroAssembler and still be useful
-        https://bugs.webkit.org/show_bug.cgi?id=124733
-
-        Reviewed by Oliver Hunt.
-        
-        This also takes the opportunity to de-duplicate some branch compaction code.
-
-        * assembler/ARM64Assembler.h:
-        * assembler/ARMv7Assembler.h:
-        (JSC::ARMv7Assembler::buffer):
-        * assembler/AssemblerBuffer.h:
-        (JSC::AssemblerData::AssemblerData):
-        (JSC::AssemblerBuffer::AssemblerBuffer):
-        (JSC::AssemblerBuffer::storage):
-        (JSC::AssemblerBuffer::grow):
-        * assembler/LinkBuffer.h:
-        (JSC::LinkBuffer::LinkBuffer):
-        (JSC::LinkBuffer::executableOffsetFor):
-        (JSC::LinkBuffer::applyOffset):
-        * assembler/MacroAssemblerARM64.h:
-        (JSC::MacroAssemblerARM64::link):
-        * assembler/MacroAssemblerARMv7.h:
-
-2014-02-21  Brent Fulgham  <bfulgham@apple.com>
-
-        Extend media support for WebVTT sources
-        https://bugs.webkit.org/show_bug.cgi?id=129156
-
-        Reviewed by Eric Carlson.
-
-        * Configurations/FeatureDefines.xcconfig: Add new feature define for AVF_CAPTIONS
-
-2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: JSContext inspection should report exceptions in the console
-        https://bugs.webkit.org/show_bug.cgi?id=128776
-
-        Reviewed by Timothy Hatcher.
-
-        When JavaScript API functions have an exception, let the inspector
-        know so it can log the JavaScript and Native backtrace that caused
-        the exception.
-
-        Include some clean up of ConsoleMessage and ScriptCallStack construction.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectMakeArray):
-        (JSObjectMakeDate):
-        (JSObjectMakeError):
-        (JSObjectMakeRegExp):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * API/JSValue.mm:
-        (reportExceptionToInspector):
-        (valueToArray):
-        (valueToDictionary):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueCreateJSONString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        When seeing an exception, let the inspector know there was an exception.
-
-        * inspector/JSGlobalObjectInspectorController.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-        Log API exceptions by also grabbing the native backtrace.
-
-        * inspector/ScriptCallStack.h:
-        * inspector/ScriptCallStack.cpp:
-        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
-        (Inspector::ScriptCallStack::append):
-        Minor extensions to ScriptCallStack to make it easier to work with.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        Provide better default information if the first call frame was native.
-
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::extractSourceInformationFromException):
-        (Inspector::createScriptCallStackFromException):
-        Perform the handling here of inserting a fake call frame for exceptions
-        if there was no call stack (e.g. a SyntaxError) or if the first call
-        frame had no information.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        * inspector/ConsoleMessage.h:
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::createScriptCallStackForConsole):
-        * inspector/ScriptCallStackFactory.h:
-        * inspector/agents/InspectorConsoleAgent.cpp:
-        (Inspector::InspectorConsoleAgent::enable):
-        (Inspector::InspectorConsoleAgent::addMessageToConsole):
-        (Inspector::InspectorConsoleAgent::count):
-        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
-        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
-        ConsoleMessage cleanup.
-
-2014-02-21  Oliver Hunt  <oliver@apple.com>
-
-        Add extra space to op_call and related opcodes
-        https://bugs.webkit.org/show_bug.cgi?id=129170
-
-        Reviewed by Mark Lam.
-
-        No change in behaviour, just some refactoring to add an extra
-        slot to the op_call instructions, and refactoring to make similar
-        changes easier in future.
-
-        * bytecode/CodeBlock.cpp:
-        (JSC::CodeBlock::printCallOp):
-        * bytecode/Opcode.h:
-        (JSC::padOpcodeName):
-        * bytecompiler/BytecodeGenerator.cpp:
-        (JSC::BytecodeGenerator::emitCall):
-        (JSC::BytecodeGenerator::emitCallVarargs):
-        (JSC::BytecodeGenerator::emitConstruct):
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleIntrinsic):
-        * jit/JITCall.cpp:
-        (JSC::JIT::compileOpCall):
-        * jit/JITCall32_64.cpp:
-        (JSC::JIT::compileOpCall):
-        * llint/LowLevelInterpreter.asm:
-        * llint/LowLevelInterpreter32_64.asm:
-        * llint/LowLevelInterpreter64.asm:
-
-2014-02-21  Mark Lam  <mark.lam@apple.com>
-
-        gatherFromOtherThread() needs to align the sp before gathering roots.
-        <https://webkit.org/b/129169>
-
-        Reviewed by Geoffrey Garen.
-
-        The GC scans the stacks of other threads using MachineThreads::gatherFromOtherThread().
-        gatherFromOtherThread() defines the range of the other thread's stack as
-        being bounded by the other thread's stack pointer and stack base. While
-        the stack base will always be aligned to sizeof(void*), the stack pointer
-        may not be. This is because the other thread may have just pushed a 32-bit
-        value on its stack before we suspended it for scanning.
-
-        The fix is to round the stack pointer up to the next aligned address of
-        sizeof(void*) and start scanning from there. On 64-bit systems, we will
-        effectively ignore the 32-bit word at the bottom of the stack (top of the
-        stack for stacks growing up) because it cannot be a 64-bit pointer anyway.
-        64-bit pointers should always be stored on 64-bit aligned boundaries (our
-        conservative scan algorithm already depends on this assumption).
-
-        On 32-bit systems, the rounding is effectively a no-op.
-
-        * heap/ConservativeRoots.cpp:
-        (JSC::ConservativeRoots::genericAddSpan):
-        - Hardened somne assertions so that we can catch misalignment issues on
-          release builds as well.
-        * heap/MachineStackMarker.cpp:
-        (JSC::MachineThreads::gatherFromOtherThread):
-
-2014-02-21  Matthew Mirman  <mmirman@apple.com>
-
-        Added a GetMyArgumentsLengthSafe and added a speculation check.
-        https://bugs.webkit.org/show_bug.cgi?id=129051
-
-        Reviewed by Filip Pizlo.
-
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
-
-2014-02-21  peavo@outlook.com  <peavo@outlook.com>
-
-        [Win][LLINT] Many JSC stress test failures.
-        https://bugs.webkit.org/show_bug.cgi?id=129155
-
-        Reviewed by Michael Saboff.
-
-        Intel syntax has reversed operand order compared to AT&T syntax, so we need to swap the operand order, in this case on floating point operations.
-        Also avoid using the reverse opcode (e.g. fdivr), as this puts the result at the wrong position in the floating point stack.
-        E.g. "divd ft0, ft1" would translate to fdivr st, st(1) (Intel syntax) on Windows, but this puts the result in st, when it should be in st(1).
-
-        * offlineasm/x86.rb: Swap operand order on Windows.
-
-2014-02-21  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG write barriers should do more speculations
-        https://bugs.webkit.org/show_bug.cgi?id=129160
-
-        Reviewed by Mark Hahnenberg.
-        
-        Replace ConditionalStoreBarrier with the cheapest speculation that you could do
-        instead.
-        
-        Miniscule speed-up on some things. It's a decent difference in code size, though.
-
-        * bytecode/SpeculatedType.cpp:
-        (JSC::speculationToAbbreviatedString):
-        * bytecode/SpeculatedType.h:
-        (JSC::isNotCellSpeculation):
-        * dfg/DFGFixupPhase.cpp:
-        (JSC::DFG::FixupPhase::fixupNode):
-        (JSC::DFG::FixupPhase::insertStoreBarrier):
-        (JSC::DFG::FixupPhase::insertPhantomCheck):
-        * dfg/DFGNode.h:
-        (JSC::DFG::Node::shouldSpeculateOther):
-        (JSC::DFG::Node::shouldSpeculateNotCell):
-        * ftl/FTLCapabilities.cpp:
-        (JSC::FTL::canCompile):
-        * ftl/FTLLowerDFGToLLVM.cpp:
-        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
-        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
-        (JSC::FTL::LowerDFGToLLVM::isNotOther):
-        (JSC::FTL::LowerDFGToLLVM::isOther):
-        (JSC::FTL::LowerDFGToLLVM::speculate):
-        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
-        (JSC::FTL::LowerDFGToLLVM::speculateOther):
-        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
-
-2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Revert r164486, causing a number of test failures.
-
-        Unreviewed rollout.
-
-2014-02-21  Filip Pizlo  <fpizlo@apple.com>
-
-        Revive SABI (aka shouldAlwaysBeInlined)
-        https://bugs.webkit.org/show_bug.cgi?id=129159
-
-        Reviewed by Mark Hahnenberg.
-        
-        This is a small Octane speed-up.
-
-        * jit/Repatch.cpp:
-        (JSC::linkFor): This code was assuming that if it's invoked then the caller is a DFG code block. That's wrong, since it's now used by all of the JITs.
-
-2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
-
-        Web Inspector: JSContext inspection should report exceptions in the console
-        https://bugs.webkit.org/show_bug.cgi?id=128776
-
-        Reviewed by Timothy Hatcher.
-
-        When JavaScript API functions have an exception, let the inspector
-        know so it can log the JavaScript and Native backtrace that caused
-        the exception.
-
-        Include some clean up of ConsoleMessage and ScriptCallStack construction.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectMakeArray):
-        (JSObjectMakeDate):
-        (JSObjectMakeError):
-        (JSObjectMakeRegExp):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * API/JSValue.mm:
-        (reportExceptionToInspector):
-        (valueToArray):
-        (valueToDictionary):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueCreateJSONString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        When seeing an exception, let the inspector know there was an exception.
-
-        * inspector/JSGlobalObjectInspectorController.h:
-        * inspector/JSGlobalObjectInspectorController.cpp:
-        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
-        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
-        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
-        Log API exceptions by also grabbing the native backtrace.
-
-        * inspector/ScriptCallStack.h:
-        * inspector/ScriptCallStack.cpp:
-        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
-        (Inspector::ScriptCallStack::append):
-        Minor extensions to ScriptCallStack to make it easier to work with.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        Provide better default information if the first call frame was native.
-
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::extractSourceInformationFromException):
-        (Inspector::createScriptCallStackFromException):
-        Perform the handling here of inserting a fake call frame for exceptions
-        if there was no call stack (e.g. a SyntaxError) or if the first call
-        frame had no information.
-
-        * inspector/ConsoleMessage.cpp:
-        (Inspector::ConsoleMessage::ConsoleMessage):
-        (Inspector::ConsoleMessage::autogenerateMetadata):
-        * inspector/ConsoleMessage.h:
-        * inspector/ScriptCallStackFactory.cpp:
-        (Inspector::createScriptCallStack):
-        (Inspector::createScriptCallStackForConsole):
-        * inspector/ScriptCallStackFactory.h:
-        * inspector/agents/InspectorConsoleAgent.cpp:
-        (Inspector::InspectorConsoleAgent::enable):
-        (Inspector::InspectorConsoleAgent::addMessageToConsole):
-        (Inspector::InspectorConsoleAgent::count):
-        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
-        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
-        ConsoleMessage cleanup.
-
-2014-02-20  Anders Carlsson  <andersca@apple.com>
-
-        Modernize JSGlobalLock and JSLockHolder
-        https://bugs.webkit.org/show_bug.cgi?id=129105
-
-        Reviewed by Michael Saboff.
-
-        Use std::mutex and std::thread::id where possible.
-
-        * runtime/JSLock.cpp:
-        (JSC::GlobalJSLock::GlobalJSLock):
-        (JSC::GlobalJSLock::~GlobalJSLock):
-        (JSC::GlobalJSLock::initialize):
-        (JSC::JSLock::JSLock):
-        (JSC::JSLock::lock):
-        (JSC::JSLock::unlock):
-        (JSC::JSLock::currentThreadIsHoldingLock):
-        * runtime/JSLock.h:
-
-2014-02-20  Mark Lam  <mark.lam@apple.com>
-
-        virtualForWithFunction() should not throw an exception with a partially initialized frame.
-        <https://webkit.org/b/129134>
-
-        Reviewed by Michael Saboff.
-
-        Currently, when JITOperations.cpp's virtualForWithFunction() fails to
-        prepare the callee function for execution, it proceeds to throw the
-        exception using the callee frame which is only partially initialized
-        thus far. Instead, it should be throwing the exception using the caller
-        frame because:
-        1. the error happened "in" the caller while preparing the callee for
-           execution i.e. the caller frame is the top fully initialized frame
-           on the stack.
-        2. the callee frame is not fully initialized yet, and the unwind
-           mechanism cannot depend on the data in it.
-
-        * jit/JITOperations.cpp:
-
-2014-02-20  Mark Lam  <mark.lam@apple.com>
-
-        DefaultGCActivityCallback::doWork() should reschedule if GC is deferred.
-        <https://webkit.org/b/129131>
-
-        Reviewed by Mark Hahnenberg.
-
-        Currently, DefaultGCActivityCallback::doWork() does not check if the GC
-        needs to be deferred before commencing. As a result, the GC may crash
-        and/or corrupt data because the VM is not in the consistent state needed
-        for the GC to run. With this fix, doWork() now checks if the GC is
-        supposed to be deferred and re-schedules if needed. It only commences
-        with GC'ing when it's safe to do so.
-
-        * runtime/GCActivityCallback.cpp:
-        (JSC::DefaultGCActivityCallback::doWork):
-
-2014-02-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Math.imul gives wrong results
-        https://bugs.webkit.org/show_bug.cgi?id=126345
-
-        Reviewed by Mark Hahnenberg.
-
-        Don't truncate non-int doubles to 0 -- that's just not how ToInt32 works.
-        Instead, take a slow path that will do the right thing.
-
-        * jit/ThunkGenerators.cpp:
-        (JSC::imulThunkGenerator):
-
-2014-02-20  Filip Pizlo  <fpizlo@apple.com>
-
-        DFG should do its own static estimates of execution frequency before it starts creating OSR entrypoints
-        https://bugs.webkit.org/show_bug.cgi?id=129129
-
-        Reviewed by Geoffrey Garen.
-        
-        We estimate execution counts based on loop depth, and then use those to estimate branch
-        weights. These weights then get carried all the way down to LLVM prof branch_weights
-        meta-data.
-        
-        This is better than letting LLVM do its own static estimates, since by the time we
-        generate LLVM IR, we may have messed up the CFG due to OSR entrypoint creation. Of
-        course, it would be even better if we just slurped in some kind of execution counts
-        from profiling, but we don't do that, yet.
-
-        * CMakeLists.txt:
-        * GNUmakefile.list.am:
-        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * dfg/DFGBasicBlock.cpp:
-        (JSC::DFG::BasicBlock::BasicBlock):
-        * dfg/DFGBasicBlock.h:
-        * dfg/DFGBlockInsertionSet.cpp:
-        (JSC::DFG::BlockInsertionSet::insert):
-        (JSC::DFG::BlockInsertionSet::insertBefore):
-        * dfg/DFGBlockInsertionSet.h:
-        * dfg/DFGByteCodeParser.cpp:
-        (JSC::DFG::ByteCodeParser::handleInlining):
-        (JSC::DFG::ByteCodeParser::parseCodeBlock):
-        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
-        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
-        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
-        (JSC::DFG::createPreHeader):
-        * dfg/DFGNaturalLoops.h:
-        (JSC::DFG::NaturalLoops::loopDepth):
-        * dfg/DFGOSREntrypointCreationPhase.cpp:
-        (JSC::DFG::OSREntrypointCreationPhase::run):
-        * dfg/DFGPlan.cpp:
-        (JSC::DFG::Plan::compileInThreadImpl):
-        * dfg/DFGStaticExecutionCountEstimationPhase.cpp: Added.
-        (JSC::DFG::StaticExecutionCountEstimationPhase::StaticExecutionCountEstimationPhase):
-        (JSC::DFG::StaticExecutionCountEstimationPhase::run):
-        (JSC::DFG::StaticExecutionCountEstimationPhase::applyCounts):
-        (JSC::DFG::performStaticExecutionCountEstimation):
-        * dfg/DFGStaticExecutionCountEstimationPhase.h: Added.
-
-2014-02-20  Filip Pizlo  <fpizlo@apple.com>
-
-        FTL may not see a compact_unwind section if there weren't any stackmaps
-        https://bugs.webkit.org/show_bug.cgi?id=129125
-
-        Reviewed by Geoffrey Garen.
-        
-        It's OK to not have an unwind section, so long as the function also doesn't have any
-        OSR exits.
-
-        * ftl/FTLCompile.cpp:
-        (JSC::FTL::fixFunctionBasedOnStackMaps):
-        (JSC::FTL::compile):
-        * ftl/FTLUnwindInfo.cpp:
-        (JSC::FTL::UnwindInfo::parse):
-        * ftl/FTLUnwindInfo.h:
 
-== Rolled over to ChangeLog-2014-02-20 ==
+== Rolled over to ChangeLog-2015-07-23 ==
diff --git a/ChangeLog-2014-10-07 b/ChangeLog-2014-10-07
new file mode 100644 (file)
index 0000000..55c897c
--- /dev/null
@@ -0,0 +1,30352 @@
+2014-10-07  Oliver Hunt  <oliver@apple.com>
+
+        Remove op_new_captured_func
+        https://bugs.webkit.org/show_bug.cgi?id=137491
+
+        Reviewed by Mark Lam.
+
+        Removes the op_captured_new_func opcode as part of the work
+        towards having any magical opcodes that write directly to
+        named "registers" and then have a follow on op to ensure that
+        the environment record correctly represents the stack state.
+
+        For this we add a non-captured scratch register so we don't
+        have to have any kind of magic opcode, and instead simply
+        have sensible creation and move semantics for capturing new
+        functions.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitNewFunction):
+        (JSC::BytecodeGenerator::emitLazyNewFunction):
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        * bytecompiler/BytecodeGenerator.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_new_captured_func): Deleted.
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+        * runtime/CommonSlowPaths.h:
+
+2014-10-06  Andy Estes  <aestes@apple.com>
+
+        Objective-C objects must be fully defined when used in a WTF::Vector
+        https://bugs.webkit.org/show_bug.cgi?id=137479
+
+        Reviewed by Mark Rowe.
+
+        When compiling an Objective-C++ file under ARC, @class types are considered non-trivially destructable, so
+        Vector needs to see their definition in order to call their destructor.
+
+        See <http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership-qualified-fields-of-structs-and-unions> for details.
+
+        * API/ObjcRuntimeExtras.h: Imported <objc/Protocol.h>.
+
+2014-10-06  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Use of 1-bit Enum type behaves improperly
+        https://bugs.webkit.org/show_bug.cgi?id=137471
+        <rdar://problem/18559172>
+
+        Reviewed by Mark Lam.
+
+        Represent 1-bit enum element as 'unsigned', as we have done elsewhere
+        in WebKit to avoid problems when building with MSVC.
+
+        * debugger/Debugger.h:
+
+2014-10-06  Mark Lam  <mark.lam@apple.com>
+
+        Fixed compiler warnings on Windows build.
+        <https://webkit.org/b/135205>
+
+        Reviewed by Geoffrey Garen.
+
+        Benchmarking with jsc shows that perf is neutral with this change.
+
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::call):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * dfg/DFGArgumentPosition.h:
+        (JSC::DFG::ArgumentPosition::mergeShouldNeverUnbox):
+        (JSC::DFG::ArgumentPosition::mergeArgumentUnboxingAwareness):
+        * dfg/DFGEdge.h:
+        (JSC::DFG::Edge::makeWord):
+        * dfg/DFGNodeFlags.h:
+        (JSC::DFG::nodeMayOverflow):
+        (JSC::DFG::nodeMayNegZero):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGVariableAccessData.cpp:
+        (JSC::DFG::VariableAccessData::mergeIsCaptured):
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::mergeIsProfitableToUnbox):
+        (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed):
+        (JSC::DFG::VariableAccessData::mergeCheckArrayHoistingFailed):
+        (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias):
+        (JSC::DFG::VariableAccessData::mergeIsLoadedFrom):
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+
+2014-10-06  Oliver Hunt  <oliver@apple.com>
+
+        Remove incorrect assertion.
+
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::tearOff):
+
+2014-10-06  Oliver Hunt  <oliver@apple.com>
+
+        Fix cloop build
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+
+2014-10-06  Mark Lam  <mark.lam@apple.com>
+
+        Unreviewed build fix.
+        <https://webkit.org/b/137279>
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2014-10-06  Oliver Hunt  <oliver@apple.com>
+
+        REGRESSION(r174226): [JSC] Crash when running the perf test Speedometer/Full.html
+        https://bugs.webkit.org/show_bug.cgi?id=137404
+
+        Reviewed by Michael Saboff.
+
+        Update the Arguments object to recognise that it must always have an
+        environment record if the referenced callee has one, and if such is not
+        present it should not try to extract one from the callframe, as that
+        path leads to madness.
+
+        Happily this makes some of the other code more sensible, and removes a
+        bunch of unnecessary and icky logic.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::tearOff):
+        (JSC::Arguments::didTearOffActivation): Deleted.
+        * runtime/Arguments.h:
+        (JSC::Arguments::argument):
+        (JSC::Arguments::finishCreation):
+
+2014-10-04  Brian J. Burg  <burg@cs.washington.edu>
+
+        Unreviewed, rolling out r174319.
+
+        Causes assertions in fast/profiler tests. Needs nontrivial
+        investigation, will take offline.
+
+        Reverted changeset:
+
+        "Web Inspector: timelines should not count time elapsed while
+        paused in the debugger"
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+        http://trac.webkit.org/changeset/174319
+
+2014-10-04  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        Now that we have a stopwatch to provide pause-aware timing data, we can remove the
+        profiler's handling of debugger pause/continue callbacks. The timeline agent accounts
+        for debugger pauses by pausing and resuming the stopwatch.
+
+        * API/JSProfilerPrivate.cpp:
+        (JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handlePause):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::profiler): Use nullptr.
+        (JSC::LegacyProfiler::startProfiling): Hand off a stopwatch to the profile generator.
+        (JSC::LegacyProfiler::stopProfiling): Use nullptr.
+        (JSC::LegacyProfiler::didPause): Deleted.
+        (JSC::LegacyProfiler::didContinue): Deleted.
+        * profiler/LegacyProfiler.h:
+        * profiler/ProfileGenerator.cpp: Remove debugger pause/continue callbacks and the
+        timestamp member that was used to track time elapsed by the debugger. Just use the
+        stopwatch's elapsed times to generate start/elapsed times for function calls.
+        (JSC::ProfileGenerator::create):
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause): Deleted.
+        (JSC::ProfileGenerator::didContinue): Deleted.
+        * profiler/ProfileGenerator.h:
+
+2014-10-04  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should sink PutLocals
+        https://bugs.webkit.org/show_bug.cgi?id=137168
+
+        Reviewed by Oliver Hunt.
+        
+        We've known for a while that our PutLocal situation was sub-optimal. We emit them anytime we
+        "pass" arguments to an inlined function call, because we need to enable the runtime to grab
+        those arguments when doing foo.arguments where foo is inlined: our engine doesn't deoptimize
+        in that case but rather just relies on the arguments being flushed (i.e. a copy of their
+        values is spilled) at a well-known place in a well-known format.
+        
+        The PutLocals incur two costs: (1) they are store instructions and stores ain't free, and (2)
+        they look like escaping sites and so they inhibit object allocation sinking.
+        
+        But in most cases, the PutLocals are unnecessary because the inlined code never performs any
+        side effect that could transitively lead to function.arguments. Even if the inlined code
+        could do such a side effect, it may be on a rare path so there is no need to penalize the
+        entire function.
+        
+        This patch implements one solution to the PutLocal problem: it aggressively sinks PutLocals
+        to the latest possible point. This is even more aggressive than the object allocation
+        sinking. That sinking algorithm avoids creating situations where an object could be
+        materialized more than one along any path. PutLocal sinking, on the other hand, doesn't avoid
+        this at all - both to make the phase cheaper and simpler and to make it more aggressive.
+        Every PutLocal is sunk no matter what.
+        
+        The upside of this patch is that it eliminates many PutLocals: many of them are sunk "past
+        their death", thus eliminating them completely. Others are sunk to rare paths. This enables a
+        lot of object allocation sinking and it removes a lot of pointless store instructions.
+        
+        It also has downsites. Sinking PutLocals increases register pressure because it increases the
+        live ranges of things like inlined arguments.
+        
+        This patch is a net performance win in its current form: 1% SunSpider regression, 2% OctaneV2
+        progression, 0.6% Kraken regression, 1% AsmBench progression, and 0.5% CompressionBench
+        regression. The biggest win is on Octane/raytrace, which improves by 27%.
+        
+        Relanding after fixing internal builds. We have to be careful about implicit casts from int64
+        to int32.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.h:
+        * bytecode/Operands.h:
+        (JSC::Operands::dump): Deleted.
+        * bytecode/OperandsInlines.h:
+        (JSC::Traits>::dump):
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::isHeader):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGClobberSet.h:
+        (JSC::DFG::ClobberSetAdd::operator()):
+        (JSC::DFG::ClobberSetOverlaps::operator()):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        (JSC::DFG::NoOpClobberize::operator()):
+        (JSC::DFG::CheckClobberize::operator()):
+        (JSC::DFG::AbstractHeapOverlaps::operator()):
+        (JSC::DFG::ReadMethodClobberize::operator()):
+        (JSC::DFG::WriteMethodClobberize::operator()):
+        (JSC::DFG::DefMethodClobberize::operator()):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::merge):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::capturedVarsFor):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPreciseLocalClobberize.h: Added.
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::PreciseLocalClobberizeAdaptor):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::read):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::write):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::callIfAppropriate):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop):
+        (JSC::DFG::forEachLocalReadByUnwind):
+        (JSC::DFG::preciseLocalClobberize):
+        * dfg/DFGPutLocalSinkingPhase.cpp: Added.
+        (JSC::DFG::performPutLocalSinking):
+        * dfg/DFGPutLocalSinkingPhase.h: Added.
+        * dfg/DFGSSACalculator.h:
+        (JSC::DFG::SSACalculator::computePhis):
+        * dfg/DFGValidate.cpp:
+
+2014-10-03  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r174216): CodeBlock::dumpByteCodes crashes on op_push_name_scope
+        https://bugs.webkit.org/show_bug.cgi?id=137412
+
+        Reviewed by Mark Lam.
+
+        Added support for the JSNameScope::type opcode parameter in dumpBytecode().
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+
+2014-10-03  Saam Barati  <saambarati1@gmail.com>
+
+        Implement op_profile_type in the 32-bit baseline JIT
+        https://bugs.webkit.org/show_bug.cgi?id=137181
+
+        Reviewed by Michael Saboff.
+
+        Generate inline code to write to the TypeProfilerLog inside the 32-bit 
+        baseline JIT instead of unconditionally bailing out to the slow path 
+        for op_profile_type.
+
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_profile_type):
+
+2014-10-03  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r174275.
+        https://bugs.webkit.org/show_bug.cgi?id=137408
+
+        Build failures on the internal bots. (Requested by dethbakin
+        on #webkit).
+
+        Reverted changeset:
+
+        "FTL should sink PutLocals"
+        https://bugs.webkit.org/show_bug.cgi?id=137168
+        http://trac.webkit.org/changeset/174275
+
+2014-10-03  Oliver Hunt  <oliver@apple.com>
+
+        tearoff_arguments should always refer to the unmodified arguments register
+        https://bugs.webkit.org/show_bug.cgi?id=137406
+
+        Reviewed by Michael Saboff.
+
+        To simplify subsequent work, and remove unnecessary work from
+        actual execution this patch simply ensures that tear_off_arguments
+        refers to the actual unmodified arguments register.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitReturn):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_tear_off_arguments):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_tear_off_arguments):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-10-03  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: Move the computation that results in UI strings from JSC to the Web Inspector
+        https://bugs.webkit.org/show_bug.cgi?id=137295
+
+        Reviewed by Timothy Hatcher.
+
+        Remove unnecessary functions and properties from JSC that are
+        now being computed inside the Web Inspector. 
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/protocol/Runtime.json:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::allPrimitiveTypeNames): Deleted.
+        * runtime/TypeSet.h:
+
+2014-10-02  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should sink PutLocals
+        https://bugs.webkit.org/show_bug.cgi?id=137168
+
+        Reviewed by Oliver Hunt.
+        
+        We've known for a while that our PutLocal situation was sub-optimal. We emit them anytime we
+        "pass" arguments to an inlined function call, because we need to enable the runtime to grab
+        those arguments when doing foo.arguments where foo is inlined: our engine doesn't deoptimize
+        in that case but rather just relies on the arguments being flushed (i.e. a copy of their
+        values is spilled) at a well-known place in a well-known format.
+        
+        The PutLocals incur two costs: (1) they are store instructions and stores ain't free, and (2)
+        they look like escaping sites and so they inhibit object allocation sinking.
+        
+        But in most cases, the PutLocals are unnecessary because the inlined code never performs any
+        side effect that could transitively lead to function.arguments. Even if the inlined code
+        could do such a side effect, it may be on a rare path so there is no need to penalize the
+        entire function.
+        
+        This patch implements one solution to the PutLocal problem: it aggressively sinks PutLocals
+        to the latest possible point. This is even more aggressive than the object allocation
+        sinking. That sinking algorithm avoids creating situations where an object could be
+        materialized more than one along any path. PutLocal sinking, on the other hand, doesn't avoid
+        this at all - both to make the phase cheaper and simpler and to make it more aggressive.
+        Every PutLocal is sunk no matter what.
+        
+        The upside of this patch is that it eliminates many PutLocals: many of them are sunk "past
+        their death", thus eliminating them completely. Others are sunk to rare paths. This enables a
+        lot of object allocation sinking and it removes a lot of pointless store instructions.
+        
+        It also has downsites. Sinking PutLocals increases register pressure because it increases the
+        live ranges of things like inlined arguments.
+        
+        This patch is a net performance win in its current form: 1% SunSpider regression, 2% OctaneV2
+        progression, 0.6% Kraken regression, 1% AsmBench progression, and 0.5% CompressionBench
+        regression. The biggest win is on Octane/raytrace, which improves by 27%.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.h:
+        * bytecode/Operands.h:
+        (JSC::Operands::dump): Deleted.
+        * bytecode/OperandsInlines.h:
+        (JSC::Traits>::dump):
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::isHeader):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGClobberSet.h:
+        (JSC::DFG::ClobberSetAdd::operator()):
+        (JSC::DFG::ClobberSetOverlaps::operator()):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        (JSC::DFG::NoOpClobberize::operator()):
+        (JSC::DFG::CheckClobberize::operator()):
+        (JSC::DFG::AbstractHeapOverlaps::operator()):
+        (JSC::DFG::ReadMethodClobberize::operator()):
+        (JSC::DFG::WriteMethodClobberize::operator()):
+        (JSC::DFG::DefMethodClobberize::operator()):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::merge):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::capturedVarsFor):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPreciseLocalClobberize.h: Added.
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::PreciseLocalClobberizeAdaptor):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::read):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::write):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::callIfAppropriate):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop):
+        (JSC::DFG::forEachLocalReadByUnwind):
+        (JSC::DFG::preciseLocalClobberize):
+        * dfg/DFGPutLocalSinkingPhase.cpp: Added.
+        (JSC::DFG::performPutLocalSinking):
+        * dfg/DFGPutLocalSinkingPhase.h: Added.
+        * dfg/DFGSSACalculator.h:
+        (JSC::DFG::SSACalculator::computePhis):
+        * dfg/DFGValidate.cpp:
+
+2014-10-03  Saam Barati  <saambarati1@gmail.com>
+
+        Change how 32-bit JSValues check if they are a Boolean
+
+        Rubber stamped by Filip Pizlo.
+
+        32-bit JSValue::isBoolean can simply check if its tag corresponds 
+        to the boolean tag instead of checking if it's either true or false.
+
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isBoolean):
+
+2014-10-01  Oliver Hunt  <oliver@apple.com>
+
+        Do all closed variable access through the local lexical object
+        https://bugs.webkit.org/show_bug.cgi?id=136869
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes all reads and writes from captured registers
+        go through the lexical record, and by doing so removes the
+        need for record tearoff.
+
+        To keep the patch simple we still number variables as though
+        they are local stack allocated registers, but ::local() will
+        fail. When local fails we perform a generic resolve, and in
+        that resolve we now use a ResolveScopeInfo struct to pass
+        around information about whether a lookup is a statically
+        known captured variable, and its location in the activation.
+        To ensure correct behaviour during codeblock linking we also
+        add a LocalClosureVariable resolution type.
+
+        To ensure correct semantics for the Arguments object, we now
+        have to eagerly create the Arguments object for any function
+        that uses both the Arguments object and requires a lexical
+        record.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeCapturedVariable):
+          During the entry to a function we are not yet in a position
+          to allocate temporaries so we directly use the lexical
+          environment register.
+        (JSC::BytecodeGenerator::resolveCallee):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::local):
+        (JSC::BytecodeGenerator::constLocal):
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitResolveConstantLocal):
+          The two resolve scope operations could technically skip
+          the op_resolve_scope, and simply perform 
+              op_mov dst, recordRegister
+          but for now it seemed best to maintain the same basic
+          behaviour.
+        (JSC::BytecodeGenerator::emitGetFromScope):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+          If we have an environment we've already created Arguments
+          so no need to check again.
+        (JSC::BytecodeGenerator::emitReturn):
+          Don't need to emit tearoff_environment
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::Local::Local):
+        (JSC::Local::operator bool):
+        (JSC::Local::get):
+        (JSC::Local::isReadOnly):
+        (JSC::Local::isSpecial):
+        (JSC::ResolveScopeInfo::ResolveScopeInfo):
+        (JSC::ResolveScopeInfo::isLocal):
+        (JSC::ResolveScopeInfo::localIndex):
+        (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly):
+        (JSC::Local::isCaptured): Deleted.
+        (JSC::Local::captureMode): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (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::EmptyVarExpression::emitBytecode):
+        (JSC::ForInNode::tryGetBoundLocal):
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::BindingNode::bindValue):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetRegisters):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_captured_mov): Deleted.
+        (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
+        (JSC::JIT::emitSlow_op_captured_mov): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_captured_mov): Deleted.
+        (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emit_op_get_from_scope):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_put_to_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emit_op_get_from_scope):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_put_to_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::tearOff):
+        * runtime/Arguments.h:
+        (JSC::Arguments::argument):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+        * runtime/CommonSlowPaths.h:
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::visitChildren):
+        (JSC::JSLexicalEnvironment::symbolTableGet):
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        (JSC::JSLexicalEnvironment::getOwnPropertySlot):
+        (JSC::JSLexicalEnvironment::argumentsGetter):
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        (JSC::JSLexicalEnvironment::tearOff): Deleted.
+        (JSC::JSLexicalEnvironment::isTornOff): Deleted.
+        * runtime/JSScope.cpp:
+        (JSC::resolveTypeName):
+        * runtime/JSScope.h:
+        (JSC::makeType):
+        (JSC::needsVarInjectionChecks):
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrier<Unknown>::WriteBarrier):
+
+2014-10-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Object allocation sinking should have a sound story for picking materialization points
+        https://bugs.webkit.org/show_bug.cgi?id=137315
+
+        Reviewed by Oliver Hunt.
+        
+        The only missing piece was having the object allocation sinking phase locate materialization
+        points that were at CFG edges.
+        
+        The logic for how and why this "just works" relies on some properties of critical edge
+        breaking, so I was fairly careful in how I did this. Also, this requires inserting things at
+        the "first origin node" of a block - that is the first node in a block that has a NodeOrigin
+        and therefore is allowed to exit. We basically had support for such a notion before, but
+        didn't close the loop on it; this patch does that.
+        
+        Also I added the ability to provide a BasicBlock* as context for a DFG_ASSERT().
+
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::firstOriginNode):
+        (JSC::DFG::BasicBlock::firstOrigin):
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::crash):
+        (JSC::DFG::Graph::handleAssertionFailure):
+        * dfg/DFGGraph.h:
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        * dfg/DFGNodeOrigin.h:
+        (JSC::DFG::NodeOrigin::isSet):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * runtime/Options.h:
+
+2014-10-02  Daniel Bates  <dabates@apple.com>
+
+        Clean up: Move XPC forward declarations in JavaScriptCore to WTF SPI wrapper header
+        https://bugs.webkit.org/show_bug.cgi?id=137277
+
+        Reviewed by Alexey Proskuryakov.
+
+        Use wtf/spi/darwin/XPCSPI.h instead of including the corresponding XPC headers/
+        forward declaring XPC functions.
+
+        * inspector/remote/RemoteInspector.mm:
+        * inspector/remote/RemoteInspectorXPCConnection.h:
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+
+2014-10-01  Anders Carlsson  <andersca@apple.com>
+
+        Use variadic templates for jsMakeNontrivialString
+        https://bugs.webkit.org/show_bug.cgi?id=137325
+
+        Reviewed by Sam Weinig.
+
+        * runtime/JSString.h:
+        (JSC::jsNontrivialString):
+        Add an overload that takes an rvalue reference to a String so we can transfer ownership easily.
+
+        * runtime/JSStringBuilder.h:
+        (JSC::jsMakeNontrivialString):
+        Make this a variadic function template, with a single-parameter version that can steal the string if it's OK to do so.
+
+2014-10-02  Mark Lam  <mark.lam@apple.com>
+
+        Fixed the Inspector to be able to properly distinguish between scope types.
+        <https://webkit.org/b/137279>
+
+        Reviewed by Geoffrey Garen.
+
+        The pre-existing code incorrectly labels Catch Scopes and Function Name Scopes
+        as With Scopes.  This patch will fix this.
+
+        * bytecode/BytecodeList.json:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        - These now passes stores the desired JSNameScope::Type in a bytecode operand.
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::isCatchScope):
+        (JSC::DebuggerScope::isFunctionNameScope):
+        - Added queries to be able to explicitly test if the scope is a CatchScope
+          or FunctionNameScope.  The FunctionNameScope is the case where the
+          NameScope is used to capture the function name of a function expression.
+        * debugger/DebuggerScope.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::scopeType):
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        (Inspector::JSJavaScriptCallFramePrototype::finishCreation):
+        (Inspector::jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE):
+        * inspector/protocol/Debugger.json:
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::addNameScopeIfNeeded):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::isFunctionNameScope):
+        (JSC::JSNameScope::isCatchScope):
+        (JSC::JSNameScope::JSNameScope):
+        - Now stores the JSNameScope::Type in a field.
+
+2014-10-01  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r174180, r174183, and r174186.
+        https://bugs.webkit.org/show_bug.cgi?id=137320
+
+        Broke the Mac MountainLion build. Will investigate offline.
+        (Requested by dydz on #webkit).
+
+        Reverted changesets:
+
+        "Clean up: Move XPC forward declarations in JavaScriptCore to
+        WTF SPI wrapper header"
+        https://bugs.webkit.org/show_bug.cgi?id=137277
+        http://trac.webkit.org/changeset/174180
+
+        "Attempt to fix the build after
+        <https://trac.webkit.org/changeset/174180>"
+        https://bugs.webkit.org/show_bug.cgi?id=137277
+        http://trac.webkit.org/changeset/174183
+
+        "Another attempt to fix the Mac build after
+        <https://trac.webkit.org/changeset/174180>"
+        https://bugs.webkit.org/show_bug.cgi?id=137277
+        http://trac.webkit.org/changeset/174186
+
+2014-10-01  Daniel Bates  <dabates@apple.com>
+
+        Clean up: Move XPC forward declarations in JavaScriptCore to WTF SPI wrapper header
+        https://bugs.webkit.org/show_bug.cgi?id=137277
+
+        Reviewed by Alexey Proskuryakov.
+
+        Use wtf/spi/darwin/XPCSPI.h instead of including the corresponding XPC headers/
+        forward declaring XPC functions.
+
+        * inspector/remote/RemoteInspector.mm:
+        * inspector/remote/RemoteInspectorXPCConnection.h:
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+
+2014-10-01  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed build gardening.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Show files in the appropriate
+        folders in Visual Studio.
+
+2014-10-01  Filip Pizlo  <fpizlo@apple.com>
+
+        Object allocation sinking is broken for escaping sites in loops
+        https://bugs.webkit.org/show_bug.cgi?id=137310
+
+        Reviewed by Michael Saboff.
+        
+        I tried to do this clever forward-flow based materialization point placement, and I messed up loops. Disabling
+        the phase for now and landing a test to demonstrate what it going on.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * runtime/Options.h:
+        * tests/stress/object-escapes-in-loop.js: Added.
+        (foo):
+        (bar):
+
+2014-10-01  Saam Barati  <saambarati1@gmail.com>
+
+        Support the type profiler in the DFG
+        https://bugs.webkit.org/show_bug.cgi?id=136712
+
+        Reviewed by Filip Pizlo.
+
+        This patch implements op_profile_type inside the DFG as the node: ProfileType.
+        The DFG will convert the ProfileType node into a Check node in the cases where
+        passing a type check is equivalent to writing to the TypeProfilerLog. This
+        gives the DFG the potential to optimize out multiple ProfileType nodes into
+        a single Check node.
+
+        When the DFG doesn't convert ProfileType into a Check node, it will generate
+        the same inline code as the baseline JIT does for writing an entry to the
+        TypeProfilerLog.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::typeLocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::logTypesForTypeLocation):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::dumpTypes):
+        (JSC::TypeSet::doesTypeConformTo):
+        Make this method public so others can reason about the types a TypeSet has seen.
+        (JSC::TypeSet::seenTypes): Deleted.
+        (JSC::TypeSet::dumpSeenTypes): Deleted.
+        Renamed to dumpTypes so the method seenTypes can be used as a public getter.
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::seenTypes):
+        * tests/typeProfiler/dfg-jit-optimizations.js: Added.
+        (tierUpToDFG):
+        (funcs):
+        (.return):
+
+2014-10-01  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix 32-bit.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-09-30  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG SSA should use PutLocal/KillLocal instead of SetLocal to communicate what is flushed to the stack and when
+        https://bugs.webkit.org/show_bug.cgi?id=137242
+
+        Reviewed by Geoffrey Garen.
+        
+        OSR availability has to do with telling you the various ways that you could go about getting
+        the value of a bytecode variable. It can give you two options: node availability means that
+        there is a node in the DFG IR that has the right value, and flush availability tells you
+        that the value was already stored to the stack. The clients of OSR availability would
+        typically prefer flush over node availability.
+        
+        Previously OSR availability was affected thusly by the various local-related nodes: SetLocal
+        set both the node and flush availability, MovHint set node availability and cleared flush
+        availability, GetArgument set both, and ZombieHint cleared both.
+        
+        A MovHint could be turned into a ZombieHint if its source value was DCEd.
+        
+        The fact that each node affected both node and flush availability caused weirdness. For
+        example it meant that we could not insert MovHints in areas of the CFG where a SetLocal's
+        variable was still live, because then those parts of the code would forget that they had an
+        availability flush. This meant that if a flush was available, we wouldn't insert MovHints,
+        and so we would forget that a node was in fact available. This kind of "either-or" picking
+        was not only hackish but it led to interesting problems for IR transformation: for example
+        if you tried to do any kind of code motion on SetLocals, you had to be super careful because
+        you might violate the rule that "MovHints must exist for a live local if a flush is
+        unavailable".
+        
+        The right thing to do is to have independent nodes for flushing and making nodes available.
+        They shouldn't interact with each other. This patch accomplishes this:
+        
+        - PutLocal means that that a value is to be stored to the stack. It makes a flush available.
+        - KillLocal means that the value stored to the stack is no longer available for the purposes
+          of OSR (i.e. it no longer accurately corresponds to what that actual bytecode variable
+          would have been, so you have to fall back on node availability).
+        - MovHint means that a node is available. It has no effect on flush availability.
+        - ZombieHint means that a node is not available. It has no effect on flush availability.
+        
+        This means that we will see a lot of KillLocals and MovHints right next to each other. It's
+        a bit verbose, but at least it's precise.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAvailability.h:
+        (JSC::DFG::Availability::setFlush):
+        (JSC::DFG::Availability::setNode):
+        (JSC::DFG::Availability::setNodeUnavailable):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::hasVariableAccessData):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasUnlinkedLocal):
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePutLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileSetLocal): Deleted.
+
+2014-10-01  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] 32-bit JavaScriptCore should limit itself to the C loop
+        https://bugs.webkit.org/show_bug.cgi?id=137304
+        <rdar://problem/18375370>
+
+        Reviewed by Michael Saboff.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl:
+        Use the C loop for 32-bit builds.
+
+2014-09-30  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: ErrorString should be passed by reference
+        https://bugs.webkit.org/show_bug.cgi?id=137257
+
+        Reviewed by Joseph Pecoraro.
+
+        Pass the leading ErrorString argument by reference, since it is always an out parameter.
+        Clean up callsites where the error message is written.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::evaluate):
+        (Inspector::InjectedScript::callFunctionOn):
+        (Inspector::InjectedScript::evaluateOnCallFrame):
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall):
+        * inspector/InjectedScriptBase.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorAgent::enable):
+        (Inspector::InspectorAgent::disable):
+        (Inspector::InspectorAgent::initialized):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::disable):
+        (Inspector::InspectorConsoleAgent::clearMessages):
+        (Inspector::InspectorConsoleAgent::reset):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        * inspector/agents/InspectorConsoleAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::enable):
+        (Inspector::InspectorDebuggerAgent::disable):
+        (Inspector::InspectorDebuggerAgent::setBreakpointsActive):
+        (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::parseLocation):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::removeBreakpoint):
+        (Inspector::InspectorDebuggerAgent::continueToLocation):
+        (Inspector::InspectorDebuggerAgent::searchInContent):
+        (Inspector::InspectorDebuggerAgent::getScriptSource):
+        (Inspector::InspectorDebuggerAgent::getFunctionDetails):
+        (Inspector::InspectorDebuggerAgent::pause):
+        (Inspector::InspectorDebuggerAgent::resume):
+        (Inspector::InspectorDebuggerAgent::stepOver):
+        (Inspector::InspectorDebuggerAgent::stepInto):
+        (Inspector::InspectorDebuggerAgent::stepOut):
+        (Inspector::InspectorDebuggerAgent::setPauseOnExceptions):
+        (Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
+        (Inspector::InspectorDebuggerAgent::setOverlayMessage):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
+        (Inspector::InspectorDebuggerAgent::assertPaused):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::parse):
+        (Inspector::InspectorRuntimeAgent::evaluate):
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        (Inspector::InspectorRuntimeAgent::releaseObject):
+        (Inspector::InspectorRuntimeAgent::releaseObjectGroup):
+        (Inspector::InspectorRuntimeAgent::run):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::InspectorRuntimeAgent::enableTypeProfiler):
+        (Inspector::InspectorRuntimeAgent::disableTypeProfiler):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/JSGlobalObjectConsoleAgent.cpp:
+        (Inspector::JSGlobalObjectConsoleAgent::setMonitoringXHREnabled):
+        (Inspector::JSGlobalObjectConsoleAgent::addInspectedNode):
+        * inspector/agents/JSGlobalObjectConsoleAgent.h:
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::injectedScriptForEval):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
+        (Inspector::JSGlobalObjectRuntimeAgent::injectedScriptForEval):
+        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator._generate_handler_declaration_for_command):
+        (BackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+
+2014-09-30  Mark Lam  <mark.lam@apple.com>
+
+        Label some asserts as having security implications.
+        <https://webkit.org/b/137260>
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::handleAssertionFailure):
+        * runtime/JSCell.h:
+        (JSC::jsCast):
+        * runtime/StructureIDTable.h:
+        (JSC::StructureIDTable::get):
+
+2014-09-30  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION (r174025): Invalid cast in JSC::asString
+        https://bugs.webkit.org/show_bug.cgi?id=137224
+
+        Reviewed by Geoffrey Garen.
+        
+        Store barrier elision in fixup depends on checking the type of the value being stored. It's very important that
+        when we speak of "the value being stored" we are really referring to the right value.
+        
+        The bug here was that the PutClosureVar case was assuming that child2 is the value being stored. It's actually
+        child3. So we were incorrectly removing all barriers from PutClosureVar.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+2014-09-30  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: use static Strings instead of AtomicStrings for replay input type tags
+        https://bugs.webkit.org/show_bug.cgi?id=137086
+
+        Reviewed by Joseph Pecoraro.
+
+        This pattern doesn't work when we want to define some inputs in WebKit2.
+        The ReplayInputTypes class was generated from WebCore inputs only. This
+        patch moves all input traits to use static local Strings as type tags.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py: Remove configuration of how
+        type tags are generated, since all framework targets now generate the same code.
+
+        * replay/NondeterministicInput.h:
+        * replay/scripts/CodeGeneratorReplayInputs.py: Simplify and rebase test results.
+        (Generator.generate_input_trait_implementation):
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py: Simplify templates.
+
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::SavedMouseButton>::type):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::SavedMouseButton>::type):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::HandleWheelEvent>::type):
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::FormCombo>::type):
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::GetCurrentTime>::type):
+        (JSC::InputTraits<Test::SetRandomSeed>::type):
+        * replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::ArrayOfThings>::type):
+        (JSC::InputTraits<Test::SavedHistory>::type):
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::ScalarInput1>::type):
+        (JSC::InputTraits<Test::ScalarInput2>::type):
+        * replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.cpp:
+        (JSC::InputTraits<Test::ScalarInput>::type):
+        (JSC::InputTraits<Test::MapInput>::type):
+        * replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.h:
+
+2014-09-30  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION (r172532): JSBase.h declares NSMapTable functions that are SPI
+        https://bugs.webkit.org/show_bug.cgi?id=137170
+        <rdar://problem/18477384>
+
+        Reviewed by Geoffrey Garen.
+
+        Move conditional include of header Foundation/NSMapTablePriv.h and forward declarations
+        of NSMapTable SPI from file JavaScriptCore/API/JSBase.h to WTF/wtf/spi/cocoa/NSMapTableSPI.h.
+
+        * API/JSBase.h:
+        * API/JSManagedValue.mm: Include header WTF/wtf/spi/cocoa/NSMapTableSPI.h.
+        * API/JSVirtualMachine.mm: Ditto.
+        * API/JSVirtualMachineInternal.h: Forward declare class NSMapTable.
+        * API/JSWrapperMap.mm: Include header WTF/wtf/spi/cocoa/NSMapTableSPI.h. Also, order
+        #include directives such that they are sorted in alphabetical order.
+
+2014-09-30  Oliver Hunt  <oliver@apple.com>
+
+        Fix C API header
+        https://bugs.webkit.org/show_bug.cgi?id=137254
+        <rdar://problem/18487528>
+
+        Build fix
+
+        Guard extern "C" behind __cplusplus ifdef
+
+        * API/JSBase.h:
+
+2014-09-29  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: InjectedScripts should not be profiled or displayed in Timeline
+        https://bugs.webkit.org/show_bug.cgi?id=136806
+
+        Reviewed by Timothy Hatcher.
+
+        It doesn't make sense to show profile nodes for injected scripts when profiling user content.
+        For now, omit nodes by suspending profiling before and after executing injected scripts.
+
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::suspendProfiling): Added.
+        (JSC::LegacyProfiler::unsuspendProfiling): Added.
+        * profiler/LegacyProfiler.h:
+        * profiler/ProfileGenerator.cpp: Add isSuspended() flag, remove unused typedef.
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::ProfileGenerator::willExecute):
+        (JSC::ProfileGenerator::didExecute):
+        * profiler/ProfileGenerator.h:
+        (JSC::ProfileGenerator::setIsSuspended): Added.
+
+2014-09-29  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: InspectorValues should use references for out parameters
+        https://bugs.webkit.org/show_bug.cgi?id=137190
+
+        Reviewed by Joseph Pecoraro.
+
+        Use references for out parameters in asType() and getType() methods.
+        Also convert to references in some miscellaneous code where we don't
+        expect or handle null values.
+
+        Remove variants of asObject() and asArray() that return a nullable RefPtr.
+        Now, client code is forced to use out parameters and check for cast failure.
+
+        Iron out control flow in some functions and fix some style issues.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::wrapObject):
+        (Inspector::InjectedScript::wrapTable):
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall):
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::injectedScriptForObjectId): Simplify control flow.
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::InspectorBackendDispatcher::dispatch):
+        (Inspector::getPropertyValue):
+        (Inspector::AsMethodBridges::asInteger):
+        (Inspector::AsMethodBridges::asDouble):
+        (Inspector::AsMethodBridges::asString):
+        (Inspector::AsMethodBridges::asBoolean):
+        (Inspector::AsMethodBridges::asObject):
+        (Inspector::AsMethodBridges::asArray):
+        * inspector/InspectorProtocolTypes.h:
+        (Inspector::Protocol::BindingTraits<Protocol::Array<T>>::runtimeCast):
+        (Inspector::Protocol::BindingTraits<Protocol::Array<T>>::assertValueHasExpectedType):
+        * inspector/InspectorValues.cpp: Use more by-reference out parameters. Add more spacing.
+        (Inspector::InspectorValue::asBoolean):
+        (Inspector::InspectorValue::asDouble):
+        (Inspector::InspectorValue::asInteger):
+        (Inspector::InspectorValue::asString):
+        (Inspector::InspectorValue::asValue):
+        (Inspector::InspectorValue::asObject):
+        (Inspector::InspectorValue::asArray):
+        (Inspector::InspectorValue::parseJSON):
+        (Inspector::InspectorValue::toJSONString):
+        (Inspector::InspectorValue::writeJSON):
+        (Inspector::InspectorBasicValue::asBoolean):
+        (Inspector::InspectorBasicValue::asDouble):
+        (Inspector::InspectorBasicValue::asInteger):
+        (Inspector::InspectorBasicValue::writeJSON):
+        (Inspector::InspectorString::asString):
+        (Inspector::InspectorString::writeJSON):
+        (Inspector::InspectorObjectBase::asObject):
+        (Inspector::InspectorObjectBase::openAccessors):
+        (Inspector::InspectorObjectBase::getBoolean):
+        (Inspector::InspectorObjectBase::getString):
+        (Inspector::InspectorObjectBase::getObject):
+        (Inspector::InspectorObjectBase::getArray):
+        (Inspector::InspectorObjectBase::writeJSON):
+        (Inspector::InspectorArrayBase::asArray):
+        (Inspector::InspectorArrayBase::writeJSON):
+        * inspector/InspectorValues.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::parseLocation):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::continueToLocation):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/scripts/codegen/generate_protocol_types_implementation.py:
+        (ProtocolTypesImplementationGenerator):
+        (ProtocolTypesImplementationGenerator._generate_assertion_for_enum):
+        * inspector/scripts/codegen/generator_templates.py:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::asObject):
+        (JSC::EncodedValue::asArray):
+        (JSC::EncodedValue::convertTo<bool>):
+        (JSC::EncodedValue::convertTo<double>):
+        (JSC::EncodedValue::convertTo<float>):
+        (JSC::EncodedValue::convertTo<int32_t>):
+        (JSC::EncodedValue::convertTo<int64_t>):
+        (JSC::EncodedValue::convertTo<uint32_t>):
+        (JSC::EncodedValue::convertTo<uint64_t>):
+        (JSC::EncodedValue::convertTo<String>):
+
+2014-09-29  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG HasStructureProperty codegen should use one fewer registers
+        https://bugs.webkit.org/show_bug.cgi?id=137235
+
+        Reviewed by Andreas Kling.
+        
+        This was an obvious source of inefficiency and it was causing us to run out of registers on
+        x86-32.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-09-29  Filip Pizlo  <fpizlo@apple.com>
+
+        Don't use GPRResult unless you're flushing registers and making a runtime function call
+        https://bugs.webkit.org/show_bug.cgi?id=137234
+
+        Rubber stamped by Andreas Kling.
+
+        Rename GPRResult to GPRFlushedCallResult, in an attempt to dissuade people from using it for results in the
+        general case.
+        
+        Replace GPRResult with GPRTemporary in those places where it was causing bugs: particularly in GetDirectPname it
+        would cause us to spill the register that has the base, and the code was assuming (rightly) that the base and the
+        result were in different registers. That's a valid assumption when using GPRTemporary but not with GPRResult.
+        Also this code wasn't getting any benefit from using GPRResult because it wasn't doing flushRegisters().
+        
+        I don't know how to test this. A test would require setting up a particularly awkward register allocation state.
+        
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+        (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+        (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+        (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::GPRFlushedCallResult::GPRFlushedCallResult):
+        (JSC::DFG::GPRFlushedCallResult2::GPRFlushedCallResult2):
+        (JSC::DFG::GPRResult::GPRResult): Deleted.
+        (JSC::DFG::GPRResult2::GPRResult2): Deleted.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepMachineInt):
+
+2014-09-29  Diego Pino Garcia  <dpino@igalia.com>
+
+        Missing changes from r174049
+        https://bugs.webkit.org/show_bug.cgi?id=137206
+
+        Reviewed by Darin Adler.
+
+        * runtime/CommonIdentifiers.h:
+
+2014-09-28  Diego Pino Garcia  <dpino@igalia.com>
+
+        Simple ES6 feature: Number constructor extras
+        https://bugs.webkit.org/show_bug.cgi?id=131707
+
+        Reviewed by Darin Adler.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation): Setup constants and
+        functions.
+        (JSC::numberConstructorFuncIsFinite): Added.
+        (JSC::numberConstructorFuncIsInteger): Added.
+        (JSC::numberConstructorFuncIsNaN): Added.
+        (JSC::numberConstructorFuncIsSafeInteger): Added.
+        (JSC::NumberConstructor::getOwnPropertySlot): Deleted.
+        (JSC::numberConstructorNaNValue): Deleted.
+        (JSC::numberConstructorNegInfinity): Deleted.
+        (JSC::numberConstructorPosInfinity): Deleted.
+        (JSC::numberConstructorMaxValue): Deleted.
+        (JSC::numberConstructorMinValue): Deleted.
+        * runtime/NumberConstructor.h:
+
+2014-09-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Disable function.arguments
+        https://bugs.webkit.org/show_bug.cgi?id=137167
+
+        Rubber stamped by Geoffrey Garen.
+        
+        Add an option to disable function.arguments. Add a test for disabling it.
+        
+        Disabling function.arguments means that it returns an Arguments object that claims that
+        there were zero arguments. All other Arguments functionality still works, so any code
+        that tries to inspect this object will still think that it is looking at a perfectly
+        valid Arguments object.
+        
+        This also makes function.arguments disabled by default. Note that the RJST harness will
+        enable them by default, to continue to get test coverage for the code that implements
+        the feature.
+        
+        We will rip out that code once we're confident that it's really safe to remove this
+        feature. Only once we rip out that support will we be able to do optimizations to
+        leverage the lack of this feature. It's important to keep the support code, and the test
+        infrastructure, in place before we are confident. The logic to keep this working touches
+        the entire compiler and a large chunk of the runtime, so reimplementing it - or even
+        merging it back in - would be a nightmare. That's also basically the reason why we want
+        to rip it out if at all possible. It's a lot of terrible code.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        * runtime/Arguments.h:
+        (JSC::Arguments::create):
+        (JSC::Arguments::finishCreation):
+        * runtime/Options.h:
+        * tests/stress/disable-function-dot-arguments.js: Added.
+        (foo):
+        (bar):
+
+2014-09-26  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Automatic Inspection should continue once all breakpoints are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=137038
+
+        Reviewed by Timothy Hatcher.
+
+        Add a new protocol command "Inspector.initialized" that signifies to the backend
+        when the frontend has sent all its initialization messages to the backend. This
+        can include information like breakpoints, which we would want to have loaded
+        before any JavaScript evaluates in the context.
+
+        * inspector/protocol/InspectorDomain.json:
+        New protocol command, Inspector.initialized.
+
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::InspectorAgent):
+        (Inspector::InspectorAgent::initialized):
+        Tell the InspectorEnvironment (the Controller) the frontend has initialized.
+
+        * inspector/InspectorEnvironment.h:
+        Abstract virtual method to handle frontend initialization. To be
+        implemented by all of the InspectorControllers.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::frontendInitialized):
+        When a frontend is initialized, if it was automatic inspection unpause the debuggable.
+
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::unpauseForInitializedInspector):
+        Complete setup for this debuggable.
+
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        Move the setup complete to later, when the frontend sends an "initialized" message.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
+        Provide a longer timeout now that the frontend must send messages after the connection
+        has established. The longest I have seen in  600ms, but the average tends to be 200ms.
+        So bump the timeout to 800ms for a buffer.
+
+        (Inspector::RemoteInspector::setupSucceeded): Deleted.
+        (Inspector::RemoteInspector::setupCompleted):
+        Rename, as this happens at a slightly different time.
+
+2014-09-26  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG shouldn't insert store barriers when it has it on good authority that we're not storing a cell
+        https://bugs.webkit.org/show_bug.cgi?id=137161
+
+        Reviewed by Mark Hahnenberg.
+        
+        This looks like a 1% Octane speed-up.
+
+        * bytecode/SpeculatedType.h:
+        (JSC::isNotCellSpeculation):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertStoreBarrier):
+        (JSC::DFG::FixupPhase::insertCheck):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateNotCell):
+
+2014-09-26  Peter Varga  <pvarga@webkit.org>
+
+        Fix typo in YARR at BOL check
+        https://bugs.webkit.org/show_bug.cgi?id=137144
+
+        Reviewed by Darin Adler.
+
+        * yarr/YarrPattern.cpp: replace bitwise and operator by logical and
+        (JSC::Yarr::YarrPatternConstructor::assertionBOL):
+
+2014-09-25  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: console.assert(bitString) TypeSet:50 
+        https://bugs.webkit.org/show_bug.cgi?id=137051
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch creates stricter requirements on a TypeDescription
+        being valid. To be valid, a TypeDescription now ensures that 
+        the TypeSet it describes has non null type information.
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::isEmpty):
+
+2014-09-25  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should sink object allocations
+        https://bugs.webkit.org/show_bug.cgi?id=136330
+
+        Reviewed by Oliver Hunt.
+        
+        This adds a comprehensive infrastructure for sinking object allocations in DFG SSA form. The
+        ultimate goal of sinking is to sink an allocation "past the points of its death" - i.e. to
+        eliminate it completely. The way sinking reasons about the CFG means that it resembles a
+        partial escape analysis: we create paths through a function where some allocation(s) don't
+        have to be done at all even if there are other paths along which those allocations still have
+        to happen. But it also produces other side benefits. Even if an allocation isn't eliminated
+        along any path, the act of sinking reduces the number of barriers that have to execute.
+        
+        Because this was a fairly ambituous SSA analysis and transformation, I added a bunch of C++11
+        sugar to the DFG's internal APIs to allow for easier iteration over blocks, nodes, and
+        successors; and to add more functor goodness to allow for more lambdas.
+        
+        This is just the beginning. The bug has a bunch of other bugs that depend on it. So far this
+        is a spectacular speed-up on microbenchmarks but it's still too limited to affect big
+        benchmarks. For example, doing o == p makes the sinking phase think that o and p escape.
+        That's just an omission and there are likely others; we can easily fix them. I think it's
+        best to land it in its current form and then to worry about the big benchmarks in subsequent
+        work (see bug 137126).
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::iterator::iterator):
+        (JSC::StructureSet::iterator::operator*):
+        (JSC::StructureSet::iterator::operator++):
+        (JSC::StructureSet::iterator::operator==):
+        (JSC::StructureSet::iterator::operator!=):
+        (JSC::StructureSet::begin):
+        (JSC::StructureSet::end):
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::phiChildren):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::AbstractInterpreter):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::execute):
+        * dfg/DFGAvailability.h:
+        (JSC::DFG::Availability::shouldUseNode):
+        (JSC::DFG::Availability::isFlushUseful):
+        (JSC::DFG::Availability::isDead):
+        (JSC::DFG::Availability::operator!=):
+        * dfg/DFGAvailabilityMap.cpp: Added.
+        (JSC::DFG::AvailabilityMap::prune):
+        (JSC::DFG::AvailabilityMap::clear):
+        (JSC::DFG::AvailabilityMap::dump):
+        (JSC::DFG::AvailabilityMap::operator==):
+        (JSC::DFG::AvailabilityMap::merge):
+        * dfg/DFGAvailabilityMap.h: Added.
+        (JSC::DFG::AvailabilityMap::forEachAvailability):
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::SSAData::SSAData):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::begin):
+        (JSC::DFG::BasicBlock::end):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::SuccessorsIterable):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::iterator):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator*):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator++):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator==):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator!=):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::begin):
+        (JSC::DFG::BasicBlock::SuccessorsIterable::end):
+        (JSC::DFG::BasicBlock::successors):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushedAt.cpp:
+        (JSC::DFG::FlushedAt::dump):
+        * dfg/DFGFlushedAt.h:
+        (JSC::DFG::FlushedAt::FlushedAt):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::mergeRelevantToOSR):
+        (JSC::DFG::Graph::invalidateCFG):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::NaturalBlockIterable::NaturalBlockIterable):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::iterator):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator*):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator++):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator==):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator!=):
+        (JSC::DFG::Graph::NaturalBlockIterable::iterator::findNext):
+        (JSC::DFG::Graph::NaturalBlockIterable::begin):
+        (JSC::DFG::Graph::NaturalBlockIterable::end):
+        (JSC::DFG::Graph::blocksInNaturalOrder):
+        (JSC::DFG::Graph::doToChildrenWithNode):
+        (JSC::DFG::Graph::doToChildren):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGInsertOSRHintsForUpdate.cpp: Added.
+        (JSC::DFG::insertOSRHintsForUpdate):
+        * dfg/DFGInsertOSRHintsForUpdate.h: Added.
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::graph):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPutByOffsetHint):
+        (JSC::DFG::Node::convertToPutStructureHint):
+        (JSC::DFG::Node::convertToPhantomNewObject):
+        (JSC::DFG::Node::isCellConstant):
+        (JSC::DFG::Node::castConstant):
+        (JSC::DFG::Node::hasIdentifier):
+        (JSC::DFG::Node::hasStorageAccessData):
+        (JSC::DFG::Node::hasObjectMaterializationData):
+        (JSC::DFG::Node::objectMaterializationData):
+        (JSC::DFG::Node::isPhantomObjectAllocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::endBlock):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRAvailabilityAnalysisPhase.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp: Added.
+        (JSC::DFG::ObjectAllocationSinkingPhase::ObjectAllocationSinkingPhase):
+        (JSC::DFG::ObjectAllocationSinkingPhase::run):
+        (JSC::DFG::ObjectAllocationSinkingPhase::performSinking):
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        (JSC::DFG::ObjectAllocationSinkingPhase::resolve):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
+        (JSC::DFG::performObjectAllocationSinking):
+        * dfg/DFGObjectAllocationSinkingPhase.h: Added.
+        * dfg/DFGObjectMaterializationData.cpp: Added.
+        (JSC::DFG::PhantomPropertyValue::dump):
+        (JSC::DFG::ObjectMaterializationData::dump):
+        (JSC::DFG::ObjectMaterializationData::oneWaySimilarityScore):
+        (JSC::DFG::ObjectMaterializationData::similarityScore):
+        * dfg/DFGObjectMaterializationData.h: Added.
+        (JSC::DFG::PhantomPropertyValue::PhantomPropertyValue):
+        (JSC::DFG::PhantomPropertyValue::operator==):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPhiChildren.cpp: Added.
+        (JSC::DFG::PhiChildren::PhiChildren):
+        (JSC::DFG::PhiChildren::~PhiChildren):
+        (JSC::DFG::PhiChildren::upsilonsOf):
+        * dfg/DFGPhiChildren.h: Added.
+        (JSC::DFG::PhiChildren::forAllIncomingValues):
+        (JSC::DFG::PhiChildren::forAllTransitiveIncomingValues):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPrePostNumbering.cpp: Added.
+        (JSC::DFG::PrePostNumbering::PrePostNumbering):
+        (JSC::DFG::PrePostNumbering::~PrePostNumbering):
+        (JSC::DFG::PrePostNumbering::compute):
+        (WTF::printInternal):
+        * dfg/DFGPrePostNumbering.h: Added.
+        (JSC::DFG::PrePostNumbering::preNumber):
+        (JSC::DFG::PrePostNumbering::postNumber):
+        (JSC::DFG::PrePostNumbering::isStrictAncestorOf):
+        (JSC::DFG::PrePostNumbering::isAncestorOf):
+        (JSC::DFG::PrePostNumbering::isStrictDescendantOf):
+        (JSC::DFG::PrePostNumbering::isDescendantOf):
+        (JSC::DFG::PrePostNumbering::edgeKind):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPromoteHeapAccess.h: Added.
+        (JSC::DFG::promoteHeapAccess):
+        * dfg/DFGPromotedHeapLocation.cpp: Added.
+        (JSC::DFG::PromotedLocationDescriptor::dump):
+        (JSC::DFG::PromotedHeapLocation::createHint):
+        (JSC::DFG::PromotedHeapLocation::dump):
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h: Added.
+        (JSC::DFG::PromotedLocationDescriptor::PromotedLocationDescriptor):
+        (JSC::DFG::PromotedLocationDescriptor::operator!):
+        (JSC::DFG::PromotedLocationDescriptor::kind):
+        (JSC::DFG::PromotedLocationDescriptor::info):
+        (JSC::DFG::PromotedLocationDescriptor::hash):
+        (JSC::DFG::PromotedLocationDescriptor::operator==):
+        (JSC::DFG::PromotedLocationDescriptor::operator!=):
+        (JSC::DFG::PromotedLocationDescriptor::isHashTableDeletedValue):
+        (JSC::DFG::PromotedHeapLocation::PromotedHeapLocation):
+        (JSC::DFG::PromotedHeapLocation::operator!):
+        (JSC::DFG::PromotedHeapLocation::kind):
+        (JSC::DFG::PromotedHeapLocation::base):
+        (JSC::DFG::PromotedHeapLocation::info):
+        (JSC::DFG::PromotedHeapLocation::descriptor):
+        (JSC::DFG::PromotedHeapLocation::hash):
+        (JSC::DFG::PromotedHeapLocation::operator==):
+        (JSC::DFG::PromotedHeapLocation::isHashTableDeletedValue):
+        (JSC::DFG::PromotedHeapLocationHash::hash):
+        (JSC::DFG::PromotedHeapLocationHash::equal):
+        * dfg/DFGSSACalculator.cpp:
+        (JSC::DFG::SSACalculator::reset):
+        * dfg/DFGSSACalculator.h:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLExitPropertyValue.cpp: Added.
+        (JSC::FTL::ExitPropertyValue::dump):
+        * ftl/FTLExitPropertyValue.h: Added.
+        (JSC::FTL::ExitPropertyValue::ExitPropertyValue):
+        (JSC::FTL::ExitPropertyValue::operator!):
+        (JSC::FTL::ExitPropertyValue::location):
+        (JSC::FTL::ExitPropertyValue::value):
+        * ftl/FTLExitTimeObjectMaterialization.cpp: Added.
+        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::add):
+        (JSC::FTL::ExitTimeObjectMaterialization::get):
+        (JSC::FTL::ExitTimeObjectMaterialization::dump):
+        * ftl/FTLExitTimeObjectMaterialization.h: Added.
+        (JSC::FTL::ExitTimeObjectMaterialization::type):
+        (JSC::FTL::ExitTimeObjectMaterialization::properties):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::materializeNewObject):
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::isObjectMaterialization):
+        (JSC::FTL::ExitValue::objectMaterialization):
+        (JSC::FTL::ExitValue::withVirtualRegister):
+        (JSC::FTL::ExitValue::valueFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileNewObject):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructureImmediate):
+        (JSC::FTL::LowerDFGToLLVM::compileMaterializeNewObject):
+        (JSC::FTL::LowerDFGToLLVM::checkStructure):
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+        (JSC::FTL::LowerDFGToLLVM::storeStructure):
+        (JSC::FTL::LowerDFGToLLVM::allocateObject):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::weakStructureID):
+        (JSC::FTL::LowerDFGToLLVM::weakStructure):
+        (JSC::FTL::LowerDFGToLLVM::availabilityMap):
+        (JSC::FTL::LowerDFGToLLVM::availability): Deleted.
+        * ftl/FTLOSRExit.h:
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileRecovery):
+        (JSC::FTL::compileStub):
+        * ftl/FTLOperations.cpp: Added.
+        (JSC::FTL::operationNewObjectWithButterfly):
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * ftl/FTLOperations.h: Added.
+        * ftl/FTLSwitchCase.h:
+        (JSC::FTL::SwitchCase::SwitchCase):
+        * runtime/JSObject.h:
+        (JSC::JSObject::finishCreation):
+        (JSC::JSFinalObject::JSFinalObject):
+        (JSC::JSFinalObject::create):
+        * runtime/Structure.cpp:
+        (JSC::Structure::canUseForAllocationsOf):
+        * runtime/Structure.h:
+        * tests/stress/elidable-new-object-roflcopter-then-exit.js: Added.
+        (sumOfArithSeries):
+        (foo):
+        * tests/stress/elide-new-object-dag-then-exit.js: Added.
+        (sumOfArithSeries):
+        (bar):
+        (verify):
+        (foo):
+        * tests/stress/obviously-elidable-new-object-then-exit.js: Added.
+        (sumOfArithSeries):
+        (foo):
+
+2014-09-25  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: Check event loop input extents during replaying too
+        https://bugs.webkit.org/show_bug.cgi?id=136316
+
+        Reviewed by Timothy Hatcher.
+
+        Sometimes we see different nondeterminism during capture and replay
+        executions, so we should add determinism checks during replay too.
+
+        Move the withinEventLoopInputExtent flag to the base class, and tighten
+        the assertion to address <http://webkit.org/b/133019>.
+
+        * replay/InputCursor.h:
+        (JSC::InputCursor::InputCursor):
+        (JSC::InputCursor::setWithinEventLoopInputExtent): Added.
+        This assertion is slightly wrong because it does not account for nested run loops.
+        We can be within two input extents when a nested run loop processes additional
+        user inputs while the debugger is paused.
+
+        This should only be the case when execution is being neither captured or
+        replayed. The debugger should not pause when capturing, and we should not replay
+        event loop inputs while in a nested run loop.
+
+        (JSC::InputCursor::withinEventLoopInputExtent): Added.
+
+2014-09-25  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove WinCE port from trunk
+        https://bugs.webkit.org/show_bug.cgi?id=136951
+
+        Reviewed by Alex Christensen.
+
+        * assembler/ARMAssembler.h:
+        (JSC::ARMAssembler::cacheFlush):
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::cacheFlush):
+        * config.h:
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::gatherFromCurrentThread):
+        (JSC::MachineThreads::gatherFromOtherThread):
+        (JSC::swapIfBackwards): Deleted.
+        * jit/ExecutableAllocator.h:
+        * jsc.cpp:
+        (main):
+        * runtime/DateConstructor.cpp:
+        * runtime/Options.cpp:
+        (JSC::overrideOptionWithHeuristic):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * testRegExp.cpp:
+        (main):
+        * tools/CodeProfiling.cpp:
+        (JSC::CodeProfiling::notifyAllocator):
+
+2014-09-24  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: subtract elapsed time while debugger is paused from profile nodes
+        https://bugs.webkit.org/show_bug.cgi?id=136796
+
+        Reviewed by Timothy Hatcher.
+
+        Rather than accruing no time to any profile node created while the debugger is paused,
+        we can instead count a node's elapsed time and exclude time elapsed while paused.
+
+        Time for a node may elapse in a non-contiguous fashion depending on the interleaving of
+        didPause, didContinue, willExecute, and didExecute. A node's start time is set to the
+        start of the last such interval that accrues elapsed time.
+
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause): Added.
+        (JSC::ProfileGenerator::didContinue): Added.
+        * profiler/ProfileGenerator.h:
+        (JSC::ProfileGenerator::didPause): Deleted.
+        (JSC::ProfileGenerator::didContinue): Deleted.
+        * profiler/ProfileNode.h: Rename totalTime to elapsedTime.
+        (JSC::ProfileNode::Call::Call):
+        (JSC::ProfileNode::Call::elapsedTime): Added.
+        (JSC::ProfileNode::Call::setElapsedTime): Added.
+        (JSC::CalculateProfileSubtreeDataFunctor::operator()):
+        (JSC::ProfileNode::Call::totalTime): Deleted.
+        (JSC::ProfileNode::Call::setTotalTime): Deleted.
+
+2014-09-24  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r173839.
+        https://bugs.webkit.org/show_bug.cgi?id=137062
+
+        NumberConstruct should no longer use static tables (Requested
+        by dpino on #webkit).
+
+        Reverted changeset:
+
+        "Simple ES6 feature: Number constructor extras"
+        https://bugs.webkit.org/show_bug.cgi?id=131707
+        http://trac.webkit.org/changeset/173839
+
+2014-09-23  Mark Lam  <mark.lam@apple.com>
+
+        DebuggerCallFrame::invalidate() should invalidate all DebuggerScope chains.
+        <https://webkit.org/b/137045>
+
+        Reviewed by Geoffrey Garen.
+
+        DebuggerCallFrame::invalidate() currently invalidates all DebuggerCallFrames
+        in the debugger stack, but only invalidates the DebuggerScope chain of the
+        top most frame.  We should also invalidate all the DebuggerScope chains of
+        the other frames in the debugger stack.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::invalidate):
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::invalidateChain):
+
+2014-09-23  Mark Lam  <mark.lam@apple.com>
+
+        Renamed DebuggerCallFrameScope to DebuggerPausedScope.
+        <https://webkit.org/b/137042>
+
+        Reviewed by Michael Saboff.
+
+        DebuggerPausedScope is a better name for this data structure because it
+        is meant for tracking the period within which the debugger is paused,
+        and doing clean ups after the pause ends.
+
+        * debugger/Debugger.cpp:
+        (JSC::DebuggerPausedScope::DebuggerPausedScope):
+        (JSC::DebuggerPausedScope::~DebuggerPausedScope):
+        (JSC::Debugger::pauseIfNeeded):
+        (JSC::DebuggerCallFrameScope::DebuggerCallFrameScope): Deleted.
+        (JSC::DebuggerCallFrameScope::~DebuggerCallFrameScope): Deleted.
+        * debugger/Debugger.h:
+        * debugger/DebuggerCallFrame.h:
+
+2014-09-23  Tomas Popela  <tpopela@redhat.com>
+
+        [CLoop] - Fix CLoop on the 32-bit Big-Endians
+        https://bugs.webkit.org/show_bug.cgi?id=137020
+
+        Reviewed by Mark Lam.
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+
+2014-09-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
+        https://bugs.webkit.org/show_bug.cgi?id=136893
+
+        Reviewed by Timothy Hatcher.
+
+        Adds new remote inspector protocol handling for automatic inspection.
+        Debuggers can signal they have enabled automatic inspection, and
+        when debuggables are created the current application will pause to
+        see if the debugger will inspect or decline to inspect the debuggable.
+
+        * inspector/remote/RemoteInspectorConstants.h:
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::globalAutomaticInspectionState):
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::start):
+        When first starting, check the global "is there an auto-inspect" debugger state.
+        This is necessary so that the current application knows if it should pause or
+        not when a debuggable is created, even without having connected to webinspectord yet.
+
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
+        When a debuggable has enabled remote inspection, take this path to propose
+        it as an automatic inspection candidate if there is an auto-inspect debugger.
+
+        (Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
+        Send the automatic inspection candidate message.
+
+        (Inspector::RemoteInspector::receivedSetupMessage):
+        (Inspector::RemoteInspector::setupFailed):
+        (Inspector::RemoteInspector::setupSucceeded):
+        After attempting to open an inspector, unpause if it was for the
+        automatic inspection candidate.
+
+        (Inspector::RemoteInspector::waitingForAutomaticInspection):
+        When running a nested runloop, check if we should remain paused.
+
+        (Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
+        If by the time we connect to webinspectord we have a candidate, then
+        immediately send the candidate message.
+
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::xpcConnectionFailed):
+        In error cases, clear our state.
+
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionConfigurationMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionRejectMessage):
+        Update state when receiving new messages.
+
+
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
+        Special case when a debuggable is newly allowed to be debuggable.
+
+        (Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection):
+        Run a nested run loop while this is an automatic inspection candidate.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        When the inspector starts via automatic inspection automatically pause.
+        We plan on removing this condition by having the frontend signal to the
+        backend when it is completely initialized.
+        
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        Pass on the flag of whether or not this was automatic inspection.
+
+        * runtime/JSGlobalObjectDebuggable.h:
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection):
+        When pausing in a JSGlobalObject we need to release the API lock.
+
+2014-09-22  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL allocatePropertyStorage code should involve less copy-paste
+        https://bugs.webkit.org/show_bug.cgi?id=137006
+
+        Reviewed by Michael Saboff.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::reallocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorageWithSizeImpl):
+
+2014-09-22  Diego Pino Garcia  <dpino@igalia.com>
+
+        Simple ES6 feature: Number constructor extras
+        https://bugs.webkit.org/show_bug.cgi?id=131707
+
+        Reviewed by Darin Adler.
+
+        * runtime/CommonIdentifiers.h: Added new identifiers.
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::getOwnPropertySlot):
+        (JSC::NumberConstructor::isFunction): Added.
+        (JSC::numberConstructorEpsilonValue): Added.
+        (JSC::numberConstructorNegInfinity): Added.
+        (JSC::numberConstructorPosInfinity): Added.
+        (JSC::numberConstructorMaxValue): Added.
+        (JSC::numberConstructorMinValue): Added.
+        (JSC::numberConstructorMaxSafeInteger): Added.
+        (JSC::numberConstructorMinSafeInteger): Added.
+        (JSC::numberConstructorFuncIsFinite): Added.
+        (JSC::numberConstructorFuncIsInteger): Added.
+        (JSC::numberConstructorFuncIsNaN): Added.
+        (JSC::numberConstructorFuncIsSafeInteger): Added.
+        * runtime/NumberConstructor.h:
+
+2014-09-21  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should store the four bytes of the cell header using a 32-bit store rather than four 8-bit stores
+        https://bugs.webkit.org/show_bug.cgi?id=136992
+
+        Reviewed by Sam Weinig.
+        
+        LLVM ought to be able to do this optimization for us given how the code was written, but
+        any such lower-level attempts to optimize this would get into trouble with the weird
+        object materialization logic I'll be introducing in bug 136330. So, this brings the
+        merging of the byte stores into the FTL lowering so that we can control it explicitly.
+
+        * ftl/FTLAbstractHeap.h:
+        (JSC::FTL::AbstractHeap::changeParent):
+        * ftl/FTLAbstractHeapRepository.cpp:
+        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+
+2014-09-21  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: fix TypeSet hierarchy in TypeTokenView
+        https://bugs.webkit.org/show_bug.cgi?id=136982
+
+        Reviewed by Joseph Pecoraro.
+
+        TypeSet was computing the set of type booleans in the Inspector::Protocol::Runtime::TypeSet 
+        object incorrectly because it was calling TypeSet::doesTypeConformTo(T) which checks if the 
+        type set has only been of type T. It now checks '(m_seenTypes & T) != TypeNothing' to see 
+        if type T is in the set of seen types, but not the entire set itself.
+
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::inspectorTypeSet):
+
+2014-09-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Structure should have a method for concurrently getting all of the property map entries, and this method shouldn't involve copy-paste
+        https://bugs.webkit.org/show_bug.cgi?id=136983
+
+        Reviewed by Mark Hahnenberg.
+
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyMapEntry::PropertyMapEntry): Moved PropertyMapEntry struct to Structure.h so that Structure can refer to it.
+        * runtime/Structure.cpp:
+        (JSC::Structure::getConcurrently): Switch to using the new forEachPropertyConcurrently() method.
+        (JSC::Structure::getPropertiesConcurrently): The subject of this patch. It will be useful for object allocation sinking (bug 136330).
+        (JSC::Structure::dump): Switch to using the new forEachPropertyConcurrently() method.
+        * runtime/Structure.h:
+        (JSC::PropertyMapEntry::PropertyMapEntry): Moved from PropertyMapHashTable.h.
+        * runtime/StructureInlines.h:
+        (JSC::Structure::forEachPropertyConcurrently): Capture this very common concurrent structure iteration pattern into a template method.
+
+2014-09-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Structure::getConcurrently() doesn't need to take a VM& argument.
+
+        Rubber stamped by Dan Bernstein.
+        
+        Removed the extra argument, and then removed similar arguments from other methods until
+        I could build successfully again. It turned out that many methods took a VM& argument
+        just for calling getConcurrently().
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::dumpStructure):
+        (JSC::dumpChain):
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        (JSC::CodeBlock::printPutByIdCacheStatus):
+        * bytecode/ComplexGetStatus.cpp:
+        (JSC::ComplexGetStatus::computeFor):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::mayInterceptStoreTo):
+        * runtime/IntendedStructureChain.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::getConcurrently):
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::getConcurrently):
+
+2014-09-20  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL OSRExit construction should be based on methods that return ExitValues rather than methods that add ExitValues to OSRExit
+        https://bugs.webkit.org/show_bug.cgi?id=136978
+
+        Reviewed by Dean Jackson.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::exitArgument):
+        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::addExitArgument): Deleted.
+
+2014-09-20  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL OSR exit should do reboxing and value recovery in the same pass
+        https://bugs.webkit.org/show_bug.cgi?id=136977
+
+        Reviewed by Oliver Hunt.
+        
+        It's conceptually simpler to have all of the logic in one place. After the
+        recover-and-rebox loop is done, all of the exit values are in the form that the baseline
+        JIT would want them to be in; the only remaining task is to move them into the right
+        place on the stack after we do all of the necessary stack adjustments.
+
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+
+2014-09-19  Filip Pizlo  <fpizlo@apple.com>
+
+        StorageAccessData should be referenced in a sensible way
+        https://bugs.webkit.org/show_bug.cgi?id=136963
+
+        Reviewed and rubber stamped by Michael Saboff.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleGetByOffset):
+        (JSC::DFG::ByteCodeParser::handlePutByOffset):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToGetByOffset):
+        (JSC::DFG::Node::convertToPutByOffset):
+        (JSC::DFG::Node::storageAccessData):
+        (JSC::DFG::Node::storageAccessDataIndex): Deleted.
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByOffset):
+
+2014-09-19  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Leak of mallocs under StructureSet::OutOfLineList::create
+        https://bugs.webkit.org/show_bug.cgi?id=136970
+
+        Reviewed by Filip Pizlo.
+
+        addOutOfLine should free the old list when expanding the capacity.
+
+        * bytecode/StructureSet.cpp:
+        (JSC::StructureSet::addOutOfLine):
+
+2014-09-19  Daniel Bates  <dabates@apple.com>
+
+        Always assume internal SDK when building configuration Production
+        https://bugs.webkit.org/show_bug.cgi?id=136925
+        <rdar://problem/18362399>
+
+        Reviewed by Dan Bernstein.
+
+        As a side effect of this change we will always enable ENABLE_TOUCH_EVENTS, ENABLE_IOS_{GESTURE, TOUCH}_EVENTS,
+        and ENABLE_XSLT when either building configuration Production or building with the Internal SDK.
+
+        * Configurations/Base.xcconfig:
+
+2014-09-19  Diego Pino Garcia  <dpino@igalia.com>
+
+        Simple ES6 feature:String prototype additions
+        https://bugs.webkit.org/show_bug.cgi?id=131704
+
+        Reviewed by Darin Adler.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        (JSC::stringProtoFuncStartsWith): Added.
+        (JSC::stringProtoFuncEndsWith): Added.
+        (JSC::stringProtoFuncContains): Added.
+
+2014-09-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed rollout r173731. Broke multiple builds.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::setupFailed):
+        (Inspector::RemoteInspector::start):
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        (Inspector::RemoteInspector::xpcConnectionFailed):
+        (Inspector::RemoteInspector::receivedSetupMessage):
+        (Inspector::globalAutomaticInspectionState): Deleted.
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate): Deleted.
+        (Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage): Deleted.
+        (Inspector::RemoteInspector::setupSucceeded): Deleted.
+        (Inspector::RemoteInspector::waitingForAutomaticInspection): Deleted.
+        (Inspector::RemoteInspector::receivedAutomaticInspectionConfigurationMessage): Deleted.
+        (Inspector::RemoteInspector::receivedAutomaticInspectionRejectMessage): Deleted.
+        * inspector/remote/RemoteInspectorConstants.h:
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
+        (Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection): Deleted.
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection): Deleted.
+        * runtime/JSGlobalObjectDebuggable.h:
+
+2014-09-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Should be able to attach a debugger to a JSContext before anything is executed
+        https://bugs.webkit.org/show_bug.cgi?id=136893
+
+        Reviewed by Timothy Hatcher.
+
+        Adds new remote inspector protocol handling for automatic inspection.
+        Debuggers can signal they have enabled automatic inspection, and
+        when debuggables are created the current application will pause to
+        see if the debugger will inspect or decline to inspect the debuggable.
+
+        * inspector/remote/RemoteInspectorConstants.h:
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::globalAutomaticInspectionState):
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::start):
+        When first starting, check the global "is there an auto-inspect" debugger state.
+        This is necessary so that the current application knows if it should pause or
+        not when a debuggable is created, even without having connected to webinspectord yet.
+
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
+        When a debuggable has enabled remote inspection, take this path to propose
+        it as an automatic inspection candidate if there is an auto-inspect debugger.
+
+        (Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
+        Send the automatic inspection candidate message.
+
+        (Inspector::RemoteInspector::receivedSetupMessage):
+        (Inspector::RemoteInspector::setupFailed):
+        (Inspector::RemoteInspector::setupSucceeded):
+        After attempting to open an inspector, unpause if it was for the
+        automatic inspection candidate.
+
+        (Inspector::RemoteInspector::waitingForAutomaticInspection):
+        When running a nested runloop, check if we should remain paused.
+
+        (Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
+        If by the time we connect to webinspectord we have a candidate, then
+        immediately send the candidate message.
+
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::xpcConnectionFailed):
+        In error cases, clear our state.
+
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionConfigurationMessage):
+        (Inspector::RemoteInspector::receivedAutomaticInspectionRejectMessage):
+        Update state when receiving new messages.
+
+
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
+        Special case when a debuggable is newly allowed to be debuggable.
+
+        (Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection):
+        Run a nested run loop while this is an automatic inspection candidate.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        When the inspector starts via automatic inspection automatically pause.
+        We plan on removing this condition by having the frontend signal to the
+        backend when it is completely initialized.
+        
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        Pass on the flag of whether or not this was automatic inspection.
+
+        * runtime/JSGlobalObjectDebuggable.h:
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection):
+        When pausing in a JSGlobalObject we need to release the API lock.
+
+2014-09-18  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        Fix "Tools/Scripts/build-webkit --efl --no-inspector" build
+        https://bugs.webkit.org/show_bug.cgi?id=136912
+
+        Reviewed by Darin Adler.
+
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::leastCommonAncestor):
+
+2014-09-17  Michael Saboff  <msaboff@apple.com>
+
+        Change CallFrame to use Callee instead of JSScope to implement vm()
+        https://bugs.webkit.org/show_bug.cgi?id=136894
+
+        Reviewed by Geoffrey Garen.
+
+        Added JSCell::vm() method that can be used on any JSObject.  Changed CallFrame::vm() to
+        use JSCell::vm with the Callee.  Made similar changes in the LLInt.
+        In support of this, changed JSGlobalObject::init() to take a VM& parameter, as there is
+        a chicken/egg problem with trying to use the Callee in the global exec before the Callee
+        has been create.  Besides, the vm is readily available in finishCreation(), the caller of
+        init().
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Changed the calculation of CallFrame::VM to use the Callee instead of JSScope.
+
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::vm): New method for getting VM from the pointer.
+        (JSC::ExecState::vm): Moved this method from JSScope.h to here since this file
+        contains the implementation of JSCell::vm(), this file is included by all users
+        of CallFrame::vm, and lastly putting it in CallFrameInlines.h required changing
+        many other .h files and possible the WebCore generator generate-bindings.pl.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::finishCreation):
+        Changed init() to take a VM parameter.
+
+        * runtime/JSScope.h:
+        (JSC::ExecState::vm): Deleted.
+
+2014-09-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, disable native inlining because it causes build failures.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-09-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Reduce a bit of churn setting initial remote inspection state
+        https://bugs.webkit.org/show_bug.cgi?id=136875
+
+        Reviewed by Timothy Hatcher.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreateInGroup):
+        Set the defaultl remote debuggable state at the API boundary.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        Do not set remote debuggable state here. Let clients set it.
+
+2014-09-16  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Promise: Drop Promise.cast
+        https://bugs.webkit.org/show_bug.cgi?id=136222
+
+        Reviewed by Sam Weinig.
+
+        Promise.cast is dropped and Promise.resolve is replaced with old Promise.cast.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructorFuncResolve):
+        (JSC::JSPromiseConstructorFuncRace):
+        (JSC::JSPromiseConstructorFuncAll):
+        (JSC::JSPromiseConstructorFuncCast): Deleted.
+
+2014-09-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Local OSR availability calculation should be reusable
+        https://bugs.webkit.org/show_bug.cgi?id=136860
+
+        Reviewed by Oliver Hunt.
+        
+        Previously, the FTL lowering repeated some of the logic of the OSR availability analysis
+        phase. Humorously, it actually did this logic a bit differently; for example the phase
+        would claim that a SetLocal makes both the flush and the node available while the FTL
+        only claimed that the flush was available. This different was benign, but still: yuck!
+        
+        Also, previously if you wanted to use availability information then you'd have to repeat
+        some of the logic that both the phase itself and the FTL lowering already had.
+        Presumably, you could get epic style points for finding other benign ways in which to
+        make your copy of the logic different from the other two!
+        
+        This reduces the amount of style points one could conceivably get in the future when
+        hacking JSC, by creating a single reusable thingy for computing local OSR availability.
+
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::LocalOSRAvailabilityCalculator):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::~LocalOSRAvailabilityCalculator):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::beginBlock):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRAvailabilityAnalysisPhase.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::compileBlock):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::availability):
+        (JSC::FTL::LowerDFGToLLVM::compileMovHint): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileZombieHint): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock): Deleted.
+
+2014-09-16  Csaba Osztrogonác  <ossy@webkit.org>
+
+        JSC test gardening
+        https://bugs.webkit.org/show_bug.cgi?id=136823
+
+        Reviewed by Geoffrey Garen.
+
+        * tests/mozilla/mozilla-tests.yaml: Unskip passing tests.
+
+2014-09-15  Michael Saboff  <msaboff@apple.com>
+
+        Create a JSCallee for GlobalExec object
+        https://bugs.webkit.org/show_bug.cgi?id=136840
+
+        Reviewed by Geoffrey Garen.
+
+        Added m_globalCallee, initialized it and then used it to set the globalExec's callee.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+
+2014-09-14  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG ref count calculation should be reusable
+        https://bugs.webkit.org/show_bug.cgi?id=136811
+
+        Reviewed by Oliver Hunt.
+        
+        Henceforth if you call Graph::computeRefCounts(), a nifty O(n) operation, every Node
+        will be able to tell you how many places it is used from. Currently only DCE uses this,
+        but it will be useful for https://bugs.webkit.org/show_bug.cgi?id=136330.
+
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        (JSC::DFG::DCEPhase::findTypeCheckRoot): Deleted.
+        (JSC::DFG::DCEPhase::countNode): Deleted.
+        (JSC::DFG::DCEPhase::countEdge): Deleted.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::computeRefCounts):
+        * dfg/DFGGraph.h:
+
+2014-09-12  Michael Saboff  <msaboff@apple.com>
+
+        Merge JSGlobalObject::reset() into ::init()
+        https://bugs.webkit.org/show_bug.cgi?id=136800
+
+        Reviewed by Oliver Hunt.
+
+        Moved the contents of reset() into init().
+        Note that the diff shows more changes.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Moved body of reset() into init.
+        (JSC::JSGlobalObject::put):
+        (JSC::JSGlobalObject::defineOwnProperty):
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        (JSC::lastInPrototypeChain):
+        (JSC::JSGlobalObject::reset): Deleted.
+        * runtime/JSGlobalObject.h:
+
+2014-09-12  Michael Saboff  <msaboff@apple.com>
+
+        Add JSCallee to program and eval CallFrames
+        https://bugs.webkit.org/show_bug.cgi?id=136785
+
+        Reviewed by Mark Lam.
+
+        Populated Callee slot for program and call eval CallFrames with a JSCallee objects.
+        Made supporting changes including adding a JSCallee structure to global object and adding
+        JSCallee::create() method.  Added code so that the newly added callee object won't be
+        returned by Function.caller.  Changed null pointer checks of callee to check the if
+        the type is JSFunction* or JSCallee*.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::functionName):
+        (JSC::DebuggerCallFrame::type):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::createCallIdentifier):
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        Changed checks of callee is a JSFunction* or JSCallee* instead of just checking
+        if it is null or not.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute): Create and use JSCallee objects for execute(EvalExecutable, ...)
+        and execute(ProgramExecutable, ...)
+
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute): Use jsDynamicCast to cast only JSFunctions.
+
+        * runtime/JSCallee.cpp:
+        (JSC::JSCallee::create): Not used, therefore deleted.
+
+        * runtime/JSCallee.h:
+        (JSC::JSCallee::create): Added.
+
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::callerGetter): Added test to return null for JSCallee's that aren't
+        JSFunction's.  This can only be the case when the JSCallee comes from a program or
+        call eval CallFrame.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::calleeStructure):
+        Added new JSCallee structure.
+
+2014-09-10  Jon Honeycutt  <jhoneycutt@apple.com>
+
+        Re-add the request autocomplete feature
+
+        <https://bugs.webkit.org/show_bug.cgi?id=136730>
+
+        This feature was rolled out in r148731 because it was only used by
+        Chromium. As we consider supporting this feature, roll it back in, but
+        leave it disabled.
+
+        This rolls out r148731 (which removed the feature) with small changes
+        needed to make the code build in ToT, to match modern style, to make
+        the tests run, and to remove unused code.
+
+        Reviewed by Andy Estes.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-09-12  Julien Brianceau  <jbriance@cisco.com>
+
+        [x86] moveDoubleToInts() does not clobber its source register anymore
+        https://bugs.webkit.org/show_bug.cgi?id=131690
+
+        Reviewed by Oliver Hunt.
+
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::moveDoubleToInts):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueRep):
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::returnDouble):
+
+2014-09-12  Mark Lam  <mark.lam@apple.com>
+
+        Unreviewed build fix for CLOOP build.
+
+        * runtime/JSCallee.h:
+
+2014-09-12  Michael Saboff  <msaboff@apple.com>
+
+        Remove unneeded declarations from JSCallee.h
+        https://bugs.webkit.org/show_bug.cgi?id=136783
+
+        Reviewed by Mark Lam.
+
+        * runtime/JSCallee.h:
+        (JSCallee::name): Deleted.
+        (JSCallee::displayName): Deleted.
+        (JSCallee::calculatedDisplayName): Deleted.
+
+2014-09-11  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: disambiguate double and integer primitive types in the protocol
+        https://bugs.webkit.org/show_bug.cgi?id=136606
+
+        Reviewed by Timothy Hatcher.
+
+        Right now it's really easy to mix up doubles and integers when serializing or deserializing
+        values for the inspector protocol. This patch disambiguates setting/getting doubles and integers
+        so that it is clearer as to which type is intended.
+
+        A new InspectorValue::Type is added for Integer types, and the Number type is renamed to Double.
+        The existing callsites for asNumber/getNumber/setNumber have been fixed.
+
+        Address various integration points to make sure the right type tag is assigned to InspectorValues.
+
+        * bindings/ScriptValue.cpp:
+        (Deprecated::jsToInspectorValue): Make an Integer if the JSValue is Int52 or smaller.
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::injectedScriptForObjectId):
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::InspectorBackendDispatcher::dispatch):
+        (Inspector::InspectorBackendDispatcher::sendResponse):
+        (Inspector::InspectorBackendDispatcher::reportProtocolError):
+        (Inspector::AsMethodBridges::asInteger):
+        (Inspector::AsMethodBridges::asDouble):
+        (Inspector::InspectorBackendDispatcher::getInteger):
+        (Inspector::InspectorBackendDispatcher::getDouble):
+        (Inspector::AsMethodBridges::asInt): Deleted.
+        (Inspector::InspectorBackendDispatcher::getInt): Deleted.
+        * inspector/InspectorBackendDispatcher.h:
+        * inspector/InspectorProtocolTypes.h: Remove the special case for checking int type tags.
+        (Inspector::Protocol::ArrayItemHelper<int>::Traits::pushRaw):
+        (Inspector::Protocol::ArrayItemHelper<double>::Traits::pushRaw):
+        (Inspector::Protocol::BindingTraits<int>::assertValueHasExpectedType): Deleted.
+        * inspector/InspectorValues.cpp: Allow integers and doubles to be convertible using asInteger/asDouble.
+        (Inspector::InspectorValue::asDouble):
+        (Inspector::InspectorValue::asInteger):
+        (Inspector::InspectorBasicValue::asDouble):
+        (Inspector::InspectorBasicValue::asInteger):
+        (Inspector::InspectorBasicValue::writeJSON):
+        (Inspector::InspectorValue::asNumber): Deleted.
+        (Inspector::InspectorBasicValue::asNumber): Deleted.
+        * inspector/InspectorValues.h:
+        (Inspector::InspectorObjectBase::setInteger):
+        (Inspector::InspectorObjectBase::setDouble):
+        (Inspector::InspectorArrayBase::pushInteger):
+        (Inspector::InspectorArrayBase::pushDouble):
+        (Inspector::InspectorObjectBase::setNumber): Deleted.
+        (Inspector::InspectorArrayBase::pushInt): Deleted.
+        (Inspector::InspectorArrayBase::pushNumber): Deleted.
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::buildObjectForBreakpointCookie):
+        (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol):
+        (Inspector::parseLocation):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/scripts/codegen/generator.py: Update emitted code and rebaseline test results.
+        (Generator.keyed_get_method_for_type):
+        (Generator.keyed_set_method_for_type):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::convertTo<double>):
+        (JSC::EncodedValue::convertTo<float>):
+        (JSC::EncodedValue::convertTo<int32_t>):
+        (JSC::EncodedValue::convertTo<int64_t>):
+        (JSC::EncodedValue::convertTo<uint32_t>):
+        (JSC::EncodedValue::convertTo<uint64_t>):
+
+2014-09-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Occasional ASSERT closing web inspector
+        https://bugs.webkit.org/show_bug.cgi?id=136762
+
+        Reviewed by Timothy Hatcher.
+
+        It is harmless, and indeed possible to have an empty set of listeners
+        now that each Page gets its own PageDebugServer instead of a shared
+        global. So we should replace the null checks with isEmpty checks.
+        Since nobody was ever returning null, convert to references as well.
+
+        * inspector/JSGlobalObjectScriptDebugServer.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionLog):
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionSound):
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionProbe):
+        (Inspector::ScriptDebugServer::sourceParsed):
+        (Inspector::ScriptDebugServer::dispatchFunctionToListeners):
+        (Inspector::ScriptDebugServer::notifyDoneProcessingDebuggerEvents):
+        (Inspector::ScriptDebugServer::handlePause):
+        (Inspector::ScriptDebugServer::needPauseHandling): Deleted.
+        * inspector/ScriptDebugServer.h:
+
+2014-09-10  Michael Saboff  <msaboff@apple.com>
+
+        Move JSScope out of JSFunction into separate JSCallee class
+        https://bugs.webkit.org/show_bug.cgi?id=136725
+
+        Reviewed by Oliver Hunt.
+
+        Created new JSCallee class that contains a JSScope*.  Changed JSFunction to inherit from
+        JSCallee.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Build changes.  Added JSCallee.cpp and JSCallee.h.
+
+        * runtime/JSCallee.cpp: Added.
+        (JSC::JSCallee::create):
+        (JSC::JSCallee::destroy):
+        (JSC::JSCallee::JSCallee):
+        (JSC::JSCallee::finishCreation):
+        (JSC::JSCallee::visitChildren):
+        (JSC::JSCallee::getOwnPropertySlot): Pass through wrapper function.
+        (JSC::JSCallee::getOwnNonIndexPropertyNames): Pass through wrapper function.
+        (JSC::JSCallee::put): Pass through wrapper function.
+        (JSC::JSCallee::deleteProperty): Pass through wrapper function.
+        (JSC::JSCallee::defineOwnProperty): Pass through wrapper function.
+
+        * runtime/JSCallee.h: Added.
+        (JSC::JSCallee::scope):
+        (JSC::JSCallee::scopeUnchecked):
+        (JSC::JSCallee::setScope):
+        (JSC::JSCallee::createStructure):
+        (JSC::JSCallee::offsetOfScopeChain):
+
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::JSFunction):
+        (JSC::JSFunction::addNameScopeIfNeeded):
+        (JSC::JSFunction::visitChildren):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::scope): Deleted.
+        (JSC::JSFunction::scopeUnchecked): Deleted.
+        (JSC::JSFunction::setScope): Deleted.
+        (JSC::JSFunction::offsetOfScopeChain): Deleted.
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::JSFunction):
+        Changed to reference JSCallee and its methods.
+
+        * runtime/JSType.h: Added JSCallee as a TypeEnum.
+
+2014-09-11  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION (r172129): Vine pages load as blank
+        https://bugs.webkit.org/show_bug.cgi?id=136655
+        rdar://problem/18281215
+
+        Reviewed by Michael Saboff.
+        
+        If lastNode is something that is subject to DCE, then removing the Phantom's reference to something
+        that lastNode references means that the thing being referenced may no longer be kept alive for OSR.
+        Teach PhantomRemovalPhase that it's only safe to do this if lastNode is a Phantom. That's probably too
+        conservative, but that's fine since this is mainly just an optimization to make the IR sane to read and
+        reasonably compact; it's OK if we miss cases here.
+
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * tests/stress/remove-phantom-after-setlocal.js: Added.
+
+2014-09-11  Bear Travis  <betravis@adobe.com>
+
+        [CSS Font Loading] Enable CSS Font Loading on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=135473
+
+        Reviewed by Antti Koivisto.
+
+        Enable CSS Font Loading in FeatureDefines.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-09-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed rebaseline of inspector generator test results after r173120.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+
+2014-09-11  Oliver Hunt  <oliver@apple.com>
+
+        Rename activation to be more in line with spec language
+        https://bugs.webkit.org/show_bug.cgi?id=136721
+
+        Reviewed by Michael Saboff.
+
+        Somewhat bigger than the last one, but still just a rename.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.order:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::isCaptured):
+        (JSC::CodeBlock::nameForRegister):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setActivationRegister):
+        (JSC::CodeBlock::activationRegister):
+        (JSC::CodeBlock::uncheckedActivationRegister):
+        (JSC::CodeBlock::needsActivation):
+        * bytecode/Instruction.h:
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setActivationRegister):
+        (JSC::UnlinkedCodeBlock::activationRegister):
+        (JSC::UnlinkedCodeBlock::hasActivationRegister):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitReturn):
+        * bytecompiler/BytecodeGenerator.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::scope):
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::isFunctionOrEvalScope):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetActivation):
+        (JSC::DFG::Graph::tryGetRegisters):
+        * dfg/DFGGraph.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::lexicalEnvironment):
+        (JSC::CallFrame::setActivation):
+        (JSC::CallFrame::activation): Deleted.
+        * interpreter/CallFrame.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        * interpreter/Register.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_tear_off_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_arguments):
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_activation): Deleted.
+        (JSC::JIT::emit_op_create_activation): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_tear_off_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_arguments):
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_activation): Deleted.
+        (JSC::JIT::emit_op_create_activation): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::visitChildren):
+        (JSC::Arguments::tearOff):
+        (JSC::Arguments::didTearOffActivation):
+        * runtime/Arguments.h:
+        (JSC::Arguments::offsetOfActivation):
+        (JSC::Arguments::argument):
+        (JSC::Arguments::finishCreation):
+        * runtime/CommonSlowPaths.cpp:
+        * runtime/JSFunction.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::activationStructure):
+        * runtime/JSLexicalEnvironment.cpp: Renamed from Source/JavaScriptCore/runtime/JSActivation.cpp.
+        (JSC::JSLexicalEnvironment::visitChildren):
+        (JSC::JSLexicalEnvironment::symbolTableGet):
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        (JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
+        (JSC::JSLexicalEnvironment::getOwnPropertySlot):
+        (JSC::JSLexicalEnvironment::put):
+        (JSC::JSLexicalEnvironment::deleteProperty):
+        (JSC::JSLexicalEnvironment::toThis):
+        (JSC::JSLexicalEnvironment::argumentsGetter):
+        * runtime/JSLexicalEnvironment.h: Renamed from Source/JavaScriptCore/runtime/JSActivation.h.
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::createStructure):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        (JSC::asActivation):
+        (JSC::Register::lexicalEnvironment):
+        (JSC::JSLexicalEnvironment::registersOffset):
+        (JSC::JSLexicalEnvironment::tearOff):
+        (JSC::JSLexicalEnvironment::isTornOff):
+        (JSC::JSLexicalEnvironment::storageOffset):
+        (JSC::JSLexicalEnvironment::storage):
+        (JSC::JSLexicalEnvironment::allocationSize):
+        (JSC::JSLexicalEnvironment::isValidIndex):
+        (JSC::JSLexicalEnvironment::isValid):
+        (JSC::JSLexicalEnvironment::registerAt):
+        * runtime/JSObject.h:
+        * runtime/JSScope.cpp:
+        (JSC::abstractAccess):
+        * runtime/JSScope.h:
+        (JSC::ResolveOp::ResolveOp):
+        * runtime/JSSymbolTableObject.cpp:
+        * runtime/StrictEvalActivation.h:
+        (JSC::StrictEvalActivation::create):
+        * runtime/VM.cpp:
+
+2014-09-11  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        [JavaScriptCore] Fix FTL on platform EFL.
+        https://bugs.webkit.org/show_bug.cgi?id=133571
+
+        Reviewed by Filip Pizlo.
+
+        There are no compact_unwind sections on Linux systems so FTL crashes.
+        We have to parse eh_frame in FTLUnwindInfo instead of compact_unwind
+        and get the information for stack unwinding from there.
+
+        * CMakeLists.txt: Revert r169181.
+        * ftl/FTLCompile.cpp:
+        Change section name literals to use SECTION_NAME macro, because of architecture differencies.
+        (JSC::FTL::mmAllocateCodeSection):
+        (JSC::FTL::mmAllocateDataSection):
+        (JSC::FTL::compile):
+        * ftl/FTLJITCode.h:
+        We need the SECTION_NAME macro in FTLCompile and FTLLink, so we define it here.
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLState.h:
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::State):
+        * ftl/FTLUnwindInfo.h:
+        * ftl/FTLUnwindInfo.cpp:
+        Lift the eh_frame parsing method from LLVM/libcxxabi project and modify it for our purposes.
+        Parse eh_frame on Linux instead of compact_unwind.
+        (JSC::FTL::UnwindInfo::parse):
+
+2014-09-10  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: Modify the type profiler runtime protocol to transfer some computation into the WebInspector
+        https://bugs.webkit.org/show_bug.cgi?id=136500
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch changes the type profiler protocol to the Web Inspector
+        by moving the work of calculating computed properties that effect the UI 
+        into the Web Inspector. This makes the Web Inspector have control over the 
+        strings it displays as UI elements representing type information to the user 
+        instead of JavaScriptCore deciding on a convention for these strings.
+        JavaScriptCore now sends enough information to the Web Inspector so that 
+        it can compute the properties JavaScriptCore used to compute.
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/protocol/Runtime.json:
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::getTypesForVariableAtOffsetForInspector): Deleted.
+        * runtime/TypeProfiler.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::inspectorTypeSet):
+        (JSC::StructureShape::leastCommonAncestor):
+        (JSC::StructureShape::inspectorRepresentation):
+        * runtime/TypeSet.h:
+
+2014-09-10  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Apply ARM64-specific lowering to load/store instructions in offlineasm
+        https://bugs.webkit.org/show_bug.cgi?id=136569
+
+        Reviewed by Michael Saboff.
+
+        The standard risc lowering of load/store instructions with base +
+        immediate offset addresses is to move the offset to a temporary, add the
+        base to the temporary, and then change the load/store to use the
+        temporary + 0 immediate offset address. However, on ARM64, base +
+        register offset addressing mode is available, so it is unnecessary to
+        perform explicit register additions but it is enough to change load/store
+        to use base + temporary as the address.
+
+        * offlineasm/arm64.rb: Added arm64LowerMalformedLoadStoreAddresses
+
+2014-09-10  Oliver Hunt  <oliver@apple.com>
+
+        Rename JSVariableObject to JSEnvironmentRecord to align naming with ES spec
+        https://bugs.webkit.org/show_bug.cgi?id=136710
+
+        Reviewed by Anders Carlsson.
+
+        This is a trivial rename.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractHeap.h:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLAbstractHeapRepository.cpp:
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters):
+        * jit/JITOpcodes32_64.cpp:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSActivation.cpp:
+        (JSC::JSActivation::getOwnNonIndexPropertyNames):
+        * runtime/JSActivation.h:
+        * runtime/JSEnvironmentRecord.cpp: Renamed from Source/JavaScriptCore/runtime/JSVariableObject.cpp.
+        * runtime/JSEnvironmentRecord.h: Renamed from Source/JavaScriptCore/runtime/JSVariableObject.h.
+        (JSC::JSEnvironmentRecord::registers):
+        (JSC::JSEnvironmentRecord::registerAt):
+        (JSC::JSEnvironmentRecord::addressOfRegisters):
+        (JSC::JSEnvironmentRecord::offsetOfRegisters):
+        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
+        * runtime/JSNameScope.h:
+        * runtime/JSSegmentedVariableObject.h:
+
+2014-09-10  Julien Brianceau   <jbriance@cisco.com>
+
+        [mips] Add missing parts and fix LLINT mips backend
+        https://bugs.webkit.org/show_bug.cgi?id=136706
+
+        Reviewed by Michael Saboff.
+
+        * llint/LowLevelInterpreter.asm: Fix invalid CalleeSave register number.
+        Implement initPCRelative and setEntryAddress macros.
+        * llint/LowLevelInterpreter32_64.asm: Fix register distribution in
+        doVMEntry macro.
+
+2014-09-10  Saam Barati  <saambarati1@gmail.com>
+
+        TypeSet needs a mode where it no longer profiles structure shapes
+        https://bugs.webkit.org/show_bug.cgi?id=136263
+
+        Reviewed by Filip Pizlo.
+
+        The TypeSet data structure used to gather as many StructureShape
+        objects as it encountered during type profiling. But, this meant 
+        that there was no upper limit on how many objects it could allocate. 
+        This patch places a fixed upper bound on the number of StructureShapes
+        allocated per TypeSet to prevent using too much memory for little gain
+        in type profiling usefulness.
+
+        StructureShape objects are now also aware of when they are created
+        from Structures which are dictionaries.
+
+        In total, this patch lays the final groundwork needed in refactoring 
+        the inspector protocol for the type profiler.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::toStructureShape):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::TypeSet):
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::StructureShape::StructureShape):
+        (JSC::StructureShape::toJSONString):
+        (JSC::StructureShape::enterDictionaryMode):
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::isOverflown):
+        * tests/typeProfiler/dictionary-mode.js: Added.
+        (wrapper):
+        * tests/typeProfiler/driver/driver.js:
+        * tests/typeProfiler/overflow.js: Added.
+        (wrapper.Proto):
+        (wrapper):
+
+2014-09-10  Peter Gal  <galpeter@inf.u-szeged.hu>
+
+        [MIPS] branch32WithPatch missing
+        https://bugs.webkit.org/show_bug.cgi?id=136696
+
+        Reviewed by Michael Saboff.
+
+        Added the missing branch32WithPatch. The implementation
+        is currently the same as the branchPtrithPatch because
+        the macro assembler supports only 32 bit MIPS.
+
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::branch32WithPatch):
+
+2014-09-10  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Fix !ENABLE(DFG_JIT) build
+        https://bugs.webkit.org/show_bug.cgi?id=136702
+
+        Reviewed by Michael Saboff.
+
+        * bytecode/CallEdgeProfile.h:
+
+2014-09-09  Benjamin Poulain  <bpoulain@apple.com>
+
+        Disable the "unreachable-code" warning
+        https://bugs.webkit.org/show_bug.cgi?id=136677
+
+        Reviewed by Darin Adler.
+
+        * Configurations/Base.xcconfig:
+
+2014-09-08  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should have a reusable SSA builder
+        https://bugs.webkit.org/show_bug.cgi?id=136331
+
+        Reviewed by Oliver Hunt.
+        
+        We want to implement sophisticated SSA transformations like object allocation sinking
+        (https://bugs.webkit.org/show_bug.cgi?id=136330), but to do that, we need to be able to do
+        updates to SSA that require inserting new Phi's. This requires calculating where Phis go.
+        Previously, our Phi calculation was based on Aycock and Horspool's algorithm, and our
+        implementation of this algorithm only worked when doing CPS->SSA conversion. The code
+        could not be reused for cases where some phase happens to know that it introduced a few
+        defs in some blocks and it wants to figure out where the Phis should go. Moreover, even
+        the general algorithm of Aycock and Horspool is not well suited to such targetted SSA
+        updates, since it requires first inserting maximal Phis. That scales well when the Phis
+        were already there (like in our CPS form) but otherwise it's quite unnatural and may be
+        difficult to make efficient.
+        
+        The usual way of handling both SSA conversion and SSA update is to use Cytron et al's
+        algorithm based on dominance frontiers. For a while now, I've been working on creating a
+        Cytron-based SSA calculator that can be used both as a replacement for our current SSA
+        converter and as a reusable tool for any phase that needs to do SSA update. I previously
+        optimized our dominator calculation and representation to use dominator trees computed
+        using Lengauer and Tarjan's algorithm - mainly to make it more scalable to enumerate over
+        the set of blocks that dominate you or vice-versa, and then I implemented a dominance
+        frontier calculator. This patch implements the final step towards making SSA update
+        available to all SSA phases: it implements an SSACalculator that can tell you where Phis
+        go when given an arbitrary set of Defs. To keep things simple, and to ensure that we have
+        good test coverage for this SSACalculator, this patch replaces the old Aycock-Horspool
+        SSA converter with one based on the SSACalculator.
+        
+        This has no observable impact. It does reduce the amount of code in SSAConversionPhase.
+        But even better, it makes SSAConversionPhase have significantly less tricky logic. It
+        mostly just relies on SSACalculator to do the tricky stuff, and SSAConversionPhase mostly
+        just reasons about the weirdnesses unique to the ThreadedCPS form that it sees as input.
+        In fact, using the Cytron et al approach means that there isn't really any "smoke and
+        mirrors" trickyness related to SSA. SSACalculator's only "tricks" are using the pruned
+        iterated dominance frontier to place Phi's and using the dom tree to find reaching defs.
+        The complexity is mostly confined to Dominators, which computes various dominator-related
+        properties over the control flow graph. That class can be difficult to understand, but at
+        least it follows well-known graph theory wisdom.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAnalysis.h:
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDominators.h:
+        (JSC::DFG::Dominators::immediateDominatorOf):
+        (JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOf):
+        (JSC::DFG::Dominators::forAllBlocksInPrunedIteratedDominanceFrontierOf):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::blocksInPreOrder):
+        (JSC::DFG::Graph::blocksInPostOrder):
+        (JSC::DFG::Graph::getBlocksInPreOrder): Deleted.
+        (JSC::DFG::Graph::getBlocksInPostOrder): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::run):
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGPhase.cpp:
+        (JSC::DFG::Phase::beginPhase):
+        (JSC::DFG::Phase::endPhase):
+        * dfg/DFGPhase.h:
+        * dfg/DFGSSACalculator.cpp: Added.
+        (JSC::DFG::SSACalculator::Variable::dump):
+        (JSC::DFG::SSACalculator::Variable::dumpVerbose):
+        (JSC::DFG::SSACalculator::Def::dump):
+        (JSC::DFG::SSACalculator::SSACalculator):
+        (JSC::DFG::SSACalculator::~SSACalculator):
+        (JSC::DFG::SSACalculator::newVariable):
+        (JSC::DFG::SSACalculator::newDef):
+        (JSC::DFG::SSACalculator::nonLocalReachingDef):
+        (JSC::DFG::SSACalculator::reachingDefAtTail):
+        (JSC::DFG::SSACalculator::dump):
+        * dfg/DFGSSACalculator.h: Added.
+        (JSC::DFG::SSACalculator::Variable::index):
+        (JSC::DFG::SSACalculator::Variable::Variable):
+        (JSC::DFG::SSACalculator::Def::variable):
+        (JSC::DFG::SSACalculator::Def::block):
+        (JSC::DFG::SSACalculator::Def::value):
+        (JSC::DFG::SSACalculator::Def::Def):
+        (JSC::DFG::SSACalculator::variable):
+        (JSC::DFG::SSACalculator::computePhis):
+        (JSC::DFG::SSACalculator::phisForBlock):
+        (JSC::DFG::SSACalculator::reachingDefAtHead):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::SSAConversionPhase):
+        (JSC::DFG::SSAConversionPhase::run):
+        (JSC::DFG::SSAConversionPhase::forwardPhiChildren): Deleted.
+        (JSC::DFG::SSAConversionPhase::forwardPhi): Deleted.
+        (JSC::DFG::SSAConversionPhase::forwardPhiEdge): Deleted.
+        (JSC::DFG::SSAConversionPhase::deduplicateChildren): Deleted.
+        * dfg/DFGSSAConversionPhase.h:
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::Validate):
+        (JSC::DFG::Validate::dumpGraphIfAppropriate):
+        (JSC::DFG::validate):
+        * dfg/DFGValidate.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        * runtime/Options.h:
+
+2014-09-08  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r173402.
+        https://bugs.webkit.org/show_bug.cgi?id=136649
+
+        Breaking buildw with error "unable to restore file position to
+        0x00000c60 for section __DWARF.__debug_info (errno = 9)"
+        (Requested by mlam_ on #webkit).
+
+        Reverted changeset:
+
+        "Move CallFrame and Register inlines functions out of
+        JSScope.h."
+        https://bugs.webkit.org/show_bug.cgi?id=136579
+        http://trac.webkit.org/changeset/173402
+
+2014-09-08  Mark Lam  <mark.lam@apple.com>
+
+        Move CallFrame and Register inlines functions out of JSScope.h.
+        <https://webkit.org/b/136579>
+
+        Reviewed by Geoffrey Garen.
+
+        This include fixing up some files to #include JSCInlines.h to pick up
+        these inline functions.  I also added JSCellInlines.h to JSCInlines.h
+        since it is included from many of the affected .cpp files.
+
+        * API/ObjCCallbackFunction.mm:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bindings/ScriptValue.cpp:
+        * inspector/InjectedScriptHost.cpp:
+        * inspector/InjectedScriptManager.cpp:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        * inspector/ScriptDebugServer.cpp:
+        * interpreter/CallFrameInlines.h:
+        (JSC::CallFrame::vm):
+        (JSC::CallFrame::lexicalGlobalObject):
+        (JSC::CallFrame::globalThisValue):
+        * interpreter/RegisterInlines.h: Added.
+        (JSC::Register::operator=):
+        (JSC::Register::scope):
+        * runtime/ArgumentsIteratorConstructor.cpp:
+        * runtime/JSArrayIterator.cpp:
+        * runtime/JSCInlines.h:
+        * runtime/JSCJSValue.cpp:
+        * runtime/JSMapIterator.cpp:
+        * runtime/JSPromiseConstructor.cpp:
+        * runtime/JSPromiseDeferred.cpp:
+        * runtime/JSPromiseFunctions.cpp:
+        * runtime/JSPromisePrototype.cpp:
+        * runtime/JSPromiseReaction.cpp:
+        * runtime/JSScope.h:
+        (JSC::Register::operator=): Deleted.
+        (JSC::Register::scope): Deleted.
+        (JSC::ExecState::vm): Deleted.
+        (JSC::ExecState::lexicalGlobalObject): Deleted.
+        (JSC::ExecState::globalThisValue): Deleted.
+        * runtime/JSSetIterator.cpp:
+        * runtime/MapConstructor.cpp:
+        * runtime/MapData.cpp:
+        * runtime/MapIteratorPrototype.cpp:
+        * runtime/MapPrototype.cpp:
+        * runtime/SetConstructor.cpp:
+        * runtime/SetIteratorPrototype.cpp:
+        * runtime/SetPrototype.cpp:
+        * runtime/WeakMapConstructor.cpp:
+        * runtime/WeakMapPrototype.cpp:
+
+2014-09-08  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        Remove FILTERS flag
+        https://bugs.webkit.org/show_bug.cgi?id=136571
+
+        Reviewed by Darin Adler.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-09-08  Saam Barati  <saambarati1@gmail.com>
+
+        Merge StructureShapes that share the same prototype chain
+        https://bugs.webkit.org/show_bug.cgi?id=136549
+
+        Reviewed by Filip Pizlo.
+
+        Instead of keeping track of many discrete StructureShapes that share
+        the same prototype chain, TypeSet should merge StructureShapes that 
+        have the same prototype chain and provide a new member variable for 
+        optional structure fields. This provides a cleaner and more concise
+        interface for dealing with StructureShapes within TypeSet. Instead
+        of having many discrete shapes that are almost identical, almost 
+        identical shapes will be merged together with an interface for 
+        understanding what fields the shapes being merged together differ in.
+
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::StructureShape::addProperty):
+        (JSC::StructureShape::toJSONString):
+        (JSC::StructureShape::inspectorRepresentation):
+        (JSC::StructureShape::hasSamePrototypeChain):
+        (JSC::StructureShape::merge):
+        * runtime/TypeSet.h:
+        * tests/typeProfiler/optional-fields.js: Added.
+        (wrapper.func):
+        (wrapper):
+
+2014-09-08  Jessie Berlin  <jberlin@apple.com>
+
+        More 32-bit Release build fixes after r173364.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-09-07  Maciej Stachowiak  <mjs@apple.com>
+
+        Fix typos in last patch to fix build.
+
+        Unreviewed build fix.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+
+2014-09-07  Maciej Stachowiak  <mjs@apple.com>
+
+        Introduce COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE) and use it
+        https://bugs.webkit.org/show_bug.cgi?id=136616
+
+        Reviewed by Darin Adler.
+        
+        Many compilers will analyze unrechable code paths (e.g. after an
+        unreachable code path), so sometimes they need dead code initializations.
+        But clang with suitable warnings will complain about unreachable code. So
+        use the quirk to include it conditionally.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdOp):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::handleExitCounts):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThread):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        * jsc.cpp:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fillArgList):
+        (JSC::JSArray::copyToArguments):
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::compile):
+        (JSC::RegExp::compileMatchOnly):
+
+2014-09-06  Darin Adler  <darin@apple.com>
+
+        Make updates suggested by new version of Xcode
+        https://bugs.webkit.org/show_bug.cgi?id=136603
+
+        Reviewed by Mark Rowe.
+
+        * Configurations/Base.xcconfig: Added CLANG_WARN_UNREACHABLE_CODE, COMBINE_HIDPI_IMAGES,
+        and ENABLE_STRICT_OBJC_MSGSEND as suggested by Xcode upgrade check.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Update LastUpgradeCheck.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode): Compile out unreachable code
+        for clang, since it understands the code is unreachable.
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fillArgList): Ditto.
+        (JSC::JSArray::copyToArguments): Ditto.
+
+2014-09-05  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: breakpoint actions should work regardless of Content Security Policy
+        https://bugs.webkit.org/show_bug.cgi?id=136542
+
+        Reviewed by Mark Lam.
+
+        Added JSC::DebuggerEvalEnabler, an RAII object which enables eval on a 
+        JSGlobalObject for the duration of a scope, returning the eval enabled state to its
+        original value when the scope exits. Used by JSC::DebuggerCallFrame::evaluate 
+        to allow breakpoint actions to execute JS in pages with a Content Security Policy
+        that would normally prohibit this (such as Inspector's Main.html).
+
+        Refactored Inspector::InjectedScriptBase to use the RAII object instead of manually
+        setting eval enabled and then resetting the original eval enabled state.
+
+        NOTE: The JS::DebuggerEvalEnabler constructor checks the passed in ExecState pointer
+        for null to be equivalent with the original code in Inspector::InjectedScriptBase.
+        InjectedScriptBase is getting the ExecState from ScriptObject::scriptState(), which
+        can currently be null.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::evaluate):
+        * debugger/DebuggerEvalEnabler.h: Added.
+        (JSC::DebuggerEvalEnabler::DebuggerEvalEnabler):
+        (JSC::DebuggerEvalEnabler::~DebuggerEvalEnabler):
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::callFunctionWithEvalEnabled):
+
+2014-09-05  peavo@outlook.com  <peavo@outlook.com>
+
+        [WinCairo] jsc.exe won't run.
+        https://bugs.webkit.org/show_bug.cgi?id=136481
+
+        Reviewed by Alex Christensen.
+        
+        We need to define WIN_CAIRO to avoid looking for the AAS folder.
+
+        * JavaScriptCore.vcxproj/jsc/DLLLauncherWinCairo.props: Added.
+        * JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props:
+        * JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj:
+
+2014-09-05  David Kilzer  <ddkilzer@apple.com>
+
+        JavaScriptCore should build with newer clang
+        <http://webkit.org/b/136002>
+        <rdar://problem/18020616>
+
+        Reviewed by Geoffrey Garen.
+
+        Other than the JSC::SourceProvider::asID() change (which simply
+        removes code that the optimizing compiler would have discarded
+        in Release builds), we move the |this| checks in OpaqueJSString
+        to NULL checks in to JSBase, JSObjectRef, JSScriptRef,
+        JSStringRef{CF} and JSValueRef.
+
+        Note that the following function arguments are _not_ NULL-checked
+        since doing so would just cover up bugs (and were not needed to
+        prevent any tests from failing):
+        - |script| in JSEvaluateScript(), JSCheckScriptSyntax();
+        - |body| in JSObjectMakeFunction();
+        - |source| in JSScriptCreateReferencingImmortalASCIIText()
+          (which is a const char* anyway);
+        - |source| in JSScriptCreateFromString().
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript): Add NULL check for |sourceURL|.
+        (JSCheckScriptSyntax): Ditto.
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction): Ditto.
+        * API/JSScriptRef.cpp:
+        (JSScriptCreateReferencingImmortalASCIIText): Ditto.
+        (JSScriptCreateFromString): Add NULL check for |url|.
+        * API/JSStringRef.cpp:
+        (JSStringGetLength): Return early if NULL pointer is passed in.
+        (JSStringGetCharactersPtr): Ditto.
+        (JSStringGetUTF8CString): Ditto.  Also check |buffer| parameter.
+        * API/JSStringRefCF.cpp:
+        (JSStringCopyCFString): Ditto.
+        * API/JSValueRef.cpp:
+        (JSValueMakeString): Add NULL check for |string|.
+
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::string): Remove code that checks |this|.
+        (OpaqueJSString::identifier): Ditto.
+        (OpaqueJSString::characters): Ditto.
+        * API/OpaqueJSString.h:
+        (OpaqueJSString::is8Bit): Remove code that checks |this|.
+        (OpaqueJSString::characters8): Ditto.
+        (OpaqueJSString::characters16): Ditto.
+        (OpaqueJSString::length): Ditto.
+
+        * parser/SourceProvider.h:
+        (JSC::SourceProvider::asID): Remove code that checks |this|.
+
+2014-06-06  Jer Noble  <jer.noble@apple.com>
+
+        Refactoring: make MediaTime the primary time type for audiovisual times.
+        https://bugs.webkit.org/show_bug.cgi?id=133579
+
+        Reviewed by Eric Carlson.
+
+        Add a utility function which converts a MediaTime to a JSNumber.
+
+        * runtime/JSCJSValue.h:
+        (JSC::jsNumber):
+
+2014-09-04  Michael Saboff  <msaboff@apple.com>
+
+        ARM: Add more coverage to ARMv7 disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=136565
+
+        Reviewed by Mark Lam.
+
+        Added ARMV7 disassembler support for Push/Pop multiple and floating point instructions
+        VCMP, VCVT[R] between floating point and integer, and VLDR.
+
+        * disassembler/ARMv7/ARMv7DOpcode.cpp:
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeDataPushPopMultiple::appendRegisterList):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeDataPopMultiple::format):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeDataPushMultiple::format):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::format):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::format):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::format):
+        * disassembler/ARMv7/ARMv7DOpcode.h:
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeDataPushPopMultiple::registerList):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeDataPushPopMultiple::condition):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::condition):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::dBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::vd):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::szBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::eBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::mBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCMP::vm):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::condition):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::dBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::op2):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::vd):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::szBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::op):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::mBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVCVTBetweenFPAndInt::vm):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::condition):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::uBit):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::rn):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::vd):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::doubleReg):
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeVLDR::immediate8):
+
+2014-09-04  Mark Lam  <mark.lam@apple.com>
+
+        Move PropertySlot's inline functions back to PropertySlot.h.
+        <https://webkit.org/b/136547>
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/JSObject.h:
+        (JSC::PropertySlot::getValue): Deleted.
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::getValue):
+
+2014-09-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Make sure that deleting all code first processes the call edge log, and reenable call edge profiling.
+
+        Rubber stamped by Sam Weinig.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::forEachCodeBlock):
+        (JSC::Debugger::setSteppingMode):
+        (JSC::Debugger::recompileAllJSFunctions):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        * runtime/Options.h: Reenable call edge profiling.
+        * runtime/VM.cpp:
+        (JSC::VM::prepareToDiscardCode): Make sure this also processes the call edge log, in case any call edge profiles are about to be destroyed.
+        (JSC::VM::discardAllCode):
+        (JSC::VM::releaseExecutableMemory):
+        (JSC::VM::setEnabledProfiler):
+        (JSC::VM::waitForCompilationsToComplete): Deleted.
+        * runtime/VM.h: Rename waitForCompilationsToComplete() back to prepareToDiscardCode() because the purpose of the method - now as ever - is to do all of the things that need to be done to ensure that code may be safely deleted.
+
+2014-09-04  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Ensure that the call frame set up by vmEntryToNative does not overlap with the stack of the callee
+        https://bugs.webkit.org/show_bug.cgi?id=136485
+
+        Reviewed by Michael Saboff.
+
+        Changed makeHostFunctionCall to keep the stack pointer above the call
+        frame set up by doVMEntry. Thus the callee will/can not override the top
+        of the call frame.
+
+        Refactored the two (32_64 and 64) versions of makeHostFunctionCall to be
+        more alike to help future maintenance.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-09-04  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r173031): crashes during run-layout-jsc on x86/Linux
+        https://bugs.webkit.org/show_bug.cgi?id=136436
+
+        Reviewed by Geoffrey Garen.
+
+        Instead of trying to calculate a stack pointer that allows for possible
+        stacked argument space, just use the "home" stack pointer location.
+        That stack pointer provides space for the worst case number of stacked
+        arguments on architectures that use stacked arguments.  It also provides
+        stack space so that the return PC and caller frame pointer that are stored
+        as part of making the call to operationCallEval will not override any part
+        of the callee frame created on the stack.
+
+        Changed compileCallEval() to use the stackPointer value of the calling
+        function.  That stack pointer is calculated to have enough space for
+        outgoing stacked arguments.  By moving the stack pointer to its "home"
+        position, the caller frame and return PC are not set as part of making
+        the call to operationCallEval().  Moved the explicit setting of the
+        callerFrame field of the callee CallFrame from operationCallEval() to
+        compileCallEval() since it has been the artifact of making a call for
+        most architectures.  Simplified the exception logic in compileCallEval()
+        as a result of the change.  To be compliant with the stack state
+        expected by virtualCallThunkGenerator(), moved the stack pointer to
+        point above the CallerFrameAndPC of the callee CallFrame.
+
+        * jit/JIT.h: Changed callOperationNoExceptionCheck(J_JITOperation_EE, ...)
+        to callOperation(J_JITOperation_EE, ...) as it now can do a typical exception
+        check.
+        * jit/JITCall.cpp & jit/JITCall32_64.cpp:
+        (JSC::JIT::compileCallEval): Use the home stack pointer when making the call
+        to operationCallEval.  Since the stack pointer adjustment no longer needs
+        to be done after making the call to operationCallEval(), the exception check
+        logic can be simplified.
+        (JSC::JIT::compileCallEvalSlowCase): Restored the stack pointer to point
+        to above the calleeFrame as this is what the generated thunk expects.
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation): Refactor of callOperationNoExceptionCheck
+        with the addition of a standard exception check.
+        (JSC::JIT::callOperationNoExceptionCheck): Deleted.
+        * jit/JITOperations.cpp:
+        (JSC::operationCallEval): Eliminated the explicit setting of caller frame
+        as that is now done in the code generated by compileCallEval().
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        Beef up the DFG's CFG analyses to include iterated dominance frontiers and more user-friendly BlockSets
+        https://bugs.webkit.org/show_bug.cgi?id=136520
+
+        Reviewed by Geoffrey Garen.
+        
+        Add code to compute iterated dominance frontiers. This involves using BlockSet a lot, so
+        this patch also makes BlockSet a lot more user-friendly.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGBlockSet.cpp: Added.
+        (JSC::DFG::BlockSet::dump):
+        * dfg/DFGBlockSet.h:
+        (JSC::DFG::BlockSet::iterator::iterator):
+        (JSC::DFG::BlockSet::iterator::operator++):
+        (JSC::DFG::BlockSet::iterator::operator==):
+        (JSC::DFG::BlockSet::iterator::operator!=):
+        (JSC::DFG::BlockSet::Iterable::Iterable):
+        (JSC::DFG::BlockSet::Iterable::begin):
+        (JSC::DFG::BlockSet::Iterable::end):
+        (JSC::DFG::BlockSet::iterable):
+        (JSC::DFG::BlockAdder::BlockAdder):
+        (JSC::DFG::BlockAdder::operator()):
+        * dfg/DFGBlockSetInlines.h: Added.
+        (JSC::DFG::BlockSet::iterator::operator*):
+        * dfg/DFGDominators.cpp:
+        (JSC::DFG::Dominators::strictDominatorsOf):
+        (JSC::DFG::Dominators::dominatorsOf):
+        (JSC::DFG::Dominators::blocksStrictlyDominatedBy):
+        (JSC::DFG::Dominators::blocksDominatedBy):
+        (JSC::DFG::Dominators::dominanceFrontierOf):
+        (JSC::DFG::Dominators::iteratedDominanceFrontierOf):
+        * dfg/DFGDominators.h:
+        (JSC::DFG::Dominators::forAllStrictDominatorsOf):
+        (JSC::DFG::Dominators::forAllDominatorsOf):
+        (JSC::DFG::Dominators::forAllBlocksStrictlyDominatedBy):
+        (JSC::DFG::Dominators::forAllBlocksDominatedBy):
+        (JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOf):
+        (JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOf):
+        (JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOfImpl):
+        (JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOfImpl):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dumpBlockHeader):
+        * dfg/DFGInvalidationPointInjectionPhase.cpp:
+        (JSC::DFG::InvalidationPointInjectionPhase::run):
+
+2014-09-04  Mark Lam  <mark.lam@apple.com>
+
+        Fixed indentations and some style warnings in JavaScriptCore/runtime.
+        <https://webkit.org/b/136518>
+
+        Reviewed by Michael Saboff.
+
+        Also removed some superflous spaces.  There are no semantic changes.
+
+        * runtime/Completion.h:
+        * runtime/ConstructData.h:
+        * runtime/DateConstructor.h:
+        * runtime/DateInstance.h:
+        * runtime/DateInstanceCache.h:
+        * runtime/DatePrototype.h:
+        * runtime/Error.h:
+        * runtime/ErrorConstructor.h:
+        * runtime/ErrorInstance.h:
+        * runtime/ErrorPrototype.h:
+        * runtime/FunctionConstructor.h:
+        * runtime/FunctionPrototype.h:
+        * runtime/GetterSetter.h:
+        * runtime/Identifier.h:
+        * runtime/InitializeThreading.h:
+        * runtime/InternalFunction.h:
+        * runtime/JSAPIValueWrapper.h:
+        * runtime/JSFunction.h:
+        * runtime/JSLock.h:
+        * runtime/JSNotAnObject.h:
+        * runtime/JSONObject.h:
+        * runtime/JSString.h:
+        * runtime/JSTypeInfo.h:
+        * runtime/JSWrapperObject.h:
+        * runtime/Lookup.h:
+        * runtime/MathObject.h:
+        * runtime/NativeErrorConstructor.h:
+        * runtime/NativeErrorPrototype.h:
+        * runtime/NumberConstructor.h:
+        * runtime/NumberObject.h:
+        * runtime/NumberPrototype.h:
+        * runtime/NumericStrings.h:
+        * runtime/ObjectConstructor.h:
+        * runtime/ObjectPrototype.h:
+        * runtime/PropertyDescriptor.h:
+        * runtime/Protect.h:
+        * runtime/PutPropertySlot.h:
+        * runtime/RegExp.h:
+        * runtime/RegExpCachedResult.h:
+        * runtime/RegExpConstructor.h:
+        * runtime/RegExpMatchesArray.h:
+        * runtime/RegExpObject.h:
+        * runtime/RegExpPrototype.h:
+        * runtime/SmallStrings.h:
+        * runtime/StringConstructor.h:
+        * runtime/StringObject.h:
+        * runtime/StringPrototype.h:
+        * runtime/StructureChain.h:
+        * runtime/VM.h:
+
+2014-09-04  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        Remove CSS_FILTERS flag
+        https://bugs.webkit.org/show_bug.cgi?id=136529
+
+        Reviewed by Dirk Schulze.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-09-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r173248.
+        https://bugs.webkit.org/show_bug.cgi?id=136536
+
+        call edge profiling and polymorphic call inlining are still
+        causing crashes (Requested by eric_carlson on #webkit).
+
+        Reverted changeset:
+
+        "Reenable call edge profiling and polymorphic call inlining,
+        now that a bunch of the bugs"
+        http://trac.webkit.org/changeset/173248
+
+2014-09-04  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: the profiler should not accrue time to nodes while the debugger is paused
+        https://bugs.webkit.org/show_bug.cgi?id=136352
+
+        Reviewed by Timothy Hatcher.
+
+        Hook up pause/continue events to the LegacyProfiler and any active
+        ProfilerGenerators. If the debugger is paused, all intervening call
+        entries will be created with totalTime as 0.0.
+
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handlePause):
+        * profiler/LegacyProfiler.cpp: Move from typedef'd callbacks to using
+        std::function. This allows callbacks to take different argument types.
+
+        (JSC::callFunctionForProfilesWithGroup):
+        (JSC::LegacyProfiler::willExecute):
+        (JSC::LegacyProfiler::didExecute):
+        (JSC::LegacyProfiler::exceptionUnwind):
+        (JSC::LegacyProfiler::didPause):
+        (JSC::LegacyProfiler::didContinue):
+        (JSC::dispatchFunctionToProfiles): Deleted.
+        * profiler/LegacyProfiler.h:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didExecute): Deleted.
+        * profiler/ProfileGenerator.h:
+        (JSC::ProfileGenerator::didPause):
+        (JSC::ProfileGenerator::didContinue):
+
+2014-09-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r173245.
+        https://bugs.webkit.org/show_bug.cgi?id=136533
+
+        Broke JSC tests. (Requested by ddkilzer on #webkit).
+
+        Reverted changeset:
+
+        "JavaScriptCore should build with newer clang"
+        https://bugs.webkit.org/show_bug.cgi?id=136002
+        http://trac.webkit.org/changeset/173245
+
+2014-09-04  Brian J. Burg  <burg@cs.washington.edu>
+
+        LegacyProfiler: ProfileNodes should be used more like structs
+        https://bugs.webkit.org/show_bug.cgi?id=136381
+
+        Reviewed by Timothy Hatcher.
+
+        Previously, both the profile generator and individual profile nodes
+        were collectively responsible for creating new Call entries and
+        maintaining data structure invariants. This complexity is unnecessary.
+
+        This patch centralizes profile data creation inside the profile generator.
+        The profile nodes manage nextSibling and parent pointers, but do not
+        collect the current time or create new Call entries themselves.
+
+        Since ProfileNode::nextSibling and its callers are only used within
+        debug printing code, it should be compiled out for release builds.
+
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::AddParentForConsoleStartFunctor::operator()):
+        (JSC::ProfileGenerator::beginCallEntry): create a new Call entry.
+        (JSC::ProfileGenerator::endCallEntry): finish the last Call entry.
+        (JSC::ProfileGenerator::willExecute): inline ProfileNode::willExecute()
+        (JSC::ProfileGenerator::didExecute): inline ProfileNode::didExecute()
+        (JSC::ProfileGenerator::stopProfiling): Only walk up the spine.
+        (JSC::ProfileGenerator::removeProfileStart):
+        (JSC::ProfileGenerator::removeProfileEnd):
+        * profiler/ProfileGenerator.h:
+        * profiler/ProfileNode.cpp:
+        (JSC::ProfileNode::ProfileNode):
+        (JSC::ProfileNode::addChild):
+        (JSC::ProfileNode::removeChild):
+        (JSC::ProfileNode::spliceNode): Renamed from insertNode.
+        (JSC::ProfileNode::debugPrintRecursively):
+        (JSC::ProfileNode::willExecute): Deleted.
+        (JSC::ProfileNode::insertNode): Deleted.
+        (JSC::ProfileNode::stopProfiling): Deleted.
+        (JSC::ProfileNode::traverseNextNodePostOrder):
+        (JSC::ProfileNode::endAndRecordCall): Deleted.
+        (JSC::ProfileNode::debugPrintDataSampleStyle):
+        * profiler/ProfileNode.h:
+        (JSC::ProfileNode::Call::setStartTime):
+        (JSC::ProfileNode::Call::setTotalTime):
+        (JSC::ProfileNode::appendCall):
+        (JSC::ProfileNode::firstChild):
+        (JSC::ProfileNode::lastChild):
+        (JSC::ProfileNode::nextSibling):
+        (JSC::ProfileNode::setNextSibling):
+
+2014-09-02  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: fix prefixes for subclasses of JSC::ConsoleClient
+        https://bugs.webkit.org/show_bug.cgi?id=136476
+
+        Reviewed by Timothy Hatcher.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/JSGlobalObjectConsoleClient.cpp: Renamed from Source/JavaScriptCore/inspector/JSConsoleClient.cpp.
+        * inspector/JSGlobalObjectConsoleClient.h: Renamed from Source/JavaScriptCore/inspector/JSConsoleClient.h.
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        * inspector/JSGlobalObjectInspectorController.h:
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        Reenable call edge profiling and polymorphic call inlining, now that a bunch of the bugs
+        are fixed.
+
+        * runtime/Options.h:
+
+2014-09-03  David Kilzer  <ddkilzer@apple.com>
+
+        JavaScriptCore should build with newer clang
+        <http://webkit.org/b/136002>
+        <rdar://problem/18020616>
+
+        Reviewed by Geoffrey Garen.
+
+        Other than the JSC::SourceProvider::asID() change (which simply
+        removes code that the optimizing compiler would have discarded
+        in Release builds), we move the |this| checks in OpaqueJSString
+        to NULL checks in to JSBase, JSScriptRef, JSStringRef{CF} and
+        JSValueRef.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript): Use String() in case |script| or |sourceURL|
+        are NULL.
+        * API/JSScriptRef.cpp:
+        (JSScriptCreateReferencingImmortalASCIIText): Use String() in
+        case |url| is NULL.
+        * API/JSStringRef.cpp:
+        (JSStringGetLength): Return early if NULL pointer is passed in.
+        (JSStringGetCharactersPtr): Ditto.
+        (JSStringGetUTF8CString): Ditto.  Also check |buffer| parameter.
+        * API/JSStringRefCF.cpp:
+        (JSStringCopyCFString): Ditto.
+        * API/JSValueRef.cpp:
+        (JSValueMakeString): Use String() in case |string| is NULL.
+
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::string): Remove code that checks |this|.
+        (OpaqueJSString::identifier): Ditto.
+        (OpaqueJSString::characters): Ditto.
+        * API/OpaqueJSString.h:
+        (OpaqueJSString::is8Bit): Remove code that checks |this|.
+        (OpaqueJSString::characters8): Ditto.
+        (OpaqueJSString::characters16): Ditto.
+        (OpaqueJSString::length): Ditto.
+
+        * parser/SourceProvider.h:
+        (JSC::SourceProvider::asID): Remove code that checks |this|.
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        CallEdgeProfile::visitWeak() shouldn't attempt to despecify empty profiles
+        https://bugs.webkit.org/show_bug.cgi?id=136511
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/CallEdgeProfile.cpp:
+        (JSC::CallEdgeProfile::worthDespecifying):
+        (JSC::CallEdgeProfile::visitWeak):
+        (JSC::CallEdgeProfile::mergeBack):
+
+2014-09-03  David Kilzer  <ddkilzer@apple.com>
+
+        REGRESSION (r167325): (null) entry added to Xcode project file when JSBoundFunction.h was removed
+        <http://webkit.org/b/136509>
+
+        Reviewed by Daniel Bates.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Remove the (null)
+        entry left behind when JSBoundFunction.h was removed.
+
+2014-09-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Avoid warning if a process does not have access to com.apple.webinspector
+        https://bugs.webkit.org/show_bug.cgi?id=136473
+
+        Reviewed by Alexey Proskuryakov.
+
+        Pre-check for access to the mach port to avoid emitting warnings
+        in syslog for processes that do not have access.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::canAccessWebInspectorMachPort):
+        (Inspector::RemoteInspector::shared):
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        Temporarily disable call edge profiling. It is causing crashes and I'm still investigating
+        them.
+
+        * runtime/Options.h:
+
+2014-09-03  Balazs Kilvady  <kilvadyb@homejinni.com>
+
+        [MIPS] Wrong register usage in LLInt op_catch.
+        https://bugs.webkit.org/show_bug.cgi?id=125168
+
+        Reviewed by Geoffrey Garen.
+
+        Fix register usage and add PIC header to all the ops in LLInt.
+
+        * offlineasm/instructions.rb:
+        * offlineasm/mips.rb:
+
+2014-09-03  Saam Barati  <saambarati1@gmail.com>
+
+        Create tests for type profiling
+        https://bugs.webkit.org/show_bug.cgi?id=136161
+
+        Reviewed by Geoffrey Garen.
+
+        The type profiler is now being tested. These are basic tests that don't 
+        check every edge case, but will catch any major failures in the type profiler. 
+        These tests cover:
+        - The basic, inheritance-based type system in TypeSet.
+        - Function return types.
+        - Correct merging of types for multiple assignments to one variable.
+
+        This patch also provides an API for writing new tests for
+        the type profiler. The API works by passing in a function and a 
+        unique substring of an expression contained in that function, and 
+        returns an object representing type information for that expression.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionFindTypeForExpression):
+        (functionReturnTypeFor):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
+        * runtime/TypeProfiler.h:
+        * runtime/TypeProfilerLog.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::toJSONString):
+        (JSC::StructureShape::toJSONString):
+        * runtime/TypeSet.h:
+        * tests/typeProfiler: Added.
+        * tests/typeProfiler.yaml: Added.
+        * tests/typeProfiler/basic.js: Added.
+        (wrapper.foo):
+        (wrapper):
+        * tests/typeProfiler/captured.js: Added.
+        (wrapper.changeFoo):
+        (wrapper):
+        * tests/typeProfiler/driver: Added.
+        * tests/typeProfiler/driver/driver.js: Added.
+        (assert):
+        * tests/typeProfiler/inheritance.js: Added.
+        (wrapper.A):
+        (wrapper.B):
+        (wrapper.C):
+        (wrapper):
+        * tests/typeProfiler/return.js: Added.
+        (foo):
+        (Ctor):
+
+2014-09-03  Julien Brianceau   <jbriance@cisco.com>
+
+        Add missing implementations to fix build for sh4 architecture
+        https://bugs.webkit.org/show_bug.cgi?id=136455
+
+        Reviewed by Geoffrey Garen.
+
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::store8):
+        (JSC::MacroAssemblerSH4::moveWithPatch):
+        (JSC::MacroAssemblerSH4::branchAdd32):
+        (JSC::MacroAssemblerSH4::branch32WithPatch):
+        (JSC::MacroAssemblerSH4::abortWithReason):
+        (JSC::MacroAssemblerSH4::canJumpReplacePatchableBranch32WithPatch):
+        (JSC::MacroAssemblerSH4::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::MacroAssemblerSH4::revertJumpReplacementToPatchableBranch32WithPatch):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitFunctionPrologue):
+        (JSC::AssemblyHelpers::emitFunctionEpilogue):
+
+2014-09-03  Dan Bernstein  <mitz@apple.com>
+
+        Get rid of HIGH_DPI_CANVAS leftovers
+        https://bugs.webkit.org/show_bug.cgi?id=136491
+
+        Reviewed by Benjamin Poulain.
+
+        * Configurations/FeatureDefines.xcconfig: Removed definition of ENABLE_HIGH_DPI_CANVAS
+        and removed it from FEATURE_DEFINES.
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        CallEdgeProfile::visitWeak() should gracefully handle the case where primaryCallee duplicates an entry in otherCallees
+        https://bugs.webkit.org/show_bug.cgi?id=136490
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/CallEdgeProfile.cpp:
+        (JSC::CallEdgeProfile::visitWeak):
+
+2014-09-03  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL In implementation sets callReturnLocation incorrectly leading to crashes beneath repatchCall()
+        https://bugs.webkit.org/show_bug.cgi?id=136488
+
+        Reviewed by Mark Hahnenberg.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::generateCheckInICFastPath): The call is in the slow path.
+        * tests/stress/ftl-in-overflow.js: Added. This used to crash with 100% with FTL enabled.
+        (foo):
+
+2014-09-03  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Don't generate superfluous mov instructions for move immediate on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=136435
+
+        Reviewed by Michael Saboff.
+
+        On ARM64, the size of an immediate operand for a mov instruction is 16
+        bits. Thus, a move immediate offlineasm instruction may potentially be
+        split up to several machine level instructions. The current
+        implementation always emits a mov for the least significant 16 bits of
+        the value. However, if any of the bits 63:16 are significant then the
+        first emitted mov already filled bits 15:0 with zeroes (or ones, for
+        negative values). So, if bits 15:0 of the value are all zeroes (or ones)
+        then the last mov does not need to be emitted.
+
+        * offlineasm/arm64.rb:
+
+2014-09-02  Brian J. Burg  <burg@cs.washington.edu>
+
+        LegacyProfiler: remove redundant ProfileNode members and other cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=136380
+
+        Reviewed by Timothy Hatcher.
+
+        ProfileNode's selfTime and totalTime members are redundant and only used
+        for dumping profile data from debug-only code. Remove the members and compute
+        the same data on-demand when necessary using a postorder traversal functor.
+
+        Remove ProfileNode.head since it is only used to calculate percentages for
+        dumped profile data. This can be explicitly passed around when needed.
+
+        Rename Profile.head to Profile.rootNode, and other various renamings.
+
+        Rearrange some header includes so that touching LegacyProfiler-related headers
+        will no longer cause a full rebuild.
+
+        * inspector/JSConsoleClient.cpp: Add header include.
+        * inspector/agents/InspectorProfilerAgent.cpp:
+        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
+        * inspector/protocol/Profiler.json: Remove unused Profile.idleTime member.
+        * jit/JIT.h: Remove header include.
+        * jit/JITCode.h: Remove header include.
+        * jit/JITOperations.cpp: Sort and add header include.
+        * llint/LLIntSlowPaths.cpp: Sort and add header include.
+        * profiler/Profile.cpp: Rename the debug dumping functions. Move the node
+        postorder traversal code to ProfileNode so we can traverse any subtree.
+        (JSC::Profile::Profile):
+        (JSC::Profile::debugPrint):
+        (JSC::Profile::debugPrintSampleStyle):
+        (JSC::Profile::forEach): Deleted.
+        (JSC::Profile::debugPrintData): Deleted.
+        (JSC::Profile::debugPrintDataSampleStyle): Deleted.
+        * profiler/Profile.h:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
+        (JSC::AddParentForConsoleStartFunctor::operator()):
+        (JSC::ProfileGenerator::addParentForConsoleStart):
+        (JSC::ProfileGenerator::didExecute):
+        (JSC::StopProfilingFunctor::operator()):
+        (JSC::ProfileGenerator::stopProfiling):
+        (JSC::ProfileGenerator::removeProfileStart):
+        (JSC::ProfileGenerator::removeProfileEnd):
+        * profiler/ProfileGenerator.h:
+        * profiler/ProfileNode.cpp:
+        (JSC::ProfileNode::ProfileNode):
+        (JSC::ProfileNode::willExecute):
+        (JSC::ProfileNode::removeChild):
+        (JSC::ProfileNode::stopProfiling):
+        (JSC::ProfileNode::endAndRecordCall):
+        (JSC::ProfileNode::debugPrint):
+        (JSC::ProfileNode::debugPrintSampleStyle):
+        (JSC::ProfileNode::debugPrintRecursively):
+        (JSC::ProfileNode::debugPrintSampleStyleRecursively):
+        (JSC::ProfileNode::debugPrintData): Deleted.
+        (JSC::ProfileNode::debugPrintDataSampleStyle): Deleted.
+        * profiler/ProfileNode.h: Calculate per-node self and total times using a postorder traversal.
+        The forEachNodePostorder functor traverses the subtree rooted at |this|.
+        (JSC::ProfileNode::create):
+        (JSC::ProfileNode::calls):
+        (JSC::ProfileNode::forEachNodePostorder):
+        (JSC::CalculateProfileSubtreeDataFunctor::returnValue):
+        (JSC::CalculateProfileSubtreeDataFunctor::operator()):
+        (JSC::ProfileNode::head): Deleted.
+        (JSC::ProfileNode::setHead): Deleted.
+        (JSC::ProfileNode::totalTime): Deleted.
+        (JSC::ProfileNode::setTotalTime): Deleted.
+        (JSC::ProfileNode::selfTime): Deleted.
+        (JSC::ProfileNode::setSelfTime): Deleted.
+        (JSC::ProfileNode::totalPercent): Deleted.
+        (JSC::ProfileNode::selfPercent): Deleted.
+        * runtime/ConsoleClient.h: Remove header include.
+
+2014-09-02  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
+        https://bugs.webkit.org/show_bug.cgi?id=136462
+
+        Reviewed by Timothy Hatcher.
+
+        It's not used by the frontend anymore.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+        * inspector/JSConsoleClient.cpp:
+        (Inspector::JSConsoleClient::JSConsoleClient): Stub out console.profile/profileEnd
+        methods since they didn't work for JSContexts anyway.
+        (Inspector::JSConsoleClient::profile):
+        (Inspector::JSConsoleClient::profileEnd):
+        * inspector/JSConsoleClient.h:
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        * inspector/agents/InspectorProfilerAgent.cpp: Removed.
+        * inspector/agents/InspectorProfilerAgent.h: Removed.
+        * inspector/agents/JSGlobalObjectProfilerAgent.cpp: Removed.
+        * inspector/agents/JSGlobalObjectProfilerAgent.h: Removed.
+        * inspector/protocol/Profiler.json: Removed.
+
+2014-09-02  Andreas Kling  <akling@apple.com>
+
+        Optimize own property GetByVals with rope string subscripts.
+        <https://webkit.org/b/136458>
+
+        For simple JSObjects that don't override getOwnPropertySlot to implement
+        custom properties, we have a fast path that grabs directly at the object
+        property storage.
+
+        Make this fast path even faster when the property name is an unresolved
+        rope string by using JSString::toExistingAtomicString(). This is faster
+        because it avoids allocating a new StringImpl if the string is already
+        a known Identifier, which is guaranteed to be the case if it's present
+        as an own property on the object.)
+
+        ~10% speed-up on Dromaeo/dom-attr.html
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+
+            When using the fastGetOwnProperty() optimization, get the String
+            out of JSString by using toExistingAtomicString(). This avoids
+            StringImpl allocation and lets us bypass the PropertyTable lookup
+            entirely if no AtomicString is found.
+
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::fastGetOwnProperty):
+
+            Make fastGetOwnProperty() take a PropertyName instead of a String.
+            This avoids churning the ref count, since we don't need to create
+            a temporary wrapper around the AtomicStringImpl* found in GetByVal.
+
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+
+            Add constructor: PropertyName(AtomicStringImpl*)
+
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::get):
+        (JSC::PropertyTable::findWithString): Deleted.
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get):
+
+            Remove code for querying a PropertyTable with an unhashed string key
+            since the only client is now gone.
+
+2014-09-02  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        [ARM] MacroAssembler generating incorrect code on ARM32 Traditional
+        https://bugs.webkit.org/show_bug.cgi?id=136429
+
+        Reviewed by Csaba Osztrogonác.
+
+        Changed test32 to use tst to check if reg is zero, instead of cmp.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::test32):
+
+2014-09-02  Michael Saboff  <msaboff@apple.com>
+
+        Out of bounds write in vmEntryToJavaScript / JSC::JITCode::execute
+        https://bugs.webkit.org/show_bug.cgi?id=136305
+
+        Reviewed by Filip Pizlo.
+
+        While preparing the callee's CallFrame, ProtoCallFrame fixes any arity mismatch
+        and then JITCode::execute() calls the normal entrypoint.  This is incompatible
+        with the expectation of FTL generated functions.  Changed ProtoCallFrame to not 
+        perform the arity fix, but just flag an arity mismatch.  now JITCode::execute()
+        uses that arity mismatch condition to select the normal or arity check
+        entrypoint.  The entrypoint selection is only done for functions, programs
+        and eval always have one parameter.
+
+        * interpreter/ProtoCallFrame.cpp:
+        (JSC::ProtoCallFrame::init): Changed to flag arity mismatch instead of fixing it.
+        * interpreter/ProtoCallFrame.h:
+        (JSC::ProtoCallFrame::needArityCheck): New boolean to signify what entrypoint
+        should be called.
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute): Select normal or arity check entrypoint as appropriate.
+
+2014-09-02  peavo@outlook.com  <peavo@outlook.com>
+
+        [WinCairo] testapi.exe is not built.
+        https://bugs.webkit.org/show_bug.cgi?id=136369
+
+        Reviewed by Alex Christensen.
+
+        The testapi project should be of type Application.
+
+        * JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj: Change project type to Application.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj: Ditto.
+        * JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props: Compile and link fix.
+        * JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj: Change project type to Application.
+
+2014-09-01  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        [CMAKE] Add missing offlineasm dependencies
+        https://bugs.webkit.org/show_bug.cgi?id=136437
+
+        Reviewed by Csaba Osztrogonác.
+
+        Add the ARM64, MIPS and SH4 backends to the dependencies.
+
+        * CMakeLists.txt:
+
+2014-09-01  Brian J. Burg  <burg@cs.washington.edu>
+
+        Provide column numbers to DTrace willExecute/didExecute probes
+        https://bugs.webkit.org/show_bug.cgi?id=136434
+
+        Reviewed by Antti Koivisto.
+
+        Provide the columnNumber and update stubs for !HAVE(DTRACE).
+
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::willExecute):
+        (JSC::ProfileGenerator::didExecute):
+        * runtime/Tracing.d:
+        * runtime/Tracing.h:
+
+2014-09-01  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        [CMAKE] Build warning by INTERFACE_LINK_LIBRARIES
+        https://bugs.webkit.org/show_bug.cgi?id=136194
+
+        Reviewed by Csaba Osztrogonác.
+
+        Set the LINK_INTERFACE_LIBRARIES target property on the top level CMakeLists.txt.
+
+        * CMakeLists.txt:
+
+2014-08-26  Maciej Stachowiak  <mjs@apple.com>
+
+        Use RetainPtr::autorelease in some places where it seems appropriate
+        https://bugs.webkit.org/show_bug.cgi?id=136280
+
+        Reviewed by Darin Adler.
+
+        * API/JSContext.mm:
+        (-[JSContext name]): Use RetainPtr::autorelease() in place of ObjC autorelease.
+        * API/JSValue.mm:
+        (valueToString): Make appropriate use of RetainPtr
+
+2014-08-29  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Ensure that the call frame passed from doVMEntry to the called function always contains the valid scope chain.
+        https://bugs.webkit.org/show_bug.cgi?id=136391
+
+        Reviewed by Michael Saboff.
+
+        Do not rely on calling conventions to fill in the CallerFrame component
+        of the ExecState* parameter of the called function.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-08-29  Saam Barati  <sbarati@apple.com>
+
+        emit op_profile_type for deconstruction assignments
+        https://bugs.webkit.org/show_bug.cgi?id=136274
+
+        Reviewed by Filip Pizlo.
+
+        Enable type profiling for ES6 deconstruction expressions.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BindingNode::bindValue):
+
+2014-08-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JavaScriptCore: Use ASCIILiteral where possible
+        https://bugs.webkit.org/show_bug.cgi?id=136179
+
+        Reviewed by Michael Saboff.
+
+        General string / character related changes. Use ASCIILiteral where
+        possible, jsNontrivialString where possible, and replace string
+        literals with character literals in some places.
+
+        No new tests, no changes to functionality.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::nameForRegister):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PostfixNode::emitBytecode):
+        (JSC::PrefixNode::emitBytecode):
+        (JSC::AssignErrorNode::emitBytecode):
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::ObjectPatternNode::toString):
+        * dfg/DFGFunctionWhitelist.cpp:
+        (JSC::DFG::FunctionWhitelist::contains):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::newTypedArrayWithSize):
+        (JSC::DFG::newTypedArrayWithOneArgument):
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::addToFrontend):
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::InspectorBackendDispatcher::dispatch):
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::extractSourceInformationFromException):
+        * inspector/scripts/codegen/generator_templates.py:
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::functionName):
+        (JSC::StackVisitor::Frame::sourceURL):
+        * jit/JITOperations.cpp:
+        * jsc.cpp:
+        (functionDescribeArray):
+        (functionRun):
+        (functionLoad):
+        (functionReadFile):
+        (functionCheckSyntax):
+        (functionTransferArrayBuffer):
+        (runWithScripts):
+        (runInteractive):
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::invalidCharacterMessage):
+        (JSC::Lexer<T>::parseString):
+        (JSC::Lexer<T>::parseStringSlowCase):
+        (JSC::Lexer<T>::lex):
+        * profiler/Profile.cpp:
+        (JSC::Profile::Profile):
+        * runtime/Arguments.cpp:
+        (JSC::argumentsFuncIterator):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::performSlowSort):
+        (JSC::arrayProtoFuncSort):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createError):
+        (JSC::createInvalidParameterError):
+        (JSC::createNotAConstructorError):
+        (JSC::createNotAFunctionError):
+        (JSC::createNotAnObjectError):
+        (JSC::createErrorForInvalidGlobalAssignment):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::insertSemicolonIfNeeded):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::defineOwnProperty):
+        (JSC::JSArray::pop):
+        (JSC::JSArray::push):
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::JSArrayBufferConstructor::finishCreation):
+        * runtime/JSArrayBufferPrototype.cpp:
+        (JSC::arrayBufferProtoFuncSlice):
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::create):
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+        (JSC::setData):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncProtoSetter):
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructor::finishCreation):
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::Lexer::lex):
+        (JSC::LiteralParser<CharType>::Lexer::lexString):
+        (JSC::LiteralParser<CharType>::parse):
+        * runtime/LiteralParser.h:
+        (JSC::LiteralParser::getErrorMessage):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::seenTypes):
+        (JSC::TypeSet::displayName):
+        (JSC::TypeSet::allPrimitiveTypeNames):
+        (JSC::StructureShape::propertyHash):
+        (JSC::StructureShape::stringRepresentation):
+
+2014-08-29  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Unreviwed, remove empty directories.
+
+        * qt: Removed.
+
+2014-08-28  Mark Lam  <mark.lam@apple.com>
+
+        DebuggerCallFrame::scope() should return a DebuggerScope.
+        <https://webkit.org/b/134420>
+
+        Reviewed by Geoffrey Garen.
+
+        Rolling back in r170680 with the fix for <https://webkit.org/b/135656>.
+
+        Previously, DebuggerCallFrame::scope() returns a JSActivation (and relevant
+        peers) which the WebInspector will use to introspect CallFrame variables.
+        Instead, we should be returning a DebuggerScope as an abstraction layer that
+        provides the introspection functionality that the WebInspector needs.  This
+        is the first step towards not forcing every frame to have a JSActivation
+        object just because the debugger is enabled.
+
+        1. Instantiate the debuggerScopeStructure as a member of the JSGlobalObject
+           instead of the VM.  This allows JSObject::globalObject() to be able to
+           return the global object for the DebuggerScope.
+
+        2. On the DebuggerScope's life-cycle management:
+
+           The DebuggerCallFrame is designed to be "valid" only during a debugging session
+           (while the debugger is broken) through the use of a DebuggerCallFrameScope in
+           Debugger::pauseIfNeeded().  Once the debugger resumes from the break, the
+           DebuggerCallFrameScope destructs, and the DebuggerCallFrame will be invalidated.
+           We can't guarantee (from this code alone) that the Inspector code isn't still
+           holding a ref to the DebuggerCallFrame (though they shouldn't), but by contract,
+           the frame will be invalidated, and any attempt to query it will return null values.
+           This is pre-existing behavior.
+
+           Now, we're adding the DebuggerScope into the picture.  While a single debugger
+           pause session is in progress, the Inspector may request the scope from the
+           DebuggerCallFrame.  While the DebuggerCallFrame is still valid, we want
+           DebuggerCallFrame::scope() to always return the same DebuggerScope object.
+           This is why we hold on to the DebuggerScope with a strong ref.
+
+           If we use a weak ref instead, the following cooky behavior can manifest:
+           1. The Inspector calls Debugger::scope() to get the top scope.
+           2. The Inspector iterates down the scope chain and is now only holding a
+              reference to a parent scope.  It is no longer referencing the top scope.
+           3. A GC occurs, and the DebuggerCallFrame's weak m_scope ref to the top scope
+              gets cleared.
+           4. The Inspector calls DebuggerCallFrame::scope() to get the top scope again but gets
+              a different DebuggerScope instance.
+           5. The Inspector iterates down the scope chain but never sees the parent scope
+              instance that retained a ref to in step 2 above.  This is because when iterating
+              this new DebuggerScope instance (which has no knowledge of the previous parent
+              DebuggerScope instance), a new DebuggerScope instance will get created for the
+              same parent scope. 
+
+           Since the DebuggerScope is a JSObject, its liveness is determined by its reachability.
+           However, its "validity" is determined by the life-cycle of its owner DebuggerCallFrame.
+           When the owner DebuggerCallFrame gets invalidated, its debugger scope chain (if
+           instantiated) will also get invalidated.  This is why we need the
+           DebuggerScope::invalidateChain() method.  The Inspector should not be using the
+           DebuggerScope instance after its owner DebuggerCallFrame is invalidated.  If it does,
+           those methods will do nothing or returned a failed status.
+
+        Fix for <https://webkit.org/b/135656>:
+        3. DebuggerScope::getOwnPropertySlot() and DebuggerScope::put() need to set
+           m_thisValue in the returned slot to the wrapped scope object.  Previously,
+           it was pointing to the DebuggerScope though the rest of the fields in the
+           returned slot will be set to data pertaining the wrapped scope object.
+
+        4. DebuggerScope::getOwnPropertySlot() will invoke getPropertySlot() on its
+           wrapped scope.  This is because JSObject::getPropertySlot() cannot be
+           overridden, and when called on a DebuggerScope, will not know to look in
+           the ptototype chain of the DebuggerScope's wrapped scope.  Hence, we'll
+           treat all properties in the wrapped scope as own properties in the
+           DebuggerScope.  This is fine because the WebInspector does not presently
+           care about where in the prototype chain the scope property comes from.
+
+           Note that the DebuggerScope and the JSActivation objects that it wraps do
+           not have prototypes.  They are always jsNull().  This works perfectly with
+           the above change to use getPropertySlot() instead of getOwnPropertySlot().
+           To make this an explicit invariant, I also changed DebuggerScope::createStructure()
+           and JSActivation::createStructure() to not take a prototype argument, and
+           to always use jsNull() for their prototype value.
+
+        * debugger/Debugger.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::scope):
+        (JSC::DebuggerCallFrame::evaluate):
+        (JSC::DebuggerCallFrame::invalidate):
+        * debugger/DebuggerCallFrame.h:
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::DebuggerScope):
+        (JSC::DebuggerScope::finishCreation):
+        (JSC::DebuggerScope::visitChildren):
+        (JSC::DebuggerScope::className):
+        (JSC::DebuggerScope::getOwnPropertySlot):
+        (JSC::DebuggerScope::put):
+        (JSC::DebuggerScope::deleteProperty):
+        (JSC::DebuggerScope::getOwnPropertyNames):
+        (JSC::DebuggerScope::defineOwnProperty):
+        (JSC::DebuggerScope::next):
+        (JSC::DebuggerScope::invalidateChain):
+        (JSC::DebuggerScope::isWithScope):
+        (JSC::DebuggerScope::isGlobalScope):
+        (JSC::DebuggerScope::isFunctionOrEvalScope):
+        * debugger/DebuggerScope.h:
+        (JSC::DebuggerScope::create):
+        (JSC::DebuggerScope::createStructure):
+        (JSC::DebuggerScope::iterator::iterator):
+        (JSC::DebuggerScope::iterator::get):
+        (JSC::DebuggerScope::iterator::operator++):
+        (JSC::DebuggerScope::iterator::operator==):
+        (JSC::DebuggerScope::iterator::operator!=):
+        (JSC::DebuggerScope::isValid):
+        (JSC::DebuggerScope::jsScope):
+        (JSC::DebuggerScope::begin):
+        (JSC::DebuggerScope::end):
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::scopeType):
+        (Inspector::JSJavaScriptCallFrame::scopeChain):
+        * inspector/JavaScriptCallFrame.h:
+        (Inspector::JavaScriptCallFrame::scopeChain):
+        * inspector/ScriptDebugServer.cpp:
+        * runtime/JSActivation.h:
+        (JSC::JSActivation::createStructure):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::debuggerScopeStructure):
+        * runtime/JSObject.cpp:
+        * runtime/JSObject.h:
+        (JSC::JSObject::isWithScope):
+        * runtime/JSScope.h:
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::setThisValue):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::setThisValue):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2014-08-28  Andreas Kling  <akling@apple.com>
+
+        Use JSString::toIdentifier() in more places.
+        <https://webkit.org/b/136348>
+
+        Call sites that grab the WTF::String from a JSString using value() can
+        use the more efficient toIdentifier() if the string is going to be used
+        to construct an Identifier.
+
+        If the JSString is a rope that resolves to something that is already
+        present in the VM's Identifier table, using toIdentifier() can avoid
+        allocating a new StringImpl.
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opIn):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Stringifier):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyDescriptor):
+        (JSC::objectConstructorDefineProperty):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncPropertyIsEnumerable):
+
+2014-08-27  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should compute immediate dominators using the O(n log n) form of Lengauer and Tarjan's "A Fast Algorithm for Finding Dominators in a Flowgraph"
+        https://bugs.webkit.org/show_bug.cgi?id=93361
+
+        Reviewed by Mark Hahnenberg.
+        
+        This patch also adds some new utilities for reasoning about block-keyed maps, block sets,
+        and block worklists. It changes preexisting code to use these abstractions.
+        
+        The main effect of this code is that all current clients of dominators end up using the
+        results of the new idom calculation. We convert the dom tree to a dominance test using
+        Dietz's pre/post number range check trick.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAnalysis.h:
+        (JSC::DFG::Analysis::computeIfNecessary):
+        (JSC::DFG::Analysis::computeDependencies):
+        * dfg/DFGBlockMap.h: Added.
+        (JSC::DFG::BlockMap::BlockMap):
+        (JSC::DFG::BlockMap::size):
+        (JSC::DFG::BlockMap::atIndex):
+        (JSC::DFG::BlockMap::operator[]):
+        * dfg/DFGBlockMapInlines.h: Added.
+        (JSC::DFG::BlockMap<T>::BlockMap):
+        * dfg/DFGBlockSet.h: Added.
+        (JSC::DFG::BlockSet::BlockSet):
+        (JSC::DFG::BlockSet::add):
+        (JSC::DFG::BlockSet::contains):
+        * dfg/DFGBlockWorklist.cpp: Added.
+        (JSC::DFG::BlockWorklist::BlockWorklist):
+        (JSC::DFG::BlockWorklist::~BlockWorklist):
+        (JSC::DFG::BlockWorklist::push):
+        (JSC::DFG::BlockWorklist::pop):
+        (JSC::DFG::PostOrderBlockWorklist::PostOrderBlockWorklist):
+        (JSC::DFG::PostOrderBlockWorklist::~PostOrderBlockWorklist):
+        (JSC::DFG::PostOrderBlockWorklist::pushPre):
+        (JSC::DFG::PostOrderBlockWorklist::pushPost):
+        (JSC::DFG::PostOrderBlockWorklist::pop):
+        * dfg/DFGBlockWorklist.h: Added.
+        (JSC::DFG::BlockWorklist::notEmpty):
+        (JSC::DFG::BlockWith::BlockWith):
+        (JSC::DFG::BlockWith::operator UnspecifiedBoolType*):
+        (JSC::DFG::ExtendedBlockWorklist::ExtendedBlockWorklist):
+        (JSC::DFG::ExtendedBlockWorklist::forcePush):
+        (JSC::DFG::ExtendedBlockWorklist::push):
+        (JSC::DFG::ExtendedBlockWorklist::notEmpty):
+        (JSC::DFG::ExtendedBlockWorklist::pop):
+        (JSC::DFG::BlockWithOrder::BlockWithOrder):
+        (JSC::DFG::BlockWithOrder::operator UnspecifiedBoolType*):
+        (JSC::DFG::PostOrderBlockWorklist::push):
+        (JSC::DFG::PostOrderBlockWorklist::notEmpty):
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGDominators.cpp:
+        (JSC::DFG::Dominators::compute):
+        (JSC::DFG::Dominators::naiveDominates):
+        (JSC::DFG::Dominators::dump):
+        (JSC::DFG::Dominators::pruneDominators): Deleted.
+        * dfg/DFGDominators.h:
+        (JSC::DFG::Dominators::strictlyDominates):
+        (JSC::DFG::Dominators::dominates):
+        (JSC::DFG::Dominators::BlockData::BlockData):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::getBlocksInPreOrder):
+        (JSC::DFG::Graph::getBlocksInPostOrder):
+        * dfg/DFGInvalidationPointInjectionPhase.cpp:
+        (JSC::DFG::InvalidationPointInjectionPhase::run):
+        * dfg/DFGNaiveDominators.cpp: Added.
+        (JSC::DFG::NaiveDominators::NaiveDominators):
+        (JSC::DFG::NaiveDominators::~NaiveDominators):
+        (JSC::DFG::NaiveDominators::compute):
+        (JSC::DFG::NaiveDominators::pruneDominators):
+        (JSC::DFG::NaiveDominators::dump):
+        * dfg/DFGNaiveDominators.h: Added.
+        (JSC::DFG::NaiveDominators::dominates):
+        * dfg/DFGNaturalLoops.cpp:
+        (JSC::DFG::NaturalLoops::computeDependencies):
+        (JSC::DFG::NaturalLoops::compute):
+        * dfg/DFGNaturalLoops.h:
+
+2014-08-27  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should be able to do polymorphic call inlining
+        https://bugs.webkit.org/show_bug.cgi?id=135145
+
+        Reviewed by Geoffrey Garen.
+        
+        Added a log-based high-fidelity call edge profiler that runs in DFG JIT (and optionally
+        baseline JIT) code. Used it to do precise polymorphic inlining in the FTL. Potential
+        inlining sites use the call edge profile if it is available, but they will still fall back
+        on the call inline cache and rare case counts if it's not. Polymorphic inlining means that
+        multiple possible callees can be inlined with a switch to guard them. The slow path may
+        either be an OSR exit or a virtual call.
+        
+        The call edge profiling added in this patch is very precise - it will tell you about every
+        call that has ever happened. It took some effort to reduce the overhead of this profiling.
+        This mostly involved ensuring that we don't do it unnecessarily. For example, we avoid it
+        in the baseline JIT (you can conditionally enable it but it's off by default) and we only do
+        it in the DFG JIT if we know that the regular inline cache profiling wasn't precise enough.
+        I also experimented with reducing the precision of the profiling. This led to a significant
+        reduction in the speed-up, so I avoided this approach. I also explored making log processing
+        concurrent, but that didn't help. Also, I tested the overhead of the log processing and
+        found that most of the overhead of this profiling is actually in putting things into the log
+        rather than in processing the log - that part appears to be surprisingly cheap.
+        
+        Polymorphic inlining could be enabled in the DFG if we enabled baseline call edge profiling,
+        and if we guarded such inlining sites with some profiling mechanism to detect
+        polyvariant monomorphisation opportunities (where the callsite being inlined reveals that
+        it's actually monomorphic).
+        
+        This is a ~28% speed-up on deltablue and a ~7% speed-up on richards, with small speed-ups on
+        other programs as well. It's about a 2% speed-up on Octane version 2, and never a regression
+        on anything we care about. Some aggregates, like V8Spider, see a regression. This is
+        highlighting the increase in profiling overhead. But since this doesn't show up on any major
+        score (code-load or SunSpider), it's probably not relevant.
+        
+        Relanding after fixing debug assertions in fast/storage/serialized-script-value.html.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallEdge.cpp: Added.
+        (JSC::CallEdge::dump):
+        * bytecode/CallEdge.h: Added.
+        (JSC::CallEdge::operator!):
+        (JSC::CallEdge::callee):
+        (JSC::CallEdge::count):
+        (JSC::CallEdge::despecifiedClosure):
+        (JSC::CallEdge::CallEdge):
+        * bytecode/CallEdgeProfile.cpp: Added.
+        (JSC::CallEdgeProfile::callEdges):
+        (JSC::CallEdgeProfile::numCallsToKnownCells):
+        (JSC::worthDespecifying):
+        (JSC::CallEdgeProfile::worthDespecifying):
+        (JSC::CallEdgeProfile::visitWeak):
+        (JSC::CallEdgeProfile::addSlow):
+        (JSC::CallEdgeProfile::mergeBack):
+        (JSC::CallEdgeProfile::fadeByHalf):
+        (JSC::CallEdgeLog::CallEdgeLog):
+        (JSC::CallEdgeLog::~CallEdgeLog):
+        (JSC::CallEdgeLog::isEnabled):
+        (JSC::operationProcessCallEdgeLog):
+        (JSC::CallEdgeLog::emitLogCode):
+        (JSC::CallEdgeLog::processLog):
+        * bytecode/CallEdgeProfile.h: Added.
+        (JSC::CallEdgeProfile::numCallsToNotCell):
+        (JSC::CallEdgeProfile::numCallsToUnknownCell):
+        (JSC::CallEdgeProfile::totalCalls):
+        * bytecode/CallEdgeProfileInlines.h: Added.
+        (JSC::CallEdgeProfile::CallEdgeProfile):
+        (JSC::CallEdgeProfile::add):
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::computeFromLLInt):
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeExitSiteData):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::computeFromCallEdgeProfile):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        (JSC::CallLinkStatus::isClosureCall):
+        (JSC::CallLinkStatus::makeClosureCall):
+        (JSC::CallLinkStatus::dump):
+        (JSC::CallLinkStatus::function): Deleted.
+        (JSC::CallLinkStatus::internalFunction): Deleted.
+        (JSC::CallLinkStatus::intrinsicFor): Deleted.
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isSet):
+        (JSC::CallLinkStatus::couldTakeSlowPath):
+        (JSC::CallLinkStatus::edges):
+        (JSC::CallLinkStatus::size):
+        (JSC::CallLinkStatus::at):
+        (JSC::CallLinkStatus::operator[]):
+        (JSC::CallLinkStatus::canOptimize):
+        (JSC::CallLinkStatus::canTrustCounts):
+        (JSC::CallLinkStatus::isClosureCall): Deleted.
+        (JSC::CallLinkStatus::callTarget): Deleted.
+        (JSC::CallLinkStatus::executable): Deleted.
+        (JSC::CallLinkStatus::makeClosureCall): Deleted.
+        * bytecode/CallVariant.cpp: Added.
+        (JSC::CallVariant::dump):
+        * bytecode/CallVariant.h: Added.
+        (JSC::CallVariant::CallVariant):
+        (JSC::CallVariant::operator!):
+        (JSC::CallVariant::despecifiedClosure):
+        (JSC::CallVariant::rawCalleeCell):
+        (JSC::CallVariant::internalFunction):
+        (JSC::CallVariant::function):
+        (JSC::CallVariant::isClosureCall):
+        (JSC::CallVariant::executable):
+        (JSC::CallVariant::nonExecutableCallee):
+        (JSC::CallVariant::intrinsicFor):
+        (JSC::CallVariant::functionExecutable):
+        (JSC::CallVariant::isHashTableDeletedValue):
+        (JSC::CallVariant::operator==):
+        (JSC::CallVariant::operator!=):
+        (JSC::CallVariant::operator<):
+        (JSC::CallVariant::operator>):
+        (JSC::CallVariant::operator<=):
+        (JSC::CallVariant::operator>=):
+        (JSC::CallVariant::hash):
+        (JSC::CallVariant::deletedToken):
+        (JSC::CallVariantHash::hash):
+        (JSC::CallVariantHash::equal):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::isNormalCall):
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        * bytecode/ExitKind.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::~BasicBlock):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::takeLast):
+        (JSC::DFG::BasicBlock::didLink):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::processSetLocalQueue):
+        (JSC::DFG::ByteCodeParser::removeLastNodeFromGraph):
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::addCall):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+        (JSC::DFG::ByteCodeParser::undoFunctionChecks):
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+        (JSC::DFG::ByteCodeParser::cancelLinkingForBlock):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::prepareToParseBlock):
+        (JSC::DFG::ByteCodeParser::clearCaches):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::linkBlock):
+        (JSC::DFG::ByteCodeParser::linkBlocks):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::getBlocksInPreOrder):
+        (JSC::DFG::Graph::visitChildren):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGLazyJSValue.cpp:
+        (JSC::DFG::LazyJSValue::switchLookupValue):
+        * dfg/DFGLazyJSValue.h:
+        (JSC::DFG::LazyJSValue::switchLookupValue): Deleted.
+        * dfg/DFGNode.cpp:
+        (WTF::printInternal):
+        * dfg/DFGNode.h:
+        (JSC::DFG::OpInfo::OpInfo):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::cellOperand):
+        (JSC::DFG::Node::setCellOperand):
+        (JSC::DFG::Node::canBeKnownFunction): Deleted.
+        (JSC::DFG::Node::hasKnownFunction): Deleted.
+        (JSC::DFG::Node::knownFunction): Deleted.
+        (JSC::DFG::Node::giveKnownFunction): Deleted.
+        (JSC::DFG::Node::hasFunction): Deleted.
+        (JSC::DFG::Node::function): Deleted.
+        (JSC::DFG::Node::hasExecutable): Deleted.
+        (JSC::DFG::Node::executable): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitch):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::ftlUnreachable):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckCell):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckBadCell):
+        (JSC::FTL::LowerDFGToLLVM::compileGetExecutable):
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::buildSwitch):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckFunction): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileCheckExecutable): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        (JSC::AssemblyHelpers::loadValue):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArguments):
+        * jit/GPRInfo.h:
+        (JSC::JSValueRegs::uses):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::ensureCallEdgeLog):
+        * runtime/VM.h:
+        * tests/stress/fold-profiled-call-to-call.js: Added. This test pinpoints the problem we saw in fast/storage/serialized-script-value.html.
+        * tests/stress/new-array-then-exit.js: Added.
+        * tests/stress/poly-call-exit-this.js: Added.
+        * tests/stress/poly-call-exit.js: Added.
+
+2014-08-28  Julien Brianceau   <jbriance@cisco.com>
+
+        Correct GC length unit and prevent division by 0 in showObjectStatistics.
+        https://bugs.webkit.org/show_bug.cgi?id=136340
+
+        Reviewed by Mark Hahnenberg.
+
+        * heap/HeapStatistics.cpp:
+        (JSC::HeapStatistics::showObjectStatistics):
+
+2014-08-27  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Ensure that the call frame passed from JIT code via JSC::operationCallEval to JSC::eval always contains the valid scope chain.
+        https://bugs.webkit.org/show_bug.cgi?id=136313
+
+        Reviewed by Michael Saboff.
+
+        Do not rely on calling conventions to fill in the CallerFrame component
+        of the execCallee parameter of JSC::operationCallEval.
+
+        * jit/JITOperations.cpp:
+
+2014-08-27  Saam Barati  <sbarati@apple.com>
+
+        Deconstruction object pattern node emits the wrong start/end text positions
+        https://bugs.webkit.org/show_bug.cgi?id=136304
+
+        Reviewed by Geoffrey Garen.
+
+        Object pattern nodes that used the syntactic sugar binding: 
+        'var {foo} = {foo:20}' instead of 'var {foo:foo} = {foo:20}' 
+        would get the wrong text position for variable 'foo'. The position 
+        would be placed on the comma(s)/closing brace instead of the identifier. 
+        This patch fixes this bug by caching the identifier's JSToken before 
+        trying to parse an optional colon.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        (JSC::Parser<LexerType>::createBindingPattern):
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        * parser/Parser.h:
+
+2014-08-27  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Build fix after last commit.
+
+        Check in new DLLLauncherMain.cpp file.
+
+        * JavaScriptCore.vcxproj/jsc/DLLLauncherMain.cpp: Added.
+        (enableTerminationOnHeapCorruption):
+        (getStringValue):
+        (applePathFromRegistry):
+        (appleApplicationSupportDirectory):
+        (copyEnvironmentVariable):
+        (prependPath):
+        (fatalError):
+        (directoryExists):
+        (modifyPath):
+        (getLastErrorString):
+        (wWinMain):
+
+2014-08-27  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] testapi and testRegExp need to find support libraries.
+        https://bugs.webkit.org/show_bug.cgi?id=136008.
+
+        Reviewed by Dean Jackson.
+
+        Revise the Windows build of jsc, testapi, and testRegExp so that they
+        find and use the proper runtime support libraries.
+
+        These locations vary between the Apple Windows build and WinCairo, and
+        are generally not in the system PATH environment setting. Consequently,
+        these applications fail on launch unless the user modifies their
+        PATH.
+
+        This patch revises these tools to work like WinLauncher and DumpRenderTree
+        so that they run reliably.
+
+        * API/tests/testapi.c:
+        (dllLauncherEntryPoint): Added.
+        * JavaScriptCore.vcxproj/JavaScriptCore.sln: Add new build projects and
+          provide proper dependencies with existing projects.
+        * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: Ditto.
+        * JavaScriptCore.vcxproj/jsc/jsc.vcxproj: Switch to build
+          a DLL, rather than an executable.
+        * JavaScriptCore.vcxproj/jsc/jscCommon.props: Add shlwapi.lib
+          to the list of libraries needed at link-time, and to use
+          the DLL/Console combination entry point.
+        * JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj: Added.
+        * JavaScriptCore.vcxproj/jsc/jscLauncherPostBuild.cmd: Copied from JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd.
+        * JavaScriptCore.vcxproj/jsc/jscLauncherPreBuild.cmd: Copied from JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd.
+        * JavaScriptCore.vcxproj/jsc/jscLauncherPreLink.cmd: Copied from JavaScriptCore.vcxproj/jsc/jscPreLink.cmd.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj: Switch to build
+          a DLL, rather than an executable.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props: Add shlwapi.lib
+          to the list of libraries needed at link-time, and to use
+          the DLL/Console combination entry point.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj: Added.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPostBuild.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreBuild.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd.
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreLink.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd.
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj: Switch to build
+          a DLL, rather than an executable.
+        * JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj: Added.
+        * JavaScriptCore.vcxproj/testapi/testapiCommon.props: Add shlwapi.lib
+          to the list of libraries needed at link-time, and to use
+          the DLL/Console combination entry point.
+        * JavaScriptCore.vcxproj/testapi/testapiLauncherPostBuild.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd.
+        * JavaScriptCore.vcxproj/testapi/testapiLauncherPreBuild.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd.
+        * JavaScriptCore.vcxproj/testapi/testapiLauncherPreLink.cmd: Copied from JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd.
+        * jsc.cpp:
+        (dllLauncherEntryPoint): Added.
+        * testRegExp.cpp:
+        (dllLauncherEntryPoint): Added.
+
+2014-08-27  Julien Brianceau   <jbriance@cisco.com>
+
+        Take advantage of 3 parameters or32() calls
+        https://bugs.webkit.org/show_bug.cgi?id=136287
+
+        Reviewed by Michael Saboff.
+
+        For specific architectures (arm and mips for instance), or32() calls
+        with 3 parameters are likely to produce a single instruction.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::branchIsOther):
+        (JSC::DFG::SpeculativeJIT::branchNotOther):
+
+2014-08-26  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: put feature flags for Inspector domains in the protocol specification
+        https://bugs.webkit.org/show_bug.cgi?id=136027
+
+        Reviewed by Timothy Hatcher.
+
+        Remove the hardcoded map of domains to feature guards, and instead parse it from the specification.
+
+        Test: inspector/scripts/tests/generate-domains-with-feature-guards.json
+
+        * inspector/scripts/codegen/generator.py:
+        (Generator.wrap_with_guard_for_domain):
+        * inspector/scripts/codegen/models.py:
+        (Protocol.parse_domain):
+        (Domain.__init__):
+        (Domains):
+        * inspector/scripts/tests/generate-domains-with-feature-guards.json: Added.
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+
+2014-08-26  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] Some projects are incorrectly installed to $BUILT_PRODUCTS_DIR
+        https://bugs.webkit.org/show_bug.cgi?id=136267
+
+        Reviewed by Dan Bernstein.
+
+        INSTALL_PATH was set to $BUILT_PRODUCTS_DIR for engineering configurations in r20225 as part of a build fix.
+        Not only is this no longer necessary to build, but it causes built products to be incorrectly installed in
+        engineering configurations.
+
+        Remove the setting of INSTALL_PATH from the pbxproj file so that the value specified in the xcconfig files is
+        used instead.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-08-26  Michael Saboff  <msaboff@apple.com>
+
+        [Win] 64-bit JavaScriptCore crashes on launch
+        https://bugs.webkit.org/show_bug.cgi?id=136241
+
+        Reviewed by Mark Lam.
+
+        * llint/LowLevelInterpreter.asm:
+        (vmEntryRecord): X86_64_WIN doesn't use "a0" (rax) for the first argument, it uses
+        "t2" (rcx).  Changed to get the input parameter using the correct register.
+
+2014-08-26  Saam Barati  <sbarati@apple.com>
+
+        TypeSet caches structureIDs even after the corresponding Structure could be GCed
+        https://bugs.webkit.org/show_bug.cgi?id=136178
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, TypeSet will never remove StructureIDs from its cache,
+        even after the corresponding Structures could be garbage collected.
+        Now, when the Garbage Collector collects, and type profiling is 
+        enabled, the Garbage Collector will invalidate all TypeSet caches.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::invalidateCache):
+        * runtime/TypeSet.h:
+        * runtime/VM.cpp:
+        (JSC::VM::invalidateTypeSetCache):
+        * runtime/VM.h:
+
+2014-08-26  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r172794) + 32Bit build: for-in-base-reassigned-later-and-change-structure.js fail with NaN result
+        https://bugs.webkit.org/show_bug.cgi?id=136187
+
+        Reviewed by Mark Hahnenberg.
+
+        Added two arg version for 32 bit builds of callOperation(J_JITOperation_ECJ, ...) that
+        doesn't require a tag for the second argument, instead it fills in a CellTag.  This is
+        used for the slow case of the GetDirectPname case in SpeculativeJIT::compile since we
+        haven't set up a register with a tag and we know that argument 2 is a cell.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation): New version with implicit CellTag.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): Eliminated extraneous filling of the scratchGPR
+        with CellTag as it wasn't in the control flow for the slow path that needed the tag.
+        Instead changed to calling new version of callOperation with an implicit CellTag.
+
+2014-08-26  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r172940.
+        https://bugs.webkit.org/show_bug.cgi?id=136256
+
+        Caused assertions on fast/storage/serialized-script-
+        value.html, and possibly flakiness on more tests (Requested by
+        ap on #webkit).
+
+        Reverted changeset:
+
+        "FTL should be able to do polymorphic call inlining"
+        https://bugs.webkit.org/show_bug.cgi?id=135145
+        http://trac.webkit.org/changeset/172940
+
+2014-08-26  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r172794) + 32Bit build: ASSERT failures in for-in-tests.js tests.
+        https://bugs.webkit.org/show_bug.cgi?id=136165
+
+        Reviewed by Mark Hahnenberg.
+
+        Changed switch case GetDirectPname: to always use the slow path for X86 since it only has
+        6 registers available, but the code requires 7.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-08-25  Saam Barati  <sbarati@apple.com>
+
+        TypeProfiler search breaks on return statements
+        https://bugs.webkit.org/show_bug.cgi?id=136201
+
+        Reviewed by Filip Pizlo.
+
+        Searching for return statements in the TypeProfiler currently 
+        breaks down because it expected to see the search descriptor 
+        TypeProfilerSearchDescriptorFunctionReturn when looking for 
+        return statements in the actual source code of the program. 
+        But, TypeProfilerSearchDescriptorFunctionReturn search descriptor 
+        is reserved for looking for return statements that aren't in the 
+        actual source code of the program, but when asking for the 
+        aggregate return type of a function. Now, searching for 
+        return statements in the actual source code of the program will 
+        work when passing in the search descriptor TypeProfilerSearchDescriptorNormal.  
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::findLocation):
+        (JSC::descriptorMatchesTypeLocation): Deleted.
+
+2014-08-25  Saam Barati  <sbarati@apple.com>
+
+        Return statement TypeSet's might be duplicated
+        https://bugs.webkit.org/show_bug.cgi?id=136200
+
+        Reviewed by Filip Pizlo.
+
+        Currently, the globalTypeSet that converges the types of all 
+        return statements in a function lives off of CodeBlock. It lives 
+        off CodeBlock because of a faulty assumption that CodeBlock 
+        will have a one to one mapping with a function in the source 
+        text of the program. (Currently, there isn't an actual bug 
+        with this design because TypeLocationCache will hash cons to 
+        the same TypeLocation, but this is still an incorrect design). 
+        In this patch, the globalTypeSet for function return statements  
+        is moved to the FunctionExecutable object which does have a one 
+        to one mapping with functions in the source text of a program.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::returnStatementTypeSet): Deleted.
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::returnStatementTypeSet):
+
+2014-08-24  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should be able to do polymorphic call inlining
+        https://bugs.webkit.org/show_bug.cgi?id=135145
+
+        Reviewed by Geoffrey Garen.
+        
+        Added a log-based high-fidelity call edge profiler that runs in DFG JIT (and optionally
+        baseline JIT) code. Used it to do precise polymorphic inlining in the FTL. Potential
+        inlining sites use the call edge profile if it is available, but they will still fall back
+        on the call inline cache and rare case counts if it's not. Polymorphic inlining means that
+        multiple possible callees can be inlined with a switch to guard them. The slow path may
+        either be an OSR exit or a virtual call.
+        
+        The call edge profiling added in this patch is very precise - it will tell you about every
+        call that has ever happened. It took some effort to reduce the overhead of this profiling.
+        This mostly involved ensuring that we don't do it unnecessarily. For example, we avoid it
+        in the baseline JIT (you can conditionally enable it but it's off by default) and we only do
+        it in the DFG JIT if we know that the regular inline cache profiling wasn't precise enough.
+        I also experimented with reducing the precision of the profiling. This led to a significant
+        reduction in the speed-up, so I avoided this approach. I also explored making log processing
+        concurrent, but that didn't help. Also, I tested the overhead of the log processing and
+        found that most of the overhead of this profiling is actually in putting things into the log
+        rather than in processing the log - that part appears to be surprisingly cheap.
+        
+        Polymorphic inlining could be enabled in the DFG if we enabled baseline call edge profiling,
+        and if we guarded such inlining sites with some profiling mechanism to detect
+        polyvariant monomorphisation opportunities (where the callsite being inlined reveals that
+        it's actually monomorphic).
+        
+        This is a ~28% speed-up on deltablue and a ~7% speed-up on richards, with small speed-ups on
+        other programs as well. It's about a 2% speed-up on Octane version 2, and never a regression
+        on anything we care about. Some aggregates, like V8Spider, see a regression. This is
+        highlighting the increase in profiling overhead. But since this doesn't show up on any major
+        score (code-load or SunSpider), it's probably not relevant.
+        
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallEdge.cpp: Added.
+        (JSC::CallEdge::dump):
+        * bytecode/CallEdge.h: Added.
+        (JSC::CallEdge::operator!):
+        (JSC::CallEdge::callee):
+        (JSC::CallEdge::count):
+        (JSC::CallEdge::despecifiedClosure):
+        (JSC::CallEdge::CallEdge):
+        * bytecode/CallEdgeProfile.cpp: Added.
+        (JSC::CallEdgeProfile::callEdges):
+        (JSC::CallEdgeProfile::numCallsToKnownCells):
+        (JSC::worthDespecifying):
+        (JSC::CallEdgeProfile::worthDespecifying):
+        (JSC::CallEdgeProfile::visitWeak):
+        (JSC::CallEdgeProfile::addSlow):
+        (JSC::CallEdgeProfile::mergeBack):
+        (JSC::CallEdgeProfile::fadeByHalf):
+        (JSC::CallEdgeLog::CallEdgeLog):
+        (JSC::CallEdgeLog::~CallEdgeLog):
+        (JSC::CallEdgeLog::isEnabled):
+        (JSC::operationProcessCallEdgeLog):
+        (JSC::CallEdgeLog::emitLogCode):
+        (JSC::CallEdgeLog::processLog):
+        * bytecode/CallEdgeProfile.h: Added.
+        (JSC::CallEdgeProfile::numCallsToNotCell):
+        (JSC::CallEdgeProfile::numCallsToUnknownCell):
+        (JSC::CallEdgeProfile::totalCalls):
+        * bytecode/CallEdgeProfileInlines.h: Added.
+        (JSC::CallEdgeProfile::CallEdgeProfile):
+        (JSC::CallEdgeProfile::add):
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::computeFromLLInt):
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeExitSiteData):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::computeFromCallEdgeProfile):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        (JSC::CallLinkStatus::isClosureCall):
+        (JSC::CallLinkStatus::makeClosureCall):
+        (JSC::CallLinkStatus::dump):
+        (JSC::CallLinkStatus::function): Deleted.
+        (JSC::CallLinkStatus::internalFunction): Deleted.
+        (JSC::CallLinkStatus::intrinsicFor): Deleted.
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isSet):
+        (JSC::CallLinkStatus::couldTakeSlowPath):
+        (JSC::CallLinkStatus::edges):
+        (JSC::CallLinkStatus::size):
+        (JSC::CallLinkStatus::at):
+        (JSC::CallLinkStatus::operator[]):
+        (JSC::CallLinkStatus::canOptimize):
+        (JSC::CallLinkStatus::canTrustCounts):
+        (JSC::CallLinkStatus::isClosureCall): Deleted.
+        (JSC::CallLinkStatus::callTarget): Deleted.
+        (JSC::CallLinkStatus::executable): Deleted.
+        (JSC::CallLinkStatus::makeClosureCall): Deleted.
+        * bytecode/CallVariant.cpp: Added.
+        (JSC::CallVariant::dump):
+        * bytecode/CallVariant.h: Added.
+        (JSC::CallVariant::CallVariant):
+        (JSC::CallVariant::operator!):
+        (JSC::CallVariant::despecifiedClosure):
+        (JSC::CallVariant::rawCalleeCell):
+        (JSC::CallVariant::internalFunction):
+        (JSC::CallVariant::function):
+        (JSC::CallVariant::isClosureCall):
+        (JSC::CallVariant::executable):
+        (JSC::CallVariant::nonExecutableCallee):
+        (JSC::CallVariant::intrinsicFor):
+        (JSC::CallVariant::functionExecutable):
+        (JSC::CallVariant::isHashTableDeletedValue):
+        (JSC::CallVariant::operator==):
+        (JSC::CallVariant::operator!=):
+        (JSC::CallVariant::operator<):
+        (JSC::CallVariant::operator>):
+        (JSC::CallVariant::operator<=):
+        (JSC::CallVariant::operator>=):
+        (JSC::CallVariant::hash):
+        (JSC::CallVariant::deletedToken):
+        (JSC::CallVariantHash::hash):
+        (JSC::CallVariantHash::equal):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::isNormalCall):
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        * bytecode/ExitKind.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::~BasicBlock):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::takeLast):
+        (JSC::DFG::BasicBlock::didLink):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::processSetLocalQueue):
+        (JSC::DFG::ByteCodeParser::removeLastNodeFromGraph):
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::addCall):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+        (JSC::DFG::ByteCodeParser::undoFunctionChecks):
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+        (JSC::DFG::ByteCodeParser::cancelLinkingForBlock):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::prepareToParseBlock):
+        (JSC::DFG::ByteCodeParser::clearCaches):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::linkBlock):
+        (JSC::DFG::ByteCodeParser::linkBlocks):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::visitChildren):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGLazyJSValue.cpp:
+        (JSC::DFG::LazyJSValue::switchLookupValue):
+        * dfg/DFGLazyJSValue.h:
+        (JSC::DFG::LazyJSValue::switchLookupValue): Deleted.
+        * dfg/DFGNode.cpp:
+        (WTF::printInternal):
+        * dfg/DFGNode.h:
+        (JSC::DFG::OpInfo::OpInfo):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::cellOperand):
+        (JSC::DFG::Node::setCellOperand):
+        (JSC::DFG::Node::canBeKnownFunction): Deleted.
+        (JSC::DFG::Node::hasKnownFunction): Deleted.
+        (JSC::DFG::Node::knownFunction): Deleted.
+        (JSC::DFG::Node::giveKnownFunction): Deleted.
+        (JSC::DFG::Node::hasFunction): Deleted.
+        (JSC::DFG::Node::function): Deleted.
+        (JSC::DFG::Node::hasExecutable): Deleted.
+        (JSC::DFG::Node::executable): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitch):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::ftlUnreachable):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckCell):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckBadCell):
+        (JSC::FTL::LowerDFGToLLVM::compileGetExecutable):
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::buildSwitch):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckFunction): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileCheckExecutable): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        (JSC::AssemblyHelpers::loadValue):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArguments):
+        * jit/GPRInfo.h:
+        (JSC::JSValueRegs::uses):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::ensureCallEdgeLog):
+        * runtime/VM.h:
+        * tests/stress/new-array-then-exit.js: Added.
+        (foo):
+        * tests/stress/poly-call-exit-this.js: Added.
+        * tests/stress/poly-call-exit.js: Added.
+
+2014-08-22  Michael Saboff  <msaboff@apple.com>
+
+        After r172867 another crash in in js/dom/line-column-numbers.html
+        https://bugs.webkit.org/show_bug.cgi?id=136192
+
+        Reviewed by Geoffrey Garen.
+
+        In lookupExceptionHandlerFromCallerFrame(), We need to use the caller's CallFrame
+        and VMEntryFrame when calling genericUnwind().  NativeCallFrameTracerWithRestore()
+        does that for us.
+
+        In general, NativeCallFrameTracerWithRestore(), restores the values because we may
+        do more processing that requires the current callFrame and vmEntryFrame before we
+        get to the catch handler where we change these to the catch values.  In this
+        particular case, that restoration isn't currently needed, but we add complexity
+        and possible future confusion if we create another NativeCallFrameTracerXXX()
+        version that doesn't restore the values.
+
+        * jit/JITOperations.cpp:
+        (JSC::lookupExceptionHandlerFromCallerFrame): Changed NativeCallFrameTracer() to
+        NativeCallFrameTracerWithRestore() so that VM::topVMEntryFrame will be updated
+        before calling genericUnwind().
+
+2014-08-24  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: rename Inspector::TypeBuilder to Inspector::Protocol
+        https://bugs.webkit.org/show_bug.cgi?id=136031
+
+        Reviewed by Timothy Hatcher.
+
+        Rename TypeBuilder namespace to Protocol. Disambiguate where
+        necessary. Also rename InspectorTypeBuilder to ProtocolTypes.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::messageSourceValue):
+        (Inspector::messageTypeValue):
+        (Inspector::messageLevelValue):
+        (Inspector::ConsoleMessage::addToFrontend):
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::buildObjectForSearchMatch):
+        (Inspector::ContentSearchUtilities::searchInTextByLines):
+        * inspector/ContentSearchUtilities.h:
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::evaluate):
+        (Inspector::InjectedScript::callFunctionOn):
+        (Inspector::InjectedScript::evaluateOnCallFrame):
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        (Inspector::InjectedScript::wrapCallFrames):
+        (Inspector::InjectedScript::wrapObject):
+        (Inspector::InjectedScript::wrapTable):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall):
+        * inspector/InjectedScriptBase.h:
+        * inspector/InspectorTypeBuilder.h: Removed.
+        * inspector/ScriptCallFrame.cpp:
+        (Inspector::ScriptCallFrame::buildInspectorObject):
+        * inspector/ScriptCallFrame.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::buildInspectorArray):
+        * inspector/ScriptCallStack.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::inspect):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::breakpointActionTypeForString):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::resolveBreakpoint):
+        (Inspector::InspectorDebuggerAgent::searchInContent):
+        (Inspector::InspectorDebuggerAgent::getFunctionDetails):
+        (Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
+        (Inspector::InspectorDebuggerAgent::currentCallFrames):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorProfilerAgent.cpp:
+        (Inspector::InspectorProfilerAgent::createProfileHeader):
+        (Inspector::InspectorProfilerAgent::getProfileHeaders):
+        (Inspector::buildInspectorObject):
+        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
+        (Inspector::InspectorProfilerAgent::getCPUProfile):
+        * inspector/agents/InspectorProfilerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::buildErrorRangeObject):
+        (Inspector::InspectorRuntimeAgent::parse):
+        (Inspector::InspectorRuntimeAgent::evaluate):
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/scripts/codegen/__init__.py:
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator._generate_async_dispatcher_class_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_header.py:
+        (FrontendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py:
+        (FrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_type_builder_header.py: Removed.
+        * inspector/scripts/codegen/generate_type_builder_implementation.py: Removed.
+        * inspector/scripts/codegen/generator.py:
+        (Generator.protocol_type_string_for_type):
+        (Generator.protocol_type_string_for_type_member):
+        (Generator.type_string_for_type_with_name):
+        (Generator.type_string_for_formal_out_parameter):
+        (Generator.type_string_for_formal_async_parameter):
+        (Generator.type_string_for_stack_in_parameter):
+        (Generator.type_string_for_stack_out_parameter):
+        (Generator.assertion_method_for_type_member.assertion_method_for_type):
+        (Generator.assertion_method_for_type_member):
+        (Generator.type_builder_string_for_type): Deleted.
+        (Generator.type_builder_string_for_type_member): Deleted.
+        * inspector/scripts/codegen/generator_templates.py:
+        (Inspector):
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        (generate_from_specification):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * runtime/HighFidelityTypeProfiler.cpp:
+        (JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector):
+        * runtime/HighFidelityTypeProfiler.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::allPrimitiveTypeNames):
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::StructureShape::inspectorRepresentation):
+        * runtime/TypeSet.h:
+
+2014-08-24  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: Rename DOM.RGBA and remove workarounds in the bindings generator
+        https://bugs.webkit.org/show_bug.cgi?id=136025
+
+        Reviewed by Joseph Pecoraro.
+
+        This workaround can be removed since it is no longer necessary.
+
+        * inspector/scripts/codegen/models.py:
+        (TypeReference.__init__):
+        (Type.raw_name):
+        (TypeDeclaration.__init__):
+        * inspector/scripts/tests/type-declaration-object-type.json: Remove related test input.
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result: Rebaseline.
+
+2014-08-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Do not copy large module source strings
+        https://bugs.webkit.org/show_bug.cgi?id=136191
+
+        Reviewed by Benjamin Poulain.
+
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::injectedScriptSource):
+
+2014-08-21  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r163179): Sporadic crash in js/dom/line-column-numbers.html test
+        https://bugs.webkit.org/show_bug.cgi?id=136111
+
+        Reviewed by Filip Pizlo.
+
+        The problem was that we weren't properly handling VM::topVMEntryFrame in two ways.
+
+        First in the case where we get an exception of a stack overflow during setup of the direct
+        callee frame of a VM entry frame, we need to throw the exception in the caller's frame.
+        This requires unrolling topVMEntryFrame while creating the exception object.  This is
+        accomplished with the renamed NativeCallFrameTracerWithRestore object.  As part of this,
+        split the JIT rollback exception handling to call a new helper,
+        callLookupExceptionHandlerFromCallerFrame, which will unroll the callFrame and VMEntryFrame.
+
+        Second, when we unwind to find a handler, we also need to unwind topVMCallFrame for the
+        case where we end up (re)throwing another exception after entering the catch block, but
+        before another vmEntry call.  Added VM::vmEntryFrameForThrow as a way similar to
+        VM::callFrameForThrow to pass the appropriate VMENtryFrame to the catch block.
+
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileExceptionHandlers):
+        Split out the unroll cases to use the new helper callLookupExceptionHandlerFromCallerFrame()
+        to unwind both the callFrame and topVMEntryFrame.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::UnwindFunctor):
+        (JSC::UnwindFunctor::operator()):
+        (JSC::Interpreter::unwind):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        Added VMEntryFrame as another component to unwind.
+
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        (JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
+        (JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
+        Renamed and changed to save and restore topCallFrame and topVMEntryFrame around the setting of
+        both values.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::gotoNextFrame):
+        (JSC::StackVisitor::readNonInlinedFrame):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::vmEntryFrame):
+        Added code to unwind the VMEntryFrame.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::jumpToExceptionHandler): Updated comment to indicate that the value
+        the handler should use for VM::topEntryFrame is in VM::vmEntryFrameForThrow.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_catch):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Added code to update VM::topVMEntryFrame from VM::vmEntryFrameForThrowOffset.
+
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationThrowStackOverflowError):
+        (JSC::operationCallArityCheck):
+        (JSC::operationConstructArityCheck):
+
+        * runtime/VM.h:
+        (JSC::VM::vmEntryFrameForThrowOffset):
+        (JSC::VM::topVMEntryFrameOffset):
+        Added as the side channel to return the topVMEntryFrame that the handler should use.
+
+2014-08-22  Daniel Bates  <dabates@apple.com>
+
+        [iOS] Disable ENABLE_IOS_{GESTURE, TOUCH}_EVENTS, and temporarily disable ENABLE_TOUCH_EVENTS
+        and ENABLE_XSLT when building with the iOS public SDK
+        https://bugs.webkit.org/show_bug.cgi?id=135945
+
+        Reviewed by Andy Estes.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-22  Jon Lee  <jonlee@apple.com>
+
+        Fix iOS build due to r172832 and move RUBBER_BANDING out of FeatureDefines.h
+        https://bugs.webkit.org/show_bug.cgi?id=136157
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig: Add ENABLE(RUBBER_BANDING).
+
+2014-08-21  Mark Lam  <mark.lam@apple.com>
+
+        r171362 accidentally increased the size of InlineCallFrame.
+        <https://webkit.org/b/136141>
+
+        Reviewed by Filip Pizlo.
+
+        r171362 increased the size of InlineCallFrame::kind to 2 bits.  This increased
+        the size of InlineCallFrame from 72 to 80 though not intentionally.  The fix
+        is to reduce the size of InlineCallFrame::stackOffset to 29 bits.
+
+        Also added an assert to ensure that we never set a value that exceeds the size
+        of InlineCallFrame::stackOffset.
+
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::setStackOffset):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+
+2014-08-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: RetainPtr misuse, CFRunLoopSource leak
+        https://bugs.webkit.org/show_bug.cgi?id=136143
+
+        Reviewed by Timothy Hatcher.
+
+        Adopt a Create into the RetainPtr to avoid leaking.
+
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setupRunLoop):
+
+2014-08-21  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(r172808): It made 6 different tests fail on 32 bit platforms.
+        <https://webkit.org/b/136123>
+
+        Reviewed by Filip Pizlo.
+
+        The original patch in r172808 removed the code to skip the top scope in
+        the 64-bit port of JIT::emitResolveClosure() but not in the 32-bit port.
+        This patch fixes that and achieves parity.
+
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitResolveClosure):
+
+2014-08-21  Zalan Bujtas  <zalan@apple.com>
+
+        Enable SATURATED_LAYOUT_ARITHMETIC.
+        https://bugs.webkit.org/show_bug.cgi?id=136106
+
+        Reviewed by Simon Fraser.
+
+        SATURATED_LAYOUT_ARITHMETIC protects LayoutUnit against arithmetic overflow.
+        (No measurable performance regression on Mac.)
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-20  Saam Barati  <sbarati@apple.com>
+
+        Fix how CodeBlock dumps the opcode op_profile_type
+        https://bugs.webkit.org/show_bug.cgi?id=136088
+
+        Reviewed by Filip Pizlo.
+
+        op_profile_type was modified to receive two extra arguments,
+        but its dump in CodeBlock::dumpBytecode wasn't changed to 
+        account for this, so it broke CodeBlock::dumpBytecode when
+        op_profile_type was in the stream of bytecode instructions.
+        CodeBlock::dumpBytecode now accounts for the change in 
+        op_profile_type's arity.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+
+2014-08-20  Saam Barati  <sbarati@apple.com>
+
+        Rename HighFidelityTypeProfiling variables for more clarity
+        https://bugs.webkit.org/show_bug.cgi?id=135899
+
+        Reviewed by Geoffrey Garen.
+
+        Many names that are used in the type profiling infrastructure
+        prefix themselves with "HighFidelity" or include the words "high"
+        and/or "fidelity" in some way. But the words "high" and "fidelity" don't 
+        add anything descriptive to the names surrounding type profiling. 
+        So this patch removes all uses of "HighFidelity" and its variants.
+
+        Most renamings change "HighFidelity*" to "TypeProfiler*" or simply 
+        drop the prefix "HighFidelity" all together. Now, almost all names 
+        in relation to type profiling contain in them "TypeProfiler" or 
+        "TypeProfiling" or some combination of the words "type" and "profile".
+
+        This patch also changes how we check if type profiling is enabled:
+        We no longer call vm::isProfilingTypesWithHighFidelity. We now just 
+        check that vm::typeProfiler is not null.
+
+        This patch also changes all calls to TypeProfilerLog::processLogEntries
+        to use ASCIILiteral to form WTFStrings instead of vanilla C string literals.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/TypeLocation.h:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedCodeBlock::typeProfilerExpressionInfoForBytecodeOffset):
+        (JSC::UnlinkedCodeBlock::addTypeProfilerExpressionInfo):
+        (JSC::UnlinkedCodeBlock::highFidelityTypeProfileExpressionInfoForBytecodeOffset): Deleted.
+        (JSC::UnlinkedCodeBlock::addHighFidelityTypeProfileExpressionInfo): Deleted.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::typeProfilingStartOffset):
+        (JSC::UnlinkedFunctionExecutable::typeProfilingEndOffset):
+        (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingStartOffset): Deleted.
+        (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingEndOffset): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::emitTypeProfilerExpressionInfo):
+        (JSC::BytecodeGenerator::emitProfileType):
+        (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo): Deleted.
+        (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        (JSC::FunctionCallDotNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PostfixNode::emitBracket):
+        (JSC::PostfixNode::emitDot):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::PrefixNode::emitBracket):
+        (JSC::PrefixNode::emitDot):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::AssignDotNode::emitBytecode):
+        (JSC::ReadModifyDotNode::emitBytecode):
+        (JSC::AssignBracketNode::emitBytecode):
+        (JSC::ReadModifyBracketNode::emitBytecode):
+        (JSC::ConstDeclNode::emitCodeSingle):
+        (JSC::EmptyVarExpression::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::FunctionBodyNode::emitBytecode):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorRuntimeAgent::enableTypeProfiler):
+        (Inspector::InspectorRuntimeAgent::disableTypeProfiler):
+        (Inspector::InspectorRuntimeAgent::setTypeProfilerEnabledState):
+        (Inspector::InspectorRuntimeAgent::enableHighFidelityTypeProfiling): Deleted.
+        (Inspector::InspectorRuntimeAgent::disableHighFidelityTypeProfiling): Deleted.
+        (Inspector::InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState): Deleted.
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_profile_type):
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_profile_type):
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity): Deleted.
+        * jit/JITOperations.cpp:
+        * jsc.cpp:
+        (functionDumpTypesForAllVariables):
+        * llint/LLIntSlowPaths.cpp:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::ScriptExecutable):
+        (JSC::ProgramExecutable::ProgramExecutable):
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/Executable.h:
+        (JSC::ScriptExecutable::typeProfilingStartOffset):
+        (JSC::ScriptExecutable::typeProfilingEndOffset):
+        (JSC::ScriptExecutable::highFidelityTypeProfilingStartOffset): Deleted.
+        (JSC::ScriptExecutable::highFidelityTypeProfilingEndOffset): Deleted.
+        * runtime/HighFidelityLog.cpp: Removed.
+        * runtime/HighFidelityLog.h: Removed.
+        * runtime/HighFidelityTypeProfiler.cpp: Removed.
+        * runtime/HighFidelityTypeProfiler.h: Removed.
+        * runtime/Options.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::prepareForTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForVariable):
+        (JSC::SymbolTable::uniqueIDForRegister):
+        (JSC::SymbolTable::prepareForHighFidelityTypeProfiling): Deleted.
+        * runtime/SymbolTable.h:
+        * runtime/TypeProfiler.cpp: Added.
+        (JSC::TypeProfiler::logTypesForTypeLocation):
+        (JSC::TypeProfiler::insertNewLocation):
+        (JSC::TypeProfiler::getTypesForVariableAtOffsetForInspector):
+        (JSC::descriptorMatchesTypeLocation):
+        (JSC::TypeProfiler::findLocation):
+        * runtime/TypeProfiler.h: Added.
+        (JSC::QueryKey::QueryKey):
+        (JSC::QueryKey::isHashTableDeletedValue):
+        (JSC::QueryKey::operator==):
+        (JSC::QueryKey::hash):
+        (JSC::QueryKeyHash::hash):
+        (JSC::QueryKeyHash::equal):
+        (JSC::TypeProfiler::functionHasExecutedCache):
+        (JSC::TypeProfiler::typeLocationCache):
+        * runtime/TypeProfilerLog.cpp: Added.
+        (JSC::TypeProfilerLog::initializeLog):
+        (JSC::TypeProfilerLog::~TypeProfilerLog):
+        (JSC::TypeProfilerLog::processLogEntries):
+        * runtime/TypeProfilerLog.h: Added.
+        (JSC::TypeProfilerLog::LogEntry::structureIDOffset):
+        (JSC::TypeProfilerLog::LogEntry::valueOffset):
+        (JSC::TypeProfilerLog::LogEntry::locationOffset):
+        (JSC::TypeProfilerLog::TypeProfilerLog):
+        (JSC::TypeProfilerLog::recordTypeInformationForLocation):
+        (JSC::TypeProfilerLog::logEndPtr):
+        (JSC::TypeProfilerLog::logStartOffset):
+        (JSC::TypeProfilerLog::currentLogEntryOffset):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::enableTypeProfiler):
+        (JSC::VM::disableTypeProfiler):
+        (JSC::VM::dumpTypeProfilerData):
+        (JSC::VM::enableHighFidelityTypeProfiling): Deleted.
+        (JSC::VM::disableHighFidelityTypeProfiling): Deleted.
+        (JSC::VM::dumpHighFidelityProfilingTypes): Deleted.
+        * runtime/VM.h:
+        (JSC::VM::typeProfilerLog):
+        (JSC::VM::typeProfiler):
+        (JSC::VM::isProfilingTypesWithHighFidelity): Deleted.
+        (JSC::VM::highFidelityLog): Deleted.
+        (JSC::VM::highFidelityTypeProfiler): Deleted.
+
+2014-08-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        URTBF after r172799.
+
+        * disassembler/ARM64/A64DOpcode.cpp:
+        * disassembler/ARM64Disassembler.cpp:
+
+2014-08-20  Oliver Hunt  <oliver@apple.com>
+
+        Stop implicitly skipping a function's own activation when walking the scope chain
+        https://bugs.webkit.org/show_bug.cgi?id=136118
+
+        Reviewed by Geoffrey Garen.
+
+        Remove the current logic that implicitly skips a function's
+        own activation when walking the scope chain. This is ground
+        work for ensuring that all closed variable access is made
+        through the function's activation. This leads to a further
+        10% regression on earley, but we're already tracking the
+        overall performance regression.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getScope):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitResolveClosure):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSScope.cpp:
+        (JSC::JSScope::abstractResolve):
+        * runtime/JSScope.h:
+
+2014-08-20  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION: Web Inspector crashes when reloading apple.com with Timeline recording active
+        https://bugs.webkit.org/show_bug.cgi?id=136034
+
+        Reviewed by Mark Lam.
+
+        DebuggerCallFrame::positionForCallFrame is trying to unwind starting somewhere in the middle
+        of the stack.  Hardened StackVisitor to skip over the frames between the current top frame
+        and the requested start frame.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::StackVisitor):
+
+2014-08-20  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] JavaScriptCore.dll is missing version information.
+        https://bugs.webkit.org/show_bug.cgi?id=136105
+        <rdar://problem/18075852>
+
+        Reviewed by Dean Jackson.
+
+        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd: Add missing step to generate
+        version information for intermediary build path.
+
+2014-08-20  Saam Barati  <sbarati@apple.com>
+
+        Fix a memory leak in TypeSet
+        https://bugs.webkit.org/show_bug.cgi?id=135913
+
+        Reviewed by Filip Pizlo.
+
+        Currently, TypeSet unconditionally allocates memory for its member
+        variable m_structureHistory, but never deallocates it. Change this 
+        from being a pointer that is unconditionally allocated to a member 
+        variable that will be deallocated when TypeSet itself is deallocated.
+
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::TypeSet):
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::seenTypes):
+        (JSC::TypeSet::displayName):
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::StructureShape::leastCommonAncestor):
+        * runtime/TypeSet.h:
+
+2014-08-20  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win] Assertion fails when running JSC stress tests.
+        https://bugs.webkit.org/show_bug.cgi?id=136103
+
+        Reviewed by Darin Adler.
+
+        Use unsigned bitfield member instead of enum bitfield member to avoid negative values.
+
+        * bytecode/CodeOrigin.h: Use unsigned bitfield member.
+        (JSC::InlineCallFrame::specializationKind): Compile fix.
+
+2014-08-20  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Enable ARM64 disassembler on EFL
+        https://bugs.webkit.org/show_bug.cgi?id=136089
+
+        Reviewed by Filip Pizlo.
+
+        * CMakeLists.txt:
+        Added disassembler/ARM64Disassembler.cpp and
+        disassembler/ARM64/A64DOpcode.cpp to JavaScriptCore_SOURCES.
+
+        * disassembler/ARM64/A64DOpcode.cpp:
+        Added USE(ARM64_DISASSEMBLER) guard around implementation.
+
+        * disassembler/ARM64/A64DOpcode.h:
+        (JSC::ARM64Disassembler::A64DOpcode::appendUnsignedImmediate64):
+        (JSC::ARM64Disassembler::A64DOpcode::appendPCRelativeOffset):
+        Made format strings portable by changing "%llx" to "%" PRIx64 for
+        uint64_t arguments.
+
+2014-08-19  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r172401): for-in optimization no longer works at all
+        https://bugs.webkit.org/show_bug.cgi?id=136056
+
+        Reviewed by Geoffrey Garen.
+        
+        Roll this back in, along with a fix to make proxies work. Previously, for-in over proxies
+        would instacrash every time.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetByVal):
+        (JSC::BytecodeGenerator::pushIndexedForInScope):
+        (JSC::BytecodeGenerator::pushStructureForInScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::ForInContext::ForInContext):
+        (JSC::StructureForInContext::StructureForInContext):
+        (JSC::IndexedForInContext::IndexedForInContext):
+        (JSC::ForInContext::base): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * runtime/JSProxy.cpp:
+        (JSC::JSProxy::getStructurePropertyNames):
+        (JSC::JSProxy::getGenericPropertyNames):
+        * tests/stress/for-in-base-reassigned-later-and-change-structure.js: Added.
+        (foo):
+        * tests/stress/for-in-base-reassigned-later.js: Added.
+        (foo):
+        * tests/stress/for-in-base-reassigned.js: Added.
+        (foo):
+        * tests/stress/for-in-proxy-target-changed-structure.js: Added.
+        (deleteAll):
+        (foo):
+        * tests/stress/for-in-proxy.js: Added.
+        (foo):
+
+2014-08-19  Jaehun Lim  <ljaehun.lim@samsung.com>
+
+        Unreviewed, fix EFL build after r17275
+
+        Fix error: ignoring #pragma clang diagnostic [-Werror=unknown-pragmas]
+
+        * runtime/JSDataViewPrototype.cpp:
+        Add #if COMPILER(CLANG) and #endif.
+
+2014-08-19  Michael Saboff  <msaboff@apple.com>
+
+        Crash in jsc-layout-tests.yaml/js/script-tests/reentrant-caching.js
+        https://bugs.webkit.org/show_bug.cgi?id=136080
+
+        Reviewed by Mark Lam.
+
+        Update VM::topVMEntryFrame via NativeCallFrameTracer() when we pass the caller's frame
+        to NativeCallFrameTracer() as the callee's frame may be the first callee from an entry
+        frame.  In that case, the caller will have the prior VM entry frame.
+
+        The new NativeCallFrameTracer with a VMEntryFrame parameter should be used when throwing
+        an exception from a caller frame.  The value to use for the VMEntryFrame should be a
+        value possibly modified by CallFrame::callerFrame(&*VMEntryFrame) used to find the caller.
+
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer): Added a new constructor that takes a
+        VMEntryFrame.  Added an ASSERT to both constructors to check that the updated topCallFrame
+        is below the current vmEntryFrame.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationThrowStackOverflowError):
+        (JSC::operationCallArityCheck):
+        (JSC::operationConstructArityCheck):
+        Set VM::topVMEntryFrame to the possibly updated VMEntryFrame after getting the caller's frame.
+
+2014-08-19  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] Offline Assembler build phase fails when $BUILT_PRODUCTS_DIR contains spaces
+        https://bugs.webkit.org/show_bug.cgi?id=136086
+
+        Reviewed by Filip Pizlo.
+
+        Enclosed arguments to asm.rb containing $BUILT_PRODUCTS_DIR in double quotes so that they don't get split on
+        whitespace. Also let Xcode have its way with an unrelated part of the project file.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-08-19  Filip Pizlo  <fpizlo@apple.com>
+
+        LLInt build should be way faster
+        https://bugs.webkit.org/show_bug.cgi?id=136085
+
+        Reviewed by Geoffrey Garen.
+        
+        This does three things to improve the LLInt build performance. One of them is only for
+        Xcode for now while the others should benefit all platforms:
+        
+        - Don't exponentially build settings combinations that correspond to being on two backends
+          simultaneously. This is by far the biggest win.
+        
+        - Don't generate offset extraction code for backends that aren't supported by the current
+          port. This currently only works on Xcode-based ports. This is a relatively small win.
+        
+        - Remove the ALWAYS_ALLOCATE_SLOW option. Each option increases build time, and we haven't
+          used this one in a long time. Anyway, setting this option could be emulated by just
+          directly hacking the code.
+        
+        This is an enormous speed-up in the LLInt build.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Prune the set of backends that we should consider on Xcode-based platforms.
+        * llint/LLIntOfflineAsmConfig.h: Remove ALWAYS_ALLOCATE_SLOW
+        * llint/LowLevelInterpreter.asm: Remove ALWAYS_ALLOCATE_SLOW
+        * offlineasm/backends.rb: Add infrastructure for reasoning about valid backends.
+        * offlineasm/generate_offset_extractor.rb: Allow the client to specify a filtered set of valid backends.
+        * offlineasm/settings.rb: Improve the construction of settings combinations so that it doesn't traverse the enourmous set of obviously invalid multi-backend combinations. Also glue into support for valid backends.
+
+2014-08-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix indentation and style in LowLevelInterpreter.asm
+        https://bugs.webkit.org/show_bug.cgi?id=136083
+
+        Reviewed by Mark Lam.
+
+        * llint/LowLevelInterpreter.asm:
+
+2014-08-19  Magnus Granberg  <zorry@gentoo.org>
+
+        TEXTREL in libjavascriptcoregtk-1.0.so.0.11.0 on x86 (or i586)
+        https://bugs.webkit.org/show_bug.cgi?id=70610
+
+        Reviewed by Darin Adler.
+
+        Setup %ebx so we can use the plt.
+
+        * jit/ThunkGenerators.cpp:
+
+2014-08-19  Zalan Bujtas  <zalan@apple.com>
+
+        Remove ENABLE(SUBPIXEL_LAYOUT).
+        https://bugs.webkit.org/show_bug.cgi?id=136077
+
+        Reviewed by Simon Fraser.
+
+        Remove compile time flag SUBPIXEL_LAYOUT. All ports have it enabled for a while now.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-19  Alex Christensen  <achristensen@webkit.org>
+
+        [CMake] Generate LLInt assembly correctly on Windows.
+        https://bugs.webkit.org/show_bug.cgi?id=135888
+
+        Reviewed by Oliver Hunt.
+
+        * CMakeLists.txt:
+        Generate LowLevelInterpreterWin.asm instead of LLIntAssembly.h on Windows like the existing build system.
+        * PlatformWin.cmake:
+        Don't build JSGlobalObjectInspectorController.cpp on Windows.
+        * offlineasm/x86.rb:
+        Detect non-cygwin ruby installations correctly.
+
+2014-08-19  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r163179): It broke the build on ARM Thumb2 with GCC
+        https://bugs.webkit.org/show_bug.cgi?id=136028
+
+        Reviewed by Oliver Hunt.
+
+        Added back ARMv7 conditionals around three op addp and subp since ARM Thumb2 spec says that
+        the behavior for those ops are undefined.  This was originally done in changeset 163179.
+
+        * llint/LowLevelInterpreter32_64.asm:
+
+2014-08-18  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r172741.
+        https://bugs.webkit.org/show_bug.cgi?id=136058
+
+        This change is breaking PLT. (Requested by mlam on #webkit).
+
+        Reverted changeset:
+
+        "REGRESSION(r172401): for-in optimization no longer works at
+        all"
+        https://bugs.webkit.org/show_bug.cgi?id=136056
+        http://trac.webkit.org/changeset/172741
+
+2014-08-18  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r172401): for-in optimization no longer works at all
+        https://bugs.webkit.org/show_bug.cgi?id=136056
+
+        Reviewed by Mark Hahnenberg.
+        
+        This is a partial roll-out of r172401. It turns out that the fix wasn't actually fixing a
+        real bug (since it's fine to use op_get_direct_pname on the wrong base because it has a
+        structure check) and it was actually breaking the entire for-in optimization (since there is
+        no way that we can statically prove that the base matches, because the base we see is a
+        newly created temporary, and anyway doing it right would be really hard in our bytecode
+        because it's 3AC form).
+        
+        But, I added a new test for the problem, and kept the original test. Both the old test and
+        the new test prove that r172401 wasn't fixing what it thought it was fixing. To the extent
+        that it resolved crashes it was because it just disabled the for-in optimization entirely.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetByVal):
+        (JSC::BytecodeGenerator::pushIndexedForInScope):
+        (JSC::BytecodeGenerator::pushStructureForInScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::ForInContext::ForInContext):
+        (JSC::StructureForInContext::StructureForInContext):
+        (JSC::IndexedForInContext::IndexedForInContext):
+        (JSC::ForInContext::base): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * tests/stress/for-in-base-reassigned.js: Added.
+        * tests/stress/for-in-base-reassigned-later.js: Added.
+        * tests/stress/for-in-base-reassigned-later-and-change-structure.js: Added.
+
+2014-08-18  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: build fix for non-Mac builds after r172737.
+        https://bugs.webkit.org/show_bug.cgi?id=135750
+
+        Not reviewed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-08-18  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r172129): ftlopt branch merge made performance tests flakey crash
+        https://bugs.webkit.org/show_bug.cgi?id=135750
+
+        Reviewed by Mark Lam.
+        
+        This was caused by a rather embarrassing oversight in how the DFG tracks structures: we
+        could sometimes perform an optimization that requires a structure to be alive but forget to
+        ensure that the structure is actually kept alive. In particular, any watchpoint-based
+        optimizations involve setting watchpoints even if the code that got optimized is eventually
+        deleted because it is unreachable. All such optimizations would leave behind something in
+        the IR to tell us that we are interested in the structure and that therefore it should be
+        kept alive. But, IR can be deleted if it is unreachable.
+        
+        The solution is to ensure that as soon as the DFG is made aware of a structure, it adds it
+        to the set of weak references.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setOSREntryValue):
+        (JSC::DFG::AbstractValue::set):
+        (JSC::DFG::AbstractValue::normalizeClarity):
+        (JSC::DFG::AbstractValue::assertIsRegistered):
+        (JSC::DFG::AbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::assertIsRegistered):
+        (JSC::DFG::AbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+        * dfg/DFGDesiredWeakReferences.cpp:
+        (JSC::DFG::DesiredWeakReferences::addLazily):
+        (JSC::DFG::DesiredWeakReferences::contains):
+        (JSC::DFG::DesiredWeakReferences::reallyAdd):
+        (JSC::DFG::DesiredWeakReferences::visitChildren):
+        * dfg/DFGDesiredWeakReferences.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::registerFrozenValues):
+        (JSC::DFG::Graph::convertToConstant):
+        (JSC::DFG::Graph::registerStructure):
+        (JSC::DFG::Graph::assertIsRegistered):
+        (JSC::DFG::Graph::assertIsWatched): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::assertIsRegistered):
+        (JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::assertIsRegistered):
+        (JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGStructureRegistrationPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp.
+        (JSC::DFG::StructureRegistrationPhase::StructureRegistrationPhase):
+        (JSC::DFG::StructureRegistrationPhase::run):
+        (JSC::DFG::StructureRegistrationPhase::registerStructures):
+        (JSC::DFG::StructureRegistrationPhase::registerStructure):
+        (JSC::DFG::performStructureRegistration):
+        (JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase): Deleted.
+        (JSC::DFG::WatchableStructureWatchingPhase::run): Deleted.
+        (JSC::DFG::WatchableStructureWatchingPhase::tryWatch): Deleted.
+        (JSC::DFG::performWatchableStructureWatching): Deleted.
+        * dfg/DFGStructureRegistrationPhase.h: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h.
+        * dfg/DFGWatchableStructureWatchingPhase.cpp: Removed.
+        * dfg/DFGWatchableStructureWatchingPhase.h: Removed.
+
+2014-08-18  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Fix ASSERT in ARM64's JSC::GPRInfo::debugName
+        https://bugs.webkit.org/show_bug.cgi?id=136050
+
+        Reviewed by Darin Adler.
+
+        Remove cast of GPRReg to unsigned to prevent signed/unsigned comparison
+        error.
+
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::debugName):
+
+2014-08-18  Andreas Kling  <akling@apple.com>
+
+        REGRESSION(r168256): JSString can get 8-bit flag wrong when re-using AtomicStrings.
+        <https://webkit.org/b/133574>
+        <rdar://problem/18051847>
+
+        The optimization that resolves JSRopeStrings into an existing
+        AtomicString (to save time and memory by avoiding StringImpl allocation)
+        had a bug that it wasn't copying the 8-bit flag from the AtomicString.
+
+        This could lead to a situation where a 16-bit StringImpl containing
+        only 8-bit characters is sitting in the AtomicString table, is found
+        by the rope resolution optimization, and gives you a rope that thinks
+        it's all 8-bit, but has a fiber with 16-bit characters.
+
+        Resolving that rope will then yield incorrect results.
+
+        This was all caught by an assertion, but very hard to reproduce.
+
+        Test: js/dopey-rope-with-16-bit-propertyname.html
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeToAtomicString):
+        (JSC::JSRopeString::resolveRopeToExistingAtomicString):
+        * runtime/JSString.h:
+        (JSC::JSString::setIs8Bit):
+        (JSC::JSString::toExistingAtomicString):
+
+2014-08-18  Matthew Mirman  <mmirman@apple.com>
+
+        Merges the two native inlining passes from the build.
+        Also adds the AvailableExternallyLinkage assertion to linked 
+        functions to allow unused and duplicate ones to be removed.
+        https://bugs.webkit.org/show_bug.cgi?id=135526
+
+        Reviewed by Filip Pizlo.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: 
+        Removed second generation of llvm binary files.
+        Fixed the flags on the first pass. 
+        * build-symbol-table-index.py: Modified some paths.
+        * build-symbol-table-index.sh: Removed.
+        * copy-llvm-ir-to-derived-sources.sh: Now calls build-symbol-table-index directly.
+        * ftl/FTLLowerDFGToLLVM.cpp: Added LLVMAvailableExternallyLinkage assertion.
+        (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): 
+        * runtime/ArrayPrototype.cpp: Removed static declarations. 
+        * runtime/DateConstructor.cpp: ditto.
+        (JSC::dateParse):
+        (JSC::dateNow):
+        (JSC::dateUTC):
+        * runtime/DatePrototype.cpp: ditto.
+        * runtime/JSDataViewPrototype.cpp: ditto on both.
+        (JSC::dataViewProtoFuncGetInt8):
+        (JSC::dataViewProtoFuncGetInt16):
+        (JSC::dataViewProtoFuncGetInt32):
+        (JSC::dataViewProtoFuncGetUint8):
+        (JSC::dataViewProtoFuncGetUint16):
+        (JSC::dataViewProtoFuncGetUint32):
+        (JSC::dataViewProtoFuncGetFloat32):
+        (JSC::dataViewProtoFuncGetFloat64):
+        (JSC::dataViewProtoFuncSetInt8):
+        (JSC::dataViewProtoFuncSetInt16):
+        (JSC::dataViewProtoFuncSetInt32):
+        (JSC::dataViewProtoFuncSetUint8):
+        (JSC::dataViewProtoFuncSetUint16):
+        (JSC::dataViewProtoFuncSetUint32):
+        (JSC::dataViewProtoFuncSetFloat32):
+        (JSC::dataViewProtoFuncSetFloat64):
+        * runtime/JSONObject.cpp: ditto.
+        * runtime/ObjectConstructor.cpp: ditto.
+        * runtime/StringPrototype.cpp: ditto.
+
+2014-08-18  Saam Barati  <sbarati@apple.com>
+
+        The parser should generate AST nodes the var declarations with no initializers
+        https://bugs.webkit.org/show_bug.cgi?id=135545
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, JSC's parser ignores variable declarations
+        that have no assignment initializer value because all 
+        variables are implicitly assigned to undefined. But, 
+        type profiling needs an AST node to be generated for these 
+        empty variable declarations because it needs to be able to 
+        profile their text locations and to see that their type 
+        is undefined.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::EmptyVarExpression::emitBytecode):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createVarStatement):
+        (JSC::ASTBuilder::createEmptyVarExpression):
+        * parser/NodeConstructors.h:
+        (JSC::EmptyVarExpression::EmptyVarExpression):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createEmptyVarExpression):
+
+2014-08-18  Diego Pino Garcia  <dpino@igalia.com>
+
+        Completed iterator can be revived by adding more than one new entry to the target object
+        https://bugs.webkit.org/show_bug.cgi?id=129993
+
+        Reviewed by Oliver Hunt.
+
+        When iterator reaches end, finish iterator.
+
+        * runtime/JSMapIterator.h:
+        (JSC::JSMapIterator::finish):
+        * runtime/JSSetIterator.h:
+        (JSC::JSSetIterator::finish):
+        * runtime/MapData.h:
+        (JSC::MapData::const_iterator::finish): set index of iterator to max
+        Int32.
+        * runtime/MapIteratorPrototype.cpp:
+        (JSC::MapIteratorPrototypeFuncNext):
+        * runtime/SetIteratorPrototype.cpp:
+        (JSC::SetIteratorPrototypeFuncNext):
+
+2014-08-15  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: rewrite CodeGeneratorInspector to be modular and testable
+        https://bugs.webkit.org/show_bug.cgi?id=131596
+
+        Unreviewed gardening to rebaseline inspector generator tests after addressing review comments.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
+2014-08-15  Brian J. Burg  <burg@cs.washington.edu>
+
+        Unreviewed build fix for some GTK bots after r172655.
+
+        Some bots use Python 2.6, which lacks the 'flags' named parameter for re.sub.
+
+        * inspector/scripts/codegen/generator.py:
+        (Generator.stylized_name_for_enum_value): Do things the old-school way.
+
+2014-08-15  Michael Saboff  <msaboff@apple.com>
+
+        Change callToJavaScript and callToNativeFunction so their callFrames match the native calling conventions
+        https://bugs.webkit.org/show_bug.cgi?id=131578
+
+        Reviewed by Geoffrey Garen.
+
+        Renamed callToJavaScript and callToNativeFunction to vmEntryToJavaScript and vmEntryToNative,
+        respectively.  Eliminated the sentinel frame and replaced it with the structure VMEntryRecord
+        that appears in the "locals" area of a VM entry stack frame.  Changed the order that
+        vmEntryToJavaScript and vmEntryToNative creates their stack frames to be native calling
+        convention compliant.  That is to save prior frame pointer, save callee save registers, then
+        allocate and populate the VMEntryRecord, and finally allocate a CallFrame for the JS function
+        that vmEntryToJavaScript will invoke.  The top most vm entry frame pointer is saved in
+        VM::topVMEntryFrame.  The vmEntry functions save prior contents of VM::topVMEntryFrame
+        along with the VM and VM::topCallFrame in the VMEntryRecord it places on the stack.  Starting
+        at VM::topCallFrame, the stack can be walked using these VMEntryRecords.
+
+        Arbitrary stack unwinding is now handled either iteratively by loading VM::topVMEntryFrame
+        into a local variable and using CallFrame::callerFrame(VMEntryFrame*&) or by using StackVisitor.
+        Given that the stack is effectively a singly linked list, general stack unwinding needs to use
+        one of these two methods.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Addition of VMEntryRecord.h
+
+        * bytecode/BytecodeList.json:
+        Renaming of llint helper opcodes due to renaming callToJavaScript and callToNativeFunction.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::stepOutOfFunction):
+        (JSC::Debugger::returnEvent):
+        (JSC::Debugger::didExecuteProgram):
+        * jsc.cpp:
+        (functionDumpCallFrame):
+        * jit/JITOperations.cpp:
+        Changed unwinding to use CallFrame::callerFrame(VMEntryFrame*&).
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::RecursionCheckFunctor::RecursionCheckFunctor):
+        (JSC::RecursionCheckFunctor::operator()):
+        (JSC::RecursionCheckFunctor::didRecurse):
+        (JSC::CodeBlock::noticeIncomingCall):
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor):
+        (JSC::FindCallerMidStackFunctor::operator()):
+        (JSC::FindCallerMidStackFunctor::getCallerFrame):
+        (JSC::DebuggerCallFrame::callerFrame):
+        * interpreter/VMInspector.cpp:
+        (JSC::CountFramesFunctor::CountFramesFunctor):
+        (JSC::CountFramesFunctor::operator()):
+        (JSC::CountFramesFunctor::count):
+        (JSC::VMInspector::countFrames):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
+        (JSC::VM::throwException):
+        Changed unwinding to use StackVisitor including added functor classes.
+
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::callerFrame):
+        Added new flavor of callerFrame() that can iteratively unwind the stack.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::callerFrame): Changed callerFrame() to use private common helper.
+        (JSC::ExecState::callerFrameOrVMEntryFrame): Deleted.
+        (JSC::ExecState::isVMEntrySentinel): Deleted.
+        (JSC::ExecState::vmEntrySentinelCallerFrame): Deleted.
+        (JSC::ExecState::initializeVMEntrySentinelFrame): Deleted.
+        (JSC::ExecState::callerFrameSkippingVMEntrySentinel): Deleted.
+        (JSC::ExecState::vmEntrySentinelCodeBlock): Deleted.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::init):
+        (JSC::ExecState::topOfFrame):
+        (JSC::ExecState::currentVPC):
+        (JSC::ExecState::setCurrentVPC):
+        Eliminated unneded checking of sentinel frame.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        (JSC::Interpreter::getStackTrace): Updated for unwidning changes.
+        (JSC::Interpreter::unwind): Eliminated unneeded sentinel frame check.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        * jit/JITStubs.h:
+        * llint/LLIntThunks.cpp:
+        (JSC::callToJavaScript): Deleted.
+        (JSC::callToNativetion): Deleted.
+        (JSC::vmEntryToJavaScript):
+        (JSC::vmEntryToNative):
+        * llint/LLIntThunks.h:
+        Updated for vmEntryToJavaScript and vmEntryToNative name changes.
+
+        * interpreter/Interpreter.h:
+        (JSC::TopCallFrameSetter::TopCallFrameSetter):
+        (JSC::TopCallFrameSetter::~TopCallFrameSetter):
+        Eliminated unneeded sentinel frame check.
+
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        Removed sentinel specific constructor.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::StackVisitor):
+        (JSC::StackVisitor::readFrame):
+        (JSC::StackVisitor::readNonInlinedFrame):
+        (JSC::StackVisitor::readInlinedFrame):
+        (JSC::StackVisitor::Frame::print):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::callerIsVMEntry):
+        Changes for unwinding using CallFrame::callerFrame(VMEntryFrame*&).  Also added field that
+        indicates when about to step over a VM entry frame.
+
+        * interpreter/VMEntryRecord.h: Added.
+        (JSC::VMEntryRecord::prevTopCallFrame):
+        (JSC::VMEntryRecord::prevTopVMEntryFrame):
+        New struct to record prior state of VM's notion of VM entry and top call frames.
+
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute):
+        Use new vmEntryToJavaScript and vmEntryToNative name.
+
+        * llint/LLIntOffsetsExtractor.cpp: Added include for VMEntryRecord.h.
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Offline assembly implementation of creating stack frame with VMEntryRecord and well as restoring 
+        relevent VM fields when exiting the VM.  Added a helper that returns a VMEntryRecord given
+        a pointer to the VM entry frame.
+
+        * llint/LLIntThunks.cpp:
+        (JSC::vmEntryRecord):
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoop::execute):
+        C Loop changes to mirror the assembly changes.
+
+        * runtime/VM.h:
+        Added topVMEntryFrame field.
+
+2014-08-15  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: rewrite CodeGeneratorInspector to be modular and testable
+        https://bugs.webkit.org/show_bug.cgi?id=131596
+
+        Reviewed by Joseph Pecoraro.
+
+        Replace CodeGeneratorInspector.py with generate-inspector-protocol-bindings.py.
+        The new generator decouples parsing and typechecking a model of the protocol from
+        code generation. Each generated file is created by a different subclass of Generator.
+        Helper methods to compute various type signatures are shared among generators.
+
+        This patch introduces a test harness and a test suite that covers all functionality.
+
+        Aside from hooking up the new inspector bindings generator to the build system,
+        there are a few comingled changes that would be painful to split from the main
+        patch:
+
+        Convert protocol enumeration types from struct-namespaced enums to C++ scoped enums.
+
+        Move all runtimeCast(), assertValueHasExpectedType(), and RuntimeCastHelper methods to static
+        methods of BindingTraits specializations.
+
+        Together, these changes reduce duplication and make it possible to forward-declare
+        all protocol enum and object types, reducing weird ordering dependencies between domains.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Add inspector scripts to solution filters.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/ConsoleMessage.cpp: Convert to scoped enums.
+        (Inspector::messageSourceValue):
+        (Inspector::messageTypeValue):
+        (Inspector::messageLevelValue):
+        * inspector/InjectedScript.cpp: Convert to scoped enums and BindingTraits.
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        (Inspector::InjectedScript::wrapCallFrames):
+        (Inspector::InjectedScript::wrapObject):
+        (Inspector::InjectedScript::wrapTable):
+        * inspector/InjectedScriptBase.cpp: Convert InspectorValue::Type to a scoped enum.
+        (Inspector::InjectedScriptBase::makeEvalCall):
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::injectedScriptForObjectId):
+        * inspector/InspectorTypeBuilder.h:
+        (Inspector::TypeBuilder::Array::create):
+        (Inspector::TypeBuilder::StructItemTraits::pushRefPtr):
+        (Inspector::TypeBuilder::ArrayItemHelper<String>::Traits::pushRaw):
+        (Inspector::TypeBuilder::ArrayItemHelper<int>::Traits::pushRaw):
+        (Inspector::TypeBuilder::ArrayItemHelper<double>::Traits::pushRaw):
+        (Inspector::TypeBuilder::ArrayItemHelper<bool>::Traits::pushRaw):
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorValue>::Traits::pushRefPtr):
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorObject>::Traits::pushRefPtr):
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorArray>::Traits::pushRefPtr):
+        (Inspector::TypeBuilder::PrimitiveBindingTraits::assertValueHasExpectedType):
+        (Inspector::TypeBuilder::BindingTraits<TypeBuilder::Array<T>>::runtimeCast):
+        (Inspector::TypeBuilder::BindingTraits<TypeBuilder::Array<T>>::assertValueHasExpectedType):
+        (Inspector::TypeBuilder::BindingTraits<InspectorValue>::assertValueHasExpectedType):
+        (Inspector::TypeBuilder::BindingTraits<int>::assertValueHasExpectedType):
+        (Inspector::TypeBuilder::ExactlyInt::ExactlyInt): Deleted. It was not used.
+        (Inspector::TypeBuilder::ExactlyInt::operator int): Deleted.
+        (Inspector::TypeBuilder::ExactlyInt::cast_to_int): Deleted.
+        (Inspector::TypeBuilder::ExactlyInt::cast_to_int<int>): Deleted.
+        (Inspector::TypeBuilder::int>): Deleted.
+        (Inspector::TypeBuilder::RuntimeCastHelper::assertType): Deleted.
+        (Inspector::TypeBuilder::RuntimeCastHelper::assertAny): Deleted.
+        (Inspector::TypeBuilder::RuntimeCastHelper::assertInt): Deleted.
+        (Inspector::TypeBuilder::Array::runtimeCast): Deleted.
+        (Inspector::TypeBuilder::Array::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::StructItemTraits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<String>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<int>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<double>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<bool>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorValue>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorObject>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<InspectorArray>::Traits::assertCorrectValue): Deleted.
+        (Inspector::TypeBuilder::ArrayItemHelper<TypeBuilder::Array<T>>::Traits::assertCorrectValue): Deleted.
+
+        * inspector/InspectorValues.cpp: Convert InspectorValue::Type to a scoped enum.
+        (Inspector::InspectorValue::writeJSON):
+        (Inspector::InspectorBasicValue::asBoolean):
+        (Inspector::InspectorBasicValue::asNumber):
+        (Inspector::InspectorBasicValue::writeJSON):
+        (Inspector::InspectorString::writeJSON):
+        (Inspector::InspectorObjectBase::InspectorObjectBase):
+        (Inspector::InspectorObjectBase::setArray): Take InspectorArrayBase.
+        (Inspector::InspectorObjectBase::setObject): Take InspectorObjectBase.
+        (Inspector::InspectorArrayBase::InspectorArrayBase):
+        * inspector/InspectorValues.h:
+
+        * inspector/agents/InspectorDebuggerAgent.cpp: Convert to scoped enums.
+        (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+        (Inspector::InspectorDebuggerAgent::breakProgram):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::parse):
+        * inspector/agents/InspectorRuntimeAgent.h:
+
+        * inspector/scripts/CodeGeneratorInspector.py: Removed.
+        * inspector/scripts/codegen/__init__.py: Added.
+        * inspector/scripts/codegen/generate_backend_commands.py: Added.
+        (BackendCommandsGenerator):
+        (BackendCommandsGenerator.__init__):
+        (BackendCommandsGenerator.model):
+        (BackendCommandsGenerator.output_filename):
+        (BackendCommandsGenerator.generate_license):
+        (BackendCommandsGenerator.generate_output):
+        (BackendCommandsGenerator.generate_domain):
+        (BackendCommandsGenerator.generate_domain.is_anonymous_enum_member):
+        (BackendCommandsGenerator.generate_domain.generate_parameter_object):
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py: Added.
+        (BackendDispatcherHeaderGenerator):
+        (BackendDispatcherHeaderGenerator.__init__):
+        (BackendDispatcherHeaderGenerator.model):
+        (BackendDispatcherHeaderGenerator.output_filename):
+        (BackendDispatcherHeaderGenerator.generate_license):
+        (BackendDispatcherHeaderGenerator.generate_output):
+        (BackendDispatcherHeaderGenerator.generate_output.for):
+        (BackendDispatcherHeaderGenerator._generate_handler_declarations_for_domain):
+        (BackendDispatcherHeaderGenerator._generate_anonymous_enum_for_parameter):
+        (BackendDispatcherHeaderGenerator._generate_handler_declaration_for_command):
+        (BackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        (BackendDispatcherHeaderGenerator._generate_dispatcher_declarations_for_domain):
+        (BackendDispatcherHeaderGenerator._generate_dispatcher_declaration_for_command):
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py: Added.
+        (BackendDispatcherImplementationGenerator):
+        (BackendDispatcherImplementationGenerator.__init__):
+        (BackendDispatcherImplementationGenerator.model):
+        (BackendDispatcherImplementationGenerator.output_filename):
+        (BackendDispatcherImplementationGenerator.generate_license):
+        (BackendDispatcherImplementationGenerator.generate_output):
+        (BackendDispatcherImplementationGenerator._generate_handler_class_destructor_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementations_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_small_dispatcher_switch_implementation_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_large_dispatcher_switch_implementation_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_async_dispatcher_class_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_header.py: Added.
+        (FrontendDispatcherHeaderGenerator):
+        (FrontendDispatcherHeaderGenerator.__init__):
+        (FrontendDispatcherHeaderGenerator.model):
+        (FrontendDispatcherHeaderGenerator.output_filename):
+        (FrontendDispatcherHeaderGenerator.generate_license):
+        (FrontendDispatcherHeaderGenerator.generate_output):
+        (FrontendDispatcherHeaderGenerator._generate_anonymous_enum_for_parameter):
+        (FrontendDispatcherHeaderGenerator._generate_dispatcher_declarations_for_domain):
+        (FrontendDispatcherHeaderGenerator._generate_dispatcher_declaration_for_event):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py: Added.
+        (FrontendDispatcherImplementationGenerator):
+        (FrontendDispatcherImplementationGenerator.__init__):
+        (FrontendDispatcherImplementationGenerator.model):
+        (FrontendDispatcherImplementationGenerator.output_filename):
+        (FrontendDispatcherImplementationGenerator.generate_license):
+        (FrontendDispatcherImplementationGenerator.generate_output):
+        (FrontendDispatcherImplementationGenerator._generate_dispatcher_implementations_for_domain):
+        (FrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_type_builder_header.py: Added.
+        (TypeBuilderHeaderGenerator):
+        (TypeBuilderHeaderGenerator.__init__):
+        (TypeBuilderHeaderGenerator.model):
+        (TypeBuilderHeaderGenerator.output_filename):
+        (TypeBuilderHeaderGenerator.generate_license):
+        (TypeBuilderHeaderGenerator.generate_output):
+        (TypeBuilderHeaderGenerator._generate_forward_declarations):
+        (_generate_typedefs):
+        (_generate_typedefs_for_domain):
+        (_generate_builders_for_domain):
+        (_generate_class_for_object_declaration):
+        (_generate_struct_for_enum_declaration):
+        (_generate_struct_for_anonymous_enum_member):
+        (_generate_struct_for_anonymous_enum_member.apply_indentation):
+        (_generate_struct_for_enum_type):
+        (_generate_builder_state_enum):
+        (_generate_builder_setter_for_member):
+        (_generate_unchecked_setter_for_member):
+        (_generate_forward_declarations_for_binding_traits):
+        * inspector/scripts/codegen/generate_type_builder_implementation.py: Added.
+        (TypeBuilderImplementationGenerator):
+        (TypeBuilderImplementationGenerator.__init__):
+        (TypeBuilderImplementationGenerator.model):
+        (TypeBuilderImplementationGenerator.output_filename):
+        (TypeBuilderImplementationGenerator.generate_license):
+        (TypeBuilderImplementationGenerator.generate_output):
+        (TypeBuilderImplementationGenerator._generate_enum_mapping):
+        (TypeBuilderImplementationGenerator._generate_open_field_names):
+        (TypeBuilderImplementationGenerator._generate_builders_for_domain):
+        (TypeBuilderImplementationGenerator._generate_runtime_cast_for_object_declaration):
+        (TypeBuilderImplementationGenerator._generate_assertion_for_object_declaration):
+        (TypeBuilderImplementationGenerator._generate_assertion_for_enum):
+        * inspector/scripts/codegen/generator.py: Added.
+        (ucfirst):
+        (Generator):
+        (Generator.__init__):
+        (Generator.model):
+        (Generator.generate_license):
+        (Generator.domains_to_generate):
+        (Generator.generate_output):
+        (Generator.output_filename):
+        (Generator.encoding_for_enum_value):
+        (Generator.assigned_enum_values):
+        (Generator.type_needs_runtime_casts):
+        (Generator.type_has_open_fields):
+        (Generator.type_needs_shape_assertions):
+        (Generator.calculate_types_requiring_shape_assertions):
+        (Generator.calculate_types_requiring_shape_assertions.gather_transitively_referenced_types):
+        (Generator._traverse_and_assign_enum_values):
+        (Generator._assign_encoding_for_enum_value):
+        (Generator.wrap_with_guard_for_domain):
+        (Generator.stylized_name_for_enum_value):
+        (Generator.stylized_name_for_enum_value.replaceCallback):
+        (Generator.keyed_get_method_for_type):
+        (Generator.keyed_set_method_for_type):
+        (Generator.type_builder_string_for_type):
+        (Generator.type_builder_string_for_type_member):
+        (Generator.type_string_for_unchecked_formal_in_parameter):
+        (Generator.type_string_for_checked_formal_event_parameter):
+        (Generator.type_string_for_type_member):
+        (Generator.type_string_for_type_with_name):
+        (Generator.type_string_for_formal_out_parameter):
+        (Generator.type_string_for_formal_async_parameter):
+        (Generator.type_string_for_stack_in_parameter):
+        (Generator.type_string_for_stack_out_parameter):
+        (Generator.assertion_method_for_type_member):
+        (Generator.assertion_method_for_type_member.assertion_method_for_type):
+        (Generator.cpp_name_for_primitive_type):
+        (Generator.js_name_for_parameter_type):
+        (Generator.should_use_wrapper_for_return_type):
+        (Generator.should_pass_by_copy_for_return_type):
+        * inspector/scripts/codegen/generator_templates.py: Added.
+        (GeneratorTemplates):
+        (void):
+        (HashMap):
+        (Builder):
+        (Inspector):
+        * inspector/scripts/codegen/models.py: Added.
+        (ucfirst):
+        (ParseException):
+        (TypecheckException):
+        (Framework):
+        (Framework.__init__):
+        (Framework.setting):
+        (Framework.fromString):
+        (Frameworks):
+        (TypeReference):
+        (TypeReference.__init__):
+        (TypeReference.referenced_name):
+        (Type):
+        (Type.__init__):
+        (Type.__eq__):
+        (Type.__hash__):
+        (Type.raw_name):
+        (Type.is_enum):
+        (Type.type_domain):
+        (Type.qualified_name):
+        (Type.resolve_type_references):
+        (PrimitiveType):
+        (PrimitiveType.__init__):
+        (PrimitiveType.__repr__):
+        (PrimitiveType.type_domain):
+        (PrimitiveType.qualified_name):
+        (AliasedType):
+        (AliasedType.__init__):
+        (AliasedType.__repr__):
+        (AliasedType.is_enum):
+        (AliasedType.type_domain):
+        (AliasedType.qualified_name):
+        (AliasedType.resolve_type_references):
+        (EnumType):
+        (EnumType.__init__):
+        (EnumType.__repr__):
+        (EnumType.is_enum):
+        (EnumType.type_domain):
+        (EnumType.enum_values):
+        (EnumType.qualified_name):
+        (EnumType.resolve_type_references):
+        (ArrayType):
+        (ArrayType.__init__):
+        (ArrayType.__repr__):
+        (ArrayType.type_domain):
+        (ArrayType.qualified_name):
+        (ArrayType.resolve_type_references):
+        (ObjectType):
+        (ObjectType.__init__):
+        (ObjectType.__repr__):
+        (ObjectType.type_domain):
+        (ObjectType.qualified_name):
+        (check_for_required_properties):
+        (Protocol):
+        (Protocol.__init__):
+        (Protocol.parse_specification):
+        (Protocol.parse_domain):
+        (Protocol.parse_type_declaration):
+        (Protocol.parse_type_member):
+        (Protocol.parse_command):
+        (Protocol.parse_event):
+        (Protocol.parse_call_or_return_parameter):
+        (Protocol.resolve_types):
+        (Protocol.lookup_type_for_declaration):
+        (Protocol.lookup_type_reference):
+        (Domain):
+        (Domain.__init__):
+        (Domain.resolve_type_references):
+        (Domains):
+        (TypeDeclaration):
+        (TypeDeclaration.__init__):
+        (TypeDeclaration.resolve_type_references):
+        (TypeMember):
+        (TypeMember.__init__):
+        (TypeMember.resolve_type_references):
+        (Parameter):
+        (Parameter.__init__):
+        (Parameter.resolve_type_references):
+        (Command):
+        (Command.__init__):
+        (Command.resolve_type_references):
+        (Event):
+        (Event.__init__):
+        (Event.resolve_type_references):
+        * inspector/scripts/generate-inspector-protocol-bindings.py: Added.
+        (IncrementalFileWriter):
+        (IncrementalFileWriter.__init__):
+        (IncrementalFileWriter.write):
+        (IncrementalFileWriter.close):
+        (generate_from_specification):
+        (generate_from_specification.load_specification):
+        * inspector/scripts/tests/commands-with-async-attribute.json: Added.
+        * inspector/scripts/tests/commands-with-optional-call-return-parameters.json: Added.
+        * inspector/scripts/tests/domains-with-varying-command-sizes.json: Added.
+        * inspector/scripts/tests/events-with-optional-parameters.json: Added.
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result: Added.
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result: Added.
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result: Added.
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result: Added.
+        * inspector/scripts/tests/fail-on-duplicate-type-declarations.json-error: Added.
+        * inspector/scripts/tests/fail-on-enum-with-no-values.json-error: Added.
+        * inspector/scripts/tests/fail-on-type-declaration-using-type-reference.json-error: Added.
+        * inspector/scripts/tests/fail-on-type-with-lowercase-name.json-error: Added.
+        * inspector/scripts/tests/fail-on-unknown-type-reference-in-type-declaration.json-error: Added.
+        * inspector/scripts/tests/fail-on-unknown-type-reference-in-type-member.json-error: Added.
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result: Added.
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result: Added.
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result: Added.
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result: Added.
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result: Added.
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result: Added.
+        * inspector/scripts/tests/fail-on-duplicate-type-declarations.json: Added.
+        * inspector/scripts/tests/fail-on-enum-with-no-values.json: Added.
+        * inspector/scripts/tests/fail-on-type-declaration-using-type-reference.json: Added.
+        * inspector/scripts/tests/fail-on-type-with-lowercase-name.json: Added.
+        * inspector/scripts/tests/fail-on-unknown-type-reference-in-type-declaration.json: Added.
+        * inspector/scripts/tests/fail-on-unknown-type-reference-in-type-member.json: Added.
+        * inspector/scripts/tests/same-type-id-different-domain.json: Added.
+        * inspector/scripts/tests/type-declaration-aliased-primitive-type.json: Added.
+        * inspector/scripts/tests/type-declaration-array-type.json: Added.
+        * inspector/scripts/tests/type-declaration-enum-type.json: Added.
+        * inspector/scripts/tests/type-declaration-object-type.json: Added.
+        * inspector/scripts/tests/type-requiring-runtime-casts.json: Added.
+
+2014-08-15  Matthew Mirman  <mmirman@apple.com>
+
+        Made native inlining errors not segfault. 
+        https://bugs.webkit.org/show_bug.cgi?id=135988
+        
+        Reviewed by Geoffrey Garen.
+
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::disposeMessage): Added.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compilePutById): 
+        abstracted out Options::verboseCompilation as was the case in the rest of the file.
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): 
+        added output error messages for llvm module loading.
+
+2014-08-14  Andreas Kling  <akling@apple.com>
+
+        Allocate the whole RegExpMatchesArray backing store up front.
+        <https://webkit.org/b/135217>
+
+        We were using the generic array backing store allocation path for
+        RegExpMatchesArray which meant starting with 4 slots and then growing
+        it dynamically as we append. Since we always know the final number of
+        entries up front, allocate a perfectly-sized backing store right away.
+
+        ~2% progression on Octane/regexp.
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSArray.h:
+        (JSC::createArrayButterflyWithExactLength):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::RegExpMatchesArray::create):
+
+2014-08-14  Saam Barati  <sbarati@apple.com>
+
+        Allow high fidelity type profiling to be enabled and disabled.
+        https://bugs.webkit.org/show_bug.cgi?id=135423
+
+        Reviewed by Geoffrey Garen.
+
+        - Merged op_put_to_scope_with_profile and op_get_from_scope_with_profile into
+          op_profile_types_with_high_fidelity by adding extra arguments to the opcode.
+        - Altered SymbolTable to use less memory by adding a rare data structure for 
+          type profiling.
+        - Created an interface to turn on and off type profiling from the Web
+          Inspector.
+        - Refactored how entries are written to HighFidelityLog to make it
+          easier to inline when generating machine code.
+        - Implemented op_profile_types_with_high_fidelity in the baseline JIT
+          by inlining the process of writing to the log and doing a small amount
+          of type inference optimizations.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::scopeDependentProfile): Deleted.
+        * bytecode/CodeBlock.h:
+        * bytecode/TypeLocation.h:
+        (JSC::TypeLocation::TypeLocation):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+        (JSC::BytecodeGenerator::emitGetFromScopeWithProfile): Deleted.
+        (JSC::BytecodeGenerator::emitPutToScopeWithProfile): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        (JSC::FunctionCallDotNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PostfixNode::emitBracket):
+        (JSC::PostfixNode::emitDot):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::PrefixNode::emitBracket):
+        (JSC::PrefixNode::emitDot):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::AssignDotNode::emitBytecode):
+        (JSC::ReadModifyDotNode::emitBytecode):
+        (JSC::AssignBracketNode::emitBytecode):
+        (JSC::ReadModifyBracketNode::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::FunctionBodyNode::emitBytecode):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::InspectorRuntimeAgent):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::TypeRecompiler::operator()):
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorRuntimeAgent::enableHighFidelityTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::disableHighFidelityTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
+        (Inspector::JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend):
+        * inspector/protocol/Runtime.json:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::getFromScopeCommon): Deleted.
+        (JSC::LLInt::putToScopeCommon): Deleted.
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/HighFidelityLog.cpp:
+        (JSC::HighFidelityLog::initializeHighFidelityLog):
+        (JSC::HighFidelityLog::~HighFidelityLog):
+        (JSC::HighFidelityLog::processHighFidelityLog):
+        * runtime/HighFidelityLog.h:
+        (JSC::HighFidelityLog::LogEntry::structureIDOffset):
+        (JSC::HighFidelityLog::LogEntry::valueOffset):
+        (JSC::HighFidelityLog::LogEntry::locationOffset):
+        (JSC::HighFidelityLog::recordTypeInformationForLocation):
+        (JSC::HighFidelityLog::logEndPtr):
+        (JSC::HighFidelityLog::logStartOffset):
+        (JSC::HighFidelityLog::currentLogEntryOffset):
+        * runtime/HighFidelityTypeProfiler.cpp:
+        (JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
+        (JSC::descriptorMatchesTypeLocation):
+        * runtime/HighFidelityTypeProfiler.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::cloneCapturedNames):
+        (JSC::SymbolTable::prepareForHighFidelityTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForVariable):
+        (JSC::SymbolTable::uniqueIDForRegister):
+        (JSC::SymbolTable::globalTypeSetForRegister):
+        (JSC::SymbolTable::globalTypeSetForVariable):
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        * runtime/TypeLocationCache.cpp:
+        (JSC::TypeLocationCache::getTypeLocation):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::getRuntimeTypeForValue):
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::allPrimitiveTypeNames):
+        (JSC::TypeSet::addTypeForValue): Deleted.
+        * runtime/TypeSet.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::nextTypeLocation):
+        (JSC::VM::enableHighFidelityTypeProfiling):
+        (JSC::VM::disableHighFidelityTypeProfiling):
+        (JSC::VM::dumpHighFidelityProfilingTypes):
+        * runtime/VM.h:
+        (JSC::VM::nextLocation): Deleted.
+
+2014-08-14  Oliver Hunt  <oliver@apple.com>
+
+        Update scope resolution to assume that the parent activation is always there
+        https://bugs.webkit.org/show_bug.cgi?id=135947
+
+        Reviewed by Andreas Kling.
+
+        Another incremental step in removing the idea of lazily created
+        activations.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitResolveClosure):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitResolveClosure):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-08-14  Oliver Hunt  <oliver@apple.com>
+
+        Create activations eagerly
+        https://bugs.webkit.org/show_bug.cgi?id=135942
+
+        Reviewed by Geoffrey Garen.
+
+        Prepare to rewrite activation objects into a more
+        sane implementation. Step 1 is reverting to eager
+        creation of the activation object. This results in
+        a 1.35x regression in earley, but otherwise has a
+        minimal performance impact.
+
+        The earley regression is being tracked by bug #135943
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        (JSC::BytecodeGenerator::emitNewFunctionExpression):
+        (JSC::BytecodeGenerator::emitCallEval):
+        (JSC::BytecodeGenerator::emitPushWithScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        (JSC::BytecodeGenerator::createActivationIfNecessary): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_activation):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_activation):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-08-14  Oliver Hunt  <oliver@apple.com>
+
+        Create activations eagerly
+        https://bugs.webkit.org/show_bug.cgi?id=135942
+
+        Reviewed by Geoffrey Garen.
+
+        Prepare to rewrite activation objects into a more
+        sane implementation. Step 1 is reverting to eager
+        creation of the activation object. This results in
+        a 1.35x regression in earley, but otherwise has a
+        minimal performance impact.
+
+        The earley regression is being tracked by 
+        http://webkit.org/b/135943
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        (JSC::BytecodeGenerator::emitNewFunctionExpression):
+        (JSC::BytecodeGenerator::emitCallEval):
+        (JSC::BytecodeGenerator::emitPushWithScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        (JSC::BytecodeGenerator::createActivationIfNecessary): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_activation):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_activation):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-08-14  Tomas Popela  <tpopela@redhat.com>
+
+        Add support for ppc, ppc64, ppc64le, s390, s390x into the CMake build
+        https://bugs.webkit.org/show_bug.cgi?id=135937
+
+        Reviewed by Carlos Garcia Campos.
+
+        * CMakeLists.txt:
+
+2014-08-14  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Fix JSC::ARM64Assembler::LinkRecord::RealTypes
+        https://bugs.webkit.org/show_bug.cgi?id=135906
+
+        Reviewed by Michael Saboff.
+
+        JSC::ARM64Assembler::LinkRecord::RealTypes::m_compareRegister is defined
+        to occupy 5 bits but JSC::ARM64Assembler::RegisterID needs 6 bits. So,
+        increase the size of the bit field and also reorganize the struct to 
+        better align with word boundaries.
+
+        * assembler/ARM64Assembler.h:
+
+2014-08-13  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Add ARM64 support to CMake-based builds
+        https://bugs.webkit.org/show_bug.cgi?id=135912
+
+        Reviewed by Gyuyoung Kim.
+
+        This patch ensures that CMake does not fail with Unknown CPU error when
+        building for ARM64.
+
+        * CMakeLists.txt:
+
+2014-08-13  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Enable CSS_SCROLL_SNAP for iOS
+        https://bugs.webkit.org/show_bug.cgi?id=135915
+
+        Turn on CSS_SCROLL_SNAP for iOS and the iOS simulator.
+
+        Reviewed by Tim Horton.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-13  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards CMake on Mac.
+        https://bugs.webkit.org/show_bug.cgi?id=135819
+
+        Reviewed by Laszlo Gombos.
+
+        * CMakeLists.txt:
+        Add the remote inspector headers to the forwarding headers list.
+
+2014-08-13  Daniel Bates  <dabates@apple.com>
+
+        [iOS] Make JavaScriptCore and bmalloc build with the public SDK
+        https://bugs.webkit.org/show_bug.cgi?id=135848
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSBase.h: Declare NSMap functions with external linkage when building for iOS without the
+        header <Foundation/NSMapTablePriv.h>.
+        * inspector/remote/RemoteInspector.mm: Define XPC functions with external linkage when building
+        without the system header <xpc/xpc.h>.
+        * inspector/remote/RemoteInspectorXPCConnection.h: Define xpc_connection_t and xpc_object_t when building
+        without the system header <xpc/xpc.h>.
+        * inspector/remote/RemoteInspectorXPCConnection.mm: Declare XPC functions with external linkage when
+        building without without the system header <xpc/xpc.h>.
+        (Inspector::RemoteInspectorXPCConnection::closeOnQueue): Fix code style; use nullptr instead of NULL.
+        (Inspector::RemoteInspectorXPCConnection::sendMessage): Ditto.
+
+2014-08-12  Peyton Randolph  <prandolph@apple.com>
+
+        Runtime switch for long mouse press gesture. Part of 135257 - Add long mouse press gesture.
+        https://bugs.webkit.org/show_bug.cgi?id=135682
+
+        Reviewed by Tim Horton.
+
+        * Configurations/FeatureDefines.xcconfig:
+        Remove ENABLE_LONG_MOUSE_PRESS feature flag.
+
+2014-08-12  Alex Christensen  <achristensen@webkit.org>
+
+        Generate header detection headers for CMake on Windows.
+        https://bugs.webkit.org/show_bug.cgi?id=135807
+
+        Reviewed by Brent Fulgham.
+
+        * CMakeLists.txt:
+        Include the derived sources directory to find WTF/WTFHeaderDetection.h.
+
+2014-08-11  Andy Estes  <aestes@apple.com>
+
+        [iOS] Get rid of iOS.xcconfig
+        https://bugs.webkit.org/show_bug.cgi?id=135809
+
+        Reviewed by Joseph Pecoraro.
+
+        All iOS.xcconfig did was include AspenFamily.xcconfig, so there's no need for the indirection.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/iOS.xcconfig: Removed.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-08-11  Michael Saboff  <msaboff@apple.com>
+
+        Eliminate {push,pop}CalleeSaves in favor of individual pushes & pops
+        https://bugs.webkit.org/show_bug.cgi?id=127155
+
+        Reviewed by Geoffrey Garen.
+
+        Eliminated the offline assembler instructions {push,pop}CalleeSaves as well as the
+        ARM64 specific {push,pop}LRAndFP and replaced them with individual push and pop
+        instructions. Where the registers referenced by the added push and pop instructions
+        are not part of the offline assembler register aliases, used a newly added "emit"
+        offline assembler instruction which takes a string literal and outputs that
+        string as a native instruction.
+
+        * llint/LowLevelInterpreter.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/arm64.rb:
+        * offlineasm/ast.rb:
+        * offlineasm/cloop.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/mips.rb:
+        * offlineasm/parser.rb:
+        * offlineasm/sh4.rb:
+        * offlineasm/transform.rb:
+        * offlineasm/x86.rb:
+
+2014-08-11  Mark Lam  <mark.lam@apple.com>
+
+        Re-landing r172401 with fixed test.
+        <https://webkit.org/b/135782>
+
+        Not reviewed.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetByVal):
+        (JSC::BytecodeGenerator::pushIndexedForInScope):
+        (JSC::BytecodeGenerator::pushStructureForInScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::ForInContext::ForInContext):
+        (JSC::ForInContext::base):
+        (JSC::StructureForInContext::StructureForInContext):
+        (JSC::IndexedForInContext::IndexedForInContext):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * tests/stress/for-in-tests.js:
+
+2014-08-11  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r172401.
+        https://bugs.webkit.org/show_bug.cgi?id=135812
+
+        Failing stress/for-in-tests.js
+        http://build.webkit.org/builders/Apple%20Mavericks%20Release%20WK1%20%28Tests%29/builds/7945/steps
+        /jscore-test/logs/stdio (Requested by mlam on #webkit).
+
+        Reverted changeset:
+
+        "for-in optimization should also make sure the base matches
+        the object being iterated"
+        https://bugs.webkit.org/show_bug.cgi?id=135782
+        http://trac.webkit.org/changeset/172401
+
+2014-08-11  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: use type builders to construct high fidelity type information payloads
+        https://bugs.webkit.org/show_bug.cgi?id=135803
+
+        Reviewed by Timothy Hatcher.
+
+        Due to some typos in the protocol file, the code had worked with raw objects
+        rather than with type builders. Convert to using builders.
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json: Fix 'item' for 'items'; true for 'true'.
+        * runtime/HighFidelityTypeProfiler.cpp:
+        (JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector):
+        * runtime/HighFidelityTypeProfiler.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::StructureShape::stringRepresentation):
+        (JSC::StructureShape::inspectorRepresentation):
+        * runtime/TypeSet.h:
+
+2014-08-11  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        for-in optimization should also make sure the base matches the object being iterated
+        https://bugs.webkit.org/show_bug.cgi?id=135782
+
+        Reviewed by Geoffrey Garen.
+
+        If we access a different base object with the same index, we shouldn't try to randomly 
+        load from that object's backing store.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetByVal):
+        (JSC::BytecodeGenerator::pushIndexedForInScope):
+        (JSC::BytecodeGenerator::pushStructureForInScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::ForInContext::ForInContext):
+        (JSC::ForInContext::base):
+        (JSC::StructureForInContext::StructureForInContext):
+        (JSC::IndexedForInContext::IndexedForInContext):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * tests/stress/for-in-tests.js:
+
+2014-08-11  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed gardening.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Display files in
+        proper folder categories..
+
+2014-08-11  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JIT should use full 64-bit stores for jsBoolean and jsNull
+        https://bugs.webkit.org/show_bug.cgi?id=135784
+
+        Reviewed by Michael Saboff.
+
+        This guarantees that we set the high bits of the register with the correct tag.
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_has_structure_property):
+        (JSC::JIT::emit_op_next_enumerator_pname):
+
+2014-08-11  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Adjust build script for Windows production build.
+        https://bugs.webkit.org/show_bug.cgi?id=135806
+        <rdar://problem/17978299>
+
+        Reviewed by Timothy Hatcher.
+
+        * JavaScriptCore.vcxproj/copy-files.cmd: Copy file for later use
+        in WebInspectorUI build.
+
+2014-08-10  Oliver Hunt  <oliver@apple.com>
+
+        Destructuring assignment in a var declaration list incorrectly consumes subsequent variable initialisers
+        https://bugs.webkit.org/show_bug.cgi?id=135773
+
+        Reviewed by Michael Saboff.
+
+        We should be using parseAssignment expression in order to get the correct
+        precedence.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+
+2014-08-10  Diego Pino Garcia  <dpino@igalia.com>
+
+        JSC Lexer is allowing octals 08 and 09 in strict mode functions
+        https://bugs.webkit.org/show_bug.cgi?id=135704
+
+        Reviewed by Oliver Hunt.
+
+        Return syntax error ("Decimal integer literals with a leading zero are
+        forbidden in strict mode") if a number starts with 0 and is followed 
+        by a digit.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::lex):
+
+2014-08-08  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION: Inspector crashes when debugger is paused and injected scripts access window.screen().
+        <https://webkit.org/b/135656>
+
+        Not reviewed.
+
+        Rolling out r170680 which was merged to ToT in r172129.
+
+        * debugger/Debugger.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::scope):
+        (JSC::DebuggerCallFrame::evaluate):
+        (JSC::DebuggerCallFrame::invalidate):
+        * debugger/DebuggerCallFrame.h:
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::DebuggerScope):
+        (JSC::DebuggerScope::finishCreation):
+        (JSC::DebuggerScope::visitChildren):
+        (JSC::DebuggerScope::className):
+        (JSC::DebuggerScope::getOwnPropertySlot):
+        (JSC::DebuggerScope::put):
+        (JSC::DebuggerScope::deleteProperty):
+        (JSC::DebuggerScope::getOwnPropertyNames):
+        (JSC::DebuggerScope::defineOwnProperty):
+        (JSC::DebuggerScope::next): Deleted.
+        (JSC::DebuggerScope::invalidateChain): Deleted.
+        (JSC::DebuggerScope::isWithScope): Deleted.
+        (JSC::DebuggerScope::isGlobalScope): Deleted.
+        (JSC::DebuggerScope::isFunctionScope): Deleted.
+        * debugger/DebuggerScope.h:
+        (JSC::DebuggerScope::create):
+        (JSC::DebuggerScope::Iterator::Iterator): Deleted.
+        (JSC::DebuggerScope::Iterator::get): Deleted.
+        (JSC::DebuggerScope::Iterator::operator++): Deleted.
+        (JSC::DebuggerScope::Iterator::operator==): Deleted.
+        (JSC::DebuggerScope::Iterator::operator!=): Deleted.
+        (JSC::DebuggerScope::isValid): Deleted.
+        (JSC::DebuggerScope::jsScope): Deleted.
+        (JSC::DebuggerScope::begin): Deleted.
+        (JSC::DebuggerScope::end): Deleted.
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::scopeType):
+        (Inspector::JSJavaScriptCallFrame::scopeChain):
+        * inspector/JavaScriptCallFrame.h:
+        (Inspector::JavaScriptCallFrame::scopeChain):
+        * inspector/ScriptDebugServer.cpp:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::debuggerScopeStructure): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::isWithScope): Deleted.
+        * runtime/JSScope.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2014-08-07  Saam Barati  <sbarati@apple.com>
+
+        Create a more generic way for VMEntryScope to notify those interested that it will be destroyed
+        https://bugs.webkit.org/show_bug.cgi?id=135358
+
+        Reviewed by Geoffrey Garen.
+
+        When VMEntryScope is destroyed, and it has a flag set indicating that the
+        Debugger needs to recompile all functions, it calls Debugger::recompileAllJSFunctions. 
+        This flag is only used by Debugger to have VMEntryScope notify it when the
+        Debugger is safe to recompile all functions. This patch will substitute this
+        Debugger-specific recompilation flag with a list of callbacks that are notified 
+        when the outermost VMEntryScope dies. This creates a general purpose interface 
+        for being notified when the VM stops executing code via the event of the outermost 
+        VMEntryScope dying.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::recompileAllJSFunctions):
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        (JSC::VMEntryScope::setEntryScopeDidPopListener):
+        (JSC::VMEntryScope::~VMEntryScope):
+        * runtime/VMEntryScope.h:
+        (JSC::VMEntryScope::setRecompilationNeeded): Deleted.
+
+2014-08-07  Benjamin Poulain  <bpoulain@apple.com>
+
+        Get rid of SCRIPTED_SPEECH
+        https://bugs.webkit.org/show_bug.cgi?id=135729
+
+        Reviewed by Brent Fulgham.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-07  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        SpeculateInt32Operand is sometimes used in a 64-bit context, which has undefined behavior
+        https://bugs.webkit.org/show_bug.cgi?id=135722
+
+        Reviewed by Filip Pizlo.
+
+        We should be using SpeculateStrictInt32Operand instead.
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-08-07  Benjamin Poulain  <bpoulain@apple.com>
+
+        Get rid of INPUT_SPEECH
+        https://bugs.webkit.org/show_bug.cgi?id=135672
+
+        Reviewed by Andreas Kling.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-07  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        for-in is failing fast/dom/dataset-xhtml.xhtml and dataset.html tests
+        https://bugs.webkit.org/show_bug.cgi?id=135681
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::canCacheGenericPropertyNameEnumerator): We were checking the entire 
+        prototype chain for overridesGetPropertyNames, but we were neglecting to check the 
+        base object's Structure. D'oh!
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix for build failure on EFL bots.
+
+        Not reviewed.
+
+        * runtime/EnumerationMode.h:
+        (JSC::shouldIncludeJSObjectPropertyNames):
+        (JSC::modeThatSkipsJSObject):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::getEnumerableLength):
+        * runtime/JSCell.h:
+
+2014-08-06  Dean Jackson  <dino@apple.com>
+
+        ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED is not used anywhere. Remove it.
+        https://bugs.webkit.org/show_bug.cgi?id=135675
+
+        Reviewed by Sam Weinig.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-06  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Implement parsing for CSS scroll snap points
+        https://bugs.webkit.org/show_bug.cgi?id=134301
+
+        Reviewed by Dean Jackson.
+
+        * Configurations/FeatureDefines.xcconfig: Added ENABLE_CSS_SCROLL_SNAP
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix for build failure on GTK bots.
+
+        Not reviewed.
+
+        * runtime/FunctionHasExecutedCache.cpp:
+        - #include <limits.h> for UINT_MAX's definition.
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix for build failure on EFL bots.
+
+        Not reviewed.
+
+        * jit/JITInlines.h:
+        (JSC::JIT::emitLoadForArrayMode):
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: adding missing build file changes from the FTLOPT merge at r172176.
+
+        Not reviewed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-08-06  Ryuan Choi  <ryuan.choi@samsung.com>
+
+        Unreviewed build fix attempt since r172184
+
+        * CMakeLists.txt: Removed TypeLocation.cpp
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: adding missing build file changes from r171510.
+        <https://webkit.org/b/134860>
+
+        Not reviewed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-08-06  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: adding missing build file changes from r170490.
+        <https://webkit.org/b/133395>
+
+        Not reviewed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-08-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Silence a debug assertion.
+
+        Reviewed by Mark Hahnenberg.
+
+        * runtime/JSPropertyNameEnumerator.h:
+        (JSC::JSPropertyNameEnumerator::cachedStructure):
+
+2014-08-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix 32-bit build.
+
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileHasIndexedProperty):
+
+2014-08-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r171389, r171495, r171508, r171510, r171605, r171606, r171611, r171614, r171763 from ftlopt.
+
+    2014-07-28  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Support for-in in the FTL
+            https://bugs.webkit.org/show_bug.cgi?id=134140
+    
+            Reviewed by Filip Pizlo.
+    
+            * dfg/DFGSSALoweringPhase.cpp:
+            (JSC::DFG::SSALoweringPhase::handleNode):
+            * ftl/FTLAbstractHeapRepository.cpp:
+            * ftl/FTLAbstractHeapRepository.h:
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLIntrinsicRepository.h:
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compileHasIndexedProperty):
+            (JSC::FTL::LowerDFGToLLVM::compileHasGenericProperty):
+            (JSC::FTL::LowerDFGToLLVM::compileHasStructureProperty):
+            (JSC::FTL::LowerDFGToLLVM::compileGetDirectPname):
+            (JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength):
+            (JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator):
+            (JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator):
+            (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
+            (JSC::FTL::LowerDFGToLLVM::compileToIndexString):
+    
+    2014-07-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Remove JSPropertyNameIterator
+            https://bugs.webkit.org/show_bug.cgi?id=135066
+    
+            Reviewed by Geoffrey Garen.
+    
+            It has been replaced by JSPropertyNameEnumerator.
+    
+            * JavaScriptCore.order:
+            * bytecode/BytecodeBasicBlock.cpp:
+            (JSC::isBranch):
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            * bytecode/PreciseJumpTargets.cpp:
+            (JSC::getJumpTargetsForBytecodeOffset):
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitGetPropertyNames): Deleted.
+            (JSC::BytecodeGenerator::emitNextPropertyName): Deleted.
+            * bytecompiler/BytecodeGenerator.h:
+            * interpreter/Interpreter.cpp:
+            * interpreter/Register.h:
+            * jit/JIT.cpp:
+            (JSC::JIT::privateCompileMainPass):
+            (JSC::JIT::privateCompileSlowCases):
+            * jit/JIT.h:
+            * jit/JITOpcodes.cpp:
+            (JSC::JIT::emit_op_get_pnames): Deleted.
+            (JSC::JIT::emit_op_next_pname): Deleted.
+            * jit/JITOpcodes32_64.cpp:
+            (JSC::JIT::emit_op_get_pnames): Deleted.
+            (JSC::JIT::emit_op_next_pname): Deleted.
+            * jit/JITOperations.cpp:
+            * jit/JITPropertyAccess.cpp:
+            (JSC::JIT::emit_op_get_by_pname): Deleted.
+            (JSC::JIT::emitSlow_op_get_by_pname): Deleted.
+            * jit/JITPropertyAccess32_64.cpp:
+            (JSC::JIT::emit_op_get_by_pname): Deleted.
+            (JSC::JIT::emitSlow_op_get_by_pname): Deleted.
+            * llint/LLIntOffsetsExtractor.cpp:
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
+            * llint/LLIntSlowPaths.h:
+            * llint/LowLevelInterpreter.asm:
+            * llint/LowLevelInterpreter32_64.asm:
+            * llint/LowLevelInterpreter64.asm:
+            * runtime/CommonSlowPaths.cpp:
+            * runtime/JSPropertyNameIterator.cpp:
+            (JSC::JSPropertyNameIterator::JSPropertyNameIterator): Deleted.
+            (JSC::JSPropertyNameIterator::create): Deleted.
+            (JSC::JSPropertyNameIterator::destroy): Deleted.
+            (JSC::JSPropertyNameIterator::get): Deleted.
+            (JSC::JSPropertyNameIterator::visitChildren): Deleted.
+            * runtime/JSPropertyNameIterator.h:
+            (JSC::JSPropertyNameIterator::createStructure): Deleted.
+            (JSC::JSPropertyNameIterator::size): Deleted.
+            (JSC::JSPropertyNameIterator::setCachedStructure): Deleted.
+            (JSC::JSPropertyNameIterator::cachedStructure): Deleted.
+            (JSC::JSPropertyNameIterator::setCachedPrototypeChain): Deleted.
+            (JSC::JSPropertyNameIterator::cachedPrototypeChain): Deleted.
+            (JSC::JSPropertyNameIterator::finishCreation): Deleted.
+            (JSC::Register::propertyNameIterator): Deleted.
+            (JSC::StructureRareData::enumerationCache): Deleted.
+            (JSC::StructureRareData::setEnumerationCache): Deleted.
+            * runtime/Structure.cpp:
+            (JSC::Structure::addPropertyWithoutTransition):
+            (JSC::Structure::removePropertyWithoutTransition):
+            * runtime/Structure.h:
+            * runtime/StructureInlines.h:
+            (JSC::Structure::setEnumerationCache): Deleted.
+            (JSC::Structure::enumerationCache): Deleted.
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::visitChildren):
+            * runtime/StructureRareData.h:
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+    
+    2014-07-25  Saam Barati  <sbarati@apple.com>
+    
+            Fix 32-bit build breakage for type profiling
+            https://bugs.webkit.org/process_bug.cgi
+    
+            Reviewed by Mark Hahnenberg.
+    
+            32-bit builds currently break because global variable IDs for high
+            fidelity type profiling are int64_t. Change this to intptr_t so that
+            it's 32 bits on 32-bit platforms and 64 bits on 64-bit platforms.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::scopeDependentProfile):
+            * bytecode/TypeLocation.h:
+            * runtime/SymbolTable.cpp:
+            (JSC::SymbolTable::uniqueIDForVariable):
+            (JSC::SymbolTable::uniqueIDForRegister):
+            * runtime/SymbolTable.h:
+            * runtime/TypeLocationCache.cpp:
+            (JSC::TypeLocationCache::getTypeLocation):
+            * runtime/TypeLocationCache.h:
+            * runtime/VM.h:
+            (JSC::VM::getNextUniqueVariableID):
+    
+    2014-07-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Reindent PropertyNameArray.h
+            https://bugs.webkit.org/show_bug.cgi?id=135067
+    
+            Reviewed by Geoffrey Garen.
+    
+            * runtime/PropertyNameArray.h:
+            (JSC::RefCountedIdentifierSet::contains):
+            (JSC::RefCountedIdentifierSet::size):
+            (JSC::RefCountedIdentifierSet::add):
+            (JSC::PropertyNameArrayData::create):
+            (JSC::PropertyNameArrayData::propertyNameVector):
+            (JSC::PropertyNameArrayData::PropertyNameArrayData):
+            (JSC::PropertyNameArray::PropertyNameArray):
+            (JSC::PropertyNameArray::vm):
+            (JSC::PropertyNameArray::add):
+            (JSC::PropertyNameArray::addKnownUnique):
+            (JSC::PropertyNameArray::operator[]):
+            (JSC::PropertyNameArray::setData):
+            (JSC::PropertyNameArray::data):
+            (JSC::PropertyNameArray::releaseData):
+            (JSC::PropertyNameArray::identifierSet):
+            (JSC::PropertyNameArray::canAddKnownUniqueForStructure):
+            (JSC::PropertyNameArray::size):
+            (JSC::PropertyNameArray::begin):
+            (JSC::PropertyNameArray::end):
+            (JSC::PropertyNameArray::numCacheableSlots):
+            (JSC::PropertyNameArray::setNumCacheableSlotsForObject):
+            (JSC::PropertyNameArray::setBaseObject):
+            (JSC::PropertyNameArray::setPreviouslyEnumeratedLength):
+    
+    2014-07-23  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Refactor our current implementation of for-in
+            https://bugs.webkit.org/show_bug.cgi?id=134142
+    
+            Reviewed by Filip Pizlo.
+    
+            This patch splits for-in loops into three distinct parts:
+    
+            - Iterating over the indexed properties in the base object.
+            - Iterating over the Structure properties in the base object.
+            - Iterating over any other enumerable properties for that object and any objects in the prototype chain.
+     
+            It does this by emitting these explicit loops in bytecode, using a new set of bytecodes to 
+            support the various operations required for each loop.
+    
+            * API/JSCallbackObjectFunctions.h:
+            (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CallLinkStatus.h:
+            (JSC::CallLinkStatus::CallLinkStatus):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            (JSC::CodeBlock::CodeBlock):
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitGetByVal):
+            (JSC::BytecodeGenerator::emitComplexPopScopes):
+            (JSC::BytecodeGenerator::emitGetEnumerableLength):
+            (JSC::BytecodeGenerator::emitHasGenericProperty):
+            (JSC::BytecodeGenerator::emitHasIndexedProperty):
+            (JSC::BytecodeGenerator::emitHasStructureProperty):
+            (JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator):
+            (JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator):
+            (JSC::BytecodeGenerator::emitNextEnumeratorPropertyName):
+            (JSC::BytecodeGenerator::emitToIndexString):
+            (JSC::BytecodeGenerator::pushIndexedForInScope):
+            (JSC::BytecodeGenerator::popIndexedForInScope):
+            (JSC::BytecodeGenerator::pushStructureForInScope):
+            (JSC::BytecodeGenerator::popStructureForInScope):
+            (JSC::BytecodeGenerator::invalidateForInContextForLocal):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::ForInContext::ForInContext):
+            (JSC::ForInContext::~ForInContext):
+            (JSC::ForInContext::isValid):
+            (JSC::ForInContext::invalidate):
+            (JSC::ForInContext::local):
+            (JSC::StructureForInContext::StructureForInContext):
+            (JSC::StructureForInContext::type):
+            (JSC::StructureForInContext::index):
+            (JSC::StructureForInContext::property):
+            (JSC::StructureForInContext::enumerator):
+            (JSC::IndexedForInContext::IndexedForInContext):
+            (JSC::IndexedForInContext::type):
+            (JSC::IndexedForInContext::index):
+            (JSC::BytecodeGenerator::pushOptimisedForIn): Deleted.
+            (JSC::BytecodeGenerator::popOptimisedForIn): Deleted.
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::ReadModifyResolveNode::emitBytecode):
+            (JSC::AssignResolveNode::emitBytecode):
+            (JSC::ForInNode::tryGetBoundLocal):
+            (JSC::ForInNode::emitLoopHeader):
+            (JSC::ForInNode::emitMultiLoopBytecode):
+            (JSC::ForInNode::emitBytecode):
+            * debugger/DebuggerScope.h:
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGCapabilities.cpp:
+            (JSC::DFG::capabilityLevel):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGHeapLocation.cpp:
+            (WTF::printInternal):
+            * dfg/DFGHeapLocation.h:
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasHeapPrediction):
+            (JSC::DFG::Node::hasArrayMode):
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT.h:
+            (JSC::DFG::SpeculativeJIT::callOperation):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * jit/JIT.cpp:
+            (JSC::JIT::privateCompileMainPass):
+            (JSC::JIT::privateCompileSlowCases):
+            * jit/JIT.h:
+            (JSC::JIT::compileHasIndexedProperty):
+            (JSC::JIT::emitInt32Load):
+            * jit/JITInlines.h:
+            (JSC::JIT::emitDoubleGetByVal):
+            (JSC::JIT::emitLoadForArrayMode):
+            (JSC::JIT::emitContiguousGetByVal):
+            (JSC::JIT::emitArrayStorageGetByVal):
+            * jit/JITOpcodes.cpp:
+            (JSC::JIT::emit_op_get_enumerable_length):
+            (JSC::JIT::emit_op_has_structure_property):
+            (JSC::JIT::emitSlow_op_has_structure_property):
+            (JSC::JIT::emit_op_has_generic_property):
+            (JSC::JIT::privateCompileHasIndexedProperty):
+            (JSC::JIT::emit_op_has_indexed_property):
+            (JSC::JIT::emitSlow_op_has_indexed_property):
+            (JSC::JIT::emit_op_get_direct_pname):
+            (JSC::JIT::emitSlow_op_get_direct_pname):
+            (JSC::JIT::emit_op_get_structure_property_enumerator):
+            (JSC::JIT::emit_op_get_generic_property_enumerator):
+            (JSC::JIT::emit_op_next_enumerator_pname):
+            (JSC::JIT::emit_op_to_index_string):
+            * jit/JITOpcodes32_64.cpp:
+            (JSC::JIT::emit_op_get_enumerable_length):
+            (JSC::JIT::emit_op_has_structure_property):
+            (JSC::JIT::emitSlow_op_has_structure_property):
+            (JSC::JIT::emit_op_has_generic_property):
+            (JSC::JIT::privateCompileHasIndexedProperty):
+            (JSC::JIT::emit_op_has_indexed_property):
+            (JSC::JIT::emitSlow_op_has_indexed_property):
+            (JSC::JIT::emit_op_get_direct_pname):
+            (JSC::JIT::emitSlow_op_get_direct_pname):
+            (JSC::JIT::emit_op_get_structure_property_enumerator):
+            (JSC::JIT::emit_op_get_generic_property_enumerator):
+            (JSC::JIT::emit_op_next_enumerator_pname):
+            (JSC::JIT::emit_op_to_index_string):
+            * jit/JITOperations.cpp:
+            * jit/JITOperations.h:
+            * jit/JITPropertyAccess.cpp:
+            (JSC::JIT::emitDoubleLoad):
+            (JSC::JIT::emitContiguousLoad):
+            (JSC::JIT::emitArrayStorageLoad):
+            (JSC::JIT::emitDoubleGetByVal): Deleted.
+            (JSC::JIT::emitContiguousGetByVal): Deleted.
+            (JSC::JIT::emitArrayStorageGetByVal): Deleted.
+            * jit/JITPropertyAccess32_64.cpp:
+            (JSC::JIT::emitContiguousLoad):
+            (JSC::JIT::emitDoubleLoad):
+            (JSC::JIT::emitArrayStorageLoad):
+            (JSC::JIT::emitContiguousGetByVal): Deleted.
+            (JSC::JIT::emitDoubleGetByVal): Deleted.
+            (JSC::JIT::emitArrayStorageGetByVal): Deleted.
+            * llint/LowLevelInterpreter.asm:
+            * parser/Nodes.h:
+            * runtime/Arguments.cpp:
+            (JSC::Arguments::getOwnPropertyNames):
+            * runtime/ClassInfo.h:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+            * runtime/CommonSlowPaths.h:
+            * runtime/EnumerationMode.h: Added.
+            (JSC::shouldIncludeDontEnumProperties):
+            (JSC::shouldExcludeDontEnumProperties):
+            (JSC::shouldIncludeJSObjectPropertyNames):
+            (JSC::modeThatSkipsJSObject):
+            * runtime/JSActivation.cpp:
+            (JSC::JSActivation::getOwnNonIndexPropertyNames):
+            * runtime/JSArray.cpp:
+            (JSC::JSArray::getOwnNonIndexPropertyNames):
+            * runtime/JSArrayBuffer.cpp:
+            (JSC::JSArrayBuffer::getOwnNonIndexPropertyNames):
+            * runtime/JSArrayBufferView.cpp:
+            (JSC::JSArrayBufferView::getOwnNonIndexPropertyNames):
+            * runtime/JSCell.cpp:
+            (JSC::JSCell::getEnumerableLength):
+            (JSC::JSCell::getStructurePropertyNames):
+            (JSC::JSCell::getGenericPropertyNames):
+            * runtime/JSCell.h:
+            * runtime/JSFunction.cpp:
+            (JSC::JSFunction::getOwnNonIndexPropertyNames):
+            * runtime/JSGenericTypedArrayViewInlines.h:
+            (JSC::JSGenericTypedArrayView<Adaptor>::getOwnNonIndexPropertyNames):
+            * runtime/JSObject.cpp:
+            (JSC::getClassPropertyNames):
+            (JSC::JSObject::hasOwnProperty):
+            (JSC::JSObject::getOwnPropertyNames):
+            (JSC::JSObject::getOwnNonIndexPropertyNames):
+            (JSC::JSObject::getEnumerableLength):
+            (JSC::JSObject::getStructurePropertyNames):
+            (JSC::JSObject::getGenericPropertyNames):
+            * runtime/JSObject.h:
+            * runtime/JSPropertyNameEnumerator.cpp: Added.
+            (JSC::JSPropertyNameEnumerator::create):
+            (JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator):
+            (JSC::JSPropertyNameEnumerator::finishCreation):
+            (JSC::JSPropertyNameEnumerator::destroy):
+            (JSC::JSPropertyNameEnumerator::visitChildren):
+            * runtime/JSPropertyNameEnumerator.h: Added.
+            (JSC::JSPropertyNameEnumerator::createStructure):
+            (JSC::JSPropertyNameEnumerator::propertyNameAtIndex):
+            (JSC::JSPropertyNameEnumerator::identifierSet):
+            (JSC::JSPropertyNameEnumerator::cachedPrototypeChain):
+            (JSC::JSPropertyNameEnumerator::setCachedPrototypeChain):
+            (JSC::JSPropertyNameEnumerator::cachedStructure):
+            (JSC::JSPropertyNameEnumerator::cachedStructureID):
+            (JSC::JSPropertyNameEnumerator::cachedInlineCapacity):
+            (JSC::JSPropertyNameEnumerator::cachedStructureIDOffset):
+            (JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset):
+            (JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset):
+            (JSC::JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset):
+            (JSC::structurePropertyNameEnumerator):
+            (JSC::genericPropertyNameEnumerator):
+            * runtime/JSProxy.cpp:
+            (JSC::JSProxy::getEnumerableLength):
+            (JSC::JSProxy::getStructurePropertyNames):
+            (JSC::JSProxy::getGenericPropertyNames):
+            * runtime/JSProxy.h:
+            * runtime/JSSymbolTableObject.cpp:
+            (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+            * runtime/PropertyNameArray.cpp:
+            (JSC::PropertyNameArray::add):
+            (JSC::PropertyNameArray::setPreviouslyEnumeratedProperties):
+            * runtime/PropertyNameArray.h:
+            (JSC::RefCountedIdentifierSet::contains):
+            (JSC::RefCountedIdentifierSet::size):
+            (JSC::RefCountedIdentifierSet::add):
+            (JSC::PropertyNameArray::PropertyNameArray):
+            (JSC::PropertyNameArray::add):
+            (JSC::PropertyNameArray::addKnownUnique):
+            (JSC::PropertyNameArray::identifierSet):
+            (JSC::PropertyNameArray::canAddKnownUniqueForStructure):
+            (JSC::PropertyNameArray::setPreviouslyEnumeratedLength):
+            * runtime/RegExpObject.cpp:
+            (JSC::RegExpObject::getOwnNonIndexPropertyNames):
+            (JSC::RegExpObject::getPropertyNames):
+            (JSC::RegExpObject::getGenericPropertyNames):
+            * runtime/RegExpObject.h:
+            * runtime/StringObject.cpp:
+            (JSC::StringObject::getOwnPropertyNames):
+            * runtime/Structure.cpp:
+            (JSC::Structure::getPropertyNamesFromStructure):
+            (JSC::Structure::setCachedStructurePropertyNameEnumerator):
+            (JSC::Structure::cachedStructurePropertyNameEnumerator):
+            (JSC::Structure::setCachedGenericPropertyNameEnumerator):
+            (JSC::Structure::cachedGenericPropertyNameEnumerator):
+            (JSC::Structure::canCacheStructurePropertyNameEnumerator):
+            (JSC::Structure::canCacheGenericPropertyNameEnumerator):
+            (JSC::Structure::canAccessPropertiesQuickly):
+            * runtime/Structure.h:
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::visitChildren):
+            (JSC::StructureRareData::cachedStructurePropertyNameEnumerator):
+            (JSC::StructureRareData::setCachedStructurePropertyNameEnumerator):
+            (JSC::StructureRareData::cachedGenericPropertyNameEnumerator):
+            (JSC::StructureRareData::setCachedGenericPropertyNameEnumerator):
+            * runtime/StructureRareData.h:
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-07-23  Saam Barati  <sbarati@apple.com>
+    
+            Make improvements to Type Profiling
+            https://bugs.webkit.org/show_bug.cgi?id=134860
+    
+            Reviewed by Filip Pizlo.
+    
+            I improved the API between the inspector and JSC. We no longer send one huge
+            string to the inspector. We now send structured data that represents the type
+            information that JSC has collected. I've also created a beginning implementation 
+            of a type lattice that allows us to resolve a display name for a type that
+            consists of a single word.
+    
+            I created a data structure that knows which functions have executed. This
+            solves the bug where types inside an un-executed function will resolve
+            to the type of the enclosing expression of that function. This data
+            structure may also be useful later if the inspector chooses to create a UI
+            around showing which functions have executed.
+    
+            Better type information is gathered for objects. StructureShape now
+            represents an object's prototype chain.  StructureShape also collects
+            the constructor name for an object.
+    
+            Expression ranges are now zero indexed.
+    
+            Removed some extraneous methods.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::scopeDependentProfile):
+            * bytecode/CodeBlock.h:
+            * bytecode/TypeLocation.h:
+            (JSC::TypeLocation::TypeLocation):
+            * bytecode/UnlinkedCodeBlock.cpp:
+            (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+            * bytecode/UnlinkedCodeBlock.h:
+            (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingStartOffset):
+            (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingEndOffset):
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::BytecodeGenerator):
+            (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo): Deleted.
+            * heap/Heap.cpp:
+            (JSC::Heap::collect):
+            * inspector/agents/InspectorRuntimeAgent.cpp:
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset): Deleted.
+            * inspector/agents/InspectorRuntimeAgent.h:
+            * inspector/protocol/Runtime.json:
+            * runtime/Executable.cpp:
+            (JSC::ScriptExecutable::ScriptExecutable):
+            (JSC::ProgramExecutable::ProgramExecutable):
+            (JSC::FunctionExecutable::FunctionExecutable):
+            (JSC::ProgramExecutable::initializeGlobalProperties):
+            * runtime/Executable.h:
+            (JSC::ScriptExecutable::highFidelityTypeProfilingStartOffset):
+            (JSC::ScriptExecutable::highFidelityTypeProfilingEndOffset):
+            * runtime/FunctionHasExecutedCache.cpp: Added.
+            (JSC::FunctionHasExecutedCache::hasExecutedAtOffset):
+            (JSC::FunctionHasExecutedCache::insertUnexecutedRange):
+            (JSC::FunctionHasExecutedCache::removeUnexecutedRange):
+            * runtime/FunctionHasExecutedCache.h: Added.
+            (JSC::FunctionHasExecutedCache::FunctionRange::FunctionRange):
+            (JSC::FunctionHasExecutedCache::FunctionRange::operator==):
+            (JSC::FunctionHasExecutedCache::FunctionRange::hash):
+            * runtime/HighFidelityLog.cpp:
+            (JSC::HighFidelityLog::processHighFidelityLog):
+            (JSC::HighFidelityLog::actuallyProcessLogThreadFunction): Deleted.
+            * runtime/HighFidelityLog.h:
+            (JSC::HighFidelityLog::recordTypeInformationForLocation):
+            * runtime/HighFidelityTypeProfiler.cpp:
+            (JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
+            (JSC::HighFidelityTypeProfiler::insertNewLocation):
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector):
+            (JSC::descriptorMatchesTypeLocation):
+            (JSC::HighFidelityTypeProfiler::findLocation):
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset): Deleted.
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset): Deleted.
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset): Deleted.
+            * runtime/HighFidelityTypeProfiler.h:
+            (JSC::QueryKey::QueryKey):
+            (JSC::QueryKey::isHashTableDeletedValue):
+            (JSC::QueryKey::operator==):
+            (JSC::QueryKey::hash):
+            (JSC::QueryKeyHash::hash):
+            (JSC::QueryKeyHash::equal):
+            (JSC::HighFidelityTypeProfiler::functionHasExecutedCache):
+            (JSC::HighFidelityTypeProfiler::typeLocationCache):
+            * runtime/Structure.cpp:
+            (JSC::Structure::toStructureShape):
+            * runtime/Structure.h:
+            * runtime/TypeLocationCache.cpp: Added.
+            (JSC::TypeLocationCache::getTypeLocation):
+            * runtime/TypeLocationCache.h: Added.
+            (JSC::TypeLocationCache::LocationKey::LocationKey):
+            (JSC::TypeLocationCache::LocationKey::operator==):
+            (JSC::TypeLocationCache::LocationKey::hash):
+            * runtime/TypeSet.cpp:
+            (JSC::TypeSet::getRuntimeTypeForValue):
+            (JSC::TypeSet::addTypeForValue):
+            (JSC::TypeSet::seenTypes):
+            (JSC::TypeSet::doesTypeConformTo):
+            (JSC::TypeSet::displayName):
+            (JSC::TypeSet::allPrimitiveTypeNames):
+            (JSC::TypeSet::allStructureRepresentations):
+            (JSC::TypeSet::leastCommonAncestor):
+            (JSC::StructureShape::StructureShape):
+            (JSC::StructureShape::addProperty):
+            (JSC::StructureShape::propertyHash):
+            (JSC::StructureShape::leastCommonAncestor):
+            (JSC::StructureShape::stringRepresentation):
+            (JSC::StructureShape::inspectorRepresentation):
+            (JSC::StructureShape::leastUpperBound): Deleted.
+            * runtime/TypeSet.h:
+            (JSC::StructureShape::setConstructorName):
+            (JSC::StructureShape::constructorName):
+            (JSC::StructureShape::setProto):
+            * runtime/VM.cpp:
+            (JSC::VM::dumpHighFidelityProfilingTypes):
+            (JSC::VM::getTypesForVariableAtOffset): Deleted.
+            (JSC::VM::updateHighFidelityTypeProfileState): Deleted.
+            * runtime/VM.h:
+            (JSC::VM::isProfilingTypesWithHighFidelity):
+            (JSC::VM::highFidelityTypeProfiler):
+    
+    2014-07-23  Filip Pizlo  <fpizlo@apple.com>
+    
+            Fix debug build.
+    
+            * bytecode/CallLinkStatus.h:
+            (JSC::CallLinkStatus::CallLinkStatus):
+    
+    2014-07-20  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Phantoms in SSA form should be aggressively hoisted
+            https://bugs.webkit.org/show_bug.cgi?id=135111
+    
+            Reviewed by Oliver Hunt.
+            
+            In CPS form, Phantom means three things: (1) that the children should be kept alive so long
+            as they are relevant to OSR (due to a MovHint), (2) that the children are live-in-bytecode
+            at the point of the Phantom, and (3) that some checks should be performed. In SSA, the
+            second meaning is not used but the other two stay.
+            
+            The fact that a Phantom that is used to keep a node alive could be anywhere in the graph,
+            even in a totally different basic block, complicates some SSA transformations. It's not
+            possible to just jettison some successor, since tha successor could have a Phantom that we
+            care about.
+            
+            This change rationalizes how Phantoms work so that:
+            
+            1) Phantoms keep children alive so long as those children are relevant to OSR. This is true
+               in both CPS and SSA. This was true before and it's true now.
+            
+            2) Phantoms are used for live-in-bytecode only in CPS. This was true before and it's true
+               now, except that now we also don't bother preserving the live-in-bytecode information
+               that Phantoms convey, when we are in SSA.
+            
+            3) Phantoms may incidentally have checks, but in cases where we only want checks, we now
+               use Check instead of Phantom. Notably, DCE phase has dead nodes decay to Check, not
+               Phantom.
+            
+            The biggest part of this change is that in SSA, we canonicalize Phantoms:
+            
+            - All Phantoms are replaced with Check nodes that include only those edges that have
+              checks.
+            
+            - Nodes that were the children of any Phantoms have a Phantom right after them.
+            
+            For example, the following code:
+            
+                5: ArithAdd(@1, @2)
+                6: ArithSub(@5, @3)
+                7: Phantom(Int32:@5)
+            
+            would be turned into the following:
+            
+                5: ArithAdd(@1, @2)
+                8: Phantom(@5) // @5 was the child of a Phantom, so we create a new Phantom right after
+                               // @5. This is the only Phantom we will have for @5.
+                6: ArithSub(@5, @3)
+                7: Check(Int32:@5) // We replace the Phantom with a Check; in this case since Int32: is
+                                   // a checking edge, we leave it.
+            
+            This is a slight speed-up across the board, presumably because we now do a better job of
+            reducing the size of the graph during compilation. It could also be a fluke, though. The
+            main purpose of this is to unlock some other work (like CFG simplification in SSA). It will
+            become a requirement to run phantom canonicalization prior to some SSA phases. None of the
+            current phases need it, but future phases probably will.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            * dfg/DFGDCEPhase.cpp:
+            (JSC::DFG::DCEPhase::run):
+            (JSC::DFG::DCEPhase::findTypeCheckRoot):
+            (JSC::DFG::DCEPhase::countEdge):
+            (JSC::DFG::DCEPhase::fixupBlock):
+            (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
+            * dfg/DFGEdge.cpp:
+            (JSC::DFG::Edge::dump):
+            * dfg/DFGEdge.h:
+            (JSC::DFG::Edge::isProved):
+            (JSC::DFG::Edge::needsCheck): Deleted.
+            * dfg/DFGNodeFlags.h:
+            * dfg/DFGPhantomCanonicalizationPhase.cpp: Added.
+            (JSC::DFG::PhantomCanonicalizationPhase::PhantomCanonicalizationPhase):
+            (JSC::DFG::PhantomCanonicalizationPhase::run):
+            (JSC::DFG::performPhantomCanonicalization):
+            * dfg/DFGPhantomCanonicalizationPhase.h: Added.
+            * dfg/DFGPhantomRemovalPhase.cpp:
+            (JSC::DFG::PhantomRemovalPhase::run):
+            * dfg/DFGPhantomRemovalPhase.h:
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+            (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+    
+    2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Get rid of structure checks as a way of checking if a function is in fact a function
+            https://bugs.webkit.org/show_bug.cgi?id=135146
+    
+            Reviewed by Oliver Hunt.
+            
+            This greatly simplifies our closure call optimizations by taking advantage of the type
+            bits available in the cell header.
+    
+            * bytecode/CallLinkInfo.cpp:
+            (JSC::CallLinkInfo::visitWeak):
+            * bytecode/CallLinkStatus.cpp:
+            (JSC::CallLinkStatus::CallLinkStatus):
+            (JSC::CallLinkStatus::computeFor):
+            (JSC::CallLinkStatus::dump):
+            * bytecode/CallLinkStatus.h:
+            (JSC::CallLinkStatus::CallLinkStatus):
+            (JSC::CallLinkStatus::executable):
+            (JSC::CallLinkStatus::structure): Deleted.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            (JSC::DFG::FixupPhase::observeUseKindOnNode):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::SafeToExecuteEdge::operator()):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::checkArray):
+            (JSC::DFG::SpeculativeJIT::speculateCellTypeWithoutTypeFiltering):
+            (JSC::DFG::SpeculativeJIT::speculateCellType):
+            (JSC::DFG::SpeculativeJIT::speculateFunction):
+            (JSC::DFG::SpeculativeJIT::speculateFinalObject):
+            (JSC::DFG::SpeculativeJIT::speculate):
+            * dfg/DFGSpeculativeJIT.h:
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGUseKind.cpp:
+            (WTF::printInternal):
+            * dfg/DFGUseKind.h:
+            (JSC::DFG::typeFilterFor):
+            (JSC::DFG::isCell):
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileCheckExecutable):
+            (JSC::FTL::LowerDFGToLLVM::speculate):
+            (JSC::FTL::LowerDFGToLLVM::isFunction):
+            (JSC::FTL::LowerDFGToLLVM::isNotFunction):
+            (JSC::FTL::LowerDFGToLLVM::speculateFunction):
+            * jit/ClosureCallStubRoutine.cpp:
+            (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
+            (JSC::ClosureCallStubRoutine::markRequiredObjectsInternal):
+            * jit/ClosureCallStubRoutine.h:
+            (JSC::ClosureCallStubRoutine::structure): Deleted.
+            * jit/JIT.h:
+            (JSC::JIT::compileClosureCall): Deleted.
+            * jit/JITCall.cpp:
+            (JSC::JIT::privateCompileClosureCall): Deleted.
+            * jit/JITCall32_64.cpp:
+            (JSC::JIT::privateCompileClosureCall): Deleted.
+            * jit/JITOperations.cpp:
+            * jit/Repatch.cpp:
+            (JSC::linkClosureCall):
+            * jit/Repatch.h:
+    
+2014-08-06  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        [ARM] Incorrect handling of Unicode characters
+        https://bugs.webkit.org/show_bug.cgi?id=135380
+
+        Reviewed by Darin Adler.
+
+        Removed erroneous fast case from stringFromUTF(), since it assumed that 
+        char is always implemented as signed.
+
+        * jsc.cpp:
+        (stringFromUTF):
+
+2014-08-06  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        [JSC] Build fix for FTL on EFL after ftlopt merge
+        https://bugs.webkit.org/show_bug.cgi?id=135565
+
+        Reviewed by Mark Lam.
+
+        Adding an enable guard for native inlining, since it now requires the bitcode
+        emitted from Clang, and we don't have a good way of creating it from other compilers.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleCall):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::State):
+        * ftl/FTLState.h:
+
+2014-08-05  Csaba Osztrogonác  <ossy@webkit.org>
+
+        URTBF after r172129. (ftlopt branch merge)
+
+        Remove the duplicated friend declaration to fix this build failure:
+        "error: ‘JSC::Structure’ is already a friend of ‘JSC::StructureRareData’ [-Werror]"
+
+        * runtime/StructureRareData.h:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix CMake-based builds, part 3.
+
+        * CMakeLists.txt:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix CMake-based builds, part 2.
+
+        * CMakeLists.txt:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix Windows build, part 2.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix CMake-based builds.
+
+        * CMakeLists.txt:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix Windows build.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+
+2014-08-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix cloop build.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettison):
+
+2014-07-29  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r170564, r170571, r170604, r170628, r170672, r170680, r170724, r170728, r170729, r170819, r170821, r170836, r170855, r170860, r170890, r170907, r170929, r171052, r171106, r171152, r171153, r171214 from ftlopt.
+
+        This part of the merge delivers roughly a 2% across-the-board performance
+        improvement, mostly due to immutable property inference and DFG-side GCSE. It also
+        almost completely resolves accessor performance issues; in the common case the DFG
+        will compile a getter/setter access into code that is just as efficient as a normal
+        property access.
+        
+        Another major highlight of this part of the merge is the work to add a type profiler
+        to the inspector. This work is still on-going but this greatly increases coverage.
+
+        Note that this merge fixes a minor bug in the GetterSetter refactoring from
+        http://trac.webkit.org/changeset/170729 (https://bugs.webkit.org/show_bug.cgi?id=134518).
+        It also adds a new tests to tests/stress to cover that bug. That bug was previously only
+        covered by layout tests.
+
+    2014-07-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw (merge trunk r171190)
+            https://bugs.webkit.org/show_bug.cgi?id=135019
+    
+            Reviewed by Oliver Hunt.
+            
+            Behaviorally, this is just a merge of trunk r171190, except that the relevant functionality
+            has moved to StrengthReductionPhase and is written in a different style. Same algorithm,
+            different code.
+    
+            * dfg/DFGNodeType.h:
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode):
+            * tests/stress/capture-escape-and-throw.js: Added.
+            (foo.f):
+            (foo):
+            * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
+            (foo):
+            (bar):
+    
+    2014-07-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Constant fold GetGetter and GetSetter if the GetterSetter is a constant
+            https://bugs.webkit.org/show_bug.cgi?id=134962
+    
+            Reviewed by Oliver Hunt.
+            
+            This removes yet another steady-state-throughput implication of using getters and setters:
+            if your accessor call is monomorphic then you'll just get a structure check, nothing more.
+            No more loads to get to the GetterSetter object or the accessor function object.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * runtime/GetterSetter.h:
+            (JSC::GetterSetter::getterConcurrently):
+            (JSC::GetterSetter::setGetter):
+            (JSC::GetterSetter::setterConcurrently):
+            (JSC::GetterSetter::setSetter):
+    
+    2014-07-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Identity replacement in CSE shouldn't create a Phantom over the Identity's children
+            https://bugs.webkit.org/show_bug.cgi?id=134893
+    
+            Reviewed by Oliver Hunt.
+            
+            Replace Identity with Check instead of Phantom. Phantom means that the child of the
+            Identity should be unconditionally live. The liveness semantics of Identity are such that
+            if the parents of Identity are live then the child is live. Removing the Identity entirely
+            preserves such liveness semantics. So, the only thing that should be left behind is the
+            type check on the child, which is what Check means: do the check but don't keep the child
+            alive if the check isn't needed.
+    
+            * dfg/DFGCSEPhase.cpp:
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToCheck):
+    
+    2014-07-13  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG should be able to do GCSE in SSA and this should be unified with the CSE in CPS, and both of these things should use abstract heaps for reasoning about effects
+            https://bugs.webkit.org/show_bug.cgi?id=134677
+    
+            Reviewed by Sam Weinig.
+            
+            This removes the old local CSE phase, which was based on manually written backward-search 
+            rules for all of the different kinds of things we cared about, and adds a new local/global
+            CSE (local for CPS and global for SSA) that leaves the node semantics almost entirely up to
+            clobberize(). Thus, the CSE phase itself just worries about the algorithms and data
+            structures used for storing sets of available values. This results in a large reduction in
+            code size in CSEPhase.cpp while greatly increasing the phase's power (since it now does
+            global CSE) and reducing compile time (since local CSE is now rewritten to use smarter data
+            structures). Even though LLVM was already running GVN, the extra GCSE at DFG IR level means
+            that this is a significant (~0.7%) throughput improvement.
+            
+            This work is based on the concept of "def" to clobberize(). If clobberize() calls def(), it
+            means that the node being analyzed makes available some value in some DFG node, and that
+            future attempts to compute that value can simply use that node. In other words, it
+            establishes an available value mapping of the form value=>node. There are two kinds of
+            values that can be passed to def():
+            
+            PureValue. This captures everything needed to determine whether two pure nodes - nodes that
+                neither read nor write, and produce a value that is a CSE candidate - are identical. It
+                carries the NodeType, an AdjacencyList, and one word of meta-data. The meta-data is
+                usually used for things like the arithmetic mode or constant pointer. Passing a
+                PureValue to def() means that the node produces a value that is valid anywhere that the
+                node dominates.
+            
+            HeapLocation. This describes a location in the heap that could be written to or read from.
+                Both stores and loads can def() a HeapLocation. HeapLocation carries around an abstract
+                heap that both serves as part of the "name" of the heap location (together with the
+                other fields of HeapLocation) and also tells us what write()'s to watch for. If someone
+                write()'s to an abstract heap that overlaps the heap associated with the HeapLocation,
+                then it means that the values for that location are no longer available.
+            
+            This approach is sufficiently clever that the CSEPhase itself can focus on the mechanism of
+            tracking the PureValue=>node and HeapLocation=>node maps, without having to worry about
+            interpreting the semantics of different DFG node types - that is now almost entirely in
+            clobberize(). The only things we special-case inside CSEPhase are the Identity node, which
+            CSE is traditionally responsible for eliminating even though it has nothing to do with CSE,
+            and the LocalCSE rule for turning PutByVal into PutByValAlias.
+            
+            This is a slight Octane, SunSpider, and Kraken speed-up - all somewhere arond 0.7% . It's
+            not a bigger win because LLVM was already giving us most of what we needed in its GVN.
+            Also, the SunSpider speed-up isn't from GCSE as much as it's a clean-up of local CSE - that
+            is no longer O(n^2). Basically this is purely good: it reduces the amount of LLVM IR we
+            generate, it removes the old CSE's heap modeling (which was a constant source of bugs), and
+            it improves both the quality of the code we generate and the speed with which we generate
+            it. Also, any future optimizations that depend on GCSE will now be easier to implement.
+            
+            During the development of this patch I also rationalized some other stuff, like Graph's
+            ordered traversals - we now have preorder and postorder rather than just "depth first".
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGAdjacencyList.h:
+            (JSC::DFG::AdjacencyList::hash):
+            (JSC::DFG::AdjacencyList::operator==):
+            * dfg/DFGBasicBlock.h:
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::performLocalCSE):
+            (JSC::DFG::performGlobalCSE):
+            (JSC::DFG::CSEPhase::CSEPhase): Deleted.
+            (JSC::DFG::CSEPhase::run): Deleted.
+            (JSC::DFG::CSEPhase::endIndexForPureCSE): Deleted.
+            (JSC::DFG::CSEPhase::pureCSE): Deleted.
+            (JSC::DFG::CSEPhase::constantCSE): Deleted.
+            (JSC::DFG::CSEPhase::constantStoragePointerCSE): Deleted.
+            (JSC::DFG::CSEPhase::getCalleeLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getArrayLengthElimination): Deleted.
+            (JSC::DFG::CSEPhase::globalVarLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::scopedVarLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::varInjectionWatchpointElimination): Deleted.
+            (JSC::DFG::CSEPhase::getByValLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkFunctionElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkExecutableElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkStructureElimination): Deleted.
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): Deleted.
+            (JSC::DFG::CSEPhase::getByOffsetLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getGetterSetterByOffsetLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::checkArrayElimination): Deleted.
+            (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getInternalFieldLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getMyScopeLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::getLocalLoadElimination): Deleted.
+            (JSC::DFG::CSEPhase::invalidationPointElimination): Deleted.
+            (JSC::DFG::CSEPhase::setReplacement): Deleted.
+            (JSC::DFG::CSEPhase::eliminate): Deleted.
+            (JSC::DFG::CSEPhase::performNodeCSE): Deleted.
+            (JSC::DFG::CSEPhase::performBlockCSE): Deleted.
+            (JSC::DFG::performCSE): Deleted.
+            * dfg/DFGCSEPhase.h:
+            * dfg/DFGClobberSet.cpp:
+            (JSC::DFG::addReads):
+            (JSC::DFG::addWrites):
+            (JSC::DFG::addReadsAndWrites):
+            (JSC::DFG::readsOverlap):
+            (JSC::DFG::writesOverlap):
+            * dfg/DFGClobberize.cpp:
+            (JSC::DFG::doesWrites):
+            (JSC::DFG::accessesOverlap):
+            (JSC::DFG::writesOverlap):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            (JSC::DFG::NoOpClobberize::operator()):
+            (JSC::DFG::CheckClobberize::operator()):
+            (JSC::DFG::ReadMethodClobberize::ReadMethodClobberize):
+            (JSC::DFG::ReadMethodClobberize::operator()):
+            (JSC::DFG::WriteMethodClobberize::WriteMethodClobberize):
+            (JSC::DFG::WriteMethodClobberize::operator()):
+            (JSC::DFG::DefMethodClobberize::DefMethodClobberize):
+            (JSC::DFG::DefMethodClobberize::operator()):
+            * dfg/DFGDCEPhase.cpp:
+            (JSC::DFG::DCEPhase::run):
+            (JSC::DFG::DCEPhase::fixupBlock):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::getBlocksInPreOrder):
+            (JSC::DFG::Graph::getBlocksInPostOrder):
+            (JSC::DFG::Graph::addForDepthFirstSort): Deleted.
+            (JSC::DFG::Graph::getBlocksInDepthFirstOrder): Deleted.
+            * dfg/DFGGraph.h:
+            * dfg/DFGHeapLocation.cpp: Added.
+            (JSC::DFG::HeapLocation::dump):
+            (WTF::printInternal):
+            * dfg/DFGHeapLocation.h: Added.
+            (JSC::DFG::HeapLocation::HeapLocation):
+            (JSC::DFG::HeapLocation::operator!):
+            (JSC::DFG::HeapLocation::kind):
+            (JSC::DFG::HeapLocation::heap):
+            (JSC::DFG::HeapLocation::base):
+            (JSC::DFG::HeapLocation::index):
+            (JSC::DFG::HeapLocation::hash):
+            (JSC::DFG::HeapLocation::operator==):
+            (JSC::DFG::HeapLocation::isHashTableDeletedValue):
+            (JSC::DFG::HeapLocationHash::hash):
+            (JSC::DFG::HeapLocationHash::equal):
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::run):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::replaceWith):
+            (JSC::DFG::Node::convertToPhantomUnchecked): Deleted.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGPureValue.cpp: Added.
+            (JSC::DFG::PureValue::dump):
+            * dfg/DFGPureValue.h: Added.
+            (JSC::DFG::PureValue::PureValue):
+            (JSC::DFG::PureValue::operator!):
+            (JSC::DFG::PureValue::op):
+            (JSC::DFG::PureValue::children):
+            (JSC::DFG::PureValue::info):
+            (JSC::DFG::PureValue::hash):
+            (JSC::DFG::PureValue::operator==):
+            (JSC::DFG::PureValue::isHashTableDeletedValue):
+            (JSC::DFG::PureValueHash::hash):
+            (JSC::DFG::PureValueHash::equal):
+            * dfg/DFGSSAConversionPhase.cpp:
+            (JSC::DFG::SSAConversionPhase::run):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::lower):
+    
+    2014-07-13  Filip Pizlo  <fpizlo@apple.com>
+    
+            Unreviewed, revert unintended change in r171051.
+    
+            * dfg/DFGCSEPhase.cpp:
+    
+    2014-07-08  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Move Flush(SetLocal) store elimination to StrengthReductionPhase
+            https://bugs.webkit.org/show_bug.cgi?id=134739
+    
+            Reviewed by Mark Hahnenberg.
+            
+            I'm going to streamline CSE around clobberize() as part of
+            https://bugs.webkit.org/show_bug.cgi?id=134677, and so Flush(SetLocal) store
+            elimination wouldn't belong in CSE anymore. It doesn't quite belong anywhere, which
+            means that it belongs in StrengthReductionPhase, since that's intended to be our
+            dumping ground.
+            
+            To do this I had to add some missing smarts to clobberize(). Previously clobberize()
+            could play a bit loose with reads of Variables because it wasn't used for store
+            elimination. The main client of read() was LICM, but it would only use it to
+            determine hoistability and anything that did a write() was not hoistable - so, we had
+            benign (but still wrong) missing read() calls in places that did write()s. This fixes
+            a bunch of those cases.
+    
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::setLocalStoreElimination): Deleted.
+            * dfg/DFGClobberize.cpp:
+            (JSC::DFG::accessesOverlap):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize): Make clobberize() smart enough for detecting when this store elimination would be sound.
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode): Implement the store elimination in terms of clobberize().
+    
+    2014-07-08  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Phantom simplification should be in its own phase
+            https://bugs.webkit.org/show_bug.cgi?id=134742
+    
+            Reviewed by Geoffrey Garen.
+            
+            This moves Phantom simplification out of CSE, which greatly simplifies CSE and gives it
+            more focus. Also this finally adds a phase that removes empty Phantoms. We sort of had
+            this in CPSRethreading, but that phase runs too infrequently and doesn't run at all for
+            SSA.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAdjacencyList.h:
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::run):
+            (JSC::DFG::CSEPhase::setReplacement):
+            (JSC::DFG::CSEPhase::eliminate):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren): Deleted.
+            * dfg/DFGPhantomRemovalPhase.cpp: Added.
+            (JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase):
+            (JSC::DFG::PhantomRemovalPhase::run):
+            (JSC::DFG::performCleanUp):
+            * dfg/DFGPhantomRemovalPhase.h: Added.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+    
+    2014-07-08  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Get rid of Node::misc by moving the fields out of the union so that you can use replacement and owner simultaneously
+            https://bugs.webkit.org/show_bug.cgi?id=134730
+    
+            Reviewed by Mark Lam.
+            
+            This will allow for a better GCSE implementation.
+    
+            * dfg/DFGCPSRethreadingPhase.cpp:
+            (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::setReplacement):
+            * dfg/DFGEdgeDominates.h:
+            (JSC::DFG::EdgeDominates::operator()):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::clearReplacements):
+            (JSC::DFG::Graph::initializeNodeOwners):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::performSubstitutionForEdge):
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::attemptHoist):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::Node):
+            * dfg/DFGSSAConversionPhase.cpp:
+            (JSC::DFG::SSAConversionPhase::run):
+    
+    2014-07-04  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Infer immutable object properties
+            https://bugs.webkit.org/show_bug.cgi?id=134567
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This introduces a new way of inferring immutable object properties. A property is said to
+            be immutable if after its creation (i.e. the transition that creates it), we never
+            overwrite it (i.e. replace it) or delete it. Immutability is a property of an "own
+            property" - so if we say that "f" is immutable at "o" then we are implying that "o" has "f"
+            directly and not on a prototype. More specifically, the immutability inference will prove
+            that a property on some structure is immutable. This means that, for example, we may have a
+            structure S1 with property "f" where we claim that "f" at S1 is immutable, but S1 has a
+            transition to S2 that adds a new property "g" and we may claim that "f" at S2 is actually
+            mutable. This is mainly for convenience; it allows us to decouple immutability logic from
+            transition logic. Immutability can be used to constant-fold accesses to objects at
+            DFG-time. The DFG needs to prove the following to constant-fold the access:
+            
+            - The base of the access must be a constant object pointer. We prove that a property at a
+              structure is immutable, but that says nothing of its value; each actual instance of that
+              property may have a different value. So, a constant object pointer is needed to get an
+              actual constant instance of the immutable value.
+            
+            - A check (or watchpoint) must have been emitted proving that the object has a structure
+              that allows loading the property in question.
+            
+            - The replacement watchpoint set of the property in the structure that we've proven the
+              object to have is still valid and we add a watchpoint to it lazily. The replacement
+              watchpoint set is the key new mechanism that this change adds. It's possible that we have
+              proven that the object has one of many structures, in which case each of those structures
+              needs a valid replacement watchpoint set.
+            
+            The replacement watchpoint set is created the first time that any access to the property is
+            cached. A put replace cache will create, and immediately invalidate, the watchpoint set. A
+            get cache will create the watchpoint set and make it start watching. Any non-cached put
+            access will invalidate the watchpoint set if one had been created; the underlying algorithm
+            ensures that checking for the existence of a replacement watchpoint set is very fast in the
+            common case. This algorithm ensures that no cached access needs to ever do any work to
+            invalidate, or check the validity of, any replacement watchpoint sets. It also has some
+            other nice properties:
+            
+            - It's very robust in its definition of immutability. The strictest that it will ever be is
+              that for any instance of the object, the property must be written to only once,
+              specifically at the time that the property is created. But it's looser than this in
+              practice. For example, the property may be written to any number of times before we add
+              the final property that the object will have before anyone reads the property; this works
+              since for optimization purposes we only care if we detect immutability on the structure
+              that the object will have when it is most frequently read from, not any previous
+              structure that the object had. Also, we may write to the property any number of times
+              before anyone caches accesses to it.
+            
+            - It is mostly orthogonal to structure transitions. No new structures need to be created to
+              track the immutability of a property. Hence, there is no risk from this feature causing
+              more polymorphism. This is different from the previous "specificValue" constant
+              inference, which did cause additional structures to be created and sometimes those
+              structures led to fake polymorphism. This feature does leverage existing transitions to
+              do some of the watchpointing: property deletions don't fire the replacement watchpoint
+              set because that would cause a new structure and so the mandatory structure check would
+              fail. Also, this feature is guaranteed to never kick in for uncacheable dictionaries
+              because those wouldn't allow for cacheable accesses - and it takes a cacheable access for
+              this feature to be enabled.
+            
+            - No memory overhead is incurred except when accesses to the property are cached.
+              Dictionary properties will typically have no meta-data for immutability. The number of
+              replacement watchpoint sets we allocate is proportional to the number of inline caches in
+              the program, which is typically must smaller than the number of structures or even the
+              number of objects.
+            
+            This inference is far more powerful than the previous "specificValue" inference, so this
+            change also removes all of that code. It's interesting that the amount of code that is
+            changed to remove that feature is almost as big as the amount of code added to support the
+            new inference - and that's if you include the new tests in the tally. Without new tests,
+            it appears that the new feature actually touches less code!
+            
+            There is one corner case where the previous "specificValue" inference was more powerful.
+            You can imagine someone creating objects with functions as self properties on those
+            objects, such that each object instance had the same function pointers - essentially,
+            someone might be trying to create a vtable but failing at the whole "one vtable for many
+            instances" concept. The "specificValue" inference would do very well for such programs,
+            because a structure check would be sufficient to prove a constant value for all of the
+            function properties. This new inference will fail because it doesn't track the constant
+            values of constant properties; instead it detects the immutability of otherwise variable
+            properties (in the sense that each instance of the property may have a different value).
+            So, the new inference requires having a particular object instance to actually get the
+            constant value. I think it's OK to lose this antifeature. It took a lot of code to support
+            and was a constant source of grief in our transition logic, and there doesn't appear to be
+            any real evidence that programs benefited from that particular kind of inference since
+            usually it's the singleton prototype instance that has all of the functions.
+            
+            This change is a speed-up on everything. date-format-xparb and both SunSpider/raytrace and
+            V8/raytrace seem to be the biggest winners among the macrobenchmarks; they see >5%
+            speed-ups. Many of our microbenchmarks see very large performance improvements, even 80% in
+            one case.
+    
+            * bytecode/ComplexGetStatus.cpp:
+            (JSC::ComplexGetStatus::computeFor):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeFromLLInt):
+            (JSC::GetByIdStatus::computeForStubInfo):
+            (JSC::GetByIdStatus::computeFor):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::operator=):
+            (JSC::GetByIdVariant::attemptToMerge):
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::alternateBase):
+            (JSC::GetByIdVariant::specificValue): Deleted.
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeForStubInfo):
+            (JSC::PutByIdStatus::computeFor):
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::operator=):
+            (JSC::PutByIdVariant::setter):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::specificValue): Deleted.
+            * bytecode/Watchpoint.cpp:
+            (JSC::WatchpointSet::fireAllSlow):
+            (JSC::WatchpointSet::fireAll): Deleted.
+            * bytecode/Watchpoint.h:
+            (JSC::WatchpointSet::fireAll):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleGetByOffset):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+            (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::tryGetConstantProperty):
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGGraph.h:
+            * dfg/DFGWatchableStructureWatchingPhase.cpp:
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * jit/JITOperations.cpp:
+            * jit/Repatch.cpp:
+            (JSC::repatchByIdSelfAccess):
+            (JSC::generateByIdStub):
+            (JSC::tryCacheGetByID):
+            (JSC::tryCachePutByID):
+            (JSC::tryBuildPutByIdList):
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            (JSC::LLInt::putToScopeCommon):
+            * runtime/CommonSlowPaths.h:
+            (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::mayInterceptStoreTo):
+            * runtime/JSCJSValue.cpp:
+            (JSC::JSValue::putToPrimitive):
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::reset):
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::put):
+            (JSC::JSObject::putDirectNonIndexAccessor):
+            (JSC::JSObject::deleteProperty):
+            (JSC::JSObject::defaultValue):
+            (JSC::getCallableObjectSlow): Deleted.
+            (JSC::JSObject::getPropertySpecificValue): Deleted.
+            * runtime/JSObject.h:
+            (JSC::JSObject::getDirect):
+            (JSC::JSObject::getDirectOffset):
+            (JSC::JSObject::inlineGetOwnPropertySlot):
+            (JSC::JSObject::putDirectInternal):
+            (JSC::JSObject::putOwnDataProperty):
+            (JSC::JSObject::putDirect):
+            (JSC::JSObject::putDirectWithoutTransition):
+            (JSC::getCallableObject): Deleted.
+            * runtime/JSScope.cpp:
+            (JSC::abstractAccess):
+            * runtime/PropertyMapHashTable.h:
+            (JSC::PropertyMapEntry::PropertyMapEntry):
+            (JSC::PropertyTable::copy):
+            * runtime/PropertyTable.cpp:
+            (JSC::PropertyTable::clone):
+            (JSC::PropertyTable::PropertyTable):
+            (JSC::PropertyTable::visitChildren): Deleted.
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::materializePropertyMap):
+            (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
+            (JSC::Structure::addPropertyTransitionToExistingStructure):
+            (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
+            (JSC::Structure::addPropertyTransition):
+            (JSC::Structure::changePrototypeTransition):
+            (JSC::Structure::attributeChangeTransition):
+            (JSC::Structure::toDictionaryTransition):
+            (JSC::Structure::preventExtensionsTransition):
+            (JSC::Structure::takePropertyTableOrCloneIfPinned):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::addPropertyWithoutTransition):
+            (JSC::Structure::allocateRareData):
+            (JSC::Structure::ensurePropertyReplacementWatchpointSet):
+            (JSC::Structure::startWatchingPropertyForReplacements):
+            (JSC::Structure::didCachePropertyReplacement):
+            (JSC::Structure::startWatchingInternalProperties):
+            (JSC::Structure::copyPropertyTable):
+            (JSC::Structure::copyPropertyTableForPinning):
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::get):
+            (JSC::Structure::add):
+            (JSC::Structure::visitChildren):
+            (JSC::Structure::prototypeChainMayInterceptStoreTo):
+            (JSC::Structure::dump):
+            (JSC::Structure::despecifyDictionaryFunction): Deleted.
+            (JSC::Structure::despecifyFunctionTransition): Deleted.
+            (JSC::Structure::despecifyFunction): Deleted.
+            (JSC::Structure::despecifyAllFunctions): Deleted.
+            (JSC::Structure::putSpecificValue): Deleted.
+            * runtime/Structure.h:
+            (JSC::Structure::startWatchingPropertyForReplacements):
+            (JSC::Structure::startWatchingInternalPropertiesIfNecessary):
+            (JSC::Structure::startWatchingInternalPropertiesIfNecessaryForEntireChain):
+            (JSC::Structure::transitionDidInvolveSpecificValue): Deleted.
+            (JSC::Structure::disableSpecificFunctionTracking): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::didReplaceProperty):
+            (JSC::Structure::propertyReplacementWatchpointSet):
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::destroy):
+            * runtime/StructureRareData.h:
+            * tests/stress/infer-constant-global-property.js: Added.
+            (foo.Math.sin):
+            (foo):
+            * tests/stress/infer-constant-property.js: Added.
+            (foo):
+            * tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+            * tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js: Added.
+            (foo):
+            (bar):
+    
+    2014-07-03  Saam Barati  <sbarati@apple.com>
+    
+            Add more coverage for the profile_types_with_high_fidelity op code.
+            https://bugs.webkit.org/show_bug.cgi?id=134616
+    
+            Reviewed by Filip Pizlo.
+    
+            More operations are now being recorded by the profile_types_with_high_fidelity 
+            opcode. Specifically: function parameters, function return values,
+            function 'this' value, get_by_id, get_by_value, resolve nodes, function return 
+            values at the call site. Added more flags to the profile_types_with_high_fidelity
+            opcode so more focused tasks can take place when the instruction is
+            being linked in CodeBlock. Re-worked the type profiler to search 
+            through character offset ranges when asked for the type of an expression
+            at a given offset. Removed redundant calls to Structure::toStructureShape
+            in HighFidelityLog and TypeSet by caching calls based on StructureID.
+    
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            (JSC::CodeBlock::scopeDependentProfile):
+            * bytecode/CodeBlock.h:
+            (JSC::CodeBlock::returnStatementTypeSet):
+            * bytecode/TypeLocation.h:
+            * bytecode/UnlinkedCodeBlock.cpp:
+            (JSC::UnlinkedCodeBlock::highFidelityTypeProfileExpressionInfoForBytecodeOffset):
+            (JSC::UnlinkedCodeBlock::addHighFidelityTypeProfileExpressionInfo):
+            * bytecode/UnlinkedCodeBlock.h:
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitMove):
+            (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+            (JSC::BytecodeGenerator::emitGetFromScopeWithProfile):
+            (JSC::BytecodeGenerator::emitPutToScope):
+            (JSC::BytecodeGenerator::emitPutToScopeWithProfile):
+            (JSC::BytecodeGenerator::emitPutById):
+            (JSC::BytecodeGenerator::emitPutByVal):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::ResolveNode::emitBytecode):
+            (JSC::BracketAccessorNode::emitBytecode):
+            (JSC::DotAccessorNode::emitBytecode):
+            (JSC::FunctionCallValueNode::emitBytecode):
+            (JSC::FunctionCallResolveNode::emitBytecode):
+            (JSC::FunctionCallBracketNode::emitBytecode):
+            (JSC::FunctionCallDotNode::emitBytecode):
+            (JSC::CallFunctionCallDotNode::emitBytecode):
+            (JSC::ApplyFunctionCallDotNode::emitBytecode):
+            (JSC::PostfixNode::emitResolve):
+            (JSC::PostfixNode::emitBracket):
+            (JSC::PostfixNode::emitDot):
+            (JSC::PrefixNode::emitResolve):
+            (JSC::PrefixNode::emitBracket):
+            (JSC::PrefixNode::emitDot):
+            (JSC::ReadModifyResolveNode::emitBytecode):
+            (JSC::AssignResolveNode::emitBytecode):
+            (JSC::AssignDotNode::emitBytecode):
+            (JSC::ReadModifyDotNode::emitBytecode):
+            (JSC::AssignBracketNode::emitBytecode):
+            (JSC::ReadModifyBracketNode::emitBytecode):
+            (JSC::ReturnNode::emitBytecode):
+            (JSC::FunctionBodyNode::emitBytecode):
+            * inspector/agents/InspectorRuntimeAgent.cpp:
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset):
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange): Deleted.
+            * inspector/agents/InspectorRuntimeAgent.h:
+            * inspector/protocol/Runtime.json:
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::getFromScopeCommon):
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            * llint/LLIntSlowPaths.h:
+            * llint/LowLevelInterpreter.asm:
+            * runtime/HighFidelityLog.cpp:
+            (JSC::HighFidelityLog::processHighFidelityLog):
+            (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
+            (JSC::HighFidelityLog::recordTypeInformationForLocation): Deleted.
+            * runtime/HighFidelityLog.h:
+            (JSC::HighFidelityLog::recordTypeInformationForLocation):
+            * runtime/HighFidelityTypeProfiler.cpp:
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset):
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset):
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset):
+            (JSC::HighFidelityTypeProfiler::insertNewLocation):
+            (JSC::HighFidelityTypeProfiler::findLocation):
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange): Deleted.
+            (JSC::HighFidelityTypeProfiler::getLocationBasedHash): Deleted.
+            * runtime/HighFidelityTypeProfiler.h:
+            (JSC::LocationKey::LocationKey): Deleted.
+            (JSC::LocationKey::hash): Deleted.
+            (JSC::LocationKey::operator==): Deleted.
+            * runtime/Structure.cpp:
+            (JSC::Structure::toStructureShape):
+            * runtime/Structure.h:
+            * runtime/TypeSet.cpp:
+            (JSC::TypeSet::TypeSet):
+            (JSC::TypeSet::addTypeForValue):
+            (JSC::TypeSet::seenTypes):
+            (JSC::TypeSet::removeDuplicatesInStructureHistory): Deleted.
+            * runtime/TypeSet.h:
+            (JSC::StructureShape::setConstructorName):
+            * runtime/VM.cpp:
+            (JSC::VM::getTypesForVariableAtOffset):
+            (JSC::VM::dumpHighFidelityProfilingTypes):
+            (JSC::VM::getTypesForVariableInRange): Deleted.
+            * runtime/VM.h:
+    
+    2014-07-04  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt][REGRESSION] debug tests fail because PutByIdDirect is now implemented in terms of In
+            https://bugs.webkit.org/show_bug.cgi?id=134642
+    
+            Rubber stamped by Andreas Kling.
+    
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+    
+    2014-07-01  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Allocate a new GetterSetter if we change the value of any of its entries other than when they were previously null, so that if we constant-infer an accessor slot then we immediately get the function constant for free
+            https://bugs.webkit.org/show_bug.cgi?id=134518
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This has no real effect right now, particularly since almost all uses of
+            setSetter/setGetter were already allocating a branch new GetterSetter. But once we start
+            doing more aggressive constant property inference, this change will allow us to remove
+            all runtime checks from getter/setter calls.
+    
+            * runtime/GetterSetter.cpp:
+            (JSC::GetterSetter::withGetter):
+            (JSC::GetterSetter::withSetter):
+            * runtime/GetterSetter.h:
+            (JSC::GetterSetter::setGetter):
+            (JSC::GetterSetter::setSetter):
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::defineOwnNonIndexProperty):
+    
+    2014-07-02  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Rename notifyTransitionFromThisStructure to didTransitionFromThisStructure
+    
+            Rubber stamped by Mark Hahnenberg.
+    
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::didTransitionFromThisStructure):
+            (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
+            * runtime/Structure.h:
+    
+    2014-07-02  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Remove the functionality for cloning StructureRareData since we never do that anymore.
+    
+            Rubber stamped by Mark Hahnenberg.
+    
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            (JSC::Structure::cloneRareDataFrom): Deleted.
+            * runtime/Structure.h:
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::clone): Deleted.
+            (JSC::StructureRareData::StructureRareData): Deleted.
+            * runtime/StructureRareData.h:
+            (JSC::StructureRareData::needsCloning): Deleted.
+    
+    2014-07-01  Mark Lam  <mark.lam@apple.com>
+    
+            [ftlopt] DebuggerCallFrame::scope() should return a DebuggerScope.
+            <https://webkit.org/b/134420>
+    
+            Reviewed by Geoffrey Garen.
+    
+            Previously, DebuggerCallFrame::scope() returns a JSActivation (and relevant
+            peers) which the WebInspector will use to introspect CallFrame variables.
+            Instead, we should be returning a DebuggerScope as an abstraction layer that
+            provides the introspection functionality that the WebInspector needs.  This
+            is the first step towards not forcing every frame to have a JSActivation
+            object just because the debugger is enabled.
+    
+            1. Instantiate the debuggerScopeStructure as a member of the JSGlobalObject
+               instead of the VM.  This allows JSObject::globalObject() to be able to
+               return the global object for the DebuggerScope.
+    
+            2. On the DebuggerScope's life-cycle management:
+    
+               The DebuggerCallFrame is designed to be "valid" only during a debugging session
+               (while the debugger is broken) through the use of a DebuggerCallFrameScope in
+               Debugger::pauseIfNeeded().  Once the debugger resumes from the break, the
+               DebuggerCallFrameScope destructs, and the DebuggerCallFrame will be invalidated.
+               We can't guarantee (from this code alone) that the Inspector code isn't still
+               holding a ref to the DebuggerCallFrame (though they shouldn't), but by contract,
+               the frame will be invalidated, and any attempt to query it will return null values.
+               This is pre-existing behavior.
+    
+               Now, we're adding the DebuggerScope into the picture.  While a single debugger
+               pause session is in progress, the Inspector may request the scope from the
+               DebuggerCallFrame.  While the DebuggerCallFrame is still valid, we want
+               DebuggerCallFrame::scope() to always return the same DebuggerScope object.
+               This is why we hold on to the DebuggerScope with a strong ref.
+    
+               If we use a weak ref instead, the following cooky behavior can manifest:
+               1. The Inspector calls Debugger::scope() to get the top scope.
+               2. The Inspector iterates down the scope chain and is now only holding a
+                  reference to a parent scope.  It is no longer referencing the top scope.
+               3. A GC occurs, and the DebuggerCallFrame's weak m_scope ref to the top scope
+                  gets cleared.
+               4. The Inspector calls DebuggerCallFrame::scope() to get the top scope again but gets
+                  a different DebuggerScope instance.
+               5. The Inspector iterates down the scope chain but never sees the parent scope
+                  instance that retained a ref to in step 2 above.  This is because when iterating
+                  this new DebuggerScope instance (which has no knowledge of the previous parent
+                  DebuggerScope instance), a new DebuggerScope instance will get created for the
+                  same parent scope. 
+    
+               Since the DebuggerScope is a JSObject, it's liveness is determined by its reachability.
+               However, it's "validity" is determined by the life-cycle of its owner DebuggerCallFrame.
+               When the owner DebuggerCallFrame gets invalidated, its debugger scope chain (if
+               instantiated) will also get invalidated.  This is why we need the
+               DebuggerScope::invalidateChain() method.  The Inspector should not be using the
+               DebuggerScope instance after its owner DebuggerCallFrame is invalidated.  If it does,
+               those methods will do nothing or returned a failed status.
+    
+            * debugger/Debugger.h:
+            * debugger/DebuggerCallFrame.cpp:
+            (JSC::DebuggerCallFrame::scope):
+            (JSC::DebuggerCallFrame::evaluate):
+            (JSC::DebuggerCallFrame::invalidate):
+            (JSC::DebuggerCallFrame::vm):
+            (JSC::DebuggerCallFrame::lexicalGlobalObject):
+            * debugger/DebuggerCallFrame.h:
+            * debugger/DebuggerScope.cpp:
+            (JSC::DebuggerScope::DebuggerScope):
+            (JSC::DebuggerScope::finishCreation):
+            (JSC::DebuggerScope::visitChildren):
+            (JSC::DebuggerScope::className):
+            (JSC::DebuggerScope::getOwnPropertySlot):
+            (JSC::DebuggerScope::put):
+            (JSC::DebuggerScope::deleteProperty):
+            (JSC::DebuggerScope::getOwnPropertyNames):
+            (JSC::DebuggerScope::defineOwnProperty):
+            (JSC::DebuggerScope::next):
+            (JSC::DebuggerScope::invalidateChain):
+            (JSC::DebuggerScope::isWithScope):
+            (JSC::DebuggerScope::isGlobalScope):
+            (JSC::DebuggerScope::isFunctionScope):
+            * debugger/DebuggerScope.h:
+            (JSC::DebuggerScope::create):
+            (JSC::DebuggerScope::Iterator::Iterator):
+            (JSC::DebuggerScope::Iterator::get):
+            (JSC::DebuggerScope::Iterator::operator++):
+            (JSC::DebuggerScope::Iterator::operator==):
+            (JSC::DebuggerScope::Iterator::operator!=):
+            (JSC::DebuggerScope::isValid):
+            (JSC::DebuggerScope::jsScope):
+            (JSC::DebuggerScope::begin):
+            (JSC::DebuggerScope::end):
+            * inspector/JSJavaScriptCallFrame.cpp:
+            (Inspector::JSJavaScriptCallFrame::scopeType):
+            (Inspector::JSJavaScriptCallFrame::scopeChain):
+            * inspector/JavaScriptCallFrame.h:
+            (Inspector::JavaScriptCallFrame::scopeChain):
+            * inspector/ScriptDebugServer.cpp:
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::reset):
+            (JSC::JSGlobalObject::visitChildren):
+            * runtime/JSGlobalObject.h:
+            (JSC::JSGlobalObject::debuggerScopeStructure):
+            * runtime/JSObject.h:
+            (JSC::JSObject::isWithScope):
+            * runtime/JSScope.h:
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-07-01  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG bytecode parser should turn PutById with nothing but a Setter stub as stuff+handleCall, and handleCall should be allowed to inline if it wants to
+            https://bugs.webkit.org/show_bug.cgi?id=130756
+    
+            Reviewed by Oliver Hunt.
+            
+            The enables exposing the call to setters in the DFG, and then inlining it. Previously we
+            already supproted inlined-cached calls to setters from within put_by_id inline caches,
+            and the DFG could certainly emit such IC's. Now, if an IC had a setter call, then the DFG
+            will either emit the GetGetterSetterByOffset/GetSetter/Call combo, or it will do one
+            better and inline the call.
+            
+            A lot of the core functionality was already available from the previous work to inline
+            getters. So, there are some refactorings in this patch that move preexisting
+            functionality around. For example, the work to figure out how the DFG should go about
+            getting to what we call the "loaded value" - i.e. the GetterSetter object reference in
+            the case of accessors - is now shared in ComplexGetStatus, and both GetByIdStatus and
+            PutByIdStatus use it. This means that we can keep the safety checks common.  This patch
+            also does additional refactorings in DFG::ByteCodeParser so that we can continue to reuse
+            handleCall() for all of the various kinds of calls we can now emit.
+            
+            83% speed-up on getter-richards, 2% speed-up on box2d.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/ComplexGetStatus.cpp: Added.
+            (JSC::ComplexGetStatus::computeFor):
+            * bytecode/ComplexGetStatus.h: Added.
+            (JSC::ComplexGetStatus::ComplexGetStatus):
+            (JSC::ComplexGetStatus::skip):
+            (JSC::ComplexGetStatus::takesSlowPath):
+            (JSC::ComplexGetStatus::kind):
+            (JSC::ComplexGetStatus::attributes):
+            (JSC::ComplexGetStatus::specificValue):
+            (JSC::ComplexGetStatus::offset):
+            (JSC::ComplexGetStatus::chain):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            * bytecode/PolymorphicPutByIdList.h:
+            (JSC::PutByIdAccess::PutByIdAccess):
+            (JSC::PutByIdAccess::setter):
+            (JSC::PutByIdAccess::structure):
+            (JSC::PutByIdAccess::chainCount):
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFromLLInt):
+            (JSC::PutByIdStatus::computeFor):
+            (JSC::PutByIdStatus::computeForStubInfo):
+            (JSC::PutByIdStatus::makesCalls):
+            * bytecode/PutByIdStatus.h:
+            (JSC::PutByIdStatus::makesCalls): Deleted.
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::operator=):
+            (JSC::PutByIdVariant::replace):
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::setter):
+            (JSC::PutByIdVariant::writesStructures):
+            (JSC::PutByIdVariant::reallocatesStorage):
+            (JSC::PutByIdVariant::makesCalls):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::structure):
+            (JSC::PutByIdVariant::oldStructure):
+            (JSC::PutByIdVariant::alternateBase):
+            (JSC::PutByIdVariant::specificValue):
+            (JSC::PutByIdVariant::callLinkStatus):
+            (JSC::PutByIdVariant::replace): Deleted.
+            (JSC::PutByIdVariant::transition): Deleted.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+            (JSC::DFG::ByteCodeParser::addCall):
+            (JSC::DFG::ByteCodeParser::handleCall):
+            (JSC::DFG::ByteCodeParser::handleInlining):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * jit/Repatch.cpp:
+            (JSC::tryCachePutByID):
+            (JSC::tryBuildPutByIdList):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::takesSlowPathInDFGForImpureProperty):
+            * runtime/IntendedStructureChain.h:
+            * tests/stress/exit-from-setter.js: Added.
+            * tests/stress/poly-chain-setter.js: Added.
+            (Cons):
+            (foo):
+            (test):
+            * tests/stress/poly-chain-then-setter.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            * tests/stress/poly-setter-combo.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/poly-setter-then-self.js: Added.
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/weird-setter-counter.js: Added.
+            (foo):
+            (test):
+            * tests/stress/weird-setter-counter-syntactic.js: Added.
+            (foo):
+            (test):
+    
+    2014-07-01  Matthew Mirman  <mmirman@apple.com>
+    
+            Added an implementation of the "in" check to FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=134508
+    
+            Reviewed by Filip Pizlo.
+    
+            * ftl/FTLCapabilities.cpp: enabled compilation for "in"
+            (JSC::FTL::canCompile): ditto
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::generateCheckInICFastPath): added.
+            (JSC::FTL::fixFunctionBasedOnStackMaps): added case for CheckIn descriptors.
+            * ftl/FTLInlineCacheDescriptor.h:
+            (JSC::FTL::CheckInGenerator::CheckInGenerator): added.
+            (JSC::FTL::CheckInDescriptor::CheckInDescriptor): added.
+            * ftl/FTLInlineCacheSize.cpp: 
+            (JSC::FTL::sizeOfCheckIn): added. Currently larger than necessary.
+            * ftl/FTLInlineCacheSize.h: ditto
+            * ftl/FTLIntrinsicRepository.h: Added function type for operationInGeneric
+            * ftl/FTLLowerDFGToLLVM.cpp: 
+            (JSC::FTL::LowerDFGToLLVM::compileNode): added case for In.
+            (JSC::FTL::LowerDFGToLLVM::compileIn): added.
+            * ftl/FTLSlowPathCall.cpp: Added a callOperation for operationIn
+            (JSC::FTL::callOperation): ditto
+            * ftl/FTLSlowPathCall.h: ditto
+            * ftl/FTLState.h: Added a vector to hold CheckIn descriptors.
+            * jit/JITOperations.h: made operationIns internal.
+            * tests/stress/ftl-checkin.js: Added.
+            * tests/stress/ftl-checkin-variable.js: Added.
+    
+    2014-06-30  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            CodeBlock::stronglyVisitWeakReferences should mark DFG::CommonData::weakStructureReferences
+            https://bugs.webkit.org/show_bug.cgi?id=134455
+    
+            Reviewed by Geoffrey Garen.
+    
+            Otherwise we get hanging pointers which can cause us to die later.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::stronglyVisitWeakReferences):
+    
+    2014-06-27  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Reduce the GC's influence on optimization decisions
+            https://bugs.webkit.org/show_bug.cgi?id=134427
+    
+            Reviewed by Oliver Hunt.
+            
+            This is a slight speed-up on some platforms, that arises from a bunch of fixes that I made
+            while trying to make the GC keep more structures alive
+            (https://bugs.webkit.org/show_bug.cgi?id=128072).
+            
+            The fixes are, roughly:
+            
+            - If the GC clears an inline cache, then this no longer causes the IC to be forever
+              polymorphic.
+            
+            - If we exit in inlined code into a function that tries to OSR enter, then we jettison
+              sooner.
+            
+            - Some variables being uninitialized led to rage-recompilations.
+            
+            This is a pretty strong step in the direction of keeping more Structures alive and not
+            blowing away code just because a Structure died. But, it seems like there is still a slight
+            speed-up to be had from blowing away code that references dead Structures.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpAssumingJITType):
+            (JSC::shouldMarkTransition):
+            (JSC::CodeBlock::propagateTransitions):
+            (JSC::CodeBlock::determineLiveness):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeForStubInfo):
+            * dfg/DFGCapabilities.cpp:
+            (JSC::DFG::isSupportedForInlining):
+            (JSC::DFG::mightInlineFunctionForCall):
+            (JSC::DFG::mightInlineFunctionForClosureCall):
+            (JSC::DFG::mightInlineFunctionForConstruct):
+            * dfg/DFGCapabilities.h:
+            * dfg/DFGCommonData.h:
+            * dfg/DFGDesiredWeakReferences.cpp:
+            (JSC::DFG::DesiredWeakReferences::reallyAdd):
+            * dfg/DFGOSREntry.cpp:
+            (JSC::DFG::prepareOSREntry):
+            * dfg/DFGOSRExitCompilerCommon.cpp:
+            (JSC::DFG::handleExitCounts):
+            * dfg/DFGOperations.cpp:
+            * dfg/DFGOperations.h:
+            * ftl/FTLForOSREntryJITCode.cpp:
+            (JSC::FTL::ForOSREntryJITCode::ForOSREntryJITCode): These variables being uninitialized is benign in terms of correctness but can sometimes cause rage-recompilations. For some reason it took this patch to reveal this.
+            * ftl/FTLOSREntry.cpp:
+            (JSC::FTL::prepareOSREntry):
+            * runtime/Executable.cpp:
+            (JSC::ExecutableBase::destroy):
+            (JSC::NativeExecutable::destroy):
+            (JSC::ScriptExecutable::ScriptExecutable):
+            (JSC::ScriptExecutable::destroy):
+            (JSC::ScriptExecutable::installCode):
+            (JSC::EvalExecutable::EvalExecutable):
+            (JSC::ProgramExecutable::ProgramExecutable):
+            * runtime/Executable.h:
+            (JSC::ScriptExecutable::setDidTryToEnterInLoop):
+            (JSC::ScriptExecutable::didTryToEnterInLoop):
+            (JSC::ScriptExecutable::addressOfDidTryToEnterInLoop):
+            (JSC::ScriptExecutable::ScriptExecutable): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::storedPrototypeObject):
+            (JSC::Structure::storedPrototypeStructure):
+    
+    2014-06-25  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] If a CodeBlock is jettisoned due to a watchpoint then it should be possible to figure out something about that watchpoint
+            https://bugs.webkit.org/show_bug.cgi?id=134333
+    
+            Reviewed by Geoffrey Garen.
+            
+            This is engineered to provide loads of information to the profiler without incurring any
+            costs when the profiler is disabled. It's the oldest trick in the book: the thing that
+            fires the watchpoint doesn't actually create anything to describe the reason why it was
+            fired; instead it creates a stack-allocated FireDetail subclass instance. Only if the
+            FireDetail::dump() virtual method is called does anything happen.
+            
+            Currently we use this to produce very fine-grained data for Structure watchpoints and
+            some cases of variable watchpoints. For all other situations, the given reason is just a
+            string constant, by using StringFireDetail. If we find a situation where that string
+            constant is insufficient to diagnose an issue then we can change it to provide more
+            fine-grained information.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::jettison):
+            * bytecode/CodeBlock.h:
+            * bytecode/CodeBlockJettisoningWatchpoint.cpp:
+            (JSC::CodeBlockJettisoningWatchpoint::fireInternal):
+            * bytecode/CodeBlockJettisoningWatchpoint.h:
+            * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp: Removed.
+            * bytecode/ProfiledCodeBlockJettisoningWatchpoint.h: Removed.
+            * bytecode/StructureStubClearingWatchpoint.cpp:
+            (JSC::StructureStubClearingWatchpoint::fireInternal):
+            * bytecode/StructureStubClearingWatchpoint.h:
+            * bytecode/VariableWatchpointSet.h:
+            (JSC::VariableWatchpointSet::invalidate):
+            (JSC::VariableWatchpointSet::finalizeUnconditionally):
+            * bytecode/VariableWatchpointSetInlines.h:
+            (JSC::VariableWatchpointSet::notifyWrite):
+            * bytecode/Watchpoint.cpp:
+            (JSC::StringFireDetail::dump):
+            (JSC::WatchpointSet::fireAll):
+            (JSC::WatchpointSet::fireAllSlow):
+            (JSC::WatchpointSet::fireAllWatchpoints):
+            (JSC::InlineWatchpointSet::fireAll):
+            * bytecode/Watchpoint.h:
+            (JSC::FireDetail::FireDetail):
+            (JSC::FireDetail::~FireDetail):
+            (JSC::StringFireDetail::StringFireDetail):
+            (JSC::Watchpoint::fire):
+            (JSC::WatchpointSet::fireAll):
+            (JSC::WatchpointSet::touch):
+            (JSC::WatchpointSet::invalidate):
+            (JSC::InlineWatchpointSet::fireAll):
+            (JSC::InlineWatchpointSet::touch):
+            * dfg/DFGCommonData.h:
+            * dfg/DFGOperations.cpp:
+            * interpreter/Interpreter.cpp:
+            (JSC::Interpreter::execute):
+            * jsc.cpp:
+            (WTF::Masquerader::create):
+            * profiler/ProfilerCompilation.cpp:
+            (JSC::Profiler::Compilation::setJettisonReason):
+            (JSC::Profiler::Compilation::toJS):
+            * profiler/ProfilerCompilation.h:
+            (JSC::Profiler::Compilation::setJettisonReason): Deleted.
+            * runtime/ArrayBuffer.cpp:
+            (JSC::ArrayBuffer::transfer):
+            * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+            (JSC::ArrayBufferNeuteringWatchpoint::fireAll):
+            * runtime/ArrayBufferNeuteringWatchpoint.h:
+            * runtime/CommonIdentifiers.h:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+            * runtime/Identifier.cpp:
+            (JSC::Identifier::dump):
+            * runtime/Identifier.h:
+            * runtime/JSFunction.cpp:
+            (JSC::JSFunction::put):
+            (JSC::JSFunction::defineOwnProperty):
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::addFunction):
+            (JSC::JSGlobalObject::haveABadTime):
+            * runtime/JSSymbolTableObject.cpp:
+            (JSC::VariableWriteFireDetail::dump):
+            * runtime/JSSymbolTableObject.h:
+            (JSC::VariableWriteFireDetail::VariableWriteFireDetail):
+            (JSC::symbolTablePut):
+            (JSC::symbolTablePutWithAttributes):
+            * runtime/PropertyName.h:
+            (JSC::PropertyName::dump):
+            * runtime/Structure.cpp:
+            (JSC::Structure::notifyTransitionFromThisStructure):
+            * runtime/Structure.h:
+            (JSC::Structure::notifyTransitionFromThisStructure): Deleted.
+            * runtime/SymbolTable.cpp:
+            (JSC::SymbolTableEntry::notifyWriteSlow):
+            (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTableEntry::notifyWrite):
+            * runtime/VM.cpp:
+            (JSC::VM::addImpureProperty):
+    
+2014-08-05  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r172099.
+        https://bugs.webkit.org/show_bug.cgi?id=135635
+
+        Needs a do-over. (Requested by kling on #webkit).
+
+        Reverted changeset:
+
+        "The JIT should cache property lookup misses."
+        https://bugs.webkit.org/show_bug.cgi?id=135578
+        http://trac.webkit.org/changeset/172099
+
+2014-08-05  Przemyslaw Kuczynski  <p.kuczynski@samsung.com>
+
+        Fix resource leak of unclosed file descriptor.
+        https://bugs.webkit.org/show_bug.cgi?id=135417
+
+        Reviewed by Darin Adler.
+
+        When open returns zero, fd handle leaks. Checking (fd > 0) needs to be replaced
+        with (fd != -1).
+
+        * assembler/MacroAssemblerARM.cpp:
+        (JSC::isVFPPresent):
+
+2014-08-05  Andreas Kling  <akling@apple.com>
+
+        The JIT should cache property lookup misses.
+        <https://webkit.org/b/135578>
+
+        Add support for inline caching of object properties that don't exist.
+        Previously we'd fall back to the C++ slow-path whenever a property was missing.
+
+        It's implemented as a simple GetById-style stub that returns jsUndefined() as
+        long as the Structure chain check passes.
+
+        10x speedup on the included microbenchmark.
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/Repatch.cpp:
+        (JSC::toString):
+        (JSC::kindFor):
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::patchJumpToGetByIdStub):
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::isUnset):
+
+2014-08-05  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r172009.
+        https://bugs.webkit.org/show_bug.cgi?id=135627
+
+        "Commit landed on trunk instead of ftlopt branch." (Requested
+        by saamyjoon on #webkit).
+
+        Reverted changeset:
+
+        "Create a more generic way for VMEntryScope to notify those
+        interested that it will be destroyed"
+        https://bugs.webkit.org/show_bug.cgi?id=135358
+        http://trac.webkit.org/changeset/172009
+
+2014-08-05  Alex Christensen  <achristensen@webkit.org>
+
+        More work on CMake.
+        https://bugs.webkit.org/show_bug.cgi?id=135620
+
+        Reviewed by Laszlo Gombos.
+
+        * CMakeLists.txt:
+        Added missing source files.
+        * PlatformEfl.cmake:
+        * PlatformGTK.cmake:
+        Include glib directories and libraries to find glib.h in EventLoop.cpp.
+        * PlatformMac.cmake:
+        Moved STATICALLY_LINKED_WITH_WTF definition away from the common CMakeLists
+        because it should not be defined on Windows.
+        Added remote inspector source files.
+
+2014-08-05  Peyton Randolph  <prandolph@apple.com>
+
+        Rename MAC_LONG_PRESS feature flag to LONG_MOUSE_PRESS.
+        https://bugs.webkit.org/show_bug.cgi?id=135276
+
+        Reviewed by Beth Dakin.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-04  Benjamin Poulain  <benjamin@webkit.org>
+
+        Add a flag for the CSS Selectors level 4 implementation
+        https://bugs.webkit.org/show_bug.cgi?id=135535
+
+        Reviewed by Andreas Kling.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-08-04  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards CMake on Mac.
+        https://bugs.webkit.org/show_bug.cgi?id=135528
+
+        Reviewed by Gyuyoung Kim.
+
+        * CMakeLists.txt:
+        Include necessary directories and copy all necessary forwarding headers.
+        Only compile UDis86Disassembler.cpp if we're using UDIS86.
+        * PlatformMac.cmake: Added.
+        * tools/CodeProfiling.cpp:
+        Compile fix.  Include sys/time.h on darwin, too.
+
+2014-08-04  Saam Barati  <sbarati@apple.com>
+
+        Create a more generic way for VMEntryScope to notify those interested that it will be destroyed
+        https://bugs.webkit.org/show_bug.cgi?id=135358
+
+        Reviewed by Geoffrey Garen.
+
+        When VMEntryScope is destroyed, and it has a flag set indicating that the
+        Debugger needs to recompile all functions, it calls Debugger::recompileAllJSFunctions. 
+        This flag is only used by Debugger to have VMEntryScope notify it when the
+        Debugger is safe to recompile all functions. This patch will substitute this
+        Debugger-specific recompilation flag with a list of callbacks that are notified 
+        when the outermost VMEntryScope dies. This creates a general purpose interface 
+        for being notified when the VM stops executing code via the event of the outermost 
+        VMEntryScope dying.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::recompileAllJSFunctions):
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        (JSC::VMEntryScope::addEntryScopeDidPopListener):
+        (JSC::VMEntryScope::~VMEntryScope):
+        * runtime/VMEntryScope.h:
+        (JSC::VMEntryScope::setRecompilationNeeded): Deleted.
+
+2014-08-01  Carlos Alberto Lopez Perez  <clopez@igalia.com>
+
+        REGRESSION(r171942): [CMAKE] [GTK] build broken (clean build).
+        https://bugs.webkit.org/show_bug.cgi?id=135522
+
+        Reviewed by Martin Robinson.
+
+        * CMakeLists.txt: Output the inspector headers inside inspector
+        subdirectory.
+
+2014-08-01  Mark Lam  <mark.lam@apple.com>
+
+        Add some structure related assertions.
+        <https://webkit.org/b/135523>
+
+        Reviewed by Geoffrey Garen.
+
+        Adding 2 assertions:
+        1. assert that we don't index pass the end of the StructureIDTable.
+           This should never happen, but this assertion will help catch bugs
+           where a bad structureID gets passed in.
+        2. assert that cells in MarkedBlock::callDestructor() that are not
+           zapped should have a non-null StructureID.  This will help us catch
+           bugs where the other cell header flag bits get set after the cell is
+           zapped, thereby making the cell look like an unzapped cell but has a
+           null structureID.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::callDestructor):
+        * runtime/StructureIDTable.h:
+        (JSC::StructureIDTable::get):
+
+2014-08-01  Csaba Osztrogonác  <ossy@webkit.org>
+
+        URTBF after r171946 to fix non-Apple builds.
+
+        * bytecode/InlineCallFrameSet.cpp:
+
+2014-08-01  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        CodeBlock fails to visit the Executables of its InlineCallFrames
+        https://bugs.webkit.org/show_bug.cgi?id=135471
+
+        Reviewed by Geoffrey Garen.
+
+        CodeBlock needs to visit its InlineCallFrames' owner Executables. If it doesn't, they 
+        can be prematurely collected and cause crashes.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::stronglyVisitStrongReferences):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::visitAggregate):
+        * bytecode/InlineCallFrameSet.cpp:
+        (JSC::InlineCallFrameSet::visitAggregate):
+        * bytecode/InlineCallFrameSet.h:
+
+2014-08-01  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards cmake on Windows.
+        https://bugs.webkit.org/show_bug.cgi?id=135484
+
+        Reviewed by Martin Robinson.
+
+        * CMakeLists.txt:
+        Generate code directly to inspector directory to avoid using the cp command
+        which is not available on Windows.
+        * PlatformWin.cmake: Added.
+
+2014-07-31  Andreas Kling  <akling@apple.com>
+
+        Remove the JSC::OverridesVisitChildren flag.
+        <https://webkit.org/b/135489>
+
+        Except for 3 special classes, the visitChildren() call is always
+        dispatched through the method table (see SlotVisitor.cpp.)
+
+        The OverridesVisitChildren flag doesn't actually do anything.
+        It could be used to implement a non-virtual direct call to
+        JSCell::visitChildren, bypassing the method table for some objects,
+        but such a micro-optimization seems like a weak trade for all this
+        code complexity. Instead, just remove the flag.
+
+        This change frees up an inline flag bit in JSCell.
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSAPIWrapperObject.h:
+        * API/JSAPIWrapperObject.mm:
+        (JSC::JSAPIWrapperObject::visitChildren):
+        * API/JSCallbackObject.h:
+        (JSC::JSCallbackObject::visitChildren):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::visitChildren):
+        (JSC::UnlinkedCodeBlock::visitChildren):
+        (JSC::UnlinkedProgramCodeBlock::visitChildren):
+        * bytecode/UnlinkedCodeBlock.h:
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::visitChildren):
+        * debugger/DebuggerScope.h:
+        * jsc.cpp:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::visitChildren):
+        * runtime/Arguments.h:
+        * runtime/Executable.cpp:
+        (JSC::EvalExecutable::visitChildren):
+        (JSC::ProgramExecutable::visitChildren):
+        (JSC::FunctionExecutable::visitChildren):
+        * runtime/Executable.h:
+        * runtime/GetterSetter.cpp:
+        (JSC::GetterSetter::visitChildren):
+        * runtime/GetterSetter.h:
+        (JSC::GetterSetter::createStructure):
+        * runtime/JSAPIValueWrapper.h:
+        (JSC::JSAPIValueWrapper::createStructure):
+        * runtime/JSActivation.cpp:
+        (JSC::JSActivation::visitChildren):
+        * runtime/JSActivation.h:
+        * runtime/JSArrayIterator.cpp:
+        (JSC::JSArrayIterator::visitChildren):
+        * runtime/JSArrayIterator.h:
+        * runtime/JSBoundFunction.cpp:
+        (JSC::JSBoundFunction::visitChildren):
+        * runtime/JSBoundFunction.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::setStructure):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::visitChildren):
+        * runtime/JSFunction.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSMap.h:
+        * runtime/JSMapIterator.cpp:
+        (JSC::JSMapIterator::visitChildren):
+        * runtime/JSMapIterator.h:
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::visitChildren):
+        * runtime/JSNameScope.h:
+        * runtime/JSPromise.cpp:
+        (JSC::JSPromise::visitChildren):
+        * runtime/JSPromise.h:
+        * runtime/JSPromiseDeferred.cpp:
+        (JSC::JSPromiseDeferred::visitChildren):
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPromiseReaction.cpp:
+        (JSC::JSPromiseReaction::visitChildren):
+        * runtime/JSPromiseReaction.h:
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::visitChildren):
+        * runtime/JSPropertyNameIterator.h:
+        * runtime/JSProxy.cpp:
+        (JSC::JSProxy::visitChildren):
+        * runtime/JSProxy.h:
+        * runtime/JSScope.cpp:
+        (JSC::JSScope::visitChildren):
+        * runtime/JSScope.h:
+        * runtime/JSSegmentedVariableObject.cpp:
+        (JSC::JSSegmentedVariableObject::visitChildren):
+        * runtime/JSSegmentedVariableObject.h:
+        * runtime/JSSet.h:
+        * runtime/JSSetIterator.cpp:
+        (JSC::JSSetIterator::visitChildren):
+        * runtime/JSSetIterator.h:
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::visitChildren):
+        * runtime/JSSymbolTableObject.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::overridesVisitChildren): Deleted.
+        * runtime/JSWeakMap.h:
+        * runtime/JSWithScope.cpp:
+        (JSC::JSWithScope::visitChildren):
+        * runtime/JSWithScope.h:
+        * runtime/JSWrapperObject.cpp:
+        (JSC::JSWrapperObject::visitChildren):
+        * runtime/JSWrapperObject.h:
+        * runtime/MapData.h:
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor::visitChildren):
+        * runtime/NativeErrorConstructor.h:
+        * runtime/PropertyMapHashTable.h:
+        * runtime/PropertyTable.cpp:
+        (JSC::PropertyTable::visitChildren):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::visitChildren):
+        * runtime/RegExpConstructor.h:
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::RegExpMatchesArray::visitChildren):
+        * runtime/RegExpMatchesArray.h:
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::visitChildren):
+        * runtime/RegExpObject.h:
+        * runtime/SparseArrayValueMap.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::visitChildren):
+        * runtime/StructureChain.cpp:
+        (JSC::StructureChain::visitChildren):
+        * runtime/StructureChain.h:
+        * runtime/StructureRareData.cpp:
+        (JSC::StructureRareData::visitChildren):
+        * runtime/StructureRareData.h:
+        * runtime/WeakMapData.h:
+
+2014-07-31  Mark Lam  <mark.lam@apple.com>
+
+        JSCell::classInfo() belongs in JSCellInlines.h.
+        <https://webkit.org/b/135475>
+
+        Reviewed by Mark Hahnenberg.
+
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::classInfo):
+        * runtime/JSDestructibleObject.h:
+        (JSC::JSCell::classInfo): Deleted.
+
+2014-07-31  Tanay C  <tanay.c@samsung.com>
+
+        Build warning in webkit/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=135414
+
+        Reviewed by Csaba Osztrogonác.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::putToScopeCommon):removed unused parameter from function definition
+
+2014-07-30  Filip Pizlo  <fpizlo@apple.com>
+
+        NewFunctionExpression and NewFunctionNoCheck should setHaveStructures(true)
+        https://bugs.webkit.org/show_bug.cgi?id=135430
+
+        Reviewed by Mark Hahnenberg.
+
+        We already handled this correctly after the ftlopt merge, but it's useful to have the test.
+
+        * tests/stress/new-function-expression-has-structures.js: Added.
+        (foo.f):
+        (foo.f.prototype.f):
+        (foo):
+
+2014-07-30  Andreas Kling  <akling@apple.com>
+
+        Speculative Windows build fix.
+
+        Try to dllimport the dllexported global object HashTable.
+
+        * jsc.cpp:
+        * testRegExp.cpp:
+
+2014-07-30  Andreas Kling  <akling@apple.com>
+
+        PropertyName's internal string is always atomic.
+        <https://webkit.org/b/135451>
+
+        Now that we've merged the JSC::Identifier and WTF::AtomicString tables,
+        we know that any string that's an Identifier is guaranteed to be atomic.
+
+        A PropertyName can be either an Identifier or a PrivateName, and the
+        private names are also guaranteed to be atomic internally.
+
+        Make PropertyName vend AtomicStringImpl* instead of StringImpl*.
+
+        Reviewed by Benjamin Poulain.
+
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (JSC::PropertyName::uid):
+        (JSC::PropertyName::publicName):
+
+2014-07-30  Andy Estes  <aestes@apple.com>
+
+        USE(CONTENT_FILTERING) should be ENABLE(CONTENT_FILTERING)
+        https://bugs.webkit.org/show_bug.cgi?id=135439
+
+        Reviewed by Tim Horton.
+
+        We now support two different platform content filters, and will soon support a mock content filter (as part of
+        webkit.org/b/128858). This makes content filtering a feature of WebKit, not just an adoption of a third-party
+        library. ENABLE() is the correct macro to use for such a feature.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-07-30  Andreas Kling  <akling@apple.com>
+
+        Static hash tables no longer need to be coupled with a VM.
+        <https://webkit.org/b/135421>
+
+        Now that the static hash tables are using char** instead of StringImpl**,
+        it's no longer necessary to make them per-VM.
+
+        This patch removes the hook in ClassInfo for providing your own static
+        hash table getter. Everyone now uses ClassInfo::staticPropHashTable.
+        Most of this patch is tweaking ClassInfo construction sites to pass one
+        less null pointer.
+
+        Also simplified Lookup.h to stop requiring ExecState/VM to access the
+        static hash tables.
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSAPIWrapperObject.mm:
+        * API/JSCallbackConstructor.cpp:
+        * API/JSCallbackFunction.cpp:
+        * API/JSCallbackObject.cpp:
+        * API/ObjCCallbackFunction.mm:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        * create_hash_table:
+        * debugger/DebuggerScope.cpp:
+        * inspector/JSInjectedScriptHost.cpp:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::arrayConstructorTable): Deleted.
+        (JSC::ExecState::arrayPrototypeTable): Deleted.
+        (JSC::ExecState::booleanPrototypeTable): Deleted.
+        (JSC::ExecState::dataViewTable): Deleted.
+        (JSC::ExecState::dateTable): Deleted.
+        (JSC::ExecState::dateConstructorTable): Deleted.
+        (JSC::ExecState::errorPrototypeTable): Deleted.
+        (JSC::ExecState::globalObjectTable): Deleted.
+        (JSC::ExecState::jsonTable): Deleted.
+        (JSC::ExecState::numberConstructorTable): Deleted.
+        (JSC::ExecState::numberPrototypeTable): Deleted.
+        (JSC::ExecState::objectConstructorTable): Deleted.
+        (JSC::ExecState::privateNamePrototypeTable): Deleted.
+        (JSC::ExecState::regExpTable): Deleted.
+        (JSC::ExecState::regExpConstructorTable): Deleted.
+        (JSC::ExecState::regExpPrototypeTable): Deleted.
+        (JSC::ExecState::stringConstructorTable): Deleted.
+        (JSC::ExecState::promisePrototypeTable): Deleted.
+        (JSC::ExecState::promiseConstructorTable): Deleted.
+        * jsc.cpp:
+        * parser/Lexer.h:
+        (JSC::Keywords::isKeyword):
+        (JSC::Keywords::getKeyword):
+        * runtime/Arguments.cpp:
+        * runtime/ArgumentsIteratorConstructor.cpp:
+        * runtime/ArgumentsIteratorPrototype.cpp:
+        * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+        * runtime/ArrayConstructor.cpp:
+        (JSC::ArrayConstructor::getOwnPropertySlot):
+        * runtime/ArrayIteratorConstructor.cpp:
+        * runtime/ArrayIteratorPrototype.cpp:
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::getOwnPropertySlot):
+        * runtime/BooleanConstructor.cpp:
+        * runtime/BooleanObject.cpp:
+        * runtime/BooleanPrototype.cpp:
+        (JSC::BooleanPrototype::getOwnPropertySlot):
+        * runtime/ClassInfo.h:
+        (JSC::ClassInfo::hasStaticProperties):
+        (JSC::ClassInfo::propHashTable): Deleted.
+        * runtime/ConsolePrototype.cpp:
+        * runtime/CustomGetterSetter.cpp:
+        * runtime/DateConstructor.cpp:
+        (JSC::DateConstructor::getOwnPropertySlot):
+        * runtime/DateInstance.cpp:
+        * runtime/DatePrototype.cpp:
+        (JSC::DatePrototype::getOwnPropertySlot):
+        * runtime/Error.cpp:
+        * runtime/ErrorConstructor.cpp:
+        * runtime/ErrorInstance.cpp:
+        * runtime/ErrorPrototype.cpp:
+        (JSC::ErrorPrototype::getOwnPropertySlot):
+        * runtime/ExceptionHelpers.cpp:
+        * runtime/Executable.cpp:
+        * runtime/FunctionConstructor.cpp:
+        * runtime/FunctionPrototype.cpp:
+        * runtime/GetterSetter.cpp:
+        * runtime/InternalFunction.cpp:
+        * runtime/JSAPIValueWrapper.cpp:
+        * runtime/JSActivation.cpp:
+        * runtime/JSArgumentsIterator.cpp:
+        * runtime/JSArray.cpp:
+        * runtime/JSArrayBuffer.cpp:
+        * runtime/JSArrayBufferConstructor.cpp:
+        * runtime/JSArrayBufferPrototype.cpp:
+        * runtime/JSArrayBufferView.cpp:
+        * runtime/JSArrayIterator.cpp:
+        * runtime/JSBoundFunction.cpp:
+        * runtime/JSConsole.cpp:
+        * runtime/JSDataView.cpp:
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::JSDataViewPrototype::getOwnPropertySlot):
+        * runtime/JSFunction.cpp:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::getOwnPropertySlot):
+        * runtime/JSMap.cpp:
+        * runtime/JSMapIterator.cpp:
+        * runtime/JSNameScope.cpp:
+        * runtime/JSNotAnObject.cpp:
+        * runtime/JSONObject.cpp:
+        (JSC::JSONObject::getOwnPropertySlot):
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::findPropertyHashEntry):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        * runtime/JSObject.h:
+        * runtime/JSPromise.cpp:
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructor::getOwnPropertySlot):
+        * runtime/JSPromiseDeferred.cpp:
+        * runtime/JSPromisePrototype.cpp:
+        (JSC::JSPromisePrototype::getOwnPropertySlot):
+        * runtime/JSPromiseReaction.cpp:
+        * runtime/JSPropertyNameIterator.cpp:
+        * runtime/JSProxy.cpp:
+        * runtime/JSSet.cpp:
+        * runtime/JSSetIterator.cpp:
+        * runtime/JSString.cpp:
+        * runtime/JSTypedArrayConstructors.cpp:
+        * runtime/JSTypedArrayPrototypes.cpp:
+        * runtime/JSTypedArrays.cpp:
+        * runtime/JSVariableObject.cpp:
+        * runtime/JSWeakMap.cpp:
+        * runtime/JSWithScope.cpp:
+        * runtime/Lookup.cpp:
+        (JSC::HashTable::createTable):
+        * runtime/Lookup.h:
+        (JSC::HashTable::initializeIfNeeded):
+        (JSC::HashTable::entry):
+        (JSC::HashTable::begin):
+        (JSC::HashTable::end):
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticFunctionSlot):
+        (JSC::getStaticValueSlot):
+        (JSC::lookupPut):
+        * runtime/MapConstructor.cpp:
+        * runtime/MapData.cpp:
+        * runtime/MapIteratorConstructor.cpp:
+        * runtime/MapIteratorPrototype.cpp:
+        * runtime/MapPrototype.cpp:
+        * runtime/MathObject.cpp:
+        * runtime/NameConstructor.cpp:
+        * runtime/NameInstance.cpp:
+        * runtime/NamePrototype.cpp:
+        (JSC::NamePrototype::getOwnPropertySlot):
+        * runtime/NativeErrorConstructor.cpp:
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::getOwnPropertySlot):
+        * runtime/NumberObject.cpp:
+        * runtime/NumberPrototype.cpp:
+        (JSC::NumberPrototype::getOwnPropertySlot):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::getOwnPropertySlot):
+        * runtime/ObjectPrototype.cpp:
+        * runtime/PropertyTable.cpp:
+        * runtime/RegExp.cpp:
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::getOwnPropertySlot):
+        * runtime/RegExpMatchesArray.cpp:
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::getOwnPropertySlot):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::RegExpPrototype::getOwnPropertySlot):
+        * runtime/SetConstructor.cpp:
+        * runtime/SetIteratorConstructor.cpp:
+        * runtime/SetIteratorPrototype.cpp:
+        * runtime/SetPrototype.cpp:
+        * runtime/SparseArrayValueMap.cpp:
+        * runtime/StrictEvalActivation.cpp:
+        * runtime/StringConstructor.cpp:
+        (JSC::StringConstructor::getOwnPropertySlot):
+        * runtime/StringObject.cpp:
+        * runtime/StringPrototype.cpp:
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::freezeTransition):
+        (JSC::ClassInfo::hasStaticSetterOrReadonlyProperties):
+        * runtime/StructureChain.cpp:
+        * runtime/StructureRareData.cpp:
+        * runtime/SymbolTable.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::~VM):
+        * runtime/VM.h:
+        * runtime/WeakMapConstructor.cpp:
+        * runtime/WeakMapData.cpp:
+        * runtime/WeakMapPrototype.cpp:
+        * testRegExp.cpp:
+
+2014-07-29  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Modify version numbering scheme to support 5-tuple versions
+        https://bugs.webkit.org/show_bug.cgi?id=135400
+        <rdar://problem/17849033>
+
+        Reviewed by David Kilzer.
+
+        * JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd: Use the
+        new version-stamp.pl script to version JavaScriptCore.dll.
+
+2014-07-29  Daniel Bates  <dabates@apple.com>
+
+        Use WTF::move() instead of std::move() to help ensure move semantics
+        https://bugs.webkit.org/show_bug.cgi?id=135351
+
+        Reviewed by Alexey Proskuryakov.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::GetByIdVariant):
+
+2014-07-28  Tamas Gergely  <tgergely.u-szeged@partner.samsung.com>
+
+        BuildFix: JavaScriptCore/bytecode/StructureSet.h:262:77: warning.
+        https://bugs.webkit.org/show_bug.cgi?id=135287
+
+        Reviewed by Darin Adler.
+
+        The set() method tries to use a part of the old value (the reservedFlag bit) which
+        was not defined when the constructor is called. Initialize m_pointer to 0 explicitely.
+
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::StructureSet):
+
+2014-07-28  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] JIT::assertStackPointerOffset() crashes on ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=135316
+
+        Reviewed by Geoffrey Garen.
+
+        JIT::assertStackPointerOffset() does a compare between an arbitrary register
+        and the stack pointer. This was not supported by the ARM64 assembler.
+
+        There are no variation that can take a stack pointer for Xd. There is one version of subs
+        that can take a stack pointer, but only for the Xn: the shift+extend one.
+        To solve the problem, I changed cmp to swap the registers if necessary, and I fixed
+        the implementation of sub.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::sub):
+        In the generic sub(reg, reg), I added assertions to catch the condition that cannot be generated
+        with either version of sub.
+
+        In sub(with shift), I remove the weird special case for SP. First, it was quite misleading because
+        the Rd case only works if "setflag == false". The other confusing part is going to addSubtractShiftedRegister()
+        gives you a reduce shift range, which could create subtle bug that only appear when SP is used.
+
+        Since I removed the weird case, I need to differentiate between the sub() that support SP, and the one that does
+        not elsewhere. That is why that branch has moved to the generic sub(reg, reg). Since at that point we know
+        the shift value must be zero, it is safe to call either variant.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branch64):
+        With the changes described above, we can now use SP for the left register. What do we do if the rightmost
+        register is SP?
+
+        For the case of JIT::assertStackPointerOffset(), the comparison is Equal so the order really does not matter,
+        we just switch the registers before generating the instruction.
+
+        For the generic case, just move the value of SP to a GPR before doing the CMP.
+
+2014-07-28  Brian J. Burg  <burg@cs.washington.edu>
+
+        Unreviewed build fix after r171682.
+
+        * replay/EncodedValue.h: Don't mark the inlined Vector<char> specialization
+        as an exported symbol.
+
+2014-07-28  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        REGRESSION: JSObjectSetPrototype() does not work on result of JSGetGlobalObject()
+        https://bugs.webkit.org/show_bug.cgi?id=135322
+
+        Reviewed by Oliver Hunt.
+
+        The prototype chain of the JSProxy object should match that of the JSGlobalObject. 
+
+        This is a separate but related issue with JSObjectSetPrototype which doesn't correctly 
+        account for JSProxies. I also audited the rest of the C API to check that we correctly 
+        handle JSProxies in all other situations where we expect a JSCallbackObject of some sort
+        and found some SPI calls (JSObject*PrivateProperty) that didn't behave correctly when 
+        passed a JSProxy.
+
+        I also added some new tests for these cases.
+
+        * API/JSObjectRef.cpp:
+        (JSObjectSetPrototype):
+        (JSObjectGetPrivateProperty):
+        (JSObjectSetPrivateProperty):
+        (JSObjectDeletePrivateProperty):
+        * API/JSWeakObjectMapRefPrivate.cpp:
+        * API/tests/CustomGlobalObjectClassTest.c:
+        (globalObjectSetPrototypeTest):
+        (globalObjectPrivatePropertyTest):
+        * API/tests/CustomGlobalObjectClassTest.h:
+        * API/tests/testapi.c:
+        (main):
+
+2014-07-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Make sure that we don't use non-speculative BooleanToNumber for a speculative Branch
+        https://bugs.webkit.org/show_bug.cgi?id=135350
+        <rdar://problem/17509889>
+
+        Reviewed by Mark Hahnenberg and Oliver Hunt.
+        
+        If we have an exiting node that uses a conversion node, then that exiting node
+        needs to have a Phantom after it for the the original node. But we can't do that
+        for Branch because https://bugs.webkit.org/show_bug.cgi?id=126778.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
+        * tests/stress/branch-check-int32-on-boolean-to-number-untyped.js: Added.
+        (foo):
+        (test):
+        * tests/stress/branch-check-number-on-boolean-to-number-untyped.js: Added.
+        (foo):
+        (test):
+
+2014-07-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JSContext Inspector: crash when using step-into
+        https://bugs.webkit.org/show_bug.cgi?id=135345
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::stepInto):
+        Null check m_listener since it may not be set.
+
+2014-07-28  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: auto-decoding of parameterized vector's elements is incorrect
+        https://bugs.webkit.org/show_bug.cgi?id=135343
+
+        Reviewed by Timothy Hatcher.
+
+        Fix an incorrect type argument in EncodingTraits<Vector<T>>::encodeValue
+        that was using the element's decoded type as the type parameter to
+        EncodedValue::append<T>. It should instead be the raw type T. This
+        causes problems when encoding Vector<RefPtr<T>>, as it later tries to
+        use encoding traits for RefPtr<T> rather than for T.
+
+        Fix incorrect generated encoding traits argument for vectors of
+        RefCounted objects. Updated test to cover this scenario.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.encoding_type_argument):
+        (VectorType.type_name):
+        (VectorType):
+        (VectorType.encoding_type_argument):
+        (Generator.generate_input_encode_implementation):
+        (Generator.generate_input_decode_implementation):
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.cpp:
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h:
+        * replay/scripts/tests/generate-input-with-vector-members.json: Updated.
+
+2014-07-28  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: incorrect serialization code generated for enum classes inside class scope
+        https://bugs.webkit.org/show_bug.cgi?id=135342
+
+        Reviewed by Timothy Hatcher.
+
+        If an enum class is defined inside of a class scope, then the enum class
+        cannot be forward-declared and the relevant header should be included.
+        Some generated code used incorrectly-scoped enum values in this situation.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Generator.generate_includes.declaration.is):
+        (Generator.generate_enum_trait_implementation.is):
+        (Generator.generate_enum_trait_implementation):
+
+        Tests:
+
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp: Rebaselined.
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h: Rebaselined.
+        * replay/scripts/tests/generate-enums-with-same-base-name.json: Add enum
+        class types to this test case.
+
+2014-07-28  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: vectors of characters should be base64-encoded
+        https://bugs.webkit.org/show_bug.cgi?id=135341
+
+        Reviewed by Timothy Hatcher.
+
+        Without this specialization, encode/decode methods try to create an
+        array of single characters in JSON, rather than treating the
+        vector as a binary blob.
+
+        * replay/EncodedValue.cpp:
+        (JSC::EncodingTraits<Vector<char>>::encodeValue): Added.
+        (JSC::EncodingTraits<Vector<char>>::decodeValue): Added.
+        * replay/EncodedValue.h:
+
+2014-07-28  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed build fix.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.proj: Switch from the 'Rebuild' target for MSBuild
+        builds to the 'Build' target to avoid a spurious 'clean' in between build steps.
+
+2014-07-27  Ryuan Choi  <ryuan.choi@samsung.com>
+
+        Unreviewed build fix on the EFL port
+
+        Build break because of -Werror=return-type
+
+        * bytecode/PutByIdVariant.cpp:
+        (JSC::PutByIdVariant::oldStructureForTransition):
+        * dfg/DFGValueStrength.h:
+        (JSC::DFG::merge):
+
+2014-07-27  Filip Pizlo  <fpizlo@apple.com>
+
+        [REGRESSION][ftlopt merge][32-bit] stress/prune-multi-put-by-offset-replace-or-transition-variant.js.dfg-eager hits an assertion in SpeculativeJIT::silentSavePlanForGPR
+        https://bugs.webkit.org/show_bug.cgi?id=135323
+
+        Reviewed by Oliver Hunt.
+        
+        SpeculativeJIT::silentSavePlanForGPR likes to believe that if a node is a constant,
+        then it's a constant that can be represented using that node's current DataFormat.
+        This doesn't work if the constant had been filled as a JSValue, and then one of the
+        fillSpeculateBlah() methods had speculated that it's of some type that the constant
+        isn't. Unless fillSpeculateBlah() specifically defends against this case, we'll have
+        a constant that claims to have a contradictory data format.
+        
+        This patch fixes such a bug in the 32-bit fillSpeculateCell(). The 64-bit
+        fillSpeculateCell() appears to not have this bug, but I added a similar defense
+        mechanism anyway just in case, since this is one of those mistakes that keeps
+        reappearing.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+
+2014-07-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r170090, r170092, r170129, r170141, r170161, r170215, r170275, r170375, r170376, r170382, r170383, r170399, r170436, r170489, r170490, r170556 from ftlopt.
+        
+        This fixes the previous mismerge and adds test coverage for the thing that went wrong.
+        
+        Additional changes listed here:
+
+        * jsc.cpp:
+        (functionHasCustomProperties): Expose a way of checking hasCustomProperties(), which the DOM relies on. The regression I previously introduced was because this didn't work right. Now we can test it!
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure): This was supposed to be setDidTransition(true); the last merge had it set to false.
+        * tests/stress/has-custom-properties.js: Added. This test failed with the mismerge.
+
+    2014-06-27  Michael Saboff  <msaboff@apple.com>
+    
+            Unreviewed build fix after r169795.
+    
+            Fixed ASSERT for 32 bit build.
+    
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+    
+    2014-06-24  Saam Barati  <sbarati@apple.com>
+    
+            Web Inspector: debugger should be able to show variable types
+            https://bugs.webkit.org/show_bug.cgi?id=133395
+    
+            Reviewed by Filip Pizlo.
+    
+            Increase the amount of type information the VM gathers when directed
+            to do so. This initial commit is working towards the goal of
+            capturing, and then showing (via the Web Inspector) type information for all
+            assignment and load operations. This patch doesn't have the feature fully 
+            implemented, but it ensures the VM has no performance regressions
+            unless the feature is specifically turned on.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            * bytecode/CodeBlock.h:
+            * bytecode/Instruction.h:
+            * bytecode/TypeLocation.h: Added.
+            (JSC::TypeLocation::TypeLocation):
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitMove):
+            (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+            (JSC::BytecodeGenerator::emitPutToScope):
+            (JSC::BytecodeGenerator::emitPutById):
+            (JSC::BytecodeGenerator::emitPutByVal):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity):
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::PostfixNode::emitResolve):
+            (JSC::PrefixNode::emitResolve):
+            (JSC::ReadModifyResolveNode::emitBytecode):
+            (JSC::AssignResolveNode::emitBytecode):
+            (JSC::ConstDeclNode::emitCodeSingle):
+            (JSC::ForInNode::emitBytecode):
+            * heap/Heap.cpp:
+            (JSC::Heap::collect):
+            * inspector/agents/InspectorRuntimeAgent.cpp:
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange):
+            * inspector/agents/InspectorRuntimeAgent.h:
+            * inspector/protocol/Runtime.json:
+            * jsc.cpp:
+            (GlobalObject::finishCreation):
+            (functionDumpTypesForAllVariables):
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            (JSC::LLInt::putToScopeCommon):
+            * llint/LLIntSlowPaths.h:
+            * llint/LowLevelInterpreter.asm:
+            * runtime/HighFidelityLog.cpp: Added.
+            (JSC::HighFidelityLog::initializeHighFidelityLog):
+            (JSC::HighFidelityLog::~HighFidelityLog):
+            (JSC::HighFidelityLog::recordTypeInformationForLocation):
+            (JSC::HighFidelityLog::processHighFidelityLog):
+            (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
+            * runtime/HighFidelityLog.h: Added.
+            (JSC::HighFidelityLog::HighFidelityLog):
+            * runtime/HighFidelityTypeProfiler.cpp: Added.
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::insertNewLocation):
+            (JSC::HighFidelityTypeProfiler::getLocationBasedHash):
+            * runtime/HighFidelityTypeProfiler.h: Added.
+            * runtime/Options.h:
+            * runtime/Structure.cpp:
+            (JSC::Structure::toStructureShape):
+            * runtime/Structure.h:
+            * runtime/SymbolTable.cpp:
+            (JSC::SymbolTable::SymbolTable):
+            (JSC::SymbolTable::cloneCapturedNames):
+            (JSC::SymbolTable::uniqueIDForVariable):
+            (JSC::SymbolTable::uniqueIDForRegister):
+            (JSC::SymbolTable::globalTypeSetForRegister):
+            (JSC::SymbolTable::globalTypeSetForVariable):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTable::add):
+            (JSC::SymbolTable::set):
+            * runtime/TypeSet.cpp: Added.
+            (JSC::TypeSet::TypeSet):
+            (JSC::TypeSet::getRuntimeTypeForValue):
+            (JSC::TypeSet::addTypeForValue):
+            (JSC::TypeSet::removeDuplicatesInStructureHistory):
+            (JSC::TypeSet::seenTypes):
+            (JSC::TypeSet::dumpSeenTypes):
+            (JSC::StructureShape::StructureShape):
+            (JSC::StructureShape::markAsFinal):
+            (JSC::StructureShape::addProperty):
+            (JSC::StructureShape::propertyHash):
+            (JSC::StructureShape::leastUpperBound):
+            (JSC::StructureShape::stringRepresentation):
+            * runtime/TypeSet.h: Added.
+            (JSC::StructureShape::create):
+            (JSC::TypeSet::create):
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            (JSC::VM::getTypesForVariableInRange):
+            (JSC::VM::updateHighFidelityTypeProfileState):
+            (JSC::VM::dumpHighFidelityProfilingTypes):
+            * runtime/VM.h:
+            (JSC::VM::isProfilingTypesWithHighFidelity):
+            (JSC::VM::highFidelityLog):
+            (JSC::VM::highFidelityTypeProfiler):
+            (JSC::VM::nextLocation):
+            (JSC::VM::getNextUniqueVariableID):
+    
+    2014-06-26  Mark Lam  <mark.lam@apple.com>
+    
+            Remove unused instantiation of the WithScope structure.
+            <https://webkit.org/b/134331>
+    
+            Reviewed by Oliver Hunt.
+    
+            The WithScope structure instance is the VM is unused, and is now removed.
+    
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Structure bit fields should have a consistent format
+            https://bugs.webkit.org/show_bug.cgi?id=134307
+    
+            Reviewed by Filip Pizlo.
+    
+            Currently we use C-style bit fields for a number of member variables in Structure to save space. 
+            This makes it difficult to load these fields in the JIT. We should instead use our own bitfield 
+            format to make it easy to load and test these variables in JIT code.
+    
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::putDirectNonIndexAccessor):
+            (JSC::JSObject::reifyStaticFunctionsForDelete):
+            * runtime/Structure.cpp:
+            (JSC::StructureTransitionTable::contains):
+            (JSC::StructureTransitionTable::get):
+            (JSC::StructureTransitionTable::add):
+            (JSC::Structure::Structure):
+            (JSC::Structure::materializePropertyMap):
+            (JSC::Structure::addPropertyTransition):
+            (JSC::Structure::despecifyFunctionTransition):
+            (JSC::Structure::toDictionaryTransition):
+            (JSC::Structure::freezeTransition):
+            (JSC::Structure::preventExtensionsTransition):
+            (JSC::Structure::takePropertyTableOrCloneIfPinned):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::flattenDictionaryStructure):
+            (JSC::Structure::addPropertyWithoutTransition):
+            (JSC::Structure::pin):
+            (JSC::Structure::allocateRareData):
+            (JSC::Structure::cloneRareDataFrom):
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::putSpecificValue):
+            (JSC::Structure::getPropertyNamesFromStructure):
+            (JSC::Structure::visitChildren):
+            (JSC::Structure::checkConsistency):
+            * runtime/Structure.h:
+            (JSC::Structure::isExtensible):
+            (JSC::Structure::isDictionary):
+            (JSC::Structure::isUncacheableDictionary):
+            (JSC::Structure::propertyAccessesAreCacheable):
+            (JSC::Structure::previousID):
+            (JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck):
+            (JSC::Structure::setContainsReadOnlyProperties):
+            (JSC::Structure::disableSpecificFunctionTracking):
+            (JSC::Structure::objectToStringValue):
+            (JSC::Structure::setObjectToStringValue):
+            (JSC::Structure::setPreviousID):
+            (JSC::Structure::clearPreviousID):
+            (JSC::Structure::previous):
+            (JSC::Structure::rareData):
+            (JSC::Structure::didTransition): Deleted.
+            (JSC::Structure::hasGetterSetterProperties): Deleted.
+            (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto): Deleted.
+            (JSC::Structure::setHasGetterSetterProperties): Deleted.
+            (JSC::Structure::hasNonEnumerableProperties): Deleted.
+            (JSC::Structure::staticFunctionsReified): Deleted.
+            (JSC::Structure::setStaticFunctionsReified): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::setEnumerationCache):
+            (JSC::Structure::enumerationCache):
+            (JSC::Structure::checkOffsetConsistency):
+    
+    2014-06-24  Mark Lam  <mark.lam@apple.com>
+    
+            [ftlopt] Renamed DebuggerActivation to DebuggerScope.
+            <https://webkit.org/b/134273>
+    
+            Reviewed by Michael Saboff.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * debugger/DebuggerActivation.cpp: Removed.
+            * debugger/DebuggerActivation.h: Removed.
+            * debugger/DebuggerScope.cpp: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.cpp.
+            (JSC::DebuggerScope::DebuggerScope):
+            (JSC::DebuggerScope::finishCreation):
+            (JSC::DebuggerScope::visitChildren):
+            (JSC::DebuggerScope::className):
+            (JSC::DebuggerScope::getOwnPropertySlot):
+            (JSC::DebuggerScope::put):
+            (JSC::DebuggerScope::deleteProperty):
+            (JSC::DebuggerScope::getOwnPropertyNames):
+            (JSC::DebuggerScope::defineOwnProperty):
+            (JSC::DebuggerActivation::DebuggerActivation): Deleted.
+            (JSC::DebuggerActivation::finishCreation): Deleted.
+            (JSC::DebuggerActivation::visitChildren): Deleted.
+            (JSC::DebuggerActivation::className): Deleted.
+            (JSC::DebuggerActivation::getOwnPropertySlot): Deleted.
+            (JSC::DebuggerActivation::put): Deleted.
+            (JSC::DebuggerActivation::deleteProperty): Deleted.
+            (JSC::DebuggerActivation::getOwnPropertyNames): Deleted.
+            (JSC::DebuggerActivation::defineOwnProperty): Deleted.
+            * debugger/DebuggerScope.h: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.h.
+            (JSC::DebuggerScope::create):
+            (JSC::DebuggerActivation::create): Deleted.
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] PutByIdFlush can also be converted to a PutByOffset so don't assert otherwise
+            https://bugs.webkit.org/show_bug.cgi?id=134265
+    
+            Reviewed by Geoffrey Garen.
+            
+            More assertion fallout from the PutById folding work.
+    
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToPutByOffset):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] GC should notify us if it resets to_this
+            https://bugs.webkit.org/show_bug.cgi?id=128231
+    
+            Reviewed by Geoffrey Garen.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/BytecodeList.json:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            * bytecode/Instruction.h:
+            * bytecode/ToThisStatus.cpp: Added.
+            (JSC::merge):
+            (WTF::printInternal):
+            * bytecode/ToThisStatus.h: Added.
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::BytecodeGenerator):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * llint/LowLevelInterpreter32_64.asm:
+            * llint/LowLevelInterpreter64.asm:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] StructureAbstractValue::onlyStructure() should return nullptr if isClobbered()
+            https://bugs.webkit.org/show_bug.cgi?id=134256
+    
+            Reviewed by Michael Saboff.
+            
+            This isn't testable right now (i.e. it's benign) but we should get it right anyway. The
+            point is to be able to precisely model what goes on in the snippets of code between a
+            side-effect and an InvalidationPoint.
+            
+            This patch also cleans up onlyStructure() by delegating more work to
+            StructureSet::onlyStructure().
+    
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::onlyStructure):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt][REGRESSION] PutById AI is introducing watchable structures without watching them
+            https://bugs.webkit.org/show_bug.cgi?id=134260
+    
+            Reviewed by Geoffrey Garen.
+            
+            This was causing loads of assertion failures in debug builds.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+    
+    2014-06-21  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Fold GetById/PutById to MultiGetByOffset/GetByOffset or MultiPutByOffset/PutByOffset, which implies handling non-singleton sets
+            https://bugs.webkit.org/show_bug.cgi?id=134090
+    
+            Reviewed by Oliver Hunt.
+            
+            This pretty much finishes off the work to eliminate the special-casing of singleton
+            structure sets by making it possible to fold GetById and PutById to various polymorphic
+            forms of the ByOffset nodes.
+            
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            (JSC::GetByIdStatus::computeFor):
+            * bytecode/GetByIdStatus.h:
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFor):
+            * bytecode/PutByIdStatus.h:
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::constantChecks):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addChecks):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToMultiGetByOffset):
+            (JSC::DFG::Node::convertToMultiPutByOffset):
+            * dfg/DFGSpeculativeJIT64.cpp: Also convert all release assertions to DFG assertions in this file, because I was hitting some of them while debugging.
+            (JSC::DFG::SpeculativeJIT::fillJSValue):
+            (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+            (JSC::DFG::SpeculativeJIT::emitCall):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Strict):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+            (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+            (JSC::DFG::SpeculativeJIT::emitBranch):
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::set):
+    
+    2014-06-19  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] StructureSet::onlyStructure() should return nullptr if it's not a singleton (instead of asserting)
+            https://bugs.webkit.org/show_bug.cgi?id=134077
+    
+            Reviewed by Sam Weinig.
+            
+            This makes StructureSet and StructureAbstractValue more consistent and fixes a debug assert
+            in the abstract interpreter.
+    
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::onlyStructure):
+    
+    2014-06-18  Filip Pizlo  <fpizlo@apple.com>
+    
+            DFG AI and constant folder should be able to precisely prune MultiGetByOffset/MultiPutByOffset even if the base structure abstract value is not a singleton
+            https://bugs.webkit.org/show_bug.cgi?id=133918
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This also adds pruning of PutStructure, since I basically had no choice but
+            to implement such logic within MultiPutByOffset.
+            
+            Also adds a bunch of PutById cache status dumping to bytecode dumping.
+    
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::structureSet):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::oldStructure):
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::filterArrayModes):
+            * bytecode/StructureSet.h:
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::changeStructure):
+            (JSC::DFG::AbstractValue::contains):
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::couldBeType):
+            (JSC::DFG::AbstractValue::isType):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::freezeStrong):
+            * dfg/DFGGraph.h:
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::operator=):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+            * tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+            * tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+    
+    2014-06-18  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Remove CompoundType and LeafType
+            https://bugs.webkit.org/show_bug.cgi?id=134037
+    
+            Reviewed by Filip Pizlo.
+    
+            We don't use them for anything. We'll replace them with a generic CellType type for all 
+            the objects that are JSCells, aren't JSObjects, and for which we generally don't care about 
+            their JSType at runtime.
+    
+            * llint/LLIntData.cpp:
+            (JSC::LLInt::Data::performAssertions):
+            * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+            (JSC::ArrayBufferNeuteringWatchpoint::createStructure):
+            * runtime/Executable.h:
+            (JSC::ExecutableBase::createStructure):
+            (JSC::NativeExecutable::createStructure):
+            * runtime/JSPromiseDeferred.h:
+            (JSC::JSPromiseDeferred::createStructure):
+            * runtime/JSPromiseReaction.h:
+            (JSC::JSPromiseReaction::createStructure):
+            * runtime/JSPropertyNameIterator.h:
+            (JSC::JSPropertyNameIterator::createStructure):
+            * runtime/JSType.h:
+            * runtime/JSTypeInfo.h:
+            (JSC::TypeInfo::TypeInfo):
+            * runtime/MapData.h:
+            (JSC::MapData::createStructure):
+            * runtime/PropertyMapHashTable.h:
+            (JSC::PropertyTable::createStructure):
+            * runtime/RegExp.h:
+            (JSC::RegExp::createStructure):
+            * runtime/SparseArrayValueMap.cpp:
+            (JSC::SparseArrayValueMap::createStructure):
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            * runtime/StructureChain.h:
+            (JSC::StructureChain::createStructure):
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::createStructure):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTable::createStructure):
+            * runtime/WeakMapData.h:
+            (JSC::WeakMapData::createStructure):
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] PutStructure and PhantomPutStructure shouldn't leave the world in a clobbered state
+            https://bugs.webkit.org/show_bug.cgi?id=134002
+    
+            Reviewed by Mark Hahnenberg.
+            
+            The effect of this bug was that if we had a PutStructure or PhantomPutStructure then any
+            JSConstants would be in a Clobbered state, so we wouldn't take advantage of our knowledge
+            of the structure if that structure was watchable.
+            
+            Also kill PhantomPutStructure.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasTransition):
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.cpp:
+            (JSC::DFG::StructureAbstractValue::observeTransition):
+            (JSC::DFG::StructureAbstractValue::observeTransitions):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            * dfg/DFGWatchableStructureWatchingPhase.cpp:
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure): Deleted.
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG put_by_id should inline accesses with a slightly polymorphic base
+            https://bugs.webkit.org/show_bug.cgi?id=133964
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::appendVariant):
+            (JSC::PutByIdStatus::computeForStubInfo):
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::oldStructureForTransition):
+            (JSC::PutByIdVariant::writesStructures):
+            (JSC::PutByIdVariant::reallocatesStorage):
+            (JSC::PutByIdVariant::attemptToMerge):
+            (JSC::PutByIdVariant::attemptToMergeTransitionWithReplace):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::replace):
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::structure):
+            (JSC::PutByIdVariant::oldStructure):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGNode.cpp:
+            (JSC::DFG::MultiPutByOffsetData::writesStructures):
+            (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
+            * ftl/FTLAbbreviations.h:
+            (JSC::FTL::getLinkage):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):
+    
+2014-07-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out r171641-r171644. It broke some tests; will investigate and
+        reland later.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::printPutByIdCacheStatus): Deleted.
+        * bytecode/CodeBlock.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::dumpInContext):
+        * bytecode/GetByIdVariant.h:
+        (JSC::GetByIdVariant::structureSet):
+        * bytecode/Instruction.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::appendVariant):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.h:
+        * bytecode/PutByIdVariant.cpp:
+        (JSC::PutByIdVariant::dumpInContext):
+        (JSC::PutByIdVariant::oldStructureForTransition): Deleted.
+        (JSC::PutByIdVariant::writesStructures): Deleted.
+        (JSC::PutByIdVariant::reallocatesStorage): Deleted.
+        (JSC::PutByIdVariant::attemptToMerge): Deleted.
+        (JSC::PutByIdVariant::attemptToMergeTransitionWithReplace): Deleted.
+        * bytecode/PutByIdVariant.h:
+        (JSC::PutByIdVariant::PutByIdVariant):
+        (JSC::PutByIdVariant::replace):
+        (JSC::PutByIdVariant::transition):
+        (JSC::PutByIdVariant::structure):
+        (JSC::PutByIdVariant::oldStructure):
+        (JSC::PutByIdVariant::newStructure):
+        (JSC::PutByIdVariant::constantChecks):
+        * bytecode/StructureSet.cpp:
+        (JSC::StructureSet::filter): Deleted.
+        (JSC::StructureSet::filterArrayModes): Deleted.
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::onlyStructure):
+        * bytecode/ToThisStatus.cpp: Removed.
+        * bytecode/ToThisStatus.h: Removed.
+        * bytecode/TypeLocation.h: Removed.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::emitPutById):
+        (JSC::BytecodeGenerator::emitPutByVal):
+        (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::ConstDeclNode::emitCodeSingle):
+        (JSC::ForInNode::emitBytecode):
+        * debugger/DebuggerActivation.cpp: Added.
+        (JSC::DebuggerActivation::DebuggerActivation):
+        (JSC::DebuggerActivation::finishCreation):
+        (JSC::DebuggerActivation::visitChildren):
+        (JSC::DebuggerActivation::className):
+        (JSC::DebuggerActivation::getOwnPropertySlot):
+        (JSC::DebuggerActivation::put):
+        (JSC::DebuggerActivation::deleteProperty):
+        (JSC::DebuggerActivation::getOwnPropertyNames):
+        (JSC::DebuggerActivation::defineOwnProperty):
+        * debugger/DebuggerActivation.h: Added.
+        (JSC::DebuggerActivation::create):
+        (JSC::DebuggerActivation::createStructure):
+        * debugger/DebuggerScope.cpp: Removed.
+        * debugger/DebuggerScope.h: Removed.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::changeStructure): Deleted.
+        (JSC::DFG::AbstractValue::contains): Deleted.
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::couldBeType):
+        (JSC::DFG::AbstractValue::isType):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        (JSC::DFG::ConstantFoldingPhase::addBaseCheck): Deleted.
+        (JSC::DFG::ConstantFoldingPhase::addChecks): Deleted.
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::visitChildren):
+        (JSC::DFG::Graph::freezeStrong):
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::MultiPutByOffsetData::writesStructures):
+        (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPutByOffset):
+        (JSC::DFG::Node::hasTransition):
+        (JSC::DFG::Node::convertToMultiGetByOffset): Deleted.
+        (JSC::DFG::Node::convertToMultiPutByOffset): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Strict):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::observeTransition):
+        (JSC::DFG::StructureAbstractValue::observeTransitions):
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::onlyStructure):
+        (JSC::DFG::StructureAbstractValue::operator=): Deleted.
+        (JSC::DFG::StructureAbstractValue::set): Deleted.
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGWatchableStructureWatchingPhase.cpp:
+        (JSC::DFG::WatchableStructureWatchingPhase::run):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::getLinkage): Deleted.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange): Deleted.
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionDumpTypesForAllVariables): Deleted.
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::putToScopeCommon): Deleted.
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+        (JSC::ArrayBufferNeuteringWatchpoint::createStructure):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/Executable.h:
+        (JSC::ExecutableBase::createStructure):
+        (JSC::NativeExecutable::createStructure):
+        * runtime/HighFidelityLog.cpp: Removed.
+        * runtime/HighFidelityLog.h: Removed.
+        * runtime/HighFidelityTypeProfiler.cpp: Removed.
+        * runtime/HighFidelityTypeProfiler.h: Removed.
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectCustomAccessor):
+        (JSC::JSObject::putDirectNonIndexAccessor):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        * runtime/JSPromiseDeferred.h:
+        (JSC::JSPromiseDeferred::createStructure):
+        * runtime/JSPromiseReaction.h:
+        (JSC::JSPromiseReaction::createStructure):
+        * runtime/JSPropertyNameIterator.h:
+        (JSC::JSPropertyNameIterator::createStructure):
+        * runtime/JSType.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::TypeInfo):
+        * runtime/MapData.h:
+        (JSC::MapData::createStructure):
+        * runtime/Options.h:
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::createStructure):
+        * runtime/RegExp.h:
+        (JSC::RegExp::createStructure):
+        * runtime/SparseArrayValueMap.cpp:
+        (JSC::SparseArrayValueMap::createStructure):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::contains):
+        (JSC::StructureTransitionTable::get):
+        (JSC::StructureTransitionTable::add):
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::freezeTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::takePropertyTableOrCloneIfPinned):
+        (JSC::Structure::nonPropertyTransition):
+        (JSC::Structure::flattenDictionaryStructure):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::pin):
+        (JSC::Structure::allocateRareData):
+        (JSC::Structure::cloneRareDataFrom):
+        (JSC::Structure::getConcurrently):
+        (JSC::Structure::putSpecificValue):
+        (JSC::Structure::getPropertyNamesFromStructure):
+        (JSC::Structure::visitChildren):
+        (JSC::Structure::checkConsistency):
+        (JSC::Structure::toStructureShape): Deleted.
+        * runtime/Structure.h:
+        (JSC::Structure::isExtensible):
+        (JSC::Structure::didTransition):
+        (JSC::Structure::isDictionary):
+        (JSC::Structure::isUncacheableDictionary):
+        (JSC::Structure::hasBeenFlattenedBefore):
+        (JSC::Structure::propertyAccessesAreCacheable):
+        (JSC::Structure::previousID):
+        (JSC::Structure::hasGetterSetterProperties):
+        (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto):
+        (JSC::Structure::setHasGetterSetterProperties):
+        (JSC::Structure::hasCustomGetterSetterProperties):
+        (JSC::Structure::setHasCustomGetterSetterProperties):
+        (JSC::Structure::setContainsReadOnlyProperties):
+        (JSC::Structure::hasNonEnumerableProperties):
+        (JSC::Structure::disableSpecificFunctionTracking):
+        (JSC::Structure::objectToStringValue):
+        (JSC::Structure::setObjectToStringValue):
+        (JSC::Structure::staticFunctionsReified):
+        (JSC::Structure::setStaticFunctionsReified):
+        (JSC::Structure::transitionWatchpointSet):
+        (JSC::Structure::setPreviousID):
+        (JSC::Structure::clearPreviousID):
+        (JSC::Structure::previous):
+        (JSC::Structure::rareData):
+        (JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck): Deleted.
+        (JSC::Structure::setHasCustomGetterSetterPropertiesWithProtoCheck): Deleted.
+        * runtime/StructureChain.h:
+        (JSC::StructureChain::createStructure):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        (JSC::Structure::enumerationCache):
+        (JSC::Structure::checkOffsetConsistency):
+        * runtime/StructureRareData.cpp:
+        (JSC::StructureRareData::createStructure):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::cloneCapturedNames):
+        (JSC::SymbolTable::uniqueIDForVariable): Deleted.
+        (JSC::SymbolTable::uniqueIDForRegister): Deleted.
+        (JSC::SymbolTable::globalTypeSetForRegister): Deleted.
+        (JSC::SymbolTable::globalTypeSetForVariable): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::createStructure):
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        * runtime/TypeSet.cpp: Removed.
+        * runtime/TypeSet.h: Removed.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::getTypesForVariableInRange): Deleted.
+        (JSC::VM::updateHighFidelityTypeProfileState): Deleted.
+        (JSC::VM::dumpHighFidelityProfilingTypes): Deleted.
+        * runtime/VM.h:
+        (JSC::VM::isProfilingTypesWithHighFidelity): Deleted.
+        (JSC::VM::highFidelityLog): Deleted.
+        (JSC::VM::highFidelityTypeProfiler): Deleted.
+        (JSC::VM::nextLocation): Deleted.
+        (JSC::VM::getNextUniqueVariableID): Deleted.
+        * runtime/WeakMapData.h:
+        (JSC::WeakMapData::createStructure):
+        * tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js: Removed.
+        * tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js: Removed.
+        * tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js: Removed.
+
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Attempt to fix non-Xcode platforms.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix cloop.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::dumpChain):
+        (JSC::CodeBlock::printPutByIdCacheStatus):
+        * bytecode/StructureSet.cpp:
+        * bytecode/StructureSet.h:
+
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r170090, r170092, r170129, r170141, r170161, r170215, r170275, r170375, r170376, r170382, r170383, r170399, r170436, r170489, r170490, r170556 from ftlopt.
+
+    2014-06-27  Michael Saboff  <msaboff@apple.com>
+    
+            Unreviewed build fix after r169795.
+    
+            Fixed ASSERT for 32 bit build.
+    
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+    
+    2014-06-24  Saam Barati  <sbarati@apple.com>
+    
+            Web Inspector: debugger should be able to show variable types
+            https://bugs.webkit.org/show_bug.cgi?id=133395
+    
+            Reviewed by Filip Pizlo.
+    
+            Increase the amount of type information the VM gathers when directed
+            to do so. This initial commit is working towards the goal of
+            capturing, and then showing (via the Web Inspector) type information for all
+            assignment and load operations. This patch doesn't have the feature fully 
+            implemented, but it ensures the VM has no performance regressions
+            unless the feature is specifically turned on.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/BytecodeList.json:
+            * bytecode/BytecodeUseDef.h:
+            (JSC::computeUsesForBytecodeOffset):
+            (JSC::computeDefsForBytecodeOffset):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            (JSC::CodeBlock::CodeBlock):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            * bytecode/CodeBlock.h:
+            * bytecode/Instruction.h:
+            * bytecode/TypeLocation.h: Added.
+            (JSC::TypeLocation::TypeLocation):
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::emitMove):
+            (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+            (JSC::BytecodeGenerator::emitPutToScope):
+            (JSC::BytecodeGenerator::emitPutById):
+            (JSC::BytecodeGenerator::emitPutByVal):
+            * bytecompiler/BytecodeGenerator.h:
+            (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity):
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::PostfixNode::emitResolve):
+            (JSC::PrefixNode::emitResolve):
+            (JSC::ReadModifyResolveNode::emitBytecode):
+            (JSC::AssignResolveNode::emitBytecode):
+            (JSC::ConstDeclNode::emitCodeSingle):
+            (JSC::ForInNode::emitBytecode):
+            * heap/Heap.cpp:
+            (JSC::Heap::collect):
+            * inspector/agents/InspectorRuntimeAgent.cpp:
+            (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange):
+            * inspector/agents/InspectorRuntimeAgent.h:
+            * inspector/protocol/Runtime.json:
+            * jsc.cpp:
+            (GlobalObject::finishCreation):
+            (functionDumpTypesForAllVariables):
+            * llint/LLIntSlowPaths.cpp:
+            (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+            (JSC::LLInt::putToScopeCommon):
+            * llint/LLIntSlowPaths.h:
+            * llint/LowLevelInterpreter.asm:
+            * runtime/HighFidelityLog.cpp: Added.
+            (JSC::HighFidelityLog::initializeHighFidelityLog):
+            (JSC::HighFidelityLog::~HighFidelityLog):
+            (JSC::HighFidelityLog::recordTypeInformationForLocation):
+            (JSC::HighFidelityLog::processHighFidelityLog):
+            (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
+            * runtime/HighFidelityLog.h: Added.
+            (JSC::HighFidelityLog::HighFidelityLog):
+            * runtime/HighFidelityTypeProfiler.cpp: Added.
+            (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange):
+            (JSC::HighFidelityTypeProfiler::insertNewLocation):
+            (JSC::HighFidelityTypeProfiler::getLocationBasedHash):
+            * runtime/HighFidelityTypeProfiler.h: Added.
+            * runtime/Options.h:
+            * runtime/Structure.cpp:
+            (JSC::Structure::toStructureShape):
+            * runtime/Structure.h:
+            * runtime/SymbolTable.cpp:
+            (JSC::SymbolTable::SymbolTable):
+            (JSC::SymbolTable::cloneCapturedNames):
+            (JSC::SymbolTable::uniqueIDForVariable):
+            (JSC::SymbolTable::uniqueIDForRegister):
+            (JSC::SymbolTable::globalTypeSetForRegister):
+            (JSC::SymbolTable::globalTypeSetForVariable):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTable::add):
+            (JSC::SymbolTable::set):
+            * runtime/TypeSet.cpp: Added.
+            (JSC::TypeSet::TypeSet):
+            (JSC::TypeSet::getRuntimeTypeForValue):
+            (JSC::TypeSet::addTypeForValue):
+            (JSC::TypeSet::removeDuplicatesInStructureHistory):
+            (JSC::TypeSet::seenTypes):
+            (JSC::TypeSet::dumpSeenTypes):
+            (JSC::StructureShape::StructureShape):
+            (JSC::StructureShape::markAsFinal):
+            (JSC::StructureShape::addProperty):
+            (JSC::StructureShape::propertyHash):
+            (JSC::StructureShape::leastUpperBound):
+            (JSC::StructureShape::stringRepresentation):
+            * runtime/TypeSet.h: Added.
+            (JSC::StructureShape::create):
+            (JSC::TypeSet::create):
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            (JSC::VM::getTypesForVariableInRange):
+            (JSC::VM::updateHighFidelityTypeProfileState):
+            (JSC::VM::dumpHighFidelityProfilingTypes):
+            * runtime/VM.h:
+            (JSC::VM::isProfilingTypesWithHighFidelity):
+            (JSC::VM::highFidelityLog):
+            (JSC::VM::highFidelityTypeProfiler):
+            (JSC::VM::nextLocation):
+            (JSC::VM::getNextUniqueVariableID):
+    
+    2014-06-26  Mark Lam  <mark.lam@apple.com>
+    
+            Remove unused instantiation of the WithScope structure.
+            <https://webkit.org/b/134331>
+    
+            Reviewed by Oliver Hunt.
+    
+            The WithScope structure instance is the VM is unused, and is now removed.
+    
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Structure bit fields should have a consistent format
+            https://bugs.webkit.org/show_bug.cgi?id=134307
+    
+            Reviewed by Filip Pizlo.
+    
+            Currently we use C-style bit fields for a number of member variables in Structure to save space. 
+            This makes it difficult to load these fields in the JIT. We should instead use our own bitfield 
+            format to make it easy to load and test these variables in JIT code.
+    
+            * runtime/JSObject.cpp:
+            (JSC::JSObject::putDirectNonIndexAccessor):
+            (JSC::JSObject::reifyStaticFunctionsForDelete):
+            * runtime/Structure.cpp:
+            (JSC::StructureTransitionTable::contains):
+            (JSC::StructureTransitionTable::get):
+            (JSC::StructureTransitionTable::add):
+            (JSC::Structure::Structure):
+            (JSC::Structure::materializePropertyMap):
+            (JSC::Structure::addPropertyTransition):
+            (JSC::Structure::despecifyFunctionTransition):
+            (JSC::Structure::toDictionaryTransition):
+            (JSC::Structure::freezeTransition):
+            (JSC::Structure::preventExtensionsTransition):
+            (JSC::Structure::takePropertyTableOrCloneIfPinned):
+            (JSC::Structure::nonPropertyTransition):
+            (JSC::Structure::flattenDictionaryStructure):
+            (JSC::Structure::addPropertyWithoutTransition):
+            (JSC::Structure::pin):
+            (JSC::Structure::allocateRareData):
+            (JSC::Structure::cloneRareDataFrom):
+            (JSC::Structure::getConcurrently):
+            (JSC::Structure::putSpecificValue):
+            (JSC::Structure::getPropertyNamesFromStructure):
+            (JSC::Structure::visitChildren):
+            (JSC::Structure::checkConsistency):
+            * runtime/Structure.h:
+            (JSC::Structure::isExtensible):
+            (JSC::Structure::isDictionary):
+            (JSC::Structure::isUncacheableDictionary):
+            (JSC::Structure::propertyAccessesAreCacheable):
+            (JSC::Structure::previousID):
+            (JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck):
+            (JSC::Structure::setContainsReadOnlyProperties):
+            (JSC::Structure::disableSpecificFunctionTracking):
+            (JSC::Structure::objectToStringValue):
+            (JSC::Structure::setObjectToStringValue):
+            (JSC::Structure::setPreviousID):
+            (JSC::Structure::clearPreviousID):
+            (JSC::Structure::previous):
+            (JSC::Structure::rareData):
+            (JSC::Structure::didTransition): Deleted.
+            (JSC::Structure::hasGetterSetterProperties): Deleted.
+            (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto): Deleted.
+            (JSC::Structure::setHasGetterSetterProperties): Deleted.
+            (JSC::Structure::hasNonEnumerableProperties): Deleted.
+            (JSC::Structure::staticFunctionsReified): Deleted.
+            (JSC::Structure::setStaticFunctionsReified): Deleted.
+            * runtime/StructureInlines.h:
+            (JSC::Structure::setEnumerationCache):
+            (JSC::Structure::enumerationCache):
+            (JSC::Structure::checkOffsetConsistency):
+    
+    2014-06-24  Mark Lam  <mark.lam@apple.com>
+    
+            [ftlopt] Renamed DebuggerActivation to DebuggerScope.
+            <https://webkit.org/b/134273>
+    
+            Reviewed by Michael Saboff.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * debugger/DebuggerActivation.cpp: Removed.
+            * debugger/DebuggerActivation.h: Removed.
+            * debugger/DebuggerScope.cpp: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.cpp.
+            (JSC::DebuggerScope::DebuggerScope):
+            (JSC::DebuggerScope::finishCreation):
+            (JSC::DebuggerScope::visitChildren):
+            (JSC::DebuggerScope::className):
+            (JSC::DebuggerScope::getOwnPropertySlot):
+            (JSC::DebuggerScope::put):
+            (JSC::DebuggerScope::deleteProperty):
+            (JSC::DebuggerScope::getOwnPropertyNames):
+            (JSC::DebuggerScope::defineOwnProperty):
+            (JSC::DebuggerActivation::DebuggerActivation): Deleted.
+            (JSC::DebuggerActivation::finishCreation): Deleted.
+            (JSC::DebuggerActivation::visitChildren): Deleted.
+            (JSC::DebuggerActivation::className): Deleted.
+            (JSC::DebuggerActivation::getOwnPropertySlot): Deleted.
+            (JSC::DebuggerActivation::put): Deleted.
+            (JSC::DebuggerActivation::deleteProperty): Deleted.
+            (JSC::DebuggerActivation::getOwnPropertyNames): Deleted.
+            (JSC::DebuggerActivation::defineOwnProperty): Deleted.
+            * debugger/DebuggerScope.h: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.h.
+            (JSC::DebuggerScope::create):
+            (JSC::DebuggerActivation::create): Deleted.
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] PutByIdFlush can also be converted to a PutByOffset so don't assert otherwise
+            https://bugs.webkit.org/show_bug.cgi?id=134265
+    
+            Reviewed by Geoffrey Garen.
+            
+            More assertion fallout from the PutById folding work.
+    
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToPutByOffset):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] GC should notify us if it resets to_this
+            https://bugs.webkit.org/show_bug.cgi?id=128231
+    
+            Reviewed by Geoffrey Garen.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/BytecodeList.json:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::dumpBytecode):
+            (JSC::CodeBlock::finalizeUnconditionally):
+            * bytecode/Instruction.h:
+            * bytecode/ToThisStatus.cpp: Added.
+            (JSC::merge):
+            (WTF::printInternal):
+            * bytecode/ToThisStatus.h: Added.
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::BytecodeGenerator::BytecodeGenerator):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * llint/LowLevelInterpreter32_64.asm:
+            * llint/LowLevelInterpreter64.asm:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] StructureAbstractValue::onlyStructure() should return nullptr if isClobbered()
+            https://bugs.webkit.org/show_bug.cgi?id=134256
+    
+            Reviewed by Michael Saboff.
+            
+            This isn't testable right now (i.e. it's benign) but we should get it right anyway. The
+            point is to be able to precisely model what goes on in the snippets of code between a
+            side-effect and an InvalidationPoint.
+            
+            This patch also cleans up onlyStructure() by delegating more work to
+            StructureSet::onlyStructure().
+    
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::onlyStructure):
+    
+    2014-06-24  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt][REGRESSION] PutById AI is introducing watchable structures without watching them
+            https://bugs.webkit.org/show_bug.cgi?id=134260
+    
+            Reviewed by Geoffrey Garen.
+            
+            This was causing loads of assertion failures in debug builds.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+    
+    2014-06-21  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Fold GetById/PutById to MultiGetByOffset/GetByOffset or MultiPutByOffset/PutByOffset, which implies handling non-singleton sets
+            https://bugs.webkit.org/show_bug.cgi?id=134090
+    
+            Reviewed by Oliver Hunt.
+            
+            This pretty much finishes off the work to eliminate the special-casing of singleton
+            structure sets by making it possible to fold GetById and PutById to various polymorphic
+            forms of the ByOffset nodes.
+            
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            (JSC::GetByIdStatus::computeFor):
+            * bytecode/GetByIdStatus.h:
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFor):
+            * bytecode/PutByIdStatus.h:
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::constantChecks):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addChecks):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToMultiGetByOffset):
+            (JSC::DFG::Node::convertToMultiPutByOffset):
+            * dfg/DFGSpeculativeJIT64.cpp: Also convert all release assertions to DFG assertions in this file, because I was hitting some of them while debugging.
+            (JSC::DFG::SpeculativeJIT::fillJSValue):
+            (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+            (JSC::DFG::SpeculativeJIT::emitCall):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Strict):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+            (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+            (JSC::DFG::SpeculativeJIT::emitBranch):
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::set):
+    
+    2014-06-19  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] StructureSet::onlyStructure() should return nullptr if it's not a singleton (instead of asserting)
+            https://bugs.webkit.org/show_bug.cgi?id=134077
+    
+            Reviewed by Sam Weinig.
+            
+            This makes StructureSet and StructureAbstractValue more consistent and fixes a debug assert
+            in the abstract interpreter.
+    
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::onlyStructure):
+    
+    2014-06-18  Filip Pizlo  <fpizlo@apple.com>
+    
+            DFG AI and constant folder should be able to precisely prune MultiGetByOffset/MultiPutByOffset even if the base structure abstract value is not a singleton
+            https://bugs.webkit.org/show_bug.cgi?id=133918
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This also adds pruning of PutStructure, since I basically had no choice but
+            to implement such logic within MultiPutByOffset.
+            
+            Also adds a bunch of PutById cache status dumping to bytecode dumping.
+    
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::structureSet):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::oldStructure):
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::filterArrayModes):
+            * bytecode/StructureSet.h:
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::changeStructure):
+            (JSC::DFG::AbstractValue::contains):
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::couldBeType):
+            (JSC::DFG::AbstractValue::isType):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::freezeStrong):
+            * dfg/DFGGraph.h:
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::operator=):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+            * tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+            * tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js: Added.
+            (foo):
+            (fu):
+            (bar):
+            (baz):
+            (.bar):
+            (.baz):
+    
+    2014-06-18  Mark Hahnenberg  <mhahnenberg@apple.com>
+    
+            Remove CompoundType and LeafType
+            https://bugs.webkit.org/show_bug.cgi?id=134037
+    
+            Reviewed by Filip Pizlo.
+    
+            We don't use them for anything. We'll replace them with a generic CellType type for all 
+            the objects that are JSCells, aren't JSObjects, and for which we generally don't care about 
+            their JSType at runtime.
+    
+            * llint/LLIntData.cpp:
+            (JSC::LLInt::Data::performAssertions):
+            * runtime/ArrayBufferNeuteringWatchpoint.cpp:
+            (JSC::ArrayBufferNeuteringWatchpoint::createStructure):
+            * runtime/Executable.h:
+            (JSC::ExecutableBase::createStructure):
+            (JSC::NativeExecutable::createStructure):
+            * runtime/JSPromiseDeferred.h:
+            (JSC::JSPromiseDeferred::createStructure):
+            * runtime/JSPromiseReaction.h:
+            (JSC::JSPromiseReaction::createStructure):
+            * runtime/JSPropertyNameIterator.h:
+            (JSC::JSPropertyNameIterator::createStructure):
+            * runtime/JSType.h:
+            * runtime/JSTypeInfo.h:
+            (JSC::TypeInfo::TypeInfo):
+            * runtime/MapData.h:
+            (JSC::MapData::createStructure):
+            * runtime/PropertyMapHashTable.h:
+            (JSC::PropertyTable::createStructure):
+            * runtime/RegExp.h:
+            (JSC::RegExp::createStructure):
+            * runtime/SparseArrayValueMap.cpp:
+            (JSC::SparseArrayValueMap::createStructure):
+            * runtime/Structure.cpp:
+            (JSC::Structure::Structure):
+            * runtime/StructureChain.h:
+            (JSC::StructureChain::createStructure):
+            * runtime/StructureRareData.cpp:
+            (JSC::StructureRareData::createStructure):
+            * runtime/SymbolTable.h:
+            (JSC::SymbolTable::createStructure):
+            * runtime/WeakMapData.h:
+            (JSC::WeakMapData::createStructure):
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] PutStructure and PhantomPutStructure shouldn't leave the world in a clobbered state
+            https://bugs.webkit.org/show_bug.cgi?id=134002
+    
+            Reviewed by Mark Hahnenberg.
+            
+            The effect of this bug was that if we had a PutStructure or PhantomPutStructure then any
+            JSConstants would be in a Clobbered state, so we wouldn't take advantage of our knowledge
+            of the structure if that structure was watchable.
+            
+            Also kill PhantomPutStructure.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasTransition):
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.cpp:
+            (JSC::DFG::StructureAbstractValue::observeTransition):
+            (JSC::DFG::StructureAbstractValue::observeTransitions):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            * dfg/DFGWatchableStructureWatchingPhase.cpp:
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure): Deleted.
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG put_by_id should inline accesses with a slightly polymorphic base
+            https://bugs.webkit.org/show_bug.cgi?id=133964
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::appendVariant):
+            (JSC::PutByIdStatus::computeForStubInfo):
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::oldStructureForTransition):
+            (JSC::PutByIdVariant::writesStructures):
+            (JSC::PutByIdVariant::reallocatesStorage):
+            (JSC::PutByIdVariant::attemptToMerge):
+            (JSC::PutByIdVariant::attemptToMergeTransitionWithReplace):
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::PutByIdVariant):
+            (JSC::PutByIdVariant::replace):
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::structure):
+            (JSC::PutByIdVariant::oldStructure):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::visitChildren):
+            * dfg/DFGNode.cpp:
+            (JSC::DFG::MultiPutByOffsetData::writesStructures):
+            (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
+            * ftl/FTLAbbreviations.h:
+            (JSC::FTL::getLinkage):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):
+    
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Add an option to disable native call inlining. Disable it for now to see how it
+        affects the bots.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleCall):
+        * runtime/Options.h:
+
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix cloop.
+
+        * dfg/DFGMayExit.cpp:
+
+2014-07-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r169795, r169819, r169864, r169902, r169949, r169950, r170016, r170017, r170060, r170064 from ftlopt.
+
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Fold constant Phis
+            https://bugs.webkit.org/show_bug.cgi?id=133967
+    
+            Reviewed by Mark Hahnenberg.
+            
+            It's surprising but we didn't really do this before. Or, rather, we only did it
+            incidentally when we would likely crash if it ever happened.
+            
+            Making this work required cleaning up the validater a bit, so I did that too. I also added
+            mayExit() validation for nodes that didn't have origin.forExit (i.e. nodes that end up in
+            the Phi header of basic blocks). But this required beefing up mayExit() a bit.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGAdjacencyList.h:
+            (JSC::DFG::AdjacencyList::isEmpty):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::run):
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
+            * dfg/DFGInPlaceAbstractState.h:
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::run):
+            (JSC::DFG::LICMPhase::attemptHoist):
+            * dfg/DFGMayExit.cpp:
+            (JSC::DFG::mayExit):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            (JSC::DFG::Validate::validateSSA):
+    
+    2014-06-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Get rid of NodeDoesNotExit and also get rid of StoreEliminationPhase
+            https://bugs.webkit.org/show_bug.cgi?id=133985
+    
+            Reviewed by Michael Saboff and Mark Hahnenberg.
+            
+            Store elimination phase has never been very profitable, and now that LLVM can do dead
+            store elimination for us, this phase is just completely pointless.
+            
+            This phase is also the primary user of NodeDoesNotExit, which is a flag that the CFA
+            computes. It computes it poorly and we often get bugs in it. It's also a lot of code to
+            maintain.
+            
+            This patch does introduce a new mayExit() calculator that is independent of the CFA and
+            should be enough for most of the previous NodeDoesNotExit users. Currently it's only used
+            for assertions in the DFG backend, but we could use it if we ever brought back any of the
+            other optimizations that previously relied upon NodeDoesNotExit.
+            
+            This is performance-neutral, except for SunSpider, where it's a speed-up.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::filterEdgeByUse):
+            (JSC::DFG::AbstractInterpreter::filterByType):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::startExecuting):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::CSEPhase):
+            (JSC::DFG::CSEPhase::invalidationPointElimination):
+            (JSC::DFG::CSEPhase::setLocalStoreElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::performBlockCSE):
+            (JSC::DFG::performCSE):
+            (JSC::DFG::CSEPhase::globalVarStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::scopedVarStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::putStructureStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::putByOffsetStoreElimination): Deleted.
+            (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
+            (JSC::DFG::performStoreElimination): Deleted.
+            * dfg/DFGCSEPhase.h:
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::resetExitStates): Deleted.
+            * dfg/DFGGraph.h:
+            * dfg/DFGMayExit.cpp: Added.
+            (JSC::DFG::mayExit):
+            * dfg/DFGMayExit.h: Added.
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::mergeFlags):
+            (JSC::DFG::Node::filterFlags):
+            (JSC::DFG::Node::setCanExit): Deleted.
+            (JSC::DFG::Node::canExit): Deleted.
+            * dfg/DFGNodeFlags.cpp:
+            (JSC::DFG::dumpNodeFlags):
+            * dfg/DFGNodeFlags.h:
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+            (JSC::DFG::SpeculativeJIT::bail):
+            (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+    
+    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Remove the DFG optimization fixpoint and remove some obvious reasons why we previously benefited from it
+            https://bugs.webkit.org/show_bug.cgi?id=133931
+    
+            Reviewed by Oliver Hunt.
+    
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Trigger constant-folding for GetMyArgumentByVal (which means turning it into GetLocalUnlinked) and correct the handling of Upsilon so we don't fold them away.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants): Implement constant-folding for GetMyArgumentByVal.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl): Remove the fixpoint.
+    
+    2014-06-15  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG OSR entry should have a crystal-clear story for when it's safe to enter at a block with a set of values
+            https://bugs.webkit.org/show_bug.cgi?id=133935
+    
+            Reviewed by Oliver Hunt.
+    
+            * bytecode/Operands.h:
+            (JSC::Operands::Operands):
+            (JSC::Operands::ensureLocals):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::filter): Now we can compute intersections of abstract values!
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::makeFullTop): Completeness.
+            (JSC::DFG::AbstractValue::bytecodeTop): Completeness.
+            (JSC::DFG::AbstractValue::fullTop): Completeness. We end up using this one.
+            * dfg/DFGBasicBlock.cpp:
+            (JSC::DFG::BasicBlock::BasicBlock):
+            (JSC::DFG::BasicBlock::ensureLocals):
+            * dfg/DFGBasicBlock.h: Remember the intersection of all things ever proven.
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::run): Compute the intersection.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants): No need for the weirdo merge check since this fixes the root of the problem.
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::dumpBlockHeader): Better dumping.
+            (JSC::DFG::Graph::dump): Better dumping.
+            * dfg/DFGJITCompiler.h:
+            (JSC::DFG::JITCompiler::noticeOSREntry): Use the intersected abstract value.
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Assert if the intersected state indicates the block shouldn't execute.
+    
+    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] A DFG inlined ById access variant should not speak of a chain, but only of what structures to test the base for, whether to use a constant as an alternate base for the actual access, and what structures to check on what additional cell constants
+            https://bugs.webkit.org/show_bug.cgi?id=133821
+    
+            Reviewed by Mark Hahnenberg.
+            
+            This allows us to efficiently cache accesses that differ only in the prototypes on the path
+            from the base to the prototype that has the field.
+            
+            It also simplifies a bunch of code - IntendedStructureChain is now just an intermediate
+            data structure.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/ConstantStructureCheck.cpp: Added.
+            (JSC::ConstantStructureCheck::dumpInContext):
+            (JSC::ConstantStructureCheck::dump):
+            (JSC::structureFor):
+            (JSC::areCompatible):
+            (JSC::mergeInto):
+            * bytecode/ConstantStructureCheck.h: Added.
+            (JSC::ConstantStructureCheck::ConstantStructureCheck):
+            (JSC::ConstantStructureCheck::operator!):
+            (JSC::ConstantStructureCheck::constant):
+            (JSC::ConstantStructureCheck::structure):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::operator=):
+            (JSC::GetByIdVariant::attemptToMerge):
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::constantChecks):
+            (JSC::GetByIdVariant::alternateBase):
+            (JSC::GetByIdVariant::GetByIdVariant): Deleted.
+            (JSC::GetByIdVariant::chain): Deleted.
+            * bytecode/PutByIdVariant.cpp:
+            (JSC::PutByIdVariant::dumpInContext):
+            * bytecode/PutByIdVariant.h:
+            (JSC::PutByIdVariant::transition):
+            (JSC::PutByIdVariant::constantChecks):
+            (JSC::PutByIdVariant::structureChain): Deleted.
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck): Deleted.
+            (JSC::DFG::ByteCodeParser::structureChainIsStillValid): Deleted.
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks): Deleted.
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDesiredStructureChains.cpp: Removed.
+            * dfg/DFGDesiredStructureChains.h: Removed.
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::watchpoints):
+            (JSC::DFG::Graph::chains): Deleted.
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::isStillValid):
+            (JSC::DFG::Plan::checkLivenessAndVisitChildren):
+            (JSC::DFG::Plan::cancel):
+            * dfg/DFGPlan.h:
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::gatherChecks):
+            * runtime/IntendedStructureChain.h:
+            (JSC::IntendedStructureChain::at):
+            (JSC::IntendedStructureChain::operator[]):
+    
+    2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Constant folding and strength reduction should work in SSA
+            https://bugs.webkit.org/show_bug.cgi?id=133839
+    
+            Reviewed by Oliver Hunt.
+    
+            * dfg/DFGAtTailAbstractState.cpp:
+            (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
+            (JSC::DFG::AtTailAbstractState::forNode):
+            * dfg/DFGAtTailAbstractState.h:
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::convertToConstant):
+            * dfg/DFGIntegerCheckCombiningPhase.cpp:
+            (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend): Fix an unrelated regression that this uncovered.
+            * dfg/DFGLICMPhase.cpp:
+            (JSC::DFG::LICMPhase::LICMPhase):
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+    
+    2014-06-11  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG get_by_id should inline chain accesses with a slightly polymorphic base
+            https://bugs.webkit.org/show_bug.cgi?id=133751
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::appendVariant):
+            (JSC::GetByIdStatus::computeForStubInfo):
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::attemptToMerge):
+            * bytecode/GetByIdVariant.h:
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::computeFor):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            * runtime/IntendedStructureChain.cpp:
+            (JSC::IntendedStructureChain::IntendedStructureChain):
+            (JSC::IntendedStructureChain::isStillValid):
+            (JSC::IntendedStructureChain::isNormalized):
+            (JSC::IntendedStructureChain::terminalPrototype):
+            (JSC::IntendedStructureChain::operator==):
+            (JSC::IntendedStructureChain::visitChildren):
+            (JSC::IntendedStructureChain::dumpInContext):
+            (JSC::IntendedStructureChain::chain): Deleted.
+            * runtime/IntendedStructureChain.h:
+            (JSC::IntendedStructureChain::prototype):
+            (JSC::IntendedStructureChain::operator!=):
+            (JSC::IntendedStructureChain::head): Deleted.
+    
+    2014-06-11  Matthew Mirman  <mmirman@apple.com>
+    
+           Readded native calling to the FTL and Split the DFG nodes 
+           Call and Construct into NativeCall and NativeConstruct 
+           to better represent their semantics.
+           https://bugs.webkit.org/show_bug.cgi?id=133660
+    
+           Reviewed by Filip Pizlo.
+    
+           * dfg/DFGAbstractInterpreterInlines.h:
+           (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 
+           Added NativeCall and NativeConstruct case
+           * dfg/DFGByteCodeParser.cpp:
+           (JSC::DFG::ByteCodeParser::addCall): added NativeCall case. 
+           (JSC::DFG::ByteCodeParser::handleCall): 
+           set to return NativeCall or NativeConstruct instead of Call or Construct
+           in the presence of a native function.
+           * dfg/DFGClobberize.h:
+           (JSC::DFG::clobberize): added NativeCall and NativeConstruct case.
+           * dfg/DFGDoesGC.cpp:
+           (JSC::DFG::doesGC): added NativeCall and NativeConstruct case.
+           * dfg/DFGFixupPhase.cpp:
+           (JSC::DFG::FixupPhase::fixupNode): added NativeCall and NativeConstruct case.
+           * dfg/DFGNode.h:
+           (JSC::DFG::Node::hasHeapPrediction): added NativeCall and NativeConstruct case.
+           (JSC::DFG::Node::canBeKnownFunction): changed to NativeCall and NativeConstruct.
+           (JSC::DFG::Node::hasKnownFunction): changed to NativeCall and NativeConstruct.
+           * dfg/DFGNodeType.h: added NativeCall and NativeConstruct.
+           * dfg/DFGPredictionPropagationPhase.cpp:
+           (JSC::DFG::PredictionPropagationPhase::propagate): added NativeCall and NativeConstruct case.
+           * dfg/DFGSafeToExecute.h:
+           (JSC::DFG::safeToExecute): added NativeCall and NativeConstruct case.
+           * dfg/DFGSpeculativeJIT32_64.cpp:
+           (JSC::DFG::SpeculativeJIT::emitCall): ditto
+           (JSC::DFG::SpeculativeJIT::compile): ditto
+           * dfg/DFGSpeculativeJIT64.cpp:
+           (JSC::DFG::SpeculativeJIT::emitCall): ditto
+           (JSC::DFG::SpeculativeJIT::compile): ditto
+           * ftl/FTLCapabilities.cpp:
+           (JSC::FTL::canCompile): ditto
+           * ftl/FTLLowerDFGToLLVM.cpp:  
+           (JSC::FTL::LowerDFGToLLVM::lower): ditto
+           (JSC::FTL::LowerDFGToLLVM::compileNode): ditto.
+           (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct): Added.
+           (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct): removed NativeCall and NativeConstruct functionality.
+           (JSC::FTL::LowerDFGToLLVM::didOverflowStack): added NativeCall and NativeConstruct case.
+           * runtime/JSCJSValue.h: added JS_EXPORT_PRIVATE to toInteger as it is apparently needed.
+           
+    2014-06-11  Matthew Mirman  <mmirman@apple.com>
+    
+            Ensured Native Calls and Construct and associated checks 
+            are only emitted during ftl mode.
+            https://bugs.webkit.org/show_bug.cgi?id=133718
+            
+            Reviewed by Filip Pizlo.
+            
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall): Added check for ftl mode 
+            before attaching the native function to Call or Construct.
+            
+    2014-06-10  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG should use its own notion of JSValue, which we should call FrozenValue, that will carry around a copy of its structure
+            https://bugs.webkit.org/show_bug.cgi?id=133426
+    
+            Reviewed by Geoffrey Garen.
+            
+            The impetus for this was to provide some sense and reason to race conditions arising from
+            cell constants having their structure changed on the main thread - this is harmess because
+            we defend against it, but when it goes wrong, it can be difficult to reproduce because it
+            requires a race. Giving the DFG the ability to "freeze" a cell's structure fixes this.
+            
+            But this patch goes quite a bit further, and completely rationalizes how the DFG reasons
+            about constants. It no longer relies on the CodeBlock constant pool at all, which allows
+            for a more object-oriented approach: for example a Node that has a constant can tell you
+            what constant it has without needing a CodeBlock.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CallLinkStatus.cpp:
+            (JSC::CallLinkStatus::computeExitSiteData):
+            * bytecode/ExitKind.cpp:
+            (JSC::exitKindToString):
+            (JSC::exitKindIsCountable):
+            * bytecode/ExitKind.h:
+            (JSC::isWatchpoint): Deleted.
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::hasExitSite):
+            * bytecode/PutByIdStatus.cpp:
+            (JSC::PutByIdStatus::hasExitSite):
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::filterByValue):
+            (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+            (JSC::DFG::AbstractInterpreter::setConstant):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::filterByValue):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::setOSREntryValue):
+            (JSC::DFG::AbstractValue::set):
+            (JSC::DFG::AbstractValue::filterByValue):
+            (JSC::DFG::AbstractValue::setMostSpecific): Deleted.
+            * dfg/DFGAbstractValue.h:
+            * dfg/DFGArgumentsSimplificationPhase.cpp:
+            (JSC::DFG::ArgumentsSimplificationPhase::run):
+            * dfg/DFGBackwardsPropagationPhase.cpp:
+            (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
+            (JSC::DFG::BackwardsPropagationPhase::isNotPosZero):
+            (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
+            (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::ByteCodeParser):
+            (JSC::DFG::ByteCodeParser::getDirect):
+            (JSC::DFG::ByteCodeParser::get):
+            (JSC::DFG::ByteCodeParser::getLocal):
+            (JSC::DFG::ByteCodeParser::setLocal):
+            (JSC::DFG::ByteCodeParser::setArgument):
+            (JSC::DFG::ByteCodeParser::jsConstant):
+            (JSC::DFG::ByteCodeParser::weakJSConstant):
+            (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
+            (JSC::DFG::ByteCodeParser::handleCall):
+            (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+            (JSC::DFG::ByteCodeParser::handleInlining):
+            (JSC::DFG::ByteCodeParser::handleMinMax):
+            (JSC::DFG::ByteCodeParser::handleIntrinsic):
+            (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::prepareToParseBlock):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            (JSC::DFG::ByteCodeParser::buildOperandMapsIfNecessary):
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+            (JSC::DFG::ByteCodeParser::parseCodeBlock):
+            (JSC::DFG::ByteCodeParser::addConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::getJSConstantForValue): Deleted.
+            (JSC::DFG::ByteCodeParser::getJSConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::isJSConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::isInt32Constant): Deleted.
+            (JSC::DFG::ByteCodeParser::valueOfJSConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::valueOfInt32Constant): Deleted.
+            (JSC::DFG::ByteCodeParser::constantUndefined): Deleted.
+            (JSC::DFG::ByteCodeParser::constantNull): Deleted.
+            (JSC::DFG::ByteCodeParser::one): Deleted.
+            (JSC::DFG::ByteCodeParser::constantNaN): Deleted.
+            (JSC::DFG::ByteCodeParser::cellConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::inferredConstant): Deleted.
+            (JSC::DFG::ByteCodeParser::ConstantRecord::ConstantRecord): Deleted.
+            * dfg/DFGCFGSimplificationPhase.cpp:
+            (JSC::DFG::CFGSimplificationPhase::run):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::constantCSE):
+            (JSC::DFG::CSEPhase::checkFunctionElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::weakConstantCSE): Deleted.
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGCommon.h:
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            (JSC::DFG::FixupPhase::fixupMakeRope):
+            (JSC::DFG::FixupPhase::truncateConstantToInt32):
+            (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteLength):
+            (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+            * dfg/DFGFrozenValue.cpp: Added.
+            (JSC::DFG::FrozenValue::emptySingleton):
+            (JSC::DFG::FrozenValue::dumpInContext):
+            (JSC::DFG::FrozenValue::dump):
+            * dfg/DFGFrozenValue.h: Added.
+            (JSC::DFG::FrozenValue::FrozenValue):
+            (JSC::DFG::FrozenValue::operator!):
+            (JSC::DFG::FrozenValue::value):
+            (JSC::DFG::FrozenValue::structure):
+            (JSC::DFG::FrozenValue::strengthenTo):
+            (JSC::DFG::FrozenValue::strength):
+            (JSC::DFG::FrozenValue::freeze):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::Graph):
+            (JSC::DFG::Graph::dump):
+            (JSC::DFG::Graph::tryGetActivation):
+            (JSC::DFG::Graph::tryGetFoldableView):
+            (JSC::DFG::Graph::registerFrozenValues):
+            (JSC::DFG::Graph::visitChildren):
+            (JSC::DFG::Graph::freezeFragile):
+            (JSC::DFG::Graph::freeze):
+            (JSC::DFG::Graph::freezeStrong):
+            (JSC::DFG::Graph::convertToConstant):
+            (JSC::DFG::Graph::convertToStrongConstant):
+            (JSC::DFG::Graph::assertIsWatched):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
+            (JSC::DFG::Graph::convertToConstant): Deleted.
+            (JSC::DFG::Graph::constantRegisterForConstant): Deleted.
+            (JSC::DFG::Graph::getJSConstantSpeculation): Deleted.
+            (JSC::DFG::Graph::isConstant): Deleted.
+            (JSC::DFG::Graph::isJSConstant): Deleted.
+            (JSC::DFG::Graph::isInt32Constant): Deleted.
+            (JSC::DFG::Graph::isDoubleConstant): Deleted.
+            (JSC::DFG::Graph::isNumberConstant): Deleted.
+            (JSC::DFG::Graph::isBooleanConstant): Deleted.
+            (JSC::DFG::Graph::isCellConstant): Deleted.
+            (JSC::DFG::Graph::isFunctionConstant): Deleted.
+            (JSC::DFG::Graph::isInternalFunctionConstant): Deleted.
+            (JSC::DFG::Graph::valueOfJSConstant): Deleted.
+            (JSC::DFG::Graph::valueOfInt32Constant): Deleted.
+            (JSC::DFG::Graph::valueOfNumberConstant): Deleted.
+            (JSC::DFG::Graph::valueOfBooleanConstant): Deleted.
+            (JSC::DFG::Graph::valueOfFunctionConstant): Deleted.
+            (JSC::DFG::Graph::mulImmediateShouldSpeculateInt32): Deleted.
+            * dfg/DFGInPlaceAbstractState.cpp:
+            (JSC::DFG::InPlaceAbstractState::initialize):
+            * dfg/DFGInsertionSet.h:
+            (JSC::DFG::InsertionSet::insertConstant):
+            (JSC::DFG::InsertionSet::insertConstantForUse):
+            * dfg/DFGIntegerCheckCombiningPhase.cpp:
+            (JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend):
+            * dfg/DFGJITCompiler.cpp:
+            (JSC::DFG::JITCompiler::link):
+            * dfg/DFGLazyJSValue.cpp:
+            (JSC::DFG::LazyJSValue::getValue):
+            (JSC::DFG::LazyJSValue::strictEqual):
+            (JSC::DFG::LazyJSValue::dumpInContext):
+            * dfg/DFGLazyJSValue.h:
+            (JSC::DFG::LazyJSValue::LazyJSValue):
+            (JSC::DFG::LazyJSValue::tryGetValue):
+            (JSC::DFG::LazyJSValue::value):
+            (JSC::DFG::LazyJSValue::switchLookupValue):
+            * dfg/DFGMinifiedNode.cpp:
+            (JSC::DFG::MinifiedNode::fromNode):
+            * dfg/DFGMinifiedNode.h:
+            (JSC::DFG::belongsInMinifiedGraph):
+            (JSC::DFG::MinifiedNode::hasConstant):
+            (JSC::DFG::MinifiedNode::constant):
+            (JSC::DFG::MinifiedNode::hasConstantNumber): Deleted.
+            (JSC::DFG::MinifiedNode::constantNumber): Deleted.
+            (JSC::DFG::MinifiedNode::hasWeakConstant): Deleted.
+            (JSC::DFG::MinifiedNode::weakConstant): Deleted.
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasConstant):
+            (JSC::DFG::Node::constant):
+            (JSC::DFG::Node::convertToConstant):
+            (JSC::DFG::Node::asJSValue):
+            (JSC::DFG::Node::isInt32Constant):
+            (JSC::DFG::Node::asInt32):
+            (JSC::DFG::Node::asUInt32):
+            (JSC::DFG::Node::isDoubleConstant):
+            (JSC::DFG::Node::isNumberConstant):
+            (JSC::DFG::Node::asNumber):
+            (JSC::DFG::Node::isMachineIntConstant):
+            (JSC::DFG::Node::asMachineInt):
+            (JSC::DFG::Node::isBooleanConstant):
+            (JSC::DFG::Node::asBoolean):
+            (JSC::DFG::Node::isCellConstant):
+            (JSC::DFG::Node::asCell):
+            (JSC::DFG::Node::dynamicCastConstant):
+            (JSC::DFG::Node::function):
+            (JSC::DFG::Node::isWeakConstant): Deleted.
+            (JSC::DFG::Node::constantNumber): Deleted.
+            (JSC::DFG::Node::convertToWeakConstant): Deleted.
+            (JSC::DFG::Node::weakConstant): Deleted.
+            (JSC::DFG::Node::valueOfJSConstant): Deleted.
+            * dfg/DFGNodeType.h:
+            * dfg/DFGOSRExitCompiler.cpp:
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+            (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
+            (JSC::DFG::SpeculativeJIT::silentFill):
+            (JSC::DFG::SpeculativeJIT::compileIn):
+            (JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
+            (JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
+            (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+            (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+            (JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
+            (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+            (JSC::DFG::SpeculativeJIT::compileAdd):
+            (JSC::DFG::SpeculativeJIT::compileArithSub):
+            (JSC::DFG::SpeculativeJIT::compileArithMod):
+            * dfg/DFGSpeculativeJIT.h:
+            (JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
+            (JSC::DFG::SpeculativeJIT::initConstantInfo):
+            (JSC::DFG::SpeculativeJIT::isConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isJSConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isInt32Constant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isDoubleConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isNumberConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isBooleanConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isFunctionConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::valueOfInt32Constant): Deleted.
+            (JSC::DFG::SpeculativeJIT::valueOfNumberConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::addressOfDoubleConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::valueOfJSConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::valueOfBooleanConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::valueOfFunctionConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isNullConstant): Deleted.
+            (JSC::DFG::SpeculativeJIT::isInteger): Deleted.
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::fillJSValue):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::fillJSValue):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+            (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStrengthReductionPhase.cpp:
+            (JSC::DFG::StrengthReductionPhase::handleNode):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            * dfg/DFGValueStrength.cpp: Added.
+            (WTF::printInternal):
+            * dfg/DFGValueStrength.h: Added.
+            (JSC::DFG::merge):
+            * dfg/DFGVariableEventStream.cpp:
+            (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
+            (JSC::DFG::VariableEventStream::reconstruct):
+            * dfg/DFGVariableEventStream.h:
+            * dfg/DFGWatchableStructureWatchingPhase.cpp:
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            (JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
+            * dfg/DFGWatchpointCollectionPhase.cpp:
+            (JSC::DFG::WatchpointCollectionPhase::handle):
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLLink.cpp:
+            (JSC::FTL::link):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
+            (JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
+            (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+            (JSC::FTL::LowerDFGToLLVM::compileCheckFunction):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
+            (JSC::FTL::LowerDFGToLLVM::lowInt32):
+            (JSC::FTL::LowerDFGToLLVM::lowCell):
+            (JSC::FTL::LowerDFGToLLVM::lowBoolean):
+            (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+            (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+            (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant): Deleted.
+            * ftl/FTLOSRExitCompiler.cpp:
+            (JSC::FTL::compileStub):
+            * runtime/JSCJSValue.cpp:
+            (JSC::JSValue::dumpInContext):
+            (JSC::JSValue::dumpInContextAssumingStructure):
+            * runtime/JSCJSValue.h:
+    
+2014-07-24  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Correct build order in JavaScriptCore.submit.sln
+        https://bugs.webkit.org/show_bug.cgi?id=135282
+        <rdar://problem/17805592>
+
+        Unreviewed build fix.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: Correct build order
+        such that LLIntDesiredOffset is built prior to the rest of JSC.
+
+2014-07-24  Mark Lam  <mark.lam@apple.com>
+
+        JSWrapperMap's jsWrapperForObject() needs to keep weak prototype and constructors from being GCed.
+        <https://webkit.org/b/135258>
+
+        Reviewed by Mark Hahnenberg.
+
+        Where needed, we cache the prototype object pointer in a stack local var.
+        This allows it to be scanned by the GC, and hence be kept alive until
+        we use it.  The constructor object will in turn be kept alive by the
+        prototype object.
+
+        Also added some comments to warn against future code additions that could
+        regress this issue.
+
+        * API/JSWrapperMap.mm:
+        (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]):
+        (-[JSObjCClassInfo reallocateConstructorAndOrPrototype]):
+        (-[JSObjCClassInfo wrapperForObject:]):
+        (-[JSObjCClassInfo constructor]):
+
+2014-07-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JSLock release should only modify the AtomicStringTable if it modified in acquire
+        https://bugs.webkit.org/show_bug.cgi?id=135143
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::JSLock):
+        Initialize the member variable to nullptr.
+
+        (JSC::JSLock::willDestroyVM):
+        Update style to use nullptr instead of 0.
+
+        (JSC::JSLock::willReleaseLock):
+        We should only reset the thread data's atomic string table if
+        didAcquireLock changed it. m_entryAtomicStringTable will have
+        been set by didAcquireLock if it changed, or nullptr if it didn't.
+        This way we are sure we are balanced, regardless of m_vm changes.
+
+2014-07-24  Peyton Randolph  <prandolph@apple.com>
+
+        Rename feature flag for long-press gesture on Mac.                                                                   
+        https://bugs.webkit.org/show_bug.cgi?id=135259                                                                 
+
+        Reviewed by Beth Dakin.
+
+        * Configurations/FeatureDefines.xcconfig:
+        Rename LINK_LONG_PRESS to MAC_LONG_PRESS.
+
+2014-07-24  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r171527.
+        https://bugs.webkit.org/show_bug.cgi?id=135265
+
+        Breaks JSC API tests (Requested by mlam on #webkit).
+
+        Reverted changeset:
+
+        "JSWrapperMap's jsWrapperForObject() needs to defer GC."
+        https://bugs.webkit.org/show_bug.cgi?id=135258
+        http://trac.webkit.org/changeset/171527
+
+2014-07-24  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Creating a JSGlobalObject with a custom JSClassRef results in a JSProxy with the wrong prototype
+        https://bugs.webkit.org/show_bug.cgi?id=135250
+
+        Reviewed by Geoffrey Garen.
+
+        JSGlobalObject::resetPrototype (which is called from JSGlobalContextCreateInGroup) doesn't change its 
+        JSProxy's prototype as well. This results in a JSProxy where no properties in the original prototype 
+        chain (as created from the JSClassRef hierarchy) are accessible. Changing resetPrototype to also change
+        the JSProxy's prototype fixes the issue.
+
+        * API/JSValueRef.cpp:
+        (JSValueIsObjectOfClass): Also fixed a bug where a JSProxy for a JSGlobalObject with a custom JSClassRef
+        would claim it wasn't of the specified class, even if the target was of the specified class.
+        * API/tests/CustomGlobalObjectClassTest.c: Added.
+        (jsDoSomething):
+        (customGlobalObjectClassTest):
+        * API/tests/CustomGlobalObjectClassTest.h: Added.
+        * API/tests/testapi.c:
+        (assertTrue):
+        (main):
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::resetPrototype):
+
+2014-07-24  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: don't encode/decode primitive types that lack explicit sizes
+        https://bugs.webkit.org/show_bug.cgi?id=133430
+
+        Reviewed by Anders Carlsson.
+
+        Don't support encode/decode of unsigned long, since its size is compiler-dependent.
+
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::convertTo<unsigned long>):
+        (JSC::unsigned long>::encodeValue): Deleted.
+        * replay/EncodedValue.h:
+
+2014-07-24  Mark Lam  <mark.lam@apple.com>
+
+        JSWrapperMap's jsWrapperForObject() needs to defer GC.
+        <https://webkit.org/b/135258>
+
+        Reviewed by Oliver Hunt.
+
+        In the process of creating a JS wrapper, jsWrapperForObject() will create
+        the prototype and constructor of the corresponding ObjC class, as well as
+        for classes in its inheritance chain.  These prototypes and constructors
+        are stored in Weak references in the JSObjCClassInfo objects.  During all
+        the allocation that is being done to create all the prototypes and
+        constructors as well as the wrapper objects, a GC may occur thereby
+        collecting one or more of these newly created prototype and constructor
+        objects.
+
+        One example of where this problem can manifest is in wrapperForObject()
+        which is called from jsWrapperForObject().  In wrapperFoObject(), we do
+        the following steps:
+
+        1. reallocateConstructorAndOrPrototype() which creates the prototype
+           object and store it in JSObjCClassInfo's m_prototype which is a Weak
+           ref.
+        2. makeWrapper() to create the wrapper object, which may trigger a GC.
+           GC will collect the prototype object and nullify the corresponding
+           JSObjCClassInfo's m_prototype Weak ref.
+        3. call JSObjectSetPrototype() to set the JSObjCClassInfo's m_prototype
+           in the newly created wrapper.  This results in the wrapper getting a
+           jsNull as a prototype instead of the expected prototype object.
+
+        To ensure that the prototype and constructor objects are retained until
+        they can be referenced properly from the wrapper object,
+        jsWrapperForObject() should defer GC until it's done with its work.
+
+        * API/JSWrapperMap.mm:
+        (-[JSWrapperMap jsWrapperForObject:]):
+
+2014-07-23  Brent Fulgham  <bfulgham@apple.com>
+
+        Build fix after r171482.
+
+        Rubberstamped by Joe Pecoraro.
+
+        * runtime/Identifier.h: Make header declarations match
+        implementation file.
+
+2014-07-23  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Use NO_RETURN_DUE_TO_CRASH on Windows
+        https://bugs.webkit.org/show_bug.cgi?id=135199
+
+        Reviewed by Mark Lam.
+
+        * jsc.cpp:
+        (WTF::RuntimeArray::deleteProperty): Stop using ugly
+        compiler work-around on Windows; use NO_RETURN_DUE_TO_CRASH
+        codepath instead.
+        * runtime/Identifier.h: Add NO_RETURN_DUE_TO_CRASH
+        to header so function declaration matches implementation.
+
+2014-07-23  Bem Jones-Bey  <bjonesbe@adobe.com>
+
+        Remove CSS_EXCLUSIONS compile flag and leftover code
+        https://bugs.webkit.org/show_bug.cgi?id=135175
+
+        Reviewed by Zoltan Horvath.
+
+        At this point, the CSS_EXCLUSIONS flag guards nothing but some useless
+        stubs. This removes the flag and the useless code.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-07-23  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r171367.
+        https://bugs.webkit.org/show_bug.cgi?id=135192
+
+        broke three API tests (Requested by thorton on #webkit).
+
+        Reverted changeset:
+
+        "JSLock release should only modify the AtomicStringTable if it
+        modified in acquire"
+        https://bugs.webkit.org/show_bug.cgi?id=135143
+        http://trac.webkit.org/changeset/171367
+
+2014-07-22  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        [EFL] Build fix after the [ftlopt] branch merge.
+
+        Reviewed by Csaba Osztrogonác.
+
+        * dfg/DFGBranchDirection.h:
+        (JSC::DFG::branchDirectionToString):
+        * dfg/DFGStructureClobberState.h:
+        (JSC::DFG::merge):
+
+2014-07-22  Brent Fulgham  <bfulgham@apple.com>
+
+        Build fix for non-clang compile.
+
+        * jsc.cpp:
+        (WTF::RuntimeArray::put): Remove incorrect return statement
+        I added.
+
+2014-07-22  Brent Fulgham  <bfulgham@apple.com>
+
+        Build fix for non-clang compile.
+
+        * jsc.cpp:
+        (WTF::RuntimeArray::deleteProperty): Need (fake) return
+        value when NO_RETURN_DUE_TO_CRASH is not defined.
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r169628 from ftlopt.
+
+    2014-06-04  Matthew Mirman  <mmirman@apple.com>
+    
+            Added system for inlining native functions via the FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=131515
+    
+            Reviewed by Filip Pizlo.
+    
+            Also fixed the build to not compress the bitcode and to 
+            include all of the relevant runtime. With GCC_GENERATE_DEBUGGING_SYMBOLS = NO, 
+            the produced bitcode files are a 100th the size they were before.  
+            Now we can include all of the relevant runtime files with only a 3mb overhead. 
+            This is the same overhead as for two compressed files before, 
+            but done more efficiently (on both ends) and with less code.
+            
+            Deciding whether to inline native functions is left up to LLVM. 
+            The entire module containing the function is linked into the current 
+            compiled JS so that inlining the native functions shouldn't make them smaller.
+            
+            Rather than loading Runtime.symtbl at runtime FTLState.cpp now generates a file 
+            InlineRuntimeSymbolTable.h which statically builds the symbol table hash table.  
+            
+            * JavaScriptCore.xcodeproj/project.pbxproj: Added back runtime files to compile.
+            * build-symbol-table-index.py: Changed bitcode suffix. 
+            Added inclusion of only tested symbols.  
+            Added output to InlineRuntimeSymbolTable.h. 
+            * build-symbol-table-index.sh: Changed bitcode suffix.
+            * copy-llvm-ir-to-derived-sources.sh: Removed gzip compression.
+            * tested-symbols.symlst: Added.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall):  
+            Now sets the knownFunction of the call node if such a function exists 
+            and emits a check that during runtime the callee is in fact known.
+            * dfg/DFGNode.h:
+            Added functions to set the known function of a call node.
+            (JSC::DFG::Node::canBeKnownFunction): Added.
+            (JSC::DFG::Node::hasKnownFunction): Added.
+            (JSC::DFG::Node::knownFunction): Added.
+            (JSC::DFG::Node::giveKnownFunction): Added.
+            * ftl/FTLAbbreviatedTypes.h: Added a typedef for LLVMMemoryBufferRef
+            * ftl/FTLAbbreviations.h: Added some abbreviations.
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Added. Hardcoded threshold to 275.
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Added.
+            (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):  
+            Added call to possiblyCompileInlineableNativeCall
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::allocaName):  Added. Useful for debugging.
+            * ftl/FTLState.cpp:
+            (JSC::FTL::State::State): Added an include for InlineRuntimeSymbolTable.h
+            * ftl/FTLState.h: Added symbol table hash table.
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::compile): Added inlining and dead function elimination passes.
+            * heap/HandleStack.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * llvm/InitializeLLVMMac.mm: Deleted.
+            * llvm/InitializeLLVMMac.cpp: Added.
+            * llvm/LLVMAPIFunctions.h: Added macros to include Bitcode parsing and linking functions.
+            * llvm/LLVMHeaders.h: Added includes for Bitcode parsing and linking.
+            * runtime/BundlePath.h: Added.
+            * runtime/BundlePath.mm: Added.
+            * runtime/DateInstance.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * runtime/DateInstance.h: ditto.
+            * runtime/DateConversion.h: ditto.
+            * runtime/ExceptionHelpers.h: ditto.
+            * runtime/JSCJSValue.h: ditto.
+            * runtime/JSArray.h: ditto.
+            * runtime/JSDateMath.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/RegExp.h: ditto.
+            * runtime/Structure.h: ditto.
+            * runtime/Options.h:  Added maximumLLVMInstructionCountForNativeInlining.
+    
+2014-07-22  Mark Lam  <mark.lam@apple.com>
+
+        Array.concat() should work on runtime arrays too.
+        <https://webkit.org/b/135179>
+
+        Reviewed by Geoffrey Garen.
+
+        * jsc.cpp:
+        (WTF::RuntimeArray::create):
+        (WTF::RuntimeArray::~RuntimeArray):
+        (WTF::RuntimeArray::destroy):
+        (WTF::RuntimeArray::getOwnPropertySlot):
+        (WTF::RuntimeArray::getOwnPropertySlotByIndex):
+        (WTF::RuntimeArray::put):
+        (WTF::RuntimeArray::deleteProperty):
+        (WTF::RuntimeArray::getLength):
+        (WTF::RuntimeArray::createPrototype):
+        (WTF::RuntimeArray::createStructure):
+        (WTF::RuntimeArray::finishCreation):
+        (WTF::RuntimeArray::RuntimeArray):
+        (WTF::RuntimeArray::lengthGetter):
+        (GlobalObject::finishCreation):
+        (functionCreateRuntimeArray):
+        - Added support to create a runtime array for testing purpose.
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getLength):
+        - Added fast case for when the array object is a JSArray.
+        (JSC::arrayProtoFuncJoin):
+        - Added a needed but missing exception check.
+        (JSC::arrayProtoFuncConcat):
+        - Use getLength() to compute the array length instead of assuming that
+          the array is a JSArray instance.
+        * tests/stress/regexp-matches-array.js: Added.
+        (testArrayConcat):
+        * tests/stress/runtime-array.js: Added.
+        (testArrayConcat):
+
+2014-07-22  Brent Fulgham  <bfulgham@apple.com>
+
+        Fix Windows (return a value!)
+
+        * jsc.cpp:
+        (functionQuit): Satisfy compiler's need for
+        a return value.
+
+2014-07-22  Brent Fulgham  <bfulgham@apple.com>
+
+        Fix Windows (sleep -> Sleep)
+
+        * jsc.cpp:
+        (WTF::jscExit):
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix Windows.
+
+        * jsc.cpp:
+        (WTF::jscExit):
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix 32-bit.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from ftlopt.
+        
+        Note that r169753 is merged out of order because it fixes a bug in r169588.
+
+    2014-06-10  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Structure::dfgShouldWatchIfPossible() is unsound
+            https://bugs.webkit.org/show_bug.cgi?id=133624
+    
+            Reviewed by Mark Hahnenberg.
+    
+            * runtime/Structure.h:
+            (JSC::Structure::dfgShouldWatchIfPossible): Make it sound and add some verbiage.
+    
+    2014-06-04  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] AI should be able track structure sets larger than 1
+            https://bugs.webkit.org/show_bug.cgi?id=128073
+    
+            Reviewed by Oliver Hunt.
+            
+            This makes two major changes to how AI (abstract interpreter) proves that a value has
+            some structure:
+            
+            - StructureAbstractValue can now track an arbitrary number of structures. A set whose
+              size is greater than one means that the value may have any of the structures, and we
+              don't know which - but we do know that it cannot be any structure not in the set. The
+              structure abstract value can still be TOP, which means the set of all structures. We
+              artificially limit the set size to StructureAbstractValue::polymorphismLimit to guard
+              memory explosion on pathological programs. This limit is big enough that it wouldn't
+              kick in for normal code, since we have other heuristics that limit the number of
+              structures that we would allow an inline cache to know about.
+            
+            - We eagerly set watchpoints on all watchable structures and then we assume that
+              watchable structures are being watched, and that the watchpoint will jettison the code.
+              This allows tracking of watchable structures to be far simpler than before. Previously,
+              a structure being tracked as "future possible" was predicated on it being watchable but
+              we might not actually watch it. This makes algebra over sets of future possible
+              structures quite weird. But watching all watchable structures means that we simple say
+              that a structure set can be in the following states: unclobbered, which means it's just
+              a set of structures and it doesn't matter what is watchable or what isn't because we've
+              proven that the value must have one of these structures right now; and clobbered, which
+              means that we have a set of structures, plus all possible structures temporarily, with
+              invalidation removing the "plus all possible structures". Clobbering a set means that
+              if any of its structures are unwatchable, the set just becomes TOP; but if all
+              structures in the set are watchable then we just set the clobbered bit to add the "plus
+              all possible structures temporarily" thing. This precisely tracks the exact meaning of
+              watchability and invalidation points.
+            
+            Slight SunSpider slow-down, neutral on Octane, slight AsmBench speed-up. I believe that
+            we will ultimately undo the SunSpider slow-down by making further improvements to the set
+            representation. I believe that Octane perfromance will ultimately improve once we remove
+            remaining singleton special-cases. The ultimate goal of this is to remove the need to
+            try quite so desperately hard to make everything monomorphic as we do currently.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::clear):
+            (JSC::StructureSet::remove):
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::copyFromOutOfLine):
+            (JSC::StructureSet::StructureSet): Deleted.
+            (JSC::StructureSet::operator=): Deleted.
+            (JSC::StructureSet::copyFrom): Deleted.
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::operator=):
+            (JSC::StructureSet::isEmpty):
+            (JSC::StructureSet::genericFilter):
+            (JSC::StructureSet::ContainsOutOfLine::ContainsOutOfLine):
+            (JSC::StructureSet::ContainsOutOfLine::operator()):
+            (JSC::StructureSet::copyFrom):
+            (JSC::StructureSet::deleteStructureListIfNecessary):
+            (JSC::StructureSet::setEmpty):
+            (JSC::StructureSet::getReservedFlag):
+            (JSC::StructureSet::setReservedFlag):
+            * dfg/DFGAbstractInterpreter.h:
+            (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::booleanResult):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::verifyEdge):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::forAllValues):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberStructures):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::setDidClobber):
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::dump):
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::observeTransitions):
+            (JSC::DFG::AbstractValue::setMostSpecific):
+            (JSC::DFG::AbstractValue::set):
+            (JSC::DFG::AbstractValue::filter):
+            (JSC::DFG::AbstractValue::shouldBeClear):
+            (JSC::DFG::AbstractValue::normalizeClarity):
+            (JSC::DFG::AbstractValue::checkConsistency):
+            (JSC::DFG::AbstractValue::assertIsWatched):
+            (JSC::DFG::AbstractValue::dumpInContext):
+            (JSC::DFG::AbstractValue::setFuturePossibleStructure): Deleted.
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::clear):
+            (JSC::DFG::AbstractValue::clobberStructures):
+            (JSC::DFG::AbstractValue::clobberStructuresFor):
+            (JSC::DFG::AbstractValue::observeInvalidationPoint):
+            (JSC::DFG::AbstractValue::observeInvalidationPointFor):
+            (JSC::DFG::AbstractValue::observeTransition):
+            (JSC::DFG::AbstractValue::TransitionObserver::TransitionObserver):
+            (JSC::DFG::AbstractValue::TransitionObserver::operator()):
+            (JSC::DFG::AbstractValue::TransitionsObserver::TransitionsObserver):
+            (JSC::DFG::AbstractValue::TransitionsObserver::operator()):
+            (JSC::DFG::AbstractValue::isHeapTop):
+            (JSC::DFG::AbstractValue::setType):
+            (JSC::DFG::AbstractValue::operator==):
+            (JSC::DFG::AbstractValue::merge):
+            (JSC::DFG::AbstractValue::validate):
+            (JSC::DFG::AbstractValue::hasClobberableState):
+            (JSC::DFG::AbstractValue::assertIsWatched):
+            (JSC::DFG::AbstractValue::observeIndexingTypeTransition):
+            (JSC::DFG::AbstractValue::makeTop):
+            (JSC::DFG::AbstractValue::bestProvenStructure): Deleted.
+            * dfg/DFGAllocator.h:
+            * dfg/DFGArgumentsSimplificationPhase.cpp:
+            (JSC::DFG::ArgumentsSimplificationPhase::run):
+            * dfg/DFGArrayMode.cpp:
+            (JSC::DFG::ArrayMode::alreadyChecked):
+            * dfg/DFGAtTailAbstractState.h:
+            (JSC::DFG::AtTailAbstractState::structureClobberState):
+            (JSC::DFG::AtTailAbstractState::setStructureClobberState):
+            (JSC::DFG::AtTailAbstractState::setFoundConstants):
+            (JSC::DFG::AtTailAbstractState::haveStructures): Deleted.
+            (JSC::DFG::AtTailAbstractState::setHaveStructures): Deleted.
+            * dfg/DFGBasicBlock.cpp:
+            (JSC::DFG::BasicBlock::BasicBlock):
+            * dfg/DFGBasicBlock.h:
+            * dfg/DFGBranchDirection.h:
+            (JSC::DFG::branchDirectionToString):
+            (WTF::printInternal):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handlePutById):
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::performBlockCFA):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::checkStructureElimination):
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGCommon.cpp:
+            (JSC::DFG::startCrashing):
+            (JSC::DFG::isCrashing):
+            * dfg/DFGCommon.h:
+            * dfg/DFGCommonData.cpp:
+            (JSC::DFG::CommonData::notifyCompilingStructureTransition):
+            * dfg/DFGConstantFoldingPhase.cpp:
+            (JSC::DFG::ConstantFoldingPhase::foldConstants):
+            (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+            (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+            (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+            * dfg/DFGDesiredWatchpoints.cpp:
+            (JSC::DFG::DesiredWatchpoints::consider):
+            (JSC::DFG::DesiredWatchpoints::addLazily): Deleted.
+            * dfg/DFGDesiredWatchpoints.h:
+            (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
+            (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
+            (JSC::DFG::GenericDesiredWatchpoints::isWatched):
+            (JSC::DFG::DesiredWatchpoints::isWatched):
+            (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::addLazily): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::isStillValid): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState): Deleted.
+            (JSC::DFG::GenericDesiredWatchpoints::isValidOrMixed): Deleted.
+            (JSC::DFG::DesiredWatchpoints::isStillValid): Deleted.
+            (JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState): Deleted.
+            (JSC::DFG::DesiredWatchpoints::isValidOrMixed): Deleted.
+            * dfg/DFGDoesGC.cpp:
+            (JSC::DFG::doesGC):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+            (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::~Graph):
+            (JSC::DFG::Graph::dump):
+            (JSC::DFG::Graph::dumpBlockHeader):
+            (JSC::DFG::Graph::tryGetFoldableView):
+            (JSC::DFG::Graph::visitChildren):
+            (JSC::DFG::Graph::assertIsWatched):
+            (JSC::DFG::Graph::handleAssertionFailure):
+            * dfg/DFGGraph.h:
+            (JSC::DFG::Graph::convertToConstant):
+            (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
+            (JSC::DFG::Graph::addStructureTransitionData): Deleted.
+            * dfg/DFGInPlaceAbstractState.cpp:
+            (JSC::DFG::InPlaceAbstractState::beginBasicBlock):
+            (JSC::DFG::InPlaceAbstractState::initialize):
+            (JSC::DFG::InPlaceAbstractState::endBasicBlock):
+            (JSC::DFG::InPlaceAbstractState::reset):
+            (JSC::DFG::InPlaceAbstractState::merge):
+            * dfg/DFGInPlaceAbstractState.h:
+            (JSC::DFG::InPlaceAbstractState::structureClobberState):
+            (JSC::DFG::InPlaceAbstractState::setStructureClobberState):
+            (JSC::DFG::InPlaceAbstractState::setFoundConstants):
+            (JSC::DFG::InPlaceAbstractState::haveStructures): Deleted.
+            (JSC::DFG::InPlaceAbstractState::setHaveStructures): Deleted.
+            * dfg/DFGLivenessAnalysisPhase.cpp:
+            (JSC::DFG::LivenessAnalysisPhase::run):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasTransition):
+            (JSC::DFG::Node::transition):
+            (JSC::DFG::Node::hasStructure):
+            (JSC::DFG::StructureTransitionData::StructureTransitionData): Deleted.
+            (JSC::DFG::Node::convertToStructureTransitionWatchpoint): Deleted.
+            (JSC::DFG::Node::hasStructureTransitionData): Deleted.
+            (JSC::DFG::Node::structureTransitionData): Deleted.
+            * dfg/DFGNodeType.h:
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::compileInThreadImpl):
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+            * dfg/DFGSpeculativeJIT.h:
+            (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGStructureAbstractValue.cpp: Added.
+            (JSC::DFG::StructureAbstractValue::assertIsWatched):
+            (JSC::DFG::StructureAbstractValue::clobber):
+            (JSC::DFG::StructureAbstractValue::observeTransition):
+            (JSC::DFG::StructureAbstractValue::observeTransitions):
+            (JSC::DFG::StructureAbstractValue::add):
+            (JSC::DFG::StructureAbstractValue::merge):
+            (JSC::DFG::StructureAbstractValue::mergeSlow):
+            (JSC::DFG::StructureAbstractValue::mergeNotTop):
+            (JSC::DFG::StructureAbstractValue::filter):
+            (JSC::DFG::StructureAbstractValue::filterSlow):
+            (JSC::DFG::StructureAbstractValue::contains):
+            (JSC::DFG::StructureAbstractValue::isSubsetOf):
+            (JSC::DFG::StructureAbstractValue::isSupersetOf):
+            (JSC::DFG::StructureAbstractValue::overlaps):
+            (JSC::DFG::StructureAbstractValue::equalsSlow):
+            (JSC::DFG::StructureAbstractValue::dumpInContext):
+            (JSC::DFG::StructureAbstractValue::dump):
+            * dfg/DFGStructureAbstractValue.h:
+            (JSC::DFG::StructureAbstractValue::StructureAbstractValue):
+            (JSC::DFG::StructureAbstractValue::operator=):
+            (JSC::DFG::StructureAbstractValue::clear):
+            (JSC::DFG::StructureAbstractValue::makeTop):
+            (JSC::DFG::StructureAbstractValue::assertIsWatched):
+            (JSC::DFG::StructureAbstractValue::observeInvalidationPoint):
+            (JSC::DFG::StructureAbstractValue::top):
+            (JSC::DFG::StructureAbstractValue::isClear):
+            (JSC::DFG::StructureAbstractValue::isTop):
+            (JSC::DFG::StructureAbstractValue::isNeitherClearNorTop):
+            (JSC::DFG::StructureAbstractValue::isClobbered):
+            (JSC::DFG::StructureAbstractValue::merge):
+            (JSC::DFG::StructureAbstractValue::filter):
+            (JSC::DFG::StructureAbstractValue::operator==):
+            (JSC::DFG::StructureAbstractValue::size):
+            (JSC::DFG::StructureAbstractValue::at):
+            (JSC::DFG::StructureAbstractValue::operator[]):
+            (JSC::DFG::StructureAbstractValue::onlyStructure):
+            (JSC::DFG::StructureAbstractValue::isSupersetOf):
+            (JSC::DFG::StructureAbstractValue::makeTopWhenThin):
+            (JSC::DFG::StructureAbstractValue::setClobbered):
+            (JSC::DFG::StructureAbstractValue::add): Deleted.
+            (JSC::DFG::StructureAbstractValue::addAll): Deleted.
+            (JSC::DFG::StructureAbstractValue::contains): Deleted.
+            (JSC::DFG::StructureAbstractValue::isSubsetOf): Deleted.
+            (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan): Deleted.
+            (JSC::DFG::StructureAbstractValue::isClearOrTop): Deleted.
+            (JSC::DFG::StructureAbstractValue::last): Deleted.
+            (JSC::DFG::StructureAbstractValue::speculationFromStructures): Deleted.
+            (JSC::DFG::StructureAbstractValue::isValidOffset): Deleted.
+            (JSC::DFG::StructureAbstractValue::hasSingleton): Deleted.
+            (JSC::DFG::StructureAbstractValue::singleton): Deleted.
+            (JSC::DFG::StructureAbstractValue::dumpInContext): Deleted.
+            (JSC::DFG::StructureAbstractValue::dump): Deleted.
+            (JSC::DFG::StructureAbstractValue::topValue): Deleted.
+            * dfg/DFGStructureClobberState.h: Added.
+            (JSC::DFG::merge):
+            (WTF::printInternal):
+            * dfg/DFGTransition.cpp: Added.
+            (JSC::DFG::Transition::dumpInContext):
+            (JSC::DFG::Transition::dump):
+            * dfg/DFGTransition.h: Added.
+            (JSC::DFG::Transition::Transition):
+            * dfg/DFGTypeCheckHoistingPhase.cpp:
+            (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+            (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+            * dfg/DFGWatchableStructureWatchingPhase.cpp: Added.
+            (JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase):
+            (JSC::DFG::WatchableStructureWatchingPhase::run):
+            (JSC::DFG::WatchableStructureWatchingPhase::tryWatch):
+            (JSC::DFG::performWatchableStructureWatching):
+            * dfg/DFGWatchableStructureWatchingPhase.h: Added.
+            * dfg/DFGWatchpointCollectionPhase.cpp:
+            (JSC::DFG::WatchpointCollectionPhase::handle):
+            (JSC::DFG::WatchpointCollectionPhase::handleEdge): Deleted.
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLIntrinsicRepository.h:
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::ftlUnreachable):
+            (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
+            (JSC::FTL::LowerDFGToLLVM::compileBlock):
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
+            (JSC::FTL::LowerDFGToLLVM::compilePhi):
+            (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+            (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+            (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+            (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
+            (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
+            (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
+            (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+            (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMod):
+            (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+            (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
+            (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+            (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+            (JSC::FTL::LowerDFGToLLVM::compileGetById):
+            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+            (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+            (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+            (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+            (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+            (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+            (JSC::FTL::LowerDFGToLLVM::compileNewArray):
+            (JSC::FTL::LowerDFGToLLVM::compileNewArrayBuffer):
+            (JSC::FTL::LowerDFGToLLVM::compileAllocatePropertyStorage):
+            (JSC::FTL::LowerDFGToLLVM::compileReallocatePropertyStorage):
+            (JSC::FTL::LowerDFGToLLVM::compileToString):
+            (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+            (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+            (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+            (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+            (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+            (JSC::FTL::LowerDFGToLLVM::compare):
+            (JSC::FTL::LowerDFGToLLVM::boolify):
+            (JSC::FTL::LowerDFGToLLVM::terminate):
+            (JSC::FTL::LowerDFGToLLVM::lowInt32):
+            (JSC::FTL::LowerDFGToLLVM::lowInt52):
+            (JSC::FTL::LowerDFGToLLVM::opposite):
+            (JSC::FTL::LowerDFGToLLVM::lowCell):
+            (JSC::FTL::LowerDFGToLLVM::lowBoolean):
+            (JSC::FTL::LowerDFGToLLVM::lowDouble):
+            (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+            (JSC::FTL::LowerDFGToLLVM::speculate):
+            (JSC::FTL::LowerDFGToLLVM::isArrayType):
+            (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+            (JSC::FTL::LowerDFGToLLVM::callCheck):
+            (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+            (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
+            (JSC::FTL::LowerDFGToLLVM::setInt52):
+            (JSC::FTL::LowerDFGToLLVM::crash):
+            (JSC::FTL::LowerDFGToLLVM::compileStructureTransitionWatchpoint): Deleted.
+            * ftl/FTLOutput.cpp:
+            (JSC::FTL::Output::crashNonTerminal): Deleted.
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::crash): Deleted.
+            * jit/JITOperations.h:
+            * jsc.cpp:
+            (WTF::jscExit):
+            (functionQuit):
+            (main):
+            (printUsageStatement):
+            (CommandLine::parseArguments):
+            * runtime/Structure.h:
+            (JSC::Structure::dfgShouldWatchIfPossible):
+            (JSC::Structure::dfgShouldWatch):
+            * tests/stress/arrayify-to-structure-contradiction.js: Added.
+            (foo):
+            * tests/stress/ftl-getmyargumentslength-inline.js: Added.
+            (foo):
+            * tests/stress/multi-put-by-offset-multiple-transitions.js: Added.
+            (foo):
+            (Foo):
+            * tests/stress/throw-from-ftl-in-loop.js: Added.
+            * tests/stress/throw-from-ftl.js: Added.
+            (foo):
+    
+    2014-06-03  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Unreviewed, roll out r169578. The build system needs some more love.
+    
+            * InlineRuntimeSymbolTable.h: Removed.
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * build-symbol-table-index.py:
+            * build-symbol-table-index.sh:
+            * copy-llvm-ir-to-derived-sources.sh:
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::canBeKnownFunction): Deleted.
+            (JSC::DFG::Node::hasKnownFunction): Deleted.
+            (JSC::DFG::Node::knownFunction): Deleted.
+            (JSC::DFG::Node::giveKnownFunction): Deleted.
+            * ftl/FTLAbbreviatedTypes.h:
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::compile):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+            (JSC::FTL::LowerDFGToLLVM::lower):
+            (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
+            (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Deleted.
+            (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Deleted.
+            * ftl/FTLState.cpp:
+            (JSC::FTL::State::State):
+            * ftl/FTLState.h:
+            * heap/HandleStack.h:
+            * llvm/InitializeLLVM.h:
+            * llvm/InitializeLLVMMac.cpp: Removed.
+            * llvm/InitializeLLVMMac.mm: Added.
+            (JSC::initializeLLVMImpl):
+            * llvm/LLVMAPIFunctions.h:
+            * llvm/LLVMHeaders.h:
+            * runtime/BundlePath.h: Removed.
+            * runtime/BundlePath.mm: Removed.
+            * runtime/DateConversion.h:
+            * runtime/DateInstance.h:
+            * runtime/ExceptionHelpers.h:
+            * runtime/JSArray.h:
+            * runtime/JSCJSValue.h:
+            (JSC::JSValue::toFloat):
+            * runtime/JSDateMath.h:
+            * runtime/JSObject.h:
+            * runtime/JSWrapperObject.h:
+            * runtime/Options.h:
+            * runtime/RegExp.h:
+            * runtime/StringObject.h:
+            * runtime/Structure.h:
+            * tested-symbols.symlst: Removed.
+    
+    2014-06-03  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] FTL native inlining tests take far too long
+            https://bugs.webkit.org/show_bug.cgi?id=133498
+    
+            Unreviewed test gardening.
+            
+            Added a new exceptions test since the other one appears to not work.
+    
+            * tests/stress/ftl-library-exception.js:
+            * tests/stress/ftl-library-inline-gettimezoneoffset.js: Added.
+            (foo):
+            * tests/stress/ftl-library-inlining-exceptions-dataview.js: Added.
+            (foo):
+            * tests/stress/ftl-library-inlining-exceptions.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-exceptions.js.
+            * tests/stress/ftl-library-inlining-loops.js: Copied from LayoutTests/js/regress/script-tests/ftl-library-inlining-loops.js.
+            * tests/stress/ftl-library-inlining-random.js:
+            * tests/stress/ftl-library-substring.js:
+    
+    2014-06-03  Matthew Mirman  <mmirman@apple.com>
+    
+            [ftlopt] Added system for inlining native functions via the FTL.
+            https://bugs.webkit.org/show_bug.cgi?id=131515
+    
+            Reviewed by Filip Pizlo.
+    
+            Also fixed the build to not compress the bitcode and to 
+            include all of the relevant runtime. With GCC_GENERATE_DEBUGGING_SYMBOLS = NO, 
+            the produced bitcode files are a 100th the size they were before.  
+            Now we can include all of the relevant runtime files with only a 3mb overhead. 
+            This is the same overhead as for two compressed files before, 
+            but done more efficiently (on both ends) and with less code.
+            
+            Deciding whether to inline native functions is left up to LLVM. 
+            The entire module containing the function is linked into the current 
+            compiled JS so that inlining the native functions shouldn't make them smaller.
+            
+            Rather than loading Runtime.symtbl at runtime FTLState.cpp now includes a file 
+            InlineRuntimeSymbolTable.h which statically builds the symbol table hash table.  
+            Currently build-symbol-table-index.py updates this file from the 
+            contents of tested-symbols.symlst when done building as a matter of convenience.  
+            However, in order to include the new contents of the file in the build
+            you'd need to build twice.  This will be fixed in future versions.
+    
+            * JavaScriptCore.xcodeproj/project.pbxproj: Added back runtime files to compile.
+            * build-symbol-table-index.py: Changed bitcode suffix. 
+            Added inclusion of only tested symbols.  
+            Added output to InlineRuntimeSymbolTable.h. 
+            * build-symbol-table-index.sh: Changed bitcode suffix.
+            * copy-llvm-ir-to-derived-sources.sh: Removed gzip compression.
+            * tested-symbols.symlst: Added.
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::handleCall):  
+            Now sets the knownFunction of the call node if such a function exists 
+            and emits a check that during runtime the callee is in fact known.
+            * dfg/DFGNode.h:
+            Added functions to set the known function of a call node.
+            (JSC::DFG::Node::canBeKnownFunction): Added.
+            (JSC::DFG::Node::hasKnownFunction): Added.
+            (JSC::DFG::Node::knownFunction): Added.
+            (JSC::DFG::Node::giveKnownFunction): Added.
+            * ftl/FTLAbbreviatedTypes.h: Added a typedef for LLVMMemoryBufferRef
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::isInlinableSize): Added. Hardcoded threshold to 275.
+            (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::getFunctionBySymbol): Added.
+            (JSC::FTL::LowerDFGToLLVM::possiblyCompileInlineableNativeCall): Added.
+            (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):  
+            Added call to possiblyCompileInlineableNativeCall
+            * ftl/FTLOutput.h:
+            (JSC::FTL::Output::allocaName):  Added. Useful for debugging.
+            * ftl/FTLState.cpp:
+            (JSC::FTL::State::State): Added an include for InlineRuntimeSymbolTable.h
+            * ftl/FTLState.h: Added symbol table hash table.
+            * ftl/FTLCompile.cpp:
+            (JSC::FTL::compile): Added inlining and dead function elimination passes.
+            * heap/HandleStack.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * InlineRuntimeSymbolTable.h: Added.  
+            * llvm/InitializeLLVMMac.mm: Deleted.
+            * llvm/InitializeLLVMMac.cpp: Added.
+            * llvm/LLVMAPIFunctions.h: Added macros to include Bitcode parsing and linking functions.
+            * llvm/LLVMHeaders.h: Added includes for Bitcode parsing and linking.
+            * runtime/BundlePath.h: Added.
+            * runtime/BundlePath.mm: Added.
+            * runtime/DateInstance.h: Added JS_EXPORT_PRIVATE to a few functions to get inlining to compile.
+            * runtime/DateInstance.h: ditto.
+            * runtime/DateConversion.h: ditto.
+            * runtime/ExceptionHelpers.h: ditto.
+            * runtime/JSCJSValue.h: ditto.
+            * runtime/JSArray.h: ditto.
+            * runtime/JSDateMath.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/JSObject.h: ditto.
+            * runtime/RegExp.h: ditto.
+            * runtime/Structure.h: ditto.
+            * runtime/Options.h:  Added maximumLLVMInstructionCountForNativeInlining.
+            * tests/stress/ftl-library-inlining-random.js: Added.
+            * tests/stress/ftl-library-substring.js: Added.
+    
+    2014-05-21  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG::clobberize should be blind to the effects of GC
+            https://bugs.webkit.org/show_bug.cgi?id=133166
+    
+            Reviewed by Goeffrey Garen.
+            
+            Move the computation of where GCs happen to DFG::doesGC().
+            
+            Large (>5x) speed-up on programs that do loop-invariant string concatenations.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            (JSC::DFG::clobberizeForAllocation): Deleted.
+            * dfg/DFGDoesGC.cpp: Added.
+            (JSC::DFG::doesGC):
+            * dfg/DFGDoesGC.h: Added.
+            * dfg/DFGStoreBarrierElisionPhase.cpp:
+            (JSC::DFG::StoreBarrierElisionPhase::handleNode):
+            (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC): Deleted.
+    
+    2014-05-16  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] A StructureSet with one element should only require one word and no allocation
+            https://bugs.webkit.org/show_bug.cgi?id=133014
+    
+            Reviewed by Oliver Hunt.
+            
+            This makes it more efficient to use StructureSet in situations where the common case is
+            just one structure.
+            
+            I also took the opportunity to use the same set terminology we use in BitVector: merge,
+            filter, exclude, contains, etc.
+            
+            Eventually, this will be used to implement StructureAbstractValue as well.
+    
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/StructureSet.cpp: Added.
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::operator=):
+            (JSC::StructureSet::clear):
+            (JSC::StructureSet::add):
+            (JSC::StructureSet::remove):
+            (JSC::StructureSet::contains):
+            (JSC::StructureSet::merge):
+            (JSC::StructureSet::filter):
+            (JSC::StructureSet::exclude):
+            (JSC::StructureSet::isSubsetOf):
+            (JSC::StructureSet::overlaps):
+            (JSC::StructureSet::operator==):
+            (JSC::StructureSet::speculationFromStructures):
+            (JSC::StructureSet::arrayModesFromStructures):
+            (JSC::StructureSet::dumpInContext):
+            (JSC::StructureSet::dump):
+            (JSC::StructureSet::addOutOfLine):
+            (JSC::StructureSet::containsOutOfLine):
+            (JSC::StructureSet::copyFrom):
+            (JSC::StructureSet::OutOfLineList::create):
+            (JSC::StructureSet::OutOfLineList::destroy):
+            * bytecode/StructureSet.h:
+            (JSC::StructureSet::StructureSet):
+            (JSC::StructureSet::~StructureSet):
+            (JSC::StructureSet::onlyStructure):
+            (JSC::StructureSet::isEmpty):
+            (JSC::StructureSet::size):
+            (JSC::StructureSet::at):
+            (JSC::StructureSet::operator[]):
+            (JSC::StructureSet::last):
+            (JSC::StructureSet::OutOfLineList::list):
+            (JSC::StructureSet::OutOfLineList::OutOfLineList):
+            (JSC::StructureSet::deleteStructureListIfNecessary):
+            (JSC::StructureSet::isThin):
+            (JSC::StructureSet::pointer):
+            (JSC::StructureSet::singleStructure):
+            (JSC::StructureSet::structureList):
+            (JSC::StructureSet::set):
+            (JSC::StructureSet::clear): Deleted.
+            (JSC::StructureSet::add): Deleted.
+            (JSC::StructureSet::addAll): Deleted.
+            (JSC::StructureSet::remove): Deleted.
+            (JSC::StructureSet::contains): Deleted.
+            (JSC::StructureSet::containsOnly): Deleted.
+            (JSC::StructureSet::isSubsetOf): Deleted.
+            (JSC::StructureSet::overlaps): Deleted.
+            (JSC::StructureSet::singletonStructure): Deleted.
+            (JSC::StructureSet::speculationFromStructures): Deleted.
+            (JSC::StructureSet::arrayModesFromStructures): Deleted.
+            (JSC::StructureSet::operator==): Deleted.
+            (JSC::StructureSet::dumpInContext): Deleted.
+            (JSC::StructureSet::dump): Deleted.
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
+            * dfg/DFGTypeCheckHoistingPhase.cpp:
+            (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):
+    
+2014-07-22  Ryuan Choi  <ryuan.choi@samsung.com>
+
+        Unreviewed build fix attempt on the EFL port after r171362.
+
+        Build break because of -Werror=return-type
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::makesCalls):
+
+2014-07-22  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JSLock release should only modify the AtomicStringTable if it modified in acquire
+        https://bugs.webkit.org/show_bug.cgi?id=135143
+
+        Reviewed by Pratik Solanki.
+
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::willDestroyVM):
+        (JSC::JSLock::willReleaseLock):
+        Only set the AtomicStringTable when there was a VM, to balance JSLock::didAcquireLock.
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix cloop build.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeExitSiteData):
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Merge r168635, r168780, r169005, r169014, and r169143 from ftlopt.
+
+    2014-05-20  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG bytecode parser should turn GetById with nothing but a Getter stub as stuff+handleCall, and handleCall should be allowed to inline if it wants to
+            https://bugs.webkit.org/show_bug.cgi?id=133105
+    
+            Reviewed by Michael Saboff.
+            
+            - GetByIdStatus now knows about getters and can report intelligent things about them.
+              As is usually the case with how we do these things, GetByIdStatus knows more about
+              getters than the DFG can actually handle: it'll report details about polymorphic
+              getter calls even though the DFG won't be able to handle those. This is fine; the DFG
+              will see those statuses and bail to a generic slow path.
+            
+            - The DFG::ByteCodeParser now knows how to set up and do handleCall() for a getter call.
+              This can, and usually does, result in inlining of getters!
+            
+            - CodeOrigin and OSR exit know about inlined getter calls. When you OSR out of an
+              inlined getter, we set the return PC to a getter return thunk that fixes up the stack.
+              We use the usual offset-true-return-PC trick, where OSR exit places the true return PC
+              of the getter's caller as a phony argument that only the thunk knows how to find.
+            
+            - Removed a bunch of dead monomorphic chain support from StructureStubInfo.
+            
+            - A large chunk of this change is dragging GetGetterSetterByOffset, GetGetter, and
+              GetSetter through the DFG and FTL. GetGetterSetterByOffset is like GetByOffset except
+              that we know that we're returning a GetterSetter cell. GetGetter and GetSetter extract
+              the getter, or setter, from the GetterSetter.
+            
+            This is a ~2.5x speed-up on the getter microbenchmarks that we already had. So far none
+            of the "real" benchmarks exercise getters enough for this to matter. But I noticed that
+            some of the variants of the Richards benchmark in other languages - for example
+            Wolczko's Java translation of a C++ translation of Deutsch's Smalltalk version - use
+            getters and setters extensively. So, I created a getter/setter JavaScript version of
+            Richards and put it in regress/script-tests/getter-richards.js. That sees about a 2.4x
+            speed-up from this patch, which is very reassuring.
+    
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::printGetByIdCacheStatus):
+            (JSC::CodeBlock::findStubInfo):
+            * bytecode/CodeBlock.h:
+            * bytecode/CodeOrigin.cpp:
+            (WTF::printInternal):
+            * bytecode/CodeOrigin.h:
+            (JSC::InlineCallFrame::specializationKindFor):
+            * bytecode/GetByIdStatus.cpp:
+            (JSC::GetByIdStatus::computeFor):
+            (JSC::GetByIdStatus::computeForStubInfo):
+            (JSC::GetByIdStatus::makesCalls):
+            (JSC::GetByIdStatus::computeForChain): Deleted.
+            * bytecode/GetByIdStatus.h:
+            (JSC::GetByIdStatus::makesCalls): Deleted.
+            * bytecode/GetByIdVariant.cpp:
+            (JSC::GetByIdVariant::~GetByIdVariant):
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::operator=):
+            (JSC::GetByIdVariant::dumpInContext):
+            * bytecode/GetByIdVariant.h:
+            (JSC::GetByIdVariant::GetByIdVariant):
+            (JSC::GetByIdVariant::callLinkStatus):
+            * bytecode/PolymorphicGetByIdList.cpp:
+            (JSC::GetByIdAccess::fromStructureStubInfo):
+            (JSC::PolymorphicGetByIdList::from):
+            * bytecode/SpeculatedType.h:
+            * bytecode/StructureStubInfo.cpp:
+            (JSC::StructureStubInfo::deref):
+            (JSC::StructureStubInfo::visitWeakReferences):
+            * bytecode/StructureStubInfo.h:
+            (JSC::isGetByIdAccess):
+            (JSC::StructureStubInfo::initGetByIdChain): Deleted.
+            * dfg/DFGAbstractHeap.h:
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::addCall):
+            (JSC::DFG::ByteCodeParser::handleCall):
+            (JSC::DFG::ByteCodeParser::handleInlining):
+            (JSC::DFG::ByteCodeParser::handleGetByOffset):
+            (JSC::DFG::ByteCodeParser::handleGetById):
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+            (JSC::DFG::ByteCodeParser::parse):
+            * dfg/DFGCSEPhase.cpp:
+            (JSC::DFG::CSEPhase::getGetterSetterByOffsetLoadElimination):
+            (JSC::DFG::CSEPhase::getInternalFieldLoadElimination):
+            (JSC::DFG::CSEPhase::performNodeCSE):
+            (JSC::DFG::CSEPhase::getTypedArrayByteOffsetLoadElimination): Deleted.
+            * dfg/DFGClobberize.h:
+            (JSC::DFG::clobberize):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGJITCompiler.cpp:
+            (JSC::DFG::JITCompiler::linkFunction):
+            * dfg/DFGNode.h:
+            (JSC::DFG::Node::hasStorageAccessData):
+            * dfg/DFGNodeType.h:
+            * dfg/DFGOSRExitCompilerCommon.cpp:
+            (JSC::DFG::reifyInlinedCallFrames):
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+            * dfg/DFGSafeToExecute.h:
+            (JSC::DFG::safeToExecute):
+            * dfg/DFGSpeculativeJIT32_64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * ftl/FTLAbstractHeapRepository.cpp:
+            * ftl/FTLAbstractHeapRepository.h:
+            * ftl/FTLCapabilities.cpp:
+            (JSC::FTL::canCompile):
+            * ftl/FTLLink.cpp:
+            (JSC::FTL::link):
+            * ftl/FTLLowerDFGToLLVM.cpp:
+            (JSC::FTL::LowerDFGToLLVM::compileNode):
+            (JSC::FTL::LowerDFGToLLVM::compileGetGetter):
+            (JSC::FTL::LowerDFGToLLVM::compileGetSetter):
+            * jit/AccessorCallJITStubRoutine.h:
+            * jit/JIT.cpp:
+            (JSC::JIT::assertStackPointerOffset):
+            (JSC::JIT::privateCompile):
+            * jit/JIT.h:
+            * jit/JITPropertyAccess.cpp:
+            (JSC::JIT::emit_op_get_by_id):
+            * jit/ThunkGenerators.cpp:
+            (JSC::arityFixupGenerator):
+            (JSC::baselineGetterReturnThunkGenerator):
+            (JSC::baselineSetterReturnThunkGenerator):
+            (JSC::arityFixup): Deleted.
+            * jit/ThunkGenerators.h:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::setupArityCheckData):
+            * tests/stress/exit-from-getter.js: Added.
+            * tests/stress/poly-chain-getter.js: Added.
+            (Cons):
+            (foo):
+            (test):
+            * tests/stress/poly-chain-then-getter.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            * tests/stress/poly-getter-combo.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/poly-getter-then-chain.js: Added.
+            (Cons1):
+            (Cons2):
+            (foo):
+            (test):
+            * tests/stress/poly-getter-then-self.js: Added.
+            (foo):
+            (test):
+            (.test):
+            * tests/stress/poly-self-getter.js: Added.
+            (foo):
+            (test):
+            (getter):
+            * tests/stress/poly-self-then-getter.js: Added.
+            (foo):
+            (test):
+            * tests/stress/weird-getter-counter.js: Added.
+            (foo):
+            (test):
+    
+    2014-05-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] Factor out how CallLinkStatus uses exit site data
+            https://bugs.webkit.org/show_bug.cgi?id=133042
+    
+            Reviewed by Anders Carlsson.
+            
+            This makes it easier to use CallLinkStatus from clients that are calling into after
+            already holding some of the relevant locks. This is necessary because we use a "one lock
+            at a time" policy for CodeBlock locks: if you hold one then you're not allowed to acquire
+            any of the others. So, any code that needs to lock multiple CodeBlock locks needs to sort
+            of lock one, do some stuff, release it, then lock another, and then do more stuff. The
+            exit site data corresponds to the stuff you do while holding the baseline lock, while the
+            CallLinkInfo method corresponds to the stuff you do while holding the CallLinkInfo owner's
+            lock.
+    
+            * bytecode/CallLinkStatus.cpp:
+            (JSC::CallLinkStatus::computeFor):
+            (JSC::CallLinkStatus::computeExitSiteData):
+            (JSC::CallLinkStatus::computeDFGStatuses):
+            * bytecode/CallLinkStatus.h:
+            (JSC::CallLinkStatus::ExitSiteData::ExitSiteData):
+    
+    2014-05-17  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] InlineCallFrame::isCall should be an enumeration
+            https://bugs.webkit.org/show_bug.cgi?id=133034
+    
+            Reviewed by Sam Weinig.
+            
+            Once we start inlining getters and setters, we'll want InlineCallFrame to be able to tell
+            us that the inlined call was a getter call or a setter call. Initially I thought I would
+            have a new field called "kind" that would have components NormalCall, GetterCall, and
+            SetterCall. But that doesn't make sense, because for GetterCall and SetterCall, isCall
+            would have to be true. Hence, It makes more sense to have one enumeration that is Call,
+            Construct, GetterCall, or SetterCall. This patch is a first step towards this.
+            
+            It's interesting that isClosureCall should probably still be separate, since getter and
+            setter inlining could inline closure calls.
+    
+            * bytecode/CodeBlock.h:
+            (JSC::baselineCodeBlockForInlineCallFrame):
+            * bytecode/CodeOrigin.cpp:
+            (JSC::InlineCallFrame::dumpInContext):
+            (WTF::printInternal):
+            * bytecode/CodeOrigin.h:
+            (JSC::InlineCallFrame::kindFor):
+            (JSC::InlineCallFrame::specializationKindFor):
+            (JSC::InlineCallFrame::InlineCallFrame):
+            (JSC::InlineCallFrame::specializationKind):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+            * dfg/DFGOSRExitPreparation.cpp:
+            (JSC::DFG::prepareCodeOriginForOSRExit):
+            * runtime/Arguments.h:
+            (JSC::Arguments::finishCreation):
+    
+    2014-05-13  Filip Pizlo  <fpizlo@apple.com>
+    
+            [ftlopt] DFG should not exit due to inadequate profiling coverage when it can trivially fill in the profiling coverage due to variable constant inference and the better prediction modeling of typed array GetByVals
+            https://bugs.webkit.org/show_bug.cgi?id=132896
+    
+            Reviewed by Geoffrey Garen.
+            
+            This is a slight win on SunSpider, but it's meant to ultimately help us on
+            embenchen/lua. We already do well on that benchmark but our convergence is slower than
+            I'd like.
+    
+            * dfg/DFGArrayMode.cpp:
+            (JSC::DFG::ArrayMode::refine):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGFixupPhase.cpp:
+            (JSC::DFG::FixupPhase::fixupNode):
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            (JSC::DFG::PredictionPropagationPhase::propagate):
+    
+    2014-05-08  Filip Pizlo  <fpizlo@apple.com>
+    
+            jsSubstring() should be lazy
+            https://bugs.webkit.org/show_bug.cgi?id=132556
+    
+            Reviewed by Andreas Kling.
+            
+            jsSubstring() is now lazy by using a special rope that is a substring instead of a
+            concatenation. To make this patch super simple, we require that a substring's base is
+            never a rope. Hence, when resolving a rope, we either go down a non-recursive substring
+            path, or we go down a concatenation path which may see exactly one level of substrings in
+            its fibers.
+            
+            This is up to a 50% speed-up on microbenchmarks and a 10% speed-up on Octane/regexp.
+            
+            Relanding this with assertion fixes.
+    
+            * heap/MarkedBlock.cpp:
+            (JSC::MarkedBlock::specializedSweep):
+            * runtime/JSString.cpp:
+            (JSC::JSRopeString::visitFibers):
+            (JSC::JSRopeString::resolveRopeInternal8):
+            (JSC::JSRopeString::resolveRopeInternal16):
+            (JSC::JSRopeString::clearFibers):
+            (JSC::JSRopeString::resolveRope):
+            (JSC::JSRopeString::resolveRopeSlowCase8):
+            (JSC::JSRopeString::resolveRopeSlowCase):
+            * runtime/JSString.h:
+            (JSC::JSRopeString::finishCreation):
+            (JSC::JSRopeString::append):
+            (JSC::JSRopeString::create):
+            (JSC::JSRopeString::offsetOfFibers):
+            (JSC::JSRopeString::fiber):
+            (JSC::JSRopeString::substringBase):
+            (JSC::JSRopeString::substringOffset):
+            (JSC::JSRopeString::notSubstringSentinel):
+            (JSC::JSRopeString::substringSentinel):
+            (JSC::JSRopeString::isSubstring):
+            (JSC::JSRopeString::setIsSubstring):
+            (JSC::jsSubstring):
+            * runtime/RegExpMatchesArray.cpp:
+            (JSC::RegExpMatchesArray::reifyAllProperties):
+            * runtime/StringPrototype.cpp:
+            (JSC::stringProtoFuncSubstring):
+    
+2014-07-21  Sam Weinig  <sam@webkit.org>
+
+        [Cocoa] WKScriptMessageHandlers don't seem to function properly after navigating
+        https://bugs.webkit.org/show_bug.cgi?id=135148
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/CommonIdentifiers.h:
+        Add a common identifier for the string "webkit".
+
+2014-07-22  Filip Pizlo  <fpizlo@apple.com>
+
+        ASSERTION FAILED: info.spillFormat() & DataFormatJS in JSC::DFG::SpeculativeJIT::fillSpeculateCell
+        https://bugs.webkit.org/show_bug.cgi?id=135155
+        <rdar://problem/17763909>
+
+        Reviewed by Oliver Hunt.
+        
+        The DFG fillSpeculate code paths all need to be mindful of the fact that they may be stumbling upon a
+        contradiction, and that this is OK. In this case, we were speculating cell on an int.
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        * tests/stress/regress-135155.js: Added.
+        (run.t.length):
+        (run):
+
+2014-07-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Extend exception fuzzing to the LLInt
+        https://bugs.webkit.org/show_bug.cgi?id=135076
+
+        Reviewed by Oliver Hunt.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jit/JITOperations.cpp:
+        (JSC::numberOfExceptionFuzzChecks): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/CommonSlowPaths.cpp:
+        * runtime/ExceptionFuzz.cpp: Added.
+        (JSC::numberOfExceptionFuzzChecks):
+        (JSC::doExceptionFuzzing):
+        * runtime/ExceptionFuzz.h: Added.
+        (JSC::doExceptionFuzzingIfEnabled):
+
+2014-07-21  Mark Lam  <mark.lam@apple.com>
+
+        Refactor ArrayPrototype to use getLength() and putLength() utility functions.
+        https://bugs.webkit.org/show_bug.cgi?id=135139.
+
+        Reviewed by Oliver Hunt.
+
+        - Specialize putProperty() to putLength() because it is only used for setting
+          the length property.
+        - Added a getLength() utility function to get the value of the length property.
+        - Use these getLength() and putLength() functions instead of the existing code
+          to get and put the length property.  Less code to read, easier to understand.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getLength):
+        (JSC::putLength):
+        (JSC::arrayProtoFuncToString):
+        (JSC::arrayProtoFuncToLocaleString):
+        (JSC::arrayProtoFuncJoin):
+        (JSC::arrayProtoFuncPop):
+        (JSC::arrayProtoFuncPush):
+        (JSC::arrayProtoFuncReverse):
+        (JSC::arrayProtoFuncShift):
+        (JSC::arrayProtoFuncSlice):
+        (JSC::arrayProtoFuncSort):
+        (JSC::arrayProtoFuncSplice):
+        (JSC::arrayProtoFuncUnShift):
+        (JSC::arrayProtoFuncReduce):
+        (JSC::arrayProtoFuncReduceRight):
+        (JSC::arrayProtoFuncIndexOf):
+        (JSC::arrayProtoFuncLastIndexOf):
+        (JSC::putProperty): Deleted.
+
+2014-07-21  Diego Pino Garcia  <dpino@igalia.com>
+
+        new Int32Array(new ArrayBuffer(100), 1, 1) shouldn't throw an error that says "RangeError: Byte offset and length out of range of buffer"
+        https://bugs.webkit.org/show_bug.cgi?id=125391
+
+        Reviewed by Darin Adler.
+
+        Create own method for verifying byte offset alignment.
+
+        * runtime/ArrayBufferView.h:
+        (JSC::ArrayBufferView::verifyByteOffsetAlignment):
+        (JSC::ArrayBufferView::verifySubRangeLength):
+        (JSC::ArrayBufferView::verifySubRange): Deleted.
+        * runtime/GenericTypedArrayViewInlines.h:
+        (JSC::GenericTypedArrayView<Adaptor>::create):
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::create):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::create):
+
+2014-07-20  Diego Pino Garcia  <dpino@igalia.com>
+
+        ES6: Implement Math.sign()
+        https://bugs.webkit.org/show_bug.cgi?id=134980
+
+        Reviewed by Darin Adler.
+
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+        (JSC::mathProtoFuncSign):
+
+2014-07-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Exception fuzzing should work on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=135070
+
+        Reviewed by Mark Hahnenberg.
+
+        * tests/exceptionFuzz.yaml:
+
+2014-07-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix cloop build.
+
+        * jsc.cpp:
+        (jscmain):
+
+2014-07-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Need ability to fuzz exception throwing
+        https://bugs.webkit.org/show_bug.cgi?id=134945
+        <rdar://problem/17722027>
+
+        Reviewed by Sam Weinig.
+        
+        Adds the ability to instrument exception checks, and to force some random
+        exception check to artificially throw an exception. Also adds new tests that
+        are suitable for testing this. Note that this is closely tied to the Tools
+        directory changes that are also part of this changeset.
+        
+        This also fixes an activation tear-off bug that arises if we ever throw an
+        exception from operationOptimize, or if due to some other bug it's only due
+        to the operationOptimize exception check that we realize that there is an
+        exception to be thrown.
+
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::fastExceptionCheck):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::callCheck):
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::callExceptionFuzz):
+        (JSC::AssemblyHelpers::emitExceptionCheck):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitExceptionCheck): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_enter):
+        * jit/JITOperations.cpp:
+        (JSC::numberOfExceptionFuzzChecks):
+        * jit/JITOperations.h:
+        * jsc.cpp:
+        (jscmain):
+        * runtime/Options.h:
+        * runtime/TestRunnerUtils.h:
+        * tests/exceptionFuzz.yaml: Added.
+        * tests/exceptionFuzz: Added.
+        * tests/exceptionFuzz/3d-cube.js: Added.
+        * tests/exceptionFuzz/date-format-xparb.js: Added.
+        * tests/exceptionFuzz/earley-boyer.js: Added.
+
+2014-07-17  David Kilzer  <ddkilzer@apple.com>
+
+        SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig
+        <http://webkit.org/b/135006>
+
+        Reviewed by Darin Adler.
+
+        * Configurations/Base.xcconfig: Move SECTORDER_FLAGS to
+        JavaScriptCore.xcconfig.
+        * Configurations/CompileRuntimeToLLVMIR.xcconfig: Remove empty
+        SECTORDER_FLAGS definition.
+        * Configurations/DebugRelease.xcconfig: Ditto.
+        * Configurations/JavaScriptCore.xcconfig: Use $(CONFIGURATION)
+        so SECTORDER_FLAGS is only set on Production builds.
+
+2014-07-17  Juergen Ributzka  <juergen@apple.com>
+
+        Disable live-out calculation for stackmap intrinsics.
+        https://bugs.webkit.org/show_bug.cgi?id=134366
+
+        The live-out variables are not required for the stackmaps, because we
+        don't care about preserving the state when we perform destructive
+        patching.
+
+        Reviewed by Filip Pizlo.
+
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-07-17  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Follow-up fix to r171195 to prevent ASSERT in fast/profiler/profile-with-no-title.html
+
+        Rubber-stamped by Alexey Proskuryakov.
+
+        Null / empty titles should be fine. Tests pass in release builds
+        which allowed empty titles, and it looks like the LegacyProfiler
+        stopProfiling handles empty titles as expected already.
+
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::startProfiling):
+
+2014-07-16  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw
+        https://bugs.webkit.org/show_bug.cgi?id=134988
+        <rdar://problem/17706349>
+
+        Reviewed by Oliver Hunt.
+        
+        Luckily, we also don't need this optimization to be super powerful: the only place
+        where it really matters is for getting rid of the redundancy between op_enter and
+        op_init_lazy_reg, and in that case, there is a small set of possible nodes between the
+        two things. This change updates the store eliminator to know about only that small,
+        obviously safe, set of nodes over which we can store-eliminate.
+        
+        This shouldn't have any performance impact in the DFG because this optimization kicks
+        in relatively rarely already. And once we tier up into the FTL, we get a much better
+        store elimination over LLVM IR, so this really shouldn't matter at all.
+        
+        The tricky part of this patch is that there is a close relative of this optimization,
+        for uncaptured variables that got flushed. This happens for arguments to inlined calls.
+        I make this work by splitting it into two different store eliminators.
+        
+        Note that in the process of crafting the tests, I realized that we were incorrectly
+        DCEing NewArrayWithSize. That's not cool, since that can throw an exception for
+        negative array sizes. If we ever did want to DCE this node, we'd need to lower the node
+        to a check node followed by the actual allocation.
+
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::uncapturedSetLocalStoreElimination):
+        (JSC::DFG::CSEPhase::capturedSetLocalStoreElimination):
+        (JSC::DFG::CSEPhase::setLocalStoreElimination):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): Deleted.
+        * dfg/DFGNodeType.h:
+        * tests/stress/capture-escape-and-throw.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
+        (foo):
+        (bar):
+
+2014-07-15  Benjamin Poulain  <benjamin@webkit.org>
+
+        Reduce the overhead of updating the AssemblerBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=134659
+
+        Reviewed by Gavin Barraclough.
+
+        In r164548, the linker was changed to allow the LinkBuffer to survive its MacroAssembler.
+        That feature is useful for JSC to get offsets inside a linked buffer in order to jump directly
+        there.
+
+        On ARM, we use branch compaction and we need to keep the "compaction offset" somewher to be able
+        to get the real address of a lable. That is done by reusing the memory of AssemblerData.
+
+        To share the memory between LinkBuffer and the Assembler, r164548 moved the AssemblerData into
+        a ref-counted object. Unfortunately, the extra complexity related to the new AssemblerData was enough
+        to make clang give up a bunch of optimizations.
+
+        This patch solve (some of) the problems by making AssemblerBuffer and AssemblerData super low overhead structures.
+        In particular, the grow() function becomes 8 Thumb instructions, which is easily inlined everywhere it is used.
+
+        Instead of sharing ownership between the Assembler and LinkBuffer, LinkBuffer now takes full ownership of
+        the AssemblerData. I feel this is also safer since LinkBuffer is reusing the AssemblerData is a very
+        specific way that would make it unusable for the Assembler.
+
+        -- Technical details --
+
+        From LinkBuffer, we don't want to ever access the Assembler after releasing its buffer (or writting anything
+        into it really). This was obviously already the case, but that was hard to prove from LinkBuffer::copyCompactAndLinkCode().
+        To make this easier to work with, I changed all the assembler specific function to be static. This way we know
+        exactly what code access the Assembler instance. The code that does access the instance is then moved
+        at the beginning, before we modify anything.
+
+        The function recordLinkOffsets() that was on the MacroAssembler and copied in Assembler was moved directly
+        to LinkBuffer. This make the modification of AssemblerData completely explicit, and that code is specific
+        to LinkBuffer anyway (see LinkBuffer::executableOffsetFor()).
+
+        -- Perf impact --
+
+        This does not put us exactly at before r164548 due to the missing inline buffer. Still, it is very close.
+        On ARMv7, this reduces the time spent in Assembler by half. On the CSS JIT, this reduces the compilation
+        time by ~20%.
+
+        I could not measure any difference on x86_64.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::jumpSizeDelta):
+        (JSC::ARM64Assembler::canCompact):
+        (JSC::ARM64Assembler::computeJumpType):
+        (JSC::ARM64Assembler::link):
+        (JSC::ARM64Assembler::recordLinkOffsets): Deleted.
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::ifThenElseConditionBit):
+        (JSC::ARMv7Assembler::ifThenElse):
+        (JSC::ARMv7Assembler::jumpSizeDelta):
+        (JSC::ARMv7Assembler::canCompact):
+        (JSC::ARMv7Assembler::computeJumpType):
+        (JSC::ARMv7Assembler::link):
+        (JSC::ARMv7Assembler::linkJumpT1):
+        (JSC::ARMv7Assembler::linkJumpT3):
+        (JSC::ARMv7Assembler::linkConditionalJumpT4):
+        (JSC::ARMv7Assembler::linkConditionalBX):
+        (JSC::ARMv7Assembler::recordLinkOffsets): Deleted.
+        * assembler/AssemblerBuffer.h:
+        (JSC::AssemblerData::AssemblerData):
+        (JSC::AssemblerData::operator=):
+        (JSC::AssemblerData::~AssemblerData):
+        (JSC::AssemblerData::buffer):
+        (JSC::AssemblerData::capacity):
+        (JSC::AssemblerData::grow):
+        (JSC::AssemblerBuffer::AssemblerBuffer):
+        (JSC::AssemblerBuffer::isAvailable):
+        (JSC::AssemblerBuffer::data):
+        (JSC::AssemblerBuffer::releaseAssemblerData):
+        (JSC::AssemblerBuffer::putIntegral):
+        (JSC::AssemblerBuffer::putIntegralUnchecked):
+        (JSC::AssemblerBuffer::append):
+        (JSC::AssemblerBuffer::grow):
+        (JSC::AssemblerBuffer::~AssemblerBuffer): Deleted.
+        (JSC::AssemblerBuffer::storage): Deleted.
+        * assembler/LinkBuffer.cpp:
+        (JSC::recordLinkOffsets):
+        (JSC::LinkBuffer::copyCompactAndLinkCode):
+        * assembler/LinkBuffer.h:
+        (JSC::LinkBuffer::LinkBuffer):
+        (JSC::LinkBuffer::executableOffsetFor):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::canCompact):
+        (JSC::MacroAssemblerARM64::computeJumpType):
+        (JSC::MacroAssemblerARM64::jumpSizeDelta):
+        (JSC::MacroAssemblerARM64::link):
+        (JSC::MacroAssemblerARM64::recordLinkOffsets): Deleted.
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::canCompact):
+        (JSC::MacroAssemblerARMv7::computeJumpType):
+        (JSC::MacroAssemblerARMv7::jumpSizeDelta):
+        (JSC::MacroAssemblerARMv7::link):
+        (JSC::MacroAssemblerARMv7::recordLinkOffsets): Deleted.
+
+2014-07-15  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Stores to PropertyTable use the Structure as the owner
+        https://bugs.webkit.org/show_bug.cgi?id=134595
+
+        Reviewed by Darin Adler.
+
+        Since PropertyTable is the object that does the marking of these references, it should be the owner.
+
+        Also removed some unused parameters to other methods that historically used the Structure as the owner.
+
+        * runtime/JSPropertyNameIterator.h:
+        (JSC::StructureRareData::setEnumerationCache):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncToString):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::copy):
+        * runtime/PropertyTable.cpp:
+        (JSC::PropertyTable::clone):
+        (JSC::PropertyTable::PropertyTable):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::takePropertyTableOrCloneIfPinned):
+        (JSC::Structure::nonPropertyTransition):
+        (JSC::Structure::copyPropertyTable):
+        (JSC::Structure::copyPropertyTableForPinning):
+        (JSC::Structure::putSpecificValue):
+        * runtime/Structure.h:
+        (JSC::Structure::setObjectToStringValue):
+        (JSC::Structure::setPreviousID):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        * runtime/StructureRareData.h:
+        * runtime/StructureRareDataInlines.h:
+        (JSC::StructureRareData::setPreviousID):
+        (JSC::StructureRareData::setObjectToStringValue):
+
+2014-07-15  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        ScriptExecutable::forEachCodeBlock can dereference null CodeBlocks
+        https://bugs.webkit.org/show_bug.cgi?id=134928
+
+        Reviewed by Andreas Kling.
+
+        * bytecode/CodeBlock.h:
+        (JSC::ScriptExecutable::forEachCodeBlock): Check for null CodeBlocks before calling forEachRelatedCodeBlock.
+
+2014-07-15  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        Buildfix if LLINT_SLOW_PATH_TRACING is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=133790
+
+        Reviewed by Mark Lam.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+2014-07-14  Filip Pizlo  <fpizlo@apple.com>
+
+        Allow for Int52Rep to see things other than Int32, and make this testable
+        https://bugs.webkit.org/show_bug.cgi?id=134873
+        <rdar://problem/17641915>
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+        
+        A major premise of our type inference is that prediction propagation can say whatever it
+        wants and we'll still have valid IR after Fixup. This previously didn't work with Int52s.
+        We required some kind of agreement between prediction propagation and fixup over which
+        data flow paths were Int52 and which weren't.
+        
+        It turns out that we basically had such an agreement, with the exception of code that was
+        unreachable due to ForceOSRExit. Then, fixup and prediction propagation would disagree. It
+        might be nice to fix that bug - but it's only in the case of Int52 that such a thing would
+        be a bug! Normally, we allow sloppiness in prediction propagation.
+        
+        This patch allows us to be sloppy with Int52 prediction propagation by giving Int52Rep the
+        ability to see inputs other than Int32. This fixes the particular ForceOSRExit bug (see
+        int52-force-osr-exit-path.js for the reduced test case). To make sure that the newly
+        empowered Int52Rep is actually correct - in case we end up using it on paths other than
+        ForceOSRExit - this patch introduces an internal intrinsic called fiatInt52() that forces
+        us to attempt Int52 conversion on the input. This patch adds a bunch of tests that stress
+        this intrinsic. This means that we're now stressing Int52Rep more so than ever before!
+        
+        Note that it would still be a bug for prediction propagation to ever cause us to create an
+        Int52Rep node for a non-Int32 input. But, this will now be a performance bug, rather than
+        a crash bug.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::isMachineIntConstant):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isMachineIntConstant):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::convertMachineInt):
+        (JSC::DFG::SpeculativeJIT::speculateMachineInt):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepMachineInt):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isNumerical):
+        (JSC::DFG::isDouble):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
+        (JSC::FTL::LowerDFGToLLVM::doubleToInt32):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::doubleToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepMachineInt):
+        * jit/JITOperations.h:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionIdentity):
+        * runtime/Intrinsic.h:
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::tryConvertToInt52):
+        (JSC::isInt52):
+        (JSC::JSValue::isMachineInt):
+        * tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-double-to-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-int32-to-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-value-to-int52-double-path.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-double-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52-then-fail-to-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52-then-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-int32-to-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52-double-path.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-exit-not-double.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-fail-to-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52-then-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/int52-force-osr-exit-path.js: Added.
+        (foo):
+
+2014-07-14  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Flattening dictionaries with oversize backing stores can cause crashes
+        https://bugs.webkit.org/show_bug.cgi?id=134906
+
+        Reviewed by Filip Pizlo.
+
+        The collector expects any pointers into CopiedSpace passed to copyLater are within 32 KB 
+        of the CopiedBlock header. This was always the case except for when flattening a dictionary 
+        caused the size of the Butterfly to decrease. This was equivalent to moving the base of the 
+        Butterfly to higher addresses. If the object was reduced sufficiently in size, the base 
+        would no longer be within the first 32 KB of the CopiedBlock and the next collection would 
+        choke on the Butterfly pointer.
+
+        This patch fixes this issue by detect this situation during flattening and memmove-ing 
+        the Butterfly down to where the old base was.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::shiftButterflyAfterFlattening):
+        * runtime/JSObject.h:
+        (JSC::JSObject::butterflyPreCapacity):
+        (JSC::JSObject::butterflyTotalSize):
+        * runtime/Structure.cpp:
+        (JSC::Structure::flattenDictionaryStructure):
+        * tests/stress/flatten-oversize-dictionary-object.js: Added.
+        (foo):
+
+2014-07-14  Benjamin Poulain  <benjamin@webkit.org>
+
+        Remove some dead code from FTLJITFinalizer
+        https://bugs.webkit.org/show_bug.cgi?id=134874
+
+        Reviewed by Geoffrey Garen.
+
+        Not sure what that code was for...but it does not do anything :)
+
+        * ftl/FTLJITFinalizer.cpp:
+        (JSC::FTL::JITFinalizer::finalizeFunction):
+        The pointer of the label is computed but never used.
+
+        * ftl/FTLJITFinalizer.h:
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        The label is never set to anything.
+
+2014-07-14  Bear Travis  <betravis@adobe.com>
+
+        [Feature Queries] Enable Feature Queries on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=134404
+
+        Reviewed by Antti Koivisto.
+
+        Enable Feature Queries on Mac and resume running the
+        feature tests.
+
+        * Configurations/FeatureDefines.xcconfig: Turn on
+        ENABLE_CSS3_CONDITIONAL_RULES.
+
+2014-07-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Debugger Pause button does not work
+        https://bugs.webkit.org/show_bug.cgi?id=134785
+
+        Reviewed by Timothy Hatcher.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        Minification strips the sourceURL command. Add it back with minification.
+
+2014-07-11  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win] Enable DFG JIT.
+        https://bugs.webkit.org/show_bug.cgi?id=123615
+
+        Reviewed by Mark Lam.
+
+        When the return type of a JIT generated function call is larger than 64-bit (e.g. SlowPathReturnType),
+        the normal call() implementation cannot be used on 64-bit Windows, because the 64-bit Windows ABI is different in this case.
+        Also, when generating calls with double arguments, we need to make sure the arguments are put in the correct registers,
+        since the register allocation differs on 64-bit Windows.
+
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::callWithSlowPathReturnType): Added method to handle function calls where the return value type size is larger than 64-bit.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState): Move arguments to correct registers when there are floating point arguments.
+        (JSC::CCallHelpers::setupArgumentsWithExecStateForCallWithSlowPathReturnType): Added method.
+        * jit/JIT.h:
+        (JSC::JIT::appendCallWithSlowPathReturnType): Added method.
+        * jit/JITInlines.h:
+        (JSC::JIT::appendCallWithExceptionCheckAndSlowPathReturnType): Added method.
+        (JSC::JIT::callOperation): Call new method.
+
+2014-07-09  Benjamin Poulain  <benjamin@webkit.org>
+
+        Use 16bits instructions for push/pop on ARMv7 when possible
+        https://bugs.webkit.org/show_bug.cgi?id=134753
+
+        Reviewed by Geoffrey Garen.
+
+        The patch r170839 mixed the code for push/pop pair and single push/pop.
+        That part was reverted in r170909.
+
+        This patch puts the code back but specialized for single push/pop.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::pop):
+        (JSC::ARMv7Assembler::push):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::pop):
+        (JSC::MacroAssemblerARMv7::push):
+
+2014-07-09  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Remove uses of 'bash' in build system
+        https://bugs.webkit.org/show_bug.cgi?id=134782
+        <rdar://problem/17615533>
+
+        Reviewed by Dean Jackson.
+
+        Remove uses of 'bash' by replacing Windows-specific bash scripts
+        with Perl equivalents.
+
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make:
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters:
+        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh.
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Removed.
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh.
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Removed.
+        * JavaScriptCore.vcxproj/build-generated-files.pl: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/build-generated-files.sh.
+        * JavaScriptCore.vcxproj/build-generated-files.sh: Removed.
+        * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd:
+
+2014-07-09  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Remove use of 'grep' in build steps
+        https://bugs.webkit.org/show_bug.cgi?id=134770
+        <rdar://problem/17608783>
+
+        Reviewed by Tim Horton.
+
+        Replace uses of the grep command in Windows builds with the equivalent
+        Perl program.
+
+        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd:
+        * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd:
+
+2014-07-08  Benjamin Poulain  <benjamin@webkit.org>
+
+        Restore the assertion changed with 170839
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::pop):
+        (JSC::ARMv7Assembler::push):
+        Revert the Assembler part of 170839. The assertions do not match both encoding.
+
+        I'll add specific version of push and pop instead.
+
+2014-07-08  Jon Honeycutt  <jhoneycutt@apple.com>
+
+        RemoteInspector::shared() should not call WTF::initializeMainThread()
+        <https://bugs.webkit.org/show_bug.cgi?id=134747>
+        <rdar://problem/17161482>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::shared):
+        Don't call WTF::initializeMainThread(). WTF threading is initialized by
+        JSC::initializeThreading().
+
+2014-07-08  Andreas Kling  <akling@apple.com>
+
+        VM::lastCachedString should be a Strong, not a Weak.
+        <https://webkit.org/b/134746>
+
+        Using Weak<JSString> for this regressed some of our bindings perf tests
+        due to Weak having to allocate a new WeakImpl every time the last cached
+        string changed. Make it a Strong instead should make that problem go away.
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+        * runtime/VM.h:
+
+2014-07-07  Benjamin Poulain  <bpoulain@apple.com>
+
+        Fix the build after r170876
+
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::linkCode):
+
+2014-07-07  Benjamin Poulain  <benjamin@webkit.org>
+
+        LinkBuffer should not keep a reference to the MacroAssembler
+        https://bugs.webkit.org/show_bug.cgi?id=134668
+
+        Reviewed by Geoffrey Garen.
+
+        In FTL, the LinkBuffer can outlive the MacroAssembler that was used for code generation.
+        When that happens, the pointer m_assembler points to released memory. That was not causing
+        issues because the attribute is not used after linking, but that was not particularily
+        future proof.
+
+        This patch refactors LinkBuffer to avoid any lifetime risk. The MacroAssembler is now passed
+        as a reference, it is used for linking but no reference is ever stored with the LinkBuffer.
+
+        While fixing the call sites to use a reference, I also discovered LinkBuffer.h was included
+        everywhere. I refactored some #include to avoid that.
+
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::copyCompactAndLinkCode):
+        (JSC::LinkBuffer::linkCode):
+        * assembler/LinkBuffer.h:
+        (JSC::LinkBuffer::LinkBuffer):
+        * bytecode/Watchpoint.cpp:
+        * dfg/DFGDisassembler.cpp:
+        * dfg/DFGDisassembler.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::linkFunction):
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGPlan.cpp:
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrExitGenerationThunkGenerator):
+        (JSC::DFG::osrEntryThunkGenerator):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::generateICFastPath):
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * ftl/FTLJSCall.cpp:
+        * ftl/FTLJSCall.h:
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::osrExitGenerationThunkGenerator):
+        (JSC::FTL::slowPathCallThunkGenerator):
+        * jit/ArityCheckFailReturnThunks.cpp:
+        (JSC::ArityCheckFailReturnThunks::returnPCsFor):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITCall.cpp:
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITDisassembler.cpp:
+        * jit/JITDisassembler.h:
+        * jit/JITOpcodes.cpp:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::stringGetByValStubGenerator):
+        (JSC::JIT::privateCompileGetByVal):
+        (JSC::JIT::privateCompilePutByVal):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::stringGetByValStubGenerator):
+        * jit/RegisterPreservationWrapperGenerator.cpp:
+        (JSC::generateRegisterPreservationWrapper):
+        (JSC::registerRestorationThunkGenerator):
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::emitPutReplaceStub):
+        (JSC::emitPutTransitionStub):
+        (JSC::tryRepatchIn):
+        (JSC::linkClosureCall):
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::finalize):
+        * jit/ThunkGenerators.cpp:
+        (JSC::throwExceptionFromCallSlowPathGenerator):
+        (JSC::linkForThunkGenerator):
+        (JSC::linkClosureCallForThunkGenerator):
+        (JSC::virtualForThunkGenerator):
+        (JSC::nativeForGenerator):
+        (JSC::arityFixup):
+        * llint/LLIntThunks.cpp:
+        (JSC::LLInt::generateThunkWithJumpTo):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::compile):
+
+2014-07-07  Andreas Kling  <akling@apple.com>
+
+        Fast path for jsStringWithCache() when asked for the same string repeatedly.
+        <https://webkit.org/b/134635>
+
+        Reviewed by Darin Adler.
+
+        Follow-up to r170818 addressing a review comment by Geoff Garen.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+
+2014-07-07  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Add missing ENABLE(FTL_JIT) guards
+        https://bugs.webkit.org/show_bug.cgi?id=134680
+
+        Reviewed by Darin Adler.
+
+        * ftl/FTLDWARFDebugLineInfo.cpp:
+        * ftl/FTLDWARFDebugLineInfo.h:
+        * ftl/FTLGeneratedFunction.h:
+
+2014-07-07  Zan Dobersek  <zdobersek@igalia.com>
+
+        Enable ARMv7 disassembler for the GTK port
+        https://bugs.webkit.org/show_bug.cgi?id=134676
+
+        Reviewed by Benjamin Poulain.
+
+        * CMakeLists.txt: Add ARMv7DOpcode.cpp file to the build.
+        * disassembler/ARMv7/ARMv7DOpcode.cpp: Include the string.h header for strlen().
+
+2014-07-06  Benjamin Poulain  <benjamin@webkit.org>
+
+        [ARMv7] Use 16 bits instructions for push/pop when possible
+        https://bugs.webkit.org/show_bug.cgi?id=134656
+
+        Reviewed by Andreas Kling.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::pop):
+        (JSC::ARMv7Assembler::push):
+        (JSC::ARMv7Assembler::ARMInstructionFormatter::oneWordOp7Imm9):
+        Add the 16 bits version of push and pop.
+
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::pop):
+        (JSC::MacroAssemblerARMv7::push):
+        Use the new push/pop instead of a regular load/store.
+
+        * disassembler/ARMv7/ARMv7DOpcode.cpp:
+        (JSC::ARMv7Disassembler::ARMv7DOpcode::appendRegisterList):
+        * disassembler/ARMv7/ARMv7DOpcode.h:
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeMiscPushPop::registerMask):
+        Fix the disassembler for push/pop:
+        -The register mask was on 7 bits for some reason.
+        -The code printing the registers was comparing a register ID with a register
+         mask.
+
+2014-07-06  Yoav Weiss  <yoav@yoav.ws>
+
+        Turn on img@sizes compile flag
+        https://bugs.webkit.org/show_bug.cgi?id=134634
+
+        Reviewed by Benjamin Poulain.
+
+        * Configurations/FeatureDefines.xcconfig: Moved compile flag to alphabetical order.
+
+2014-07-06  Daewoong Jang  <daewoong.jang@navercorp.com>
+
+        Flags value of SourceCodeKey should be unique for each case.
+        https://bugs.webkit.org/show_bug.cgi?id=134435
+
+        Reviewed by Darin Adler.
+
+        Different combinations of CodeType and JSParserStrictness could generate same m_flags value because
+        the value of CodeType and the value of JSParserStrictness shares a bit inside m_flags member variable.
+        Shift the value of CodeType one bit farther to the left so those values don't overlap.
+
+        * runtime/CodeCache.h:
+        (JSC::SourceCodeKey::SourceCodeKey):
+
+2014-07-04  Andreas Kling  <akling@apple.com>
+
+        Fast path for jsStringWithCache() when asked for the same string repeatedly.
+        <https://webkit.org/b/134635>
+
+        Also moved the whole thing from WebCore to JavaScriptCore since it
+        makes more sense here, and inline the lightweight checks, leaving only
+        the hashmap stuff out of line.
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+        * runtime/JSString.h:
+        (JSC::jsStringWithCache):
+        * runtime/VM.h:
+
+2014-07-03  Daniel Bates  <dabates@apple.com>
+
+        Add WTF::move()
+        https://bugs.webkit.org/show_bug.cgi?id=134500
+
+        Rubber-stamped by Anders Carlsson.
+
+        Substitute WTF::move() for std::move().
+
+        * bytecode/CodeBlock.h:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        * bytecompiler/BytecodeGenerator.cpp:
+        * dfg/DFGGraph.cpp:
+        * dfg/DFGJITCompiler.cpp:
+        * dfg/DFGStackLayoutPhase.cpp:
+        * dfg/DFGWorklist.cpp:
+        * heap/DelayedReleaseScope.h:
+        * heap/HeapInlines.h:
+        [...]
+
+2014-07-03  Filip Pizlo  <fpizlo@apple.com>
+
+        SSA DCE should process blocks in forward order
+        https://bugs.webkit.org/show_bug.cgi?id=134611
+
+        Reviewed by Andreas Kling.
+
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
+        * tests/stress/dead-value-with-mov-hint-in-another-block.js: Added.
+        (foo):
+
+2014-07-03  Filip Pizlo  <fpizlo@apple.com>
+
+        JSActivation::symbolTablePut() should invalidate variable watchpoints
+        https://bugs.webkit.org/show_bug.cgi?id=134602
+
+        Reviewed by Oliver Hunt.
+        
+        Usually stores to captured variables cause us to invalidate the variable watchpoint because CodeBlock does so
+        during linking - we essentially assume that if it's at all possible for an inner function to store to a
+        variable we declare then this variable cannot be a constant. But this misses the dynamic store case, i.e.
+        JSActivation::symbolTablePut(). Part of the problem here is that JSActivation duplicates
+        JSSymbolTableObject's symbolTablePut() logic, which did have the invalidation. This patch keeps that code
+        duplicated, but fixes JSActivation::symbolTablePut() to do the right thing.
+
+        * runtime/JSActivation.cpp:
+        (JSC::JSActivation::symbolTablePut):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::symbolTablePut):
+        * tests/stress/constant-closure-var-with-dynamic-invalidation.js: Added.
+        (.):
+
+2014-07-01  Mark Lam  <mark.lam@apple.com>
+
+        Debugger's breakpoint list should not be a Vector.
+        <https://webkit.org/b/134514>
+
+        Reviewed by Geoffrey Garen.
+
+        The debugger currently stores breakpoint data as entries in a Vector (see
+        BreakpointsInLine).  It also keeps a fast map look up of breakpoint IDs to
+        the breakpoint data (see m_breakpointIDToBreakpoint).  Because a Vector can
+        compact or reallocate its backing store, this can causes all sorts of havoc.
+        The m_breakpointIDToBreakpoint map assumes that the breakpoint data doesn't
+        move in memory.
+
+        The fix is to replace the BreakpointsInLine Vector with a BreakpointsList
+        doubly linked list.
+
+        * debugger/Breakpoint.h:
+        (JSC::Breakpoint::Breakpoint):
+        (JSC::BreakpointsList::~BreakpointsList):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::setBreakpoint):
+        (JSC::Debugger::removeBreakpoint):
+        (JSC::Debugger::hasBreakpoint):
+        * debugger/Debugger.h:
+
+2014-06-30  Michael Saboff  <msaboff@apple.com>
+
+        Add option to run-jsc-stress-testes to filter out tests that use large heaps
+        https://bugs.webkit.org/show_bug.cgi?id=134458
+
+        Reviewed by Filip Pizlo.
+
+        Added test to skip js1_5/Regress/regress-159334.js when testing on a memory limited device.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2014-06-30  Daniel Bates  <dabates@apple.com>
+
+        Avoid copying closed variables vector; actually use move semantics
+
+        Rubber-stamped by Oliver Hunt.
+
+        Currently we always copy the closed variables vector passed by Parser::closedVariables()
+        to ProgramNode::setClosedVariables() because these member functions return and take a const
+        rvalue reference, respectively. Instead, these member functions should take an return a non-
+        constant rvalue reference so that we actually move the closed variables vector from the Parser
+        object to the Node object.
+
+        * parser/Nodes.cpp:
+        (JSC::ProgramNode::setClosedVariables): Remove const qualifier for argument.
+        * parser/Nodes.h:
+        (JSC::ScopeNode::setClosedVariables): Ditto.
+        * parser/Parser.h:
+        (JSC::Parser::closedVariables): Remove const qualifier on return type.
+        (JSC::parse): Remove extraneous call to std::move(). Calling std::move() is unnecessary here
+        because Parser::closedVariables() returns an rvalue reference.
+
+2014-06-30  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JSContext Inspection: Provide a way to use a non-Main RunLoop for Inspector JavaScript Evaluations
+        https://bugs.webkit.org/show_bug.cgi?id=134371
+
+        Reviewed by Timothy Hatcher.
+
+        * API/JSContextPrivate.h:
+        * API/JSContext.mm:
+        (-[JSContext _debuggerRunLoop]):
+        (-[JSContext _setDebuggerRunLoop:]):
+        Private API for setting the CFRunLoop for a debugger to evaluate in.
+        
+        * API/JSContextRefInternal.h: Added.
+        * API/JSContextRef.cpp:
+        (JSGlobalContextGetDebuggerRunLoop):
+        (JSGlobalContextSetDebuggerRunLoop):
+        Internal API for setting a CFRunLoop on a JSContextRef.
+        Set this on the debuggable.
+        
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        (Inspector::RemoteInspectorBlock::RemoteInspectorBlock):
+        (Inspector::RemoteInspectorBlock::~RemoteInspectorBlock):
+        (Inspector::RemoteInspectorBlock::operator=):
+        (Inspector::RemoteInspectorBlock::operator()):
+        Moved into the header.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::inspectorDebuggable):
+        Lets store the RunLoop on the debuggable instead of this core
+        platform agnostic class, so expose the debuggable.
+
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorHandleRunSourceGlobal):
+        (Inspector::RemoteInspectorQueueTaskOnGlobalQueue):
+        (Inspector::RemoteInspectorInitializeGlobalQueue):
+        Rename the global functions for clarity.
+
+        (Inspector::RemoteInspectorHandleRunSourceWithInfo):
+        Handler for private run loops.
+
+        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
+        (Inspector::RemoteInspectorDebuggableConnection::~RemoteInspectorDebuggableConnection):
+        (Inspector::RemoteInspectorDebuggableConnection::dispatchAsyncOnDebuggable):
+        (Inspector::RemoteInspectorDebuggableConnection::setupRunLoop):
+        (Inspector::RemoteInspectorDebuggableConnection::teardownRunLoop):
+        (Inspector::RemoteInspectorDebuggableConnection::queueTaskOnPrivateRunLoop):
+        Setup and teardown and use private run loop sources if the debuggable needs it.
+
+2014-06-30  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Add missing ENABLE(DFG_JIT) guards
+        https://bugs.webkit.org/show_bug.cgi?id=134444
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGFunctionWhitelist.cpp:
+        * dfg/DFGFunctionWhitelist.h:
+
+2014-06-29  Yoav Weiss  <yoav@yoav.ws>
+
+        Add support for HTMLImageElement's sizes attribute
+        https://bugs.webkit.org/show_bug.cgi?id=133620
+
+        Reviewed by Dean Jackson.
+
+        Added an ENABLE_PICTURE_SIZES compile flag.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-06-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Don't fold a UInt32ToNumber with DoOverflow to Identity since that would result in an Identity that takes an Int32 and returns a DoubleRep
+        https://bugs.webkit.org/show_bug.cgi?id=134412
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::setReplacement):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * tests/stress/uint32-to-number-fold-constant-with-do-overflow.js: Added.
+        (foo):
+        (bar):
+        (baz):
+
+2014-06-27  Peyton Randolph  <prandolph@apple.com>
+
+         Add feature flag for link long-press gesture.                                                                   
+         https://bugs.webkit.org/show_bug.cgi?id=134262                                                                  
+                                                                                                                         
+         Reviewed by Enrica Casucci.                                                                                     
+                                                                                                                         
+         * Configurations/FeatureDefines.xcconfig:                                                                       
+         Add ENABLE_LINK_LONG_PRESS. 
+
+2014-06-27  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        [JavaScriptCore] FTL buildfix for EFL platform.
+        https://bugs.webkit.org/show_bug.cgi?id=133546
+
+        Reviewed by Darin Adler.
+
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::forStackmaps):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::opposite):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::StackMaps::Constant::dump):
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::initializeLLVMPOSIX):
+
+2014-06-26  Benjamin Poulain  <benjamin@webkit.org>
+
+        iOS 8 beta 2 ES6 'Set' clear() broken
+        https://bugs.webkit.org/show_bug.cgi?id=134346
+
+        Reviewed by Oliver Hunt.
+
+        The object map was not cleared :(.
+
+        Kudos to Ashley Gullen for tracking this and making a regression test.
+        Credit to Oliver for finding the missing code.
+
+        * runtime/MapData.h:
+        (JSC::MapData::clear):
+
+2014-06-25  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Expose Cache Information to WinLauncher
+        https://bugs.webkit.org/show_bug.cgi?id=134318
+
+        Reviewed by Dean Jackson.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add missing
+        MemoryStatistics files to the WIndows build.
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-06-26  David Kilzer  <ddkilzer@apple.com>
+
+        DFG::FunctionWhitelist::parseFunctionNamesInFile does not close file
+        <http://webkit.org/b/134343>
+        <rdar://problem/17459487>
+
+        Reviewed by Michael Saboff.
+
+        * dfg/DFGFunctionWhitelist.cpp:
+        (JSC::DFG::FunctionWhitelist::parseFunctionNamesInFile):
+        Close the file handle, and log an error on failure.
+
+2014-06-25  Dana Burkart  <dburkart@apple.com>
+
+        Add support for 5-tuple versioning.
+
+        Reviewed by David Farler.
+
+        * Configurations/Version.xcconfig:
+
+2014-06-25  Geoffrey Garen  <ggaren@apple.com>
+
+        Build fix.
+
+        Unreviewed.
+
+        * runtime/JSDateMath.cpp:
+        (JSC::parseDateFromNullTerminatedCharacters):
+        * runtime/VM.cpp:
+        (JSC::VM::resetDateCache): Use std::numeric_limits instead of QNaN
+        constant since that constant doesn't exist anymore.
+
+2014-06-25  Geoffrey Garen  <ggaren@apple.com>
+
+        Unreviewed, rolling out r166876.
+
+        Caused some ECMA test262 failures
+
+        Reverted changeset:
+
+        "Date object needs to check for ES5 15.9.1.14 TimeClip limit."
+        https://bugs.webkit.org/show_bug.cgi?id=131248
+        http://trac.webkit.org/changeset/166876
+
+2014-06-25  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed gardening.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Update to
+        put various files in proper IDE categories.
+
+2014-06-25  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win64] ASM LLINT is not enabled.
+        https://bugs.webkit.org/show_bug.cgi?id=130638
+
+        This patch adds a new LLINT assembler backend for Win64, and implements it.
+        It makes adjustments to follow the Win64 ABI spec. where it's found to be needed.
+        Also, LLINT and JIT is enabled for Win64.
+
+        Reviewed by Mark Lam.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Added JITStubsMSVC64.asm.
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+        * JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props: Increased stack size to avoid stack overflow in tests.
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Generate assembler source file for Win64.
+        * assembler/MacroAssemblerX86_64.h: 
+        (JSC::MacroAssemblerX86_64::call): Follow Win64 ABI spec.
+        * jit/JITStubsMSVC64.asm: Added.
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStub): Compile fix.
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator): Follow Win64 ABI spec.
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions): Ditto.
+        * llint/LLIntOfflineAsmConfig.h: Enable new llint backend for Win64.
+        * llint/LowLevelInterpreter.asm: Implement new Win64 backend, and follow Win64 ABI spec.
+        * llint/LowLevelInterpreter64.asm: Ditto.
+        * offlineasm/asm.rb: Compile fix.
+        * offlineasm/backends.rb: Add new llint backend for Win64.
+        * offlineasm/settings.rb: Compile fix.
+        * offlineasm/x86.rb: Implement new llint Win64 backend.
+
+2014-06-25  Laszlo Gombos  <l.gombos@samsung.com>
+
+        Remove build guard for progress element
+        https://bugs.webkit.org/show_bug.cgi?id=134292
+
+        Reviewed by Benjamin Poulain.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-06-24  Michael Saboff  <msaboff@apple.com>
+
+        Add support routines to provide descriptive JavaScript backtraces
+        https://bugs.webkit.org/show_bug.cgi?id=134278
+
+        Reviewed by Mark Lam.
+
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::dump):
+        (JSC::CallFrame::describeFrame):
+        * interpreter/CallFrame.h:
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::dumpForBacktrace):
+        * runtime/JSCJSValue.h:
+
+2014-06-24  Brady Eidson  <beidson@apple.com>
+
+        Enable GAMEPAD in the Mac build, but disabled at runtime.
+        https://bugs.webkit.org/show_bug.cgi?id=134255
+
+        Reviewed by Dean Jackson.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+        * runtime/JSObject.h: Export JSObject::removeDirect() to allow disabling
+          functions at runtime.
+
+2014-06-24  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        REGRESSION (r169703): Invalid cast in JSC::asGetterSetter / JSC::JSObject::defineOwnNonIndexProperty
+        https://bugs.webkit.org/show_bug.cgi?id=134046
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/GetterSetter.h:
+        (JSC::asGetterSetter):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::defineOwnNonIndexProperty): We need to check for a CustomGetterSetter here as well as
+        a normal GetterSetter. If we encounter a CustomGetterSetter, we delete it, create a new normal GetterSetter,
+        and insert it like normal. We also need to check for CustomAccessors when checking for unconfigurable properties.
+
+2014-06-24  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] MSVC mishandles enums in bitfields
+        https://bugs.webkit.org/show_bug.cgi?id=134237
+
+        Reviewed by Michael Saboff.
+
+        Replace uses of enum types in bit fields with unsigned to
+        avoid losing a bit to hold the sign value. This can result
+        in Windows interpreting the value of the field improperly.
+
+        * bytecode/StructureStubInfo.h:
+        * parser/Nodes.h:
+
+2014-06-23  Andreas Kling  <akling@apple.com>
+
+        Inline the UnlinkedInstructionStream::Reader logic.
+        <https://webkit.org/b/134203>
+
+        This class is only used by CodeBlock to unpack the unlinked instructions,
+        and we were spending 0.5% of total time on PLT calling Reader::next().
+        Move the logic to the header file and mark it ALWAYS_INLINE.
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/UnlinkedInstructionStream.cpp:
+        * bytecode/UnlinkedInstructionStream.h:
+        (JSC::UnlinkedInstructionStream::Reader::Reader):
+        (JSC::UnlinkedInstructionStream::Reader::read8):
+        (JSC::UnlinkedInstructionStream::Reader::read32):
+        (JSC::UnlinkedInstructionStream::Reader::next):
+
+2014-06-20  Sam Weinig  <sam@webkit.org>
+
+        Remove static tables for bindings that use eager reification
+        https://bugs.webkit.org/show_bug.cgi?id=134126
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectCustomAccessor):
+        * runtime/Structure.h:
+        (JSC::Structure::setHasCustomGetterSetterProperties):
+        Change setHasCustomGetterSetterProperties to behave like setHasGetterSetterProperties, and set
+        the m_hasReadOnlyOrGetterSetterPropertiesExcludingProto bit if the property is not __proto__.
+        Without this, JSObject::put() won't think there are any setters on the prototype chain of an
+        object that has no static lookup table and uses eagerly reified custom getter/setter properties.
+
+2014-06-21  Brady Eidson  <beidson@apple.com>
+
+        Gamepad API - Deprecate the existing implementation
+        https://bugs.webkit.org/show_bug.cgi?id=134108
+
+        Reviewed by Timothy Hatcher.
+
+        -Add new "GAMEPAD_DEPRECATED" build flag, moving the existing implementation to use it
+        -Move some implementation files into a "deprecated" subdirectory.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-06-21  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r170244.
+        https://bugs.webkit.org/show_bug.cgi?id=134157
+
+        GTK/EFL bindings generator works differently, making this
+        patch not work there.  Will fix entire patch after a rollout.
+        (Requested by bradee-oh on #webkit).
+
+        Reverted changeset:
+
+        "Gamepad API - Deprecate the existing implementation"
+        https://bugs.webkit.org/show_bug.cgi?id=134108
+        http://trac.webkit.org/changeset/170244
+
+2014-06-21  Brady Eidson  <beidson@apple.com>
+
+        Gamepad API - Deprecate the existing implementation
+        https://bugs.webkit.org/show_bug.cgi?id=134108
+
+        Reviewed by Timothy Hatcher.
+
+        -Add new "GAMEPAD_DEPRECATED" build flag, moving the existing implementation to use it
+        -Add the "Deprecated" suffix to some implementation files
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-06-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        Removing PAGE_VISIBILITY_API compile guard.
+        https://bugs.webkit.org/show_bug.cgi?id=133844
+
+        Reviewed by Gavin Barraclough.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-06-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        ARM traditional buildfix after r169942.
+        https://bugs.webkit.org/show_bug.cgi?id=134100
+
+        Reviewed by Zoltan Herczeg.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::abortWithReason): Added.
+
+2014-06-20  Andreas Kling  <akling@apple.com>
+
+        [Cocoa] Release freed up blocks from the JS heap after simulated memory pressure.
+        <https://webkit.org/b/134112>
+
+        Reviewed by Mark Hahnenberg.
+
+        * heap/BlockAllocator.h:
+
+2014-06-19  Alex Christensen  <achristensen@webkit.org>
+
+        Unreviewed fix after r170130.
+
+        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj:
+        Corrected directory so it can find common.props when opening Visual Studio.
+
+2014-06-19  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Remove ENABLE(LLINT) and ENABLE(LLINT_C_LOOP) guards
+        https://bugs.webkit.org/show_bug.cgi?id=130389
+
+        Reviewed by Mark Lam.
+
+        Removed ENABLE(LLINT) since we always build with it, and changed ENABLE(LLINT_C_LOOP)
+        into !ENABLE(JIT) since they are mutually exclusive.
+
+        * CMakeLists.txt:
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::MacroAssemblerCodePtr::createLLIntCodePtr):
+        (JSC::MacroAssemblerCodeRef::createLLIntCodeRef):
+        * assembler/MaxFrameExtentForSlowPathCall.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFromLLInt):
+        * bytecode/CodeBlock.cpp:
+        (JSC::dumpStructure):
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        (JSC::CodeBlock::printCallOp):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::propagateTransitions):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::unlinkCalls):
+        (JSC::CodeBlock::unlinkIncomingCalls):
+        (JSC::CodeBlock::linkIncomingCall):
+        (JSC::CodeBlock::frameRegisterCount):
+        * bytecode/CodeBlock.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        * bytecode/Opcode.h:
+        (JSC::padOpcodeName):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitConstruct):
+        * heap/Heap.cpp:
+        (JSC::Heap::gatherJSStackRoots):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::initialize):
+        (JSC::Interpreter::isOpcode):
+        * interpreter/Interpreter.h:
+        (JSC::Interpreter::getOpcodeID):
+        * interpreter/JSStack.cpp:
+        (JSC::JSStack::JSStack):
+        (JSC::JSStack::committedByteCount):
+        * interpreter/JSStack.h:
+        * interpreter/JSStackInlines.h:
+        (JSC::JSStack::ensureCapacityFor):
+        (JSC::JSStack::topOfFrameFor):
+        (JSC::JSStack::setStackLimit):
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+        (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
+        * jit/JIT.h:
+        (JSC::JIT::compileCTINativeCall):
+        * jit/JITExceptions.h:
+        * jit/JITThunks.cpp:
+        (JSC::JITThunks::ctiNativeCall):
+        (JSC::JITThunks::ctiNativeConstruct):
+        * llint/LLIntCLoop.cpp:
+        * llint/LLIntCLoop.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::initialize):
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntData.h:
+        (JSC::LLInt::Data::performAssertions): Deleted.
+        * llint/LLIntEntrypoint.cpp:
+        * llint/LLIntEntrypoint.h:
+        * llint/LLIntExceptions.cpp:
+        * llint/LLIntExceptions.h:
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LLIntOffsetsExtractor.cpp:
+        (JSC::LLIntOffsetsExtractor::dummy):
+        * llint/LLIntOpcode.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LLIntThunks.cpp:
+        * llint/LLIntThunks.h:
+        * llint/LowLevelInterpreter.cpp:
+        * llint/LowLevelInterpreter.h:
+        * runtime/CommonSlowPaths.cpp:
+        * runtime/CommonSlowPaths.h:
+        * runtime/ErrorHandlingScope.cpp:
+        (JSC::ErrorHandlingScope::ErrorHandlingScope):
+        (JSC::ErrorHandlingScope::~ErrorHandlingScope):
+        * runtime/Executable.cpp:
+        (JSC::setupLLInt):
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreading):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::sanitizeStackForVM):
+        * runtime/VM.h:
+        (JSC::VM::canUseJIT): Deleted.
+
+2014-06-18  Alex Christensen  <achristensen@webkit.org>
+
+        Add FTL to Windows build.
+        https://bugs.webkit.org/show_bug.cgi?id=134015
+
+        Reviewed by Filip Pizlo.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        Added ftl source files.
+        * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+        Added ftl and llvm directories to include path.
+        * JavaScriptCore.vcxproj/libllvmForJSC: Added.
+        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.props: Added.
+        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj: Added.
+        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj.filters: Added.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+        MSVC doesn't like to divide by zero while compiling.  Use std::nan instead.
+        * llvm/InitializeLLVMWin.cpp: Added.
+        (JSC::initializeLLVMImpl):
+        Implemented dynamic loading and linking for Windows.
+
+2014-06-18  Alex Christensen  <achristensen@webkit.org>
+
+        Unreviewed build fix after r170107.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        Use non-template sub for armv7s.
+
+2014-06-18  David Kilzer  <ddkilzer@apple.com>
+
+        -[JSContext setName:] leaks NSString
+        <http://webkit.org/b/134038>
+
+        Reviewed by Joseph Pecoraro.
+
+        Fixes the following static analyzer warning:
+
+            JavaScriptCore/API/JSContext.mm:200:73: warning: Potential leak of an object
+                JSStringRef nameJS = name ? JSStringCreateWithCFString((CFStringRef)[name copy]) : nullptr;
+                                                                                    ^
+
+        * API/JSContext.mm:
+        (-[JSContext setName:]): Autorelease the copy of |name|.
+
+2014-06-18  Mark Lam  <mark.lam@apple.com>
+
+        DFGGraph::m_doubleConstantMap will not map 0 values correctly.
+        <https://webkit.org/b/133994>
+
+        Reviewed by Geoffrey Garen.
+
+        DFGGraph::m_doubleConstantsMap should not use a double as a key to its HashMap,
+        because it means two unfortunate things:
+        - It will probably break for zero.
+        - It will think that -0 is the same as +0 under some circumstances, size
+          -0==+0 even though they are distinct values (for example 1/-0 != 1/+0).
+
+        The fix is to use std::unordered_map which does not require special empty
+        and deleted values, and to use the raw bits instead of the double value as
+        the key.
+
+        * dfg/DFGGraph.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+
+2014-06-18  Alex Christensen  <achristensen@webkit.org>
+
+        Remove duplicate code using sdiv.
+        https://bugs.webkit.org/show_bug.cgi?id=133764
+
+        Reviewed by Daniel Bates.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::sdiv):
+        Make sdiv a template to match arm64.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithDiv):
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        Remove duplicate code that was identical except for sdiv not being a template.
+
+2014-06-17  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r170082.
+        https://bugs.webkit.org/show_bug.cgi?id=134006
+
+        Breaks build. (Requested by mlam on #webkit).
+
+        Reverted changeset:
+
+        "DFGGraph::m_doubleConstantMap will not map 0 values
+        correctly."
+        https://bugs.webkit.org/show_bug.cgi?id=133994
+        http://trac.webkit.org/changeset/170082
+
+2014-06-17  Mark Lam  <mark.lam@apple.com>
+
+        DFGGraph::m_doubleConstantMap will not map 0 values correctly.
+        <https://webkit.org/b/133994>
+
+        Reviewed by Geoffrey Garen.
+
+        DFGGraph::m_doubleConstantsMap should not use a double as a key to its HashMap,
+        because it means two unfortunate things:
+        - It will probably break for zero.
+        - It will think that -0 is the same as +0 under some circumstances, size
+          -0==+0 even though they are distinct values (for example 1/-0 != 1/+0).
+
+        The fix is to use std::unordered_map which does not require special empty
+        and deleted values, and to use the raw bits instead of the double value as
+        the key.
+
+        * dfg/DFGGraph.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+
+2014-06-17  Oliver Hunt  <oliver@apple.com>
+
+        Fix error messages for incorrect hex literals
+        https://bugs.webkit.org/show_bug.cgi?id=133998
+
+        Reviewed by Mark Lam.
+
+        Ensure that the error messages for bogus hex literals actually
+        make sense.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::lex):
+        * parser/ParserTokens.h:
+
+2014-06-17  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes bug where building JSC sometimes crashes at build-symbol-table-index.py. Also adds licenses. 
+        https://bugs.webkit.org/show_bug.cgi?id=133814
+
+        Reviewed by Filip Pizlo.
+        
+        Adds the "shopt -s nullglob" line necessary to prevent the loop in the shell 
+        script from using "*.o" as a file when no other files in the directory exist. 
+        
+        * build-symbol-table-index.sh: Added license.
+        * copy-llvm-ir-to-derived-sources.sh: Added license and "shopt -s nullglob" line.
+
+2014-06-16  Sam Weinig  <sam@webkit.org>
+
+        Move forward declaration of bindings static functions into their implementation files
+        https://bugs.webkit.org/show_bug.cgi?id=133943
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/CommonIdentifiers.h:
+        Add a few identifiers that are needed by the DOM.
+
+2014-06-16  Mark Lam  <mark.lam@apple.com>
+
+        Parser statementDepth accounting needs to account for when a function body excludes its braces.
+        <https://webkit.org/b/133832>
+
+        Reviewed by Oliver Hunt.
+
+        In some cases (e.g. when a Function object is instantiated from a string), the
+        function body source may not include its braces.  The parser needs to account
+        for this when calculating its statementDepth.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+        * bytecode/UnlinkedCodeBlock.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseStatement):
+        - Also fixed the error message for declaring nested functions in strict mode
+          to be more accurate.
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse):
+        (JSC::parse):
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+
+2014-06-16  Juergen Ributzka  <juergen@apple.com>
+
+        Change the order of the alias analysis passes to align with the opt pipeline of LLVM
+        https://bugs.webkit.org/show_bug.cgi?id=133753
+
+        Reviewed by Geoffrey Garen.
+
+        The order in which the alias analysis passes are added affects also the
+        order in which they are utilized. Change the order to align with the
+        one use by LLVM itself. The last alias analysis pass added will be
+        evaluated first. With this change we first perform a basic alias
+        analysis and then use the type-based alias analysis (if required).
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+
+2014-06-16  Juergen Ributzka  <juergen@apple.com>
+
+        Fix the arguments passed to the LLVM dylib
+        https://bugs.webkit.org/show_bug.cgi?id=133757
+
+        Reviewed by Geoffrey Garen.
+
+        The LLVM command line argument parser assumes that the first argument
+        is the program name. We need to add a fake program name, otherwise the
+        first argument will be parsed as program name and ignored.
+
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-06-16  Michael Saboff  <msaboff@apple.com>
+
+        Convert ASSERT in inlineFunctionForCapabilityLevel to early return
+        https://bugs.webkit.org/show_bug.cgi?id=133903
+
+        Reviewed by Mark Hahnenberg.
+
+        Hardened code by Converting ASSERT to return CannotCompile.
+
+        * dfg/DFGCapabilities.h:
+        (JSC::DFG::inlineFunctionForCapabilityLevel):
+
+2014-06-13  Sam Weinig  <sam@webkit.org>
+
+        Store DOM constants directly in the JS object rather than jumping through a custom accessor
+        https://bugs.webkit.org/show_bug.cgi?id=133898
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/Lookup.h:
+        (JSC::HashTableValue::attributes):
+        Switch attributes to be stored as an unsigned rather than an unsigned char, since there is no difference in memory use
+        and will make adding more flags possibles.
+
+        (JSC::HashTableValue::propertyGetter):
+        (JSC::HashTableValue::propertyPutter):
+        Change assertion to use BuiltinOrFunctionOrConstant.
+
+        (JSC::HashTableValue::constantInteger):
+        Added.
+
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticValueSlot):
+        Use PropertySlot::setValue() for constants during static lookup.
+
+        (JSC::reifyStaticProperties):
+        Put the constant directly on the object when eagerly reifying.
+
+        * runtime/PropertySlot.h:
+        Add ConstantInteger flag and BuiltinOrFunctionOrConstant helper.
+
+2014-06-14  Michael Saboff  <msaboff@apple.com>
+
+        operationCreateArguments could cause a GC during OSR exit
+        https://bugs.webkit.org/show_bug.cgi?id=133905
+
+        Reviewed by Filip Pizlo.
+
+        Defer GC via new wrapper functions for operationCreateArguments and operationCreateInlinedArguments
+        for use by OSR exit stubs.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
+2014-06-13  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        OSR exit should barrier the Executables for all InlineCallFrames, not just those on the stack at the time of exit
+        https://bugs.webkit.org/show_bug.cgi?id=133880
+
+        Reviewed by Filip Pizlo.
+
+        We could have exited due to a value received from an inlined block that's no longer on 
+        the stack, so we should just barrier all InlineCallFrames.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::adjustAndJumpToTarget):
+
+2014-06-13  Alex Christensen  <achristensen@webkit.org>
+
+        Make css jit compile for armv7.
+        https://bugs.webkit.org/show_bug.cgi?id=133596
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/MacroAssembler.h:
+        Use branchPtr on ARM_THUMB2.
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::addPtrNoFlags):
+        (JSC::MacroAssemblerARMv7::or32):
+        (JSC::MacroAssemblerARMv7::test32):
+        (JSC::MacroAssemblerARMv7::branch):
+        (JSC::MacroAssemblerARMv7::branchPtr):
+        Added macros necessary for css jit.
+
+2014-06-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix ARMv7.
+
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::abortWithReason):
+
+2014-06-12  Filip Pizlo  <fpizlo@apple.com>
+
+        Even better diagnostics from DFG traps
+        https://bugs.webkit.org/show_bug.cgi?id=133836
+
+        Reviewed by Oliver Hunt.
+        
+        We now stuff the DFG::NodeType into a register before bailing. Also made the
+        DFGBailed abort reason a bit more specific. As planned, the new abort reasons use
+        different numbers than any previous abort reasons.
+
+        * assembler/AbortReason.h:
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::abortWithReason):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::abortWithReason):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::abortWithReason):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::abortWithReason):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
+        (JSC::DFG::SpeculativeJIT::bail):
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGSpeculativeJIT.h:
+
+2014-06-12  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix assertions under JSC::setNeverInline() when running js tests in WebKitTestRunner
+        https://bugs.webkit.org/show_bug.cgi?id=133840
+
+        Reviewed by Filip Pizlo.
+        
+        Fix ASSERT(exec->vm().currentThreadIsHoldingAPILock()); under JSC::setNeverInline()
+        when running DFG tests.
+
+        * API/JSCTestRunnerUtils.cpp:
+        (JSC::numberOfDFGCompiles):
+        (JSC::setNeverInline):
+
+2014-06-12  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Avoid fork bomb during build
+        https://bugs.webkit.org/show_bug.cgi?id=133837
+        <rdar://problem/17296034>
+
+        Reviewed by Tim Horton.
+
+        * JavaScriptCore.vcxproj/build-generated-files.sh: Use a
+        reasonable default value when the 'num-cpus' script is not available.
+
+2014-06-12  Mark Lam  <mark.lam@apple.com>
+
+        Remove some dead / unused code.
+        <https://webkit.org/b/133828>
+
+        Reviewed by Filip Pizlo.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::create):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::makeFunction):
+        * parser/Parser.h:
+        (JSC::DepthManager::DepthManager): Deleted.
+        (JSC::DepthManager::~DepthManager): Deleted.
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+
+2014-06-12  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Move structureHasRareData out of TypeInfo
+        https://bugs.webkit.org/show_bug.cgi?id=133800
+
+        Reviewed by Andreas Kling.
+
+        StructureHasRareData was originally put in TypeInfo to avoid making Structure bigger, 
+        but we have a few spare bits in Structure so it would be nice to remove this hack.
+
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::newImpurePropertyFiresWatchpoints):
+        (JSC::TypeInfo::structureHasRareData): Deleted.
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::allocateRareData):
+        (JSC::Structure::cloneRareDataFrom):
+        * runtime/Structure.h:
+        (JSC::Structure::previousID):
+        (JSC::Structure::objectToStringValue):
+        (JSC::Structure::setObjectToStringValue):
+        (JSC::Structure::setPreviousID):
+        (JSC::Structure::clearPreviousID):
+        (JSC::Structure::previous):
+        (JSC::Structure::rareData):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        (JSC::Structure::enumerationCache):
+
+2014-06-12  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
+
+        Allow enum guards to be generated from the replay json files
+        https://bugs.webkit.org/show_bug.cgi?id=133399
+
+        Reviewed by Csaba Osztrogonác.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.__init__):
+        (InputsModel.parse_type_with_framework_name):
+        (Generator.generate_header):
+        (Generator.generate_implementation):
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp: Added.
+        (Test::HandleWheelEvent::HandleWheelEvent):
+        (Test::HandleWheelEvent::~HandleWheelEvent):
+        (JSC::InputTraits<Test::HandleWheelEvent>::type):
+        (JSC::InputTraits<Test::HandleWheelEvent>::encode):
+        (JSC::InputTraits<Test::HandleWheelEvent>::decode):
+        (JSC::EncodingTraits<WebCore::PlatformWheelEventPhase>::encodeValue):
+        (JSC::EncodingTraits<WebCore::PlatformWheelEventPhase>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h: Added.
+        (JSC::InputTraits<Test::HandleWheelEvent>::queue):
+        (Test::HandleWheelEvent::platformEvent):
+        * replay/scripts/tests/generate-enum-with-guard.json: Added.
+
+2014-06-12  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        Unreviewed. Fix GTK+ build after r169823.
+
+        Include StructureInlines.h in a few more files to fix linking
+        issues due to JSC::Structure::get undefined symbol.
+
+        * runtime/ArrayIteratorConstructor.cpp:
+        * runtime/ArrayIteratorPrototype.cpp:
+        * runtime/JSConsole.cpp:
+        * runtime/JSMapIterator.cpp:
+        * runtime/JSSet.cpp:
+        * runtime/JSSetIterator.cpp:
+        * runtime/JSWeakMap.cpp:
+        * runtime/MapIteratorPrototype.cpp:
+        * runtime/MapPrototype.cpp:
+        * runtime/SetIteratorPrototype.cpp:
+        * runtime/SetPrototype.cpp:
+        * runtime/WeakMapPrototype.cpp:
+
+2014-06-12  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [EFL] One more URTBF after r169823 to make ARM64 build happy too.
+
+        * runtime/JSMap.cpp:
+
+2014-06-11  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Inline caching should try to flatten uncacheable dictionaries
+        https://bugs.webkit.org/show_bug.cgi?id=133683
+
+        Reviewed by Geoffrey Garen.
+
+        There exists a body of JS code that deletes properties off of objects (especially function/constructor objects), 
+        which puts them into an uncacheable dictionary state. This prevents all future inline caching for these objects. 
+        If properties are deleted out of the object during its initialization, we can enable caching for that object by 
+        attempting to flatten it when we see we're trying to do inline caching with that object. We then record that we 
+        performed this flattening optimization in the object's Structure. If it ever re-enters the uncacheable dictionary 
+        state then we can just give up on caching that object.
+
+        In refactoring some of the code in tryCacheGetById and tryBuildGetByIdList to reduce some duplication, I added
+        the InlineCacheAction enum, a new way to indicate the success or failure of an inline caching attempt. I changed
+        the other inline caching functions to return this enum rather than the opaque booleans that we were previously 
+        returning.
+
+        * jit/Repatch.cpp:
+        (JSC::actionForCell):
+        (JSC::tryCacheGetByID):
+        (JSC::repatchGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::buildGetByIDList):
+        (JSC::tryCachePutByID):
+        (JSC::repatchPutByID):
+        (JSC::tryBuildPutByIdList):
+        (JSC::buildPutByIdList):
+        (JSC::tryRepatchIn):
+        (JSC::repatchIn):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::flattenDictionaryStructure):
+        * runtime/Structure.h:
+        (JSC::Structure::hasBeenFlattenedBefore):
+
+2014-06-11  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [EFL] URTBF after r169823.
+
+        * bindings/ScriptValue.cpp: Missing include added.
+
+2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Remove an unnecessary asObject(this) call inside JSObject::fastGetOwnPropertySlot.
+
+        Rubber-stamped by Andreas Kling.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::fastGetOwnPropertySlot):
+
+2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Turning on DUMP_PROPERTYMAP_STATS causes a build failure
+        https://bugs.webkit.org/show_bug.cgi?id=133673
+
+        Reviewed by Andreas Kling.
+
+        Rewrote the property map statistics code because the old code wasn't building,
+        and it was also mixing numbers for lookups and insertions/removals.
+
+        New logging code records the number of calls to PropertyTable::find (finds) and
+        PropertyTable::get/PropertyTable::findWithString separately so that we can quantify
+        the number of probing during updates and lookups.
+
+        * jsc.cpp:
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::get):
+        (JSC::PropertyTable::findWithString):
+        (JSC::PropertyTable::add):
+        (JSC::PropertyTable::remove):
+        (JSC::PropertyTable::reinsert):
+        (JSC::PropertyTable::rehash):
+        * runtime/Structure.cpp:
+        (JSC::PropertyMapStatisticsExitLogger::PropertyMapStatisticsExitLogger):
+        (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger):
+
+2014-06-11  Andreas Kling  <akling@apple.com>
+
+        Always inline JSValue::get() and Structure::get().
+        <https://webkit.org/b/133755>
+
+        Reviewed by Ryosuke Niwa.
+
+        These functions get really hot, so ask the compiler to be more
+        aggressive about inlining them.
+
+        ~28% speed-up on Ryosuke's microbenchmark for accessing nextSibling
+        through GetByVal.
+
+        * runtime/JSArrayIterator.cpp:
+        * runtime/JSCJSValue.cpp:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::get):
+        * runtime/JSPromiseDeferred.cpp:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get):
+
+2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Structure::get should instantiate DeferGC only when materializing property map
+        https://bugs.webkit.org/show_bug.cgi?id=133727
+
+        Rubber-stamped by Andreas Kling.
+
+        Make materializePropertyMapIfNecessary always inline.
+
+        This is ~12% improvement on the microbenchmark attached in the bug.
+
+        * runtime/Structure.h:
+        (JSC::Structure::materializePropertyMapIfNecessary):
+        (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+
+2014-06-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Structure::get should instantiate DeferGC only when materializing property map
+        https://bugs.webkit.org/show_bug.cgi?id=133727
+
+        Reviewed by Geoffrey Garen.
+
+        DeferGC instances in Structure::get was added in http://trac.webkit.org/r157539 in order to avoid
+        collecting the property table newly created by materializePropertyMapIfNecessary since GC can happen
+        when GCSafeConcurrentJITLocker goes out of scope.
+
+        However, always instantiating DeferGC inside Structure::get introduced a new performance bottleneck
+        in JSObject::getPropertySlot because frequently incrementing and decrementing a counter in vm.m_heap
+        and running a release assertion inside Heap::incrementDeferralDepth() is expensive.
+
+        Work around this by instantiating DeferGC only when we're actually calling materializePropertyMap,
+        and immediately storing a pointer to the newly created property table in the stack before DeferGC
+        goes out of scope so that the property table will be marked.
+
+        This shows 13-16% improvement on the microbenchmark attached in the bug.
+
+        * runtime/JSCJSValue.cpp:
+        * runtime/JSObject.h:
+        (JSC::JSObject::fastGetOwnPropertySlot):
+        * runtime/Structure.h:
+        (JSC::Structure::materializePropertyMapIfNecessary):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get):
+
+2014-06-11  Andreas Kling  <akling@apple.com>
+
+        Some JSValue::get() micro-optimzations.
+        <https://webkit.org/b/133739>
+
+        Tighten some of the property lookup code to improve performance of the
+        eagerly reified prototype attributes:
+
+        - Instead of converting the property name to an integer at every step
+          in the prototype chain, move that to a separate pass at the end
+          since it should be a rare case.
+
+        - Cache the StructureIDTable in a local instead of fetching it from
+          the Heap on every step.
+
+        - Make fillCustomGetterPropertySlot inline. It was out-of-lined based
+          on the assumption that clients would mostly be cacheable GetByIds,
+          and it gets pretty hot (~1%) in GetByVal.
+
+        - Pass the Structure directly to fillCustomGetterPropertySlot instead
+          of refetching it from the StructureIDTable.
+
+        Reviewed by Geoff Garen.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::fillCustomGetterPropertySlot): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+        (JSC::JSObject::fillCustomGetterPropertySlot):
+        (JSC::JSObject::getOwnPropertySlot):
+        (JSC::JSObject::fastGetOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+        (JSC::JSObject::getOwnPropertySlotSlow): Deleted.
+
+2014-06-10  Sam Weinig  <sam@webkit.org>
+
+        Don't create a HashTable for JSObjects that use eager reification
+        https://bugs.webkit.org/show_bug.cgi?id=133705
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/Lookup.h:
+        (JSC::reifyStaticProperties):
+        Add a version of reifyStaticProperties that takes an array of HashTableValues
+        rather than a HashTable.
+
+2014-06-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Prediction propagator should make sure everyone knows that a variable that is in an argument position where other versions of that variable are not MachineInts cannot possibly be flushed as Int52
+        https://bugs.webkit.org/show_bug.cgi?id=133698
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate): Use the new utility to figure out if a variable could ever represent an Int52.
+        * dfg/DFGVariableAccessData.cpp:
+        (JSC::DFG::VariableAccessData::couldRepresentInt52): Add a new utility to detect early on if a variable could possibly be Int52.
+        (JSC::DFG::VariableAccessData::couldRepresentInt52Impl):
+        (JSC::DFG::VariableAccessData::flushFormat):
+        * dfg/DFGVariableAccessData.h:
+        * tests/stress/int52-inlined-call-argument.js: Added.
+        (foo):
+        (bar):
+
+2014-06-10  Mark Lam  <mark.lam@apple.com>
+
+        Assertion failure at JSC::Structure::checkOffsetConsistency() const + 234.
+        <https://webkit.org/b/133356>
+
+        Reviewed by Mark Hahnenberg.
+
+        The root cause of this issue is that a nonPropertyTransition can transition
+        a pinned dictionary structure to an unpinned dictionary structure.  The new
+        structure will get a copy of the property table from the original structure.
+        However, when a GC occurs, the property table in the new structure will be
+        cleared because it is unpinned.  This leads to complications in subsequent
+        derivative structures when flattening occurs, which eventually leads to the
+        assertion failure in this bug.
+
+        The fix is to ensure that the new dictionary structure generated by the
+        nonPropertyTransition will have a copy of its predecessor's property table
+        and is pinned.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::nonPropertyTransition):
+
+2014-06-10  Michael Saboff  <msaboff@apple.com>
+
+        In a certain app state, Array.prototype.filter() returns incorrect results
+        https://bugs.webkit.org/show_bug.cgi?id=133577
+
+        Reviewed by Oliver Hunt.
+
+        Fixed the LLInt processing of op_put_by_val_direct to have the same hole check as op_put_by_val.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-06-09  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Global HashTables contain references to atomic StringImpls
+        https://bugs.webkit.org/show_bug.cgi?id=133661
+
+        Reviewed by Geoffrey Garen.
+
+        This was a long-standing bug revealed by bug 133558. The issue is that the global static HashTables 
+        cache their set of keys as StringImpls that are associated with a particular VM.  This is obviously 
+        incompatible with using multiple VMs on multiple threads (e.g. when using workers). The fix is to 
+        change the "keys" field of the static HashTables to be char** instead of StringImpl**.
+
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        * runtime/Lookup.cpp:
+        (JSC::HashTable::createTable):
+        (JSC::HashTable::deleteTable):
+        * runtime/Lookup.h:
+        (JSC::HashTable::ConstIterator::key):
+        (JSC::HashTable::entry):
+
+2014-06-09  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Build fix after r169703
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-06-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Eagerly reify DOM prototype attributes
+        https://bugs.webkit.org/show_bug.cgi?id=133558
+
+        Reviewed by Oliver Hunt.
+
+        This allows us to get rid of a lot of the additional overhead of pushing DOM attributes up into the prototype. 
+        By eagerly reifying the custom getters and setters into the actual JSObject we avoid having to override 
+        getOwnPropertySlot for all of the DOM prototypes, which is a lot of the overhead of doing property lookups on 
+        DOM wrappers.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/BatchedTransitionOptimizer.h:
+        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
+        * runtime/CustomGetterSetter.cpp: Added.
+        (JSC::callCustomSetter):
+        * runtime/CustomGetterSetter.h: Added.
+        (JSC::CustomGetterSetter::create):
+        (JSC::CustomGetterSetter::getter):
+        (JSC::CustomGetterSetter::setter):
+        (JSC::CustomGetterSetter::createStructure):
+        (JSC::CustomGetterSetter::CustomGetterSetter):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isCustomGetterSetter):
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::isCustomGetterSetter):
+        (JSC::JSCell::canUseFastGetOwnProperty):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::isHostOrBuiltinFunction): Deleted.
+        (JSC::JSFunction::isBuiltinFunction): Deleted.
+        * runtime/JSFunction.h:
+        * runtime/JSFunctionInlines.h: Inlined some random functions that appeared hot during profiling.
+        (JSC::JSFunction::isBuiltinFunction):
+        (JSC::JSFunction::isHostOrBuiltinFunction):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC::JSObject::putDirectCustomAccessor):
+        (JSC::JSObject::fillGetterPropertySlot):
+        (JSC::JSObject::fillCustomGetterPropertySlot):
+        (JSC::JSObject::getOwnPropertySlotSlow): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::hasCustomGetterSetterProperties):
+        (JSC::JSObject::convertToDictionary):
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+        (JSC::JSObject::getOwnPropertySlotSlow): Inlined because it looked hot during profiling.
+        (JSC::JSObject::putOwnDataProperty):
+        (JSC::JSObject::putDirect):
+        (JSC::JSObject::putDirectWithoutTransition):
+        * runtime/JSType.h:
+        * runtime/Lookup.h:
+        (JSC::reifyStaticProperties):
+        * runtime/PropertyDescriptor.h:
+        (JSC::PropertyDescriptor::PropertyDescriptor):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::nextOutOfLineStorageCapacity): Deleted.
+        (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Deleted.
+        (JSC::Structure::get): Deleted.
+        * runtime/Structure.h:
+        (JSC::Structure::hasCustomGetterSetterProperties):
+        (JSC::Structure::setHasCustomGetterSetterProperties):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get): Inlined due to hotness.
+        (JSC::nextOutOfLineStorageCapacity): Inlined due to hotness.
+        (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Inlined due to hotness.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase<Unknown>::isCustomGetterSetter):
+
+2014-06-07  Mark Lam  <mark.lam@apple.com>
+
+        Structure should initialize its previousID in its constructor.
+        <https://webkit.org/b/133606>
+
+        Reviewed by Mark Hahnenberg.
+
+        Currently, the Structure constructor that takes a previous structure will
+        initialize its previousID to point to the previous structure's previousID.
+        This is incorrect.  However, the caller of the Structure::create() factory
+        method (which instantiated the Structure) will later call setPreviousID()
+        to set the previousID to the correct previous structure.  This makes the
+        code confusing to read and more error prone in that the structure relies
+        on client code to fix its invalid previousID.
+
+        This patch fixes this by making the Structure constructor initialize
+        previousID correctly.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::nonPropertyTransition):
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::create):
+
+2014-06-06  Andreas Kling  <akling@apple.com>
+
+        Indexed getters should return values directly on the PropertySlot.
+        <https://webkit.org/b/133586>
+
+        Remove PropertySlot's custom index mode.
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSObject.h:
+        (JSC::PropertySlot::getValue):
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::setCustomIndex): Deleted.
+
+2014-06-04  Timothy Horton  <timothy_horton@apple.com>
+
+        iOS Debug build fix
+
+        Rubber-stamped by Filip Pizlo.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        Dead-code strip the llvmForJSC library unconditionally, to work around <rdar://problem/16920916>.
+
+2014-06-04  Oliver Hunt  <oliver@apple.com>
+
+        ArrayIterator should not be exposed in Safari 8
+        https://bugs.webkit.org/show_bug.cgi?id=133494
+
+        Reviewed by Michael Saboff.
+
+        Separate out types that require constructor objects, and don't
+        include the iterator types in that list.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObject.h:
+
+2014-06-04  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::Safepoint::begin() should set m_didCallBegin before releasing the rightToRun lock, because otherwise, Safepoint::checkLivenessAndVisitChildren() may assert due to a race
+        https://bugs.webkit.org/show_bug.cgi?id=133525
+        <rdar://problem/16790296>
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGSafepoint.cpp:
+        (JSC::DFG::Safepoint::begin):
+
+2014-06-03  Filip Pizlo  <fpizlo@apple.com>
+
+        LLVM soft-linking should be truly fail-silent
+        https://bugs.webkit.org/show_bug.cgi?id=133482
+
+        Reviewed by Mark Lam.
+
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::initializeLLVMPOSIX): Missing return statement in the dlsym() returning null case.
+
+2014-06-03  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        REGRESSION(r169092 and r169102): Skip failing JSC tests poperly on non-x86 Darwin platforms
+        https://bugs.webkit.org/show_bug.cgi?id=133149
+
+        Reviewed by Csaba Osztrogonác.
+
+        * tests/mozilla/mozilla-tests.yaml: Skip js1_5/Regress/regress-159334.js only if the architecture isn't x86 and the host is Darwin.
+
+2014-05-31  Anders Carlsson  <andersca@apple.com>
+
+        Add a LazyNeverDestroyed class template and use it
+        https://bugs.webkit.org/show_bug.cgi?id=133425
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGFunctionWhitelist.cpp:
+        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
+        * dfg/DFGFunctionWhitelist.h:
+
+2014-05-28  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::DCEPhase inserts into an insertion set in reverse, causing hilarious basic block corruption if you kill a lot of NewArrays
+        https://bugs.webkit.org/show_bug.cgi?id=133368
+
+        Reviewed by Mark Lam.
+
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::fixupBlock): Loop in the right order so that we insert in the right order.
+        * tests/stress/new-array-dead.js: Added.
+        (foo):
+
+2014-05-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix not-x86 32-bit.
+
+        * llint/LowLevelInterpreter32_64.asm:
+
+2014-05-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Arrayify neglects to inform the clobberizer that it might fire watchpoints
+        https://bugs.webkit.org/show_bug.cgi?id=133340
+
+        Reviewed by Mark Lam.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize): Be honest.
+        * llint/LowLevelInterpreter32_64.asm: Profile the object, not its structure.
+        * tests/stress/arrayify-fires-watchpoint.js: Added.
+        (foo):
+        (test):
+        (makeObjectArray):
+        * tests/stress/arrayify-structure-bad-test.js: Added.
+        (foo):
+        (test):
+
+2014-05-27  Jon Lee  <jonlee@apple.com>
+
+        Update ENABLE(MEDIA_SOURCE) on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=133141
+
+        Reviewed by Darin Adler.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-05-27  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Remove BLOB guards
+        https://bugs.webkit.org/show_bug.cgi?id=132863
+
+        Reviewed by Csaba Osztrogonác.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-05-27  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
+
+        Allow building CMake based ports with WEB_REPLAY
+        https://bugs.webkit.org/show_bug.cgi?id=133154
+
+        Reviewed by Csaba Osztrogonác.
+
+        * CMakeLists.txt:
+
+2014-05-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Latest emscripten life benchmark is 4x slower because the DFG doesn't realize that arithmetic on booleans is a thing
+        https://bugs.webkit.org/show_bug.cgi?id=133136
+
+        Reviewed by Oliver Hunt.
+        
+        Some key concepts:
+
+        - Except for the prediction propagation and type fixup phases, which are super early in
+          the pipeline, nobody has to know about the fact that booleans may flow into numerical
+          operations because there will just be a BooleanToNumber node that will take a value
+          and, if that value is a boolean, will convert it to the equivalent numerical value. It
+          will have a BooleanUse mode where it will also speculate that the input is a boolean
+          but it can also do UntypedUse in which case it will pass through any non-booleans.
+          This operation is very easy to model in all of the compiler tiers.
+
+        - No changes to the baseline JIT. The Baseline JIT will still believe that boolean
+          inputs require taking the slow path and it will still report that it took slow path
+          for any such operations.  The DFG will now be smart enough to ignore baseline JIT slow
+          path profiling on operations that were known to have had boolean inputs.  That's a
+          little quirky, but it's probably easier than modifying the baseline JIT to track
+          booleans correctly.
+        
+        4.1x speed-up on the emscripten "life" benchmark. Up to 10x speed-up on microbenchmarks.
+
+        * bytecode/SpeculatedType.h:
+        (JSC::isInt32OrBooleanSpeculation):
+        (JSC::isInt32SpeculationForArithmetic):
+        (JSC::isInt32OrBooleanSpeculationForArithmetic):
+        (JSC::isInt32OrBooleanSpeculationExpectingDefined):
+        (JSC::isInt52Speculation):
+        (JSC::isMachineIntSpeculation):
+        (JSC::isFullNumberOrBooleanSpeculation):
+        (JSC::isFullNumberOrBooleanSpeculationExpectingDefined):
+        (JSC::isInt32SpeculationExpectingDefined): Deleted.
+        (JSC::isMachineIntSpeculationExpectingDefined): Deleted.
+        (JSC::isMachineIntSpeculationForArithmetic): Deleted.
+        (JSC::isBytecodeNumberSpeculationExpectingDefined): Deleted.
+        (JSC::isFullNumberSpeculationExpectingDefined): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAllocator.h:
+        (JSC::DFG::Allocator<T>::indexOf):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::makeSafe):
+        (JSC::DFG::ByteCodeParser::makeDivSafe):
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixIntConvertingEdge):
+        (JSC::DFG::FixupPhase::fixIntOrBooleanEdge):
+        (JSC::DFG::FixupPhase::fixDoubleOrBooleanEdge):
+        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
+        (JSC::DFG::FixupPhase::fixIntEdge): Deleted.
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addSpeculationMode):
+        (JSC::DFG::Graph::valueAddSpeculationMode):
+        (JSC::DFG::Graph::arithAddSpeculationMode):
+        (JSC::DFG::Graph::addShouldSpeculateInt32):
+        (JSC::DFG::Graph::mulShouldSpeculateInt32):
+        (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
+        (JSC::DFG::Graph::negateShouldSpeculateInt32):
+        (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
+        (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
+        (JSC::DFG::Graph::mulImmediateShouldSpeculateInt32): Deleted.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::sawBooleans):
+        (JSC::DFG::Node::shouldSpeculateInt32OrBoolean):
+        (JSC::DFG::Node::shouldSpeculateInt32ForArithmetic):
+        (JSC::DFG::Node::shouldSpeculateInt32OrBooleanForArithmetic):
+        (JSC::DFG::Node::shouldSpeculateInt32OrBooleanExpectingDefined):
+        (JSC::DFG::Node::shouldSpeculateMachineInt):
+        (JSC::DFG::Node::shouldSpeculateDouble):
+        (JSC::DFG::Node::shouldSpeculateNumberOrBoolean):
+        (JSC::DFG::Node::shouldSpeculateNumberOrBooleanExpectingDefined):
+        (JSC::DFG::Node::shouldSpeculateNumber):
+        (JSC::DFG::Node::canSpeculateInt32):
+        (JSC::DFG::Node::canSpeculateInt52):
+        (JSC::DFG::Node::sourceFor):
+        (JSC::DFG::Node::shouldSpeculateInt32ExpectingDefined): Deleted.
+        (JSC::DFG::Node::shouldSpeculateMachineIntForArithmetic): Deleted.
+        (JSC::DFG::Node::shouldSpeculateMachineIntExpectingDefined): Deleted.
+        (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic): Deleted.
+        (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined): Deleted.
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        (JSC::DFG::nodeMayOverflow):
+        (JSC::DFG::nodeMayNegZero):
+        (JSC::DFG::nodeCanSpeculateInt32):
+        (JSC::DFG::nodeCanSpeculateInt52):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::run):
+        (JSC::DFG::PredictionPropagationPhase::propagateToFixpoint):
+        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+        (JSC::FTL::LowerDFGToLLVM::compileBooleanToNumber):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::asInt32ForArithmetic):
+        * tests/stress/max-boolean-exit.js: Added.
+        (foo):
+        (test):
+        * tests/stress/mul-boolean-exit.js: Added.
+        (foo):
+        (test):
+        * tests/stress/plus-boolean-exit.js: Added.
+        (foo):
+        (test):
+        * tests/stress/plus-boolean-or-double.js: Added.
+        (foo):
+        (test):
+        * tests/stress/plus-boolean-or-int.js: Added.
+        (foo):
+        (test):
+
+2014-05-26  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
+
+        Remove dead code from VM.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=133284
+
+        Reviewed by Darin Adler.
+
+        This workaround was added in r127505. Since the clang is the
+        only used compiler in this case, this workaround is obsolete.
+
+        * runtime/VM.cpp:
+        (JSC::enableAssembler):
+
+2014-05-26  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        JSC CLoop warning fix
+        https://bugs.webkit.org/show_bug.cgi?id=133259
+
+        Reviewed by Darin Adler.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+2014-05-24  Andreas Kling  <akling@apple.com>
+
+        Object.prototype.toString() should use cached strings for null/undefined.
+        <https://webkit.org/b/133261>
+
+        Normally, when calling Object.prototype.toString() on a regular object,
+        we'd cache the result of the stringification on the object's structure,
+        making repeated calls fast.
+
+        For null and undefined, we were not as smart. We'd instead construct a
+        new string with either "[object Null]" or "[object Undefined]" each time.
+
+        This was exposed by Dromaeo's JS library tests, where some prototype.js
+        subtests generate millions of strings this way.
+
+        This patch adds two VM-permanent cached strings to the SmallStrings.
+        Looks like ~10% speed-up on Dromaeo/jslib-traverse-prototype.html
+
+        Reviewed by Darin Adler.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncToString):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::SmallStrings):
+        (JSC::SmallStrings::initializeCommonStrings):
+        (JSC::SmallStrings::visitStrongReferences):
+        * runtime/SmallStrings.h:
+        (JSC::SmallStrings::nullObjectString):
+        (JSC::SmallStrings::undefinedObjectString):
+
+2014-05-23  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Remove operationCallGetter
+
+        Rubber stamped by Filip Pizlo.
+
+        Nobody calls this function.
+
+        * JavaScriptCore.order:
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
+2014-05-23  Andreas Kling  <akling@apple.com>
+
+        Templatize GC's destructor invocation for dtor type.
+        <https://webkit.org/b/133231>
+
+        Get rid of a branch in callDestructor() by templatizing it for
+        the DestructorType. Removed JSCell::methodTableForDestruction()
+        since this was the only call site and it was jumping through
+        a bunch of unnecessary hoops.
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::callDestructor):
+        (JSC::MarkedBlock::specializedSweep):
+        * heap/MarkedBlock.h:
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::methodTableForDestruction): Deleted.
+
+2014-05-23  Andreas Kling  <akling@apple.com>
+
+        Support inline caching of RegExpMatchesArray.length
+        <https://webkit.org/b/133234>
+
+        Give RegExpMatchesArray.length the same treatment as JSArray in
+        repatch so we don't have to go out of line on every access.
+
+        ~13% speed-up on Octane/regexp.
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        * runtime/RegExpMatchesArray.h:
+        (JSC::isRegExpMatchesArray):
+
+2014-05-22  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(r154797): Debugger crashes when stepping over an uncaught exception.
+        <https://webkit.org/b/133182>
+
+        Reviewed by Oliver Hunt.
+
+        Before r154797, we used to clear the VM exception before calling into the
+        debugger.  After r154797, we don't.  This patch will restore this clearing
+        of the exception before calling into the debugger.
+
+        Also added assertions after returning from calls into the debugger to
+        ensure that the debugger did not introduce any exceptions.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        (JSC::Interpreter::unwind):
+        (JSC::Interpreter::debug):
+        - Fixed the assertion here.  Interpreter::debug() should never be called
+          with a pending exception.  Debugger callbacks for exceptions should be
+          handled by Interpreter::unwind() and Interpreter::unwindCallFrame().
+
+2014-05-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Store barrier elision should run after DCE in both the DFG path and the FTL path
+        https://bugs.webkit.org/show_bug.cgi?id=129718
+
+        Rubber stamped by Mark Hahnenberg.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+
+2014-05-21  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
+
+        [EFL] Add include path of compact_unwind_encoding.h if FTL JIT is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=132907
+
+        Reviewed by Gyuyoung Kim.
+
+        * CMakeLists.txt:
+
+2014-05-16  Martin Robinson  <mrobinson@igalia.com>
+
+        [CMake] Improve handling of LIB_INSTALL_DIR, EXEC_INSTALL_DIR, and LIBEXEC_INSTALL_DIR
+        https://bugs.webkit.org/show_bug.cgi?id=132819
+
+        Reviewed by Carlos Garcia Campos.
+
+        * javascriptcoregtk.pc.in: Instead of using the special pkg-config variables,
+        use the common CMake ones directly.
+
+2014-05-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out http://trac.webkit.org/changeset/169159.
+        
+        This was a unilateral change and wasn't properly reviewed.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2014-05-21  Antoine Quint  <graouts@webkit.org>
+
+        Array.prototype.find and findIndex should skip holes
+        https://bugs.webkit.org/show_bug.cgi?id=132658
+
+        Reviewed by Geoffrey Garen.
+
+        Skip holes in the array when iterating such that callback isn't called.
+
+        * builtins/Array.prototype.js:
+        (find):
+        (findIndex):
+
+2014-05-21  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
+
+        REGRESSION(r169092 and r169102): Skip failing JSC tests on ARM64 properly
+        https://bugs.webkit.org/show_bug.cgi?id=133149
+
+        Reviewed by Csaba Osztrogonác.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2014-05-20  Geoffrey Garen  <ggaren@apple.com>
+
+        Rolled out <http://trac.webkit.org/changeset/166184>
+        https://bugs.webkit.org/show_bug.cgi?id=133144
+
+        Reviewed by Gavin Barraclough.
+
+        It caused a performance regression.
+
+        * heap/BlockAllocator.cpp:
+        (JSC::BlockAllocator::blockFreeingThreadStartFunc):
+
+2014-05-20  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG prediction propagation should agree with fixup phase over the return type of GetByVal
+        https://bugs.webkit.org/show_bug.cgi?id=133134
+
+        Reviewed by Mark Hahnenberg.
+        
+        Make prediction propagator use ArrayMode refinement to decide the return type.
+        
+        Also introduce a heap prediction intrinsic that allows us to test weird corner cases
+        like this. The only way we'll see a mismatch like this in the real world is probably
+        through a gnarly race condition.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::setHeapPrediction):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionFalse1):
+        (functionFalse2):
+        (functionUndefined1):
+        (functionUndefined2):
+        (functionFalse): Deleted.
+        (functionOtherFalse): Deleted.
+        (functionUndefined): Deleted.
+        * runtime/Intrinsic.h:
+        * tests/stress/get-by-val-double-predicted-int.js: Added.
+        (foo):
+
+2014-05-20  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Watchdog timer should be lazily allocated
+        https://bugs.webkit.org/show_bug.cgi?id=133135
+
+        Reviewed by Geoffrey Garen.
+
+        We incur a noticeable amount of overhead on some benchmarks due to checking if the Watchdog ever fired. 
+        There is no reason to do this checking if we never activated the Watchdog, which can only be done through 
+        JSContextGroupSetExecutionTimeLimit or JSContextGroupClearExecutionTimeLimit. 
+
+        By allocating the Watchdog lazily on the VM we can avoid all of the associated overhead when we don't use 
+        these two API functions (which is true of most clients).
+
+        * API/JSContextRef.cpp:
+        (JSContextGroupSetExecutionTimeLimit):
+        (JSContextGroupClearExecutionTimeLimit):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_loop_hint):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/VM.h:
+        * runtime/Watchdog.cpp:
+        (JSC::Watchdog::Scope::Scope): Deleted.
+        (JSC::Watchdog::Scope::~Scope): Deleted.
+        * runtime/Watchdog.h:
+        (JSC::Watchdog::Scope::Scope):
+        (JSC::Watchdog::Scope::~Scope):
+
+2014-05-19  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSArray::shiftCountWith* could be more efficient
+        https://bugs.webkit.org/show_bug.cgi?id=133011
+
+        Reviewed by Geoffrey Garen.
+
+        Our current implementations of shiftCountWithAnyIndexingType and shiftCountWithArrayStorage 
+        are scared of the presence of any holes in the array. We can mitigate this somewhat by enabling 
+        them to correctly handle holes, thus avoiding the slowest of slow paths in most cases.
+
+        * runtime/ArrayStorage.h:
+        (JSC::ArrayStorage::indexingHeader):
+        (JSC::ArrayStorage::length):
+        (JSC::ArrayStorage::hasHoles):
+        * runtime/IndexingHeader.h:
+        (JSC::IndexingHeader::publicLength):
+        (JSC::IndexingHeader::from):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::shiftCountWithArrayStorage):
+        (JSC::JSArray::shiftCountWithAnyIndexingType):
+        (JSC::JSArray::unshiftCountWithArrayStorage):
+        * runtime/JSArray.h:
+        (JSC::JSArray::shiftCountForShift):
+        (JSC::JSArray::shiftCountForSplice):
+        (JSC::JSArray::shiftCount):
+        * runtime/Structure.cpp:
+        (JSC::Structure::holesRequireSpecialBehavior):
+        * runtime/Structure.h:
+
+2014-05-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Test gardening: skip some failing tests on not-X86.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2014-05-19  Mark Lam  <mark.lam@apple.com>
+
+        operationOptimize() should defer the GC for a while.
+        <https://webkit.org/b/133103>
+
+        Reviewed by Filip Pizlo.
+
+        Currently, operationOptimize() only defers the GC until its end.  As a result,
+        a GC may be triggered just before we return from operationOptimize(), and it may
+        jettison the optimize codeBlock that we're planning to OSR enter into when we
+        return from this function.  This is because the OSR entry on-ramp code hasn't
+        been executed yet, and hence, there is not yet a reference to this new codeBlock
+        from the stack, and there won't be until we've had a chance to return out of
+        operationOptimize() to run the OSR entry on-ramp code.
+
+        This issue is now fixed by using DeferGCForAWhile instead of DeferGC.  This
+        ensures that the GC will be deferred until after the OSR entry on-ramp can be
+        executed.
+
+        * jit/JITOperations.cpp:
+
+2014-05-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Take care of some ARM64 test failures
+        https://bugs.webkit.org/show_bug.cgi?id=133090
+
+        Reviewed by Geoffrey Garen.
+        
+        Constant blinding on ARM64 cannot use the scratch register.
+
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::convertInt32ToDouble):
+        (JSC::MacroAssembler::branchPtr):
+        (JSC::MacroAssembler::storePtr):
+        (JSC::MacroAssembler::store64):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::scratchRegisterForBlinding):
+
+2014-05-19  Tanay C  <tanay.c@samsung.com>
+
+        Removing some check-webkit-style warnings from ./dfg
+        https://bugs.webkit.org/show_bug.cgi?id=132854
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGAbstractInterpreter.h:
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGBlockInsertionSet.h:
+        * dfg/DFGCommonData.h:
+        * dfg/DFGDominators.h:
+        * dfg/DFGGraph.h:
+        * dfg/DFGInPlaceAbstractState.h:
+        * dfg/DFGPredictionPropagationPhase.h:
+
+2014-05-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, remove bogus comment. We already made the FTL use our calling convention.
+        That was a long time ago.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileReturn):
+
+2014-05-18  Rik Cabanier  <cabanier@adobe.com>
+
+        support for navigator.hardwareConcurrency
+        https://bugs.webkit.org/show_bug.cgi?id=132588
+
+        Reviewed by Filip Pizlo.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-05-16  Michael Saboff  <msaboff@apple.com>
+
+        Crash in JSC::Yarr::YarrGenerator<(JSC::Yarr::YarrJITCompileMode)0>::generatePatternCharacterFixed() due to WTF::CrashOnOverflow::overflowed + 9
+        https://bugs.webkit.org/show_bug.cgi?id=133009
+
+        Reviewed by Oliver Hunt.
+
+        If we determine that any alternative requires a minumum match size greater than
+        INT_MAX, we handle the match in the interpreter.
+
+        Check to see if the pattern has unsigned lengths before invoking YARR JIT.
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::compile):
+        (JSC::RegExp::compileMatchOnly):
+
+        * tests/stress/large-regexp.js: New test added.
+
+        Set m_containsUnsignedLengthPattern flag if any alternative's minimum length
+        doesn't fit in an int.
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
+
+        Clear new m_containsUnsignedLengthPattern flag.
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::YarrPattern::YarrPattern):
+        * yarr/YarrPattern.h:
+        (JSC::Yarr::YarrPattern::reset):
+        (JSC::Yarr::YarrPattern::containsUnsignedLengthPattern):
+
+2014-05-15  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSDOMWindow should not claim HasImpureGetOwnPropertySlot
+        https://bugs.webkit.org/show_bug.cgi?id=132918
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/Repatch.cpp:
+        (JSC::tryRepatchIn): We forgot to check for watchpoints when repatching "in".
+
+2014-05-15  Alex Christensen  <achristensen@webkit.org>
+
+        Add pointer lock to features without enabling it.
+        https://bugs.webkit.org/show_bug.cgi?id=132961
+
+        Reviewed by Sam Weinig.
+
+        * Configurations/FeatureDefines.xcconfig:
+        Added ENABLE_POINTER_LOCK to list of features.
+
+2014-05-14  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Inline caching for proxies clobbers baseGPR too early
+        https://bugs.webkit.org/show_bug.cgi?id=132916
+
+        Reviewed by Filip Pizlo.
+
+        We clobber baseGPR prior to the Structure checks, so if any of the checks fail then the slow path 
+        gets the target of the proxy rather than the proxy itself. We need to delay the clobbering of baseGPR 
+        until we know the inline cache is going to succeed.
+
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+
+2014-05-14  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed build fix.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: This solution
+        was missing commands to build LLInt portions of JSC.
+        * llint/LLIntData.cpp: 64-bit build fix.
+
+2014-05-14  Martin Hodovan <mhodovan.u-szeged@partner.samsung.com>
+
+        ARM Traditional buildfix after r168776.
+        https://bugs.webkit.org/show_bug.cgi?id=132903
+
+        Reviewed by Darin Adler.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::abortWithReason): Added.
+
+2014-05-14  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Remove CSS_STICKY_POSITION guards
+        https://bugs.webkit.org/show_bug.cgi?id=132676
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-05-13  Filip Pizlo  <fpizlo@apple.com>
+
+        JIT breakpoints should be more informative
+        https://bugs.webkit.org/show_bug.cgi?id=132882
+
+        Reviewed by Oliver Hunt.
+        
+        Introduce the notion of an AbortReason, which is a nice enumeration of coded assertion
+        failure names. This means that all you need to figure out why the JIT SIGTRAP'd is to look
+        at that platform's abort reason register (r11 on X86-64 for example).
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/AbortReason.h: Added.
+        * assembler/AbstractMacroAssembler.h:
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::abortWithReason):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::abortWithReason):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::abortWithReason):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::abortWithReason):
+        * dfg/DFGSlowPathGenerator.h:
+        (JSC::DFG::SlowPathGenerator::generate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::bail):
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        (JSC::DFG::SpeculativeJIT::compileMakeRope):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrEntryThunkGenerator):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::jitAssertIsInt32):
+        (JSC::AssemblyHelpers::jitAssertIsJSInt32):
+        (JSC::AssemblyHelpers::jitAssertIsJSNumber):
+        (JSC::AssemblyHelpers::jitAssertIsJSDouble):
+        (JSC::AssemblyHelpers::jitAssertIsCell):
+        (JSC::AssemblyHelpers::jitAssertTagsInPlace):
+        (JSC::AssemblyHelpers::jitAssertHasValidCallFrame):
+        (JSC::AssemblyHelpers::jitAssertIsNull):
+        (JSC::AssemblyHelpers::jitAssertArgumentCountSane):
+        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::checkStackPointerAlignment):
+        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): Deleted.
+        * jit/JIT.h:
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitSlow_op_div):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTINativeCall):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::compileGetDirectOffset):
+        (JSC::JIT::addStructureTransitionCheck): Deleted.
+        (JSC::JIT::testPrototype): Deleted.
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::compileGetDirectOffset):
+        * jit/RegisterPreservationWrapperGenerator.cpp:
+        (JSC::generateRegisterRestoration):
+        * jit/Repatch.cpp:
+        (JSC::addStructureTransitionCheck):
+        (JSC::linkClosureCall):
+        * jit/ThunkGenerators.cpp:
+        (JSC::emitPointerValidation):
+        (JSC::nativeForGenerator):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::generate):
+
+2014-05-13  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win] Enum type with value zero is compatible with void*, potential cause of crashes.
+        https://bugs.webkit.org/show_bug.cgi?id=132772
+
+        Reviewed by Geoffrey Garen.
+
+        Using the MSVC compiler, an instance of an enum type with value zero, is compatible with void* (see bug 132683 for a code example).
+        This has caused crashes on Windows on two occasions (bug 132683, and bug 121001).
+        This patch tries to prevent these type of crashes by using a type with explicit constructors instead of void*.
+        The void* parameter in the loadDouble and storeDouble methods are replaced with TrustedImmPtr.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::loadDouble):
+        (JSC::MacroAssemblerARM::storeDouble):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::loadDouble):
+        (JSC::MacroAssemblerARM64::storeDouble):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::loadDouble):
+        (JSC::MacroAssemblerARMv7::storeDouble):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::loadDouble):
+        (JSC::MacroAssemblerMIPS::storeDouble):
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::loadDouble):
+        (JSC::MacroAssemblerSH4::storeDouble):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::storeDouble):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::absDouble):
+        (JSC::MacroAssemblerX86Common::negateDouble):
+        (JSC::MacroAssemblerX86Common::loadDouble):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentFill):
+        (JSC::DFG::compileClampDoubleToByte):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::purifyNaN):
+        * jit/JITInlines.h:
+        (JSC::JIT::emitLoadDouble):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        * jit/ThunkGenerators.cpp:
+        (JSC::floorThunkGenerator):
+        (JSC::roundThunkGenerator):
+        (JSC::powThunkGenerator):
+
+2014-05-12  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r168642.
+        https://bugs.webkit.org/show_bug.cgi?id=132839
+
+        Broke ARM build (Requested by jpfau on #webkit).
+
+        Reverted changeset:
+
+        "[Win] Enum type with value zero is compatible with void*,
+        potential cause of crashes."
+        https://bugs.webkit.org/show_bug.cgi?id=132772
+        http://trac.webkit.org/changeset/168642
+
+2014-05-12  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win] Enum type with value zero is compatible with void*, potential cause of crashes.
+        https://bugs.webkit.org/show_bug.cgi?id=132772
+
+        Reviewed by Geoffrey Garen.
+
+        Using the MSVC compiler, an instance of an enum type with value zero, is compatible with void* (see bug 132683 for a code example).
+        This has caused crashes on Windows on two occasions (bug 132683, and bug 121001).
+        This patch tries to prevent these type of crashes by using a type with explicit constructors instead of void*.
+        The void* parameter in the loadDouble and storeDouble methods are replaced with TrustedImmPtr.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::loadDouble):
+        (JSC::MacroAssemblerARM::storeDouble):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::loadDouble):
+        (JSC::MacroAssemblerARM64::storeDouble):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::loadDouble):
+        (JSC::MacroAssemblerARMv7::storeDouble):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::loadDouble):
+        (JSC::MacroAssemblerMIPS::storeDouble):
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::loadDouble):
+        (JSC::MacroAssemblerSH4::storeDouble):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::storeDouble):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::absDouble):
+        (JSC::MacroAssemblerX86Common::negateDouble):
+        (JSC::MacroAssemblerX86Common::loadDouble):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentFill):
+        (JSC::DFG::compileClampDoubleToByte):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::purifyNaN):
+        * jit/JITInlines.h:
+        (JSC::JIT::emitLoadDouble):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        * jit/ThunkGenerators.cpp:
+        (JSC::floorThunkGenerator):
+        (JSC::roundThunkGenerator):
+        (JSC::powThunkGenerator):
+
+2014-05-12  Andreas Kling  <akling@apple.com>
+
+        0.4% of PLT3 in JSCell::structure() below JSObject::visitChildren().
+        <https://webkit.org/b/132828>
+        <rdar://problem/16886285>
+
+        Reviewed by Michael Saboff.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::visitButterfly):
+        (JSC::JSObject::visitChildren):
+
+            Use JSCell::structure(VM&) to reduce the number of hoops we jump
+            through to find Structures during marking.
+
+2014-05-12  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        [cmake] Add missing FTL source files to the build system.
+
+        Reviewed by Csaba Osztrogonác.
+
+        * CMakeLists.txt:
+
+2014-05-09  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Allow Remote Inspector to entitlement check UIProcess through WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=132409
+
+        Reviewed by Timothy Hatcher.
+
+        Proxy applications are applications which hold WebViews for other
+        applications. The WebProcess (Web Content Service) is a proxy application.
+        For legacy reasons we were supporting a scenario where proxy applications
+        could potentially host WebViews for more then one other application. That
+        was never the case for WebProcess and it is now a scenario we don't need
+        to worry about supporting.
+
+        With this change, a proxy application more naturally only holds WebViews
+        for a single parent / host application. The proxy process can set the
+        parent pid / audit_token data on the RemoteInspector singleton, and
+        that data will be sent on to webinspectord later on to be validated.
+        In the WebProcess<->UIProcess relationship that information is known
+        and set immediately. In the Legacy iOS case that information is set
+        soon after, but not immediately known at the point the WebView is created.
+
+        This allows us to simplify the RemoteInspectorDebuggable interface.
+        We no longer need a pid per-Debuggable.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::setParentProcessInformation):
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        (Inspector::RemoteInspector::listingForDebuggable):
+        (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage):
+        Handle new proxy application setup message, and provide an API
+        for a proxy application to set the parent process information.
+
+        * inspector/remote/RemoteInspectorConstants.h:
+        New setup and response message for proxy applications to pass
+        their parent / host application information to webinspectord.
+
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::info):
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        (Inspector::RemoteInspectorDebuggableInfo::RemoteInspectorDebuggableInfo):
+        (Inspector::RemoteInspectorDebuggableInfo::hasParentProcess): Deleted.
+        pid per debuggable is no longer needed.
+
+2014-05-09  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSDOMWindow should disable property caching after a certain point
+        https://bugs.webkit.org/show_bug.cgi?id=132751
+
+        Reviewed by Filip Pizlo.
+
+        This is part of removing HasImpureGetOwnPropertySlot from JSDOMWindow. After the lookup in the static 
+        hash table for JSDOMWindow fails we want to disable property caching even if the code that follows thinks 
+        that it has provided a cacheable value.
+
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::PropertySlot):
+        (JSC::PropertySlot::isCacheable):
+        (JSC::PropertySlot::disableCaching):
+
+2014-05-09  Andreas Kling  <akling@apple.com>
+
+        8.8% spent in Object.prototype.hasOwnProperty() on sbperftest.
+        <https://webkit.org/b/132749>
+
+        Leverage the fast-resolve-to-AtomicString optimization for JSRopeString
+        in Object.prototype.* by using JSString::toIdentifier() in the cases where
+        we are converting JSString -> String -> Identifier.
+
+        This brings time spent in hasOwnProperty() from 8.8% to 1.3% on
+        "The Great HTML5 Gaming Performance Test: 2014 edition"
+        <http://www.scirra.com/demos/c2/sbperftest/>
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncHasOwnProperty):
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+
+2014-05-08  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSDOMWindow should have a WatchpointSet to fire on window close
+        https://bugs.webkit.org/show_bug.cgi?id=132721
+
+        Reviewed by Filip Pizlo.
+
+        This patch allows us to reset the inline caches that assumed they could skip 
+        the first part of JSDOMWindow::getOwnPropertySlot that checks if the window has 
+        been closed. This is part of getting rid of HasImpureGetOwnPropertySlot on JSDOMWindow.
+
+        PropertySlot now accepts a WatchpointSet which the inline cache code can look for
+        to see if it should create a new Watchpoint for that particular inline cache site.
+
+        * bytecode/Watchpoint.h:
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::PropertySlot):
+        (JSC::PropertySlot::watchpointSet):
+        (JSC::PropertySlot::setWatchpointSet):
+
+2014-05-09  Tanay C  <tanay.c@samsung.com>
+
+        Fix build warning (uninitialized variable) in DFGFixupPhase.cpp 
+        https://bugs.webkit.org/show_bug.cgi?id=132331
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+
+2014-05-09  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win] Crash when enabling DFG JIT.
+        https://bugs.webkit.org/show_bug.cgi?id=132683
+
+        Reviewed by Geoffrey Garen.
+
+        On windows, using register GPRInfo::regT0 as parameter to e.g. JIT::storeDouble(..., GPRInfo::regT0)),
+        results in a call to JIT::storeDouble(FPRegisterID src, const void* address),
+        where the address parameter gets the value of GPRInfo::regT0, which is 0 (eax on Windows).
+        This causes the register to be written to address 0, hence the crash.
+
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): Use address in regT0 as parameter.
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): Ditto.
+
+2014-05-09  Martin Hodovan <mhodovan.u-szeged@partner.samsung.com>
+
+        REGRESSION(r167094): JSC crashes on ARM Traditional
+        https://bugs.webkit.org/show_bug.cgi?id=132738
+
+        Reviewed by Zoltan Herczeg.
+
+        PC is two instructions ahead of the current instruction
+        on ARM Traditional, so the distance is 8 bytes not 2.
+
+        * llint/LowLevelInterpreter.asm:
+
+2014-05-09  Alberto Garcia  <berto@igalia.com>
+
+        jsmin.py license header confusing, mentions non-free license
+        https://bugs.webkit.org/show_bug.cgi?id=123665
+
+        Reviewed by Darin Adler.
+
+        Pull the most recent version from upstream, which has a clear
+        license.
+
+        * inspector/scripts/jsmin.py:
+
+2014-05-08  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Base case for get-by-id inline cache doesn't check for HasImpureGetOwnPropertySlot
+        https://bugs.webkit.org/show_bug.cgi?id=132695
+
+        Reviewed by Filip Pizlo.
+
+        We check in the case where we're accessing something other than the base object (e.g. the prototype), 
+        but we fail to do so for the base object.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        * jsc.cpp: Added some infrastructure to support this test. We don't currently trigger this bug anywhere in WebKit
+        because all of the values that are returned that could be impure are set to uncacheable anyways.
+        (WTF::ImpureGetter::ImpureGetter):
+        (WTF::ImpureGetter::createStructure):
+        (WTF::ImpureGetter::create):
+        (WTF::ImpureGetter::finishCreation):
+        (WTF::ImpureGetter::getOwnPropertySlot):
+        (WTF::ImpureGetter::visitChildren):
+        (WTF::ImpureGetter::setDelegate):
+        (GlobalObject::finishCreation):
+        (functionCreateImpureGetter):
+        (functionSetImpureGetterDelegate):
+        * tests/stress/impure-get-own-property-slot-inline-cache.js: Added.
+        (foo):
+
+2014-05-08  Filip Pizlo  <fpizlo@apple.com>
+
+        deleteAllCompiledCode() shouldn't use the suspension worklist
+        https://bugs.webkit.org/show_bug.cgi?id=132708
+
+        Reviewed by Mark Hahnenberg.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::isStillValid):
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllCompiledCode):
+
+2014-05-08  Filip Pizlo  <fpizlo@apple.com>
+
+        SSA conversion should delete PhantomLocals for captured variables
+        https://bugs.webkit.org/show_bug.cgi?id=132693
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGCommon.cpp:
+        (JSC::DFG::startCrashing): Parallel JIT and a JIT bug means that we man dump IR in parallel. This is the workaround. This patch uses it in all of the places where we dump IR and crash.
+        * dfg/DFGCommon.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge): Use the workaround.
+        * dfg/DFGLivenessAnalysisPhase.cpp:
+        (JSC::DFG::LivenessAnalysisPhase::run): Use the workaround.
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run): Fix the bug - it's true that PhantomLocal for captured variables doesn't need anything done to it, but it's wrong that we didn't delete it outright.
+        * dfg/DFGValidate.cpp: Use the workaround.
+        * tests/stress/phantom-local-captured-but-not-flushed-to-ssa.js: Added.
+        (foo):
+        (bar):
+
+2014-05-07  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r168451.
+        https://bugs.webkit.org/show_bug.cgi?id=132670
+
+        Not a speed-up, just do what other compilers do. (Requested by
+        kling on #webkit).
+
+        Reverted changeset:
+
+        "[X86] Emit BT instruction for single-bit tests."
+        https://bugs.webkit.org/show_bug.cgi?id=132650
+        http://trac.webkit.org/changeset/168451
+
+2014-05-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Make Executable::clearCode() actually clear all of the entrypoints, and
+        clean up some other FTL-related calling convention stuff.
+        <rdar://problem/16720172>
+
+        Rubber stamped by Mark Hahnenberg.
+
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::Worklist):
+        (JSC::DFG::Worklist::finishCreation):
+        (JSC::DFG::Worklist::create):
+        (JSC::DFG::ensureGlobalDFGWorklist):
+        (JSC::DFG::ensureGlobalFTLWorklist):
+        * dfg/DFGWorklist.h:
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::dump):
+        * heap/CodeBlockSet.h:
+        * runtime/Executable.cpp:
+        (JSC::ExecutableBase::clearCode):
+
+2014-05-07  Andreas Kling  <akling@apple.com>
+
+        [X86] Emit BT instruction for single-bit tests.
+        <https://webkit.org/b/132650>
+
+        Implement test-bit-and-branch slightly more efficiently by using
+        BT + JC/JNC instead of TEST + JZ/JNZ when we're only testing for
+        a single bit.
+
+        Reviewed by Michael Saboff.
+
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::singleBitIndex):
+        (JSC::MacroAssemblerX86Common::branchTest32):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::bt_i8r):
+        (JSC::X86Assembler::bt_i8m):
+
+2014-05-07  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(r166678): Dromaeo/cssquery-dojo.html crashes regularly.
+        <https://webkit.org/b/131356>
+
+        Reviewed by Geoffrey Garen.
+
+        The issue is that GC needs to be made aware of writes to m_inferredValue
+        in the VariableWatchpointSet, but was not.  As a result, if a JSCell*
+        is written to a VariableWatchpointSet m_inferredValue, and that JSCell
+        does not survive an eden GC shortly after, we will end up with a stale
+        JSCell pointer left in the m_inferredValue.
+
+        This issue can be detected more easily by running Dromaeo/cssquery-dojo.html
+        using DumpRenderTree with the VM heap in zombie mode.
+
+        The fix is to change VariableWatchpointSet m_inferredValue to type
+        WriteBarrier<Unknown> and ensure that VariableWatchpointSet::notifyWrite()
+        is executed by all the execution engines so that the WriteBarrier semantics
+        are honored.
+
+        We still check if the value to be written is the same as the one in the
+        inferredValue.  We'll by-pass calling the slow path notifyWrite() if the
+        values are the same.        
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        - need to pass the symbolTable to prepareToWatch() because it will be needed
+          for instantiating the VariableWatchpointSet in prepareToWatch().
+
+        * bytecode/VariableWatchpointSet.h:
+        (JSC::VariableWatchpointSet::VariableWatchpointSet):
+        - VariableWatchpointSet now tracks its owner symbol table for its m_inferredValue
+          write barrier, and yes, m_inferredValue is now of type WriteBarrier<Unknown>.
+        (JSC::VariableWatchpointSet::inferredValue):
+        (JSC::VariableWatchpointSet::invalidate):
+        (JSC::VariableWatchpointSet::finalizeUnconditionally):
+        (JSC::VariableWatchpointSet::addressOfInferredValue):
+        (JSC::VariableWatchpointSet::notifyWrite): Deleted.
+        * bytecode/VariableWatchpointSetInlines.h: Added.
+        (JSC::VariableWatchpointSet::notifyWrite):
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::cellConstant):
+        - Added an assert in case we try to make constants of zombified JSCells again.
+
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        - We now let the slow path handle the cases when the VariableWatchpointSet is
+          in state ClearWatchpoint and IsWatched, and the slow path will ensure that
+          we handle the needed write barrier semantics correctly.
+          We will by-pass the slow path if the value being written is the same as the
+          inferred value.
+
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNotifyWrite):
+        - Let the slow path handle the cases when the VariableWatchpointSet is
+          in state ClearWatchpoint and IsWatched.
+          We will by-pass the slow path if the value being written is the same as the
+          inferred value.
+
+        * heap/Heap.cpp:
+        (JSC::Zombify::operator()):
+        - Use a different value for the zombified bits (to distinguish it from 0xbbadbeef
+          which is used everywhere else).
+        * heap/Heap.h:
+        (JSC::Heap::isZombified):
+        - Provide a convenience test function to check if JSCells are zombified.  This is
+          currently only used in an assertion in the DFG bytecode parser, but the intent
+          it that we'll apply this test in other strategic places later to help with early
+          detection of usage of GC'ed objects when we run in zombie mode.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emitSlow_op_captured_mov):
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitNotifyWrite):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitNotifyWrite):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        - Let the slow path for notifyWrite handle the cases when the VariableWatchpointSet
+          is in state ClearWatchpoint and IsWatched.
+          We will by-pass the slow path if the value being written is the same as the
+          inferred value.
+        
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        - Let the slow path for notifyWrite handle the cases when the VariableWatchpointSet
+          is in state ClearWatchpoint and IsWatched.
+          We will by-pass the slow path if the value being written is the same as the
+          inferred value.
+        
+        * runtime/CommonSlowPaths.cpp:
+
+        * runtime/JSCJSValue.h: Fixed some typos in the comments.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::prepareToWatch):
+        (JSC::SymbolTableEntry::notifyWriteSlow):
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTableEntry::notifyWrite):
+
+2014-05-06  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewd build fix for C-LOOP after r168396.
+
+        * runtime/TestRunnerUtils.cpp:
+        (JSC::optimizeNextInvocation): Wrapped actual call inside #if ENABLE(JIT)
+
+2014-05-06  Michael Saboff  <msaboff@apple.com>
+
+        Add test for deleteAllCompiledCode
+        https://bugs.webkit.org/show_bug.cgi?id=132632
+
+        Reviewed by Phil Pizlo.
+
+        Added two new hooks to jsc, one to call Heap::deleteAllCompiledCode() and
+        the other to call CodeBlock::optimizeNextInvocation().  Used these two hooks
+        to write a test that will queue up loads of DFG compiles and then call
+        Heap::deleteAllCompiledCode() to make sure that it can handle compiled
+        code as well as code being compiled.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionDeleteAllCompiledCode):
+        (functionOptimizeNextInvocation):
+        * runtime/TestRunnerUtils.cpp:
+        (JSC::optimizeNextInvocation):
+        * runtime/TestRunnerUtils.h:
+        * tests/stress/deleteAllCompiledCode.js: Added.
+        (functionList):
+        (runTest):
+
+2014-05-06  Andreas Kling  <akling@apple.com>
+
+        JSString::toAtomicString() should return AtomicString.
+        <https://webkit.org/b/132627>
+
+        Remove premature optimization where I was trying to avoid refcount
+        churn when returning an already atomicized String.
+
+        Instead of using reinterpret_cast to mangle the String member into
+        a const AtomicString& return value, just return AtomicString.
+
+        Reviewed by Geoff Garen.
+
+        * runtime/JSString.h:
+        (JSC::JSString::toAtomicString):
+
+2014-05-06  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Roll out r167889
+
+        Rubber stamped by Geoff Garen.
+
+        It broke some websites.
+
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::create):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::hasDeletedOffset):
+        (JSC::PropertyTable::hadDeletedOffset): Deleted.
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::Structure::removePropertyTransition):
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::removePropertyWithoutTransition):
+        (JSC::Structure::pin):
+        (JSC::Structure::pinAndPreventTransitions): Deleted.
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        (JSC::Structure::propertyTable):
+        (JSC::Structure::checkOffsetConsistency):
+        (JSC::Structure::hadDeletedOffsets): Deleted.
+        * tests/stress/for-in-after-delete.js:
+        (foo): Deleted.
+
+2014-05-05  Andreas Kling  <akling@apple.com>
+
+        Fix debug build.
+
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::fastGetOwnProperty):
+
+2014-05-05  Andreas Kling  <akling@apple.com>
+
+        Optimize GetByVal when subscript is a rope string.
+        <https://webkit.org/b/132590>
+
+        Use JSString::toIdentifier() in the various GetByVal implementations
+        to try and avoid allocating extra strings.
+
+        Added canUseFastGetOwnProperty() and wrap calls to fastGetOwnProperty()
+        in that, to avoid calling JSString::value() which always resolves ropes
+        into new strings and de-optimizes subsequent toIdentifier() calls.
+
+        My iMac says ~9% progression on Dromaeo/dom-attr.html
+
+        Reviewed by Phil Pizlo.
+
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::fastGetOwnProperty):
+        (JSC::JSCell::canUseFastGetOwnProperty):
+
+2014-05-05  Andreas Kling  <akling@apple.com>
+
+        REGRESSION (r168256): ASSERTION FAILED: (buffer + m_length) == position loading vanityfair.com article.
+        <https://webkit.org/b/168256>
+        <rdar://problem/16816316>
+
+        Make resolveRopeSlowCase8() behave like its 16-bit counterpart and not
+        clear the fibers. The caller takes care of this.
+
+        Test: fast/dom/getElementById-with-rope-string-arg.html
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeSlowCase8):
+
+2014-05-05  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION: RELEASE_ASSERT in CodeBlock::baselineVersion @ cnn.com
+        https://bugs.webkit.org/show_bug.cgi?id=132581
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::isStillValid): Check that the alternative codeBlock we
+        started compiling for is still the same at the end of compilation.
+        Also did some minor restructuring.
+
+2014-05-05  Andreas Kling  <akling@apple.com>
+
+        Optimize PutByVal when subscript is a rope string.
+        <https://webkit.org/b/132572>
+
+        Add a JSString::toIdentifier() that is smarter when the JSString is
+        really a rope string. Use this in baseline & DFG's PutByVal to avoid
+        allocating new StringImpls that we immediately deduplicate anyway.
+
+        Reviewed by Antti Koivisto.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * jit/JITOperations.cpp:
+        * runtime/JSString.h:
+        (JSC::JSString::toIdentifier):
+
+2014-05-05  Andreas Kling  <akling@apple.com>
+
+        Remove two now-incorrect assertions after r168256.
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeSlowCase8):
+        (JSC::JSRopeString::resolveRopeSlowCase):
+
+2014-05-04  Andreas Kling  <akling@apple.com>
+
+        Optimize JSRopeString for resolving directly to AtomicString.
+        <https://webkit.org/b/132548>
+
+        If we know that the JSRopeString we are resolving is going to be used
+        as an AtomicString, we can try to avoid creating a new string.
+
+        We do this by first resolving the rope into a stack buffer, and using
+        that buffer as a key into the AtomicString table. If there is already
+        an AtomicString with the same characters, we reuse that instead of
+        constructing a new StringImpl.
+
+        JSString gains these two public functions:
+
+        - AtomicString toAtomicString()
+
+            Returns an AtomicString, tries to avoid allocating a new string
+            if possible.
+
+        - AtomicStringImpl* toExistingAtomicString()
+
+            Returns a non-null AtomicStringImpl* if one already exists in the
+            AtomicString table. If none is found, the rope is left unresolved.
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeInternal8):
+        (JSC::JSRopeString::resolveRopeInternal16):
+        (JSC::JSRopeString::resolveRopeToAtomicString):
+        (JSC::JSRopeString::clearFibers):
+        (JSC::JSRopeString::resolveRopeToExistingAtomicString):
+        (JSC::JSRopeString::resolveRope):
+        (JSC::JSRopeString::outOfMemory):
+        * runtime/JSString.h:
+        (JSC::JSString::toAtomicString):
+        (JSC::JSString::toExistingAtomicString):
+
+2014-05-04  Andreas Kling  <akling@apple.com>
+
+        Unreviewed, rolling out r168254.
+
+        Very crashy on debug JSC tests.
+
+        Reverted changeset:
+
+        "jsSubstring() should be lazy"
+        https://bugs.webkit.org/show_bug.cgi?id=132556
+        http://trac.webkit.org/changeset/168254
+
+2014-05-04  Filip Pizlo  <fpizlo@apple.com>
+
+        jsSubstring() should be lazy
+        https://bugs.webkit.org/show_bug.cgi?id=132556
+
+        Reviewed by Andreas Kling.
+        
+        jsSubstring() is now lazy by using a special rope that is a substring instead of a
+        concatenation. To make this patch super simple, we require that a substring's base is
+        never a rope. Hence, when resolving a rope, we either go down a non-recursive substring
+        path, or we go down a concatenation path which may see exactly one level of substrings in
+        its fibers.
+        
+        This is up to a 50% speed-up on microbenchmarks and a 10% speed-up on Octane/regexp.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::specializedSweep):
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::visitFibers):
+        (JSC::JSRopeString::resolveRope):
+        (JSC::JSRopeString::resolveRopeSlowCase8):
+        (JSC::JSRopeString::resolveRopeSlowCase):
+        (JSC::JSRopeString::outOfMemory):
+        * runtime/JSString.h:
+        (JSC::JSRopeString::finishCreation):
+        (JSC::JSRopeString::append):
+        (JSC::JSRopeString::create):
+        (JSC::JSRopeString::offsetOfFibers):
+        (JSC::JSRopeString::fiber):
+        (JSC::JSRopeString::substringBase):
+        (JSC::JSRopeString::substringOffset):
+        (JSC::JSRopeString::substringSentinel):
+        (JSC::JSRopeString::isSubstring):
+        (JSC::jsSubstring):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::RegExpMatchesArray::reifyAllProperties):
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncSubstring):
+
+2014-05-02  Michael Saboff  <msaboff@apple.com>
+
+        "arm64 function not 4-byte aligned" warnings when building JSC
+        https://bugs.webkit.org/show_bug.cgi?id=132495
+
+        Reviewed by Geoffrey Garen.
+
+        Added ".align 4" for both ARM Thumb2 and ARM 64 to silence the linker.
+
+        * llint/LowLevelInterpreter.cpp:
+
+2014-05-02  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Fix cloop build after r168178
+
+        * bytecode/CodeBlock.cpp:
+
+2014-05-01  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Add a DFG function whitelist
+        https://bugs.webkit.org/show_bug.cgi?id=132437
+
+        Reviewed by Geoffrey Garen.
+
+        Often times when debugging, using bytecode ranges isn't enough to narrow down to the 
+        particular DFG block that's causing issues. This patch adds the ability to whitelist 
+        specific functions specified in a file to enable further filtering without having to recompile.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupported):
+        (JSC::DFG::mightInlineFunctionForCall):
+        (JSC::DFG::mightInlineFunctionForClosureCall):
+        (JSC::DFG::mightInlineFunctionForConstruct):
+        * dfg/DFGFunctionWhitelist.cpp: Added.
+        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
+        (JSC::DFG::FunctionWhitelist::FunctionWhitelist):
+        (JSC::DFG::FunctionWhitelist::parseFunctionNamesInFile):
+        (JSC::DFG::FunctionWhitelist::contains):
+        * dfg/DFGFunctionWhitelist.h: Added.
+        * runtime/Options.cpp:
+        (JSC::parse):
+        (JSC::Options::dumpOption):
+        * runtime/Options.h:
+
+2014-05-02  Filip Pizlo  <fpizlo@apple.com>
+
+        DFGAbstractInterpreter should not claim Int52 arithmetic creates Int52s
+        https://bugs.webkit.org/show_bug.cgi?id=132446
+
+        Reviewed by Mark Hahnenberg.
+        
+        Basically any arithmetic operation can turn an Int52 into an Int32 or vice-versa, and
+        our modeling of Int52Rep nodes is such that they can have either Int32 or Int52 type
+        to indicate a bound on the value. This is useful for knowing, for example, that
+        Int52Rep(Int32:) returns a value that cannot be outside the Int32 range. Also,
+        ValueRep(Int52Rep:) uses this to determine whether it may return a double or an int.
+        But this means that all arithmetic operations must be careful to note that they may
+        turn Int32 inputs into an Int52 output or vice-versa, as these new tests show.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::makeSafe):
+        * tests/stress/int52-ai-add-then-filter-int32.js: Added.
+        (foo):
+        * tests/stress/int52-ai-mul-and-clean-neg-zero-then-filter-int32.js: Added.
+        (foo):
+        * tests/stress/int52-ai-mul-then-filter-int32-directly.js: Added.
+        (foo):
+        * tests/stress/int52-ai-mul-then-filter-int32.js: Added.
+        (foo):
+        * tests/stress/int52-ai-neg-then-filter-int32.js: Added.
+        (foo):
+        * tests/stress/int52-ai-sub-then-filter-int32.js: Added.
+        (foo):
+
+2014-05-01  Geoffrey Garen  <ggaren@apple.com>
+
+        JavaScriptCore fails to build with some versions of clang
+        https://bugs.webkit.org/show_bug.cgi?id=132436
+
+        Reviewed by Anders Carlsson.
+
+        * runtime/ArgumentsIteratorConstructor.cpp: Since we call
+        putDirectWithoutTransition, and it calls putWillGrowOutOfLineStorage,
+        and both are marked inline, it's valid for the compiler to decide
+        to inline both and emit neither in the binary. Therefore, we need
+        both inline definitions to be available in the translation unit at
+        compile time, or we'll try to link against a function that doesn't exist.
+
+2014-05-01  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167964.
+        https://bugs.webkit.org/show_bug.cgi?id=132431
+
+        Memory improvements should not regress memory usage (Requested
+        by olliej on #webkit).
+
+        Reverted changeset:
+
+        "Don't hold on to parameter BindingNodes forever"
+        https://bugs.webkit.org/show_bug.cgi?id=132360
+        http://trac.webkit.org/changeset/167964
+
+2014-05-01  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix trivial debug-only race-that-crashes in CallLinkStatus and explain why the remaining races are totally awesome
+        https://bugs.webkit.org/show_bug.cgi?id=132427
+
+        Reviewed by Mark Hahnenberg.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+
+2014-04-30  Simon Fraser  <simon.fraser@apple.com>
+
+        Remove ENABLE_PLUGIN_PROXY_FOR_VIDEO
+        https://bugs.webkit.org/show_bug.cgi?id=132396
+
+        Reviewed by Eric Carlson.
+
+        Remove ENABLE_PLUGIN_PROXY_FOR_VIDEO and related code.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-04-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Argument flush formats should not be presumed to be JSValue since 'this' is weird
+        https://bugs.webkit.org/show_bug.cgi?id=132404
+
+        Reviewed by Michael Saboff.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock): Don't assume that arguments are flushed as JSValue. Use the logic for locals instead.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): SetArgument "changes" the format because before this we wouldn't know we had arguments.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): Ditto.
+        * dfg/DFGValueSource.cpp:
+        (JSC::DFG::ValueSource::dumpInContext): Make this easier to dump.
+        * dfg/DFGValueSource.h:
+        (JSC::DFG::ValueSource::operator!): Make this easier to dump because Operands<T> uses T::operator!().
+        * ftl/FTLOSREntry.cpp:
+        (JSC::FTL::prepareOSREntry): This had a useful assertion for everything except 'this'.
+        * tests/stress/strict-to-this-int.js: Added.
+        (foo):
+        (Number.prototype.valueOf):
+        (test):
+
+2014-04-29  Oliver Hunt  <oliver@apple.com>
+
+        Don't hold on to parameterBindingNodes forever
+        https://bugs.webkit.org/show_bug.cgi?id=132360
+
+        Reviewed by Geoffrey Garen.
+
+        Don't keep the parameter nodes anymore. Instead we store the
+        original parameter string and reparse whenever we actually
+        need them. Because we only actually need them for compilation
+        this only results in a single extra parse.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedFunctionExecutable::visitChildren):
+        (JSC::UnlinkedFunctionExecutable::finishCreation):
+        (JSC::UnlinkedFunctionExecutable::paramString):
+        (JSC::UnlinkedFunctionExecutable::parameters):
+        (JSC::UnlinkedFunctionExecutable::parameterCount): Deleted.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::create):
+        (JSC::UnlinkedFunctionExecutable::parameterCount):
+        (JSC::UnlinkedFunctionExecutable::parameters): Deleted.
+        (JSC::UnlinkedFunctionExecutable::finishCreation): Deleted.
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::ASTBuilder):
+        (JSC::ASTBuilder::setFunctionBodyParameters):
+        * parser/Nodes.h:
+        (JSC::FunctionBodyNode::parametersStartOffset):
+        (JSC::FunctionBodyNode::parametersEndOffset):
+        (JSC::FunctionBodyNode::setParameterLocation):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::parseParameters):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/SourceCode.h:
+        (JSC::SourceCode::subExpression):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::setFunctionBodyParameters):
+
+2014-04-29  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSProxies should be cacheable
+        https://bugs.webkit.org/show_bug.cgi?id=132351
+
+        Reviewed by Geoffrey Garen.
+
+        Whenever we encounter a proxy in an inline cache we should try to cache on the 
+        proxy's target instead of giving up.
+
+        This patch adds support for a simple "recursive" inline cache if the base object
+        we're accessing is a pure forwarding proxy. JSGlobalObject and its subclasses 
+        are the only ones to benefit from this right now.
+
+        This is performance neutral on the benchmarks we track. Currently we won't
+        cache on JSDOMWindow due to HasImpureGetOwnPropertySlot, but this issue will be fixed soon.
+
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionCreateProxy):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::isNormalized):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::isProxy):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::finishCreation):
+        * runtime/JSProxy.h:
+        (JSC::JSProxy::createStructure):
+        (JSC::JSProxy::targetOffset):
+        * runtime/JSType.h:
+        * runtime/Operations.h:
+        (JSC::isPrototypeChainNormalized):
+        * runtime/Structure.h:
+        (JSC::Structure::isProxy):
+        * tests/stress/proxy-inline-cache.js: Added.
+        (cacheOnTarget.getX):
+        (cacheOnTarget):
+        (cacheOnPrototypeOfTarget.getX):
+        (cacheOnPrototypeOfTarget):
+        (dontCacheOnProxyInPrototypeChain.getX):
+        (dontCacheOnProxyInPrototypeChain):
+        (dontCacheOnTargetOfProxyInPrototypeChainOfTarget.getX):
+        (dontCacheOnTargetOfProxyInPrototypeChainOfTarget):
+
+2014-04-29  Filip Pizlo  <fpizlo@apple.com>
+
+        Use LLVM as a backend for the fourth-tier DFG JIT (a.k.a. the FTL JIT)
+        https://bugs.webkit.org/show_bug.cgi?id=112840
+
+        Rubber stamped by Geoffrey Garen.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-04-29  Geoffrey Garen  <ggaren@apple.com>
+
+        String.prototype.trim removes U+200B from strings.
+        https://bugs.webkit.org/show_bug.cgi?id=130184
+
+        Reviewed by Michael Saboff.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::trimString):
+        (JSC::isTrimWhitespace): Deleted.
+
+2014-04-29  Mark Lam  <mark.lam@apple.com>
+
+        Zombifying sweep should ignore retired blocks.
+        <https://webkit.org/b/132344>
+
+        Reviewed by Mark Hahnenberg.
+
+        By definition, retired blocks do not have "dead" objects, or at least
+        none that we know of yet until the next marking phase has been run
+        over it.  So, we should not be sweeping them (even for zombie mode).
+
+        * heap/Heap.cpp:
+        (JSC::Heap::zombifyDeadObjects):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::zombifySweep):
+        * heap/MarkedSpace.h:
+        (JSC::ZombifySweep::operator()):
+
+2014-04-29  Mark Lam  <mark.lam@apple.com>
+
+        Fix bit rot in zombie mode heap code.
+        <https://webkit.org/b/132342>
+
+        Reviewed by Mark Hahnenberg.
+
+        Need to enter a DelayedReleaseScope before doing a sweep.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::zombifyDeadObjects):
+
+2014-04-29  Tomas Popela  <tpopela@redhat.com>
+
+        LLINT loadisFromInstruction doesn't need special case for big endians
+        https://bugs.webkit.org/show_bug.cgi?id=132330
+
+        Reviewed by Mark Lam.
+
+        The change introduced in r167076 was wrong. We should not apply the offset
+        adjustment on loadisFromInstruction usage as the instruction
+        (UnlinkedInstruction) is declared as an union (i.e. with the int32_t
+        operand variable). The offset of the other union members will be the
+        same as the offset of the first one, that is 0. The behavior here is the
+        same on little and big endian architectures. Thus we don't need
+        special case for big endians.
+
+        * llint/LowLevelInterpreter.asm:
+
+2014-04-28  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Simplify tryCacheGetById
+        https://bugs.webkit.org/show_bug.cgi?id=132314
+
+        Reviewed by Oliver Hunt and Filip Pizlo.
+
+        This is neutral across all benchmarks we track, although it looks like a wee 0.5% progression on sunspider.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID): If we fail to cache on self, we just repatch to call tryBuildGetByIDList next time.
+
+2014-04-28  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r153142) ASSERT from CodeBlock::dumpBytecode dumping String Switch Jump Tables
+        https://bugs.webkit.org/show_bug.cgi?id=132315
+
+        Reviewed by Mark Hahnenberg.
+
+        Used the StringImpl version of utf8() instead of creating a String first.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+
+2014-04-28  Filip Pizlo  <fpizlo@apple.com>
+
+        The LLInt is awesome and it should get more of the action.
+
+        Rubber stamped by Geoffrey Garen.
+        
+        5% speed-up on JSBench and no meaningful regressions.  Should be a PLT/DYE speed-up also.
+
+        * runtime/Options.h:
+
+2014-04-27  Filip Pizlo  <fpizlo@apple.com>
+
+        GC should be able to remove things from the DFG worklist and cancel on-going compilations if it knows that the compilation would already be invalidated
+        https://bugs.webkit.org/show_bug.cgi?id=132166
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+        
+        The GC can aid type inference by removing structures that are dead and jettisoning
+        code that relies on those structures. This can dramatically accelerate type inference
+        for some tricky programs.
+        
+        Unfortunately, we previously pinned any structures that enqueued compilations depended
+        on. This means that if you're on a machine that only runs a single compilation thread
+        and where compilations are relatively slow, you have a high chance of large numbers of
+        structures being pinned during any GC since the compilation queue is likely to be full
+        of random stuff.
+        
+        This comprehensively fixes this issue by allowing the GC to remove compilation plans
+        if the things they depend on are dead, and to even cancel safepointed compilations.
+        
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
+        (JSC::CodeBlock::isKnownToBeLiveDuringGC):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan): Deleted.
+        * dfg/DFGDesiredIdentifiers.cpp:
+        (JSC::DFG::DesiredIdentifiers::DesiredIdentifiers):
+        * dfg/DFGDesiredIdentifiers.h:
+        * dfg/DFGDesiredWatchpoints.h:
+        * dfg/DFGDesiredWeakReferences.cpp:
+        (JSC::DFG::DesiredWeakReferences::DesiredWeakReferences):
+        * dfg/DFGDesiredWeakReferences.h:
+        * dfg/DFGGraphSafepoint.cpp:
+        (JSC::DFG::GraphSafepoint::GraphSafepoint):
+        * dfg/DFGGraphSafepoint.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::Plan):
+        (JSC::DFG::Plan::compileInThread):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        (JSC::DFG::Plan::notifyCompiling):
+        (JSC::DFG::Plan::notifyCompiled):
+        (JSC::DFG::Plan::notifyReady):
+        (JSC::DFG::Plan::checkLivenessAndVisitChildren):
+        (JSC::DFG::Plan::isKnownToBeLiveDuringGC):
+        (JSC::DFG::Plan::cancel):
+        (JSC::DFG::Plan::visitChildren): Deleted.
+        * dfg/DFGPlan.h:
+        * dfg/DFGSafepoint.cpp:
+        (JSC::DFG::Safepoint::Result::~Result):
+        (JSC::DFG::Safepoint::Result::didGetCancelled):
+        (JSC::DFG::Safepoint::Safepoint):
+        (JSC::DFG::Safepoint::~Safepoint):
+        (JSC::DFG::Safepoint::checkLivenessAndVisitChildren):
+        (JSC::DFG::Safepoint::isKnownToBeLiveDuringGC):
+        (JSC::DFG::Safepoint::cancel):
+        (JSC::DFG::Safepoint::visitChildren): Deleted.
+        * dfg/DFGSafepoint.h:
+        (JSC::DFG::Safepoint::Result::Result):
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::compilationState):
+        (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
+        (JSC::DFG::Worklist::removeAllReadyPlansForVM):
+        (JSC::DFG::Worklist::completeAllReadyPlansForVM):
+        (JSC::DFG::Worklist::visitWeakReferences):
+        (JSC::DFG::Worklist::removeDeadPlans):
+        (JSC::DFG::Worklist::runThread):
+        (JSC::DFG::Worklist::visitChildren): Deleted.
+        * dfg/DFGWorklist.h:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLCompile.h:
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::visitCompilerWorklistWeakReferences):
+        (JSC::Heap::removeDeadCompilerWorklistEntries):
+        (JSC::Heap::visitWeakHandles):
+        (JSC::Heap::collect):
+        (JSC::Heap::visitCompilerWorklists): Deleted.
+        * heap/Heap.h:
+
+2014-04-28  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Deleting properties poisons objects
+        https://bugs.webkit.org/show_bug.cgi?id=131551
+
+        Reviewed by Oliver Hunt.
+
+        This is ~3% progression on Dromaeo with a ~6% progression on the jslib portion of Dromaeo in particular.
+
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::create):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::hasDeletedOffset):
+        (JSC::PropertyTable::hadDeletedOffset): If we ever had deleted properties we can no longer cache offsets when 
+        iterating properties because we're required to iterate properties in insertion order.
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap): We now re-use deleted properties when materializing the property map.
+        (JSC::Structure::removePropertyTransition): We allow up to 5 deletes for a particular path through the tree of 
+        Structure transitions. After that, we convert to an uncacheable dictionary like we used to. We don't cache 
+        delete transitions, but we allow transitioning from them.
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::removePropertyWithoutTransition):
+        (JSC::Structure::pin): Now does only what it says it does--marks the property table as pinned.
+        (JSC::Structure::pinAndPreventTransitions): More descriptive version of what the old pin() was doing.
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setEnumerationCache):
+        (JSC::Structure::hadDeletedOffsets):
+        (JSC::Structure::propertyTable):
+        (JSC::Structure::checkOffsetConsistency): Rearranged variables to be more sensible.
+        * tests/stress/for-in-after-delete.js: Added.
+        (foo):
+
+2014-04-25  Andreas Kling  <akling@apple.com>
+
+        Inline (C++) GetByVal with numeric indices more aggressively.
+        <https://webkit.org/b/132218>
+
+        We were already inlining the string indexed GetByVal path pretty well,
+        while the path for numeric indices got neglected. No more!
+
+        ~9.5% improvement on Dromaeo/dom-traverse.html on my MBP:
+
+            Before: 199.50 runs/s
+             After: 218.58 runs/s
+
+        Reviewed by Phil Pizlo.
+
+        * dfg/DFGOperations.cpp:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::get):
+
+            ALWAYS_INLINE all the things.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::getPropertySlot):
+
+            Avoid fetching the Structure more than once. We have the same
+            optimization in the string-indexed code path.
+
+2014-04-25  Oliver Hunt  <oliver@apple.com>
+
+        Need earlier cell test
+        https://bugs.webkit.org/show_bug.cgi?id=132211
+
+        Reviewed by Mark Lam.
+
+        Move cell test to before the function call repatch
+        location, as the repatch logic for 32bit assumes that the
+        caller will already have performed a cell check.
+
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+
+2014-04-25  Andreas Kling  <akling@apple.com>
+
+        Un-fast-allocate JSGlobalObjectRareData because Windows doesn't build and I'm not in the mood.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::JSGlobalObjectRareData::JSGlobalObjectRareData):
+        (JSC::JSGlobalObject::JSGlobalObjectRareData::~JSGlobalObjectRareData): Deleted.
+
+2014-04-25  Andreas Kling  <akling@apple.com>
+
+        Windows build fix attempt.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::JSGlobalObjectRareData::~JSGlobalObjectRareData):
+
+2014-04-25  Mark Lam  <mark.lam@apple.com>
+
+        Refactor debugging code to use BreakpointActions instead of Vector<ScriptBreakpointAction>.
+        <https://webkit.org/b/132201>
+
+        Reviewed by Joseph Pecoraro.
+
+        BreakpointActions is Vector<ScriptBreakpointAction>.  Let's just consistently use
+        BreakpointActions everywhere.
+
+        * inspector/ScriptBreakpoint.h:
+        (Inspector::ScriptBreakpoint::ScriptBreakpoint):
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::setBreakpoint):
+        (Inspector::ScriptDebugServer::getActionsForBreakpoint):
+        * inspector/ScriptDebugServer.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::removeBreakpoint):
+        * inspector/agents/InspectorDebuggerAgent.h:
+
+2014-04-24  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG worklist scanning should not treat the key as a separate entity
+        https://bugs.webkit.org/show_bug.cgi?id=132167
+
+        Reviewed by Mark Hahnenberg.
+        
+        This simplifies the interface to the GC and will enable more optimizations.
+
+        * dfg/DFGCompilationKey.cpp:
+        (JSC::DFG::CompilationKey::visitChildren): Deleted.
+        * dfg/DFGCompilationKey.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::visitChildren):
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::visitChildren):
+
+2014-04-25  Oliver Hunt  <oliver@apple.com>
+
+        Remove unused parameter from codeblock linking function
+        https://bugs.webkit.org/show_bug.cgi?id=132199
+
+        Reviewed by Anders Carlsson.
+
+        No change in behaviour. This is just a small change to make it
+        slightly easier to reason about what the offsets in UnlinkedFunctionExecutable
+        actually mean.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::link):
+        * bytecode/UnlinkedCodeBlock.h:
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+
+2014-04-25  Andreas Kling  <akling@apple.com>
+
+        Mark some things with WTF_MAKE_FAST_ALLOCATED.
+        <https://webkit.org/b/132198>
+
+        Use FastMalloc for more things.
+
+        Reviewed by Anders Carlsson.
+
+        * builtins/BuiltinExecutables.h:
+        * heap/GCThreadSharedData.h:
+        * inspector/JSConsoleClient.h:
+        * inspector/agents/InspectorAgent.h:
+        * runtime/CodeCache.h:
+        * runtime/JSGlobalObject.h:
+        * runtime/Lookup.cpp:
+        (JSC::HashTable::createTable):
+        (JSC::HashTable::deleteTable):
+        * runtime/WeakGCMap.h:
+
+2014-04-25  Antoine Quint  <graouts@webkit.org>
+
+        Implement Array.prototype.find()
+        https://bugs.webkit.org/show_bug.cgi?id=130966
+
+        Reviewed by Oliver Hunt.
+
+        Implement Array.prototype.find() and Array.prototype.findIndex() as proposed in the Harmony spec.
+
+        * builtins/Array.prototype.js:
+        (find):
+        (findIndex):
+        * runtime/ArrayPrototype.cpp:
+
+2014-04-24  Brady Eidson  <beidson@apple.com>
+
+        Rename "IMAGE_CONTROLS" feature to "SERVICE_CONTROLS"
+        https://bugs.webkit.org/show_bug.cgi?id=132155
+
+        Reviewed by Tim Horton.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-04-24  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION: Apparent hang of PCE.js Mac OS System 7.0.1 on ARM64 devices
+        https://bugs.webkit.org/show_bug.cgi?id=132147
+
+        Reviewed by Mark Lam.
+
+        Fixed or64(), eor32( ) and eor64() to use "src" register when we have a valid logicalImm.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::or64):
+        (JSC::MacroAssemblerARM64::xor32):
+        (JSC::MacroAssemblerARM64::xor64):
+        * tests/stress/regress-132147.js: Added test.
+
+2014-04-24  Mark Lam  <mark.lam@apple.com>
+
+        Make slowPathAllocsBetweenGCs a runtime option.
+        <https://webkit.org/b/132137>
+
+        Reviewed by Mark Hahnenberg.
+
+        This will make it easier to more casually run tests with this configuration
+        as well as to reproduce issues (instead of requiring a code mod and rebuild).
+        We will now take --slowPathAllocsBetweenGCs=N where N is the number of
+        slow path allocations before we trigger a collection.
+
+        The option defaults to 0, which is reserved to mean that we will not trigger
+        any collections there.
+
+        * heap/Heap.h:
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::doTestCollectionsIfNeeded):
+        (JSC::MarkedAllocator::allocateSlowCase):
+        * heap/MarkedAllocator.h:
+        * runtime/Options.h:
+
+2014-04-23  Mark Lam  <mark.lam@apple.com>
+
+        The GC should only resume compiler threads that it suspended in the same GC pass.
+        <https://webkit.org/b/132088>
+
+        Reviewed by Mark Hahnenberg.
+
+        Previously, this scenario can occur:
+        1. Thread 1 starts a GC and tries to suspend DFG worklist threads.  However,
+           no worklists were created yet at the that time.
+        2. Thread 2 starts to compile some functions and creates a DFG worklist, and
+           acquires the worklist thread's lock.
+        3. Thread 1's GC completes and tries to resume suspended DFG worklist thread.
+           This time, it sees the worklist created by Thread 2 and ends up unlocking
+           the worklist thread's lock that is supposedly held by Thread 2.
+        Thereafter, chaos ensues.
+
+        The fix is to cache the worklists that were actually suspended by each GC pass,
+        and only resume those when the GC is done.
+
+        This issue was discovered by enabling COLLECT_ON_EVERY_ALLOCATION and running
+        the fast/workers layout tests.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::visitCompilerWorklists):
+        (JSC::Heap::deleteAllCompiledCode):
+        (JSC::Heap::suspendCompilerThreads):
+        (JSC::Heap::resumeCompilerThreads):
+        * heap/Heap.h:
+
+2014-04-23  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Arguments::copyBackingStore needs to update m_registers in tandem with m_registerArray
+        https://bugs.webkit.org/show_bug.cgi?id=132079
+
+        Reviewed by Michael Saboff.
+
+        Since we're moving the register backing store, we don't want to leave a dangling pointer into a random CopiedBlock.
+
+        Also added a test that previously triggered this bug.
+
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyBackingStore): D'oh!
+        * tests/stress/arguments-copy-register-array-backing-store.js: Added.
+        (foo):
+        (bar):
+
+2014-04-23  Mark Rowe  <mrowe@apple.com>
+
+        [Mac] REGRESSION (r164823): Building JavaScriptCore creates files under /tmp/JavaScriptCore.dst
+        <https://webkit.org/b/132053>
+
+        Reviewed by Dan Bernstein.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Don't try to create a symlink at /usr/local/bin/jsc inside
+        the DSTROOT unless we're building to the deployment location. Also remove the unnecessary -x argument
+        from /bin/sh since that generates unnecessary output.
+
+2014-04-22  Mark Lam  <mark.lam@apple.com>
+
+        DFG::Worklist should acquire the m_lock before iterating DFG plans.
+        <https://webkit.org/b/132032>
+
+        Reviewed by Filip Pizlo.
+
+        Currently, there's a rightToRun mechanism that ensures that no compilation
+        threads are running when the GC is iterating through the DFG worklists.
+        However, this does not prevent a Worker thread from doing a DFG compilation
+        and modifying the plans in the worklists thereby invalidating the plan
+        iterator that the GC is using.  This patch fixes the issue by acquiring
+        the worklist m_lock before iterating the worklist plans.
+
+        This issue was uncovered by running the fast/workers layout tests with
+        COLLECT_ON_EVERY_ALLOCATION enabled.
+
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::isActiveForVM):
+        (JSC::DFG::Worklist::visitChildren):
+
+2014-04-22  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Support Python 2.7 in Cygwin
+        https://bugs.webkit.org/show_bug.cgi?id=132023
+
+        Reviewed by Michael Saboff.
+
+        * DerivedSources.make: Use a conditional variable to define
+        the path to Python/Perl.
+
+2014-04-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Switch the LLVMForJSC target to using the LLVM in /usr/local rather than /usr/local/LLVMForJavaScriptCore on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=130867
+        <rdar://problem/16432456> 
+
+        Reviewed by Mark Hahnenberg.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/LLVMForJSC.xcconfig:
+
+2014-04-22  Alex Christensen  <achristensen@webkit.org>
+
+        [Win] Unreviewed build fix after my r167666.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
+        Added ../../../ again to include headers in Source/JavaScriptCore.
+
+2014-04-22  Alex Christensen  <achristensen@webkit.org>
+
+        Removed old stdbool and inttypes headers.
+        https://bugs.webkit.org/show_bug.cgi?id=131966
+
+        Reviewed by Brent Fulgham.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props:
+        Removed references to os-win32 directory.
+        * os-win32: Removed.
+        * os-win32/inttypes.h: Removed.
+        * os-win32/stdbool.h: Removed.
+
+2014-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::clobberize() should honestly admit that profiler and debugger nodes are effectful
+        https://bugs.webkit.org/show_bug.cgi?id=131971
+        <rdar://problem/16676511>
+
+        Reviewed by Mark Lam.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
+2014-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Switch statements that skip the baseline JIT should work
+        https://bugs.webkit.org/show_bug.cgi?id=131965
+
+        Reviewed by Mark Hahnenberg.
+
+        * bytecode/JumpTable.h:
+        (JSC::SimpleJumpTable::ensureCTITable):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_switch_imm):
+        (JSC::JIT::emit_op_switch_char):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_switch_imm):
+        (JSC::JIT::emit_op_switch_char):
+        * tests/stress/inline-llint-with-switch.js: Added.
+        (foo):
+        (bar):
+        (test):
+
+2014-04-21  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Arguments objects shouldn't need a destructor
+        https://bugs.webkit.org/show_bug.cgi?id=131899
+
+        Reviewed by Oliver Hunt.
+
+        This patch rids Arguments objects of their destructors. It does this by 
+        switching their backing stores to use CopiedSpace rather than malloc memory.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Fix the code emitted for inline
+        Arguments allocation so that it only emits an extra write for strict mode code rather
+        than unconditionally.
+        * heap/CopyToken.h: New CopyTokens for the two different types of Arguments backing stores.
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::visitChildren): We need to tell the collector to copy the back stores now.
+        (JSC::Arguments::copyBackingStore): Do the actual copying of the backing stores.
+        (JSC::Arguments::deletePropertyByIndex): Update all the accesses to SlowArgumentData and m_registerArray.
+        (JSC::Arguments::deleteProperty):
+        (JSC::Arguments::defineOwnProperty):
+        (JSC::Arguments::allocateRegisterArray):
+        (JSC::Arguments::tearOff):
+        (JSC::Arguments::destroy): Deleted. We don't need the destructor any more.
+        * runtime/Arguments.h:
+        (JSC::Arguments::registerArraySizeInBytes):
+        (JSC::Arguments::SlowArgumentData::SlowArgumentData): Switch SlowArgumentData to being allocated
+        in CopiedSpace. Now the SlowArgumentData and its backing store are a single contiguous CopiedSpace
+        allocation.
+        (JSC::Arguments::SlowArgumentData::slowArguments):
+        (JSC::Arguments::SlowArgumentData::bytecodeToMachineCaptureOffset):
+        (JSC::Arguments::SlowArgumentData::setBytecodeToMachineCaptureOffset):
+        (JSC::Arguments::SlowArgumentData::sizeForNumArguments):
+        (JSC::Arguments::Arguments):
+        (JSC::Arguments::allocateSlowArguments):
+        (JSC::Arguments::tryDeleteArgument):
+        (JSC::Arguments::isDeletedArgument):
+        (JSC::Arguments::isArgument):
+        (JSC::Arguments::argument):
+        (JSC::Arguments::finishCreation):
+        * runtime/SymbolTable.h:
+
+2014-04-21  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] implement WebKitDataCue
+        https://bugs.webkit.org/show_bug.cgi?id=131799
+
+        Reviewed by Dean Jackson.
+
+        * Configurations/FeatureDefines.xcconfig: Define ENABLE_DATACUE_VALUE.
+
+2014-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed test gardening, run the repeat-out-of-bounds tests again.
+
+        * tests/stress/float32-repeat-out-of-bounds.js:
+        * tests/stress/int8-repeat-out-of-bounds.js:
+
+2014-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        OSR exit should know about Int52 and Double constants
+        https://bugs.webkit.org/show_bug.cgi?id=131945
+
+        Reviewed by Oliver Hunt.
+        
+        The DFG OSR exit machinery's ignorance would lead to some constants becoming
+        jsUndefined() after OSR exit.
+        
+        The FTL OSR exit machinery's ignorance just meant that we would sometimes use a
+        stackmap constant rather than baking the constant into the OSRExit data structure.
+        So, not a big deal, but worth fixing.
+        
+        Also added some helpful hacks to jsc.cpp for testing such OSR exit pathologies.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGMinifiedNode.h:
+        (JSC::DFG::belongsInMinifiedGraph):
+        (JSC::DFG::MinifiedNode::hasConstantNumber):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionOtherFalse):
+        (functionUndefined):
+        * runtime/Intrinsic.h:
+        * tests/stress/fold-to-double-constant-then-exit.js: Added.
+        (foo):
+        * tests/stress/fold-to-int52-constant-then-exit.js: Added.
+        (foo):
+
+2014-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Provide feedback when we encounter an unrecognied node in the FTL backend.
+
+        Rubber stamped by Alexey Proskuryakov.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2014-04-21  Andreas Kling  <akling@apple.com>
+
+        Move the JSString cache from DOMWrapperWorld to VM.
+        <https://webkit.org/b/131940>
+
+        Reviewed by Geoff Garen.
+
+        * runtime/VM.h:
+
+2014-04-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Take block execution count estimates into account when voting double
+        https://bugs.webkit.org/show_bug.cgi?id=131906
+
+        Reviewed by Geoffrey Garen.
+        
+        This was a drama in three acts.
+        
+        Act I: Slurp in BasicBlock::executionCount and use it as a weight when counting the
+            number of uses of a variable that want double or non-double. Easy as pie. This
+            gave me a huge speed-up on FloatMM and a huge slow-down on basically everything
+            else.
+        
+        Act II: Realize that there were some programs where our previous double voting was
+            just on the edge of disaster and making it more precise tipped it over. In
+            particular, if you had an integer variable that would infrequently be used in a
+            computation that resulted in a variable that was frequently used as an array index,
+            the outer infrequentness would be the thing we'd use in the vote. So, an array
+            index would become double. We fix this by reviving global backwards propagation
+            and introducing the concept of ReallyWantsInt, which is used just for array
+            indices. Any variable transitively flagged as ReallyWantsInt will never be forced
+            double. We need that flag to be separate from UsedAsInt, since UsedAsInt needs to
+            be set in bitops for RageConversion but using it for double forcing is too much.
+            Basically, it's cheaper to have to convert a double to an int for a bitop than it
+            is to convert a double to an int for an array index; also a variable being used as
+            an array index is a much stronger hint that it ought to be an int. This recovered
+            performance on everything except programs that used FTL OSR entry.
+        
+        Act III: Realize that OSR entrypoint creation creates blocks that have NaN execution
+            count, which then completely pollutes the weighting - essentially all votes go
+            NaN. Fix this with some surgical defenses. Basically, any client of execution
+            counts should allow for them to be NaN and shouldn't completely fall off a cliff
+            when it happens.
+        
+        This is awesome. 75% speed-up on FloatMM. 11% speed-up on audio-dft. This leads to
+        7% speed-up on AsmBench and 2% speed-up on Kraken.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::run):
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dumpBlockHeader):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::voteNode):
+        (JSC::DFG::Graph::voteChildren):
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGOSREntrypointCreationPhase.cpp:
+        (JSC::DFG::OSREntrypointCreationPhase::run):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+        * dfg/DFGVariableAccessData.cpp: Added.
+        (JSC::DFG::VariableAccessData::VariableAccessData):
+        (JSC::DFG::VariableAccessData::mergeIsCaptured):
+        (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox):
+        (JSC::DFG::VariableAccessData::predict):
+        (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction):
+        (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
+        (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
+        (JSC::DFG::VariableAccessData::mergeDoubleFormatState):
+        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
+        (JSC::DFG::VariableAccessData::flushFormat):
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::vote):
+        (JSC::DFG::VariableAccessData::VariableAccessData): Deleted.
+        (JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
+        (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox): Deleted.
+        (JSC::DFG::VariableAccessData::predict): Deleted.
+        (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction): Deleted.
+        (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): Deleted.
+        (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat): Deleted.
+        (JSC::DFG::VariableAccessData::mergeDoubleFormatState): Deleted.
+        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat): Deleted.
+        (JSC::DFG::VariableAccessData::flushFormat): Deleted.
+
+2014-04-21  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r167591): ARM64 and ARM traditional builds broken
+        https://bugs.webkit.org/show_bug.cgi?id=131935
+
+        Reviewed by Mark Hahnenberg.
+
+        Added store8(TrustedImm32, MacroAssembler::Address) to the ARM traditional and ARM64
+        macro assemblers.  Added a new test for the original patch.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::store8):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::store8):
+        * tests/stress/dfg-create-arguments-inline-alloc.js: New test.
+
+2014-04-21  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Inline allocate Arguments objects in the DFG
+        https://bugs.webkit.org/show_bug.cgi?id=131897
+
+        Reviewed by Geoffrey Garen.
+
+        Many libraries/frameworks depend on the arguments object for overloaded API entry points. 
+        This is the first step to making Arguments fast(er). We'll duplicate the logic in Arguments::create 
+        for now and take the slow path for complicated cases like slow arguments, tearing off for strict mode, etc.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/Arguments.h:
+        (JSC::Arguments::offsetOfActivation):
+        (JSC::Arguments::offsetOfOverrodeLength):
+        (JSC::Arguments::offsetOfIsStrictMode):
+        (JSC::Arguments::offsetOfRegisterArray):
+        (JSC::Arguments::offsetOfCallee):
+        (JSC::Arguments::allocationSize):
+
+2014-04-20  Andreas Kling  <akling@apple.com>
+
+        Speed up jsStringWithCache() through WeakGCMap inlining.
+        <https://webkit.org/b/131923>
+
+        Always inline WeakGCMap::add() but move the slow garbage collecting
+        path out-of-line.
+
+        Reviewed by Darin Adler.
+
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::add):
+        (JSC::WeakGCMap::gcMap):
+
+2014-04-20  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        JavaScriptCore: ARM build fix after r167094.
+        https://bugs.webkit.org/show_bug.cgi?id=131612
+
+        Reviewed by Michael Saboff.
+
+        After r167094 there are many build errors on ARM like these:
+
+            /tmp/ccgtHRno.s:370: Error: invalid constant (425a) after fixup
+            /tmp/ccgtHRno.s:374: Error: invalid constant (426e) after fixup
+            /tmp/ccgtHRno.s:378: Error: invalid constant (4282) after fixup
+            /tmp/ccgtHRno.s:382: Error: invalid constant (4296) after fixup
+
+        Problem is caused by the wrong generated assembly like:
+            "\tmov r2, (" LOCAL_LABEL_STRING(llint_op_strcat) " - " LOCAL_LABEL_STRING(relativePCBase) ")\n" // /home/webkit/WebKit/Source/JavaScriptCore/llint/LowLevelInterpreter.asm:741
+
+        `mov` can only move 8 bit immediate, but not every constant fit into 8 bit. Clang converts
+        the mov to a single movw or a movw and a movt, depending on the immediate, but binutils doesn't.
+        Add a new ARM specific offline assembler instruction (`mvlbl`) for the following llint_entry
+        use case: move rn, (label1-label2) which is translated to movw and movt.
+
+        * llint/LowLevelInterpreter.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/instructions.rb:
+
+2014-04-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Unreviewed build fix after r167336.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::branchAdd32):
+
+2014-04-20  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167501.
+        https://bugs.webkit.org/show_bug.cgi?id=131913
+
+        It broke DYEBench (Requested by mhahnenberg on #webkit).
+
+        Reverted changeset:
+
+        "Deleting properties poisons objects"
+        https://bugs.webkit.org/show_bug.cgi?id=131551
+        http://trac.webkit.org/changeset/167501
+
+2014-04-19  Filip Pizlo  <fpizlo@apple.com>
+
+        It should be OK to store new fields into objects that have no prototypes
+        https://bugs.webkit.org/show_bug.cgi?id=131905
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+        * tests/stress/put-by-id-transition-null-prototype.js: Added.
+        (foo):
+
+2014-04-19  Benjamin Poulain  <bpoulain@apple.com>
+
+        Make the CSS JIT compile for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=131834
+
+        Reviewed by Gavin Barraclough.
+
+        Extend the ARM64 MacroAssembler to support the code generation required by
+        the CSS JIT.
+
+        * assembler/MacroAssembler.h:
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::addPtrNoFlags):
+        (JSC::MacroAssemblerARM64::or32):
+        (JSC::MacroAssemblerARM64::branchPtr):
+        (JSC::MacroAssemblerARM64::test32):
+        (JSC::MacroAssemblerARM64::branch):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::test32):
+
+2014-04-19  Andreas Kling  <akling@apple.com>
+
+        Two little shortcuts to the JSType.
+        <https://webkit.org/b/131896>
+
+        Tweak two sites that take the long road through JSCell::structure()->typeInfo()
+        to look at data that's already in JSCell::type().
+
+        Reviewed by Darin Adler.
+
+        * runtime/NameInstance.h:
+        (JSC::isName):
+        * runtime/NumberPrototype.cpp:
+        (JSC::toThisNumber):
+
+2014-04-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Make it easier to check if an integer sum would overflow
+        https://bugs.webkit.org/show_bug.cgi?id=131900
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGOperations.cpp:
+        * runtime/Operations.h:
+        (JSC::jsString):
+
+2014-04-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Address some feedback on https://bugs.webkit.org/show_bug.cgi?id=130684.
+
+        * dfg/DFGOperations.cpp:
+        * runtime/JSString.h:
+        (JSC::JSRopeString::RopeBuilder::append):
+
+2014-04-18  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(r164205): WebKit crash @StructureIDTable::get.
+        <https://webkit.org/b/130539>
+
+        Reviewed by Geoffrey Garen.
+
+        prepareOSREntry() prepares for OSR entry by first copying the local var
+        values from the baseline frame to a scartch buffer, which is then used
+        to fill in the locals in their new position in the DFG frame.  Unfortunately,
+        prepareOSREntry() was using the DFG frame's frameRegisterCount as the frame
+        size of the baseline frame.  As a result, some values of locals in the
+        baseline frame were not saved off, and the DFG frame may get initialized
+        with random content that happened to be in the uninitialized (and possibly
+        unallocated) portions of the scratch buffer.
+
+        The fix is to use OSREntryData::m_expectedValues.numberOfLocals() as the
+        number of locals in the baseline frame that we want to copy to the scratch
+        buffer.
+
+        Note: osrEntryThunkGenerator() is expecting the DFG frameRegisterCount
+        at offset 0 in the scratch buffer.  So, we continue to write that value
+        there, not the baseline frame size.
+
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+
+2014-04-18  Timothy Hatcher  <timothy@apple.com>
+
+        Web Inspector: Move InspectorProfilerAgent to JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=131673
+
+        Passes existing profiler and inspector tests.
+
+        Reviewed by Joseph Pecoraro.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/JSConsoleClient.cpp:
+        (Inspector::JSConsoleClient::JSConsoleClient):
+        (Inspector::JSConsoleClient::profile):
+        (Inspector::JSConsoleClient::profileEnd):
+        (Inspector::JSConsoleClient::count): Deleted.
+        * inspector/JSConsoleClient.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        * inspector/agents/InspectorProfilerAgent.cpp: Added.
+        (Inspector::InspectorProfilerAgent::InspectorProfilerAgent):
+        (Inspector::InspectorProfilerAgent::~InspectorProfilerAgent):
+        (Inspector::InspectorProfilerAgent::addProfile):
+        (Inspector::InspectorProfilerAgent::createProfileHeader):
+        (Inspector::InspectorProfilerAgent::enable):
+        (Inspector::InspectorProfilerAgent::disable):
+        (Inspector::InspectorProfilerAgent::getUserInitiatedProfileName):
+        (Inspector::InspectorProfilerAgent::getProfileHeaders):
+        (Inspector::buildInspectorObject):
+        (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
+        (Inspector::InspectorProfilerAgent::getCPUProfile):
+        (Inspector::InspectorProfilerAgent::removeProfile):
+        (Inspector::InspectorProfilerAgent::reset):
+        (Inspector::InspectorProfilerAgent::didCreateFrontendAndBackend):
+        (Inspector::InspectorProfilerAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorProfilerAgent::start):
+        (Inspector::InspectorProfilerAgent::stop):
+        (Inspector::InspectorProfilerAgent::setRecordingProfile):
+        (Inspector::InspectorProfilerAgent::startProfiling):
+        (Inspector::InspectorProfilerAgent::stopProfiling):
+        * inspector/agents/InspectorProfilerAgent.h: Added.
+        * inspector/agents/JSGlobalObjectProfilerAgent.cpp: Copied from Source/WebCore/inspector/ScriptProfile.idl.
+        (Inspector::JSGlobalObjectProfilerAgent::JSGlobalObjectProfilerAgent):
+        (Inspector::JSGlobalObjectProfilerAgent::profilingGlobalExecState):
+        * inspector/agents/JSGlobalObjectProfilerAgent.h: Copied from Source/WebCore/inspector/ScriptProfile.idl.
+        * inspector/protocol/Profiler.json: Renamed from Source/WebCore/inspector/protocol/Profiler.json.
+        * profiler/Profile.h:
+        * runtime/ConsoleClient.h:
+
+2014-04-18  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167527.
+        https://bugs.webkit.org/show_bug.cgi?id=131883
+
+        Broke 32-bit build (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "[Mac] implement WebKitDataCue"
+        https://bugs.webkit.org/show_bug.cgi?id=131799
+        http://trac.webkit.org/changeset/167527
+
+2014-04-18  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] implement WebKitDataCue
+        https://bugs.webkit.org/show_bug.cgi?id=131799
+
+        Reviewed by Dean Jackson.
+
+        * Configurations/FeatureDefines.xcconfig: Define ENABLE_DATACUE_VALUE.
+
+2014-04-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Actually address Mark's review feedback.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::handleExitCounts):
+
+2014-04-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Options::maximumExecutionCountsBetweenCheckpoints() should be higher for DFG->FTL tier-up but the same for other tier-ups
+        https://bugs.webkit.org/show_bug.cgi?id=131850
+
+        Reviewed by Mark Hahnenberg.
+        
+        Templatize ExecutionCounter to allow for two different styles of calculating the
+        checkpoint threshold.
+        
+        Appears to be a slight speed-up on DYEBench.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::llintExecuteCounter):
+        (JSC::CodeBlock::offsetOfJITExecuteCounter):
+        (JSC::CodeBlock::offsetOfJITExecutionActiveThreshold):
+        (JSC::CodeBlock::offsetOfJITExecutionTotalCount):
+        (JSC::CodeBlock::jitExecuteCounter):
+        * bytecode/ExecutionCounter.cpp:
+        (JSC::ExecutionCounter<countingVariant>::ExecutionCounter):
+        (JSC::ExecutionCounter<countingVariant>::forceSlowPathConcurrently):
+        (JSC::ExecutionCounter<countingVariant>::checkIfThresholdCrossedAndSet):
+        (JSC::ExecutionCounter<countingVariant>::setNewThreshold):
+        (JSC::ExecutionCounter<countingVariant>::deferIndefinitely):
+        (JSC::applyMemoryUsageHeuristics):
+        (JSC::applyMemoryUsageHeuristicsAndConvertToInt):
+        (JSC::ExecutionCounter<countingVariant>::hasCrossedThreshold):
+        (JSC::ExecutionCounter<countingVariant>::setThreshold):
+        (JSC::ExecutionCounter<countingVariant>::reset):
+        (JSC::ExecutionCounter<countingVariant>::dump):
+        (JSC::ExecutionCounter::ExecutionCounter): Deleted.
+        (JSC::ExecutionCounter::forceSlowPathConcurrently): Deleted.
+        (JSC::ExecutionCounter::checkIfThresholdCrossedAndSet): Deleted.
+        (JSC::ExecutionCounter::setNewThreshold): Deleted.
+        (JSC::ExecutionCounter::deferIndefinitely): Deleted.
+        (JSC::ExecutionCounter::applyMemoryUsageHeuristics): Deleted.
+        (JSC::ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt): Deleted.
+        (JSC::ExecutionCounter::hasCrossedThreshold): Deleted.
+        (JSC::ExecutionCounter::setThreshold): Deleted.
+        (JSC::ExecutionCounter::reset): Deleted.
+        (JSC::ExecutionCounter::dump): Deleted.
+        * bytecode/ExecutionCounter.h:
+        (JSC::formattedTotalExecutionCount):
+        (JSC::ExecutionCounter::maximumExecutionCountsBetweenCheckpoints):
+        (JSC::ExecutionCounter::clippedThreshold):
+        (JSC::ExecutionCounter::formattedTotalCount): Deleted.
+        * dfg/DFGJITCode.h:
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::handleExitCounts):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/Options.h:
+
+2014-04-17  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Deleting properties poisons objects
+        https://bugs.webkit.org/show_bug.cgi?id=131551
+
+        Reviewed by Geoffrey Garen.
+
+        This is ~3% progression on Dromaeo with a ~6% progression on the jslib portion of Dromaeo in particular.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap): We now re-use deleted properties when materializing the property map.
+        (JSC::Structure::removePropertyTransition): We allow up to 5 deletes for a particular path through the tree of 
+        Structure transitions. After that, we convert to an uncacheable dictionary like we used to. We don't cache 
+        delete transitions, but we allow transitioning from them.
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::removePropertyWithoutTransition):
+        (JSC::Structure::pin): Now does only what it says it does--marks the property table as pinned.
+        (JSC::Structure::pinAndPreventTransitions): More descriptive version of what the old pin() was doing.
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::checkOffsetConsistency): Rearranged variables to be more sensible.
+
+2014-04-17  Filip Pizlo  <fpizlo@apple.com>
+
+        InlineCallFrameSet should be refcounted
+        https://bugs.webkit.org/show_bug.cgi?id=131829
+
+        Reviewed by Geoffrey Garen.
+        
+        And DFG::Plan should hold a ref to it. Previously it was owned by Graph until it
+        became owned by JITCode. Except that if we're "failing" to compile, JITCode may die.
+        Even as it dies, the GC may still want to scan the DFG::Plan, which leads to scanning
+        the DesiredWriteBarriers, which leads to scanning the InlineCallFrameSet.
+        
+        So, just make the darn thing refcounted.
+
+        * bytecode/InlineCallFrameSet.h:
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGCommonData.h:
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::requiredRegisterCountForExit):
+        * dfg/DFGGraph.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::Plan):
+        * dfg/DFGPlan.h:
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * ftl/FTLFail.cpp:
+        (JSC::FTL::fail):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+
+2014-04-17  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL::fail() should manage memory "correctly"
+        https://bugs.webkit.org/show_bug.cgi?id=131823
+        <rdar://problem/16384297>
+
+        Reviewed by Oliver Hunt.
+
+        * ftl/FTLFail.cpp:
+        (JSC::FTL::fail):
+
+2014-04-17  Filip Pizlo  <fpizlo@apple.com>
+
+        Prediction propagator should correctly model Int52s flowing through arguments
+        https://bugs.webkit.org/show_bug.cgi?id=131822
+        <rdar://problem/16641408>
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * tests/stress/int52-argument.js: Added.
+        (foo):
+        * tests/stress/int52-variable.js: Added.
+        (foo):
+
+2014-04-17  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION: ASSERT(!typeInfo().hasImpureGetOwnPropertySlot() || typeInfo().newImpurePropertyFiresWatchpoints()) on jquery tests
+        https://bugs.webkit.org/show_bug.cgi?id=131798
+
+        Reviewed by Alexey Proskuryakov.
+        
+        Some day, we will fix https://bugs.webkit.org/show_bug.cgi?id=131810 and some version
+        of this assertion can return. For now, it's not clear that the assertion is guarding
+        any truly undesirable behavior - so it should just go away and be replaced with a
+        FIXME.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * runtime/Structure.h:
+        (JSC::Structure::takesSlowPathInDFGForImpureProperty):
+
+2014-04-17  David Kilzer  <ddkilzer@apple.com>
+
+        Blind attempt to fix Windows build after r166837
+        <http://webkit.org/b/131246>
+
+        Hoping to fix this build error:
+
+            warning MSB8027: Two or more files with the name of GCLogging.cpp will produce outputs to the same location. This can lead to an incorrect build result.  The files involved are ..\heap\GCLogging.cpp, ..\heap\GCLogging.cpp.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Fix copy-paste
+        boo-boo by changing the GCLogging.cpp ClCompile entry to a
+        GCLogging.h ClInclude entry.
+
+2014-04-16  Filip Pizlo  <fpizlo@apple.com>
+
+        AI for GetLocal should match the DFG backend, and in this case, the best way to do that is to get rid of the "exit if empty prediction" thing since it's a vestige of a time long gone
+        https://bugs.webkit.org/show_bug.cgi?id=131764
+
+        Reviewed by Geoffrey Garen.
+        
+        The attached test case can be made to not crash by deleting old code. It used to be
+        the case that the DFG needed empty prediction guards, for shady reasons. We fixed that
+        long ago. At this point, these guards just make life difficult. So get rid of them.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * tests/stress/bug-131764.js: Added.
+        (test1):
+        (test2):
+
+2014-04-17  Darin Adler  <darin@apple.com>
+
+        Add separate flag for IndexedDatabase in workers since the current implementation is not threadsafe
+        https://bugs.webkit.org/show_bug.cgi?id=131785
+        rdar://problem/16003108
+
+        Reviewed by Brady Eidson.
+
+        * Configurations/FeatureDefines.xcconfig: Added INDEXED_DATABASE_IN_WORKERS.
+
+2014-04-16  Alexey Proskuryakov  <ap@apple.com>
+
+        Build fix after http://trac.webkit.org/changeset/167416 (Sink NaN sanitization)
+
+        * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::speculate):
+
+2014-04-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Extra error reporting for invalid value conversions
+        https://bugs.webkit.org/show_bug.cgi?id=131786
+
+        Rubber stamped by Ryosuke Niwa.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+
+2014-04-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Sink NaN sanitization to uses and remove it when it's unnecessary
+        https://bugs.webkit.org/show_bug.cgi?id=131419
+
+        Reviewed by Oliver Hunt.
+        
+        This moves NaN purification to stores that could see an impure NaN.
+        
+        5% speed-up on AsmBench, 50% speed-up on AsmBench/n-body. It is a regression on FloatMM
+        though, because of the other bug that causes that benchmark to box doubles in a loop.
+
+        * bytecode/SpeculatedType.h:
+        (JSC::isInt32SpeculationForArithmetic):
+        (JSC::isMachineIntSpeculationForArithmetic):
+        (JSC::isDoubleSpeculation):
+        (JSC::isDoubleSpeculationForArithmetic):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueRep):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        * runtime/PureNaN.h:
+        * tests/stress/float32-array-nan-inlined.js: Added.
+        (foo):
+        (test):
+        * tests/stress/float32-array-nan.js: Added.
+        (foo):
+        (test):
+        * tests/stress/float64-array-nan-inlined.js: Added.
+        (foo):
+        (isBigEndian):
+        (test):
+        * tests/stress/float64-array-nan.js: Added.
+        (foo):
+        (isBigEndian):
+        (test):
+
+2014-04-16  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed Windows gardening. Restrict our new 'isinf' check
+        to 32-bit builds, and revise the comment to explain what we are
+        doing.
+
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isMachineInt): Provide motivation for the new
+        'isinf' check for our 32-bit code path.
+
+2014-04-16  Juergen Ributzka  <juergen@apple.com>
+
+        Allocate the data section on the heap again for FTL on ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=130156
+
+        Reviewed by Geoffrey Garen and Filip Pizlo.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLDataSection.cpp:
+        (JSC::FTL::DataSection::DataSection):
+        (JSC::FTL::DataSection::~DataSection):
+        * ftl/FTLDataSection.h:
+
+2014-04-16  Mark Lam  <mark.lam@apple.com>
+
+        Crash in CodeBlock::setOptimizationThresholdBasedOnCompilationResult() when the debugger activates.
+        <https://webkit.org/b/131747>
+
+        Reviewed by Filip Pizlo.
+
+        When the debugger is about to activate (e.g. enter stepping mode), it first
+        waits for all DFG compilations to complete.  However, when the DFG completes,
+        if compilation is successful, it will install a new DFG codeBlock.  The
+        CodeBlock installation process is required to register codeBlocks with the
+        debugger.  Debugger::registerCodeBlock() will eventually call
+        CodeBlock::setSteppingMode() which may jettison the DFG codeBlock that we're
+        trying to install.  Thereafter, chaos ensues.
+
+        This jettison'ing only happens because the debugger currently set its
+        m_steppingMode flag before waiting for compilation to complete.  The fix is
+        simply to set that flag only after compilation is complete.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::setSteppingMode):
+        (JSC::Debugger::registerCodeBlock):
+
+2014-04-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Discern between NaNs that would be safe to tag and NaNs that need some purification before tagging
+        https://bugs.webkit.org/show_bug.cgi?id=131420
+
+        Reviewed by Oliver Hunt.
+        
+        Rationalizes our handling of NaNs. We now have the notion of pureNaN(), or PNaN, which
+        replaces QNaN and represents a "safe" NaN for our tagging purposes. NaN purification now
+        goes through the purifyNaN() API.
+        
+        SpeculatedType and its clients can now distinguish between a PureNaN and an ImpureNaN.
+        
+        Prediction propagator is made slightly more cautious when dealing with NaNs. It doesn't
+        have to be too cautious since most prediction-based logic only cares about whether or not
+        a value could be an integer.
+        
+        AI is made much more cautious when dealing with NaNs. We don't yet introduce ImpureNaN
+        anywhere in the compiler, but when we do, we ought to be able to trust AI to propagate it
+        soundly and precisely.
+        
+        No performance change because this just unblocks
+        https://bugs.webkit.org/show_bug.cgi?id=131419.
+
+        * API/JSValueRef.cpp:
+        (JSValueMakeNumber):
+        (JSValueToNumber):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationFromValue):
+        (JSC::typeOfDoubleSum):
+        (JSC::typeOfDoubleDifference):
+        (JSC::typeOfDoubleProduct):
+        (JSC::polluteDouble):
+        (JSC::typeOfDoubleQuotient):
+        (JSC::typeOfDoubleMinMax):
+        (JSC::typeOfDoubleNegation):
+        (JSC::typeOfDoubleAbs):
+        (JSC::typeOfDoubleFRound):
+        (JSC::typeOfDoubleBinaryOp):
+        (JSC::typeOfDoubleUnaryOp):
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        * dfg/DFGNode.h:
+        (JSC::DFG::BranchTarget::BranchTarget):
+        * dfg/DFGOSREntrypointCreationPhase.cpp:
+        (JSC::DFG::OSREntrypointCreationPhase::run):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
+        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
+        (JSC::FTL::LowerDFGToLLVM::allocateJSArray):
+        * ftl/FTLValueFormat.cpp:
+        (JSC::FTL::reboxAccordingToFormat):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::purifyNaN):
+        (JSC::AssemblyHelpers::sanitizeDouble): Deleted.
+        * jit/AssemblyHelpers.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        * runtime/DateConstructor.cpp:
+        (JSC::constructDate):
+        * runtime/DateInstanceCache.h:
+        (JSC::DateInstanceData::DateInstanceData):
+        (JSC::DateInstanceCache::reset):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::TerminatedExecutionError::defaultValue):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLength):
+        (JSC::JSArray::pop):
+        (JSC::JSArray::shiftCountWithAnyIndexingType):
+        (JSC::JSArray::sortVector):
+        (JSC::JSArray::compactForSorting):
+        * runtime/JSArray.h:
+        (JSC::JSArray::create):
+        (JSC::JSArray::tryCreateUninitialized):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::toNumberSlowCase):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::jsNaN):
+        (JSC::JSValue::JSValue):
+        (JSC::JSValue::getPrimitiveNumber):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::parseInt):
+        (JSC::jsStrDecimalLiteral):
+        (JSC::toDouble):
+        (JSC::jsToNumber):
+        (JSC::parseFloat):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::createInitialDouble):
+        (JSC::JSObject::convertUndecidedToDouble):
+        (JSC::JSObject::convertInt32ToDouble):
+        (JSC::JSObject::deletePropertyByIndex):
+        (JSC::JSObject::ensureLengthSlow):
+        * runtime/MathObject.cpp:
+        (JSC::mathProtoFuncMax):
+        (JSC::mathProtoFuncMin):
+        * runtime/PureNaN.h: Added.
+        (JSC::pureNaN):
+        (JSC::isImpureNaN):
+        (JSC::purifyNaN):
+        * runtime/TypedArrayAdaptors.h:
+        (JSC::FloatTypedArrayAdaptor::toJSValue):
+
+2014-04-16  Juergen Ributzka  <juergen@apple.com>
+
+        Enable system library calls in FTL for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=130154
+
+        Reviewed by Geoffrey Garen and Filip Pizlo.
+
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleRem):
+        (JSC::FTL::Output::doubleSin):
+        (JSC::FTL::Output::doubleCos):
+
+2014-04-16  peavo@outlook.com  <peavo@outlook.com>
+
+        Fix JSC Debug Regressions on Windows
+        https://bugs.webkit.org/show_bug.cgi?id=131182
+
+        Reviewed by Brent Fulgham.
+
+        The cast static_cast<int64_t>(number) in JSValue::isMachineInt() can generate a floating point error,
+        and set the st floating point register tags, if the value of the number parameter is infinite.
+        If the st floating point register tags are not cleared, this can cause strange floating point behavior later on.
+        This can be avoided by checking for infinity first.
+
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isMachineInt): Avoid floating point error by checking for infinity first.
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions): Re-enable jit for Windows.
+
+2014-04-16  Oliver Hunt  <oliver@apple.com>
+
+        Simple ES6 feature:Array.prototype.fill
+        https://bugs.webkit.org/show_bug.cgi?id=131703
+
+        Reviewed by David Hyatt.
+
+        Add support for Array.prototype.fill
+
+        * builtins/Array.prototype.js:
+        (fill):
+        * runtime/ArrayPrototype.cpp:
+
+2014-04-16  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        [WebKit] Cleanup the build from uninitialized variable in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=131728
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::genericConvertDoubleToContiguous): Add a RELEASE_ASSERT on the 
+        path we expect to never take. Also shut up confused compilers about uninitialized things.
+
+2014-04-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, ARMv7 build fix after r167336.
+
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::branchAdd32):
+
+2014-04-16  Gabor Rapcsanyi  <rgabor@webkit.org>
+
+        Unreviewed, ARM64 buildfix after r167336.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branchAdd32): Add missing function.
+
+2014-04-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, add the obvious thing that marks MakeRope as exiting since it can exit.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
+2014-04-15  Filip Pizlo  <fpizlo@apple.com>
+
+        compileMakeRope does not emit necessary bounds checks
+        https://bugs.webkit.org/show_bug.cgi?id=130684
+        <rdar://problem/16398388>
+
+        Reviewed by Oliver Hunt.
+        
+        Add string length bounds checks in a bunch of places. We should never allow a string
+        to have a length greater than 2^31-1 because it's not clear that the language has
+        semantics for it and because there is code that assumes that this cannot happen.
+        
+        Also add a bunch of tests to that effect to cover the various ways in which this was
+        previously allowed to happen.
+
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMakeRope):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::RopeBuilder::expand):
+        * runtime/JSString.h:
+        (JSC::JSString::create):
+        (JSC::JSRopeString::RopeBuilder::append):
+        (JSC::JSRopeString::RopeBuilder::release):
+        (JSC::JSRopeString::append):
+        * runtime/Operations.h:
+        (JSC::jsString):
+        (JSC::jsStringFromRegisterArray):
+        (JSC::jsStringFromArguments):
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncIndexOf):
+        (JSC::stringProtoFuncSlice):
+        (JSC::stringProtoFuncSubstring):
+        (JSC::stringProtoFuncToLowerCase):
+        * tests/stress/make-large-string-jit-strcat.js: Added.
+        (foo):
+        * tests/stress/make-large-string-jit.js: Added.
+        (foo):
+        * tests/stress/make-large-string-strcat.js: Added.
+        * tests/stress/make-large-string.js: Added.
+
+2014-04-15  Julien Brianceau  <jbriance@cisco.com>
+
+        Remove invalid sh4 specific code in JITInlines header.
+        https://bugs.webkit.org/show_bug.cgi?id=131692
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation): Prototype is not F_JITOperation_EJJZ
+        anymore since r160244, so the sh4 specific code is invalid now
+        and has to be removed.
+
+2014-04-15  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Fix precedence issue in JSCell:setRemembered
+
+        Rubber stamped by Filip Pizlo.
+
+        * runtime/JSCell.h:
+        (JSC::JSCell::setRemembered):
+
+2014-04-15  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Objective-C API external object graphs don't handle generational collection properly
+        https://bugs.webkit.org/show_bug.cgi?id=131634
+
+        Reviewed by Geoffrey Garen.
+
+        If the set of Objective-C objects transitively reachable through an object changes, we 
+        need to update the set of opaque roots accordingly. If we don't, the next EdenCollection 
+        won't rescan the external object graph, which would lead us to consider a newly allocated 
+        JSManagedValue to be dead.
+
+        * API/JSBase.cpp:
+        (JSSynchronousEdenCollectForDebugging):
+        * API/JSVirtualMachine.mm:
+        (-[JSVirtualMachine initWithContextGroupRef:]):
+        (-[JSVirtualMachine dealloc]):
+        (-[JSVirtualMachine isOldExternalObject:]):
+        (-[JSVirtualMachine addExternalRememberedObject:]):
+        (-[JSVirtualMachine addManagedReference:withOwner:]):
+        (-[JSVirtualMachine removeManagedReference:withOwner:]):
+        (-[JSVirtualMachine externalRememberedSet]):
+        (scanExternalObjectGraph):
+        (scanExternalRememberedSet):
+        * API/JSVirtualMachineInternal.h:
+        * API/tests/testapi.mm:
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        * heap/Heap.h:
+        (JSC::Heap::slotVisitor):
+        * heap/SlotVisitor.h:
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::containsOpaqueRoot):
+        (JSC::SlotVisitor::containsOpaqueRootTriState):
+
+2014-04-15  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG IR should keep the data flow of doubles and int52's separate from the data flow of JSValue's
+        https://bugs.webkit.org/show_bug.cgi?id=131423
+
+        Reviewed by Geoffrey Garen.
+        
+        This introduces more static typing into DFG IR. Previously we just had the notion of
+        JSValues and Storage. This was weird because doubles weren't always convertible to
+        JSValues, and Int52s weren't always convertible to either doubles or JSValues. We would
+        sort of insert explicit conversion nodes just for the places where we knew that an
+        implicit conversion wouldn't have been possible -- but there was no hard and fast rule so
+        we'd get bugs from forgetting to do the right conversion.
+        
+        This patch introduces a hard and fast rule: doubles can never be implicitly converted to
+        anything but doubles, and likewise Int52's can never be implicitly converted. Conversion
+        nodes are used for all of the conversions. Int52Rep, DoubleRep, and ValueRep are the
+        conversions. They are like Identity but return the same value using a different
+        representation. Likewise, constants may now be represented using either JSConstant,
+        Int52Constant, or DoubleConstant. UseKinds have been adjusted accordingly, as well.
+        Int52RepUse and DoubleRepUse are node uses that mean "the node must be of Int52 (or
+        Double) type". They don't imply checks. There is also DoubleRepRealUse, which means that
+        we speculate DoubleReal and expect Double representation.
+        
+        In addition to simplifying a bunch of rules in the IR and making the IR more verifiable,
+        this also makes it easier to introduce optimizations in the future. It's now possible for
+        AI to model when/how conversion take place. For example if doing a conversion results in
+        NaN sanitization, then AI can model this and can allow us to sink sanitizations. That's
+        what https://bugs.webkit.org/show_bug.cgi?id=131419 will be all about.
+        
+        This was a big change, so I had to do some interesting things, like finally get rid of
+        the DFG's weird variadic template macro hacks and use real C++11 variadic templates. Also
+        the ByteCodeParser no longer emits Identity nodes since that was always pointless.
+        
+        No performance change because this mostly just rationalizes preexisting behavior.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/MacroAssemblerX86.h:
+        * bytecode/CodeBlock.cpp:
+        * bytecode/CodeBlock.h:
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+        (JSC::DFG::AbstractInterpreter::setConstant):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::set):
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        (JSC::DFG::AbstractValue::checkConsistency):
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGBasicBlockInlines.h:
+        (JSC::DFG::BasicBlock::appendNode):
+        (JSC::DFG::BasicBlock::appendNonTerminal):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::constantCSE):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        (JSC::DFG::CSEPhase::int32ToDoubleCSE): Deleted.
+        * dfg/DFGCapabilities.h:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::fixupBlock):
+        * dfg/DFGEdge.h:
+        (JSC::DFG::Edge::willNotHaveCheck):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::run):
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupGetAndSetLocalsInBlock):
+        (JSC::DFG::FixupPhase::observeUseKindOnNode):
+        (JSC::DFG::FixupPhase::fixIntEdge):
+        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
+        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
+        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        (JSC::DFG::FixupPhase::addRequiredPhantom):
+        (JSC::DFG::FixupPhase::addPhantomsIfNecessary):
+        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
+        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock): Deleted.
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::resultFor):
+        (JSC::DFG::useKindFor):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addNode):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertNode):
+        (JSC::DFG::InsertionSet::insertConstant):
+        (JSC::DFG::InsertionSet::insertConstantForUse):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
+        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToIdentity):
+        (WTF::printInternal):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::Node):
+        (JSC::DFG::Node::setResult):
+        (JSC::DFG::Node::result):
+        (JSC::DFG::Node::isConstant):
+        (JSC::DFG::Node::hasConstant):
+        (JSC::DFG::Node::convertToConstant):
+        (JSC::DFG::Node::valueOfJSConstant):
+        (JSC::DFG::Node::hasResult):
+        (JSC::DFG::Node::hasInt32Result):
+        (JSC::DFG::Node::hasInt52Result):
+        (JSC::DFG::Node::hasNumberResult):
+        (JSC::DFG::Node::hasDoubleResult):
+        (JSC::DFG::Node::hasJSResult):
+        (JSC::DFG::Node::hasBooleanResult):
+        (JSC::DFG::Node::hasStorageResult):
+        (JSC::DFG::Node::defaultUseKind):
+        (JSC::DFG::Node::defaultEdge):
+        (JSC::DFG::Node::convertToIdentity): Deleted.
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        (JSC::DFG::canonicalResultRepresentation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGResurrectionForValidationPhase.cpp:
+        (JSC::DFG::ResurrectionForValidationPhase::run):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+        (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
+        (JSC::DFG::SpeculativeJIT::silentFill):
+        (JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
+        (JSC::DFG::JSValueRegsTemporary::~JSValueRegsTemporary):
+        (JSC::DFG::JSValueRegsTemporary::regs):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+        (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        (JSC::DFG::SpeculativeJIT::compileValueRep):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+        (JSC::DFG::SpeculativeJIT::compileAdd):
+        (JSC::DFG::SpeculativeJIT::compileArithSub):
+        (JSC::DFG::SpeculativeJIT::compileArithNegate):
+        (JSC::DFG::SpeculativeJIT::compileArithMul):
+        (JSC::DFG::SpeculativeJIT::compileArithDiv):
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        (JSC::DFG::SpeculativeJIT::compare):
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::speculateNumber):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleReal):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): Deleted.
+        (JSC::DFG::SpeculativeJIT::speculateMachineInt): Deleted.
+        (JSC::DFG::SpeculativeJIT::speculateRealNumber): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::allocate):
+        (JSC::DFG::SpeculativeJIT::use):
+        (JSC::DFG::SpeculativeJIT::boxDouble):
+        (JSC::DFG::SpeculativeJIT::spill):
+        (JSC::DFG::SpeculativeJIT::jsValueResult):
+        (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
+        (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
+        (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
+        (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::shouldNotHaveTypeCheck):
+        (JSC::DFG::mayHaveTypeCheck):
+        (JSC::DFG::isNumerical):
+        (JSC::DFG::isDouble):
+        (JSC::DFG::isCell):
+        (JSC::DFG::usesStructure):
+        (JSC::DFG::useKindForResult):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGVariadicFunction.h: Removed.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
+        (JSC::FTL::LowerDFGToLLVM::compilePhi):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
+        (JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
+        (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+        (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMod):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
+        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compare):
+        (JSC::FTL::LowerDFGToLLVM::boolify):
+        (JSC::FTL::LowerDFGToLLVM::lowInt52):
+        (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
+        (JSC::FTL::LowerDFGToLLVM::lowDouble):
+        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+        (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal):
+        (JSC::FTL::LowerDFGToLLVM::compileInt52ToValue): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt): Deleted.
+        * ftl/FTLValueFormat.cpp:
+        (JSC::FTL::reboxAccordingToFormat):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::sanitizeDouble):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::boxDouble):
+
+2014-04-15  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167199 and r167251.
+        https://bugs.webkit.org/show_bug.cgi?id=131678
+
+        Caused a DYEBench regression and does not seem to improve perf
+        on relevant websites (Requested by rniwa on #webkit).
+
+        Reverted changesets:
+
+        "Rewrite Function.bind as a builtin"
+        https://bugs.webkit.org/show_bug.cgi?id=131083
+        http://trac.webkit.org/changeset/167199
+
+        "Update test result"
+        http://trac.webkit.org/changeset/167251
+
+2014-04-14  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167272.
+        https://bugs.webkit.org/show_bug.cgi?id=131666
+
+        Broke multiple tests (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "Function.bind itself is too slow"
+        https://bugs.webkit.org/show_bug.cgi?id=131636
+        http://trac.webkit.org/changeset/167272
+
+2014-04-14  Geoffrey Garen  <ggaren@apple.com>
+
+        ASSERT when firing low memory warning
+        https://bugs.webkit.org/show_bug.cgi?id=131659
+
+        Reviewed by Mark Hahnenberg.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllCompiledCode): Allow deleteAllCompiledCode to be
+        called when no GC is happening because that is what we do when a low
+        memory warning fires, and it is harmless.
+
+2014-04-14  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        emit_op_put_by_id should not emit a write barrier that filters on value
+        https://bugs.webkit.org/show_bug.cgi?id=131654
+
+        Reviewed by Filip Pizlo.
+
+        The 32-bit implementation does this, and it can cause crashes if we later repatch the 
+        code to allocate and store new Butterflies.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitWriteBarrier): We also weren't verifying that the base was a cell on 
+        32-bit if we were passed ShouldFilterBase. I also took the liberty of sinking the tag 
+        load down into the if statement so that we don't do it if we're not filtering on the value.
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_put_by_id):
+
+2014-04-14  Oliver Hunt  <oliver@apple.com>
+
+        Function.bind itself is too slow
+        https://bugs.webkit.org/show_bug.cgi?id=131636
+
+        Reviewed by Geoffrey Garen.
+
+        Rather than forcing creation of an activation, we now store
+        bound function properties directly on the returned closure.
+        This is necessary to deal with code that creates many function
+        bindings, but does not call them very often.
+
+        This is a 60% speed up in the included js/regress test.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/Function.prototype.js:
+        (bind.bindingFunction):
+        (bind.else.switch.case.1.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
+        (bind.else.switch.case.1.bindingFunction):
+        (bind.else.switch.case.2.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
+        (bind.else.switch.case.2.bindingFunction):
+        (bind.else.switch.case.3.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk):
+        (bind.else.switch.case.3.bindingFunction):
+        (bind.else.switch.bindingFunction):
+        (bind):
+        (bind.else.switch.case.1.bindingFunction.oversizedCall): Deleted.
+        (bind.else.switch.case.2.bindingFunction.oversizedCall): Deleted.
+        (bind.else.switch.case.3.bindingFunction.oversizedCall): Deleted.
+        * runtime/CommonIdentifiers.h:
+
+2014-04-14  Julien Brianceau  <jbriance@cisco.com>
+
+        [sh4] Allow use of SubImmediates in LLINT.
+        https://bugs.webkit.org/show_bug.cgi?id=131608
+
+        Reviewed by Mark Lam.
+
+        Allow use of SubImmediates with const pool so the sh4 architecture can
+        share the arm path for setEntryAddress macro. It reduces architecture
+        specific code and lead to a more optimal generated code for sh4.
+
+        * llint/LowLevelInterpreter.asm:
+        * offlineasm/sh4.rb:
+
+2014-04-14  Andreas Kling  <akling@apple.com>
+
+        Array.prototype.concat should allocate output storage only once.
+        <https://webkit.org/b/131609>
+
+        Do a first pass across 'this' and any arguments to compute the
+        final size of the resulting array from Array.prototype.concat.
+        This avoids having to grow the output incrementally as we go.
+
+        This also includes two other micro-optimizations:
+
+        - Mark getProperty() with ALWAYS_INLINE.
+
+        - Use JSArray::length() instead of taking the generic property
+          lookup path when we know an argument is an Array.
+
+        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
+
+        Reviewed by Oliver & Darin.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        (JSC::arrayProtoFuncConcat):
+
+2014-04-14  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r167249.
+        https://bugs.webkit.org/show_bug.cgi?id=131621
+
+        broke 3 tests on cloop (Requested by kling on #webkit).
+
+        Reverted changeset:
+
+        "Array.prototype.concat should allocate output storage only
+        once."
+        https://bugs.webkit.org/show_bug.cgi?id=131609
+        http://trac.webkit.org/changeset/167249
+
+2014-04-14  Alex Christensen  <achristensen@webkit.org>
+
+        Fixed potential integer truncation.
+        https://bugs.webkit.org/show_bug.cgi?id=131615
+
+        Reviewed by Darin Adler.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::fillNops):
+        Truncate the size_t to an unsigned after it is limited to 15 instead of before.
+
+2014-04-14  Andreas Kling  <akling@apple.com>
+
+        Array.prototype.concat should allocate output storage only once.
+        <https://webkit.org/b/131609>
+
+        Do a first pass across 'this' and any arguments to compute the
+        final size of the resulting array from Array.prototype.concat.
+        This avoids having to grow the output incrementally as we go.
+
+        This also includes two other micro-optimizations:
+
+        - Mark getProperty() with ALWAYS_INLINE.
+
+        - Use JSArray::length() instead of taking the generic property
+          lookup path when we know an argument is an Array.
+
+        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
+
+        Reviewed by Darin Adler.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        (JSC::arrayProtoFuncConcat):
+
+2014-04-14  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] Improve the call site of string comparison in some hot path
+        https://bugs.webkit.org/show_bug.cgi?id=131605
+
+        Reviewed by Darin Adler.
+
+        When resolved, the String of a JSString is never null. It can be empty but not null.
+        The null value is reserved for ropes but those would be resolved when getting the value.
+
+        Consequently, we should use the equal() operation that do not handle null values.
+        Using the StringImpl directly is already common in StringPrototype but it was not used here for some reason.
+
+        * jit/JITOperations.cpp:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::equalSlowCaseInline):
+        (JSC::JSValue::strictEqualSlowCaseInline):
+        (JSC::JSValue::pureStrictEqual):
+
+2014-04-08  Oliver Hunt  <oliver@apple.com>
+
+        Rewrite Function.bind as a builtin
+        https://bugs.webkit.org/show_bug.cgi?id=131083
+
+        Reviewed by Geoffrey Garen.
+
+        This change removes the existing function.bind implementation
+        entirely so JSBoundFunction is no more.
+
+        Instead we just return a regular JS closure with a few
+        private properties hanging off it that allow us to perform
+        the necessary bound function fakery.  While most of this is
+        simple, a couple of key changes:
+
+        - The parser and lexer now directly track whether they're
+          parsing code for call or construct and convert the private
+          name @IsConstructor into TRUETOK or FALSETOK as appropriate.
+          This automatically gives us the ability to vary behaviour
+          from within the builtin. It also leaves a lot of headroom
+          for trivial future improvements.
+        - The instanceof operator now uses the prototypeForHasInstance
+          private name, and we have a helper function to ensure that
+          all objects that need to can update their magical 'prototype'
+          property pair correctly.
+
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/Function.prototype.js:
+        (bind.bindingFunction):
+        (bind.else.bindingFunction):
+        (bind):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::InstanceOfNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        * parser/Lexer.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/ParserModes.h:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::addFunctionProperties):
+        (JSC::functionProtoFuncBind): Deleted.
+        * runtime/JSBoundFunction.cpp: Removed.
+        * runtime/JSBoundFunction.h: Removed.
+        * runtime/JSFunction.cpp:
+        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
+        (JSC::RetrieveCallerFunctionFunctor::operator()):
+        (JSC::retrieveCallerFunction):
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncSetTypeErrorAccessor):
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSObject.h:
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+
+2014-04-12  Filip Pizlo  <fpizlo@apple.com>
+
+        Math.fround() should be an intrinsic
+        https://bugs.webkit.org/show_bug.cgi?id=131583
+
+        Reviewed by Geoffrey Garen.
+        
+        Makes programs that use Math.fround() run up to 6x faster.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithFRound):
+        * runtime/Intrinsic.h:
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+
+2014-04-12  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should use stackmap register liveness
+        https://bugs.webkit.org/show_bug.cgi?id=130791
+
+        Reviewed by Goeffrey Garen.
+        
+        Enable the stackmap register liveness support by fixing the two last bugs:
+        
+        - If everything is dead after the patchpoint - a good possibility for a put_by_id -
+          then we shouldn't crash due to a null scratch buffer.
+        
+        - Always consider callee-saves as if they were live. More precisely, we should
+          consider those callee-saves that are not saved by the enclosing function to be live.
+          For now we do the much simpler thing and consider callee-saves to be always live
+          since it has minimal impact on the scratch register allocator. It will know not to
+          preserve those for calls, anyway.
+        
+        I tried writing a test for the null scratch buffer thing, but failed. I will land the
+        test anyway since it seems useful.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::usedRegistersFor):
+        * jit/ScratchRegisterAllocator.cpp:
+        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall):
+        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall):
+        * runtime/Options.h:
+        * tests/stress/repeated-put-by-id-reallocating-transition.js: Added.
+        (foo):
+
+2014-04-11  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::FixupPhase should insert conversion nodes after the rest of fixup so that we know how the types settled
+        https://bugs.webkit.org/show_bug.cgi?id=131424
+
+        Reviewed by Geoffrey Garen.
+        
+        This defers type conversion injection until we've decided on types. This makes the
+        process of deciding types a bit more flexible - for example we can naturally fixpoint
+        and change our minds. Only when things are settled do we actually insert conversions.
+        
+        This is a necessary prerequisite for keeping double, int52, and JSValue data flow
+        separate. A SetLocal/GetLocal will appear to be JSValue until we fixpoint and realize
+        that there are typed uses. If we were eagerly inserting type conversions then we would
+        first insert a to/from-JSValue conversion in some cases only to then replace it by
+        the other conversions. It's probably trivial to remove those redundant conversions later
+        but I think it's better if we don't insert them to begin with.
+
+        * bytecode/CodeOrigin.h:
+        (JSC::CodeOrigin::operator!):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::run):
+        (JSC::DFG::FixupPhase::fixupBlock):
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
+        (JSC::DFG::FixupPhase::fixEdge):
+        (JSC::DFG::FixupPhase::fixIntEdge):
+        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        (JSC::DFG::FixupPhase::addRequiredPhantom):
+        (JSC::DFG::FixupPhase::addPhantomsIfNecessary):
+        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
+        (JSC::DFG::FixupPhase::observeUntypedEdge): Deleted.
+        (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock): Deleted.
+        (JSC::DFG::FixupPhase::injectInt32ToDoubleNode): Deleted.
+
+2014-04-11  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: code generator should consider enclosing class when computing duplicate type names
+        https://bugs.webkit.org/show_bug.cgi?id=131554
+
+        Reviewed by Timothy Hatcher.
+
+        We need to prepend an enum's enclosing class, if any, so that multiple enums with the same name
+        can coexist without triggering a "duplicate types" error. Now, such enums must be referenced
+        by the enclosing class and enum name.
+
+        Added tests for the new syntax, and rebaselined one test to reflect a previous patch's change.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.type_name): Prepend the enclosing class name.
+        (Type.type_name.is):
+        * replay/scripts/tests/expected/fail-on-duplicate-enum-type.json-error: Added.
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp: Added.
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h: Added.
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h: Rebaseline.
+        * replay/scripts/tests/fail-on-duplicate-enum-type.json: Added.
+        * replay/scripts/tests/generate-enums-with-same-base-name.json: Added.
+
+2014-04-11  Gavin Barraclough  <baraclough@apple.com>
+
+        Rollout - Rewrite Function.bind as a builtin
+        https://bugs.webkit.org/show_bug.cgi?id=131083
+
+        Unreviewed.
+
+        Rolling out r167020 while investigating a performance regression.
+
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeConstructor):
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/Function.prototype.js:
+        (apply):
+        (bind.bindingFunction): Deleted.
+        (bind.else.bindingFunction): Deleted.
+        (bind): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::InstanceOfNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        * parser/Lexer.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/ParserModes.h:
+        * runtime/ArgumentsIteratorConstructor.cpp:
+        (JSC::ArgumentsIteratorConstructor::finishCreation):
+        * runtime/ArrayConstructor.cpp:
+        (JSC::ArrayConstructor::finishCreation):
+        * runtime/BooleanConstructor.cpp:
+        (JSC::BooleanConstructor::finishCreation):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        * runtime/DateConstructor.cpp:
+        (JSC::DateConstructor::finishCreation):
+        * runtime/ErrorConstructor.cpp:
+        (JSC::ErrorConstructor::finishCreation):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/FunctionConstructor.cpp:
+        (JSC::FunctionConstructor::finishCreation):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::addFunctionProperties):
+        (JSC::functionProtoFuncBind):
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::JSArrayBufferConstructor::finishCreation):
+        * runtime/JSBoundFunction.cpp: Added.
+        (JSC::boundFunctionCall):
+        (JSC::boundFunctionConstruct):
+        (JSC::JSBoundFunction::create):
+        (JSC::JSBoundFunction::destroy):
+        (JSC::JSBoundFunction::customHasInstance):
+        (JSC::JSBoundFunction::JSBoundFunction):
+        (JSC::JSBoundFunction::finishCreation):
+        (JSC::JSBoundFunction::visitChildren):
+        * runtime/JSBoundFunction.h: Added.
+        (JSC::JSBoundFunction::targetFunction):
+        (JSC::JSBoundFunction::boundThis):
+        (JSC::JSBoundFunction::boundArgs):
+        (JSC::JSBoundFunction::createStructure):
+        * runtime/JSFunction.cpp:
+        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
+        (JSC::RetrieveCallerFunctionFunctor::operator()):
+        (JSC::retrieveCallerFunction):
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::getOwnNonIndexPropertyNames):
+        (JSC::JSFunction::put):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::JSGenericTypedArrayViewConstructor<ViewClass>::finishCreation):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncSetTypeErrorAccessor): Deleted.
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectPrototypeProperty): Deleted.
+        (JSC::JSObject::putDirectPrototypePropertyWithoutTransitions): Deleted.
+        * runtime/JSObject.h:
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructor::finishCreation):
+        * runtime/MapConstructor.cpp:
+        (JSC::MapConstructor::finishCreation):
+        * runtime/MapIteratorConstructor.cpp:
+        (JSC::MapIteratorConstructor::finishCreation):
+        * runtime/NameConstructor.cpp:
+        (JSC::NameConstructor::finishCreation):
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor::finishCreation):
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::finishCreation):
+        * runtime/SetConstructor.cpp:
+        (JSC::SetConstructor::finishCreation):
+        * runtime/SetIteratorConstructor.cpp:
+        (JSC::SetIteratorConstructor::finishCreation):
+        * runtime/StringConstructor.cpp:
+        (JSC::StringConstructor::finishCreation):
+        * runtime/WeakMapConstructor.cpp:
+        (JSC::WeakMapConstructor::finishCreation):
+
+2014-04-11  David Kilzer  <ddkilzer@apple.com>
+
+        [ASan] Build broke because libCompileRuntimeToLLVMIR.a links to libclang_rt.asan_osx_dynamic.dylib
+        <http://webkit.org/b/131556>
+        <rdar://problem/16591856>
+
+        Reviewed by Brent Fulgham.
+
+        * Configurations/CompileRuntimeToLLVMIR.xcconfig: Clear
+        OTHER_LDFLAGS so the ASan build does not try to link to
+        libclang_rt.asan_osx_dynamic.dylib.
+
+2014-04-11  Mark Lam  <mark.lam@apple.com>
+
+        JSMainThreadExecState::call() should clear exceptions before returning.
+        <https://webkit.org/b/131530>
+
+        Reviewed by Geoffrey Garen.
+
+        Added a version of JSC::call() that return any uncaught exception instead
+        of leaving it pending in the VM.
+
+        As part of this change, I updated various parts of the code base to use the
+        new API as needed.
+
+        * bindings/ScriptFunctionCall.cpp:
+        (Deprecated::ScriptFunctionCall::call):
+        - ScriptFunctionCall::call() is only used by the inspector to inject scripts.
+          The injected scripts that will include Inspector scripts that should catch
+          and handle any exceptions that were thrown.  We should not be seeing any
+          exceptions returned from this call.  However, we do have checks for
+          exceptions in case there are bugs in the Inspector scripts which allowed
+          the exception to leak through.  Hence, it is proper to clear the exception
+          here, and only record the fact that an exception was seen (if present).
+
+        * bindings/ScriptFunctionCall.h:
+        * inspector/InspectorEnvironment.h:
+        * runtime/CallData.cpp:
+        (JSC::call):
+        * runtime/CallData.h:
+
+2014-04-11  Oliver Hunt  <oliver@apple.com>
+
+        Add BuiltinLog function to make debugging builtins easier
+        https://bugs.webkit.org/show_bug.cgi?id=131550
+
+        Reviewed by Andreas Kling.
+
+        Add a logging function that builtins can use for debugging.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncBuiltinLog):
+        * runtime/JSGlobalObjectFunctions.h:
+
+2014-04-11  Julien Brianceau  <jbriance@cisco.com>
+
+        Fix LLInt for sh4 architecture (broken since C stack merge).
+        https://bugs.webkit.org/show_bug.cgi?id=131532
+
+        Reviewed by Mark Lam.
+
+        This patch fixes build and also implements sh4 parts for initPCRelative and
+        setEntryAddress macros introduced in http://trac.webkit.org/changeset/167094.
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * offlineasm/instructions.rb:
+        * offlineasm/sh4.rb:
+
+2014-04-10  Michael Saboff  <msaboff@apple.com>
+
+        Crash beneath DFG JIT code @ video.disney.com
+        https://bugs.webkit.org/show_bug.cgi?id=131447
+
+        Reviewed by Geoffrey Garen.
+
+        The 32-bit path of speculateMisc() uses an 'is not int32' check followed by
+        'tag not less than Undefined' check.  The first check was incorrectly elided if we
+        knew that the value *was* an int32, when it should have been elided if we already
+        knew that the value *was not* an int32.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculateMisc):
+        * tests/stress/test-spec-misc.js: Added test.
+        (getX):
+        (foo):
+        (bar):
+
+2014-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        Make room for additional types in SpeculatedType.h
+        https://bugs.webkit.org/show_bug.cgi?id=131422
+
+        Reviewed by Sam Weinig.
+        
+        This'll make it easier to add DoubleHeavyNaN and DoubleEmptyNaN.
+
+        * bytecode/SpeculatedType.h:
+
+2014-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Compile fix for Win64.
+        https://bugs.webkit.org/show_bug.cgi?id=131508
+
+        Reviewed by Geoffrey Garen.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::fillNops):
+        Added unsigned template parameter to distinguish between size_t and unsigned long.
+
+2014-04-10  Michael Saboff  <msaboff@apple.com>
+
+        LLInt interpreter code should be generated as part of one function
+        https://bugs.webkit.org/show_bug.cgi?id=131205
+
+        Reviewed by Mark Lam.
+
+        Changed the generation of llint opcodes so that they are all part of the same
+        global function, llint_entry.  That function is used to fill in an entry point
+        table that includes each of the opcodes and helpers.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added appropriate use of new -I option to offline assembler and offset
+        generator scripts.
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter.cpp:
+        * llint/LowLevelInterpreter.h:
+        * offlineasm/arm.rb:
+        * offlineasm/arm64.rb:
+        * offlineasm/asm.rb:
+        * offlineasm/ast.rb:
+        * offlineasm/backends.rb:
+        * offlineasm/cloop.rb:
+        * offlineasm/generate_offset_extractor.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/parser.rb:
+        * offlineasm/registers.rb:
+        * offlineasm/self_hash.rb:
+        * offlineasm/settings.rb:
+        * offlineasm/transform.rb:
+        * offlineasm/x86.rb:
+        Added a new "global" keyword to the offline assembler that denotes a label that
+        should be exported.  Added opcode and operand support to get the absolute
+        address of a local label using position independent calculations.  Updated the
+        offline assembler to handle included files, both when generating the checksum
+        as well as including files from other than the local directory via a newly
+        added -I option.  The offline assembler now automatically determines external
+        functions by keeping track of referenced functions that are defined within the
+        assembly source.  This is used both for choosing the correct macro for external
+        references as well as generating the needed EXTERN directives for masm.
+        Updated the generation of the masm only .sym file to be written once at the end
+        of the offline assembler.
+
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::MacroAssemblerCodePtr::createLLIntCodePtr):
+        (JSC::MacroAssemblerCodeRef::createLLIntCodeRef):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        * bytecode/Opcode.h:
+        (JSC::padOpcodeName):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JITStubs.h:
+        * llint/LLIntCLoop.cpp:
+        (JSC::LLInt::initialize):
+        * llint/LLIntData.h:
+        (JSC::LLInt::getCodeFunctionPtr):
+        (JSC::LLInt::getOpcode): Deleted.
+        (JSC::LLInt::getCodePtr): Deleted.
+        * llint/LLIntOpcode.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntThunks.cpp:
+        (JSC::LLInt::functionForCallEntryThunkGenerator):
+        (JSC::LLInt::functionForConstructEntryThunkGenerator):
+        (JSC::LLInt::functionForCallArityCheckThunkGenerator):
+        (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
+        (JSC::LLInt::evalEntryThunkGenerator):
+        (JSC::LLInt::programEntryThunkGenerator):
+        * llint/LLIntThunks.h:
+        Changed references to llint helpers to go through the entry point table populated
+        by llint_entry.  Added helpers to OpcodeID enum for all builds.
+
+        * bytecode/BytecodeList.json:
+        * generate-bytecode-files:
+        * llint/LLIntCLoop.cpp:
+        (JSC::LLInt::CLoop::initialize):
+        Reordered sections to match the order that the functions are added to the entry point
+        table.  Added new "asmPrefix" property for symbols that have one name but are generated
+        with a prefix, e.g. op_enter -> llint_op_enter.  Eliminated the "emitDefineID" property
+        as we are using enums for all bytecode references.  Changed the C Loop only
+        llint_c_loop_init to llint_entry.
+
+2014-04-10  Matthew Mirman  <mmirman@apple.com>
+
+        WIP for inlining C++.  Added a build target to produce LLVM IR.
+        https://bugs.webkit.org/show_bug.cgi?id=130523
+
+        Reviewed by Mark Rowe.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * build-symbol-table-index.py: Added.
+        * build-symbol-table-index.sh: Added.
+        * Configurations/CompileRuntimeToLLVMIR.xcconfig: Added.
+        * copy-llvm-ir-to-derived-sources.sh: Added.
+
+2014-04-10  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
+        https://bugs.webkit.org/show_bug.cgi?id=131341
+
+        Reviewed by Timothy Hatcher.
+
+        Add support for encoding/decoding unsigned long with EncodedValue.
+        It is a distinct type from uint32_t and uint64_t.
+
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::convertTo<unsigned long>):
+        * replay/EncodedValue.h:
+
+2014-04-10  Mark Lam  <mark.lam@apple.com>
+
+        LLINT loadisFromInstruction should handle the big endian case.
+        <https://webkit.org/b/131495>
+
+        Reviewed by Mark Hahnenberg.
+
+        The LLINT loadisFromInstruction macro aims to load the least significant
+        32-bit word from the 64-bit bytecode instruction stream and sign extend
+        it.  For big endian machines, the current implementation would load the
+        wrong 32-bit word.
+
+        Without this fix, the JSC tests will crash on big endian machines.
+        Thanks to Tomas Popela for diagnosing this issue.
+
+        * llint/LowLevelInterpreter.asm:
+
+2014-04-09  Mark Lam  <mark.lam@apple.com>
+
+        Temporarily disable the JIT for the Windows port.
+        <https://webkit.org/b/131470>
+
+        Reviewed by Brent Fulgham.
+
+        This is a temporary stop gap measure to green the Windows bots until
+        we have a fix for https://webkit.org/b/131182.
+
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+
+2014-04-09  Juergen Ributzka  <juergen@apple.com>
+
+        [FTL] Emit multibyte NOPs on X86-64
+        https://bugs.webkit.org/show_bug.cgi?id=131394
+
+        Reviewed by Michael Saboff.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::fillNops):
+
+2014-04-09  Julien Brianceau  <jbriance@cisco.com>
+
+        Get rid of JITOperationWrappers.h header file.
+        https://bugs.webkit.org/show_bug.cgi?id=131450
+
+        Reviewed by Michael Saboff.
+
+        JITOperationWrappers header file contains architecture specific code that is
+        not needed anymore, so get rid of it.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperationWrappers.h: Removed.
+        * jit/JITOperations.cpp:
+
+2014-04-09  Mark Lam  <mark.lam@apple.com>
+
+        Ensure that LLINT accessing of the ProtoCallFrame is big endian friendly.
+        <https://webkit.org/b/131449>
+
+        Reviewed by Mark Hahnenberg.
+
+        Change ProtoCallFrame::paddedArgCount to be of type uint32_t.  The argCount
+        that it pads is of type int anyway.  It doesn't need to be 64 bit.  This
+        also makes it work with the LLINT which is loading it with a loadi
+        instruction.
+
+        We should add the PayLoadOffset to ProtoCallFrame::argCountAndCodeOriginValue
+        when loading the argCount.
+
+        The paddedArgCount issue was causing failures when running the JSC tests on a
+        64-bit big endian machine.  In this case, the paddedArgCount in the
+        ProtoCallFrame has the value 2.  However, because the paddedArgCount was stored
+        as a 64-bit size_t and the LLINT was loading only the low address 32-bits of
+        that field, the LLINT got a value of 0 instead of the expected 2.  With this
+        patch, we now have a matching store and load of a 32-bit value, and endianness
+        no longer comes into play.
+
+        As for ProtoCallFrame::argCountAndCodeOriginValue, the argCount is stored in
+        the payload field of the Register.  In the definition of EncodedValueDescriptor,
+        We already ensure that that the payload is in the least significant 32-bits for
+        little endian machines, and in the most significant 32-bits for big endian
+        machines.  This means that there is no endianness bug when loading this value
+        using loadi.  However, adding the PayLoadOffset clarifies the intent of the
+        code to load the payload part of the Register value.
+
+        * interpreter/ProtoCallFrame.h:
+        (JSC::ProtoCallFrame::setPaddedArgCount):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-04-08  Oliver Hunt  <oliver@apple.com>
+
+        Rewrite Function.bind as a builtin
+        https://bugs.webkit.org/show_bug.cgi?id=131083
+
+        Reviewed by Geoffrey Garen.
+
+        This change removes the existing function.bind implementation
+        entirely so JSBoundFunction is no more.
+
+        Instead we just return a regular JS closure with a few
+        private properties hanging off it that allow us to perform
+        the necessary bound function fakery.  While most of this is
+        simple, a couple of key changes:
+
+        - The parser and lexer now directly track whether they're
+          parsing code for call or construct and convert the private
+          name @IsConstructor into TRUETOK or FALSETOK as appropriate.
+          This automatically gives us the ability to vary behaviour
+          from within the builtin. It also leaves a lot of headroom
+          for trivial future improvements.
+        - The instanceof operator now uses the prototypeForHasInstance
+          private name, and we have a helper function to ensure that
+          all objects that need to can update their magical 'prototype'
+          property pair correctly.
+
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/Function.prototype.js:
+        (bind.bindingFunction):
+        (bind.else.bindingFunction):
+        (bind):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::InstanceOfNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        * parser/Lexer.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/ParserModes.h:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::addFunctionProperties):
+        (JSC::functionProtoFuncBind): Deleted.
+        * runtime/JSBoundFunction.cpp: Removed.
+        * runtime/JSBoundFunction.h: Removed.
+        * runtime/JSFunction.cpp:
+        (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
+        (JSC::RetrieveCallerFunctionFunctor::operator()):
+        (JSC::retrieveCallerFunction):
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncSetTypeErrorAccessor):
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSObject.h:
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+
+2014-04-08  Jon Lee  <jonlee@apple.com>
+
+        Turn MSE on by default
+        https://bugs.webkit.org/show_bug.cgi?id=131313
+        <rdar://problem/16525223>
+
+        Reviewed by Jer Noble.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-04-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Prevent deadlocks receiving WIRPermissionDenied message
+        https://bugs.webkit.org/show_bug.cgi?id=131406
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::stop):
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        Provide a way to stop externally and a path to stop when in
+        the middle of handling a message already with the locked mutex.
+
+        * inspector/remote/RemoteInspectorXPCConnection.h:
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+        (Inspector::RemoteInspectorXPCConnection::close):
+        (Inspector::RemoteInspectorXPCConnection::closeFromMessage):
+        Provide a way to close externally and a path to close when in
+        the middle of handling a message already with a mutex.
+
+2014-04-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Address stale FIXMEs concerning console in JSContext inspection
+        https://bugs.webkit.org/show_bug.cgi?id=131398
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        The console object can be deleted from a page or JSContext,
+        so keep code that expects that it could have been deleted
+        to be resilient in those cases.
+
+        * inspector/JSGlobalObjectScriptDebugServer.h:
+        * inspector/agents/JSGlobalObjectDebuggerAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
+        Change the FIXMEs to NOTEs that explain why these functions
+        have empty implementations for JSContext inspection.
+
+2014-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix a goofy assertion to fix debug.
+
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::isSetter):
+        (JSC::PutByIdAccess::oldStructure):
+        (JSC::PutByIdAccess::chain):
+        (JSC::PutByIdAccess::stubRoutine):
+        (JSC::PutByIdAccess::customSetter):
+
+2014-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        Fail silently if the LLVM dylib isn't found
+        https://bugs.webkit.org/show_bug.cgi?id=131385
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * llvm/InitializeLLVM.cpp:
+        (JSC::initializeLLVM):
+        * llvm/InitializeLLVM.h:
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::initializeLLVMPOSIX):
+
+2014-04-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Repatch should support setters and plant calls to them directly
+        https://bugs.webkit.org/show_bug.cgi?id=130750
+
+        Reviewed by Geoffrey Garen.
+        
+        All of the infrastructure was in place so this just enables setter optimization.
+        
+        This is a 12x speed-up on setter microbenchmarks. This is a 1% speed-up on Octane.
+
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PutByIdAccess::visitWeak):
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::setter):
+        (JSC::PutByIdAccess::customSetter): Deleted.
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * jit/Repatch.cpp:
+        (JSC::toString):
+        (JSC::kindFor):
+        (JSC::customFor):
+        (JSC::generateByIdStub):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::setCacheableSetter):
+        (JSC::PutPropertySlot::isCacheableSetter):
+        (JSC::PutPropertySlot::isCacheableCustom):
+        (JSC::PutPropertySlot::setCacheableCustomProperty): Deleted.
+        (JSC::PutPropertySlot::isCacheableCustomProperty): Deleted.
+        * tests/stress/setter.js: Added.
+        (foo):
+
+2014-04-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Setters are just getters that take an extra argument and don't return a value
+        https://bugs.webkit.org/show_bug.cgi?id=131336
+
+        Reviewed by Geoffrey Garen.
+        
+        Other than that, they're totally the same thing.
+        
+        This isn't as dumb as it sounds.        
+
+        Most of the work in calling an accessor has to do with emitting the necessary checks for
+        figuring out whether we're calling the accessor we expected, followed by the boilerplate
+        needed for setting up a call inside of a stub. It makes sense for the code to be totally
+        common.
+
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        (JSC::AssemblyHelpers::moveTrustedValue):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupResults):
+        * jit/Repatch.cpp:
+        (JSC::kindFor):
+        (JSC::customFor):
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        (JSC::generateGetByIdStub): Deleted.
+        (JSC::emitCustomSetterStub): Deleted.
+        * runtime/JSCJSValue.h:
+        (JSC::JSValue::asValue):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::cachedOffset):
+
+2014-04-07  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Hang in debuggable application after receiving WIRPermissionDenied
+        https://bugs.webkit.org/show_bug.cgi?id=131321
+
+        Reviewed by Mark Rowe.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::xpcConnectionReceivedMessage):
+        Avoid attempting to take the same lock twice. Move the received message
+        lock grab after the WIRPermissionDenied branch, which takes the lock
+        inside RemoteInspector::stop.
+
+2014-04-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Make it possible to disable some of the FTL's more interesting features
+        https://bugs.webkit.org/show_bug.cgi?id=131312
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        (JSC::DFG::ByteCodeParser::parse):
+        * runtime/Options.h:
+
+2014-04-04  Mark Lam  <mark.lam@apple.com>
+
+        Date object needs to check for ES5 15.9.1.14 TimeClip limit.
+        <https://webkit.org/b/131248>
+
+        Reviewed by Mark Hahnenberg.
+
+        The current Date object code does not adequately check for the ES5
+        15.9.1.14 TimeClip limit.  As a result, some calculations can underflow
+        / overflow and produce unexpected results.
+
+        For example, we were getting an assertion failure in
+        WTF::equivalentYearForDST() due int underflows in this function, which
+        in turn were due to an int overflow in WTF::msToYear().
+
+        This patch adds the needed checks, and adds some assertions to ensure
+        that the used values are sane.
+
+        The changes have no noticeable impact on benchmark results.
+
+        * runtime/DateConstructor.cpp:
+        (JSC::callDate):
+        * runtime/JSDateMath.cpp:
+        (JSC::localTimeOffset):
+        (JSC::gregorianDateTimeToMS):
+        (JSC::msToGregorianDateTime):
+        (JSC::parseDateFromNullTerminatedCharacters):
+        (JSC::parseDate):
+        * runtime/JSDateMath.h:
+        - parseDateFromNullTerminatedCharacters() does not need to be public.
+          Made it a static function.
+        * runtime/VM.cpp:
+        (JSC::VM::resetDateCache):
+        - Changed cachedDateStringValue to use std::numeric_limits<double>::quiet_NaN()
+          to be consistent with other Date code.
+
+2014-04-06  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Unreviewed speculative 32-bit buildfix after r166837.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::updateObjectCounts):
+
+2014-04-06  Dan Bernstein  <mitz@apple.com>
+
+        32-bit build fix.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::setInputCursor):
+
+2014-04-04  Brian J. Burg  <burg@cs.washington.edu>
+
+        Enable WEB_REPLAY for PLATFORM(MAC)
+        https://bugs.webkit.org/show_bug.cgi?id=130700
+
+        Reviewed by Timothy Hatcher.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-04-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Add missing files from r166837
+
+        * heap/GCLogging.cpp: Added.
+        (JSC::GCLogging::levelAsString):
+        (JSC::LoggingFunctor::LoggingFunctor):
+        (JSC::LoggingFunctor::~LoggingFunctor):
+        (JSC::LoggingFunctor::operator()):
+        (JSC::LoggingFunctor::log):
+        (JSC::LoggingFunctor::reviveCells):
+        (JSC::LoggingFunctor::returnValue):
+        (JSC::GCLogging::dumpObjectGraph):
+        * heap/GCLogging.h: Added.
+
+2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Enhanced GC logging
+        https://bugs.webkit.org/show_bug.cgi?id=131246
+
+        Reviewed by Geoff Garen.
+
+        Getting data on the state of the JSC Heap at runtime is currently in a sad state. 
+        The OBJECT_MARK_LOGGING macro enables some basic GC logging, but it requires a full 
+        recompile to turn it on. It would be nice if we could runtime enable our GC logging 
+        infrastructure while incurring minimal cost when it is disabled. 
+
+        It would also be nice to get a complete view of the Heap. Currently OBJECT_MARK_LOGGING 
+        provides us with the discovered roots along with parent-child relationships as objects 
+        are scanned. However, once an object is scanned it will never be declared as the child 
+        of another object during that collection. This gives us a tree-like view of the 
+        Heap (i.e. each scanned node only reports having a single parent), where the actual 
+        Heap can be an arbitrary graph.
+
+        This patch replaces OBJECT_MARK_LOGGING and gives us these nice to haves. First it enhances 
+        our logGC() runtime Option by changing it to be a tri-state value of None, Basic, or Verbose 
+        logging levels. None means no logging is done, Basic is what logGC() = true would have done 
+        prior to this patch, and Verbose logs all object relationships.
+
+        JSCell has new dump/dumpToStream methods, the latter of which is "virtual" to allow 
+        subclasses to override the default string representation that will be dumped. These 
+        methods allow JSCells to be dumped using the standard dataLog() calls similar to much of
+        the logging infrastructure in our compilers.
+
+        This patch also adds a GCLogging class that handles dumping the relationships between objects.
+        It does this by using the pre-existing visitChildren virtual methods to obtain the immediate
+        children of each live cell at the end of garbage collection.
+
+        This change meets our goal of being neutral on the benchmarks we track.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/GCLogging.cpp: Added.
+        (JSC::GCLogging::levelAsString):
+        (JSC::LoggingFunctor::LoggingFunctor):
+        (JSC::LoggingFunctor::operator()):
+        (JSC::LoggingFunctor::log):
+        (JSC::LoggingFunctor::reviveCells):
+        (JSC::LoggingFunctor::returnValue):
+        (JSC::GCLogging::dumpObjectGraph):
+        * heap/GCLogging.h: Added.
+        * heap/GCSegmentedArray.h:
+        (JSC::GCSegmentedArray::begin):
+        (JSC::GCSegmentedArray::end):
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::visitSmallStrings):
+        (JSC::Heap::visitConservativeRoots):
+        (JSC::Heap::visitCompilerWorklists):
+        (JSC::Heap::visitProtectedObjects):
+        (JSC::Heap::visitTempSortVectors):
+        (JSC::Heap::visitArgumentBuffers):
+        (JSC::Heap::visitException):
+        (JSC::Heap::visitStrongHandles):
+        (JSC::Heap::visitHandleStack):
+        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
+        (JSC::Heap::visitWeakHandles):
+        (JSC::Heap::updateObjectCounts):
+        (JSC::Heap::collect):
+        (JSC::Heap::didFinishCollection):
+        * heap/Heap.h:
+        * heap/MarkStack.h:
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::dump):
+        * heap/SlotVisitor.h:
+        (JSC::SlotVisitor::markStack):
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::internalAppend):
+        * runtime/ClassInfo.h:
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::dump):
+        (JSC::JSCell::dumpToStream):
+        (JSC::JSCell::className):
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::visitChildren):
+        * runtime/JSString.cpp:
+        (JSC::JSString::dumpToStream):
+        (JSC::JSString::visitChildren):
+        * runtime/JSString.h:
+        (JSC::JSString::length):
+        (JSC::JSRopeString::RopeBuilder::length):
+        * runtime/Options.cpp:
+        (JSC::parse):
+        (JSC::Options::setOption):
+        (JSC::Options::dumpOption):
+        * runtime/Options.h:
+
+2014-04-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Remove bogus ASSERT in -JSVirtualMachine scanObjectGraph
+        https://bugs.webkit.org/show_bug.cgi?id=131251
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSVirtualMachine.mm:
+        (scanExternalObjectGraph):
+        * API/tests/testapi.mm:
+
+2014-04-03  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: hook up probe samples to TimelineAgent's records
+        https://bugs.webkit.org/show_bug.cgi?id=131127
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/ScriptDebugListener.h: Add a proper forward declaration for ScriptBreakpointAction.
+
+2014-04-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r166820.
+        https://bugs.webkit.org/show_bug.cgi?id=131256
+
+        Broke builds. (Requested by bdash on #webkit).
+
+        Reverted changeset:
+
+        "WIP for inlining C++.  Added a build target to produce llvm
+        ir."
+        https://bugs.webkit.org/show_bug.cgi?id=130523
+        http://trac.webkit.org/changeset/166820
+
+2014-04-04  Matthew Mirman  <mmirman@apple.com>
+
+        WIP for inlining C++.  Added a build target to produce llvm ir.
+        https://bugs.webkit.org/show_bug.cgi?id=130523
+
+        Reviewed by Filip Pizlo.
+
+        The llvm ir gets placed JavaScriptCoreRuntimeToLLVMir.build with the extension .o
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * build_index.py: Added.
+        * Configurations/CompileRuntimeToLLVMir.xcconfig: Added.
+
+2014-04-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Log JS Exceptions to System Console if JavaScriptCoreOutputConsoleMessagesToSystemConsole enabled
+        https://bugs.webkit.org/show_bug.cgi?id=131241
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Log the exception to the system console if system console output is enabled.
+
+2014-04-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Provide a way for JSContext console to log to system console
+        https://bugs.webkit.org/show_bug.cgi?id=131050
+
+        Reviewed by Timothy Hatcher.
+
+        Applications often re-expose some log -> NSLog functionality.
+        We already have the capability ourselves, which includes extra
+        information such as sourceURL:line:column, all arguments instead
+        of just one argument, and backtrace information on console.trace.
+        Therefore it would be convenient if developers could just use
+        the built-in console.log and get rich output in both the inspector
+        and the console, without writing their own logger.
+
+        The logging will be enabled in debug builds by default, and can be enabled
+        otherwise by setting a user default before creating the first context.
+        
+        For example, in the application itself:
+
+            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"JavaScriptCoreOutputConsoleMessagesToSystemConsole"];
+
+        Or from outside the application:
+        
+            shell> defaults write <app-bundle-identifier> JavaScriptCoreOutputConsoleMessagesToSystemConsole -bool YES
+
+        * inspector/JSConsoleClient.h:
+        * inspector/JSConsoleClient.cpp:
+        (Inspector::JSConsoleClient::logToSystemConsole):
+        (Inspector::JSConsoleClient::setLogToSystemConsole):
+        (Inspector::JSConsoleClient::initializeLogToSystemConsole):
+        (Inspector::JSConsoleClient::JSConsoleClient):
+        Global setting for logging to system console. Enabled on
+        debug builds, and by a user default on supported platforms.
+
+        (Inspector::JSConsoleClient::messageWithTypeAndLevel):
+        Log to system console when the static setting is enabled.
+
+        * runtime/ConsoleClient.h:
+        * runtime/ConsoleClient.cpp:
+        (JSC::appendURLAndPosition):
+        (JSC::appendMessagePrefix):
+        (JSC::ConsoleClient::printConsoleMessage):
+        (JSC::ConsoleClient::printConsoleMessageWithArguments):
+        Clean up printing. Build strings and use WTFLogAlways instead of printf
+        for consistant logging.
+
+        * runtime/ConsoleClient.cpp:
+        (JSC::ConsoleClient::printConsoleMessageWithArguments):
+        Clean up printing. If there is no source URL, don't print a leading colon.
+
+2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Use JSCell::indexingType instead of Structure::indexingType wherever possible
+        https://bugs.webkit.org/show_bug.cgi?id=131230
+
+        Reviewed by Mark Lam.
+
+        Avoid the indirection through the Structure.
+
+        * bytecode/ArrayAllocationProfile.cpp:
+        (JSC::ArrayAllocationProfile::updateIndexingType):
+        * bytecode/ArrayAllocationProfile.h:
+        (JSC::ArrayAllocationProfile::selectIndexingType):
+        * heap/HeapStatistics.cpp:
+        (JSC::StorageStatistics::operator()):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::attemptFastSort):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::objectPrototypeIsSane):
+        (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
+        (JSC::JSGlobalObject::stringPrototypeChainIsSane):
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::create):
+
+2014-04-04  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Use JSCell::type instead of TypeInfo::type wherever possible
+        https://bugs.webkit.org/show_bug.cgi?id=131229
+
+        Reviewed by Michael Saboff.
+
+        Avoid going through the Structure and reifying the TypeInfo.
+
+        * runtime/Executable.h:
+        (JSC::ExecutableBase::isEvalExecutable):
+        (JSC::ExecutableBase::isProgramExecutable):
+
+2014-04-03  Andreas Kling  <akling@apple.com>
+
+        Fast-path for casting JS wrappers to JSNode.
+        <https://webkit.org/b/131196>
+
+        Allow code outside of JSC (well, WebCore) to extend the JSType spectrum
+        a little bit. We do this by exposing a LastJSCObjectType constant so
+        WebCore can encode its own wrapper types after that.
+
+        Reviewed by Mark Hahnenberg and Geoff Garen.
+
+        * runtime/JSType.h:
+
+            Added LastJSCObjectType for use by WebCore.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::isVariableObject):
+
+            Updated since this can no longer assume that types >= VariableObjectType
+            are all variable objects.
+
+2014-04-03  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        All Heap::writeBarriers should be inline
+        https://bugs.webkit.org/show_bug.cgi?id=131197
+
+        Reviewed by Mark Lam.
+
+        One is in a JSCellInlines.h, another is in Heap.cpp. These are all critical 
+        enough and small enough to belong in HeapInlines.h. Also added the proper 
+        ENABLE(GGC) ifdefs to minimize the cost of C++ barriers for !ENABLE(GGC) builds.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::writeBarrier): Deleted.
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::writeBarrier):
+        * runtime/JSCellInlines.h:
+        (JSC::Heap::writeBarrier): Deleted.
+
+2014-04-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: JSContext inspection provide a way to opt-out of including Native Call Stacks in Exception traces reported to Web Inspector
+        https://bugs.webkit.org/show_bug.cgi?id=131186
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSContextPrivate.h:
+        * API/JSContext.mm:
+        (-[JSContext _includesNativeCallStackWhenReportingExceptions]):
+        (-[JSContext _setIncludesNativeCallStackWhenReportingExceptions:]):
+        JSContext ObjC SPI to opt-out of including native call stacks in exceptions.
+
+        * API/JSContextRefPrivate.h:
+        * API/JSContextRef.cpp:
+        (JSGlobalContextGetIncludesNativeCallStackWhenReportingExceptions):
+        (JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions):
+        JSContext C SPI to opt-out of including native call stacks in exceptions.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Only include the native call stack if the setting is enabled. It is enabled by default.
+
+2014-04-03  Mark Lam  <mark.lam@apple.com>
+
+        Fix bit rot in ARMv7 JIT probe mechanism.
+        <https://webkit.org/b/131167>
+
+        Reviewed by Geoffrey Garen.
+
+        1. The macro assembler does not support pushing the SP register.  Worked
+           around this by pushing the LR register as a placeholder, and then
+           writing the original SP value to that slot.
+        2. The CPUState field in the ProbeContext needs to be aligned on a 4
+           byte boundary, not an 8 byte boundary.
+
+        * assembler/MacroAssemblerARMv7.cpp:
+        (JSC::MacroAssemblerARMv7::probe):
+        * jit/JITStubsARMv7.h:
+
+2014-04-02  Mark Lam  <mark.lam@apple.com>
+
+        ARMv7 compare32() should not use TST to do CMP's job.
+        <https://webkit.org/b/131146>
+
+        Reviewed by Geoffrey Garen.
+
+        The ARMv7 implementation of "compare32(RegisterID left, TrustedImm32 right)"
+        was using "tst reg, reg" to implement "cmp reg, #0".  Unfortunately, the tst
+        instruction doesn't set the Overflow (V) flag and this results in random
+        results depending on whether there was a preceeding instruction that did set
+        the Overflow (V) flag.  This issue was causing emscripten-cube2hash to run
+        with a lot of OSR exits where not expected as well as producing wrong results.
+
+        The fix is to use "cmp reg, #0" to do the job properly.
+
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::compare32):
+
+2014-04-02  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        CodeBlockSet should be generational
+        https://bugs.webkit.org/show_bug.cgi?id=127152
+
+        Reviewed by Geoffrey Garen.
+
+        During EdenCollections we now only visit those CodeBlocks that:
+        a) Are new since the last collection if they were somehow otherwise reachable.
+        b) Are reachable from an Executable that is part of the remembered set.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock): Initialize uninitialized variables.
+        (JSC::CodeBlock::visitAggregate): Move the addition of the weak reference harvester after the
+        shouldImmediatelyAssumeLivenessDuringScan check since it's redundant if we assume liveness.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::forEachRelatedCodeBlock): Executes a functor for each CodeBlock reachable from the current CodeBlock (including this).
+        We use this to clear marks for the CodeBlocks of remembered Executables (see: CodeBlockSet::clearMarksForEdenCollection).
+        (JSC::CodeBlockSet::mark): Also check the set of new CodeBlocks for memebership when doing conservative scanning.
+        (JSC::ScriptExecutable::forEachCodeBlock): Executes a functor for each of this Executable's CodeBlocks.
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::~CodeBlockSet):
+        (JSC::CodeBlockSet::add):
+        (JSC::CodeBlockSet::promoteYoungCodeBlocks): Moves all CodeBlocks currently in the set of new CodeBlocks into 
+        the set of old CodeBlocks.
+        (JSC::CodeBlockSet::clearMarksForFullCollection): Clears the marks for all CodeBlocks.
+        (JSC::CodeBlockSet::clearMarksForEdenCollection): Clears the marks for CodeBlocks owned by Executables in the 
+        remembered set. When an Executable is added to the remembered set it's typically because we need to do something 
+        with its CodeBlock.
+        (JSC::CodeBlockSet::clearMarks):
+        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): Fixpoints over either just the new CodeBlocks or all CodeBlocks
+        to determine which CodeBlocks are dead and eagerly finalizes/deletes them.
+        (JSC::CodeBlockSet::remove):
+        (JSC::CodeBlockSet::traceMarked): Iterate only the currently executing CodeBlocks instead of all CodeBlocks.
+        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks): Clear m_mayBeExecuting for all currently executing 
+        CodeBlocks because we no longer always do this at the beginning of EdenCollections.
+        * heap/CodeBlockSet.h:
+        (JSC::CodeBlockSet::iterate):
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::deleteAllCompiledCode):
+        (JSC::Heap::deleteUnmarkedCompiledCode):
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::installCode): Write barrier code on installation. We do this due to the following situation:
+        a) A CodeBlock is created and is compiled on a DFG worker thread.
+        b) No GC happens.
+        c) The CodeBlock has finished being compiled and is installed in the Executable.
+        d) The function never executes before the next GC.
+        e) The next GC needs needs to visit the new CodeBlock but the Executable won't be revisited unless 
+            it's added to the remembered set.
+
+2014-04-02  Mark Lam  <mark.lam@apple.com>
+
+        Added some more dataLog info for OSR exits.
+        <https://webkit.org/b/131120>
+
+        Reviewed by Michael Saboff.
+
+        Adding info about the OSR exit index, the bytecode index of the bytecode
+        that is OSR exiting, and the reason for the OSR exit.  This change is
+        for debugging code which only comes into play when we use the
+        --printEachOSRExit option.
+
+        * dfg/DFGOSRExit.h:
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOperations.cpp:
+
+2014-04-02  Martin Robinson  <mrobinson@igalia.com>
+
+        REGRESSION(r165704): [GTK] Inspector resources not correctly generated
+        https://bugs.webkit.org/show_bug.cgi?id=130343
+
+        Reviewed by Gustavo Noronha Silva.
+
+        * CMakeLists.txt: We generate the inspector JavaScript file into a directory like the one
+        in which it should be distributed. This allows us to more easily package it for GTK+.
+
+2014-04-01  Timothy Hatcher  <timothy@apple.com>
+
+        Remove HeapProfiler from the Web Inspector protocol.
+
+        https://bugs.webkit.org/show_bug.cgi?id=131070
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/agents/InspectorConsoleAgent.h:
+        * inspector/agents/JSGlobalObjectConsoleAgent.cpp:
+        (Inspector::JSGlobalObjectConsoleAgent::addInspectedHeapObject): Deleted.
+        * inspector/agents/JSGlobalObjectConsoleAgent.h:
+        * inspector/protocol/Console.json:
+
+2014-03-31  Simon Fraser  <simon.fraser@apple.com>
+
+        Enable WEB_TIMING on Mac and iOS
+        https://bugs.webkit.org/show_bug.cgi?id=128064
+
+        Reviewed by Sam Weinig, Brent Fulgham.
+
+        Enable WEB_TIMING.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-03-31  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r166415): JSObject{Get,Set}Private() don't work with proxies objects
+        https://bugs.webkit.org/show_bug.cgi?id=130992
+
+        Reviewed by Mark Hahnenberg.
+
+        Forward JSObjectGetPrivate() and JSObjectSetPrivate() to the wrapped object.
+
+        * API/JSObjectRef.cpp:
+        (JSObjectGetPrivate):
+        (JSObjectSetPrivate):
+        * API/tests/testapi.c:
+        (main): Added new test case to validate we are properly foarwarding.
+
+2014-03-31  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Improve GC_LOGGING
+        https://bugs.webkit.org/show_bug.cgi?id=130988
+
+        Reviewed by Geoffrey Garen.
+
+        GC_LOGGING can be useful for diagnosing where we're spending our time during collection, 
+        but it doesn't distinguish between Eden and Full collections in the data it gathers. This
+        patch updates it so that it can. It also adds the process ID to the beginning of each line 
+        of input to be able to distinguish between the output of multiple processes exiting at the 
+        same time.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+
+2014-03-31  Dean Jackson  <dino@apple.com>
+
+        Remove WEB_ANIMATIONS
+        https://bugs.webkit.org/show_bug.cgi?id=130989
+
+        Reviewed by Simon Fraser.
+
+        Remove this feature flag until we plan to implement.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-03-31  Filip Pizlo  <fpizlo@apple.com>
+
+        More validation for FTL inline caches
+        https://bugs.webkit.org/show_bug.cgi?id=130948
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * runtime/Options.h:
+
+2014-03-31  Filip Pizlo  <fpizlo@apple.com>
+
+        LLVM IR for store barriers should be nicely arranged and they don't need exception checks
+        https://bugs.webkit.org/show_bug.cgi?id=130950
+
+        Reviewed by Mark Hahnenberg.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+
+2014-03-31  Raphael Kubo da Costa  <raphael.kubo.da.costa@intel.com>
+
+        [CMake] Stop checking for WTF_USE_ICU_UNICODE.
+        https://bugs.webkit.org/show_bug.cgi?id=130965
+
+        Reviewed by Martin Robinson.
+
+        This is somewhat of a follow-up to r162782, which got rid of
+        WTF_USE_ICU_UNICODE in CMake but did not remove the check in JSC's
+        CMakeLists.txt. This meant the includes and libraries were not
+        being properly included since then.
+
+        * CMakeLists.txt:
+
+2014-03-31  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Remove hostThisRegister() and hostThisValue()
+        https://bugs.webkit.org/show_bug.cgi?id=130895
+
+        Reviewed by Geoffrey Garen.
+
+        Removed hostThisRegister() and hostThisValue() and instead use thisArgumentOffset() and thisValue() respectively.
+
+        * API/APICallbackFunction.h:
+        (JSC::APICallbackFunction::call):
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::call):
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::jsInjectedScriptHostPrototypeAttributeEvaluate):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionInternalConstructorName):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionType):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionFunctionDetails):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionGetInternalProperties):
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        (Inspector::jsJavaScriptCallFramePrototypeFunctionEvaluate):
+        (Inspector::jsJavaScriptCallFramePrototypeFunctionScopeType):
+        (Inspector::jsJavaScriptCallFrameAttributeCaller):
+        (Inspector::jsJavaScriptCallFrameAttributeSourceID):
+        (Inspector::jsJavaScriptCallFrameAttributeLine):
+        (Inspector::jsJavaScriptCallFrameAttributeColumn):
+        (Inspector::jsJavaScriptCallFrameAttributeFunctionName):
+        (Inspector::jsJavaScriptCallFrameAttributeScopeChain):
+        (Inspector::jsJavaScriptCallFrameAttributeThisObject):
+        (Inspector::jsJavaScriptCallFrameAttributeType):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::hostThisRegister): Deleted.
+        (JSC::ExecState::hostThisValue): Deleted.
+        * runtime/Arguments.cpp:
+        (JSC::argumentsFuncIterator):
+        * 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::arrayProtoFuncReduce):
+        (JSC::arrayProtoFuncReduceRight):
+        (JSC::arrayProtoFuncIndexOf):
+        (JSC::arrayProtoFuncLastIndexOf):
+        (JSC::arrayProtoFuncValues):
+        (JSC::arrayProtoFuncEntries):
+        (JSC::arrayProtoFuncKeys):
+        * runtime/BooleanPrototype.cpp:
+        (JSC::booleanProtoFuncToString):
+        (JSC::booleanProtoFuncValueOf):
+        * runtime/ConsolePrototype.cpp:
+        (JSC::consoleLogWithLevel):
+        (JSC::consoleProtoFuncClear):
+        (JSC::consoleProtoFuncDir):
+        (JSC::consoleProtoFuncDirXML):
+        (JSC::consoleProtoFuncTable):
+        (JSC::consoleProtoFuncTrace):
+        (JSC::consoleProtoFuncAssert):
+        (JSC::consoleProtoFuncCount):
+        (JSC::consoleProtoFuncProfile):
+        (JSC::consoleProtoFuncProfileEnd):
+        (JSC::consoleProtoFuncTime):
+        (JSC::consoleProtoFuncTimeEnd):
+        (JSC::consoleProtoFuncTimeStamp):
+        (JSC::consoleProtoFuncGroup):
+        (JSC::consoleProtoFuncGroupCollapsed):
+        (JSC::consoleProtoFuncGroupEnd):
+        * runtime/DatePrototype.cpp:
+        (JSC::formateDateInstance):
+        (JSC::dateProtoFuncToISOString):
+        (JSC::dateProtoFuncToLocaleString):
+        (JSC::dateProtoFuncToLocaleDateString):
+        (JSC::dateProtoFuncToLocaleTimeString):
+        (JSC::dateProtoFuncGetTime):
+        (JSC::dateProtoFuncGetFullYear):
+        (JSC::dateProtoFuncGetUTCFullYear):
+        (JSC::dateProtoFuncGetMonth):
+        (JSC::dateProtoFuncGetUTCMonth):
+        (JSC::dateProtoFuncGetDate):
+        (JSC::dateProtoFuncGetUTCDate):
+        (JSC::dateProtoFuncGetDay):
+        (JSC::dateProtoFuncGetUTCDay):
+        (JSC::dateProtoFuncGetHours):
+        (JSC::dateProtoFuncGetUTCHours):
+        (JSC::dateProtoFuncGetMinutes):
+        (JSC::dateProtoFuncGetUTCMinutes):
+        (JSC::dateProtoFuncGetSeconds):
+        (JSC::dateProtoFuncGetUTCSeconds):
+        (JSC::dateProtoFuncGetMilliSeconds):
+        (JSC::dateProtoFuncGetUTCMilliseconds):
+        (JSC::dateProtoFuncGetTimezoneOffset):
+        (JSC::dateProtoFuncSetTime):
+        (JSC::setNewValueFromTimeArgs):
+        (JSC::setNewValueFromDateArgs):
+        (JSC::dateProtoFuncSetYear):
+        (JSC::dateProtoFuncGetYear):
+        (JSC::dateProtoFuncToJSON):
+        * runtime/ErrorPrototype.cpp:
+        (JSC::errorProtoFuncToString):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString):
+        (JSC::functionProtoFuncBind):
+        * runtime/NamePrototype.cpp:
+        (JSC::privateNameProtoFuncToString):
+        * runtime/NumberPrototype.cpp:
+        (JSC::numberProtoFuncToExponential):
+        (JSC::numberProtoFuncToFixed):
+        (JSC::numberProtoFuncToPrecision):
+        (JSC::numberProtoFuncClz):
+        (JSC::numberProtoFuncToString):
+        (JSC::numberProtoFuncToLocaleString):
+        (JSC::numberProtoFuncValueOf):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncValueOf):
+        (JSC::objectProtoFuncHasOwnProperty):
+        (JSC::objectProtoFuncIsPrototypeOf):
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+        (JSC::objectProtoFuncPropertyIsEnumerable):
+        (JSC::objectProtoFuncToLocaleString):
+        (JSC::objectProtoFuncToString):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::regExpProtoFuncTest):
+        (JSC::regExpProtoFuncExec):
+        (JSC::regExpProtoFuncCompile):
+        (JSC::regExpProtoFuncToString):
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncReplace):
+        (JSC::stringProtoFuncToString):
+        (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::stringProtoFuncTrim):
+        (JSC::stringProtoFuncTrimLeft):
+        (JSC::stringProtoFuncTrimRight):
+
+2014-03-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Land the stackmap register liveness glue with the uses of the liveness disabled
+        https://bugs.webkit.org/show_bug.cgi?id=130924
+
+        Reviewed by Oliver Hunt.
+        
+        Add the liveness and fix other bugs I found.
+
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::usedRegistersFor):
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * ftl/FTLSlowPathCall.cpp:
+        * ftl/FTLSlowPathCallKey.cpp:
+        (JSC::FTL::SlowPathCallKey::dump):
+        * ftl/FTLSlowPathCallKey.h:
+        (JSC::FTL::SlowPathCallKey::SlowPathCallKey):
+        (JSC::FTL::SlowPathCallKey::argumentRegisters):
+        (JSC::FTL::SlowPathCallKey::withCallTarget):
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::StackMaps::Record::locationSet):
+        (JSC::FTL::StackMaps::Record::liveOutsSet):
+        (JSC::FTL::StackMaps::Record::usedRegisterSet):
+        * ftl/FTLStackMaps.h:
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::registerClobberCheck):
+        (JSC::FTL::slowPathCallThunkGenerator):
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::stackRegisters):
+        (JSC::RegisterSet::reservedHardwareRegisters):
+        (JSC::RegisterSet::runtimeRegisters):
+        (JSC::RegisterSet::specialRegisters):
+        (JSC::RegisterSet::dump):
+        * jit/RegisterSet.h:
+        (JSC::RegisterSet::RegisterSet):
+        (JSC::RegisterSet::setAny):
+        (JSC::RegisterSet::setMany):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryCachePutByID):
+        (JSC::tryRepatchIn):
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+
+2014-03-28  Mark Lam  <mark.lam@apple.com>
+
+        mandreel throws a checksum error on 32-bit x86.
+        <https://webkit.org/b/125706>
+
+        Reviewed by Filip Pizlo.
+
+        The 32-bit DFG can emit code that loads double constants from its
+        CodeBlock's m_constantRegisters vector.  The emitted instruction will
+        embed the address of the constant from the vector's backing store.
+        Subsequently, while inserting new constants, the DFG may resize the
+        vector, thereby reallocating the backing store.  This renders the
+        previously embedded constant addresses stale.
+
+        The fix is to use a dedicated doubles constant pool stored in the DFG
+        CommonData instead.  This constant pool won't be reallocated, and
+        hence will not manifest this issue.
+
+        * dfg/DFGCommonData.h:
+        * dfg/DFGGraph.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::addressOfDoubleConstant): Deleted.
+
+2014-03-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: console.warn is showing as error instead of warning
+        https://bugs.webkit.org/show_bug.cgi?id=130921
+
+        Reviewed by Timothy Hatcher.
+
+        * runtime/ConsolePrototype.cpp:
+        (JSC::consoleProtoFuncWarn):
+        console.warn should be MessageLevel Warning, not Error.
+
+2014-03-28  Oliver Hunt  <oliver@apple.com>
+
+        Fix cloop build.
+
+        * bytecode/BytecodeList.json:
+
+2014-03-28  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewed, rolling r166248 back in.
+
+        Turns out r166070 didn't cause a 2% performance loss in page load times
+
+        Reverted changeset:
+
+        Unreviewed, rolling out r166126.
+        Rollout r166126 in prepartion to roll out prerequisite r166070
+
+2014-03-27  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r166376.
+        https://bugs.webkit.org/show_bug.cgi?id=130887
+
+        This was a misguided optimization. (Requested by kling on
+        #webkit).
+
+        Reverted changeset:
+
+        "Avoid fetching JSObject::structure() repeatedly in
+        putDirectInternal."
+        https://bugs.webkit.org/show_bug.cgi?id=130857
+        http://trac.webkit.org/changeset/166376
+
+2014-03-27  Oliver Hunt  <oliver@apple.com>
+
+        Support spread operand in |new| expressions
+        https://bugs.webkit.org/show_bug.cgi?id=130877
+
+        Reviewed by Michael Saboff.
+
+        Add support for the spread operator being applied in
+        |new| expressions.  This required adding support for
+        a new opcode, op_construct_varargs.  This is a relatively
+        simple refactoring of the call_varargs implementation.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::callTypeFor):
+        (JSC::CallLinkInfo::specializationKind):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCallVarargs):
+        (JSC::BytecodeGenerator::emitConstructVarargs):
+        (JSC::BytecodeGenerator::emitConstruct):
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        (JSC::JIT::emit_op_construct_varargs):
+        (JSC::JIT::emitSlow_op_construct_varargs):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emitSlow_op_construct_varargs):
+        (JSC::JIT::emit_op_construct_varargs):
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseMemberExpression):
+
+2014-03-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Revert http://trac.webkit.org/changeset/166386 because it broke builds.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/LLVMForJSC.xcconfig:
+
+2014-03-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, skip this test for now.
+
+        * tests/stress/recurse-infinitely-on-getter.js:
+
+2014-03-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Switch the LLVMForJSC target to using the LLVM in /usr/local rather than /usr/local/LLVMForJavaScriptCore on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=130867
+        <rdar://problem/16432456> 
+
+        Reviewed by Mark Hahnenberg.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/LLVMForJSC.xcconfig:
+
+2014-03-27  Andreas Kling  <akling@apple.com>
+
+        Avoid fetching JSObject::structure() repeatedly in putDirectInternal.
+        <https://webkit.org/b/130857>
+
+        Use the cached Structure* instead of re-fetching it over and over since
+        that's a non-trivial operation these days.
+
+        Reviewed by Mark Hahnenberg.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::putDirectInternal):
+
+2014-03-27  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Check the remembered set bit faster
+        https://bugs.webkit.org/show_bug.cgi?id=130860
+
+        Reviewed by Oliver Hunt.
+
+        Currently we look up the remembered set bit in the MarkedBlock in C++ code, but 
+        that bit is also stored in the object. We should look it up there whenever possible.
+
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::shouldReportLiveBytes):
+        * heap/Heap.cpp:
+        (JSC::Heap::addToRememberedSet):
+        * heap/Heap.h:
+        * heap/HeapInlines.h: Removed.
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::reportExtraMemoryUsage):
+
+2014-03-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Provide SPI to disallow remote inspection of a JSContext
+        https://bugs.webkit.org/show_bug.cgi?id=130853
+
+        Reviewed by Timothy Hatcher.
+
+        * API/JSContextPrivate.h: Added.
+        * API/JSContext.mm:
+        (-[JSContext _remoteInspectionEnabled]):
+        (-[JSContext _setRemoteInspectionEnabled:]):
+        ObjC SPI to enable/disable remote inspection.
+
+        * API/JSContextRefPrivate.h:
+        * API/JSContextRef.cpp:
+        (JSGlobalContextGetRemoteInspectionEnabled):
+        (JSGlobalContextSetRemoteInspectionEnabled):
+        C SPI to enable/disable remote inspection.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Add new private header, and export as a private header.
+
+2014-03-27  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Clean up questionable style in ScriptExecutable::prepareForExecutionImpl
+        https://bugs.webkit.org/show_bug.cgi?id=130845
+
+        Reviewed by Filip Pizlo.
+
+        There was a hack added to make sure C Loop LLInt worked which included overriding the 
+        global Options::useLLInt setting, which makes no sense to do here. We should put the 
+        update of the global setting in Options::recomputeDependentOptions along with the other 
+        execution engine flags.
+
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::prepareForExecutionImpl):
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+
+2014-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Enable LLVM stackmap liveOuts computation
+        https://bugs.webkit.org/show_bug.cgi?id=130821
+
+        Reviewed by Andy Estes and Sam Weinig.
+
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::StackMaps::Record::dump):
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Parse stackmaps liveOuts
+        https://bugs.webkit.org/show_bug.cgi?id=130801
+
+        Reviewed by Geoffrey Garen.
+        
+        This just adds the code to parse them but doesn't do anything with them, yet.
+
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::forStackmaps):
+        * ftl/FTLLocation.h:
+        (JSC::FTL::Location::forRegister):
+        (JSC::FTL::Location::forIndirect):
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::StackMaps::Location::parse):
+        (JSC::FTL::StackMaps::Location::dump):
+        (JSC::FTL::StackMaps::LiveOut::parse):
+        (JSC::FTL::StackMaps::LiveOut::dump):
+        (JSC::FTL::StackMaps::Record::parse):
+        (JSC::FTL::StackMaps::Record::dump):
+        * ftl/FTLStackMaps.h:
+
+2014-03-26  Mark Lam  <mark.lam@apple.com>
+
+        Build fix after r166307.
+
+        Not reviewed.
+
+        * runtime/JSCell.h:
+        - The inline function isAPIValueWrapper() should not be exported.  This
+          was causing a linkage error when building for 32-bit x86 on Mac.
+
+2014-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Reasoning about DWARF register numbers should be moved out of FTL::Location
+        https://bugs.webkit.org/show_bug.cgi?id=130792
+
+        Reviewed by Oliver Hunt.
+        
+        Moving this code makes it possible for things other than FTL::Location to reason about
+        DWARF register encoding. This refactoring also appears to reduce some code duplication
+        and makes FTLLocation.cpp cleaner.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * ftl/FTLDWARFRegister.cpp: Added.
+        (JSC::FTL::DWARFRegister::reg):
+        (JSC::FTL::DWARFRegister::dump):
+        * ftl/FTLDWARFRegister.h: Added.
+        (JSC::FTL::DWARFRegister::DWARFRegister):
+        (JSC::FTL::DWARFRegister::dwarfRegNum):
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::dump):
+        (JSC::FTL::Location::isGPR):
+        (JSC::FTL::Location::gpr):
+        (JSC::FTL::Location::isFPR):
+        (JSC::FTL::Location::fpr):
+        * ftl/FTLLocation.h:
+        (JSC::FTL::Location::hasDwarfReg):
+        (JSC::FTL::Location::dwarfReg):
+
+2014-03-26  Brent Fulgham  <bfulgham@apple.com>
+
+        Unreviewed build fix.
+
+        * runtime/JSCell.h: VS2013 confused about argument type.
+
+2014-03-26  Zoltan Horvath  <zoltan@webkit.org>
+
+        [CSS Shapes] Remove shape-inside support
+        https://bugs.webkit.org/show_bug.cgi?id=130698
+
+        Reviewed by David Hyatt.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-03-26  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Rename hasFastArrayStorage to be more appropriate
+        https://bugs.webkit.org/show_bug.cgi?id=130773
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNewArray):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArrayBuffer):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
+        * runtime/ButterflyInlines.h:
+        (JSC::Butterfly::unshift):
+        (JSC::Butterfly::shift):
+        * runtime/IndexingHeaderInlines.h:
+        (JSC::IndexingHeader::preCapacity):
+        * runtime/IndexingType.h:
+        (JSC::hasArrayStorage):
+        (JSC::hasAnyArrayStorage):
+        (JSC::hasFastArrayStorage): Deleted.
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::sortVector):
+        (JSC::JSArray::compactForSorting):
+        * runtime/JSArray.h:
+        (JSC::JSArray::create):
+        (JSC::JSArray::tryCreateUninitialized):
+        * runtime/JSGlobalObject.cpp:
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
+        * runtime/JSObject.h:
+        (JSC::JSObject::ensureArrayStorage):
+        (JSC::JSObject::arrayStorage):
+        * runtime/StructureTransitionTable.h:
+        (JSC::newIndexingType):
+
+2014-03-26  Zan Dobersek  <zdobersek@igalia.com>
+
+        Unreviewed. Removing the remaining Automake cruft.
+
+        * GNUmakefile.list.am: Removed.
+
+2014-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Arguments simplification phase should be fine with marking the arguments local itself as an arguments alias
+        https://bugs.webkit.org/show_bug.cgi?id=130764
+        <rdar://problem/16304788>
+
+        Reviewed by Sam Weinig.
+        
+        Being an arguments alias just means that your OSR exit recovery should attempt arguments
+        creation. This is true of arguments locals. We had special cases that tried to make it not
+        true of arguments locals. The only consequence of those special cases was to cause crashes
+        in case of arguments that are also captured variables (i.e. we have SlowArguments). This
+        change just removes those special cases.
+        
+        This change means that the FTL will now see SetLocals with a FlushedArguments format.
+        Previously you wouldn't see them because previously only non-captured variable would be
+        arguments aliases, and non-captured variables get completely SSAified - i.e. no SetLocals
+        left. Adding handling for FlushedArguments is a benign and simple change since its
+        behavior is identical to FlushedJSValue for that code's purposes.
+
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
+        * tests/stress/captured-arguments-variable.js: Added.
+        (foo):
+        (noInline):
+
+2014-03-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Add HeapInlines
+        https://bugs.webkit.org/show_bug.cgi?id=130759
+
+        Reviewed by Filip Pizlo.
+
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/Heap.cpp:
+        (JSC::MarkedBlockSnapshotFunctor::MarkedBlockSnapshotFunctor):
+        (JSC::MarkedBlockSnapshotFunctor::operator()):
+        * heap/Heap.h: Also reindented while we're here.
+        (JSC::Heap::writeBarrierBuffer):
+        (JSC::Heap::vm):
+        (JSC::Heap::objectSpace):
+        (JSC::Heap::machineThreads):
+        (JSC::Heap::operationInProgress):
+        (JSC::Heap::allocatorForObjectWithoutDestructor):
+        (JSC::Heap::allocatorForObjectWithNormalDestructor):
+        (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor):
+        (JSC::Heap::storageAllocator):
+        (JSC::Heap::notifyIsSafeToCollect):
+        (JSC::Heap::isSafeToCollect):
+        (JSC::Heap::handleSet):
+        (JSC::Heap::handleStack):
+        (JSC::Heap::lastFullGCLength):
+        (JSC::Heap::lastEdenGCLength):
+        (JSC::Heap::increaseLastFullGCLength):
+        (JSC::Heap::sizeBeforeLastEdenCollection):
+        (JSC::Heap::sizeAfterLastEdenCollection):
+        (JSC::Heap::sizeBeforeLastFullCollection):
+        (JSC::Heap::sizeAfterLastFullCollection):
+        (JSC::Heap::jitStubRoutines):
+        (JSC::Heap::isDeferred):
+        (JSC::Heap::structureIDTable):
+        (JSC::Heap::removeCodeBlock):
+        * heap/HeapInlines.h: Added.
+        (JSC::Heap::shouldCollect):
+        (JSC::Heap::isBusy):
+        (JSC::Heap::isCollecting):
+        (JSC::Heap::heap):
+        (JSC::Heap::isLive):
+        (JSC::Heap::isInRememberedSet):
+        (JSC::Heap::isMarked):
+        (JSC::Heap::testAndSetMarked):
+        (JSC::Heap::setMarked):
+        (JSC::Heap::isWriteBarrierEnabled):
+        (JSC::Heap::writeBarrier):
+        (JSC::Heap::reportExtraMemoryCost):
+        (JSC::Heap::forEachProtectedCell):
+        (JSC::Heap::forEachCodeBlock):
+        (JSC::Heap::allocateWithNormalDestructor):
+        (JSC::Heap::allocateWithImmortalStructureDestructor):
+        (JSC::Heap::allocateWithoutDestructor):
+        (JSC::Heap::tryAllocateStorage):
+        (JSC::Heap::tryReallocateStorage):
+        (JSC::Heap::ascribeOwner):
+        (JSC::Heap::blockAllocator):
+        (JSC::Heap::releaseSoon):
+        (JSC::Heap::incrementDeferralDepth):
+        (JSC::Heap::decrementDeferralDepth):
+        (JSC::Heap::collectIfNecessaryOrDefer):
+        (JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
+        (JSC::Heap::markListSet):
+        * runtime/JSCInlines.h:
+
+2014-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::ByteCodeParser::SetMode should distinguish between setting immediately without a flush and setting immediately with a flush
+        https://bugs.webkit.org/show_bug.cgi?id=130760
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::setArgument):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * tests/stress/assign-argument-in-inlined-call.js: Added.
+        (f1):
+        (getF2Arguments):
+        (f2):
+        (f3):
+        * tests/stress/assign-captured-argument-in-inlined-call.js: Added.
+        (f1):
+        (f2):
+        (f3):
+
+2014-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix 32-bit getter call alignment.
+
+        Reviewed by Mark Hahnenberg.
+
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub):
+
+2014-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Repatch should plant calls to getters directly rather than through a C helper
+        https://bugs.webkit.org/show_bug.cgi?id=129589
+
+        Reviewed by Mark Hahnenberg.
+        
+        As the title says. All of the superstructure for this was already in place, so now it
+        was just a matter of actually emitting the call.
+        
+        8x speed-up for getter microbenchmarks. 
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/PolymorphicGetByIdList.h:
+        (JSC::GetByIdAccess::doesCalls):
+        * jit/AccessorCallJITStubRoutine.cpp: Added.
+        (JSC::AccessorCallJITStubRoutine::AccessorCallJITStubRoutine):
+        (JSC::AccessorCallJITStubRoutine::~AccessorCallJITStubRoutine):
+        (JSC::AccessorCallJITStubRoutine::visitWeak):
+        * jit/AccessorCallJITStubRoutine.h: Added.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeCell):
+        * jit/GCAwareJITStubRoutine.h:
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub):
+        * runtime/GetterSetter.h:
+        (JSC::GetterSetter::offsetOfGetter):
+        (JSC::GetterSetter::offsetOfSetter):
+
+2014-03-25  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewed, rolling out r166126.
+
+        Rollout r166126 in prepartion to roll out prerequisite r166070
+
+        Reverted changeset:
+
+        "toThis() on a JSWorkerGlobalScope should return a JSProxy and
+        not undefined"
+        https://bugs.webkit.org/show_bug.cgi?id=130554
+        http://trac.webkit.org/changeset/166126
+
+2014-03-25  Oliver Hunt  <oliver@apple.com>
+
+        AST incorrectly conflates readable and writable locations
+        https://bugs.webkit.org/show_bug.cgi?id=130734
+
+        Reviewed by Filip Pizlo.
+
+        We need to distinguish between "locations" that are valid for reading
+        and writing, vs those that may only be written.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitBytecode):
+        (JSC::ForOfNode::emitBytecode):
+        * parser/Nodes.h:
+        (JSC::ExpressionNode::isAssignmentLocation):
+
+2014-03-24  Oliver Hunt  <oliver@apple.com>
+
+        ASSERTION FAILED in Parser: dst != localReg
+        https://bugs.webkit.org/show_bug.cgi?id=130710
+
+        Reviewed by Filip Pizlo.
+
+        Just make sure we don't try to write to a captured constant,
+        following the change to track captured variables separately.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PrefixNode::emitResolve):
+
+2014-03-25  Martin Robinson  <mrobinson@igalia.com>
+
+        [GTK] Remove the autotools build
+        https://bugs.webkit.org/show_bug.cgi?id=130717
+
+        Reviewed by Anders Carlsson.
+
+        * GNUmakefile.am: Removed.
+        * config.h: Remove references to the autotools configure file.
+
+2014-03-24  Filip Pizlo  <fpizlo@apple.com>
+
+        More scaffolding for a stub routine to have a stub recursively embedded inside it
+        https://bugs.webkit.org/show_bug.cgi?id=130770
+
+        Reviewed by Oliver Hunt.
+
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink): VM& argument is superfluous.
+        (JSC::CallLinkInfo::visitWeak): Factor this out, it used to be in CodeBlock::finalizeUnconditionally().
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finalizeUnconditionally): Factor out some functionality into CallLinkInfo::visitWeak(), and make sure we pass RepatchBuffer& in more places.
+        (JSC::CodeBlock::unlinkCalls):
+        (JSC::CodeBlock::unlinkIncomingCalls):
+        * bytecode/PolymorphicGetByIdList.cpp: Pass RepatchBuffer& through and call JITStubRoutine::visitWeak().
+        (JSC::GetByIdAccess::visitWeak):
+        (JSC::PolymorphicGetByIdList::visitWeak):
+        * bytecode/PolymorphicGetByIdList.h:
+        * bytecode/PolymorphicPutByIdList.cpp: Pass RepatchBuffer& through and call JITStubRoutine::visitWeak().
+        (JSC::PutByIdAccess::visitWeak):
+        (JSC::PolymorphicPutByIdList::visitWeak):
+        * bytecode/PolymorphicPutByIdList.h:
+        * bytecode/StructureStubInfo.cpp: Pass RepatchBuffer& through.
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * bytecode/StructureStubInfo.h:
+        * jit/ClosureCallStubRoutine.cpp: isClosureCall is unused.
+        (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
+        * jit/GCAwareJITStubRoutine.cpp:
+        (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
+        (JSC::createJITStubRoutine):
+        * jit/GCAwareJITStubRoutine.h: Make it easier to construct one of these.
+        (JSC::GCAwareJITStubRoutine::isClosureCall): Deleted.
+        * jit/JITStubRoutine.cpp:
+        (JSC::JITStubRoutine::visitWeak): This will allow future JITStubRoutine subclasses to have stubs recursively embedded inside them.
+        * jit/JITStubRoutine.h:
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub): Fix a possible GC bug where we weren't making the stub routine GC aware.
+        (JSC::emitCustomSetterStub): Clean up some code.
+
+2014-03-24  Geoffrey Garen  <ggaren@apple.com>
+
+        Safari crashes in JavaScriptCore: JSC::JSObject::growOutOfLineStorage
+        when WebKit is compiled with fcatch-undefined-behavior
+        https://bugs.webkit.org/show_bug.cgi?id=130652
+
+        Reviewed by Mark Hahnenberg.
+
+        Use a static member function because the butterfly we pass in might be
+        NULL, and passing NULL to a member function is undefined behavior.
+
+        Stylistically, I think this new way reads a little more clearly, since it
+        matches createOrGrowArrayRight, and it helps to convey that m_butterfly
+        might not exist yet.
+
+        * runtime/Butterfly.h:
+        * runtime/ButterflyInlines.h:
+        (JSC::Butterfly::createOrGrowPropertyStorage): Renamed from growPropertyStorage
+        because we might create. Split out the create path to avoid using NULL
+        in a member function expression.
+
+        Removed some unused versions of this function.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::growOutOfLineStorage): Updated for interface change.
+
+2014-03-24  Oliver Hunt  <oliver@apple.com>
+
+        Strict mode destructuring assignment crashes the parser.
+        https://bugs.webkit.org/show_bug.cgi?id=130538
+
+        Reviewed by Michael Saboff.
+
+        The SyntaxChecker mode always return 1 for success, except
+        for a small subset of functions where we needed exact information.
+        This ends up just being a poor design decision as it means
+        the parser can get confused between a function return 1, and
+        the Resolve constant which was also 1. So we now use a unique
+        type for every creation method.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createSourceElements):
+        (JSC::SyntaxChecker::createFunctionBody):
+        (JSC::SyntaxChecker::createArguments):
+        (JSC::SyntaxChecker::createSpreadExpression):
+        (JSC::SyntaxChecker::createArgumentsList):
+        (JSC::SyntaxChecker::createPropertyList):
+        (JSC::SyntaxChecker::createElementList):
+        (JSC::SyntaxChecker::createFormalParameterList):
+        (JSC::SyntaxChecker::createClause):
+        (JSC::SyntaxChecker::createClauseList):
+        (JSC::SyntaxChecker::createFuncDeclStatement):
+        (JSC::SyntaxChecker::createBlockStatement):
+        (JSC::SyntaxChecker::createExprStatement):
+        (JSC::SyntaxChecker::createIfStatement):
+        (JSC::SyntaxChecker::createForLoop):
+        (JSC::SyntaxChecker::createForInLoop):
+        (JSC::SyntaxChecker::createForOfLoop):
+        (JSC::SyntaxChecker::createEmptyStatement):
+        (JSC::SyntaxChecker::createVarStatement):
+        (JSC::SyntaxChecker::createReturnStatement):
+        (JSC::SyntaxChecker::createBreakStatement):
+        (JSC::SyntaxChecker::createContinueStatement):
+        (JSC::SyntaxChecker::createTryStatement):
+        (JSC::SyntaxChecker::createSwitchStatement):
+        (JSC::SyntaxChecker::createWhileStatement):
+        (JSC::SyntaxChecker::createWithStatement):
+        (JSC::SyntaxChecker::createDoWhileStatement):
+        (JSC::SyntaxChecker::createLabelStatement):
+        (JSC::SyntaxChecker::createThrowStatement):
+        (JSC::SyntaxChecker::createDebugger):
+        (JSC::SyntaxChecker::createConstStatement):
+        (JSC::SyntaxChecker::appendConstDecl):
+        (JSC::SyntaxChecker::combineCommaNodes):
+        (JSC::SyntaxChecker::operatorStackPop):
+
+2014-03-24  Brent Fulgham  <bfulgham@apple.com>
+
+        Activate WebVTT Tests Once Merging is Complete
+        https://bugs.webkit.org/show_bug.cgi?id=130420
+
+        Reviewed by Eric Carlson.
+
+        * Configurations/FeatureDefines.xcconfig: Turn on ENABLE(WEBVTT_REGIONS)
+
+2014-03-24  Andreas Kling  <akling@apple.com>
+
+        Stop pulling in all the macro assemblers from VM.h
+        <https://webkit.org/b/130691>
+
+        Remove #include of "GPRInfo.h". This breaks WebCore's dependency
+        on macro assemblers headers and removes 8 includes from every
+        .cpp file in the JS bindings.
+
+        Reviewed by Geoff Garen.
+
+        * runtime/VM.h:
+
+2014-03-24  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for thread QoS
+        https://bugs.webkit.org/show_bug.cgi?id=130688
+
+        Reviewed by Andreas Kling.
+
+        * heap/BlockAllocator.cpp:
+        (JSC::BlockAllocator::blockFreeingThreadStartFunc):
+            - block freeing is a utility activity.
+
+2014-03-24  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix CLOOP build.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printCallOp):
+        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
+        (JSC::CodeBlock::resetStubDuringGCInternal): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::callLinkInfosEnd): Deleted.
+
+2014-03-24  Gabor Rapcsanyi  <rgabor@webkit.org>
+
+        [ARM64] GNU assembler doesn't work with LLInt arm64 backend.
+        https://bugs.webkit.org/show_bug.cgi?id=130453
+        
+        Reviewed by Filip Pizlo.
+
+        Change fp and lr to x29 and x30. Add both operand kinds to emitARM64()
+        at sxtw and uxtw instructions.
+
+        * offlineasm/arm64.rb:
+
+2014-03-23  Hyowon Kim  <hw1008.kim@samsung.com>
+
+        Move all EFL typedefs into EflTypedefs.h.
+        https://bugs.webkit.org/show_bug.cgi?id=130511
+
+        Reviewed by Gyuyoung Kim
+
+        * heap/HeapTimer.h: Remove EFL typedefs.
+
+2014-03-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Gotta grow the locals vectors if we are about to do SetLocals beyond the bytecode's numCalleeRegisters
+        https://bugs.webkit.org/show_bug.cgi?id=130650
+        <rdar://problem/16122966>
+
+        Reviewed by Michael Saboff.
+        
+        Previously, it was only in the case of inlining that we would do SetLocal's beyond the
+        previously established numLocals limit. But then we added generalized op_call_varargs
+        handling, which results in us emitting SetLocals that didn't previously exist in the
+        bytecode.
+        
+        This factors out the inliner's ensureLocals loop and calls it from op_call_varargs.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::ensureLocals):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::parse):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub): Make this do alignment correctly.
+        * runtime/Options.h:
+        * tests/stress/call-varargs-from-inlined-code.js: Added.
+        * tests/stress/call-varargs-from-inlined-code-with-odd-number-of-arguments.js: Added.
+
+2014-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, adjust sizes for ARM64.
+
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCall):
+
+2014-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Protect the silent spiller/filler's desire to fill Int32Constants by making sure that we don't mark something as having a Int32 register format if it's a non-Int32 constant
+        https://bugs.webkit.org/show_bug.cgi?id=130649
+        <rdar://problem/16399949>
+
+        Reviewed by Andreas Kling.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        * tests/stress/fuzz-bug-16399949.js: Added.
+        (tryItOut.f):
+        (tryItOut):
+
+2014-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Call linking slow paths should be passed a CallLinkInfo* directly so that you can create a call IC without adding it to any CodeBlocks
+        https://bugs.webkit.org/show_bug.cgi?id=130644
+
+        Reviewed by Andreas Kling.
+        
+        This is conceptually a really simple change but it involves the following:
+        
+        - The inline part of the call IC stuffs a pointer to the CallLinkInfo into regT2.
+        
+        - CodeBlock uses a Bag of CallLinkInfos instead of a Vector.
+        
+        - Remove the significance of a CallLinkInfo's index. This means that DFG::JITCode no
+          longer has a vector of slow path counts that shadows the CallLinkInfo vector.
+        
+        - Make CallLinkInfo have its own slowPathCount, which counts actual slow path executions
+          and not all relinking.
+        
+        This makes planting JS->JS calls inside other inline caches or stubs a lot easier, since
+        the CallLinkInfo and the call IC slow paths no longer rely on the call being associated
+        with a op_call/op_construct instruction and a machine code return PC within such an
+        instruction.
+
+        * bytecode/CallLinkInfo.h:
+        (JSC::getCallLinkInfoCodeOrigin):
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        * bytecode/CallLinkStatus.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printCallOp):
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::getCallLinkInfoMap):
+        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
+        (JSC::CodeBlock::addCallLinkInfo):
+        (JSC::CodeBlock::unlinkCalls):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::stubInfoBegin):
+        (JSC::CodeBlock::stubInfoEnd):
+        (JSC::CodeBlock::callLinkInfosBegin):
+        (JSC::CodeBlock::callLinkInfosEnd):
+        (JSC::CodeBlock::byValInfo):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGJITCode.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::addJSCall):
+        (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCall):
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::JSCall):
+        (JSC::FTL::JSCall::emit):
+        (JSC::FTL::JSCall::link):
+        * ftl/FTLJSCall.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::compileOpCallSlowCase):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationLinkFor):
+        (JSC::operationVirtualFor):
+        (JSC::operationLinkClosureCallFor):
+        * jit/Repatch.cpp:
+        (JSC::linkClosureCall):
+        * jit/ThunkGenerators.cpp:
+        (JSC::slowPathFor):
+        (JSC::virtualForThunkGenerator):
+        * tests/stress/eval-that-is-not-eval.js: Added.
+
+2014-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix mispelled test name.
+
+        * tests/stress/constand-folding-osr-exit.js: Removed.
+        * tests/stress/constant-folding-osr-exit.js: Copied from Source/JavaScriptCore/tests/stress/constand-folding-osr-exit.js.
+
+2014-03-22  Andreas Kling  <akling@apple.com>
+
+        CREATE_DOM_WRAPPER doesn't need the ExecState.
+        <https://webkit.org/b/130648>
+
+        Add a fast path from JSGlobalObject to the VM so we don't have
+        to dance via the Heap.
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::vm):
+
+2014-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix FTL build.
+
+        * ftl/FTLJITFinalizer.cpp:
+
+2014-03-22  Michael Saboff  <msaboff@apple.com>
+
+        toThis() on a JSWorkerGlobalScope should return a JSProxy and not undefined
+        https://bugs.webkit.org/show_bug.cgi?id=130554
+
+        Reviewed by Geoffrey Garen.
+
+        Fixed toThis() on WorkerGlobalScope to return a JSProxy instead of the JSGlobalObject.
+        Did some cleanup as well.  Moved the setting of the thisObject in a JSGlobalObject to
+        happen in finishCreation() so that it will also happen for other derived classes including
+        JSWorkerGlobalScopeBase.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreateInGroup):
+        * jsc.cpp:
+        (GlobalObject::create):
+        * API/tests/testapi.c:
+        (globalObject_initialize): Eliminated ASSERT that the global object we are creating matches
+        the result from JSContextGetGlobalObject() as that will return the proxy.       
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Removed thisValue parameter and the call to setGlobalThis() since
+        we now call setGlobalThis in finishCreation().
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::finishCreation):
+        (JSC::JSGlobalObject::setGlobalThis): Made this a private method.
+
+2014-03-22  Andreas Kling  <akling@apple.com>
+
+        Fix debug build.
+
+        * bytecode/CodeBlock.cpp:
+        * runtime/Executable.cpp:
+
+2014-03-22  Andreas Kling  <akling@apple.com>
+
+        Cut down on JSC profiler includes in WebCore & co.
+        <https://webkit.org/b/130637>
+
+        Most of WebKit was pulling in JSC's profiler headers via VM.h.
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGDisassembler.cpp:
+        * dfg/DFGDisassembler.h:
+        * dfg/DFGJITFinalizer.cpp:
+        * jsc.cpp:
+        * runtime/VM.cpp:
+        * runtime/VM.h:
+
+2014-03-22  Landry Breuil <landry@openbsd.org>
+
+        Use pthread_stackseg_np() to find the stack bounds on OpenBSD.
+        https://bugs.webkit.org/show_bug.cgi?id=129965
+
+        Reviewed By Anders Carlsson.
+
+2014-03-21  Mark Lam  <mark.lam@apple.com>
+
+        Crash when BytecodeGenerator::emitJump calls Label::bind on null pointer.
+        <https://webkit.org/b/124508>
+
+        Reviewed by Oliver Hunt.
+
+        The issue is that BreakNode::emitBytecode() is holding onto a LabelScope
+        pointer from the BytecodeGenerator's m_localScopes vector, and then it
+        calls emitPopScopes().  emitPopScopes() may do finally clause handling
+        which will require the m_localScopes to be cloned so that it can change
+        the local scopes for the finally block, and then restore it after
+        handling the finally clause.  These modifications of the m_localScopes
+        vector will result in the LabelScope pointer in BreakNode::emitBytecode()
+        becoming stale, thereby causing the crash.
+
+        The same issue applies to the ContinueNode as well.
+
+        The fix is to use the existing LabelScopePtr abstraction instead of raw
+        LabelScope pointers.  The LabelScopePtr is resilient to the underlying
+        vector re-allocating its backing store.
+
+        I also changed the LabelScopePtr constructor that takes a LabelScopeStore
+        to expect a reference to the owner store instead of a pointer because the
+        owner store should never be a null pointer.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::newLabelScope):
+        (JSC::BytecodeGenerator::breakTarget):
+        (JSC::BytecodeGenerator::continueTarget):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/LabelScope.h:
+        (JSC::LabelScopePtr::LabelScopePtr):
+        (JSC::LabelScopePtr::operator bool):
+        (JSC::LabelScopePtr::null):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ContinueNode::trivialTarget):
+        (JSC::ContinueNode::emitBytecode):
+        (JSC::BreakNode::trivialTarget):
+        (JSC::BreakNode::emitBytecode):
+
+2014-03-21  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        6% SunSpider commandline regression due to r165940
+        https://bugs.webkit.org/show_bug.cgi?id=130617
+
+        Reviewed by Michael Saboff.
+
+        In GCActivityCallback::didAllocate, lastGCLength() returns 0 if we've never collected 
+        before. Some of the benchmarks are never running a single EdenCollection, which causes 
+        them to repeatedly call scheduleTimer with a newDelay of 0. This defeats our timer 
+        slop heuristic, causing us to invoke CFRunLoopTimerSetNextFireDate a couple orders of 
+        magnitude more than we normally would.
+
+        The fix is to seed the last GC lengths in Heap with a non-zero length so that our heuristic works.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+
+2014-03-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Constants folded by DFG::ByteCodeParser should not be dead.
+        https://bugs.webkit.org/show_bug.cgi?id=130576
+
+        Reviewed by Mark Hahnenberg.
+        
+        This fixes bugs in the ByteCodeParser's constant folder by removing that constant folder. This
+        reduces the number of folders in JSC from fourish to just threeish (parser, DFG AI, and one
+        or more folders in LLVM). Doing so has no performance impact since the other constant folders
+        already subsume this one.
+        
+        Also added a test case for the specific bug that instigated this.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getJSConstantForValue):
+        (JSC::DFG::ByteCodeParser::getJSConstant):
+        (JSC::DFG::ByteCodeParser::inferredConstant):
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGNode.h:
+        * dfg/DFGNodeFlags.h:
+        * tests/stress/constand-folding-osr-exit.js: Added.
+        (foo):
+        (test):
+        (.var):
+
+2014-03-21  Mark Lam  <mark.lam@apple.com>
+
+        StackLayoutPhase should find the union'ed calleeVariable before accessing its machineLocal.
+        <https://webkit.org/b/130566>
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+
+2014-03-20  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should correctly compile GetByVal on Uint32Array that claims to return non-int32 values
+        https://bugs.webkit.org/show_bug.cgi?id=130562
+        <rdar://problem/16382842>
+
+        Reviewed by Geoffrey Garen.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        * tests/stress/uint32array-unsigned-load.js: Added.
+        (foo):
+
+2014-03-20  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: add frontend controller and models for replay sessions
+        https://bugs.webkit.org/show_bug.cgi?id=130145
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/scripts/CodeGeneratorInspector.py: Add the conditional Replay domain.
+
+2014-03-20  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL ValueToInt32 mishandles the constant case, and by the way, there is a constant case that the FTL sees
+        https://bugs.webkit.org/show_bug.cgi?id=130546
+        <rdar://problem/16383308>
+
+        Reviewed by Mark Hahnenberg.
+        
+        Make AI do a better job of folding this.
+        
+        Also made the FTL backend be more tolerant of data representations. In this case it
+        didn't know that "constant" was a valid representation. There is a finite set of
+        possible representations, but broadly, we don't write code that presumes anything
+        about the representation of an input; that's what methods like lowJSValue() are for.
+        ValueToInt32 was previously not relying on those methods at all because it had some
+        hacks. Now, those hacks are just a fast-path optimization but ultimately we fall down
+        to lowJSValue().
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
+        * tests/stress/value-to-int32-undefined-constant.js: Added.
+        (foo):
+        * tests/stress/value-to-int32-undefined.js: Added.
+        (foo):
+
+2014-03-20  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Add some assertions back
+        https://bugs.webkit.org/show_bug.cgi?id=130531
+
+        Reviewed by Geoffrey Garen.
+
+        We removed a useful set of assertions for verifying that MarkedBlocks were 
+        in the state that we expected them to be in after clearing marks in the Heap. 
+        We should add these back to catch bugs earlier.
+
+        * heap/MarkedBlock.h:
+        * heap/MarkedSpace.cpp:
+        (JSC::VerifyMarkedOrRetired::operator()):
+        (JSC::MarkedSpace::clearMarks):
+
+2014-03-20  Filip Pizlo  <fpizlo@apple.com>
+
+        Implement stackmap header version check and support new stackmap formats
+        https://bugs.webkit.org/show_bug.cgi?id=130535
+        <rdar://problem/16164284>
+
+        Reviewed by Geoffrey Garen.
+        
+        Add the notion of versioning so that LLVMers can happily implement new stackmap formats
+        without worrying about WebKit getting version-locked to LLVM. In the future, we will have
+        to implement parsing for a new LLVM stackmap format before it lands in LLVM, or we'll have
+        to have a "max usable LLVM revision" limit. But, thanks to versioning, we'll always be
+        happy to move backward in time to older versions of LLVM.
+
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::readObject):
+        (JSC::FTL::StackMaps::Constant::parse):
+        (JSC::FTL::StackMaps::StackSize::parse):
+        (JSC::FTL::StackMaps::Location::parse):
+        (JSC::FTL::StackMaps::Record::parse):
+        (JSC::FTL::StackMaps::parse):
+        (JSC::FTL::StackMaps::dump):
+        (JSC::FTL::StackMaps::dumpMultiline):
+        * ftl/FTLStackMaps.h:
+
+2014-03-20  Filip Pizlo  <fpizlo@apple.com>
+
+        Crash beneath operationTearOffActivation running this JS compression demo
+        https://bugs.webkit.org/show_bug.cgi?id=130295
+        <rdar://problem/16332337>
+
+        Reviewed by Oliver Hunt.
+        
+        Make sure that we flush things as if we were at a terminal, if we are at a block with
+        no forward edges. This fixes infinitely loopy code with captured variables.
+
+        Make sure that the CFG simplifier adds explicit flushes whenever it jettisons a block.
+        
+        Make it so that NodeIsFlushed is a thing. Previously only SSA used it and it computed
+        it by itself. Now it's an artifact of CPS rethreading.
+        
+        Add a bunch of tests. All of them previously either crashed or returned bad output due
+        to memory corruption.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::isCaptured):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::flushForTerminal):
+        (JSC::DFG::ByteCodeParser::flushForReturn):
+        (JSC::DFG::ByteCodeParser::flushIfTerminal):
+        (JSC::DFG::ByteCodeParser::branchData):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::run):
+        (JSC::DFG::CPSRethreadingPhase::computeIsFlushed):
+        (JSC::DFG::CPSRethreadingPhase::addFlushedLocalOp):
+        (JSC::DFG::CPSRethreadingPhase::addFlushedLocalEdge):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::clearFlagsOnAllNodes):
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.h:
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * tests/stress/activation-test-loop.js: Added.
+        (Inner.this.doStuff):
+        (Inner):
+        (foo.inner.isDone):
+        (foo):
+        * tests/stress/inferred-infinite-loop-that-uses-captured-variables.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+        * tests/stress/infinite-loop-that-uses-captured-variables-before-throwing.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+        * tests/stress/infinite-loop-that-uses-captured-variables-but-they-do-not-escape.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+        * tests/stress/infinite-loop-that-uses-captured-variables-with-osr-entry.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+        * tests/stress/infinite-loop-that-uses-captured-variables.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+        * tests/stress/tricky-indirectly-inferred-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
+        (bar):
+        (fuzz):
+        (foo.f):
+        (foo):
+        * tests/stress/tricky-inferred-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
+        (bar):
+        (foo.f):
+        (foo):
+        * tests/stress/tricky-infinite-loop-that-uses-captured-variables-and-creates-the-activation-outside-the-loop.js: Added.
+        (bar):
+        (foo.f):
+        (foo):
+        * tests/stress/tricky-infinite-loop-that-uses-captured-variables.js: Added.
+        (bar):
+        (foo):
+        (noInline):
+
+2014-03-20  Oliver Hunt  <oliver@apple.com>
+
+        Incorrect behavior when mutating a typed array during set.
+        https://bugs.webkit.org/show_bug.cgi?id=130428
+
+        Reviewed by Geoffrey Garen.
+
+        This fixes a null derefence that occurs if a typed array
+        is mutated during the set() operation. The patch gets rid
+        of the "Quickly" version of setIndex that is assigning
+        JSValues of unknown type, as the numeric conversion can trigger
+        side effects that lead to neutering, and so we deref null.
+
+        * runtime/JSGenericTypedArrayView.h:
+        (JSC::JSGenericTypedArrayView::setIndex):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::set):
+        (JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):
+
+2014-03-20  Gavin Barraclough  <barraclough@apple.com>
+
+        Remove IdentifierTable typedef, isIdentifier()
+        https://bugs.webkit.org/show_bug.cgi?id=130533
+
+        Rubber stamped by Geoff Garen.
+
+        Code should use AtomicStringTable, isAtomic() directly.
+
+        * API/JSClassRef.cpp:
+        (OpaqueJSClass::~OpaqueJSClass):
+        (OpaqueJSClassContextData::OpaqueJSClassContextData):
+        (OpaqueJSClass::className):
+        * API/JSClassRef.h:
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationFromCell):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        (JSC::DFG::SpeculativeJIT::speculateStringIdentAndLoadStorage):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::speculateStringIdent):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::atomicStringTable):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::addVar):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::createBindingPattern):
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        (JSC::evaluate):
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::checkCurrentAtomicStringTable):
+        * runtime/Identifier.h:
+        (JSC::Identifier::Identifier):
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::add):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::dumpInContext):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::didAcquireLock):
+        (JSC::JSLock::willReleaseLock):
+        (JSC::JSLock::DropAllLocks::DropAllLocks):
+        (JSC::JSLock::DropAllLocks::~DropAllLocks):
+        * runtime/JSLock.h:
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::get):
+        (JSC::PropertyTable::findWithString):
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::~VM):
+        * runtime/VM.h:
+        (JSC::VM::atomicStringTable):
+
+2014-03-20  Gavin Barraclough  <barraclough@apple.com>
+
+        Merge AtomicString, Identifier
+        https://bugs.webkit.org/show_bug.cgi?id=128624
+
+        Reviewed by Geoff Garen.
+
+        WTF::StringImpl currently supports two uniquing mechanism - AtomicString and
+        Identifer - that is one too many.
+
+        Remove Identifier in favour of AtomicString. Identifier had two interesting
+        mechanisms that we preserve.
+
+        (1) JSC API VMs each get their own string table, switch the string table on
+            API entry/exit.
+        (2) JSC caches a pointer to the string table on the VM to avoid a thread
+            specific access. Adds a new AtomicString::add method to support this.
+
+        * API/JSAPIWrapperObject.mm:
+            - updated includes.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+            - added IdentifierInlines.h.
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+            - updated includes.
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::atomicStringTable):
+            - added, used via AtomicString::add to avoid thread-specific access.
+        * runtime/ConsolePrototype.cpp:
+            - updated includes.
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::add):
+        (JSC::Identifier::add8):
+            - vm->smallStrings.singleCharacterStringRep now returns Atomic strings, use AtomicString::add.
+        * runtime/Identifier.h:
+        (JSC::Identifier::Identifier):
+            - added ASSERTS.
+        (JSC::Identifier::add):
+            - vm->smallStrings.singleCharacterStringRep now returns Atomic strings, use AtomicString::add.
+        * runtime/IdentifierInlines.h: Added.
+        (JSC::Identifier::add):
+            - moved from Identifier.h, use AtomicString::add.
+        * runtime/JSCInlines.h:
+            - added IdentifierInlines.h.
+        * runtime/JSLock.h:
+            - removed IdentifierTable.
+        * runtime/PropertyNameArray.cpp:
+            - updated includes.
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStringsStorage::SmallStringsStorage):
+            - ensure all single character strings are Atomic.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+            - instantiate CommonIdentifiers with the correct AtomicStringTable set on thread data.
+        * runtime/VM.h:
+        (JSC::VM::atomicStringTable):
+            - added, used via AtomicString::add to avoid thread-specific access.
+
+2014-03-20  Gabor Rapcsanyi  <rgabor@webkit.org>
+
+        [ARM64] Fix assembler build issues and add cacheFlush support for Linux
+        https://bugs.webkit.org/show_bug.cgi?id=130502
+
+        Reviewed by Michael Saboff.
+
+        Add limits.h for INT_MIN in ARM64Assembler(). Delete shouldBlindForSpecificArch(uintptr_t)
+        because on ARM64 uint64_t and uintptr_t is the same with GCC and Clang as well.
+        Add cacheFlush support for Linux.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::linuxPageFlush):
+        (JSC::ARM64Assembler::cacheFlush):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::shouldBlindForSpecificArch):
+
+2014-03-19  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=130494
+        EmptyUnique strings are Identifiers/Atomic
+
+        Reviewed by Geoff Garen.
+
+        EmptyUnique strings should set the Identifier/Atomic flag.
+
+        This fixes an unreproducible bug we believe exists in Identifier handling.
+        Expected behaviour is that while Identifiers may reference EmptyUniques
+        (StringImpls allocated as UIDs for PrivateNames), these are not created
+        through the main Identifier constructor, the Identifier flag is not set
+        on PrivateNames, and we should never lookup EmptyUnique strings in the
+        IdentifierTable.
+
+        Unfortunately that was happening. Some tables used to implement property
+        access in the JIT hold StringImpl*s, and turn these back into Identifiers
+        using the identfiier constructor. Since the code generator will now plant
+        by-id (cachable) accesses to PrivateNames we can end up passing an
+        EmptyUnique to Identifier::add, potentially leading to PrivateNames being
+        uniqued together (though hard to prove, since the hash codes are random).
+
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (JSC::PropertyName::uid):
+        (JSC::PropertyName::publicName):
+        (JSC::PropertyName::asIndex):
+            - PropertyName assumed that PrivateNames are not Identifiers - instead check isEmptyUnique().
+        * runtime/Structure.cpp:
+        (JSC::Structure::getPropertyNamesFromStructure):
+            - Structure assumed that PrivateNames are not Identifiers - instead check isEmptyUnique().
+
+2014-03-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, revert the DFGCommon.h change in r165938. It was not intentional.
+
+        * dfg/DFGCommon.h:
+
+2014-03-19  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        GC timer should intelligently choose between EdenCollections and FullCollections
+        https://bugs.webkit.org/show_bug.cgi?id=128261
+
+        Reviewed by Geoffrey Garen.
+
+        Most of the GCs while browsing the web are due to the GC timer. Currently the GC timer 
+        always does FullCollections. To reduce the impact of the GC timer on the system this patch
+        changes Heap so that it has two timers, one for each type of collection. The FullCollection
+        timer is notified at the end of EdenCollections how much the Heap has grown since the last 
+        FullCollection and when somebody notifies the Heap of abandoned memory (which usually wouldn't 
+        be detected by an EdenCollection).
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/EdenGCActivityCallback.cpp: Added.
+        (JSC::EdenGCActivityCallback::EdenGCActivityCallback):
+        (JSC::EdenGCActivityCallback::doCollection):
+        (JSC::EdenGCActivityCallback::lastGCLength):
+        (JSC::EdenGCActivityCallback::deathRate):
+        (JSC::EdenGCActivityCallback::gcTimeSlice):
+        * heap/EdenGCActivityCallback.h: Added.
+        (JSC::GCActivityCallback::createEdenTimer):
+        * heap/FullGCActivityCallback.cpp: Added.
+        (JSC::FullGCActivityCallback::FullGCActivityCallback):
+        (JSC::FullGCActivityCallback::doCollection):
+        (JSC::FullGCActivityCallback::lastGCLength):
+        (JSC::FullGCActivityCallback::deathRate):
+        (JSC::FullGCActivityCallback::gcTimeSlice):
+        * heap/FullGCActivityCallback.h: Added.
+        (JSC::GCActivityCallback::createFullTimer):
+        * heap/GCActivityCallback.cpp:
+        (JSC::GCActivityCallback::GCActivityCallback):
+        (JSC::GCActivityCallback::doWork):
+        (JSC::GCActivityCallback::scheduleTimer):
+        (JSC::GCActivityCallback::cancelTimer):
+        (JSC::GCActivityCallback::didAllocate):
+        (JSC::GCActivityCallback::willCollect):
+        (JSC::GCActivityCallback::cancel):
+        * heap/GCActivityCallback.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::reportAbandonedObjectGraph):
+        (JSC::Heap::didAbandon):
+        (JSC::Heap::collectAllGarbage):
+        (JSC::Heap::collect):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::updateAllocationLimits):
+        (JSC::Heap::didFinishCollection):
+        (JSC::Heap::setFullActivityCallback):
+        (JSC::Heap::setEdenActivityCallback):
+        (JSC::Heap::fullActivityCallback):
+        (JSC::Heap::edenActivityCallback):
+        (JSC::Heap::setGarbageCollectionTimerEnabled):
+        (JSC::Heap::didAllocate):
+        (JSC::Heap::shouldDoFullCollection):
+        * heap/Heap.h:
+        (JSC::Heap::lastFullGCLength):
+        (JSC::Heap::lastEdenGCLength):
+        (JSC::Heap::increaseLastFullGCLength):
+        (JSC::Heap::sizeBeforeLastEdenCollection):
+        (JSC::Heap::sizeAfterLastEdenCollection):
+        (JSC::Heap::sizeBeforeLastFullCollection):
+        (JSC::Heap::sizeAfterLastFullCollection):
+        * heap/HeapOperation.h:
+        * heap/HeapStatistics.cpp:
+        (JSC::HeapStatistics::showObjectStatistics):
+        * heap/HeapTimer.cpp:
+        (JSC::HeapTimer::timerDidFire):
+        * jsc.cpp:
+        (functionFullGC):
+        (functionEdenGC):
+        * runtime/Options.h:
+
+2014-03-19  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r165926.
+        https://bugs.webkit.org/show_bug.cgi?id=130488
+
+        broke the iOS build (Requested by estes on #webkit).
+
+        Reverted changeset:
+
+        "GC timer should intelligently choose between EdenCollections
+        and FullCollections"
+        https://bugs.webkit.org/show_bug.cgi?id=128261
+        http://trac.webkit.org/changeset/165926
+
+2014-03-13  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        GC timer should intelligently choose between EdenCollections and FullCollections
+        https://bugs.webkit.org/show_bug.cgi?id=128261
+
+        Reviewed by Geoffrey Garen.
+
+        Most of the GCs while browsing the web are due to the GC timer. Currently the GC timer 
+        always does FullCollections. To reduce the impact of the GC timer on the system this patch
+        changes Heap so that it has two timers, one for each type of collection. The FullCollection
+        timer is notified at the end of EdenCollections how much the Heap has grown since the last 
+        FullCollection and when somebody notifies the Heap of abandoned memory (which wouldn't be 
+        detected by an EdenCollection).
+
+        * heap/GCActivityCallback.cpp:
+        (JSC::GCActivityCallback::GCActivityCallback):
+        (JSC::GCActivityCallback::doWork):
+        (JSC::FullGCActivityCallback::FullGCActivityCallback):
+        (JSC::FullGCActivityCallback::doCollection):
+        (JSC::EdenGCActivityCallback::EdenGCActivityCallback):
+        (JSC::EdenGCActivityCallback::doCollection):
+        (JSC::GCActivityCallback::scheduleTimer):
+        (JSC::GCActivityCallback::cancelTimer):
+        (JSC::GCActivityCallback::didAllocate):
+        (JSC::GCActivityCallback::willCollect):
+        (JSC::GCActivityCallback::cancel):
+        * heap/GCActivityCallback.h:
+        (JSC::GCActivityCallback::GCActivityCallback):
+        (JSC::GCActivityCallback::createFullTimer):
+        (JSC::GCActivityCallback::createEdenTimer):
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::didAbandon):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::updateAllocationLimits):
+        (JSC::Heap::setFullActivityCallback):
+        (JSC::Heap::setEdenActivityCallback):
+        (JSC::Heap::fullActivityCallback):
+        (JSC::Heap::edenActivityCallback):
+        (JSC::Heap::setGarbageCollectionTimerEnabled):
+        (JSC::Heap::didAllocate):
+        * heap/Heap.h:
+        * heap/HeapTimer.cpp:
+        (JSC::HeapTimer::timerDidFire):
+
+2014-03-19  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r165459): It broke 109 jsc stress test on ARM Thumb2 and Mac 32 bit
+        https://bugs.webkit.org/show_bug.cgi?id=130134
+
+        Reviewed by Mark Hahnenberg.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Can't do some optimizations if you don't have a lot of registers.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById): Move stuff around before going into the IC code to ensure that we give the IC code the invariants it needs. This only happens in case of GetByIdFlush, where we are forced into using weird combinations of registers because the results have to be in t0/t1.
+        (JSC::DFG::SpeculativeJIT::compile): For a normal GetById, the register allocator should just do the right thing so nobody has to move anything around.
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITGetByIdGenerator::JITGetByIdGenerator): Assert the things we want.
+        * jit/JITInlineCacheGenerator.h:
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub): Remove a previous incomplete hack to try to work around the DFG's problem.
+
+2014-03-19  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Normalize some of the older JSC options
+        https://bugs.webkit.org/show_bug.cgi?id=128753
+
+        Reviewed by Michael Saboff.
+
+        * runtime/Options.cpp:
+        (JSC::Options::initialize):
+
+2014-03-12  Mark Lam  <mark.lam@apple.com>
+
+        Update type of local vars to match the type of String length.
+        <https://webkit.org/b/130077>
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSStringJoiner.cpp:
+        (JSC::JSStringJoiner::join):
+
+2014-03-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Get rid of Flush in SSA
+        https://bugs.webkit.org/show_bug.cgi?id=130440
+
+        Reviewed by Sam Weinig.
+        
+        This is basically a red patch. We used to use backwards flow for determining what was
+        flushed, until it became clear that this doesn't make sense. Now the Flush nodes don't
+        accomplish anything. Keeping them around in SSA can only make things hard.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::SSAData::SSAData):
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGFlushLivenessAnalysisPhase.cpp: Removed.
+        * dfg/DFGFlushLivenessAnalysisPhase.h: Removed.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2014-03-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix iOS production build.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-03-18  Michael Saboff  <msaboff@apple.com>
+
+        Update RegExp Tracing code
+        https://bugs.webkit.org/show_bug.cgi?id=130381
+
+        Reviewed by Andreas Kling.
+
+        Updated the regular expression tracing code for 8/16 bit JIT as
+        well as match only entry points.  Also added average string length
+        metric.
+
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::RegExp):
+        (JSC::RegExp::match):
+        (JSC::RegExp::printTraceData):
+        * runtime/RegExp.h:
+        * runtime/VM.cpp:
+        (JSC::VM::addRegExpToTrace):
+        (JSC::VM::dumpRegExpTrace):
+        * runtime/VM.h:
+        * yarr/YarrJIT.h:
+        (JSC::Yarr::YarrCodeBlock::get8BitMatchOnlyAddr):
+        (JSC::Yarr::YarrCodeBlock::get16BitMatchOnlyAddr):
+        (JSC::Yarr::YarrCodeBlock::get8BitMatchAddr):
+        (JSC::Yarr::YarrCodeBlock::get16BitMatchAddr):
+
+2014-03-17  Filip Pizlo  <fpizlo@apple.com>
+
+        Add CompareStrictEq(StringIdent:, NotStringVar:) and CompareStrictEq(String:, Untyped:)
+        https://bugs.webkit.org/show_bug.cgi?id=130300
+
+        Reviewed by Mark Hahnenberg.
+        
+        We can quickly strictly compare StringIdent's to NotStringVar's and String's to Untyped's.
+        This makes the DFG aware of this.
+        
+        Also adds StringIdent-to-StringIdent and StringIdent-to-NotStringVar strict comparisons to
+        the FTL. Also adds StringIdent-to-StringIdent non-strict comparisons to the FTL.
+        
+        This also gives the DFG some abstractions for checking something is a cell or is other.
+        This made this patch easier to write and also simplified a bunch of other stuff.
+        
+        1% speed-up on Octane.
+
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::JumpList::JumpList):
+        * bytecode/SpeculatedType.h:
+        (JSC::isNotStringVarSpeculation):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::childFor):
+        (JSC::DFG::Node::shouldSpeculateNotStringVar):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::compileBooleanCompare):
+        (JSC::DFG::SpeculativeJIT::compileStringEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringIdentEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringZeroLength):
+        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+        (JSC::DFG::SpeculativeJIT::speculateString):
+        (JSC::DFG::SpeculativeJIT::speculateStringIdentAndLoadStorage):
+        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
+        (JSC::DFG::SpeculativeJIT::speculateNotCell):
+        (JSC::DFG::SpeculativeJIT::speculateOther):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::blessedBooleanResult):
+        (JSC::DFG::SpeculativeJIT::unblessedBooleanResult):
+        (JSC::DFG::SpeculativeJIT::booleanResult):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::branchIsCell):
+        (JSC::DFG::branchNotCell):
+        (JSC::DFG::SpeculativeJIT::branchIsOther):
+        (JSC::DFG::SpeculativeJIT::branchNotOther):
+        (JSC::DFG::SpeculativeJIT::moveTrueTo):
+        (JSC::DFG::SpeculativeJIT::moveFalseTo):
+        (JSC::DFG::SpeculativeJIT::blessBoolean):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        (JSC::DFG::SpeculativeJIT::branchIsCell):
+        (JSC::DFG::SpeculativeJIT::branchNotCell):
+        (JSC::DFG::SpeculativeJIT::branchIsOther):
+        (JSC::DFG::SpeculativeJIT::branchNotOther):
+        (JSC::DFG::SpeculativeJIT::moveTrueTo):
+        (JSC::DFG::SpeculativeJIT::moveFalseTo):
+        (JSC::DFG::SpeculativeJIT::blessBoolean):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::lowString):
+        (JSC::FTL::LowerDFGToLLVM::lowStringIdent):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateString):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringIdent):
+        (JSC::FTL::LowerDFGToLLVM::speculateNotStringVar):
+        * runtime/JSCJSValue.h:
+        * tests/stress/string-ident-to-not-string-var-equality.js: Added.
+        (foo):
+        (bar):
+        (test):
+
+2014-03-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Add Copyright to framework.sb
+        https://bugs.webkit.org/show_bug.cgi?id=130413
+
+        Reviewed by Timothy Hatcher.
+
+        Other sb files got the copyright. Follow suit.
+
+        * framework.sb:
+
+2014-03-18  Matthew Mirman  <mmirman@apple.com>
+
+        Removed extra parens from if statement in a preprocessor define.
+        https://bugs.webkit.org/show_bug.cgi?id=130408
+
+        Reviewed by Filip Pizlo.
+
+        * parser/Parser.cpp:
+
+2014-03-18  Filip Pizlo  <fpizlo@apple.com>
+
+        More FTL enabling.
+
+        Rubber stamped by Dan Bernstein and Mark Hahnenberg.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+
+2014-03-17  Michael Saboff  <msaboff@apple.com>
+
+        V8 regexp spends most of its time in operationGetById
+        https://bugs.webkit.org/show_bug.cgi?id=130380
+
+        Reviewed by Filip Pizlo.
+
+        Added String.length case to tryCacheGetByID that will only help the BaseLine JIT.
+        When V8 regexp is run from the command line, this nets a 2% performance improvement.
+        When the test is run for a longer amount of time, there is much less benefit as the
+        DFG will emit the appropriate code for String.length.  This does remove
+        operationGetById as the hottest function whne run from the command line.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+
+2014-03-17  Andreas Kling  <akling@apple.com>
+
+        Add one-deep cache to opaque roots hashset.
+        <https://webkit.org/b/130357>
+
+        The vast majority of WebCore JS wrappers will have their Document*
+        as the root(). This change adds a simple optimization where we cache
+        the last lookup and avoid going to the hashset for repeated queries.
+
+        Looks like 0.4% progression on DYEB on my MBP.
+
+        Reviewed by Mark Hahnenberg.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/OpaqueRootSet.h: Added.
+        (JSC::OpaqueRootSet::OpaqueRootSet):
+        (JSC::OpaqueRootSet::contains):
+        (JSC::OpaqueRootSet::isEmpty):
+        (JSC::OpaqueRootSet::clear):
+        (JSC::OpaqueRootSet::add):
+        (JSC::OpaqueRootSet::size):
+        (JSC::OpaqueRootSet::begin):
+        (JSC::OpaqueRootSet::end):
+        * heap/SlotVisitor.h:
+
+2014-03-17  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Implement Math.hypot
+        https://bugs.webkit.org/show_bug.cgi?id=129486
+
+        Reviewed by Darin Adler.
+
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+        (JSC::mathProtoFuncHypot):
+
+2014-03-17  Zsolt Borbely  <borbezs@inf.u-szeged.hu>
+
+        Fix the !ENABLE(PROMISES) build
+        https://bugs.webkit.org/show_bug.cgi?id=130328
+
+        Reviewed by Darin Adler.
+
+        Add missing ENABLE(PROMISES) guards.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSPromiseDeferred.cpp:
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPromiseReaction.cpp:
+        * runtime/JSPromiseReaction.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2014-03-16  Andreas Kling  <akling@apple.com>
+
+        REGRESSION(r165703): JSC tests crashing in StringImpl::destroy().
+        <https://webkit.org/b/130304>
+
+        Reviewed by Anders Carlsson.
+
+        Unreviewed, restoring the old behavior of OpaqueJSString::identifier()
+        that doesn't put a potentially unwanted string into the Identifier table.
+
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::identifier):
+
+2014-03-16  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: generated backend commands should reflect build system ENABLE settings
+        https://bugs.webkit.org/show_bug.cgi?id=130111
+
+        Reviewed by Timothy Hatcher.
+
+        * CMakeLists.txt:
+
+        Combine only the Inspector domains listed in INSPECTOR_DOMAINS,
+        instead of globbing any .json file.
+
+        * DerivedSources.make:
+
+        Force the combined inspector protocol file to be regenerated if
+        the content or list of domains itself changes.
+
+2014-03-16  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: vended backend commands file should be generated as part of the build
+        https://bugs.webkit.org/show_bug.cgi?id=130110
+
+        Reviewed by Timothy Hatcher.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Copy InspectorJSBackendCommands.js to the
+        private headers directory.
+
+2014-03-16  Darin Adler  <darin@apple.com>
+
+        Remove all uses of deprecatedCharacters from JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=130304
+
+        Reviewed by Anders Carlsson.
+
+        * API/JSValueRef.cpp:
+        (JSValueMakeFromJSONString): Use characters16 in the 16-bit code path.
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::~OpaqueJSString): Use characters 16 in the 16-bit code path.
+        (OpaqueJSString::identifier): Get rid of custom Identifier constructor, and
+        juse use the standard one that takes a String.
+        (OpaqueJSString::characters): Use getCharactersWithUpconvert instead of a
+        hand-written alternative.
+
+        * bindings/ScriptValue.cpp:
+        (Deprecated::jsToInspectorValue): Create InspectorString from String directly
+        instead of involving a character pointer. Use the String from Identifier
+        directly instead of making a new String.
+
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::createSearchRegexSource): Use StringBuilder
+        instead of building a String a character at a time. This is still a very slow
+        way to do this. Also use strchr to search for a character instead of building
+        a String every time just to use find on it.
+
+        * inspector/InspectorValues.cpp:
+        (Inspector::doubleQuoteString): Remove unnecessary trip through a
+        character pointer. This is still a really slow way to do this.
+        (Inspector::InspectorValue::parseJSON): Use StringView::upconvertedCharacters
+        instead of String::deprecatedCharacters. Still slow to always upconvert.
+
+        * runtime/DateConstructor.cpp: Removed unneeded include.
+        * runtime/DatePrototype.cpp: Ditto.
+
+        * runtime/Identifier.h: Removed deprecatedCharacters function.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::encode): Added a type cast to avoid ambiguity with the two character-
+        appending functions from JSStringBuilder. Removed unneeded code duplicating
+        what JSStringBuilder already does in its character append function.
+        (JSC::decode): Deleted code that creates a JSStringBuilder that is never used.
+        (JSC::parseIntOverflow): Changed lengths to unsigned. Made only the overload that
+        is used outside this file have external linkage. Added a new overload that takes
+        a StringView.
+        (JSC::parseInt): Use StringView::substring to call parseIntOverflow.
+        (JSC::globalFuncEscape): Use JSBuilder::append in a more efficient way for a
+        single character.
+
+        * runtime/JSGlobalObjectFunctions.h: Removed unused overloads of parseIntOverflow.
+
+        * runtime/JSStringBuilder.h: Marked this "lightly deprecated".
+        (JSC::JSStringBuilder::append): Overloaded for better speed with 8-bit characters.
+        Made one overload private. Fixed a performance bug where we would reserve capacity
+        in the 8-bit buffer but then append to the 16-bit buffer.
+
+        * runtime/ObjectPrototype.cpp: Removed unneeded include.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncFontsize): Use StringView::getCharactersWithUpconvert.
+        (JSC::stringProtoFuncLink): Ditto.
+
+2014-03-15  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL ArrayifyToStructure shouldn't fail every time that it actually arrayifies
+        https://bugs.webkit.org/show_bug.cgi?id=130296
+
+        Reviewed by Andreas Kling.
+        
+        During the 32-bit structure ID work, the second load of the structure was removed.
+        That's wrong. The whole point of loading the structure ID again is that the structure
+        ID would have been changed by the arrayification call, and we're verifying that the
+        arrayification succeeded in changing the structure. If we check the old structure - as
+        the code was doing after the 32-bit structure ID work - then this check is guaranteed
+        to fail, causing a significant performance regression.
+        
+        It's actually amazing that the regression wasn't bigger. The reason is that if FTL
+        code pathologically exits but the equivalent DFG code doesn't, then the exponential
+        backoff almost perfectly guarantees that we just end up in the DFG. For this code, at
+        the time at least, the DFG wasn't much slower so this didn't cause too much pain.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+
+2014-03-15  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should support CheckHasInstance/InstanceOf
+        https://bugs.webkit.org/show_bug.cgi?id=130285
+
+        Reviewed by Sam Weinig.
+        
+        Fairly straightforward; I also discovered an inaccurate FIXME in the process.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckHasInstance):
+        (JSC::FTL::LowerDFGToLLVM::compileInstanceOf):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::phi):
+        * tests/stress/instanceof.js: Added.
+        * tests/stress/instanceof-not-cell.js: Added.
+
+2014-03-15  Michael Saboff  <msaboff@apple.com>
+
+        It should be possible to adjust DFG and FTL compiler thread priorities
+        https://bugs.webkit.org/show_bug.cgi?id=130288
+
+        Reviewed by Filip Pizlo.
+
+        Added ability to change thread priorities relative to its current priority.
+        Created options to adjust the priority of the DFG and FTL compilation work thread
+        pools.  For two core systems, there might be three runnable threads, the main thread,
+        the DFG compilation thread and the FTL compilation thread.  With the same priority,
+        the scheduler is free to schedule whatever thread it wants.  By lowering the
+        compilation threads, the main thread can run.  Further tests may suggest better values
+        for the new options, priorityDeltaOfDFGCompilerThreads and priorityDeltaOfFTLCompilerThreads.
+
+        For a two-core device, this change has a net positive improvement of 1-3% across
+        SunSpider, Octane, Kraken and AsmBench.
+
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::finishCreation):
+        (JSC::DFG::Worklist::create):
+        (JSC::DFG::ensureGlobalDFGWorklist):
+        (JSC::DFG::ensureGlobalFTLWorklist):
+        * dfg/DFGWorklist.h:
+        * runtime/Options.cpp:
+        (JSC::computePriorityDeltaOfWorkerThreads):
+        * runtime/Options.h:
+
+2014-03-15  David Kilzer  <ddkilzer@apple.com>
+
+        [iOS] Define SYSTEM_VERSION_PREFIX consistently
+        <http://webkit.org/b/130293>
+        <rdar://problem/15926359>
+
+        Reviewed by Dan Bernstein.
+
+        * Configurations/Version.xcconfig:
+        (SYSTEM_VERSION_PREFIX_iphoneos): Sync with
+        Source/WebKit/mac/Version.xcconfig.
+
+2014-03-15  David Kilzer  <ddkilzer@apple.com>
+
+        Fix build: using integer absolute value function 'abs' when argument is of floating point type
+        <http://webkit.org/b/130286>
+
+        Reviewed by Filip Pizlo.
+
+        Fixes the following build failure using trunk clang:
+
+            JavaScriptCore/assembler/MacroAssembler.h:992:17: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
+                    value = abs(value);
+                            ^
+            JavaScriptCore/assembler/MacroAssembler.h:992:17: note: use function 'fabs' instead
+                    value = abs(value);
+                            ^~~
+                            fabs
+
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::shouldBlindDouble): Switch from abs() to
+        fabs().
+
+2014-03-14  Oliver Hunt  <oliver@apple.com>
+
+        Reinstate intialiser syntax in for-in loops
+        https://bugs.webkit.org/show_bug.cgi?id=130269
+
+        Reviewed by Michael Saboff.
+
+        Disallowing the initialiser broke some sites so this patch re-allows
+        the syntax.  We still disallow the syntax in 'of' and pattern based
+        enumeration.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::isBindingNode):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        (JSC::Parser<LexerType>::parseForStatement):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+
+2014-03-14  Mark Lam  <mark.lam@apple.com>
+
+        Accessing __lookupGetter__ and __lookupSetter__ should not crash the VM when undefined.
+        <https://webkit.org/b/130279>
+
+        Reviewed by Filip Pizlo.
+
+        If neither the getter nor setter are defined, accessing __lookupGetter__
+        and __lookupSetter__ will return undefined as expected.  However, if the
+        getter is defined but the setter is not, accessing __lookupSetter__ will
+        crash the VM.  Similarly, accessing __lookupGetter__ when only the setter
+        is defined will crash the VM.
+
+        The reason is because objectProtoFuncLookupGetter() and
+        objectProtoFuncLookupSetter() did not check if the getter and setter
+        value is non-null before returning it as an EncodedJSValue.  The fix is
+        to add the appropriate null checks.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+
+2014-03-14  Mark Rowe  <mrowe@apple.com>
+
+        Fix the production build.
+
+        Don't rely on USE_INTERNAL_SDK being set for the Production configuration since UseInternalSDK.xcconfig won't
+        be at the expected relative path when working from installed source.
+
+        * Configurations/Base.xcconfig:
+
+2014-03-14  Maciej Stachowiak  <mjs@apple.com>
+
+        Replace "Apple Computer, Inc." with "Apple Inc." in copyright headers
+        https://bugs.webkit.org/show_bug.cgi?id=130276
+        <rdar://problem/16266927>
+
+        Reviewed by Simon Fraser.
+
+        * API/APICast.h:
+        * API/JSBase.cpp:
+        * API/JSBase.h:
+        * API/JSBasePrivate.h:
+        * API/JSCallbackConstructor.cpp:
+        * API/JSCallbackConstructor.h:
+        * API/JSCallbackFunction.cpp:
+        * API/JSCallbackFunction.h:
+        * API/JSCallbackObject.cpp:
+        * API/JSCallbackObject.h:
+        * API/JSCallbackObjectFunctions.h:
+        * API/JSClassRef.cpp:
+        * API/JSClassRef.h:
+        * API/JSContextRef.cpp:
+        * API/JSContextRef.h:
+        * API/JSContextRefPrivate.h:
+        * API/JSObjectRef.cpp:
+        * API/JSObjectRef.h:
+        * API/JSProfilerPrivate.cpp:
+        * API/JSProfilerPrivate.h:
+        * API/JSRetainPtr.h:
+        * API/JSStringRef.cpp:
+        * API/JSStringRef.h:
+        * API/JSStringRefBSTR.cpp:
+        * API/JSStringRefBSTR.h:
+        * API/JSStringRefCF.cpp:
+        * API/JSStringRefCF.h:
+        * API/JSValueRef.cpp:
+        * API/JSValueRef.h:
+        * API/JavaScript.h:
+        * API/JavaScriptCore.h:
+        * API/OpaqueJSString.cpp:
+        * API/OpaqueJSString.h:
+        * API/tests/JSNode.c:
+        * API/tests/JSNode.h:
+        * API/tests/JSNodeList.c:
+        * API/tests/JSNodeList.h:
+        * API/tests/Node.c:
+        * API/tests/Node.h:
+        * API/tests/NodeList.c:
+        * API/tests/NodeList.h:
+        * API/tests/minidom.c:
+        * API/tests/minidom.js:
+        * API/tests/testapi.c:
+        * API/tests/testapi.js:
+        * DerivedSources.make:
+        * bindings/ScriptValue.cpp:
+        * bytecode/CodeBlock.cpp:
+        * bytecode/CodeBlock.h:
+        * bytecode/EvalCodeCache.h:
+        * bytecode/Instruction.h:
+        * bytecode/JumpTable.cpp:
+        * bytecode/JumpTable.h:
+        * bytecode/Opcode.cpp:
+        * bytecode/Opcode.h:
+        * bytecode/SamplingTool.cpp:
+        * bytecode/SamplingTool.h:
+        * bytecode/SpeculatedType.cpp:
+        * bytecode/SpeculatedType.h:
+        * bytecode/ValueProfile.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/Label.h:
+        * bytecompiler/LabelScope.h:
+        * bytecompiler/RegisterID.h:
+        * debugger/DebuggerCallFrame.cpp:
+        * debugger/DebuggerCallFrame.h:
+        * dfg/DFGDesiredStructureChains.cpp:
+        * dfg/DFGDesiredStructureChains.h:
+        * heap/GCActivityCallback.cpp:
+        * heap/GCActivityCallback.h:
+        * inspector/ConsoleMessage.cpp:
+        * inspector/ConsoleMessage.h:
+        * inspector/IdentifiersFactory.cpp:
+        * inspector/IdentifiersFactory.h:
+        * inspector/InjectedScriptManager.cpp:
+        * inspector/InjectedScriptManager.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/ScriptBreakpoint.h:
+        * inspector/ScriptDebugListener.h:
+        * inspector/ScriptDebugServer.cpp:
+        * inspector/ScriptDebugServer.h:
+        * inspector/agents/InspectorAgent.cpp:
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * interpreter/Interpreter.cpp:
+        * interpreter/Interpreter.h:
+        * interpreter/JSStack.cpp:
+        * interpreter/JSStack.h:
+        * interpreter/Register.h:
+        * jit/CompactJITCodeMap.h:
+        * jit/JITStubs.cpp:
+        * jit/JITStubs.h:
+        * jit/JITStubsARM.h:
+        * jit/JITStubsARMv7.h:
+        * jit/JITStubsX86.h:
+        * jit/JITStubsX86_64.h:
+        * os-win32/stdbool.h:
+        * parser/SourceCode.h:
+        * parser/SourceProvider.h:
+        * profiler/LegacyProfiler.cpp:
+        * profiler/LegacyProfiler.h:
+        * profiler/ProfileNode.cpp:
+        * profiler/ProfileNode.h:
+        * runtime/ArrayBufferView.cpp:
+        * runtime/ArrayBufferView.h:
+        * runtime/BatchedTransitionOptimizer.h:
+        * runtime/CallData.h:
+        * runtime/ConstructData.h:
+        * runtime/DumpContext.cpp:
+        * runtime/DumpContext.h:
+        * runtime/ExceptionHelpers.cpp:
+        * runtime/ExceptionHelpers.h:
+        * runtime/InitializeThreading.cpp:
+        * runtime/InitializeThreading.h:
+        * runtime/IntegralTypedArrayBase.h:
+        * runtime/IntendedStructureChain.cpp:
+        * runtime/IntendedStructureChain.h:
+        * runtime/JSActivation.cpp:
+        * runtime/JSActivation.h:
+        * runtime/JSExportMacros.h:
+        * runtime/JSGlobalObject.cpp:
+        * runtime/JSNotAnObject.cpp:
+        * runtime/JSNotAnObject.h:
+        * runtime/JSPropertyNameIterator.cpp:
+        * runtime/JSPropertyNameIterator.h:
+        * runtime/JSSegmentedVariableObject.cpp:
+        * runtime/JSSegmentedVariableObject.h:
+        * runtime/JSSymbolTableObject.cpp:
+        * runtime/JSSymbolTableObject.h:
+        * runtime/JSTypeInfo.h:
+        * runtime/JSVariableObject.cpp:
+        * runtime/JSVariableObject.h:
+        * runtime/PropertyTable.cpp:
+        * runtime/PutPropertySlot.h:
+        * runtime/SamplingCounter.cpp:
+        * runtime/SamplingCounter.h:
+        * runtime/Structure.cpp:
+        * runtime/Structure.h:
+        * runtime/StructureChain.cpp:
+        * runtime/StructureChain.h:
+        * runtime/StructureInlines.h:
+        * runtime/StructureTransitionTable.h:
+        * runtime/SymbolTable.cpp:
+        * runtime/SymbolTable.h:
+        * runtime/TypedArrayBase.h:
+        * runtime/TypedArrayType.cpp:
+        * runtime/TypedArrayType.h:
+        * runtime/VM.cpp:
+        * runtime/VM.h:
+        * yarr/RegularExpression.cpp:
+        * yarr/RegularExpression.h:
+
+2014-03-14  Filip Pizlo  <fpizlo@apple.com>
+
+        Final FTL iOS build magic
+        https://bugs.webkit.org/show_bug.cgi?id=130281
+
+        Reviewed by Michael Saboff.
+
+        * Configurations/Base.xcconfig: For now our LLVM headers are in /usr/local/LLVMForJavaScriptCore/include, which is the same as OS X.
+        * Configurations/LLVMForJSC.xcconfig: We need to be more careful about how we specify library paths if we want to get the prioritzation right. Also we need protobuf because things. :-/
+
+2014-03-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Gracefully handle nil name -[JSContext setName:]
+        https://bugs.webkit.org/show_bug.cgi?id=130262
+
+        Reviewed by Mark Hahnenberg.
+
+        * API/JSContext.mm:
+        (-[JSContext setName:]):
+        Gracefully handle nil input.
+
+        * API/tests/testapi.c:
+        (globalContextNameTest):
+        * API/tests/testapi.mm:
+        Test for nil / NULL names in the ObjC and C APIs.
+
+2014-03-11  Oliver Hunt  <oliver@apple.com>
+
+        Improve dom error messages
+        https://bugs.webkit.org/show_bug.cgi?id=130103
+
+        Reviewed by Andreas Kling.
+
+        Add new helper function.
+
+        * runtime/Error.h:
+        (JSC::throwVMTypeError):
+
+2014-03-14  László Langó  <llango.u-szeged@partner.samsung.com>
+
+        Remove unused method declaration.
+        https://bugs.webkit.org/show_bug.cgi?id=130238
+
+        Reviewed by Filip Pizlo.
+
+        The implementation of CallFrame::dumpCaller was removed in
+        http://trac.webkit.org/changeset/153183, but the declaration of it was not.
+
+        * interpreter/CallFrame.h:
+        Remove CallFrame::dumpCaller() method declaration.
+
+2014-03-12  Sergio Villar Senin  <svillar@igalia.com>
+
+        Rename DEFINE_STATIC_LOCAL to DEPRECATED_DEFINE_STATIC_LOCAL
+        https://bugs.webkit.org/show_bug.cgi?id=129612
+
+        Reviewed by Darin Adler.
+
+        For new code use static NeverDestroyed<T> instead.
+
+        * API/JSAPIWrapperObject.mm:
+        (jsAPIWrapperObjectHandleOwner):
+        * API/JSManagedValue.mm:
+        (managedValueHandleOwner):
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::objectGroupForBreakpointAction):
+        * inspector/scripts/CodeGeneratorInspectorStrings.py:
+        * interpreter/JSStack.cpp:
+        (JSC::stackStatisticsMutex):
+        * jit/ExecutableAllocator.cpp:
+        (JSC::DemandExecutableAllocator::allocators):
+
+2014-03-12  Gavin Barraclough  <barraclough@apple.com>
+
+        Reduce memory use for static property maps
+        https://bugs.webkit.org/show_bug.cgi?id=129986
+
+        Reviewed by Andreas Kling.
+
+        Static property tables are currently duplicated on first use from read-only memory into dirty memory
+        in every process, and since the entries are large (48 bytes) and the tables can be unusually sparse
+        (we use a custom hash table without a rehash) a lot of memory may be wasted.
+
+        First, reduce the size of the hashtable. Instead of storing values in the table the hashtable maps
+        from string hashes to indicies into a densely packed array of values. Compute the index table at
+        compile time as a part of the derived sources step, such that this may be read-only data.
+
+        Second, don't copy all data from the HashTableValue array into a HashEntry objects. Instead refer
+        directly to the HashTableValue entries. The only data that needs to be allocated at runtime are the
+        keys, which are Identifiers.
+
+        * create_hash_table:
+            - emit the hash table index into the derived source (we were calculating this already to ensure chaining does not get too deep).
+        * parser/Lexer.cpp:
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        (JSC::Lexer<T>::parseIdentifierSlowCase):
+            - HashEntry -> HashTableValue.
+        * parser/Lexer.h:
+        (JSC::Keywords::getKeyword):
+            - HashEntry -> HashTableValue.
+        * runtime/ClassInfo.h:
+            - removed HashEntry.
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+            - use HashTable::ConstIterator.
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::findPropertyHashEntry):
+            - HashEntry -> HashTableValue.
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+            - changed HashTable::ConstIterator interface.
+        * runtime/JSObject.h:
+            - HashEntry -> HashTableValue.
+        * runtime/Lookup.cpp:
+        (JSC::HashTable::createTable):
+            - table -> keys, keys array is now densely packed.
+        (JSC::HashTable::deleteTable):
+            - table -> keys.
+        (JSC::setUpStaticFunctionSlot):
+            - HashEntry -> HashTableValue.
+        * runtime/Lookup.h:
+        (JSC::HashTableValue::builtinGenerator):
+        (JSC::HashTableValue::function):
+        (JSC::HashTableValue::functionLength):
+        (JSC::HashTableValue::propertyGetter):
+        (JSC::HashTableValue::propertyPutter):
+        (JSC::HashTableValue::lexerValue):
+            - added accessor methods from HashEntry.
+        (JSC::HashTable::copy):
+            - fields changed.
+        (JSC::HashTable::initializeIfNeeded):
+            - table -> keys.
+        (JSC::HashTable::entry):
+            - HashEntry -> HashTableValue.
+        (JSC::HashTable::ConstIterator::ConstIterator):
+            - iterate packed value array, so no need to skipInvalidKeys().
+        (JSC::HashTable::ConstIterator::value):
+        (JSC::HashTable::ConstIterator::key):
+        (JSC::HashTable::ConstIterator::operator->):
+            - accessors now get HashTableValue/StringImpl* separately.
+        (JSC::HashTable::ConstIterator::operator++):
+            - iterate packed value array, so no need to skipInvalidKeys().
+        (JSC::HashTable::end):
+            - end is now size of dense not sparse array.
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticFunctionSlot):
+        (JSC::getStaticValueSlot):
+        (JSC::putEntry):
+        (JSC::lookupPut):
+            - HashEntry -> HashTableValue.
+
+2014-03-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix Mac no-FTL build.
+
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-03-13  Juergen Ributzka  <juergen@apple.com>
+
+        Only export initializeAndGetJSCLLVMAPI from libllvmForJSC.dylib
+        https://bugs.webkit.org/show_bug.cgi?id=130224
+
+        Reviewed by Filip Pizlo.
+
+        This limits the exported symbols to only initializeAndGetJSCLLVMAPI from
+        the LLVM dylib. This allows the dylib to be safely used with other LLVM
+        dylibs on the same system. It also reduces the dynamic linking overhead
+        and also reduces the size by 6MB, because the linker can now dead strip
+        many unused functions.
+
+        * Configurations/LLVMForJSC.xcconfig:
+
+2014-03-13  Andreas Kling  <akling@apple.com>
+
+        VM::discardAllCode() should clear the RegExp cache.
+        <https://webkit.org/b/130144>
+
+        Reviewed by Michael Saboff.
+
+        * runtime/VM.cpp:
+        (JSC::VM::discardAllCode):
+
+2014-03-13  Andreas Kling  <akling@apple.com>
+
+        Revert "Short-circuit JSGlobalObjectInspectorController when not inspecting."
+        <https://webkit.org/b/129995>
+
+        This code path is not taken anymore on DYEB, and I can't explain why
+        it was showing up in my profiles. Backing it out per JoePeck's suggestion.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+
+2014-03-13  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should support IsBlah
+        https://bugs.webkit.org/show_bug.cgi?id=130202
+
+        Reviewed by Geoffrey Garen.
+
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileIsUndefined):
+        (JSC::FTL::LowerDFGToLLVM::compileIsBoolean):
+        (JSC::FTL::LowerDFGToLLVM::compileIsNumber):
+        (JSC::FTL::LowerDFGToLLVM::compileIsString):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
+        (JSC::FTL::LowerDFGToLLVM::compileIsFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileStoreBarrier):
+        (JSC::FTL::LowerDFGToLLVM::compileStoreBarrierWithNullCheck):
+        (JSC::FTL::LowerDFGToLLVM::isNotCellOrMisc):
+        (JSC::FTL::LowerDFGToLLVM::isNumber):
+        (JSC::FTL::LowerDFGToLLVM::isNotNumber):
+        (JSC::FTL::LowerDFGToLLVM::isBoolean):
+        * ftl/FTLOSRExitCompiler.cpp:
+        * tests/stress/is-undefined-exit-on-masquerader.js: Added.
+        (bar):
+        (foo):
+        (test):
+        * tests/stress/is-undefined-jettison-on-masquerader.js: Added.
+        (foo):
+        (test):
+        * tests/stress/is-undefined-masquerader.js: Added.
+        (foo):
+        (test):
+
+2014-03-13  Mark Lam  <mark.lam@apple.com>
+
+        JS benchmarks crash with a bus error on 32-bit x86.
+        <https://webkit.org/b/130203>
+
+        Reviewed by Geoffrey Garen.
+
+        The issue is that generateGetByIdStub() can potentially use the same register
+        for the JSValue base register and the target tag register.  After loading the
+        tag value into the target tag register, the JSValue base address is lost.
+        The code then proceeds to load the payload value using the base register, and
+        this results in a crash.
+
+        The fix is to check if the base register is the same as the target tag register.
+        If so, we should make a copy the base register first before loading the tag
+        value, and use the copy to load the payload value instead.
+
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub):
+
+2014-03-12  Filip Pizlo  <fpizlo@apple.com>
+
+        WebKit shouldn't crash on uniprocessor machines
+        https://bugs.webkit.org/show_bug.cgi?id=130176
+
+        Reviewed by Michael Saboff.
+        
+        Previously the math for computing the number of JIT compiler threads would come up with
+        zero threads on uniprocessor machines, and then the Worklist code would assert.
+
+        * runtime/Options.cpp:
+        (JSC::computeNumberOfWorkerThreads):
+        * runtime/Options.h:
+
+2014-03-13  Radu Stavila  <stavila@adobe.com>
+
+        Webkit not building on XCode 5.1 due to garbage collection no longer being supported
+        https://bugs.webkit.org/show_bug.cgi?id=130087
+
+        Reviewed by Mark Rowe.
+
+        Disable garbage collection on macosx when not using internal SDK.
+
+        * Configurations/Base.xcconfig:
+
+2014-03-10  Darin Adler  <darin@apple.com>
+
+        Avoid copy-prone idiom "for (auto item : collection)"
+        https://bugs.webkit.org/show_bug.cgi?id=129990
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/CodeBlockSet.h:
+        (JSC::CodeBlockSet::iterate): Use auto& to be sure we don't copy by accident.
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionLog): Use auto* to
+        make explicit that we are iterating through pointers.
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionSound): Ditto.
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionProbe): Ditto.
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::removeBreakpoint): Use auto&, and also
+        get rid of an unneeded local variable.
+
+2014-03-13  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: Remove unused callId parameter from evaluateInWebInspector
+        https://bugs.webkit.org/show_bug.cgi?id=129744
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::enable):
+        (Inspector::InspectorAgent::evaluateForTestInFrontend):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/protocol/InspectorDomain.json:
+
+2014-03-11  Filip Pizlo  <fpizlo@apple.com>
+
+        ASSERTION FAILED: node->op() == Phi || node->op() == SetArgument
+        https://bugs.webkit.org/show_bug.cgi?id=130069
+
+        Reviewed by Geoffrey Garen.
+        
+        This was a great assertion, and it represents our strictest interpretation of the rules of
+        our intermediate representation. However, fixing DCE to actually preserve the relevant
+        property would be hard, and it wouldn't have an observable effect right now because nobody
+        actually uses the propery of CPS that this assertion is checking for.
+        
+        In particular, we do always require, and rely on, the fact that non-captured variables
+        have variablesAtTail refer to the last interesting use of the variable: a SetLocal if the
+        block assigns to the variable, a GetLocal if it only reads from it, and a Flush,
+        PhantomLocal, or Phi otherwise. We do preserve this property successfully and DCE was not
+        broken in this regard. But, in the strictest sense, CPS also means that for captured
+        variables, variablesAtTail also continues to point to the last relevant use of the
+        variable. In particular, if there are multiple GetLocals, then it should point to the last
+        one. This is hard for DCE to preserve. Also, nobody relies on variablesAtTail for captured
+        variables, except to check the VariableAccessData; but in that case, we don't really need
+        the *last* relevant use of the variable - any node that mentions the same variable will do
+        just fine.
+        
+        So, this change loosens the assertion and adds a detailed FIXME describing what we would
+        have to do if we wanted to preserve the more strict property.
+        
+        This also makes changes to various debug printing paths so that validation doesn't crash
+        during graph dump. This also adds tests for the interesting cases of DCE failing to
+        preserve CPS in the strictest sense. This also attempts to win the record for longest test
+        name.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::hashAsStringIfPossible):
+        (JSC::CodeBlock::dumpAssumingJITType):
+        * bytecode/CodeBlock.h:
+        * bytecode/CodeOrigin.cpp:
+        (JSC::InlineCallFrame::hashAsStringIfPossible):
+        (JSC::InlineCallFrame::dumpBriefFunctionInformation):
+        * bytecode/CodeOrigin.h:
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::run):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::cleanVariables):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * runtime/FunctionExecutableDump.cpp:
+        (JSC::FunctionExecutableDump::dump):
+        * tests/stress/dead-access-to-captured-variable-preceded-by-a-live-store-in-function-with-multiple-basic-blocks.js: Added.
+        (foo):
+        * tests/stress/dead-access-to-captured-variable-preceded-by-a-live-store.js: Added.
+        (foo):
+
+2014-03-12  Brian Burg  <bburg@apple.com>
+
+        Web Replay: add infrastructure for memoizing nondeterministic DOM APIs
+        https://bugs.webkit.org/show_bug.cgi?id=129445
+
+        Reviewed by Timothy Hatcher.
+
+        There was a bug in the replay inputs code generator that would include
+        headers for definitions of enum classes, even though they can be safely
+        forward-declared.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Generator.generate_includes): Only include for copy constructor if the
+        type is a heavy scalar (i.e., String, URL), not a normal scalar
+        (i.e., int, double, enum classes).
+
+        (Generator.generate_type_forward_declarations): Forward-declare scalars
+        that are enums or enum classes.
+
+2014-03-12  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Disable REMOTE_INSPECTOR in earlier OS X releases
+        https://bugs.webkit.org/show_bug.cgi?id=130118
+
+        Reviewed by Timothy Hatcher.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-03-12  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Hang in Remote Inspection triggering breakpoint from console
+        https://bugs.webkit.org/show_bug.cgi?id=130032
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/EventLoop.h:
+        * inspector/EventLoop.cpp:
+        (Inspector::EventLoop::remoteInspectorRunLoopMode):
+        (Inspector::EventLoop::cycle):
+        Expose the run loop mode name so it can be used if needed by others.
+
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorBlock::RemoteInspectorBlock):
+        (Inspector::RemoteInspectorBlock::~RemoteInspectorBlock):
+        (Inspector::RemoteInspectorBlock::operator=):
+        (Inspector::RemoteInspectorBlock::operator()):
+        (Inspector::RemoteInspectorQueueTask):
+        Instead of a dispatch_queue, have our own static Vector of debugger tasks.
+
+        (Inspector::RemoteInspectorHandleRunSource):
+        (Inspector::RemoteInspectorInitializeQueue):
+        Initialize the static queue and run loop source. When the run loop source
+        fires, it will exhaust the queue of debugger messages.
+
+        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
+        (Inspector::RemoteInspectorDebuggableConnection::~RemoteInspectorDebuggableConnection):
+        When we get a debuggable connection add a run loop source for inspector commands.
+
+        (Inspector::RemoteInspectorDebuggableConnection::dispatchAsyncOnDebuggable):
+        (Inspector::RemoteInspectorDebuggableConnection::sendMessageToBackend):
+        Enqueue blocks on our Vector instead of our dispatch_queue.
+
+2014-03-12  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r165482.
+        https://bugs.webkit.org/show_bug.cgi?id=130157
+
+        Broke the windows build; "error C2466: cannot allocate an
+        array of constant size 0" (Requested by jernoble on #webkit).
+
+        Reverted changeset:
+
+        "Reduce memory use for static property maps"
+        https://bugs.webkit.org/show_bug.cgi?id=129986
+        http://trac.webkit.org/changeset/165482
+
+2014-03-12  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Remove HandleSet::m_nextToFinalize
+        https://bugs.webkit.org/show_bug.cgi?id=130109
+
+        Reviewed by Mark Lam.
+
+        This is a remnant of when HandleSet contained things that needed to be finalized. 
+
+        * heap/HandleSet.cpp:
+        (JSC::HandleSet::HandleSet):
+        (JSC::HandleSet::writeBarrier):
+        * heap/HandleSet.h:
+        (JSC::HandleSet::allocate):
+        (JSC::HandleSet::deallocate):
+
+2014-03-12  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Layout Test fast/workers/worker-gc.html is failing
+        https://bugs.webkit.org/show_bug.cgi?id=130135
+
+        Reviewed by Geoffrey Garen.
+
+        When removing MarkedBlocks, we always expect them to be in the MarkedAllocator's 
+        main list of blocks, i.e. not in the retired list. When shutting down the VM this
+        wasn't always the case which was causing ASSERTs to fire. We should rearrange things 
+        so that allocators are notified with lastChanceToFinalize. This will give them 
+        the chance to move their retired blocks back into the main list before removing them all.
+
+        * heap/MarkedAllocator.cpp:
+        (JSC::LastChanceToFinalize::operator()):
+        (JSC::MarkedAllocator::lastChanceToFinalize):
+        * heap/MarkedAllocator.h:
+        * heap/MarkedSpace.cpp:
+        (JSC::LastChanceToFinalize::operator()):
+        (JSC::MarkedSpace::lastChanceToFinalize):
+
+2014-03-12  Gavin Barraclough  <barraclough@apple.com>
+
+        Reduce memory use for static property maps
+        https://bugs.webkit.org/show_bug.cgi?id=129986
+
+        Reviewed by Andreas Kling.
+
+        Static property tables are currently duplicated on first use from read-only memory into dirty memory
+        in every process, and since the entries are large (48 bytes) and the tables can be unusually sparse
+        (we use a custom hash table without a rehash) a lot of memory may be wasted.
+
+        First, reduce the size of the hashtable. Instead of storing values in the table the hashtable maps
+        from string hashes to indicies into a densely packed array of values. Compute the index table at
+        compile time as a part of the derived sources step, such that this may be read-only data.
+
+        Second, don't copy all data from the HashTableValue array into a HashEntry objects. Instead refer
+        directly to the HashTableValue entries. The only data that needs to be allocated at runtime are the
+        keys, which are Identifiers.
+
+        * create_hash_table:
+            - emit the hash table index into the derived source (we were calculating this already to ensure chaining does not get too deep).
+        * parser/Lexer.cpp:
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        (JSC::Lexer<T>::parseIdentifierSlowCase):
+            - HashEntry -> HashTableValue.
+        * parser/Lexer.h:
+        (JSC::Keywords::getKeyword):
+            - HashEntry -> HashTableValue.
+        * runtime/ClassInfo.h:
+            - removed HashEntry.
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+            - use HashTable::ConstIterator.
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::findPropertyHashEntry):
+            - HashEntry -> HashTableValue.
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+            - changed HashTable::ConstIterator interface.
+        * runtime/JSObject.h:
+            - HashEntry -> HashTableValue.
+        * runtime/Lookup.cpp:
+        (JSC::HashTable::createTable):
+            - table -> keys, keys array is now densely packed.
+        (JSC::HashTable::deleteTable):
+            - table -> keys.
+        (JSC::setUpStaticFunctionSlot):
+            - HashEntry -> HashTableValue.
+        * runtime/Lookup.h:
+        (JSC::HashTableValue::builtinGenerator):
+        (JSC::HashTableValue::function):
+        (JSC::HashTableValue::functionLength):
+        (JSC::HashTableValue::propertyGetter):
+        (JSC::HashTableValue::propertyPutter):
+        (JSC::HashTableValue::lexerValue):
+            - added accessor methods from HashEntry.
+        (JSC::HashTable::copy):
+            - fields changed.
+        (JSC::HashTable::initializeIfNeeded):
+            - table -> keys.
+        (JSC::HashTable::entry):
+            - HashEntry -> HashTableValue.
+        (JSC::HashTable::ConstIterator::ConstIterator):
+            - iterate packed value array, so no need to skipInvalidKeys().
+        (JSC::HashTable::ConstIterator::value):
+        (JSC::HashTable::ConstIterator::key):
+        (JSC::HashTable::ConstIterator::operator->):
+            - accessors now get HashTableValue/StringImpl* separately.
+        (JSC::HashTable::ConstIterator::operator++):
+            - iterate packed value array, so no need to skipInvalidKeys().
+        (JSC::HashTable::end):
+            - end is now size of dense not sparse array.
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticFunctionSlot):
+        (JSC::getStaticValueSlot):
+        (JSC::putEntry):
+        (JSC::lookupPut):
+            - HashEntry -> HashTableValue.
+
+2014-03-11  Filip Pizlo  <fpizlo@apple.com>
+
+        It should be possible to build WebKit with FTL on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=130116
+
+        Reviewed by Dan Bernstein.
+
+        * Configurations/Base.xcconfig:
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        GetById list caching should use something object-oriented rather than PolymorphicAccessStructureList
+        https://bugs.webkit.org/show_bug.cgi?id=129778
+
+        Reviewed by Geoffrey Garen.
+        
+        Also deduplicate the GetById getter call caching. Also add some small tests for
+        get stubs.
+        
+        This change reduces the amount of code involved in GetById access caching and it
+        creates data structures that can serve as an elegant scaffold for introducing other
+        kinds of caches or improving current caching styles. It will definitely make getter
+        performance improvements easier to implement.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PolymorphicGetByIdList.cpp: Added.
+        (JSC::GetByIdAccess::GetByIdAccess):
+        (JSC::GetByIdAccess::~GetByIdAccess):
+        (JSC::GetByIdAccess::fromStructureStubInfo):
+        (JSC::GetByIdAccess::visitWeak):
+        (JSC::PolymorphicGetByIdList::PolymorphicGetByIdList):
+        (JSC::PolymorphicGetByIdList::from):
+        (JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList):
+        (JSC::PolymorphicGetByIdList::currentSlowPathTarget):
+        (JSC::PolymorphicGetByIdList::addAccess):
+        (JSC::PolymorphicGetByIdList::isFull):
+        (JSC::PolymorphicGetByIdList::isAlmostFull):
+        (JSC::PolymorphicGetByIdList::didSelfPatching):
+        (JSC::PolymorphicGetByIdList::visitWeak):
+        * bytecode/PolymorphicGetByIdList.h: Added.
+        (JSC::GetByIdAccess::GetByIdAccess):
+        (JSC::GetByIdAccess::isSet):
+        (JSC::GetByIdAccess::operator!):
+        (JSC::GetByIdAccess::type):
+        (JSC::GetByIdAccess::structure):
+        (JSC::GetByIdAccess::chain):
+        (JSC::GetByIdAccess::chainCount):
+        (JSC::GetByIdAccess::stubRoutine):
+        (JSC::GetByIdAccess::doesCalls):
+        (JSC::PolymorphicGetByIdList::isEmpty):
+        (JSC::PolymorphicGetByIdList::size):
+        (JSC::PolymorphicGetByIdList::at):
+        (JSC::PolymorphicGetByIdList::operator[]):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * bytecode/StructureStubInfo.h:
+        (JSC::isGetByIdAccess):
+        (JSC::StructureStubInfo::initGetByIdList):
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::patchJumpToGetByIdStub):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryBuildPutByIdList):
+        * tests/stress/getter.js: Added.
+        (foo):
+        (.o):
+        * tests/stress/polymorphic-prototype-accesses.js: Added.
+        (Foo):
+        (Bar):
+        (foo):
+        * tests/stress/prototype-getter.js: Added.
+        (Foo):
+        (foo):
+        * tests/stress/simple-prototype-accesses.js: Added.
+        (Foo):
+        (foo):
+
+2014-03-11  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        MarkedBlocks that are "full enough" shouldn't be swept after EdenCollections
+        https://bugs.webkit.org/show_bug.cgi?id=129920
+
+        Reviewed by Geoffrey Garen.
+
+        This patch introduces the notion of "retiring" MarkedBlocks. We retire a MarkedBlock
+        when the amount of free space in a MarkedBlock drops below a certain threshold.
+        Retired blocks are not considered for sweeping.
+
+        This is profitable because it reduces churn during sweeping. To build a free list, 
+        we have to scan through each cell in a block. After a collection, all objects that 
+        are live in the block will remain live until the next FullCollection, at which time
+        we un-retire all previously retired blocks. Thus, a small number of objects in a block
+        that die during each EdenCollection could cause us to do a disproportiante amount of 
+        sweeping for how much free memory we get back.
+
+        This patch looks like a consistent ~2% progression on boyer and is neutral everywhere else.
+
+        * heap/Heap.h:
+        (JSC::Heap::didRetireBlockWithFreeListSize):
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::tryAllocateHelper):
+        (JSC::MarkedAllocator::removeBlock):
+        (JSC::MarkedAllocator::reset):
+        * heap/MarkedAllocator.h:
+        (JSC::MarkedAllocator::MarkedAllocator):
+        (JSC::MarkedAllocator::forEachBlock):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::sweepHelper):
+        (JSC::MarkedBlock::clearMarksWithCollectionType):
+        (JSC::MarkedBlock::didRetireBlock):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::willRemoveBlock):
+        (JSC::MarkedBlock::isLive):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::clearNewlyAllocated):
+        (JSC::MarkedSpace::clearMarks):
+        * runtime/Options.h:
+
+2014-03-11  Andreas Kling  <akling@apple.com>
+
+        Streamline PropertyTable for lookup-only access.
+        <https://webkit.org/b/130060>
+
+        The PropertyTable lookup algorithm was written to support both read
+        and write access. This wasn't actually needed in most places.
+
+        This change adds a PropertyTable::get() that just returns the value
+        type (instead of an insertion iterator.) It also adds an early return
+        for empty tables.
+
+        Finally, up the minimum table capacity from 8 to 16. It was lowered
+        to 8 in order to save memory, but that was before PropertyTables were
+        GC allocated. Nowadays we don't have nearly as many tables, since all
+        the unpinned transitions die off.
+
+        Reviewed by Darin Adler.
+
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::get):
+        * runtime/Structure.cpp:
+        (JSC::Structure::despecifyDictionaryFunction):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::get):
+        (JSC::Structure::despecifyFunction):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get):
+
+2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        REGRESSION(r165407): DoYouEvenBench crashes in DRT
+        https://bugs.webkit.org/show_bug.cgi?id=130066
+
+        Reviewed by Geoffrey Garen.
+
+        The baseline JIT does a conditional store barrier for the put_by_id, but we need 
+        an unconditional store barrier so that we cover the butterfly case as well in emitPutTransitionStub.
+
+        * jit/JIT.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_put_by_id):
+        (JSC::JIT::emitWriteBarrier):
+
+2014-03-10  Mark Lam  <mark.lam@apple.com>
+
+        Resurrect bit-rotted JIT::probe() mechanism.
+        <https://webkit.org/b/130067>
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JITStubs.cpp:
+        - Added the needed #include <wtf/InlineASM.h>.
+
+2014-03-10  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix typo in EXCLUDED_SOURCE_FILE_NAMES_iphoneos.
+
+        Rubber-stamped by Dan Bernstein.
+
+        * Configurations/JavaScriptCore.xcconfig:
+
+2014-03-10  Mark Lam  <mark.lam@apple.com>
+
+        r165414 broke the 32-bit x86 tests: ASSERTION FAILED: result != InvalidIndex @ GPRInfo.h:330.
+        <https://webkit.org/b/130065>
+
+        Reviewed by Michael Saboff.
+
+        There is code in ScratchRegisterAllocator.cpp that is relying on GPRInfo::toIndex()
+        being able to return InvalidIndex.  Hence, the assertion is invalid.  Ditto for
+        FPRInfo::toIndex().
+
+        The fix is to remove the "result != InvalidIndex" assertions.
+
+        * jit/FPRInfo.h:
+        (JSC::FPRInfo::toIndex):
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::toIndex):
+
+2014-03-10  Mark Lam  <mark.lam@apple.com>
+
+        Crash on a stack overflow on 32-bit x86 in http/tests/websocket/tests/hybi/workers/no-onmessage-in-sync-op.html.
+        <https://webkit.org/b/129955>
+
+        Reviewed by Geoffrey Garen.
+
+        The 32-bit x86 version of getHostCallReturnValue() was leaking 16 bytes
+        stack memory every time it was called.  This is now fixed.
+
+        * jit/JITOperations.cpp:
+
+2014-03-10  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Better JSContext API for named evaluations (other than //# sourceURL)
+        https://bugs.webkit.org/show_bug.cgi?id=129911
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSBase.h:
+        * API/JSContext.h:
+        * API/JSContext.mm:
+        (-[JSContext evaluateScript:]):
+        (-[JSContext evaluateScript:withSourceURL:]):
+        Add new evaluateScript:withSourceURL:.
+
+        * API/tests/testapi.c:
+        (main):
+        * API/tests/testapi.mm:
+        (testObjectiveCAPI):
+        Add tests for sourceURL in evaluate APIs. It should
+        affect the exception objects.
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Repatch should save and restore all used registers - not just temp ones - when making a call
+        https://bugs.webkit.org/show_bug.cgi?id=130041
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+        
+        The save/restore code was written back when the only client was the DFG, which only uses a
+        subset of hardware registers: the "temp" registers in our lingo. But the FTL may use many
+        other registers, especially on ARM64. The fact that Repatch doesn't know to save those can
+        lead to data corruption on ARM64. 
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::calleeSaveRegisters):
+        (JSC::RegisterSet::numberOfSetGPRs):
+        (JSC::RegisterSet::numberOfSetFPRs):
+        * jit/RegisterSet.h:
+        * jit/Repatch.cpp:
+        (JSC::storeToWriteBarrierBuffer):
+        (JSC::emitPutTransitionStub):
+        * jit/ScratchRegisterAllocator.cpp:
+        (JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
+        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
+        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
+        (JSC::ScratchRegisterAllocator::usedRegistersForCall):
+        (JSC::ScratchRegisterAllocator::desiredScratchBufferSizeForCall):
+        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall):
+        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall):
+        * jit/ScratchRegisterAllocator.h:
+
+2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Remove ConditionalStore barrier
+        https://bugs.webkit.org/show_bug.cgi?id=130040
+
+        Reviewed by Geoffrey Garen.
+
+        ConditionalStoreBarrier was created when barriers were much more expensive. Now that 
+        they're cheap(er), we can get rid of them. This also allows us to get rid of the write 
+        barrier logic in emitPutTransitionStub because we always will have executed a write barrier 
+        on the base object in the case where we are allocating and storing a new Butterfly into it. 
+        Previously, a ConditionalStoreBarrier might or might not have barrier-ed the base object, 
+        so we'd have to emit a write barrier in the transition case.
+
+        This is performance neutral on the benchmarks we track.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertStoreBarrier):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isStoreBarrier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStoreBarrier):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStub):
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG and FTL should know that comparing anything to Misc is cheap and easy
+        https://bugs.webkit.org/show_bug.cgi?id=130001
+
+        Reviewed by Geoffrey Garen.
+        
+        - Expand CompareStrictEq(Misc:, Misc:) to work for cases where either side of the
+          comparison is just Untyped:.
+        
+        - This obviates the need for CompareStrictEqConstant, so remove it.
+        
+        - FTL had a thing called "Nully" which is really "Other". Rename it and add
+          OtherUse.
+        
+        9% speed-up on box2d.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isBinaryUseKind):
+        (JSC::DFG::Node::shouldSpeculateOther):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+        (JSC::DFG::SpeculativeJIT::compare):
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isNotOther):
+        (JSC::FTL::LowerDFGToLLVM::isOther):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
+        (JSC::FTL::LowerDFGToLLVM::speculateOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
+        * tests/stress/compare-strict-eq-integer-to-misc.js: Added.
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, remove unintended change.
+
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        jsc commandline shouldn't have a "console" because that confuses some tests into thinking
+        that they're running in the browser.
+
+        Rubber stamped by Mark Hahnenberg.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+
+2014-03-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Out-line ScratchRegisterAllocator
+
+        Rubber stamped by Mark Hahnenberg.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * jit/ScratchRegisterAllocator.cpp: Added.
+        (JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
+        (JSC::ScratchRegisterAllocator::~ScratchRegisterAllocator):
+        (JSC::ScratchRegisterAllocator::lock):
+        (JSC::ScratchRegisterAllocator::allocateScratch):
+        (JSC::ScratchRegisterAllocator::allocateScratchGPR):
+        (JSC::ScratchRegisterAllocator::allocateScratchFPR):
+        (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
+        (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
+        (JSC::ScratchRegisterAllocator::desiredScratchBufferSize):
+        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
+        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
+        * jit/ScratchRegisterAllocator.h:
+
+2014-03-10  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Pass environment to Pre-Build, Pre-link, and Post-Build Stages.
+        https://bugs.webkit.org/show_bug.cgi?id=130023
+
+        Reviewed by Dean Jackson.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.proj: Avoid trailing backslashes in
+        path names to avoid accidental escaping of later string substitutions.
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for testb_i8r when register is accumulator.
+        <https://webkit.org/b/130026>
+
+        Generate the shorthand version of "test al, imm" when possible.
+
+        Reviewed by Michael Saboff.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::testb_i8r):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for sub_ir when register is accumulator.
+        <https://webkit.org/b/130025>
+
+        Generate the shorthand version of "sub eax, imm" when possible.
+
+        Reviewed by Michael Saboff.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::subl_ir):
+        (JSC::X86Assembler::subq_ir):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for add_ir when register is accumulator.
+        <https://webkit.org/b/130024>
+
+        Generate the shorthand version of "add eax, imm" when possible.
+
+        Reviewed by Michael Saboff.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::addl_ir):
+        (JSC::X86Assembler::addq_ir):
+
+2014-03-10  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        writeBarrier in emitPutReplaceStub is unnecessary
+        https://bugs.webkit.org/show_bug.cgi?id=130030
+
+        Reviewed by Filip Pizlo.
+
+        We already emit write barriers for each put-by-id when they're first compiled, so it's 
+        redundant to emit a write barrier as part of the repatched code.
+
+        * jit/Repatch.cpp:
+        (JSC::emitPutReplaceStub):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for xor_ir when register is accumulator.
+        <https://webkit.org/b/130008>
+
+        Generate the shorthand version of "xor eax, imm" when possible.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::xorl_ir):
+        (JSC::X86Assembler::xorq_ir):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for or_ir when register is accumulator.
+        <https://webkit.org/b/130007>
+
+        Generate the shorthand version of "or eax, imm" when possible.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::orl_ir):
+        (JSC::X86Assembler::orq_ir):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for test_ir when register is accumulator.
+        <https://webkit.org/b/130006>
+
+        Generate the shorthand version of "test eax, imm" when possible.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::testl_i32r):
+        (JSC::X86Assembler::testq_i32r):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for cmp_ir when register is accumulator.
+        <https://webkit.org/b/130005>
+
+        Generate the shorthand version of "cmp eax, imm" when possible.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::cmpl_ir):
+        (JSC::X86Assembler::cmpq_ir):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for store64(imm, address) when imm fits in 32 bits.
+        <https://webkit.org/b/130002>
+
+        Generate this:
+
+            mov [address], imm32
+
+        Instead of this:
+
+            mov scratchRegister, imm32
+            mov [address], scratchRegister
+
+        For store64(imm, address) where the 64-bit immediate can be passed as
+        a sign-extended 32-bit value.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/MacroAssemblerX86_64.h:
+        (CAN_SIGN_EXTEND_32_64):
+        (JSC::MacroAssemblerX86_64::store64):
+
+2014-03-10  Andreas Kling  <akling@apple.com>
+
+        [X86_64] Smaller code for xchg_rr when one register is accumulator.
+        <https://webkit.org/b/130004>
+
+        Generate the 1-byte version of "xchg eax, reg" when possible.
+
+        Reviewed by Benjamin Poulain.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::xchgl_rr):
+        (JSC::X86Assembler::xchgq_rr):
+
+2014-03-09  Filip Pizlo  <fpizlo@apple.com>
+
+        GPRInfo::toIndex should return InvalidIndex for non-temp registers on ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=129998
+
+        Reviewed by Geoffrey Garen.
+        
+        Not only is that the established contract, but this is used to signal to
+        ScratchRegisterAllocator that the register doesn't need locking since it isn't a register
+        that this allocator would use. In the FTL, we may have an inline cache where LLVM had used
+        some non-temp register (i.e. a register that JSC itself wouldn't have used). This is totally
+        fine but previously it would have led to either an assertion failure, or data corruption, in
+        the ScratchRegisterAllocator.
+
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::toIndex):
+
+2014-03-09  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL fails the new equals-masquerader strictEqualConstant test
+        https://bugs.webkit.org/show_bug.cgi?id=129996
+
+        Reviewed by Mark Lam.
+        
+        It turns out that the FTL was trying to do the masquerading stuff for ===null. But
+        that's wrong since none of the other engines do it. The DFG even had an ancient
+        FIXME about doing it - but that doesn't make sense since the LLInt and baseline JIT
+        don't do it and JSValue::strictEqual() doesn't do it.
+        
+        Remove the FIXME and remove the extra checks in the FTL.
+        
+        This is a glorious patch: nothing but red and it fixes a test failure.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
+
+2014-03-09  Andreas Kling  <akling@apple.com>
+
+        Short-circuit JSGlobalObjectInspectorController when not inspecting.
+        <https://webkit.org/b/129995>
+
+        Add an early return in reportAPIException() when the console agent
+        is disabled. This avoids expensive symbolication during exceptions
+        if there's nobody expecting the fancy backtrace anyway.
+
+        ~2% progression on DYEB on my MBP.
+
+        Reviewed by Geoff Garen.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+
+2014-03-09  Andreas Kling  <akling@apple.com>
+
+        Inline the trivial parts of GC deferral.
+        <https://webkit.org/b/129984>
+
+        Made most of the functions called by the DeferGC RAII object inline
+        to avoid function call overhead.
+
+        Looks like ~1% progression on DYEB.
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/Heap.cpp:
+        * heap/Heap.h:
+        (JSC::Heap::incrementDeferralDepth):
+        (JSC::Heap::decrementDeferralDepth):
+        (JSC::Heap::collectIfNecessaryOrDefer):
+        (JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
+
+2014-03-08  Mark Lam  <mark.lam@apple.com>
+
+        32-bit x86 handleUncaughtException returns to wrong location after a stack overflow.
+        <https://webkit.org/b/129969>
+
+        Reviewed by Geoffrey Garen.
+
+        The 32-bit version of handleUncaughtException was missing the handling of an
+        edge case for stack overflows where the current frame may already be the
+        sentinel frame.  This edge case was handled in the 64-bit version.  The fix
+        is to bring the 32-bit version up to parity.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * llint/LowLevelInterpreter32_64.asm:
+
+2014-03-07  Mark Lam  <mark.lam@apple.com>
+
+        Fix bugs in 32-bit Structure implementation.
+        <https://webkit.org/b/129947>
+
+        Reviewed by Mark Hahnenberg.
+
+        Added the loading of the Structure (from the JSCell) before use that was
+        missing in a few places.  Also added more test cases to equals-masquerader.js.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * llint/LowLevelInterpreter32_64.asm:
+        * tests/stress/equals-masquerader.js:
+        (equalsNull):
+        (notEqualsNull):
+        (strictEqualsNull):
+        (strictNotEqualsNull):
+        (equalsUndefined):
+        (notEqualsUndefined):
+        (strictEqualsUndefined):
+        (strictNotEqualsUndefined):
+        (isFalsey):
+        (test):
+
+2014-03-07  Andrew Trick  <atrick@apple.com>
+
+        Temporarily disable repeat-out-of-bounds stress tests pending fix for 129953.
+        https://bugs.webkit.org/show_bug.cgi?id=129954
+
+        Reviewed by Filip Pizlo.
+
+        * tests/stress/float32-repeat-out-of-bounds.js:
+        * tests/stress/int8-repeat-out-of-bounds.js:
+
+2014-03-07  Michael Saboff  <msaboff@apple.com>
+
+        .cfi directives in LowLevelInterpreter.cpp are providing no benefit
+        https://bugs.webkit.org/show_bug.cgi?id=129945
+
+        Reviewed by Mark Lam.
+
+        Removed .cfi directive.  Verified that stack traces didn't regress in crash reporter
+        or in lldb.
+
+        * llint/LowLevelInterpreter.cpp:
+
+2014-03-07  Oliver Hunt  <oliver@apple.com>
+
+        Continue hangs when performing for-of over arguments
+        https://bugs.webkit.org/show_bug.cgi?id=129915
+
+        Reviewed by Geoffrey Garen.
+
+        Put the continue label in the right place
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEnumeration):
+
+2014-03-07  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win64] Compile error after r165128.
+        https://bugs.webkit.org/show_bug.cgi?id=129807
+
+        Reviewed by Mark Lam.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: 
+        Check platform environment variable to determine if an assembler file should be generated.
+
+2014-03-07  Michael Saboff  <msaboff@apple.com>
+
+        Clarify how we deal with "special" registers
+        https://bugs.webkit.org/show_bug.cgi?id=129806
+
+        Already reviewed change being relanded.
+
+        Relanding change set r165196 as it wasn't responsible for the breakage reported in
+        https://bugs.webkit.org/show_bug.cgi?id=129822.  That appears to be a build or
+
+        Reviewed by Michael Saboff.
+        configuration issue.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::lastRegister):
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::nextRegister):
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::restoreInto):
+        * ftl/FTLSaveRestore.cpp:
+        (JSC::FTL::saveAllRegisters):
+        (JSC::FTL::restoreAllRegisters):
+        * ftl/FTLSlowPathCall.cpp:
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::reservedHardwareRegisters):
+        (JSC::RegisterSet::runtimeRegisters):
+        (JSC::RegisterSet::specialRegisters):
+        (JSC::RegisterSet::calleeSaveRegisters):
+        * jit/RegisterSet.h:
+
+2014-03-07  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Move GCActivityCallback to heap
+        https://bugs.webkit.org/show_bug.cgi?id=129457
+
+        Reviewed by Geoffrey Garen.
+
+        All the other GC timer related stuff is there already.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/GCActivityCallback.cpp: Copied from Source/JavaScriptCore/runtime/GCActivityCallback.cpp.
+        * heap/GCActivityCallback.h: Copied from Source/JavaScriptCore/runtime/GCActivityCallback.h.
+        * runtime/GCActivityCallback.cpp: Removed.
+        * runtime/GCActivityCallback.h: Removed.
+
+2014-03-07  Andrew Trick  <atrick@apple.com>
+
+        Correct a comment typo from:
+        FLT should call fmod directly on platforms where LLVM cannot relocate the libcall
+        https://bugs.webkit.org/show_bug.cgi?id=129865
+
+        Reviewed by Mark Lam.
+
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleRem):
+
+2014-03-07  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Use OwnPtr in StructureIDTable
+        https://bugs.webkit.org/show_bug.cgi?id=129828
+
+        Reviewed by Geoffrey Garen.
+
+        This reduces the amount of boilerplate and fixes a memory leak.
+
+        * runtime/StructureIDTable.cpp:
+        (JSC::StructureIDTable::StructureIDTable):
+        (JSC::StructureIDTable::resize):
+        (JSC::StructureIDTable::flushOldTables):
+        (JSC::StructureIDTable::allocateID):
+        (JSC::StructureIDTable::deallocateID):
+        * runtime/StructureIDTable.h:
+        (JSC::StructureIDTable::table):
+        (JSC::StructureIDTable::get):
+
+2014-03-07  Andrew Trick  <atrick@apple.com>
+
+        FLT should call fmod directly on platforms where LLVM cannot relocate the libcall
+        https://bugs.webkit.org/show_bug.cgi?id=129865
+
+        Reviewed by Filip Pizlo.
+
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleRem):
+
+2014-03-06  Filip Pizlo  <fpizlo@apple.com>
+
+        If the FTL is build-time enabled then it should be run-time enabled.
+
+        Rubber stamped by Geoffrey Garen.
+
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+
+2014-03-06  Joseph Pecoraro  <pecoraro@apple.com>
+
+        [OS X] Web Inspector: Allow Apps using JavaScriptCore to access "com.apple.webinspector" mach port
+        https://bugs.webkit.org/show_bug.cgi?id=129852
+
+        Reviewed by Geoffrey Garen.
+
+        * framework.sb: Added.
+        Sandbox extension to allow access to "com.apple.webinspector".
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Add a Copy Resources build phase and include framework.sb.
+
+        * Configurations/JavaScriptCore.xcconfig:
+        Do not copy framework.sb on iOS.
+
+2014-03-06  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSGlobalContextRelease incorrectly handles saving/restoring IdentifierTable
+        https://bugs.webkit.org/show_bug.cgi?id=129858
+
+        Reviewed by Mark Lam.
+
+        It was correct (but really ugly) prior to the combining of APIEntryShim and JSLock, 
+        but now it ends up overwriting the IdentifierTable that JSLock just restored.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextRelease):
+
+2014-03-06  Oliver Hunt  <oliver@apple.com>
+
+        Fix FTL build.
+
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2014-03-06  Brent Fulgham  <bfulgham@apple.com>
+
+        Unreviewed build fix after r165128.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: The SEH flag was not getting set when
+        performing 'Production' and 'DebugSuffix' type builds.
+
+2014-03-06  Julien Brianceau  <jbriance@cisco.com>
+
+        Unreviewed, fix style in my previous commit.
+        https://bugs.webkit.org/show_bug.cgi?id=129833
+
+        * runtime/JSConsole.cpp:
+
+2014-03-06  Julien Brianceau  <jbriance@cisco.com>
+
+        Build fix: add missing include in JSConole.cpp.
+        https://bugs.webkit.org/show_bug.cgi?id=129833
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/JSConsole.cpp:
+
+2014-03-06  Oliver Hunt  <oliver@apple.com>
+
+        Fix ARMv7
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2014-03-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r165196.
+        http://trac.webkit.org/changeset/165196
+        https://bugs.webkit.org/show_bug.cgi?id=129822
+
+        broke arm64 on hardware (Requested by bfulgham on #webkit).
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::lastRegister):
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::isStackRelated):
+        (JSC::MacroAssembler::firstRealRegister):
+        (JSC::MacroAssembler::nextRegister):
+        (JSC::MacroAssembler::secondRealRegister):
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::restoreInto):
+        * ftl/FTLSaveRestore.cpp:
+        (JSC::FTL::saveAllRegisters):
+        (JSC::FTL::restoreAllRegisters):
+        * ftl/FTLSlowPathCall.cpp:
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::specialRegisters):
+        (JSC::RegisterSet::calleeSaveRegisters):
+        * jit/RegisterSet.h:
+
+2014-03-06  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(r165205): broke the CLOOP build (Requested by smfr on #webkit).
+        <https://webkit.org/b/129813>
+
+        Reviewed by Michael Saboff.
+
+        Fixed broken C loop LLINT build.
+
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoop::execute):
+        * offlineasm/cloop.rb:
+
+2014-03-03  Oliver Hunt  <oliver@apple.com>
+
+        Support caching of custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=129519
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds caching of assignment to properties that
+        are backed by C functions. This provides most of the leg
+        work required to start supporting setters, and resolves
+        the remaining regressions from moving DOM properties up
+        the prototype chain.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PutByIdAccess::visitWeak):
+        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
+        (JSC::PolymorphicPutByIdList::from):
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::transition):
+        (JSC::PutByIdAccess::replace):
+        (JSC::PutByIdAccess::customSetter):
+        (JSC::PutByIdAccess::isCustom):
+        (JSC::PutByIdAccess::oldStructure):
+        (JSC::PutByIdAccess::chain):
+        (JSC::PutByIdAccess::stubRoutine):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::dump):
+        * bytecode/PutByIdStatus.h:
+        (JSC::PutByIdStatus::PutByIdStatus):
+        (JSC::PutByIdStatus::takesSlowPath):
+        (JSC::PutByIdStatus::makesCalls):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPutById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasIdentifier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITByIdGenerator::JITByIdGenerator):
+        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
+        * jit/JITInlineCacheGenerator.h:
+        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::emitCustomSetterStub):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * jit/SpillRegistersMode.h: Added.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::setCacheableCustomProperty):
+        (JSC::PutPropertySlot::customSetter):
+        (JSC::PutPropertySlot::isCacheablePut):
+        (JSC::PutPropertySlot::isCacheableCustomProperty):
+        (JSC::PutPropertySlot::cachedOffset):
+
+2014-03-06  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL arity fixup should work on ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=129810
+
+        Reviewed by Michael Saboff.
+        
+        - Using regT5 to pass the thunk return address to arityFixup is shady since that's a
+          callee-save.
+        
+        - The FTL path was assuming X86 conventions for where SP points at the top of the prologue.
+        
+        This makes some more tests pass.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileFunction):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::prologueStackPointerDelta):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/ThunkGenerators.cpp:
+        (JSC::arityFixup):
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm64.rb:
+        * offlineasm/x86.rb: In addition to the t7 change, make t6 agree with GPRInfo.h.
+
+2014-03-06  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Fix write barriers in Repatch.cpp for !ENABLE(DFG_JIT) platforms after r165128
+        https://bugs.webkit.org/show_bug.cgi?id=129760
+
+        Reviewed by Geoffrey Garen.
+
+        r165128 disabled the write barrier fast path for inline caches on !ENABLE(DFG_JIT) platforms. 
+        The fix is to refactor the write barrier code into AssemblyHelpers and use that everywhere.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::checkMarkByte):
+        * jit/JIT.h:
+        * jit/JITPropertyAccess.cpp:
+        * jit/Repatch.cpp:
+        (JSC::writeBarrier):
+
+2014-03-06  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Expose the console object in JSContexts to interact with Web Inspector
+        https://bugs.webkit.org/show_bug.cgi?id=127944
+
+        Reviewed by Geoffrey Garen.
+
+        Always expose the Console object in JSContexts, just like we
+        do for web pages. The default behavior will route to an
+        attached JSContext inspector. This can be overriden by
+        setting the ConsoleClient on the JSGlobalObject, which WebCore
+        does to get slightly different behavior.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Update build systems.
+
+        * API/tests/testapi.js:
+        * API/tests/testapi.mm:
+        Test that "console" exists in C and ObjC contexts.
+
+        * runtime/ConsoleClient.cpp: Added.
+        (JSC::ConsoleClient::printURLAndPosition):
+        (JSC::ConsoleClient::printMessagePrefix):
+        (JSC::ConsoleClient::printConsoleMessage):
+        (JSC::ConsoleClient::printConsoleMessageWithArguments):
+        (JSC::ConsoleClient::internalMessageWithTypeAndLevel):
+        (JSC::ConsoleClient::logWithLevel):
+        (JSC::ConsoleClient::clear):
+        (JSC::ConsoleClient::dir):
+        (JSC::ConsoleClient::dirXML):
+        (JSC::ConsoleClient::table):
+        (JSC::ConsoleClient::trace):
+        (JSC::ConsoleClient::assertCondition):
+        (JSC::ConsoleClient::group):
+        (JSC::ConsoleClient::groupCollapsed):
+        (JSC::ConsoleClient::groupEnd):
+        * runtime/ConsoleClient.h: Added.
+        (JSC::ConsoleClient::~ConsoleClient):
+        New private interface for handling the console object's methods.
+        A lot of the methods funnel through messageWithTypeAndLevel.
+
+        * runtime/ConsoleTypes.h: Renamed from Source/JavaScriptCore/inspector/ConsoleTypes.h.
+        Moved to JSC namespace.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        Create the "console" object when initializing the environment.
+        Also set the default console client to be the JS context inspector.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::setConsoleClient):
+        (JSC::JSGlobalObject::consoleClient):
+        Ability to change the console client, so WebCore can set a custom client.
+
+        * runtime/ConsolePrototype.cpp: Added.
+        (JSC::ConsolePrototype::finishCreation):
+        (JSC::valueToStringWithUndefinedOrNullCheck):
+        (JSC::consoleLogWithLevel):
+        (JSC::consoleProtoFuncDebug):
+        (JSC::consoleProtoFuncError):
+        (JSC::consoleProtoFuncLog):
+        (JSC::consoleProtoFuncWarn):
+        (JSC::consoleProtoFuncClear):
+        (JSC::consoleProtoFuncDir):
+        (JSC::consoleProtoFuncDirXML):
+        (JSC::consoleProtoFuncTable):
+        (JSC::consoleProtoFuncTrace):
+        (JSC::consoleProtoFuncAssert):
+        (JSC::consoleProtoFuncCount):
+        (JSC::consoleProtoFuncProfile):
+        (JSC::consoleProtoFuncProfileEnd):
+        (JSC::consoleProtoFuncTime):
+        (JSC::consoleProtoFuncTimeEnd):
+        (JSC::consoleProtoFuncTimeStamp):
+        (JSC::consoleProtoFuncGroup):
+        (JSC::consoleProtoFuncGroupCollapsed):
+        (JSC::consoleProtoFuncGroupEnd):
+        * runtime/ConsolePrototype.h: Added.
+        (JSC::ConsolePrototype::create):
+        (JSC::ConsolePrototype::createStructure):
+        (JSC::ConsolePrototype::ConsolePrototype):
+        Define the console object interface. Parse out required / expected
+        arguments and throw expcetions when methods are misused.
+
+        * runtime/JSConsole.cpp: Added.
+        * runtime/JSConsole.h: Added.
+        (JSC::JSConsole::createStructure):
+        (JSC::JSConsole::create):
+        (JSC::JSConsole::JSConsole):
+        Empty "console" object. Everything is in the prototype.
+
+        * inspector/JSConsoleClient.cpp: Added.
+        (Inspector::JSConsoleClient::JSGlobalObjectConsole):
+        (Inspector::JSConsoleClient::count):
+        (Inspector::JSConsoleClient::profile):
+        (Inspector::JSConsoleClient::profileEnd):
+        (Inspector::JSConsoleClient::time):
+        (Inspector::JSConsoleClient::timeEnd):
+        (Inspector::JSConsoleClient::timeStamp):
+        (Inspector::JSConsoleClient::warnUnimplemented):
+        (Inspector::JSConsoleClient::internalAddMessage):
+        * inspector/JSConsoleClient.h: Added.
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::consoleClient):
+        * inspector/JSGlobalObjectInspectorController.h:
+        Default JSContext ConsoleClient implementation. Handle nearly
+        everything exception profile/profileEnd and timeStamp.
+
+2014-03-06  Andreas Kling  <akling@apple.com>
+
+        Drop unlinked function code on memory pressure.
+        <https://webkit.org/b/129789>
+
+        Make VM::discardAllCode() also drop UnlinkedFunctionCodeBlocks that
+        are not currently being compiled.
+
+        4.5 MB progression on Membuster.
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllUnlinkedFunctionCode):
+        * heap/Heap.h:
+        * runtime/VM.cpp:
+        (JSC::VM::discardAllCode):
+
+2014-03-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Clarify how we deal with "special" registers
+        https://bugs.webkit.org/show_bug.cgi?id=129806
+
+        Reviewed by Michael Saboff.
+        
+        Previously we had two different places that defined what "stack" registers are, a thing
+        called "specialRegisters" that had unclear meaning, and a really weird "firstRealRegister"/
+        "secondRealRegister"/"nextRegister" idiom in MacroAssembler that appeared to only be used by
+        one place and had a baked-in notion of what it meant for a register to be "real" or not.
+        
+        It's not cool to use words like "real" and "special" to describe registers, especially if you
+        fail to qualify what that means. This originally made sense on X86 - "real" registers were
+        the ones that weren't "stack related" (so "real" was the opposite of "stack"). But on ARM64,
+        you also have to worry about the LR register, which we'd want to say is "not real" but it's
+        also not a "stack" register. This got super confusing.
+        
+        So, this patch removes any mention of "real" registers, consolidates the knowledge of what is
+        a "stack" register, and uses the word special only in places where it's clearly defined and
+        where no better word comes to mind.
+        
+        This cleans up the code and fixes what seems like it was probably a harmless ARM64 bug: the
+        Reg and RegisterSet data structures would sometimes think that FP was Q0. Somehow this
+        magically didn't break anything because you never need to save/restore either FP or Q0, but
+        it was still super weird.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::lastRegister):
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::nextRegister):
+        * ftl/FTLLocation.cpp:
+        (JSC::FTL::Location::restoreInto):
+        * ftl/FTLSaveRestore.cpp:
+        (JSC::FTL::saveAllRegisters):
+        (JSC::FTL::restoreAllRegisters):
+        * ftl/FTLSlowPathCall.cpp:
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::reservedHardwareRegisters):
+        (JSC::RegisterSet::runtimeRegisters):
+        (JSC::RegisterSet::specialRegisters):
+        (JSC::RegisterSet::calleeSaveRegisters):
+        * jit/RegisterSet.h:
+
+2014-03-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix build.
+
+        * disassembler/ARM64Disassembler.cpp:
+
+2014-03-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Use the LLVM disassembler on ARM64 if we are enabling the FTL
+        https://bugs.webkit.org/show_bug.cgi?id=129785
+
+        Reviewed by Geoffrey Garen.
+        
+        Our disassembler can't handle some of the code sequences that LLVM emits. LLVM's disassembler
+        is strictly more capable at this point. Use it if it's available.
+
+        * disassembler/ARM64Disassembler.cpp:
+        (JSC::tryToDisassemble):
+
+2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Reduce RWI message frequency
+        https://bugs.webkit.org/show_bug.cgi?id=129767
+
+        Reviewed by Timothy Hatcher.
+
+        This used to be 0.2s and changed by accident to 0.02s.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::pushListingSoon):
+
+2014-03-05  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r165141, r165157, and r165158.
+        http://trac.webkit.org/changeset/165141
+        http://trac.webkit.org/changeset/165157
+        http://trac.webkit.org/changeset/165158
+        https://bugs.webkit.org/show_bug.cgi?id=129772
+
+        "broke ftl" (Requested by olliej_ on #webkit).
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PutByIdAccess::visitWeak):
+        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
+        (JSC::PolymorphicPutByIdList::from):
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::transition):
+        (JSC::PutByIdAccess::replace):
+        (JSC::PutByIdAccess::oldStructure):
+        (JSC::PutByIdAccess::chain):
+        (JSC::PutByIdAccess::stubRoutine):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::dump):
+        * bytecode/PutByIdStatus.h:
+        (JSC::PutByIdStatus::PutByIdStatus):
+        (JSC::PutByIdStatus::takesSlowPath):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPutById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasIdentifier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITByIdGenerator::JITByIdGenerator):
+        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
+        * jit/JITInlineCacheGenerator.h:
+        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * jit/SpillRegistersMode.h: Removed.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::isCacheable):
+        (JSC::PutPropertySlot::cachedOffset):
+
+2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Prevent possible deadlock in view indication
+        https://bugs.webkit.org/show_bug.cgi?id=129766
+
+        Reviewed by Geoffrey Garen.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::receivedIndicateMessage):
+
+2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSObject::fastGetOwnPropertySlot does a slow check for OverridesGetOwnPropertySlot
+        https://bugs.webkit.org/show_bug.cgi?id=129754
+
+        Reviewed by Geoffrey Garen.
+
+        InlineTypeFlags are stored in JSCell, so we can just load those instead of going through the TypeInfo.
+
+        * runtime/JSCell.h:
+        (JSC::JSCell::inlineTypeFlags):
+        * runtime/JSObject.h:
+        (JSC::JSObject::fastGetOwnPropertySlot):
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::TypeInfo):
+        (JSC::TypeInfo::overridesGetOwnPropertySlot):
+
+2014-03-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ASSERTION FAILED: m_javaScriptBreakpoints.isEmpty()
+        https://bugs.webkit.org/show_bug.cgi?id=129763
+
+        Reviewed by Geoffrey Garen.
+
+        Clear the list of all breakpoints, including unresolved breakpoints.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
+
+2014-03-05  Mark Lam  <mark.lam@apple.com>
+
+        llint_slow_path_check_has_instance() should not adjust PC before accessing operands.
+        <https://webkit.org/b/129768>
+
+        Reviewed by Mark Hahnenberg.
+
+        When evaluating "a instanceof b" where b is an object that ImplementsHasInstance
+        and OverridesHasInstance (e.g. a bound function), the LLINT will take the slow
+        path llint_slow_path_check_has_instance(), and execute a code path that does the
+        following:
+        1. Adjusts the byte code PC to the jump target PC.
+        2. For the purpose of storing the result, get the result registerIndex from the
+           1st operand using the PC as if the PC is still pointing to op_check_has_instance
+           bytecode.
+
+        The result is that whatever value resides after where the jump target PC is will
+        be used as a result register value.  Depending on what that value is, the result
+        can be:
+        1. the code coincidently works correctly
+        2. memory corruption
+        3. crashes
+
+        The fix is to only adjust the byte code PC after we have stored the result.
+        
+        * llint/LLIntSlowPaths.cpp:
+        (llint_slow_path_check_has_instance):
+
+2014-03-05  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Another build fix attempt after r165141.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+
+2014-03-05  Ryosuke Niwa  <rniwa@webkit.org>
+
+        FTL build fix attempt after r165141.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+
+2014-03-05  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=128625
+        Add fast mapping from StringImpl to JSString
+
+        Unreviewed roll-out.
+
+        Reverting r164347, r165054, r165066 - not clear the performance tradeoff was right.
+
+        * runtime/JSString.cpp:
+        * runtime/JSString.h:
+        * runtime/VM.cpp:
+        (JSC::VM::createLeaked):
+        * runtime/VM.h:
+
+2014-03-03  Oliver Hunt  <oliver@apple.com>
+
+        Support caching of custom setters
+        https://bugs.webkit.org/show_bug.cgi?id=129519
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds caching of assignment to properties that
+        are backed by C functions. This provides most of the leg
+        work required to start supporting setters, and resolves
+        the remaining regressions from moving DOM properties up
+        the prototype chain.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PutByIdAccess::visitWeak):
+        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList):
+        (JSC::PolymorphicPutByIdList::from):
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::transition):
+        (JSC::PutByIdAccess::replace):
+        (JSC::PutByIdAccess::customSetter):
+        (JSC::PutByIdAccess::isCustom):
+        (JSC::PutByIdAccess::oldStructure):
+        (JSC::PutByIdAccess::chain):
+        (JSC::PutByIdAccess::stubRoutine):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::dump):
+        * bytecode/PutByIdStatus.h:
+        (JSC::PutByIdStatus::PutByIdStatus):
+        (JSC::PutByIdStatus::takesSlowPath):
+        (JSC::PutByIdStatus::makesCalls):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPutById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasIdentifier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITByIdGenerator::JITByIdGenerator):
+        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
+        * jit/JITInlineCacheGenerator.h:
+        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_put_by_id):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::emitCustomSetterStub):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        * jit/SpillRegistersMode.h: Added.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::setCacheableCustomProperty):
+        (JSC::PutPropertySlot::customSetter):
+        (JSC::PutPropertySlot::isCacheablePut):
+        (JSC::PutPropertySlot::isCacheableCustomProperty):
+        (JSC::PutPropertySlot::cachedOffset):
+
+2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSCell::m_gcData should encode its information differently
+        https://bugs.webkit.org/show_bug.cgi?id=129741
+
+        Reviewed by Geoffrey Garen.
+
+        We want to keep track of three GC states for an object:
+
+        1. Not marked (which implies not in the remembered set)
+        2. Marked but not in the remembered set
+        3. Marked and in the remembered set
+        
+        Currently we only indicate marked vs. not marked in JSCell::m_gcData. During a write 
+        barrier, we only want to take the slow path if the object being stored to is in state #2. 
+        We'd like to make the test for state #2 as fast as possible, which means making it a 
+        compare against 0.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::osrWriteBarrier):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::checkMarkByte):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        * heap/Heap.cpp:
+        (JSC::Heap::clearRememberedSet):
+        (JSC::Heap::addToRememberedSet):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::checkMarkByte):
+        * jit/JIT.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::checkMarkByte):
+        (JSC::JIT::emitWriteBarrier):
+        * jit/Repatch.cpp:
+        (JSC::writeBarrier):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSCell.h:
+        (JSC::JSCell::mark):
+        (JSC::JSCell::remember):
+        (JSC::JSCell::forget):
+        (JSC::JSCell::isMarked):
+        (JSC::JSCell::isRemembered):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::JSCell):
+        * runtime/StructureIDBlob.h:
+        (JSC::StructureIDBlob::StructureIDBlob):
+
+2014-03-05  Filip Pizlo  <fpizlo@apple.com>
+
+        More FTL ARM fixes
+        https://bugs.webkit.org/show_bug.cgi?id=129755
+
+        Reviewed by Geoffrey Garen.
+        
+        - Be more defensive about inline caches that have degenerate chains.
+        
+        - Temporarily switch to allocating all MCJIT memory in the executable pool on non-x86
+          platforms. The bug tracking the real fix is: https://bugs.webkit.org/show_bug.cgi?id=129756
+        
+        - Don't even emit intrinsic declarations on non-x86 platforms.
+        
+        - More debug printing support.
+        
+        - Don't use vmCall() in the prologue. This should have crashed on all platforms all the time
+          but somehow it gets lucky on x86.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::appendVariant):
+        (JSC::GetByIdStatus::computeForChain):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::appendVariant):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.h:
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::overlaps):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLDataSection.cpp:
+        (JSC::FTL::DataSection::DataSection):
+        (JSC::FTL::DataSection::~DataSection):
+        * ftl/FTLDataSection.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleSin):
+        (JSC::FTL::Output::doubleCos):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::dumpInContext):
+        * runtime/JSCell.h:
+        (JSC::JSCell::structureID):
+
+2014-03-05  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win32][LLINT] Crash when running JSC stress tests.
+        https://bugs.webkit.org/show_bug.cgi?id=129429
+
+        On Windows the reserved stack space consists of committed memory, a guard page, and uncommitted memory,
+        where the guard page is a barrier between committed and uncommitted memory.
+        When data from the guard page is read or written, the guard page is moved, and memory is committed.
+        This is how the system grows the stack.
+        When using the C stack on Windows we need to precommit the needed stack space.
+        Otherwise we might crash later if we access uncommitted stack memory.
+        This can happen if we allocate stack space larger than the page guard size (4K).
+        The system does not get the chance to move the guard page, and commit more memory,
+        and we crash if uncommitted memory is accessed.
+        The MSVC compiler fixes this by inserting a call to the _chkstk() function,
+        when needed, see http://support.microsoft.com/kb/100775.
+
+        Reviewed by Geoffrey Garen.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Enable LLINT.
+        * jit/Repatch.cpp:
+        (JSC::writeBarrier): Compile fix when DFG_JIT is not enabled.
+        * offlineasm/x86.rb: Compile fix, and small simplification.
+        * runtime/VM.cpp:
+        (JSC::preCommitStackMemory): Added function to precommit stack memory.
+        (JSC::VM::updateStackLimit): Call function to precommit stack memory when stack limit is updated.
+
+2014-03-05  Michael Saboff  <msaboff@apple.com>
+
+        JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
+        https://bugs.webkit.org/show_bug.cgi?id=129746
+
+        Reviewed by Filip Pizlo.
+
+        Changed to use a union to manually assemble or disassemble the various types
+        from / to the corresponding bytes.  All memory access is now done using
+        byte accesses.
+
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+        (JSC::setData):
+
+2014-03-05  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL loadStructure always generates invalid IR
+        https://bugs.webkit.org/show_bug.cgi?id=129747
+
+        Reviewed by Mark Hahnenberg.
+
+        As the comment at the top of FTL::Output states, the FTL doesn't use LLVM's notion
+        of pointers. LLVM's notion of pointers tries to model C, in the sense that you have
+        to have a pointer to a type, and you can only load things of that type from that
+        pointer. Pointer arithmetic is basically not possible except through the bizarre
+        getelementptr operator. This doesn't fit with how the JS object model works since
+        the JS object model doesn't consist of nice and tidy C types placed in C arrays.
+        Also, it would be impossible to use getelementptr and LLVM pointers for accessing
+        any of JSC's C or C++ objects unless we went through the exercise of redeclaring
+        all of our fundamental data structures in LLVM IR as LLVM types. Clang could do
+        this for us, but that would require that to use the FTL, JSC itself would have to
+        be compiled with clang. Worse, it would have to be compiled with a clang that uses
+        a version of LLVM that is compatible with the one against which the FTL is linked.
+        Yuck!
+
+        The solution is to NEVER use LLVM pointers. This has always been the case in the
+        FTL. But it causes some confusion.
+        
+        Not using LLVM pointers means that if the FTL has a "pointer", it's actually a
+        pointer-wide integer (m_out.intPtr in FTL-speak). The act of "loading" and
+        "storing" from or to a pointer involves first bitcasting the intPtr to a real LLVM
+        pointer that has the type that we want. The load and store operations over pointers
+        are called Output::load* and Output::store*, where * is one of "8", "16", "32",
+        "64", "Ptr", "Float", or "Double.
+        
+        There is unavoidable confusion here. It would be bizarre for the FTL to call its
+        "pointer-wide integers" anything other than "pointers", since they are, in all
+        respects that we care about, simply pointers. But they are *not* LLVM pointers and
+        they never will be that.
+        
+        There is one exception to this "no pointers" rule. The FTL does use actual LLVM
+        pointers for refering to LLVM alloca's - i.e. local variables. To try to reduce
+        confusion, we call these "references". So an "FTL reference" is actually an "LLVM
+        pointer", while an "FTL pointer" is actually an "LLVM integer". FTL references have
+        methods for access called Output::get and Output::set. These lower to LLVM load
+        and store, since FTL references are just LLVM pointers.
+        
+        This confusion appears to have led to incorrect code in loadStructure().
+        loadStructure() was using get() and set() to access FTL pointers. But those methods
+        don't work on FTL pointers and never will, since they are for FTL references.
+        
+        The worst part of this is that it was previously impossible to have test coverage
+        for the relevant path (MasqueradesAsUndefined) without writing a DRT test. This
+        patch fixes this by introducing a Masquerader object to jsc.cpp.
+        
+        * ftl/FTLAbstractHeapRepository.h: Add an abstract heap for the structure table.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::loadStructure): This was wrong.
+        * ftl/FTLOutput.h: Add a comment to disuade people from using get() and set().
+        * jsc.cpp: Give us the power to test for MasqueradesAsUndefined.
+        (WTF::Masquerader::Masquerader):
+        (WTF::Masquerader::create):
+        (WTF::Masquerader::createStructure):
+        (GlobalObject::finishCreation):
+        (functionMakeMasquerader):
+        * tests/stress/equals-masquerader.js: Added.
+        (foo):
+        (test):
+
+2014-03-05  Anders Carlsson  <andersca@apple.com>
+
+        Tweak after r165109 to avoid extra copies
+        https://bugs.webkit.org/show_bug.cgi?id=129745
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::visitProtectedObjects):
+        (JSC::Heap::visitTempSortVectors):
+        (JSC::Heap::clearRememberedSet):
+        * heap/Heap.h:
+        (JSC::Heap::forEachProtectedCell):
+
+2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        DFGStoreBarrierElisionPhase should should GCState directly instead of m_gcClobberSet when calling writesOverlap()
+        https://bugs.webkit.org/show_bug.cgi?id=129717
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGStoreBarrierElisionPhase.cpp:
+        (JSC::DFG::StoreBarrierElisionPhase::StoreBarrierElisionPhase):
+        (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC):
+
+2014-03-05  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Use range-based loops where possible in Heap methods
+        https://bugs.webkit.org/show_bug.cgi?id=129513
+
+        Reviewed by Mark Lam.
+
+        Replace old school iterator based loops with the new range-based loop hotness
+        for a better tomorrow.
+
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::~CodeBlockSet):
+        (JSC::CodeBlockSet::clearMarks):
+        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
+        (JSC::CodeBlockSet::traceMarked):
+        * heap/Heap.cpp:
+        (JSC::Heap::visitProtectedObjects):
+        (JSC::Heap::visitTempSortVectors):
+        (JSC::Heap::clearRememberedSet):
+        * heap/Heap.h:
+        (JSC::Heap::forEachProtectedCell):
+
+2014-03-04  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
+        https://bugs.webkit.org/show_bug.cgi?id=129563
+
+        Reviewed by Geoffrey Garen.
+        
+        Rolling this back in after fixing an assertion failure. speculateMisc() should have
+        said DFG_TYPE_CHECK instead of typeCheck.
+        
+        This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
+        when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
+        user of this was EarleyBoyer, and in that benchmark what it was really doing was
+        comparing undefined, null, and booleans to each other.
+        
+        This also adds support for miscellaneous things that I needed to make my various test
+        cases work. This includes comparison over booleans and the various Throw-related node
+        types.
+        
+        This also improves constant folding of CompareStrictEq and CompareEq.
+        
+        Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
+        based on profiling, which caused some downstream badness. We don't actually support
+        compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
+        emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
+        shouldn't factor out the bounds check since the access is not InBounds but then the
+        backend would ignore the flag and assume that the bounds check was already emitted.
+        This showed up on an existing test but I added a test for this explicitly to have more
+        certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
+        that we'll have a bounds check anyway.
+        
+        This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
+        general progressions across the board. No speed-up yet on EarleyBoyer, since there is
+        still a lot more coverage work to be done there.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
+        (JSC::valuesCouldBeEqual):
+        * bytecode/SpeculatedType.h:
+        (JSC::isMiscSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        * dfg/DFGArrayMode.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateMisc):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::speculateMisc):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileThrow):
+        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
+        (JSC::FTL::LowerDFGToLLVM::isMisc):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
+        * tests/stress/float32-array-out-of-bounds.js: Added.
+        * tests/stress/weird-equality-folding-cases.js: Added.
+
+2014-03-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r165085.
+        http://trac.webkit.org/changeset/165085
+        https://bugs.webkit.org/show_bug.cgi?id=129729
+
+        Broke imported/w3c/html-templates/template-element/template-
+        content.html (Requested by ap on #webkit).
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        * dfg/DFGArrayMode.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateBoolean):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        * dfg/DFGSpeculativeJIT64.cpp:
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        * tests/stress/float32-array-out-of-bounds.js: Removed.
+        * tests/stress/weird-equality-folding-cases.js: Removed.
+
+2014-03-04  Brian Burg  <bburg@apple.com>
+
+        Inspector does not restore breakpoints after a page reload
+        https://bugs.webkit.org/show_bug.cgi?id=129655
+
+        Reviewed by Joseph Pecoraro.
+
+        Fix a regression introduced by r162096 that erroneously removed
+        the inspector backend's mapping of files to breakpoints whenever the
+        global object was cleared.
+
+        The inspector's breakpoint mappings should only be cleared when the
+        debugger agent is disabled or destroyed. We should only clear the
+        debugger's breakpoint state when the global object is cleared.
+
+        To make it clearer what state is being cleared, the two cases have
+        been split into separate methods.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::disable):
+        (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState):
+        (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
+        (Inspector::InspectorDebuggerAgent::didClearGlobalObject):
+        * inspector/agents/InspectorDebuggerAgent.h:
+
+2014-03-04  Andreas Kling  <akling@apple.com>
+
+        Streamline JSValue::get().
+        <https://webkit.org/b/129720>
+
+        Fetch each Structure and VM only once when walking the prototype chain
+        in JSObject::getPropertySlot(), then pass it along to the functions
+        we call from there, so they don't have to re-fetch it.
+
+        Reviewed by Geoff Garen.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+        (JSC::JSObject::fastGetOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+
+2014-03-01  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
+        https://bugs.webkit.org/show_bug.cgi?id=129563
+
+        Reviewed by Geoffrey Garen.
+        
+        This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
+        when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
+        user of this was EarleyBoyer, and in that benchmark what it was really doing was
+        comparing undefined, null, and booleans to each other.
+        
+        This also adds support for miscellaneous things that I needed to make my various test
+        cases work. This includes comparison over booleans and the various Throw-related node
+        types.
+        
+        This also improves constant folding of CompareStrictEq and CompareEq.
+        
+        Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
+        based on profiling, which caused some downstream badness. We don't actually support
+        compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
+        emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
+        shouldn't factor out the bounds check since the access is not InBounds but then the
+        backend would ignore the flag and assume that the bounds check was already emitted.
+        This showed up on an existing test but I added a test for this explicitly to have more
+        certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
+        that we'll have a bounds check anyway.
+        
+        This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
+        general progressions across the board. No speed-up yet on EarleyBoyer, since there is
+        still a lot more coverage work to be done there.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
+        (JSC::valuesCouldBeEqual):
+        * bytecode/SpeculatedType.h:
+        (JSC::isMiscSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateMisc):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::speculateMisc):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileThrow):
+        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
+        (JSC::FTL::LowerDFGToLLVM::isMisc):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
+        * tests/stress/float32-array-out-of-bounds.js: Added.
+        * tests/stress/weird-equality-folding-cases.js: Added.
+
+2014-03-04  Andreas Kling  <akling@apple.com>
+
+        Spam static branch prediction hints on JS bindings.
+        <https://webkit.org/b/129703>
+
+        Add LIKELY hint to jsDynamicCast since it's always used in a context
+        where we expect it to succeed and takes an error path when it doesn't.
+
+        Reviewed by Geoff Garen.
+
+        * runtime/JSCell.h:
+        (JSC::jsDynamicCast):
+
+2014-03-04  Andreas Kling  <akling@apple.com>
+
+        Get to Structures more efficiently in JSCell::methodTable().
+        <https://webkit.org/b/129702>
+
+        In JSCell::methodTable(), get the VM once and pass that along to
+        structure(VM&) instead of using the heavier structure().
+
+        In JSCell::methodTable(VM&), replace calls to structure() with
+        calls to structure(VM&).
+
+        Reviewed by Mark Hahnenberg.
+
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::methodTable):
+
+2014-03-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Listen for the XPC_ERROR_CONNECTION_INVALID event to deref
+        https://bugs.webkit.org/show_bug.cgi?id=129697
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+        (Inspector::RemoteInspectorXPCConnection::RemoteInspectorXPCConnection):
+        (Inspector::RemoteInspectorXPCConnection::handleEvent):
+
+2014-03-04  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Merge API shims and JSLock
+        https://bugs.webkit.org/show_bug.cgi?id=129650
+
+        Reviewed by Mark Lam.
+
+        JSLock is now taking on all of APIEntryShim's responsibilities since there is never a reason 
+        to take just the JSLock. Ditto for DropAllLocks and APICallbackShim.
+
+        * API/APICallbackFunction.h:
+        (JSC::APICallbackFunction::call):
+        (JSC::APICallbackFunction::construct):
+        * API/APIShims.h: Removed.
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        (JSGarbageCollect):
+        (JSReportExtraMemoryCost):
+        (JSSynchronousGarbageCollectForDebugging):
+        * API/JSCallbackConstructor.cpp:
+        * API/JSCallbackFunction.cpp:
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::init):
+        (JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
+        (JSC::JSCallbackObject<Parent>::put):
+        (JSC::JSCallbackObject<Parent>::putByIndex):
+        (JSC::JSCallbackObject<Parent>::deleteProperty):
+        (JSC::JSCallbackObject<Parent>::construct):
+        (JSC::JSCallbackObject<Parent>::customHasInstance):
+        (JSC::JSCallbackObject<Parent>::call):
+        (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
+        (JSC::JSCallbackObject<Parent>::getStaticValue):
+        (JSC::JSCallbackObject<Parent>::callbackGetter):
+        * API/JSContext.mm:
+        (-[JSContext setException:]):
+        (-[JSContext wrapperForObjCObject:]):
+        (-[JSContext wrapperForJSObject:]):
+        * API/JSContextRef.cpp:
+        (JSContextGroupRelease):
+        (JSContextGroupSetExecutionTimeLimit):
+        (JSContextGroupClearExecutionTimeLimit):
+        (JSGlobalContextCreateInGroup):
+        (JSGlobalContextRetain):
+        (JSGlobalContextRelease):
+        (JSContextGetGlobalObject):
+        (JSContextGetGlobalContext):
+        (JSGlobalContextCopyName):
+        (JSGlobalContextSetName):
+        * API/JSManagedValue.mm:
+        (-[JSManagedValue value]):
+        * API/JSObjectRef.cpp:
+        (JSObjectMake):
+        (JSObjectMakeFunctionWithCallback):
+        (JSObjectMakeConstructor):
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetPrototype):
+        (JSObjectSetPrototype):
+        (JSObjectHasProperty):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectGetPrivateProperty):
+        (JSObjectSetPrivateProperty):
+        (JSObjectDeletePrivateProperty):
+        (JSObjectIsFunction):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        (JSObjectCopyPropertyNames):
+        (JSPropertyNameArrayRelease):
+        (JSPropertyNameAccumulatorAddName):
+        * API/JSScriptRef.cpp:
+        * API/JSValue.mm:
+        (isDate):
+        (isArray):
+        (containerValueToObject):
+        (valueToArray):
+        (valueToDictionary):
+        (objectToValue):
+        * API/JSValueRef.cpp:
+        (JSValueGetType):
+        (JSValueIsUndefined):
+        (JSValueIsNull):
+        (JSValueIsBoolean):
+        (JSValueIsNumber):
+        (JSValueIsString):
+        (JSValueIsObject):
+        (JSValueIsObjectOfClass):
+        (JSValueIsEqual):
+        (JSValueIsStrictEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueMakeUndefined):
+        (JSValueMakeNull):
+        (JSValueMakeBoolean):
+        (JSValueMakeNumber):
+        (JSValueMakeString):
+        (JSValueMakeFromJSONString):
+        (JSValueCreateJSONString):
+        (JSValueToBoolean):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        (JSValueProtect):
+        (JSValueUnprotect):
+        * API/JSVirtualMachine.mm:
+        (-[JSVirtualMachine addManagedReference:withOwner:]):
+        (-[JSVirtualMachine removeManagedReference:withOwner:]):
+        * API/JSWeakObjectMapRefPrivate.cpp:
+        * API/JSWrapperMap.mm:
+        (constructorHasInstance):
+        (makeWrapper):
+        (tryUnwrapObjcObject):
+        * API/ObjCCallbackFunction.mm:
+        (JSC::objCCallbackFunctionCallAsFunction):
+        (JSC::objCCallbackFunctionCallAsConstructor):
+        (objCCallbackFunctionForInvocation):
+        * CMakeLists.txt:
+        * ForwardingHeaders/JavaScriptCore/APIShims.h: Removed.
+        * GNUmakefile.list.am:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGWorklist.cpp:
+        * heap/DelayedReleaseScope.h:
+        (JSC::DelayedReleaseScope::~DelayedReleaseScope):
+        * heap/HeapTimer.cpp:
+        (JSC::HeapTimer::timerDidFire):
+        (JSC::HeapTimer::timerEvent):
+        * heap/IncrementalSweeper.cpp:
+        * inspector/InjectedScriptModule.cpp:
+        (Inspector::InjectedScriptModule::ensureInjected):
+        * jsc.cpp:
+        (jscmain):
+        * runtime/GCActivityCallback.cpp:
+        (JSC::DefaultGCActivityCallback::doWork):
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::disconnect):
+        (JSC::JSGlobalObjectDebuggable::dispatchMessageFromRemoteFrontend):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::lock):
+        (JSC::JSLock::didAcquireLock):
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::willReleaseLock):
+        (JSC::JSLock::DropAllLocks::DropAllLocks):
+        (JSC::JSLock::DropAllLocks::~DropAllLocks):
+        * runtime/JSLock.h:
+        * testRegExp.cpp:
+        (realMain):
+
+2014-03-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r164812.
+        http://trac.webkit.org/changeset/164812
+        https://bugs.webkit.org/show_bug.cgi?id=129699
+
+        it made things run slower (Requested by pizlo on #webkit).
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        * runtime/BatchedTransitionOptimizer.h:
+        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
+        (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
+
+2014-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        GetMyArgumentByVal in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=128850
+
+        Reviewed by Oliver Hunt.
+        
+        This would have been easy if the OSR exit compiler's arity checks hadn't been wrong.
+        They checked arity by doing "exec->argumentCount == codeBlock->numParameters", which
+        caused it to think that the arity check had failed if the caller had passed more
+        arguments than needed. This would cause the call frame copying to sort of go into
+        reverse (because the amount-by-which-we-failed-arity would have opposite sign,
+        throwing off a bunch of math) and the stack would end up being corrupted.
+        
+        The bug was revealed by two existing tests although as far as I could tell, neither
+        test was intending to cover this case directly. So, I added a new test.
+
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated):
+        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLState.h:
+        * tests/stress/exit-from-ftl-when-caller-passed-extra-args-then-use-function-dot-arguments.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val-inlined-and-not-inlined.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val-inlined.js: Added.
+        * tests/stress/ftl-get-my-argument-by-val.js: Added.
+
+2014-03-04  Zan Dobersek  <zdobersek@igalia.com>
+
+        [GTK] Build the Udis86 disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=129679
+
+        Reviewed by Michael Saboff.
+
+        * GNUmakefile.am: Generate the Udis86-related derived sources. Distribute the required files.
+        * GNUmakefile.list.am: Add the Udis86 disassembler files to the build.
+
+2014-03-04  Andreas Kling  <akling@apple.com>
+
+        Fix too-narrow assertion I added in r165054.
+
+        It's okay for a 1-character string to come in here. This will happen
+        if the VM small string optimization doesn't apply (ch > 0xFF)
+
+        * runtime/JSString.h:
+        (JSC::jsStringWithWeakOwner):
+
+2014-03-04  Andreas Kling  <akling@apple.com>
+
+        Micro-optimize Strings in JS bindings.
+        <https://webkit.org/b/129673>
+
+        Make jsStringWithWeakOwner() take a StringImpl& instead of a String.
+        This avoids branches in length() and operator[].
+
+        Also call JSString::create() directly instead of jsString() and just
+        assert that the string length is >1. This way we don't duplicate the
+        optimizations for empty and single-character strings.
+
+        Reviewed by Ryosuke Niwa.
+
+        * runtime/JSString.h:
+        (JSC::jsStringWithWeakOwner):
+
+2014-03-04  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Implement Number.prototype.clz()
+        https://bugs.webkit.org/show_bug.cgi?id=129479
+
+        Reviewed by Oliver Hunt.
+
+        Implemented Number.prototype.clz() as specified in the ES6 standard.
+
+        * runtime/NumberPrototype.cpp:
+        (JSC::numberProtoFuncClz):
+
+2014-03-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Avoid too early deref caused by RemoteInspectorXPCConnection::close
+        https://bugs.webkit.org/show_bug.cgi?id=129631
+
+        Reviewed by Timothy Hatcher.
+
+        Avoid deref() too early if a client calls close(). The xpc_connection_close
+        will cause another XPC_ERROR event to come in from the queue, deref then.
+        Likewise, protect multithreaded access to m_client. If a client calls
+        close() we want to immediately clear the pointer to prevent calls to it.
+
+        Overall the multi-threading aspects of RemoteInspectorXPCConnection are
+        growing too complicated for probably little benefit. We may want to
+        clean this up later.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::xpcConnectionFailed):
+        * inspector/remote/RemoteInspectorXPCConnection.h:
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+        (Inspector::RemoteInspectorXPCConnection::RemoteInspectorXPCConnection):
+        (Inspector::RemoteInspectorXPCConnection::close):
+        (Inspector::RemoteInspectorXPCConnection::closeOnQueue):
+        (Inspector::RemoteInspectorXPCConnection::deserializeMessage):
+        (Inspector::RemoteInspectorXPCConnection::handleEvent):
+        (Inspector::RemoteInspectorXPCConnection::sendMessage):
+
+2014-03-03  Michael Saboff  <msaboff@apple.com>
+
+        AbstractMacroAssembler::CachedTempRegister should start out invalid
+        https://bugs.webkit.org/show_bug.cgi?id=129657
+
+        Reviewed by Filip Pizlo.
+
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::AbstractMacroAssembler):
+        - Invalidate all cached registers in constructor as we don't know the
+          contents of any register at the entry to the code we are going to
+          generate.
+
+2014-03-03  Andreas Kling  <akling@apple.com>
+
+        StructureOrOffset should be fastmalloced.
+        <https://webkit.org/b/129640>
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/StructureIDTable.h:
+
+2014-03-03  Michael Saboff  <msaboff@apple.com>
+
+        Crash in JIT code while watching a video @ storyboard.tumblr.com
+        https://bugs.webkit.org/show_bug.cgi?id=129635
+
+        Reviewed by Filip Pizlo.
+
+        Clear m_set before we set bits in the TempRegisterSet(const RegisterSet& other)
+        construtor.
+
+        * jit/TempRegisterSet.cpp:
+        (JSC::TempRegisterSet::TempRegisterSet): Clear map before setting it.
+        * jit/TempRegisterSet.h:
+        (JSC::TempRegisterSet::TempRegisterSet): Use new clearAll() helper.
+        (JSC::TempRegisterSet::clearAll): New private helper.
+
+2014-03-03  Benjamin Poulain  <benjamin@webkit.org>
+
+        [x86] Improve code generation of byte test
+        https://bugs.webkit.org/show_bug.cgi?id=129597
+
+        Reviewed by Geoffrey Garen.
+
+        When possible, test the 8 bit register to itself instead of comparing it
+        to a literal.
+
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::test32):
+
+2014-03-03  Mark Lam  <mark.lam@apple.com>
+
+        Web Inspector: debugger statements do not break.
+        <https://webkit.org/b/129524>
+
+        Reviewed by Geoff Garen.
+
+        Since we no longer call op_debug hooks unless there is a debugger request
+        made on the CodeBlock, the op_debug for the debugger statement never gets
+        serviced.
+
+        With this fix, we check in the CodeBlock constructor if any debugger
+        statements are present.  If so, we set a m_hasDebuggerStatement flag that
+        causes the CodeBlock to show as having debugger requests.  Hence,
+        breaking at debugger statements is now restored.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::hasDebuggerRequests):
+        (JSC::CodeBlock::clearDebuggerRequests):
+
+2014-03-03  Mark Lam  <mark.lam@apple.com>
+
+        ASSERTION FAILED: m_numBreakpoints >= numBreakpoints when deleting breakpoints.
+        <https://webkit.org/b/129393>
+
+        Reviewed by Geoffrey Garen.
+
+        The issue manifests because the debugger will iterate all CodeBlocks in
+        the heap when setting / clearing breakpoints, but it is possible for a
+        CodeBlock to have been instantiate but is not yet registered with the
+        debugger.  This can happen because of the following:
+
+        1. DFG worklist compilation is still in progress, and the target
+           codeBlock is not ready for installation in its executable yet.
+
+        2. DFG compilation failed and we have a codeBlock that will never be
+           installed in its executable, and the codeBlock has not been cleaned
+           up by the GC yet.
+
+        The code for installing the codeBlock in its executable is the same code
+        that registers it with the debugger.  Hence, these codeBlocks are not
+        registered with the debugger, and any pending breakpoints that would map
+        to that CodeBlock is as yet unset or will never be set.  As such, an
+        attempt to remove a breakpoint in that CodeBlock will fail that assertion.
+
+        To fix this, we do the following:
+
+        1. We'll eagerly clean up any zombie CodeBlocks due to failed DFG / FTL
+           compilation.  This is achieved by providing a
+           DeferredCompilationCallback::compilationDidComplete() that does this
+           clean up, and have all sub classes call it at the end of their
+           compilationDidComplete() methods.
+
+        2. Before the debugger or profiler iterates CodeBlocks in the heap, they
+           will wait for all compilations to complete before proceeding.  This
+           ensures that:
+           1. any zombie CodeBlocks would have been cleaned up, and won't be
+              seen by the debugger or profiler.
+           2. all CodeBlocks that the debugger and profiler needs to operate on
+              will be "ready" for whatever needs to be done to them e.g.
+              jettison'ing of DFG codeBlocks.
+
+        * bytecode/DeferredCompilationCallback.cpp:
+        (JSC::DeferredCompilationCallback::compilationDidComplete):
+        * bytecode/DeferredCompilationCallback.h:
+        - Provide default implementation method to clean up zombie CodeBlocks.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::forEachCodeBlock):
+        - Utility function to iterate CodeBlocks.  It ensures that all compilations
+          are complete before proceeding.
+        (JSC::Debugger::setSteppingMode):
+        (JSC::Debugger::toggleBreakpoint):
+        (JSC::Debugger::recompileAllJSFunctions):
+        (JSC::Debugger::clearBreakpoints):
+        (JSC::Debugger::clearDebuggerRequests):
+        - Use the utility iterator function.
+
+        * debugger/Debugger.h:
+        * dfg/DFGOperations.cpp:
+        - Added an assert to ensure that zombie CodeBlocks will be imminently cleaned up.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+        - Remove unneeded code (that was not the best solution anyway) for ensuring
+          that we don't generate new DFG codeBlocks after enabling the debugger or
+          profiler.  Now that we wait for compilations to complete before proceeding
+          with debugger and profiler work, this scenario will never happen.
+
+        * dfg/DFGToFTLDeferredCompilationCallback.cpp:
+        (JSC::DFG::ToFTLDeferredCompilationCallback::compilationDidComplete):
+        - Call the super class method to clean up zombie codeBlocks.
+
+        * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp:
+        (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete):
+        - Call the super class method to clean up zombie codeBlocks.
+
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::remove):
+        * heap/CodeBlockSet.h:
+        * heap/Heap.h:
+        (JSC::Heap::removeCodeBlock):
+        - New method to remove a codeBlock from the codeBlock set.
+
+        * jit/JITOperations.cpp:
+        - Added an assert to ensure that zombie CodeBlocks will be imminently cleaned up.
+
+        * jit/JITToDFGDeferredCompilationCallback.cpp:
+        (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete):
+        - Call the super class method to clean up zombie codeBlocks.
+
+        * runtime/VM.cpp:
+        (JSC::VM::waitForCompilationsToComplete):
+        - Renamed from prepareToDiscardCode() to be clearer about what it does.
+
+        (JSC::VM::discardAllCode):
+        (JSC::VM::releaseExecutableMemory):
+        (JSC::VM::setEnabledProfiler):
+        - Wait for compilation to complete before enabling the profiler.
+
+        * runtime/VM.h:
+
+2014-03-03  Brian Burg  <bburg@apple.com>
+
+        Another unreviewed build fix attempt for Windows after r164986.
+
+        We never told Visual Studio to copy over the web replay code generator scripts
+        and the generated headers for JavaScriptCore replay inputs as if they were
+        private headers.
+
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+
+2014-03-03  Brian Burg  <bburg@apple.com>
+
+        Web Replay: upstream input storage, capture/replay machinery, and inspector domain
+        https://bugs.webkit.org/show_bug.cgi?id=128782
+
+        Reviewed by Timothy Hatcher.
+
+        Alter the replay inputs code generator so that it knows when it is necessary to
+        to include headers for HEAVY_SCALAR types such as WTF::String and WebCore::URL.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Framework.fromString):
+        (Frameworks): Add WTF as an allowed framework for code generation.
+        (Generator.generate_includes): Include headers for HEAVY_SCALAR types in the header file.
+        (Generator.generate_includes.declaration):
+        (Generator.generate_includes.or):
+        (Generator.generate_type_forward_declarations): Skip HEAVY_SCALAR types.
+
+2014-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        PolymorphicPutByIdList should have a simpler construction API with basically a single entrypoint
+        https://bugs.webkit.org/show_bug.cgi?id=129591
+
+        Reviewed by Michael Saboff.
+
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PutByIdAccess::fromStructureStubInfo): This function can figure out the slow path target for itself.
+        (JSC::PolymorphicPutByIdList::PolymorphicPutByIdList): This constuctor should be private, only from() should call it.
+        (JSC::PolymorphicPutByIdList::from):
+        * bytecode/PolymorphicPutByIdList.h:
+        (JSC::PutByIdAccess::stubRoutine):
+        * jit/Repatch.cpp:
+        (JSC::tryBuildPutByIdList): Don't pass the slow path target since it can be derived from the stubInfo.
+
+2014-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Debugging improvements from my gbemu investigation session
+        https://bugs.webkit.org/show_bug.cgi?id=129599
+
+        Reviewed by Mark Lam.
+        
+        Various improvements from when I was investigating bug 129411.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::optimizationThresholdScalingFactor): Make the dataLog() statement print the actual multiplier.
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionDescribe): Make describe() return a string rather than printing the string.
+        (functionDescribeArray): Like describe(), but prints details about arrays.
+
+2014-02-25  Andreas Kling  <akling@apple.com>
+
+        JSDOMWindow::commonVM() should return a reference.
+        <https://webkit.org/b/129293>
+
+        Added a DropAllLocks constructor that takes VM& without null checks.
+
+        Reviewed by Geoff Garen.
+
+2014-03-02  Mark Lam  <mark.lam@apple.com>
+
+        CodeBlock::hasDebuggerRequests() should returning a bool instead of an int.
+        <https://webkit.org/b/129584>
+
+        Reviewed by Darin Adler.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::hasDebuggerRequests):
+
+2014-03-02  Mark Lam  <mark.lam@apple.com>
+
+        Clean up use of Options::enableConcurrentJIT().
+        <https://webkit.org/b/129582>
+
+        Reviewed by Filip Pizlo.
+
+        DFG Driver was conditionally checking Options::enableConcurrentJIT()
+        only if ENABLE(CONCURRENT_JIT).  Otherwise, it bypasses it with a local
+        enableConcurrentJIT set to false.
+
+        Instead we should configure Options::enableConcurrentJIT() to be false
+        in Options.cpp if !ENABLE(CONCURRENT_JIT), and DFG Driver should always
+        check Options::enableConcurrentJIT().  This makes the code read a little
+        cleaner.
+
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+
+2014-03-01  Filip Pizlo  <fpizlo@apple.com>
+
+        This shouldn't have been a layout test since it runs only under jsc. Moving it to JSC
+        stress tests.
+
+        * tests/stress/generational-opaque-roots.js: Copied from LayoutTests/js/script-tests/generational-opaque-roots.js.
+
+2014-03-01  Andreas Kling  <akling@apple.com>
+
+        JSCell::fastGetOwnProperty() should get the Structure more efficiently.
+        <https://webkit.org/b/129560>
+
+        Now that structure() is nontrivial and we have a faster structure(VM&),
+        make use of that in fastGetOwnProperty() since we already have VM.
+
+        Reviewed by Sam Weinig.
+
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::fastGetOwnProperty):
+
+2014-03-01  Andreas Kling  <akling@apple.com>
+
+        Avoid going through ExecState for VM when we already have it (in some places.)
+        <https://webkit.org/b/129554>
+
+        Tweak some places that jump through unnecessary hoops to get the VM.
+        There are many more like this.
+
+        Reviewed by Sam Weinig.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putByIndexBeyondVectorLength):
+        (JSC::JSObject::putDirectIndexBeyondVectorLength):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncToString):
+
+2014-02-28  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should support PhantomArguments
+        https://bugs.webkit.org/show_bug.cgi?id=113986
+
+        Reviewed by Oliver Hunt.
+        
+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
+        object into the FTL's OSR exit compiler.
+        
+        This isn't a speed-up yet, since there is still more to be done to fully support
+        all of the arguments craziness that our varargs benchmarks do.
+
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
+        * dfg/DFGOSRExitCompilerCommon.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
+        (JSC::FTL::ExitValue::valueFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
+        * tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js: Added.
+        * tests/stress/trivially-foldable-reflective-arguments-access.js: Added.
+
+2014-02-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, uncomment some code. It wasn't meant to be commented in the first place.
+
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+
+2014-02-28  Andreas Kling  <akling@apple.com>
+
+        JSObject::findPropertyHashEntry() should take VM instead of ExecState.
+        <https://webkit.org/b/129529>
+
+        Callers already have VM in a local, and findPropertyHashEntry() only
+        uses the VM, no need to go all the way through ExecState.
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::findPropertyHashEntry):
+        * runtime/JSObject.h:
+
+2014-02-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Deadlock remotely inspecting iOS Simulator
+        https://bugs.webkit.org/show_bug.cgi?id=129511
+
+        Reviewed by Timothy Hatcher.
+
+        Avoid synchronous setup. Do it asynchronously, and let
+        the RemoteInspector singleton know later if it failed.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::setupFailed):
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+
+2014-02-28  Oliver Hunt  <oliver@apple.com>
+
+        REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
+        https://bugs.webkit.org/show_bug.cgi?id=129488
+
+        Reviewed by Mark Lam.
+
+        Whoops, modify the right register.
+
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileLoadVarargs):
+
+2014-02-28  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should be able to call sin/cos directly on platforms where the intrinsic is busted
+        https://bugs.webkit.org/show_bug.cgi?id=129503
+
+        Reviewed by Mark Lam.
+
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleSin):
+        (JSC::FTL::Output::doubleCos):
+        (JSC::FTL::Output::intrinsicOrOperation):
+
+2014-02-28  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Fix !ENABLE(GGC) builds
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::gatherJSStackRoots): Also fix one of the names of the GC phases.
+
+2014-02-27  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Clean up Heap::collect and Heap::markRoots
+        https://bugs.webkit.org/show_bug.cgi?id=129464
+
+        Reviewed by Geoffrey Garen.
+
+        These functions have built up a lot of cruft recently. 
+        We should do a bit of cleanup to make them easier to grok.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::finalizeUnconditionalFinalizers):
+        (JSC::Heap::gatherStackRoots):
+        (JSC::Heap::gatherJSStackRoots):
+        (JSC::Heap::gatherScratchBufferRoots):
+        (JSC::Heap::clearLivenessData):
+        (JSC::Heap::visitSmallStrings):
+        (JSC::Heap::visitConservativeRoots):
+        (JSC::Heap::visitCompilerWorklists):
+        (JSC::Heap::markProtectedObjects):
+        (JSC::Heap::markTempSortVectors):
+        (JSC::Heap::markArgumentBuffers):
+        (JSC::Heap::visitException):
+        (JSC::Heap::visitStrongHandles):
+        (JSC::Heap::visitHandleStack):
+        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
+        (JSC::Heap::converge):
+        (JSC::Heap::visitWeakHandles):
+        (JSC::Heap::clearRememberedSet):
+        (JSC::Heap::updateObjectCounts):
+        (JSC::Heap::resetVisitors):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::copyBackingStores):
+        (JSC::Heap::deleteUnmarkedCompiledCode):
+        (JSC::Heap::collect):
+        (JSC::Heap::collectIfNecessaryOrDefer):
+        (JSC::Heap::suspendCompilerThreads):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::deleteOldCode):
+        (JSC::Heap::flushOldStructureIDTables):
+        (JSC::Heap::flushWriteBarrierBuffer):
+        (JSC::Heap::stopAllocation):
+        (JSC::Heap::reapWeakHandles):
+        (JSC::Heap::sweepArrayBuffers):
+        (JSC::Heap::snapshotMarkedSpace):
+        (JSC::Heap::deleteSourceProviderCaches):
+        (JSC::Heap::notifyIncrementalSweeper):
+        (JSC::Heap::rememberCurrentlyExecutingCodeBlocks):
+        (JSC::Heap::resetAllocators):
+        (JSC::Heap::updateAllocationLimits):
+        (JSC::Heap::didFinishCollection):
+        (JSC::Heap::resumeCompilerThreads):
+        * heap/Heap.h:
+
+2014-02-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        indexOf and lastIndexOf shouldn't resolve ropes when needle is longer than haystack
+        https://bugs.webkit.org/show_bug.cgi?id=129466
+
+        Reviewed by Michael Saboff.
+
+        Refactored the code to avoid calling JSString::value when needle is longer than haystack.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncIndexOf):
+        (JSC::stringProtoFuncLastIndexOf):
+
+2014-02-27  Timothy Hatcher  <timothy@apple.com>
+
+        Improve how ContentSearchUtilities::lineEndings works by supporting the three common line endings.
+
+        https://bugs.webkit.org/show_bug.cgi?id=129458
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::textPositionFromOffset): Remove assumption about line ending length.
+        (Inspector::ContentSearchUtilities::getRegularExpressionMatchesByLines): Remove assumption about
+        line ending type and don't try to strip the line ending. Use size_t
+        (Inspector::ContentSearchUtilities::lineEndings): Use findNextLineStart to find the lines.
+        This will include the line ending in the lines, but that is okay.
+        (Inspector::ContentSearchUtilities::buildObjectForSearchMatch): Use size_t.
+        (Inspector::ContentSearchUtilities::searchInTextByLines): Modernize.
+
+2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        [Mac] Warning: Multiple build commands for output file GCSegmentedArray and InspectorAgent
+        https://bugs.webkit.org/show_bug.cgi?id=129446
+
+        Reviewed by Timothy Hatcher.
+
+        Remove duplicate header entries in Copy Header build phase.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-02-27  Oliver Hunt  <oliver@apple.com>
+
+        Whoops, include all of last patch.
+
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileLoadVarargs):
+
+2014-02-27  Oliver Hunt  <oliver@apple.com>
+
+        Slow cases for function.apply and function.call should not require vm re-entry
+        https://bugs.webkit.org/show_bug.cgi?id=129454
+
+        Reviewed by Geoffrey Garen.
+
+        Implement call and apply using builtins. Happily the use
+        of @call and @apply don't perform function equality checks
+        and just plant direct var_args calls. This did expose a few
+        codegen issues, but they're all covered by existing tests
+        once call and apply are implemented in JS.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/Function.prototype.js: Added.
+        (call):
+        (apply):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        * interpreter/Interpreter.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileLoadVarargs):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        * parser/Lexer.cpp:
+        (JSC::isSafeBuiltinIdentifier):
+        * runtime/CommonIdentifiers.h:
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::addFunctionProperties):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectBuiltinFunction):
+        (JSC::JSObject::putDirectBuiltinFunctionWithoutTransition):
+        * runtime/JSObject.h:
+
+2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Better name for RemoteInspectorDebuggableConnection dispatch queue
+        https://bugs.webkit.org/show_bug.cgi?id=129443
+
+        Reviewed by Timothy Hatcher.
+
+        This queue is specific to the JSContext debuggable connections,
+        there is no XPC involved. Give it a better name.
+
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::RemoteInspectorDebuggableConnection):
+
+2014-02-27  David Kilzer  <ddkilzer@apple.com>
+
+        Remove jsc symlink if it already exists
+
+        This is a follow-up fix for:
+
+        Create symlink to /usr/local/bin/jsc during installation
+        <http://webkit.org/b/129399>
+        <rdar://problem/16168734>
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        (Create /usr/local/bin/jsc symlink): If a jsc symlink already
+        exists where we're about to create the symlink, remove the old
+        one first.
+
+2014-02-27  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewed build fix for Mac tools after r164814
+
+        * Configurations/ToolExecutable.xcconfig:
+        - Added JavaScriptCore.framework/PrivateHeaders to ToolExecutable include path.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        - Changed productName to testRegExp for testRegExp target.
+
+2014-02-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        When JavaScript API functions have an exception, let the inspector
+        know so it can log the JavaScript and Native backtrace that caused
+        the exception.
+
+        Include some clean up of ConsoleMessage and ScriptCallStack construction.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (reportExceptionToInspector):
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        When seeing an exception, let the inspector know there was an exception.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Log API exceptions by also grabbing the native backtrace.
+
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
+        (Inspector::ScriptCallStack::append):
+        Minor extensions to ScriptCallStack to make it easier to work with.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        Provide better default information if the first call frame was native.
+
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::extractSourceInformationFromException):
+        (Inspector::createScriptCallStackFromException):
+        Perform the handling here of inserting a fake call frame for exceptions
+        if there was no call stack (e.g. a SyntaxError) or if the first call
+        frame had no information.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+        ConsoleMessage cleanup.
+
+2014-02-27  David Kilzer  <ddkilzer@apple.com>
+
+        Create symlink to /usr/local/bin/jsc during installation
+        <http://webkit.org/b/129399>
+        <rdar://problem/16168734>
+
+        Reviewed by Dan Bernstein.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        - Add "Create /usr/local/bin/jsc symlink" build phase script to
+          create the symlink during installation.
+
+2014-02-27  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Math.{max, min}() must not return after first NaN value
+        https://bugs.webkit.org/show_bug.cgi?id=104147
+
+        Reviewed by Oliver Hunt.
+
+        According to the spec, ToNumber going to be called on each argument
+        even if a `NaN` value was already found
+
+        * runtime/MathObject.cpp:
+        (JSC::mathProtoFuncMax):
+        (JSC::mathProtoFuncMin):
+
+2014-02-27  Gergo Balogh  <gbalogh.u-szeged@partner.samsung.com>
+
+        JSType upper limit (0xff) assertion can be removed.
+        https://bugs.webkit.org/show_bug.cgi?id=129424
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::TypeInfo):
+
+2014-02-26  Michael Saboff  <msaboff@apple.com>
+
+        Auto generate bytecode information for bytecode parser and LLInt
+        https://bugs.webkit.org/show_bug.cgi?id=129181
+
+        Reviewed by Mark Lam.
+
+        Added new bytecode/BytecodeList.json that contains a list of bytecodes and related
+        helpers.  It also includes bytecode length and other information used to generate files.
+        Added a new generator, generate-bytecode-files that generates Bytecodes.h and InitBytecodes.asm
+        in DerivedSources/JavaScriptCore/.
+
+        Added the generation of these files to the "DerivedSource" build step.
+        Slighty changed the build order, since the Bytecodes.h file is needed by
+        JSCLLIntOffsetsExtractor.  Moved the offline assembly to a separate step since it needs
+        to be run after JSCLLIntOffsetsExtractor.
+
+        Made related changes to OPCODE macros and their use.
+
+        Added JavaScriptCore.framework/PrivateHeaders to header file search path for building
+        jsc to resolve Mac build issue.
+
+        * CMakeLists.txt:
+        * Configurations/JSC.xcconfig:
+        * DerivedSources.make:
+        * GNUmakefile.am:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/Opcode.h:
+        (JSC::padOpcodeName):
+        * llint/LLIntCLoop.cpp:
+        (JSC::LLInt::CLoop::initialize):
+        * llint/LLIntCLoop.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::initialize):
+        * llint/LLIntOpcode.h:
+        * llint/LowLevelInterpreter.asm:
+
+2014-02-27  Julien Brianceau   <jbriance@cisco.com>
+
+        Fix 32-bit V_JITOperation_EJ callOperation introduced in r162652.
+        https://bugs.webkit.org/show_bug.cgi?id=129420
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation): Payload and tag are swapped.
+        Also, EABI_32BIT_DUMMY_ARG is missing for arm EABI and mips.
+
+2014-02-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Octane/closure thrashes between flattening dictionaries during global object initialization in a global eval
+        https://bugs.webkit.org/show_bug.cgi?id=129435
+
+        Reviewed by Oliver Hunt.
+        
+        This is a 5-10% speed-up on Octane/closure.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionClearCodeCache):
+        * runtime/BatchedTransitionOptimizer.h:
+        (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
+        (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
+
+2014-02-27  Alexey Proskuryakov  <ap@apple.com>
+
+        Added svn:ignore to two directories, so that .pyc files don't show up as unversioned.
+
+        * inspector/scripts: Added property svn:ignore.
+        * replay/scripts: Added property svn:ignore.
+
+2014-02-27  Gabor Rapcsanyi  <rgabor@webkit.org>
+
+        r164764 broke the ARM build
+        https://bugs.webkit.org/show_bug.cgi?id=129415
+
+        Reviewed by Zoltan Herczeg.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::moveWithPatch): Change reinterpret_cast to static_cast.
+        (JSC::MacroAssemblerARM::canJumpReplacePatchableBranch32WithPatch): Add missing function.
+        (JSC::MacroAssemblerARM::startOfPatchableBranch32WithPatchOnAddress): Add missing function.
+        (JSC::MacroAssemblerARM::revertJumpReplacementToPatchableBranch32WithPatch): Add missing function.
+
+2014-02-27  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        r164764 broke the ARM build
+        https://bugs.webkit.org/show_bug.cgi?id=129415
+
+        Reviewed by Geoffrey Garen.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::moveWithPatch):
+
+2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        r164764 broke the ARM build
+        https://bugs.webkit.org/show_bug.cgi?id=129415
+
+        Reviewed by Geoffrey Garen.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::branch32WithPatch): Missing this function.
+
+2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        EFL build fix
+
+        * dfg/DFGSpeculativeJIT32_64.cpp: Remove unused variables.
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+
+2014-02-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Make JSCells have 32-bit Structure pointers
+        https://bugs.webkit.org/show_bug.cgi?id=123195
+
+        Reviewed by Filip Pizlo.
+
+        This patch changes JSCells such that they no longer have a full 64-bit Structure
+        pointer in their header. Instead they now have a 32-bit index into
+        a per-VM table of Structure pointers. 32-bit platforms still use normal Structure
+        pointers.
+
+        This change frees up an additional 32 bits of information in our object headers.
+        We then use this extra space to store the indexing type of the object, the JSType
+        of the object, some various type flags, and garbage collection data (e.g. mark bit).
+        Because this inline type information is now faster to read, it pays for the slowdown 
+        incurred by having to perform an extra indirection through the StructureIDTable.
+
+        This patch also threads a reference to the current VM through more of the C++ runtime
+        to offset the cost of having to look up the VM to get the actual Structure pointer.
+
+        * API/JSContext.mm:
+        (-[JSContext setException:]):
+        (-[JSContext wrapperForObjCObject:]):
+        (-[JSContext wrapperForJSObject:]):
+        * API/JSContextRef.cpp:
+        (JSContextGroupRelease):
+        (JSGlobalContextRelease):
+        * API/JSObjectRef.cpp:
+        (JSObjectIsFunction):
+        (JSObjectCopyPropertyNames):
+        * API/JSValue.mm:
+        (containerValueToObject):
+        * API/JSWrapperMap.mm:
+        (tryUnwrapObjcObject):
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/AbstractMacroAssembler.h:
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::patchableBranch32WithPatch):
+        (JSC::MacroAssembler::patchableBranch32):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branchPtrWithPatch):
+        (JSC::MacroAssemblerARM64::patchableBranch32WithPatch):
+        (JSC::MacroAssemblerARM64::canJumpReplacePatchableBranch32WithPatch):
+        (JSC::MacroAssemblerARM64::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::MacroAssemblerARM64::revertJumpReplacementToPatchableBranch32WithPatch):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::store8):
+        (JSC::MacroAssemblerARMv7::branch32WithPatch):
+        (JSC::MacroAssemblerARMv7::patchableBranch32WithPatch):
+        (JSC::MacroAssemblerARMv7::canJumpReplacePatchableBranch32WithPatch):
+        (JSC::MacroAssemblerARMv7::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranch32WithPatch):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::branch32WithPatch):
+        (JSC::MacroAssemblerX86::canJumpReplacePatchableBranch32WithPatch):
+        (JSC::MacroAssemblerX86::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::MacroAssemblerX86::revertJumpReplacementToPatchableBranch32WithPatch):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::store32):
+        (JSC::MacroAssemblerX86_64::moveWithPatch):
+        (JSC::MacroAssemblerX86_64::branch32WithPatch):
+        (JSC::MacroAssemblerX86_64::canJumpReplacePatchableBranch32WithPatch):
+        (JSC::MacroAssemblerX86_64::startOfBranch32WithPatchOnRegister):
+        (JSC::MacroAssemblerX86_64::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::MacroAssemblerX86_64::revertJumpReplacementToPatchableBranch32WithPatch):
+        * assembler/RepatchBuffer.h:
+        (JSC::RepatchBuffer::startOfPatchableBranch32WithPatchOnAddress):
+        (JSC::RepatchBuffer::revertJumpReplacementToPatchableBranch32WithPatch):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::revertJumpTo_movq_i64r):
+        (JSC::X86Assembler::revertJumpTo_movl_i32r):
+        * bytecode/ArrayProfile.cpp:
+        (JSC::ArrayProfile::computeUpdatedPrediction):
+        * bytecode/ArrayProfile.h:
+        (JSC::ArrayProfile::ArrayProfile):
+        (JSC::ArrayProfile::addressOfLastSeenStructureID):
+        (JSC::ArrayProfile::observeStructure):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::heap):
+        * bytecode/UnlinkedCodeBlock.h:
+        * debugger/Debugger.h:
+        * dfg/DFGAbstractHeap.h:
+        * dfg/DFGArrayifySlowPathGenerator.h:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::branchWeakStructure):
+        (JSC::DFG::JITCompiler::branchStructurePtr):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::osrWriteBarrier):
+        (JSC::DFG::adjustAndJumpToTarget):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::putByVal):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::checkArray):
+        (JSC::DFG::SpeculativeJIT::arrayify):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+        (JSC::DFG::SpeculativeJIT::speculateObject):
+        (JSC::DFG::SpeculativeJIT::speculateFinalObject):
+        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+        (JSC::DFG::SpeculativeJIT::speculateString):
+        (JSC::DFG::SpeculativeJIT::speculateStringObject):
+        (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        (JSC::DFG::SpeculativeJIT::genericWriteBarrier):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
+        (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGWorklist.cpp:
+        * ftl/FTLAbstractHeapRepository.cpp:
+        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileToString):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
+        (JSC::FTL::LowerDFGToLLVM::allocateCell):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isObject):
+        (JSC::FTL::LowerDFGToLLVM::isString):
+        (JSC::FTL::LowerDFGToLLVM::isArrayType):
+        (JSC::FTL::LowerDFGToLLVM::hasClassInfo):
+        (JSC::FTL::LowerDFGToLLVM::isType):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringOrStringObject):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForCell):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+        (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
+        (JSC::FTL::LowerDFGToLLVM::loadMarkByte):
+        (JSC::FTL::LowerDFGToLLVM::loadStructure):
+        (JSC::FTL::LowerDFGToLLVM::weakStructure):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::store8):
+        * heap/GCAssertions.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::getConservativeRegisterRoots):
+        (JSC::Heap::collect):
+        (JSC::Heap::writeBarrier):
+        * heap/Heap.h:
+        (JSC::Heap::structureIDTable):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::forEachBlock):
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::internalAppend):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfCellNotObject):
+        (JSC::AssemblyHelpers::genericWriteBarrier):
+        (JSC::AssemblyHelpers::emitLoadStructure):
+        (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emit_op_ret_object_or_this):
+        (JSC::JIT::compileOpCall):
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITByIdGenerator::generateFastPathChecks):
+        * jit/JITInlineCacheGenerator.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::emitLoadCharacterString):
+        (JSC::JIT::checkStructure):
+        (JSC::JIT::emitJumpIfCellNotObject):
+        (JSC::JIT::emitAllocateJSObject):
+        (JSC::JIT::emitArrayProfilingSiteWithCell):
+        (JSC::JIT::emitArrayProfilingSiteForBytecodeIndexWithCell):
+        (JSC::JIT::branchStructure):
+        (JSC::branchStructure):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_check_has_instance):
+        (JSC::JIT::emit_op_instanceof):
+        (JSC::JIT::emit_op_is_undefined):
+        (JSC::JIT::emit_op_is_string):
+        (JSC::JIT::emit_op_ret_object_or_this):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::emit_op_jeq_null):
+        (JSC::JIT::emit_op_jneq_null):
+        (JSC::JIT::emit_op_get_pnames):
+        (JSC::JIT::emit_op_next_pname):
+        (JSC::JIT::emit_op_eq_null):
+        (JSC::JIT::emit_op_neq_null):
+        (JSC::JIT::emit_op_to_this):
+        (JSC::JIT::emitSlow_op_to_this):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_check_has_instance):
+        (JSC::JIT::emit_op_instanceof):
+        (JSC::JIT::emit_op_is_undefined):
+        (JSC::JIT::emit_op_is_string):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::emit_op_jeq_null):
+        (JSC::JIT::emit_op_jneq_null):
+        (JSC::JIT::emitSlow_op_eq):
+        (JSC::JIT::emitSlow_op_neq):
+        (JSC::JIT::compileOpStrictEq):
+        (JSC::JIT::emit_op_eq_null):
+        (JSC::JIT::emit_op_neq_null):
+        (JSC::JIT::emit_op_get_pnames):
+        (JSC::JIT::emit_op_next_pname):
+        (JSC::JIT::emit_op_to_this):
+        * jit/JITOperations.cpp:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::stringGetByValStubGenerator):
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emit_op_get_by_pname):
+        (JSC::JIT::emit_op_put_by_val):
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emitLoadWithStructureCheck):
+        (JSC::JIT::emitSlow_op_get_from_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        (JSC::JIT::checkMarkWord):
+        (JSC::JIT::emitWriteBarrier):
+        (JSC::JIT::addStructureTransitionCheck):
+        (JSC::JIT::emitIntTypedArrayGetByVal):
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        (JSC::JIT::emitIntTypedArrayPutByVal):
+        (JSC::JIT::emitFloatTypedArrayPutByVal):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::stringGetByValStubGenerator):
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emit_op_put_by_val):
+        (JSC::JIT::emit_op_get_by_id):
+        (JSC::JIT::emit_op_get_by_pname):
+        (JSC::JIT::emitLoadWithStructureCheck):
+        * jit/JSInterfaceJIT.h:
+        (JSC::JSInterfaceJIT::emitJumpIfNotType):
+        * jit/Repatch.cpp:
+        (JSC::repatchByIdSelfAccess):
+        (JSC::addStructureTransitionCheck):
+        (JSC::replaceWithJump):
+        (JSC::generateProtoChainAccessStub):
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::writeBarrier):
+        (JSC::emitPutReplaceStub):
+        (JSC::emitPutTransitionStub):
+        (JSC::tryBuildPutByIdList):
+        (JSC::tryRepatchIn):
+        (JSC::linkClosureCall):
+        (JSC::resetGetByID):
+        (JSC::resetPutByID):
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::loadJSStringArgument):
+        (JSC::SpecializedThunkJIT::loadArgumentWithSpecificClass):
+        * jit/ThunkGenerators.cpp:
+        (JSC::virtualForThunkGenerator):
+        (JSC::arrayIteratorNextThunkGenerator):
+        * jit/UnusedPointer.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::createStrictModeCallerIfNecessary):
+        (JSC::Arguments::createStrictModeCalleeIfNecessary):
+        * runtime/Arguments.h:
+        (JSC::Arguments::createStructure):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::shift):
+        (JSC::unshift):
+        (JSC::arrayProtoFuncToString):
+        (JSC::arrayProtoFuncPop):
+        (JSC::arrayProtoFuncReverse):
+        (JSC::performSlowSort):
+        (JSC::arrayProtoFuncSort):
+        (JSC::arrayProtoFuncSplice):
+        (JSC::arrayProtoFuncUnShift):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/Executable.h:
+        (JSC::ExecutableBase::isFunctionExecutable):
+        (JSC::ExecutableBase::clearCodeVirtual):
+        (JSC::ScriptExecutable::unlinkCalls):
+        * runtime/GetterSetter.cpp:
+        (JSC::callGetter):
+        (JSC::callSetter):
+        * runtime/InitializeThreading.cpp:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::unshiftCountSlowCase):
+        (JSC::JSArray::setLength):
+        (JSC::JSArray::pop):
+        (JSC::JSArray::push):
+        (JSC::JSArray::shiftCountWithArrayStorage):
+        (JSC::JSArray::shiftCountWithAnyIndexingType):
+        (JSC::JSArray::unshiftCountWithArrayStorage):
+        (JSC::JSArray::unshiftCountWithAnyIndexingType):
+        (JSC::JSArray::sortNumericVector):
+        (JSC::JSArray::sortNumeric):
+        (JSC::JSArray::sortCompactedVector):
+        (JSC::JSArray::sort):
+        (JSC::JSArray::sortVector):
+        (JSC::JSArray::fillArgList):
+        (JSC::JSArray::copyToArguments):
+        (JSC::JSArray::compactForSorting):
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::toThis):
+        (JSC::JSValue::put):
+        (JSC::JSValue::putByIndex):
+        (JSC::JSValue::equalSlowCaseInline):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::put):
+        (JSC::JSCell::putByIndex):
+        (JSC::JSCell::deleteProperty):
+        (JSC::JSCell::deletePropertyByIndex):
+        * runtime/JSCell.h:
+        (JSC::JSCell::clearStructure):
+        (JSC::JSCell::mark):
+        (JSC::JSCell::isMarked):
+        (JSC::JSCell::structureIDOffset):
+        (JSC::JSCell::typeInfoFlagsOffset):
+        (JSC::JSCell::typeInfoTypeOffset):
+        (JSC::JSCell::indexingTypeOffset):
+        (JSC::JSCell::gcDataOffset):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::JSCell):
+        (JSC::JSCell::finishCreation):
+        (JSC::JSCell::type):
+        (JSC::JSCell::indexingType):
+        (JSC::JSCell::structure):
+        (JSC::JSCell::visitChildren):
+        (JSC::JSCell::isObject):
+        (JSC::JSCell::isString):
+        (JSC::JSCell::isGetterSetter):
+        (JSC::JSCell::isProxy):
+        (JSC::JSCell::isAPIValueWrapper):
+        (JSC::JSCell::setStructure):
+        (JSC::JSCell::methodTable):
+        (JSC::Heap::writeBarrier):
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::createStructure):
+        * runtime/JSDestructibleObject.h:
+        (JSC::JSCell::classInfo):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getOwnNonIndexPropertyNames):
+        (JSC::JSFunction::put):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGenericTypedArrayView.h:
+        (JSC::JSGenericTypedArrayView::createStructure):
+        * runtime/JSObject.cpp:
+        (JSC::getCallableObjectSlow):
+        (JSC::JSObject::copyButterfly):
+        (JSC::JSObject::visitButterfly):
+        (JSC::JSFinalObject::visitChildren):
+        (JSC::JSObject::getOwnPropertySlotByIndex):
+        (JSC::JSObject::put):
+        (JSC::JSObject::putByIndex):
+        (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+        (JSC::JSObject::enterDictionaryIndexingMode):
+        (JSC::JSObject::notifyPresenceOfIndexedAccessors):
+        (JSC::JSObject::createInitialIndexedStorage):
+        (JSC::JSObject::createInitialUndecided):
+        (JSC::JSObject::createInitialInt32):
+        (JSC::JSObject::createInitialDouble):
+        (JSC::JSObject::createInitialContiguous):
+        (JSC::JSObject::createArrayStorage):
+        (JSC::JSObject::convertUndecidedToInt32):
+        (JSC::JSObject::convertUndecidedToDouble):
+        (JSC::JSObject::convertUndecidedToContiguous):
+        (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
+        (JSC::JSObject::convertUndecidedToArrayStorage):
+        (JSC::JSObject::convertInt32ToDouble):
+        (JSC::JSObject::convertInt32ToContiguous):
+        (JSC::JSObject::convertInt32ToArrayStorage):
+        (JSC::JSObject::genericConvertDoubleToContiguous):
+        (JSC::JSObject::convertDoubleToArrayStorage):
+        (JSC::JSObject::convertContiguousToArrayStorage):
+        (JSC::JSObject::ensureInt32Slow):
+        (JSC::JSObject::ensureDoubleSlow):
+        (JSC::JSObject::ensureContiguousSlow):
+        (JSC::JSObject::ensureArrayStorageSlow):
+        (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
+        (JSC::JSObject::switchToSlowPutArrayStorage):
+        (JSC::JSObject::setPrototype):
+        (JSC::JSObject::setPrototypeWithCycleCheck):
+        (JSC::JSObject::putDirectNonIndexAccessor):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::hasOwnProperty):
+        (JSC::JSObject::deletePropertyByIndex):
+        (JSC::JSObject::getPrimitiveNumber):
+        (JSC::JSObject::hasInstance):
+        (JSC::JSObject::getPropertySpecificValue):
+        (JSC::JSObject::getPropertyNames):
+        (JSC::JSObject::getOwnPropertyNames):
+        (JSC::JSObject::getOwnNonIndexPropertyNames):
+        (JSC::JSObject::seal):
+        (JSC::JSObject::freeze):
+        (JSC::JSObject::preventExtensions):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        (JSC::JSObject::removeDirect):
+        (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+        (JSC::JSObject::putByIndexBeyondVectorLength):
+        (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
+        (JSC::JSObject::putDirectIndexBeyondVectorLength):
+        (JSC::JSObject::getNewVectorLength):
+        (JSC::JSObject::countElements):
+        (JSC::JSObject::increaseVectorLength):
+        (JSC::JSObject::ensureLengthSlow):
+        (JSC::JSObject::growOutOfLineStorage):
+        (JSC::JSObject::getOwnPropertyDescriptor):
+        (JSC::putDescriptor):
+        (JSC::JSObject::defineOwnNonIndexProperty):
+        * runtime/JSObject.h:
+        (JSC::getJSFunction):
+        (JSC::JSObject::getArrayLength):
+        (JSC::JSObject::getVectorLength):
+        (JSC::JSObject::putByIndexInline):
+        (JSC::JSObject::canGetIndexQuickly):
+        (JSC::JSObject::getIndexQuickly):
+        (JSC::JSObject::tryGetIndexQuickly):
+        (JSC::JSObject::getDirectIndex):
+        (JSC::JSObject::canSetIndexQuickly):
+        (JSC::JSObject::canSetIndexQuicklyForPutDirect):
+        (JSC::JSObject::setIndexQuickly):
+        (JSC::JSObject::initializeIndex):
+        (JSC::JSObject::hasSparseMap):
+        (JSC::JSObject::inSparseIndexingMode):
+        (JSC::JSObject::getDirect):
+        (JSC::JSObject::getDirectOffset):
+        (JSC::JSObject::isSealed):
+        (JSC::JSObject::isFrozen):
+        (JSC::JSObject::flattenDictionaryObject):
+        (JSC::JSObject::ensureInt32):
+        (JSC::JSObject::ensureDouble):
+        (JSC::JSObject::ensureContiguous):
+        (JSC::JSObject::rageEnsureContiguous):
+        (JSC::JSObject::ensureArrayStorage):
+        (JSC::JSObject::arrayStorage):
+        (JSC::JSObject::arrayStorageOrNull):
+        (JSC::JSObject::ensureLength):
+        (JSC::JSObject::currentIndexingData):
+        (JSC::JSObject::getHolyIndexQuickly):
+        (JSC::JSObject::currentRelevantLength):
+        (JSC::JSObject::isGlobalObject):
+        (JSC::JSObject::isVariableObject):
+        (JSC::JSObject::isStaticScopeObject):
+        (JSC::JSObject::isNameScopeObject):
+        (JSC::JSObject::isActivationObject):
+        (JSC::JSObject::isErrorInstance):
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+        (JSC::JSObject::fastGetOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+        (JSC::JSObject::putDirectInternal):
+        (JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
+        * runtime/JSPropertyNameIterator.h:
+        (JSC::JSPropertyNameIterator::createStructure):
+        * runtime/JSProxy.cpp:
+        (JSC::JSProxy::getOwnPropertySlot):
+        (JSC::JSProxy::getOwnPropertySlotByIndex):
+        (JSC::JSProxy::put):
+        (JSC::JSProxy::putByIndex):
+        (JSC::JSProxy::defineOwnProperty):
+        (JSC::JSProxy::deleteProperty):
+        (JSC::JSProxy::deletePropertyByIndex):
+        (JSC::JSProxy::getPropertyNames):
+        (JSC::JSProxy::getOwnPropertyNames):
+        * runtime/JSScope.cpp:
+        (JSC::JSScope::objectAtScope):
+        * runtime/JSString.h:
+        (JSC::JSString::createStructure):
+        (JSC::isJSString):
+        * runtime/JSType.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::TypeInfo):
+        (JSC::TypeInfo::isObject):
+        (JSC::TypeInfo::structureIsImmortal):
+        (JSC::TypeInfo::zeroedGCDataOffset):
+        (JSC::TypeInfo::inlineTypeFlags):
+        * runtime/MapData.h:
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyNames):
+        (JSC::objectConstructorKeys):
+        (JSC::objectConstructorDefineProperty):
+        (JSC::defineProperties):
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        (JSC::objectConstructorIsSealed):
+        (JSC::objectConstructorIsFrozen):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncToString):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        (JSC::jsIsObjectType):
+        * runtime/Operations.h:
+        (JSC::normalizePrototypeChainForChainAccess):
+        (JSC::normalizePrototypeChain):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::createStructure):
+        * runtime/RegExp.h:
+        (JSC::RegExp::createStructure):
+        * runtime/SparseArrayValueMap.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::~Structure):
+        (JSC::Structure::prototypeChainMayInterceptStoreTo):
+        * runtime/Structure.h:
+        (JSC::Structure::id):
+        (JSC::Structure::idBlob):
+        (JSC::Structure::objectInitializationFields):
+        (JSC::Structure::structureIDOffset):
+        * runtime/StructureChain.h:
+        (JSC::StructureChain::createStructure):
+        * runtime/StructureIDTable.cpp: Added.
+        (JSC::StructureIDTable::StructureIDTable):
+        (JSC::StructureIDTable::~StructureIDTable):
+        (JSC::StructureIDTable::resize):
+        (JSC::StructureIDTable::flushOldTables):
+        (JSC::StructureIDTable::allocateID):
+        (JSC::StructureIDTable::deallocateID):
+        * runtime/StructureIDTable.h: Added.
+        (JSC::StructureIDTable::base):
+        (JSC::StructureIDTable::get):
+        * runtime/SymbolTable.h:
+        * runtime/TypedArrayType.cpp:
+        (JSC::typeForTypedArrayType):
+        * runtime/TypedArrayType.h:
+        * runtime/WeakMapData.h:
+
+2014-02-26  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Unconditional logging in compileFTLOSRExit
+        https://bugs.webkit.org/show_bug.cgi?id=129407
+
+        Reviewed by Michael Saboff.
+
+        This was causing tests to fail with the FTL enabled.
+
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileFTLOSRExit):
+
+2014-02-26  Oliver Hunt  <oliver@apple.com>
+
+        Remove unused access types
+        https://bugs.webkit.org/show_bug.cgi?id=129385
+
+        Reviewed by Filip Pizlo.
+
+        Remove unused cruft.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        * bytecode/StructureStubInfo.h:
+        (JSC::isGetByIdAccess):
+        (JSC::isPutByIdAccess):
+
+2014-02-26  Oliver Hunt  <oliver@apple.com>
+
+        Function.prototype.apply has a bad time with the spread operator
+        https://bugs.webkit.org/show_bug.cgi?id=129381
+
+        Reviewed by Mark Hahnenberg.
+
+        Make sure our apply logic handle the spread operator correctly.
+        To do this we simply emit the enumeration logic that we'd normally
+        use for other enumerations, but only store the first two results
+        to registers.  Then perform a varargs call.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+
+2014-02-26  Mark Lam  <mark.lam@apple.com>
+
+        Compilation policy management belongs in operationOptimize(), not the DFG Driver.
+        <https://webkit.org/b/129355>
+
+        Reviewed by Filip Pizlo.
+
+        By compilation policy, I mean the rules for determining whether to
+        compile, when to compile, when to attempt compilation again, etc.  The
+        few of these policy decisions that were previously being made in the
+        DFG driver are now moved to operationOptimize() where we keep the rest
+        of the policy logic.  Decisions that are based on the capabilities
+        supported by the DFG are moved to DFG capabiliityLevel().
+
+        I've run the following benchmarks:
+        1. the collection of jsc benchmarks on the jsc executable vs. its
+           baseline.
+        2. Octane 2.0 in browser without the WebInspector.
+        3. Octane 2.0 in browser with the WebInspector open and a breakpoint
+           set somewhere where it won't break.
+
+        In all of these, the results came out to be a wash as expected.
+
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupported):
+        (JSC::DFG::mightCompileEval):
+        (JSC::DFG::mightCompileProgram):
+        (JSC::DFG::mightCompileFunctionForCall):
+        (JSC::DFG::mightCompileFunctionForConstruct):
+        (JSC::DFG::mightInlineFunctionForCall):
+        (JSC::DFG::mightInlineFunctionForClosureCall):
+        (JSC::DFG::mightInlineFunctionForConstruct):
+        * dfg/DFGCapabilities.h:
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * jit/JITOperations.cpp:
+
+2014-02-26  Mark Lam  <mark.lam@apple.com>
+
+        ASSERTION FAILED: m_heap->vm()->currentThreadIsHoldingAPILock() in inspector-protocol/*.
+        <https://webkit.org/b/129364>
+
+        Reviewed by Alexey Proskuryakov.
+
+        InjectedScriptModule::ensureInjected() needs an APIEntryShim.
+
+        * inspector/InjectedScriptModule.cpp:
+        (Inspector::InjectedScriptModule::ensureInjected):
+        - Added the needed but missing APIEntryShim. 
+
+2014-02-25  Mark Lam  <mark.lam@apple.com>
+
+        Web Inspector: CRASH when evaluating in console of JSContext RWI with disabled breakpoints.
+        <https://webkit.org/b/128766>
+
+        Reviewed by Geoffrey Garen.
+
+        Make the JSLock::grabAllLocks() work the same way as for the C loop LLINT.
+        The reasoning is that we don't know of any clients that need unordered
+        re-entry into the VM from different threads. So, we're enforcing ordered
+        re-entry i.e. we must re-grab locks in the reverse order of dropping locks.
+
+        The crash in this bug happened because we were allowing unordered re-entry,
+        and the following type of scenario occurred:
+
+        1. Thread T1 locks the VM, and enters the VM to execute some JS code.
+        2. On entry, T1 detects that VM::m_entryScope is null i.e. this is the
+           first time it entered the VM.
+           T1 sets VM::m_entryScope to T1's entryScope.
+        3. T1 drops all locks.
+
+        4. Thread T2 locks the VM, and enters the VM to execute some JS code.
+           On entry, T2 sees that VM::m_entryScope is NOT null, and therefore
+           does not set the entryScope.
+        5. T2 drops all locks.
+
+        6. T1 re-grabs locks.
+        7. T1 returns all the way out of JS code. On exit from the outer most
+           JS function, T1 clears VM::m_entryScope (because T1 was the one who
+           set it).
+        8. T1 unlocks the VM.
+
+        9. T2 re-grabs locks.
+        10. T2 proceeds to execute some code and expects VM::m_entryScope to be
+            NOT null, but it turns out to be null. Assertion failures and
+            crashes ensue.
+
+        With ordered re-entry, at step 6, T1 will loop and yield until T2 exits
+        the VM. Hence, the issue will no longer manifest.
+
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::dropAllLocks):
+        (JSC::JSLock::grabAllLocks):
+        * runtime/JSLock.h:
+        (JSC::JSLock::DropAllLocks::dropDepth):
+
+2014-02-25  Mark Lam  <mark.lam@apple.com>
+
+        Need to initialize VM stack data even when the VM is on an exclusive thread.
+        <https://webkit.org/b/129265>
+
+        Not reviewed.
+
+        Relanding r164627 now that <https://webkit.org/b/129341> is fixed.
+
+        * API/APIShims.h:
+        (JSC::APIEntryShim::APIEntryShim):
+        (JSC::APICallbackShim::shouldDropAllLocks):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::addCurrentThread):
+        * runtime/JSLock.cpp:
+        (JSC::JSLockHolder::JSLockHolder):
+        (JSC::JSLockHolder::init):
+        (JSC::JSLockHolder::~JSLockHolder):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::setExclusiveThread):
+        (JSC::JSLock::lock):
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::currentThreadIsHoldingLock):
+        (JSC::JSLock::dropAllLocks):
+        (JSC::JSLock::grabAllLocks):
+        * runtime/JSLock.h:
+        (JSC::JSLock::hasExclusiveThread):
+        (JSC::JSLock::exclusiveThread):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::hasExclusiveThread):
+        (JSC::VM::exclusiveThread):
+        (JSC::VM::setExclusiveThread):
+        (JSC::VM::currentThreadIsHoldingAPILock):
+
+2014-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Inline caching in the FTL on ARM64 should "work"
+        https://bugs.webkit.org/show_bug.cgi?id=129334
+
+        Reviewed by Mark Hahnenberg.
+        
+        Gets us to the point where simple tests that use inline caching are passing.
+
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::copyCompactAndLinkCode):
+        (JSC::LinkBuffer::shrink):
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfGetById):
+        (JSC::FTL::sizeOfPutById):
+        (JSC::FTL::sizeOfCall):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileFTLOSRExit):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::osrExitGenerationThunkGenerator):
+        * jit/GPRInfo.h:
+        * offlineasm/arm64.rb:
+
+2014-02-25  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r164627.
+        http://trac.webkit.org/changeset/164627
+        https://bugs.webkit.org/show_bug.cgi?id=129325
+
+        Broke SubtleCrypto tests (Requested by ap on #webkit).
+
+        * API/APIShims.h:
+        (JSC::APIEntryShim::APIEntryShim):
+        (JSC::APICallbackShim::shouldDropAllLocks):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::addCurrentThread):
+        * runtime/JSLock.cpp:
+        (JSC::JSLockHolder::JSLockHolder):
+        (JSC::JSLockHolder::init):
+        (JSC::JSLockHolder::~JSLockHolder):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::lock):
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::currentThreadIsHoldingLock):
+        (JSC::JSLock::dropAllLocks):
+        (JSC::JSLock::grabAllLocks):
+        * runtime/JSLock.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::currentThreadIsHoldingAPILock):
+
+2014-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        ARM64 rshift64 should be an arithmetic shift
+        https://bugs.webkit.org/show_bug.cgi?id=129323
+
+        Reviewed by Mark Hahnenberg.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::rshift64):
+
+2014-02-25  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Add ENABLE flag
+        https://bugs.webkit.org/show_bug.cgi?id=129153
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig: added ENABLE_CSS_GRID_LAYOUT feature flag.
+
+2014-02-25  Michael Saboff  <msaboff@apple.com>
+
+        JIT Engines use the wrong stack limit for stack checks
+        https://bugs.webkit.org/show_bug.cgi?id=129314
+
+        Reviewed by Filip Pizlo.
+
+        Change the Baseline and DFG code to use VM::m_stackLimit for stack limit checks.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileFunction):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileLoadVarargs):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileLoadVarargs):
+        * runtime/VM.h:
+        (JSC::VM::addressOfStackLimit):
+
+2014-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out http://trac.webkit.org/changeset/164493.
+        
+        It causes crashes, apparently because it's removing too many barriers. I will investigate
+        later.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertStoreBarrier):
+        * dfg/DFGNode.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isNotNully):
+        (JSC::FTL::LowerDFGToLLVM::isNully):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
+
+2014-02-24  Oliver Hunt  <oliver@apple.com>
+
+        Fix build.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2014-02-24  Oliver Hunt  <oliver@apple.com>
+
+        Spread operator has a bad time when applied to call function
+        https://bugs.webkit.org/show_bug.cgi?id=128853
+
+        Reviewed by Geoffrey Garen.
+
+        Follow on from the previous patch the added an extra slot to
+        op_call_varargs (and _call, _call_eval, _construct).  We now
+        use the slot as an offset to in effect act as a 'slice' on
+        the spread subject.  This allows us to automatically retain
+        all our existing argument and array optimisatons.  Most of
+        this patch is simply threading the offset around.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitCallVarargs):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::getArgumentByVal):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        * interpreter/Interpreter.h:
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileLoadVarargs):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyToArguments):
+        * runtime/Arguments.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::copyToArguments):
+        * runtime/JSArray.h:
+
+2014-02-24  Mark Lam  <mark.lam@apple.com>
+
+        Need to initialize VM stack data even when the VM is on an exclusive thread.
+        <https://webkit.org/b/129265>
+
+        Reviewed by Geoffrey Garen.
+
+        We check VM::exclusiveThread as an optimization to forego the need to do
+        JSLock locking. However, we recently started piggy backing on JSLock's
+        lock() and unlock() to initialize VM stack data (stackPointerAtVMEntry
+        and lastStackTop) to appropriate values for the current thread. This is
+        needed because we may be acquiring the lock to enter the VM on a different
+        thread.
+
+        As a result, we ended up not initializing the VM stack data when
+        VM::exclusiveThread causes us to bypass the locking activity. Even though
+        the VM::exclusiveThread will not have to deal with the VM being entered
+        on a different thread, it still needs to initialize the VM stack data.
+        The VM relies on that data being initialized properly once it has been
+        entered.
+
+        With this fix, we push the check for exclusiveThread down into the JSLock,
+        and handle the bypassing of unneeded locking activity there while still
+        executing the necessary the VM stack data initialization.
+
+        * API/APIShims.h:
+        (JSC::APIEntryShim::APIEntryShim):
+        (JSC::APICallbackShim::shouldDropAllLocks):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::addCurrentThread):
+        * runtime/JSLock.cpp:
+        (JSC::JSLockHolder::JSLockHolder):
+        (JSC::JSLockHolder::init):
+        (JSC::JSLockHolder::~JSLockHolder):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::setExclusiveThread):
+        (JSC::JSLock::lock):
+        (JSLock::unlock):
+        (JSLock::currentThreadIsHoldingLock):
+        (JSLock::dropAllLocks):
+        (JSLock::grabAllLocks):
+        * runtime/JSLock.h:
+        (JSC::JSLock::exclusiveThread):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::exclusiveThread):
+        (JSC::VM::setExclusiveThread):
+        (JSC::VM::currentThreadIsHoldingAPILock):
+
+2014-02-24  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should do polymorphic PutById inlining
+        https://bugs.webkit.org/show_bug.cgi?id=129210
+
+        Reviewed by Mark Hahnenberg and Oliver Hunt.
+        
+        This makes PutByIdStatus inform us about polymorphic cases by returning an array of
+        PutByIdVariants. The DFG now has a node called MultiPutByOffset that indicates a
+        selection of multiple inlined PutByIdVariants.
+        
+        MultiPutByOffset is almost identical to MultiGetByOffset, which we added in
+        http://trac.webkit.org/changeset/164207.
+        
+        This also does some FTL refactoring to make MultiPutByOffset share code with some nodes
+        that generate similar code.
+        
+        1% speed-up on V8v7 due to splay improving by 6.8%. Splay does the thing where it
+        sometimes swaps field insertion order, creating fake polymorphism.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        (JSC::PutByIdStatus::dump):
+        * bytecode/PutByIdStatus.h:
+        (JSC::PutByIdStatus::PutByIdStatus):
+        (JSC::PutByIdStatus::isSimple):
+        (JSC::PutByIdStatus::numVariants):
+        (JSC::PutByIdStatus::variants):
+        (JSC::PutByIdStatus::at):
+        (JSC::PutByIdStatus::operator[]):
+        * bytecode/PutByIdVariant.cpp: Added.
+        (JSC::PutByIdVariant::dump):
+        (JSC::PutByIdVariant::dumpInContext):
+        * bytecode/PutByIdVariant.h: Added.
+        (JSC::PutByIdVariant::PutByIdVariant):
+        (JSC::PutByIdVariant::replace):
+        (JSC::PutByIdVariant::transition):
+        (JSC::PutByIdVariant::kind):
+        (JSC::PutByIdVariant::isSet):
+        (JSC::PutByIdVariant::operator!):
+        (JSC::PutByIdVariant::structure):
+        (JSC::PutByIdVariant::oldStructure):
+        (JSC::PutByIdVariant::newStructure):
+        (JSC::PutByIdVariant::structureChain):
+        (JSC::PutByIdVariant::offset):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::emitPrototypeChecks):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::emitPutById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::checkStructureElimination):
+        (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+        (JSC::DFG::CSEPhase::putStructureStoreElimination):
+        (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+        (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::MultiPutByOffsetData::writesStructures):
+        (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPutByOffset):
+        (JSC::DFG::Node::hasMultiPutByOffsetData):
+        (JSC::DFG::Node::multiPutByOffsetData):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileAllocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::compileReallocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+        (JSC::FTL::LowerDFGToLLVM::loadProperty):
+        (JSC::FTL::LowerDFGToLLVM::storeProperty):
+        (JSC::FTL::LowerDFGToLLVM::addressOfProperty):
+        (JSC::FTL::LowerDFGToLLVM::storageForTransition):
+        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::reallocatePropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        * tests/stress/fold-multi-put-by-offset-to-put-by-offset.js: Added.
+        * tests/stress/multi-put-by-offset-reallocation-butterfly-cse.js: Added.
+        * tests/stress/multi-put-by-offset-reallocation-cases.js: Added.
+
+2014-02-24  peavo@outlook.com  <peavo@outlook.com>
+
+        JSC regressions after r164494
+        https://bugs.webkit.org/show_bug.cgi?id=129272
+
+        Reviewed by Mark Lam.
+
+        * offlineasm/x86.rb: Only avoid reverse opcode (fdivr) for Windows.
+
+2014-02-24  Tamas Gergely  <tgergely.u-szeged@partner.samsung.com>
+
+        Code cleanup: remove leftover ENABLE(WORKERS) macros and support.
+        https://bugs.webkit.org/show_bug.cgi?id=129255
+
+        Reviewed by Csaba Osztrogonác.
+
+        ENABLE_WORKERS macro was removed in r159679.
+        Support is now also removed from xcconfig files.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-02-24  David Kilzer  <ddkilzer@apple.com>
+
+        Remove redundant setting in FeatureDefines.xcconfig
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-02-23  Sam Weinig  <sam@webkit.org>
+
+        Update FeatureDefines.xcconfig
+
+        Rubber-stamped by Anders Carlsson.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-02-23  Dean Jackson  <dino@apple.com>
+
+        Sort the project file with sort-Xcode-project-file.
+
+        Rubber-stamped by Sam Weinig.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-02-23  Sam Weinig  <sam@webkit.org>
+
+        Move telephone number detection behind its own ENABLE macro
+        https://bugs.webkit.org/show_bug.cgi?id=129236
+
+        Reviewed by Dean Jackson.
+
+        * Configurations/FeatureDefines.xcconfig:
+        Add ENABLE_TELEPHONE_NUMBER_DETECTION.
+
+2014-02-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Refine DFG+FTL inlining and compilation limits
+        https://bugs.webkit.org/show_bug.cgi?id=129212
+
+        Reviewed by Mark Hahnenberg.
+        
+        Allow larger functions to be DFG-compiled. Institute a limit on FTL compilation,
+        and set that limit quite high. Institute a limit on inlining-into. The idea here is
+        that large functions tend to be autogenerated, and code generators like emscripten
+        appear to leave few inlining opportunities anyway. Also, we don't want the code
+        size explosion that we would risk if we allowed compilation of a large function and
+        then inlined a ton of stuff into it.
+        
+        This is a 0.5% speed-up on Octane v2 and almost eliminates the typescript
+        regression. This is a 9% speed-up on AsmBench.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::noticeIncomingCall):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        * dfg/DFGCapabilities.h:
+        (JSC::DFG::isSmallEnoughToInlineCodeInto):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLState.h:
+        (JSC::FTL::shouldShowDisassembly):
+        * runtime/Options.h:
+
+2014-02-22  Dan Bernstein  <mitz@apple.com>
+
+        REGRESSION (r164507): Crash beneath JSGlobalObjectInspectorController::reportAPIException at facebook.com, twitter.com, youtube.com
+        https://bugs.webkit.org/show_bug.cgi?id=129227
+
+        Reviewed by Eric Carlson.
+
+        Reverted r164507.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptCallStack.cpp:
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        (Inspector::createScriptCallStackFromException):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+
+2014-02-22  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Remove some unreachable code (-Wunreachable-code)
+        https://bugs.webkit.org/show_bug.cgi?id=129220
+
+        Reviewed by Eric Carlson.
+
+        * API/tests/testapi.c:
+        (EvilExceptionObject_convertToType):
+        * disassembler/udis86/udis86_decode.c:
+        (decode_operand):
+
+2014-02-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, ARMv7 build fix.
+
+        * assembler/ARMv7Assembler.h:
+
+2014-02-21  Filip Pizlo  <fpizlo@apple.com>
+
+        It should be possible for a LinkBuffer to outlive the MacroAssembler and still be useful
+        https://bugs.webkit.org/show_bug.cgi?id=124733
+
+        Reviewed by Oliver Hunt.
+        
+        This also takes the opportunity to de-duplicate some branch compaction code.
+
+        * assembler/ARM64Assembler.h:
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::buffer):
+        * assembler/AssemblerBuffer.h:
+        (JSC::AssemblerData::AssemblerData):
+        (JSC::AssemblerBuffer::AssemblerBuffer):
+        (JSC::AssemblerBuffer::storage):
+        (JSC::AssemblerBuffer::grow):
+        * assembler/LinkBuffer.h:
+        (JSC::LinkBuffer::LinkBuffer):
+        (JSC::LinkBuffer::executableOffsetFor):
+        (JSC::LinkBuffer::applyOffset):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::link):
+        * assembler/MacroAssemblerARMv7.h:
+
+2014-02-21  Brent Fulgham  <bfulgham@apple.com>
+
+        Extend media support for WebVTT sources
+        https://bugs.webkit.org/show_bug.cgi?id=129156
+
+        Reviewed by Eric Carlson.
+
+        * Configurations/FeatureDefines.xcconfig: Add new feature define for AVF_CAPTIONS
+
+2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        When JavaScript API functions have an exception, let the inspector
+        know so it can log the JavaScript and Native backtrace that caused
+        the exception.
+
+        Include some clean up of ConsoleMessage and ScriptCallStack construction.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (reportExceptionToInspector):
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        When seeing an exception, let the inspector know there was an exception.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Log API exceptions by also grabbing the native backtrace.
+
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
+        (Inspector::ScriptCallStack::append):
+        Minor extensions to ScriptCallStack to make it easier to work with.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        Provide better default information if the first call frame was native.
+
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::extractSourceInformationFromException):
+        (Inspector::createScriptCallStackFromException):
+        Perform the handling here of inserting a fake call frame for exceptions
+        if there was no call stack (e.g. a SyntaxError) or if the first call
+        frame had no information.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+        ConsoleMessage cleanup.
+
+2014-02-21  Oliver Hunt  <oliver@apple.com>
+
+        Add extra space to op_call and related opcodes
+        https://bugs.webkit.org/show_bug.cgi?id=129170
+
+        Reviewed by Mark Lam.
+
+        No change in behaviour, just some refactoring to add an extra
+        slot to the op_call instructions, and refactoring to make similar
+        changes easier in future.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printCallOp):
+        * bytecode/Opcode.h:
+        (JSC::padOpcodeName):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitCallVarargs):
+        (JSC::BytecodeGenerator::emitConstruct):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-02-21  Mark Lam  <mark.lam@apple.com>
+
+        gatherFromOtherThread() needs to align the sp before gathering roots.
+        <https://webkit.org/b/129169>
+
+        Reviewed by Geoffrey Garen.
+
+        The GC scans the stacks of other threads using MachineThreads::gatherFromOtherThread().
+        gatherFromOtherThread() defines the range of the other thread's stack as
+        being bounded by the other thread's stack pointer and stack base. While
+        the stack base will always be aligned to sizeof(void*), the stack pointer
+        may not be. This is because the other thread may have just pushed a 32-bit
+        value on its stack before we suspended it for scanning.
+
+        The fix is to round the stack pointer up to the next aligned address of
+        sizeof(void*) and start scanning from there. On 64-bit systems, we will
+        effectively ignore the 32-bit word at the bottom of the stack (top of the
+        stack for stacks growing up) because it cannot be a 64-bit pointer anyway.
+        64-bit pointers should always be stored on 64-bit aligned boundaries (our
+        conservative scan algorithm already depends on this assumption).
+
+        On 32-bit systems, the rounding is effectively a no-op.
+
+        * heap/ConservativeRoots.cpp:
+        (JSC::ConservativeRoots::genericAddSpan):
+        - Hardened somne assertions so that we can catch misalignment issues on
+          release builds as well.
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::gatherFromOtherThread):
+
+2014-02-21  Matthew Mirman  <mmirman@apple.com>
+
+        Added a GetMyArgumentsLengthSafe and added a speculation check.
+        https://bugs.webkit.org/show_bug.cgi?id=129051
+
+        Reviewed by Filip Pizlo.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+
+2014-02-21  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win][LLINT] Many JSC stress test failures.
+        https://bugs.webkit.org/show_bug.cgi?id=129155
+
+        Reviewed by Michael Saboff.
+
+        Intel syntax has reversed operand order compared to AT&T syntax, so we need to swap the operand order, in this case on floating point operations.
+        Also avoid using the reverse opcode (e.g. fdivr), as this puts the result at the wrong position in the floating point stack.
+        E.g. "divd ft0, ft1" would translate to fdivr st, st(1) (Intel syntax) on Windows, but this puts the result in st, when it should be in st(1).
+
+        * offlineasm/x86.rb: Swap operand order on Windows.
+
+2014-02-21  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG write barriers should do more speculations
+        https://bugs.webkit.org/show_bug.cgi?id=129160
+
+        Reviewed by Mark Hahnenberg.
+        
+        Replace ConditionalStoreBarrier with the cheapest speculation that you could do
+        instead.
+        
+        Miniscule speed-up on some things. It's a decent difference in code size, though.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        * bytecode/SpeculatedType.h:
+        (JSC::isNotCellSpeculation):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertStoreBarrier):
+        (JSC::DFG::FixupPhase::insertPhantomCheck):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateOther):
+        (JSC::DFG::Node::shouldSpeculateNotCell):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isNotOther):
+        (JSC::FTL::LowerDFGToLLVM::isOther):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
+
+2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Revert r164486, causing a number of test failures.
+
+        Unreviewed rollout.
+
+2014-02-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Revive SABI (aka shouldAlwaysBeInlined)
+        https://bugs.webkit.org/show_bug.cgi?id=129159
+
+        Reviewed by Mark Hahnenberg.
+        
+        This is a small Octane speed-up.
+
+        * jit/Repatch.cpp:
+        (JSC::linkFor): This code was assuming that if it's invoked then the caller is a DFG code block. That's wrong, since it's now used by all of the JITs.
+
+2014-02-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: JSContext inspection should report exceptions in the console
+        https://bugs.webkit.org/show_bug.cgi?id=128776
+
+        Reviewed by Timothy Hatcher.
+
+        When JavaScript API functions have an exception, let the inspector
+        know so it can log the JavaScript and Native backtrace that caused
+        the exception.
+
+        Include some clean up of ConsoleMessage and ScriptCallStack construction.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+        * API/JSValue.mm:
+        (reportExceptionToInspector):
+        (valueToArray):
+        (valueToDictionary):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        When seeing an exception, let the inspector know there was an exception.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        Log API exceptions by also grabbing the native backtrace.
+
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::firstNonNativeCallFrame):
+        (Inspector::ScriptCallStack::append):
+        Minor extensions to ScriptCallStack to make it easier to work with.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        Provide better default information if the first call frame was native.
+
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::extractSourceInformationFromException):
+        (Inspector::createScriptCallStackFromException):
+        Perform the handling here of inserting a fake call frame for exceptions
+        if there was no call stack (e.g. a SyntaxError) or if the first call
+        frame had no information.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::ConsoleMessage):
+        (Inspector::ConsoleMessage::autogenerateMetadata):
+        * inspector/ConsoleMessage.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::enable):
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+        ConsoleMessage cleanup.
+
+2014-02-20  Anders Carlsson  <andersca@apple.com>
+
+        Modernize JSGlobalLock and JSLockHolder
+        https://bugs.webkit.org/show_bug.cgi?id=129105
+
+        Reviewed by Michael Saboff.
+
+        Use std::mutex and std::thread::id where possible.
+
+        * runtime/JSLock.cpp:
+        (JSC::GlobalJSLock::GlobalJSLock):
+        (JSC::GlobalJSLock::~GlobalJSLock):
+        (JSC::GlobalJSLock::initialize):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::lock):
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::currentThreadIsHoldingLock):
+        * runtime/JSLock.h:
+
+2014-02-20  Mark Lam  <mark.lam@apple.com>
+
+        virtualForWithFunction() should not throw an exception with a partially initialized frame.
+        <https://webkit.org/b/129134>
+
+        Reviewed by Michael Saboff.
+
+        Currently, when JITOperations.cpp's virtualForWithFunction() fails to
+        prepare the callee function for execution, it proceeds to throw the
+        exception using the callee frame which is only partially initialized
+        thus far. Instead, it should be throwing the exception using the caller
+        frame because:
+        1. the error happened "in" the caller while preparing the callee for
+           execution i.e. the caller frame is the top fully initialized frame
+           on the stack.
+        2. the callee frame is not fully initialized yet, and the unwind
+           mechanism cannot depend on the data in it.
+
+        * jit/JITOperations.cpp:
+
+2014-02-20  Mark Lam  <mark.lam@apple.com>
+
+        DefaultGCActivityCallback::doWork() should reschedule if GC is deferred.
+        <https://webkit.org/b/129131>
+
+        Reviewed by Mark Hahnenberg.
+
+        Currently, DefaultGCActivityCallback::doWork() does not check if the GC
+        needs to be deferred before commencing. As a result, the GC may crash
+        and/or corrupt data because the VM is not in the consistent state needed
+        for the GC to run. With this fix, doWork() now checks if the GC is
+        supposed to be deferred and re-schedules if needed. It only commences
+        with GC'ing when it's safe to do so.
+
+        * runtime/GCActivityCallback.cpp:
+        (JSC::DefaultGCActivityCallback::doWork):
+
+2014-02-20  Geoffrey Garen  <ggaren@apple.com>
+
+        Math.imul gives wrong results
+        https://bugs.webkit.org/show_bug.cgi?id=126345
+
+        Reviewed by Mark Hahnenberg.
+
+        Don't truncate non-int doubles to 0 -- that's just not how ToInt32 works.
+        Instead, take a slow path that will do the right thing.
+
+        * jit/ThunkGenerators.cpp:
+        (JSC::imulThunkGenerator):
+
+2014-02-20  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should do its own static estimates of execution frequency before it starts creating OSR entrypoints
+        https://bugs.webkit.org/show_bug.cgi?id=129129
+
+        Reviewed by Geoffrey Garen.
+        
+        We estimate execution counts based on loop depth, and then use those to estimate branch
+        weights. These weights then get carried all the way down to LLVM prof branch_weights
+        meta-data.
+        
+        This is better than letting LLVM do its own static estimates, since by the time we
+        generate LLVM IR, we may have messed up the CFG due to OSR entrypoint creation. Of
+        course, it would be even better if we just slurped in some kind of execution counts
+        from profiling, but we don't do that, yet.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::BasicBlock):
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGBlockInsertionSet.cpp:
+        (JSC::DFG::BlockInsertionSet::insert):
+        (JSC::DFG::BlockInsertionSet::insertBefore):
+        * dfg/DFGBlockInsertionSet.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        * dfg/DFGNaturalLoops.h:
+        (JSC::DFG::NaturalLoops::loopDepth):
+        * dfg/DFGOSREntrypointCreationPhase.cpp:
+        (JSC::DFG::OSREntrypointCreationPhase::run):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStaticExecutionCountEstimationPhase.cpp: Added.
+        (JSC::DFG::StaticExecutionCountEstimationPhase::StaticExecutionCountEstimationPhase):
+        (JSC::DFG::StaticExecutionCountEstimationPhase::run):
+        (JSC::DFG::StaticExecutionCountEstimationPhase::applyCounts):
+        (JSC::DFG::performStaticExecutionCountEstimation):
+        * dfg/DFGStaticExecutionCountEstimationPhase.h: Added.
+
+2014-02-20  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL may not see a compact_unwind section if there weren't any stackmaps
+        https://bugs.webkit.org/show_bug.cgi?id=129125
+
+        Reviewed by Geoffrey Garen.
+        
+        It's OK to not have an unwind section, so long as the function also doesn't have any
+        OSR exits.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        (JSC::FTL::compile):
+        * ftl/FTLUnwindInfo.cpp:
+        (JSC::FTL::UnwindInfo::parse):
+        * ftl/FTLUnwindInfo.h:
+
+== Rolled over to ChangeLog-2014-02-20 ==
diff --git a/ChangeLog-2015-07-23 b/ChangeLog-2015-07-23
new file mode 100644 (file)
index 0000000..acc233a
--- /dev/null
@@ -0,0 +1,34401 @@
+2015-07-20  Matthew Hanson  <matthew_hanson@apple.com>
+
+        Merge r186819. rdar://problem/21729083
+
+    2015-07-14  Matthew Mirman  <mmirman@apple.com>
+
+            Repatch. Makes compileArithSub in the DFG ensure that the constant is an int32.
+            https://bugs.webkit.org/show_bug.cgi?id=146910
+            rdar://problem/21729083
+
+            Reviewed by Filip Pizlo.
+
+            Also fixes the debug build problem where all edges are assumed to
+            have UntypedUse before the fixup phase.
+
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileArithSub):
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validateEdgeWithDoubleResultIfNecessary):
+            * tests/stress/arith-add-with-constants.js: Added some tests for this case.
+            (arithAdd42WrittenAsInteger):
+            (testArithAdd42WrittenAsInteger):
+            (arithSub42WrittenAsDouble):
+            (testArithSub42WrittenAsDouble):
+            (doubleConstant):
+            (testDoubleConstant): Added test for the case of +0.0 and Math.min(0.0)
+            (arithAdd42WrittenAsDouble): Deleted.
+            (testArithAdd42WrittenAsDouble): Deleted.
+
+2015-07-20  Matthew Hanson  <matthew_hanson@apple.com>
+
+        Merge r187028. rdar://problem/21869970
+
+    2015-07-18  Filip Pizlo  <fpizlo@apple.com>
+
+            REGRESSION(186691): OSR entry is broken on loop headers that have no live variables
+            https://bugs.webkit.org/show_bug.cgi?id=147074
+            rdar://problem/21869970
+
+            Reviewed by Michael Saboff.
+
+            The OSR entry must-handle block/value widening introduced in r186691 would cause the
+            CFA to reexecute if it caused any live local variables to change value. But this fails
+            if the must-handle block has no live local variables, and the entry block otherwise
+            appears to be unreachable.
+
+            This fixes the bug by having the change detection include whether the block hadn't been
+            visited in addition to whether any local variable values got widened.
+
+            This is a ~4% speed-up on SunSpider in browser.
+
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::run):
+
+2015-07-16  Matthew Hanson  <matthew_hanson@apple.com>
+
+        Merge r186920. rdar://problem/21764196
+
+    2015-07-16  Mark Lam  <mark.lam@apple.com>
+
+            RegExp::match() should set m_state to ByteCode if compilation fails.
+            https://bugs.webkit.org/show_bug.cgi?id=147023
+
+            Reviewed by Michael Saboff.
+
+            A RegExp has a YarrCodeBlock that has 4 MacroAssemblerCodeRefs for compiled code.
+            If one of these compilations succeeds, RegExp::m_state will be set to JITCode.
+            Subsequently, if RegExp tries to compile another one of these but fails, m_state
+            will be left untouched i.e. it still says JITCode.  As a result, when
+            RegExp::match() later tries to execute the non-existant compiled code, it will
+            crash.
+
+            The fix is to downgrade m_state to ByteCode if RegExp ever fails to compile.
+            This failure should be rare.  We'll do the minimal work here to fix the issue and
+            keep an eye on the perf bots.  If perf regresses, we can do some optimization work then.
+
+            This issue is difficult to test for since it either requires a low memory condition
+            to trigger a failed RegExp compilation at the right moment, or for the RegExp to
+            succeed compilation in the MatchedOnly mode but fail in IncludeSubpatterns mode.
+            Instead, I manually tested it by instrumenting RegExp::compile() to fail once in every
+            10 compilation attempts.
+
+            * runtime/RegExp.cpp:
+            (JSC::RegExp::compile):
+            (JSC::RegExp::compileMatchOnly):
+
+2015-07-15  Lucas Forschler  <lforschler@apple.com>
+
+        Merge r186826
+
+    2015-07-14  Anders Carlsson  <andersca@apple.com>
+
+            Assertions.h should include ExportMacros.h
+            https://bugs.webkit.org/show_bug.cgi?id=146948
+
+            Reviewed by Tim Horton.
+
+            Remove now unneeded WTF_EXPORT_PRIVATE define.
+
+            * API/JSBase.h:
+
+2015-07-13  Babak Shafiei  <bshafiei@apple.com>
+
+        Merge r186777.
+
+    2015-07-13  Anders Carlsson  <andersca@apple.com>
+
+            Apps linked with a deployment target of iOS 7.x or earlier crash when using modern WebKit API
+            https://bugs.webkit.org/show_bug.cgi?id=146913
+            rdar://problem/21789252
+
+            Reviewed by Dan Bernstein.
+
+            Make a top-level symlink from /System/Library/PrivateFrameworks/JavaScriptCore.framework to
+            /System/Library/Frameworks/JavaScriptCore.framework.
+
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-07-12  Babak Shafiei  <bshafiei@apple.com>
+
+        Merge r186702.
+
+    2015-07-10  Filip Pizlo  <fpizlo@apple.com>
+
+            AI folding of IsObjectOrNull is broken for non-object types that may be null
+            https://bugs.webkit.org/show_bug.cgi?id=146867
+
+            Reviewed by Ryosuke Niwa.
+
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Fix the bug and add some text describing what is going on.
+            * tests/stress/misc-is-object-or-null.js: Added. Test for the bug.
+            (foo):
+            * tests/stress/other-is-object-or-null.js: Added. Test for a bug I almost introduced.
+            (foo):
+
+2015-07-12  Babak Shafiei  <bshafiei@apple.com>
+
+        Merge r186691.
+
+    2015-07-04  Filip Pizlo  <fpizlo@apple.com>
+
+            DFG fragile frozen values are fundamentally broken
+            https://bugs.webkit.org/show_bug.cgi?id=146602
+
+            Reviewed by Mark Lam.
+
+            This change gets rid of the FragileValue value strength, because it was fundamentally
+            broken.
+
+            FragileValue was a value known to the compiler but not tracked by the GC in any way -
+            it wasn't marked and it wasn't weak. This was used to support AI bootstrap for OSR
+            must-handle values. The philosophy was that if the compiler did use the value for
+            optimization, it would have been strengthened to a weak value (or maybe even a strong
+            value, though we probably won't do that). But this was too much of a pipe dream. I've
+            found at least one case where the compiler did use the value, but never strengthened
+            it: it would happen if the value ended up in an OSR entry data expected value. Then if
+            we GCed, we might have killed the value, but OSR entry would still try to use it for
+            validation. That might have sort of just worked, but it's clearly shady.
+
+            The reason why we made must-handle values fragile and not weak is that most of the time
+            the values disappear from the abstract state: they are LUBed to a non-constant. If we
+            kept them around as weak, we'd have too many cases of the GC killing the code because
+            it thought that the value was somehow meaningful to the code when it was only used as a
+            temporary artifact of optimization.
+
+            So, it's true that it's very important for must-handle values not to automatically be
+            weak or strong. It's also true that the values are necessary for AI bootstrap because
+            we need to know what values OSR entry will require. But we shouldn't accomplish these
+            goals by having the compiler hold onto what are essentially dangling pointers.
+
+            This implements a better solution: instead of having InPlaceAbstractState bootstrap the
+            AI with must-handle values at the beginning, we now widen the valuesAtHead of the
+            must-handle block after AI converges. This widening is done in CFAPhase. This allows us
+            to see if the must-handle values are necessary at all. In most cases, the widening
+            takes a non-constant abstract value and simply amends something to its type based on
+            the type of the must-handle value, and so the must-handle value never actually shows up
+            in either the IR or any abstract value. In the unlikely event that the value at head is
+            bottom, we freeze the must-handle value. This change removes FragileValue, and this
+            freezing uses WeakValue as the strength. That makes sense: since the abstract value was
+            bottom, the must-handle value becomes integral to the IR and so it makes no sense for
+            the GC to keep the resulting CodeBlock alive if that must-handle value dies. This will
+            sometimes happen for example if you have a very long-running loop whose pre-header
+            allocates some object, but that pre-header appears to always exit to the optimizing JIT
+            because it was only profiled once in the LLInt and that profiling appears insufficient
+            to the DFG. In that case, we'll effectively constant-fold the references to the object
+            inside the loop, which is both efficient (yay constant folding!) and necessary
+            (otherwise we wouldn't know what the type of the variable should have been).
+
+            Testing and debugging this is complicated. So, this adds some new capabilities:
+
+            - DFG IR dumps also dump all of the FrozenValues that point to the heap along with
+              their strengths, so that it's easy to see what GC objects the DFG feels are necessary
+              for the compilation.
+
+            - DFG OSR entry preparation prints out the OSR entry data structures, so that it's easy
+              to see what GC pointers (and other things) are used for OSR entry validation. The
+              printouts are quite detailed, and should also help other kinds of OSR entry
+              debugging.
+
+            - DFG::Plan now validates whether all of the GC pointers planted in the various JITCode
+              data structures are also properly registered as either weak or strong pointers in the
+              CodeBlock. This validation check previously failed due to fragile values ending up in
+              the OSR entry data structures, both in the newly added test (dead-osr-entry-value.js)
+              and in some pre-existing tests (like earley-boyer and 3d-raytrace).
+
+            * CMakeLists.txt:
+            * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::stronglyVisitStrongReferences):
+            * bytecode/CodeOrigin.cpp:
+            (JSC::InlineCallFrame::visitAggregate):
+            * bytecode/Operands.h:
+            (JSC::Operands::operand):
+            (JSC::Operands::hasOperand):
+            * bytecode/StructureSet.cpp:
+            (JSC::StructureSet::dump):
+            (JSC::StructureSet::validateReferences):
+            * bytecode/StructureSet.h:
+            * bytecode/TrackedReferences.cpp: Added.
+            (JSC::TrackedReferences::TrackedReferences):
+            (JSC::TrackedReferences::~TrackedReferences):
+            (JSC::TrackedReferences::add):
+            (JSC::TrackedReferences::check):
+            (JSC::TrackedReferences::dump):
+            * bytecode/TrackedReferences.h: Added.
+            * dfg/DFGAbstractValue.cpp:
+            (JSC::DFG::AbstractValue::observeTransitions):
+            (JSC::DFG::AbstractValue::set):
+            (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+            (JSC::DFG::AbstractValue::mergeOSREntryValue):
+            (JSC::DFG::AbstractValue::filter):
+            (JSC::DFG::AbstractValue::dumpInContext):
+            (JSC::DFG::AbstractValue::validateReferences):
+            (JSC::DFG::AbstractValue::setOSREntryValue): Deleted.
+            * dfg/DFGAbstractValue.h:
+            (JSC::DFG::AbstractValue::fullTop):
+            (JSC::DFG::AbstractValue::merge):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+            * dfg/DFGCFAPhase.cpp:
+            (JSC::DFG::CFAPhase::run):
+            * dfg/DFGCommonData.cpp:
+            (JSC::DFG::CommonData::invalidate):
+            (JSC::DFG::CommonData::validateReferences):
+            * dfg/DFGCommonData.h:
+            (JSC::DFG::CommonData::requiredRegisterCountForExecutionAndExit):
+            * dfg/DFGFrozenValue.h:
+            (JSC::DFG::FrozenValue::FrozenValue):
+            (JSC::DFG::FrozenValue::strengthenTo):
+            (JSC::DFG::FrozenValue::pointsToHeap):
+            (JSC::DFG::FrozenValue::strength):
+            (JSC::DFG::FrozenValue::freeze):
+            * dfg/DFGGraph.cpp:
+            (JSC::DFG::Graph::Graph):
+            (JSC::DFG::Graph::dump):
+            (JSC::DFG::Graph::registerFrozenValues):
+            (JSC::DFG::Graph::visitChildren):
+            (JSC::DFG::Graph::freeze):
+            (JSC::DFG::Graph::freezeStrong):
+            (JSC::DFG::Graph::freezeFragile): Deleted.
+            * dfg/DFGGraph.h:
+            * dfg/DFGInPlaceAbstractState.cpp:
+            (JSC::DFG::InPlaceAbstractState::initialize):
+            * dfg/DFGJITCode.cpp:
+            (JSC::DFG::JITCode::setOptimizationThresholdBasedOnCompilationResult):
+            (JSC::DFG::JITCode::validateReferences):
+            * dfg/DFGJITCode.h:
+            * dfg/DFGJITCompiler.cpp:
+            (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+            (JSC::DFG::JITCompiler::noticeOSREntry):
+            * dfg/DFGJITCompiler.h:
+            (JSC::DFG::JITCompiler::branchStructurePtr):
+            (JSC::DFG::JITCompiler::jitCode):
+            (JSC::DFG::JITCompiler::noticeOSREntry): Deleted.
+            * dfg/DFGMinifiedGraph.cpp: Added.
+            (JSC::DFG::MinifiedGraph::prepareAndShrink):
+            (JSC::DFG::MinifiedGraph::validateReferences):
+            * dfg/DFGMinifiedGraph.h:
+            (JSC::DFG::MinifiedGraph::append):
+            (JSC::DFG::MinifiedGraph::prepareAndShrink): Deleted.
+            * dfg/DFGOSREntry.cpp:
+            (JSC::DFG::OSREntryData::dumpInContext):
+            (JSC::DFG::OSREntryData::dump):
+            (JSC::DFG::prepareOSREntry):
+            * dfg/DFGOSREntry.h:
+            (JSC::DFG::getOSREntryDataBytecodeIndex):
+            * dfg/DFGPlan.cpp:
+            (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::linkOSREntries):
+            (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+            * dfg/DFGStructureAbstractValue.cpp:
+            (JSC::DFG::StructureAbstractValue::dump):
+            (JSC::DFG::StructureAbstractValue::validateReferences):
+            * dfg/DFGStructureAbstractValue.h:
+            * dfg/DFGValidate.cpp:
+            (JSC::DFG::Validate::validate):
+            * dfg/DFGValueStrength.cpp:
+            (WTF::printInternal):
+            * dfg/DFGValueStrength.h:
+            (JSC::DFG::merge):
+            * ftl/FTLExitPropertyValue.cpp:
+            (JSC::FTL::ExitPropertyValue::dump):
+            (JSC::FTL::ExitPropertyValue::validateReferences):
+            * ftl/FTLExitPropertyValue.h:
+            * ftl/FTLExitTimeObjectMaterialization.cpp:
+            (JSC::FTL::ExitTimeObjectMaterialization::dump):
+            (JSC::FTL::ExitTimeObjectMaterialization::validateReferences):
+            * ftl/FTLExitTimeObjectMaterialization.h:
+            * ftl/FTLExitValue.cpp:
+            (JSC::FTL::ExitValue::dump):
+            (JSC::FTL::ExitValue::validateReferences):
+            * ftl/FTLExitValue.h:
+            * ftl/FTLJITCode.cpp:
+            (JSC::FTL::JITCode::dfgCommon):
+            (JSC::FTL::JITCode::validateReferences):
+            * ftl/FTLJITCode.h:
+            (JSC::FTL::JITCode::handles):
+            (JSC::FTL::JITCode::dataSections):
+            * ftl/FTLOSRExit.cpp:
+            (JSC::FTL::OSRExit::codeLocationForRepatch):
+            (JSC::FTL::OSRExit::validateReferences):
+            * ftl/FTLOSRExit.h:
+            (JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
+            * jit/JITCode.cpp:
+            (JSC::JITCode::typeName):
+            (JSC::JITCode::validateReferences):
+            (JSC::JITCode::execute):
+            * jit/JITCode.h:
+            (JSC::JITCode::start):
+            * tests/stress/dead-osr-entry-value.js: Added.
+            (foo):
+
+2015-07-10  Matthew Hanson  <matthew_hanson@apple.com>
+
+        Disable non-shipping features.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-07-09  Mark Lam  <mark.lam@apple.com>
+
+        SymbolTable::entryFor() should do a bounds check before indexing into the localToEntry vector.
+        https://bugs.webkit.org/show_bug.cgi?id=146807
+
+        Reviewed by Filip Pizlo.
+
+        When we capture an argument by name and we use "arguments", we put all of the
+        arguments into the scope.  But destructured arguments are put into the scope
+        anonymously i.e. the SymbolTable knows that the scope offset is in use via
+        SymbolTable::m_maxScopeOffset, but that ScopeOffset won't appear in
+        SymbolTable::m_map.
+
+        The SymbolTable's m_localToEntry vector is synthesized from its m_map, and will
+        have a size which is based on the largest ScopeOffset in the m_map.  If we have a
+        scenario where the anonymous argument is at a higher ScopeOffset than all the
+        named arguments, then the m_localsToEntry vector will not have an entry for it
+        i.e. the m_localsToEntry vector will have a size that is <= the ScopeOffset of
+        the anonymous argument.
+
+        Hence, SymbolTable::entryFor() should ensure that the requested ScopeOffset is
+        within the bounds of the m_localToEntry vector before indexing into it.
+
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::entryFor):
+
+2015-07-09  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (r180248): Repro Crash: com.apple.WebKit.WebContent at com.apple.JavaScriptCore: JSC::createRangeError + 20
+        https://bugs.webkit.org/show_bug.cgi?id=146767
+
+        Reviewed by Geoffrey Garen.
+
+        If the stack check fails at the top most frame, we must use that frame to
+        generate the exception.  Reverted the code to always use the current frame to
+        throw an out of stack exception.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+2015-07-03  Filip Pizlo  <fpizlo@apple.com>
+
+        OSR exit fuzzing should allow us to select a static exit site
+        https://bugs.webkit.org/show_bug.cgi?id=146601
+
+        Reviewed by Geoffrey Garen.
+        
+        The original implementation of the fuzzer allows us to trigger an exit based on its index
+        in the dynamic sequence of exit sites encountered. But there are usually millions of
+        dynamically encountered exit sites, even if the program only has thousands of static exit
+        sites. That means that we would at best be able to do a random sampling of exits, and
+        those would be biased to the hottest exit sites.
+        
+        This change allows us to also select exit sites based on their index in the static
+        sequence of exit sites that the compiler compiled. Then, once that static exit site is
+        selected, we can select which dynamic exit at that exit site we should trigger. Since the
+        number of static exit sites is usually smallish (it's bounded by program size), we can do
+        an exhaustive search over all exit sites in most programs.
+
+        * dfg/DFGOSRExitFuzz.cpp:
+        (JSC::numberOfStaticOSRExitFuzzChecks):
+        (JSC::numberOfOSRExitFuzzChecks):
+        * dfg/DFGOSRExitFuzz.h:
+        (JSC::DFG::doOSRExitFuzzing):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitOSRExitFuzzCheck):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
+        * jsc.cpp:
+        (jscmain):
+        * runtime/Options.h:
+        * runtime/TestRunnerUtils.h:
+
+2015-07-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix grammar issue in TypeError attempting to change an unconfigurable property
+        https://bugs.webkit.org/show_bug.cgi?id=146774
+
+        Reviewed by Brent Fulgham.
+
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::defineOwnNonIndexProperty):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::defineOwnProperty):
+
+2015-07-06  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove the unused HeapBlock.h
+        https://bugs.webkit.org/show_bug.cgi?id=146580
+
+        Reviewed by Andreas Kling.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/CopiedBlock.h:
+        * heap/CopiedSpace.h:
+        * heap/CopiedSpaceInlines.h:
+        * heap/HandleBlock.h:
+        * heap/HeapBlock.h: Removed.
+        * heap/MarkedBlock.h:
+
+2015-07-06  Saam barati  <saambarati1@gmail.com>
+
+        JSC's parser should follow the ES6 spec with respect to parsing Declarations
+        https://bugs.webkit.org/show_bug.cgi?id=146621
+
+        Reviewed by Mark Lam.
+
+        There were a few locations where JSC would allow declaration statements
+        in incorrect ways. JSC didn't distinguish between 'Statement' and
+        'StatementListItem' grammar productions. The relevant grammar is here:
+        http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
+
+        From the ECMA Script 6.0 spec:
+        1. Section 13.6 The if Statement (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-if-statement) 
+         says that IfStatements only takes Statements for the "then-else" clauses, not StatementListItems.
+         (Same with 'while/for/do-while' loop bodies).
+        2. Section 13 ECMAScript Language: Statements and Declarations 
+         (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ecmascript-language-statements-and-declarations)
+         defines the syntax of Statements, and they do not include ClassDeclarations and LexicalDeclarations 
+         (const, let, see 13.3.1 Let and Const Declarations).
+         Declarations can only be in the “then-else” clauses when embedded in a StatementListItem in a BlockStatement (see 13.2).
+
+        Hence, the following style of declarations are no longer allowed:
+            'if/for/while (condition) const x = 40;'
+            'if/for/while (condition) class C { }'
+
+        Instead, we mandate such declaration constructs are within a StatementList 
+       (which is the production that JSC's Parser::parseSourceElements function parses):
+           'if/for/while (condition) { const x = 40; }'
+           'if/for/while (condition) { class C { } }'
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseSourceElements):
+        (JSC::Parser<LexerType>::parseStatementListItem):
+        (JSC::Parser<LexerType>::parseVarDeclaration):
+        (JSC::Parser<LexerType>::parseStatement):
+        (JSC::Parser<LexerType>::parseExpressionStatement):
+        * parser/Parser.h:
+        (JSC::Parser::getLabel):
+
+2015-07-06  Alex Christensen  <achristensen@webkit.org>
+
+        Unreviewed debug build fix after r186358.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fastConcatWith):
+        Pass vm parameter to fastConcatType.
+
+2015-07-06  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Array.concat should be fast for integer or double arrays
+        https://bugs.webkit.org/show_bug.cgi?id=146260
+
+        Reviewed by Darin Adler.
+
+        Added a fast path to Array.prototype.concat. When concatenating two Int32, Double, or Contiguous
+        arrays, simply memcopy the arrays into a new uninitialized buffer.
+
+        This improves huffman encoding in CompressionBench by 3.7x on a Mid 2014 MacBookPro.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncConcat):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fastConcatWith): Added.
+        * runtime/JSArray.h:
+        (JSC::JSArray::fastConcatType): Added. Returns the resultant array's indexing type if we can use
+        the fact path. Returns NonArray otherwise.
+
+2015-07-06  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] Remove ReadableStream custom constructor
+        https://bugs.webkit.org/show_bug.cgi?id=146547
+
+        Reviewed by Darin Adler.
+
+        Adding helper function to throw range errors.
+
+        * runtime/Error.h:
+        (JSC::throwRangeError):
+        (JSC::throwVMRangeError):
+
+2015-07-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement the latest Promise spec in JS
+        https://bugs.webkit.org/show_bug.cgi?id=146229
+
+        Reviewed by Sam Weinig.
+
+        Updated the Promise implementation to meet to the ES6 spec.
+        This patch
+        1. Implement ES6 Promise and related abstract operations in builtins JS
+        2. Expose @enqueueJob private function to JS world to post the microtask
+
+        Updated implementation has one-on-one correspondence to the ES6 spec description.
+        And keep the JSPromiseDeferred because it is the interface used from the WebCore.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/Array.prototype.js:
+        (reduce):
+        (reduceRight):
+        (every):
+        (forEach):
+        (filter):
+        (map):
+        (some):
+        (fill):
+        (find):
+        (findIndex):
+        (includes):
+        (copyWithin):
+        ToInteger / ToLength are renamed to toInteger and toLength.
+        * builtins/ArrayConstructor.js:
+        (from):
+        ToInteger / ToLength are renamed to toInteger and toLength.
+        * builtins/GlobalObject.js:
+        (toInteger):
+        (toLength):
+        (isObject):
+        (ToInteger): Deleted.
+        (ToLength): Deleted.
+        ToInteger / ToLength are renamed to toInteger and toLength.
+        Add new abstract operation, isObject.
+        * builtins/Operations.Promise.js: Added.
+        (isPromise):
+        (newPromiseReaction):
+        (newPromiseDeferred):
+        (newPromiseCapability.executor):
+        (newPromiseCapability):
+        (triggerPromiseReactions):
+        (rejectPromise):
+        (fulfillPromise):
+        (createResolvingFunctions.resolve):
+        (createResolvingFunctions.reject):
+        (createResolvingFunctions):
+        (promiseReactionJob):
+        (promiseResolveThenableJob):
+        (initializePromise):
+        Added Promise related abstract operations.
+        * builtins/Promise.prototype.js:
+        (catch):
+        (.onFulfilled):
+        (.onRejected):
+        (then):
+        Promise#then implementation in JS.
+        * builtins/PromiseConstructor.js: Added.
+        (all.newResolveElement):
+        (all):
+        (race):
+        (reject):
+        (resolve):
+        Promise static functions implementations in JS.
+        * builtins/StringConstructor.js:
+        (raw):
+        ToInteger / ToLength are renamed to toInteger and toLength.
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::enqueueJob):
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::initializePromiseFunction):
+        (JSC::JSGlobalObject::newPromiseDeferredFunction):
+        * runtime/JSJob.cpp: Renamed from Source/JavaScriptCore/runtime/JSPromiseReaction.h.
+        (JSC::createJSJob):
+        (JSC::JSJobMicrotask::run):
+        * runtime/JSJob.h: Renamed from Source/JavaScriptCore/runtime/JSPromiseFunctions.h.
+        * runtime/JSPromise.cpp:
+        (JSC::JSPromise::create):
+        (JSC::JSPromise::JSPromise):
+        (JSC::JSPromise::finishCreation):
+        (JSC::JSPromise::result):
+        (JSC::JSPromise::destroy): Deleted.
+        (JSC::JSPromise::visitChildren): Deleted.
+        (JSC::JSPromise::reject): Deleted.
+        (JSC::JSPromise::resolve): Deleted.
+        (JSC::JSPromise::appendResolveReaction): Deleted.
+        (JSC::JSPromise::appendRejectReaction): Deleted.
+        (JSC::triggerPromiseReactions): Deleted.
+        * runtime/JSPromise.h:
+        (JSC::JSPromise::status): Deleted.
+        (JSC::JSPromise::result): Deleted.
+        (JSC::JSPromise::constructor): Deleted.
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::constructPromise):
+        (JSC::JSPromiseConstructorFuncResolve): Deleted.
+        (JSC::JSPromiseConstructorFuncReject): Deleted.
+        (JSC::performPromiseRaceLoop): Deleted.
+        (JSC::JSPromiseConstructorFuncRace): Deleted.
+        (JSC::performPromiseAll): Deleted.
+        (JSC::JSPromiseConstructorFuncAll): Deleted.
+        * runtime/JSPromiseDeferred.cpp:
+        (JSC::JSPromiseDeferred::create):
+        (JSC::createJSPromiseDeferredFromConstructor): Deleted.
+        (JSC::updateDeferredFromPotentialThenable): Deleted.
+        (JSC::performDeferredResolve): Deleted.
+        (JSC::performDeferredReject): Deleted.
+        (JSC::abruptRejection): Deleted.
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPromiseFunctions.cpp: Removed.
+        (JSC::deferredConstructionFunction): Deleted.
+        (JSC::createDeferredConstructionFunction): Deleted.
+        (JSC::identifyFunction): Deleted.
+        (JSC::createIdentifyFunction): Deleted.
+        (JSC::promiseAllCountdownFunction): Deleted.
+        (JSC::createPromiseAllCountdownFunction): Deleted.
+        (JSC::promiseResolutionHandlerFunction): Deleted.
+        (JSC::createPromiseResolutionHandlerFunction): Deleted.
+        (JSC::rejectPromiseFunction): Deleted.
+        (JSC::createRejectPromiseFunction): Deleted.
+        (JSC::resolvePromiseFunction): Deleted.
+        (JSC::createResolvePromiseFunction): Deleted.
+        (JSC::throwerFunction): Deleted.
+        (JSC::createThrowerFunction): Deleted.
+        * runtime/JSPromisePrototype.cpp:
+        (JSC::JSPromisePrototypeFuncThen): Deleted.
+        * runtime/JSPromiseReaction.cpp: Removed.
+        (JSC::createExecutePromiseReactionMicrotask): Deleted.
+        (JSC::ExecutePromiseReactionMicrotask::run): Deleted.
+        (JSC::JSPromiseReaction::create): Deleted.
+        (JSC::JSPromiseReaction::JSPromiseReaction): Deleted.
+        (JSC::JSPromiseReaction::finishCreation): Deleted.
+        (JSC::JSPromiseReaction::visitChildren): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM): Deleted.
+        * runtime/VM.h:
+
+2015-07-04  Chris Dumez  <cdumez@apple.com>
+
+        Drop RefPtr::clear() method
+        https://bugs.webkit.org/show_bug.cgi?id=146556
+
+        Reviewed by Brady Eidson.
+
+        Drop RefPtr::clear() method in favor of "= nullptr;" pattern.
+
+2015-07-03  Dan Bernstein  <mitz@apple.com>
+
+        Just give up on -Wunreachable-code in JavaScriptCore.
+
+        * Configurations/Base.xcconfig:
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoop::execute):
+
+2015-07-03  Dan Bernstein  <mitz@apple.com>
+
+        Fixed the LLINT CLoop build.
+
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoop::execute):
+
+2015-07-03  Dan Bernstein  <mitz@apple.com>
+
+        [Xcode] Update some build settings as recommended by Xcode 7
+        https://bugs.webkit.org/show_bug.cgi?id=146597
+
+        Reviewed by Sam Weinig.
+
+        * Configurations/Base.xcconfig: Enabled CLANG_WARN_UNREACHABLE_CODE and
+        GCC_NO_COMMON_BLOCKS. Removed GCC_MODEL_TUNING.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Updated LastUpgradeCheck.
+
+        * dfg/DFGGraph.h: Tweaked the definition of DFG_CRASH to suppress unreachable code warnings.
+
+2015-07-03  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Relax builtin JS restriction about try-catch
+        https://bugs.webkit.org/show_bug.cgi?id=146555
+
+        Reviewed by Sam Weinig.
+
+        When retrieving the captured variables from the full activated scope,
+        it swapped the given vector with the stored declared variables vector.
+        This is because retrieving the captured variables are executed in the
+        last sequence of the parser, so declared variables are no longer used.
+        However, in builtins functions case, after retrieving the captured
+        variables, we check the variables by using declared variables vector.
+        So at that time, the declared variables vector becomes empty and it
+        raises assertion failures when the builtins function contains the full
+        activated scope. try-catch's catch scope requires the upper scope full
+        activated, so JS code in the builtins cannot use the try-catch.
+
+        This patch relaxes this restriction. When retrieving the captured
+        variables from the scope, just copy to the given vector.
+
+        * parser/Parser.h:
+        (JSC::Scope::getCapturedVariables):
+
+2015-07-02  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG and FTL should have an OSR exit fuzzer
+        https://bugs.webkit.org/show_bug.cgi?id=146562
+
+        Reviewed by Benjamin Poulain.
+        
+        Adds a basic OSR exit fuzzer to JSC. This isn't hooked into any test harnesses yet, but I
+        spot-checked it on v8-earley-boyer.js and so far found no bugs. I'd like to figure out how
+        to harness this after I land it.
+        
+        Since it's turned off by default, it should have no effect on behavior.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGOSRExitFuzz.cpp: Added.
+        (JSC::numberOfOSRExitFuzzChecks):
+        * dfg/DFGOSRExitFuzz.h: Added.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
+        (JSC::DFG::SpeculativeJIT::emitOSRExitFuzzCheck):
+        (JSC::DFG::SpeculativeJIT::speculationCheck):
+        * dfg/DFGSpeculativeJIT.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
+        * jsc.cpp:
+        (jscmain):
+        * runtime/Options.h:
+        * runtime/TestRunnerUtils.h:
+
+2015-07-02  Saam barati  <saambarati1@gmail.com>
+
+        Rename "Deconstruction" to "Destructuring" throughout JSC
+        https://bugs.webkit.org/show_bug.cgi?id=146100
+
+        Reviewed by Mark Lam.
+
+        It is good to use the same naming conventions as the ES6 
+        spec because it is the de facto way of speaking about these 
+        language features. This also has the benefit of improving JSC's
+        hackability because it improves code readability for newcomers 
+        to JSC or newcomers to this part of the code base.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeNextParameter):
+        (JSC::BytecodeGenerator::visibleNameForParameter):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::registerFor):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::tryGetBoundLocal):
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::ClassExprNode::emitBytecode):
+        (JSC::DestructuringAssignmentNode::emitBytecode):
+        (JSC::DestructuringPatternNode::~DestructuringPatternNode):
+        (JSC::ArrayPatternNode::collectBoundIdentifiers):
+        (JSC::DeconstructingAssignmentNode::emitBytecode): Deleted.
+        (JSC::DeconstructionPatternNode::~DeconstructionPatternNode): Deleted.
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createElementList):
+        (JSC::ASTBuilder::createFormalParameterList):
+        (JSC::ASTBuilder::createClause):
+        (JSC::ASTBuilder::createClauseList):
+        (JSC::ASTBuilder::createForInLoop):
+        (JSC::ASTBuilder::createForOfLoop):
+        (JSC::ASTBuilder::isBindingNode):
+        (JSC::ASTBuilder::isResolve):
+        (JSC::ASTBuilder::createDestructuringAssignment):
+        (JSC::ASTBuilder::createArrayPattern):
+        (JSC::ASTBuilder::appendArrayPatternSkipEntry):
+        (JSC::ASTBuilder::appendArrayPatternEntry):
+        (JSC::ASTBuilder::appendArrayPatternRestEntry):
+        (JSC::ASTBuilder::createObjectPattern):
+        (JSC::ASTBuilder::appendObjectPatternEntry):
+        (JSC::ASTBuilder::createDeconstructingAssignment): Deleted.
+        * parser/NodeConstructors.h:
+        (JSC::TryNode::TryNode):
+        (JSC::ParameterNode::ParameterNode):
+        (JSC::ForOfNode::ForOfNode):
+        (JSC::DestructuringPatternNode::DestructuringPatternNode):
+        (JSC::ArrayPatternNode::ArrayPatternNode):
+        (JSC::ArrayPatternNode::create):
+        (JSC::ObjectPatternNode::ObjectPatternNode):
+        (JSC::BindingNode::create):
+        (JSC::BindingNode::BindingNode):
+        (JSC::DestructuringAssignmentNode::DestructuringAssignmentNode):
+        (JSC::DeconstructionPatternNode::DeconstructionPatternNode): Deleted.
+        (JSC::DeconstructingAssignmentNode::DeconstructingAssignmentNode): Deleted.
+        * parser/Nodes.cpp:
+        (JSC::FunctionParameters::create):
+        * parser/Nodes.h:
+        (JSC::ExpressionNode::isResolveNode):
+        (JSC::ExpressionNode::isBracketAccessorNode):
+        (JSC::ExpressionNode::isDotAccessorNode):
+        (JSC::ExpressionNode::isDestructuringNode):
+        (JSC::ExpressionNode::isFuncExprNode):
+        (JSC::ExpressionNode::isCommaNode):
+        (JSC::ExpressionNode::isSimpleArray):
+        (JSC::ParameterNode::pattern):
+        (JSC::ParameterNode::nextParam):
+        (JSC::FunctionParameters::size):
+        (JSC::FunctionParameters::at):
+        (JSC::FunctionParameters::patterns):
+        (JSC::DestructuringPatternNode::isBindingNode):
+        (JSC::DestructuringPatternNode::emitDirectBinding):
+        (JSC::ArrayPatternNode::appendIndex):
+        (JSC::ObjectPatternNode::appendEntry):
+        (JSC::BindingNode::boundProperty):
+        (JSC::DestructuringAssignmentNode::bindings):
+        (JSC::ExpressionNode::isDeconstructionNode): Deleted.
+        (JSC::DeconstructionPatternNode::isBindingNode): Deleted.
+        (JSC::DeconstructionPatternNode::emitDirectBinding): Deleted.
+        (JSC::DeconstructingAssignmentNode::bindings): Deleted.
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclaration):
+        (JSC::Parser<LexerType>::parseWhileStatement):
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        (JSC::Parser<LexerType>::createBindingPattern):
+        (JSC::Parser<LexerType>::tryParseDestructuringPatternExpression):
+        (JSC::Parser<LexerType>::parseDestructuringPattern):
+        (JSC::Parser<LexerType>::parseDefaultValueForDestructuringPattern):
+        (JSC::Parser<LexerType>::parseForStatement):
+        (JSC::Parser<LexerType>::parseFormalParameters):
+        (JSC::Parser<LexerType>::parseFunctionParameters):
+        (JSC::Parser<LexerType>::parseAssignmentExpression):
+        (JSC::Parser<LexerType>::tryParseDeconstructionPatternExpression): Deleted.
+        (JSC::Parser<LexerType>::parseDeconstructionPattern): Deleted.
+        (JSC::Parser<LexerType>::parseDefaultValueForDeconstructionPattern): Deleted.
+        * parser/Parser.h:
+        (JSC::isEvalNode):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createPropertyList):
+        (JSC::SyntaxChecker::createElementList):
+        (JSC::SyntaxChecker::createFormalParameterList):
+        (JSC::SyntaxChecker::createClause):
+        (JSC::SyntaxChecker::createClauseList):
+        (JSC::SyntaxChecker::operatorStackPop):
+        * tests/stress/reserved-word-with-escape.js:
+        * tests/stress/rest-elements.js:
+
+2015-07-02  Mark Lam  <mark.lam@apple.com>
+
+        Build fix for Win EWS bot.
+        https://bugs.webkit.org/show_bug.cgi?id=146551
+
+        Not reviewed.
+
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::functionCrash):
+
+2015-07-02  Dan Bernstein  <mitz@apple.com>
+
+        <rdar://problem/21429613> [iOS] Stop making symlinks from PrivateFrameworks to Frameworks
+        https://bugs.webkit.org/show_bug.cgi?id=146542
+
+        Reviewed by Sam Weinig.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Removed the build phase that makes the symlink.
+
+2015-07-01  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Aggregate profile call information on the backend to drastically reduce profile sizes
+        https://bugs.webkit.org/show_bug.cgi?id=146536
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Timeline.json:
+        Change a CPUProfile from sending a required "calls" param to sending a required
+        "callInfo" param which includes aggregated information about the calls.
+
+2015-06-30  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::freezeFragile should register the frozen value's structure
+        https://bugs.webkit.org/show_bug.cgi?id=136055
+        rdar://problem/21042120
+
+        Reviewed by Mark Lam and Geoffrey Garen.
+        
+        This fixes weird concurrency bugs where the constant folding phase tries to convert
+        something to a constant but then crashes because the constant's structure wasn't
+        registered. The AI was registering the structure of any value it saw, but constant folding
+        wasn't - and that's fine so long as there ain't no concurrency.
+        
+        The best fix is to just make it impossible to introduce a constant into the IR without
+        registering its structure. That's what this change does. This is not only a great
+        concurrency fix - it also makes the compiler somewhat easier to hack on because it's one
+        less case of structure registering that you have to remember about.
+        
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setOSREntryValue): No need to register.
+        (JSC::DFG::AbstractValue::set): We still call register, but just to get the watchpoint state.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::freezeFragile): Register the structure.
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run): Assert that these are all registered.
+
+2015-07-01  Matthew Mirman  <mmirman@apple.com>
+
+        Unreviewed, rolling out r185889
+        https://bugs.webkit.org/show_bug.cgi?id=146528
+        rdar://problem/21573959
+
+        Patch breaks chromeexperiments.com
+        
+        Reverted changeset:
+        
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/InjectedScriptSource.js:
+        (.):
+        * runtime/JSBoundSlotBaseFunction.cpp: Removed.
+        * runtime/JSBoundSlotBaseFunction.h: Removed.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Deleted.
+        (JSC::JSGlobalObject::visitChildren): Deleted.
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::boundSlotBaseFunctionStructure): Deleted.
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::getOwnPropertyDescriptor):
+        (JSC::getBoundSlotBaseFunctionForGetterSetter): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM): Deleted.
+        * runtime/VM.h:
+
+2015-07-01  Dean Jackson  <dino@apple.com>
+
+        Disable the experimental WebGL2 implementation
+        https://bugs.webkit.org/show_bug.cgi?id=146526
+        <rdar://problem/21641235>
+
+        Reviewed by Myles Maxfield.
+
+        Add (and disable) an ENABLE_WEBGL2 flag.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-07-01  Matthew Daiter  <mdaiter@apple.com>
+
+        Enable MEDIA_STREAM flag
+        https://bugs.webkit.org/show_bug.cgi?id=145947
+        <rdar://problem/21365829>
+
+        Reviewed by Eric Carlson.
+
+        * Configurations/FeatureDefines.xcconfig: Added MEDIA_STREAM flag
+
+2015-06-30  Andy VanWagoner  <thetalecrafter@gmail.com>
+
+        Implement ECMAScript Internationalization API
+        https://bugs.webkit.org/show_bug.cgi?id=90906
+
+        Reviewed by Benjamin Poulain.
+
+        * CMakeLists.txt: add IntlObject.cpp
+        * Configurations/FeatureDefines.xcconfig: add ENABLE_INTL flag
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: add IntlObject
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: add IntlObject
+        * JavaScriptCore.xcodeproj/project.pbxproj: add IntlObject
+        * runtime/CommonIdentifiers.h: add "Intl" name
+        * runtime/IntlObject.cpp: Added.
+        (JSC::IntlObject::IntlObject):
+        (JSC::IntlObject::create):
+        (JSC::IntlObject::finishCreation):
+        (JSC::IntlObject::createStructure):
+        * runtime/IntlObject.h: Added.
+        * runtime/JSGlobalObject.cpp: Add global Intl
+        (JSC::JSGlobalObject::init):
+
+2015-06-30  Basile Clement  <basile_clement@apple.com>
+
+        Allow object allocation sinking through GetScope, GetExecutable and SkipScope nodes
+        https://bugs.webkit.org/show_bug.cgi?id=146431
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isFunctionAllocation):
+        (JSC::DFG::Node::isPhantomFunctionAllocation):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPromoteHeapAccess.h:
+        (JSC::DFG::promoteHeapAccess):
+
+2015-06-30  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Reduce rendering frames "Other" time by instrumenting compositing
+        https://bugs.webkit.org/show_bug.cgi?id=146168
+
+        Reviewed by Brian Burg.
+
+        * inspector/protocol/Timeline.json:
+        New timeline record type for compositing events.
+
+2015-06-29  Dean Jackson  <dino@apple.com>
+
+        Temporarily disable PICTURE_SIZES
+        https://bugs.webkit.org/show_bug.cgi?id=146435
+        <rdar://problem/21087013>
+
+        Reviewed by Tim Horton.
+
+        Temporarily disable PICTURE_SIZES because it causes problems with out
+        of date <picture> polyfills.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-06-29  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        Binding generator should allow using JSC::Value for "any" parameter in lieu of ScriptValue
+        https://bugs.webkit.org/show_bug.cgi?id=146403
+
+        Reviewed by Darin Adler.
+
+        * bindings/ScriptValue.h: Added implicit conversion to JSC::JSValue.
+
+2015-06-28 Aleksandr Skachkov   <gskachkov@gmail.com>
+
+        [ES6] Implement ES6 arrow function syntax. No Line terminator between function parameters and =>
+        https://bugs.webkit.org/show_bug.cgi?id=146394
+
+        Reviewed by Yusuke Suzuki.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+
+2015-06-27  Darin Adler  <darin@apple.com>
+
+        Make converting JSString to StringView idiomatically safe
+        https://bugs.webkit.org/show_bug.cgi?id=146387
+
+        Reviewed by Anders Carlsson.
+
+        * jsc.cpp:
+        (functionPrint): Add explicit call to SafeView::get, needed since there
+        is no StringView temporary.
+        (functionDebug): Ditto.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::holesMustForwardToPrototype): Refactored into helper function.
+        (JSC::join): Refactored so that StringView is a function argument, making
+        the lifetime simpler.
+        (JSC::arrayProtoFuncJoin): Ditto.
+        (JSC::arrayProtoFuncReverse): Use new holesMustForwardToPrototype helper.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::encode): Add explicit call to SafeView::get.
+
+        * runtime/JSString.h: Moved declarations of functions to the top of the
+        file instead of mixing them in with the function definitions. Changed
+        return type of the view function to return a JSString::SafeView so that
+        the JSString's lifetime will last as long as the StringView does in
+        typical coding idioms.
+        (JSC::JSString::getIndex): Use unsafeView so we can index into the
+        view; could also have used view.get but here in this class this seems fine.
+        (JSC::JSRopeString::unsafeView): Renamed existing view function to this.
+        (JSC::JSString::unsafeView): Ditto.
+        (JSC::JSString::SafeView::SafeView): Contains reference to an ExecState
+        and a JSString. The ExecState is needed to create the StringView, and the
+        JSString needs to be kept alive as long as the StringView is.
+        (JSC::JSString::SafeView::operator StringView): Call unsafeView.
+        (JSC::JSString::SafeView::get): Convenience for when we want to call
+        StringView member functions.
+        (JSC::JSString::view): Added. Returns a SafeView.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncIndexOf): Add explicit call to SafeView::get.
+
+2015-06-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove ARMv7Assembler.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=146340
+
+        Reviewed by Filip Pizlo.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/ARMv7Assembler.cpp: Removed.
+
+2015-06-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Fix the !ENABLE(ES6_ARROWFUNCTION_SYNTAX) build after r185989
+        https://bugs.webkit.org/show_bug.cgi?id=146344
+
+        Reviewed by Yusuke Suzuki.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseSourceElements):
+
+2015-06-26 Aleksandr Skachkov  <gskachkov@gmail.com>
+
+         [ES6] Implement ES6 arrow function syntax. Parser of arrow function with execution as common function. 
+         https://bugs.webkit.org/show_bug.cgi?id=144955
+
+         Reviewed by Yusuke Suzuki.
+
+         Added support of ES6 arrow function. Changes were made according to following spec http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax. Patch does not include any arrow function specific behavior e.g. lexical bind this, arguments and etc.     
+        This patch implements the simplest cases of arrow function declaration:
+           parameters             () => 10 + 20
+           parameter               x => x + 20
+           parameters         (x, y) => x + y
+           function with block     x => { return x*10; }
+
+        Not implemented:
+           bind of the this, arguments, super and etc.
+           exception in case of trying to use 'new' with arrow function
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createArrowFunctionExpr):
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::setTokenPosition):
+        (JSC::Lexer<T>::lex):
+        * parser/Lexer.h:
+        (JSC::Lexer::lastTokenLocation):
+        (JSC::Lexer::setTerminator):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::parseSourceElements):
+        (JSC::Parser<LexerType>::parseArrowFunctionSingleExpressionBody):
+        (JSC::Parser<LexerType>::parseSwitchClauses):
+        (JSC::Parser<LexerType>::parseSwitchDefaultClause):
+        (JSC::Parser<LexerType>::parseBlockStatement):
+        (JSC::Parser<LexerType>::parseFunctionBody):
+        (JSC::stringForFunctionMode):
+        (JSC::Parser<LexerType>::parseFunctionParameters):
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass):
+        (JSC::Parser<LexerType>::parseAssignmentExpression):
+        (JSC::Parser<LexerType>::parsePropertyMethod):
+        (JSC::Parser<LexerType>::parseGetterSetter):
+        (JSC::Parser<LexerType>::parseArrowFunctionExpression):
+        * parser/Parser.h:
+        (JSC::Parser::locationBeforeLastToken):
+        (JSC::Parser::isEndOfArrowFunction):
+        (JSC::Parser::isArrowFunctionParamters):
+        (JSC::Parser::setEndOfStatement):
+        * parser/ParserFunctionInfo.h:
+        * parser/ParserTokens.h:
+        * parser/SourceCode.h:
+        (JSC::SourceCode::subArrowExpression):
+        * parser/SourceProviderCacheItem.h:
+        (JSC::SourceProviderCacheItem::endFunctionToken):
+        (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createArrowFunctionExpr):
+        (JSC::SyntaxChecker::setFunctionNameStart):
+
+2015-06-25  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support rest element in destructuring assignments
+        https://bugs.webkit.org/show_bug.cgi?id=146206
+
+        Reviewed by Oliver Hunt.
+
+        This patch enables rest element (...rest) in array binding patterns.
+        It generates array from the iterables.
+        In variable declarations and parameters, `[...identifier]` form is only allowed,
+        while expressions can take `[...[...rest]]` pattern.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::emitIteratorNext):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ArrayPatternNode::bindValue):
+        (JSC::ArrayPatternNode::toString):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::appendArrayPatternSkipEntry):
+        (JSC::ASTBuilder::appendArrayPatternEntry):
+        (JSC::ASTBuilder::appendArrayPatternRestEntry):
+        * parser/Nodes.h:
+        (JSC::ArrayPatternNode::appendIndex):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+        * tests/stress/rest-elements.js: Added.
+        (shouldBe):
+        (shouldThrow):
+
+2015-06-25  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r185956.
+        https://bugs.webkit.org/show_bug.cgi?id=146321
+
+        Causes massive crashes on test bots (Requested by bfulgham on
+        #webkit).
+
+        Reverted changeset:
+
+        "Enabling MEDIA_STREAM"
+        https://bugs.webkit.org/show_bug.cgi?id=145947
+        http://trac.webkit.org/changeset/185956
+
+2015-06-25  Michael Saboff  <msaboff@apple.com>
+
+        Minor fix to idx bounds check after 185954
+
+        Rubber Stamped by Ryosuke Niwa.
+
+        Changed "idx > 1" to "idx > 0" in two places.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::functionCallBase):
+
+2015-06-25  Keith Miller  <keith_miller@apple.com>
+
+        Address Sanitizer does not play well with memcpy in JSC::MachineThreads::tryCopyOtherThreadStack.
+        https://bugs.webkit.org/show_bug.cgi?id=146297
+
+        Reviewed by Filip Pizlo.
+
+        Since we cannot blacklist the system memcpy we must use our own naive implementation,
+        copyMemory. This is not a significant performance loss as tryCopyOtherThreadStack is
+        only called as part of an O(heapsize) operation. As the heap is generally much larger
+        than the stack the performance hit is minimal.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::copyMemory):
+        (JSC::MachineThreads::tryCopyOtherThreadStack):
+        (JSC::asanUnsafeMemcpy): Deleted.
+
+2015-06-25  Matthew Daiter  <mdaiter@apple.com>
+
+        Enabling MEDIA_STREAM
+        https://bugs.webkit.org/show_bug.cgi?id=145947
+        <rdar://problem/21365829>
+
+        Reviewed by Brent Fulgham.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-06-25  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (r181889): basspro.com hangs on load under JSC::ErrorInstance::finishCreation(JSC::ExecState*, JSC::VM&, WTF::String const&, bool) + 2801 (JavaScriptCore + 3560689)
+        https://bugs.webkit.org/show_bug.cgi?id=146298
+
+        Reviewed by Mark Lam.
+
+        We were underflowing in ExceptionHelpers.cpp::functionCallBase() with a right to left
+        string index.  Added checks that idx stays within the string.  Also added a termination
+        condition when idx is 0.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::functionCallBase):
+
+2015-06-24  Chris Dumez  <cdumez@apple.com>
+
+        Unreviewed, speculative build fix after r185942.
+
+        Add missing include for StrongInlines.h.
+
+        * runtime/ArrayPrototype.cpp:
+
+2015-06-24  Darin Adler  <darin@apple.com>
+
+        Optimize Array.join and Array.reverse for high speed array types
+        https://bugs.webkit.org/show_bug.cgi?id=146275
+
+        Reviewed by Mark Lam.
+
+        This seems to yield another 17% speed improvement in the array
+        test from the Peacekeeper benchmark.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::isHole): Added. Helper to check for holes.
+        (JSC::containsHole): Ditto.
+        (JSC::arrayProtoFuncJoin): Added special cases for the various types
+        of arrays that could be in a butterfly.
+        (JSC::arrayProtoFuncReverse): Ditto.
+
+        * runtime/JSStringJoiner.h: Made appendEmptyString public so we can
+        call it from the new parts of Array.join.
+
+2015-06-24  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::SpeculativeJIT shouldn't use filter==Contradiction when it meant isClear
+        https://bugs.webkit.org/show_bug.cgi?id=146291
+        rdar://problem/21435366
+
+        Reviewed by Michael Saboff.
+        
+        The filter() method returns Contradiction only when a value *becomes* clear. This is
+        necessary for supporting the convention that non-JSValue nodes have a bottom proved
+        type. (We should fix that convention eventually, but for now let's just be consistent
+        about it.)
+        
+        * dfg/DFGFiltrationResult.h: Document the issue.
+        * dfg/DFGSpeculativeJIT32_64.cpp: Work around the issue.
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        * dfg/DFGSpeculativeJIT64.cpp: Work around the issue.
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+
+2015-06-24  Michael Saboff  <msaboff@apple.com>
+
+        Crash on gog.com due to PolymorphicCallNode's having stale references to CallLinkInfo
+        https://bugs.webkit.org/show_bug.cgi?id=146285
+
+        Reviewed by Filip Pizlo.
+
+        CallLinkInfo's contain a RefPtr to a PolymorphicCallStubRoutine, named stub, which contains
+        a collection of PolymorphicCallNode.  Those PolymorphicCallNodes have a reference back to the
+        CallLinkInfo.  When a CallLinkInfo replaces or clears "stub", the ref count of the
+        PolymorphicCallStubRoutine is decremented as expected, but since it inherits from
+        GCAwareJITStubRoutine, it isn't actually deleted until GC.  In the mean time, the original
+        CallLinkInfo can go away.  If PolymorphicCallNode::unlink() is called at that point,
+        it will try to unlink a now deleted CallLinkInfo and crash as a result.
+
+        The fix is to clear the CallLinkInfo references from any PolymorphicCallNode objects when
+        when we set a new stub or clear an existing stub for a CallLinkInfo.  This is done by
+        calling PolymorphicCallNode::clearCallNodesFor() on the old stub.
+
+        The prior code would only call clearCallNodesFor() from the CallLinkInfo destructor.
+        This only took care of the last PolymorphicCallStubRoutine held in the CallLinkInfo.
+        Any prior PolymorphicCallStubRoutine would still have a, now bad, reference to the CallLinkInfo.
+
+        In the process I refactored CallLinkInfo from a struct to a class with proper accessors and
+        made all the data elements private.
+
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::clearStub): Updated to call PolymorphicCallStubRoutine::clearCallNodesFor()
+        to clear the back references to this CallLinkInfo.
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::~CallLinkInfo): Moved clearCallNodesFor() call to clearStub().
+        (JSC::CallLinkInfo::setStub): Clear any prior stub before changing to the new stub.
+
+2015-06-24  Michael Saboff  <msaboff@apple.com>
+
+        Refactor CallLinkInfo from a struct to a class
+        https://bugs.webkit.org/show_bug.cgi?id=146292
+
+        Rubber stamped by Filip Pizlo.
+
+        Refactored CallLinkInfo from a struct to a class with proper accessors and made all the
+        data elements private.
+
+        Done in preparation for fixing https://bugs.webkit.org/show_bug.cgi?id=146285.
+
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::clearStub):
+        (JSC::CallLinkInfo::unlink):
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::callTypeFor):
+        (JSC::CallLinkInfo::CallLinkInfo):
+        (JSC::CallLinkInfo::~CallLinkInfo):
+        (JSC::CallLinkInfo::specializationKindFor):
+        (JSC::CallLinkInfo::specializationKind):
+        (JSC::CallLinkInfo::isLinked):
+        (JSC::CallLinkInfo::setUpCall):
+        (JSC::CallLinkInfo::setCallLocations):
+        (JSC::CallLinkInfo::setUpCallFromFTL):
+        (JSC::CallLinkInfo::callReturnLocation):
+        (JSC::CallLinkInfo::hotPathBegin):
+        (JSC::CallLinkInfo::hotPathOther):
+        (JSC::CallLinkInfo::setCallee):
+        (JSC::CallLinkInfo::clearCallee):
+        (JSC::CallLinkInfo::callee):
+        (JSC::CallLinkInfo::setLastSeenCallee):
+        (JSC::CallLinkInfo::clearLastSeenCallee):
+        (JSC::CallLinkInfo::lastSeenCallee):
+        (JSC::CallLinkInfo::haveLastSeenCallee):
+        (JSC::CallLinkInfo::setStub):
+        (JSC::CallLinkInfo::stub):
+        (JSC::CallLinkInfo::seenOnce):
+        (JSC::CallLinkInfo::clearSeen):
+        (JSC::CallLinkInfo::setSeen):
+        (JSC::CallLinkInfo::hasSeenClosure):
+        (JSC::CallLinkInfo::setHasSeenClosure):
+        (JSC::CallLinkInfo::clearedByGC):
+        (JSC::CallLinkInfo::setCallType):
+        (JSC::CallLinkInfo::callType):
+        (JSC::CallLinkInfo::addressOfMaxNumArguments):
+        (JSC::CallLinkInfo::maxNumArguments):
+        (JSC::CallLinkInfo::offsetOfSlowPathCount):
+        (JSC::CallLinkInfo::setCalleeGPR):
+        (JSC::CallLinkInfo::calleeGPR):
+        (JSC::CallLinkInfo::slowPathCount):
+        (JSC::CallLinkInfo::setCodeOrigin):
+        (JSC::CallLinkInfo::codeOrigin):
+        (JSC::getCallLinkInfoCodeOrigin):
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        * bytecode/CallLinkStatus.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printCallOp):
+        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * ftl/FTLJSCallBase.cpp:
+        (JSC::FTL::JSCallBase::link):
+        * jit/AccessorCallJITStubRoutine.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        (JSC::JIT::compileOpCall):
+        * jit/JITOperations.cpp:
+        * jit/PolymorphicCallStubRoutine.cpp:
+        (JSC::PolymorphicCallNode::unlink):
+        (JSC::PolymorphicCallNode::clearCallLinkInfo):
+        * jit/PolymorphicCallStubRoutine.h:
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::linkSlowFor):
+        (JSC::linkFor):
+        (JSC::revertCall):
+        (JSC::unlinkFor):
+        (JSC::linkPolymorphicCall):
+        * jit/ThunkGenerators.cpp:
+        (JSC::virtualForThunkGenerator):
+
+2015-06-24  Doug Russell  <d_russell@apple.com>
+
+        Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject 
+        when posting a selection notification when on the border between two accessibilityObjects
+        https://bugs.webkit.org/show_bug.cgi?id=146177
+
+        Add an adopt() function to simplify JSRetainPtr<JSStringRef> { Adopt, string } to adopt(string).
+
+        Reviewed by Darin Adler.
+
+        * API/JSRetainPtr.h:
+        (adopt):
+
+2015-06-24  Keith Miller  <keith_miller@apple.com>
+
+        Strict Equality on objects should only check that one of the two sides is an object.
+        https://bugs.webkit.org/show_bug.cgi?id=145992
+
+        This patch adds a new optimization for checking strict equality on objects.
+        If we speculate that a strict equality comparison has an object on one side
+        we only need to type check that side. Equality is then determined by a pointer
+        comparison between the two values (although in the 32-bit case we must also check
+        that the other side is a cell). Once LICM hoists type checks out of a loop we
+        can be cleverer about how we choose the operand we type check if both are
+        speculated to be objects.
+
+        For testing I added the addressOf function, which returns the address
+        of a Cell to the runtime.
+
+        Reviewed by Mark Lam.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectStrictEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectStrictEquality):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectStrictEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectStrictEquality):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCompareStrictEq):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionAddressOf):
+        * tests/stress/equality-type-checking.js: Added.
+        (Foo):
+        (checkStrictEq):
+        (checkStrictEqOther):
+
+2015-06-24  Mark Lam  <mark.lam@apple.com>
+
+        Fixed assertion in JSStringJoiner::join() (regression from r185899).
+
+        Not reviewed.
+
+        JSStringJoiner did not account for the case where the array being joined can
+        have null or undefined elements.  As a result, its size may be less than
+        its initially reserved capacity (which was estimated based on the array length).
+
+        * runtime/JSStringJoiner.cpp:
+        (JSC::JSStringJoiner::join):
+
+2015-06-24  Darin Adler  <darin@apple.com>
+
+        Fix Array.concat with RuntimeArray (regression from my last patch)
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncConcat): Use getLength instead of JSArray::length.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::defineOwnProperty): Added comment about use of
+        JSArray::length here that is incorrect (in a really non-obvious way).
+        (JSC::JSArray::fillArgList): Ditto.
+        (JSC::JSArray::copyToArguments): Ditto.
+
+        * runtime/JSArray.h: Added a comment explaining that it is not always
+        safe to use JSArray::length.
+
+2015-06-23  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: Fixing 2 bad asserts from r185889.
+        https://bugs.webkit.org/show_bug.cgi?id=140575
+
+        Not reviewed.
+
+        * runtime/JSBoundSlotBaseFunction.cpp:
+        (JSC::JSBoundSlotBaseFunction::finishCreation):
+
+2015-06-23  Dan Bernstein  <mitz@apple.com>
+
+        Fixed iOS production builds.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-06-22  Darin Adler  <darin@apple.com>
+
+        Make Array.join work directly on substrings without reifying them
+        https://bugs.webkit.org/show_bug.cgi?id=146191
+
+        Reviewed by Andreas Kling.
+
+        Besides the Array.join change, this has other optimizations based on
+        profiling the Peacekeeper array benchmark.
+
+        I measured a 14% speed improvement in the Peacekeeper array benchmark.
+
+        Still a lot of low hanging fruit in that test because so many of functions
+        on the array prototype are not optimizing for simple cases. For example,
+        the reverse function does individual get and put calls even when the array
+        is entirely made up of integers in contiguous storage.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty): Use tryGetIndexQuickly first before getPropertySlot.
+        (JSC::argumentClampedIndexFromStartOrEnd): Marked inline.
+        (JSC::shift): Use the getProperty helper in this file instead of using
+        getPropertySlot. Use putByIndexInline instead of calling putByIndex directly.
+        In both cases this can yield a faster code path.
+        (JSC::unshift): Ditto.
+        (JSC::arrayProtoFuncToString): Updated to use the new JSStringJoiner
+        interface. Changed local variable name to thisArray since it's not a
+        JSObject*. Changed loop index to i instead of k.
+        (JSC::arrayProtoFuncToLocaleString): Updated to use the new JSStringJoiner
+        interface. Renamed thisObj to thisObject. Added a missing exception check
+        after the toLocaleString function is called, but before toString is called
+        the result of that function.
+        (JSC::arrayProtoFuncJoin): Updated to use the new JSStringJointer interface.
+        Added a missing exception check after calling toString on the separator
+        but before calling get to get the first element in the array-like object
+        being joined. Changed loop index to i instead of k. Added missing exception
+        check after calling toString on each string from the array before calling
+        get for the next element.
+        (JSC::arrayProtoFuncConcat): Use JSArray::length instead of using the
+        getLength function.
+        (JSC::arrayProtoFuncReverse): Ditto. Also use putByIndexInline.
+        (JSC::arrayProtoFuncShift): Ditto.
+        (JSC::arrayProtoFuncSplice): Use getIndex instead of get, which includes some
+        additional optimizations.
+        (JSC::getOrHole): Deleted. Unused function.
+        (JSC::arrayProtoFuncUnShift): Use putByIndexInline.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::errorDescriptionForValue): Removed the duplicate copy of the the logic
+        from JSValue::toString.
+
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::toStringSlowCase): Improved the performance when converting a
+        small integer to a single character string.
+        (JSC::JSValue::toWTFStringSlowCase): Moved the contents of the
+        inlineJSValueNotStringtoString function here.
+        * runtime/JSCJSValue.h: Removed no longer used toWTFStringInline and fixed
+        a comment with a typo.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::putByIndexInline): Marked ALWAYS_INLINE because this was not
+        getting inlined at some call sites.
+        (JSC::JSObject::indexingData): Deleted. Unused function.
+        (JSC::JSObject::currentIndexingData): Deleted. Unused function.
+        (JSC::JSObject::getHolyIndexQuickly): Deleted. Unused function.
+        (JSC::JSObject::relevantLength): Deleted. Unused function.
+        (JSC::JSObject::currentRelevantLength): Deleted. Unused function.
+
+        * runtime/JSString.h: Added the StringViewWithUnderlyingString struct and
+        the viewWithUnderlyingString function. Removed the inlineJSValueNotStringtoString
+        and toWTFStringInline functions.
+
+        * runtime/JSStringJoiner.cpp:
+        (JSC::appendStringToData): Changed this to be a template instead of writing
+        it out, since StringView::getCharactersWithUpconvert does almsot exactly what
+        this function was trying to do.
+        (JSC::joinStrings): Rewrote this to use StringView.
+        (JSC::JSStringJoiner::joinedLength): Added. Factored out from the join function.
+        (JSC::JSStringJoiner::join): Rewrote to make it a bit simpler. Added an assertion
+        that we entirely filled capacity, since we are now reserving capacity and using
+        uncheckedAppend. Use String instead of RefPtr<StringImpl> because there was no
+        particular value to using the impl directly.
+
+        * runtime/JSStringJoiner.h: Changed the interface to the class to use StringView.
+        Also changed this class so it now has the responsibility to convert each JSValue
+        into a string. This let us share more code between toString and join, and also
+        lets us use the new viewWithUnderlyingString function, which could be confusing at
+        all the call sites, but is easier to understand here.
+
+2015-06-23  Matthew Mirman  <mmirman@apple.com>
+
+        Completes native binding descriptors with native getters and potentially setters.
+        https://bugs.webkit.org/show_bug.cgi?id=140575
+        rdar://problem/19506502
+
+        Reviewed by Mark Lam.
+
+        * CMakeLists.txt:  Added JSBoundSlotBaseFunction.cpp
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/InjectedScriptSource.js: Added case for descriptor having a native getter.
+        * runtime/JSBoundSlotBaseFunction.cpp: Added.
+        (JSC::boundSlotBaseFunctionCall):
+        (JSC::JSBoundSlotBaseFunction::JSBoundSlotBaseFunction):  
+        Necessary wrapper for custom getters and setters as objects.
+        (JSC::JSBoundSlotBaseFunction::create):
+        (JSC::JSBoundSlotBaseFunction::visitChildren):
+        (JSC::JSBoundSlotBaseFunction::finishCreation):
+        * runtime/JSBoundSlotBaseFunction.h: Added.
+        (JSC::JSBoundSlotBaseFunction::createStructure):
+        (JSC::JSBoundSlotBaseFunction::boundSlotBase):
+        (JSC::JSBoundSlotBaseFunction::customGetterSetter):
+        (JSC::JSBoundSlotBaseFunction::isGetter):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Added a globally initialized structure for JSBoundSlotBaseFunction
+        (JSC::JSGlobalObject::visitChildren): visits that structure
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::boundSlotBaseFunctionStructure): added a getter for that structure
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::getOwnPropertyDescriptor): extends the case for CustomGetterSetter to 
+        actually include GetterSetter as a JSBoundSlotBaseFunction
+        * runtime/VM.cpp: Added initializer for customGetterSetterFunctionMap
+        * runtime/VM.h: Added cache for JSBoundSlotBaseFunction
+
+2015-06-22  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Allow trailing comma in ArrayBindingPattern and ObjectBindingPattern
+        https://bugs.webkit.org/show_bug.cgi?id=146192
+
+        Reviewed by Darin Adler.
+
+        According to the ES6 spec, trailing comma in ArrayBindingPattern and ObjectBindingPattern is allowed.
+        And empty ArrayBindingPattern and ObjectBindingPattern is also allowed.
+
+        This patch allows trailing comma and empty binding patterns.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ArrayPatternNode::bindValue):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        * tests/stress/trailing-comma-in-patterns.js: Added.
+        (shouldBe):
+        (iterator):
+
+2015-06-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Destructuring assignment need to accept iterables
+        https://bugs.webkit.org/show_bug.cgi?id=144111
+
+        Reviewed by Darin Adler.
+
+        This patch makes that destructuring assignments to array binding patterns accept iterables.
+        Previously, it just access the indexed properties.
+        After this patch, it iterates the given value by using ES6 iterator protocol.
+
+        The iteration becomes different from the for-of case.
+        1. Since there's no break/continue case, finally scope is not necessary.
+        2. When the error is raised, the close status of the iterator becomes true. So IteratorClose is not called for that.
+        3. Since the array binding patterns requires a limited count of iterations (if there is no rest(...rest) case), IteratorClose is called when the iteration does not consume the all values of the iterator.
+        4. Since the array binding patterns requires a specified count of iterations, iterator's next call is skipped when iterator becomes closed.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitIteratorClose):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ArrayPatternNode::bindValue):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::finishArrayPattern):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+        * tests/stress/destructuring-assignment-accepts-iterables.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (.set shouldThrow):
+
+2015-06-19  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Highlight currently edited CSS selector
+        https://bugs.webkit.org/show_bug.cgi?id=145658
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/DOM.json: Added highlightSelector to show highlight over multiple nodes.
+
+2015-06-19  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix build for EWS bots.
+
+        Not reviewed.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLengthWithArrayStorage):
+
+2015-06-19  Michael Saboff  <msaboff@apple.com>
+
+        Crash in com.apple.WebKit.WebContent at com.apple.JavaScriptCore: JSC::FTL::fixFunctionBasedOnStackMaps + 17225
+        https://bugs.webkit.org/show_bug.cgi?id=146133
+
+        Reviewed by Geoffrey Garen.
+
+        When generating code to put in inline caching areas, if there isn't enough space,
+        then create and link to an out of line area.  We connect the inline code to this
+        out of line code area by planting a jump from the inline area to the out of line
+        code and appending a jump at the end of the out of line code bck to the instruction
+        following the inline area.  We fill the unused inline area with nops, primarily to 
+        ensure the disassembler doesn't get confused.
+
+        * ftl/FTLCompile.cpp:
+        (generateInlineIfPossibleOutOfLineIfNot): New function that determines if there is enough space
+        in the inline code area for the code to link.  If so, it links inline, otherwise it links the
+        code out of line and plants appropriate jumps to/from the out of line code.
+        (generateICFastPath):
+        (generateCheckInICFastPath):
+        (fixFunctionBasedOnStackMaps):
+        Use generateInlineIfPossibleOutOfLineIfNot() to link code intended for inline cache space.
+
+        * ftl/FTLJITFinalizer.cpp:
+        (JSC::FTL::JITFinalizer::finalizeFunction):
+        * ftl/FTLJITFinalizer.h:
+        (JSC::FTL::OutOfLineCodeInfo::OutOfLineCodeInfo):
+        Added code to finalize any out of line LinkBuffer created by generateInlineIfPossibleOutOfLineIfNot().
+
+2015-06-19  Geoffrey Garen  <ggaren@apple.com>
+
+        WebKit crash while loading nytimes at JavaScriptCore: JSC::ExecutableAllocator::allocate + 276
+        https://bugs.webkit.org/show_bug.cgi?id=146163
+        <rdar://problem/20392986>
+
+        Reviewed by Michael Saboff.
+
+        There's no good way to test this in our test harness because we don't
+        have a way to simulate executable memory pressure, and doing so would
+        cause the cases that still use JITCompilationMustSucceed to crash.
+
+        Instead, I tested by manually forcing all regexp JIT compilation to
+        fail and running the JavaScriptCore tests.
+
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::compile): Allow compilation to fail. We can
+        fall back to the regexp interpreter if we need to.
+
+2015-06-19  Mark Lam  <mark.lam@apple.com>
+
+        Employ explicit operator bool() instead of using the UnspecifiedBoolType workaround.
+        https://bugs.webkit.org/show_bug.cgi?id=146154
+
+        Reviewed by Darin Adler.
+
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::MacroAssemblerCodePtr::dataLocation):
+        (JSC::MacroAssemblerCodePtr::operator bool):
+        (JSC::MacroAssemblerCodePtr::operator==):
+        (JSC::MacroAssemblerCodeRef::tryToDisassemble):
+        (JSC::MacroAssemblerCodeRef::operator bool):
+        (JSC::MacroAssemblerCodeRef::dump):
+        (JSC::MacroAssemblerCodePtr::operator UnspecifiedBoolType*): Deleted.
+        (JSC::MacroAssemblerCodeRef::operator UnspecifiedBoolType*): Deleted.
+
+        * bytecode/CodeOrigin.cpp:
+        (JSC::CodeOrigin::isApproximatelyEqualTo):
+        - Fixed a bug here where we were expecting to compare Executable pointers, but
+          ended up comparing a (UnspecifiedBoolType*)1 with another
+          (UnspecifiedBoolType*)1.
+
+        * bytecode/LLIntCallLinkInfo.h:
+        (JSC::LLIntCallLinkInfo::~LLIntCallLinkInfo):
+        (JSC::LLIntCallLinkInfo::isLinked):
+        (JSC::LLIntCallLinkInfo::unlink):
+        * dfg/DFGBlockWorklist.h:
+        (JSC::DFG::BlockWith::BlockWith):
+        (JSC::DFG::BlockWith::operator bool):
+        (JSC::DFG::BlockWithOrder::BlockWithOrder):
+        (JSC::DFG::BlockWithOrder::operator bool):
+        (JSC::DFG::BlockWith::operator UnspecifiedBoolType*): Deleted.
+        (JSC::DFG::BlockWithOrder::operator UnspecifiedBoolType*): Deleted.
+        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
+        * dfg/DFGLazyNode.h:
+        (JSC::DFG::LazyNode::operator!):
+        (JSC::DFG::LazyNode::operator bool):
+        (JSC::DFG::LazyNode::operator UnspecifiedBoolType*): Deleted.
+        * heap/CopyWriteBarrier.h:
+        (JSC::CopyWriteBarrier::operator!):
+        (JSC::CopyWriteBarrier::operator bool):
+        (JSC::CopyWriteBarrier::get):
+        (JSC::CopyWriteBarrier::operator UnspecifiedBoolType*): Deleted.
+        * heap/Handle.h:
+        (JSC::HandleBase::operator!):
+        (JSC::HandleBase::operator bool):
+        (JSC::HandleBase::slot):
+        (JSC::HandleBase::operator UnspecifiedBoolType*): Deleted.
+        * heap/Strong.h:
+        (JSC::Strong::operator!):
+        (JSC::Strong::operator bool):
+        (JSC::Strong::swap):
+        (JSC::Strong::operator UnspecifiedBoolType*): Deleted.
+        * jit/JITWriteBarrier.h:
+        (JSC::JITWriteBarrierBase::operator bool):
+        (JSC::JITWriteBarrierBase::operator!):
+        (JSC::JITWriteBarrierBase::setFlagOnBarrier):
+        (JSC::JITWriteBarrierBase::operator UnspecifiedBoolType*): Deleted.
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLengthWithArrayStorage):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::JSValue):
+        (JSC::JSValue::operator bool):
+        (JSC::JSValue::operator==):
+        (JSC::JSValue::operator UnspecifiedBoolType*): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::hasSparseMap):
+        * runtime/PropertyDescriptor.h:
+        (JSC::PropertyDescriptor::writablePresent):
+        (JSC::PropertyDescriptor::enumerablePresent):
+        (JSC::PropertyDescriptor::configurablePresent):
+        (JSC::PropertyDescriptor::setterPresent):
+        (JSC::PropertyDescriptor::getterPresent):
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase::slot):
+        (JSC::WriteBarrierBase::operator bool):
+        (JSC::WriteBarrierBase::operator!):
+        (JSC::WriteBarrierBase<Unknown>::tagPointer):
+        (JSC::WriteBarrierBase<Unknown>::payloadPointer):
+        (JSC::WriteBarrierBase<Unknown>::operator bool):
+        (JSC::WriteBarrierBase<Unknown>::operator!):
+        (JSC::WriteBarrierBase::operator UnspecifiedBoolType*): Deleted.
+        (JSC::WriteBarrierBase<Unknown>::operator UnspecifiedBoolType*): Deleted.
+
+2015-06-19  Anders Carlsson  <andersca@apple.com>
+
+        Add a JSC symlink in /System/Library/PrivateFrameworks
+        https://bugs.webkit.org/show_bug.cgi?id=146158
+        rdar://problem/21465968
+
+        Reviewed by Dan Bernstein.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-06-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Avoid getOwnPropertyNames/Symbols on very large lists
+        https://bugs.webkit.org/show_bug.cgi?id=146141
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.prototype._propertyDescriptors):
+        Avoid calling getOwnPropertyNames/Symbols on very large lists. Instead
+        just generate property descriptors for the first 100 indexes. Note
+        this would behave poorly for sparse arrays with a length > 100, but
+        general support for lists with more than 100 elements is poor. See:
+        <https://webkit.org/b/143589> Web Inspector: Better handling for large collections in Object Trees
+
+2015-06-18  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [DFG] Avoid OSR exit in the middle of string concatenation
+        https://bugs.webkit.org/show_bug.cgi?id=145820
+
+        Reviewed by Filip Pizlo.
+
+        DFG attempt to compile ValueAdd with String type into MakeRope(left, ToString(ToPrimitive(right))).
+
+        So when right is speculated as SpecObject, ToPrimitive(SpecObject) is speculated as SpecString.
+        It leads ToString to become Identity with a speculated type check.
+
+        However, ToPrimitive and ToString are originated from the same bytecode. And ToPrimitive may have
+        an observable side effect when the given parameter is an object (calling object.{toString,valueOf}).
+
+        So when object.toString() returns a number (it is allowed in the ES spec), ToPrimitive performs
+        observable `object.toString()` calling. But ToString is converted into a speculated type check for
+        SpecString and it raises OSR exit. And we exit to the original ValueAdd's bytecode position and
+        it redundantly performs an observable ToPrimitive execution.
+
+        To fix this, this patch avoid fixing up for newly introduced ToString node.
+        Since fix up phase is not iterated repeatedly, by avoiding fixing up when generating the node,
+        we can avoid conversion from ToString to Check.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+        * tests/stress/toprimitive-speculated-types.js: Added.
+        (shouldBe):
+        (raw):
+        (Counter):
+
+2015-06-18  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: improve generated types for objects passed to backend commands
+        https://bugs.webkit.org/show_bug.cgi?id=146091
+
+        Reviewed by Joseph Pecoraro.
+
+        The main change is that objects passed in will have a type like const T& or const T*,
+        rather than const RefPtr<T>&&. These protocol objects are owned by the generated dispatcher
+        methods and only exist to pass data to backend command implementations. So, there is no
+        reason for callees to add a reference or take ownership of these inputs.
+
+        Some small improvements were made in the code generator to standardize how these
+        expressions are generated for parameters. Optional in parameters are now prefixed with
+        'opt_in_' to make the generated method signatures and implementations clearer.
+
+        * inspector/InspectorValues.cpp:
+        (Inspector::InspectorArrayBase::get): Add const qualifier.
+        * inspector/InspectorValues.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::parseLocation):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::continueToLocation):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        (Inspector::InspectorRuntimeAgent::saveResult):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * inspector/agents/InspectorRuntimeAgent.h:
+
+        * inspector/scripts/codegen/cpp_generator.py: Always generate PrimitiveType('array').
+        (CppGenerator.cpp_type_for_unchecked_formal_in_parameter): Alter the type signature
+        for an unchecked input to use pointers or references.
+
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
+        (CppBackendDispatcherHeaderGenerator._generate_handler_declaration_for_command):
+        (CppBackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        Local variables for optional parameters now have the 'opt_' prefix.
+
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator._generate_async_dispatcher_class_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        Local variables for optional parameters now have the 'opt_' prefix.
+        Split parameterName and parameterKey into two separate template variables to avoid mixups.
+
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+
+2015-06-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed. Rollout r185670 as it caused some tests to be flakey.
+
+        * debugger/Debugger.cpp:
+
+2015-06-17  Alex Christensen  <achristensen@webkit.org>
+
+        [Content Extensions] Log blocked loads to the WebInspector console
+        https://bugs.webkit.org/show_bug.cgi?id=146089
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::messageSourceValue):
+        * inspector/protocol/Console.json:
+        * runtime/ConsoleTypes.h:
+        Add content blocker message source.
+
+2015-06-18  Saam Barati  <saambarati1@gmail.com>
+
+        [ES6] support default values in deconstruction parameter nodes
+        https://bugs.webkit.org/show_bug.cgi?id=142679
+
+        Reviewed by Darin Adler.
+
+        ES6 destructuring allows destructuring properties to assign 
+        default values. A link to the spec: 
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns
+
+        This patch implements default values for all places where deconstruction
+        is allowed besides function parameters. This is because function
+        parameters are parsed in a separate parser arena than the function
+        body itself and ExpresionNode's which are default values for
+        deconstruction parameters will be deallocated by the time we parse the body
+        of the function. I have opened a bug to address this problem:
+        https://bugs.webkit.org/show_bug.cgi?id=145995
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::DeconstructionPatternNode::~DeconstructionPatternNode):
+        (JSC::assignDefaultValueIfUndefined):
+        (JSC::ArrayPatternNode::bindValue):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        (JSC::ArrayPatternNode::toString):
+        (JSC::ArrayPatternNode::collectBoundIdentifiers):
+        (JSC::ObjectPatternNode::bindValue):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::appendArrayPatternSkipEntry):
+        (JSC::ASTBuilder::appendArrayPatternEntry):
+        (JSC::ASTBuilder::createObjectPattern):
+        (JSC::ASTBuilder::appendObjectPatternEntry):
+        (JSC::ASTBuilder::createBindingLocation):
+        * parser/Nodes.h:
+        (JSC::ArrayPatternNode::appendIndex):
+        (JSC::ObjectPatternNode::appendEntry):
+        (JSC::ObjectPatternNode::Entry::Entry): Deleted.
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        (JSC::Parser<LexerType>::parseDefaultValueForDeconstructionPattern):
+        (JSC::Parser<LexerType>::parseConstDeclarationList):
+        * parser/Parser.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+
+2015-06-17  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Do not show JavaScriptCore builtins in inspector
+        https://bugs.webkit.org/show_bug.cgi?id=146049
+
+        Reviewed by Timothy Hatcher.
+
+        * debugger/Debugger.cpp:
+
+2015-06-17  Andreas Kling  <akling@apple.com>
+
+        [JSC] jsSubstring() should have a fast path for 0..baseLength "substrings."
+        <https://webkit.org/b/146051>
+
+        Reviewed by Anders Carlsson.
+
+        If asked to make a substring that actually spans the entire base string,
+        have jsSubstring() just return the base instead of allocating a new JSString.
+
+        3% speed-up on Octane/regexp.
+
+        * runtime/JSString.h:
+        (JSC::jsSubstring):
+
+2015-06-16  Alex Christensen  <achristensen@webkit.org>
+
+        32-bit build fix after r185640.
+
+        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
+        Explicitly cast clamped int64_t to an int.
+
+2015-06-09  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should eliminate array bounds checks in loops
+        https://bugs.webkit.org/show_bug.cgi?id=145768
+
+        Reviewed by Benjamin Poulain.
+        
+        This adds a phase that does forward propagation of integer inequalities. This allows us
+        to do the algebraic reasoning we need to eliminate array bounds checks in loops. It
+        also eliminates overflow checks on ArithAdd with a constant.
+        
+        The phase's analysis produces results that are powerful enough to do speculative bounds
+        check hoisting, but this phase currently only does elimination. We can implement
+        hoisting later.
+        
+        On programs that just loop over an array like:
+        
+            for (var i = 0; i < array.length; ++i)
+                thingy += array[i]
+        
+        This change is a 60% speed-up.
+        
+        This is also a ~3% speed-up on Kraken, and it shows various speed-ups on individual
+        tests in Octane.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGIntegerRangeOptimizationPhase.cpp: Added.
+        (JSC::DFG::performIntegerRangeOptimization):
+        * dfg/DFGIntegerRangeOptimizationPhase.h: Added.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * tests/stress/add-overflows-after-not-equal.js: Added.
+        * tests/stress/no-abc-skippy-loop.js: Added.
+        * tests/stress/no-abc-skippy-paired-loop.js: Added.
+        * tests/stress/sub-overflows-after-not-equal.js: Added.
+
+2015-06-16  Andreas Kling  <akling@apple.com>
+
+        Remove unused template parameter InlineCapacity from SegmentedVector.
+        <https://webkit.org/b/146044>
+
+        Reviewed by Anders Carlsson.
+
+        * bytecode/ArrayProfile.h:
+        * dfg/DFGCommonData.h:
+
+2015-06-16  Michael Saboff  <msaboff@apple.com>
+
+        Inlining in the DFG trashes ByteCodeParser::m_currentInstruction for the calling function
+        https://bugs.webkit.org/show_bug.cgi?id=146029
+
+        Reviewed by Benjamin Poulain.
+
+        Save and restore m_currentInstruction around call to ByteCodeParser::inlineCall() as it will
+        use m_currentInstruction during its own parsing.  This happens because inlineCall() parses the
+        inlined callee's bytecodes by calling parseCodeBlock() which calls parseBlock() on each block.
+        It is in parseBlock() that we set m_currentInstruction to an instruction before we parse it.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::parseBlock): Added an ASSERT to catch this issue.
+
+2015-06-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out unintended JSC change from https://trac.webkit.org/changeset/185425.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::hasExitSite):
+        (JSC::CodeBlock::exitProfile):
+        (JSC::CodeBlock::numberOfExitSites): Deleted.
+        * bytecode/DFGExitProfile.cpp:
+        (JSC::DFG::ExitProfile::add):
+        * bytecode/DFGExitProfile.h:
+        (JSC::DFG::ExitProfile::hasExitSite):
+        (JSC::DFG::ExitProfile::size): Deleted.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        * runtime/Options.h:
+
+2015-06-16  Mark Lam  <mark.lam@apple.com>
+
+        Use NakedPtr<Exception>& to return exception results.
+        https://bugs.webkit.org/show_bug.cgi?id=145870
+
+        Reviewed by Anders Carlsson and Filip Pizlo.
+
+        Before r185259, calls into the VM takes a JSValue* exception result argument for
+        returning any uncaught exception that may have been thrown while executing JS code.
+        As a result, clients of the VM functions will declare a local JSValue exception
+        result which is automatically initialized to a null value (i.e. the empty value,
+        not the JS null value).
+
+        With r185259, the VM functions were changed to take an Exception*& exception result
+        instead, and the VM functions are responsible for initializing the exception result
+        to null if no exception is thrown.
+
+        This introduces 2 issues:
+
+        1. the VM functions are vulnerable to modifications that may add early returns
+           before the exception result is nullified.  This can result in the exception
+           result being used without initialization.
+
+        2. Previously, a client could technically use the same exception result for more
+           than one calls into the VM functions.  If an earlier call sets it to a thrown
+           value, the thrown value will stick unless a subsequent call throws a different
+           exception.
+
+           With the new Exception*& exception result, the VM functions will always clear
+           the exception result before proceeding.  As a result, the client's exception
+           result will be null after the second call even though the first call saw an
+           exception thrown.  This is a change in the expected behavior.
+
+        To fix these issues, we'll introduce a NakedPtr smart pointer whose sole purpose
+        is to guarantee that the pointer is initialized.  The VM functions will now take
+        a NakedPtr<Exception>& instead of the Exception*&.  This ensures that the
+        exception result is initialized.
+
+        The VM functions be also reverted to only set the exception result if a new
+        exception is thrown.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        * API/JSScriptRef.cpp:
+        * bindings/ScriptFunctionCall.cpp:
+        (Deprecated::ScriptFunctionCall::call):
+        * bindings/ScriptFunctionCall.h:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::hasBreakpoint):
+        * debugger/Debugger.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::thisValue):
+        (JSC::DebuggerCallFrame::evaluate):
+        * debugger/DebuggerCallFrame.h:
+        (JSC::DebuggerCallFrame::isValid):
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::createInjectedScript):
+        * inspector/InspectorEnvironment.h:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::evaluate):
+        * inspector/JavaScriptCallFrame.h:
+        (Inspector::JavaScriptCallFrame::vmEntryGlobalObject):
+        (Inspector::JavaScriptCallFrame::thisValue):
+        (Inspector::JavaScriptCallFrame::evaluate):
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::evaluateBreakpointAction):
+        * jsc.cpp:
+        (functionRun):
+        (functionLoad):
+        (runWithScripts):
+        (runInteractive):
+        * runtime/CallData.cpp:
+        (JSC::call):
+        * runtime/CallData.h:
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        (JSC::evaluate):
+        * runtime/Completion.h:
+        (JSC::evaluate):
+
+2015-06-15  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL boolify() UntypedUse is wrong in the masquerades-as-undefined case
+        https://bugs.webkit.org/show_bug.cgi?id=146002
+
+        Reviewed by Darin Adler.
+
+        * ftl/FTLLowerDFGToLLVM.cpp: Put this in an anonymous namespace. We should have done that all along. It makes it easier to add debug code.
+        (JSC::FTL::DFG::LowerDFGToLLVM::boolify): Fix the bug.
+        * tests/stress/logical-not-masquerades.js: Added. This test creates a masquerader so that the watchpoint is invalid. Previously this would fail for the normal object cases.
+        (foo):
+
+2015-06-16  Andreas Kling  <akling@apple.com>
+
+        [JSC] Pre-bake final Structure for RegExp matches arrays.
+        <https://webkit.org/b/146006>
+
+        Reviewed by Darin Adler.
+
+        Since we always add the "index" and "input" fields to RegExp matches arrays,
+        cache a finished structure on the global object so we can create these arrays without
+        starting from scratch with a bare array every time.
+
+        10% progression on Octane/regexp (on my MBP.)
+
+        * runtime/JSArray.h:
+        (JSC::JSArray::create):
+        (JSC::JSArray::tryCreateUninitialized):
+        (JSC::JSArray::createWithButterfly): Factored out JSArray construction into a helper
+        so we can call this from RegExpMatchesArray.cpp.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure): Add a cached Structure for RegExp
+        subpattern matches arrays.
+
+        * runtime/JSObject.h:
+        (JSC::JSNonFinalObject::finishCreation): Tweak assertion that used to check that
+        JSNonFinalObjects always start out with zero capacity. Since RegExp matches arrays now
+        start out with capacity for 2 properties, that won't work. Change it to check that we
+        don't have inline storage instead, since that should only be used by final objects.
+
+        * runtime/RegExpMatchesArray.h:
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::tryCreateUninitializedRegExpMatchesArray): Helper to construct a JSArray with
+        the cached Structure and a Butterfly with 2 slots of property storage.
+
+        (JSC::createRegExpMatchesArray):
+        (JSC::createRegExpMatchesArrayStructure): Creates the array Structure that gets cached
+        by the JSGlobalObject.
+
+2015-06-16  Saam Barati  <saambarati1@gmail.com>
+
+        LLInt's code path for get_from_scope with case GlobalVarWithVarInjectionChecks has dead code
+        https://bugs.webkit.org/show_bug.cgi?id=144268
+
+        Reviewed by Darin Adler.
+
+        The call to loadVariable(.) both for 32bit and 64bit is unnecessary. 
+        It grabs a value that is immediately overwritten by a call to getGlobalVar(). 
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2015-06-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Introduce %IteratorPrototype% and drop all XXXIteratorConstructor
+        https://bugs.webkit.org/show_bug.cgi?id=145963
+
+        Reviewed by Darin Adler.
+
+        ES6 iterators inherit %IteratorPrototype%.
+        And these prototype objects of derived iterators don't have @@iterator methods.
+        Instead they use the %IteratorPrototype%[@@iterator] method.
+
+        To encourage inlining in for-of statement, we define this method in JS builtins.
+
+        And these iterator prototype objects don't have any constructor function.
+        This patch drops them (like StringIteratorConstructor).
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/Iterator.prototype.js: Renamed from Source/JavaScriptCore/runtime/StringIteratorConstructor.cpp.
+        (SymbolIterator):
+        * runtime/ArrayIteratorConstructor.cpp:
+        (JSC::ArrayIteratorConstructor::finishCreation): Deleted.
+        * runtime/ArrayIteratorConstructor.h: Removed.
+        (JSC::ArrayIteratorConstructor::create): Deleted.
+        (JSC::ArrayIteratorConstructor::createStructure): Deleted.
+        (JSC::ArrayIteratorConstructor::ArrayIteratorConstructor): Deleted.
+        * runtime/ArrayIteratorPrototype.cpp:
+        (JSC::ArrayIteratorPrototype::finishCreation):
+        (JSC::arrayIteratorProtoFuncIterator): Deleted.
+        * runtime/IteratorPrototype.cpp: Renamed from Source/JavaScriptCore/runtime/ArrayIteratorConstructor.cpp.
+        (JSC::IteratorPrototype::finishCreation):
+        * runtime/IteratorPrototype.h: Renamed from Source/JavaScriptCore/runtime/SetIteratorConstructor.h.
+        (JSC::IteratorPrototype::create):
+        (JSC::IteratorPrototype::createStructure):
+        (JSC::IteratorPrototype::IteratorPrototype):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::createBuiltinFunction):
+        * runtime/JSFunction.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::iteratorPrototype):
+        * runtime/MapIteratorConstructor.cpp: Removed.
+        (JSC::MapIteratorConstructor::finishCreation): Deleted.
+        * runtime/MapIteratorConstructor.h: Removed.
+        (JSC::MapIteratorConstructor::create): Deleted.
+        (JSC::MapIteratorConstructor::createStructure): Deleted.
+        (JSC::MapIteratorConstructor::MapIteratorConstructor): Deleted.
+        * runtime/MapIteratorPrototype.cpp:
+        (JSC::MapIteratorPrototype::finishCreation): Deleted.
+        (JSC::MapIteratorPrototypeFuncIterator): Deleted.
+        * runtime/SetIteratorConstructor.cpp: Removed.
+        (JSC::SetIteratorConstructor::finishCreation): Deleted.
+        * runtime/SetIteratorConstructor.h:
+        (JSC::SetIteratorConstructor::create): Deleted.
+        (JSC::SetIteratorConstructor::createStructure): Deleted.
+        (JSC::SetIteratorConstructor::SetIteratorConstructor): Deleted.
+        * runtime/SetIteratorPrototype.cpp:
+        (JSC::SetIteratorPrototype::finishCreation): Deleted.
+        (JSC::SetIteratorPrototypeFuncIterator): Deleted.
+        * runtime/StringIteratorConstructor.cpp:
+        (JSC::StringIteratorConstructor::finishCreation): Deleted.
+        * runtime/StringIteratorConstructor.h: Removed.
+        (JSC::StringIteratorConstructor::create): Deleted.
+        (JSC::StringIteratorConstructor::createStructure): Deleted.
+        (JSC::StringIteratorConstructor::StringIteratorConstructor): Deleted.
+        * runtime/StringIteratorPrototype.cpp:
+        (JSC::StringIteratorPrototype::finishCreation):
+        (JSC::stringIteratorPrototypeIterator): Deleted.
+        * tests/stress/iterator-prototype.js: Added.
+        (shouldBe):
+        (inheritIteratorPrototype):
+        (testChain):
+
+2015-06-15  Michael Saboff  <msaboff@apple.com>
+
+        JIT bug - fails when inspector closed, works when open
+        https://bugs.webkit.org/show_bug.cgi?id=145243
+
+        Reviewed by Oliver Hunt.
+
+        We need to provide the Arguments object as the base when creating the HeapLocation for
+        GetFromArguments and PutToArguments.  Otherwise we endup creating a HeapLocation for
+        any arguments object, not the one we need.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
+2015-06-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: console.table() with a list of objects no longer works
+        https://bugs.webkit.org/show_bug.cgi?id=145952
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.RemoteObject.prototype._generatePreview):
+        Calling generatePreview again was actually starting with a preview
+        of the current object instead of the sub-value. Go down the other
+        path that correctly generates sub-previews. Leave filtering on the
+        backend unimplemented, which we were already ignoring.
+
+2015-06-13  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] ReadableJSStream should handle promises returned by JS source start callback
+        https://bugs.webkit.org/show_bug.cgi?id=145792
+
+        Reviewed by Darin Adler.
+
+        Added support for JSFunction implemented by std::function.
+
+        * runtime/JSFunction.cpp:
+        (JSC::getNativeExecutable): Refactored code to share it with the two JSFunction::create
+        (JSC::JSFunction::create):
+        (JSC::runStdFunction):
+        * runtime/JSFunction.h: Added std::function based JSFunction::create prototype.
+        * runtime.JSPromise.h:
+
+2015-06-12  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
+
+        Purge PassRefPtr in JavaScriptCore - 2
+        https://bugs.webkit.org/show_bug.cgi?id=145834
+
+        Reviewed by Darin Adler.
+
+        As a step to remove PassRefPtr, this patch cleans up PassRefPtr as much as possible
+        in JavaScriptCore.
+
+        * API/JSClassRef.cpp:
+        (OpaqueJSClass::create):
+        * API/JSClassRef.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::callerFrame):
+        * debugger/DebuggerCallFrame.h:
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::jitCode):
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::createScriptCallStack):
+        (Inspector::createScriptCallStackForConsole):
+        (Inspector::createScriptCallStackFromException):
+        (Inspector::createScriptArguments):
+        * inspector/ScriptCallStackFactory.h:
+        * jit/ExecutableAllocator.cpp:
+        (JSC::ExecutableAllocator::allocate):
+        * jit/ExecutableAllocator.h:
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+        (JSC::ExecutableAllocator::allocate):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::stopProfiling):
+        * profiler/LegacyProfiler.h:
+        * runtime/DateInstanceCache.h:
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        * runtime/Executable.h:
+        * runtime/GenericTypedArrayView.h:
+        * runtime/GenericTypedArrayViewInlines.h:
+        (JSC::GenericTypedArrayView<Adaptor>::create):
+        (JSC::GenericTypedArrayView<Adaptor>::createUninitialized):
+
+2015-06-12  Darin Adler  <darin@apple.com>
+
+        Fix minor ES6 compliance issue in RegExp.prototype.toString and optimize performance a little
+        https://bugs.webkit.org/show_bug.cgi?id=145935
+
+        Reviewed by Anders Carlsson.
+
+        Test: js/regexp-toString.html
+
+        * runtime/RegExpPrototype.cpp:
+        (JSC::getFlags): Avoid memory allocation for the flags string by returning it in a character
+        buffer instead of constructing a WTF::String for it.
+        (JSC::regExpProtoFuncToString): Require only that the this value be an object; don't require
+        that it is actually a regular expression object. This is covered in the ES6 specification.
+        Also removed comment about the "/(?:)/" trick since that is now the repsonsibility of the
+        getter for the "source" property. Updated to use getFlags so we do one less memory allocation.
+        (JSC::regExpProtoGetterFlags): Chagned to use getFlags instead of the old flagsString.
+
+2015-06-12  Basile Clement  <basile_clement@apple.com>
+
+        DFG Object Allocation Sinking should not consider GetClosureVar as escapes
+        https://bugs.webkit.org/show_bug.cgi?id=145904
+
+        Reviewed by Filip Pizlo.
+
+        The object allocation sinking phase is currently able to sink
+        CreateActivation nodes, but will consider any GetClosureVar node as
+        escaping.
+
+        This is not problematic in general as most of the GetClosureVar nodes
+        we would have been able to sink over will have been eliminated by CSE
+        anyway. Still, this is an oversight that we should fix since the
+        machinery is already in place.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPromoteHeapAccess.h:
+        (JSC::DFG::promoteHeapAccess):
+
+2015-06-11  Mark Lam  <mark.lam@apple.com>
+
+        WebCore::reportException() needs to be able to accept a raw thrown value in addition to Exception objects.
+        https://bugs.webkit.org/show_bug.cgi?id=145872
+
+        Reviewed by Michael Saboff.
+
+        In r185259, we changed exception handling code inside the VM to work with
+        Exception objects instead of the thrown JSValue.  The handling code will get the
+        exception stack trace from the Exception object.
+
+        However, there is some code that cannot be updated to pass the Exception object.
+        An example of this are the ObjC API functions.  Those functions are specified to
+        return any thrown exception JSValue in a JSValueRef.  Since these APIs are
+        public, we cannot arbitrarily change them to use the Exception object.
+
+        There are client code that calls these APIs and then passes the returned exception
+        JSValue to WebCore::reportException() to be reported.  WebCore::reportException()
+        previously relied on the VM::exceptionStackTrace() to provide a cache of the
+        stack trace of the last thrown exception.  VM::exceptionStackTrace() no longer
+        exists in the current code.
+
+        To restore this functionality, we will introduce VM::lastException() which
+        caches the last thrown Exception object.  With this, if the exception passed to
+        WebCore::reportException() to be reported isn't an Exception object (which has its
+        own stack trace), reportException() can again use the cached exception stack trace
+        which is available from VM::lastException().
+
+        * heap/Heap.cpp:
+        (JSC::Heap::visitException):
+        - visit VM::m_lastException on GCs.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::lastException):
+        (JSC::ExecState::clearLastException):
+        - convenience functions to get and clear the last exception.
+
+        * runtime/Exception.cpp:
+        (JSC::Exception::create):
+        (JSC::Exception::finishCreation):
+        - add support to create an Exception object without capturing the JS stack trace.
+          This is needed for making an Exception object to wrap a thrown value that does
+          not have a stack trace.
+          Currently, this is only used by WebCore::reportException() when there is no
+          Exception object and no last exception available to provide a stack trace.
+
+        * runtime/Exception.h:
+        (JSC::Exception::cast): Deleted.  No longer needed.
+
+        * runtime/VM.h:
+        (JSC::VM::clearLastException):
+        (JSC::VM::setException):
+        (JSC::VM::lastException):
+        (JSC::VM::addressOfLastException):
+        - Added support for VM::m_lastException.
+          VM::m_lastException serves to cache the exception stack of the most recently
+          thrown exception like VM::exceptionStackTrace() used to before r185259.
+
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        - Clear VM::m_lastException when we re-enter the VM.  Exceptions should have been
+          handled before we re-enter the VM anyway.  So, this is a good place to release
+          the cached last exception.
+
+          NOTE: this is also where the old code before r185259 clears the last exception
+          stack trace.  So, we're just restoring the previous behavior here in terms of
+          the lifecycle of the last exception stack.
+
+2015-06-11  Andreas Kling  <akling@apple.com>
+
+        jsSubstring() should support creating substrings from substrings.
+        <https://webkit.org/b/145427>
+
+        Reviewed by Geoffrey Garen
+
+        Tweak jsSubstring() to support base strings that are themselves substrings.
+        They will now share the same grandparent base. This avoids creating a new StringImpl.
+
+        * runtime/JSString.h:
+        (JSC::jsSubstring): Don't force rope resolution here. Instead do that in finishCreation()
+        if the base string is a non-substring rope. Note that resolveRope() is the very last thing
+        called, since it may allocate and the JSRopeString needs to be ready for marking.
+
+        (JSC::JSString::isSubstring): Added a helper to find out if a JSString is
+        a substring. This is just for internal use, so you don't have to cast to
+        JSRopeString for the real substringness flag.
+
+2015-06-11  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r185465.
+        https://bugs.webkit.org/show_bug.cgi?id=145893
+
+        "This patch is breaking 32bit mac build" (Requested by youenn
+        on #webkit).
+
+        Reverted changeset:
+
+        "[Streams API] ReadableJSStream should handle promises
+        returned by JS source start callback"
+        https://bugs.webkit.org/show_bug.cgi?id=145792
+        http://trac.webkit.org/changeset/185465
+
+2015-06-11  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] ReadableJSStream should handle promises returned by JS source start callback
+        https://bugs.webkit.org/show_bug.cgi?id=145792
+
+        Reviewed by Darin Adler.
+
+        Added support for JSFunction implemented by std::function.
+
+        * runtime/JSFunction.cpp:
+        (JSC::getNativeExecutable): Refactored code to share it with the two JSFunction::create
+        (JSC::JSFunction::create):
+        (JSC::runStdFunction):
+        * runtime/JSFunction.h: Added std::function based JSFunction::create prototype.
+        * runtime.JSPromise.h:
+
+2015-06-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        ASSERTION FAILED: s.length() > 1 on LayoutTests/js/regexp-flags.html
+        https://bugs.webkit.org/show_bug.cgi?id=145599
+
+        Unreviewed, simple follow up patch.
+
+        use jsString instead of jsMakeNontrivialString
+        since the flag string may be trivial (0 or 1 length).
+
+        * runtime/RegExpPrototype.cpp:
+        (JSC::regExpProtoGetterFlags):
+
+2015-06-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        JavaScript: Drop the “escaped reserved words as identifiers” compatibility measure
+        https://bugs.webkit.org/show_bug.cgi?id=90678
+
+        Reviewed by Darin Adler.
+
+        After ES6, escaped reserved words in identifiers are prohibited.
+        After parsing Identifier, we should perform `m_buffer16.shrink(0)`.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<CharacterType>::parseIdentifierSlowCase):
+        * tests/mozilla/ecma_3/Unicode/uc-003.js:
+        (test): Deleted.
+        * tests/stress/reserved-word-with-escape.js: Added.
+        (testSyntax):
+        (testSyntaxError):
+
+2015-06-10  Jordan Harband  <ljharb@gmail.com>
+
+        Implement RegExp.prototype.flags
+        https://bugs.webkit.org/show_bug.cgi?id=145599
+
+        Reviewed by Geoffrey Garen.
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.flags
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/RegExpPrototype.cpp:
+        (JSC::flagsString):
+        (JSC::regExpProtoFuncToString):
+        (JSC::regExpProtoGetterFlags):
+        * tests/stress/static-getter-in-names.js:
+
+2015-06-10  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG ASSERTION FAILED: !iterate() on stress/singleton-scope-then-overwrite.js.ftl-eager
+        https://bugs.webkit.org/show_bug.cgi?id=145853
+
+        Unreviewed, remove the assertion.
+
+        * dfg/DFGCSEPhase.cpp:
+
+2015-06-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r185414.
+        https://bugs.webkit.org/show_bug.cgi?id=145844
+
+        broke debug and jsc tests (Requested by alexchristensen on
+        #webkit).
+
+        Reverted changeset:
+
+        "JavaScript: Drop the “escaped reserved words as identifiers”
+        compatibility measure"
+        https://bugs.webkit.org/show_bug.cgi?id=90678
+        http://trac.webkit.org/changeset/185414
+
+2015-06-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        JavaScript: Drop the “escaped reserved words as identifiers” compatibility measure
+        https://bugs.webkit.org/show_bug.cgi?id=90678
+
+        Reviewed by Darin Adler.
+
+        After ES6, escaped reserved words in identifiers are prohibited.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<CharacterType>::parseIdentifierSlowCase):
+        * tests/stress/reserved-word-with-escape.js: Added.
+        (testSyntax):
+        (testSyntaxError):
+
+2015-06-10  Andreas Kling  <akling@apple.com>
+
+        [JSC] InlineCallFrame::arguments should be sized-to-fit.
+        <https://webkit.org/b/145782>
+
+        Reviewed by Darin Adler.
+
+        I spotted this Vector<ValueRecovery> looking a bit chubby in Instruments,
+        with 354 kB of memory allocated on cnet.com.
+
+        Use resizeToFit() instead of resize() since we know the final size up front.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+
+2015-06-09  Chris Dumez  <cdumez@apple.com>
+
+        Allow one sync GC per gcTimer interval on critical memory pressure warning
+        https://bugs.webkit.org/show_bug.cgi?id=145773
+
+        Reviewed by Geoffrey Garen.
+
+        On critical memory pressure warning, we were calling GCController::garbageCollectSoon(),
+        which does not offer any guarantee on when the garbage collection will actually take
+        place.
+
+        On critical memory pressure, we need to free up memory as soon as possible to avoid
+        getting killed so this is an issue. Also, the fact that we clear the PageCache on
+        critical memory pressure means a GC would likely be useful, even if the last
+        collection did not free much memory.
+
+        This patch adds a new GCController::garbageCollectNowIfNotDoneRecently() API that allows
+        one synchronous GC per gcTimer interval on critical memory pressure warning. This makes
+        us more responsive to critical memory pressure and avoids doing synchronous GCs too
+        often.
+
+        * heap/FullGCActivityCallback.cpp:
+        (JSC::FullGCActivityCallback::doCollection):
+        * heap/FullGCActivityCallback.h:
+        (JSC::GCActivityCallback::createFullTimer):
+        * heap/GCActivityCallback.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbageIfNotDoneRecently):
+        * heap/Heap.h:
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::doWork): Deleted.
+        * heap/IncrementalSweeper.h:
+
+        Drop fullSweep() API as it no longer seems useful. garbageCollectNow()
+        already does a sweep after the full collection.
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        [JSC] CodeBlock::m_constantRegisters should be sized-to-fit.
+        <https://webkit.org/b/145784>
+
+        Reviewed by Darin Adler.
+
+        Spotted this Vector looking chubby on cnet.com, with 1.23 MB of memory
+        allocated below CodeBlock::setConstantRegisters().
+
+        Use resizeToFit() instead since we know the final size up front.
+        Also removed some unused functions that operated on this constants vector
+        and the corresponding one in UnlinkedCodeBlock.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::addOrFindConstant): Deleted.
+        (JSC::CodeBlock::findConstant): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setConstantRegisters):
+        (JSC::CodeBlock::numberOfConstantRegisters): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::addOrFindConstant): Deleted.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::numberOfConstantRegisters): Deleted.
+        (JSC::UnlinkedCodeBlock::getConstant): Deleted.
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        [JSC] Polymorphic{Get,Put}ByIdList::addAccess() should optimize for size, not speed.
+        <https://webkit.org/b/145786>
+
+        Reviewed by Darin Adler.
+
+        These functions already contained comments saying they optimize for size over speed,
+        but they were using Vector::resize() which adds the usual slack for faster append().
+
+        Switch them over to using Vector::resizeToFit() instead, which makes the Vector
+        allocate a perfectly sized backing store.
+
+        Spotted 670 kB of the GetById ones, and 165 kB of PutById on cnet.com, so these
+        Vectors are definitely worth shrink-wrapping.
+
+        * bytecode/PolymorphicGetByIdList.cpp:
+        (JSC::PolymorphicGetByIdList::addAccess):
+        * bytecode/PolymorphicPutByIdList.cpp:
+        (JSC::PolymorphicPutByIdList::addAccess):
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        [JSC] JSPropertyNameEnumerator's property name vector should be sized-to-fit.
+        <https://webkit.org/b/145787>
+
+        Reviewed by Darin Adler.
+
+        Saw 108 kB worth of JSPropertyNameEnumerator backing store Vectors on cnet.com.
+        Use Vector::resizeToFit() since we know the perfect size up front.
+
+        * runtime/JSPropertyNameEnumerator.cpp:
+        (JSC::JSPropertyNameEnumerator::finishCreation):
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        FunctionExecutable::isCompiling() is weird and wrong.
+        <https://webkit.org/b/145689>
+
+        Reviewed by Geoffrey Garen.
+
+        Remove FunctionExecutable::isCompiling() and the clearCodeIfNotCompiling() style
+        functions that called it before throwing away code.
+
+        isCompiling() would consider the executable to be "compiling" if it had a CodeBlock
+        but no JITCode. In practice, every executable gets a JITCode at the same time as it
+        gets a CodeBlock, by way of prepareForExecutionImpl().
+
+        * debugger/Debugger.cpp:
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllCompiledCode):
+        (JSC::Heap::deleteAllUnlinkedFunctionCode):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::TypeRecompiler::visit):
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilation):
+        (JSC::FunctionExecutable::clearCodeIfNotCompiling): Deleted.
+        (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling): Deleted.
+        * runtime/Executable.h:
+        * runtime/VM.cpp:
+        (JSC::StackPreservingRecompiler::visit):
+
+2015-06-09  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Introduce getter definition into static hash tables and use it for getters in RegExp.prototype.
+        https://bugs.webkit.org/show_bug.cgi?id=145705
+
+        Reviewed by Darin Adler.
+
+        In this patch, we introduce Accessor type into property tables.
+        With Accessor type, create_hash_table creates a static getter property.
+        This getter property is reified as the same to the static functions.
+
+        In the mean time, we only support getter because `putEntry` and `lookupPut`
+        only work with null setter currently. However, in the spec, there's
+        no need to add static setter properties. So we will add it if it becomes
+        necessary in the future.
+
+        And at the same time, this patch fixes the issue 145738. Before this patch,
+        `putEntry` in `JSObject::deleteProperty` adds `undefined` property if
+        `isValidOffset(...)` is false (deleted). As the result, deleting twice
+        revives the property with `undefined` value.
+
+        If the static functions are reified and the entry is
+        `BuiltinOrFunctionOrAccessor`, there's no need to execute `putEntry` with
+        static hash table entry. They should be handled in the normal structure's
+        looking up because they should be already reified. So added guard for this.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * create_hash_table:
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        * runtime/Lookup.cpp:
+        (JSC::reifyStaticAccessor):
+        (JSC::setUpStaticFunctionSlot):
+        * runtime/Lookup.h:
+        (JSC::HashTableValue::propertyGetter):
+        (JSC::HashTableValue::propertyPutter):
+        (JSC::HashTableValue::accessorGetter):
+        (JSC::HashTableValue::accessorSetter):
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticValueSlot):
+        (JSC::putEntry):
+        (JSC::reifyStaticProperties):
+        * runtime/PropertySlot.h:
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::getOwnPropertySlot):
+        (JSC::regExpObjectGlobal): Deleted.
+        (JSC::regExpObjectIgnoreCase): Deleted.
+        (JSC::regExpObjectMultiline): Deleted.
+        (JSC::appendLineTerminatorEscape<LChar>): Deleted.
+        (JSC::appendLineTerminatorEscape<UChar>): Deleted.
+        (JSC::regExpObjectSourceInternal): Deleted.
+        (JSC::regExpObjectSource): Deleted.
+        * runtime/RegExpPrototype.cpp:
+        (JSC::RegExpPrototype::getOwnPropertySlot):
+        (JSC::regExpProtoGetterGlobal):
+        (JSC::regExpProtoGetterIgnoreCase):
+        (JSC::regExpProtoGetterMultiline):
+        (JSC::appendLineTerminatorEscape<LChar>):
+        (JSC::appendLineTerminatorEscape<UChar>):
+        (JSC::regExpProtoGetterSourceInternal):
+        (JSC::regExpProtoGetterSource):
+        * tests/stress/static-function-delete.js: Added.
+        (shouldBe):
+        * tests/stress/static-function-put.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-delete.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        * tests/stress/static-getter-descriptors.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-enumeration.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-get.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-in-names.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-names.js: Added.
+        (shouldBe):
+        * tests/stress/static-getter-put.js: Added.
+        (shouldBe):
+        (shouldThrow):
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        [JSC] JSString::getIndex() should avoid reifying substrings.
+        <https://webkit.org/b/145803>
+
+        Reviewed by Darin Adler.
+
+        Implement getIndex() using JSString::view(), which cuts it down to a one-liner
+        and also avoids reifying substrings.
+
+        I saw 178 kB of reified substrings below operationGetByVal -> getIndex()
+        on cnet.com, so this should help.
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::getIndexSlowCase): Deleted.
+        * runtime/JSString.h:
+        (JSC::JSString::getIndex):
+
+2015-06-09  Andreas Kling  <akling@apple.com>
+
+        [JSC] String.prototype.indexOf() should use StringView.
+        <https://webkit.org/b/145351>
+
+        Reviewed by Darin Adler.
+
+        Use StringView::find() to implement String.prototype.indexOf().
+        This avoids reifying the needle and haystack JSStrings in case they
+        are substrings.
+
+        Reduces malloc memory by ~190 kB on cnet.com.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncIndexOf):
+
+2015-06-09  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [cmake] Fix the style issues in cmake project files
+        https://bugs.webkit.org/show_bug.cgi?id=145755
+
+        Reviewed by Darin Adler.
+
+        * CMakeLists.txt:
+
+2015-06-08  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
+
+        Purge PassRefPtr in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=145750
+
+        As a step to purge PassRefPtr, this patch replaces PassRefPtr with Ref or RefPtr.
+
+        Reviewed by Darin Adler.
+
+        * API/JSClassRef.cpp:
+        (OpaqueJSClass::createNoAutomaticPrototype):
+        * API/JSClassRef.h:
+        * API/JSContextRef.cpp:
+        * API/JSScriptRef.cpp:
+        (OpaqueJSScript::create):
+        * API/JSStringRef.cpp:
+        (JSStringCreateWithCharacters):
+        (JSStringCreateWithUTF8CString):
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::create):
+        * API/OpaqueJSString.h:
+        (OpaqueJSString::create):
+        * bytecompiler/StaticPropertyAnalysis.h:
+        (JSC::StaticPropertyAnalysis::create):
+        * debugger/DebuggerCallFrame.h:
+        (JSC::DebuggerCallFrame::create):
+        * dfg/DFGToFTLDeferredCompilationCallback.cpp:
+        (JSC::DFG::ToFTLDeferredCompilationCallback::create):
+        * dfg/DFGToFTLDeferredCompilationCallback.h:
+        * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp:
+        (JSC::DFG::Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create):
+        (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::create): Deleted.
+        * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::create):
+        (JSC::DFG::ensureGlobalDFGWorklist):
+        (JSC::DFG::ensureGlobalFTLWorklist):
+        * dfg/DFGWorklist.h:
+        * heap/EdenGCActivityCallback.h:
+        (JSC::GCActivityCallback::createEdenTimer):
+        * heap/FullGCActivityCallback.h:
+        (JSC::GCActivityCallback::createFullTimer):
+        * heap/GCActivityCallback.h:
+        * inspector/InjectedScriptHost.h:
+        * inspector/JavaScriptCallFrame.h:
+        (Inspector::JavaScriptCallFrame::create):
+        * inspector/ScriptArguments.cpp:
+        (Inspector::ScriptArguments::create):
+        * inspector/ScriptArguments.h:
+        * jit/JITStubRoutine.h:
+        (JSC::JITStubRoutine::createSelfManagedRoutine):
+        * jit/JITToDFGDeferredCompilationCallback.cpp:
+        (JSC::JITToDFGDeferredCompilationCallback::create):
+        * jit/JITToDFGDeferredCompilationCallback.h:
+        * jsc.cpp:
+        (jscmain):
+        * parser/NodeConstructors.h:
+        (JSC::ArrayPatternNode::create):
+        (JSC::ObjectPatternNode::create):
+        (JSC::BindingNode::create):
+        * parser/Nodes.cpp:
+        (JSC::FunctionParameters::create):
+        * parser/Nodes.h:
+        * parser/SourceProvider.h:
+        (JSC::StringSourceProvider::create):
+        * profiler/Profile.cpp:
+        (JSC::Profile::create):
+        * profiler/Profile.h:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::create):
+        * profiler/ProfileGenerator.h:
+        * profiler/ProfileNode.h:
+        (JSC::ProfileNode::create):
+        * runtime/DataView.cpp:
+        (JSC::DataView::create):
+        * runtime/DataView.h:
+        * runtime/DateInstanceCache.h:
+        (JSC::DateInstanceData::create):
+        * runtime/JSPromiseReaction.cpp:
+        (JSC::createExecutePromiseReactionMicrotask):
+        * runtime/JSPromiseReaction.h:
+        * runtime/PropertyNameArray.h:
+        (JSC::PropertyNameArrayData::create):
+        * runtime/TypeSet.h:
+        (JSC::StructureShape::create):
+        (JSC::TypeSet::create):
+        * runtime/TypedArrayBase.h:
+        (JSC::TypedArrayBase::create):
+        (JSC::TypedArrayBase::createUninitialized):
+        (JSC::TypedArrayBase::subarrayImpl):
+        * runtime/VM.cpp:
+        (JSC::VM::createContextGroup):
+        (JSC::VM::create):
+        (JSC::VM::createLeaked):
+        * runtime/VM.h:
+        * yarr/RegularExpression.cpp:
+        (JSC::Yarr::RegularExpression::Private::create):
+
+2015-06-08  Filip Pizlo  <fpizlo@apple.com>
+
+        It should be possible to hoist all constants in DFG SSA
+        https://bugs.webkit.org/show_bug.cgi?id=145769
+
+        Reviewed by Geoffrey Garen.
+        
+        It's sometimes somewhat more efficient, and convenient, to have all constants at the
+        top of the root block. We don't require this as an IR invariant because too many phases
+        want to be able to insert constants in weird places. But, this phase will be great for
+        preparing for https://bugs.webkit.org/show_bug.cgi?id=145768.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGConstantHoistingPhase.cpp: Added.
+        (JSC::DFG::performConstantHoisting):
+        * dfg/DFGConstantHoistingPhase.h: Added.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+
+2015-06-07  Filip Pizlo  <fpizlo@apple.com>
+
+        The tiny set magic in StructureSet should be available in WTF
+        https://bugs.webkit.org/show_bug.cgi?id=145722
+
+        Reviewed by Geoffrey Garen.
+        
+        I moved the generic logic of small sets of pointers and moved it into WTF. Now,
+        StructureSet is a subclass of TinyPtrSet<Structure*>. There shouldn't be any functional
+        change.
+
+        * bytecode/StructureSet.cpp:
+        (JSC::StructureSet::filter):
+        (JSC::StructureSet::filterArrayModes):
+        (JSC::StructureSet::speculationFromStructures):
+        (JSC::StructureSet::arrayModesFromStructures):
+        (JSC::StructureSet::dumpInContext):
+        (JSC::StructureSet::dump):
+        (JSC::StructureSet::clear): Deleted.
+        (JSC::StructureSet::add): Deleted.
+        (JSC::StructureSet::remove): Deleted.
+        (JSC::StructureSet::contains): Deleted.
+        (JSC::StructureSet::merge): Deleted.
+        (JSC::StructureSet::exclude): Deleted.
+        (JSC::StructureSet::isSubsetOf): Deleted.
+        (JSC::StructureSet::overlaps): Deleted.
+        (JSC::StructureSet::operator==): Deleted.
+        (JSC::StructureSet::addOutOfLine): Deleted.
+        (JSC::StructureSet::containsOutOfLine): Deleted.
+        (JSC::StructureSet::copyFromOutOfLine): Deleted.
+        (JSC::StructureSet::OutOfLineList::create): Deleted.
+        (JSC::StructureSet::OutOfLineList::destroy): Deleted.
+        * bytecode/StructureSet.h:
+        (JSC::StructureSet::onlyStructure):
+        (JSC::StructureSet::StructureSet): Deleted.
+        (JSC::StructureSet::operator=): Deleted.
+        (JSC::StructureSet::~StructureSet): Deleted.
+        (JSC::StructureSet::isEmpty): Deleted.
+        (JSC::StructureSet::genericFilter): Deleted.
+        (JSC::StructureSet::isSupersetOf): Deleted.
+        (JSC::StructureSet::size): Deleted.
+        (JSC::StructureSet::at): Deleted.
+        (JSC::StructureSet::operator[]): Deleted.
+        (JSC::StructureSet::last): Deleted.
+        (JSC::StructureSet::iterator::iterator): Deleted.
+        (JSC::StructureSet::iterator::operator*): Deleted.
+        (JSC::StructureSet::iterator::operator++): Deleted.
+        (JSC::StructureSet::iterator::operator==): Deleted.
+        (JSC::StructureSet::iterator::operator!=): Deleted.
+        (JSC::StructureSet::begin): Deleted.
+        (JSC::StructureSet::end): Deleted.
+        (JSC::StructureSet::ContainsOutOfLine::ContainsOutOfLine): Deleted.
+        (JSC::StructureSet::ContainsOutOfLine::operator()): Deleted.
+        (JSC::StructureSet::copyFrom): Deleted.
+        (JSC::StructureSet::OutOfLineList::list): Deleted.
+        (JSC::StructureSet::OutOfLineList::OutOfLineList): Deleted.
+        (JSC::StructureSet::deleteStructureListIfNecessary): Deleted.
+        (JSC::StructureSet::isThin): Deleted.
+        (JSC::StructureSet::pointer): Deleted.
+        (JSC::StructureSet::singleStructure): Deleted.
+        (JSC::StructureSet::structureList): Deleted.
+        (JSC::StructureSet::set): Deleted.
+        (JSC::StructureSet::setEmpty): Deleted.
+        (JSC::StructureSet::getReservedFlag): Deleted.
+        (JSC::StructureSet::setReservedFlag): Deleted.
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::clobber):
+        (JSC::DFG::StructureAbstractValue::filter):
+        (JSC::DFG::StructureAbstractValue::filterSlow):
+        (JSC::DFG::StructureAbstractValue::contains):
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::makeTop):
+
+2015-06-08  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Add the missing setupArgumentsWithExecState functions after r185240
+        https://bugs.webkit.org/show_bug.cgi?id=145754
+
+        Reviewed by Benjamin Poulain.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2015-06-08  Brady Eidson  <beidson@apple.com>
+
+        Completely remove all IDB properties/constructors when it is disabled at runtime.
+        rdar://problem/18429374 and https://bugs.webkit.org/show_bug.cgi?id=137034
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/CommonIdentifiers.h:
+
+2015-06-06  Mark Lam  <mark.lam@apple.com>
+
+        Returned Exception* values need to be initialized to nullptr when no exceptions are thrown.
+        https://bugs.webkit.org/show_bug.cgi?id=145720
+
+        Reviewed by Dan Bernstein.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::evaluate):
+
+2015-06-05  Mark Lam  <mark.lam@apple.com>
+
+        Subclasses of JSNonFinalObject with gc'able children need to implement visitChildren().
+        https://bugs.webkit.org/show_bug.cgi?id=145709
+
+        Reviewed by Geoffrey Garen.
+
+        * jsc.cpp:
+        (functionSetElementRoot):
+        - The Element class has a member of type Root which extends JSDestructibleObject.
+          It should be stored in a WriteBarrier, and visited by visitChildren().  
+
+        * runtime/ClonedArguments.cpp:
+        (JSC::ClonedArguments::materializeSpecialsIfNecessary):
+        (JSC::ClonedArguments::visitChildren):
+        * runtime/ClonedArguments.h:
+        - Add missing visitChildren().
+
+        * tests/stress/cloned-arguments-should-visit-callee-during-gc.js: Added.
+        (makeTransientFunction.transientFunc):
+        (makeTransientFunction):
+
+2015-06-05  Geoffrey Garen  <ggaren@apple.com>
+
+        DropAllLocks RELEASE_ASSERT on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=139654
+
+        Reviewed by Mark Lam.
+
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::dropAllLocks): Removed a comment because it duplicated
+        the code beneath it. Removed a FIXME because we can't ASSERT that
+        we're holding the lock. WebKit1 on iOS drops the lock before calling to
+        delegates, not knowing whether it holds the lock or not.
+
+        (JSC::JSLock::DropAllLocks::DropAllLocks): Only ASSERT that we are not
+        GC'ing if we hold the lock. If we do not hold the lock, it is perfectly
+        valid for some other thread, which does hold the lock, to be GC'ing.
+        What is not valid is to drop the lock in the middle of GC, since GC
+        must be atomic.
+
+2015-06-05  Filip Pizlo  <fpizlo@apple.com>
+
+        speculateRealNumber() should early exit if you're already a real number, not if you're already a real double.
+
+        Rubber stamped by Mark Lam.
+        
+        This was causing: https://build.webkit.org/results/Apple%20Yosemite%20Debug%20WK1%20(Tests)/r185261%20(5180)/webaudio/note-grain-on-timing-crash-log.txt
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculateRealNumber):
+
+2015-06-05  Mark Lam  <mark.lam@apple.com>
+
+        finally blocks should not set the exception stack trace when re-throwing the exception.
+        https://bugs.webkit.org/show_bug.cgi?id=145525
+
+        Reviewed by Geoffrey Garen.
+
+        How exceptions presently work:
+        =============================
+        1. op_throw can throw any JSValue.
+        2. the VM tries to capture the stack at the throw point and propagate that as needed.
+        3. finally blocks are implemented using op_catch to catch the thrown value, and throws it again using op_throw.
+
+        What's wrong with how it presently works:
+        ========================================
+        1. finally's makes for bad exception throw line numbers in the Inspector console.
+
+           The op_throw in finally will throw the value anew i.e. it captures a stack from the re-throw point.
+           As a result, the Inspector sees the finally block as the throw point.  The original stack is lost.
+
+        2. finally's breaks the Inspector's "Breaks on Uncaught Exception"
+
+           This is because finally blocks are indistinguishable from catch blocks.  As a result, a try-finally,
+           which should break in the Inspector on the throw, does not because the Inspector thought the
+           exception was "caught".
+
+        3. finally's yields confusing break points when the Inspector "Breaks on All Exceptions"
+
+           a. In a try-finally scenario, the Inspector breaks 2 times: 1 at the throw, 1 at the finally.
+           b. In a for-of loop (which has synthesized finallys), the Inspector will do another break.
+              Similarly for other cases of JS code which synthesize finallys.
+           c. At VM re-entry boundaries (e.g. js throws & returns to native code, which returns to js),
+              the Inspector will do another break if there's an uncaught exception.
+
+        How this patch fixes the issues:
+        ===============================
+        1. We introduce an Exception object that wraps the thrown value and the exception stack.
+
+           When throwing an exception, the VM will check if the thrown value is an Exception
+           object or not.  If it is not an Exception object, then we must be throwing a new
+           exception.  The VM will create an Exception object to wrap the thrown value and
+           capture the current stack for it.
+
+           If the thrown value is already an Exception object, then the requested throw operation
+           must be a re-throw.  The VM will not capture a new stack for it.
+
+        2. op_catch will now populate 2 locals: 1 for the Exception, 1 for the thrown JSValue.
+
+           The VM is aware of the Exception object and uses it for rethrows in finally blocks.
+           JS source code is never aware of the Exception object.
+
+           JS code is aware of the thrown value.  If it throws the caught thrown value, that
+           constitutes a new throw, and a new Exception object will be created for it.
+
+        3. The VM no longer tracks the thrown JSValue and the exception stack.  It will only
+           track a m_exception field which is an Exception*.
+
+        4. The BytecodeGenerator has already been updated in a prior patch to distinguish
+           between Catch, Finally, and SynthesizedFinally blocks.  The interpreter runtime will
+           now report to the debugger whether we have a Catch handler, not just any handlers.
+
+           The debugger will use this detail to determine whether to break or not.  "Break on
+           uncaught exceptions" will only break if no Catch handler was found.
+
+           This solves the issue of the debugger breaking at finally blocks, and for-of statements.
+
+        5. The Exception object will also have a flag to indicate whether the debugger has been
+           notified of the Exception being thrown.  Once the Interpreter notifies the debugger
+           of the Exception object, it will mark this flag and not repeat the notify the debugger
+           again of the same Exception.
+
+           This solves the issue of the debugger breaking at VM re-entry points due to uncaught
+           exceptions.
+
+        6. The life-cycle of the captured exception stack trace will now follow the life-cycle
+           of the Exception object.
+
+        Other changes:
+        7. Change all clients of the VM::exception() to expect an Exception* instead of JSValue.
+
+        8. Fixed a few bugs where thrown exceptions are not cleared before exiting the VM.
+
+        9. Also renamed some variables and classes to better describe what they are.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+
+        * API/JSObjectRef.cpp:
+        (handleExceptionIfNeeded):
+        - The functions below all do the same exception check.  Added this helper
+          to simplify the code.
+        (JSClassCreate):
+        (JSObjectMakeFunction):
+        (JSObjectMakeArray):
+        (JSObjectMakeDate):
+        (JSObjectMakeError):
+        (JSObjectMakeRegExp):
+        (JSObjectGetProperty):
+        (JSObjectSetProperty):
+        (JSObjectGetPropertyAtIndex):
+        (JSObjectSetPropertyAtIndex):
+        (JSObjectDeleteProperty):
+        (JSObjectCallAsFunction):
+        (JSObjectCallAsConstructor):
+
+        * API/JSScriptRef.cpp:
+        * API/JSValue.mm:
+        (JSContainerConvertor::take):
+        (reportExceptionToInspector):
+
+        * API/JSValueRef.cpp:
+        (handleExceptionIfNeeded):
+        - The functions below all do the same exception check.  Added this helper
+          to simplify the code.
+        (evernoteHackNeeded):
+        (JSValueIsEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueCreateJSONString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        - Added new files Exception.h and Exception.cpp.
+
+        * bindings/ScriptFunctionCall.cpp:
+        (Deprecated::ScriptFunctionCall::call):
+        * bindings/ScriptFunctionCall.h:
+
+        * bytecode/BytecodeList.json:
+        - op_catch now had 2 operands: the exception register, and the thrown value register.
+
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::handlerForBytecodeOffset):
+        * bytecode/CodeBlock.h:
+        - handlerForBytecodeOffset() now can look for just Catch handlers only.
+
+        * bytecode/HandlerInfo.h:
+        - Cleaned up some white space I accidentally added in a previous patch.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::pushTry):
+        (JSC::BytecodeGenerator::popTryAndEmitCatch):
+        (JSC::BytecodeGenerator::emitThrowReferenceError):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitThrow):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TryNode::emitBytecode):
+        - Adding support for op_catch's 2 operands.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::hasBreakpoint):
+        (JSC::Debugger::pauseIfNeeded):
+        (JSC::Debugger::exception):
+        * debugger/Debugger.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::thisValue):
+        (JSC::DebuggerCallFrame::evaluate):
+        * debugger/DebuggerCallFrame.h:
+        (JSC::DebuggerCallFrame::isValid):
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::createInjectedScript):
+        * inspector/InspectorEnvironment.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectScriptDebugServer.h:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::evaluate):
+        * inspector/JavaScriptCallFrame.h:
+        (Inspector::JavaScriptCallFrame::vmEntryGlobalObject):
+        (Inspector::JavaScriptCallFrame::thisValue):
+        (Inspector::JavaScriptCallFrame::evaluate):
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::extractSourceInformationFromException):
+        (Inspector::createScriptCallStackFromException):
+        * inspector/ScriptCallStackFactory.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::evaluateBreakpointAction):
+        (Inspector::ScriptDebugServer::handleBreakpointHit):
+        (Inspector::ScriptDebugServer::handleExceptionInBreakpointCondition):
+        * inspector/ScriptDebugServer.h:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::clearException):
+        (JSC::ExecState::exception):
+        (JSC::ExecState::hadException):
+        (JSC::ExecState::atomicStringTable):
+        (JSC::ExecState::propertyNames):
+        (JSC::ExecState::clearSupplementaryExceptionInfo): Deleted.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        (JSC::Interpreter::stackTraceAsString):
+        (JSC::GetCatchHandlerFunctor::GetCatchHandlerFunctor):
+        (JSC::GetCatchHandlerFunctor::operator()):
+        (JSC::Interpreter::unwind):
+        - Added a check for didNotifyInspectorOfThrow() here to prevent duplicate reports
+          of the same Exception to the debugger.
+
+        (JSC::GetExceptionHandlerFunctor::GetExceptionHandlerFunctor): Deleted.
+        (JSC::GetExceptionHandlerFunctor::operator()): Deleted.
+        - Renamed GetExceptionHandlerFunctor to GetCatchHandlerFunctor since the debugger
+          is only interested in knowing whether we have Catch handlers.
+
+        * interpreter/Interpreter.h:
+        (JSC::SuspendExceptionScope::SuspendExceptionScope):
+        (JSC::SuspendExceptionScope::~SuspendExceptionScope):
+        (JSC::Interpreter::sampler):
+        (JSC::ClearExceptionScope::ClearExceptionScope): Deleted.
+        (JSC::ClearExceptionScope::~ClearExceptionScope): Deleted.
+        - Renamed ClearExceptionScope to SuspendExceptionScope because "clear" implies that
+          we're purging the exception.  Instead, we're merely suspending any handling of
+          that exception for a period defined by the scope.
+
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::emitExceptionCheck):
+
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        - Removed the exception argument.  It is always the value in VM::exception() anyway.
+          genericUnwind() can just get it from the VM, and save everyone some work.
+
+        * jit/JITExceptions.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTINativeCall):
+        (JSC::JIT::emit_op_catch):
+        - Add support for the new op_catch operands.
+
+        * jit/JITOperations.cpp:
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator):
+        * jsc.cpp:
+        (functionRun):
+        (functionLoad):
+        (runWithScripts):
+        (runInteractive):
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        - Add support for the new op_catch operands.  Also update the code to handle
+          VM::m_exception being an Exception pointer, not a JSValue.
+
+        * parser/NodeConstructors.h:
+        (JSC::TryNode::TryNode):
+        * parser/Nodes.h:
+        * runtime/CallData.cpp:
+        (JSC::call):
+        * runtime/CallData.h:
+
+        * runtime/Completion.cpp:
+        (JSC::evaluate):
+        * runtime/Completion.h:
+        (JSC::evaluate):
+        - Change evaluate() to take a reference to the returned exception value instead
+          of a pointer.  In all but 2 or 3 cases, we want the returned exception anyway.
+          Might as well simplify the code by requiring the reference.
+
+        * runtime/Error.h:
+        (JSC::throwVMError):
+        (JSC::throwVMTypeError):
+
+        * runtime/Exception.cpp: Added.
+        (JSC::Exception::create):
+        (JSC::Exception::destroy):
+        (JSC::Exception::createStructure):
+        (JSC::Exception::visitChildren):
+        (JSC::Exception::Exception):
+        (JSC::Exception::~Exception):
+        * runtime/Exception.h: Added.
+        (JSC::Exception::valueOffset):
+        (JSC::Exception::cast):
+        (JSC::Exception::value):
+        (JSC::Exception::stack):
+        (JSC::Exception::didNotifyInspectorOfThrow):
+        (JSC::Exception::setDidNotifyInspectorOfThrow):
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createTerminatedExecutionException):
+        (JSC::isTerminatedExecutionException):
+        (JSC::createStackOverflowError):
+        * runtime/ExceptionHelpers.h:
+        * runtime/GetterSetter.cpp:
+        (JSC::callGetter):
+        * runtime/IteratorOperations.cpp:
+        (JSC::iteratorClose):
+        * runtime/JSObject.cpp:
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::constructPromise):
+        * runtime/JSPromiseDeferred.cpp:
+        (JSC::updateDeferredFromPotentialThenable):
+        (JSC::abruptRejection):
+        * runtime/JSPromiseReaction.cpp:
+        (JSC::ExecutePromiseReactionMicrotask::run):
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::releaseExecutableMemory):
+        (JSC::VM::throwException):
+        (JSC::VM::setStackPointerAtVMEntry):
+        (JSC::VM::getExceptionInfo): Deleted.
+        (JSC::VM::setExceptionInfo): Deleted.
+        (JSC::VM::clearException): Deleted.
+        (JSC::clearExceptionStack): Deleted.
+        * runtime/VM.h:
+        (JSC::VM::targetMachinePCForThrowOffset):
+        (JSC::VM::clearException):
+        (JSC::VM::setException):
+        (JSC::VM::exception):
+        (JSC::VM::addressOfException):
+        (JSC::VM::exceptionStack): Deleted.
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        (JSC::VMEntryScope::setEntryScopeDidPopListener):
+
+2015-06-04  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Always track out-of-bounds array access explicitly instead of relying on the slow case
+        https://bugs.webkit.org/show_bug.cgi?id=145673
+
+        Reviewed by Geoffrey Garen.
+
+        Previously, we were deciding to use out-of-bounds speculation based on two informations:
+        -Explicitly detected out-of-bounds accesses tracked on ArrayProfile.
+        -The number of time we took the slow cases in the baseline JIT.
+
+        The heuristic based on slow cases was a little too fragile.
+
+        In some cases, we were running into that limit just because the indexing type changes between
+        two values (typically Int32Array and DoubleArray). Sometimes we were just unlucky on what
+        we used for the inline cache.
+
+        In Kraken, this was hurting us on "audio-beat-detection" and "audio-fft". The array types we see
+        change between Int32 and Double. We run into the slow path a bit but never hit
+        out-of-bounds.
+
+        By the time we compile in DFG, we have stable Double Arrays but we speculate out-of-bounds based
+        on the number of slow cases we took. Because of that, we start boxing the double on GetByVal,
+        using DoubleRep, etc. adding a ton of overhead over otherwise very simple operations.
+
+        WebXPRT was also suffering from this problem but the other way arround: we were missing
+        the out-of-bounds accesses due to changes in indexing types, we were below the threshold
+        of slow-path access, thus we predicted in-bounds accesses for code that was doing plenty
+        of out-of-bands.
+
+
+        This patch fixes the problem by tracking the out-of-bounds access explicitly any time we go
+        into the slow path in baseline JIT. Since we no longer miss any out-of-bounds, we can remove
+        the slow-path heuristic.
+
+        There is new additional special case in the C code regarding out-of-bounds: Arguments access.
+        Mispredicting out-of-bounds accesses on arguments is a disaster for performance, so those are
+        tracked in the way DFG expect it.
+
+
+        There are a few important cases that are still not covered optimally:
+        -PutByVal on Arguments.
+        -Get/Put ByVal on TypedArray.
+        Those are simply not used by DFG in any way. TypedArrays should probably be looked at in the future.
+
+        * bytecode/ArrayProfile.cpp:
+        (JSC::ArrayProfile::computeUpdatedPrediction):
+        The inline-cache repatch cases now update the ArrayProfile information. This has no value in baseline
+        JIT but it helps avoiding one recompile in DFG for the missing ArrayProfile information.
+
+        * bytecode/ArrayProfile.h:
+        (JSC::ArrayProfile::setOutOfBounds):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getArrayMode):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::getArrayModeConsideringSlowPath): Deleted.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emitSlow_op_has_indexed_property):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emitSlow_op_has_indexed_property):
+        * jit/JITOperations.cpp:
+        (JSC::canUseFastArgumentAccess):
+        This is not my favorite part of this patch.
+
+        I tried having JSObject::canGetIndexQuickly() handle arguments which would put everything
+        on the generic path. Unfortunately, that code is very performance sensitive and some benchmarks were
+        impacted by over 10%
+
+        I left JSObject::canGetIndexQuickly() alone, and I added the canUseFastArgumentAccess() mirroring
+        how DFG uses out-of-bounds for Arguments.
+
+        (JSC::getByVal):
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emitSlow_op_put_by_val):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitSlow_op_get_by_val):
+        (JSC::JIT::emitSlow_op_put_by_val):
+        * runtime/JSPromiseFunctions.cpp:
+        * tests/stress/get-by-val-out-of-bounds-basics.js: Added.
+        (opaqueGetByValOnInt32ArrayEarlyOutOfBounds):
+        (testInt32ArrayEarlyOutOfBounds):
+        (testIndexingTypeChangesOnInt32Array):
+        (opaqueGetByValOnStringArrayHotOutOfBounds):
+        (testStringArrayHotOutOfBounds):
+        (testIndexingTypeChangesOnStringArray):
+        (opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds):
+        (testStringAndInt32ArrayHotOutOfBounds):
+        (opaqueGetByValOnDoubleArrayHotOutOfBounds):
+        * tests/stress/put-by-val-out-of-bounds-basics.js: Added.
+        (opaquePutByValOnInt32ArrayEarlyOutOfBounds):
+        (testInt32ArrayEarlyOutOfBounds):
+        (opaquePutByValOnStringArrayHotOutOfBounds):
+        (testStringArrayHotOutOfBounds):
+
+2015-06-03  Filip Pizlo  <fpizlo@apple.com>
+
+        Simplify unboxing of double JSValues known to be not NaN and not Int32
+        https://bugs.webkit.org/show_bug.cgi?id=145618
+
+        Reviewed by Geoffrey Garen.
+        
+        In many cases we know that we most likely loaded a non-NaN double value from the heap.
+        Prior to this patch, we would do two branches before unboxing the double. This patch
+        reduces this to one branch in the common case. Before:
+        
+            if (is int32)
+                unbox int32 and convert to double
+            else if (is number)
+                unbox double
+            else
+                exit
+        
+        After:
+
+            tmp = unbox double
+            if (tmp == tmp)
+                done
+            else if (is int32)
+                unbox int32 and convert to double
+            else
+                exit
+        
+        We only use the new style if we have profiling that tells us that we are unlikely to see
+        either Int32 or NaN - since we will now exit on NaN and int32 requires an extra branch.
+        
+        This is a 8% speed-up on Octane/box2d. On one microbenchmark this is a 25% speed-up.
+        
+        Rolling this back in after I made DFG::SpeculativeJIT call a new version of unboxDouble()
+        that doesn't assert that the JSValue is a double, since we are intentionally using it
+        before doing the "is a double" test. This wasn't a problem on 32-bit since unboxDouble()
+        does no such assertion on 32-bit.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::observeUseKindOnNode):
+        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateDouble):
+        (JSC::DFG::Node::shouldSpeculateDoubleReal):
+        (JSC::DFG::Node::shouldSpeculateNumber):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        (JSC::DFG::SpeculativeJIT::speculateNumber):
+        (JSC::DFG::SpeculativeJIT::speculateRealNumber):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepReal):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleReal): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isNumerical):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::boxDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepReal):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfNotOther):
+        (JSC::AssemblyHelpers::branchIfInt32):
+        (JSC::AssemblyHelpers::branchIfNotInt32):
+        (JSC::AssemblyHelpers::branchIfNumber):
+
+2015-06-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Class constructor appearing as Object Tree property does not include parameters
+        https://bugs.webkit.org/show_bug.cgi?id=145661
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.prototype._classPreview):
+        (InjectedScript.RemoteObject.prototype._appendPropertyPreviews):
+        The string we will return for previews of class constructor functions.
+
+        (InjectedScript.RemoteObject):
+        (InjectedScript.RemoteObject.prototype._describe):
+        No longer return the class name as the description string.
+        Instead return the class name for the RemoteObject.className.
+
+2015-06-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r185216.
+        https://bugs.webkit.org/show_bug.cgi?id=145666
+
+        it caused a bunch of debug crashes (Requested by pizlo on
+        #webkit).
+
+        Reverted changeset:
+
+        "Simplify unboxing of double JSValues known to be not NaN and
+        not Int32"
+        https://bugs.webkit.org/show_bug.cgi?id=145618
+        http://trac.webkit.org/changeset/185216
+
+2015-06-03  Filip Pizlo  <fpizlo@apple.com>
+
+        Simplify unboxing of double JSValues known to be not NaN and not Int32
+        https://bugs.webkit.org/show_bug.cgi?id=145618
+
+        Reviewed by Geoffrey Garen.
+        
+        In many cases we know that we most likely loaded a non-NaN double value from the heap.
+        Prior to this patch, we would do two branches before unboxing the double. This patch
+        reduces this to one branch in the common case. Before:
+        
+            if (is int32)
+                unbox int32 and convert to double
+            else if (is number)
+                unbox double
+            else
+                exit
+        
+        After:
+
+            tmp = unbox double
+            if (tmp == tmp)
+                done
+            else if (is int32)
+                unbox int32 and convert to double
+            else
+                exit
+        
+        We only use the new style if we have profiling that tells us that we are unlikely to see
+        either Int32 or NaN - since we will now exit on NaN and int32 requires an extra branch.
+        
+        This is a 8% speed-up on Octane/box2d. On one microbenchmark this is a 25% speed-up.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::observeUseKindOnNode):
+        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateDouble):
+        (JSC::DFG::Node::shouldSpeculateDoubleReal):
+        (JSC::DFG::Node::shouldSpeculateNumber):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        (JSC::DFG::SpeculativeJIT::speculateNumber):
+        (JSC::DFG::SpeculativeJIT::speculateRealNumber):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepReal):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleReal): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isNumerical):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::boxDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepReal):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfNotOther):
+        (JSC::AssemblyHelpers::branchIfInt32):
+        (JSC::AssemblyHelpers::branchIfNotInt32):
+        (JSC::AssemblyHelpers::branchIfNumber):
+
+2015-06-04  Filip Pizlo  <fpizlo@apple.com>
+
+        SideState should be a distinct abstract heap from Heap and Stack
+        https://bugs.webkit.org/show_bug.cgi?id=145653
+
+        Reviewed by Geoffrey Garen.
+        
+        Before, SideState fit into the hierarchy like so:
+        
+        World
+           |
+           +-- Stack
+           |
+           +-- Heap
+                 |
+                 +-- SideState
+        
+        Now we will have:
+        
+        World
+           |
+           +-- Stack
+           |
+           +-- Heap
+           |
+           +-- SideState
+        
+        This makes it easy to ask if a writing operation wrote to anything that is observable even
+        if we don't exit. SideState is only observable if we exit.
+
+        * dfg/DFGAbstractHeap.h:
+        (JSC::DFG::AbstractHeap::AbstractHeap):
+        (JSC::DFG::AbstractHeap::supertype):
+
+2015-06-04  Chris Dumez  <cdumez@apple.com>
+
+        [WK2] Prune more resources from the MemoryCache before process suspension
+        https://bugs.webkit.org/show_bug.cgi?id=145633
+
+        Reviewed by Andreas Kling.
+
+        No longer move protect IncrementalSweeper::fullSweep() behind
+        USE(CF) so we don't need #ifdefs at call sites, similarly to what is
+        done for the rest of the IncrementalSweeper API.
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::fullSweep):
+        * heap/IncrementalSweeper.h:
+
+2015-06-01  Filip Pizlo  <fpizlo@apple.com>
+
+        CallLinkStatus should return takesSlowPath if the GC often cleared the IC
+        https://bugs.webkit.org/show_bug.cgi?id=145502
+
+        Reviewed by Geoffrey Garen.
+        
+        CallLinkInfo now remembers when it has been cleared by GC. This has some safeguards for when
+        a call gets cleared by GC only because we hadn't converted it into a closure call; in that
+        case the GC will just tell us that it should be a closure call. The DFG will not optimize
+        a call that was cleared by GC, and the DFG will always prefer a closure call if the GC told
+        us that the specific callee was dead but the executable wasn't.
+        
+        This guards us from some scenarios that came up in Speedometer. It's neutral on the pure JS
+        benchmarks, most likely just because those benchmarks aren't real enough to have interesting
+        GC of code.
+
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::visitWeak):
+        (JSC::CallLinkInfo::dummy):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::CallLinkInfo):
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+
+2015-06-02  Filip Pizlo  <fpizlo@apple.com>
+
+        GetById and PutById profiling should be more precise about it takes slow path
+        https://bugs.webkit.org/show_bug.cgi?id=145590
+
+        Reviewed by Geoffrey Garen.
+        
+        If a ById access ever takes slow path, we want the DFG and FTL to know this. Previously we
+        were relying on slow path counts, which conflate slow paths taken due to a megamorphic
+        access and slow paths taken due to IC building.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFor):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/StructureStubInfo.h:
+        (JSC::StructureStubInfo::StructureStubInfo):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetById):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
+2015-06-03  Michael Saboff  <msaboff@apple.com>
+
+        Improve test coverage for changes made in 145527
+        https://bugs.webkit.org/show_bug.cgi?id=145578
+
+        Reviewed by Geoffrey Garen.
+
+        Added more complexity to poly-setter-combo.js stress test to create more turmoil in the
+        polymorphic get-by-id / put-by-id with getters and setters to exercise the code change in
+        https://bugs.webkit.org/show_bug.cgi?id=145527.  By changing the objects that the main test
+        function sees, we are able to test those paths.  Verified with temporary logging code.
+
+        * tests/stress/poly-setter-combo.js:
+        (Cons2):
+        (Cons3):
+        (Cons4):
+        (foo):
+        (test):
+        (runTestWithConstructors):
+
+2015-06-02  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix broken CLoop build.
+
+        Not reviewed.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeExitSiteData):
+
+2015-06-02  Keith Miller  <keith_miller@apple.com>
+
+        JavaScriptCore: JSExport protocol with an NSInteger property converts negative values to 18446744073709552000
+        https://bugs.webkit.org/show_bug.cgi?id=145563
+
+        Reviewed by Darin Adler.
+
+        The Objective-C bindings were improperly converting negative
+        long long/NSIntegers to 18446744073709552000 because they
+        were converted to unsigned numbers.
+
+        * API/ObjcRuntimeExtras.h:
+        (parseObjCType):
+        * API/tests/testapi.mm:
+        (testObjectiveCAPIMain):
+        (checkNegativeNSIntegers):
+        (testObjectiveCAPI):
+
+2015-06-02  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Heap-use-after-free read of size 4 in JavaScriptCore: WTF::StringImpl::isSymbol() (StringImpl.h:496)
+        https://bugs.webkit.org/show_bug.cgi?id=145532
+
+        Reviewed by Geoffrey Garen.
+
+        AtomicStringImpl::lookUp returns AtomicStringImpl*,
+        it doesn't give any ownership to the caller.
+        Originally, this is ok because the ownership is taken
+        by AtomicStringImpl's table (& the register side).
+
+        But if we would like to use this returned AtomicStringImpl*,
+        we should take its ownership immediately.
+        Because if the register side releases its ownership (ref count),
+        it will be destroyed.
+
+        In JSString::toExistingAtomicString, it returns AtomicStringImpl*.
+        But it's not appropriate.
+        If the owner of AtomicStringImpl* is always JSString*, it is ok.
+        But it looks up the table-registered AtomicStringImpl* from
+        the AtomicStringImpl table. So JSString* may not have the ownership
+        of the returned AtomicStringImpl*.
+
+        The failure situation is the following.
+
+        1. A creates AtomicStringImpl. A has its ownership.
+           And A registers it to AtomicStringImpl table.
+        2. JSString looks up the AtomicStringImpl from the table.
+           It gets AtomicStringImpl*. And JSString doesn't have its ownership.
+           It returns the raw pointer immediately to the users
+        3. A is released. There's no owner for AtomicStringImpl*.
+           So it's also destroyed.
+        4. Use looked up AtomicStringImpl in (2). It becomes use-after-free.
+
+        This patch fixes it by the following changes.
+
+        1. Change the signature of `AtomicStringImpl* AtomicStringImpl::lookUp(...)`
+           to `RefPtr<AtomicStringImpl> AtomicStringImpl::lookUp(..)`.
+           Use `RefPtr` because it may return `nullptr`.
+        2. Change the signature of `AtomicStringImpl* JSString::toExistingAtomicString(...)`
+           to `RefPtr<AtomicStringImpl> JSString::toExistingAtomicString(...)`.
+           Using `RefPtr` is the same reason.
+        3. Receive the result with `RefPtr<AtomicStringImpl>` in the caller side.
+
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeToExistingAtomicString):
+        * runtime/JSString.h:
+        (JSC::JSString::toExistingAtomicString):
+
+2015-05-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Any exit from any JIT due to profiling for an inline cache should force all future compilations to be wary
+        https://bugs.webkit.org/show_bug.cgi?id=145496
+
+        Reviewed by Geoffrey Garen.
+        
+        This pessimizes compilation a bit, but it reduces the likelihood of exiting from FTL. I
+        couldn't find any convincing reason not to do this, and we know from Speedometer that this
+        change is necessary for weirder code.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeExitSiteData):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        * bytecode/CallLinkStatus.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::appendVariant):
+        (JSC::GetByIdStatus::hasExitSite):
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::appendVariant):
+        (JSC::PutByIdStatus::hasExitSite):
+        (JSC::PutByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.h:
+
+2015-05-31  Filip Pizlo  <fpizlo@apple.com>
+
+        If a call has ever taken the virtual slow path, make sure that the DFG knows this
+        https://bugs.webkit.org/show_bug.cgi?id=145501
+
+        Reviewed by Geoffrey Garen.
+        
+        Now now return higher fidelity information in the case of no polymorphic call stub. If the
+        virtual slow path was ever taken, we note this, and we note either zero or one call variant
+        based on the IC's last callee.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::computeFor):
+
+2015-06-01  Michael Saboff  <msaboff@apple.com>
+
+        Crash in com.apple.WebKit.WebContent at com.apple.JavaScriptCore: JSC::revertCall + 24
+        https://bugs.webkit.org/show_bug.cgi?id=145527
+
+        Reviewed by Filip Pizlo.
+
+        If a CallLinkInfo is GC'ed, we need to notify any PolymorphicCallNode's that reference it.
+        Added plumbling to clear the m_callLinkInfo of a PolymorphicCallNode when that CallLinkInfo
+        is going away.
+
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::~CallLinkInfo):
+        * jit/PolymorphicCallStubRoutine.cpp:
+        (JSC::PolymorphicCallNode::unlink):
+        (JSC::PolymorphicCallNode::clearCallLinkInfo):
+        (JSC::PolymorphicCallCase::dump):
+        (JSC::PolymorphicCallStubRoutine::edges):
+        (JSC::PolymorphicCallStubRoutine::clearCallNodesFor):
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        * jit/PolymorphicCallStubRoutine.h:
+        (JSC::PolymorphicCallNode::hasCallLinkInfo):
+
+2015-06-01  Mark Lam  <mark.lam@apple.com>
+
+        Add the ability to tell between Catch and Finally blocks.
+        https://bugs.webkit.org/show_bug.cgi?id=145524 
+
+        Reviewed by Michael Saboff.
+
+        ... and also SynthesizedFinally blocks too.  A SynthesizedFinally block
+        is a finally block that is synthesized by the bytecode generator but
+        does not actually correspond to any exception handling construct at the
+        JS source code level.  An example of this is the "for ... of" statement
+        where it needs to do some "final" clean up before passing on the
+        exception.
+
+        Manually tested by inspecting the bytecode dump of functions with
+        try-catch-finally blocks as well as for of statements which have
+        synthesized finally blocks.  The bytecode dumps contains the exception
+        handlers table which has these blocks labelled with their newly added
+        types.  No automatic test because this type info is not visible to JS
+        code.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/HandlerInfo.h:
+        (JSC::HandlerInfoBase::type):
+        (JSC::HandlerInfoBase::setType):
+        (JSC::HandlerInfoBase::typeName):
+        (JSC::HandlerInfoBase::isCatchHandler):
+        (JSC::UnlinkedHandlerInfo::UnlinkedHandlerInfo):
+        (JSC::HandlerInfo::initialize):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::pushTry):
+        (JSC::BytecodeGenerator::popTryAndEmitCatch):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitThrow):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TryNode::emitBytecode):
+
+2015-05-29  Geoffrey Garen  <ggaren@apple.com>
+
+        REGRESSION: These sorting idioms used by Peacekeeper and Browsermark are ~20X slower
+        https://bugs.webkit.org/show_bug.cgi?id=145412
+
+        Reviewed by Darin Adler.
+
+        Moar speedup.
+
+        Added a bucket sort for string sorting.
+
+        * builtins/Array.prototype.js:
+        (sort.compactSparse):
+        (sort.compactSlow):
+        (sort.compact): Split out a compaction fast path for dense arrays. Without
+        it, compaction can increase sort time by 2X for simple sorts.
+
+        (sort.bucketSort):
+        (sort.stringSort): Use a bucket sorting algorithm if we know we're sorting
+        strings. This makes average case string sorting O(N) with O(N) additional
+        memory use.
+
+        The worst case bucket sort can require O(M * N) additional
+        space. We avoid this by falling back to merge sort when things are
+        simple or overly duplicative. These are the two cases that accumulate
+        excessive -- and potentially pathological -- bucketing overhead.
+
+2015-06-01  Mark Lam  <mark.lam@apple.com>
+
+        HandlerInfo::initialize() should not assume that CodeLocationLabel is available.
+        https://bugs.webkit.org/show_bug.cgi?id=145515
+
+        Reviewed by Csaba Osztrogonác.
+
+        CodeLocationLabel is only defined for ENABLE(ASSEMBLER) builds.  r185022's
+        attempt at simplifying code to increase readability failed to take this into
+        account.  This patch fixes it.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/HandlerInfo.h:
+        (JSC::HandlerInfo::initialize):
+
+2015-05-31  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, add a FIXME referencing https://bugs.webkit.org/show_bug.cgi?id=145503.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::inliningCost):
+
+2015-05-31  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Drop WeakMap#clear
+        https://bugs.webkit.org/show_bug.cgi?id=145489
+
+        Reviewed by Mark Lam.
+
+        ES6 spec intentionally drops the WeakMap#clear
+        to allow engine to implement WeakMap as a per-object table.
+
+        This patch drops WeakMap.prototype.clear.
+
+        * runtime/WeakMapPrototype.cpp:
+        (JSC::WeakMapPrototype::finishCreation): Deleted.
+        (JSC::protoFuncWeakMapClear): Deleted.
+
+2015-05-31  Jordan Harband  <ljharb@gmail.com>
+
+        Array#reduce and reduceRight don't follow ToLength
+        https://bugs.webkit.org/show_bug.cgi?id=145364
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+
+        Reviewed by Yusuke Suzuki.
+
+        * builtins/Array.prototype.js:
+        (reduce):
+        (reduceRight):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        (JSC::arrayProtoFuncReduce): Deleted.
+        (JSC::arrayProtoFuncReduceRight): Deleted.
+
+2015-05-29  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL codegen for MultiGetByOffset and MultiPutByOffset where the structure set is already proved should have an unreachable default case instead of an exit
+        https://bugs.webkit.org/show_bug.cgi?id=145469
+
+        Reviewed by Geoffrey Garen.
+        
+        Omitting the speculation on the fail path when the speculation is guaranteed not to be
+        taken hints to LLVM that the default case is impossible. This enables some useful
+        optimizations.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
+        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
+
+2015-05-29  Mark Lam  <mark.lam@apple.com>
+
+        Refactoring HandlerInfo and UnlinkedHandlerInfo.
+        https://bugs.webkit.org/show_bug.cgi?id=145480
+
+        Reviewed by Benjamin Poulain.
+
+        HandlerInfo and UnlinkedHandlerInfo have common parts, but are not currently
+        expressed as 2 unrelated structs that happen to have near identical fields.
+        We can refactor them to better express their relationship.  We can also add
+        some convenience functions to make the code that uses them a little more
+        readable.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::handlerForBytecodeOffset):
+        * bytecode/HandlerInfo.h:
+        (JSC::UnlinkedHandlerInfo::UnlinkedHandlerInfo):
+        (JSC::HandlerInfo::initialize):
+        - I chose to include CodeLocationLabel arg even though it is unused by
+          by non-JIT builds.  This makes the call site cleaner to read.
+
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedSimpleJumpTable::add):
+        (JSC::UnlinkedInstruction::UnlinkedInstruction):
+        (JSC::UnlinkedCodeBlock::numberOfExceptionHandlers):
+        (JSC::UnlinkedCodeBlock::addExceptionHandler):
+        (JSC::UnlinkedCodeBlock::exceptionHandler):
+        (JSC::UnlinkedCodeBlock::symbolTable):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+
+2015-05-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Non-speculative Branch should be fast in the FTL
+        https://bugs.webkit.org/show_bug.cgi?id=145452
+
+        Reviewed by Andreas Kling.
+        
+        Inlines the code for convertJSValueToBoolean into the FTL. This also includes some other
+        clean-ups that I found along the way.
+        
+        I found this by looking at the hottest functions in DeltaBlue. Despite having so many
+        Branch specializations, apparently there was still a hot one that we missed that was going
+        down the untyped path. It was either Int32 or Other. Maybe we could specialize for that
+        combo, but it makes so much sense to just make all of this nonsense fast.
+
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle): Need to watch the masquerades watchpoint on UntypedUse: forms of Branch now.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::boolify): The actual fix.
+        (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::isInt32):
+        (JSC::FTL::LowerDFGToLLVM::isNotInt32):
+        (JSC::FTL::LowerDFGToLLVM::unboxInt32):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::toBoolean): Symbol is always true.
+        (JSC::JSCell::pureToBoolean): Symbol is always true.
+        * runtime/JSString.cpp:
+        (JSC::JSString::getPrimitiveNumber):
+        (JSC::JSString::toNumber):
+        (JSC::JSString::toBoolean): Deleted. This is a tiny method. It doesn't need to be out-of-line.
+        * runtime/JSString.h:
+        (JSC::JSString::length):
+        (JSC::JSString::toBoolean): This method shouldbe inline.
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::toPrimitive):
+        (JSC::Symbol::getPrimitiveNumber):
+        (JSC::Symbol::toBoolean): Deleted. A Symbol is always true, so we don't need a method for this.
+        * runtime/Symbol.h:
+
+2015-05-29  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184860.
+        https://bugs.webkit.org/show_bug.cgi?id=145456
+
+        May have caused ~1% Octane regression (Requested by kling on
+        #webkit).
+
+        Reverted changeset:
+
+        "Try to use StringView when comparing JSStrings for equality."
+        https://bugs.webkit.org/show_bug.cgi?id=145379
+        http://trac.webkit.org/changeset/184860
+
+2015-05-28  Michael Saboff  <msaboff@apple.com>
+
+        mozilla/js1_5/Array/regress-154338.js test causes ARM 32 bit iOS devices to run out of memory
+        https://bugs.webkit.org/show_bug.cgi?id=145444
+
+        Reviewed by Geoffrey Garen.
+
+        Disabled mozilla/js1_5/Array/regress-154338.js when run on iOS ARM 32 bit devices and
+        the --memory-limited option is passed to run-jsc-stress-tests.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2015-05-28  Benjamin Poulain  <benjamin@webkit.org>
+
+        [iOS8][ARMv7(s)] Optimized Object.create in 'use strict' context sometimes breaks.
+        https://bugs.webkit.org/show_bug.cgi?id=138038
+
+        Reviewed by Michael Saboff.
+
+        TL;DR: sometimes the baseline JIT could accidentally nuke the tag before calling
+               to C++, making put_by_id behave erratically.
+
+        The bug was that put_by_id would randomly not work correctly in 32bits. It happened
+        in the baseline JIT if we were unlucky enough:
+        -The code get hot enough and the structure is stable so we get a fast path for
+         put_by_id.
+        -We repatch the fast-path branch with a stub generated by
+         emitPutTransitionStubAndGetOldStructure().
+        -In emitPutTransitionStubAndGetOldStructure(), we only preserve the payload of the base
+         register, the tag register is ignored.
+        -emitPutTransitionStubAndGetOldStructure() allocate 2 to 3 registers. Any of those
+         could be the one used for the base's tag before the fast path and the value is trashed.
+        -If we hit one of the failure case, we fallback to the slow path, but we destroyed
+         the tag pointer.
+        -We now have unrelated bits in the tag, the most likely value type is now "double"
+         and we fail the put_by_id because we try to set a property on a number.
+
+        The most obvious solution would be to change emitPutTransitionStubAndGetOldStructure()
+        to preserve the tag register in addition to the value register.
+        I decided against that option because of the added complexity. The DFG does not need
+        that case, so I would have to add branches everywhere to distinguish the cases
+        were we need to preserve the tag or not.
+
+        Instead, I just load the tag back from memory in the slow path. The function in the slow
+        path is several order of magnitude slower than a load, it is not worth eliminating it,
+        especially in baseline JIT.
+
+        I also discovered 4 useless loads in the fast path, so even with my extra load, this patch
+        makes the baseline faster :)
+
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitSlow_op_put_by_id):
+        (JSC::JIT::emit_op_put_by_id): Deleted.
+        * tests/stress/put-by-id-on-new-object-after-prototype-transition-non-strict.js: Added.
+        (opaqueNewObject):
+        (putValueOnNewObject):
+        * tests/stress/put-by-id-on-new-object-after-prototype-transition-strict.js: Added.
+        (string_appeared_here.opaqueNewObject):
+        (putValueOnNewObject):
+
+2015-05-28  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] reduction the iteration count of the DoubleRep stress tests
+
+        Once again, I used big numbers for manual testing and I forgot to fix them before landing.
+
+        * tests/stress/double-rep-with-non-cell.js:
+        * tests/stress/double-rep-with-null.js:
+        * tests/stress/double-rep-with-undefined.js:
+
+2015-05-28  Basile Clement  <basile_clement@apple.com>
+
+        Add debug mode assertions for accessors casting JSC::DFG::Node.m_opInfo
+        https://bugs.webkit.org/show_bug.cgi?id=145441
+
+        Reviewed by Filip Pizlo.
+
+        Most accessor functions casting m_opInfo in JSC::DFG::Node are
+        performing debug checks that they are only accessed for node types that
+        should have them. This patch adds similar checks for the accessors that
+        were missing them.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::watchpointSet):
+        (JSC::DFG::Node::storagePointer):
+        (JSC::DFG::Node::multiGetByOffsetData):
+        (JSC::DFG::Node::multiPutByOffsetData):
+        (JSC::DFG::Node::hasTypeLocation):
+        (JSC::DFG::Node::typeLocation):
+        (JSC::DFG::Node::hasBasicBlockLocation):
+        (JSC::DFG::Node::basicBlockLocation):
+
+2015-05-28  Matt Rajca  <mrajca@apple.com>
+
+        Add ENABLE_MEDIA_SESSION feature flag (which is off by default).
+        https://bugs.webkit.org/show_bug.cgi?id=145415
+
+        Reviewed by Eric Carlson.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-05-27  Jordan Harband  <ljharb@gmail.com>
+
+        Array.of should work with other constructors
+        https://bugs.webkit.org/show_bug.cgi?id=145365
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of
+        step 4
+
+        Reviewed by Yusuke Suzuki.
+
+        * builtins/ArrayConstructor.js:
+        (of):
+        * runtime/ArrayConstructor.cpp:
+        (JSC::arrayConstructorOf): Deleted.
+
+2015-05-27  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Add undefined->double conversion to DoubleRep
+        https://bugs.webkit.org/show_bug.cgi?id=145293
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds undefined to double conversion to the DoubleRep
+        node for the cases were we speculate "undefined" as part of the types
+        processed.
+
+        The use case is doing math with accidental out-of-bounds access. For example,
+        something like:
+            for (var i = 0; i <= length; ++i)
+                ouptput += array[i];
+
+        would cause us to OSR exit every time i === length.
+
+        When hitting one of those cases, we would already speculate double math,
+        but the DoubleRep node was unable to convert the undefined and would exit.
+
+        With this patch the use kind NotCellUse cover this conversion for DoubleRep.
+        I have been quite conservative so in general we will not find "undefined"
+        until a few recompile but being optimistic seems better since this is a corner case.
+
+        This patch is a 80% progression on WebXPRT's DNA Sequencing test.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::sawUndefined):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
+        * tests/stress/double-rep-with-undefined.js: Added.
+        (addArgsNumberAndUndefined):
+        (addArgsInt32AndUndefined):
+        (testFallbackWithDouble):
+        (addArgsDoubleAndUndefined):
+        (testFallbackWithObject.):
+        (testFallbackWithObject):
+        (addArgsOnlyUndefined):
+        (testFallbackWithString):
+
+2015-05-27  Dean Jackson  <dino@apple.com>
+
+        img.currentSrc problem in strict mode with old picturefill
+        https://bugs.webkit.org/show_bug.cgi?id=144095
+        <rdar://problem/21087013>
+
+        Reviewed by Simon Fraser.
+
+        Add a PICTURE_SIZES flag.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-05-27  Basile Clement  <basile_clement@apple.com>
+
+        LazyNode comparison can return incorrect results when comparing an empty value
+        https://bugs.webkit.org/show_bug.cgi?id=145421
+
+        Reviewed by Geoffrey Garen.
+
+        When comparing a LazyNode to another, we compare the value pointers if
+        we have one, and otherwise compare the nodes.
+        We should be comparing value pointers if the other LazyNode has one as
+        well, otherwise we risk an incoherency when we are a empty LazyNode
+        being compared to a FrozenValue without node.
+
+        Note that this is not a problem in any other case because if we don't
+        have a FrozenValue and we are not an empty LazyNode, we are a
+        non-constant node, and comparing the node pointers is correct.
+
+        * dfg/DFGLazyNode.h:
+        (JSC::DFG::LazyNode::operator==):
+
+2015-05-27  Geoffrey Garen  <ggaren@apple.com>
+
+        REGRESSION: These sorting idioms used by Peacekeeper and Browsermark are ~20X slower
+        https://bugs.webkit.org/show_bug.cgi?id=145412
+
+        Reviewed by Benjamin Poulain.
+
+        Cache strings when doing a string-converting sort.
+
+        This is a 21% speedup.
+
+        * builtins/Array.prototype.js:
+        (sort.stringComparator): Use subtraction instead of branching because
+        it's slightly faster.
+
+        (sort.comparatorSort):
+        (sort.stringSort):
+        (sort): Add a special case for string sorting to avoid redundant string
+        conversion.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::createBindingPattern): Names can be empty if
+        they are private names.
+
+2015-05-26  Filip Pizlo  <fpizlo@apple.com>
+
+        JIT-generated store barrier code should assume the buffer pointer and capacity to be compile-time constants
+        https://bugs.webkit.org/show_bug.cgi?id=145404
+
+        Reviewed by Andreas Kling.
+        
+        We never change the capacity of a write barrier buffer. We never repoint the buffer
+        pointer. So, the JIT shouldn't load those from memory; it should take advantage of the
+        fact that these are compile-time constants.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        * heap/WriteBarrierBuffer.h:
+        (JSC::WriteBarrierBuffer::currentIndexAddress):
+        (JSC::WriteBarrierBuffer::capacity):
+        (JSC::WriteBarrierBuffer::buffer):
+        (JSC::WriteBarrierBuffer::currentIndexOffset): Deleted.
+        (JSC::WriteBarrierBuffer::capacityOffset): Deleted.
+        (JSC::WriteBarrierBuffer::bufferOffset): Deleted.
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStubAndGetOldStructure):
+
+2015-05-27  Geoffrey Garen  <ggaren@apple.com>
+
+        REGRESSION: These sorting idioms used by Peacekeeper and Browsermark are ~20X slower
+        https://bugs.webkit.org/show_bug.cgi?id=145412
+
+        Reviewed by Darin Adler.
+
+        Use @toString instead of the String constructor because calls to the
+        String constructor are never optimized. (See
+        https://bugs.webkit.org/show_bug.cgi?id=144458.)
+
+        This is a ~2X speedup.
+
+        * builtins/Array.prototype.js:
+        (sort.stringComparator):
+
+2015-05-27  Dan Bernstein  <mitz@apple.com>
+
+        Remove JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
+        https://bugs.webkit.org/show_bug.cgi?id=145403
+
+        Reviewed by Anders Carlsson.
+
+        JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080 was used to enable the JavaScriptCore Objective-C API
+        for WebKit and Safari projects building with JavaScriptCore targeting OS X 10.8. We don’t
+        need it anymore.
+
+        * API/JSBase.h:
+        * API/JSContext.h:
+        * API/JSManagedValue.h:
+        * API/JSValue.h:
+        * API/JSVirtualMachine.h:
+        * Configurations/Base.xcconfig:
+        * postprocess-headers.sh:
+
+2015-05-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Photo Booth hangs under JSC::MachineThreads::tryCopyOtherThreadStacks
+        https://bugs.webkit.org/show_bug.cgi?id=145395
+
+        Reviewed by Mark Hahnenberg.
+
+        No test case because we already have --threaded mode, which runs lots of
+        parallel GC, but it (and the original in-app test case) can't reproduce
+        this bug.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::tryCopyOtherThreadStacks): Use a lock to prevent
+        two threads from mutually suspending each other.
+
+2015-05-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Add Array.prototype.copyWithin to JSC features.json
+        https://bugs.webkit.org/show_bug.cgi?id=145387
+
+        Reviewed by Darin Adler.
+
+        * features.json:
+
+2015-05-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Reflect nits for r184863
+        https://bugs.webkit.org/show_bug.cgi?id=145107
+
+        Reviewed by Darin Adler.
+
+        1. Added the copyright line.
+        2. Added an optional argument (/*, end */). To do so, fixed generate-js-builtins.
+        3. Dropped the unnecessary variable `thisValue`.
+        4. Fix the type error messages. This is also found in StringIterator.prototype.js.
+        5. Added tests for 0 arguments.
+
+        * builtins/Array.prototype.js:
+        (copyWithin):
+        * builtins/StringIterator.prototype.js:
+        (next):
+        * generate-js-builtins:
+        * tests/stress/array-copywithin.js:
+        * tests/stress/string-iterators.js:
+
+2015-05-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Inline @Array / @Object callsites
+        https://bugs.webkit.org/show_bug.cgi?id=145382
+
+        Reviewed by Geoffrey Garen.
+
+        As the same to Array/Object callsite inlining, @Array/@Object also
+        should be inlined in bytecode level.
+        While `new @Object` style is not encouraged in the builtins,
+        `@Array(len)` is already used at least in Array.from code.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::expectedFunctionForIdentifier):
+
+2015-05-26  Andreas Kling  <akling@apple.com>
+
+        String.prototype.charCodeAt() should use StringView.
+        <https://webkit.org/b/145353>
+
+        Reviewed by Darin Adler.
+
+        Use JSString::view() in charCodeAt() to avoid reifying the JSString if it's
+        a substring. This avoids StringImpl allocation in some cases and ref churn
+        in all cases.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncCharCodeAt):
+
+2015-05-26  Andreas Kling  <akling@apple.com>
+
+        String.prototype.charAt() should use StringView.
+        <https://webkit.org/b/145352>
+
+        Reviewed by Darin Adler.
+
+        Remove the jsSingleCharacterSubstring() function since it's actually completely
+        counter-productive: it could create a single-character string that would retain
+        a much larger string for the duration of its lifetime.
+
+        This made sense before StringImpl learned to put its characters at the tail end
+        of its own allocation. Now that it does, it's far better to just create a new
+        single-character StringImpl.
+
+        With that out of the way, we can make String.prototype.charAt() use StringView
+        to avoid reifying substring JSStrings (and avoid some ref churn too.)
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::getIndexSlowCase):
+        * runtime/JSString.h:
+        (JSC::JSString::getIndex):
+        (JSC::jsSingleCharacterSubstring): Deleted.
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncCharAt):
+        (JSC::stringProtoFuncSplit):
+
+2015-05-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement Array.prototype.copyWithin
+        https://bugs.webkit.org/show_bug.cgi?id=145107
+
+        Reviewed by Darin Adler.
+
+        This patch implements ES6 Array.prototype.copyWithin.
+        It is intended to be used for copying the region to the other region
+        in the callee array itself safely (like memmove, not memcpy).
+        This function is proposed in the context of WebGL.
+
+        * builtins/Array.prototype.js:
+        (.maxWithPositives):
+        (.minWithMaybeNegativeZeroAndPositive):
+        (copyWithin):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        * tests/stress/array-copywithin.js: Added.
+        (shouldBe):
+        (shouldBeArray):
+        (shouldThrow):
+        (arrayToObject):
+        (valueOf):
+
+2015-05-26  Dan Bernstein  <mitz@apple.com>
+
+        <rdar://problem/21104551> Update build settings
+
+        Reviewed by Anders Carlsson.
+
+        * Configurations/DebugRelease.xcconfig:
+        * Configurations/FeatureDefines.xcconfig:
+        * Configurations/Version.xcconfig:
+
+2015-05-26  Andreas Kling  <akling@apple.com>
+
+        Try to use StringView when comparing JSStrings for equality.
+        <https://webkit.org/b/145379>
+
+        Reviewed by Darin Adler.
+
+        Use JSString::view() when sending two JSStrings to WTF::equal()
+        for comparison. This avoids creating new objects in the case where
+        the strings are actually substrings.
+
+        * jit/JITOperations.cpp:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::equalSlowCaseInline):
+        (JSC::JSValue::strictEqualSlowCaseInline):
+
+2015-05-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] Generate put_by_val_direct for indexed identifiers instead of put_by_id with direct postfix
+        https://bugs.webkit.org/show_bug.cgi?id=145360
+
+        Reviewed by Darin Adler.
+
+        JSObject::putDirect only accepts non-indexed properties.
+        So when generating put_by_id (with direct postfix) for indexed property,
+        we should generate put_by_val_direct instead.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitPutConstantProperty):
+        * tests/stress/put-by-id-direct-should-be-done-for-non-index-property.js: Added.
+
+2015-05-24  Jordan Harband  <ljharb@gmail.com>
+
+        Array#findIndex/find should not skip holes
+        https://bugs.webkit.org/show_bug.cgi?id=145361
+        per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.findindex
+        and https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.find
+
+        Reviewed by Yusuke Suzuki.
+
+        * builtins/Array.prototype.js:
+        (find): Deleted.
+        (findIndex): Deleted.
+
+2015-05-24  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: Uncaught exception when using Inspect tool on SVG elements
+        https://bugs.webkit.org/show_bug.cgi?id=145363
+
+        Reviewed by Joseph Pecoraro.
+
+        The injected script failed by chaining a call to String.prototype.trim to the result of
+        SVG*Element.className, which is an SVGAnimatedString and lacks useful methods. So, obtain
+        the class name using Node.getAttribute, which always returns a DOMString.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScriptSource.prototype._getDescription): use getAttribute instead of className.
+
+2015-05-23  Dan Bernstein  <mitz@apple.com>
+
+        Remove unused definitions of WEBKIT_VERSION_MIN_REQUIRED
+        https://bugs.webkit.org/show_bug.cgi?id=145345
+
+        Reviewed by Sam Weinig.
+
+        * Configurations/Base.xcconfig: Also changed to use $(inherited).
+
+2015-05-23  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Introduce UniquedStringImpl and SymbolImpl to separate symbolic strings from AtomicStringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=144848
+
+        Reviewed by Darin Adler.
+
+        Use UniquedStringImpl, SymbolImpl and AtomicStringImpl.
+
+        * API/JSCallbackObject.h:
+        * builtins/BuiltinNames.h:
+        (JSC::BuiltinNames::isPrivateName):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/ComplexGetStatus.cpp:
+        (JSC::ComplexGetStatus::computeFor):
+        * bytecode/ComplexGetStatus.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        (JSC::GetByIdStatus::computeFor):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/Instruction.h:
+        (JSC::Instruction::Instruction):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::visibleNameForParameter):
+        (JSC::BytecodeGenerator::hasConstant):
+        (JSC::BytecodeGenerator::addConstant):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitBytecode):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGDesiredIdentifiers.cpp:
+        (JSC::DFG::DesiredIdentifiers::addLazily):
+        (JSC::DFG::DesiredIdentifiers::at):
+        (JSC::DFG::DesiredIdentifiers::reallyAdd):
+        * dfg/DFGDesiredIdentifiers.h:
+        (JSC::DFG::DesiredIdentifiers::operator[]):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::identifierUID):
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLInlineCacheDescriptor.h:
+        (JSC::FTL::InlineCacheDescriptor::InlineCacheDescriptor):
+        (JSC::FTL::InlineCacheDescriptor::uid):
+        (JSC::FTL::GetByIdDescriptor::GetByIdDescriptor):
+        (JSC::FTL::PutByIdDescriptor::PutByIdDescriptor):
+        (JSC::FTL::CheckInDescriptor::CheckInDescriptor):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compilePutById):
+        (JSC::FTL::LowerDFGToLLVM::compileIn):
+        (JSC::FTL::LowerDFGToLLVM::compileMaterializeCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::getById):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * ftl/FTLSlowPathCall.cpp:
+        (JSC::FTL::callOperation):
+        * ftl/FTLSlowPathCall.h:
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * parser/Nodes.cpp:
+        (JSC::ProgramNode::setClosedVariables):
+        * parser/Nodes.h:
+        (JSC::ScopeNode::captures):
+        (JSC::ScopeNode::setClosedVariables):
+        (JSC::ProgramNode::closedVariables):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::didFinishParsing):
+        (JSC::Parser<LexerType>::parseContinueStatement):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::pushLabel):
+        (JSC::Scope::getLabel):
+        (JSC::Scope::declareCallee):
+        (JSC::Scope::declareVariable):
+        (JSC::Scope::declareParameter):
+        (JSC::Scope::declareBoundParameter):
+        (JSC::Scope::useVariable):
+        (JSC::Scope::copyCapturedVariablesToVector):
+        (JSC::Parser::closedVariables):
+        (JSC::ScopeLabelInfo::ScopeLabelInfo): Deleted.
+        * parser/SourceProviderCacheItem.h:
+        (JSC::SourceProviderCacheItem::usedVariables):
+        (JSC::SourceProviderCacheItem::writtenVariables):
+        (JSC::SourceProviderCacheItem::create):
+        * runtime/CommonIdentifiers.cpp:
+        (JSC::CommonIdentifiers::isPrivateName):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Identifier.h:
+        (JSC::Identifier::impl):
+        (JSC::Identifier::Identifier):
+        (JSC::parseIndex):
+        (JSC::IdentifierRepHash::hash):
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::fromUid):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::mayInterceptStoreTo):
+        * runtime/IntendedStructureChain.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/Lookup.h:
+        (JSC::HashTable::entry):
+        * runtime/MapData.h:
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertySymbols):
+        * runtime/PrivateName.h:
+        (JSC::PrivateName::PrivateName):
+        (JSC::PrivateName::uid):
+        * runtime/PropertyMapHashTable.h:
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (JSC::PropertyName::uid):
+        (JSC::PropertyName::publicName):
+        (JSC::parseIndex):
+        * runtime/PropertyNameArray.h:
+        (JSC::PropertyNameArray::addKnownUnique):
+        (JSC::PropertyNameArray::add):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::contains):
+        (JSC::StructureTransitionTable::get):
+        (JSC::StructureTransitionTable::add):
+        (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
+        (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
+        (JSC::Structure::getConcurrently):
+        (JSC::Structure::add):
+        (JSC::Structure::remove):
+        (JSC::Structure::toStructureShape):
+        * runtime/Structure.h:
+        (JSC::PropertyMapEntry::PropertyMapEntry):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::getConcurrently):
+        * runtime/StructureTransitionTable.h:
+        (JSC::StructureTransitionTable::Hash::hash):
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::Symbol):
+        * runtime/Symbol.h:
+        * runtime/SymbolConstructor.cpp:
+        (JSC::symbolConstructorFor):
+        (JSC::symbolConstructorKeyFor):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::uniqueIDForVariable):
+        (JSC::SymbolTable::globalTypeSetForVariable):
+        * runtime/SymbolTable.h:
+        * runtime/TypeSet.cpp:
+        (JSC::StructureShape::addProperty):
+        (JSC::StructureShape::propertyHash):
+        * runtime/TypeSet.h:
+
+2015-05-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Arguments elimination phase mishandles arity check failure in its reduction of LoadVarargs to GetStack/PutStacks
+        https://bugs.webkit.org/show_bug.cgi?id=145298
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGArgumentsEliminationPhase.cpp: Fix the bug. I restructured the loop to make it more obvious that we're initializing everything that we're supposed to initialize.
+        * dfg/DFGNode.h: Add a comment to clarify something I was confused about while writing this code.
+        * dfg/DFGPutStackSinkingPhase.cpp: Hacking on PutStacks made me think deep thoughts, and I added some FIXMEs.
+        * tests/stress/fold-load-varargs-arity-check-fail-barely.js: Added. This test crashes or fails before this patch.
+        * tests/stress/fold-load-varargs-arity-check-fail.js: Added. This is even more sure to crash or fail.
+        * tests/stress/simplify-varargs-mandatory-minimum-smaller-than-limit.js: Added. Not sure if we had coverage for this case before.
+
+2015-05-22  Basile Clement  <basile_clement@apple.com>
+
+        Allow DFGClobberize to return non-node constants that must be later created
+        https://bugs.webkit.org/show_bug.cgi?id=145272
+
+        Reviewed by Filip Pizlo.
+
+        This adds a new LazyNode class in DFG that represents either a Node*,
+        or a FrozenValue* with a way to convert it to a Node* provided a block
+        to insert it into. DFGClobberize is converted to use LazyNode instead
+        of Node* when def()'ing values, which allows to now define the array's
+        length as well as the value of its various fields in NewArray and
+        NewArrayBuffer nodes.
+
+        We also introduce a Vector<uint32_t> in DFG::Graph to collect all the
+        values that can be used as index, in order to avoid def()'ing too many
+        values at once for big NewArrayBuffers.
+
+        HeapLocation had to be updated to use a LazyNode as its index to be
+        able to define array values.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        (JSC::DFG::DefMethodClobberize::operator()):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::freezeFragile):
+        * dfg/DFGGraph.h:
+        * dfg/DFGHeapLocation.h:
+        (JSC::DFG::HeapLocation::HeapLocation):
+        (JSC::DFG::HeapLocation::index):
+        (JSC::DFG::HeapLocation::hash):
+        * dfg/DFGLazyNode.cpp: Added.
+        (JSC::DFG::LazyNode::dump):
+        * dfg/DFGLazyNode.h: Added.
+        (JSC::DFG::LazyNode::LazyNode):
+        (JSC::DFG::LazyNode::setNode):
+        (JSC::DFG::LazyNode::isHashTableDeletedValue):
+        (JSC::DFG::LazyNode::isNode):
+        (JSC::DFG::LazyNode::op):
+        (JSC::DFG::LazyNode::asNode):
+        (JSC::DFG::LazyNode::asValue):
+        (JSC::DFG::LazyNode::hash):
+        (JSC::DFG::LazyNode::operator==):
+        (JSC::DFG::LazyNode::operator!=):
+        (JSC::DFG::LazyNode::ensureIsNode):
+        (JSC::DFG::LazyNode::operator->):
+        (JSC::DFG::LazyNode::operator*):
+        (JSC::DFG::LazyNode::operator!):
+        (JSC::DFG::LazyNode::operator UnspecifiedBoolType*):
+        (JSC::DFG::LazyNode::setFrozenValue):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        * dfg/DFGPutStackSinkingPhase.cpp:
+
+2015-05-22  Andreas Kling  <akling@apple.com>
+
+        [JSC] Speed up new array construction in Array.prototype.splice().
+        <https://webkit.org/b/145303>
+
+        Reviewed by Benjamin Poulain.
+
+        Give splice() a fast path just like slice(), for indexing types where the backing
+        store can be memcpy'd. I generalized JSArray::fastSlice() a little bit so it works
+        for this optimization as well.
+
+        7% progression on Kraken/stanford-crypto-pbkdf2.
+
+        * runtime/JSArray.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fastSlice): Tweak this to return JSArray*, and don't bother throwing
+        out-of-memory exceptions. Let the caller worry about that.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSlice): Update for fastSlice() changes.
+        (JSC::arrayProtoFuncSplice): If the object we're splicing out of is a bona fide
+        JSArray, use fastSlice() to create the returned array instead of doing a generic
+        get/put loop.
+
+2015-05-21  Filip Pizlo  <fpizlo@apple.com>
+
+        CPS rethreading should really get rid of GetLocals
+        https://bugs.webkit.org/show_bug.cgi?id=145290
+
+        Reviewed by Benjamin Poulain.
+        
+        CPS rethreading is intended to get rid of redundant GetLocals. CSE can also do it, but
+        the idea is that you should be able to disable CSE and everything would still work. This
+        fixes a bug in CPS rethreading's GetLocal elimination: we should be calling replaceWith
+        rather than setReplacement, since setReplacement still leaves the original node.
+
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor): Fix the bug.
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Eliminating GetLocals means that they turn into Check. We should handle Checks that have zero inputs.
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS): Add a validation for what a GetLocal should look like in ThreadedCPS.
+        * tests/stress/get-local-elimination.js: Added.
+        (foo):
+
+2015-05-21  Saam Barati  <saambarati1@gmail.com>
+
+        Object allocation sinking phase should explicitly create bottom values for CreateActivation sink candidates and CreateActivation should have SymbolTable as a child node
+        https://bugs.webkit.org/show_bug.cgi?id=145192
+
+        Reviewed by Filip Pizlo.
+
+        When we sink CreateActivation and generate MaterializeCreateActivation
+        in the object allocation sinking phase, we now explictly add PutHints for 
+        all variables on the activation setting those variables to their default value 
+        (undefined for Function activations and soon to be JS Empty Value for block scope activations). 
+        This allows us to remove code that fills FTL fast activation allocations with Undefined.
+
+        This patch also adds the constant SymbolTable as an OpInfo of CreateActivation and MaterializeCreateActivation
+        nodes. This is in preparation for ES6 block scoping which will introduce a new 
+        op code that gets lowered to CreateActivation.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::cellOperand):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::compileMaterializeCreateActivation):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * tests/stress/activation-sink-default-value.js: Added.
+        (bar):
+        * tests/stress/activation-sink-osrexit-default-value.js: Added.
+        (foo.set result):
+
+2015-05-21  Per Arne Vollan  <peavo@outlook.com>
+
+        MSVC internal compiler error when compiling TemplateRegistryKey class.
+        https://bugs.webkit.org/show_bug.cgi?id=145259
+
+        Reviewed by Alex Christensen.
+
+        MSVC is not able to handle the brace initialization of a class member in this case.
+
+        * runtime/TemplateRegistryKey.h:
+
+2015-05-21  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Fix the !ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX) build after r184337
+        https://bugs.webkit.org/show_bug.cgi?id=145248
+
+        Reviewed by Yusuke Suzuki.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        * bytecompiler/BytecodeGenerator.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseMemberExpression):
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: array previews should have a much smaller cap on values
+        https://bugs.webkit.org/show_bug.cgi?id=145195
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.RemoteObject.prototype._generatePreview):
+        Reduce the indexes threshold for previews.
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Use native Arguments detection instead of using toString
+        https://bugs.webkit.org/show_bug.cgi?id=145235
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.prototype._subtype):
+        Deleted the old string code.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        Replaced with a stricter, more accurate check.
+
+2015-05-20  Andreas Kling  <akling@apple.com>
+
+        Remove unused MarkedBlock::m_rememberedSet.
+        <https://webkit.org/b/145224>
+
+        Reviewed by Mark Hahnenberg.
+
+        The MarkedBlock had a copy of the remembered bit for each of its cells,
+        and we were maintaining that bitmap despite no one actually ever consulting it.
+
+        This patch removes MarkedBlock::m_rememberedSet, freeing up 128 bytes in each
+        block and making write barriers a little faster.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::clearRememberedSet):
+        (JSC::Heap::addToRememberedSet):
+        * heap/HeapInlines.h:
+        (JSC::Heap::isRemembered):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::clearRememberedSet): Deleted.
+        (JSC::MarkedBlock::clearMarksWithCollectionType):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::setRemembered): Deleted.
+        (JSC::MarkedBlock::clearRemembered): Deleted.
+        (JSC::MarkedBlock::atomicClearRemembered): Deleted.
+        (JSC::MarkedBlock::isRemembered): Deleted.
+        * heap/MarkedSpace.h:
+        (JSC::ClearRememberedSet::operator()): Deleted.
+        (JSC::MarkedSpace::clearRememberedSet): Deleted.
+
+2015-05-20  Andreas Kling  <akling@apple.com>
+
+        Eden collections should extend the IncrementalSweeper work list, not replace it.
+        <https://webkit.org/b/145213>
+        <rdar://problem/21002666>
+
+        Reviewed by Geoffrey Garen.
+
+        After an eden collection, the garbage collector was adding all MarkedBlocks containing
+        new objects to the IncrementalSweeper's work list, to make sure they didn't have to
+        wait until the next full collection before getting swept.
+
+        Or at least, that's what it thought it was doing. It turns out that IncrementalSweeper's
+        internal work list is really just a reference to Heap::m_blockSnapshot. I didn't realize
+        this when writing the post-eden sweep code, and instead made eden collections cancel
+        all pending sweeps and *replace* them with the list of blocks with new objects.
+
+        This made it so that rapidly occurring eden collections could prevent large numbers of
+        heap blocks from ever getting swept. This would manifest as accumulation of MarkedBlocks
+        when a system under heavy load was also allocating short lived objects at a high rate.
+        Things would eventually get cleaned up when there was a lull and a full collection was
+        allowed to run its heap sweep to completion.
+
+        Fix this by moving all management of the block snapshot to Heap. snapshotMarkedSpace()
+        now handles eden collections by merging the list of blocks with new objects into the
+        existing block snapshot.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::snapshotMarkedSpace):
+        (JSC::Heap::notifyIncrementalSweeper):
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::startSweeping):
+        (JSC::IncrementalSweeper::addBlocksAndContinueSweeping): Deleted.
+        * heap/IncrementalSweeper.h:
+
+2015-05-20  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        AudioContext resume/close/suspend should reject promises with a DOM exception in lieu of throwing exceptions
+        https://bugs.webkit.org/show_bug.cgi?id=145064
+
+        Reviewed by Darin Adler.
+
+        Added default message for TypeError.
+
+        * runtime/Error.cpp:
+        (JSC::throwTypeError):
+        * runtime/Error.h:
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        No LLInt Test Failure: jsc-layout-tests.yaml/js/script-tests/object-literal-duplicate-properties.js.layout-no-llint
+        https://bugs.webkit.org/show_bug.cgi?id=145219
+
+        Reviewed by Mark Lam.
+
+        * jit/JITOperations.cpp:
+        Throw the error we just got, instead of a stack overflow exception.
+        This matches other error handling for callers of prepareForExecution.
+
+2015-05-19  Filip Pizlo  <fpizlo@apple.com>
+
+        Add some assertions about the CFG in the loop pre-header creation phase
+        https://bugs.webkit.org/show_bug.cgi?id=145205
+
+        Reviewed by Geoffrey Garen.
+        
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::currentNodeOrigin): Add a FIXME.
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::run): Add a FIXME.
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::LoopPreHeaderCreationPhase::run): Add the assertions.
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Implement Object.setPrototypeOf
+        https://bugs.webkit.org/show_bug.cgi?id=145202
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncProtoSetter):
+        (JSC::checkProtoSetterAccessAllowed):
+        Extract a helper to share this code between __proto__ setter and setPrototypeOf.
+
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorSetPrototypeOf):
+        Implementation is very similiar to __proto__ setter.
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Should not allow duplicate basic __proto__ properties in Object Literals
+        https://bugs.webkit.org/show_bug.cgi?id=145138
+
+        Reviewed by Darin Adler.
+
+        Implement ES6 Annex B.3.1, which disallows duplicate basic __proto__
+        properties in object literals. This doesn't affect computed properties,
+        shorthand properties, or getters/setters all of which avoid setting
+        the actual prototype of the object anyway.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::eval):
+        Remove out of date comment. Duplicate property names are allowed
+        now in ES6, they were not in ES5 strict mode.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::getName):
+        (JSC::ASTBuilder::getType):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::getName):
+        Add back getName to get the property name depending on the tree builder.
+        Also tighten up the parameter types.
+
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::parse):
+        In quick JSON literal parsing for eval, we actually need to evaluate
+        the __proto__ property assignment, instead of just building up a list
+        of direct properties. Only do this when not doing a strict JSON parse.
+
+        * parser/Nodes.h:
+        Add "Shorthand" to the list of PropertyNode types to allow it to
+        be distinguished without relying on other information.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseProperty):
+        Add the Shorthand type when parsing a shorthand property.
+
+        (JSC::Parser<LexerType>::shouldCheckPropertyForUnderscoreProtoDuplicate):
+        (JSC::Parser<LexerType>::parseObjectLiteral):
+        (JSC::Parser<LexerType>::parseStrictObjectLiteral):
+        Check for duplicate __proto__ properties, and throw a SyntaxError
+        if that was the case.
+
+2015-05-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [JSC] Add missing copyrights and licenses for some scripts
+        https://bugs.webkit.org/show_bug.cgi?id=145044
+
+        Reviewed by Darin Adler.
+
+        * build-symbol-table-index.py:
+        * create-llvm-ir-from-source-file.py:
+        * create-symbol-table-index.py:
+
+2015-05-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Slightly better node previews in arrays
+        https://bugs.webkit.org/show_bug.cgi?id=145188
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.prototype._nodeDescription):
+        (InjectedScript.prototype._nodePreview):
+        Different stringified representations for a basic object description or in a preview.
+
+        (InjectedScript.RemoteObject.prototype._appendPropertyPreviews):
+        Use the node preview string representation inside previews.
+
+2015-05-19  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184613 and r184614.
+        https://bugs.webkit.org/show_bug.cgi?id=145206
+
+        Broke 10 tests :| (Requested by kling on #webkit).
+
+        Reverted changesets:
+
+        "[JSC] Speed up URL encode/decode by using bitmaps instead of
+        strchr()."
+        https://bugs.webkit.org/show_bug.cgi?id=145115
+        http://trac.webkit.org/changeset/184613
+
+        "[JSC] Speed up URL encode/decode by using bitmaps instead of
+        strchr()."
+        https://bugs.webkit.org/show_bug.cgi?id=145115
+        http://trac.webkit.org/changeset/184614
+
+2015-05-19  Andreas Kling  <akling@apple.com>
+
+        Give StringView a utf8() API.
+        <https://webkit.org/b/145201>
+
+        Reviewed by Anders Carlsson.
+
+        Use JSString::view() in a few places where we couldn't before due to StringView
+        lacking a utf8() API. This is a minor speed-up on Kraken's crypto subtests,
+        which like to call encode() with substring JSStrings.
+
+        * jsc.cpp:
+        (functionPrint):
+        (functionDebug):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::encode):
+
+2015-05-19  Andreas Kling  <akling@apple.com>
+
+        [JSC] Speed up URL encode/decode by using bitmaps instead of strchr().
+        <https://webkit.org/b/145115>
+
+        Incorporate review feedback from Darin, removing some unnecessary zero checks.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::encode):
+        (JSC::decode):
+        (JSC::globalFuncEscape):
+
+2015-05-19  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Move AtomicStringImpl table related operations from AtomicString to AtomicStringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=145109
+
+        Reviewed by Darin Adler.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::nameForRegister):
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::add):
+        (JSC::Identifier::add8):
+        * runtime/Identifier.h:
+        (JSC::Identifier::add):
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::Identifier):
+        (JSC::Identifier::add):
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::resolveRopeToExistingAtomicString):
+        * runtime/JSString.h:
+        (JSC::JSString::toExistingAtomicString):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStringsStorage::SmallStringsStorage):
+        * runtime/TypeSet.cpp:
+        (JSC::StructureShape::propertyHash):
+
+2015-05-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Improve Preview for NodeList / array like collections
+        https://bugs.webkit.org/show_bug.cgi?id=145177
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        (InjectedScript.RemoteObject.prototype._appendPropertyPreviews):
+        For "array" like object previews skip over non-index properties.
+        We are not marking the object as lossless by choice, but we
+        may return to this decision later.
+
+2015-05-19  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(183787): JIT is enabled for all builds
+        https://bugs.webkit.org/show_bug.cgi?id=145179
+
+        Reviewed by Geoffrey Garen.
+
+        Eliminated the setting of ENABLE_JIT, as wtf/Platform.h has appropriate logic to
+        set it depending on OS and CPU type.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-05-19  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        Rename createIterResultObject as createIteratorResultObject
+        https://bugs.webkit.org/show_bug.cgi?id=145116
+
+        Reviewed by Darin Adler.
+
+        Renamed createIterResultObject as createIteratorResultObject.
+        Made this function exportable for future use by streams API.
+
+        * runtime/IteratorOperations.cpp:
+        (JSC::createIteratorResultObject):
+        * runtime/IteratorOperations.h:
+        * runtime/MapIteratorPrototype.cpp:
+        (JSC::MapIteratorPrototypeFuncNext):
+        * runtime/SetIteratorPrototype.cpp:
+        (JSC::SetIteratorPrototypeFuncNext):
+
+2015-05-19  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Array.prototype methods must use ToLength
+        https://bugs.webkit.org/show_bug.cgi?id=144128
+
+        Reviewed by Oliver Hunt.
+
+        Patch by Jordan Harband  <ljharb@gmail.com> and Yusuke Suzuki <utatane.tea@gmail.com>
+
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+
+        This patch introduces ToLength and ToInteger JS implementation to encourage the DFG/FTL's inlining.
+        These implementations are located in GlobalObject.js.
+        And set to the JSGlobalObject with the private symbols @ToLength and @ToInteger manually.
+
+        * builtins/Array.prototype.js:
+        (every):
+        (forEach):
+        (filter):
+        (map):
+        (some):
+        (fill):
+        (find):
+        (findIndex):
+        (includes):
+        * builtins/ArrayConstructor.js:
+        (from):
+        * builtins/GlobalObject.js: Copied from Source/JavaScriptCore/builtins/StringConstructor.js.
+        (ToInteger):
+        (ToLength):
+        * builtins/StringConstructor.js:
+        (raw):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObjectFunctions.h:
+
+2015-05-19  Mark Lam  <mark.lam@apple.com>
+
+        Fix the build of a universal binary with ARMv7k of JavaScriptCore.
+        https://bugs.webkit.org/show_bug.cgi?id=145143
+
+        Reviewed by Geoffrey Garen.
+
+        The offlineasm works in 3 phases:
+
+        Phase 1:
+           Parse the llint asm files for config options and desired offsets.
+           Let's say the offlineasm discovers C unique options and O unique offsets.
+           The offlineasm will then generate a LLIntDesiredOffsets.h file with
+           C x C build configurations, each with a set of O offsets.
+
+           Each of these build configurations is given a unique configuration index number.
+
+        Phase 2: 
+           Compile the LLIntDesiredOffsets.h file into a JSCLLIntOffsetsExtractor binary.
+
+           If we're building a fat binary with 2 configurations: armv7, and armv7k,
+           then the fat binary will contain 2 blobs of offsets, one for each of these
+           build configurations.
+
+        Phase 3:
+           Parse the llint asm files and emit asm code using the offsets that are
+           extracted from the JSCLLIntOffsetsExtractor binary for the corresponding
+           configuration index number.
+
+        In the pre-existing code, there are no "if ARMv7k" statements in the llint asm
+        source.  As a result, OFFLINE_ASM_ARMv7k is not one of the config options in
+        the set of C unique options.
+
+        For armv7k builds, OFFLINE_ASM_ARMv7 is also true.  As a result, for an armv7k
+        target, we will end up building armv7 source.  In general, this is fine except:
+
+        1. armv7k has different alignment requirements from armv7.  Hence, their offset
+           values (in JSCLLIntOffsetsExtractor) will be different.
+
+        2. The offlineasm was never told that it needed to make a different configuration
+           for armv7k builds.  Hence, the armv7k build of LLIntDesiredOffsets.h will
+           build the armv7 configuration, and consequently, the armv7k blob of offsets in
+           JSCLLIntOffsetsExtractor will have the same configuration index number as
+           the armv7 blob of offsets.
+
+        In phase 3, when the offlineasm parses the JSCLLIntOffsetsExtractor fat binary
+        looking for the armv7 build's configuration index number, it discovers the
+        armv7k blob which has the same configuration number.  As a result, it
+        erroneously thinks the armv7k offsets are appropriate for emitting armv7 code.
+        Needless to say, armv7 code using armv7k offsets will lead to incorrect behavior
+        and all round badness.
+
+        The fix is to add a simple "if ARMv7k" statement to the llint asm files.  While
+        the if statement has no body, it does make the offlineasm aware of the need for
+        ARMv7k as a configuration option.  As a result, it will generate an armv7k
+        variant configuration in the LLIntDesiredOffsets.h file with its own unique
+        configuration index number.  With that, the JSCLLIntOffsetsExtractor fat binary
+        will no longer have duplicate configuration index numbers for the armv7 and
+        armv7k blobs of offsets, and the issue is resolved.
+
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LowLevelInterpreter.asm:
+
+2015-05-19  Andreas Kling  <akling@apple.com>
+
+        Give JSString a StringView getter and start using it.
+        <https://webkit.org/b/145131>
+
+        Reviewed by Anders Carlsson.
+
+        When JSString is a substring internally, calling value(ExecState*) on it
+        will reify the baseString/start/length tuple into a new StringImpl.
+
+        For clients that only want to look at the characters of a JSString, but
+        don't actually need a reffable StringImpl, adding a light-weight StringView
+        getter lets them avoid constructing anything.
+
+        This patch adds JSString::view(ExecState*) and uses it in a few places.
+        There are many more opportunities to use this API, but let's do a few things
+        at a time.
+
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::decode):
+        (JSC::parseInt):
+        (JSC::jsToNumber):
+        (JSC::parseFloat):
+        (JSC::globalFuncParseInt):
+        (JSC::globalFuncParseFloat):
+        (JSC::globalFuncEscape):
+        (JSC::globalFuncUnescape):
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/JSONObject.cpp:
+        (JSC::JSONProtoFuncParse):
+        * runtime/JSString.cpp:
+        (JSC::JSString::getPrimitiveNumber):
+        (JSC::JSString::toNumber):
+        * runtime/JSString.h:
+        (JSC::JSRopeString::view):
+        (JSC::JSString::view):
+
+2015-05-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Better optimize 'if' with ternaries conditional tests.
+        https://bugs.webkit.org/show_bug.cgi?id=144136
+
+        Reviewed by Benjamin Poulain.
+        
+        This is the last fix I'll do for this for now. BooleanToNumber(Untyped:) where the input
+        is proved to be either BoolInt32 or Boolean should be optimized to just masking the
+        lowest bit.
+        
+        This is another 37% speed-up on JSRegress/slow-ternaries.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileBooleanToNumber):
+
+2015-05-18  Benjamin Poulain  <bpoulain@apple.com>
+
+        <rdar://problem/21003555> cloberrize() is wrong for ArithRound because it doesn't account for the arith mode
+        https://bugs.webkit.org/show_bug.cgi?id=145147
+
+        Reviewed by Filip Pizlo.
+
+        Really stupid bug: ArithRound nodes with different rounding modes
+        were not distinguished and CSE would happily unify with a node of
+        a different rounding mode.
+
+        DFG::clobberize() already support additional data but I was not using it.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * tests/stress/math-round-arith-rounding-mode.js: Added.
+        (firstCareAboutZeroSecondDoesNot):
+        (firstDoNotCareAboutZeroSecondDoes):
+        (warmup):
+        (verifyNegativeZeroIsPreserved):
+
+2015-05-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Add SpecBoolInt32 type that means "I'm an int and I'm either 0 or 1"
+        https://bugs.webkit.org/show_bug.cgi?id=145137
+
+        Reviewed by Benjamin Poulain.
+        
+        It's super useful to know if an integer value could be either zero or one. We have an
+        immediate need for this because of Int32|Boolean uses, where knowing that the Int32 is
+        either 0 or 1 means that there is no actual polymorphism if you just look at the low bit
+        (1 behaves like true, 0 behaves like false, and the low bit of 1|true is 1, and the low
+        bit of 0|false is 0).
+        
+        We do this by splitting the SpecInt32 type into SpecBoolInt32 and SpecNonBoolInt32. This
+        change doesn't have any effect on behavior, yet. But it does give us the ability to
+        predict and prove when values are SpecBoolInt32; it's just we don't leverage this yet.
+        
+        This is perf-neutral.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationToAbbreviatedString):
+        (JSC::speculationFromValue):
+        * bytecode/SpeculatedType.h:
+        (JSC::isStringOrStringObjectSpeculation):
+        (JSC::isBoolInt32Speculation):
+        (JSC::isInt32Speculation):
+        (JSC::isInt32OrBooleanSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
+2015-05-18  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        [CMake] Ignore warnings in system headers
+        https://bugs.webkit.org/show_bug.cgi?id=144747
+
+        Reviewed by Darin Adler.
+
+        Separate include directories into WebKit project includes and system includes. Suppress all
+        warnings from headers in system include directories using the SYSTEM argument to
+        the include_directories command.
+
+        * CMakeLists.txt:
+        * PlatformGTK.cmake:
+
+2015-05-18  Skachkov Alexandr  <gskachkov@gmail.com>
+
+        [ES6] Arrow function syntax. Feature flag for arrow function
+        https://bugs.webkit.org/show_bug.cgi?id=145108
+
+        Reviewed by Ryosuke Niwa.
+
+        Added feature flag ENABLE_ES6_ARROWFUNCTION_SYNTAX for arrow function
+
+        * Configurations/FeatureDefines.xcconfig:
+        
+2015-05-18  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] When entering a CheckTierUp without OSREntry, force the CheckTierUp for the outer loops with OSR Entry
+        https://bugs.webkit.org/show_bug.cgi?id=145092
+
+        Reviewed by Filip Pizlo.
+
+        When we have a hot loop without OSR Entry inside a slower loop that support OSR Entry,
+        we get the inside loop driving the tierUpCounter and we have very little chance of
+        doing a CheckTierUp on the outer loop. In turn, this give almost no opportunity to tier
+        up in the outer loop and OSR Enter there.
+
+        This patches changes CheckTierUp to force its outer loops to do a CheckTierUp themselves.
+
+        To do that, CheckTierUp sets a flag "nestedTriggerIsSet" to force the outer loop to
+        enter their CheckTierUp regardless of the tier-up counter.
+
+        * bytecode/ExecutionCounter.cpp:
+        (JSC::ExecutionCounter<countingVariant>::setThreshold):
+        This is somewhat unrelated. This assertion is incorrect because it relies on
+        m_counter, which changes on an other thread.
+
+        I have hit it a couple of times with this patch because we are a bit more aggressive
+        on CheckTierUp. What happens is:
+        1) ExecutionCounter<countingVariant>::checkIfThresholdCrossedAndSet() first checks
+           hasCrossedThreshold(), and it is false.
+        2) On the main thread, the hot loops keeps running and the counter becomes large
+           enough to cross the threshold.
+        3) ExecutionCounter<countingVariant>::checkIfThresholdCrossedAndSet() runs the next
+           test, setThreshold(), where the assertion is. Since the counter is now large enough,
+           the assertion fails.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+        * dfg/DFGJITCode.h:
+        I used a uint8_t instead of a boolean to make the code generation clearer
+        in DFGSpeculativeJIT64.
+
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        This is a bit annoying: we have the NaturalLoops analysis that provides us
+        everything we need to know about loops, but the TierUpCheck are conservative
+        and set on LoopHint.
+
+        To make the two work together, we first find all the CheckTierUp that cannot
+        OSR enter and we keep a list of all the natural loops containing them.
+
+        Then we do a second pass over the LoopHints, get their NaturalLoop, and check
+        if it contains a loop that cannot OSR enter.
+
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::canOSREnterAtLoopHint):
+
+2015-05-18  Filip Pizlo  <fpizlo@apple.com>
+
+        Add a Int-or-Boolean speculation to Branch
+        https://bugs.webkit.org/show_bug.cgi?id=145134
+
+        Reviewed by Benjamin Poulain.
+        
+        After https://bugs.webkit.org/show_bug.cgi?id=126778 we no longer have a reason not to do the
+        int-or-boolean optimization that we already do everywhere else.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+2015-05-18  Andreas Kling  <akling@apple.com>
+
+        [JSC] Speed up URL encode/decode by using bitmaps instead of strchr().
+        <https://webkit.org/b/145115>
+
+        Reviewed by Anders Carlsson.
+
+        We were calling strchr() for every character when doing URL encoding/decoding and it stood out
+        like a sore O(n) thumb in Instruments. Optimize this by using a Bitmap<256> instead.
+
+        5.5% progression on Kraken/stanford-crypto-sha256-iterative.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::makeCharacterBitmap):
+        (JSC::encode):
+        (JSC::decode):
+        (JSC::globalFuncDecodeURI):
+        (JSC::globalFuncDecodeURIComponent):
+        (JSC::globalFuncEncodeURI):
+        (JSC::globalFuncEncodeURIComponent):
+        (JSC::globalFuncEscape):
+
+2015-05-17  Benjamin Poulain  <benjamin@webkit.org>
+
+        Do not use fastMallocGoodSize anywhere
+        https://bugs.webkit.org/show_bug.cgi?id=145103
+
+        Reviewed by Michael Saboff.
+
+        * assembler/AssemblerBuffer.h:
+        (JSC::AssemblerData::AssemblerData):
+        (JSC::AssemblerData::grow):
+
+2015-05-17  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] Make StringRecursionChecker faster in the simple cases without any recursion
+        https://bugs.webkit.org/show_bug.cgi?id=145102
+
+        Reviewed by Darin Adler.
+
+        In general, the array targeted by Array.toString() or Array.join() are pretty
+        simple. In those simple cases, we spend as much time in StringRecursionChecker
+        as we do on the actual operation.
+
+        The reason for this is the HashSet stringRecursionCheckVisitedObjects used
+        to detect recursion. We are constantly adding and removing objects which
+        dirty buckets and force constant rehash.
+
+        This patch adds a simple shortcut for those simple case: in addition to the HashSet,
+        we keep a pointer to the root object of the recursion.
+        In the vast majority of cases, we no longer touch the HashSet at all.
+
+        This patch is a 12% progression on the overall score of ArrayWeighted.
+
+        * runtime/StringRecursionChecker.h:
+        (JSC::StringRecursionChecker::performCheck):
+        (JSC::StringRecursionChecker::~StringRecursionChecker):
+        * runtime/VM.h:
+
+2015-05-17  Filip Pizlo  <fpizlo@apple.com>
+
+        Insert store barriers late so that IR transformations don't have to worry about them
+        https://bugs.webkit.org/show_bug.cgi?id=145015
+
+        Reviewed by Geoffrey Garen.
+        
+        We have had three kinds of bugs with store barriers. For the sake of discussion we say
+        that a store barrier is needed when we have something like:
+        
+            base.field = value
+        
+        - We sometimes fail to realize that we could remove a barrier when value is a non-cell.
+          This might happen if we prove value to be a non-cell even though in the FixupPhase it
+          wasn't predicted non-cell.
+        
+        - We sometimes have a barrier in the wrong place after object allocation sinking. We
+          might sink an allocation to just above the store, but that puts it just after the
+          StoreBarrier that FixupPhase inserted.
+        
+        - We don't remove redundant barriers across basic blocks.
+        
+        This comprehensively fixes these issues by doing store barrier insertion late, and
+        removing the store barrier elision phase. Store barrier insertion uses an epoch-based
+        algorithm to determine when stores need barriers. Briefly, a barrier is not needed if
+        base is in the current GC epoch (i.e. was the last object that we allocated or had a
+        barrier since last GC) or if base has a newer GC epoch than value (i.e. value would have
+        always been allocated before base). We do conservative things when merging epoch state
+        between basic blocks, and we only do such inter-block removal in the FTL. FTL also
+        queries AI to determine what type we've proved about value, and avoids barriers when
+        value is not a cell. FixupPhase still inserts type checks on some stores, to maximize
+        the likelihood that this AI-based removal is effective.
+        
+        Rolling back in after fixing some debug build test failures.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBlockMap.h:
+        (JSC::DFG::BlockMap::at):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGEpoch.h:
+        (JSC::DFG::Epoch::operator<):
+        (JSC::DFG::Epoch::operator>):
+        (JSC::DFG::Epoch::operator<=):
+        (JSC::DFG::Epoch::operator>=):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::speculateForBarrier):
+        (JSC::DFG::FixupPhase::insertStoreBarrier): Deleted.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStoreBarrierElisionPhase.cpp: Removed.
+        * dfg/DFGStoreBarrierElisionPhase.h: Removed.
+        * dfg/DFGStoreBarrierInsertionPhase.cpp: Added.
+        (JSC::DFG::performFastStoreBarrierInsertion):
+        (JSC::DFG::performGlobalStoreBarrierInsertion):
+        * dfg/DFGStoreBarrierInsertionPhase.h: Added.
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR): Fix an unrelated debug-only bug.
+        * tests/stress/load-varargs-then-inlined-call-and-exit.js: Test for that debug-only bug.
+        * tests/stress/load-varargs-then-inlined-call-and-exit-strict.js: Strict version of that test.
+
+2015-05-16  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184415.
+        https://bugs.webkit.org/show_bug.cgi?id=145096
+
+        Broke several tests (Requested by msaboff on #webkit).
+
+        Reverted changeset:
+
+        "Insert store barriers late so that IR transformations don't
+        have to worry about them"
+        https://bugs.webkit.org/show_bug.cgi?id=145015
+        http://trac.webkit.org/changeset/184415
+
+2015-05-14  Filip Pizlo  <fpizlo@apple.com>
+
+        Insert store barriers late so that IR transformations don't have to worry about them
+        https://bugs.webkit.org/show_bug.cgi?id=145015
+
+        Reviewed by Geoffrey Garen.
+        
+        We have had three kinds of bugs with store barriers. For the sake of discussion we say
+        that a store barrier is needed when we have something like:
+        
+            base.field = value
+        
+        - We sometimes fail to realize that we could remove a barrier when value is a non-cell.
+          This might happen if we prove value to be a non-cell even though in the FixupPhase it
+          wasn't predicted non-cell.
+        
+        - We sometimes have a barrier in the wrong place after object allocation sinking. We
+          might sink an allocation to just above the store, but that puts it just after the
+          StoreBarrier that FixupPhase inserted.
+        
+        - We don't remove redundant barriers across basic blocks.
+        
+        This comprehensively fixes these issues by doing store barrier insertion late, and
+        removing the store barrier elision phase. Store barrier insertion uses an epoch-based
+        algorithm to determine when stores need barriers. Briefly, a barrier is not needed if
+        base is in the current GC epoch (i.e. was the last object that we allocated or had a
+        barrier since last GC) or if base has a newer GC epoch than value (i.e. value would have
+        always been allocated before base). We do conservative things when merging epoch state
+        between basic blocks, and we only do such inter-block removal in the FTL. FTL also
+        queries AI to determine what type we've proved about value, and avoids barriers when
+        value is not a cell. FixupPhase still inserts type checks on some stores, to maximize
+        the likelihood that this AI-based removal is effective.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBlockMap.h:
+        (JSC::DFG::BlockMap::at):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGEpoch.h:
+        (JSC::DFG::Epoch::operator<):
+        (JSC::DFG::Epoch::operator>):
+        (JSC::DFG::Epoch::operator<=):
+        (JSC::DFG::Epoch::operator>=):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::speculateForBarrier):
+        (JSC::DFG::FixupPhase::insertStoreBarrier): Deleted.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStoreBarrierElisionPhase.cpp: Removed.
+        * dfg/DFGStoreBarrierElisionPhase.h: Removed.
+        * dfg/DFGStoreBarrierInsertionPhase.cpp: Added.
+        (JSC::DFG::performFastStoreBarrierInsertion):
+        (JSC::DFG::performGlobalStoreBarrierInsertion):
+        * dfg/DFGStoreBarrierInsertionPhase.h: Added.
+
+2015-05-15  Benjamin Poulain  <bpoulain@apple.com>
+
+        [ARM64] Do not fail branchConvertDoubleToInt32 when the result is zero and not negative zero
+        https://bugs.webkit.org/show_bug.cgi?id=144976
+
+        Reviewed by Michael Saboff.
+
+        Failing the conversion on zero is pretty dangerous as we discovered on x86.
+
+        This patch does not really impact performance significantly because
+        r184220 removed the zero checks from Kraken. This patch is just to be
+        on the safe side for cases not covered by existing benchmarks.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branchConvertDoubleToInt32):
+
+2015-05-15  Sungmann Cho  <sungmann.cho@navercorp.com>
+
+        Remove unnecessary forward declarations in PropertyNameArray.h.
+        https://bugs.webkit.org/show_bug.cgi?id=145058
+
+        Reviewed by Andreas Kling.
+
+        No new tests, no behavior change.
+
+        * runtime/PropertyNameArray.h:
+
+2015-05-15  Mark Lam  <mark.lam@apple.com>
+
+        JSArray::setLength() should reallocate instead of zero-filling if the reallocation would be small enough.
+        https://bugs.webkit.org/show_bug.cgi?id=144622
+
+        Reviewed by Geoffrey Garen.
+
+        When setting the array to a new length that is shorter, we now check if it is worth
+        just making a new butterfly instead of clearing out the slots in the old butterfly
+        that resides beyond the new length.  If so, we will make a new butterfly instead.
+
+        There is no perf differences in the benchmark results.  However, this does benefit
+        the perf of pathological cases where we need to shorten the length of a very large
+        array, as is the case in tests/mozilla/js1_5/Array/regress-101964.js.  With this
+        patch, we can expect that test to complete in a short time again.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLength):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::reallocateAndShrinkButterfly):
+        - makes a new butterfly with a new shorter length.
+        * runtime/JSObject.h:
+        * tests/mozilla/js1_5/Array/regress-101964.js:
+        - Undo this test change since this patch will prevent us from spending a lot of time
+          clearing a large butterfly.
+
+2015-05-15  Basile Clement  <basile_clement@apple.com>
+
+        DFGLICMPhase shouldn't create NodeOrigins with forExit but without semantic
+        https://bugs.webkit.org/show_bug.cgi?id=145062
+
+        Reviewed by Filip Pizlo.
+
+        We assert in various places (including NodeOrigin::isSet()) that a
+        NodeOrigin's semantic and forExit must be either both set, or both
+        unset.  However, LICM'ing a node with unset NodeOrigin would only set
+        forExit, and leave semantic unset. This can for instance happen when a
+        Phi node is constant-folded into a JSConstant, which in turn gets
+        LICM'd.
+
+        This patch changes DFGLICMPhase to set the NodeOrigin's semantic in
+        addition to its forExit if semantic was previously unset.
+
+        It also adds two validators to DFGValidate.cpp:
+         - In both SSA and CPS form, a NodeOrigin semantic and forExit must be either both set or both unset
+         - In CPS form, all nodes must have a set NodeOrigin forExit (this is
+           the CPS counterpart to the SSA validator that checks that all nodes
+           must have a set NodeOrigin except possibly for a continuous chunk of
+           nodes at the top of a block)
+
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::attemptHoist):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateCPS):
+
+2015-05-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, remove an unused declaration.
+
+        * dfg/DFGSpeculativeJIT.h:
+
+2015-05-14  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove unused constant-base and constant-value store barrier code in the DFG
+        https://bugs.webkit.org/show_bug.cgi?id=145039
+
+        Reviewed by Andreas Kling.
+        
+        Just killing dead code.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer): Deleted.
+        (JSC::DFG::SpeculativeJIT::writeBarrier): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+
+2015-05-15  Alexandr Skachkov  <gskachkov@gmail.com>
+
+        Fix typo in function name parseFunctionParamters -> parseFunctionParameters
+        https://bugs.webkit.org/show_bug.cgi?id=145040
+
+        Reviewed by Mark Lam.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+
+2015-05-14  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove StoreBarrierWithNullCheck, nobody ever generates this.
+        
+        Rubber stamped by Benjamin Poulain and Michael Saboff.
+
+        If we did bring something like this back in the future, we would just use UntypedUse instead
+        of CellUse to indicate that this is what we want.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isStoreBarrier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStoreBarrier):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileStoreBarrierWithNullCheck): Deleted.
+
+2015-05-14  Filip Pizlo  <fpizlo@apple.com>
+
+        PutGlobalVar should reference the global object it's storing into
+        https://bugs.webkit.org/show_bug.cgi?id=145036
+
+        Reviewed by Michael Saboff.
+        
+        This makes it easier to reason about store barrier insertion and elimination. This changes
+        the format of PutGlobalVar so that child1 is the global object and child2 is the value.
+        Previously it just had child1, and that was the value.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
+
+2015-05-14  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        [CMake] Error out when ruby is too old
+        https://bugs.webkit.org/show_bug.cgi?id=145014
+
+        Reviewed by Martin Robinson.
+
+        Don't enforce the check for the Ruby executable here; it's now enforced in the top-level
+        CMakeLists.txt instead.
+
+        * CMakeLists.txt:
+
+2015-05-12  Basile Clement  <basile_clement@apple.com>
+
+        Enforce options coherency
+        https://bugs.webkit.org/show_bug.cgi?id=144921
+
+        Reviewed by Mark Lam.
+
+        JavaScriptCore should be failing early when the options are set in such
+        a way that we don't have a meaningful way to execute JavaScript, rather
+        than failing for obscure reasons at some point during execution.
+
+        This patch adds a new function that checks whether the options are set
+        in a coherent way, and makes JSC::Options::initialize() crash when the
+        environment enforces incoherent options.
+        Client applications able to add or change additional options are
+        responsible to check for coherency again before starting to actually
+        execute JavaScript, if any additional options have been set. This is
+        implemented for the jsc executable in this patch.
+
+        * jsc.cpp:
+        (CommandLine::parseArguments):
+        * runtime/Options.cpp:
+        (JSC::Options::initialize):
+        (JSC::Options::ensureOptionsAreCoherent): Added.
+        * runtime/Options.h:
+        (JSC::Options::ensureOptionsAreCoherent): Added.
+
+2015-05-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION (r184337): [EFL] unresolved reference errors in ARM builds
+        https://bugs.webkit.org/show_bug.cgi?id=145019
+
+        Reviewed by Ryosuke Niwa.
+
+        Attempt to fix compile errors in EFL ARM buildbots.
+        By executing `nm`, found JSTemplateRegistryKey.cpp.o and TemplateRegistry.cpp.o have
+        unresolved reference to Structure::get. That is inlined function in StructureInlines.h.
+
+        * runtime/JSTemplateRegistryKey.cpp:
+        * runtime/TemplateRegistry.cpp:
+
+2015-05-14  Alexandr Skachkov  <gskachkov@gmail.com>
+
+        Small refactoring before implementation of the ES6 arrow function.
+        https://bugs.webkit.org/show_bug.cgi?id=144954
+
+        Reviewed by Ryosuke Niwa.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+
+2015-05-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION (r184337): ASSERT failed in debug builds for tagged templates
+        https://bugs.webkit.org/show_bug.cgi?id=145013
+
+        Reviewed by Filip Pizlo.
+
+        Fix the regression introduced by r184337.
+
+        1. JSTemporaryRegistryKey::s_info should inherit the Base::s_info,
+           JSDestructibleObject::s_info.
+
+        2. The first register argument of BytecodeGenerator::emitNode
+           should be a referenced register if it is a temporary register.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TaggedTemplateNode::emitBytecode):
+        * runtime/JSTemplateRegistryKey.cpp:
+
+2015-05-14  Andreas Kling  <akling@apple.com>
+
+        String.prototype.split() should create efficient substrings.
+        <https://webkit.org/b/144985>
+        <rdar://problem/20949344>
+
+        Reviewed by Geoffrey Garen.
+
+        Teach split() how to make substring JSStrings instead of relying on StringImpl's
+        substring sharing mechanism. The optimization works by deferring the construction
+        of a StringImpl until the substring's value is actually needed.
+
+        This knocks ~2MB off of theverge.com by avoiding the extra StringImpl allocations.
+        Out of ~70000 substrings created by split(), only ~2000 of them get reified.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::jsSubstring):
+        (JSC::splitStringByOneCharacterImpl):
+        (JSC::stringProtoFuncSplit):
+
+2015-05-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Change the status of ES6 tagged templates to Done in features.json
+        https://bugs.webkit.org/show_bug.cgi?id=145003
+
+        Reviewed by Benjamin Poulain.
+
+        Now it's implemented in r184337.
+
+        * features.json:
+
+2015-05-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Introduce SymbolType into SpeculativeTypes
+        https://bugs.webkit.org/show_bug.cgi?id=142651
+
+        Reviewed by Filip Pizlo.
+
+        Introduce SpecSymbol type into speculative types.
+        Previously symbol type is categorized into SpecCellOther.
+        But SpecCellOther is not intended to be used for such cells.
+
+        This patch just introduces SpecSymbol.
+        It represents the type of target value is definitely the symbol type.
+        It is the part of SpecCell.
+
+        In this patch, we do not introduce SymbolUse tracking.
+        It will be added in the separate patch.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationFromStructure):
+        * bytecode/SpeculatedType.h:
+        (JSC::isSymbolSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setType):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * tests/stress/typeof-symbol.js: Added.
+
+2015-05-14  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement tagged templates
+        https://bugs.webkit.org/show_bug.cgi?id=143183
+
+        Reviewed by Oliver Hunt.
+
+        This patch implements ES6 tagged templates.
+        In tagged templates, the function takes the template object.
+
+        The template object contains the raw and cooked template strings,
+        so when parsing the tagged templates, we need to tokenize the raw and cooked strings.
+        While tagged templates require the both strings, the template literal only requires
+        the cooked strings. So when tokenizing under the template literal context,
+        we only builds the cooked strings.
+
+        As per ES6 spec, the template objects for the same raw strings are shared in the same realm.
+        The template objects is cached. And every time we evaluate the same tagged templates,
+        the same (cached) template objects are used.
+        Since the spec freezes this template objects completely,
+        we cannot attach some properties to it.
+        So we can say that it behaves as if the template objects are the primitive values (like JSString).
+        Since we cannot attach properties, the only way to test the identity of the template object is comparing. (===)
+        As the result, when there is no reference to the template object, we can garbage collect it
+        because the user has no way to test that the newly created template object does not equal
+        to the already collected template object.
+
+        So, to implement tagged templates, we implement the following components.
+
+        1. JSTemplateRegistryKey
+        It holds the template registry key and it does not exposed to users.
+        TemplateRegistryKey holds the vector of raw and cooked strings with the pre-computed hash value.
+        When obtaining the template object for the (statically, a.k.a. at the parsing time) given raw string vectors,
+        we use this JSTemplateRegistryKey as a key to the map and look up the template object from
+        TemplateRegistry.
+        JSTemplateRegistryKey is created at the bytecode compiling time and
+        stored in the CodeBlock as like as JSString content values.
+
+        2. TemplateRegistry
+        This manages the cached template objects.
+        It holds the weak map (JSTemplateRegistryKey -> the template object).
+        The template object is weakly referenced.
+        So if there is no reference to the template object,
+        the template object is automatically GC-ed.
+        When looking up the template object, it searches the cached template object.
+        If it is found, it is returned to the users.
+        If there is no cached template objects, it creates the new template object and
+        stores it with the given template registry key.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
+        (JSC::BytecodeGenerator::emitGetTemplateObject):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TaggedTemplateNode::emitBytecode):
+        (JSC::TemplateLiteralNode::emitBytecode): Deleted.
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createTaggedTemplate):
+        (JSC::ASTBuilder::createTemplateLiteral): Deleted.
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::setCode):
+        (JSC::Lexer<T>::parseTemplateLiteral):
+        (JSC::Lexer<T>::lex):
+        (JSC::Lexer<T>::scanTrailingTemplateString):
+        (JSC::Lexer<T>::clear):
+        * parser/Lexer.h:
+        (JSC::Lexer<T>::makeEmptyIdentifier):
+        * parser/NodeConstructors.h:
+        (JSC::TaggedTemplateNode::TaggedTemplateNode):
+        (JSC::TemplateLiteralNode::TemplateLiteralNode): Deleted.
+        * parser/Nodes.h:
+        (JSC::TemplateLiteralNode::templateStrings):
+        (JSC::TemplateLiteralNode::templateExpressions):
+        (JSC::TaggedTemplateNode::templateLiteral):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseTemplateString):
+        (JSC::Parser<LexerType>::parseTemplateLiteral):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        * parser/Parser.h:
+        * parser/ParserArena.h:
+        (JSC::IdentifierArena::makeEmptyIdentifier):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createTaggedTemplate):
+        (JSC::SyntaxChecker::createTemplateLiteral): Deleted.
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::getTemplateObject):
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::templateRegistry):
+        * runtime/JSTemplateRegistryKey.cpp: Added.
+        (JSC::JSTemplateRegistryKey::JSTemplateRegistryKey):
+        (JSC::JSTemplateRegistryKey::create):
+        (JSC::JSTemplateRegistryKey::destroy):
+        * runtime/JSTemplateRegistryKey.h: Added.
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorFreeze):
+        * runtime/ObjectConstructor.h:
+        * runtime/TemplateRegistry.cpp: Added.
+        (JSC::TemplateRegistry::TemplateRegistry):
+        (JSC::TemplateRegistry::getTemplateObject):
+        * runtime/TemplateRegistry.h: Added.
+        * runtime/TemplateRegistryKey.h: Added.
+        (JSC::TemplateRegistryKey::isDeletedValue):
+        (JSC::TemplateRegistryKey::isEmptyValue):
+        (JSC::TemplateRegistryKey::hash):
+        (JSC::TemplateRegistryKey::rawStrings):
+        (JSC::TemplateRegistryKey::cookedStrings):
+        (JSC::TemplateRegistryKey::operator==):
+        (JSC::TemplateRegistryKey::operator!=):
+        (JSC::TemplateRegistryKey::Hasher::hash):
+        (JSC::TemplateRegistryKey::Hasher::equal):
+        (JSC::TemplateRegistryKey::TemplateRegistryKey):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * tests/stress/tagged-templates-identity.js: Added.
+        (shouldBe):
+        * tests/stress/tagged-templates-raw-strings.js: Added.
+        (shouldBe):
+        (tag):
+        (testEval):
+        * tests/stress/tagged-templates-syntax.js: Added.
+        (tag):
+        (testSyntax):
+        (testSyntaxError):
+        * tests/stress/tagged-templates-template-object.js: Added.
+        (shouldBe):
+        (tag):
+        * tests/stress/tagged-templates-this.js: Added.
+        (shouldBe):
+        (tag):
+        * tests/stress/tagged-templates.js: Added.
+        (shouldBe):
+        (raw):
+        (cooked):
+        (Counter):
+
+2015-05-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180595): same-callee profiling no longer works
+        https://bugs.webkit.org/show_bug.cgi?id=144787
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces a DFG optimization to use NewObject node when the callee of op_create_this is
+        always the same JSFunction. This condition doesn't hold when the byte code creates multiple
+        JSFunction objects at runtime as in: function y() { return function () {} }; new y(); new y();
+
+        To enable this optimization, LLint and baseline JIT now store the last callee we saw in the newly
+        added fourth operand of op_create_this. We use this JSFunction's structure in DFG after verifying
+        our speculation that the callee is the same. To avoid recompiling the same code for different callee
+        objects in the polymorphic case, the special value of seenMultipleCalleeObjects() is set in
+        LLint and baseline JIT when multiple callees are observed.
+
+        Tests: stress/create-this-with-callee-variants.js
+
+        * bytecode/BytecodeList.json: Increased the number of operands to 5.
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Dump the newly added callee cache.
+        (JSC::CodeBlock::finalizeUnconditionally): Clear the callee cache if the callee is no longer alive.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCreateThis): Add the instruction to propertyAccessInstructions so that
+        we can clear the callee cache in CodeBlock::finalizeUnconditionally. Also initialize the newly added
+        operand.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock): Implement the optimization. Speculate the actual callee to
+        match the cache. Use the cached callee's structure if the speculation succeeds. Otherwise, OSR exit.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_this): Go to the slow path to update the cache unless it's already marked
+        as seenMultipleCalleeObjects() to indicate the polymorphic behavior and/or we've OSR exited here.
+        (JSC::JIT::emitSlow_op_create_this):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_this): Ditto.
+        (JSC::JIT::emitSlow_op_create_this):
+        * llint/LowLevelInterpreter32_64.asm:
+        (_llint_op_create_this): Ditto.
+        * llint/LowLevelInterpreter64.asm:
+        (_llint_op_create_this): Ditto.
+        * runtime/CommonSlowPaths.cpp:
+        (slow_path_create_this): Set the callee cache to the actual callee if it's not set. If the cache has
+        been set to a JSFunction* different from the actual callee, set it to seenMultipleCalleeObjects().
+        * runtime/JSCell.h:
+        (JSC::JSCell::seenMultipleCalleeObjects): Added.
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase::unvalidatedGet): Removed the compile guard around it.
+        * tests/stress/create-this-with-callee-variants.js: Added.
+
+2015-05-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Clean up some possible RefPtr to PassRefPtr churn
+        https://bugs.webkit.org/show_bug.cgi?id=144779
+
+        Reviewed by Darin Adler.
+
+        * runtime/GenericTypedArrayViewInlines.h:
+        (JSC::GenericTypedArrayView<Adaptor>::create):
+        (JSC::GenericTypedArrayView<Adaptor>::createUninitialized):
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::constructArrayBuffer):
+        * runtime/Structure.cpp:
+        (JSC::Structure::toStructureShape):
+        * runtime/TypedArrayBase.h:
+        (JSC::TypedArrayBase::create):
+        (JSC::TypedArrayBase::createUninitialized):
+        * tools/FunctionOverrides.cpp:
+        (JSC::initializeOverrideInfo):
+        Release the last use of a RefPtr as it is passed on.
+
+2015-05-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Allow duplicate property names
+        https://bugs.webkit.org/show_bug.cgi?id=142895
+
+        Reviewed by Geoffrey Garen.
+
+        Introduce new `op_put_getter_by_id` and `op_put_setter_by_id` opcodes
+        that will define a single getter or setter property on an object.
+
+        The existing `op_put_getter_setter` opcode is still preferred for
+        putting both a getter and setter at the same time but cannot be used
+        for putting an individual getter or setter which is needed in
+        some cases.
+
+        Add a new slow path when generating bytecodes for a property list
+        with computed properties, as computed properties are the only time
+        the list of properties cannot be determined statically.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitBytecode):
+        - fast path for all constant properties
+        - slow but paired getter/setter path if there are no computed properties
+        - slow path, individual put operation for every property, if there are computed properties
+
+        * parser/Nodes.h:
+        Distinguish a Computed property from a Constant property.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parsePropertyMethod):
+        Distingish Computed and Constant properties.
+
+        (JSC::Parser<LexerType>::parseObjectLiteral):
+        When we drop into strict mode it is because we saw a getter
+        or setter, so be more explicit.
+
+        (JSC::Parser<LexerType>::parseStrictObjectLiteral):
+        Eliminate duplicate property syntax error exception.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::getName):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::getName): Deleted.
+        No longer used.
+
+        * runtime/JSObject.h:
+        (JSC::JSObject::putDirectInternal):
+        When updating a property. If the Accessor attribute changed
+        update the Structure.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putGetter):
+        (JSC::JSObject::putSetter):
+        Called by the opcodes, just perform the same operation that
+        __defineGetter__ or __defineSetter__ would do.
+
+        (JSC::JSObject::putDirectNonIndexAccessor):
+        This transition is now handled in putDirectInternal.
+
+        * runtime/Structure.h:
+        Add needed export.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPutGetterById):
+        (JSC::BytecodeGenerator::emitPutSetterById):
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_put_getter_by_id):
+        (JSC::JIT::emit_op_put_setter_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_put_getter_by_id):
+        (JSC::JIT::emit_op_put_setter_by_id):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        New bytecodes. Modelled after existing op_put_getter_setter.
+
+2015-05-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Creating a new blank document in icloud pages causes an AI error: Abstract value (CellBytecodedoubleBoolOther, TOP, TOP) for double node has type outside SpecFullDouble.
+        https://bugs.webkit.org/show_bug.cgi?id=144856
+
+        Reviewed by Benjamin Poulain.
+        
+        First I made fixTypeForRepresentation() print out better diagnostics when it dies.
+        
+        Then I fixed the bug: Node::convertToIdentityOn(Node*) needs to make sure that when it
+        converts to a representation-changing node, it needs to use one of the UseKinds that such
+        a node expects. For example, DoubleRep(UntypedUse:) doesn't make sense; it needs to be
+        something like DoubleRep(NumberUse:) since it will speculate that the input is a number.
+
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToIdentityOn):
+        * tests/stress/cloned-arguments-get-by-val-double-array.js: Added.
+        (foo):
+
+2015-05-13  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184313.
+        https://bugs.webkit.org/show_bug.cgi?id=144974
+
+        Introduced an assertion failure in class-syntax-
+        declaration.js, class-syntax-expression.js, and object-
+        literal-syntax.js (Requested by rniwa on #webkit).
+
+        Reverted changeset:
+
+        "Small refactoring before ES6 Arrow function implementation."
+        https://bugs.webkit.org/show_bug.cgi?id=144954
+        http://trac.webkit.org/changeset/184313
+
+2015-05-13  Oliver Hunt  <oliver@apple.com>
+        Ensure that all the smart pointer types in WTF clear their pointer before deref
+        https://bugs.webkit.org/show_bug.cgi?id=143789
+
+        Reviewed by Ryosuke Niwa.
+
+        One of the simpler cases of this in JavaScriptCore. There
+        are other cases where we need to guard the derefs but they
+        are more complex cases.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::releaseImpl):
+        * inspector/JSJavaScriptCallFrame.cpp:
+        (Inspector::JSJavaScriptCallFrame::releaseImpl):
+
+2015-05-13  Alexandr Skachkov  <gskachkov@gmail.com>
+
+        Small refactoring before ES6 Arrow function implementation.
+        https://bugs.webkit.org/show_bug.cgi?id=144954
+
+        Reviewed by Filip Pizlo.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+
+2015-05-13  Filip Pizlo  <fpizlo@apple.com>
+
+        The liveness pruning done by ObjectAllocationSinkingPhase ignores the possibility of an object's bytecode liveness being longer than its DFG liveness
+        https://bugs.webkit.org/show_bug.cgi?id=144945
+
+        Reviewed by Michael Saboff.
+        
+        We were making the mistake of using DFG liveness for object allocation sinking decisions.
+        This is wrong. In fact we almost never want to use DFG liveness directly. The only place
+        where that makes sense is pruning in DFG AI.
+        
+        So, I created a CombinedLiveness class that combines the DFG liveness with bytecode
+        liveness.
+        
+        In the process of doing this, I realized that the DFGForAllKills definition of combined
+        liveness at block tail was not strictly right; it was using the bytecode liveness at the
+        block terminal instead of the union of the bytecode live-at-heads of successor blocks. So,
+        I changed DFGForAllKills to work in terms of CombinedLiveness.
+        
+        This allows me to unskip the test I added in r184260. I also added a new test that tries to
+        trigger this bug more directly.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGCombinedLiveness.cpp: Added.
+        (JSC::DFG::liveNodesAtHead):
+        (JSC::DFG::CombinedLiveness::CombinedLiveness):
+        * dfg/DFGCombinedLiveness.h: Added.
+        (JSC::DFG::CombinedLiveness::CombinedLiveness):
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllKillsInBlock):
+        (JSC::DFG::forAllLiveNodesAtTail): Deleted.
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::performSinking):
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        * tests/stress/escape-object-in-diamond-then-exit.js: Added.
+        * tests/stress/sink-object-past-invalid-check-sneaky.js:
+
+2015-05-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        I skipped a wrong test in r184270. Fix that.
+        The failure is tracked by webkit.org/b/144947.
+
+        * tests/stress/arith-modulo-node-behaviors.js:
+        * tests/stress/arith-mul-with-constants.js:
+
+2015-05-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Avoid always running some debug code in type profiling
+        https://bugs.webkit.org/show_bug.cgi?id=144775
+
+        Reviewed by Daniel Bates.
+
+        * runtime/TypeProfilerLog.cpp:
+        (JSC::TypeProfilerLog::processLogEntries):
+
+2015-05-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Pass String as reference in more places
+        https://bugs.webkit.org/show_bug.cgi?id=144769
+
+        Reviewed by Daniel Bates.
+
+        * debugger/Breakpoint.h:
+        (JSC::Breakpoint::Breakpoint):
+        * parser/Parser.h:
+        (JSC::Parser::setErrorMessage):
+        (JSC::Parser::updateErrorWithNameAndMessage):
+        * parser/ParserError.h:
+        (JSC::ParserError::ParserError):
+        * runtime/RegExp.cpp:
+        (JSC::RegExpFunctionalTestCollector::outputOneTest):
+        * runtime/RegExpObject.cpp:
+        (JSC::regExpObjectSourceInternal):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
+        * runtime/TypeProfilerLog.cpp:
+        (JSC::TypeProfilerLog::processLogEntries):
+        * runtime/TypeProfilerLog.h:
+        * tools/FunctionOverrides.cpp:
+        (JSC::initializeOverrideInfo):
+        * inspector/scripts/codegen/generate_objc_conversion_helpers.py:
+        (ObjCConversionHelpersGenerator._generate_enum_from_protocol_string):
+
+        * inspector/scripts/codegen/objc_generator_templates.py:
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        Rebaseline tests after updating the generator.
+
+2015-05-13  Michael Saboff  <msaboff@apple.com>
+
+        com.apple.WebKit.WebContent crashed at JavaScriptCore: JSC::CodeBlock::finalizeUnconditionally
+        https://bugs.webkit.org/show_bug.cgi?id=144933
+
+        Changed the RELEASE_ASSERT_NOT_REACHED into an ASSERT.  Added some diagnostic messages to
+        help determine the cause for any crash.
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finalizeUnconditionally):
+
+2015-05-13  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r184260): arguments elimination has stopped working because of Check(UntypedUse:) from SSAConversionPhase
+        https://bugs.webkit.org/show_bug.cgi?id=144951
+
+        Reviewed by Michael Saboff.
+        
+        There were two issues here:
+        
+        - In r184260 we expected a small number of possible use kinds in Check nodes, and
+          UntypedUse was not one of them. That seemed like a sensible assumption because we don't
+          create Check nodes unless it's to have a check. But, SSAConversionPhase was creating a
+          Check that could have UntypedUse. I fixed this. It's cleaner for SSAConversionPhase to
+          follow the same idiom as everyone else and not create tautological checks.
+        
+        - It's clearly not very robust to assume that Checks will not be used tautologically. So,
+          this changes how we validate Checks in the escape analyses. We now use willHaveCheck,
+          which catches cases that AI would have already marked as unnecessary. It then also uses
+          a new helper called alreadyChecked(), which allows us to just ask if the check is
+          unnecessary for objects. That's a good fall-back in case AI hadn't run yet.
+
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGMayExit.cpp:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::alreadyChecked):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+
+k
+2015-05-13  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement String.raw
+        https://bugs.webkit.org/show_bug.cgi?id=144330
+
+        Reviewed by Filip Pizlo.
+
+        Implement String.raw. It is intended to be used with tagged-templates syntax.
+        To implement ToString abstract operation efficiently,
+        we introduce @toString bytecode intrinsic. It emits op_to_string directly.
+
+        * CMakeLists.txt:
+        * builtins/StringConstructor.js: Added.
+        (raw):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_toString):
+        * runtime/CommonIdentifiers.h:
+        * runtime/StringConstructor.cpp:
+        * tests/stress/string-raw.js: Added.
+        (shouldBe):
+        (.get shouldBe):
+        (Counter):
+
+2015-05-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Temporarily disable the test on Windows. The failure is tracked in webkit.org/b/144897.
+
+        * tests/stress/arith-mul-with-constants.js:
+
+2015-05-12  Filip Pizlo  <fpizlo@apple.com>
+
+        js/dom/stack-trace.html fails with eager compilation
+        https://bugs.webkit.org/show_bug.cgi?id=144853
+
+        Reviewed by Benjamin Poulain.
+        
+        All of our escape analyses were mishandling Check(). They were assuming that this is a
+        non-escaping operation. But, if we do for example a Check(Int32:@x) and @x is an escape
+        candidate, then we need to do something: if we eliminate or sink @x, then the check no
+        longer makes any sense since a phantom allocation has no type. This will make us forget
+        that this operation would have exited. This was causing us to not call a valueOf method in
+        js/dom/stack-trace.html with eager compilation enabled, because it was doing something like
+        +o where o had a valueOf method, and o was otherwise sinkable.
+        
+        This changes our escape analyses to basically pretend that any Check() that isn't obviously
+        unnecessary is an escape. We don't have to be super careful here. Most checks will be
+        completely eliminated by constant-folding. If that doesn't run in time, then the most
+        common check we will see is CellUse. So, we just recognize some very obvious check kinds
+        that we know would have passed, and for all of the rest we just assume that it's an escape.
+        
+        This was super tricky to test. The obvious way to test it is to use +o like
+        stack-trace.html, except that doing so relies on the fact that we still haven't implemented
+        the optimal behavior for op_to_number. So, I take four approaches in testing this patch:
+        
+        1) Use +o. These will test what we want it to test for now, but at some point in the future
+           these tests will just be a good sanity-check that our op_to_number implementation is
+           right.
+        
+        2) Do fancy control flow tricks to fool the profiling into thinking that some arithmetic
+           operation always sees integers even though we eventually feed it an object and that
+           object is a sink candidate.
+        
+        3) Introduce a new jsc.cpp intrinsic called isInt32() which returns true if the incoming
+           value is an int32. This intrinsic is required to be implemented by DFG by
+           unconditionally speculating that the input is int32. This allows us to write much more
+           targetted tests of the underlying issue.
+        
+        4) I made a version of stack-trace.html that runs in run-jsc-stress-tests, so that we can
+           get regression test coverage of this test in eager mode.
+
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileFTLOSRExit):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionIsInt32):
+        * runtime/Intrinsic.h:
+        * tests/stress/sink-arguments-past-invalid-check-dfg.js: Added.
+        * tests/stress/sink-arguments-past-invalid-check-int32-dfg.js: Added.
+        * tests/stress/sink-arguments-past-invalid-check-int32.js: Added.
+        * tests/stress/sink-arguments-past-invalid-check-sneakier.js: Added.
+        * tests/stress/sink-arguments-past-invalid-check.js: Added.
+        * tests/stress/sink-function-past-invalid-check-sneakier.js: Added.
+        * tests/stress/sink-function-past-invalid-check-sneaky.js: Added.
+        * tests/stress/sink-object-past-invalid-check-int32.js: Added.
+        * tests/stress/sink-object-past-invalid-check-sneakier.js: Added.
+        * tests/stress/sink-object-past-invalid-check-sneaky.js: Added.
+        * tests/stress/sink-object-past-invalid-check.js: Added.
+
+2015-05-12  Benjamin Poulain  <benjamin@webkit.org>
+
+        Fix the iteration count of arith-modulo-node-behaviors.js
+
+        * tests/stress/arith-modulo-node-behaviors.js:
+        No need for big numbers for the real testing.
+
+2015-05-12  Mark Lam  <mark.lam@apple.com>
+
+        Windows: Cannot use HANDLE from GetCurrentThread() to get the CONTEXT of another thread.
+        https://bugs.webkit.org/show_bug.cgi?id=144924
+
+        Reviewed by Alex Christensen.
+
+        The present stack scanning code in the Windows port is expecting that the
+        GetCurrentThread() API will provide a unique HANDLE for each thread.  The code
+        then saves and later uses that HANDLE with GetThreadContext() to get the
+        runtime state of the target thread from the GC thread.  According to
+        https://msdn.microsoft.com/en-us/library/windows/desktop/ms683182(v=vs.85).aspx,
+        GetCurrentThread() does not provide this unique HANDLE that we expect:
+
+            "The function cannot be used by one thread to create a handle that can
+            be used by other threads to refer to the first thread. The handle is
+            always interpreted as referring to the thread that is using it. A
+            thread can create a "real" handle to itself that can be used by other
+            threads, or inherited by other processes, by specifying the pseudo
+            handle as the source handle in a call to the DuplicateHandle function."
+
+        As a result of this, GetCurrentThread() always returns the same HANDLE value, and
+        we end up never scanning the stacks of other threads because we wrongly think that
+        they are all equal (in identity) to the scanning thread.  This, in turn, results
+        in crashes due to objects that are incorrectly collected.
+
+        The fix is to call DuplicateHandle() to create a HANDLE that we can use.  The
+        MachineThreads::Thread class already accurately tracks the period of time when
+        we need that HANDLE for the VM.  Hence, the life-cycle of the HANDLE can be tied
+        to the life-cycle of the MachineThreads::Thread object for the corresponding thread.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::getCurrentPlatformThread):
+        (JSC::MachineThreads::Thread::Thread):
+        (JSC::MachineThreads::Thread::~Thread):
+        (JSC::MachineThreads::Thread::suspend):
+        (JSC::MachineThreads::Thread::resume):
+        (JSC::MachineThreads::Thread::getRegisters):
+
+2015-05-12  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Make the NegZero backward propagated flags of ArithMod stricter
+        https://bugs.webkit.org/show_bug.cgi?id=144897
+
+        Reviewed by Geoffrey Garen.
+
+        The NegZero flags of ArithMod were the same as ArithDiv: both children were
+        marked as needing to handle NegativeZero.
+
+        Lucky for us, ArithMod is quite a bit different than ArithDiv.
+
+        First, the sign of the result is completely independent from
+        the sign of the divisor. A zero on the divisor always produces a NaN.
+        That's great, we can remove the NodeBytecodeNeedsNegZero
+        from the flags propagated to child2.
+
+        Second, the sign of the result is always the same as the sign of
+        the dividend. A dividend of zero produces a zero of same sign
+        unless the divisor is zero (in which case the result is NaN).
+        This is great too: we can just pass the flags we got into
+        ArithMod.
+
+        With those two out of the way, we can make a faster version of ArithRound
+        for Kraken's oscillator. Since we no longer care about negative zero,
+        rounding becomes cast<int32>(value + 0.5). This gives ~3% faster runtime
+        on the benchmark.
+
+        Unfortunatelly, most of the time is spent in FTL and the same optimization
+        does not apply well just yet: rdar://problem/20904149.
+
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        Never add NodeBytecodeNeedsNegZero unless needed by the users of this node.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithRound):
+        Faster Math.round() when negative zero is not important.
+
+        * tests/stress/arith-modulo-node-behaviors.js: Added.
+        (moduloWithNegativeZeroDividend):
+        (moduloWithUnusedNegativeZeroDividend):
+        (moduloWithNegativeZeroDivisor):
+
+2015-05-12  Mark Lam  <mark.lam@apple.com>
+
+        Refactor MachineStackMarker.cpp so that it's easier to reason about MachineThreads::Thread.
+        https://bugs.webkit.org/show_bug.cgi?id=144925
+
+        Reviewed by Michael Saboff.
+
+        Currently, the code in MachineStackMarker.cpp is written as a bunch of functions that
+        operate on the platformThread value in the MachineThreads::Thread struct.  Instead, we
+        can apply better OO encapsulation and convert all these functions into methods of the
+        MachineThreads::Thread struct.
+
+        This will also make it easier to reason about the fix for
+        https://bugs.webkit.org/show_bug.cgi?id=144924 later.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::getCurrentPlatformThread):
+        (JSC::MachineThreads::Thread::createForCurrentThread):
+        (JSC::MachineThreads::Thread::operator!=):
+        (JSC::MachineThreads::Thread::operator==):
+        (JSC::MachineThreads::addCurrentThread):
+        (JSC::MachineThreads::removeThreadIfFound):
+        (JSC::MachineThreads::Thread::suspend):
+        (JSC::MachineThreads::Thread::resume):
+        (JSC::MachineThreads::Thread::getRegisters):
+        (JSC::MachineThreads::Thread::Registers::stackPointer):
+        (JSC::MachineThreads::Thread::freeRegisters):
+        (JSC::MachineThreads::Thread::captureStack):
+        (JSC::MachineThreads::tryCopyOtherThreadStack):
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+        (JSC::equalThread): Deleted.
+        (JSC::suspendThread): Deleted.
+        (JSC::resumeThread): Deleted.
+        (JSC::getPlatformThreadRegisters): Deleted.
+        (JSC::otherThreadStackPointer): Deleted.
+        (JSC::freePlatformThreadRegisters): Deleted.
+        (JSC::otherThreadStack): Deleted.
+
+2015-05-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Array.slice should have a fast path like Array.splice
+        https://bugs.webkit.org/show_bug.cgi?id=144901
+
+        Reviewed by Geoffrey Garen.
+
+        Add a fast memcpy path to Array.prototype.slice as done for Array.prototype.splice.
+        In Kraken, this appears to be 30% win on stanford-crypto-ccm and 10% win on stanford-crypto-pbkdf2.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSlice):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fastSlice): Added.
+        * runtime/JSArray.h:
+
+2015-05-11  Filip Pizlo  <fpizlo@apple.com>
+
+        OSR availability analysis would be more scalable (and correct) if it did more liveness pruning
+        https://bugs.webkit.org/show_bug.cgi?id=143078
+
+        Reviewed by Andreas Kling.
+        
+        In https://bugs.webkit.org/show_bug.cgi?id=144883, we found an example of where liveness
+        pruning is actually necessary. Well, not quite: we just need to prune out keys from the
+        heap availability map where the base node doesn't dominate the point where we are asking
+        for availability. If we don't do this, then eventually the IR gets corrupt because we'll
+        insert PutHints that reference the base node in places where the base node doesn't
+        dominate. But if we're going to do any pruning, then it makes sense to prune by bytecode
+        liveness. This is the strongest possible pruning we can do, and it should be sound. We
+        shouldn't have a node available for a virtual register if that register is live and the
+        node doesn't dominate.
+        
+        Making this work meant reusing the prune-to-liveness algorithm from the FTL backend. So, I
+        abstracted this a bit better. You can now availabilityMap.pruneByLiveness(graph, origin).
+
+        * dfg/DFGAvailabilityMap.cpp:
+        (JSC::DFG::AvailabilityMap::pruneHeap):
+        (JSC::DFG::AvailabilityMap::pruneByLiveness):
+        (JSC::DFG::AvailabilityMap::prune): Deleted.
+        * dfg/DFGAvailabilityMap.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        * tests/stress/liveness-pruning-needed-for-osr-availability.js: Added. This is a proper regression test.
+        * tests/stress/liveness-pruning-needed-for-osr-availability-eager.js: Added. This is the original reduced test case, requires eager-no-cjit to fail prior to this changeset.
+
+2015-05-12  Gabor Loki  <loki@webkit.org>
+
+        Workaround for Cortex-A53 erratum 843419
+        https://bugs.webkit.org/show_bug.cgi?id=144680
+
+        Reviewed by Michael Saboff.
+
+        This patch is about to give simple workaround for Cortex-A53 erratum 843419.
+        It inserts nops after ADRP instruction to avoid wrong address accesses.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::adrp):
+        (JSC::ARM64Assembler::nopCortexA53Fix843419):
+
+2015-05-11  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184009.
+        https://bugs.webkit.org/show_bug.cgi?id=144900
+
+        Caused crashes on inspector tests (Requested by ap on
+        #webkit).
+
+        Reverted changeset:
+
+        "MapDataImpl::add() shouldn't do the same hash lookup twice."
+        https://bugs.webkit.org/show_bug.cgi?id=144759
+        http://trac.webkit.org/changeset/184009
+
+2015-05-11  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r184123.
+        https://bugs.webkit.org/show_bug.cgi?id=144899
+
+        Seems to have introduced flaky crashes in many JS tests
+        (Requested by rniwa on #webkit).
+
+        Reverted changeset:
+
+        "REGRESSION(r180595): same-callee profiling no longer works"
+        https://bugs.webkit.org/show_bug.cgi?id=144787
+        http://trac.webkit.org/changeset/184123
+
+2015-05-11  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Move Windows build target to Windows 7 (or newer)
+        https://bugs.webkit.org/show_bug.cgi?id=144890
+        <rdar://problem/20707307>
+
+        Reviewed by Anders Carlsson.
+
+        Update linked SDK and minimal Windows level to be compatible with
+        Windows 7 or newer.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj:
+        * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj:
+        * JavaScriptCore.vcxproj/jsc/jsc.vcxproj:
+        * JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj:
+        * JavaScriptCore.vcxproj/libllvmForJSC/libllvmForJSC.vcxproj:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj:
+        * config.h:
+
+2015-05-08  Filip Pizlo  <fpizlo@apple.com>
+
+        CPS rethreading phase's flush detector flushes way too many SetLocals
+        https://bugs.webkit.org/show_bug.cgi?id=144819
+
+        Reviewed by Geoffrey Garen.
+        
+        After probably unrelated changes, this eventually caused some arguments elimination to stop
+        working because it would cause more SetLocals to turn into PutStacks. But it was a bug for
+        a long time. Basically, we don't want the children of a SetLocal to be flushed. Flushing is
+        meant to only affect the SetLocal itself.
+        
+        This is a speed-up on Octane/earley.
+
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::computeIsFlushed):
+
+2015-05-11  Filip Pizlo  <fpizlo@apple.com>
+
+        gmail and google maps fail to load with eager compilation: Failed to insert inline cache for varargs call (specifically, CallForwardVarargs) because we thought the size would be 250 but it ended up being 262 prior to compaction.
+        https://bugs.webkit.org/show_bug.cgi?id=144854
+
+        Reviewed by Oliver Hunt.
+        
+        This is easy: just lift the threshold. Also remove the need for some duplicate thresholds.
+        It used to be that Construct required less code, but that's not the case for now.
+
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCallForwardVarargs):
+        (JSC::FTL::sizeOfConstructVarargs):
+        (JSC::FTL::sizeOfConstructForwardVarargs):
+
+2015-05-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180595): same-callee profiling no longer works
+        https://bugs.webkit.org/show_bug.cgi?id=144787
+
+        Reviewed by Michael Saboff.
+
+        This patch introduces a DFG optimization to use NewObject node when the callee of op_create_this is
+        always the same JSFunction. This condition doesn't hold when the byte code creates multiple
+        JSFunction objects at runtime as in: function y() { return function () {} }; new y(); new y();
+
+        To enable this optimization, LLint and baseline JIT now store the last callee we saw in the newly
+        added fourth operand of op_create_this. We use this JSFunction's structure in DFG after verifying
+        our speculation that the callee is the same. To avoid recompiling the same code for different callee
+        objects in the polymorphic case, the special value of seenMultipleCalleeObjects() is set in
+        LLint and baseline JIT when multiple callees are observed.
+
+        Tests: stress/create-this-with-callee-variants.js
+
+        * bytecode/BytecodeList.json: Increased the number of operands to 5.
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset): op_create_this uses 2nd (constructor) and 4th (callee cache)
+        operands.
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Dump the newly added callee cache.
+        (JSC::CodeBlock::finalizeUnconditionally): Clear the callee cache if the callee is no longer alive.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCreateThis): Add the instruction to propertyAccessInstructions so that
+        we can clear the callee cache in CodeBlock::finalizeUnconditionally. Also initialize the newly added
+        operand.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock): Implement the optimization. Speculate the actual callee to
+        match the cache. Use the cached callee's structure if the speculation succeeds. Otherwise, OSR exit.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_this): Go to the slow path to update the cache unless it's already marked
+        as seenMultipleCalleeObjects() to indicate the polymorphic behavior.
+        (JSC::JIT::emitSlow_op_create_this):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_this): Ditto.
+        (JSC::JIT::emitSlow_op_create_this):
+        * llint/LowLevelInterpreter32_64.asm:
+        (_llint_op_create_this): Ditto.
+        * llint/LowLevelInterpreter64.asm:
+        (_llint_op_create_this): Ditto.
+        * runtime/CommonSlowPaths.cpp:
+        (slow_path_create_this): Set the callee cache to the actual callee if it's not set. If the cache has
+        been set to a JSFunction* different from the actual callee, set it to seenMultipleCalleeObjects().
+        * runtime/JSCell.h:
+        (JSC::JSCell::seenMultipleCalleeObjects): Added.
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase::unvalidatedGet): Removed the compile guard around it.
+        * tests/stress/create-this-with-callee-variants.js: Added.
+
+2015-05-11  Andreas Kling  <akling@apple.com>
+
+        PropertyNameArray should use a Vector when there are few entries.
+        <https://webkit.org/b/144874>
+
+        Reviewed by Geoffrey Garen.
+
+        Bring back an optimization that was lost in the for-in refactoring.
+        PropertyNameArray now holds a Vector<AtomicStringImpl*> until there are
+        enough (20) entries to justify converting to a HashSet for contains().
+
+        Also inlined the code while we're here, since it has so few clients and
+        the call overhead adds up.
+
+        ~5% progression on Kraken/json-stringify-tinderbox.
+
+        * runtime/PropertyNameArray.cpp: Removed.
+        * runtime/PropertyNameArray.h:
+        (JSC::PropertyNameArray::canAddKnownUniqueForStructure):
+        (JSC::PropertyNameArray::add):
+        (JSC::PropertyNameArray::addKnownUnique):
+
+2015-05-11  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: REGRESSION (r175203): No profile information is shown in Inspector
+        https://bugs.webkit.org/show_bug.cgi?id=144808
+
+        Reviewed by Darin Adler.
+
+        Since a profile can be started after a timeline recording has already begun, we can't assume a zero start time.
+        The start time for the root node's call entry should be based on the stopwatch used by the ProfileGenerator.
+
+        * profiler/Profile.cpp:
+        (JSC::Profile::create):
+        (JSC::Profile::Profile):
+        * profiler/Profile.h:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::AddParentForConsoleStartFunctor::operator()):
+
+2015-05-11  Basile Clement  <basile_clement@apple.com>
+
+        Unreviewed, remove unintended change.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
+2015-05-11  Filip Pizlo  <fpizlo@apple.com>
+
+        Make it easy to enable eager/non-concurrent JIT compilation
+        https://bugs.webkit.org/show_bug.cgi?id=144877
+
+        Reviewed by Michael Saboff.
+
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+
+2015-05-10  Filip Pizlo  <fpizlo@apple.com>
+
+        We shouldn't promote LoadVarargs to a sequence of GetStacks and PutStacks if doing so would exceed the LoadVarargs' limit
+        https://bugs.webkit.org/show_bug.cgi?id=144851
+
+        Reviewed by Michael Saboff.
+        
+        LoadVarargs loads arguments from some object and puts them on the stack. The region of
+        stack is controlled by a bunch of meta-data, including InlineCallFrame. InlineCallFrame
+        shouldn't really be edited after ByteCodeParser, so we cannot convert LoadVarargs to
+        something that uses more stack than the LoadVarargs wanted to.
+        
+        This check was missing in the ArgumentsEliminationPhase's LoadVarargs->GetStack+PutStack
+        promoter. This is an important promotion rule for performance, and in cases where we are
+        compiling truly hot code, the LoadVarargs limit will be at least as big as the length of
+        the phantom arguments array that this phase sees. The LoadVarargs limit is based on
+        profiling and the phantom arguments array is a proof; in most cases the profiling is more
+        conservative.
+        
+        But, you could write some crazy code where the statically obvious arguments array value is
+        bigger than what the profiling would have told you. When this happens, this promotion
+        effectively removes a bounds check. This either results in us clobbering a bunch of stack,
+        or it means that we never initialize a region of the stack that a later operation will read
+        (the uninitialization happens because PutStackSinkingPhase removes PutStacks that appear
+        unnecessary, and a GetMyArgumentByVal will claim not to use the region of the stack outside
+        the original LoadVarargs limit).
+        
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * tests/stress/load-varargs-elimination-bounds-check-barely.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        * tests/stress/load-varargs-elimination-bounds-check.js: Added.
+        (foo):
+        (bar):
+        (baz):
+
+2015-05-11  Andreas Kling  <akling@apple.com>
+
+        JSON.stringify shouldn't use generic get() to access Array.length
+        <https://webkit.org/b/144847>
+
+        Reviewed by Geoffrey Garen.
+
+        If the value being serialized is a JSArray object, we can downcast and call its
+        length() directly instead of doing a generic property lookup.
+
+        0.5% progression on Kraken/json-stringify-tinderbox.
+
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Holder::appendNextProperty):
+
+2015-05-10  Andreas Kling  <akling@apple.com>
+
+        Remove unnecessary AtomicStringImpl* hash specification in PropertyNameArray.
+
+        Follow up to r184050 suggested by Darin.
+
+        * runtime/PropertyNameArray.h:
+
+2015-05-10  Andreas Kling  <akling@apple.com>
+
+        Remove unused things from PropertyNameArray.
+        <https://webkit.org/b/144834>
+
+        Reviewed by Filip Pizlo.
+
+        PropertyNameArray had a bunch of bells and whistles added to it when for-in iteration
+        was refactored and optimized last year. Then more refactoring happened and this class
+        doesn't need to ring and toot anymore.
+
+        The RefCountedIdentifierSet class disappears since the JSPropertyNameEnumerator wasn't
+        actually using it for anything and we were just wasting time creating these.
+
+        Also made the member functions take AtomicStringImpl* instead of plain StringImpl*.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::getPropertyNames):
+        * runtime/JSPropertyNameEnumerator.cpp:
+        (JSC::JSPropertyNameEnumerator::create):
+        (JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator):
+        * runtime/JSPropertyNameEnumerator.h:
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        (JSC::PropertyNameArray::setPreviouslyEnumeratedProperties): Deleted.
+        * runtime/PropertyNameArray.h:
+        (JSC::PropertyNameArray::PropertyNameArray):
+        (JSC::PropertyNameArray::add):
+        (JSC::PropertyNameArray::addKnownUnique):
+        (JSC::PropertyNameArray::canAddKnownUniqueForStructure):
+        (JSC::RefCountedIdentifierSet::contains): Deleted.
+        (JSC::RefCountedIdentifierSet::size): Deleted.
+        (JSC::RefCountedIdentifierSet::add): Deleted.
+        (JSC::PropertyNameArray::identifierSet): Deleted.
+        (JSC::PropertyNameArray::numCacheableSlots): Deleted.
+        (JSC::PropertyNameArray::setNumCacheableSlotsForObject): Deleted.
+        (JSC::PropertyNameArray::setBaseObject): Deleted.
+        (JSC::PropertyNameArray::setPreviouslyEnumeratedLength): Deleted.
+
+2015-05-09  Yoav Weiss  <yoav@yoav.ws>
+
+        Remove the PICTURE_SIZES build flag
+        https://bugs.webkit.org/show_bug.cgi?id=144679
+
+        Reviewed by Benjamin Poulain.
+
+        Removed the PICTURE_SIZES build time flag.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-05-08  Filip Pizlo  <fpizlo@apple.com>
+
+        Extend the SaneChain optimization to Contiguous arrays
+        https://bugs.webkit.org/show_bug.cgi?id=144664
+
+        Reviewed by Mark Lam.
+        
+        Previously if you loaded from a hole, you'd either have to take slow path for the array
+        load (which means C++ calls and prototype chain walks) or you'd exit (if you hadn't
+        gathered the necessary profiling yet). But that's unnecessary if we know that the
+        prototype chain is sane - i.e. has no indexed properties. Then we can just return
+        Undefined for the hole.
+        
+        Making this change requires setting more watchpoints on the array prototype chain. But
+        that hit a horrible bug: ArrayPrototype still uses the static lookup tables and builds
+        itself up lazily. This means that this increased the number of recompilations we'd get
+        due to the array prototype chain being built up.
+        
+        So, this change also removes the laziness and static tables from ArrayPrototype.
+        
+        But to make that change, I also had to add a helper for eagerly building up a prototype
+        that has builtin functions.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * dfg/DFGArrayMode.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        (JSC::ArrayPrototype::getOwnPropertySlot): Deleted.
+        * runtime/ArrayPrototype.h:
+        * runtime/JSObject.h:
+
+2015-05-08  Michael Saboff  <msaboff@apple.com>
+
+        Creating a large MarkedBlock sometimes results in more than one cell in the block
+        https://bugs.webkit.org/show_bug.cgi?id=144815
+
+        Reviewed by Mark Lam.
+
+        Large MarkedBlocks should have one and only one cell.  Changed the calculation of
+        m_endAtom for large blocks to use the location of the first cell + 1.  This
+        assures that large blocks only have one cell.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::MarkedBlock):
+
+2015-05-08  Oliver Hunt  <oliver@apple.com>
+
+        MapDataImpl::add() shouldn't do the same hash lookup twice.
+        https://bugs.webkit.org/show_bug.cgi?id=144759
+
+        Reviewed by Gavin Barraclough.
+
+        We don't actually need to do a double lookup here, all we need to
+        do is update the index to point to the correct m_size.
+
+        * runtime/MapDataInlines.h:
+        (JSC::JSIterator>::add):
+
+2015-05-08  Andreas Kling  <akling@apple.com>
+
+        Micro-optimize JSON serialization of string primitives.
+        <https://webkit.org/b/144800>
+
+        Reviewed by Sam Weinig.
+
+        Don't use the out-of-line JSValue::getString() to grab at string primitives
+        in serialization. Just check if it's a JSString and then downcast to grab at
+        the WTF::String inside.
+
+        2% progression on Kraken/json-stringify-tinderbox.
+
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue):
+
+2015-05-08  Andreas Kling  <akling@apple.com>
+
+        Optimize serialization of quoted JSON strings.
+        <https://webkit.org/b/144754>
+
+        Reviewed by Darin Adler.
+
+        Optimized the serialization of quoted strings into JSON by moving the logic into
+        StringBuilder so it can make smarter decisions about buffering.
+
+        12% progression on Kraken/json-stringify-tinderbox (on my Mac Pro.)
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ObjectPatternNode::toString): Use the new StringBuilder API.
+
+        * runtime/JSONObject.h:
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Holder::appendNextProperty):
+        (JSC::appendStringToStringBuilder): Deleted.
+        (JSC::appendQuotedJSONStringToBuilder): Deleted.
+        (JSC::Stringifier::appendQuotedString): Deleted.
+        (JSC::Stringifier::appendStringifiedValue): Moved the bulk of this logic
+        to StringBuilder and call that from here.
+
+2015-05-07  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183961.
+        https://bugs.webkit.org/show_bug.cgi?id=144784
+
+        Broke js/dom/JSON-stringify.html (Requested by kling on
+        #webkit).
+
+        Reverted changeset:
+
+        "Optimize serialization of quoted JSON strings."
+        https://bugs.webkit.org/show_bug.cgi?id=144754
+        http://trac.webkit.org/changeset/183961
+
+2015-05-07  Filip Pizlo  <fpizlo@apple.com>
+
+        GC has trouble with pathologically large array allocations
+        https://bugs.webkit.org/show_bug.cgi?id=144609
+
+        Reviewed by Geoffrey Garen.
+
+        The bug was that SlotVisitor::copyLater() would return early for oversize blocks (right
+        after pinning them), and would skip the accounting. The GC calculates the size of the heap
+        in tandem with the scan to save time, and that accounting was part of how the GC would
+        know how big the heap was. The GC would then think that oversize copied blocks use no
+        memory, and would then mess up its scheduling of the next GC.
+        
+        Fixing this bug is harder than it seems. When running an eden GC, we figure out the heap
+        size by summing the size from the last collection and the size by walking the eden heap.
+        But this breaks when we eagerly delete objects that the last collection touched. We can do
+        that in one corner case: copied block reallocation. The old block will be deleted from old
+        space during the realloc and a new block will be allocated in new space. In order for the
+        GC to know that the size of old space actually shrank, we need a field to tell us how much
+        such shrinkage could occur. Since this is a very dirty corner case and it only works for
+        very particular reasons arising from the special properties of copied space (single owner,
+        and the realloc is used in places where the compiler already knows that it cannot register
+        allocate a pointer to the old block), I opted for an equally dirty shrinkage counter
+        devoted just to this case. It's called bytesRemovedFromOldSpaceDueToReallocation.
+        
+        To test this, I needed to add an Option to force a particular RAM size in the GC. This
+        allows us to write tests that assert that the GC heap size is some value X, without
+        worrying about machine-to-machine variations due to GC heuristics changing based on RAM
+        size.
+
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::CopiedSpace): Initialize the dirty shrinkage counter.
+        (JSC::CopiedSpace::tryReallocateOversize): Bump the dirty shrinkage counter.
+        * heap/CopiedSpace.h:
+        (JSC::CopiedSpace::takeBytesRemovedFromOldSpaceDueToReallocation): Swap out the counter. Used by the GC when it does its accounting.
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap): Allow the user to force the RAM size.
+        (JSC::Heap::updateObjectCounts): Use the dirty shrinkage counter to good effect. Also, make this code less confusing.
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::copyLater): The early return for isOversize() was the bug. We still need to report these bytes as live. Otherwise the GC doesn't know that it owns this memory.
+        * jsc.cpp: Add size measuring hooks to write the largeish test.
+        (GlobalObject::finishCreation):
+        (functionGCAndSweep):
+        (functionFullGC):
+        (functionEdenGC):
+        (functionHeapSize):
+        * runtime/Options.h:
+        * tests/stress/new-array-storage-array-with-size.js: Fix this so that it actually allocates ArrayStorage arrays and tests the thing it was supposed to test.
+        * tests/stress/new-largeish-contiguous-array-with-size.js: Added. This tests what the other test accidentally started testing, but does so without running your system out of memory.
+        (foo):
+        (test):
+
+2015-05-07  Saam Barati  <saambarati1@gmail.com>
+
+        Global functions should be initialized as JSFunctions in byte code
+        https://bugs.webkit.org/show_bug.cgi?id=144178
+
+        Reviewed by Geoffrey Garen.
+
+        This patch makes the initialization of global functions more explicit by
+        moving initialization into bytecode. It also prepares JSC for having ES6
+        style lexical scoping because initializing global functions in bytecode
+        easily allows global functions to be initialized with the proper scope that
+        will have access to global lexical variables. Global lexical variables
+        should be visible to global functions but don't live on the global object.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedProgramCodeBlock::visitChildren):
+        * bytecode/UnlinkedCodeBlock.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * bytecompiler/BytecodeGenerator.h:
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        * runtime/JSGlobalObject.h:
+
+2015-05-07  Benjamin Poulain  <bpoulain@apple.com>
+
+        Fix the x86 32bits build
+
+        * assembler/X86Assembler.h:
+
+2015-05-07  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Add basic DFG/FTL support for Math.round
+        https://bugs.webkit.org/show_bug.cgi?id=144725
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds two optimizations targeting Math.round():
+        -Add a DFGNode ArithRound corresponding to the intrinsic RoundIntrinsic.
+        -Change the MacroAssembler to be stricter on how we fail to convert a double
+         to ingeter. Previously, any number valued zero would fail, now we only
+         fail for -0.
+
+        Since ArithRound speculate it produces int32, the MacroAssembler assembler
+        part became necessary because zero is a pretty common output of Math.round()
+        and we would OSR exit a lot (and eventually recompile for doubles).
+
+        The implementation itself of the inline Math.round() is exactly the same
+        as the C function that exists for Math.round(). We can very likely do better
+        but it is a good start known to be valid and inlining alone alread provides
+        significant speedups.
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::movmskpd_rr):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
+        When we have a zero, get the sign bit out of the double and check if is one.
+
+        I'll look into doing the same improvement for ARM.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::typeOfDoubleRounding):
+        (JSC::typeOfDoubleFRound): Deleted.
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::roundShouldSpeculateInt32):
+        (JSC::DFG::Graph::negateShouldSpeculateMachineInt): Deleted.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::arithNodeFlags):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasArithMode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithRound):
+        * dfg/DFGSpeculativeJIT.h:
+        * 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/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::convertDoubleToInt32):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleAsInt32):
+        (JSC::FTL::LowerDFGToLLVM::compileArithRound):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::ceil64):
+        * jit/ThunkGenerators.cpp:
+        * runtime/MathCommon.cpp:
+        * runtime/MathCommon.h:
+        * runtime/MathObject.cpp:
+        (JSC::mathProtoFuncRound):
+        * tests/stress/math-round-basics.js: Added.
+        (mathRoundOnIntegers):
+        (mathRoundOnDoubles):
+        (mathRoundOnBooleans):
+        (uselessMathRound):
+        (mathRoundWithOverflow):
+        (mathRoundConsumedAsDouble):
+        (mathRoundDoesNotCareAboutMinusZero):
+        (mathRoundNoArguments):
+        (mathRoundTooManyArguments):
+        (testMathRoundOnConstants):
+        (mathRoundStructTransition):
+        (Math.round):
+
+2015-05-07  Saam Barati  <saambarati1@gmail.com>
+
+        exceptionFuzz tests should explicitly initialize the exceptionFuzz boolean in JavaScript code through a function in jsc.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=144753
+
+        Reviewed by Mark Lam.
+
+        This allows the BytecodeGenerator to freely emit startup code that "may"
+        throw exceptions without worrying that this startup code will trigger
+        the exceptionFuzz exception. The exceptionFuzz counter will only begin
+        ticking when the 'enableExceptionFuzz' function is explicitly called in 
+        the exceptionFuzz tests.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionEnableExceptionFuzz):
+        * tests/exceptionFuzz/3d-cube.js:
+        * tests/exceptionFuzz/date-format-xparb.js:
+        * tests/exceptionFuzz/earley-boyer.js:
+
+2015-05-07  Andreas Kling  <akling@apple.com>
+
+        Optimize serialization of quoted JSON strings.
+        <https://webkit.org/b/144754>
+
+        Reviewed by Darin Adler.
+
+        Optimized the serialization of quoted strings into JSON by moving the logic into
+        StringBuilder so it can make smarter decisions about buffering.
+
+        12% progression on Kraken/json-stringify-tinderbox (on my Mac Pro.)
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ObjectPatternNode::toString): Use the new StringBuilder API.
+
+        * runtime/JSONObject.h:
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Holder::appendNextProperty):
+        (JSC::appendStringToStringBuilder): Deleted.
+        (JSC::appendQuotedJSONStringToBuilder): Deleted.
+        (JSC::Stringifier::appendQuotedString): Deleted.
+        (JSC::Stringifier::appendStringifiedValue): Moved the bulk of this logic
+        to StringBuilder and call that from here.
+
+2015-05-07  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        FunctionCallBracketNode should store the base value to the temporary when subscript has assignment
+        https://bugs.webkit.org/show_bug.cgi?id=144678
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, FunctionCallBracketNode directly use the RegisterID returned by emitNode.
+        But if the base part is the local register and the subscript part has assignment to it, the base result is accidentally rewritten.
+
+        function t() { var ok = {null: function () { } }; ok[ok = null](); }
+        t();  // Should not throw error.
+
+        This patch takes care about `subscriptHasAssignment`.
+        By using `emitNodeForLeftHandSide`, when there's assignment to local variables in RHS,
+        it correctly moves the LHS value to a temporary register.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        * parser/NodeConstructors.h:
+        (JSC::FunctionCallBracketNode::FunctionCallBracketNode):
+        * parser/Nodes.h:
+        * tests/stress/assignment-in-function-call-bracket-node.js: Added.
+        (shouldBe):
+        (shouldBe.):
+
+2015-05-07  Basile Clement  <basile_clement@apple.com>
+
+        Unreviewed, add missing braces on a single-line if that got expanded in r183939
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+
+2015-05-05  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Revert "Introducing the Platform Abstraction Layer (PAL)"
+        https://bugs.webkit.org/show_bug.cgi?id=144751
+
+        Unreviewed.
+
+        PAL should be a new target inside WebCore, rather than a top-level folder.
+
+        * Configurations/FeatureDefines.xcconfig: Updated
+
+2015-05-07  Basile Clement  <basile_clement@apple.com>
+
+        Dumping OSR ExitValue should expand materializations only once
+        https://bugs.webkit.org/show_bug.cgi?id=144694
+
+        Reviewed by Filip Pizlo.
+
+        Currently, dumping OSR exit values will print the full materialization
+        information each time it is encountered. We change it to print only a
+        brief description (only the materialization's address), and print the
+        whole set of materializations later on.
+
+        This makes the dump less confusing (less likely to think that two
+        instances of the same materialization are different), and will be a
+        necessary change if/when we support materialization cycles.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+
+2015-05-07  Andreas Kling  <akling@apple.com>
+
+        Worker threads leak WeakBlocks (as seen on leaks bot)
+        <https://webkit.org/b/144721>
+        <rdar://problem/20848288>
+
+        Reviewed by Darin Adler.
+
+        Nuke any remaining empty WeakBlocks when the Heap is being torn down.
+        Trying to peek into these blocks after the VM is dead would be a bug anyway.
+
+        This fixes a ~750 KB leak seen on the leaks bot.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::~Heap):
+
+2015-05-05  Geoffrey Garen  <ggaren@apple.com>
+
+        Don't branch when accessing the callee
+        https://bugs.webkit.org/show_bug.cgi?id=144645
+
+        Reviewed by Michael Saboff.
+
+        The branch was added in <http://trac.webkit.org/changeset/81040> without
+        explanation.
+
+        kling found it to be a performance problem. See <https://webkit.org/b/144586>.
+
+        Our theory of access to Registers is that it's up to the client to access
+        them in the right way. So, let's do that.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::callee):
+        (JSC::ExecState::setCallee): Call the field object instead of function
+        because nothing guarantees that it's a function.
+        * interpreter/ProtoCallFrame.h:
+        (JSC::ProtoCallFrame::callee):
+        (JSC::ProtoCallFrame::setCallee):
+        * interpreter/Register.h:
+        * runtime/JSObject.h:
+        (JSC::Register::object): Just do a cast like our other accessors do.
+        (JSC::Register::operator=):
+        (JSC::Register::function): Deleted.
+        (JSC::Register::withCallee): Deleted.
+
+2015-05-07  Dan Bernstein  <mitz@apple.com>
+
+        <rdar://problem/19317140> [Xcode] Remove usage of AspenFamily.xcconfig in Source/
+        https://bugs.webkit.org/show_bug.cgi?id=144727
+
+        Reviewed by Darin Adler.
+
+        * Configurations/Base.xcconfig: Don’t include AspenFamily.xcconfig, and define
+        INSTALL_PATH_PREFIX and LD_DYLIB_INSTALL_NAME for the iOS 8.x Simulator.
+
+2015-05-07  Andreas Kling  <akling@apple.com>
+
+        Special-case Int32 values in JSON.stringify().
+        <https://webkit.org/b/144731>
+
+        Reviewed by Michael Saboff.
+
+        Add a fast path for serializing Int32 values to JSON. This is far faster than dragging
+        simple integers through the full-blown dtoa() machinery.
+
+        ~50% speedup on Kraken/json-stringify-tinderbox.
+
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue):
+
+2015-05-06  Ryosuke Niwa  <rniwa@webkit.org>
+
+        ToT WebKit crashes while loading ES6 compatibility table
+        https://bugs.webkit.org/show_bug.cgi?id=144726
+
+        Reviewed by Filip Pizlo.
+
+        The bug was caused by parseClass superfluously avoiding to build up the string after seeing {.
+
+        Always build the identifier here as it could be a method name.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+
+2015-05-05  Filip Pizlo  <fpizlo@apple.com>
+
+        Sane chain and string watchpoints should be set in FixupPhase or the backend rather than WatchpointCollectionPhase
+        https://bugs.webkit.org/show_bug.cgi?id=144665
+
+        Reviewed by Michael Saboff.
+        
+        This is a step towards getting rid of WatchpointCollectionPhase. It's also a step towards
+        extending SaneChain to all indexing shapes.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Set the watchpoints here so that we don't need a case in WatchpointCollectionPhase.
+        (JSC::DFG::FixupPhase::checkArray): Clarify the need for checking the structure. We often forget why we do this instead of always using CheckArray.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnString): Set the watchpoints here so that we don't need a case in WatchpointCollectionPhase.
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle): Remove some code.
+        (JSC::DFG::WatchpointCollectionPhase::handleStringGetByVal): Deleted.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharAt): Set the watchpoints here so that we don't need a case in WatchpointCollectionPhase.
+
+2015-04-02  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Introducing the Platform Abstraction Layer (PAL)
+        https://bugs.webkit.org/show_bug.cgi?id=143358
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig: Updated
+
+2015-05-06  Andreas Kling  <akling@apple.com>
+
+        Don't allocate a StringImpl for every Number JSValue in JSON.stringify().
+        <https://webkit.org/b/144676>
+
+        Reviewed by Darin Adler.
+
+        We were creating a new String for every number JSValue passing through the JSON stringifier.
+        These StringImpl allocations were dominating one of the Kraken JSON benchmarks.
+        Optimize this by using StringBuilder::appendECMAScriptNumber() which uses a stack buffer
+        for the conversion instead.
+
+        13% progression on Kraken/json-stringify-tinderbox.
+
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::appendStringifiedValue):
+
+2015-05-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183847.
+        https://bugs.webkit.org/show_bug.cgi?id=144691
+
+        Caused many assertion failures (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "GC has trouble with pathologically large array allocations"
+        https://bugs.webkit.org/show_bug.cgi?id=144609
+        http://trac.webkit.org/changeset/183847
+
+2015-05-05  Filip Pizlo  <fpizlo@apple.com>
+
+        PutGlobalVar shouldn't have an unconditional store barrier
+        https://bugs.webkit.org/show_bug.cgi?id=133104
+
+        Reviewed by Benjamin Poulain.
+        
+        We don't need a store barrier on PutGlobalVar if the value being stored can be
+        speculated to not be a cell.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+2015-05-05  Filip Pizlo  <fpizlo@apple.com>
+
+        CopiedBlock::reportLiveBytes() should be totally cool with oversize blocks
+        https://bugs.webkit.org/show_bug.cgi?id=144667
+
+        Reviewed by Andreas Kling.
+        
+        We are now calling this method for oversize blocks. It had an assertion that indirectly
+        implied that the block is not oversize, because it was claiming that the number of live
+        bytes should be smaller than the non-oversize-block size.
+
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::reportLiveBytes):
+
+2015-05-05  Filip Pizlo  <fpizlo@apple.com>
+
+        GC has trouble with pathologically large array allocations
+        https://bugs.webkit.org/show_bug.cgi?id=144609
+
+        Reviewed by Mark Lam.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::updateObjectCounts): Make this code less confusing.
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::copyLater): The early return for isOversize() was the bug. We still need to report these bytes as live. Otherwise the GC doesn't know that it owns this memory.
+        * jsc.cpp: Add size measuring hooks to write the largeish test.
+        (GlobalObject::finishCreation):
+        (functionGCAndSweep):
+        (functionFullGC):
+        (functionEdenGC):
+        (functionHeapSize):
+        * tests/stress/new-array-storage-array-with-size.js: Fix this so that it actually allocates ArrayStorage arrays and tests the thing it was supposed to test.
+        * tests/stress/new-largeish-contiguous-array-with-size.js: Added. This tests what the other test accidentally started testing, but does so without running your system out of memory.
+        (foo):
+        (test):
+
+2015-05-05  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL SwitchString slow case creates duplicate switch cases
+        https://bugs.webkit.org/show_bug.cgi?id=144634
+
+        Reviewed by Geoffrey Garen.
+        
+        The problem of duplicate switches is sufficiently annoying that I fixed the issue and also
+        added mostly-debug-only asserts to catch such issues earlier.
+
+        * bytecode/CallVariant.cpp:
+        (JSC::variantListWithVariant): Assertion to prevent similar bugs.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::switchStringRecurse): Assertion to prevent similar bugs.
+        (JSC::FTL::LowerDFGToLLVM::switchStringSlow): This is the bug.
+        * jit/BinarySwitch.cpp:
+        (JSC::BinarySwitch::BinarySwitch): Assertion to prevent similar bugs.
+        * jit/Repatch.cpp:
+        (JSC::linkPolymorphicCall): Assertion to prevent similar bugs.
+        * tests/stress/ftl-switch-string-slow-duplicate-cases.js: Added. This tests the FTL SwitchString bug. It was previously crashing every time.
+        (foo):
+        (cat):
+
+2015-05-05  Basile Clement  <basile_clement@apple.com>
+
+        Fix debug builds after r183812
+        https://bugs.webkit.org/show_bug.cgi?id=144300
+
+        Rubber stamped by Andreas Kling and Filip Pizlo.
+
+        hasObjectMaterializationData() didn't treat MaterializeCreateActivation
+        as having materialization data, which was causing an assertion failure when
+        sinking CreateActivations on debug builds.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasObjectMaterializationData):
+
+2015-05-04  Basile Clement  <basile_clement@apple.com>
+
+        Allow CreateActivation sinking
+        https://bugs.webkit.org/show_bug.cgi?id=144300
+
+        Reviewed by Filip Pizlo.
+
+        This pursues the work started in
+        https://bugs.webkit.org/show_bug.cgi?id=144016 to expand the set of
+        allocations we are able to sink by allowing sinking of CreateActivation
+        node.
+
+        This is achieved by following closely the way NewObject is currently
+        sunk: we add a new PhantomCreateActivation node to record the initial
+        position of the CreateActivation node, new ClosureVarPLoc promoted heap
+        locations to keep track of the variables put in the activation, and a
+        new MaterializeCreateActivation node to allocate and populate the sunk
+        activation.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToPutClosureVarHint):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPhantomCreateActivation):
+        (JSC::DFG::Node::isActivationAllocation):
+        (JSC::DFG::Node::isPhantomActivationAllocation):
+        (JSC::DFG::Node::isPhantomAllocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileMaterializeCreateActivation):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * tests/stress/activation-sink-osrexit.js: Added.
+        (bar):
+        (foo.set result):
+        * tests/stress/activation-sink.js: Added.
+        (bar):
+
+2015-05-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix stale comment.
+
+        * tests/mozilla/js1_5/Array/regress-101964.js:
+
+2015-05-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Large array shouldn't be slow
+        https://bugs.webkit.org/show_bug.cgi?id=144617
+
+        Rubber stamped by Mark Lam.
+
+        * tests/mozilla/js1_5/Array/regress-101964.js: 500ms isn't enough in debug mode. We don't care how long this takes so long as we run it to completion. I've raised the limit much higher.
+
+2015-05-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Large array shouldn't be slow
+        https://bugs.webkit.org/show_bug.cgi?id=144617
+
+        Rubber stamped by Mark Lam.
+
+        * tests/mozilla/js1_5/Array/regress-101964.js: Mozilla may have cared about this being fast a decade ago (or more), but we don't care. We've consistently found that an array implementation that punishes this case to get speed on common-case array accesses is better. This should fix some test failures on the bots.
+
+2015-05-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183789.
+        https://bugs.webkit.org/show_bug.cgi?id=144620
+
+        Causing flakiness on exceptionFuzz tests locally on 32-bit
+        build (Requested by saamyjoon on #webkit).
+
+        Reverted changeset:
+
+        "Global functions should be initialized as JSFunctions in byte
+        code"
+        https://bugs.webkit.org/show_bug.cgi?id=144178
+        http://trac.webkit.org/changeset/183789
+
+2015-05-04  Saam Barati  <saambarati1@gmail.com>
+
+        Global functions should be initialized as JSFunctions in byte code
+        https://bugs.webkit.org/show_bug.cgi?id=144178
+
+        Reviewed by Geoffrey Garen.
+
+        This patch makes the initialization of global functions more explicit by
+        moving initialization into bytecode. It also prepares JSC for having ES6
+        style lexical scoping because initializing global functions in bytecode
+        easily allows global functions to be initialized with the proper scope that
+        will have access to global lexical variables. Global lexical variables
+        should be visible to global functions but don't live on the global object.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedProgramCodeBlock::visitChildren):
+        * bytecode/UnlinkedCodeBlock.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * bytecompiler/BytecodeGenerator.h:
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        * runtime/JSGlobalObject.h:
+
+2015-05-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Large array shouldn't be slow
+        https://bugs.webkit.org/show_bug.cgi?id=144617
+
+        Reviewed by Geoffrey Garen.
+        
+        Decouple MIN_SPARSE_ARRAY_INDEX, which is the threshold for storing to the sparse map when
+        you're already using ArrayStorage mode, from the minimul array length required to use
+        ArrayStorage in a new Array(length) allocation.
+        
+        Lift the array allocation length threshold to something very high. If this works, we'll
+        probably remove that threshold entirely.
+        
+        This is a 27% speed-up on JetStream/hash-map. Because run-jsc-benchmarks still can't run
+        JetStream as a discrete suite, this adds hash-map to LongSpider so that we run it somewhere
+        for now.
+
+        * dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
+        * runtime/ArrayConventions.h:
+        * runtime/JSArray.h:
+        (JSC::JSArray::create):
+        * runtime/JSGlobalObject.h:
+        (JSC::constructEmptyArray):
+        * tests/stress/new-array-storage-array-with-size.js: Skip this test until we fix https://bugs.webkit.org/show_bug.cgi?id=144609.
+
+2015-05-03  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Add backed intrinsics to private functions exposed with private symbols in global object
+        https://bugs.webkit.org/show_bug.cgi?id=144545
+
+        Reviewed by Darin Adler.
+
+        Math.abs and Math.floor have ASM intrinsics And it is further accelerated in DFG/FTL layers.
+        This patch adds intrinsic to private functions exposed with private symbols in global object,
+        @floor and @abs.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalPrivateFuncAbs): Deleted.
+        (JSC::globalPrivateFuncFloor): Deleted.
+        * runtime/MathObject.cpp:
+        * runtime/MathObject.h:
+        * tests/stress/array-from-abs-and-floor.js: Added.
+        (target1):
+        (target2):
+        (target3):
+
+2015-05-04  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [cmake] ARM related build system cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=144566
+
+        Reviewed by Darin Adler.
+
+        * CMakeLists.txt:
+
+2015-05-04  Andreas Kling  <akling@apple.com>
+
+        Optimize WeakBlock's "reap" and "visit" operations.
+        <https://webkit.org/b/144585>
+
+        Reviewed by Geoffrey Garen.
+
+        WeakBlock was using Heap::isLive(void*) to determine the liveness of weak pointees.
+        That function was really written with conservative roots marking in mind, and will do a bunch
+        of sanity and bounds checks.
+
+        For weaks, we know that the pointer will have been a valid cell pointer into a block
+        of appropriate cell size, so we can skip a lot of the checks.
+
+        We now keep a pointer to the MarkedBlock in each WeakBlock. That way we no longer have to do
+        MarkedBlock::blockFor() for every single cell when iterating.
+
+        Note that a WeakBlock's MarkedBlock pointer becomes null when we detach a logically empty
+        WeakBlock from its WeakSet and transfer ownership to Heap. At that point, the block will never
+        be pointing to any live cells, and the only operation that will run on the block is sweep().
+
+        Finally, MarkedBlock allows liveness queries in three states: Marked, Retired, and Allocated.
+        In Allocated state, all cells are reported as live. This state will reset to Marked on next GC.
+        This patch uses that knowledge to avoid branching on the MarkedBlock's state for every cell.
+
+        This is a ~3x speedup of visit() and a ~2x speedup of reap() on Dromaeo/dom-modify, netting
+        what looks like a 1% speedup locally.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::MarkedBlock): Pass *this to the WeakSet's ctor.
+
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::isMarkedOrNewlyAllocated): Added, stripped-down version of isLive() when the
+        block's state is known to be either Marked or Retired.
+
+        (JSC::MarkedBlock::isAllocated): Added, tells WeakBlock it's okay to skip reap/visit since isLive()
+        would report that all cells are live anyway.
+
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::create):
+        (JSC::WeakBlock::WeakBlock): Stash a MarkedBlock* on each WeakBlock.
+
+        (JSC::WeakBlock::visit):
+        (JSC::WeakBlock::reap): Optimized these two to avoid a bunch of pointer arithmetic and branches.
+
+        * heap/WeakBlock.h:
+        (JSC::WeakBlock::disconnectMarkedBlock): Added.
+        * heap/WeakSet.cpp:
+        (JSC::WeakSet::sweep): Call the above when removing a WeakBlock from WeakSet and transferring
+        ownership to Heap until it can die peacefully.
+
+        (JSC::WeakSet::addAllocator):
+        * heap/WeakSet.h:
+        (JSC::WeakSet::WeakSet): Give WeakSet a MarkedBlock& for passing on to WeakBlocks.
+
+2015-05-04  Basile Clement  <basile_clement@apple.com>
+
+        Allocation sinking is prohibiting the creation of phis between a Phantom object and its materialization
+        https://bugs.webkit.org/show_bug.cgi?id=144587
+
+        Rubber stamped by Filip Pizlo.
+
+        When sinking object allocations, we ensure in
+        determineMaterializationPoints that whenever an allocation is
+        materialized on a path to a block, it is materialized in all such
+        paths. Thus when running the SSA calculator to place Phis in
+        placeMaterializationPoints, we can't encounter a situation where some
+        Upsilons are referring to a materialization while others are referring
+        to the phantom object.
+
+        This replaces the code that was adding a materialization late in
+        placeMaterializationPoints to handle that case by an assertion that it
+        does not happen, which will make
+        https://bugs.webkit.org/show_bug.cgi?id=143073 easier to implement.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+
+2015-05-04  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Extending undefined in class syntax should throw a TypeError
+        https://bugs.webkit.org/show_bug.cgi?id=144284
+
+        Reviewed by Darin Adler.
+
+        The bug was caused by op_eq_null evaluating to true when compared to undefined.
+        Explicitly check op_eq_undefined first to detect the case where we're extending undefined.
+
+        We also had bogus test cases checked in class-syntax-extends.html. This patch also fixes them.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ClassExprNode::emitBytecode):
+
+2015-05-04  Ryosuke Niwa  <rniwa@webkit.org>
+
+        new super should be a syntax error
+        https://bugs.webkit.org/show_bug.cgi?id=144282
+
+        Reviewed by Joseph Pecoraro.
+
+        Disallow "new super" as ES6 spec doesn't allow this.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseMemberExpression):
+
+2015-05-04  Saam Barati  <saambarati1@gmail.com>
+
+        JSCallbackObject does not maintain symmetry between accesses for getOwnPropertySlot and put
+        https://bugs.webkit.org/show_bug.cgi?id=144265
+
+        Reviewed by Geoffrey Garen.
+
+        JSCallbackObject will defer to a parent's implementation of getOwnPropertySlot
+        for a static function if the parent has that property slot. JSCallbackObject::put 
+        did not maintain this symmetry of also calling ::put on the parent if the parent 
+        has the property. We should ensure that this symmetry exists.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::put):
+        * API/tests/testapi.c:
+        * API/tests/testapi.js:
+        (globalStaticFunction2):
+        (this.globalStaticFunction2):
+        (iAmNotAStaticFunction):
+        (this.iAmNotAStaticFunction):
+
+2015-05-04  Andreas Kling  <akling@apple.com>
+
+        Make ExecState::vm() branchless in release builds.
+        <https://webkit.org/b/144586>
+
+        Reviewed by Geoffrey Garen.
+
+        Avoid null checking the ExecState's callee() before getting the
+        VM from it. The code was already dereferencing it anyway, since we
+        know it's not gonna be null.
+
+        * runtime/JSCellInlines.h:
+        (JSC::ExecState::vm):
+
+2015-05-04  Basile Clement  <basile_clement@apple.com>
+
+        Object allocation not sinking properly through CheckStructure
+        https://bugs.webkit.org/show_bug.cgi?id=144465
+
+        Reviewed by Filip Pizlo.
+
+        Currently, sinking an allocation through a CheckStructure will
+        completely ignore all structure checking, which is obviously wrong.
+
+        A CheckStructureImmediate node type was present for that purpose, but
+        the CheckStructures were not properly replaced.  This ensures that
+        CheckStructure nodes are replaced by CheckStructureImmediate nodes when
+        sunk through, and that structure checking happens correctly.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToCheckStructureImmediate): Added.
+        (JSC::DFG::Node::hasStructureSet):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckStructureImmediate):
+        (JSC::FTL::LowerDFGToLLVM::checkStructure):
+        * tests/stress/sink_checkstructure.js: Added.
+        (foo):
+
+2015-05-01  Geoffrey Garen  <ggaren@apple.com>
+
+        REGRESSION(r183570): jslib-traverse-jquery is 22% slower
+        https://bugs.webkit.org/show_bug.cgi?id=144476
+
+        Reviewed by Sam Weinig.
+
+        jslib-traverse-jquery is now 31% faster than its unregressed baseline.
+
+        The jQuery algorithm for sorting DOM nodes is so pathologically slow that,
+        to my knowledge, the topic of how to optimize it is not covered in any
+        literature about sorting.
+
+        On the slowest jQuery sorting test -- prevAll -- our new
+        Array.prototype.sort, compared to its predecessor, performed 12% fewer
+        comparisons and requireed 10X less overhead per comparison. Yet, it was
+        slower.
+
+        It was slower because it inadvertantly increased the average cost of the
+        comparison function by 2X. jQuery uses compareDocumentPosition to compare
+        DOM nodes, and compareDocumentPosition(a, b) is O(N) in the distance
+        required to traverse backwards from b to a. In prevAll, we encounter the
+        worst case for merge sort of compareDocumentPosition: A long list of DOM
+        nodes in mostly reverse order. In this case, merge sort will sequentially
+        compareDocumentPosition(a, b), where a is not reachable backwards from
+        b, and therefore compareDocumentPosition will traverse the whole sibling
+        list.
+
+        The solution is simple enough: Call compareDocumentPosition(b, a) instead.
+
+        This is a pretty silly thing to do, but it is harmless, and jQuery is
+        popular, so let's do it.
+
+        We do not risk suffering the same problem in reverse when sorting a long
+        list of DOM nodes in forward order. (We still have a 37% speedup on the
+        nextAll benchmark.) The reason is that merge sort performs 2X fewer
+        comparisons when the list is already sorted, so we can worry less about
+        the cost of each comparison.
+
+        A fully principled soultion to this problem would probably do something
+        like Python's timsort, which special-cases ordered ranges to perform
+        only O(n) comparisons. But that would contradict our original
+        goal of just having something simple that works.
+
+        Another option is for elements to keep a compareDocumentPosition cache,
+        like a node list cache, which allows you to determine the absolute
+        position of a node using a hash lookup. I will leave this as an exercise
+        for kling.
+
+        * builtins/Array.prototype.js:
+        (sort.merge): Compare in an order that is favorable to a comparator
+        that calls compareDocumentPosition.
+
+2015-05-04  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [cmake] Fix generate-js-builtins related incremental build issue
+        https://bugs.webkit.org/show_bug.cgi?id=144094
+
+        Reviewed by Michael Saboff.
+
+        * CMakeLists.txt: Generated JSCBuiltins.<cpp|h> should depend on Source/JavaScriptCore/builtins directory.
+        Pass input directory to generate-js-builtins instead of Source/JavaScriptCore/builtins/*.js.
+        * DerivedSources.make:
+        Pass input directory to generate-js-builtins instead of Source/JavaScriptCore/builtins/*.js.
+        * generate-js-builtins: Accept input files and input directory too.
+
+2015-05-03  Simon Fraser  <simon.fraser@apple.com>
+
+        Make some static data const
+        https://bugs.webkit.org/show_bug.cgi?id=144552
+
+        Reviewed by Andreas Kling.
+        
+        Turn characterSetInfo into const data.
+
+        * yarr/YarrCanonicalizeUCS2.cpp:
+        * yarr/YarrCanonicalizeUCS2.h:
+
+2015-05-01  Filip Pizlo  <fpizlo@apple.com>
+
+        TypeOf should be fast
+        https://bugs.webkit.org/show_bug.cgi?id=144396
+
+        Reviewed by Geoffrey Garen.
+        
+        Adds comprehensive support for fast typeof to the optimizing JITs. Calls into the runtime
+        are only used for very exotic objects - they must have either the MasqueradesAsUndefined or
+        TypeOfShouldCallGetCallData type flags set. All other cases are handled inline.
+        
+        This means optimizing IsObjectOrNull, IsFunction, and TypeOf - all node types that used to
+        rely heavily on C++ calls to fulfill their function.
+        
+        Because TypeOf is now so fast, we no longer need to do any speculations on this node.
+        
+        In the FTL, we take this further by querying AI for each branch in the TypeOf decision tree.
+        This means that if the TypeOf is dominated by any type checks, we will automatically prune
+        out cases that are redundant.
+        
+        This patch anticipates the addition of SwitchTypeOf or something like that. So, the TypeOf
+        code generation is designed to be reusable.
+        
+        This is a speed-up on most typeof benchmarks. But, it is a slow-down on benchmarks that take
+        the exotic call trap hook. That hook is now in a deeper slow path than before.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize): TypeOf was pure all along, but we failed to realize this.
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIsObjectOrNull):
+        (JSC::DFG::SpeculativeJIT::compileIsFunction):
+        (JSC::DFG::SpeculativeJIT::compileTypeOf):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::blessedBooleanResult):
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * 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/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObjectOrNull):
+        (JSC::FTL::LowerDFGToLLVM::compileIsFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileTypeOf):
+        (JSC::FTL::LowerDFGToLLVM::buildTypeOf): Reusable TypeOf building for the FTL.
+        (JSC::FTL::LowerDFGToLLVM::isExoticForTypeof):
+        * ftl/FTLSwitchCase.h:
+        (JSC::FTL::SwitchCase::SwitchCase):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfNotEqual):
+        (JSC::AssemblyHelpers::branchIfEqual):
+        (JSC::AssemblyHelpers::branchIfNumber):
+        (JSC::AssemblyHelpers::branchIfNotNumber):
+        (JSC::AssemblyHelpers::branchIfBoolean):
+        (JSC::AssemblyHelpers::branchIfNotBoolean):
+        (JSC::AssemblyHelpers::boxBooleanPayload):
+        (JSC::AssemblyHelpers::boxBoolean):
+        (JSC::AssemblyHelpers::emitTypeOf): Reusable TypeOf building for assembly JITs.
+        * jit/JITOperations.h:
+        * runtime/SmallStrings.h:
+        (JSC::SmallStrings::typeString):
+        * runtime/TypeofType.cpp: Added.
+        (WTF::printInternal):
+        * runtime/TypeofType.h: Added.
+        * tests/stress/type-of-functions-and-objects.js: Modified this test to give more comprehensive feedback.
+
+2015-05-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, add a FIXME referencing https://bugs.webkit.org/show_bug.cgi?id=144527.
+
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::attemptHoist):
+
+2015-05-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, add FIXMEs referencing https://bugs.webkit.org/show_bug.cgi?id=144524 and
+        https://bugs.webkit.org/show_bug.cgi?id=144525.
+
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::attemptHoist):
+        * dfg/DFGPhantomInsertionPhase.cpp:
+
+2015-05-02  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Static property hashtable should only lookup with non-symbol key
+        https://bugs.webkit.org/show_bug.cgi?id=144438
+
+        Reviewed by Darin Adler.
+
+        Static property hashtable compares the Identifier's uid
+        with the normal C string without interning it.
+        So this comparison is performed in their contents.
+        As the result, in this comparison, symbol-ness is not considered.
+
+        So if accidentally the hash collision occur with the symbol and the string
+        and they have the same contents, the hash table entry is looked up incorrectly.
+
+        * runtime/Lookup.h:
+        (JSC::HashTable::entry):
+
+2015-05-01  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Class syntax should allow string and numeric identifiers for method names
+        https://bugs.webkit.org/show_bug.cgi?id=144254
+
+        Reviewed by Darin Adler.
+
+        Added the support for string and numeric identifiers in class syntax.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo): Instead of using ConstructorKind to indicate whether we're
+        inside a class or not, use the newly added SuperBinding argument instead. ConstructorKind is now None
+        outside a class constructor as it should be.
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass): No longer expects an identifier at the beginning of every class
+        element to allow numeric and string method names. For both of those method names, parse it here instead
+        of parseFunctionInfo since it doesn't support either type. Also pass in SuperBinding::Needed.
+        (JSC::Parser<LexerType>::parsePropertyMethod): Call parseFunctionInfo with SuperBinding::NotNeeded since
+        this function is never used to parse a class method.
+        (JSC::Parser<LexerType>::parseGetterSetter): Pass in superBinding argument to parseFunctionInfo.
+        (JSC::Parser<LexerType>::parsePrimaryExpression): Call parseFunctionInfo with SuperBinding::NotNeeded.
+        * parser/Parser.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createProperty):
+
+2015-05-01  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should use AI more
+        https://bugs.webkit.org/show_bug.cgi?id=144500
+
+        Reviewed by Oliver Hunt.
+        
+        This makes our type check folding even more comprehensive by ensuring that even if the FTL
+        decides to emit some checks, it will still do another query to the abstract interpreter to
+        see if the check is necessary. This helps with cases where we decided early on to speculate
+        one way, but later proved a more specific type of the value in question, and the constant
+        folder didn't catch it.
+        
+        This also makes it more natural to query the abstract interpreter. For example, if you just
+        want the proven type, you can now say provenType(node) or provenType(edge).
+
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        * dfg/DFGArrayMode.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileBooleanToNumber):
+        (JSC::FTL::LowerDFGToLLVM::compileToThis):
+        (JSC::FTL::LowerDFGToLLVM::compileValueAdd):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+        (JSC::FTL::LowerDFGToLLVM::compileArithPow):
+        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+        (JSC::FTL::LowerDFGToLLVM::compileGetById):
+        (JSC::FTL::LowerDFGToLLVM::compileCheckArray):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileToStringOrCallStringConstructor):
+        (JSC::FTL::LowerDFGToLLVM::compileToPrimitive):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::compileIsBoolean):
+        (JSC::FTL::LowerDFGToLLVM::compileIsNumber):
+        (JSC::FTL::LowerDFGToLLVM::compileIsString):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
+        (JSC::FTL::LowerDFGToLLVM::compileInstanceOf):
+        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
+        (JSC::FTL::LowerDFGToLLVM::baseIndex):
+        (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
+        (JSC::FTL::LowerDFGToLLVM::typedArrayLength):
+        (JSC::FTL::LowerDFGToLLVM::boolify):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::lowInt32):
+        (JSC::FTL::LowerDFGToLLVM::lowInt52):
+        (JSC::FTL::LowerDFGToLLVM::lowCell):
+        (JSC::FTL::LowerDFGToLLVM::lowBoolean):
+        (JSC::FTL::LowerDFGToLLVM::lowDouble):
+        (JSC::FTL::LowerDFGToLLVM::isCellOrMisc):
+        (JSC::FTL::LowerDFGToLLVM::isNotCellOrMisc):
+        (JSC::FTL::LowerDFGToLLVM::isNumber):
+        (JSC::FTL::LowerDFGToLLVM::isNotNumber):
+        (JSC::FTL::LowerDFGToLLVM::isNotCell):
+        (JSC::FTL::LowerDFGToLLVM::isCell):
+        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
+        (JSC::FTL::LowerDFGToLLVM::isMisc):
+        (JSC::FTL::LowerDFGToLLVM::isNotBoolean):
+        (JSC::FTL::LowerDFGToLLVM::isBoolean):
+        (JSC::FTL::LowerDFGToLLVM::isNotOther):
+        (JSC::FTL::LowerDFGToLLVM::isOther):
+        (JSC::FTL::LowerDFGToLLVM::isProvenValue):
+        (JSC::FTL::LowerDFGToLLVM::isObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotString):
+        (JSC::FTL::LowerDFGToLLVM::isString):
+        (JSC::FTL::LowerDFGToLLVM::isFunction):
+        (JSC::FTL::LowerDFGToLLVM::isNotFunction):
+        (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+        (JSC::FTL::LowerDFGToLLVM::speculateStringObjectForStructureID):
+        (JSC::FTL::LowerDFGToLLVM::speculateNotStringVar):
+        (JSC::FTL::LowerDFGToLLVM::abstractValue):
+        (JSC::FTL::LowerDFGToLLVM::provenType):
+        (JSC::FTL::LowerDFGToLLVM::provenValue):
+        (JSC::FTL::LowerDFGToLLVM::abstractStructure):
+
+2015-05-01  Martin Robinson  <mrobinson@igalia.com>
+
+        USE(...) macro should expect unprefixed variables
+        https://bugs.webkit.org/show_bug.cgi?id=144454
+
+        Reviewed by Daniel Bates.
+
+        * CMakeLists.txt: Replace all occurrences WTF_USE with USE.
+
+2015-05-01  Jordan Harband  <ljharb@gmail.com>
+
+        String#startsWith/endsWith/includes don't handle Infinity position/endPosition args correctly
+        https://bugs.webkit.org/show_bug.cgi?id=144314
+
+        Reviewed by Darin Adler.
+
+        Fixing handling of Infinity position args, per
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.includes
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith
+
+        * runtime/StringPrototype.cpp:
+        (JSC::clampInt32):
+        (JSC::stringProtoFuncStartsWith):
+        (JSC::stringProtoFuncEndsWith):
+        (JSC::stringProtoFuncIncludes):
+
+2015-05-01  Basile Clement  <basile_clement@apple.com>
+
+        Math.abs() returns negative
+        https://bugs.webkit.org/show_bug.cgi?id=137827
+
+        Reviewed by Michael Saboff.
+
+        Math.abs() on doubles was mistakenly assumed by the DFG AI to be the
+        identity function.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * tests/stress/math-abs-positive.js: Added, was previously failing.
+        (foo):
+
+2015-05-01  Basile Clement  <basile_clement@apple.com>
+
+        Function allocation sinking shouldn't be performed on singleton functions
+        https://bugs.webkit.org/show_bug.cgi?id=144166
+
+        Reviewed by Geoffrey Garen.
+
+        Function allocations usually are free of any other side effects, but
+        this is not the case for allocations performed while the underlying
+        FunctionExecutable is still a singleton (as this allogation will fire
+        watchpoints invalidating code that depends on it being a singleton).
+        As the object allocation sinking phase assumes object allocation is
+        free of side-effects, sinking these allocations is not correct.
+
+        This also means that when materializing a function allocation on OSR
+        exit, that function's executable will never be a singleton, and we don't have
+        to worry about its watchpoint, allowing us to use
+        JSFunction::createWithInvalidatedRellocationWatchpoint instead of
+        JSFunction::create.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+
+2015-04-30  Jon Davis  <jond@apple.com>
+
+        Web Inspector: console should show an icon for console.info() messages
+        https://bugs.webkit.org/show_bug.cgi?id=18530
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::messageLevelValue):
+        * inspector/protocol/Console.json:
+        * runtime/ConsoleClient.cpp:
+        (JSC::appendMessagePrefix):
+        * runtime/ConsolePrototype.cpp:
+        (JSC::ConsolePrototype::finishCreation):
+        (JSC::consoleProtoFuncInfo):
+        * runtime/ConsoleTypes.h:
+
+2015-04-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Move all of the branchIs<type> helpers from SpeculativeJIT into AssemblyHelpers
+        https://bugs.webkit.org/show_bug.cgi?id=144462
+
+        Reviewed by Geoffrey Garen and Mark Lam.
+        
+        At some point we started adding representation-agnostic helpers for doing common type tests.
+        We added some in SpeculativeJIT, and then some in AssemblyHelpers. Prior to this change,
+        they had overlapping powers, though SpeculativeJIT was a bit better.
+        
+        This removes SpeculativeJIT's helpers and strengthens AssemblyHelpers' helpers. This is
+        better because now all of these helpers can be used in all of the assembly-based JITs, not
+        just the DFG. It also settles on what I find to be a slightly better naming convention.
+        For example where we previously would have said branchIsString, now we say
+        branchIfString. Similarly, branchNotString becomes branchIfNotString.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
+        (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell):
+        (JSC::DFG::SpeculativeJIT::speculateObject):
+        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+        (JSC::DFG::SpeculativeJIT::speculateString):
+        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
+        (JSC::DFG::SpeculativeJIT::speculateNotCell):
+        (JSC::DFG::SpeculativeJIT::speculateOther):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        (JSC::DFG::SpeculativeJIT::branchIsObject): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotObject): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchIsString): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotString): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::branchIsCell): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotCell): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchIsOther): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotOther): Deleted.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        (JSC::DFG::SpeculativeJIT::branchIsCell): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotCell): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchIsOther): Deleted.
+        (JSC::DFG::SpeculativeJIT::branchNotOther): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfCell):
+        (JSC::AssemblyHelpers::branchIfOther):
+        (JSC::AssemblyHelpers::branchIfNotOther):
+        (JSC::AssemblyHelpers::branchIfObject):
+        (JSC::AssemblyHelpers::branchIfNotObject):
+        (JSC::AssemblyHelpers::branchIfType):
+        (JSC::AssemblyHelpers::branchIfNotType):
+        (JSC::AssemblyHelpers::branchIfString):
+        (JSC::AssemblyHelpers::branchIfNotString):
+        (JSC::AssemblyHelpers::branchIfSymbol):
+        (JSC::AssemblyHelpers::branchIfNotSymbol):
+        (JSC::AssemblyHelpers::branchIfFunction):
+        (JSC::AssemblyHelpers::branchIfNotFunction):
+        (JSC::AssemblyHelpers::branchIfEmpty):
+        (JSC::AssemblyHelpers::branchIsEmpty): Deleted.
+        (JSC::AssemblyHelpers::branchIfCellNotObject): Deleted.
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+
+2015-04-30  Filip Pizlo  <fpizlo@apple.com>
+
+        js/regress/is-string-fold-tricky.html and js/regress/is-string-fold.html are crashing
+        https://bugs.webkit.org/show_bug.cgi?id=144463
+
+        Reviewed by Benjamin Poulain.
+        
+        Fixup phase was super cleverly folding an IsString(@x) when @x is predicted SpecString
+        into a Check(String:@x) followed by JSConstant(true). Then in these tests the
+        ValueAdd(IsString(@x), @stuff) would try to turn this into an integer add by cleverly
+        converting the boolean into an integer. But as part of doing that, it would try to
+        short-circuit any profiling by leveraging the fact that the IsString is now a constant,
+        and it would try to figure out if the addition might overflow. Part of that logic
+        involved checking if the immediate is either a boolean or a sufficiently small integer.
+        But: it would check if it's a sufficiently small integer before checking if it was a
+        boolean, so it would try to call asNumber() on the boolean.
+        
+        All of this cleverness was very deliberate, but apparently the @stuff + booleanConstant
+        case was previously never hit until I wrote these tests, and so we never knew that
+        calling asNumber() on a boolean was wrong.
+        
+        The fix is super simple: the expression should just check for boolean first.
+        
+        This bug was benign in release builds. JSValue::asNumber() on a boolean would return
+        garbage, and that's OK, since we'd take the boolean case anyway.
+
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
+
+2015-04-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, add a FIXME comment referencing https://bugs.webkit.org/show_bug.cgi?id=144458.
+
+        * jit/JITOperations.cpp:
+
+2015-04-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Add a comment clarifying the behavior and semantics of getCallData/getConstructData, in
+        particular that they cannot change their minds and may be called from compiler threads.
+
+        Rubber stamped by Geoffrey Garen.
+
+        * runtime/JSCell.h:
+
+2015-04-29  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG Is<Blah> versions of TypeOf should fold based on proven input type
+        https://bugs.webkit.org/show_bug.cgi?id=144409
+
+        Reviewed by Geoffrey Garen.
+        
+        We were missing some obvious folding opportunities here. I don't know how this affects real
+        code, but in general, we like to ensure that our constant folding is comprehensive. So this
+        is more about placating my static analysis OCD than anything else.
+        
+        I added a bunch of speed/correctness tests for this in LayoutTests/js/regress.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
+2015-04-30  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Use the default hash value for Symbolized StringImpl
+        https://bugs.webkit.org/show_bug.cgi?id=144347
+
+        Reviewed by Darin Adler.
+
+        Before this patch, symbolized StringImpl* has a special hash value
+        to avoid the hash collision with the other normal StringImpl*.
+        I guess that it is introduced when private symbols are introduced.
+        However, it prevents using symbolized StringImpl* in the other place
+        For example, using it as WTFString cause a problem because of its special hash value.
+
+        When only using private symbols, they are not exposed to the outside of JSC,
+        so we can handle it carefully. But now, it's extended to symbols.
+        So I think storing a special hash value in StringImpl* causes an error.
+
+        To avoid this, I propose using the usual hash value in symbolized StringImpl*.
+        And to provide significantly different hash value when using it as symbol,
+        store the additional hash value in symbolized StringImpl*. It is used when
+        the hash value is required by IdentifierRepHash.
+
+        * runtime/Identifier.h:
+        (JSC::IdentifierRepHash::hash):
+        * runtime/Lookup.h:
+        (JSC::HashTable::entry):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::get):
+        * runtime/Structure.cpp:
+        (JSC::PropertyTable::checkConsistency):
+
+2015-04-29  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Remove RageConvert array conversion
+        https://bugs.webkit.org/show_bug.cgi?id=144433
+
+        Reviewed by Filip Pizlo.
+
+        RageConvert was causing a subtle bug that was hitting the Kraken crypto tests
+        pretty hard:
+        -The indexing types shows that the array access varies between Int32 and DoubleArray.
+        -ArrayMode::fromObserved() decided to use the most generic type: DoubleArray.
+         An Arrayify node would convert the Int32 to that type.
+        -Somewhere, a GetByVal or PutByVal would have the flag NodeBytecodeUsesAsInt. That
+         node would use RageConvert instead of Convert.
+        -The Arrayify for that GetByVal with RageConvert would not convert the array to
+         Contiguous.
+        -All the following array access that do not have the flag NodeBytecodeUsesAsInt would
+         now expect a DoubleArray and always get a Contiguous Array. The CheckStructure
+         fail systematically and we never get to run the later code.
+
+        Getting rid of RageConvert fixes the problem and does not seems to have any
+        negative side effect on other benchmarks.
+
+        The improvments on Kraken are:
+            -stanford-crypto-aes: definitely 1.0915x faster.
+            -stanford-crypto-pbkdf2: definitely 1.2446x faster.
+            -stanford-crypto-sha256-iterative: definitely 1.0544x faster.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        (JSC::DFG::arrayConversionToString):
+        * dfg/DFGArrayMode.h:
+        * dfg/DFGArrayifySlowPathGenerator.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertDoubleToContiguous):
+        (JSC::JSObject::ensureContiguousSlow):
+        (JSC::JSObject::genericConvertDoubleToContiguous): Deleted.
+        (JSC::JSObject::rageConvertDoubleToContiguous): Deleted.
+        (JSC::JSObject::rageEnsureContiguousSlow): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::rageEnsureContiguous): Deleted.
+
+2015-04-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Gracefully handle missing auto pause key on remote inspector setup
+        https://bugs.webkit.org/show_bug.cgi?id=144411
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::receivedSetupMessage):
+
+2015-04-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        NodeList has issues with Symbol and empty string
+        https://bugs.webkit.org/show_bug.cgi?id=144310
+
+        Reviewed by Darin Adler.
+
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::isSymbol):
+        Helper to check if the PropertyName is a string or symbol property.
+
+2015-04-29  Alex Christensen  <achristensen@webkit.org>
+
+        Fix non-cygwin incremental builds on Windows.
+        https://bugs.webkit.org/show_bug.cgi?id=143264
+
+        Reviewed by Brent Fulgham.
+
+        * generate-js-builtins:
+        Remove stale headers before calling os.rename to replace them.
+
+2015-04-29  Filip Pizlo  <fpizlo@apple.com>
+
+        JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
+        https://bugs.webkit.org/show_bug.cgi?id=144397
+
+        Reviewed by Andreas Kling.
+        
+        Add the flag to JSTypeInfo. It's an inline flag so that it's fast to query. Slap the flag on
+        callback objects and internal functions. Modify the TypeOf operation to use this flag to avoid
+        making a getCallData() call if it isn't necessary.
+
+        * API/JSCallbackObject.h:
+        * runtime/InternalFunction.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::typeOfShouldCallGetCallData):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        * tests/stress/type-of-functions-and-objects.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (fuzz):
+        (expect):
+        (test):
+
+2015-04-28  Geoffrey Garen  <ggaren@apple.com>
+
+        It shouldn't take 1846 lines of code and 5 FIXMEs to sort an array.
+        https://bugs.webkit.org/show_bug.cgi?id=144013
+
+        Reviewed by Mark Lam.
+
+        This patch implements Array.prototype.sort in JavaScript, removing the
+        C++ implementations. It is simpler and less error-prone to express our
+        operations in JavaScript, which provides memory safety, exception safety,
+        and recursion safety.
+
+        The performance result is mixed, but net positive in my opinion. It's
+        difficult to enumerate all the results, since we used to have so many
+        different sorting modes, and there are lots of different data patterns
+        across which you might want to measure sorting. Suffice it to say:
+
+            (*) The benchmarks we track are faster or unchanged.
+
+            (*) Sorting random input using a comparator -- which we think is
+            common -- is 3X faster.
+
+            (*) Sorting random input in a non-array object -- which jQuery does
+            -- is 4X faster.
+
+            (*) Sorting random input in a compact array of integers using a
+            trivial pattern-matchable comparator is 2X *slower*.
+
+        * builtins/Array.prototype.js:
+        (sort.min):
+        (sort.stringComparator):
+        (sort.compactSparse): Special case compaction for sparse arrays because
+        we don't want to hang when sorting new Array(BIG).
+
+        (sort.compact):
+        (sort.merge):
+        (sort.mergeSort): Use merge sort because it's a reasonably efficient
+        stable sort. We have evidence that some sites depend on stable sort,
+        even though the ES6 spec does not mandate it. (See
+        <http://trac.webkit.org/changeset/33967>.)
+
+        This is a textbook implementation of merge sort with three optimizations:
+
+            (1) Use iteration instead of recursion;
+
+            (2) Use array subscripting instead of array copying in order to
+            create logical sub-lists without creating physical sub-lists;
+
+            (3) Swap src and dst at each iteration instead of copying src into
+            dst, and only copy src into the subject array at the end if src is
+            not the subject array.
+
+        (sort.inflate):
+        (sort.comparatorSort):
+        (sort): Sort in JavaScript for the win.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutableInternal): Allow non-private
+        names so we can use helper functions.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::isNumericCompareFunction): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setIsNumericCompareFunction): Deleted.
+        (JSC::UnlinkedCodeBlock::isNumericCompareFunction): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::setIsNumericCompareFunction): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionNode::emitBytecode): We don't do this special casing based
+        on pattern matching anymore. This was mainly an optimization to avoid 
+        the overhead of calling from C++ to JS, which we now avoid by
+        sorting in JS.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::pushTempSortVector): Deleted.
+        (JSC::Heap::popTempSortVector): Deleted.
+        (JSC::Heap::visitTempSortVectors): Deleted.
+        * heap/Heap.h: We don't have temp sort vectors anymore because we sort
+        in JavaScript using a normal JavaScript array for our temporary storage.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner): Allow capturing so we can use
+        helper functions.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::isNumericCompareFunction): Deleted.
+        (JSC::attemptFastSort): Deleted.
+        (JSC::performSlowSort): Deleted.
+        (JSC::arrayProtoFuncSort): Deleted.
+
+        * runtime/CommonIdentifiers.h: New strings used by sort.
+
+        * runtime/JSArray.cpp:
+        (JSC::compareNumbersForQSortWithInt32): Deleted.
+        (JSC::compareNumbersForQSortWithDouble): Deleted.
+        (JSC::compareNumbersForQSort): Deleted.
+        (JSC::compareByStringPairForQSort): Deleted.
+        (JSC::JSArray::sortNumericVector): Deleted.
+        (JSC::JSArray::sortNumeric): Deleted.
+        (JSC::ContiguousTypeAccessor::getAsValue): Deleted.
+        (JSC::ContiguousTypeAccessor::setWithValue): Deleted.
+        (JSC::ContiguousTypeAccessor::replaceDataReference): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::getAsValue): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::setWithValue): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::replaceDataReference): Deleted.
+        (JSC::JSArray::sortCompactedVector): Deleted.
+        (JSC::JSArray::sort): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_less): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_less): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_greater): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_greater): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_balance_factor): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_balance_factor): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_key_node): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_node_node): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::null): Deleted.
+        (JSC::JSArray::sortVector): Deleted.
+        (JSC::JSArray::compactForSorting): Deleted.
+        * runtime/JSArray.h:
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation): Provide some builtins used
+        by sort.
+
+2015-04-29  Mark Lam  <mark.lam@apple.com>
+
+        Safari WebKit crash when loading Google Spreadsheet.
+        https://bugs.webkit.org/show_bug.cgi?id=144020
+
+        Reviewed by Filip Pizlo.
+
+        The bug is that the object allocation sinking phase did not account for a case
+        where a property of a sunken object is only initialized on one path and not
+        another.  As a result, on the path where the property is not initialized, we'll
+        encounter an Upsilon with a BottomValue (which is not allowed by definition).
+
+        The fix is to use a JSConstant(undefined) as the bottom value instead (of
+        BottomValue).  If the property is uninitialized, it should still be accessible
+        and have the value undefined.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        * tests/stress/object-allocation-sinking-with-uninitialized-property-on-one-path.js: Added.
+        (foo):
+        (foo2):
+
+2015-04-29  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION (r183373): ASSERT failed in wtf/SHA1.h
+        https://bugs.webkit.org/show_bug.cgi?id=144257
+
+        Reviewed by Darin Adler.
+
+        SHA1 is used to calculate CodeBlockHash.
+        To calculate hash value, we pass the source code UTF-8 CString to SHA1::addBytes.
+        However, the source code can contain null character.
+        So when performing `strlen` on the source code's CString, it returns the incorrect length.
+        In SHA1::addBytes, there's assertion `input.length() == strlen(string)` and it fails.
+
+        In the template-literal-syntax.js, we perform `eval` with the script contains "\0".
+        As the result, `strlen(string)` accidentally shortened by the contained "\0", and assertion fails.
+
+        CString will be changed not to contain a null-character[1]. However, inserting the assertion here
+        is not correct. Because
+
+        1. If CString should not contain a null character, this should be asserted in CString side instead of SHA1::addBytes.
+        2. If CString can contain a null character, this assertion becomes incorrect.
+
+        So this patch just drops the assertion.
+
+        In the current implementation, we once convert the entire source code to the newly allocated
+        UTF-8 string and pass it to the SHA1 processing. However, this is memory consuming.
+        Ideally, we should stream the decoded bytes into the SHA1 processing iteratively.
+        We'll implement it in the separate patch[2].
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=144339
+        [2]: https://bugs.webkit.org/show_bug.cgi?id=144263
+
+        * tests/stress/eval-script-contains-null-character.js: Added.
+        (shouldBe):
+        (test):
+        * tests/stress/template-literal-line-terminators.js:
+        * tests/stress/template-literal-syntax.js:
+        * tests/stress/template-literal.js:
+
+2015-04-29  Filip Pizlo  <fpizlo@apple.com>
+
+        Evict IsEnvironmentRecord from inline type flags
+        https://bugs.webkit.org/show_bug.cgi?id=144398
+
+        Reviewed by Mark Lam and Michael Saboff.
+        
+        In https://bugs.webkit.org/show_bug.cgi?id=144397, we'll need an extra bit in the inline
+        type flags. This change picks the least important inline type flag - IsEnvironmentRecord -
+        and evicts it into the out-of-line type flags. This change has no performance implications
+        because we never even accessed IsEnvironmentRecord via the StructureIDBlob. The only place
+        where we access it at all is in String.prototype.repeat, and there we already load the
+        structure anyway.
+
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::implementsHasInstance):
+        (JSC::TypeInfo::structureIsImmortal):
+        (JSC::TypeInfo::isEnvironmentRecord):
+
+2015-04-29  Darin Adler  <darin@apple.com>
+
+        [ES6] Implement Unicode code point escapes
+        https://bugs.webkit.org/show_bug.cgi?id=144377
+
+        Reviewed by Antti Koivisto.
+
+        * parser/Lexer.cpp: Moved the UnicodeHexValue class in here from
+        the header. Made it a non-member class so it doesn't need to be part
+        of a template. Made it use UChar32 instead of int for the value to
+        make it clearer what goes into this class.
+        (JSC::ParsedUnicodeEscapeValue::isIncomplete): Added. Replaces the
+        old type() function.
+        (JSC::Lexer<CharacterType>::parseUnicodeEscape): Renamed from
+        parseFourDigitUnicodeHex and added support for code point escapes.
+        (JSC::isLatin1): Added an overload for UChar32.
+        (JSC::isIdentStart): Changed this to take UChar32; no caller tries
+        to call it with a UChar, so no need to overload for that type for now.
+        (JSC::isNonLatin1IdentPart): Changed argument type to UChar32 for clarity.
+        Also added FIXME about a subtle ES6 change that we might want to make later.
+        (JSC::isIdentPart): Changed this to take UChar32; no caller tries
+        to call it with a UChar, so no need to overload for that type for now.
+        (JSC::isIdentPartIncludingEscapeTemplate): Made this a template so that we
+        don't need to repeat the code twice. Added code to handle code point escapes.
+        (JSC::isIdentPartIncludingEscape): Call the template instead of having the
+        code in line.
+        (JSC::Lexer<CharacterType>::recordUnicodeCodePoint): Added.
+        (JSC::Lexer<CharacterType>::parseIdentifierSlowCase): Made small tweaks and
+        updated to call parseUnicodeEscape instead of parseFourDigitUnicodeHex.
+        (JSC::Lexer<CharacterType>::parseComplexEscape): Call parseUnicodeEscape
+        instead of parseFourDigitUnicodeHex. Move the code to handle "\u" before
+        the code that handles the escapes, since the code point escape code now
+        consumes characters while parsing rather than peeking ahead. Test case
+        covers this: Symptom would be that "\u{" would evaluate to "u" instead of
+        giving a syntax error.
+
+        * parser/Lexer.h: Updated for above changes.
+
+        * runtime/StringConstructor.cpp:
+        (JSC::stringFromCodePoint): Use ICU's UCHAR_MAX_VALUE instead of writing
+        out 0x10FFFF; clearer this way.
+
+2015-04-29  Martin Robinson  <mrobinson@igalia.com>
+
+        [CMake] [GTK] Organize and clean up unused CMake variables
+        https://bugs.webkit.org/show_bug.cgi?id=144364
+
+        Reviewed by Gyuyoung Kim.
+
+        * PlatformGTK.cmake: Add variables specific to this project.
+
+2015-04-28  Filip Pizlo  <fpizlo@apple.com>
+
+        TypeOf should return SpecStringIdent and the DFG should know this
+        https://bugs.webkit.org/show_bug.cgi?id=144376
+
+        Reviewed by Andreas Kling.
+        
+        Make TypeOf return atomic strings. That's a simple change in SmallStrings.
+        
+        Make the DFG know this and use it for optimization. This makes Switch(TypeOf) a bit less
+        bad.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setType):
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::setType):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::initialize):
+        * tests/stress/switch-typeof-indirect.js: Added.
+        (bar):
+        (foo):
+        (test):
+        * tests/stress/switch-typeof-slightly-indirect.js: Added.
+        (foo):
+        (test):
+        * tests/stress/switch-typeof.js: Added.
+        (foo):
+        (test):
+
+2015-04-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        REGRESSION(181868): Windows Live SkyDrive cannot open an excel file
+        https://bugs.webkit.org/show_bug.cgi?id=144373
+
+        Reviewed by Darin Adler.
+
+        Revert r181868 as it caused a failure on live.com. We can try
+        re-enabling this exception after we make idl attributes configurable,
+        which may have prevented this particular failure.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+
+2015-04-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Deadlock on applications using JSContext on non-main thread
+        https://bugs.webkit.org/show_bug.cgi?id=144370
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::singleton):
+        Prevent a possible deadlock by assuming we can synchronously
+        run something on the main queue at this time.
+
+2015-04-28  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should fully support Switch (it currently lacks the SwitchString variant)
+        https://bugs.webkit.org/show_bug.cgi?id=144348
+
+        Reviewed by Benjamin Poulain.
+        
+        This adds SwitchString support to the FTL. This is already tested by switch microbenchmarks
+        in LayoutTests/js/regress.
+
+        * dfg/DFGCommon.cpp:
+        (JSC::DFG::stringLessThan):
+        * dfg/DFGCommon.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::StringSwitchCase::operator<): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::StringSwitchCase::operator<):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::switchString):
+        (JSC::FTL::LowerDFGToLLVM::StringSwitchCase::StringSwitchCase):
+        (JSC::FTL::LowerDFGToLLVM::StringSwitchCase::operator<):
+        (JSC::FTL::LowerDFGToLLVM::CharacterCase::CharacterCase):
+        (JSC::FTL::LowerDFGToLLVM::CharacterCase::operator<):
+        (JSC::FTL::LowerDFGToLLVM::switchStringRecurse):
+        (JSC::FTL::LowerDFGToLLVM::switchStringSlow):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        * ftl/FTLOutput.cpp:
+        (JSC::FTL::Output::check):
+        * ftl/FTLOutput.h:
+        * ftl/FTLWeight.h:
+        (JSC::FTL::Weight::inverse):
+        * jit/JITOperations.h:
+
+2015-04-28  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Fully replace ENABLE_LLINT_C_LOOP with ENABLE_JIT
+        https://bugs.webkit.org/show_bug.cgi?id=144304
+
+        Reviewed by Geoffrey Garen.
+
+        * Configurations/FeatureDefines.xcconfig: Define ENABLE_JIT, enabled by default, instead of
+        ENABLE_LLINT_C_LOOP, disabled by default.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL): Check ENABLE_JIT instead of ENABLE_LLINT_C_LOOP.
+
+2015-04-28  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183514.
+        https://bugs.webkit.org/show_bug.cgi?id=144359
+
+        It broke cloop test bots (Requested by mcatanzaro on #webkit).
+
+        Reverted changeset:
+
+        "Fully replace ENABLE_LLINT_C_LOOP with ENABLE_JIT"
+        https://bugs.webkit.org/show_bug.cgi?id=144304
+        http://trac.webkit.org/changeset/183514
+
+2015-04-28  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Fully replace ENABLE_LLINT_C_LOOP with ENABLE_JIT
+        https://bugs.webkit.org/show_bug.cgi?id=144304
+
+        Reviewed by Geoffrey Garen.
+
+        * Configurations/FeatureDefines.xcconfig: Define ENABLE_JIT, enabled by default, instead of
+        ENABLE_LLINT_C_LOOP, disabled by default.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL): Check ENABLE_JIT instead of ENABLE_LLINT_C_LOOP.
+
+2015-04-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix common typo "targetting" => "targeting"
+        https://bugs.webkit.org/show_bug.cgi?id=144349
+
+        Reviewed by Daniel Bates.
+
+        * bytecode/ExecutionCounter.h:
+
+2015-04-28  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Update the features.json for WeakSet, WeakMap, Template literals, Tagged templates
+        https://bugs.webkit.org/show_bug.cgi?id=144328
+
+        Reviewed by Andreas Kling.
+
+        Update the status of ES6 features.
+
+        * features.json:
+
+2015-04-28  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should not use or preserve Phantoms during transformations
+        https://bugs.webkit.org/show_bug.cgi?id=143736
+
+        Reviewed by Geoffrey Garen.
+        
+        Since http://trac.webkit.org/changeset/183207 and http://trac.webkit.org/changeset/183406, it is
+        no longer necessary to preserve Phantoms during transformations. They are still useful just
+        before FixupPhase to support backwards propagation analyses. They are still inserted late in the
+        game in the DFG backend. But transformations don't need to worry about them. Inside a basic
+        block, we can be sure that so long as the IR pinpoints the place where the value becomes
+        available in a bytecode register (using MovHint) and so long as there is a SetLocal anytime some
+        other block would need the value (either for OSR or for DFG execution), then we don't need any
+        liveness markers.
+        
+        So, this removes any places where we inserted Phantoms just for liveness during transformation
+        and it replaces convertToPhantom() with remove(), which just converts the node to a Check. A
+        Check node only keeps its children so long as those children have checks.
+        
+        The fact that we no longer convertToPhantom() means that we have to be more careful when
+        constant-folding GetLocal. Previously we would convertToPhantom() and use the fact that
+        Phantom(Phi) was a valid construct. It's not valid anymore. So, when constant folding encounters
+        a GetLocal it needs to insert a PhantomLocal directly. This allows us to simplify
+        Graph::convertToConstant() a bit. Luckily, none of the other users of this method would see
+        GetLocals.
+        
+        The only Phantom-like cruft left over after this patch is:
+        
+        - Phantoms before FixupPhase. I kind of like these. It means that before FixupPhase, we can do
+          backwards analyses and rely on the fact that the users of a node in DFG IR are a superset of
+          the users of the original local's live range in bytecode. This is essential for supporting our
+          BackwardsPropagationPhase, which is an important optimization for things like asm.js.
+        
+        - PhantomLocals and GetLocals being NodeMustGenerate. See discussion in
+          https://bugs.webkit.org/show_bug.cgi?id=144086. It appears that this is not as evil as the
+          alternatives. The best long-term plan is to simply ditch the ThreadedCPS IR entirely and have
+          the DFG use SSA. For now, so long as any new DFG optimizations we add are block-local and
+          treat GetLocal/SetLocal conservatively, this should all be sound.
+        
+        This change should be perf-neutral although it does reduce the total work that the compiler
+        does.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAdjacencyList.h:
+        (JSC::DFG::AdjacencyList::justChecks):
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::replaceTerminal):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::findTerminal):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+        (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
+        (JSC::DFG::CPSRethreadingPhase::clearVariables):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGCleanUpPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp.
+        (JSC::DFG::CleanUpPhase::CleanUpPhase):
+        (JSC::DFG::CleanUpPhase::run):
+        (JSC::DFG::performCleanUp):
+        (JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase): Deleted.
+        (JSC::DFG::PhantomRemovalPhase::run): Deleted.
+        (JSC::DFG::performPhantomRemoval): Deleted.
+        * dfg/DFGCleanUpPhase.h: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h.
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
+        (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        (JSC::DFG::DCEPhase::fixupBlock):
+        (JSC::DFG::DCEPhase::cleanVariables):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupBlock):
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::convertStringAddUse):
+        (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+        (JSC::DFG::FixupPhase::checkArray):
+        (JSC::DFG::FixupPhase::fixIntConvertingEdge):
+        (JSC::DFG::FixupPhase::fixIntOrBooleanEdge):
+        (JSC::DFG::FixupPhase::fixDoubleOrBooleanEdge):
+        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
+        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        (JSC::DFG::FixupPhase::addRequiredPhantom): Deleted.
+        (JSC::DFG::FixupPhase::addPhantomsIfNecessary): Deleted.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::convertToConstant):
+        (JSC::DFG::Graph::mergeRelevantToOSR): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertCheck):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::attemptHoist):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::remove):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::replaceWith):
+        (JSC::DFG::Node::convertToPhantom): Deleted.
+        (JSC::DFG::Node::convertToCheck): Deleted.
+        (JSC::DFG::Node::willHaveCodeGenOrOSR): Deleted.
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp: Removed.
+        * dfg/DFGPhantomCanonicalizationPhase.h: Removed.
+        * dfg/DFGPhantomRemovalPhase.cpp: Removed.
+        * dfg/DFGPhantomRemovalPhase.h: Removed.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPutStackSinkingPhase.cpp:
+        * dfg/DFGResurrectionForValidationPhase.cpp: Removed.
+        * dfg/DFGResurrectionForValidationPhase.h: Removed.
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+        * dfg/DFGStoreBarrierElisionPhase.cpp:
+        (JSC::DFG::StoreBarrierElisionPhase::elideBarrier):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        (JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateCPS):
+        (JSC::DFG::Validate::validateSSA):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileNoOp):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantom): Deleted.
+
+2015-04-28  Andreas Kling  <akling@apple.com>
+
+        DFG+FTL should generate efficient code for branching on a string's boolean value.
+        <https://webkit.org/b/144317>
+
+        Reviewed by Geoff Garen & Filip Pizlo
+
+        Teach Branch nodes about StringUse and have them generate an efficient zero-length string check
+        instead of dropping out to C++ whenever we branch on a string.
+
+        The FTL JIT already handled Branch nodes with StringUse through its use of boolify(), so only
+        the DFG JIT gets some new codegen logic in this patch.
+
+        Test: js/regress/branch-on-string-as-boolean.js (~4.5x speedup)
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitStringBranch):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+
+2015-04-28  Filip Pizlo  <fpizlo@apple.com>
+
+        VarargsForwardingPhase should only consider MovHints that have the candidate as a child
+        https://bugs.webkit.org/show_bug.cgi?id=144340
+
+        Reviewed by Michael Saboff and Mark Lam.
+        
+        Since we were considering all MovHints, we'd assume that the CreateDirectArguments or
+        CreateClosedArguments node was live so long as any MovHinted bytecode variable was alive.
+        Basically, we'd keep it alive until the end of the block. This maximized the chances of
+        there being an interfering operation, which would prevent elimination.
+        
+        The fix is to only consider MovHints that have the arguments candidate as a child. We only
+        care to track the liveness of those bytecode locals that would need an arguments object
+        recovery on OSR exit.
+        
+        This is a speed-up on V8Spider/raytrace and Octane/raytrace because it undoes the regression
+        introduced in http://trac.webkit.org/changeset/183406.
+
+        * dfg/DFGVarargsForwardingPhase.cpp:
+
+2015-04-28  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove WinCE cruft from cmake build system
+        https://bugs.webkit.org/show_bug.cgi?id=144325
+
+        Reviewed by Gyuyoung Kim.
+
+        * CMakeLists.txt:
+        * create_jit_stubs: Removed.
+
+2015-04-27  Andreas Kling  <akling@apple.com>
+
+        RegExp matches arrays should use contiguous indexing.
+        <https://webkit.org/b/144286>
+
+        Reviewed by Geoffrey Garen.
+
+        We had a custom Structure being used for RegExp matches arrays that would
+        put the arrays into SlowPutArrayStorageShape mode. This was just left
+        from when matches arrays were custom, lazily initialized objects.
+
+        This change removes that Structure and switches the matches arrays to
+        using the default ContiguousShape Structure. This allows the FTL JIT
+        to compile the inner loop of the Octane/regexp benchmark.
+
+        Also made a version of initializeIndex() [inline] that takes the indexing
+        type in an argument, allowing createRegExpMatchesArray() to initialize
+        the entire array without branching on the indexing type for each entry.
+
+        ~3% progression on Octane/regexp.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::mapStructure):
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::initializeIndex):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+
+2015-04-27  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL failed to initialize arguments.callee on the slow path as well as the fast path
+        https://bugs.webkit.org/show_bug.cgi?id=144293
+
+        Reviewed by Mark Lam.
+        
+        The slow path doesn't fully initialize DirectArguments - it leaves callee blank. So, we need
+        to initialize the callee on the common path after the fast and slow path.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
+        * tests/stress/arguments-callee-uninitialized.js: Added.
+        (foo):
+
+2015-04-27  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Add support for typed arrays to the Array profiling
+        https://bugs.webkit.org/show_bug.cgi?id=143913
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds ArrayModes for every typed arrays. Having that information
+        let us generate better GetByVal and PutByVal when the type speculation
+        are not good enough.
+
+        A typical case where this is useful is any basic block for which the type
+        of the object is always more restrictive than the speculation (for example, 
+        a basic block gated by a branch only taken for on type).
+
+        * bytecode/ArrayProfile.cpp:
+        (JSC::dumpArrayModes):
+        * bytecode/ArrayProfile.h:
+        (JSC::arrayModeFromStructure):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::fromObserved):
+        (JSC::DFG::ArrayMode::refine):
+        Maintain the refine() semantic. We do not support OutOfBounds access
+        for GetByVal on typed array.
+
+        * runtime/IndexingType.h:
+        * tests/stress/typed-array-get-by-val-profiling.js: Added.
+        (testArray.testCode):
+        (testArray):
+        * tests/stress/typed-array-put-by-val-profiling.js: Added.
+        (testArray.testCode):
+        (testArray):
+
+2015-04-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out r183438 "RegExp matches arrays should use contiguous indexing". It
+        causes many debug test failures.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure):
+        * runtime/JSObject.h:
+        (JSC::JSObject::initializeIndex):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+
+2015-04-27  Andreas Kling  <akling@apple.com>
+
+        RegExp matches arrays should use contiguous indexing.
+        <https://webkit.org/b/144286>
+
+        Reviewed by Geoffrey Garen.
+
+        We had a custom Structure being used for RegExp matches arrays that would
+        put the arrays into SlowPutArrayStorageShape mode. This was just left
+        from when matches arrays were custom, lazily initialized objects.
+
+        This change removes that Structure and switches the matches arrays to
+        using the default ContiguousShape Structure. This allows the FTL JIT
+        to compile the inner loop of the Octane/regexp benchmark.
+
+        Also made a version of initializeIndex() [inline] that takes the indexing
+        type in an argument, allowing createRegExpMatchesArray() to initialize
+        the entire array without branching on the indexing type for each entry.
+
+        ~3% progression on Octane/regexp.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::mapStructure):
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::initializeIndex):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+
+2015-04-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION (r183373): ASSERT failed in wtf/SHA1.h
+        https://bugs.webkit.org/show_bug.cgi?id=144257
+
+        Temporarily disable skip these tests.
+
+        * tests/stress/template-literal-line-terminators.js:
+        * tests/stress/template-literal-syntax.js:
+        * tests/stress/template-literal.js:
+
+2015-04-27  Basile Clement  <basile_clement@apple.com>
+
+        Function allocations shouldn't sink through Put operations
+        https://bugs.webkit.org/show_bug.cgi?id=144176
+
+        Reviewed by Filip Pizlo.
+
+        By design, we don't support function allocation sinking through any
+        related operation ; however object allocation can sink through PutByOffset et
+        al.
+
+        Currently, the checks to prevent function allocation to sink through
+        these are misguided and do not prevent anything ; function allocation sinking
+        through these operations is prevented as a side effect of requiring an
+        AllocatePropertyStorage through which the function allocation is seen as
+        escaping.
+
+        This changes it so that ObjectAllocationSinkingPhase::handleNode()
+        checks properly that only object allocations sink through related write
+        operations.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+
+2015-04-25  Filip Pizlo  <fpizlo@apple.com>
+
+        VarargsForwardingPhase should use bytecode liveness in addition to other uses to determine the last point that a candidate is used
+        https://bugs.webkit.org/show_bug.cgi?id=143843
+
+        Reviewed by Geoffrey Garen.
+        
+        It will soon come to pass that Phantom isn't available at the time that
+        VarargsForwardingPhase runs. So, it needs to use some other mechanism for discovering when
+        a value dies for OSR.
+        
+        This is simplified by two things:
+        
+        1) The bytecode kill analysis is now reusable. This patch makes it even more reusable than
+           before by polishing the API.
+        
+        2) This phase already operates on one node at a time and allows itself to do a full search
+           of the enclosing basic block for that node. This is fine because CreateDirectArguments
+           and friends is a rarely occurring node. The fact that it operates on one node at a time
+           makes it even easier to reason about OSR liveness - we just track the list of locals in
+           which it is live.
+        
+        This change has no effect right now but it is a necessary prerequisite to implementing
+        https://bugs.webkit.org/show_bug.cgi?id=143736.
+
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::tryAt):
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllKilledOperands):
+        * dfg/DFGPhantomInsertionPhase.cpp:
+        * dfg/DFGVarargsForwardingPhase.cpp:
+
+2015-04-27  Jordan Harband  <ljharb@gmail.com>
+
+        Map#entries and Map#keys error for non-Maps is swapped
+        https://bugs.webkit.org/show_bug.cgi?id=144253
+
+        Reviewed by Simon Fraser.
+
+        Correcting error messages on Set/Map methods when called on
+        incompatible objects.
+
+        * runtime/MapPrototype.cpp:
+        (JSC::mapProtoFuncEntries):
+        (JSC::mapProtoFuncKeys):
+        * runtime/SetPrototype.cpp:
+        (JSC::setProtoFuncEntries):
+
+2015-04-24  Filip Pizlo  <fpizlo@apple.com>
+
+        Rationalize DFG DCE handling of nodes that perform checks that propagate through AI
+        https://bugs.webkit.org/show_bug.cgi?id=144186
+
+        Reviewed by Geoffrey Garen.
+        
+        If I do ArithAdd(Int32Use, Int32Use, CheckOverflow) then AI will prove that this returns
+        Int32. We may later perform code simplifications based on the proof that this is Int32, and
+        we may kill all DFG users of this ArithAdd. Then we may prove that there is no exit site at
+        which the ArithAdd is live. This seems like it is sufficient to then kill the ArithAdd,
+        except that we still need the overflow check!
+
+        Previously we mishandled this:
+
+        - In places where we want the overflow check we need to use MustGenerate(@ArithAdd) as a hack
+          to keep it alive. That's dirty and it's just indicative of a deeper issue.
+
+        - Our MovHint removal doesn't do Phantom canonicalization which essentially makes it
+          powerless. This was sort of hiding the bug.
+
+        - Nodes that have checks that AI leverages should always be NodeMustGenerate. You can't kill
+          something that you are relying on for subsequent simplifications.
+        
+        This fixes MovHint removal to also canonicalize Phantoms. This also adds ModeMustGenerate to
+        nodes that may perform checks that are used by AI to guarantee the result type. As a result,
+        we no longer need the weird MustGenerate node.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
+        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd): Deleted.
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * tests/stress/fold-based-on-int32-proof-mul-branch.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof-mul.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof-or-zero.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof.js: Added.
+        (foo):
+
+2015-04-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Class body ending with a semicolon throws a SyntaxError
+        https://bugs.webkit.org/show_bug.cgi?id=144244
+
+        Reviewed by Darin Adler.
+
+        The bug was caused by parseClass's inner loop for method definitions not moving onto the next iteration
+        it encounters a semicolon. As a result, we always expected a method to appear after a semicolon. Fixed
+        it by continue'ing when it encounters a semicolon.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+
+2015-04-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Getter or setter method named "prototype" or "constrcutor" should throw SyntaxError
+        https://bugs.webkit.org/show_bug.cgi?id=144243
+
+        Reviewed by Darin Adler.
+
+        Fixed the bug by adding explicit checks in parseGetterSetter when we're parsing class methods.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseGetterSetter):
+
+2015-04-26  Jordan Harband  <ljharb@gmail.com>
+
+        Map#forEach does not pass "map" argument to callback.
+        https://bugs.webkit.org/show_bug.cgi?id=144187
+
+        Reviewed by Darin Adler.
+
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-map.prototype.foreach
+        step 7.a.i., the callback should be called with three arguments.
+
+        * runtime/MapPrototype.cpp:
+        (JSC::mapProtoFuncForEach):
+
+2015-04-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement ES6 template literals
+        https://bugs.webkit.org/show_bug.cgi?id=142691
+
+        Reviewed by Darin Adler.
+
+        This patch implements TemplateLiteral.
+        Since TaggedTemplate requires some global states and
+        primitive operations like GetTemplateObject,
+        we separate the patch. It will be implemented in a subsequent patch.
+
+        Template Literal Syntax is guarded by ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX compile time flag.
+        By disabling it, we can disable Template Literal support.
+
+        To implement template literals, in this patch,
+        we newly introduces bytecode op_to_string.
+        In template literals, we alternately evaluate the expression and
+        perform ToString onto the result of evaluation.
+        For example,
+
+        `${f1()} ${f2()}`
+
+        In this template literal, execution order is the following,
+        1. calling f1()
+        2. ToString(the result of f1())
+        3. calling f2()
+        4. ToString(the result of f2())
+
+        op_strcat also performs ToString. However, performing ToString
+        onto expressions are batched in op_strcat, it's not the same to the
+        template literal spec. In the above example,
+        ToString(f1()) should be called before calling f2().
+
+        * Configurations/FeatureDefines.xcconfig:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitToString):
+        (JSC::BytecodeGenerator::emitToNumber): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::TemplateStringNode::emitBytecode):
+        (JSC::TemplateLiteralNode::emitBytecode):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_to_string):
+        (JSC::JIT::emitSlow_op_to_string):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_to_string):
+        (JSC::JIT::emitSlow_op_to_string):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createTemplateString):
+        (JSC::ASTBuilder::createTemplateStringList):
+        (JSC::ASTBuilder::createTemplateExpressionList):
+        (JSC::ASTBuilder::createTemplateLiteral):
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::Lexer<T>::parseIdentifierSlowCase):
+        (JSC::Lexer<T>::parseString):
+        (JSC::LineNumberAdder::LineNumberAdder):
+        (JSC::LineNumberAdder::clear):
+        (JSC::LineNumberAdder::add):
+        (JSC::Lexer<T>::parseTemplateLiteral):
+        (JSC::Lexer<T>::lex):
+        (JSC::Lexer<T>::scanRegExp):
+        (JSC::Lexer<T>::scanTrailingTemplateString):
+        (JSC::Lexer<T>::parseStringSlowCase): Deleted.
+        * parser/Lexer.h:
+        * parser/NodeConstructors.h:
+        (JSC::TemplateExpressionListNode::TemplateExpressionListNode):
+        (JSC::TemplateStringNode::TemplateStringNode):
+        (JSC::TemplateStringListNode::TemplateStringListNode):
+        (JSC::TemplateLiteralNode::TemplateLiteralNode):
+        * parser/Nodes.h:
+        (JSC::TemplateExpressionListNode::value):
+        (JSC::TemplateExpressionListNode::next):
+        (JSC::TemplateStringNode::cooked):
+        (JSC::TemplateStringNode::raw):
+        (JSC::TemplateStringListNode::value):
+        (JSC::TemplateStringListNode::next):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseTemplateString):
+        (JSC::Parser<LexerType>::parseTemplateLiteral):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        * parser/Parser.h:
+        * parser/ParserTokens.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createTemplateString):
+        (JSC::SyntaxChecker::createTemplateStringList):
+        (JSC::SyntaxChecker::createTemplateExpressionList):
+        (JSC::SyntaxChecker::createTemplateLiteral):
+        (JSC::SyntaxChecker::createSpreadExpression): Deleted.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * tests/stress/template-literal-line-terminators.js: Added.
+        (test):
+        (testEval):
+        (testEvalLineNumber):
+        * tests/stress/template-literal-syntax.js: Added.
+        (testSyntax):
+        (testSyntaxError):
+        * tests/stress/template-literal.js: Added.
+        (test):
+        (testEval):
+        (testEmbedded):
+
+2015-04-26  Jordan Harband  <ljharb@gmail.com>
+
+        Set#forEach does not pass "key" or "set" arguments to callback.
+        https://bugs.webkit.org/show_bug.cgi?id=144188
+
+        Reviewed by Darin Adler.
+
+        Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-set.prototype.foreach
+        Set#forEach should pass 3 arguments to the callback.
+
+        * runtime/SetPrototype.cpp:
+        (JSC::setProtoFuncForEach):
+
+2015-04-26  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] Implement Math.clz32(), remove Number.clz()
+        https://bugs.webkit.org/show_bug.cgi?id=144205
+
+        Reviewed by Michael Saboff.
+
+        This patch adds the ES6 function Math.clz32(), and remove the non-standard
+        Number.clz(). Number.clz() probably came from an older draft.
+
+        The new function has a corresponding instrinsic: Clz32Intrinsic,
+        and a corresponding DFG node: ArithClz32, optimized all the way to LLVM.
+
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::countLeadingZeros32):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::bsr_rr):
+        The x86 assembler did not have countLeadingZeros32() because there is
+        no native CLZ instruction on that architecture.
+
+        I have added the version with bsr + branches for the case of zero.
+        An other popular version uses cmov to handle the case of zero. I kept
+        it simple since the Assembler has no support for cmov.
+
+        It is unlikely to matter much. If the code is hot enough, LLVM picks
+        something good based on the surrounding code.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        Constant handling + effect propagation. The node only produces integer (between 0 and 32).
+
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        Thanks to the definition of toUint32(), we can ignore plenty of details
+        from doubles.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithClz32):
+        * dfg/DFGSpeculativeJIT.h:
+        * 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/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithClz32):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::ctlz32):
+        * jit/ThunkGenerators.cpp:
+        (JSC::clz32ThunkGenerator):
+        * jit/ThunkGenerators.h:
+        * runtime/Intrinsic.h:
+        * runtime/MathCommon.h:
+        (JSC::clz32):
+        Fun fact: InstCombine does not recognize this pattern to eliminate
+        the branch which makes our FTL version better than the C version.
+
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+        (JSC::mathProtoFuncClz32):
+        * runtime/NumberPrototype.cpp:
+        (JSC::clz): Deleted.
+        (JSC::numberProtoFuncClz): Deleted.
+        * runtime/VM.cpp:
+        (JSC::thunkGeneratorForIntrinsic):
+        * tests/stress/math-clz32-basics.js: Added.
+        (mathClz32OnInteger):
+        (testMathClz32OnIntegers):
+        (verifyMathClz32OnIntegerWithOtherTypes):
+        (mathClz32OnDouble):
+        (testMathClz32OnDoubles):
+        (verifyMathClz32OnDoublesWithOtherTypes):
+        (mathClz32NoArguments):
+        (mathClz32TooManyArguments):
+        (testMathClz32OnConstants):
+        (mathClz32StructTransition):
+        (Math.clz32):
+
+2015-04-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Array.from need to accept iterables
+        https://bugs.webkit.org/show_bug.cgi?id=141055
+
+        Reviewed by Darin Adler.
+
+        ES6 spec requires that Array.from accepts iterable objects.
+        This patch introduces this functionality, Array.from accepting iterable objects.
+
+        Currently, `isConstructor` is not used. Instead of it, `typeof thiObj === "function"` is used.
+        However, it doesn't conform to the spec. While `isConstructor` queries the given object has `[[Construct]]`,
+        `typeof thisObj === "function"` queries the given object has `[[Call]]`.
+        This will be fixed in the subsequent patch[1].
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=144093
+
+        * builtins/ArrayConstructor.js:
+        (from):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * tests/stress/array-from-with-iterable.js: Added.
+        (shouldBe):
+        (.set for):
+        (.set var):
+        (.get var):
+        (argumentsGenerators):
+        (.set shouldBe):
+        (.set new):
+        * tests/stress/array-from-with-iterator.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (createIterator.iterator.return):
+        (createIterator):
+        (.):
+
+2015-04-25  Jordan Harband  <ljharb@gmail.com>
+
+        Set#keys !== Set#values
+        https://bugs.webkit.org/show_bug.cgi?id=144190
+
+        Reviewed by Darin Adler.
+
+        per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-set.prototype.keys
+        Set#keys should === Set#values
+
+        * runtime/SetPrototype.cpp:
+        (JSC::SetPrototype::finishCreation):
+        (JSC::setProtoFuncValues):
+        (JSC::setProtoFuncEntries):
+        (JSC::setProtoFuncKeys): Deleted.
+
+2015-04-25  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Allow for pausing a JSContext when opening a Web Inspector
+        <rdar://problem/20564788>
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::receivedSetupMessage):
+        * inspector/remote/RemoteInspectorConstants.h:
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        On any incoming setup message, we may want to automatically
+        pause the debuggable. If requested, pause the debuggable
+        after we have setup the frontend connection.
+
+        * runtime/JSGlobalObjectDebuggable.h:
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::pause):
+        Pass through to the inspector controller.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::pause):
+        Enable pause on next statement.
+
+2015-04-23  Ryosuke Niwa  <rniwa@webkit.org>
+
+        class methods should be non-enumerable
+        https://bugs.webkit.org/show_bug.cgi?id=143181
+
+        Reviewed by Darin Adler.
+
+        Fixed the bug by using Object.defineProperty to define methods.
+
+        This patch adds the concept of link time constants and uses it to resolve Object.defineProperty
+        inside CodeBlock's constructor since bytecode can be linked against multiple global objects.
+
+        * bytecode/CodeBlock.cpp: 
+        (JSC::CodeBlock::CodeBlock): Resolve link time constants that are used. Ignore ones with register
+        index of zero.
+        * bytecode/SpecialPointer.h: Added a new enum for link time constants. It currently contains
+        exactly one entry for Object.defineProperty.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::addConstant): Added. Like addConstant that takes JSValue, allocate a new
+        constant register for the link time constant we're adding.
+        (JSC::UnlinkedCodeBlock::registerIndexForLinkTimeConstant): Added.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitMoveLinkTimeConstant): Added. Like addConstantValue, allocate a new
+        register for the specified link time constant and notify UnlinkedCodeBlock about it.
+        (JSC::BytecodeGenerator::emitCallDefineProperty): Added. Create a new property descriptor and call
+        Object.defineProperty with it.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitBytecode): Make static and non-static getters and setters for classes
+        non-enumerable by using emitCallDefineProperty to define them.
+        (JSC::PropertyListNode::emitPutConstantProperty): Ditto for a non-accessor properties.
+        (JSC::ClassExprNode::emitBytecode): Make prototype.constructor non-enumerable and make prototype
+        property on the class non-writable, non-configurable, and non-enumerable by using defineProperty.
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Set m_definePropertyFunction.
+        (JSC::JSGlobalObject::visitChildren): Visit m_definePropertyFunction.
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::definePropertyFunction): Added.
+        (JSC::JSGlobalObject::actualPointerFor): Added a variant that takes LinkTimeConstant.
+        (JSC::JSGlobalObject::jsCellForLinkTimeConstant): Like actualPointerFor, takes LinkTimeConstant and
+        returns a JSCell; e.g. Object.defineProperty.
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::addDefineProperty): Added. Returns Object.defineProperty.
+        * runtime/ObjectConstructor.h:
+
+2015-04-25  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement String.fromCodePoint
+        https://bugs.webkit.org/show_bug.cgi?id=144160
+
+        Reviewed by Darin Adler.
+
+        This patch implements String.fromCodePoint.
+        It accepts multiple code points and generates a string that consists of given code points.
+        The range [0x0000 - 0x10FFFF] is valid for code points.
+        If the given value is out of range, throw a range error.
+
+        When a 0xFFFF <= valid code point is given,
+        String.fromCodePoint generates a string that contains surrogate pairs.
+
+        * runtime/StringConstructor.cpp:
+        (JSC::stringFromCodePoint):
+        (JSC::constructWithStringConstructor):
+        * tests/stress/string-from-code-point.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (toCodePoints):
+        (passThrough):
+
+2015-04-25  Martin Robinson  <mrobinson@igalia.com>
+
+        Rename ENABLE_3D_RENDERING to ENABLE_3D_TRANSFORMS
+        https://bugs.webkit.org/show_bug.cgi?id=144182
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig: Replace all instances of 3D_RENDERING with 3D_TRANSFORMS.
+
+2015-04-25  Mark Lam  <mark.lam@apple.com>
+
+        mayExit() is wrong about Branch nodes with ObjectOrOtherUse: they can exit.
+        https://bugs.webkit.org/show_bug.cgi?id=144152
+
+        Reviewed by Filip Pizlo.
+
+        Changed the EdgeMayExit functor to recognize ObjectUse, ObjectOrOtherUse,
+        StringObjectUse, and StringOrStringObjectUse kinds as potentially triggering
+        OSR exits.  This was overlooked in the original code.
+
+        While only the ObjectOrOtherUse kind is relevant for manifesting this bug with
+        the Branch node, the other 3 may also trigger the same bug for other nodes.
+        To prevent this bug from manifesting with other nodes (and future ones that
+        are yet to be added to mayExits()'s "potential won't exit" set), we fix the
+        EdgeMayExit functor to handle all 4 use kinds (instead of just ObjectOrOtherUse).
+
+        Also added a test to exercise a code path that will trigger this bug with
+        the Branch node before the fix is applied.
+
+        * dfg/DFGMayExit.cpp:
+        * tests/stress/branch-may-exit-due-to-object-or-other-use-kind.js: Added.
+        (inlinedFunction):
+        (foo):
+
+2015-04-24  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183288.
+        https://bugs.webkit.org/show_bug.cgi?id=144189
+
+        Made js/sort-with-side-effecting-comparisons.html time out in
+        debug builds (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "It shouldn't take 1846 lines of code and 5 FIXMEs to sort an
+        array."
+        https://bugs.webkit.org/show_bug.cgi?id=144013
+        http://trac.webkit.org/changeset/183288
+
+2015-04-24  Filip Pizlo  <fpizlo@apple.com>
+
+        CRASH in operationCreateDirectArgumentsDuringExit()
+        https://bugs.webkit.org/show_bug.cgi?id=143962
+
+        Reviewed by Geoffrey Garen.
+        
+        We shouldn't assume that constant-like OSR exit values are always recoverable. They are only
+        recoverable so long as they are live. Therefore, OSR exit should track liveness of
+        constants instead of assuming that they are always live.
+
+        * dfg/DFGGenerationInfo.h:
+        (JSC::DFG::GenerationInfo::noticeOSRBirth):
+        (JSC::DFG::GenerationInfo::appendBirth):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGVariableEvent.cpp:
+        (JSC::DFG::VariableEvent::dump):
+        * dfg/DFGVariableEvent.h:
+        (JSC::DFG::VariableEvent::birth):
+        (JSC::DFG::VariableEvent::id):
+        (JSC::DFG::VariableEvent::dataFormat):
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::VariableEventStream::reconstruct):
+        * tests/stress/phantom-direct-arguments-clobber-argument-count.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/phantom-direct-arguments-clobber-callee.js: Added.
+        (foo):
+        (bar):
+
+2015-04-24  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] When inserting a NaN into a Int32 array, we convert it to DoubleArray then to ContiguousArray
+        https://bugs.webkit.org/show_bug.cgi?id=144169
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertInt32ForValue):
+        DoubleArray do not store NaN, they are used for holes.
+        What happened was:
+        1) We fail to insert the NaN in the Int32 array because it is a double.
+        2) We were converting the array to DoubleArray.
+        3) We were trying to insert the value again. We would fail again because
+           DoubleArray does not store NaN.
+        4) We would convert the DoubleArrayt to Contiguous Array, converting the values
+           to boxed values.
+
+        * tests/stress/int32array-transition-on-nan.js: Added.
+        The behavior is not really observable. This only test nothing crashes in those
+        cases.
+
+        (insertNaNWhileFilling):
+        (testInsertNaNWhileFilling):
+        (insertNaNAfterFilling):
+        (testInsertNaNAfterFilling):
+        (pushNaNWhileFilling):
+        (testPushNaNWhileFilling):
+
+2015-04-21  Geoffrey Garen  <ggaren@apple.com>
+
+        It shouldn't take 1846 lines of code and 5 FIXMEs to sort an array.
+        https://bugs.webkit.org/show_bug.cgi?id=144013
+
+        Reviewed by Mark Lam.
+
+        This patch implements Array.prototype.sort in JavaScript, removing the
+        C++ implementations. It is simpler and less error-prone to express our
+        operations in JavaScript, which provides memory safety, exception safety,
+        and recursion safety.
+
+        The performance result is mixed, but net positive in my opinion. It's
+        difficult to enumerate all the results, since we used to have so many
+        different sorting modes, and there are lots of different data patterns
+        across which you might want to measure sorting. Suffice it to say:
+
+            (*) The benchmarks we track are faster or unchanged.
+
+            (*) Sorting random input using a comparator -- which we think is
+            common -- is 3X faster.
+
+            (*) Sorting random input in a non-array object -- which jQuery does
+            -- is 4X faster.
+
+            (*) Sorting random input in a compact array of integers using a
+            trivial pattern-matchable comparator is 2X *slower*.
+
+        * builtins/Array.prototype.js:
+        (sort.min):
+        (sort.stringComparator):
+        (sort.compactSparse): Special case compaction for sparse arrays because
+        we don't want to hang when sorting new Array(BIG).
+
+        (sort.compact):
+        (sort.merge):
+        (sort.mergeSort): Use merge sort because it's a reasonably efficient
+        stable sort. We have evidence that some sites depend on stable sort,
+        even though the ES6 spec does not mandate it. (See
+        <http://trac.webkit.org/changeset/33967>.)
+
+        This is a textbook implementation of merge sort with three optimizations:
+
+            (1) Use iteration instead of recursion;
+
+            (2) Use array subscripting instead of array copying in order to
+            create logical sub-lists without creating physical sub-lists;
+
+            (3) Swap src and dst at each iteration instead of copying src into
+            dst, and only copy src into the subject array at the end if src is
+            not the subject array.
+
+        (sort.inflate):
+        (sort.comparatorSort):
+        (sort): Sort in JavaScript for the win.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutableInternal): Allow non-private
+        names so we can use helper functions.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::isNumericCompareFunction): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setIsNumericCompareFunction): Deleted.
+        (JSC::UnlinkedCodeBlock::isNumericCompareFunction): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::setIsNumericCompareFunction): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionNode::emitBytecode): We don't do this special casing based
+        on pattern matching anymore. This was mainly an optimization to avoid 
+        the overhead of calling from C++ to JS, which we now avoid by
+        sorting in JS.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::pushTempSortVector): Deleted.
+        (JSC::Heap::popTempSortVector): Deleted.
+        (JSC::Heap::visitTempSortVectors): Deleted.
+        * heap/Heap.h: We don't have temp sort vectors anymore because we sort
+        in JavaScript using a normal JavaScript array for our temporary storage.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner): Allow capturing so we can use
+        helper functions.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::isNumericCompareFunction): Deleted.
+        (JSC::attemptFastSort): Deleted.
+        (JSC::performSlowSort): Deleted.
+        (JSC::arrayProtoFuncSort): Deleted.
+
+        * runtime/CommonIdentifiers.h: New strings used by sort.
+
+        * runtime/JSArray.cpp:
+        (JSC::compareNumbersForQSortWithInt32): Deleted.
+        (JSC::compareNumbersForQSortWithDouble): Deleted.
+        (JSC::compareNumbersForQSort): Deleted.
+        (JSC::compareByStringPairForQSort): Deleted.
+        (JSC::JSArray::sortNumericVector): Deleted.
+        (JSC::JSArray::sortNumeric): Deleted.
+        (JSC::ContiguousTypeAccessor::getAsValue): Deleted.
+        (JSC::ContiguousTypeAccessor::setWithValue): Deleted.
+        (JSC::ContiguousTypeAccessor::replaceDataReference): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::getAsValue): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::setWithValue): Deleted.
+        (JSC::ContiguousTypeAccessor<ArrayWithDouble>::replaceDataReference): Deleted.
+        (JSC::JSArray::sortCompactedVector): Deleted.
+        (JSC::JSArray::sort): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_less): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_less): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_greater): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_greater): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::get_balance_factor): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::set_balance_factor): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_key_node): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::compare_node_node): Deleted.
+        (JSC::AVLTreeAbstractorForArrayCompare::null): Deleted.
+        (JSC::JSArray::sortVector): Deleted.
+        (JSC::JSArray::compactForSorting): Deleted.
+        * runtime/JSArray.h:
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation): Provide some builtins used
+        by sort.
+
+2015-04-24  Matthew Mirman  <mmirman@apple.com>
+
+        Made Object.prototype.__proto__ native getter and setter check that this object not null or undefined
+        https://bugs.webkit.org/show_bug.cgi?id=141865
+        rdar://problem/19927273
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncProtoGetter):
+        (JSC::globalFuncProtoSetter):
+
+2015-04-23  Benjamin Poulain  <bpoulain@apple.com>
+
+        Remove a useless branch on DFGGraph::addShouldSpeculateMachineInt()
+        https://bugs.webkit.org/show_bug.cgi?id=144118
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addShouldSpeculateMachineInt):
+        Both block do the same thing.
+
+2015-04-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Speculative fix for non-main thread auto-attach failures
+        https://bugs.webkit.org/show_bug.cgi?id=144134
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::singleton):
+
+2015-04-23  Basile Clement  <basile_clement@apple.com>
+
+        Allow function allocation sinking
+        https://bugs.webkit.org/show_bug.cgi?id=144016
+
+        Reviewed by Filip Pizlo.
+
+        This adds the ability to sink function allocations in the
+        DFGObjectAllocationSinkingPhase.
+
+        In order to enable this, we add a new PhantomNewFunction node that is
+        used similarily to the PhantomNewObject node, i.e. as a placeholder to replace
+        a sunk NewFunction and keep track of the allocations that have to be performed
+        in case of OSR exit after the sunk allocation but before the real one.
+        The FunctionExecutable and JSLexicalEnvironment (activation) of the function
+        are stored onto the PhantomNewFunction through PutHints in order for them
+        to be recovered on OSR exit.
+
+        Contrary to sunk object allocations, sunk function allocations do not
+        support any kind of operations (e.g. storing into a field) ; any such operation
+        will mark the function allocation as escaping and trigger materialization. As
+        such, function allocations can only be sunk to places where it would have been
+        correct to syntactically move them, and we don't need a special
+        MaterializeNewFunction node to recover possible operations on the function. A
+        sunk NewFunction node will simply create new NewFunction nodes, then replace
+        itself with a PhantomNewFunction node.
+
+        In itself, this change is not expected to have a significant impact on
+        performances other than in degenerate cases (see e.g.
+        JSRegress/sink-function), but it is a step towards being able to sink recursive
+        closures onces we support CreateActivation sinking as well as allocation cycles
+        sinking.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPhantomNewFunction):
+        (JSC::DFG::Node::isPhantomAllocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
+        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * tests/stress/function-sinking-no-double-allocate.js: Added.
+        (call):
+        (.f):
+        (sink):
+        * tests/stress/function-sinking-osrexit.js: Added.
+        (.g):
+        (sink):
+        * tests/stress/function-sinking-put.js: Added.
+        (.g):
+        (sink):
+
+2015-04-23  Basile Clement  <basile_clement@apple.com>
+
+        Make FunctionRareData allocation thread-safe
+        https://bugs.webkit.org/show_bug.cgi?id=144001
+
+        Reviewed by Mark Lam.
+
+        The two things we want to prevent are:
+
+         1. A thread seeing a pointer to a not-yet-fully-created rare data from
+            a JSFunction
+         2. A thread seeing a pointer to a not-yet-fully-created Structure from
+            an ObjectAllocationProfile
+
+        For 1., only the JS thread can be creating the rare data (in
+        runtime/CommonSlowPaths.cpp or in dfg/DFGOperations.cpp), so we don't need to
+        worry about concurrent writes, and we don't need any fences when *reading* the
+        rare data from the JS thread. Thus we only need a storeStoreFence between the
+        rare data creation and assignment to m_rareData in
+        JSFunction::createAndInitializeRareData() to ensure that when the store to
+        m_rareData is issued, the rare data has been properly created.
+
+        For the DFG compilation threads, the only place they can access the
+        rare data is through JSFunction::rareData(), and so we only need a
+        loadLoadFence there to ensure that when we see a non-null pointer in
+        m_rareData, the pointed object will be seen as a fully created
+        FunctionRareData.
+
+
+        For 2., the structure is created in
+        ObjectAllocationProfile::initialize() (which appears to be called only by the
+        JS thread as well, in bytecode/CodeBlock.cpp and on rare data initialization,
+        which always happen in the JS thread), and read through
+        ObjectAllocationProfile::structure() and
+        ObjectAllocationProfile::inlineCapacity(), so following the same reasoning we
+        put a storeStoreFence in ObjectAllocationProfile::initialize() and a
+        loadLoadFence in ObjectAllocationProfile::structure() (and change
+        ObjectAllocationProfile::inlineCapacity() to go through
+        ObjectAllocationProfile::structure()).
+
+        We don't need a fence in ObjectAllocationProfile::clear() because
+        clearing the structure is already as atomic as it gets.
+
+        Finally, notice that we don't care about the ObjectAllocationProfile's
+        m_allocator as that is only used by ObjectAllocationProfile::initialize() and
+        ObjectAllocationProfile::clear() that are always run in the JS thread.
+        ObjectAllocationProfile::isNull() could cause some trouble, but it is
+        currently only used in the ObjectAllocationProfile::clear()'s ASSERT in the JS
+        thread.  Doing isNull()-style pre-checks would be wrong in any other concurrent
+        thread anyway.
+
+        * bytecode/ObjectAllocationProfile.h:
+        (JSC::ObjectAllocationProfile::initialize):
+        (JSC::ObjectAllocationProfile::structure):
+        (JSC::ObjectAllocationProfile::inlineCapacity):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::allocateAndInitializeRareData):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::rareData):
+        (JSC::JSFunction::allocationStructure): Deleted.
+        This is no longer used, as all the accesses to the ObjectAllocationProfile go through the rare data.
+
+2015-04-22  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should insert Phantoms late using BytecodeKills and block-local OSR availability
+        https://bugs.webkit.org/show_bug.cgi?id=143735
+
+        Reviewed by Geoffrey Garen.
+        
+        We've always had bugs arising from the fact that we would MovHint something into a local,
+        and then fail to keep it alive. We would then try to keep things alive by putting Phantoms
+        on those Nodes that were MovHinted. But this became increasingly tricky. Given the
+        sophistication of the transformations we are doing today, this approach is just not sound
+        anymore.
+        
+        This comprehensively fixes these bugs by having the DFG backend automatically insert
+        Phantoms just before codegen based on bytecode liveness. To make this practical, this also
+        makes it much faster to query bytecode liveness.
+        
+        It's about as perf-neutral as it gets for a change that increases compiler work without
+        actually optimizing anything. Later changes will remove the old Phantom-preserving logic,
+        which should then speed us up. I can't really report concrete slow-down numbers because
+        they are low enough to basically be in the noise. For example, a 20-iteration run of
+        SunSpider yields "maybe 0.8% slower", whatever that means.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeLivenessAnalysis.cpp:
+        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
+        * bytecode/FullBytecodeLiveness.h:
+        (JSC::FullBytecodeLiveness::getLiveness):
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::operator+):
+        (JSC::VirtualRegister::operator-):
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllLiveNodesAtTail):
+        (JSC::DFG::forAllKilledOperands):
+        (JSC::DFG::forAllKilledNodesAtNodeIndex):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::isLiveInBytecode):
+        (JSC::DFG::Graph::localsLiveInBytecode):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::forAllLocalsLiveInBytecode):
+        (JSC::DFG::Graph::forAllLiveInBytecode):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGMovHintRemovalPhase.cpp:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPhantomInsertionPhase.cpp: Added.
+        (JSC::DFG::performPhantomInsertion):
+        * dfg/DFGPhantomInsertionPhase.h: Added.
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGScoreBoard.h:
+        (JSC::DFG::ScoreBoard::sortFree):
+        (JSC::DFG::ScoreBoard::assertClear):
+        * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+        (JSC::DFG::VirtualRegisterAllocationPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        * tests/stress/phantom-inadequacy.js: Added.
+        (bar):
+        (baz):
+        (foo):
+
+2015-04-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Rename HardPhantom to MustGenerate.
+
+        Rubber stamped by Geoffrey Garen.
+        
+        We are steadily moving towards Phantom just being a backend hack in the DFG. HardPhantom
+        is more than that; it's a utility for forcing the execution of otherwise killable nodes.
+        NodeMustGenerate is the flag we use to indicate that something isn't killable. So this
+        node should just be called MustGenerate.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2015-04-23  Jordan Harband  <ljharb@gmail.com>
+
+        Implement `Object.assign`
+        https://bugs.webkit.org/show_bug.cgi?id=143980
+
+        Reviewed by Filip Pizlo.
+
+        per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign
+
+        * builtins/ObjectConstructor.js: Added.
+        (assign):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/ObjectConstructor.cpp:
+        * runtime/ObjectConstructor.h:
+
+2015-04-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix debug build.
+
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::performSubstitutionForEdge):
+
+2015-04-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Nodes should have an optional epoch field
+        https://bugs.webkit.org/show_bug.cgi?id=144084
+
+        Reviewed by Ryosuke Niwa and Mark Lam.
+        
+        This makes it easier to do epoch-based analyses on nodes. I plan to do just that in
+        https://bugs.webkit.org/show_bug.cgi?id=143735. Currently the epoch field is not yet
+        used.
+
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGEpoch.h:
+        (JSC::DFG::Epoch::fromUnsigned):
+        (JSC::DFG::Epoch::toUnsigned):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::clearReplacements):
+        (JSC::DFG::Graph::clearEpochs):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::performSubstitutionForEdge):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::Node):
+        (JSC::DFG::Node::replaceWith):
+        (JSC::DFG::Node::replacement):
+        (JSC::DFG::Node::setReplacement):
+        (JSC::DFG::Node::epoch):
+        (JSC::DFG::Node::setEpoch):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+
+2015-04-22  Mark Lam  <mark.lam@apple.com>
+
+        Fix assertion failure and race condition in Options::dumpSourceAtDFGTime().
+        https://bugs.webkit.org/show_bug.cgi?id=143898
+
+        Reviewed by Filip Pizlo.
+
+        CodeBlock::dumpSource() will access SourceCode strings in a way that requires
+        ref'ing of the underlying StringImpls. This is unsafe to do from arbitrary
+        compilation threads because StringImpls are not thread safe. As a result, we get
+        an assertion failure when we run with JSC_dumpSourceAtDFGTime=true on a debug
+        build.
+
+        This patch fixes the issue by only collecting the CodeBlock (and associated info)
+        into a DeferredSourceDump record while compiling, and stashing it away in a
+        deferredSourceDump list in the DeferredCompilationCallback object to be dumped
+        later.
+
+        When compilation is done, the callback object will be notified that
+        compilationDidComplete().  We will dump the SourceCode strings from there. 
+        Since compilationDidComplete() is guaranteed to only be called on the thread
+        doing JS execution, it is safe to access the SourceCode strings there and ref
+        their underlying StringImpls as needed.        
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/DeferredCompilationCallback.cpp:
+        (JSC::DeferredCompilationCallback::compilationDidComplete):
+        (JSC::DeferredCompilationCallback::sourceDumpInfo):
+        (JSC::DeferredCompilationCallback::dumpCompiledSources):
+        * bytecode/DeferredCompilationCallback.h:
+        * bytecode/DeferredSourceDump.cpp: Added.
+        (JSC::DeferredSourceDump::DeferredSourceDump):
+        (JSC::DeferredSourceDump::dump):
+        * bytecode/DeferredSourceDump.h: Added.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+
+2015-04-22  Benjamin Poulain  <benjamin@webkit.org>
+
+        Implement String.codePointAt()
+        https://bugs.webkit.org/show_bug.cgi?id=143934
+
+        Reviewed by Darin Adler.
+
+        This patch adds String.codePointAt() as defined by ES6.
+        I opted for a C++ implementation for now.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        (JSC::codePointAt):
+        (JSC::stringProtoFuncCodePointAt):
+
+2015-04-22  Mark Lam  <mark.lam@apple.com>
+
+        SparseArrayEntry's write barrier owner should be the SparseArrayValueMap.
+        https://bugs.webkit.org/show_bug.cgi?id=144067
+
+        Reviewed by Michael Saboff.
+
+        Currently, there are a few places where the JSObject that owns the
+        SparseArrayValueMap is designated as the owner of the SparseArrayEntry
+        write barrier.  This is a bug and can result in the GC collecting the
+        SparseArrayEntry even though it is being referenced by the
+        SparseArrayValueMap.  This patch fixes the bug.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+        (JSC::JSObject::putIndexedDescriptor):
+        * tests/stress/sparse-array-entry-update-144067.js: Added.
+        (useMemoryToTriggerGCs):
+        (foo):
+
+2015-04-22  Mark Lam  <mark.lam@apple.com>
+
+        Give the heap object iterators the ability to return early.
+        https://bugs.webkit.org/show_bug.cgi?id=144011
+
+        Reviewed by Michael Saboff.
+
+        JSDollarVMPrototype::isValidCell() uses a heap object iterator to validate
+        candidate cell pointers, and, when in use, is called a lot more often than
+        the normal way those iterators are used.  As a result, I see my instrumented
+        VM killed with a SIGXCPU (CPU time limit exceeded).  This patch gives the
+        callback functor the ability to tell the iterators to return early when the
+        functor no longer needs to continue iterating.  With this, my instrumented
+        VM is useful again for debugging.
+
+        Since heap iteration is not something that we do in a typical fast path,
+        I don't expect this to have any noticeable impact on performance.
+
+        I also renamed ObjectAddressCheckFunctor to CellAddressCheckFunctor since
+        it checks JSCell addresses, not just JSObjects.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * debugger/Debugger.cpp:
+        * heap/GCLogging.cpp:
+        (JSC::LoggingFunctor::operator()):
+        * heap/Heap.cpp:
+        (JSC::Zombify::visit):
+        (JSC::Zombify::operator()):
+        * heap/HeapStatistics.cpp:
+        (JSC::StorageStatistics::visit):
+        (JSC::StorageStatistics::operator()):
+        * heap/HeapVerifier.cpp:
+        (JSC::GatherLiveObjFunctor::visit):
+        (JSC::GatherLiveObjFunctor::operator()):
+        * heap/MarkedBlock.cpp:
+        (JSC::SetNewlyAllocatedFunctor::operator()):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::forEachCell):
+        (JSC::MarkedBlock::forEachLiveCell):
+        (JSC::MarkedBlock::forEachDeadCell):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::forEachLiveCell):
+        (JSC::MarkedSpace::forEachDeadCell):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::TypeRecompiler::visit):
+        (Inspector::TypeRecompiler::operator()):
+        * runtime/IterationStatus.h: Added.
+        * runtime/JSGlobalObject.cpp:
+        * runtime/VM.cpp:
+        (JSC::StackPreservingRecompiler::visit):
+        (JSC::StackPreservingRecompiler::operator()):
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::CellAddressCheckFunctor::CellAddressCheckFunctor):
+        (JSC::CellAddressCheckFunctor::operator()):
+        (JSC::JSDollarVMPrototype::isValidCell):
+        (JSC::ObjectAddressCheckFunctor::ObjectAddressCheckFunctor): Deleted.
+        (JSC::ObjectAddressCheckFunctor::operator()): Deleted.
+
+2015-04-22  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [[Set]] should be properly executed in JS builtins
+        https://bugs.webkit.org/show_bug.cgi?id=143996
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, all assignments in builtins JS code is compiled into put_by_val_direct.
+        However,
+
+        1. Some functions (like Array.from) needs [[Set]]. (but it is now compiled into put_by_val_direct, [[DefineOwnProperty]]).
+        2. It's different from the default JS behavior.
+
+        In this patch, we implement the bytecode intrinsic emitting put_by_val_direct and use it explicitly.
+        And dropping the current hack for builtins.
+
+        * builtins/Array.prototype.js:
+        (filter):
+        (map):
+        (find):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPutByVal):
+        * tests/stress/array-fill-put-by-val.js: Added.
+        (shouldThrow):
+        (.set get array):
+        * tests/stress/array-filter-put-by-val-direct.js: Added.
+        (shouldBe):
+        (.set get var):
+        * tests/stress/array-find-does-not-lookup-twice.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (.get shouldBe):
+        * tests/stress/array-from-put-by-val-direct.js: Added.
+        (shouldBe):
+        (.set get var):
+        * tests/stress/array-from-set-length.js: Added.
+        (shouldBe):
+        (ArrayLike):
+        (ArrayLike.prototype.set length):
+        (ArrayLike.prototype.get length):
+        * tests/stress/array-map-put-by-val-direct.js: Added.
+        (shouldBe):
+        (.set get var):
+
+2015-04-22  Basile Clement  <basile_clement@apple.com>
+        Don't de-allocate FunctionRareData
+        https://bugs.webkit.org/show_bug.cgi?id=144000
+
+        Reviewed by Michael Saboff.
+
+        A function rare data (containing most notably its allocation profile) is currently
+        freed and re-allocated each time the function's prototype is cleared.
+        This is not optimal as it means we are invalidating the watchpoint and recompiling the
+        scope each time the prototype is cleared.
+
+        This makes it so that a single rare data is reused, clearing the underlying
+        ObjectAllocationProfile instead of throwing away the whole rare data on
+        .prototype updates.
+
+        * runtime/FunctionRareData.cpp:
+        (JSC::FunctionRareData::create):
+        (JSC::FunctionRareData::finishCreation):
+        * runtime/FunctionRareData.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::allocateAndInitializeRareData):
+        (JSC::JSFunction::initializeRareData):
+
+2015-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix 32-bit. Forgot to make this simple change to 32_64 as well.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2015-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should allow Phantoms after terminals
+        https://bugs.webkit.org/show_bug.cgi?id=126778
+
+        Reviewed by Mark Lam.
+        
+        It's important for us to be able to place liveness-marking nodes after nodes that do
+        things. These liveness-marking nodes are nops. Previously, we disallowed such nodes after
+        terminals. That made things awkward, especially for Switch and Branch, which may do
+        things that necessitate liveness markers (for example they might want to use a converted
+        version of a value rather than the value that was MovHinted). We previously made this
+        work by disallowing certain optimizations on Switch and Branch, which was probably a bad
+        thing.
+        
+        This changes our IR to allow for the terminal to not be the last node in a block. Asking
+        for the terminal involves a search. DFG::validate() checks that the nodes after the
+        terminal are liveness markers that have no effects or checks.
+        
+        This is perf-neutral but will allow more optimizations in the future. It will also make
+        it cleaner to fix https://bugs.webkit.org/show_bug.cgi?id=143735.
+
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::replaceTerminal):
+        * dfg/DFGBasicBlock.h:
+        (JSC::DFG::BasicBlock::findTerminal):
+        (JSC::DFG::BasicBlock::terminal):
+        (JSC::DFG::BasicBlock::insertBeforeTerminal):
+        (JSC::DFG::BasicBlock::numSuccessors):
+        (JSC::DFG::BasicBlock::successor):
+        (JSC::DFG::BasicBlock::successorForCondition):
+        (JSC::DFG::BasicBlock::successors):
+        (JSC::DFG::BasicBlock::last): Deleted.
+        (JSC::DFG::BasicBlock::takeLast): Deleted.
+        (JSC::DFG::BasicBlock::insertBeforeLast): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::SuccessorsIterable): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::iterator): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator*): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator++): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator==): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator!=): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::begin): Deleted.
+        (JSC::DFG::BasicBlock::SuccessorsIterable::end): Deleted.
+        * dfg/DFGBasicBlockInlines.h:
+        (JSC::DFG::BasicBlock::appendNonTerminal):
+        (JSC::DFG::BasicBlock::replaceTerminal):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addToGraph):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::linkBlock):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::run):
+        (JSC::DFG::CFGSimplificationPhase::convertToJump):
+        (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        * dfg/DFGCommon.h:
+        (JSC::DFG::NodeAndIndex::NodeAndIndex):
+        (JSC::DFG::NodeAndIndex::operator!):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupBlock):
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
+        (JSC::DFG::FixupPhase::clearPhantomsAtEnd): Deleted.
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllLiveNodesAtTail):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::terminalsAreValid):
+        (JSC::DFG::Graph::dumpBlockHeader):
+        * dfg/DFGGraph.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeToSuccessors):
+        * dfg/DFGLICMPhase.cpp:
+        (JSC::DFG::LICMPhase::run):
+        (JSC::DFG::LICMPhase::attemptHoist):
+        * dfg/DFGMovHintRemovalPhase.cpp:
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::SuccessorsIterable::SuccessorsIterable):
+        (JSC::DFG::Node::SuccessorsIterable::iterator::iterator):
+        (JSC::DFG::Node::SuccessorsIterable::iterator::operator*):
+        (JSC::DFG::Node::SuccessorsIterable::iterator::operator++):
+        (JSC::DFG::Node::SuccessorsIterable::iterator::operator==):
+        (JSC::DFG::Node::SuccessorsIterable::iterator::operator!=):
+        (JSC::DFG::Node::SuccessorsIterable::begin):
+        (JSC::DFG::Node::SuccessorsIterable::end):
+        (JSC::DFG::Node::successors):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPutStackSinkingPhase.cpp:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStaticExecutionCountEstimationPhase.cpp:
+        (JSC::DFG::StaticExecutionCountEstimationPhase::run):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * tests/stress/closure-call-exit.js: Added.
+        (foo):
+
+2015-04-21  Basile Clement  <basile_clement@apple.com>
+
+        PhantomNewObject should be marked NodeMustGenerate
+        https://bugs.webkit.org/show_bug.cgi?id=143974
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToPhantomNewObject):
+        Was not properly marking NodeMustGenerate when converting.
+
+2015-04-21  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG Call/ConstructForwardVarargs fails to restore the stack pointer
+        https://bugs.webkit.org/show_bug.cgi?id=144007
+
+        Reviewed by Mark Lam.
+        
+        We were conditioning the stack pointer restoration on isVarargs, but we also need to do it
+        if isForwardVarargs.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * tests/stress/varargs-then-slow-call.js: Added.
+        (foo):
+        (bar):
+        (fuzz):
+        (baz):
+
+2015-04-21  Basile Clement  <basile_clement@apple.com>
+
+        Remove AllocationProfileWatchpoint node
+        https://bugs.webkit.org/show_bug.cgi?id=143999
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCellOperand):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::rareData):
+        (JSC::JSFunction::allocationProfileWatchpointSet): Deleted.
+
+2015-04-19  Filip Pizlo  <fpizlo@apple.com>
+
+        MovHint should be a strong use
+        https://bugs.webkit.org/show_bug.cgi?id=143734
+
+        Reviewed by Geoffrey Garen.
+        
+        This disables any DCE that assumes equivalence between DFG IR uses and bytecode uses. Doing
+        so is a major step towards allowing more fancy DFG transformations and also probably fixing
+        some bugs.
+        
+        Just making MovHint a strong use would also completely disable DCE. So we mitigate this by
+        introducing a MovHint removal phase that runs in FTL.
+        
+        This is a slight slowdown on Octane/gbemu, but it's basically neutral on suite averages.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeOrigin.cpp:
+        (JSC::InlineCallFrame::dumpInContext):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::fixupBlock):
+        * dfg/DFGDisassembler.cpp:
+        (JSC::DFG::Disassembler::createDumpList):
+        * dfg/DFGEpoch.cpp: Added.
+        (JSC::DFG::Epoch::dump):
+        * dfg/DFGEpoch.h: Added.
+        (JSC::DFG::Epoch::Epoch):
+        (JSC::DFG::Epoch::first):
+        (JSC::DFG::Epoch::operator!):
+        (JSC::DFG::Epoch::next):
+        (JSC::DFG::Epoch::bump):
+        (JSC::DFG::Epoch::operator==):
+        (JSC::DFG::Epoch::operator!=):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGMovHintRemovalPhase.cpp: Added.
+        (JSC::DFG::performMovHintRemoval):
+        * dfg/DFGMovHintRemovalPhase.h: Added.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/Options.h:
+
+2015-04-21  Basile Clement  <basile_clement@apple.com>
+
+        REGRESSION (r182899): icloud.com crashes
+        https://bugs.webkit.org/show_bug.cgi?id=143960
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::allocationStructure):
+        * tests/stress/dfg-rare-data.js: Added.
+        (F): Regression test
+
+2015-04-21  Michael Saboff  <msaboff@apple.com>
+
+        Crash in JSC::Interpreter::execute
+        https://bugs.webkit.org/show_bug.cgi?id=142625
+
+        Reviewed by Filip Pizlo.
+
+        We need to keep the FunctionExecutables in the code block for the eval flavor of 
+        Interpreter::execute() in order to create the scope used to eval.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettisonFunctionDeclsAndExprs): Deleted.
+        * bytecode/CodeBlock.h:
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::registerFrozenValues):
+
+2015-04-21  Chris Dumez  <cdumez@apple.com>
+
+        Make Vector(const Vector<T, otherCapacity, otherOverflowBehaviour>&) constructor explicit
+        https://bugs.webkit.org/show_bug.cgi?id=143970
+
+        Reviewed by Darin Adler.
+
+        Make Vector(const Vector<T, otherCapacity, otherOverflowBehaviour>&)
+        constructor explicit as it copies the vector and it is easy to call it
+        by mistake.
+
+        * bytecode/UnlinkedInstructionStream.cpp:
+        (JSC::UnlinkedInstructionStream::UnlinkedInstructionStream):
+        * bytecode/UnlinkedInstructionStream.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+
+2015-04-20  Basile Clement  <basile_clement@apple.com>
+
+        PhantomNewObject should be marked NodeMustGenerate
+        https://bugs.webkit.org/show_bug.cgi?id=143974
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGNodeType.h: Mark PhantomNewObject as NodeMustGenerate
+
+2015-04-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Cleanup some StringBuilder use
+        https://bugs.webkit.org/show_bug.cgi?id=143550
+
+        Reviewed by Darin Adler.
+
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::descriptiveString):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::toJSONString):
+        (JSC::StructureShape::propertyHash):
+        (JSC::StructureShape::stringRepresentation):
+        (JSC::StructureShape::toJSONString):
+
+2015-04-20  Mark Lam  <mark.lam@apple.com>
+
+        Add debugging tools to test if a given pointer is a valid object and in the heap.
+        https://bugs.webkit.org/show_bug.cgi?id=143910
+
+        Reviewed by Geoffrey Garen.
+
+        When doing debugging from lldb, sometimes, it is useful to be able to tell if a
+        purported JSObject is really a valid object in the heap or not.  We can add the
+        following utility functions to help:
+            isValidCell(heap, candidate) - returns true if the candidate is a "live" cell in the heap.
+            isInHeap(heap, candidate) - returns true if the candidate is the heap's Object space or Storage space.
+            isInObjectSpace(heap, candidate) - returns true if the candidate is the heap's Object space.
+            isInStorageSpace(heap, candidate) - returns true if the candidate is the heap's Storage space.
+
+        Also moved lldb callable debug utility function prototypes from
+        JSDollarVMPrototype.cpp to JSDollarVMPrototype.h as static members of the
+        JSDollarVMPrototype class.  This is so that we can conveniently #include that
+        file to get the prototypes when we need to call them programmatically from
+        instrumentation that we add while debugging an issue.
+
+        * heap/Heap.h:
+        (JSC::Heap::storageSpace):
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::JSDollarVMPrototype::currentThreadOwnsJSLock):
+        (JSC::ensureCurrentThreadOwnsJSLock):
+        (JSC::JSDollarVMPrototype::gc):
+        (JSC::functionGC):
+        (JSC::JSDollarVMPrototype::edenGC):
+        (JSC::functionEdenGC):
+        (JSC::JSDollarVMPrototype::isInHeap):
+        (JSC::JSDollarVMPrototype::isInObjectSpace):
+        (JSC::JSDollarVMPrototype::isInStorageSpace):
+        (JSC::ObjectAddressCheckFunctor::ObjectAddressCheckFunctor):
+        (JSC::ObjectAddressCheckFunctor::operator()):
+        (JSC::JSDollarVMPrototype::isValidCell):
+        (JSC::JSDollarVMPrototype::isValidCodeBlock):
+        (JSC::JSDollarVMPrototype::codeBlockForFrame):
+        (JSC::functionCodeBlockForFrame):
+        (JSC::codeBlockFromArg):
+        (JSC::JSDollarVMPrototype::printCallFrame):
+        (JSC::JSDollarVMPrototype::printStack):
+        (JSC::JSDollarVMPrototype::printValue):
+        (JSC::currentThreadOwnsJSLock): Deleted.
+        (JSC::gc): Deleted.
+        (JSC::edenGC): Deleted.
+        (JSC::isValidCodeBlock): Deleted.
+        (JSC::codeBlockForFrame): Deleted.
+        (JSC::printCallFrame): Deleted.
+        (JSC::printStack): Deleted.
+        (JSC::printValue): Deleted.
+        * tools/JSDollarVMPrototype.h:
+
+2015-04-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Improve Support for WeakSet in Console
+        https://bugs.webkit.org/show_bug.cgi?id=143951
+
+        Reviewed by Darin Adler.
+
+        * inspector/InjectedScriptSource.js:
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        (Inspector::JSInjectedScriptHost::weakSetSize):
+        (Inspector::JSInjectedScriptHost::weakSetEntries):
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionWeakSetSize):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionWeakSetEntries):
+        Treat WeakSets like special sets.
+
+        * inspector/protocol/Runtime.json:
+        Add a new object subtype, "weakset".
+
+2015-04-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        HashMap storing PropertyKey StringImpl* need to use IdentifierRepHash to handle Symbols
+        https://bugs.webkit.org/show_bug.cgi?id=143947
+
+        Reviewed by Darin Adler.
+
+        Type profiler has map between PropertyKey (StringImpl*) and offset.
+        StringImpl* is also used for Symbol PropertyKey.
+        So equality of hash tables is considered by interned StringImpl*'s pointer value.
+        To do so, use IdentifierRepHash instead of StringHash.
+
+        * runtime/SymbolTable.h:
+
+2015-04-20  Jordan Harband  <ljharb@gmail.com>
+
+        Implement `Object.is`
+        https://bugs.webkit.org/show_bug.cgi?id=143865
+
+        Reviewed by Darin Adler.
+
+        Expose sameValue to JS, via Object.is
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.is
+
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorIs):
+        * runtime/PropertyDescriptor.cpp:
+        (JSC::sameValue):
+
+2015-04-19  Darin Adler  <darin@apple.com>
+
+        Remove all the remaining uses of OwnPtr and PassOwnPtr in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=143941
+
+        Reviewed by Gyuyoung Kim.
+
+        * API/JSCallbackObject.h: Use unique_ptr for m_callbackObjectData.
+        * API/JSCallbackObjectFunctions.h: Ditto.
+
+        * API/ObjCCallbackFunction.h: Use unique_ptr for the arguments to the
+        create function and the constructor and for m_impl.
+        * API/ObjCCallbackFunction.mm:
+        (CallbackArgumentOfClass::CallbackArgumentOfClass): Streamline this
+        class by using RetainPtr<Class>.
+        (ArgumentTypeDelegate::typeInteger): Use make_unique.
+        (ArgumentTypeDelegate::typeDouble): Ditto.
+        (ArgumentTypeDelegate::typeBool): Ditto.
+        (ArgumentTypeDelegate::typeVoid): Ditto.
+        (ArgumentTypeDelegate::typeId): Ditto.
+        (ArgumentTypeDelegate::typeOfClass): Ditto.
+        (ArgumentTypeDelegate::typeBlock): Ditto.
+        (ArgumentTypeDelegate::typeStruct): Ditto.
+        (ResultTypeDelegate::typeInteger): Ditto.
+        (ResultTypeDelegate::typeDouble): Ditto.
+        (ResultTypeDelegate::typeBool): Ditto.
+        (ResultTypeDelegate::typeVoid): Ditto.
+        (ResultTypeDelegate::typeId): Ditto.
+        (ResultTypeDelegate::typeOfClass): Ditto.
+        (ResultTypeDelegate::typeBlock): Ditto.
+        (ResultTypeDelegate::typeStruct): Ditto.
+        (JSC::ObjCCallbackFunctionImpl::ObjCCallbackFunctionImpl): Use
+        unique_ptr for the arguments to the constructor, m_arguments, and m_result.
+        Use RetainPtr<Class> for m_instanceClass.
+        (JSC::objCCallbackFunctionCallAsConstructor): Use nullptr instead of nil or 0
+        for non-Objective-C object pointer null.
+        (JSC::ObjCCallbackFunction::ObjCCallbackFunction): Use unique_ptr for
+        the arguments to the constructor and for m_impl.
+        (JSC::ObjCCallbackFunction::create): Use unique_ptr for arguments.
+        (skipNumber): Mark this static since it's local to this source file.
+        (objCCallbackFunctionForInvocation): Call parseObjCType without doing any
+        explicit adoptPtr since the types in the traits are now unique_ptr. Also use
+        nullptr instead of nil for JSObjectRef values.
+        (objCCallbackFunctionForMethod): Tweaked comment.
+        (objCCallbackFunctionForBlock): Use nullptr instead of 0 for JSObjectRef.
+
+        * bytecode/CallLinkInfo.h: Removed unneeded include of OwnPtr.h.
+
+        * heap/GCThread.cpp:
+        (JSC::GCThread::GCThread): Use unique_ptr.
+        * heap/GCThread.h: Use unique_ptr for arguments to the constructor and for
+        m_slotVisitor and m_copyVisitor.
+        * heap/GCThreadSharedData.cpp:
+        (JSC::GCThreadSharedData::GCThreadSharedData): Ditto.
+
+        * parser/SourceProvider.h: Removed unneeded include of PassOwnPtr.h.
+
+2015-04-19  Benjamin Poulain  <benjamin@webkit.org>
+
+        Improve the feature.json files
+
+        * features.json:
+
+2015-04-19  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Introduce bytecode intrinsics
+        https://bugs.webkit.org/show_bug.cgi?id=143926
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces bytecode level intrinsics into builtins/*.js JS code.
+        When implementing functions in builtins/*.js,
+        sometimes we require lower level functionality.
+
+        For example, in the current Array.from, we use `result[k] = value`.
+        The spec requires `[[DefineOwnProperty]]` operation here.
+        However, usual `result[k] = value` is evaluated as `[[Set]]`. (`PutValue` => `[[Set]]`)
+        So if we implement `Array.prototype[k]` getter/setter, the difference is observable.
+
+        Ideally, reaching here, we would like to use put_by_val_direct bytecode.
+        However, there's no syntax to generate it directly.
+
+        This patch introduces bytecode level intrinsics into JSC BytecodeCompiler.
+        Like @call, @apply, we introduce a new node, Intrinsic.
+        These are generated when calling appropriate private symbols in privileged code.
+        AST parser detects them and generates Intrinsic nodes and
+        BytecodeCompiler detects them and generate required bytecodes.
+
+        Currently, Array.from implementation works fine without this patch.
+        This is because when the target code is builtin JS,
+        BytecodeGenerator emits put_by_val_direct instead of put_by_val.
+        This solves the above issue. However, instead of solving this issue,
+        it raises another issue; There's no way to emit `[[Set]]` operation.
+        `[[Set]]` operation is actually used in the spec (Array.from's "length" is set by `[[Set]]`).
+        So to implement it precisely, introducing bytecode level intrinsics is necessary.
+
+        In the subsequent fixes, we'll remove that special path emitting put_by_val_direct
+        for `result[k] = value` under builtin JS environment. Instead of that special handling,
+        use bytecode intrinsics instead. It solves problems and it is more intuitive
+        because written JS code in builtin works as the same to the usual JS code.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/ArrayConstructor.js:
+        (from):
+        * bytecode/BytecodeIntrinsicRegistry.cpp: Added.
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        (JSC::BytecodeIntrinsicRegistry::lookup):
+        * bytecode/BytecodeIntrinsicRegistry.h: Added.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emitBytecode):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_putByValDirect):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        * parser/NodeConstructors.h:
+        (JSC::BytecodeIntrinsicNode::BytecodeIntrinsicNode):
+        * parser/Nodes.h:
+        (JSC::BytecodeIntrinsicNode::identifier):
+        * runtime/CommonIdentifiers.cpp:
+        (JSC::CommonIdentifiers::CommonIdentifiers):
+        * runtime/CommonIdentifiers.h:
+        (JSC::CommonIdentifiers::bytecodeIntrinsicRegistry):
+        * tests/stress/array-from-with-accessors.js: Added.
+        (shouldBe):
+
+2015-04-19  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Make Builtin functions non constructible
+        https://bugs.webkit.org/show_bug.cgi?id=143923
+
+        Reviewed by Darin Adler.
+
+        Builtin functions defined by builtins/*.js accidentally have [[Construct]].
+        According to the spec, these functions except for explicitly defined as a constructor do not have [[Construct]].
+        This patch fixes it. When the JS function used for a construction is builtin function, throw not a constructor error.
+
+        Ideally, returning ConstructTypeNone in JSFunction::getConstructData is enough.
+        However, to avoid calling getConstructData (it involves indirect call of function pointer of getConstructData), some places do not check ConstructType.
+        In these places, they only check the target function is JSFunction because previously JSFunction always has [[Construct]].
+        So in this patch, we check `isBuiltinFunction()` in those places.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getConstructData):
+        * tests/stress/builtin-function-is-construct-type-none.js: Added.
+        (shouldThrow):
+
+2015-04-19  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement WeakSet
+        https://bugs.webkit.org/show_bug.cgi?id=142408
+
+        Reviewed by Darin Adler.
+
+        This patch implements ES6 WeakSet.
+        Current implementation simply leverages WeakMapData with undefined value.
+        This WeakMapData should be optimized in the same manner as MapData/SetData in the subsequent patch[1].
+
+        And in this patch, we also fix WeakMap/WeakSet behavior to conform the ES6 spec.
+        Except for adders (WeakMap.prototype.set/WeakSet.prototype.add),
+        methods return false (or undefined for WeakMap.prototype.get)
+        when a key is not Object instead of throwing a type error.
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=143919
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSWeakSet.cpp: Added.
+        (JSC::JSWeakSet::finishCreation):
+        (JSC::JSWeakSet::visitChildren):
+        * runtime/JSWeakSet.h: Added.
+        (JSC::JSWeakSet::createStructure):
+        (JSC::JSWeakSet::create):
+        (JSC::JSWeakSet::weakMapData):
+        (JSC::JSWeakSet::JSWeakSet):
+        * runtime/WeakMapPrototype.cpp:
+        (JSC::getWeakMapData):
+        (JSC::protoFuncWeakMapDelete):
+        (JSC::protoFuncWeakMapGet):
+        (JSC::protoFuncWeakMapHas):
+        * runtime/WeakSetConstructor.cpp: Added.
+        (JSC::WeakSetConstructor::finishCreation):
+        (JSC::callWeakSet):
+        (JSC::constructWeakSet):
+        (JSC::WeakSetConstructor::getConstructData):
+        (JSC::WeakSetConstructor::getCallData):
+        * runtime/WeakSetConstructor.h: Added.
+        (JSC::WeakSetConstructor::create):
+        (JSC::WeakSetConstructor::createStructure):
+        (JSC::WeakSetConstructor::WeakSetConstructor):
+        * runtime/WeakSetPrototype.cpp: Added.
+        (JSC::WeakSetPrototype::finishCreation):
+        (JSC::getWeakMapData):
+        (JSC::protoFuncWeakSetDelete):
+        (JSC::protoFuncWeakSetHas):
+        (JSC::protoFuncWeakSetAdd):
+        * runtime/WeakSetPrototype.h: Added.
+        (JSC::WeakSetPrototype::create):
+        (JSC::WeakSetPrototype::createStructure):
+        (JSC::WeakSetPrototype::WeakSetPrototype):
+        * tests/stress/weak-set-constructor-adder.js: Added.
+        (WeakSet.prototype.add):
+        * tests/stress/weak-set-constructor.js: Added.
+
+2015-04-17  Alexey Proskuryakov  <ap@apple.com>
+
+        Remove unused BoundsCheckedPointer
+        https://bugs.webkit.org/show_bug.cgi?id=143896
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/SpeculatedType.cpp: The header was included here.
+
+2015-04-17  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Fix name enumeration of static functions for Symbol constructor
+        https://bugs.webkit.org/show_bug.cgi?id=143891
+
+        Reviewed by Geoffrey Garen.
+
+        Fix missing symbolPrototypeTable registration to the js class object.
+        This patch fixes name enumeration of static functions (Symbol.key, Symbol.keyFor) for Symbol constructor.
+
+        * runtime/SymbolConstructor.cpp:
+
+2015-04-17  Basile Clement  <basile_clement@apple.com>
+
+        Inline JSFunction allocation in DFG
+        https://bugs.webkit.org/show_bug.cgi?id=143858
+
+        Reviewed by Filip Pizlo.
+
+        Followup to my previous patch which inlines JSFunction allocation when
+        using FTL, now also enabled in DFG.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunction):
+
+2015-04-16  Jordan Harband  <ljharb@gmail.com>
+
+        Number.parseInt is not === global parseInt in nightly r182673
+        https://bugs.webkit.org/show_bug.cgi?id=143799
+
+        Reviewed by Darin Adler.
+
+        Ensuring parseInt === Number.parseInt, per spec
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.parseint
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::parseIntFunction):
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation):
+
+2015-04-16  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix CLOOP build after r182927.
+
+        Not reviewed.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::print):
+
+2015-04-16  Basile Clement  <basile_clement@apple.com>
+
+        Inline JSFunction allocation in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=143851
+
+        Reviewed by Filip Pizlo.
+
+        JSFunction allocation is a simple operation that should be inlined when possible.
+
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::allocationSize):
+
+2015-04-16  Mark Lam  <mark.lam@apple.com>
+
+        Add $vm debugging tool.
+        https://bugs.webkit.org/show_bug.cgi?id=143809
+
+        Reviewed by Geoffrey Garen.
+
+        For debugging VM bugs, it would be useful to be able to dump VM data structures
+        from JS code that we instrument.  To this end, let's introduce a
+        JS_enableDollarVM option that, if true, installs an $vm property into each JS
+        global object at creation time.  The $vm property refers to an object that
+        provides a collection of useful utility functions.  For this initial
+        implementation, $vm will have the following:
+
+            crash() - trigger an intentional crash.
+
+            dfgTrue() - returns true if the current function is DFG compiled, else returns false.
+            jitTrue() - returns true if the current function is compiled by the baseline JIT, else returns false.
+            llintTrue() - returns true if the current function is interpreted by the LLINT, else returns false.
+
+            gc() - runs a full GC.
+            edenGC() - runs an eden GC.
+
+            codeBlockForFrame(frameNumber) - gets the codeBlock at the specified frame (0 = current, 1 = caller, etc).
+            printSourceFor(codeBlock) - prints the source code for the codeBlock.
+            printByteCodeFor(codeBlock) - prints the bytecode for the codeBlock.
+
+            print(str) - prints a string to dataLog output.
+            printCallFrame() - prints the current CallFrame.
+            printStack() - prints the JS stack.
+            printInternal(value) - prints the JSC internal info for the specified value.
+
+        With JS_enableDollarVM=true, JS code can use the above functions like so:
+
+            $vm.print("Using $vm features\n");
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printCallOp):
+        - FTL compiled functions don't like it when we try to compute the CallLinkStatus.
+          Hence, we skip this step if we're dumping an FTL codeBlock.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAndSweep):
+        (JSC::Heap::collectAllGarbage): Deleted.
+        * heap/Heap.h:
+        (JSC::Heap::collectAllGarbage):
+        - Add ability to do an Eden collection and sweep.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::printIndents):
+        (JSC::log):
+        (JSC::logF):
+        (JSC::StackVisitor::Frame::print):
+        (JSC::jitTypeName): Deleted.
+        (JSC::printif): Deleted.
+        - Modernize the implementation of StackVisitor::Frame::print(), and remove some
+          now redundant code.
+        - Also fix it so that it downgrades gracefully when encountering inlined DFG
+          and compiled FTL functions.
+
+        (DebugPrintFrameFunctor::DebugPrintFrameFunctor): Deleted.
+        (DebugPrintFrameFunctor::operator()): Deleted.
+        (debugPrintCallFrame): Deleted.
+        (debugPrintStack): Deleted.
+        - these have been moved into JSDollarVMPrototype.cpp. 
+
+        * interpreter/StackVisitor.h:
+        - StackVisitor::Frame::print() is now enabled for release builds as well so that
+          we can call it from $vm.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        - Added the $vm instance to global objects conditional on the JSC_enableDollarVM
+          option.
+
+        * runtime/Options.h:
+        - Added the JSC_enableDollarVM option.
+
+        * tools/JSDollarVM.cpp: Added.
+        * tools/JSDollarVM.h: Added.
+        (JSC::JSDollarVM::createStructure):
+        (JSC::JSDollarVM::create):
+        (JSC::JSDollarVM::JSDollarVM):
+
+        * tools/JSDollarVMPrototype.cpp: Added.
+        - This file contains 2 sets of functions:
+
+          a. a C++ implementation of debugging utility functions that are callable when
+             doing debugging from lldb.  To the extent possible, these functions try to
+             be cautious and not cause unintended crashes should the user call them with
+             the wrong info.  Hence, they are designed to be robust rather than speedy.
+
+          b. the native implementations of JS functions in the $vm object.  Where there
+             is overlapping functionality, these are built on top of the C++ functions
+             above to do the work.
+
+          Note: it does not make sense for all of the $vm functions to have a C++
+          counterpart for lldb debugging.  For example, the $vm.dfgTrue() function is
+          only useful for JS code, and works via the DFG intrinsics mechanism.
+          When doing debugging via lldb, the optimization level of the currently
+          executing JS function can be gotten by dumping the current CallFrame instead.
+
+        (JSC::currentThreadOwnsJSLock):
+        (JSC::ensureCurrentThreadOwnsJSLock):
+        (JSC::JSDollarVMPrototype::addFunction):
+        (JSC::functionCrash): - $vm.crash()
+        (JSC::functionDFGTrue): - $vm.dfgTrue()
+        (JSC::CallerFrameJITTypeFunctor::CallerFrameJITTypeFunctor):
+        (JSC::CallerFrameJITTypeFunctor::operator()):
+        (JSC::CallerFrameJITTypeFunctor::jitType):
+        (JSC::functionLLintTrue): - $vm.llintTrue()
+        (JSC::functionJITTrue): - $vm.jitTrue()
+        (JSC::gc):
+        (JSC::functionGC): - $vm.gc()
+        (JSC::edenGC):
+        (JSC::functionEdenGC): - $vm.edenGC()
+        (JSC::isValidCodeBlock):
+        (JSC::codeBlockForFrame):
+        (JSC::functionCodeBlockForFrame): - $vm.codeBlockForFrame(frameNumber)
+        (JSC::codeBlockFromArg):
+        (JSC::functionPrintSourceFor): - $vm.printSourceFor(codeBlock)
+        (JSC::functionPrintByteCodeFor): - $vm.printBytecodeFor(codeBlock)
+        (JSC::functionPrint): - $vm.print(str)
+        (JSC::PrintFrameFunctor::PrintFrameFunctor):
+        (JSC::PrintFrameFunctor::operator()):
+        (JSC::printCallFrame):
+        (JSC::printStack):
+        (JSC::functionPrintCallFrame): - $vm.printCallFrame()
+        (JSC::functionPrintStack): - $vm.printStack()
+        (JSC::printValue):
+        (JSC::functionPrintValue): - $vm.printValue()
+        (JSC::JSDollarVMPrototype::finishCreation):
+        * tools/JSDollarVMPrototype.h: Added.
+        (JSC::JSDollarVMPrototype::create):
+        (JSC::JSDollarVMPrototype::createStructure):
+        (JSC::JSDollarVMPrototype::JSDollarVMPrototype):
+
+2015-04-16  Geoffrey Garen  <ggaren@apple.com>
+
+        Speculative fix after r182915
+        https://bugs.webkit.org/show_bug.cgi?id=143404
+
+        Reviewed by Alexey Proskuryakov.
+
+        * runtime/SymbolConstructor.h:
+
+2015-04-16  Mark Lam  <mark.lam@apple.com>
+
+        Fixed some typos in a comment.
+
+        Not reviewed.
+
+        * dfg/DFGGenerationInfo.h:
+
+2015-04-16  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement Symbol.for and Symbol.keyFor
+        https://bugs.webkit.org/show_bug.cgi?id=143404
+
+        Reviewed by Geoffrey Garen.
+
+        This patch implements Symbol.for and Symbol.keyFor.
+        SymbolRegistry maintains registered StringImpl* symbols.
+        And to make this mapping enabled over realms,
+        VM owns this mapping (not JSGlobalObject).
+
+        While there's Default AtomicStringTable per thread,
+        SymbolRegistry should not exist over VMs.
+        So everytime VM is created, SymbolRegistry is also created.
+
+        In SymbolRegistry implementation, we don't leverage WeakGCMap (or weak reference design).
+        Theres are several reasons.
+        1. StringImpl* which represents identity of Symbols is not GC-managed object.
+           So we cannot use WeakGCMap directly.
+           While Symbol* is GC-managed object, holding weak reference to Symbol* doesn't maintain JS symbols (exposed primitive values to users) liveness,
+           because distinct Symbol* can exist.
+           Distinct Symbol* means the Symbol* object that pointer value (Symbol*) is different from weakly referenced Symbol* but held StringImpl* is the same.
+
+        2. We don't use WTF::WeakPtr. If we add WeakPtrFactory into StringImpl's member, we can track StringImpl*'s liveness by WeakPtr.
+           However there's problem about when we prune staled entries in SymbolRegistry.
+           Since the memory allocated for the Symbol is typically occupied by allocated symbolized StringImpl*'s content,
+           and it is not in GC-heap.
+           While heavily registering Symbols and storing StringImpl* into SymbolRegistry, Heap's EdenSpace is not so occupied.
+           So GC typically attempt to perform EdenCollection, and it doesn't call WeakGCMap's pruleStaleEntries callback.
+           As a result, before pruning staled entries in SymbolRegistry, fast malloc-ed memory fills up the system memory.
+
+        So instead of using Weak reference, we take relatively easy design.
+        When we register symbolized StringImpl* into SymbolRegistry, symbolized StringImpl* is aware of that.
+        And when destructing it, it removes its reference from SymbolRegistry as if atomic StringImpl do so with AtomicStringTable.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * runtime/SymbolConstructor.cpp:
+        (JSC::SymbolConstructor::getOwnPropertySlot):
+        (JSC::symbolConstructorFor):
+        (JSC::symbolConstructorKeyFor):
+        * runtime/SymbolConstructor.h:
+        * runtime/VM.cpp:
+        * runtime/VM.h:
+        (JSC::VM::symbolRegistry):
+        * tests/stress/symbol-registry.js: Added.
+        (test):
+
+2015-04-16  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Use specific functions for @@iterator functions
+        https://bugs.webkit.org/show_bug.cgi?id=143838
+
+        Reviewed by Geoffrey Garen.
+
+        In ES6, some methods are defined with the different names.
+
+        For example,
+
+        Map.prototype[Symbol.iterator] === Map.prototype.entries
+        Set.prototype[Symbol.iterator] === Set.prototype.values
+        Array.prototype[Symbol.iterator] === Array.prototype.values
+        %Arguments%[Symbol.iterator] === Array.prototype.values
+
+        However, current implementation creates different function objects per name.
+        This patch fixes it by setting the object that is used for the other method to @@iterator.
+        e.g. Setting Array.prototype.values function object to Array.prototype[Symbol.iterator].
+
+        And we drop Arguments' iterator implementation and replace Argument[@@iterator] implementation
+        with Array.prototype.values to conform to the spec.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        (Inspector::JSInjectedScriptHost::iteratorEntries):
+        * runtime/ArgumentsIteratorConstructor.cpp: Removed.
+        * runtime/ArgumentsIteratorConstructor.h: Removed.
+        * runtime/ArgumentsIteratorPrototype.cpp: Removed.
+        * runtime/ArgumentsIteratorPrototype.h: Removed.
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        * runtime/ArrayPrototype.h:
+        * runtime/ClonedArguments.cpp:
+        (JSC::ClonedArguments::getOwnPropertySlot):
+        (JSC::ClonedArguments::put):
+        (JSC::ClonedArguments::deleteProperty):
+        (JSC::ClonedArguments::defineOwnProperty):
+        (JSC::ClonedArguments::materializeSpecials):
+        * runtime/ClonedArguments.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/DirectArguments.cpp:
+        (JSC::DirectArguments::overrideThings):
+        * runtime/GenericArgumentsInlines.h:
+        (JSC::GenericArguments<Type>::getOwnPropertySlot):
+        (JSC::GenericArguments<Type>::getOwnPropertyNames):
+        (JSC::GenericArguments<Type>::put):
+        (JSC::GenericArguments<Type>::deleteProperty):
+        (JSC::GenericArguments<Type>::defineOwnProperty):
+        * runtime/JSArgumentsIterator.cpp: Removed.
+        * runtime/JSArgumentsIterator.h: Removed.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::arrayProtoValuesFunction):
+        * runtime/MapPrototype.cpp:
+        (JSC::MapPrototype::finishCreation):
+        * runtime/ScopedArguments.cpp:
+        (JSC::ScopedArguments::overrideThings):
+        * runtime/SetPrototype.cpp:
+        (JSC::SetPrototype::finishCreation):
+        * tests/stress/arguments-iterator.js: Added.
+        (test):
+        (testArguments):
+        * tests/stress/iterator-functions.js: Added.
+        (test):
+        (argumentsTests):
+
+2015-04-14  Mark Lam  <mark.lam@apple.com>
+
+        Add JSC_functionOverrides=<overrides file> debugging tool.
+        https://bugs.webkit.org/show_bug.cgi?id=143717
+
+        Reviewed by Geoffrey Garen.
+
+        This tool allows us to do runtime replacement of function bodies with alternatives
+        for debugging purposes.  For example, this is useful when we need to debug VM bugs
+        which manifest in scripts executing in webpages downloaded from remote servers
+        that we don't control.  The tool allows us to augment those scripts with logging
+        or test code to help isolate the bugs.
+
+        This tool works by substituting the SourceCode at FunctionExecutable creation
+        time.  It identifies which SourceCode to substitute by comparing the source
+        string against keys in a set of key value pairs.
+
+        The keys are function body strings defined by 'override' clauses in the overrides
+        file specified by in the JSC_functionOverrides option.  The values are function
+        body strings defines by 'with' clauses in the overrides file.
+        See comment blob at top of FunctionOverrides.cpp on the formatting
+        of the overrides file.
+
+        At FunctionExecutable creation time, if the SourceCode string matches one of the
+        'override' keys from the overrides file, the tool will replace the SourceCode with
+        a new one based on the corresponding 'with' value string.  The FunctionExecutable
+        will then be created with the new SourceCode instead.
+
+        Some design decisions:
+        1. We opted to require that the 'with' clause appear on a separate line than the
+           'override' clause because this makes it easier to read and write when the
+           'override' clause's function body is single lined and long.
+
+        2. The user can use any sequence of characters for the delimiter (except for '{',
+           '}' and white space characters) because this ensures that there can always be
+           some delimiter pattern that does not appear in the function body in the clause
+           e.g. in the body of strings in the JS code.
+
+           '{' and '}' are disallowed because they are used to mark the boundaries of the
+           function body string.  White space characters are disallowed because they can
+           be error prone (the user may not be able to tell between spaces and tabs).
+
+        3. The start and end delimiter must be an identical sequence of characters.
+
+           I had considered allowing the use of complementary characters like <>, [], and
+           () for making delimiter pairs like:
+               [[[[ ... ]]]]
+               <[([( ... )])]>
+
+           But in the end, decided against it because:
+           a. These sequences of complementary characters can exists in JS code.
+              In contrast, a repeating delimiter like %%%% is unlikely to appear in JS
+              code.
+           b. It can be error prone for the user to have to type the exact complement
+              character for the end delimiter in reverse order.
+              In contrast, a repeating delimiter like %%%% is much easier to type and
+              less error prone.  Even a sequence like @#$%^ is less error prone than
+              a complementary sequence because it can be copy-pasted, and need not be
+              typed in reverse order.
+           c. It is easier to parse for the same delimiter string for both start and end.
+
+        4. The tool does a lot of checks for syntax errors in the overrides file because
+           we don't want any overrides to fail silently.  If a syntax error is detected,
+           the tool will print an error message and call exit().  This avoids the user
+           wasting time doing debugging only to be surprised later that their specified
+           overrides did not take effect because of some unnoticed typo.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::link):
+        * runtime/Executable.h:
+        * runtime/Options.h:
+        * tools/FunctionOverrides.cpp: Added.
+        (JSC::FunctionOverrides::overrides):
+        (JSC::FunctionOverrides::FunctionOverrides):
+        (JSC::initializeOverrideInfo):
+        (JSC::FunctionOverrides::initializeOverrideFor):
+        (JSC::hasDisallowedCharacters):
+        (JSC::parseClause):
+        (JSC::FunctionOverrides::parseOverridesInFile):
+        * tools/FunctionOverrides.h: Added.
+
+2015-04-16  Basile Clement  <basile_clement@apple.com>
+        Extract the allocation profile from JSFunction into a rare object
+        https://bugs.webkit.org/show_bug.cgi?id=143807
+        Reviewed by Filip Pizlo.
+        The allocation profile is only needed for those functions that are used
+        to create objects with [new].
+        Extracting it into its own JSCell removes the need for JSFunction and
+        JSCallee to be JSDestructibleObjects, which should improve performances in most
+        cases at the cost of an extra pointer dereference when the allocation profile
+        is actually needed.
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_this):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_this):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/FunctionRareData.cpp: Added.
+        (JSC::FunctionRareData::create):
+        (JSC::FunctionRareData::destroy):
+        (JSC::FunctionRareData::createStructure):
+        (JSC::FunctionRareData::visitChildren):
+        (JSC::FunctionRareData::FunctionRareData):
+        (JSC::FunctionRareData::~FunctionRareData):
+        (JSC::FunctionRareData::finishCreation):
+        * runtime/FunctionRareData.h: Added.
+        (JSC::FunctionRareData::offsetOfAllocationProfile):
+        (JSC::FunctionRareData::allocationProfile):
+        (JSC::FunctionRareData::allocationStructure):
+        (JSC::FunctionRareData::allocationProfileWatchpointSet):
+        * runtime/JSBoundFunction.cpp:
+        (JSC::JSBoundFunction::destroy): Deleted.
+        * runtime/JSBoundFunction.h:
+        * runtime/JSCallee.cpp:
+        (JSC::JSCallee::destroy): Deleted.
+        * runtime/JSCallee.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::JSFunction):
+        (JSC::JSFunction::createRareData):
+        (JSC::JSFunction::visitChildren):
+        (JSC::JSFunction::put):
+        (JSC::JSFunction::defineOwnProperty):
+        (JSC::JSFunction::destroy): Deleted.
+        (JSC::JSFunction::createAllocationProfile): Deleted.
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::offsetOfRareData):
+        (JSC::JSFunction::rareData):
+        (JSC::JSFunction::allocationStructure):
+        (JSC::JSFunction::allocationProfileWatchpointSet):
+        (JSC::JSFunction::offsetOfAllocationProfile): Deleted.
+        (JSC::JSFunction::allocationProfile): Deleted.
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::JSFunction):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+2015-04-16  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove the unnecessary WTF_CHANGES define
+        https://bugs.webkit.org/show_bug.cgi?id=143825
+
+        Reviewed by Andreas Kling.
+
+        * config.h:
+
+2015-04-15  Andreas Kling  <akling@apple.com>
+
+        Make MarkedBlock and WeakBlock 4x smaller.
+        <https://webkit.org/b/143802>
+
+        Reviewed by Mark Hahnenberg.
+
+        To reduce GC heap fragmentation and generally use less memory, reduce the size of MarkedBlock
+        and its buddy WeakBlock by 4x, bringing them from 64kB+4kB to 16kB+1kB.
+
+        In a sampling of cool web sites, I'm seeing ~8% average reduction in overall GC heap size.
+        Some examples:
+
+                   apple.com:  6.3MB ->  5.5MB (14.5% smaller)
+                  reddit.com:  4.5MB ->  4.1MB ( 9.7% smaller)
+                 twitter.com: 23.2MB -> 21.4MB ( 8.4% smaller)
+            cuteoverload.com: 24.5MB -> 23.6MB ( 3.8% smaller)
+
+        Benchmarks look mostly neutral.
+        Some small slowdowns on Octane, some slightly bigger speedups on Kraken and SunSpider.
+
+        * heap/MarkedBlock.h:
+        * heap/WeakBlock.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+
+2015-04-15  Jordan Harband  <ljharb@gmail.com>
+
+        String.prototype.startsWith/endsWith/includes have wrong length in r182673
+        https://bugs.webkit.org/show_bug.cgi?id=143659
+
+        Reviewed by Benjamin Poulain.
+
+        Fix lengths of String.prototype.{includes,startsWith,endsWith} per spec
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.includes
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith
+
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+
+2015-04-15  Mark Lam  <mark.lam@apple.com>
+
+        Remove obsolete VMInspector debugging tool.
+        https://bugs.webkit.org/show_bug.cgi?id=143798
+
+        Reviewed by Michael Saboff.
+
+        I added the VMInspector tool 3 years ago to aid in VM hacking work.  Some of it
+        has bit rotted, and now the VM also has better ways to achieve its functionality.
+        Hence this code is now obsolete and should be removed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * interpreter/CallFrame.h:
+        * interpreter/VMInspector.cpp: Removed.
+        * interpreter/VMInspector.h: Removed.
+        * llint/LowLevelInterpreter.cpp:
+
+2015-04-15  Jordan Harband  <ljharb@gmail.com>
+
+        Math.imul has wrong length in Safari 8.0.4
+        https://bugs.webkit.org/show_bug.cgi?id=143658
+
+        Reviewed by Benjamin Poulain.
+
+        Correcting function length from 1, to 2, to match spec
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul
+
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+
+2015-04-15  Jordan Harband  <ljharb@gmail.com>
+
+        Number.parseInt in nightly r182673 has wrong length
+        https://bugs.webkit.org/show_bug.cgi?id=143657
+
+        Reviewed by Benjamin Poulain.
+
+        Correcting function length from 1, to 2, to match spec
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.parseint
+
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation):
+
+2015-04-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Harden DFGForAllKills
+        https://bugs.webkit.org/show_bug.cgi?id=143792
+
+        Reviewed by Geoffrey Garen.
+        
+        Unfortunately, we don't have a good way to test this yet - but it will be needed to prevent
+        bugs in https://bugs.webkit.org/show_bug.cgi?id=143734.
+        
+        Previously ForAllKills used the bytecode kill analysis. That seemed like a good idea because
+        that analysis is cheaper than the full liveness analysis. Unfortunately, it's probably wrong:
+        
+        - It looks for kill sites at forExit origin boundaries. But, something might have been killed
+          by an operation that was logically in between the forExit origins at the boundary, but was
+          removed from the DFG for whatever reason. The DFG is allowed to have bytecode instruction
+          gaps.
+        
+        - It overlooked the fact that a MovHint that addresses a local that is always live kills that
+          local. For example, storing to an argument means that the prior value of the argument is
+          killed.
+        
+        This fixes the analysis by making it handle MovHints directly, and making it define kills in
+        the most conservative way possible: it asks if you were live before but dead after. If we
+        have the compile time budget to afford this more direct approach, then it's definitel a good
+        idea since it's so fool-proof.
+
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGForAllKills.h:
+        (JSC::DFG::forAllKilledOperands):
+        (JSC::DFG::forAllKilledNodesAtNodeIndex):
+        (JSC::DFG::forAllDirectlyKilledOperands): Deleted.
+
+2015-04-15  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Provide SPI to allow changing whether JSContexts are remote debuggable by default
+        https://bugs.webkit.org/show_bug.cgi?id=143681
+
+        Reviewed by Darin Adler.
+
+        * API/JSRemoteInspector.h:
+        * API/JSRemoteInspector.cpp:
+        (JSRemoteInspectorGetInspectionEnabledByDefault):
+        (JSRemoteInspectorSetInspectionEnabledByDefault):
+        Provide SPI to toggle the default enabled inspection state of debuggables.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreateInGroup):
+        Respect the default setting.
+
+2015-04-15  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JavaScriptCore: Use kCFAllocatorDefault where possible
+        https://bugs.webkit.org/show_bug.cgi?id=143747
+
+        Reviewed by Darin Adler.
+
+        * heap/HeapTimer.cpp:
+        (JSC::HeapTimer::HeapTimer):
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorInitializeGlobalQueue):
+        (Inspector::RemoteInspectorDebuggableConnection::setupRunLoop):
+        For consistency and readability use the constant instead of
+        different representations of null.
+
+2015-04-14  Michael Saboff  <msaboff@apple.com>
+
+        Remove JavaScriptCoreUseJIT default from JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=143746
+
+        Reviewed by Mark Lam.
+
+        * runtime/VM.cpp:
+        (JSC::enableAssembler):
+
+2015-04-14  Chris Dumez  <cdumez@apple.com>
+
+        Regression(r180020): Web Inspector crashes on pages that have a stylesheet with an invalid MIME type
+        https://bugs.webkit.org/show_bug.cgi?id=143745
+        <rdar://problem/20243916>
+
+        Reviewed by Joseph Pecoraro.
+
+        Add assertion in ContentSearchUtilities::findMagicComment() to make
+        sure the content String is not null or we would crash in
+        JSC::Yarr::interpret() later.
+
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::findMagicComment):
+
+2015-04-14  Michael Saboff  <msaboff@apple.com>
+
+        DFG register fillSpeculate*() functions should validate incoming spill format is compatible with requested fill format
+        https://bugs.webkit.org/show_bug.cgi?id=143727
+
+        Reviewed by Geoffrey Garen.
+
+        Used the result of AbstractInterpreter<>::filter() to check that the current spill format is compatible
+        with the requested fill format.  If filter() reports a contradiction, then we force an OSR exit.
+        Removed individual checks made redundant by the new check.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+
+2015-04-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Replace JavaScriptCoreOutputConsoleMessagesToSystemConsole default with an SPI
+        https://bugs.webkit.org/show_bug.cgi?id=143691
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSRemoteInspector.h:
+        * API/JSRemoteInspector.cpp:
+        (JSRemoteInspectorSetLogToSystemConsole):
+        Add SPI to enable/disable logging to the system console.
+        This only affects JSContext `console` logs and warnings.
+
+        * inspector/JSGlobalObjectConsoleClient.h:
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        (Inspector::JSGlobalObjectConsoleClient::logToSystemConsole):
+        (Inspector::JSGlobalObjectConsoleClient::setLogToSystemConsole):
+        (Inspector::JSGlobalObjectConsoleClient::messageWithTypeAndLevel):
+        (Inspector::JSGlobalObjectConsoleClient::initializeLogToSystemConsole): Deleted.
+        Simplify access to the setting now that it doesn't need to
+        initialize its value from preferences.
+
+2015-04-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Auto-attach fails after r179562, initialization too late after dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=143682
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::singleton):
+        If we are on the main thread, run the initialization immediately.
+        Otherwise dispatch to the main thread. This way if the first JSContext
+        was created on the main thread it can get auto-attached if applicable.
+
+2015-04-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed build fix for Mavericks.
+
+        Mavericks includes this file but does not enable ENABLE_REMOTE_INSPECTOR
+        so the Inspector namespace is not available when compiling this file.
+
+        * API/JSRemoteInspector.cpp:
+
+2015-04-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Expose private APIs to interact with RemoteInspector instead of going through WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=143729
+
+        Reviewed by Timothy Hatcher.
+
+        * API/JSRemoteInspector.h: Added.
+        * API/JSRemoteInspector.cpp: Added.
+        (JSRemoteInspectorDisableAutoStart):
+        (JSRemoteInspectorStart):
+        (JSRemoteInspectorSetParentProcessInformation):
+        Add the new SPIs for basic remote inspection behavior.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Add the new files to Mac only, since remote inspection is only
+        enabled there anyways.
+
+2015-04-14  Mark Lam  <mark.lam@apple.com>
+
+        Rename JSC_dfgFunctionWhitelistFile to JSC_dfgWhitelist.
+        https://bugs.webkit.org/show_bug.cgi?id=143722
+
+        Reviewed by Michael Saboff.
+
+        Renaming JSC_dfgFunctionWhitelistFile to JSC_dfgWhitelist so that it is
+        shorter, and easier to remember (without having to look it up) and to
+        type.  JSC options now support descriptions, and one can always look up
+        the description if the option's purpose is not already obvious.
+
+        * dfg/DFGFunctionWhitelist.cpp:
+        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
+        (JSC::DFG::FunctionWhitelist::contains):
+        * runtime/Options.h:
+
+2015-04-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix Windows build. Windows doesn't take kindly to private classes that use FAST_ALLOCATED.
+
+        * runtime/InferredValue.h:
+
+2015-04-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix build. I introduced a new cell type at the same time as kling changed how new cell types are written.
+
+        * runtime/InferredValue.h:
+
+2015-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        JSC should detect singleton functions
+        https://bugs.webkit.org/show_bug.cgi?id=143232
+
+        Reviewed by Geoffrey Garen.
+        
+        This started out as an attempt to make constructors faster by detecting when a constructor is a
+        singleton. The idea is that each FunctionExecutable has a VariableWatchpointSet - a watchpoint
+        along with an inferred value - that detects if only one JSFunction has been allocated for that
+        executable, and if so, what that JSFunction is. Then, inside the code for the FunctionExecutable,
+        if the watchpoint set has an inferred value (i.e. it's been initialized and it is still valid),
+        we can constant-fold GetCallee.
+        
+        Unfortunately, constructors don't use GetCallee anymore, so that didn't pan out. But in the
+        process I realized a bunch of things:
+        
+        - This allows us to completely eliminate the GetCallee/GetScope sequence that we still sometimes
+          had even in code where our singleton-closure detection worked. That's because singleton-closure
+          inference worked at the op_resolve_scope, and that op_resolve_scope still needed to keep alive
+          the incoming scope in case we OSR exit. But by constant-folding GetCallee, that sequence
+          disappears. OSR exit can rematerialize the callee or the scope by just knowing their constant
+          values.
+          
+        - Singleton detection should be a reusable thing. So, I got rid of VariableWatchpointSet and
+          created InferredValue. InferredValue is a cell, so it can handle its own GC magic.
+          FunctionExecutable uses an InferredValue to tell you about singleton JSFunctions.
+        
+        - The old singleton-scope detection in op_resolve_scope is better abstracted as a SymbolTable
+          detecting a singleton JSSymbolTableObject. So, SymbolTable uses an InferredValue to tell you
+          about singleton JSSymbolTableObjects. It's curious that we want to have singleton detection in
+          SymbolTable if we already have it in FunctionExecutable. This comes into play in two ways.
+          First, it means that the DFG can realize sooner that a resolve_scope resolves to a constant
+          scope. Ths saves compile times and it allows prediction propagation to benefit from the
+          constant folding. Second, it means that we will detect a singleton scope even if it is
+          referenced from a non-singleton scope that is nearer to us in the scope chain. This refactoring
+          allows us to eliminate the function reentry watchpoint.
+        
+        - This allows us to use a normal WatchpointSet, instead of a VariableWatchpointSet, for inferring
+          constant values in scopes. Previously when the DFG inferred that a closure variable was
+          constant, it wouldn't know which closure that variable was in and so it couldn't just load that
+          value. But now we are first inferring that the function is a singleton, which means that we
+          know exactly what scope it points to, and we can load the value from the scope. Using a
+          WatchpointSet instead of a VariableWatchpointSet saves some memory and simplifies a bunch of
+          code. This also means that now, the only user of VariableWatchpointSet is FunctionExecutable.
+          I've tweaked the code of VariableWatchpointSet to reduce its power to just be what
+          FunctionExecutable wants.
+        
+        This also has the effect of simplifying the implementation of block scoping. Prior to this
+        change, block scoping would have needed to have some story for the function reentry watchpoint on
+        any nested symbol table. That's totally weird to think about; it's not really a function reentry
+        but a scope reentry. Now we don't have to think about this. Constant inference on nested scopes
+        will "just work": if we prove that we know the constant value of the scope then the machinery
+        kicks in, otherwise it doesn't.
+        
+        This is a small Octane and AsmBench speed-up. AsmBench sees 1% while Octane sees sub-1%.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::valueProfileForBytecodeOffset):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::valueProfileForBytecodeOffset): Deleted.
+        * bytecode/CodeOrigin.cpp:
+        (JSC::InlineCallFrame::calleeConstant):
+        (JSC::InlineCallFrame::visitAggregate):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::calleeConstant): Deleted.
+        (JSC::InlineCallFrame::visitAggregate): Deleted.
+        * bytecode/Instruction.h:
+        * bytecode/VariableWatchpointSet.cpp: Removed.
+        * bytecode/VariableWatchpointSet.h: Removed.
+        * bytecode/VariableWatchpointSetInlines.h: Removed.
+        * bytecode/VariableWriteFireDetail.cpp: Added.
+        (JSC::VariableWriteFireDetail::dump):
+        (JSC::VariableWriteFireDetail::touch):
+        * bytecode/VariableWriteFireDetail.h: Added.
+        (JSC::VariableWriteFireDetail::VariableWriteFireDetail):
+        * bytecode/Watchpoint.h:
+        (JSC::WatchpointSet::stateOnJSThread):
+        (JSC::WatchpointSet::startWatching):
+        (JSC::WatchpointSet::fireAll):
+        (JSC::WatchpointSet::touch):
+        (JSC::WatchpointSet::invalidate):
+        (JSC::InlineWatchpointSet::stateOnJSThread):
+        (JSC::InlineWatchpointSet::state):
+        (JSC::InlineWatchpointSet::hasBeenInvalidated):
+        (JSC::InlineWatchpointSet::invalidate):
+        (JSC::InlineWatchpointSet::touch):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::getScope): Deleted.
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDesiredWatchpoints.cpp:
+        (JSC::DFG::InferredValueAdaptor::add):
+        (JSC::DFG::DesiredWatchpoints::addLazily):
+        (JSC::DFG::DesiredWatchpoints::reallyAdd):
+        (JSC::DFG::DesiredWatchpoints::areStillValid):
+        * dfg/DFGDesiredWatchpoints.h:
+        (JSC::DFG::InferredValueAdaptor::hasBeenInvalidated):
+        (JSC::DFG::DesiredWatchpoints::isWatched):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::tryGetConstantClosureVar):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasWatchpointSet):
+        (JSC::DFG::Node::watchpointSet):
+        (JSC::DFG::Node::hasVariableWatchpointSet): Deleted.
+        (JSC::DFG::Node::variableWatchpointSet): Deleted.
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunction):
+        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+        (JSC::DFG::SpeculativeJIT::compileNotifyWrite):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileNotifyWrite):
+        * interpreter/Interpreter.cpp:
+        (JSC::StackFrame::friendlySourceURL):
+        (JSC::StackFrame::friendlyFunctionName):
+        * interpreter/Interpreter.h:
+        (JSC::StackFrame::friendlySourceURL): Deleted.
+        (JSC::StackFrame::friendlyFunctionName): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::emitNotifyWrite):
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_touch_entry): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitPutGlobalVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emitNotifyWrite): Deleted.
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitPutGlobalVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emitNotifyWrite): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+        * runtime/CommonSlowPaths.h:
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::finishCreation):
+        (JSC::FunctionExecutable::visitChildren):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::singletonFunction):
+        * runtime/InferredValue.cpp: Added.
+        (JSC::InferredValue::create):
+        (JSC::InferredValue::destroy):
+        (JSC::InferredValue::createStructure):
+        (JSC::InferredValue::visitChildren):
+        (JSC::InferredValue::InferredValue):
+        (JSC::InferredValue::~InferredValue):
+        (JSC::InferredValue::notifyWriteSlow):
+        (JSC::InferredValue::ValueCleanup::ValueCleanup):
+        (JSC::InferredValue::ValueCleanup::~ValueCleanup):
+        (JSC::InferredValue::ValueCleanup::finalizeUnconditionally):
+        * runtime/InferredValue.h: Added.
+        (JSC::InferredValue::inferredValue):
+        (JSC::InferredValue::state):
+        (JSC::InferredValue::isStillValid):
+        (JSC::InferredValue::hasBeenInvalidated):
+        (JSC::InferredValue::add):
+        (JSC::InferredValue::notifyWrite):
+        (JSC::InferredValue::invalidate):
+        * runtime/JSEnvironmentRecord.cpp:
+        (JSC::JSEnvironmentRecord::visitChildren):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::isValid):
+        (JSC::JSEnvironmentRecord::finishCreation):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::create):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
+        (JSC::JSFunction::createImpl):
+        (JSC::JSFunction::create): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        * runtime/JSScope.h:
+        (JSC::ResolveOp::ResolveOp):
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::finishCreation):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::JSSymbolTableObject):
+        (JSC::JSSymbolTableObject::setSymbolTable):
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/PutPropertySlot.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::prepareToWatch):
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::finishCreation):
+        (JSC::SymbolTable::visitChildren):
+        (JSC::SymbolTableEntry::inferredValue): Deleted.
+        (JSC::SymbolTableEntry::notifyWriteSlow): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::WatchpointCleanup): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::~WatchpointCleanup): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTableEntry::disableWatching):
+        (JSC::SymbolTableEntry::watchpointSet):
+        (JSC::SymbolTable::singletonScope):
+        (JSC::SymbolTableEntry::notifyWrite): Deleted.
+        * runtime/TypeProfiler.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * tests/stress/infer-uninitialized-closure-var.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/singleton-scope-then-overwrite.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/singleton-scope-then-realloc-and-overwrite.js: Added.
+        (foo):
+        * tests/stress/singleton-scope-then-realloc.js: Added.
+        (foo):
+
+2015-04-13  Andreas Kling  <akling@apple.com>
+
+        Don't segregate heap objects based on Structure immortality.
+        <https://webkit.org/b/143638>
+
+        Reviewed by Darin Adler.
+
+        Put all objects that need a destructor call into the same MarkedBlock.
+        This reduces memory consumption in many situations, while improving locality,
+        since much more of the MarkedBlock space can be shared.
+
+        Instead of branching on the MarkedBlock type, we now check a bit in the
+        JSCell's inline type flags (StructureIsImmortal) to see whether it's safe
+        to access the cell's Structure during destruction or not.
+
+        Performance benchmarks look mostly neutral. Maybe a small regression on
+        SunSpider's date objects.
+
+        On the amazon.com landing page, this saves us 50 MarkedBlocks (3200kB) along
+        with a bunch of WeakBlocks that were hanging off of them. That's on the higher
+        end of savings we can get from this, but still a very real improvement.
+
+        Most of this patch is removing the "hasImmortalStructure" constant from JSCell
+        derived classes and passing that responsibility to the StructureIsImmortal flag.
+        StructureFlags is made public so that it's accessible from non-member functions.
+        I made sure to declare it everywhere and make classes final to try to make it
+        explicit what each class is doing to its inherited flags.
+
+        * API/JSCallbackConstructor.h:
+        * API/JSCallbackObject.h:
+        * bytecode/UnlinkedCodeBlock.h:
+        * debugger/DebuggerScope.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMakeRope):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+        * heap/Heap.h:
+        (JSC::Heap::subspaceForObjectDestructor):
+        (JSC::Heap::allocatorForObjectWithDestructor):
+        (JSC::Heap::subspaceForObjectNormalDestructor): Deleted.
+        (JSC::Heap::subspaceForObjectsWithImmortalStructure): Deleted.
+        (JSC::Heap::allocatorForObjectWithNormalDestructor): Deleted.
+        (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): Deleted.
+        * heap/HeapInlines.h:
+        (JSC::Heap::allocateWithDestructor):
+        (JSC::Heap::allocateObjectOfType):
+        (JSC::Heap::subspaceForObjectOfType):
+        (JSC::Heap::allocatorForObjectOfType):
+        (JSC::Heap::allocateWithNormalDestructor): Deleted.
+        (JSC::Heap::allocateWithImmortalStructureDestructor): Deleted.
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateBlock):
+        * heap/MarkedAllocator.h:
+        (JSC::MarkedAllocator::needsDestruction):
+        (JSC::MarkedAllocator::MarkedAllocator):
+        (JSC::MarkedAllocator::init):
+        (JSC::MarkedAllocator::destructorType): Deleted.
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::create):
+        (JSC::MarkedBlock::MarkedBlock):
+        (JSC::MarkedBlock::callDestructor):
+        (JSC::MarkedBlock::specializedSweep):
+        (JSC::MarkedBlock::sweep):
+        (JSC::MarkedBlock::sweepHelper):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::needsDestruction):
+        (JSC::MarkedBlock::destructorType): Deleted.
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::MarkedSpace):
+        (JSC::MarkedSpace::resetAllocators):
+        (JSC::MarkedSpace::forEachAllocator):
+        (JSC::MarkedSpace::isPagedOut):
+        (JSC::MarkedSpace::clearNewlyAllocated):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::subspaceForObjectsWithDestructor):
+        (JSC::MarkedSpace::destructorAllocatorFor):
+        (JSC::MarkedSpace::allocateWithDestructor):
+        (JSC::MarkedSpace::forEachBlock):
+        (JSC::MarkedSpace::subspaceForObjectsWithNormalDestructor): Deleted.
+        (JSC::MarkedSpace::subspaceForObjectsWithImmortalStructure): Deleted.
+        (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): Deleted.
+        (JSC::MarkedSpace::normalDestructorAllocatorFor): Deleted.
+        (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): Deleted.
+        (JSC::MarkedSpace::allocateWithNormalDestructor): Deleted.
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.h:
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.h:
+        * jsc.cpp:
+        * runtime/ArrayBufferNeuteringWatchpoint.h:
+        * runtime/ArrayConstructor.h:
+        * runtime/ArrayIteratorPrototype.h:
+        * runtime/BooleanPrototype.h:
+        * runtime/ClonedArguments.h:
+        * runtime/CustomGetterSetter.h:
+        * runtime/DateConstructor.h:
+        * runtime/DatePrototype.h:
+        * runtime/ErrorPrototype.h:
+        * runtime/ExceptionHelpers.h:
+        * runtime/Executable.h:
+        * runtime/GenericArguments.h:
+        * runtime/GetterSetter.h:
+        * runtime/InternalFunction.h:
+        * runtime/JSAPIValueWrapper.h:
+        * runtime/JSArgumentsIterator.h:
+        * runtime/JSArray.h:
+        * runtime/JSArrayBuffer.h:
+        * runtime/JSArrayBufferView.h:
+        * runtime/JSBoundFunction.h:
+        * runtime/JSCallee.h:
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::classInfo):
+        * runtime/JSDataViewPrototype.h:
+        * runtime/JSEnvironmentRecord.h:
+        * runtime/JSFunction.h:
+        * runtime/JSGenericTypedArrayView.h:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSLexicalEnvironment.h:
+        * runtime/JSNameScope.h:
+        * runtime/JSNotAnObject.h:
+        * runtime/JSONObject.h:
+        * runtime/JSObject.h:
+        (JSC::JSFinalObject::JSFinalObject):
+        * runtime/JSPromiseConstructor.h:
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPromisePrototype.h:
+        * runtime/JSPromiseReaction.h:
+        * runtime/JSPropertyNameEnumerator.h:
+        * runtime/JSProxy.h:
+        * runtime/JSScope.h:
+        * runtime/JSString.h:
+        * runtime/JSSymbolTableObject.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::structureIsImmortal):
+        * runtime/MathObject.h:
+        * runtime/NumberConstructor.h:
+        * runtime/NumberPrototype.h:
+        * runtime/ObjectConstructor.h:
+        * runtime/PropertyMapHashTable.h:
+        * runtime/RegExp.h:
+        * runtime/RegExpConstructor.h:
+        * runtime/RegExpObject.h:
+        * runtime/RegExpPrototype.h:
+        * runtime/ScopedArgumentsTable.h:
+        * runtime/SparseArrayValueMap.h:
+        * runtime/StrictEvalActivation.h:
+        * runtime/StringConstructor.h:
+        * runtime/StringIteratorPrototype.h:
+        * runtime/StringObject.h:
+        * runtime/StringPrototype.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        * runtime/Structure.h:
+        * runtime/StructureChain.h:
+        * runtime/StructureRareData.h:
+        * runtime/Symbol.h:
+        * runtime/SymbolPrototype.h:
+        * runtime/SymbolTable.h:
+        * runtime/WeakMapData.h:
+
+2015-04-13  Mark Lam  <mark.lam@apple.com>
+
+        DFG inlining of op_call_varargs should keep the callee alive in case of OSR exit.
+        https://bugs.webkit.org/show_bug.cgi?id=143407
+
+        Reviewed by Filip Pizlo.
+
+        DFG inlining of a varargs call / construct needs to keep the local
+        containing the callee alive with a Phantom node because the LoadVarargs
+        node may OSR exit.  After the OSR exit, the baseline JIT executes the
+        op_call_varargs with that callee in the local.
+
+        Previously, because that callee local was not explicitly kept alive,
+        the op_call_varargs case can OSR exit a DFG function and leave an
+        undefined value in that local.  As a result, the baseline observes the
+        side effect of an op_call_varargs on an undefined value instead of the
+        function it expected.
+
+        Note: this issue does not manifest with op_construct_varargs because
+        the inlined constructor will have an op_create_this which operates on
+        the incoming callee value, thereby keeping it alive.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        * tests/stress/call-varargs-with-different-arguments-length-after-warmup.js: Added.
+        (foo):
+        (Foo):
+        (doTest):
+
+2015-04-12  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement Array.prototype.values
+        https://bugs.webkit.org/show_bug.cgi?id=143633
+
+        Reviewed by Darin Adler.
+
+        Symbol.unscopables is implemented, so we can implement Array.prototype.values
+        without largely breaking the web. The following script passes.
+
+        var array = [];
+        var values = 42;
+        with (array) {
+            assert(values, 42);
+        }
+
+        * runtime/ArrayPrototype.cpp:
+        * tests/stress/array-iterators-next.js:
+        * tests/stress/map-iterators-next.js:
+        * tests/stress/set-iterators-next.js:
+        * tests/stress/values-unscopables.js: Added.
+        (test):
+
+2015-04-11  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Run flaky conservative GC related test first before polluting stack and registers
+        https://bugs.webkit.org/show_bug.cgi?id=143634
+
+        Reviewed by Ryosuke Niwa.
+
+        After r182653, JSC API tests fail. However, it's not related to the change.
+        After investigating the cause of this failure, I've found that the failed test is flaky
+        because JSC's GC is conservative. If previously allocated JSGlobalObject is accidentally alive
+        due to conservative roots in C stack and registers, this test fails.
+
+        Since GC marks C stack and registers as roots conservatively,
+        objects not referenced logically can be accidentally marked and alive.
+        To avoid this situation as possible as we can,
+        1. run this test first before stack is polluted,
+        2. extract this test as a function to suppress stack height.
+
+        * API/tests/testapi.mm:
+        (testWeakValue):
+        (testObjectiveCAPIMain):
+        (testObjectiveCAPI):
+
+2015-04-11  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: create content view and details sidebar for Frames timeline
+        https://bugs.webkit.org/show_bug.cgi?id=143533
+
+        Reviewed by Timothy Hatcher.
+
+        Refactoring: RunLoop prefix changed to RenderingFrame.
+
+        * inspector/protocol/Timeline.json:
+
+2015-04-11  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Enable Symbol in web pages
+        https://bugs.webkit.org/show_bug.cgi?id=143375
+
+        Reviewed by Ryosuke Niwa.
+
+        Expose Symbol to web pages.
+        Symbol was exposed, but it was hidden since it breaks Facebook comments.
+        This is because at that time Symbol is implemented,
+        but methods for Symbol.iterator and Object.getOwnPropertySymbols are not implemented yet
+        and it breaks React.js and immutable.js.
+
+        Now methods for Symbol.iterator and Object.getOwnPropertySymbols are implemented
+        and make sure that Facebook comment input functionality is not broken with exposed Symbol.
+
+        So this patch replaces runtime flags SymbolEnabled to SymbolDisabled
+        and makes enabling symbols by default.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation):
+        * runtime/RuntimeFlags.h:
+
+2015-04-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        ES6: Iterator toString names should be consistent
+        https://bugs.webkit.org/show_bug.cgi?id=142424
+
+        Reviewed by Geoffrey Garen.
+
+        Iterator Object Names in the spec right now have spaces.
+        In our implementation some do and some don't.
+        This patch aligns JSC to the spec.
+
+        * runtime/JSArrayIterator.cpp:
+        * runtime/JSStringIterator.cpp:
+        * tests/stress/iterator-names.js: Added.
+        (test):
+        (iter):
+        (check):
+
+2015-04-10  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (182567): regress/script-tests/sorting-benchmark.js fails on 32 bit dfg-eager tests
+        https://bugs.webkit.org/show_bug.cgi?id=143582
+
+        Reviewed by Mark Lam.
+
+        For 32 bit builds, we favor spilling unboxed values.  The ASSERT at the root of this bug doesn't
+        fire for 64 bit builds, because we spill an "Other" value as a full JS value (DataFormatJS).
+        For 32 bit builds however, if we are able, we spill Other values as JSCell* (DataFormatCell).
+        The fix is to add a check in fillSpeculateInt32Internal() before the ASSERT that always OSR exits
+        if the spillFormat is DataFormatCell.  Had we spilled in DataFormatJS and the value was a JSCell*,
+        we would still OSR exit after the speculation check.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Fixed an error in a comment while debugging.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
+
+2015-04-10  Milan Crha  <mcrha@redhat.com>
+
+        Disable Linux-specific code in a Windows build
+        https://bugs.webkit.org/show_bug.cgi?id=137973
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::appendAPIBacktrace):
+
+2015-04-10  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Fix calleeSaveRegisters() on non iOS platforms after r180516
+        https://bugs.webkit.org/show_bug.cgi?id=143368
+
+        Reviewed by Michael Saboff.
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::calleeSaveRegisters):
+
+2015-04-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Use jsNontrivialString in more places if the string is guaranteed to be 2 or more characters
+        https://bugs.webkit.org/show_bug.cgi?id=143430
+
+        Reviewed by Darin Adler.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::errorDescriptionForValue):
+        * runtime/NumberPrototype.cpp:
+        (JSC::numberProtoFuncToExponential):
+        (JSC::numberProtoFuncToPrecision):
+        (JSC::numberProtoFuncToString):
+        * runtime/SymbolPrototype.cpp:
+        (JSC::symbolProtoFuncToString):
+
+2015-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        JSArray::sortNumeric should handle ArrayWithUndecided
+        https://bugs.webkit.org/show_bug.cgi?id=143535
+
+        Reviewed by Geoffrey Garen.
+        
+        ArrayWithUndecided is what you get if you haven't stored anything into the array yet. We need to handle it.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::sortNumeric):
+        * tests/stress/sort-array-with-undecided.js: Added.
+
+2015-04-08  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::IntegerCheckCombiningPhase's wrap-around check shouldn't trigger C++ undef behavior on wrap-around
+        https://bugs.webkit.org/show_bug.cgi?id=143532
+
+        Reviewed by Gavin Barraclough.
+        
+        Oh the irony!  We were protecting an optimization that only worked if there was no wrap-around in JavaScript.
+        But the C++ code had wrap-around, which is undef in C++.  So, if the compiler was smart enough, our compiler
+        would think that there never was wrap-around.
+        
+        This fixes a failure in stress/tricky-array-boiunds-checks.js when JSC is compiled with bleeding-edge clang.
+
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::isValid):
+
+2015-04-07  Michael Saboff  <msaboff@apple.com>
+
+        Lazily initialize LogToSystemConsole flag to reduce memory usage
+        https://bugs.webkit.org/show_bug.cgi?id=143506
+
+        Reviewed by Mark Lam.
+
+        Only call into CF preferences code when we need to in order to reduce memory usage.
+
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        (Inspector::JSGlobalObjectConsoleClient::logToSystemConsole):
+        (Inspector::JSGlobalObjectConsoleClient::setLogToSystemConsole):
+        (Inspector::JSGlobalObjectConsoleClient::initializeLogToSystemConsole):
+        (Inspector::JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient):
+
+2015-04-07  Benjamin Poulain  <benjamin@webkit.org>
+
+        Get the features.json files ready for open contributions
+        https://bugs.webkit.org/show_bug.cgi?id=143436
+
+        Reviewed by Darin Adler.
+
+        * features.json:
+
+2015-04-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Constant folding of typed array properties should be handled by AI rather than strength reduction
+        https://bugs.webkit.org/show_bug.cgi?id=143496
+
+        Reviewed by Geoffrey Garen.
+        
+        Handling constant folding in AI is better because it precludes us from having to fixpoint the CFA
+        phase and whatever other phase did the folding in order to find all constants.
+        
+        This also removes the TypedArrayWatchpoint node type because we can just set the watchpoint
+        directly.
+        
+        This also fixes a bug in FTL lowering of GetTypedArrayByteOffset. The bug was previously not
+        found because all of the tests for it involved the property getting constant folded. I found that
+        the codegen was bad because an earlier version of the patch broke that constant folding. This
+        adds a new test for that node type, which makes constant folding impossible by allocating a new
+        typed array every type. The lesson here is: if you write a test for something, run the test with
+        full IR dumps to make sure it's actually testing the thing you want it to test.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::tryGetFoldableView):
+        (JSC::DFG::Graph::tryGetFoldableViewForChild1): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasTypedArray): Deleted.
+        (JSC::DFG::Node::typedArray): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant): Deleted.
+        (JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray): Deleted.
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        (JSC::DFG::WatchpointCollectionPhase::addLazily):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetTypedArrayByteOffset):
+        (JSC::FTL::LowerDFGToLLVM::typedArrayLength):
+        * tests/stress/fold-typed-array-properties.js:
+        (foo):
+        * tests/stress/typed-array-byte-offset.js: Added.
+        (foo):
+
+2015-04-07  Matthew Mirman  <mmirman@apple.com>
+
+        Source and stack information should get appended only to native errors
+        and should be added directly after construction rather than when thrown. 
+        This fixes frozen objects being unfrozen when thrown while conforming to 
+        ecma script standard and other browser behavior.
+        rdar://problem/19927293
+        https://bugs.webkit.org/show_bug.cgi?id=141871
+        
+        Reviewed by Geoffrey Garen.
+
+        Appending stack, source, line, and column information to an object whenever that object is thrown 
+        is incorrect because it violates the ecma script standard for the behavior of throw.  Suppose for example
+        that the object being thrown already has one of these properties or is frozen.  Adding the properties 
+        would then violate the frozen contract or overwrite those properties.  Other browsers do not do this,
+        and doing this causes unnecessary performance hits in code with heavy use of the throw construct as
+        a control flow construct rather than just an error reporting mechanism.  
+        
+        Because WebCore adds "native" errors which do not inherit from any JSC native error, 
+        appending the error properties as a seperate call after construction of the error is required 
+        to avoid having to manually truncate the stack and gather local source information due to 
+        the stack being extended by a nested call to construct one of the native jsc error.
+        
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * interpreter/Interpreter.h:
+        * parser/ParserError.h:
+        (JSC::ParserError::toErrorObject):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Error.cpp:
+        (JSC::createError):
+        (JSC::createEvalError):
+        (JSC::createRangeError):
+        (JSC::createReferenceError):
+        (JSC::createSyntaxError):
+        (JSC::createTypeError):
+        (JSC::createNotEnoughArgumentsError):
+        (JSC::createURIError):
+        (JSC::createOutOfMemoryError):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
+        (JSC::addErrorInfoAndGetBytecodeOffset):  Added.
+        (JSC::addErrorInfo): Added special case for appending complete error info 
+        to a newly constructed error object.
+        * runtime/Error.h:
+        * runtime/ErrorConstructor.cpp:
+        (JSC::Interpreter::constructWithErrorConstructor):
+        (JSC::Interpreter::callErrorConstructor):
+        * runtime/ErrorInstance.cpp:
+        (JSC::appendSourceToError): Moved from VM.cpp
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
+        (JSC::addErrorInfoAndGetBytecodeOffset):
+        (JSC::ErrorInstance::finishCreation):
+        * runtime/ErrorInstance.h:
+        (JSC::ErrorInstance::create):
+        * runtime/ErrorPrototype.cpp:
+        (JSC::ErrorPrototype::finishCreation):
+        * runtime/ExceptionFuzz.cpp:
+        (JSC::doExceptionFuzzing):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createError):
+        (JSC::createInvalidFunctionApplyParameterError):
+        (JSC::createInvalidInParameterError):
+        (JSC::createInvalidInstanceofParameterError):
+        (JSC::createNotAConstructorError):
+        (JSC::createNotAFunctionError):
+        (JSC::createNotAnObjectError):
+        (JSC::throwOutOfMemoryError):
+        (JSC::createStackOverflowError): Deleted.
+        (JSC::createOutOfMemoryError): Deleted.
+        * runtime/ExceptionHelpers.h:
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::constructArrayBuffer):
+        * runtime/JSArrayBufferPrototype.cpp:
+        (JSC::arrayBufferProtoFuncSlice):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::create):
+        (JSC::JSGenericTypedArrayView<Adaptor>::createUninitialized):
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::Interpreter::constructWithNativeErrorConstructor):
+        (JSC::Interpreter::callNativeErrorConstructor):
+        * runtime/VM.cpp:
+        (JSC::VM::throwException):
+        (JSC::appendSourceToError): Moved to Error.cpp
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor): Deleted.
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()): Deleted.
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame): Deleted.
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::index): Deleted.
+        * tests/stress/freeze_leek.js: Added.
+
+2015-04-07  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Show Symbol properties on Objects
+        https://bugs.webkit.org/show_bug.cgi?id=141279
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Runtime.json:
+        Give PropertyDescriptor a reference to the Symbol RemoteObject
+        if the property is a symbol property.
+
+        * inspector/InjectedScriptSource.js:
+        Enumerate symbol properties on objects.
+
+2015-04-07  Filip Pizlo  <fpizlo@apple.com>
+
+        Make it possible to enable LLVM FastISel
+        https://bugs.webkit.org/show_bug.cgi?id=143489
+
+        Reviewed by Michael Saboff.
+
+        The decision to enable FastISel is made by Options.h|cpp, but the LLVM library can disable it if it finds that it is built
+        against a version of LLVM that doesn't support it. Thereafter, JSC::enableLLVMFastISel is the flag that tells the system
+        if we should enable it.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * llvm/InitializeLLVM.cpp:
+        (JSC::initializeLLVMImpl):
+        * llvm/InitializeLLVM.h:
+        * llvm/InitializeLLVMLinux.cpp:
+        (JSC::getLLVMInitializerFunction):
+        (JSC::initializeLLVMImpl): Deleted.
+        * llvm/InitializeLLVMMac.cpp:
+        (JSC::getLLVMInitializerFunction):
+        (JSC::initializeLLVMImpl): Deleted.
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::getLLVMInitializerFunctionPOSIX):
+        (JSC::initializeLLVMPOSIX): Deleted.
+        * llvm/InitializeLLVMPOSIX.h:
+        * llvm/InitializeLLVMWin.cpp:
+        (JSC::getLLVMInitializerFunction):
+        (JSC::initializeLLVMImpl): Deleted.
+        * llvm/LLVMAPI.cpp:
+        * llvm/LLVMAPI.h:
+        * llvm/library/LLVMExports.cpp:
+        (initCommandLine):
+        (initializeAndGetJSCLLVMAPI):
+        * runtime/Options.cpp:
+        (JSC::Options::initialize):
+
+2015-04-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
+        https://bugs.webkit.org/show_bug.cgi?id=140426
+
+        Reviewed by Darin Adler.
+
+        In the put_by_val_direct operation, we use JSObject::putDirect.
+        However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
+        This patch checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::putByVal):
+        (JSC::DFG::operationPutByValInternal):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Identifier.h:
+        (JSC::isIndex):
+        (JSC::parseIndex):
+        * tests/stress/dfg-put-by-val-direct-with-edge-numbers.js: Added.
+        (lookupWithKey):
+        (toStringThrowsError.toString):
+
+2015-04-06  Alberto Garcia  <berto@igalia.com>
+
+        [GTK] Fix HPPA build
+        https://bugs.webkit.org/show_bug.cgi?id=143453
+
+        Reviewed by Darin Adler.
+
+        Add HPPA to the list of supported CPUs.
+
+        * CMakeLists.txt:
+
+2015-04-06  Mark Lam  <mark.lam@apple.com>
+
+        In the 64-bit DFG and FTL, Array::Double case for HasIndexedProperty should set its result to true when all is well.
+        <https://webkit.org/b/143396>
+
+        Reviewed by Filip Pizlo.
+
+        The DFG was neglecting to set the result boolean.  The FTL was setting it with
+        an inverted value.  Both of these are now resolved.
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileHasIndexedProperty):
+        * tests/stress/for-in-array-mode.js: Added.
+        (.):
+        (test):
+
+2015-04-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] DFG and FTL should be aware of that StringConstructor behavior for symbols becomes different from ToString
+        https://bugs.webkit.org/show_bug.cgi?id=143424
+
+        Reviewed by Geoffrey Garen.
+
+        In ES6, StringConstructor behavior becomes different from ToString abstract operations in the spec. (and JSValue::toString).
+
+        ToString(symbol) throws a type error.
+        However, String(symbol) produces SymbolDescriptiveString(symbol).
+
+        So, in DFG and FTL phase, they should not inline StringConstructor to ToString.
+
+        Now, in the template literals patch, ToString DFG operation is planned to be used.
+        And current ToString behavior is aligned to the spec (and JSValue::toString) and it's better.
+        So intead of changing ToString behavior, this patch adds CallStringConstructor operation into DFG and FTL.
+        In CallStringConstructor, all behavior in DFG analysis is the same.
+        Only the difference from ToString is, when calling DFG operation functions, it calls
+        operationCallStringConstructorOnCell and operationCallStringConstructor instead of
+        operationToStringOnCell and operationToString.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::fixupToStringOrCallStringConstructor):
+        (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+        (JSC::DFG::FixupPhase::fixupToString): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell):
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileToStringOrCallStringConstructor):
+        (JSC::FTL::LowerDFGToLLVM::compileToString): Deleted.
+        * runtime/StringConstructor.cpp:
+        (JSC::stringConstructor):
+        (JSC::callStringConstructor):
+        * runtime/StringConstructor.h:
+        * tests/stress/symbol-and-string-constructor.js: Added.
+        (performString):
+
+2015-04-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Return Optional<uint32_t> from PropertyName::asIndex
+        https://bugs.webkit.org/show_bug.cgi?id=143422
+
+        Reviewed by Darin Adler.
+
+        PropertyName::asIndex returns uint32_t and use UINT_MAX as NotAnIndex.
+        But it's not obvious to callers.
+
+        This patch changes
+        1. PropertyName::asIndex() to return Optional<uint32_t> and
+        2. function name `asIndex()` to `parseIndex()`.
+        It forces callers to check the value is index or not explicitly.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStubAndGetOldStructure):
+        * jsc.cpp:
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSort):
+        * runtime/GenericArgumentsInlines.h:
+        (JSC::GenericArguments<Type>::getOwnPropertySlot):
+        (JSC::GenericArguments<Type>::put):
+        (JSC::GenericArguments<Type>::deleteProperty):
+        (JSC::GenericArguments<Type>::defineOwnProperty):
+        * runtime/Identifier.h:
+        (JSC::parseIndex):
+        (JSC::Identifier::isSymbol):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::defineOwnProperty):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
+        (JSC::JSGenericTypedArrayView<Adaptor>::put):
+        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
+        (JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC::JSObject::putDirectAccessor):
+        (JSC::JSObject::putDirectCustomAccessor):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::putDirectMayBeIndex):
+        (JSC::JSObject::defineOwnProperty):
+        * runtime/JSObject.h:
+        (JSC::JSObject::getOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+        (JSC::JSObject::putDirectInternal):
+        * runtime/JSString.cpp:
+        (JSC::JSString::getStringPropertyDescriptor):
+        * runtime/JSString.h:
+        (JSC::JSString::getStringPropertySlot):
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::parse):
+        * runtime/PropertyName.h:
+        (JSC::parseIndex):
+        (JSC::toUInt32FromCharacters): Deleted.
+        (JSC::toUInt32FromStringImpl): Deleted.
+        (JSC::PropertyName::asIndex): Deleted.
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::deleteProperty):
+        * runtime/Structure.cpp:
+        (JSC::Structure::prototypeChainMayInterceptStoreTo):
+
+2015-04-05  Andreas Kling  <akling@apple.com>
+
+        URI encoding/escaping should use efficient string building instead of calling snprintf().
+        <https://webkit.org/b/143426>
+
+        Reviewed by Gavin Barraclough.
+
+        I saw 0.5% of main thread time in snprintf() on <http://polymerlabs.github.io/benchmarks/>
+        which seemed pretty silly. This change gets that down to nothing in favor of using our
+        existing JSStringBuilder and HexNumber.h facilities.
+
+        These APIs are well-exercised by our existing test suite.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::encode):
+        (JSC::globalFuncEscape):
+
+2015-04-05  Masataka Yakura  <masataka.yakura@gmail.com>
+
+        documentation for ES Promises points to the wrong one
+        https://bugs.webkit.org/show_bug.cgi?id=143263
+
+        Reviewed by Darin Adler.
+
+        * features.json:
+
+2015-04-05  Simon Fraser  <simon.fraser@apple.com>
+
+        Remove "go ahead and" from comments
+        https://bugs.webkit.org/show_bug.cgi?id=143421
+
+        Reviewed by Darin Adler, Benjamin Poulain.
+
+        Remove the phrase "go ahead and" from comments where it doesn't add
+        anything (which is almost all of them).
+
+        * interpreter/JSStack.cpp:
+        (JSC::JSStack::growSlowCase):
+
+2015-04-04  Andreas Kling  <akling@apple.com>
+
+        Logically empty WeakBlocks should not pin down their MarkedBlocks indefinitely.
+        <https://webkit.org/b/143210>
+
+        Reviewed by Geoffrey Garen.
+
+        Since a MarkedBlock cannot be destroyed until all the WeakBlocks pointing into it are gone,
+        we had a little problem where WeakBlocks with only null pointers would still keep their
+        MarkedBlock alive.
+
+        This patch fixes that by detaching WeakBlocks from their MarkedBlock once a sweep discovers
+        that the WeakBlock contains no pointers to live objects. Ownership of the WeakBlock is passed
+        to the Heap, which will sweep the list of these detached WeakBlocks as part of a full GC,
+        destroying them once they're fully dead.
+
+        This allows the garbage collector to reclaim the 64kB MarkedBlocks much sooner, and resolves
+        a mysterious issue where doing two full garbage collections back-to-back would free additional
+        memory in the second collection.
+
+        Management of detached WeakBlocks is implemented as a Vector<WeakBlock*> in Heap, along with
+        an index of the next block in that vector that needs to be swept. The IncrementalSweeper then
+        calls into Heap::sweepNextLogicallyEmptyWeakBlock() to sweep one block at a time.
+
+        * heap/Heap.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbage): Add a final pass where we sweep the logically empty WeakBlocks
+        owned by Heap, after everything else has been swept.
+
+        (JSC::Heap::notifyIncrementalSweeper): Set up an incremental sweep of logically empty WeakBlocks
+        after a full garbage collection ends. Note that we don't do this after Eden collections, since
+        they are unlikely to cause entire WeakBlocks to go empty.
+
+        (JSC::Heap::addLogicallyEmptyWeakBlock): Added. Interface for passing ownership of a WeakBlock
+        to the Heap when it's detached from a WeakSet.
+
+        (JSC::Heap::sweepAllLogicallyEmptyWeakBlocks): Helper for collectAllGarbage() that sweeps all
+        of the logically empty WeakBlocks owned by Heap.
+
+        (JSC::Heap::sweepNextLogicallyEmptyWeakBlock): Sweeps one logically empty WeakBlock if needed
+        and updates the next-logically-empty-weak-block-to-sweep index.
+
+        (JSC::Heap::lastChanceToFinalize): call sweepAllLogicallyEmptyWeakBlocks() here, since there
+        won't be another chance after this.
+
+        * heap/IncrementalSweeper.h:
+        (JSC::IncrementalSweeper::hasWork): Deleted.
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::fullSweep):
+        (JSC::IncrementalSweeper::doSweep):
+        (JSC::IncrementalSweeper::sweepNextBlock): Restructured IncrementalSweeper a bit to simplify
+        adding a new sweeping stage for the Heap's logically empty WeakBlocks. sweepNextBlock() is
+        changed to return a bool (true if there's more work to be done.)
+
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::sweep): This now figures out if the WeakBlock is logically empty, i.e doesn't
+        contain any pointers to live objects. The answer is stored in a new SweepResult member.
+
+        * heap/WeakBlock.h:
+        (JSC::WeakBlock::isLogicallyEmptyButNotFree): Added. Can be queried after a sweep to determine
+        if the WeakBlock could be detached from the MarkedBlock.
+
+        (JSC::WeakBlock::SweepResult::SweepResult): Deleted in favor of initializing member variables
+        when declaring them.
+
+2015-04-04  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement ES6 Object.getOwnPropertySymbols
+        https://bugs.webkit.org/show_bug.cgi?id=141106
+
+        Reviewed by Geoffrey Garen.
+
+        This patch implements `Object.getOwnPropertySymbols`.
+        One technical issue is that, since we use private symbols (such as `@Object`) in the
+        privileged JS code in `builtins/`, they should not be exposed.
+        To distinguish them from the usual symbols, check the target `StringImpl*` is a not private name
+        before adding it into PropertyNameArray.
+
+        To check the target `StringImpl*` is a private name, we leverage privateToPublic map in `BuiltinNames`
+        since all private symbols are held in this map.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutableInternal):
+        * builtins/BuiltinNames.h:
+        (JSC::BuiltinNames::isPrivateName):
+        * runtime/CommonIdentifiers.cpp:
+        (JSC::CommonIdentifiers::isPrivateName):
+        * runtime/CommonIdentifiers.h:
+        * runtime/EnumerationMode.h:
+        (JSC::EnumerationMode::EnumerationMode):
+        (JSC::EnumerationMode::includeSymbolProperties):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createUndefinedVariableError):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation):
+        (JSC::objectConstructorGetOwnPropertySymbols):
+        (JSC::defineProperties):
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        (JSC::objectConstructorIsSealed):
+        (JSC::objectConstructorIsFrozen):
+        * runtime/ObjectConstructor.h:
+        (JSC::ObjectConstructor::create):
+        * runtime/Structure.cpp:
+        (JSC::Structure::getPropertyNamesFromStructure):
+        * tests/stress/object-get-own-property-symbols-perform-to-object.js: Added.
+        (compare):
+        * tests/stress/object-get-own-property-symbols.js: Added.
+        (forIn):
+        * tests/stress/symbol-define-property.js: Added.
+        (testSymbol):
+        * tests/stress/symbol-seal-and-freeze.js: Added.
+        * tests/stress/symbol-with-json.js: Added.
+
+2015-04-03  Mark Lam  <mark.lam@apple.com>
+
+        Add Options::jitPolicyScale() as a single knob to make all compilations happen sooner.
+        <https://webkit.org/b/143385>
+
+        Reviewed by Geoffrey Garen.
+
+        For debugging purposes, sometimes, we want to be able to make compilation happen
+        sooner to see if we can accelerate the manifestation of certain events / bugs.
+        Currently, in order to achieve this, we'll have to tweak multiple JIT thresholds
+        which make up the compilation policy.  Let's add a single knob that can tune all
+        the thresholds up / down in one go proportionately so that we can easily tweak
+        how soon compilation occurs.
+
+        * runtime/Options.cpp:
+        (JSC::scaleJITPolicy):
+        (JSC::recomputeDependentOptions):
+        * runtime/Options.h:
+
+2015-04-03  Geoffrey Garen  <ggaren@apple.com>
+
+        is* API methods should be @properties
+        https://bugs.webkit.org/show_bug.cgi?id=143388
+
+        Reviewed by Mark Lam.
+
+        This appears to be the preferred idiom in WebKit, CA, AppKit, and
+        Foundation.
+
+        * API/JSValue.h: Be @properties.
+
+        * API/tests/testapi.mm:
+        (testObjectiveCAPI): Use the @properties.
+
+2015-04-03  Mark Lam  <mark.lam@apple.com>
+
+        Some JSC Options refactoring and enhancements.
+        <https://webkit.org/b/143384>
+
+        Rubber stamped by Benjamin Poulain.
+
+        Create a better encapsulated Option class to make working with options easier.  This
+        is a building block towards a JIT policy scaling debugging option I will introduce later.
+
+        This work entails:
+        1. Convert Options::Option into a public class Option (who works closely with Options).
+        2. Convert Options::EntryType into an enum class Options::Type and make it public.
+        3. Renamed Options::OPT_<option name> to Options::<option name>ID because it reads better.
+        4. Add misc methods to class Option to make it more useable.
+
+        * runtime/Options.cpp:
+        (JSC::Options::dumpOption):
+        (JSC::Option::dump):
+        (JSC::Option::operator==):
+        (JSC::Options::Option::dump): Deleted.
+        (JSC::Options::Option::operator==): Deleted.
+        * runtime/Options.h:
+        (JSC::Option::Option):
+        (JSC::Option::operator!=):
+        (JSC::Option::name):
+        (JSC::Option::description):
+        (JSC::Option::type):
+        (JSC::Option::isOverridden):
+        (JSC::Option::defaultOption):
+        (JSC::Option::boolVal):
+        (JSC::Option::unsignedVal):
+        (JSC::Option::doubleVal):
+        (JSC::Option::int32Val):
+        (JSC::Option::optionRangeVal):
+        (JSC::Option::optionStringVal):
+        (JSC::Option::gcLogLevelVal):
+        (JSC::Options::Option::Option): Deleted.
+        (JSC::Options::Option::operator!=): Deleted.
+
+2015-04-03  Geoffrey Garen  <ggaren@apple.com>
+
+        JavaScriptCore API should support type checking for Array and Date
+        https://bugs.webkit.org/show_bug.cgi?id=143324
+
+        Follow-up to address a comment by Dan.
+
+        * API/WebKitAvailability.h: __MAC_OS_X_VERSION_MIN_REQUIRED <= 101100
+        is wrong, since this API is available when __MAC_OS_X_VERSION_MIN_REQUIRED
+        is equal to 101100.
+
+2015-04-03  Geoffrey Garen  <ggaren@apple.com>
+
+        JavaScriptCore API should support type checking for Array and Date
+        https://bugs.webkit.org/show_bug.cgi?id=143324
+
+        Follow-up to address a comment by Dan.
+
+        * API/WebKitAvailability.h: Do use 10.0 because it was right all along.
+        Added a comment explaining why.
+
+2015-04-03  Csaba Osztrogonác  <ossy@webkit.org>
+
+        FTL JIT tests should fail if LLVM library isn't available
+        https://bugs.webkit.org/show_bug.cgi?id=143374
+
+        Reviewed by Mark Lam.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * runtime/Options.h:
+
+2015-04-03  Zan Dobersek  <zdobersek@igalia.com>
+
+        Fix the EFL and GTK build after r182243
+        https://bugs.webkit.org/show_bug.cgi?id=143361
+
+        Reviewed by Csaba Osztrogonác.
+
+        * CMakeLists.txt: InspectorBackendCommands.js is generated in the
+        DerivedSources/JavaScriptCore/inspector/ directory.
+
+2015-04-03  Zan Dobersek  <zdobersek@igalia.com>
+
+        Unreviewed, fixing Clang builds of the GTK port on Linux.
+
+        * runtime/Options.cpp:
+        Include the <math.h> header for isnan().
+
+2015-04-02  Mark Lam  <mark.lam@apple.com>
+
+        Enhance ability to dump JSC Options.
+        <https://webkit.org/b/143357>
+
+        Reviewed by Benjamin Poulain.
+
+        Some enhancements to how the JSC options work:
+
+        1. Add a JSC_showOptions option which take values: 0 = None, 1 = Overridden only,
+           2 = All, 3 = Verbose.
+
+           The default is 0 (None).  This dumps nothing.
+           With the Overridden setting, at VM initialization time, we will dump all
+           option values that have been changed from their default.
+           With the All setting, at VM initialization time, we will dump all option values.
+           With the Verbose setting, at VM initialization time, we will dump all option
+           values along with their descriptions (if available).
+
+        2. We now store a copy of the default option values.
+
+           We later use this for comparison to tell if an option has been overridden, and
+           print the default value for reference.  As a result, we no longer need the
+           didOverride flag since we can compute whether the option is overridden at any time.
+
+        3. Added description strings to some options to be printed when JSC_showOptions=3 (Verbose).
+
+           This will come in handy later when we want to rename some of the options to more sane
+           names that are easier to remember.  For example, we can change
+           Options::dfgFunctionWhitelistFile() to Options::dfgWhiteList(), and
+           Options::slowPathAllocsBetweenGCs() to Options::forcedGcRate().  With the availability
+           of the description, we can afford to use shorter and less descriptive option names,
+           but they will be easier to remember and use for day to day debugging work.
+
+           In this patch, I did not change the names of any of the options yet.  I only added
+           description strings for options that I know about, and where I think the option name
+           isn't already descriptive enough.
+
+        4. Also deleted some unused code.
+
+        * jsc.cpp:
+        (CommandLine::parseArguments):
+        * runtime/Options.cpp:
+        (JSC::Options::initialize):
+        (JSC::Options::setOption):
+        (JSC::Options::dumpAllOptions):
+        (JSC::Options::dumpOption):
+        (JSC::Options::Option::dump):
+        (JSC::Options::Option::operator==):
+        * runtime/Options.h:
+        (JSC::OptionRange::rangeString):
+        (JSC::Options::Option::Option):
+        (JSC::Options::Option::operator!=):
+
+2015-04-02  Geoffrey Garen  <ggaren@apple.com>
+
+        JavaScriptCore API should support type checking for Array and Date
+        https://bugs.webkit.org/show_bug.cgi?id=143324
+
+        Reviewed by Darin Adler, Sam Weinig, Dan Bernstein.
+
+        * API/JSValue.h:
+        * API/JSValue.mm:
+        (-[JSValue isArray]):
+        (-[JSValue isDate]): Added an ObjC API.
+
+        * API/JSValueRef.cpp:
+        (JSValueIsArray):
+        (JSValueIsDate):
+        * API/JSValueRef.h: Added a C API.
+
+        * API/WebKitAvailability.h: Brought our availability macros up to date
+        and fixed a harmless bug where "10_10" translated to "10.0".
+
+        * API/tests/testapi.c:
+        (main): Added a test and corrected a pre-existing leak.
+
+        * API/tests/testapi.mm:
+        (testObjectiveCAPI): Added a test.
+
+2015-04-02  Mark Lam  <mark.lam@apple.com>
+
+        Add Options::dumpSourceAtDFGTime().
+        <https://webkit.org/b/143349>
+
+        Reviewed by Oliver Hunt, and Michael Saboff.
+
+        Sometimes, we will want to see the JS source code that we're compiling, and it
+        would be nice to be able to do this without having to jump thru a lot of hoops.
+        So, let's add a Options::dumpSourceAtDFGTime() option just like we have a
+        Options::dumpBytecodeAtDFGTime() option.
+
+        Also added versions of CodeBlock::dumpSource() and CodeBlock::dumpBytecode()
+        that explicitly take no arguments (instead of relying on the version that takes
+        the default argument).  These versions are friendlier to use when we want to call
+        them from an interactive debugging session.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpSource):
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/CodeBlock.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * runtime/Options.h:
+
+2015-04-02  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Clean up EnumerationMode to easily extend
+        https://bugs.webkit.org/show_bug.cgi?id=143276
+
+        Reviewed by Geoffrey Garen.
+
+        To make the followings easily,
+        1. Adding new flag Include/ExcludeSymbols in the Object.getOwnPropertySymbols patch
+        2. Make ExcludeSymbols implicitly default for the existing flags
+        we encapsulate EnumerationMode flags into EnumerationMode class.
+
+        And this class manages 2 flags. Later it will be extended to 3.
+        1. DontEnumPropertiesMode (default is Exclude)
+        2. JSObjectPropertiesMode (default is Include)
+        3. SymbolPropertiesMode (default is Exclude)
+            SymbolPropertiesMode will be added in Object.getOwnPropertySymbols patch.
+
+        This patch replaces places using ExcludeDontEnumProperties
+        to EnumerationMode() value which represents default mode.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
+        * API/JSObjectRef.cpp:
+        (JSObjectCopyPropertyNames):
+        * bindings/ScriptValue.cpp:
+        (Deprecated::jsToInspectorValue):
+        * bytecode/ObjectAllocationProfile.h:
+        (JSC::ObjectAllocationProfile::possibleDefaultPropertyCount):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSort):
+        * runtime/EnumerationMode.h:
+        (JSC::EnumerationMode::EnumerationMode):
+        (JSC::EnumerationMode::includeDontEnumProperties):
+        (JSC::EnumerationMode::includeJSObjectProperties):
+        (JSC::shouldIncludeDontEnumProperties): Deleted.
+        (JSC::shouldExcludeDontEnumProperties): Deleted.
+        (JSC::shouldIncludeJSObjectPropertyNames): Deleted.
+        (JSC::modeThatSkipsJSObject): Deleted.
+        * runtime/GenericArgumentsInlines.h:
+        (JSC::GenericArguments<Type>::getOwnPropertyNames):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::getOwnNonIndexPropertyNames):
+        * runtime/JSArrayBuffer.cpp:
+        (JSC::JSArrayBuffer::getOwnNonIndexPropertyNames):
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::JSArrayBufferView::getOwnNonIndexPropertyNames):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getOwnNonIndexPropertyNames):
+        * runtime/JSFunction.h:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnNonIndexPropertyNames):
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Holder::appendNextProperty):
+        (JSC::Walker::walk):
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::getOwnPropertyNames):
+        (JSC::JSObject::getOwnNonIndexPropertyNames):
+        (JSC::JSObject::getGenericPropertyNames):
+        * runtime/JSPropertyNameEnumerator.h:
+        (JSC::propertyNameEnumerator):
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyNames):
+        (JSC::objectConstructorKeys):
+        (JSC::defineProperties):
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        (JSC::objectConstructorIsSealed):
+        (JSC::objectConstructorIsFrozen):
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::getOwnNonIndexPropertyNames):
+        (JSC::RegExpObject::getPropertyNames):
+        (JSC::RegExpObject::getGenericPropertyNames):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::getOwnPropertyNames):
+        * runtime/Structure.cpp:
+        (JSC::Structure::getPropertyNamesFromStructure):
+
+2015-04-01  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards CMake on Windows and Mac.
+        https://bugs.webkit.org/show_bug.cgi?id=143293
+
+        Reviewed by Filip Pizlo.
+
+        * CMakeLists.txt:
+        Enabled using assembly on Windows.
+        Replaced unix commands with CMake commands.
+        * PlatformMac.cmake:
+        Tell open source builders where to find unicode headers.
+
+2015-04-01  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        IteratorClose should be called when jumping over the target for-of loop
+        https://bugs.webkit.org/show_bug.cgi?id=143140
+
+        Reviewed by Geoffrey Garen.
+
+        This patch fixes labeled break/continue behaviors with for-of and iterators.
+
+        1. Support IteratorClose beyond multiple loop contexts
+        Previously, IteratorClose is only executed in for-of's breakTarget().
+        However, this misses IteratorClose execution when statement roll-ups multiple control flow contexts.
+        For example,
+        outer: for (var e1 of outer) {
+            inner: for (var e2 of inner) {
+                break outer;
+            }
+        }
+        In this case, return method of inner should be called.
+        We leverage the existing system for `finally` to execute inner.return method correctly.
+        Leveraging `finally` system fixes `break`, `continue` and `return` cases.
+        `throw` case is already supported by emitting try-catch handlers in for-of.
+
+        2. Incorrect LabelScope creation is done in ForOfNode
+        ForOfNode creates duplicated LabelScope.
+        It causes infinite loop when executing the following program that contains
+        explicitly labeled for-of loop.
+        For example,
+        inner: for (var elm of array) {
+            continue inner;
+        }
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::pushFinallyContext):
+        (JSC::BytecodeGenerator::pushIteratorCloseContext):
+        (JSC::BytecodeGenerator::popFinallyContext):
+        (JSC::BytecodeGenerator::popIteratorCloseContext):
+        (JSC::BytecodeGenerator::emitComplexPopScopes):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::emitIteratorClose):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForOfNode::emitBytecode):
+        * tests/stress/iterator-return-beyond-multiple-iteration-scopes.js: Added.
+        (createIterator.iterator.return):
+        (createIterator):
+        * tests/stress/raise-error-in-iterator-close.js: Added.
+        (createIterator.iterator.return):
+        (createIterator):
+
+2015-04-01  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement Symbol.unscopables
+        https://bugs.webkit.org/show_bug.cgi?id=142829
+
+        Reviewed by Geoffrey Garen.
+
+        This patch introduces Symbol.unscopables functionality.
+        In ES6, some generic names (like keys, values) are introduced
+        as Array's method name. And this breaks the web since some web sites
+        use like the following code.
+
+        var values = ...;
+        with (array) {
+            values;  // This values is trapped by array's method "values".
+        }
+
+        To fix this, Symbol.unscopables introduces blacklist
+        for with scope's trapping. When resolving scope,
+        if name is found in the target scope and the target scope is with scope,
+        we check Symbol.unscopables object to filter generic names.
+
+        This functionality is only active for with scopes.
+        Global scope does not have unscopables functionality.
+
+        And since
+        1) op_resolve_scope for with scope always return Dynamic resolve type,
+        2) in that case, JSScope::resolve is always used in JIT and LLInt,
+        3) the code which contains op_resolve_scope that returns Dynamic cannot be compiled with DFG and FTL,
+        to implement this functionality, we just change JSScope::resolve and no need to change JIT code.
+        So performance regression is only visible in Dynamic resolving case, and it is already much slow.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::runtimeFlags):
+        * runtime/JSScope.cpp:
+        (JSC::isUnscopable):
+        (JSC::JSScope::resolve):
+        * runtime/JSScope.h:
+        (JSC::ScopeChainIterator::scope):
+        * tests/stress/global-environment-does-not-trap-unscopables.js: Added.
+        (test):
+        * tests/stress/unscopables.js: Added.
+        (test):
+        (.):
+
+2015-03-31  Ryosuke Niwa  <rniwa@webkit.org>
+
+        ES6 class syntax should allow static setters and getters
+        https://bugs.webkit.org/show_bug.cgi?id=143180
+
+        Reviewed by Filip Pizlo
+
+        Apparently I misread the spec when I initially implemented parseClass.
+        ES6 class syntax allows static getters and setters so just allow that.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+
+2015-03-31  Filip Pizlo  <fpizlo@apple.com>
+
+        PutClosureVar CSE def() rule has a wrong base
+        https://bugs.webkit.org/show_bug.cgi?id=143280
+
+        Reviewed by Michael Saboff.
+        
+        I think that this code was incorrect in a benign way, since the base of a
+        PutClosureVar is not a JS-visible object. But it was preventing some optimizations.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
+2015-03-31  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r182200.
+        https://bugs.webkit.org/show_bug.cgi?id=143279
+
+        Probably causing assertion extravaganza on bots. (Requested by
+        kling on #webkit).
+
+        Reverted changeset:
+
+        "Logically empty WeakBlocks should not pin down their
+        MarkedBlocks indefinitely."
+        https://bugs.webkit.org/show_bug.cgi?id=143210
+        http://trac.webkit.org/changeset/182200
+
+2015-03-31  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Clean up Identifier factories to clarify the meaning of StringImpl*
+        https://bugs.webkit.org/show_bug.cgi?id=143146
+
+        Reviewed by Filip Pizlo.
+
+        In the a lot of places, `Identifier(VM*/ExecState*, StringImpl*)` constructor is used.
+        However, it's ambiguous because `StringImpl*` has 2 different meanings.
+        1) normal string, it is replacable with `WTFString` and
+        2) `uid`, which holds `isSymbol` information to represent Symbols.
+        So we dropped Identifier constructors for strings and instead, introduced 2 factory functions.
+        + `Identifier::fromString(VM*/ExecState*, const String&)`.
+        Just construct Identifier from strings. The symbol-ness of StringImpl* is not kept.
+        + `Identifier::fromUid(VM*/ExecState*, StringImpl*)`.
+        This function is used for 2) `uid`. So symbol-ness of `StringImpl*` is kept.
+
+        And to clean up `StringImpl` which is used as uid,
+        we introduce `StringKind` into `StringImpl`. There's 3 kinds
+        1. StringNormal (non-atomic, non-symbol)
+        2. StringAtomic (atomic, non-symbol)
+        3. StringSymbol (non-atomic, symbol)
+        They are mutually exclusive. And (atomic, symbol) case should not exist.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeFunction):
+        * API/OpaqueJSString.cpp:
+        (OpaqueJSString::identifier):
+        * bindings/ScriptFunctionCall.cpp:
+        (Deprecated::ScriptFunctionCall::call):
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutableInternal):
+        * builtins/BuiltinNames.h:
+        (JSC::BuiltinNames::BuiltinNames):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitThrowReferenceError):
+        (JSC::BytecodeGenerator::emitThrowTypeError):
+        (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        * dfg/DFGDesiredIdentifiers.cpp:
+        (JSC::DFG::DesiredIdentifiers::reallyAdd):
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::functionDetails):
+        (Inspector::constructInternalProperty):
+        (Inspector::JSInjectedScriptHost::weakMapEntries):
+        (Inspector::JSInjectedScriptHost::iteratorEntries):
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::extractSourceInformationFromException):
+        * jit/JITOperations.cpp:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (GlobalObject::addFunction):
+        (GlobalObject::addConstructableFunction):
+        (functionRun):
+        (runWithScripts):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::addVar):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::createBindingPattern):
+        * parser/ParserArena.h:
+        (JSC::IdentifierArena::makeIdentifier):
+        (JSC::IdentifierArena::makeIdentifierLCharFromUChar):
+        (JSC::IdentifierArena::makeNumericIdentifier):
+        * runtime/ArgumentsIteratorPrototype.cpp:
+        (JSC::ArgumentsIteratorPrototype::finishCreation):
+        * runtime/ArrayIteratorPrototype.cpp:
+        (JSC::ArrayIteratorPrototype::finishCreation):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        (JSC::arrayProtoFuncPush):
+        * runtime/ClonedArguments.cpp:
+        (JSC::ClonedArguments::getOwnPropertySlot):
+        * runtime/CommonIdentifiers.cpp:
+        (JSC::CommonIdentifiers::CommonIdentifiers):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Error.cpp:
+        (JSC::addErrorInfo):
+        (JSC::hasErrorInfo):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createUndefinedVariableError):
+        * runtime/GenericArgumentsInlines.h:
+        (JSC::GenericArguments<Type>::getOwnPropertySlot):
+        * runtime/Identifier.h:
+        (JSC::Identifier::isSymbol):
+        (JSC::Identifier::Identifier):
+        (JSC::Identifier::from): Deleted.
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::Identifier):
+        (JSC::Identifier::fromUid):
+        (JSC::Identifier::fromString):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::dumpInContextAssumingStructure):
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::toPropertyKey):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        * runtime/JSObject.h:
+        (JSC::makeIdentifier):
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructorFuncRace):
+        (JSC::JSPromiseConstructorFuncAll):
+        * runtime/JSString.h:
+        (JSC::JSString::toIdentifier):
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::tryJSONPParse):
+        (JSC::LiteralParser<CharType>::makeIdentifier):
+        * runtime/Lookup.h:
+        (JSC::reifyStaticProperties):
+        * runtime/MapConstructor.cpp:
+        (JSC::constructMap):
+        * runtime/MapIteratorPrototype.cpp:
+        (JSC::MapIteratorPrototype::finishCreation):
+        * runtime/MapPrototype.cpp:
+        (JSC::MapPrototype::finishCreation):
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::finishCreation):
+        * runtime/PrivateName.h:
+        (JSC::PrivateName::PrivateName):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::get):
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (JSC::PropertyName::publicName):
+        (JSC::PropertyName::asIndex):
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/PropertyNameArray.h:
+        (JSC::PropertyNameArray::addKnownUnique):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::finishCreation):
+        * runtime/SetConstructor.cpp:
+        (JSC::constructSet):
+        * runtime/SetIteratorPrototype.cpp:
+        (JSC::SetIteratorPrototype::finishCreation):
+        * runtime/SetPrototype.cpp:
+        (JSC::SetPrototype::finishCreation):
+        * runtime/StringIteratorPrototype.cpp:
+        (JSC::StringIteratorPrototype::finishCreation):
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        * runtime/Structure.cpp:
+        (JSC::Structure::getPropertyNamesFromStructure):
+        * runtime/SymbolConstructor.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::throwException):
+        * runtime/WeakMapConstructor.cpp:
+        (JSC::constructWeakMap):
+
+2015-03-31  Andreas Kling  <akling@apple.com>
+
+        Logically empty WeakBlocks should not pin down their MarkedBlocks indefinitely.
+        <https://webkit.org/b/143210>
+
+        Reviewed by Geoffrey Garen.
+
+        Since a MarkedBlock cannot be destroyed until all the WeakBlocks pointing into it are gone,
+        we had a little problem where WeakBlocks with only null pointers would still keep their
+        MarkedBlock alive.
+
+        This patch fixes that by detaching WeakBlocks from their MarkedBlock once a sweep discovers
+        that the WeakBlock contains no pointers to live objects. Ownership of the WeakBlock is passed
+        to the Heap, which will sweep the list of these detached WeakBlocks as part of a full GC,
+        destroying them once they're fully dead.
+
+        This allows the garbage collector to reclaim the 64kB MarkedBlocks much sooner, and resolves
+        a mysterious issue where doing two full garbage collections back-to-back would free additional
+        memory in the second collection.
+
+        Management of detached WeakBlocks is implemented as a Vector<WeakBlock*> in Heap, along with
+        an index of the next block in that vector that needs to be swept. The IncrementalSweeper then
+        calls into Heap::sweepNextLogicallyEmptyWeakBlock() to sweep one block at a time.
+
+        * heap/Heap.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbage): Add a final pass where we sweep the logically empty WeakBlocks
+        owned by Heap, after everything else has been swept.
+
+        (JSC::Heap::notifyIncrementalSweeper): Set up an incremental sweep of logically empty WeakBlocks
+        after a full garbage collection ends. Note that we don't do this after Eden collections, since
+        they are unlikely to cause entire WeakBlocks to go empty.
+
+        (JSC::Heap::addLogicallyEmptyWeakBlock): Added. Interface for passing ownership of a WeakBlock
+        to the Heap when it's detached from a WeakSet.
+
+        (JSC::Heap::sweepAllLogicallyEmptyWeakBlocks): Helper for collectAllGarbage() that sweeps all
+        of the logically empty WeakBlocks owned by Heap.
+
+        (JSC::Heap::sweepNextLogicallyEmptyWeakBlock): Sweeps one logically empty WeakBlock if needed
+        and updates the next-logically-empty-weak-block-to-sweep index.
+
+        (JSC::Heap::lastChanceToFinalize): call sweepAllLogicallyEmptyWeakBlocks() here, since there
+        won't be another chance after this.
+
+        * heap/IncrementalSweeper.h:
+        (JSC::IncrementalSweeper::hasWork): Deleted.
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::fullSweep):
+        (JSC::IncrementalSweeper::doSweep):
+        (JSC::IncrementalSweeper::sweepNextBlock): Restructured IncrementalSweeper a bit to simplify
+        adding a new sweeping stage for the Heap's logically empty WeakBlocks. sweepNextBlock() is
+        changed to return a bool (true if there's more work to be done.)
+
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::sweep): This now figures out if the WeakBlock is logically empty, i.e doesn't
+        contain any pointers to live objects. The answer is stored in a new SweepResult member.
+
+        * heap/WeakBlock.h:
+        (JSC::WeakBlock::isLogicallyEmptyButNotFree): Added. Can be queried after a sweep to determine
+        if the WeakBlock could be detached from the MarkedBlock.
+
+        (JSC::WeakBlock::SweepResult::SweepResult): Deleted in favor of initializing member variables
+        when declaring them.
+
+2015-03-31  Ryosuke Niwa  <rniwa@webkit.org>
+
+        eval("this.foo") causes a crash if this had not been initialized in a derived class's constructor
+        https://bugs.webkit.org/show_bug.cgi?id=142883
+
+        Reviewed by Filip Pizlo.
+
+        The crash was caused by eval inside the constructor of a derived class not checking TDZ.
+
+        Fixed the bug by adding a parser flag that forces the TDZ check to be always emitted when accessing "this"
+        in eval inside a derived class' constructor.
+
+        * bytecode/EvalCodeCache.h:
+        (JSC::EvalCodeCache::getSlow):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::evaluate):
+        * interpreter/Interpreter.cpp:
+        (JSC::eval):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::thisExpr):
+        * parser/NodeConstructors.h:
+        (JSC::ThisNode::ThisNode):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/ParserModes.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::thisExpr):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getProgramCodeBlock):
+        (JSC::CodeCache::getEvalCodeBlock):
+        * runtime/CodeCache.h:
+        (JSC::SourceCodeKey::SourceCodeKey):
+        * runtime/Executable.cpp:
+        (JSC::EvalExecutable::create):
+        * runtime/Executable.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::createEvalCodeBlock):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncEval):
+        * tests/stress/class-syntax-no-tdz-in-eval.js: Added.
+        * tests/stress/class-syntax-tdz-in-eval.js: Added.
+
+2015-03-31  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r182186.
+        https://bugs.webkit.org/show_bug.cgi?id=143270
+
+        it crashes all the WebGL tests on the Debug bots (Requested by
+        dino on #webkit).
+
+        Reverted changeset:
+
+        "Web Inspector: add 2D/WebGL canvas instrumentation
+        infrastructure"
+        https://bugs.webkit.org/show_bug.cgi?id=137278
+        http://trac.webkit.org/changeset/182186
+
+2015-03-31  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Object type restrictions on a first parameter of several Object.* functions are relaxed
+        https://bugs.webkit.org/show_bug.cgi?id=142937
+
+        Reviewed by Darin Adler.
+
+        In ES6, Object type restrictions on a first parameter of several Object.* functions are relaxed.
+        In ES5 or prior, when a first parameter is not object type, these functions raise TypeError.
+        But now, several functions perform ToObject onto a non-object parameter.
+        And others behaves as if a parameter is a non-extensible ordinary object with no own properties.
+        It is described in ES6 Annex E.
+        Functions different from ES5 are following.
+
+        1. An attempt is make to coerce the argument using ToObject.
+            Object.getOwnPropertyDescriptor
+            Object.getOwnPropertyNames
+            Object.getPrototypeOf
+            Object.keys
+
+        2. Treated as if it was a non-extensible ordinary object with no own properties.
+            Object.freeze
+            Object.isExtensible
+            Object.isFrozen
+            Object.isSealed
+            Object.preventExtensions
+            Object.seal
+
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructorGetPrototypeOfFunctor::operator()):
+        (JSC::objectConstructorGetPrototypeOf):
+        (JSC::objectConstructorGetOwnPropertyDescriptor):
+        (JSC::objectConstructorGetOwnPropertyNames):
+        (JSC::objectConstructorKeys):
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        (JSC::objectConstructorPreventExtensions):
+        (JSC::objectConstructorIsSealed):
+        (JSC::objectConstructorIsFrozen):
+        (JSC::objectConstructorIsExtensible):
+        * tests/stress/object-freeze-accept-non-object.js: Added.
+        * tests/stress/object-get-own-property-descriptor-perform-to-object.js: Added.
+        (canary):
+        * tests/stress/object-get-own-property-names-perform-to-object.js: Added.
+        (compare):
+        * tests/stress/object-get-prototype-of-perform-to-object.js: Added.
+        * tests/stress/object-is-extensible-accept-non-object.js: Added.
+        * tests/stress/object-is-frozen-accept-non-object.js: Added.
+        * tests/stress/object-is-sealed-accept-non-object.js: Added.
+        * tests/stress/object-keys-perform-to-object.js: Added.
+        (compare):
+        * tests/stress/object-prevent-extensions-accept-non-object.js: Added.
+        * tests/stress/object-seal-accept-non-object.js: Added.
+
+2015-03-31  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: add 2D/WebGL canvas instrumentation infrastructure
+        https://bugs.webkit.org/show_bug.cgi?id=137278
+
+        Reviewed by Timothy Hatcher.
+
+        Added Canvas protocol which defines types used by InspectorCanvasAgent.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * inspector/protocol/Canvas.json: Added.
+
+        * inspector/scripts/codegen/generator.py:
+        (Generator.stylized_name_for_enum_value):
+        Added special handling for 2D (always uppercase) and WebGL (rename mapping) enum strings.
+
+2015-03-30  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Extending null should set __proto__ to null
+        https://bugs.webkit.org/show_bug.cgi?id=142882
+
+        Reviewed by Geoffrey Garen and Benjamin Poulain.
+
+        Set Derived.prototype.__proto__ to null when extending null.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ClassExprNode::emitBytecode):
+
+2015-03-30  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION (r181993): inspector-protocol/debugger/setBreakpoint-dfg-and-modify-local.html crashes.
+        <https://webkit.org/b/143105>
+
+        Reviewed by Filip Pizlo.
+
+        With r181993, the DFG and FTL may elide the storing of the scope register.  As a result,
+        on OSR exits from DFG / FTL frames where this elision has take place, we may get baseline
+        JIT frames that may have its scope register not set.  The Debugger's current implementation
+        which relies on the scope register is not happy about this.  For example, this results in a
+        crash in the layout test inspector-protocol/debugger/setBreakpoint-dfg-and-modify-local.html.
+
+        The fix is to disable inlining when the debugger is in use.  Also, we add Flush nodes to
+        ensure that the scope register value is flushed to the register in the stack frame.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::ByteCodeParser):
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::flush):
+        - Add code to flush the scope register.
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        - Pretend that all codeBlocks are too expensive to inline if the debugger is in use, thereby
+          disabling inlining whenever the debugger is in use.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::hasDebuggerEnabled):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        - Update the DFG codeBlock's scopeRegister since it can be moved during stack layout.
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        - Update the FTL codeBlock's scopeRegister since it can be moved during stack layout.
+
+2015-03-30  Michael Saboff  <msaboff@apple.com>
+
+        Fix flakey float32-repeat-out-of-bounds.js and int8-repeat-out-of-bounds.js tests for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=138391
+
+        Reviewed by Mark Lam.
+
+        Re-enabling these tests as I can't get them to fail on local iOS test devices.
+        There have been many changes since these tests were disabled.
+        I'll watch automated test results for failures.  If there are failures running automated
+        testing, it might be due to the device's relative CPU performance.
+        
+        * tests/stress/float32-repeat-out-of-bounds.js:
+        * tests/stress/int8-repeat-out-of-bounds.js:
+
+2015-03-30  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Regression: Preview for [[null]] shouldn't be []
+        https://bugs.webkit.org/show_bug.cgi?id=143208
+
+        Reviewed by Mark Lam.
+
+        * inspector/InjectedScriptSource.js:
+        Handle null when generating simple object previews.
+
+2015-03-30  Per Arne Vollan  <peavo@outlook.com>
+
+        Avoid using hardcoded values for JSValue::Int32Tag, if possible.
+        https://bugs.webkit.org/show_bug.cgi?id=143134
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JSInterfaceJIT.h:
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+
+2015-03-30  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION: js/regress/inline-arguments-local-escape.html is flaky
+        https://bugs.webkit.org/show_bug.cgi?id=143104
+
+        Reviewed by Geoffrey Garen.
+        
+        Created a test that is a 100% repro of the flaky failure. This test is called
+        get-my-argument-by-val-for-inlined-escaped-arguments.js. It fails all of the time because it
+        always causes the compiler to emit a GetMyArgumentByVal of the arguments object returned by
+        the inlined function. Other than that, it's the same as inline-arguments-local-escape.
+        
+        Also created three more tests for three similar, but not identical, failures.
+        
+        Then fixed the bug: PreciseLocalClobberize was assuming that if we read(Stack) then we are
+        only reading those parts of the stack that are relevant to the current semantic code origin.
+        That's false after ArgumentsEliminationPhase - we might have operations on phantom arguments,
+        like GetMyArgumentByVal, ForwardVarargs, CallForwardVarargs, and ConstructForwardVarargs, that
+        read parts of the stack associated with the inline call frame for the phantom arguments. This
+        may not be subsumed by the current semantic origin's stack area in cases that the arguments
+        were allowed to "locally" escape.
+        
+        The higher-order lesson here is that in DFG SSA IR, the current semantic origin's stack area
+        is not really a meaningful concept anymore. It is only meaningful for nodes that will read
+        the stack due to function.arguments, but there are a bunch of other ways that we could also
+        read the stack and those operations may read any stack slot. I believe that this change makes
+        PreciseLocalClobberize right: it will refine a read(Stack) from Clobberize correctly by casing
+        on node type. In future, if we add a read(Stack) to Clobberize, we'll have to make sure that
+        readTop() in PreciseLocalClobberize does the right thing.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        * dfg/DFGPutStackSinkingPhase.cpp:
+        * tests/stress/call-forward-varargs-for-inlined-escaped-arguments.js: Added.
+        * tests/stress/construct-forward-varargs-for-inlined-escaped-arguments.js: Added.
+        * tests/stress/forward-varargs-for-inlined-escaped-arguments.js: Added.
+        * tests/stress/get-my-argument-by-val-for-inlined-escaped-arguments.js: Added.
+        * tests/stress/real-forward-varargs-for-inlined-escaped-arguments.js: Added.
+
+2015-03-30  Benjamin Poulain  <benjamin@webkit.org>
+
+        Start the features.json files
+        https://bugs.webkit.org/show_bug.cgi?id=143207
+
+        Reviewed by Darin Adler.
+
+        Start the features.json files to have something to experiment
+        with for the UI.
+
+        * features.json: Added.
+
+2015-03-29  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Win] Addresing post-review comment after r182122
+        https://bugs.webkit.org/show_bug.cgi?id=143189
+
+        Unreviewed.
+
+2015-03-29  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Win] Allow building JavaScriptCore without Cygwin
+        https://bugs.webkit.org/show_bug.cgi?id=143189
+
+        Reviewed by Brent Fulgham.
+
+        Paths like /usr/bin/ don't exist on Windows.
+        Hashbangs don't work on Windows. Instead we must explicitly call the executable.
+        Prefixing commands with environment variables doesn't work on Windows.
+        Windows doesn't have 'cmp'
+        Windows uses 'del' instead of 'rm'
+        Windows uses 'type NUL' intead of 'touch'
+
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make:
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make:
+        * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.pl:
+        * JavaScriptCore.vcxproj/build-generated-files.pl:
+        * UpdateContents.py: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.pl.
+
+2015-03-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Clean up JavaScriptCore/builtins
+        https://bugs.webkit.org/show_bug.cgi?id=143177
+
+        Reviewed by Ryosuke Niwa.
+
+        * builtins/ArrayConstructor.js:
+        (from):
+        - We can compare to undefined instead of using a typeof undefined check.
+        - Converge on double quoted strings everywhere.
+
+        * builtins/ArrayIterator.prototype.js:
+        (next):
+        * builtins/StringIterator.prototype.js:
+        (next):
+        - Use shorthand object construction to avoid duplication.
+        - Improve grammar in error messages.
+
+        * tests/stress/array-iterators-next-with-call.js:
+        * tests/stress/string-iterators.js:
+        - Update for new error message strings.
+
+2015-03-28  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: ES6: Better support for Symbol types in Type Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=141257
+
+        Reviewed by Joseph Pecoraro.
+
+        ES6 introduces the new primitive type Symbol. This patch makes JSC's 
+        type profiler support this new primitive type.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * inspector/protocol/Runtime.json:
+        * runtime/RuntimeType.cpp:
+        (JSC::runtimeTypeForValue):
+        * runtime/RuntimeType.h:
+        (JSC::runtimeTypeIsPrimitive):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::dumpTypes):
+        (JSC::TypeSet::doesTypeConformTo):
+        (JSC::TypeSet::displayName):
+        (JSC::TypeSet::inspectorTypeSet):
+        (JSC::TypeSet::toJSONString):
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::seenTypes):
+        * tests/typeProfiler/driver/driver.js:
+        * tests/typeProfiler/symbol.js: Added.
+        (wrapper.foo):
+        (wrapper.bar):
+        (wrapper.bar.bar.baz):
+        (wrapper):
+
+2015-03-27  Saam Barati  <saambarati1@gmail.com>
+
+        Deconstruction parameters are bound too late
+        https://bugs.webkit.org/show_bug.cgi?id=143148
+
+        Reviewed by Filip Pizlo.
+
+        Currently, a deconstruction pattern named with the same
+        name as a function will shadow the function. This is
+        wrong. It should be the other way around.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+
+2015-03-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        parse doesn't initialize the 16-bit version of the JSC parser with defaultConstructorKind
+        https://bugs.webkit.org/show_bug.cgi?id=143170
+
+        Reviewed by Benjamin Poulain.
+
+        Assert that we never use 16-bit version of the parser to parse a default constructor
+        since both base and derived default constructors should be using a 8-bit string.
+
+        * parser/Parser.h:
+        (JSC::parse):
+
+2015-03-27  Ryosuke Niwa  <rniwa@webkit.org>
+
+        ES6 Classes: Runtime error in JIT'd class calling super() with arguments and superclass has default constructor
+        https://bugs.webkit.org/show_bug.cgi?id=142862
+
+        Reviewed by Benjamin Poulain.
+
+        Add a test that used to fail in DFG now that the bug has been fixed by r181993.
+
+        * tests/stress/class-syntax-derived-default-constructor.js: Added.
+
+2015-03-27  Michael Saboff  <msaboff@apple.com>
+
+        load8Signed() and load16Signed() should be renamed to avoid confusion
+        https://bugs.webkit.org/show_bug.cgi?id=143168
+
+        Reviewed by Benjamin Poulain.
+
+        Renamed load8Signed() to load8SignedExtendTo32() and load16Signed() to load16SignedExtendTo32().
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::load8SignedExtendTo32):
+        (JSC::MacroAssemblerARM::load16SignedExtendTo32):
+        (JSC::MacroAssemblerARM::load8Signed): Deleted.
+        (JSC::MacroAssemblerARM::load16Signed): Deleted.
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::load16SignedExtendTo32):
+        (JSC::MacroAssemblerARM64::load8SignedExtendTo32):
+        (JSC::MacroAssemblerARM64::load16Signed): Deleted.
+        (JSC::MacroAssemblerARM64::load8Signed): Deleted.
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::load16SignedExtendTo32):
+        (JSC::MacroAssemblerARMv7::load8SignedExtendTo32):
+        (JSC::MacroAssemblerARMv7::load16Signed): Deleted.
+        (JSC::MacroAssemblerARMv7::load8Signed): Deleted.
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::load8SignedExtendTo32):
+        (JSC::MacroAssemblerMIPS::load16SignedExtendTo32):
+        (JSC::MacroAssemblerMIPS::load8Signed): Deleted.
+        (JSC::MacroAssemblerMIPS::load16Signed): Deleted.
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::load8SignedExtendTo32):
+        (JSC::MacroAssemblerSH4::load8):
+        (JSC::MacroAssemblerSH4::load16SignedExtendTo32):
+        (JSC::MacroAssemblerSH4::load16):
+        (JSC::MacroAssemblerSH4::load8Signed): Deleted.
+        (JSC::MacroAssemblerSH4::load16Signed): Deleted.
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::load8SignedExtendTo32):
+        (JSC::MacroAssemblerX86Common::load16SignedExtendTo32):
+        (JSC::MacroAssemblerX86Common::load8Signed): Deleted.
+        (JSC::MacroAssemblerX86Common::load16Signed): Deleted.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitIntTypedArrayGetByVal):
+
+2015-03-27  Michael Saboff  <msaboff@apple.com>
+
+        Fix flakey dfg-int8array.js and dfg-int16array.js tests for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=138390
+
+        Reviewed by Mark Lam.
+
+        Changed load8Signed() and load16Signed() to only sign extend the loaded value to 32 bits
+        instead of 64 bits.  This is what X86-64 does.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::load16Signed):
+        (JSC::MacroAssemblerARM64::load8Signed):
+
+2015-03-27  Saam Barati  <saambarati1@gmail.com>
+
+        Add back previously broken assert from bug 141869
+        https://bugs.webkit.org/show_bug.cgi?id=143005
+
+        Reviewed by Michael Saboff.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::invalidParameterInSourceAppender):
+
+2015-03-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Make some more objects use FastMalloc
+        https://bugs.webkit.org/show_bug.cgi?id=143122
+
+        Reviewed by Csaba Osztrogonác.
+
+        * API/JSCallbackObject.h:
+        * heap/IncrementalSweeper.h:
+        * jit/JITThunks.h:
+        * runtime/JSGlobalObjectDebuggable.h:
+        * runtime/RegExpCache.h:
+
+2015-03-27  Michael Saboff  <msaboff@apple.com>
+
+        Objects with numeric properties intermittently get a phantom 'length' property
+        https://bugs.webkit.org/show_bug.cgi?id=142792
+
+        Reviewed by Csaba Osztrogonác.
+
+        Fixed a > (greater than) that should be a >> (right shift) in the code that disassembles
+        test and branch instructions.  This function is used for linking tbz/tbnz branches between
+        two seperately JIT'ed sections of code.  Sometime we'd create a bogus tbz instruction in
+        the failure case checks in the GetById array length stub created for "obj.length" access.
+        If the failure case code address was at a negative offset from the stub, we'd look for bit 1
+        being set when we should have been looking for bit 0.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::disassembleTestAndBranchImmediate):
+
+2015-03-27  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Insert exception check around toPropertyKey call
+        https://bugs.webkit.org/show_bug.cgi?id=142922
+
+        Reviewed by Geoffrey Garen.
+
+        In some places, exception check is missing after/before toPropertyKey.
+        However, since it calls toString, it's observable to users,
+
+        Missing exception checks in Object.prototype methods can be
+        observed since it would be overridden with toObject(null/undefined) errors.
+        We inserted exception checks after toPropertyKey.
+
+        Missing exception checks in GetById related code can be
+        observed since it would be overridden with toObject(null/undefined) errors.
+        In this case, we need to insert exception checks before/after toPropertyKey
+        since RequireObjectCoercible followed by toPropertyKey can cause exceptions.
+
+        JSValue::get checks null/undefined and raise an exception if |this| is null or undefined.
+        However, we need to check whether the baseValue is object coercible before executing JSValue::toPropertyKey.
+        According to the spec, we first perform RequireObjectCoercible and check the exception.
+        And second, we perform ToPropertyKey and check the exception.
+        Since JSValue::toPropertyKey can cause toString call, this is observable to users.
+        For example, if the target is not object coercible,
+        ToPropertyKey should not be executed, and toString should not be executed by ToPropertyKey.
+        So the order of observable actions (RequireObjectCoercible and ToPropertyKey) should be correct to the spec.
+
+        This patch introduces JSValue::requireObjectCoercible and use it because of the following 2 reasons.
+
+        1. Using toObject instead of requireObjectCoercible produces unnecessary wrapper object.
+
+        toObject converts primitive types into wrapper objects.
+        But it is not efficient since wrapper objects are not necessary
+        if we look up methods from primitive values's prototype. (using synthesizePrototype is better).
+
+        2. Using the result of toObject is not correct to the spec.
+
+        To align to the spec correctly, we cannot use JSObject::get
+        by using the wrapper object produced by the toObject suggested in (1).
+        If we use JSObject that is converted by toObject, getter will be called by using this JSObject as |this|.
+        It is not correct since getter should be called with the original |this| value that may be primitive types.
+
+        So in this patch, we use JSValue::requireObjectCoercible
+        to check the target is object coercible and raise an error if it's not.
+
+        * dfg/DFGOperations.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::requireObjectCoercible):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncHasOwnProperty):
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+        (JSC::objectProtoFuncPropertyIsEnumerable):
+        * tests/stress/exception-in-to-property-key-should-be-handled-early-in-object-methods.js: Added.
+        (shouldThrow):
+        (if):
+        * tests/stress/exception-in-to-property-key-should-be-handled-early.js: Added.
+        (shouldThrow):
+        (.):
+
+2015-03-26  Joseph Pecoraro  <pecoraro@apple.com>
+
+        WebContent Crash when instantiating class with Type Profiling enabled
+        https://bugs.webkit.org/show_bug.cgi?id=143037
+
+        Reviewed by Ryosuke Niwa.
+
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitMoveEmptyValue):
+        We cannot profile the type of an uninitialized empty JSValue.
+        Nor do we expect this to be necessary, since it is effectively
+        an unseen undefined value. So add a way to put the empty value
+        without profiling.
+
+        (JSC::BytecodeGenerator::emitMove):
+        Add an assert to try to catch this issue early on, and force
+        callers to explicitly use emitMoveEmptyValue instead.
+
+        * tests/typeProfiler/classes.js: Added.
+        (wrapper.Base):
+        (wrapper.Derived):
+        (wrapper):
+        Add test coverage both for this case and classes in general.
+
+2015-03-26  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Provide a better view for Classes in the console
+        https://bugs.webkit.org/show_bug.cgi?id=142999
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Runtime.json:
+        Provide a new `subtype` enum "class". This is a subtype of `type`
+        "function", all other subtypes are subtypes of `object` types.
+        For a class, the frontend will immediately want to get the prototype
+        to enumerate its methods, so include the `classPrototype`.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        Denote class construction functions as "class" subtypes.
+
+        * inspector/InjectedScriptSource.js:
+        Handling for the new "class" type.
+
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::isClassConstructorFunction):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::isClassConstructorFunction):
+        * runtime/JSFunction.h:
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::isClassConstructorFunction):
+        Check if this function is a class constructor function. That information
+        is on the UnlinkedFunctionExecutable, so plumb it through to JSFunction.
+
+2015-03-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Function.prototype.toString should not decompile the AST
+        https://bugs.webkit.org/show_bug.cgi?id=142853
+
+        Reviewed by Darin Adler.
+
+        Following up on Darin's review comments.
+
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+
+2015-03-26  Geoffrey Garen  <ggaren@apple.com>
+
+        "lineNo" does not match WebKit coding style guidelines
+        https://bugs.webkit.org/show_bug.cgi?id=143119
+
+        Reviewed by Michael Saboff.
+
+        We can afford to use whole words.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::lineNumberForBytecodeOffset):
+        (JSC::CodeBlock::expressionRangeForBytecodeOffset):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::link):
+        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
+        * bytecode/UnlinkedCodeBlock.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::WhileNode::emitBytecode):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::toggleBreakpoint):
+        * interpreter/Interpreter.cpp:
+        (JSC::StackFrame::computeLineAndColumn):
+        (JSC::GetStackTraceFunctor::operator()):
+        (JSC::Interpreter::execute):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::computeLineAndColumn):
+        * parser/Nodes.h:
+        (JSC::Node::firstLine):
+        (JSC::Node::lineNo): Deleted.
+        (JSC::StatementNode::firstLine): Deleted.
+        * parser/ParserError.h:
+        (JSC::ParserError::toErrorObject):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::createCallIdentifierFromFunctionImp):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::ScriptExecutable):
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        (JSC::FunctionExecutable::fromGlobalCode):
+        * runtime/Executable.h:
+        (JSC::ScriptExecutable::firstLine):
+        (JSC::ScriptExecutable::setOverrideLineNumber):
+        (JSC::ScriptExecutable::hasOverrideLineNumber):
+        (JSC::ScriptExecutable::overrideLineNumber):
+        (JSC::ScriptExecutable::lineNo): Deleted.
+        (JSC::ScriptExecutable::setOverrideLineNo): Deleted.
+        (JSC::ScriptExecutable::hasOverrideLineNo): Deleted.
+        (JSC::ScriptExecutable::overrideLineNo): Deleted.
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+        * runtime/FunctionConstructor.h:
+        * tools/CodeProfile.cpp:
+        (JSC::CodeProfile::report):
+        * tools/CodeProfile.h:
+        (JSC::CodeProfile::CodeProfile):
+
+2015-03-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Assertion firing in JavaScriptCore/parser/parser.h for statesman.com site
+        https://bugs.webkit.org/show_bug.cgi?id=142974
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch does two things:
+
+        (1) Restore JavaScriptCore's sanitization of line and column numbers to
+        one-based values.
+
+        We need this because WebCore sometimes provides huge negative column
+        numbers.
+
+        (2) Solve the attribute event listener line numbering problem a different
+        way: Rather than offseting all line numbers by -1 in an attribute event
+        listener in order to arrange for a custom result, instead use an explicit
+        feature for saying "all errors in this code should map to this line number".
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::link):
+        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
+        * bytecode/UnlinkedCodeBlock.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::StackFrame::computeLineAndColumn):
+        (JSC::GetStackTraceFunctor::operator()):
+        * interpreter/Interpreter.h:
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::computeLineAndColumn):
+        * parser/ParserError.h:
+        (JSC::ParserError::toErrorObject): Plumb through an override line number.
+        When a function has an override line number, all syntax and runtime
+        errors in the function will map to it. This is useful for attribute event
+        listeners.
+        * parser/SourceCode.h:
+        (JSC::SourceCode::SourceCode): Restore the old sanitization of line and
+        column numbers to one-based integers. It was kind of a hack to remove this.
+
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::ScriptExecutable):
+        (JSC::FunctionExecutable::fromGlobalCode):
+        * runtime/Executable.h:
+        (JSC::ScriptExecutable::setOverrideLineNo):
+        (JSC::ScriptExecutable::hasOverrideLineNo):
+        (JSC::ScriptExecutable::overrideLineNo):
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+        * runtime/FunctionConstructor.h: Plumb through an override line number.
+
+2015-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        If we're in code for accessing scoped arguments, we should probably check if the object is a scoped arguments rather than checking if it's a direct arguments.
+
+        Reviewed by Michael Saboff.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+        * tests/stress/scoped-then-direct-arguments-get-by-val-in-baseline.js: Added.
+
+2015-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL ScopedArguments GetArrayLength generates incorrect code and crashes in LLVM
+        https://bugs.webkit.org/show_bug.cgi?id=143098
+
+        Reviewed by Csaba Osztrogonác.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength): Fix a typo.
+        * tests/stress/scoped-arguments-array-length.js: Added. This test previously always crashed in ftl-no-cjit mode.
+
+2015-03-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Unreviewed gardening, skip failing tests on AArch64 Linux.
+
+        * tests/mozilla/mozilla-tests.yaml:
+        * tests/stress/cached-prototype-setter.js:
+
+2015-03-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fixes to silly things. While landing fixes to r181993, I introduced crashes. This fixes them.
+
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants): I landed a fix for a VS warning. It broke this. Now I'm fixing it.
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile): Make sure we pass the module when dumping. This makes FTL debugging possible again.
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::dumpState): New overload that takes a module, so that we can call this after FTL::compile() clears State's module.
+        * ftl/FTLState.h:
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix obvious goof that was causing 32-bit debug crashes. The 64-bit version did it
+        right, so this just makes 32-bit do the same.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Fix a typo that ggaren found but that I didn't fix before.
+
+        * runtime/DirectArgumentsOffset.h:
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, VC found a bug. This fixes the bug.
+
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, try to fix Windows build.
+
+        * runtime/ClonedArguments.cpp:
+        (JSC::ClonedArguments::createWithInlineFrame):
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix debug build.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConstDeclNode::emitCodeSingle):
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix CLOOP build.
+
+        * dfg/DFGMinifiedID.h:
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Heap variables shouldn't end up in the stack frame
+        https://bugs.webkit.org/show_bug.cgi?id=141174
+
+        Reviewed by Geoffrey Garen.
+        
+        This is a major change to how JavaScriptCore handles declared variables (i.e. "var"). It removes
+        any ambiguity about whether a variable should be in the heap or on the stack. A variable will no
+        longer move between heap and stack during its lifetime. This enables a bunch of optimizations and
+        simplifications:
+        
+        - Accesses to variables no longer need checks or indirections to determine where the variable is
+          at that moment in time. For example, loading a closure variable now takes just one load instead
+          of two. Loading an argument by index now takes a bounds check and a load in the fastest case
+          (when no arguments object allocation is required) while previously that same operation required
+          a "did I allocate arguments yet" check, a bounds check, and then the load.
+        
+        - Reasoning about the allocation of an activation or arguments object now follows the same simple
+          logic as the allocation of any other kind of object. Previously, those objects were lazily
+          allocated - so an allocation instruction wasn't the actual allocation site, since it might not
+          allocate anything at all. This made the implementation of traditional escape analyses really
+          awkward, and ultimately it meant that we missed important cases. Now, we can reason about the
+          arguments object using the usual SSA tricks which allows for more comprehensive removal.
+        
+        - The allocations of arguments objects, functions, and activations are now much faster. While
+          this patch generally expands our ability to eliminate arguments object allocations, an earlier
+          version of the patch - which lacked that functionality - was a progression on some arguments-
+          and closure-happy benchmarks because although no allocations were eliminated, all allocations
+          were faster.
+        
+        - There is no tear-off. The runtime no loner needs to know about where on the stack a frame keeps
+          its arguments objects or activations. The runtime doesn't have to do things to the arguments
+          objects and activations that a frame allocated, when the frame is unwound. We always had horrid
+          bugs in that code, so it's good to see it go. This removes *a ton* of machinery from the DFG,
+          FTL, CodeBlock, and other places. All of the things having to do with "captured variables" is
+          now gone. This also enables implementing block-scoping. Without this change, block-scope
+          support would require telling CodeBlock and all of the rest of the runtime about all of the
+          variables that store currently-live scopes. That would have been so disastrously hard that it
+          might as well be impossible. With this change, it's fair game for the bytecode generator to
+          simply allocate whatever activations it wants, wherever it wants, and to keep them live for
+          however long it wants. This all works, because after bytecode generation, an activation is just
+          an object and variables that refer to it are just normal variables.
+        
+        - SymbolTable can now tell you explicitly where a variable lives. The answer is in the form of a
+          VarOffset object, which has methods like isStack(), isScope(), etc. VirtualRegister is never
+          used for offsets of non-stack variables anymore. We now have shiny new objects for other kinds
+          of offsets - ScopeOffset for offsets into scopes, and DirectArgumentsOffset for offsets into
+          an arguments object.
+        
+        - Functions that create activations can now tier-up into the FTL. Previously they couldn't. Also,
+          using activations used to prevent inlining; now functions that use activations can be inlined
+          just fine.
+        
+        This is a >1% speed-up on Octane. This is a >2% speed-up on CompressionBench. This is a tiny
+        speed-up on AsmBench (~0.4% or something). This looks like it might be a speed-up on SunSpider.
+        It's only a slow-down on very short-running microbenchmarks we had previously written for our old
+        style of tear-off-based arguments optimization. Those benchmarks are not part of any major suite.
+        
+        The easiest way of understanding this change is to start by looking at the changes in runtime/,
+        and then the changes in bytecompiler/, and then sort of work your way up the compiler tiers.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/AbortReason.h:
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::BaseIndex::withOffset):
+        * bytecode/ByValInfo.h:
+        (JSC::hasOptimizableIndexingForJSType):
+        (JSC::hasOptimizableIndexing):
+        (JSC::jitArrayModeForJSType):
+        (JSC::jitArrayModePermitsPut):
+        (JSC::jitArrayModeForStructure):
+        * bytecode/BytecodeKills.h: Added.
+        (JSC::BytecodeKills::BytecodeKills):
+        (JSC::BytecodeKills::operandIsKilled):
+        (JSC::BytecodeKills::forEachOperandKilledAt):
+        (JSC::BytecodeKills::KillSet::KillSet):
+        (JSC::BytecodeKills::KillSet::add):
+        (JSC::BytecodeKills::KillSet::forEachLocal):
+        (JSC::BytecodeKills::KillSet::contains):
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeLivenessAnalysis.cpp:
+        (JSC::isValidRegisterForLiveness):
+        (JSC::stepOverInstruction):
+        (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
+        (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
+        (JSC::BytecodeLivenessAnalysis::computeKills):
+        (JSC::indexForOperand): Deleted.
+        (JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset): Deleted.
+        (JSC::getLivenessInfo): Deleted.
+        * bytecode/BytecodeLivenessAnalysis.h:
+        * bytecode/BytecodeLivenessAnalysisInlines.h:
+        (JSC::operandIsAlwaysLive):
+        (JSC::operandThatIsNotAlwaysLiveIsLive):
+        (JSC::operandIsLive):
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::nameForRegister):
+        (JSC::CodeBlock::validate):
+        (JSC::CodeBlock::isCaptured): Deleted.
+        (JSC::CodeBlock::framePointerOffsetToGetActivationRegisters): Deleted.
+        (JSC::CodeBlock::machineSlowArguments): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::unmodifiedArgumentsRegister): Deleted.
+        (JSC::CodeBlock::setArgumentsRegister): Deleted.
+        (JSC::CodeBlock::argumentsRegister): Deleted.
+        (JSC::CodeBlock::uncheckedArgumentsRegister): Deleted.
+        (JSC::CodeBlock::usesArguments): Deleted.
+        (JSC::CodeBlock::captureCount): Deleted.
+        (JSC::CodeBlock::captureStart): Deleted.
+        (JSC::CodeBlock::captureEnd): Deleted.
+        (JSC::CodeBlock::argumentIndexAfterCapture): Deleted.
+        (JSC::CodeBlock::hasSlowArguments): Deleted.
+        (JSC::ExecState::argumentAfterCapture): Deleted.
+        * bytecode/CodeOrigin.h:
+        * bytecode/DataFormat.h:
+        (JSC::dataFormatToString):
+        * bytecode/FullBytecodeLiveness.h:
+        (JSC::FullBytecodeLiveness::getLiveness):
+        (JSC::FullBytecodeLiveness::operandIsLive):
+        (JSC::FullBytecodeLiveness::FullBytecodeLiveness): Deleted.
+        (JSC::FullBytecodeLiveness::getOut): Deleted.
+        * bytecode/Instruction.h:
+        (JSC::Instruction::Instruction):
+        * bytecode/Operands.h:
+        (JSC::Operands::virtualRegisterForIndex):
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationToAbbreviatedString):
+        (JSC::speculationFromClassInfo):
+        * bytecode/SpeculatedType.h:
+        (JSC::isDirectArgumentsSpeculation):
+        (JSC::isScopedArgumentsSpeculation):
+        (JSC::isActionableMutableArraySpeculation):
+        (JSC::isActionableArraySpeculation):
+        (JSC::isArgumentsSpeculation): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setArgumentsRegister): Deleted.
+        (JSC::UnlinkedCodeBlock::usesArguments): Deleted.
+        (JSC::UnlinkedCodeBlock::argumentsRegister): Deleted.
+        * bytecode/ValueRecovery.cpp:
+        (JSC::ValueRecovery::dumpInContext):
+        * bytecode/ValueRecovery.h:
+        (JSC::ValueRecovery::directArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::outOfBandArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::nodeID):
+        (JSC::ValueRecovery::argumentsThatWereNotCreated): Deleted.
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::operator==):
+        (JSC::VirtualRegister::operator!=):
+        (JSC::VirtualRegister::operator<):
+        (JSC::VirtualRegister::operator>):
+        (JSC::VirtualRegister::operator<=):
+        (JSC::VirtualRegister::operator>=):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeNextParameter):
+        (JSC::BytecodeGenerator::visibleNameForParameter):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::variable):
+        (JSC::BytecodeGenerator::createVariable):
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitGetFromScope):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::initializeVariable):
+        (JSC::BytecodeGenerator::emitInstanceOf):
+        (JSC::BytecodeGenerator::emitNewFunction):
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitReturn):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::isArgumentNumber):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::addVar): Deleted.
+        (JSC::BytecodeGenerator::emitInitLazyRegister): Deleted.
+        (JSC::BytecodeGenerator::initializeCapturedVariable): Deleted.
+        (JSC::BytecodeGenerator::resolveCallee): Deleted.
+        (JSC::BytecodeGenerator::addCallee): Deleted.
+        (JSC::BytecodeGenerator::addParameter): Deleted.
+        (JSC::BytecodeGenerator::willResolveToArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): Deleted.
+        (JSC::BytecodeGenerator::isCaptured): Deleted.
+        (JSC::BytecodeGenerator::local): Deleted.
+        (JSC::BytecodeGenerator::constLocal): Deleted.
+        (JSC::BytecodeGenerator::emitResolveConstantLocal): Deleted.
+        (JSC::BytecodeGenerator::emitGetArgumentsLength): Deleted.
+        (JSC::BytecodeGenerator::emitGetArgumentByVal): Deleted.
+        (JSC::BytecodeGenerator::emitLazyNewFunction): Deleted.
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::Variable::Variable):
+        (JSC::Variable::isResolved):
+        (JSC::Variable::ident):
+        (JSC::Variable::offset):
+        (JSC::Variable::isLocal):
+        (JSC::Variable::local):
+        (JSC::Variable::isSpecial):
+        (JSC::BytecodeGenerator::argumentsRegister):
+        (JSC::BytecodeGenerator::emitNode):
+        (JSC::BytecodeGenerator::registerFor):
+        (JSC::Local::Local): Deleted.
+        (JSC::Local::operator bool): Deleted.
+        (JSC::Local::get): Deleted.
+        (JSC::Local::isSpecial): Deleted.
+        (JSC::ResolveScopeInfo::ResolveScopeInfo): Deleted.
+        (JSC::ResolveScopeInfo::isLocal): Deleted.
+        (JSC::ResolveScopeInfo::localIndex): Deleted.
+        (JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::captureMode): Deleted.
+        (JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly): Deleted.
+        (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): Deleted.
+        (JSC::BytecodeGenerator::hasWatchableVariable): Deleted.
+        (JSC::BytecodeGenerator::watchableVariableIdentifier): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ResolveNode::isPure):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::EvalFunctionCallNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::DeleteResolveNode::emitBytecode):
+        (JSC::TypeOfResolveNode::emitBytecode):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::ConstDeclNode::emitCodeSingle):
+        (JSC::EmptyVarExpression::emitBytecode):
+        (JSC::ForInNode::tryGetBoundLocal):
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        (JSC::BindingNode::bindValue):
+        (JSC::getArgumentByVal): Deleted.
+        * dfg/DFGAbstractHeap.h:
+        * dfg/DFGAbstractInterpreter.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberWorld):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars): Deleted.
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGArgumentPosition.h:
+        (JSC::DFG::ArgumentPosition::addVariable):
+        * dfg/DFGArgumentsEliminationPhase.cpp: Added.
+        (JSC::DFG::performArgumentsElimination):
+        * dfg/DFGArgumentsEliminationPhase.h: Added.
+        * dfg/DFGArgumentsSimplificationPhase.cpp: Removed.
+        * dfg/DFGArgumentsSimplificationPhase.h: Removed.
+        * dfg/DFGArgumentsUtilities.cpp: Added.
+        (JSC::DFG::argumentsInvolveStackSlot):
+        (JSC::DFG::emitCodeToGetArgumentsArrayLength):
+        * dfg/DFGArgumentsUtilities.h: Added.
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        (JSC::DFG::arrayTypeToString):
+        * dfg/DFGArrayMode.h:
+        (JSC::DFG::ArrayMode::canCSEStorage):
+        (JSC::DFG::ArrayMode::modeForPut):
+        * dfg/DFGAvailabilityMap.cpp:
+        (JSC::DFG::AvailabilityMap::prune):
+        * dfg/DFGAvailabilityMap.h:
+        (JSC::DFG::AvailabilityMap::closeOverNodes):
+        (JSC::DFG::AvailabilityMap::closeStartingWithLocal):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::newVariableAccessData):
+        (JSC::DFG::ByteCodeParser::getLocal):
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::getArgument):
+        (JSC::DFG::ByteCodeParser::setArgument):
+        (JSC::DFG::ByteCodeParser::flushDirect):
+        (JSC::DFG::ByteCodeParser::flush):
+        (JSC::DFG::ByteCodeParser::noticeArgumentsUse):
+        (JSC::DFG::ByteCodeParser::handleVarargsCall):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: Added.
+        (JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupportedForInlining):
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGCommonData.h:
+        (JSC::DFG::CommonData::CommonData):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::cleanVariables):
+        * dfg/DFGDisassembler.h:
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushFormat.cpp:
+        (WTF::printInternal):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::resultFor):
+        (JSC::DFG::useKindFor):
+        (JSC::DFG::dataFormatFor):
+        * dfg/DFGForAllKills.h: Added.
+        (JSC::DFG::forAllLiveNodesAtTail):
+        (JSC::DFG::forAllDirectlyKilledOperands):
+        (JSC::DFG::forAllKilledOperands):
+        (JSC::DFG::forAllKilledNodesAtNodeIndex):
+        (JSC::DFG::forAllKillsInBlock):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::substituteGetLocal):
+        (JSC::DFG::Graph::livenessFor):
+        (JSC::DFG::Graph::killsFor):
+        (JSC::DFG::Graph::tryGetConstantClosureVar):
+        (JSC::DFG::Graph::tryGetRegisters): Deleted.
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::symbolTableFor):
+        (JSC::DFG::Graph::uses):
+        (JSC::DFG::Graph::bytecodeRegisterForArgument): Deleted.
+        (JSC::DFG::Graph::capturedVarsFor): Deleted.
+        (JSC::DFG::Graph::usesArguments): Deleted.
+        (JSC::DFG::Graph::argumentsRegisterFor): Deleted.
+        (JSC::DFG::Graph::machineArgumentsRegisterFor): Deleted.
+        (JSC::DFG::Graph::uncheckedArgumentsRegisterFor): Deleted.
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGMinifiedID.h:
+        * dfg/DFGMinifiedNode.cpp:
+        (JSC::DFG::MinifiedNode::fromNode):
+        * dfg/DFGMinifiedNode.h:
+        (JSC::DFG::belongsInMinifiedGraph):
+        (JSC::DFG::MinifiedNode::hasInlineCallFrame):
+        (JSC::DFG::MinifiedNode::inlineCallFrame):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToIdentityOn):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasConstant):
+        (JSC::DFG::Node::constant):
+        (JSC::DFG::Node::hasScopeOffset):
+        (JSC::DFG::Node::scopeOffset):
+        (JSC::DFG::Node::hasDirectArgumentsOffset):
+        (JSC::DFG::Node::capturedArgumentsOffset):
+        (JSC::DFG::Node::variablePointer):
+        (JSC::DFG::Node::hasCallVarargsData):
+        (JSC::DFG::Node::hasLoadVarargsData):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::objectMaterializationData):
+        (JSC::DFG::Node::isPhantomAllocation):
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        (JSC::DFG::Node::shouldSpeculateDirectArguments):
+        (JSC::DFG::Node::shouldSpeculateScopedArguments):
+        (JSC::DFG::Node::isPhantomArguments): Deleted.
+        (JSC::DFG::Node::hasVarNumber): Deleted.
+        (JSC::DFG::Node::varNumber): Deleted.
+        (JSC::DFG::Node::registerPointer): Deleted.
+        (JSC::DFG::Node::shouldSpeculateArguments): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRExitCompiler.cpp:
+        (JSC::DFG::OSRExitCompiler::emitRestoreArguments):
+        * dfg/DFGOSRExitCompiler.h:
+        (JSC::DFG::OSRExitCompiler::badIndex): Deleted.
+        (JSC::DFG::OSRExitCompiler::initializePoisoned): Deleted.
+        (JSC::DFG::OSRExitCompiler::poisonIndex): Deleted.
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator): Deleted.
+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator): Deleted.
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): Deleted.
+        * dfg/DFGOSRExitCompilerCommon.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::read):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::write):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        (JSC::DFG::preciseLocalClobberize):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): Deleted.
+        (JSC::DFG::forEachLocalReadByUnwind): Deleted.
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::run):
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+        (JSC::DFG::PredictionPropagationPhase::propagateThroughArgumentPositions):
+        * dfg/DFGPromoteHeapAccess.h:
+        (JSC::DFG::promoteHeapAccess):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+        (JSC::DFG::SpeculativeJIT::emitGetLength):
+        (JSC::DFG::SpeculativeJIT::emitGetCallee):
+        (JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
+        (JSC::DFG::SpeculativeJIT::checkArray):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+        (JSC::DFG::SpeculativeJIT::compileNewFunction):
+        (JSC::DFG::SpeculativeJIT::compileForwardVarargs):
+        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+        (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetFromArguments):
+        (JSC::DFG::SpeculativeJIT::compilePutToArguments):
+        (JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSObjectWithKnownSize):
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+        (JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters): Deleted.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGUnificationPhase.cpp:
+        (JSC::DFG::UnificationPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * dfg/DFGValueSource.cpp:
+        (JSC::DFG::ValueSource::dump):
+        * dfg/DFGValueSource.h:
+        (JSC::DFG::dataFormatToValueSourceKind):
+        (JSC::DFG::valueSourceKindToDataFormat):
+        (JSC::DFG::ValueSource::ValueSource):
+        (JSC::DFG::ValueSource::forFlushFormat):
+        (JSC::DFG::ValueSource::valueRecovery):
+        * dfg/DFGVarargsForwardingPhase.cpp: Added.
+        (JSC::DFG::performVarargsForwarding):
+        * dfg/DFGVarargsForwardingPhase.h: Added.
+        * dfg/DFGVariableAccessData.cpp:
+        (JSC::DFG::VariableAccessData::VariableAccessData):
+        (JSC::DFG::VariableAccessData::flushFormat):
+        (JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::shouldNeverUnbox):
+        (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
+        (JSC::DFG::VariableAccessData::isCaptured): Deleted.
+        (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): Deleted.
+        (JSC::DFG::VariableAccessData::isArgumentsAlias): Deleted.
+        * dfg/DFGVariableAccessDataDump.cpp:
+        (JSC::DFG::VariableAccessDataDump::dump):
+        * dfg/DFGVariableAccessDataDump.h:
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
+        * dfg/DFGVariableEventStream.h:
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::AbstractHeap::dump):
+        (JSC::FTL::AbstractField::dump):
+        (JSC::FTL::IndexedAbstractHeap::dump):
+        (JSC::FTL::NumberedAbstractHeap::dump):
+        (JSC::FTL::AbsoluteAbstractHeap::dump):
+        * ftl/FTLAbstractHeap.h:
+        * ftl/FTLAbstractHeapRepository.cpp:
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLExitArgument.cpp:
+        (JSC::FTL::ExitArgument::dump):
+        * ftl/FTLExitPropertyValue.cpp:
+        (JSC::FTL::ExitPropertyValue::withLocalsOffset):
+        * ftl/FTLExitPropertyValue.h:
+        * ftl/FTLExitTimeObjectMaterialization.cpp:
+        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::accountForLocalsOffset):
+        * ftl/FTLExitTimeObjectMaterialization.h:
+        (JSC::FTL::ExitTimeObjectMaterialization::origin):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::withLocalsOffset):
+        (JSC::FTL::ExitValue::valueFormat):
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::isArgument):
+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated): Deleted.
+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated): Deleted.
+        (JSC::FTL::ExitValue::valueFormat): Deleted.
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCallForwardVarargs):
+        (JSC::FTL::sizeOfConstructForwardVarargs):
+        (JSC::FTL::sizeOfICFor):
+        * ftl/FTLInlineCacheSize.h:
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLJSCallVarargs.cpp:
+        (JSC::FTL::JSCallVarargs::JSCallVarargs):
+        (JSC::FTL::JSCallVarargs::emit):
+        * ftl/FTLJSCallVarargs.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStack):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateScopedArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateClonedArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
+        (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
+        (JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArgumentCount):
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
+        (JSC::FTL::LowerDFGToLLVM::compilePutClosureVar):
+        (JSC::FTL::LowerDFGToLLVM::compileGetFromArguments):
+        (JSC::FTL::LowerDFGToLLVM::compilePutToArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileForwardVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
+        (JSC::FTL::LowerDFGToLLVM::ArgumentsLength::ArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::getArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::getCurrentCallee):
+        (JSC::FTL::LowerDFGToLLVM::getArgumentsStart):
+        (JSC::FTL::LowerDFGToLLVM::baseIndex):
+        (JSC::FTL::LowerDFGToLLVM::allocateObject):
+        (JSC::FTL::LowerDFGToLLVM::allocateVariableSizedObject):
+        (JSC::FTL::LowerDFGToLLVM::isArrayType):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::loadStructure):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated): Deleted.
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileRecovery):
+        (JSC::FTL::compileStub):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::aShr):
+        (JSC::FTL::Output::lShr):
+        (JSC::FTL::Output::zeroExtPtr):
+        * heap/CopyToken.h:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::getArgumentUnsafe):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeOfVarargs):
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::unwindCallFrame):
+        * interpreter/Interpreter.h:
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        (JSC::StackVisitor::Frame::existingArguments): Deleted.
+        * interpreter/StackVisitor.h:
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        (JSC::AssemblyHelpers::loadValue):
+        (JSC::AssemblyHelpers::storeTrustedValue):
+        (JSC::AssemblyHelpers::branchIfNotCell):
+        (JSC::AssemblyHelpers::branchIsEmpty):
+        (JSC::AssemblyHelpers::argumentsStart):
+        (JSC::AssemblyHelpers::baselineArgumentsRegisterFor): Deleted.
+        (JSC::AssemblyHelpers::offsetOfLocals): Deleted.
+        (JSC::AssemblyHelpers::offsetOfArguments): Deleted.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgument):
+        * jit/GPRInfo.h:
+        (JSC::JSValueRegs::withTwoAvailableRegs):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_new_func):
+        (JSC::JIT::emit_op_create_direct_arguments):
+        (JSC::JIT::emit_op_create_scoped_arguments):
+        (JSC::JIT::emit_op_create_out_of_band_arguments):
+        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
+        (JSC::JIT::emit_op_create_arguments): Deleted.
+        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
+        (JSC::JIT::emit_op_get_arguments_length): Deleted.
+        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
+        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
+        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
+        (JSC::JIT::emit_op_create_arguments): Deleted.
+        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
+        (JSC::JIT::emit_op_get_arguments_length): Deleted.
+        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
+        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
+        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_get_from_arguments):
+        (JSC::JIT::emit_op_put_to_arguments):
+        (JSC::JIT::emit_op_init_global_const):
+        (JSC::JIT::privateCompileGetByVal):
+        (JSC::JIT::emitDirectArgumentsGetByVal):
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_get_from_arguments):
+        (JSC::JIT::emit_op_put_to_arguments):
+        (JSC::JIT::emit_op_init_global_const):
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetupVarargsFrameFastCase):
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * parser/Nodes.h:
+        (JSC::ScopeNode::captures):
+        * runtime/Arguments.cpp: Removed.
+        * runtime/Arguments.h: Removed.
+        * runtime/ArgumentsMode.h: Added.
+        * runtime/DirectArgumentsOffset.cpp: Added.
+        (JSC::DirectArgumentsOffset::dump):
+        * runtime/DirectArgumentsOffset.h: Added.
+        (JSC::DirectArgumentsOffset::DirectArgumentsOffset):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/ConstantMode.cpp: Added.
+        (WTF::printInternal):
+        * runtime/ConstantMode.h:
+        (JSC::modeForIsConstant):
+        * runtime/DirectArguments.cpp: Added.
+        (JSC::DirectArguments::DirectArguments):
+        (JSC::DirectArguments::createUninitialized):
+        (JSC::DirectArguments::create):
+        (JSC::DirectArguments::createByCopying):
+        (JSC::DirectArguments::visitChildren):
+        (JSC::DirectArguments::copyBackingStore):
+        (JSC::DirectArguments::createStructure):
+        (JSC::DirectArguments::overrideThings):
+        (JSC::DirectArguments::overrideThingsIfNecessary):
+        (JSC::DirectArguments::overrideArgument):
+        (JSC::DirectArguments::copyToArguments):
+        (JSC::DirectArguments::overridesSize):
+        * runtime/DirectArguments.h: Added.
+        (JSC::DirectArguments::internalLength):
+        (JSC::DirectArguments::length):
+        (JSC::DirectArguments::canAccessIndexQuickly):
+        (JSC::DirectArguments::getIndexQuickly):
+        (JSC::DirectArguments::setIndexQuickly):
+        (JSC::DirectArguments::callee):
+        (JSC::DirectArguments::argument):
+        (JSC::DirectArguments::overrodeThings):
+        (JSC::DirectArguments::offsetOfCallee):
+        (JSC::DirectArguments::offsetOfLength):
+        (JSC::DirectArguments::offsetOfMinCapacity):
+        (JSC::DirectArguments::offsetOfOverrides):
+        (JSC::DirectArguments::storageOffset):
+        (JSC::DirectArguments::offsetOfSlot):
+        (JSC::DirectArguments::allocationSize):
+        (JSC::DirectArguments::storage):
+        * runtime/FunctionPrototype.cpp:
+        * runtime/GenericArguments.h: Added.
+        (JSC::GenericArguments::GenericArguments):
+        * runtime/GenericArgumentsInlines.h: Added.
+        (JSC::GenericArguments<Type>::getOwnPropertySlot):
+        (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
+        (JSC::GenericArguments<Type>::getOwnPropertyNames):
+        (JSC::GenericArguments<Type>::put):
+        (JSC::GenericArguments<Type>::putByIndex):
+        (JSC::GenericArguments<Type>::deleteProperty):
+        (JSC::GenericArguments<Type>::deletePropertyByIndex):
+        (JSC::GenericArguments<Type>::defineOwnProperty):
+        (JSC::GenericArguments<Type>::copyToArguments):
+        * runtime/GenericOffset.h: Added.
+        (JSC::GenericOffset::GenericOffset):
+        (JSC::GenericOffset::operator!):
+        (JSC::GenericOffset::offsetUnchecked):
+        (JSC::GenericOffset::offset):
+        (JSC::GenericOffset::operator==):
+        (JSC::GenericOffset::operator!=):
+        (JSC::GenericOffset::operator<):
+        (JSC::GenericOffset::operator>):
+        (JSC::GenericOffset::operator<=):
+        (JSC::GenericOffset::operator>=):
+        (JSC::GenericOffset::operator+):
+        (JSC::GenericOffset::operator-):
+        (JSC::GenericOffset::operator+=):
+        (JSC::GenericOffset::operator-=):
+        * runtime/JSArgumentsIterator.cpp:
+        (JSC::JSArgumentsIterator::finishCreation):
+        (JSC::argumentsFuncIterator):
+        * runtime/JSArgumentsIterator.h:
+        (JSC::JSArgumentsIterator::create):
+        (JSC::JSArgumentsIterator::next):
+        * runtime/JSEnvironmentRecord.cpp:
+        (JSC::JSEnvironmentRecord::visitChildren):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::variables):
+        (JSC::JSEnvironmentRecord::isValid):
+        (JSC::JSEnvironmentRecord::variableAt):
+        (JSC::JSEnvironmentRecord::offsetOfVariables):
+        (JSC::JSEnvironmentRecord::offsetOfVariable):
+        (JSC::JSEnvironmentRecord::allocationSizeForScopeSize):
+        (JSC::JSEnvironmentRecord::allocationSize):
+        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
+        (JSC::JSEnvironmentRecord::finishCreationUninitialized):
+        (JSC::JSEnvironmentRecord::finishCreation):
+        (JSC::JSEnvironmentRecord::registers): Deleted.
+        (JSC::JSEnvironmentRecord::registerAt): Deleted.
+        (JSC::JSEnvironmentRecord::addressOfRegisters): Deleted.
+        (JSC::JSEnvironmentRecord::offsetOfRegisters): Deleted.
+        * runtime/JSFunction.cpp:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        (JSC::JSGlobalObject::visitChildren):
+        (JSC::JSGlobalObject::addStaticGlobals):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::directArgumentsStructure):
+        (JSC::JSGlobalObject::scopedArgumentsStructure):
+        (JSC::JSGlobalObject::outOfBandArgumentsStructure):
+        (JSC::JSGlobalObject::argumentsStructure): Deleted.
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::symbolTableGet):
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        (JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
+        (JSC::JSLexicalEnvironment::visitChildren): Deleted.
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        (JSC::JSLexicalEnvironment::registersOffset): Deleted.
+        (JSC::JSLexicalEnvironment::storageOffset): Deleted.
+        (JSC::JSLexicalEnvironment::storage): Deleted.
+        (JSC::JSLexicalEnvironment::allocationSize): Deleted.
+        (JSC::JSLexicalEnvironment::isValidIndex): Deleted.
+        (JSC::JSLexicalEnvironment::isValid): Deleted.
+        (JSC::JSLexicalEnvironment::registerAt): Deleted.
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::visitChildren): Deleted.
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::value):
+        (JSC::JSNameScope::finishCreation):
+        (JSC::JSNameScope::JSNameScope):
+        * runtime/JSScope.cpp:
+        (JSC::abstractAccess):
+        * runtime/JSSegmentedVariableObject.cpp:
+        (JSC::JSSegmentedVariableObject::findVariableIndex):
+        (JSC::JSSegmentedVariableObject::addVariables):
+        (JSC::JSSegmentedVariableObject::visitChildren):
+        (JSC::JSSegmentedVariableObject::findRegisterIndex): Deleted.
+        (JSC::JSSegmentedVariableObject::addRegisters): Deleted.
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::variableAt):
+        (JSC::JSSegmentedVariableObject::assertVariableIsInThisObject):
+        (JSC::JSSegmentedVariableObject::registerAt): Deleted.
+        (JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): Deleted.
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::offsetOfSymbolTable):
+        (JSC::symbolTableGet):
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/JSType.h:
+        * runtime/Options.h:
+        * runtime/ClonedArguments.cpp: Added.
+        (JSC::ClonedArguments::ClonedArguments):
+        (JSC::ClonedArguments::createEmpty):
+        (JSC::ClonedArguments::createWithInlineFrame):
+        (JSC::ClonedArguments::createWithMachineFrame):
+        (JSC::ClonedArguments::createByCopyingFrom):
+        (JSC::ClonedArguments::createStructure):
+        (JSC::ClonedArguments::getOwnPropertySlot):
+        (JSC::ClonedArguments::getOwnPropertyNames):
+        (JSC::ClonedArguments::put):
+        (JSC::ClonedArguments::deleteProperty):
+        (JSC::ClonedArguments::defineOwnProperty):
+        (JSC::ClonedArguments::materializeSpecials):
+        (JSC::ClonedArguments::materializeSpecialsIfNecessary):
+        * runtime/ClonedArguments.h: Added.
+        (JSC::ClonedArguments::specialsMaterialized):
+        * runtime/ScopeOffset.cpp: Added.
+        (JSC::ScopeOffset::dump):
+        * runtime/ScopeOffset.h: Added.
+        (JSC::ScopeOffset::ScopeOffset):
+        * runtime/ScopedArguments.cpp: Added.
+        (JSC::ScopedArguments::ScopedArguments):
+        (JSC::ScopedArguments::finishCreation):
+        (JSC::ScopedArguments::createUninitialized):
+        (JSC::ScopedArguments::create):
+        (JSC::ScopedArguments::createByCopying):
+        (JSC::ScopedArguments::createByCopyingFrom):
+        (JSC::ScopedArguments::visitChildren):
+        (JSC::ScopedArguments::createStructure):
+        (JSC::ScopedArguments::overrideThings):
+        (JSC::ScopedArguments::overrideThingsIfNecessary):
+        (JSC::ScopedArguments::overrideArgument):
+        (JSC::ScopedArguments::copyToArguments):
+        * runtime/ScopedArguments.h: Added.
+        (JSC::ScopedArguments::internalLength):
+        (JSC::ScopedArguments::length):
+        (JSC::ScopedArguments::canAccessIndexQuickly):
+        (JSC::ScopedArguments::getIndexQuickly):
+        (JSC::ScopedArguments::setIndexQuickly):
+        (JSC::ScopedArguments::callee):
+        (JSC::ScopedArguments::overrodeThings):
+        (JSC::ScopedArguments::offsetOfOverrodeThings):
+        (JSC::ScopedArguments::offsetOfTotalLength):
+        (JSC::ScopedArguments::offsetOfTable):
+        (JSC::ScopedArguments::offsetOfScope):
+        (JSC::ScopedArguments::overflowStorageOffset):
+        (JSC::ScopedArguments::allocationSize):
+        (JSC::ScopedArguments::overflowStorage):
+        * runtime/ScopedArgumentsTable.cpp: Added.
+        (JSC::ScopedArgumentsTable::ScopedArgumentsTable):
+        (JSC::ScopedArgumentsTable::~ScopedArgumentsTable):
+        (JSC::ScopedArgumentsTable::destroy):
+        (JSC::ScopedArgumentsTable::create):
+        (JSC::ScopedArgumentsTable::clone):
+        (JSC::ScopedArgumentsTable::setLength):
+        (JSC::ScopedArgumentsTable::set):
+        (JSC::ScopedArgumentsTable::createStructure):
+        * runtime/ScopedArgumentsTable.h: Added.
+        (JSC::ScopedArgumentsTable::length):
+        (JSC::ScopedArgumentsTable::get):
+        (JSC::ScopedArgumentsTable::lock):
+        (JSC::ScopedArgumentsTable::offsetOfLength):
+        (JSC::ScopedArgumentsTable::offsetOfArguments):
+        (JSC::ScopedArgumentsTable::at):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::prepareToWatch):
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::visitChildren):
+        (JSC::SymbolTable::localToEntry):
+        (JSC::SymbolTable::entryFor):
+        (JSC::SymbolTable::cloneScopePart):
+        (JSC::SymbolTable::prepareForTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForOffset):
+        (JSC::SymbolTable::globalTypeSetForOffset):
+        (JSC::SymbolTable::cloneCapturedNames): Deleted.
+        (JSC::SymbolTable::uniqueIDForRegister): Deleted.
+        (JSC::SymbolTable::globalTypeSetForRegister): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTableEntry::varOffsetFromBits):
+        (JSC::SymbolTableEntry::scopeOffsetFromBits):
+        (JSC::SymbolTableEntry::Fast::varOffset):
+        (JSC::SymbolTableEntry::Fast::scopeOffset):
+        (JSC::SymbolTableEntry::Fast::isDontEnum):
+        (JSC::SymbolTableEntry::Fast::getAttributes):
+        (JSC::SymbolTableEntry::SymbolTableEntry):
+        (JSC::SymbolTableEntry::varOffset):
+        (JSC::SymbolTableEntry::isWatchable):
+        (JSC::SymbolTableEntry::scopeOffset):
+        (JSC::SymbolTableEntry::setAttributes):
+        (JSC::SymbolTableEntry::constantMode):
+        (JSC::SymbolTableEntry::isDontEnum):
+        (JSC::SymbolTableEntry::disableWatching):
+        (JSC::SymbolTableEntry::pack):
+        (JSC::SymbolTableEntry::isValidVarOffset):
+        (JSC::SymbolTable::createNameScopeTable):
+        (JSC::SymbolTable::maxScopeOffset):
+        (JSC::SymbolTable::didUseScopeOffset):
+        (JSC::SymbolTable::didUseVarOffset):
+        (JSC::SymbolTable::scopeSize):
+        (JSC::SymbolTable::nextScopeOffset):
+        (JSC::SymbolTable::takeNextScopeOffset):
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        (JSC::SymbolTable::argumentsLength):
+        (JSC::SymbolTable::setArgumentsLength):
+        (JSC::SymbolTable::argumentOffset):
+        (JSC::SymbolTable::setArgumentOffset):
+        (JSC::SymbolTable::arguments):
+        (JSC::SlowArgument::SlowArgument): Deleted.
+        (JSC::SymbolTableEntry::Fast::getIndex): Deleted.
+        (JSC::SymbolTableEntry::getIndex): Deleted.
+        (JSC::SymbolTableEntry::isValidIndex): Deleted.
+        (JSC::SymbolTable::captureStart): Deleted.
+        (JSC::SymbolTable::setCaptureStart): Deleted.
+        (JSC::SymbolTable::captureEnd): Deleted.
+        (JSC::SymbolTable::setCaptureEnd): Deleted.
+        (JSC::SymbolTable::captureCount): Deleted.
+        (JSC::SymbolTable::isCaptured): Deleted.
+        (JSC::SymbolTable::parameterCount): Deleted.
+        (JSC::SymbolTable::parameterCountIncludingThis): Deleted.
+        (JSC::SymbolTable::setParameterCountIncludingThis): Deleted.
+        (JSC::SymbolTable::slowArguments): Deleted.
+        (JSC::SymbolTable::setSlowArguments): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * runtime/VarOffset.cpp: Added.
+        (JSC::VarOffset::dump):
+        (WTF::printInternal):
+        * runtime/VarOffset.h: Added.
+        (JSC::VarOffset::VarOffset):
+        (JSC::VarOffset::assemble):
+        (JSC::VarOffset::isValid):
+        (JSC::VarOffset::operator!):
+        (JSC::VarOffset::kind):
+        (JSC::VarOffset::isStack):
+        (JSC::VarOffset::isScope):
+        (JSC::VarOffset::isDirectArgument):
+        (JSC::VarOffset::stackOffsetUnchecked):
+        (JSC::VarOffset::scopeOffsetUnchecked):
+        (JSC::VarOffset::capturedArgumentsOffsetUnchecked):
+        (JSC::VarOffset::stackOffset):
+        (JSC::VarOffset::scopeOffset):
+        (JSC::VarOffset::capturedArgumentsOffset):
+        (JSC::VarOffset::rawOffset):
+        (JSC::VarOffset::checkSanity):
+        (JSC::VarOffset::operator==):
+        (JSC::VarOffset::operator!=):
+        (JSC::VarOffset::hash):
+        (JSC::VarOffset::isHashTableDeletedValue):
+        (JSC::VarOffsetHash::hash):
+        (JSC::VarOffsetHash::equal):
+        * tests/stress/arguments-exit-strict-mode.js: Added.
+        * tests/stress/arguments-exit.js: Added.
+        * tests/stress/arguments-inlined-exit-strict-mode-fixed.js: Added.
+        * tests/stress/arguments-inlined-exit-strict-mode.js: Added.
+        * tests/stress/arguments-inlined-exit.js: Added.
+        * tests/stress/arguments-interference.js: Added.
+        * tests/stress/arguments-interference-cfg.js: Added.
+        * tests/stress/dead-get-closure-var.js: Added.
+        * tests/stress/get-declared-unpassed-argument-in-direct-arguments.js: Added.
+        * tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js: Added.
+        * tests/stress/varargs-closure-inlined-exit-strict-mode.js: Added.
+        * tests/stress/varargs-closure-inlined-exit.js: Added.
+        * tests/stress/varargs-exit.js: Added.
+        * tests/stress/varargs-inlined-exit.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing-weird.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing.js: Added.
+        * tests/stress/varargs-inlined-simple-exit.js: Added.
+        * tests/stress/varargs-too-few-arguments.js: Added.
+        * tests/stress/varargs-varargs-closure-inlined-exit.js: Added.
+        * tests/stress/varargs-varargs-inlined-exit-strict-mode.js: Added.
+        * tests/stress/varargs-varargs-inlined-exit.js: Added.
+
+2015-03-25  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] RemoteInspectorXPCConnection::deserializeMessage() leaks a NSDictionary under Objective-C GC
+        https://bugs.webkit.org/show_bug.cgi?id=143068
+
+        Reviewed by Dan Bernstein.
+
+        * inspector/remote/RemoteInspectorXPCConnection.mm:
+        (Inspector::RemoteInspectorXPCConnection::deserializeMessage): Used RetainPtr::autorelease(), which does the right thing under GC.
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Use JITCompilationCanFail in more places, and make the fail path of JITCompilationMustSucceed a crash instead of attempting GC
+        https://bugs.webkit.org/show_bug.cgi?id=142993
+
+        Reviewed by Geoffrey Garen and Mark Lam.
+        
+        This changes the most commonly invoked paths that relied on JITCompilationMustSucceed
+        into using JITCompilationCanFail and having a legit fallback path. This mostly involves
+        having the FTL JIT do the same trick as the DFG JIT in case of any memory allocation
+        failure, but also involves adding the same kind of thing to the stub generators in
+        Repatch.
+        
+        Because of that change, there are relatively few uses of JITCompilationMustSucceed. Most
+        of those uses cannot handle a GC, and so cannot do releaseExecutableMemory(). Only a few,
+        like host call stub generation, could handle a GC, but those get invoked very rarely. So,
+        this patch changes the releaseExecutableMemory() call into a crash with some diagnostic
+        printout.
+        
+        Also add a way of inducing executable allocation failure, so that we can test this.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compile):
+        (JSC::DFG::JITCompiler::compileFunction):
+        (JSC::DFG::JITCompiler::link): Deleted.
+        (JSC::DFG::JITCompiler::linkFunction): Deleted.
+        * dfg/DFGJITCompiler.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateCodeSection):
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLState.h:
+        * jit/ArityCheckFailReturnThunks.cpp:
+        (JSC::ArityCheckFailReturnThunks::returnPCsFor):
+        * jit/ExecutableAllocationFuzz.cpp: Added.
+        (JSC::numberOfExecutableAllocationFuzzChecks):
+        (JSC::doExecutableAllocationFuzzing):
+        * jit/ExecutableAllocationFuzz.h: Added.
+        (JSC::doExecutableAllocationFuzzingIfEnabled):
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+        (JSC::ExecutableAllocator::allocate):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITCompilationEffort.h:
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::emitPutReplaceStub):
+        (JSC::emitPutTransitionStubAndGetOldStructure):
+        (JSC::tryCachePutByID):
+        (JSC::tryBuildPutByIdList):
+        (JSC::tryRepatchIn):
+        (JSC::linkPolymorphicCall):
+        * jsc.cpp:
+        (jscmain):
+        * runtime/Options.h:
+        * runtime/TestRunnerUtils.h:
+        * runtime/VM.cpp:
+        * tests/executableAllocationFuzz: Added.
+        * tests/executableAllocationFuzz.yaml: Added.
+        * tests/executableAllocationFuzz/v8-raytrace.js: Added.
+
+2015-03-25  Mark Lam  <mark.lam@apple.com>
+
+        REGRESSION(169139): LLINT intermittently fails JSC testapi tests.
+        <https://webkit.org/b/135719>
+
+        Reviewed by Geoffrey Garen.
+
+        This is a regression introduced in http://trac.webkit.org/changeset/169139 which
+        changed VM::watchdog from an embedded field into a std::unique_ptr, but did not
+        update the LLINT to access it as such.
+
+        The issue has only manifested so far on the CLoop tests because those are LLINT
+        only.  In the non-CLoop cases, the JIT kicks in and does the right thing, thereby
+        hiding the bug in the LLINT.
+
+        * API/JSContextRef.cpp:
+        (createWatchdogIfNeeded):
+        (JSContextGroupSetExecutionTimeLimit):
+        (JSContextGroupClearExecutionTimeLimit):
+        * llint/LowLevelInterpreter.asm:
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Change Atomic methods from using the_wrong_naming_conventions to using theRightNamingConventions. Also make seq_cst the default.
+
+        Rubber stamped by Geoffrey Garen.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::visitAggregate):
+
+2015-03-25  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix formatting in BuiltinExecutables
+        https://bugs.webkit.org/show_bug.cgi?id=143061
+
+        Reviewed by Ryosuke Niwa.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutableInternal):
+
+2015-03-25  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Classes: Program level class statement throws exception in strict mode
+        https://bugs.webkit.org/show_bug.cgi?id=143038
+
+        Reviewed by Ryosuke Niwa.
+
+        Classes expose a name to the current lexical environment. This treats
+        "class X {}" like "var X = class X {}". Ideally it would be "let X = class X {}".
+        Also, improve error messages for class statements where the class is missing a name.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        Fill name in info parameter if needed. Better error message if name is needed and missing.
+
+        (JSC::Parser<LexerType>::parseClassDeclaration):
+        Pass info parameter to get name, and expose the name as a variable name.
+
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        Pass info parameter that is ignored.
+
+        * parser/ParserFunctionInfo.h:
+        Add a parser info for class, to extract the name.
+
+2015-03-25  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        New map and set modification tests in r181922 fails
+        https://bugs.webkit.org/show_bug.cgi?id=143031
+
+        Reviewed and tweaked by Geoffrey Garen.
+
+        When packing Map/Set backing store, we need to decrement Map/Set iterator's m_index
+        to adjust for the packed backing store.
+
+        Consider the following map data.
+
+        x: deleted, o: exists
+        0 1 2 3 4
+        x x x x o
+
+        And iterator with m_index 3.
+
+        When packing the map data, map data will become,
+
+        0
+        o
+
+        At that time, we perfom didRemoveEntry 4 times on iterators.
+        times => m_index/index/result
+        1 => 3/0/dec
+        2 => 2/1/dec
+        3 => 1/2/nothing
+        4 => 1/3/nothing
+
+        After iteration, iterator's m_index becomes 1. But we expected that becomes 0.
+        This is because if we use decremented m_index for comparison,
+        while provided deletedIndex is the index in old storage, m_index is the index in partially packed storage.
+
+        In this patch, we compare against the packed index instead.
+        times => m_index/packedIndex/result
+        1 => 3/0/dec
+        2 => 2/0/dec
+        3 => 1/0/dec
+        4 => 0/0/nothing
+
+        So m_index becomes 0 as expected.
+
+        And according to the spec, once the iterator is closed (becomes done: true),
+        its internal [[Map]]/[[Set]] is set to undefined.
+        So after the iterator is finished, we don't revive the iterator (e.g. by clearing m_index = 0).
+
+        In this patch, we change 2 things.
+        1.
+        Compare an iterator's index against the packed index when removing an entry.
+
+        2.
+        If the iterator is closed (isFinished()), we don't apply adjustment to the iterator.
+
+        * runtime/MapData.h:
+        (JSC::MapDataImpl::IteratorData::finish):
+        (JSC::MapDataImpl::IteratorData::isFinished):
+        (JSC::MapDataImpl::IteratorData::didRemoveEntry):
+        (JSC::MapDataImpl::IteratorData::didRemoveAllEntries):
+        (JSC::MapDataImpl::IteratorData::startPackBackingStore):
+        * runtime/MapDataInlines.h:
+        (JSC::JSIterator>::replaceAndPackBackingStore):
+        * tests/stress/modify-map-during-iteration.js:
+        * tests/stress/modify-set-during-iteration.js:
+
+2015-03-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Setter should have a single formal parameter, Getter no parameters
+        https://bugs.webkit.org/show_bug.cgi?id=142903
+
+        Reviewed by Geoffrey Garen.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        Enforce no parameters for getters and a single parameter
+        for setters, with informational error messages.
+
+2015-03-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Classes: Early return in sub-class constructor results in returning undefined instead of instance
+        https://bugs.webkit.org/show_bug.cgi?id=143012
+
+        Reviewed by Ryosuke Niwa.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitReturn):
+        Fix handling of "undefined" when returned from a Derived class. It was
+        returning "undefined" when it should have returned "this".
+
+2015-03-24  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION (r181458): Heap use-after-free in JSSetIterator destructor
+        https://bugs.webkit.org/show_bug.cgi?id=142696
+
+        Reviewed and tweaked by Geoffrey Garen.
+
+        Before r142556, JSSetIterator::destroy was not defined.
+        So accidentally MapData::const_iterator in JSSet was never destroyed.
+        But it had non trivial destructor, decrementing MapData->m_iteratorCount.
+
+        After r142556, JSSetIterator::destroy works.
+        It correctly destruct MapData::const_iterator and m_iteratorCount partially works.
+        But JSSetIterator::~JSSetIterator requires owned JSSet since it mutates MapData->m_iteratorCount.
+
+        It is guaranteed that JSSet is live since JSSetIterator has a reference to JSSet
+        and marks it in visitChildren (WriteBarrier<Unknown>).
+        However, the order of destructions is not guaranteed in GC-ed system.
+
+        Consider the following case,
+        allocate JSSet and subsequently allocate JSSetIterator.
+        And they resides in the separated MarkedBlock, <1> and <2>.
+
+        JSSet<1> <- JSSetIterator<2>
+
+        And after that, when performing GC, Marker decides that the above 2 objects are not marked.
+        And Marker also decides MarkedBlocks <1> and <2> can be sweeped.
+
+        First Sweeper sweep <1>, destruct JSSet<1> and free MarkedBlock<1>.
+        Second Sweeper sweep <2>, attempt to destruct JSSetIterator<2>.
+        However, JSSetIterator<2>'s destructor,
+        JSSetIterator::~JSSetIterator requires live JSSet<1>, it causes use-after-free.
+
+        In this patch, we introduce WeakGCMap into JSMap/JSSet to track live iterators.
+        When packing the removed elements in JSSet/JSMap, we apply the change to all live
+        iterators tracked by WeakGCMap.
+
+        WeakGCMap can only track JSCell since they are managed by GC.
+        So we drop JSSet/JSMap C++ style iterators. Instead of C++ style iterator, this patch
+        introduces JS style iterator signatures into C++ class IteratorData.
+        If we need to iterate over JSMap/JSSet, use JSSetIterator/JSMapIterator instead of using
+        IteratorData directly.
+
+        * runtime/JSMap.cpp:
+        (JSC::JSMap::destroy):
+        * runtime/JSMap.h:
+        (JSC::JSMap::JSMap):
+        (JSC::JSMap::begin): Deleted.
+        (JSC::JSMap::end): Deleted.
+        * runtime/JSMapIterator.cpp:
+        (JSC::JSMapIterator::destroy):
+        * runtime/JSMapIterator.h:
+        (JSC::JSMapIterator::next):
+        (JSC::JSMapIterator::nextKeyValue):
+        (JSC::JSMapIterator::iteratorData):
+        (JSC::JSMapIterator::JSMapIterator):
+        * runtime/JSSet.cpp:
+        (JSC::JSSet::destroy):
+        * runtime/JSSet.h:
+        (JSC::JSSet::JSSet):
+        (JSC::JSSet::begin): Deleted.
+        (JSC::JSSet::end): Deleted.
+        * runtime/JSSetIterator.cpp:
+        (JSC::JSSetIterator::destroy):
+        * runtime/JSSetIterator.h:
+        (JSC::JSSetIterator::next):
+        (JSC::JSSetIterator::iteratorData):
+        (JSC::JSSetIterator::JSSetIterator):
+        * runtime/MapData.h:
+        (JSC::MapDataImpl::IteratorData::finish):
+        (JSC::MapDataImpl::IteratorData::isFinished):
+        (JSC::MapDataImpl::shouldPack):
+        (JSC::JSIterator>::MapDataImpl):
+        (JSC::JSIterator>::KeyType::KeyType):
+        (JSC::JSIterator>::IteratorData::IteratorData):
+        (JSC::JSIterator>::IteratorData::next):
+        (JSC::JSIterator>::IteratorData::ensureSlot):
+        (JSC::JSIterator>::IteratorData::applyMapDataPatch):
+        (JSC::JSIterator>::IteratorData::refreshCursor):
+        (JSC::MapDataImpl::const_iterator::key): Deleted.
+        (JSC::MapDataImpl::const_iterator::value): Deleted.
+        (JSC::MapDataImpl::const_iterator::operator++): Deleted.
+        (JSC::MapDataImpl::const_iterator::finish): Deleted.
+        (JSC::MapDataImpl::const_iterator::atEnd): Deleted.
+        (JSC::MapDataImpl::begin): Deleted.
+        (JSC::MapDataImpl::end): Deleted.
+        (JSC::MapDataImpl<Entry>::MapDataImpl): Deleted.
+        (JSC::MapDataImpl<Entry>::clear): Deleted.
+        (JSC::MapDataImpl<Entry>::KeyType::KeyType): Deleted.
+        (JSC::MapDataImpl<Entry>::const_iterator::internalIncrement): Deleted.
+        (JSC::MapDataImpl<Entry>::const_iterator::ensureSlot): Deleted.
+        (JSC::MapDataImpl<Entry>::const_iterator::const_iterator): Deleted.
+        (JSC::MapDataImpl<Entry>::const_iterator::~const_iterator): Deleted.
+        (JSC::MapDataImpl<Entry>::const_iterator::operator): Deleted.
+        (JSC::=): Deleted.
+        * runtime/MapDataInlines.h:
+        (JSC::JSIterator>::clear):
+        (JSC::JSIterator>::find):
+        (JSC::JSIterator>::contains):
+        (JSC::JSIterator>::add):
+        (JSC::JSIterator>::set):
+        (JSC::JSIterator>::get):
+        (JSC::JSIterator>::remove):
+        (JSC::JSIterator>::replaceAndPackBackingStore):
+        (JSC::JSIterator>::replaceBackingStore):
+        (JSC::JSIterator>::ensureSpaceForAppend):
+        (JSC::JSIterator>::visitChildren):
+        (JSC::JSIterator>::copyBackingStore):
+        (JSC::JSIterator>::applyMapDataPatch):
+        (JSC::MapDataImpl<Entry>::find): Deleted.
+        (JSC::MapDataImpl<Entry>::contains): Deleted.
+        (JSC::MapDataImpl<Entry>::add): Deleted.
+        (JSC::MapDataImpl<Entry>::set): Deleted.
+        (JSC::MapDataImpl<Entry>::get): Deleted.
+        (JSC::MapDataImpl<Entry>::remove): Deleted.
+        (JSC::MapDataImpl<Entry>::replaceAndPackBackingStore): Deleted.
+        (JSC::MapDataImpl<Entry>::replaceBackingStore): Deleted.
+        (JSC::MapDataImpl<Entry>::ensureSpaceForAppend): Deleted.
+        (JSC::MapDataImpl<Entry>::visitChildren): Deleted.
+        (JSC::MapDataImpl<Entry>::copyBackingStore): Deleted.
+        * runtime/MapPrototype.cpp:
+        (JSC::mapProtoFuncForEach):
+        * runtime/SetPrototype.cpp:
+        (JSC::setProtoFuncForEach):
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::forEach):
+        * tests/stress/modify-map-during-iteration.js: Added.
+        (testValue):
+        (identityPairs):
+        (.set if):
+        (var):
+        (set map):
+        * tests/stress/modify-set-during-iteration.js: Added.
+        (testValue):
+        (set forEach):
+        (set delete):
+
+2015-03-24  Mark Lam  <mark.lam@apple.com>
+
+        The ExecutionTimeLimit test should use its own JSGlobalContextRef.
+        <https://webkit.org/b/143024>
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, the ExecutionTimeLimit test is using a JSGlobalContextRef
+        passed in from testapi.c.  It should create its own for better
+        encapsulation of the test.
+
+        * API/tests/ExecutionTimeLimitTest.cpp:
+        (currentCPUTimeAsJSFunctionCallback):
+        (testExecutionTimeLimit):
+        * API/tests/ExecutionTimeLimitTest.h:
+        * API/tests/testapi.c:
+        (main):
+
+2015-03-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Object Literal Methods toString is missing method name
+        https://bugs.webkit.org/show_bug.cgi?id=142992
+
+        Reviewed by Geoffrey Garen.
+
+        Always stringify functions in the pattern:
+
+          "function " + <function name> + <text from opening parenthesis to closing brace>.
+
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString):
+        Update the path that was not stringifying in this pattern.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::parametersStartOffset):
+        * parser/Nodes.h:
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::FunctionExecutable):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::parametersStartOffset):
+        Pass the already known function parameter opening parenthesis
+        start offset through to the FunctionExecutable. 
+
+        * tests/mozilla/js1_5/Scope/regress-185485.js:
+        (with.g):
+        Add back original space in this test that was removed by r181810
+        now that we have the space again in stringification.
+
+2015-03-24  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (172175-172177): Change in for...in processing causes properties added in loop to be enumerated
+        https://bugs.webkit.org/show_bug.cgi?id=142856
+
+        Reviewed by Filip Pizlo.
+
+        Refactored the way the for .. in enumeration over objects is done.  We used to make three C++ calls to
+        get info for three loops to iterate over indexed properties, structure properties and other properties,
+        respectively.  We still have the three loops, but now we make one C++ call to get all the info needed
+        for all loops before we exectue any enumeration.
+
+        The JSPropertyEnumerator has a count of the indexed properties and a list of named properties.
+        The named properties are one list, with structured properties in the range [0,m_endStructurePropertyIndex)
+        and the generic properties in the range [m_endStructurePropertyIndex, m_endGenericPropertyIndex);
+
+        Eliminated the bytecodes op_get_structure_property_enumerator, op_get_generic_property_enumerator and
+        op_next_enumerator_pname.
+        Added the bytecodes op_get_property_enumerator, op_enumerator_structure_pname and op_enumerator_generic_pname.
+        The bytecodes op_enumerator_structure_pname and op_enumerator_generic_pname are similar except for what
+        end value we stop iterating on.
+
+        Made corresponding node changes to the DFG and FTL for the bytecode changes.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetPropertyEnumerator):
+        (JSC::BytecodeGenerator::emitEnumeratorStructurePropertyName):
+        (JSC::BytecodeGenerator::emitEnumeratorGenericPropertyName):
+        (JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): Deleted.
+        (JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): Deleted.
+        (JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetPropertyEnumerator):
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorStructurePname):
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorGenericPname):
+        (JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_enumerator_structure_pname):
+        (JSC::JIT::emit_op_enumerator_generic_pname):
+        (JSC::JIT::emit_op_get_property_enumerator):
+        (JSC::JIT::emit_op_next_enumerator_pname): Deleted.
+        (JSC::JIT::emit_op_get_structure_property_enumerator): Deleted.
+        (JSC::JIT::emit_op_get_generic_property_enumerator): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_enumerator_structure_pname):
+        (JSC::JIT::emit_op_enumerator_generic_pname):
+        (JSC::JIT::emit_op_next_enumerator_pname): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/JSPropertyNameEnumerator.cpp:
+        (JSC::JSPropertyNameEnumerator::create):
+        (JSC::JSPropertyNameEnumerator::finishCreation):
+        * runtime/JSPropertyNameEnumerator.h:
+        (JSC::JSPropertyNameEnumerator::indexedLength):
+        (JSC::JSPropertyNameEnumerator::endStructurePropertyIndex):
+        (JSC::JSPropertyNameEnumerator::endGenericPropertyIndex):
+        (JSC::JSPropertyNameEnumerator::indexedLengthOffset):
+        (JSC::JSPropertyNameEnumerator::endStructurePropertyIndexOffset):
+        (JSC::JSPropertyNameEnumerator::endGenericPropertyIndexOffset):
+        (JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset):
+        (JSC::propertyNameEnumerator):
+        (JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): Deleted.
+        (JSC::structurePropertyNameEnumerator): Deleted.
+        (JSC::genericPropertyNameEnumerator): Deleted.
+        * runtime/Structure.cpp:
+        (JSC::Structure::setCachedPropertyNameEnumerator):
+        (JSC::Structure::cachedPropertyNameEnumerator):
+        (JSC::Structure::canCachePropertyNameEnumerator):
+        (JSC::Structure::setCachedStructurePropertyNameEnumerator): Deleted.
+        (JSC::Structure::cachedStructurePropertyNameEnumerator): Deleted.
+        (JSC::Structure::setCachedGenericPropertyNameEnumerator): Deleted.
+        (JSC::Structure::cachedGenericPropertyNameEnumerator): Deleted.
+        (JSC::Structure::canCacheStructurePropertyNameEnumerator): Deleted.
+        (JSC::Structure::canCacheGenericPropertyNameEnumerator): Deleted.
+        * runtime/Structure.h:
+        * runtime/StructureRareData.cpp:
+        (JSC::StructureRareData::visitChildren):
+        (JSC::StructureRareData::cachedPropertyNameEnumerator):
+        (JSC::StructureRareData::setCachedPropertyNameEnumerator):
+        (JSC::StructureRareData::cachedStructurePropertyNameEnumerator): Deleted.
+        (JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): Deleted.
+        (JSC::StructureRareData::cachedGenericPropertyNameEnumerator): Deleted.
+        (JSC::StructureRareData::setCachedGenericPropertyNameEnumerator): Deleted.
+        * runtime/StructureRareData.h:
+        * tests/stress/for-in-delete-during-iteration.js:
+
+2015-03-24  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewed build fix for debug builds.
+
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::invalidParameterInSourceAppender):
+
+2015-03-24  Saam Barati  <saambarati1@gmail.com>
+
+        Improve error messages in JSC
+        https://bugs.webkit.org/show_bug.cgi?id=141869
+
+        Reviewed by Geoffrey Garen.
+
+        JavaScriptCore has some unintuitive error messages associated
+        with certain common errors. This patch changes some specific
+        error messages to be more understandable and also creates a
+        mechanism that will allow for easy modification of error messages
+        in the future. The specific errors we change are not a function
+        errors and invalid parameter errors.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeOfVarargs):
+        * jit/JITOperations.cpp:
+        op_throw_static_error always has a JSString as its argument.
+        There is no need to dance around this, and we should assert
+        that this always holds. This JSString represents the error 
+        message we want to display to the user, so there is no need
+        to pass it into errorDescriptionForValue which will now place
+        quotes around the string.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opIn):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::ErrorInstance):
+        * runtime/ErrorInstance.h:
+        (JSC::ErrorInstance::hasSourceAppender):
+        (JSC::ErrorInstance::sourceAppender):
+        (JSC::ErrorInstance::setSourceAppender):
+        (JSC::ErrorInstance::clearSourceAppender):
+        (JSC::ErrorInstance::setRuntimeTypeForCause):
+        (JSC::ErrorInstance::runtimeTypeForCause):
+        (JSC::ErrorInstance::clearRuntimeTypeForCause):
+        (JSC::ErrorInstance::appendSourceToMessage): Deleted.
+        (JSC::ErrorInstance::setAppendSourceToMessage): Deleted.
+        (JSC::ErrorInstance::clearAppendSourceToMessage): Deleted.
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::errorDescriptionForValue):
+        (JSC::defaultApproximateSourceError):
+        (JSC::defaultSourceAppender):
+        (JSC::functionCallBase):
+        (JSC::notAFunctionSourceAppender):
+        (JSC::invalidParameterInSourceAppender):
+        (JSC::invalidParameterInstanceofSourceAppender):
+        (JSC::createError):
+        (JSC::createInvalidFunctionApplyParameterError):
+        (JSC::createInvalidInParameterError):
+        (JSC::createInvalidInstanceofParameterError):
+        (JSC::createNotAConstructorError):
+        (JSC::createNotAFunctionError):
+        (JSC::createNotAnObjectError):
+        (JSC::createInvalidParameterError): Deleted.
+        * runtime/ExceptionHelpers.h:
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::hasInstance):
+        * runtime/RuntimeType.cpp: Added.
+        (JSC::runtimeTypeForValue):
+        (JSC::runtimeTypeAsString):
+        * runtime/RuntimeType.h: Added.
+        * runtime/TypeProfilerLog.cpp:
+        (JSC::TypeProfilerLog::processLogEntries):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::getRuntimeTypeForValue): Deleted.
+        * runtime/TypeSet.h:
+        * runtime/VM.cpp:
+        (JSC::appendSourceToError):
+        (JSC::VM::throwException):
+
+2015-03-23  Filip Pizlo  <fpizlo@apple.com>
+
+        JSC should have a low-cost asynchronous disassembler
+        https://bugs.webkit.org/show_bug.cgi?id=142997
+
+        Reviewed by Mark Lam.
+        
+        This adds a JSC_asyncDisassembly option that disassembles on a thread. Disassembly
+        doesn't block execution. Some code will live a little longer because of this, since the
+        work tasks hold a ref to the code, but other than that there is basically no overhead.
+        
+        At present, this isn't really a replacement for JSC_showDisassembly, since it doesn't
+        provide contextual IR information for Baseline and DFG disassemblies, and it doesn't do
+        the separate IR dumps for FTL. Using JSC_showDisassembly and friends along with
+        JSC_asyncDisassembly has bizarre behavior - so just choose one.
+        
+        A simple way of understanding how great this is, is to run a small benchmark like
+        V8Spider/earley-boyer.
+        
+        Performance without any disassembly flags: 60ms
+        Performance with JSC_showDisassembly=true: 477ms
+        Performance with JSC_asyncDisassembly=true: 65ms
+        
+        So, the overhead of disassembly goes from 8x to 8%.
+        
+        Note that JSC_asyncDisassembly=true does make it incorrect to run "time" as a way of
+        measuring benchmark performance. This is because at VM exit, we wait for all async
+        disassembly requests to finish. For example, for earley-boyer, we spend an extra ~130ms
+        after the benchmark completely finishes to finish the disassemblies. This small weirdness
+        should be OK for the intended use-cases, since all you have to do to get around it is to
+        measure the execution time of the benchmark payload rather than the end-to-end time of
+        launching the VM.
+
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+        * assembler/LinkBuffer.h:
+        (JSC::LinkBuffer::wasAlreadyDisassembled):
+        (JSC::LinkBuffer::didAlreadyDisassemble):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::disassemble):
+        * dfg/DFGJITFinalizer.cpp:
+        (JSC::DFG::JITFinalizer::finalize):
+        (JSC::DFG::JITFinalizer::finalizeFunction):
+        * disassembler/Disassembler.cpp:
+        (JSC::disassembleAsynchronously):
+        (JSC::waitForAsynchronousDisassembly):
+        * disassembler/Disassembler.h:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jsc.cpp:
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::~VM):
+
+2015-03-23  Dean Jackson  <dino@apple.com>
+
+        ES7: Implement Array.prototype.includes
+        https://bugs.webkit.org/show_bug.cgi?id=142707
+
+        Reviewed by Geoffrey Garen.
+
+        Add support for the ES7 includes method on Arrays.
+        https://github.com/tc39/Array.prototype.includes
+
+        * builtins/Array.prototype.js:
+        (includes): Implementation in JS.
+        * runtime/ArrayPrototype.cpp: Add 'includes' to the lookup table.
+
+2015-03-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        __defineGetter__/__defineSetter__ should throw exceptions
+        https://bugs.webkit.org/show_bug.cgi?id=142934
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        Throw exceptions when these functions are used directly.
+
+2015-03-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix DO_PROPERTYMAP_CONSTENCY_CHECK enabled build
+        https://bugs.webkit.org/show_bug.cgi?id=142952
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/Structure.cpp:
+        (JSC::PropertyTable::checkConsistency):
+        The check offset method doesn't exist in PropertyTable, it exists in Structure.
+
+        (JSC::Structure::checkConsistency):
+        So move it here, and always put it at the start to match normal behavior.
+
+2015-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove DFG::ValueRecoveryOverride; it's been dead since we removed forward speculations
+        https://bugs.webkit.org/show_bug.cgi?id=142956
+
+        Rubber stamped by Gyuyoung Kim.
+        
+        Just removing dead code.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGOSRExit.h:
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGValueRecoveryOverride.h: Removed.
+
+2015-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG OSR exit shouldn't assume that the frame count for exit is greater than the frame count in DFG
+        https://bugs.webkit.org/show_bug.cgi?id=142948
+
+        Reviewed by Sam Weinig.
+        
+        It's necessary to ensure that the stack pointer accounts for the extent of our stack usage
+        since a signal may clobber the area below the stack pointer. When the DFG is executing,
+        the stack pointer accounts for the DFG's worst-case stack usage. When we OSR exit back to
+        baseline, we will use a different amount of stack. This is because baseline is a different
+        compiler. It will make different decisions. So it will use a different amount of stack.
+        
+        This gets tricky when we are in the process of doing an OSR exit, because we are sort of
+        incrementally transforming the stack from how it looked in the DFG to how it will look in
+        baseline. The most conservative approach would be to set the stack pointer to the max of
+        DFG and baseline.
+        
+        When this code was written, a reckless assumption was made: that the stack usage in
+        baseline is always at least as large as the stack usage in DFG. Based on this incorrect
+        assumption, the code first adjusts the stack pointer to account for the baseline stack
+        usage. This sort of usually works, because usually baseline does happen to use more stack.
+        But that's not an invariant. Nobody guarantees this. We will never make any changes that
+        would make this be guaranteed, because that would be antithetical to how optimizing
+        compilers work. The DFG should be allowed to use however much stack it decides that it
+        should use in order to get good performance, and it shouldn't try to guarantee that it
+        always uses less stack than baseline.
+        
+        As such, we must always assume that the frame size for DFG execution (i.e.
+        frameRegisterCount) and the frame size in baseline once we exit (i.e.
+        requiredRegisterCountForExit) are two independent quantities and they have no
+        relationship.
+        
+        Fortunately, though, this code can be made correct by just moving the stack adjustment to
+        just before we do conversions. This is because we have since changed the OSR exit
+        algorithm to first lift up all state from the DFG state into a scratch buffer, and then to
+        drop it out of the scratch buffer and into the stack according to the baseline layout. The
+        point just before conversions is the point where we have finished reading the DFG frame
+        and will not read it anymore, and we haven't started writing the baseline frame. So, at
+        this point it is safe to set the stack pointer to account for the frame size at exit.
+        
+        This is benign because baseline happens to create larger frames than DFG.
+
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::adjustAndJumpToTarget):
+
+2015-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Shorten the number of iterations to 10,000 since that's enough to test all tiers.
+
+        Rubber stamped by Sam Weinig.
+
+        * tests/stress/equals-masquerader.js:
+
+2015-03-22  Filip Pizlo  <fpizlo@apple.com>
+
+        tests/stress/*tdz* tests do 10x more iterations than necessary
+        https://bugs.webkit.org/show_bug.cgi?id=142946
+
+        Reviewed by Ryosuke Niwa.
+        
+        The stress test harness runs all of these tests in various configurations. This includes
+        no-cjit, which has tier-up heuristics locked in such a way that 10,000 iterations is
+        enough to get to the highest tier. The only exceptions are very large functions or
+        functions that have some reoptimizations. That happens rarely, and when it does happen,
+        usually 20,000 iterations is enough.
+        
+        Therefore, these tests use 10x too many iterations. This is bad, since these tests
+        allocate on each iteration, and so they run very slowly in debug mode.
+
+        * tests/stress/class-syntax-no-loop-tdz.js:
+        * tests/stress/class-syntax-no-tdz-in-catch.js:
+        * tests/stress/class-syntax-no-tdz-in-conditional.js:
+        * tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js:
+        * tests/stress/class-syntax-no-tdz-in-loop.js:
+        * tests/stress/class-syntax-no-tdz.js:
+        * tests/stress/class-syntax-tdz-in-catch.js:
+        * tests/stress/class-syntax-tdz-in-conditional.js:
+        * tests/stress/class-syntax-tdz-in-loop.js:
+        * tests/stress/class-syntax-tdz.js:
+
+2015-03-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Fix a typo in Parser error message
+        https://bugs.webkit.org/show_bug.cgi?id=142942
+
+        Reviewed by Alexey Proskuryakov.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        Fix a common identifier typo.
+
+2015-03-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Computed Property names should allow only AssignmentExpressions not any Expression
+        https://bugs.webkit.org/show_bug.cgi?id=142902
+
+        Reviewed by Ryosuke Niwa.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseProperty):
+        Limit computed expressions to just assignment expressions instead of
+        any expression (which allowed comma expressions).
+
+2015-03-21  Andreas Kling  <akling@apple.com>
+
+        Make UnlinkedFunctionExecutable fit in a 128-byte cell.
+        <https://webkit.org/b/142939>
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-arrange the members of UnlinkedFunctionExecutable so it can fit inside
+        a 128-byte heap cell instead of requiring a 256-byte one.
+
+        Threw in a static_assert to catch anyone pushing it over the limit again.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::functionMode):
+
+2015-03-20  Mark Hahnenberg  <mhahnenb@gmail.com>
+
+        GCTimer should know keep track of nested GC phases
+        https://bugs.webkit.org/show_bug.cgi?id=142675
+
+        Reviewed by Darin Adler.
+
+        This improves the GC phase timing output in Heap.cpp by linking
+        phases nested inside other phases together, allowing tools
+        to compute how much time we're spending in various nested phases.
+
+        * heap/Heap.cpp:
+
+2015-03-20  Geoffrey Garen  <ggaren@apple.com>
+
+        FunctionBodyNode should known where its parameters started
+        https://bugs.webkit.org/show_bug.cgi?id=142926
+
+        Reviewed by Ryosuke Niwa.
+
+        This will allow us to re-parse parameters instead of keeping the
+        parameters piece of the AST around forever.
+
+        I also took the opportunity to initialize most FunctionBodyNode data
+        members at construction time, to help clarify that they are set right.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr): No need to pass
+        functionKeywordStart here; we now provide it at FunctionBodyNode
+        creation time.
+
+        (JSC::ASTBuilder::createFunctionBody): Require everything we need at
+        construction time, including the start of our parameters.
+
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createFuncDeclStatement):  No need to pass
+        functionKeywordStart here; we now provide it at FunctionBodyNode
+        creation time.
+
+        (JSC::ASTBuilder::setFunctionNameStart): Deleted.
+
+        * parser/Nodes.cpp:
+        (JSC::FunctionBodyNode::FunctionBodyNode): Initialize everything at
+        construction time.
+
+        * parser/Nodes.h: Added a field for the location of our parameters.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionBody):
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass):
+        (JSC::Parser<LexerType>::parsePropertyMethod):
+        (JSC::Parser<LexerType>::parseGetterSetter):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        * parser/Parser.h: Refactored to match above interface changes.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionExpr):
+        (JSC::SyntaxChecker::createFunctionBody):
+        (JSC::SyntaxChecker::createFuncDeclStatement):
+        (JSC::SyntaxChecker::createGetterOrSetterProperty): Refactored to match
+        above interface changes.
+
+        (JSC::SyntaxChecker::setFunctionNameStart): Deleted.
+
+2015-03-20  Filip Pizlo  <fpizlo@apple.com>
+
+        Observably effectful nodes in DFG IR should come last in their bytecode instruction (i.e. forExit section), except for Hint nodes
+        https://bugs.webkit.org/show_bug.cgi?id=142920
+
+        Reviewed by Oliver Hunt, Geoffrey Garen, and Mark Lam.
+        
+        Observably effectful, n.: If we reexecute the bytecode instruction after this node has
+        executed, then something other than the bytecode instruction's specified outcome will
+        happen.
+
+        We almost never had observably effectful nodes except at the end of the bytecode
+        instruction.  The exception is a lowered transitioning PutById:
+
+        PutStructure(@o, S1 -> S2)
+        PutByOffset(@o, @o, @v)
+
+        The PutStructure is observably effectful: if you try to reexecute the bytecode after
+        doing the PutStructure, then we'll most likely crash.  The generic PutById handling means
+        first checking what the old structure of the object is; but if we reexecute, the old
+        structure will seem to be the new structure.  But the property ensured by the new
+        structure hasn't been stored yet, so any attempt to load it or scan it will crash.
+
+        Intriguingly, however, none of the other operations involved in the PutById are
+        observably effectful.  Consider this example:
+
+        PutByOffset(@o, @o, @v)
+        PutStructure(@o, S1 -> S2)
+
+        Note that the PutStructure node doesn't reallocate property storage; see further below
+        for an example that does that. Because no property storage is happening, we know that we
+        already had room for the new property.  This means that the PutByOffset is no observable
+        until the PutStructure executes and "reveals" the property.  Hence, PutByOffset is not
+        observably effectful.
+
+        Now consider this:
+
+        b: AllocatePropertyStorage(@o)
+        PutByOffset(@b, @o, @v)
+        PutStructure(@o, S1 -> S2)
+
+        Surprisingly, this is also safe, because the AllocatePropertyStorage is not observably
+        effectful. It *does* reallocate the property storage and the new property storage pointer
+        is stored into the object. But until the PutStructure occurs, the world will just think
+        that the reallocation didn't happen, in the sense that we'll think that the property
+        storage is using less memory than what we just allocated. That's harmless.
+
+        The AllocatePropertyStorage is safe in other ways, too. Even if we GC'd after the
+        AllocatePropertyStorage but before the PutByOffset (or before the PutStructure),
+        everything could be expected to be fine, so long as all of @o, @v and @b are on the
+        stack. If they are all on the stack, then the GC will leave the property storage alone
+        (so the extra memory we just allocated would be safe). The GC will not scan the part of
+        the property storage that contains @v, but that's fine, so long as @v is on the stack.
+        
+        The better long-term solution is probably bug 142921.
+        
+        But for now, this:
+        
+        - Fixes an object materialization bug, exemplified by the two tests, that previously
+          crashed 100% of the time with FTL enabled and concurrent JIT disabled.
+        
+        - Allows us to remove the workaround introduced in r174856.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handlePutById):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::insertCheck):
+        (JSC::DFG::FixupPhase::indexOfNode): Deleted.
+        (JSC::DFG::FixupPhase::indexOfFirstNodeOfExitOrigin): Deleted.
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertOutOfOrder): Deleted.
+        (JSC::DFG::InsertionSet::insertOutOfOrderNode): Deleted.
+        * tests/stress/materialize-past-butterfly-allocation.js: Added.
+        (bar):
+        (foo0):
+        (foo1):
+        (foo2):
+        (foo3):
+        (foo4):
+        * tests/stress/materialize-past-put-structure.js: Added.
+        (foo):
+
+2015-03-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION (r179429): Potential Use after free in JavaScriptCore`WTF::StringImpl::ref + 83
+        https://bugs.webkit.org/show_bug.cgi?id=142410
+
+        Reviewed by Geoffrey Garen.
+
+        Before this patch, added function JSValue::toPropertyKey returns PropertyName.
+        Since PropertyName doesn't have AtomicStringImpl ownership,
+        if Identifier is implicitly converted to PropertyName and Identifier is destructed,
+        PropertyName may refer freed AtomicStringImpl*.
+
+        This patch changes the result type of JSValue::toPropertyName from PropertyName to Identifier,
+        to keep AtomicStringImpl* ownership after the toPropertyName call is done.
+        And receive the result value as Identifier type to keep ownership in the caller side.
+
+        To catch the result of toPropertyKey as is, we catch the result of toPropertyName as auto.
+
+        However, now we don't need to have both Identifier and PropertyName.
+        So we'll merge PropertyName to Identifier in the subsequent patch.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opIn):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::toPropertyKey):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyDescriptor):
+        (JSC::objectConstructorDefineProperty):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncPropertyIsEnumerable):
+
+2015-03-18  Geoffrey Garen  <ggaren@apple.com>
+
+        Function.prototype.toString should not decompile the AST
+        https://bugs.webkit.org/show_bug.cgi?id=142853
+
+        Reviewed by Sam Weinig.
+
+        To recover the function parameter string, Function.prototype.toString
+        decompiles the function parameters from the AST. This is bad for a few
+        reasons:
+
+        (1) It requires us to keep pieces of the AST live forever. This is an
+        awkward design and a waste of memory.
+
+        (2) It doesn't match Firefox or Chrome (because it changes whitespace
+        and ES6 destructuring expressions).
+
+        (3) It doesn't scale to ES6 default argument parameters, which require
+        arbitrarily complex decompilation.
+
+        (4) It can counterfeit all the line numbers in a function (because
+        whitespace can include newlines).
+
+        (5) It's expensive, and we've seen cases where websites invoke
+        Function.prototype.toString a lot by accident.
+
+        The fix is to do what we do for the rest of the function: Just quote the
+        original source text.
+
+        Since this change inevitably changes some function stringification, I
+        took the opportunity to make our stringification match Firefox's and
+        Chrome's.
+
+        * API/tests/testapi.c:
+        (assertEqualsAsUTF8String): Be more informative when this fails.
+
+        (main): Updated to match new stringification rules.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::paramString): Deleted. Yay!
+        * bytecode/UnlinkedCodeBlock.h:
+
+        * parser/Nodes.h:
+        (JSC::StatementNode::isFuncDeclNode): New helper for constructing
+        anonymous functions.
+
+        * parser/SourceCode.h:
+        (JSC::SourceCode::SourceCode): Allow zero because WebCore wants it.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode): Updated for use
+        of function declaration over function expression.
+
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::paramString): Deleted. Yay!
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::parameterCount):
+
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck): Added a newline after
+        the opening brace to match Firefox and Chrome, and a space after the comma
+        to match Firefox and WebKit coding style. Added the function name to
+        the text of the function so it would look right when stringify-ing. Switched
+        from parentheses to braces to produce a function declaration instead of
+        a function expression because we are required to exclude the function's
+        name from its scope, and that's what a function declaration does.
+
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString): Removed an old workaround because the
+        library it worked around doesn't really exist anymore, and the behavior
+        doesn't match Firefox or Chrome. Use type profiling offsets instead of
+        function body offsets because we want to include the function name and
+        the parameter string, rather than stitching them in manually by
+        decompiling the AST.
+
+        (JSC::insertSemicolonIfNeeded): Deleted.
+
+        * tests/mozilla/js1_2/function/tostring-1.js:
+        * tests/mozilla/js1_5/Scope/regress-185485.js:
+        (with.g): Updated these test results for formatting changes.
+
+2015-03-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        SyntaxChecker assertion is trapped with computed property name and getter
+        https://bugs.webkit.org/show_bug.cgi?id=142863
+
+        Reviewed by Ryosuke Niwa.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::getName):
+        Remove invalid assert. Computed properties will not have a name
+        and the calling code is checking for null expecting it. The
+        AST path (non-CheckingPath) already does this without the assert
+        so it is well tested.
+
+2015-03-19  Mark Lam  <mark.lam@apple.com>
+
+        JSCallbackObject<JSGlobalObject> should not destroy its JSCallbackObjectData before all its finalizers have been called.
+        <https://webkit.org/b/142846>
+
+        Reviewed by Geoffrey Garen.
+
+        Currently, JSCallbackObject<JSGlobalObject> registers weak finalizers via 2 mechanisms:
+        1. JSCallbackObject<Parent>::init() registers a weak finalizer for all JSClassRef
+           that a JSCallbackObject references.
+        2. JSCallbackObject<JSGlobalObject>::create() registers a finalizer via
+           vm.heap.addFinalizer() which destroys the JSCallbackObject.
+
+        The first finalizer is implemented as a virtual function of a JSCallbackObjectData
+        instance that will be destructed if the 2nd finalizer is called.  Hence, if the
+        2nd finalizer if called first, the later invocation of the 1st finalizer will
+        result in a crash.
+
+        This patch fixes the issue by eliminating the finalizer registration in init().
+        Instead, we'll have the JSCallbackObject destructor call all the JSClassRef finalizers
+        if needed.  This ensures that these finalizers are called before the JSCallbackObject
+        is destructor.
+
+        Also added assertions to a few Heap functions because JSCell::classInfo() expects
+        all objects that are allocated from MarkedBlock::Normal blocks to be derived from
+        JSDestructibleObject.  These assertions will help us catch violations of this
+        expectation earlier.
+
+        * API/JSCallbackObject.cpp:
+        (JSC::JSCallbackObjectData::finalize): Deleted.
+        * API/JSCallbackObject.h:
+        (JSC::JSCallbackObjectData::~JSCallbackObjectData):
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::~JSCallbackObject):
+        (JSC::JSCallbackObject<Parent>::init):
+        * API/tests/GlobalContextWithFinalizerTest.cpp: Added.
+        (finalize):
+        (testGlobalContextWithFinalizer):
+        * API/tests/GlobalContextWithFinalizerTest.h: Added.
+        * API/tests/testapi.c:
+        (main):
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/HeapInlines.h:
+        (JSC::Heap::allocateObjectOfType):
+        (JSC::Heap::subspaceForObjectOfType):
+        (JSC::Heap::allocatorForObjectOfType):
+
+2015-03-19  Andreas Kling  <akling@apple.com>
+
+        JSCallee unnecessarily overrides a bunch of things in the method table.
+        <https://webkit.org/b/142855>
+
+        Reviewed by Geoffrey Garen.
+
+        Remove JSCallee method table overrides that simply call to base class.
+        This makes JSFunction property slot lookups slightly more efficient since
+        they can take the fast path when passing over JSCallee in the base class chain.
+
+        * runtime/JSCallee.cpp:
+        (JSC::JSCallee::getOwnPropertySlot): Deleted.
+        (JSC::JSCallee::getOwnNonIndexPropertyNames): Deleted.
+        (JSC::JSCallee::put): Deleted.
+        (JSC::JSCallee::deleteProperty): Deleted.
+        (JSC::JSCallee::defineOwnProperty): Deleted.
+        * runtime/JSCallee.h:
+
+2015-03-19  Andreas Kling  <akling@apple.com>
+
+        DFGAllocator should use bmalloc's aligned allocator.
+        <https://webkit.org/b/142871>
+
+        Reviewed by Geoffrey Garen.
+
+        Switch DFGAllocator to using bmalloc through fastAlignedMalloc().
+
+        * dfg/DFGAllocator.h:
+        (JSC::DFG::Allocator<T>::allocateSlow):
+        (JSC::DFG::Allocator<T>::freeRegionsStartingAt):
+        * heap/CopiedSpace.h:
+        * heap/MarkedBlock.h:
+        * heap/MarkedSpace.h:
+
+2015-03-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6 Classes: Extends should accept an expression without parenthesis
+        https://bugs.webkit.org/show_bug.cgi?id=142840
+
+        Reviewed by Ryosuke Niwa.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        "extends" allows a LeftHandExpression (new expression / call expression,
+        which includes a member expression), not a primary expression. Our
+        parseMemberExpression does all of these.
+
+2015-03-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Debugger Popovers and Probes should use FormattedValue/ObjectTreeView instead of Custom/ObjectPropertiesSection
+        https://bugs.webkit.org/show_bug.cgi?id=142830
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        Give Probe Samples object previews.
+
+2015-03-17  Ryuan Choi  <ryuan.choi@navercorp.com>
+
+        [EFL] Expose JavaScript binding interface through ewk_extension
+        https://bugs.webkit.org/show_bug.cgi?id=142033
+
+        Reviewed by Gyuyoung Kim.
+
+        * PlatformEfl.cmake: Install Javascript APIs.
+
+2015-03-17  Geoffrey Garen  <ggaren@apple.com>
+
+        Function bodies should always include braces
+        https://bugs.webkit.org/show_bug.cgi?id=142795
+
+        Reviewed by Michael Saboff.
+
+        Having a mode for excluding the opening and closing braces from a function
+        body was unnecessary and confusing.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock): Adopt the new one true linking function.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::link):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor): No need to pass through
+        a boolean: there is only one kind of function now.
+
+        (JSC::UnlinkedFunctionExecutable::linkInsideExecutable): Deleted.
+        (JSC::UnlinkedFunctionExecutable::linkGlobalCode): Deleted. Let's only
+        have one way to do things. This removes the old mode that would pretend
+        that a function always started at column 1. That pretense was not true:
+        an attribute event listener does not necessarily start at column 1.
+
+        * bytecode/UnlinkedCodeBlock.h:
+        * generate-js-builtins: Adopt the new one true linking function.
+
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse):
+        (JSC::parse): needsReparsingAdjustment is always true now, so I removed it.
+
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        (JSC::FunctionExecutable::fromGlobalCode):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::create):
+        (JSC::FunctionExecutable::bodyIncludesBraces): Deleted. Removed unused stuff.
+
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck): Always provide a
+        leading space because that's what this function's comment says is required
+        for web compatibility. We used to fake this up after the fact when
+        stringifying, based on the bodyIncludesBraces flag, but that flag is gone now.
+
+        * runtime/FunctionPrototype.cpp:
+        (JSC::insertSemicolonIfNeeded):
+        (JSC::functionProtoFuncToString): No need to add braces and/or a space
+        after the fact -- we always have them now.
+
+2015-03-17  Mark Lam  <mark.lam@apple.com>
+
+        Refactor execution time limit tests out of testapi.c.
+        <https://webkit.org/b/142798>
+
+        Rubber stamped by Michael Saboff.
+
+        These tests were sometimes failing to time out on C loop builds.  Let's
+        refactor them out of the big monolith that is testapi.c so that we can
+        reason more easily about them and make adjustments if needed.
+
+        * API/tests/ExecutionTimeLimitTest.cpp: Added.
+        (currentCPUTime):
+        (currentCPUTimeAsJSFunctionCallback):
+        (shouldTerminateCallback):
+        (cancelTerminateCallback):
+        (extendTerminateCallback):
+        (testExecutionTimeLimit):
+        * API/tests/ExecutionTimeLimitTest.h: Added.
+        * API/tests/testapi.c:
+        (main):
+        (currentCPUTime): Deleted.
+        (currentCPUTime_callAsFunction): Deleted.
+        (shouldTerminateCallback): Deleted.
+        (cancelTerminateCallback): Deleted.
+        (extendTerminateCallback): Deleted.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-03-17  Geoffrey Garen  <ggaren@apple.com>
+
+        Built-in functions should know that they use strict mode
+        https://bugs.webkit.org/show_bug.cgi?id=142788
+
+        Reviewed by Mark Lam.
+
+        Even though all of our builtin functions use strict mode, the parser
+        thinks that they don't. This is because Executable::toStrictness treats
+        builtin-ness and strict-ness as mutually exclusive.
+
+        The fix is to disambiguate builtin-ness from strict-ness.
+
+        This bug is currently unobservable because of some other parser bugs. But
+        it causes lots of test failures once those other bugs are fixed.
+
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable): Adopt the new API
+        for a separate value to indicate builtin-ness vs strict-ness.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor): Ditto.
+
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::toStrictness): Deleted. This function
+        was misleading since it pretended that no builtin function was ever
+        strict, which is the opposite of true.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        * parser/Lexer.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        * parser/Parser.h:
+        (JSC::parse): Adopt the new API.
+
+        * parser/ParserModes.h: Added JSParserBuiltinMode, and tried to give
+        existing modes clearer names.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getProgramCodeBlock):
+        (JSC::CodeCache::getEvalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode): Adopt the new API.
+
+        * runtime/CodeCache.h:
+        (JSC::SourceCodeKey::SourceCodeKey): Be sure to treat strict-ness and
+        bulitin-ness as separate pieces of the code cache key. We would not want
+        a user function to match a built-in function in the cache, even if they
+        agreed about strictness, since builtin functions have different lexing
+        rules.
+
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::create):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::createProgramCodeBlock):
+        (JSC::JSGlobalObject::createEvalCodeBlock): Adopt the new API.
+
+2015-03-16  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG IR shouldn't have a separate node for every kind of put hint that could be described using PromotedLocationDescriptor
+        https://bugs.webkit.org/show_bug.cgi?id=142769
+
+        Reviewed by Michael Saboff.
+        
+        When we sink an object allocation, we need to have some way of tracking what stores would
+        have happened had the allocation not been sunk, so that we know how to rematerialize the
+        object on OSR exit. Prior to this change, trunk had two ways of describing such a "put
+        hint":
+        
+        - The PutStrutureHint and PutByOffsetHint node types.
+        - The PromotedLocationDescriptor class, which has an enum with cases StructurePLoc and
+          NamedPropertyPLoc.
+        
+        We also had ways of converting from a Node with those two node types to a
+        PromotedLocationDescriptor, and we had a way of converting a PromotedLocationDescriptor to
+        a Node.
+        
+        This change removes the redundancy. We now have just one node type that corresponds to a
+        put hint, and it's called PutHint. It has a PromotedLocationDescriptor as metadata.
+        Converting between a PutHint node and a PromotedLocationDescriptor and vice-versa is now
+        trivial.
+        
+        This means that if we add new kinds of sunken objects, we'll have less pro-forma to write
+        for the put hints to those objects. This is mainly to simplify the implementation of
+        arguments elimination in bug 141174.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::mergeRelevantToOSR):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToPutHint):
+        (JSC::DFG::Node::convertToPutStructureHint):
+        (JSC::DFG::Node::convertToPutByOffsetHint):
+        (JSC::DFG::Node::promotedLocationDescriptor):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasIdentifier):
+        (JSC::DFG::Node::hasPromotedLocationDescriptor):
+        (JSC::DFG::Node::convertToPutByOffsetHint): Deleted.
+        (JSC::DFG::Node::convertToPutStructureHint): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::run):
+        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPromoteHeapAccess.h:
+        (JSC::DFG::promoteHeapAccess):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (JSC::DFG::PromotedHeapLocation::createHint):
+        * dfg/DFGPromotedHeapLocation.h:
+        (JSC::DFG::PromotedLocationDescriptor::imm1):
+        (JSC::DFG::PromotedLocationDescriptor::imm2):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2015-03-17  Michael Saboff  <msaboff@apple.com>
+
+        Windows X86-64 should use the fixed executable allocator
+        https://bugs.webkit.org/show_bug.cgi?id=142749
+
+        Reviewed by Filip Pizlo.
+
+        Added jit/ExecutableAllocatorFixedVMPool.cpp to Windows build.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * jit/ExecutableAllocatorFixedVMPool.cpp: Don't include unistd.h on Windows.
+
+2015-03-17  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Show rendering frames (and FPS) in Layout and Rendering timeline
+        https://bugs.webkit.org/show_bug.cgi?id=142029
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Timeline.json:
+        Added new event type for runloop timeline records.
+
+2015-03-16  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Enable ES6 classes by default
+        https://bugs.webkit.org/show_bug.cgi?id=142774
+
+        Reviewed by Gavin Barraclough.
+
+        Enabled the feature and unskipped tests.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * tests/stress/class-syntax-no-loop-tdz.js:
+        * tests/stress/class-syntax-no-tdz-in-catch.js:
+        * tests/stress/class-syntax-no-tdz-in-conditional.js:
+        * tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js:
+        * tests/stress/class-syntax-no-tdz-in-loop.js:
+        * tests/stress/class-syntax-no-tdz.js:
+        * tests/stress/class-syntax-tdz-in-catch.js:
+        * tests/stress/class-syntax-tdz-in-conditional.js:
+        * tests/stress/class-syntax-tdz-in-loop.js:
+        * tests/stress/class-syntax-tdz.js:
+
+2015-03-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Better Console Previews for Arrays / Small Objects
+        https://bugs.webkit.org/show_bug.cgi?id=142322
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        Create deep valuePreviews for simple previewable objects,
+        such as arrays with 5 values, or basic objects with
+        3 properties.
+
+2015-03-16  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Add support for default constructor
+        https://bugs.webkit.org/show_bug.cgi?id=142388
+
+        Reviewed by Filip Pizlo.
+
+        Added the support for default constructors. They're generated by ClassExprNode::emitBytecode
+        via BuiltinExecutables::createDefaultConstructor.
+
+        UnlinkedFunctionExecutable now has the ability to override SourceCode provided by the owner
+        executable. We can't make store SourceCode in UnlinkedFunctionExecutable since CodeCache can use
+        the same UnlinkedFunctionExecutable to generate code blocks for multiple functions.
+
+        Parser now has the ability to treat any function expression as a constructor of the kind specified
+        by m_defaultConstructorKind member variable.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createDefaultConstructor): Added.
+        (JSC::BuiltinExecutables::createExecutableInternal): Generalized from createBuiltinExecutable.
+        Parse default constructors as normal non-builtin functions. Override SourceCode in the unlinked
+        function executable since the Miranda function's code is definitely not in the owner executable's
+        source code. That's the whole point.
+        * builtins/BuiltinExecutables.h:
+        (UnlinkedFunctionExecutable::createBuiltinExecutable): Added. Wraps createExecutableInternal.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedFunctionExecutable::linkInsideExecutable):
+        (JSC::UnlinkedFunctionExecutable::linkGlobalCode):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::create):
+        (JSC::UnlinkedFunctionExecutable::symbolTable): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewDefaultConstructor): Added.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ClassExprNode::emitBytecode): Generate the default constructor if needed.
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseFunctionInfo): Override ownerClassKind and assume the function as
+        a constructor if we're parsing a default constructor.
+        (JSC::Parser<LexerType>::parseClass): Allow omission of the class constructor.
+        * parser/Parser.h:
+        (JSC::parse):
+
+2015-03-16  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards CMake on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=142747
+
+        Reviewed by Chris Dumez.
+
+        * CMakeLists.txt:
+        Include AugmentableInspectorController.h in CMake build.
+
+2015-03-16  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Enable generating idiv instructions if it is supported
+        https://bugs.webkit.org/show_bug.cgi?id=142725
+
+        Reviewed by Michael Saboff.
+
+        * assembler/ARMAssembler.h: Added sdiv and udiv implementation for ARM Traditional instruction set.
+        (JSC::ARMAssembler::sdiv):
+        (JSC::ARMAssembler::udiv):
+        * assembler/ARMv7Assembler.h: Use HAVE(ARM_IDIV_INSTRUCTIONS) instead of CPU(APPLE_ARMV7S).
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::isARMv7IDIVSupported):
+        (JSC::optimizeForARMv7IDIVSupported):
+        (JSC::isARMv7s): Renamed to isARMv7IDIVSupported().
+        (JSC::optimizeForARMv7s): Renamed to optimizeForARMv7IDIVSupported().
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithDiv):
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+
+2015-03-15  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::PutStackSinkingPhase should eliminate GetStacks that have an obviously known source, and emit GetStacks when the stack's value is needed and none is deferred
+        https://bugs.webkit.org/show_bug.cgi?id=141624
+
+        Reviewed by Geoffrey Garen.
+
+        Not eliminating GetStacks was an obvious omission from the original PutStackSinkingPhase.
+        Previously, we would treat GetStacks conservatively and assume that the stack slot
+        escaped. That's pretty dumb, since a GetStack is a local load of the stack. This change
+        makes GetStack a no-op from the standpoint of this phase's deferral analysis. At the end
+        we either keep the GetStack (if there was no concrete deferral) or we replace it with an
+        identity over the value that would have been stored by the deferred PutStack. Note that
+        this might be a Phi that the phase creates, so this is strictly stronger than what GCSE
+        could do.
+        
+        But this change revealed the fact that this phase never correctly handled side effects in
+        case that we had done a GetStack, then a side-effect, and then found ourselves wanting the
+        value on the stack due to (for example) a Phi on a deferred PutStack and that GetStack.
+        Basically, it's only correct to use the SSA converter's incoming value mapping if we have
+        a concrete deferral - since anything but a concrete deferral may imply that the value has
+        been clobbered.
+        
+        This has no performance change. I believe that the bug was previously benign because we
+        have so few operations that clobber the stack anymore, and most of those get used in a
+        very idiomatic way. The GetStack elimination will be very useful for the varargs
+        simplification that is part of bug 141174.
+        
+        This includes a test for the case that Speedometer hit, plus tests for the other cases I
+        thought of once I realized the deeper issue.
+
+        * dfg/DFGPutStackSinkingPhase.cpp:
+        * tests/stress/get-stack-identity-due-to-sinking.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/get-stack-mapping-with-dead-get-stack.js: Added.
+        (bar):
+        (foo):
+        * tests/stress/get-stack-mapping.js: Added.
+        (bar):
+        (foo):
+        * tests/stress/weird-put-stack-varargs.js: Added.
+        (baz):
+        (foo):
+        (fuzz):
+        (bar):
+
+2015-03-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Update Map/Set to treat -0 and 0 as the same value
+        https://bugs.webkit.org/show_bug.cgi?id=142709
+
+        Reviewed by Csaba Osztrogonác.
+
+        * runtime/MapData.h:
+        (JSC::MapDataImpl<Entry>::KeyType::KeyType):
+        No longer special case -0. It will be treated as the same as 0.
+
+2015-03-15  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Better handle displaying -0
+        https://bugs.webkit.org/show_bug.cgi?id=142708
+
+        Reviewed by Timothy Hatcher.
+
+        Modeled after a blink change:
+
+        Patch by <aandrey@chromium.org>
+        DevTools: DevTools: Show -0 for negative zero in console
+        https://src.chromium.org/viewvc/blink?revision=162605&view=revision
+
+        * inspector/InjectedScriptSource.js:
+        When creating a description string, or preview value string
+        for -0, be sure the string is "-0" and not "0".
+
+2015-03-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        parseClass should popScope after pushScope
+        https://bugs.webkit.org/show_bug.cgi?id=142689
+
+        Reviewed by Benjamin Poulain.
+
+        Pop the parser scope as needed.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+
+2015-03-14  Dean Jackson  <dino@apple.com>
+
+        Feature flag for Animations Level 2
+        https://bugs.webkit.org/show_bug.cgi?id=142699
+        <rdar://problem/20165097>
+
+        Reviewed by Brent Fulgham.
+
+        Add ENABLE_CSS_ANIMATIONS_LEVEL_2 and a runtime flag animationTriggersEnabled.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-03-14  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r181487.
+        https://bugs.webkit.org/show_bug.cgi?id=142695
+
+        Caused Speedometer/Full.html to fail (Requested by smfr on
+        #webkit).
+
+        Reverted changeset:
+
+        "DFG::PutStackSinkingPhase should eliminate GetStacks that
+        have an obviously known source"
+        https://bugs.webkit.org/show_bug.cgi?id=141624
+        http://trac.webkit.org/changeset/181487
+
+2015-03-14  Michael Saboff  <msaboff@apple.com>
+
+        ES6: Add binary and octal literal support
+        https://bugs.webkit.org/show_bug.cgi?id=142681
+
+        Reviewed by Ryosuke Niwa.
+
+        Added a binary literal parser function, parseBinary(), to Lexer patterned after the octal parser.
+        Refactored the parseBinary, parseOctal and parseDecimal to use a constant size for the number of
+        characters to try and handle directly. Factored out the shifting past any prefix to be handled by
+        the caller. Added binary and octal parsing to toDouble() via helper functions.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::parseHex):
+        (JSC::Lexer<T>::parseBinary):
+        (JSC::Lexer<T>::parseOctal):
+        (JSC::Lexer<T>::parseDecimal):
+        (JSC::Lexer<T>::lex):
+        * parser/Lexer.h:
+        * parser/ParserTokens.h:
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::jsBinaryIntegerLiteral):
+        (JSC::jsOctalIntegerLiteral):
+        (JSC::toDouble):
+
+2015-03-13  Alex Christensen  <achristensen@webkit.org>
+
+        Progress towards CMake on Mac.
+        https://bugs.webkit.org/show_bug.cgi?id=142680
+
+        Reviewed by Gyuyoung Kim.
+
+        * PlatformMac.cmake:
+        Generate TracingDtrace.h based on project.pbxproj.
+
+2015-03-13  Filip Pizlo  <fpizlo@apple.com>
+
+        Object allocation sinking phase shouldn't re-decorate previously sunken allocations on each fixpoint operation
+        https://bugs.webkit.org/show_bug.cgi?id=142686
+
+        Reviewed by Oliver Hunt.
+        
+        Just because promoteHeapAccess() notifies us of an effect to a heap location in a node doesn't
+        mean that we should handle it as if it was for one of our sinking candidates. Instead we should
+        prune based on m_sinkCandidates.
+        
+        This fixes a benign bug where we would generate a lot of repeated IR for some pathological
+        tests.
+
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
+
+2015-03-13  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] Enable WIRELESS_PLAYBACK_TARGET
+        https://bugs.webkit.org/show_bug.cgi?id=142635
+
+        Reviewed by Darin Adler.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-03-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Class constructor should throw TypeError when "called"
+        https://bugs.webkit.org/show_bug.cgi?id=142566
+
+        Reviewed by Michael Saboff.
+
+        Added ConstructorKind::None to denote code that doesn't belong to an ES6 class.
+        This allows BytecodeGenerator to emit code to throw TypeError when generating code block
+        to call ES6 class constructors.
+
+        Most of changes are about increasing the number of bits to store ConstructorKind from one
+        bit to two bits.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::ExecutableInfo::ExecutableInfo):
+        (JSC::ExecutableInfo::needsActivation):
+        (JSC::ExecutableInfo::usesEval):
+        (JSC::ExecutableInfo::isStrictMode):
+        (JSC::ExecutableInfo::isConstructor):
+        (JSC::ExecutableInfo::isBuiltinFunction):
+        (JSC::ExecutableInfo::constructorKind):
+        (JSC::UnlinkedFunctionExecutable::constructorKind):
+        (JSC::UnlinkedCodeBlock::constructorKind):
+        (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Deleted.
+        (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate): Don't emit bytecode when we had already emitted code
+        to throw TypeError.
+        (JSC::BytecodeGenerator::BytecodeGenerator): Emit code to throw TypeError when generating
+        code to call.
+        (JSC::BytecodeGenerator::emitReturn):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::constructorKind):
+        (JSC::BytecodeGenerator::constructorKindIsDerived): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        * parser/Nodes.cpp:
+        (JSC::FunctionBodyNode::FunctionBodyNode):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo): Renamed the incoming function argument to
+        ownerClassKind. Set constructorKind to Base or Derived only if we're parsing a constructor.
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass): Don't parse static methods using MethodMode since that
+        would result in BytecodeGenerator erroneously treating static method named "constructor" as
+        a class constructor.
+        (JSC::Parser<LexerType>::parsePropertyMethod):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        * parser/Parser.h:
+        * parser/ParserModes.h:
+        * runtime/Executable.h:
+        (JSC::EvalExecutable::executableInfo):
+        (JSC::ProgramExecutable::executableInfo):
+
+2015-03-13  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::PutStackSinkingPhase should eliminate GetStacks that have an obviously known source
+        https://bugs.webkit.org/show_bug.cgi?id=141624
+
+        Reviewed by Oliver Hunt.
+        
+        This was an obvious omission from the original PutStackSinkingPhase. Previously, we would treat
+        GetStacks conservatively and assume that the stack slot escaped. That's pretty dumb, since a
+        GetStack is a local load of the stack. This change makes GetStack a no-op from the standpoint of
+        this phase's deferral analysis. At the end we either keep the GetStack (if there was no concrete
+        deferral) or we replace it with an identity over the value that would have been stored by the
+        deferred PutStack. Note that this might be a Phi that the phase creates, so this is strictly
+        stronger than what GCSE could do.
+        
+        This is probably not a speed-up now, but it will be very useful for the varargs simplification
+        done in bug 141174.
+
+        * dfg/DFGPutStackSinkingPhase.cpp:
+
+2015-03-12  Geoffrey Garen  <ggaren@apple.com>
+
+        Prohibit GC while sweeping
+        https://bugs.webkit.org/show_bug.cgi?id=142638
+
+        Reviewed by Andreas Kling.
+
+        I noticed in https://bugs.webkit.org/show_bug.cgi?id=142636 that a GC
+        could trigger a sweep which could trigger another GC. Yo Dawg.
+
+        I tried to figure out whether this could cause problems or not and it
+        made me cross-eyed.
+
+        (Some clients like to report extra memory cost during deallocation as a
+        way to indicate that the GC now owns something exclusively. It's
+        arguably a bug to communicate with the GC in this way, but we shouldn't
+        do crazy when this happens.)
+
+        This patch makes explicit the fact that we don't allow GC while sweeping.
+
+        Usually, sweeping implicitly defers GC by virtue of happening during
+        allocation. But not always.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbage): Defer GC while sweeping due to an
+        explicit GC request.
+
+        (JSC::Heap::didFinishCollection): Make sure that zombifying sweep
+        defers GC by not returning to the non-GC state until we're all done.
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::sweepNextBlock): Defer GC while sweeping due
+        to a timer.
+
+2015-03-13  Mark Lam  <mark.lam@apple.com>
+
+        Replace TCSpinLock with a new WTF::SpinLock based on WTF::Atomic.
+        <https://webkit.org/b/142674>
+
+        Reviewed by Filip Pizlo.
+
+        * API/JSValue.mm:
+        (handerForStructTag):
+        * API/JSWrapperMap.mm:
+        * dfg/DFGCommon.cpp:
+        (JSC::DFG::startCrashing):
+        (JSC::DFG::isCrashing):
+        - Changed to use a StaticSpinLock since that's what this code was trying to do
+          anyway.
+        * heap/CopiedBlock.h:
+        (JSC::CopiedBlock::CopiedBlock):
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::CopiedSpace):
+        * heap/CopiedSpace.h:
+        * heap/GCThreadSharedData.cpp:
+        (JSC::GCThreadSharedData::GCThreadSharedData):
+        * heap/GCThreadSharedData.h:
+        * heap/ListableHandler.h:
+        (JSC::ListableHandler::List::List):
+        * parser/SourceProvider.cpp:
+        * profiler/ProfilerDatabase.cpp:
+        (JSC::Profiler::Database::addDatabaseToAtExit):
+        (JSC::Profiler::Database::removeDatabaseFromAtExit):
+        (JSC::Profiler::Database::removeFirstAtExitDatabase):
+
+2015-03-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        BytecodeGenerator needs to be re-entrant to support miranda functions
+        https://bugs.webkit.org/show_bug.cgi?id=142627
+
+        Reviewed by Filip Pizlo.
+
+        Made CodeCache::getGlobalCodeBlock and CodeCache::getFunctionExecutableFromGlobalCode re-entrant
+        by not keeping AddResult while invoking BytecodeGenerator::generate.
+
+        This is needed to support Miranda functions since they need to be lazily initialized.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CodeCache.h:
+        (JSC::CodeCacheMap::findCacheAndUpdateAge): Extracted from add.
+        (JSC::CodeCacheMap::addCache): Extracted from add.
+        (JSC::CodeCacheMap::add): Deleted.
+
+2015-03-13  Mark Lam  <mark.lam@apple.com>
+
+        Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
+        <https://webkit.org/b/142661>
+
+        Reviewed by Filip Pizlo.
+
+        Changed CodeBlock, and the DFG's crashLock to use WTF::Atomic instead of
+        std::atomic.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::visitAggregate):
+        * bytecode/CodeBlock.h:
+        * dfg/DFGCommon.cpp:
+        (JSC::DFG::startCrashing):
+
+2015-03-12  Mark Lam  <mark.lam@apple.com>
+
+        Change the DFG crashLock to use std::atomic.
+        <https://webkit.org/b/142649>
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGCommon.cpp:
+        (JSC::DFG::startCrashing):
+        (JSC::DFG::isCrashing):
+
+2015-03-12  Filip Pizlo  <fpizlo@apple.com>
+
+        Bytecode liveness analysis should have more lambdas and fewer sets
+        https://bugs.webkit.org/show_bug.cgi?id=142647
+
+        Reviewed by Mark Lam.
+        
+        In bug 141174 I'll need to identify all of the bytecode kill sites. This requires hooking into
+        the bytecode analysis' stepOverFunction method, except in such a way that we observe uses that
+        are not in outs. This refactors stepOverFunction so that you can pass it use/def functors that
+        can either be used to propagate outs (as we do right now) or to additionally detect kills or
+        whatever else.
+        
+        In order to achieve this, the liveness analysis was moved off of maintaining uses/defs
+        bitvectors. This wasn't helping the abstraction and was probably inefficient. The new code
+        should be a bit faster since we don't have to clear uses/defs bitvectors on each instruction. On
+        the other hand, being able to intercept each use means that our code for exception handlers is
+        no longer a bitwise-merge; it requires finding set bits. Fortunately, this code only kicks in
+        for instructions inside a try, and its performance is O(live at catch), so that's probably not
+        bad.
+
+        * bytecode/BytecodeLivenessAnalysis.cpp:
+        (JSC::indexForOperand):
+        (JSC::stepOverInstruction):
+        (JSC::computeLocalLivenessForBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
+        (JSC::setForOperand): Deleted.
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+
+2015-03-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        "this" should be in TDZ until super is called in the constructor of a derived class
+        https://bugs.webkit.org/show_bug.cgi?id=142527
+
+        Reviewed by Mark Hahnenberg.
+
+        DFG and FTL implementations co-authored by Filip Pizlo.
+
+        In ES6 class syntax, "this" register must be in the "temporal dead zone" (TDZ) and throw ReferenceError until
+        super() is called inside the constructor of a derived class.
+
+        Added op_check_tdz, a new OP code, which throws a reference error when the first operand is an empty value
+        to all tiers of JIT and LLint. The op code throws in the slow path on the basis that a TDZ error should be
+        a programming error and not a part of the programs' normal control flow. In DFG, this op code is represented
+        by a no-op must-generate node CheckNotEmpty modeled after CheckCell.
+
+        Also made the constructor of a derived class assign the empty value to "this" register rather than undefined
+        so that ThisNode can emit the op_check_tdz to check the initialized-ness of "this" in such a constructor.
+
+        * bytecode/BytecodeList.json: Added op_check_tdz.
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset): Ditto.
+        (JSC::computeDefsForBytecodeOffset): Ditto.
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Ditto.
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString): Added TDZFailure.
+        * bytecode/ExitKind.h: Ditto.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator): Assign the empty value to "this" register to indicate it's in TDZ.
+        (JSC::BytecodeGenerator::emitTDZCheck): Added.
+        (JSC::BytecodeGenerator::emitReturn): Emit the TDZ check since "this" can still be in TDZ if super() was never
+        called. e.g. class B extends A { constructor() { } }
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode): Always emit the TDZ check if we're inside the constructor of a derived class.
+        We can't omit this check even if the result was ignored per spec.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Previously, empty value could never appear
+        in a local variable. This is no longer true so generalize this code. Also added the support for CheckNotEmpty.
+        Like CheckCell, we phantomize this DFG node in the constant folding phase if the type of the operand is already
+        found to be not empty. Otherwise filter out SpecEmpty.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock): Added op_check_tdz.
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel): op_check_tdz can be compiled and inlined.
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize): CheckNotEmpty doesn't read or write values.
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants): Convert CheckNotEmpty to a phantom if non-emptiness had already
+        been proven for the operand prior to this node.
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC): CheckNotEmpty does not trigger GC.
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): CheckNotEmpty is a no-op in the fixup phase.
+        * dfg/DFGNodeType.h: CheckNotEmpty cannot be removed even if the result was ignored. See ThisNode::emitBytecode.
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate): CheckNotEmpty doesn't return any value.
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute): CheckNotEmpty doesn't load from heap so it's safe.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): Speculative the operand to be not empty. OSR exit if the speculation fails.
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): Ditto.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile): CheckNotEmpty can be compiled in FTL.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode): Calls compileCheckNotEmpty for CheckNotEmpty.
+        (JSC::FTL::LowerDFGToLLVM::compileCheckNotEmpty): OSR exit with "TDZFailure" if the operand is not empty.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass): Added op_check_tdz.
+        (JSC::JIT::privateCompileSlowCases): Ditto.
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_check_tdz): Implements op_check_tdz in Baseline JIT.
+        (JSC::JIT::emitSlow_op_check_tdz): Ditto.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_check_tdz): Ditto.
+        (JSC::JIT::emitSlow_op_check_tdz): Ditto.
+        * llint/LowLevelInterpreter32_64.asm: Implements op_check_tdz in LLint.
+        * llint/LowLevelInterpreter64.asm: Ditto.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Throws a reference error for op_check_tdz. Shared by LLint and Baseline JIT.
+        * runtime/CommonSlowPaths.h:
+        * tests/stress/class-syntax-no-loop-tdz.js: Added.
+        * tests/stress/class-syntax-no-tdz-in-catch.js: Added.
+        * tests/stress/class-syntax-no-tdz-in-conditional.js: Added.
+        * tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js: Added.
+        * tests/stress/class-syntax-no-tdz-in-loop.js: Added.
+        * tests/stress/class-syntax-no-tdz.js: Added.
+        * tests/stress/class-syntax-tdz-in-catch.js: Added.
+        * tests/stress/class-syntax-tdz-in-conditional.js: Added.
+        * tests/stress/class-syntax-tdz-in-loop.js: Added.
+        * tests/stress/class-syntax-tdz.js: Added.
+
+2015-03-12  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Integrate MapData into JSMap and JSSet
+        https://bugs.webkit.org/show_bug.cgi?id=142556
+
+        Reviewed by Filip Pizlo.
+
+        This patch integrates MapData into JSMap and JSSet.
+        This removes 2 object allocation per one JSMap / JSSet.
+
+        MapDataImpl is specialized into MapData and SetData.
+        In the case of SetData, it does not have the dummy values
+        previously stored in the MapDataImpl. So the storage size of SetData
+        becomes the half of the previous implementation.
+
+        And now MapData and SetData are completely integrated into JSMap and JSSet,
+        these structures are not exposed to the other code even in WebCore world.
+
+        And at the same time, this patch fixes missing destroy functions
+        in JSMapIterator and JSSetIterator.
+        They are needed because MapData::const_iterator is a non-trivial destructor.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/JSMap.cpp:
+        (JSC::JSMap::destroy):
+        (JSC::JSMap::visitChildren):
+        (JSC::JSMap::copyBackingStore):
+        (JSC::JSMap::has):
+        (JSC::JSMap::size):
+        (JSC::JSMap::get):
+        (JSC::JSMap::set):
+        (JSC::JSMap::clear):
+        (JSC::JSMap::remove):
+        (JSC::JSMap::finishCreation): Deleted.
+        * runtime/JSMap.h:
+        (JSC::JSMap::Entry::key):
+        (JSC::JSMap::Entry::value):
+        (JSC::JSMap::Entry::visitChildren):
+        (JSC::JSMap::Entry::setKey):
+        (JSC::JSMap::Entry::setKeyWithoutWriteBarrier):
+        (JSC::JSMap::Entry::setValue):
+        (JSC::JSMap::Entry::clear):
+        (JSC::JSMap::begin):
+        (JSC::JSMap::end):
+        (JSC::JSMap::JSMap):
+        (JSC::JSMap::mapData): Deleted.
+        * runtime/JSMapIterator.cpp:
+        (JSC::JSMapIterator::finishCreation):
+        (JSC::JSMapIterator::destroy):
+        (JSC::JSMapIterator::visitChildren):
+        * runtime/JSMapIterator.h:
+        (JSC::JSMapIterator::JSMapIterator):
+        * runtime/JSSet.cpp:
+        (JSC::JSSet::destroy):
+        (JSC::JSSet::visitChildren):
+        (JSC::JSSet::copyBackingStore):
+        (JSC::JSSet::has):
+        (JSC::JSSet::size):
+        (JSC::JSSet::add):
+        (JSC::JSSet::clear):
+        (JSC::JSSet::remove):
+        (JSC::JSSet::finishCreation): Deleted.
+        * runtime/JSSet.h:
+        (JSC::JSSet::Entry::key):
+        (JSC::JSSet::Entry::value):
+        (JSC::JSSet::Entry::visitChildren):
+        (JSC::JSSet::Entry::setKey):
+        (JSC::JSSet::Entry::setKeyWithoutWriteBarrier):
+        (JSC::JSSet::Entry::setValue):
+        (JSC::JSSet::Entry::clear):
+        (JSC::JSSet::begin):
+        (JSC::JSSet::end):
+        (JSC::JSSet::JSSet):
+        (JSC::JSSet::mapData): Deleted.
+        * runtime/JSSetIterator.cpp:
+        (JSC::JSSetIterator::finishCreation):
+        (JSC::JSSetIterator::visitChildren):
+        (JSC::JSSetIterator::destroy):
+        * runtime/JSSetIterator.h:
+        (JSC::JSSetIterator::JSSetIterator):
+        * runtime/MapConstructor.cpp:
+        (JSC::constructMap):
+        * runtime/MapData.h:
+        (JSC::MapDataImpl::const_iterator::key):
+        (JSC::MapDataImpl::const_iterator::value):
+        (JSC::MapDataImpl::size):
+        (JSC::MapDataImpl<Entry>::MapDataImpl):
+        (JSC::MapDataImpl<Entry>::clear):
+        (JSC::MapDataImpl<Entry>::KeyType::KeyType):
+        (JSC::MapDataImpl<Entry>::const_iterator::internalIncrement):
+        (JSC::MapDataImpl<Entry>::const_iterator::ensureSlot):
+        (JSC::MapDataImpl<Entry>::const_iterator::const_iterator):
+        (JSC::MapDataImpl<Entry>::const_iterator::~const_iterator):
+        (JSC::MapDataImpl<Entry>::const_iterator::operator):
+        (JSC::=):
+        (JSC::MapData::const_iterator::key): Deleted.
+        (JSC::MapData::const_iterator::value): Deleted.
+        (JSC::MapData::create): Deleted.
+        (JSC::MapData::createStructure): Deleted.
+        (JSC::MapData::size): Deleted.
+        (JSC::MapData::clear): Deleted.
+        (JSC::MapData::KeyType::KeyType): Deleted.
+        (JSC::MapData::const_iterator::internalIncrement): Deleted.
+        (JSC::MapData::const_iterator::ensureSlot): Deleted.
+        (JSC::MapData::const_iterator::const_iterator): Deleted.
+        (JSC::MapData::const_iterator::~const_iterator): Deleted.
+        (JSC::MapData::const_iterator::operator*): Deleted.
+        (JSC::MapData::const_iterator::end): Deleted.
+        (JSC::MapData::const_iterator::operator!=): Deleted.
+        (JSC::MapData::const_iterator::operator==): Deleted.
+        * runtime/MapDataInlines.h: Renamed from Source/JavaScriptCore/runtime/MapData.cpp.
+        (JSC::MapDataImpl<Entry>::find):
+        (JSC::MapDataImpl<Entry>::contains):
+        (JSC::MapDataImpl<Entry>::add):
+        (JSC::MapDataImpl<Entry>::set):
+        (JSC::MapDataImpl<Entry>::get):
+        (JSC::MapDataImpl<Entry>::remove):
+        (JSC::MapDataImpl<Entry>::replaceAndPackBackingStore):
+        (JSC::MapDataImpl<Entry>::replaceBackingStore):
+        (JSC::MapDataImpl<Entry>::ensureSpaceForAppend):
+        (JSC::MapDataImpl<Entry>::visitChildren):
+        (JSC::MapDataImpl<Entry>::copyBackingStore):
+        * runtime/MapPrototype.cpp:
+        (JSC::getMap):
+        (JSC::mapProtoFuncClear):
+        (JSC::mapProtoFuncDelete):
+        (JSC::mapProtoFuncForEach):
+        (JSC::mapProtoFuncGet):
+        (JSC::mapProtoFuncHas):
+        (JSC::mapProtoFuncSet):
+        (JSC::mapProtoFuncSize):
+        (JSC::getMapData): Deleted.
+        * runtime/SetPrototype.cpp:
+        (JSC::getSet):
+        (JSC::setProtoFuncAdd):
+        (JSC::setProtoFuncClear):
+        (JSC::setProtoFuncDelete):
+        (JSC::setProtoFuncForEach):
+        (JSC::setProtoFuncHas):
+        (JSC::setProtoFuncSize):
+        (JSC::getMapData): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2015-03-12  Mark Lam  <mark.lam@apple.com>
+
+        Use std::atomic for CodeBlock::m_visitAggregateHasBeenCalled.
+        <https://webkit.org/b/142640>
+
+        Reviewed by Mark Hahnenberg.
+
+        We used to spin our own compare and swap on a uint8_t.  Now that we can
+        use C++11, let's use std::atomic instead.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::visitAggregate):
+        - The CAS here needs std::memory_order_acquire ordering because it
+          requires lock acquisition semantics to visit the CodeBlock.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlockSet::mark):
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::clearMarksForFullCollection):
+        (JSC::CodeBlockSet::clearMarksForEdenCollection):
+        - These can go with relaxed ordering because they are all done before
+          the GC starts parallel marking.
+
+2015-03-12  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [cmake] Fix the incremental build issue revealed by r181419
+        https://bugs.webkit.org/show_bug.cgi?id=142613
+
+        Reviewed by Carlos Garcia Campos.
+
+        * CMakeLists.txt:
+
+2015-03-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        "static" should not be a reserved keyword in non-strict mode even when ES6 class is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=142600
+
+        Reviewed by Mark Lam.
+
+        Make "static" RESERVED_IF_STRICT and manually detect it in parseClass.
+
+        No new tests. This is already checked by js/reserved-words.html and js/keywords-and-reserved_words.html
+
+        * parser/Keywords.table:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        * parser/ParserTokens.h:
+
+2015-03-11  Geoffrey Garen  <ggaren@apple.com>
+
+        Many users of Heap::reportExtraMemory* are wrong, causing lots of memory growth
+        https://bugs.webkit.org/show_bug.cgi?id=142593
+
+        Reviewed by Andreas Kling.
+
+        Adopt deprecatedReportExtraMemory as a short-term fix for runaway
+        memory growth in these cases where we have not adopted
+        reportExtraMemoryVisited.
+
+        Long-term, we should use reportExtraMemoryAllocated+reportExtraMemoryVisited.
+        That's tracked by https://bugs.webkit.org/show_bug.cgi?id=142595.
+
+        * API/JSBase.cpp:
+        (JSReportExtraMemoryCost):
+        * runtime/SparseArrayValueMap.cpp:
+        (JSC::SparseArrayValueMap::add):
+
+2015-03-11  Geoffrey Garen  <ggaren@apple.com>
+
+        Refactored the JSC::Heap extra cost API for clarity and to make some known bugs more obvious
+        https://bugs.webkit.org/show_bug.cgi?id=142589
+
+        Reviewed by Andreas Kling.
+
+        * API/JSBase.cpp:
+        (JSReportExtraMemoryCost): Added a FIXME to annotate a known bug.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::visitAggregate):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setJITCode): Updated for rename.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::reportExtraMemoryAllocatedSlowCase):
+        (JSC::Heap::deprecatedReportExtraMemorySlowCase): Renamed our reporting
+        APIs to clarify their relationship to each other: One must report extra
+        memory at the time of allocation, and at the time the GC visits it.
+
+        (JSC::Heap::extraMemorySize):
+        (JSC::Heap::size):
+        (JSC::Heap::capacity):
+        (JSC::Heap::sizeAfterCollect):
+        (JSC::Heap::willStartCollection): Updated for renames. Added explicit
+        API for deprecated users who can't use our best API.
+        (JSC::Heap::reportExtraMemoryCostSlowCase): Deleted.
+        (JSC::Heap::extraSize): Deleted.
+
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::reportExtraMemoryAllocated):
+        (JSC::Heap::reportExtraMemoryVisited):
+        (JSC::Heap::deprecatedReportExtraMemory):
+        (JSC::Heap::reportExtraMemoryCost): Deleted. Ditto.
+
+        * heap/SlotVisitor.h:
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::reportExtraMemoryVisited):
+        (JSC::SlotVisitor::reportExtraMemoryUsage): Deleted. Moved this
+        functionality into the Heap since it's pretty detailed in its access
+        to the heap.
+
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): Updated for
+        renames.
+
+        * runtime/JSString.cpp:
+        (JSC::JSString::visitChildren):
+        (JSC::JSRopeString::resolveRopeToAtomicString):
+        (JSC::JSRopeString::resolveRope):
+        * runtime/JSString.h:
+        (JSC::JSString::finishCreation): Updated for renames.
+
+        * runtime/SparseArrayValueMap.cpp:
+        (JSC::SparseArrayValueMap::add): Added FIXME.
+
+        * runtime/WeakMapData.cpp:
+        (JSC::WeakMapData::visitChildren): Updated for rename.
+
+2015-03-11  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Calling super() in a base class results in a crash
+        https://bugs.webkit.org/show_bug.cgi?id=142563
+
+        Reviewed by Filip Pizlo.
+
+        The bug was caused by BytecodeGenerator trying to generate "super" expression inside the constructor of a base class.
+        Disallow that by keeping track of whether "super" has been used in the current scope or not (needsSuperBinding flag)
+        and then throwing a syntax error in parseFunctionInfo if it was used and the current scope wasn't the constructor of
+        a derived class.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo): Don't allow super() or super.foo outside the constructor of a derived class.
+        (JSC::Parser<LexerType>::parseClass): Pass in the constructor kind to parseGetterSetter.
+        (JSC::Parser<LexerType>::parseGetterSetter): Ditto to parseFunctionInfo.
+        (JSC::Parser<LexerType>::parseMemberExpression): Set needsSuperBinding flag true on the containing scope.
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::needsSuperBinding): Added.
+        (JSC::Scope::setNeedsSuperBinding): Added.
+
+2015-03-10  Darin Adler  <darin@apple.com>
+
+        Some event handler fixes
+        https://bugs.webkit.org/show_bug.cgi?id=142474
+
+        Reviewed by Anders Carlsson.
+
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::createInjectedScript): Call clearException.
+        I spotted the fact it was missing by auditing all the calls to JSC::call.
+
+2015-03-10  Matthew Mirman  <mmirman@apple.com>
+
+        Functions should have initialization precedence over arguments. 
+        https://bugs.webkit.org/show_bug.cgi?id=142550
+        rdar://problem/19702564
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeCapturedVariable):
+        * tests/stress/initialize_functions_after_arguments.js: Added.
+
+2015-03-10  Andreas Kling  <akling@apple.com>
+
+        Eden collections should trigger sweep of MarkedBlocks containing new objects.
+        <https://webkit.org/b/142538>
+
+        Reviewed by Geoffrey Garen.
+
+        Take a snapshot of all MarkedBlocks with new objects as part of Eden collections,
+        and append that to the IncrementalSweeper's working set.
+
+        This ensures that we run destructors for objects that were discovered to be garbage during
+        Eden collections, instead of delaying their teardown until the next full collection,
+        or the next allocation cycle for their block.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::snapshotMarkedSpace): For Eden collections, snapshot the list of MarkedBlocks
+        that contain new objects, since those are the only ones we're interested in.
+        Also use Vector::resizeToFit() to allocate the snapshot for full collections, since we know
+        the final size we need up front.
+
+        (JSC::Heap::notifyIncrementalSweeper): For Eden collections, tell the IncrementalSweeper
+        to add the block snapshot (taken earlier) to its existing set of blocks instead of replacing
+        it entirely. This allows Eden collections and incremental sweeping to occur interleaved with
+        each other without missing destruction opportunities.
+
+        * heap/IncrementalSweeper.h:
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::doSweep):
+        (JSC::IncrementalSweeper::sweepNextBlock): Change the way we iterate over the sweeper's
+        work list: instead of keeping an index for the next block, just pop from the end of the list.
+        This allows us to add new blocks and deduplicate the list without disturbing iteration.
+
+        (JSC::IncrementalSweeper::startSweeping): Make this take a Vector<MarkedBlock>&& so we can
+        pass ownership of this Vector efficiently from Heap to IncrementalSweeper.
+
+        (JSC::IncrementalSweeper::addBlocksAndContinueSweeping): Added. This is used by Eden
+        collections to add a set of MarkedBlocks with new objects to the sweeper's existing
+        working set and kick the timer.
+
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::blocksWithNewObjects): Expose the list of MarkedBlocks with new objects.
+
+2015-03-10  Alex Christensen  <achristensen@webkit.org>
+
+        Use unsigned for HashSet size.
+        https://bugs.webkit.org/show_bug.cgi?id=142518
+
+        Reviewed by Benjamin Poulain.
+
+        * dfg/DFGAvailabilityMap.cpp:
+        (JSC::DFG::AvailabilityMap::prune):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * heap/MarkedBlockSet.h:
+        (JSC::MarkedBlockSet::remove):
+        * runtime/WeakMapData.h:
+
+2015-03-10  Mark Lam  <mark.lam@apple.com>
+
+        Use std::numeric_limits<unsigned>::max() instead of (unsigned)-1.
+        <https://webkit.org/b/142539>
+
+        Reviewed by Benjamin Poulain.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::JIT):
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        (JSC::JIT::privateCompile):
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JITInlines.h:
+        (JSC::JIT::emitNakedCall):
+        (JSC::JIT::addSlowCase):
+        (JSC::JIT::addJump):
+        (JSC::JIT::emitJumpSlowToHot):
+        (JSC::JIT::emitGetVirtualRegister):
+        * jit/SlowPathCall.h:
+        (JSC::JITSlowPathCall::call):
+        * yarr/Yarr.h:
+
+2015-03-10  Mark Lam  <mark.lam@apple.com>
+
+        [Win] JSC Build Warnings Need to be Resolved.
+        <https://webkit.org/b/142366>
+
+        Reviewed by Brent Fulgham.
+
+        Applied some benign changes to make the MSVC compiler happy.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        * runtime/BasicBlockLocation.cpp:
+        (JSC::BasicBlockLocation::getExecutedRanges):
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::hasBasicBlockAtTextOffsetBeenExecuted):
+
+2015-03-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Upgrade Map, Set and WeakMap constructor interface
+        https://bugs.webkit.org/show_bug.cgi?id=142348
+
+        Reviewed by Filip Pizlo.
+
+        In the latest ES6 spec, Map and Set constructors take initialization data sets
+        as iterable value. And iterate it and add the values into the constructed one.
+
+        This is breaking change because the old constructor interface is
+        already shipped in Safari 8.
+
+        * runtime/MapConstructor.cpp:
+        (JSC::callMap):
+        (JSC::constructMap):
+        (JSC::MapConstructor::getCallData):
+        * runtime/SetConstructor.cpp:
+        (JSC::callSet):
+        (JSC::constructSet):
+        * runtime/WeakMapConstructor.cpp:
+        (JSC::callWeakMap):
+        (JSC::constructWeakMap):
+        (JSC::WeakMapConstructor::getCallData):
+        * tests/stress/map-constructor-adder.js: Added.
+        * tests/stress/map-constructor.js: Added.
+        (testCallTypeError):
+        (testTypeError):
+        (for):
+        * tests/stress/set-constructor-adder.js: Added.
+        (Set.prototype.add):
+        * tests/stress/set-constructor.js: Added.
+        (for):
+        * tests/stress/weak-map-constructor-adder.js: Added.
+        * tests/stress/weak-map-constructor.js: Added.
+        (testCallTypeError):
+        (testTypeError):
+        (for):
+
+2015-03-10  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        GCC: CRASH() should be annotated with NORETURN
+        https://bugs.webkit.org/show_bug.cgi?id=142524
+
+        Reviewed by Anders Carlsson.
+
+        Don't return from a NORETURN function. This used to avoid a warning from GCC, but now it
+        causes one.
+
+        * jsc.cpp:
+
+2015-03-10  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: fix bleeding debug test bots.
+        https://webkit.org/b/142513>
+
+        Not reviewed.
+
+        The test needs to initialize WTF threading explicitly before using it.
+
+        * API/tests/CompareAndSwapTest.cpp:
+        (testCompareAndSwap):
+
+2015-03-10  Alex Christensen  <achristensen@webkit.org>
+
+        [WinCairo] Unreviewed build fix.
+
+        * JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props:
+        Added directory containing config.h, like r181304.
+
+2015-03-09  Mark Lam  <mark.lam@apple.com>
+
+        Yet another build fix for Windows.
+        https://webkit.org/b/142513>
+
+        Reviewed by Alex Christensen.
+
+        Looks like MSVC requires the function be explicitly declared in a header file
+        in order for it to be linkable from another file in the same project.  This is
+        strange, but it seems to make MSVC happy.
+
+        Also fixed a typo in testapi.vcxproj.filters.
+
+        * API/tests/CompareAndSwapTest.cpp:
+        * API/tests/CompareAndSwapTest.h: Added.
+        * API/tests/testapi.c:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-03-09  Chris Dumez  <cdumez@apple.com>
+
+        [iOS] Sweep all collected objects on critical memory pressure
+        https://bugs.webkit.org/show_bug.cgi?id=142457
+        <rdar://problem/20044440>
+
+        Reviewed by Geoffrey Garen.
+
+        All fullSweep() API to IncrementalSweeper so that we can call it in the
+        memory pressure handler.
+
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::fullSweep):
+        * heap/IncrementalSweeper.h:
+        (JSC::IncrementalSweeper::hasWork):
+
+2015-03-09  Mark Lam  <mark.lam@apple.com>
+
+        Another build fix for Windows.
+        https://webkit.org/b/142513>
+
+        Not reviewed.
+
+        * API/tests/CompareAndSwapTest.cpp:
+        - Added JS_EXPORT_PRIVATE attribute.
+
+2015-03-09  Mark Lam  <mark.lam@apple.com>
+
+        Build fix for Windows after r181305.
+        https://webkit.org/b/142513>
+
+        Reviewed by Alex Christensen.
+
+        Windows doesn't like pthreads anymore.  Changed test to use WTF threading.
+
+        * API/tests/CompareAndSwapTest.cpp:
+        (setBitThreadFunc):
+        (testCompareAndSwap):
+
+2015-03-09  Mark Lam  <mark.lam@apple.com>
+
+        8-bit version of weakCompareAndSwap() can cause an infinite loop.
+        https://webkit.org/b/142513>
+
+        Reviewed by Filip Pizlo.
+
+        Added a test that exercises the 8-bit CAS from multiple threads.  The threads
+        will contend to set bits in a large array of bytes using the CAS function.
+
+        * API/tests/CompareAndSwapTest.cpp: Added.
+        (Bitmap::Bitmap):
+        (Bitmap::numBits):
+        (Bitmap::clearAll):
+        (Bitmap::concurrentTestAndSet):
+        (setBitThreadFunc):
+        (testCompareAndSwap):
+        * API/tests/testapi.c:
+        (main):
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-03-09  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] testapi project is unable to find the 'config.h' file.
+
+        Rubberstamped by Mark Lam.
+
+        * JavaScriptCore.vcxproj/testapi/testapiCommon.props: Add JavaScriptCore source directory
+        to the include path.
+
+2015-03-09  Andreas Kling  <akling@apple.com>
+
+        Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
+        <https://webkit.org/b/142115>
+        <rdar://problem/19992268>
+
+        Reviewed by Geoffrey Garen.
+
+        Prune stale entries from WeakGCMaps as part of every full garbage collection.
+        This frees up tons of previously-stuck WeakBlocks that were only sitting around
+        with finalized handles waiting to die.
+
+        Note that WeakGCMaps register/unregister themselves with the GC heap in their
+        ctor/dtor, so creating one now requires passing the VM.
+
+        Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
+        to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
+        It seems somewhat excessive to do this on every Eden collection, so it's only
+        doing work in full collections for now.
+
+        Because the GC may now mutate WeakGCMap below object allocation, I've made it
+        so that the classic HashMap::add() optimization can't be used with WeakGCMap.
+        This caused intermittent test failures when originally landed due to having
+        an invalid iterator on the stack after add() inserted a new entry and we
+        proceeded to allocate the new object, triggering GC.
+
+        * API/JSWeakObjectMapRefInternal.h:
+        (OpaqueJSWeakObjectMap::create):
+        (OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
+        * API/JSWeakObjectMapRefPrivate.cpp:
+        * API/JSWrapperMap.mm:
+        (-[JSWrapperMap initWithContext:]):
+        (-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make
+        it project-private so WebCore clients can access it.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        (JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
+        stale entries from WeakGCMaps. This is only executed during full collections.
+
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::registerWeakGCMap):
+        (JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
+        themselves with the Heap and provide a pruning callback.
+
+        * runtime/PrototypeMap.h:
+        (JSC::PrototypeMap::PrototypeMap):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.
+
+        * runtime/JSCInlines.h: Add "WeakGCMapInlines.h"
+
+        * runtime/JSGlobalObject.cpp: Include "WeakGCMapInlines.h" so this builds.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+        * runtime/PrototypeMap.cpp:
+        (JSC::PrototypeMap::addPrototype):
+        (JSC::PrototypeMap::emptyObjectStructureForPrototype): Remove HashMap add()
+        optimization since it's not safe in the GC-managed WeakGCMap world.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM): Pass VM to WeakGCMap constructor.
+
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::set):
+        (JSC::WeakGCMap::add):
+        (JSC::WeakGCMap::WeakGCMap): Deleted.
+        (JSC::WeakGCMap::gcMap): Deleted.
+        (JSC::WeakGCMap::gcMapIfNeeded): Deleted.
+        * runtime/WeakGCMapInlines.h: Added.
+        (JSC::WeakGCMap::WeakGCMap):
+        (JSC::WeakGCMap::~WeakGCMap):
+        (JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
+        to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
+        prunes WeakGCMap at certain growth milestones and instead rely on the GC
+        callback for housekeeping.
+
+2015-03-09  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Support extends and super keywords
+        https://bugs.webkit.org/show_bug.cgi?id=142200
+
+        Reviewed by Filip Pizlo.
+
+        Added the support for ES6 class syntax inheritance.
+
+        Added ConstructorKind as well as boolean flags indicating the constructor kind to
+        various classes in UnlinkedCodeBlock as well as AST nodes.
+
+        Each method stores the associated class as its homeObjectPrivateName. This value is used to
+        make super calls.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::ExecutableInfo::ExecutableInfo):
+        (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Added.
+        (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Added.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator): Don't emit op_create_this in a derived class
+        as the object is allocated by the highest base class's constructor. Also set "this" to null
+        and store the original value in m_newTargetRegister. "this" is supposed to be in TDZ but
+        that will be implemented in a separate patch.
+        (JSC::BytecodeGenerator::emitReturn): Allow "undefined" to be returned from a derived class.
+        In a derived class's constructor, not returning "undefined" or an object results in a type
+        error instead of "this" being returned.
+        (JSC::BytecodeGenerator::emitThrowTypeError): Added.
+
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::constructorKindIsDerived): Added.
+        (JSC::BytecodeGenerator::newTarget): Added.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::SuperNode::emitBytecode): Added. Emits the code to obtain the callee's parent class.
+        (JSC::emitSuperBaseForCallee): Added. Emits the code to obtain the parent class's prototype.
+        (JSC::emitPutHomeObject): Added.
+        (JSC::PropertyListNode::emitBytecode): Stores the home object when adding methods.
+        (JSC::PropertyListNode::emitPutConstantProperty): Ditto.
+        (JSC::BracketAccessorNode::emitBytecode): Added the support for super['foo'].
+        (JSC::DotAccessorNode::emitBytecode): Added the support for super.foo.
+        (JSC::FunctionCallValueNode::emitBytecode): Added the support for super().
+        (JSC::FunctionCallBracketNode::emitBytecode): Added the support for super['foo']().
+        (JSC::FunctionCallDotNode::emitBytecode): Added the support for super.foo().
+        (JSC::DeleteBracketNode::emitBytecode): Forbid "delete super.foo".
+        (JSC::DeleteDotNode::emitBytecode): Forbid "delete super['foo']".
+        (JSC::ClassExprNode::emitBytecode): Added the support for "classHeritage". This is the main
+        logic for inheritance. When a class B inherits from a class A, set B.__proto__ to A and set
+        B.prototype.__proto__ to A.prototype. Throw exceptions when either A or A.__proto__ is not
+        an object.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::superExpr): Added.
+
+        * parser/NodeConstructors.h:
+        (JSC::SuperNode::SuperNode): Added.
+
+        * parser/Nodes.cpp:
+        (JSC::FunctionBodyNode::FunctionBodyNode):
+
+        * parser/Nodes.h:
+        (JSC::ExpressionNode::isSuperNode):
+        (JSC::PropertyNode::type):
+        (JSC::PropertyNode::needsSuperBinding):
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionBody):
+        (JSC::Parser<LexerType>::parseFunctionInfo): Throw a parser error if super() is used outside
+        of class constructors.
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass): ConstructorKind is "derived" if and only if the parent
+        class is specified in the declaration / expression.
+        (JSC::Parser<LexerType>::parseGetterSetter):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        (JSC::Parser<LexerType>::parseMemberExpression): Added the support for "super()", "super.foo",
+        and "super['foo']". Throw a semantic error if "super" appears by itself.
+
+        * parser/Parser.h:
+        (JSC::Scope::Scope): Added m_hasDirectSuper. This variable keeps track of the use of "super()"
+        so that parseFunctionInfo can spit an error if it's used outside of class constructors.
+        (JSC::Scope::hasDirectSuper): Added.
+        (JSC::Scope::setHasDirectSuper): Added.
+
+        * parser/ParserModes.h:
+        (JSC::ConstructorKind): Added.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::superExpr): Added.
+
+        * runtime/CommonIdentifiers.h: Added homeObjectPrivateName.
+
+        * runtime/Executable.h:
+        (JSC::EvalExecutable::executableInfo): 
+        (JSC::ProgramExecutable::executableInfo):
+
+2015-03-08  Andreas Kling  <akling@apple.com>
+
+        JITThunks keeps finalized Weaks around, pinning WeakBlocks.
+        <https://webkit.org/b/142454>
+
+        Reviewed by Darin Adler.
+
+        Make JITThunks a WeakHandleOwner so it can keep its host function map free of stale entries.
+        This fixes an issue I was seeing where a bunch of WeakBlocks stuck around with nothing but
+        finalized Weak<NativeExecutable> entries.
+
+        * jit/JITThunks.h:
+        * jit/JITThunks.cpp:
+        (JSC::JITThunks::finalize): Make JITThunks inherit from WeakHandleOwner so it can receive
+        a callback when the NativeExecutables get garbage collected.
+
+        (JSC::JITThunks::hostFunctionStub): Pass 'this' as the handle owner when creating Weaks.
+
+2015-03-08  Andreas Kling  <akling@apple.com>
+
+        BuiltinExecutables keeps finalized Weaks around, pinning WeakBlocks.
+        <https://webkit.org/b/142460>
+
+        Reviewed by Geoffrey Garen.
+
+        Make BuiltinExecutables a WeakHandleOwner so it can clear out its respective Weak members
+        if and when their pointees get garbage collected.
+
+        This fixes an issue I've seen locally where a WeakBlock is pinned down by a single one of
+        these Weak<BuiltinExecutables>.
+
+        * builtins/BuiltinExecutables.h: Make BuiltinExecutables inherit from WeakHandleOwner.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::finalize): Clear out the relevant member pointer when it's been
+        garbage collected. We use the WeakImpl's "context" field to pass the address of the member.
+
+2015-03-07  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the removal of BlockAllocator, which is now unused.
+
+        * API/JSBase.cpp:
+        * CMakeLists.txt:
+        * JavaScriptCore.order:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/BlockAllocator.cpp: Removed.
+        * heap/BlockAllocator.h: Removed.
+        * heap/GCThreadSharedData.h:
+        * heap/HandleBlockInlines.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::blockAllocator): Deleted.
+        * heap/HeapTimer.cpp:
+        * heap/MarkedBlock.h:
+        * heap/MarkedSpace.h:
+        * heap/Region.h: Removed.
+        * heap/SuperRegion.cpp: Removed.
+        * heap/SuperRegion.h: Removed.
+
+2015-03-07  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r181010.
+        https://bugs.webkit.org/show_bug.cgi?id=142442
+
+        Broke media/video-src-invalid-poster.html (Requested by kling
+        on #webkit).
+
+        Reverted changeset:
+
+        "Stale entries in WeakGCMaps are keeping tons of WeakBlocks
+        alive unnecessarily."
+        https://bugs.webkit.org/show_bug.cgi?id=142115
+        http://trac.webkit.org/changeset/181010
+
+2015-03-07  Ryosuke Niwa  <rniwa@webkit.org>
+
+        The code to link FunctionExecutable is duplicated everywhere
+        https://bugs.webkit.org/show_bug.cgi?id=142436
+
+        Reviewed by Darin Adler.
+
+        Reduced code duplication by factoring out linkInsideExecutable and linkGlobalCode.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock): Calls linkInsideExecutable.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::linkInsideExecutable): Renamed from link. Now takes care of startOffset.
+        This change was needed to use this function in CodeBlock::CodeBlock. Also, this function no longer takes
+        lineOffset since this information is already stored in the source code.
+        (JSC::UnlinkedFunctionExecutable::linkGlobalCode): Extracted from FunctionExecutable::fromGlobalCode.
+
+        * bytecode/UnlinkedCodeBlock.h:
+
+        * generate-js-builtins: Calls linkGlobalCode.
+
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::initializeGlobalProperties): Calls linkGlobalCode.
+        (JSC::FunctionExecutable::fromGlobalCode): Calls linkGlobalCode.
+
+2015-03-06  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the MarkedBlock piece of this patch.
+
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateBlock):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::create):
+        (JSC::MarkedBlock::destroy):
+        (JSC::MarkedBlock::MarkedBlock):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::capacity):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::freeBlock):
+
+2015-03-07  Ryosuke Niwa  <rniwa@webkit.org>
+
+        fromGlobalCode has an unused Debugger* argument
+        https://bugs.webkit.org/show_bug.cgi?id=142430
+
+        Reviewed by Darin Adler.
+
+        Removed the debugger argument from UnlinkedFunctionExecutable::fromGlobalCode and
+        FunctionExecutable::fromGlobalCode since it's not used in either function.
+
+        Also use reference in other arguments.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
+        * bytecode/UnlinkedCodeBlock.h:
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::fromGlobalCode):
+        * runtime/Executable.h:
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+
+2015-03-06  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Turn off a warning on Windows.
+
+        Reduce build logging noise on Windows.
+
+        * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+
+2015-03-06  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Improved Support for Iterator Objects
+        https://bugs.webkit.org/show_bug.cgi?id=142420
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Runtime.json:
+        Add new object subtype "iterator" for built-in iterator objects.
+
+        * inspector/InjectedScriptSource.js:
+        Return iterator values as Entry objects.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        Identify "iterator" typed objects.
+
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        Provide internal properties for the different Iterator objects.
+
+        (Inspector::JSInjectedScriptHost::iteratorEntries):
+        Fetch the next few iterator entries of a built-in iterator object.
+
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionIteratorEntries):
+        Call through to JSInjectedScriptHost.
+
+        * runtime/JSArgumentsIterator.cpp:
+        (JSC::JSArgumentsIterator::clone):
+        * runtime/JSArgumentsIterator.h:
+        (JSC::JSArgumentsIterator::iteratedValue):
+        * runtime/JSArrayIterator.cpp:
+        (JSC::JSArrayIterator::kind):
+        (JSC::JSArrayIterator::iteratedValue):
+        (JSC::JSArrayIterator::clone):
+        * runtime/JSArrayIterator.h:
+        * runtime/JSMapIterator.cpp:
+        (JSC::JSMapIterator::finishCreation):
+        (JSC::JSMapIterator::clone):
+        * runtime/JSMapIterator.h:
+        (JSC::JSMapIterator::kind):
+        (JSC::JSMapIterator::iteratedValue):
+        * runtime/JSSetIterator.cpp:
+        (JSC::JSSetIterator::finishCreation):
+        (JSC::JSSetIterator::clone):
+        * runtime/JSSetIterator.h:
+        (JSC::JSSetIterator::kind):
+        (JSC::JSSetIterator::iteratedValue):
+        * runtime/JSStringIterator.cpp:
+        (JSC::JSStringIterator::iteratedValue):
+        (JSC::JSStringIterator::clone):
+        * runtime/JSStringIterator.h:
+        Add accessors for internal properties and provide a way to clone the
+        iterator so we can be at the same index and peek at the next few
+        objects without modifying the original iterator object.
+
+2015-03-06  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180595): construct varargs fails in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=142030
+
+        Reviewed by Michael Saboff.
+
+        Increase sizeOfCallVarargs as done for sizeOfConstructVarargs in r180651.
+
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCallVarargs):
+
+2015-03-06  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Adopt Object Literal Shorthand Property Construction Syntax
+        https://bugs.webkit.org/show_bug.cgi?id=142374
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+
+2015-03-06  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Object Literal Extensions - Methods
+        https://bugs.webkit.org/show_bug.cgi?id=142390
+
+        Reviewed by Geoffrey Garen.
+
+        Support method syntax in object literals.
+
+        * parser/Parser.h:
+        * parser/Parser.cpp:
+        (JSC::stringForFunctionMode):
+        (JSC::Parser<LexerType>::parseProperty):
+        Methods are allowed for identifier, string, and numeric names,
+        and computed property names.
+
+        (JSC::Parser<LexerType>::parsePropertyMethod):
+        Helper for parsing a property method.
+
+2015-03-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        __proto__ shorthand property should not modify prototype in Object Literal construction
+        https://bugs.webkit.org/show_bug.cgi?id=142382
+
+        Reviewed by Geoffrey Garen.
+
+        When parsing shorthand property syntax we know we will do a
+        put direct, even if the property name is __proto__. Pass that
+        information through to bytecode generation.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitPutConstantProperty):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createProperty):
+        * parser/NodeConstructors.h:
+        (JSC::PropertyNode::PropertyNode):
+        * parser/Nodes.h:
+        (JSC::PropertyNode::putType):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        (JSC::Parser<LexerType>::parseProperty):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createProperty):
+
+2015-03-06  Geoffrey Garen  <ggaren@apple.com>
+
+        Fix crashes seen on the the 32-bit buildbots after my last patch.
+
+        Unreviewed.
+
+        * heap/CopiedBlock.h:
+        (JSC::CopiedBlock::payload):
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::tryAllocateOversize): Round up to the right alignment,
+        since the size of the CopiedBlock class is not guaranteed to be the
+        right alignment, and is in fact the wrong alignment on 32-bit.
+
+2015-03-05  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the CopiedBlock piece of this patch.
+
+        * heap/CopiedBlock.h:
+        (JSC::CopiedBlock::createNoZeroFill):
+        (JSC::CopiedBlock::destroy):
+        (JSC::CopiedBlock::create):
+        (JSC::CopiedBlock::CopiedBlock):
+        (JSC::CopiedBlock::isOversize):
+        (JSC::CopiedBlock::payloadEnd):
+        (JSC::CopiedBlock::capacity):
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::~CopiedSpace):
+        (JSC::CopiedSpace::tryAllocateOversize):
+        (JSC::CopiedSpace::tryReallocateOversize):
+        * heap/CopiedSpaceInlines.h:
+        (JSC::CopiedSpace::recycleEvacuatedBlock):
+        (JSC::CopiedSpace::recycleBorrowedBlock):
+        (JSC::CopiedSpace::allocateBlockForCopyingPhase):
+        (JSC::CopiedSpace::allocateBlock):
+        (JSC::CopiedSpace::startedCopying):
+        * heap/CopyWorkList.h:
+
+2015-03-06  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [iOS] SVG fonts are garbled
+        https://bugs.webkit.org/show_bug.cgi?id=142377
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-03-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ES6: Object Literal Extensions - Shorthand Properties (Identifiers)
+        https://bugs.webkit.org/show_bug.cgi?id=142353
+
+        Reviewed by Geoffrey Garen.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseProperty):
+        Parsing an identifier property followed by a comma or end brace treat
+        as a shorthand property and create a property that has the same
+        property name as the identifier name and value of a variable with that
+        identifier. Otherwise, fall through to getter/setter parsing.
+
+2015-03-05  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed gardening.
+
+        Confirmed with JSC that warning 4611 (interaction between '_setjmp' and C++ object
+        destruction is non-portable) should be ignored in the JavaScriptCore project.
+
+        * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props: Silence warning 4611.
+
+2015-03-05  Chris Dumez  <cdumez@apple.com>
+
+        Regression(r173761): ASSERTION FAILED: !is8Bit() in StringImpl::characters16()
+        https://bugs.webkit.org/show_bug.cgi?id=142350
+
+        Reviewed by Michael Saboff and Benjamin Poulain.
+
+        Call WTFString::hasInfixStartingAt() / hasInfixEndingAt() now that these
+        methods have been renamed for clarity.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncStartsWith):
+        (JSC::stringProtoFuncEndsWith):
+
+2015-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement ES6 StringIterator
+        https://bugs.webkit.org/show_bug.cgi?id=142080
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces ES6 String Iterator.
+        It enumerates code points instead of elements in String.
+        So surrogate pairs should be handled correctly.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/StringIterator.prototype.js: Added.
+        (next):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSStringIterator.cpp: Added.
+        (JSC::JSStringIterator::finishCreation):
+        * runtime/JSStringIterator.h: Added.
+        (JSC::JSStringIterator::createStructure):
+        (JSC::JSStringIterator::create):
+        (JSC::JSStringIterator::JSStringIterator):
+        * runtime/StringIteratorConstructor.cpp: Added.
+        (JSC::StringIteratorConstructor::finishCreation):
+        * runtime/StringIteratorConstructor.h: Added.
+        (JSC::StringIteratorConstructor::create):
+        (JSC::StringIteratorConstructor::createStructure):
+        (JSC::StringIteratorConstructor::StringIteratorConstructor):
+        * runtime/StringIteratorPrototype.cpp: Added.
+        (JSC::StringIteratorPrototype::finishCreation):
+        (JSC::StringIteratorPrototype::getOwnPropertySlot):
+        (JSC::stringIteratorPrototypeIterator):
+        * runtime/StringIteratorPrototype.h: Added.
+        (JSC::StringIteratorPrototype::create):
+        (JSC::StringIteratorPrototype::createStructure):
+        (JSC::StringIteratorPrototype::StringIteratorPrototype):
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        (JSC::stringProtoFuncIterator):
+        * tests/stress/string-iterators.js: Added.
+        (testSurrogatePair):
+        (increment):
+        (for):
+
+2015-03-05  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Fix the FTL build on Aarch64 Linux after r177421
+        https://bugs.webkit.org/show_bug.cgi?id=142040
+
+        Reviewed by Mark Lam.
+
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2015-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Upgrade ES6 Iterator interfaces
+        https://bugs.webkit.org/show_bug.cgi?id=141351
+
+        Reviewed by Filip Pizlo.
+
+        This patch upgrades the exising ES6 iterator to align the latest spec.
+        In the latest spec,
+        1. `Iterator.next` returns object that implements IteratorResult interface { value: value, done, boolean }.
+        2. `Iterator.return` is introduced. When the iteration is terminated by the abrupt completion,
+        it is called to close iterator state.
+        3. Iterator.next of Array is moved from an iterator object to `%ArrayIteratorPrototype%`.
+
+        To upgrade it, we changes the bytecode that represents for-of loops.
+        And to embody the efficient iteration with an iterator object,
+        we implemented %ArrayIteratorPrototype%.next in JavaScript and
+        it is located in builtins/ArrayIterator.prototype.js.
+        Implementing it in JavaScript encourages inlining and
+        utilizes escape analysis for an iterator result object in DFG JIT.
+        And we dropped the intrinsic version of %ArrayIteratorPrototype%.next.
+
+        And we introduced IteratorOperations that is defined in the spec.
+        It aligns the iteration in the runtime to the latest spec.
+        Currently, Promise.all and Promise.race uses an iterable object.
+        However, Promise.all and Promise.race implementation is also based on the old spec.
+        Subsequent patches will upgrade it.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/ArrayIterator.prototype.js: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h.
+        (next):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitReturn):
+        (JSC::BytecodeGenerator::emitThrowTypeError):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::emitIsObject):
+        (JSC::BytecodeGenerator::emitIsUndefined):
+        * bytecompiler/BytecodeGenerator.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::arrayIteratorNextThunkGenerator): Deleted.
+        (JSC::arrayIteratorNextKeyThunkGenerator): Deleted.
+        (JSC::arrayIteratorNextValueThunkGenerator): Deleted.
+        * jit/ThunkGenerators.h:
+        * runtime/ArgumentsIteratorPrototype.cpp:
+        (JSC::ArgumentsIteratorPrototype::finishCreation):
+        (JSC::argumentsIteratorPrototypeFuncNext):
+        * runtime/ArrayIteratorPrototype.cpp:
+        (JSC::ArrayIteratorPrototype::finishCreation):
+        (JSC::ArrayIteratorPrototype::getOwnPropertySlot):
+        (JSC::arrayIteratorProtoFuncIterator):
+        (JSC::arrayIteratorPrototypeIterate): Deleted.
+        * runtime/ArrayIteratorPrototype.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/Intrinsic.h:
+        * runtime/IteratorOperations.cpp: Added.
+        (JSC::iteratorNext):
+        (JSC::iteratorValue):
+        (JSC::iteratorComplete):
+        (JSC::iteratorStep):
+        (JSC::iteratorClose):
+        (JSC::createIterResultObject):
+        * runtime/IteratorOperations.h: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp.
+        * runtime/JSArrayIterator.cpp:
+        (JSC::JSArrayIterator::finishCreation):
+        (JSC::JSArrayIterator::visitChildren): Deleted.
+        (JSC::createIteratorResult): Deleted.
+        (JSC::arrayIteratorNext): Deleted.
+        (JSC::arrayIteratorNextKey): Deleted.
+        (JSC::arrayIteratorNextValue): Deleted.
+        (JSC::arrayIteratorNextGeneric): Deleted.
+        * runtime/JSArrayIterator.h:
+        (JSC::JSArrayIterator::JSArrayIterator):
+        (JSC::JSArrayIterator::iterationKind): Deleted.
+        (JSC::JSArrayIterator::iteratedObject): Deleted.
+        (JSC::JSArrayIterator::nextIndex): Deleted.
+        (JSC::JSArrayIterator::setNextIndex): Deleted.
+        (JSC::JSArrayIterator::finish): Deleted.
+        (JSC::JSArrayIterator::offsetOfIterationKind): Deleted.
+        (JSC::JSArrayIterator::offsetOfIteratedObject): Deleted.
+        (JSC::JSArrayIterator::offsetOfNextIndex): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::performPromiseRaceLoop):
+        (JSC::JSPromiseConstructorFuncRace):
+        (JSC::performPromiseAll):
+        (JSC::JSPromiseConstructorFuncAll):
+        * runtime/MapIteratorPrototype.cpp:
+        (JSC::MapIteratorPrototype::finishCreation):
+        (JSC::MapIteratorPrototypeFuncNext):
+        * runtime/SetIteratorPrototype.cpp:
+        (JSC::SetIteratorPrototype::finishCreation):
+        (JSC::SetIteratorPrototypeFuncNext):
+        * runtime/VM.cpp:
+        (JSC::thunkGeneratorForIntrinsic):
+        * tests/stress/array-iterators-next-with-call.js: Added.
+        (increment):
+        (for):
+        * tests/stress/array-iterators-next.js: Added.
+
+        Revive the older Array iterator tests that manually call 'next' method.
+
+        * tests/stress/custom-iterators.js: Added.
+        (iter.next):
+        (iter.Symbol.iterator):
+        (iter.return):
+        (iter.get next):
+        (iter.get return):
+        (iteratorInterfaceErrorTest.iter.next):
+        (iteratorInterfaceErrorTest.iter.Symbol.iterator):
+        (iteratorInterfaceErrorTest.iter.return):
+        (iteratorInterfaceErrorTest):
+        (iteratorInterfaceErrorTestReturn.iter.next):
+        (iteratorInterfaceErrorTestReturn.iter.Symbol.iterator):
+        (iteratorInterfaceErrorTestReturn.iter.return):
+        (iteratorInterfaceErrorTestReturn):
+        (iteratorInterfaceBreakTestReturn.iter.next):
+        (iteratorInterfaceBreakTestReturn.iter.Symbol.iterator):
+        (iteratorInterfaceBreakTestReturn.iter.return):
+        (iteratorInterfaceBreakTestReturn):
+
+        This tests the behavior of custom iterators.
+        'next' and 'return' of iterator work with for-of.
+
+        * tests/stress/iterators-shape.js: Added.
+        (iteratorShape):
+        (sameNextMethods):
+        (set var):
+
+        This tests the shape of iterators; iterators of Array have 'next' method in %ArrayIteratorPrototype%.
+
+        * tests/stress/map-iterators-next.js: Added.
+        (set var):
+        (.get if):
+        (otherKey):
+        * tests/stress/set-iterators-next.js: Added.
+        (otherKey):
+
+2015-03-04  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Hide Promise with runtime flags under Cocoa JSContext API
+        https://bugs.webkit.org/show_bug.cgi?id=141965
+
+        Reviewed by Filip Pizlo.
+
+        Since there's no run loop in JavaScriptCore APIs, Promises don't work currently.
+        So until they work, we hide Promise from a global object.
+        Introduce new JSC runtime flag, PromiseDisabled. When `isPromiseDisabled` is true,
+        Promise constructor is not attached to JSGlobalObject.
+
+        To make 0 as default runtime flags, we choose PromiseDisabled flag
+        instead of PromiseEnabled flag. So by default, Promise is enabled.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::JSCallbackObject):
+        * API/JSContextRef.cpp:
+        (javaScriptRuntimeFlags):
+        (JSGlobalContextCreateInGroup):
+        * API/tests/testapi.c:
+        (main):
+        * API/tests/testapi.mm:
+        (testObjectiveCAPI):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::create):
+        * runtime/RuntimeFlags.h:
+        (JSC::RuntimeFlags::createAllEnabled):
+
+2015-03-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Array/Collection Sizes should be visible and distinct
+        https://bugs.webkit.org/show_bug.cgi?id=142254
+
+        Reviewed by Timothy Hatcher.
+
+        * runtime/WeakMapData.h:
+        (JSC::WeakMapData::size):
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::weakMapSize):
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionWeakMapSize):
+        Add a way to get a WeakMap's size.
+
+        * inspector/protocol/Runtime.json:
+        Include size in RemoteObject and ObjectPreview.
+
+        * inspector/InjectedScriptSource.js:
+        Set the size of RemoteObjects and previews if they
+        are array/collection types.
+
+2015-03-04  Andreas Kling  <akling@apple.com>
+
+        GC should compute stack bounds and dump registers at the earliest opportunity.
+        <https://webkit.org/b/142310>
+        <rdar://problem/20045624>
+
+        Reviewed by Geoffrey Garen.
+
+        Make Heap::collect() a wrapper function around a collectImpl() where the work is actually done.
+        The wrapper function that grabs a snapshot of the current stack boundaries and register values
+        on entry, and sanitizes the stack on exit.
+
+        This is a speculative fix for what appears to be overly conservative behavior in the garbage
+        collector following r178364 which caused a measurable regression in memory usage on Membuster.
+        The theory being that we were putting pointers to dead things on the stack before scanning it,
+        and by doing that ended up marking things that we'd otherwise discover to be garbage.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::gatherStackRoots):
+        (JSC::Heap::collect):
+        (JSC::Heap::collectImpl):
+        * heap/Heap.h:
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::gatherFromCurrentThread):
+        (JSC::MachineThreads::gatherConservativeRoots):
+        * heap/MachineStackMarker.h:
+
+2015-03-04  Debarshi Ray  <debarshir@gnome.org>
+
+        Silence GCC's -Wstrict-prototypes
+        https://bugs.webkit.org/show_bug.cgi?id=142278
+
+        Reviewed by Alexey Proskuryakov.
+
+        * API/JSContextRef.h:
+
+2015-03-04  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Add a node for Math.log()
+        https://bugs.webkit.org/show_bug.cgi?id=142126
+
+        Reviewed by Geoffrey Garen.
+
+        This patch adds the DFG node ArithLog for LogIntrinsic.
+
+        Having a direct call to log has very little value by itself, the implementation
+        in DFG and FTL is a simple function call.
+
+        What is useful in ArithLog is that we know the operation is pure.
+        This allow us to hoist it out of loops when the argument is independent
+        is an invariant of the loop.
+
+        Perf wise, this patch gives:
+        -Kraken's imaging-darkroom: definitely 1.2372x faster.
+        -AsmBench's Towers.c: definitely 1.0261x faster.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithLog):
+        * dfg/DFGSpeculativeJIT.h:
+        * 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/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithLog):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleLog):
+        * tests/stress/math-log-basics.js: Added.
+        * tests/stress/math-log-with-constants.js: Added.
+
+2015-03-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Only Heap should be in charge of deciding how to select a subspace for a type
+        https://bugs.webkit.org/show_bug.cgi?id=142304
+
+        Reviewed by Mark Lam.
+        
+        This slightly reduces the code duplication for selecting subspace based on type, and what
+        duplication is left is at least localized in HeapInlines.h. The immediate effect is that
+        the DFG and FTL don't have to duplicate this pattern.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+        (JSC::DFG::SpeculativeJIT::emitAllocateVariableSizedJSObject):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::allocateObject):
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::allocateObjectOfType):
+        (JSC::Heap::subspaceForObjectOfType):
+        (JSC::Heap::allocatorForObjectOfType):
+        * runtime/JSCellInlines.h:
+        (JSC::allocateCell):
+
+2015-03-04  Andreas Kling  <akling@apple.com>
+
+        Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
+        <https://webkit.org/b/142115>
+        <rdar://problem/19992268>
+
+        Reviewed by Geoffrey Garen.
+
+        Prune stale entries from WeakGCMaps as part of every full garbage collection.
+        This frees up tons of previously-stuck WeakBlocks that were only sitting around
+        with finalized handles waiting to die.
+
+        Note that WeakGCMaps register/unregister themselves with the GC heap in their
+        ctor/dtor, so creating one now requires passing the VM.
+
+        Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
+        to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
+        It seems somewhat excessive to do this on every Eden collection, so it's only
+        doing work in full collections for now.
+
+        * API/JSWeakObjectMapRefInternal.h:
+        (OpaqueJSWeakObjectMap::create):
+        (OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
+        * API/JSWeakObjectMapRefPrivate.cpp:
+        * API/JSWrapperMap.mm:
+        (-[JSWrapperMap initWithContext:]):
+        (-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make
+        it project-private so WebCore clients can access it.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        (JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
+        stale entries from WeakGCMaps. This is only executed during full collections.
+
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::registerWeakGCMap):
+        (JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
+        themselves with the Heap and provide a pruning callback.
+
+        * runtime/PrototypeMap.h:
+        (JSC::PrototypeMap::PrototypeMap):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.
+
+        * runtime/JSCInlines.h: Add "WeakGCMapInlines.h"
+
+        * runtime/JSGlobalObject.cpp: Include "WeakGCMapInlines.h" so this builds.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM): Pass VM to WeakGCMap constructor.
+
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::set):
+        (JSC::WeakGCMap::add):
+        (JSC::WeakGCMap::WeakGCMap): Deleted.
+        (JSC::WeakGCMap::gcMap): Deleted.
+        (JSC::WeakGCMap::gcMapIfNeeded): Deleted.
+        * runtime/WeakGCMapInlines.h: Added.
+        (JSC::WeakGCMap::WeakGCMap):
+        (JSC::WeakGCMap::~WeakGCMap):
+        (JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
+        to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
+        prunes WeakGCMap at certain growth milestones and instead rely on the GC
+        callback for housekeeping.
+
+2015-03-03  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG IR should refer to FunctionExecutables directly and not via the CodeBlock
+        https://bugs.webkit.org/show_bug.cgi?id=142229
+
+        Reviewed by Mark Lam and Benjamin Poulain.
+        
+        Anytime a DFG IR node refers to something in CodeBlock, it has three effects:
+
+        - Cumbersome API for accessing the thing that the node refers to.
+        
+        - Not obvious how to create a new such node after bytecode parsing, especially if the
+          thing it refers to isn't already in the CodeBlock. We have done this in the past, but
+          it usually involves subtle changes to CodeBlock.
+        
+        - Not obvious how to inline code that ends up using such nodes. Again, when we have done
+          this, it involved subtle changes to CodeBlock.
+        
+        Prior to this change, the NewFunction* node types used an index into tables in CodeBlock.
+        For this reason, those operations were not inlineable. But the functin tables in CodeBlock
+        just point to FunctionExecutables, which are cells; this means that we can just abstract
+        these operands in DFG IR as cellOperands. cellOperands use DFG::FrozenValue, which means
+        that GC registration happens automagically. Even better, our dumping for cellOperand
+        already did FunctionExecutable dumping - so that functionality gets to be deduplicated.
+        
+        Because this change increases the number of users of cellOperand, it also adds some
+        convenience methods for using it. For example, whereas before you'd say things like:
+        
+            jsCast<Foo*>(node->cellOperand()->value())
+        
+        you can now just say:
+        
+            node->castOperand<Foo*>()
+        
+        This change also changes existing cellOperand users to use the new conveniance API when
+        applicable.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettisonFunctionDeclsAndExprs):
+        * bytecode/CodeBlock.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGFrozenValue.h:
+        (JSC::DFG::FrozenValue::cell):
+        (JSC::DFG::FrozenValue::dynamicCast):
+        (JSC::DFG::FrozenValue::cast):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::registerFrozenValues):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::castOperand):
+        (JSC::DFG::Node::hasFunctionDeclIndex): Deleted.
+        (JSC::DFG::Node::functionDeclIndex): Deleted.
+        (JSC::DFG::Node::hasFunctionExprIndex): Deleted.
+        (JSC::DFG::Node::functionExprIndex): Deleted.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCheckCell):
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+
+2015-03-03  Michael Saboff  <msaboff@apple.com>
+
+        DelayedReleaseScope drops locks during GC which can cause a thread switch and code reentry
+        https://bugs.webkit.org/show_bug.cgi?id=141275
+
+        Reviewed by Geoffrey Garen.
+
+        The original issue is that the CodeCache uses an unsafe method to add new UnlinkedCodeBlocks.
+        It basically adds a null UnlinkedCodeBlock if there isn't a cached entry and then later
+        updates the null entry to the result of the compilation.  If during that compilation and
+        related processing we need to garbage collect, the DelayedReleaseScope would drop locks
+        possibly allowing another thread to try to get the same source out of the CodeCache.
+        This second thread would find the null entry and crash.  The fix is to move the processing of
+        DelayedReleaseScope to when we drop locks and not drop locks during GC.  That was done in
+        the original patch with the new function releaseDelayedReleasedObjects().
+
+        Updated releaseDelayedReleasedObjects() so that objects are released with all locks
+        dropped.  Now its processing follows these steps
+            Increment recursion counter and do recursion check and exit if recursing
+            While there are objects to release
+                ASSERT that lock is held by current thread
+                Take all items from delayed release Vector and put into temporary Vector
+                Release API lock
+                Release and clear items from temporary vector
+                Reaquire API lock
+        This meets the requirement that we release while the API lock is released and it is
+        safer processing of the delayed release Vector.
+
+        Added new regression test to testapi.
+
+        Also added comment describing how recursion into releaseDelayedReleasedObjects() is
+        prevented.
+
+        * API/tests/Regress141275.h: Added.
+        * API/tests/Regress141275.mm: Added.
+        (+[JSTEvaluatorTask evaluatorTaskWithEvaluateBlock:completionHandler:]):
+        (-[JSTEvaluator init]):
+        (-[JSTEvaluator initWithScript:]):
+        (-[JSTEvaluator _accessPendingTasksWithBlock:]):
+        (-[JSTEvaluator insertSignPostWithCompletion:]):
+        (-[JSTEvaluator evaluateScript:completion:]):
+        (-[JSTEvaluator evaluateBlock:completion:]):
+        (-[JSTEvaluator waitForTasksDoneAndReportResults]):
+        (__JSTRunLoopSourceScheduleCallBack):
+        (__JSTRunLoopSourcePerformCallBack):
+        (__JSTRunLoopSourceCancelCallBack):
+        (-[JSTEvaluator _jsThreadMain]):
+        (-[JSTEvaluator _sourceScheduledOnRunLoop:]):
+        (-[JSTEvaluator _setupEvaluatorThreadContextIfNeeded]):
+        (-[JSTEvaluator _callCompletionHandler:ifNeededWithError:]):
+        (-[JSTEvaluator _sourcePerform]):
+        (-[JSTEvaluator _sourceCanceledOnRunLoop:]):
+        (runRegress141275):
+        * API/tests/testapi.mm:
+        (testObjectiveCAPI):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/Heap.cpp:
+        (JSC::Heap::releaseDelayedReleasedObjects):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::unlock):
+
+2015-03-03  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should constant fold GetScope, and accesses to the scope register in the ByteCodeParser should not pretend that it's a constant as that breaks OSR exit liveness tracking
+        https://bugs.webkit.org/show_bug.cgi?id=106202
+
+        Rubber stamped by Benjamin Poulain.
+        
+        This fixes a bug discovered by working on https://bugs.webkit.org/show_bug.cgi?id=142229,
+        which was in turn discovered by working on https://bugs.webkit.org/show_bug.cgi?id=141174.
+        Our way of dealing with scopes known to be constant is very sketchy, and only really works
+        when a function is inlined. When it is, we pretend that every load of the scopeRegister sees
+        a constant. But this breaks the DFG's tracking of the liveness of the scopeRegister. The way
+        this worked made us miss oppportunities for optimizing based on a constant scope, and it also
+        meant that in some cases - particularly like when we inline code that uses NewFuction and
+        friends, as I do in bug 142229 - it makes OSR exit think that the scope is dead even though
+        it's most definitely alive and it's a constant.
+        
+        The problem here is that we were doing too many optimizations in the ByteCodeParser, and not
+        later. Later optimization phases know how to preserve OSR exit liveness. They're actually
+        really good at it. Also, later phases know how to infer that any variable is a constant no
+        matter how that constant arose - rather than the inlining-specific thing in ByteCodeParser.
+        
+        This changes the ByteCodeParser to largely avoid doing constant folding on the scope, except
+        making the GetScope operation itself a constant. This is a compilation-time hack for small
+        functions, and it doesn't break the loads of local variables - so OSR exit liveness still
+        sees that the scopeRegister is in use. This then adds a vastly more powerful GetScope and
+        GetClosureVar constant folder in the AbstractInterpreter. This handles most general cases
+        including those that arise in complex control flow. This will catch cases where the scope
+        is constant for any number of reasons. Basically anytime that the callee is inferred constant
+        this will give us a constant scope. Also, we still have the parse-time constant folding of
+        ResolveScope based on the reentry watchpoint, which luckily did the right thing with respect
+        to OSR exit liveness (it splats a Phantom on its inputs, and it produces a constant result
+        which is then set() normally).
+        
+        This appears to be a broad speed-up, albeit a small one. But mainly it unblocks bug 142229,
+        which then should unblock bug 141174.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::getLocal):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::parse):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetConstantClosureVar):
+        (JSC::DFG::Graph::tryGetRegisters):
+        (JSC::DFG::Graph::tryGetActivation): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasVariableWatchpointSet):
+        (JSC::DFG::Node::hasSymbolTable): Deleted.
+        (JSC::DFG::Node::symbolTable): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::visitChildren):
+        (JSC::SymbolTable::localToEntry):
+        (JSC::SymbolTable::entryFor):
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        * tests/stress/function-expression-exit.js: Added.
+        * tests/stress/function-reentry-infer-on-self.js: Added.
+        (thingy):
+        * tests/stress/goofy-function-reentry-incorrect-inference.js: Added.
+
+2015-03-03  Anders Carlsson  <andersca@apple.com>
+
+        Remove unused compression code
+        https://bugs.webkit.org/show_bug.cgi?id=142237
+
+        Reviewed by Geoffrey Garen.
+
+        * bytecode/UnlinkedCodeBlock.h:
+
+2015-03-03  Filip Pizlo  <fpizlo@apple.com>
+
+        JIT debugging features that selectively disable the JITs for code blocks need to stay out of the way of the critical path of JIT management
+        https://bugs.webkit.org/show_bug.cgi?id=142234
+
+        Reviewed by Mark Lam and Benjamin Poulain.
+        
+        Long ago, we used to selectively disable compilation of CodeBlocks for debugging purposes by
+        adding hacks to DFGDriver.cpp.  This was all well and good.  It used the existing
+        CompilationFailed mode of the DFG driver to signal failure of CodeBlocks that we didn't want
+        to compile.  That's great because CompilationFailed is a well-supported return value on the
+        critical path, usually used for when we run out of JIT memory.
+
+        Later, this was moved into DFGCapabilities. This was basically incorrect. It introduced a bug
+        where disabling compiling of a CodeBlock meant that we stopped inlining it as well.  So if
+        you had a compiler bug that arose if foo was inlined into bar, and you bisected down to bar,
+        then foo would no longer get inlined and you wouldn't see the bug.  That's busted.
+
+        So then we changed the code in DFGCapabilities to mark bar as CanCompile and foo as
+        CanInline. Now, foo wouldn't get compiled alone but it would get inlined.
+
+        But then we removed CanCompile because that capability mode only existed for the purpose of
+        our old varargs hacks.  After that removal, "CanInline" became CannotCompile.  This means
+        that if you bisect down on bar in the "foo inlined into bar" case, you'll crash in the DFG
+        because the baseline JIT wouldn't have known to insert profiling on foo.
+
+        We could fix this by bringing back CanInline.
+
+        But this is all a pile of nonsense.  The debug support to selectively disable compilation of
+        some CodeBlocks shouldn't cross-cut our entire engine and should most certainly never involve
+        adding new capability modes.  This support is a hack at best and is for use by JSC hackers
+        only.  It should be as unintrusive as possible.
+
+        So, as in the ancient times, the only proper place to put this hack is in DFGDriver.cpp, and
+        return CompilationFailed.  This is correct not just because it takes capability modes out of
+        the picture (and obviates the need to introduce new ones), but also because it means that
+        disabling compilation doesn't change the profiling mode of other CodeBlocks in the Baseline
+        JIT.  Capability mode influences profiling mode which in turn influences code generation in
+        the Baseline JIT, sometimes in very significant ways - like, we sometimes do additional
+        double-to-int conversions in Baseline if we know that we might tier-up into the DFG, since
+        this buys us more precise profiling.
+        
+        This change reduces the intrusiveness of debugging hacks by making them use the very simple
+        CompilationFailed mechanism rather than trying to influence capability modes. Capability
+        modes have very subtle effects on the whole engine, while CompilationFailed just makes the
+        engine pretend like the DFG compilation will happen at timelike infinity. That makes these
+        hacks much more likely to continue working as we make other changes to the system.
+        
+        This brings back the ability to bisect down onto a function bar when bar inlines foo. Prior
+        to this change, we would crash in that case.
+
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupported):
+        (JSC::DFG::mightCompileEval):
+        (JSC::DFG::mightCompileProgram):
+        (JSC::DFG::mightCompileFunctionForCall):
+        (JSC::DFG::mightCompileFunctionForConstruct):
+        * dfg/DFGCapabilities.h:
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+
+2015-03-03  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win64] JSC compile error.
+        https://bugs.webkit.org/show_bug.cgi?id=142216
+
+        Reviewed by Mark Lam.
+
+        There is missing a version of setupArgumentsWithExecState when NUMBER_OF_ARGUMENT_REGISTERS == 4.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2015-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG compile time measurements should really report milliseconds
+        https://bugs.webkit.org/show_bug.cgi?id=142209
+
+        Reviewed by Benjamin Poulain.
+        
+        Fix this to record milliseconds instead of seconds.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThread):
+        (JSC::DFG::Plan::compileInThreadImpl):
+
+2015-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove op_get_callee, it's unused
+        https://bugs.webkit.org/show_bug.cgi?id=142206
+
+        Reviewed by Andreas Kling.
+        
+        It's a bit of a shame that we stopped using this opcode since it gives us same-callee
+        profiling. But, if we were to add this functionality back in, we would almost certainly do
+        it by adding a JSFunction allocation watchpoint on FunctionExecutable.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_get_callee): Deleted.
+        (JSC::JIT::emitSlow_op_get_callee): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_get_callee): Deleted.
+        (JSC::JIT::emitSlow_op_get_callee): Deleted.
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+
+2015-03-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Context Menu to Log a Particular Object
+        https://bugs.webkit.org/show_bug.cgi?id=142198
+
+        Reviewed by Timothy Hatcher.
+
+        Add a protocol method to assign a $n index to a value. For an object
+        use the injected script context for that object. For a value, use
+        the execution context to know where to save the value.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::saveResult):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::saveResult):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Debugger.json:
+        * inspector/protocol/Runtime.json:
+
+2015-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        SpeculativeJIT::emitAllocateArguments() should be a bit faster, and shouldn't do destructor initialization
+        https://bugs.webkit.org/show_bug.cgi?id=142197
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Use shift instead of mul, since mul doesn't automatically strength-reduce to shift. Also pass the structure as a TrustedImmPtr.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateVariableSizedJSObject): Rationalize this a bit. The other emitAllocate... methods take a templated structure so that it can be either a TrustedImmPtr or a register. Also don't do destructor initialization, since its one client doesn't need it, and it's actually probably wrong.
+
+2015-03-02  Mark Lam  <mark.lam@apple.com>
+
+        Exception stack unwinding in JSC hangs while the Timeline Profiler is enabled.
+        <https://webkit.org/b/142191>
+
+        Reviewed by Geoffrey Garen.
+
+        Imagine a scenario where the Inspector is paused / suspended at a breakpoint or
+        while the user is stepping through JS code. The user then tries to evaluate an
+        expression in the console, and that evaluation results in an exception being
+        thrown. Currently, if the Timeline Profiler is enabled while this exception is
+        being thrown, the WebProcess will hang while trying to handle that exception.
+
+        The issue is that the Timeline Profiler's ProfileGenerator::didExecute() will
+        return early and decline to process ProfileNodes if the Inspector is paused.
+        This is proper because it does not want to count work done for injected scripts
+        (e.g. from the console) towards the timeline profile of the webpage being run.
+        However, this is in conflict with ProfileGenerator::exceptionUnwind()'s
+        expectation that didExecute() will process ProfileNodes in order to do the stack
+        unwinding for the exception handling. As a result,
+        ProfileGenerator::exceptionUnwind() hangs.
+
+        ProfileGenerator::exceptionUnwind() is in error. While the Inspector is paused,
+        there will not be any ProfileNodes that it needs to "unwind". Hence, the fix is
+        simply to return early also in ProfileGenerator::exceptionUnwind() if the
+        Inspector is paused.
+
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::exceptionUnwind):
+
+2015-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should correctly document where it puts the argument count for inlined varargs frames
+        https://bugs.webkit.org/show_bug.cgi?id=142187
+
+        Reviewed by Geoffrey Garn.
+        
+        After LLVM tells us where the captured variables alloca landed in the frame, we need to
+        tell all of our meta-data about it. We were forgetting to do so for the argument count
+        register, which is used by inlined varargs calls.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * tests/stress/inline-varargs-get-arguments.js: Added.
+        (foo):
+        (bar):
+        (baz):
+
+2015-03-02  Filip Pizlo  <fpizlo@apple.com>
+
+        Deduplicate slow path calling code in JITOpcodes.cpp/JITOpcodes32_64.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=142184
+
+        Reviewed by Michael Saboff.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_get_enumerable_length):
+        (JSC::JIT::emitSlow_op_has_structure_property):
+        (JSC::JIT::emit_op_has_generic_property):
+        (JSC::JIT::emit_op_get_structure_property_enumerator):
+        (JSC::JIT::emit_op_get_generic_property_enumerator):
+        (JSC::JIT::emit_op_to_index_string):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_get_enumerable_length): Deleted.
+        (JSC::JIT::emitSlow_op_has_structure_property): Deleted.
+        (JSC::JIT::emit_op_has_generic_property): Deleted.
+        (JSC::JIT::emit_op_get_structure_property_enumerator): Deleted.
+        (JSC::JIT::emit_op_get_generic_property_enumerator): Deleted.
+        (JSC::JIT::emit_op_to_index_string): Deleted.
+        (JSC::JIT::emit_op_profile_control_flow): Deleted.
+
+2015-03-02  Antti Koivisto  <antti@apple.com>
+
+        Add way to dump cache meta data to file
+        https://bugs.webkit.org/show_bug.cgi?id=142183
+
+        Reviewed by Andreas Kling.
+
+        Export appendQuotedJSONStringToBuilder.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ObjectPatternNode::toString):
+        * runtime/JSONObject.cpp:
+        (JSC::appendQuotedJSONStringToBuilder):
+        (JSC::Stringifier::appendQuotedString):
+        (JSC::escapeStringToBuilder): Deleted.
+        * runtime/JSONObject.h:
+
+2015-03-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Add Context Menus to Object Tree properties
+        https://bugs.webkit.org/show_bug.cgi?id=142125
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::functionDetails):
+        Update to include columnNumber.
+
+2015-03-01  Filip Pizlo  <fpizlo@apple.com>
+
+        BytecodeGenerator shouldn't emit op_resolve_scope as a roundabout way of returning the scopeRegister
+        https://bugs.webkit.org/show_bug.cgi?id=142153
+
+        Reviewed by Michael Saboff.
+        
+        We don't need a op_resolve_scope if we know that it will simply return the scope register.
+        This changes the BytecodeGenerator to use the scope register directly in those cases where
+        we know statically that we would just have returned that from op_resolve_scope.
+        
+        This doesn't appear to have a significant impact on performance.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitReturn):
+        (JSC::BytecodeGenerator::emitGetOwnScope): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (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::EmptyVarExpression::emitBytecode):
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::BindingNode::bindValue):
+
+2015-02-27  Benjamin Poulain  <bpoulain@apple.com>
+
+        [JSC] Use the way number constants are written to help type speculation
+        https://bugs.webkit.org/show_bug.cgi?id=142072
+
+        Reviewed by Filip Pizlo.
+
+        This patch changes how we interpret numeric constant based on how they appear
+        in the source.
+
+        Constants that are integers but written with a decimal point now carry that information
+        to the optimizating tiers. From there, we use that to be more aggressive about typing
+        math operations toward double operations.
+
+        For example, in:
+            var a = x + 1.0;
+            var b = y + 1;
+        The Add for a would be biased toward doubles, the Add for b would speculate
+        integer as usual.
+
+
+        The gains are tiny but this is a prerequisite to make my next patch useful:
+        -SunSpider's access-fannkuch: definitely 1.0661x faster
+        -SunSpider's math-cordic: definitely 1.0266x slower
+            overal: might be 1.0066x slower.
+        -Kraken's imaging-darkroom: definitely 1.0333x faster.
+
+        * parser/Lexer.cpp:
+        (JSC::tokenTypeForIntegerLikeToken):
+        (JSC::Lexer<T>::lex):
+        The lexer now create two types of tokens for number: INTEGER and DOUBLE.
+        Those token types only carry information about how the values were
+        entered, an INTEGER does not have to be an integer, it is only written like one.
+        Large integer still end up represented as double in memory.
+
+        One trap I fell into was typing numbers like 12e3 as double. This kind of literal
+        is frequently used in integer-typed code, while 12.e3 would appear in double-typed
+        code.
+        Because of that, the only signals for double are: decimal point, negative zero,
+        and ridiculously large values.
+
+        * parser/NodeConstructors.h:
+        (JSC::DoubleNode::DoubleNode):
+        (JSC::IntegerNode::IntegerNode):
+        * parser/Nodes.h:
+        (JSC::NumberNode::value):
+        (JSC::NumberNode::setValue): Deleted.
+        Number get specialized in two new kind of nodes in the AST: IntegerNode and DoubleNode.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::NumberNode::emitBytecode):
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createDoubleExpr):
+        (JSC::ASTBuilder::createIntegerExpr):
+        (JSC::ASTBuilder::createIntegerLikeNumber):
+        (JSC::ASTBuilder::createDoubleLikeNumber):
+        (JSC::ASTBuilder::createNumberFromBinaryOperation):
+        (JSC::ASTBuilder::createNumberFromUnaryOperation):
+        (JSC::ASTBuilder::makeNegateNode):
+        (JSC::ASTBuilder::makeBitwiseNotNode):
+        (JSC::ASTBuilder::makeMultNode):
+        (JSC::ASTBuilder::makeDivNode):
+        (JSC::ASTBuilder::makeModNode):
+        (JSC::ASTBuilder::makeAddNode):
+        (JSC::ASTBuilder::makeSubNode):
+        (JSC::ASTBuilder::makeLeftShiftNode):
+        (JSC::ASTBuilder::makeRightShiftNode):
+        (JSC::ASTBuilder::makeURightShiftNode):
+        (JSC::ASTBuilder::makeBitOrNode):
+        (JSC::ASTBuilder::makeBitAndNode):
+        (JSC::ASTBuilder::makeBitXOrNode):
+        (JSC::ASTBuilder::createNumberExpr): Deleted.
+        (JSC::ASTBuilder::createNumber): Deleted.
+        The AST has some optimization to resolve constants before emitting bytecode.
+        In the new code, the intger representation is kept if both operands where
+        also represented as integers.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseDeconstructionPattern):
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseGetterSetter):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        (JSC::Parser<LexerType>::printUnexpectedTokenText):
+        * parser/ParserTokens.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createDoubleExpr):
+        (JSC::SyntaxChecker::createIntegerExpr):
+        (JSC::SyntaxChecker::createNumberExpr): Deleted.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::registerName):
+        (JSC::CodeBlock::constantName):
+        Change constantName(r, getConstant(r)) -> constantName(r) to simplify
+        the dump code.
+
+        (JSC::CodeBlock::dumpBytecode):
+        Dump thre soure representation information we have with each constant.
+
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::shrinkToFit):
+        (JSC::constantName): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::constantsSourceCodeRepresentation):
+        (JSC::CodeBlock::addConstant):
+        (JSC::CodeBlock::addConstantLazily):
+        (JSC::CodeBlock::constantSourceCodeRepresentation):
+        (JSC::CodeBlock::setConstantRegisters):
+
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::addConstant):
+        (JSC::UnlinkedCodeBlock::constantsSourceCodeRepresentation):
+        (JSC::UnlinkedCodeBlock::shrinkToFit):
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addConstantValue):
+        (JSC::BytecodeGenerator::emitLoad):
+        * bytecompiler/BytecodeGenerator.h:
+        We have to differentiate between constants that have the same values but are
+        represented differently in the source. Values like 1.0 and 1 now end up
+        as different constants.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::addConstantToGraph):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::registerFrozenValues):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addSpeculationMode):
+        (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
+        ArithAdd is very aggressive toward using Int52, which is quite useful
+        in many benchmarks.
+
+        Here we need to specialize to make sure we don't force our literals
+        to Int52 if there were represented as double.
+
+        There is one exception to that rule: when the other operand is guaranteed
+        to come from a NodeResultInt32. This is because there is some weird code
+        doing stuff like:
+            var b = a|0;
+            var c = b*2.0;
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::Node):
+        (JSC::DFG::Node::setOpAndDefaultFlags):
+        (JSC::DFG::Node::sourceCodeRepresentation):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * runtime/JSCJSValue.h:
+        (JSC::EncodedJSValueWithRepresentationHashTraits::emptyValue):
+        (JSC::EncodedJSValueWithRepresentationHashTraits::constructDeletedValue):
+        (JSC::EncodedJSValueWithRepresentationHashTraits::isDeletedValue):
+        (JSC::EncodedJSValueWithRepresentationHash::hash):
+        (JSC::EncodedJSValueWithRepresentationHash::equal):
+        * tests/stress/arith-add-with-constants.js: Added.
+        * tests/stress/arith-mul-with-constants.js: Added.
+
+2015-02-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, roll out r180723. It broke a bunch of tests.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::constLocal):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConstDeclNode::emitCodeSingle):
+        * tests/stress/const-arguments.js: Removed.
+
+2015-02-26  Mark Lam  <mark.lam@apple.com>
+
+        Assertion fix for r180711: The bool returning form of BytecodeGenerator::addVar() can be removed.
+        <https://webkit.org/b/142064>
+
+        Reviewed by Joseph Pecoraro.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addVar):
+
+2015-02-26  Mark Lam  <mark.lam@apple.com>
+
+        MachineThreads::Thread clean up has a use after free race condition.
+        <https://webkit.org/b/141990>
+
+        Reviewed by Filip Pizlo.
+
+        MachineThreads::Thread clean up relies on the clean up mechanism
+        implemented in _pthread_tsd_cleanup_key(), which looks like this:
+
+        void _pthread_tsd_cleanup_key(pthread_t self, pthread_key_t key)
+        {
+            void (*destructor)(void *);
+            if (_pthread_key_get_destructor(key, &destructor)) {
+                void **ptr = &self->tsd[key];
+                void *value = *ptr;
+
+            // === Start of window for the bug to manifest =================
+
+                // At this point, this thread has cached "destructor" and "value"
+                // (which is a MachineThreads*).  If the VM gets destructed (along
+                // with its MachineThreads registry) by another thread, then this
+                // thread will have no way of knowing that the MachineThreads* is
+                // now pointing to freed memory.  Calling the destructor below will
+                // therefore result in a use after free scenario when it tries to
+                // access the MachineThreads' data members.
+
+                if (value) {
+                    *ptr = NULL;
+                    if (destructor) {
+
+            // === End of window for the bug to manifest ==================
+
+                        destructor(value);
+                    }
+                }
+            }
+        }
+
+        The fix is to add each active MachineThreads to an ActiveMachineThreadsManager,
+        and always check if the manager still contains that MachineThreads object
+        before we call removeCurrentThread() on it.  When MachineThreads is destructed,
+        it will remove itself from the manager.  The add, remove, and checking
+        operations are all synchronized on the manager's lock, thereby ensuring that
+        the MachineThreads object, if found in the manager, will remain alive for the
+        duration of time we call removeCurrentThread() on it.
+
+        There's also possible for the MachineThreads object to already be destructed
+        and another one happened to have been instantiated at the same address.
+        Hence, we should only remove the exiting thread if it is found in the
+        MachineThreads object.
+
+        There is no test for this issue because this bug requires a race condition
+        between 2 threads where:
+        1. Thread B, which had previously used the VM, exiting and
+           getting to the bug window shown in _pthread_tsd_cleanup_key() above.
+        2. Thread A destructing the VM (and its MachineThreads object)
+           within that window of time before Thread B calls the destructor.
+
+        It is not possible to get a reliable test case without invasively
+        instrumenting _pthread_tsd_cleanup_key() or MachineThreads::removeCurrentThread()
+        to significantly increase that window of opportunity.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::ActiveMachineThreadsManager::Locker::Locker):
+        (JSC::ActiveMachineThreadsManager::add):
+        (JSC::ActiveMachineThreadsManager::remove):
+        (JSC::ActiveMachineThreadsManager::contains):
+        (JSC::ActiveMachineThreadsManager::ActiveMachineThreadsManager):
+        (JSC::activeMachineThreadsManager):
+        (JSC::MachineThreads::MachineThreads):
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::removeThread):
+        (JSC::MachineThreads::removeThreadIfFound):
+        (JSC::MachineThreads::removeCurrentThread): Deleted.
+        * heap/MachineStackMarker.h:
+
+2015-02-26  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Save Console Evaluations into Command Line variables $1-$99 ($n)
+        https://bugs.webkit.org/show_bug.cgi?id=142061
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Debugger.json:
+        * inspector/protocol/Runtime.json:
+        Input flag "saveResult" on whether we should try to save a result.
+        Output int "savedResultIndex" to tell the frontend the saved state.
+
+        * inspector/InjectedScriptSource.js:
+        Handle saving and clearing $1-$99 values.
+        Include in BasicCommandLineAPI for JSContext inspection.
+
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall):
+        * inspector/InjectedScriptBase.h:
+        Allow an optional "savedResultIndex" out value on evals.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::evaluate):
+        (Inspector::InjectedScript::evaluateOnCallFrame):
+        * inspector/InjectedScript.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::evaluate):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        Plumbing for new in and out parameters.
+
+2015-02-26  Filip Pizlo  <fpizlo@apple.com>
+
+        The bool returning form of BytecodeGenerator::addVar() can be removed
+        https://bugs.webkit.org/show_bug.cgi?id=142064
+
+        Reviewed by Mark Lam.
+        
+        It's easier to implement addVar() when you don't have to return whether it's a new
+        variable or not.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::addVar):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::addVar): Deleted.
+
+2015-02-26  Filip Pizlo  <fpizlo@apple.com>
+
+        Various array access corner cases should take OSR exit feedback
+        https://bugs.webkit.org/show_bug.cgi?id=142056
+
+        Reviewed by Geoffrey Garen.
+        
+        Two major changes here:
+        
+        - Don't keep converting GetById into GetArrayLength if we exited due to any kind of array
+          type check.
+        
+        - Use a generic form of GetByVal/PutByVal if we exited due to any kind of exotic checks,
+          like the Arguments safety checks. We use the "ExoticObjectMode" for out-of-bounds on
+          arguments for now, since it's a convenient way of forcing out-of-bounds to be handled by
+          the Generic array mode.
+
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        * bytecode/ExitKind.h:
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
+        * tests/stress/array-length-array-storage-plain-object.js: Added.
+        (foo):
+        * tests/stress/array-length-plain-object.js: Added.
+        (foo):
+
+2015-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG SSA stack accesses shouldn't speak of VariableAccessDatas
+        https://bugs.webkit.org/show_bug.cgi?id=142036
+
+        Reviewed by Michael Saboff.
+        
+        VariableAccessData is a useful thing in LoadStore and ThreadedCPS, but it's purely harmful in
+        SSA because you can't cook up new VariableAccessDatas. So, if you know that you want to load
+        or store to the stack, and you know what format to use as well as the location, then prior to
+        this patch you couldn't do it unless you found some existing VariableAccessData that matched
+        your requirements. That can be a hard task.
+        
+        It's better if SSA doesn't speak of VariableAccessDatas but instead just has stack accesses
+        that speak of the things that a stack access needs: local, machineLocal, and format. This
+        patch changes the SSA way of accessing the stack to do just that.
+        
+        Also add more IR validation.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::isConcrete):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::hasVariableAccessData):
+        * dfg/DFGNode.h:
+        (JSC::DFG::StackAccessData::StackAccessData):
+        (JSC::DFG::StackAccessData::flushedAt):
+        (JSC::DFG::Node::convertToPutStack):
+        (JSC::DFG::Node::convertToGetStack):
+        (JSC::DFG::Node::hasUnlinkedLocal):
+        (JSC::DFG::Node::hasStackAccessData):
+        (JSC::DFG::Node::stackAccessData):
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPutLocalSinkingPhase.cpp: Removed.
+        * dfg/DFGPutLocalSinkingPhase.h: Removed.
+        * dfg/DFGPutStackSinkingPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGPutLocalSinkingPhase.cpp.
+        (JSC::DFG::performPutStackSinking):
+        (JSC::DFG::performPutLocalSinking): Deleted.
+        * dfg/DFGPutStackSinkingPhase.h: Copied from Source/JavaScriptCore/dfg/DFGPutLocalSinkingPhase.h.
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateCPS):
+        (JSC::DFG::Validate::validateSSA):
+        * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+        (JSC::DFG::VirtualRegisterAllocationPhase::run):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetStack):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStack):
+        (JSC::FTL::LowerDFGToLLVM::compileGetLocal): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compilePutLocal): Deleted.
+        * ftl/FTLOSRExit.h:
+        * tests/stress/many-sunken-locals.js: Added. This failure mode was caught by some miscellaneous test, so I figured I should write an explicit test for it.
+        (foo):
+        (bar):
+        (baz):
+        (fuzz):
+        (buzz):
+
+2015-02-26  Mark Lam  <mark.lam@apple.com>
+
+        Rolling out r180602, r180608, r180613, r180617, r180671.
+        <https://webkit.org/b/141990>
+
+        Not reviewed.
+
+        The r180602 solution does result in more work for GC when worker
+        threads are in use.  Filip is uncomfortable with that.
+        The EFL and GTK ports also seem to be unhappy with this change.
+        Rolling out while we investigate.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::gatherStackRoots):
+        (JSC::Heap::machineThreads): Deleted.
+        * heap/Heap.h:
+        (JSC::Heap::machineThreads):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::MachineThreads):
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::addCurrentThread):
+        * heap/MachineStackMarker.h:
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::didAcquireLock):
+
+2015-02-26  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Mac] [iOS] Parsing support for -apple-trailing-word
+        https://bugs.webkit.org/show_bug.cgi?id=141939
+
+        Reviewed by Andreas Kling.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-02-26  Michael Saboff  <msaboff@apple.com>
+
+        [Win] Debug-only JavaScriptCore failures
+        https://bugs.webkit.org/show_bug.cgi?id=142045
+
+        Rubber stamped by Filip Pizlo.
+
+        Reduced loop count to a more reasonable value of 10,000.  This still gets us to tier up
+        to the FTL, but doesn't take too long to run.
+
+        * tests/stress/repeated-arity-check-fail.js:
+
+2015-02-26  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Make build logs more legible by reducing noise
+        https://bugs.webkit.org/show_bug.cgi?id=142034
+
+        Reviewed by Alexey Proskuryakov.
+
+        Modify batch files, makefiles, and DOS commands to remove
+        uninteresting/unhelpful output.
+
+        * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make:
+        * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.vcxproj/jsc/jscLauncherPreBuild.cmd:
+        * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiLauncherPostBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiLauncherPreBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd:
+        * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd:
+
+2015-02-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Add calleeSaveRegisters() implementation for ARM Traditional
+        https://bugs.webkit.org/show_bug.cgi?id=141903
+
+        Reviewed by Darin Adler.
+
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::calleeSaveRegisters):
+
+2015-02-25  Michael Saboff  <msaboff@apple.com>
+
+        Web Inspector: CRASH when debugger pauses inside a Promise handler
+        https://bugs.webkit.org/show_bug.cgi?id=141396
+
+        Reviewed by Mark Lam.
+
+        For frames that don't have a scope, typically native frames, use the lexicalGlobalObject to
+        create the DebuggerScope for that frame.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::scope):
+
+2015-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG abstract heaps should respect the difference between heap and stack
+        https://bugs.webkit.org/show_bug.cgi?id=142022
+
+        Reviewed by Geoffrey Garen.
+        
+        We will soon (https://bugs.webkit.org/show_bug.cgi?id=141174) be in a world where a "world
+        clobbering" operation cannot write to our stack, but may be able to read from it. This
+        means that we need to change the DFG abstract heap hierarchy to have a notion of Heap that
+        subsumes all that World previously subsumed, and a new notion of Stack that is a subtype
+        of World and a sibling of Heap.
+
+        So, henceforth "clobbering the world" means reading World and writing Heap.
+        
+        This makes a bunch of changes to make this work, including changing the implementation of
+        disjointness in AbstractHeap to make it support a more general hierarchy. I was expecting
+        a slow-down, but I measured the heck out of this and found no perf difference.
+
+        * dfg/DFGAbstractHeap.cpp:
+        (JSC::DFG::AbstractHeap::dump):
+        * dfg/DFGAbstractHeap.h:
+        (JSC::DFG::AbstractHeap::supertype):
+        (JSC::DFG::AbstractHeap::isStrictSubtypeOf):
+        (JSC::DFG::AbstractHeap::isSubtypeOf):
+        (JSC::DFG::AbstractHeap::overlaps):
+        (JSC::DFG::AbstractHeap::isDisjoint):
+        * dfg/DFGClobberize.cpp:
+        (JSC::DFG::clobbersHeap):
+        (JSC::DFG::clobbersWorld): Deleted.
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+
+2015-02-25  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180595): construct varargs fails in FTL
+        https://bugs.webkit.org/show_bug.cgi?id=142030
+
+        Reviewed by Geoffrey Garen.
+
+        The bug was caused by IC size being too small for construct_varargs even though we've added a new argument.
+        Fixed the bug by increasing the IC size to match call_varargs.
+
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfConstructVarargs):
+
+2015-02-25  Mark Lam  <mark.lam@apple.com>
+
+        ASan does not like JSC::MachineThreads::tryCopyOtherThreadStack.
+        <https://webkit.org/b/141672>
+
+        Reviewed by Alexey Proskuryakov.
+
+        ASan does not like the fact that we memcpy the stack for GC scans.  So,
+        we're working around this by using our own memcpy (asanUnsafeMemcpy)
+        implementation that we can tell ASan to ignore.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::asanUnsafeMemcpy):
+
+2015-02-25  Benjamin Poulain  <bpoulain@apple.com>
+
+        CodeBlock crashes when dumping op_push_name_scope
+        https://bugs.webkit.org/show_bug.cgi?id=141953
+
+        Reviewed by Filip Pizlo and Csaba Osztrogonác.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * tests/stress/op-push-name-scope-crashes-profiler.js: Added.
+
+2015-02-25  Benjamin Poulain  <benjamin@webkit.org>
+
+        Make ParserError immutable by design
+        https://bugs.webkit.org/show_bug.cgi?id=141955
+
+        Reviewed by Geoffrey Garen.
+
+        This patch enforce that no field of ParserError can
+        be modified after the constructor.
+
+        * parser/ParserError.h:
+        Move the attributes to pack the integer + 2 bytes together.
+        This is irrelevant for memory impact, it is to remve a load-store
+        when copying by value.
+
+        Also move the attributes to be private.
+
+        (JSC::ParserError::isValid):
+        To client of the interface cared about the type of the error,
+        the only information needed was: is there an error.
+
+        (JSC::ParserError::ParserError):
+        (JSC::ParserError::syntaxErrorType):
+        (JSC::ParserError::token):
+        (JSC::ParserError::message):
+        (JSC::ParserError::line):
+        (JSC::ParserError::toErrorObject):
+        * API/JSScriptRef.cpp:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+        * bytecode/UnlinkedCodeBlock.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::parse):
+        * jsc.cpp:
+        (runInteractive):
+        * parser/Parser.h:
+        (JSC::parse):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CodeCache.h:
+        * runtime/Completion.h:
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::createProgramCodeBlock):
+        (JSC::JSGlobalObject::createEvalCodeBlock):
+
+2015-02-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Need to pass RTLD_DEEPBIND to dlopen() to ensure that our LLVMOverrides take effect on Linux
+        https://bugs.webkit.org/show_bug.cgi?id=142006
+
+        Reviewed by Csaba Osztrogonác.
+
+        This fixes hard-to-reproduce concurrency-related crashes when running stress tests with FTL and
+        concurrent JIT enabled.
+
+        * llvm/InitializeLLVMPOSIX.cpp:
+        (JSC::initializeLLVMPOSIX):
+
+2015-02-24  Filip Pizlo  <fpizlo@apple.com>
+
+        CMake build of libllvmForJSC.so should limit its export list like the Xcode build does
+        https://bugs.webkit.org/show_bug.cgi?id=141989
+
+        Reviewed by Gyuyoung Kim.
+
+        * CMakeLists.txt:
+        * llvm/library/libllvmForJSC.version: Added.
+
+2015-02-24  Alexey Proskuryakov  <ap@apple.com>
+
+        More iOS build fix after r180602.
+
+        * heap/Heap.h: Export Heap::machineThreads().
+
+2015-02-24  Brent Fulgham  <bfulgham@apple.com>
+
+        Unreviewed build fix after r180602.
+
+        * heap/MachineStackMarker.h: Add missing 'no return'
+        declaration for Windows.
+
+2015-02-24  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r180599.
+        https://bugs.webkit.org/show_bug.cgi?id=141998
+
+        Lots of new test failures (Requested by smfr on #webkit).
+
+        Reverted changeset:
+
+        "Parsing support for -webkit-trailing-word"
+        https://bugs.webkit.org/show_bug.cgi?id=141939
+        http://trac.webkit.org/changeset/180599
+
+2015-02-24  Mark Lam  <mark.lam@apple.com>
+
+        MachineThreads::Thread clean up has a use after free race condition.
+        <https://webkit.org/b/141990>
+
+        Reviewed by Michael Saboff.
+
+        MachineThreads::Thread clean up relies on the clean up mechanism
+        implemented in _pthread_tsd_cleanup_key(), which looks like this:
+
+        void _pthread_tsd_cleanup_key(pthread_t self, pthread_key_t key)
+        {
+            void (*destructor)(void *);
+            if (_pthread_key_get_destructor(key, &destructor)) {
+                void **ptr = &self->tsd[key];
+                void *value = *ptr;
+
+                // At this point, this thread has cached "destructor" and "value"
+                // (which is a MachineThreads*).  If the VM gets destructed (along
+                // with its MachineThreads registry) by another thread, then this
+                // thread will have no way of knowing that the MachineThreads* is
+                // now pointing to freed memory.  Calling the destructor below will
+                // therefore result in a use after free scenario when it tries to
+                // access the MachineThreads' data members.
+
+                if (value) {
+                    *ptr = NULL;
+                    if (destructor) {
+                        destructor(value);
+                    }
+                }
+            }
+        }
+
+        The solution is simply to change MachineThreads from a per VM thread
+        registry to a process global singleton thread registry i.e. the
+        MachineThreads registry is now immortal and we cannot have a use after
+        free scenario since we never free it.
+
+        The cost of this change is that all VM instances will have to scan
+        stacks of all threads ever touched by a VM, and not just those that
+        touched a specific VM.  However, stacks tend to be shallow.  Hence,
+        those additional scans will tend to be cheap.
+
+        Secondly, it is not common for there to be multiple JSC VMs in use
+        concurrently on multiple threads.  Hence, this cost should rarely
+        manifest in real world applications.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::machineThreads):
+        (JSC::Heap::gatherStackRoots):
+        * heap/Heap.h:
+        (JSC::Heap::machineThreads): Deleted.
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::MachineThreads):
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::addCurrentThread):
+        * heap/MachineStackMarker.h:
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::didAcquireLock):
+
+2015-02-24  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Mac] [iOS] Parsing support for -apple-trailing-word
+        https://bugs.webkit.org/show_bug.cgi?id=141939
+
+        Reviewed by Andreas Kling.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-02-24  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Use "this" instead of "callee" to get the constructor
+        https://bugs.webkit.org/show_bug.cgi?id=141019
+
+        Reviewed by Filip Pizlo.
+
+        This patch uses "this" register to pass the constructor (newTarget) to op_create_this from
+        op_construct or op_construct_varargs. This will allow future patches that implement ES6 class
+        to pass in the most derived class' constructor through "this" argument.
+
+        BytecodeGenerator's emitConstruct and emitConstructVarargs now passes thisRegister like
+        regular calls and emitCreateThis passes in this register to op_create_this as constructor.
+
+        The rest of the code change removes the code for special casing "this" register not being used
+        in call to construct.
+
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitCreateThis):
+        (JSC::BytecodeGenerator::emitConstructVarargs):
+        (JSC::BytecodeGenerator::emitConstruct):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::NewExprNode::emitBytecode):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::handleVarargsCall):
+        (JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGJITCode.cpp:
+        (JSC::DFG::JITCode::reconstruct):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * ftl/FTLJSCallVarargs.cpp:
+        (JSC::FTL::JSCallVarargs::emit):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeConstruct):
+        * jit/JITOperations.cpp:
+
+2015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Make Getter/Setter RemoteObject property and ObjectPreview handling consistent
+        https://bugs.webkit.org/show_bug.cgi?id=141587
+
+        Reviewed by Timothy Hatcher.
+
+        Convert getProperties(ownAndGetterProperties) to getDisplayableProperties().
+        Mark PropertyDescriptors that are presumed to be native getters / bindings
+        separately so that the frontend may display them differently.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getDisplayableProperties):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        (Inspector::InspectorRuntimeAgent::getDisplayableProperties):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+
+2015-02-24  Mark Lam  <mark.lam@apple.com>
+
+        Rolling out r179753.  The fix was invalid.
+        <https://webkit.org/b/141990>
+
+        Not reviewed.
+
+        * API/tests/testapi.mm:
+        (threadMain):
+        (useVMFromOtherThread): Deleted.
+        (useVMFromOtherThreadAndOutliveVM): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::~Heap):
+        (JSC::Heap::gatherStackRoots):
+        * heap/Heap.h:
+        (JSC::Heap::machineThreads):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::Thread::Thread):
+        (JSC::MachineThreads::MachineThreads):
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::addCurrentThread):
+        (JSC::MachineThreads::removeThread):
+        (JSC::MachineThreads::removeCurrentThread):
+        * heap/MachineStackMarker.h:
+
+2015-02-24  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Constructor returning null should construct an object instead of null
+        https://bugs.webkit.org/show_bug.cgi?id=141640
+
+        Reviewed by Filip Pizlo.
+
+        When constructor code doesn't return object, constructor should return `this` object instead.
+        Since we used `op_is_object` for this check and `op_is_object` is intended to be used for `typeof`,
+        it allows `null` as an object.
+        This patch fixes it by introducing an new bytecode `op_is_object_or_null` for `typeof` use cases.
+        Instead, constructor uses simplified `is_object`.
+
+        As a result, `op_is_object` becomes fairly simple. So we introduce optimization for `op_is_object`.
+
+        1. LLInt and baseline JIT support `op_is_object` as a fast path.
+        2. DFG abstract interpreter support `op_is_object`. And recognize its speculated type and read-write effects.
+        3. DFG introduces inlined asm for `op_is_object` rather than calling a C++ function.
+        4. FTL lowers DFG's IsObject into LLVM IR.
+
+        And at the same time, this patch fixes isString / isObject predicate used for `op_is_object` and others
+        in LLInt, JIT, DFG and FTL.
+        Before introducing ES6 Symbol, JSCell is only used for object and string in user observable area.
+        So in many places, when the cell is not object, we recognize it as a string, and vice versa.
+        However, now ES6 Symbol is implemented as a JSCell, this assumption is broken.
+        So this patch stop using !isString as isObject.
+        To check whether a cell is an object, instead of seeing that structure ID of a cell is not stringStructure,
+        we examine typeInfo in JSCell.
+
+        * JavaScriptCore.order:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEqualityOp):
+        (JSC::BytecodeGenerator::emitReturn):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
+        IsObject operation only touches JSCell typeInfoType.
+        And this value would be changed through structure transition.
+        As a result, IsObject can report that it doesn't read any information.
+
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+        Just like IsString, IsObject is also fixed up.
+
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+        (JSC::DFG::SpeculativeJIT::speculateObject):
+        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+        (JSC::DFG::SpeculativeJIT::speculateString):
+        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        (JSC::DFG::SpeculativeJIT::branchIsObject):
+        (JSC::DFG::SpeculativeJIT::branchNotObject):
+        (JSC::DFG::SpeculativeJIT::branchIsString):
+        (JSC::DFG::SpeculativeJIT::branchNotString):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileToString):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObjectOrNull):
+        (JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotString):
+        (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::emitJumpIfCellObject):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_is_object):
+        (JSC::JIT::emit_op_to_primitive):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_is_object):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::compileOpStrictEq):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/Operations.cpp:
+        (JSC::jsIsObjectTypeOrNull):
+        (JSC::jsIsObjectType): Deleted.
+        * runtime/Operations.h:
+        * tests/stress/constructor-with-return.js: Added.
+        (Test):
+
+        When constructor doesn't return an object, `this` should be returned instead.
+        In this test, we check all primitives. And test object, array and wrappers.
+
+        * tests/stress/dfg-to-primitive-pass-symbol.js: Added.
+        (toPrimitiveTarget):
+        (doToPrimitive):
+
+        op_to_primitive operation passes Symbol in fast path.
+
+2015-02-24  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION(r179429): Can't type comments in Facebook
+        https://bugs.webkit.org/show_bug.cgi?id=141859
+
+        Reviewed by Brent Fulgham.
+
+        When window.Symbol is exposed to user-space pages,
+        Facebook's JavaScript use it (maybe, for immutable-js and React.js's unique key).
+        However, to work with Symbols completely, it also requires
+        1) Object.getOwnPropertySymbols (for mixin including Symbols)
+        2) the latest ES6 Iterator interface that uses Iterator.next and it returns { done: boolean, value: value }.
+        Since they are not landed yet, comments in Facebook don't work.
+
+        This patch introduces RuntimeFlags for JavaScriptCore.
+        Specifying SymbolEnabled flag under test runner and inspector to continue to work with Symbol.
+        And drop JavaScriptExperimentsEnabled flag
+        because it is no longer used and use case of this is duplicated to runtime flags.
+
+        * JavaScriptCore.order:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jsc.cpp:
+        (GlobalObject::javaScriptRuntimeFlags):
+        (GlobalObject::javaScriptExperimentsEnabled): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::finishCreation):
+        (JSC::JSGlobalObject::javaScriptRuntimeFlags):
+        (JSC::JSGlobalObject::javaScriptExperimentsEnabled): Deleted.
+        * runtime/RuntimeFlags.h: Added.
+        (JSC::RuntimeFlags::RuntimeFlags):
+        (JSC::RuntimeFlags::createAllEnabled):
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Our bizarre behavior on Arguments::defineOwnProperty should be deliberate rather than a spaghetti incident
+        https://bugs.webkit.org/show_bug.cgi?id=141951
+
+        Reviewed by Benjamin Poulain.
+        
+        This patch has no behavioral change, but it simplifies a bunch of wrong code. The code is
+        still wrong in exactly the same way, but at least it's obvious what's going on. The wrongness
+        is covered by this bug: https://bugs.webkit.org/show_bug.cgi?id=141952.
+
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyBackingStore): We should only see the arguments token; assert otherwise. This works because if the GC sees the butterfly token it calls the JSObject::copyBackingStore method directly.
+        (JSC::Arguments::defineOwnProperty): Make our bizarre behavior deliberate rather than an accident of a decade of patches.
+        * tests/stress/arguments-bizarre-behavior.js: Added.
+        (foo):
+        * tests/stress/arguments-bizarre-behaviour-disable-enumerability.js: Added. My choice of spellings of the word "behavio[u]r" is almost as consistent as our implementation of arguments.
+        (foo):
+        * tests/stress/arguments-custom-properties-gc.js: Added. I added this test because at first I was unsure if we GCd arguments correctly.
+        (makeBaseArguments):
+        (makeArray):
+        (cons):
+
+2015-02-23  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r180547 and r180550.
+        https://bugs.webkit.org/show_bug.cgi?id=141957
+
+        Broke 10 Windows tests. (Requested by bfulgham_ on #webkit).
+
+        Reverted changesets:
+
+        "REGRESSION(r179429): Can't type comments in Facebook"
+        https://bugs.webkit.org/show_bug.cgi?id=141859
+        http://trac.webkit.org/changeset/180547
+
+        "Constructor returning null should construct an object instead
+        of null"
+        https://bugs.webkit.org/show_bug.cgi?id=141640
+        http://trac.webkit.org/changeset/180550
+
+2015-02-23  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Constructor returning null should construct an object instead of null
+        https://bugs.webkit.org/show_bug.cgi?id=141640
+
+        Reviewed by Geoffrey Garen.
+
+        When constructor code doesn't return object, constructor should return `this` object instead.
+        Since we used `op_is_object` for this check and `op_is_object` is intended to be used for `typeof`,
+        it allows `null` as an object.
+        This patch fixes it by introducing an new bytecode `op_is_object_or_null` for `typeof` use cases.
+        Instead, constructor uses simplified `is_object`.
+
+        As a result, `op_is_object` becomes fairly simple. So we introduce optimization for `op_is_object`.
+
+        1. LLInt and baseline JIT support `op_is_object` as a fast path.
+        2. DFG abstract interpreter support `op_is_object`. And recognize its speculated type and read-write effects.
+        3. DFG introduces inlined asm for `op_is_object` rather than calling a C++ function.
+        4. FTL lowers DFG's IsObject into LLVM IR.
+
+        And at the same time, this patch fixes isString / isObject predicate used for `op_is_object` and others
+        in LLInt, JIT, DFG and FTL.
+        Before introducing ES6 Symbol, JSCell is only used for object and string in user observable area.
+        So in many places, when the cell is not object, we recognize it as a string, and vice versa.
+        However, now ES6 Symbol is implemented as a JSCell, this assumption is broken.
+        So this patch stop using !isString as isObject.
+        To check whether a cell is an object, instead of seeing that structure ID of a cell is not stringStructure,
+        we examine typeInfo in JSCell.
+
+        * JavaScriptCore.order:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEqualityOp):
+        (JSC::BytecodeGenerator::emitReturn):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+
+        IsObject operation only touches JSCell typeInfoType.
+        And this value would not be changed through structure transition.
+        As a result, IsObject can report that it doesn't read any information.
+
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+        Just like IsString, IsObject is also fixed up.
+
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
+        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
+        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+        (JSC::DFG::SpeculativeJIT::speculateObject):
+        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+        (JSC::DFG::SpeculativeJIT::speculateString):
+        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        (JSC::DFG::SpeculativeJIT::branchIsObject):
+        (JSC::DFG::SpeculativeJIT::branchNotObject):
+        (JSC::DFG::SpeculativeJIT::branchIsString):
+        (JSC::DFG::SpeculativeJIT::branchNotString):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileToString):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
+        (JSC::FTL::LowerDFGToLLVM::compileIsObjectOrNull):
+        (JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
+        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+        (JSC::FTL::LowerDFGToLLVM::isObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotObject):
+        (JSC::FTL::LowerDFGToLLVM::isNotString):
+        (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::emitJumpIfCellObject):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_is_object):
+        (JSC::JIT::emit_op_to_primitive):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_is_object):
+        (JSC::JIT::emit_op_to_primitive):
+        (JSC::JIT::compileOpStrictEq):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/Operations.cpp:
+        (JSC::jsIsObjectTypeOrNull):
+        (JSC::jsIsObjectType): Deleted.
+        * runtime/Operations.h:
+
+2015-02-23  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Disable font loading events until our implementation gets updated to match the latest spec
+        https://bugs.webkit.org/show_bug.cgi?id=141938
+
+        Reviewed by Andreas Kling.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-02-23  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        REGRESSION(r179429): Can't type comments in Facebook
+        https://bugs.webkit.org/show_bug.cgi?id=141859
+
+        Reviewed by Geoffrey Garen.
+
+        When window.Symbol is exposed to user-space pages,
+        Facebook's JavaScript use it (maybe, for immutable-js and React.js's unique key).
+        However, to work with Symbols completely, it also requires
+        1) Object.getOwnPropertySymbols (for mixin including Symbols)
+        2) the latest ES6 Iterator interface that uses Iterator.next and it returns { done: boolean, value: value }.
+        Since they are not landed yet, comments in Facebook don't work.
+
+        This patch introduces RuntimeFlags for JavaScriptCore.
+        Specifying SymbolEnabled flag under test runner and inspector to continue to work with Symbol.
+        And drop JavaScriptExperimentsEnabled flag
+        because it is no longer used and use case of this is duplicated to runtime flags.
+
+        * JavaScriptCore.order:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jsc.cpp:
+        (GlobalObject::javaScriptRuntimeFlags):
+        (GlobalObject::javaScriptExperimentsEnabled): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::finishCreation):
+        (JSC::JSGlobalObject::javaScriptRuntimeFlags):
+        (JSC::JSGlobalObject::javaScriptExperimentsEnabled): Deleted.
+        * runtime/RuntimeFlags.h: Added.
+        (JSC::RuntimeFlags::RuntimeFlags):
+        (JSC::RuntimeFlags::createAllEnabled):
+
+2015-02-23  Benjamin Poulain  <bpoulain@apple.com>
+
+        Set the semantic origin of delayed SetLocal to the Bytecode that originated it
+        https://bugs.webkit.org/show_bug.cgi?id=141727
+
+        Reviewed by Filip Pizlo.
+
+        Previously, delayed SetLocals would have the NodeOrigin of the next
+        bytecode. This was because delayed SetLocal are...delayed... and
+        currentCodeOrigin() is the one where the node is emitted.
+
+        This made debugging a little awkward since the OSR exits on SetLocal
+        were reported for the next bytecode. This patch changes the semantic
+        origin to keep the original bytecode.
+
+        From benchmarks, this looks like it could be a tiny bit faster
+        but it likely just noise.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::setDirect):
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::setArgument):
+        (JSC::DFG::ByteCodeParser::currentNodeOrigin):
+        (JSC::DFG::ByteCodeParser::addToGraph):
+        (JSC::DFG::ByteCodeParser::DelayedSetLocal::DelayedSetLocal):
+        (JSC::DFG::ByteCodeParser::DelayedSetLocal::execute):
+
+2015-02-23  Benjamin Poulain  <bpoulain@apple.com>
+
+        Remove DFGNode::predictHeap()
+        https://bugs.webkit.org/show_bug.cgi?id=141864
+
+        Reviewed by Geoffrey Garen.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::predictHeap): Deleted.
+        Unused code.
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Get rid of JSLexicalEnvironment::argumentsGetter
+        https://bugs.webkit.org/show_bug.cgi?id=141930
+
+        Reviewed by Mark Lam.
+        
+        This function is unused, and the way it's written is bizarre - it's a return statement that
+        dominates a bunch of dead code.
+
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::argumentsGetter): Deleted.
+        * runtime/JSLexicalEnvironment.h:
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove unused activationCount and allTheThingsCount variable declarations.
+
+        Rubber stamped by Mark Lam and Michael Saboff.
+
+        * runtime/JSLexicalEnvironment.h:
+
+2015-02-23  Saam Barati  <saambarati1@gmail.com>
+
+        Adjust the ranges of basic block statements in JSC's control flow profiler to be mutually exclusive
+        https://bugs.webkit.org/show_bug.cgi?id=141095
+
+        Reviewed by Mark Lam.
+
+        Suppose the control flow of a program forms basic block A with successor block
+        B. A's end offset will be the *same* as B's start offset in the current architecture 
+        of the control flow profiler. This makes reasoning about the text offsets of
+        the control flow profiler unsound. To make reasoning about offsets sound, all 
+        basic block ranges should be mutually exclusive.  All calls to emitProfileControlFlow 
+        now pass in the *start* of a basic block as the text offset argument. This simplifies 
+        all calls to emitProfileControlFlow because the previous implementation had a
+        lot of edge cases for getting the desired basic block text boundaries.
+
+        This patch also ensures that the basic block boundary of a block statement 
+        is the exactly the block's open and close brace offsets (inclusive). For example,
+        in if/for/while statements. This also has the consequence that for statements 
+        like "if (cond) foo();", the whitespace preceding "foo()" is not part of 
+        the "foo()" basic block, but instead is part of the "if (cond) " basic block. 
+        This is okay because these text offsets aren't meant to be human readable.
+        Instead, they reflect the text offsets of JSC's AST nodes. The Web Inspector 
+        is the only client of this API and user of these text offsets and it is 
+        not negatively effected by this new behavior.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
+        When computing basic block boundaries in CodeBlock, we ensure that every
+        block's end offset is one less than its successor's start offset to
+        maintain that boundaries' ranges should be mutually exclusive.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        Because the control flow profiler needs to know which functions
+        have executed, we can't lazily create functions. This was a bug 
+        from before that was hidden because the Type Profiler was always 
+        enabled when the control flow profiler was enabled when profiling 
+        was turned on from the Web Inspector. But, JSC allows for Control 
+        Flow profiling to be turned on without Type Profiling, so we need 
+        to ensure the Control Flow profiler has all the data it needs.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConditionalNode::emitBytecode):
+        (JSC::IfElseNode::emitBytecode):
+        (JSC::WhileNode::emitBytecode):
+        (JSC::ForNode::emitBytecode):
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::TryNode::emitBytecode):
+        * jsc.cpp:
+        (functionHasBasicBlockExecuted):
+        We now assert that the substring argument is indeed a substring
+        of the function argument's text because subtle bugs could be
+        introduced otherwise.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::setStartOffset):
+        * parser/Nodes.h:
+        (JSC::Node::setStartOffset):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseBlockStatement):
+        (JSC::Parser<LexerType>::parseStatement):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        For the various function call AST nodes, their m_position member 
+        variable is now the start of the entire function call expression 
+        and not at the start of the open paren of the arguments list.
+
+        * runtime/BasicBlockLocation.cpp:
+        (JSC::BasicBlockLocation::getExecutedRanges):
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::getBasicBlocksForSourceID):
+        Function ranges inserted as gaps should follow the same criteria
+        that the bytecode generator uses to ensure that basic blocks
+        start and end offsets are mutually exclusive.
+
+        * tests/controlFlowProfiler/brace-location.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (testIf):
+        (testForRegular):
+        (testForIn):
+        (testForOf):
+        (testWhile):
+        (testIfNoBraces):
+        (testForRegularNoBraces):
+        (testForInNoBraces):
+        (testForOfNoBraces):
+        (testWhileNoBraces):
+        * tests/controlFlowProfiler/conditional-expression.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (testConditionalBasic):
+        (testConditionalFunctionCall):
+        * tests/controlFlowProfiler/driver/driver.js:
+        (checkBasicBlock):
+
+2015-02-23  Matthew Mirman  <mmirman@apple.com>
+
+        r9 is volatile on ARMv7 for iOS 3 and up. 
+        https://bugs.webkit.org/show_bug.cgi?id=141489
+        rdar://problem/19432916
+
+        Reviewed by Michael Saboff.
+
+        * jit/RegisterSet.cpp: 
+        (JSC::RegisterSet::calleeSaveRegisters): removed r9 from the list of ARMv7 callee save registers.
+        * tests/stress/regress-141489.js: Added.
+        (foo):
+
+2015-02-23  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Add the necessary setupArgumentsWithExecState after bug141915
+        https://bugs.webkit.org/show_bug.cgi?id=141921
+
+        Reviewed by Michael Saboff.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Scopes should always be created with a previously-created symbol table rather than creating one on the fly
+        https://bugs.webkit.org/show_bug.cgi?id=141915
+
+        Reviewed by Mark Lam.
+        
+        The main effect of this change is that pushing name scopes no longer requires creating symbol
+        tables on the fly.
+        
+        This also makes it so that JSEnvironmentRecords must always have an a priori symbol table.
+        
+        JSSegmentedVariableObject still does a hack where it creates a blank symbol table on-demand.
+        This is needed because that's what JSGlobalObject and all of its many subclasses want. That's
+        harmless; I mainly needed a prior symbol tables for JSEnvironmentRecords anyway.
+
+        * bytecode/BytecodeList.json:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOperations.cpp:
+        (JSC::pushNameScope):
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        * runtime/JSCatchScope.h:
+        (JSC::JSCatchScope::JSCatchScope):
+        (JSC::JSCatchScope::create):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
+        * runtime/JSFunctionNameScope.h:
+        (JSC::JSFunctionNameScope::JSFunctionNameScope):
+        (JSC::JSFunctionNameScope::create):
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::create):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::finishCreation):
+        (JSC::JSNameScope::JSNameScope):
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::finishCreation):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::JSSymbolTableObject):
+        (JSC::JSSymbolTableObject::finishCreation): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::createNameScopeTable):
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
+        Add a comment to clarify that the test was taken from the bug report, in response to
+        feedback from Michael Saboff and Benjamin Poulain.
+        
+        * tests/stress/regress-141883.js:
+
+2015-02-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Function name scope is only created on the function instance that triggered parsing rather than on every function instance that needs it
+        https://bugs.webkit.org/show_bug.cgi?id=141881
+
+        Reviewed by Michael Saboff.
+        
+        Previously we only created the function name scope in a way that made it visible to the
+        function that triggered parsing/linking of the executable/codeBlock, and to the linker for
+        that code block. This was sort of the bare minimum for the feature to appear to work right to
+        synthetic tests.
+
+        There are two valid "times" to create the function name scope. Either it's created for each
+        JSFunction instance that needs a name scope, or it's created for each execution of such a
+        JSFunction. This change chooses the latter, because it happens to be the easiest to implement
+        with what we have right now. I opened a bug for optimizing this if we ever need to:
+        https://bugs.webkit.org/show_bug.cgi?id=141887.
+        
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::isNumericCompareFunction):
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        (JSC::ScriptExecutable::prepareForExecutionImpl):
+        (JSC::FunctionExecutable::FunctionExecutable):
+        * runtime/Executable.h:
+        (JSC::ScriptExecutable::prepareForExecution):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::addNameScopeIfNeeded): Deleted.
+        * runtime/JSFunction.h:
+        * tests/stress/function-name-scope.js: Added.
+        (check.verify):
+        (check):
+
+2015-02-22  Filip Pizlo  <fpizlo@apple.com>
+
+        Crash in DFGFrozenValue
+        https://bugs.webkit.org/show_bug.cgi?id=141883
+
+        Reviewed by Benjamin Poulain.
+        
+        If a value might be a cell, then we have to have Graph freeze it rather than trying to
+        create the FrozenValue directly. Creating it directly is just an optimization for when you
+        know for sure that it cannot be a cell.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * tests/stress/regress-141883.js: Added. Hacked the original test to be faster while still crashing before this fix.
+
+2015-02-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Generate Previews more often for RemoteObject interaction
+        https://bugs.webkit.org/show_bug.cgi?id=141875
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Runtime.json:
+        Add generatePreview to getProperties.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        * inspector/InjectedScript.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        Plumb the generatePreview boolean through to the injected script.
+
+        * inspector/InjectedScriptSource.js:
+        Add generatePreview for getProperties.
+        Fix callFunctionOn to generatePreviews if asked.
+
+2015-02-20  Mark Lam  <mark.lam@apple.com>
+
+        Refactor JSWrapperMap.mm to defer creation of the ObjC JSValue until the latest possible moment.
+        <https://webkit.org/b/141856>
+
+        Reviewed by Geoffrey Garen.
+
+        1. Make JSObjCClassInfo's -constructor and -wrapperForObject return a
+           JSC::JSObject* just like -prototype.
+        2. Defer the creation of the ObjC JSValue from JSC::JSObject* until
+           the latest moment when it is needed.  This allows us to not have to
+           keep converting back to a JSC::JSObject* in intermediate code.
+
+        * API/JSWrapperMap.mm:
+        (makeWrapper):
+        (objectWithCustomBrand):
+        (constructorWithCustomBrand):
+        (allocateConstructorForCustomClass):
+        (-[JSObjCClassInfo allocateConstructorAndPrototype]):
+        (-[JSObjCClassInfo wrapperForObject:]):
+        (-[JSObjCClassInfo constructor]):
+        (-[JSWrapperMap jsWrapperForObject:]):
+
+2015-02-20  Filip Pizlo  <fpizlo@apple.com>
+
+        Build fix for gcc.
+
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::create):
+
+2015-02-20  Filip Pizlo  <fpizlo@apple.com>
+
+        Get rid of JSNameScope::m_type
+        https://bugs.webkit.org/show_bug.cgi?id=141851
+
+        Reviewed by Geoffrey Garen.
+        
+        This is a big step towards getting rid of JSEnvironmentRecord::m_registers. To do it we need
+        to ensure that subclasses of JSEnvironmentRecord never have additional C++ fields, so that
+        JSEnvironmentRecord can always place "registers" right after the end of itself.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::isCatchScope):
+        (JSC::DebuggerScope::isFunctionNameScope):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/JSCatchScope.cpp: Added.
+        * runtime/JSCatchScope.h: Added.
+        (JSC::JSCatchScope::JSCatchScope):
+        (JSC::JSCatchScope::create):
+        (JSC::JSCatchScope::createStructure):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::addNameScopeIfNeeded):
+        * runtime/JSFunctionNameScope.cpp: Added.
+        * runtime/JSFunctionNameScope.h: Added.
+        (JSC::JSFunctionNameScope::JSFunctionNameScope):
+        (JSC::JSFunctionNameScope::create):
+        (JSC::JSFunctionNameScope::createStructure):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::catchScopeStructure):
+        (JSC::JSGlobalObject::functionNameScopeStructure):
+        (JSC::JSGlobalObject::nameScopeStructure): Deleted.
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::create):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::JSNameScope):
+        (JSC::JSNameScope::createStructure): Deleted.
+        (JSC::JSNameScope::isFunctionNameScope): Deleted.
+        (JSC::JSNameScope::isCatchScope): Deleted.
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::isCatchScopeObject):
+        (JSC::JSObject::isFunctionNameScopeObject):
+        * runtime/JSObject.h:
+
+2015-02-20  Mark Lam  <mark.lam@apple.com>
+
+        [JSObjCClassInfo reallocateConstructorAndOrPrototype] should also reallocate super class prototype chain.
+        <https://webkit.org/b/141809>
+
+        Reviewed by Geoffrey Garen.
+
+        A ObjC class that implement the JSExport protocol will have a JS prototype
+        chain and constructor automatically synthesized for its JS wrapper object.
+        However, if there are no more instances of that ObjC class reachable by a
+        JS GC root scan, then its synthesized prototype chain and constructors may
+        be released by the GC.  If a new instance of that ObjC class is subsequently
+        instantiated, then [JSObjCClassInfo reallocateConstructorAndOrPrototype]
+        should re-construct the prototype chain and constructor (if they were
+        previously released).  However, the current implementation only
+        re-constructs the immediate prototype, but not every other prototype
+        object upstream in the prototype chain.
+
+        To fix this, we do the following:
+        1. We no longer allocate the JSObjCClassInfo's prototype and constructor
+           eagerly.  Hence, -initWithContext:forClass: will no longer call
+           -allocateConstructorAndPrototypeWithSuperClassInfo:.
+        2. Instead, we'll always access the prototype and constructor thru
+           accessor methods.  The accessor methods will call
+           -allocateConstructorAndPrototype: if needed.
+        3. -allocateConstructorAndPrototype: will fetch the needed superClassInfo
+           from the JSWrapperMap itself.  This makes it so that we no longer
+           need to pass the superClassInfo all over.
+        4. -allocateConstructorAndPrototype: will get the super class prototype
+           by invoking -prototype: on the superClassInfo, thereby allowing the
+           super class to allocate its prototype and constructor if needed and
+           fixing the issue in this bug.
+
+        5. Also removed the GC warning comments, and ensured that needed JS
+           objects are kept alive by having a local var pointing to it from the
+           stack (which makes a GC root).
+
+        * API/JSWrapperMap.mm:
+        (-[JSObjCClassInfo initWithContext:forClass:]):
+        (-[JSObjCClassInfo allocateConstructorAndPrototype]):
+        (-[JSObjCClassInfo wrapperForObject:]):
+        (-[JSObjCClassInfo constructor]):
+        (-[JSObjCClassInfo prototype]):
+        (-[JSWrapperMap classInfoForClass:]):
+        (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]): Deleted.
+        (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): Deleted.
+        (-[JSObjCClassInfo reallocateConstructorAndOrPrototype]): Deleted.
+        * API/tests/Regress141809.h: Added.
+        * API/tests/Regress141809.mm: Added.
+        (-[TestClassB name]):
+        (-[TestClassC name]):
+        (runRegress141809):
+        * API/tests/testapi.mm:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-02-20  Alexey Proskuryakov  <ap@apple.com>
+
+        Remove svn:keywords property.
+
+        As far as I can tell, the property had no effect on any of these files, but also,
+        when it has effect it's likely harmful.
+
+        * builtins/ArrayConstructor.js: Removed property svn:keywords.
+
+2015-02-20  Michael Saboff  <msaboff@apple.com>
+
+        DFG JIT needs to check for stack overflow at the start of Program and Eval execution
+        https://bugs.webkit.org/show_bug.cgi?id=141676
+
+        Reviewed by Filip Pizlo.
+
+        Added stack check to the beginning of the code the DFG copmiler emits for Program and Eval nodes.
+        To aid in testing the code, I replaced the EvalCodeCache::maxCacheableSourceLength const
+        a options in runtime/Options.h.  The test script, run-jsc-stress-tests, sets that option
+        to a huge value when running with the "Eager" options.  This allows the updated test to 
+        reliably exercise the code in questions.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compile):
+        Added stack check.
+
+        * bytecode/EvalCodeCache.h:
+        (JSC::EvalCodeCache::tryGet):
+        (JSC::EvalCodeCache::getSlow):
+        * runtime/Options.h:
+        Replaced EvalCodeCache::imaxCacheableSourceLength with Options::maximumEvalCacheableSourceLength
+        so that it can be configured when running the related test.
+
+2015-02-20  Eric Carlson  <eric.carlson@apple.com>
+
+        [iOS] cleanup AirPlay code
+        https://bugs.webkit.org/show_bug.cgi?id=141811
+
+        Reviewed by Jer Noble.
+
+        * Configurations/FeatureDefines.xcconfig: IOS_AIRPLAY -> WIRELESS_PLAYBACK_TARGET.
+
+2015-02-19  Dean Jackson  <dino@apple.com>
+
+        ES6: Implement Array.from()
+        https://bugs.webkit.org/show_bug.cgi?id=141054
+        <rdar://problem/19654521>
+
+        Reviewed by Filip Pizlo.
+
+        Implement the Array.from() ES6 method
+        as defined in Section 22.1.2.1 of the specification.
+
+        Given that we can't rely on the built-in
+        global functions or objects to be untainted,
+        I had to expose a few of them directly to
+        the function via private names. In particular:
+        - Math.floor -> @floor
+        - Math.abs -> @abs
+        - Number -> @Number
+        - Array -> @Array
+        - isFinite -> @isFinite
+
+        * builtins/ArrayConstructor.js: Added.
+        (from): Implementation of Array.from in JavaScript.
+        * runtime/ArrayConstructor.cpp: Add "from" to the lookup
+        table for the constructor object.
+        * runtime/CommonIdentifiers.h: Add the private versions
+        of the identifiers listed above.
+        * runtime/JSGlobalObject.cpp: Add the implementations of
+        those identifiers to the global object (using their
+        private names).
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalPrivateFuncAbs): Implementation of the abs function.
+        (JSC::globalPrivateFuncFloor): Implementation of the floor function.
+        * runtime/JSGlobalObjectFunctions.h:
+
+2015-02-19  Benjamin Poulain  <bpoulain@apple.com>
+
+        Refine the FTL part of ArithPow
+        https://bugs.webkit.org/show_bug.cgi?id=141792
+
+        Reviewed by Filip Pizlo.
+
+        This patch refines the FTL lowering of ArithPow. This was left out
+        of the original patch to keep it simpler.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileArithPow):
+        Two improvements here:
+        1) Do not generate the NaN check unless we know the exponent might be a NaN.
+        2) Use one BasicBlock per check with the appropriate weight. Now that we have
+           one branch per test, move the Infinity check before the check for 1 since
+           it is the less common case.
+
+        * tests/stress/math-pow-becomes-custom-function.js: Added.
+        Test for changing the Math.pow() function after it has been optimized.
+
+        * tests/stress/math-pow-nan-behaviors.js:
+        The previous tests were only going as far as the DFGAbstractInterpreter
+        were the operations were replaced by the equivalent constant.
+
+        I duplicated the test functions to also test the dynamic behavior of DFG
+        and FTL.
+
+        * tests/stress/math-pow-with-constants.js:
+        Add cases covering exponent constants. LLVM removes many value
+        checks for those.
+
+        * tests/stress/math-pow-with-never-NaN-exponent.js: Added.
+        Test for the new optimization removing the NaN check.
+
+2015-02-19  Csaba Osztrogonác  <ossy@webkit.org>
+
+        REGRESSION(r180279): It broke 20 tests on ARM Linux
+        https://bugs.webkit.org/show_bug.cgi?id=141771
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation): Align 64-bit values to respect ARM EABI.
+
+2015-02-18  Benjamin Poulain  <bpoulain@apple.com>
+
+        Remove BytecodeGenerator's numberMap, it is dead code
+        https://bugs.webkit.org/show_bug.cgi?id=141779
+
+        Reviewed by Filip Pizlo.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitLoad): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        The JSValueMap seems better in every way.
+
+        The emitLoad() taking a double was the only way to use numberMap
+        and that code has no caller.
+
+2015-02-18  Michael Saboff  <msaboff@apple.com>
+
+        Rollout r180247 & r180249 from trunk
+        https://bugs.webkit.org/show_bug.cgi?id=141773
+
+        Reviewed by Filip Pizlo.
+
+        Theses changes makes sense to fix the crash reported in https://bugs.webkit.org/show_bug.cgi?id=141730
+        only for branches.  The change to fail the FTL compile but continue running is not comprehensive
+        enough for general use on trunk.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
+        (JSC::FTL::LowerDFGToLLVM::compilePhi):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+        (JSC::FTL::LowerDFGToLLVM::compilePutLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+        (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMod):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
+        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileGetById):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArray):
+        (JSC::FTL::LowerDFGToLLVM::compileToString):
+        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::compare):
+        (JSC::FTL::LowerDFGToLLVM::boolify):
+        (JSC::FTL::LowerDFGToLLVM::opposite):
+        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::isArrayType):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::setInt52):
+        (JSC::FTL::lowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::loweringFailed): Deleted.
+        * ftl/FTLLowerDFGToLLVM.h:
+
+2015-02-18  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should really support varargs
+        https://bugs.webkit.org/show_bug.cgi?id=141332
+
+        Reviewed by Oliver Hunt.
+        
+        This adds comprehensive vararg call support to the DFG and FTL compilers. Previously, if a
+        function had a varargs call, then it could only be compiled if that varargs call was just
+        forwarding arguments and we were inlining the function rather than compiling it directly. Also,
+        only varargs calls were dealt with; varargs constructs were not.
+        
+        This lifts all of those restrictions. Every varargs call or construct can now be compiled by both
+        the DFG and the FTL. Those calls can also be inlined, too - provided that profiling gives us a
+        sensible bound on arguments list length. When we inline a varargs call, the act of loading the
+        varargs is now made explicit in IR. I believe that we have enough IR machinery in place that we
+        would be able to do the arguments forwarding optimization as an IR transformation. This patch
+        doesn't implement that yet, and keeps the old bytecode-based varargs argument forwarding
+        optimization for now.
+        
+        There are three major IR features introduced in this patch:
+        
+        CallVarargs/ConstructVarargs: these are like Call/Construct except that they take an arguments
+        array rather than a list of arguments. Currently, they splat this arguments array onto the stack
+        using the same basic technique as the baseline JIT has always done. Except, these nodes indicate
+        that we are not interested in doing the non-escaping "arguments" optimization.
+        
+        CallForwardVarargs: this is a form of CallVarargs that just does the non-escaping "arguments"
+        optimization, aka forwarding arguments. It's somewhat lazy that this doesn't include
+        ConstructForwardVarargs, but the reason is that once we eliminate the lazy tear-off for
+        arguments, this whole thing will have to be tweaked - and for now forwarding on construct is just
+        not important in benchmarks. ConstructVarargs will still do forwarding, just not inlined.
+        
+        LoadVarargs: loads all elements out of an array onto the stack in a manner suitable for a varargs
+        call. This is used only when a varargs call (or construct) was inlined. The bytecode parser will
+        make room on the stack for the arguments, and will use LoadVarars to put those arguments into
+        place.
+        
+        In the future, we can consider adding strength reductions like:
+        
+        - If CallVarargs/ConstructVarargs see an array of known size with known elements, turn them into
+          Call/Construct.
+        
+        - If CallVarargs/ConstructVarargs are passed an unmodified, unescaped Arguments object, then
+          turn them into CallForwardVarargs/ConstructForwardVarargs.
+        
+        - If LoadVarargs sees an array of known size, then turn it into a sequence of GetByVals and
+          PutLocals.
+        
+        - If LoadVarargs sees an unmodified, unescaped Arguments object, then turn it into something like
+          LoadForwardVarargs.
+        
+        - If CallVarargs/ConstructVarargs/LoadVarargs see the result of a splice (or other Array
+          prototype function), then do the splice and varargs loading in one go (maybe via a new node
+          type).
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::rshiftPtr):
+        (JSC::MacroAssembler::urshiftPtr):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::urshift64):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::urshift64):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::shrq_i8r):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::CallLinkInfo):
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::setProvenConstantCallee):
+        (JSC::CallLinkStatus::dump):
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::maxNumArguments):
+        (JSC::CallLinkStatus::setIsProved): Deleted.
+        * bytecode/CodeOrigin.cpp:
+        (WTF::printInternal):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::varargsKindFor):
+        (JSC::InlineCallFrame::specializationKindFor):
+        (JSC::InlineCallFrame::isVarargs):
+        (JSC::InlineCallFrame::isNormalCall): Deleted.
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        * bytecode/ExitKind.h:
+        * bytecode/ValueRecovery.cpp:
+        (JSC::ValueRecovery::dumpInContext):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::flush):
+        (JSC::DFG::ByteCodeParser::addCall):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::handleVarargsCall):
+        (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::handleMinMax):
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        (JSC::DFG::ByteCodeParser::handleTypedArrayConstructor):
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::removeLastNodeFromGraph): Deleted.
+        (JSC::DFG::ByteCodeParser::undoFunctionChecks): Deleted.
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGCapabilities.h:
+        (JSC::DFG::functionCapabilityLevel):
+        (JSC::DFG::mightCompileFunctionFor):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.cpp:
+        (WTF::printInternal):
+        * dfg/DFGCommon.h:
+        (JSC::DFG::canInline):
+        (JSC::DFG::leastUpperBound):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::isLiveInBytecode):
+        (JSC::DFG::Graph::valueProfileFor):
+        (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::valueProfileFor): Deleted.
+        (JSC::DFG::Graph::methodOfGettingAValueProfileFor): Deleted.
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCallVarargsData):
+        (JSC::DFG::Node::callVarargsData):
+        (JSC::DFG::Node::hasLoadVarargsData):
+        (JSC::DFG::Node::loadVarargsData):
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::dumpAndVerifyGraph):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSSAConversionPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::isFlushed):
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        (JSC::DFG::StackLayoutPhase::assign):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::functionType):
+        (JSC::FTL::buildCall):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCall):
+        (JSC::FTL::sizeOfCallVarargs):
+        (JSC::FTL::sizeOfCallForwardVarargs):
+        (JSC::FTL::sizeOfConstructVarargs):
+        (JSC::FTL::sizeOfIn):
+        (JSC::FTL::sizeOfICFor):
+        (JSC::FTL::sizeOfCheckIn): Deleted.
+        * ftl/FTLInlineCacheSize.h:
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::JSCall):
+        * ftl/FTLJSCallBase.cpp:
+        * ftl/FTLJSCallBase.h:
+        * ftl/FTLJSCallVarargs.cpp: Added.
+        (JSC::FTL::JSCallVarargs::JSCallVarargs):
+        (JSC::FTL::JSCallVarargs::numSpillSlotsNeeded):
+        (JSC::FTL::JSCallVarargs::emit):
+        (JSC::FTL::JSCallVarargs::link):
+        * ftl/FTLJSCallVarargs.h: Added.
+        (JSC::FTL::JSCallVarargs::node):
+        (JSC::FTL::JSCallVarargs::stackmapID):
+        (JSC::FTL::JSCallVarargs::operator<):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileLoadVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileIn):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        (JSC::FTL::LowerDFGToLLVM::vmCall):
+        (JSC::FTL::LowerDFGToLLVM::vmCallNoExceptions):
+        (JSC::FTL::LowerDFGToLLVM::callCheck):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::call):
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::State):
+        * ftl/FTLState.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeOfVarargs):
+        (JSC::sizeFrameForVarargs):
+        * interpreter/Interpreter.h:
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::readInlinedFrame):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::emitExceptionCheck):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::addressFor):
+        (JSC::AssemblyHelpers::calleeFrameSlot):
+        (JSC::AssemblyHelpers::calleeArgumentSlot):
+        (JSC::AssemblyHelpers::calleeFrameTagSlot):
+        (JSC::AssemblyHelpers::calleeFramePayloadSlot):
+        (JSC::AssemblyHelpers::calleeArgumentTagSlot):
+        (JSC::AssemblyHelpers::calleeArgumentPayloadSlot):
+        (JSC::AssemblyHelpers::calleeFrameCallerFrame):
+        (JSC::AssemblyHelpers::selectScratchGPR):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/GPRInfo.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        (JSC::JIT::compileOpCall):
+        * jit/JITOperations.h:
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h:
+        * runtime/Arguments.h:
+        (JSC::Arguments::create):
+        (JSC::Arguments::registerArraySizeInBytes):
+        (JSC::Arguments::finishCreation):
+        * runtime/Options.h:
+        * tests/stress/construct-varargs-inline-smaller-Foo.js: Added.
+        (Foo):
+        (bar):
+        (checkEqual):
+        (test):
+        * tests/stress/construct-varargs-inline.js: Added.
+        (Foo):
+        (bar):
+        (checkEqual):
+        (test):
+        * tests/stress/construct-varargs-no-inline.js: Added.
+        (Foo):
+        (bar):
+        (checkEqual):
+        (test):
+        * tests/stress/get-argument-by-val-in-inlined-varargs-call-out-of-bounds.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/get-argument-by-val-safe-in-inlined-varargs-call-out-of-bounds.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/get-my-argument-by-val-creates-arguments.js: Added.
+        (blah):
+        (foo):
+        (bar):
+        (checkEqual):
+        (test):
+        * tests/stress/load-varargs-then-inlined-call-exit-in-foo.js: Added.
+        (foo):
+        (bar):
+        (checkEqual):
+        * tests/stress/load-varargs-then-inlined-call-inlined.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (checkEqual):
+        (test):
+        * tests/stress/load-varargs-then-inlined-call.js: Added.
+        (foo):
+        (bar):
+        (checkEqual):
+        (test):
+
+2015-02-17  Michael Saboff  <msaboff@apple.com>
+
+        Unreviewed, Restoring the C LOOP insta-crash fix in r180184.
+
+        Fixed a typo that only affected the C Loop in the prologue() macro in LowLevelInterpreter.asm.
+        After the stackHeightOKGetCodeBlock label, codeBlockSetter(t1) should be codeBlockGetter(t1).
+
+        * llint/LowLevelInterpreter.asm: Fixed a typo.
+
+2015-02-18  Csaba Osztrogonác  <ossy@webkit.org>
+
+        URTBF after r180258 to fix Windows build.
+
+        * runtime/MathCommon.cpp:
+        (JSC::mathPowInternal):
+
+2015-02-18  Joseph Pecoraro  <pecoraro@apple.com>
+
+        REGRESSION(r180235): It broke the !ENABLE(PROMISES) build
+        https://bugs.webkit.org/show_bug.cgi?id=141746
+
+        Unreviewed build fix.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        Wrap JSPromise related code in ENABLE(PROMISES) guard.
+
+2015-02-18  Benjamin Poulain  <benjamin@webkit.org>
+
+        Fix the C-Loop LLInt build
+        https://bugs.webkit.org/show_bug.cgi?id=141618
+
+        Reviewed by Filip Pizlo.
+
+        I broke C-Loop when moving the common code of pow()
+        to JITOperations because that file is #ifdefed out
+        when the JITs are disabled.
+
+        It would be weird to move it back to MathObject since
+        the function needs to know about the calling conventions.
+
+        To avoid making a mess, I just gave the function its own file
+        that is used by both the runtime and the JIT.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * runtime/MathCommon.cpp: Added.
+        (JSC::fdlibmScalbn):
+        (JSC::fdlibmPow):
+        (JSC::isDenormal):
+        (JSC::isEdgeCase):
+        (JSC::mathPowInternal):
+        (JSC::operationMathPow):
+        * runtime/MathCommon.h: Added.
+        * runtime/MathObject.cpp:
+
+2015-02-17  Benjamin Poulain  <bpoulain@apple.com>
+
+        Clean up OSRExit's considerAddingAsFrequentExitSite()
+        https://bugs.webkit.org/show_bug.cgi?id=141690
+
+        Reviewed by Anders Carlsson.
+
+        Looks like some code was removed from CodeBlock::tallyFrequentExitSites()
+        and the OSRExit were left untouched.
+
+        This patch cleans up the two loops and remove the boolean return
+        on considerAddingAsFrequentExitSite().
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::tallyFrequentExitSites):
+        * dfg/DFGOSRExit.h:
+        (JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
+        * dfg/DFGOSRExitBase.cpp:
+        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
+        * dfg/DFGOSRExitBase.h:
+        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
+        * ftl/FTLOSRExit.h:
+        (JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
+
+2015-02-17  Alexey Proskuryakov  <ap@apple.com>
+
+        Debug build fix after r180247.
+
+        * ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::loweringFailed):
+
+2015-02-17  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r180184.
+        https://bugs.webkit.org/show_bug.cgi?id=141733
+
+        Caused infinite recursion on js/function-apply-aliased.html
+        (Requested by ap_ on #webkit).
+
+        Reverted changeset:
+
+        "REGRESSION(r180060): C Loop crashes"
+        https://bugs.webkit.org/show_bug.cgi?id=141671
+        http://trac.webkit.org/changeset/180184
+
+2015-02-17  Michael Saboff  <msaboff@apple.com>
+
+        CrashTracer: DFG_CRASH beneath JSC::FTL::LowerDFGToLLVM::compileNode
+        https://bugs.webkit.org/show_bug.cgi?id=141730
+
+        Reviewed by Geoffrey Garen.
+
+        Added a new failure handler, loweringFailed(), to LowerDFGToLLVM that reports failures
+        while processing DFG lowering.  For debug builds, the failures are logged identical
+        to the way the DFG_CRASH() reports them.  For release builds, the failures are reported
+        and that FTL compilation is terminated, but the process is allowed to continue.
+        Wrapped calls to loweringFailed() in a macro LOWERING_FAILED so the function and
+        line number are reported at the point of the inconsistancy.
+
+        Converted instances of DFG_CRASH to LOWERING_FAILED.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl): Added lowerDFGToLLVM() failure check that
+        will fail the FTL compile.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        Added new member variable, m_loweringSucceeded, to stop compilation on the first
+        reported failure.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        * ftl/FTLLowerDFGToLLVM.h:
+        Added check for compilation failures and now report those failures via a boolean
+        return value.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
+        (JSC::FTL::LowerDFGToLLVM::compilePhi):
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
+        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
+        (JSC::FTL::LowerDFGToLLVM::compilePutLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+        (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMod):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
+        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayifyToStructure):
+        (JSC::FTL::LowerDFGToLLVM::compileGetById):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArray):
+        (JSC::FTL::LowerDFGToLLVM::compileToString):
+        (JSC::FTL::LowerDFGToLLVM::compileMakeRope):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::compare):
+        (JSC::FTL::LowerDFGToLLVM::boolify):
+        (JSC::FTL::LowerDFGToLLVM::opposite):
+        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::isArrayType):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::setInt52):
+        Changed DFG_CRASH() to LOWERING_FAILED().  Updated related control flow as appropriate.
+
+        (JSC::FTL::LowerDFGToLLVM::loweringFailed): New error reporting member function.
+
+2015-02-17  Filip Pizlo  <fpizlo@apple.com>
+
+        StackLayoutPhase should use CodeBlock::usesArguments rather than FunctionExecutable::usesArguments
+        https://bugs.webkit.org/show_bug.cgi?id=141721
+        rdar://problem/17198633
+
+        Reviewed by Michael Saboff.
+        
+        I've seen cases where the two are out of sync.  We know we can trust the CodeBlock::usesArguments because
+        we use it everywhere else.
+        
+        No test because I could never reproduce the crash.
+
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::usesArguments):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+
+2015-02-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Improved Console Support for Bound Functions
+        https://bugs.webkit.org/show_bug.cgi?id=141635
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        Expose internal properties of a JSBoundFunction.
+
+2015-02-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Improved Console Support for Promise Objects
+        https://bugs.webkit.org/show_bug.cgi?id=141634
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getInternalProperties):
+        * inspector/InjectedScriptSource.js:
+        Include internal properties in previews. Share code
+        with normal internal property handling.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::constructInternalProperty):
+        (Inspector::JSInjectedScriptHost::getInternalProperties):
+        Provide internal state of Promises.
+
+        * inspector/protocol/Runtime.json:
+        Provide an optional field to distinguish if a PropertyPreview
+        is for an Internal property or not.
+
+2015-02-17  Filip Pizlo  <fpizlo@apple.com>
+
+        Throwing from an FTL call IC slow path may result in tag registers being clobbered on 64-bit CPUs
+        https://bugs.webkit.org/show_bug.cgi?id=141717
+        rdar://problem/19863382
+
+        Reviewed by Geoffrey Garen.
+        
+        The best solution is to ensure that the engine catching an exception restores tag registers.
+        
+        Each of these new test cases reliably crashed prior to this patch and they don't crash at all now.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_catch):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * tests/stress/throw-from-ftl-call-ic-slow-path-cells.js: Added.
+        * tests/stress/throw-from-ftl-call-ic-slow-path-undefined.js: Added.
+        * tests/stress/throw-from-ftl-call-ic-slow-path.js: Added.
+
+2015-02-17  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Add the necessary setupArgumentsWithExecState after bug141332
+        https://bugs.webkit.org/show_bug.cgi?id=141714
+
+        Reviewed by Michael Saboff.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2015-02-15  Sam Weinig  <sam@webkit.org>
+
+        Add experimental <attachment> element support
+        https://bugs.webkit.org/show_bug.cgi?id=141626
+
+        Reviewed by Tim Horton.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-02-16  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r180060): C Loop crashes
+        https://bugs.webkit.org/show_bug.cgi?id=141671
+
+        Reviewed by Geoffrey Garen.
+
+        Fixed a typo that only affected the C Loop in the prologue() macro in LowLevelInterpreter.asm.
+        After the stackHeightOKGetCodeBlock label, codeBlockSetter(t1) should be codeBlockGetter(t1).
+        Fixed the processing of an out of stack exception in llint_stack_check to not get the caller's
+        frame.  This isn't needed, since this helper is only called to check the stack on entry.  Any
+        exception will be handled by a call ancestor.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_stack_check): Changed to use the current frame for processing an exception.
+        * llint/LowLevelInterpreter.asm: Fixed a typo.
+
+2015-02-16  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Scope details sidebar should label objects with constructor names
+        https://bugs.webkit.org/show_bug.cgi?id=139449
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::internalConstructorName):
+        * runtime/Structure.cpp:
+        (JSC::Structure::toStructureShape):
+        Share calculatedClassName.
+
+        * runtime/JSObject.h:        
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::calculatedClassName):
+        Elaborate on a way to get an Object's class name.
+
+2015-02-16  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG SSA should use GetLocal for arguments, and the GetArgument node type should be removed
+        https://bugs.webkit.org/show_bug.cgi?id=141623
+
+        Reviewed by Oliver Hunt.
+        
+        During development of https://bugs.webkit.org/show_bug.cgi?id=141332, I realized that I
+        needed to use GetArgument for loading something that has magically already appeared on the
+        stack, so currently trunk sort of allows this. But then I realized three things:
+        
+        - A GetArgument with a non-JSValue flush format means speculating that the value on the
+          stack obeys that format, rather than just assuming that that it already has that format.
+          In bug 141332, I want it to assume rather than speculate. That also happens to be more
+          intuitive; I don't think I was wrong to expect that.
+        
+        - The node I really want is GetLocal. I'm just getting the value of the local and I don't
+          want to do anything else.
+        
+        - Maybe it would be easier if we just used GetLocal for all of the cases where we currently
+          use GetArgument.
+        
+        This changes the FTL to do argument speculations in the prologue just like the DFG does.
+        This brings some consistency to our system, and allows us to get rid of the GetArgument
+        node. The speculations that the FTL must do are now made explicit in the m_argumentFormats
+        vector in DFG::Graph. This has natural DCE behavior: even if all uses of the argument are
+        dead we will still speculate. We already have safeguards to ensure we only speculate if
+        there are uses that benefit from speculation (which is a much more conservative criterion
+        than DCE).
+        
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::typeFilterFor):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::valueProfileFor):
+        (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::hasVariableAccessData):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGPutLocalSinkingPhase.cpp:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArgument): Deleted.
+        * tests/stress/dead-speculating-argument-use.js: Added.
+        (foo):
+        (o.valueOf):
+
+2015-02-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Rare case profiling should actually work
+        https://bugs.webkit.org/show_bug.cgi?id=141632
+
+        Reviewed by Michael Saboff.
+        
+        This simple adjustment appears to be a 2% speed-up on Octane. Over time, the slow case
+        heuristic has essentially stopped working because the typical execution count threshold for a
+        bytecode instruction is around 66 while the slow case threshold is 100: virtually
+        guaranteeing that the DFG will never think that a bytecode instruction has taken the slow
+        case even if it took it every single time. So, this changes the slow case threshold to 20.
+        
+        I checked if we could lower this down further, like to 10. That is worse than 20, and about
+        as bad as 100.
+
+        * runtime/Options.h:
+
+2015-02-15  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: remove unused XHR replay code
+        https://bugs.webkit.org/show_bug.cgi?id=141622
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Network.json: remove XHR replay methods.
+
+2015-02-15  David Kilzer  <ddkilzer@apple.com>
+
+        REGRESSION (r180082): WebCore Debug builds fail on Mavericks due to weak export symbols
+        <http://webkit.org/b/141607>
+
+        More work towards fixing the Mavericks Debug build.
+
+        * inspector/ScriptDebugServer.h:
+        (Inspector::ScriptDebugServer::Task):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        (Inspector::InspectorDebuggerAgent::Listener):
+        - Remove subclass exports. They did not help.
+
+        * runtime/JSCJSValue.h:
+        (JSC::JSValue::toFloat): Do not mark inline method for export.
+
+2015-02-09  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: remove some unnecessary Inspector prefixes from class names in Inspector namespace
+        https://bugs.webkit.org/show_bug.cgi?id=141372
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::addToFrontend):
+        (Inspector::ConsoleMessage::updateRepeatCountInConsole):
+        * inspector/ConsoleMessage.h:
+        * inspector/InspectorAgentBase.h:
+        * inspector/InspectorAgentRegistry.cpp:
+        (Inspector::AgentRegistry::AgentRegistry):
+        (Inspector::AgentRegistry::append):
+        (Inspector::AgentRegistry::appendExtraAgent):
+        (Inspector::AgentRegistry::didCreateFrontendAndBackend):
+        (Inspector::AgentRegistry::willDestroyFrontendAndBackend):
+        (Inspector::AgentRegistry::discardAgents):
+        (Inspector::InspectorAgentRegistry::InspectorAgentRegistry): Deleted.
+        (Inspector::InspectorAgentRegistry::append): Deleted.
+        (Inspector::InspectorAgentRegistry::appendExtraAgent): Deleted.
+        (Inspector::InspectorAgentRegistry::didCreateFrontendAndBackend): Deleted.
+        (Inspector::InspectorAgentRegistry::willDestroyFrontendAndBackend): Deleted.
+        (Inspector::InspectorAgentRegistry::discardAgents): Deleted.
+        * inspector/InspectorAgentRegistry.h:
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::BackendDispatcher::CallbackBase::CallbackBase):
+        (Inspector::BackendDispatcher::CallbackBase::isActive):
+        (Inspector::BackendDispatcher::CallbackBase::sendFailure):
+        (Inspector::BackendDispatcher::CallbackBase::sendIfActive):
+        (Inspector::BackendDispatcher::create):
+        (Inspector::BackendDispatcher::registerDispatcherForDomain):
+        (Inspector::BackendDispatcher::dispatch):
+        (Inspector::BackendDispatcher::sendResponse):
+        (Inspector::BackendDispatcher::reportProtocolError):
+        (Inspector::BackendDispatcher::getInteger):
+        (Inspector::BackendDispatcher::getDouble):
+        (Inspector::BackendDispatcher::getString):
+        (Inspector::BackendDispatcher::getBoolean):
+        (Inspector::BackendDispatcher::getObject):
+        (Inspector::BackendDispatcher::getArray):
+        (Inspector::BackendDispatcher::getValue):
+        (Inspector::InspectorBackendDispatcher::CallbackBase::CallbackBase): Deleted.
+        (Inspector::InspectorBackendDispatcher::CallbackBase::isActive): Deleted.
+        (Inspector::InspectorBackendDispatcher::CallbackBase::sendFailure): Deleted.
+        (Inspector::InspectorBackendDispatcher::CallbackBase::sendIfActive): Deleted.
+        (Inspector::InspectorBackendDispatcher::create): Deleted.
+        (Inspector::InspectorBackendDispatcher::registerDispatcherForDomain): Deleted.
+        (Inspector::InspectorBackendDispatcher::dispatch): Deleted.
+        (Inspector::InspectorBackendDispatcher::sendResponse): Deleted.
+        (Inspector::InspectorBackendDispatcher::reportProtocolError): Deleted.
+        (Inspector::InspectorBackendDispatcher::getInteger): Deleted.
+        (Inspector::InspectorBackendDispatcher::getDouble): Deleted.
+        (Inspector::InspectorBackendDispatcher::getString): Deleted.
+        (Inspector::InspectorBackendDispatcher::getBoolean): Deleted.
+        (Inspector::InspectorBackendDispatcher::getObject): Deleted.
+        (Inspector::InspectorBackendDispatcher::getArray): Deleted.
+        (Inspector::InspectorBackendDispatcher::getValue): Deleted.
+        * inspector/InspectorBackendDispatcher.h:
+        (Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher):
+        (Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher):
+        (Inspector::InspectorSupplementalBackendDispatcher::InspectorSupplementalBackendDispatcher): Deleted.
+        (Inspector::InspectorSupplementalBackendDispatcher::~InspectorSupplementalBackendDispatcher): Deleted.
+        * inspector/InspectorFrontendChannel.h:
+        (Inspector::FrontendChannel::~FrontendChannel):
+        (Inspector::InspectorFrontendChannel::~InspectorFrontendChannel): Deleted.
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::dispatchMessageFromFrontend):
+        (Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::didCreateFrontendAndBackend):
+        (Inspector::InspectorAgent::willDestroyFrontendAndBackend):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::didCreateFrontendAndBackend):
+        (Inspector::InspectorConsoleAgent::willDestroyFrontendAndBackend):
+        * inspector/agents/InspectorConsoleAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::didCreateFrontendAndBackend):
+        (Inspector::InspectorDebuggerAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorDebuggerAgent::handleConsoleAssert):
+        (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+        (Inspector::InspectorDebuggerAgent::pause):
+        (Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
+        (Inspector::InspectorDebuggerAgent::didPause):
+        (Inspector::InspectorDebuggerAgent::breakProgram):
+        (Inspector::InspectorDebuggerAgent::clearBreakDetails):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
+        (Inspector::JSGlobalObjectRuntimeAgent::didCreateFrontendAndBackend):
+        (Inspector::JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend):
+        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
+        * inspector/augmentable/AlternateDispatchableAgent.h:
+        * inspector/augmentable/AugmentableInspectorController.h:
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.h:
+        * inspector/scripts/codegen/cpp_generator.py:
+        (CppGenerator.cpp_type_for_formal_out_parameter):
+        (CppGenerator.cpp_type_for_stack_out_parameter):
+        * inspector/scripts/codegen/cpp_generator_templates.py:
+        (AlternateBackendDispatcher):
+        (Alternate):
+        (void):
+        (AlternateInspectorBackendDispatcher): Deleted.
+        (AlternateInspector): Deleted.
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
+        (CppBackendDispatcherHeaderGenerator._generate_alternate_handler_forward_declarations_for_domains.Alternate):
+        (CppBackendDispatcherHeaderGenerator._generate_dispatcher_declaration_for_command):
+        (CppBackendDispatcherHeaderGenerator._generate_alternate_handler_forward_declarations_for_domains.AlternateInspector): Deleted.
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator._generate_handler_class_destructor_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_large_dispatcher_switch_implementation_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py:
+        (CppFrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::connect):
+        (JSC::JSGlobalObjectDebuggable::disconnect):
+        * runtime/JSGlobalObjectDebuggable.h:
+
+2015-02-14  David Kilzer  <ddkilzer@apple.com>
+
+        REGRESSION (r180082): WebCore Debug builds fail on Mavericks due to weak export symbols
+        <http://webkit.org/b/141607>
+
+        Work towards fixing the Mavericks Debug build.
+
+        * inspector/ScriptDebugServer.h:
+        (Inspector::ScriptDebugServer::Task): Export class.
+        * inspector/agents/InspectorDebuggerAgent.h:
+        (Inspector::InspectorDebuggerAgent::Listener): Export class.
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::setConsoleClient): Do not mark inline
+        method for export.
+
+2015-02-14  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Symbol RemoteObject should not send sub-type
+        https://bugs.webkit.org/show_bug.cgi?id=141604
+
+        Reviewed by Brian Burg.
+
+        * inspector/InjectedScriptSource.js:
+
+2015-02-13  Benjamin Poulain  <bpoulain@apple.com>
+
+        Attempt to fix 32bits build after r180098
+
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        I copied the attribute from the MathObject version of that function when I moved
+        it over. DFG has no version of a function call taking those attributes.
+
+2015-02-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        JSContext Inspector: Do not stash console messages for non-debuggable JSContext
+        https://bugs.webkit.org/show_bug.cgi?id=141589
+
+        Reviewed by Timothy Hatcher.
+
+        Consider developer extras disabled for JSContext inspection if the
+        RemoteInspector server is not enabled (typically a non-debuggable
+        process rejected by webinspectord) or if remote debugging on the
+        JSContext was explicitly disabled via SPI.
+
+        When developer extras are disabled, console message will not be stashed.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::developerExtrasEnabled):
+        * inspector/JSGlobalObjectInspectorController.h:
+
+2015-02-13  Benjamin Poulain  <bpoulain@apple.com>
+
+        Add a DFG node for the Pow Intrinsics
+        https://bugs.webkit.org/show_bug.cgi?id=141540
+
+        Reviewed by Filip Pizlo.
+
+        Add a DFG Node for PowIntrinsic. This patch covers the basic cases
+        need to avoid massive regression. I will iterate over the node to cover
+        the missing types.
+
+        With this patch I get the following progressions on benchmarks:
+        -LongSpider's math-partial-sums: +5%.
+        -Kraken's imaging-darkroom: +17%
+        -AsmBench's cray.c: +6.6%
+        -CompressionBench: +2.2% globally.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        Cover a couple of trivial cases:
+        -If the exponent is zero, the result is always one, regardless of the base.
+        -If both arguments are constants, compute the result at compile time.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        We only support 2 basic cases at this time:
+        -Math.pow(double, int)
+        -Math.pow(double, double).
+
+        I'll cover Math.pow(int, int) in a follow up.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToArithSqrt):
+        (JSC::DFG::Node::arithNodeFlags):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::compileArithPowIntegerFastPath):
+        (JSC::DFG::SpeculativeJIT::compileArithPow):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithPow):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doublePow):
+        (JSC::FTL::Output::doublePowi):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * runtime/MathObject.cpp:
+        (JSC::mathProtoFuncPow):
+        (JSC::isDenormal): Deleted.
+        (JSC::isEdgeCase): Deleted.
+        (JSC::mathPow): Deleted.
+
+        * tests/stress/math-pow-basics.js: Added.
+        * tests/stress/math-pow-integer-exponent-fastpath.js: Added.
+        * tests/stress/math-pow-nan-behaviors.js: Added.
+        * tests/stress/math-pow-with-constants.js: Added.
+        Start some basic testing of Math.pow().
+        Due to the various transform, the value change when the code tiers up,
+        I covered this by checking for approximate values.
+
+2015-02-13  Benjamin Poulain  <bpoulain@apple.com>
+
+        ArithSqrt should not be conditional on supportsFloatingPointSqrt
+        https://bugs.webkit.org/show_bug.cgi?id=141546
+
+        Reviewed by Geoffrey Garen and Filip Pizlo.
+
+        Just fallback to the function call in the DFG codegen.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithSqrt):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * tests/stress/math-sqrt-basics.js: Added.
+        Basic coverage.
+
+        * tests/stress/math-sqrt-basics-disable-architecture-specific-optimizations.js: Added.
+        Same tests but forcing the function call.
+
+2015-02-13  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r180060) New js/regress-141098 test crashes when LLInt is disabled.
+        https://bugs.webkit.org/show_bug.cgi?id=141577
+
+        Reviewed by Benjamin Poulain.
+
+        Changed the prologue of the baseline JIT to check for stack space for all
+        types of code blocks.  Previously, it was only checking Function.  Now
+        it checks Program and Eval as well.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+
+2015-02-13  Benjamin Poulain  <bpoulain@apple.com>
+
+        Generate incq instead of addq when the immediate value is one
+        https://bugs.webkit.org/show_bug.cgi?id=141548
+
+        Reviewed by Gavin Barraclough.
+
+        JSC emits "addq #1 (rXX)" *a lot*.
+        This patch replace that by incq, which is one byte shorter
+        and is the adviced form.
+
+        Sunspider: +0.47%
+        Octane: +0.28%
+        Kraken: +0.44%
+        AsmBench, CompressionBench: neutral.
+
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::add64):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::incq_m):
+
+2015-02-13  Benjamin Poulain  <benjamin@webkit.org>
+
+        Little clean up of Bytecode Generator's Label
+        https://bugs.webkit.org/show_bug.cgi?id=141557
+
+        Reviewed by Michael Saboff.
+
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        Label was a friend of BytecodeGenerator in order to access
+        m_instructions. There is no need for that, BytecodeGenerator
+        has a public getter.
+
+        * bytecompiler/Label.h:
+        (JSC::Label::Label):
+        (JSC::Label::setLocation):
+        (JSC::BytecodeGenerator::newLabel):
+        Make it explicit that the generator must exist.
+
+2015-02-13  Michael Saboff  <msaboff@apple.com>
+
+        Google doc spreadsheet reproducibly crashes when sorting
+        https://bugs.webkit.org/show_bug.cgi?id=141098
+
+        Reviewed by Oliver Hunt.
+
+        Moved the stack check to before the callee registers are allocated in the
+        prologue() by movving it from the functionInitialization() macro.  This
+        way we can check the stack before moving the stack pointer, avoiding a
+        crash during a "call" instruction.  Before this change, we weren't even
+        checking the stack for program and eval execution.
+
+        Made a couple of supporting changes.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_stack_check): We can't just go up one frame as we
+        may be processing an exception to an entry frame.
+
+        * llint/LowLevelInterpreter.asm:
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        (llint_throw_from_slow_path_trampoline): Changed method to get the vm
+        from the code block to not use the codeBlock, since we may need to
+        continue from an exception in a native function.
+
+2015-02-12  Benjamin Poulain  <benjamin@webkit.org>
+
+        Simplify the initialization of BytecodeGenerator a bit
+        https://bugs.webkit.org/show_bug.cgi?id=141505
+
+        Reviewed by Anders Carlsson.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * bytecompiler/BytecodeGenerator.h:
+        Setup the default initialization at the declaration level
+        instead of the constructor.
+
+        Also made m_scopeNode and m_codeType const to make it explicit
+        that they are invariant after construction.
+
+        * parser/Nodes.cpp:
+        * runtime/Executable.cpp:
+        Remove 2 useless #includes.
+
+2015-02-12  Benjamin Poulain  <benjamin@webkit.org>
+
+        Move the generators for GetScope and SkipScope to the common core in DFGSpeculativeJIT
+        https://bugs.webkit.org/show_bug.cgi?id=141506
+
+        Reviewed by Michael Saboff.
+
+        The generators for the nodes GetScope and SkipScope were
+        completely identical between 32 and 64bits.
+
+        This patch moves the duplicated code to DFGSpeculativeJIT.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetScope):
+        (JSC::DFG::SpeculativeJIT::compileSkipScope):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2015-02-11  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] [64-bit] Work around MSVC2013 Runtime Bug
+        https://bugs.webkit.org/show_bug.cgi?id=141498
+        <rdar://problem/19803642>
+
+        Reviewed by Anders Carlsson.
+
+        Disable FMA3 instruction use in the MSVC math library to
+        work around a VS2013 runtime crash. We can remove this
+        workaround when we switch to VS2015.
+
+        * API/tests/testapi.c: Call _set_FMA3_enable(0) to disable
+        FMA3 support.
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add new files.
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+        * JavaScriptCore.vcxproj/JavaScriptCoreDLL.cpp: Added.
+        * JavaScriptCore.vcxproj/jsc/DLLLauncherMain.cpp: Call _set_FMA3_enable(0)
+        to disable FMA3 support.
+        * jsc.cpp: Ditto.
+        * testRegExp.cpp: Ditto.
+
+2015-02-11  Filip Pizlo  <fpizlo@apple.com>
+
+        The callee frame helpers in DFG::SpeculativeJIT should be available to other JITs
+        https://bugs.webkit.org/show_bug.cgi?id=141493
+
+        Reviewed by Michael Saboff.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::calleeFrameSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeArgumentSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeFrameTagSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeFramePayloadSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeArgumentTagSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeArgumentPayloadSlot): Deleted.
+        (JSC::DFG::SpeculativeJIT::calleeFrameCallerFrame): Deleted.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::calleeFrameSlot):
+        (JSC::AssemblyHelpers::calleeArgumentSlot):
+        (JSC::AssemblyHelpers::calleeFrameTagSlot):
+        (JSC::AssemblyHelpers::calleeFramePayloadSlot):
+        (JSC::AssemblyHelpers::calleeArgumentTagSlot):
+        (JSC::AssemblyHelpers::calleeArgumentPayloadSlot):
+        (JSC::AssemblyHelpers::calleeFrameCallerFrame):
+
+2015-02-11  Filip Pizlo  <fpizlo@apple.com>
+
+        SetupVarargsFrame should not assume that an inline stack frame would have identical layout to a normal stack frame
+        https://bugs.webkit.org/show_bug.cgi?id=141485
+
+        Reviewed by Oliver Hunt.
+        
+        The inlineStackOffset argument was meant to make it easy for the DFG to use this helper for
+        vararg calls from inlined code, but that doesn't work since the DFG inline call frame
+        doesn't actually put the argument count at the JSStack::ArgumentCount offset. In fact there
+        is really no such thing as an inlineStackOffset except when we OSR exit; while the code is
+        running the stack layout is compacted so that the stackOffset is not meaningful.
+
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h:
+
+2015-02-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Split FTL::JSCall into the part that knows about call inline caching and the part that interacts with LLVM patchpoints
+        https://bugs.webkit.org/show_bug.cgi?id=141455
+
+        Reviewed by Mark Lam.
+        
+        The newly introduced FTL::JSCallBase can be used to build other things, like the FTL portion
+        of https://bugs.webkit.org/show_bug.cgi?id=141332.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::specializationKindFor):
+        (JSC::CallLinkInfo::specializationKind):
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::JSCall):
+        (JSC::FTL::JSCall::emit): Deleted.
+        (JSC::FTL::JSCall::link): Deleted.
+        * ftl/FTLJSCall.h:
+        * ftl/FTLJSCallBase.cpp: Added.
+        (JSC::FTL::JSCallBase::JSCallBase):
+        (JSC::FTL::JSCallBase::emit):
+        (JSC::FTL::JSCallBase::link):
+        * ftl/FTLJSCallBase.h: Added.
+
+2015-02-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix build.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+
+2015-02-10  Filip Pizlo  <fpizlo@apple.com>
+
+        op_call_varargs should only load the length once
+        https://bugs.webkit.org/show_bug.cgi?id=141440
+        rdar://problem/19761683
+
+        Reviewed by Michael Saboff.
+        
+        Refactors the pair of calls that set up the varargs frame so that the first call returns the
+        length, and the second call uses the length returned by the first one. It turns out that this
+        gave me an opportunity to shorten a lot of the code.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::setupVarargsFrame):
+        (JSC::setupVarargsFrameAndSetThis):
+        * interpreter/Interpreter.h:
+        (JSC::calleeFrameForVarargs):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetVarargsFrame):
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyToArguments):
+        * runtime/Arguments.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::copyToArguments):
+        * runtime/JSArray.h:
+        * runtime/VM.h:
+        * tests/stress/call-varargs-length-effects.js: Added.
+        (foo):
+        (bar):
+
+2015-02-10  Michael Saboff  <msaboff@apple.com>
+
+        Crash in JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq
+        https://bugs.webkit.org/show_bug.cgi?id=139398
+
+        Reviewed by Filip Pizlo.
+
+        Due to CFA analysis, the CompareStrictEq node was determined to be unreachable, but later
+        was determined to be reachable.  When we go to lower to LLVM, the edges for the CompareStrictEq
+        node are UntypedUse which we can't compile.  Fixed this by checking that the IR before
+        lowering can still be handled by the FTL.
+
+        Had to add GetArgument as a node that the FTL can compile as the SSA conversion phase converts
+        a SetArgument to a GetArgument.  Before this change FTL::canCompile() would never see a GetArgument
+        node.  With the check right before lowering, we see this node.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl): Added a final FTL::canCompile() check before lowering
+        to verify that after all the transformations we still have valid IR for the FTL.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile): Added GetArgument as a node the FTL can compile.
+
+2015-02-10  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove unused DFG::SpeculativeJIT::calleeFrameOffset().
+
+        Rubber stamped by Michael Saboff.
+        
+        Not only was this not used, I believe that the math was wrong. The callee frame doesn't
+        actually land past m_nextMachineLocal; instead it lands just below wherever we put SP and
+        that decision is made elsewhere. Also, it makes no sense to subtract 1 from
+        m_nextMachineLocal when trying to deduce the number of in-use stack slots.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::calleeFrameOffset): Deleted.
+
+2015-02-10  Saam Barati  <saambarati1@gmail.com>
+
+        Parser::parseVarDeclarationList gets the wrong JSToken for the last identifier
+        https://bugs.webkit.org/show_bug.cgi?id=141272
+
+        Reviewed by Oliver Hunt.
+
+        This patch fixes a bug where the wrong text location would be 
+        assigned to a variable declaration inside a ForIn/ForOf loop. 
+        It also fixes a bug in the type profiler where the type profiler 
+        emits the wrong text offset for a ForIn loop's variable declarator 
+        when it's not a pattern node.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitLoopHeader):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        * tests/typeProfiler/loop.js:
+        (testForIn):
+        (testForOf):
+
+2015-02-09  Saam Barati  <saambarati1@gmail.com>
+
+        JSC's Type Profiler doesn't profile the type of the looping variable in ForOf/ForIn loops
+        https://bugs.webkit.org/show_bug.cgi?id=141241
+
+        Reviewed by Filip Pizlo.
+
+        Type information is now recorded for ForIn and ForOf statements. 
+        It was an oversight to not have these statements profiled before.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        * tests/typeProfiler/loop.js: Added.
+        (testForIn):
+        (testForOf):
+
+2015-02-09  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG::StackLayoutPhase should always set the scopeRegister to VirtualRegister() because the DFG doesn't do anything to make its value valid
+        https://bugs.webkit.org/show_bug.cgi?id=141412
+
+        Reviewed by Michael Saboff.
+        
+        StackLayoutPhase was attempting to ensure that the register that
+        CodeBlock::scopeRegister() points to is the right one for the DFG. But the DFG did nothing
+        else to maintain the validity of the scopeRegister(). It wasn't captured as far as I can
+        tell. StackLayoutPhase didn't explicitly mark it live. PreciseLocalClobberize didn't mark
+        it as being live. So, by the time we got here the register referred to by
+        CodeBlock::scopeRegister() would have been junk. Moreover, CodeBlock::scopeRegister() was
+        not used for DFG code blocks, and was hardly ever used outside of bytecode generation.
+        
+        So, this patch just removes the code to manipulate this field and replaces it with an
+        unconditional setScopeRegister(VirtualRegister()). Setting it to the invalid register
+        ensures that any attempst to read the scopeRegister in a DFG or FTL frame immediately
+        punts.
+
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+
+2015-02-09  Filip Pizlo  <fpizlo@apple.com>
+
+        Varargs frame set-up should be factored out for use by other JITs
+        https://bugs.webkit.org/show_bug.cgi?id=141388
+
+        Reviewed by Michael Saboff.
+        
+        Previously the code that dealt with varargs always assumed that we were setting up a varargs call
+        frame by literally following the execution semantics of op_call_varargs. This isn't how it'll
+        happen once the DFG and FTL do varargs calls, or when varargs calls get inlined. The DFG and FTL
+        don't literally execute bytecode; for example their stack frame layout has absolutely nothing in
+        common with what the bytecode says, and that will never change.
+        
+        This patch makes two changes:
+        
+        Setting up the varargs callee frame can be done in smaller steps: particularly in the case of a
+        varargs call that gets inlined, we aren't going to actually want to set up a callee frame in
+        full - we just want to put the arguments somewhere, and that place will not have much (if
+        anything) in common with the call frame format. This patch factors that out into something called
+        a loadVarargs. The thing we used to call loadVarargs is now called setupVarargsFrame. This patch
+        also separates loading varargs from setting this, since the fact that those two things are done
+        together is a detail made explicit in bytecode but it's not at all required in the higher-tier
+        engines. In the process of factoring this code out, I found a bunch of off-by-one errors in the
+        various calculations. I fixed them. The distance from the caller's frame pointer to the callee
+        frame pointer is always:
+        
+            numUsedCallerSlots + argCount + 1 + CallFrameSize
+        
+        where numUsedCallerSlots is toLocal(firstFreeRegister) - 1, which simplifies down to just
+        -firstFreeRegister. The code now speaks of numUsedCallerSlots rather than firstFreeRegister,
+        since the latter is a bytecode peculiarity that doesn't apply in the DFG or FTL. In the DFG, the
+        internally-computed frame size, minus the parameter slots, will be used for numUsedCallerSlots.
+        In the FTL, we will essentially compute numUsedCallerSlots dynamically by subtracting SP from FP.
+        Eventually, LLVM might give us some cleaner way of doing this, but it probably doesn't matter
+        very much.
+        
+        The arguments forwarding optimization is factored out of the Baseline JIT: the DFG and FTL will
+        want to do this optimization as well, but it involves quite a bit of code. So, this code is now
+        factored out into SetupVarargsFrame.h|cpp, so that other JITs can use it. In the process of factoring
+        this code out I noticed that the 32-bit and 64-bit code is nearly identical, so I combined them.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.h:
+        (JSC::ExecState::r):
+        (JSC::ExecState::uncheckedR):
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::operator+):
+        (JSC::VirtualRegister::operator-):
+        (JSC::VirtualRegister::operator+=):
+        (JSC::VirtualRegister::operator-=):
+        * interpreter/CallFrame.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::setupVarargsFrame):
+        (JSC::setupVarargsFrameAndSetThis):
+        * interpreter/Interpreter.h:
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader32):
+        (JSC::AssemblyHelpers::emitGetFromCallFrameHeader64):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        (JSC::JIT::emitGetFromCallFrameHeaderPtr): Deleted.
+        (JSC::JIT::emitGetFromCallFrameHeader32): Deleted.
+        (JSC::JIT::emitGetFromCallFrameHeader64): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/SetupVarargsFrame.cpp: Added.
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h: Added.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyToArguments):
+        * runtime/Arguments.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::copyToArguments):
+        * runtime/JSArray.h:
+
+2015-02-09  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG call codegen should resolve the callee operand as late as possible
+        https://bugs.webkit.org/show_bug.cgi?id=141398
+
+        Reviewed by Mark Lam.
+        
+        This is mostly a benign restructuring to help with the implementation of
+        https://bugs.webkit.org/show_bug.cgi?id=141332.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+
+2015-02-08  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG should only have two mechanisms for describing effectfulness of nodes; previously there were three
+        https://bugs.webkit.org/show_bug.cgi?id=141369
+
+        Reviewed by Michael Saboff.
+
+        We previously used the NodeMightClobber and NodeClobbersWorld NodeFlags to describe
+        effectfulness.  Starting over a year ago, we introduced a more powerful mechanism - the
+        DFG::clobberize() function.  Now we only have one remaining client of the old NodeFlags,
+        and everyone else uses DFG::clobberize().  We should get rid of those NodeFlags and
+        finally switch everyone over to DFG::clobberize().
+        
+        Unfortunately there is still another place where effectfulness of nodes is described: the
+        AbstractInterpreter. This is because the AbstractInterpreter has special tuning both for
+        compile time performance and there are places where the AI is more precise than
+        clobberize() because of its flow-sensitivity.
+        
+        This means that after this change there will be only two places, rather than three, where
+        the effectfulness of a node has to be described:
+
+        - DFG::clobberize()
+        - DFG::AbstractInterpreter
+
+        * dfg/DFGClobberize.cpp:
+        (JSC::DFG::clobbersWorld):
+        * dfg/DFGClobberize.h:
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteLength):
+        (JSC::DFG::FixupPhase::convertToGetArrayLength):
+        (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteOffset):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::isPredictedNumerical): Deleted.
+        (JSC::DFG::Graph::byValIsPure): Deleted.
+        (JSC::DFG::Graph::clobbersWorld): Deleted.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToConstant):
+        (JSC::DFG::Node::convertToGetLocalUnlinked):
+        (JSC::DFG::Node::convertToGetByOffset):
+        (JSC::DFG::Node::convertToMultiGetByOffset):
+        (JSC::DFG::Node::convertToPutByOffset):
+        (JSC::DFG::Node::convertToMultiPutByOffset):
+        * dfg/DFGNodeFlags.cpp:
+        (JSC::DFG::dumpNodeFlags):
+        * dfg/DFGNodeFlags.h:
+        * dfg/DFGNodeType.h:
+
+2015-02-09  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Fix the !ENABLE(DFG_JIT) build
+        https://bugs.webkit.org/show_bug.cgi?id=141387
+
+        Reviewed by Darin Adler.
+
+        * jit/Repatch.cpp:
+
+2015-02-08  Benjamin Poulain  <benjamin@webkit.org>
+
+        Remove a few duplicate propagation steps from the DFG's PredictionPropagation phase
+        https://bugs.webkit.org/show_bug.cgi?id=141363
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        Some blocks were duplicated, they probably evolved separately
+        to the same state.
+
+2015-02-08  Benjamin Poulain  <benjamin@webkit.org>
+
+        Remove useless declarations and a stale comment from DFGByteCodeParser.h
+        https://bugs.webkit.org/show_bug.cgi?id=141361
+
+        Reviewed by Darin Adler.
+
+        The comment refers to the original form of the ByteCodeParser:
+            parse(Graph&, JSGlobalData*, CodeBlock*, unsigned startIndex);
+
+        That form is long dead, the comment is more misleading than anything.
+
+        * dfg/DFGByteCodeParser.cpp:
+        * dfg/DFGByteCodeParser.h:
+
+2015-02-08  Benjamin Poulain  <benjamin@webkit.org>
+
+        Encapsulate DFG::Plan's beforeFTL timestamp
+        https://bugs.webkit.org/show_bug.cgi?id=141360
+
+        Reviewed by Darin Adler.
+
+        Make the attribute private, it is an internal state.
+
+        Rename beforeFTL->timeBeforeFTL for readability.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThread):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPlan.h:
+
+2015-02-08  Benjamin Poulain  <bpoulain@apple.com>
+
+        Remove DFGNode::hasArithNodeFlags()
+        https://bugs.webkit.org/show_bug.cgi?id=141319
+
+        Reviewed by Michael Saboff.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasArithNodeFlags): Deleted.
+        Unused code is unused.
+
+2015-02-07  Chris Dumez  <cdumez@apple.com>
+
+        Add Vector::removeFirstMatching() / removeAllMatching() methods taking lambda functions
+        https://bugs.webkit.org/show_bug.cgi?id=141321
+
+        Reviewed by Darin Adler.
+
+        Use new Vector::removeFirstMatching() / removeAllMatching() methods.
+
+2015-02-06  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG SSA shouldn't have SetArgument nodes
+        https://bugs.webkit.org/show_bug.cgi?id=141342
+
+        Reviewed by Mark Lam.
+
+        I was wondering why we kept the SetArgument around for captured
+        variables. It turns out we did so because we thought we had to, even
+        though we didn't have to. The node is meaningless in SSA.
+
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2015-02-06  Filip Pizlo  <fpizlo@apple.com>
+
+        It should be possible to use the DFG SetArgument node to indicate that someone set the value of a local out-of-band
+        https://bugs.webkit.org/show_bug.cgi?id=141337
+
+        Reviewed by Mark Lam.
+
+        This mainly involved ensuring that SetArgument behaves just like SetLocal from a CPS standpoint, but with a special case for those SetArguments that
+        are associated with the prologue.
+
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::run):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeSet):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        (JSC::DFG::CPSRethreadingPhase::specialCaseArguments):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeSetLocal): Deleted.
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeSetArgument): Deleted.
+
+2015-02-06  Mark Lam  <mark.lam@apple.com>
+
+        MachineThreads should be ref counted.
+        <https://webkit.org/b/141317>
+
+        Reviewed by Filip Pizlo.
+
+        The VM's MachineThreads registry object is being referenced from other
+        threads as a raw pointer.  In a scenario where the VM is destructed on
+        the main thread, there is no guarantee that another thread isn't still
+        holding a reference to the registry and will eventually invoke
+        removeThread() on it on thread exit.  Hence, there's a possible use
+        after free scenario here.
+
+        The fix is to make MachineThreads ThreadSafeRefCounted, and have all
+        threads that references keep a RefPtr to it to ensure that it stays
+        alive until the very last thread is done with it.
+
+        * API/tests/testapi.mm:
+        (useVMFromOtherThread): - Renamed to be more descriptive.
+        (useVMFromOtherThreadAndOutliveVM):
+        - Added a test that has another thread which uses the VM outlive the
+          VM to confirm that there is no crash.
+
+          However, I was not actually able to get the VM to crash without this
+          patch because I wasn't always able to the thread destructor to be
+          called.  With this patch applied, I did verify with some logging that
+          the MachineThreads registry is only destructed after all threads
+          have removed themselves from it.
+
+        (threadMain): Deleted.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::~Heap):
+        (JSC::Heap::gatherStackRoots):
+        * heap/Heap.h:
+        (JSC::Heap::machineThreads):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::Thread::Thread):
+        (JSC::MachineThreads::addCurrentThread):
+        (JSC::MachineThreads::removeCurrentThread):
+        * heap/MachineStackMarker.h:
+
+2015-02-06  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179743.
+        https://bugs.webkit.org/show_bug.cgi?id=141335
+
+        caused missing symbols in non-WebKit clients of WTF::Vector
+        (Requested by kling on #webkit).
+
+        Reverted changeset:
+
+        "Remove WTF::fastMallocGoodSize()."
+        https://bugs.webkit.org/show_bug.cgi?id=141020
+        http://trac.webkit.org/changeset/179743
+
+2015-02-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Remove BytecodeGenerator::preserveLastVar() and replace it with a more robust mechanism for preserving non-temporary registers
+        https://bugs.webkit.org/show_bug.cgi?id=141211
+
+        Reviewed by Mark Lam.
+
+        Previously, the way non-temporary registers were preserved (i.e. not reclaimed anytime
+        we did newTemporary()) by calling preserveLastVar() after all non-temps are created. It
+        would raise the refcount on the last (highest-numbered) variable created, and rely on
+        the fact that register reclamation started at higher-numbered registers and worked its
+        way down. So any retained register would block any lower-numbered registers from being
+        reclaimed.
+        
+        Also, preserveLastVar() sets a thing called m_firstConstantIndex. It's unused.
+        
+        This removes preserveLastVar() and makes addVar() retain each register it creates. This
+        is more explicit, since addVar() is the mechanism for creating non-temporary registers.
+        
+        To make this work I had to remove an assertion that Register::setIndex() can only be
+        called when the refcount is zero. This method might be called after a var is created to
+        change its index. This previously worked because preserveLastVar() would be called after
+        we had already made all index changes, so the vars would still have refcount zero. Now
+        they have refcount 1. I think it's OK to lose this assertion; I can't remember this
+        assertion ever firing in a way that alerted me to a serious issue.
+        
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::preserveLastVar): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::addVar):
+        * bytecompiler/RegisterID.h:
+        (JSC::RegisterID::setIndex):
+
+2015-02-06  Andreas Kling  <akling@apple.com>
+
+        Remove WTF::fastMallocGoodSize().
+        <https://webkit.org/b/141020>
+
+        Reviewed by Anders Carlsson.
+
+        * assembler/AssemblerBuffer.h:
+        (JSC::AssemblerData::AssemblerData):
+        (JSC::AssemblerData::grow):
+
+2015-02-05  Michael Saboff  <msaboff@apple.com>
+
+        CodeCache is not thread safe when adding the same source from two different threads
+        https://bugs.webkit.org/show_bug.cgi?id=141275
+
+        Reviewed by Mark Lam.
+
+        The issue for this bug is that one thread, takes a cache miss in CodeCache::getGlobalCodeBlock,
+        but in the process creates a cache entry with a nullptr UnlinkedCodeBlockType* which it
+        will fill in later in the function.  During the body of that function, it allocates
+        objects that may garbage collect.  During that garbage collection, we drop the all locks.
+        While the locks are released by the first thread, another thread can enter the VM and might
+        have exactly the same source and enter CodeCache::getGlobalCodeBlock() itself.  When it
+        looks up the code block, it sees it as a cache it and uses the nullptr UnlinkedCodeBlockType*
+        and crashes.  This fixes the problem by not dropping the locks during garbage collection.
+        There are other likely scenarios where we have a data structure like this code cache in an
+        unsafe state for arbitrary reentrance.
+
+        Moved the functionality of DelayedReleaseScope directly into Heap.  Changed it into
+        a simple list that is cleared with the new function Heap::releaseDelayedReleasedObjects.
+        Now we accumulate objects to be released and release them when all locks are dropped or
+        when destroying the Heap.  This eliminated the dropping and reaquiring of locks associated
+        with the old scope form of this list.
+
+        Given that all functionality of DelayedReleaseScope is now used and referenced by Heap
+        and the lock management no longer needs to be done, just made the list a member of Heap.
+        We do need to guard against the case that releasing an object can create more objects
+        by calling into JS.  That is why releaseDelayedReleasedObjects() is written to remove
+        an object to release so that we aren't recursively in Vector code.  The other thing we
+        do in releaseDelayedReleasedObjects() is to guard against recursive calls to itself using
+        the m_delayedReleaseRecursionCount.  We only release at the first entry into the function.
+        This case is already tested by testapi.mm.
+
+        * heap/DelayedReleaseScope.h: Removed file
+
+        * API/JSAPIWrapperObject.mm:
+        * API/ObjCCallbackFunction.mm:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::doSweep):
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::tryAllocateHelper):
+        (JSC::MarkedAllocator::tryAllocate):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::sweep):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::MarkedSpace):
+        (JSC::MarkedSpace::lastChanceToFinalize):
+        (JSC::MarkedSpace::didFinishIterating):
+        * heap/MarkedSpace.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbage):
+        (JSC::Heap::zombifyDeadObjects):
+        Removed references to DelayedReleaseScope and DelayedReleaseScope.h.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap): Initialized m_delayedReleaseRecursionCount.
+        (JSC::Heap::lastChanceToFinalize): Call releaseDelayedObjectsNow() as the VM is going away.
+        (JSC::Heap::releaseDelayedReleasedObjects): New function that released the accumulated
+        delayed release objects.
+
+        * heap/Heap.h:
+        (JSC::Heap::m_delayedReleaseObjects): List of objects to be released later.
+        (JSC::Heap::m_delayedReleaseRecursionCount): Counter to indicate that
+        releaseDelayedReleasedObjects is being called recursively.
+        * heap/HeapInlines.h:
+        (JSC::Heap::releaseSoon): Changed location of list to add delayed release objects.
+        
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::willReleaseLock):
+        Call Heap::releaseDelayedObjectsNow() when releasing the lock.
+
+2015-02-05  Youenn Fablet  <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar <calvaris@igalia.com>
+
+        [Streams API] Implement a barebone ReadableStream interface
+        https://bugs.webkit.org/show_bug.cgi?id=141045
+
+        Reviewed by Benjamin Poulain.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-02-05  Saam Barati  <saambarati1@gmail.com>
+
+        Crash in uninitialized deconstructing variable.
+        https://bugs.webkit.org/show_bug.cgi?id=141070
+
+        Reviewed by Michael Saboff.
+
+        According to the ES6 spec, when a destructuring pattern occurs
+        as the left hand side of an assignment inside a var declaration 
+        statement, the assignment must also have a right hand side value.
+        "var {x} = {};" is a legal syntactic statement, but,
+        "var {x};" is a syntactic error.
+
+        Section 13.2.2 of the latest draft ES6 spec specifies this requirement:
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-variable-statement
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseVarDeclaration):
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        (JSC::Parser<LexerType>::parseForStatement):
+        * parser/Parser.h:
+
+2015-02-04  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Unreviewed, fix a build break on EFL port since r179648.
+
+        * heap/MachineStackMarker.cpp: EFL port doesn't use previousThread variable. 
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+
+2015-02-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Improved Console Support for Symbol Objects
+        https://bugs.webkit.org/show_bug.cgi?id=141173
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Runtime.json:
+        New type, "symbol".
+
+        * inspector/InjectedScriptSource.js:
+        Handle Symbol objects in a few places. They don't have properties
+        and they cannot be implicitly converted to strings.
+
+2015-02-04  Mark Lam  <mark.lam@apple.com>
+
+        Undo gardening: Restoring the expected ERROR message since that is not the cause of the bot unhappiness.
+
+        Not reviewed.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+
+2015-02-04  Mark Lam  <mark.lam@apple.com>
+
+        Gardening: Changed expected ERROR message to WARNING to make test bots happy.
+
+        Rubber stamped by Simon Fraser.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+
+2015-02-04  Mark Lam  <mark.lam@apple.com>
+
+        r179576 introduce a deadlock potential during GC thread suspension.
+        <https://webkit.org/b/141268>
+
+        Reviewed by Michael Saboff.
+
+        http://trac.webkit.org/r179576 introduced a potential for deadlocking.
+        In the GC thread suspension loop, we currently delete
+        MachineThreads::Thread that we detect to be invalid.  This is unsafe
+        because we may have already suspended some threads, and one of those
+        suspended threads may still be holding the C heap lock which we need
+        for deleting the invalid thread.
+
+        The fix is to put the invalid threads in a separate toBeDeleted list,
+        and delete them only after GC has resumed all threads.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::removeCurrentThread):
+        - Undo refactoring removeThreadWithLockAlreadyAcquired() out of
+          removeCurrentThread() since it is no longer needed.
+
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+        - Put invalid Threads on a threadsToBeDeleted list, and delete those
+          Threads only after all threads have been resumed.
+
+        (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired): Deleted.
+        * heap/MachineStackMarker.h:
+
+2015-02-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Clean up Object Property Descriptor Collection
+        https://bugs.webkit.org/show_bug.cgi?id=141222
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        Use a list of options when determining which properties to collect
+        instead of a few booleans with overlapping responsibilities.
+
+2015-02-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: console.table with columnName filter for non-existent property should still show column
+        https://bugs.webkit.org/show_bug.cgi?id=141066
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::addToFrontend):
+        When a user provides a second argument, e.g. console.table(..., columnNames),
+        then pass that second argument to the frontend.
+
+        * inspector/InjectedScriptSource.js:
+        Add a FIXME about the old, unused path now.
+
+2015-02-04  Saam Barati  <saambarati1@gmail.com>
+
+        TypeSet can use 1 byte instead of 4 bytes for its m_seenTypes member variable
+        https://bugs.webkit.org/show_bug.cgi?id=141204
+
+        Reviewed by Darin Adler.
+
+        There is no need to use 32 bits to store a TypeSet::RuntimeType set 
+        bit-vector when the largest value for a single TypeSet::RuntimeType 
+        is 0x80. 8 bits is enough to represent the set of seen types.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::doesTypeConformTo):
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::seenTypes):
+
+2015-02-04  Mark Lam  <mark.lam@apple.com>
+
+        Remove concept of makeUsableFromMultipleThreads().
+        <https://webkit.org/b/141221>
+
+        Reviewed by Mark Hahnenberg.
+
+        Currently, we rely on VM::makeUsableFromMultipleThreads() being called before we
+        start acquiring the JSLock and entering the VM from different threads.
+        Acquisition of the JSLock will register the acquiring thread with the VM's thread
+        registry if not already registered.  However, it will only do this if the VM's
+        thread specific key has been initialized by makeUsableFromMultipleThreads().
+
+        This is fragile, and also does not read intuitively because one would expect to
+        acquire the JSLock before calling any methods on the VM.  This is exactly what
+        JSGlobalContextCreateInGroup() did (i.e. acquire the lock before calling
+        makeUsableFromMultipleThreads()), but is wrong.  The result is that the invoking
+        thread will not have been registered with the VM during that first entry into
+        the VM.
+
+        The fix is to make it so that we initialize the VM's thread specific key on
+        construction of the VM's MachineThreads registry instead of relying on
+        makeUsableFromMultipleThreads() being called.  With this, we can eliminate
+        makeUsableFromMultipleThreads() altogether.
+
+        Performance results are neutral in aggregate.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreateInGroup):
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::MachineThreads):
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::addCurrentThread):
+        (JSC::MachineThreads::removeThread):
+        (JSC::MachineThreads::gatherConservativeRoots):
+        (JSC::MachineThreads::makeUsableFromMultipleThreads): Deleted.
+        * heap/MachineStackMarker.h:
+        * runtime/VM.cpp:
+        (JSC::VM::sharedInstance):
+        * runtime/VM.h:
+        (JSC::VM::makeUsableFromMultipleThreads): Deleted.
+
+2015-02-04  Chris Dumez  <cdumez@apple.com>
+
+        Add removeFirst(value) / removeAll(value) methods to WTF::Vector
+        https://bugs.webkit.org/show_bug.cgi?id=141192
+
+        Reviewed by Benjamin Poulain.
+
+        Use new Vector::removeFirst(value) / removeAll(value) API to simplify the
+        code a bit.
+
+        * inspector/InspectorValues.cpp:
+        (Inspector::InspectorObjectBase::remove):
+
+2015-02-03  Mark Lam  <mark.lam@apple.com>
+
+        Workaround a thread library bug where thread destructors may not get called.
+        <https://webkit.org/b/141209>
+
+        Reviewed by Michael Saboff.
+
+        There's a bug where thread destructors may not get called.  As far as
+        we know, this only manifests on darwin ports.  We will work around this
+        by checking at GC time if the platform thread is still valid.  If not,
+        we'll purge it from the VM's registeredThreads list before proceeding
+        with thread scanning activity.
+
+        Note: it is important that we do this invalid thread detection during
+        suspension, because the validity (and liveness) of the other thread is
+        only guaranteed while it is suspended.
+
+        * API/tests/testapi.mm:
+        (threadMain):
+        - Added a test to enter the VM from another thread before we GC on
+          the main thread.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired):
+        (JSC::MachineThreads::removeCurrentThread):
+        - refactored removeThreadWithLockAlreadyAcquired() out from
+          removeCurrentThread() so that we can also call it for purging invalid
+          threads.
+        (JSC::suspendThread):
+        - Added a return status to tell if the suspension succeeded or not.
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+        - Check if the suspension failed, and purge the thread if we can't
+          suspend it.  Failure to suspend implies that the thread has
+          terminated without calling its destructor.
+        * heap/MachineStackMarker.h:
+
+2015-02-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ASSERT mainThreadPthread launching remote debuggable JSContext app with Debug JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=141189
+
+        Reviewed by Michael Saboff.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::singleton):
+        Ensure we call WTF::initializeMainThread() on the main thread so that
+        we can perform automatic String <-> NSString conversions.
+
+2015-02-03  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Project file cleanups after r179429.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2015-02-02  Filip Pizlo  <fpizlo@apple.com>
+
+        arguments[-1] should have well-defined behavior
+        https://bugs.webkit.org/show_bug.cgi?id=141183
+
+        Reviewed by Mark Lam.
+        
+        According to JSC's internal argument numbering, 0 is "this" and 1 is the first argument.
+        In the "arguments[i]" expression, "this" is not accessible and i = 0 refers to the first
+        argument. Previously we handled the bounds check in "arguments[i]" - where "arguments" is
+        statically known to be the current function's arguments object - as follows:
+        
+            add 1, i
+            branchAboveOrEqual i, callFrame.ArgumentCount, slowPath
+        
+        The problem with this is that if i = -1, this passes the test, and we end up accessing
+        what would be the "this" argument slot. That's wrong, since we should really be bottoming
+        out in arguments["-1"], which is usually undefined but could be anything. It's even worse
+        if the function is inlined or if we're in a constructor - in that case the "this" slot
+        could be garbage.
+        
+        It turns out that we had this bug in all of our engines.
+        
+        This fixes the issue by changing the algorithm to:
+        
+            load32 callFrame.ArgumentCount, tmp
+            sub 1, tmp
+            branchAboveOrEqual i, tmp, slowPath
+        
+        In some engines, we would have used the modified "i" (the one that had 1 added to it) for
+        the subsequent argument load; since we don't do this anymore I also had to change some of
+        the offsets on the BaseIndex arguments load.
+        
+        This also includes tests that are written in such a way as to get coverage on LLInt and
+        Baseline JIT (get-my-argument-by-val-wrap-around-no-warm-up), DFG and FTL
+        (get-my-argument-by-val-wrap-around), and DFG when we're being paranoid about the user
+        overwriting the "arguments" variable (get-my-argument-by-val-safe-wrap-around). This also
+        includes off-by-1 out-of-bounds tests for each of these cases, since in the process of
+        writing the patch I broke the arguments[arguments.length] case in the DFG and didn't see
+        any test failures.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::offsetOfArguments):
+        (JSC::AssemblyHelpers::offsetOfArgumentsIncludingThis): Deleted.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_get_argument_by_val):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_get_argument_by_val):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js: Added.
+        (foo):
+        * tests/stress/get-my-argument-by-val-out-of-bounds.js: Added.
+        (foo):
+        * tests/stress/get-my-argument-by-val-safe-out-of-bounds.js: Added.
+        (foo):
+        * tests/stress/get-my-argument-by-val-safe-wrap-around.js: Added.
+        (foo):
+        * tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js: Added.
+        (foo):
+        * tests/stress/get-my-argument-by-val-wrap-around.js: Added.
+        (foo):
+
+2015-02-02  Filip Pizlo  <fpizlo@apple.com>
+
+        MultiGetByOffset should be marked NodeMustGenerate
+        https://bugs.webkit.org/show_bug.cgi?id=140137
+
+        Reviewed by Michael Saboff.
+
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToGetByOffset): We were sloppy - we should also clear NodeMustGenerate once it's a GetByOffset.
+        (JSC::DFG::Node::convertToMultiGetByOffset): Assert that we converted from something that already had NodeMustGenerate.
+        * dfg/DFGNodeType.h: We shouldn't DCE a node that does checks and could be effectful in baseline. Making MultiGetByOffset as NodeMustGenerate prevents DCE. FTL could still DCE the actual loads, but the checks will stay.
+        * tests/stress/multi-get-by-offset-dce.js: Added. This previously failed because the getter wasn't called.
+        (foo):
+
+2015-02-02  Filip Pizlo  <fpizlo@apple.com>
+
+        [FTL] inlined GetMyArgumentByVal with no arguments passed causes instant crash
+        https://bugs.webkit.org/show_bug.cgi?id=141180
+        rdar://problem/19677552
+
+        Reviewed by Benjamin Poulain.
+        
+        If we do a GetMyArgumentByVal on an inlined call frame that has no arguments, then the
+        bounds check already terminates execution. This means we can skip the part where we
+        previously did an out-of-bound array access on the inlined call frame arguments vector.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::safelyInvalidateAfterTermination):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::terminate):
+        (JSC::FTL::LowerDFGToLLVM::didAlreadyTerminate):
+        (JSC::FTL::LowerDFGToLLVM::crash):
+        * tests/stress/get-my-argument-by-val-inlined-no-formal-parameters.js: Added.
+        (foo):
+        (bar):
+
+2015-02-02  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r179477): arguments simplification no longer works
+        https://bugs.webkit.org/show_bug.cgi?id=141169
+
+        Reviewed by Mark Lam.
+        
+        The operations involved in callee/scope access don't exit and shouldn't get in the way
+        of strength-reducing a Flush to a PhantomLocal. Then the PhantomLocal shouldn't get in
+        the way of further such strength-reduction. We also need to canonicalize PhantomLocal
+        before running arguments simplification.
+
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+
+2015-02-02  Filip Pizlo  <fpizlo@apple.com>
+
+        VirtualRegister should really know how to dump itself
+        https://bugs.webkit.org/show_bug.cgi?id=141171
+
+        Reviewed by Geoffrey Garen.
+        
+        Gives VirtualRegister a dump() method that pretty-prints the virtual register. The rest of
+        the patch is all about using this new power.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::constantName):
+        (JSC::CodeBlock::registerName):
+        * bytecode/CodeBlock.h:
+        (JSC::missingThisObjectMarker): Deleted.
+        * bytecode/VirtualRegister.cpp: Added.
+        (JSC::VirtualRegister::dump):
+        * bytecode/VirtualRegister.h:
+        (WTF::printInternal): Deleted.
+        * dfg/DFGArgumentPosition.h:
+        (JSC::DFG::ArgumentPosition::dump):
+        * dfg/DFGFlushedAt.cpp:
+        (JSC::DFG::FlushedAt::dump):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGPutLocalSinkingPhase.cpp:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::reportValidationContext):
+        * dfg/DFGValueSource.cpp:
+        (JSC::DFG::ValueSource::dump):
+        * dfg/DFGVariableEvent.cpp:
+        (JSC::DFG::VariableEvent::dump):
+        (JSC::DFG::VariableEvent::dumpSpillInfo):
+        * ftl/FTLExitArgumentForOperand.cpp:
+        (JSC::FTL::ExitArgumentForOperand::dump):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * profiler/ProfilerBytecodeSequence.cpp:
+        (JSC::Profiler::BytecodeSequence::BytecodeSequence):
+
+2015-02-02  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the HandleBlock piece of this patch.
+
+        * heap/HandleBlock.h:
+        * heap/HandleBlockInlines.h:
+        (JSC::HandleBlock::create):
+        (JSC::HandleBlock::destroy):
+        (JSC::HandleBlock::HandleBlock):
+        (JSC::HandleBlock::payloadEnd):
+        * heap/HandleSet.cpp:
+        (JSC::HandleSet::~HandleSet):
+        (JSC::HandleSet::grow):
+
+2015-02-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Support console.table
+        https://bugs.webkit.org/show_bug.cgi?id=141058
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        Include the firstLevelKeys filter when generating previews.
+
+        * runtime/ConsoleClient.cpp:
+        (JSC::appendMessagePrefix):
+        Differentiate console.table logs to system log.
+
+2015-01-31  Filip Pizlo  <fpizlo@apple.com>
+
+        BinarySwitch should be faster on average
+        https://bugs.webkit.org/show_bug.cgi?id=141046
+
+        Reviewed by Anders Carlsson.
+        
+        This optimizes our binary switch using math. It's strictly better than what we had before
+        assuming we bottom out in some case (rather than fall through), assuming all cases get
+        hit with equal probability. The difference is particularly large for large switch
+        statements. For example, a switch statement with 1000 cases would previously require on
+        average 13.207 branches to get to some case, while now it just requires 10.464.
+        
+        This is also a progression for the fall-through case, though we could shave off another
+        1/6 branch on average if we wanted to - though it would regress taking a case (not falling
+        through) by 1/6 branch. I believe it's better to bias the BinarySwitch for not falling
+        through.
+        
+        This also adds some randomness to the algorithm to minimize the likelihood of us
+        generating a switch statement that is always particularly bad for some input. Note that
+        the randomness has no effect on average-case performance assuming all cases are equally
+        likely.
+        
+        This ought to have no actual performance change because we don't rely on binary switches
+        that much. The main reason why this change is interesting is that I'm finding myself
+        increasingly relying on BinarySwitch, and I'd like to know that it's optimal.
+
+        * jit/BinarySwitch.cpp:
+        (JSC::BinarySwitch::BinarySwitch):
+        (JSC::BinarySwitch::~BinarySwitch):
+        (JSC::BinarySwitch::build):
+        * jit/BinarySwitch.h:
+
+2015-02-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Extend CSS.getSupportedCSSProperties to provide values for properties for CSS Augmented JSContext
+        https://bugs.webkit.org/show_bug.cgi?id=141064
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/CSS.json:
+
+2015-02-02  Daniel Bates  <dabates@apple.com>
+
+        [iOS] ASSERTION FAILED: m_scriptExecutionContext->isContextThread() in ContextDestructionObserver::observeContext
+        https://bugs.webkit.org/show_bug.cgi?id=141057
+        <rdar://problem/19068790>
+
+        Reviewed by Alexey Proskuryakov.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::receivedIndicateMessage): Modified to call WTF::callOnWebThreadOrDispatchAsyncOnMainThread().
+        (Inspector::dispatchAsyncOnQueueSafeForAnyDebuggable): Deleted; moved logic to common helper function,
+        WTF::callOnWebThreadOrDispatchAsyncOnMainThread() so that it can be called from both RemoteInspector::receivedIndicateMessage()
+        and CryptoKeyRSA::generatePair().
+
+2015-02-02  Saam Barati  <saambarati1@gmail.com>
+
+        Create tests for JSC's Control Flow Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=141123
+
+        Reviewed by Filip Pizlo.
+
+        This patch creates a control flow profiler testing API in jsc.cpp 
+        that accepts a function and a string as arguments. The string must 
+        be a substring of the text of the function argument. The API returns 
+        a boolean indicating whether or not the basic block that encloses the 
+        substring has executed.
+
+        This patch uses this API to test that the control flow profiler
+        behaves as expected on basic block boundaries. These tests do not
+        provide full coverage for all JavaScript statements that can create
+        basic blocks boundaries. Full coverage will come in a later patch.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionHasBasicBlockExecuted):
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::hasBasicBlockAtTextOffsetBeenExecuted):
+        * runtime/ControlFlowProfiler.h:
+        * tests/controlFlowProfiler: Added.
+        * tests/controlFlowProfiler.yaml: Added.
+        * tests/controlFlowProfiler/driver: Added.
+        * tests/controlFlowProfiler/driver/driver.js: Added.
+        (assert):
+        * tests/controlFlowProfiler/if-statement.js: Added.
+        (testIf):
+        (noMatches):
+        * tests/controlFlowProfiler/loop-statements.js: Added.
+        (forRegular):
+        (forIn):
+        (forOf):
+        (whileLoop):
+        * tests/controlFlowProfiler/switch-statements.js: Added.
+        (testSwitch):
+        * tests/controlFlowProfiler/test-jit.js: Added.
+        (tierUpToBaseline):
+        (tierUpToDFG):
+        (baselineTest):
+        (dfgTest):
+
+2015-01-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Polymorphic call inlining should be based on polymorphic call inline caching rather than logging
+        https://bugs.webkit.org/show_bug.cgi?id=140660
+
+        Reviewed by Geoffrey Garen.
+        
+        When we first implemented polymorphic call inlining, we did the profiling based on a call
+        edge log. The idea was to store each call edge (a tuple of call site and callee) into a
+        global log that was processed lazily. Processing the log would give precise counts of call
+        edges, and could be used to drive well-informed inlining decisions - polymorphic or not.
+        This was a speed-up on throughput tests but a slow-down for latency tests. It was a net win
+        nonetheless.
+        
+        Experience with this code shows three things. First, the call edge profiler is buggy and
+        complex. It would take work to fix the bugs. Second, the call edge profiler incurs lots of
+        overhead for latency code that we care deeply about. Third, it's not at all clear that
+        having call edge counts for every possible callee is any better than just having call edge
+        counts for the limited number of callees that an inline cache would catch.
+        
+        So, this patch removes the call edge profiler and replaces it with a polymorphic call inline
+        cache. If we miss the basic call inline cache, we inflate the cache to be a jump to an
+        out-of-line stub that cases on the previously known callees. If that misses again, then we
+        rewrite that stub to include the new callee. We do this up to some number of callees. If we
+        hit the limit then we switch to using a plain virtual call.
+        
+        Substantial speed-up on V8Spider; undoes the slow-down that the original call edge profiler
+        caused. Might be a SunSpider speed-up (below 1%), depending on hardware.
+        
+        Rolling this back in after fixing https://bugs.webkit.org/show_bug.cgi?id=141107.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallEdge.h:
+        (JSC::CallEdge::count):
+        (JSC::CallEdge::CallEdge):
+        * bytecode/CallEdgeProfile.cpp: Removed.
+        * bytecode/CallEdgeProfile.h: Removed.
+        * bytecode/CallEdgeProfileInlines.h: Removed.
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink):
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::isClosureCall):
+        (JSC::CallLinkStatus::makeClosureCall):
+        (JSC::CallLinkStatus::dump):
+        (JSC::CallLinkStatus::computeFromCallEdgeProfile): Deleted.
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isSet):
+        (JSC::CallLinkStatus::variants):
+        (JSC::CallLinkStatus::size):
+        (JSC::CallLinkStatus::at):
+        (JSC::CallLinkStatus::operator[]):
+        (JSC::CallLinkStatus::canOptimize):
+        (JSC::CallLinkStatus::edges): Deleted.
+        (JSC::CallLinkStatus::canTrustCounts): Deleted.
+        * bytecode/CallVariant.cpp:
+        (JSC::variantListWithVariant):
+        (JSC::despecifiedVariantList):
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::linkIncomingPolymorphicCall):
+        (JSC::CodeBlock::unlinkIncomingCalls):
+        (JSC::CodeBlock::noticeIncomingCall):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::isIncomingCallAlreadyLinked): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling): Deleted.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * jit/BinarySwitch.h:
+        * jit/ClosureCallStubRoutine.cpp: Removed.
+        * jit/ClosureCallStubRoutine.h: Removed.
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationLinkPolymorphicCallFor):
+        (JSC::operationLinkClosureCallFor): Deleted.
+        * jit/JITStubRoutine.h:
+        * jit/JITWriteBarrier.h:
+        * jit/PolymorphicCallStubRoutine.cpp: Added.
+        (JSC::PolymorphicCallNode::~PolymorphicCallNode):
+        (JSC::PolymorphicCallNode::unlink):
+        (JSC::PolymorphicCallCase::dump):
+        (JSC::PolymorphicCallStubRoutine::PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::variants):
+        (JSC::PolymorphicCallStubRoutine::edges):
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        (JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal):
+        * jit/PolymorphicCallStubRoutine.h: Added.
+        (JSC::PolymorphicCallNode::PolymorphicCallNode):
+        (JSC::PolymorphicCallCase::PolymorphicCallCase):
+        (JSC::PolymorphicCallCase::variant):
+        (JSC::PolymorphicCallCase::codeBlock):
+        * jit/Repatch.cpp:
+        (JSC::linkSlowFor):
+        (JSC::linkFor):
+        (JSC::revertCall):
+        (JSC::unlinkFor):
+        (JSC::linkVirtualFor):
+        (JSC::linkPolymorphicCall):
+        (JSC::linkClosureCall): Deleted.
+        * jit/Repatch.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::linkPolymorphicCallForThunkGenerator):
+        (JSC::linkPolymorphicCallThunkGenerator):
+        (JSC::linkPolymorphicCallThatPreservesRegsThunkGenerator):
+        (JSC::linkClosureCallForThunkGenerator): Deleted.
+        (JSC::linkClosureCallThunkGenerator): Deleted.
+        (JSC::linkClosureCallThatPreservesRegsThunkGenerator): Deleted.
+        * jit/ThunkGenerators.h:
+        (JSC::linkPolymorphicCallThunkGeneratorFor):
+        (JSC::linkClosureCallThunkGeneratorFor): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::jitCompileAndSetHeuristics):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::prepareToDiscardCode):
+        (JSC::VM::ensureCallEdgeLog): Deleted.
+        * runtime/VM.h:
+
+2015-01-30  Filip Pizlo  <fpizlo@apple.com>
+
+        Converting Flushes and PhantomLocals to Phantoms requires an OSR availability analysis rather than just using the SetLocal's child
+        https://bugs.webkit.org/show_bug.cgi?id=141107
+
+        Reviewed by Michael Saboff.
+        
+        See the bugzilla for a discussion of the problem. This addresses the problem by ensuring
+        that Flushes are always strength-reduced to PhantomLocals, and CPS rethreading does a mini
+        OSR availability analysis to determine the right MovHint value to use for the Phantom.
+
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
+        (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
+        (JSC::DFG::CPSRethreadingPhase::clearVariables):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        (JSC::DFG::CPSRethreadingPhase::clearVariablesAtHeadAndTail): Deleted.
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertPhantomToPhantomLocal):
+        (JSC::DFG::Node::convertFlushToPhantomLocal):
+        (JSC::DFG::Node::convertToPhantomLocal): Deleted.
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * tests/stress/inline-call-that-doesnt-use-all-args.js: Added.
+        (foo):
+        (bar):
+        (baz):
+
+2015-01-31  Michael Saboff  <msaboff@apple.com>
+
+        Crash (DFG assertion) beneath AbstractInterpreter::verifyEdge() @ http://experilous.com/1/planet-generator/2014-09-28/version-1
+        https://bugs.webkit.org/show_bug.cgi?id=141111
+
+        Reviewed by Filip Pizlo.
+
+        In LowerDFGToLLVM::compileNode(), if we determine while compiling a node that we would have
+        exited, we don't need to process the OSR availability or abstract interpreter.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::safelyInvalidateAfterTermination): Broke this out a a separate
+        method since we need to call it at the top and near the bottom of compileNode().
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2015-01-31  Sam Weinig  <sam@webkit.org>
+
+        Remove even more Mountain Lion support
+        https://bugs.webkit.org/show_bug.cgi?id=141124
+
+        Reviewed by Alexey Proskuryakov.
+
+        * API/tests/DateTests.mm:
+        * Configurations/Base.xcconfig:
+        * Configurations/DebugRelease.xcconfig:
+        * Configurations/FeatureDefines.xcconfig:
+        * Configurations/Version.xcconfig:
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+
+2015-01-31  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179426.
+        https://bugs.webkit.org/show_bug.cgi?id=141119
+
+        "caused a memory use regression" (Requested by Guest45 on
+        #webkit).
+
+        Reverted changeset:
+
+        "Use FastMalloc (bmalloc) instead of BlockAllocator for GC
+        pages"
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+        http://trac.webkit.org/changeset/179426
+
+2015-01-30  Daniel Bates  <dabates@apple.com>
+
+        Clean up: Remove unnecessary <dispatch/dispatch.h> header from RemoteInspectorDebuggableConnection.h
+        https://bugs.webkit.org/show_bug.cgi?id=141067
+
+        Reviewed by Timothy Hatcher.
+
+        Remove the header <dispatch/dispatch.h> from RemoteInspectorDebuggableConnection.h as we
+        do not make use of its functionality. Instead, include this header in RemoteInspectorDebuggableConnection.mm
+        and RemoteInspector.mm. The latter depended on <dispatch/dispatch.h> being included via
+        header RemoteInspectorDebuggableConnection.h.
+
+        * inspector/remote/RemoteInspector.mm: Include header <dispatch/dispatch.h>.
+        * inspector/remote/RemoteInspectorDebuggableConnection.h: Remove header <dispatch/dispatch.h>.
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm: Include header <dispatch/dispatch.h>.
+
+2015-01-30  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement ES6 Symbol
+        https://bugs.webkit.org/show_bug.cgi?id=140435
+
+        Reviewed by Geoffrey Garen.
+
+        This patch implements ES6 Symbol. In this patch, we don't support
+        Symbol.keyFor, Symbol.for, Object.getOwnPropertySymbols. They will be
+        supported in the subsequent patches.
+
+        Since ES6 Symbol is introduced as new primitive value, we implement
+        Symbol as a derived class from JSCell. And now JSValue accepts Symbol*
+        as a new primitive value.
+
+        Symbol has a *unique* flagged StringImpl* as an `uid`. Which pointer
+        value represents the Symbol's identity. So don't compare Symbol's
+        JSCell pointer value for comparison.
+        This enables re-producing Symbol primitive value from StringImpl* uid
+        by executing`Symbol::create(vm, uid)`. This is needed to produce
+        Symbol primitive values from stored StringImpl* in `Object.getOwnPropertySymbols`.
+
+        And Symbol.[[Description]] is folded into the string value of Symbol's uid.
+        By doing so, we can represent ES6 Symbol without extending current PropertyTable key; StringImpl*.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.order:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/BuiltinNames.h:
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        * interpreter/Interpreter.cpp:
+        * jit/JITOperations.cpp:
+        (JSC::getByVal):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonIdentifiers.h:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opIn):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createUndefinedVariableError):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::synthesizePrototype):
+        (JSC::JSValue::dumpInContextAssumingStructure):
+        (JSC::JSValue::toStringSlowCase):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isSymbol):
+        (JSC::JSValue::isPrimitive):
+        (JSC::JSValue::toPropertyKey):
+
+        It represents ToPropertyKey abstract operation in the ES6 spec.
+        It cleans up the old implementation's `isName` checks.
+        And to prevent performance regressions in
+            js/regress/fold-get-by-id-to-multi-get-by-offset-rare-int.html
+            js/regress/fold-get-by-id-to-multi-get-by-offset.html
+        we annnotate this function as ALWAYS_INLINE.
+
+        (JSC::JSValue::getPropertySlot):
+        (JSC::JSValue::get):
+        (JSC::JSValue::equalSlowCaseInline):
+        (JSC::JSValue::strictEqualSlowCaseInline):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::put):
+        (JSC::JSCell::putByIndex):
+        (JSC::JSCell::toPrimitive):
+        (JSC::JSCell::getPrimitiveNumber):
+        (JSC::JSCell::toNumber):
+        (JSC::JSCell::toObject):
+        * runtime/JSCell.h:
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::isSymbol):
+        (JSC::JSCell::toBoolean):
+        (JSC::JSCell::pureToBoolean):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::symbolPrototype):
+        (JSC::JSGlobalObject::symbolObjectStructure):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Stringifier):
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+        * runtime/JSType.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::isName): Deleted.
+        * runtime/MapData.cpp:
+        (JSC::MapData::find):
+        (JSC::MapData::add):
+        (JSC::MapData::remove):
+        (JSC::MapData::replaceAndPackBackingStore):
+        * runtime/MapData.h:
+        (JSC::MapData::clear):
+        * runtime/NameInstance.h: Removed.
+        * runtime/NamePrototype.cpp: Removed.
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyDescriptor):
+        (JSC::objectConstructorDefineProperty):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncHasOwnProperty):
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+        (JSC::objectProtoFuncPropertyIsEnumerable):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        (JSC::jsIsObjectType):
+        * runtime/PrivateName.h:
+        (JSC::PrivateName::PrivateName):
+        (JSC::PrivateName::operator==):
+        (JSC::PrivateName::operator!=):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::get):
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (JSC::PropertyName::publicName):
+        * runtime/SmallStrings.h:
+        * runtime/StringConstructor.cpp:
+        (JSC::callStringConstructor):
+
+        In ES6, String constructor accepts Symbol to execute `String(symbol)`.
+
+        * runtime/Structure.cpp:
+        (JSC::Structure::getPropertyNamesFromStructure):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::prototypeForLookup):
+        * runtime/Symbol.cpp: Added.
+        (JSC::Symbol::Symbol):
+        (JSC::SymbolObject::create):
+        (JSC::Symbol::toPrimitive):
+        (JSC::Symbol::toBoolean):
+        (JSC::Symbol::getPrimitiveNumber):
+        (JSC::Symbol::toObject):
+        (JSC::Symbol::toNumber):
+        (JSC::Symbol::destroy):
+        (JSC::Symbol::descriptiveString):
+        * runtime/Symbol.h: Added.
+        (JSC::Symbol::createStructure):
+        (JSC::Symbol::create):
+        (JSC::Symbol::privateName):
+        (JSC::Symbol::finishCreation):
+        (JSC::asSymbol):
+        * runtime/SymbolConstructor.cpp: Renamed from Source/JavaScriptCore/runtime/NameConstructor.cpp.
+        (JSC::SymbolConstructor::SymbolConstructor):
+        (JSC::SymbolConstructor::finishCreation):
+        (JSC::callSymbol):
+        (JSC::SymbolConstructor::getConstructData):
+        (JSC::SymbolConstructor::getCallData):
+        * runtime/SymbolConstructor.h: Renamed from Source/JavaScriptCore/runtime/NameConstructor.h.
+        (JSC::SymbolConstructor::create):
+        (JSC::SymbolConstructor::createStructure):
+        * runtime/SymbolObject.cpp: Renamed from Source/JavaScriptCore/runtime/NameInstance.cpp.
+        (JSC::SymbolObject::SymbolObject):
+        (JSC::SymbolObject::finishCreation):
+        (JSC::SymbolObject::defaultValue):
+
+        Now JSC doesn't support @@toPrimitive. So instead of it, we implement
+        Symbol.prototype[@@toPrimitive] as ES5 Symbol.[[DefaultValue]].
+
+        * runtime/SymbolObject.h: Added.
+        (JSC::SymbolObject::create):
+        (JSC::SymbolObject::internalValue):
+        (JSC::SymbolObject::createStructure):
+        * runtime/SymbolPrototype.cpp: Added.
+        (JSC::SymbolPrototype::SymbolPrototype):
+        (JSC::SymbolPrototype::finishCreation):
+        (JSC::SymbolPrototype::getOwnPropertySlot):
+        (JSC::symbolProtoFuncToString):
+        (JSC::symbolProtoFuncValueOf):
+        * runtime/SymbolPrototype.h: Renamed from Source/JavaScriptCore/runtime/NamePrototype.h.
+        (JSC::SymbolPrototype::create):
+        (JSC::SymbolPrototype::createStructure):
+
+        SymbolPrototype object is ordinary JS object. Not wrapper object of Symbol.
+        It is tested in js/symbol-prototype-is-ordinary-object.html.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2015-01-30  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the HandleBlock piece of this patch.
+
+        * heap/HandleBlock.h:
+        * heap/HandleBlockInlines.h:
+        (JSC::HandleBlock::create):
+        (JSC::HandleBlock::destroy):
+        (JSC::HandleBlock::HandleBlock):
+        (JSC::HandleBlock::payloadEnd):
+        * heap/HandleSet.cpp:
+        (JSC::HandleSet::~HandleSet):
+        (JSC::HandleSet::grow):
+
+2015-01-30  Geoffrey Garen  <ggaren@apple.com>
+
+        GC marking threads should clear malloc caches
+        https://bugs.webkit.org/show_bug.cgi?id=141097
+
+        Reviewed by Sam Weinig.
+
+        Follow-up based on Mark Hahnenberg's review: Release after the copy
+        phase, rather than after any phase, since we'd rather not release
+        between marking and copying.
+
+        * heap/GCThread.cpp:
+        (JSC::GCThread::waitForNextPhase):
+        (JSC::GCThread::gcThreadMain):
+
+2015-01-30  Geoffrey Garen  <ggaren@apple.com>
+
+        GC marking threads should clear malloc caches
+        https://bugs.webkit.org/show_bug.cgi?id=141097
+
+        Reviewed by Andreas Kling.
+
+        This is an attempt to ameliorate a potential memory use regression
+        caused by https://bugs.webkit.org/show_bug.cgi?id=140900
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages.
+
+        FastMalloc may accumulate a per-thread cache on each of the 8-ish
+        GC marking threads, which can be expensive.
+
+        * heap/GCThread.cpp:
+        (JSC::GCThread::waitForNextPhase): Scavenge the current thread before
+        going to sleep. There's probably not too much value to keeping our
+        per-thread cache between GCs, and it has some memory footprint.
+
+2015-01-30  Chris Dumez  <cdumez@apple.com>
+
+        Rename shared() static member functions to singleton() for singleton classes.
+        https://bugs.webkit.org/show_bug.cgi?id=141088
+
+        Reviewed by Ryosuke Niwa and Benjamin Poulain.
+
+        Rename shared() static member functions to singleton() for singleton
+        classes as per the recent coding style change.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::singleton):
+        (Inspector::RemoteInspector::start):
+        (Inspector::RemoteInspector::shared): Deleted.
+        * inspector/remote/RemoteInspectorDebuggable.cpp:
+        (Inspector::RemoteInspectorDebuggable::~RemoteInspectorDebuggable):
+        (Inspector::RemoteInspectorDebuggable::init):
+        (Inspector::RemoteInspectorDebuggable::update):
+        (Inspector::RemoteInspectorDebuggable::setRemoteDebuggingAllowed):
+        (Inspector::RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection):
+        (Inspector::RemoteInspectorDebuggable::unpauseForInitializedInspector):
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::setup):
+        (Inspector::RemoteInspectorDebuggableConnection::sendMessageToFrontend):
+
+2015-01-30  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the CopyWorkListSegment piece of this patch.
+
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::reportLiveBytes):
+        * heap/CopyWorkList.h:
+        (JSC::CopyWorkListSegment::create):
+        (JSC::CopyWorkListSegment::destroy):
+        (JSC::CopyWorkListSegment::CopyWorkListSegment):
+        (JSC::CopyWorkList::CopyWorkList):
+        (JSC::CopyWorkList::~CopyWorkList):
+        (JSC::CopyWorkList::append):
+
+2015-01-29  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179357 and r179358.
+        https://bugs.webkit.org/show_bug.cgi?id=141062
+
+        Suspect this caused WebGL tests to start flaking (Requested by
+        kling on #webkit).
+
+        Reverted changesets:
+
+        "Polymorphic call inlining should be based on polymorphic call
+        inline caching rather than logging"
+        https://bugs.webkit.org/show_bug.cgi?id=140660
+        http://trac.webkit.org/changeset/179357
+
+        "Unreviewed, fix no-JIT build."
+        http://trac.webkit.org/changeset/179358
+
+2015-01-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed op_ret_object_or_this
+        https://bugs.webkit.org/show_bug.cgi?id=141048
+
+        Reviewed by Michael Saboff.
+
+        op_ret_object_or_this was one opcode that would keep us out of the
+        optimizing compilers.
+
+        We don't need a special-purpose opcode; we can just use a branch.
+
+        * bytecode/BytecodeBasicBlock.cpp:
+        (JSC::isTerminal): Removed.
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset): Removed.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Removed.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitReturn): Use an explicit branch to determine
+        if we need to substitute 'this' for the return value. Our engine no longer
+        benefits from fused opcodes that dispatch less in the interpreter.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::emit_op_ret_object_or_this): Deleted.
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_ret_object_or_this): Deleted.
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm: Removed.
+
+2015-01-29  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Implement ES6 class syntax without inheritance support
+        https://bugs.webkit.org/show_bug.cgi?id=140918
+
+        Reviewed by Geoffrey Garen.
+
+        Added the most basic support for ES6 class syntax. After this patch, we support basic class definition like:
+        class A {
+            constructor() { }
+            someMethod() { }
+        }
+
+        We'll add the support for "extends" keyword and automatically generating a constructor in follow up patches.
+        We also don't support block scoping of a class declaration.
+
+        We support both class declaration and class expression. A class expression is implemented by the newly added
+        ClassExprNode AST node. A class declaration is implemented by ClassDeclNode, which is a thin wrapper around
+        AssignResolveNode.
+
+        Tests: js/class-syntax-declaration.html
+               js/class-syntax-expression.html
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ObjectLiteralNode::emitBytecode): Create a new object instead of delegating the work to PropertyListNode.
+        Also fixed the 5-space indentation.
+        (JSC::PropertyListNode::emitBytecode): Don't create a new object now that ObjectLiteralNode does this.
+        (JSC::ClassDeclNode::emitBytecode): Added. Just let the AssignResolveNode node emit the byte code.
+        (JSC::ClassExprNode::emitBytecode): Create the class constructor and add static methods to the constructor by
+        emitting the byte code for PropertyListNode. Add instance methods to the class's prototype object the same way.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createClassExpr): Added. Creates a ClassExprNode.
+        (JSC::ASTBuilder::createClassDeclStatement): Added. Creates a AssignResolveNode and wraps it by a ClassDeclNode.
+
+        * parser/NodeConstructors.h:
+        (JSC::ClassDeclNode::ClassDeclNode): Added.
+        (JSC::ClassExprNode::ClassExprNode): Added.
+
+        * parser/Nodes.h:
+        (JSC::ClassExprNode): Added.
+        (JSC::ClassDeclNode): Added.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseStatement): Added the support for class declaration.
+        (JSC::stringForFunctionMode): Return "method" for MethodMode.
+        (JSC::Parser<LexerType>::parseClassDeclaration): Added. Uses parseClass to create a class expression and wraps
+        it with ClassDeclNode as described above.
+        (JSC::Parser<LexerType>::parseClass): Parses a class expression.
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseGetterSetter): Extracted from parseProperty to share the code between parseProperty
+        and parseClass.
+        (JSC::Parser<LexerType>::parsePrimaryExpression): Added the support for class expression.
+
+        * parser/Parser.h:
+        (FunctionParseMode): Added MethodMode.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createClassExpr): Added.
+        (JSC::SyntaxChecker::createClassDeclStatement): Added.
+
+2015-01-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Try to fix the Windows build.
+
+        Not reviewed.
+
+        * heap/WeakBlock.h: Use the fully qualified name when declaring our friend.
+
+2015-01-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the WeakBlock piece of this patch.
+
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::create):
+        (JSC::WeakBlock::destroy):
+        (JSC::WeakBlock::WeakBlock):
+        * heap/WeakBlock.h:
+        * heap/WeakSet.cpp:
+        (JSC::WeakSet::~WeakSet):
+        (JSC::WeakSet::addAllocator):
+        (JSC::WeakSet::removeAllocator):
+
+2015-01-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Use Vector instead of GCSegmentedArray in CodeBlockSet
+        https://bugs.webkit.org/show_bug.cgi?id=141044
+
+        Reviewed by Ryosuke Niwa.
+
+        This is allowed now that we've gotten rid of fastMallocForbid.
+
+        4kB was a bit overkill for just storing a few pointers.
+
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::CodeBlockSet):
+        * heap/CodeBlockSet.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+
+2015-01-29  Filip Pizlo  <fpizlo@apple.com>
+
+        Unreviewed, fix no-JIT build.
+
+        * jit/PolymorphicCallStubRoutine.cpp:
+
+2015-01-28  Filip Pizlo  <fpizlo@apple.com>
+
+        Polymorphic call inlining should be based on polymorphic call inline caching rather than logging
+        https://bugs.webkit.org/show_bug.cgi?id=140660
+
+        Reviewed by Geoffrey Garen.
+        
+        When we first implemented polymorphic call inlining, we did the profiling based on a call
+        edge log. The idea was to store each call edge (a tuple of call site and callee) into a
+        global log that was processed lazily. Processing the log would give precise counts of call
+        edges, and could be used to drive well-informed inlining decisions - polymorphic or not.
+        This was a speed-up on throughput tests but a slow-down for latency tests. It was a net win
+        nonetheless.
+        
+        Experience with this code shows three things. First, the call edge profiler is buggy and
+        complex. It would take work to fix the bugs. Second, the call edge profiler incurs lots of
+        overhead for latency code that we care deeply about. Third, it's not at all clear that
+        having call edge counts for every possible callee is any better than just having call edge
+        counts for the limited number of callees that an inline cache would catch.
+        
+        So, this patch removes the call edge profiler and replaces it with a polymorphic call inline
+        cache. If we miss the basic call inline cache, we inflate the cache to be a jump to an
+        out-of-line stub that cases on the previously known callees. If that misses again, then we
+        rewrite that stub to include the new callee. We do this up to some number of callees. If we
+        hit the limit then we switch to using a plain virtual call.
+        
+        Substantial speed-up on V8Spider; undoes the slow-down that the original call edge profiler
+        caused. Might be a SunSpider speed-up (below 1%), depending on hardware.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallEdge.h:
+        (JSC::CallEdge::count):
+        (JSC::CallEdge::CallEdge):
+        * bytecode/CallEdgeProfile.cpp: Removed.
+        * bytecode/CallEdgeProfile.h: Removed.
+        * bytecode/CallEdgeProfileInlines.h: Removed.
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::unlink):
+        (JSC::CallLinkInfo::visitWeak):
+        * bytecode/CallLinkInfo.h:
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeFromCallLinkInfo):
+        (JSC::CallLinkStatus::isClosureCall):
+        (JSC::CallLinkStatus::makeClosureCall):
+        (JSC::CallLinkStatus::dump):
+        (JSC::CallLinkStatus::computeFromCallEdgeProfile): Deleted.
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isSet):
+        (JSC::CallLinkStatus::variants):
+        (JSC::CallLinkStatus::size):
+        (JSC::CallLinkStatus::at):
+        (JSC::CallLinkStatus::operator[]):
+        (JSC::CallLinkStatus::canOptimize):
+        (JSC::CallLinkStatus::edges): Deleted.
+        (JSC::CallLinkStatus::canTrustCounts): Deleted.
+        * bytecode/CallVariant.cpp:
+        (JSC::variantListWithVariant):
+        (JSC::despecifiedVariantList):
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::linkIncomingPolymorphicCall):
+        (JSC::CodeBlock::unlinkIncomingCalls):
+        (JSC::CodeBlock::noticeIncomingCall):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::isIncomingCallAlreadyLinked): Deleted.
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addCallWithoutSettingResult):
+        (JSC::DFG::ByteCodeParser::handleCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTierUpCheckInjectionPhase.cpp:
+        (JSC::DFG::TierUpCheckInjectionPhase::run):
+        (JSC::DFG::TierUpCheckInjectionPhase::removeFTLProfiling): Deleted.
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * jit/BinarySwitch.h:
+        * jit/ClosureCallStubRoutine.cpp: Removed.
+        * jit/ClosureCallStubRoutine.h: Removed.
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationLinkPolymorphicCallFor):
+        (JSC::operationLinkClosureCallFor): Deleted.
+        * jit/JITStubRoutine.h:
+        * jit/JITWriteBarrier.h:
+        * jit/PolymorphicCallStubRoutine.cpp: Added.
+        (JSC::PolymorphicCallNode::~PolymorphicCallNode):
+        (JSC::PolymorphicCallNode::unlink):
+        (JSC::PolymorphicCallCase::dump):
+        (JSC::PolymorphicCallStubRoutine::PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine):
+        (JSC::PolymorphicCallStubRoutine::variants):
+        (JSC::PolymorphicCallStubRoutine::edges):
+        (JSC::PolymorphicCallStubRoutine::visitWeak):
+        (JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal):
+        * jit/PolymorphicCallStubRoutine.h: Added.
+        (JSC::PolymorphicCallNode::PolymorphicCallNode):
+        (JSC::PolymorphicCallCase::PolymorphicCallCase):
+        (JSC::PolymorphicCallCase::variant):
+        (JSC::PolymorphicCallCase::codeBlock):
+        * jit/Repatch.cpp:
+        (JSC::linkSlowFor):
+        (JSC::linkFor):
+        (JSC::revertCall):
+        (JSC::unlinkFor):
+        (JSC::linkVirtualFor):
+        (JSC::linkPolymorphicCall):
+        (JSC::linkClosureCall): Deleted.
+        * jit/Repatch.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::linkPolymorphicCallForThunkGenerator):
+        (JSC::linkPolymorphicCallThunkGenerator):
+        (JSC::linkPolymorphicCallThatPreservesRegsThunkGenerator):
+        (JSC::linkClosureCallForThunkGenerator): Deleted.
+        (JSC::linkClosureCallThunkGenerator): Deleted.
+        (JSC::linkClosureCallThatPreservesRegsThunkGenerator): Deleted.
+        * jit/ThunkGenerators.h:
+        (JSC::linkPolymorphicCallThunkGeneratorFor):
+        (JSC::linkClosureCallThunkGeneratorFor): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::jitCompileAndSetHeuristics):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::prepareToDiscardCode):
+        (JSC::VM::ensureCallEdgeLog): Deleted.
+        * runtime/VM.h:
+
+2015-01-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ES6: Improved Console Format for Set and Map Objects (like Arrays)
+        https://bugs.webkit.org/show_bug.cgi?id=122867
+
+        Reviewed by Timothy Hatcher.
+
+        Add new Runtime.RemoteObject object subtypes for "map", "set", and "weakmap".
+
+        Upgrade Runtime.ObjectPreview to include type/subtype information. Now,
+        an ObjectPreview can be used for any value, in place of a RemoteObject,
+        and not capture / hold a reference to the value. The value will be in
+        the string description.
+
+        Adding this information to ObjectPreview can duplicate some information
+        in the protocol messages if a preview is provided, but simplifies
+        previews, so that all the information you need for any RemoteObject
+        preview is available. To slim messages further, make "overflow" and
+        "properties" only available on previews that may contain properties.
+        So, not primitives or null.
+
+        Finally, for "Map/Set/WeakMap" add an "entries" list to the preview
+        that will return previews with "key" and "value" properties depending
+        on the collection type. To get live, non-preview objects from a
+        collection, use Runtime.getCollectionEntries.
+
+        In order to keep the WeakMap's values Weak the frontend may provide
+        a unique object group name when getting collection entries. It may
+        then release that object group, e.g. when not showing the WeakMap's
+        values to the user, and thus remove the strong reference to the keys
+        so they may be garbage collected.
+
+        * runtime/WeakMapData.h:
+        (JSC::WeakMapData::begin):
+        (JSC::WeakMapData::end):
+        Expose iterators so the Inspector may access WeakMap keys/values.
+
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionWeakMapEntries):
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        Discern "map", "set", and "weakmap" object subtypes.
+
+        (Inspector::JSInjectedScriptHost::weakMapEntries):
+        Return a list of WeakMap entries. These are strong references
+        that the Inspector code is responsible for releasing.
+
+        * inspector/protocol/Runtime.json:
+        Update types and expose the new getCollectionEntries command.
+
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getCollectionEntries):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getInternalProperties):
+        (Inspector::InjectedScript::getCollectionEntries):
+        Pass through to the InjectedScript and call getCollectionEntries.
+
+        * inspector/scripts/codegen/generator.py:
+        Add another type with runtime casting.
+
+        * inspector/InjectedScriptSource.js:
+        - Implement getCollectionEntries to get a range of values from a
+        collection. The non-Weak collections have an order to their keys (in
+        order of added) so range'd gets are okay. WeakMap does not have an
+        order, so only allow fetching a number of values.
+        - Update preview generation to address the Runtime.ObjectPreview
+        type changes.
+
+2015-01-28  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Re-landing just the GCArraySegment piece of this patch.
+
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::CodeBlockSet):
+        * heap/CodeBlockSet.h:
+        * heap/GCSegmentedArray.h:
+        (JSC::GCArraySegment::GCArraySegment):
+        * heap/GCSegmentedArrayInlines.h:
+        (JSC::GCSegmentedArray<T>::GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::~GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::clear):
+        (JSC::GCSegmentedArray<T>::expand):
+        (JSC::GCSegmentedArray<T>::refill):
+        (JSC::GCArraySegment<T>::create):
+        (JSC::GCArraySegment<T>::destroy):
+        * heap/GCThreadSharedData.cpp:
+        (JSC::GCThreadSharedData::GCThreadSharedData):
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        * heap/MarkStack.cpp:
+        (JSC::MarkStackArray::MarkStackArray):
+        * heap/MarkStack.h:
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::SlotVisitor):
+
+2015-01-29  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Move HAVE_DTRACE definition back to Platform.h
+        https://bugs.webkit.org/show_bug.cgi?id=141033
+
+        Reviewed by Dan Bernstein.
+
+        * Configurations/Base.xcconfig:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2015-01-28  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed fastMallocForbid / fastMallocAllow
+        https://bugs.webkit.org/show_bug.cgi?id=141012
+
+        Reviewed by Mark Hahnenberg.
+
+        Copy non-current thread stacks before scanning them instead of scanning
+        them in-place.
+
+        This operation is uncommon (i.e., never in the web content process),
+        and even in a stress test with 4 threads it only copies about 27kB,
+        so I think the performance cost is OK.
+
+        Scanning in-place requires a complex dance where we constrain our GC
+        data structures not to use malloc, free, or any other interesting functions
+        that might acquire locks. We've gotten this wrong many times in the past,
+        and I just got it wrong again yesterday. Since this code path is rarely
+        tested, I want it to just make sense, and not depend on or constrain the
+        details of the rest of the GC heap's design.
+
+        * heap/MachineStackMarker.cpp:
+        (JSC::otherThreadStack): Factored out a helper function for dealing with
+        unaligned and/or backwards pointers.
+
+        (JSC::MachineThreads::tryCopyOtherThreadStack): This is now the only
+        constrained function, and it only calls memcpy and low-level thread APIs.
+
+        (JSC::MachineThreads::tryCopyOtherThreadStacks): The design here is that
+        you do one pass over all the threads to compute their combined size,
+        and then a second pass to do all the copying. In theory, the threads may
+        grow in between passes, in which case you'll continue until the threads
+        stop growing. In practice, you never continue.
+
+        (JSC::growBuffer): Helper function for growing.
+
+        (JSC::MachineThreads::gatherConservativeRoots):
+        (JSC::MachineThreads::gatherFromOtherThread): Deleted.
+        * heap/MachineStackMarker.h: Updated for interface changes.
+
+2015-01-28  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: remove CSS.setPropertyText, CSS.toggleProperty and related dead code
+        https://bugs.webkit.org/show_bug.cgi?id=140961
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/CSS.json: Remove unused protocol methods.
+
+2015-01-28  Dana Burkart  <dburkart@apple.com>
+
+        Move ASan flag settings from DebugRelease.xcconfig to Base.xcconfig
+        https://bugs.webkit.org/show_bug.cgi?id=136765
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/DebugRelease.xcconfig:
+
+2015-01-27  Filip Pizlo  <fpizlo@apple.com>
+
+        ExitSiteData saying m_takesSlowPath shouldn't mean early returning takesSlowPath() since for the non-LLInt case we later set m_couldTakeSlowPath, which is more precise
+        https://bugs.webkit.org/show_bug.cgi?id=140980
+
+        Reviewed by Oliver Hunt.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+
+2015-01-27  Filip Pizlo  <fpizlo@apple.com>
+
+        Move DFGBinarySwitch out of the DFG so that all of the JITs can use it
+        https://bugs.webkit.org/show_bug.cgi?id=140959
+
+        Rubber stamped by Geoffrey Garen.
+        
+        I want to use this for polymorphic stubs for https://bugs.webkit.org/show_bug.cgi?id=140660.
+        This code no longer has DFG dependencies so this is a very clean move.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGBinarySwitch.cpp: Removed.
+        * dfg/DFGBinarySwitch.h: Removed.
+        * dfg/DFGSpeculativeJIT.cpp:
+        * jit/BinarySwitch.cpp: Copied from Source/JavaScriptCore/dfg/DFGBinarySwitch.cpp.
+        * jit/BinarySwitch.h: Copied from Source/JavaScriptCore/dfg/DFGBinarySwitch.h.
+
+2015-01-27  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179192.
+        https://bugs.webkit.org/show_bug.cgi?id=140953
+
+        Caused numerous layout test failures (Requested by mattbaker_
+        on #webkit).
+
+        Reverted changeset:
+
+        "Use FastMalloc (bmalloc) instead of BlockAllocator for GC
+        pages"
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+        http://trac.webkit.org/changeset/179192
+
+2015-01-27  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r178591): 20% regression in Octane box2d
+        https://bugs.webkit.org/show_bug.cgi?id=140948
+
+        Reviewed by Geoffrey Garen.
+
+        Added check that we have a lexical environment to the arguments is captured check.
+        It doesn't make sense to resolve "arguments" when it really isn't captured.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::willResolveToArgumentsRegister):
+
+2015-01-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+
+        Reviewed by Mark Hahnenberg.
+
+        Removes some more custom allocation code.
+
+        Looks like a speedup. (See results attached to bugzilla.)
+
+        Will hopefully reduce memory use by improving sharing between the GC and
+        malloc heaps.
+
+        * API/JSBase.cpp:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj: Feed the compiler.
+
+        * heap/BlockAllocator.cpp: Removed.
+        * heap/BlockAllocator.h: Removed. No need for a custom allocator anymore.
+
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::CodeBlockSet):
+        * heap/CodeBlockSet.h: Feed the compiler.
+
+        * heap/CopiedBlock.h:
+        (JSC::CopiedBlock::createNoZeroFill):
+        (JSC::CopiedBlock::create):
+        (JSC::CopiedBlock::CopiedBlock):
+        (JSC::CopiedBlock::isOversize):
+        (JSC::CopiedBlock::payloadEnd):
+        (JSC::CopiedBlock::capacity):
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::reportLiveBytes): Each copied block now tracks its
+        own size, since we can't rely on Region to tell us our size anymore.
+
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::~CopiedSpace):
+        (JSC::CopiedSpace::tryAllocateOversize):
+        (JSC::CopiedSpace::tryReallocateOversize):
+        * heap/CopiedSpaceInlines.h:
+        (JSC::CopiedSpace::recycleEvacuatedBlock):
+        (JSC::CopiedSpace::recycleBorrowedBlock):
+        (JSC::CopiedSpace::allocateBlockForCopyingPhase):
+        (JSC::CopiedSpace::allocateBlock):
+        (JSC::CopiedSpace::startedCopying): Deallocate blocks directly, rather
+        than pushing them onto the block allocator's free list; the block
+        allocator doesn't exist anymore.
+
+        * heap/CopyWorkList.h:
+        (JSC::CopyWorkListSegment::create):
+        (JSC::CopyWorkListSegment::CopyWorkListSegment):
+        (JSC::CopyWorkList::~CopyWorkList):
+        (JSC::CopyWorkList::append):
+        (JSC::CopyWorkList::CopyWorkList): Deleted.
+        * heap/GCSegmentedArray.h:
+        (JSC::GCArraySegment::GCArraySegment):
+        * heap/GCSegmentedArrayInlines.h:
+        (JSC::GCSegmentedArray<T>::GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::~GCSegmentedArray):
+        (JSC::GCSegmentedArray<T>::clear):
+        (JSC::GCSegmentedArray<T>::expand):
+        (JSC::GCSegmentedArray<T>::refill):
+        (JSC::GCArraySegment<T>::create):
+        * heap/GCThreadSharedData.cpp:
+        (JSC::GCThreadSharedData::GCThreadSharedData):
+        * heap/GCThreadSharedData.h: Feed the compiler.
+
+        * heap/HandleBlock.h:
+        * heap/HandleBlockInlines.h:
+        (JSC::HandleBlock::create):
+        (JSC::HandleBlock::HandleBlock):
+        (JSC::HandleBlock::payloadEnd):
+        * heap/HandleSet.cpp:
+        (JSC::HandleSet::~HandleSet):
+        (JSC::HandleSet::grow): Same as above.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        * heap/Heap.h: Removed the block allocator since it is unused now.
+
+        * heap/HeapBlock.h:
+        (JSC::HeapBlock::destroy):
+        (JSC::HeapBlock::HeapBlock):
+        (JSC::HeapBlock::region): Deleted. Removed the Region pointer from each
+        HeapBlock since a HeapBlock is just a normal allocation now.
+
+        * heap/HeapInlines.h:
+        (JSC::Heap::blockAllocator): Deleted.
+
+        * heap/HeapTimer.cpp:
+        * heap/MarkStack.cpp:
+        (JSC::MarkStackArray::MarkStackArray):
+        * heap/MarkStack.h: Feed the compiler.
+
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateBlock): No need to use a custom code path
+        based on size, since we use a general purpose allocator now.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::create):
+        (JSC::MarkedBlock::destroy):
+        (JSC::MarkedBlock::MarkedBlock):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::capacity): Track block size explicitly, like CopiedBlock.
+
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::freeBlock):
+        * heap/MarkedSpace.h:
+
+        * heap/Region.h: Removed.
+
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::SlotVisitor): Removed reference to block allocator.
+
+        * heap/SuperRegion.cpp: Removed.
+        * heap/SuperRegion.h: Removed.
+
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::create):
+        (JSC::WeakBlock::WeakBlock):
+        * heap/WeakBlock.h:
+        * heap/WeakSet.cpp:
+        (JSC::WeakSet::~WeakSet):
+        (JSC::WeakSet::addAllocator):
+        (JSC::WeakSet::removeAllocator): Removed reference to block allocator.
+
+2015-01-27  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [ARM] Typo fix after r176083
+        https://bugs.webkit.org/show_bug.cgi?id=140937
+
+        Reviewed by Anders Carlsson.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::ldrh):
+
+2015-01-27  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [Win] Unreviewed gardening, skip failing tests.
+
+        * tests/exceptionFuzz.yaml: Skip exception fuzz tests due to bug140928.
+        * tests/mozilla/mozilla-tests.yaml: Skip ecma/Date/15.9.5.28-1.js due to bug140927.
+
+2015-01-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [Win] Enable JSC stress tests by default
+        https://bugs.webkit.org/show_bug.cgi?id=128307
+
+        Unreviewed typo fix after r179165.
+
+        * tests/mozilla/mozilla-tests.yaml:
+
+2015-01-26  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [Win] Enable JSC stress tests by default
+        https://bugs.webkit.org/show_bug.cgi?id=128307
+
+        Reviewed by Brent Fulgham.
+
+        * tests/mozilla/mozilla-tests.yaml: Skipped on Windows.
+        * tests/stress/ftl-arithcos.js: Skipped on Windows.
+
+2015-01-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Parse a function expression as a primary expression
+        https://bugs.webkit.org/show_bug.cgi?id=140908
+
+        Reviewed by Mark Lam.
+
+        Moved the code to generate an AST node for a function expression from parseMemberExpression
+        to parsePrimaryExpression to match the ES6 specification terminology:
+        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-primary-expression
+
+        There should be no behavior change from this change since parsePrimaryExpression is only
+        called in parseMemberExpression other than the fact failIfStackOverflow() is called.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+
+2015-01-26  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [iOS] [SVG -> OTF Converter] Flip the switch off on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=140860
+
+        Reviewed by Darin Adler.
+
+        The fonts it makes are grotesque. (See what I did there? Typographic
+        humor is the best humor.)
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-01-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Rename InjectedScriptHost::type to subtype
+        https://bugs.webkit.org/show_bug.cgi?id=140841
+
+        Reviewed by Timothy Hatcher.
+
+        We were using this to set the subtype of an "object" type RemoteObject
+        so we should clean up the name and call it subtype.
+
+        * inspector/InjectedScriptHost.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::subtype):
+        (Inspector::JSInjectedScriptHost::type): Deleted.
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionSubtype):
+        (Inspector::jsInjectedScriptHostPrototypeFunctionType): Deleted.
+
+2015-01-23  Michael Saboff  <msaboff@apple.com>
+
+        LayoutTests/js/script-tests/reentrant-caching.js crashing on 32 bit builds
+        https://bugs.webkit.org/show_bug.cgi?id=140843
+
+        Reviewed by Oliver Hunt.
+
+        When we are in vmEntryToJavaScript, we keep the stack pointer at an
+        alignment sutiable for pointing to a call frame header, which is the
+        alignment post making a call.  We adjust the sp when calling to JS code,
+        but don't adjust it before calling the out of stack handler.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        Moved stack point down 8 bytes to get it aligned.
+
+2015-01-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Object Previews in the Console
+        https://bugs.webkit.org/show_bug.cgi?id=129204
+
+        Reviewed by Timothy Hatcher.
+
+        Update the very old, unused object preview code. Part of this comes from
+        the earlier WebKit legacy implementation, and the Blink implementation.
+
+        A RemoteObject may include a preview, if it is asked for, and if the
+        RemoteObject is an object. Previews are a shallow (single level) list
+        of a limited number of properties on the object. The previewed
+        properties are always stringified (even if primatives). Previews are
+        limited to just 5 properties or 100 indices. Previews are marked
+        as lossless if they are a complete snapshot of the object.
+
+        There is a path to make previews two levels deep, that is currently
+        unused but should soon be used for tables (e.g. IndexedDB).
+
+        * inspector/InjectedScriptSource.js:
+        - Move some code off of InjectedScript to be generic functions
+        usable by RemoteObject as well.
+        - Update preview generation to use 
+
+        * inspector/protocol/Runtime.json:
+        - Add a new type, "accessor" for preview objects. This represents
+        a getter / setter. We currently don't get the value.
+
+2015-01-23  Michael Saboff  <msaboff@apple.com>
+
+        Immediate crash when setting JS breakpoint
+        https://bugs.webkit.org/show_bug.cgi?id=140811
+
+        Reviewed by Mark Lam.
+
+        When the DFG stack layout phase doesn't allocate a register for the scope register,
+        it incorrectly sets the scope register in the code block to a bad value, one with
+        an offset of 0.  Changed it so that we set the code block's scope register to the 
+        invalid VirtualRegister instead.
+
+        No tests needed as adding the ASSERT in setScopeRegister() was used to find the bug.
+        We crash with that ASSERT in testapi and likely many other tests as well.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setScopeRegister):
+        (JSC::CodeBlock::scopeRegister):
+        Added ASSERTs to catch any future improper setting of the code block's scope register.
+
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+
+2015-01-22  Mark Hahnenberg  <mhahnenb@gmail.com>
+
+        EdenCollections unnecessarily visit SmallStrings
+        https://bugs.webkit.org/show_bug.cgi?id=140762
+
+        Reviewed by Geoffrey Garen.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::copyBackingStores): Also added a GCPhase for copying
+        backing stores, which is a significant portion of garbage collection.
+        (JSC::Heap::visitSmallStrings): Check to see if we need to visit
+        SmallStrings based on the collection type.
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::SmallStrings):
+        (JSC::SmallStrings::visitStrongReferences): Set the fact that we have
+        visited the SmallStrings since the last modification.
+        * runtime/SmallStrings.h:
+        (JSC::SmallStrings::needsToBeVisited): If we're doing a
+        FullCollection, we need to visit. Otherwise, it depends on whether
+        we've been visited since the last modification/allocation.
+
+2015-01-22  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Add a build flag for ES6 class syntax
+        https://bugs.webkit.org/show_bug.cgi?id=140760
+
+        Reviewed by Michael Saboff.
+
+        Added ES6_CLASS_SYNTAX build flag and used it in tokenizer to recognize
+        "class", "extends", "static" and "super" keywords.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * parser/Keywords.table:
+        * parser/ParserTokens.h:
+
+2015-01-22  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r178894.
+        https://bugs.webkit.org/show_bug.cgi?id=140775
+
+        Broke JSC and bindings tests (Requested by ap_ on #webkit).
+
+        Reverted changeset:
+
+        "put_by_val_direct need to check the property is index or not
+        for using putDirect / putDirectIndex"
+        https://bugs.webkit.org/show_bug.cgi?id=140426
+        http://trac.webkit.org/changeset/178894
+
+2015-01-22  Mark Lam  <mark.lam@apple.com>
+
+        BytecodeGenerator::initializeCapturedVariable() sets a misleading value for the 5th operand of op_put_to_scope.
+        <https://webkit.org/b/140743>
+
+        Reviewed by Oliver Hunt.
+
+        BytecodeGenerator::initializeCapturedVariable() was setting the 5th operand to
+        op_put_to_scope to an inappropriate value (i.e. 0).  As a result, the execution
+        of put_to_scope could store a wrong inferred value into the VariableWatchpointSet
+        for which ever captured variable is at local index 0.  In practice, this turns
+        out to be the local for the Arguments object.  In this reproduction case in the
+        bug, the wrong inferred value written there is the boolean true.
+
+        Subsequently, DFG compilation occurs and CreateArguments is emitted to first do
+        a check of the local for the Arguments object.  But because that local has a
+        wrong inferred value, the check always discovers a non-null value and we never
+        actually create the Arguments object.  Immediately after this, an OSR exit
+        occurs leaving the Arguments object local uninitialized.  Later on at arguments
+        tear off, we run into a boolean true where we had expected to find an Arguments
+        object, which in turn, leads to the crash.
+
+        The fix is to:
+        1. In the case where the resolveModeType is LocalClosureVar, change the
+           5th operand of op_put_to_scope to be a boolean.  True means that the
+           local var is watchable.  False means it is not watchable.  We no longer
+           pass the local index (instead of true) and UINT_MAX (instead of false).
+
+           This allows us to express more clearer in the code what that value means,
+           as well as remove the redundant way of getting the local's identifier.
+           The identifier is always the one passed in the 2nd operand. 
+
+        2. Previously, though intuitively, we know that the watchable variable
+           identifier should be the same as the one that is passed in operand 2, this
+           relationship was not clear in the code.  By code analysis, I confirmed that 
+           the callers of BytecodeGenerator::emitPutToScope() always use the same
+           identifier for operand 2 and for filling out the ResolveScopeInfo from
+           which we get the watchable variable identifier later.  I've changed the
+           code to make this clear now by always using the identifier passed in
+           operand 2.
+
+        3. In the case where the resolveModeType is LocalClosureVar,
+           initializeCapturedVariable() and emitPutToScope() will now query
+           hasWatchableVariable() to determine if the local is watchable or not.
+           Accordingly, we pass the boolean result of hasWatchableVariable() as
+           operand 5 of op_put_to_scope.
+
+        Also added some assertions.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::initializeCapturedVariable):
+        (JSC::BytecodeGenerator::hasConstant):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::hasWatchableVariable):
+        (JSC::BytecodeGenerator::watchableVariableIdentifier):
+        (JSC::BytecodeGenerator::watchableVariable): Deleted.
+
+2015-01-22  Ryosuke Niwa  <rniwa@webkit.org>
+
+        PropertyListNode::emitNode duplicates the code to put a constant property
+        https://bugs.webkit.org/show_bug.cgi?id=140761
+
+        Reviewed by Geoffrey Garen.
+
+        Extracted PropertyListNode::emitPutConstantProperty to share the code.
+
+        Also made PropertyListNode::emitBytecode private since nobody is calling this function directly.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitBytecode):
+        (JSC::PropertyListNode::emitPutConstantProperty): Added.
+        * parser/Nodes.h:
+
+2015-01-22  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
+        https://bugs.webkit.org/show_bug.cgi?id=140426
+
+        Reviewed by Geoffrey Garen.
+
+        In the put_by_val_direct operation, we use JSObject::putDirect.
+        However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
+        This patch changes Identifier::asIndex() to return Optional<uint32_t>.
+        It forces callers to check the value is index or not explicitly.
+        Additionally, it checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStubAndGetOldStructure):
+        * jsc.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::getOwnPropertySlot):
+        (JSC::Arguments::put):
+        (JSC::Arguments::deleteProperty):
+        (JSC::Arguments::defineOwnProperty):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSort):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::defineOwnProperty):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
+        (JSC::JSGenericTypedArrayView<Adaptor>::put):
+        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
+        (JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC::JSObject::putDirectAccessor):
+        (JSC::JSObject::putDirectCustomAccessor):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::putDirectMayBeIndex):
+        (JSC::JSObject::defineOwnProperty):
+        * runtime/JSObject.h:
+        (JSC::JSObject::getOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+        (JSC::JSObject::putDirectInternal):
+        * runtime/JSString.cpp:
+        (JSC::JSString::getStringPropertyDescriptor):
+        * runtime/JSString.h:
+        (JSC::JSString::getStringPropertySlot):
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::parse):
+        * runtime/PropertyName.h:
+        (JSC::toUInt32FromCharacters):
+        (JSC::toUInt32FromStringImpl):
+        (JSC::PropertyName::asIndex):
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::deleteProperty):
+        * runtime/Structure.cpp:
+        (JSC::Structure::prototypeChainMayInterceptStoreTo):
+
+2015-01-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Consolidate out arguments of parseFunctionInfo into a struct
+        https://bugs.webkit.org/show_bug.cgi?id=140754
+
+        Reviewed by Oliver Hunt.
+
+        Introduced ParserFunctionInfo for storing out arguments of parseFunctionInfo.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createGetterOrSetterProperty): This one takes a property name in addition to
+        ParserFunctionInfo since the property name and the function name could differ.
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        * parser/Parser.h:
+        * parser/ParserFunctionInfo.h: Added.
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionExpr):
+        (JSC::SyntaxChecker::createFuncDeclStatement):
+        (JSC::SyntaxChecker::createClassDeclStatement):
+        (JSC::SyntaxChecker::createGetterOrSetterProperty):
+
+2015-01-21  Mark Hahnenberg  <mhahnenb@gmail.com>
+
+        Change Heap::m_compiledCode to use a Vector
+        https://bugs.webkit.org/show_bug.cgi?id=140717
+
+        Reviewed by Andreas Kling.
+
+        Right now it's a DoublyLinkedList, which is iterated during each
+        collection. This contributes to some of the longish Eden pause times.
+        A Vector would be more appropriate and would also allow ExecutableBase
+        to be 2 pointers smaller.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::deleteAllCompiledCode):
+        (JSC::Heap::deleteAllUnlinkedFunctionCode):
+        (JSC::Heap::clearUnmarkedExecutables):
+        * heap/Heap.h:
+        * runtime/Executable.h: No longer need to inherit from DoublyLinkedListNode.
+
+2015-01-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        BytecodeGenerator shouldn't expose all of its member variables
+        https://bugs.webkit.org/show_bug.cgi?id=140752
+
+        Reviewed by Mark Lam.
+
+        Added "private:" and removed unused data members as detected by clang.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::lastOpcodeID): Added. Used in BinaryOpNode::emitBytecode.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BinaryOpNode::emitBytecode):
+
+2015-01-21  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ASSERT expanding objects in console PrimitiveBindingTraits<T>::assertValueHasExpectedType
+        https://bugs.webkit.org/show_bug.cgi?id=140746
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        Do not add impure properties to the descriptor object that will
+        eventually be sent to the frontend.
+
+2015-01-21  Matthew Mirman  <mmirman@apple.com>
+
+        Updated split such that it does not include the empty end of input string match.
+        https://bugs.webkit.org/show_bug.cgi?id=138129
+        <rdar://problem/18807403>
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncSplit):
+        * tests/stress/empty_eos_regex_split.js: Added.
+
+2015-01-21  Michael Saboff  <msaboff@apple.com>
+
+        Eliminate Scope slot from JavaScript CallFrame
+        https://bugs.webkit.org/show_bug.cgi?id=136724
+
+        Reviewed by Geoffrey Garen.
+
+        This finishes the removal of the scope chain slot from the call frame header.
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::emit):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
+        * interpreter/JSStack.h:
+        * interpreter/VMInspector.cpp:
+        (JSC::VMInspector::dumpFrame):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileOpCall):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTINativeCall):
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::linkClosureCall):
+        * jit/ThunkGenerators.cpp:
+        (JSC::virtualForThunkGenerator):
+        (JSC::nativeForGenerator):
+        Deleted ScopeChain slot from JSStack.  Removed all code where ScopeChain was being
+        read or set.  In most cases this was where we make JS calls.
+
+        * interpreter/CallFrameClosure.h:
+        (JSC::CallFrameClosure::setArgument):
+        (JSC::CallFrameClosure::resetCallFrame): Deleted.
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        * interpreter/ProtoCallFrame.cpp:
+        (JSC::ProtoCallFrame::init):
+        * interpreter/ProtoCallFrame.h:
+        (JSC::ProtoCallFrame::scope): Deleted.
+        (JSC::ProtoCallFrame::setScope): Deleted.
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Removed the related scopeChainValue member from ProtoCallFrame.  Reduced the number of
+        registers that needed to be copied from the ProtoCallFrame to a callee's frame
+        from 5 to 4.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        In addition to the prior changes, also deleted the unused macro getDeBruijnScope.
+
+2015-01-21  Michael Saboff  <msaboff@apple.com>
+
+        Eliminate construct methods from NullGetterFunction and NullSetterFunction classes
+        https://bugs.webkit.org/show_bug.cgi?id=140708
+
+        Reviewed by Mark Lam.
+
+        Eliminated construct methods and change getConstructData() for both classes to return
+        ConstructTypeNone as they can never be called.
+
+        * runtime/NullGetterFunction.cpp:
+        (JSC::NullGetterFunction::getConstructData):
+        (JSC::constructReturnUndefined): Deleted.
+        * runtime/NullSetterFunction.cpp:
+        (JSC::NullSetterFunction::getConstructData):
+        (JSC::constructReturnUndefined): Deleted.
+
+2015-01-21  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove ENABLE(INSPECTOR) ifdef guards
+        https://bugs.webkit.org/show_bug.cgi?id=140668
+
+        Reviewed by Darin Adler.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * bindings/ScriptValue.cpp:
+        (Deprecated::ScriptValue::toInspectorValue):
+        * bindings/ScriptValue.h:
+        * inspector/ConsoleMessage.cpp:
+        * inspector/ConsoleMessage.h:
+        * inspector/ContentSearchUtilities.cpp:
+        * inspector/ContentSearchUtilities.h:
+        * inspector/IdentifiersFactory.cpp:
+        * inspector/IdentifiersFactory.h:
+        * inspector/InjectedScript.cpp:
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.cpp:
+        * inspector/InjectedScriptBase.h:
+        * inspector/InjectedScriptHost.cpp:
+        * inspector/InjectedScriptHost.h:
+        * inspector/InjectedScriptManager.cpp:
+        * inspector/InjectedScriptManager.h:
+        * inspector/InjectedScriptModule.cpp:
+        * inspector/InjectedScriptModule.h:
+        * inspector/InspectorAgentRegistry.cpp:
+        * inspector/InspectorBackendDispatcher.cpp:
+        * inspector/InspectorBackendDispatcher.h:
+        * inspector/InspectorProtocolTypes.h:
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectScriptDebugServer.cpp:
+        * inspector/JSGlobalObjectScriptDebugServer.h:
+        * inspector/JSInjectedScriptHost.cpp:
+        * inspector/JSInjectedScriptHost.h:
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        * inspector/JSInjectedScriptHostPrototype.h:
+        * inspector/JSJavaScriptCallFrame.cpp:
+        * inspector/JSJavaScriptCallFrame.h:
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        * inspector/JSJavaScriptCallFramePrototype.h:
+        * inspector/JavaScriptCallFrame.cpp:
+        * inspector/JavaScriptCallFrame.h:
+        * inspector/ScriptCallFrame.cpp:
+        (Inspector::ScriptCallFrame::buildInspectorObject):
+        * inspector/ScriptCallFrame.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::buildInspectorArray):
+        * inspector/ScriptCallStack.h:
+        * inspector/ScriptDebugServer.cpp:
+        * inspector/agents/InspectorAgent.cpp:
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        * inspector/agents/InspectorConsoleAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/JSGlobalObjectConsoleAgent.cpp:
+        * inspector/agents/JSGlobalObjectConsoleAgent.h:
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        * inspector/agents/JSGlobalObjectDebuggerAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
+        * inspector/scripts/codegen/cpp_generator_templates.py:
+        (CppGeneratorTemplates):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::inspectorTypeSet):
+        (JSC::StructureShape::inspectorRepresentation):
+
+2015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Clean up InjectedScriptSource.js
+        https://bugs.webkit.org/show_bug.cgi?id=140709
+
+        Reviewed by Timothy Hatcher.
+
+        This patch includes some relevant Blink patches and small changes.
+        
+        Patch by <aandrey@chromium.org>
+        DevTools: Remove console last result $_ on console clear.
+        https://src.chromium.org/viewvc/blink?revision=179179&view=revision
+
+        Patch by <eustas@chromium.org>
+        [Inspect DOM properties] incorrect CSS Selector Syntax
+        https://src.chromium.org/viewvc/blink?revision=156903&view=revision
+
+        * inspector/InjectedScriptSource.js:
+
+2015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Cleanup RuntimeAgent a bit
+        https://bugs.webkit.org/show_bug.cgi?id=140706
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScript.h:
+        * inspector/InspectorBackendDispatcher.h:
+        * inspector/ScriptCallFrame.cpp:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::evaluate):
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        (Inspector::InspectorRuntimeAgent::run):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::setTypeProfilerEnabledState):
+
+2015-01-20  Matthew Mirman  <mmirman@apple.com>
+
+        Made Identity in the DFG allocate a new temp register and move 
+        the old data to it.
+        https://bugs.webkit.org/show_bug.cgi?id=140700
+        <rdar://problem/19339106>
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): 
+        Added scratch registers for Identity. 
+        * tests/mozilla/mozilla-tests.yaml: enabled previously failing test
+
+2015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Expanding event objects in console shows undefined for most values, it should have real values
+        https://bugs.webkit.org/show_bug.cgi?id=137306
+
+        Reviewed by Timothy Hatcher.
+
+        Provide another optional parameter to getProperties, to gather a list
+        of all own and getter properties.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getProperties):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+
+2015-01-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Should show dynamic specificity values
+        https://bugs.webkit.org/show_bug.cgi?id=140647
+
+        Reviewed by Benjamin Poulain.
+
+        * inspector/protocol/CSS.json:
+        Clarify CSSSelector optional values and add "dynamic" property indicating
+        if the selector can be dynamic based on the element it is matched against.
+
+2015-01-20  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r178751.
+        https://bugs.webkit.org/show_bug.cgi?id=140694
+
+        Caused 32-bit JSC test failures (Requested by JoePeck on
+        #webkit).
+
+        Reverted changeset:
+
+        "put_by_val_direct need to check the property is index or not
+        for using putDirect / putDirectIndex"
+        https://bugs.webkit.org/show_bug.cgi?id=140426
+        http://trac.webkit.org/changeset/178751
+
+2015-01-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
+        https://bugs.webkit.org/show_bug.cgi?id=140426
+
+        Reviewed by Geoffrey Garen.
+
+        In the put_by_val_direct operation, we use JSObject::putDirect.
+        However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
+        This patch changes Identifier::asIndex() to return Optional<uint32_t>.
+        It forces callers to check the value is index or not explicitly.
+        Additionally, it checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFor):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitDirectPutById):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStubAndGetOldStructure):
+        * jsc.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::getOwnPropertySlot):
+        (JSC::Arguments::put):
+        (JSC::Arguments::deleteProperty):
+        (JSC::Arguments::defineOwnProperty):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSort):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::defineOwnProperty):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
+        (JSC::JSGenericTypedArrayView<Adaptor>::put):
+        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
+        (JSC::JSGenericTypedArrayView<Adaptor>::deleteProperty):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC::JSObject::putDirectAccessor):
+        (JSC::JSObject::putDirectCustomAccessor):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::putDirectMayBeIndex):
+        (JSC::JSObject::defineOwnProperty):
+        * runtime/JSObject.h:
+        (JSC::JSObject::getOwnPropertySlot):
+        (JSC::JSObject::getPropertySlot):
+        (JSC::JSObject::putDirectInternal):
+        * runtime/JSString.cpp:
+        (JSC::JSString::getStringPropertyDescriptor):
+        * runtime/JSString.h:
+        (JSC::JSString::getStringPropertySlot):
+        * runtime/LiteralParser.cpp:
+        (JSC::LiteralParser<CharType>::parse):
+        * runtime/PropertyName.h:
+        (JSC::toUInt32FromCharacters):
+        (JSC::toUInt32FromStringImpl):
+        (JSC::PropertyName::asIndex):
+        * runtime/PropertyNameArray.cpp:
+        (JSC::PropertyNameArray::add):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::deleteProperty):
+        * runtime/Structure.cpp:
+        (JSC::Structure::prototypeChainMayInterceptStoreTo):
+
+2015-01-20  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(178696): Sporadic crashes while garbage collecting
+        https://bugs.webkit.org/show_bug.cgi?id=140688
+
+        Reviewed by Geoffrey Garen.
+
+        Added missing visitor.append(&thisObject->m_nullSetterFunction).
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::visitChildren):
+
+2015-01-19  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: code generator should take supplemental specifications and allow cross-framework references
+        https://bugs.webkit.org/show_bug.cgi?id=136312
+
+        Reviewed by Joseph Pecoraro.
+
+        Some types are shared between replay inputs from different frameworks.
+        Previously, these type declarations were duplicated in every input
+        specification file in which they were used. This caused some type encoding
+        traits to be emitted twice if used from WebCore inputs and WebKit2 inputs.
+
+        This patch teaches the replay inputs code generator to accept multiple
+        input specification files. Inputs can freely reference types from other
+        frameworks without duplicating declarations.
+
+        On the code generation side, the model could contain types and inputs from
+        frameworks that are not the target framework. Only generate code for the
+        target framework.
+
+        To properly generate cross-framework type encoding traits, use
+        Type.encoding_type_argument in more places, and add the export macro for WebCore
+        and the Test framework.
+
+        Adjust some tests so that enum coverage is preserved by moving the enum types
+        into "Test" (the target framework for tests).
+
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        For Windows, copy over JSInputs.json as if it were a private header.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Make JSInputs.json a private header.
+        * replay/JSInputs.json:
+        Put all primitive types and WTF types in this specification file.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Input.__init__):
+        (InputsModel.__init__): Keep track of the input's framework.
+        (InputsModel.parse_specification): Parse the framework here. Adjust to new format,
+        and allow either types or inputs to be missing from a single file.
+
+        (InputsModel.parse_type_with_framework):
+        (InputsModel.parse_input_with_framework):
+        (Generator.should_generate_item): Added helper method.
+        (Generator.generate_header): Filter inputs to generate.
+        (Generator.generate_implementation): Filter inputs to generate.
+        (Generator.generate_enum_trait_declaration): Filter enums to generate.
+        Add WEBCORE_EXPORT macro to enum encoding traits.
+
+        (Generator.generate_for_each_macro): Filter inputs to generate.
+        (Generator.generate_enum_trait_implementation): Filter enums to generate.
+        (generate_from_specifications): Added.
+        (generate_from_specifications.parse_json_from_file):
+        (InputsModel.parse_toplevel): Deleted.
+        (InputsModel.parse_type_with_framework_name): Deleted.
+        (InputsModel.parse_input): Deleted.
+        (generate_from_specification): Deleted.
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py:
+        * replay/scripts/tests/expected/fail-on-no-inputs.json-error: Removed.
+        * replay/scripts/tests/expected/fail-on-no-types.json-error: Removed.
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.cpp:
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.h:
+        * replay/scripts/tests/fail-on-c-style-enum-no-storage.json:
+        * replay/scripts/tests/fail-on-duplicate-enum-type.json:
+        * replay/scripts/tests/fail-on-duplicate-input-names.json:
+        * replay/scripts/tests/fail-on-duplicate-type-names.json:
+        * replay/scripts/tests/fail-on-enum-type-missing-values.json:
+        * replay/scripts/tests/fail-on-missing-input-member-name.json:
+        * replay/scripts/tests/fail-on-missing-input-name.json:
+        * replay/scripts/tests/fail-on-missing-input-queue.json:
+        * replay/scripts/tests/fail-on-missing-type-mode.json:
+        * replay/scripts/tests/fail-on-missing-type-name.json:
+        * replay/scripts/tests/fail-on-no-inputs.json:
+        Removed, no longer required to be in a single file.
+
+        * replay/scripts/tests/fail-on-no-types.json:
+        Removed, no longer required to be in a single file.
+
+        * replay/scripts/tests/fail-on-unknown-input-queue.json:
+        * replay/scripts/tests/fail-on-unknown-member-type.json:
+        * replay/scripts/tests/fail-on-unknown-type-mode.json:
+        * replay/scripts/tests/generate-enum-encoding-helpers-with-guarded-values.json:
+        * replay/scripts/tests/generate-enum-encoding-helpers.json:
+        * replay/scripts/tests/generate-enum-with-guard.json:
+        Include enums that are and are not generated.
+
+        * replay/scripts/tests/generate-enums-with-same-base-name.json:
+        * replay/scripts/tests/generate-event-loop-shape-types.json:
+        * replay/scripts/tests/generate-input-with-guard.json:
+        * replay/scripts/tests/generate-input-with-vector-members.json:
+        * replay/scripts/tests/generate-inputs-with-flags.json:
+        * replay/scripts/tests/generate-memoized-type-modes.json:
+
+2015-01-20  Tomas Popela  <tpopela@redhat.com>
+
+        [GTK] Cannot compile 2.7.3 on PowerPC machines
+        https://bugs.webkit.org/show_bug.cgi?id=140616
+
+        Include climits for INT_MAX and wtf/DataLog.h for dataLogF
+
+        Reviewed by Csaba Osztrogonác.
+
+        * runtime/BasicBlockLocation.cpp:
+
+2015-01-19  Michael Saboff  <msaboff@apple.com>
+
+        A "cached" null setter should throw a TypeException when called in strict mode and doesn't
+        https://bugs.webkit.org/show_bug.cgi?id=139418
+
+        Reviewed by Filip Pizlo.
+
+        Made a new NullSetterFunction class similar to NullGetterFunction.  The difference is that 
+        NullSetterFunction will throw a TypeError per the ECMA262 spec for a strict mode caller.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added new files NullSetterFunction.cpp and NullSetterFunction.h.
+
+        * runtime/GetterSetter.h:
+        (JSC::GetterSetter::GetterSetter):
+        (JSC::GetterSetter::isSetterNull):
+        (JSC::GetterSetter::setSetter):
+        Change setter instances from using NullGetterFunction to using NullSetterFunction.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::nullSetterFunction):
+        Added m_nullSetterFunction and accessor.
+
+        * runtime/NullSetterFunction.cpp: Added.
+        (JSC::GetCallerStrictnessFunctor::GetCallerStrictnessFunctor):
+        (JSC::GetCallerStrictnessFunctor::operator()):
+        (JSC::GetCallerStrictnessFunctor::callerIsStrict):
+        (JSC::callerIsStrict):
+        Method to determine if the caller is in strict mode.
+
+        (JSC::callReturnUndefined):
+        (JSC::constructReturnUndefined):
+        (JSC::NullSetterFunction::getCallData):
+        (JSC::NullSetterFunction::getConstructData):
+        * runtime/NullSetterFunction.h: Added.
+        (JSC::NullSetterFunction::create):
+        (JSC::NullSetterFunction::createStructure):
+        (JSC::NullSetterFunction::NullSetterFunction):
+        Class with handlers for a null setter.
+
+2015-01-19  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: Provide a front end for JSC's Control Flow Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=138454
+
+        Reviewed by Timothy Hatcher.
+
+        This patch puts the final touches on what JSC needs to provide
+        for the Web Inspector to show a UI for the control flow profiler.
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::getBasicBlocksForSourceID):
+        * runtime/FunctionHasExecutedCache.cpp:
+        (JSC::FunctionHasExecutedCache::getFunctionRanges):
+        (JSC::FunctionHasExecutedCache::getUnexecutedFunctionRanges): Deleted.
+        * runtime/FunctionHasExecutedCache.h:
+
+2015-01-19  David Kilzer  <ddkilzer@apple.com>
+
+        [iOS] Only use LLVM static library arguments on 64-bit builds of libllvmForJSC.dylib
+        <http://webkit.org/b/140658>
+
+        Reviewed by Filip Pizlo.
+
+        * Configurations/LLVMForJSC.xcconfig: Set OTHER_LDFLAGS_LLVM
+        only when building for 64-bit architectures.
+
+2015-01-19  Filip Pizlo  <fpizlo@apple.com>
+
+        ClosureCallStubRoutine no longer needs codeOrigin
+        https://bugs.webkit.org/show_bug.cgi?id=140659
+
+        Reviewed by Michael Saboff.
+        
+        Once upon a time, we would look for the CodeOrigin associated with a return PC. This search
+        would start with the CodeBlock according to the caller frame's call frame header. But if the
+        call was a closure call, the return PC would be inside some closure call stub. So if the
+        CodeBlock search failed, we would search *all* closure call stub routines to see which one
+        encompasses the return PC. Then, we would use the CodeOrigin stored in the stub routine
+        object. This was all a bunch of madness, and we actually got rid of it - we now determine
+        the CodeOrigin for a call frame using the encoded code origin bits inside the tag of the
+        argument count.
+        
+        This patch removes the final vestiges of the madness:
+        
+        - Remove the totally unused method declaration for the thing that did the closure call stub
+          search.
+        
+        - Remove the CodeOrigin field from the ClosureCallStubRoutine. Except for that crazy search
+          that we no longer do, everyone else who finds a ClosureCallStubRoutine will find it via
+          the CallLinkInfo. The CallLinkInfo also has the CodeOrigin, so we don't need this field
+          anymore.
+
+        * bytecode/CodeBlock.h:
+        * jit/ClosureCallStubRoutine.cpp:
+        (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
+        * jit/ClosureCallStubRoutine.h:
+        (JSC::ClosureCallStubRoutine::executable):
+        (JSC::ClosureCallStubRoutine::codeOrigin): Deleted.
+        * jit/Repatch.cpp:
+        (JSC::linkClosureCall):
+
+2015-01-19  Saam Barati  <saambarati1@gmail.com>
+
+        Basic block start offsets should never be larger than end offsets in the control flow profiler
+        https://bugs.webkit.org/show_bug.cgi?id=140377
+
+        Reviewed by Filip Pizlo.
+
+        The bytecode generator will emit code more than once for some AST nodes. For instance, 
+        the finally block of TryNode will emit two code paths for its finally block: one for 
+        the normal path, and another for the path where an exception is thrown in the catch block. 
+        
+        This repeated code emission of the same AST node previously broke how the control 
+        flow profiler computed text ranges of basic blocks because when the same AST node 
+        is emitted multiple times, there is a good chance that there are ranges that span 
+        from the end offset of one of these duplicated nodes back to the start offset of 
+        the same duplicated node. This caused a basic block range to report a larger start 
+        offset than end offset. This was incorrect. Now, when this situation is encountered 
+        while linking a CodeBlock, the faulty range in question is ignored.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
+        * bytecode/CodeBlock.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::TryNode::emitBytecode):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseConditionalExpression):
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::ControlFlowProfiler):
+        * runtime/ControlFlowProfiler.h:
+        (JSC::ControlFlowProfiler::dummyBasicBlock):
+
+2015-01-19  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [SVG -> OTF Converter] Flip the switch on
+        https://bugs.webkit.org/show_bug.cgi?id=140592
+
+        Reviewed by Antti Koivisto.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-01-19  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: convert to is<T> and downcast<T> for decoding replay inputs
+        https://bugs.webkit.org/show_bug.cgi?id=140512
+
+        Reviewed by Chris Dumez.
+
+        Generate a SPECIALIZE_TYPE_TRAITS_* chunk of code for each input. This cannot
+        be done using REPLAY_INPUT_NAMES_FOR_EACH macro since that doesn't fully qualify
+        input types, and the type traits macro is defined in namespace WTF.
+
+        * replay/NondeterministicInput.h: Make overridden methods public.
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Generator.generate_header):
+        (Generator.qualified_input_name): Allow forcing qualification. WTF is never a target framework.
+        (Generator.generate_input_type_trait_declaration): Added.
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py: Add a template.
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.h:
+
+2015-01-19  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r178653.
+        https://bugs.webkit.org/show_bug.cgi?id=140634
+
+        Broke multiple SVG tests on Mountain Lion (Requested by ap on
+        #webkit).
+
+        Reverted changeset:
+
+        "[SVG -> OTF Converter] Flip the switch on"
+        https://bugs.webkit.org/show_bug.cgi?id=140592
+        http://trac.webkit.org/changeset/178653
+
+2015-01-18  Dean Jackson  <dino@apple.com>
+
+        ES6: Support Array.of construction
+        https://bugs.webkit.org/show_bug.cgi?id=140605
+        <rdar://problem/19513655>
+
+        Reviewed by Geoffrey Garen.
+
+        Add and implementation of Array.of, described in 22.1.2.3 of the ES6
+        specification (15 Jan 2015). The Array.of() method creates a new Array
+        instance with a variable number of arguments, regardless of number or type
+        of the arguments.
+
+        * runtime/ArrayConstructor.cpp:
+        (JSC::arrayConstructorOf): Create a new empty Array, then iterate
+        over the arguments, setting them to the appropriate index.
+
+2015-01-19  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [SVG -> OTF Converter] Flip the switch on
+        https://bugs.webkit.org/show_bug.cgi?id=140592
+
+        Reviewed by Antti Koivisto.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-01-17  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: highlight data for overlay should use protocol type builders
+        https://bugs.webkit.org/show_bug.cgi?id=129441
+
+        Reviewed by Timothy Hatcher.
+
+        Add a new domain for overlay types.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * inspector/protocol/OverlayTypes.json: Added.
+
+2015-01-17  Michael Saboff  <msaboff@apple.com>
+
+        Crash in JSScope::resolve() on tools.ups.com
+        https://bugs.webkit.org/show_bug.cgi?id=140579
+
+        Reviewed by Geoffrey Garen.
+
+        For op_resolve_scope of a global property or variable that needs to check for the var
+        injection check watchpoint, we need to keep the scope around with a Phantom.  The
+        baseline JIT slowpath for op_resolve_scope needs the scope value if the watchpoint
+        fired.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+
+2015-01-16  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: code generator should introduce typedefs for protocol types that are arrays
+        https://bugs.webkit.org/show_bug.cgi?id=140557
+
+        Reviewed by Joseph Pecoraro.
+
+        Currently, there is no generated type name for "array" type declarations such as Console.CallStack.
+        This makes it longwinded and confusing to use the type in C++ code.
+
+        This patch adds a typedef for array type declarations, so types such as Console::CallStack
+        can be referred to directly, rather than using Inspector::Protocol::Array<Console::CallFrame>.
+
+        Some tests were updated to cover array type declarations used as parameters and type members.
+
+        * inspector/ScriptCallStack.cpp: Use the new typedef.
+        (Inspector::ScriptCallStack::buildInspectorArray):
+        * inspector/ScriptCallStack.h:
+        * inspector/scripts/codegen/cpp_generator.py:
+        (CppGenerator.cpp_protocol_type_for_type): If an ArrayType is nominal, use the typedef'd name instead.
+        * inspector/scripts/codegen/generate_cpp_protocol_types_header.py:
+        (_generate_typedefs_for_domain): Also generate typedefs for array type declarations.
+        (_generate_typedefs_for_domain.Inspector):
+        * inspector/scripts/codegen/models.py: Save the name of an ArrayType when it is a type declaration.
+        (ArrayType.__init__):
+        (Protocol.resolve_types):
+        (Protocol.lookup_type_reference):
+        * inspector/scripts/tests/commands-with-async-attribute.json:
+        * inspector/scripts/tests/commands-with-optional-call-return-parameters.json:
+        * inspector/scripts/tests/events-with-optional-parameters.json:
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * inspector/scripts/tests/type-declaration-object-type.json:
+
+2015-01-16  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: purge remaining PassRefPtr uses and minor cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=140456
+
+        Reviewed by Andreas Kling.
+
+        Get rid of PassRefPtr. Introduce default initializers where it makes sense.
+        Remove mistaken uses of AtomicString that were not removed as part of r174113.
+
+        * replay/EmptyInputCursor.h:
+        * replay/InputCursor.h:
+        (JSC::InputCursor::InputCursor):
+
+2015-01-16  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: code generator should fail on duplicate parameter and member names
+        https://bugs.webkit.org/show_bug.cgi?id=140555
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/scripts/codegen/models.py:
+        (find_duplicates): Add a helper function to find duplicates in a list.
+        (Protocol.parse_type_declaration):
+        (Protocol.parse_command):
+        (Protocol.parse_event):
+        * inspector/scripts/tests/expected/fail-on-duplicate-command-call-parameter-names.json-error: Added.
+        * inspector/scripts/tests/expected/fail-on-duplicate-command-return-parameter-names.json-error: Added.
+        * inspector/scripts/tests/expected/fail-on-duplicate-event-parameter-names.json-error: Added.
+        * inspector/scripts/tests/expected/fail-on-duplicate-type-member-names.json-error: Added.
+        * inspector/scripts/tests/fail-on-duplicate-command-call-parameter-names.json: Added.
+        * inspector/scripts/tests/fail-on-duplicate-command-return-parameter-names.json: Added.
+        * inspector/scripts/tests/fail-on-duplicate-event-parameter-names.json: Added.
+        * inspector/scripts/tests/fail-on-duplicate-type-member-names.json: Added.
+
+2015-01-16  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (r174226): Header on huffingtonpost.com is too large
+        https://bugs.webkit.org/show_bug.cgi?id=140306
+
+        Reviewed by Filip Pizlo.
+
+        BytecodeGenerator::willResolveToArguments() is used to check to see if we can use the
+        arguments register or whether we need to resolve "arguments".  If the arguments have
+        been captured, then they are stored in the lexical environment and the arguments
+        register is not used.
+
+        Changed BytecodeGenerator::willResolveToArguments() to also check to see if the arguments
+        register is captured.  Renamed the function to willResolveToArgumentsRegister() to
+        better indicate what we are checking.
+
+        Aligned 32 and 64 bit paths in ArgumentsRecoveryGenerator::generateFor() for creating
+        an arguments object that was optimized out of an inlined callFrame.  The 32 bit path
+        incorrectly calculated the location of the reified callee frame.  This alignment resulted
+        in the removal of operationCreateInlinedArgumentsDuringOSRExit()
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::willResolveToArgumentsRegister):
+        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::willResolveToArguments): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::getArgumentByVal):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor):
+        * dfg/DFGOperations.cpp:
+        (JSC::operationCreateInlinedArgumentsDuringOSRExit): Deleted.
+        * dfg/DFGOperations.h:
+        (JSC::operationCreateInlinedArgumentsDuringOSRExit): Deleted.
+
+2015-01-15  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove ENABLE(SQL_DATABASE) guards
+        https://bugs.webkit.org/show_bug.cgi?id=140434
+
+        Reviewed by Darin Adler.
+
+        * CMakeLists.txt:
+        * Configurations/FeatureDefines.xcconfig:
+        * DerivedSources.make:
+        * inspector/protocol/Database.json:
+
+2015-01-14  Alexey Proskuryakov  <ap@apple.com>
+
+        Web Inspector and regular console use different source code locations for messages
+        https://bugs.webkit.org/show_bug.cgi?id=140478
+
+        Reviewed by Brian Burg.
+
+        * inspector/ConsoleMessage.h: Expose computed source location.
+
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::addMessageToConsole):
+        (Inspector::InspectorConsoleAgent::stopTiming):
+        (Inspector::InspectorConsoleAgent::count):
+        * inspector/agents/InspectorConsoleAgent.h:
+        addMessageToConsole() now takes a pre-made ConsoleMessage object.
+
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        (Inspector::JSGlobalObjectConsoleClient::messageWithTypeAndLevel):
+        (Inspector::JSGlobalObjectConsoleClient::warnUnimplemented):
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::reportAPIException):
+        * inspector/agents/JSGlobalObjectDebuggerAgent.cpp:
+        (Inspector::JSGlobalObjectDebuggerAgent::breakpointActionLog):
+        Updated for the above changes.
+
+2015-01-15  Mark Lam  <mark.lam@apple.com>
+
+        [Part 2] Argument object created by "Function dot arguments" should use a clone of argument values.
+        <https://webkit.org/b/140093>
+
+        Reviewed by Geoffrey Garen.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        - We should not fetching the lexicalEnvironment here.  The reason we've
+          introduced the ClonedArgumentsCreationMode is because the lexicalEnvironment
+          may not be available to us at this point.  Instead, we'll just pass a nullptr.
+
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::tearOffForCloning):
+        * runtime/Arguments.h:
+        (JSC::Arguments::finishCreation):
+        - Use the new tearOffForCloning() to tear off arguments right out of the values
+          passed on the stack.  tearOff() is not appropriate for this purpose because
+          it takes slowArgumentsData into account.
+
+2015-01-14  Matthew Mirman  <mmirman@apple.com>
+
+        Removed accidental commit of "invalid_array.js" 
+        http://trac.webkit.org/changeset/178439
+
+        * tests/stress/invalid_array.js: Removed.
+
+2015-01-14  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes operationPutByIdOptimizes such that they check that the put didn't
+        change the structure of the object who's property access is being
+        cached.  Also removes uses of the new base value from the cache generation code.
+        https://bugs.webkit.org/show_bug.cgi?id=139500
+
+        Reviewed by Filip Pizlo.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationPutByIdStrictOptimize): saved the structure before the put.
+        (JSC::operationPutByIdNonStrictOptimize): ditto.
+        (JSC::operationPutByIdDirectStrictOptimize): ditto.
+        (JSC::operationPutByIdDirectNonStrictOptimize): ditto.
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+        (JSC::emitPutReplaceStub):
+        (JSC::emitPutTransitionStubAndGetOldStructure): Added.
+        (JSC::tryCachePutByID):
+        (JSC::repatchPutByID):
+        (JSC::tryBuildPutByIdList):
+        (JSC::tryRepatchIn):
+        (JSC::emitPutTransitionStub): Deleted.
+        * jit/Repatch.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/JSPropertyNameEnumerator.h:
+        (JSC::genericPropertyNameEnumerator):
+        * runtime/Operations.h:
+        (JSC::normalizePrototypeChainForChainAccess): restructured to not use the base value.
+        (JSC::normalizePrototypeChain): restructured to not use the base value.
+        * tests/mozilla/mozilla-tests.yaml:
+        * tests/stress/proto-setter.js: Added.
+        * tests/stress/put-by-id-build-list-order-recurse.js: Added.
+        Added test that fails without this patch.
+
+2015-01-13  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Remove unused ResizeImage and DecodeImageData timeline events
+        https://bugs.webkit.org/show_bug.cgi?id=140404
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/Timeline.json:
+
+2015-01-13  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        DFG can call PutByValDirect for generic arrays
+        https://bugs.webkit.org/show_bug.cgi?id=140389
+
+        Reviewed by Geoffrey Garen.
+
+        Computed properties in object initializers (ES6) use the put_by_val_direct operation.
+        However, current DFG asserts that put_by_val_direct is not used for the generic array,
+        the assertion failure is raised.
+        This patch allow DFG to use put_by_val_direct to generic arrays.
+
+        And fix the DFG put_by_val_direct implementation for string properties.
+        At first, put_by_val_direct is inteded to be used for spread elements.
+        So the property keys were limited to numbers (indexes).
+        But now, it's also used for computed properties in object initializers.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2015-01-13  Geoffrey Garen  <ggaren@apple.com>
+
+        Out of bounds access in BytecodeGenerator::emitGetById under DotAccessorNode::emitBytecode
+        https://bugs.webkit.org/show_bug.cgi?id=140397
+
+        Reviewed by Geoffrey Garen.
+
+        Patch by Alexey Proskuryakov.
+
+        Reviewed, performance tested, and ChangeLogged by Geoffrey Garen.
+
+        No performance change.
+
+        No test, since this is a small past-the-end read, which is very
+        difficult to turn into a reproducible failing test -- and existing tests
+        crash reliably using ASan.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::DeleteBracketNode::emitBytecode):
+        (JSC::DeleteDotNode::emitBytecode):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::UnaryOpNode::emitBytecode):
+        (JSC::BitwiseNotNode::emitBytecode):
+        (JSC::BinaryOpNode::emitBytecode):
+        (JSC::EqualNode::emitBytecode):
+        (JSC::StrictEqualNode::emitBytecode):
+        (JSC::ThrowableBinaryOpNode::emitBytecode):
+        (JSC::AssignDotNode::emitBytecode):
+        (JSC::AssignBracketNode::emitBytecode): Use RefPtr in more places. Any
+        register used across a call to a function that might allocate a new
+        temporary register must be held in a RefPtr.
+
+2015-01-12  Michael Saboff  <msaboff@apple.com>
+
+        Local JSArray* "keys" in objectConstructorKeys() is not marked during garbage collection
+        https://bugs.webkit.org/show_bug.cgi?id=140348
+
+        Reviewed by Mark Lam.
+
+        We used to read registers in MachineThreads::gatherFromCurrentThread(), but that is too late
+        because those registers may have been spilled on the stack and replaced with other values by
+        the time we call down to gatherFromCurrentThread().
+
+        Now we get the register contents at the same place that we demarcate the current top of
+        stack using the address of a local variable, in Heap::markRoots().  The register contents
+        buffer is passed along with the demarcation pointer.  These need to be done at this level 
+        in the call tree and no lower, as markRoots() calls various functions that visit object
+        pointers that may be latter proven dead.  Any of those pointers that are left on the
+        stack or in registers could be incorrectly marked as live if we scan the stack contents
+        from a called function or one of its callees.  The stack demarcation pointer and register
+        saving need to be done in the same function so that we have a consistent stack, active
+        and spilled registers.
+
+        Because we don't want to make unnecessary calls to get the register contents, we use
+        a macro to allocated, and possibly align, the register structure and get the actual
+        register contents.
+
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::gatherStackRoots):
+        * heap/Heap.h:
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::gatherFromCurrentThread):
+        (JSC::MachineThreads::gatherConservativeRoots):
+        * heap/MachineStackMarker.h:
+
+2015-01-12  Benjamin Poulain  <benjamin@webkit.org>
+
+        Add basic pattern matching support to the url filters
+        https://bugs.webkit.org/show_bug.cgi?id=140283
+
+        Reviewed by Andreas Kling.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Make YarrParser.h private in order to use it from WebCore.
+
+2015-01-12  Geoffrey Garen  <ggaren@apple.com>
+
+        Out of bounds read in IdentifierArena::makeIdentifier
+        https://bugs.webkit.org/show_bug.cgi?id=140376
+
+        Patch by Alexey Proskuryakov.
+
+        Reviewed and ChangeLogged by Geoffrey Garen.
+
+        No test, since this is a small past-the-end read, which is very
+        difficult to turn into a reproducible failing test -- and existing tests
+        crash reliably using ASan.
+
+        * parser/ParserArena.h:
+        (JSC::IdentifierArena::makeIdentifier):
+        (JSC::IdentifierArena::makeIdentifierLCharFromUChar): Check for a
+        zero-length string input, like we do in the literal parser, since it is
+        not valid to dereference characters in a zero-length string.
+
+        A zero-length string is allowed in JavaScript -- for example, "".
+
+2015-01-11  Sam Weinig  <sam@webkit.org>
+
+        Remove support for SharedWorkers
+        https://bugs.webkit.org/show_bug.cgi?id=140344
+
+        Reviewed by Anders Carlsson.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-01-12  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Allow targetting the SVG->OTF font converter with ENABLE(SVG_OTF_CONVERTER)
+        https://bugs.webkit.org/show_bug.cgi?id=136769
+
+        Reviewed by Antti Koivisto.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2015-01-12  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r178266.
+        https://bugs.webkit.org/show_bug.cgi?id=140363
+
+        Broke a JSC test (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "Local JSArray* "keys" in objectConstructorKeys() is not
+        marked during garbage collection"
+        https://bugs.webkit.org/show_bug.cgi?id=140348
+        http://trac.webkit.org/changeset/178266
+
+2015-01-12  Michael Saboff  <msaboff@apple.com>
+
+        Local JSArray* "keys" in objectConstructorKeys() is not marked during garbage collection
+        https://bugs.webkit.org/show_bug.cgi?id=140348
+
+        Reviewed by Mark Lam.
+
+        Move the address of the local variable that is used to demarcate the top of the stack for 
+        conservative roots down to MachineThreads::gatherFromCurrentThread() since it also gets
+        the register values using setjmp().  That way we don't lose any callee save register
+        contents between Heap::markRoots(), where it was set, and gatherFromCurrentThread().
+        If we lose any JSObject* that are only in callee save registers, they will be GC'ed
+        erroneously.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::gatherStackRoots):
+        * heap/Heap.h:
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::gatherFromCurrentThread):
+        (JSC::MachineThreads::gatherConservativeRoots):
+        * heap/MachineStackMarker.h:
+
+2015-01-11  Eric Carlson  <eric.carlson@apple.com>
+
+        Fix typo in testate.c error messages
+        https://bugs.webkit.org/show_bug.cgi?id=140305
+
+        Reviewed by Geoffrey Garen.
+
+        * API/tests/testapi.c:
+        (main): "... script did not timed out ..." -> "... script did not time out ..."
+
+2015-01-09  Michael Saboff  <msaboff@apple.com>
+
+        Breakpoint doesn't fire in this HTML5 game
+        https://bugs.webkit.org/show_bug.cgi?id=140269
+
+        Reviewed by Mark Lam.
+
+        When parsing a single line cached function, use the lineStartOffset of the
+        location where we found the cached function instead of the cached lineStartOffset.
+        The cache location's lineStartOffset has not been adjusted for any possible
+        containing functions.
+
+        This change is not needed for multi-line cached functions.  Consider the
+        single line source:
+
+        function outer(){function inner1(){doStuff();}; (function inner2() {doMoreStuff()})()}
+
+        The first parser pass, we parse and cache inner1() and inner2() with a lineStartOffset
+        of 0.  Later when we parse outer() and find inner1() in the cache, SourceCode start
+        character is at outer()'s outermost open brace.  That is what we should use for
+        lineStartOffset for inner1().  When done parsing inner1() we set the parsing token
+        to the saved location for inner1(), including the lineStartOffset of 0.  We need
+        to use the value of lineStartOffset before we started parsing inner1().  That is
+        what the fix does.  When we parse inner2() the lineStartOffset will be correct.
+
+        For a multi-line function, the close brace is guaranteed to be on a different line
+        than the open brace.  Hence, its lineStartOffset will not change with the change of
+        the SourceCode start character
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+
+2015-01-09  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Uncaught Exception in ProbeManager deleting breakpoint
+        https://bugs.webkit.org/show_bug.cgi?id=140279
+        rdar://problem/19422299
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/MapData.cpp:
+        (JSC::MapData::replaceAndPackBackingStore):
+        The cell table also needs to have its values fixed.
+
+2015-01-09  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Remove or use TimelineAgent Resource related event types
+        https://bugs.webkit.org/show_bug.cgi?id=140155
+
+        Reviewed by Timothy Hatcher.
+
+        Remove unused / stale Timeline event types.
+
+        * inspector/protocol/Timeline.json:
+
+2015-01-09  Csaba Osztrogonác  <ossy@webkit.org>
+
+        REGRESSION(r177925): It broke the !ENABLE(INSPECTOR) build
+        https://bugs.webkit.org/show_bug.cgi?id=140098
+
+        Reviewed by Brian Burg.
+
+        * inspector/InspectorBackendDispatcher.h: Missing ENABLE(INSPECTOR) guard added.
+
+2015-01-08  Mark Lam  <mark.lam@apple.com>
+
+        Argument object created by "Function dot arguments" should use a clone of the argument values.
+        <https://webkit.org/b/140093>
+
+        Reviewed by Geoffrey Garen.
+
+        After the change in <https://webkit.org/b/139827>, the dfg-tear-off-arguments-not-activation.js
+        test will crash.  The relevant code which manifests the issue is as follows:
+
+            function bar() {
+                return foo.arguments;
+            }
+
+            function foo(p) {
+                var x = 42;
+                if (p)
+                    return (function() { return x; });
+                else
+                    return bar();
+            }
+
+        In this case, foo() has no knowledge of bar() needing its LexicalEnvironment and
+        has dead code eliminated the SetLocal that stores it into its designated local.
+        In bar(), the factory for the Arguments object (for creating foo.arguments) tries
+        to read foo's LexicalEnvironment from its designated lexicalEnvironment local,
+        but instead, finds it to be uninitialized.  This results in a null pointer access
+        which causes a crash.
+
+        This can be resolved by having bar() instantiate a clone of the Arguments object
+        instead, and populate its elements with values fetched directly from foo's frame.
+        There's no need to reference foo's LexicalEnvironment (whether present or not).
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        * runtime/Arguments.h:
+        (JSC::Arguments::finishCreation):
+
+2015-01-08  Mark Lam  <mark.lam@apple.com>
+
+        Make the LLINT and Baseline JIT's op_create_arguments and op_get_argument_by_val use their lexicalEnvironment operand.
+        <https://webkit.org/b/140236>
+
+        Reviewed by Geoffrey Garen.
+
+        Will change the DFG to use the operand on a subsequent pass.  For now,
+        the DFG uses a temporary thunk (operationCreateArgumentsForDFG()) to
+        retain the old behavior of getting the lexicalEnviroment from the
+        ExecState.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitGetArgumentByVal):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+        - When the lexicalEnvironment is not available, pass the invalid VirtualRegister
+          instead of an empty JSValue as the lexicalEnvironment operand.
+
+        * dfg/DFGOperations.cpp:
+        - Use the lexicalEnvironment from the ExecState for now.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        - Use the operationCreateArgumentsForDFG() thunk for now.
+
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::lexicalEnvironmentOrNullptr):
+        * interpreter/CallFrame.h:
+        - Added this convenience function to return either the
+          lexicalEnvironment or a nullptr so that we don't need to do a
+          conditional check on codeBlock->needsActivation() at multiple sites.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_arguments):
+        (JSC::JIT::emitSlow_op_get_argument_by_val):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_arguments):
+        (JSC::JIT::emitSlow_op_get_argument_by_val):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.h:
+        (JSC::Arguments::create):
+        (JSC::Arguments::finishCreation):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::argumentsGetter):
+
+2015-01-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Pause Reason Improvements (Breakpoint, Debugger Statement, Pause on Next Statement)
+        https://bugs.webkit.org/show_bug.cgi?id=138991
+
+        Reviewed by Timothy Hatcher.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::Debugger):
+        (JSC::Debugger::pauseIfNeeded):
+        (JSC::Debugger::didReachBreakpoint):
+        When actually pausing, if we hit a breakpoint ensure the reason
+        is PausedForBreakpoint, otherwise use the current reason.
+
+        * debugger/Debugger.h:
+        Make pause reason and pausing breakpoint ID public.
+
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::buildAssertPauseReason):
+        (Inspector::buildCSPViolationPauseReason):
+        (Inspector::InspectorDebuggerAgent::buildBreakpointPauseReason):
+        (Inspector::InspectorDebuggerAgent::buildExceptionPauseReason):
+        (Inspector::InspectorDebuggerAgent::handleConsoleAssert):
+        (Inspector::buildObjectForBreakpointCookie):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::InspectorDebuggerAgent::removeBreakpoint):
+        (Inspector::InspectorDebuggerAgent::resolveBreakpoint):
+        (Inspector::InspectorDebuggerAgent::pause):
+        (Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
+        (Inspector::InspectorDebuggerAgent::currentCallFrames):
+        (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
+        Clean up creation of pause reason objects and other cleanup
+        of PassRefPtr use and InjectedScript use.
+
+        (Inspector::InspectorDebuggerAgent::didPause):
+        Clean up so that we first check for an Exception, and then fall
+        back to including a Pause Reason derived from the Debugger.
+
+        * inspector/protocol/Debugger.json:
+        Add new DebuggerStatement, Breakpoint, and PauseOnNextStatement reasons.
+
+2015-01-08  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Type check NSArray's in ObjC Interfaces have the right object types
+        https://bugs.webkit.org/show_bug.cgi?id=140209
+
+        Reviewed by Timothy Hatcher.
+
+        Check the types of objects in NSArrays for all interfaces (commands, events, types)
+        when the user can set an array of objects. Previously we were only type checking
+        they were RWIJSONObjects, now we add an explicit check for the exact object type.
+
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
+        (ObjCConfigurationImplementationGenerator._generate_success_block_for_command):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event):
+        * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py:
+        (ObjCProtocolTypesImplementationGenerator._generate_init_method_for_required_members):
+        (ObjCProtocolTypesImplementationGenerator._generate_setter_for_member):
+        * inspector/scripts/codegen/objc_generator.py:
+        (ObjCGenerator.objc_class_for_array_type):
+        (ObjCGenerator):
+
+2015-01-07  Mark Lam  <mark.lam@apple.com>
+
+        Add the lexicalEnvironment as an operand to op_get_argument_by_val.
+        <https://webkit.org/b/140233>
+
+        Reviewed by Filip Pizlo.
+
+        This patch only adds the operand to the bytecode.  It is not in use yet.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetArgumentByVal):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2015-01-07  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Investigate the character type of repeated string instead of checking is8Bit flag
+        https://bugs.webkit.org/show_bug.cgi?id=140139
+
+        Reviewed by Darin Adler.
+
+        Instead of checking is8Bit flag of the repeated string, investigate
+        the actual value of the repeated character since i8Bit flag give a false negative case.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::repeatCharacter):
+        (JSC::stringProtoFuncRepeat):
+        (JSC::repeatSmallString): Deleted.
+
+2015-01-07  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ObjC Generate types from the GenericTypes domain
+        https://bugs.webkit.org/show_bug.cgi?id=140229
+
+        Reviewed by Timothy Hatcher.
+
+        Generate types from the GenericTypes domain, as they are expected
+        by other domains (like Page domain). Also, don't include the @protocol
+        forward declaration for a domain if it doesn't have any commands.
+
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py:
+        (ObjCBackendDispatcherHeaderGenerator._generate_objc_forward_declarations):
+        (ObjCBackendDispatcherHeaderGenerator): Deleted.
+        (ObjCBackendDispatcherHeaderGenerator._generate_objc_forward_declarations_for_domains): Deleted.
+        * inspector/scripts/codegen/objc_generator.py:
+        (ObjCGenerator):
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
+2015-01-07  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Remove unnecessary copyRef for paramsObject in generated dispatchers
+        https://bugs.webkit.org/show_bug.cgi?id=140228
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py:
+        (CppFrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event_out_parameters):
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+
+2015-01-07  Saam Barati  <saambarati1@gmail.com>
+
+        interpret op_profile_type in the LLInt instead of unconditionally calling into the slow path
+        https://bugs.webkit.org/show_bug.cgi?id=140165
+
+        Reviewed by Michael Saboff.
+
+        Inlining the functionality of TypeProfilerLog::recordTypeInformationForLocation
+        into the LLInt speeds up type profiling.
+
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/TypeProfilerLog.h:
+        (JSC::TypeProfilerLog::recordTypeInformationForLocation): Deleted.
+
+2015-01-07  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: purge PassRefPtr from Inspector code and use Ref for typed and untyped protocol objects
+        https://bugs.webkit.org/show_bug.cgi?id=140053
+
+        Reviewed by Andreas Kling.
+
+        This patch replaces uses of PassRefPtr with uses of RefPtr&& and WTF::move() in code
+        related to Web Inspector. It also converts many uses of RefPtr to Ref where
+        references are always non-null. These two refactorings have been combined since
+        they tend to require similar changes to the code.
+
+        Creation methods for subclasses of InspectorValue now return a Ref, and callsites
+        have been updated to take a Ref instead of RefPtr.
+
+        Builders for typed protocol objects now return a Ref. Since there is no implicit
+        call to operator&, callsites now must explicitly call .release() to convert a
+        builder object into the corresponding protocol object once required fields are set.
+        Update callsites and use auto to eliminate repetition of longwinded protocol types.
+
+        Tests for inspector protocol and replay inputs have been rebaselined.
+
+        * bindings/ScriptValue.cpp:
+        (Deprecated::jsToInspectorValue):
+        (Deprecated::ScriptValue::toInspectorValue):
+        * bindings/ScriptValue.h:
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::addToFrontend):
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::buildObjectForSearchMatch):
+        (Inspector::ContentSearchUtilities::searchInTextByLines):
+        * inspector/ContentSearchUtilities.h:
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        (Inspector::InjectedScript::wrapCallFrames):
+        (Inspector::InjectedScript::wrapObject):
+        (Inspector::InjectedScript::wrapTable):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall): Split the early exits.
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::InspectorBackendDispatcher::CallbackBase::CallbackBase):
+        (Inspector::InspectorBackendDispatcher::CallbackBase::sendIfActive):
+        (Inspector::InspectorBackendDispatcher::create):
+        (Inspector::InspectorBackendDispatcher::dispatch):
+        (Inspector::InspectorBackendDispatcher::sendResponse):
+        (Inspector::InspectorBackendDispatcher::reportProtocolError):
+        (Inspector::getPropertyValue): Add a comment to clarify what this clever code does.
+        (Inspector::InspectorBackendDispatcher::getInteger):
+        (Inspector::InspectorBackendDispatcher::getDouble):
+        (Inspector::InspectorBackendDispatcher::getString):
+        (Inspector::InspectorBackendDispatcher::getBoolean):
+        (Inspector::InspectorBackendDispatcher::getObject):
+        (Inspector::InspectorBackendDispatcher::getArray):
+        (Inspector::InspectorBackendDispatcher::getValue):
+        * inspector/InspectorBackendDispatcher.h: Use a typed protocol object to collect
+        protocol error strings.
+        (Inspector::InspectorSupplementalBackendDispatcher::InspectorSupplementalBackendDispatcher):
+        Convert the supplemental dispatcher's reference to Ref since it is never null.
+        * inspector/InspectorEnvironment.h:
+        * inspector/InspectorProtocolTypes.h: Get rid of ArrayItemHelper and
+        StructItemTraits. Add more versions of addItem to handle pushing various types.
+        (Inspector::Protocol::Array::openAccessors):
+        (Inspector::Protocol::Array::addItem):
+        (Inspector::Protocol::Array::create):
+        (Inspector::Protocol::StructItemTraits::push):
+        (Inspector::Protocol::BindingTraits<Protocol::Array<T>>::runtimeCast): Assert argument.
+        (Inspector::Protocol::StructItemTraits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<String>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<int>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<double>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<bool>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorValue>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorObject>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorArray>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<Protocol::Array<T>>::Traits::pushRefPtr): Deleted.
+        * inspector/InspectorValues.cpp: Straighten out getArray and getObject to have
+        the same call signature as other getters. Use Ref where possible.
+        (Inspector::InspectorObjectBase::getBoolean):
+        (Inspector::InspectorObjectBase::getString):
+        (Inspector::InspectorObjectBase::getObject):
+        (Inspector::InspectorObjectBase::getArray):
+        (Inspector::InspectorObjectBase::getValue):
+        (Inspector::InspectorObjectBase::writeJSON):
+        (Inspector::InspectorArrayBase::get):
+        (Inspector::InspectorObject::create):
+        (Inspector::InspectorArray::create):
+        (Inspector::InspectorValue::null):
+        (Inspector::InspectorString::create):
+        (Inspector::InspectorBasicValue::create):
+        (Inspector::InspectorObjectBase::get): Deleted.
+        * inspector/InspectorValues.h:
+        (Inspector::InspectorObjectBase::setValue):
+        (Inspector::InspectorObjectBase::setObject):
+        (Inspector::InspectorObjectBase::setArray):
+        (Inspector::InspectorArrayBase::pushValue):
+        (Inspector::InspectorArrayBase::pushObject):
+        (Inspector::InspectorArrayBase::pushArray):
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        (Inspector::JSGlobalObjectConsoleClient::messageWithTypeAndLevel):
+        (Inspector::JSGlobalObjectConsoleClient::count):
+        (Inspector::JSGlobalObjectConsoleClient::timeEnd):
+        (Inspector::JSGlobalObjectConsoleClient::timeStamp):
+        * inspector/JSGlobalObjectConsoleClient.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::executionStopwatch):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptCallFrame.cpp:
+        (Inspector::ScriptCallFrame::buildInspectorObject):
+        * inspector/ScriptCallFrame.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::create):
+        (Inspector::ScriptCallStack::buildInspectorArray):
+        * inspector/ScriptCallStack.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::enable):
+        (Inspector::InspectorAgent::inspect):
+        (Inspector::InspectorAgent::activateExtraDomain):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::handleConsoleAssert):
+        (Inspector::buildObjectForBreakpointCookie):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::continueToLocation):
+        (Inspector::InspectorDebuggerAgent::resolveBreakpoint):
+        (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+        (Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
+        (Inspector::InspectorDebuggerAgent::currentCallFrames):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        (Inspector::InspectorDebuggerAgent::breakProgram):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::buildErrorRangeObject):
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::InspectorRuntimeAgent::getBasicBlocks):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/scripts/codegen/cpp_generator.py:
+        (CppGenerator.cpp_type_for_unchecked_formal_in_parameter):
+        (CppGenerator.cpp_type_for_type_with_name):
+        (CppGenerator.cpp_type_for_formal_async_parameter):
+        (CppGenerator.should_use_references_for_type):
+        (CppGenerator):
+        * inspector/scripts/codegen/cpp_generator_templates.py:
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
+        (CppBackendDispatcherHeaderGenerator.generate_output):
+        (CppBackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator._generate_small_dispatcher_switch_implementation_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py:
+        (CppFrontendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py:
+        (CppFrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_cpp_protocol_types_header.py:
+        (CppProtocolTypesHeaderGenerator.generate_output):
+        (_generate_class_for_object_declaration):
+        (_generate_unchecked_setter_for_member):
+        (_generate_forward_declarations_for_binding_traits):
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
+        (ObjCConfigurationImplementationGenerator._generate_success_block_for_command):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event):
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event_out_parameters):
+        * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py:
+        (ObjCProtocolTypesImplementationGenerator.generate_output):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::asObject):
+        (JSC::EncodedValue::asArray):
+        (JSC::EncodedValue::put<EncodedValue>):
+        (JSC::EncodedValue::append<EncodedValue>):
+        (JSC::EncodedValue::get<EncodedValue>):
+        * replay/EncodedValue.h:
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.borrow_type):
+        (Type.argument_type):
+        (Generator.generate_member_move_expression):
+        * runtime/ConsoleClient.cpp:
+        (JSC::ConsoleClient::printConsoleMessageWithArguments):
+        (JSC::ConsoleClient::internalMessageWithTypeAndLevel):
+        (JSC::ConsoleClient::logWithLevel):
+        (JSC::ConsoleClient::clear):
+        (JSC::ConsoleClient::dir):
+        (JSC::ConsoleClient::dirXML):
+        (JSC::ConsoleClient::table):
+        (JSC::ConsoleClient::trace):
+        (JSC::ConsoleClient::assertCondition):
+        (JSC::ConsoleClient::group):
+        (JSC::ConsoleClient::groupCollapsed):
+        (JSC::ConsoleClient::groupEnd):
+        * runtime/ConsoleClient.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::TypeSet::inspectorTypeSet):
+        (JSC::StructureShape::inspectorRepresentation):
+        * runtime/TypeSet.h:
+
+2015-01-07  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r178039.
+        https://bugs.webkit.org/show_bug.cgi?id=140187
+
+        Breaks ObjC Inspector Protocol (Requested by JoePeck on
+        #webkit).
+
+        Reverted changeset:
+
+        "Web Inspector: purge PassRefPtr from Inspector code and use
+        Ref for typed and untyped protocol objects"
+        https://bugs.webkit.org/show_bug.cgi?id=140053
+        http://trac.webkit.org/changeset/178039
+
+2015-01-06  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: purge PassRefPtr from Inspector code and use Ref for typed and untyped protocol objects
+        https://bugs.webkit.org/show_bug.cgi?id=140053
+
+        Reviewed by Andreas Kling.
+
+        This patch replaces uses of PassRefPtr with uses of RefPtr&& and WTF::move() in code
+        related to Web Inspector. It also converts many uses of RefPtr to Ref where
+        references are always non-null. These two refactorings have been combined since
+        they tend to require similar changes to the code.
+
+        Creation methods for subclasses of InspectorValue now return a Ref, and callsites
+        have been updated to take a Ref instead of RefPtr.
+
+        Builders for typed protocol objects now return a Ref. Since there is no implicit
+        call to operator&, callsites now must explicitly call .release() to convert a
+        builder object into the corresponding protocol object once required fields are set.
+        Update callsites and use auto to eliminate repetition of longwinded protocol types.
+
+        Tests for inspector protocol and replay inputs have been rebaselined.
+
+        * bindings/ScriptValue.cpp:
+        (Deprecated::jsToInspectorValue):
+        (Deprecated::ScriptValue::toInspectorValue):
+        * bindings/ScriptValue.h:
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::ConsoleMessage::addToFrontend):
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::buildObjectForSearchMatch):
+        (Inspector::ContentSearchUtilities::searchInTextByLines):
+        * inspector/ContentSearchUtilities.h:
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getFunctionDetails):
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getInternalProperties):
+        (Inspector::InjectedScript::wrapCallFrames):
+        (Inspector::InjectedScript::wrapObject):
+        (Inspector::InjectedScript::wrapTable):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.cpp:
+        (Inspector::InjectedScriptBase::makeEvalCall): Split the early exits.
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::InspectorBackendDispatcher::CallbackBase::CallbackBase):
+        (Inspector::InspectorBackendDispatcher::CallbackBase::sendIfActive):
+        (Inspector::InspectorBackendDispatcher::create):
+        (Inspector::InspectorBackendDispatcher::dispatch):
+        (Inspector::InspectorBackendDispatcher::sendResponse):
+        (Inspector::InspectorBackendDispatcher::reportProtocolError):
+        (Inspector::getPropertyValue): Add a comment to clarify what this clever code does.
+        (Inspector::InspectorBackendDispatcher::getInteger):
+        (Inspector::InspectorBackendDispatcher::getDouble):
+        (Inspector::InspectorBackendDispatcher::getString):
+        (Inspector::InspectorBackendDispatcher::getBoolean):
+        (Inspector::InspectorBackendDispatcher::getObject):
+        (Inspector::InspectorBackendDispatcher::getArray):
+        (Inspector::InspectorBackendDispatcher::getValue):
+        * inspector/InspectorBackendDispatcher.h: Use a typed protocol object to collect
+        protocol error strings.
+        (Inspector::InspectorSupplementalBackendDispatcher::InspectorSupplementalBackendDispatcher):
+        Convert the supplemental dispatcher's reference to Ref since it is never null.
+        * inspector/InspectorEnvironment.h:
+        * inspector/InspectorProtocolTypes.h: Get rid of ArrayItemHelper and
+        StructItemTraits. Add more versions of addItem to handle pushing various types.
+        (Inspector::Protocol::Array::openAccessors):
+        (Inspector::Protocol::Array::addItem):
+        (Inspector::Protocol::Array::create):
+        (Inspector::Protocol::StructItemTraits::push):
+        (Inspector::Protocol::BindingTraits<Protocol::Array<T>>::runtimeCast): Assert argument.
+        (Inspector::Protocol::StructItemTraits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<String>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<int>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<double>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<bool>::Traits::pushRaw): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorValue>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorObject>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<InspectorArray>::Traits::pushRefPtr): Deleted.
+        (Inspector::Protocol::ArrayItemHelper<Protocol::Array<T>>::Traits::pushRefPtr): Deleted.
+        * inspector/InspectorValues.cpp: Straighten out getArray and getObject to have
+        the same call signature as other getters. Use Ref where possible.
+        (Inspector::InspectorObjectBase::getBoolean):
+        (Inspector::InspectorObjectBase::getString):
+        (Inspector::InspectorObjectBase::getObject):
+        (Inspector::InspectorObjectBase::getArray):
+        (Inspector::InspectorObjectBase::getValue):
+        (Inspector::InspectorObjectBase::writeJSON):
+        (Inspector::InspectorArrayBase::get):
+        (Inspector::InspectorObject::create):
+        (Inspector::InspectorArray::create):
+        (Inspector::InspectorValue::null):
+        (Inspector::InspectorString::create):
+        (Inspector::InspectorBasicValue::create):
+        (Inspector::InspectorObjectBase::get): Deleted.
+        * inspector/InspectorValues.h:
+        (Inspector::InspectorObjectBase::setValue):
+        (Inspector::InspectorObjectBase::setObject):
+        (Inspector::InspectorObjectBase::setArray):
+        (Inspector::InspectorArrayBase::pushValue):
+        (Inspector::InspectorArrayBase::pushObject):
+        (Inspector::InspectorArrayBase::pushArray):
+        * inspector/JSGlobalObjectConsoleClient.cpp:
+        (Inspector::JSGlobalObjectConsoleClient::messageWithTypeAndLevel):
+        (Inspector::JSGlobalObjectConsoleClient::count):
+        (Inspector::JSGlobalObjectConsoleClient::timeEnd):
+        (Inspector::JSGlobalObjectConsoleClient::timeStamp):
+        * inspector/JSGlobalObjectConsoleClient.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::executionStopwatch):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptCallFrame.cpp:
+        (Inspector::ScriptCallFrame::buildInspectorObject):
+        * inspector/ScriptCallFrame.h:
+        * inspector/ScriptCallStack.cpp:
+        (Inspector::ScriptCallStack::create):
+        (Inspector::ScriptCallStack::buildInspectorArray):
+        * inspector/ScriptCallStack.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::enable):
+        (Inspector::InspectorAgent::inspect):
+        (Inspector::InspectorAgent::activateExtraDomain):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::handleConsoleAssert):
+        (Inspector::buildObjectForBreakpointCookie):
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+        (Inspector::InspectorDebuggerAgent::setBreakpoint):
+        (Inspector::InspectorDebuggerAgent::continueToLocation):
+        (Inspector::InspectorDebuggerAgent::resolveBreakpoint):
+        (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+        (Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
+        (Inspector::InspectorDebuggerAgent::currentCallFrames):
+        (Inspector::InspectorDebuggerAgent::didParseSource):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        (Inspector::InspectorDebuggerAgent::breakProgram):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::buildErrorRangeObject):
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::InspectorRuntimeAgent::getBasicBlocks):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/scripts/codegen/cpp_generator.py:
+        (CppGenerator.cpp_type_for_unchecked_formal_in_parameter):
+        (CppGenerator.cpp_type_for_type_with_name):
+        (CppGenerator.cpp_type_for_formal_async_parameter):
+        (CppGenerator.should_use_references_for_type):
+        (CppGenerator):
+        * inspector/scripts/codegen/cpp_generator_templates.py:
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py:
+        (CppBackendDispatcherHeaderGenerator.generate_output):
+        (CppBackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py:
+        (CppBackendDispatcherImplementationGenerator._generate_small_dispatcher_switch_implementation_for_domain):
+        (CppBackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py:
+        (CppFrontendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py:
+        (CppFrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        * inspector/scripts/codegen/generate_cpp_protocol_types_header.py:
+        (CppProtocolTypesHeaderGenerator.generate_output):
+        (_generate_class_for_object_declaration):
+        (_generate_unchecked_setter_for_member):
+        (_generate_forward_declarations_for_binding_traits):
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
+        (ObjCConfigurationImplementationGenerator._generate_success_block_for_command):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event):
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event_out_parameters):
+        * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py:
+        (ObjCProtocolTypesImplementationGenerator.generate_output):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        * replay/EncodedValue.cpp:
+        (JSC::EncodedValue::asObject):
+        (JSC::EncodedValue::asArray):
+        (JSC::EncodedValue::put<EncodedValue>):
+        (JSC::EncodedValue::append<EncodedValue>):
+        (JSC::EncodedValue::get<EncodedValue>):
+        * replay/EncodedValue.h:
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (Type.borrow_type):
+        (Type.argument_type):
+        (Generator.generate_member_move_expression):
+        * runtime/ConsoleClient.cpp:
+        (JSC::ConsoleClient::printConsoleMessageWithArguments):
+        (JSC::ConsoleClient::internalMessageWithTypeAndLevel):
+        (JSC::ConsoleClient::logWithLevel):
+        (JSC::ConsoleClient::clear):
+        (JSC::ConsoleClient::dir):
+        (JSC::ConsoleClient::dirXML):
+        (JSC::ConsoleClient::table):
+        (JSC::ConsoleClient::trace):
+        (JSC::ConsoleClient::assertCondition):
+        (JSC::ConsoleClient::group):
+        (JSC::ConsoleClient::groupCollapsed):
+        (JSC::ConsoleClient::groupEnd):
+        * runtime/ConsoleClient.h:
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::TypeSet::inspectorTypeSet):
+        (JSC::StructureShape::inspectorRepresentation):
+        * runtime/TypeSet.h:
+
+2015-01-06  Chris Dumez  <cdumez@apple.com>
+
+        Drop ResourceResponseBase::connectionID and connectionReused members
+        https://bugs.webkit.org/show_bug.cgi?id=140158
+
+        Reviewed by Sam Weinig.
+
+        Drop ResourceResponseBase::connectionID and connectionReused members.
+        Those were needed by the Chromium port but are no longer used.
+
+        * inspector/protocol/Network.json:
+
+2015-01-06  Mark Lam  <mark.lam@apple.com>
+
+        Add the lexicalEnvironment as an operand to op_create_arguments.
+        <https://webkit.org/b/140148>
+
+        Reviewed by Geoffrey Garen.
+
+        This patch only adds the operand to the bytecode.  It is not in use yet.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+        - Adds the lexicalEnvironment register (if present) as an operand to
+          op_create_arguments.  Else, adds a constant empty JSValue.
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2015-01-06  Alexey Proskuryakov  <ap@apple.com>
+
+        ADDRESS_SANITIZER macro is overloaded
+        https://bugs.webkit.org/show_bug.cgi?id=140130
+
+        Reviewed by Anders Carlsson.
+
+        * interpreter/JSStack.cpp: (JSC::JSStack::sanitizeStack): Use the new macro.
+        This code is nearly unused (only compiled in when JIT is disabled at build time),
+        however I've been told that it's best to keep it.
+
+2015-01-06  Mark Lam  <mark.lam@apple.com>
+
+        Fix Use details for op_create_arguments.
+        <https://webkit.org/b/140110>
+
+        Rubber stamped by Filip Pizlo.
+
+        The previous patch was wrong about op_create_arguments not using its 1st operand.
+        It does read from it (hence, used) to check if the Arguments object has already
+        been created or not.  This patch reverts the change for op_create_arguments.
+
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+
+2015-01-06  Mark Lam  <mark.lam@apple.com>
+
+        Fix Use details for op_create_lexical_environment and op_create_arguments.
+        <https://webkit.org/b/140110>
+
+        Reviewed by Filip Pizlo.
+
+        The current "Use" details for op_create_lexical_environment and
+        op_create_arguments are wrong.  op_create_argument uses nothing instead of the
+        1st operand (the output local).  op_create_lexical_environment uses its 2nd
+        operand (the scope chain) instead of the 1st (the output local).
+        This patch fixes them to specify the proper uses.
+
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+
+2015-01-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement ES6 String.prototype.repeat(count)
+        https://bugs.webkit.org/show_bug.cgi?id=140047
+
+        Reviewed by Darin Adler.
+
+        Introducing ES6 String.prototype.repeat(count) function.
+
+        * runtime/JSString.h:
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        (JSC::repeatSmallString):
+        (JSC::stringProtoFuncRepeat):
+
+2015-01-03  Michael Saboff  <msaboff@apple.com>
+
+        Crash in operationNewFunction when scrolling on Google+
+        https://bugs.webkit.org/show_bug.cgi?id=140033
+
+        Reviewed by Oliver Hunt.
+
+        In DFG code, the scope register can be eliminated because all uses have been
+        dead code eliminated.  In the case where one of the uses was creating a function
+        that is never used, the baseline code will still create the function.  If we OSR
+        exit to a path where that function gets created, check the scope register value
+        and set the new, but dead, function to undefined instead of creating a new function.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_new_func_exp):
+
+2015-01-01  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        String includes methods perform toString on searchString before toInt32 on a offset
+        https://bugs.webkit.org/show_bug.cgi?id=140031
+
+        Reviewed by Darin Adler.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncStartsWith):
+        (JSC::stringProtoFuncEndsWith):
+        (JSC::stringProtoFuncIncludes):
+
+2015-01-01  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Change to return std::unique_ptr<> in fooCreate()
+        https://bugs.webkit.org/show_bug.cgi?id=139983
+
+        Reviewed by Darin Adler.
+
+        To avoid unnecessary std::unique_ptr<> casting, fooCreate() returns std::unique_ptr<> directly.
+
+        * create_regex_tables:
+        * yarr/YarrPattern.h:
+        (JSC::Yarr::YarrPattern::reset):
+        (JSC::Yarr::YarrPattern::newlineCharacterClass):
+        (JSC::Yarr::YarrPattern::digitsCharacterClass):
+        (JSC::Yarr::YarrPattern::spacesCharacterClass):
+        (JSC::Yarr::YarrPattern::wordcharCharacterClass):
+        (JSC::Yarr::YarrPattern::nondigitsCharacterClass):
+        (JSC::Yarr::YarrPattern::nonspacesCharacterClass):
+        (JSC::Yarr::YarrPattern::nonwordcharCharacterClass):
+
+2015-01-01  Jeff Miller  <jeffm@apple.com>
+
+        Update user-visible copyright strings to include 2015
+        https://bugs.webkit.org/show_bug.cgi?id=139880
+
+        Reviewed by Darin Adler.
+
+        * Info.plist:
+
+2015-01-01  Darin Adler  <darin@apple.com>
+
+        We often misspell identifier as "identifer"
+        https://bugs.webkit.org/show_bug.cgi?id=140025
+
+        Reviewed by Michael Saboff.
+
+        * runtime/ArrayConventions.h: Fix it.
+
+2014-12-29  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Move JavaScriptCore/yarr to std::unique_ptr
+        https://bugs.webkit.org/show_bug.cgi?id=139621
+
+        Reviewed by Anders Carlsson.
+
+        Final clean up OwnPtr|PassOwnPtr in JavaScriptCore/yarr.
+
+        * yarr/YarrInterpreter.cpp:
+        (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternEnd):
+        * yarr/YarrInterpreter.h:
+        (JSC::Yarr::BytecodePattern::BytecodePattern):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern):
+        (JSC::Yarr::YarrGenerator::opCompileParentheticalAssertion):
+        (JSC::Yarr::YarrGenerator::opCompileBody):
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::CharacterClassConstructor::charClass):
+        (JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
+        (JSC::Yarr::YarrPatternConstructor::reset):
+        (JSC::Yarr::YarrPatternConstructor::atomPatternCharacter):
+        (JSC::Yarr::YarrPatternConstructor::atomCharacterClassEnd):
+        (JSC::Yarr::YarrPatternConstructor::atomParenthesesSubpatternBegin):
+        (JSC::Yarr::YarrPatternConstructor::atomParentheticalAssertionBegin):
+        (JSC::Yarr::YarrPatternConstructor::copyDisjunction):
+        (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses):
+        (JSC::Yarr::YarrPatternConstructor::optimizeDotStarWrappedExpressions):
+        * yarr/YarrPattern.h:
+        (JSC::Yarr::PatternDisjunction::addNewAlternative):
+        (JSC::Yarr::YarrPattern::newlineCharacterClass):
+        (JSC::Yarr::YarrPattern::digitsCharacterClass):
+        (JSC::Yarr::YarrPattern::spacesCharacterClass):
+        (JSC::Yarr::YarrPattern::wordcharCharacterClass):
+        (JSC::Yarr::YarrPattern::nondigitsCharacterClass):
+        (JSC::Yarr::YarrPattern::nonspacesCharacterClass):
+        (JSC::Yarr::YarrPattern::nonwordcharCharacterClass):
+
+2014-12-26  Dan Bernstein  <mitz@apple.com>
+
+        <rdar://problem/19348208> REGRESSION (r177027): iOS builds use the wrong toolchain
+        https://bugs.webkit.org/show_bug.cgi?id=139950
+
+        Reviewed by David Kilzer.
+
+        * Configurations/Base.xcconfig: Only define TOOLCHAINS when building for OS X, doing so
+        in a manner that works with Xcode 5.1.1.
+
+2014-12-22  Mark Lam  <mark.lam@apple.com>
+
+        Use ctiPatchCallByReturnAddress() in JITOperations.cpp.
+        <https://webkit.org/b/139892>
+
+        Reviewed by Michael Saboff.
+
+        The code in JITOperations.cpp sometimes calls RepatchBuffer::relinkCallerToFunction()
+        directly, and sometimes uses a helper function, ctiPatchCallByReturnAddress().
+        This patch changes it to use the helper function consistently.
+
+        * jit/JITOperations.cpp:
+
+2014-12-22  Mark Lam  <mark.lam@apple.com>
+
+        Fix some typos in a comment.
+        <https://webkit.org/b/139882>
+
+        Reviewed by Michael Saboff.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_val):
+
+2014-12-22  Mark Lam  <mark.lam@apple.com>
+
+        Assert that Array elements not copied when changing shape to ArrayStorage type are indeed holes.
+        <https://webkit.org/b/138118>
+
+        Reviewed by Michael Saboff.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertInt32ToArrayStorage):
+        (JSC::JSObject::convertDoubleToArrayStorage):
+        (JSC::JSObject::convertContiguousToArrayStorage):
+
+2014-12-20  Eric Carlson  <eric.carlson@apple.com>
+
+        [iOS] add optimized fullscreen API
+        https://bugs.webkit.org/show_bug.cgi?id=139833
+        <rdar://problem/18844486>
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig: Add ENABLE_VIDEO_PRESENTATION_MODE.
+
+2014-12-20  David Kilzer  <ddkilzer@apple.com>
+
+        Switch from using PLATFORM_NAME to SDK selectors in WebCore, WebInspectorUI, WebKit, WebKit2
+        <http://webkit.org/b/139463>
+
+        Reviewed by Mark Rowe.
+
+        * Configurations/JavaScriptCore.xcconfig:
+        - Simplify SECTORDER_FLAGS.
+
+2014-12-19  Andreas Kling  <akling@apple.com>
+
+        Plug leak below LLVMCopyStringRepOfTargetData().
+        <https://webkit.org/b/139832>
+
+        Reviewed by Michael Saboff.
+
+        LLVMCopyStringRepOfTargetData() returns a strdup()'ed string, so make sure
+        to free() it after we're done using it.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+
+2014-12-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: CRASH inspector-protocol/debugger/breakpoint-action-detach.html
+        https://bugs.webkit.org/show_bug.cgi?id=139797
+
+        Reviewed by Mark Lam.
+
+        * debugger/Debugger.h:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::isAttached):
+        Check if we are the debugger for a particular global object.
+        (JSC::Debugger::pauseIfNeeded):
+        Pass the global object on when hitting a brekapoint.
+
+        * inspector/ScriptDebugServer.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handleBreakpointHit):
+        Stop evaluting breakpoint actions if a previous action caused the
+        debugger to detach from this global object.
+        (Inspector::ScriptDebugServer::handlePause):
+        Standardize on passing JSGlobalObject parameter first.
+
+2014-12-19  Mark Lam  <mark.lam@apple.com>
+
+        [Win] Endless compiler warnings created by DFGEdge.h.
+        <https://webkit.org/b/139801>
+
+        Reviewed by Brent Fulgham.
+
+        Add a cast to fix the type just the way the 64-bit version does.
+
+        * dfg/DFGEdge.h:
+        (JSC::DFG::Edge::makeWord):
+
+2014-12-19  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r177574.
+        https://bugs.webkit.org/show_bug.cgi?id=139821
+
+        "Broke Production builds by installing
+        libWebCoreTestSupport.dylib in the wrong directory" (Requested
+        by ddkilzer on #webkit).
+
+        Reverted changeset:
+
+        "Switch from using PLATFORM_NAME to SDK selectors in WebCore,
+        WebInspectorUI, WebKit, WebKit2"
+        https://bugs.webkit.org/show_bug.cgi?id=139463
+        http://trac.webkit.org/changeset/177574
+
+2014-12-19  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(174226): Captured arguments in a using function compiled by the DFG have the initial value when the closure was invoked
+        https://bugs.webkit.org/show_bug.cgi?id=139808
+
+        Reviewed by Oliver Hunt.
+
+        There are three changes here.
+        1) Create a VariableWatchpointSet for captured arguments variables.
+        2) Properly use the VariableWatchpointSet* found in op_put_to_scope in the 64 bit LLInt code.
+        3) Add the same putLocalClosureVar path to the 32 bit LLInt code that exists in the 64 bit version.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-12-19  David Kilzer  <ddkilzer@apple.com>
+
+        Switch from using PLATFORM_NAME to SDK selectors in WebCore, WebInspectorUI, WebKit, WebKit2
+        <http://webkit.org/b/139463>
+
+        Reviewed by Mark Rowe.
+
+        * Configurations/JavaScriptCore.xcconfig:
+        - Simplify SECTORDER_FLAGS.
+
+2014-12-18  Brent Fulgham  <bfulgham@apple.com>
+
+        Unreviewed build fix.
+
+        * jsc.cpp: Remove typo.
+
+2014-12-17  Michael Saboff  <msaboff@apple.com>
+
+        Tests with infinite recursion frequently crash
+        https://bugs.webkit.org/show_bug.cgi?id=139548
+
+        Reviewed by Geoffrey Garen.
+
+        While unwinding, if the call frame doesn't have a codeblock, then we
+        are in native code, handle appropriately.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        (JSC::UnwindFunctor::operator()):
+        Added checks for null CodeBlock.
+
+        (JSC::Interpreter::unwind): Removed wrong ASSERT.
+
+2014-12-17  Chris Dumez  <cdumez@apple.com>
+
+        [iOS] Make it possible to toggle FeatureCounter support at runtime
+        https://bugs.webkit.org/show_bug.cgi?id=139688
+        <rdar://problem/19266254>
+
+        Reviewed by Andreas Kling.
+
+        Stop linking against AppSupport framework as the functionality is no
+        longer in WTF (it was moved to WebCore).
+
+        * Configurations/JavaScriptCore.xcconfig:
+
+2014-12-17  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Correct DebugSuffix builds under MSBuild
+        https://bugs.webkit.org/show_bug.cgi?id=139733
+        <rdar://problem/19276880>
+
+        Reviewed by Simon Fraser.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.proj: Make sure to use the
+        '_debug' suffix when building the DebugSuffix target.
+
+2014-12-16  Enrica Casucci  <enrica@apple.com>
+
+        Fix iOS builders for 8.0
+        https://bugs.webkit.org/show_bug.cgi?id=139495
+
+        Reviewed by Michael Saboff.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-12-16  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r177380.
+        https://bugs.webkit.org/show_bug.cgi?id=139707
+
+        "Breaks js/regres/elidable-new-object-* tests" (Requested by
+        msaboff_ on #webkit).
+
+        Reverted changeset:
+
+        "Fixes operationPutByIdOptimizes such that they check that the
+        put didn't"
+        https://bugs.webkit.org/show_bug.cgi?id=139500
+        http://trac.webkit.org/changeset/177380
+
+2014-12-16  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes operationPutByIdOptimizes such that they check that the put didn't
+        change the structure of the object who's property access is being
+        cached.
+        https://bugs.webkit.org/show_bug.cgi?id=139500
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationPutByIdStrictOptimize): saved the structure before the put.
+        (JSC::operationPutByIdNonStrictOptimize): ditto.
+        (JSC::operationPutByIdDirectStrictOptimize): ditto.
+        (JSC::operationPutByIdDirectNonStrictOptimize): ditto.
+        * jit/Repatch.cpp:
+        (JSC::tryCachePutByID): Added argument for the old structure
+        (JSC::repatchPutByID): Added argument for the old structure
+        * jit/Repatch.h:
+        * tests/stress/put-by-id-build-list-order-recurse.js: 
+        Added test that fails without this patch.
+
+2014-12-15  Chris Dumez  <cdumez@apple.com>
+
+        [iOS] Add feature counting support
+        https://bugs.webkit.org/show_bug.cgi?id=139652
+        <rdar://problem/19255690>
+
+        Reviewed by Gavin Barraclough.
+
+        Link against AppSupport framework on iOS as we need it to implement
+        the new FeatureCounter API in WTF.
+
+        * Configurations/JavaScriptCore.xcconfig:
+
+2014-12-15  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r177284.
+        https://bugs.webkit.org/show_bug.cgi?id=139658
+
+        "Breaks API tests and LayoutTests on Yosemite Debug"
+        (Requested by msaboff on #webkit).
+
+        Reverted changeset:
+
+        "Make sure range based iteration of Vector<> still receives
+        bounds checking"
+        https://bugs.webkit.org/show_bug.cgi?id=138821
+        http://trac.webkit.org/changeset/177284
+
+2014-12-15  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        [EFL] FTL JIT not working on ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=139295
+
+        Reviewed by Michael Saboff.
+
+        Added the missing code for stack unwinding and some additional small fixes
+        to get FTL working correctly.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLUnwindInfo.cpp:
+        (JSC::FTL::UnwindInfo::parse):
+
+2014-12-15  Oliver Hunt  <oliver@apple.com>
+
+        Make sure range based iteration of Vector<> still receives bounds checking
+        https://bugs.webkit.org/show_bug.cgi?id=138821
+
+        Reviewed by Mark Lam.
+
+        Update code to deal with slightly changed iterator semantics.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::visitChildren):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitComplexPopScopes):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::mdNode):
+        (JSC::FTL::buildCall):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLengthWithArrayStorage):
+        (JSC::JSArray::sortCompactedVector):
+        * tools/ProfileTreeNode.h:
+        (JSC::ProfileTreeNode::dumpInternal):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::matchCharacterClass):
+
+2014-12-14  Filip Pizlo  <fpizlo@apple.com>
+
+        PutLocalSinkingPhase has an invalid assertion about incoming values, because both liveness and deferral analyses are conservative
+        https://bugs.webkit.org/show_bug.cgi?id=139630
+
+        Reviewed by Oliver Hunt.
+        
+        Replaces a faulty assertion with code to handle an awesome special case. Also adds a lot of
+        comments that reconstruct my reasoning about this code. I had to work hard to remember how
+        deferral worked so I wrote my discoveries down.
+
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertBottomConstantForUse):
+        * dfg/DFGPutLocalSinkingPhase.cpp:
+        * tests/stress/put-local-conservative.js: Added.
+        (foo):
+        (.result):
+        (bar):
+
+2014-12-14  Andreas Kling  <akling@apple.com>
+
+        Replace PassRef with Ref/Ref&& across the board.
+        <https://webkit.org/b/139587>
+
+        Reviewed by Darin Adler.
+
+        * runtime/Identifier.cpp:
+        (JSC::Identifier::add):
+        (JSC::Identifier::add8):
+        * runtime/Identifier.h:
+        (JSC::Identifier::add):
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::add):
+
+2014-12-12  Matthew Mirman  <mmirman@apple.com>
+
+        shiftCountWithArrayStorage should exit to slow path if the object has a sparse map.
+        https://bugs.webkit.org/show_bug.cgi?id=139598
+        <rdar://problem/18779367>
+
+        Reviewed by Filip Pizlo.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::shiftCountWithArrayStorage): Added check for object having a sparse map.
+        * tests/stress/sparse_splice.js: Added.
+
+2014-12-12  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Final clean up OwnPtr in JSC - runtime, ftl, and tool directories
+        https://bugs.webkit.org/show_bug.cgi?id=139532
+
+        Reviewed by Mark Lam.
+
+        Final remove OwnPtr, PassOwnPtr in runtime, ftl, and tools directories of JSC.
+
+        * builtins/BuiltinExecutables.h:
+        * bytecode/CodeBlock.h:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::IndexedAbstractHeap::atSlow):
+        * ftl/FTLAbstractHeap.h:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLJITFinalizer.h:
+        * jsc.cpp:
+        (jscmain):
+        * parser/Lexer.h:
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::clearDeletedOffsets):
+        (JSC::PropertyTable::addDeletedOffset):
+        * runtime/PropertyTable.cpp:
+        (JSC::PropertyTable::PropertyTable):
+        * runtime/RegExpObject.cpp:
+        * runtime/SmallStrings.cpp:
+        * runtime/Structure.cpp:
+        * runtime/StructureIDTable.cpp:
+        (JSC::StructureIDTable::StructureIDTable):
+        (JSC::StructureIDTable::resize):
+        * runtime/StructureIDTable.h:
+        * runtime/StructureTransitionTable.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::~VM):
+        * runtime/VM.h:
+        * tools/CodeProfile.h:
+        (JSC::CodeProfile::CodeProfile):
+        (JSC::CodeProfile::addChild):
+
+2014-12-11  Dan Bernstein  <mitz@apple.com>
+
+        iOS Simulator production build fix.
+
+        * Configurations/JavaScriptCore.xcconfig: Don’t use an order file when building for the iOS
+        Simulator, as we did prior to 177027.
+
+2014-12-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Explicitly export somre more RWIProtocol classes.
+        rdar://problem/19220408
+
+        Unreviewed build fix.
+
+        * inspector/scripts/codegen/generate_objc_configuration_header.py:
+        (ObjCConfigurationHeaderGenerator._generate_configuration_interface_for_domains):
+        * inspector/scripts/codegen/generate_objc_header.py:
+        (ObjCHeaderGenerator._generate_event_interfaces):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
+2014-12-11  Alexey Proskuryakov  <ap@apple.com>
+
+        Explicitly export some RWIProtocol classes
+        rdar://problem/19220408
+
+        * inspector/scripts/codegen/generate_objc_header.py:
+        (ObjCHeaderGenerator._generate_type_interface):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
+2014-12-11  Mark Lam  <mark.lam@apple.com>
+
+        Fix broken build after r177146.
+        https://bugs.webkit.org/show_bug.cgi?id=139533 
+
+        Not reviewed.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::init):
+        - Restored CallFrame::init() minus the unused JSScope* arg.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        - Remove JSScope* arg when calling CallFrame::init().
+
+2014-12-11  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION: Use of undefined CallFrame::ScopeChain value
+        https://bugs.webkit.org/show_bug.cgi?id=139533
+
+        Reviewed by Mark Lam.
+
+        Removed CallFrame::scope() and CallFrame::setScope() and eliminated or changed
+        all usages of these funcitons.  In some cases the scope is passed in or determined
+        another way.  In some cases the scope is used to calculate other values.  Lastly
+        were places where these functions where used that are no longer needed.  For
+        example when making a call, the caller's ScopeChain was copied to the callee's
+        ScopeChain.  This change no longer uses the ScopeChain call frame header slot.
+        That slot will be removed in a future patch.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::handleHostCall):
+        (JSC::LLInt::setUpCall):
+        (JSC::LLInt::llint_throw_stack_overflow_error):
+        Pass the current scope value to the helper operationCreateActivation() and
+        the call to JSLexicalEnvironment::create() instead of using the stack frame
+        scope chain value.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        CreateActivation now has a second child, the scope.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::init): Deleted.  This is dead code.
+        (JSC::ExecState::scope): Deleted.
+        (JSC::ExecState::setScope): Deleted.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::dumpRegisters): Changed so we didn't access the scope
+        chain slot.  
+        
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        Changed process to find JSScope values on the stack or by some other means.
+
+        * runtime/JSWithScope.h:
+        (JSC::JSWithScope::JSWithScope): Deleted.
+        Eliminated unused constructor.
+
+        * runtime/StrictEvalActivation.cpp:
+        (JSC::StrictEvalActivation::StrictEvalActivation):
+        * runtime/StrictEvalActivation.h:
+        (JSC::StrictEvalActivation::create):
+        Changed to pass in the current scope.
+
+2014-12-10  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr instead of OwnPtr in JSC - heap, jit, runtime, and parser directories
+        https://bugs.webkit.org/show_bug.cgi?id=139351
+
+        Reviewed by Filip Pizlo.
+
+        As a step to use std::unique_ptr<>, this cleans up OwnPtr and PassOwnPtr.
+
+        * bytecode/SamplingTool.h:
+        (JSC::SamplingTool::SamplingTool):
+        * heap/CopiedBlock.h:
+        (JSC::CopiedBlock::didSurviveGC):
+        (JSC::CopiedBlock::pin):
+        * heap/CopiedBlockInlines.h:
+        (JSC::CopiedBlock::reportLiveBytes):
+        * heap/GCActivityCallback.h:
+        * heap/GCThread.cpp:
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::markListSet):
+        * jit/ExecutableAllocator.cpp:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITThunks.cpp:
+        (JSC::JITThunks::JITThunks):
+        (JSC::JITThunks::clearHostFunctionStubs):
+        * jit/JITThunks.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::pushLabel):
+        * parser/ParserArena.cpp:
+        * parser/ParserArena.h:
+        (JSC::ParserArena::identifierArena):
+        * parser/SourceProviderCache.h:
+        * runtime/CodeCache.h:
+        * runtime/Executable.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::sortVector):
+        * runtime/JSGlobalObject.h:
+
+2014-12-10  Geoffrey Garen  <ggaren@apple.com>
+
+        Please disable the webkitFirstVersionWithInitConstructorSupport check on Apple TV
+        https://bugs.webkit.org/show_bug.cgi?id=139501
+
+        Reviewed by Gavin Barraclough.
+
+        NSVersionOfLinkTimeLibrary only works if you link directly against
+        JavaScriptCore, which is a bit awkward for our Apple TV client to do.
+
+        It's easy enough just to disable this check on Apple TV, since it has no
+        backwards compatibility requirement.
+
+        * API/JSWrapperMap.mm:
+        (supportsInitMethodConstructors):
+
+2014-12-10  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes operationPutByIds such that they check that the put didn't
+        change the structure of the object who's property access is being
+        cached.
+        https://bugs.webkit.org/show_bug.cgi?id=139196
+
+        Reviewed by Filip Pizlo.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationGetByIdOptimize): changed get to getPropertySlot
+        (JSC::operationPutByIdStrictBuildList): saved the structure before the put.
+        (JSC::operationPutByIdNonStrictBuildList): ditto.
+        (JSC::operationPutByIdDirectStrictBuildList): ditto.
+        (JSC::operationPutByIdDirectNonStrictBuildList): ditto.
+        * jit/Repatch.cpp:
+        (JSC::tryCachePutByID): fixed structure() to use the existant vm. 
+        (JSC::tryBuildPutByIdList): Added a check that the old structure's id 
+        is the same as the new.
+        (JSC::buildPutByIdList): Added an argument
+        * jit/Repatch.h: 
+        (JSC::buildPutByIdList): Added an argument
+        * tests/stress/put-by-id-strict-build-list-order.js: Added.
+
+2014-12-10  Csaba Osztrogonác  <ossy@webkit.org>
+
+        URTBF after r177030.
+
+        Fix linking failure occured on ARM buildbots:
+        lib/libjavascriptcore_efl.so.1.11.0: undefined reference to `JSC::Structure::get(JSC::VM&, JSC::PropertyName, unsigned int&)'
+
+        * runtime/NullGetterFunction.cpp:
+
+2014-12-09  Michael Saboff  <msaboff@apple.com>
+
+        DFG Tries using an inner object's getter/setter when one hasn't been defined
+        https://bugs.webkit.org/show_bug.cgi?id=139229
+
+        Reviewed by Filip Pizlo.
+
+        Added a new NullGetterFunction singleton class to use for getters and setters that
+        haven't been set to a user defined value.  The NullGetterFunction callReturnUndefined()
+        and createReturnUndefined() methods return undefined.  Changed all null checks of the
+        getter and setter pointers to the newly added isGetterNull() and isSetterNull()
+        helper methods.  
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Added NullGetterFunction.cpp & .h to build files.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncLookupGetter):
+        (JSC::objectProtoFuncLookupSetter):
+        * runtime/PropertyDescriptor.cpp:
+        (JSC::PropertyDescriptor::setDescriptor):
+        (JSC::PropertyDescriptor::setAccessorDescriptor):
+        Changed checking getter and setter to null to use new isGetterNull() and isSetterNull()
+        helpers.
+
+        * inspector/JSInjectedScriptHostPrototype.cpp:
+        (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+        * inspector/JSJavaScriptCallFramePrototype.cpp:
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putIndexedDescriptor):
+        (JSC::putDescriptor):
+        (JSC::JSObject::defineOwnNonIndexProperty):
+        * runtime/MapPrototype.cpp:
+        (JSC::MapPrototype::finishCreation):
+        * runtime/SetPrototype.cpp:
+        (JSC::SetPrototype::finishCreation):
+        Updated calls to GetterSetter::create(), setGetter(), setSetter(), withGetter()
+        and withSetter() to provide a global object.
+
+        * runtime/GetterSetter.cpp:
+        (JSC::GetterSetter::withGetter):
+        (JSC::GetterSetter::withSetter):
+        (JSC::callGetter):
+        (JSC::callSetter):
+        * runtime/GetterSetter.h:
+        (JSC::GetterSetter::GetterSetter):
+        (JSC::GetterSetter::create):
+        (JSC::GetterSetter::isGetterNull):
+        (JSC::GetterSetter::isSetterNull):
+        (JSC::GetterSetter::setGetter):
+        (JSC::GetterSetter::setSetter):
+        Changed to use NullGetterFunction for unspecified getters / setters.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::createThrowTypeError):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::nullGetterFunction):
+        (JSC::JSGlobalObject::evalFunction):
+        Added m_nullGetterFunction singleton.  Updated calls to GetterSetter::create(),
+        setGetter() and setSetter() to provide a global object.
+
+        * runtime/NullGetterFunction.cpp: Added.
+        (JSC::callReturnUndefined):
+        (JSC::constructReturnUndefined):
+        (JSC::NullGetterFunction::getCallData):
+        (JSC::NullGetterFunction::getConstructData):
+        * runtime/NullGetterFunction.h: Added.
+        (JSC::NullGetterFunction::create):
+        (JSC::NullGetterFunction::createStructure):
+        (JSC::NullGetterFunction::NullGetterFunction):
+        New singleton class that returns undefined when called.
+
+2014-12-09  Geoffrey Garen  <ggaren@apple.com>
+
+        Re-enable function.arguments
+        https://bugs.webkit.org/show_bug.cgi?id=139452
+        <rdar://problem/18848149>
+
+        Reviewed by Sam Weinig.
+
+        Disabling function.arguments broke a few websites, and we don't have
+        time right now to work through the details.
+
+        I'm re-enabling function.arguments but leaving in the infrastructure
+        to re-disable it, so we can try this experiment again in the future.
+
+        * runtime/Options.h:
+
+2014-12-09  David Kilzer  <ddkilzer@apple.com>
+
+        Switch from using PLATFORM_NAME to SDK selectors in ANGLE, bmalloc, gtest, JavaScriptCore, WTF
+        <http://webkit.org/b/139212>
+
+        Reviewed by Joseph Pecoraro.
+
+        * Configurations/Base.xcconfig:
+        - Only set GCC_ENABLE_OBJC_GC, GCC_MODEL_TUNING and TOOLCHAINS
+          on OS X.
+        - Only set LLVM_LOCAL_HEADER_PATH and LLVM_SYSTEM_HEADER_PATH on
+          OS X.
+        - Set JAVASCRIPTCORE_CONTENTS_DIR and
+          JAVASCRIPTCORE_FRAMEWORKS_DIR separately for iOS and OS X.
+
+        * Configurations/DebugRelease.xcconfig:
+        - Only set MACOSX_DEPLOYMENT_TARGET and SDKROOT on OS X.
+
+        * Configurations/JSC.xcconfig:
+        - Only set CODE_SIGN_ENTITLEMENTS for iOS hardware builds.
+
+        * Configurations/JavaScriptCore.xcconfig:
+        - Set OTHER_LDFLAGS separately for iOS and OS X.
+        - Set SECTORDER_FLAGS separately for iOS and OS X, but only for
+          Production builds.
+        - Only set EXCLUDED_SOURCE_FILE_NAMES for iOS.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        - Rename LLVM_LIBS_iphoneos to LLVM_LIBS_ios.
+        - Set LLVM_LIBRARY_PATHS and OTHER_LDFLAGS_LLVM_ENABLE_FTL_JIT
+          separately for iOS hardware and OS X.
+        - Fix curly braces in LIBRARY_SEARCH_PATHS.
+        - Merge OTHER_LDFLAGS_BASE into OTHER_LDFLAGS. (Could have been
+          done before this patch.)
+
+        * Configurations/ToolExecutable.xcconfig:
+        - Only set CODE_SIGN_ENTITLEMENTS for iOS, per target.
+        - Only set CLANG_ENABLE_OBJC_ARC for i386 on the iOS Simulator.
+        - Add missing newline.
+
+        * Configurations/Version.xcconfig:
+        - Set SYSTEM_VERSION_PREFIX separately for iOS and OS X.
+
+2014-12-08  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Fix EFL build fix since r177001
+        https://bugs.webkit.org/show_bug.cgi?id=139428
+
+        Unreviewed, EFL build fix.
+
+        Do not inherit duplicated class. ExpressionNode is already
+        child of ParserArenaFreeable class.
+
+        * parser/Nodes.h:
+
+2014-12-08  Shivakumar JM  <shiva.jm@samsung.com>
+
+        Fix Build Warning in JavaScriptCore ControlFlowProfiler::dumpData() api.
+        https://bugs.webkit.org/show_bug.cgi?id=139384
+
+        Reviewed by Mark Lam.
+
+        Fix Build Warning by using dataLog() function instead of dataLogF() function.
+
+        * runtime/ControlFlowProfiler.cpp:
+        (JSC::ControlFlowProfiler::dumpData):
+
+2014-12-08  Saam Barati  <saambarati1@gmail.com>
+
+        Web Inspector: Enable runtime API for JSC's control flow profiler
+        https://bugs.webkit.org/show_bug.cgi?id=139346
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch creates an API that the Web Inspector can use
+        to get information about which basic blocks have exectued
+        from JSC's control flow profiler.
+
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getBasicBlocks):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+
+2014-12-08  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed some allocation and cruft from the parser
+        https://bugs.webkit.org/show_bug.cgi?id=139416
+
+        Reviewed by Mark Lam.
+
+        Now, the only AST nodes that require a destructor are the ones that
+        relate to pickling a function's arguments -- which will required some
+        deeper thinking to resolve.
+
+        This is a < 1% parser speedup.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj: Removed NodeInfo because it
+        was unused.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::CommaNode::emitBytecode):
+        (JSC::SourceElements::lastStatement):
+        (JSC::SourceElements::emitBytecode): Updated for interface change to linked list.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::ASTBuilder):
+        (JSC::ASTBuilder::varDeclarations):
+        (JSC::ASTBuilder::funcDeclarations):
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        (JSC::ASTBuilder::addVar): Removed the ParserArenaData abstraction because
+        it wasn't buying us anything. We can just use Vector directly.
+
+        (JSC::ASTBuilder::createCommaExpr):
+        (JSC::ASTBuilder::appendToCommaExpr): Changed to use a linked list instead
+        of a vector, to avoid allocating a vector with inline capacity in the
+        common case in which an expression is not followed by a vector.
+
+        (JSC::ASTBuilder::Scope::Scope): Use Vector directly to avoid new'ing
+        up a Vector*.
+
+        (JSC::ASTBuilder::appendToComma): Deleted.
+        (JSC::ASTBuilder::combineCommaNodes): Deleted.
+
+        * parser/Lexer.cpp:
+
+        * parser/NodeConstructors.h:
+        (JSC::StatementNode::StatementNode):
+        (JSC::CommaNode::CommaNode):
+        (JSC::SourceElements::SourceElements): Updated for interface change to linked list.
+
+        * parser/NodeInfo.h: Removed.
+
+        * parser/Nodes.cpp:
+        (JSC::SourceElements::append):
+        (JSC::SourceElements::singleStatement): Use a linked list instead of a
+        vector to track the statements in a list. This removes some allocation
+        and it means that we don't need a destructor anymore.
+
+        (JSC::ScopeNode::ScopeNode):
+        (JSC::ProgramNode::ProgramNode):
+        (JSC::EvalNode::EvalNode):
+        (JSC::FunctionNode::FunctionNode): Updated for interface change to reference,
+        since these values are never null.
+
+        * parser/Nodes.h:
+        (JSC::StatementNode::next):
+        (JSC::StatementNode::setNext):
+        (JSC::CommaNode::append): Deleted. Updated for interface change to linked list.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::didFinishParsing): Updated for interface change to reference.
+
+        (JSC::Parser<LexerType>::parseVarDeclarationList):
+        (JSC::Parser<LexerType>::parseExpression): Track comma expressions as
+        an explicit list of CommaNodes, removing a use of vector and a destructor.
+
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createCommaExpr):
+        (JSC::SyntaxChecker::appendToCommaExpr):
+        (JSC::SyntaxChecker::appendToComma): Deleted. Updated for interface changes.
+
+2014-12-08  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r176979.
+        https://bugs.webkit.org/show_bug.cgi?id=139424
+
+        "New JSC test in this patch is failing" (Requested by mlam on
+        #webkit).
+
+        Reverted changeset:
+
+        "Fixes operationPutByIds such that they check that the put
+        didn't"
+        https://bugs.webkit.org/show_bug.cgi?id=139196
+        http://trac.webkit.org/changeset/176979
+
+2014-12-08  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes operationPutByIds such that they check that the put didn't
+        change the structure of the object who's property access is being
+        cached.
+        https://bugs.webkit.org/show_bug.cgi?id=139196
+
+        Reviewed by Filip Pizlo.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationGetByIdOptimize): changed get to getPropertySlot
+        (JSC::operationPutByIdStrictBuildList): saved the structure before the put.
+        (JSC::operationPutByIdNonStrictBuildList): ditto.
+        (JSC::operationPutByIdDirectStrictBuildList): ditto.
+        (JSC::operationPutByIdDirectNonStrictBuildList): ditto.
+        * jit/Repatch.cpp:
+        (JSC::tryCachePutByID): fixed structure() to use the existant vm. 
+        (JSC::tryBuildPutByIdList): Added a check that the old structure's id 
+        is the same as the new.
+        (JSC::buildPutByIdList): Added an argument
+        * jit/Repatch.h: 
+        (JSC::buildPutByIdList): Added an argument
+        * tests/stress/put-by-id-build-list-order-recurse.js: Test that failed before the change
+        * tests/stress/put-by-id-strict-build-list-order.js: Added.
+
+2014-12-08  Anders Carlsson  <andersca@apple.com>
+
+        Change WTF::currentCPUTime to return std::chrono::microseconds and get rid of currentCPUTimeMS
+        https://bugs.webkit.org/show_bug.cgi?id=139410
+
+        Reviewed by Andreas Kling.
+
+        * API/JSContextRef.cpp:
+        (JSContextGroupSetExecutionTimeLimit):
+        (JSContextGroupClearExecutionTimeLimit):
+        * runtime/Watchdog.cpp:
+        (JSC::Watchdog::setTimeLimit):
+        (JSC::Watchdog::didFire):
+        (JSC::Watchdog::startCountdownIfNeeded):
+        (JSC::Watchdog::startCountdown):
+        * runtime/Watchdog.h:
+        * runtime/WatchdogMac.cpp:
+        (JSC::Watchdog::startTimer):
+
+2014-12-08  Mark Lam  <mark.lam@apple.com>
+
+        CFA wrongly assumes that a speculation for SlowPutArrayStorageShape disallows ArrayStorageShape arrays.
+        <https://webkit.org/b/139327>
+
+        Reviewed by Michael Saboff.
+
+        The code generator and runtime slow paths expects otherwise.  This patch fixes
+        CFA to match the code generator's expectation.
+
+        * dfg/DFGArrayMode.h:
+        (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
+        (JSC::DFG::ArrayMode::arrayModesWithIndexingShapes):
+
+2014-12-08  Chris Dumez  <cdumez@apple.com>
+
+        Revert r176293 & r176275
+
+        Unreviewed, revert r176293 & r176275 changing the Vector API to use unsigned type
+        instead of size_t. There is some disagreement regarding the long-term direction
+        of the API and we shouldn’t leave the API partly transitioned to unsigned type
+        while making a decision.
+
+        * bytecode/PreciseJumpTargets.cpp:
+        * replay/EncodedValue.h:
+
+2014-12-07  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove the unused WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND after r129453.
+        https://bugs.webkit.org/show_bug.cgi?id=139373
+
+        Reviewed by Sam Weinig.
+
+        * interpreter/Interpreter.cpp:
+
+2014-12-06  Anders Carlsson  <andersca@apple.com>
+
+        Fix build with newer versions of clang.
+        rdar://problem/18978716
+
+        * ftl/FTLJITCode.h:
+        Add missing overrides.
+
+2014-12-05  Roger Fong  <roger_fong@apple.com>
+
+        [Win] proj files copying over too many resources..
+        https://bugs.webkit.org/show_bug.cgi?id=139315.
+        <rdar://problem/19148278>
+
+        Reviewed by Brent Fulgham.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.proj: Only copy resource folders and JavaScriptCore.dll.
+
+2014-12-05  Juergen Ributzka  <juergen@apple.com>
+
+        [JSC][FTL] Add the data layout to the module and fix the pass order.
+        https://bugs.webkit.org/show_bug.cgi?id=138748
+
+        Reviewed by Oliver Hunt.
+
+        This adds the data layout to the module, so it can be used by all
+        optimization passes in the LLVM optimizer pipeline. This also allows
+        FastISel to select more instructions, because less non-legal types are
+        generated.
+        
+        Also fix the order of the alias analysis passes in the optimization
+        pipeline.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+
+2014-12-05  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed an unused function.
+
+        Reviewed by Michael Saboff.
+
+        Broken out from https://bugs.webkit.org/show_bug.cgi?id=139305.
+
+        * parser/ParserArena.h:
+
+2014-12-05  David Kilzer  <ddkilzer@apple.com>
+
+        FeatureDefines.xcconfig: Workaround bug in Xcode 5.1.1 when defining ENABLE_WEB_REPLAY
+        <http://webkit.org/b/139286>
+
+        Reviewed by Daniel Bates.
+
+        * Configurations/FeatureDefines.xcconfig: Switch back to using
+        PLATFORM_NAME to workaround a bug in Xcode 5.1.1 on 10.8.
+
+2014-12-04  Mark Rowe  <mrowe@apple.com>
+
+        Build fix after r176836.
+
+        Reviewed by Mark Lam.
+
+        * runtime/VM.h:
+        (JSC::VM::controlFlowProfiler): Don't try to export an inline function.
+        Doing so results in a weak external symbol being generated.
+
+2014-12-04  Saam Barati  <saambarati1@gmail.com>
+
+        JavaScript Control Flow Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=137785
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces a mechanism for JavaScriptCore to profile
+        which basic blocks have executed. This mechanism will then be
+        used by the Web Inspector to indicate which basic blocks
+        have and have not executed.
+        
+        The profiling works by compiling in an op_profile_control_flow
+        at the start of every basic block. Then, whenever this op code 
+        executes, we know that a particular basic block has executed.
+        
+        When we tier up a CodeBlock that contains an op_profile_control_flow
+        that corresponds to an already executed basic block, we don't
+        have to emit code for that particular op_profile_control_flow
+        because the internal data structures used to keep track of 
+        basic block locations has already recorded that the corresponding
+        op_profile_control_flow has executed.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/Instruction.h:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::addOpProfileControlFlowBytecodeOffset):
+        (JSC::UnlinkedCodeBlock::opProfileControlFlowBytecodeOffsets):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitProfileControlFlow):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConditionalNode::emitBytecode):
+        (JSC::IfElseNode::emitBytecode):
+        (JSC::WhileNode::emitBytecode):
+        (JSC::ForNode::emitBytecode):
+        (JSC::ContinueNode::emitBytecode):
+        (JSC::BreakNode::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::CaseClauseNode::emitBytecode):
+        (JSC::SwitchNode::emitBytecode):
+        (JSC::ThrowNode::emitBytecode):
+        (JSC::TryNode::emitBytecode):
+        (JSC::ProgramNode::emitBytecode):
+        (JSC::FunctionNode::emitBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::basicBlockLocation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_profile_control_flow):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_profile_control_flow):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionFindTypeForExpression):
+        (functionReturnTypeFor):
+        (functionDumpBasicBlockExecutionRanges):
+        * llint/LowLevelInterpreter.asm:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        (JSC::ASTBuilder::endOffset):
+        (JSC::ASTBuilder::setStartOffset):
+        * parser/NodeConstructors.h:
+        (JSC::Node::Node):
+        * parser/Nodes.h:
+        (JSC::CaseClauseNode::setStartOffset):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseSwitchClauses):
+        (JSC::Parser<LexerType>::parseSwitchDefaultClause):
+        (JSC::Parser<LexerType>::parseBlockStatement):
+        (JSC::Parser<LexerType>::parseStatement):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseIfStatement):
+        (JSC::Parser<LexerType>::parseExpression):
+        (JSC::Parser<LexerType>::parseConditionalExpression):
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionExpr):
+        (JSC::SyntaxChecker::createFuncDeclStatement):
+        (JSC::SyntaxChecker::createGetterOrSetterProperty):
+        (JSC::SyntaxChecker::operatorStackPop):
+        * runtime/BasicBlockLocation.cpp: Added.
+        (JSC::BasicBlockLocation::BasicBlockLocation):
+        (JSC::BasicBlockLocation::insertGap):
+        (JSC::BasicBlockLocation::getExecutedRanges):
+        (JSC::BasicBlockLocation::dumpData):
+        (JSC::BasicBlockLocation::emitExecuteCode):
+        * runtime/BasicBlockLocation.h: Added.
+        (JSC::BasicBlockLocation::startOffset):
+        (JSC::BasicBlockLocation::endOffset):
+        (JSC::BasicBlockLocation::setStartOffset):
+        (JSC::BasicBlockLocation::setEndOffset):
+        (JSC::BasicBlockLocation::hasExecuted):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/ControlFlowProfiler.cpp: Added.
+        (JSC::ControlFlowProfiler::~ControlFlowProfiler):
+        (JSC::ControlFlowProfiler::getBasicBlockLocation):
+        (JSC::ControlFlowProfiler::dumpData):
+        (JSC::ControlFlowProfiler::getBasicBlocksForSourceID):
+        * runtime/ControlFlowProfiler.h: Added. This class is in 
+        charge of generating BasicBlockLocations and also
+        providing an interface that the Web Inspector can use to ping
+        which basic blocks have executed based on the source id of a script.
+
+        (JSC::BasicBlockKey::BasicBlockKey):
+        (JSC::BasicBlockKey::isHashTableDeletedValue):
+        (JSC::BasicBlockKey::operator==):
+        (JSC::BasicBlockKey::hash):
+        (JSC::BasicBlockKeyHash::hash):
+        (JSC::BasicBlockKeyHash::equal):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::ProgramExecutable):
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/FunctionHasExecutedCache.cpp:
+        (JSC::FunctionHasExecutedCache::getUnexecutedFunctionRanges):
+        * runtime/FunctionHasExecutedCache.h:
+        * runtime/Options.h:
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::logTypesForTypeLocation):
+        (JSC::TypeProfiler::typeInformationForExpressionAtOffset):
+        (JSC::TypeProfiler::findLocation):
+        (JSC::TypeProfiler::dumpTypeProfilerData):
+        * runtime/TypeProfiler.h:
+        (JSC::TypeProfiler::functionHasExecutedCache): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::enableProfilerWithRespectToCount):
+        (JSC::disableProfilerWithRespectToCount):
+        (JSC::VM::enableTypeProfiler):
+        (JSC::VM::disableTypeProfiler):
+        (JSC::VM::enableControlFlowProfiler):
+        (JSC::VM::disableControlFlowProfiler):
+        (JSC::VM::dumpTypeProfilerData):
+        * runtime/VM.h:
+        (JSC::VM::functionHasExecutedCache):
+        (JSC::VM::controlFlowProfiler):
+
+2014-12-04  Filip Pizlo  <fpizlo@apple.com>
+
+        printInternal(PrintStream& out, JSC::JITCode::JITType type) ends up dumping a literal %s
+        https://bugs.webkit.org/show_bug.cgi?id=139274
+
+        Reviewed by Geoffrey Garen.
+
+        * jit/JITCode.cpp:
+        (WTF::printInternal):
+
+2014-12-04  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed the concept of ParserArenaRefCounted
+        https://bugs.webkit.org/show_bug.cgi?id=139277
+
+        Reviewed by Oliver Hunt.
+
+        This is a step toward a parser speedup.
+
+        Now that we have a clear root node type for each parse tree, there's no
+        need to have a concept for "I might be refcounted or arena allocated".
+        Instead, we can just use unique_ptr to manage the tree as a whole.
+
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createBuiltinExecutable): Updated for type change.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock): Use unique_ptr. No need to call
+        destroyData() explicitly: the unique_ptr destructor will do everything
+        we need, as Bjarne intended.
+
+        * parser/NodeConstructors.h:
+        (JSC::ParserArenaRoot::ParserArenaRoot):
+        (JSC::ParserArenaRefCounted::ParserArenaRefCounted): Deleted.
+
+        * parser/Nodes.cpp:
+        (JSC::ScopeNode::ScopeNode):
+        (JSC::ProgramNode::ProgramNode):
+        (JSC::EvalNode::EvalNode):
+        (JSC::FunctionNode::FunctionNode):
+        (JSC::ProgramNode::create): Deleted.
+        (JSC::EvalNode::create): Deleted.
+        (JSC::FunctionNode::create): Deleted. All special create semantics can
+        just go away now that we play by C++ constructor / destructor rules.
+
+        * parser/Nodes.h:
+        (JSC::ParserArenaRoot::parserArena):
+        (JSC::ParserArenaRoot::~ParserArenaRoot): Just a normal class now, which
+        holds onto the whole parse tree by virtue of owning the arena in which
+        all the parsed nodes (except for itself) were allocated.
+
+        (JSC::ProgramNode::closedVariables):
+        (JSC::ParserArenaRefCounted::~ParserArenaRefCounted): Deleted.
+
+        (JSC::ScopeNode::destroyData): Deleted. No need to destroy anything
+        explicitly anymore -- we can just rely on destructors.
+
+        (JSC::ScopeNode::parserArena): Deleted.
+
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse):
+        (JSC::parse): unique_ptr all the things.
+
+        * parser/ParserArena.cpp:
+        (JSC::ParserArena::reset):
+        (JSC::ParserArena::isEmpty):
+        (JSC::ParserArena::contains): Deleted.
+        (JSC::ParserArena::last): Deleted.
+        (JSC::ParserArena::removeLast): Deleted.
+        (JSC::ParserArena::derefWithArena): Deleted.
+        * parser/ParserArena.h:
+        (JSC::ParserArena::swap): Much delete. Such wow.
+
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax): unique_ptr all the things.
+
+2014-12-04  Andreas Kling  <akling@apple.com>
+
+        REGRESSION(r173188): Text inserted when trying to delete a word from the Twitter message box.
+        <https://webkit.org/b/139076>
+
+        Reviewed by Geoffrey Garen.
+
+        The StringImpl* -> Weak<JSString> cache used by the DOM bindings
+        had a bug where the key could become a stale pointer if the cached
+        JSString had its internal StringImpl atomicized.
+
+        If a new StringImpl was then later constructed at the exact same
+        address as the stale key, before the Weak<JSString> got booted out
+        of the string cache, we'd now have a situation where asking the
+        string cache for that key would return the old JSString.
+
+        Solve this by not allowing JSString::toExistingAtomicString() to
+        change the JSString's internal StringImpl unless it's resolving a
+        rope string. (The StringImpl nullity determines rope state.)
+
+        This means that calling toExistingAtomicString() may now have to
+        query the AtomicString table on each call rather than just once.
+        All clients of this API would be forced to do this regardless,
+        since they return value will be used to key into containers with
+        AtomicStringImpl* keys.
+
+        No test because this relies on malloc putting two StringImpls
+        at the same address at different points in time and we have no
+        mechanism to reliably test that.
+
+        * runtime/JSString.h:
+        (JSC::JSString::toExistingAtomicString):
+
+2014-12-04  Geoffrey Garen  <ggaren@apple.com>
+
+        Marked some final things final.
+
+        Reviewed by Andreas Kling.
+
+        * parser/Nodes.h:
+
+2014-12-04  Geoffrey Garen  <ggaren@apple.com>
+
+        Split out FunctionNode from FunctionBodyNode
+        https://bugs.webkit.org/show_bug.cgi?id=139273
+
+        Reviewed by Andreas Kling.
+
+        This is step toward a parser speedup.
+
+        We used to use FunctionBodyNode for two different purposes:
+
+        (1) "I am the root function you are currently parsing";
+
+        (2) "I am a lazy record of a nested function, which you will parse later".
+
+        This made for awkward lifetime semantics and interfaces.
+
+        Now, case (1) is handled by FunctionBodyNode, and case (2) is handled by
+        a new node named FunctionNode.
+
+        Since case (1) no longer needs to handle being the root of the parse
+        tree, FunctionBodyNode can be a normal arena-allocated node.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock): Use FunctionNode instead of
+        FunctionBodyNode, since we are producing the root of the function parse
+        tree.
+
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): Removed
+        some unused data, and default-initialized other data, which isn't filled
+        in meaningfully until recordParse() is called. (The previous values were
+        incorrect / meaningless, since the FunctionBodyNode didn't have
+        meaningful values in this case.)
+
+        * bytecode/UnlinkedCodeBlock.h: Ditto.
+
+        (JSC::UnlinkedFunctionExecutable::forceUsesArguments): Deleted.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator): Use FunctionNode instead of
+        FunctionBodyNode, since we are generating code starting at the root of
+        the parse tree.
+
+        (JSC::BytecodeGenerator::resolveCallee):
+        (JSC::BytecodeGenerator::addCallee):
+        * bytecompiler/BytecodeGenerator.h: Ditto.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionBodyNode::emitBytecode):
+        (JSC::FunctionNode::emitBytecode): Moved the emitBytecode implementation
+        to FunctionNode, since we never generate code for FunctionBodyNode,
+        since it's just a placeholder in the AST.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionBody):
+        (JSC::ASTBuilder::setUsesArguments): Deleted. Updated for interface
+        changes.
+
+        * parser/Nodes.cpp:
+        (JSC::FunctionBodyNode::FunctionBodyNode):
+        (JSC::FunctionBodyNode::finishParsing):
+        (JSC::FunctionBodyNode::setEndPosition):
+        (JSC::FunctionNode::FunctionNode):
+        (JSC::FunctionNode::create):
+        (JSC::FunctionNode::finishParsing):
+        (JSC::FunctionBodyNode::create): Deleted.
+
+        * parser/Nodes.h:
+        (JSC::FunctionBodyNode::parameters):
+        (JSC::FunctionBodyNode::source):
+        (JSC::FunctionBodyNode::startStartOffset):
+        (JSC::FunctionBodyNode::isInStrictContext):
+        (JSC::FunctionNode::parameters):
+        (JSC::FunctionNode::ident):
+        (JSC::FunctionNode::functionMode):
+        (JSC::FunctionNode::startColumn):
+        (JSC::FunctionNode::endColumn):
+        (JSC::ScopeNode::setSource): Deleted.
+        (JSC::FunctionBodyNode::parameterCount): Deleted. Split out the differences
+        between FunctionNode and FunctionBodyNode.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createClauseList):
+        (JSC::SyntaxChecker::setUsesArguments): Deleted. Removed setUsesArguments
+        since it wasn't used.
+
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax): Removed a branch that was always
+        false.
+
+2014-12-02  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: timeline probe records have inaccurate per-probe hit counts
+        https://bugs.webkit.org/show_bug.cgi?id=138976
+
+        Reviewed by Joseph Pecoraro.
+
+        Previously, the DebuggerAgent was responsible for assigning unique ids to samples.
+        However, this makes it impossible for the frontend's Timeline manager to associate
+        a Probe Sample timeline record with the corresponding probe sample data. The record
+        only included the probe batchId (misnamed as hitCount in ScriptDebugServer).
+
+        This patch moves both the batchId and sampleId counters into ScriptDebugServer, so
+        any client of ScriptDebugListener will get the correct sampleId for each sample.
+
+        * inspector/ScriptDebugListener.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::ScriptDebugServer):
+        (Inspector::ScriptDebugServer::dispatchBreakpointActionProbe):
+        (Inspector::ScriptDebugServer::handleBreakpointHit):
+        * inspector/ScriptDebugServer.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::InspectorDebuggerAgent):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        * inspector/agents/InspectorDebuggerAgent.h:
+
+2014-12-04  Oliver Hunt  <oliver@apple.com>
+
+        Serialization of MapData object provides unsafe access to internal types
+        https://bugs.webkit.org/show_bug.cgi?id=138653
+
+        Reviewed by Geoffrey Garen.
+
+        Converting these ASSERTs into RELEASE_ASSERTs, as it is now obvious
+        that despite trying hard to be safe in all cases it's simply to easy
+        to use an iterator in an unsafe state.
+
+        * runtime/MapData.h:
+        (JSC::MapData::const_iterator::key):
+        (JSC::MapData::const_iterator::value):
+
+2014-12-03  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Move JavaScriptCore/dfg to std::unique_ptr
+        https://bugs.webkit.org/show_bug.cgi?id=139169
+
+        Reviewed by Filip Pizlo.
+
+        Use std::unique_ptr<>|std::make_unique<> in JavaScriptCore/dfg directory.
+
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::JITCompiler):
+        (JSC::DFG::JITCompiler::compile):
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::compileFunction):
+        (JSC::DFG::JITCompiler::linkFunction):
+        * dfg/DFGJITCompiler.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        (JSC::DFG::Plan::cancel):
+        * dfg/DFGPlan.h:
+        * dfg/DFGSlowPathGenerator.h:
+        * dfg/DFGWorklist.h:
+        * ftl/FTLFail.cpp:
+        (JSC::FTL::fail):
+        * ftl/FTLState.cpp:
+        (JSC::FTL::State::State):
+
+2014-12-03  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (r176479): DFG ASSERTION beneath emitOSRExitCall running Kraken/imaging-gaussian-blur.js.ftl-no-cjit-osr-validation and other tests
+        https://bugs.webkit.org/show_bug.cgi?id=139246
+
+        Reviewed by Geoffrey Garen.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        The DFG_ASSERT that checks liveness at exit time doesn't properly
+        handle the case where the local is not available at OSR exit time,
+        but the local is live in the bytecode.  This now happens with the
+        allocated scope register when we are compiling for FTLForOSREntryMode
+        due to DCE done when the control flow was changed and a new entrypoint
+        was added in the OSR entrypoint creation phase.  Therefore we silence
+        the assert when compiling for FTLForOSREntryMode.
+
+2014-12-03  Geoffrey Garen  <ggaren@apple.com>
+
+        Removed the global parser arena
+        https://bugs.webkit.org/show_bug.cgi?id=139236
+
+        Reviewed by Sam Weinig.
+
+        Simplifies parser lifetime logic.
+
+        There's no need to keep a global arena. We can create a new arena
+        each time we parse.
+
+        * bytecompiler/BytecodeGenerator.h: Global replace to pass around a
+        ParserArena instead of VM*, since the VM no longer owns the arena.
+        (JSC::BytecodeGenerator::parserArena):
+
+        * bytecompiler/NodesCodegen.cpp: Ditto.
+        (JSC::ArrayNode::toArgumentList):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        * parser/ASTBuilder.h: Ditto.
+        (JSC::ASTBuilder::ASTBuilder):
+        (JSC::ASTBuilder::createSourceElements):
+        (JSC::ASTBuilder::createCommaExpr):
+        (JSC::ASTBuilder::createLogicalNot):
+        (JSC::ASTBuilder::createUnaryPlus):
+        (JSC::ASTBuilder::createVoid):
+        (JSC::ASTBuilder::thisExpr):
+        (JSC::ASTBuilder::createResolve):
+        (JSC::ASTBuilder::createObjectLiteral):
+        (JSC::ASTBuilder::createArray):
+        (JSC::ASTBuilder::createNumberExpr):
+        (JSC::ASTBuilder::createString):
+        (JSC::ASTBuilder::createBoolean):
+        (JSC::ASTBuilder::createNull):
+        (JSC::ASTBuilder::createBracketAccess):
+        (JSC::ASTBuilder::createDotAccess):
+        (JSC::ASTBuilder::createSpreadExpression):
+        (JSC::ASTBuilder::createRegExp):
+        (JSC::ASTBuilder::createNewExpr):
+        (JSC::ASTBuilder::createConditionalExpr):
+        (JSC::ASTBuilder::createAssignResolve):
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createFunctionBody):
+        (JSC::ASTBuilder::createGetterOrSetterProperty):
+        (JSC::ASTBuilder::createArguments):
+        (JSC::ASTBuilder::createArgumentsList):
+        (JSC::ASTBuilder::createProperty):
+        (JSC::ASTBuilder::createPropertyList):
+        (JSC::ASTBuilder::createElementList):
+        (JSC::ASTBuilder::createFormalParameterList):
+        (JSC::ASTBuilder::createClause):
+        (JSC::ASTBuilder::createClauseList):
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        (JSC::ASTBuilder::createBlockStatement):
+        (JSC::ASTBuilder::createExprStatement):
+        (JSC::ASTBuilder::createIfStatement):
+        (JSC::ASTBuilder::createForLoop):
+        (JSC::ASTBuilder::createForInLoop):
+        (JSC::ASTBuilder::createForOfLoop):
+        (JSC::ASTBuilder::createEmptyStatement):
+        (JSC::ASTBuilder::createVarStatement):
+        (JSC::ASTBuilder::createEmptyVarExpression):
+        (JSC::ASTBuilder::createReturnStatement):
+        (JSC::ASTBuilder::createBreakStatement):
+        (JSC::ASTBuilder::createContinueStatement):
+        (JSC::ASTBuilder::createTryStatement):
+        (JSC::ASTBuilder::createSwitchStatement):
+        (JSC::ASTBuilder::createWhileStatement):
+        (JSC::ASTBuilder::createDoWhileStatement):
+        (JSC::ASTBuilder::createLabelStatement):
+        (JSC::ASTBuilder::createWithStatement):
+        (JSC::ASTBuilder::createThrowStatement):
+        (JSC::ASTBuilder::createDebugger):
+        (JSC::ASTBuilder::createConstStatement):
+        (JSC::ASTBuilder::appendConstDecl):
+        (JSC::ASTBuilder::combineCommaNodes):
+        (JSC::ASTBuilder::createDeconstructingAssignment):
+        (JSC::ASTBuilder::Scope::Scope):
+        (JSC::ASTBuilder::createNumber):
+        (JSC::ASTBuilder::makeTypeOfNode):
+        (JSC::ASTBuilder::makeDeleteNode):
+        (JSC::ASTBuilder::makeNegateNode):
+        (JSC::ASTBuilder::makeBitwiseNotNode):
+        (JSC::ASTBuilder::makeMultNode):
+        (JSC::ASTBuilder::makeDivNode):
+        (JSC::ASTBuilder::makeModNode):
+        (JSC::ASTBuilder::makeAddNode):
+        (JSC::ASTBuilder::makeSubNode):
+        (JSC::ASTBuilder::makeLeftShiftNode):
+        (JSC::ASTBuilder::makeRightShiftNode):
+        (JSC::ASTBuilder::makeURightShiftNode):
+        (JSC::ASTBuilder::makeBitOrNode):
+        (JSC::ASTBuilder::makeBitAndNode):
+        (JSC::ASTBuilder::makeBitXOrNode):
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        (JSC::ASTBuilder::makeBinaryNode):
+        (JSC::ASTBuilder::makeAssignNode):
+        (JSC::ASTBuilder::makePrefixNode):
+        (JSC::ASTBuilder::makePostfixNode):
+
+        * parser/NodeConstructors.h: Ditto.
+        (JSC::ParserArenaFreeable::operator new):
+        (JSC::ParserArenaDeletable::operator new):
+        (JSC::ParserArenaRefCounted::ParserArenaRefCounted):
+
+        * parser/Nodes.cpp: Ditto.
+        (JSC::ScopeNode::ScopeNode):
+        (JSC::ProgramNode::ProgramNode):
+        (JSC::ProgramNode::create):
+        (JSC::EvalNode::EvalNode):
+        (JSC::EvalNode::create):
+        (JSC::FunctionBodyNode::FunctionBodyNode):
+        (JSC::FunctionBodyNode::create):
+
+        * parser/Nodes.h: Ditto.
+        (JSC::ScopeNode::parserArena):
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::parseProperty): The parser now owns its own
+        arena, and transfers ownership of its contents when invoking the ScopeNode
+        constructor.
+
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse): No need to explicitly reset the arena,
+        since its lifetime is tied to the parser's lifetime now.
+
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createProperty):
+        (JSC::SyntaxChecker::createGetterOrSetterProperty):
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h: The point of the patch: no more global.
+
+2014-12-03  Geoffrey Garen  <ggaren@apple.com>
+
+        The parser should allocate all pieces of the AST
+        https://bugs.webkit.org/show_bug.cgi?id=139230
+
+        Reviewed by Oliver Hunt.
+
+        This is a step toward a 14% parsing speedup.
+
+        Previously, allocation was split between the parser and certain node
+        constructor functions. This made for some duplicated code and circular
+        dependencies.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createGetterOrSetterProperty): No need to pass through
+        the VM, since our callee no longer needs to allocate anything.
+
+        (JSC::ASTBuilder::createProperty): Allocate the identifier for our
+        callee, since that is simpler than requiring our callee to notice that
+        we didn't do so, and do it for us.
+
+        (JSC::ASTBuilder::createForInLoop): Allocate the DeconstructingAssignmentNode
+        for our callee, since that is simpler than requiring our callee to notice
+        that we didn't do so, and do it for us.
+
+        Also, reuse some code instead of duplicating it.
+
+        (JSC::ASTBuilder::createForOfLoop): Ditto.
+
+        (JSC::ASTBuilder::createArrayPattern):
+        (JSC::ASTBuilder::createObjectPattern):
+        (JSC::ASTBuilder::createBindingLocation): No need to pass through a VM
+        pointer, since our callee no longer needs to allocate anything.
+
+        (JSC::ASTBuilder::createBreakStatement): Deleted.
+        (JSC::ASTBuilder::createContinueStatement): Deleted.
+
+        * parser/NodeConstructors.h:
+        (JSC::PropertyNode::PropertyNode):
+        (JSC::DeconstructionPatternNode::DeconstructionPatternNode):
+        (JSC::ArrayPatternNode::ArrayPatternNode):
+        (JSC::ArrayPatternNode::create):
+        (JSC::ObjectPatternNode::ObjectPatternNode):
+        (JSC::ObjectPatternNode::create):
+        (JSC::BindingNode::create):
+        (JSC::BindingNode::BindingNode):
+        (JSC::ContinueNode::ContinueNode): Deleted.
+        (JSC::BreakNode::BreakNode): Deleted.
+        (JSC::EnumerationNode::EnumerationNode): Deleted.
+        (JSC::ForInNode::ForInNode): Deleted.
+        (JSC::ForOfNode::ForOfNode): Deleted. Deleted a bunch of special cases
+        that don't exist anymore, now that the parser allocates all pieces of
+        the AST unconditionally.
+
+        * parser/Nodes.h: Ditto.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseBreakStatement):
+        (JSC::Parser<LexerType>::parseContinueStatement): Allocate the null
+        identifier for our callee, since that is simpler than requiring our
+        callee to notice that we didn't do so, and do it for us.
+
+        (JSC::Parser<LexerType>::parseProperty):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createProperty): No need to pass through a VM
+        pointer, since our callee no longer needs to allocate anything.
+
+2014-12-03  Zsolt Borbely  <zsborbely.u-szeged@partner.samsung.com>
+
+        Remove unused JSC runtime options
+        https://bugs.webkit.org/show_bug.cgi?id=133070
+
+        Reviewed by Csaba Osztrogonác.
+
+        * runtime/Options.h:
+
+2014-12-02  Mark Lam  <mark.lam@apple.com>
+
+        Rolling out r176592, r176603, r176616, and r176705 until build and perf issues are resolved.
+        https://bugs.webkit.org/show_bug.cgi?id=138821
+
+        Not reviewed.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::visitChildren):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitComplexPopScopes):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::mdNode):
+        (JSC::FTL::buildCall):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLengthWithArrayStorage):
+        (JSC::JSArray::sortCompactedVector):
+        * tools/ProfileTreeNode.h:
+        (JSC::ProfileTreeNode::dumpInternal):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::matchCharacterClass):
+
+2014-12-02  Michael Saboff  <msaboff@apple.com>
+
+        Change CallFrame::globalThisValue() to not use CallFrame::scope()
+        https://bugs.webkit.org/show_bug.cgi?id=139202
+
+        Reviewed by Mark Lam.
+
+        Changed to use the globalThis() on the globalObject associated with the
+        callee.  Moved the inline definition to JSGlobalObject.h instead of
+        including JSGlobalObject.h in JSScope.h.  Also moved it as JSScope
+        objects are no longer involved in getting the value.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::ExecState::globalThisValue):
+        * runtime/JSScope.h:
+        (JSC::ExecState::globalThisValue): Deleted.
+
+2014-12-02  Matthew Mirman  <mmirman@apple.com>
+
+        Fixes inline cache fast path accessing nonexistant getters.
+        <rdar://problem/18416918>
+        https://bugs.webkit.org/show_bug.cgi?id=136961
+
+        Reviewed by Filip Pizlo.
+
+        Fixes a bug in inline caching where getters would have been able to 
+        modify the property they are getting during 
+        building the inline cache and then accessing that 
+        property through the inline cache site causing a recursive 
+        inline cache building and allowing the fast path of the cache to 
+        try to load a getter for the property that no longer exists.
+                
+        * jit/JITOperations.cpp: Switched use of get to getPropertySlot.
+        * runtime/JSCJSValue.h: 
+        added getPropertySlot for when you don't want to perform the get quite yet but want 
+        to fill out the slot.
+        * runtime/JSCJSValueInlines.h: Added implementation for getPropertySlot
+        (JSC::JSValue::get): changed to simply call getPropertySlot
+        (JSC::JSValue::getPropertySlot): added.
+        * tests/stress/recursive_property_redefine_during_inline_caching.js: Added test case for bug.
+        (test):
+        
+2014-12-01  Michael Saboff  <msaboff@apple.com>
+
+        Remove GetMyScope node from DFG
+        https://bugs.webkit.org/show_bug.cgi?id=139166
+
+        Reviewed by Oliver Hunt.
+
+        Eliminated GetMyScope DFG node type.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::isLiveInBytecode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyScope): Deleted.
+
+2014-12-01  Michael Saboff  <msaboff@apple.com>
+
+        Crash (integer overflow) beneath ByteCodeParser::handleGetById typing in search field on weather.com
+        https://bugs.webkit.org/show_bug.cgi?id=139165
+
+        Reviewed by Oliver Hunt.
+
+        If we don't have any getById or putById variants, emit non-cached versions of these operations.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::handlePutById):
+
+2014-12-01  Andreas Kling  <akling@apple.com>
+
+        Optimize constructing JSC::Identifier from AtomicString.
+        <https://webkit.org/b/139157>
+
+        Reviewed by Michael Saboff.
+
+        Add constructors for Identifier taking AtomicString and AtomicStringImpl.
+        This avoids branching on the string's isAtomic flag, which is obviously
+        always true for AtomicString & AtomicStringImpl.
+
+        Had to add a Identifier(const char*) constructor to resolve implicit
+        ambiguity between String / AtomicString.
+
+        Also made PrivateName::uid() return AtomicStringImpl* to take advantage
+        of the new constructor in a few places.
+
+        * runtime/Identifier.h:
+        (JSC::Identifier::Identifier):
+        * runtime/IdentifierInlines.h:
+        (JSC::Identifier::Identifier):
+        * runtime/PrivateName.h:
+        (JSC::PrivateName::uid):
+
+2014-12-01  Alexey Proskuryakov  <ap@apple.com>
+
+        Several JavaScriptCore date tests are flaky, because they expect time to be frozen during execution
+        https://bugs.webkit.org/show_bug.cgi?id=139138
+
+        Reviewed by Mark Lam.
+
+        Merged a fix by Bob Clary.
+
+        * tests/mozilla/ecma/Date/15.9.1.1-1.js:
+        * tests/mozilla/ecma/Date/15.9.1.1-2.js:
+        * tests/mozilla/ecma/Date/15.9.2.1.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-1.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-2.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-3.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-4.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-5.js:
+        * tests/mozilla/ecma/Date/15.9.2.2-6.js:
+
+2014-11-17  Oliver Hunt  <oliver@apple.com>
+
+        Make sure range based iteration of Vector<> still receives bounds checking
+        https://bugs.webkit.org/show_bug.cgi?id=138821
+
+        Reviewed by Mark Lam.
+
+        There are a few uses of begin()/end() that explicitly require pointers,
+        so we use getPtr() to extract the underlying pointer generically.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::visitChildren):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitComplexPopScopes):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        * ftl/FTLAbbreviations.h:
+        (JSC::FTL::mdNode):
+        (JSC::FTL::buildCall):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        * profiler/ProfileNode.cpp:
+        (JSC::ProfileNode::debugPrintRecursively):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLengthWithArrayStorage):
+        (JSC::JSArray::sortCompactedVector):
+        * tools/ProfileTreeNode.h:
+        (JSC::ProfileTreeNode::dumpInternal):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::matchCharacterClass):
+
+2014-11-29  Andreas Kling  <akling@apple.com>
+
+        PropertyTable keys should be AtomicStringImpl.
+        <https://webkit.org/b/139096>
+
+        Reviewed by Sam Weinig.
+
+        Since PropertyTable keys are really always Identifiers, switch the key
+        type from StringImpl* to AtomicStringImpl*.
+
+        We have code in the GetByVal opcode implementations that assumes things
+        about this, so this change adds confidence to those algorithms.
+
+        * bytecode/ComplexGetStatus.cpp:
+        (JSC::ComplexGetStatus::computeFor):
+        * bytecode/ComplexGetStatus.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        (JSC::GetByIdStatus::computeFor):
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/GetByIdStatus.h:
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        (JSC::PutByIdStatus::computeFor):
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGDesiredIdentifiers.cpp:
+        (JSC::DFG::DesiredIdentifiers::addLazily):
+        (JSC::DFG::DesiredIdentifiers::at):
+        * dfg/DFGDesiredIdentifiers.h:
+        (JSC::DFG::DesiredIdentifiers::operator[]):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+        * runtime/Identifier.h:
+        (JSC::Identifier::impl):
+        * runtime/IntendedStructureChain.cpp:
+        (JSC::IntendedStructureChain::mayInterceptStoreTo):
+        * runtime/IntendedStructureChain.h:
+        * runtime/PropertyMapHashTable.h:
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::contains):
+        (JSC::StructureTransitionTable::get):
+        (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
+        (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
+        (JSC::Structure::getConcurrently):
+        (JSC::Structure::add):
+        (JSC::Structure::remove):
+        * runtime/Structure.h:
+        (JSC::PropertyMapEntry::PropertyMapEntry):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::getConcurrently):
+        * runtime/StructureTransitionTable.h:
+        (JSC::StructureTransitionTable::Hash::hash):
+
+2014-11-28  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr<>|make_unique<> in ftl, bytecode of JSC
+        https://bugs.webkit.org/show_bug.cgi?id=139063
+
+        Reviewed by Andreas Kling.
+
+        Clean up OwnPtr and PassOwnPtr in JSC.
+
+        * bytecode/StructureStubClearingWatchpoint.cpp:
+        (JSC::StructureStubClearingWatchpoint::push):
+        * bytecode/StructureStubClearingWatchpoint.h:
+        (JSC::StructureStubClearingWatchpoint::StructureStubClearingWatchpoint):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLJITFinalizer.h:
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * parser/SourceProviderCacheItem.h:
+
+2014-11-27  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr instead of OwnPtr in JSC classes
+        https://bugs.webkit.org/show_bug.cgi?id=139009
+
+        Reviewed by Filip Pizlo.
+
+        As a step of using std::unique_ptr<>, this patch replaces OwnPtr with
+        std::unique_ptr<>|std::make_unique<>.
+
+        * bytecode/DFGExitProfile.cpp:
+        (JSC::DFG::ExitProfile::add):
+        * bytecode/DFGExitProfile.h:
+        * bytecode/LazyOperandValueProfile.cpp:
+        (JSC::CompressedLazyOperandValueProfileHolder::add):
+        * bytecode/LazyOperandValueProfile.h:
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::specializedSweep):
+        (JSC::MarkedBlock::stopAllocating):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::clearNewlyAllocated):
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::findMagicComment):
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::invalidateCode):
+        * runtime/RegExp.h:
+        * yarr/RegularExpression.cpp:
+        (JSC::Yarr::RegularExpression::Private::compile):
+        (JSC::Yarr::RegularExpression::isValid):
+        * yarr/YarrInterpreter.cpp:
+        (JSC::Yarr::ByteCompiler::compile):
+        (JSC::Yarr::ByteCompiler::regexBegin):
+        (JSC::Yarr::byteCompile):
+        * yarr/YarrInterpreter.h:
+        (JSC::Yarr::BytecodePattern::BytecodePattern):
+
+2014-11-24  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Clean up OwnPtr and PassOwnPtr in JSC - bytecode, jit, inspector, and interpreter
+        https://bugs.webkit.org/show_bug.cgi?id=139022
+
+        Reviewed by Filip Pizlo.
+
+        As a step of using std::unique_ptr<>, this patch replaces OwnPtr with
+        std::unique_ptr<>|std::make_unique<>.
+
+        * bytecode/DFGExitProfile.cpp:
+        (JSC::DFG::ExitProfile::add):
+        * bytecode/DFGExitProfile.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::linkFunction):
+        * dfg/DFGJITFinalizer.cpp:
+        (JSC::DFG::JITFinalizer::JITFinalizer):
+        * dfg/DFGJITFinalizer.h:
+        * heap/IncrementalSweeper.h:
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::findMagicComment):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::enableSampler):
+        * interpreter/Interpreter.h:
+        * jit/ExecutableAllocator.cpp:
+        (JSC::ExecutableAllocator::ExecutableAllocator):
+        * jit/ExecutableAllocator.h:
+
+2014-11-22  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Clean up OwnPtr and PassOwnPtr in some of JS classes
+        https://bugs.webkit.org/show_bug.cgi?id=138724
+
+        Reviewed by Filip Pizlo.
+
+        As a step to use std::unique_ptr<> and std::make_unique<>, this patch replaces
+        OwnPtr with std::unique_ptr<>. Besides create() factory function is removed as well.
+
+        * builtins/BuiltinExecutables.h:
+        (JSC::BuiltinExecutables::create): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::createRareDataIfNecessary):
+        * bytecode/StructureStubInfo.h:
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::hasRareData):
+        (JSC::UnlinkedCodeBlock::createRareDataIfNecessary):
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/CodeCache.h:
+        (JSC::CodeCache::create): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::clearRareData):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::createRareDataIfNeeded):
+        * runtime/RegExpConstructor.h:
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::createSingleCharacterString):
+        (JSC::SmallStrings::singleCharacterStringRep):
+        * runtime/SmallStrings.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
+2014-11-21  Michael Saboff  <msaboff@apple.com>
+
+        r176455: ASSERT(!m_vector.isEmpty()) in IntendedStructureChain.cpp(143)
+        https://bugs.webkit.org/show_bug.cgi?id=139000
+
+        Reviewed by Darin Adler.
+
+        Check that the chainCount is non-zero before using a StructureChain.
+
+        * bytecode/ComplexGetStatus.cpp:
+        (JSC::ComplexGetStatus::computeFor):
+
+2014-11-21  Michael Saboff  <msaboff@apple.com>
+
+        Allocate local ScopeChain register
+        https://bugs.webkit.org/show_bug.cgi?id=138793
+
+        Reviewed by Geoffrey Garen.
+
+        Now we allocate the scope register as a local.  The allocated register is stored in the 
+        CodeBlock for use by other components.  Update the DFG to work with a local scope register.
+        Changed usage of JSStack::ScopeChain access to the CallFrame header to use the allocated
+        local register.
+
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        Updated to properly represent the operand inputs and bytecode result.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setScopeRegister):
+        (JSC::CodeBlock::scopeRegister):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setScopeRegister):
+        (JSC::UnlinkedCodeBlock::scopeRegister):
+        Added scope register member and accessors.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::allocateAndEmitScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::scopeRegister):
+        Change m_scopeRegister to an allocated register.  Added allocateAndEmitScope helper to
+        allocate the scope register, set the CodeBlock with its value and emit op_get_scope.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::scope): Changed to access the scope using the new convention.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::flush):
+        (JSC::DFG::ByteCodeParser::inlineCall):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        Changed op_create_lexical_environment to set the scope VirtualRegister operand.
+        Filled out op_get_scope processing to emit a GetScope node putting the result in
+        the scope VirtualRegister result operand.
+        Added Phantoms where appropriate to keep the Scope register alive in places where
+        it use is optimized away, but where the baseline JIT would need to use its value.
+        Eliminated uses of JSStack::ScopeChain.
+
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        Make sure that the scope register stack location is allocated using the same place
+        that the codeBlock expects. 
+
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        Allow strength reduction of Flush to skip of GetScope nodes looking for a prior
+        corresponding SetLocal.
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::scope):
+        (JSC::ExecState::setScope):
+        Added new scope() and setScope() helpers that take a VirtualRegister offset.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::eval):
+        Changed eval() to get the scope from the caller's scope register instead of from the
+        temporary frame created for eval.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::unwind):
+        Changed unwind() to manipulate the scope n the allocated register instead of from the
+        call frame slot.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::readNonInlinedFrame):
+        (JSC::StackVisitor::readInlinedFrame):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::callee):
+        (JSC::StackVisitor::Frame::scope): Deleted.
+        Eliminated the scope member as it needed to change and no StackVisitor users use it.
+
+        * jit/JITOperations.cpp:
+        (JSC::operationPushNameScope):
+        (JSC::operationPushWithScope):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        * runtime/JSWithScope.h:
+        (JSC::JSWithScope::create): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        Deleted JSNameScope::create() and JSWithScope::create() flavors tht used the ScopeChain slot
+        in the CallFrame header.  Changed the only user of these function, op_push_name_scope and
+        op_push_with_scope helpers, to use the remaining create variants that require explicit scope.  
+        Those operations get the scope from the register pointed to by their scope operands.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Changed resolveScope to use the allocated register.
+
+2014-11-21  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [JSC] Disable verifyHeap
+        https://bugs.webkit.org/show_bug.cgi?id=138962
+
+        Reviewed by Mark Lam.
+
+        * runtime/Options.h:
+
+2014-11-20  Mark Lam  <mark.lam@apple.com>
+
+        Add some comments to describe the DFG UseKind representations.
+        <https://webkit.org/b/138934>
+
+        Reviewed by Filip Pizlo.
+
+        * dfg/DFGUseKind.h:
+        - Also regrouped the UseKind enums by representation to be more readable.
+
+2014-11-20  Mark Lam  <mark.lam@apple.com>
+
+        Add Heap verification infrastructure.
+        <https://webkit.org/b/138851>
+
+        Reviewed by Geoffrey Garen.
+
+        The verification infrastructure code is always built in but disabled by
+        default.  When disabled, the cost is minimal:
+        1. Heap has a m_verifier field.
+        2. GC does a few "if (m_verifier)" checks that should fail.
+        3. HeapVerifier takes up code space though not used.
+
+        When enabled:
+        1. The HeapVerifier will keep N number of GC cycle data.
+           Each GC cycle will contain a "before marking" and "after marking" live
+           object list.
+           The GC cycles is a circular buffer.  Only data for the last N GC cycles
+           will be retained.
+        2. During GC, the current GC cycle's live objects lists will be populated
+           before and after marking.
+        3. The current GC cycle's live object lists will be validated before GC,
+           after marking, and after GC.
+
+        Currently, the only validation being done is to verify that object
+        butterflies are allocated from valid blocks in the Storage (aka Copied)
+        space.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::collect):
+        * heap/Heap.h:
+        * heap/HeapVerifier.cpp: Added.
+        (JSC::LiveObjectList::findObject):
+        (JSC::HeapVerifier::HeapVerifier):
+        (JSC::HeapVerifier::collectionTypeName):
+        (JSC::HeapVerifier::phaseName):
+        (JSC::getButterflyDetails):
+        (JSC::HeapVerifier::initializeGCCycle):
+        (JSC::GatherLiveObjFunctor::GatherLiveObjFunctor):
+        (JSC::GatherLiveObjFunctor::operator()):
+        (JSC::HeapVerifier::gatherLiveObjects):
+        (JSC::HeapVerifier::liveObjectListForGathering):
+        (JSC::trimDeadObjectsFromList):
+        (JSC::HeapVerifier::trimDeadObjects):
+        (JSC::HeapVerifier::verifyButterflyIsInStorageSpace):
+        (JSC::HeapVerifier::verify):
+        (JSC::HeapVerifier::reportObject):
+        (JSC::HeapVerifier::checkIfRecorded):
+        * heap/HeapVerifier.h: Added.
+        (JSC::LiveObjectData::LiveObjectData):
+        (JSC::LiveObjectList::LiveObjectList):
+        (JSC::LiveObjectList::reset):
+        (JSC::HeapVerifier::GCCycle::GCCycle):
+        (JSC::HeapVerifier::GCCycle::collectionTypeName):
+        (JSC::HeapVerifier::incrementCycle):
+        (JSC::HeapVerifier::currentCycle):
+        (JSC::HeapVerifier::cycleForIndex):
+        * runtime/Options.h:
+
+2014-11-20  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Rename String.prototype.contains to String.prototype.includes
+        https://bugs.webkit.org/show_bug.cgi?id=138923
+
+        As per the latest TC39 meeting[1, 2], String.prototype.contains is
+        renamed to String.prototype.includes. This is because the name
+        `contains` breaks the web since it conflicts with existing `contains`
+        implementations in major libraries.
+
+        [1]: https://github.com/mathiasbynens/String.prototype.includes
+        [2]: https://github.com/tc39/test262/pull/119
+
+        Reviewed by Geoffrey Garen.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::StringPrototype::finishCreation):
+        (JSC::stringProtoFuncIncludes):
+        (JSC::stringProtoFuncContains): Deleted.
+
+2014-11-19  Mark Lam  <mark.lam@apple.com>
+
+        WTFCrashWithSecurityImplication under SpeculativeJIT::compile() when loading a page from theblaze.com.
+        <https://webkit.org/b/137642>
+
+        Reviewed by Filip Pizlo.
+
+        In the DFG, we have a ConstantFolding phase that occurs after all LocalCSE
+        phases have already transpired.  Hence, Identity nodes introduced in the
+        ConstantFolding phase will be left in the node graph.  Subsequently, the
+        DFG code generator asserts that CSE phases have consumed all Identity nodes.
+        This turns out to not be true.  Hence, the crash.  We fix this by teaching
+        the DFG code generator to emit code for Identity nodes.
+
+        Unlike the DFG, the FTL does not have this issue.  That is because the FTL
+        plan has GlobalCSE phases that come after ConstantFolding and any other
+        phases that can generate Identity nodes.  Hence, for the FTL, it is true that
+        CSE will consume all Identity nodes, and the code generator should not see any
+        Identity nodes.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-11-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: JSContext inspection Resource search does not work
+        https://bugs.webkit.org/show_bug.cgi?id=131252
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::searchInContent):
+        * inspector/protocol/Debugger.json:
+        Do some cleanup of the description and implementation of content searching.
+
+2014-11-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Provide $exception in the console for the thrown exception value
+        https://bugs.webkit.org/show_bug.cgi?id=138726
+
+        Reviewed by Timothy Hatcher.
+
+        * debugger/DebuggerScope.cpp:
+        (JSC::DebuggerScope::caughtValue):
+        * debugger/DebuggerScope.h:
+        Access the caught value if this scope is a catch scope.
+
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::isFunctionNameScope):
+        (JSC::JSNameScope::isCatchScope):
+        (JSC::JSNameScope::value):
+        Provide an accessor for the single value in the JSNameScope (with / catch block).
+
+        * inspector/InjectedScriptSource.js:
+        Save the exception value and expose it via $exception. Since the command line api
+        is recreated on each evaluation, $exception is essentially readonly.
+
+        * inspector/ScriptDebugServer.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::dispatchDidPause):
+        (Inspector::ScriptDebugServer::exceptionOrCaughtValue):
+        When pausing, get the exception or caught value. The exception will be provided
+        if we are breaking on an explicit exception. When inside of a catch block, we
+        can get the caught value by walking up the scope chain.
+
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::InspectorDebuggerAgent):
+        (Inspector::InspectorDebuggerAgent::resume):
+        (Inspector::InspectorDebuggerAgent::stepOver):
+        (Inspector::InspectorDebuggerAgent::stepInto):
+        (Inspector::InspectorDebuggerAgent::stepOut):
+        Clearing state can be done in didContinue.
+
+        (Inspector::InspectorDebuggerAgent::didPause):
+        Set the exception value explicitly in the injected script when we have it.
+
+        (Inspector::InspectorDebuggerAgent::didContinue):
+        Clear state saved when we had paused, including clearly an exception value if needed.
+
+        (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
+        (Inspector::InspectorDebuggerAgent::clearExceptionValue):
+        Call into the injected script only when needed.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::setExceptionValue):
+        (Inspector::InjectedScript::clearExceptionValue):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::clearExceptionValue):
+        * inspector/InjectedScriptManager.h:
+        Clear on all injected scripts.
+
+2014-11-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed build fixes after r176329.
+
+          - export all of the codegen python files as they are included by the main generator
+          - update the imports of the main generator to match __init__.py
+          - remove bundling the python scripts as framework resources, just have them PrivateHeaders
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+
+2014-11-18  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: standardize language-specific protocol generator file, class, and method prefixes
+        https://bugs.webkit.org/show_bug.cgi?id=138237
+
+        Reviewed by Joseph Pecoraro.
+
+        Settle on cpp/objc/js file prefixes and Cpp/ObjC/JS class prefixes for generators.
+        Move C++-specific static methods into CppGenerator and add cpp_ prefixes where relevant.
+        Split the templates file into language-specific template files.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/scripts/codegen/__init__.py:
+        * inspector/scripts/codegen/cpp_generator.py: Copied from Source/JavaScriptCore/inspector/scripts/codegen/generator.py.
+        * inspector/scripts/codegen/cpp_generator_templates.py: Copied from Source/JavaScriptCore/inspector/scripts/codegen/generator_templates.py.
+        (CppGeneratorTemplates):
+        * inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py.
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_backend_dispatcher_header.py.
+        * inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_backend_dispatcher_implementation.py.
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_frontend_dispatcher_header.py.
+        * inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py.
+        * inspector/scripts/codegen/generate_cpp_protocol_types_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_protocol_types_header.py.
+        * inspector/scripts/codegen/generate_cpp_protocol_types_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_protocol_types_implementation.py.
+        * inspector/scripts/codegen/generate_js_backend_commands.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_backend_commands.py.
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_backend_dispatcher_header.py.
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_backend_dispatcher_implementation.py.
+        * inspector/scripts/codegen/generate_objc_configuration_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_configuration_header.py.
+        * inspector/scripts/codegen/generate_objc_configuration_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_configuration_implementation.py.
+        * inspector/scripts/codegen/generate_objc_conversion_helpers.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_conversion_helpers.py.
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_frontend_dispatcher_implementation.py.
+        * inspector/scripts/codegen/generate_objc_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_header.py.
+        * inspector/scripts/codegen/generate_objc_internal_header.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_internal_header.py.
+        * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c_types_implementation.py.
+        * inspector/scripts/codegen/generator.py:
+        * inspector/scripts/codegen/generator_templates.py:
+        * inspector/scripts/codegen/objc_generator.py: Renamed from Source/JavaScriptCore/inspector/scripts/codegen/generate_objective_c.py.
+        * inspector/scripts/codegen/objc_generator_templates.py: Added.
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+
+2014-11-19  Juergen Ributzka  <juergen@apple.com>
+
+        Update WebKit to build with LLVM TOT
+        https://bugs.webkit.org/show_bug.cgi?id=138519
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        * llvm/LLVMAPIFunctions.h:
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-11-18  David Kilzer  <ddkilzer@apple.com>
+
+        FeatureDefines.xcconfig: Switch from using PLATFORM_NAME to SDK selectors
+        <http://webkit.org/b/138813>
+
+        Reviewed by Mark Rowe.
+
+        * Configurations/FeatureDefines.xcconfig: Switch to using SDK
+        selectors.
+
+2014-11-18  Chris Dumez  <cdumez@apple.com>
+
+        Update the Vector API to deal with unsigned types instead of size_t
+        https://bugs.webkit.org/show_bug.cgi?id=138824
+
+        Reviewed by Andreas Kling.
+
+        Update code base to fix build errors related to the typing changes
+        in the Vector API (size_t -> unsigned).
+
+        * bytecode/PreciseJumpTargets.cpp:
+        * replay/EncodedValue.h:
+
+2014-11-18  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r176207.
+        https://bugs.webkit.org/show_bug.cgi?id=138836
+
+        Not ready yet (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "Update WebKit to build with LLVM TOT"
+        https://bugs.webkit.org/show_bug.cgi?id=138519
+        http://trac.webkit.org/changeset/176207
+
+2014-11-17  Mark Lam  <mark.lam@apple.com>
+
+        Add printing functionality in JITted code for debugging purposes.
+        <https://webkit.org/b/138660>
+
+        Reviewed by Geoffrey Garen.
+
+        Sometimes, for debugging, it'd be nice to be able to just print the
+        values of constants or registers used in JITted code, or even just
+        a string to log that certain pieces of JITted code have been executed.
+        Using the JIT probe mechanism, we can make this happen.
+
+        * assembler/ARMv7Assembler.h:
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::CPUState::registerName):
+        (JSC::AbstractMacroAssembler::CPUState::registerValue):
+        (JSC::AbstractMacroAssembler::print):
+        (JSC::AbstractMacroAssembler::PrintArg::PrintArg):
+        (JSC::AbstractMacroAssembler::appendPrintArg):
+        (JSC::AbstractMacroAssembler::printInternal):
+        (JSC::AbstractMacroAssembler::printCallback):
+        * assembler/MacroAssemblerARM.cpp:
+        (JSC::MacroAssemblerARM::printCPURegisters):
+        (JSC::MacroAssemblerARM::printRegister):
+        * assembler/MacroAssemblerARM.h:
+        * assembler/MacroAssemblerARMv7.cpp:
+        (JSC::MacroAssemblerARMv7::printCPURegisters):
+        (JSC::MacroAssemblerARMv7::printRegister):
+        * assembler/MacroAssemblerARMv7.h:
+        * assembler/MacroAssemblerX86Common.cpp:
+        (JSC::MacroAssemblerX86Common::printRegister):
+        * assembler/MacroAssemblerX86Common.h:
+
+2014-11-17  Anders Carlsson  <andersca@apple.com>
+
+        Fix JavaScriptCore build with newer versions of clang.
+        <rdar://problem/18978716>
+
+        * heap/Heap.cpp:
+        (JSC::Heap::visitTempSortVectors):
+        (JSC::Heap::deleteAllCompiledCode): Deleted.
+        * inspector/agents/InspectorConsoleAgent.h:
+
+2014-11-17  Juergen Ributzka  <juergen@apple.com>
+
+        Update WebKit to build with LLVM TOT
+        https://bugs.webkit.org/show_bug.cgi?id=138519
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        * llvm/LLVMAPIFunctions.h:
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-11-14  Benjamin Poulain  <bpoulain@apple.com>
+
+        STRH can store values with the wrong offset
+        https://bugs.webkit.org/show_bug.cgi?id=138723
+
+        Reviewed by Michael Saboff.
+
+        This is the counterpart of r176083 for the str instruction.
+
+        I believe this code is currently unreachable because there is only one client of strh()
+        in the MacroAssembler and it always setup the scale explicitely.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::strh):
+
+2014-11-13  Mark Lam  <mark.lam@apple.com>
+
+        Reduce amount of cut-and-paste needed for probe mechanism implementations.
+        <https://webkit.org/b/138671>
+
+        Reviewed by Geoffrey Garen.
+
+        The existing code requires that each MacroAssembler implementation provide
+        their own copy of all of the probe implementations even when most of it is
+        identical.  This patch hoists the common parts into AbstractMacroAssembler
+        (with some minor renaming).  Each target specific MacroAssembler now only
+        need to implement a few target specific methods that are expected by and
+        documented in AbstractMacroAssembler.h in the ENABLE(MASM_PROBE) section.
+
+        In this patch, I also simplified the X86 and X86_64 ports to use the same
+        port implementation.  The ARMv7 probe implementation should not conditionally
+        exclude the higher FP registers (since the JIT doesn't).  Fixed the ARMv7
+        probe code to include the higher FP registers always. 
+
+        This is all done in preparation to add printing functionality in JITted code
+        for debugging.
+
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::Label::Label):
+        (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel):
+        (JSC::AbstractMacroAssembler::DataLabelPtr::DataLabelPtr):
+        (JSC::AbstractMacroAssembler::DataLabel32::DataLabel32):
+        (JSC::AbstractMacroAssembler::DataLabelCompact::DataLabelCompact):
+        (JSC::AbstractMacroAssembler::Jump::link):
+        (JSC::AbstractMacroAssembler::Jump::linkTo):
+        (JSC::AbstractMacroAssembler::JumpList::link):
+        (JSC::AbstractMacroAssembler::JumpList::linkTo):
+        (JSC::AbstractMacroAssembler::ProbeContext::print):
+        (JSC::AbstractMacroAssembler::printIndent):
+        (JSC::AbstractMacroAssembler::printCPU):
+        (JSC::AbstractMacroAssembler::CachedTempRegister::CachedTempRegister):
+        - Except for the 3 printing methods (which are for the probe), the rest
+          are touched simply because we need to add the MacroAssemblerType to the
+          template args.
+          The MacroAssemblerType is used by the abstract probe code to call the
+          few probe methods that need to have CPU specific implementations.
+
+        * assembler/MacroAssemblerARM.cpp:
+        (JSC::MacroAssemblerARM::printCPURegisters):
+        - This was refactored from ProbeContext::dumpCPURegisters() which no
+          longer exists.
+        (JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters): Deleted.
+        (JSC::MacroAssemblerARM::ProbeContext::dump): Deleted.
+
+        * assembler/MacroAssemblerARM.h:
+        * assembler/MacroAssemblerARM64.h:
+
+        * assembler/MacroAssemblerARMv7.cpp:
+        (JSC::MacroAssemblerARMv7::printCPURegisters):
+        - This was refactored from ProbeContext::dumpCPURegisters() which no
+          longer exists.
+        (JSC::MacroAssemblerARMv7::ProbeContext::dumpCPURegisters): Deleted.
+        (JSC::MacroAssemblerARMv7::ProbeContext::dump): Deleted.
+
+        * assembler/MacroAssemblerARMv7.h:
+        * assembler/MacroAssemblerMIPS.h:
+        * assembler/MacroAssemblerSH4.h:
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::trustedImm32FromPtr): Deleted.
+        (JSC::MacroAssemblerX86::probe): Deleted.
+
+        * assembler/MacroAssemblerX86Common.cpp:
+        (JSC::MacroAssemblerX86Common::printCPURegisters):
+        - This was refactored from ProbeContext::dumpCPURegisters() which no
+          longer exists.
+        (JSC::MacroAssemblerX86Common::probe):
+        - This implementation of probe() is based on the one originally in
+          MacroAssemblerX86_64.h.  It is generic and should work for both
+          32-bit and 64-bit.
+        (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters): Deleted.
+        (JSC::MacroAssemblerX86Common::ProbeContext::dump): Deleted.
+
+        * assembler/MacroAssemblerX86Common.h:
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::trustedImm64FromPtr): Deleted.
+        (JSC::MacroAssemblerX86_64::probe): Deleted.
+        * jit/JITStubsARMv7.h:
+
+2014-11-13  Michael Saboff  <msaboff@apple.com>
+
+        Add scope operand to op_new_func* byte codes
+        https://bugs.webkit.org/show_bug.cgi?id=138707
+
+        Reviewed by Mark Lam.
+
+        Added scope operand to op_new_func and op_new_func_expr to replace the implicit use
+        of exec->scope().
+
+        * bytecode/BytecodeList.json: Increased size of op_new_func & op_new_func_expr bytecodes.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Added scope operand to dump output.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        (JSC::BytecodeGenerator::emitNewFunctionExpression):
+        Emit scope operand.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        Added new scope source nodes to NewFunction, NewFunctionExpression & NewFunctionNoCheck.
+        
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        Use scope children when making new function JIT_Operation calls.  Use JSScope* value instead of
+        exec->scope().
+
+        * dfg/DFGOperations.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_new_func):
+        (JSC::JIT::emit_op_new_func_exp):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        Added new Jsc JIT_Operation parameter type for JSScope* values.  Created declarations and
+        definitions for new JIT_Operations with Jsc parameters.  Use the JSScope* parameters in lieu
+        of exec->scope() in operationNewFunction().
+        Removed comment for unused Jsa (JSLexicalEnvironment*) JIT_Operation parameter type.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        Use the scope operand instead of exec->scope().
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Changed the operand indecies for added scope operand.
+
+2014-11-13  Mark Lam  <mark.lam@apple.com>
+
+        Change X86/64 JIT probes to save/restore xmm regs as double instead of __m128. [Follow up]
+        <https://webkit.org/b/138708>
+
+        Reviewed by Michael Saboff.
+
+        Removed a stale comment and a now unnecessary #include. 
+
+        * assembler/X86Assembler.h:
+
+2014-11-13  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r176087.
+        https://bugs.webkit.org/show_bug.cgi?id=138714
+
+        Broke the build (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "Update WebKit to build with LLVM TOT"
+        https://bugs.webkit.org/show_bug.cgi?id=138519
+        http://trac.webkit.org/changeset/176087
+
+2014-11-13  Mark Lam  <mark.lam@apple.com>
+
+        Change X86/64 JIT probes to save/restore xmm regs as double instead of __m128.
+        <https://webkit.org/b/138708>
+
+        Reviewed by Michael Saboff.
+
+        The JIT code only uses the xmm regs as double registers.  This patch changes
+        the storage types of the FP registers in X86Assembler.h to double instead of
+        __m128, and updates the X86 and X86_64 JIT probe implementations accordingly.
+
+        Also made some minor cosmetic changes in the output of the probe dump functions.
+
+        * assembler/MacroAssemblerX86Common.cpp:
+        (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):
+        * assembler/X86Assembler.h:
+        * jit/JITStubsX86.h:
+        * jit/JITStubsX86Common.h:
+        * jit/JITStubsX86_64.h:
+
+2014-11-13  Juergen Ributzka  <juergen@apple.com>
+
+        Update WebKit to build with LLVM TOT
+        https://bugs.webkit.org/show_bug.cgi?id=138519
+
+        Reviewed by Geoffrey Garen.
+
+        * Configurations/LLVMForJSC.xcconfig:
+        * llvm/LLVMAPIFunctions.h:
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+
+2014-11-13  Benjamin Poulain  <benjamin@webkit.org>
+
+        ARMv7(s) Assembler: LDRH with immediate offset is loading from the wrong offset
+        https://bugs.webkit.org/show_bug.cgi?id=136914
+
+        Reviewed by Michael Saboff.
+
+        TLDR: the immediate offset of half-word load was divided by 2.
+
+        Story time: So I started getting those weird reports of :nth-child() behaving bizarrely
+        on ARMv7 and ARMv7s. To make things worse, the behavior changes depending on style updates.
+
+        I started looking the disassembly on the tests cases...
+
+        The first thing I noticed was that the computation of An+B looked wrong. For example,
+        in the case of n+6, the instruction should have been:
+            subs r1, r1, #6
+        but was
+            subs r1, r1, #2
+
+        After spending a lot of time trying to find the error in the assembler, I discovered
+        the problem was not real, but just a bug in the disassembler.
+        This is the first fix: ARMv7DOpcodeAddSubtractImmediate3's immediate3() was truncating
+        the value to 2 bits instead of 3 bits.
+
+        The disassembler being fixed, I still have no lead on the weird bug. Some disassembly later,
+        I realize the LDRH instruction is not decoded at all. The reason is that both LDRH and STRH
+        were under the umbrella ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord but the pattern
+        only matched SRTH.
+
+        I fix that next, ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord is split into
+        ARMv7DOpcodeStoreRegisterImmediateHalfWord and ARMv7DOpcodeLoadRegisterImmediateHalfWord,
+        each with their own pattern and their instruction group.
+
+        Now that I can see the LDRHs correctly, there is something fishy about them, their offset
+        is way too small for the data I load.
+
+        This time, looking at the binary, the generated code is indeed incorrect. It turns out that
+        the ARMv7 assembler shifted the offset of half-word load as if they were byte load: divided by 4.
+        As a result, all the load of half-words with more than zero offset were loading
+        values with a smaller offset than what they should have.
+
+        That being fixed, I dump the assembly: still wrong. I am ready to throw my keyboard through
+        my screen at that point.
+
+        Looking at the disassembler, there is yet again a bug. The computation of the scale() adjustment
+        of the offset was incorrect for anything but word loads.
+        I replaced it by a switch-case to make it explicit.
+
+        STRH is likely incorrect too. I'll fix that in a follow up, I want to survey all the 16 bits cases
+        that are not directly used by the CSS JIT.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::ldrh):
+        Fix the immediate scaling. Add an assertion to make sure the alignment of the input is correct.
+
+        * disassembler/ARMv7/ARMv7DOpcode.cpp:
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeLoadStoreRegisterImmediate::scale):
+        Fix the scaling code. Just hardcode instruction-to-scale table.
+
+        * disassembler/ARMv7/ARMv7DOpcode.h:
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeAddSubtractImmediate3::immediate3):
+        The mask for a 3 bits immediate is not 3 :)
+
+        (JSC::ARMv7Disassembler::ARMv7DOpcodeLoadStoreRegisterImmediate::scale): Deleted.
+
+2014-11-13  Andreas Kling  <akling@apple.com>
+
+        Generate put_by_id for bracket assignment with constant string subscript.
+        <https://webkit.org/b/138702>
+
+        Reviewed by Geoffrey Garen.
+
+        Transform o["f"]=x to o.f=x when generating bytecode. This allows our JIT
+        to inline-cache those accesses instead of always dropping out to C++.
+
+        Just like the get_by_id transformations, this gets a bunch of use on
+        real-web content (and Speedometer) but little/none on raw JS benchmarks.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::AssignBracketNode::emitBytecode):
+
+2014-11-12  Mark Lam  <mark.lam@apple.com>
+
+        Create canonical lists of registers used by both the Assemblers and the JIT probes.
+        <https://webkit.org/b/138681>
+
+        Reviewed by Filip Pizlo.
+
+        * assembler/ARMAssembler.h:
+        * assembler/ARMv7Assembler.h:
+        * assembler/X86Assembler.h:
+        - The FP register storage type is still defined as __m128 because the JIT
+          probe code still expects that amount of storage to be available.  Will
+          change this to double when the JIT probe code is updated accordingly in a
+          later patch.
+
+2014-11-12  Andreas Kling  <akling@apple.com>
+
+        Generate get_by_id for bracket access with constant string subscript.
+        <https://webkit.org/b/138663>
+
+        Reviewed by Michael Saboff.
+
+        Transform o["f"] into o.f when generating bytecode. This allows our JIT
+        to inline-cache those accesses instead of always dropping out to C++.
+
+        This is surprisingly common in real-web content, less so in benchmarks.
+        Interestingly, Speedometer does hit the optimization quite a bit.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BracketAccessorNode::emitBytecode):
+
+2014-11-12  Mark Lam  <mark.lam@apple.com>
+
+        Rename USE(MASM_PROBE) to ENABLE(MASM_PROBE).
+        <https://webkit.org/b/138661>
+
+        Reviewed by Michael Saboff.
+
+        Also move the switch for enabling the use of MASM_PROBE from JavaScriptCore's
+        config.h to WTF's Platform.h.  This ensures that the setting is consistently
+        applied even when building WebCore parts as well.
+
+        * assembler/ARMAssembler.h:
+        * assembler/ARMv7Assembler.h:
+        * assembler/MacroAssemblerARM.cpp:
+        * assembler/MacroAssemblerARM.h:
+        * assembler/MacroAssemblerARMv7.cpp:
+        * assembler/MacroAssemblerARMv7.h:
+        * assembler/MacroAssemblerX86.h:
+        * assembler/MacroAssemblerX86Common.cpp:
+        * assembler/MacroAssemblerX86Common.h:
+        * assembler/MacroAssemblerX86_64.h:
+        * assembler/X86Assembler.h:
+        * config.h:
+        * jit/JITStubs.h:
+        * jit/JITStubsARM.h:
+        * jit/JITStubsARMv7.h:
+        * jit/JITStubsX86.h:
+        * jit/JITStubsX86Common.h:
+        * jit/JITStubsX86_64.h:
+
+2014-11-12  peavo@outlook.com  <peavo@outlook.com>
+
+        [WinCairo] Incorrect names for test executables in debug mode.
+        https://bugs.webkit.org/show_bug.cgi?id=138659
+
+        Reviewed by Alex Christensen.
+
+        In debug mode, jsc.exe, and testapi.exe are not created, causing JSC test failures.
+
+        * JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj:
+        * JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj:
+
+2014-11-11  Michael Saboff  <msaboff@apple.com>
+
+        Change DFG to use scope operand for op_resolve_scope
+        https://bugs.webkit.org/show_bug.cgi?id=138651
+
+        Reviewed by Geoffrey Garen.
+
+        Changed to use the provided scope VirtualRegister.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getScope): Changed to use an argument scope register.
+        (JSC::DFG::ByteCodeParser::parseBlock): Created VirtualRegister from scope operand.
+
+2014-11-11  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Remove IncrementalSweeper::create()
+        https://bugs.webkit.org/show_bug.cgi?id=138243
+
+        Reviewed by Filip Pizlo.
+
+        As a step to use std::unique_ptr<> and std::make_unique<>, this patch removes
+        IncrementalSweeper::create(), then set constructor of IncrementalSweeper to public.
+        Now we begins to use std::make_unique<> to create IncrementalSweeper instance.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::setIncrementalSweeper):
+        * heap/Heap.h:
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::create): Deleted.
+        * heap/IncrementalSweeper.h:
+
+2014-11-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Handle activating extra agents properly after inspector has connected
+        https://bugs.webkit.org/show_bug.cgi?id=138639
+
+        Reviewed by Timothy Hatcher.
+
+        Instead of having the protocol configuration directly add the extra agent
+        to the inspector registry, isntead go through the augmentable controller.
+        The controller will initialize as required if we are already connected or not,
+        and will add to the registry.
+
+        The functional change here is that the frontend can be notified to activate
+        extra agents multiple times as agents eventually become available.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::activateExtraDomain):
+        * inspector/agents/InspectorAgent.h:
+        * inspector/augmentable/AugmentableInspectorController.h:
+        * inspector/scripts/codegen/generator_templates.py:
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        Rebased results.
+
+2014-11-11  Michael Saboff  <msaboff@apple.com>
+
+        Use scope register when processing op_resolve_scope in LLInt and Baseline JIT
+        https://bugs.webkit.org/show_bug.cgi?id=138637
+
+        Reviewed by Mark Lam.
+
+        Filled out op_resolve_scope processing to use the scope operand to access the current
+        scope chain.
+
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        Added scope virtual register parameter to emitResolveClosure().  Added new callOperation() to
+        support the additional argument.
+
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitResolveClosure):
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitResolveClosure):
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        Added "scope" parameter to emitResolveClosure().  Passed scope register index to slow path.
+        Used scope virtual register instead of JSStack::ScopeChain.
+
+2014-11-11  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Don't require a debugger be attached for inspector auto attach
+        https://bugs.webkit.org/show_bug.cgi?id=138638
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::RemoteInspector::updateDebuggableAutomaticInspectCandidate):
+
+2014-11-11  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Handle cases in StackVisitor::Frame::existingArguments() when lexicalEnvironment and/or unmodifiedArgumentsRegister is not set up yet
+        https://bugs.webkit.org/show_bug.cgi?id=138543
+
+        Reviewed by Geoffrey Garen.
+
+        Exception fuzzing may may raise exceptions in places where they would be
+        otherwise impossible. Therefore, a callFrame may lack activation even if
+        the codeBlock signals need of activation. Also, even if codeBlock
+        signals the use of arguments, the unmodifiedArgumentsRegister may not be
+        initialized yet (neither locally nor in lexicalEnvironment).
+
+        If codeBlock()->needsActivation() is false, unmodifiedArgumentsRegister
+        is already checked for Undefined. This patch applies the same check when
+        the condition is true (and also checks whether
+        callFrame()->hasActivation()).
+
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::hasActivation):
+        Moved to interpreter/CallFrameInlines.h.
+        * interpreter/CallFrameInlines.h:
+        (JSC::CallFrame::hasActivation):
+        Fixed to verify that the JSValue returned by uncheckedActivation() is a
+        cell.
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::existingArguments):
+
+2014-11-11  Andreas Kling  <akling@apple.com>
+
+        Another assertion fix for debug builds after r175846.
+
+        generateByIdStub() can now be called with an empty prototype chain
+        if kind == GetUndefined, so tweak the assertion to cover that.
+
+        * jit/Repatch.cpp:
+        (JSC::generateByIdStub):
+
+2014-11-10  Andreas Kling  <akling@apple.com>
+
+        Assertion fix for debug builds after r175846.
+
+        PropertySlot::slotBase() will assert if the slot is unset, so reorder
+        the tests to check for isCacheableValue() first.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+
+2014-11-10  Andreas Kling  <akling@apple.com>
+
+        The JIT should cache property lookup misses.
+        <https://webkit.org/b/135578>
+
+        Add support for inline caching of missed property lookups.
+        Previously this would banish us to C++ slow path.
+
+        It's implemented as a simple GetById cache that returns jsUndefined()
+        as long as the Structure chain check passes. There's no DFG exploitation
+        of this knowledge in this patch.
+
+        Test: js/regress/undefined-property-access.js (~5.5x speedup)
+
+        Reviewed by Filip Pizlo.
+
+        * bytecode/PolymorphicGetByIdList.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+
+            Add GetByIdAccess::SimpleMiss so we can communicate to the DFG that
+            the access has been cached.
+
+        * jit/Repatch.cpp:
+        (JSC::toString):
+        (JSC::kindFor):
+        (JSC::generateByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::tryBuildGetByIDList):
+
+            Added a GetUndefined stub kind, just a simple "store jsUndefined()" snippet.
+            Use this to cache missed lookups, piggybacking mostly on the GetValue kind.
+
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::isUnset):
+
+            Exposed the unset state so PropertySlot can communicate that lookup failed.
+
+2014-11-10  Michael Saboff  <msaboff@apple.com>
+
+        Add scope operand to op_create_lexical_environment
+        https://bugs.webkit.org/show_bug.cgi?id=138588
+
+        Reviewed by Geoffrey Garen.
+
+        Added a second operand to op_create_lexical_environment that contains the scope register
+        to update.  Note that the DFG relies on operationCreateActivation() to update the
+        scope register since we can't issue a set() with a non-local, non-argument register.
+        This is temporary until the scope register is allocated as a local.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        Added the scope register operand.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        Filled in the scope register operand.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Set the scope register with the result of the appropriate create activation slow call.
+
+2014-11-09  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Fix 'noreturn' function does return warning in LLVMOverrides.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=138306
+
+        Reviewed by Filip Pizlo.
+
+        Adding NO_RETURN where needed.
+
+        * llvm/library/LLVMExports.cpp:
+        (initializeAndGetJSCLLVMAPI):
+        * llvm/library/LLVMOverrides.cpp:
+        * llvm/library/LLVMTrapCallback.h:
+
+2014-11-07  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Fix an alignment issue with operationPushCatchScope on ARMv7
+        https://bugs.webkit.org/show_bug.cgi?id=138510
+
+        Reviewed by Csaba Osztrogonác.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+
+2014-11-07  Michael Saboff  <msaboff@apple.com>
+
+        Update scope related slow path code to use scope register added to opcodes
+        https://bugs.webkit.org/show_bug.cgi?id=138254
+
+        Reviewed by Mark Lam.
+
+        Updated slow paths for op_pop_scope, op_push_name_scope and op_push_with_scope.
+        Added scope register index parameter to the front of the relevant argument lists of the
+        slow functions.  In the case of op_push_name_scope for x86 (32 bit), there aren't enough
+        registers to accomodate all the parameters.  Therefore, added two new JSVALUE32_64 slow
+        paths called operationPushCatchScope() and operationPushFunctionNameScope() to eliminate
+        the last "type" argument.
+        
+
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::FunctionPtr::FunctionPtr): Added a new template to take 6 arguments.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        New variants of setupArgumentsWithExecState() and callOperation() to handle the new
+        combinations of argument types and counts.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_pop_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_pop_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        Use the new slow paths.
+
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        Updates to set the scope result using the scope register index.  Added operationPushCatchScope()
+        and operationPushFunctionNameScope().
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        Updated the scope slow paths to use the scope register index in the instruction to read and
+        write the register instead of using CallFrame::scope() and CallFrame::setScope().
+
+2014-11-07  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Apply std::unique_ptr to slowPathCall()
+        https://bugs.webkit.org/show_bug.cgi?id=138489
+
+        Reviewed by Mark Lam.
+
+        As a step to use std::unique_ptr<>, this patch makes slowPathCall() use std::unique_ptr<>,
+        std::make_unique<>, and WTF::move(). 
+
+        * dfg/DFGSlowPathGenerator.h:
+        (JSC::DFG::slowPathCall):
+        (JSC::DFG::slowPathMove):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+        (JSC::DFG::SpeculativeJIT::addSlowPathGenerator):
+        (JSC::DFG::SpeculativeJIT::arrayify):
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2014-11-06  Mark Lam  <mark.lam@apple.com>
+
+        slow_path_get_direct_pname() needs to be hardened against a constant baseValue.
+        <https://webkit.org/b/138476>
+
+        Reviewed by Michael Saboff.
+
+        slow_path_get_direct_pname() currently assumes that the baseValue is always a
+        non-constant virtual register.  However, this is not always the case like in the
+        following:
+
+            function foo() {
+                var o = { a:1 };
+                for (var n in o)
+                    0[n];
+            }
+            foo();
+
+        This patch fixes it to also check for constant virtual register indexes.
+
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+
+2014-11-06  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION (r174985-174986): Site display disappears 
+        https://bugs.webkit.org/show_bug.cgi?id=138082
+
+        Reviewed by Geoffrey Garen.
+
+        In support of the change in WebCore, this adds a new functor class to unwind to our
+        caller's frame possibly skipping of intermediate C++ frames.
+
+        * interpreter/StackVisitor.h:
+        (JSC::CallerFunctor::CallerFunctor):
+        (JSC::CallerFunctor::callerFrame):
+        (JSC::CallerFunctor::operator()):
+
+2014-11-06  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr in CodeBlock class
+        https://bugs.webkit.org/show_bug.cgi?id=138395
+
+        Reviewed by Darin Adler.
+
+        * bytecode/CodeBlock.h: Use std::unique_ptr.
+        (JSC::CodeBlock::setJITCodeMap):
+        * jit/CompactJITCodeMap.h: Use std::unique_ptr instead of OwnPtr|PassOwnPtr.
+        (JSC::CompactJITCodeMap::CompactJITCodeMap):
+        (JSC::CompactJITCodeMap::Encoder::finish): Use std::unique_ptr instead of PassOwnPtr.
+
+2014-11-05  Mark Lam  <mark.lam@apple.com>
+
+        PutById inline caches should have a store barrier when it triggers a structure transition.
+        <https://webkit.org/b/138441>
+
+        Reviewed by Geoffrey Garen.
+
+        After r174025, we no longer insert DFG store barriers when the payload of a
+        PutById operation is not a cell.  However, this can lead to a crash when we have
+        PutById inline cache code transitioning the structure and re-allocating the
+        butterfly of an old gen object.  The lack of a store barrier in that inline
+        cache results in the old gen object not being noticed during an eden GC scan.
+        As a result, its newly allocated butterfly will not be kept alive, which leads
+        to a stale butterfly pointer and, eventually, a crash.
+
+        It is also possible that the new structure can be collected by the eden GC if
+        (at GC time):
+        1. It is in the eden gen.
+        2. The inline cache that installed it has been evicted.
+        3. There are no live eden gen objects referring to it.
+
+        The chances of this should be more rare than the butterfly re-allocation, but
+        it is still possible.  Hence, the fix is to always add a store barrier if the
+        inline caches performs a structure transition.
+
+        * jit/Repatch.cpp:
+        (JSC::emitPutTransitionStub):
+        - Added store barrier code based on SpeculativeJIT::storeToWriteBarrierBuffer()'s
+          implementation.
+
+2014-11-05  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr in JSClassRef and JSCallbackObject
+        https://bugs.webkit.org/show_bug.cgi?id=138402
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSCallbackObject.h: Use std::unique_ptr instead of OwnPtr|PassOwnPtr.
+        (JSC::JSCallbackObjectData::setPrivateProperty): ditto.
+        * API/JSClassRef.cpp: ditto.
+        * API/JSClassRef.h: ditto.
+
+2014-11-05  Michael Saboff  <msaboff@apple.com>
+
+        Disable flakey float32-repeat-out-of-bounds.js and int8-repeat-out-of-bounds.js tests for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=138381
+
+        Reviewed by Mark Lam.
+
+        Disabled these test for ARM64.  Will address the failures and then re-enable.
+
+        * tests/stress/float32-repeat-out-of-bounds.js:
+        * tests/stress/int8-repeat-out-of-bounds.js:
+
+2014-11-05  Alexey Proskuryakov  <ap@apple.com>
+
+        Incorrect sandbox_check in RemoteInspector.mm
+        https://bugs.webkit.org/show_bug.cgi?id=138408
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/remote/RemoteInspector.mm:
+        (Inspector::canAccessWebInspectorMachPort):
+
+2014-11-03  Dean Jackson  <dino@apple.com>
+
+        Add ENABLE_FILTERS_LEVEL_2 feature guard.
+        https://bugs.webkit.org/show_bug.cgi?id=138362
+
+        Reviewed by Tim Horton.
+
+        Add a new feature define for Level 2 of CSS Filters.
+        http://dev.w3.org/fxtf/filters-2/
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-11-04  Mark Lam  <mark.lam@apple.com>
+
+        Rename checkMarkByte() to jumpIfIsRememberedOrInEden().
+        <https://webkit.org/b/138369>
+
+        Reviewed by Geoffrey Garen.
+
+        Write barriers are needed for GC Eden collections so that we can scan pointers
+        pointing from old generation objects to eden generation objects.  The barrier
+        currently checks the mark byte in a cell to see if we should skip adding the
+        cell to the GC remembered set.  The addition should be skipped if:
+
+        1. The cell is in the young generation.  It has no old to eden pointers by
+           definition.
+        2. The cell is already in the remembered set.  While it is ok to add the cell
+           to the GC remembered set more than once, it would be redundant.  Hence,
+           we skip this as an optimization to avoid doing unnecessary work.
+
+        The barrier currently names this check as checkMarkByte().  We should rename it
+        to jumpIfIsRememberedOrInEden() to be clearer about its intent.
+
+        Similarly, Jump results of this check are currently named
+        ownerNotMarkedOrAlreadyRemembered.  This can be misinterpreted as the owner is
+        not marked or not already remembered.  We should rename it to
+        ownerIsRememberedOrInEden which is clearer about the intent of the
+        check.  What we are really checking for is that the cell is in the eden gen,
+        which is implied by it being "not marked".
+
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::osrWriteBarrier):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::writeBarrier):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::jumpIfIsRememberedOrInEden):
+        (JSC::AssemblyHelpers::checkMarkByte): Deleted.
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitWriteBarrier):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSCell.h:
+
+2014-11-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Pause on exceptions should show the actual exception
+        https://bugs.webkit.org/show_bug.cgi?id=63096
+
+        Reviewed by Timothy Hatcher.
+
+        * debugger/Debugger.h:
+        Expose accessor for the pause reason to subclasses.
+
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::type):
+        New "error" subtype for error objects.
+
+        * inspector/InjectedScriptSource.js:
+        When an object is an error object, use toString to provide a richer description.
+
+        * inspector/protocol/Runtime.json:
+        Expose a new "error" subtype for Error types (TypeError, ReferenceError, EvalError, etc).
+
+        * inspector/protocol/Debugger.json:
+        Provide type checked objects for different Debugger.pause pause reasons.
+        An exception provides the thrown object, but assert / CSP pauses provide
+        a richer typed object as the auxiliary data.
+
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::dispatchDidPause):
+        When paused because of an exception, pass the exception on.
+
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::handleConsoleAssert):
+        (Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
+        Provide richer data in pause events.
+
+        * inspector/scripts/codegen/generate_backend_commands.py:
+        (BackendCommandsGenerator.generate_domain.is_anonymous_enum_param):
+        (BackendCommandsGenerator.generate_domain):
+        * inspector/scripts/tests/expected/enum-values.json-result:
+        Generate frontend enums for anonymous enum event parameters.
+
+2014-11-04  Michael Saboff  <msaboff@apple.com>
+
+        Disable flakey float32-repeat-out-of-bounds.js and int8-repeat-out-of-bounds.js tests for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=138381
+
+        Reviewed by Mark Lam.
+
+        Disabled these test for ARM64.  Will address the failures and then re-enable.
+
+        * tests/stress/float32-repeat-out-of-bounds.js:
+        * tests/stress/int8-repeat-out-of-bounds.js:
+
+2014-11-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Enum value collisions between different generators
+        https://bugs.webkit.org/show_bug.cgi?id=138343
+
+        Reviewed by Brian Burg.
+
+        Each generator was using its own filtered list of domains_to_generate
+        to build the shared unique list of enum value encodings. This list
+        was slightly different across different generators. Instead always
+        use the list of all non-supplemental domains to generate the shared
+        list of enum values.
+
+        * inspector/scripts/codegen/generator.py:
+        (Generator.non_supplemental_domains):
+        (Generator.domains_to_generate):
+        (Generator._traverse_and_assign_enum_values):
+        * inspector/scripts/tests/enum-values.json: Added.
+        * inspector/scripts/tests/expected/enum-values.json-result: Added.
+
+2014-11-03  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Workaround for Cortex-A53 erratum 835769
+        https://bugs.webkit.org/show_bug.cgi?id=138315
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces CMake variable and preprocessor macro
+        WTF_CPU_ARM64_CORTEXA53 with the aim of enabling Cortex-A53-specific
+        code paths, if set true. The patch also implements one case where such
+        code paths are needed: the workaround for Cortex-A53 erratum 835769. If
+        WTF_CPU_ARM64_CORTEXA53 is set then:
+        - CMake checks whether the compiler already has support for a workaround
+          and adds -mfix-cortex-a53-835769 to the compiler flags if so,
+        - the ARM64 backend of offlineasm inserts a nop between memory and
+          multiply-accumulate instructions, and
+        - the ARM64 assembler also inserts a nop between memory and (64-bit) 
+          multiply-accumulate instructions.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::madd):
+        Call nopCortexA53Fix835769() to insert a nop if CPU(ARM64_CORTEXA53) and
+        if necessary.
+        (JSC::ARM64Assembler::msub): Likewise.
+        (JSC::ARM64Assembler::smaddl): Likewise.
+        (JSC::ARM64Assembler::smsubl): Likewise.
+        (JSC::ARM64Assembler::umaddl): Likewise.
+        (JSC::ARM64Assembler::umsubl): Likewise.
+        (JSC::ARM64Assembler::nopCortexA53Fix835769):
+        Added. Insert a nop if the previously emitted instruction was a load, a
+        store, or a prefetch, and if the current instruction is 64-bit.
+        * offlineasm/arm64.rb:
+        Add the arm64CortexA53Fix835769 phase and call it from
+        getModifiedListARM64 to insert nopCortexA53Fix835769 between appropriate
+        macro instructions. Also, lower nopCortexA53Fix835769 to nop if
+        CPU(ARM64_CORTEXA53), to nothing otherwise.
+        * offlineasm/instructions.rb:
+        Define macro instruction nopFixCortexA53Err835769.
+
+2014-11-03  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r175509.
+        https://bugs.webkit.org/show_bug.cgi?id=138349
+
+        broke some builds (Requested by msaboff on #webkit).
+
+        Reverted changeset:
+
+        "Update scope related slow path code to use scope register
+        added to opcodes"
+        https://bugs.webkit.org/show_bug.cgi?id=138254
+        http://trac.webkit.org/changeset/175509
+
+2014-11-03  Michael Saboff  <msaboff@apple.com>
+
+        Update scope related slow path code to use scope register added to opcodes
+        https://bugs.webkit.org/show_bug.cgi?id=138254
+
+        Reviewed by Mark Lam.
+
+        Updated slow paths for op_pop_scope, op_push_name_scope and op_push_with_scope.
+        Added scope register index parameter to the front of the relevant argument lists of the
+        slow functions.  In the case of op_push_name_scope for x86 (32 bit), there aren't enough
+        registers to accomodate all the parameters.  Therefore, added two new JSVALUE32_64 slow
+        paths called operationPushCatchScope() and operationPushFunctionNameScope() to eliminate
+        the last "type" argument.
+        
+
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::FunctionPtr::FunctionPtr): Added a new template to take 6 arguments.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        New variants of setupArgumentsWithExecState() and callOperation() to handle the new
+        combinations of argument types and counts.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_pop_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_pop_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        Use the new slow paths.
+
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        Updates to set the scope result using the scope register index.  Added operationPushCatchScope()
+        and operationPushFunctionNameScope().
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        Updated the scope slow paths to use the scope register index in the instruction to read and
+        write the register instead of using CallFrame::scope() and CallFrame::setScope().
+
+2014-11-03  Michael Saboff  <msaboff@apple.com>
+
+        Add "get scope" byte code
+        https://bugs.webkit.org/show_bug.cgi?id=138326
+
+        Reviewed by Mark Lam.
+
+        Added op_get_scope.  Added implementations for the LLInt and baseline JIT.
+        Provided nop implementation for DFG and FTL.  The new byte code is emitted
+        after op_enter for any function, program or eval.  It is expected that the
+        DFG will be implemented such that unneeded op_get_scope would be eliminated
+        during DFG compilation.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        Added new op_get_scope bytecode.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitGetScope):
+        * bytecompiler/BytecodeGenerator.h:
+        Emit new op_get_scope bytecode.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        Added framework for new op_get_scope bytecode.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_get_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_get_scope):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Implementation of op_get_scope bytecode.
+
+2014-11-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Fix RWIProtocol 64-to-32 bit conversion warnings
+        https://bugs.webkit.org/show_bug.cgi?id=138325
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InspectorValues.h:
+        Vector's length really is an unsigned, so a static_cast here is fine.
+
+        * inspector/scripts/codegen/generate_objective_c.py:
+        (ObjCGenerator.objc_type_for_raw_name):
+        Use int instead of NSInteger for APIs that eventually map to
+        InspectorObject's setInteger, which takes an int.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        Rebaselined results with the type change.
+
+2014-11-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Show Selector's Specificity
+        https://bugs.webkit.org/show_bug.cgi?id=138189
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/protocol/CSS.json:
+        Create a new named type CSSSelector to include a selector's text and specificity.
+        The specificity tuple is optional as it may soon be made dynamic in some cases.
+
+2014-11-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ObjC Protocol Interfaces should throw exceptions for nil arguments
+        https://bugs.webkit.org/show_bug.cgi?id=138221
+
+        Reviewed by Timothy Hatcher.
+
+        The RWIProtocol APIs will now raise exceptions when:
+
+          - any properties are set on a type with a nil value or key (handled by RWIProtocolJSONObject)
+          - required parameters in type constructors have nil value
+          - required or optional command return parameters have nil values
+          - required or optional event parameters have nil values
+
+        The exceptions include the name of the field when possible.
+
+        * inspector/scripts/codegen/generate_objective_c.py:
+        (ObjCGenerator.is_type_objc_pointer_type):
+        Provide a quick check to see if type would be a pointer or not
+        in the ObjC API. Enums for example are not pointers in the API
+        because we manage converting them to/from strings.
+
+        * inspector/scripts/codegen/generate_objective_c_backend_dispatcher_implementation.py:
+        (ObjectiveCConfigurationImplementationGenerator._generate_success_block_for_command):
+        * inspector/scripts/codegen/generate_objective_c_frontend_dispatcher_implementation.py:
+        (ObjectiveCFrontendDispatcherImplementationGenerator._generate_event):
+        * inspector/scripts/codegen/generate_objective_c_types_implementation.py:
+        (ObjectiveCTypesImplementationGenerator._generate_init_method_for_required_members):
+        (ObjectiveCTypesImplementationGenerator._generate_setter_for_member):
+        Throw exceptions when nil values are disallowed.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        Rebaseline tests which include the exception raise calls.
+
+2014-11-03  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: ALTERNATE_DISPATCHERS Let the frontend know about extra agents
+        https://bugs.webkit.org/show_bug.cgi?id=138236
+
+        Reviewed by Brian Burg.
+
+        Inform the frontend about any extra domains the backend may have
+        above and beyond the default list of domains for the debuggable type.
+        This approach means there is almost no cost to normal debugging.
+        When a JSContext is debugged with extra agents, a message is sent
+        to the frontend letting it know which domains to then activate,
+        and perform any initialization work that may be required.
+
+        * inspector/InspectorAgentBase.h:
+        (Inspector::InspectorAgentBase::domainName):
+        * inspector/InspectorAgentRegistry.cpp:
+        (Inspector::InspectorAgentRegistry::appendExtraAgent):
+        * inspector/InspectorAgentRegistry.h:
+        * inspector/scripts/codegen/generator_templates.py:
+        Provide a way to get a list of just the extra domains.
+        To aggregate this list provide a different "append"
+        specifically for extra agents.
+
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        When a frontend connects, inform it of the extra domains.
+
+        * inspector/protocol/Inspector.json:
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorAgent.cpp:
+        (Inspector::InspectorAgent::enable):
+        (Inspector::InspectorAgent::activateExtraDomains):
+        Send an event with the extra domains to activate.
+
+2014-11-01  Michael Saboff  <msaboff@apple.com>
+
+        Add scope operand to op_resolve_scope
+        https://bugs.webkit.org/show_bug.cgi?id=138253
+
+        Reviewed by Mark Lam.
+
+        Added scope operand to op_resolve_scope.  Although the scope register is filled in with
+        the ScopeChain register, this operand is not used in the processing of the bytecode.
+        That will be addressed in a future patch.
+
+        * bytecode/BytecodeList.json: Lengthened the three bytecodes.
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Added code to dump the scope operand.
+
+        (JSC::CodeBlock::CodeBlock): 
+        (JSC::CodeBlock::finalizeUnconditionally):
+        Updated the operand indecies for the processing of op_resolve_scope.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitGetOwnScope):
+        (JSC::BytecodeGenerator::emitReturn):
+        Added scope register to these emit functions and the bytecodes they emit.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Updated the operand indecies for the processing of op_resolve_scope.
+
+2014-11-01  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        REGRESSION(CMake): Make it possible to build without introspection
+        https://bugs.webkit.org/show_bug.cgi?id=138006
+
+        Reviewed by Philippe Normand.
+
+        Do not install introspection files when introspection is disabled.
+
+        * PlatformGTK.cmake:
+
+2014-10-31  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use std::unique_ptr for TypeCountSet
+        https://bugs.webkit.org/show_bug.cgi?id=138242
+
+        Reviewed by Andreas Kling.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::protectedObjectTypeCounts):
+        Use std::unique_ptr<> instead of PassOwnPtr|OwnPtr.
+        (JSC::Heap::objectTypeCounts): ditto.
+        * heap/Heap.h:
+
+2014-10-31  Michael Saboff  <msaboff@apple.com>
+
+        Add scope operand to op_push_with_scope, op_push_name_scope and op_pop_scope
+        https://bugs.webkit.org/show_bug.cgi?id=138252
+
+        Reviewed by Geoffrey Garen.
+
+        Added scope operand to op_push_with_scope, op_push_name_scope and op_pop_scope.
+        Although the scope register is filled in with the ScopeChain register for all 
+        three bytecodes, this operand is not used in the processing of the bytecodes.
+        That will be addressed in a future patch.
+
+        * bytecode/BytecodeList.json: Lengthened the three bytecodes.
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode): Added code to dump the scope operand.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitPushWithScope):
+        (JSC::BytecodeGenerator::emitPopScope):
+        (JSC::BytecodeGenerator::emitComplexPopScopes):
+        (JSC::BytecodeGenerator::emitPopScopes):
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::scopeRegister):
+        Added scope register to these emit functions and the bytecodes they emit.
+        New m_scopeRegister and accessor.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ContinueNode::emitBytecode):
+        (JSC::BreakNode::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::WithNode::emitBytecode):
+        (JSC::TryNode::emitBytecode):
+        Created a RegisterID for the ScopeChain register and used it to emit the updated
+        bytecodes.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_with_scope):
+        (JSC::JIT::emit_op_push_name_scope):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        Updated the operand indecies for the processing of the updated bytecodes.
+
+2014-10-31  Andreas Kling  <akling@apple.com>
+
+        Make writes to RegExpObject.lastIndex cacheable.
+        <https://webkit.org/b/138255>
+
+        Reviewed by Geoffrey Garen.
+
+        We were neglecting to IC the puts to RegExpObject.lastIndex on Octane/regexp,
+        and ended up spending 4.5% of a time profile in operationPutByIdNonStrict.
+
+        ~3% progression on Octane/regexp.
+
+        * runtime/RegExpObject.cpp:
+        (JSC::regExpObjectSetLastIndexStrict):
+        (JSC::regExpObjectSetLastIndexNonStrict):
+        (JSC::RegExpObject::put):
+
+2014-10-31  Chris Dumez  <cdumez@apple.com>
+
+        Fix a couple of warnings in JSC reported by clang static analyzer
+        https://bugs.webkit.org/show_bug.cgi?id=138240
+
+        Reviewed by Geoffrey Garen.
+
+        Fix a couple of warnings in JSC reported by clang static analyzer about
+        value stored in variables never being read. This is addressed by
+        reducing the scope of the variable or removing the variable entirely.
+
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
+        * runtime/VM.cpp:
+        (JSC::VM::throwException):
+
+2014-10-30  Dana Burkart  <dburkart@apple.com>
+
+        <rdar://problem/18821260> Prepare for the mysterious future
+
+        Reviewed by Lucas Forschler.
+
+        * Configurations/Base.xcconfig:
+        * Configurations/DebugRelease.xcconfig:
+        * Configurations/FeatureDefines.xcconfig:
+        * Configurations/Version.xcconfig:
+
+2014-10-30  Saam Barati  <saambarati1@gmail.com>
+
+        AST Nodes should keep track of their end offset
+        https://bugs.webkit.org/show_bug.cgi?id=138143
+
+        Reviewed by Filip Pizlo.
+
+        AST nodes nodes now have an int property for their end text 
+        offsets. This change lays some foundational work that will be 
+        needed in profiling which basic blocks have executed.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::setEndOffset):
+        * parser/Nodes.h:
+        (JSC::Node::endOffset):
+        (JSC::Node::setEndOffset):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseStatement):
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseExpression):
+        (JSC::Parser<LexerType>::parseProperty):
+        * parser/Parser.h:
+        (JSC::Parser<LexerType>::parse):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::operatorStackPop):
+
+2014-10-30  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Generate ObjC inspector protocol types and alternate dispatcher interfaces
+        https://bugs.webkit.org/show_bug.cgi?id=138048
+
+        Reviewed by Brian Burg.
+
+        Generate Objective-C interfaces for inspector protocol types, command, and event dispatchers.
+        This is very much like the InspectorProtocolTypes, BackendDispatchers, and FrontendDispatchers,
+        but with an ObjC spin on things.
+
+        The private API that clients would use is all encapsulated in RWIProtocol.h. It includes the
+        types interfaces, command handler protocol, and event dispatcher interface. Where possible the
+        API uses real enums, which hides the raw protocol enum strings from clients.
+
+        Inspector protocol types are, like InspectorProtocolObjects, built on top of an InspectorObject.
+        This offers the flexibilty of adding arbitrary key/values using the RWIProtocolJSONObject
+        interface, which may be required for certain protocol objects like "Network.Headers" which
+        have no fields, but expect arbitrary properties to be added.
+
+        Command handler protocols always have two callbacks. An error callback and a success callback.
+        The signature is very much like BackendDispatchers. In parameters are passed directly to
+        the selectors, and out parameters are defined by the success callback. It will be the client's
+        responsibility to call either of these callbacks to complete handling of a request.
+
+        Event dispatcher interfaces are straight forward, just packaging up the arguments and sending
+        the message to the frontend.
+
+        ObjC <-> Protocol conversion happens in each of the generated files. In type getters / setters,
+        in commands parameters and event parameters. For this to work we generate conversion helpers
+        for all enums, ObjC enum <-> protocol strings. For NSArray <-> InspectorArray there are some
+        static helpers to do the conversions. We do lose some type safety in these conversions.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/scripts/codegen/__init__.py:
+        * inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py:
+        (AlternateBackendDispatcherHeaderGenerator._generate_handler_declarations_for_domain):
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator._generate_alternate_handler_forward_declarations_for_domains.AlternateInspector):
+        (BackendDispatcherHeaderGenerator._generate_handler_declarations_for_domain):
+        (BackendDispatcherHeaderGenerator._generate_dispatcher_declarations_for_domain):
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator._generate_handler_class_destructor_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementations_for_domain):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_header.py:
+        (FrontendDispatcherHeaderGenerator._generate_dispatcher_declarations_for_domain):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py:
+        (FrontendDispatcherImplementationGenerator._generate_dispatcher_implementations_for_domain):
+        * inspector/scripts/codegen/generate_objective_c.py: Added.
+        (join_type_and_name):
+        (strip_comment_markers):
+        (remove_duplicate_from_str):
+        (ObjCTypeCategory):
+        (ObjCTypeCategory.category_of_type):
+        (ObjCGenerator):
+        (ObjCGenerator.identifier_to_objc_identifier):
+        (ObjCGenerator.objc_identifier_to_identifier):
+        (ObjCGenerator.should_generate_domain_types_filter):
+        (ObjCGenerator.should_generate_domain_types_filter.should_generate_domain_types):
+        (ObjCGenerator.should_generate_domain_command_handler_filter):
+        (ObjCGenerator.should_generate_domain_command_handler_filter.should_generate_domain_command_handler):
+        (ObjCGenerator.should_generate_domain_event_dispatcher_filter):
+        (ObjCGenerator.should_generate_domain_event_dispatcher_filter.should_generate_domain_event_dispatcher):
+        (ObjCGenerator.objc_name_for_type):
+        (ObjCGenerator.objc_enum_name_for_anonymous_enum_declaration):
+        (ObjCGenerator.objc_enum_name_for_anonymous_enum_member):
+        (ObjCGenerator.objc_enum_name_for_anonymous_enum_parameter):
+        (ObjCGenerator.objc_enum_name_for_non_anonymous_enum):
+        (ObjCGenerator.variable_name_prefix_for_domain):
+        (ObjCGenerator.objc_accessor_type_for_raw_name):
+        (ObjCGenerator.objc_type_for_raw_name):
+        (ObjCGenerator.objc_class_for_raw_name):
+        (ObjCGenerator.protocol_type_for_raw_name):
+        (ObjCGenerator.protocol_type_for_type):
+        (ObjCGenerator.objc_class_for_type):
+        (ObjCGenerator.objc_accessor_type_for_member):
+        (ObjCGenerator.objc_accessor_type_for_member_internal):
+        (ObjCGenerator.objc_type_for_member):
+        (ObjCGenerator.objc_type_for_member_internal):
+        (ObjCGenerator.objc_type_for_param):
+        (ObjCGenerator.objc_type_for_param_internal):
+        (ObjCGenerator.objc_protocol_export_expression_for_variable):
+        (ObjCGenerator.objc_protocol_import_expression_for_member):
+        (ObjCGenerator.objc_protocol_import_expression_for_parameter):
+        (ObjCGenerator.objc_protocol_import_expression_for_variable):
+        (ObjCGenerator.objc_to_protocol_expression_for_member):
+        (ObjCGenerator.protocol_to_objc_expression_for_member):
+        (ObjCGenerator.objc_setter_method_for_member):
+        (ObjCGenerator.objc_setter_method_for_member_internal):
+        (ObjCGenerator.objc_getter_method_for_member):
+        (ObjCGenerator.objc_getter_method_for_member_internal):
+        * inspector/scripts/codegen/generate_objective_c_backend_dispatcher_header.py: Copied from Source/JavaScriptCore/inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py.
+        (ObjectiveCBackendDispatcherHeaderGenerator):
+        (ObjectiveCBackendDispatcherHeaderGenerator.output_filename):
+        (ObjectiveCBackendDispatcherHeaderGenerator.domains_to_generate):
+        (ObjectiveCBackendDispatcherHeaderGenerator.generate_output):
+        (ObjectiveCBackendDispatcherHeaderGenerator._generate_objc_forward_declarations):
+        (ObjectiveCBackendDispatcherHeaderGenerator._generate_objc_forward_declarations_for_domains):
+        (ObjectiveCBackendDispatcherHeaderGenerator._generate_objc_handler_declarations_for_domain):
+        (ObjectiveCBackendDispatcherHeaderGenerator._generate_objc_handler_declaration_for_command):
+        * inspector/scripts/codegen/generate_objective_c_backend_dispatcher_implementation.py: Added.
+        (ObjectiveCConfigurationImplementationGenerator):
+        (ObjectiveCConfigurationImplementationGenerator.__init__):
+        (ObjectiveCConfigurationImplementationGenerator.output_filename):
+        (ObjectiveCConfigurationImplementationGenerator.domains_to_generate):
+        (ObjectiveCConfigurationImplementationGenerator.generate_output):
+        (ObjectiveCConfigurationImplementationGenerator._generate_handler_implementation_for_domain):
+        (ObjectiveCConfigurationImplementationGenerator._generate_handler_implementation_for_command):
+        (ObjectiveCConfigurationImplementationGenerator._generate_success_block_for_command):
+        (ObjectiveCConfigurationImplementationGenerator._generate_conversions_for_command):
+        (ObjectiveCConfigurationImplementationGenerator._generate_invocation_for_command):
+        * inspector/scripts/codegen/generate_objective_c_configuration_header.py: Copied from Source/JavaScriptCore/inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py.
+        (ObjectiveCConfigurationHeaderGenerator):
+        (ObjectiveCConfigurationHeaderGenerator.output_filename):
+        (ObjectiveCConfigurationHeaderGenerator.generate_output):
+        (ObjectiveCConfigurationHeaderGenerator._generate_configuration_interface_for_domains):
+        (ObjectiveCConfigurationHeaderGenerator._generate_properties_for_domain):
+        * inspector/scripts/codegen/generate_objective_c_configuration_implementation.py: Added.
+        (ObjectiveCBackendDispatcherImplementationGenerator):
+        (ObjectiveCBackendDispatcherImplementationGenerator.__init__):
+        (ObjectiveCBackendDispatcherImplementationGenerator.output_filename):
+        (ObjectiveCBackendDispatcherImplementationGenerator.generate_output):
+        (ObjectiveCBackendDispatcherImplementationGenerator._generate_configuration_implementation_for_domains):
+        (ObjectiveCBackendDispatcherImplementationGenerator._generate_ivars):
+        (ObjectiveCBackendDispatcherImplementationGenerator._generate_dealloc):
+        (ObjectiveCBackendDispatcherImplementationGenerator._generate_handler_setter_for_domain):
+        (ObjectiveCBackendDispatcherImplementationGenerator._generate_event_dispatcher_getter_for_domain):
+        * inspector/scripts/codegen/generate_objective_c_conversion_helpers.py: Added.
+        (add_whitespace_separator):
+        (ObjectiveCConversionHelpersGenerator):
+        (ObjectiveCConversionHelpersGenerator.__init__):
+        (ObjectiveCConversionHelpersGenerator.output_filename):
+        (ObjectiveCConversionHelpersGenerator.domains_to_generate):
+        (ObjectiveCConversionHelpersGenerator.generate_output):
+        (ObjectiveCConversionHelpersGenerator._generate_enum_conversion_functions):
+        (ObjectiveCConversionHelpersGenerator._generate_anonymous_enum_conversion_for_declaration):
+        (ObjectiveCConversionHelpersGenerator._generate_anonymous_enum_conversion_for_member):
+        (ObjectiveCConversionHelpersGenerator._generate_anonymous_enum_conversion_for_parameter):
+        (ObjectiveCConversionHelpersGenerator._generate_enum_objc_to_protocol_string):
+        (ObjectiveCConversionHelpersGenerator._generate_enum_from_protocol_string):
+        * inspector/scripts/codegen/generate_objective_c_frontend_dispatcher_implementation.py: Added.
+        (ObjectiveCFrontendDispatcherImplementationGenerator):
+        (ObjectiveCFrontendDispatcherImplementationGenerator.__init__):
+        (ObjectiveCFrontendDispatcherImplementationGenerator.output_filename):
+        (ObjectiveCFrontendDispatcherImplementationGenerator.domains_to_generate):
+        (ObjectiveCFrontendDispatcherImplementationGenerator.generate_output):
+        (ObjectiveCFrontendDispatcherImplementationGenerator._generate_event_dispatcher_implementations):
+        (ObjectiveCFrontendDispatcherImplementationGenerator._generate_event):
+        (ObjectiveCFrontendDispatcherImplementationGenerator._generate_event_signature):
+        (ObjectiveCFrontendDispatcherImplementationGenerator._generate_event_out_parameters):
+        * inspector/scripts/codegen/generate_objective_c_header.py: Added.
+        (add_whitespace_separator):
+        (ObjectiveCHeaderGenerator):
+        (ObjectiveCHeaderGenerator.__init__):
+        (ObjectiveCHeaderGenerator.output_filename):
+        (ObjectiveCHeaderGenerator.generate_output):
+        (ObjectiveCHeaderGenerator._generate_forward_declarations):
+        (ObjectiveCHeaderGenerator._generate_enums):
+        (ObjectiveCHeaderGenerator._generate_types):
+        (ObjectiveCHeaderGenerator._generate_anonymous_enum_for_declaration):
+        (ObjectiveCHeaderGenerator._generate_anonymous_enum_for_member):
+        (ObjectiveCHeaderGenerator._generate_anonymous_enum_for_parameter):
+        (ObjectiveCHeaderGenerator._generate_enum):
+        (ObjectiveCHeaderGenerator._generate_enum.NS_ENUM):
+        (ObjectiveCHeaderGenerator._generate_type_interface):
+        (ObjectiveCHeaderGenerator._generate_init_method_for_required_members):
+        (ObjectiveCHeaderGenerator._generate_member_property):
+        (ObjectiveCHeaderGenerator._generate_command_protocols):
+        (ObjectiveCHeaderGenerator._generate_single_command_protocol):
+        (ObjectiveCHeaderGenerator._callback_block_for_command):
+        (ObjectiveCHeaderGenerator._generate_event_interfaces):
+        (ObjectiveCHeaderGenerator._generate_single_event_interface):
+        * inspector/scripts/codegen/generate_objective_c_internal_header.py: Copied from Source/JavaScriptCore/inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py.
+        (ObjectiveCTypesInternalHeaderGenerator):
+        (ObjectiveCTypesInternalHeaderGenerator.output_filename):
+        (ObjectiveCTypesInternalHeaderGenerator.generate_output):
+        (ObjectiveCTypesInternalHeaderGenerator._generate_event_dispatcher_private_interfaces):
+        * inspector/scripts/codegen/generate_objective_c_types_implementation.py: Added.
+        (add_whitespace_separator):
+        (ObjectiveCTypesImplementationGenerator):
+        (ObjectiveCTypesImplementationGenerator.__init__):
+        (ObjectiveCTypesImplementationGenerator.output_filename):
+        (ObjectiveCTypesImplementationGenerator.domains_to_generate):
+        (ObjectiveCTypesImplementationGenerator.generate_output):
+        (ObjectiveCTypesImplementationGenerator.generate_type_implementations):
+        (ObjectiveCTypesImplementationGenerator.generate_type_implementation):
+        (ObjectiveCTypesImplementationGenerator._generate_init_method_for_required_members):
+        (ObjectiveCTypesImplementationGenerator._generate_setter_for_member):
+        (ObjectiveCTypesImplementationGenerator._generate_getter_for_member):
+        * inspector/scripts/codegen/generate_protocol_types_header.py:
+        (ProtocolTypesHeaderGenerator._generate_forward_declarations):
+        (_generate_typedefs_for_domain):
+        (_generate_builders_for_domain):
+        * inspector/scripts/codegen/generator.py:
+        (Generator.wrap_with_guard_for_domain):
+        (Generator):
+        (Generator.wrap_with_guard):
+        * inspector/scripts/codegen/generator_templates.py:
+        (AlternateInspector):
+        (ObjCInspector):
+        * inspector/scripts/codegen/models.py:
+        (Framework.fromString):
+        (Frameworks):
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        (generate_from_specification):
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+
+2014-10-30  Andreas Kling  <akling@apple.com>
+
+        Unreviewed assertion fix.
+
+        RegExpCachedResult::m_reified is now the dedicated member that knows whether
+        the result was reified into an array or not. Check that instead of m_result
+        which is now single-purpose.
+
+        * runtime/RegExpCachedResult.cpp:
+        (JSC::RegExpCachedResult::setInput):
+
+2014-10-29  Andreas Kling  <akling@apple.com>
+
+        Use plain JSArray for RegExp matches instead of a lazily populated custom object.
+        <https://webkit.org/b/138191>
+
+        Reviewed by Geoffrey Garen.
+
+        We're already offering two RegExp matching APIs, one that collects subpattern
+        matches (exec), and one that simply tests for a match (test).
+        Given that, it was pretty overkill to lazily populate the resulting array of
+        matches, since the user could simply use test() if they didn't need them.
+
+        This allows the JIT to generate better code for RegExp match arrays, and also
+        enables some fast paths in the JSC runtime that check if an object isJSArray().
+
+        Looks like ~1.5% improvement on Octane/regexp according to run-jsc-benchmarks.
+
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        * runtime/JSArray.h:
+        (JSC::createArrayButterflyWithExactLength): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/RegExpCachedResult.cpp:
+        (JSC::RegExpCachedResult::visitChildren):
+        (JSC::RegExpCachedResult::lastResult):
+        (JSC::RegExpCachedResult::leftContext):
+        (JSC::RegExpCachedResult::rightContext):
+        * runtime/RegExpCachedResult.h:
+        (JSC::RegExpCachedResult::RegExpCachedResult):
+        (JSC::RegExpCachedResult::record):
+        (JSC::RegExpCachedResult::input):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::getBackref):
+        (JSC::RegExpConstructor::getLastParen):
+        (JSC::RegExpConstructor::getLeftContext):
+        (JSC::RegExpConstructor::getRightContext):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+        (JSC::RegExpMatchesArray::RegExpMatchesArray): Deleted.
+        (JSC::RegExpMatchesArray::create): Deleted.
+        (JSC::RegExpMatchesArray::finishCreation): Deleted.
+        (JSC::RegExpMatchesArray::visitChildren): Deleted.
+        (JSC::RegExpMatchesArray::reifyAllProperties): Deleted.
+        (JSC::RegExpMatchesArray::reifyMatchProperty): Deleted.
+        (JSC::RegExpMatchesArray::leftContext): Deleted.
+        (JSC::RegExpMatchesArray::rightContext): Deleted.
+        * runtime/RegExpMatchesArray.h:
+        (JSC::RegExpMatchesArray::createStructure): Deleted.
+        (JSC::RegExpMatchesArray::reifyAllPropertiesIfNecessary): Deleted.
+        (JSC::RegExpMatchesArray::reifyMatchPropertyIfNecessary): Deleted.
+        (JSC::RegExpMatchesArray::getOwnPropertySlot): Deleted.
+        (JSC::RegExpMatchesArray::getOwnPropertySlotByIndex): Deleted.
+        (JSC::RegExpMatchesArray::put): Deleted.
+        (JSC::RegExpMatchesArray::putByIndex): Deleted.
+        (JSC::RegExpMatchesArray::deleteProperty): Deleted.
+        (JSC::RegExpMatchesArray::deletePropertyByIndex): Deleted.
+        (JSC::RegExpMatchesArray::getOwnPropertyNames): Deleted.
+        (JSC::RegExpMatchesArray::defineOwnProperty): Deleted.
+        (JSC::isRegExpMatchesArray): Deleted.
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::exec):
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncMatch):
+
+2014-10-29  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Fix Type Dependency Issues
+        https://bugs.webkit.org/show_bug.cgi?id=125664
+
+        Reviewed by Brian Burg.
+
+        Now that all JSON protocol files are processed together again
+        in r174892, we can remove the duplicated types which were only
+        needed when the domains were split.
+
+        * inspector/protocol/Console.json:
+        * inspector/protocol/Runtime.json:
+
+2014-10-28  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r175249.
+        https://bugs.webkit.org/show_bug.cgi?id=138138
+
+        Appears to be failing some JS tests (Requested by mlam_ on
+        #webkit).
+
+        Reverted changeset:
+
+        "Holes are not copied properly when Arrays change shape to
+        ArrayStorage type."
+        https://bugs.webkit.org/show_bug.cgi?id=138118
+        http://trac.webkit.org/changeset/175249
+
+2014-10-27  Mark Lam  <mark.lam@apple.com>
+
+        Holes are not copied properly when Arrays change shape to ArrayStorage type.
+        <https://webkit.org/b/138118>
+
+        Reviewed by Mark Hahnenberg.
+
+        When we convert non-ArrayStorage typed arrays into ArrayStorage typed arrays,
+        we skipped the holes.  As a result, the slots in the ArrayStorage vector that
+        corresponds to those holes are uninitialize.  This is now fixed.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertUndecidedToArrayStorage):
+        (JSC::JSObject::convertInt32ToArrayStorage):
+        (JSC::JSObject::convertDoubleToArrayStorage):
+        (JSC::JSObject::convertContiguousToArrayStorage):
+
+2014-10-27  Mark Lam  <mark.lam@apple.com>
+
+        Crash when attempting to perform array iteration on a non-array with numeric keys not initialized.
+        <https://webkit.org/b/137814>
+
+        Reviewed by Geoffrey Garen.
+
+        The arrayIteratorNextThunkGenerator() thunk was not checking for the case where
+        the butterfly may be NULL.  This was the source of the crash, and is now fixed.
+
+        In addition, it is also not checking for the case where a property named "length"
+        may have been set on the iterated object.  The thunk only checks the butterfly's
+        publicLength for its iteration operation.  Array objects will work fine with this
+        because it always updates its butterfly's publicLength when its length changes.
+        In the case of iterable non-Array objects, the "length" property will require a
+        look up outside of the scope of this thunk.  The fix is simply to limit the fast
+        case checks in this thunk to Array objects.
+
+        * jit/ThunkGenerators.cpp:
+        (JSC::arrayIteratorNextThunkGenerator):
+
+2014-10-27  Mark Lam  <mark.lam@apple.com>
+
+        Simplified some JSObject methods for converting arrays to ArrayStorage shape.
+        <https://webkit.org/b/138119>
+
+        Reviewed by Filip Pizlo.
+
+        Currently, for each Undecided, Int32, Double, and Contiguous array shapes,
+        there are 3 JSObject methods to convert them to ArrayStorage shape:
+            ArrayStorage* convert<shape>ToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
+            ArrayStorage* convert<shape>ToArrayStorage(VM&, NonPropertyTransition);
+            ArrayStorage* convert<shape>ToArrayStorage(VM&);
+
+        However, the neededLength that is passed is always m_butterfly->vectorLength().
+        Hence, the method that takes a neededLength is really not needed.  This patch
+        removes this unneeded verbosity.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertUndecidedToArrayStorage):
+        (JSC::JSObject::convertInt32ToArrayStorage):
+        - Also reordered the placement of the DeferGC statement so this Int32 function
+          will look more similar to the others.
+        (JSC::JSObject::convertDoubleToArrayStorage):
+        (JSC::JSObject::convertContiguousToArrayStorage):
+        * runtime/JSObject.h:
+
+2014-10-25  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Unreviewed, follow-up fix after r175203. The debugger agent should not assume
+        that the inspector environment's stopwatch has already been started.
+
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::didPause): Check if the stopwatch isActive() before stopping.
+
+2014-10-18  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        Now that we have a stopwatch to provide pause-aware timing data, we can remove the
+        profiler's handling of debugger pause/continue callbacks. The debugger agent accounts
+        for suspended execution by pausing and resuming the stopwatch.
+
+        * API/JSProfilerPrivate.cpp:
+        (JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
+        * inspector/InspectorEnvironment.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::executionStopwatch):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handlePause):
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::didPause):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        (Inspector::InspectorDebuggerAgent::didContinue):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::profiler): Use nullptr.
+        (JSC::LegacyProfiler::startProfiling): Hand off a stopwatch to the profile generator.
+        (JSC::LegacyProfiler::stopProfiling): Use nullptr.
+        (JSC::LegacyProfiler::didPause): Deleted.
+        (JSC::LegacyProfiler::didContinue): Deleted.
+        * profiler/LegacyProfiler.h:
+        * profiler/Profile.cpp: The root node should always have a start time of 0.0.
+        (JSC::Profile::Profile):
+        * profiler/ProfileGenerator.cpp: Remove debugger pause/continue callbacks and the
+        timestamp member that was used to track time elapsed by the debugger. Just use the
+        stopwatch's elapsed times to generate start/elapsed times for function calls.
+
+        (JSC::ProfileGenerator::create):
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::AddParentForConsoleStartFunctor::operator()): The parent node of |console.profile|
+        should have a start time of 0.0, since it represents the starting node of profiling.
+
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause): Deleted.
+        (JSC::ProfileGenerator::didContinue): Deleted.
+        * profiler/ProfileGenerator.h:
+
+2014-10-24  Mark Lam  <mark.lam@apple.com>
+
+        Simplified IndexingType's hasAnyArrayStorage().
+        <https://webkit.org/b/138051>
+
+        Reviewed by Michael Saboff.
+
+        IndexingType's hasAnyArrayStorage() currently does subtraction of ArrayStorageShape
+        with the purpose of making non-ArrayStorage types underflow (with that subtraction)
+        and have a result that exceeds SlowPutArrayStorageShape.  What it is doing is
+        basically checking for a shape value that is greater equal to ArrayStorageShape.
+        We can just simplify the code as such.
+
+        Also added a comment to describe the structure of the bits in IndexingType.
+
+        * runtime/IndexingType.h:
+        (JSC::hasAnyArrayStorage):
+
+2014-10-23  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Provide a way to have alternate inspector agents
+        https://bugs.webkit.org/show_bug.cgi?id=137901
+
+        Reviewed by Brian Burg.
+
+        Provide a way to use alternate inspector agents debugging a JSContext.
+        Expose a very slim private API that a client could use to know when
+        an inspector has connected/disconnected, and a way to register its
+        augmentative agents.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        New feature guard. New files.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextGetAugmentableInspectorController):
+        * API/JSContextRefInspectorSupport.h: Added.
+        Access to the private interface from a JSContext.
+
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/augmentable/AugmentableInspectorController.h: Added.
+        (Inspector::AugmentableInspectorController::~AugmentableInspectorController):
+        (Inspector::AugmentableInspectorController::connected):
+        * inspector/augmentable/AugmentableInspectorControllerClient.h: Added.
+        (Inspector::AugmentableInspectorControllerClient::~AugmentableInspectorControllerClient):
+        * inspector/augmentable/AlternateDispatchableAgent.h: Added.
+        (Inspector::AlternateDispatchableAgent::AlternateDispatchableAgent):
+        Provide the private APIs a client could use to add alternate agents using alternate backend dispatchers.
+
+        * inspector/scripts/codegen/__init__.py:
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        (generate_from_specification):
+        New includes, and use the new generator.
+        
+        * inspector/scripts/codegen/generate_alternate_backend_dispatcher_header.py: Added.
+        (AlternateBackendDispatcherHeaderGenerator):
+        (AlternateBackendDispatcherHeaderGenerator.__init__):
+        (AlternateBackendDispatcherHeaderGenerator.output_filename):
+        (AlternateBackendDispatcherHeaderGenerator.generate_output):
+        (AlternateBackendDispatcherHeaderGenerator._generate_handler_declarations_for_domain):
+        (AlternateBackendDispatcherHeaderGenerator._generate_handler_declaration_for_command):
+        Generate the abstract AlternateInspectorBackendDispatcher interfaces.
+
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator.generate_output):
+        (BackendDispatcherHeaderGenerator._generate_alternate_handler_forward_declarations_for_domains):
+        (BackendDispatcherHeaderGenerator._generate_alternate_handler_forward_declarations_for_domains.AlternateInspector):
+        Forward declare alternate dispatchers, and allow setting an alternate dispatcher on a domain dispatcher.
+
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator.generate_output):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        Check for and dispatch on an AlternateInspectorBackendDispatcher if there is one for this domain.
+
+        * inspector/scripts/codegen/generator_templates.py:
+        (AlternateInspectorBackendDispatcher):
+        (AlternateInspector):
+        Template boilerplate for prelude and postlude.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        Rebaseline tests.
+
+2014-10-23  Michael Saboff  <msaboff@apple.com>
+
+        offsets.rb:183:in `buildOffsetsMap': unhandled exception - is offlineasm dependency tracking broken? (132668)
+        https://bugs.webkit.org/show_bug.cgi?id=138017
+
+        Reviewed by Mark Lam.
+
+        Removed from the nput file $(SRCROOT)/llint/LowLevelAssembler.asm and output file
+        $(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h from the Generate Derived Sources
+        build phase in the LLInt Offset target.  There is no need for Xcode to do any dependency
+        checking with these files as the ruby script offlineasm/generate_offset_extractor.rb will
+        do that for us.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2014-10-23  Michael Saboff  <msaboff@apple.com>
+
+        Change CallFrame::lexicalGlobalObject() to use Callee instead of JSScope
+        https://bugs.webkit.org/show_bug.cgi?id=136901
+
+        Reviewed by Mark Lam.
+
+        Implement ExecState::lexicalGlobalObject() using Callee.
+        
+        * runtime/JSScope.h:
+        (JSC::ExecState::lexicalGlobalObject):
+
+2014-10-22  Milan Crha  <mcrha@redhat.com>
+
+        Prefix isnan() with std::.
+        <https://webkit.org/b/137966>.
+
+        Reviewed by Carlos Garcia Campos.
+
+        * profiler/ProfileNode.h:
+        (JSC::ProfileNode::Call::setStartTime):
+        (JSC::ProfileNode::Call::setElapsedTime):
+
+2014-10-22  Mark Lam  <mark.lam@apple.com>
+
+        Refactoring to simplify some code in DatePrototype.cpp.
+        <https://webkit.org/b/137997>
+
+        Reviewed by Filip Pizlo.
+
+        A bunch of functions in DatePrototype.cpp have the pattern of loading a
+        constant into a local variable only to pass it to a callee function
+        immediately after.  There is no other use for that variable.  This adds
+        additional verbosity with no added benefit.
+
+        This patch refactors those functions to just pass the constant arg directly.
+
+        * runtime/DatePrototype.cpp:
+        (JSC::dateProtoFuncSetMilliSeconds):
+        (JSC::dateProtoFuncSetUTCMilliseconds):
+        (JSC::dateProtoFuncSetSeconds):
+        (JSC::dateProtoFuncSetUTCSeconds):
+        (JSC::dateProtoFuncSetMinutes):
+        (JSC::dateProtoFuncSetUTCMinutes):
+        (JSC::dateProtoFuncSetHours):
+        (JSC::dateProtoFuncSetUTCHours):
+        (JSC::dateProtoFuncSetDate):
+        (JSC::dateProtoFuncSetUTCDate):
+        (JSC::dateProtoFuncSetMonth):
+        (JSC::dateProtoFuncSetUTCMonth):
+        (JSC::dateProtoFuncSetFullYear):
+        (JSC::dateProtoFuncSetUTCFullYear):
+
+2014-10-22  Byungseon Shin  <sun.shin@lge.com>
+
+        String(new Date(Mar 30 2014 01:00:00)) is wrong in CET
+        https://bugs.webkit.org/show_bug.cgi?id=130967
+
+        Reviewed by Mark Lam.
+
+        By definition of calculateLocalTimeOffset, input time should be UTC time.
+        But there are many cases when input time is based on local time.
+        So, it gives erroneous results while calculating offset of DST boundary time.
+        By adding a argument to distinguish UTC and local time, we can get the correct offset.
+
+        * JavaScriptCore.order:
+        * runtime/DateConstructor.cpp:
+        (JSC::constructDate):
+        (JSC::callDate):
+        (JSC::dateUTC):
+        * runtime/DateInstance.cpp:
+        (JSC::DateInstance::calculateGregorianDateTime):
+        (JSC::DateInstance::calculateGregorianDateTimeUTC):
+        * runtime/DatePrototype.cpp:
+        (JSC::setNewValueFromTimeArgs):
+        (JSC::setNewValueFromDateArgs):
+        (JSC::dateProtoFuncSetMilliSeconds):
+        (JSC::dateProtoFuncSetUTCMilliseconds):
+        (JSC::dateProtoFuncSetSeconds):
+        (JSC::dateProtoFuncSetUTCSeconds):
+        (JSC::dateProtoFuncSetMinutes):
+        (JSC::dateProtoFuncSetUTCMinutes):
+        (JSC::dateProtoFuncSetHours):
+        (JSC::dateProtoFuncSetUTCHours):
+        (JSC::dateProtoFuncSetDate):
+        (JSC::dateProtoFuncSetUTCDate):
+        (JSC::dateProtoFuncSetMonth):
+        (JSC::dateProtoFuncSetUTCMonth):
+        (JSC::dateProtoFuncSetFullYear):
+        (JSC::dateProtoFuncSetUTCFullYear):
+        (JSC::dateProtoFuncSetYear):
+        * runtime/JSDateMath.cpp:
+        (JSC::localTimeOffset):
+        (JSC::gregorianDateTimeToMS):
+        (JSC::msToGregorianDateTime):
+        (JSC::parseDateFromNullTerminatedCharacters):
+        * runtime/JSDateMath.h:
+        * runtime/VM.h:
+        (JSC::LocalTimeOffsetCache::LocalTimeOffsetCache):
+        (JSC::LocalTimeOffsetCache::reset):
+        Passing TimeType argument to distingush UTC time and local time.
+
+2014-10-22  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Fix generator importing of protocol type "any", treat as value
+        https://bugs.webkit.org/show_bug.cgi?id=137931
+
+        Reviewed by Timothy Hatcher.
+
+        Treat incoming "any" objects as InspectorValues, which can be any type.
+        Add the necessary boilerplate to import.
+
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::AsMethodBridges::asValue):
+        (Inspector::InspectorBackendDispatcher::getValue):
+        * inspector/InspectorBackendDispatcher.h:
+        * inspector/scripts/codegen/generator.py:
+        (Generator.keyed_get_method_for_type):
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+
+2014-10-22  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r174996): Broke C_LOOP
+        https://bugs.webkit.org/show_bug.cgi?id=137971
+
+        Reviewed by Mark Lam.
+
+        Removed incorrect move to cfr (CallFrameRegister) before we make the call to a native function.
+        After r174996, the source register for the move contained garbage causing the crash.  The move
+        to cfr before making the call to the native function is wrong and should have been removed
+        some time ago.  This brings the ARM64 / C_LOOP code path inline with the other CPU paths.
+        Tested on ARM64 as well as a C_LOOP build.
+
+        * llint/LowLevelInterpreter64.asm:
+
+2014-10-21  Mark Lam  <mark.lam@apple.com>
+
+        Remove erroneous canUseJIT() in the intrinsics version of JITThunks::hostFunctionStub().
+        <https://webkit.org/b/137937>
+
+        Reviewed by Michael Saboff.
+
+        This version of JITThunks::hostFunctionStub() can only be called from the intrinsics
+        version of VM::getHostFunction() which asserts canUseJIT().  Hence, we can eliminate
+        the canUseJIT() check in JITThunks::hostFunctionStub().  We don't handle the
+        !canUseJIT() case properly there anyway.
+
+        * jit/JITThunks.cpp:
+        (JSC::JITThunks::hostFunctionStub):
+
+2014-10-21  Michael Saboff  <msaboff@apple.com>
+
+        Add operator==(PropertyName, const char*)
+        https://bugs.webkit.org/show_bug.cgi?id=137925
+
+        Reviewed by Mark Lam.
+
+        * runtime/PropertyName.h:
+        (JSC::operator==): Added to simplify comparison with string literals.
+
+
+2014-10-21  Michael Saboff  <msaboff@apple.com>
+
+        Change native call frames to use the scope from their Callee instead of their caller's scope
+        https://bugs.webkit.org/show_bug.cgi?id=137907
+
+        Reviewed by Mark Lam.
+
+        Changed setting of scope for native CallFrames to use the scope associated with the
+        Callee instead of the caller's scope.
+
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
+2014-10-21  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Add missing ENABLE(FTL_NATIVE_CALL_INLINING) guard to BundlePath.cpp after r174940
+        https://bugs.webkit.org/show_bug.cgi?id=137924
+
+        Reviewed by Csaba Osztrogonác.
+
+        * runtime/BundlePath.cpp:
+
+2014-10-21  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
+
+        Fix FTL Native Inlining for EFL
+        https://bugs.webkit.org/show_bug.cgi?id=137774
+
+        Reviewed by Michael Saboff.
+
+        Added required functionality for Native Inlining to EFL, and fixed a bug/typo in the original code,
+        which caused incorrect memory allocation.
+
+        * CMakeLists.txt:
+        * create-llvm-ir-from-source-file.py: Added.
+        * create-symbol-table-index.py: Added.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        * runtime/BundlePath.cpp: Added.
+        (JSC::bundlePath):
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::getData):
+        (JSC::setData):
+        * runtime/MathObject.cpp:
+
+2014-10-21  Milan Crha  <mcrha@redhat.com>
+
+        Move JSC::MacroAssemblerX86Common::s_sse2CheckState definition to MacroAssemblerX86Common.cpp.
+        <https://webkit.org/b/137807>
+
+        Reviewed by Csaba Osztrogonác.
+
+        * assembler/MacroAssemblerX86Common.cpp:
+        * jit/JIT.cpp:
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed add back copyright line that was accidentally removed.
+
+        * inspector/scripts/codegen/generator_templates.py:
+        (GeneratorTemplates):
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: InspectorBackendCommands should include when to activate particular domains
+        https://bugs.webkit.org/show_bug.cgi?id=137753
+
+        Reviewed by Timothy Hatcher.
+
+        Add an availability property to domains that only activate for
+        particular debuggable types. If missing, the domain is always
+        activated. Otherwise it must be a debuggable type string.
+        When a frontend is opened for that debuggable type, the domain
+        will be activated.
+
+        * inspector/scripts/codegen/models.py:
+        (Protocol.parse_domain):
+        (Domain.__init__):
+        (Domains):
+        Parse and validate the Domain's "availability" property.
+
+        * inspector/scripts/codegen/generate_backend_commands.py:
+        (BackendCommandsGenerator.generate_domain):
+        Emit InspectorBackend.activateDomain with debuggable type filter.
+
+        * inspector/protocol/ApplicationCache.json:
+        * inspector/protocol/CSS.json:
+        * inspector/protocol/DOM.json:
+        * inspector/protocol/DOMDebugger.json:
+        * inspector/protocol/DOMStorage.json:
+        * inspector/protocol/Database.json:
+        * inspector/protocol/IndexedDB.json:
+        * inspector/protocol/LayerTree.json:
+        * inspector/protocol/Network.json:
+        * inspector/protocol/Page.json:
+        * inspector/protocol/Replay.json:
+        * inspector/protocol/Timeline.json:
+        * inspector/protocol/Worker.json:
+        These domains only activate for Web debuggables.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        Update existing tests that now have activate output.
+
+        * inspector/scripts/tests/expected/fail-on-domain-availability.json-error: Added.
+        * inspector/scripts/tests/fail-on-domain-availability.json: Added.
+        Add a test for "availability" validation.
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        [Win] Build fix for generated inspector files.
+
+        Rubberstamped by Brent Fulgham.
+
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator._generate_async_handler_declaration_for_command):
+        * inspector/scripts/codegen/generator_templates.py:
+        (GeneratorTemplates):
+
+2014-10-20  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed build fix.
+
+        We need to (1) pass the 'windows' argument to our script for checking feature definitions,
+        and (2) we must use Cwd::realpath on our path input arguments to avoid Cygwin and Windows
+        getting confused about path separators versus escape characters.
+
+
+        * JavaScriptCore.vcxproj/build-generated-files.pl:
+
+2014-10-20  Mark Lam  <mark.lam@apple.com>
+
+        [Follow up] Web Process crash when starting the web inspector after r174025.
+        <https://webkit.org/b/137340>
+
+        Reviewed by Geoffrey Garen.
+
+        Applied Geoff's feedback to clean up some code for better clarity after
+        r174856.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::insertCheck):
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertOutOfOrder):
+
+2014-10-20  Mark Lam  <mark.lam@apple.com>
+
+        Factor out JITCode::typeName() for debugging use.
+        <https://webkit.org/b/137888>
+
+        Reviewed by Geoffrey Garen.
+
+        JITCode's printInternal() currently decodes the JITType into a string and
+        prints it.  This change factors out the part that decodes the JITType into
+        JITCode::typeName() so that we can call it from lldb while debugging to
+        quickly decode a JITType value.
+
+        * jit/JITCode.cpp:
+        (JSC::JITCode::typeName):
+        (WTF::printInternal):
+        * jit/JITCode.h:
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed Windows Build Fix #2 after r174892.
+
+        * JavaScriptCore.vcxproj/build-generated-files.pl:
+        Define FEATURE_DEFINES for JavaScriptCore's DerivedSources.make.
+        This uses the same technique as WebCore.
+
+2014-10-20  Mark Lam  <mark.lam@apple.com>
+
+        Fix placement of a few items in vcxproj ItemGroups.
+        <https://webkit.org/b/137886>
+
+        Reviewed by Geoffrey Garen.
+
+        https://webkit.org/b/137873 is likely a cut-and-paste error that manifested
+        because we had ClCompile and ClInclude entries mixed up in the wrong ItemGroups.
+        We should fix these so that ClCompile entries are in the ClCompile ItemGroup,
+        and ClInclude entries in the ClInclude ItemGroup.  This will help reduce the
+        chance of future cut-and-paste errors of this nature.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Unreviewed Windows Build Fix after r174892.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        Update file name to the new generated file name.
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Rename generated Inspector.json to CombinedDomains.json to prevent name collisions
+        https://bugs.webkit.org/show_bug.cgi?id=137825
+
+        Reviewed by Timothy Hatcher.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * inspector/protocol/Inspector.json: Renamed from Source/JavaScriptCore/inspector/protocol/InspectorDomain.json.
+
+2014-10-20  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Generate all Inspector domains together in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=137748
+
+        Reviewed by Brian Burg.
+
+        * inspector/protocol/ApplicationCache.json: Renamed from Source/WebCore/inspector/protocol/ApplicationCache.json.
+        * inspector/protocol/CSS.json: Renamed from Source/WebCore/inspector/protocol/CSS.json.
+        * inspector/protocol/DOM.json: Renamed from Source/WebCore/inspector/protocol/DOM.json.
+        * inspector/protocol/DOMDebugger.json: Renamed from Source/WebCore/inspector/protocol/DOMDebugger.json.
+        * inspector/protocol/DOMStorage.json: Renamed from Source/WebCore/inspector/protocol/DOMStorage.json.
+        * inspector/protocol/Database.json: Renamed from Source/WebCore/inspector/protocol/Database.json.
+        * inspector/protocol/IndexedDB.json: Renamed from Source/WebCore/inspector/protocol/IndexedDB.json.
+        * inspector/protocol/LayerTree.json: Renamed from Source/WebCore/inspector/protocol/LayerTree.json.
+        * inspector/protocol/Network.json: Renamed from Source/WebCore/inspector/protocol/Network.json.
+        * inspector/protocol/Page.json: Renamed from Source/WebCore/inspector/protocol/Page.json.
+        * inspector/protocol/Replay.json: Renamed from Source/WebCore/inspector/protocol/Replay.json.
+        * inspector/protocol/Timeline.json: Renamed from Source/WebCore/inspector/protocol/Timeline.json.
+        * inspector/protocol/Worker.json: Renamed from Source/WebCore/inspector/protocol/Worker.json.
+        Move all protocol files into this directory.
+
+        * inspector/InspectorProtocolTypesBase.h: Renamed from Source/JavaScriptCore/inspector/InspectorProtocolTypes.h.
+        Renamed the base types file to not clash with the generated types file.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.vcxproj/copy-files.cmd:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        Update build phases for new JSON files and new filenames.
+
+        * inspector/scripts/tests/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/expected/events-with-optional-parameters.json-result:
+        * inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/expected/same-type-id-different-domain.json-result:
+        * inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result:
+        * inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result:
+        Updated names of things now that prefixes are no longer needed.
+
+        * inspector/ConsoleMessage.h:
+        * inspector/ContentSearchUtilities.cpp:
+        * inspector/ContentSearchUtilities.h:
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptBase.h:
+        * inspector/ScriptCallFrame.h:
+        * inspector/ScriptCallStack.h:
+        * inspector/agents/InspectorAgent.h:
+        * inspector/agents/InspectorConsoleAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::breakpointActionTypeForString):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * runtime/TypeProfiler.cpp:
+        * runtime/TypeSet.cpp:
+        Update includes and update a few function names that are generated.
+
+        * inspector/scripts/codegen/generate_protocol_types_header.py:
+        (ProtocolTypesHeaderGenerator.output_filename):
+        (ProtocolTypesHeaderGenerator.generate_output):
+        Include an export macro for type string constants defined in the implementation file.
+
+        * inspector/scripts/codegen/generate_backend_commands.py:
+        (BackendCommandsGenerator.output_filename):
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator.output_filename):
+        (BackendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator.output_filename):
+        (BackendDispatcherImplementationGenerator.generate_output):
+        (BackendDispatcherImplementationGenerator._generate_async_dispatcher_class_for_domain):
+        (BackendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_command):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_header.py:
+        (FrontendDispatcherHeaderGenerator.output_filename):
+        (FrontendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py:
+        (FrontendDispatcherImplementationGenerator.output_filename):
+        (FrontendDispatcherImplementationGenerator.generate_output):
+        (FrontendDispatcherImplementationGenerator._generate_dispatcher_implementation_for_event):
+        (_generate_class_for_object_declaration):
+        (_generate_builder_setter_for_member):
+        (_generate_unchecked_setter_for_member):
+        * inspector/scripts/codegen/generate_protocol_types_implementation.py:
+        (ProtocolTypesImplementationGenerator.output_filename):
+        (ProtocolTypesImplementationGenerator.generate_output):
+        (ProtocolTypesImplementationGenerator._generate_enum_mapping):
+        * inspector/scripts/codegen/models.py:
+        (Framework.fromString):
+        (Frameworks):
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        Simplify generator now that prefixes are no longer needed. This updates
+        filenames, includes, and the list of supported directories.
+
+2014-10-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        Remove obsolete comments after r99798
+        https://bugs.webkit.org/show_bug.cgi?id=137871
+
+        Reviewed by Darin Adler.
+
+        r99798 removed the comment in MacroAssemblerARMv7::supportsFloatingPointTruncate(),
+        so we should remove the stale references to this removed comment.
+
+        * assembler/MacroAssemblerX86.h:
+        * assembler/MacroAssemblerX86_64.h:
+
+2014-10-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        MacroAssemblerX86Common.cpp should be built on Windows too
+        https://bugs.webkit.org/show_bug.cgi?id=137873
+
+        Reviewed by Brent Fulgham.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2014-10-20  Csaba Osztrogonác  <ossy@webkit.org>
+
+        [cmake] Remove duplicated source files
+        https://bugs.webkit.org/show_bug.cgi?id=137875
+
+        Reviewed by Gyuyoung Kim.
+
+        * CMakeLists.txt:
+
+2014-10-18  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: code generator shouldn't complain about enums without a storage type if they are in an enclosing scope
+        https://bugs.webkit.org/show_bug.cgi?id=137084
+
+        Reviewed by Joseph Pecoraro.
+
+        In order to generate encode/decode method declarations without pulling in lots of headers,
+        the generator must forward declare enums (for enum classes or enums with explicit sizes).
+
+        Change the generator to not require an explicit size if an enum is declared inside a struct
+        or class definition. In that case, it must pull in headers since scoped enums can't be
+        forward declared.
+
+        This patch also fixes some chained if-statements that should be if-else statements.
+
+        Test: updated replay/scripts/tests/generate-enum-encoding-helpers.json to cover the new case.
+
+        * replay/scripts/CodeGeneratorReplayInputs.py:
+        (InputsModel.parse_type_with_framework_name.is):
+        (InputsModel.parse_type_with_framework_name.is.must):
+        (Generator.generate_enum_trait_implementation):
+        (InputsModel.parse_type_with_framework_name): Deleted.
+        * replay/scripts/CodeGeneratorReplayInputsTemplates.py:
+        * replay/scripts/tests/expected/fail-on-c-style-enum-no-storage.json-error:
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::MouseButton>::decodeValue):
+        (JSC::EncodingTraits<WebCore::PlatformEvent::Type>::encodeValue):
+        (JSC::EncodingTraits<WebCore::PlatformEvent::Type>::decodeValue):
+        * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h:
+        * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.cpp:
+        (JSC::EncodingTraits<WebCore::FormData1::Type>::decodeValue):
+        (JSC::EncodingTraits<PlatformEvent1::Type>::decodeValue):
+        * replay/scripts/tests/generate-enum-encoding-helpers.json: Added a new input to cover this case.
+
+2014-10-17  Mark Lam  <mark.lam@apple.com>
+
+        Web Process crash when starting the web inspector after r174025.
+        <https://webkit.org/b/137340>
+
+        Reviewed by Filip Pizlo.
+
+        After r174025, we can generate a bad graph in the DFG fixup phase like so:
+
+            102:<!0:-> StoreBarrier(Check:KnownCell:@19, ..., bc#44)
+            60:<!0:->  PutStructure(Check:KnownCell:@19, ..., bc#44)
+            103:<!0:-> Check(Check:NotCell:@54, ..., bc#44)
+                    // ^-- PutByOffset's StoreBarrier has been elided and replaced
+                    //     with a speculation check which can OSR exit.
+            61:<!0:->  PutByOffset(Check:KnownCell:@19, ..., bc#44)
+
+        As a result, the structure change will get executed even if we end up OSR
+        exiting before the PutByOffset.  In the baseline JIT code, the structure now
+        erroneously tells the put operation that there is a value in that property
+        slot when it is actually uninitialized (hence, the crash).
+
+        The fix is to insert the Check at the earliest point possible:
+
+        1. If the checked node is in the same bytecode as the PutByOffset, then
+           the earliest point where we can insert the Check is right after the
+           checked node.
+
+        2. If the checked node is from a preceding bytecode (before the PutByOffset),
+           then the earliest point where we can insert the Check is at the start
+           of the current bytecode.
+
+        Also reverted the workaround from r174749: https://webkit.org/b/137758.
+
+        Benchmark results appear to be a wash on aggregate.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::indexOfNode):
+        (JSC::DFG::FixupPhase::indexOfFirstNodeOfExitOrigin):
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::insertCheck):
+        * dfg/DFGInsertionSet.h:
+        (JSC::DFG::InsertionSet::insertOutOfOrder):
+        (JSC::DFG::InsertionSet::insertOutOfOrderNode):
+
+2014-10-10  Oliver Hunt  <oliver@apple.com>
+
+        Various arguments optimisations in codegen fail to account for arguments being in lexical record
+        https://bugs.webkit.org/show_bug.cgi?id=137617
+
+        Reviewed by Michael Saboff.
+
+        Rework the way we track |arguments| references so that we don't try
+        to use the |arguments| reference on the stack if it's not safe.
+
+        To do this without nuking performance it was necessary to update
+        the parser to track modification of the |arguments| reference
+        itself.
+
+        * bytecode/CodeBlock.cpp:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::willResolveToArguments):
+        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::uncheckedRegisterForArguments): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::getArgumentByVal):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::existingArguments):
+        * parser/Nodes.h:
+        (JSC::ScopeNode::modifiesArguments):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        * parser/Parser.h:
+        (JSC::Scope::getCapturedVariables):
+        * parser/ParserModes.h:
+
+2014-10-17  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Use WTF::move() instead of std::move() to help ensure move semantics in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=137809
+
+        Reviewed by Csaba Osztrogonác.
+
+        Substitution of WTF::move() for std::move(). Clean up std::move() in JavaScriptCore.
+
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/PutByIdVariant.cpp:
+        (JSC::PutByIdVariant::setter):
+
+2014-10-15  Oliver Hunt  <oliver@apple.com>
+
+        Use a single allocation for the Arguments object
+        https://bugs.webkit.org/show_bug.cgi?id=137751
+
+        Reviewed by Filip Pizlo.
+
+        This patch removes the secondary allocation for parameters in the Arguments
+        object.  This is faily simple, but we needed to make it possible for the JIT
+        to allocate a variable GC object.  To do this i've added a new 
+        emitAllocateVariableSizedJSObject function to the JIT that does the work to
+        find the correct heap for a variable sized allocation and then bump that
+        allocator.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateVariableSizedJSObject):
+        * heap/CopyToken.h:
+        * heap/Heap.h:
+        (JSC::Heap::subspaceForObjectWithoutDestructor):
+        (JSC::Heap::subspaceForObjectNormalDestructor):
+        (JSC::Heap::subspaceForObjectsWithImmortalStructure):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::subspaceForObjectsWithNormalDestructor):
+        (JSC::MarkedSpace::subspaceForObjectsWithImmortalStructure):
+        (JSC::MarkedSpace::subspaceForObjectsWithoutDestructor):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::visitChildren):
+        (JSC::Arguments::copyBackingStore):
+        (JSC::Arguments::tearOff):
+        (JSC::Arguments::allocateRegisterArray): Deleted.
+        * runtime/Arguments.h:
+        (JSC::Arguments::create):
+        (JSC::Arguments::isTornOff):
+        (JSC::Arguments::offsetOfRegisterArray):
+        (JSC::Arguments::registerArraySizeInBytes):
+        (JSC::Arguments::registerArray):
+        (JSC::Arguments::allocationSize): Deleted.
+
+2014-10-15  Filip Pizlo  <fpizlo@apple.com>
+
+        Apparently we've had a hole in arguments capture all along
+        https://bugs.webkit.org/show_bug.cgi?id=137767
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getArgument):
+        * tests/stress/arguments-captured.js: Added.
+        (foo):
+        (bar):
+
+2014-10-16  Saam Barati  <saambarati1@gmail.com>
+
+        Have the ProfileType node in the DFG convert to a structure check where it can
+        https://bugs.webkit.org/show_bug.cgi?id=137596
+
+        Reviewed by Filip Pizlo.
+
+        TypeSet now keeps track of the live set of Structures it has seen.
+        It no longer nukes everything during GC. It now only removes unmarked
+        structures during GC. This modification allows the ProfileType node 
+        to convert into a CheckStructure node safely in the DFG. 
+
+        This change brings up the conversion rate from ProfileType to Check 
+        or CheckStructrue from ~45% to ~65%. This change also speeds the 
+        type profiler up significantly: consistently between 2x-20x faster. 
+
+        This patch also does some slight refactoring: a few type profiler
+        related fields are moved from VM to TypeProfiler.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToCheckStructure):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::uniqueIDForVariable):
+        * runtime/SymbolTable.h:
+        * runtime/TypeLocationCache.cpp:
+        (JSC::TypeLocationCache::getTypeLocation):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::TypeProfiler):
+        (JSC::TypeProfiler::nextTypeLocation):
+        (JSC::TypeProfiler::invalidateTypeSetCache):
+        (JSC::TypeProfiler::dumpTypeProfilerData):
+        * runtime/TypeProfiler.h:
+        (JSC::TypeProfiler::getNextUniqueVariableID):
+        * runtime/TypeProfilerLog.cpp:
+        (JSC::TypeProfilerLog::processLogEntries):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::invalidateCache):
+        * runtime/TypeSet.h:
+        (JSC::TypeSet::structureSet):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::enableTypeProfiler):
+        (JSC::VM::disableTypeProfiler):
+        (JSC::VM::dumpTypeProfilerData):
+        (JSC::VM::nextTypeLocation): Deleted.
+        (JSC::VM::invalidateTypeSetCache): Deleted.
+        * runtime/VM.h:
+        (JSC::VM::typeProfiler):
+        (JSC::VM::getNextUniqueVariableID): Deleted.
+        * tests/typeProfiler/dfg-jit-optimizations.js:
+
+2014-10-16  Adrien Destugues  <pulkomandy@gmail.com>
+
+        Use isnan from std namespace in ProfileGenerator.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=137653
+
+        Reviewed by Darin Adler.
+
+        The C++ isnan() function is in the std namespace. The unprefixed isnan
+        may be available because of C99 headers leakage in C++, but should not
+        be used.
+
+        No new tests: no functional change, build fix on platforms which don't
+        export C99 functions in C++.
+
+        * profiler/ProfileGenerator.cpp:
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause):
+        (JSC::ProfileGenerator::didContinue):
+
+2014-10-15  Michael Saboff  <msaboff@apple.com>
+
+        REGRESSION(r174025): remote inspector crashes frequently when executing inspector frontend's JavaScript
+        https://bugs.webkit.org/show_bug.cgi?id=137758
+
+        Rubber stamped by Filip Pizlo.
+
+        Reverted r174025 for just PutByOffset Nodes.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
+2014-10-14  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
+
+        Clean up unnecessary PassOwnPtr.h inclusion
+        https://bugs.webkit.org/show_bug.cgi?id=137726
+
+        Reviewed by Chris Dumez.
+
+        * API/JSCallbackObject.h: Remove PassOwnPtr.h inclusion.
+        * bytecode/DFGExitProfile.cpp: ditto.
+
+2014-10-14  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Unreviewed gardening. Ignore Visual Studio *.sdf files.
+
+        * JavaScriptCore.vcxproj: Modified properties svn:ignore and svn:ignore.
+        * JavaScriptCore.vcxproj/jsc: Modified property svn:ignore.
+
+2014-10-14  Matthew Mirman  <mmirman@apple.com>
+
+        Removes references to LLVMJIT which is no longer part of LLVM
+        https://bugs.webkit.org/show_bug.cgi?id=137708
+
+        Reviewed by Filip Pizlo.
+
+        * Configurations/LLVMForJSC.xcconfig: removed -lLLVMJIT
+        * llvm/LLVMAPIFunctions.h: removed LinkInJIT
+
+2014-10-14  peavo@outlook.com  <peavo@outlook.com>
+
+        [Win32] Thunk is not implemented.
+        https://bugs.webkit.org/show_bug.cgi?id=137691
+
+        Reviewed by Mark Lam.
+
+        Thunks for functions with double operands (floor, etc.) are not implemented on Win32.
+
+        * jit/ThunkGenerators.cpp:
+
+2014-10-12  Alexey Proskuryakov  <ap@apple.com>
+
+        Adding svn:ignore so that .pyc files don't show up as new.
+
+        * inspector/scripts/codegen: Added property svn:ignore.
+
+2014-10-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r174606.
+        https://bugs.webkit.org/show_bug.cgi?id=137621
+
+        broke a JSC test (Requested by estes on #webkit).
+
+        Reverted changeset:
+
+        "Various arguments optimisations in codegen fail to account
+        for arguments being in lexical record"
+        https://bugs.webkit.org/show_bug.cgi?id=137617
+        http://trac.webkit.org/changeset/174606
+
+2014-10-10  Oliver Hunt  <oliver@apple.com>
+
+        Various arguments optimisations in codegen fail to account for arguments being in lexical record
+        https://bugs.webkit.org/show_bug.cgi?id=137617
+
+        Reviewed by Michael Saboff.
+
+        Rework the way we track |arguments| references so that we don't try
+        to use the |arguments| reference on the stack if it's not safe.
+
+        To do this without nuking performance it was necessary to update
+        the parser to track modification of the |arguments| reference
+        itself.
+
+        * bytecode/CodeBlock.cpp:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::willResolveToArguments):
+        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::uncheckedRegisterForArguments): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::getArgumentByVal):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::existingArguments):
+        * parser/Nodes.h:
+        (JSC::ScopeNode::modifiesArguments):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseInner):
+        * parser/Parser.h:
+        (JSC::Scope::getCapturedVariables):
+        * parser/ParserModes.h:
+
+2014-10-09  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Remove unused generator code
+        https://bugs.webkit.org/show_bug.cgi?id=137564
+
+        Reviewed by Brian Burg.
+
+        * inspector/scripts/codegen/generate_backend_dispatcher_header.py:
+        (BackendDispatcherHeaderGenerator.generate_output): Deleted.
+        * inspector/scripts/codegen/generate_backend_dispatcher_implementation.py:
+        (BackendDispatcherImplementationGenerator.generate_output):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_header.py:
+        (FrontendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_frontend_dispatcher_implementation.py:
+        (FrontendDispatcherImplementationGenerator.generate_output):
+        * inspector/scripts/codegen/generate_protocol_types_header.py:
+        (ProtocolTypesHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_protocol_types_implementation.py:
+        (ProtocolTypesImplementationGenerator.generate_output):
+        inputFilename is now handled by the generic generator base class.
+
+        * inspector/scripts/codegen/models.py:
+        (Framework.fromString):
+        (Frameworks):
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        The WTF framework is unused. Remove unexpected frameworks.
+
+2014-10-09  Dean Jackson  <dino@apple.com>
+
+        Remove ENABLE_CSS3_CONDITIONAL_RULES
+        https://bugs.webkit.org/show_bug.cgi?id=137571
+
+        Reviewed by Simon Fraser.
+
+        * Configurations/FeatureDefines.xcconfig:
+
+2014-10-09  Adrien Destugues  <pulkomandy@gmail.com>
+
+        Fix compiler warning on noreturn function
+        https://bugs.webkit.org/show_bug.cgi?id=137558
+
+        Reviewed by Darin Adler.
+
+        The function is marked "noreturn", but the stub implementation does
+        return. No new tests: function is never called. Only fixes a warning.
+
+        * heap/HeapStatistics.cpp:
+        (JSC::HeapStatistics::exitWithFailure):
+
+2014-10-09  Akos Kiss  <akiss@inf.u-szeged.hu>
+
+        Ensure that inline assembly Thunk functions don't conflict with the section designations of the compiler
+        https://bugs.webkit.org/show_bug.cgi?id=137434
+
+        Reviewed by Michael Saboff.
+
+        The ARM64 version of the defineUnaryDoubleOpWrapper macro in
+        ThunkGenerators.cpp contains inline assembly with .text assembler
+        directive followed by a static variable declaration. This macro gets
+        expanded several times afterwards, however, only during the compilation
+        of the first expansion does gcc insert a .data assembler directive
+        before the assembled version of the static variable. Thus, only the
+        first variable gets allocated in the .data section, all the others
+        remain in .text. If JavaScriptCore is built as a shared library then
+        this causes a segmentation fault during dynamic linking.
+
+        This patch puts a .previous directive at the end of the inline assembly
+        to ensure that the assumptions of the compiler about the sections are
+        not broken and the following variable goes to the right place.
+
+        * jit/ThunkGenerators.cpp:
+
+2014-10-08  Oliver Hunt  <oliver@apple.com>
+
+        Make sure arguments tearoff is performed through the environment record if necessary
+        https://bugs.webkit.org/show_bug.cgi?id=137538
+
+        Reviewed by Michael Saboff.
+
+        Fairly simple change.  If we have a lexical record we need to pull the unmodified
+        arguments object from the record and then use the standard op_tear_off_arguments
+        instruction on the temporary.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetOwnScope):
+        (JSC::BytecodeGenerator::emitReturn):
+        * bytecompiler/BytecodeGenerator.h:
+
+2014-10-08  peavo@outlook.com  <peavo@outlook.com>
+
+        [WinCairo] Enable JIT on 32-bit.
+        https://bugs.webkit.org/show_bug.cgi?id=137521
+
+        Reviewed by Mark Lam.
+
+        Enable JIT on Windows 32-bit, but disable it at runtime if SSE2 is not present.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.pl:
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+
+2014-10-08  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Resolve some static analysis warnings in JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=137508
+
+        Reviewed by Geoffrey Garen.
+
+        * API/tests/testapi.c:
+        (assertEqualsAsCharactersPtr): MSVC insists on using %Iu as its format specifier
+        for size_t. Make the format string conditional on Windows.
+        * bytecode/Watchpoint.h:
+        (JSC::InlineWatchpointSet::encodeState): Silence warning about left-shifting 'state'
+        as a 32-bit value before OR-ing it with a 64-bit value.
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Silence warning about operator prescedence
+        causing the || operation to take place before the >= test.
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::endBasicBlock): Ditto (|| before !=)
+        * testRegExp.cpp:
+        (testOneRegExp): Ditto %Iu format specifier.
+        * yarr/YarrInterpreter.cpp:
+        (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext): Silence warning about
+        using a 32-bit value as part of a 64-bit calculation.
+
+2014-10-07  Simon Fraser  <simon.fraser@apple.com>
+
+        Roll-over Changelogs.
+
+        * ChangeLog-2014-10-07: Copied from Source/JavaScriptCore/ChangeLog.
+
+== Rolled over to ChangeLog-2014-10-07 ==
index 912be7717400a20c0f46494d15578029ddf053b9..ded3d37ca8a9bafaef7ffdc82f1a6770044c3a63 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
+// Copyright (C) 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
-#include "iOS.xcconfig"
-#include "../../../../Internal/Configurations/UseInternalSDK.xcconfig"
+#include "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
+
+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION));
+USE_INTERNAL_SDK_Production = YES;
+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK);
+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK);
 
 CLANG_CXX_LANGUAGE_STANDARD = gnu++0x;
 CLANG_CXX_LIBRARY = libc++;
@@ -33,32 +37,26 @@ CLANG_WARN_EMPTY_BODY = YES;
 CLANG_WARN_ENUM_CONVERSION = YES;
 CLANG_WARN_INT_CONVERSION = YES;
 CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+COMBINE_HIDPI_IMAGES = NO;
 DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
+ENABLE_STRICT_OBJC_MSGSEND = YES;
 GCC_C_LANGUAGE_STANDARD = gnu99;
 GCC_DEBUGGING_SYMBOLS = default;
 GCC_DYNAMIC_NO_PIC = NO;
 GCC_ENABLE_CPP_EXCEPTIONS = NO;
 GCC_ENABLE_CPP_RTTI = NO;
 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
-GCC_ENABLE_OBJC_GC = $(GCC_ENABLE_OBJC_GC_$(PLATFORM_NAME));
-GCC_ENABLE_OBJC_GC_iphoneos = NO;
-GCC_ENABLE_OBJC_GC_iphonesimulator = NO;
-GCC_ENABLE_OBJC_GC_macosx = $(GCC_ENABLE_OBJC_GC_macosx_$(CONFIGURATION));
-GCC_ENABLE_OBJC_GC_macosx_Production = supported;
-GCC_ENABLE_OBJC_GC_macosx_Debug = $(GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release);
-GCC_ENABLE_OBJC_GC_macosx_Release = $(GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release);
-GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release = $(GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release_$(USE_INTERNAL_SDK));
-GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release_ = NO;
-GCC_ENABLE_OBJC_GC_macosx_Debug_or_Release_YES = supported;
+GCC_ENABLE_OBJC_GC = $(GCC_ENABLE_OBJC_GC_$(PLATFORM_NAME)_$(USE_INTERNAL_SDK));
+GCC_ENABLE_OBJC_GC_macosx_ = NO;
+GCC_ENABLE_OBJC_GC_macosx_YES = supported;
 GCC_ENABLE_SYMBOL_SEPARATION = NO;
 GCC_FAST_OBJC_DISPATCH = YES;
 GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
-GCC_MODEL_TUNING = $(GCC_MODEL_TUNING_$(PLATFORM_NAME));
-GCC_MODEL_TUNING_macosx = G5;
+GCC_NO_COMMON_BLOCKS = YES;
 GCC_OBJC_CALL_CXX_CDTORS = YES;
 GCC_PRECOMPILE_PREFIX_HEADER = YES;
-GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) HAVE_DTRACE=$(HAVE_DTRACE) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST HAVE_HEADER_DETECTION_H JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080 $(FEATURE_DEFINES) $(GCC_PREPROCESSOR_DEFINITIONS);
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) HAVE_HEADER_DETECTION_H $(FEATURE_DEFINES) $(inherited);
 GCC_STRICT_ALIASING = YES;
 GCC_THREADSAFE_STATICS = NO;
 GCC_TREAT_WARNINGS_AS_ERRORS = YES;
@@ -86,15 +84,9 @@ LINKER_DISPLAYS_MANGLED_NAMES = YES;
 PREBINDING = NO;
 WARNING_CFLAGS = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough;
 
-LLVM_LOCAL_HEADER_PATH = $(LLVM_LOCAL_HEADER_PATH_$(PLATFORM_NAME))
-LLVM_LOCAL_HEADER_PATH_macosx = "${BUILT_PRODUCTS_DIR}/usr/local/LLVMForJavaScriptCore/include"
-LLVM_LOCAL_HEADER_PATH_iphoneos = ;
-LLVM_LOCAL_HEADER_PATH_iphonesimulator = ;
+LLVM_LOCAL_HEADER_PATH[sdk=macosx*] = "$(BUILT_PRODUCTS_DIR)/usr/local/LLVMForJavaScriptCore/include";
 
-LLVM_SYSTEM_HEADER_PATH = $(LLVM_SYSTEM_HEADER_PATH_$(PLATFORM_NAME))
-LLVM_SYSTEM_HEADER_PATH_macosx = /usr/local/LLVMForJavaScriptCore/include;
-LLVM_SYSTEM_HEADER_PATH_iphoneos = ;
-LLVM_SYSTEM_HEADER_PATH_iphonesimulator = ;
+LLVM_SYSTEM_HEADER_PATH[sdk=macosx*] = /usr/local/LLVMForJavaScriptCore/include;
 
 HEADER_SEARCH_PATHS = . icu $(LLVM_LOCAL_HEADER_PATH) "${BUILT_PRODUCTS_DIR}/ExtraIncludesForLocalLLVMBuild" $(LLVM_SYSTEM_HEADER_PATH) "${BUILT_PRODUCTS_DIR}/usr/local/include" $(HEADER_SEARCH_PATHS);
 
@@ -109,19 +101,14 @@ STAGED_FRAMEWORKS_SEARCH_PATH_YES = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/StagedFram
 
 NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR = $(SYSTEM_LIBRARY_DIR)/Frameworks;
 
-JAVASCRIPTCORE_FRAMEWORKS_DIR = $(JAVASCRIPTCORE_FRAMEWORKS_DIR_$(PLATFORM_NAME));
-JAVASCRIPTCORE_FRAMEWORKS_DIR_iphoneos = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR);
-JAVASCRIPTCORE_FRAMEWORKS_DIR_iphonesimulator = $(JAVASCRIPTCORE_FRAMEWORKS_DIR_iphoneos);
-
-JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx = $(JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_$(USE_STAGING_INSTALL_PATH));
+JAVASCRIPTCORE_FRAMEWORKS_DIR[sdk=iphone*] = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR);
+JAVASCRIPTCORE_FRAMEWORKS_DIR = $(JAVASCRIPTCORE_FRAMEWORKS_DIR_$(PLATFORM_NAME)_USE_STAGING_INSTALL_PATH_$(USE_STAGING_INSTALL_PATH));
 JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_ = $(JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_NO);
 JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_NO = $(NORMAL_JAVASCRIPTCORE_FRAMEWORKS_DIR);
 JAVASCRIPTCORE_FRAMEWORKS_DIR_macosx_USE_STAGING_INSTALL_PATH_YES = $(SYSTEM_LIBRARY_DIR)/StagedFrameworks/Safari;
 
-JAVASCRIPTCORE_CONTENTS_DIR = $(JAVASCRIPTCORE_CONTENTS_DIR_$(PLATFORM_NAME));
-JAVASCRIPTCORE_CONTENTS_DIR_iphoneos = JavaScriptCore.framework;
-JAVASCRIPTCORE_CONTENTS_DIR_iphonesimulator = $(JAVASCRIPTCORE_CONTENTS_DIR_iphoneos);
-JAVASCRIPTCORE_CONTENTS_DIR_macosx = JavaScriptCore.framework/Versions/A;
+JAVASCRIPTCORE_CONTENTS_DIR[sdk=iphone*] = JavaScriptCore.framework;
+JAVASCRIPTCORE_CONTENTS_DIR[sdk=macosx*] = JavaScriptCore.framework/Versions/A;
 
 JAVASCRIPTCORE_RESOURCES_DIR = $(JAVASCRIPTCORE_CONTENTS_DIR)/Resources;
 JAVASCRIPTCORE_LIBRARIES_DIR = $(JAVASCRIPTCORE_CONTENTS_DIR)/Libraries;
@@ -144,19 +131,14 @@ DEAD_CODE_STRIPPING_debug = NO;
 DEAD_CODE_STRIPPING_normal = YES;
 DEAD_CODE_STRIPPING = $(DEAD_CODE_STRIPPING_$(CURRENT_VARIANT));
 
-SECTORDER_FLAGS = $(SECTORDER_FLAGS_$(PLATFORM_NAME));
-SECTORDER_FLAGS_iphoneos = -Wl,-order_file,$(SDKROOT)/AppleInternal/OrderFiles/JavaScriptCore.order;
-SECTORDER_FLAGS_macosx = -Wl,-order_file,JavaScriptCore.order;
-
 SDKROOT = macosx.internal;
 
+INSTALL_PATH_PREFIX[sdk=iphonesimulator8.*] = $(DEVELOPER_INSTALL_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/$(SDK_DIR:file);
 INSTALL_PATH = $(INSTALL_PATH_PREFIX)$(INSTALL_PATH_ACTUAL);
-HAVE_DTRACE = 1;
-
-TOOLCHAINS = $(TOOLCHAINS_$(PLATFORM_NAME));
-TOOLCHAINS_iphoneos = $(TOOLCHAINS);
-TOOLCHAINS_iphonesimulator = $(TOOLCHAINS);
-TOOLCHAINS_macosx = $(TOOLCHAINS_macosx_$(MAC_OS_X_VERSION_MAJOR));
-TOOLCHAINS_macosx_1080 = default;
-TOOLCHAINS_macosx_1090 = $(TOOLCHAINS);
-TOOLCHAINS_macosx_101000 = $(TOOLCHAINS_macosx_1090);
+
+LD_DYLIB_INSTALL_NAME[sdk=iphonesimulator8.*]=$(LD_DYLIB_INSTALL_NAME_$(MACH_O_TYPE));
+LD_DYLIB_INSTALL_NAME_mh_dylib=$(INSTALL_PATH_ACTUAL)/$(EXECUTABLE_PATH);
+
+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS);
+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
index aa50d483369c939aa3d11bbc536d4c71017e7d82..41ccb334cb65c53c5166ad7b36a92e83edcc536f 100644 (file)
@@ -34,8 +34,6 @@ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 
 HEADER_SEARCH_PATHS = "${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore" $(HEADER_SEARCH_PATHS);
 
-SECTORDER_FLAGS = ;
-
 OTHER_CFLAGS = -c -flto;
 OTHER_CPLUSPLUSFLAGS = -c -flto;
 OTHER_LDFLAGS = ;
index a070ea4fbe88d09251d0285da102582256333b25..91e815d084dbd339f96eeb89db6c0b7cd18bf897 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
+// Copyright (C) 2009, 2010, 2013, 2014 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
@@ -27,26 +27,16 @@ ARCHS = $(ARCHS_STANDARD_32_64_BIT);
 
 ONLY_ACTIVE_ARCH = YES;
 
-MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(PLATFORM_NAME));
-MACOSX_DEPLOYMENT_TARGET_iphoneos = 10.5;
-MACOSX_DEPLOYMENT_TARGET_iphonesimulator = 10.5;
-MACOSX_DEPLOYMENT_TARGET_macosx = $(MACOSX_DEPLOYMENT_TARGET_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-MACOSX_DEPLOYMENT_TARGET_macosx_1080 = 10.8;
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(PLATFORM_NAME)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 MACOSX_DEPLOYMENT_TARGET_macosx_1090 = 10.9;
 MACOSX_DEPLOYMENT_TARGET_macosx_101000 = 10.10;
+MACOSX_DEPLOYMENT_TARGET_macosx_101100 = 10.11;
+MACOSX_DEPLOYMENT_TARGET_macosx_101200 = 10.12;
 
 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
 DEBUG_INFORMATION_FORMAT = dwarf;
 
-SECTORDER_FLAGS = ; 
-
-OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS);
-OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
-OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
-
-SDKROOT = $(SDKROOT_$(PLATFORM_NAME));
-SDKROOT_iphoneos = $(SDKROOT);
-SDKROOT_iphonesimulator = $(SDKROOT);
-SDKROOT_macosx = $(SDKROOT_macosx_$(USE_INTERNAL_SDK));
+SDKROOT[sdk=iphone*] = $(SDKROOT);
+SDKROOT = $(SDKROOT_$(PLATFORM_NAME)_$(USE_INTERNAL_SDK));
 SDKROOT_macosx_ = macosx;
 SDKROOT_macosx_YES = macosx.internal;
index e8e2332fcc63cfcd74af27add9f89859ee8ffa33..5c030baaadfbf3e673f977551ae9dbce4886b09d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009, 2010, 2014 Apple Inc. All rights reserved.
+// Copyright (C) 2009, 2010, 2014, 2015 Apple Inc. All rights reserved.
 // Copyright (C) 2009 Google Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 
 // Set any ENABLE_FEATURE_NAME macro to an empty string to disable that feature.
 
-ENABLE_3D_RENDERING = ENABLE_3D_RENDERING;
+ENABLE_3D_TRANSFORMS = ENABLE_3D_TRANSFORMS;
 ENABLE_ACCELERATED_2D_CANVAS = ;
-ENABLE_ACCELERATED_OVERFLOW_SCROLLING = $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING_$(PLATFORM_NAME));
-ENABLE_ACCELERATED_OVERFLOW_SCROLLING_iphoneos = ENABLE_ACCELERATED_OVERFLOW_SCROLLING;
-ENABLE_ACCELERATED_OVERFLOW_SCROLLING_iphonesimulator = $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING_iphoneos);
-ENABLE_AVF_CAPTIONS = $(ENABLE_AVF_CAPTIONS_$(PLATFORM_NAME));
-ENABLE_AVF_CAPTIONS_macosx = $(ENABLE_AVF_CAPTIONS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_AVF_CAPTIONS_macosx_1080 = ;
+ENABLE_ACCELERATED_OVERFLOW_SCROLLING[sdk=iphone*] = ENABLE_ACCELERATED_OVERFLOW_SCROLLING;
+ENABLE_ATTACHMENT_ELEMENT = ;
+ENABLE_AVF_CAPTIONS[sdk=iphone*] = ENABLE_AVF_CAPTIONS;
+ENABLE_AVF_CAPTIONS[sdk=macosx*] = $(ENABLE_AVF_CAPTIONS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_AVF_CAPTIONS_macosx_1090 = ;
 ENABLE_AVF_CAPTIONS_macosx_101000 = ENABLE_AVF_CAPTIONS;
-ENABLE_AVF_CAPTIONS_iphoneos = ENABLE_AVF_CAPTIONS;
-ENABLE_AVF_CAPTIONS_iphonesimulator = $(ENABLE_AVF_CAPTIONS_iphoneos);
+ENABLE_AVF_CAPTIONS_macosx_101100 = ENABLE_AVF_CAPTIONS;
+ENABLE_AVF_CAPTIONS_macosx_101200 = ENABLE_AVF_CAPTIONS;
 ENABLE_CACHE_PARTITIONING = ENABLE_CACHE_PARTITIONING;
-ENABLE_CANVAS_PATH = ;
+ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
+ENABLE_ES6_ARROWFUNCTION_SYNTAX = ;
+ENABLE_ES6_CLASS_SYNTAX = ENABLE_ES6_CLASS_SYNTAX;
+ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX = ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX;
+ENABLE_CONTENT_FILTERING = ENABLE_CONTENT_FILTERING;
 ENABLE_CSP_NEXT = ;
+ENABLE_CSS_ANIMATIONS_LEVEL_2 = ;
 ENABLE_CSS_BOX_DECORATION_BREAK = ENABLE_CSS_BOX_DECORATION_BREAK;
 ENABLE_CSS_COMPOSITING = ENABLE_CSS_COMPOSITING;
 ENABLE_CSS_DEVICE_ADAPTATION = ;
-ENABLE_CSS_EXCLUSIONS = ;
-ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS;
 ENABLE_CSS_GRID_LAYOUT = ;
 ENABLE_CSS_IMAGE_ORIENTATION = ;
 ENABLE_CSS_IMAGE_RESOLUTION = ;
 ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS;
+ENABLE_CSS_SELECTORS_LEVEL4 = ;
 ENABLE_CSS_SHAPES = ENABLE_CSS_SHAPES;
-ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED = ;
-ENABLE_CSS3_CONDITIONAL_RULES = ;
 ENABLE_CSS3_TEXT = ;
 ENABLE_CSS3_TEXT_LINE_BREAK = ;
 ENABLE_CURSOR_VISIBILITY = ENABLE_CURSOR_VISIBILITY;
 ENABLE_CUSTOM_SCHEME_HANDLER = ;
-ENABLE_DASHBOARD_SUPPORT = $(ENABLE_DASHBOARD_SUPPORT_$(PLATFORM_NAME));
-ENABLE_DASHBOARD_SUPPORT_macosx = ENABLE_DASHBOARD_SUPPORT;
+ENABLE_DASHBOARD_SUPPORT[sdk=macosx*] = ENABLE_DASHBOARD_SUPPORT;
 ENABLE_DATALIST_ELEMENT = ;
 ENABLE_DATA_TRANSFER_ITEMS = ;
 ENABLE_DETAILS_ELEMENT = ENABLE_DETAILS_ELEMENT;
-ENABLE_DEVICE_ORIENTATION = $(ENABLE_DEVICE_ORIENTATION_$(PLATFORM_NAME));
-ENABLE_DEVICE_ORIENTATION_iphoneos = ENABLE_DEVICE_ORIENTATION;
-ENABLE_DEVICE_ORIENTATION_iphonesimulator = $(ENABLE_DEVICE_ORIENTATION_iphoneos);
+ENABLE_DEVICE_ORIENTATION[sdk=iphone*] = ENABLE_DEVICE_ORIENTATION;
 ENABLE_DOM4_EVENTS_CONSTRUCTOR = ENABLE_DOM4_EVENTS_CONSTRUCTOR;
-ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(PLATFORM_NAME));
-ENABLE_ENCRYPTED_MEDIA_macosx = $(ENABLE_ENCRYPTED_MEDIA_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_ENCRYPTED_MEDIA_macosx_1080 = ;
-ENABLE_ENCRYPTED_MEDIA_macosx_1090 = ENABLE_ENCRYPTED_MEDIA;
-ENABLE_ENCRYPTED_MEDIA_macosx_101000 = ENABLE_ENCRYPTED_MEDIA;
-ENABLE_ENCRYPTED_MEDIA_V2 = $(ENABLE_ENCRYPTED_MEDIA_V2_$(PLATFORM_NAME));
-ENABLE_ENCRYPTED_MEDIA_V2_macosx = $(ENABLE_ENCRYPTED_MEDIA_V2_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_ENCRYPTED_MEDIA_V2_macosx_1080 = ;
-ENABLE_ENCRYPTED_MEDIA_V2_macosx_1090 = ENABLE_ENCRYPTED_MEDIA_V2;
-ENABLE_ENCRYPTED_MEDIA_V2_macosx_101000 = ENABLE_ENCRYPTED_MEDIA_V2;
-ENABLE_FILTERS = ENABLE_FILTERS;
+ENABLE_ENCRYPTED_MEDIA[sdk=macosx*] = ENABLE_ENCRYPTED_MEDIA;
+ENABLE_ENCRYPTED_MEDIA_V2[sdk=macosx*] = ENABLE_ENCRYPTED_MEDIA_V2;
+ENABLE_FILTERS_LEVEL_2[sdk=iphone*] = ENABLE_FILTERS_LEVEL_2;
+ENABLE_FILTERS_LEVEL_2[sdk=macosx*] = $(ENABLE_FILTERS_LEVEL_2_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+ENABLE_FILTERS_LEVEL_2_macosx_1090 = ;
+ENABLE_FILTERS_LEVEL_2_macosx_101000 = ENABLE_FILTERS_LEVEL_2;
+ENABLE_FILTERS_LEVEL_2_macosx_101100 = ENABLE_FILTERS_LEVEL_2;
+ENABLE_FILTERS_LEVEL_2_macosx_101200 = ENABLE_FILTERS_LEVEL_2;
 ENABLE_FONT_LOAD_EVENTS = ;
-ENABLE_FULLSCREEN_API = $(ENABLE_FULLSCREEN_API_$(PLATFORM_NAME));
-ENABLE_FULLSCREEN_API_macosx = ENABLE_FULLSCREEN_API;
-ENABLE_GAMEPAD = $(ENABLE_GAMEPAD_$(PLATFORM_NAME));
-ENABLE_GAMEPAD_macosx = ;
+ENABLE_FULLSCREEN_API[sdk=macosx*] = ENABLE_FULLSCREEN_API;
+ENABLE_GAMEPAD[sdk=macosx*] = ;
 ENABLE_GAMEPAD_DEPRECATED = ;
 ENABLE_GEOLOCATION = ENABLE_GEOLOCATION;
-ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING = $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING_$(PLATFORM_NAME));
-ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING_macosx = ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING;
-ENABLE_HIGH_DPI_CANVAS = $(ENABLE_HIGH_DPI_CANVAS_$(PLATFORM_NAME));
-ENABLE_ICONDATABASE = $(ENABLE_ICONDATABASE_$(PLATFORM_NAME));
-ENABLE_ICONDATABASE_macosx = ENABLE_ICONDATABASE;
-ENABLE_SERVICE_CONTROLS = $(ENABLE_SERVICE_CONTROLS_$(PLATFORM_NAME));
-ENABLE_SERVICE_CONTROLS_macosx = $(ENABLE_SERVICE_CONTROLS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_SERVICE_CONTROLS_macosx_1080 = ;
+ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING[sdk=macosx*] = ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING;
+ENABLE_ICONDATABASE[sdk=macosx*] = ENABLE_ICONDATABASE;
+ENABLE_SERVICE_CONTROLS[sdk=macosx*] = $(ENABLE_SERVICE_CONTROLS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_SERVICE_CONTROLS_macosx_1090 = ;
 ENABLE_SERVICE_CONTROLS_macosx_101000 = ENABLE_SERVICE_CONTROLS;
+ENABLE_SERVICE_CONTROLS_macosx_101100 = ENABLE_SERVICE_CONTROLS;
+ENABLE_SERVICE_CONTROLS_macosx_101200 = ENABLE_SERVICE_CONTROLS;
 ENABLE_INDEXED_DATABASE = ENABLE_INDEXED_DATABASE;
 ENABLE_INDEXED_DATABASE_IN_WORKERS = ;
 ENABLE_INDIE_UI = ;
-ENABLE_INPUT_SPEECH = ;
-ENABLE_INPUT_TYPE_COLOR = $(ENABLE_INPUT_TYPE_COLOR_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_COLOR_macosx = ;
-ENABLE_INPUT_TYPE_COLOR_POPOVER = $(ENABLE_INPUT_TYPE_COLOR_POPOVER_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_COLOR_POPOVER_macosx = ;
-ENABLE_INPUT_TYPE_DATE = $(ENABLE_INPUT_TYPE_DATE_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_DATE_iphoneos = ENABLE_INPUT_TYPE_DATE;
-ENABLE_INPUT_TYPE_DATE_iphonesimulator = $(ENABLE_INPUT_TYPE_DATE_iphoneos);
+ENABLE_INPUT_TYPE_COLOR[sdk=macosx*] = ;
+ENABLE_INPUT_TYPE_COLOR_POPOVER[sdk=macosx*] = ;
+ENABLE_INPUT_TYPE_DATE[sdk=iphone*] = ENABLE_INPUT_TYPE_DATE;
 ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE = ;
-ENABLE_INPUT_TYPE_DATETIMELOCAL = $(ENABLE_INPUT_TYPE_DATETIMELOCAL_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_DATETIMELOCAL_iphoneos = ENABLE_INPUT_TYPE_DATETIMELOCAL;
-ENABLE_INPUT_TYPE_DATETIMELOCAL_iphonesimulator = $(ENABLE_INPUT_TYPE_DATETIMELOCAL_iphoneos);
-ENABLE_INPUT_TYPE_MONTH = $(ENABLE_INPUT_TYPE_MONTH_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_MONTH_iphoneos = ENABLE_INPUT_TYPE_MONTH;
-ENABLE_INPUT_TYPE_MONTH_iphonesimulator = $(ENABLE_INPUT_TYPE_MONTH_iphoneos);
-ENABLE_INPUT_TYPE_TIME = $(ENABLE_INPUT_TYPE_TIME_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_TIME_iphoneos = ENABLE_INPUT_TYPE_TIME;
-ENABLE_INPUT_TYPE_TIME_iphonesimulator = $(ENABLE_INPUT_TYPE_TIME_iphoneos);
-ENABLE_INPUT_TYPE_WEEK = $(ENABLE_INPUT_TYPE_WEEK_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_WEEK_iphoneos = ENABLE_INPUT_TYPE_WEEK;
-ENABLE_INPUT_TYPE_WEEK_iphonesimulator = $(ENABLE_INPUT_TYPE_WEEK_iphoneos);
-ENABLE_INSPECTOR = ENABLE_INSPECTOR;
-ENABLE_IOS_AIRPLAY = $(ENABLE_IOS_AIRPLAY_$(PLATFORM_NAME));
-ENABLE_IOS_AIRPLAY_iphoneos = ENABLE_IOS_AIRPLAY;
-ENABLE_IOS_AIRPLAY_iphonesimulator = $(ENABLE_IOS_AIRPLAY_iphoneos);
-ENABLE_IOS_TEXT_AUTOSIZING = $(ENABLE_IOS_TEXT_AUTOSIZING_$(PLATFORM_NAME));
-ENABLE_IOS_TEXT_AUTOSIZING_iphoneos = ENABLE_IOS_TEXT_AUTOSIZING;
-ENABLE_IOS_TEXT_AUTOSIZING_iphonesimulator = $(ENABLE_IOS_TEXT_AUTOSIZING_iphoneos);
+ENABLE_INPUT_TYPE_DATETIMELOCAL[sdk=iphone*] = ENABLE_INPUT_TYPE_DATETIMELOCAL;
+ENABLE_INPUT_TYPE_MONTH[sdk=iphone*] = ENABLE_INPUT_TYPE_MONTH;
+ENABLE_INPUT_TYPE_TIME[sdk=iphone*] = ENABLE_INPUT_TYPE_TIME;
+ENABLE_INPUT_TYPE_WEEK[sdk=iphone*] = ENABLE_INPUT_TYPE_WEEK;
+
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS[sdk=iphone*] = ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS;
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS[sdk=macosx*] = $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR))
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS_macosx_1090 = ;
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS_macosx_101000 = ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS;
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS_macosx_101100 = ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS;
+ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS_macosx_101200 = ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS;
+
+ENABLE_WIRELESS_PLAYBACK_TARGET[sdk=iphone*] = ENABLE_WIRELESS_PLAYBACK_TARGET;
+ENABLE_WIRELESS_PLAYBACK_TARGET[sdk=macosx*] = $(ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR))
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_1090 = ;
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101000 = ;
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101100 = ENABLE_WIRELESS_PLAYBACK_TARGET;
+ENABLE_WIRELESS_PLAYBACK_TARGET_macosx_101200 = ENABLE_WIRELESS_PLAYBACK_TARGET;
+
+ENABLE_INTL = ;
+
+ENABLE_IOS_GESTURE_EVENTS[sdk=iphone*] = $(ENABLE_IOS_GESTURE_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_IOS_GESTURE_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_IOS_GESTURE_EVENTS;
+
+ENABLE_IOS_TEXT_AUTOSIZING[sdk=iphone*] = ENABLE_IOS_TEXT_AUTOSIZING;
+
+ENABLE_IOS_TOUCH_EVENTS[sdk=iphone*] = $(ENABLE_IOS_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_IOS_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_IOS_TOUCH_EVENTS;
+
 ENABLE_LEGACY_CSS_VENDOR_PREFIXES = ENABLE_LEGACY_CSS_VENDOR_PREFIXES;
-ENABLE_LEGACY_NOTIFICATIONS = $(ENABLE_LEGACY_NOTIFICATIONS_$(PLATFORM_NAME));
-ENABLE_LEGACY_NOTIFICATIONS_macosx = ENABLE_LEGACY_NOTIFICATIONS;
+ENABLE_LEGACY_NOTIFICATIONS[sdk=macosx*] = ENABLE_LEGACY_NOTIFICATIONS;
 ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
 ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
-ENABLE_LETTERPRESS = $(ENABLE_LETTERPRESS_$(PLATFORM_NAME));
-ENABLE_LETTERPRESS_iphoneos = ENABLE_LETTERPRESS;
-ENABLE_LETTERPRESS_iphonesimulator = $(ENABLE_LETTERPRESS_iphoneos);
-
-ENABLE_LINK_LONG_PRESS = $(ENABLE_LINK_LONG_PRESS_$(PLATFORM_NAME));
-ENABLE_LINK_LONG_PRESS_macosx = $(ENABLE_LINK_LONG_PRESS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_LINK_LONG_PRESS_macosx_1080 = ;
-ENABLE_LINK_LONG_PRESS_macosx_1090 = ;
-ENABLE_LINK_LONG_PRESS_macosx_101000 = ENABLE_LINK_LONG_PRESS;
-
+ENABLE_LETTERPRESS[sdk=iphone*] = ENABLE_LETTERPRESS;
 ENABLE_LINK_PREFETCH = ;
 ENABLE_MATHML = ENABLE_MATHML;
 ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
+ENABLE_MEDIA_SESSION = ;
 
-ENABLE_MEDIA_SOURCE = $(ENABLE_MEDIA_SOURCE_$(PLATFORM_NAME));
-ENABLE_MEDIA_SOURCE_macosx = $(ENABLE_MEDIA_SOURCE_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_MEDIA_SOURCE_macosx_1080 = ;
+ENABLE_MEDIA_SOURCE[sdk=macosx*] = $(ENABLE_MEDIA_SOURCE_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_MEDIA_SOURCE_macosx_1090 = ;
 ENABLE_MEDIA_SOURCE_macosx_101000 = ENABLE_MEDIA_SOURCE;
+ENABLE_MEDIA_SOURCE_macosx_101100 = ENABLE_MEDIA_SOURCE;
+ENABLE_MEDIA_SOURCE_macosx_101200 = ENABLE_MEDIA_SOURCE;
 
 ENABLE_MEDIA_STATISTICS = ;
-ENABLE_METER_ELEMENT = $(ENABLE_METER_ELEMENT_$(PLATFORM_NAME));
-ENABLE_METER_ELEMENT_macosx = ENABLE_METER_ELEMENT;
+ENABLE_MEDIA_STREAM = ;
+ENABLE_METER_ELEMENT[sdk=macosx*] = ENABLE_METER_ELEMENT;
 ENABLE_MHTML = ;
-ENABLE_MOUSE_CURSOR_SCALE = $(ENABLE_MOUSE_CURSOR_SCALE_$(PLATFORM_NAME));
-ENABLE_MOUSE_CURSOR_SCALE_macosx = ENABLE_MOUSE_CURSOR_SCALE;
+ENABLE_MOUSE_CURSOR_SCALE[sdk=macosx*] = ENABLE_MOUSE_CURSOR_SCALE;
 ENABLE_NAVIGATOR_CONTENT_UTILS = ;
 ENABLE_NAVIGATOR_HWCONCURRENCY = ;
 ENABLE_NOSNIFF = ;
-ENABLE_NOTIFICATIONS = $(ENABLE_NOTIFICATIONS_$(PLATFORM_NAME));
-ENABLE_NOTIFICATIONS_macosx = ENABLE_NOTIFICATIONS;
-ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(PLATFORM_NAME));
-ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
+ENABLE_NOTIFICATIONS[sdk=macosx*] = ENABLE_NOTIFICATIONS;
+ENABLE_PDFKIT_PLUGIN[sdk=macosx*] = ENABLE_PDFKIT_PLUGIN;
 ENABLE_PICTURE_SIZES = ;
 ENABLE_POINTER_LOCK = ;
 ENABLE_PROMISES = ENABLE_PROMISES;
@@ -177,76 +159,73 @@ ENABLE_PROXIMITY_EVENTS = ;
 ENABLE_PUBLIC_SUFFIX_LIST = ENABLE_PUBLIC_SUFFIX_LIST;
 ENABLE_QUOTA = ;
 ENABLE_REQUEST_ANIMATION_FRAME = ENABLE_REQUEST_ANIMATION_FRAME;
-ENABLE_REMOTE_INSPECTOR = $(ENABLE_REMOTE_INSPECTOR_$(PLATFORM_NAME));
-ENABLE_REMOTE_INSPECTOR_iphoneos = ENABLE_REMOTE_INSPECTOR;
-ENABLE_REMOTE_INSPECTOR_iphonesimulator = $(ENABLE_REMOTE_INSPECTOR_iphoneos);
-ENABLE_REMOTE_INSPECTOR_macosx = $(ENABLE_REMOTE_INSPECTOR_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR))
-ENABLE_REMOTE_INSPECTOR_macosx_1080 = ;
+ENABLE_REQUEST_AUTOCOMPLETE = ;
+ENABLE_REMOTE_INSPECTOR[sdk=iphone*] = ENABLE_REMOTE_INSPECTOR;
+ENABLE_REMOTE_INSPECTOR[sdk=macosx*] = $(ENABLE_REMOTE_INSPECTOR_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_REMOTE_INSPECTOR_macosx_1090 = ;
 ENABLE_REMOTE_INSPECTOR_macosx_101000 = ENABLE_REMOTE_INSPECTOR;
+ENABLE_REMOTE_INSPECTOR_macosx_101100 = ENABLE_REMOTE_INSPECTOR;
+ENABLE_REMOTE_INSPECTOR_macosx_101200 = ENABLE_REMOTE_INSPECTOR;
 ENABLE_RESOLUTION_MEDIA_QUERY = ;
-ENABLE_SCRIPTED_SPEECH = ;
-ENABLE_SHARED_WORKERS = ;
-ENABLE_SPEECH_SYNTHESIS = $(ENABLE_SPEECH_SYNTHESIS_$(PLATFORM_NAME));
+ENABLE_RUBBER_BANDING[sdk=macosx*] = ENABLE_RUBBER_BANDING;
+ENABLE_CSS_SCROLL_SNAP = ENABLE_CSS_SCROLL_SNAP;
 ENABLE_SPEECH_SYNTHESIS = ENABLE_SPEECH_SYNTHESIS;
-ENABLE_SQL_DATABASE = ENABLE_SQL_DATABASE;
-ENABLE_SUBPIXEL_LAYOUT = ENABLE_SUBPIXEL_LAYOUT;
-ENABLE_SUBTLE_CRYPTO = $(ENABLE_SUBTLE_CRYPTO_$(PLATFORM_NAME));
-ENABLE_SUBTLE_CRYPTO_macosx = $(ENABLE_SUBTLE_CRYPTO_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_SUBTLE_CRYPTO_macosx_1080 = ;
-ENABLE_SUBTLE_CRYPTO_macosx_1090 = ENABLE_SUBTLE_CRYPTO;
-ENABLE_SUBTLE_CRYPTO_macosx_101000 = ENABLE_SUBTLE_CRYPTO;
-ENABLE_SUBTLE_CRYPTO_iphoneos = ENABLE_SUBTLE_CRYPTO;
-ENABLE_SUBTLE_CRYPTO_iphonesimulator = $(ENABLE_SUBTLE_CRYPTO_iphoneos);
+ENABLE_STREAMS_API = ;
+ENABLE_SUBTLE_CRYPTO = ENABLE_SUBTLE_CRYPTO;
 ENABLE_SVG_FONTS = ENABLE_SVG_FONTS;
+ENABLE_SVG_OTF_CONVERTER = ENABLE_SVG_OTF_CONVERTER;
 
-ENABLE_TELEPHONE_NUMBER_DETECTION = $(ENABLE_TELEPHONE_NUMBER_DETECTION_$(PLATFORM_NAME));
-ENABLE_TELEPHONE_NUMBER_DETECTION_macosx = $(ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_1080 = ;
+ENABLE_TELEPHONE_NUMBER_DETECTION[sdk=iphone*] = ENABLE_TELEPHONE_NUMBER_DETECTION;
+ENABLE_TELEPHONE_NUMBER_DETECTION[sdk=macosx*] = $(ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_1090 = ;
 ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_101000 = ENABLE_TELEPHONE_NUMBER_DETECTION;
-ENABLE_TELEPHONE_NUMBER_DETECTION_iphoneos = ENABLE_TELEPHONE_NUMBER_DETECTION;
-ENABLE_TELEPHONE_NUMBER_DETECTION_iphonesimulator = $(ENABLE_TELEPHONE_NUMBER_DETECTION_iphoneos);
+ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_101100 = ENABLE_TELEPHONE_NUMBER_DETECTION;
+ENABLE_TELEPHONE_NUMBER_DETECTION_macosx_101200 = ENABLE_TELEPHONE_NUMBER_DETECTION;
 
 ENABLE_TEMPLATE_ELEMENT = ENABLE_TEMPLATE_ELEMENT;
 ENABLE_TEXT_AUTOSIZING = ;
-ENABLE_TOUCH_EVENTS = $(ENABLE_TOUCH_EVENTS_$(PLATFORM_NAME));
-ENABLE_TOUCH_EVENTS_iphoneos = ENABLE_TOUCH_EVENTS;
-ENABLE_TOUCH_EVENTS_iphonesimulator = $(ENABLE_TOUCH_EVENTS_iphoneos);
+
+ENABLE_CSS_TRAILING_WORD = ENABLE_CSS_TRAILING_WORD;
+
+// FIXME: Remove the USE_INTERNAL_SDK condition once we support touch events when building for iOS with
+// the public SDK. We will also need to update FeatureDefines.h.
+ENABLE_TOUCH_EVENTS[sdk=iphone*] = $(ENABLE_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_TOUCH_EVENTS_ios_WITH_INTERNAL_SDK_YES = ENABLE_TOUCH_EVENTS;
+
 ENABLE_TOUCH_ICON_LOADING = ;
 ENABLE_USERSELECT_ALL = ENABLE_USERSELECT_ALL;
 ENABLE_VIDEO = ENABLE_VIDEO;
+ENABLE_VIDEO_PRESENTATION_MODE[sdk=iphone*] = ENABLE_VIDEO_PRESENTATION_MODE;
 ENABLE_VIDEO_TRACK = ENABLE_VIDEO_TRACK;
 ENABLE_DATACUE_VALUE = ENABLE_DATACUE_VALUE;
 ENABLE_VIEW_MODE_CSS_MEDIA = ;
 ENABLE_WEBGL = ENABLE_WEBGL;
+ENABLE_WEBGL2 = ;
 ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO;
-ENABLE_WEB_REPLAY = $(ENABLE_WEB_REPLAY_$(PLATFORM_NAME));
-ENABLE_WEB_REPLAY_macosx = $(ENABLE_WEB_REPLAY_macosx_$(CONFIGURATION));
-ENABLE_WEB_REPLAY_macosx_Debug = ENABLE_WEB_REPLAY;
-ENABLE_WEB_REPLAY_macosx_Release = ENABLE_WEB_REPLAY;
-ENABLE_WEB_REPLAY_macosx_Production = ;
-ENABLE_WEB_REPLAY_iphoneos = ;
-ENABLE_WEB_REPLAY_iphonesimulator = ;
+ENABLE_WEB_REPLAY = $(ENABLE_WEB_REPLAY_$(PLATFORM_NAME)_$(CONFIGURATION));
+ENABLE_WEB_REPLAY_macosx_Debug = ;
+ENABLE_WEB_REPLAY_macosx_Release = ;
 ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS;
 
-ENABLE_WEB_TIMING = $(ENABLE_WEB_TIMING_$(PLATFORM_NAME));
-ENABLE_WEB_TIMING_macosx = $(ENABLE_WEB_TIMING_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_WEB_TIMING_macosx_1080 = ;
+ENABLE_WEB_TIMING[sdk=iphone*] = ENABLE_WEB_TIMING;
+ENABLE_WEB_TIMING[sdk=macosx*] = $(ENABLE_WEB_TIMING_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 ENABLE_WEB_TIMING_macosx_1090 = ;
 ENABLE_WEB_TIMING_macosx_101000 = ENABLE_WEB_TIMING;
-ENABLE_WEB_TIMING_iphoneos = ;
-ENABLE_WEB_TIMING_iphonesimulator = ;
+ENABLE_WEB_TIMING_macosx_101100 = ENABLE_WEB_TIMING;
+ENABLE_WEB_TIMING_macosx_101200 = ENABLE_WEB_TIMING;
 
 ENABLE_WEBVTT_REGIONS = ENABLE_WEBVTT_REGIONS;
 ENABLE_XHR_TIMEOUT = ENABLE_XHR_TIMEOUT;
-ENABLE_XSLT = ENABLE_XSLT;
 
-ENABLE_FTL_JIT = $(ENABLE_FTL_JIT_$(PLATFORM_NAME));
-ENABLE_FTL_JIT_macosx = ENABLE_FTL_JIT;
-ENABLE_FTL_JIT_iphoneos = ENABLE_FTL_JIT;
-ENABLE_FTL_JIT_iphonesimulator = ;
+// FIXME: Remove the USE_INTERNAL_SDK condition once we support XSLT when building for iOS with the
+// public SDK. We will also need to update FeatureDefines.h.
+ENABLE_XSLT[sdk=macosx*] = ENABLE_XSLT;
+ENABLE_XSLT[sdk=iphone*] = $(ENABLE_XSLT_ios_WITH_INTERNAL_SDK_$(USE_INTERNAL_SDK));
+ENABLE_XSLT_ios_WITH_INTERNAL_SDK_YES = ENABLE_XSLT;
+
+ENABLE_FTL_JIT[sdk=macosx*] = ENABLE_FTL_JIT;
+ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
-ENABLE_LLINT_C_LOOP = ;
+ENABLE_SATURATED_LAYOUT_ARITHMETIC = ENABLE_SATURATED_LAYOUT_ARITHMETIC;
 
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR) $(ENABLE_IOS_AIRPLAY) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_LONG_PRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_PICTURE_SIZES) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_LLINT_C_LOOP) $(FEATURE_DEFINES_$(PLATFORM_NAME));
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE);
index 8190416480f65dd1d59717acd615dca7d28fb054..d1d32ef73ec166a0f3b6711b15ae5d7f4e9c379b 100644 (file)
@@ -26,8 +26,7 @@
 
 INSTALL_PATH_ACTUAL = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/$(JAVASCRIPTCORE_RESOURCES_DIR);
 PRODUCT_NAME = jsc;
-CODE_SIGN_ENTITLEMENTS = $(CODE_SIGN_ENTITLEMENTS_$(PLATFORM_NAME));
-CODE_SIGN_ENTITLEMENTS_iphoneos = entitlements.plist;
+CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*] = entitlements.plist;
 
 // Explicitly add the PrivateHeaders directory to the search path so that generated header files can be found in production builds.
 HEADER_SEARCH_PATHS = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders $(inherited);
index a02e6b36f2e0b3c2717473fe87c2737c0baad05e..0cb895f47837675fb24b9c830f9cfa08db98923a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 Apple Inc. All rights reserved.
+// Copyright (C) 2009, 2014 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
@@ -37,10 +37,13 @@ JSVALUE_MODEL_x86_64 = 64;
 OTHER_LDFLAGS_HIDE_SYMBOLS = -Wl,-unexported_symbol -Wl,__ZTISt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTISt9exception -Wl,-unexported_symbol -Wl,__ZTSSt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTSSt9exception -Wl,-unexported_symbol -Wl,__ZdlPvS_ -Wl,-unexported_symbol -Wl,__ZnwmPv -Wl,-unexported_symbol -Wl,__ZNKSt3__18functionIFvvEEclEv -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvvEEC1EOS2_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvvEEC2EOS2_ -Wl,-unexported_symbol -Wl,__ZNKSt3__18functionIFvRN3JSC17BytecodeGeneratorEPNS1_10RegisterIDEEEclES3_S5_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvRN3JSC17BytecodeGeneratorEPNS1_10RegisterIDEEED1Ev -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvRN3JSC17BytecodeGeneratorEPNS1_10RegisterIDEEED2Ev -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvvEED1Ev -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvvEED2Ev -Wl,-unexported_symbol -Wl,__ZTVNSt3__117bad_function_callE -Wl,-all_load;
 
 OTHER_LDFLAGS_BASE = -lobjc -Wl,-Y,3 $(OTHER_LDFLAGS_HIDE_SYMBOLS);
-OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_$(PLATFORM_NAME));
-OTHER_LDFLAGS_iphoneos = $(OTHER_LDFLAGS_BASE);
-OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_iphoneos);
-OTHER_LDFLAGS_macosx = $(OTHER_LDFLAGS_BASE) -sub_library libobjc -framework CoreServices;
+OTHER_LDFLAGS[sdk=iphone*] = $(inherited) $(OTHER_LDFLAGS_BASE);
+OTHER_LDFLAGS[sdk=macosx*] = $(inherited) $(OTHER_LDFLAGS_BASE) -sub_library libobjc -framework CoreServices;
+
+SECTORDER_FLAGS = $(SECTORDER_FLAGS_$(CONFIGURATION));
+SECTORDER_FLAGS_Production[sdk=iphoneos*] = -Wl,-order_file,$(SDKROOT)/AppleInternal/OrderFiles/JavaScriptCore.order;
+SECTORDER_FLAGS_Production[sdk=macosx*] = -Wl,-order_file,JavaScriptCore.order;
+
 GCC_PREFIX_HEADER = JavaScriptCorePrefix.h;
 GCC_SYMBOLS_PRIVATE_EXTERN = YES;
 HEADER_SEARCH_PATHS = "${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore" $(HEADER_SEARCH_PATHS);
@@ -51,6 +54,4 @@ PRODUCT_NAME = JavaScriptCore;
 
 INSTALLHDRS_SCRIPT_PHASE = YES;
 
-EXCLUDED_SOURCE_FILE_NAMES = $(EXCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME));
-EXCLUDED_SOURCE_FILE_NAMES_iphoneos = framework.sb;
-EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(EXCLUDED_SOURCE_FILE_NAMES_iphoneos);
+EXCLUDED_SOURCE_FILE_NAMES[sdk=iphone*] = framework.sb;
index 8a668425fa01da496a98dcd53a1477013f4126c8..9b4c44bd88270c2b7b4a3fa828badba6f2c823f7 100644 (file)
 // Only export our hook for initializing LLVM and returning the API struct.
 OTHER_LDFLAGS_HIDE_SYMBOLS = -Wl,-exported_symbol -Wl,_initializeAndGetJSCLLVMAPI -Wl,-all_load;
 
-LLVM_LIBS_ios = -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMBitWriter -lLLVMTableGen -lLLVMInstrumentation -lLLVMIRReader -lLLVMBitReader -lLLVMAsmParser -lLLVMARM64Disassembler -lLLVMARM64CodeGen -lLLVMARM64AsmParser -lLLVMARM64Desc -lLLVMARM64Info -lLLVMARM64AsmPrinter -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMDebugInfo -lLLVMOption -lLLVMInterpreter -lLLVMJIT -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport -lprotobuf
+LLVM_LIBS_ios = -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMIRReader -lLLVMBitReader -lLLVMAsmParser -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMDebugInfo -lLLVMOption -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils;
+LLVM_LIBS_ios_8_0 = -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMBitWriter -lLLVMTableGen -lLLVMInstrumentation -lLLVMIRReader -lLLVMBitReader -lLLVMAsmParser -lLLVMARM64Disassembler -lLLVMARM64CodeGen -lLLVMARM64AsmParser -lLLVMARM64Desc -lLLVMARM64Info -lLLVMARM64AsmPrinter -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMDebugInfo -lLLVMOption -lLLVMInterpreter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport -lprotobuf;
+LLVM_LIBS_ios[sdk=iphoneos8.0*] = $(LLVM_LIBS_ios_8_0);
+LLVM_LIBS_ios[sdk=iphoneos8.1*] = $(LLVM_LIBS_ios_8_0);
+LLVM_LIBS_ios[sdk=iphoneos8.2*] = $(LLVM_LIBS_ios_8_0);
+LLVM_LIBS_macosx   = -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMIRReader -lLLVMBitReader -lLLVMAsmParser -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMMCParser -lLLVMDebugInfo -lLLVMOption -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMMCDisassembler -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport -lLLVMX86Disassembler     -lLLVMX86CodeGen     -lLLVMX86AsmParser     -lLLVMX86Desc     -lLLVMX86Info     -lLLVMX86AsmPrinter     -lLLVMX86Utils;
 
-#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/AspenLLVM.xcconfig"
+LLVM_LIBRARY_PATHS[sdk=iphoneos*] = "$(BUILT_PRODUCTS_DIR)/usr/local/lib" /usr/local/lib;
+LLVM_LIBRARY_PATHS[sdk=macosx*] = "$(BUILT_PRODUCTS_DIR)/usr/local/LLVMForJavaScriptCore/lib" /usr/local/LLVMForJavaScriptCore/lib;
 
-// In general, we prefer to not append libraries this way because it may interfere with the required
-// ordering of library linkage (as determined by their dependencies on other libraries).  In this
-// case, we'll make this a one time exception to work around the fact that there are pre-existing
-// versions of AspenLLVM.xcconfig that overrides LLVM_LIBS_ios but is missing -lLLVMMCDisassembler.
-LLVM_LIBS_iphoneos = $(LLVM_LIBS_ios) -lLLVMMCDisassembler
+LIBRARY_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR) $(LLVM_LIBRARY_PATHS) $(LIBRARY_SEARCH_PATHS);
 
-LLVM_LIBS_macosx = -lLLVMTableGen -lLLVMDebugInfo -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMIRReader -lLLVMAsmParser -lLLVMMCDisassembler -lLLVMMCParser -lLLVMInstrumentation -lLLVMBitReader -lLLVMInterpreter -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMBitWriter -lLLVMMCJIT -lLLVMJIT -lLLVMCodeGen -lLLVMObjCARCOpts -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMTarget -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport;
+OTHER_LDFLAGS_LLVM = $(OTHER_LDFLAGS_LLVM_$(ENABLE_FTL_JIT)_$(CURRENT_ARCH));
+OTHER_LDFLAGS_LLVM_ENABLE_FTL_JIT_arm64[sdk=iphoneos*] = -lpthread -lm $(LLVM_LIBS_ios);
+OTHER_LDFLAGS_LLVM_ENABLE_FTL_JIT_x86_64[sdk=macosx*] = -lpthread -lm $(LLVM_LIBS_macosx);
 
-LLVM_LIBRARY_PATHS = $(LLVM_LIBRARY_PATHS_$(PLATFORM_NAME))
-LLVM_LIBRARY_PATHS_macosx = "${BUILT_PRODUCTS_DIR}/usr/local/LLVMForJavaScriptCore/lib" /usr/local/LLVMForJavaScriptCore/lib;
-LLVM_LIBRARY_PATHS_iphoneos = "${BUILT_PRODUCTS_DIR}/usr/local/lib" /usr/local/lib;
-LLVM_LIBRARY_PATHS_iphonesimulator = ;
-
-LIBRARY_SEARCH_PATHS = ${BUILT_PRODUCTS_DIR} $(LLVM_LIBRARY_PATHS) $(LIBRARY_SEARCH_PATHS)
-
-OTHER_LDFLAGS_LLVM = $(OTHER_LDFLAGS_LLVM_$(ENABLE_FTL_JIT));
-OTHER_LDFLAGS_LLVM_ = ;
-OTHER_LDFLAGS_LLVM_ENABLE_FTL_JIT = -lpthread -lm $(LLVM_LIBS_$(PLATFORM_NAME));
-
-OTHER_LDFLAGS_BASE = -lobjc -Wl,-Y,3 $(OTHER_LDFLAGS_HIDE_SYMBOLS);
-OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_$(PLATFORM_NAME));
-OTHER_LDFLAGS_iphoneos = $(OTHER_LDFLAGS_BASE) $(OTHER_LDFLAGS_LLVM);
-OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_iphoneos);
-OTHER_LDFLAGS_macosx = $(OTHER_LDFLAGS_BASE) $(OTHER_LDFLAGS_LLVM)
+OTHER_LDFLAGS = $(inherited) -lobjc -Wl,-Y,3 $(OTHER_LDFLAGS_HIDE_SYMBOLS) $(OTHER_LDFLAGS_LLVM);
 GCC_SYMBOLS_PRIVATE_EXTERN = YES;
 HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore" $(HEADER_SEARCH_PATHS);
 
index 69293109b684d30c1328bf3df99796b7d4fef8a0..6ffcc873076e8f426e798d696380e77b99070831 100644 (file)
 
 INSTALL_PATH_ACTUAL = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/$(JAVASCRIPTCORE_RESOURCES_DIR);
 PRODUCT_NAME = $(TARGET_NAME);
-CODE_SIGN_ENTITLEMENTS = $(CODE_SIGN_ENTITLEMENTS_$(PLATFORM_NAME)_$(TARGET_NAME));
-CODE_SIGN_ENTITLEMENTS_iphoneos_minidom = entitlements.plist;
-CODE_SIGN_ENTITLEMENTS_iphoneos_testapi = entitlements.plist;
-CODE_SIGN_ENTITLEMENTS_iphoneos_testRegExp = entitlements.plist;
+CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*] = $(CODE_SIGN_ENTITLEMENTS_ios_$(TARGET_NAME));
+CODE_SIGN_ENTITLEMENTS_ios_minidom = entitlements.plist;
+CODE_SIGN_ENTITLEMENTS_ios_testapi = entitlements.plist;
+CODE_SIGN_ENTITLEMENTS_ios_testRegExp = entitlements.plist;
 
 SKIP_INSTALL = $(SKIP_INSTALL_$(FORCE_TOOL_INSTALL));
 SKIP_INSTALL_ = YES;
@@ -38,8 +38,7 @@ SKIP_INSTALL_YES = NO;
 
 GCC_ENABLE_OBJC_GC = NO;
 CLANG_ENABLE_OBJC_ARC = $(CLANG_ENABLE_OBJC_ARC_$(CURRENT_ARCH));
-CLANG_ENABLE_OBJC_ARC_i386 = $(CLANG_ENABLE_OBJC_ARC_i386_$(PLATFORM_NAME));
-CLANG_ENABLE_OBJC_ARC_i386_iphonesimulator = YES; # For iOS Simulator version 4.0 and greater
+CLANG_ENABLE_OBJC_ARC_i386[sdk=iphonesimulator*] = YES;
 CLANG_ENABLE_OBJC_ARC_x86_64 = YES;
 CLANG_ENABLE_OBJC_ARC_armv7 = YES;
 CLANG_ENABLE_OBJC_ARC_armv7k = YES;
@@ -51,4 +50,4 @@ OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
 OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
 
 // Explicitly add the PrivateHeaders directory to the search path so that generated header files can be found in production builds.
-HEADER_SEARCH_PATHS = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders $(inherited);
\ No newline at end of file
+HEADER_SEARCH_PATHS = $(JAVASCRIPTCORE_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders $(inherited);
index 985194fd69fedf82c0fcebded3ab97b173c5d6df..04ef8f14463f9280a7d9fff0fec346d4403c9d57 100644 (file)
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
-MAJOR_VERSION = 600;
+MAJOR_VERSION = 601;
 MINOR_VERSION = 1;
-TINY_VERSION = 4;
-MICRO_VERSION = 17;
-NANO_VERSION = 5;
-FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(TINY_VERSION).$(MICRO_VERSION).$(NANO_VERSION);
+TINY_VERSION = 46;
+MICRO_VERSION = 3;
+NANO_VERSION = 0;
+FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(TINY_VERSION).$(MICRO_VERSION);
 
 // The bundle version and short version string are set based on the current build configuration, see below.
 BUNDLE_VERSION = $(BUNDLE_VERSION_$(CONFIGURATION));
 SHORT_VERSION_STRING = $(SHORT_VERSION_STRING_$(CONFIGURATION))
 
 // The system version prefix is based on the current system version.
-SYSTEM_VERSION_PREFIX = $(SYSTEM_VERSION_PREFIX_$(PLATFORM_NAME));
-SYSTEM_VERSION_PREFIX_iphoneos = 8;
-SYSTEM_VERSION_PREFIX_iphonesimulator = $(SYSTEM_VERSION_PREFIX_iphoneos);
-SYSTEM_VERSION_PREFIX_macosx = $(SYSTEM_VERSION_PREFIX_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-SYSTEM_VERSION_PREFIX_macosx_1080 = 8;
+SYSTEM_VERSION_PREFIX[sdk=iphone*] = 8;
+SYSTEM_VERSION_PREFIX = $(SYSTEM_VERSION_PREFIX_$(PLATFORM_NAME)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
 SYSTEM_VERSION_PREFIX_macosx_1090 = 9;
 SYSTEM_VERSION_PREFIX_macosx_101000 = 10;
+SYSTEM_VERSION_PREFIX_macosx_101100 = 11;
+SYSTEM_VERSION_PREFIX_macosx_101200 = 12;
 
 // The production build always uses the full version with a system version prefix.
 BUNDLE_VERSION_Production = $(SYSTEM_VERSION_PREFIX)$(FULL_VERSION);
diff --git a/Configurations/iOS.xcconfig b/Configurations/iOS.xcconfig
deleted file mode 100644 (file)
index 177b319..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/AspenFamily.xcconfig"
index cc307d7e7479b9bf90a8a3efbf13c9873a3883b8..677f4cee693560459e80787a608656822a5f475a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
+# Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -36,7 +36,7 @@ VPATH = \
 .PHONY : all
 all : \
     ArrayConstructor.lut.h \
-    ArrayPrototype.lut.h \
+    ArrayIteratorPrototype.lut.h \
     BooleanPrototype.lut.h \
     DateConstructor.lut.h \
     DatePrototype.lut.h \
@@ -48,15 +48,16 @@ all : \
     JSPromiseConstructor.lut.h \
     KeywordLookup.h \
     Lexer.lut.h \
-    NamePrototype.lut.h \
     NumberConstructor.lut.h \
     NumberPrototype.lut.h \
     ObjectConstructor.lut.h \
     RegExpConstructor.lut.h \
     RegExpPrototype.lut.h \
     RegExpJitTables.h \
-    RegExpObject.lut.h \
     StringConstructor.lut.h \
+    StringIteratorPrototype.lut.h \
+    SymbolConstructor.lut.h \
+    SymbolPrototype.lut.h \
     udis86_itab.h \
     Bytecodes.h \
     InitBytecodes.asm \
@@ -66,28 +67,28 @@ all : \
 # builtin functions
 .PHONY: JSCBuiltins
 
-# Windows has specific needs for specifying the path to its interpreters
+PYTHON = python
+PERL = perl
+
 ifeq ($(OS),Windows_NT)
-    PYTHON = /usr/bin/python
-    PERL = /usr/bin/perl
+    DELETE = cmd //C del
 else
-    PYTHON = python
-    PERL = perl
+    DELETE = rm -f
 endif
 # --------
 
 JSCBuiltins: $(JavaScriptCore)/generate-js-builtins JSCBuiltins.h JSCBuiltins.cpp
-JSCBuiltins.h: $(JavaScriptCore)/generate-js-builtins $(JavaScriptCore)/builtins/*.js
-       $(PYTHON) $^ $@
+JSCBuiltins.h: $(JavaScriptCore)/generate-js-builtins $(JavaScriptCore)/builtins
+       $(PYTHON) $(JavaScriptCore)/generate-js-builtins --input-directory $(JavaScriptCore)/builtins --output $@
                                                                                                                                                                 
 JSCBuiltins.cpp: JSCBuiltins.h
 
 # lookup tables for classes
 
 %.lut.h: create_hash_table %.cpp
-       $^ -i > $@
+       $(PERL) $^ -i > $@
 Lexer.lut.h: create_hash_table Keywords.table
-       $^ > $@
+       $(PERL) $^ > $@
 
 # character tables for Yarr
 
@@ -100,7 +101,7 @@ KeywordLookup.h: KeywordLookupGenerator.py Keywords.table
 # udis86 instruction tables
 
 udis86_itab.h: $(JavaScriptCore)/disassembler/udis86/itab.py $(JavaScriptCore)/disassembler/udis86/optable.xml
-       (PYTHONPATH=$(JavaScriptCore)/disassembler/udis86 $(PYTHON) $(JavaScriptCore)/disassembler/udis86/itab.py $(JavaScriptCore)/disassembler/udis86/optable.xml || exit 1)
+       $(PYTHON) $(JavaScriptCore)/disassembler/udis86/itab.py $(JavaScriptCore)/disassembler/udis86/optable.xml
 
 # Bytecode files
 
@@ -113,22 +114,54 @@ InitBytecodes.asm: $(JavaScriptCore)/generate-bytecode-files $(JavaScriptCore)/b
 # Inspector interfaces
 
 INSPECTOR_DOMAINS = \
+    $(JavaScriptCore)/inspector/protocol/ApplicationCache.json \
+    $(JavaScriptCore)/inspector/protocol/CSS.json \
     $(JavaScriptCore)/inspector/protocol/Console.json \
+    $(JavaScriptCore)/inspector/protocol/DOM.json \
+    $(JavaScriptCore)/inspector/protocol/DOMDebugger.json \
+    $(JavaScriptCore)/inspector/protocol/DOMStorage.json \
+    $(JavaScriptCore)/inspector/protocol/Database.json \
     $(JavaScriptCore)/inspector/protocol/Debugger.json \
     $(JavaScriptCore)/inspector/protocol/GenericTypes.json \
-    $(JavaScriptCore)/inspector/protocol/InspectorDomain.json \
-    $(JavaScriptCore)/inspector/protocol/Profiler.json \
+    $(JavaScriptCore)/inspector/protocol/Inspector.json \
+    $(JavaScriptCore)/inspector/protocol/LayerTree.json \
+    $(JavaScriptCore)/inspector/protocol/Network.json \
+    $(JavaScriptCore)/inspector/protocol/OverlayTypes.json \
+    $(JavaScriptCore)/inspector/protocol/Page.json \
     $(JavaScriptCore)/inspector/protocol/Runtime.json \
+    $(JavaScriptCore)/inspector/protocol/Timeline.json \
+    $(JavaScriptCore)/inspector/protocol/Worker.json \
 #
 
+ifeq ($(findstring ENABLE_INDEXED_DATABASE,$(FEATURE_DEFINES)), ENABLE_INDEXED_DATABASE)
+    INSPECTOR_DOMAINS := $(INSPECTOR_DOMAINS) $(JavaScriptCore)/inspector/protocol/IndexedDB.json
+endif
+
+ifeq ($(findstring ENABLE_WEB_REPLAY,$(FEATURE_DEFINES)), ENABLE_WEB_REPLAY)
+    INSPECTOR_DOMAINS := $(INSPECTOR_DOMAINS) $(JavaScriptCore)/inspector/protocol/Replay.json
+endif
+
 INSPECTOR_GENERATOR_SCRIPTS = \
-       $(JavaScriptCore)/inspector/scripts/CodeGeneratorInspector.py \
-       $(JavaScriptCore)/inspector/scripts/CodeGeneratorInspectorStrings.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/__init__.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/cpp_generator_templates.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/cpp_generator.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_protocol_types_header.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_cpp_protocol_types_implementation.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generate_js_backend_commands.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generator_templates.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/generator.py \
+       $(JavaScriptCore)/inspector/scripts/codegen/models.py \
+       $(JavaScriptCore)/inspector/scripts/generate-combined-inspector-json.py \
+       $(JavaScriptCore)/inspector/scripts/generate-inspector-protocol-bindings.py \
 #
 
 all : \
-    InspectorJS.json \
-    InspectorJSFrontendDispatchers.h \
+    CombinedDomains.json \
+    InspectorFrontendDispatchers.h \
     InjectedScriptSource.h \
 #
 
@@ -136,21 +169,21 @@ all : \
 # adding, modifying, or removing domains will trigger regeneration of inspector files.
 
 .PHONY: force
-EnabledInspectorDomains : force
-       echo '$(INSPECTOR_DOMAINS)' | cmp -s - $@ || echo '$(INSPECTOR_DOMAINS)' > $@
+EnabledInspectorDomains : $(JavaScriptCore)/UpdateContents.py force
+       $(PYTHON) $(JavaScriptCore)/UpdateContents.py '$(INSPECTOR_DOMAINS)' $@
 
-InspectorJS.json : inspector/scripts/generate-combined-inspector-json.py $(INSPECTOR_DOMAINS) EnabledInspectorDomains
-       $(PYTHON) $(JavaScriptCore)/inspector/scripts/generate-combined-inspector-json.py $(INSPECTOR_DOMAINS) > ./InspectorJS.json
+CombinedDomains.json : inspector/scripts/generate-combined-inspector-json.py $(INSPECTOR_DOMAINS) EnabledInspectorDomains
+       $(PYTHON) $(JavaScriptCore)/inspector/scripts/generate-combined-inspector-json.py $(INSPECTOR_DOMAINS) > ./CombinedDomains.json
 
 # Inspector Backend Dispatchers, Frontend Dispatchers, Type Builders
-InspectorJSFrontendDispatchers.h : InspectorJS.json $(INSPECTOR_GENERATOR_SCRIPTS)
-       $(PYTHON) $(JavaScriptCore)/inspector/scripts/CodeGeneratorInspector.py ./InspectorJS.json --output_h_dir . --output_cpp_dir . --output_js_dir . --output_type JavaScript
+InspectorFrontendDispatchers.h : CombinedDomains.json $(INSPECTOR_GENERATOR_SCRIPTS)
+       $(PYTHON) $(JavaScriptCore)/inspector/scripts/generate-inspector-protocol-bindings.py --framework JavaScriptCore --outputDir . ./CombinedDomains.json
 
 InjectedScriptSource.h : inspector/InjectedScriptSource.js $(JavaScriptCore)/inspector/scripts/jsmin.py $(JavaScriptCore)/inspector/scripts/xxd.pl
        echo "//# sourceURL=__WebInspectorInjectedScript__" > ./InjectedScriptSource.min.js
        $(PYTHON) $(JavaScriptCore)/inspector/scripts/jsmin.py < $(JavaScriptCore)/inspector/InjectedScriptSource.js >> ./InjectedScriptSource.min.js
        $(PERL) $(JavaScriptCore)/inspector/scripts/xxd.pl InjectedScriptSource_js ./InjectedScriptSource.min.js InjectedScriptSource.h
-       rm -f ./InjectedScriptSource.min.js
+       $(DELETE) InjectedScriptSource.min.js
 
 # Web Replay inputs generator
 
index 7a2f110ce3a9e3da53da2d5f163763792eae454b..e5675ce0e19722f1114c1a64dd4cc862ef58ea74 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundleGetInfoString</key>
-       <string>${BUNDLE_VERSION}, Copyright 2003-2014 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
+       <string>${BUNDLE_VERSION}, Copyright 2003-2015 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.${PRODUCT_NAME}</string>
        <key>CFBundleInfoDictionaryVersion</key>
index 633dd456be09a15a2393721ada1abea8a1aebc5f..6a3c1a5ef36e6fc1a80849752d39c3d648d4d8c3 100644 (file)
@@ -173,20 +173,14 @@ __ZN3JSC19ExecutableAllocatorC1ERNS_2VME
 __ZN3JSC4HeapC1EPNS_2VMENS_8HeapTypeE
 __ZN3JSC4HeapC2EPNS_2VMENS_8HeapTypeE
 __ZN3WTF7ramSizeEv
-__ZN3JSC14BlockAllocatorC1Ev
 __ZN3JSC11SuperRegionC1Ev
 __ZN3JSC11MarkedSpaceC1EPNS_4HeapE
 __ZN3JSC11MarkedSpaceC2EPNS_4HeapE
 __ZN3JSC11CopiedSpaceC1EPNS_4HeapE
 __ZN3JSC14MachineThreadsC1EPNS_4HeapE
 __ZN3JSC18GCThreadSharedDataC1EPNS_2VME
-__ZN3JSC14BlockAllocator27blockFreeingThreadStartFuncEPv
 __ZN3JSC18GCThreadSharedDataC2EPNS_2VME
-__ZN3JSC14MarkStackArrayC1ERNS_14BlockAllocatorE
-__ZN3JSC14BlockAllocator22blockFreeingThreadMainEv
-__ZN3JSC14BlockAllocator8allocateINS_16MarkStackSegmentEEEPNS_9DeadBlockEv
 __ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
-__ZN3JSC14BlockAllocator21tryAllocateFromRegionERNS0_9RegionSetERN3WTF16DoublyLinkedListINS_6RegionEEERm
 __ZN3WTF21PageAllocationAligned8allocateEmmNS_11OSAllocator5UsageEb
 __ZN3JSC11SlotVisitorC1ERNS_18GCThreadSharedDataE
 __ZN3JSC11CopyVisitorC1ERNS_18GCThreadSharedDataE
@@ -198,7 +192,6 @@ __ZN3JSC8GCThread12gcThreadMainEv
 __ZN3WTF16registerGCThreadEv
 __ZN3JSC8GCThread16waitForNextPhaseEv
 __ZN3JSC9HandleSetC1EPNS_2VME
-__ZN3JSC14BlockAllocator8allocateINS_11HandleBlockEEEPNS_9DeadBlockEv
 __ZN3JSC11HandleStackC1Ev
 __ZN3WTF10BlockStackIN3JSC7JSValueEE4growEv
 __ZN3WTF6VectorIPN3JSC7JSValueELm0ENS_15CrashOnOverflowEE14expandCapacityEm
@@ -210,7 +203,6 @@ __ZN3JSCL13retainAPILockEPKv
 __ZN3JSC18IncrementalSweeper6createEPNS_4HeapE
 __ZN3JSC11CopiedSpace4initEv
 __ZN3JSC11CopiedSpace13allocateBlockEv
-__ZN3JSC14BlockAllocator8allocateINS_11CopiedBlockEEEPNS_9DeadBlockEv
 __ZN3WTF9HashTableIPN3JSC11CopiedBlockES3_NS_17IdentityExtractorENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES8_E3addINS_22IdentityHashTranslatorIS6_EES3_S3_EENS_18HashTableAddResultINS_17HashTableIteratorIS3_S3_S4_S6_S8_S8_EEEERKT0_RKT1_
 __ZN3JSC8WatchdogC1Ev
 __ZN3JSC8Watchdog9initTimerEv
@@ -233,7 +225,6 @@ __ZN3JSC15MarkedAllocator16allocateSlowCaseEm
 __ZN3JSC4Heap11didAllocateEm
 __ZN3JSC25DefaultGCActivityCallback11didAllocateEm
 __ZN3JSC15MarkedAllocator13allocateBlockEm
-__ZN3JSC14BlockAllocator8allocateINS_11MarkedBlockEEEPNS_9DeadBlockEv
 __ZN3JSC11MarkedBlock6createEPNS_9DeadBlockEPNS_15MarkedAllocatorEmNS0_14DestructorTypeE
 __ZN3JSC11MarkedBlock5sweepENS0_9SweepModeE
 __ZN3JSC7WeakSet5sweepEv
@@ -285,7 +276,6 @@ __ZN3JSC9Structure16putSpecificValueERNS_2VMENS_12PropertyNameEjPNS_6JSCellE
 __ZN3JSC13PropertyTable3addERKNS_16PropertyMapEntryERiNS0_22EffectOnPropertyOffsetE
 __ZN3JSC24StructureTransitionTable3addERNS_2VMEPNS_9StructureE
 __ZN3JSC7WeakSet13findAllocatorEv
-__ZN3JSC14BlockAllocator8allocateINS_9WeakBlockEEEPNS_9DeadBlockEv
 __ZN3JSC9WeakBlock6createEPNS_9DeadBlockE
 __ZN3JSC8JSObject43setStructureAndReallocateStorageIfNecessaryERNS_2VMEPNS_9StructureE
 __ZN3JSC8JSObject20growOutOfLineStorageERNS_2VMEmm
@@ -553,7 +543,6 @@ __ZN3JSC25JSSegmentedVariableObject13visitChildrenEPNS_6JSCellERNS_11SlotVisitor
 __ZN3JSC19JSSymbolTableObject13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC7JSScope13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC11CopiedBlock15reportLiveBytesEPNS_6JSCellEj
-__ZN3JSC14BlockAllocator8allocateINS_19CopyWorkListSegmentEEEPNS_9DeadBlockEv
 __ZN3JSC13PropertyTable13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC12RegExpObject13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC6JSCell13visitChildrenEPS0_RNS_11SlotVisitorE
@@ -590,7 +579,6 @@ __ZN3JSC4Heap17copyBackingStoresEv
 __ZN3JSC11CopiedSpace14startedCopyingEv
 __ZN3JSC11MarkedSpace12forEachBlockINS_8CapacityEEENT_10ReturnTypeERS3_
 __ZN3JSC11CopiedSpace11doneCopyingEv
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_19CopyWorkListSegmentEEEEEvPT_
 __ZN3JSC11SlotVisitor31finalizeUnconditionalFinalizersEv
 __ZN3JSC12SmallStrings20finalizeSmallStringsEv
 __ZN3JSC4Heap26deleteUnmarkedCompiledCodeEv
@@ -637,7 +625,6 @@ __ZN3JSC14MachineThreads29makeUsableFromMultipleThreadsEv
 __ZN3JSC12GlobalJSLockD1Ev
 _JSGlobalContextCreateInGroup
 __ZN3JSC14JSGlobalObjectC1ERNS_2VMEPNS_9StructureEPKNS_23GlobalObjectMethodTableE
-__ZN3JSC14JSGlobalObject28javaScriptExperimentsEnabledEPKS0_
 _JSGlobalContextRetain
 _JSStringCreateWithCFString
 _JSEvaluateScript
@@ -1049,7 +1036,6 @@ __ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansENS_11HardenedSLLE
 __ZN3JSC11CopiedSpace21recycleEvacuatedBlockEPNS_11CopiedBlockE
 __ZN3WTF7HashSetIPN3JSC11CopiedBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE6removeERKS3_
 __ZN3WTF7HashSetIPN3JSC11CopiedBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE6removeENS_29HashTableConstIteratorAdapterINS_9HashTableIS3_S3_NS_17IdentityExtractorES5_S7_S7_EES3_EE
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_11CopiedBlockEEEEEvPT_
 __ZN3WTF13StringBuilder6appendEPKtj
 __ZN3JSC24UnlinkedProgramCodeBlock13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC17UnlinkedCodeBlock13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
@@ -1300,7 +1286,6 @@ __ZN3WTF9HashTableINSt3__14pairIPN3JSC8JSObjectEjEENS_12KeyValuePairIS6_NS3_4Wea
 __ZN3WTF9HashTableINSt3__14pairIPN3JSC8JSObjectEjEENS_12KeyValuePairIS6_NS3_4WeakINS3_9StructureEEEEENS_24KeyValuePairKeyExtractorISB_EENS_8PairHashIS5_jEENS_18HashMapValueTraitsINS_10HashTraitsIS6_EENSH_ISA_EEEESI_E3addINS_17HashMapTranslatorISK_SF_EES6_NS3_8PassWeakIS9_EEEENS_18HashTableAddResultINS_17HashTableIteratorIS6_SB_SD_SF_SK_SI_EEEERKT0_RKT1_
 __ZN3WTF9HashTableINSt3__14pairIPN3JSC8JSObjectEjEENS_12KeyValuePairIS6_NS3_4WeakINS3_9StructureEEEEENS_24KeyValuePairKeyExtractorISB_EENS_8PairHashIS5_jEENS_18HashMapValueTraitsINS_10HashTraitsIS6_EENSH_ISA_EEEESI_E6lookupINS_22IdentityHashTranslatorISF_EES6_EEPSB_RKT0_
 __ZN3WTF9HashTableINSt3__14pairIPN3JSC8JSObjectEjEENS_12KeyValuePairIS6_NS3_4WeakINS3_9StructureEEEEENS_24KeyValuePairKeyExtractorISB_EENS_8PairHashIS5_jEENS_18HashMapValueTraitsINS_10HashTraitsIS6_EENSH_ISA_EEEESI_E6rehashEi
-__ZN3JSC12JSActivation6createERNS_2VMEPNS_9ExecStateEPNS_9CodeBlockE
 __ZNK3JSC7JSValue3getEPNS_9ExecStateENS_12PropertyNameERNS_12PropertySlotE
 __ZNK3JSC19BracketAccessorNode10isLocationEv
 __ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
@@ -1312,8 +1297,6 @@ __ZNK3JSC7JSScope14isDynamicScopeERb
 __ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
 __ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEPNS_9StructureEPNS_6RegExpE
-__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameERNS_12PropertySlotE
-__ZN3JSC12JSActivation14symbolTableGetENS_12PropertyNameERNS_12PropertySlotE
 __ZN3JSC17ObjectConstructor18getOwnPropertySlotEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameERNS_12PropertySlotE
 __ZN3JSC21getStaticFunctionSlotINS_8JSObjectEEEbPNS_9ExecStateEPKNS_9HashTableEPS1_NS_12PropertyNameERNS_12PropertySlotE
 __ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameERNS_12PropertySlotE
@@ -1352,9 +1335,7 @@ __ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_S2_S2_S2_P
 __ZN3JSC11PostfixNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC11PostfixNode11emitResolveERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator7emitIncEPNS_10RegisterIDE
-__ZN3JSC14jsIsObjectTypeEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC6JSCell11getCallDataEPS0_RNS_8CallDataE
-__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateEPNS_8JSObjectE
 __ZN3JSC8JSObject16getPropertyNamesEPS0_PNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC8JSObject19getOwnPropertyNamesEPS0_PNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC8JSObject27getOwnNonIndexPropertyNamesEPS0_PNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
@@ -1638,13 +1619,10 @@ __ZN3JSC3JIT19emit_compareAndJumpENS_8OpcodeIDEjjjNS_23MacroAssemblerX86Common19
 __ZN3JSC3JIT17emit_op_loop_hintEPNS_11InstructionE
 __ZN3JSC8Watchdog9isEnabledEv
 __ZN3JSC3JIT16emit_op_jeq_nullEPNS_11InstructionE
-__ZN3JSC3JIT18emit_op_get_pnamesEPNS_11InstructionE
 __ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE
-__ZN3JSC3JIT20emit_op_get_by_pnameEPNS_11InstructionE
 __ZN3JSC3JIT22compileGetDirectOffsetENS_12X86Registers10RegisterIDES2_S2_S2_NS0_15FinalObjectModeE
 __ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE
 __ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE
-__ZN3JSC3JIT18emit_op_next_pnameEPNS_11InstructionE
 __ZN3JSC3JIT11emit_op_incEPNS_11InstructionE
 __ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE
 __ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE
@@ -1663,7 +1641,6 @@ __ZN3JSC3JIT23emit_compareAndJumpSlowEjjjNS_23MacroAssemblerX86Common15DoubleCon
 __ZN3JSC12X86Assembler23X86InstructionFormatter11twoByteOp64ENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDE
 __ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_
 __ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDE
-__ZN3JSC3JIT24emitSlow_op_get_by_pnameEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT15emitSlow_op_incEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE
@@ -1674,8 +1651,7 @@ _cti_op_get_by_val_generic
 __ZN3JSCL8getByValEPNS_9ExecStateENS_7JSValueES2_NS_16ReturnAddressPtrE
 _cti_op_stricteq
 _cti_op_jtrue
-_cti_op_is_object
-_cti_op_get_pnames
+_cti_op_is_object_or_null
 __ZN3JSC8JSString12toThisObjectEPNS_6JSCellEPNS_9ExecStateE
 __ZN3JSC12StringObjectC1ERNS_2VMEPNS_9StructureE
 __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
@@ -2622,7 +2598,6 @@ __ZN3JSC17JITStubRoutineSet8markSlowEm
 __ZN3WTF7HashMapImPN3JSC21GCAwareJITStubRoutineENS_7IntHashImEENS_10HashTraitsImEENS6_IS3_EEE4findERKm
 __ZN3JSC13JSFinalObject13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC17StructureRareData13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
-__ZN3JSC22JSPropertyNameIterator13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC14StructureChain13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC14MarkStackArray6expandEv
 __ZN3JSC17ProgramExecutable13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
@@ -2631,12 +2606,10 @@ __ZN3JSC18FunctionExecutable13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC9CodeBlock29stronglyVisitStrongReferencesERNS_11SlotVisitorE
 __ZN3JSC13EvalCodeCache14visitAggregateERNS_11SlotVisitorE
 __ZN3JSC9CodeBlock27stronglyVisitWeakReferencesERNS_11SlotVisitorE
-__ZN3JSC12JSActivation13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC9CodeBlock31performTracingFixpointIterationERNS_11SlotVisitorE
 __ZN3JSC16JSCallbackObjectINS_20JSDestructibleObjectEE13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3JSC18RegExpMatchesArray13visitChildrenEPNS_6JSCellERNS_11SlotVisitorE
 __ZN3WTF9HashTableIPvS1_NS_17IdentityExtractorENS_7PtrHashIS1_EENS_10HashTraitsIS1_EES6_E16lookupForWritingINS_22IdentityHashTranslatorIS4_EES1_EENSt3__14pairIPS1_bEERKT0_
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_16MarkStackSegmentEEEEEvPT_
 __ZThn16_N3JSC9CodeBlock19visitWeakReferencesERNS_11SlotVisitorE
 __ZN3JSC9CodeBlock23finalizeUnconditionallyEv
 __ZN3JSC17StructureStubInfo19visitWeakReferencesEv
@@ -2666,7 +2639,6 @@ __ZN3JSC18FunctionExecutable7destroyEPNS_6JSCellE
 __ZN3JSC17ProgramExecutable7destroyEPNS_6JSCellE
 __ZN3JSC17SharedSymbolTable7destroyEPNS_6JSCellE
 __ZN3JSC10JSFunction7destroyEPNS_6JSCellE
-__ZN3JSC22JSPropertyNameIterator7destroyEPNS_6JSCellE
 __ZN3JSC19ResolveGlobalStatus10computeForEPNS_9CodeBlockEiPNS_16ResolveOperationERNS_10IdentifierE
 __ZN3JSC13GetByIdStatus10computeForERNS_2VMEPNS_9StructureERNS_10IdentifierE
 __ZN3JSC3DFG14SpeculativeJIT23emitObjectOrOtherBranchENS0_4EdgeEjj
@@ -2897,13 +2869,11 @@ __ZN3JSC11MarkedSpace9freeBlockEPNS_11MarkedBlockE
 __ZN3JSC15MarkedAllocator11removeBlockEPNS_11MarkedBlockE
 __ZN3WTF7HashSetIPN3JSC11MarkedBlockENS_15MarkedBlockHashENS_10HashTraitsIS3_EEE6removeERKS3_
 __ZN3JSC7WeakSetD1Ev
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_11MarkedBlockEEEEEvPT_
 __ZN3JSC16NativeExecutable7destroyEPNS_6JSCellE
 __ZN3JSC11RegExpCache8finalizeENS_6HandleINS_7UnknownEEEPv
 __ZN3JSC6RegExp14invalidateCodeEv
 __ZN3JSC6RegExp7destroyEPNS_6JSCellE
 __ZN3JSC4Yarr13YarrCodeBlockD2Ev
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_9WeakBlockEEEEEvPT_
 __ZN3JSC17RegExpConstructor7destroyEPNS_6JSCellE
 __ZN3JSC4Heap14FinalizerOwner8finalizeENS_6HandleINS_7UnknownEEEPv
 __ZN3JSC14JSGlobalObject7destroyEPNS_6JSCellE
@@ -2976,7 +2946,6 @@ __ZN3JSC6ParserINS_5LexerItEEE19parseBreakStatementINS_10ASTBuilderEEENT_9Statem
 __ZN3WTF6VectorIPN3JSC8JSObjectELm4ENS_15CrashOnOverflowEE15reserveCapacityEm
 __ZN3WTF15BinarySemaphore4waitEd
 __ZN3WTF15BinarySemaphore6signalEv
-_JSValueIsObject
 __ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateE
 __ZN3JSC5shiftILNS_7JSArray14ShiftCountModeE0EEEvPNS_9ExecStateEPNS_8JSObjectEjjjj
 __ZN3JSC7JSArray26shiftCountWithArrayStorageEjjPNS_12ArrayStorageE
@@ -3068,7 +3037,6 @@ __ZNK3JSC26UnlinkedFunctionExecutable11paramStringEv
 __ZN3JSC22jsMakeNontrivialStringIPKcN3WTF6StringES2_S4_S2_S4_EENS_7JSValueEPNS_9ExecStateET_T0_T1_T2_T3_T4_
 __ZN3WTF13tryMakeStringIPKcNS_6StringES2_S3_S2_S3_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_T2_T3_T4_
 __ZN3JSC4Yarr12ByteCompiler26alternativeBodyDisjunctionEb
-__ZN3JSC9Arguments20didTearOffActivationEPNS_9ExecStateEPNS_12JSActivationE
 __ZN3JSC3JIT24emit_op_create_argumentsEPNS_11InstructionE
 __ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE
 _cti_op_create_arguments
@@ -3209,7 +3177,6 @@ __ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateE
 __ZN3JSCL19formateDateInstanceEPNS_9ExecStateENS_14DateTimeFormatEb
 __ZNK3JSC12DateInstance29calculateGregorianDateTimeUTCEPNS_9ExecStateE
 __ZN3JSC17DateInstanceCache3addEd
-__ZN3JSC21msToGregorianDateTimeEPNS_9ExecStateEdbRN3WTF17GregorianDateTimeE
 __ZN3WTF8msToYearEd
 __ZN3WTF11msToMinutesEd
 __ZN3WTF9msToHoursEd
@@ -3285,7 +3252,6 @@ __ZN3JSC3JIT21emitLoadInt32ToDoubleEiNS_12X86Registers13XMMRegisterIDE
 __ZN3JSC14MacroAssembler20convertInt32ToDoubleENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5Imm32ENS_12X86Registers13XMMRegisterIDE
 __ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateE
-__ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKN3WTF17GregorianDateTimeEdb
 __ZN3WTF18dateToDaysFrom1970Eiii
 __ZN3JSC10PrefixNode11emitBracketERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC16globalFuncEscapeEPNS_9ExecStateE
@@ -3406,7 +3372,6 @@ _operationEnsureContiguous
 __ZN3JSC8JSObject20ensureContiguousSlowERNS_2VME
 __ZN3JSC8JSObject20ensureContiguousSlowERNS_2VMENS0_22DoubleToContiguousModeE
 _operationMakeRope3
-_operationIsObject
 __ZN3JSC3DFG12slowPathCallINS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpEPFxPNS_9ExecStateExPNS_7JSArrayEENS0_11NoResultTagENS_12X86Registers10RegisterIDESE_SE_EEN3WTF10PassOwnPtrINS0_17SlowPathGeneratorEEET_PNS0_14SpeculativeJITET0_T1_T2_T3_T4_NS0_18SpillRegistersModeE
 __ZN3JSC3DFG14SpeculativeJIT13callOperationEPFxPNS_9ExecStateExPNS_7JSArrayEENS_12X86Registers10RegisterIDES9_S9_
 _operationArrayPush
@@ -3735,8 +3700,6 @@ __ZN3JSC3DFG15AssemblyHelpers9boxDoubleENS_12X86Registers13XMMRegisterIDENS2_10R
 __ZN3JSC3DFG12GPRTemporaryC1EPNS0_14SpeculativeJITERNS0_23SpeculateIntegerOperandE
 __ZN3JSC3DFG12GPRTemporaryC2EPNS0_14SpeculativeJITERNS0_23SpeculateIntegerOperandE
 __ZN3JSC23MacroAssemblerX86Common9compare32ENS0_19RelationalConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemblerINS_12X86AssemblerEE12TrustedImm32ES3_
-__ZN3JSC12JSActivation3putEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC12JSActivation14symbolTablePutEPNS_9ExecStateENS_12PropertyNameENS_7JSValueEb
 _cti_op_mod
 __ZN3JSC3DFG14SpeculativeJIT21compileObjectEqualityEPNS0_4NodeE
 __ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateE
@@ -4143,7 +4106,6 @@ __ZN3JSCL20callArrayConstructorEPNS_9ExecStateE
 __ZN3WTF5DequeINS_19FunctionWithContextELm0EE6removeEm
 __ZN3JSC17BytecodeGenerator20emitLoadGlobalObjectEPNS_10RegisterIDE
 __ZN3JSC4Yarr13YarrGeneratorILNS0_18YarrJITCompileModeE1EE29generatePatternCharacterFixedEm
-__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateENS_7JSValueENS_12PropertyNameE
 __ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateE
 _operationCompareLess
 __ZN3JSCL23dateProtoFuncSetUTCDateEPNS_9ExecStateE
@@ -4555,7 +4517,6 @@ __ZN3JSC17JITStubRoutineSetD2Ev
 __ZN3JSC13DFGCodeBlocksD1Ev
 __ZN3JSC13DFGCodeBlocksD2Ev
 __ZN3JSC9HandleSetD1Ev
-__ZN3JSC14BlockAllocator10deallocateINS_9HeapBlockINS_11HandleBlockEEEEEvPT_
 __ZN3JSC11SlotVisitorD1Ev
 __ZN3JSC14MarkStackArrayD1Ev
 __ZN3JSC18GCThreadSharedDataD1Ev
@@ -4567,8 +4528,6 @@ __ZN3JSC11CopiedSpaceD1Ev
 __ZN3JSC11CopiedSpaceD2Ev
 __ZN3JSC11MarkedSpaceD1Ev
 __ZN3JSC11MarkedSpace12forEachBlockINS_4FreeEEENT_10ReturnTypeERS3_
-__ZN3JSC14BlockAllocatorD1Ev
-__ZN3JSC14BlockAllocator18releaseFreeRegionsEv
 __ZN3JSC11SuperRegionD1Ev
 __ZN3WTF13MetaAllocatorD2Ev
 __ZN3JSC19ExecutableAllocatorD1Ev
@@ -4617,14 +4576,8 @@ __ZN3JSCL24regExpConstructorDollar6EPNS_9ExecStateENS_7JSValueENS_12PropertyName
 __ZN3JSC5LexerIhE23parseIdentifierSlowCaseILb1EEENS_11JSTokenTypeEPNS_11JSTokenDataEjb
 __ZN3JSC4Yarr13YarrGeneratorILNS0_18YarrJITCompileModeE1EE33generatePatternCharacterNonGreedyEm
 __ZN3JSC4Yarr13YarrGeneratorILNS0_18YarrJITCompileModeE1EE34backtrackPatternCharacterNonGreedyEm
-__ZN3JSC13NamePrototypeC1EPNS_9ExecStateEPNS_9StructureE
-__ZN3JSC12NameInstanceC2ERNS_2VMEPNS_9StructureEPNS_8JSStringE
-__ZN3JSC13NamePrototype14finishCreationEPNS_9ExecStateE
-__ZN3JSC15NameConstructorC1EPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC15NameConstructor14finishCreationEPNS_9ExecStateEPNS_13NamePrototypeE
 _JSStringIsEqualToUTF8CString
 _JSStringIsEqual
-__ZN3JSC12NameInstance7destroyEPNS_6JSCellE
 __ZN3WTF3MD5C1Ev
 __ZN3WTF3MD58addBytesEPKhm
 __ZN3WTFL12MD5TransformEPjPKj
@@ -4772,12 +4725,9 @@ __ZN3JSCL26callNativeErrorConstructorEPNS_9ExecStateE
 __ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
 __ZN3JSC22createOutOfMemoryErrorEPNS_14JSGlobalObjectE
 __ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateE
-__ZN3JSC12JSActivation14deletePropertyEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameE
 __ZN3JSC11JSNameScope3putEPNS_6JSCellEPNS_9ExecStateENS_12PropertyNameENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC14symbolTablePutINS_11JSNameScopeEEEbPT_PNS_9ExecStateENS_12PropertyNameENS_7JSValueEb
-__ZN3JSC15NameConstructor11getCallDataEPNS_6JSCellERNS_8CallDataE
 __ZN3JSCL20constructPrivateNameEPNS_9ExecStateE
-__ZN3JSC12NameInstanceC1ERNS_2VMEPNS_9StructureEPNS_8JSStringE
 __ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateE
 __ZN3JSC13JSNotAnObject24getOwnPropertyDescriptorEPNS_8JSObjectEPNS_9ExecStateENS_12PropertyNameERNS_18PropertyDescriptorE
 __ZN3JSCL20isNonLatin1IdentPartEi
@@ -4925,7 +4875,7 @@ _llint_slow_path_bitxor
 _llint_slow_path_check_has_instance
 _llint_slow_path_instanceof
 _llint_slow_path_typeof
-_llint_slow_path_is_object
+_llint_slow_path_is_object_or_null
 _llint_slow_path_is_function
 _llint_slow_path_in
 _llint_slow_path_resolve
@@ -4940,7 +4890,6 @@ _llint_slow_path_put_by_id
 _llint_slow_path_del_by_id
 _llint_slow_path_get_by_val
 _llint_slow_path_get_argument_by_val
-_llint_slow_path_get_by_pname
 _llint_slow_path_put_by_val
 _llint_slow_path_del_by_val
 _llint_slow_path_put_by_index
@@ -4968,8 +4917,6 @@ _llint_slow_path_tear_off_activation
 _llint_slow_path_tear_off_arguments
 _llint_slow_path_strcat
 _llint_slow_path_to_primitive
-_llint_slow_path_get_pnames
-_llint_slow_path_next_pname
 _llint_slow_path_push_with_scope
 _llint_slow_path_pop_scope
 _llint_slow_path_push_name_scope
@@ -5036,7 +4983,6 @@ _llint_op_put_by_id_transition_normal
 _llint_op_put_by_id_transition_normal_out_of_line
 _llint_op_get_by_val
 _llint_op_get_argument_by_val
-_llint_op_get_by_pname
 _llint_op_put_by_val
 _llint_op_jmp
 _llint_op_jeq_null
@@ -5051,7 +4997,6 @@ _llint_op_ret
 _llint_op_call_put_result
 _llint_op_ret_object_or_this
 _llint_op_to_primitive
-_llint_op_next_pname
 _llint_op_catch
 _llint_op_get_scoped_var
 _llint_op_put_scoped_var
@@ -5068,7 +5013,7 @@ _llint_op_greater
 _llint_op_greatereq
 _llint_op_mod
 _llint_op_typeof
-_llint_op_is_object
+_llint_op_is_object_or_null
 _llint_op_is_function
 _llint_op_in
 _llint_op_put_to_base_variable
@@ -5109,7 +5054,6 @@ _llint_op_call_varargs
 _llint_op_call_eval
 _llint_generic_return_point
 _llint_op_strcat
-_llint_op_get_pnames
 _llint_op_push_with_scope
 _llint_op_pop_scope
 _llint_op_push_name_scope
index 6b3f9718d43ffabd995b29cb1d29f6ee4b59bd3a..b89bac494b47f26d1556b8b26902a592773a96a4 100644 (file)
@@ -4,9 +4,11 @@
   <!-- normalize configuration case -->\r
   <PropertyGroup Condition="'$(CONFIGURATION)'=='Release'">\r
        <CONFIG>Production</CONFIG>\r
+    <DebugSuffix></DebugSuffix>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(CONFIGURATION)'=='Debug'">\r
        <CONFIG>DebugSuffix</CONFIG>\r
+    <DebugSuffix>_debug</DebugSuffix>\r
   </PropertyGroup>\r
 \r
   <!-- Wrapper to build JavaScriptCore for both win32 and x64. -->\r
@@ -60,7 +62,7 @@
     <Message Text="Building $(CONFIGURATION) Solution" />\r
     <Error Text="DSTROOT property or environment variable must be defined." Condition="'$(DSTROOT)' == ''" />\r
     <Message Text="Output=$(WebKit_OutputDir)" />\r
-    <MSBuild Projects="@(JavaScriptCore)" Properties="Configuration=$(CONFIG)" Targets="ReBuild" />\r
+    <MSBuild Projects="@(JavaScriptCore)" Properties="Configuration=$(CONFIG)" Targets="Build" />\r
   </Target>\r
 \r
   <Target Name="PostBuild" AfterTargets="Build">\r
     <CreateItem Include="$(ConfigurationBuildDir)\bin64\*.pdb">\r
       <Output TaskParameter="Include" ItemName="Bin64SymbolFiles" />\r
     </CreateItem>\r
+    <CreateItem Include="$(ConfigurationBuildDir)\bin32\JavaScriptCore$(DebugSuffix).dll">\r
+      <Output TaskParameter="Include" ItemName="Bin32DLLFiles" />\r
+    </CreateItem>\r
+    <CreateItem Include="$(ConfigurationBuildDir)\bin64\JavaScriptCore$(DebugSuffix).dll">\r
+      <Output TaskParameter="Include" ItemName="Bin64DLLFiles" />\r
+    </CreateItem>\r
+    <CreateItem Include="$(ConfigurationBuildDir)\bin32\*.resources">\r
+      <Output TaskParameter="Include" ItemName="Bin32ResourceFolders" />\r
+    </CreateItem>\r
+    <CreateItem Include="$(ConfigurationBuildDir)\bin64\*.resources">\r
+      <Output TaskParameter="Include" ItemName="Bin64ResourceFolders" />\r
+    </CreateItem>\r
     <CreateItem Include="$(ConfigurationBuildDir)\bin32\JavaScriptCore.resources\**\*.*">\r
       <Output TaskParameter="Include" ItemName="Bin32Resources" />\r
     </CreateItem>\r
     <Copy SourceFiles="@(Lib32Files)" DestinationFolder="$(AppleInternalLib32)" />\r
     <Copy SourceFiles="@(Lib64Files)" DestinationFolder="$(AppleInternalLib64)" />\r
     <Copy SourceFiles="@(Bin32Files)" DestinationFolder="$(AppleInternalBin32)" />\r
-    <Copy SourceFiles="@(Bin32Files)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS32)" />\r
+    <Copy SourceFiles="@(Bin32DLLFiles)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS32)" />\r
+    <Copy SourceFiles="@(Bin32ResourceFolders)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS32)" />\r
     <Copy SourceFiles="@(Bin32SymbolFiles)" DestinationFolder="$(AppleInternal32Symbols)" />\r
     <Copy SourceFiles="@(Bin32Resources)" DestinationFiles="@(Bin32Resources->'$(DSTROOT)\$(ProgramFilesAAS32)\JavaScriptCore.resources\%(RecursiveDir)%(Filename)%(Extension)')" />\r
     <Copy SourceFiles="@(Bin64Files)" DestinationFolder="$(AppleInternalBin64)" />\r
-    <Copy SourceFiles="@(Bin64Files)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS64)" />\r
+    <Copy SourceFiles="@(Bin64DLLFiles)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS64)" />\r
+    <Copy SourceFiles="@(Bin64ResourceFolders)" DestinationFolder="$(DSTROOT)\$(ProgramFilesAAS64)" />\r
     <Copy SourceFiles="@(Bin64SymbolFiles)" DestinationFolder="$(AppleInternal64Symbols)" />\r
     <Copy SourceFiles="@(Bin64Resources)" DestinationFiles="@(Bin64Resources->'$(DSTROOT)\$(ProgramFilesAAS64)\JavaScriptCore.resources\%(RecursiveDir)%(Filename)%(Extension)')" />\r
     <Copy SourceFiles="@(Derived32Sources)" DestinationFiles="@(Derived32Sources->'$(DSTROOT)\AppleInternal\Sources32\JavaScriptCore\%(RecursiveDir)%(Filename)%(Extension)')" />\r
index 6aa8521c80e94094343291eaea088546715d3e42..8fe5da46428a1d9d0d3f79ba245ba1ef3022a360 100644 (file)
@@ -1,6 +1,8 @@
 
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCore", "JavaScriptCore.vcxproj", "{22413D41-3A18-42B7-92A8-CEDC6CE86920}"
        ProjectSection(ProjectDependencies) = postProject
                {9221744B-5715-4F56-9590-42F7AB23DD8B} = {9221744B-5715-4F56-9590-42F7AB23DD8B}
@@ -33,12 +35,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LLIntOffsetsExtractor", "LL
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testapi", "testapi\testapi.vcxproj", "{5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}"
        ProjectSection(ProjectDependencies) = postProject
-               {BB16286B-AADC-46C1-BC0D-6C06F323E04B} = {BB16286B-AADC-46C1-BC0D-6C06F323E04B}
+               {FE09F693-9744-4D73-A17C-DE3209EB1905} = {FE09F693-9744-4D73-A17C-DE3209EB1905}
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F} = {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}
        EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExp", "testRegExp\testRegExp.vcxproj", "{BB16286B-AADC-46C1-BC0D-6C06F323E04B}"
        ProjectSection(ProjectDependencies) = postProject
-               {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3} = {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}
+               {FE09F693-9744-4D73-A17C-DE3209EB1905} = {FE09F693-9744-4D73-A17C-DE3209EB1905}
        EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "..\..\WTF\WTF.vcxproj\WTF.vcxproj", "{8EF73779-BED3-45BB-816D-9FF58399AFA5}"
@@ -48,6 +51,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "..\..\WTF\WTF.vcxpro
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTFGenerated", "..\..\WTF\WTF.vcxproj\WTFGenerated.vcxproj", "{F7366596-0520-4433-B8FF-D843E31E5199}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jscLauncher", "jsc\jsclauncher.vcxproj", "{FE09F693-9744-4D73-A17C-DE3209EB1905}"
+       ProjectSection(ProjectDependencies) = postProject
+               {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3} = {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testapiLauncher", "testapi\testapiLauncher.vcxproj", "{FE09F693-9744-4D73-A17C-FE3209EB1905}"
+       ProjectSection(ProjectDependencies) = postProject
+               {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843} = {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}
+               {FE09F693-9744-4D73-A17C-DE3209EB1905} = {FE09F693-9744-4D73-A17C-DE3209EB1905}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExpLauncher", "testRegExp\testRegExpLauncher.vcxproj", "{1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}"
+       ProjectSection(ProjectDependencies) = postProject
+               {BB16286B-AADC-46C1-BC0D-6C06F323E04B} = {BB16286B-AADC-46C1-BC0D-6C06F323E04B}
+               {FE09F693-9744-4D73-A17C-DE3209EB1905} = {FE09F693-9744-4D73-A17C-DE3209EB1905}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug_WinCairo|Win32 = Debug_WinCairo|Win32
@@ -304,6 +324,78 @@ Global
                {F7366596-0520-4433-B8FF-D843E31E5199}.Release|Win32.Build.0 = Release|Win32
                {F7366596-0520-4433-B8FF-D843E31E5199}.Release|x64.ActiveCfg = Release|x64
                {F7366596-0520-4433-B8FF-D843E31E5199}.Release|x64.Build.0 = Release|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|Win32.ActiveCfg = Debug|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|Win32.Build.0 = Debug|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|x64.ActiveCfg = Debug|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|x64.Build.0 = Debug|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|Win32.ActiveCfg = Production|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|Win32.Build.0 = Production|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|x64.ActiveCfg = Production|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|x64.Build.0 = Production|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|Win32.ActiveCfg = Release|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|Win32.Build.0 = Release|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|x64.ActiveCfg = Release|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|x64.Build.0 = Release|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|Win32.ActiveCfg = Debug|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|Win32.Build.0 = Debug|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|x64.ActiveCfg = Debug|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|x64.Build.0 = Debug|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|Win32.ActiveCfg = Production|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|Win32.Build.0 = Production|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|x64.ActiveCfg = Production|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|x64.Build.0 = Production|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|Win32.ActiveCfg = Release|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|Win32.Build.0 = Release|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|x64.ActiveCfg = Release|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|x64.Build.0 = Release|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|Win32.ActiveCfg = Debug|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|Win32.Build.0 = Debug|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|x64.ActiveCfg = Debug|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|x64.Build.0 = Debug|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|Win32.ActiveCfg = Production|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|Win32.Build.0 = Production|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|x64.ActiveCfg = Production|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|x64.Build.0 = Production|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|Win32.ActiveCfg = Release|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|Win32.Build.0 = Release|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|x64.ActiveCfg = Release|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
index bdfe54fee56d5c2e8a8202c098ca08495ce339b6..1a50adbdb448ebb9ef91f4360544ccaf027f3fee 100644 (file)
@@ -18,12 +18,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcxproj", "{
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExp", "testRegExp\testRegExp.vcxproj", "{BB16286B-AADC-46C1-BC0D-6C06F323E04B}"
        ProjectSection(ProjectDependencies) = postProject
-               {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3} = {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}
+               {FE09F693-9744-4D73-A17C-DE3209EB1905} = {FE09F693-9744-4D73-A17C-DE3209EB1905}
        EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testapi", "testapi\testapi.vcxproj", "{5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}"
        ProjectSection(ProjectDependencies) = postProject
-               {BB16286B-AADC-46C1-BC0D-6C06F323E04B} = {BB16286B-AADC-46C1-BC0D-6C06F323E04B}
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F} = {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}
        EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LLIntAssembly", "LLInt\LLIntAssembly\LLIntAssembly.vcxproj", "{9221744B-5715-4F56-9590-42F7AB23DD8B}"
@@ -41,6 +41,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LLIntOffsetsExtractor", "LL
                {877150A0-41B3-4730-9D98-1B8298098B14} = {877150A0-41B3-4730-9D98-1B8298098B14}
        EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jscLauncher", "jsc\jscLauncher.vcxproj", "{FE09F693-9744-4D73-A17C-DE3209EB1905}"
+       ProjectSection(ProjectDependencies) = postProject
+               {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3} = {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testapiLauncher", "testapi\testapiLauncher.vcxproj", "{FE09F693-9744-4D73-A17C-FE3209EB1905}"
+       ProjectSection(ProjectDependencies) = postProject
+               {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843} = {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExpLauncher", "testRegExp\testRegExpLauncher.vcxproj", "{1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}"
+       ProjectSection(ProjectDependencies) = postProject
+               {BB16286B-AADC-46C1-BC0D-6C06F323E04B} = {BB16286B-AADC-46C1-BC0D-6C06F323E04B}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug_WinCairo|Win32 = Debug_WinCairo|Win32
@@ -249,6 +264,78 @@ Global
                {D595E3F6-24F2-4C60-935C-95D50C6B3E96}.Release|Win32.Build.0 = Release|Win32
                {D595E3F6-24F2-4C60-935C-95D50C6B3E96}.Release|x64.ActiveCfg = Release|x64
                {D595E3F6-24F2-4C60-935C-95D50C6B3E96}.Release|x64.Build.0 = Release|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|Win32.ActiveCfg = Debug|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|Win32.Build.0 = Debug|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|x64.ActiveCfg = Debug|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Debug|x64.Build.0 = Debug|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|Win32.ActiveCfg = Production|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|Win32.Build.0 = Production|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|x64.ActiveCfg = Production|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Production|x64.Build.0 = Production|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|Win32.ActiveCfg = Release|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|Win32.Build.0 = Release|Win32
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|x64.ActiveCfg = Release|x64
+               {FE09F693-9744-4D73-A17C-DE3209EB1905}.Release|x64.Build.0 = Release|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|Win32.ActiveCfg = Debug|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|Win32.Build.0 = Debug|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|x64.ActiveCfg = Debug|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Debug|x64.Build.0 = Debug|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|Win32.ActiveCfg = Production|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|Win32.Build.0 = Production|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|x64.ActiveCfg = Production|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Production|x64.Build.0 = Production|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|Win32.ActiveCfg = Release|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|Win32.Build.0 = Release|Win32
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|x64.ActiveCfg = Release|x64
+               {FE09F693-9744-4D73-A17C-FE3209EB1905}.Release|x64.Build.0 = Release|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|Win32.ActiveCfg = Debug_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|Win32.Build.0 = Debug_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|x64.ActiveCfg = Debug_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug_WinCairo|x64.Build.0 = Debug_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|Win32.ActiveCfg = Debug|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|Win32.Build.0 = Debug|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|x64.ActiveCfg = Debug|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Debug|x64.Build.0 = Debug|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|x64.ActiveCfg = DebugSuffix|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.DebugSuffix|x64.Build.0 = DebugSuffix|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|Win32.ActiveCfg = Production|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|Win32.Build.0 = Production|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|x64.ActiveCfg = Production|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Production|x64.Build.0 = Production|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|Win32.ActiveCfg = Release_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|Win32.Build.0 = Release_WinCairo|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|x64.ActiveCfg = Release_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release_WinCairo|x64.Build.0 = Release_WinCairo|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|Win32.ActiveCfg = Release|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|Win32.Build.0 = Release|Win32
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|x64.ActiveCfg = Release|x64
+               {1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
index 14e46d336e14cf8cd37a99bf073d4383a55d1b2b..1c1e5f37ee13ca09c8a1dff6c5ebd414662500f8 100644 (file)
@@ -61,7 +61,7 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <UseDebugLibraries>true</UseDebugLibraries>
@@ -85,7 +85,7 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
     <UseDebugLibraries>true</UseDebugLibraries>
@@ -97,7 +97,7 @@
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <ClCompile Include="..\API\OpaqueJSString.cpp" />
     <ClCompile Include="..\assembler\LinkBuffer.cpp" />
     <ClCompile Include="..\assembler\MacroAssembler.cpp" />
-    <ClInclude Include="..\API\JSCTestRunnerUtils.h" />
-    <ClInclude Include="..\assembler\MacroAssemblerX86Common.cpp" />
+    <ClCompile Include="..\assembler\MacroAssemblerX86Common.cpp" />
     <ClCompile Include="..\bindings\ScriptFunctionCall.cpp" />
     <ClCompile Include="..\bindings\ScriptObject.cpp" />
     <ClCompile Include="..\bindings\ScriptValue.cpp" />
     <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp" />
     <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
     <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp" />
+    <ClCompile Include="..\bytecode\BytecodeIntrinsicRegistry.cpp" />
     <ClCompile Include="..\bytecode\BytecodeLivenessAnalysis.cpp" />
+    <ClCompile Include="..\bytecode\CallEdge.cpp" />
     <ClCompile Include="..\bytecode\CallLinkInfo.cpp" />
     <ClCompile Include="..\bytecode\CallLinkStatus.cpp" />
+    <ClCompile Include="..\bytecode\CallVariant.cpp" />
     <ClCompile Include="..\bytecode\CodeBlock.cpp" />
     <ClCompile Include="..\bytecode\CodeBlockHash.cpp" />
     <ClCompile Include="..\bytecode\CodeBlockJettisoningWatchpoint.cpp" />
     <ClCompile Include="..\bytecode\CodeOrigin.cpp" />
     <ClCompile Include="..\bytecode\CodeType.cpp" />
+    <ClCompile Include="..\bytecode\ComplexGetStatus.cpp" />
+    <ClCompile Include="..\bytecode\ConstantStructureCheck.cpp" />
     <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp" />
+    <ClCompile Include="..\bytecode\DeferredSourceDump.cpp" />
     <ClCompile Include="..\bytecode\DFGExitProfile.cpp" />
     <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />
     <ClCompile Include="..\bytecode\ExitKind.cpp" />
     <ClCompile Include="..\bytecode\Opcode.cpp" />
     <ClCompile Include="..\bytecode\PolymorphicGetByIdList.cpp" />
     <ClCompile Include="..\bytecode\PolymorphicPutByIdList.cpp" />
-    <ClCompile Include="..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.cpp" />
     <ClCompile Include="..\bytecode\PreciseJumpTargets.cpp" />
     <ClCompile Include="..\bytecode\PutByIdStatus.cpp" />
     <ClCompile Include="..\bytecode\PutByIdVariant.cpp" />
     <ClCompile Include="..\bytecode\SamplingTool.cpp" />
     <ClCompile Include="..\bytecode\SpecialPointer.cpp" />
     <ClCompile Include="..\bytecode\SpeculatedType.cpp" />
+    <ClCompile Include="..\bytecode\StructureSet.cpp" />
     <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" />
     <ClCompile Include="..\bytecode\StructureStubInfo.cpp" />
+    <ClCompile Include="..\bytecode\ToThisStatus.cpp" />
+    <ClCompile Include="..\bytecode\TrackedReferences.cpp" />
     <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
     <ClCompile Include="..\bytecode\UnlinkedInstructionStream.cpp" />
     <ClCompile Include="..\bytecode\ValueRecovery.cpp" />
+    <ClCompile Include="..\bytecode\VariableWriteFireDetail.cpp" />
+    <ClCompile Include="..\bytecode\VirtualRegister.cpp" />
     <ClCompile Include="..\bytecode\Watchpoint.cpp" />
     <ClCompile Include="..\bytecompiler\BytecodeGenerator.cpp" />
     <ClCompile Include="..\bytecompiler\NodesCodegen.cpp" />
     <ClCompile Include="..\debugger\Debugger.cpp" />
-    <ClCompile Include="..\debugger\DebuggerActivation.cpp" />
     <ClCompile Include="..\debugger\DebuggerCallFrame.cpp" />
+    <ClCompile Include="..\debugger\DebuggerScope.cpp" />
     <ClCompile Include="..\dfg\DFGAbstractHeap.cpp" />
     <ClCompile Include="..\dfg\DFGAbstractValue.cpp" />
-    <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsEliminationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsUtilities.cpp" />
     <ClCompile Include="..\dfg\DFGArithMode.cpp" />
     <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
     <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
     <ClCompile Include="..\dfg\DFGAvailability.cpp" />
+    <ClCompile Include="..\dfg\DFGAvailabilityMap.cpp" />
     <ClCompile Include="..\dfg\DFGBackwardsPropagationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
-    <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
     <ClCompile Include="..\dfg\DFGBlockInsertionSet.cpp" />
+    <ClCompile Include="..\dfg\DFGBlockSet.cpp" />
+    <ClCompile Include="..\dfg\DFGBlockWorklist.cpp" />
     <ClCompile Include="..\dfg\DFGByteCodeParser.cpp" />
     <ClCompile Include="..\dfg\DFGCapabilities.cpp" />
     <ClCompile Include="..\dfg\DFGCFAPhase.cpp" />
     <ClCompile Include="..\dfg\DFGCFGSimplificationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGCleanUpPhase.cpp" />
     <ClCompile Include="..\dfg\DFGClobberize.cpp" />
     <ClCompile Include="..\dfg\DFGClobberSet.cpp" />
+    <ClCompile Include="..\dfg\DFGCombinedLiveness.cpp" />
     <ClCompile Include="..\dfg\DFGCommon.cpp" />
     <ClCompile Include="..\dfg\DFGCommonData.cpp" />
     <ClCompile Include="..\dfg\DFGCompilationKey.cpp" />
     <ClCompile Include="..\dfg\DFGCompilationMode.cpp" />
     <ClCompile Include="..\dfg\DFGConstantFoldingPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGConstantHoistingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGCPSRethreadingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGCriticalEdgeBreakingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGCSEPhase.cpp" />
     <ClCompile Include="..\dfg\DFGDCEPhase.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredIdentifiers.cpp" />
-    <ClCompile Include="..\dfg\DFGDesiredStructureChains.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredTransitions.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredWatchpoints.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredWeakReferences.cpp" />
     <ClCompile Include="..\dfg\DFGDesiredWriteBarriers.cpp" />
     <ClCompile Include="..\dfg\DFGDisassembler.cpp" />
+    <ClCompile Include="..\dfg\DFGDoesGC.cpp" />
     <ClCompile Include="..\dfg\DFGDominators.cpp" />
     <ClCompile Include="..\dfg\DFGDriver.cpp" />
     <ClCompile Include="..\dfg\DFGEdge.cpp" />
+    <ClCompile Include="..\dfg\DFGEpoch.cpp" />
     <ClCompile Include="..\dfg\DFGFailedFinalizer.cpp" />
     <ClCompile Include="..\dfg\DFGFinalizer.cpp" />
     <ClCompile Include="..\dfg\DFGFixupPhase.cpp" />
     <ClCompile Include="..\dfg\DFGFlushedAt.cpp" />
     <ClCompile Include="..\dfg\DFGFlushFormat.cpp" />
+    <ClCompile Include="..\dfg\DFGFrozenValue.cpp" />
     <ClCompile Include="..\dfg\DFGFunctionWhitelist.cpp" />
     <ClCompile Include="..\dfg\DFGGraph.cpp" />
     <ClCompile Include="..\dfg\DFGGraphSafepoint.cpp" />
+    <ClCompile Include="..\dfg\DFGHeapLocation.cpp" />
     <ClCompile Include="..\dfg\DFGInPlaceAbstractState.cpp" />
+    <ClCompile Include="..\dfg\DFGInsertOSRHintsForUpdate.cpp" />
     <ClCompile Include="..\dfg\DFGIntegerCheckCombiningPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGIntegerRangeOptimizationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGInvalidationPointInjectionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGJITCode.cpp" />
     <ClCompile Include="..\dfg\DFGJITCompiler.cpp" />
     <ClCompile Include="..\dfg\DFGJITFinalizer.cpp" />
     <ClCompile Include="..\dfg\DFGJumpReplacement.cpp" />
     <ClCompile Include="..\dfg\DFGLazyJSValue.cpp" />
+    <ClCompile Include="..\dfg\DFGLazyNode.cpp" />
     <ClCompile Include="..\dfg\DFGLICMPhase.cpp" />
     <ClCompile Include="..\dfg\DFGLivenessAnalysisPhase.cpp" />
     <ClCompile Include="..\dfg\DFGLongLivedState.cpp" />
     <ClCompile Include="..\dfg\DFGLoopPreHeaderCreationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGMayExit.cpp" />
+    <ClCompile Include="..\dfg\DFGMinifiedGraph.cpp" />
     <ClCompile Include="..\dfg\DFGMinifiedNode.cpp" />
+    <ClCompile Include="..\dfg\DFGMovHintRemovalPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGNaiveDominators.cpp" />
     <ClCompile Include="..\dfg\DFGNaturalLoops.cpp" />
     <ClCompile Include="..\dfg\DFGNode.cpp" />
     <ClCompile Include="..\dfg\DFGNodeFlags.cpp" />
     <ClCompile Include="..\dfg\DFGOSRExitCompiler32_64.cpp" />
     <ClCompile Include="..\dfg\DFGOSRExitCompiler64.cpp" />
     <ClCompile Include="..\dfg\DFGOSRExitCompilerCommon.cpp" />
+    <ClCompile Include="..\dfg\DFGOSRExitFuzz.cpp" />
     <ClCompile Include="..\dfg\DFGOSRExitJumpPlaceholder.cpp" />
     <ClCompile Include="..\dfg\DFGOSRExitPreparation.cpp" />
+    <ClCompile Include="..\dfg\DFGObjectAllocationSinkingPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGObjectMaterializationData.cpp" />
+    <ClCompile Include="..\dfg\DFGPhantomInsertionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGPhiChildren.cpp" />
     <ClCompile Include="..\dfg\DFGPlan.cpp" />
+    <ClCompile Include="..\dfg\DFGPrePostNumbering.cpp" />
     <ClCompile Include="..\dfg\DFGPredictionInjectionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGPredictionPropagationPhase.cpp" />
-    <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGPromotedHeapLocation.cpp" />
+    <ClCompile Include="..\dfg\DFGPureValue.cpp" />
+    <ClCompile Include="..\dfg\DFGPutStackSinkingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGSafepoint.cpp" />
     <ClCompile Include="..\dfg\DFGSpeculativeJIT.cpp" />
     <ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" />
     <ClCompile Include="..\dfg\DFGSpeculativeJIT64.cpp" />
+    <ClCompile Include="..\dfg\DFGSSACalculator.cpp" />
     <ClCompile Include="..\dfg\DFGSSAConversionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGSSALoweringPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStackLayoutPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStaticExecutionCountEstimationPhase.cpp" />
-    <ClCompile Include="..\dfg\DFGStoreBarrierElisionPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGStoreBarrierInsertionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStrengthReductionPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGStructureAbstractValue.cpp" />
+    <ClCompile Include="..\dfg\DFGStructureRegistrationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGThreadData.cpp" />
     <ClCompile Include="..\dfg\DFGThunks.cpp" />
     <ClCompile Include="..\dfg\DFGTierUpCheckInjectionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGToFTLDeferredCompilationCallback.cpp" />
     <ClCompile Include="..\dfg\DFGToFTLForOSREntryDeferredCompilationCallback.cpp" />
+    <ClCompile Include="..\dfg\DFGTransition.cpp" />
     <ClCompile Include="..\dfg\DFGTypeCheckHoistingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGUnificationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGUseKind.cpp" />
     <ClCompile Include="..\dfg\DFGValidate.cpp" />
     <ClCompile Include="..\dfg\DFGValueSource.cpp" />
+    <ClCompile Include="..\dfg\DFGValueStrength.cpp" />
+    <ClCompile Include="..\dfg\DFGVarargsForwardingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessData.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessDataDump.cpp" />
     <ClCompile Include="..\dfg\DFGVariableEvent.cpp" />
     <ClCompile Include="..\ftl\FTLDWARFRegister.cpp" />
     <ClCompile Include="..\ftl\FTLExitArgument.cpp" />
     <ClCompile Include="..\ftl\FTLExitArgumentForOperand.cpp" />
+    <ClCompile Include="..\ftl\FTLExitPropertyValue.cpp" />
     <ClCompile Include="..\ftl\FTLExitThunkGenerator.cpp" />
+    <ClCompile Include="..\ftl\FTLExitTimeObjectMaterialization.cpp" />
     <ClCompile Include="..\ftl\FTLExitValue.cpp" />
     <ClCompile Include="..\ftl\FTLFail.cpp" />
     <ClCompile Include="..\ftl\FTLForOSREntryJITCode.cpp" />
     <ClCompile Include="..\ftl\FTLJITCode.cpp" />
     <ClCompile Include="..\ftl\FTLJITFinalizer.cpp" />
     <ClCompile Include="..\ftl\FTLJSCall.cpp" />
+    <ClCompile Include="..\ftl\FTLJSCallBase.cpp" />
+    <ClCompile Include="..\ftl\FTLJSCallVarargs.cpp" />
     <ClCompile Include="..\ftl\FTLLink.cpp" />
     <ClCompile Include="..\ftl\FTLLocation.cpp" />
     <ClCompile Include="..\ftl\FTLLowerDFGToLLVM.cpp" />
     <ClCompile Include="..\ftl\FTLOSREntry.cpp" />
     <ClCompile Include="..\ftl\FTLOSRExit.cpp" />
     <ClCompile Include="..\ftl\FTLOSRExitCompiler.cpp" />
+    <ClCompile Include="..\ftl\FTLOperations.cpp" />
     <ClCompile Include="..\ftl\FTLOutput.cpp" />
     <ClCompile Include="..\ftl\FTLRecoveryOpcode.cpp" />
     <ClCompile Include="..\ftl\FTLRegisterAtOffset.cpp" />
     <ClCompile Include="..\ftl\FTLUnwindInfo.cpp" />
     <ClCompile Include="..\ftl\FTLValueFormat.cpp" />
     <ClCompile Include="..\ftl\FTLValueRange.cpp" />
-    <ClCompile Include="..\heap\BlockAllocator.cpp" />
     <ClCompile Include="..\heap\CodeBlockSet.cpp" />
     <ClCompile Include="..\heap\ConservativeRoots.cpp" />
     <ClCompile Include="..\heap\CopiedSpace.cpp" />
     <ClCompile Include="..\heap\Heap.cpp" />
     <ClCompile Include="..\heap\HeapStatistics.cpp" />
     <ClCompile Include="..\heap\HeapTimer.cpp" />
+    <ClCompile Include="..\heap\HeapVerifier.cpp" />
     <ClCompile Include="..\heap\IncrementalSweeper.cpp" />
     <ClCompile Include="..\heap\JITStubRoutineSet.cpp" />
     <ClCompile Include="..\heap\MachineStackMarker.cpp" />
     <ClCompile Include="..\heap\MarkedSpace.cpp" />
     <ClCompile Include="..\heap\MarkStack.cpp" />
     <ClCompile Include="..\heap\SlotVisitor.cpp" />
-    <ClCompile Include="..\heap\SuperRegion.cpp" />
     <ClCompile Include="..\heap\Weak.cpp" />
     <ClCompile Include="..\heap\WeakBlock.cpp" />
     <ClCompile Include="..\heap\WeakHandleOwner.cpp" />
     <ClCompile Include="..\inspector\agents\InspectorAgent.cpp" />
     <ClCompile Include="..\inspector\agents\InspectorConsoleAgent.cpp" />
     <ClCompile Include="..\inspector\agents\InspectorDebuggerAgent.cpp" />
-    <ClCompile Include="..\inspector\agents\InspectorProfilerAgent.cpp" />
     <ClCompile Include="..\inspector\agents\InspectorRuntimeAgent.cpp" />
     <ClCompile Include="..\interpreter\AbstractPC.cpp" />
     <ClCompile Include="..\interpreter\CallFrame.cpp" />
     <ClCompile Include="..\interpreter\JSStack.cpp" />
     <ClCompile Include="..\interpreter\ProtoCallFrame.cpp" />
     <ClCompile Include="..\interpreter\StackVisitor.cpp" />
-    <ClCompile Include="..\interpreter\VMInspector.cpp" />
     <ClCompile Include="..\jit\AccessorCallJITStubRoutine.cpp" />
     <ClCompile Include="..\jit\ArityCheckFailReturnThunks.cpp" />
     <ClCompile Include="..\jit\AssemblyHelpers.cpp" />
-    <ClCompile Include="..\jit\ClosureCallStubRoutine.cpp" />
+    <ClCompile Include="..\jit\BinarySwitch.cpp" />
+    <ClCompile Include="..\jit\ExecutableAllocationFuzz.cpp" />
     <ClCompile Include="..\jit\ExecutableAllocator.cpp" />
+    <ClCompile Include="..\jit\ExecutableAllocatorFixedVMPool.cpp" />
     <ClCompile Include="..\jit\GCAwareJITStubRoutine.cpp" />
     <ClCompile Include="..\jit\HostCallReturnValue.cpp" />
     <ClCompile Include="..\jit\JIT.cpp" />
     <ClCompile Include="..\jit\JITStubs.cpp" />
     <ClCompile Include="..\jit\JITThunks.cpp" />
     <ClCompile Include="..\jit\JITToDFGDeferredCompilationCallback.cpp" />
+    <ClCompile Include="..\jit\SetupVarargsFrame.cpp" />
+    <ClCompile Include="..\jit\PolymorphicCallStubRoutine.cpp" />
     <ClCompile Include="..\jit\Reg.cpp" />
     <ClCompile Include="..\jit\RegisterPreservationWrapperGenerator.cpp" />
+    <ClCompile Include="..\jit\RegisterSet.cpp" />
     <ClCompile Include="..\jit\Repatch.cpp" />
     <ClCompile Include="..\jit\ScratchRegisterAllocator.cpp" />
+    <ClCompile Include="..\jit\TempRegisterSet.cpp" />
     <ClCompile Include="..\jit\ThunkGenerators.cpp" />
     <ClCompile Include="..\llint\LLIntCLoop.cpp" />
     <ClCompile Include="..\llint\LLIntData.cpp" />
     <ClCompile Include="..\profiler\ProfilerOSRExitSite.cpp" />
     <ClCompile Include="..\profiler\ProfilerProfiledBytecodes.cpp" />
     <ClCompile Include="..\runtime\ArgList.cpp" />
-    <ClCompile Include="..\runtime\Arguments.cpp" />
-    <ClCompile Include="..\runtime\ArgumentsIteratorConstructor.cpp" />
-    <ClCompile Include="..\runtime\ArgumentsIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\ArrayBuffer.cpp" />
     <ClCompile Include="..\runtime\ArrayBufferNeuteringWatchpoint.cpp" />
     <ClCompile Include="..\runtime\ArrayBufferView.cpp" />
     <ClCompile Include="..\runtime\ArrayConstructor.cpp" />
-    <ClCompile Include="..\runtime\ArrayIteratorConstructor.cpp" />
     <ClCompile Include="..\runtime\ArrayIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\ArrayPrototype.cpp" />
+    <ClCompile Include="..\runtime\BasicBlockLocation.cpp" />
     <ClCompile Include="..\runtime\BooleanConstructor.cpp" />
     <ClCompile Include="..\runtime\BooleanObject.cpp" />
     <ClCompile Include="..\runtime\BooleanPrototype.cpp" />
     <ClCompile Include="..\runtime\CallData.cpp" />
+    <ClCompile Include="..\runtime\ClonedArguments.cpp" />
     <ClCompile Include="..\runtime\CodeCache.cpp" />
     <ClCompile Include="..\runtime\CodeSpecializationKind.cpp" />
     <ClCompile Include="..\runtime\CommonIdentifiers.cpp" />
     <ClCompile Include="..\runtime\Completion.cpp" />
     <ClCompile Include="..\runtime\ConsoleClient.cpp" />
     <ClCompile Include="..\runtime\ConsolePrototype.cpp" />
+    <ClCompile Include="..\runtime\ConstantMode.cpp" />
     <ClCompile Include="..\runtime\ConstructData.cpp" />
+    <ClCompile Include="..\runtime\ControlFlowProfiler.cpp" />
     <ClCompile Include="..\runtime\CustomGetterSetter.cpp" />
     <ClCompile Include="..\runtime\DataView.cpp" />
     <ClCompile Include="..\runtime\DateConstructor.cpp" />
     <ClCompile Include="..\runtime\DateConversion.cpp" />
     <ClCompile Include="..\runtime\DateInstance.cpp" />
     <ClCompile Include="..\runtime\DatePrototype.cpp" />
+    <ClCompile Include="..\runtime\DirectArguments.cpp" />
+    <ClCompile Include="..\runtime\DirectArgumentsOffset.cpp" />
     <ClCompile Include="..\runtime\DumpContext.cpp" />
     <ClCompile Include="..\runtime\Error.cpp" />
     <ClCompile Include="..\runtime\ErrorConstructor.cpp" />
     <ClCompile Include="..\runtime\ErrorHandlingScope.cpp" />
     <ClCompile Include="..\runtime\ErrorInstance.cpp" />
     <ClCompile Include="..\runtime\ErrorPrototype.cpp" />
+    <ClCompile Include="..\runtime\Exception.cpp" />
+    <ClCompile Include="..\runtime\ExceptionFuzz.cpp" />
     <ClCompile Include="..\runtime\ExceptionHelpers.cpp" />
     <ClCompile Include="..\runtime\Executable.cpp" />
     <ClCompile Include="..\runtime\FunctionConstructor.cpp" />
     <ClCompile Include="..\runtime\FunctionExecutableDump.cpp" />
+    <ClCompile Include="..\runtime\FunctionHasExecutedCache.cpp" />
     <ClCompile Include="..\runtime\FunctionPrototype.cpp" />
+    <ClCompile Include="..\runtime\FunctionRareData.cpp" />
     <ClCompile Include="..\runtime\GetterSetter.cpp" />
     <ClCompile Include="..\runtime\Identifier.cpp" />
     <ClCompile Include="..\runtime\IndexingType.cpp" />
+    <ClCompile Include="..\runtime\InferredValue.cpp" />
     <ClCompile Include="..\runtime\InitializeThreading.cpp" />
     <ClCompile Include="..\runtime\IntendedStructureChain.cpp" />
     <ClCompile Include="..\runtime\InternalFunction.cpp" />
+    <ClCompile Include="..\runtime\IntlObject.cpp" />
+    <ClCompile Include="..\runtime\IteratorOperations.cpp" />
+    <ClCompile Include="..\runtime\IteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\JSAPIValueWrapper.cpp" />
-    <ClCompile Include="..\runtime\JSActivation.cpp" />
-    <ClCompile Include="..\runtime\JSArgumentsIterator.cpp" />
+    <ClCompile Include="..\runtime\JSLexicalEnvironment.cpp" />
     <ClCompile Include="..\runtime\JSArray.cpp" />
     <ClCompile Include="..\runtime\JSArrayIterator.cpp" />
     <ClCompile Include="..\runtime\JSArrayBuffer.cpp" />
     <ClCompile Include="..\runtime\JSArrayBufferView.cpp" />
     <ClCompile Include="..\runtime\JSBoundFunction.cpp" />
     <ClCompile Include="..\runtime\JSCJSValue.cpp" />
+    <ClCompile Include="..\runtime\JSCallee.cpp" />
+    <ClCompile Include="..\runtime\JSCatchScope.cpp" />
     <ClCompile Include="..\runtime\JSCell.cpp" />
     <ClCompile Include="..\runtime\JSConsole.cpp" />
     <ClCompile Include="..\runtime\JSDataView.cpp" />
     <ClCompile Include="..\runtime\JSDataViewPrototype.cpp" />
     <ClCompile Include="..\runtime\JSDateMath.cpp" />
     <ClCompile Include="..\runtime\JSFunction.cpp" />
+    <ClCompile Include="..\runtime\JSFunctionNameScope.cpp" />
     <ClCompile Include="..\runtime\JSGlobalObject.cpp" />
     <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp" />
+    <ClCompile Include="..\runtime\JSJob.cpp" />
     <ClCompile Include="..\runtime\JSLock.cpp" />
     <ClCompile Include="..\runtime\JSMap.cpp" />
     <ClCompile Include="..\runtime\JSMapIterator.cpp" />
     <ClCompile Include="..\runtime\JSPromise.cpp" />
     <ClCompile Include="..\runtime\JSPromiseConstructor.cpp" />
     <ClCompile Include="..\runtime\JSPromiseDeferred.cpp" />
-    <ClCompile Include="..\runtime\JSPromiseFunctions.cpp" />
-    <ClCompile Include="..\runtime\JSPromiseReaction.cpp" />
     <ClCompile Include="..\runtime\JSPromisePrototype.cpp" />
-    <ClCompile Include="..\runtime\JSPropertyNameIterator.cpp" />
+    <ClCompile Include="..\runtime\JSPropertyNameEnumerator.cpp" />
     <ClCompile Include="..\runtime\JSProxy.cpp" />
     <ClCompile Include="..\runtime\JSScope.cpp" />
     <ClCompile Include="..\runtime\JSSegmentedVariableObject.cpp" />
     <ClCompile Include="..\runtime\JSSet.cpp" />
     <ClCompile Include="..\runtime\JSSetIterator.cpp" />
     <ClCompile Include="..\runtime\JSString.cpp" />
+    <ClCompile Include="..\runtime\JSStringIterator.cpp" />
     <ClCompile Include="..\runtime\JSStringJoiner.cpp" />
     <ClCompile Include="..\runtime\JSSymbolTableObject.cpp" />
+    <ClCompile Include="..\runtime\JSTemplateRegistryKey.cpp" />
     <ClCompile Include="..\runtime\JSTypedArrayConstructors.cpp" />
     <ClCompile Include="..\runtime\JSTypedArrayPrototypes.cpp" />
     <ClCompile Include="..\runtime\JSTypedArrays.cpp" />
-    <ClCompile Include="..\runtime\JSVariableObject.cpp" />
+    <ClCompile Include="..\runtime\JSEnvironmentRecord.cpp" />
     <ClCompile Include="..\runtime\JSWeakMap.cpp" />
+    <ClCompile Include="..\runtime\JSWeakSet.cpp" />
     <ClCompile Include="..\runtime\JSWithScope.cpp" />
     <ClCompile Include="..\runtime\JSWrapperObject.cpp" />
     <ClCompile Include="..\runtime\LiteralParser.cpp" />
     <ClCompile Include="..\runtime\Lookup.cpp" />
     <ClCompile Include="..\runtime\MapConstructor.cpp" />
-    <ClCompile Include="..\runtime\MapData.cpp" />
-    <ClCompile Include="..\runtime\MapIteratorConstructor.cpp" />
     <ClCompile Include="..\runtime\MapIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\MapPrototype.cpp" />
+    <ClCompile Include="..\runtime\MathCommon.cpp" />
     <ClCompile Include="..\runtime\MathObject.cpp" />
     <ClCompile Include="..\runtime\MemoryStatistics.cpp" />
-    <ClCompile Include="..\runtime\NameConstructor.cpp" />
-    <ClCompile Include="..\runtime\NameInstance.cpp" />
-    <ClCompile Include="..\runtime\NamePrototype.cpp" />
     <ClCompile Include="..\runtime\NativeErrorConstructor.cpp" />
     <ClCompile Include="..\runtime\NativeErrorPrototype.cpp" />
+    <ClCompile Include="..\runtime\NullGetterFunction.cpp" />
+    <ClCompile Include="..\runtime\NullSetterFunction.cpp" />
     <ClCompile Include="..\runtime\NumberConstructor.cpp" />
     <ClCompile Include="..\runtime\NumberObject.cpp" />
     <ClCompile Include="..\runtime\NumberPrototype.cpp" />
     <ClCompile Include="..\runtime\Operations.cpp" />
     <ClCompile Include="..\runtime\Options.cpp" />
     <ClCompile Include="..\runtime\PropertyDescriptor.cpp" />
-    <ClCompile Include="..\runtime\PropertyNameArray.cpp" />
     <ClCompile Include="..\runtime\PropertySlot.cpp" />
     <ClCompile Include="..\runtime\PropertyTable.cpp" />
     <ClCompile Include="..\runtime\PrototypeMap.cpp" />
     <ClCompile Include="..\runtime\RegExpMatchesArray.cpp" />
     <ClCompile Include="..\runtime\RegExpObject.cpp" />
     <ClCompile Include="..\runtime\RegExpPrototype.cpp" />
+    <ClCompile Include="..\runtime\RuntimeType.cpp" />
     <ClCompile Include="..\runtime\SamplingCounter.cpp" />
     <ClCompile Include="..\runtime\SetConstructor.cpp" />
-    <ClCompile Include="..\runtime\SetIteratorConstructor.cpp" />
     <ClCompile Include="..\runtime\SetIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\SetPrototype.cpp" />
+    <ClCompile Include="..\runtime\ScopeOffset.cpp" />
+    <ClCompile Include="..\runtime\ScopedArguments.cpp" />
+    <ClCompile Include="..\runtime\ScopedArgumentsTable.cpp" />
     <ClCompile Include="..\runtime\SimpleTypedArrayController.cpp" />
     <ClCompile Include="..\runtime\SmallStrings.cpp" />
     <ClCompile Include="..\runtime\SparseArrayValueMap.cpp" />
     <ClCompile Include="..\runtime\StrictEvalActivation.cpp" />
     <ClCompile Include="..\runtime\StringConstructor.cpp" />
     <ClCompile Include="..\runtime\StringObject.cpp" />
+    <ClCompile Include="..\runtime\StringIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\StringPrototype.cpp" />
     <ClCompile Include="..\runtime\StringRecursionChecker.cpp" />
     <ClCompile Include="..\runtime\Structure.cpp" />
     <ClCompile Include="..\runtime\StructureChain.cpp" />
     <ClCompile Include="..\runtime\StructureIDTable.cpp" />
     <ClCompile Include="..\runtime\StructureRareData.cpp" />
+    <ClCompile Include="..\runtime\Symbol.cpp" />
+    <ClCompile Include="..\runtime\SymbolConstructor.cpp" />
+    <ClCompile Include="..\runtime\SymbolObject.cpp" />
+    <ClCompile Include="..\runtime\SymbolPrototype.cpp" />
     <ClCompile Include="..\runtime\SymbolTable.cpp" />
+    <ClCompile Include="..\runtime\TemplateRegistry.cpp" />
     <ClCompile Include="..\runtime\TestRunnerUtils.cpp" />
     <ClCompile Include="..\runtime\TypedArrayController.cpp" />
     <ClCompile Include="..\runtime\TypedArrayType.cpp" />
+    <ClCompile Include="..\runtime\TypeofType.cpp" />
+    <ClCompile Include="..\runtime\TypeLocationCache.cpp" />
+    <ClCompile Include="..\runtime\TypeProfiler.cpp" />
+    <ClCompile Include="..\runtime\TypeProfilerLog.cpp" />
+    <ClCompile Include="..\runtime\TypeSet.cpp" />
     <ClCompile Include="..\runtime\VM.cpp" />
     <ClCompile Include="..\runtime\VMEntryScope.cpp" />
+    <ClCompile Include="..\runtime\VarOffset.cpp" />
     <ClCompile Include="..\runtime\Watchdog.cpp" />
     <ClCompile Include="..\runtime\WatchdogNone.cpp" />
     <ClCompile Include="..\runtime\WeakMapConstructor.cpp" />
     <ClCompile Include="..\runtime\WeakMapData.cpp" />
     <ClCompile Include="..\runtime\WeakMapPrototype.cpp" />
+    <ClCompile Include="..\runtime\WeakSetConstructor.cpp" />
+    <ClCompile Include="..\runtime\WeakSetPrototype.cpp" />
     <ClCompile Include="..\tools\CodeProfile.cpp" />
     <ClCompile Include="..\tools\CodeProfiling.cpp" />
+    <ClCompile Include="..\tools\FunctionOverrides.cpp" />
+    <ClCompile Include="..\tools\JSDollarVM.cpp" />
+    <ClCompile Include="..\tools\JSDollarVMPrototype.cpp" />
     <ClCompile Include="..\yarr\RegularExpression.cpp" />
     <ClCompile Include="..\yarr\YarrCanonicalizeUCS2.cpp" />
     <ClCompile Include="..\yarr\YarrInterpreter.cpp" />
     <ClCompile Include="..\yarr\YarrJIT.cpp" />
     <ClCompile Include="..\yarr\YarrPattern.cpp" />
     <ClCompile Include="..\yarr\YarrSyntaxChecker.cpp" />
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSBackendDispatchers.cpp" />
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSFrontendDispatchers.cpp" />
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.cpp" />
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorBackendDispatchers.cpp" />
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorFrontendDispatchers.cpp" />
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorProtocolObjects.cpp" />
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.cpp" />
+    <ClCompile Include="JavaScriptCoreDLL.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayConstructor.lut.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayIteratorPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\BooleanPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\DateConstructor.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ErrorPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\HeaderDetection.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InjectedScriptSource.h" />
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSBackendDispatchers.h" />
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSFrontendDispatchers.h" />
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorBackendDispatchers.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorFrontendDispatchers.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorProtocolObjects.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSDataViewPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSGlobalObject.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSONObject.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSPromisePrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\KeywordLookup.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\Lexer.lut.h" />
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\NamePrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\NumberConstructor.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\NumberPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ObjectConstructor.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpJitTables.h" />
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpObject.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\StringConstructor.lut.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\SymbolPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\API\JSAPIWrapperObject.h" />
     <ClInclude Include="..\API\JSBase.h" />
     <ClInclude Include="..\API\JSBasePrivate.h" />
+    <ClInclude Include="..\API\JSCTestRunnerUtils.h" />
     <ClInclude Include="..\API\JSCallbackConstructor.h" />
     <ClInclude Include="..\API\JSCallbackFunction.h" />
     <ClInclude Include="..\API\JSCallbackObject.h" />
     <ClInclude Include="..\bytecode\ArrayProfile.h" />
     <ClInclude Include="..\bytecode\ByValInfo.h" />
     <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
+    <ClInclude Include="..\bytecode\BytecodeKills.h" />
+    <ClInclude Include="..\bytecode\BytecodeIntrinsicRegistry.h" />
     <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
     <ClInclude Include="..\bytecode\BytecodeUseDef.h" />
+    <ClInclude Include="..\bytecode\CallEdge.h" />
     <ClInclude Include="..\bytecode\CallLinkInfo.h" />
     <ClInclude Include="..\bytecode\CallLinkStatus.h" />
     <ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h" />
+    <ClInclude Include="..\bytecode\CallVariant.h" />
     <ClInclude Include="..\bytecode\CodeBlock.h" />
     <ClInclude Include="..\bytecode\CodeBlockHash.h" />
     <ClInclude Include="..\bytecode\CodeBlockJettisoningWatchpoint.h" />
     <ClInclude Include="..\bytecode\CodeOrigin.h" />
     <ClInclude Include="..\bytecode\CodeType.h" />
     <ClInclude Include="..\bytecode\Comment.h" />
+    <ClInclude Include="..\bytecode\ComplexGetStatus.h" />
+    <ClInclude Include="..\bytecode\ConstantStructureCheck.h" />
     <ClInclude Include="..\bytecode\DataFormat.h" />
     <ClInclude Include="..\bytecode\DeferredCompilationCallback.h" />
+    <ClInclude Include="..\bytecode\DeferredSourceDump.h" />
     <ClInclude Include="..\bytecode\DFGExitProfile.h" />
     <ClInclude Include="..\bytecode\EvalCodeCache.h" />
     <ClInclude Include="..\bytecode\ExecutionCounter.h" />
     <ClInclude Include="..\bytecode\Operands.h" />
     <ClInclude Include="..\bytecode\PolymorphicGetByIdList.h" />
     <ClInclude Include="..\bytecode\PolymorphicPutByIdList.h" />
-    <ClInclude Include="..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.h" />
     <ClInclude Include="..\bytecode\PreciseJumpTargets.h" />
     <ClInclude Include="..\bytecode\PutByIdStatus.h" />
     <ClInclude Include="..\bytecode\PutByIdVariant.h" />
     <ClInclude Include="..\bytecode\StructureSet.h" />
     <ClInclude Include="..\bytecode\StructureStubClearingWatchpoint.h" />
     <ClInclude Include="..\bytecode\StructureStubInfo.h" />
+    <ClInclude Include="..\bytecode\ToThisStatus.h" />
+    <ClInclude Include="..\bytecode\TrackedReferences.h" />
+    <ClInclude Include="..\bytecode\TypeLocation.h" />
     <ClInclude Include="..\bytecode\UnlinkedCodeBlock.h" />
     <ClInclude Include="..\bytecode\UnlinkedInstructionStream.h" />
     <ClInclude Include="..\bytecode\ValueProfile.h" />
     <ClInclude Include="..\bytecode\ValueRecovery.h" />
-    <ClInclude Include="..\bytecode\VariableWatchpointSet.h" />
+    <ClInclude Include="..\bytecode\VariableWriteFireDetail.h" />
     <ClInclude Include="..\bytecode\VirtualRegister.h" />
     <ClInclude Include="..\bytecode\Watchpoint.h" />
     <ClInclude Include="..\bytecompiler\BytecodeGenerator.h" />
     <ClInclude Include="..\config.h" />
     <ClInclude Include="..\debugger\Breakpoint.h" />
     <ClInclude Include="..\debugger\Debugger.h" />
-    <ClInclude Include="..\debugger\DebuggerActivation.h" />
     <ClInclude Include="..\debugger\DebuggerCallFrame.h" />
+    <ClInclude Include="..\debugger\DebuggerEvalEnabler.h" />
     <ClInclude Include="..\debugger\DebuggerPrimitives.h" />
+    <ClInclude Include="..\debugger\DebuggerScope.h" />
     <ClInclude Include="..\dfg\DFGAbstractHeap.h" />
     <ClInclude Include="..\dfg\DFGAbstractInterpreter.h" />
     <ClInclude Include="..\dfg\DFGAbstractInterpreterInlines.h" />
     <ClInclude Include="..\dfg\DFGAllocator.h" />
     <ClInclude Include="..\dfg\DFGAnalysis.h" />
     <ClInclude Include="..\dfg\DFGArgumentPosition.h" />
-    <ClInclude Include="..\dfg\DFGArgumentsSimplificationPhase.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsEliminationPhase.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsUtilities.h" />
     <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGArithMode.h" />
     <ClInclude Include="..\dfg\DFGArrayMode.h" />
     <ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
     <ClInclude Include="..\dfg\DFGAvailability.h" />
+    <ClInclude Include="..\dfg\DFGAvailabilityMap.h" />
     <ClInclude Include="..\dfg\DFGBackwardsPropagationPhase.h" />
     <ClInclude Include="..\dfg\DFGBasicBlock.h" />
     <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
-    <ClInclude Include="..\dfg\DFGBinarySwitch.h" />
     <ClInclude Include="..\dfg\DFGBlockInsertionSet.h" />
+    <ClInclude Include="..\dfg\DFGBlockMap.h" />
+    <ClInclude Include="..\dfg\DFGBlockMapInlines.h" />
+    <ClInclude Include="..\dfg\DFGBlockWorklist.h" />
+    <ClInclude Include="..\dfg\DFGBlockSet.h" />
+    <ClInclude Include="..\dfg\DFGBlockSetInlines.h" />
     <ClInclude Include="..\dfg\DFGBranchDirection.h" />
     <ClInclude Include="..\dfg\DFGByteCodeParser.h" />
     <ClInclude Include="..\dfg\DFGCallArrayAllocatorSlowPathGenerator.h" />
+    <ClInclude Include="..\dfg\DFGCallCreateDirectArgumentsSlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGCapabilities.h" />
     <ClInclude Include="..\dfg\DFGCCallHelpers.h" />
     <ClInclude Include="..\dfg\DFGCFAPhase.h" />
     <ClInclude Include="..\dfg\DFGCFGSimplificationPhase.h" />
+    <ClInclude Include="..\dfg\DFGCleanUpPhase.h" />
     <ClInclude Include="..\dfg\DFGClobberize.h" />
     <ClInclude Include="..\dfg\DFGClobberSet.h" />
+    <ClInclude Include="..\dfg\DFGCombinedLiveness.h" />
     <ClInclude Include="..\dfg\DFGCommon.h" />
     <ClInclude Include="..\dfg\DFGCommonData.h" />
     <ClInclude Include="..\dfg\DFGCompilationKey.h" />
     <ClInclude Include="..\dfg\DFGCompilationMode.h" />
     <ClInclude Include="..\dfg\DFGConstantFoldingPhase.h" />
+    <ClInclude Include="..\dfg\DFGConstantHoistingPhase.h" />
     <ClInclude Include="..\dfg\DFGCPSRethreadingPhase.h" />
     <ClInclude Include="..\dfg\DFGCriticalEdgeBreakingPhase.h" />
     <ClInclude Include="..\dfg\DFGCSEPhase.h" />
     <ClInclude Include="..\dfg\DFGDCEPhase.h" />
     <ClInclude Include="..\dfg\DFGDesiredIdentifiers.h" />
-    <ClInclude Include="..\dfg\DFGDesiredStructureChains.h" />
     <ClInclude Include="..\dfg\DFGDesiredTransitions.h" />
     <ClInclude Include="..\dfg\DFGDesiredWatchpoints.h" />
     <ClInclude Include="..\dfg\DFGDesiredWeakReferences.h" />
     <ClInclude Include="..\dfg\DFGDesiredWriteBarriers.h" />
     <ClInclude Include="..\dfg\DFGDisassembler.h" />
+    <ClInclude Include="..\dfg\DFGDoesGC.h" />
     <ClInclude Include="..\dfg\DFGDominators.h" />
     <ClInclude Include="..\dfg\DFGDoubleFormatState.h" />
     <ClInclude Include="..\dfg\DFGDriver.h" />
     <ClInclude Include="..\dfg\DFGEdge.h" />
     <ClInclude Include="..\dfg\DFGEdgeDominates.h" />
     <ClInclude Include="..\dfg\DFGEdgeUsesStructure.h" />
+    <ClInclude Include="..\dfg\DFGEpoch.h" />
     <ClInclude Include="..\dfg\DFGFailedFinalizer.h" />
     <ClInclude Include="..\dfg\DFGFiltrationResult.h" />
     <ClInclude Include="..\dfg\DFGFinalizer.h" />
     <ClInclude Include="..\dfg\DFGFixupPhase.h" />
     <ClInclude Include="..\dfg\DFGFlushedAt.h" />
     <ClInclude Include="..\dfg\DFGFlushFormat.h" />
+    <ClInclude Include="..\dfg\DFGForAllKills.h" />
     <ClInclude Include="..\dfg\DFGFPRInfo.h" />
+    <ClInclude Include="..\dfg\DFGFrozenValue.h" />
     <ClInclude Include="..\dfg\DFGFunctionWhitelist.h" />
     <ClInclude Include="..\dfg\DFGGenerationInfo.h" />
     <ClInclude Include="..\dfg\DFGGPRInfo.h" />
     <ClInclude Include="..\dfg\DFGGraph.h" />
     <ClInclude Include="..\dfg\DFGGraphSafepoint.h" />
+    <ClInclude Include="..\dfg\DFGHeapLocation.h" />
     <ClInclude Include="..\dfg\DFGInPlaceAbstractState.h" />
+    <ClInclude Include="..\dfg\DFGInsertOSRHintsForUpdate.h" />
     <ClInclude Include="..\dfg\DFGInsertionSet.h" />
     <ClInclude Include="..\dfg\DFGIntegerCheckCombiningPhase.h" />
+    <ClInclude Include="..\dfg\DFGIntegerRangeOptimizationPhase.h" />
     <ClInclude Include="..\dfg\DFGInvalidationPointInjectionPhase.h" />
     <ClInclude Include="..\dfg\DFGJITCode.h" />
     <ClInclude Include="..\dfg\DFGJITCompiler.h" />
     <ClInclude Include="..\dfg\DFGJITFinalizer.h" />
     <ClInclude Include="..\dfg\DFGJumpReplacement.h" />
     <ClInclude Include="..\dfg\DFGLazyJSValue.h" />
+    <ClInclude Include="..\dfg\DFGLazyNode.h" />
     <ClInclude Include="..\dfg\DFGLICMPhase.h" />
     <ClInclude Include="..\dfg\DFGLivenessAnalysisPhase.h" />
     <ClInclude Include="..\dfg\DFGLongLivedState.h" />
     <ClInclude Include="..\dfg\DFGLoopPreHeaderCreationPhase.h" />
+    <ClInclude Include="..\dfg\DFGMayExit.h" />
     <ClInclude Include="..\dfg\DFGMergeMode.h" />
     <ClInclude Include="..\dfg\DFGMinifiedGraph.h" />
     <ClInclude Include="..\dfg\DFGMinifiedID.h" />
     <ClInclude Include="..\dfg\DFGMinifiedNode.h" />
+    <ClInclude Include="..\dfg\DFGMovHintRemovalPhase.h" />
+    <ClInclude Include="..\dfg\DFGNaiveDominators.h" />
     <ClInclude Include="..\dfg\DFGNaturalLoops.h" />
     <ClInclude Include="..\dfg\DFGNode.h" />
     <ClInclude Include="..\dfg\DFGNodeAllocator.h" />
     <ClInclude Include="..\dfg\DFGNodeFlags.h" />
     <ClInclude Include="..\dfg\DFGNodeOrigin.h" />
     <ClInclude Include="..\dfg\DFGNodeType.h" />
+    <ClInclude Include="..\dfg\DFGObjectAllocationSinkingPhase.h" />
+    <ClInclude Include="..\dfg\DFGObjectMaterializationData.h" />
     <ClInclude Include="..\dfg\DFGOperations.h" />
     <ClInclude Include="..\dfg\DFGOSRAvailabilityAnalysisPhase.h" />
     <ClInclude Include="..\dfg\DFGOSREntry.h" />
     <ClInclude Include="..\dfg\DFGOSRExitCompilationInfo.h" />
     <ClInclude Include="..\dfg\DFGOSRExitCompiler.h" />
     <ClInclude Include="..\dfg\DFGOSRExitCompilerCommon.h" />
+    <ClInclude Include="..\dfg\DFGOSRExitFuzz.h" />
     <ClInclude Include="..\dfg\DFGOSRExitJumpPlaceholder.h" />
     <ClInclude Include="..\dfg\DFGOSRExitPreparation.h" />
+    <ClInclude Include="..\dfg\DFGPhantomInsertionPhase.h" />
     <ClInclude Include="..\dfg\DFGPhase.h" />
+    <ClInclude Include="..\dfg\DFGPhiChildren.h" />
     <ClInclude Include="..\dfg\DFGPlan.h" />
+    <ClInclude Include="..\dfg\DFGPrePostNumbering.h" />
+    <ClInclude Include="..\dfg\DFGPreciseLocalClobberize.h" />
     <ClInclude Include="..\dfg\DFGPredictionInjectionPhase.h" />
     <ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" />
+    <ClInclude Include="..\dfg\DFGPromoteHeapAccess.h" />
+    <ClInclude Include="..\dfg\DFGPromotedHeapLocation.h" />
+    <ClInclude Include="..\dfg\DFGPureValue.h" />
+    <ClInclude Include="..\dfg\DFGPutStackSinkingPhase.h" />
     <ClInclude Include="..\dfg\DFGRegisterBank.h" />
     <ClInclude Include="..\dfg\DFGRegisterSet.h" />
-    <ClInclude Include="..\dfg\DFGResurrectionForValidationPhase.h" />
     <ClInclude Include="..\dfg\DFGSafeToExecute.h" />
     <ClInclude Include="..\dfg\DFGSafepoint.h" />
     <ClInclude Include="..\dfg\DFGSaneStringGetByValSlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGSilentRegisterSavePlan.h" />
     <ClInclude Include="..\dfg\DFGSlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGSpeculativeJIT.h" />
+    <ClInclude Include="..\dfg\DFGSSACalculator.h" />
     <ClInclude Include="..\dfg\DFGSSAConversionPhase.h" />
     <ClInclude Include="..\dfg\DFGSSALoweringPhase.h" />
     <ClInclude Include="..\dfg\DFGStackLayoutPhase.h" />
     <ClInclude Include="..\dfg\DFGStaticExecutionCountEstimationPhase.h" />
-    <ClInclude Include="..\dfg\DFGStoreBarrierElisionPhase.h" />
+    <ClInclude Include="..\dfg\DFGStoreBarrierInsertionPhase.h" />
     <ClInclude Include="..\dfg\DFGStrengthReductionPhase.h" />
     <ClInclude Include="..\dfg\DFGStructureAbstractValue.h" />
+    <ClInclude Include="..\dfg\DFGStructureClobberState.h" />
+    <ClInclude Include="..\dfg\DFGStructureRegistrationPhase.h" />
     <ClInclude Include="..\dfg\DFGThreadData.h" />
     <ClInclude Include="..\dfg\DFGThunks.h" />
     <ClInclude Include="..\dfg\DFGTierUpCheckInjectionPhase.h" />
     <ClInclude Include="..\dfg\DFGToFTLDeferredCompilationCallback.h" />
     <ClInclude Include="..\dfg\DFGToFTLForOSREntryDeferredCompilationCallback.h" />
+    <ClInclude Include="..\dfg\DFGTransition.h" />
     <ClInclude Include="..\dfg\DFGTypeCheckHoistingPhase.h" />
     <ClInclude Include="..\dfg\DFGUnificationPhase.h" />
     <ClInclude Include="..\dfg\DFGUseKind.h" />
     <ClInclude Include="..\dfg\DFGValidate.h" />
-    <ClInclude Include="..\dfg\DFGValueRecoveryOverride.h" />
     <ClInclude Include="..\dfg\DFGValueSource.h" />
+    <ClInclude Include="..\dfg\DFGValueStrength.h" />
+    <ClInclude Include="..\dfg\DFGVarargsForwardingPhase.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessData.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessDataDump.h" />
     <ClInclude Include="..\dfg\DFGVariableEvent.h" />
     <ClInclude Include="..\ftl\FTLExitArgument.h" />
     <ClInclude Include="..\ftl\FTLExitArgumentForOperand.h" />
     <ClInclude Include="..\ftl\FTLExitArgumentList.h" />
+    <ClInclude Include="..\ftl\FTLExitPropertyValue.h" />
     <ClInclude Include="..\ftl\FTLExitThunkGenerator.h" />
+    <ClInclude Include="..\ftl\FTLExitTimeObjectMaterialization.h" />
     <ClInclude Include="..\ftl\FTLExitValue.h" />
     <ClInclude Include="..\ftl\FTLFail.h" />
     <ClInclude Include="..\ftl\FTLFormattedValue.h" />
     <ClInclude Include="..\ftl\FTLJITCode.h" />
     <ClInclude Include="..\ftl\FTLJITFinalizer.h" />
     <ClInclude Include="..\ftl\FTLJSCall.h" />
+    <ClInclude Include="..\ftl\FTLJSCallBase.h" />
+    <ClInclude Include="..\ftl\FTLJSCallVarargs.h" />
     <ClInclude Include="..\ftl\FTLLink.h" />
     <ClInclude Include="..\ftl\FTLLocation.h" />
     <ClInclude Include="..\ftl\FTLLowerDFGToLLVM.h" />
     <ClInclude Include="..\ftl\FTLOSRExit.h" />
     <ClInclude Include="..\ftl\FTLOSRExitCompilationInfo.h" />
     <ClInclude Include="..\ftl\FTLOSRExitCompiler.h" />
+    <ClInclude Include="..\ftl\FTLOperations.h" />
     <ClInclude Include="..\ftl\FTLOutput.h" />
     <ClInclude Include="..\ftl\FTLRecoveryOpcode.h" />
     <ClInclude Include="..\ftl\FTLRegisterAtOffset.h" />
     <ClInclude Include="..\ftl\FTLValueRange.h" />
     <ClInclude Include="..\ftl\FTLWeight.h" />
     <ClInclude Include="..\ftl\FTLWeightedTarget.h" />
-    <ClInclude Include="..\heap\BlockAllocator.h" />
     <ClInclude Include="..\heap\CodeBlockSet.h" />
     <ClInclude Include="..\heap\ConservativeRoots.h" />
     <ClInclude Include="..\heap\CopiedAllocator.h" />
     <ClInclude Include="..\heap\CopyWorkList.h" />
     <ClInclude Include="..\heap\CopyWriteBarrier.h" />
     <ClInclude Include="..\heap\DeferGC.h" />
-    <ClInclude Include="..\heap\DelayedReleaseScope.h" />
     <ClInclude Include="..\heap\EdenGCActivityCallback.h" />
     <ClInclude Include="..\heap\FullGCActivityCallback.h" />
     <ClInclude Include="..\heap\GCActivityCallback.h" />
     <ClInclude Include="..\heap\HandleStack.h" />
     <ClInclude Include="..\heap\HandleTypes.h" />
     <ClInclude Include="..\heap\Heap.h" />
-    <ClInclude Include="..\heap\HeapBlock.h" />
     <ClInclude Include="..\heap\HeapInlines.h" />
     <ClInclude Include="..\heap\HeapOperation.h" />
     <ClInclude Include="..\heap\HeapRootVisitor.h" />
     <ClInclude Include="..\heap\HeapStatistics.h" />
     <ClInclude Include="..\heap\HeapTimer.h" />
+    <ClInclude Include="..\heap\HeapVerifier.h" />
     <ClInclude Include="..\heap\IncrementalSweeper.h" />
     <ClInclude Include="..\heap\JITStubRoutineSet.h" />
     <ClInclude Include="..\heap\ListableHandler.h" />
     <ClInclude Include="..\heap\MarkedSpace.h" />
     <ClInclude Include="..\heap\MarkStack.h" />
     <ClInclude Include="..\heap\RecursiveAllocationScope.h" />
-    <ClInclude Include="..\heap\Region.h" />
     <ClInclude Include="..\heap\SlotVisitor.h" />
     <ClInclude Include="..\heap\SlotVisitorInlines.h" />
     <ClInclude Include="..\heap\Strong.h" />
     <ClInclude Include="..\heap\StrongInlines.h" />
-    <ClInclude Include="..\heap\SuperRegion.h" />
     <ClInclude Include="..\heap\TinyBloomFilter.h" />
     <ClInclude Include="..\heap\UnconditionalFinalizer.h" />
     <ClInclude Include="..\heap\Weak.h" />
     <ClInclude Include="..\inspector\InspectorBackendDispatcher.h" />
     <ClInclude Include="..\inspector\InspectorEnvironment.h" />
     <ClInclude Include="..\inspector\InspectorFrontendChannel.h" />
-    <ClInclude Include="..\inspector\InspectorTypeBuilder.h" />
     <ClInclude Include="..\inspector\InspectorValues.h" />
     <ClInclude Include="..\inspector\JSInjectedScriptHost.h" />
     <ClInclude Include="..\inspector\JSInjectedScriptHostPrototype.h" />
     <ClInclude Include="..\inspector\agents\InspectorAgent.h" />
     <ClInclude Include="..\inspector\agents\InspectorConsoleAgent.h" />
     <ClInclude Include="..\inspector\agents\InspectorDebuggerAgent.h" />
-    <ClInclude Include="..\inspector\agents\InspectorProfilerAgent.h" />
     <ClInclude Include="..\inspector\agents\InspectorRuntimeAgent.h" />
     <ClInclude Include="..\interpreter\AbstractPC.h" />
     <ClInclude Include="..\interpreter\CachedCall.h" />
     <ClInclude Include="..\interpreter\CallFrame.h" />
     <ClInclude Include="..\interpreter\CallFrameInlines.h" />
     <ClInclude Include="..\interpreter\CallFrameClosure.h" />
+    <ClInclude Include="..\interpreter\VMEntryRecord.h" />
     <ClInclude Include="..\interpreter\Interpreter.h" />
     <ClInclude Include="..\interpreter\JSStack.h" />
     <ClInclude Include="..\interpreter\JSStackInlines.h" />
     <ClInclude Include="..\interpreter\ProtoCallFrame.h" />
     <ClInclude Include="..\interpreter\Register.h" />
     <ClInclude Include="..\interpreter\StackVisitor.h" />
-    <ClInclude Include="..\interpreter\VMInspector.h" />
     <ClInclude Include="..\jit\AccessorCallJITStubRoutine.h" />
     <ClInclude Include="..\jit\ArityCheckFailReturnThunks.h" />
     <ClInclude Include="..\jit\AssemblyHelpers.h" />
+    <ClInclude Include="..\jit\BinarySwitch.h" />
     <ClInclude Include="..\jit\CCallHelpers.h" />
-    <ClInclude Include="..\jit\ClosureCallStubRoutine.h" />
     <ClInclude Include="..\jit\CompactJITCodeMap.h" />
+    <ClInclude Include="..\jit\ExecutableAllocationFuzz.h" />
     <ClInclude Include="..\jit\ExecutableAllocator.h" />
     <ClInclude Include="..\jit\FPRInfo.h" />
     <ClInclude Include="..\jit\GCAwareJITStubRoutine.h" />
     <ClInclude Include="..\jit\JITToDFGDeferredCompilationCallback.h" />
     <ClInclude Include="..\jit\JITWriteBarrier.h" />
     <ClInclude Include="..\jit\JSInterfaceJIT.h" />
-    <ClCompile Include="..\jit\RegisterSet.cpp" />
+    <ClInclude Include="..\jit\SetupVarargsFrame.h" />
+    <ClInclude Include="..\jit\PolymorphicCallStubRoutine.h" />
     <ClInclude Include="..\jit\Reg.h" />
     <ClInclude Include="..\jit\RegisterPreservationWrapperGenerator.h" />
     <ClInclude Include="..\jit\RegisterSet.h" />
     <ClInclude Include="..\jit\Repatch.h" />
     <ClInclude Include="..\jit\ScratchRegisterAllocator.h" />
     <ClInclude Include="..\jit\SpecializedThunkJIT.h" />
-    <ClCompile Include="..\jit\TempRegisterSet.cpp" />
     <ClInclude Include="..\jit\TempRegisterSet.h" />
     <ClInclude Include="..\jit\ThunkGenerator.h" />
     <ClInclude Include="..\jit\ThunkGenerators.h" />
     <ClInclude Include="..\parser\ASTBuilder.h" />
     <ClInclude Include="..\parser\Lexer.h" />
     <ClInclude Include="..\parser\NodeConstructors.h" />
-    <ClInclude Include="..\parser\NodeInfo.h" />
     <ClInclude Include="..\parser\Nodes.h" />
     <ClInclude Include="..\parser\Parser.h" />
     <ClInclude Include="..\parser\ParserArena.h" />
     <ClInclude Include="..\profiler\ProfilerOSRExitSite.h" />
     <ClInclude Include="..\profiler\ProfilerProfiledBytecodes.h" />
     <ClInclude Include="..\runtime\ArgList.h" />
-    <ClInclude Include="..\runtime\Arguments.h" />
+    <ClInclude Include="..\runtime\ArgumentsMode.h" />
     <ClInclude Include="..\runtime\ArrayBuffer.h" />
     <ClInclude Include="..\runtime\ArrayBufferNeuteringWatchpoint.h" />
     <ClInclude Include="..\runtime\ArrayBufferView.h" />
     <ClInclude Include="..\runtime\ArrayConstructor.h" />
     <ClInclude Include="..\runtime\ArrayConventions.h" />
-    <ClInclude Include="..\runtime\ArrayIteratorConstructor.h" />
     <ClInclude Include="..\runtime\ArrayIteratorPrototype.h" />
     <ClInclude Include="..\runtime\ArrayPrototype.h" />
     <ClInclude Include="..\runtime\ArrayStorage.h" />
+    <ClInclude Include="..\runtime\BasicBlockLocation.h" />
     <ClInclude Include="..\runtime\BatchedTransitionOptimizer.h" />
     <ClInclude Include="..\runtime\BigInteger.h" />
     <ClInclude Include="..\runtime\BooleanConstructor.h" />
     <ClInclude Include="..\runtime\ButterflyInlines.h" />
     <ClInclude Include="..\runtime\CallData.h" />
     <ClInclude Include="..\runtime\ClassInfo.h" />
+    <ClInclude Include="..\runtime\ClonedArguments.h" />
     <ClInclude Include="..\runtime\CodeCache.h" />
     <ClInclude Include="..\runtime\CodeSpecializationKind.h" />
     <ClInclude Include="..\runtime\CommonIdentifiers.h" />
     <ClInclude Include="..\runtime\ConsoleTypes.h" />
     <ClInclude Include="..\runtime\ConstantMode.h" />
     <ClInclude Include="..\runtime\ConstructData.h" />
+    <ClInclude Include="..\runtime\ControlFlowProfiler.h" />
     <ClInclude Include="..\runtime\CustomGetterSetter.h" />
     <ClInclude Include="..\runtime\DataView.h" />
     <ClInclude Include="..\runtime\DateConstructor.h" />
     <ClInclude Include="..\runtime\DateInstance.h" />
     <ClInclude Include="..\runtime\DateInstanceCache.h" />
     <ClInclude Include="..\runtime\DatePrototype.h" />
+    <ClInclude Include="..\runtime\DirectArguments.h" />
+    <ClInclude Include="..\runtime\DirectArgumentsOffset.h" />
     <ClInclude Include="..\runtime\DumpContext.h" />
+    <ClInclude Include="..\runtime\EnumerationMode.h" />
     <ClInclude Include="..\runtime\Error.h" />
     <ClInclude Include="..\runtime\ErrorConstructor.h" />
     <ClInclude Include="..\runtime\ErrorHandlingScope.h" />
     <ClInclude Include="..\runtime\ErrorInstance.h" />
     <ClInclude Include="..\runtime\ErrorPrototype.h" />
+    <ClInclude Include="..\runtime\Exception.h" />
+    <ClInclude Include="..\runtime\ExceptionFuzz.h" />
     <ClInclude Include="..\runtime\ExceptionHelpers.h" />
     <ClInclude Include="..\runtime\Executable.h" />
     <ClInclude Include="..\runtime\Float32Array.h" />
     <ClInclude Include="..\runtime\Float64Array.h" />
     <ClInclude Include="..\runtime\FunctionConstructor.h" />
     <ClInclude Include="..\runtime\FunctionExecutableDump.h" />
+    <ClInclude Include="..\runtime\FunctionHasExecutedCache.h" />
     <ClInclude Include="..\runtime\FunctionPrototype.h" />
+    <ClInclude Include="..\runtime\FunctionRareData.h" />
+    <ClInclude Include="..\runtime\GenericArguments.h" />
+    <ClInclude Include="..\runtime\GenericArgumentsInlines.h" />
+    <ClInclude Include="..\runtime\GenericOffset.h" />
     <ClInclude Include="..\runtime\GenericTypedArrayView.h" />
     <ClInclude Include="..\runtime\GenericTypedArrayViewInlines.h" />
     <ClInclude Include="..\runtime\GetterSetter.h" />
     <ClInclude Include="..\runtime\IndexingHeader.h" />
     <ClInclude Include="..\runtime\IndexingHeaderInlines.h" />
     <ClInclude Include="..\runtime\IndexingType.h" />
+    <ClInclude Include="..\runtime\InferredValue.h" />
     <ClInclude Include="..\runtime\InitializeThreading.h" />
     <ClInclude Include="..\runtime\Int16Array.h" />
     <ClInclude Include="..\runtime\Int32Array.h" />
     <ClInclude Include="..\runtime\Int8Array.h" />
     <ClInclude Include="..\runtime\IntendedStructureChain.h" />
     <ClInclude Include="..\runtime\InternalFunction.h" />
+    <ClInclude Include="..\runtime\IntlObject.h" />
     <ClInclude Include="..\runtime\Intrinsic.h" />
+    <ClInclude Include="..\runtime\IterationStatus.h" />
+    <ClInclude Include="..\runtime\IteratorOperations.h" />
+    <ClInclude Include="..\runtime\IteratorPrototype.h" />
     <ClInclude Include="..\runtime\JSAPIValueWrapper.h" />
-    <ClInclude Include="..\runtime\JSActivation.h" />
-    <ClInclude Include="..\runtime\JSArgumentsIterator.h" />
+    <ClInclude Include="..\runtime\JSLexicalEnvironment.h" />
     <ClInclude Include="..\runtime\JSArray.h" />
     <ClInclude Include="..\runtime\JSArrayBuffer.h" />
     <ClInclude Include="..\runtime\JSArrayBufferConstructor.h" />
     <ClInclude Include="..\runtime\JSCInlines.h" />
     <ClInclude Include="..\runtime\JSCJSValue.h" />
     <ClInclude Include="..\runtime\JSCJSValueInlines.h" />
+    <ClInclude Include="..\runtime\JSCallee.h" />
+    <ClInclude Include="..\runtime\JSCatchScope.h" />
     <ClInclude Include="..\runtime\JSCell.h" />
     <ClInclude Include="..\runtime\JSConsole.h" />
     <ClInclude Include="..\runtime\JSDataView.h" />
     <ClInclude Include="..\runtime\JSFloat32Array.h" />
     <ClInclude Include="..\runtime\JSFloat64Array.h" />
     <ClInclude Include="..\runtime\JSFunction.h" />
+    <ClInclude Include="..\runtime\JSFunctionNameScope.h" />
     <ClInclude Include="..\runtime\JSGenericTypedArrayView.h" />
     <ClInclude Include="..\runtime\JSGenericTypedArrayViewConstructor.h" />
     <ClInclude Include="..\runtime\JSGenericTypedArrayViewConstructorInlines.h" />
     <ClInclude Include="..\runtime\JSGenericTypedArrayViewPrototypeInlines.h" />
     <ClInclude Include="..\runtime\JSGlobalObject.h" />
     <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h" />
+    <ClInclude Include="..\runtime\JSJob.h" />
     <ClInclude Include="..\runtime\JSInt16Array.h" />
     <ClInclude Include="..\runtime\JSInt32Array.h" />
     <ClInclude Include="..\runtime\JSInt8Array.h" />
     <ClInclude Include="..\runtime\JSPromise.h" />
     <ClInclude Include="..\runtime\JSPromiseConstructor.h" />
     <ClInclude Include="..\runtime\JSPromiseDeferred.h" />
-    <ClInclude Include="..\runtime\JSPromiseFunctions.h" />
-    <ClInclude Include="..\runtime\JSPromiseReaction.h" />
     <ClInclude Include="..\runtime\JSPromisePrototype.h" />
-    <ClInclude Include="..\runtime\JSPropertyNameIterator.h" />
+    <ClInclude Include="..\runtime\JSPropertyNameEnumerator.h" />
     <ClInclude Include="..\runtime\JSProxy.h" />
     <ClInclude Include="..\runtime\JSScope.h" />
     <ClInclude Include="..\runtime\JSSegmentedVariableObject.h" />
     <ClInclude Include="..\runtime\JSSetIterator.h" />
     <ClInclude Include="..\runtime\JSString.h" />
     <ClInclude Include="..\runtime\JSStringBuilder.h" />
+    <ClInclude Include="..\runtime\JSStringIterator.h" />
     <ClInclude Include="..\runtime\JSStringJoiner.h" />
     <ClInclude Include="..\runtime\JSSymbolTableObject.h" />
+    <ClInclude Include="..\runtime\JSTemplateRegistryKey.h" />
     <ClInclude Include="..\runtime\JSType.h" />
     <ClInclude Include="..\runtime\JSTypeInfo.h" />
     <ClInclude Include="..\runtime\JSTypedArrayConstructors.h" />
     <ClInclude Include="..\runtime\JSUint32Array.h" />
     <ClInclude Include="..\runtime\JSUint8Array.h" />
     <ClInclude Include="..\runtime\JSUint8ClampedArray.h" />
-    <ClInclude Include="..\runtime\JSVariableObject.h" />
+    <ClInclude Include="..\runtime\JSEnvironmentRecord.h" />
     <ClInclude Include="..\runtime\JSWeakMap.h" />
+    <ClInclude Include="..\runtime\JSWeakSet.h" />
     <ClInclude Include="..\runtime\JSWithScope.h" />
     <ClInclude Include="..\runtime\JSWrapperObject.h" />
     <ClInclude Include="..\runtime\LiteralParser.h" />
     <ClInclude Include="..\runtime\Lookup.h" />
     <ClInclude Include="..\runtime\MapConstructor.h" />
     <ClInclude Include="..\runtime\MapData.h" />
-    <ClInclude Include="..\runtime\MapIteratorConstructor.h" />
+    <ClInclude Include="..\runtime\MapDataInlines.h" />
     <ClInclude Include="..\runtime\MapIteratorPrototype.h" />
     <ClInclude Include="..\runtime\MapPrototype.h" />
     <ClInclude Include="..\runtime\MatchResult.h" />
+    <ClInclude Include="..\runtime\MathCommon.h" />
     <ClInclude Include="..\runtime\MathObject.h" />
     <ClInclude Include="..\runtime\MemoryStatistics.h" />
     <ClInclude Include="..\runtime\Microtask.h" />
-    <ClInclude Include="..\runtime\NameConstructor.h" />
-    <ClInclude Include="..\runtime\NameInstance.h" />
-    <ClInclude Include="..\runtime\NamePrototype.h" />
     <ClInclude Include="..\runtime\NativeErrorConstructor.h" />
     <ClInclude Include="..\runtime\NativeErrorPrototype.h" />
+    <ClInclude Include="..\runtime\NullGetterFunction.h" />
+    <ClInclude Include="..\runtime\NullSetterFunction.h" />
     <ClInclude Include="..\runtime\NumberConstructor.h" />
     <ClInclude Include="..\runtime\NumberObject.h" />
     <ClInclude Include="..\runtime\NumberPrototype.h" />
     <ClInclude Include="..\runtime\RegExpObject.h" />
     <ClInclude Include="..\runtime\RegExpPrototype.h" />
     <ClInclude Include="..\runtime\Reject.h" />
+    <ClInclude Include="..\runtime\RuntimeFlags.h" />
+    <ClInclude Include="..\runtime\RuntimeType.h" />
     <ClInclude Include="..\runtime\SamplingCounter.h" />
+    <ClInclude Include="..\runtime\ScopeOffset.h" />
+    <ClInclude Include="..\runtime\ScopedArguments.h" />
+    <ClInclude Include="..\runtime\ScopedArgumentsTable.h" />
     <ClInclude Include="..\runtime\SetConstructor.h" />
-    <ClInclude Include="..\runtime\SetIteratorConstructor.h" />
     <ClInclude Include="..\runtime\SetIteratorPrototype.h" />
     <ClInclude Include="..\runtime\SetPrototype.h" />
     <ClInclude Include="..\runtime\SimpleTypedArrayController.h" />
     <ClInclude Include="..\runtime\StackAlignment.h" />
     <ClInclude Include="..\runtime\StrictEvalActivation.h" />
     <ClInclude Include="..\runtime\StringConstructor.h" />
+    <ClInclude Include="..\runtime\StringIteratorPrototype.h" />
     <ClInclude Include="..\runtime\StringObject.h" />
     <ClInclude Include="..\runtime\StringPrototype.h" />
     <ClInclude Include="..\runtime\StringRecursionChecker.h" />
     <ClInclude Include="..\runtime\StructureRareData.h" />
     <ClInclude Include="..\runtime\StructureRareDataInlines.h" />
     <ClInclude Include="..\runtime\StructureTransitionTable.h" />
+    <ClInclude Include="..\runtime\Symbol.h" />
+    <ClInclude Include="..\runtime\SymbolConstructor.h" />
+    <ClInclude Include="..\runtime\SymbolObject.h" />
+    <ClInclude Include="..\runtime\SymbolPrototype.h" />
     <ClInclude Include="..\runtime\SymbolTable.h" />
+    <ClInclude Include="..\runtime\TemplateRegistry.h" />
+    <ClInclude Include="..\runtime\TemplateRegistryKey.h" />
     <ClInclude Include="..\runtime\TestRunnerUtils.h" />
     <ClInclude Include="..\runtime\Tracing.h" />
     <ClInclude Include="..\runtime\ToNativeFromValue.h" />
     <ClInclude Include="..\runtime\TypedArrayController.h" />
     <ClInclude Include="..\runtime\TypedArrayInlines.h" />
     <ClInclude Include="..\runtime\TypedArrayType.h" />
+    <ClInclude Include="..\runtime\TypeofType.h" />
+    <ClInclude Include="..\runtime\TypeLocationCache.h" />
+    <ClInclude Include="..\runtime\TypeProfiler.h" />
+    <ClInclude Include="..\runtime\TypeProfilerLog.h" />
+    <ClInclude Include="..\runtime\TypeSet.h" />
     <ClInclude Include="..\runtime\TypedArrays.h" />
     <ClInclude Include="..\runtime\Uint16Array.h" />
     <ClInclude Include="..\runtime\Uint16WithFraction.h" />
     <ClInclude Include="..\runtime\Uint8Array.h" />
     <ClInclude Include="..\runtime\VM.h" />
     <ClInclude Include="..\runtime\VMEntryScope.h" />
+    <ClInclude Include="..\runtime\VarOffset.h" />
     <ClInclude Include="..\runtime\Watchdog.h" />
     <ClInclude Include="..\runtime\WeakGCMap.h" />
     <ClInclude Include="..\runtime\WeakMapConstructor.h" />
     <ClInclude Include="..\runtime\WeakMapData.h" />
     <ClInclude Include="..\runtime\WeakMapPrototype.h" />
+    <ClInclude Include="..\runtime\WeakSetConstructor.h" />
+    <ClInclude Include="..\runtime\WeakSetPrototype.h" />
     <ClInclude Include="..\runtime\WeakRandom.h" />
     <ClInclude Include="..\runtime\WriteBarrier.h" />
     <ClInclude Include="..\runtime\WriteBarrierInlines.h" />
     <ClInclude Include="..\tools\CodeProfile.h" />
     <ClInclude Include="..\tools\CodeProfiling.h" />
+    <ClInclude Include="..\tools\FunctionOverrides.h" />
+    <ClInclude Include="..\tools\JSDollarVM.h" />
+    <ClInclude Include="..\tools\JSDollarVMPrototype.h" />
     <ClInclude Include="..\tools\ProfileTreeNode.h" />
     <ClInclude Include="..\tools\TieredMMapArray.h" />
     <ClInclude Include="..\yarr\RegularExpression.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\bytecode\BytecodeList.json" />
+    <None Include="..\inspector\scripts\codegen\cpp_generator.py" />
+    <None Include="..\inspector\scripts\codegen\cpp_generator_templates.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_backend_dispatcher_header.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_backend_dispatcher_implementation.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_frontend_dispatcher_header.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_frontend_dispatcher_implementation.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_protocol_types_header.py" />
+    <None Include="..\inspector\scripts\codegen\generate_cpp_protocol_types_implementation.py" />
+    <None Include="..\inspector\scripts\codegen\generate_js_backend_commands.py" />
+    <None Include="..\inspector\scripts\codegen\generator.py" />
+    <None Include="..\inspector\scripts\codegen\generator_templates.py" />
+    <None Include="..\inspector\scripts\codegen\models.py" />
+    <None Include="..\inspector\scripts\codegen\__init__.py" />
+    <None Include="..\inspector\scripts\cssmin.py" />
+    <None Include="..\inspector\scripts\generate-combined-inspector-json.py" />
+    <None Include="..\inspector\scripts\generate-inspector-protocol-bindings.py" />
+    <None Include="..\inspector\scripts\inline-and-minify-stylesheets-and-scripts.py" />
+    <None Include="..\inspector\scripts\jsmin.py" />
+    <None Include="..\inspector\scripts\tests\commands-with-async-attribute.json" />
+    <None Include="..\inspector\scripts\tests\commands-with-optional-call-return-parameters.json" />
+    <None Include="..\inspector\scripts\tests\domains-with-varying-command-sizes.json" />
+    <None Include="..\inspector\scripts\tests\events-with-optional-parameters.json" />
+    <None Include="..\inspector\scripts\tests\expected\commands-with-async-attribute.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\commands-with-optional-call-return-parameters.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\domains-with-varying-command-sizes.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\events-with-optional-parameters.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-duplicate-type-declarations.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-enum-with-no-values.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-string-typed-optional-parameter-flag.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-string-typed-optional-type-member.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-type-declaration-using-type-reference.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-type-with-lowercase-name.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-unknown-type-reference-in-type-declaration.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\fail-on-unknown-type-reference-in-type-member.json-error" />
+    <None Include="..\inspector\scripts\tests\expected\same-type-id-different-domain.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\shadowed-optional-type-setters.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-aliased-primitive-type.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-array-type.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-enum-type.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-object-type.json-result" />
+    <None Include="..\inspector\scripts\tests\expected\type-requiring-runtime-casts.json-result" />
+    <None Include="..\inspector\scripts\tests\fail-on-duplicate-type-declarations.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-enum-with-no-values.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-string-typed-optional-parameter-flag.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-string-typed-optional-type-member.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-type-declaration-using-type-reference.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-type-with-lowercase-name.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-unknown-type-reference-in-type-declaration.json" />
+    <None Include="..\inspector\scripts\tests\fail-on-unknown-type-reference-in-type-member.json" />
+    <None Include="..\inspector\scripts\tests\same-type-id-different-domain.json" />
+    <None Include="..\inspector\scripts\tests\shadowed-optional-type-setters.json" />
+    <None Include="..\inspector\scripts\tests\type-declaration-aliased-primitive-type.json" />
+    <None Include="..\inspector\scripts\tests\type-declaration-array-type.json" />
+    <None Include="..\inspector\scripts\tests\type-declaration-enum-type.json" />
+    <None Include="..\inspector\scripts\tests\type-declaration-object-type.json" />
+    <None Include="..\inspector\scripts\tests\type-requiring-runtime-casts.json" />
+    <None Include="..\inspector\scripts\xxd.pl" />
     <None Include="JavaScriptCorePostBuild.cmd">
       <FileType>Document</FileType>
     </None>
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index a9872367c3cfd7681e459a8da09fb0131958ae61..a66b830d4aa586b0d3c3bff0eedfab109081f783 100644 (file)
     <Filter Include="llvm">
       <UniqueIdentifier>{852e9415-245c-4012-aeb8-38ca9efb73b8}</UniqueIdentifier>
     </Filter>
+    <Filter Include="inspector\scripts">
+      <UniqueIdentifier>{a29d27c0-2c34-482b-87cc-21e7ef290c88}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="inspector\scripts\codegen">
+      <UniqueIdentifier>{17e304e8-c0e8-4b18-88fa-62b86eba9959}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="inspector\scripts\tests">
+      <UniqueIdentifier>{0a034c97-3947-47c4-8085-2ddc8aa1ade0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="inspector\scripts\tests\expected">
+      <UniqueIdentifier>{6be9d367-0091-4ebb-b96c-4ef83790362b}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\API\JSBase.cpp">
     <ClCompile Include="..\assembler\MacroAssembler.cpp">
       <Filter>assembler</Filter>
     </ClCompile>
+    <ClCompile Include="..\assembler\MacroAssemblerX86Common.cpp">
+      <Filter>assembler</Filter>
+    </ClCompile>
     <ClCompile Include="..\builtins\BuiltinExecutables.cpp">
       <Filter>builtins</Filter>
     </ClCompile>
     <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp">
       <Filter>bytecode</Filter>
     </ClCompile>
+    <ClCompile Include="..\bytecode\BytecodeIntrinsicRegistry.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
     <ClCompile Include="..\bytecode\BytecodeLivenessAnalysis.cpp">
       <Filter>bytecode</Filter>
     </ClCompile>
     <ClCompile Include="..\debugger\Debugger.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
-    <ClCompile Include="..\debugger\DebuggerActivation.cpp">
+    <ClCompile Include="..\debugger\DebuggerCallFrame.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
-    <ClCompile Include="..\debugger\DebuggerCallFrame.cpp">
+    <ClCompile Include="..\debugger\DebuggerScope.cpp">
       <Filter>debugger</Filter>
     </ClCompile>
     <ClCompile Include="..\disassembler\Disassembler.cpp">
       <Filter>disassembler</Filter>
     </ClCompile>
-    <ClCompile Include="..\heap\BlockAllocator.cpp">
-      <Filter>heap</Filter>
-    </ClCompile>
     <ClCompile Include="..\heap\ConservativeRoots.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClCompile Include="..\heap\HeapTimer.cpp">
       <Filter>heap</Filter>
     </ClCompile>
+    <ClCompile Include="..\heap\HeapVerifier.cpp">
+      <Filter>heap</Filter>
+    </ClCompile>
     <ClCompile Include="..\heap\IncrementalSweeper.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClCompile Include="..\heap\SlotVisitor.cpp">
       <Filter>heap</Filter>
     </ClCompile>
-    <ClCompile Include="..\heap\SuperRegion.cpp">
-      <Filter>heap</Filter>
-    </ClCompile>
     <ClCompile Include="..\heap\Weak.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClCompile Include="..\inspector\agents\InspectorDebuggerAgent.cpp">
       <Filter>inspector</Filter>
     </ClCompile>
-    <ClCompile Include="..\inspector\agents\InspectorProfilerAgent.cpp">
-      <Filter>inspector</Filter>
-    </ClCompile>
     <ClCompile Include="..\inspector\agents\InspectorRuntimeAgent.cpp">
       <Filter>inspector</Filter>
     </ClCompile>
     <ClCompile Include="..\interpreter\StackVisitor.cpp">
       <Filter>interpreter</Filter>
     </ClCompile>
-    <ClCompile Include="..\interpreter\VMInspector.cpp">
-      <Filter>interpreter</Filter>
-    </ClCompile>
-    <ClCompile Include="..\jit\ClosureCallStubRoutine.cpp">
-      <Filter>jit</Filter>
-    </ClCompile>
     <ClCompile Include="..\jit\ExecutableAllocator.cpp">
       <Filter>jit</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\ArgList.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\Arguments.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\ArrayConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\ArrayPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\BasicBlockLocation.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\BooleanConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\ConstructData.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\ControlFlowProfiler.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\CustomGetterSetter.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\FunctionConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\FunctionHasExecutedCache.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\FunctionPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\FunctionRareData.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\GetterSetter.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\InternalFunction.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\JSActivation.cpp">
+    <ClCompile Include="..\runtime\IntlObject.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\IteratorOperations.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\IteratorPrototype.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\JSLexicalEnvironment.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSAPIValueWrapper.cpp">
     <ClCompile Include="..\runtime\JSBoundFunction.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\JSCallee.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\JSCell.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\JSJob.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\JSLock.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSONObject.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\JSPropertyNameIterator.cpp">
+    <ClCompile Include="..\runtime\JSPropertyNameEnumerator.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSProxy.cpp">
     <ClCompile Include="..\runtime\JSString.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\JSStringIterator.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\JSStringJoiner.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSSymbolTableObject.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\JSVariableObject.cpp">
+    <ClCompile Include="..\runtime\JSTemplateRegistryKey.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\JSEnvironmentRecord.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSWithScope.cpp">
     <ClCompile Include="..\runtime\JSWeakMap.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\JSWeakSet.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\JSWrapperObject.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\MapPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\MapData.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\MapConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\MathObject.cpp">
+    <ClCompile Include="..\runtime\MathCommon.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\NameConstructor.cpp">
+    <ClCompile Include="..\runtime\MathObject.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\NameInstance.cpp">
+    <ClCompile Include="..\runtime\NativeErrorConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\NamePrototype.cpp">
+    <ClCompile Include="..\runtime\NativeErrorPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\NativeErrorConstructor.cpp">
+    <ClCompile Include="..\runtime\NullGetterFunction.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\NativeErrorPrototype.cpp">
+    <ClCompile Include="..\runtime\NullSetterFunction.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\NumberConstructor.cpp">
     <ClCompile Include="..\runtime\PropertyDescriptor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\PropertyNameArray.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\PropertySlot.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\RegExpPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\RuntimeType.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\SamplingCounter.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\SetIteratorPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\SetIteratorConstructor.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\SetConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\SetIteratorConstructor.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\SparseArrayValueMap.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\StringConstructor.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\StringIteratorPrototype.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\StringObject.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\StructureIDTable.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\Symbol.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\SymbolConstructor.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\SymbolObject.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\SymbolPrototype.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\SymbolTable.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\TemplateRegistry.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\TypeLocationCache.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\TypeProfiler.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\TypeProfilerLog.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\TypeSet.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\runtime\Watchdog.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\tools\CodeProfiling.cpp">
       <Filter>tools</Filter>
     </ClCompile>
+    <ClCompile Include="..\tools\FunctionOverrides.cpp">
+      <Filter>tools</Filter>
+    </ClCompile>
+    <ClCompile Include="..\tools\JSDollarVM.cpp">
+      <Filter>tools</Filter>
+    </ClCompile>
+    <ClCompile Include="..\tools\JSDollarVMPrototype.cpp">
+      <Filter>tools</Filter>
+    </ClCompile>
     <ClCompile Include="..\yarr\RegularExpression.cpp">
       <Filter>yarr</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSPromiseDeferred.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\JSPromiseFunctions.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
-    <ClCompile Include="..\runtime\JSPromiseReaction.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\JSPromisePrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\WeakMapPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\runtime\WeakSetConstructor.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\WeakSetPrototype.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
     <ClCompile Include="..\heap\CodeBlockSet.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp">
       <Filter>bytecode</Filter>
     </ClCompile>
+    <ClCompile Include="..\bytecode\DeferredSourceDump.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
     <ClCompile Include="..\dfg\DFGCompilationKey.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
     <ClCompile Include="..\dfg\DFGAbstractValue.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
-    <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp">
-      <Filter>dfg</Filter>
-    </ClCompile>
     <ClCompile Include="..\dfg\DFGArrayMode.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
     <ClCompile Include="..\dfg\DFGBasicBlock.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
-    <ClCompile Include="..\dfg\DFGBinarySwitch.cpp">
-      <Filter>dfg</Filter>
-    </ClCompile>
     <ClCompile Include="..\dfg\DFGBlockInsertionSet.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
     <ClCompile Include="..\dfg\DFGDesiredIdentifiers.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
-    <ClCompile Include="..\dfg\DFGDesiredStructureChains.cpp">
-      <Filter>dfg</Filter>
-    </ClCompile>
     <ClCompile Include="..\dfg\DFGDesiredTransitions.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
     <ClCompile Include="..\dfg\DFGLazyJSValue.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
+    <ClCompile Include="..\dfg\DFGLazyNode.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
     <ClCompile Include="..\dfg\DFGLICMPhase.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\CompilationResult.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\ArrayIteratorConstructor.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\ArrayIteratorPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\ArgumentsIteratorConstructor.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
-    <ClCompile Include="..\runtime\ArgumentsIteratorPrototype.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
-    <ClCompile Include="..\runtime\MapIteratorConstructor.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\MapIteratorPrototype.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\JSArrayIterator.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="..\runtime\JSArgumentsIterator.cpp">
-      <Filter>runtime</Filter>
-    </ClCompile>
     <ClCompile Include="..\runtime\JSMapIterator.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
     <ClCompile Include="..\dfg\DFGAvailability.cpp">
       <Filter>dfg</Filter>
     </ClCompile>
-    <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp">
-      <Filter>dfg</Filter>
-    </ClCompile>
     <ClCompile Include="..\bytecode\CodeBlockJettisoningWatchpoint.cpp">
       <Filter>bytecode</Filter>
     </ClCompile>
-    <ClCompile Include="..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.cpp">
-      <Filter>bytecode</Filter>
-    </ClCompile>
     <ClCompile Include="..\bindings\ScriptValue.cpp">
       <Filter>bindings</Filter>
     </ClCompile>
     <ClCompile Include="..\runtime\ArrayBufferNeuteringWatchpoint.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSBackendDispatchers.cpp">
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorBackendDispatchers.cpp">
       <Filter>Derived Sources</Filter>
     </ClCompile>
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSFrontendDispatchers.cpp">
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorFrontendDispatchers.cpp">
       <Filter>Derived Sources</Filter>
     </ClCompile>
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.cpp">
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorProtocolObjects.cpp">
       <Filter>Derived Sources</Filter>
     </ClCompile>
     <ClCompile Include="..\jit\ArityCheckFailReturnThunks.cpp">
     <ClCompile Include="..\runtime\MemoryStatistics.cpp">
       <Filter>runtime</Filter>
     </ClCompile>
+    <ClCompile Include="..\bytecode\ComplexGetStatus.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\ConstantStructureCheck.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGDoesGC.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGFrozenValue.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGHeapLocation.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGMayExit.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGPureValue.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGStructureAbstractValue.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGStructureRegistrationPhase.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGTransition.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGValueStrength.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\Exception.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\runtime\ExceptionFuzz.cpp">
+      <Filter>runtime</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\StructureSet.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\ToThisStatus.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\CallEdge.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\CallVariant.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGAvailabilityMap.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGBlockSet.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGBlockWorklist.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGInsertOSRHintsForUpdate.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGNaiveDominators.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGObjectAllocationSinkingPhase.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGObjectMaterializationData.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGPhiChildren.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGPrePostNumbering.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGPromotedHeapLocation.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGSSACalculator.cpp">
+      <Filter>dfg</Filter>
+    </ClCompile>
+    <ClCompile Include="..\ftl\FTLExitPropertyValue.cpp">
+      <Filter>ftl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\ftl\FTLExitTimeObjectMaterialization.cpp">
+      <Filter>ftl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\ftl\FTLOperations.cpp">
+      <Filter>ftl</Filter>
+    </ClCompile>
+    <ClCompile Include="..\jit\BinarySwitch.cpp">
+      <Filter>jit</Filter>
+    </ClCompile>
+    <ClCompile Include="..\jit\PolymorphicCallStubRoutine.cpp">
+      <Filter>jit</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\VirtualRegister.cpp">
+      <Filter>bytecode</Filter>
+    </ClCompile>
+    <ClCompile Include="..\jit\SetupVarargsFrame.cpp" />
+    <ClCompile Include="JavaScriptCoreDLL.cpp">
+      <Filter>API</Filter>
+    </ClCompile>
+    <ClCompile Include="..\dfg\DFGPutStackSinkingPhase.cpp" />
+    <ClCompile Include="..\ftl\FTLJSCallBase.cpp" />
+    <ClCompile Include="..\ftl\FTLJSCallVarargs.cpp" />
+    <ClCompile Include="..\runtime\JSCatchScope.cpp" />
+    <ClCompile Include="..\runtime\JSFunctionNameScope.cpp" />
+    <ClCompile Include="..\jit\ExecutableAllocatorFixedVMPool.cpp">
+      <Filter>jit</Filter>
+    </ClCompile>
+    <ClCompile Include="..\bytecode\VariableWriteFireDetail.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsEliminationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsUtilities.cpp" />
+    <ClCompile Include="..\dfg\DFGCleanUpPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGEpoch.cpp" />
+    <ClCompile Include="..\dfg\DFGMovHintRemovalPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGPhantomInsertionPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGVarargsForwardingPhase.cpp" />
+    <ClCompile Include="..\jit\ExecutableAllocationFuzz.cpp" />
+    <ClCompile Include="..\runtime\ClonedArguments.cpp" />
+    <ClCompile Include="..\runtime\ConstantMode.cpp" />
+    <ClCompile Include="..\runtime\DirectArguments.cpp" />
+    <ClCompile Include="..\runtime\DirectArgumentsOffset.cpp" />
+    <ClCompile Include="..\runtime\InferredValue.cpp" />
+    <ClCompile Include="..\runtime\ScopeOffset.cpp" />
+    <ClCompile Include="..\runtime\ScopedArguments.cpp" />
+    <ClCompile Include="..\runtime\ScopedArgumentsTable.cpp" />
+    <ClCompile Include="..\runtime\TypeofType.cpp" />
+    <ClCompile Include="..\runtime\VarOffset.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\API\APICallbackFunction.h">
     <ClInclude Include="..\bytecode\BytecodeBasicBlock.h">
       <Filter>bytecode</Filter>
     </ClInclude>
+    <ClInclude Include="..\bytecode\BytecodeIntrinsicRegistry.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
     <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h">
       <Filter>bytecode</Filter>
     </ClInclude>
     <ClInclude Include="..\bytecode\StructureStubInfo.h">
       <Filter>bytecode</Filter>
     </ClInclude>
+    <ClInclude Include="..\bytecode\TypeLocation.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
     <ClInclude Include="..\bytecode\UnlinkedCodeBlock.h">
       <Filter>bytecode</Filter>
     </ClInclude>
     <ClInclude Include="..\debugger\Debugger.h">
       <Filter>debugger</Filter>
     </ClInclude>
-    <ClInclude Include="..\debugger\DebuggerActivation.h">
+    <ClInclude Include="..\debugger\DebuggerCallFrame.h">
       <Filter>debugger</Filter>
     </ClInclude>
-    <ClInclude Include="..\debugger\DebuggerCallFrame.h">
+    <ClInclude Include="..\debugger\DebuggerEvalEnabler.h">
       <Filter>debugger</Filter>
     </ClInclude>
     <ClInclude Include="..\debugger\DebuggerPrimitives.h">
       <Filter>debugger</Filter>
     </ClInclude>
+    <ClInclude Include="..\debugger\DebuggerScope.h">
+      <Filter>debugger</Filter>
+    </ClInclude>
     <ClInclude Include="..\dfg\DFGDriver.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\disassembler\Disassembler.h">
       <Filter>disassembler</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\BlockAllocator.h">
-      <Filter>heap</Filter>
-    </ClInclude>
     <ClInclude Include="..\heap\ConservativeRoots.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\Heap.h">
       <Filter>heap</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\HeapBlock.h">
-      <Filter>heap</Filter>
-    </ClInclude>
     <ClInclude Include="..\heap\HeapInlines.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\HeapTimer.h">
       <Filter>heap</Filter>
     </ClInclude>
+    <ClInclude Include="..\heap\HeapVerifier.h">
+      <Filter>heap</Filter>
+    </ClInclude>
     <ClInclude Include="..\heap\IncrementalSweeper.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\RecursiveAllocationScope.h">
       <Filter>heap</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\Region.h">
-      <Filter>heap</Filter>
-    </ClInclude>
     <ClInclude Include="..\heap\SlotVisitor.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\StrongInlines.h">
       <Filter>heap</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\SuperRegion.h">
-      <Filter>heap</Filter>
-    </ClInclude>
     <ClInclude Include="..\heap\TinyBloomFilter.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\inspector\InspectorFrontendChannel.h">
       <Filter>inspector</Filter>
     </ClInclude>
-    <ClInclude Include="..\inspector\InspectorTypeBuilder.h">
-      <Filter>inspector</Filter>
-    </ClInclude>
     <ClInclude Include="..\inspector\InspectorValues.h">
       <Filter>inspector</Filter>
     </ClInclude>
     <ClInclude Include="..\inspector\agents\InspectorDebuggerAgent.h">
       <Filter>inspector</Filter>
     </ClInclude>
-    <ClInclude Include="..\inspector\agents\InspectorProfilerAgent.h">
-      <Filter>inspector</Filter>
-    </ClInclude>
     <ClInclude Include="..\inspector\agents\InspectorRuntimeAgent.h">
       <Filter>inspector</Filter>
     </ClInclude>
     <ClInclude Include="..\interpreter\CallFrameClosure.h">
       <Filter>interpreter</Filter>
     </ClInclude>
+    <ClInclude Include="..\interpreter\VMEntryRecord.h">
+      <Filter>interpreter</Filter>
+    </ClInclude>
     <ClInclude Include="..\interpreter\Interpreter.h">
       <Filter>interpreter</Filter>
     </ClInclude>
     <ClInclude Include="..\interpreter\StackVisitor.h">
       <Filter>interpreter</Filter>
     </ClInclude>
-    <ClInclude Include="..\interpreter\VMInspector.h">
-      <Filter>interpreter</Filter>
-    </ClInclude>
-    <ClInclude Include="..\jit\ClosureCallStubRoutine.h">
-      <Filter>jit</Filter>
-    </ClInclude>
     <ClInclude Include="..\jit\CompactJITCodeMap.h">
       <Filter>jit</Filter>
     </ClInclude>
     <ClInclude Include="..\parser\NodeConstructors.h">
       <Filter>parser</Filter>
     </ClInclude>
-    <ClInclude Include="..\parser\NodeInfo.h">
-      <Filter>parser</Filter>
-    </ClInclude>
     <ClInclude Include="..\parser\Nodes.h">
       <Filter>parser</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\ArgList.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\Arguments.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\ArrayConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\ArrayStorage.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\BasicBlockLocation.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\BatchedTransitionOptimizer.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\ConstructData.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\ControlFlowProfiler.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\CustomGetterSetter.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\DatePrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\EnumerationMode.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\Error.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\FunctionConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\FunctionHasExecutedCache.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\FunctionPrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\FunctionRareData.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\GetterSetter.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\InternalFunction.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\IntlObject.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\Intrinsic.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSActivation.h">
+    <ClInclude Include="..\runtime\IterationStatus.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\IteratorOperations.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\IteratorPrototype.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\JSLexicalEnvironment.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSAPIValueWrapper.h">
     <ClInclude Include="..\runtime\JSBoundFunction.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\JSCallee.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\JSCell.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\JSJob.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\JSLock.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSONObject.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSPropertyNameIterator.h">
+    <ClInclude Include="..\runtime\JSPropertyNameEnumerator.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSProxy.h">
     <ClInclude Include="..\runtime\JSStringBuilder.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\JSStringIterator.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\JSStringJoiner.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSSymbolTableObject.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\JSTemplateRegistryKey.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\JSType.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSTypeInfo.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSVariableObject.h">
+    <ClInclude Include="..\runtime\JSEnvironmentRecord.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSWithScope.h">
     <ClInclude Include="..\runtime\MathObject.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\NameConstructor.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
-    <ClInclude Include="..\runtime\NameInstance.h">
+    <ClInclude Include="..\runtime\NativeErrorConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\NamePrototype.h">
+    <ClInclude Include="..\runtime\NativeErrorPrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\NativeErrorConstructor.h">
+    <ClInclude Include="..\runtime\NullGetterFunction.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\NativeErrorPrototype.h">
+    <ClInclude Include="..\runtime\NullSetterFunction.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\NumberConstructor.h">
     <ClInclude Include="..\runtime\Reject.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\RuntimeFlags.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\RuntimeType.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\SamplingCounter.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\StringConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\StringIteratorPrototype.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\StringObject.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\StructureTransitionTable.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\Symbol.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\SymbolConstructor.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\SymbolObject.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\SymbolPrototype.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\SymbolTable.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\TemplateRegistry.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\TemplateRegistryKey.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\Tracing.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\TypeLocationCache.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\TypeProfiler.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\TypeProfilerLog.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\TypeSet.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\Uint16WithFraction.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\tools\CodeProfiling.h">
       <Filter>tools</Filter>
     </ClInclude>
+    <ClInclude Include="..\tools\FunctionOverrides.h">
+      <Filter>tools</Filter>
+    </ClInclude>
+    <ClInclude Include="..\tools\JSDollarVM.h">
+      <Filter>tools</Filter>
+    </ClInclude>
+    <ClInclude Include="..\tools\JSDollarVMPrototype.h">
+      <Filter>tools</Filter>
+    </ClInclude>
     <ClInclude Include="..\tools\ProfileTreeNode.h">
       <Filter>tools</Filter>
     </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\HeaderDetection.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSBackendDispatchers.h">
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorBackendDispatchers.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSFrontendDispatchers.h">
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorFrontendDispatchers.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.h">
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorProtocolObjects.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSGlobalObject.lut.h">
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\StringConstructor.lut.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayIteratorPrototype.lut.h">
+      <Filter>Derived Sources</Filter>
+    </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\VMEntryScope.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\assembler\MacroAssemblerX86Common.cpp">
-      <Filter>assembler</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\IntendedStructureChain.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSPromiseDeferred.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSPromiseFunctions.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
-    <ClInclude Include="..\runtime\JSPromiseReaction.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\JSPromisePrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\KeywordLookup.lut.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpObject.lut.h">
-      <Filter>Derived Sources</Filter>
-    </ClInclude>
-    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\NamePrototype.lut.h">
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\SymbolPrototype.lut.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\CodeBlockSet.h">
     <ClInclude Include="..\bytecode\DeferredCompilationCallback.h">
       <Filter>bytecode</Filter>
     </ClInclude>
+    <ClInclude Include="..\bytecode\DeferredSourceDump.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
     <ClInclude Include="..\dfg\DFGCompilationKey.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\MapData.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\MapDataInlines.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\SetPrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\SetConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\SetIteratorConstructor.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGAbstractHeap.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\dfg\DFGArgumentPosition.h">
       <Filter>dfg</Filter>
     </ClInclude>
-    <ClInclude Include="..\dfg\DFGArgumentsSimplificationPhase.h">
-      <Filter>dfg</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\dfg\DFGBasicBlockInlines.h">
       <Filter>dfg</Filter>
     </ClInclude>
-    <ClInclude Include="..\dfg\DFGBinarySwitch.h">
-      <Filter>dfg</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGBlockInsertionSet.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\dfg\DFGDesiredIdentifiers.h">
       <Filter>dfg</Filter>
     </ClInclude>
-    <ClInclude Include="..\dfg\DFGDesiredStructureChains.h">
-      <Filter>dfg</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGDesiredTransitions.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\dfg\DFGLazyJSValue.h">
       <Filter>dfg</Filter>
     </ClInclude>
+    <ClInclude Include="..\dfg\DFGLazyNode.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
     <ClInclude Include="..\dfg\DFGLICMPhase.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\dfg\DFGValidate.h">
       <Filter>dfg</Filter>
     </ClInclude>
-    <ClInclude Include="..\dfg\DFGValueRecoveryOverride.h">
-      <Filter>dfg</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGValueSource.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\ArrayIteratorPrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\ArrayIteratorConstructor.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\MapIteratorPrototype.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\MapIteratorConstructor.h">
-      <Filter>runtime</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\Microtask.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\WeakMapConstructor.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\runtime\WeakSetConstructor.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\WeakSetPrototype.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\JSWeakMap.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSArrayIterator.h">
+    <ClInclude Include="..\runtime\JSWeakSet.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\runtime\JSArgumentsIterator.h">
+    <ClInclude Include="..\runtime\JSArrayIterator.h">
       <Filter>runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\JSMapIterator.h">
     <ClInclude Include="..\jit\JITInlineCacheGenerator.h">
       <Filter>jit</Filter>
     </ClInclude>
-    <ClInclude Include="..\dfg\DFGResurrectionForValidationPhase.h">
-      <Filter>dfg</Filter>
-    </ClInclude>
     <ClInclude Include="..\dfg\DFGAvailability.h">
       <Filter>dfg</Filter>
     </ClInclude>
     <ClInclude Include="..\bytecode\CodeBlockJettisoningWatchpoint.h">
       <Filter>bytecode</Filter>
     </ClInclude>
-    <ClInclude Include="..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.h">
-      <Filter>bytecode</Filter>
-    </ClInclude>
     <ClInclude Include="..\runtime\StackAlignment.h">
       <Filter>runtime</Filter>
     </ClInclude>
-    <ClInclude Include="..\heap\DelayedReleaseScope.h">
-      <Filter>heap</Filter>
-    </ClInclude>
-    <ClInclude Include="..\bytecode\VariableWatchpointSet.h">
-      <Filter>bytecode</Filter>
-    </ClInclude>
     <ClInclude Include="..\bindings\ScriptFunctionCall.h">
       <Filter>bindings</Filter>
     </ClInclude>
     <ClInclude Include="..\runtime\MemoryStatistics.h">
       <Filter>runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\bytecode\ComplexGetStatus.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
+    <ClInclude Include="..\bytecode\ConstantStructureCheck.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGDoesGC.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGFrozenValue.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGHeapLocation.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGMayExit.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPureValue.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGStructureClobberState.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGStructureRegistrationPhase.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGTransition.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGValueStrength.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\Exception.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\runtime\ExceptionFuzz.h">
+      <Filter>runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\bytecode\ToThisStatus.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
+    <ClInclude Include="..\bytecode\CallVariant.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
+    <ClInclude Include="..\bytecode\CallEdge.h">
+      <Filter>bytecode</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGAvailabilityMap.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGBlockMap.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGBlockMapInlines.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGBlockSet.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGSSACalculator.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGBlockSetInlines.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGBlockWorklist.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGInsertOSRHintsForUpdate.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGNaiveDominators.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGObjectAllocationSinkingPhase.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGObjectMaterializationData.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPhiChildren.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPrePostNumbering.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPromotedHeapLocation.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPromoteHeapAccess.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\ftl\FTLExitPropertyValue.h">
+      <Filter>ftl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\ftl\FTLExitTimeObjectMaterialization.h">
+      <Filter>ftl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\ftl\FTLOperations.h">
+      <Filter>ftl</Filter>
+    </ClInclude>
+    <ClInclude Include="..\jit\BinarySwitch.h">
+      <Filter>jit</Filter>
+    </ClInclude>
+    <ClInclude Include="..\dfg\DFGPreciseLocalClobberize.h">
+      <Filter>dfg</Filter>
+    </ClInclude>
+    <ClInclude Include="..\jit\PolymorphicCallStubRoutine.h">
+      <Filter>jit</Filter>
+    </ClInclude>
+    <ClInclude Include="..\jit\SetupVarargsFrame.h" />
+    <ClInclude Include="..\dfg\DFGPutStackSinkingPhase.h" />
+    <ClInclude Include="..\ftl\FTLJSCallBase.h" />
+    <ClInclude Include="..\ftl\FTLJSCallVarargs.h" />
+    <ClInclude Include="..\runtime\JSCatchScope.h" />
+    <ClInclude Include="..\runtime\JSFunctionNameScope.h" />
+    <ClInclude Include="..\runtime\MathCommon.h" />
+    <ClInclude Include="..\bytecode\BytecodeKills.h" />
+    <ClInclude Include="..\bytecode\VariableWriteFireDetail.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsEliminationPhase.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsUtilities.h" />
+    <ClInclude Include="..\dfg\DFGCallCreateDirectArgumentsSlowPathGenerator.h" />
+    <ClInclude Include="..\dfg\DFGCleanUpPhase.h" />
+    <ClInclude Include="..\dfg\DFGEpoch.h" />
+    <ClInclude Include="..\dfg\DFGForAllKills.h" />
+    <ClInclude Include="..\dfg\DFGMovHintRemovalPhase.h" />
+    <ClInclude Include="..\dfg\DFGPhantomInsertionPhase.h" />
+    <ClInclude Include="..\dfg\DFGVarargsForwardingPhase.h" />
+    <ClInclude Include="..\jit\ExecutableAllocationFuzz.h" />
+    <ClInclude Include="..\runtime\ArgumentsMode.h" />
+    <ClInclude Include="..\runtime\ClonedArguments.h" />
+    <ClInclude Include="..\runtime\DirectArguments.h" />
+    <ClInclude Include="..\runtime\DirectArgumentsOffset.h" />
+    <ClInclude Include="..\runtime\GenericArguments.h" />
+    <ClInclude Include="..\runtime\GenericArgumentsInlines.h" />
+    <ClInclude Include="..\runtime\GenericOffset.h" />
+    <ClInclude Include="..\runtime\InferredValue.h" />
+    <ClInclude Include="..\runtime\ScopeOffset.h" />
+    <ClInclude Include="..\runtime\ScopedArguments.h" />
+    <ClInclude Include="..\runtime\ScopedArgumentsTable.h" />
+    <ClInclude Include="..\runtime\TypeofType.h" />
+    <ClInclude Include="..\runtime\VarOffset.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="JavaScriptCorePreLink.cmd" />
     <None Include="..\bytecode\BytecodeList.json">
       <Filter>bytecode</Filter>
     </None>
+    <None Include="..\inspector\scripts\cssmin.py">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\generate-combined-inspector-json.py">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\generate-inspector-protocol-bindings.py">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\inline-and-minify-stylesheets-and-scripts.py">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\jsmin.py">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\xxd.pl">
+      <Filter>inspector\scripts</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\__init__.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\cpp_generator.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\cpp_generator_templates.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_backend_dispatcher_header.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_backend_dispatcher_implementation.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_frontend_dispatcher_header.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_frontend_dispatcher_implementation.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_protocol_types_header.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_cpp_protocol_types_implementation.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generate_js_backend_commands.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generator.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\generator_templates.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\codegen\models.py">
+      <Filter>inspector\scripts\codegen</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\commands-with-async-attribute.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\commands-with-optional-call-return-parameters.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\domains-with-varying-command-sizes.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\events-with-optional-parameters.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-duplicate-type-declarations.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-enum-with-no-values.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-string-typed-optional-parameter-flag.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-string-typed-optional-type-member.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-type-declaration-using-type-reference.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-type-with-lowercase-name.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-unknown-type-reference-in-type-declaration.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\fail-on-unknown-type-reference-in-type-member.json-error">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\same-type-id-different-domain.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\shadowed-optional-type-setters.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-aliased-primitive-type.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-array-type.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-enum-type.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\type-declaration-object-type.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\expected\type-requiring-runtime-casts.json-result">
+      <Filter>inspector\scripts\tests\expected</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\commands-with-async-attribute.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\commands-with-optional-call-return-parameters.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\domains-with-varying-command-sizes.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\events-with-optional-parameters.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-duplicate-type-declarations.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-enum-with-no-values.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-string-typed-optional-parameter-flag.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-string-typed-optional-type-member.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-type-declaration-using-type-reference.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-type-with-lowercase-name.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-unknown-type-reference-in-type-declaration.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\fail-on-unknown-type-reference-in-type-member.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\same-type-id-different-domain.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\shadowed-optional-type-setters.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\type-declaration-aliased-primitive-type.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\type-declaration-array-type.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\type-declaration-enum-type.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\type-declaration-object-type.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
+    <None Include="..\inspector\scripts\tests\type-requiring-runtime-casts.json">
+      <Filter>inspector\scripts\tests</Filter>
+    </None>
   </ItemGroup>
   <ItemGroup>
     <MASM Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\LowLevelInterpreterWin.asm">
       <Filter>jit</Filter>
     </MASM>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 9b00e4f34eb5efa8595b0af912277d5efa6354e9..6954c3daa4a48c7b5d27380beeabaffae01413ee 100644 (file)
@@ -5,8 +5,10 @@
   <PropertyGroup />
   <ItemDefinitionGroup>
     <ClCompile>
+      <DisableSpecificWarnings>4611;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <AdditionalIncludeDirectories>..\;..\tools\;..\runtime\;..\llint\;..\jit\;..\disassembler\;..\heap\;..\debugger\;..\assembler\;..\profiler\;..\yarr\;..\interpreter\;..\bytecode\;..\builtins\;..\dfg\;..\bytecompiler\;..\parser\;..\API\;..\ftl\;..\bindings\;..\inspector\;..\ftl;..\llvm;..\llvm\library;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\JavaScriptCore\DerivedSources\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\include\private\;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+      <DisableSpecificWarnings>4611;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <Link>
       <AdditionalDependencies>winmm.lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;WTF$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -16,4 +18,4 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup />
-</Project>
\ No newline at end of file
+</Project>
diff --git a/JavaScriptCore.vcxproj/JavaScriptCoreDLL.cpp b/JavaScriptCore.vcxproj/JavaScriptCoreDLL.cpp
new file mode 100644 (file)
index 0000000..779e1b8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* Copyright (C) 2015 Apple Inc.  All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <Windows.h>
+#include <math.h>
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    switch (fdwReason) {
+    case DLL_PROCESS_ATTACH:
+#if defined(_M_X64) || defined(__x86_64__)
+        // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+        // if the feature has been disabled in firmware. This causes us to crash
+        // in some of the math functions. For now, we disable those optimizations
+        // because Microsoft is not going to fix the problem in VS2013.
+        // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+        _set_FMA3_enable(0);
+#endif
+        break;
+
+    case DLL_PROCESS_DETACH:
+    case DLL_THREAD_ATTACH:
+    case DLL_THREAD_DETACH:
+        break;
+    }
+
+    return TRUE;
+}
index 78a514eb09f143018eb86c6b3cbbd0d8c6452d7a..8868e40afca192846d5151cda7b03d0e2bc4dd35 100644 (file)
@@ -1,12 +1,12 @@
 all:
-    touch "%ConfigurationBuildDir%\buildfailed"
-    perl build-generated-files.pl "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)" "%PlatformArchitecture%"
-    copy-files.cmd
+    @type NUL > "%ConfigurationBuildDir%\buildfailed"
+    @perl build-generated-files.pl "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)" "%PlatformArchitecture%"
+    @copy-files.cmd
 
-    -del "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdbool.h" "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdint.h"
-    -del "%ConfigurationBuildDir%\buildfailed"
+    -@del "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdbool.h" "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdint.h" >nul 2>nul
+    -@del "%ConfigurationBuildDir%\buildfailed"
 
 clean:
-    -del "%ConfigurationBuildDir%\buildfailed"
+    -@del "%ConfigurationBuildDir%\buildfailed"
     copy-files.cmd clean
-    -del /s /q "%ConfigurationBuildDir%\obj%PlatformArchitecture%\JavaScriptCore\DerivedSources"
+    -@del /s /q "%ConfigurationBuildDir%\obj%PlatformArchitecture%\JavaScriptCore\DerivedSources"
index 3275c40cb810dc55a70dd8141652cf7fabc64ac1..c03de34d988b0acd4a3a6697aa90f94f85a398d1 100644 (file)
@@ -64,7 +64,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 8b0a3a4586bbe3f46197385b9bdb3e9e6c935a34..b4d17c7a0fdd6d62f2a00ac4af32dc2d9dee72b9 100644 (file)
@@ -1,2 +1,2 @@
-if exist "%WEBKIT_LIBRARIES%\tools\VersionStamper\VersionStamper.exe" "%WEBKIT_LIBRARIES%\tools\VersionStamper\VersionStamper.exe" --verbose "%TARGETPATH%"
+perl "%WEBKIT_LIBRARIES%\tools\scripts\version-stamp.pl" "%INTDIR%" "%TARGETPATH%"
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
index 72ab16a0e5f79fc7697549b8af616b811736e165..b8cf878b3d33f953bf0965e740b01c2ffa75177e 100644 (file)
@@ -1,6 +1,8 @@
-%SystemDrive%\cygwin\bin\which.exe perl
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
 if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
 cmd /c
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
 if errorlevel 1 exit 1
 echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
+
+perl "%WEBKIT_LIBRARIES%\tools\scripts\auto-version.pl" "%INTDIR%"
index 5aff3ba4493c83918ffe8e4dd3dd7664d3d4bb0f..6da9beba1f3b6d5f644700ff00793f08c231caac 100644 (file)
@@ -1,5 +1,5 @@
 all:
-    touch "%ConfigurationBuildDir%\buildfailed"
+    @type NUL > "%ConfigurationBuildDir%\buildfailed"
     perl build-LLIntAssembly.pl "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)" "$(DEBUGSUFFIX)" "%PlatformArchitecture%"
     -del "%ConfigurationBuildDir%\buildfailed"
 
index 3f705e0fa683ee4212d35d1639c790b7582ffffc..9b0f13aa9aa157f80fb12c5d36d1a5fceb6742ea 100644 (file)
@@ -58,7 +58,7 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -74,7 +74,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -82,7 +82,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -98,7 +98,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -280,4 +280,4 @@ nmake /nologo -f $(ProjectName).make DEBUGSUFFIX=_debug</NMakeReBuildCommandLine
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 7afe7488f0dc72b714f08204711d5982362a75ec..6f43c957e29bd87a06c8fffd15791819193b3735 100644 (file)
@@ -67,4 +67,4 @@ my $OUTPUTFILENAME = File::Spec->catfile($DERIVED_SOURCES_DIR, 'LowLevelInterpre
 my $offlineAsm = File::Spec->catfile($XSRCROOT, 'offlineasm', 'asm.rb');
 my $lowLevelInterpreter = File::Spec->catfile($XSRCROOT, 'llint', 'LowLevelInterpreter.asm');
 my $offsetsExtractor = File::Spec->catfile($BUILD_PRODUCTS_DIR, 'LLIntOffsetsExtractor', "LLIntOffsetsExtractor$ARGV[2].exe");
-system('/usr/bin/env', 'ruby', $offlineAsm, '-I.', $lowLevelInterpreter, $offsetsExtractor, $OUTPUTFILENAME) and die "Failed to generate $OUTPUTFILENAME: $!";
+system('ruby', $offlineAsm, '-I.', $lowLevelInterpreter, $offsetsExtractor, $OUTPUTFILENAME) and die "Failed to generate $OUTPUTFILENAME: $!";
index e6bdb859e06d236163f3132754efca5178dfaec2..b2447b04cc8fa31a6a706115906cfb9acee0db14 100644 (file)
@@ -1,5 +1,5 @@
 all:
-    touch "%ConfigurationBuildDir%\buildfailed"
+    @type NUL > "%ConfigurationBuildDir%\buildfailed"
     perl build-LLIntDesiredOffsets.pl "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)" "%PlatformArchitecture%"
 
     -del "%ConfigurationBuildDir%\buildfailed"
index 16f783fab205226cc4295750bee1b7e7e63bb338..b7796b4ed21b0f4b564e453a21ca1793fa26c2cf 100644 (file)
@@ -58,7 +58,7 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -74,7 +74,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -82,7 +82,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
@@ -98,7 +98,7 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
     <ConfigurationType>Makefile</ConfigurationType>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 84cb43874c23bbded6857c61d59cbe9280bb781c..c6f5efcb2b199e9f74d59d5f36199d5f1e188ac9 100644 (file)
@@ -55,4 +55,4 @@ unless (-d $BUILD_PRODUCTS_DIR) {
 my $generateOffsetExtractor = File::Spec->catfile($XSRCROOT, 'offlineasm', 'generate_offset_extractor.rb');
 my $lowLevelInterpreter = File::Spec->catfile($XSRCROOT, 'llint', 'LowLevelInterpreter.asm');
 my $OUTPUTFILENAME = File::Spec->catfile($BUILD_PRODUCTS_DIR, 'LLIntDesiredOffsets.h');
-system('/usr/bin/env', 'ruby', $generateOffsetExtractor, "-I$BUILD_PRODUCTS_DIR", $lowLevelInterpreter, $OUTPUTFILENAME) and die "Failed to generate $OUTPUTFILENAME: $!";
+system('ruby', $generateOffsetExtractor, "-I$BUILD_PRODUCTS_DIR", $lowLevelInterpreter, $OUTPUTFILENAME) and die "Failed to generate $OUTPUTFILENAME: $!";
index bf1b1a32f2bc8020ea374a9f7194d236a327642e..2a242787387176d1c6fa33227e436baf346d8ab9 100644 (file)
@@ -61,7 +61,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
@@ -81,7 +81,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
index 7bd1316a69460a3795b9bb0608453a6414b6aff0..2415c1fb44d8cd8fcef622dca49ec6332c11a603 100755 (executable)
@@ -49,10 +49,10 @@ for (@ARGV) {
     s/\"$//;
 }
 
-my $XDSTROOT = $ARGV[0];
+my $XDSTROOT = Cwd::realpath($ARGV[0]);
 $ENV{'XDSTROOT'} = $XDSTROOT;
 
-my $SDKROOT = $ARGV[1];
+my $SDKROOT = Cwd::realpath($ARGV[1]);
 $ENV{'SDKROOT'} = $SDKROOT;
 
 my $BUILD_PRODUCTS_DIR = File::Spec->catdir($XDSTROOT, "obj$ARGV[2]", 'JavaScriptCore');
@@ -65,9 +65,13 @@ unless (-d $DERIVED_SOURCES_DIR) {
 
 chdir $DERIVED_SOURCES_DIR or die "Couldn't change directory to $DERIVED_SOURCES_DIR: $!";
 
+my $featureDefinesCommand = File::Spec->catfile($SDKROOT, 'tools', 'scripts', 'feature-defines.pl');
+my $featureDefines = `$featureDefinesCommand $SDKROOT windows`;
+chomp($featureDefines);
+$ENV{'FEATURE_DEFINES'} = $featureDefines;
+
 $ENV{'JavaScriptCore'} = $XSRCROOT;
 $ENV{'DFTABLES_EXTENSION'} = '.exe';
 
 my $DERIVED_SOURCES_MAKEFILE = File::Spec->catfile($XSRCROOT, 'DerivedSources.make');
-
-system('/usr/bin/make', '-f', $DERIVED_SOURCES_MAKEFILE, '-j', $NUMCPUS) and die "Failed to build $DERIVED_SOURCES_MAKEFILE: $!";
+system('make', '-f', $DERIVED_SOURCES_MAKEFILE, '-j', $NUMCPUS) and die "Failed to build $DERIVED_SOURCES_MAKEFILE: $!";
index 535e27b3a19e0676e114d654020dc6cbdca42356..a245c3ea08c5e73e2c1710d5423bcc1887955612 100755 (executable)
@@ -9,7 +9,7 @@ if "%1" EQU "clean" goto :clean
 if "%1" EQU "rebuild" call :clean\r
 \r
 echo Copying public headers...\r
-mkdir "%PublicHeadersDirectory%" 2>NUL\r
+@mkdir "%PublicHeadersDirectory%" 2>NUL\r
 for %%f in (\r
     APICast.h\r
     APIShims.h\r
@@ -33,7 +33,7 @@ for %%f in (
     OpaqueJSString.h\r
     WebKitAvailability.h\r
 ) do (\r
-    xcopy /y /d ..\API\%%f "%PublicHeadersDirectory%" >NUL\r
+    @xcopy /y /d ..\API\%%f "%PublicHeadersDirectory%" >NUL\r
 )\r
 \r
 echo Copying private headers...\r
@@ -58,45 +58,50 @@ for %%d in (
     runtime\r
     yarr\r
 ) do (\r
-    xcopy /y /d ..\%%d\*.h "%PrivateHeadersDirectory%" >NUL\r
+    @xcopy /y /d ..\%%d\*.h "%PrivateHeadersDirectory%" >NUL\r
 )\r
 \r
 echo Copying Inspector scripts as if they were private headers...\r
 for %%d in (\r
     inspector\scripts\r
+       inspector\scripts\codegen\r
 ) do (\r
-    xcopy /y /d ..\%%d\* "%PrivateHeadersDirectory%" >NUL\r
+    @xcopy /y /d ..\%%d\* "%PrivateHeadersDirectory%" >NUL\r
 )\r
 \r
 echo Copying Inspector generated files as if they were private headers...\r
-xcopy /y "%DerivedSourcesDirectory%\InspectorJS.json" "%PrivateHeadersDirectory%" >NUL\r
-xcopy /y "%DerivedSourcesDirectory%\InspectorJSTypeBuilders.h" "%PrivateHeadersDirectory%" >NUL\r
-xcopy /y "%DerivedSourcesDirectory%\InspectorJSBackendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
-xcopy /y "%DerivedSourcesDirectory%\InspectorJSFrontendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\CombinedDomains.json" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\InspectorProtocolObjects.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\InspectorBackendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\InspectorFrontendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\InspectorBackendCommands.js" "%PrivateHeadersDirectory%" >NUL\r
 \r
 echo Copying Web Replay scripts as if they were private headers...\r
 for %%d in (\r
     replay\scripts\r
 ) do (\r
-    xcopy /y /d ..\%%d\* "%PrivateHeadersDirectory%" >NUL\r
+    @xcopy /y /d ..\%%d\* "%PrivateHeadersDirectory%" >NUL\r
 )\r
 \r
 echo Copying Web Replay generated headers as if they were private headers...\r
-xcopy /y "%DerivedSourcesDirectory%\JSReplayInputs.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\JSReplayInputs.h" "%PrivateHeadersDirectory%" >NUL\r
+\r
+echo Copying Web Replay specification files as if they were private headers...\r
+@xcopy /y /d ..\replay\*.json "%PrivateHeadersDirectory%" >NUL\r
 \r
 echo Copying builtins header as if it were a private header...\r
-xcopy /y "%DerivedSourcesDirectory%\JSCBuiltins.h" "%PrivateHeadersDirectory%" >NUL\r
-xcopy /y "%DerivedSourcesDirectory%\Bytecodes.h" "%PrivateHeadersDirectory%" >NUL
+@xcopy /y "%DerivedSourcesDirectory%\JSCBuiltins.h" "%PrivateHeadersDirectory%" >NUL\r
+@xcopy /y "%DerivedSourcesDirectory%\Bytecodes.h" "%PrivateHeadersDirectory%" >NUL\r
 \r
 echo Copying resources...\r
-mkdir "%ResourcesDirectory%" 2>NUL\r
-xcopy /y /d JavaScriptCore.resources\* "%ResourcesDirectory%" >NUL\r
+@mkdir "%ResourcesDirectory%" 2>NUL\r
+@xcopy /y /d JavaScriptCore.resources\* "%ResourcesDirectory%" >NUL\r
 \r
 goto :EOF\r
 \r
 :clean\r
 \r
 echo Deleting copied files...\r
-if exist "%PublicHeadersDirectory%" rmdir /s /q "%PublicHeadersDirectory%" >NUL\r
-if exist "%PrivateHeadersDirectory%" rmdir /s /q "%PrivateHeadersDirectory%" >NUL\r
-if exist "%ResourcesDirectory%" rmdir /s /q "%ResourcesDirectory%" >NUL\r
+@if exist "%PublicHeadersDirectory%" rmdir /s /q "%PublicHeadersDirectory%" >NUL 2>NUL\r
+@if exist "%PrivateHeadersDirectory%" rmdir /s /q "%PrivateHeadersDirectory%" >NUL 2>NUL\r
+@if exist "%ResourcesDirectory%" rmdir /s /q "%ResourcesDirectory%" >NUL 2>NUL\r
diff --git a/JavaScriptCore.vcxproj/jsc/DLLLauncherMain.cpp b/JavaScriptCore.vcxproj/jsc/DLLLauncherMain.cpp
new file mode 100644 (file)
index 0000000..e2359a2
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This file contains code for a launcher executable for WebKit apps. When compiled into foo.exe, it
+// will set PATH so that Apple Application Support DLLs can be found, then will load foo.dll and
+// call its dllLauncherEntryPoint function, which should be declared like so:
+//     extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstCmdLine, int nCmdShow);
+// If USE_CONSOLE_ENTRY_POINT is defined, this function will be called instead:
+//     extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[]);
+
+#include <shlwapi.h>
+#include <string>
+#include <vector>
+#include <windows.h>
+
+using namespace std;
+
+#if defined _M_IX86
+#define PROCESSORARCHITECTURE "x86"
+#elif defined _M_IA64
+#define PROCESSORARCHITECTURE "ia64"
+#elif defined _M_X64
+#define PROCESSORARCHITECTURE "amd64"
+#else
+#define PROCESSORARCHITECTURE "*"
+#endif
+
+#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='" PROCESSORARCHITECTURE "' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#if defined(_MSC_VER) && (_MSC_VER >= 1600) && !defined(WIN_CAIRO)
+#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.6195' processorArchitecture='" PROCESSORARCHITECTURE "' publicKeyToken='1fc8b3b9a1e18e3b' language='*'\"")
+#endif
+
+static void enableTerminationOnHeapCorruption()
+{
+    // Enable termination on heap corruption on OSes that support it (Vista and XPSP3).
+    // http://msdn.microsoft.com/en-us/library/aa366705(VS.85).aspx
+
+    HEAP_INFORMATION_CLASS heapEnableTerminationOnCorruption = static_cast<HEAP_INFORMATION_CLASS>(1);
+
+    HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
+    if (!module)
+        return;
+
+    typedef BOOL (WINAPI*HSI)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
+    HSI heapSetInformation = reinterpret_cast<HSI>(::GetProcAddress(module, "HeapSetInformation"));
+    if (!heapSetInformation)
+        return;
+
+    heapSetInformation(0, heapEnableTerminationOnCorruption, 0, 0);
+}
+
+static wstring getStringValue(HKEY key, const wstring& valueName)
+{
+    DWORD type = 0;
+    DWORD bufferSize = 0;
+    if (::RegQueryValueExW(key, valueName.c_str(), 0, &type, 0, &bufferSize) != ERROR_SUCCESS || type != REG_SZ)
+        return wstring();
+
+    vector<wchar_t> buffer(bufferSize / sizeof(wchar_t));
+    if (::RegQueryValueExW(key, valueName.c_str(), 0, &type, reinterpret_cast<LPBYTE>(&buffer[0]), &bufferSize) != ERROR_SUCCESS)
+        return wstring();
+
+    return &buffer[0];
+}
+
+static wstring applePathFromRegistry(const wstring& key, const wstring& value)
+{
+    HKEY applePathKey = 0;
+    if (::RegOpenKeyExW(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ, &applePathKey) != ERROR_SUCCESS)
+        return wstring();
+    wstring path = getStringValue(applePathKey, value);
+    ::RegCloseKey(applePathKey);
+    return path;
+}
+
+static wstring appleApplicationSupportDirectory()
+{
+    return applePathFromRegistry(L"SOFTWARE\\Apple Inc.\\Apple Application Support", L"InstallDir");
+}
+
+static wstring copyEnvironmentVariable(const wstring& variable)
+{
+    DWORD length = ::GetEnvironmentVariableW(variable.c_str(), 0, 0);
+    if (!length)
+        return wstring();
+    vector<wchar_t> buffer(length);
+    if (!GetEnvironmentVariable(variable.c_str(), &buffer[0], buffer.size()) || !buffer[0])
+        return wstring();
+    return &buffer[0];
+}
+
+static bool prependPath(const wstring& directoryToPrepend)
+{
+    wstring pathVariable = L"PATH";
+    wstring oldPath = copyEnvironmentVariable(pathVariable);
+    wstring newPath = directoryToPrepend + L';' + oldPath;
+    return ::SetEnvironmentVariableW(pathVariable.c_str(), newPath.c_str());
+}
+
+static int fatalError(const wstring& programName, const wstring& message)
+{
+    wstring caption = programName + L" can't open.";
+    ::MessageBoxW(0, message.c_str(), caption.c_str(), MB_ICONERROR);
+    return 1;
+}
+
+static bool directoryExists(const wstring& path)
+{
+    DWORD attrib = ::GetFileAttributes(path.c_str());
+
+    return ((attrib != INVALID_FILE_ATTRIBUTES) && (attrib & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+static bool modifyPath(const wstring& programName)
+{
+#ifdef WIN_CAIRO
+
+#if defined(_M_X64)
+    wstring pathWinCairo = copyEnvironmentVariable(L"WEBKIT_LIBRARIES") + L"\\bin64";
+#else
+    wstring pathWinCairo = copyEnvironmentVariable(L"WEBKIT_LIBRARIES") + L"\\bin32";
+#endif
+    prependPath(pathWinCairo);
+    return true;
+
+#else
+
+    const wstring& pathPrefix = appleApplicationSupportDirectory();
+
+    if (!directoryExists(pathPrefix)) {
+        fatalError(programName, L"Failed to determine path to AAS directory.");
+        return false;
+    }
+
+    if (prependPath(pathPrefix))
+        return true;
+
+    fatalError(programName, L"Failed to modify PATH environment variable.");
+    return false;
+#endif
+}
+
+static wstring getLastErrorString(HRESULT hr)
+{
+    static const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
+    static const size_t bufSize = 4096;
+
+    wchar_t errorMessage[bufSize];
+    DWORD len = ::FormatMessageW(kFlags, 0, hr, 0, errorMessage, bufSize, 0);
+    if (len >= bufSize)
+        len = bufSize - 1;
+
+    errorMessage[len] = 0;
+
+    return errorMessage;
+}
+
+#if USE_CONSOLE_ENTRY_POINT
+int main(int argc, const char* argv[])
+#else
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpstrCmdLine, int nCmdShow)
+#endif
+{
+#if defined(_M_X64) || defined(__x86_64__)
+    // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+    // if the feature has been disabled in firmware. This causes us to crash
+    // in some of the math functions. For now, we disable those optimizations
+    // because Microsoft is not going to fix the problem in VS2013.
+    // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+    _set_FMA3_enable(0);
+#endif
+
+    enableTerminationOnHeapCorruption();
+
+    // Get the path of our executable.
+    wchar_t exePath[MAX_PATH];
+    if (!::GetModuleFileNameW(0, exePath, _countof(exePath)))
+        return fatalError(L"Unknown Program", L"Failed to determine name of executable: " + getLastErrorString(::GetLastError()));
+
+    ::PathRemoveExtensionW(exePath);
+
+    wstring programName = ::PathFindFileNameW(exePath);
+
+    if (!modifyPath(programName))
+        return 1;
+
+    // Load our corresponding DLL.
+    wstring dllName = programName + L".dll";
+    if (!::PathRemoveFileSpecW(exePath))
+        return fatalError(programName, L"::PathRemoveFileSpecW failed: " + getLastErrorString(::GetLastError()));
+    if (!::PathAppendW(exePath, dllName.c_str()))
+        return fatalError(programName, L"::PathAppendW failed: " + getLastErrorString(::GetLastError()));
+    HMODULE module = ::LoadLibraryW(exePath);
+    if (!module)
+        return fatalError(programName, L"::LoadLibraryW failed: \npath=" + wstring(exePath) + L"\n" + getLastErrorString(::GetLastError()));
+
+#if USE_CONSOLE_ENTRY_POINT
+    typedef int (WINAPI*EntryPoint)(int, const char*[]);
+#if defined _M_AMD64 || defined _WIN64
+    const char* entryPointName = "dllLauncherEntryPoint";
+#else
+    const char* entryPointName = "_dllLauncherEntryPoint@8";
+#endif
+#else
+    typedef int (WINAPI*EntryPoint)(HINSTANCE, HINSTANCE, LPWSTR, int);
+#if defined _M_AMD64 || defined _WIN64
+    const char* entryPointName = "dllLauncherEntryPoint";
+#else
+    const char* entryPointName = "_dllLauncherEntryPoint@16";
+#endif
+#endif
+
+    EntryPoint entryPoint = reinterpret_cast<EntryPoint>(::GetProcAddress(module, entryPointName));
+    if (!entryPoint)
+        return fatalError(programName, L"Failed to find dllLauncherEntryPoint function: " + getLastErrorString(::GetLastError()));
+
+#if USE_CONSOLE_ENTRY_POINT
+    return entryPoint(argc, argv);
+#else
+    return entryPoint(hInstance, hPrevInstance, lpstrCmdLine, nCmdShow);
+#endif
+}
diff --git a/JavaScriptCore.vcxproj/jsc/DLLLauncherWinCairo.props b/JavaScriptCore.vcxproj/jsc/DLLLauncherWinCairo.props
new file mode 100644 (file)
index 0000000..dd13fbc
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>WIN_CAIRO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup />
+</Project>
\ No newline at end of file
index a829c05b25d52ea1f649841071ba1a4918a6320e..921dcf5636ffb7a1f896291eb2637fc5414ce446 100644 (file)
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
     <Import Project="jscProduction.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>
index 8545424118e4db2301301a267f70019d6dd5452a..3abbdf619e2bbbca9b278d50061bfb74de95818f 100644 (file)
@@ -8,11 +8,11 @@
   <ItemDefinitionGroup>
     <ClCompile>
       <AdditionalIncludeDirectories>..\..\;..\..\tools\;..\..\runtime\;..\..\llint\;..\..\jit\;..\..\disassembler\;..\..\heap\;..\..\debugger\;..\..\assembler\;..\..\profiler\;..\..\interpreter\;..\..\bytecode\;..\..\dfg\;..\..\bytecompiler\;..\..\parser\;..\..\API\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\private\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\JavaScriptCore\DerivedSources\;$(WebKit_Libraries)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>USE_CONSOLE_ENTRY_POINT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ForcedIncludeFiles>ICUVersion.h</ForcedIncludeFiles>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>WTF$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;winmm.lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>WTF$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;winmm.lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ModuleDefinitionFile>
       </ModuleDefinitionFile>
       <SubSystem>Console</SubSystem>
diff --git a/JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj b/JavaScriptCore.vcxproj/jsc/jscLauncher.vcxproj
new file mode 100644 (file)
index 0000000..05a5b46
--- /dev/null
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="DebugSuffix|Win32">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="DebugSuffix|x64">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|Win32">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|x64">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|Win32">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|x64">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|Win32">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|x64">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{FE09F693-9744-4D73-A17C-DE3209EB1905}</ProjectGuid>\r
+    <RootNamespace>jscLauncher</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <ProjectName>jscLauncher</ProjectName>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscRelease.props" />\r
+    <Import Project="DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscRelease.props" />\r
+    <Import Project="DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+    <Import Project="DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+    <Import Project="DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="jscDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|x64'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">jsc$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">jsc$(DebugSuffix)</TargetName>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="DLLLauncherMain.cpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="jscLauncherPostBuild.cmd" />\r
+    <None Include="jscLauncherPreBuild.cmd" />\r
+    <None Include="jscLauncherPreLink.cmd" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/JavaScriptCore.vcxproj/jsc/jscLauncherPostBuild.cmd b/JavaScriptCore.vcxproj/jsc/jscLauncherPostBuild.cmd
new file mode 100644 (file)
index 0000000..02da44b
--- /dev/null
@@ -0,0 +1 @@
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
\ No newline at end of file
diff --git a/JavaScriptCore.vcxproj/jsc/jscLauncherPreBuild.cmd b/JavaScriptCore.vcxproj/jsc/jscLauncherPreBuild.cmd
new file mode 100644 (file)
index 0000000..4e5ccc5
--- /dev/null
@@ -0,0 +1,6 @@
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+cmd /c
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
+if errorlevel 1 exit 1
+echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
diff --git a/JavaScriptCore.vcxproj/jsc/jscLauncherPreLink.cmd b/JavaScriptCore.vcxproj/jsc/jscLauncherPreLink.cmd
new file mode 100644 (file)
index 0000000..e69de29
index 72ab16a0e5f79fc7697549b8af616b811736e165..4e5ccc54583056010fad8d66dbf2230754eccd32 100644 (file)
@@ -1,4 +1,4 @@
-%SystemDrive%\cygwin\bin\which.exe perl
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
 if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
 cmd /c
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
index 00897fd45947e2f965b7c5c118b53c700067cfc1..9c8bec15976d5d8a14dbd9c5d67b28e250bda429 100644 (file)
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -77,7 +77,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -89,7 +89,7 @@
   </PropertyGroup>
   <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
index dc7805bc9fb36d6b1af176ea3039bedf51916d70..337b2354cda0f4c966c71d9cb6b7de2a13e62b47 100644 (file)
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
     <Import Project="testRegExpProduction.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+    <TargetExt>.dll</TargetExt>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>
index b35061d757b68db43b5b68598b39bbe5c22e9d4c..eddf98b1b79045940c5423235066306764af55c1 100644 (file)
@@ -5,11 +5,11 @@
   <PropertyGroup />
   <ItemDefinitionGroup>
     <ClCompile>
-      <PreprocessorDefinitions>_CONSOLE;__STD_C;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>USE_CONSOLE_ENTRY_POINT;_CONSOLE;__STD_C;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\JavaScriptCore\DerivedSources;..\..\;..\..\assembler;..\..\API;..\..\parser;..\..\heap;..\..\runtime;..\..\bytecode;..\..\interpreter;..\..\debugger;..\..\bytecompiler;..\..\profiler;..\..\jit;$(WebKit_Libraries)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>JavaScriptCore$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;WTF$(DebugSuffix).lib;winmm.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>JavaScriptCore$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;WTF$(DebugSuffix).lib;winmm.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Console</SubSystem>
     </Link>
   </ItemDefinitionGroup>
diff --git a/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj b/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncher.vcxproj
new file mode 100644 (file)
index 0000000..a6509a4
--- /dev/null
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="DebugSuffix|Win32">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="DebugSuffix|x64">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|Win32">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|x64">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|Win32">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|x64">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|Win32">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|x64">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{1B8A5CB0-D0CF-4458-8247-8FBA5C6EA20F}</ProjectGuid>\r
+    <RootNamespace>testRegExpLauncher</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <ProjectName>testRegExpLauncher</ProjectName>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpRelease.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpRelease.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testRegExpDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|x64'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">testRegExp$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">testRegExp$(DebugSuffix)</TargetName>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">\r
+    <TargetName>testRegExp$(DebugSuffix)</TargetName>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">\r
+    <TargetName>testRegExp$(DebugSuffix)</TargetName>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="../jsc/DLLLauncherMain.cpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="testRegExpLauncherPostBuild.cmd" />\r
+    <None Include="testRegExpLauncherPreBuild.cmd" />\r
+    <None Include="testRegExpLauncherPreLink.cmd" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPostBuild.cmd b/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPostBuild.cmd
new file mode 100644 (file)
index 0000000..0204125
--- /dev/null
@@ -0,0 +1,3 @@
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
+
+cmd /c
diff --git a/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreBuild.cmd b/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreBuild.cmd
new file mode 100644 (file)
index 0000000..4e5ccc5
--- /dev/null
@@ -0,0 +1,6 @@
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+cmd /c
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
+if errorlevel 1 exit 1
+echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
diff --git a/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreLink.cmd b/JavaScriptCore.vcxproj/testRegExp/testRegExpLauncherPreLink.cmd
new file mode 100644 (file)
index 0000000..e69de29
index 72ab16a0e5f79fc7697549b8af616b811736e165..4e5ccc54583056010fad8d66dbf2230754eccd32 100644 (file)
@@ -1,4 +1,4 @@
-%SystemDrive%\cygwin\bin\which.exe perl
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
 if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
 cmd /c
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
index bb317ad7dbb1277a2c060d72c5da4aee8ec6428b..b26c84ddaf9cfa9acccd928b9d8936862d068ed3 100644 (file)
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120_xp</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120_xp</PlatformToolset>
+    <PlatformToolset>v120</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v120</PlatformToolset>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\API\tests\testapi.c" />
+    <ClCompile Include="..\..\API\tests\CompareAndSwapTest.cpp" />
+    <ClInclude Include="..\..\API\tests\CompareAndSwapTest.h" />
     <ClCompile Include="..\..\API\tests\CustomGlobalObjectClassTest.c" />
     <ClInclude Include="..\..\API\tests\CustomGlobalObjectClassTest.h" />
+    <ClCompile Include="..\..\API\tests\GlobalContextWithFinalizerTest.cpp" />
+    <ClInclude Include="..\..\API\tests\GlobalContextWithFinalizerTest.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 9641ef701e7ac09edac5d8197eb3023db0e512fd..3598f8b733416dbb7e86a51a1396376e2c479c39 100644 (file)
@@ -8,7 +8,11 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\API\tests\testapi.c" />
+    <ClCompile Include="..\..\API\tests\CompareAndSwapTest.cpp" />
+    <ClInclude Include="..\..\API\tests\CompareAndSwapTest.h" />
     <ClCompile Include="..\..\API\tests\CustomGlobalObjectClassTest.c" />
     <ClInclude Include="..\..\API\tests\CustomGlobalObjectClassTest.h" />
+    <ClCompile Include="..\..\API\tests\GlobalContextWithFinalizerTest.cpp" />
+    <ClInclude Include="..\..\API\tests\GlobalContextWithFinalizerTest.h" />
   </ItemGroup>
 </Project>
index c8c791a7d6eb2ab289cce1c666770736a27e4b1e..cdf25c565715bdbcec5adb46ea92b2632287ae09 100644 (file)
@@ -5,12 +5,12 @@
   <PropertyGroup />
   <ItemDefinitionGroup>
     <Link>
-      <AdditionalDependencies>CoreFoundation$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>CoreFoundation$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Console</SubSystem>
     </Link>
     <ClCompile>
-      <PreprocessorDefinitions>NOMINMAX;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NOMINMAX;USE_CONSOLE_ENTRY_POINT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ProjectDir)\..\..\;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
   </ItemDefinitionGroup>
   <ItemGroup />
index 0da8cdf70773168109215b5a71c0245a4dcf00e2..e58c40ca3c3b68574a0992ee04f3d0754a9c1413 100644 (file)
@@ -5,12 +5,12 @@
   <PropertyGroup />
   <ItemDefinitionGroup>
     <Link>
-      <AdditionalDependencies>CFLite.lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin.lib;libicuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>CFLite.lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin.lib;libicuuc.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Console</SubSystem>
     </Link>
     <ClCompile>
-      <PreprocessorDefinitions>NOMINMAX;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NOMINMAX;USE_CONSOLE_ENTRY_POINT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ProjectDir)\..\..\;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
   </ItemDefinitionGroup>
   <ItemGroup />
diff --git a/JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj b/JavaScriptCore.vcxproj/testapi/testapiLauncher.vcxproj
new file mode 100644 (file)
index 0000000..fb15f4d
--- /dev/null
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="DebugSuffix|Win32">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="DebugSuffix|x64">\r
+      <Configuration>DebugSuffix</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|Win32">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug_WinCairo|x64">\r
+      <Configuration>Debug_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|Win32">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Production|x64">\r
+      <Configuration>Production</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|Win32">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release_WinCairo|x64">\r
+      <Configuration>Release_WinCairo</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{FE09F693-9744-4D73-A17C-FE3209EB1905}</ProjectGuid>\r
+    <RootNamespace>testapiLauncher</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <ProjectName>testapiLauncher</ProjectName>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120_xp</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v120</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiRelease.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiReleaseCFLite.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiReleaseCFLite.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiProduction.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebug.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebugCFLite.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebugCFLite.props" />\r
+    <Import Project="..\jsc\DLLLauncherWinCairo.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="testapiDebug.props" />\r
+    <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Production|x64'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">testapi$(DebugSuffix)</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">testapi$(DebugSuffix)</TargetName>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="../jsc/DLLLauncherMain.cpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="testapiLauncherPostBuild.cmd" />\r
+    <None Include="testapiLauncherPreBuild.cmd" />\r
+    <None Include="testapiLauncherPreLink.cmd" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/JavaScriptCore.vcxproj/testapi/testapiLauncherPostBuild.cmd b/JavaScriptCore.vcxproj/testapi/testapiLauncherPostBuild.cmd
new file mode 100644 (file)
index 0000000..64fb320
--- /dev/null
@@ -0,0 +1,3 @@
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
+
+@xcopy /y /d "%PROJECTDIR%\..\..\API\tests\testapi.js" "%OUTDIR%" >nul 2>nul
diff --git a/JavaScriptCore.vcxproj/testapi/testapiLauncherPreBuild.cmd b/JavaScriptCore.vcxproj/testapi/testapiLauncherPreBuild.cmd
new file mode 100644 (file)
index 0000000..4e5ccc5
--- /dev/null
@@ -0,0 +1,6 @@
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+cmd /c
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
+if errorlevel 1 exit 1
+echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
diff --git a/JavaScriptCore.vcxproj/testapi/testapiLauncherPreLink.cmd b/JavaScriptCore.vcxproj/testapi/testapiLauncherPreLink.cmd
new file mode 100644 (file)
index 0000000..e69de29
index 0820433b0007bf2f62f6d3d7d160f9c165d0d359..64fb320d7c446b8794888d300f02a0557bc19824 100644 (file)
@@ -1,3 +1,3 @@
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
 
-xcopy /y /d "%PROJECTDIR%\..\..\API\tests\testapi.js" "%OUTDIR%"
+@xcopy /y /d "%PROJECTDIR%\..\..\API\tests\testapi.js" "%OUTDIR%" >nul 2>nul
index 72ab16a0e5f79fc7697549b8af616b811736e165..49e17231930895bef5748279af95c1d5c12131d6 100644 (file)
@@ -1,6 +1,6 @@
-%SystemDrive%\cygwin\bin\which.exe perl
+%SystemDrive%\cygwin\bin\which.exe perl >nul 2>nul
 if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
 cmd /c
 if exist "%CONFIGURATIONBUILDDIR%\buildfailed" perl -wnle "if (/XX%PROJECTNAME%XX/) { print } else { exit 1 }" "%CONFIGURATIONBUILDDIR%\buildfailed"
 if errorlevel 1 exit 1
-echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
+@echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed"
index 308d9df9350a6aad3a35c3eb103fc2a689aa9171..67e8a292405f0ac9ff838cc9a7b28fcc73018372 100644 (file)
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+               0A6441519420A6C61AD1882E /* MapDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */; };
+               0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0123311944EA1B00843A0C /* DFGValueStrength.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */; };
                0F0332C318B01763005F979A /* GetByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0332C118B01763005F979A /* GetByIdVariant.cpp */; };
                0F0332C418B01763005F979A /* GetByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0332C218B01763005F979A /* GetByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0332C618B53FA9005F979A /* FTLWeight.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0332C518B53FA9005F979A /* FTLWeight.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0332C818B546EC005F979A /* FTLWeightedTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0332C718B546EC005F979A /* FTLWeightedTarget.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F04396D1B03DC0B009598B7 /* DFGCombinedLiveness.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F04396B1B03DC0B009598B7 /* DFGCombinedLiveness.cpp */; };
+               0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0776BD14FF002800102332 /* JITCompilationEffort.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */; };
@@ -92,6 +97,8 @@
                0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */; };
                0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F12DE0F1979D5FD0006FF4E /* ExceptionFuzz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F12DE0D1979D5FD0006FF4E /* ExceptionFuzz.cpp */; };
+               0F12DE101979D5FD0006FF4E /* ExceptionFuzz.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F12DE0E1979D5FD0006FF4E /* ExceptionFuzz.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F136D4D174AD69E0075B354 /* DeferGC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F136D4B174AD69B0075B354 /* DeferGC.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13912416771C30009CCB07 /* ProfilerBytecodeSequence.cpp */; };
                0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912516771C30009CCB07 /* ProfilerBytecodeSequence.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
                0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */; };
-               0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */; };
                0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */; };
                0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1DD84918A945BE0026F3FA /* JSCInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1FE51C1922A3BC006987C5 /* AbortReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FE51B1922A3BC006987C5 /* AbortReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F20C2591A8013AB00DA3229 /* VirtualRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F20C2581A8013AB00DA3229 /* VirtualRegister.cpp */; };
                0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F235BD317178E1C00690C7F /* FTLExitArgument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBD17178E1C00690C7F /* FTLExitArgument.cpp */; };
                0F2B670917B6B5AB00A7AE3F /* TypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */; };
                0F2B670B17B6B5AB00A7AE3F /* TypedArrayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */; };
+               0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */; };
+               0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */; };
+               0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */; };
+               0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */; };
+               0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */; };
+               0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */; };
+               0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */; };
+               0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */; };
+               0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; };
                0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC2B151FDE8B00CD8910 /* Operands.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC401522801700CD8910 /* DFGValueSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC411522801700CD8910 /* DFGVariableEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC421522801700CD8910 /* DFGVariableEventStream.cpp */; };
                0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */; };
                0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */; };
                0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */; };
+               0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */; };
+               0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */; };
+               0F2D4DE919832DAC007D4B19 /* ToThisStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2D4DEA19832DAC007D4B19 /* TypeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE719832DAC007D4B19 /* TypeLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2D4DEB19832DC4007D4B19 /* TypeProfilerLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DDF19832D91007D4B19 /* TypeProfilerLog.cpp */; };
+               0F2D4DEC19832DC4007D4B19 /* TypeProfilerLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DE319832D91007D4B19 /* TypeSet.cpp */; };
+               0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE419832D91007D4B19 /* TypeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */; };
+               0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */; };
+               0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2F16828A7E003C2F8D /* UnusedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */; };
                0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01417CFE75500B144D3 /* DFGCompilationKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F38B01917CFE75500B144D3 /* DFGCompilationMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */; };
                0F38B01A17CFE75500B144D3 /* DFGCompilationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F392C891B46188400844728 /* DFGOSRExitFuzz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F392C871B46188400844728 /* DFGOSRExitFuzz.cpp */; };
+               0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F392C881B46188400844728 /* DFGOSRExitFuzz.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F3A1BF91A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3A1BF71A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp */; };
+               0F3A1BFA1A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3A1BF81A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F3AC752183EA1040032029F /* StackAlignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3AC751183EA1040032029F /* StackAlignment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F3AC754188E5EC80032029F /* ExitingJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3AC753188E5EC80032029F /* ExitingJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */; };
                0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */; };
                0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */; };
+               0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2519A11B8000D9BC56 /* CallVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; };
+               0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */; };
+               0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
                0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */; };
                0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5780A118FE1E98001E72D9 /* PureNaN.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */; };
+               0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F5A1273192D9FDF008764A3 /* DFGDoesGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */; };
+               0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A52CF17ADD717008ECB2D /* CopyToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */; };
                0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A6282188C98D40072C9DF /* FTLValueRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F6237971AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6237951AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp */; };
+               0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6237961AE45CA700D402EA /* DFGPhantomInsertionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F63943F15C75F19006A597C /* DFGTypeCheckHoistingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */; };
                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63945115D07051006A597C /* ArrayProfile.cpp */; };
                0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63948115E48114006A597C /* DFGArrayMode.cpp */; };
                0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63948215E48114006A597C /* DFGArrayMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */; };
+               0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F64B2771A7957B2006E4E66 /* CallEdge.cpp */; };
+               0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2781A7957B2006E4E66 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */; };
                0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EC31835672B00D017F1 /* DFGAvailability.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */; };
-               0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F682FB219BCB36400FA3BAD /* DFGSSACalculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */; };
+               0F682FB319BCB36400FA3BAD /* DFGSSACalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F682FB119BCB36400FA3BAD /* DFGSSACalculator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */; };
+               0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F69CC87193AC60A0045759E /* DFGFrozenValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */; };
                0F6B1CB6185FC9E900845D97 /* FTLJSCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */; };
                0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; };
+               0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; };
+               0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */; };
+               0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7025A91714B0FA00382C0E /* DFGOSRExitCompilerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */; };
                0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
                0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */; };
-               0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */; };
                0F7576D218E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */; };
                0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */; };
                0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
+               0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */; };
+               0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */; };
+               0F898F311B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F898F2F1B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp */; };
+               0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F898F301B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F8F14331ADF090100ED792C /* DFGEpoch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F142F1ADF090100ED792C /* DFGEpoch.cpp */; };
+               0F8F14341ADF090100ED792C /* DFGEpoch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8F14301ADF090100ED792C /* DFGEpoch.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F8F14351ADF090100ED792C /* DFGMovHintRemovalPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F14311ADF090100ED792C /* DFGMovHintRemovalPhase.cpp */; };
+               0F8F14361ADF090100ED792C /* DFGMovHintRemovalPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8F14321ADF090100ED792C /* DFGMovHintRemovalPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */; };
                0F8F2B96172E04A3007DBDA5 /* FTLLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8F2B94172E049E007DBDA5 /* FTLLink.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */; };
                0F8F94421667633500D61971 /* CodeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F943F1667632D00D61971 /* CodeType.cpp */; };
                0F8F94441667635400D61971 /* JITCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F94431667635200D61971 /* JITCode.cpp */; };
                0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F9445166764EE00D61971 /* CodeOrigin.cpp */; };
-               0F9181C718415CA50057B669 /* VariableWatchpointSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9181C618415CA50057B669 /* VariableWatchpointSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */; };
                0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */; };
                0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */; };
                0F93B4AA18B92C4D00178A3F /* PutByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F952ABC1B487A7700C367C5 /* TrackedReferences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */; };
+               0F952ABD1B487A7700C367C5 /* TrackedReferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F952ABB1B487A7700C367C5 /* TrackedReferences.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */; };
                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
                0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F9C5E5E18E35F5E00D431C3 /* FTLDWARFRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9C5E5C18E35F5E00D431C3 /* FTLDWARFRegister.cpp */; };
                0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D33981803ADB70073C2BC /* FTLStackMaps.cpp */; };
                0F9D339B1803ADB70073C2BC /* FTLStackMaps.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D33991803ADB70073C2BC /* FTLStackMaps.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F9D36941AE9CC33000D4DFB /* DFGCleanUpPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */; };
+               0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F9E32631B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9E32611B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp */; };
+               0F9E32641B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9E32621B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */; };
                0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
                0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
                0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; };
+               0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
                0FB14E1F18124ACE009B6B4D /* JITInlineCacheGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FB17660196B8F9E0091052A /* DFGHeapLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */; };
+               0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */; };
+               0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1765F196B8F9E0091052A /* DFGPureValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */; };
                0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
                0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */; };
                0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */; };
                0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */; };
                0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */; };
                0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */; };
+               0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */; };
                0FC314121814559100033232 /* RegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC314101814559100033232 /* RegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC314111814559100033232 /* TempRegisterSet.cpp */; };
                0FC3141518146D7000033232 /* RegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3141418146D7000033232 /* RegisterSet.cpp */; };
+               0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */; };
+               0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */; };
+               0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; };
                0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; };
                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
                0FC97F33182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */; };
                0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */; };
-               0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */; };
                0FC97F3E18202119002C9B26 /* DFGInvalidationPointInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3918202119002C9B26 /* DFGJumpReplacement.cpp */; };
                0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */; };
                0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FCEFAB01805CA6D00472CE4 /* InitializeLLVM.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAE1805CA6D00472CE4 /* InitializeLLVM.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0FCEFAB11805CA6D00472CE4 /* InitializeLLVMMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAAF1805CA6D00472CE4 /* InitializeLLVMMac.mm */; };
                0FCEFAC11805D94E00472CE4 /* LLVMOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC01805D94100472CE4 /* LLVMOverrides.cpp */; };
                0FCEFAC31805E74000472CE4 /* LLVMExports.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC21805E74000472CE4 /* LLVMExports.cpp */; };
                0FCEFACA1805E75500472CE4 /* InitializeLLVM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC41805E75500472CE4 /* InitializeLLVM.cpp */; };
-               0FCEFACB1805E75500472CE4 /* InitializeLLVMPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC51805E75500472CE4 /* InitializeLLVMPOSIX.cpp */; };
                0FCEFACC1805E75500472CE4 /* InitializeLLVMPOSIX.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAC61805E75500472CE4 /* InitializeLLVMPOSIX.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FCEFACD1805E75500472CE4 /* LLVMAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC71805E75500472CE4 /* LLVMAPI.cpp */; };
                0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAC81805E75500472CE4 /* LLVMAPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FCEFADC18064A1400472CE4 /* config_llvm.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFADB18064A1400472CE4 /* config_llvm.h */; };
                0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */; };
                0FCEFAE0180738C000472CE4 /* FTLLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFADE180738C000472CE4 /* FTLLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FD1202F1A8AED12000F5280 /* FTLJSCallBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD1202D1A8AED12000F5280 /* FTLJSCallBase.cpp */; };
+               0FD120301A8AED12000F5280 /* FTLJSCallBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD1202E1A8AED12000F5280 /* FTLJSCallBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD120311A8C85BD000F5280 /* FTLJSCallVarargs.cpp */; };
+               0FD120341A8C85BD000F5280 /* FTLJSCallVarargs.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD120321A8C85BD000F5280 /* FTLJSCallVarargs.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
                0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
                0FD8A32A17D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD8A32217D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */; };
                0FD8A32C17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FD949821A97DB9600E28966 /* JSCatchScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */; };
+               0FD949831A97DB9600E28966 /* JSCatchScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD9497F1A97DB9600E28966 /* JSCatchScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FD949841A97DB9600E28966 /* JSFunctionNameScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD949801A97DB9600E28966 /* JSFunctionNameScope.cpp */; };
+               0FD949851A97DB9600E28966 /* JSFunctionNameScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD949811A97DB9600E28966 /* JSFunctionNameScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CC7173DA51E007B3C1B /* FTLAbbreviatedTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CC8173DA51E007B3C1B /* FTLValueFromBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FDB2CE7174830A2007B3C1B /* DFGWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */; };
                0FDB2CEA174896C7007B3C1B /* ConcurrentJITLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */; };
                0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */; };
+               0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */; };
+               0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050101AA9091100D33B33 /* DirectArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050111AA9091100D33B33 /* GenericArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050131AA9091100D33B33 /* GenericOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */; };
+               0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501D1AA9095600D33B33 /* ClonedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */; };
+               0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501F1AA9095600D33B33 /* ScopedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050211AA9095600D33B33 /* ScopeOffset.cpp */; };
+               0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050221AA9095600D33B33 /* ScopeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050231AA9095600D33B33 /* VarOffset.cpp */; };
+               0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050241AA9095600D33B33 /* VarOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */; };
                0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
+               0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */; };
+               0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */; };
+               0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE7211C193B9C590031F6ED /* DFGTransition.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FE834171A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */; };
+               0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */; };
                0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FE95F7918B5694700B531FB /* FTLDataSection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE95F7718B5694700B531FB /* FTLDataSection.cpp */; };
                0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A2F170D40BF00BB722C /* DFGJITCode.cpp */; };
                0FEA0A34170D40BF00BB722C /* DFGJITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA0A30170D40BF00BB722C /* DFGJITCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
+               0FED67B91B26256D0066CE15 /* DFGConstantHoistingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FED67B71B26256D0066CE15 /* DFGConstantHoistingPhase.cpp */; };
+               0FED67BA1B26256D0066CE15 /* DFGConstantHoistingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FED67B81B26256D0066CE15 /* DFGConstantHoistingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */; };
                0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
                0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FF054F91AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */; };
+               0FF054FA1AC35B4400E5BE57 /* ExecutableAllocationFuzz.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */; };
                0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51E16B62772003F696B /* DFGNode.cpp */; };
                0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FF8BDEA1AD4CF7100DFE884 /* InferredValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */; };
+               0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
                0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A221651C69700A80AFE /* A64DOpcode.cpp */; };
                0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 652A3A231651C69700A80AFE /* A64DOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FFB6C381AF48DDC00DB1BF7 /* TypeofType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */; };
+               0FFB6C391AF48DDC00DB1BF7 /* TypeofType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFB6C371AF48DDC00DB1BF7 /* TypeofType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51916B62772003F696B /* DFGAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
                140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; };
-               140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; };
+               140B7D1D0DC69AF7009C42B8 /* JSLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSLexicalEnvironment.cpp */; };
                140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
                141211340A48795800480255 /* minidom.c in Sources */ = {isa = PBXBuildFile; fileRef = 141211020A48780900480255 /* minidom.c */; };
                14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C40E16D4E900A06E92 /* NumberPrototype.cpp */; };
                14469DE5107EC7E700650446 /* ObjectConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C60E16D4E900A06E92 /* ObjectConstructor.cpp */; };
                14469DE6107EC7E700650446 /* ObjectPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */; };
-               14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */; };
                14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* PropertySlot.cpp */; };
                14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */; };
                14469DEC107EC7E700650446 /* StringObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C20E16EE3300B34460 /* StringObject.cpp */; };
                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF605110E203EF800B9A64D /* ArgList.cpp */; };
-               147F39BE107EC37600427A48 /* Arguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DE50E1F51C50016B6C9 /* Arguments.cpp */; };
                147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; };
                147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; };
                147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */; };
                147F39D4107EC37600427A48 /* JSObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A3980E16E14800AF21C8 /* JSObject.cpp */; };
                147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; };
                147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSCJSValue.cpp */; };
-               147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */; };
-               14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14816E19154CC56C00B8054C /* BlockAllocator.cpp */; };
-               14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14816E1A154CC56C00B8054C /* BlockAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */; };
                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
                1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
                14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14874ADF15EBDE4A002E3587 /* JSNameScope.cpp */; };
                14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */; };
-               1CAA9A1E18F4997F000A369D /* InspectorProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAA9A1C18F4997F000A369D /* InspectorProfilerAgent.cpp */; };
-               1CAA9A1F18F4997F000A369D /* InspectorProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA9A1D18F4997F000A369D /* InspectorProfilerAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               1CAA9A2218F4A220000A369D /* JSGlobalObjectProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAA9A2018F4A220000A369D /* JSGlobalObjectProfilerAgent.cpp */; };
-               1CAA9A2318F4A220000A369D /* JSGlobalObjectProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA9A2118F4A220000A369D /* JSGlobalObjectProfilerAgent.h */; };
                2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; };
                2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
+               2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */; };
+               2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */; };
                2A111245192FCE79005EE18D /* CustomGetterSetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */; };
                2A111246192FCE79005EE18D /* CustomGetterSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A111244192FCE79005EE18D /* CustomGetterSetter.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */; };
                2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; };
                2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */; };
                2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
                2AAD964A18569417001F93BE /* RecursiveAllocationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AAD964918569417001F93BE /* RecursiveAllocationScope.h */; };
                2AC922BB18A16182003CE0FB /* FTLDWARFDebugLineInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AC922B918A16182003CE0FB /* FTLDWARFDebugLineInfo.cpp */; };
                2AC922BC18A16182003CE0FB /* FTLDWARFDebugLineInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC922BA18A16182003CE0FB /* FTLDWARFDebugLineInfo.h */; };
-               2ACCF3DE185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACCF3DC185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp */; };
-               2ACCF3DF185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */; };
+               2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD8932917E3868F00668276 /* HeapIterationScope.h */; };
                2ADFA26318EF3540004F9FCC /* GCLogging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADFA26218EF3540004F9FCC /* GCLogging.cpp */; };
                2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */; };
                2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
                371D842D17C98B6E00ECF994 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 371D842C17C98B6E00ECF994 /* libz.dylib */; };
                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
+               4340A4841A9051AF00D73CCA /* MathCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4340A4821A9051AF00D73CCA /* MathCommon.cpp */; };
+               4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 4340A4831A9051AF00D73CCA /* MathCommon.h */; };
                4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
                451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               5510502618EB827500001F3E /* JSCallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F88F0A508B100005F061 /* JSCallbackFunction.h */; };
-               5540757218DA58AD00EFF7F2 /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; };
-               5540757318DA58AD00EFF7F2 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; };
-               5540757418DA58AD00EFF7F2 /* ArgumentsIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */; };
-               5540757518DA58AD00EFF7F2 /* ArgumentsIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */; };
-               5540757718DA58AD00EFF7F2 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; };
-               5540757C18DA58AD00EFF7F2 /* StructureIDBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */; };
-               5540758318DA58AD00EFF7F2 /* ArrayBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2617ADB5F3005AB174 /* ArrayBuffer.h */; };
-               5540758418DA58AD00EFF7F2 /* ArrayBufferNeuteringWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */; };
-               5540758518DA58AD00EFF7F2 /* ArrayBufferView.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2817ADB5F3005AB174 /* ArrayBufferView.h */; };
-               5540758618DA58AD00EFF7F2 /* ArrayConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7952070E15E8A800A898AB /* ArrayConstructor.h */; };
-               5540758718DA58AD00EFF7F2 /* ArrayConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */; };
-               5540758818DA58AD00EFF7F2 /* ArrayIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC117F4EA1400F6140C /* ArrayIteratorConstructor.h */; };
-               5540758918DA58AD00EFF7F2 /* ArrayIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC317F4EA1400F6140C /* ArrayIteratorPrototype.h */; };
-               5540758B18DA58AD00EFF7F2 /* ArrayPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* ArrayPrototype.h */; };
-               5540758D18DA58AD00EFF7F2 /* StructureIDTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */; };
-               5540758E18DA58AD00EFF7F2 /* ArrayStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */; };
-               5540759318DA58AD00EFF7F2 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; };
-               5540759418DA58AD00EFF7F2 /* BigInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D013BFDE710023D87C /* BigInteger.h */; };
-               5540759618DA58AD00EFF7F2 /* BooleanObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 704FD35305697E6D003DBED9 /* BooleanObject.h */; };
-               5540759A18DA58AD00EFF7F2 /* Butterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */; };
-               5540759B18DA58AD00EFF7F2 /* ButterflyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */; };
-               554075A318DA58AD00EFF7F2 /* CallData.h in Headers */ = {isa = PBXBuildFile; fileRef = 145C507F0D9DF63B0088F6B9 /* CallData.h */; };
-               554075AB18DA58AD00EFF7F2 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; };
-               554075B218DA58AD00EFF7F2 /* CodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F1820164088B200640A47 /* CodeCache.h */; };
-               554075B718DA58AD00EFF7F2 /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; };
-               554075B918DA58AD00EFF7F2 /* CommonIdentifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */; };
-               554075BA18DA58AD00EFF7F2 /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; };
-               554075BB18DA58AD00EFF7F2 /* CommonSlowPathsExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6553A33017A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h */; };
-               554075BD18DA58AD00EFF7F2 /* CompilationResult.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E5A3A61797432D00E893C0 /* CompilationResult.h */; };
-               554075BE18DA58AD00EFF7F2 /* JSConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = A53CE08418BC1A5600BEDF76 /* JSConsole.h */; };
-               554075BF18DA58AD00EFF7F2 /* Completion.h in Headers */ = {isa = PBXBuildFile; fileRef = F5BB2BC5030F772101FCFE1D /* Completion.h */; };
-               554075C018DA58AD00EFF7F2 /* ConcurrentJITLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */; };
-               554075C418DA58AD00EFF7F2 /* ConsoleTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FD0071189B038C00633231 /* ConsoleTypes.h */; };
-               554075C518DA58AD00EFF7F2 /* ConstantMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */; };
-               554075C618DA58AD00EFF7F2 /* ConstructData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */; };
-               554075D518DA58AD00EFF7F2 /* DataView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B117B6B5AB00A7AE3F /* DataView.h */; };
-               554075D618DA58AD00EFF7F2 /* DateConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203460E17135E002C7E82 /* DateConstructor.h */; };
-               554075D718DA58AD00EFF7F2 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
-               554075D818DA58AD00EFF7F2 /* DateInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1166010E1997B1008066DD /* DateInstance.h */; };
-               554075D918DA58AD00EFF7F2 /* DateInstanceCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A1563010966365006FA260 /* DateInstanceCache.h */; };
-               554075DA18DA58AD00EFF7F2 /* DatePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203480E17135E002C7E82 /* DatePrototype.h */; };
-               554075DC18DA58AD00EFF7F2 /* Debugger.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8590255597D01FF60F7 /* Debugger.h */; };
-               5540766D18DA58AD00EFF7F2 /* DumpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A70447EC17A0BD7000F5898E /* DumpContext.h */; };
-               5540767018DA58AD00EFF7F2 /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; };
-               5540767118DA58AD00EFF7F2 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; };
-               5540767218DA58AD00EFF7F2 /* ErrorHandlingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB58C13187B8B160098EF0B /* ErrorHandlingScope.h */; };
-               5540767318DA58AD00EFF7F2 /* ErrorInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E98B0E183E38000F9297 /* ErrorInstance.h */; };
-               5540767418DA58AD00EFF7F2 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; };
-               5540767718DA58AD00EFF7F2 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
-               5540767818DA58AD00EFF7F2 /* Executable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CAFEE21035DDE60028A609 /* Executable.h */; };
-               5540767E18DA58AD00EFF7F2 /* Float32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2917ADB5F3005AB174 /* Float32Array.h */; };
-               5540767F18DA58AD00EFF7F2 /* Float64Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */; };
-               5540768318DA58AD00EFF7F2 /* ConsoleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A53CE08918BC21C300BEDF76 /* ConsoleClient.h */; };
-               5540769118DA58AD00EFF7F2 /* ConsolePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */; };
-               554076B618DA58AD00EFF7F2 /* FunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */; };
-               554076B718DA58AD00EFF7F2 /* FunctionExecutableDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */; };
-               554076B818DA58AD00EFF7F2 /* FunctionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A85D0255597D01FF60F7 /* FunctionPrototype.h */; };
-               554076C218DA58AD00EFF7F2 /* GenericTypedArrayView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */; };
-               554076C318DA58AD00EFF7F2 /* GenericTypedArrayViewInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */; };
-               554076D618DA58AD00EFF7F2 /* Identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A349A038AE7C6008635CE /* Identifier.h */; };
-               554076DA18DA58AD00EFF7F2 /* IndexingHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */; };
-               554076DB18DA58AD00EFF7F2 /* IndexingHeaderInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */; };
-               554076DC18DA58AD00EFF7F2 /* IndexingType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */; };
-               554076DF18DA58AD00EFF7F2 /* InitializeThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = E178633F0D9BEC0000D74E75 /* InitializeThreading.h */; };
-               554076F818DA58AD00EFF7F2 /* Int16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2C17ADB5F3005AB174 /* Int16Array.h */; };
-               554076F918DA58AD00EFF7F2 /* Int32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2D17ADB5F3005AB174 /* Int32Array.h */; };
-               554076FA18DA58AD00EFF7F2 /* Int8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */; };
-               554076FB18DA58AD00EFF7F2 /* IntendedStructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = A78853F817972629001440E4 /* IntendedStructureChain.h */; };
-               554076FC18DA58AD00EFF7F2 /* InternalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC11667A0E199C05008066DD /* InternalFunction.h */; };
-               554076FE18DA58AD00EFF7F2 /* Intrinsic.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BF642A148DB2B5004DE36A /* Intrinsic.h */; };
-               5540771818DA58AD00EFF7F2 /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; settings = {ATTRIBUTES = (); }; };
-               5540771918DA58AD00EFF7F2 /* JSAPIValueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */; };
-               5540771B18DA58AD00EFF7F2 /* JSArgumentsIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140CC182982CB00750624 /* JSArgumentsIterator.h */; };
-               5540771C18DA58AD00EFF7F2 /* JSArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 938772E5038BFE19008635CE /* JSArray.h */; };
-               5540771D18DA58AD00EFF7F2 /* JSArrayBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */; };
-               5540771E18DA58AD00EFF7F2 /* JSArrayBufferConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B717B6B5AB00A7AE3F /* JSArrayBufferConstructor.h */; };
-               5540771F18DA58AD00EFF7F2 /* JSArrayBufferPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66B917B6B5AB00A7AE3F /* JSArrayBufferPrototype.h */; };
-               5540772018DA58AD00EFF7F2 /* JSArrayBufferView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66BB17B6B5AB00A7AE3F /* JSArrayBufferView.h */; };
-               5540772118DA58AD00EFF7F2 /* JSArrayBufferViewInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66BC17B6B5AB00A7AE3F /* JSArrayBufferViewInlines.h */; };
-               5540772218DA58AD00EFF7F2 /* JSArrayIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */; };
-               5540772518DA58AD00EFF7F2 /* (null) in Headers */ = {isa = PBXBuildFile; };
-               5540772B18DA58AD00EFF7F2 /* JSCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1167D80E19BCC9008066DD /* JSCell.h */; };
-               5540772C18DA58AD00EFF7F2 /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; };
-               5540772D18DA58AD00EFF7F2 /* JSCInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1DD84918A945BE0026F3FA /* JSCInlines.h */; };
-               5540772E18DA58AD00EFF7F2 /* JSCJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB36E099C076400E2A24F /* JSCJSValue.h */; };
-               5540772F18DA58AD00EFF7F2 /* JSCJSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */; };
-               5540773618DA58AD00EFF7F2 /* JSDataView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66BE17B6B5AB00A7AE3F /* JSDataView.h */; };
-               5540773718DA58AD00EFF7F2 /* JSDataViewPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C017B6B5AB00A7AE3F /* JSDataViewPrototype.h */; };
-               5540773818DA58AD00EFF7F2 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; };
-               5540773918DA58AD00EFF7F2 /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A7F687160432D400F76B98 /* JSDestructibleObject.h */; };
-               5540773B18DA58AD00EFF7F2 /* JSExportMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */; };
-               5540773C18DA58AD00EFF7F2 /* JSFloat32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C117B6B5AB00A7AE3F /* JSFloat32Array.h */; };
-               5540773D18DA58AD00EFF7F2 /* JSFloat64Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C217B6B5AB00A7AE3F /* JSFloat64Array.h */; };
-               5540773E18DA58AD00EFF7F2 /* JSFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A85F0255597D01FF60F7 /* JSFunction.h */; };
-               5540773F18DA58AD00EFF7F2 /* JSFunctionInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B91797603D0098028C /* JSFunctionInlines.h */; };
-               5540774018DA58AD00EFF7F2 /* JSGenericTypedArrayView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C317B6B5AB00A7AE3F /* JSGenericTypedArrayView.h */; };
-               5540774118DA58AD00EFF7F2 /* JSGenericTypedArrayViewConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C417B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h */; };
-               5540774218DA58AD00EFF7F2 /* JSGenericTypedArrayViewConstructorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C517B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructorInlines.h */; };
-               5540774318DA58AD00EFF7F2 /* JSGenericTypedArrayViewInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C617B6B5AB00A7AE3F /* JSGenericTypedArrayViewInlines.h */; };
-               5540774418DA58AD00EFF7F2 /* JSGenericTypedArrayViewPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C717B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototype.h */; };
-               5540774518DA58AD00EFF7F2 /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C817B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h */; };
-               5540774618DA58AD00EFF7F2 /* JSGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E894330CD0603F00367179 /* JSGlobalObject.h */; };
-               5540774818DA58AD00EFF7F2 /* JSGlobalObjectDebuggable.h in Headers */ = {isa = PBXBuildFile; fileRef = A59455911824744700CC3843 /* JSGlobalObjectDebuggable.h */; };
-               5540774A18DA58AD00EFF7F2 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
-               5540775018DA58AD00EFF7F2 /* JSInt16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66CA17B6B5AB00A7AE3F /* JSInt16Array.h */; };
-               5540775118DA58AD00EFF7F2 /* JSInt32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66CB17B6B5AB00A7AE3F /* JSInt32Array.h */; };
-               5540775218DA58AD00EFF7F2 /* JSInt8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */; };
-               5540775518DA58AD00EFF7F2 /* JSLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA4C9A092AF9E20093D800 /* JSLock.h */; };
-               5540775818DA58AD00EFF7F2 /* JSMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A700874017CBE8EB00C3E643 /* JSMap.h */; };
-               5540775918DA58AD00EFF7F2 /* JSMapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF90182D991400522C22 /* JSMapIterator.h */; };
-               5540775B18DA58AD00EFF7F2 /* JSNameScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 14874AE015EBDE4A002E3587 /* JSNameScope.h */; };
-               5540775C18DA58AD00EFF7F2 /* JSObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC22A3990E16E14800AF21C8 /* JSObject.h */; };
-               5540775F18DA58AD00EFF7F2 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
-               5540776218DA58AD00EFF7F2 /* JSPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E1917BEDBD3007CB63A /* JSPromise.h */; };
-               5540776318DA58AD00EFF7F2 /* JSPromiseConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E2117BEE240007CB63A /* JSPromiseConstructor.h */; };
-               5540776418DA58AD00EFF7F2 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; };
-               5540776518DA58AD00EFF7F2 /* JSPromiseFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */; };
-               5540776618DA58AD00EFF7F2 /* JSPromisePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E1D17BEE22E007CB63A /* JSPromisePrototype.h */; };
-               5540776718DA58AD00EFF7F2 /* JSPromiseReaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CDD1871258D00955C24 /* JSPromiseReaction.h */; };
-               5540776818DA58AD00EFF7F2 /* JSProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 862553CF16136AA5009F17D0 /* JSProxy.h */; };
-               5540776B18DA58AD00EFF7F2 /* JSScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 14874AE215EBDE4A002E3587 /* JSScope.h */; };
-               5540776D18DA58AD00EFF7F2 /* JSSegmentedVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0F157F3327004A4E7D /* JSSegmentedVariableObject.h */; };
-               5540776E18DA58AD00EFF7F2 /* JSSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299D9C17D12837005F5FF9 /* JSSet.h */; };
-               5540776F18DA58AD00EFF7F2 /* JSSetIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD6A182F499700588807 /* JSSetIterator.h */; };
-               5540777118DA58AD00EFF7F2 /* JSStackInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C1EAEB17987AB600299DB2 /* JSStackInlines.h */; };
-               5540777218DA58AD00EFF7F2 /* JSString.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8620255597D01FF60F7 /* JSString.h */; };
-               5540777318DA58AD00EFF7F2 /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
-               5540777418DA58AD00EFF7F2 /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
-               5540777818DA58AD00EFF7F2 /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; };
-               5540777918DA58AD00EFF7F2 /* JSType.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB454099C2A0F00E2A24F /* JSType.h */; };
-               5540777A18DA58AD00EFF7F2 /* JSTypedArrayConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66CD17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h */; };
-               5540777B18DA58AD00EFF7F2 /* JSTypedArrayPrototypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66CF17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.h */; };
-               5540777C18DA58AD00EFF7F2 /* JSTypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D117B6B5AB00A7AE3F /* JSTypedArrays.h */; };
-               5540777D18DA58AD00EFF7F2 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; };
-               5540777E18DA58AD00EFF7F2 /* JSUint16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */; };
-               5540777F18DA58AD00EFF7F2 /* JSUint32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */; };
-               5540778018DA58AD00EFF7F2 /* JSUint8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */; };
-               5540778118DA58AD00EFF7F2 /* JSUint8ClampedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */; };
-               5540778518DA58AD00EFF7F2 /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; };
-               5540778818DA58AD00EFF7F2 /* JSWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3AE217DA41AE006538AF /* JSWeakMap.h */; };
-               5540778B18DA58AD00EFF7F2 /* JSWithScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 1442566015EDE98D0066A49B /* JSWithScope.h */; };
-               5540778D18DA58AD00EFF7F2 /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; };
-               5540779818DA58AD00EFF7F2 /* LiteralParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E2EA690FB460CF00601F06 /* LiteralParser.h */; };
-               554077A918DA58AD00EFF7F2 /* Lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* Lookup.h */; };
-               554077B718DA58AD00EFF7F2 /* MapConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A700873817CBE85300C3E643 /* MapConstructor.h */; };
-               554077B818DA58AD00EFF7F2 /* MapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A78507D517CBC6FD0011F6E7 /* MapData.h */; };
-               554077B918DA58AD00EFF7F2 /* MapIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF8C182D991400522C22 /* MapIteratorConstructor.h */; };
-               554077BA18DA58AD00EFF7F2 /* MapIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF8E182D991400522C22 /* MapIteratorPrototype.h */; };
-               554077BB18DA58AD00EFF7F2 /* MapPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A700873C17CBE8D300C3E643 /* MapPrototype.h */; };
-               554077C118DA58AD00EFF7F2 /* MatchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 8612E4CB1522918400C836BE /* MatchResult.h */; };
-               554077C218DA58AD00EFF7F2 /* MathObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86B0255597D01FF60F7 /* MathObject.h */; };
-               554077C318DA58AD00EFF7F2 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; };
-               554077C518DA58AD00EFF7F2 /* Microtask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CE5187631B600955C24 /* Microtask.h */; };
-               554077C718DA58AD00EFF7F2 /* NameConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FA1560F036008E9222 /* NameConstructor.h */; };
-               554077C818DA58AD00EFF7F2 /* NameInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FC1560F036008E9222 /* NameInstance.h */; };
-               554077C918DA58AD00EFF7F2 /* NamePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FE1560F036008E9222 /* NamePrototype.h */; };
-               554077CA18DA58AD00EFF7F2 /* NativeErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */; };
-               554077CB18DA58AD00EFF7F2 /* NativeErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E90B0E1839DB000F9297 /* NativeErrorPrototype.h */; };
-               554077D118DA58AD00EFF7F2 /* NumberConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C30E16D4E900A06E92 /* NumberConstructor.h */; };
-               554077D318DA58AD00EFF7F2 /* NumberObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8710255597D01FF60F7 /* NumberObject.h */; };
-               554077D418DA58AD00EFF7F2 /* NumberPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C50E16D4E900A06E92 /* NumberPrototype.h */; };
-               554077D618DA58AD00EFF7F2 /* NumericStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 142D3938103E4560007DCB52 /* NumericStrings.h */; };
-               554077DA18DA58AD00EFF7F2 /* ObjectConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */; };
-               554077DB18DA58AD00EFF7F2 /* ObjectPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */; };
-               554077E018DA58AD00EFF7F2 /* Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* Operations.h */; };
-               554077E118DA58AD00EFF7F2 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; };
-               554077EA18DA58AD00EFF7F2 /* PrivateName.h in Headers */ = {isa = PBXBuildFile; fileRef = 868916A9155F285400CB2B9A /* PrivateName.h */; };
-               554077FD18DA58AD00EFF7F2 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; };
-               554077FE18DA58AD00EFF7F2 /* PropertyMapHashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */; };
-               554077FF18DA58AD00EFF7F2 /* PropertyName.h in Headers */ = {isa = PBXBuildFile; fileRef = 86158AB2155C8B3F00B45C9C /* PropertyName.h */; };
-               5540780018DA58AD00EFF7F2 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; };
-               5540780118DA58AD00EFF7F2 /* PropertyOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */; };
-               5540780318DA58AD00EFF7F2 /* PropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* PropertySlot.h */; };
-               5540780418DA58AD00EFF7F2 /* PropertyStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */; };
-               5540780518DA58AD00EFF7F2 /* Protect.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C02FBB0637462A003E7EE6 /* Protect.h */; };
-               5540780618DA58AD00EFF7F2 /* PrototypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */; };
-               5540780818DA58AD00EFF7F2 /* PutDirectIndexMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */; };
-               5540780A18DA58AD00EFF7F2 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; };
-               5540780E18DA58AD00EFF7F2 /* RegExp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* RegExp.h */; };
-               5540780F18DA58AD00EFF7F2 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; };
-               5540781018DA58AD00EFF7F2 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
-               5540781218DA58AD00EFF7F2 /* RegExpKey.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B4011C7B235007A5315 /* RegExpKey.h */; };
-               5540781318DA58AD00EFF7F2 /* RegExpObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87C0255597D01FF60F7 /* RegExpObject.h */; };
-               5540781518DA58AD00EFF7F2 /* RegExpPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */; };
-               5540781918DA58AD00EFF7F2 /* RegisterPreservationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB81861244C00845D97 /* RegisterPreservationMode.h */; };
-               5540781D18DA58AD00EFF7F2 /* Reject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39115ED8E3800F167B2 /* Reject.h */; };
-               5540782618DA58AD00EFF7F2 /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; };
-               5540783318DA58AD00EFF7F2 /* SetConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299DA417D12858005F5FF9 /* SetConstructor.h */; };
-               5540783418DA58AD00EFF7F2 /* SetIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD66182F499700588807 /* SetIteratorConstructor.h */; };
-               5540783518DA58AD00EFF7F2 /* SetIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD68182F499700588807 /* SetIteratorPrototype.h */; };
-               5540783618DA58AD00EFF7F2 /* SetPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A7299DA017D12848005F5FF9 /* SetPrototype.h */; };
-               5540783818DA58AD00EFF7F2 /* SimpleTypedArrayController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D717B6B5AB00A7AE3F /* SimpleTypedArrayController.h */; };
-               5540783C18DA58AD00EFF7F2 /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; };
-               5540784118DA58AD00EFF7F2 /* SparseArrayValueMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */; };
-               5540784518DA58AD00EFF7F2 /* StackAlignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3AC751183EA1040032029F /* StackAlignment.h */; };
-               5540784918DA58AD00EFF7F2 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; };
-               5540784A18DA58AD00EFF7F2 /* StringConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C10E16EE3300B34460 /* StringConstructor.h */; };
-               5540784B18DA58AD00EFF7F2 /* StringObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C30E16EE3300B34460 /* StringObject.h */; };
-               5540784C18DA58AD00EFF7F2 /* StringPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C60E16EE3300B34460 /* StringPrototype.h */; };
-               5540784F18DA58AD00EFF7F2 /* Structure.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDE3AB10E6C82CF001453A7 /* Structure.h */; };
-               5540785018DA58AD00EFF7F2 /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; };
-               5540785118DA58AD00EFF7F2 /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; };
-               5540785218DA58AD00EFF7F2 /* StructureRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FE18A316BAEC4000AF3061 /* StructureRareData.h */; };
-               5540785318DA58AD00EFF7F2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; };
-               5540785718DA58AD00EFF7F2 /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; };
-               5540785918DA58AD00EFF7F2 /* SymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A396A60CD2933100B5B4FF /* SymbolTable.h */; };
-               5540785C18DA58AD00EFF7F2 /* TestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */; };
-               5540786018DA58AD00EFF7F2 /* ToNativeFromValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */; };
-               5540786118DA58AD00EFF7F2 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
-               5540786218DA58AD00EFF7F2 /* TypedArrayAdaptors.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66D817B6B5AB00A7AE3F /* TypedArrayAdaptors.h */; };
-               5540786318DA58AD00EFF7F2 /* TypedArrayController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DA17B6B5AB00A7AE3F /* TypedArrayController.h */; };
-               5540786418DA58AD00EFF7F2 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; };
-               5540786518DA58AD00EFF7F2 /* TypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */; };
-               5540786618DA58AD00EFF7F2 /* TypedArrayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */; };
-               5540786E18DA58AD00EFF7F2 /* Uint16Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */; };
-               5540786F18DA58AD00EFF7F2 /* Uint16WithFraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D113BFDE710023D87C /* Uint16WithFraction.h */; };
-               5540787018DA58AD00EFF7F2 /* Uint32Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */; };
-               5540787118DA58AD00EFF7F2 /* Uint8Array.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */; };
-               5540787218DA58AD00EFF7F2 /* Uint8ClampedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */; };
-               5540787A18DA58AD00EFF7F2 /* VM.h in Headers */ = {isa = PBXBuildFile; fileRef = E18E3A560DF9278C00D90B34 /* VM.h */; };
-               5540787B18DA58AD00EFF7F2 /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; };
-               5540787D18DA58AD00EFF7F2 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; };
-               5540788118DA58AD00EFF7F2 /* WeakGCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */; };
-               5540788518DA58AD00EFF7F2 /* WeakMapConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */; };
-               5540788618DA58AD00EFF7F2 /* WeakMapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3AEA17DA5168006538AF /* WeakMapData.h */; };
-               5540788718DA58AD00EFF7F2 /* WeakMapPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3AE017DA41AE006538AF /* WeakMapPrototype.h */; };
-               5540788818DA58AD00EFF7F2 /* WeakRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */; };
-               5540788D18DA58AD00EFF7F2 /* WriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DCB77912E3D90500911940 /* WriteBarrier.h */; };
-               5540788F18DA58AD00EFF7F2 /* WriteBarrierInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */; };
-               554078AB18DA58AD00EFF7F2 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; };
-               554078AF18DA58AD00EFF7F2 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; };
-               55407A3818DA58AD00EFF7F2 /* NumberConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */; };
-               55407A3A18DA58AD00EFF7F2 /* NumberPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C40E16D4E900A06E92 /* NumberPrototype.cpp */; };
+               52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */; };
+               52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */; };
+               52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */; };
+               52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FE1975B4240080857C /* TypeLocationCache.cpp */; };
+               52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */; };
+               52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
                5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
                5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
                5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 14D857740A4696C80032146C /* testapi.js */; };
                5DBB1525131D0BD70056AD36 /* minidom.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 1412110D0A48788700480255 /* minidom.js */; };
                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; };
+               62D2D38F1ADF103F000206C1 /* FunctionRareData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */; };
+               62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D2D38E1ADF103F000206C1 /* FunctionRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */; };
+               62F2AA381B0BEDE300610C7A /* DFGLazyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                651122FD14046A4C002B101D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
                651122FE14046A4C002B101D /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
                6511230714046B0A002B101D /* testRegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651122E5140469BA002B101D /* testRegExp.cpp */; };
                6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6514F21718B3E1670098FF8B /* Bytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65303D641447B9E100D3F904 /* ParserTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 65303D631447B9E100D3F904 /* ParserTokens.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               6546F5211A32B313006F07D5 /* NullGetterFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */; };
+               65525FC51A6DD801007B5495 /* NullSetterFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */; };
                6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6553A32F17A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp */; };
                6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6553A33017A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h */; };
+               65570F5A1AA4C3EA009B3C23 /* Regress141275.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65570F591AA4C00A009B3C23 /* Regress141275.mm */; };
                655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
+               657CF45819BF6662004ACBF2 /* JSCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 657CF45619BF6662004ACBF2 /* JSCallee.cpp */; };
+               657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = 657CF45719BF6662004ACBF2 /* JSCallee.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 658D3A5519638268003C45D6 /* VMEntryRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */; };
                65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; };
                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C0285B1717966800351E35 /* ARMv7DOpcode.h */; };
                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */; };
-               7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */; };
-               7C008CD3186F8A9300955C24 /* JSPromiseFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70113D4B1A8DB093003848C4 /* IteratorOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70113D491A8DB093003848C4 /* IteratorOperations.cpp */; };
+               70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 70113D4A1A8DB093003848C4 /* IteratorOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7013CA8B1B491A9400CAE613 /* JSJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7013CA891B491A9400CAE613 /* JSJob.cpp */; };
+               7013CA8C1B491A9400CAE613 /* JSJob.h in Headers */ = {isa = PBXBuildFile; fileRef = 7013CA8A1B491A9400CAE613 /* JSJob.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               705B41AB1A6E501E00716757 /* Symbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705B41A31A6E501E00716757 /* Symbol.cpp */; };
+               705B41AC1A6E501E00716757 /* Symbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 705B41A41A6E501E00716757 /* Symbol.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               705B41AD1A6E501E00716757 /* SymbolConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705B41A51A6E501E00716757 /* SymbolConstructor.cpp */; };
+               705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 705B41A61A6E501E00716757 /* SymbolConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               705B41AF1A6E501E00716757 /* SymbolObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705B41A71A6E501E00716757 /* SymbolObject.cpp */; };
+               705B41B01A6E501E00716757 /* SymbolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 705B41A81A6E501E00716757 /* SymbolObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               705B41B11A6E501E00716757 /* SymbolPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705B41A91A6E501E00716757 /* SymbolPrototype.cpp */; };
+               705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 705B41AA1A6E501E00716757 /* SymbolPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7094C4DE1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7094C4DC1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp */; };
+               7094C4DF1AE439530041A2EE /* BytecodeIntrinsicRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 7094C4DD1AE439530041A2EE /* BytecodeIntrinsicRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 709FB8611AE335C60039D069 /* JSWeakSet.cpp */; };
+               709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 709FB8621AE335C60039D069 /* JSWeakSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               709FB8691AE335C60039D069 /* WeakSetConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */; };
+               709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 709FB8641AE335C60039D069 /* WeakSetConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               709FB86B1AE335C60039D069 /* WeakSetPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 709FB8651AE335C60039D069 /* WeakSetPrototype.cpp */; };
+               709FB86C1AE335C60039D069 /* WeakSetPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 709FB8661AE335C60039D069 /* WeakSetPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70B0A9D11A9B66460001306A /* RuntimeFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 70B0A9D01A9B66200001306A /* RuntimeFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70DC3E091B2DF2C700054299 /* IteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70DC3E071B2DF2C700054299 /* IteratorPrototype.cpp */; };
+               70DC3E0A1B2DF2C700054299 /* IteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 70DC3E081B2DF2C700054299 /* IteratorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70EC0EC21AA0D7DA00B6AAFA /* JSStringIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */; };
+               70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70EC0EC61AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70EC0EC01AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp */; };
+               70EC0EC71AA0D7DA00B6AAFA /* StringIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 70EC0EC11AA0D7DA00B6AAFA /* StringIteratorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70ECA6051AFDBEA200449739 /* JSTemplateRegistryKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6001AFDBEA200449739 /* JSTemplateRegistryKey.cpp */; };
+               70ECA6061AFDBEA200449739 /* JSTemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6011AFDBEA200449739 /* JSTemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
+               70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
                7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               7C008CDE1871258D00955C24 /* JSPromiseReaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CDC1871258D00955C24 /* JSPromiseReaction.cpp */; };
-               7C008CDF1871258D00955C24 /* JSPromiseReaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CDD1871258D00955C24 /* JSPromiseReaction.h */; };
                7C008CE7187631B600955C24 /* Microtask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CE5187631B600955C24 /* Microtask.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C184E1A17BEDBD3007CB63A /* JSPromise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C184E1817BEDBD3007CB63A /* JSPromise.cpp */; };
                7C184E1B17BEDBD3007CB63A /* JSPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E1917BEDBD3007CB63A /* JSPromise.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C184E2317BEE240007CB63A /* JSPromiseConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C184E2117BEE240007CB63A /* JSPromiseConstructor.h */; };
                7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */; };
-               7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
                860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B7F12DBA33700A9FE7B /* YarrJIT.cpp */; };
                86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8012DBA33700A9FE7B /* YarrJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8112DBA33700A9FE7B /* YarrParser.h */; settings = {ATTRIBUTES = (); }; };
+               86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8112DBA33700A9FE7B /* YarrParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B8212DBA33700A9FE7B /* YarrPattern.cpp */; };
                86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8312DBA33700A9FE7B /* YarrPattern.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
                86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86E3C610167BAB87006D760A /* JSVirtualMachine.mm */; };
                86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
-               86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2F91560F036008E9222 /* NameConstructor.cpp */; };
-               86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FA1560F036008E9222 /* NameConstructor.h */; };
-               86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FB1560F036008E9222 /* NameInstance.cpp */; };
-               86EBF3021560F06A008E9222 /* NameInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FC1560F036008E9222 /* NameInstance.h */; };
-               86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FD1560F036008E9222 /* NamePrototype.cpp */; };
-               86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FE1560F036008E9222 /* NamePrototype.h */; };
                86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */; };
                86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
                9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9928FF3918AC4AEC00B8CF12 /* JSReplayInputs.cpp */; };
                9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 9928FF3A18AC4AEC00B8CF12 /* JSReplayInputs.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               996231E918D1804200C03FDA /* InspectorJSBackendCommands.js in Headers */ = {isa = PBXBuildFile; fileRef = A53243961856A475002ED692 /* InspectorJSBackendCommands.js */; settings = {ATTRIBUTES = (Private, ); }; };
+               996231E918D1804200C03FDA /* InspectorBackendCommands.js in Headers */ = {isa = PBXBuildFile; fileRef = A53243961856A475002ED692 /* InspectorBackendCommands.js */; settings = {ATTRIBUTES = (Private, ); }; };
                99CC0B6218BE9946006CEBCC /* CodeGeneratorReplayInputsTemplates.py in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1E18A1B1E70026D88F /* CodeGeneratorReplayInputsTemplates.py */; settings = {ATTRIBUTES = (Private, ); }; };
                99CC0B6318BE9950006CEBCC /* CodeGeneratorReplayInputs.py in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1D18A1B1E70026D88F /* CodeGeneratorReplayInputs.py */; settings = {ATTRIBUTES = (Private, ); }; };
                99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1F18A1B2590026D88F /* EmptyInputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2118A1B2590026D88F /* EncodedValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                99E45A2718A1B2590026D88F /* InputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2218A1B2590026D88F /* InputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2318A1B2590026D88F /* NondeterministicInput.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
+               9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC51805E75500472CE4 /* InitializeLLVMPOSIX.cpp */; };
+               9E72940B190F0514001A91B5 /* BundlePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E72940A190F0514001A91B5 /* BundlePath.h */; };
+               9EA5C7A1190F084200508EBE /* BundlePath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9E729409190F0306001A91B5 /* BundlePath.mm */; };
+               9EA5C7A2190F088700508EBE /* InitializeLLVMMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9EA5C7A0190F05D200508EBE /* InitializeLLVMMac.cpp */; };
+               A12BBFF21B044A8B00664B69 /* IntlObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A12BBFF11B044A8B00664B69 /* IntlObject.h */; };
+               A12BBFF41B044A9800664B69 /* IntlObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A12BBFF31B044A9800664B69 /* IntlObject.cpp */; };
                A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1712B3A11C7B212007A5315 /* RegExpCache.cpp */; };
                A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B4011C7B235007A5315 /* RegExpKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A513E5CB185F9624007E95AD /* InjectedScriptManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A513E5C9185F9624007E95AD /* InjectedScriptManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A514B2C0185A684400F3C7CB /* InjectedScriptBase.cpp */; };
                A514B2C3185A684400F3C7CB /* InjectedScriptBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A514B2C1185A684400F3C7CB /* InjectedScriptBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A532438718568335002ED692 /* InspectorJSBackendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438118568317002ED692 /* InspectorJSBackendDispatchers.cpp */; };
-               A532438818568335002ED692 /* InspectorJSBackendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438218568317002ED692 /* InspectorJSBackendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A532438918568335002ED692 /* InspectorJSFrontendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438318568317002ED692 /* InspectorJSFrontendDispatchers.cpp */; };
-               A532438A18568335002ED692 /* InspectorJSFrontendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438418568317002ED692 /* InspectorJSFrontendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A532438B18568335002ED692 /* InspectorJSTypeBuilders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438518568317002ED692 /* InspectorJSTypeBuilders.cpp */; };
-               A532438C18568335002ED692 /* InspectorJSTypeBuilders.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438618568317002ED692 /* InspectorJSTypeBuilders.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */ = {isa = PBXBuildFile; fileRef = A532438F185696E6002ED692 /* CodeGeneratorInspector.py */; settings = {ATTRIBUTES = (Private, ); }; };
-               A532439318569709002ED692 /* CodeGeneratorInspectorStrings.py in Headers */ = {isa = PBXBuildFile; fileRef = A5324390185696E6002ED692 /* CodeGeneratorInspectorStrings.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A532438718568335002ED692 /* InspectorBackendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438118568317002ED692 /* InspectorBackendDispatchers.cpp */; };
+               A532438818568335002ED692 /* InspectorBackendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438218568317002ED692 /* InspectorBackendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A532438918568335002ED692 /* InspectorFrontendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438318568317002ED692 /* InspectorFrontendDispatchers.cpp */; };
+               A532438A18568335002ED692 /* InspectorFrontendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438418568317002ED692 /* InspectorFrontendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A532438B18568335002ED692 /* InspectorProtocolObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438518568317002ED692 /* InspectorProtocolObjects.cpp */; };
+               A532438C18568335002ED692 /* InspectorProtocolObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438618568317002ED692 /* InspectorProtocolObjects.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A532439418569709002ED692 /* generate-combined-inspector-json.py in Headers */ = {isa = PBXBuildFile; fileRef = A5324391185696E6002ED692 /* generate-combined-inspector-json.py */; settings = {ATTRIBUTES = (Private, ); }; };
-               A53243981856A489002ED692 /* InspectorJS.json in Headers */ = {isa = PBXBuildFile; fileRef = A53243951856A475002ED692 /* InspectorJS.json */; settings = {ATTRIBUTES = (Private, ); }; };
+               A53243981856A489002ED692 /* CombinedDomains.json in Headers */ = {isa = PBXBuildFile; fileRef = A53243951856A475002ED692 /* CombinedDomains.json */; settings = {ATTRIBUTES = (Private, ); }; };
                A53CE08518BC1A5600BEDF76 /* ConsolePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */; };
                A53CE08618BC1A5600BEDF76 /* ConsolePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */; };
                A53CE08718BC1A5600BEDF76 /* JSConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53CE08318BC1A5600BEDF76 /* JSConsole.cpp */; };
                A54CF2FA184EAEDA00237F19 /* ScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A54CF2F8184EAEDA00237F19 /* ScriptObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A54E8EB118BFFBBE00556D28 /* GCSegmentedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A552C37F1ADDB8FE00139726 /* JSRemoteInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A552C37D1ADDB8FE00139726 /* JSRemoteInspector.cpp */; };
+               A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = A552C37E1ADDB8FE00139726 /* JSRemoteInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A55D93A5185012A800400DED /* ScriptFunctionCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A55D93A3185012A800400DED /* ScriptFunctionCall.cpp */; };
                A55D93A6185012A800400DED /* ScriptFunctionCall.h in Headers */ = {isa = PBXBuildFile; fileRef = A55D93A4185012A800400DED /* ScriptFunctionCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A55D93AC18514F7900400DED /* InspectorTypeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A55D93AB18514F7900400DED /* InspectorTypeBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A55D93AC18514F7900400DED /* InspectorProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A55D93AB18514F7900400DED /* InspectorProtocolTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A57D23E51890CEBF0031C7FA /* InspectorDebuggerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A57D23E31890CEBF0031C7FA /* InspectorDebuggerAgent.cpp */; };
                A57D23E61890CEBF0031C7FA /* InspectorDebuggerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = A57D23E41890CEBF0031C7FA /* InspectorDebuggerAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A57D23E91891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A57D23E71891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp */; };
                A5BA15ED182340B400A82E69 /* RemoteInspectorXPCConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = A5BA15E6182340B300A82E69 /* RemoteInspectorXPCConnection.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5BA15EE182340B400A82E69 /* RemoteInspectorXPCConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5BA15E7182340B300A82E69 /* RemoteInspectorXPCConnection.mm */; };
                A5BA15F0182345AF00A82E69 /* RemoteInspectorDebuggable.h in Headers */ = {isa = PBXBuildFile; fileRef = A5BA15EF182345AF00A82E69 /* RemoteInspectorDebuggable.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A5C3A1A518C0490200C9593A /* JSConsoleClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5C3A1A318C0490200C9593A /* JSConsoleClient.cpp */; };
-               A5C3A1A618C0490200C9593A /* JSConsoleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A5C3A1A418C0490200C9593A /* JSConsoleClient.h */; };
+               A5C3A1A518C0490200C9593A /* JSGlobalObjectConsoleClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5C3A1A318C0490200C9593A /* JSGlobalObjectConsoleClient.cpp */; };
+               A5C3A1A618C0490200C9593A /* JSGlobalObjectConsoleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A5C3A1A418C0490200C9593A /* JSGlobalObjectConsoleClient.h */; };
                A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5CEEE12187F3BAD00E55C99 /* InspectorAgent.cpp */; };
                A5D0A1BB1862301B00C7B496 /* InspectorEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A5D0A1BA1862301B00C7B496 /* InspectorEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A5D2E664195E173800A518E7 /* JSContextRefInternal.h */; };
+               A5EA70E719F5B1010098F5EC /* AugmentableInspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70E419F5B1010098F5EC /* AugmentableInspectorController.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA70E819F5B1010098F5EC /* AugmentableInspectorControllerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70E519F5B1010098F5EC /* AugmentableInspectorControllerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70E619F5B1010098F5EC /* AlternateDispatchableAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA70EC19F5B3EA0098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70EA19F5B3D50098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70ED19F5B5C40098F5EC /* JSContextRefInspectorSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710319F6DE6F0098F5EC /* generate_objc_backend_dispatcher_header.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70EF19F6DE5A0098F5EC /* generate_objc_backend_dispatcher_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710419F6DE720098F5EC /* generate_objc_backend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F019F6DE5A0098F5EC /* generate_objc_backend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710519F6DE740098F5EC /* generate_objc_configuration_header.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F119F6DE5A0098F5EC /* generate_objc_configuration_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710619F6DE760098F5EC /* generate_objc_configuration_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F219F6DE5A0098F5EC /* generate_objc_configuration_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710719F6DE780098F5EC /* generate_objc_conversion_helpers.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F319F6DE5A0098F5EC /* generate_objc_conversion_helpers.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710819F6DE7A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F419F6DE5A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710919F6DE7C0098F5EC /* generate_objc_header.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F519F6DE5A0098F5EC /* generate_objc_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710A19F6DE7E0098F5EC /* generate_objc_internal_header.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F619F6DE5A0098F5EC /* generate_objc_internal_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710C19F6DE820098F5EC /* objc_generator.py in Headers */ = {isa = PBXBuildFile; fileRef = A5EA70F819F6DE5A0098F5EC /* objc_generator.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EA710E19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EA710D19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D11A05C76F005CAB76 /* generate_cpp_backend_dispatcher_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B151A1D43FA00702E90 /* generate_cpp_backend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D21A05C76F005CAB76 /* generate_cpp_backend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B161A1D440000702E90 /* generate_cpp_frontend_dispatcher_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D31A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B171A1D440300702E90 /* generate_cpp_frontend_dispatcher_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D41A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D51A05C76F005CAB76 /* generate_cpp_protocol_types_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D61A05C76F005CAB76 /* generate_cpp_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
                A5FD0067189AFE9C00633231 /* ScriptArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */; };
                A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = A5FD0066189AFE9C00633231 /* ScriptArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5FD006D189B00AA00633231 /* ScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */; };
                A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = A704D90217A0BAA8006BA554 /* DFGMergeMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */ = {isa = PBXBuildFile; fileRef = A709F2EF17A0AC0400512E98 /* SlowPathCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A709F2F217A0AC2A00512E98 /* CommonSlowPaths.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A709F2F117A0AC2A00512E98 /* CommonSlowPaths.cpp */; };
-               A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A70B083017A0B79B00DAF14B /* DFGBinarySwitch.cpp */; };
-               A70B083317A0B79B00DAF14B /* DFGBinarySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */; };
                A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */; };
                A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */; };
                A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B51797601E0098028C /* JSCTestRunnerUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B91797603D0098028C /* JSFunctionInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
                A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
-               A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A729009C17976C6000317298 /* MacroAssemblerARMv7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */; };
                A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7299D9B17D12837005F5FF9 /* JSSet.cpp */; };
                A7386556118697B400540279 /* ThunkGenerators.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386553118697B400540279 /* ThunkGenerators.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */; };
                A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */; };
-               A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
                A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */; };
-               A74DEF91182D991400522C22 /* MapIteratorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DEF8B182D991400522C22 /* MapIteratorConstructor.cpp */; };
-               A74DEF92182D991400522C22 /* MapIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF8C182D991400522C22 /* MapIteratorConstructor.h */; };
                A74DEF93182D991400522C22 /* MapIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DEF8D182D991400522C22 /* MapIteratorPrototype.cpp */; };
                A74DEF94182D991400522C22 /* MapIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF8E182D991400522C22 /* MapIteratorPrototype.h */; };
                A74DEF95182D991400522C22 /* JSMapIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DEF8F182D991400522C22 /* JSMapIterator.cpp */; };
-               A74DEF96182D991400522C22 /* JSMapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF90182D991400522C22 /* JSMapIterator.h */; };
+               A74DEF96182D991400522C22 /* JSMapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A74DEF90182D991400522C22 /* JSMapIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */; };
                A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */ = {isa = PBXBuildFile; fileRef = A75EE9B018AAB7E200AAD043 /* BuiltinNames.h */; };
-               A76140CD182982CB00750624 /* ArgumentsIteratorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A76140C7182982CB00750624 /* ArgumentsIteratorConstructor.cpp */; };
-               A76140CE182982CB00750624 /* ArgumentsIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */; };
-               A76140CF182982CB00750624 /* ArgumentsIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */; };
-               A76140D0182982CB00750624 /* ArgumentsIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */; };
-               A76140D1182982CB00750624 /* JSArgumentsIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A76140CB182982CB00750624 /* JSArgumentsIterator.cpp */; };
-               A76140D2182982CB00750624 /* JSArgumentsIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A76140CC182982CB00750624 /* JSArgumentsIterator.h */; };
                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A767B5B517A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A767B5B317A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp */; };
                A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = A767B5B417A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A77F1825164192C700640A47 /* ParserModes.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F18241641925400640A47 /* ParserModes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A78507D617CBC6FD0011F6E7 /* MapData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78507D417CBC6FD0011F6E7 /* MapData.cpp */; };
                A78507D717CBC6FD0011F6E7 /* MapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A78507D517CBC6FD0011F6E7 /* MapData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A785F6BC18C553FE00F10626 /* SpillRegistersMode.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FF647A18C52E8500B55307 /* SpillRegistersMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A78853F917972629001440E4 /* IntendedStructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78853F717972629001440E4 /* IntendedStructureChain.cpp */; };
                A78A977F179738D5009DF744 /* FTLGeneratedFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A977C179738D5009DF744 /* FTLGeneratedFunction.h */; };
                A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A78A977D179738D5009DF744 /* FTLJITFinalizer.cpp */; };
                A78A9781179738D5009DF744 /* FTLJITFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A78A977E179738D5009DF744 /* FTLJITFinalizer.h */; };
-               A790DD6B182F499700588807 /* SetIteratorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A790DD65182F499700588807 /* SetIteratorConstructor.cpp */; };
-               A790DD6C182F499700588807 /* SetIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD66182F499700588807 /* SetIteratorConstructor.h */; };
                A790DD6D182F499700588807 /* SetIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A790DD67182F499700588807 /* SetIteratorPrototype.cpp */; };
                A790DD6E182F499700588807 /* SetIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD68182F499700588807 /* SetIteratorPrototype.h */; };
                A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A790DD69182F499700588807 /* JSSetIterator.cpp */; };
-               A790DD70182F499700588807 /* JSSetIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD6A182F499700588807 /* JSSetIterator.h */; };
+               A790DD70182F499700588807 /* JSSetIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A790DD6A182F499700588807 /* JSSetIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7986D5717A0BB1E00A95DD0 /* DFGEdgeUsesStructure.h in Headers */ = {isa = PBXBuildFile; fileRef = A7986D5617A0BB1E00A95DD0 /* DFGEdgeUsesStructure.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7A4AE0817973B26005612B1 /* MacroAssemblerX86Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A4AE0717973B26005612B1 /* MacroAssemblerX86Common.cpp */; };
                A7A4AE1017973B4D005612B1 /* JITStubsX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */; };
                A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */; };
                A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A7BDAEC617F4EA1400F6140C /* ArrayIteratorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC017F4EA1400F6140C /* ArrayIteratorConstructor.cpp */; };
-               A7BDAEC717F4EA1400F6140C /* ArrayIteratorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC117F4EA1400F6140C /* ArrayIteratorConstructor.h */; };
                A7BDAEC817F4EA1400F6140C /* ArrayIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */; };
                A7BDAEC917F4EA1400F6140C /* ArrayIteratorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC317F4EA1400F6140C /* ArrayIteratorPrototype.h */; };
                A7BDAECA17F4EA1400F6140C /* JSArrayIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */; };
                A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
+               AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
                B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */; };
                BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */; settings = {ATTRIBUTES = (Public, ); }; };
                BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
                BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */; };
-               BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; settings = {ATTRIBUTES = (); }; };
+               BC18C4160E16F5CD00B34460 /* JSLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSLexicalEnvironment.h */; settings = {ATTRIBUTES = (); }; };
                BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 938772E5038BFE19008635CE /* JSArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 142711380A460BBB0080EEEA /* JSBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
                BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F8AC0A508D200005F061 /* JSCallbackConstructor.h */; };
                BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB454099C2A0F00E2A24F /* JSType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB36E099C076400E2A24F /* JSCJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B6EA0A4300B300517CFC /* JSValueRef.h */; settings = {ATTRIBUTES = (Public, ); }; };
-               BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSEnvironmentRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8660255597D01FF60F7 /* Lexer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* Lookup.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A396A60CD2933100B5B4FF /* SymbolTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; };
                BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */; };
-               BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */; };
                BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* Lexer.lut.h */; };
-               BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; };
                BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3135620F302FA3003DFD3A /* DebuggerActivation.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */; };
                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
                BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC87CDB810712ACA000614CF /* JSONObject.lut.h */; };
                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C20328201981979D0088B499 /* CustomGlobalObjectClassTest.c in Sources */ = {isa = PBXBuildFile; fileRef = C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */; };
-               C20B25991706536200C21F4E /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = C20B25981706536200C21F4E /* Region.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; };
                C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C0F7CC17BBFC5B00464FE4 /* DFGDesiredTransitions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */; };
                C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */; };
                C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DA778218E259990066FCB6 /* HeapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */; };
-               C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DF442E1707AC0100A5CA96 /* SuperRegion.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2E526BB1590EF000054E48D /* HeapTimer.cpp */; };
                C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = C2E526BC1590EF000054E48D /* HeapTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAA3F8149A830800FCE112 /* CopiedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */; };
                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FE18A316BAEC4000AF3061 /* StructureRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */ = {isa = PBXBuildFile; fileRef = 9928FF3D18AC4B1C00B8CF12 /* JSInputs.json */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4703CC0192844960013FBEA /* generate-inspector-protocol-bindings.py in Headers */ = {isa = PBXBuildFile; fileRef = C4703CBF192844960013FBEA /* generate-inspector-protocol-bindings.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4703CCE192844CC0013FBEA /* generate_js_backend_commands.py in Headers */ = {isa = PBXBuildFile; fileRef = C4703CC3192844CC0013FBEA /* generate_js_backend_commands.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4703CD5192844CC0013FBEA /* generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4703CCA192844CC0013FBEA /* generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4703CD6192844CC0013FBEA /* generator.py in Headers */ = {isa = PBXBuildFile; fileRef = C4703CCB192844CC0013FBEA /* generator.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4703CD7192844CC0013FBEA /* models.py in Headers */ = {isa = PBXBuildFile; fileRef = C4703CCC192844CC0013FBEA /* models.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6CF1A05C76F005CAB76 /* cpp_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D01A05C76F005CAB76 /* cpp_generator.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
-               E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
                E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* VM.cpp */; };
                E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; };
                E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */; };
+               FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; };
+               FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1C0FFC1B193E9800B53FCA /* Exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE1C0FFF1B194FD100B53FCA /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1C0FFE1B194FD100B53FCA /* Exception.cpp */; };
                FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
-               FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */; };
+               FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE384EE71ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE384EE31ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp */; };
+               FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE41ADDB7AD0055DE2C /* JSDollarVMPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
+               FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
+               FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4D55B71AE716CA0052E459 /* IterationStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5068641AE246390009DAB7 /* DeferredSourceDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */; };
                FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
+               FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEB51F6B1A97B688001F921C /* Regress141809.mm */; };
                FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */; };
+               FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
                FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835A174343CC00A32E25 /* JITStubsARM.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEF6835F174343CC00A32E25 /* JITStubsARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEF68360174343CC00A32E25 /* JITStubsX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */; settings = {ATTRIBUTES = (Private, ); }; };
                        remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
                        remoteInfo = "LLInt Offsets";
                };
-               5540756418DA58AD00EFF7F2 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 0FCEFAB51805D61600472CE4;
-                       remoteInfo = llvmForJSC;
-               };
-               5540756618DA58AD00EFF7F2 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 65788A9D18B409EB00C189FF;
-                       remoteInfo = "Offline Assembler";
-               };
-               5540756818DA58AD00EFF7F2 /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 65FB3F6609D11E9100F49DEB;
-                       remoteInfo = "Generate Derived Sources";
-               };
-               55F8FC2B18EB937B00783E6E /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 5540756218DA58AD00EFF7F2;
-                       remoteInfo = CompileRuntimeToLLVMIR;
-               };
                5D69E911152BE5470028D720 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+               0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueStrength.cpp; path = dfg/DFGValueStrength.cpp; sourceTree = "<group>"; };
+               0F0123311944EA1B00843A0C /* DFGValueStrength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValueStrength.h; path = dfg/DFGValueStrength.h; sourceTree = "<group>"; };
                0F0332BF18ADFAE1005F979A /* ExitingJITType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitingJITType.cpp; sourceTree = "<group>"; };
                0F0332C118B01763005F979A /* GetByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetByIdVariant.cpp; sourceTree = "<group>"; };
                0F0332C218B01763005F979A /* GetByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetByIdVariant.h; sourceTree = "<group>"; };
                0F0332C518B53FA9005F979A /* FTLWeight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLWeight.h; path = ftl/FTLWeight.h; sourceTree = "<group>"; };
                0F0332C718B546EC005F979A /* FTLWeightedTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLWeightedTarget.h; path = ftl/FTLWeightedTarget.h; sourceTree = "<group>"; };
+               0F04396B1B03DC0B009598B7 /* DFGCombinedLiveness.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCombinedLiveness.cpp; path = dfg/DFGCombinedLiveness.cpp; sourceTree = "<group>"; };
+               0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCombinedLiveness.h; path = dfg/DFGCombinedLiveness.h; sourceTree = "<group>"; };
                0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayifySlowPathGenerator.h; path = dfg/DFGArrayifySlowPathGenerator.h; sourceTree = "<group>"; };
                0F0776BD14FF002800102332 /* JITCompilationEffort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCompilationEffort.h; sourceTree = "<group>"; };
                0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
                0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutDirectIndexMode.h; sourceTree = "<group>"; };
                0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SparseArrayValueMap.cpp; sourceTree = "<group>"; };
                0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
+               0F12DE0D1979D5FD0006FF4E /* ExceptionFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionFuzz.cpp; sourceTree = "<group>"; };
+               0F12DE0E1979D5FD0006FF4E /* ExceptionFuzz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionFuzz.h; sourceTree = "<group>"; };
                0F136D4B174AD69B0075B354 /* DeferGC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferGC.h; sourceTree = "<group>"; };
                0F13912416771C30009CCB07 /* ProfilerBytecodeSequence.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerBytecodeSequence.cpp; path = profiler/ProfilerBytecodeSequence.cpp; sourceTree = "<group>"; };
                0F13912516771C30009CCB07 /* ProfilerBytecodeSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerBytecodeSequence.h; path = profiler/ProfilerBytecodeSequence.h; sourceTree = "<group>"; };
                0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerProfiledBytecodes.h; path = profiler/ProfilerProfiledBytecodes.h; sourceTree = "<group>"; };
                0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
                0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
-               0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsSimplificationPhase.cpp; path = dfg/DFGArgumentsSimplificationPhase.cpp; sourceTree = "<group>"; };
-               0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsSimplificationPhase.h; path = dfg/DFGArgumentsSimplificationPhase.h; sourceTree = "<group>"; };
+               0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMinifiedGraph.cpp; path = dfg/DFGMinifiedGraph.cpp; sourceTree = "<group>"; };
                0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerJettisonReason.cpp; path = profiler/ProfilerJettisonReason.cpp; sourceTree = "<group>"; };
                0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerJettisonReason.h; path = profiler/ProfilerJettisonReason.h; sourceTree = "<group>"; };
                0F1DD84918A945BE0026F3FA /* JSCInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCInlines.h; sourceTree = "<group>"; };
                0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSlowPathGenerator.h; path = dfg/DFGSlowPathGenerator.h; sourceTree = "<group>"; };
                0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSilentRegisterSavePlan.h; path = dfg/DFGSilentRegisterSavePlan.h; sourceTree = "<group>"; };
                0F1FE51B1922A3BC006987C5 /* AbortReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbortReason.h; sourceTree = "<group>"; };
+               0F20C2581A8013AB00DA3229 /* VirtualRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VirtualRegister.cpp; sourceTree = "<group>"; };
                0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
                0F235BBD17178E1C00690C7F /* FTLExitArgument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitArgument.cpp; path = ftl/FTLExitArgument.cpp; sourceTree = "<group>"; };
                0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrays.h; sourceTree = "<group>"; };
                0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypedArrayType.cpp; sourceTree = "<group>"; };
                0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayType.h; sourceTree = "<group>"; };
+               0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailabilityMap.cpp; path = dfg/DFGAvailabilityMap.cpp; sourceTree = "<group>"; };
+               0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailabilityMap.h; path = dfg/DFGAvailabilityMap.h; sourceTree = "<group>"; };
+               0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInsertOSRHintsForUpdate.cpp; path = dfg/DFGInsertOSRHintsForUpdate.cpp; sourceTree = "<group>"; };
+               0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertOSRHintsForUpdate.h; path = dfg/DFGInsertOSRHintsForUpdate.h; sourceTree = "<group>"; };
+               0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectAllocationSinkingPhase.cpp; path = dfg/DFGObjectAllocationSinkingPhase.cpp; sourceTree = "<group>"; };
+               0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectAllocationSinkingPhase.h; path = dfg/DFGObjectAllocationSinkingPhase.h; sourceTree = "<group>"; };
+               0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectMaterializationData.cpp; path = dfg/DFGObjectMaterializationData.cpp; sourceTree = "<group>"; };
+               0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectMaterializationData.h; path = dfg/DFGObjectMaterializationData.h; sourceTree = "<group>"; };
+               0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhiChildren.cpp; path = dfg/DFGPhiChildren.cpp; sourceTree = "<group>"; };
+               0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhiChildren.h; path = dfg/DFGPhiChildren.h; sourceTree = "<group>"; };
+               0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPromotedHeapLocation.cpp; path = dfg/DFGPromotedHeapLocation.cpp; sourceTree = "<group>"; };
+               0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromotedHeapLocation.h; path = dfg/DFGPromotedHeapLocation.h; sourceTree = "<group>"; };
+               0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitPropertyValue.cpp; path = ftl/FTLExitPropertyValue.cpp; sourceTree = "<group>"; };
+               0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitPropertyValue.h; path = ftl/FTLExitPropertyValue.h; sourceTree = "<group>"; };
+               0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitTimeObjectMaterialization.cpp; path = ftl/FTLExitTimeObjectMaterialization.cpp; sourceTree = "<group>"; };
+               0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitTimeObjectMaterialization.h; path = ftl/FTLExitTimeObjectMaterialization.h; sourceTree = "<group>"; };
+               0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOperations.cpp; path = ftl/FTLOperations.cpp; sourceTree = "<group>"; };
+               0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOperations.h; path = ftl/FTLOperations.h; sourceTree = "<group>"; };
                0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = "<group>"; };
                0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFixupPhase.h; path = dfg/DFGFixupPhase.h; sourceTree = "<group>"; };
                0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertionSet.h; path = dfg/DFGInsertionSet.h; sourceTree = "<group>"; };
                0F2BDC2B151FDE8B00CD8910 /* Operands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Operands.h; sourceTree = "<group>"; };
                0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedGraph.h; path = dfg/DFGMinifiedGraph.h; sourceTree = "<group>"; };
                0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedNode.h; path = dfg/DFGMinifiedNode.h; sourceTree = "<group>"; };
-               0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValueRecoveryOverride.h; path = dfg/DFGValueRecoveryOverride.h; sourceTree = "<group>"; };
                0F2BDC401522801700CD8910 /* DFGValueSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValueSource.h; path = dfg/DFGValueSource.h; sourceTree = "<group>"; };
                0F2BDC411522801700CD8910 /* DFGVariableEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableEvent.h; path = dfg/DFGVariableEvent.h; sourceTree = "<group>"; };
                0F2BDC421522801700CD8910 /* DFGVariableEventStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableEventStream.cpp; path = dfg/DFGVariableEventStream.cpp; sourceTree = "<group>"; };
                0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMinifiedNode.cpp; path = dfg/DFGMinifiedNode.cpp; sourceTree = "<group>"; };
                0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueSource.cpp; path = dfg/DFGValueSource.cpp; sourceTree = "<group>"; };
                0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableEvent.cpp; path = dfg/DFGVariableEvent.cpp; sourceTree = "<group>"; };
+               0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerScope.cpp; sourceTree = "<group>"; };
+               0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerScope.h; sourceTree = "<group>"; };
+               0F2D4DDF19832D91007D4B19 /* TypeProfilerLog.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfilerLog.cpp; sourceTree = "<group>"; };
+               0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfilerLog.h; sourceTree = "<group>"; };
+               0F2D4DE319832D91007D4B19 /* TypeSet.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeSet.cpp; sourceTree = "<group>"; };
+               0F2D4DE419832D91007D4B19 /* TypeSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeSet.h; sourceTree = "<group>"; };
+               0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToThisStatus.cpp; sourceTree = "<group>"; };
+               0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToThisStatus.h; sourceTree = "<group>"; };
+               0F2D4DE719832DAC007D4B19 /* TypeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = "<group>"; };
+               0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeKills.h; sourceTree = "<group>"; };
+               0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsEliminationPhase.cpp; path = dfg/DFGArgumentsEliminationPhase.cpp; sourceTree = "<group>"; };
+               0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsEliminationPhase.h; path = dfg/DFGArgumentsEliminationPhase.h; sourceTree = "<group>"; };
+               0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsUtilities.cpp; path = dfg/DFGArgumentsUtilities.cpp; sourceTree = "<group>"; };
+               0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsUtilities.h; path = dfg/DFGArgumentsUtilities.h; sourceTree = "<group>"; };
+               0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGForAllKills.h; path = dfg/DFGForAllKills.h; sourceTree = "<group>"; };
                0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDCEPhase.cpp; path = dfg/DFGDCEPhase.cpp; sourceTree = "<group>"; };
                0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDCEPhase.h; path = dfg/DFGDCEPhase.h; sourceTree = "<group>"; };
                0F2FCCF218A60070001A27F8 /* DFGGraphSafepoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGGraphSafepoint.cpp; path = dfg/DFGGraphSafepoint.cpp; sourceTree = "<group>"; };
                0F38B01417CFE75500B144D3 /* DFGCompilationKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCompilationKey.h; path = dfg/DFGCompilationKey.h; sourceTree = "<group>"; };
                0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationMode.cpp; path = dfg/DFGCompilationMode.cpp; sourceTree = "<group>"; };
                0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCompilationMode.h; path = dfg/DFGCompilationMode.h; sourceTree = "<group>"; };
+               0F392C871B46188400844728 /* DFGOSRExitFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitFuzz.cpp; path = dfg/DFGOSRExitFuzz.cpp; sourceTree = "<group>"; };
+               0F392C881B46188400844728 /* DFGOSRExitFuzz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitFuzz.h; path = dfg/DFGOSRExitFuzz.h; sourceTree = "<group>"; };
+               0F3A1BF71A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPutStackSinkingPhase.cpp; path = dfg/DFGPutStackSinkingPhase.cpp; sourceTree = "<group>"; };
+               0F3A1BF81A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPutStackSinkingPhase.h; path = dfg/DFGPutStackSinkingPhase.h; sourceTree = "<group>"; };
                0F3AC751183EA1040032029F /* StackAlignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackAlignment.h; sourceTree = "<group>"; };
                0F3AC753188E5EC80032029F /* ExitingJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExitingJITType.h; sourceTree = "<group>"; };
                0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantFoldingPhase.cpp; path = dfg/DFGConstantFoldingPhase.cpp; sourceTree = "<group>"; };
                0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFGSimplificationPhase.h; path = dfg/DFGCFGSimplificationPhase.h; sourceTree = "<group>"; };
                0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValidate.cpp; path = dfg/DFGValidate.cpp; sourceTree = "<group>"; };
                0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValidate.h; path = dfg/DFGValidate.h; sourceTree = "<group>"; };
+               0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallVariant.cpp; sourceTree = "<group>"; };
+               0F3B7E2519A11B8000D9BC56 /* CallVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallVariant.h; sourceTree = "<group>"; };
+               0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = "<group>"; };
+               0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = "<group>"; };
+               0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPrePostNumbering.cpp; path = dfg/DFGPrePostNumbering.cpp; sourceTree = "<group>"; };
+               0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPrePostNumbering.h; path = dfg/DFGPrePostNumbering.h; sourceTree = "<group>"; };
                0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
                0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
                0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
                0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicGetByIdList.h; sourceTree = "<group>"; };
                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
+               0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; };
                0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; };
                0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; };
                0F55989717C86C5600A1E543 /* ToNativeFromValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToNativeFromValue.h; sourceTree = "<group>"; };
                0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionCounter.cpp; sourceTree = "<group>"; };
                0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerator.h; sourceTree = "<group>"; };
                0F5780A118FE1E98001E72D9 /* PureNaN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PureNaN.h; sourceTree = "<group>"; };
+               0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMayExit.cpp; path = dfg/DFGMayExit.cpp; sourceTree = "<group>"; };
+               0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMayExit.h; path = dfg/DFGMayExit.h; sourceTree = "<group>"; };
+               0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDoesGC.cpp; path = dfg/DFGDoesGC.cpp; sourceTree = "<group>"; };
+               0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDoesGC.h; path = dfg/DFGDoesGC.h; sourceTree = "<group>"; };
                0F5A52CF17ADD717008ECB2D /* CopyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyToken.h; sourceTree = "<group>"; };
                0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueRange.cpp; path = ftl/FTLValueRange.cpp; sourceTree = "<group>"; };
                0F5A6282188C98D40072C9DF /* FTLValueRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueRange.h; path = ftl/FTLValueRange.h; sourceTree = "<group>"; };
                0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
                0F620170143FCD2F0068B77C /* DFGBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlock.h; path = dfg/DFGBasicBlock.h; sourceTree = "<group>"; };
                0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessData.h; path = dfg/DFGVariableAccessData.h; sourceTree = "<group>"; };
+               0F6237951AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomInsertionPhase.cpp; path = dfg/DFGPhantomInsertionPhase.cpp; sourceTree = "<group>"; };
+               0F6237961AE45CA700D402EA /* DFGPhantomInsertionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomInsertionPhase.h; path = dfg/DFGPhantomInsertionPhase.h; sourceTree = "<group>"; };
                0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTypeCheckHoistingPhase.cpp; path = dfg/DFGTypeCheckHoistingPhase.cpp; sourceTree = "<group>"; };
                0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTypeCheckHoistingPhase.h; path = dfg/DFGTypeCheckHoistingPhase.h; sourceTree = "<group>"; };
                0F63945115D07051006A597C /* ArrayProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayProfile.cpp; sourceTree = "<group>"; };
                0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureAbstractValue.h; path = dfg/DFGStructureAbstractValue.h; sourceTree = "<group>"; };
                0F63948115E48114006A597C /* DFGArrayMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArrayMode.cpp; path = dfg/DFGArrayMode.cpp; sourceTree = "<group>"; };
                0F63948215E48114006A597C /* DFGArrayMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayMode.h; path = dfg/DFGArrayMode.h; sourceTree = "<group>"; };
+               0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BinarySwitch.cpp; sourceTree = "<group>"; };
+               0F64B2701A784BAF006E4E66 /* BinarySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BinarySwitch.h; sourceTree = "<group>"; };
+               0F64B2771A7957B2006E4E66 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = "<group>"; };
+               0F64B2781A7957B2006E4E66 /* CallEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdge.h; sourceTree = "<group>"; };
                0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysisInlines.h; sourceTree = "<group>"; };
                0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullBytecodeLiveness.h; sourceTree = "<group>"; };
                0F666EC21835672B00D017F1 /* DFGAvailability.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailability.cpp; path = dfg/DFGAvailability.cpp; sourceTree = "<group>"; };
                0F666EC31835672B00D017F1 /* DFGAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailability.h; path = dfg/DFGAvailability.h; sourceTree = "<group>"; };
-               0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGResurrectionForValidationPhase.cpp; path = dfg/DFGResurrectionForValidationPhase.cpp; sourceTree = "<group>"; };
-               0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGResurrectionForValidationPhase.h; path = dfg/DFGResurrectionForValidationPhase.h; sourceTree = "<group>"; };
                0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
                0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
+               0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSSACalculator.cpp; path = dfg/DFGSSACalculator.cpp; sourceTree = "<group>"; };
+               0F682FB119BCB36400FA3BAD /* DFGSSACalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSSACalculator.h; path = dfg/DFGSSACalculator.h; sourceTree = "<group>"; };
+               0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFrozenValue.cpp; path = dfg/DFGFrozenValue.cpp; sourceTree = "<group>"; };
+               0F69CC87193AC60A0045759E /* DFGFrozenValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFrozenValue.h; path = dfg/DFGFrozenValue.h; sourceTree = "<group>"; };
                0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJSCall.cpp; path = ftl/FTLJSCall.cpp; sourceTree = "<group>"; };
                0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJSCall.h; path = ftl/FTLJSCall.h; sourceTree = "<group>"; };
                0F6B1CB71861244C00845D97 /* ArityCheckMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckMode.h; sourceTree = "<group>"; };
                0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLUnwindInfo.h; path = ftl/FTLUnwindInfo.h; sourceTree = "<group>"; };
                0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArityCheckFailReturnThunks.cpp; sourceTree = "<group>"; };
                0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckFailReturnThunks.h; sourceTree = "<group>"; };
+               0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = "<group>"; };
+               0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = "<group>"; };
                0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = "<group>"; };
+               0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexGetStatus.cpp; sourceTree = "<group>"; };
+               0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComplexGetStatus.h; sourceTree = "<group>"; };
                0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompilerCommon.cpp; path = dfg/DFGOSRExitCompilerCommon.cpp; sourceTree = "<group>"; };
                0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilerCommon.h; path = dfg/DFGOSRExitCompilerCommon.h; sourceTree = "<group>"; };
                0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = "<group>"; };
                0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = "<group>"; };
-               0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClosureCallStubRoutine.cpp; sourceTree = "<group>"; };
-               0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClosureCallStubRoutine.h; sourceTree = "<group>"; };
                0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessorCallJITStubRoutine.cpp; sourceTree = "<group>"; };
                0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessorCallJITStubRoutine.h; sourceTree = "<group>"; };
                0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; };
                0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubClearingWatchpoint.h; sourceTree = "<group>"; };
                0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
                0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
+               0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureRegistrationPhase.cpp; path = dfg/DFGStructureRegistrationPhase.cpp; sourceTree = "<group>"; };
+               0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureRegistrationPhase.h; path = dfg/DFGStructureRegistrationPhase.h; sourceTree = "<group>"; };
                0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; };
                0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = "<group>"; };
                0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
                0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; };
                0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = "<group>"; };
+               0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureAbstractValue.cpp; path = dfg/DFGStructureAbstractValue.cpp; sourceTree = "<group>"; };
+               0F898F2F1B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGIntegerRangeOptimizationPhase.cpp; path = dfg/DFGIntegerRangeOptimizationPhase.cpp; sourceTree = "<group>"; };
+               0F898F301B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGIntegerRangeOptimizationPhase.h; path = dfg/DFGIntegerRangeOptimizationPhase.h; sourceTree = "<group>"; };
+               0F8F142F1ADF090100ED792C /* DFGEpoch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGEpoch.cpp; path = dfg/DFGEpoch.cpp; sourceTree = "<group>"; };
+               0F8F14301ADF090100ED792C /* DFGEpoch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEpoch.h; path = dfg/DFGEpoch.h; sourceTree = "<group>"; };
+               0F8F14311ADF090100ED792C /* DFGMovHintRemovalPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMovHintRemovalPhase.cpp; path = dfg/DFGMovHintRemovalPhase.cpp; sourceTree = "<group>"; };
+               0F8F14321ADF090100ED792C /* DFGMovHintRemovalPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMovHintRemovalPhase.h; path = dfg/DFGMovHintRemovalPhase.h; sourceTree = "<group>"; };
                0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLink.cpp; path = ftl/FTLLink.cpp; sourceTree = "<group>"; };
                0F8F2B94172E049E007DBDA5 /* FTLLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FTLLink.h; path = ftl/FTLLink.h; sourceTree = "<group>"; };
                0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredIdentifiers.cpp; path = dfg/DFGDesiredIdentifiers.cpp; sourceTree = "<group>"; };
                0F8F943F1667632D00D61971 /* CodeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeType.cpp; sourceTree = "<group>"; };
                0F8F94431667635200D61971 /* JITCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCode.cpp; sourceTree = "<group>"; };
                0F8F9445166764EE00D61971 /* CodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeOrigin.cpp; sourceTree = "<group>"; };
-               0F9181C618415CA50057B669 /* VariableWatchpointSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWatchpointSet.h; sourceTree = "<group>"; };
                0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSymbolTableObject.cpp; sourceTree = "<group>"; };
                0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSymbolTableObject.h; sourceTree = "<group>"; };
                0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObject.cpp; sourceTree = "<group>"; };
                0F93329B14CA7DC10085F3C6 /* StructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureSet.h; sourceTree = "<group>"; };
                0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PutByIdVariant.cpp; sourceTree = "<group>"; };
                0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutByIdVariant.h; sourceTree = "<group>"; };
+               0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackedReferences.cpp; sourceTree = "<group>"; };
+               0F952ABB1B487A7700C367C5 /* TrackedReferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackedReferences.h; sourceTree = "<group>"; };
                0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
                0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
                0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
+               0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantMode.cpp; sourceTree = "<group>"; };
                0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreciseJumpTargets.cpp; sourceTree = "<group>"; };
                0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargets.h; sourceTree = "<group>"; };
                0F9C5E5C18E35F5E00D431C3 /* FTLDWARFRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDWARFRegister.cpp; path = ftl/FTLDWARFRegister.cpp; sourceTree = "<group>"; };
                0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFlushedAt.h; path = dfg/DFGFlushedAt.h; sourceTree = "<group>"; };
                0F9D33981803ADB70073C2BC /* FTLStackMaps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLStackMaps.cpp; path = ftl/FTLStackMaps.cpp; sourceTree = "<group>"; };
                0F9D33991803ADB70073C2BC /* FTLStackMaps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLStackMaps.h; path = ftl/FTLStackMaps.h; sourceTree = "<group>"; };
+               0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCleanUpPhase.cpp; path = dfg/DFGCleanUpPhase.cpp; sourceTree = "<group>"; };
+               0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCleanUpPhase.h; path = dfg/DFGCleanUpPhase.h; sourceTree = "<group>"; };
+               0F9E32611B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStoreBarrierInsertionPhase.cpp; path = dfg/DFGStoreBarrierInsertionPhase.cpp; sourceTree = "<group>"; };
+               0F9E32621B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierInsertionPhase.h; path = dfg/DFGStoreBarrierInsertionPhase.h; sourceTree = "<group>"; };
                0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStackLayoutPhase.cpp; path = dfg/DFGStackLayoutPhase.cpp; sourceTree = "<group>"; };
                0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStackLayoutPhase.h; path = dfg/DFGStackLayoutPhase.h; sourceTree = "<group>"; };
                0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicPutByIdList.cpp; sourceTree = "<group>"; };
                0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = "<group>"; };
                0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = "<group>"; };
                0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = "<group>"; };
+               0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromoteHeapAccess.h; path = dfg/DFGPromoteHeapAccess.h; sourceTree = "<group>"; };
                0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
                0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
                0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = "<group>"; };
                0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineCacheGenerator.h; sourceTree = "<group>"; };
                0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapper.h; path = dfg/DFGInlineCacheWrapper.h; sourceTree = "<group>"; };
                0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInlineCacheWrapperInlines.h; path = dfg/DFGInlineCacheWrapperInlines.h; sourceTree = "<group>"; };
+               0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGHeapLocation.cpp; path = dfg/DFGHeapLocation.cpp; sourceTree = "<group>"; };
+               0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGHeapLocation.h; path = dfg/DFGHeapLocation.h; sourceTree = "<group>"; };
+               0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPureValue.cpp; path = dfg/DFGPureValue.cpp; sourceTree = "<group>"; };
+               0FB1765F196B8F9E0091052A /* DFGPureValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPureValue.h; path = dfg/DFGPureValue.h; sourceTree = "<group>"; };
+               0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = "<group>"; };
                0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; };
                0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = "<group>"; };
                0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = "<group>"; };
                0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGExitProfile.cpp; sourceTree = "<group>"; };
                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGExitProfile.h; sourceTree = "<group>"; };
                0FBD7E671447998F00481315 /* CodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeOrigin.h; sourceTree = "<group>"; };
+               0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallCreateDirectArgumentsSlowPathGenerator.h; path = dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h; sourceTree = "<group>"; };
                0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCPSRethreadingPhase.cpp; path = dfg/DFGCPSRethreadingPhase.cpp; sourceTree = "<group>"; };
                0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCPSRethreadingPhase.h; path = dfg/DFGCPSRethreadingPhase.h; sourceTree = "<group>"; };
                0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPredictionInjectionPhase.cpp; path = dfg/DFGPredictionInjectionPhase.cpp; sourceTree = "<group>"; };
                0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPredictionInjectionPhase.h; path = dfg/DFGPredictionInjectionPhase.h; sourceTree = "<group>"; };
                0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUnificationPhase.cpp; path = dfg/DFGUnificationPhase.cpp; sourceTree = "<group>"; };
                0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; };
+               0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockSet.cpp; path = dfg/DFGBlockSet.cpp; sourceTree = "<group>"; };
+               0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSetInlines.h; path = dfg/DFGBlockSetInlines.h; sourceTree = "<group>"; };
                0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = "<group>"; };
                0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompiler.h; path = dfg/DFGOSRExitCompiler.h; sourceTree = "<group>"; };
                0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler64.cpp; path = dfg/DFGOSRExitCompiler64.cpp; sourceTree = "<group>"; };
                0FC314101814559100033232 /* RegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterSet.h; sourceTree = "<group>"; };
                0FC314111814559100033232 /* TempRegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TempRegisterSet.cpp; sourceTree = "<group>"; };
                0FC3141418146D7000033232 /* RegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterSet.cpp; sourceTree = "<group>"; };
+               0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMap.h; path = dfg/DFGBlockMap.h; sourceTree = "<group>"; };
+               0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMapInlines.h; path = dfg/DFGBlockMapInlines.h; sourceTree = "<group>"; };
+               0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSet.h; path = dfg/DFGBlockSet.h; sourceTree = "<group>"; };
+               0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockWorklist.cpp; path = dfg/DFGBlockWorklist.cpp; sourceTree = "<group>"; };
+               0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockWorklist.h; path = dfg/DFGBlockWorklist.h; sourceTree = "<group>"; };
+               0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaiveDominators.cpp; path = dfg/DFGNaiveDominators.cpp; sourceTree = "<group>"; };
+               0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaiveDominators.h; path = dfg/DFGNaiveDominators.h; sourceTree = "<group>"; };
                0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; };
                0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; };
                0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; };
                0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
                0FC97F2F182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlockJettisoningWatchpoint.cpp; sourceTree = "<group>"; };
                0FC97F30182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockJettisoningWatchpoint.h; sourceTree = "<group>"; };
-               0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProfiledCodeBlockJettisoningWatchpoint.cpp; sourceTree = "<group>"; };
-               0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfiledCodeBlockJettisoningWatchpoint.h; sourceTree = "<group>"; };
                0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInvalidationPointInjectionPhase.cpp; path = dfg/DFGInvalidationPointInjectionPhase.cpp; sourceTree = "<group>"; };
                0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInvalidationPointInjectionPhase.h; path = dfg/DFGInvalidationPointInjectionPhase.h; sourceTree = "<group>"; };
                0FC97F3918202119002C9B26 /* DFGJumpReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJumpReplacement.cpp; path = dfg/DFGJumpReplacement.cpp; sourceTree = "<group>"; };
                0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSaveRestore.cpp; path = ftl/FTLSaveRestore.cpp; sourceTree = "<group>"; };
                0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSaveRestore.h; path = ftl/FTLSaveRestore.h; sourceTree = "<group>"; };
                0FCEFAAE1805CA6D00472CE4 /* InitializeLLVM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InitializeLLVM.h; path = llvm/InitializeLLVM.h; sourceTree = "<group>"; };
-               0FCEFAAF1805CA6D00472CE4 /* InitializeLLVMMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InitializeLLVMMac.mm; path = llvm/InitializeLLVMMac.mm; sourceTree = "<group>"; };
                0FCEFAB61805D61600472CE4 /* libllvmForJSC.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libllvmForJSC.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = LLVMForJSC.xcconfig; sourceTree = "<group>"; };
                0FCEFAC01805D94100472CE4 /* LLVMOverrides.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LLVMOverrides.cpp; sourceTree = "<group>"; };
                0FCEFADB18064A1400472CE4 /* config_llvm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_llvm.h; sourceTree = "<group>"; };
                0FCEFADD180738C000472CE4 /* FTLLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLocation.cpp; path = ftl/FTLLocation.cpp; sourceTree = "<group>"; };
                0FCEFADE180738C000472CE4 /* FTLLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLocation.h; path = ftl/FTLLocation.h; sourceTree = "<group>"; };
+               0FD1202D1A8AED12000F5280 /* FTLJSCallBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJSCallBase.cpp; path = ftl/FTLJSCallBase.cpp; sourceTree = "<group>"; };
+               0FD1202E1A8AED12000F5280 /* FTLJSCallBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJSCallBase.h; path = ftl/FTLJSCallBase.h; sourceTree = "<group>"; };
+               0FD120311A8C85BD000F5280 /* FTLJSCallVarargs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJSCallVarargs.cpp; path = ftl/FTLJSCallVarargs.cpp; sourceTree = "<group>"; };
+               0FD120321A8C85BD000F5280 /* FTLJSCallVarargs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJSCallVarargs.h; path = ftl/FTLJSCallVarargs.h; sourceTree = "<group>"; };
                0FD2C92316D01EE900C7803F /* StructureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureInlines.h; sourceTree = "<group>"; };
                0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = "<group>"; };
                0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = "<group>"; };
                0FD8A32217D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGToFTLDeferredCompilationCallback.h; path = dfg/DFGToFTLDeferredCompilationCallback.h; sourceTree = "<group>"; };
                0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGToFTLForOSREntryDeferredCompilationCallback.cpp; path = dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp; sourceTree = "<group>"; };
                0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGToFTLForOSREntryDeferredCompilationCallback.h; path = dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h; sourceTree = "<group>"; };
+               0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCatchScope.cpp; sourceTree = "<group>"; };
+               0FD9497F1A97DB9600E28966 /* JSCatchScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCatchScope.h; sourceTree = "<group>"; };
+               0FD949801A97DB9600E28966 /* JSFunctionNameScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFunctionNameScope.cpp; sourceTree = "<group>"; };
+               0FD949811A97DB9600E28966 /* JSFunctionNameScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFunctionNameScope.h; sourceTree = "<group>"; };
                0FDB2CC7173DA51E007B3C1B /* FTLAbbreviatedTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FTLAbbreviatedTypes.h; path = ftl/FTLAbbreviatedTypes.h; sourceTree = "<group>"; };
                0FDB2CC8173DA51E007B3C1B /* FTLValueFromBlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FTLValueFromBlock.h; path = ftl/FTLValueFromBlock.h; sourceTree = "<group>"; };
                0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWorklist.cpp; path = dfg/DFGWorklist.cpp; sourceTree = "<group>"; };
                0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcurrentJITLock.h; sourceTree = "<group>"; };
                0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessDataDump.cpp; path = dfg/DFGVariableAccessDataDump.cpp; sourceTree = "<group>"; };
                0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; };
+               0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsMode.h; sourceTree = "<group>"; };
+               0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArgumentsOffset.cpp; sourceTree = "<group>"; };
+               0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArgumentsOffset.h; sourceTree = "<group>"; };
+               0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArguments.cpp; sourceTree = "<group>"; };
+               0FE050101AA9091100D33B33 /* DirectArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArguments.h; sourceTree = "<group>"; };
+               0FE050111AA9091100D33B33 /* GenericArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArguments.h; sourceTree = "<group>"; };
+               0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArgumentsInlines.h; sourceTree = "<group>"; };
+               0FE050131AA9091100D33B33 /* GenericOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericOffset.h; sourceTree = "<group>"; };
+               0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClonedArguments.cpp; sourceTree = "<group>"; };
+               0FE0501D1AA9095600D33B33 /* ClonedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClonedArguments.h; sourceTree = "<group>"; };
+               0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArguments.cpp; sourceTree = "<group>"; };
+               0FE0501F1AA9095600D33B33 /* ScopedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArguments.h; sourceTree = "<group>"; };
+               0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArgumentsTable.h; sourceTree = "<group>"; };
+               0FE050211AA9095600D33B33 /* ScopeOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopeOffset.cpp; sourceTree = "<group>"; };
+               0FE050221AA9095600D33B33 /* ScopeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeOffset.h; sourceTree = "<group>"; };
+               0FE050231AA9095600D33B33 /* VarOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VarOffset.cpp; sourceTree = "<group>"; };
+               0FE050241AA9095600D33B33 /* VarOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VarOffset.h; sourceTree = "<group>"; };
+               0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArgumentsTable.cpp; sourceTree = "<group>"; };
                0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = "<group>"; };
                0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; };
+               0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVarargsForwardingPhase.cpp; path = dfg/DFGVarargsForwardingPhase.cpp; sourceTree = "<group>"; };
+               0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVarargsForwardingPhase.h; path = dfg/DFGVarargsForwardingPhase.h; sourceTree = "<group>"; };
+               0FE7211B193B9C590031F6ED /* DFGTransition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTransition.cpp; path = dfg/DFGTransition.cpp; sourceTree = "<group>"; };
+               0FE7211C193B9C590031F6ED /* DFGTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTransition.h; path = dfg/DFGTransition.h; sourceTree = "<group>"; };
+               0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicCallStubRoutine.cpp; sourceTree = "<group>"; };
+               0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicCallStubRoutine.h; sourceTree = "<group>"; };
                0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredWatchpoints.cpp; path = dfg/DFGDesiredWatchpoints.cpp; sourceTree = "<group>"; };
                0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredWatchpoints.h; path = dfg/DFGDesiredWatchpoints.h; sourceTree = "<group>"; };
                0FE95F7718B5694700B531FB /* FTLDataSection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDataSection.cpp; path = ftl/FTLDataSection.cpp; sourceTree = "<group>"; };
                0FEA0A2F170D40BF00BB722C /* DFGJITCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCode.cpp; path = dfg/DFGJITCode.cpp; sourceTree = "<group>"; };
                0FEA0A30170D40BF00BB722C /* DFGJITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCode.h; path = dfg/DFGJITCode.h; sourceTree = "<group>"; };
                0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
+               0FED67B71B26256D0066CE15 /* DFGConstantHoistingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantHoistingPhase.cpp; path = dfg/DFGConstantHoistingPhase.cpp; sourceTree = "<group>"; };
+               0FED67B81B26256D0066CE15 /* DFGConstantHoistingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGConstantHoistingPhase.h; path = dfg/DFGConstantHoistingPhase.h; sourceTree = "<group>"; };
+               0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetupVarargsFrame.h; sourceTree = "<group>"; };
+               0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetupVarargsFrame.cpp; sourceTree = "<group>"; };
                0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
                0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitJumpPlaceholder.h; path = dfg/DFGOSRExitJumpPlaceholder.h; sourceTree = "<group>"; };
+               0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocationFuzz.cpp; sourceTree = "<group>"; };
+               0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocationFuzz.h; sourceTree = "<group>"; };
                0FF4272F158EBD44004CB9FF /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Disassembler.h; path = disassembler/Disassembler.h; sourceTree = "<group>"; };
                0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UDis86Disassembler.cpp; path = disassembler/UDis86Disassembler.cpp; sourceTree = "<group>"; };
                0FF42734158EBD94004CB9FF /* udis86_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86_decode.c; path = disassembler/udis86/udis86_decode.c; sourceTree = "<group>"; };
                0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOrigin.h; path = profiler/ProfilerOrigin.h; sourceTree = "<group>"; };
                0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOriginStack.cpp; path = profiler/ProfilerOriginStack.cpp; sourceTree = "<group>"; };
                0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOriginStack.h; path = profiler/ProfilerOriginStack.h; sourceTree = "<group>"; };
+               0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredValue.cpp; sourceTree = "<group>"; };
+               0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredValue.h; sourceTree = "<group>"; };
                0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
+               0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeofType.cpp; sourceTree = "<group>"; };
+               0FFB6C371AF48DDC00DB1BF7 /* TypeofType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeofType.h; sourceTree = "<group>"; };
                0FFC99D0184EC8AD009C10AB /* ConstantMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantMode.h; sourceTree = "<group>"; };
                0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBufferNeuteringWatchpoint.cpp; sourceTree = "<group>"; };
                0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayBufferNeuteringWatchpoint.h; sourceTree = "<group>"; };
                1429D8830ED21C3D00B89619 /* SamplingTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingTool.cpp; sourceTree = "<group>"; };
                1429D8840ED21C3D00B89619 /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingTool.h; sourceTree = "<group>"; };
                1429D8DB0ED2205B00B89619 /* CallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallFrame.cpp; sourceTree = "<group>"; };
-               1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrame.h; sourceTree = "<group>"; };
+               1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CallFrame.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; };
                1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
                142D3938103E4560007DCB52 /* NumericStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumericStrings.h; sourceTree = "<group>"; };
                147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BatchedTransitionOptimizer.h; sourceTree = "<group>"; };
                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutPropertySlot.h; sourceTree = "<group>"; };
                1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerCallFrame.h; sourceTree = "<group>"; };
-               14816E19154CC56C00B8054C /* BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlockAllocator.cpp; sourceTree = "<group>"; };
-               14816E1A154CC56C00B8054C /* BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockAllocator.h; sourceTree = "<group>"; };
                1482B6EA0A4300B300517CFC /* JSValueRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueRef.h; sourceTree = "<group>"; };
                1482B74B0A43032800517CFC /* JSStringRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRef.h; sourceTree = "<group>"; };
                1482B74C0A43032800517CFC /* JSStringRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringRef.cpp; sourceTree = "<group>"; };
                14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeMap.cpp; sourceTree = "<group>"; };
                14D844A316AA2C7000A65AF0 /* PrototypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeMap.h; sourceTree = "<group>"; };
                14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
-               14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; };
-               14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; };
+               14DA818E0D99FD2000B0A4FB /* JSLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLexicalEnvironment.h; sourceTree = "<group>"; };
+               14DA818F0D99FD2000B0A4FB /* JSLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLexicalEnvironment.cpp; sourceTree = "<group>"; };
                14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JSGlobalObject.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
                14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticPropertyAnalysis.h; sourceTree = "<group>"; };
                14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakBlock.cpp; sourceTree = "<group>"; };
                14E84F9B14EE1ACC00D6D5D4 /* WeakSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakSet.cpp; sourceTree = "<group>"; };
                14E84F9C14EE1ACC00D6D5D4 /* WeakSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakSet.h; sourceTree = "<group>"; };
                14E84F9D14EE1ACC00D6D5D4 /* WeakImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakImpl.h; sourceTree = "<group>"; };
-               14F252560D08DD8D004ECFFF /* JSVariableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVariableObject.h; sourceTree = "<group>"; };
+               14F252560D08DD8D004ECFFF /* JSEnvironmentRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEnvironmentRecord.h; sourceTree = "<group>"; };
                14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHandleOwner.cpp; sourceTree = "<group>"; };
                14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
                14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
                1C9051450BA9E8A70081E9D0 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
                1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScript.h; sourceTree = "<group>"; };
                1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; };
-               1CAA9A1C18F4997F000A369D /* InspectorProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProfilerAgent.cpp; sourceTree = "<group>"; };
-               1CAA9A1D18F4997F000A369D /* InspectorProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProfilerAgent.h; sourceTree = "<group>"; };
-               1CAA9A2018F4A220000A369D /* JSGlobalObjectProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectProfilerAgent.cpp; sourceTree = "<group>"; };
-               1CAA9A2118F4A220000A369D /* JSGlobalObjectProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectProfilerAgent.h; sourceTree = "<group>"; };
                2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringJoiner.cpp; sourceTree = "<group>"; };
                2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringJoiner.h; sourceTree = "<group>"; };
+               2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameEnumerator.cpp; sourceTree = "<group>"; };
+               2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameEnumerator.h; sourceTree = "<group>"; };
                2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomGetterSetter.cpp; sourceTree = "<group>"; };
                2A111244192FCE79005EE18D /* CustomGetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomGetterSetter.h; sourceTree = "<group>"; };
-               2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; };
                2A343F7418A1748B0039B085 /* GCSegmentedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArray.h; sourceTree = "<group>"; };
                2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArrayInlines.h; sourceTree = "<group>"; };
                2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValueInternal.h; sourceTree = "<group>"; };
                2AAD964918569417001F93BE /* RecursiveAllocationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursiveAllocationScope.h; sourceTree = "<group>"; };
                2AC922B918A16182003CE0FB /* FTLDWARFDebugLineInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDWARFDebugLineInfo.cpp; path = ftl/FTLDWARFDebugLineInfo.cpp; sourceTree = "<group>"; };
                2AC922BA18A16182003CE0FB /* FTLDWARFDebugLineInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLDWARFDebugLineInfo.h; path = ftl/FTLDWARFDebugLineInfo.h; sourceTree = "<group>"; };
-               2ACCF3DC185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStoreBarrierElisionPhase.cpp; path = dfg/DFGStoreBarrierElisionPhase.cpp; sourceTree = "<group>"; };
-               2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierElisionPhase.h; path = dfg/DFGStoreBarrierElisionPhase.h; sourceTree = "<group>"; };
+               2AD2EDFA19799E38004D6478 /* EnumerationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnumerationMode.h; sourceTree = "<group>"; };
                2AD8932917E3868F00668276 /* HeapIterationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapIterationScope.h; sourceTree = "<group>"; };
                2ADFA26218EF3540004F9FCC /* GCLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCLogging.cpp; sourceTree = "<group>"; };
                2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureIDTable.cpp; sourceTree = "<group>"; };
                2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDTable.h; sourceTree = "<group>"; };
                371D842C17C98B6E00ECF994 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+               4340A4821A9051AF00D73CCA /* MathCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathCommon.cpp; sourceTree = "<group>"; };
+               4340A4831A9051AF00D73CCA /* MathCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathCommon.h; sourceTree = "<group>"; };
                449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeatureDefines.xcconfig; sourceTree = "<group>"; };
                451539B812DC994500EF7AC4 /* Yarr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Yarr.h; path = yarr/Yarr.h; sourceTree = "<group>"; };
                45E12D8806A49B0F00E9DF84 /* jsc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsc.cpp; sourceTree = "<group>"; tabWidth = 4; };
                51F0EB6105C86C6B00E6DF1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
                51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
+               52678F8C1A031009006A306D /* BasicBlockLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBlockLocation.cpp; sourceTree = "<group>"; };
+               52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; };
+               52678F901A04177C006A306D /* ControlFlowProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlFlowProfiler.h; sourceTree = "<group>"; };
+               527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; };
+               52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = "<group>"; };
+               52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionHasExecutedCache.cpp; sourceTree = "<group>"; };
+               52B310FE1975B4240080857C /* TypeLocationCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLocationCache.cpp; sourceTree = "<group>"; };
+               52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = "<group>"; };
+               52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlFlowProfiler.cpp; sourceTree = "<group>"; };
+               52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
+               52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
+               52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
                5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CompileRuntimeToLLVMIR.xcconfig; sourceTree = "<group>"; };
-               55407AC818DA58AD00EFF7F2 /* libCompileRuntimeToLLVMIR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCompileRuntimeToLLVMIR.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
                5D53726D0E1C546B0021E549 /* Tracing.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Tracing.d; sourceTree = "<group>"; };
                5D53726E0E1C54880021E549 /* Tracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = "<group>"; };
                5D53727D0E1C55EC0021E549 /* TracingDtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TracingDtrace.h; sourceTree = "<group>"; };
                5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = "<group>"; };
                5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntDesiredOffsets.h; path = LLIntOffsets/LLIntDesiredOffsets.h; sourceTree = BUILT_PRODUCTS_DIR; };
                5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAvailability.h; sourceTree = "<group>"; };
+               62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyNode.cpp; path = dfg/DFGLazyNode.cpp; sourceTree = "<group>"; };
+               62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyNode.h; path = dfg/DFGLazyNode.h; sourceTree = "<group>"; };
+               62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionRareData.cpp; sourceTree = "<group>"; };
+               62D2D38E1ADF103F000206C1 /* FunctionRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionRareData.h; sourceTree = "<group>"; };
                6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = "<group>"; };
                651122E5140469BA002B101D /* testRegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testRegExp.cpp; sourceTree = "<group>"; };
                6511230514046A4C002B101D /* testRegExp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testRegExp; sourceTree = BUILT_PRODUCTS_DIR; };
                652A3A221651C69700A80AFE /* A64DOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = A64DOpcode.cpp; path = disassembler/ARM64/A64DOpcode.cpp; sourceTree = "<group>"; };
                652A3A231651C69700A80AFE /* A64DOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = A64DOpcode.h; path = disassembler/ARM64/A64DOpcode.h; sourceTree = "<group>"; };
                65303D631447B9E100D3F904 /* ParserTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserTokens.h; sourceTree = "<group>"; };
-               65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyNameArray.cpp; sourceTree = "<group>"; };
                65400C100A69BAF200509887 /* PropertyNameArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PropertyNameArray.h; sourceTree = "<group>"; };
+               6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = NullGetterFunction.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+               6546F5201A32A59C006F07D5 /* NullGetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullGetterFunction.h; sourceTree = "<group>"; };
+               65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullSetterFunction.cpp; sourceTree = "<group>"; };
+               65525FC41A6DD3B3007B5495 /* NullSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NullSetterFunction.h; sourceTree = "<group>"; };
                6553A32F17A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommonSlowPathsExceptions.cpp; sourceTree = "<group>"; };
                6553A33017A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPathsExceptions.h; sourceTree = "<group>"; };
+               65570F581AA4C00A009B3C23 /* Regress141275.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Regress141275.h; path = API/tests/Regress141275.h; sourceTree = "<group>"; };
+               65570F591AA4C00A009B3C23 /* Regress141275.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Regress141275.mm; path = API/tests/Regress141275.mm; sourceTree = "<group>"; };
                655EB29A10CE2581001A990E /* NodesCodegen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodesCodegen.cpp; sourceTree = "<group>"; };
                6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
                65621E6B089E859700760F35 /* PropertySlot.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertySlot.cpp; sourceTree = "<group>"; tabWidth = 8; };
                65621E6C089E859700760F35 /* PropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PropertySlot.h; sourceTree = "<group>"; tabWidth = 8; };
+               657CF45619BF6662004ACBF2 /* JSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallee.cpp; sourceTree = "<group>"; };
+               657CF45719BF6662004ACBF2 /* JSCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallee.h; sourceTree = "<group>"; };
                65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaxFrameExtentForSlowPathCall.h; sourceTree = "<group>"; };
+               658D3A5519638268003C45D6 /* VMEntryRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VMEntryRecord.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = "<group>"; };
                65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = "<group>"; };
                65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ARMv7Disassembler.cpp; path = disassembler/ARMv7Disassembler.cpp; sourceTree = "<group>"; };
                65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
+               6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerEvalEnabler.h; sourceTree = "<group>"; };
+               70113D491A8DB093003848C4 /* IteratorOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorOperations.cpp; sourceTree = "<group>"; };
+               70113D4A1A8DB093003848C4 /* IteratorOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorOperations.h; sourceTree = "<group>"; };
+               7013CA891B491A9400CAE613 /* JSJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJob.cpp; sourceTree = "<group>"; };
+               7013CA8A1B491A9400CAE613 /* JSJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSJob.h; sourceTree = "<group>"; };
                704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
-               7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JSPromiseFunctions.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
-               7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseFunctions.h; sourceTree = "<group>"; };
+               705B41A31A6E501E00716757 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = "<group>"; };
+               705B41A41A6E501E00716757 /* Symbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Symbol.h; sourceTree = "<group>"; };
+               705B41A51A6E501E00716757 /* SymbolConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolConstructor.cpp; sourceTree = "<group>"; };
+               705B41A61A6E501E00716757 /* SymbolConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolConstructor.h; sourceTree = "<group>"; };
+               705B41A71A6E501E00716757 /* SymbolObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolObject.cpp; sourceTree = "<group>"; };
+               705B41A81A6E501E00716757 /* SymbolObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolObject.h; sourceTree = "<group>"; };
+               705B41A91A6E501E00716757 /* SymbolPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolPrototype.cpp; sourceTree = "<group>"; };
+               705B41AA1A6E501E00716757 /* SymbolPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolPrototype.h; sourceTree = "<group>"; };
+               7094C4DC1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeIntrinsicRegistry.cpp; sourceTree = "<group>"; };
+               7094C4DD1AE439530041A2EE /* BytecodeIntrinsicRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeIntrinsicRegistry.h; sourceTree = "<group>"; };
+               709FB8611AE335C60039D069 /* JSWeakSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakSet.cpp; sourceTree = "<group>"; };
+               709FB8621AE335C60039D069 /* JSWeakSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakSet.h; sourceTree = "<group>"; };
+               709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakSetConstructor.cpp; sourceTree = "<group>"; };
+               709FB8641AE335C60039D069 /* WeakSetConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakSetConstructor.h; sourceTree = "<group>"; };
+               709FB8651AE335C60039D069 /* WeakSetPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakSetPrototype.cpp; sourceTree = "<group>"; };
+               709FB8661AE335C60039D069 /* WeakSetPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakSetPrototype.h; sourceTree = "<group>"; };
+               70B0A9D01A9B66200001306A /* RuntimeFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeFlags.h; sourceTree = "<group>"; };
+               70DC3E071B2DF2C700054299 /* IteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorPrototype.cpp; sourceTree = "<group>"; };
+               70DC3E081B2DF2C700054299 /* IteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorPrototype.h; sourceTree = "<group>"; };
+               70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringIterator.cpp; sourceTree = "<group>"; };
+               70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringIterator.h; sourceTree = "<group>"; };
+               70EC0EC01AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringIteratorPrototype.cpp; sourceTree = "<group>"; };
+               70EC0EC11AA0D7DA00B6AAFA /* StringIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringIteratorPrototype.h; sourceTree = "<group>"; };
+               70ECA6001AFDBEA200449739 /* JSTemplateRegistryKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTemplateRegistryKey.cpp; sourceTree = "<group>"; };
+               70ECA6011AFDBEA200449739 /* JSTemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTemplateRegistryKey.h; sourceTree = "<group>"; };
+               70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
+               70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
+               70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
                7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
                7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = "<group>"; };
-               7C008CDC1871258D00955C24 /* JSPromiseReaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseReaction.cpp; sourceTree = "<group>"; };
-               7C008CDD1871258D00955C24 /* JSPromiseReaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseReaction.h; sourceTree = "<group>"; };
                7C008CE5187631B600955C24 /* Microtask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Microtask.h; sourceTree = "<group>"; };
                7C184E1817BEDBD3007CB63A /* JSPromise.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromise.cpp; sourceTree = "<group>"; };
                7C184E1917BEDBD3007CB63A /* JSPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromise.h; sourceTree = "<group>"; };
                7CFBAC1C18B535E500D00750 /* Promise.prototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = Promise.prototype.js; sourceTree = "<group>"; };
                7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; };
                7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureChain.cpp; sourceTree = "<group>"; };
-               7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeInfo.h; sourceTree = "<group>"; };
                860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractMacroAssembler.h; sourceTree = "<group>"; };
                860161E00F3A83C100F84710 /* MacroAssemblerX86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86.h; sourceTree = "<group>"; };
                860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86_64.h; sourceTree = "<group>"; };
                860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; };
                8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeProfiling.cpp; sourceTree = "<group>"; };
                8603CEF314C7546400AE59E3 /* CodeProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeProfiling.h; sourceTree = "<group>"; };
-               8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
+               8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; lineEnding = 0; path = ChangeLog; sourceTree = "<group>"; };
                8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdentifierInlines.h; sourceTree = "<group>"; };
                8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; };
                86158AB2155C8B3F00B45C9C /* PropertyName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyName.h; sourceTree = "<group>"; };
                868916A9155F285400CB2B9A /* PrivateName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateName.h; sourceTree = "<group>"; };
                869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
                86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; };
-               86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; };
-               86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; };
+               86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; };
+               86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; };
                86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
                86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; };
                86E3C610167BAB87006D760A /* JSVirtualMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSVirtualMachine.mm; sourceTree = "<group>"; };
                86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVirtualMachineInternal.h; sourceTree = "<group>"; };
                86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; };
-               86EBF2F91560F036008E9222 /* NameConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameConstructor.cpp; sourceTree = "<group>"; };
-               86EBF2FA1560F036008E9222 /* NameConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameConstructor.h; sourceTree = "<group>"; };
-               86EBF2FB1560F036008E9222 /* NameInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameInstance.cpp; sourceTree = "<group>"; };
-               86EBF2FC1560F036008E9222 /* NameInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameInstance.h; sourceTree = "<group>"; };
-               86EBF2FD1560F036008E9222 /* NamePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NamePrototype.cpp; sourceTree = "<group>"; };
-               86EBF2FE1560F036008E9222 /* NamePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NamePrototype.h; sourceTree = "<group>"; };
                86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGByteCodeParser.cpp; path = dfg/DFGByteCodeParser.cpp; sourceTree = "<group>"; };
                86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeParser.h; path = dfg/DFGByteCodeParser.h; sourceTree = "<group>"; };
                86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGGenerationInfo.h; path = dfg/DFGGenerationInfo.h; sourceTree = "<group>"; };
                99E45A2118A1B2590026D88F /* EncodedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodedValue.h; sourceTree = "<group>"; };
                99E45A2218A1B2590026D88F /* InputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputCursor.h; sourceTree = "<group>"; };
                99E45A2318A1B2590026D88F /* NondeterministicInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NondeterministicInput.h; sourceTree = "<group>"; };
+               9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserFunctionInfo.h; sourceTree = "<group>"; };
+               9E729409190F0306001A91B5 /* BundlePath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundlePath.mm; sourceTree = "<group>"; };
+               9E72940A190F0514001A91B5 /* BundlePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundlePath.h; sourceTree = "<group>"; };
+               9EA5C7A0190F05D200508EBE /* InitializeLLVMMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitializeLLVMMac.cpp; path = llvm/InitializeLLVMMac.cpp; sourceTree = "<group>"; };
+               A12BBFF11B044A8B00664B69 /* IntlObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlObject.h; sourceTree = "<group>"; };
+               A12BBFF31B044A9800664B69 /* IntlObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlObject.cpp; sourceTree = "<group>"; };
                A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
                A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
                A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; };
                A513E5C9185F9624007E95AD /* InjectedScriptManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScriptManager.h; sourceTree = "<group>"; };
                A514B2C0185A684400F3C7CB /* InjectedScriptBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedScriptBase.cpp; sourceTree = "<group>"; };
                A514B2C1185A684400F3C7CB /* InjectedScriptBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScriptBase.h; sourceTree = "<group>"; };
-               A532438118568317002ED692 /* InspectorJSBackendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorJSBackendDispatchers.cpp; sourceTree = "<group>"; };
-               A532438218568317002ED692 /* InspectorJSBackendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorJSBackendDispatchers.h; sourceTree = "<group>"; };
-               A532438318568317002ED692 /* InspectorJSFrontendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorJSFrontendDispatchers.cpp; sourceTree = "<group>"; };
-               A532438418568317002ED692 /* InspectorJSFrontendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorJSFrontendDispatchers.h; sourceTree = "<group>"; };
-               A532438518568317002ED692 /* InspectorJSTypeBuilders.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorJSTypeBuilders.cpp; sourceTree = "<group>"; };
-               A532438618568317002ED692 /* InspectorJSTypeBuilders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorJSTypeBuilders.h; sourceTree = "<group>"; };
+               A532438118568317002ED692 /* InspectorBackendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorBackendDispatchers.cpp; sourceTree = "<group>"; };
+               A532438218568317002ED692 /* InspectorBackendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorBackendDispatchers.h; sourceTree = "<group>"; };
+               A532438318568317002ED692 /* InspectorFrontendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorFrontendDispatchers.cpp; sourceTree = "<group>"; };
+               A532438418568317002ED692 /* InspectorFrontendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorFrontendDispatchers.h; sourceTree = "<group>"; };
+               A532438518568317002ED692 /* InspectorProtocolObjects.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProtocolObjects.cpp; sourceTree = "<group>"; };
+               A532438618568317002ED692 /* InspectorProtocolObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorProtocolObjects.h; sourceTree = "<group>"; };
                A532438D185696CA002ED692 /* protocol */ = {isa = PBXFileReference; lastKnownFileType = folder; path = protocol; sourceTree = "<group>"; };
-               A532438F185696E6002ED692 /* CodeGeneratorInspector.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = CodeGeneratorInspector.py; sourceTree = "<group>"; };
-               A5324390185696E6002ED692 /* CodeGeneratorInspectorStrings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = CodeGeneratorInspectorStrings.py; sourceTree = "<group>"; };
                A5324391185696E6002ED692 /* generate-combined-inspector-json.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "generate-combined-inspector-json.py"; sourceTree = "<group>"; };
-               A53243951856A475002ED692 /* InspectorJS.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = InspectorJS.json; sourceTree = "<group>"; };
-               A53243961856A475002ED692 /* InspectorJSBackendCommands.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InspectorJSBackendCommands.js; sourceTree = "<group>"; };
+               A53243951856A475002ED692 /* CombinedDomains.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = CombinedDomains.json; sourceTree = "<group>"; };
+               A53243961856A475002ED692 /* InspectorBackendCommands.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InspectorBackendCommands.js; sourceTree = "<group>"; };
                A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsolePrototype.cpp; sourceTree = "<group>"; };
                A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsolePrototype.h; sourceTree = "<group>"; };
                A53CE08318BC1A5600BEDF76 /* JSConsole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSConsole.cpp; sourceTree = "<group>"; };
                A54CF2F3184EAB2400237F19 /* ScriptValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptValue.h; sourceTree = "<group>"; };
                A54CF2F7184EAEDA00237F19 /* ScriptObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptObject.cpp; sourceTree = "<group>"; };
                A54CF2F8184EAEDA00237F19 /* ScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptObject.h; sourceTree = "<group>"; };
+               A552C37D1ADDB8FE00139726 /* JSRemoteInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRemoteInspector.cpp; sourceTree = "<group>"; };
+               A552C37E1ADDB8FE00139726 /* JSRemoteInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRemoteInspector.h; sourceTree = "<group>"; };
                A55D93A3185012A800400DED /* ScriptFunctionCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptFunctionCall.cpp; sourceTree = "<group>"; };
                A55D93A4185012A800400DED /* ScriptFunctionCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptFunctionCall.h; sourceTree = "<group>"; };
-               A55D93AB18514F7900400DED /* InspectorTypeBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorTypeBuilder.h; sourceTree = "<group>"; };
+               A55D93AB18514F7900400DED /* InspectorProtocolTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProtocolTypes.h; sourceTree = "<group>"; };
                A57D23E31890CEBF0031C7FA /* InspectorDebuggerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDebuggerAgent.cpp; sourceTree = "<group>"; };
                A57D23E41890CEBF0031C7FA /* InspectorDebuggerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDebuggerAgent.h; sourceTree = "<group>"; };
                A57D23E71891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectDebuggerAgent.cpp; sourceTree = "<group>"; };
                A5BA15E6182340B300A82E69 /* RemoteInspectorXPCConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorXPCConnection.h; sourceTree = "<group>"; };
                A5BA15E7182340B300A82E69 /* RemoteInspectorXPCConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteInspectorXPCConnection.mm; sourceTree = "<group>"; };
                A5BA15EF182345AF00A82E69 /* RemoteInspectorDebuggable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteInspectorDebuggable.h; sourceTree = "<group>"; };
-               A5C3A1A318C0490200C9593A /* JSConsoleClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSConsoleClient.cpp; sourceTree = "<group>"; };
-               A5C3A1A418C0490200C9593A /* JSConsoleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSConsoleClient.h; sourceTree = "<group>"; };
+               A5C3A1A318C0490200C9593A /* JSGlobalObjectConsoleClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectConsoleClient.cpp; sourceTree = "<group>"; };
+               A5C3A1A418C0490200C9593A /* JSGlobalObjectConsoleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectConsoleClient.h; sourceTree = "<group>"; };
                A5CEEE12187F3BAD00E55C99 /* InspectorAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorAgent.cpp; sourceTree = "<group>"; };
                A5CEEE13187F3BAD00E55C99 /* InspectorAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorAgent.h; sourceTree = "<group>"; };
                A5D0A1BA1862301B00C7B496 /* InspectorEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorEnvironment.h; sourceTree = "<group>"; };
                A5D2E664195E173800A518E7 /* JSContextRefInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSContextRefInternal.h; sourceTree = "<group>"; };
+               A5EA70E419F5B1010098F5EC /* AugmentableInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AugmentableInspectorController.h; sourceTree = "<group>"; };
+               A5EA70E519F5B1010098F5EC /* AugmentableInspectorControllerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AugmentableInspectorControllerClient.h; sourceTree = "<group>"; };
+               A5EA70E619F5B1010098F5EC /* AlternateDispatchableAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlternateDispatchableAgent.h; sourceTree = "<group>"; };
+               A5EA70EA19F5B3D50098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_alternate_backend_dispatcher_header.py; sourceTree = "<group>"; };
+               A5EA70ED19F5B5C40098F5EC /* JSContextRefInspectorSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSContextRefInspectorSupport.h; sourceTree = "<group>"; };
+               A5EA70EF19F6DE5A0098F5EC /* generate_objc_backend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_backend_dispatcher_header.py; sourceTree = "<group>"; };
+               A5EA70F019F6DE5A0098F5EC /* generate_objc_backend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_backend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               A5EA70F119F6DE5A0098F5EC /* generate_objc_configuration_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_configuration_header.py; sourceTree = "<group>"; };
+               A5EA70F219F6DE5A0098F5EC /* generate_objc_configuration_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_configuration_implementation.py; sourceTree = "<group>"; };
+               A5EA70F319F6DE5A0098F5EC /* generate_objc_conversion_helpers.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_conversion_helpers.py; sourceTree = "<group>"; };
+               A5EA70F419F6DE5A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_frontend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               A5EA70F519F6DE5A0098F5EC /* generate_objc_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_header.py; sourceTree = "<group>"; };
+               A5EA70F619F6DE5A0098F5EC /* generate_objc_internal_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_internal_header.py; sourceTree = "<group>"; };
+               A5EA70F819F6DE5A0098F5EC /* objc_generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = objc_generator.py; sourceTree = "<group>"; };
+               A5EA710D19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorAlternateBackendDispatchers.h; sourceTree = "<group>"; };
                A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptArguments.cpp; sourceTree = "<group>"; };
                A5FD0066189AFE9C00633231 /* ScriptArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptArguments.h; sourceTree = "<group>"; };
                A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallFrame.cpp; sourceTree = "<group>"; };
                A704D90217A0BAA8006BA554 /* DFGMergeMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMergeMode.h; path = dfg/DFGMergeMode.h; sourceTree = "<group>"; };
                A709F2EF17A0AC0400512E98 /* SlowPathCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlowPathCall.h; sourceTree = "<group>"; };
                A709F2F117A0AC2A00512E98 /* CommonSlowPaths.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommonSlowPaths.cpp; sourceTree = "<group>"; };
-               A70B083017A0B79B00DAF14B /* DFGBinarySwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBinarySwitch.cpp; path = dfg/DFGBinarySwitch.cpp; sourceTree = "<group>"; };
-               A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBinarySwitch.h; path = dfg/DFGBinarySwitch.h; sourceTree = "<group>"; };
                A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITOpcodes32_64.cpp; sourceTree = "<group>"; };
                A718F61A11754A21002465A7 /* RegExpJitTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpJitTables.h; sourceTree = "<group>"; };
                A718F8211178EB4B002465A7 /* create_regex_tables */ = {isa = PBXFileReference; explicitFileType = text.script.python; fileEncoding = 4; path = create_regex_tables; sourceTree = "<group>"; };
                A72700770DAC605600E548D7 /* JSNotAnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNotAnObject.h; sourceTree = "<group>"; };
                A72700780DAC605600E548D7 /* JSNotAnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNotAnObject.cpp; sourceTree = "<group>"; };
                A72701B30DADE94900E548D7 /* ExceptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHelpers.h; sourceTree = "<group>"; };
-               A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; };
-               A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; };
                A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARMv7.cpp; sourceTree = "<group>"; };
                A7299D9B17D12837005F5FF9 /* JSSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSet.cpp; sourceTree = "<group>"; };
                A7299D9C17D12837005F5FF9 /* JSSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSet.h; sourceTree = "<group>"; };
                A7386553118697B400540279 /* ThunkGenerators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerators.h; sourceTree = "<group>"; };
                A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyJSValue.cpp; path = dfg/DFGLazyJSValue.cpp; sourceTree = "<group>"; };
                A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; };
-               A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredStructureChains.cpp; path = dfg/DFGDesiredStructureChains.cpp; sourceTree = "<group>"; };
-               A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredStructureChains.h; path = dfg/DFGDesiredStructureChains.h; sourceTree = "<group>"; };
                A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSaneStringGetByValSlowPathGenerator.h; path = dfg/DFGSaneStringGetByValSlowPathGenerator.h; sourceTree = "<group>"; };
                A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefPrivate.h; sourceTree = "<group>"; };
                A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; };
                A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefInternal.h; sourceTree = "<group>"; };
-               A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7Assembler.cpp; sourceTree = "<group>"; };
-               A74DEF8B182D991400522C22 /* MapIteratorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapIteratorConstructor.cpp; sourceTree = "<group>"; };
-               A74DEF8C182D991400522C22 /* MapIteratorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapIteratorConstructor.h; sourceTree = "<group>"; };
                A74DEF8D182D991400522C22 /* MapIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapIteratorPrototype.cpp; sourceTree = "<group>"; };
                A74DEF8E182D991400522C22 /* MapIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapIteratorPrototype.h; sourceTree = "<group>"; };
                A74DEF8F182D991400522C22 /* JSMapIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMapIterator.cpp; sourceTree = "<group>"; };
                A74DEF90182D991400522C22 /* JSMapIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMapIterator.h; sourceTree = "<group>"; };
                A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic32_64.cpp; sourceTree = "<group>"; };
                A75EE9B018AAB7E200AAD043 /* BuiltinNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinNames.h; sourceTree = "<group>"; };
-               A76140C7182982CB00750624 /* ArgumentsIteratorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArgumentsIteratorConstructor.cpp; sourceTree = "<group>"; };
-               A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsIteratorConstructor.h; sourceTree = "<group>"; };
-               A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = ArgumentsIteratorPrototype.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
-               A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsIteratorPrototype.h; sourceTree = "<group>"; };
-               A76140CB182982CB00750624 /* JSArgumentsIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSArgumentsIterator.cpp; sourceTree = "<group>"; };
-               A76140CC182982CB00750624 /* JSArgumentsIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArgumentsIterator.h; sourceTree = "<group>"; };
                A767B5B317A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLoopPreHeaderCreationPhase.cpp; path = dfg/DFGLoopPreHeaderCreationPhase.cpp; sourceTree = "<group>"; };
                A767B5B417A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLoopPreHeaderCreationPhase.h; path = dfg/DFGLoopPreHeaderCreationPhase.h; sourceTree = "<group>"; };
                A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; };
                A77F181F164088B200640A47 /* CodeCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeCache.cpp; sourceTree = "<group>"; };
                A77F1820164088B200640A47 /* CodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeCache.h; sourceTree = "<group>"; };
                A77F18241641925400640A47 /* ParserModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserModes.h; sourceTree = "<group>"; };
-               A78507D417CBC6FD0011F6E7 /* MapData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapData.cpp; sourceTree = "<group>"; };
                A78507D517CBC6FD0011F6E7 /* MapData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapData.h; sourceTree = "<group>"; };
                A78853F717972629001440E4 /* IntendedStructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntendedStructureChain.cpp; sourceTree = "<group>"; };
                A78853F817972629001440E4 /* IntendedStructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntendedStructureChain.h; sourceTree = "<group>"; };
                A78A977C179738D5009DF744 /* FTLGeneratedFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLGeneratedFunction.h; path = ftl/FTLGeneratedFunction.h; sourceTree = "<group>"; };
                A78A977D179738D5009DF744 /* FTLJITFinalizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLJITFinalizer.cpp; path = ftl/FTLJITFinalizer.cpp; sourceTree = "<group>"; };
                A78A977E179738D5009DF744 /* FTLJITFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLJITFinalizer.h; path = ftl/FTLJITFinalizer.h; sourceTree = "<group>"; };
-               A790DD65182F499700588807 /* SetIteratorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetIteratorConstructor.cpp; sourceTree = "<group>"; };
-               A790DD66182F499700588807 /* SetIteratorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetIteratorConstructor.h; sourceTree = "<group>"; };
                A790DD67182F499700588807 /* SetIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetIteratorPrototype.cpp; sourceTree = "<group>"; };
                A790DD68182F499700588807 /* SetIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetIteratorPrototype.h; sourceTree = "<group>"; };
                A790DD69182F499700588807 /* JSSetIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSetIterator.cpp; sourceTree = "<group>"; };
                A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
                A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
                A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExportMacros.h; sourceTree = "<group>"; };
-               A7BDAEC017F4EA1400F6140C /* ArrayIteratorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayIteratorConstructor.cpp; sourceTree = "<group>"; };
-               A7BDAEC117F4EA1400F6140C /* ArrayIteratorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayIteratorConstructor.h; sourceTree = "<group>"; };
                A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = ArrayIteratorPrototype.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
                A7BDAEC317F4EA1400F6140C /* ArrayIteratorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayIteratorPrototype.h; sourceTree = "<group>"; };
                A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JSArrayIterator.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
                A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
                A7C1EAEA17987AB600299DB2 /* CallFrameInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameInlines.h; sourceTree = "<group>"; };
                A7C1EAEB17987AB600299DB2 /* JSStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStackInlines.h; sourceTree = "<group>"; };
-               A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackVisitor.cpp; sourceTree = "<group>"; };
+               A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = StackVisitor.cpp; sourceTree = "<group>"; };
                A7C1EAED17987AB600299DB2 /* StackVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackVisitor.h; sourceTree = "<group>"; };
                A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; };
                A7C225CD1399849C00FF1662 /* KeywordLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeywordLookup.h; sourceTree = "<group>"; };
                A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
                A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
                AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
+               AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
                B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
                B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedInstructionStream.cpp; sourceTree = "<group>"; };
                BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringPrototype.cpp; sourceTree = "<group>"; };
                BC18C3C60E16EE3300B34460 /* StringPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringPrototype.h; sourceTree = "<group>"; };
                BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayPrototype.lut.h; sourceTree = "<group>"; };
-               BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObject.lut.h; sourceTree = "<group>"; };
                BC18C52D0E16FCE100B34460 /* Lexer.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.lut.h; sourceTree = "<group>"; };
                BC22A3980E16E14800AF21C8 /* JSObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObject.cpp; sourceTree = "<group>"; };
                BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; };
-               BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVariableObject.cpp; sourceTree = "<group>"; };
-               BC257DE50E1F51C50016B6C9 /* Arguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Arguments.cpp; sourceTree = "<group>"; };
-               BC257DE60E1F51C50016B6C9 /* Arguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Arguments.h; sourceTree = "<group>"; };
+               BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEnvironmentRecord.cpp; sourceTree = "<group>"; };
                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionConstructor.cpp; sourceTree = "<group>"; };
                BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionConstructor.h; sourceTree = "<group>"; };
                BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NumberConstructor.cpp; sourceTree = "<group>"; };
                BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectPrototype.h; sourceTree = "<group>"; };
                BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumberConstructor.lut.h; sourceTree = "<group>"; };
                BC3046060E1F497F003232CF /* Error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Error.h; sourceTree = "<group>"; };
-               BC3135620F302FA3003DFD3A /* DebuggerActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerActivation.h; sourceTree = "<group>"; };
-               BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerActivation.cpp; sourceTree = "<group>"; };
-               BC337BDE0E1AF0B80076918A /* GetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetterSetter.h; sourceTree = "<group>"; };
+               BC337BDE0E1AF0B80076918A /* GetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = GetterSetter.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
                BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; };
                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; };
                BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectFunctions.cpp; sourceTree = "<group>"; };
                BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
                C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CustomGlobalObjectClassTest.c; path = API/tests/CustomGlobalObjectClassTest.c; sourceTree = "<group>"; };
                C203281F1981979D0088B499 /* CustomGlobalObjectClassTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomGlobalObjectClassTest.h; path = API/tests/CustomGlobalObjectClassTest.h; sourceTree = "<group>"; };
-               C20B25981706536200C21F4E /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
                C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.h; sourceTree = "<group>"; };
                C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; };
                C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; };
                C2C0F7CC17BBFC5B00464FE4 /* DFGDesiredTransitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredTransitions.h; path = dfg/DFGDesiredTransitions.h; sourceTree = "<group>"; };
                C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpaceInlines.h; sourceTree = "<group>"; };
                C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedBlock.h; sourceTree = "<group>"; };
-               C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapBlock.h; sourceTree = "<group>"; };
                C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSAPIWrapperObject.mm; sourceTree = "<group>"; };
                C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAPIWrapperObject.h; sourceTree = "<group>"; };
                C2DA778218E259990066FCB6 /* HeapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapInlines.h; sourceTree = "<group>"; };
-               C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuperRegion.cpp; sourceTree = "<group>"; };
-               C2DF442E1707AC0100A5CA96 /* SuperRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuperRegion.h; sourceTree = "<group>"; };
                C2E526BB1590EF000054E48D /* HeapTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapTimer.cpp; sourceTree = "<group>"; };
                C2E526BC1590EF000054E48D /* HeapTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapTimer.h; sourceTree = "<group>"; };
                C2EAA3F8149A830800FCE112 /* CopiedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpace.h; sourceTree = "<group>"; };
                C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeLivenessAnalysis.cpp; sourceTree = "<group>"; };
                C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysis.h; sourceTree = "<group>"; };
                C2FE18A316BAEC4000AF3061 /* StructureRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareData.h; sourceTree = "<group>"; };
+               C4703CBF192844960013FBEA /* generate-inspector-protocol-bindings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "generate-inspector-protocol-bindings.py"; sourceTree = "<group>"; };
+               C4703CC2192844CC0013FBEA /* __init__.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
+               C4703CC3192844CC0013FBEA /* generate_js_backend_commands.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_js_backend_commands.py; sourceTree = "<group>"; };
+               C4703CCA192844CC0013FBEA /* generator_templates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generator_templates.py; sourceTree = "<group>"; };
+               C4703CCB192844CC0013FBEA /* generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generator.py; sourceTree = "<group>"; };
+               C4703CCC192844CC0013FBEA /* models.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = models.py; sourceTree = "<group>"; };
+               C4F4B6CF1A05C76F005CAB76 /* cpp_generator_templates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = cpp_generator_templates.py; sourceTree = "<group>"; };
+               C4F4B6D01A05C76F005CAB76 /* cpp_generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = cpp_generator.py; sourceTree = "<group>"; };
+               C4F4B6D11A05C76F005CAB76 /* generate_cpp_backend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_backend_dispatcher_header.py; sourceTree = "<group>"; };
+               C4F4B6D21A05C76F005CAB76 /* generate_cpp_backend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_backend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               C4F4B6D31A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_frontend_dispatcher_header.py; sourceTree = "<group>"; };
+               C4F4B6D41A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_frontend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               C4F4B6D51A05C76F005CAB76 /* generate_cpp_protocol_types_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_protocol_types_header.py; sourceTree = "<group>"; };
+               C4F4B6D61A05C76F005CAB76 /* generate_cpp_protocol_types_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_cpp_protocol_types_implementation.py; sourceTree = "<group>"; };
+               C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_objc_protocol_types_implementation.py; sourceTree = "<group>"; };
+               C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = objc_generator_templates.py; sourceTree = "<group>"; };
                D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
                D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
+               DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPreciseLocalClobberize.h; path = dfg/DFGPreciseLocalClobberize.h; sourceTree = "<group>"; };
                E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
                E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
                E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
                E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
-               E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VM.h; sourceTree = "<group>"; };
-               E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VM.cpp; sourceTree = "<group>"; };
+               E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VM.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+               E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = VM.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
                E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; };
                E49DC15112EF272200184A1F /* SourceProviderCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCache.h; sourceTree = "<group>"; };
                E49DC15512EF277200184A1F /* SourceProviderCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProviderCache.cpp; sourceTree = "<group>"; };
                F692A87D0255597D01FF60F7 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = "<group>"; tabWidth = 8; };
                F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
                F692A8870255597D01FF60F7 /* JSCJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCJSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
+               FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExecutionTimeLimitTest.cpp; path = API/tests/ExecutionTimeLimitTest.cpp; sourceTree = "<group>"; };
+               FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionTimeLimitTest.h; path = API/tests/ExecutionTimeLimitTest.h; sourceTree = "<group>"; };
+               FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalContextWithFinalizerTest.cpp; path = API/tests/GlobalContextWithFinalizerTest.cpp; sourceTree = "<group>"; };
+               FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalContextWithFinalizerTest.h; path = API/tests/GlobalContextWithFinalizerTest.h; sourceTree = "<group>"; };
+               FE1C0FFC1B193E9800B53FCA /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = "<group>"; };
+               FE1C0FFE1B194FD100B53FCA /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = "<group>"; };
                FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
                FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
-               FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
-               FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
-               FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWatchpointSetInlines.h; sourceTree = "<group>"; };
+               FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVM.cpp; sourceTree = "<group>"; };
+               FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDollarVM.h; sourceTree = "<group>"; };
+               FE384EE31ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVMPrototype.cpp; sourceTree = "<group>"; };
+               FE384EE41ADDB7AD0055DE2C /* JSDollarVMPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDollarVMPrototype.h; sourceTree = "<group>"; };
+               FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
+               FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
+               FE4D55B71AE716CA0052E459 /* IterationStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterationStatus.h; sourceTree = "<group>"; };
+               FE5068641AE246390009DAB7 /* DeferredSourceDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferredSourceDump.h; sourceTree = "<group>"; };
+               FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredSourceDump.cpp; sourceTree = "<group>"; };
                FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; };
                FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = "<group>"; };
+               FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapVerifier.cpp; sourceTree = "<group>"; };
+               FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapVerifier.h; sourceTree = "<group>"; };
                FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; };
                FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; };
                FEB51F6A1A97B688001F921C /* Regress141809.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Regress141809.h; path = API/tests/Regress141809.h; sourceTree = "<group>"; };
                FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Watchdog.cpp; sourceTree = "<group>"; };
                FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = "<group>"; };
                FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WatchdogMac.cpp; sourceTree = "<group>"; };
-               FEE7D5A00D99AC04005351F6 /* iOS.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = iOS.xcconfig; sourceTree = "<group>"; };
+               FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
+               FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
                FEF6835A174343CC00A32E25 /* JITStubsARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM.h; sourceTree = "<group>"; };
                FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARMv7.h; sourceTree = "<group>"; };
                FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsX86_64.h; sourceTree = "<group>"; };
                                141211200A48793C00480255 /* minidom */,
                                14BD59BF0A3E8F9000BAF59C /* testapi */,
                                6511230514046A4C002B101D /* testRegExp */,
-                               55407AC818DA58AD00EFF7F2 /* libCompileRuntimeToLLVMIR.a */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                0FCEFAAD1805CA4400472CE4 /* llvm */ = {
                        isa = PBXGroup;
                        children = (
+                               9EA5C7A0190F05D200508EBE /* InitializeLLVMMac.cpp */,
                                0FCEFABF1805D94100472CE4 /* library */,
                                0FCEFAC41805E75500472CE4 /* InitializeLLVM.cpp */,
                                0FCEFAAE1805CA6D00472CE4 /* InitializeLLVM.h */,
-                               0FCEFAAF1805CA6D00472CE4 /* InitializeLLVMMac.mm */,
                                0FCEFAC51805E75500472CE4 /* InitializeLLVMPOSIX.cpp */,
                                0FCEFAC61805E75500472CE4 /* InitializeLLVMPOSIX.h */,
                                0FCEFAC71805E75500472CE4 /* LLVMAPI.cpp */,
                                0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */,
                                0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */,
                                0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */,
+                               0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */,
+                               0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */,
                                0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */,
                                0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */,
+                               0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */,
+                               0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */,
                                0F235BC417178E1C00690C7F /* FTLExitValue.cpp */,
                                0F235BC517178E1C00690C7F /* FTLExitValue.h */,
                                A7F2996917A0BB670010417A /* FTLFail.cpp */,
                                A78A977E179738D5009DF744 /* FTLJITFinalizer.h */,
                                0F6B1CB3185FC9E900845D97 /* FTLJSCall.cpp */,
                                0F6B1CB4185FC9E900845D97 /* FTLJSCall.h */,
+                               0FD1202D1A8AED12000F5280 /* FTLJSCallBase.cpp */,
+                               0FD1202E1A8AED12000F5280 /* FTLJSCallBase.h */,
+                               0FD120311A8C85BD000F5280 /* FTLJSCallVarargs.cpp */,
+                               0FD120321A8C85BD000F5280 /* FTLJSCallVarargs.h */,
                                0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */,
                                0F8F2B94172E049E007DBDA5 /* FTLLink.h */,
                                0FCEFADD180738C000472CE4 /* FTLLocation.cpp */,
                                0FEA0A04170513DB00BB722C /* FTLLowerDFGToLLVM.cpp */,
                                0FEA0A05170513DB00BB722C /* FTLLowerDFGToLLVM.h */,
                                A7D89D0117A0B90400773AD8 /* FTLLoweredNodeValue.h */,
+                               0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */,
+                               0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */,
                                0FD8A31717D51F2200CA2C40 /* FTLOSREntry.cpp */,
                                0FD8A31817D51F2200CA2C40 /* FTLOSREntry.h */,
                                0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */,
                141211000A48772600480255 /* tests */ = {
                        isa = PBXGroup;
                        children = (
+                               FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */,
+                               FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */,
                                C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */,
                                C203281F1981979D0088B499 /* CustomGlobalObjectClassTest.h */,
                                C29ECB021804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.h */,
                                C29ECB011804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.mm */,
                                C288B2DC18A54D3E007BE40B /* DateTests.h */,
                                C288B2DD18A54D3E007BE40B /* DateTests.mm */,
+                               FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */,
+                               FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */,
+                               FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */,
+                               FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */,
                                C2181FC018A948FB0025A235 /* JSExportTests.h */,
                                C2181FC118A948FB0025A235 /* JSExportTests.mm */,
+                               65570F581AA4C00A009B3C23 /* Regress141275.h */,
+                               65570F591AA4C00A009B3C23 /* Regress141275.mm */,
                                FEB51F6A1A97B688001F921C /* Regress141809.h */,
                                FEB51F6B1A97B688001F921C /* Regress141809.mm */,
                                144005170A531CB50005F061 /* minidom */,
                1429D77A0ED20D7300B89619 /* interpreter */ = {
                        isa = PBXGroup;
                        children = (
+                               658D3A5519638268003C45D6 /* VMEntryRecord.h */,
                                0F55F0F114D1063600AC7649 /* AbstractPC.cpp */,
                                0F55F0F214D1063600AC7649 /* AbstractPC.h */,
                                A7F8690E0F9584A100558697 /* CachedCall.h */,
                                149B24FF0D8AF6D1009CB8C7 /* Register.h */,
                                A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */,
                                A7C1EAED17987AB600299DB2 /* StackVisitor.h */,
-                               FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */,
-                               FE4A331E15BD2E07006F54F3 /* VMInspector.h */,
                        );
                        path = interpreter;
                        sourceTree = "<group>";
                1429D92C0ED22D7000B89619 /* jit */ = {
                        isa = PBXGroup;
                        children = (
+                               0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */,
+                               0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */,
                                0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */,
                                0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */,
                                0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */,
                                0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */,
                                0F24E53B17EA9F5900ABB217 /* AssemblyHelpers.cpp */,
                                0F24E53C17EA9F5900ABB217 /* AssemblyHelpers.h */,
+                               0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */,
+                               0F64B2701A784BAF006E4E66 /* BinarySwitch.h */,
                                0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */,
-                               0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */,
-                               0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */,
                                0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
                                A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
                                A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
                                14A6581A0F4E36F4000150FD /* JITStubs.h */,
                                FEF6835A174343CC00A32E25 /* JITStubsARM.h */,
                                FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */,
-                               FEF6835D174343CC00A32E25 /* JITStubsX86.h */,
                                FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */,
+                               FEF6835D174343CC00A32E25 /* JITStubsX86.h */,
                                A7A4AE0C17973B4D005612B1 /* JITStubsX86Common.h */,
                                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
                                0F5EF91C16878F78003E5C25 /* JITThunks.h */,
                                0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
+                               0FEE98421A89227500754E93 /* SetupVarargsFrame.cpp */,
+                               0FEE98401A8865B600754E93 /* SetupVarargsFrame.h */,
+                               0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */,
+                               0FE834161A6EF97B00D04847 /* PolymorphicCallStubRoutine.h */,
                                0FA7A8E918B413C80052371D /* Reg.cpp */,
                                0FA7A8EA18B413C80052371D /* Reg.h */,
                                0F6B1CBB1861246A00845D97 /* RegisterPreservationWrapperGenerator.cpp */,
                142E312A134FF0A600AFADB5 /* heap */ = {
                        isa = PBXGroup;
                        children = (
+                               FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */,
+                               FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */,
                                C2DA778218E259990066FCB6 /* HeapInlines.h */,
                                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */,
                                2AACE63A18CA5A0300ED0191 /* GCActivityCallback.cpp */,
                                2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */,
-                               14816E19154CC56C00B8054C /* BlockAllocator.cpp */,
-                               14816E1A154CC56C00B8054C /* BlockAllocator.h */,
                                0FD8A31117D4326C00CA2C40 /* CodeBlockSet.cpp */,
                                0FD8A31217D4326C00CA2C40 /* CodeBlockSet.h */,
                                146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
                                2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */,
                                2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */,
                                0F136D4B174AD69B0075B354 /* DeferGC.h */,
-                               2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */,
                                BCBE2CAD14E985AA000593AD /* GCAssertions.h */,
                                0F2B66A817B6B53D00A7AE3F /* GCIncomingRefCounted.h */,
                                0F2B66A917B6B53D00A7AE3F /* GCIncomingRefCountedInlines.h */,
                                146FA5A81378F6B0003627A3 /* HandleTypes.h */,
                                14BA7A9513AADFF8005B7C2C /* Heap.cpp */,
                                14BA7A9613AADFF8005B7C2C /* Heap.h */,
-                               C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */,
                                2AD8932917E3868F00668276 /* HeapIterationScope.h */,
                                2A6F462517E959CE00C45C98 /* HeapOperation.h */,
                                14F97446138C853E00DA1C67 /* HeapRootVisitor.h */,
                                142D6F0E13539A4100B02E86 /* MarkStack.cpp */,
                                142D6F0F13539A4100B02E86 /* MarkStack.h */,
                                2AAD964918569417001F93BE /* RecursiveAllocationScope.h */,
-                               C20B25981706536200C21F4E /* Region.h */,
                                C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
                                14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
                                0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */,
                                142E3132134FF0A600AFADB5 /* Strong.h */,
                                145722851437E140005FDE26 /* StrongInlines.h */,
-                               C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */,
-                               C2DF442E1707AC0100A5CA96 /* SuperRegion.h */,
                                141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
                                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */,
                                1ACF7376171CA6FB00C9BB1E /* Weak.cpp */,
                                86E3C609167BAB87006D760A /* JSContextInternal.h */,
                                14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */,
                                14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */,
+                               A5EA70ED19F5B5C40098F5EC /* JSContextRefInspectorSupport.h */,
                                A5D2E664195E173800A518E7 /* JSContextRefInternal.h */,
                                148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */,
                                A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */,
                                A72028B51797601E0098028C /* JSCTestRunnerUtils.h */,
                                86E3C60A167BAB87006D760A /* JSExport.h */,
+                               A552C37D1ADDB8FE00139726 /* JSRemoteInspector.cpp */,
+                               A552C37E1ADDB8FE00139726 /* JSRemoteInspector.h */,
                                C25D709A16DE99F400FCA6BC /* JSManagedValue.h */,
                                C25D709916DE99F400FCA6BC /* JSManagedValue.mm */,
                                2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */,
                                FEA0861E182B7A0400F6D851 /* Breakpoint.h */,
                                F692A8580255597D01FF60F7 /* Debugger.cpp */,
                                F692A8590255597D01FF60F7 /* Debugger.h */,
-                               BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */,
-                               BC3135620F302FA3003DFD3A /* DebuggerActivation.h */,
                                149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */,
                                1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */,
+                               6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */,
                                FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */,
+                               0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */,
+                               0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */,
                        );
                        path = debugger;
                        sourceTree = "<group>";
                                1C9051450BA9E8A70081E9D0 /* Base.xcconfig */,
                                1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */,
                                449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */,
-                               FEE7D5A00D99AC04005351F6 /* iOS.xcconfig */,
                                1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */,
                                5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */,
                                0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */,
                        children = (
                                BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */,
                                6514F21718B3E1670098FF8B /* Bytecodes.h */,
+                               A53243951856A475002ED692 /* CombinedDomains.json */,
                                BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
                                6514F21818B3E1670098FF8B /* InitBytecodes.asm */,
                                A513E5C6185F9436007E95AD /* InjectedScriptSource.h */,
-                               A53243951856A475002ED692 /* InspectorJS.json */,
-                               A53243961856A475002ED692 /* InspectorJSBackendCommands.js */,
-                               A532438118568317002ED692 /* InspectorJSBackendDispatchers.cpp */,
-                               A532438218568317002ED692 /* InspectorJSBackendDispatchers.h */,
-                               A532438318568317002ED692 /* InspectorJSFrontendDispatchers.cpp */,
-                               A532438418568317002ED692 /* InspectorJSFrontendDispatchers.h */,
-                               A532438518568317002ED692 /* InspectorJSTypeBuilders.cpp */,
-                               A532438618568317002ED692 /* InspectorJSTypeBuilders.h */,
+                               A5EA710D19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h */,
+                               A53243961856A475002ED692 /* InspectorBackendCommands.js */,
+                               A532438118568317002ED692 /* InspectorBackendDispatchers.cpp */,
+                               A532438218568317002ED692 /* InspectorBackendDispatchers.h */,
+                               A532438318568317002ED692 /* InspectorFrontendDispatchers.cpp */,
+                               A532438418568317002ED692 /* InspectorFrontendDispatchers.h */,
+                               A532438518568317002ED692 /* InspectorProtocolObjects.cpp */,
+                               A532438618568317002ED692 /* InspectorProtocolObjects.h */,
                                A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */,
                                A7D801A71880D6A80026C39B /* JSCBuiltins.h */,
                                BC87CDB810712ACA000614CF /* JSONObject.lut.h */,
                                BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */,
                                BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */,
                                A718F61A11754A21002465A7 /* RegExpJitTables.h */,
-                               BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */,
                                5D53727D0E1C55EC0021E549 /* TracingDtrace.h */,
                        );
                        name = "Derived Sources";
                                F692A8650255597D01FF60F7 /* Lexer.cpp */,
                                F692A8660255597D01FF60F7 /* Lexer.h */,
                                930DAD030FB1EB1A0082D205 /* NodeConstructors.h */,
-                               7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */,
                                F692A86D0255597D01FF60F7 /* Nodes.cpp */,
                                F692A86E0255597D01FF60F7 /* Nodes.h */,
                                93F0B3A909BB4DC00068FCE3 /* Parser.cpp */,
                                93052C320FB792190048FDC3 /* ParserArena.cpp */,
                                93052C330FB792190048FDC3 /* ParserArena.h */,
                                0FCCAE4316D0CF6E00D0C65B /* ParserError.h */,
+                               9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */,
                                A77F18241641925400640A47 /* ParserModes.h */,
                                65303D631447B9E100D3F904 /* ParserTokens.h */,
                                869EBCB60E8C6D4A008722CC /* ResultType.h */,
                        children = (
                                BCF605110E203EF800B9A64D /* ArgList.cpp */,
                                BCF605120E203EF800B9A64D /* ArgList.h */,
-                               BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
-                               BC257DE60E1F51C50016B6C9 /* Arguments.h */,
-                               A76140C7182982CB00750624 /* ArgumentsIteratorConstructor.cpp */,
-                               A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */,
-                               A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */,
-                               A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */,
+                               0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */,
                                0F6B1CB71861244C00845D97 /* ArityCheckMode.h */,
                                A7A8AF2517ADB5F2005AB174 /* ArrayBuffer.cpp */,
                                A7A8AF2617ADB5F3005AB174 /* ArrayBuffer.h */,
                                BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */,
                                BC7952070E15E8A800A898AB /* ArrayConstructor.h */,
                                0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */,
-                               A7BDAEC017F4EA1400F6140C /* ArrayIteratorConstructor.cpp */,
-                               A7BDAEC117F4EA1400F6140C /* ArrayIteratorConstructor.h */,
                                A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */,
                                A7BDAEC317F4EA1400F6140C /* ArrayIteratorPrototype.h */,
                                F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */,
                                F692A84E0255597D01FF60F7 /* ArrayPrototype.h */,
                                0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */,
+                               52678F8C1A031009006A306D /* BasicBlockLocation.cpp */,
+                               52678F8D1A031009006A306D /* BasicBlockLocation.h */,
                                147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */,
                                866739D013BFDE710023D87C /* BigInteger.h */,
                                BC7952320E15EB5600A898AB /* BooleanConstructor.cpp */,
                                704FD35305697E6D003DBED9 /* BooleanObject.h */,
                                BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */,
                                BC7952350E15EB5600A898AB /* BooleanPrototype.h */,
+                               9E72940A190F0514001A91B5 /* BundlePath.h */,
+                               9E729409190F0306001A91B5 /* BundlePath.mm */,
                                0FB7F38B15ED8E3800F167B2 /* Butterfly.h */,
                                0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */,
                                BCA62DFE0E2826230004F30D /* CallData.cpp */,
                                145C507F0D9DF63B0088F6B9 /* CallData.h */,
                                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
+                               0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */,
+                               0FE0501D1AA9095600D33B33 /* ClonedArguments.h */,
                                A77F181F164088B200640A47 /* CodeCache.cpp */,
                                A77F1820164088B200640A47 /* CodeCache.h */,
                                0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */,
                                A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */,
                                A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */,
                                A5FD0071189B038C00633231 /* ConsoleTypes.h */,
+                               0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */,
                                0FFC99D0184EC8AD009C10AB /* ConstantMode.h */,
                                BCA62DFF0E2826310004F30D /* ConstructData.cpp */,
                                BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */,
+                               52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */,
+                               52678F901A04177C006A306D /* ControlFlowProfiler.h */,
+                               2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */,
+                               2A111244192FCE79005EE18D /* CustomGetterSetter.h */,
                                0F2B66B017B6B5AB00A7AE3F /* DataView.cpp */,
                                0F2B66B117B6B5AB00A7AE3F /* DataView.h */,
                                BCD203450E17135E002C7E82 /* DateConstructor.cpp */,
                                14A1563010966365006FA260 /* DateInstanceCache.h */,
                                BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
                                BCD203480E17135E002C7E82 /* DatePrototype.h */,
+                               0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */,
+                               0FE050101AA9091100D33B33 /* DirectArguments.h */,
+                               0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */,
+                               0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */,
                                A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
                                A70447EC17A0BD7000F5898E /* DumpContext.h */,
+                               2AD2EDFA19799E38004D6478 /* EnumerationMode.h */,
                                BC337BEA0E1B00CB0076918A /* Error.cpp */,
                                BC3046060E1F497F003232CF /* Error.h */,
                                BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */,
                                BC02E98B0E183E38000F9297 /* ErrorInstance.h */,
                                BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */,
                                BC02E9070E1839DB000F9297 /* ErrorPrototype.h */,
+                               FE1C0FFC1B193E9800B53FCA /* Exception.h */,
+                               FE1C0FFE1B194FD100B53FCA /* Exception.cpp */,
+                               0F12DE0D1979D5FD0006FF4E /* ExceptionFuzz.cpp */,
+                               0F12DE0E1979D5FD0006FF4E /* ExceptionFuzz.h */,
                                1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */,
                                A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
                                86CA032D1038E8440028A609 /* Executable.cpp */,
                                BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
                                0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */,
                                0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */,
+                               52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */,
+                               52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */,
                                F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
                                F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
+                               62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */,
+                               62D2D38E1ADF103F000206C1 /* FunctionRareData.h */,
+                               0FE050111AA9091100D33B33 /* GenericArguments.h */,
+                               0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */,
+                               0FE050131AA9091100D33B33 /* GenericOffset.h */,
                                0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */,
                                0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */,
                                BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
                                0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */,
                                0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */,
                                0FB7F38F15ED8E3800F167B2 /* IndexingType.h */,
+                               0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */,
+                               0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */,
                                E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
                                E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
+                               A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
                                A7A8AF2C17ADB5F3005AB174 /* Int16Array.h */,
                                A7A8AF2D17ADB5F3005AB174 /* Int32Array.h */,
-                               A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
                                A78853F717972629001440E4 /* IntendedStructureChain.cpp */,
                                A78853F817972629001440E4 /* IntendedStructureChain.h */,
                                BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */,
                                BC11667A0E199C05008066DD /* InternalFunction.h */,
+                               A12BBFF31B044A9800664B69 /* IntlObject.cpp */,
+                               A12BBFF11B044A8B00664B69 /* IntlObject.h */,
                                86BF642A148DB2B5004DE36A /* Intrinsic.h */,
-                               14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */,
-                               14DA818E0D99FD2000B0A4FB /* JSActivation.h */,
-                               A76140CB182982CB00750624 /* JSArgumentsIterator.cpp */,
-                               A76140CC182982CB00750624 /* JSArgumentsIterator.h */,
+                               FE4D55B71AE716CA0052E459 /* IterationStatus.h */,
+                               70113D491A8DB093003848C4 /* IteratorOperations.cpp */,
+                               70113D4A1A8DB093003848C4 /* IteratorOperations.h */,
+                               70DC3E071B2DF2C700054299 /* IteratorPrototype.cpp */,
+                               70DC3E081B2DF2C700054299 /* IteratorPrototype.h */,
                                93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
                                938772E5038BFE19008635CE /* JSArray.h */,
                                0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
                                A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */,
                                86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */,
                                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */,
+                               657CF45619BF6662004ACBF2 /* JSCallee.cpp */,
+                               657CF45719BF6662004ACBF2 /* JSCallee.h */,
+                               0FD9497E1A97DB9600E28966 /* JSCatchScope.cpp */,
+                               0FD9497F1A97DB9600E28966 /* JSCatchScope.h */,
                                BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
                                BC1167D80E19BCC9008066DD /* JSCell.h */,
                                0F97496F1687ADE200A4FF6A /* JSCellInlines.h */,
                                9788FC221471AD0C0068CE2D /* JSDateMath.cpp */,
                                9788FC231471AD0C0068CE2D /* JSDateMath.h */,
                                C2A7F687160432D400F76B98 /* JSDestructibleObject.h */,
+                               BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */,
+                               14F252560D08DD8D004ECFFF /* JSEnvironmentRecord.h */,
                                A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */,
                                0F2B66C117B6B5AB00A7AE3F /* JSFloat32Array.h */,
                                0F2B66C217B6B5AB00A7AE3F /* JSFloat64Array.h */,
                                F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
                                F692A85F0255597D01FF60F7 /* JSFunction.h */,
                                A72028B91797603D0098028C /* JSFunctionInlines.h */,
+                               0FD949801A97DB9600E28966 /* JSFunctionNameScope.cpp */,
+                               0FD949811A97DB9600E28966 /* JSFunctionNameScope.h */,
                                0F2B66C317B6B5AB00A7AE3F /* JSGenericTypedArrayView.h */,
                                0F2B66C417B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h */,
                                0F2B66C517B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructorInlines.h */,
                                A59455911824744700CC3843 /* JSGlobalObjectDebuggable.h */,
                                BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
                                BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */,
+                               0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
                                0F2B66CA17B6B5AB00A7AE3F /* JSInt16Array.h */,
                                0F2B66CB17B6B5AB00A7AE3F /* JSInt32Array.h */,
-                               0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
+                               7013CA891B491A9400CAE613 /* JSJob.cpp */,
+                               7013CA8A1B491A9400CAE613 /* JSJob.h */,
+                               14DA818F0D99FD2000B0A4FB /* JSLexicalEnvironment.cpp */,
+                               14DA818E0D99FD2000B0A4FB /* JSLexicalEnvironment.h */,
                                65EA4C99092AF9E20093D800 /* JSLock.cpp */,
                                65EA4C9A092AF9E20093D800 /* JSLock.h */,
                                A700873F17CBE8EB00C3E643 /* JSMap.cpp */,
                                7C184E2117BEE240007CB63A /* JSPromiseConstructor.h */,
                                7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */,
                                7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */,
-                               7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */,
-                               7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */,
                                7C184E1C17BEE22E007CB63A /* JSPromisePrototype.cpp */,
                                7C184E1D17BEE22E007CB63A /* JSPromisePrototype.h */,
-                               7C008CDC1871258D00955C24 /* JSPromiseReaction.cpp */,
-                               7C008CDD1871258D00955C24 /* JSPromiseReaction.h */,
-                               A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */,
-                               A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */,
+                               2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */,
+                               2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */,
                                862553CE16136AA5009F17D0 /* JSProxy.cpp */,
                                862553CF16136AA5009F17D0 /* JSProxy.h */,
                                14874AE115EBDE4A002E3587 /* JSScope.cpp */,
                                BC02E9B60E1842FA000F9297 /* JSString.cpp */,
                                F692A8620255597D01FF60F7 /* JSString.h */,
                                86E85538111B9968001AF51E /* JSStringBuilder.h */,
+                               70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */,
+                               70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */,
                                2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */,
                                2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */,
                                0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */,
                                0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */,
+                               70ECA6001AFDBEA200449739 /* JSTemplateRegistryKey.cpp */,
+                               70ECA6011AFDBEA200449739 /* JSTemplateRegistryKey.h */,
                                14ABB454099C2A0F00E2A24F /* JSType.h */,
                                0F2B66CC17B6B5AB00A7AE3F /* JSTypedArrayConstructors.cpp */,
                                0F2B66CD17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h */,
                                0F2B66D017B6B5AB00A7AE3F /* JSTypedArrays.cpp */,
                                0F2B66D117B6B5AB00A7AE3F /* JSTypedArrays.h */,
                                6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
-                               0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
-                               0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
                                0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
                                0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
-                               BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */,
-                               14F252560D08DD8D004ECFFF /* JSVariableObject.h */,
+                               0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
+                               0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
                                A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
                                A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
+                               709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
+                               709FB8621AE335C60039D069 /* JSWeakSet.h */,
                                1442565F15EDE98D0066A49B /* JSWithScope.cpp */,
                                1442566015EDE98D0066A49B /* JSWithScope.h */,
                                65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */,
                                F692A8690255597D01FF60F7 /* Lookup.h */,
                                A700873717CBE85300C3E643 /* MapConstructor.cpp */,
                                A700873817CBE85300C3E643 /* MapConstructor.h */,
-                               A78507D417CBC6FD0011F6E7 /* MapData.cpp */,
                                A78507D517CBC6FD0011F6E7 /* MapData.h */,
-                               A74DEF8B182D991400522C22 /* MapIteratorConstructor.cpp */,
-                               A74DEF8C182D991400522C22 /* MapIteratorConstructor.h */,
+                               593D43CCA0BBE06D89C59707 /* MapDataInlines.h */,
                                A74DEF8D182D991400522C22 /* MapIteratorPrototype.cpp */,
                                A74DEF8E182D991400522C22 /* MapIteratorPrototype.h */,
                                A700873B17CBE8D300C3E643 /* MapPrototype.cpp */,
                                A700873C17CBE8D300C3E643 /* MapPrototype.h */,
                                8612E4CB1522918400C836BE /* MatchResult.h */,
+                               4340A4821A9051AF00D73CCA /* MathCommon.cpp */,
+                               4340A4831A9051AF00D73CCA /* MathCommon.h */,
                                F692A86A0255597D01FF60F7 /* MathObject.cpp */,
                                F692A86B0255597D01FF60F7 /* MathObject.h */,
                                90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */,
                                90213E3C123A40C200D422F3 /* MemoryStatistics.h */,
                                7C008CE5187631B600955C24 /* Microtask.h */,
-                               86EBF2F91560F036008E9222 /* NameConstructor.cpp */,
-                               86EBF2FA1560F036008E9222 /* NameConstructor.h */,
-                               86EBF2FB1560F036008E9222 /* NameInstance.cpp */,
-                               86EBF2FC1560F036008E9222 /* NameInstance.h */,
-                               86EBF2FD1560F036008E9222 /* NamePrototype.cpp */,
-                               86EBF2FE1560F036008E9222 /* NamePrototype.h */,
                                BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */,
                                BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */,
                                BC02E90A0E1839DB000F9297 /* NativeErrorPrototype.cpp */,
                                BC02E90B0E1839DB000F9297 /* NativeErrorPrototype.h */,
+                               6546F51F1A32A59C006F07D5 /* NullGetterFunction.cpp */,
+                               6546F5201A32A59C006F07D5 /* NullGetterFunction.h */,
+                               65525FC31A6DD3B3007B5495 /* NullSetterFunction.cpp */,
+                               65525FC41A6DD3B3007B5495 /* NullSetterFunction.h */,
                                BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */,
                                BC2680C30E16D4E900A06E92 /* NumberConstructor.h */,
                                F692A8700255597D01FF60F7 /* NumberObject.cpp */,
                                A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */,
                                BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */,
                                86158AB2155C8B3F00B45C9C /* PropertyName.h */,
-                               65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
                                65400C100A69BAF200509887 /* PropertyNameArray.h */,
                                0FF7168A15A3B231008F5DAA /* PropertyOffset.h */,
                                65621E6B089E859700760F35 /* PropertySlot.cpp */,
                                BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */,
                                0F6B1CB81861244C00845D97 /* RegisterPreservationMode.h */,
                                0FB7F39115ED8E3800F167B2 /* Reject.h */,
+                               70B0A9D01A9B66200001306A /* RuntimeFlags.h */,
+                               527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */,
+                               52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */,
                                0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
                                0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
+                               0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */,
+                               0FE0501F1AA9095600D33B33 /* ScopedArguments.h */,
+                               0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */,
+                               0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */,
+                               0FE050211AA9095600D33B33 /* ScopeOffset.cpp */,
+                               0FE050221AA9095600D33B33 /* ScopeOffset.h */,
                                A7299DA317D12858005F5FF9 /* SetConstructor.cpp */,
                                A7299DA417D12858005F5FF9 /* SetConstructor.h */,
-                               A790DD65182F499700588807 /* SetIteratorConstructor.cpp */,
-                               A790DD66182F499700588807 /* SetIteratorConstructor.h */,
                                A790DD67182F499700588807 /* SetIteratorPrototype.cpp */,
                                A790DD68182F499700588807 /* SetIteratorPrototype.h */,
                                A7299D9F17D12848005F5FF9 /* SetPrototype.cpp */,
                                A730B6101250068F009D25B1 /* StrictEvalActivation.h */,
                                BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
                                BC18C3C10E16EE3300B34460 /* StringConstructor.h */,
+                               70EC0EC01AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp */,
+                               70EC0EC11AA0D7DA00B6AAFA /* StringIteratorPrototype.h */,
                                BC18C3C20E16EE3300B34460 /* StringObject.cpp */,
                                BC18C3C30E16EE3300B34460 /* StringObject.h */,
                                BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */,
                                C2FE18A316BAEC4000AF3061 /* StructureRareData.h */,
                                C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */,
                                BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
+                               705B41A31A6E501E00716757 /* Symbol.cpp */,
+                               705B41A41A6E501E00716757 /* Symbol.h */,
+                               705B41A51A6E501E00716757 /* SymbolConstructor.cpp */,
+                               705B41A61A6E501E00716757 /* SymbolConstructor.h */,
+                               705B41A71A6E501E00716757 /* SymbolObject.cpp */,
+                               705B41A81A6E501E00716757 /* SymbolObject.h */,
+                               705B41A91A6E501E00716757 /* SymbolPrototype.cpp */,
+                               705B41AA1A6E501E00716757 /* SymbolPrototype.h */,
                                0F919D2715856770004A4E7D /* SymbolTable.cpp */,
                                14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+                               70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */,
+                               70ECA6031AFDBEA200449739 /* TemplateRegistry.h */,
+                               70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */,
                                0FA2C17917D7CF84009D015F /* TestRunnerUtils.cpp */,
                                0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */,
                                0F55989717C86C5600A1E543 /* ToNativeFromValue.h */,
                                0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */,
                                0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */,
                                0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */,
+                               52B310FE1975B4240080857C /* TypeLocationCache.cpp */,
+                               52B311001975B4670080857C /* TypeLocationCache.h */,
+                               0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */,
+                               0FFB6C371AF48DDC00DB1BF7 /* TypeofType.h */,
+                               52C952B819A28A1C0069B386 /* TypeProfiler.cpp */,
+                               52C952B619A289850069B386 /* TypeProfiler.h */,
+                               0F2D4DDF19832D91007D4B19 /* TypeProfilerLog.cpp */,
+                               0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */,
+                               0F2D4DE319832D91007D4B19 /* TypeSet.cpp */,
+                               0F2D4DE419832D91007D4B19 /* TypeSet.h */,
+                               A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
+                               A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
                                A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
                                866739D113BFDE710023D87C /* Uint16WithFraction.h */,
                                A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
-                               A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
-                               A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
+                               0FE050231AA9095600D33B33 /* VarOffset.cpp */,
+                               0FE050241AA9095600D33B33 /* VarOffset.h */,
                                E18E3A570DF9278C00D90B34 /* VM.cpp */,
                                E18E3A560DF9278C00D90B34 /* VM.h */,
                                FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */,
                                FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
                                FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
                                14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
+                               AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */,
                                A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */,
                                A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */,
                                A7CA3AE917DA5168006538AF /* WeakMapData.cpp */,
                                A7CA3ADF17DA41AE006538AF /* WeakMapPrototype.cpp */,
                                A7CA3AE017DA41AE006538AF /* WeakMapPrototype.h */,
                                1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
+                               709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */,
+                               709FB8641AE335C60039D069 /* WeakSetConstructor.h */,
+                               709FB8651AE335C60039D069 /* WeakSetPrototype.cpp */,
+                               709FB8661AE335C60039D069 /* WeakSetPrototype.h */,
                                A7DCB77912E3D90500911940 /* WriteBarrier.h */,
                                C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
-                               2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */,
-                               2A111244192FCE79005EE18D /* CustomGetterSetter.h */,
                        );
                        path = runtime;
                        sourceTree = "<group>";
                                86B5822F14D2373B00A9C306 /* CodeProfile.h */,
                                8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */,
                                8603CEF314C7546400AE59E3 /* CodeProfiling.h */,
+                               FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */,
+                               FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */,
+                               FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */,
+                               FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */,
+                               FE384EE31ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp */,
+                               FE384EE41ADDB7AD0055DE2C /* JSDollarVMPrototype.h */,
                                86B5822C14D22F5F00A9C306 /* ProfileTreeNode.h */,
                                86B5826A14D35D5100A9C306 /* TieredMMapArray.h */,
                        );
                                0FB4B51916B62772003F696B /* DFGAllocator.h */,
                                A73781091799EA2E00817533 /* DFGAnalysis.h */,
                                0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
-                               0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
-                               0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
+                               0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */,
+                               0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */,
+                               0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */,
+                               0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */,
                                0F48531F187750560083B687 /* DFGArithMode.cpp */,
                                0F485320187750560083B687 /* DFGArithMode.h */,
                                0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */,
                                A7D9A29017A0BC7400EE2618 /* DFGAtTailAbstractState.h */,
                                0F666EC21835672B00D017F1 /* DFGAvailability.cpp */,
                                0F666EC31835672B00D017F1 /* DFGAvailability.h */,
+                               0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */,
+                               0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */,
                                0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
                                0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
                                A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */,
                                0F620170143FCD2F0068B77C /* DFGBasicBlock.h */,
                                0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */,
-                               A70B083017A0B79B00DAF14B /* DFGBinarySwitch.cpp */,
-                               A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */,
                                A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */,
                                A7D89CE517A0B8CC00773AD8 /* DFGBlockInsertionSet.h */,
+                               0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */,
+                               0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */,
+                               0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */,
+                               0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */,
+                               0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */,
+                               0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */,
+                               0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */,
                                0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */,
                                86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
                                86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,
                                0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */,
+                               0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */,
                                0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */,
                                0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */,
                                0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */,
                                0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */,
                                0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */,
                                0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */,
+                               0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */,
+                               0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */,
                                A77A423817A0BBFD00A8DB81 /* DFGClobberize.cpp */,
                                A77A423917A0BBFD00A8DB81 /* DFGClobberize.h */,
                                A77A423A17A0BBFD00A8DB81 /* DFGClobberSet.cpp */,
                                A77A423B17A0BBFD00A8DB81 /* DFGClobberSet.h */,
+                               0F04396B1B03DC0B009598B7 /* DFGCombinedLiveness.cpp */,
+                               0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */,
                                0FB4B51A16B62772003F696B /* DFGCommon.cpp */,
                                0FC0977E1469EBC400CF2442 /* DFGCommon.h */,
                                0FEA0A2D170D40BF00BB722C /* DFGCommonData.cpp */,
                                0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */,
                                0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */,
                                0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */,
+                               0FED67B71B26256D0066CE15 /* DFGConstantHoistingPhase.cpp */,
+                               0FED67B81B26256D0066CE15 /* DFGConstantHoistingPhase.h */,
                                0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */,
                                0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */,
                                A7D89CE617A0B8CC00773AD8 /* DFGCriticalEdgeBreakingPhase.cpp */,
                                0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */,
                                0F8F2B97172F04FD007DBDA5 /* DFGDesiredIdentifiers.cpp */,
                                0F8F2B98172F04FD007DBDA5 /* DFGDesiredIdentifiers.h */,
-                               A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */,
-                               A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */,
                                C2C0F7CB17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp */,
                                C2C0F7CC17BBFC5B00464FE4 /* DFGDesiredTransitions.h */,
                                0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */,
                                C2981FDB17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.h */,
                                0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */,
                                0FF427621591A1C9004CB9FF /* DFGDisassembler.h */,
+                               0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */,
+                               0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */,
                                0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */,
                                0FD81AD0154FB4EB00983E72 /* DFGDominators.h */,
                                0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */,
                                0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */,
                                A7D9A29117A0BC7400EE2618 /* DFGEdgeDominates.h */,
                                A7986D5617A0BB1E00A95DD0 /* DFGEdgeUsesStructure.h */,
+                               0F8F142F1ADF090100ED792C /* DFGEpoch.cpp */,
+                               0F8F14301ADF090100ED792C /* DFGEpoch.h */,
                                A78A976C179738B8009DF744 /* DFGFailedFinalizer.cpp */,
                                A78A976D179738B8009DF744 /* DFGFailedFinalizer.h */,
                                A7BFF3BF179868940002F462 /* DFGFiltrationResult.h */,
                                0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
                                A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
                                A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
+                               0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */,
+                               0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
+                               0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
+                               2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
+                               2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
                                86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */,
                                86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */,
                                86EC9DB81328DF82002B2AD7 /* DFGGraph.h */,
                                0F2FCCF218A60070001A27F8 /* DFGGraphSafepoint.cpp */,
                                0F2FCCF318A60070001A27F8 /* DFGGraphSafepoint.h */,
+                               0FB1765C196B8F9E0091052A /* DFGHeapLocation.cpp */,
+                               0FB1765D196B8F9E0091052A /* DFGHeapLocation.h */,
                                0FB14E201812570B009B6B4D /* DFGInlineCacheWrapper.h */,
                                0FB14E2218130955009B6B4D /* DFGInlineCacheWrapperInlines.h */,
                                A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */,
                                A704D90117A0BAA8006BA554 /* DFGInPlaceAbstractState.h */,
                                0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */,
+                               0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */,
+                               0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */,
                                0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */,
                                0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */,
+                               0F898F2F1B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp */,
+                               0F898F301B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h */,
                                0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */,
                                0FC97F3818202119002C9B26 /* DFGInvalidationPointInjectionPhase.h */,
                                0FEA0A2F170D40BF00BB722C /* DFGJITCode.cpp */,
                                0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */,
                                A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */,
                                A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */,
+                               62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */,
+                               62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */,
                                A7D9A29217A0BC7400EE2618 /* DFGLICMPhase.cpp */,
                                A7D9A29317A0BC7400EE2618 /* DFGLICMPhase.h */,
                                A7D89CEC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.cpp */,
                                0FB4B51D16B62772003F696B /* DFGLongLivedState.h */,
                                A767B5B317A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp */,
                                A767B5B417A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h */,
+                               0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */,
+                               0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */,
                                A704D90217A0BAA8006BA554 /* DFGMergeMode.h */,
+                               0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */,
                                0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */,
                                0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
                                0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
                                0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */,
+                               0F8F14311ADF090100ED792C /* DFGMovHintRemovalPhase.cpp */,
+                               0F8F14321ADF090100ED792C /* DFGMovHintRemovalPhase.h */,
+                               0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */,
+                               0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */,
                                A737810A1799EA2E00817533 /* DFGNaturalLoops.cpp */,
                                A737810B1799EA2E00817533 /* DFGNaturalLoops.h */,
                                0FB4B51E16B62772003F696B /* DFGNode.cpp */,
                                0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
                                0F300B7718AB051100A6D72E /* DFGNodeOrigin.h */,
                                0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
+                               0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */,
+                               0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */,
+                               0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */,
+                               0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */,
                                86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */,
                                86EC9DC01328DF82002B2AD7 /* DFGOperations.h */,
                                A7D89CEE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp */,
                                0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */,
                                0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */,
                                0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */,
+                               0F392C871B46188400844728 /* DFGOSRExitFuzz.cpp */,
+                               0F392C881B46188400844728 /* DFGOSRExitFuzz.h */,
                                0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */,
                                0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
                                0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */,
                                0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */,
+                               0F6237951AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp */,
+                               0F6237961AE45CA700D402EA /* DFGPhantomInsertionPhase.h */,
                                0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
                                0FFFC95014EF909500C72532 /* DFGPhase.h */,
+                               0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */,
+                               0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */,
                                A78A9772179738B8009DF744 /* DFGPlan.cpp */,
                                A78A9773179738B8009DF744 /* DFGPlan.h */,
+                               DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */,
                                0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
                                0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
                                0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
                                0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
+                               0F3E01A819D353A500F61B7F /* DFGPrePostNumbering.cpp */,
+                               0F3E01A919D353A500F61B7F /* DFGPrePostNumbering.h */,
+                               0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */,
+                               0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */,
+                               0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */,
+                               0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */,
+                               0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
+                               0F3A1BF71A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp */,
+                               0F3A1BF81A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h */,
                                86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
-                               0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */,
-                               0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */,
                                0F2FCCF418A60070001A27F8 /* DFGSafepoint.cpp */,
                                0F2FCCF518A60070001A27F8 /* DFGSafepoint.h */,
                                A77A423C17A0BBFD00A8DB81 /* DFGSafeToExecute.h */,
                                86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */,
                                86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */,
                                86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */,
+                               0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */,
+                               0F682FB119BCB36400FA3BAD /* DFGSSACalculator.h */,
                                A7D89CF017A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp */,
                                A7D89CF117A0B8CC00773AD8 /* DFGSSAConversionPhase.h */,
                                0FC20CB718556A3500C9E954 /* DFGSSALoweringPhase.cpp */,
                                0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */,
                                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */,
                                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */,
-                               2ACCF3DC185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp */,
-                               2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */,
+                               0F9E32611B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp */,
+                               0F9E32621B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h */,
                                0FC20CB31852E2C600C9E954 /* DFGStrengthReductionPhase.cpp */,
                                0FC20CB41852E2C600C9E954 /* DFGStrengthReductionPhase.h */,
+                               0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */,
                                0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */,
+                               0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */,
+                               0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */,
+                               0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */,
                                0F2FCCF718A60070001A27F8 /* DFGThreadData.cpp */,
                                0F2FCCF818A60070001A27F8 /* DFGThreadData.h */,
                                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
                                0FD8A32217D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h */,
                                0FD8A32317D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp */,
                                0FD8A32417D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h */,
+                               0FE7211B193B9C590031F6ED /* DFGTransition.cpp */,
+                               0FE7211C193B9C590031F6ED /* DFGTransition.h */,
                                0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */,
                                0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */,
                                0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
                                0F34B14816D4200E001CDA5A /* DFGUseKind.h */,
                                0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
                                0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
-                               0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
                                0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */,
                                0F2BDC401522801700CD8910 /* DFGValueSource.h */,
+                               0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
+                               0F0123311944EA1B00843A0C /* DFGValueStrength.h */,
+                               0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */,
+                               0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */,
                                0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */,
                                0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */,
                                0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */,
                                0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */,
                                0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */,
                                0FDB2CE6174830A2007B3C1B /* DFGWorklist.h */,
-                               2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
-                               2A88067719107D5500CB0BBB /* DFGFunctionWhitelist.h */,
                        );
                        name = dfg;
                        sourceTree = "<group>";
                                8640923B156EED3B00566CB2 /* ARM64Assembler.h */,
                                86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */,
                                86D3B2C010156BDE002865E7 /* ARMAssembler.h */,
-                               A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */,
                                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */,
                                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
                                86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */,
                                C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
                                C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
                                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
+                               7094C4DC1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp */,
+                               7094C4DD1AE439530041A2EE /* BytecodeIntrinsicRegistry.h */,
+                               0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */,
                                6529FB3118B2D99900C61102 /* BytecodeList.json */,
                                C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
                                C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
                                0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */,
                                0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */,
                                0F8023E91613832300A0BA45 /* ByValInfo.h */,
+                               0F64B2771A7957B2006E4E66 /* CallEdge.cpp */,
+                               0F64B2781A7957B2006E4E66 /* CallEdge.h */,
                                0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */,
                                0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */,
                                0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
                                0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
                                0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
+                               0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */,
+                               0F3B7E2519A11B8000D9BC56 /* CallVariant.h */,
                                969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
                                969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
                                0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */,
                                0FBD7E671447998F00481315 /* CodeOrigin.h */,
                                0F8F943F1667632D00D61971 /* CodeType.cpp */,
                                0F0B83A514BCF50400885B4F /* CodeType.h */,
+                               0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */,
+                               0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */,
+                               0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */,
+                               0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */,
                                0F426A4A1460CD6B00131F8F /* DataFormat.h */,
                                0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
                                0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
+                               FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */,
+                               FE5068641AE246390009DAB7 /* DeferredSourceDump.h */,
                                0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
                                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
                                969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
                                0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
                                0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */,
                                0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */,
-                               0FC97F31182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp */,
-                               0FC97F32182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h */,
                                0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
                                0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
                                0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */,
                                0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */,
                                0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
                                0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
+                               0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */,
                                0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
                                0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */,
                                0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */,
                                BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */,
                                BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
+                               0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */,
+                               0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */,
+                               0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */,
+                               0F952ABB1B487A7700C367C5 /* TrackedReferences.h */,
+                               0F2D4DE719832DAC007D4B19 /* TypeLocation.h */,
                                A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
                                A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
                                B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */,
                                0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
                                0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */,
                                0F426A451460CBAB00131F8F /* ValueRecovery.h */,
-                               0F9181C618415CA50057B669 /* VariableWatchpointSet.h */,
-                               FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */,
+                               0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */,
+                               0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */,
+                               0F20C2581A8013AB00DA3229 /* VirtualRegister.cpp */,
                                0F426A461460CBAB00131F8F /* VirtualRegister.h */,
                                0F919D2215853CDE004A4E7D /* Watchpoint.cpp */,
                                0F919D2315853CDE004A4E7D /* Watchpoint.h */,
                                A5FD0080189B191A00633231 /* InspectorConsoleAgent.h */,
                                A57D23E31890CEBF0031C7FA /* InspectorDebuggerAgent.cpp */,
                                A57D23E41890CEBF0031C7FA /* InspectorDebuggerAgent.h */,
-                               1CAA9A1C18F4997F000A369D /* InspectorProfilerAgent.cpp */,
-                               1CAA9A1D18F4997F000A369D /* InspectorProfilerAgent.h */,
                                A50E4B5D18809DD50068A46D /* InspectorRuntimeAgent.cpp */,
                                A50E4B5E18809DD50068A46D /* InspectorRuntimeAgent.h */,
                                A5FD0083189B1B7E00633231 /* JSGlobalObjectConsoleAgent.cpp */,
                                A5FD0084189B1B7E00633231 /* JSGlobalObjectConsoleAgent.h */,
                                A57D23E71891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp */,
                                A57D23E81891B0770031C7FA /* JSGlobalObjectDebuggerAgent.h */,
-                               1CAA9A2018F4A220000A369D /* JSGlobalObjectProfilerAgent.cpp */,
-                               1CAA9A2118F4A220000A369D /* JSGlobalObjectProfilerAgent.h */,
                                A50E4B5F18809DD50068A46D /* JSGlobalObjectRuntimeAgent.cpp */,
                                A50E4B6018809DD50068A46D /* JSGlobalObjectRuntimeAgent.h */,
                        );
                A532438E185696CE002ED692 /* scripts */ = {
                        isa = PBXGroup;
                        children = (
-                               A532438F185696E6002ED692 /* CodeGeneratorInspector.py */,
-                               A5324390185696E6002ED692 /* CodeGeneratorInspectorStrings.py */,
+                               C4703CC1192844A40013FBEA /* codegen */,
                                A5840E26187C980700843B10 /* cssmin.py */,
                                A5324391185696E6002ED692 /* generate-combined-inspector-json.py */,
+                               C4703CBF192844960013FBEA /* generate-inspector-protocol-bindings.py */,
                                A5840E28187CA5B800843B10 /* inline-and-minify-stylesheets-and-scripts.py */,
                                A513E5C4185F92DC007E95AD /* jsmin.py */,
                                A513E5C5185F92F0007E95AD /* xxd.pl */,
                        isa = PBXGroup;
                        children = (
                                A513E5CC185FB992007E95AD /* agents */,
+                               A5EA70E319F5B0E20098F5EC /* augmentable */,
                                A532438D185696CA002ED692 /* protocol */,
                                A5BA15E01823409D00A82E69 /* remote */,
                                A532438E185696CE002ED692 /* scripts */,
                                A593CF7B1840360300BFCE27 /* InspectorBackendDispatcher.h */,
                                A5D0A1BA1862301B00C7B496 /* InspectorEnvironment.h */,
                                A5945594182479EB00CC3843 /* InspectorFrontendChannel.h */,
-                               A55D93AB18514F7900400DED /* InspectorTypeBuilder.h */,
+                               A55D93AB18514F7900400DED /* InspectorProtocolTypes.h */,
                                A593CF801840377100BFCE27 /* InspectorValues.cpp */,
                                A593CF811840377100BFCE27 /* InspectorValues.h */,
                                A503FA13188E0FAF00110F14 /* JavaScriptCallFrame.cpp */,
                                A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */,
-                               A5C3A1A318C0490200C9593A /* JSConsoleClient.cpp */,
-                               A5C3A1A418C0490200C9593A /* JSConsoleClient.h */,
+                               A5C3A1A318C0490200C9593A /* JSGlobalObjectConsoleClient.cpp */,
+                               A5C3A1A418C0490200C9593A /* JSGlobalObjectConsoleClient.h */,
                                A51007BE187CC3C600B38879 /* JSGlobalObjectInspectorController.cpp */,
                                A51007BF187CC3C600B38879 /* JSGlobalObjectInspectorController.h */,
                                A503FA27188F105900110F14 /* JSGlobalObjectScriptDebugServer.cpp */,
                        path = remote;
                        sourceTree = "<group>";
                };
+               A5EA70E319F5B0E20098F5EC /* augmentable */ = {
+                       isa = PBXGroup;
+                       children = (
+                               A5EA70E419F5B1010098F5EC /* AugmentableInspectorController.h */,
+                               A5EA70E519F5B1010098F5EC /* AugmentableInspectorControllerClient.h */,
+                               A5EA70E619F5B1010098F5EC /* AlternateDispatchableAgent.h */,
+                       );
+                       path = augmentable;
+                       sourceTree = "<group>";
+               };
                A7D8019F1880D66E0026C39B /* builtins */ = {
                        isa = PBXGroup;
                        children = (
                        path = builtins;
                        sourceTree = "<group>";
                };
+               C4703CC1192844A40013FBEA /* codegen */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C4703CC2192844CC0013FBEA /* __init__.py */,
+                               C4F4B6CF1A05C76F005CAB76 /* cpp_generator_templates.py */,
+                               C4F4B6D01A05C76F005CAB76 /* cpp_generator.py */,
+                               A5EA70EA19F5B3D50098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py */,
+                               C4F4B6D11A05C76F005CAB76 /* generate_cpp_backend_dispatcher_header.py */,
+                               C4F4B6D21A05C76F005CAB76 /* generate_cpp_backend_dispatcher_implementation.py */,
+                               C4F4B6D31A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_header.py */,
+                               C4F4B6D41A05C76F005CAB76 /* generate_cpp_frontend_dispatcher_implementation.py */,
+                               C4F4B6D51A05C76F005CAB76 /* generate_cpp_protocol_types_header.py */,
+                               C4F4B6D61A05C76F005CAB76 /* generate_cpp_protocol_types_implementation.py */,
+                               C4703CC3192844CC0013FBEA /* generate_js_backend_commands.py */,
+                               A5EA70EF19F6DE5A0098F5EC /* generate_objc_backend_dispatcher_header.py */,
+                               A5EA70F019F6DE5A0098F5EC /* generate_objc_backend_dispatcher_implementation.py */,
+                               A5EA70F119F6DE5A0098F5EC /* generate_objc_configuration_header.py */,
+                               A5EA70F219F6DE5A0098F5EC /* generate_objc_configuration_implementation.py */,
+                               A5EA70F319F6DE5A0098F5EC /* generate_objc_conversion_helpers.py */,
+                               A5EA70F419F6DE5A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py */,
+                               A5EA70F519F6DE5A0098F5EC /* generate_objc_header.py */,
+                               A5EA70F619F6DE5A0098F5EC /* generate_objc_internal_header.py */,
+                               C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */,
+                               C4703CCA192844CC0013FBEA /* generator_templates.py */,
+                               C4703CCB192844CC0013FBEA /* generator.py */,
+                               C4703CCC192844CC0013FBEA /* models.py */,
+                               C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */,
+                               A5EA70F819F6DE5A0098F5EC /* objc_generator.py */,
+                       );
+                       path = codegen;
+                       sourceTree = "<group>";
+               };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
-               5540756C18DA58AD00EFF7F2 /* Headers */ = {
-                       isa = PBXHeadersBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               5540757318DA58AD00EFF7F2 /* Arguments.h in Headers */,
-                               5540757418DA58AD00EFF7F2 /* ArgumentsIteratorConstructor.h in Headers */,
-                               5540757518DA58AD00EFF7F2 /* ArgumentsIteratorPrototype.h in Headers */,
-                               5540758618DA58AD00EFF7F2 /* ArrayConstructor.h in Headers */,
-                               5540758818DA58AD00EFF7F2 /* ArrayIteratorConstructor.h in Headers */,
-                               5540758918DA58AD00EFF7F2 /* ArrayIteratorPrototype.h in Headers */,
-                               5540759318DA58AD00EFF7F2 /* BatchedTransitionOptimizer.h in Headers */,
-                               5540759418DA58AD00EFF7F2 /* BigInteger.h in Headers */,
-                               554075BB18DA58AD00EFF7F2 /* CommonSlowPathsExceptions.h in Headers */,
-                               554075BE18DA58AD00EFF7F2 /* JSConsole.h in Headers */,
-                               554075D618DA58AD00EFF7F2 /* DateConstructor.h in Headers */,
-                               554075D718DA58AD00EFF7F2 /* DateConversion.h in Headers */,
-                               554075DA18DA58AD00EFF7F2 /* DatePrototype.h in Headers */,
-                               5540767118DA58AD00EFF7F2 /* ErrorConstructor.h in Headers */,
-                               5540769118DA58AD00EFF7F2 /* ConsolePrototype.h in Headers */,
-                               5540771818DA58AD00EFF7F2 /* JSActivation.h in Headers */,
-                               5540771B18DA58AD00EFF7F2 /* JSArgumentsIterator.h in Headers */,
-                               5540772218DA58AD00EFF7F2 /* JSArrayIterator.h in Headers */,
-                               5540772518DA58AD00EFF7F2 /* (null) in Headers */,
-                               5540774818DA58AD00EFF7F2 /* JSGlobalObjectDebuggable.h in Headers */,
-                               5540774A18DA58AD00EFF7F2 /* JSGlobalObjectFunctions.h in Headers */,
-                               5540775918DA58AD00EFF7F2 /* JSMapIterator.h in Headers */,
-                               5540776318DA58AD00EFF7F2 /* JSPromiseConstructor.h in Headers */,
-                               5540776618DA58AD00EFF7F2 /* JSPromisePrototype.h in Headers */,
-                               5540776718DA58AD00EFF7F2 /* JSPromiseReaction.h in Headers */,
-                               5540776F18DA58AD00EFF7F2 /* JSSetIterator.h in Headers */,
-                               5540777118DA58AD00EFF7F2 /* JSStackInlines.h in Headers */,
-                               5540777318DA58AD00EFF7F2 /* JSStringBuilder.h in Headers */,
-                               5540777418DA58AD00EFF7F2 /* JSStringJoiner.h in Headers */,
-                               5540778818DA58AD00EFF7F2 /* JSWeakMap.h in Headers */,
-                               5540779818DA58AD00EFF7F2 /* LiteralParser.h in Headers */,
-                               554077B718DA58AD00EFF7F2 /* MapConstructor.h in Headers */,
-                               554077B918DA58AD00EFF7F2 /* MapIteratorConstructor.h in Headers */,
-                               554077BA18DA58AD00EFF7F2 /* MapIteratorPrototype.h in Headers */,
-                               554077BB18DA58AD00EFF7F2 /* MapPrototype.h in Headers */,
-                               554077C718DA58AD00EFF7F2 /* NameConstructor.h in Headers */,
-                               554077C818DA58AD00EFF7F2 /* NameInstance.h in Headers */,
-                               554077C918DA58AD00EFF7F2 /* NamePrototype.h in Headers */,
-                               554077CA18DA58AD00EFF7F2 /* NativeErrorConstructor.h in Headers */,
-                               554077CB18DA58AD00EFF7F2 /* NativeErrorPrototype.h in Headers */,
-                               554077D118DA58AD00EFF7F2 /* NumberConstructor.h in Headers */,
-                               5540757C18DA58AD00EFF7F2 /* StructureIDBlob.h in Headers */,
-                               5540758318DA58AD00EFF7F2 /* ArrayBuffer.h in Headers */,
-                               5540758418DA58AD00EFF7F2 /* ArrayBufferNeuteringWatchpoint.h in Headers */,
-                               5540758518DA58AD00EFF7F2 /* ArrayBufferView.h in Headers */,
-                               5540758718DA58AD00EFF7F2 /* ArrayConventions.h in Headers */,
-                               5540758B18DA58AD00EFF7F2 /* ArrayPrototype.h in Headers */,
-                               5540758D18DA58AD00EFF7F2 /* StructureIDTable.h in Headers */,
-                               5540758E18DA58AD00EFF7F2 /* ArrayStorage.h in Headers */,
-                               5540759618DA58AD00EFF7F2 /* BooleanObject.h in Headers */,
-                               5540759A18DA58AD00EFF7F2 /* Butterfly.h in Headers */,
-                               5540759B18DA58AD00EFF7F2 /* ButterflyInlines.h in Headers */,
-                               554075A318DA58AD00EFF7F2 /* CallData.h in Headers */,
-                               554075AB18DA58AD00EFF7F2 /* ClassInfo.h in Headers */,
-                               554075B218DA58AD00EFF7F2 /* CodeCache.h in Headers */,
-                               554075B718DA58AD00EFF7F2 /* CodeSpecializationKind.h in Headers */,
-                               554075B918DA58AD00EFF7F2 /* CommonIdentifiers.h in Headers */,
-                               554075BA18DA58AD00EFF7F2 /* CommonSlowPaths.h in Headers */,
-                               554075BD18DA58AD00EFF7F2 /* CompilationResult.h in Headers */,
-                               554075BF18DA58AD00EFF7F2 /* Completion.h in Headers */,
-                               554075C018DA58AD00EFF7F2 /* ConcurrentJITLock.h in Headers */,
-                               554075C418DA58AD00EFF7F2 /* ConsoleTypes.h in Headers */,
-                               554075C518DA58AD00EFF7F2 /* ConstantMode.h in Headers */,
-                               554075C618DA58AD00EFF7F2 /* ConstructData.h in Headers */,
-                               554075D518DA58AD00EFF7F2 /* DataView.h in Headers */,
-                               554075D818DA58AD00EFF7F2 /* DateInstance.h in Headers */,
-                               554075D918DA58AD00EFF7F2 /* DateInstanceCache.h in Headers */,
-                               554075DC18DA58AD00EFF7F2 /* Debugger.h in Headers */,
-                               5540766D18DA58AD00EFF7F2 /* DumpContext.h in Headers */,
-                               5540767018DA58AD00EFF7F2 /* Error.h in Headers */,
-                               5540767218DA58AD00EFF7F2 /* ErrorHandlingScope.h in Headers */,
-                               5540767318DA58AD00EFF7F2 /* ErrorInstance.h in Headers */,
-                               5540767418DA58AD00EFF7F2 /* ErrorPrototype.h in Headers */,
-                               5540767718DA58AD00EFF7F2 /* ExceptionHelpers.h in Headers */,
-                               5540767818DA58AD00EFF7F2 /* Executable.h in Headers */,
-                               5540767E18DA58AD00EFF7F2 /* Float32Array.h in Headers */,
-                               5540767F18DA58AD00EFF7F2 /* Float64Array.h in Headers */,
-                               5540768318DA58AD00EFF7F2 /* ConsoleClient.h in Headers */,
-                               554076B618DA58AD00EFF7F2 /* FunctionConstructor.h in Headers */,
-                               554076B718DA58AD00EFF7F2 /* FunctionExecutableDump.h in Headers */,
-                               554076B818DA58AD00EFF7F2 /* FunctionPrototype.h in Headers */,
-                               554076C218DA58AD00EFF7F2 /* GenericTypedArrayView.h in Headers */,
-                               554076C318DA58AD00EFF7F2 /* GenericTypedArrayViewInlines.h in Headers */,
-                               554076D618DA58AD00EFF7F2 /* Identifier.h in Headers */,
-                               554076DA18DA58AD00EFF7F2 /* IndexingHeader.h in Headers */,
-                               554076DB18DA58AD00EFF7F2 /* IndexingHeaderInlines.h in Headers */,
-                               554076DC18DA58AD00EFF7F2 /* IndexingType.h in Headers */,
-                               554076DF18DA58AD00EFF7F2 /* InitializeThreading.h in Headers */,
-                               554076F818DA58AD00EFF7F2 /* Int16Array.h in Headers */,
-                               554076F918DA58AD00EFF7F2 /* Int32Array.h in Headers */,
-                               554076FA18DA58AD00EFF7F2 /* Int8Array.h in Headers */,
-                               554076FB18DA58AD00EFF7F2 /* IntendedStructureChain.h in Headers */,
-                               554076FC18DA58AD00EFF7F2 /* InternalFunction.h in Headers */,
-                               554076FE18DA58AD00EFF7F2 /* Intrinsic.h in Headers */,
-                               5540771918DA58AD00EFF7F2 /* JSAPIValueWrapper.h in Headers */,
-                               5540771C18DA58AD00EFF7F2 /* JSArray.h in Headers */,
-                               5540771D18DA58AD00EFF7F2 /* JSArrayBuffer.h in Headers */,
-                               5540771E18DA58AD00EFF7F2 /* JSArrayBufferConstructor.h in Headers */,
-                               5540771F18DA58AD00EFF7F2 /* JSArrayBufferPrototype.h in Headers */,
-                               5540772018DA58AD00EFF7F2 /* JSArrayBufferView.h in Headers */,
-                               5540772118DA58AD00EFF7F2 /* JSArrayBufferViewInlines.h in Headers */,
-                               5540772B18DA58AD00EFF7F2 /* JSCell.h in Headers */,
-                               5540772C18DA58AD00EFF7F2 /* JSCellInlines.h in Headers */,
-                               5540772D18DA58AD00EFF7F2 /* JSCInlines.h in Headers */,
-                               5540772E18DA58AD00EFF7F2 /* JSCJSValue.h in Headers */,
-                               5540772F18DA58AD00EFF7F2 /* JSCJSValueInlines.h in Headers */,
-                               5540773618DA58AD00EFF7F2 /* JSDataView.h in Headers */,
-                               5540773718DA58AD00EFF7F2 /* JSDataViewPrototype.h in Headers */,
-                               5540773818DA58AD00EFF7F2 /* JSDateMath.h in Headers */,
-                               5540773918DA58AD00EFF7F2 /* JSDestructibleObject.h in Headers */,
-                               5540773B18DA58AD00EFF7F2 /* JSExportMacros.h in Headers */,
-                               5540773C18DA58AD00EFF7F2 /* JSFloat32Array.h in Headers */,
-                               5540773D18DA58AD00EFF7F2 /* JSFloat64Array.h in Headers */,
-                               5540773E18DA58AD00EFF7F2 /* JSFunction.h in Headers */,
-                               5540773F18DA58AD00EFF7F2 /* JSFunctionInlines.h in Headers */,
-                               5540774018DA58AD00EFF7F2 /* JSGenericTypedArrayView.h in Headers */,
-                               5540774118DA58AD00EFF7F2 /* JSGenericTypedArrayViewConstructor.h in Headers */,
-                               5540774218DA58AD00EFF7F2 /* JSGenericTypedArrayViewConstructorInlines.h in Headers */,
-                               5540774318DA58AD00EFF7F2 /* JSGenericTypedArrayViewInlines.h in Headers */,
-                               5540774418DA58AD00EFF7F2 /* JSGenericTypedArrayViewPrototype.h in Headers */,
-                               5540774518DA58AD00EFF7F2 /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */,
-                               5540774618DA58AD00EFF7F2 /* JSGlobalObject.h in Headers */,
-                               5540775018DA58AD00EFF7F2 /* JSInt16Array.h in Headers */,
-                               5540775118DA58AD00EFF7F2 /* JSInt32Array.h in Headers */,
-                               5540775218DA58AD00EFF7F2 /* JSInt8Array.h in Headers */,
-                               5540775518DA58AD00EFF7F2 /* JSLock.h in Headers */,
-                               5540775818DA58AD00EFF7F2 /* JSMap.h in Headers */,
-                               5540775B18DA58AD00EFF7F2 /* JSNameScope.h in Headers */,
-                               5540775C18DA58AD00EFF7F2 /* JSObject.h in Headers */,
-                               5540775F18DA58AD00EFF7F2 /* JSONObject.h in Headers */,
-                               5540776218DA58AD00EFF7F2 /* JSPromise.h in Headers */,
-                               5540776418DA58AD00EFF7F2 /* JSPromiseDeferred.h in Headers */,
-                               5540776518DA58AD00EFF7F2 /* JSPromiseFunctions.h in Headers */,
-                               5540776818DA58AD00EFF7F2 /* JSProxy.h in Headers */,
-                               5540776B18DA58AD00EFF7F2 /* JSScope.h in Headers */,
-                               5540776D18DA58AD00EFF7F2 /* JSSegmentedVariableObject.h in Headers */,
-                               5540776E18DA58AD00EFF7F2 /* JSSet.h in Headers */,
-                               5540777218DA58AD00EFF7F2 /* JSString.h in Headers */,
-                               5540777818DA58AD00EFF7F2 /* JSSymbolTableObject.h in Headers */,
-                               5540777918DA58AD00EFF7F2 /* JSType.h in Headers */,
-                               5540777A18DA58AD00EFF7F2 /* JSTypedArrayConstructors.h in Headers */,
-                               5540777B18DA58AD00EFF7F2 /* JSTypedArrayPrototypes.h in Headers */,
-                               5540777C18DA58AD00EFF7F2 /* JSTypedArrays.h in Headers */,
-                               5540777D18DA58AD00EFF7F2 /* JSTypeInfo.h in Headers */,
-                               5540777E18DA58AD00EFF7F2 /* JSUint16Array.h in Headers */,
-                               5540777F18DA58AD00EFF7F2 /* JSUint32Array.h in Headers */,
-                               5540778018DA58AD00EFF7F2 /* JSUint8Array.h in Headers */,
-                               5540778118DA58AD00EFF7F2 /* JSUint8ClampedArray.h in Headers */,
-                               5540778518DA58AD00EFF7F2 /* JSVariableObject.h in Headers */,
-                               5540778B18DA58AD00EFF7F2 /* JSWithScope.h in Headers */,
-                               5540778D18DA58AD00EFF7F2 /* JSWrapperObject.h in Headers */,
-                               554077A918DA58AD00EFF7F2 /* Lookup.h in Headers */,
-                               554077B818DA58AD00EFF7F2 /* MapData.h in Headers */,
-                               554077C118DA58AD00EFF7F2 /* MatchResult.h in Headers */,
-                               554077C218DA58AD00EFF7F2 /* MathObject.h in Headers */,
-                               554077C318DA58AD00EFF7F2 /* MemoryStatistics.h in Headers */,
-                               554077C518DA58AD00EFF7F2 /* Microtask.h in Headers */,
-                               554077D318DA58AD00EFF7F2 /* NumberObject.h in Headers */,
-                               554077D418DA58AD00EFF7F2 /* NumberPrototype.h in Headers */,
-                               554077D618DA58AD00EFF7F2 /* NumericStrings.h in Headers */,
-                               554077DA18DA58AD00EFF7F2 /* ObjectConstructor.h in Headers */,
-                               554077DB18DA58AD00EFF7F2 /* ObjectPrototype.h in Headers */,
-                               554077E018DA58AD00EFF7F2 /* Operations.h in Headers */,
-                               554077E118DA58AD00EFF7F2 /* Options.h in Headers */,
-                               554077EA18DA58AD00EFF7F2 /* PrivateName.h in Headers */,
-                               554077FD18DA58AD00EFF7F2 /* PropertyDescriptor.h in Headers */,
-                               554077FE18DA58AD00EFF7F2 /* PropertyMapHashTable.h in Headers */,
-                               554077FF18DA58AD00EFF7F2 /* PropertyName.h in Headers */,
-                               5540780018DA58AD00EFF7F2 /* PropertyNameArray.h in Headers */,
-                               5540780118DA58AD00EFF7F2 /* PropertyOffset.h in Headers */,
-                               5540780318DA58AD00EFF7F2 /* PropertySlot.h in Headers */,
-                               5540780418DA58AD00EFF7F2 /* PropertyStorage.h in Headers */,
-                               5540780518DA58AD00EFF7F2 /* Protect.h in Headers */,
-                               5540780618DA58AD00EFF7F2 /* PrototypeMap.h in Headers */,
-                               5540780818DA58AD00EFF7F2 /* PutDirectIndexMode.h in Headers */,
-                               5540780A18DA58AD00EFF7F2 /* PutPropertySlot.h in Headers */,
-                               5540780E18DA58AD00EFF7F2 /* RegExp.h in Headers */,
-                               5540780F18DA58AD00EFF7F2 /* RegExpCache.h in Headers */,
-                               5540781218DA58AD00EFF7F2 /* RegExpKey.h in Headers */,
-                               5540781318DA58AD00EFF7F2 /* RegExpObject.h in Headers */,
-                               5540781918DA58AD00EFF7F2 /* RegisterPreservationMode.h in Headers */,
-                               5540781D18DA58AD00EFF7F2 /* Reject.h in Headers */,
-                               5540782618DA58AD00EFF7F2 /* SamplingCounter.h in Headers */,
-                               5540783818DA58AD00EFF7F2 /* SimpleTypedArrayController.h in Headers */,
-                               5540783C18DA58AD00EFF7F2 /* SmallStrings.h in Headers */,
-                               5540784118DA58AD00EFF7F2 /* SparseArrayValueMap.h in Headers */,
-                               5540784518DA58AD00EFF7F2 /* StackAlignment.h in Headers */,
-                               5540784B18DA58AD00EFF7F2 /* StringObject.h in Headers */,
-                               5540784C18DA58AD00EFF7F2 /* StringPrototype.h in Headers */,
-                               5540784F18DA58AD00EFF7F2 /* Structure.h in Headers */,
-                               5540785018DA58AD00EFF7F2 /* StructureChain.h in Headers */,
-                               5540785118DA58AD00EFF7F2 /* StructureInlines.h in Headers */,
-                               5540785218DA58AD00EFF7F2 /* StructureRareData.h in Headers */,
-                               5540785318DA58AD00EFF7F2 /* StructureRareDataInlines.h in Headers */,
-                               5540785718DA58AD00EFF7F2 /* StructureTransitionTable.h in Headers */,
-                               5540785918DA58AD00EFF7F2 /* SymbolTable.h in Headers */,
-                               5540785C18DA58AD00EFF7F2 /* TestRunnerUtils.h in Headers */,
-                               5540786018DA58AD00EFF7F2 /* ToNativeFromValue.h in Headers */,
-                               5540786218DA58AD00EFF7F2 /* TypedArrayAdaptors.h in Headers */,
-                               5540786318DA58AD00EFF7F2 /* TypedArrayController.h in Headers */,
-                               5540786418DA58AD00EFF7F2 /* TypedArrayInlines.h in Headers */,
-                               5540786518DA58AD00EFF7F2 /* TypedArrays.h in Headers */,
-                               5540786618DA58AD00EFF7F2 /* TypedArrayType.h in Headers */,
-                               5540786E18DA58AD00EFF7F2 /* Uint16Array.h in Headers */,
-                               5540787018DA58AD00EFF7F2 /* Uint32Array.h in Headers */,
-                               5540787118DA58AD00EFF7F2 /* Uint8Array.h in Headers */,
-                               5540787218DA58AD00EFF7F2 /* Uint8ClampedArray.h in Headers */,
-                               5540787A18DA58AD00EFF7F2 /* VM.h in Headers */,
-                               5540787B18DA58AD00EFF7F2 /* VMEntryScope.h in Headers */,
-                               5540787D18DA58AD00EFF7F2 /* Watchdog.h in Headers */,
-                               5540788118DA58AD00EFF7F2 /* WeakGCMap.h in Headers */,
-                               5540788818DA58AD00EFF7F2 /* WeakRandom.h in Headers */,
-                               5540788D18DA58AD00EFF7F2 /* WriteBarrier.h in Headers */,
-                               5540788F18DA58AD00EFF7F2 /* WriteBarrierInlines.h in Headers */,
-                               5540757718DA58AD00EFF7F2 /* ArityCheckMode.h in Headers */,
-                               5540757218DA58AD00EFF7F2 /* ArgList.h in Headers */,
-                               5510502618EB827500001F3E /* JSCallbackFunction.h in Headers */,
-                               5540781018DA58AD00EFF7F2 /* RegExpConstructor.h in Headers */,
-                               5540781518DA58AD00EFF7F2 /* RegExpPrototype.h in Headers */,
-                               5540783318DA58AD00EFF7F2 /* SetConstructor.h in Headers */,
-                               5540783418DA58AD00EFF7F2 /* SetIteratorConstructor.h in Headers */,
-                               5540783518DA58AD00EFF7F2 /* SetIteratorPrototype.h in Headers */,
-                               5540783618DA58AD00EFF7F2 /* SetPrototype.h in Headers */,
-                               5540784918DA58AD00EFF7F2 /* StrictEvalActivation.h in Headers */,
-                               5540784A18DA58AD00EFF7F2 /* StringConstructor.h in Headers */,
-                               5540786118DA58AD00EFF7F2 /* Tracing.h in Headers */,
-                               5540786F18DA58AD00EFF7F2 /* Uint16WithFraction.h in Headers */,
-                               5540788518DA58AD00EFF7F2 /* WeakMapConstructor.h in Headers */,
-                               5540788618DA58AD00EFF7F2 /* WeakMapData.h in Headers */,
-                               5540788718DA58AD00EFF7F2 /* WeakMapPrototype.h in Headers */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
                932F5B3F0822A1C700736975 /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                                0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */,
                                860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
+                               0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
                                0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
                                2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
                                BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
                                BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
                                2A88067919107D5500CB0BBB /* DFGFunctionWhitelist.h in Headers */,
-                               BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
-                               A76140CE182982CB00750624 /* ArgumentsIteratorConstructor.h in Headers */,
-                               A76140D0182982CB00750624 /* ArgumentsIteratorPrototype.h in Headers */,
                                0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */,
                                0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
                                A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
+                               0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
                                86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
+                               0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
+                               52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
+                               FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */,
+                               FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */,
+                               C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
+                               FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */,
+                               52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
+                               52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */,
+                               A5EA710E19F6DF810098F5EC /* InspectorAlternateBackendDispatchers.h in Headers */,
+                               A5EA70EC19F5B3EA0098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py in Headers */,
+                               C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
+                               A5EF9B151A1D43FA00702E90 /* generate_cpp_backend_dispatcher_implementation.py in Headers */,
+                               FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */,
+                               FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */,
+                               6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */,
+                               658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */,
+                               A5EF9B161A1D440000702E90 /* generate_cpp_frontend_dispatcher_header.py in Headers */,
+                               2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
+                               A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */,
+                               A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */,
+                               C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */,
+                               70DC3E0A1B2DF2C700054299 /* IteratorPrototype.h in Headers */,
+                               A5EF9B171A1D440300702E90 /* generate_cpp_frontend_dispatcher_implementation.py in Headers */,
                                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
                                2A111246192FCE79005EE18D /* CustomGetterSetter.h in Headers */,
+                               C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */,
                                A584032018BFFBE1005A0811 /* InspectorAgent.h in Headers */,
                                2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
-                               FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */,
+                               FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */,
+                               A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */,
                                C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */,
+                               C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
+                               A532439418569709002ED692 /* generate-combined-inspector-json.py in Headers */,
+                               A5840E27187C981E00843B10 /* cssmin.py in Headers */,
+                               A5EA710419F6DE720098F5EC /* generate_objc_backend_dispatcher_implementation.py in Headers */,
+                               C4703CD5192844CC0013FBEA /* generator_templates.py in Headers */,
+                               A5EA710519F6DE740098F5EC /* generate_objc_configuration_header.py in Headers */,
+                               A5EA710619F6DE760098F5EC /* generate_objc_configuration_implementation.py in Headers */,
+                               A5EA710719F6DE780098F5EC /* generate_objc_conversion_helpers.py in Headers */,
+                               A5EA710819F6DE7A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py in Headers */,
+                               A5EA710A19F6DE7E0098F5EC /* generate_objc_internal_header.py in Headers */,
+                               A5EA710C19F6DE820098F5EC /* objc_generator.py in Headers */,
+                               A5EA710919F6DE7C0098F5EC /* generate_objc_header.py in Headers */,
+                               C4703CD6192844CC0013FBEA /* generator.py in Headers */,
+                               C4703CC0192844960013FBEA /* generate-inspector-protocol-bindings.py in Headers */,
+                               C4703CCE192844CC0013FBEA /* generate_js_backend_commands.py in Headers */,
+                               C4703CD7192844CC0013FBEA /* models.py in Headers */,
+                               A5EA710319F6DE6F0098F5EC /* generate_objc_backend_dispatcher_header.py in Headers */,
                                2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */,
                                2A83638618D7D0EE0000EBCC /* EdenGCActivityCallback.h in Headers */,
                                2A83638A18D7D0FE0000EBCC /* FullGCActivityCallback.h in Headers */,
                                6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */,
                                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
                                0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
+                               0FD120341A8C85BD000F5280 /* FTLJSCallVarargs.h in Headers */,
                                A7A8AF3517ADB5F3005AB174 /* ArrayBuffer.h in Headers */,
                                0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h in Headers */,
                                A7A8AF3717ADB5F3005AB174 /* ArrayBufferView.h in Headers */,
                                BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
                                0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
-                               A7BDAEC717F4EA1400F6140C /* ArrayIteratorConstructor.h in Headers */,
                                A7BDAEC917F4EA1400F6140C /* ArrayIteratorPrototype.h in Headers */,
                                0F63945515D07057006A597C /* ArrayProfile.h in Headers */,
                                BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
                                0F24E54117EA9F5900ABB217 /* AssemblyHelpers.h in Headers */,
                                A784A26111D16622005776AC /* ASTBuilder.h in Headers */,
                                866739D213BFDE710023D87C /* BigInteger.h in Headers */,
-                               14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
                                BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
                                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */,
                                A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
                                A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
                                A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */,
+                               0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */,
                                0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
                                0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
+                               62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */,
                                C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
                                0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
                                969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
                                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
                                0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */,
+                               0F8F14361ADF090100ED792C /* DFGMovHintRemovalPhase.h in Headers */,
                                0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
                                0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
                                BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
+                               AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
                                1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
                                A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */,
                                95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
                                0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
                                0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
                                0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
+                               0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
                                0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
                                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
-                               0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
                                969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
                                0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
                                0FC97F34182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.h in Headers */,
+                               70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */,
                                0FD8A31417D4326C00CA2C40 /* CodeBlockSet.h in Headers */,
                                0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */,
                                A77F1822164088B200640A47 /* CodeCache.h in Headers */,
-                               A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */,
-                               A532439318569709002ED692 /* CodeGeneratorInspectorStrings.py in Headers */,
                                86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */,
                                0FBD7E691447999600481315 /* CodeOrigin.h in Headers */,
                                0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
                                0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
                                BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
+                               709FB86C1AE335C60039D069 /* WeakSetPrototype.h in Headers */,
                                0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
                                6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */,
                                0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */,
                                BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
                                0FDB2CEA174896C7007B3C1B /* ConcurrentJITLock.h in Headers */,
                                BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
+                               0FFB6C391AF48DDC00DB1BF7 /* TypeofType.h in Headers */,
                                144836E7132DA7BE005BE785 /* ConservativeRoots.h in Headers */,
                                A5FD007A189B051000633231 /* ConsoleMessage.h in Headers */,
                                A5FD0074189B038C00633231 /* ConsoleTypes.h in Headers */,
                                C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
                                C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */,
                                C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
+                               A12BBFF21B044A8B00664B69 /* IntlObject.h in Headers */,
                                C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
                                C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
+                               0FEE98411A8865B700754E93 /* SetupVarargsFrame.h in Headers */,
+                               0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
                                0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */,
                                C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
                                C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,
                                C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
                                2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
                                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
-                               A5840E27187C981E00843B10 /* cssmin.py in Headers */,
                                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
+                               0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */,
                                0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
                                BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
+                               0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
                                14A1563210966365006FA260 /* DateInstanceCache.h in Headers */,
                                BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */,
                                BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
                                BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */,
-                               BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */,
                                BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
                                FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */,
                                0F136D4D174AD69E0075B354 /* DeferGC.h in Headers */,
                                0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */,
-                               2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */,
                                A77A423E17A0BBFD00A8DB81 /* DFGAbstractHeap.h in Headers */,
+                               A5EA70E819F5B1010098F5EC /* AugmentableInspectorControllerClient.h in Headers */,
                                A704D90317A0BAA8006BA554 /* DFGAbstractInterpreter.h in Headers */,
                                A704D90417A0BAA8006BA554 /* DFGAbstractInterpreterInlines.h in Headers */,
                                0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */,
+                               0FF054FA1AC35B4400E5BE57 /* ExecutableAllocationFuzz.h in Headers */,
                                0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
                                0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
                                A737810C1799EA2E00817533 /* DFGAnalysis.h in Headers */,
                                0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
-                               A5C3A1A618C0490200C9593A /* JSConsoleClient.h in Headers */,
-                               0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */,
+                               A5C3A1A618C0490200C9593A /* JSGlobalObjectConsoleClient.h in Headers */,
                                0F485322187750560083B687 /* DFGArithMode.h in Headers */,
                                0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
                                0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
                                0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */,
                                0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */,
                                0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */,
-                               A70B083317A0B79B00DAF14B /* DFGBinarySwitch.h in Headers */,
                                A7D89CF417A0B8CC00773AD8 /* DFGBlockInsertionSet.h in Headers */,
                                0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */,
                                86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */,
                                0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
                                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
                                0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
+                               0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */,
                                0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
                                A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
                                A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
                                0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
                                0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
                                0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */,
-                               A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */,
                                C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
                                0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
                                C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */,
                                0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */,
                                0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */,
                                A7D9A29617A0BC7400EE2618 /* DFGEdgeDominates.h in Headers */,
+                               0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */,
                                A7986D5717A0BB1E00A95DD0 /* DFGEdgeUsesStructure.h in Headers */,
                                0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */,
                                A78A9775179738B8009DF744 /* DFGFailedFinalizer.h in Headers */,
                                A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
                                A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */,
                                0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
+                               0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */,
                                0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
                                A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
                                86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
                                0F2FCCFA18A60070001A27F8 /* DFGGraphSafepoint.h in Headers */,
                                0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */,
                                0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */,
+                               0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */,
                                A704D90617A0BAA8006BA554 /* DFGInPlaceAbstractState.h in Headers */,
                                0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
                                0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */,
                                A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */,
                                0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */,
                                A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */,
+                               0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */,
                                A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */,
                                A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
                                0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
+                               709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */,
                                A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
+                               0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */,
                                A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */,
+                               0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
                                0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
                                0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
                                0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
                                A7D89CFE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.h in Headers */,
                                0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
                                0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
+                               62F2AA381B0BEDE300610C7A /* DFGLazyNode.h in Headers */,
                                0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
                                0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
                                0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
                                0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
                                0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
+                               0FD949851A97DB9600E28966 /* JSFunctionNameScope.h in Headers */,
                                0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
                                0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */,
                                0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
                                0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
+                               A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
                                A78A977B179738B8009DF744 /* DFGPlan.h in Headers */,
                                0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */,
                                0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
                                86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
-                               0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */,
                                0F2FCCFC18A60070001A27F8 /* DFGSafepoint.h in Headers */,
                                A77A424317A0BBFD00A8DB81 /* DFGSafeToExecute.h in Headers */,
                                A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
                                0F2FCCFD18A60070001A27F8 /* DFGScannable.h in Headers */,
+                               0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
                                86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
                                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
                                0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */,
                                A7D89D0017A0B8CC00773AD8 /* DFGSSAConversionPhase.h in Headers */,
                                0FC20CBA18556A3500C9E954 /* DFGSSALoweringPhase.h in Headers */,
                                0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */,
+                               0F9E32641B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h in Headers */,
                                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */,
-                               2ACCF3DF185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h in Headers */,
                                0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */,
                                0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
                                0F2FCCFF18A60070001A27F8 /* DFGThreadData.h in Headers */,
                                0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */,
                                0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */,
                                0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
-                               0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
                                0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
                                0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
+                               0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */,
                                0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
                                0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
                                0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
                                A70447EE17A0BD7000F5898E /* DumpContext.h in Headers */,
                                99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */,
                                99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */,
+                               0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
                                BC3046070E1F497F003232CF /* Error.h in Headers */,
                                BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
                                FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */,
                                A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
                                A7A8AF3917ADB5F3005AB174 /* Float64Array.h in Headers */,
                                0F24E54317EA9F5900ABB217 /* FPRInfo.h in Headers */,
+                               7094C4DF1AE439530041A2EE /* BytecodeIntrinsicRegistry.h in Headers */,
                                0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */,
                                0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */,
                                A53CE08A18BC21C300BEDF76 /* ConsoleClient.h in Headers */,
+                               0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
                                0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
+                               DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */,
                                0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
                                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
                                0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
                                0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */,
                                0F235BD717178E1C00690C7F /* FTLExitArgumentList.h in Headers */,
                                0F235BD917178E1C00690C7F /* FTLExitThunkGenerator.h in Headers */,
+                               0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
                                0F235BDB17178E1C00690C7F /* FTLExitValue.h in Headers */,
                                A53CE08618BC1A5600BEDF76 /* ConsolePrototype.h in Headers */,
                                A7F2996C17A0BB670010417A /* FTLFail.h in Headers */,
                                0FEA0A241709606900BB722C /* FTLIntrinsicRepository.h in Headers */,
                                0FEA0A0E170513DB00BB722C /* FTLJITCode.h in Headers */,
                                A78A9781179738D5009DF744 /* FTLJITFinalizer.h in Headers */,
+                               0FED67BA1B26256D0066CE15 /* DFGConstantHoistingPhase.h in Headers */,
                                0F6B1CB6185FC9E900845D97 /* FTLJSCall.h in Headers */,
                                0F8F2B96172E04A3007DBDA5 /* FTLLink.h in Headers */,
                                0FCEFAE0180738C000472CE4 /* FTLLocation.h in Headers */,
                                0F235BDD17178E1C00690C7F /* FTLOSRExit.h in Headers */,
                                0F235BDE17178E1C00690C7F /* FTLOSRExitCompilationInfo.h in Headers */,
                                0F235BE017178E1C00690C7F /* FTLOSRExitCompiler.h in Headers */,
+                               52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */,
                                0FEA0A11170513DB00BB722C /* FTLOutput.h in Headers */,
+                               9E72940B190F0514001A91B5 /* BundlePath.h in Headers */,
                                0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
                                0F6B1CC41862C47800845D97 /* FTLRegisterAtOffset.h in Headers */,
                                0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */,
                                0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */,
                                0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */,
                                0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
+                               0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */,
                                0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */,
                                0F0332C618B53FA9005F979A /* FTLWeight.h in Headers */,
                                0F0332C818B546EC005F979A /* FTLWeightedTarget.h in Headers */,
                                BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
                                BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
                                0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
+                               70EC0EC71AA0D7DA00B6AAFA /* StringIteratorPrototype.h in Headers */,
                                0F2B66AC17B6B53F00A7AE3F /* GCIncomingRefCounted.h in Headers */,
                                0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */,
                                0F2B66AE17B6B54500A7AE3F /* GCIncomingRefCountedSet.h in Headers */,
                                0F2B66AF17B6B54500A7AE3F /* GCIncomingRefCountedSetInlines.h in Headers */,
                                C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */,
                                C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
-                               A532439418569709002ED692 /* generate-combined-inspector-json.py in Headers */,
                                0F2B66E017B6B5AB00A7AE3F /* GenericTypedArrayView.h in Headers */,
                                0F1FE51C1922A3BC006987C5 /* AbortReason.h in Headers */,
                                0F2B66E117B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h in Headers */,
                                C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
                                C283190216FE533E00157BFD /* HandleBlockInlines.h in Headers */,
                                0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
+                               0F2D4DEC19832DC4007D4B19 /* TypeProfilerLog.h in Headers */,
                                142E3136134FF0A600AFADB5 /* HandleSet.h in Headers */,
                                142E3138134FF0A600AFADB5 /* HandleStack.h in Headers */,
                                1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
                                14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
-                               C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */,
                                2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
                                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
+                               0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
                                14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
                                C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
                                C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
                                0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
                                BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
                                A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
-                               996231E918D1804200C03FDA /* InspectorJSBackendCommands.js in Headers */,
+                               996231E918D1804200C03FDA /* InspectorBackendCommands.js in Headers */,
                                C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
                                0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
                                0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
                                A513E5CB185F9624007E95AD /* InjectedScriptManager.h in Headers */,
                                A5840E21187B7B8600843B10 /* InjectedScriptModule.h in Headers */,
                                A513E5C7185F9446007E95AD /* InjectedScriptSource.h in Headers */,
+                               0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
                                A5840E29187CA5E600843B10 /* inline-and-minify-stylesheets-and-scripts.py in Headers */,
                                0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */,
                                99E45A2718A1B2590026D88F /* InputCursor.h in Headers */,
+                               0F952ABD1B487A7700C367C5 /* TrackedReferences.h in Headers */,
                                A593CF7F1840362C00BFCE27 /* InspectorAgentBase.h in Headers */,
+                               0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */,
                                A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
+                               0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
                                A593CF7D1840360300BFCE27 /* InspectorBackendDispatcher.h in Headers */,
                                A5FD0082189B191A00633231 /* InspectorConsoleAgent.h in Headers */,
                                A57D23E61890CEBF0031C7FA /* InspectorDebuggerAgent.h in Headers */,
                                A5D0A1BB1862301B00C7B496 /* InspectorEnvironment.h in Headers */,
                                A5945595182479EB00CC3843 /* InspectorFrontendChannel.h in Headers */,
-                               A53243981856A489002ED692 /* InspectorJS.json in Headers */,
-                               A532438818568335002ED692 /* InspectorJSBackendDispatchers.h in Headers */,
-                               A532438A18568335002ED692 /* InspectorJSFrontendDispatchers.h in Headers */,
+                               A53243981856A489002ED692 /* CombinedDomains.json in Headers */,
+                               A532438818568335002ED692 /* InspectorBackendDispatchers.h in Headers */,
+                               A532438A18568335002ED692 /* InspectorFrontendDispatchers.h in Headers */,
                                8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
-                               A532438C18568335002ED692 /* InspectorJSTypeBuilders.h in Headers */,
+                               A532438C18568335002ED692 /* InspectorProtocolObjects.h in Headers */,
                                A50E4B6218809DD50068A46D /* InspectorRuntimeAgent.h in Headers */,
-                               A55D93AC18514F7900400DED /* InspectorTypeBuilder.h in Headers */,
+                               A55D93AC18514F7900400DED /* InspectorProtocolTypes.h in Headers */,
                                A593CF831840377100BFCE27 /* InspectorValues.h in Headers */,
                                969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
                                A7A8AF3B17ADB5F3005AB174 /* Int16Array.h in Headers */,
                                BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
                                1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
                                860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
+                               70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */,
                                BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
+                               0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */,
+                               A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */,
                                A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */,
                                BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
                                BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
                                1429D9300ED22D7000B89619 /* JIT.h in Headers */,
+                               A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */,
                                86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
                                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
                                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
                                0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
                                0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
                                14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */,
+                               0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */,
                                FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */,
                                FEF6835F174343CC00A32E25 /* JITStubsARMv7.h in Headers */,
                                FEF68361174343CC00A32E25 /* JITStubsX86.h in Headers */,
                                0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */,
                                0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */,
                                A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */,
-                               BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */,
+                               BC18C4160E16F5CD00B34460 /* JSLexicalEnvironment.h in Headers */,
                                840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */,
                                C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */,
-                               A76140D2182982CB00750624 /* JSArgumentsIterator.h in Headers */,
                                BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
                                0F2B66E317B6B5AB00A7AE3F /* JSArrayBuffer.h in Headers */,
-                               1CAA9A2318F4A220000A369D /* JSGlobalObjectProfilerAgent.h in Headers */,
                                0F2B66E517B6B5AB00A7AE3F /* JSArrayBufferConstructor.h in Headers */,
                                0F2B66E717B6B5AB00A7AE3F /* JSArrayBufferPrototype.h in Headers */,
                                0F2B66E917B6B5AB00A7AE3F /* JSArrayBufferView.h in Headers */,
                                0F2B66EA17B6B5AB00A7AE3F /* JSArrayBufferViewInlines.h in Headers */,
                                A7BDAECB17F4EA1400F6140C /* JSArrayIterator.h in Headers */,
                                BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */,
+                               0F2D4DE919832DAC007D4B19 /* ToThisStatus.h in Headers */,
                                140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
                                86FA9E92142BBB2E001773B7 /* JSBoundFunction.h in Headers */,
+                               657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */,
                                BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
                                BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
+                               0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */,
                                BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
                                BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
                                A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
                                BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
                                0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */,
                                0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */,
+                               0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
                                BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */,
+                               0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */,
                                865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */,
                                BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
                                86E3C613167BABD7006D760A /* JSContext.h in Headers */,
                                A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
                                0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */,
                                0F2B66EC17B6B5AB00A7AE3F /* JSDataView.h in Headers */,
-                               1CAA9A1F18F4997F000A369D /* InspectorProfilerAgent.h in Headers */,
                                0F2B66EE17B6B5AB00A7AE3F /* JSDataViewPrototype.h in Headers */,
                                978801411471AD920041B016 /* JSDateMath.h in Headers */,
                                C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
                                0F2B66F217B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h in Headers */,
                                0F2B66F317B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructorInlines.h in Headers */,
                                0F2B66F417B6B5AB00A7AE3F /* JSGenericTypedArrayViewInlines.h in Headers */,
+                               0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */,
                                0F2B66F517B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototype.h in Headers */,
                                0F2B66F617B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */,
                                BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
                                A5840E2B187CA75B00843B10 /* jsmin.py in Headers */,
                                14874AE415EBDE4A002E3587 /* JSNameScope.h in Headers */,
                                BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
+                               709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */,
                                BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
                                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
                                A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
                                7C184E1B17BEDBD3007CB63A /* JSPromise.h in Headers */,
                                7C184E2317BEE240007CB63A /* JSPromiseConstructor.h in Headers */,
                                7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */,
-                               7C008CD3186F8A9300955C24 /* JSPromiseFunctions.h in Headers */,
                                7C184E1F17BEE22E007CB63A /* JSPromisePrototype.h in Headers */,
-                               7C008CDF1871258D00955C24 /* JSPromiseReaction.h in Headers */,
                                862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
                                9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */,
                                BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
                                1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
                                0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
                                BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
+                               0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */,
                                0F2B66FB17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h in Headers */,
                                0F2B66FD17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.h in Headers */,
                                0F2B66FF17B6B5AB00A7AE3F /* JSTypedArrays.h in Headers */,
                                6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */,
                                0F2B670217B6B5AB00A7AE3F /* JSUint16Array.h in Headers */,
                                0F2B670317B6B5AB00A7AE3F /* JSUint32Array.h in Headers */,
+                               0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */,
                                0F2B670017B6B5AB00A7AE3F /* JSUint8Array.h in Headers */,
+                               0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
                                0F2B670117B6B5AB00A7AE3F /* JSUint8ClampedArray.h in Headers */,
                                86E3C612167BABD7006D760A /* JSValue.h in Headers */,
                                86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
+                               7013CA8C1B491A9400CAE613 /* JSJob.h in Headers */,
                                BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
-                               BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */,
+                               BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
                                86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
                                86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
+                               0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */,
                                A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
                                A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
+                               0FD949831A97DB9600E28966 /* JSCatchScope.h in Headers */,
                                A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
                                1442566215EDE98D0066A49B /* JSWithScope.h in Headers */,
                                86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */,
                                BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */,
                                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */,
                                A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
+                               0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */,
                                969A072A0ED1CE6900F1F681 /* Label.h in Headers */,
                                960097A60EBABB58007A7297 /* LabelScope.h in Headers */,
                                0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
                                0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
                                A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
                                0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
+                               0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */,
+                               0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */,
                                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
+                               0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
                                0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
+                               0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */,
                                0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
                                0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */,
                                0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
                                FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
                                0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
                                0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
+                               0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
                                0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */,
                                0FCEFACF1805E75500472CE4 /* LLVMAPIFunctions.h in Headers */,
+                               0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */,
                                A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */,
                                0FCEFAD31805EDCC00472CE4 /* LLVMHeaders.h in Headers */,
                                142E3139134FF0A600AFADB5 /* Local.h in Headers */,
                                0F93B4AA18B92C4D00178A3F /* PutByIdVariant.h in Headers */,
                                A700873A17CBE85300C3E643 /* MapConstructor.h in Headers */,
                                A78507D717CBC6FD0011F6E7 /* MapData.h in Headers */,
-                               A74DEF92182D991400522C22 /* MapIteratorConstructor.h in Headers */,
+                               0A6441519420A6C61AD1882E /* MapDataInlines.h in Headers */,
+                               FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */,
                                A74DEF94182D991400522C22 /* MapIteratorPrototype.h in Headers */,
                                A700873E17CBE8D300C3E643 /* MapPrototype.h in Headers */,
                                C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
                                BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
                                90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
                                0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
+                               0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */,
                                7C008CE7187631B600955C24 /* Microtask.h in Headers */,
                                86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
-                               86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */,
-                               86EBF3021560F06A008E9222 /* NameInstance.h in Headers */,
-                               86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */,
                                BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
                                BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
                                99CC0B6318BE9950006CEBCC /* CodeGeneratorReplayInputs.py in Headers */,
                                0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */,
-                               7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
+                               70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */,
                                BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
                                99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */,
+                               0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */,
                                BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
                                0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */,
                                BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
                                969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
                                0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
                                A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
+                               0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */,
                                BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
+                               0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
                                0FE228ED1436AB2700196C48 /* Options.h in Headers */,
                                BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
                                93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
                                65303D641447B9E100D3F904 /* ParserTokens.h in Headers */,
                                0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */,
                                0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
+                               0F8F14341ADF090100ED792C /* DFGEpoch.h in Headers */,
                                0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
+                               0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
                                868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
+                               A5EA70E719F5B1010098F5EC /* AugmentableInspectorController.h in Headers */,
                                BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
-                               0FC97F36182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.h in Headers */,
                                95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
                                BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
                                0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */,
                                0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
                                0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,
                                0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
+                               0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */,
                                0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
                                0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
+                               2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
+                               52B311011975B4670080857C /* TypeLocationCache.h in Headers */,
                                0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */,
                                0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */,
+                               52C952B719A289850069B386 /* TypeProfiler.h in Headers */,
                                0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
                                0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */,
                                0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */,
                                A785F6BC18C553FE00F10626 /* SpillRegistersMode.h in Headers */,
                                BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
                                0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
+                               0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */,
+                               0F12DE101979D5FD0006FF4E /* ExceptionFuzz.h in Headers */,
                                BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
                                1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
                                0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */,
                                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
                                2AAD964A18569417001F93BE /* RecursiveAllocationScope.h in Headers */,
                                0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
+                               0FD120301A8AED12000F5280 /* FTLJSCallBase.h in Headers */,
                                0FA7A8EC18B413C80052371D /* Reg.h in Headers */,
                                BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
                                A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */,
+                               4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */,
                                BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
                                BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */,
                                A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */,
                                BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
-                               BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */,
+                               70ECA6061AFDBEA200449739 /* JSTemplateRegistryKey.h in Headers */,
                                BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
-                               C20B25991706536200C21F4E /* Region.h in Headers */,
                                BC18C45D0E16F5CD00B34460 /* Register.h in Headers */,
                                969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
                                0F6B1CBA1861244C00845D97 /* RegisterPreservationMode.h in Headers */,
                                0F6B1CBE1861246A00845D97 /* RegisterPreservationWrapperGenerator.h in Headers */,
                                0FC314121814559100033232 /* RegisterSet.h in Headers */,
+                               0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */,
                                A57D23EE1891B5540031C7FA /* RegularExpression.h in Headers */,
+                               0F682FB319BCB36400FA3BAD /* DFGSSACalculator.h in Headers */,
                                0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
+                               0F2D4DEA19832DAC007D4B19 /* TypeLocation.h in Headers */,
                                A5BA15E8182340B300A82E69 /* RemoteInspector.h in Headers */,
                                A5BA15EA182340B400A82E69 /* RemoteInspectorConstants.h in Headers */,
                                A5BA15F0182345AF00A82E69 /* RemoteInspectorDebuggable.h in Headers */,
                                869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
                                C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
                                1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
+                               0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */,
                                0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
                                A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */,
                                A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */,
                                A54CF2FA184EAEDA00237F19 /* ScriptObject.h in Headers */,
                                A54CF2F6184EAB2400237F19 /* ScriptValue.h in Headers */,
                                A7299DA617D12858005F5FF9 /* SetConstructor.h in Headers */,
-                               A790DD6C182F499700588807 /* SetIteratorConstructor.h in Headers */,
                                A790DD6E182F499700588807 /* SetIteratorPrototype.h in Headers */,
                                A7299DA217D12848005F5FF9 /* SetPrototype.h in Headers */,
                                86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
+                               0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
                                0F2B670517B6B5AB00A7AE3F /* SimpleTypedArrayController.h in Headers */,
                                14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
+                               0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */,
                                C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
                                A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
                                933040040E6A749400786E6A /* SmallStrings.h in Headers */,
                                BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */,
+                               0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
                                BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
+                               70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */,
                                E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
                                E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
                                0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
                                0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
                                C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
                                C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
+                               0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */,
                                0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
                                0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
                                BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
                                BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
-                               C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */,
+                               705B41AC1A6E501E00716757 /* Symbol.h in Headers */,
+                               705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */,
+                               705B41B01A6E501E00716757 /* SymbolObject.h in Headers */,
+                               705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
                                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
                                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
                                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
                                0FF42744158EBE91004CB9FF /* udis86_input.h in Headers */,
                                0FF42748158EBE91004CB9FF /* udis86_syn.h in Headers */,
                                0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
+                               70B0A9D11A9B66460001306A /* RuntimeFlags.h in Headers */,
                                A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */,
+                               0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
                                A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */,
+                               0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */,
                                866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
                                A7A8AF4217ADB5F3005AB174 /* Uint32Array.h in Headers */,
                                A7A8AF3F17ADB5F3005AB174 /* Uint8Array.h in Headers */,
                                0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
                                0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
                                0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
-                               0F9181C718415CA50057B669 /* VariableWatchpointSet.h in Headers */,
                                0F9C5E5F18E35F5E00D431C3 /* FTLDWARFRegister.h in Headers */,
                                0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
                                BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
                                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
-                               FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */,
                                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
                                0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
                                142E313C134FF0A600AFADB5 /* Weak.h in Headers */,
                                14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
                                14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
                                14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
+                               0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */,
                                14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
                                A7CA3AE417DA41AE006538AF /* WeakMapConstructor.h in Headers */,
                                A7CA3AEC17DA5168006538AF /* WeakMapData.h in Headers */,
                                0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
                                9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
                                A5840E2A187CA75900843B10 /* xxd.pl in Headers */,
+                               0F3A1BFA1A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h in Headers */,
                                451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
                                86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
                                86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
                        productReference = 14BD59BF0A3E8F9000BAF59C /* testapi */;
                        productType = "com.apple.product-type.tool";
                };
-               5540756218DA58AD00EFF7F2 /* Compile Runtime to LLVM IR */ = {
-                       isa = PBXNativeTarget;
-                       buildConfigurationList = 55407AC318DA58AD00EFF7F2 /* Build configuration list for PBXNativeTarget "Compile Runtime to LLVM IR" */;
-                       buildPhases = (
-                               5540756C18DA58AD00EFF7F2 /* Headers */,
-                               5540789A18DA58AD00EFF7F2 /* Sources */,
-                               559CD06A18F487A800F9ADC0 /* Copy LLVM IR */,
-                       );
-                       buildRules = (
-                       );
-                       dependencies = (
-                               5540756318DA58AD00EFF7F2 /* PBXTargetDependency */,
-                               5540756518DA58AD00EFF7F2 /* PBXTargetDependency */,
-                               5540756718DA58AD00EFF7F2 /* PBXTargetDependency */,
-                       );
-                       name = "Compile Runtime to LLVM IR";
-                       productName = JavaScriptCore;
-                       productReference = 55407AC818DA58AD00EFF7F2 /* libCompileRuntimeToLLVMIR.a */;
-                       productType = "com.apple.product-type.library.static";
-               };
                651122F714046A4C002B101D /* testRegExp */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 6511230014046A4C002B101D /* Build configuration list for PBXNativeTarget "testRegExp" */;
                                5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables and Externals */,
                                3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */,
                                A55DEAA416703DF7003DB841 /* Check For Inappropriate Macros in External Headers */,
-                               55850CA118F4842000F81829 /* Build Symbol Index Table */,
+                               1A02D9A81B34A882000D1522 /* Add Symlink in /System/Library/PrivateFrameworks */,
                        );
                        buildRules = (
                        );
                        dependencies = (
-                               55F8FC2C18EB937B00783E6E /* PBXTargetDependency */,
                                0FCEFABD1805D66300472CE4 /* PBXTargetDependency */,
                                65788AAD18B40A7B00C189FF /* PBXTargetDependency */,
                                65FB3F7E09D11EF300F49DEB /* PBXTargetDependency */,
                        isa = PBXProject;
                        attributes = {
                                BuildIndependentTargetsInParallel = YES;
-                               LastUpgradeCheck = 0500;
+                               LastSwiftUpdateCheck = 0700;
+                               LastUpgradeCheck = 0700;
                        };
                        buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
                        compatibilityVersion = "Xcode 3.2";
                        projectRoot = "";
                        targets = (
                                932F5BE30822A1C700736975 /* All */,
-                               5540756218DA58AD00EFF7F2 /* Compile Runtime to LLVM IR */,
                                932F5B3E0822A1C700736975 /* JavaScriptCore */,
                                0FCEFAB51805D61600472CE4 /* llvmForJSC */,
                                0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
                        files = (
                        );
                        inputPaths = (
-                               "$(SRCROOT)/llint/LowLevelAssembler.asm",
                        );
                        name = "Generate Derived Sources";
                        outputPaths = (
-                               "$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "set -e\n\nmkdir -p \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/\"\n\n/usr/bin/env ruby \"${SRCROOT}/offlineasm/generate_offset_extractor.rb\" \"-I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\" \"${SRCROOT}/llint/LowLevelInterpreter.asm\" \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\"\n";
+                       shellScript = "set -e\n\nmkdir -p \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/\"\n\n/usr/bin/env ruby \"${SRCROOT}/offlineasm/generate_offset_extractor.rb\" \"-I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\" \"${SRCROOT}/llint/LowLevelInterpreter.asm\" \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\" \"X86,X86_64,ARMv7,ARMv7s,ARM64,C_LOOP\"\n";
                };
                0FCEFAD91806191800472CE4 /* Copy LLVM Library Into Framework */ = {
                        isa = PBXShellScriptBuildPhase;
                        shellPath = /bin/sh;
                        shellScript = "set -e\n\nif [[ $ENABLE_FTL_JIT != \"ENABLE_FTL_JIT\" ]]\nthen\n    exit 0\nfi\n\nif [[ ${CONFIGURATION:=Debug} != \"Production\" ]]\nthen\n    # Copy the llvmForJSC library into the framework.\n    ditto \"${BUILT_PRODUCTS_DIR}/libllvmForJSC.dylib\" \"${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/Libraries/libllvmForJSC.dylib\"\nfi\n\nif [[ $PLATFORM_NAME != \"macosx\" ]]\nthen\n    exit 0\nfi\n\nif [ ! -e \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Libraries\" ]\nthen\n    ln -fs \"Versions/Current/Libraries\" \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Libraries\"\nfi";
                };
+               1A02D9A81B34A882000D1522 /* Add Symlink in /System/Library/PrivateFrameworks */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Add Symlink in /System/Library/PrivateFrameworks";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "if [[ ${PLATFORM_NAME} != \"iphoneos\" ]]; then\n    exit 0\nfi\n\nif [[ ! -d \"${INSTALL_ROOT}/${SYSTEM_LIBRARY_DIR}/PrivateFrameworks\" ]]; then\n    mkdir -p \"${INSTALL_ROOT}/${SYSTEM_LIBRARY_DIR}/PrivateFrameworks\"\nfi\n\nln -s -h -f ../Frameworks/JavaScriptCore.framework \"${INSTALL_ROOT}/${SYSTEM_LIBRARY_DIR}/PrivateFrameworks/JavaScriptCore.framework\"";
+               };
                3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellPath = /bin/sh;
                        shellScript = "exec ${SRCROOT}/postprocess-headers.sh";
                };
-               55850CA118F4842000F81829 /* Build Symbol Index Table */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       name = "Build Symbol Index Table";
-                       outputPaths = (
-                               "$(BUILT_PRODUCTS_DIR)/$(JAVASCRIPTCORE_RESOURCES_DIR)/Runtime.symtbl",
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "${SRCROOT}/build-symbol-table-index.sh";
-               };
-               559CD06A18F487A800F9ADC0 /* Copy LLVM IR */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       name = "Copy LLVM IR";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "${SRCROOT}/copy-llvm-ir-to-derived-sources.sh";
-               };
                5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables and Externals */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "set -e\n\nTRACING_D=\"$SRCROOT/runtime/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$HAVE_DTRACE\" = \"1\" && \"$TRACING_D\" -nt \"$TRACING_H\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
+                       shellScript = "set -e\n\nTRACING_D=\"$SRCROOT/runtime/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$TRACING_D\" -nt \"$TRACING_H\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
                };
                5D5D8ABF0E0D0B0300F9C692 /* Create /usr/local/bin/jsc symlink */ = {
                        isa = PBXShellScriptBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [[ \"${ACTION}\" == \"installhdrs\" ]]; then\n    exit 0\nfi\n\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/usr/bin/env ruby JavaScriptCore/offlineasm/asm.rb -I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore JavaScriptCore/llint/LowLevelInterpreter.asm ${BUILT_PRODUCTS_DIR}/JSCLLIntOffsetsExtractor LLIntAssembly.h || exit 1";
+                       shellScript = "if [[ \"${ACTION}\" == \"installhdrs\" ]]; then\n    exit 0\nfi\n\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/usr/bin/env ruby JavaScriptCore/offlineasm/asm.rb \"-I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\" JavaScriptCore/llint/LowLevelInterpreter.asm \"${BUILT_PRODUCTS_DIR}/JSCLLIntOffsetsExtractor\" LLIntAssembly.h || exit 1";
                };
                65FB3F6509D11E9100F49DEB /* Generate Derived Sources */ = {
                        isa = PBXShellScriptBuildPhase;
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */,
+                               65570F5A1AA4C3EA009B3C23 /* Regress141275.mm in Sources */,
                                C29ECB031804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.mm in Sources */,
                                FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */,
                                C20328201981979D0088B499 /* CustomGlobalObjectClassTest.c in Sources */,
                                C288B2DE18A54D3E007BE40B /* DateTests.mm in Sources */,
                                C2181FC218A948FB0025A235 /* JSExportTests.mm in Sources */,
+                               FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */,
                                1440F6100A4F85670005F061 /* testapi.c in Sources */,
                                86D2221A167EF9440024C804 /* testapi.mm in Sources */,
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               5540789A18DA58AD00EFF7F2 /* Sources */ = {
-                       isa = PBXSourcesBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                               554078AB18DA58AD00EFF7F2 /* ArrayConstructor.cpp in Sources */,
-                               554078AF18DA58AD00EFF7F2 /* ArrayPrototype.cpp in Sources */,
-                               55407A3818DA58AD00EFF7F2 /* NumberConstructor.cpp in Sources */,
-                               55407A3A18DA58AD00EFF7F2 /* NumberPrototype.cpp in Sources */,
+                               FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               9EA5C7A2190F088700508EBE /* InitializeLLVMMac.cpp in Sources */,
+                               9EA5C7A1190F084200508EBE /* BundlePath.mm in Sources */,
+                               52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */,
+                               9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */,
+                               9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */,
                                0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */,
+                               0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */,
                                0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
                                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
-                               147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
-                               A76140CD182982CB00750624 /* ArgumentsIteratorConstructor.cpp in Sources */,
-                               A76140CF182982CB00750624 /* ArgumentsIteratorPrototype.cpp in Sources */,
                                0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */,
                                0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
                                86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
-                               A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */,
                                65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */,
                                65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */,
                                0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
                                A7A8AF3417ADB5F3005AB174 /* ArrayBuffer.cpp in Sources */,
                                0FFC99D4184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp in Sources */,
                                A7A8AF3617ADB5F3005AB174 /* ArrayBufferView.cpp in Sources */,
+                               0F12DE0F1979D5FD0006FF4E /* ExceptionFuzz.cpp in Sources */,
                                147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */,
-                               A7BDAEC617F4EA1400F6140C /* ArrayIteratorConstructor.cpp in Sources */,
                                A7BDAEC817F4EA1400F6140C /* ArrayIteratorPrototype.cpp in Sources */,
                                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
                                147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
                                0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
-                               14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
+                               0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */,
                                14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
                                14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
                                14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
                                1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
                                0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
                                0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
-                               0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
+                               0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */,
                                969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
                                0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
                                0FC97F33182020D7002C9B26 /* CodeBlockJettisoningWatchpoint.cpp in Sources */,
                                A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
                                0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
                                86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
+                               0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */,
                                86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
                                0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
                                0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
                                0F9C5E5E18E35F5E00D431C3 /* FTLDWARFRegister.cpp in Sources */,
                                A709F2F217A0AC2A00512E98 /* CommonSlowPaths.cpp in Sources */,
                                6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */,
+                               0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
+                               0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */,
                                A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
                                147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
                                146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
                                2AACE63C18CA5A0300ED0191 /* GCActivityCallback.cpp in Sources */,
                                C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
                                0F2B66DE17B6B5AB00A7AE3F /* DataView.cpp in Sources */,
+                               0F682FB219BCB36400FA3BAD /* DFGSSACalculator.cpp in Sources */,
                                147F39C3107EC37600427A48 /* DateConstructor.cpp in Sources */,
                                147F39C4107EC37600427A48 /* DateConversion.cpp in Sources */,
                                147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */,
+                               7094C4DE1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp in Sources */,
                                147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */,
                                14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
-                               BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */,
                                149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
                                2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */,
                                0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
                                A77A423D17A0BBFD00A8DB81 /* DFGAbstractHeap.cpp in Sources */,
                                0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */,
-                               0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
                                0F485321187750560083B687 /* DFGArithMode.cpp in Sources */,
+                               0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
                                0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
                                A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
                                0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
                                0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
+                               0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */,
                                A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
-                               A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */,
                                2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
+                               0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */,
                                A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
                                86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
                                0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
+                               0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */,
                                0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
                                0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
                                A77A423F17A0BBFD00A8DB81 /* DFGClobberize.cpp in Sources */,
                                0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */,
                                0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
                                A7D89CF517A0B8CC00773AD8 /* DFGCriticalEdgeBreakingPhase.cpp in Sources */,
+                               FE384EE71ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp in Sources */,
                                0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
                                0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
                                0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */,
-                               A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */,
                                C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */,
                                0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */,
                                C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
                                0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
                                0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
                                0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
+                               0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */,
+                               0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */,
                                0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
                                0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
+                               0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
                                A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */,
                                A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
                                0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
+                               0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */,
                                0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */,
+                               0F9D36941AE9CC33000D4DFB /* DFGCleanUpPhase.cpp in Sources */,
                                A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */,
+                               0F3A1BF91A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp in Sources */,
                                86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */,
                                0F2FCCF918A60070001A27F8 /* DFGGraphSafepoint.cpp in Sources */,
                                A704D90517A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp in Sources */,
                                0F300B7B18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp in Sources */,
                                0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */,
-                               A5C3A1A518C0490200C9593A /* JSConsoleClient.cpp in Sources */,
+                               A5C3A1A518C0490200C9593A /* JSGlobalObjectConsoleClient.cpp in Sources */,
                                0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */,
                                86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
+                               0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */,
                                A78A9778179738B8009DF744 /* DFGJITFinalizer.cpp in Sources */,
                                0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */,
                                A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */,
                                A7D89CFD17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp in Sources */,
                                0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
                                0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
+                               FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */,
                                0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
+                               70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */,
                                0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
                                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
                                0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
                                0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
+                               70EC0EC21AA0D7DA00B6AAFA /* JSStringIterator.cpp in Sources */,
                                0F7025A91714B0FA00382C0E /* DFGOSRExitCompilerCommon.cpp in Sources */,
+                               A12BBFF41B044A9800664B69 /* IntlObject.cpp in Sources */,
                                0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */,
                                0F235BED17178E7300690C7F /* DFGOSRExitPreparation.cpp in Sources */,
                                0FFFC95B14EF90AD00C72532 /* DFGPhase.cpp in Sources */,
                                A78A977A179738B8009DF744 /* DFGPlan.cpp in Sources */,
                                0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
                                0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */,
-                               0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */,
                                0F2FCCFB18A60070001A27F8 /* DFGSafepoint.cpp in Sources */,
                                86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
                                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
                                86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
                                A7D89CFF17A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp in Sources */,
+                               2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */,
                                0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */,
+                               52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */,
+                               0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */,
                                0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */,
                                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */,
-                               2ACCF3DE185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp in Sources */,
+                               0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */,
                                0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */,
                                0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */,
                                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
                                0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
+                               709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
                                0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
                                0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
+                               0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
                                0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */,
                                0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */,
                                0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
                                0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */,
                                0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
+                               0FB17660196B8F9E0091052A /* DFGHeapLocation.cpp in Sources */,
                                0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */,
                                0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
+                               0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */,
                                0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
                                0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
                                0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
+                               0F9E32631B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp in Sources */,
                                0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */,
                                0FDB2CE7174830A2007B3C1B /* DFGWorklist.cpp in Sources */,
                                0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
                                86CA032E1038E8440028A609 /* Executable.cpp in Sources */,
                                A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
                                86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
+                               0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */,
                                0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
+                               52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */,
+                               0F2D4DEB19832DC4007D4B19 /* TypeProfilerLog.cpp in Sources */,
                                0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,
                                0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
+                               0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */,
+                               0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */,
+                               0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
                                0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
                                0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */,
                                0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */,
                                A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */,
+                               0FE834171A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp in Sources */,
                                0FD8A31917D51F2200CA2C40 /* FTLForOSREntryJITCode.cpp in Sources */,
                                0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
                                0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
+                               0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
                                0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
                                A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
+                               0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */,
+                               62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */,
                                0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
                                0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */,
                                0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */,
                                0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */,
                                0F6B1CC31862C47800845D97 /* FTLRegisterAtOffset.cpp in Sources */,
                                0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */,
-                               1CAA9A2218F4A220000A369D /* JSGlobalObjectProfilerAgent.cpp in Sources */,
                                0F25F1B1181635F300522F39 /* FTLSlowPathCall.cpp in Sources */,
                                0F25F1B3181635F300522F39 /* FTLSlowPathCallKey.cpp in Sources */,
                                0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */,
                                0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */,
                                0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */,
                                0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */,
+                               0F5A1273192D9FDF008764A3 /* DFGDoesGC.cpp in Sources */,
                                A53CE08718BC1A5600BEDF76 /* JSConsole.cpp in Sources */,
                                0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */,
                                147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
                                0FF0F19F16B72A17005DF95B /* FunctionExecutableDump.cpp in Sources */,
+                               52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */,
                                147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */,
+                               0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */,
                                0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
                                C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */,
                                C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */,
                                C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */,
                                0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */,
                                0FCEFACA1805E75500472CE4 /* InitializeLLVM.cpp in Sources */,
-                               0FCEFAB11805CA6D00472CE4 /* InitializeLLVMMac.mm in Sources */,
-                               0FCEFACB1805E75500472CE4 /* InitializeLLVMPOSIX.cpp in Sources */,
-                               E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
+                               527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */,
                                A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */,
+                               0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */,
                                A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */,
                                A58E35911860DECF001F24FE /* InjectedScriptHost.cpp in Sources */,
                                A513E5CA185F9624007E95AD /* InjectedScriptManager.cpp in Sources */,
                                A5840E20187B7B8600843B10 /* InjectedScriptModule.cpp in Sources */,
                                0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
+                               FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */,
                                A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
                                A593CF86184038CA00BFCE27 /* InspectorAgentRegistry.cpp in Sources */,
+                               0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */,
                                A593CF7C1840360300BFCE27 /* InspectorBackendDispatcher.cpp in Sources */,
                                2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */,
                                A5FD0081189B191A00633231 /* InspectorConsoleAgent.cpp in Sources */,
                                A57D23E51890CEBF0031C7FA /* InspectorDebuggerAgent.cpp in Sources */,
-                               A532438718568335002ED692 /* InspectorJSBackendDispatchers.cpp in Sources */,
-                               A532438918568335002ED692 /* InspectorJSFrontendDispatchers.cpp in Sources */,
-                               A532438B18568335002ED692 /* InspectorJSTypeBuilders.cpp in Sources */,
+                               A532438718568335002ED692 /* InspectorBackendDispatchers.cpp in Sources */,
+                               709FB8691AE335C60039D069 /* WeakSetConstructor.cpp in Sources */,
+                               A532438918568335002ED692 /* InspectorFrontendDispatchers.cpp in Sources */,
+                               A532438B18568335002ED692 /* InspectorProtocolObjects.cpp in Sources */,
                                A50E4B6118809DD50068A46D /* InspectorRuntimeAgent.cpp in Sources */,
                                A593CF821840377100BFCE27 /* InspectorValues.cpp in Sources */,
                                A78853F917972629001440E4 /* IntendedStructureChain.cpp in Sources */,
                                147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */,
                                1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */,
+                               70113D4B1A8DB093003848C4 /* IteratorOperations.cpp in Sources */,
                                A503FA19188E0FB000110F14 /* JavaScriptCallFrame.cpp in Sources */,
                                1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */,
                                86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */,
                                A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */,
                                0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */,
                                0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */,
+                               FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */,
                                14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */,
                                0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */,
                                0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
-                               140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
+                               140B7D1D0DC69AF7009C42B8 /* JSLexicalEnvironment.cpp in Sources */,
                                140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
                                C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */,
-                               A76140D1182982CB00750624 /* JSArgumentsIterator.cpp in Sources */,
                                147F39D0107EC37600427A48 /* JSArray.cpp in Sources */,
                                0F2B66E217B6B5AB00A7AE3F /* JSArrayBuffer.cpp in Sources */,
                                0F2B66E417B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp in Sources */,
                                0F2B66E817B6B5AB00A7AE3F /* JSArrayBufferView.cpp in Sources */,
                                A7BDAECA17F4EA1400F6140C /* JSArrayIterator.cpp in Sources */,
                                1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
+                               0F898F311B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp in Sources */,
                                86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */,
                                1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
                                1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
                                14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
                                A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */,
+                               657CF45819BF6662004ACBF2 /* JSCallee.cpp in Sources */,
                                147F39D1107EC37600427A48 /* JSCell.cpp in Sources */,
                                147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */,
                                1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
                                86E3C616167BABEE006D760A /* JSContext.mm in Sources */,
                                14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
+                               70DC3E091B2DF2C700054299 /* IteratorPrototype.cpp in Sources */,
+                               0FD949821A97DB9600E28966 /* JSCatchScope.cpp in Sources */,
                                A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */,
                                0F2B66EB17B6B5AB00A7AE3F /* JSDataView.cpp in Sources */,
                                0F2B66ED17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp in Sources */,
+                               0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */,
+                               FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */,
                                978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
+                               0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */,
                                140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,
                                147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */,
                                A5FD0085189B1B7E00633231 /* JSGlobalObjectConsoleAgent.cpp in Sources */,
                                A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */,
                                A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */,
                                14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */,
+                               0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */,
                                C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
                                A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */,
                                A74DEF95182D991400522C22 /* JSMapIterator.cpp in Sources */,
                                147F39D4107EC37600427A48 /* JSObject.cpp in Sources */,
                                1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
                                A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */,
+                               0FFB6C381AF48DDC00DB1BF7 /* TypeofType.cpp in Sources */,
                                95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
                                7C184E1A17BEDBD3007CB63A /* JSPromise.cpp in Sources */,
                                7C184E2217BEE240007CB63A /* JSPromiseConstructor.cpp in Sources */,
+                               A552C37F1ADDB8FE00139726 /* JSRemoteInspector.cpp in Sources */,
+                               0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */,
                                7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */,
-                               7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */,
                                7C184E1E17BEE22E007CB63A /* JSPromisePrototype.cpp in Sources */,
-                               7C008CDE1871258D00955C24 /* JSPromiseReaction.cpp in Sources */,
-                               A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */,
+                               FE1C0FFF1B194FD100B53FCA /* Exception.cpp in Sources */,
+                               709FB86B1AE335C60039D069 /* WeakSetPrototype.cpp in Sources */,
                                862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */,
                                9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */,
                                14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
                                A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
                                0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
                                A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */,
+                               0F20C2591A8013AB00DA3229 /* VirtualRegister.cpp in Sources */,
                                A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */,
                                2A83638918D7D0FE0000EBCC /* FullGCActivityCallback.cpp in Sources */,
                                1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
                                147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
+                               0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */,
                                2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
                                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
                                146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
                                0F2B66FA17B6B5AB00A7AE3F /* JSTypedArrayConstructors.cpp in Sources */,
                                0F2B66FC17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.cpp in Sources */,
                                0F2B66FE17B6B5AB00A7AE3F /* JSTypedArrays.cpp in Sources */,
+                               0FF054F91AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp in Sources */,
                                86E3C61A167BABEE006D760A /* JSValue.mm in Sources */,
+                               0FF8BDEA1AD4CF7100DFE884 /* InferredValue.cpp in Sources */,
+                               0F8F14351ADF090100ED792C /* DFGMovHintRemovalPhase.cpp in Sources */,
                                14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
-                               147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */,
+                               147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */,
                                86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */,
                                A7CA3AE717DA41AE006538AF /* JSWeakMap.cpp in Sources */,
                                A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
                                1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
+                               0FEE98431A89227500754E93 /* SetupVarargsFrame.cpp in Sources */,
                                86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
                                14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
                                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
                                FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
                                0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
                                0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */,
+                               0F392C891B46188400844728 /* DFGOSRExitFuzz.cpp in Sources */,
                                0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
+                               0FD949841A97DB9600E28966 /* JSFunctionNameScope.cpp in Sources */,
                                0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
                                0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
                                0FCEFACD1805E75500472CE4 /* LLVMAPI.cpp in Sources */,
                                A7A4AE0817973B26005612B1 /* MacroAssemblerX86Common.cpp in Sources */,
                                A5B6A74D18C6DBA600F11E91 /* ConsoleClient.cpp in Sources */,
                                A700873917CBE85300C3E643 /* MapConstructor.cpp in Sources */,
-                               A78507D617CBC6FD0011F6E7 /* MapData.cpp in Sources */,
-                               A74DEF91182D991400522C22 /* MapIteratorConstructor.cpp in Sources */,
                                A74DEF93182D991400522C22 /* MapIteratorPrototype.cpp in Sources */,
                                A700873D17CBE8D300C3E643 /* MapPrototype.cpp in Sources */,
                                C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
                                14469DDF107EC7E700650446 /* MathObject.cpp in Sources */,
                                90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */,
                                0FB5467D14F5CFD6002C2989 /* MethodOfGettingAValueProfile.cpp in Sources */,
-                               86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */,
-                               86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */,
-                               86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */,
                                14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */,
                                14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */,
                                148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */,
                                655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */,
+                               6546F5211A32B313006F07D5 /* NullGetterFunction.cpp in Sources */,
+                               65525FC51A6DD801007B5495 /* NullSetterFunction.cpp in Sources */,
+                               0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */,
                                14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */,
                                14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */,
                                14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */,
                                14469DE6107EC7E700650446 /* ObjectPrototype.cpp in Sources */,
                                E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
                                969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */,
+                               0FED67B91B26256D0066CE15 /* DFGConstantHoistingPhase.cpp in Sources */,
                                14280850107EC0D70013E7B2 /* Operations.cpp in Sources */,
                                0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
                                148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
                                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
                                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
                                95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
-                               0FC97F35182020D7002C9B26 /* ProfiledCodeBlockJettisoningWatchpoint.cpp in Sources */,
+                               0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */,
                                95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
                                95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
                                0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
                                0FF729AE166AD35C000F5BA3 /* ProfilerBytecodes.cpp in Sources */,
+                               0F6237971AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp in Sources */,
                                0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */,
                                0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */,
-                               1CAA9A1E18F4997F000A369D /* InspectorProfilerAgent.cpp in Sources */,
                                0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */,
                                0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */,
                                0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */,
                                0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
                                0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
                                0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
+                               70ECA6051AFDBEA200449739 /* JSTemplateRegistryKey.cpp in Sources */,
                                A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */,
-                               14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */,
                                14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */,
                                ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */,
                                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */,
                                1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
                                0F9332A314CA7DD70085F3C6 /* PutByIdStatus.cpp in Sources */,
+                               0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */,
                                0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */,
                                0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */,
                                14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
                                A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
+                               0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
                                8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
                                14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
                                8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
                                A5BA15EC182340B400A82E69 /* RemoteInspectorDebuggableConnection.mm in Sources */,
                                A5BA15EE182340B400A82E69 /* RemoteInspectorXPCConnection.mm in Sources */,
                                0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */,
+                               62D2D38F1ADF103F000206C1 /* FunctionRareData.cpp in Sources */,
                                0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
                                1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */,
+                               70EC0EC61AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp in Sources */,
                                A5FD0067189AFE9C00633231 /* ScriptArguments.cpp in Sources */,
                                A5FD006D189B00AA00633231 /* ScriptCallFrame.cpp in Sources */,
+                               0F04396D1B03DC0B009598B7 /* DFGCombinedLiveness.cpp in Sources */,
                                A5FD006F189B00AA00633231 /* ScriptCallStack.cpp in Sources */,
                                A5FD007D189B0B4C00633231 /* ScriptCallStackFactory.cpp in Sources */,
                                A503FA25188EFFFD00110F14 /* ScriptDebugServer.cpp in Sources */,
                                A54CF2F9184EAEDA00237F19 /* ScriptObject.cpp in Sources */,
                                A54CF2F5184EAB2400237F19 /* ScriptValue.cpp in Sources */,
                                A7299DA517D12858005F5FF9 /* SetConstructor.cpp in Sources */,
-                               A790DD6B182F499700588807 /* SetIteratorConstructor.cpp in Sources */,
+                               0FD1202F1A8AED12000F5280 /* FTLJSCallBase.cpp in Sources */,
+                               0F952ABC1B487A7700C367C5 /* TrackedReferences.cpp in Sources */,
                                A790DD6D182F499700588807 /* SetIteratorPrototype.cpp in Sources */,
                                A7299DA117D12848005F5FF9 /* SetPrototype.cpp in Sources */,
                                0F2B670417B6B5AB00A7AE3F /* SimpleTypedArrayController.cpp in Sources */,
                                A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
                                14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */,
                                14469DEC107EC7E700650446 /* StringObject.cpp in Sources */,
+                               0F8F14331ADF090100ED792C /* DFGEpoch.cpp in Sources */,
                                14469DED107EC7E700650446 /* StringPrototype.cpp in Sources */,
+                               0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */,
                                9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */,
                                BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */,
                                7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */,
                                C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */,
+                               7013CA8B1B491A9400CAE613 /* JSJob.cpp in Sources */,
                                0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
                                BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
-                               C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */,
+                               705B41AB1A6E501E00716757 /* Symbol.cpp in Sources */,
+                               705B41AD1A6E501E00716757 /* SymbolConstructor.cpp in Sources */,
+                               705B41AF1A6E501E00716757 /* SymbolObject.cpp in Sources */,
+                               705B41B11A6E501E00716757 /* SymbolPrototype.cpp in Sources */,
                                0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
                                0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */,
                                0FA2C17B17D7CF84009D015F /* TestRunnerUtils.cpp in Sources */,
                                A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */,
                                0F2B670717B6B5AB00A7AE3F /* TypedArrayController.cpp in Sources */,
                                0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */,
+                               52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */,
                                0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
                                0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
                                0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */,
                                0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
                                0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
                                0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
+                               0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */,
                                0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
                                A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
                                B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */,
                                0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */,
                                E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */,
                                FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */,
-                               FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */,
                                FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
                                FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */,
                                0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
                                1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
+                               0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */,
                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
                                A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
                                A7CA3AEB17DA5168006538AF /* WeakMapData.cpp in Sources */,
+                               4340A4841A9051AF00D73CCA /* MathCommon.cpp in Sources */,
                                A7CA3AE517DA41AE006538AF /* WeakMapPrototype.cpp in Sources */,
                                14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
                                2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */,
                                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
+                               0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */,
+                               0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
                                A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
                                863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
+                               0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */,
                                86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
                                86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
                                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
                        target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
                        targetProxy = 0FF922D214F46B2F0041A24E /* PBXContainerItemProxy */;
                };
-               5540756318DA58AD00EFF7F2 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 0FCEFAB51805D61600472CE4 /* llvmForJSC */;
-                       targetProxy = 5540756418DA58AD00EFF7F2 /* PBXContainerItemProxy */;
-               };
-               5540756518DA58AD00EFF7F2 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 65788A9D18B409EB00C189FF /* Offline Assembler */;
-                       targetProxy = 5540756618DA58AD00EFF7F2 /* PBXContainerItemProxy */;
-               };
-               5540756718DA58AD00EFF7F2 /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 65FB3F6609D11E9100F49DEB /* Derived Sources */;
-                       targetProxy = 5540756818DA58AD00EFF7F2 /* PBXContainerItemProxy */;
-               };
-               55F8FC2C18EB937B00783E6E /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 5540756218DA58AD00EFF7F2 /* Compile Runtime to LLVM IR */;
-                       targetProxy = 55F8FC2B18EB937B00783E6E /* PBXContainerItemProxy */;
-               };
                5D69E912152BE5470028D720 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 932F5BDA0822A1C700736975 /* jsc */;
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */;
                        buildSettings = {
-                               INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */;
                        buildSettings = {
-                               INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
                        };
                        name = Release;
                };
                        };
                        name = Production;
                };
-               55407AC418DA58AD00EFF7F2 /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */;
-                       buildSettings = {
-                       };
-                       name = Debug;
-               };
-               55407AC518DA58AD00EFF7F2 /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */;
-                       buildSettings = {
-                       };
-                       name = Release;
-               };
-               55407AC618DA58AD00EFF7F2 /* Profiling */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */;
-                       buildSettings = {
-                       };
-                       name = Profiling;
-               };
-               55407AC718DA58AD00EFF7F2 /* Production */ = {
-                       isa = XCBuildConfiguration;
-                       baseConfigurationReference = 5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */;
-                       buildSettings = {
-                       };
-                       name = Production;
-               };
                5D6B2A48152B9E17005231DE /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */;
                        buildSettings = {
-                               INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
                        };
                        name = Profiling;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Production;
                };
-               55407AC318DA58AD00EFF7F2 /* Build configuration list for PBXNativeTarget "Compile Runtime to LLVM IR" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               55407AC418DA58AD00EFF7F2 /* Debug */,
-                               55407AC518DA58AD00EFF7F2 /* Release */,
-                               55407AC618DA58AD00EFF7F2 /* Profiling */,
-                               55407AC718DA58AD00EFF7F2 /* Production */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Production;
-               };
                5D6B2A4C152B9E17005231DE /* Build configuration list for PBXAggregateTarget "Test Tools" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 17bcc2d6ed1439b920c4ab9b01060918d8fdd533..d13daba61d24758b0a062a9695a1e1825094c46e 100644 (file)
@@ -141,7 +141,7 @@ class Trie:
         str = makePadding(indent)
 
         if self.value != None:
-            print(str + "if (!isIdentPart(code[%d])) {" % (len(self.fullPrefix)))
+            print(str + "if (!isIdentPartIncludingEscape(code+%d, m_codeEnd)) {" % (len(self.fullPrefix)))
             print(str + "    internalShift<%d>();" % len(self.fullPrefix))
             print(str + "    if (shouldCreateIdentifier)")
             print(str + ("        data->ident = &m_vm->propertyNames->%sKeyword;" % self.fullPrefix))
@@ -184,8 +184,8 @@ class Trie:
     def printAsC(self):
         print("namespace JSC {")
         print("")
-        print("static ALWAYS_INLINE bool isIdentPart(LChar c);")
-        print("static ALWAYS_INLINE bool isIdentPart(UChar c);")
+        print("static ALWAYS_INLINE bool isIdentPartIncludingEscape(const LChar* code, const LChar* codeEnd);")
+        print("static ALWAYS_INLINE bool isIdentPartIncludingEscape(const UChar* code, const UChar* codeEnd);")
         # max length + 1 so we don't need to do any bounds checking at all
         print("static const int maxTokenLength = %d;" % (self.maxLength() + 1))
         print("")
index 978c37f2a6a25e7a52476bc647f72cae337c13fe..6cc8c0e6473f664dbd4d4409a8c92b21128bb9c8 100644 (file)
@@ -3,3 +3,14 @@ list(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
     ${EINA_INCLUDE_DIRS}
     ${EO_INCLUDE_DIRS}
 )
+add_definitions(-DSTATICALLY_LINKED_WITH_WTF)
+
+install(FILES API/JavaScript.h
+              API/JSBase.h
+              API/JSContextRef.h
+              API/JSObjectRef.h
+              API/JSStringRef.h
+              API/JSValueRef.h
+              API/WebKitAvailability.h
+        DESTINATION "${HEADER_INSTALL_DIR}/JavaScriptCore"
+)
index be016ec16bc71f6e768a7a8f198d73645788c09b..6f94a29a1c88af9b9f5a85806d05e22f0941b637 100644 (file)
@@ -1,3 +1,5 @@
+set(JavaScriptCore_OUTPUT_NAME javascriptcoregtk-${WEBKITGTK_API_VERSION})
+
 configure_file(javascriptcoregtk.pc.in ${CMAKE_BINARY_DIR}/Source/JavaScriptCore/javascriptcoregtk-${WEBKITGTK_API_VERSION}.pc @ONLY)
 configure_file(JavaScriptCore.gir.in ${CMAKE_BINARY_DIR}/JavaScriptCore-${WEBKITGTK_API_VERSION}.gir @ONLY)
 
@@ -23,9 +25,20 @@ install(FILES API/JavaScript.h
         DESTINATION "${WEBKITGTK_HEADER_INSTALL_DIR}/JavaScriptCore"
 )
 
-install(FILES ${CMAKE_BINARY_DIR}/JavaScriptCore-${WEBKITGTK_API_VERSION}.gir
-        DESTINATION ${INTROSPECTION_INSTALL_GIRDIR}
+if (ENABLE_INTROSPECTION)
+    install(FILES ${CMAKE_BINARY_DIR}/JavaScriptCore-${WEBKITGTK_API_VERSION}.gir
+            DESTINATION ${INTROSPECTION_INSTALL_GIRDIR}
+    )
+    install(FILES ${CMAKE_BINARY_DIR}/JavaScriptCore-${WEBKITGTK_API_VERSION}.typelib
+            DESTINATION ${INTROSPECTION_INSTALL_TYPELIBDIR}
+    )
+endif ()
+
+add_definitions(-DSTATICALLY_LINKED_WITH_WTF)
+
+list(APPEND JavaScriptCore_LIBRARIES
+    ${GLIB_LIBRARIES}
 )
-install(FILES ${CMAKE_BINARY_DIR}/JavaScriptCore-${WEBKITGTK_API_VERSION}.typelib
-        DESTINATION ${INTROSPECTION_INSTALL_TYPELIBDIR}
+list(APPEND JavaScriptCore_SYSTEM_INCLUDE_DIRECTORIES
+    ${GLIB_INCLUDE_DIRS}
 )
diff --git a/PlatformMac.cmake b/PlatformMac.cmake
new file mode 100644 (file)
index 0000000..b747df7
--- /dev/null
@@ -0,0 +1,41 @@
+find_library(COCOA_LIBRARY Cocoa)
+find_library(COREFOUNDATION_LIBRARY CoreFoundation)
+find_library(READLINE_LIBRARY Readline)
+list(APPEND JavaScriptCore_LIBRARIES
+    ${COREFOUNDATION_LIBRARY}
+    ${COCOA_LIBRARY}
+    ${READLINE_LIBRARY}
+    libicucore.dylib
+)
+
+list(APPEND JavaScriptCore_SOURCES
+    API/JSAPIWrapperObject.mm
+    API/JSContext.mm
+    API/JSManagedValue.mm
+    API/JSStringRefCF.cpp
+    API/JSValue.mm
+    API/JSVirtualMachine.mm
+    API/JSWrapperMap.mm
+    API/ObjCCallbackFunction.mm
+
+    inspector/remote/RemoteInspector.mm
+    inspector/remote/RemoteInspectorDebuggable.cpp
+    inspector/remote/RemoteInspectorDebuggableConnection.mm
+    inspector/remote/RemoteInspectorXPCConnection.mm
+)
+add_definitions(-DSTATICALLY_LINKED_WITH_WTF)
+
+add_custom_command(
+    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/TracingDtrace.h
+    DEPENDS ${JAVASCRIPTCORE_DIR}/runtime/Tracing.d
+    WORKING_DIRECTORY ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
+    COMMAND dtrace -h -o "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/TracingDtrace.h" -s "${JAVASCRIPTCORE_DIR}/runtime/Tracing.d";
+    VERBATIM)
+
+list(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
+    ${JAVASCRIPTCORE_DIR}/disassembler/udis86
+    ${JAVASCRIPTCORE_DIR}/icu
+)
+list(APPEND JavaScriptCore_HEADERS
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/TracingDtrace.h
+)
diff --git a/PlatformWin.cmake b/PlatformWin.cmake
new file mode 100644 (file)
index 0000000..9575a16
--- /dev/null
@@ -0,0 +1,29 @@
+list(APPEND JavaScriptCore_SOURCES
+    API/JSStringRefBSTR.cpp
+    API/JSStringRefCF.cpp
+)
+
+if (WTF_PLATFORM_WIN_CAIRO)
+    list(APPEND JavaScriptCore_LIBRARIES
+        CFLite
+    )
+else ()
+    list(APPEND JavaScriptCore_LIBRARIES
+        CoreFoundation
+    )
+endif ()
+
+if (MSVC AND "${JavaScriptCore_LIBRARY_TYPE}" MATCHES "SHARED")
+    get_property(WTF_LIBRARY_LOCATION TARGET WTF PROPERTY LOCATION)
+
+    add_custom_command(
+        OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/forwarded-exports.cpp
+        DEPENDS WTF
+        COMMAND ${PYTHON_EXECUTABLE} ${TOOLS_DIR}/Scripts/generate-win32-export-forwards ${WTF_LIBRARY_LOCATION} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/forwarded-exports.cpp
+        VERBATIM)
+    list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/forwarded-exports.cpp)
+endif ()
+
+list(REMOVE_ITEM JavaScriptCore_SOURCES
+    inspector/JSGlobalObjectInspectorController.cpp
+)
diff --git a/UpdateContents.py b/UpdateContents.py
new file mode 100644 (file)
index 0000000..52f9532
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+# Copyright (C) 2015 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple puter, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+import os
+
+assert(len(sys.argv) == 3)
+
+comp = sys.argv[1]
+filename = sys.argv[2]
+
+t = False
+
+if os.path.isfile(filename):
+    f = open(filename, 'r')
+    comparator = f.read()
+    f.close()
+    t = True
+
+if (not t or comp != comparator):
+    f = open(filename, 'w')
+    f.write(comp)
+    f.close()
index d51181409c88ad4db0e5ba489576e37c4426a570..68f3ed0342dbcbe5a8d75546f83fcf505a16b988 100644 (file)
@@ -624,9 +624,9 @@ public:
                 JumpType m_type : 8;
                 JumpLinkType m_linkType : 8;
                 Condition m_condition : 4;
-                bool m_is64Bit : 1;
                 unsigned m_bitNumber : 6;
-                RegisterID m_compareRegister : 5;
+                RegisterID m_compareRegister : 6;
+                bool m_is64Bit : 1;
             } realTypes;
             struct CopyTypes {
                 uint64_t content[3];
@@ -947,6 +947,7 @@ public:
     {
         ASSERT(!(offset & 0xfff));
         insn(pcRelative(true, offset >> 12, rd));
+        nopCortexA53Fix843419();
     }
 
     template<int datasize, SetFlags setFlags = DontSetFlags>
@@ -1568,6 +1569,7 @@ public:
     ALWAYS_INLINE void madd(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
         CHECK_DATASIZE();
+        nopCortexA53Fix835769<datasize>();
         insn(dataProcessing3Source(DATASIZE, DataOp_MADD, rm, ra, rn, rd));
     }
 
@@ -1620,6 +1622,7 @@ public:
     ALWAYS_INLINE void msub(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
         CHECK_DATASIZE();
+        nopCortexA53Fix835769<datasize>();
         insn(dataProcessing3Source(DATASIZE, DataOp_MSUB, rm, ra, rn, rd));
     }
 
@@ -1806,6 +1809,7 @@ public:
 
     ALWAYS_INLINE void smaddl(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
+        nopCortexA53Fix835769<64>();
         insn(dataProcessing3Source(Datasize_64, DataOp_SMADDL, rm, ra, rn, rd));
     }
 
@@ -1816,6 +1820,7 @@ public:
 
     ALWAYS_INLINE void smsubl(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
+        nopCortexA53Fix835769<64>();
         insn(dataProcessing3Source(Datasize_64, DataOp_SMSUBL, rm, ra, rn, rd));
     }
 
@@ -1958,7 +1963,13 @@ public:
     template<int datasize, SetFlags setFlags = DontSetFlags>
     ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, RegisterID rm)
     {
-        sub<datasize, setFlags>(rd, rn, rm, LSL, 0);
+        ASSERT_WITH_MESSAGE(!isSp(rd) || setFlags == DontSetFlags, "SUBS with shifted register does not support SP for Xd, it uses XZR for the register 31. SUBS with extended register support SP for Xd, but only if SetFlag is not used, otherwise register 31 is Xd.");
+        ASSERT_WITH_MESSAGE(!isSp(rm), "No encoding of SUBS supports SP for the third operand.");
+
+        if (isSp(rd) || isSp(rn))
+            sub<datasize, setFlags>(rd, rn, rm, UXTX, 0);
+        else
+            sub<datasize, setFlags>(rd, rn, rm, LSL, 0);
     }
 
     template<int datasize, SetFlags setFlags = DontSetFlags>
@@ -1972,12 +1983,8 @@ public:
     ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftType shift, int amount)
     {
         CHECK_DATASIZE();
-        if (isSp(rd) || isSp(rn)) {
-            ASSERT(shift == LSL);
-            ASSERT(!isSp(rm));
-            sub<datasize, setFlags>(rd, rn, rm, UXTX, amount);
-        } else
-            insn(addSubtractShiftedRegister(DATASIZE, AddOp_SUB, setFlags, shift, rm, amount, rn, rd));
+        ASSERT(!isSp(rd) && !isSp(rn) && !isSp(rm));
+        insn(addSubtractShiftedRegister(DATASIZE, AddOp_SUB, setFlags, shift, rm, amount, rn, rd));
     }
 
     template<int datasize>
@@ -2057,6 +2064,7 @@ public:
 
     ALWAYS_INLINE void umaddl(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
+        nopCortexA53Fix835769<64>();
         insn(dataProcessing3Source(Datasize_64, DataOp_UMADDL, rm, ra, rn, rd));
     }
 
@@ -2067,6 +2075,7 @@ public:
 
     ALWAYS_INLINE void umsubl(RegisterID rd, RegisterID rn, RegisterID rm, RegisterID ra)
     {
+        nopCortexA53Fix835769<64>();
         insn(dataProcessing3Source(Datasize_64, DataOp_UMSUBL, rm, ra, rn, rd));
     }
 
@@ -3229,7 +3238,7 @@ private:
         int insn = *static_cast<int*>(address);
         op = (insn >> 24) & 0x1;
         imm14 = (insn << 13) >> 18;
-        bitNumber = static_cast<unsigned>((((insn >> 26) & 0x20)) | ((insn > 19) & 0x1f));
+        bitNumber = static_cast<unsigned>((((insn >> 26) & 0x20)) | ((insn >> 19) & 0x1f));
         rt = static_cast<RegisterID>(insn & 0x1f);
         return (insn & 0x7e000000) == 0x36000000;
         
@@ -3627,6 +3636,37 @@ private:
         return (0xd6000000 | opc << 21 | op2 << 16 | op3 << 10 | xOrZr(rn) << 5 | op4);
     }
 
+    // Workaround for Cortex-A53 erratum (835769). Emit an extra nop if the
+    // last instruction in the buffer is a load, store or prefetch. Needed
+    // before 64-bit multiply-accumulate instructions.
+    template<int datasize>
+    ALWAYS_INLINE void nopCortexA53Fix835769()
+    {
+#if CPU(ARM64_CORTEXA53)
+        CHECK_DATASIZE();
+        if (datasize == 64) {
+            if (LIKELY(m_buffer.codeSize() >= sizeof(int32_t))) {
+                // From ARMv8 Reference Manual, Section C4.1: the encoding of the
+                // instructions in the Loads and stores instruction group is:
+                // ---- 1-0- ---- ---- ---- ---- ---- ----
+                if (UNLIKELY((*reinterpret_cast_ptr<int32_t*>(reinterpret_cast_ptr<char*>(m_buffer.data()) + m_buffer.codeSize() - sizeof(int32_t)) & 0x0a000000) == 0x08000000))
+                    nop();
+            }
+        }
+#endif
+    }
+
+    // Workaround for Cortex-A53 erratum (843419). Emit extra nops to avoid
+    // wrong address access after ADRP instruction.
+    ALWAYS_INLINE void nopCortexA53Fix843419()
+    {
+#if CPU(ARM64_CORTEXA53)
+        nop();
+        nop();
+        nop();
+#endif
+    }
+
     AssemblerBuffer m_buffer;
     Vector<LinkRecord, 0, UnsafeVectorOverflow> m_jumpsToLink;
     int m_indexOfLastWatchpoint;
index 087d31c14ab91ba25c089ec9fd40de7ce084bd3f..f18f0fe0829483be3a23e188077e2d4556a9eb4f 100644 (file)
@@ -36,62 +36,6 @@ namespace JSC {
 
     typedef uint32_t ARMWord;
 
-    namespace ARMRegisters {
-        typedef enum {
-            r0 = 0,
-            r1,
-            r2,
-            r3,
-            r4,
-            r5,
-            r6, S0 = r6,
-            r7,
-            r8,
-            r9,
-            r10,
-            r11, fp = r11, // frame pointer
-            r12, ip = r12, S1 = r12,
-            r13, sp = r13,
-            r14, lr = r14,
-            r15, pc = r15
-        } RegisterID;
-
-        typedef enum {
-            d0,
-            d1,
-            d2,
-            d3,
-            d4,
-            d5,
-            d6,
-            d7, SD0 = d7, /* Same as thumb assembler. */
-            d8,
-            d9,
-            d10,
-            d11,
-            d12,
-            d13,
-            d14,
-            d15,
-            d16,
-            d17,
-            d18,
-            d19,
-            d20,
-            d21,
-            d22,
-            d23,
-            d24,
-            d25,
-            d26,
-            d27,
-            d28,
-            d29,
-            d30,
-            d31
-        } FPRegisterID;
-
-#if USE(MASM_PROBE)
     #define FOR_EACH_CPU_REGISTER(V) \
         FOR_EACH_CPU_GPREGISTER(V) \
         FOR_EACH_CPU_SPECIAL_REGISTER(V) \
@@ -109,11 +53,11 @@ namespace JSC {
         V(void*, r8) \
         V(void*, r9) \
         V(void*, r10) \
-        V(void*, r11) \
+        V(void*, fp) \
         V(void*, ip) \
         V(void*, sp) \
         V(void*, lr) \
-        V(void*, pc)
+        V(void*, pc) \
 
     #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
         V(void*, apsr) \
@@ -135,8 +79,49 @@ namespace JSC {
         V(double, d12) \
         V(double, d13) \
         V(double, d14) \
-        V(double, d15)
-#endif // USE(MASM_PROBE)
+        V(double, d15) \
+        V(double, d16) \
+        V(double, d17) \
+        V(double, d18) \
+        V(double, d19) \
+        V(double, d20) \
+        V(double, d21) \
+        V(double, d22) \
+        V(double, d23) \
+        V(double, d24) \
+        V(double, d25) \
+        V(double, d26) \
+        V(double, d27) \
+        V(double, d28) \
+        V(double, d29) \
+        V(double, d30) \
+        V(double, d31) \
+
+    namespace ARMRegisters {
+
+        typedef enum {
+            #define DECLARE_REGISTER(_type, _regName) _regName,
+            FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+            #undef DECLARE_REGISTER
+
+            // Pseudonyms for some of the registers.
+            S0 = r6,
+            r11 = fp, // frame pointer
+            r12 = ip, S1 = ip,
+            r13 = sp,
+            r14 = lr,
+            r15 = pc
+        } RegisterID;
+
+        typedef enum {
+            #define DECLARE_REGISTER(_type, _regName) _regName,
+            FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+            #undef DECLARE_REGISTER
+
+            // Pseudonyms for some of the registers.
+            SD0 = d7, /* Same as thumb assembler. */
+        } FPRegisterID;
+
     } // namespace ARMRegisters
 
     class ARMAssembler {
@@ -231,6 +216,10 @@ namespace JSC {
 #endif
             NOP = 0xe1a00000,
             DMB_SY = 0xf57ff05f,
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
+            SDIV = 0x0710f010,
+            UDIV = 0x0730f010,
+#endif
         };
 
         enum {
@@ -492,6 +481,26 @@ namespace JSC {
             m_buffer.putInt(toARMWord(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm));
         }
 
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
+        template<int datasize>
+        void sdiv(int rd, int rn, int rm, Condition cc = AL)
+        {
+            static_assert(datasize == 32, "sdiv datasize must be 32 for armv7s");
+            ASSERT(rd != ARMRegisters::pc);
+            ASSERT(rn != ARMRegisters::pc);
+            ASSERT(rm != ARMRegisters::pc);
+            m_buffer.putInt(toARMWord(cc) | SDIV | RN(rd) | RM(rn) | RS(rm));
+        }
+
+        void udiv(int rd, int rn, int rm, Condition cc = AL)
+        {
+            ASSERT(rd != ARMRegisters::pc);
+            ASSERT(rn != ARMRegisters::pc);
+            ASSERT(rm != ARMRegisters::pc);
+            m_buffer.putInt(toARMWord(cc) | UDIV | RN(rd) | RM(rn) | RS(rm));
+        }
+#endif
+
         void vmov_f64(int dd, int dm, Condition cc = AL)
         {
             emitDoublePrecisionInstruction(toARMWord(cc) | VMOV_F64, dd, 0, dm);
@@ -1119,8 +1128,6 @@ namespace JSC {
                 linuxPageFlush(current, current + page);
 
             linuxPageFlush(current, end);
-#elif OS(WINCE)
-            CacheRangeFlush(code, size, CACHE_SYNC_ALL);
 #else
 #error "The cacheFlush support is missing on this platform."
 #endif
diff --git a/assembler/ARMv7Assembler.cpp b/assembler/ARMv7Assembler.cpp
deleted file mode 100644 (file)
index faca664..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
-
-#include "ARMv7Assembler.h"
-
-namespace JSC {
-
-}
-
-#endif
index ce079d90dfaed8a29e554291368d0ab287b2000a..1d731f98b6a0f9d051684f69b90ba6c4460f393c 100644 (file)
 namespace JSC {
 
 namespace ARMRegisters {
+
+    #define FOR_EACH_CPU_REGISTER(V) \
+        FOR_EACH_CPU_GPREGISTER(V) \
+        FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+        FOR_EACH_CPU_FPREGISTER(V)
+
+    // The following are defined as pairs of the following value:
+    // 1. type of the storage needed to save the register value by the JIT probe.
+    // 2. name of the register.
+    #define FOR_EACH_CPU_GPREGISTER(V) \
+        V(void*, r0) \
+        V(void*, r1) \
+        V(void*, r2) \
+        V(void*, r3) \
+        V(void*, r4) \
+        V(void*, r5) \
+        V(void*, r6) \
+        V(void*, r7) \
+        V(void*, r8) \
+        V(void*, r9) \
+        V(void*, r10) \
+        V(void*, r11) \
+        V(void*, ip) \
+        V(void*, sp) \
+        V(void*, lr) \
+        V(void*, pc)
+
+    #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+        V(void*, apsr) \
+        V(void*, fpscr) \
+
+    #define FOR_EACH_CPU_FPREGISTER(V) \
+        V(double, d0) \
+        V(double, d1) \
+        V(double, d2) \
+        V(double, d3) \
+        V(double, d4) \
+        V(double, d5) \
+        V(double, d6) \
+        V(double, d7) \
+        V(double, d8) \
+        V(double, d9) \
+        V(double, d10) \
+        V(double, d11) \
+        V(double, d12) \
+        V(double, d13) \
+        V(double, d14) \
+        V(double, d15) \
+        V(double, d16) \
+        V(double, d17) \
+        V(double, d18) \
+        V(double, d19) \
+        V(double, d20) \
+        V(double, d21) \
+        V(double, d22) \
+        V(double, d23) \
+        V(double, d24) \
+        V(double, d25) \
+        V(double, d26) \
+        V(double, d27) \
+        V(double, d28) \
+        V(double, d29) \
+        V(double, d30) \
+        V(double, d31)
+
     typedef enum {
-        r0,
-        r1,
-        r2,
-        r3,
-        r4,
-        r5,
-        r6,
-        r7, fp = r7,   // frame pointer
-        r8,
-        r9, sb = r9,   // static base
-        r10, sl = r10, // stack limit
-        r11,
-        r12, ip = r12,
-        r13, sp = r13,
-        r14, lr = r14,
-        r15, pc = r15,
+        #define DECLARE_REGISTER(_type, _regName) _regName,
+        FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+        #undef DECLARE_REGISTER
+
+        fp = r7,   // frame pointer
+        sb = r9,   // static base
+        sl = r10,  // stack limit
+        r12 = ip,
+        r13 = sp,
+        r14 = lr,
+        r15 = pc
     } RegisterID;
 
     typedef enum {
@@ -93,38 +153,9 @@ namespace ARMRegisters {
     } FPSingleRegisterID;
 
     typedef enum {
-        d0,
-        d1,
-        d2,
-        d3,
-        d4,
-        d5,
-        d6,
-        d7,
-        d8,
-        d9,
-        d10,
-        d11,
-        d12,
-        d13,
-        d14,
-        d15,
-        d16,
-        d17,
-        d18,
-        d19,
-        d20,
-        d21,
-        d22,
-        d23,
-        d24,
-        d25,
-        d26,
-        d27,
-        d28,
-        d29,
-        d30,
-        d31,
+        #define DECLARE_REGISTER(_type, _regName) _regName,
+        FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+        #undef DECLARE_REGISTER
     } FPDoubleRegisterID;
 
     typedef enum {
@@ -174,77 +205,7 @@ namespace ARMRegisters {
         return (FPDoubleRegisterID)(reg >> 1);
     }
 
-#if USE(MASM_PROBE)
-    #define FOR_EACH_CPU_REGISTER(V) \
-        FOR_EACH_CPU_GPREGISTER(V) \
-        FOR_EACH_CPU_SPECIAL_REGISTER(V) \
-        FOR_EACH_CPU_FPREGISTER(V)
-
-    #define FOR_EACH_CPU_GPREGISTER(V) \
-        V(void*, r0) \
-        V(void*, r1) \
-        V(void*, r2) \
-        V(void*, r3) \
-        V(void*, r4) \
-        V(void*, r5) \
-        V(void*, r6) \
-        V(void*, r7) \
-        V(void*, r8) \
-        V(void*, r9) \
-        V(void*, r10) \
-        V(void*, r11) \
-        V(void*, ip) \
-        V(void*, sp) \
-        V(void*, lr) \
-        V(void*, pc)
-
-    #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
-        V(void*, apsr) \
-        V(void*, fpscr) \
-
-    #define FOR_EACH_CPU_FPREGISTER(V) \
-        V(double, d0) \
-        V(double, d1) \
-        V(double, d2) \
-        V(double, d3) \
-        V(double, d4) \
-        V(double, d5) \
-        V(double, d6) \
-        V(double, d7) \
-        V(double, d8) \
-        V(double, d9) \
-        V(double, d10) \
-        V(double, d11) \
-        V(double, d12) \
-        V(double, d13) \
-        V(double, d14) \
-        V(double, d15) \
-        FOR_EACH_CPU_FPREGISTER_EXTENSION(V)
-
-#if CPU(APPLE_ARMV7S)
-    #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) \
-        V(double, d16) \
-        V(double, d17) \
-        V(double, d18) \
-        V(double, d19) \
-        V(double, d20) \
-        V(double, d21) \
-        V(double, d22) \
-        V(double, d23) \
-        V(double, d24) \
-        V(double, d25) \
-        V(double, d26) \
-        V(double, d27) \
-        V(double, d28) \
-        V(double, d29) \
-        V(double, d30) \
-        V(double, d31)
-#else
-    #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) // Nothing to add.
-#endif // CPU(APPLE_ARMV7S)
-
-#endif // USE(MASM_PROBE)
-}
+} // namespace ARMRegisters
 
 class ARMv7Assembler;
 class ARMThumbImmediate {
@@ -747,7 +708,7 @@ private:
         OP_ROR_reg_T2   = 0xFA60,
         OP_CLZ          = 0xFAB0,
         OP_SMULL_T1     = 0xFB80,
-#if CPU(APPLE_ARMV7S)
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
         OP_SDIV_T1      = 0xFB90,
         OP_UDIV_T1      = 0xFBB0,
 #endif
@@ -1538,7 +1499,7 @@ public:
         m_formatter.twoWordOp16Imm16(OP_PUSH_T2, registerList);
     }
 
-#if CPU(APPLE_ARMV7S)
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
     template<int datasize>
     ALWAYS_INLINE void sdiv(RegisterID rd, RegisterID rn, RegisterID rm)
     {
@@ -1687,8 +1648,8 @@ public:
         ASSERT(rn != ARMRegisters::pc);
         ASSERT(imm.isUInt12());
         
-        if (!((rt | rn) & 8) && imm.isUInt7())
-            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt7() >> 2, rn, rt);
+        if (!((rt | rn) & 8) && imm.isUInt6())
+            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt6() >> 1, rn, rt);
         else
             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T2, rn, rt, imm.getUInt12());
     }
@@ -1886,7 +1847,7 @@ public:
         m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
     }
 
-#if CPU(APPLE_ARMV7S)
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
     ALWAYS_INLINE void udiv(RegisterID rd, RegisterID rn, RegisterID rm)
     {
         ASSERT(!BadReg(rd));
@@ -2411,8 +2372,6 @@ public:
             linuxPageFlush(current, current + page);
 
         linuxPageFlush(current, end);
-#elif OS(WINCE)
-        CacheRangeFlush(code, size, CACHE_SYNC_ALL);
 #else
 #error "The cacheFlush support is missing on this platform."
 #endif
index 34c345bec3f101fbe29b19dbcaa49f5247eded1a..1a5f068c720b31f2485082cd97a5af8a2ddebaf1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,6 +57,7 @@ enum AbortReason {
     DFGSlowPathGeneratorFellThrough                   = 210,
     DFGUnreachableBasicBlock                          = 220,
     DFGUnreasonableOSREntryJumpDestination            = 230,
+    DFGVarargsThrowingPathDidNotThrow                 = 235,
     JITDivOperandsAreNotNumbers                       = 240,
     JITGetByValResultIsNotEmpty                       = 250,
     JITNotSupported                                   = 260,
index a20990072fa058ba5cbb1e55a7a85b0da5600e49..6e82dcc5eb2758e7ab960b022a7dbaf58ce0736f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,9 +39,9 @@
 
 namespace JSC {
 
-inline bool isARMv7s()
+inline bool isARMv7IDIVSupported()
 {
-#if CPU(APPLE_ARMV7S)
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
     return true;
 #else
     return false;
@@ -66,9 +66,9 @@ inline bool isX86()
 #endif
 }
 
-inline bool optimizeForARMv7s()
+inline bool optimizeForARMv7IDIVSupported()
 {
-    return isARMv7s() && Options::enableArchitectureSpecificOptimizations();
+    return isARMv7IDIVSupported() && Options::enableArchitectureSpecificOptimizations();
 }
 
 inline bool optimizeForARM64()
@@ -88,10 +88,11 @@ namespace DFG {
 struct OSRExit;
 }
 
-template <class AssemblerType>
+template <class AssemblerType, class MacroAssemblerType>
 class AbstractMacroAssembler {
 public:
     friend class JITWriteBarrierBase;
+    typedef AbstractMacroAssembler<AssemblerType, MacroAssemblerType> AbstractMacroAssemblerType;
     typedef AssemblerType AssemblerType_T;
 
     typedef MacroAssemblerCodePtr CodePtr;
@@ -204,6 +205,11 @@ public:
         RegisterID index;
         Scale scale;
         int32_t offset;
+        
+        BaseIndex withOffset(int32_t additionalOffset)
+        {
+            return BaseIndex(base, index, scale, offset + additionalOffset);
+        }
     };
 
     // AbsoluteAddress:
@@ -355,7 +361,7 @@ public:
     // A Label records a point in the generated instruction stream, typically such that
     // it may be used as a destination for a jump.
     class Label {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend struct DFG::OSRExit;
         friend class Jump;
@@ -368,7 +374,7 @@ public:
         {
         }
 
-        Label(AbstractMacroAssembler<AssemblerType>* masm)
+        Label(AbstractMacroAssemblerType* masm)
             : m_label(masm->m_assembler.label())
         {
             masm->invalidateAllTempRegisters();
@@ -390,7 +396,7 @@ public:
     //
     // addPtr(TrustedImmPtr(i), a, b)
     class ConvertibleLoadLabel {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend class LinkBuffer;
         
@@ -399,7 +405,7 @@ public:
         {
         }
         
-        ConvertibleLoadLabel(AbstractMacroAssembler<AssemblerType>* masm)
+        ConvertibleLoadLabel(AbstractMacroAssemblerType* masm)
             : m_label(masm->m_assembler.labelIgnoringWatchpoints())
         {
         }
@@ -414,7 +420,7 @@ public:
     // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
     // patched after the code has been generated.
     class DataLabelPtr {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend class LinkBuffer;
     public:
@@ -422,7 +428,7 @@ public:
         {
         }
 
-        DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
+        DataLabelPtr(AbstractMacroAssemblerType* masm)
             : m_label(masm->m_assembler.label())
         {
         }
@@ -438,7 +444,7 @@ public:
     // A DataLabel32 is used to refer to a location in the code containing a 32-bit constant to be
     // patched after the code has been generated.
     class DataLabel32 {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend class LinkBuffer;
     public:
@@ -446,7 +452,7 @@ public:
         {
         }
 
-        DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
+        DataLabel32(AbstractMacroAssemblerType* masm)
             : m_label(masm->m_assembler.label())
         {
         }
@@ -462,7 +468,7 @@ public:
     // A DataLabelCompact is used to refer to a location in the code containing a
     // compact immediate to be patched after the code has been generated.
     class DataLabelCompact {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend class LinkBuffer;
     public:
@@ -470,7 +476,7 @@ public:
         {
         }
         
-        DataLabelCompact(AbstractMacroAssembler<AssemblerType>* masm)
+        DataLabelCompact(AbstractMacroAssemblerType* masm)
             : m_label(masm->m_assembler.label())
         {
         }
@@ -493,7 +499,7 @@ public:
     // relative offset such that when executed it will call to the desired
     // destination.
     class Call {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
 
     public:
@@ -537,7 +543,7 @@ public:
     // relative offset such that when executed it will jump to the desired
     // destination.
     class Jump {
-        template<class TemplateAssemblerType>
+        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
         friend class AbstractMacroAssembler;
         friend class Call;
         friend struct DFG::OSRExit;
@@ -602,7 +608,7 @@ public:
             return result;
         }
 
-        void link(AbstractMacroAssembler<AssemblerType>* masm) const
+        void link(AbstractMacroAssemblerType* masm) const
         {
             masm->invalidateAllTempRegisters();
 
@@ -626,7 +632,7 @@ public:
 #endif
         }
         
-        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
+        void linkTo(Label label, AbstractMacroAssemblerType* masm) const
         {
 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
             masm->checkRegisterAllocationAgainstBranchRange(label.m_label.m_offset, m_label.m_offset);
@@ -698,7 +704,7 @@ public:
                 append(jump);
         }
 
-        void link(AbstractMacroAssembler<AssemblerType>* masm)
+        void link(AbstractMacroAssemblerType* masm)
         {
             size_t size = m_jumps.size();
             for (size_t i = 0; i < size; ++i)
@@ -706,7 +712,7 @@ public:
             m_jumps.clear();
         }
         
-        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+        void linkTo(Label label, AbstractMacroAssemblerType* masm)
         {
             size_t size = m_jumps.size();
             for (size_t i = 0; i < size; ++i)
@@ -836,6 +842,188 @@ public:
         AssemblerType::cacheFlush(code, size);
     }
 
+#if ENABLE(MASM_PROBE)
+
+    struct CPUState {
+        #define DECLARE_REGISTER(_type, _regName) \
+            _type _regName;
+        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
+        #undef DECLARE_REGISTER
+
+        static const char* registerName(RegisterID regID)
+        {
+            switch (regID) {
+                #define DECLARE_REGISTER(_type, _regName) \
+                case RegisterID::_regName: \
+                    return #_regName;
+                FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+                #undef DECLARE_REGISTER
+            }
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        static const char* registerName(FPRegisterID regID)
+        {
+            switch (regID) {
+                #define DECLARE_REGISTER(_type, _regName) \
+                case FPRegisterID::_regName: \
+                    return #_regName;
+                FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+                #undef DECLARE_REGISTER
+            }
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        void* registerValue(RegisterID regID)
+        {
+            switch (regID) {
+                #define DECLARE_REGISTER(_type, _regName) \
+                case RegisterID::_regName: \
+                    return _regName;
+                FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+                #undef DECLARE_REGISTER
+            }
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        double registerValue(FPRegisterID regID)
+        {
+            switch (regID) {
+                #define DECLARE_REGISTER(_type, _regName) \
+                case FPRegisterID::_regName: \
+                    return _regName;
+                FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+                #undef DECLARE_REGISTER
+            }
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+    };
+
+    struct ProbeContext;
+    typedef void (*ProbeFunction)(struct ProbeContext*);
+
+    struct ProbeContext {
+        ProbeFunction probeFunction;
+        void* arg1;
+        void* arg2;
+        CPUState cpu;
+
+        void print(int indentation = 0)
+        {
+            #define INDENT MacroAssemblerType::printIndent(indentation)
+
+            INDENT, dataLogF("ProbeContext %p {\n", this);
+            indentation++;
+            {
+                INDENT, dataLogF("probeFunction: %p\n", probeFunction);
+                INDENT, dataLogF("arg1: %p %llu\n", arg1, reinterpret_cast<int64_t>(arg1));
+                INDENT, dataLogF("arg2: %p %llu\n", arg2, reinterpret_cast<int64_t>(arg2));
+                MacroAssemblerType::printCPU(cpu, indentation);
+            }
+            indentation--;
+            INDENT, dataLog("}\n");
+
+            #undef INDENT
+        }
+    };
+
+    static void printIndent(int indentation)
+    {
+        for (; indentation > 0; indentation--)
+            dataLog("    ");
+    }
+
+    static void printCPU(CPUState& cpu, int indentation = 0)
+    {
+        #define INDENT printIndent(indentation)
+
+        INDENT, dataLog("cpu: {\n");
+        MacroAssemblerType::printCPURegisters(cpu, indentation + 1);
+        INDENT, dataLog("}\n");
+
+        #undef INDENT
+    }
+
+    // This is a marker type only used with print(). See print() below for details.
+    struct AllRegisters { };
+
+    // Emits code which will print debugging info at runtime. The type of values that
+    // can be printed is encapsulated in the PrintArg struct below. Here are some
+    // examples:
+    //
+    //      print("Hello world\n"); // Emits code to print the string.
+    //
+    //      CodeBlock* cb = ...;
+    //      print(cb);              // Emits code to print the pointer value.
+    //
+    //      RegisterID regID = ...;
+    //      print(regID);           // Emits code to print the register value (not the id).
+    //
+    //      // Emits code to print all registers.  Unlike other items, this prints
+    //      // multiple lines as follows:
+    //      //      cpu {
+    //      //          eax: 0x123456789
+    //      //          ebx: 0x000000abc
+    //      //          ...
+    //      //      }
+    //      print(AllRegisters());
+    //
+    //      // Print multiple things at once. This incurs the probe overhead only once
+    //      // to print all the items.
+    //      print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters());
+
+    template<typename... Arguments>
+    void print(Arguments... args)
+    {
+        printInternal(static_cast<MacroAssemblerType*>(this), args...);
+    }
+
+    // This function will be called by printCPU() to print the contents of the
+    // target specific registers which are saved away in the CPUState struct.
+    // printCPURegisters() should make use of printIndentation() to print the
+    // registers with the appropriate amount of indentation.
+    //
+    // Note: printCPURegisters() should be implemented by the target specific
+    // MacroAssembler. This prototype is only provided here to document the
+    // interface.
+
+    static void printCPURegisters(CPUState&, int indentation = 0);
+
+    // This function will be called by print() to print the contents of a
+    // specific register (from the CPUState) in line with other items in the
+    // print stream. Hence, no indentation is needed.
+    //
+    // Note: printRegister() should be implemented by the target specific
+    // MacroAssembler. These prototypes are only provided here to document their
+    // interface.
+
+    static void printRegister(CPUState&, RegisterID);
+    static void printRegister(CPUState&, FPRegisterID);
+
+    // This function emits code to preserve the CPUState (e.g. registers),
+    // call a user supplied probe function, and restore the CPUState before
+    // continuing with other JIT generated code.
+    //
+    // The user supplied probe function will be called with a single pointer to
+    // a ProbeContext struct (defined above) which contains, among other things,
+    // the preserved CPUState. This allows the user probe function to inspect
+    // the CPUState at that point in the JIT generated code.
+    //
+    // If the user probe function alters the register values in the ProbeContext,
+    // the altered values will be loaded into the CPU registers when the probe
+    // returns.
+    //
+    // The ProbeContext is stack allocated and is only valid for the duration
+    // of the call to the user probe function.
+    //
+    // Note: probe() should be implemented by the target specific MacroAssembler.
+    // This prototype is only provided here to document the interface.
+
+    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
+
+#endif // ENABLE(MASM_PROBE)
+
     AssemblerType m_assembler;
     
 protected:
@@ -877,7 +1065,7 @@ protected:
         friend class Label;
 
     public:
-        CachedTempRegister(AbstractMacroAssembler<AssemblerType>* masm, RegisterID registerID)
+        CachedTempRegister(AbstractMacroAssemblerType* masm, RegisterID registerID)
             : m_masm(masm)
             , m_registerID(registerID)
             , m_value(0)
@@ -905,7 +1093,7 @@ protected:
         ALWAYS_INLINE void invalidate() { m_masm->clearTempRegisterValid(m_validBit); }
 
     private:
-        AbstractMacroAssembler<AssemblerType>* m_masm;
+        AbstractMacroAssemblerType* m_masm;
         RegisterID m_registerID;
         intptr_t m_value;
         unsigned m_validBit;
@@ -995,7 +1183,143 @@ protected:
     {
         AssemblerType::replaceWithAddressComputation(label.dataLocation());
     }
-};
+
+private:
+
+#if ENABLE(MASM_PROBE)
+
+    struct PrintArg {
+    
+        enum class Type {
+            AllRegisters,
+            RegisterID,
+            FPRegisterID,
+            ConstCharPtr,
+            ConstVoidPtr,
+            IntptrValue,
+            UintptrValue,
+        };
+
+        PrintArg(AllRegisters&)
+            : type(Type::AllRegisters)
+        {
+        }
+
+        PrintArg(RegisterID regID)
+            : type(Type::RegisterID)
+        {
+            u.gpRegisterID = regID;
+        }
+
+        PrintArg(FPRegisterID regID)
+            : type(Type::FPRegisterID)
+        {
+            u.fpRegisterID = regID;
+        }
+
+        PrintArg(const char* ptr)
+            : type(Type::ConstCharPtr)
+        {
+            u.constCharPtr = ptr;
+        }
+
+        PrintArg(const void* ptr)
+            : type(Type::ConstVoidPtr)
+        {
+            u.constVoidPtr = ptr;
+        }
+
+        PrintArg(int value)
+            : type(Type::IntptrValue)
+        {
+            u.intptrValue = value;
+        }
+
+        PrintArg(unsigned value)
+            : type(Type::UintptrValue)
+        {
+            u.intptrValue = value;
+        }
+
+        PrintArg(intptr_t value)
+            : type(Type::IntptrValue)
+        {
+            u.intptrValue = value;
+        }
+
+        PrintArg(uintptr_t value)
+            : type(Type::UintptrValue)
+        {
+            u.uintptrValue = value;
+        }
+
+        Type type;
+        union {
+            RegisterID gpRegisterID;
+            FPRegisterID fpRegisterID;
+            const char* constCharPtr;
+            const void* constVoidPtr;
+            intptr_t intptrValue;
+            uintptr_t uintptrValue;
+        } u;
+    };
+
+    typedef Vector<PrintArg> PrintArgsList;
+
+    template<typename FirstArg, typename... Arguments>
+    static void appendPrintArg(PrintArgsList* argsList, FirstArg& firstArg, Arguments... otherArgs)
+    {
+        argsList->append(PrintArg(firstArg));
+        appendPrintArg(argsList, otherArgs...);
+    }
+
+    static void appendPrintArg(PrintArgsList*) { }
+
+    
+    template<typename... Arguments>
+    static void printInternal(MacroAssemblerType* masm, Arguments... args)
+    {
+        auto argsList = std::make_unique<PrintArgsList>();
+        appendPrintArg(argsList.get(), args...);
+        masm->probe(printCallback, argsList.release());
+    }
+
+    static void printCallback(ProbeContext* context)
+    {
+        typedef PrintArg Arg;
+        PrintArgsList& argsList =
+            *reinterpret_cast<PrintArgsList*>(context->arg1);
+        for (size_t i = 0; i < argsList.size(); i++) {
+            auto& arg = argsList[i];
+            switch (arg.type) {
+            case Arg::Type::AllRegisters:
+                MacroAssemblerType::printCPU(context->cpu);
+                break;
+            case Arg::Type::RegisterID:
+                MacroAssemblerType::printRegister(context->cpu, arg.u.gpRegisterID);
+                break;
+            case Arg::Type::FPRegisterID:
+                MacroAssemblerType::printRegister(context->cpu, arg.u.fpRegisterID);
+                break;
+            case Arg::Type::ConstCharPtr:
+                dataLog(arg.u.constCharPtr);
+                break;
+            case Arg::Type::ConstVoidPtr:
+                dataLogF("%p", arg.u.constVoidPtr);
+                break;
+            case Arg::Type::IntptrValue:
+                dataLog(arg.u.intptrValue);
+                break;
+            case Arg::Type::UintptrValue:
+                dataLog(arg.u.uintptrValue);
+                break;
+            }
+        }
+    }
+
+#endif // ENABLE(MASM_PROBE)
+
+}; // class AbstractMacroAssembler
 
 } // namespace JSC
 
index 1c33fe1ac26fa017eb73e9da923d09567a6e4dd5..3632a5b6ef3cf8fd100e29593756945394a3227f 100644 (file)
@@ -69,7 +69,7 @@ namespace JSC {
 
         AssemblerData(unsigned initialCapacity)
         {
-            m_capacity = fastMallocGoodSize(initialCapacity);
+            m_capacity = initialCapacity;
             m_buffer = static_cast<char*>(fastMalloc(m_capacity));
         }
 
@@ -101,7 +101,7 @@ namespace JSC {
 
         void grow(unsigned extraCapacity = 0)
         {
-            m_capacity = fastMallocGoodSize(m_capacity + m_capacity / 2 + extraCapacity);
+            m_capacity = m_capacity + m_capacity / 2 + extraCapacity;
             m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
         }
 
index a66541d605b002ba29a1e1b40e0bfdeedcc20fcd..d53ef451b1ce6a35fd2970e503f66d49f0793e37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,19 +59,28 @@ LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format,
 {
     CodeRef result = finalizeCodeWithoutDisassembly();
 
-#if ENABLE(DISASSEMBLER)
-    dataLogF("Generated JIT code for ");
+    if (m_alreadyDisassembled)
+        return result;
+    
+    StringPrintStream out;
+    out.printf("Generated JIT code for ");
     va_list argList;
     va_start(argList, format);
-    WTF::dataLogFV(format, argList);
+    out.vprintf(format, argList);
     va_end(argList);
-    dataLogF(":\n");
+    out.printf(":\n");
+
+    out.printf("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
+    
+    CString header = out.toCString();
     
-    dataLogF("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
+    if (Options::asyncDisassembly()) {
+        disassembleAsynchronously(header, result, m_size, "    ");
+        return result;
+    }
+    
+    dataLog(header);
     disassemble(result.code(), m_size, "    ", WTF::dataFile());
-#else
-    UNUSED_PARAM(format);
-#endif // ENABLE(DISASSEMBLER)
     
     return result;
 }
index 516e4568c8074d557d9b2e00188ce09d67d8703c..9b0d4c437ba017952de03942b1aaadf01a90bc6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -254,6 +254,9 @@ public:
     {
         return m_size;
     }
+    
+    bool wasAlreadyDisassembled() const { return m_alreadyDisassembled; }
+    void didAlreadyDisassemble() { m_alreadyDisassembled = true; }
 
 private:
 #if ENABLE(BRANCH_COMPACTION)
@@ -310,6 +313,7 @@ private:
 #ifndef NDEBUG
     bool m_completed;
 #endif
+    bool m_alreadyDisassembled { false };
 };
 
 #define FINALIZE_CODE_IF(condition, linkBufferReference, dataLogFArgumentsForHeading)  \
@@ -320,7 +324,7 @@ private:
 bool shouldShowDisassemblyFor(CodeBlock*);
 
 #define FINALIZE_CODE_FOR(codeBlock, linkBufferReference, dataLogFArgumentsForHeading)  \
-    FINALIZE_CODE_IF(shouldShowDisassemblyFor(codeBlock), linkBufferReference, dataLogFArgumentsForHeading)
+    FINALIZE_CODE_IF(shouldShowDisassemblyFor(codeBlock) || Options::asyncDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
 
 // Use this to finalize code, like so:
 //
@@ -339,10 +343,10 @@ bool shouldShowDisassemblyFor(CodeBlock*);
 // is true, so you can hide expensive disassembly-only computations inside there.
 
 #define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading)  \
-    FINALIZE_CODE_IF(JSC::Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
+    FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
 
 #define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading)  \
-    FINALIZE_CODE_IF((JSC::Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)
+    FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::showDisassembly() || Options::showDFGDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
 
 } // namespace JSC
 
index c70f2b7904e47ef99cc99a1091037f44549cf825..fd4c5bbf5e4938e7ff96f1429d8fb5659ea2a555 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -471,6 +471,16 @@ public:
     {
         lshift32(trustedImm32ForShift(imm), srcDest);
     }
+    
+    void rshiftPtr(Imm32 imm, RegisterID srcDest)
+    {
+        rshift32(trustedImm32ForShift(imm), srcDest);
+    }
+
+    void urshiftPtr(Imm32 imm, RegisterID srcDest)
+    {
+        urshift32(trustedImm32ForShift(imm), srcDest);
+    }
 
     void negPtr(RegisterID dest)
     {
@@ -750,6 +760,16 @@ public:
         lshift64(trustedImm32ForShift(imm), srcDest);
     }
 
+    void rshiftPtr(Imm32 imm, RegisterID srcDest)
+    {
+        rshift64(trustedImm32ForShift(imm), srcDest);
+    }
+
+    void urshiftPtr(Imm32 imm, RegisterID srcDest)
+    {
+        urshift64(trustedImm32ForShift(imm), srcDest);
+    }
+
     void negPtr(RegisterID dest)
     {
         neg64(dest);
index a6f3e65c028fd3a0133fb426d34f80501c30f4fc..2500d84871340987eaca99ff39c79dd5ff5e42d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc.
+ * Copyright (C) 2013, 2014 Apple Inc.
  * Copyright (C) 2009 University of Szeged
  * All rights reserved.
  *
 
 #include "MacroAssemblerARM.h"
 
-#if USE(MASM_PROBE)
-#include <wtf/StdLibExtras.h>
-#endif
-
 #if OS(LINUX)
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -50,7 +46,7 @@ static bool isVFPPresent()
 {
 #if OS(LINUX)
     int fd = open("/proc/self/auxv", O_RDONLY);
-    if (fd > 0) {
+    if (fd != -1) {
         Elf32_auxv_t aux;
         while (read(fd, &aux, sizeof(Elf32_auxv_t))) {
             if (aux.a_type == AT_HWCAP) {
@@ -99,51 +95,58 @@ void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, Register
 }
 #endif // CPU(ARMV5_OR_LOWER)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
+
+#define INDENT printIndent(indentation)
 
-void MacroAssemblerARM::ProbeContext::dumpCPURegisters(const char* indentation)
+void MacroAssemblerARM::printCPURegisters(CPUState& cpu, int indentation)
 {
-    #define DUMP_GPREGISTER(_type, _regName) { \
+    #define PRINT_GPREGISTER(_type, _regName) { \
         int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
-        dataLogF("%s    %5s: 0x%08x   %d\n", indentation, #_regName, value, value) ; \
+        INDENT, dataLogF("%5s: 0x%08x  %d\n", #_regName, value, value) ; \
     }
-    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
-    FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER)
-    #undef DUMP_GPREGISTER
+    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
+    FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER)
+    #undef PRINT_GPREGISTER
 
-    #define DUMP_FPREGISTER(_type, _regName) { \
-        uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
+    #define PRINT_FPREGISTER(_type, _regName) { \
+        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
         double* d = reinterpret_cast<double*>(&cpu._regName); \
-        dataLogF("%s    %5s: 0x %08x %08x   %12g\n", \
-            indentation, #_regName, u[1], u[0], d[0]); \
+        INDENT, dataLogF("%5s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
     }
-    FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
-    #undef DUMP_FPREGISTER
+    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
+    #undef PRINT_FPREGISTER
 }
 
-void MacroAssemblerARM::ProbeContext::dump(const char* indentation)
-{
-    if (!indentation)
-        indentation = "";
-
-    dataLogF("%sProbeContext %p {\n", indentation, this);
-    dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
-    dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
-    dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
-    dataLogF("%s  cpu: {\n", indentation);
+#undef INDENT
 
-    dumpCPURegisters(indentation);
-
-    dataLogF("%s  }\n", indentation);
-    dataLogF("%s}\n", indentation);
+void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState& cpu, RegisterID regID)
+{
+    const char* name = CPUState::registerName(regID);
+    union {
+        void* voidPtr;
+        intptr_t intptrValue;
+    } u;
+    u.voidPtr = cpu.registerValue(regID);
+    dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue);
 }
 
+void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState& cpu, FPRegisterID regID)
+{
+    const char* name = CPUState::registerName(regID);
+    union {
+        double doubleValue;
+        uint64_t uint64Value;
+    } u;
+    u.doubleValue = cpu.registerValue(regID);
+    dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue);
+}
 
 extern "C" void ctiMasmProbeTrampoline();
 
 // For details on "What code is emitted for the probe?" and "What values are in
-// the saved registers?", see comment for MacroAssemblerX86::probe() in
-// MacroAssemblerX86_64.h.
+// the saved registers?", see comment for MacroAssemblerX86Common::probe() in
+// MacroAssemblerX86Common.cpp.
 
 void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function, void* arg1, void* arg2)
 {
@@ -160,7 +163,7 @@ void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function, void* a
     m_assembler.blx(RegisterID::S0);
 
 }
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 } // namespace JSC
 
index 82c80564850b3f6f80ef7b539d97d4248c5c4360..6cda896a36784b4d70e2da2896b6cac9b0452a68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013 Apple Inc.
+ * Copyright (C) 2008, 2013, 2014 Apple Inc.
  * Copyright (C) 2009, 2010 University of Szeged
  * All rights reserved.
  *
@@ -35,7 +35,7 @@
 
 namespace JSC {
 
-class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
+class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler, MacroAssemblerARM> {
     static const int DoubleConditionMask = 0x0f;
     static const int DoubleConditionBitSpecial = 0x10;
     COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
@@ -370,7 +370,7 @@ public:
         m_assembler.dataTransfer32(ARMAssembler::LoadUint8, dest, ARMRegisters::S0, 0);
     }
 
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt8, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
     }
@@ -385,7 +385,7 @@ public:
         m_assembler.baseIndexTransfer16(ARMAssembler::LoadUint16, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
     }
 
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt16, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
     }
@@ -942,7 +942,7 @@ public:
     void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
     {
         if (mask.m_value == -1)
-            m_assembler.cmp(0, reg);
+            m_assembler.tst(reg, reg);
         else
             m_assembler.tst(reg, m_assembler.getImm(mask.m_value, ARMRegisters::S0));
         m_assembler.mov(dest, ARMAssembler::getOp2Byte(0));
@@ -1432,31 +1432,14 @@ public:
         UNREACHABLE_FOR_PLATFORM();
     }
 
-#if USE(MASM_PROBE)
-    struct CPUState {
-        #define DECLARE_REGISTER(_type, _regName) \
-            _type _regName;
-        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
-        #undef DECLARE_REGISTER
-    };
-
-    struct ProbeContext;
-    typedef void (*ProbeFunction)(struct ProbeContext*);
-
-    struct ProbeContext {
-        ProbeFunction probeFunction;
-        void* arg1;
-        void* arg2;
-        CPUState cpu;
-
-        void dump(const char* indentation = 0);
-    private:
-        void dumpCPURegisters(const char* indentation);
-    };
-
-    // For details about probe(), see comment in MacroAssemblerX86_64.h.
+#if ENABLE(MASM_PROBE)
+    // Methods required by the MASM_PROBE mechanism as defined in
+    // AbstractMacroAssembler.h. 
+    static void printCPURegisters(CPUState&, int indentation = 0);
+    static void printRegister(CPUState&, RegisterID);
+    static void printRegister(CPUState&, FPRegisterID);
     void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 protected:
     ARMAssembler::Condition ARMCondition(RelationalCondition cond)
@@ -1513,7 +1496,7 @@ private:
         ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
     }
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
     inline TrustedImm32 trustedImm32FromPtr(void* ptr)
     {
         return TrustedImm32(TrustedImmPtr(ptr));
index 830b58eeca9931de8fde3c16d2cbc8a7c3eec87b..661fc0ad8fd0e7e761bb268dabfd4a84cc840cc3 100644 (file)
@@ -34,7 +34,7 @@
 
 namespace JSC {
 
-class MacroAssemblerARM64 : public AbstractMacroAssembler<ARM64Assembler> {
+class MacroAssemblerARM64 : public AbstractMacroAssembler<ARM64Assembler, MacroAssemblerARM64> {
     static const RegisterID dataTempRegister = ARM64Registers::ip0;
     static const RegisterID memoryTempRegister = ARM64Registers::ip1;
     static const ARM64Registers::FPRegisterID fpTempRegister = ARM64Registers::q31;
@@ -689,6 +689,26 @@ public:
         urshift32(dest, imm, dest);
     }
 
+    void urshift64(RegisterID src, RegisterID shiftAmount, RegisterID dest)
+    {
+        m_assembler.lsr<64>(dest, src, shiftAmount);
+    }
+    
+    void urshift64(RegisterID src, TrustedImm32 imm, RegisterID dest)
+    {
+        m_assembler.lsr<64>(dest, src, imm.m_value & 0x1f);
+    }
+
+    void urshift64(RegisterID shiftAmount, RegisterID dest)
+    {
+        urshift64(dest, shiftAmount, dest);
+    }
+    
+    void urshift64(TrustedImm32 imm, RegisterID dest)
+    {
+        urshift64(dest, imm, dest);
+    }
+
     void xor32(RegisterID src, RegisterID dest)
     {
         xor32(dest, src, dest);
@@ -898,16 +918,16 @@ public:
         load16(address, dest);
     }
 
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         if (!address.offset && (!address.scale || address.scale == 1)) {
-            m_assembler.ldrsh<64>(dest, address.base, address.index, ARM64Assembler::UXTX, address.scale);
+            m_assembler.ldrsh<32>(dest, address.base, address.index, ARM64Assembler::UXTX, address.scale);
             return;
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
         m_assembler.add<64>(memoryTempRegister, memoryTempRegister, address.index, ARM64Assembler::UXTX, address.scale);
-        m_assembler.ldrsh<64>(dest, address.base, memoryTempRegister);
+        m_assembler.ldrsh<32>(dest, address.base, memoryTempRegister);
     }
 
     void load8(ImplicitAddress address, RegisterID dest)
@@ -939,16 +959,16 @@ public:
             m_cachedMemoryTempRegister.invalidate();
     }
 
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         if (!address.offset && !address.scale) {
-            m_assembler.ldrsb<64>(dest, address.base, address.index, ARM64Assembler::UXTX, address.scale);
+            m_assembler.ldrsb<32>(dest, address.base, address.index, ARM64Assembler::UXTX, address.scale);
             return;
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
         m_assembler.add<64>(memoryTempRegister, memoryTempRegister, address.index, ARM64Assembler::UXTX, address.scale);
-        m_assembler.ldrsb<64>(dest, address.base, memoryTempRegister);
+        m_assembler.ldrsb<32>(dest, address.base, memoryTempRegister);
     }
 
     void store64(RegisterID src, ImplicitAddress address)
@@ -1193,9 +1213,14 @@ public:
         m_assembler.scvtf<64, 32>(fpTempRegister, dest);
         failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister));
 
-        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
-        if (negZeroCheck)
-            failureCases.append(branchTest32(Zero, dest));
+        // Test for negative zero.
+        if (negZeroCheck) {
+            Jump valueIsNonZero = branchTest32(NonZero, dest);
+            RegisterID scratch = getCachedMemoryTempRegisterIDAndInvalidate();
+            m_assembler.fmov<64>(scratch, src);
+            failureCases.append(makeTestBitAndBranch(scratch, 63, IsNonZero));
+            valueIsNonZero.link(this);
+        }
     }
 
     Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
@@ -1651,6 +1676,16 @@ public:
 
     Jump branch64(RelationalCondition cond, RegisterID left, RegisterID right)
     {
+        if (right == ARM64Registers::sp) {
+            if (cond == Equal && left != ARM64Registers::sp) {
+                // CMP can only use SP for the left argument, since we are testing for equality, the order
+                // does not matter here.
+                std::swap(left, right);
+            } else {
+                move(right, getCachedDataTempRegisterIDAndInvalidate());
+                right = dataTempRegister;
+            }
+        }
         m_assembler.cmp<64>(left, right);
         return Jump(makeBranch(cond));
     }
index 3132e318e66ad9c2637f9a4c65d71166dbb78524..6651fff06264df7a696c9d6ab608098adf7073b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
 #include "MacroAssemblerARMv7.h"
 
-#if USE(MASM_PROBE)
-#include <wtf/StdLibExtras.h>
-#endif
-
 namespace JSC {
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
+
+#define INDENT printIndent(indentation)
 
-void MacroAssemblerARMv7::ProbeContext::dumpCPURegisters(const char* indentation)
+void MacroAssemblerARMv7::printCPURegisters(CPUState& cpu, int indentation)
 {
-    #define DUMP_GPREGISTER(_type, _regName) { \
+    #define PRINT_GPREGISTER(_type, _regName) { \
         int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
-        dataLogF("%s    %5s: 0x%08x   %d\n", indentation, #_regName, value, value) ; \
+        INDENT, dataLogF("%5s: 0x%08x  %d\n", #_regName, value, value) ; \
     }
-    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
-    FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER)
-    #undef DUMP_GPREGISTER
+    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
+    FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER)
+    #undef PRINT_GPREGISTER
 
-    #define DUMP_FPREGISTER(_type, _regName) { \
-        uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
+    #define PRINT_FPREGISTER(_type, _regName) { \
+        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
         double* d = reinterpret_cast<double*>(&cpu._regName); \
-        dataLogF("%s    %5s: 0x %08x %08x   %12g\n", \
-            indentation, #_regName, u[1], u[0], d[0]); \
+        INDENT, dataLogF("%5s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
     }
-    FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
-    #undef DUMP_FPREGISTER
+    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
+    #undef PRINT_FPREGISTER
 }
 
-void MacroAssemblerARMv7::ProbeContext::dump(const char* indentation)
-{
-    if (!indentation)
-        indentation = "";
-
-    dataLogF("%sProbeContext %p {\n", indentation, this);
-    dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
-    dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
-    dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
-    dataLogF("%s  cpu: {\n", indentation);
+#undef INDENT
 
-    dumpCPURegisters(indentation);
-
-    dataLogF("%s  }\n", indentation);
-    dataLogF("%s}\n", indentation);
+void MacroAssemblerARMv7::printRegister(MacroAssemblerARMv7::CPUState& cpu, RegisterID regID)
+{
+    const char* name = CPUState::registerName(regID);
+    union {
+        void* voidPtr;
+        intptr_t intptrValue;
+    } u;
+    u.voidPtr = cpu.registerValue(regID);
+    dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue);
 }
 
+void MacroAssemblerARMv7::printRegister(MacroAssemblerARMv7::CPUState& cpu, FPRegisterID regID)
+{
+    const char* name = CPUState::registerName(regID);
+    union {
+        double doubleValue;
+        uint64_t uint64Value;
+    } u;
+    u.doubleValue = cpu.registerValue(regID);
+    dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue);
+}
 
 extern "C" void ctiMasmProbeTrampoline();
 
 // For details on "What code is emitted for the probe?" and "What values are in
-// the saved registers?", see comment for MacroAssemblerX86::probe() in
-// MacroAssemblerX86_64.h.
+// the saved registers?", see comment for MacroAssemblerX86Common::probe() in
+// MacroAssemblerX86Common.cpp.
 
 void MacroAssemblerARMv7::probe(MacroAssemblerARMv7::ProbeFunction function, void* arg1, void* arg2)
 {
@@ -96,7 +99,7 @@ void MacroAssemblerARMv7::probe(MacroAssemblerARMv7::ProbeFunction function, voi
     move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::ip);
     m_assembler.blx(RegisterID::ip);
 }
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 } // namespace JSC
 
index 80d17eb1575c896d9b727d9ff46993f05f8d34c1..2e71e61d856efc254b0c274230d90dd46e5cea03 100644 (file)
@@ -34,7 +34,7 @@
 
 namespace JSC {
 
-class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
+class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler, MacroAssemblerARMv7> {
     static const RegisterID dataTempRegister = ARMRegisters::ip;
     static const RegisterID addressTempRegister = ARMRegisters::r6;
 
@@ -546,7 +546,7 @@ private:
         }
     }
     
-    void load16Signed(ArmAddress address, RegisterID dest)
+    void load16SignedExtendTo32(ArmAddress address, RegisterID dest)
     {
         ASSERT(address.type == ArmAddress::HasIndex);
         m_assembler.ldrsh(dest, address.base, address.u.index, address.u.scale);
@@ -566,7 +566,7 @@ private:
         }
     }
     
-    void load8Signed(ArmAddress address, RegisterID dest)
+    void load8SignedExtendTo32(ArmAddress address, RegisterID dest)
     {
         ASSERT(address.type == ArmAddress::HasIndex);
         m_assembler.ldrsb(dest, address.base, address.u.index, address.u.scale);
@@ -668,7 +668,7 @@ public:
         load8(setupArmAddress(address), dest);
     }
 
-    void load8Signed(ImplicitAddress, RegisterID)
+    void load8SignedExtendTo32(ImplicitAddress, RegisterID)
     {
         UNREACHABLE_FOR_PLATFORM();
     }
@@ -678,9 +678,9 @@ public:
         load8(setupArmAddress(address), dest);
     }
     
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
-        load8Signed(setupArmAddress(address), dest);
+        load8SignedExtendTo32(setupArmAddress(address), dest);
     }
 
     void load8(const void* address, RegisterID dest)
@@ -714,9 +714,9 @@ public:
         m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
     }
     
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
-        load16Signed(setupArmAddress(address), dest);
+        load16SignedExtendTo32(setupArmAddress(address), dest);
     }
     
     void load16(ImplicitAddress address, RegisterID dest)
@@ -730,7 +730,7 @@ public:
         }
     }
     
-    void load16Signed(ImplicitAddress, RegisterID)
+    void load16SignedExtendTo32(ImplicitAddress, RegisterID)
     {
         UNREACHABLE_FOR_PLATFORM();
     }
@@ -1901,31 +1901,14 @@ public:
         UNREACHABLE_FOR_PLATFORM();
     }
 
-#if USE(MASM_PROBE)
-    struct CPUState {
-        #define DECLARE_REGISTER(_type, _regName) \
-            _type _regName;
-        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
-        #undef DECLARE_REGISTER
-    };
-
-    struct ProbeContext;
-    typedef void (*ProbeFunction)(struct ProbeContext*);
-
-    struct ProbeContext {
-        ProbeFunction probeFunction;
-        void* arg1;
-        void* arg2;
-        CPUState cpu;
-
-        void dump(const char* indentation = 0);
-    private:
-        void dumpCPURegisters(const char* indentation);
-    };
-
-    // For details about probe(), see comment in MacroAssemblerX86_64.h.
+#if ENABLE(MASM_PROBE)
+    // Methods required by the MASM_PROBE mechanism as defined in
+    // AbstractMacroAssembler.h. 
+    static void printCPURegisters(CPUState&, int indentation = 0);
+    static void printRegister(CPUState&, RegisterID);
+    static void printRegister(CPUState&, FPRegisterID);
     void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 protected:
     ALWAYS_INLINE Jump jump()
@@ -2037,7 +2020,7 @@ private:
         ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
     }
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
     inline TrustedImm32 trustedImm32FromPtr(void* ptr)
     {
         return TrustedImm32(TrustedImmPtr(ptr));
index 57951262d9a25d26c8f24c1f0e2dace25b36b657..b4d6c0bfb447308a8ea42d40be026576ceb04a2a 100644 (file)
@@ -132,6 +132,12 @@ public:
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
+    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5, typename argType6>
+    FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5, argType6))
+        : m_value((void*)value)
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
 // MSVC doesn't seem to treat functions with different calling conventions as
 // different types; these methods already defined for fastcall, below.
 #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS)
@@ -312,11 +318,7 @@ public:
     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
 #endif
 
-    typedef void* (MacroAssemblerCodePtr::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const
-    {
-        return !!m_value ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
-    }
+    explicit operator bool() const { return m_value; }
     
     bool operator==(const MacroAssemblerCodePtr& other) const
     {
@@ -436,11 +438,7 @@ public:
         return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile());
     }
     
-    typedef void* (MacroAssemblerCodeRef::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const
-    {
-        return !!m_codePtr ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
-    }
+    explicit operator bool() const { return !!m_codePtr; }
     
     void dump(PrintStream& out) const
     {
index 71b5fa9dff079eee39ceba8cd340e1e1c7f4a790..1a931282950ab1c7b1acdac5897b33a1fe9fe891 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 
 namespace JSC {
 
-class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> {
+class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler, MacroAssemblerMIPS> {
 public:
     typedef MIPSRegisters::FPRegisterID FPRegisterID;
 
@@ -707,7 +707,7 @@ public:
         m_assembler.lbu(dest, addrTempRegister, 0);
     }
 
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         if (address.offset >= -32768 && address.offset <= 32767
             && !m_fixedWidth) {
@@ -919,7 +919,7 @@ public:
         }
     }
 
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         if (address.offset >= -32768 && address.offset <= 32767
             && !m_fixedWidth) {
@@ -2120,6 +2120,16 @@ public:
         return temp;
     }
 
+    Jump branch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0))
+    {
+        m_fixedWidth = true;
+        load32(left, dataTempRegister);
+        dataLabel = moveWithPatch(initialRightValue, immTempRegister);
+        Jump temp = branch32(cond, dataTempRegister, immTempRegister);
+        m_fixedWidth = false;
+        return temp;
+    }
+
     DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
     {
         m_fixedWidth = true;
index 0e9c4db0bc13bf21f30d751479030d65d7c010f0..6857c60a424dea2fb328c9de69ba070564685f19 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
  * Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,7 +36,7 @@
 
 namespace JSC {
 
-class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler> {
+class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler, MacroAssemblerSH4> {
 public:
     typedef SH4Assembler::FPRegisterID FPRegisterID;
 
@@ -718,13 +718,13 @@ public:
         m_assembler.extub(dest, dest);
     }
 
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         RegisterID scr = claimScratch();
         move(address.index, scr);
         lshift32(TrustedImm32(address.scale), scr);
         add32(address.base, scr);
-        load8Signed(scr, address.offset, dest);
+        load8SignedExtendTo32(scr, address.offset, dest);
         releaseScratch(scr);
     }
 
@@ -770,7 +770,7 @@ public:
             releaseScratch(scr);
     }
 
-    void load8Signed(RegisterID base, int offset, RegisterID dest)
+    void load8SignedExtendTo32(RegisterID base, int offset, RegisterID dest)
     {
         if (!offset) {
             m_assembler.movbMemReg(base, dest);
@@ -798,7 +798,7 @@ public:
 
     void load8(RegisterID base, int offset, RegisterID dest)
     {
-        load8Signed(base, offset, dest);
+        load8SignedExtendTo32(base, offset, dest);
         m_assembler.extub(dest, dest);
     }
 
@@ -858,14 +858,14 @@ public:
         m_assembler.extuw(dest, dest);
     }
 
-    void load16Signed(RegisterID src, RegisterID dest)
+    void load16SignedExtendTo32(RegisterID src, RegisterID dest)
     {
         m_assembler.movwMemReg(src, dest);
     }
 
     void load16(BaseIndex address, RegisterID dest)
     {
-        load16Signed(address, dest);
+        load16SignedExtendTo32(address, dest);
         m_assembler.extuw(dest, dest);
     }
 
@@ -875,7 +875,7 @@ public:
         m_assembler.extuw(dest, dest);
     }
 
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         RegisterID scr = claimScratch();
 
@@ -887,7 +887,7 @@ public:
             m_assembler.movwR0mr(scr, dest);
         else {
             add32(address.base, scr);
-            load16Signed(scr, dest);
+            load16SignedExtendTo32(scr, dest);
         }
 
         releaseScratch(scr);
@@ -931,6 +931,19 @@ public:
         releaseScratch(srcval);
     }
 
+    void store8(TrustedImm32 imm, Address address)
+    {
+        ASSERT((imm.m_value >= -128) && (imm.m_value <= 127));
+        RegisterID dstptr = claimScratch();
+        move(address.base, dstptr);
+        add32(TrustedImm32(address.offset), dstptr);
+        RegisterID srcval = claimScratch();
+        move(imm, srcval);
+        m_assembler.movbRegMem(srcval, dstptr);
+        releaseScratch(dstptr);
+        releaseScratch(srcval);
+    }
+
     void store16(RegisterID src, BaseIndex address)
     {
         RegisterID scr = claimScratch();
@@ -1733,6 +1746,14 @@ public:
         return dataLabel;
     }
 
+    DataLabel32 moveWithPatch(TrustedImm32 initialValue, RegisterID dest)
+    {
+        m_assembler.ensureSpace(m_assembler.maxInstructionSize, sizeof(uint32_t));
+        DataLabel32 dataLabel(this);
+        m_assembler.loadConstantUnReusable(static_cast<uint32_t>(initialValue.m_value), dest);
+        return dataLabel;
+    }
+
     void move(RegisterID src, RegisterID dest)
     {
         if (src != dest)
@@ -2140,6 +2161,29 @@ public:
         return result ? branchTrue() : branchFalse();
     }
 
+    Jump branchAdd32(ResultCondition cond, Address src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
+
+        if (cond == Overflow) {
+            RegisterID srcVal = claimScratch();
+            load32(src, srcVal);
+            m_assembler.addvlRegReg(srcVal, dest);
+            releaseScratch(srcVal);
+            return branchTrue();
+        }
+
+        add32(src, dest);
+
+        if ((cond == Signed) || (cond == PositiveOrZero)) {
+            m_assembler.cmppz(dest);
+            return (cond == Signed) ? branchFalse() : branchTrue();
+        }
+
+        compare32(0, dest, Equal);
+        return (cond == NonZero) ? branchFalse() : branchTrue();
+    }
+
     Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -2419,6 +2463,23 @@ public:
         return branchTrue();
     }
 
+    Jump branch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0))
+    {
+        RegisterID scr = claimScratch();
+
+        m_assembler.loadConstant(left.offset, scr);
+        m_assembler.addlRegReg(left.base, scr);
+        m_assembler.movlMemReg(scr, scr);
+        RegisterID scr1 = claimScratch();
+        m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t));
+        dataLabel = moveWithPatch(initialRightValue, scr1);
+        m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
+        releaseScratch(scr);
+        releaseScratch(scr1);
+
+        return (cond == NotEqual) ? branchFalse() : branchTrue();
+    }
+
     void ret()
     {
         m_assembler.ret();
@@ -2468,6 +2529,18 @@ public:
         m_assembler.synco();
     }
 
+    void abortWithReason(AbortReason reason)
+    {
+        move(TrustedImm32(reason), SH4Registers::r0);
+        breakpoint();
+    }
+
+    void abortWithReason(AbortReason reason, intptr_t misc)
+    {
+        move(TrustedImm32(misc), SH4Registers::r1);
+        abortWithReason(reason);
+    }
+
     static FunctionPtr readCallTarget(CodeLocationCall call)
     {
         return FunctionPtr(reinterpret_cast<void(*)()>(SH4Assembler::readCallTarget(call.dataLocation())));
@@ -2485,6 +2558,8 @@ public:
 
     static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
 
+    static bool canJumpReplacePatchableBranch32WithPatch() { return false; }
+
     static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label)
     {
         return label.labelAtOffset(0);
@@ -2501,11 +2576,22 @@ public:
         return CodeLocationLabel();
     }
 
+    static CodeLocationLabel startOfPatchableBranch32WithPatchOnAddress(CodeLocationDataLabel32)
+    {
+        UNREACHABLE_FOR_PLATFORM();
+        return CodeLocationLabel();
+    }
+
     static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*)
     {
         UNREACHABLE_FOR_PLATFORM();
     }
 
+    static void revertJumpReplacementToPatchableBranch32WithPatch(CodeLocationLabel, Address, int32_t)
+    {
+        UNREACHABLE_FOR_PLATFORM();
+    }
+
 protected:
     SH4Assembler::Condition SH4Condition(RelationalCondition cond)
     {
index 56416856f2c4b480c6ecc048696bc7d5111f9516..bdd9e57ba91f4f78e914e63637d9edc394e57aef 100644 (file)
 
 #include "MacroAssemblerX86Common.h"
 
-#if USE(MASM_PROBE)
-#include <wtf/StdLibExtras.h>
-#endif
-
 namespace JSC {
 
 class MacroAssemblerX86 : public MacroAssemblerX86Common {
@@ -168,14 +164,14 @@ public:
         m_assembler.movb_i8m(imm.m_value, address);
     }
     
-    // Possibly clobbers src.
-    // FIXME: Don't do that.
-    // https://bugs.webkit.org/show_bug.cgi?id=131690
     void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
     {
+        ASSERT(isSSE2Present());
+        m_assembler.pextrw_irr(3, src, dest1);
+        m_assembler.pextrw_irr(2, src, dest2);
+        lshift32(TrustedImm32(16), dest1);
+        or32(dest1, dest2);
         movePackedToInt32(src, dest1);
-        rshiftPacked(TrustedImm32(32), src);
-        movePackedToInt32(src, dest2);
     }
 
     void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch)
@@ -287,7 +283,6 @@ public:
     }
 
     static bool supportsFloatingPoint() { return isSSE2Present(); }
-    // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     static bool supportsFloatingPointTruncate() { return isSSE2Present(); }
     static bool supportsFloatingPointSqrt() { return isSSE2Present(); }
     static bool supportsFloatingPointAbs() { return isSSE2Present(); }
@@ -350,11 +345,6 @@ public:
         X86Assembler::revertJumpTo_cmpl_im_force32(instructionStart.executableAddress(), initialValue, 0, address.base);
     }
 
-#if USE(MASM_PROBE)
-    // For details about probe(), see comment in MacroAssemblerX86_64.h.
-    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
-#endif // USE(MASM_PROBE)
-
 private:
     friend class LinkBuffer;
     friend class RepatchBuffer;
@@ -373,46 +363,8 @@ private:
     {
         X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
     }
-
-#if USE(MASM_PROBE)
-    inline TrustedImm32 trustedImm32FromPtr(void* ptr)
-    {
-        return TrustedImm32(TrustedImmPtr(ptr));
-    }
-
-    inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function)
-    {
-        return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
-    }
-
-    inline TrustedImm32 trustedImm32FromPtr(void (*function)())
-    {
-        return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
-    }
-#endif
 };
 
-#if USE(MASM_PROBE)
-
-extern "C" void ctiMasmProbeTrampoline();
-
-// For details on "What code is emitted for the probe?" and "What values are in
-// the saved registers?", see comment for MacroAssemblerX86::probe() in
-// MacroAssemblerX86_64.h.
-
-inline void MacroAssemblerX86::probe(MacroAssemblerX86::ProbeFunction function, void* arg1, void* arg2)
-{
-    push(RegisterID::esp);
-    push(RegisterID::eax);
-    push(trustedImm32FromPtr(arg2));
-    push(trustedImm32FromPtr(arg1));
-    push(trustedImm32FromPtr(function));
-
-    move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
-    call(RegisterID::eax);
-}
-#endif // USE(MASM_PROBE)
-
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
index 0fab05fb5d946f76a43a855cdb1542f7ac5c6f7c..0108ef4c0f0cd29baa9e7e35790266c1de48d828 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 
-void MacroAssemblerX86Common::ProbeContext::dumpCPURegisters(const char* indentation)
+#define INDENT printIndent(indentation)
+
+void MacroAssemblerX86Common::printCPURegisters(MacroAssemblerX86Common::CPUState& cpu, int indentation)
 {
 #if CPU(X86)
-    #define DUMP_GPREGISTER(_type, _regName) { \
+    #define PRINT_GPREGISTER(_type, _regName) { \
         int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
-        dataLogF("%s    %6s: 0x%08x   %d\n", indentation, #_regName, value, value) ; \
+        INDENT, dataLogF("%6s: 0x%08x  %d\n", #_regName, value, value) ; \
     }
 #elif CPU(X86_64)
-    #define DUMP_GPREGISTER(_type, _regName) { \
+    #define PRINT_GPREGISTER(_type, _regName) { \
         int64_t value = reinterpret_cast<int64_t>(cpu._regName); \
-        dataLogF("%s    %6s: 0x%016llx   %lld\n", indentation, #_regName, value, value) ; \
+        INDENT, dataLogF("%6s: 0x%016llx  %lld\n", #_regName, value, value) ; \
     }
 #endif
-    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
-    FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER)
-    #undef DUMP_GPREGISTER
+    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
+    FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER)
+    #undef PRINT_GPREGISTER
 
-    #define DUMP_FPREGISTER(_type, _regName) { \
-        uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
+    #define PRINT_FPREGISTER(_type, _regName) { \
+        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
         double* d = reinterpret_cast<double*>(&cpu._regName); \
-        dataLogF("%s    %6s: 0x%08x%08x 0x%08x%08x   %12g %12g\n", \
-            indentation, #_regName, u[3], u[2], u[1], u[0], d[1], d[0]); \
+        INDENT, dataLogF("%6s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
     }
-    FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
-    #undef DUMP_FPREGISTER
+    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
+    #undef PRINT_FPREGISTER
 }
 
-void MacroAssemblerX86Common::ProbeContext::dump(const char* indentation)
+#undef INDENT
+
+void MacroAssemblerX86Common::printRegister(MacroAssemblerX86Common::CPUState& cpu, RegisterID regID)
 {
-    if (!indentation)
-        indentation = "";
+    const char* name = CPUState::registerName(regID);
+    union {
+        void* voidPtr;
+        intptr_t intptrValue;
+    } u;
+    u.voidPtr = cpu.registerValue(regID);
+    dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue);
+}
 
-    dataLogF("%sProbeContext %p {\n", indentation, this);
-    dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
-    dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
-    dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
-    dataLogF("%s  cpu: {\n", indentation);
+void MacroAssemblerX86Common::printRegister(MacroAssemblerX86Common::CPUState& cpu, FPRegisterID regID)
+{
+    const char* name = CPUState::registerName(regID);
+    union {
+        double doubleValue;
+        uint64_t uint64Value;
+    } u;
+    u.doubleValue = cpu.registerValue(regID);
+    dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue);
+}
 
-    dumpCPURegisters(indentation);
+extern "C" void ctiMasmProbeTrampoline();
 
-    dataLogF("%s  }\n", indentation);
-    dataLogF("%s}\n", indentation);
+// What code is emitted for the probe?
+// ==================================
+// We want to keep the size of the emitted probe invocation code as compact as
+// possible to minimize the perturbation to the JIT generated code. However,
+// we also need to preserve the CPU registers and set up the ProbeContext to be
+// passed to the user probe function.
+//
+// Hence, we do only the minimum here to preserve a scratch register (i.e. rax
+// in this case) and the stack pointer (i.e. rsp), and pass the probe arguments.
+// We'll let the ctiMasmProbeTrampoline handle the rest of the probe invocation
+// work i.e. saving the CPUState (and setting up the ProbeContext), calling the
+// user probe function, and restoring the CPUState before returning to JIT
+// generated code.
+//
+// What registers need to be saved?
+// ===============================
+// The registers are saved for 2 reasons:
+// 1. To preserve their state in the JITted code. This means that all registers
+//    that are not callee saved needs to be saved. We also need to save the
+//    condition code registers because the probe can be inserted between a test
+//    and a branch.
+// 2. To allow the probe to inspect the values of the registers for debugging
+//    purposes. This means all registers need to be saved.
+//
+// In summary, save everything. But for reasons stated above, we should do the
+// minimum here and let ctiMasmProbeTrampoline do the heavy lifting to save the
+// full set.
+//
+// What values are in the saved registers?
+// ======================================
+// Conceptually, the saved registers should contain values as if the probe
+// is not present in the JIT generated code. Hence, they should contain values
+// that are expected at the start of the instruction immediately following the
+// probe.
+//
+// Specifically, the saved stack pointer register will point to the stack
+// position before we push the ProbeContext frame. The saved rip will point to
+// the address of the instruction immediately following the probe. 
+
+void MacroAssemblerX86Common::probe(MacroAssemblerX86Common::ProbeFunction function, void* arg1, void* arg2)
+{
+    push(RegisterID::esp);
+    push(RegisterID::eax);
+    move(TrustedImmPtr(arg2), RegisterID::eax);
+    push(RegisterID::eax);
+    move(TrustedImmPtr(arg1), RegisterID::eax);
+    push(RegisterID::eax);
+    move(TrustedImmPtr(reinterpret_cast<void*>(function)), RegisterID::eax);
+    push(RegisterID::eax);
+    move(TrustedImmPtr(reinterpret_cast<void*>(ctiMasmProbeTrampoline)), RegisterID::eax);
+    call(RegisterID::eax);
 }
 
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
+
+#if CPU(X86) && !OS(MAC_OS_X)
+MacroAssemblerX86Common::SSE2CheckState MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2;
+#endif
 
 } // namespace JSC
 
index 2466ac34873677ef5b8276929194e437e1f1efa3..b3b50748a96c98b3c4e862e709466c5aa055d524 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,7 +33,7 @@
 
 namespace JSC {
 
-class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler, MacroAssemblerX86Common> {
 public:
 #if CPU(X86_64)
     static const X86Registers::RegisterID scratchRegister = X86Registers::r11;
@@ -183,6 +183,18 @@ public:
         and32(imm, dest);
     }
 
+    void countLeadingZeros32(RegisterID src, RegisterID dst)
+    {
+        m_assembler.bsr_rr(src, dst);
+        Jump srcIsNonZero = m_assembler.jCC(x86Condition(NonZero));
+        move(TrustedImm32(32), dst);
+
+        Jump skipNonZeroCase = jump();
+        srcIsNonZero.link(this);
+        xor32(TrustedImm32(0x1f), dst);
+        skipNonZeroCase.link(this);
+    }
+
     void lshift32(RegisterID shift_amount, RegisterID dest)
     {
         ASSERT(shift_amount != dest);
@@ -525,12 +537,12 @@ public:
         m_assembler.movzbl_mr(address.offset, address.base, dest);
     }
     
-    void load8Signed(BaseIndex address, RegisterID dest)
+    void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         m_assembler.movsbl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
 
-    void load8Signed(ImplicitAddress address, RegisterID dest)
+    void load8SignedExtendTo32(ImplicitAddress address, RegisterID dest)
     {
         m_assembler.movsbl_mr(address.offset, address.base, dest);
     }
@@ -545,12 +557,12 @@ public:
         m_assembler.movzwl_mr(address.offset, address.base, dest);
     }
 
-    void load16Signed(BaseIndex address, RegisterID dest)
+    void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         m_assembler.movswl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
     
-    void load16Signed(Address address, RegisterID dest)
+    void load16SignedExtendTo32(Address address, RegisterID dest)
     {
         m_assembler.movswl_mr(address.offset, address.base, dest);
     }
@@ -909,8 +921,17 @@ public:
         m_assembler.cvttsd2si_rr(src, dest);
 
         // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
+#if CPU(X86_64)
+        if (negZeroCheck) {
+            Jump valueIsNonZero = branchTest32(NonZero, dest);
+            m_assembler.movmskpd_rr(src, scratchRegister);
+            failureCases.append(branchTest32(NonZero, scratchRegister, TrustedImm32(1)));
+            valueIsNonZero.link(this);
+        }
+#else
         if (negZeroCheck)
             failureCases.append(branchTest32(Zero, dest));
+#endif
 
         // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
         convertInt32ToDouble(dest, fpTemp);
@@ -1469,28 +1490,14 @@ public:
         return X86Assembler::maxJumpReplacementSize();
     }
 
-#if USE(MASM_PROBE)
-    struct CPUState {
-        #define DECLARE_REGISTER(_type, _regName) \
-            _type _regName;
-        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
-        #undef DECLARE_REGISTER
-    };
-
-    struct ProbeContext;
-    typedef void (*ProbeFunction)(struct ProbeContext*);
-
-    struct ProbeContext {
-        ProbeFunction probeFunction;
-        void* arg1;
-        void* arg2;
-        CPUState cpu;
-
-        void dump(const char* indentation = 0);
-    private:
-        void dumpCPURegisters(const char* indentation);
-    };
-#endif // USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
+    // Methods required by the MASM_PROBE mechanism as defined in
+    // AbstractMacroAssembler.h. 
+    static void printCPURegisters(CPUState&, int indentation = 0);
+    static void printRegister(CPUState&, RegisterID);
+    static void printRegister(CPUState&, FPRegisterID);
+    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
+#endif // ENABLE(MASM_PROBE)
 
 protected:
     X86Assembler::Condition x86Condition(RelationalCondition cond)
index 5f92261a9b7ffc07c8253ec36a5365e19db9979b..920de74cbca7e19c0e9a766b4235b2af6583d7d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "MacroAssemblerX86Common.h"
 
-#if USE(MASM_PROBE)
-#include <wtf/StdLibExtras.h>
-#endif
-
 #define REPTACH_OFFSET_CALL_R11 3
 
 inline bool CAN_SIGN_EXTEND_32_64(int64_t value) { return value == (int64_t)(int32_t)value; }
@@ -203,11 +199,11 @@ public:
 
         // Copy argument 5
         load64(Address(X86Registers::esp, 4 * sizeof(int64_t)), scratchRegister);
-        store64(scratchRegister, Address(X86Registers::esp, -4 * sizeof(int64_t)));
+        store64(scratchRegister, Address(X86Registers::esp, -4 * static_cast<int32_t>(sizeof(int64_t))));
 
         // Copy argument 6
         load64(Address(X86Registers::esp, 5 * sizeof(int64_t)), scratchRegister);
-        store64(scratchRegister, Address(X86Registers::esp, -3 * sizeof(int64_t)));
+        store64(scratchRegister, Address(X86Registers::esp, -3 * static_cast<int32_t>(sizeof(int64_t))));
 
         // We also need to allocate the shadow space on the stack for the 4 parameter registers.
         // Also, we should allocate 16 bytes for the frame pointer, and return address (not populated).
@@ -295,7 +291,10 @@ public:
 
     void add64(TrustedImm32 imm, Address address)
     {
-        m_assembler.addq_im(imm.m_value, address.offset, address.base);
+        if (imm.m_value == 1)
+            m_assembler.incq_m(address.offset, address.base);
+        else
+            m_assembler.addq_im(imm.m_value, address.offset, address.base);
     }
 
     void add64(TrustedImm32 imm, AbsoluteAddress address)
@@ -335,6 +334,11 @@ public:
         m_assembler.sarq_i8r(imm.m_value, dest);
     }
     
+    void urshift64(TrustedImm32 imm, RegisterID dest)
+    {
+        m_assembler.shrq_i8r(imm.m_value, dest);
+    }
+    
     void mul64(RegisterID src, RegisterID dest)
     {
         m_assembler.imulq_rr(src, dest);
@@ -780,7 +784,6 @@ public:
     }
 
     static bool supportsFloatingPoint() { return true; }
-    // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     static bool supportsFloatingPointTruncate() { return true; }
     static bool supportsFloatingPointSqrt() { return true; }
     static bool supportsFloatingPointAbs() { return true; }
@@ -841,26 +844,6 @@ public:
         X86Assembler::revertJumpTo_movq_i64r(instructionStart.executableAddress(), reinterpret_cast<intptr_t>(initialValue), scratchRegister);
     }
 
-#if USE(MASM_PROBE)
-    // This function emits code to preserve the CPUState (e.g. registers),
-    // call a user supplied probe function, and restore the CPUState before
-    // continuing with other JIT generated code.
-    //
-    // The user supplied probe function will be called with a single pointer to
-    // a ProbeContext struct (defined above) which contains, among other things,
-    // the preserved CPUState. This allows the user probe function to inspect
-    // the CPUState at that point in the JIT generated code.
-    //
-    // If the user probe function alters the register values in the ProbeContext,
-    // the altered values will be loaded into the CPU registers when the probe
-    // returns.
-    //
-    // The ProbeContext is stack allocated and is only valid for the duration
-    // of the call to the user probe function.
-
-    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
-#endif // USE(MASM_PROBE)
-
 private:
     friend class LinkBuffer;
     friend class RepatchBuffer;
@@ -882,69 +865,8 @@ private:
     {
         X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
     }
-
-#if USE(MASM_PROBE)
-    inline TrustedImm64 trustedImm64FromPtr(void* ptr)
-    {
-        return TrustedImm64(TrustedImmPtr(ptr));
-    }
-
-    inline TrustedImm64 trustedImm64FromPtr(ProbeFunction function)
-    {
-        return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
-    }
-
-    inline TrustedImm64 trustedImm64FromPtr(void (*function)())
-    {
-        return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
-    }
-#endif
 };
 
-#if USE(MASM_PROBE)
-
-extern "C" void ctiMasmProbeTrampoline();
-
-// What code is emitted for the probe?
-// ==================================
-// We want to keep the size of the emitted probe invocation code as compact as
-// possible to minimize the perturbation to the JIT generated code. However,
-// we also need to preserve the CPU registers and set up the ProbeContext to be
-// passed to the user probe function.
-//
-// Hence, we do only the minimum here to preserve a scratch register (i.e. rax
-// in this case) and the stack pointer (i.e. rsp), and pass the probe arguments.
-// We'll let the ctiMasmProbeTrampoline handle the rest of the probe invocation
-// work i.e. saving the CPUState (and setting up the ProbeContext), calling the
-// user probe function, and restoring the CPUState before returning to JIT
-// generated code.
-//
-// What values are in the saved registers?
-// ======================================
-// Conceptually, the saved registers should contain values as if the probe
-// is not present in the JIT generated code. Hence, they should contain values
-// that are expected at the start of the instruction immediately following the
-// probe.
-//
-// Specifcally, the saved stack pointer register will point to the stack
-// position before we push the ProbeContext frame. The saved rip will point to
-// the address of the instruction immediately following the probe. 
-
-inline void MacroAssemblerX86_64::probe(MacroAssemblerX86_64::ProbeFunction function, void* arg1, void* arg2)
-{
-    push(RegisterID::esp);
-    push(RegisterID::eax);
-    move(trustedImm64FromPtr(arg2), RegisterID::eax);
-    push(RegisterID::eax);
-    move(trustedImm64FromPtr(arg1), RegisterID::eax);
-    push(RegisterID::eax);
-    move(trustedImm64FromPtr(function), RegisterID::eax);
-    push(RegisterID::eax);
-    move(trustedImm64FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
-    call(RegisterID::eax);
-}
-#endif // USE(MASM_PROBE)
-
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
index 4a01c72e8ed755b28b68dd72d6af7c2cf07ea890..da3181e5854ded2b632377883fbc4d8af06b1328 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <wtf/Assertions.h>
 #include <wtf/Vector.h>
 
-#if USE(MASM_PROBE)
-#include <xmmintrin.h>
-#endif
-
 namespace JSC {
 
 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
 
 namespace X86Registers {
-    typedef enum {
-        eax,
-        ecx,
-        edx,
-        ebx,
-        esp,
-        ebp,
-        esi,
-        edi,
 
-#if CPU(X86_64)
-        r8,
-        r9,
-        r10,
-        r11,
-        r12,
-        r13,
-        r14,
-        r15,
-#endif
-    } RegisterID;
+#define FOR_EACH_CPU_REGISTER(V) \
+    FOR_EACH_CPU_GPREGISTER(V) \
+    FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+    FOR_EACH_CPU_FPREGISTER(V)
+
+// The following are defined as pairs of the following value:
+// 1. type of the storage needed to save the register value by the JIT probe.
+// 2. name of the register.
+#define FOR_EACH_CPU_GPREGISTER(V) \
+    V(void*, eax) \
+    V(void*, ecx) \
+    V(void*, edx) \
+    V(void*, ebx) \
+    V(void*, esp) \
+    V(void*, ebp) \
+    V(void*, esi) \
+    V(void*, edi) \
+    FOR_EACH_X86_64_CPU_GPREGISTER(V)
+
+#define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+    V(void*, eip) \
+    V(void*, eflags) \
+
+// Note: the JITs only stores double values in the FP registers.
+#define FOR_EACH_CPU_FPREGISTER(V) \
+    V(double, xmm0) \
+    V(double, xmm1) \
+    V(double, xmm2) \
+    V(double, xmm3) \
+    V(double, xmm4) \
+    V(double, xmm5) \
+    V(double, xmm6) \
+    V(double, xmm7) \
+    FOR_EACH_X86_64_CPU_FPREGISTER(V)
 
-    typedef enum {
-        xmm0,
-        xmm1,
-        xmm2,
-        xmm3,
-        xmm4,
-        xmm5,
-        xmm6,
-        xmm7,
+#if CPU(X86)
 
-#if CPU(X86_64)
-        xmm8,
-        xmm9,
-        xmm10,
-        xmm11,
-        xmm12,
-        xmm13,
-        xmm14,
-        xmm15,
-#endif
-    } XMMRegisterID;
-
-#if USE(MASM_PROBE)
-    #define FOR_EACH_CPU_REGISTER(V) \
-        FOR_EACH_CPU_GPREGISTER(V) \
-        FOR_EACH_CPU_SPECIAL_REGISTER(V) \
-        FOR_EACH_CPU_FPREGISTER(V)
-
-    #define FOR_EACH_CPU_GPREGISTER(V) \
-        V(void*, eax) \
-        V(void*, ebx) \
-        V(void*, ecx) \
-        V(void*, edx) \
-        V(void*, esi) \
-        V(void*, edi) \
-        V(void*, ebp) \
-        V(void*, esp) \
-        FOR_EACH_X86_64_CPU_GPREGISTER(V)
-
-    #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
-        V(void*, eip) \
-        V(void*, eflags) \
-
-    #define FOR_EACH_CPU_FPREGISTER(V) \
-        V(__m128, xmm0) \
-        V(__m128, xmm1) \
-        V(__m128, xmm2) \
-        V(__m128, xmm3) \
-        V(__m128, xmm4) \
-        V(__m128, xmm5) \
-        V(__m128, xmm6) \
-        V(__m128, xmm7)
+#define FOR_EACH_X86_64_CPU_GPREGISTER(V) // Nothing to add.
+#define FOR_EACH_X86_64_CPU_FPREGISTER(V) // Nothing to add.
 
-#if CPU(X86)
-    #define FOR_EACH_X86_64_CPU_GPREGISTER(V) // Nothing to add.
 #elif CPU(X86_64)
-    #define FOR_EACH_X86_64_CPU_GPREGISTER(V) \
-        V(void*, r8) \
-        V(void*, r9) \
-        V(void*, r10) \
-        V(void*, r11) \
-        V(void*, r12) \
-        V(void*, r13) \
-        V(void*, r14) \
-        V(void*, r15)
+
+#define FOR_EACH_X86_64_CPU_GPREGISTER(V) \
+    V(void*, r8) \
+    V(void*, r9) \
+    V(void*, r10) \
+    V(void*, r11) \
+    V(void*, r12) \
+    V(void*, r13) \
+    V(void*, r14) \
+    V(void*, r15)
+
+#define FOR_EACH_X86_64_CPU_FPREGISTER(V) \
+    V(double, xmm8) \
+    V(double, xmm9) \
+    V(double, xmm10) \
+    V(double, xmm11) \
+    V(double, xmm12) \
+    V(double, xmm13) \
+    V(double, xmm14) \
+    V(double, xmm15)
+
 #endif // CPU(X86_64)
-#endif // USE(MASM_PROBE)
-}
+
+typedef enum {
+    #define DECLARE_REGISTER(_type, _regName) _regName,
+    FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
+    #undef DECLARE_REGISTER
+} RegisterID;
+
+typedef enum {
+    #define DECLARE_REGISTER(_type, _regName) _regName,
+    FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
+    #undef DECLARE_REGISTER
+} XMMRegisterID;
+
+} // namespace X86Register
 
 class X86Assembler {
 public:
@@ -269,6 +253,7 @@ private:
         OP2_CVTSS2SD_VsdWsd = 0x5A,
         OP2_SUBSD_VsdWsd    = 0x5C,
         OP2_DIVSD_VsdWsd    = 0x5E,
+        OP2_MOVMSKPD_VdEd   = 0x50,
         OP2_SQRTSD_VsdWsd   = 0x51,
         OP2_ANDNPD_VpdWpd   = 0x55,
         OP2_XORPD_VpdWpd    = 0x57,
@@ -279,6 +264,7 @@ private:
         OP2_3BYTE_ESCAPE    = 0xAE,
         OP2_IMUL_GvEv       = 0xAF,
         OP2_MOVZX_GvEb      = 0xB6,
+        OP2_BSR             = 0xBD,
         OP2_MOVSX_GvEb      = 0xBE,
         OP2_MOVZX_GvEw      = 0xB7,
         OP2_MOVSX_GvEw      = 0xBF,
@@ -576,6 +562,11 @@ public:
     {
         m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
     }
+
+    void incq_m(int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, base, offset);
+    }
 #endif // CPU(X86_64)
 
     void negl_r(RegisterID dst)
@@ -831,6 +822,11 @@ public:
 
 #endif
 
+    void bsr_rr(RegisterID src, RegisterID dst)
+    {
+        m_formatter.twoByteOp(OP2_BSR, dst, src);
+    }
+
     void sarl_i8r(int imm, RegisterID dst)
     {
         if (imm == 1)
@@ -892,6 +888,16 @@ public:
         }
     }
 
+    void shrq_i8r(int imm, RegisterID dst)
+    {
+        if (imm == 1)
+            m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
+        else {
+            m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
+            m_formatter.immediate8(imm);
+        }
+    }
+
     void shlq_i8r(int imm, RegisterID dst)
     {
         if (imm == 1)
@@ -1800,6 +1806,12 @@ public:
     }
 
 #if CPU(X86_64)
+    void movmskpd_rr(XMMRegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_66);
+        m_formatter.twoByteOp64(OP2_MOVMSKPD_VdEd, dst, (RegisterID)src);
+    }
+
     void movq_rr(XMMRegisterID src, RegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_66);
index 2df7876410e78cf9fabf241786e60242fe4eee09..f7254d9a89b16a596fab30fac41b2ba2d9e5d91e 100644 (file)
@@ -121,7 +121,7 @@ Deprecated::ScriptValue ScriptFunctionCall::call(bool& hadException)
 
     JSLockHolder lock(m_exec);
 
-    JSValue function = thisObject->get(m_exec, Identifier(m_exec, m_name));
+    JSValue function = thisObject->get(m_exec, Identifier::fromString(m_exec, m_name));
     if (m_exec->hadException()) {
         hadException = true;
         return Deprecated::ScriptValue();
@@ -133,11 +133,11 @@ Deprecated::ScriptValue ScriptFunctionCall::call(bool& hadException)
         return Deprecated::ScriptValue();
 
     JSValue result;
-    JSValue exception;
+    NakedPtr<Exception> exception;
     if (m_callHandler)
-        result = m_callHandler(m_exec, function, callType, callData, thisObject, m_arguments, &exception);
+        result = m_callHandler(m_exec, function, callType, callData, thisObject, m_arguments, exception);
     else
-        result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments, &exception);
+        result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments, exception);
 
     if (exception) {
         hadException = true;
index 7c3e78c255cf3a1c32f645a141250050ac80071b..25cdfb214d437ba86df713a57bbf9062eb3a0788 100644 (file)
@@ -71,7 +71,7 @@ private:
 
 class JS_EXPORT_PRIVATE ScriptFunctionCall : public ScriptCallArgumentHandler {
 public:
-    typedef JSC::JSValue (*ScriptFunctionCallHandler)(JSC::ExecState* exec, JSC::JSValue functionObject, JSC::CallType callType, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args, JSC::JSValue* exception);
+    typedef JSC::JSValue (*ScriptFunctionCallHandler)(JSC::ExecState* exec, JSC::JSValue functionObject, JSC::CallType callType, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args, NakedPtr<JSC::Exception>&);
     ScriptFunctionCall(const ScriptObject& thisObject, const String& name, ScriptFunctionCallHandler handler = nullptr);
     ScriptValue call(bool& hadException);
     ScriptValue call();
index 004ff246b4671a60c6ae6baff4858f71c4f73fbb..153b033a11780e01d0fcb34b5f59daf7d1cd7cd8 100644 (file)
@@ -97,8 +97,7 @@ bool ScriptValue::isFunction() const
     return getCallData(m_value.get(), callData) != CallTypeNone;
 }
 
-#if ENABLE(INSPECTOR)
-static PassRefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSValue value, int maxDepth)
+static RefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSValue value, int maxDepth)
 {
     if (!value) {
         ASSERT_NOT_REACHED();
@@ -114,14 +113,16 @@ static PassRefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSV
         return InspectorValue::null();
     if (value.isBoolean())
         return InspectorBasicValue::create(value.asBoolean());
-    if (value.isNumber())
+    if (value.isNumber() && value.isDouble())
         return InspectorBasicValue::create(value.asNumber());
+    if (value.isNumber() && value.isMachineInt())
+        return InspectorBasicValue::create(static_cast<int>(value.asMachineInt()));
     if (value.isString())
         return InspectorString::create(value.getString(scriptState));
 
     if (value.isObject()) {
         if (isJSArray(value)) {
-            RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
+            Ref<InspectorArray> inspectorArray = InspectorArray::create();
             JSArray* array = asArray(value);
             unsigned length = array->length();
             for (unsigned i = 0; i < length; i++) {
@@ -129,34 +130,33 @@ static PassRefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSV
                 RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element, maxDepth);
                 if (!elementValue)
                     return nullptr;
-                inspectorArray->pushValue(elementValue);
+                inspectorArray->pushValue(WTF::move(elementValue));
             }
-            return inspectorArray;
+            return WTF::move(inspectorArray);
         }
-        RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
+        Ref<InspectorObject> inspectorObject = InspectorObject::create();
         JSObject* object = value.getObject();
         PropertyNameArray propertyNames(scriptState);
-        object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, ExcludeDontEnumProperties);
+        object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, EnumerationMode());
         for (size_t i = 0; i < propertyNames.size(); i++) {
             const Identifier& name = propertyNames[i];
             JSValue propertyValue = object->get(scriptState, name);
             RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue, maxDepth);
             if (!inspectorValue)
                 return nullptr;
-            inspectorObject->setValue(name.string(), inspectorValue);
+            inspectorObject->setValue(name.string(), WTF::move(inspectorValue));
         }
-        return inspectorObject;
+        return WTF::move(inspectorObject);
     }
 
     ASSERT_NOT_REACHED();
     return nullptr;
 }
 
-PassRefPtr<InspectorValue> ScriptValue::toInspectorValue(ExecState* scriptState) const
+RefPtr<InspectorValue> ScriptValue::toInspectorValue(ExecState* scriptState) const
 {
     JSLockHolder holder(scriptState);
     return jsToInspectorValue(scriptState, m_value.get(), InspectorValue::maxDepth);
 }
-#endif // ENABLE(INSPECTOR)
 
 } // namespace Deprecated
index d5fade90b16e347fd832b9cb9b52d300f5d9ca40..b7b521eccfca9a909466b029d304eaae3c2ad697 100644 (file)
@@ -51,6 +51,7 @@ public:
     ScriptValue(JSC::VM& vm, JSC::JSValue value) : m_value(vm, value) { }
     virtual ~ScriptValue();
 
+    operator JSC::JSValue() const { return jsValue(); }
     JSC::JSValue jsValue() const { return m_value.get(); }
     bool getString(JSC::ExecState*, String& result) const;
     String toString(JSC::ExecState*) const;
@@ -65,9 +66,7 @@ public:
 
     bool operator==(const ScriptValue& other) const { return m_value == other.m_value; }
 
-#if ENABLE(INSPECTOR)
-    PassRefPtr<Inspector::InspectorValue> toInspectorValue(JSC::ExecState*) const;
-#endif
+    RefPtr<Inspector::InspectorValue> toInspectorValue(JSC::ExecState*) const;
 
 private:
     JSC::Strong<JSC::Unknown> m_value;
index fe8469f24aa1461aff8f50e1faca069ada97378f..06ef0308a73d220957117fea879f0460f6ed7033 100755 (executable)
@@ -1,9 +1,33 @@
 #!/usr/bin/python
 
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 import glob
 import os
 import subprocess
 import sys
+from sets import Set
 from operator import itemgetter
 
 
@@ -14,14 +38,15 @@ print("Building Index Table")
 if current_arch not in ("x86_64", "arm64"):
     sys.exit()
 
-binary_file_directory = os.path.join(os.getenv("OBJECT_FILE_DIR_" + os.getenv("CURRENT_VARIANT")), current_arch)
+bitcode_file_original_directory = os.path.join(os.getenv("TARGET_TEMP_DIR"), "Objects-" + os.getenv("CURRENT_VARIANT"), current_arch)
 
-if not os.path.isdir(binary_file_directory):
-    print("Failed to build index table at " + binary_file_directory)
+if not os.path.isdir(bitcode_file_original_directory):
+    print("Failed to build index table at " + bitcode_file_original_directory)
     sys.exit()
 
 framework_directory = os.path.join(os.getenv("BUILT_PRODUCTS_DIR"), os.getenv("JAVASCRIPTCORE_RESOURCES_DIR"), "Runtime", current_arch)
 
+
 symbol_table_location = os.path.join(framework_directory, "Runtime.symtbl")
 
 symbol_table = {}
@@ -33,23 +58,36 @@ symbol_table_modification_time = 0
 if os.path.isfile(symbol_table_location):
     symbol_table_modification_time = os.path.getmtime(symbol_table_location)
 
-file_suffix = "bc.gz"
+file_suffix = "bc"
 file_suffix_length = len(file_suffix)
 
+tested_symbols_location = "./tested-symbols.symlst"
+include_symbol_table_location = os.path.join(os.getenv("SHARED_DERIVED_FILE_DIR"), "JavaScriptCore/InlineRuntimeSymbolTable.h")
+
+tested_symbols = Set([])
+
+if os.path.isfile(tested_symbols_location):
+    with open(tested_symbols_location, 'r') as file:
+        print("Loading tested symbols")
+        for line in file:
+            tested_symbols.add(line[:-1])
+
+print ("Original directory: " + bitcode_file_original_directory)
+
 for bitcode_file in glob.iglob(os.path.join(framework_directory, "*." + file_suffix)):
     bitcode_basename = os.path.basename(bitcode_file)
-    binary_file = os.path.join(binary_file_directory, bitcode_basename[:-file_suffix_length] + "o")
-    if os.path.getmtime(binary_file) < symbol_table_modification_time:
+    bitcode_file_original = os.path.join(bitcode_file_original_directory, bitcode_basename[:-file_suffix_length] + "o")
+    if os.path.getmtime(bitcode_file_original) < symbol_table_modification_time:
         continue
 
     symbol_table_is_out_of_date = True
 
     print("Appending symbols from " + bitcode_basename)
-    lines = subprocess.check_output(["nm", "-U", "-j", binary_file]).splitlines()
+    lines = subprocess.check_output(["nm", "-U", "-j", bitcode_file]).splitlines()
 
     for symbol in lines:
-        if symbol[:2] == "__" and symbol[-3:] != ".eh":
-            symbol_table[symbol] = bitcode_basename[1:]
+        if symbol[:2] == "__" and symbol[-3:] != ".eh" and symbol in tested_symbols:
+            symbol_table[symbol[1:]] = bitcode_basename
 
 if not symbol_table_is_out_of_date:
     sys.exit()
@@ -65,10 +103,14 @@ if os.path.isfile(symbol_table_location):
 
 symbol_list = symbol_table.items()
 
-print("Writing symbol table")
-
-with open(symbol_table_location, "w") as file:
-    for symbol, location in symbol_list:
-        file.write("{} {}\n".format(symbol, location))
+print("Writing symbol table: " + symbol_table_location)
+print("Writing inline file: " + include_symbol_table_location)
 
+with open(symbol_table_location, "w") as symbol_file:
+    with open(include_symbol_table_location, "w") as include_file:
+        include_file.write("#define FOR_EACH_LIBRARY_SYMBOL(macro)")
+        for symbol, location in symbol_list:
+            symbol_file.write("{} {}\n".format(symbol, location))
+            include_file.write(" \\\nmacro(\"{}\", \"{}\")".format(symbol, location))
+        include_file.write("\n")
 print("Done")
diff --git a/build-symbol-table-index.sh b/build-symbol-table-index.sh
deleted file mode 100755 (executable)
index 89610d2..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) 2014 Apple Inc.  All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
-
-RUNTIME_DERIVED_SOURCES_DIR=${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCoreRuntime
-RUNTIME_INSTALL_DIR=${BUILT_PRODUCTS_DIR}/${JAVASCRIPTCORE_RESOURCES_DIR}/Runtime
-
-for arch in $ARCHS;
-do
-    if [ -d "$RUNTIME_DERIVED_SOURCES_DIR/$arch" ];
-    then
-        mkdir -p "$RUNTIME_INSTALL_DIR/$arch"
-        cp "$RUNTIME_DERIVED_SOURCES_DIR/$arch"/*.bc.gz "$RUNTIME_INSTALL_DIR/$arch"/.
-        ${SRCROOT}/build-symbol-table-index.py $arch
-    fi
-done
index 8566a18d9987e4b036308c8ea6807b1ee737b29a..af46dd8feffe534bcd40534f34f7bf25fa5be443 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+function reduce(callback /*, initialValue */)
+{
+    "use strict";
+    if (this === null)
+        throw new @TypeError("Array.prototype.reduce requires that |this| not be null");
+
+    if (this === undefined)
+        throw new @TypeError("Array.prototype.reduce requires that |this| not be undefined");
+
+    var array = @Object(this);
+    var length = @toLength(array.length);
+
+    if (typeof callback !== "function")
+        throw new @TypeError("Array.prototype.reduce callback must be a function");
+
+    if (length === 0 && arguments.length < 2)
+        throw new @TypeError("reduce of empty array with no initial value");
+
+    var accumulator, k = 0;
+    if (arguments.length > 1)
+        accumulator = arguments[1];
+    else {
+        while (k < length && !(k in array))
+            k += 1;
+        if (k >= length)
+            throw new @TypeError("reduce of empty array with no initial value");
+        accumulator = array[k++];
+    }
+
+    while (k < length) {
+        if (k in array)
+            accumulator = callback.@call(undefined, accumulator, array[k], k, array);
+        k += 1;
+    }
+    return accumulator;
+}
+
+function reduceRight(callback /*, initialValue */)
+{
+    "use strict";
+    if (this === null)
+        throw new @TypeError("Array.prototype.reduceRight requires that |this| not be null");
+
+    if (this === undefined)
+        throw new @TypeError("Array.prototype.reduceRight requires that |this| not be undefined");
+
+    var array = @Object(this);
+    var length = @toLength(array.length);
+
+    if (typeof callback !== "function")
+        throw new @TypeError("Array.prototype.reduceRight callback must be a function");
+
+    if (length === 0 && arguments.length < 2)
+        throw new @TypeError("reduceRight of empty array with no initial value");
+
+    var accumulator, k = length - 1;
+    if (arguments.length > 1)
+        accumulator = arguments[1];
+    else {
+        while (k >= 0 && !(k in array))
+            k -= 1;
+        if (k < 0)
+            throw new @TypeError("reduceRight of empty array with no initial value");
+        accumulator = array[k--];
+    }
+
+    while (k >= 0) {
+        if (k in array)
+            accumulator = callback.@call(undefined, accumulator, array[k], k, array);
+        k -= 1;
+    }
+    return accumulator;
+}
+
 function every(callback /*, thisArg */) {
     "use strict";
     if (this === null)
@@ -32,8 +107,8 @@ function every(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.every requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.every callback must be a function");
     
@@ -58,8 +133,8 @@ function forEach(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.forEach requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.forEach callback must be a function");
     
@@ -80,8 +155,8 @@ function filter(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.filter requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.filter callback must be a function");
     
@@ -92,8 +167,10 @@ function filter(callback /*, thisArg */) {
         if (!(i in array))
             continue;
         var current = array[i]
-        if (callback.@call(thisArg, current, i, array))
-            result[nextIndex++] = current;
+        if (callback.@call(thisArg, current, i, array)) {
+            @putByValDirect(result, nextIndex, current);
+            ++nextIndex;
+        }
     }
     return result;
 }
@@ -107,8 +184,8 @@ function map(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.map requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.map callback must be a function");
     
@@ -119,7 +196,8 @@ function map(callback /*, thisArg */) {
     for (var i = 0; i < length; i++) {
         if (!(i in array))
             continue;
-        result[i] = callback.@call(thisArg, array[i], i, array)
+        var mappedValue = callback.@call(thisArg, array[i], i, array);
+        @putByValDirect(result, i, mappedValue);
     }
     return result;
 }
@@ -133,8 +211,8 @@ function some(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.some requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.some callback must be a function");
     
@@ -157,7 +235,7 @@ function fill(value /* [, start [, end]] */)
     if (this === undefined)
         throw new @TypeError("Array.prototype.fill requires that |this| not be undefined");
     var O = @Object(this);
-    var len = O.length >>> 0;
+    var len = @toLength(O.length);
     var relativeStart = 0;
     if (arguments.length > 1 && arguments[1] !== undefined)
         relativeStart = arguments[1] | 0;
@@ -198,17 +276,16 @@ function find(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.find requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.find callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : undefined;
     for (var i = 0; i < length; i++) {
-        if (!(i in array))
-            continue;
-        if (callback.@call(thisArg, array[i], i, array))
-            return array[i];
+        var kValue = array[i];
+        if (callback.@call(thisArg, kValue, i, array))
+            return kValue;
     }
     return undefined;
 }
@@ -222,17 +299,346 @@ function findIndex(callback /*, thisArg */) {
         throw new @TypeError("Array.prototype.findIndex requires that |this| not be undefined");
     
     var array = @Object(this);
-    var length = array.length >>> 0;
-    
+    var length = @toLength(array.length);
+
     if (typeof callback !== "function")
         throw new @TypeError("Array.prototype.findIndex callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : undefined;
     for (var i = 0; i < length; i++) {
-        if (!(i in array))
-            continue;
         if (callback.@call(thisArg, array[i], i, array))
             return i;
     }
     return -1;
 }
+
+function includes(searchElement /*, fromIndex*/) {
+    "use strict";
+    if (this === null)
+        throw new @TypeError("Array.prototype.includes requires that |this| not be null");
+
+    if (this === undefined)
+        throw new @TypeError("Array.prototype.includes requires that |this| not be undefined");
+
+    var array = @Object(this);
+    var length = @toLength(array.length);
+
+    if (length === 0)
+        return false;
+
+    var fromIndex = 0;
+    if (arguments.length > 1 && arguments[1] !== undefined)
+        fromIndex = arguments[1] | 0;
+
+    var index;
+    if (fromIndex >= 0)
+        index = fromIndex;
+    else
+        index = length + fromIndex;
+
+    if (index < 0)
+        index = 0;
+
+    var currentElement;
+    for (; index < length; ++index) {
+        currentElement = array[index];
+        // Use SameValueZero comparison, rather than just StrictEquals.
+        if (searchElement === currentElement || (searchElement !== searchElement && currentElement !== currentElement))
+            return true;
+    }
+    return false;
+}
+
+function sort(comparator)
+{
+    "use strict";
+
+    function min(a, b)
+    {
+        return a < b ? a : b;
+    }
+
+    function stringComparator(a, b)
+    {
+        var aString = a.string;
+        var bString = b.string;
+
+        var aLength = aString.length;
+        var bLength = bString.length;
+        var length = min(aLength, bLength);
+
+        for (var i = 0; i < length; ++i) {
+            var aCharCode = aString.@charCodeAt(i);
+            var bCharCode = bString.@charCodeAt(i);
+
+            if (aCharCode == bCharCode)
+                continue;
+
+            return aCharCode - bCharCode;
+        }
+
+        return aLength - bLength;
+    }
+
+    // Move undefineds and holes to the end of a sparse array. Result is [values..., undefineds..., holes...].
+    function compactSparse(array, dst, src, length)
+    {
+        var values = [ ];
+        var seen = { };
+        var valueCount = 0;
+        var undefinedCount = 0;
+
+        // Clean up after the in-progress non-sparse compaction that failed.
+        for (var i = dst; i < src; ++i)
+            delete array[i];
+
+        for (var object = array; object; object = @Object.@getPrototypeOf(object)) {
+            var propertyNames = @Object.@getOwnPropertyNames(object);
+            for (var i = 0; i < propertyNames.length; ++i) {
+                var index = propertyNames[i];
+                if (index < length) { // Exclude non-numeric properties and properties past length.
+                    if (seen[index]) // Exclude duplicates.
+                        continue;
+                    seen[index] = 1;
+
+                    var value = array[index];
+                    delete array[index];
+
+                    if (value === undefined) {
+                        ++undefinedCount;
+                        continue;
+                    }
+
+                    array[valueCount++] = value;
+                }
+            }
+        }
+
+        for (var i = valueCount; i < valueCount + undefinedCount; ++i)
+            array[i] = undefined;
+
+        return valueCount;
+    }
+
+    function compactSlow(array, length)
+    {
+        var holeCount = 0;
+
+        for (var dst = 0, src = 0; src < length; ++src) {
+            if (!(src in array)) {
+                ++holeCount;
+                if (holeCount < 256)
+                    continue;
+                return compactSparse(array, dst, src, length);
+            }
+
+            var value = array[src];
+            if (value === undefined)
+                continue;
+
+            array[dst++] = value;
+        }
+
+        var valueCount = dst;
+        var undefinedCount = length - valueCount - holeCount;
+
+        for (var i = valueCount; i < valueCount + undefinedCount; ++i)
+            array[i] = undefined;
+
+        for (var i = valueCount + undefinedCount; i < length; ++i)
+            delete array[i];
+
+        return valueCount;
+    }
+
+    // Move undefineds and holes to the end of an array. Result is [values..., undefineds..., holes...].
+    function compact(array, length)
+    {
+        for (var i = 0; i < array.length; ++i) {
+            if (array[i] === undefined)
+                return compactSlow(array, length);
+        }
+
+        return length;
+    }
+
+    function merge(dst, src, srcIndex, srcEnd, width, comparator)
+    {
+        var left = srcIndex;
+        var leftEnd = min(left + width, srcEnd);
+        var right = leftEnd;
+        var rightEnd = min(right + width, srcEnd);
+
+        for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
+            if (right < rightEnd) {
+                if (left >= leftEnd || comparator(src[right], src[left]) < 0) {
+                    dst[dstIndex] = src[right++];
+                    continue;
+                }
+            }
+
+            dst[dstIndex] = src[left++];
+        }
+    }
+
+    function mergeSort(array, valueCount, comparator)
+    {
+        var buffer = [ ];
+        buffer.length = valueCount;
+
+        var dst = buffer;
+        var src = array;
+        for (var width = 1; width < valueCount; width *= 2) {
+            for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width)
+                merge(dst, src, srcIndex, valueCount, width, comparator);
+
+            var tmp = src;
+            src = dst;
+            dst = tmp;
+        }
+
+        if (src != array) {
+            for(var i = 0; i < valueCount; i++)
+                array[i] = src[i];
+        }
+    }
+
+    function bucketSort(array, dst, bucket, depth)
+    {
+        if (bucket.length < 32 || depth > 32) {
+            mergeSort(bucket, bucket.length, stringComparator);
+            for (var i = 0; i < bucket.length; ++i)
+                array[dst++] = bucket[i].value;
+            return dst;
+        }
+
+        var buckets = [ ];
+        for (var i = 0; i < bucket.length; ++i) {
+            var entry = bucket[i];
+            var string = entry.string;
+            if (string.length == depth) {
+                array[dst++] = entry.value;
+                continue;
+            }
+
+            var c = string.@charCodeAt(depth);
+            if (!buckets[c])
+                buckets[c] = [ ];
+            buckets[c][buckets[c].length] = entry;
+        }
+
+        for (var i = 0; i < buckets.length; ++i) {
+            if (!buckets[i])
+                continue;
+            dst = bucketSort(array, dst, buckets[i], depth + 1);
+        }
+
+        return dst;
+    }
+
+    function comparatorSort(array, comparator)
+    {
+        var length = array.length >>> 0;
+
+        // For compatibility with Firefox and Chrome, do nothing observable
+        // to the target array if it has 0 or 1 sortable properties.
+        if (length < 2)
+            return;
+
+        var valueCount = compact(array, length);
+        mergeSort(array, valueCount, comparator);
+    }
+
+    function stringSort(array)
+    {
+        var length = array.length >>> 0;
+
+        // For compatibility with Firefox and Chrome, do nothing observable
+        // to the target array if it has 0 or 1 sortable properties.
+        if (length < 2)
+            return;
+
+        var valueCount = compact(array, length);
+
+        var strings = new @Array(valueCount);
+        for (var i = 0; i < valueCount; ++i)
+            strings[i] = { string: @toString(array[i]), value: array[i] };
+
+        bucketSort(array, 0, strings, 0);
+    }
+
+    if (this === null)
+        throw new @TypeError("Array.prototype.sort requires that |this| not be null");
+
+    if (this === undefined)
+        throw new @TypeError("Array.prototype.sort requires that |this| not be undefined");
+
+    if (typeof this == "string")
+        throw new @TypeError("Attempted to assign to readonly property.");
+
+    var array = @Object(this);
+
+    if (typeof comparator == "function")
+        comparatorSort(array, comparator);
+    else
+        stringSort(array);
+
+    return array;
+}
+
+function copyWithin(target, start /*, end */)
+{
+    "use strict";
+
+    function maxWithPositives(a, b)
+    {
+        return (a < b) ? b : a;
+    }
+
+    function minWithMaybeNegativeZeroAndPositive(maybeNegativeZero, positive)
+    {
+        return (maybeNegativeZero < positive) ? maybeNegativeZero : positive;
+    }
+
+    if (this === null || this === undefined)
+        throw new @TypeError("Array.copyWithin requires that |this| not be null or undefined");
+    var thisObject = @Object(this);
+
+    var length = @toLength(thisObject.length);
+
+    var relativeTarget = @toInteger(target);
+    var to = (relativeTarget < 0) ? maxWithPositives(length + relativeTarget, 0) : minWithMaybeNegativeZeroAndPositive(relativeTarget, length);
+
+    var relativeStart = @toInteger(start);
+    var from = (relativeStart < 0) ? maxWithPositives(length + relativeStart, 0) : minWithMaybeNegativeZeroAndPositive(relativeStart, length);
+
+    var relativeEnd;
+    if (arguments.length >= 3) {
+        var end = arguments[2];
+        if (end === undefined)
+            relativeEnd = length;
+        else
+            relativeEnd = @toInteger(end);
+    } else
+        relativeEnd = length;
+
+    var finalValue = (relativeEnd < 0) ? maxWithPositives(length + relativeEnd, 0) : minWithMaybeNegativeZeroAndPositive(relativeEnd, length);
+
+    var count = minWithMaybeNegativeZeroAndPositive(finalValue - from, length - to);
+
+    var direction = 1;
+    if (from < to && to < from + count) {
+        direction = -1;
+        from = from + count - 1;
+        to = to + count - 1;
+    }
+
+    for (var i = 0; i < count; ++i, from += direction, to += direction) {
+        if (from in thisObject)
+            thisObject[to] = thisObject[from];
+        else
+            delete thisObject[to];
+    }
+
+    return thisObject;
+}
diff --git a/builtins/ArrayConstructor.js b/builtins/ArrayConstructor.js
new file mode 100644 (file)
index 0000000..5a551f7
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function of(/* items... */)
+{
+    "use strict";
+
+    var length = arguments.length;
+    // TODO: Need isConstructor(this) instead of typeof "function" check.
+    var array = typeof this === 'function' ? new this(length) : new @Array(length);
+    for (var k = 0; k < length; ++k)
+        @putByValDirect(array, k, arguments[k]);
+    array.length = length;
+    return array;
+}
+
+function from(items /*, mapFn, thisArg */) {
+    "use strict";
+
+    var thisObj = this;
+
+    var mapFn = arguments.length > 1 ? arguments[1] : undefined;
+
+    var thisArg;
+
+    if (mapFn !== undefined) {
+        if (typeof mapFn !== "function")
+            throw new @TypeError("Array.from requires that the second argument, when provided, be a function");
+
+        if (arguments.length > 2)
+            thisArg = arguments[2];
+    }
+
+    if (items == null)
+        throw new @TypeError("Array.from requires an array-like object - not null or undefined");
+
+    var iteratorMethod = items[@symbolIterator];
+    if (iteratorMethod != null) {
+        if (typeof iteratorMethod !== "function")
+            throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+
+        // TODO: Need isConstructor(thisObj) instead of typeof "function" check.
+        var result = (typeof thisObj === "function") ? @Object(new thisObj()) : [];
+
+        var k = 0;
+        var iterator = iteratorMethod.@call(items);
+
+        // Since for-of loop once more looks up the @@iterator property of a given iterable,
+        // it could be observable if the user defines a getter for @@iterator.
+        // To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
+        var wrapper = {
+            [@symbolIterator]() {
+                return iterator;
+            }
+        };
+
+        for (var value of wrapper) {
+            if (mapFn)
+                @putByValDirect(result, k, thisArg === undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
+            else
+                @putByValDirect(result, k, value);
+            k += 1;
+        }
+
+        result.length = k;
+        return result;
+    }
+
+    var arrayLike = @Object(items);
+    var arrayLikeLength = @toLength(arrayLike.length);
+
+    // TODO: Need isConstructor(thisObj) instead of typeof "function" check.
+    var result = (typeof thisObj === "function") ? @Object(new thisObj(arrayLikeLength)) : new @Array(arrayLikeLength);
+
+    var k = 0;
+    while (k < arrayLikeLength) {
+        var value = arrayLike[k];
+        if (mapFn)
+            @putByValDirect(result, k, thisArg === undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
+        else
+            @putByValDirect(result, k, value);
+        k += 1;
+    }
+
+    result.length = arrayLikeLength;
+    return result;
+}
diff --git a/builtins/ArrayIterator.prototype.js b/builtins/ArrayIterator.prototype.js
new file mode 100644 (file)
index 0000000..82df528
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function next() {
+    "use strict";
+
+    if (this == null)
+        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
+
+    var itemKind = this.@arrayIterationKind;
+    if (itemKind === undefined)
+        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");
+
+    var done = true;
+    var value = undefined;
+
+    var array = this.@iteratedObject;
+    if (array !== undefined) {
+        var index = this.@arrayIteratorNextIndex;
+        var length = array.length >>> 0;
+        if (index >= length) {
+            this.@iteratedObject = undefined;
+        } else {
+            this.@arrayIteratorNextIndex = index + 1;
+            done = false;
+            if (itemKind === @arrayIterationKindKey) {
+                value = index;
+            } else if (itemKind === @arrayIterationKindValue) {
+                value = array[index];
+            } else {
+                value = [ index, array[index] ];
+            }
+        }
+    }
+
+    return {done, value};
+}
index 70b43d5e6766f97de0c2fbd0de1c46fd97a2cc85..245eff3b7dd39e7c7ac9cdbd48914502cbd78a48 100644 (file)
@@ -31,6 +31,7 @@
 #include "Executable.h"
 #include "JSCInlines.h"
 #include "Parser.h"
+#include <wtf/NeverDestroyed.h>
 
 namespace JSC {
 
@@ -42,14 +43,39 @@ BuiltinExecutables::BuiltinExecutables(VM& vm)
 {
 }
 
-UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& source, const Identifier& name)
+UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name)
+{
+    static NeverDestroyed<const String> baseConstructorCode(ASCIILiteral("(function () { })"));
+    static NeverDestroyed<const String> derivedConstructorCode(ASCIILiteral("(function () { super(...arguments); })"));
+
+    switch (constructorKind) {
+    case ConstructorKind::None:
+        break;
+    case ConstructorKind::Base:
+        return createExecutableInternal(makeSource(baseConstructorCode), name, constructorKind);
+    case ConstructorKind::Derived:
+        return createExecutableInternal(makeSource(derivedConstructorCode), name, constructorKind);
+    }
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createExecutableInternal(const SourceCode& source, const Identifier& name, ConstructorKind constructorKind)
 {
     JSTextPosition positionBeforeLastNewline;
     ParserError error;
-    RefPtr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), JSParseBuiltin, JSParseProgramCode, error, &positionBeforeLastNewline);
+    bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None;
+    JSParserBuiltinMode builtinMode = isParsingDefaultConstructor ? JSParserBuiltinMode::NotBuiltin : JSParserBuiltinMode::Builtin;
+    UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
+    RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr;
+    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
+        &m_vm, source, 0, Identifier(), builtinMode, 
+        JSParserStrictMode::NotStrict, 
+        JSParserCodeType::Program,
+        error, &positionBeforeLastNewline, constructorKind);
 
     if (!program) {
-        dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.m_message);
+        dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.message());
         CRASH();
     }
 
@@ -71,23 +97,27 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const So
     RELEASE_ASSERT(body);
     for (const auto& closedVariable : program->closedVariables()) {
         if (closedVariable == m_vm.propertyNames->arguments.impl())
-        continue;
+            continue;
         
         if (closedVariable == m_vm.propertyNames->undefinedKeyword.impl())
             continue;
-        RELEASE_ASSERT(closedVariable->isEmptyUnique());
     }
     body->overrideName(name);
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, UnlinkedBuiltinFunction);
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, kind, WTF::move(sourceOverride));
     functionExecutable->m_nameValue.set(m_vm, functionExecutable, jsString(&m_vm, name.string()));
     return functionExecutable;
 }
 
+void BuiltinExecutables::finalize(Handle<Unknown>, void* context)
+{
+    static_cast<Weak<UnlinkedFunctionExecutable>*>(context)->clear();
+}
+
 #define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \
 UnlinkedFunctionExecutable* BuiltinExecutables::name##Executable() \
 {\
     if (!m_##name##Executable)\
-        m_##name##Executable = createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->builtinNames().functionName##PublicName());\
+        m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->builtinNames().functionName##PublicName()), this, &m_##name##Executable);\
     return m_##name##Executable.get();\
 }
 JSC_FOREACH_BUILTIN(DEFINE_BUILTIN_EXECUTABLES)
index d44bf4c9bda8cdbb12a943439bd23f7ce0c5a7cc..f0d5f4e59bd89e176e0bd56064b506cda19b8e4f 100644 (file)
 #define BuiltinExecutables_h
 
 #include "JSCBuiltins.h"
+#include "ParserModes.h"
 #include "SourceCode.h"
 #include "Weak.h"
-#include <wtf/PassOwnPtr.h>
+#include "WeakHandleOwner.h"
 
 namespace JSC {
 
@@ -37,25 +38,31 @@ class UnlinkedFunctionExecutable;
 class Identifier;
 class VM;
 
-class BuiltinExecutables {
+class BuiltinExecutables final: private WeakHandleOwner {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<BuiltinExecutables> create(VM& vm)
-    {
-        return adoptPtr(new BuiltinExecutables(vm));
-    }
-    
+    explicit BuiltinExecutables(VM&);
+
 #define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \
 UnlinkedFunctionExecutable* name##Executable(); \
 const SourceCode& name##Source() { return m_##name##Source; }
     
     JSC_FOREACH_BUILTIN(EXPOSE_BUILTIN_EXECUTABLES)
 #undef EXPOSE_BUILTIN_SOURCES
-    
+
+    UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
+
 private:
-    BuiltinExecutables(VM&);
+    void finalize(Handle<Unknown>, void* context) override;
+
     VM& m_vm;
-    UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&);
+
+    UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode& code, const Identifier& name)
+    {
+        return createExecutableInternal(code, name, ConstructorKind::None);
+    }
+    UnlinkedFunctionExecutable* createExecutableInternal(const SourceCode&, const Identifier&, ConstructorKind);
+
 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\
     SourceCode m_##name##Source; \
     Weak<UnlinkedFunctionExecutable> m_##name##Executable;
index 67e1f563bca018d03209cf81052623601ba4405b..5dc716cfcbab1f4d8512363d11cf5d0dff276d8a 100644 (file)
 
 namespace JSC {
     
-#define INITIALISE_BUILTIN_NAMES(name) , m_##name(vm, #name), m_##name##PrivateName(Identifier::from(PrivateName()))
-#define DECLARE_BUILTIN_NAMES(name) const Identifier m_##name; const Identifier m_##name##PrivateName;;
+#define INITIALISE_BUILTIN_NAMES(name) , m_##name(Identifier::fromString(vm, #name)), m_##name##PrivateName(Identifier::fromUid(PrivateName()))
+#define DECLARE_BUILTIN_NAMES(name) const Identifier m_##name; const Identifier m_##name##PrivateName;
 #define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
     const Identifier& name##PublicName() const { return m_##name; } \
     const Identifier& name##PrivateName() const { return m_##name##PrivateName; }
 
+#define INITIALISE_BUILTIN_SYMBOLS(name) INITIALISE_BUILTIN_NAMES(name), m_##name##Symbol(Identifier::fromUid(PrivateName(PrivateName::Description, ASCIILiteral("Symbol." #name))))
+#define DECLARE_BUILTIN_SYMBOLS(name) DECLARE_BUILTIN_NAMES(name) const Identifier m_##name##Symbol;
+#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
+    DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
+    const Identifier& name##Symbol() const { return m_##name##Symbol; }
+
 #define INITIALISE_PRIVATE_TO_PUBLIC_ENTRY(name) m_privateToPublicMap.add(m_##name##PrivateName.impl(), &m_##name);
 #define INITIALISE_PUBLIC_TO_PRIVATE_ENTRY(name) m_publicToPrivateMap.add(m_##name.impl(), &m_##name##PrivateName);
     
@@ -48,24 +54,32 @@ public:
         : m_emptyIdentifier(commonIdentifiers->emptyIdentifier)
         JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALISE_BUILTIN_NAMES)
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALISE_BUILTIN_NAMES)
+        JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALISE_BUILTIN_SYMBOLS)
     {
         JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALISE_PRIVATE_TO_PUBLIC_ENTRY)
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALISE_PRIVATE_TO_PUBLIC_ENTRY)
+        JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALISE_PRIVATE_TO_PUBLIC_ENTRY)
         JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALISE_PUBLIC_TO_PRIVATE_ENTRY)
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALISE_PUBLIC_TO_PRIVATE_ENTRY)
+        JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALISE_PUBLIC_TO_PRIVATE_ENTRY)
     }
 
+    bool isPrivateName(SymbolImpl& uid) const;
+    bool isPrivateName(UniquedStringImpl& uid) const;
+    bool isPrivateName(const Identifier&) const;
     const Identifier* getPrivateName(const Identifier&) const;
     const Identifier& getPublicName(const Identifier&) const;
     
     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
 
 private:
     Identifier m_emptyIdentifier;
     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES)
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_NAMES)
-    typedef HashMap<RefPtr<StringImpl>, const Identifier*, IdentifierRepHash> BuiltinNamesMap;
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS)
+    typedef HashMap<RefPtr<UniquedStringImpl>, const Identifier*, IdentifierRepHash> BuiltinNamesMap;
     BuiltinNamesMap m_publicToPrivateMap;
     BuiltinNamesMap m_privateToPublicMap;
 };
@@ -73,7 +87,28 @@ private:
 #undef DECLARE_BUILTIN_NAMES
 #undef INITIALISE_BUILTIN_NAMES
 #undef DECLARE_BUILTIN_IDENTIFIER_ACCESSOR
+#undef DECLARE_BUILTIN_SYMBOLS
+#undef INITIALISE_BUILTIN_SYMBOLS
+#undef DECLARE_BUILTIN_SYMBOL_ACCESSOR
+
+inline bool BuiltinNames::isPrivateName(SymbolImpl& uid) const
+{
+    return m_privateToPublicMap.contains(&uid);
+}
 
+inline bool BuiltinNames::isPrivateName(UniquedStringImpl& uid) const
+{
+    if (!uid.isSymbol())
+        return false;
+    return m_privateToPublicMap.contains(&uid);
+}
+
+inline bool BuiltinNames::isPrivateName(const Identifier& ident) const
+{
+    if (ident.isNull())
+        return false;
+    return isPrivateName(*ident.impl());
+}
 
 inline const Identifier* BuiltinNames::getPrivateName(const Identifier& ident) const
 {
@@ -91,7 +126,7 @@ inline const Identifier& BuiltinNames::getPublicName(const Identifier& ident) co
     return m_emptyIdentifier;
 }
 
-    
+
 }
 
 #endif
diff --git a/builtins/GlobalObject.js b/builtins/GlobalObject.js
new file mode 100644 (file)
index 0000000..6adadef
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function toInteger(target)
+{
+    "use strict";
+
+    var numberValue = @Number(target);
+
+    // isNaN(numberValue)
+    if (numberValue !== numberValue)
+        return 0;
+
+    if (numberValue === 0 || !@isFinite(numberValue))
+        return numberValue;
+
+    return (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue));
+}
+
+function toLength(target)
+{
+    "use strict";
+
+    var maxSafeInteger = 0x1FFFFFFFFFFFFF;
+    var length = @toInteger(target);
+    // originally Math.min(Math.max(length, 0), maxSafeInteger));
+    return length > 0 ? (length < maxSafeInteger ? length : maxSafeInteger) : 0;
+}
+
+function isObject(object)
+{
+    "use strict";
+
+    return (object !== null && typeof object === "object") || typeof object === "function";
+}
diff --git a/builtins/Iterator.prototype.js b/builtins/Iterator.prototype.js
new file mode 100644 (file)
index 0000000..dc72a64
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function SymbolIterator()
+{
+    'use strict';
+    return this;
+}
diff --git a/builtins/ObjectConstructor.js b/builtins/ObjectConstructor.js
new file mode 100644 (file)
index 0000000..eeec196
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 Jordan Harband. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function assign(target/*[*/, /*...*/sources/*] */) {
+    "use strict";
+
+    if (target == null)
+        throw new @TypeError("can't convert " + target + " to object");
+
+    var objTarget = @Object(target);
+    var s, nextSource, from, i, keys, nextKey, desc;
+    for (s = 1; s < arguments.length; ++s) {
+        nextSource = arguments[s];
+        if (nextSource != null) {
+            from = @Object(nextSource);
+            // TODO: replace @objectKeys + @objectGetOwnPropertySymbols with single @OwnPropertyKeys c++ operation
+            keys = @objectKeys(from);
+            for (i = 0; i < keys.length; ++i) {
+                nextKey = keys[i];
+                desc = @objectGetOwnPropertyDescriptor(from, nextKey);
+                if (typeof desc !== "undefined" && desc.enumerable) {
+                    objTarget[nextKey] = from[nextKey];
+                }
+            }
+            keys = @objectGetOwnPropertySymbols(from);
+            for (i = 0; i < keys.length; ++i) {
+                nextKey = keys[i];
+                desc = @objectGetOwnPropertyDescriptor(from, nextKey);
+                if (typeof desc !== "undefined" && desc.enumerable) {
+                    objTarget[nextKey] = from[nextKey];
+                }
+            }
+        }
+    }
+    return objTarget;
+}
diff --git a/builtins/Operations.Promise.js b/builtins/Operations.Promise.js
new file mode 100644 (file)
index 0000000..80c57ab
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function isPromise(promise)
+{
+    "use strict";
+
+    return @isObject(promise) && !!promise.@promiseState;
+}
+
+function newPromiseReaction(capability, handler)
+{
+    "use strict";
+
+    return {
+        @capabilities: capability,
+        @handler: handler
+    };
+}
+
+function newPromiseDeferred()
+{
+    "use strict";
+
+    return @newPromiseCapability(@Promise);
+}
+
+function newPromiseCapability(constructor)
+{
+    "use strict";
+
+    // FIXME: Check isConstructor(constructor).
+    if (typeof constructor !== "function")
+        throw new @TypeError("promise capability requires a constructor function");
+
+    var promiseCapability = {
+        @promise: undefined,
+        @resolve: undefined,
+        @reject: undefined
+    };
+
+    function executor(resolve, reject)
+    {
+        if (promiseCapability.@resolve !== undefined)
+            throw new @TypeError("resolve function is already set");
+        if (promiseCapability.@reject !== undefined)
+            throw new @TypeError("reject function is already set");
+
+        promiseCapability.@resolve = resolve;
+        promiseCapability.@reject = reject;
+    }
+
+    var promise = new constructor(executor);
+
+    if (typeof promiseCapability.@resolve !== "function")
+        throw new @TypeError("executor did not take a resolve function");
+
+    if (typeof promiseCapability.@reject !== "function")
+        throw new @TypeError("executor did not take a reject function");
+
+    promiseCapability.@promise = promise;
+
+    return promiseCapability;
+}
+
+function triggerPromiseReactions(reactions, argument)
+{
+    "use strict";
+
+    for (var index = 0, length = reactions.length; index < length; ++index)
+        @enqueueJob(@promiseReactionJob, [reactions[index], argument]);
+}
+
+function rejectPromise(promise, reason)
+{
+    "use strict";
+
+    var reactions = promise.@promiseRejectReactions;
+    promise.@promiseResult = reason;
+    promise.@promiseFulfillReactions = undefined;
+    promise.@promiseRejectReactions = undefined;
+    promise.@promiseState = @promiseRejected;
+    @triggerPromiseReactions(reactions, reason);
+}
+
+function fulfillPromise(promise, value)
+{
+    "use strict";
+
+    var reactions = promise.@promiseFulfillReactions;
+    promise.@promiseResult = value;
+    promise.@promiseFulfillReactions = undefined;
+    promise.@promiseRejectReactions = undefined;
+    promise.@promiseState = @promiseFulfilled;
+    @triggerPromiseReactions(reactions, value);
+}
+
+function createResolvingFunctions(promise)
+{
+    "use strict";
+
+    var alreadyResolved = false;
+
+    var resolve = function (resolution) {
+        if (alreadyResolved)
+            return undefined;
+        alreadyResolved = true;
+
+        if (resolution === promise)
+            return @rejectPromise(promise, new @TypeError("Resolve a promise with itself"));
+
+        if (!@isObject(resolution))
+            return @fulfillPromise(promise, resolution);
+
+        var then;
+        try {
+            then = resolution.then;
+        } catch (error) {
+            return @rejectPromise(promise, error);
+        }
+
+        if (typeof then !== 'function')
+            return @fulfillPromise(promise, resolution);
+
+        @enqueueJob(@promiseResolveThenableJob, [promise, resolution, then]);
+
+        return undefined;
+    };
+
+    var reject = function (reason) {
+        if (alreadyResolved)
+            return undefined;
+        alreadyResolved = true;
+
+        return @rejectPromise(promise, reason);
+    };
+
+    return {
+        @resolve: resolve,
+        @reject: reject
+    };
+}
+
+function promiseReactionJob(reaction, argument)
+{
+    "use strict";
+
+    var promiseCapability = reaction.@capabilities;
+
+    var result;
+    try {
+        result = reaction.@handler.@call(undefined, argument);
+    } catch (error) {
+        return promiseCapability.@reject.@call(undefined, error);
+    }
+
+    return promiseCapability.@resolve.@call(undefined, result);
+}
+
+function promiseResolveThenableJob(promiseToResolve, thenable, then)
+{
+    "use strict";
+
+    var resolvingFunctions = @createResolvingFunctions(promiseToResolve);
+
+    try {
+        return then.@call(thenable, resolvingFunctions.@resolve, resolvingFunctions.@reject);
+    } catch (error) {
+        return resolvingFunctions.@reject.@call(undefined, error);
+    }
+}
+
+function initializePromise(executor)
+{
+    "use strict";
+
+    if (typeof executor !== 'function')
+        throw new @TypeError("Promise constructor takes a function argument");
+
+    this.@promiseState = @promisePending;
+    this.@promiseFulfillReactions = [];
+    this.@promiseRejectReactions = [];
+
+    var resolvingFunctions = @createResolvingFunctions(this);
+    try {
+        executor(resolvingFunctions.@resolve, resolvingFunctions.@reject);
+    } catch (error) {
+        return resolvingFunctions.@reject.@call(undefined, error);
+    }
+
+    return this;
+}
index fbd53b05a60acebc7781e6a0215e78be142039dc..8563df0d927fb233968939e14942396ec85e65aa 100644 (file)
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-function catch(onRejected) {
+function catch(onRejected)
+{
     "use strict";
 
     return this.then(undefined, onRejected);
 }
+
+function then(onFulfilled, onRejected)
+{
+    "use strict";
+
+    if (!@isPromise(this))
+        throw new @TypeError("|this| is not a object");
+
+    // FIXME: Fix this code when @@species well-known symbol is landed.
+    // https://bugs.webkit.org/show_bug.cgi?id=146624
+    var constructor = this.constructor;
+
+    var resultCapability = @newPromiseCapability(constructor);
+
+    if (typeof onFulfilled !== "function")
+        onFulfilled = function (argument) { return argument; };
+
+    if (typeof onRejected !== "function")
+        onRejected = function (argument) { throw argument; };
+
+    var fulfillReaction = @newPromiseReaction(resultCapability, onFulfilled);
+    var rejectReaction = @newPromiseReaction(resultCapability, onRejected);
+
+    var state = this.@promiseState;
+
+    if (state === @promisePending) {
+        @putByValDirect(this.@promiseFulfillReactions, this.@promiseFulfillReactions.length, fulfillReaction)
+        @putByValDirect(this.@promiseRejectReactions, this.@promiseRejectReactions.length, rejectReaction)
+    } else if (state === @promiseFulfilled)
+        @enqueueJob(@promiseReactionJob, [fulfillReaction, this.@promiseResult]);
+    else if (state === @promiseRejected)
+        @enqueueJob(@promiseReactionJob, [rejectReaction, this.@promiseResult]);
+
+    return resultCapability.@promise;
+}
diff --git a/builtins/PromiseConstructor.js b/builtins/PromiseConstructor.js
new file mode 100644 (file)
index 0000000..1f83b47
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function all(iterable)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        throw new TypeError("|this| is not a object");
+
+    // FIXME: Fix this code when @@species well-known symbol is landed.
+    // https://bugs.webkit.org/show_bug.cgi?id=146624
+    var constructor = this;
+
+    var promiseCapability = @newPromiseCapability(constructor);
+
+    var values = [];
+    var index = 0;
+    var remainingElementsCount = 1;
+
+    function newResolveElement(index)
+    {
+        var alreadyCalled = false;
+        return function (argument)
+        {
+            if (alreadyCalled)
+                return undefined;
+            alreadyCalled = true;
+
+            @putByValDirect(values, index, argument);
+
+            --remainingElementsCount;
+            if (remainingElementsCount === 0)
+                return promiseCapability.@resolve.@call(undefined, values);
+
+            return undefined;
+        }
+    }
+
+    try {
+        for (var value of iterable) {
+            @putByValDirect(values, index, undefined);
+            var nextPromise = constructor.resolve(value);
+            var resolveElement = newResolveElement(index);
+            ++remainingElementsCount;
+            nextPromise.then(resolveElement, promiseCapability.@reject);
+            ++index;
+        }
+
+        --remainingElementsCount;
+        if (remainingElementsCount === 0)
+            promiseCapability.@resolve.@call(undefined, values);
+    } catch (error) {
+        promiseCapability.@reject.@call(undefined, error);
+    }
+
+    return promiseCapability.@promise;
+}
+
+function race(iterable)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        throw new TypeError("|this| is not a object");
+
+    // FIXME: Fix this code when @@species well-known symbol is landed.
+    // https://bugs.webkit.org/show_bug.cgi?id=146624
+    var constructor = this;
+
+    var promiseCapability = @newPromiseCapability(constructor);
+
+    try {
+        for (var value of iterable) {
+            var nextPromise = constructor.resolve(value);
+            nextPromise.then(promiseCapability.@resolve, promiseCapability.@reject);
+        }
+    } catch (error) {
+        promiseCapability.@reject.@call(undefined, error);
+    }
+
+    return promiseCapability.@promise;
+}
+
+function reject(reason)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        throw new TypeError("|this| is not a object");
+
+    var promiseCapability = @newPromiseCapability(this);
+
+    promiseCapability.@reject.@call(undefined, reason);
+
+    return promiseCapability.@promise;
+}
+
+function resolve(value)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        throw new TypeError("|this| is not a object");
+
+    if (@isPromise(value)) {
+        var valueConstructor = value.constructor;
+        if (valueConstructor === this)
+            return value;
+    }
+
+    var promiseCapability = @newPromiseCapability(this);
+
+    promiseCapability.@resolve.@call(undefined, value);
+
+    return promiseCapability.@promise;
+}
diff --git a/builtins/StringConstructor.js b/builtins/StringConstructor.js
new file mode 100644 (file)
index 0000000..f8cd16b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function raw(template) {
+    "use strict";
+
+    if (template === null || template === undefined)
+        throw new @TypeError("String.raw requires template not be null or undefined");
+    var cookedSegments = @Object(template);
+
+    var rawValue = cookedSegments.raw;
+    if (rawValue === null || rawValue === undefined)
+        throw new @TypeError("String.raw requires template.raw not be null or undefined");
+    var rawSegments = @Object(rawValue);
+
+    var numberOfSubstitutions = arguments.length - 1;
+
+    var segmentCount = @toLength(rawSegments.length);
+
+    if (segmentCount <= 0)
+        return '';
+
+    var stringElements = '';
+    for (var i = 0; ; ++i) {
+        var segment = @toString(rawSegments[i]);
+        stringElements += segment;
+
+        if ((i + 1) === segmentCount)
+            return stringElements;
+
+        if (i < numberOfSubstitutions) {
+            var substitutionIndexInArguments = i + 1;
+            var next = @toString(arguments[substitutionIndexInArguments]);
+            stringElements += next;
+        }
+    }
+}
diff --git a/builtins/StringIterator.prototype.js b/builtins/StringIterator.prototype.js
new file mode 100644 (file)
index 0000000..8810c7d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function next() {
+    "use strict";
+
+    if (this == null)
+        throw new @TypeError("%StringIteratorPrototype%.next requires that |this| not be null or undefined");
+
+    var position = this.@stringIteratorNextIndex;
+    if (position === undefined)
+        throw new @TypeError("%StringIteratorPrototype%.next requires that |this| be a String Iterator instance");
+
+    var done = true;
+    var value = undefined;
+
+    var string = this.@iteratedString;
+    if (string !== undefined) {
+        var length = string.length >>> 0;
+        if (position >= length) {
+            this.@iteratedString = undefined;
+        } else {
+            done = false;
+
+            var first = string.@charCodeAt(position);
+            if (first < 0xD800 || first > 0xDBFF || position + 1 === length)
+                value = string[position];
+            else {
+                var second = string.@charCodeAt(position + 1);
+                if (second < 0xDC00 || second > 0xDFFF)
+                    value = string[position];
+                else
+                    value = string[position] + string[position + 1];
+            }
+
+            this.@stringIteratorNextIndex = position + value.length;
+        }
+    }
+
+    return {done, value};
+}
index ef49f20ce767116e0fe7ad4ac89f6b3b40ab7189..b8ade2223945e918aa6402aca911b8152ecdb4ff 100644 (file)
@@ -73,14 +73,39 @@ void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
         out.print(comma, "ArrayWithArrayStorage");
     if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
         out.print(comma, "ArrayWithSlowPutArrayStorage");
+
+    if (arrayModes & Int8ArrayMode)
+        out.print(comma, "Int8ArrayMode");
+    if (arrayModes & Int16ArrayMode)
+        out.print(comma, "Int16ArrayMode");
+    if (arrayModes & Int32ArrayMode)
+        out.print(comma, "Int32ArrayMode");
+    if (arrayModes & Uint8ArrayMode)
+        out.print(comma, "Uint8ArrayMode");
+    if (arrayModes & Uint8ClampedArrayMode)
+        out.print(comma, "Uint8ClampedArrayMode");
+    if (arrayModes & Uint16ArrayMode)
+        out.print(comma, "Uint16ArrayMode");
+    if (arrayModes & Uint32ArrayMode)
+        out.print(comma, "Uint32ArrayMode");
+    if (arrayModes & Float32ArrayMode)
+        out.print(comma, "Float32ArrayMode");
+    if (arrayModes & Float64ArrayMode)
+        out.print(comma, "Float64ArrayMode");
 }
 
-void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock)
+void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker& locker, CodeBlock* codeBlock)
 {
     if (!m_lastSeenStructureID)
         return;
     
     Structure* lastSeenStructure = codeBlock->heap()->structureIDTable().get(m_lastSeenStructureID);
+    computeUpdatedPrediction(locker, codeBlock, lastSeenStructure);
+    m_lastSeenStructureID = 0;
+}
+
+void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure)
+{
     m_observedArrayModes |= arrayModeFromStructure(lastSeenStructure);
     
     if (!m_didPerformFirstRunPruning
@@ -95,7 +120,6 @@ void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBloc
     if (!globalObject->isOriginalArrayStructure(lastSeenStructure)
         && !globalObject->isOriginalTypedArrayStructure(lastSeenStructure))
         m_usesOriginalArrayStructures = false;
-    m_lastSeenStructureID = 0;
 }
 
 CString ArrayProfile::briefDescription(const ConcurrentJITLocker& locker, CodeBlock* codeBlock)
index 302365ff006e2c3dcdc53ae9bd2ebf663b9d97f6..66b295da7920a10c9a7cf627d5428f8b5dc15478 100644 (file)
@@ -37,20 +37,44 @@ namespace JSC {
 class CodeBlock;
 class LLIntOffsetsExtractor;
 
-// This is a bitfield where each bit represents an IndexingType that we have seen.
-// There are 32 indexing types, so an unsigned is enough.
+// This is a bitfield where each bit represents an type of array access that we have seen.
+// There are 16 indexing types that use the lower bits.
+// There are 9 typed array types taking the bits 16 to 25.
 typedef unsigned ArrayModes;
 
+const ArrayModes Int8ArrayMode = 1 << 16;
+const ArrayModes Int16ArrayMode = 1 << 17;
+const ArrayModes Int32ArrayMode = 1 << 18;
+const ArrayModes Uint8ArrayMode = 1 << 19;
+const ArrayModes Uint8ClampedArrayMode = 1 << 20;
+const ArrayModes Uint16ArrayMode = 1 << 21;
+const ArrayModes Uint32ArrayMode = 1 << 22;
+const ArrayModes Float32ArrayMode = 1 << 23;
+const ArrayModes Float64ArrayMode = 1 << 24;
+
 #define asArrayModes(type) \
     (static_cast<unsigned>(1) << static_cast<unsigned>(type))
 
+#define ALL_TYPED_ARRAY_MODES \
+    (Int8ArrayMode            \
+    | Int16ArrayMode          \
+    | Int32ArrayMode          \
+    | Uint8ArrayMode          \
+    | Uint8ClampedArrayMode   \
+    | Uint16ArrayMode         \
+    | Uint32ArrayMode         \
+    | Float32ArrayMode        \
+    | Float64ArrayMode        \
+    )
+
 #define ALL_NON_ARRAY_ARRAY_MODES                       \
     (asArrayModes(NonArray)                             \
     | asArrayModes(NonArrayWithInt32)                   \
     | asArrayModes(NonArrayWithDouble)                  \
     | asArrayModes(NonArrayWithContiguous)              \
     | asArrayModes(NonArrayWithArrayStorage)            \
-    | asArrayModes(NonArrayWithSlowPutArrayStorage))
+    | asArrayModes(NonArrayWithSlowPutArrayStorage)     \
+    | ALL_TYPED_ARRAY_MODES)
 
 #define ALL_ARRAY_ARRAY_MODES                           \
     (asArrayModes(ArrayClass)                           \
@@ -65,6 +89,29 @@ typedef unsigned ArrayModes;
 
 inline ArrayModes arrayModeFromStructure(Structure* structure)
 {
+    switch (structure->classInfo()->typedArrayStorageType) {
+    case TypeInt8:
+        return Int8ArrayMode;
+    case TypeUint8:
+        return Uint8ArrayMode;
+    case TypeUint8Clamped:
+        return Uint8ClampedArrayMode;
+    case TypeInt16:
+        return Int16ArrayMode;
+    case TypeUint16:
+        return Uint16ArrayMode;
+    case TypeInt32:
+        return Int32ArrayMode;
+    case TypeUint32:
+        return Uint32ArrayMode;
+    case TypeFloat32:
+        return Float32ArrayMode;
+    case TypeFloat64:
+        return Float64ArrayMode;
+    case TypeDataView:
+    case NotTypedArray:
+        break;
+    }
     return asArrayModes(structure->indexingType());
 }
 
@@ -162,6 +209,8 @@ public:
     StructureID* addressOfLastSeenStructureID() { return &m_lastSeenStructureID; }
     ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
     bool* addressOfMayStoreToHole() { return &m_mayStoreToHole; }
+
+    void setOutOfBounds() { m_outOfBounds = true; }
     bool* addressOfOutOfBounds() { return &m_outOfBounds; }
     
     void observeStructure(Structure* structure)
@@ -170,6 +219,7 @@ public:
     }
     
     void computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock*);
+    void computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock*, Structure* lastSeenStructure);
     
     ArrayModes observedArrayModes(const ConcurrentJITLocker&) const { return m_observedArrayModes; }
     bool mayInterceptIndexedAccesses(const ConcurrentJITLocker&) const { return m_mayInterceptIndexedAccesses; }
@@ -197,7 +247,7 @@ private:
     ArrayModes m_observedArrayModes;
 };
 
-typedef SegmentedVector<ArrayProfile, 4, 0> ArrayProfileVector;
+typedef SegmentedVector<ArrayProfile, 4> ArrayProfileVector;
 
 } // namespace JSC
 
index ebe587d79511e8804453ff159dcefae2f7da3d37..d98851613258a71b9f04ba49073f44033e571083 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,6 +41,8 @@ enum JITArrayMode {
     JITDouble,
     JITContiguous,
     JITArrayStorage,
+    JITDirectArguments,
+    JITScopedArguments,
     JITInt8Array,
     JITInt16Array,
     JITInt32Array,
@@ -65,6 +67,17 @@ inline bool isOptimizableIndexingType(IndexingType indexingType)
     }
 }
 
+inline bool hasOptimizableIndexingForJSType(JSType type)
+{
+    switch (type) {
+    case DirectArgumentsType:
+    case ScopedArgumentsType:
+        return true;
+    default:
+        return false;
+    }
+}
+
 inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
 {
     return isTypedView(classInfo->typedArrayStorageType);
@@ -73,6 +86,7 @@ inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
 inline bool hasOptimizableIndexing(Structure* structure)
 {
     return isOptimizableIndexingType(structure->indexingType())
+        || hasOptimizableIndexingForJSType(structure->typeInfo().type())
         || hasOptimizableIndexingForClassInfo(structure->classInfo());
 }
 
@@ -93,6 +107,19 @@ inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType)
     }
 }
 
+inline JITArrayMode jitArrayModeForJSType(JSType type)
+{
+    switch (type) {
+    case DirectArgumentsType:
+        return JITDirectArguments;
+    case ScopedArgumentsType:
+        return JITScopedArguments;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return JITContiguous;
+    }
+}
+
 inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
 {
     switch (classInfo->typedArrayStorageType) {
@@ -120,6 +147,19 @@ inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
     }
 }
 
+inline bool jitArrayModePermitsPut(JITArrayMode mode)
+{
+    switch (mode) {
+    case JITDirectArguments:
+    case JITScopedArguments:
+        // We could support put_by_val on these at some point, but it's just not that profitable
+        // at the moment.
+        return false;
+    default:
+        return true;
+    }
+}
+
 inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
 {
     switch (mode) {
@@ -152,6 +192,9 @@ inline JITArrayMode jitArrayModeForStructure(Structure* structure)
     if (isOptimizableIndexingType(structure->indexingType()))
         return jitArrayModeForIndexingType(structure->indexingType());
     
+    if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
+        return jitArrayModeForJSType(structure->typeInfo().type());
+    
     ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
     return jitArrayModeForClassInfo(structure->classInfo());
 }
index 95a7472209548cf025175086e7d36e36d80962c3..961eadb6a7d661b1b5e57c575691f230e2dae988 100644 (file)
@@ -52,8 +52,6 @@ static bool isBranch(OpcodeID opcodeID)
     case op_switch_imm:
     case op_switch_char:
     case op_switch_string:
-    case op_get_pnames:
-    case op_next_pname:
     case op_check_has_instance:
         return true;
     default:
@@ -75,7 +73,6 @@ static bool isTerminal(OpcodeID opcodeID)
 {
     switch (opcodeID) {
     case op_ret:
-    case op_ret_object_or_this:
     case op_end:
         return true;
     default:
diff --git a/bytecode/BytecodeIntrinsicRegistry.cpp b/bytecode/BytecodeIntrinsicRegistry.cpp
new file mode 100644 (file)
index 0000000..83f93c6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BytecodeIntrinsicRegistry.h"
+
+#include "CommonIdentifiers.h"
+#include "Nodes.h"
+
+namespace JSC {
+
+#define INITIALISE_BYTECODE_INTRINSIC_NAMES_TO_SET(name) m_bytecodeIntrinsicMap.add(propertyNames.name##PrivateName.impl(), &BytecodeIntrinsicNode::emit_intrinsic_##name);
+
+BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry(const CommonIdentifiers& propertyNames)
+    : m_propertyNames(propertyNames)
+    , m_bytecodeIntrinsicMap()
+{
+    JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(INITIALISE_BYTECODE_INTRINSIC_NAMES_TO_SET)
+}
+
+BytecodeIntrinsicNode::EmitterType BytecodeIntrinsicRegistry::lookup(const Identifier& ident) const
+{
+    if (!m_propertyNames.isPrivateName(ident))
+        return nullptr;
+    auto iterator = m_bytecodeIntrinsicMap.find(ident.impl());
+    if (iterator == m_bytecodeIntrinsicMap.end())
+        return nullptr;
+    return iterator->value;
+}
+
+} // namespace JSC
+
diff --git a/bytecode/BytecodeIntrinsicRegistry.h b/bytecode/BytecodeIntrinsicRegistry.h
new file mode 100644 (file)
index 0000000..87a578c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BytecodeIntrinsicRegistry_h
+#define BytecodeIntrinsicRegistry_h
+
+#include "Identifier.h"
+#include <wtf/HashTable.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class CommonIdentifiers;
+class BytecodeGenerator;
+class BytecodeIntrinsicNode;
+class RegisterID;
+
+class BytecodeIntrinsicRegistry {
+    WTF_MAKE_NONCOPYABLE(BytecodeIntrinsicRegistry);
+public:
+    explicit BytecodeIntrinsicRegistry(const CommonIdentifiers&);
+
+    typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
+
+    EmitterType lookup(const Identifier&) const;
+
+private:
+    const CommonIdentifiers& m_propertyNames;
+    HashMap<RefPtr<UniquedStringImpl>, EmitterType, IdentifierRepHash> m_bytecodeIntrinsicMap;
+};
+
+} // namespace JSC
+
+#endif // BytecodeIntrinsicRegistry_h
diff --git a/bytecode/BytecodeKills.h b/bytecode/BytecodeKills.h
new file mode 100644 (file)
index 0000000..6e504a6
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BytecodeKills_h
+#define BytecodeKills_h
+
+#include "CodeBlock.h"
+#include <wtf/FastBitVector.h>
+
+namespace JSC {
+
+class BytecodeLivenessAnalysis;
+
+class BytecodeKills {
+public:
+    BytecodeKills()
+        : m_codeBlock(nullptr)
+    {
+    }
+    
+    // By convention, we say that non-local operands are never killed.
+    bool operandIsKilled(unsigned bytecodeIndex, int operand) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(bytecodeIndex < m_codeBlock->instructions().size());
+        VirtualRegister reg(operand);
+        if (reg.isLocal())
+            return m_killSets[bytecodeIndex].contains(operand);
+        return false;
+    }
+    
+    bool operandIsKilled(Instruction* instruction, int operand) const
+    {
+        return operandIsKilled(instruction - m_codeBlock->instructions().begin(), operand);
+    }
+    
+    template<typename Functor>
+    void forEachOperandKilledAt(unsigned bytecodeIndex, const Functor& functor) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(bytecodeIndex < m_codeBlock->instructions().size());
+        m_killSets[bytecodeIndex].forEachLocal(
+            [&] (unsigned local) {
+                functor(virtualRegisterForLocal(local));
+            });
+    }
+    
+    template<typename Functor>
+    void forEachOperandKilledAt(Instruction* pc, const Functor& functor) const
+    {
+        forEachOperandKilledAt(pc - m_codeBlock->instructions().begin(), functor);
+    }
+    
+private:
+    friend class BytecodeLivenessAnalysis;
+
+    class KillSet {
+    public:
+        KillSet()
+            : m_word(0)
+        {
+        }
+
+        ~KillSet()
+        {
+            if (hasVector())
+                delete vector();
+        }
+        
+        void add(unsigned local)
+        {
+            if (isEmpty()) {
+                setOneItem(local);
+                return;
+            }
+            if (hasOneItem()) {
+                ASSERT(oneItem() != local);
+                Vector<unsigned>* vector = new Vector<unsigned>();
+                vector->append(oneItem());
+                vector->append(local);
+                setVector(vector);
+                return;
+            }
+            ASSERT(!vector()->contains(local));
+            vector()->append(local);
+        }
+        
+        template<typename Functor>
+        void forEachLocal(const Functor& functor)
+        {
+            if (isEmpty())
+                return;
+            if (hasOneItem()) {
+                functor(oneItem());
+                return;
+            }
+            for (unsigned local : *vector())
+                functor(local);
+        }
+        
+        bool contains(unsigned expectedLocal)
+        {
+            if (isEmpty())
+                return false;
+            if (hasOneItem())
+                return oneItem() == expectedLocal;
+            for (unsigned local : *vector()) {
+                if (local == expectedLocal)
+                    return true;
+            }
+            return false;
+        }
+        
+    private:
+        bool isEmpty() const
+        {
+            return !m_word;
+        }
+        
+        bool hasOneItem() const
+        {
+            return m_word & 1;
+        }
+        
+        unsigned oneItem() const
+        {
+            return m_word >> 1;
+        }
+        
+        void setOneItem(unsigned value)
+        {
+            m_word = (value << 1) | 1;
+        }
+        
+        bool hasVector() const
+        {
+            return !isEmpty() && !hasOneItem();
+        }
+        
+        Vector<unsigned>* vector()
+        {
+            return bitwise_cast<Vector<unsigned>*>(m_word);
+        }
+        
+        void setVector(Vector<unsigned>* value)
+        {
+            m_word = bitwise_cast<uintptr_t>(value);
+        }
+        
+        uintptr_t m_word;
+    };
+    
+    CodeBlock* m_codeBlock;
+    std::unique_ptr<KillSet[]> m_killSets;
+};
+
+} // namespace JSC
+
+#endif // BytecodeKills_h
+
index dce81e7f219d181bc0b0eca1f24f1a70933ac42f..9a1fdd1be2039ccfa3d26fa1d772ac0f91ad880d 100644 (file)
@@ -4,20 +4,20 @@
         "macroNameComponent" : "BYTECODE", "asmPrefix" : "llint_", 
         "bytecodes" : [
             { "name" : "op_enter", "length" : 1 },
-            { "name" : "op_create_activation", "length" : 2 },
-            { "name" : "op_touch_entry", "length" : 1 },
-            { "name" : "op_init_lazy_reg", "length" : 2 },
-            { "name" : "op_create_arguments", "length" : 2 },
-            { "name" : "op_create_this", "length" : 4 },
-            { "name" : "op_get_callee", "length" : 3 },
-            { "name" : "op_to_this", "length" : 3 },
+            { "name" : "op_create_lexical_environment", "length" : 3 },
+            { "name" : "op_get_scope", "length" : 2 },
+            { "name" : "op_create_direct_arguments", "length" : 2 },
+            { "name" : "op_create_scoped_arguments", "length" : 3 },
+            { "name" : "op_create_out_of_band_arguments", "length" : 2 },
+            { "name" : "op_create_this", "length" : 5 },
+            { "name" : "op_to_this", "length" : 4 },
+            { "name" : "op_check_tdz", "length" : 2 },
             { "name" : "op_new_object", "length" : 4 },
             { "name" : "op_new_array", "length" : 5 },
             { "name" : "op_new_array_with_size", "length" : 4 },
             { "name" : "op_new_array_buffer", "length" : 5 },
             { "name" : "op_new_regexp", "length" : 3 },
             { "name" : "op_mov", "length" : 3 },
-            { "name" : "op_captured_mov", "length" : 4 },
             { "name" : "op_not", "length" : 3 },
             { "name" : "op_eq", "length" : 4 },
             { "name" : "op_eq_null", "length" : 3 },
@@ -32,6 +32,7 @@
             { "name" : "op_inc", "length" : 2 },
             { "name" : "op_dec", "length" : 2 },
             { "name" : "op_to_number", "length" : 3 },
+            { "name" : "op_to_string", "length" : 3 },
             { "name" : "op_negate", "length" : 3 },
             { "name" : "op_add", "length" : 5 },
             { "name" : "op_mul", "length" : 5 },
@@ -53,6 +54,7 @@
             { "name" : "op_is_number", "length" : 3 },
             { "name" : "op_is_string", "length" : 3 },
             { "name" : "op_is_object", "length" : 3 },
+            { "name" : "op_is_object_or_null", "length" : 3 },
             { "name" : "op_is_function", "length" : 3 },
             { "name" : "op_in", "length" : 4 },
             { "name" : "op_init_global_const_nop", "length" : 5 },
@@ -60,7 +62,6 @@
             { "name" : "op_get_by_id", "length" : 9  },
             { "name" : "op_get_by_id_out_of_line", "length" : 9  },
             { "name" : "op_get_array_length", "length" : 9 },
-            { "name" : "op_get_arguments_length", "length" : 4 },
             { "name" : "op_put_by_id", "length" : 9 },
             { "name" : "op_put_by_id_out_of_line", "length" : 9 },
             { "name" : "op_put_by_id_transition_direct", "length" : 9 },
             { "name" : "op_put_by_id_transition_normal_out_of_line", "length" : 9 },
             { "name" : "op_del_by_id", "length" : 4 },
             { "name" : "op_get_by_val", "length" : 6 },
-            { "name" : "op_get_argument_by_val", "length" : 6 },
-            { "name" : "op_get_by_pname", "length" : 7 },
             { "name" : "op_put_by_val", "length" : 5 },
             { "name" : "op_put_by_val_direct", "length" : 5 },
             { "name" : "op_del_by_val", "length" : 4 },
             { "name" : "op_put_by_index", "length" : 4 },
+            { "name" : "op_put_getter_by_id", "length" : 4 },
+            { "name" : "op_put_setter_by_id", "length" : 4 },
             { "name" : "op_put_getter_setter", "length" : 5 },
             { "name" : "op_jmp", "length" : 2 },
             { "name" : "op_jtrue", "length" : 3 },
             { "name" : "op_switch_char", "length" : 4 },
             { "name" : "op_switch_string", "length" : 4 },
             { "name" : "op_new_func", "length" : 4 },
-            { "name" : "op_new_captured_func", "length" : 4 },
-            { "name" : "op_new_func_exp", "length" : 3 },
+            { "name" : "op_new_func_exp", "length" : 4 },
             { "name" : "op_call", "length" : 9 },
             { "name" : "op_call_eval", "length" : 9 },
             { "name" : "op_call_varargs", "length" : 9 },
-            { "name" : "op_tear_off_activation", "length" : 2 },
-            { "name" : "op_tear_off_arguments", "length" : 3 },
             { "name" : "op_ret", "length" : 2 },
-            { "name" : "op_ret_object_or_this", "length" : 3 },
             { "name" : "op_construct", "length" : 9 },
             { "name" : "op_construct_varargs", "length" : 9 },
             { "name" : "op_strcat", "length" : 4 },
             { "name" : "op_to_primitive", "length" : 3 },
-            { "name" : "op_get_pnames", "length" : 6 },
-            { "name" : "op_next_pname", "length" : 7 },
-            { "name" : "op_resolve_scope", "length" : 6 },
+            { "name" : "op_resolve_scope", "length" : 7 },
             { "name" : "op_get_from_scope", "length" : 8 },
             { "name" : "op_put_to_scope", "length" : 7 },
-            { "name" : "op_push_with_scope", "length" : 2 },
-            { "name" : "op_pop_scope", "length" : 1 },
-            { "name" : "op_push_name_scope", "length" : 4 },
-            { "name" : "op_catch", "length" : 2 },
+            { "name" : "op_get_from_arguments", "length" : 5 },
+            { "name" : "op_put_to_arguments", "length" : 4 },
+            { "name" : "op_push_with_scope", "length" : 3 },
+            { "name" : "op_pop_scope", "length" : 2 },
+            { "name" : "op_push_name_scope", "length" : 5 },
+            { "name" : "op_catch", "length" : 3 },
             { "name" : "op_throw", "length" : 2 },
             { "name" : "op_throw_static_error", "length" : 3 },
             { "name" : "op_debug", "length" : 3 },
             { "name" : "op_profile_will_call", "length" : 2 },
             { "name" : "op_profile_did_call", "length" : 2 },
-            { "name" : "op_end", "length" : 2 }
+            { "name" : "op_end", "length" : 2 },
+            { "name" : "op_profile_type", "length" : 6 },
+            { "name" : "op_profile_control_flow", "length" : 2 },
+            { "name" : "op_get_enumerable_length", "length" : 3 },
+            { "name" : "op_has_indexed_property", "length" : 5 },
+            { "name" : "op_has_structure_property", "length" : 5 },
+            { "name" : "op_has_generic_property", "length" : 4 },
+            { "name" : "op_get_direct_pname", "length" : 7 },
+            { "name" : "op_get_property_enumerator", "length" : 3 },
+            { "name" : "op_enumerator_structure_pname", "length" : 4 },
+            { "name" : "op_enumerator_generic_pname", "length" : 4 },
+            { "name" : "op_to_index_string", "length" : 3 }
         ]
     },
     {
             { "name" : "llint_entry" },
             { "name" : "getHostCallReturnValue" },
             { "name" : "llint_return_to_host" },
-            { "name" : "llint_call_to_javascript" },
-            { "name" : "llint_call_to_native_function" },
+            { "name" : "llint_vm_entry_to_javascript" },
+            { "name" : "llint_vm_entry_to_native" },
             { "name" : "llint_cloop_did_return_from_js_1" },
             { "name" : "llint_cloop_did_return_from_js_2" },
             { "name" : "llint_cloop_did_return_from_js_3" },
index 926334c444c9c2f3dfcc95012cd0a4a03104d2d9..80173ac22616fa40e1dbcaec525e23e6ca093d05 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "BytecodeLivenessAnalysis.h"
 
+#include "BytecodeKills.h"
 #include "BytecodeLivenessAnalysisInlines.h"
 #include "BytecodeUseDef.h"
 #include "CodeBlock.h"
@@ -47,48 +48,9 @@ static bool isValidRegisterForLiveness(CodeBlock* codeBlock, int operand)
         return false;
     
     VirtualRegister virtualReg(operand);
-    if (!virtualReg.isLocal())
-        return false;
-    
-    if (codeBlock->captureCount()
-        && operand <= codeBlock->captureStart()
-        && operand > codeBlock->captureEnd())
-        return false;
-    
-    return true;
-}
-
-static void setForOperand(CodeBlock* codeBlock, FastBitVector& bits, int operand)
-{
-    ASSERT(isValidRegisterForLiveness(codeBlock, operand));
-    VirtualRegister virtualReg(operand);
-    if (virtualReg.offset() > codeBlock->captureStart())
-        bits.set(virtualReg.toLocal());
-    else
-        bits.set(virtualReg.toLocal() - codeBlock->captureCount());
+    return virtualReg.isLocal();
 }
 
-namespace {
-
-class SetBit {
-public:
-    SetBit(FastBitVector& bits)
-        : m_bits(bits)
-    {
-    }
-    
-    void operator()(CodeBlock* codeBlock, Instruction*, OpcodeID, int operand)
-    {
-        if (isValidRegisterForLiveness(codeBlock, operand))
-            setForOperand(codeBlock, m_bits, operand);
-    }
-    
-private:
-    FastBitVector& m_bits;
-};
-
-} // anonymous namespace
-
 static unsigned getLeaderOffsetForBasicBlock(RefPtr<BytecodeBasicBlock>* basicBlock)
 {
     return (*basicBlock)->leaderBytecodeOffset();
@@ -133,28 +95,63 @@ static BytecodeBasicBlock* findBasicBlockForBytecodeOffset(Vector<RefPtr<Bytecod
     return basicBlock[1].get();
 }
 
-static void stepOverInstruction(CodeBlock* codeBlock, Vector<RefPtr<BytecodeBasicBlock>>& basicBlocks, unsigned bytecodeOffset, FastBitVector& uses, FastBitVector& defs, FastBitVector& out)
+// Simplified interface to bytecode use/def, which determines defs first and then uses, and includes
+// exception handlers in the uses.
+template<typename UseFunctor, typename DefFunctor>
+static void stepOverInstruction(CodeBlock* codeBlock, Vector<RefPtr<BytecodeBasicBlock>>& basicBlocks, unsigned bytecodeOffset, const UseFunctor& use, const DefFunctor& def)
 {
-    uses.clearAll();
-    defs.clearAll();
-    
-    SetBit setUses(uses);
-    SetBit setDefs(defs);
-    computeUsesForBytecodeOffset(codeBlock, bytecodeOffset, setUses);
-    computeDefsForBytecodeOffset(codeBlock, bytecodeOffset, setDefs);
-    
-    out.exclude(defs);
-    out.merge(uses);
+    // This abstractly execute the instruction in reverse. Instructions logically first use operands and
+    // then define operands. This logical ordering is necessary for operations that use and def the same
+    // operand, like:
+    //
+    //     op_add loc1, loc1, loc2
+    //
+    // The use of loc1 happens before the def of loc1. That's a semantic requirement since the add
+    // operation cannot travel forward in time to read the value that it will produce after reading that
+    // value. Since we are executing in reverse, this means that we must do defs before uses (reverse of
+    // uses before defs).
+    //
+    // Since this is a liveness analysis, this ordering ends up being particularly important: if we did
+    // uses before defs, then the add operation above would appear to not have loc1 live, since we'd
+    // first add it to the out set (the use), and then we'd remove it (the def).
     
+    computeDefsForBytecodeOffset(
+        codeBlock, bytecodeOffset,
+        [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
+            if (isValidRegisterForLiveness(codeBlock, operand))
+                def(VirtualRegister(operand).toLocal());
+        });
+
+    computeUsesForBytecodeOffset(
+        codeBlock, bytecodeOffset,
+        [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
+            if (isValidRegisterForLiveness(codeBlock, operand))
+                use(VirtualRegister(operand).toLocal());
+        });
+        
     // If we have an exception handler, we want the live-in variables of the 
     // exception handler block to be included in the live-in of this particular bytecode.
     if (HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset)) {
         BytecodeBasicBlock* handlerBlock = findBasicBlockWithLeaderOffset(basicBlocks, handler->target);
         ASSERT(handlerBlock);
-        out.merge(handlerBlock->in());
+        handlerBlock->in().forEachSetBit(use);
     }
 }
 
+static void stepOverInstruction(CodeBlock* codeBlock, Vector<RefPtr<BytecodeBasicBlock>>& basicBlocks, unsigned bytecodeOffset, FastBitVector& out)
+{
+    stepOverInstruction(
+        codeBlock, basicBlocks, bytecodeOffset,
+        [&] (unsigned bitIndex) {
+            // This is the use functor, so we set the bit.
+            out.set(bitIndex);
+        },
+        [&] (unsigned bitIndex) {
+            // This is the def functor, so we clear the bit.
+            out.clear(bitIndex);
+        });
+}
+
 static void computeLocalLivenessForBytecodeOffset(CodeBlock* codeBlock, BytecodeBasicBlock* block, Vector<RefPtr<BytecodeBasicBlock> >& basicBlocks, unsigned targetOffset, FastBitVector& result)
 {
     ASSERT(!block->isExitBlock());
@@ -162,17 +159,12 @@ static void computeLocalLivenessForBytecodeOffset(CodeBlock* codeBlock, Bytecode
 
     FastBitVector out = block->out();
 
-    FastBitVector uses;
-    FastBitVector defs;
-    uses.resize(out.numBits());
-    defs.resize(out.numBits());
-
     for (int i = block->bytecodeOffsets().size() - 1; i >= 0; i--) {
         unsigned bytecodeOffset = block->bytecodeOffsets()[i];
         if (targetOffset > bytecodeOffset)
             break;
         
-        stepOverInstruction(codeBlock, basicBlocks, bytecodeOffset, uses, defs, out);
+        stepOverInstruction(codeBlock, basicBlocks, bytecodeOffset, out);
     }
 
     result.set(out);
@@ -188,8 +180,7 @@ static void computeLocalLivenessForBlock(CodeBlock* codeBlock, BytecodeBasicBloc
 void BytecodeLivenessAnalysis::runLivenessFixpoint()
 {
     UnlinkedCodeBlock* unlinkedCodeBlock = m_codeBlock->unlinkedCodeBlock();
-    unsigned numberOfVariables =
-        unlinkedCodeBlock->m_numCalleeRegisters - m_codeBlock->captureCount();
+    unsigned numberOfVariables = unlinkedCodeBlock->m_numCalleeRegisters;
 
     for (unsigned i = 0; i < m_basicBlocks.size(); i++) {
         BytecodeBasicBlock* block = m_basicBlocks[i].get();
@@ -204,7 +195,7 @@ void BytecodeLivenessAnalysis::runLivenessFixpoint()
     newOut.resize(m_basicBlocks.last()->out().numBits());
     do {
         changed = false;
-        for (int i = m_basicBlocks.size() - 2; i >= 0; i--) {
+        for (unsigned i = m_basicBlocks.size() - 1; i--;) {
             BytecodeBasicBlock* block = m_basicBlocks[i].get();
             newOut.clearAll();
             for (unsigned j = 0; j < block->successors().size(); j++)
@@ -216,7 +207,7 @@ void BytecodeLivenessAnalysis::runLivenessFixpoint()
     } while (changed);
 }
 
-void BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
+void BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
 {
     BytecodeBasicBlock* block = findBasicBlockForBytecodeOffset(m_basicBlocks, bytecodeOffset);
     ASSERT(block);
@@ -228,60 +219,47 @@ void BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset
 
 bool BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset)
 {
-    if (operandIsAlwaysLive(m_codeBlock, operand))
+    if (operandIsAlwaysLive(operand))
         return true;
     FastBitVector result;
-    getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, result);
-    return operandThatIsNotAlwaysLiveIsLive(m_codeBlock, result, operand);
+    getLivenessInfoAtBytecodeOffset(bytecodeOffset, result);
+    return operandThatIsNotAlwaysLiveIsLive(result, operand);
 }
 
-FastBitVector getLivenessInfo(CodeBlock* codeBlock, const FastBitVector& out)
+FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
 {
-    FastBitVector result;
-
-    unsigned numCapturedVars = codeBlock->captureCount();
-    if (numCapturedVars) {
-        int firstCapturedLocal = VirtualRegister(codeBlock->captureStart()).toLocal();
-        result.resize(out.numBits() + numCapturedVars);
-        for (unsigned i = 0; i < numCapturedVars; ++i)
-            result.set(firstCapturedLocal + i);
-    } else
-        result.resize(out.numBits());
-
-    int outLength = out.numBits();
-    ASSERT(outLength >= 0);
-    for (int i = 0; i < outLength; i++) {
-        if (!out.get(i))
-            continue;
-
-        if (!numCapturedVars) {
-            result.set(i);
-            continue;
-        }
-
-        if (virtualRegisterForLocal(i).offset() > codeBlock->captureStart())
-            result.set(i);
-        else 
-            result.set(numCapturedVars + i);
-    }
-    return result;
+    FastBitVector out;
+    getLivenessInfoAtBytecodeOffset(bytecodeOffset, out);
+    return out;
 }
 
-FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
+void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
 {
     FastBitVector out;
-    getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, out);
-    return getLivenessInfo(m_codeBlock, out);
+    
+    result.m_map.resize(m_codeBlock->instructions().size());
+    
+    for (unsigned i = m_basicBlocks.size(); i--;) {
+        BytecodeBasicBlock* block = m_basicBlocks[i].get();
+        if (block->isEntryBlock() || block->isExitBlock())
+            continue;
+        
+        out = block->out();
+        
+        for (unsigned i = block->bytecodeOffsets().size(); i--;) {
+            unsigned bytecodeOffset = block->bytecodeOffsets()[i];
+            stepOverInstruction(m_codeBlock, m_basicBlocks, bytecodeOffset, out);
+            result.m_map[bytecodeOffset] = out;
+        }
+    }
 }
 
-void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
+void BytecodeLivenessAnalysis::computeKills(BytecodeKills& result)
 {
     FastBitVector out;
-    FastBitVector uses;
-    FastBitVector defs;
     
     result.m_codeBlock = m_codeBlock;
-    result.m_map.clear();
+    result.m_killSets = std::make_unique<BytecodeKills::KillSet[]>(m_codeBlock->instructions().size());
     
     for (unsigned i = m_basicBlocks.size(); i--;) {
         BytecodeBasicBlock* block = m_basicBlocks[i].get();
@@ -289,13 +267,22 @@ void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
             continue;
         
         out = block->out();
-        uses.resize(out.numBits());
-        defs.resize(out.numBits());
         
         for (unsigned i = block->bytecodeOffsets().size(); i--;) {
             unsigned bytecodeOffset = block->bytecodeOffsets()[i];
-            stepOverInstruction(m_codeBlock, m_basicBlocks, bytecodeOffset, uses, defs, out);
-            result.m_map.add(bytecodeOffset, out);
+            stepOverInstruction(
+                m_codeBlock, m_basicBlocks, bytecodeOffset,
+                [&] (unsigned index) {
+                    // This is for uses.
+                    if (out.get(index))
+                        return;
+                    result.m_killSets[bytecodeOffset].add(index);
+                    out.set(index);
+                },
+                [&] (unsigned index) {
+                    // This is for defs.
+                    out.clear(index);
+                });
         }
     }
 }
index 349912175a093db2b7f8ff641ae604cfcd032b53..3f42c4431ed21fa88188cb89edf558fc756e66a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 
 namespace JSC {
 
+class BytecodeKills;
 class CodeBlock;
 class FullBytecodeLiveness;
 
@@ -44,23 +45,22 @@ public:
     FastBitVector getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset);
     
     void computeFullLiveness(FullBytecodeLiveness& result);
+    void computeKills(BytecodeKills& result);
 
 private:
     void compute();
     void runLivenessFixpoint();
     void dumpResults();
 
-    void getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
+    void getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
 
     CodeBlock* m_codeBlock;
     Vector<RefPtr<BytecodeBasicBlock> > m_basicBlocks;
 };
 
-inline bool operandIsAlwaysLive(CodeBlock*, int operand);
-inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock*, const FastBitVector& out, int operand);
-inline bool operandIsLive(CodeBlock*, const FastBitVector& out, int operand);
-
-FastBitVector getLivenessInfo(CodeBlock*, const FastBitVector& out);
+inline bool operandIsAlwaysLive(int operand);
+inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand);
+inline bool operandIsLive(const FastBitVector& out, int operand);
 
 } // namespace JSC
 
index 6587cd297002317dc1826484e4051177da37b22c..9b5c755fcb6cd518051450078922ac4d6d4d238f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-inline bool operandIsAlwaysLive(CodeBlock* codeBlock, int operand)
+inline bool operandIsAlwaysLive(int operand)
 {
-    if (VirtualRegister(operand).isArgument())
-        return true;
-    return operand <= codeBlock->captureStart() && operand > codeBlock->captureEnd();
+    return !VirtualRegister(operand).isLocal();
 }
 
-inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
+inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand)
 {
-    VirtualRegister virtualReg(operand);
-    if (virtualReg.offset() > codeBlock->captureStart())
-        return out.get(virtualReg.toLocal());
-    size_t index = virtualReg.toLocal() - codeBlock->captureCount();
-    if (index >= out.numBits())
+    unsigned local = VirtualRegister(operand).toLocal();
+    if (local >= out.numBits())
         return false;
-    return out.get(index);
+    return out.get(local);
 }
 
-inline bool operandIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
+inline bool operandIsLive(const FastBitVector& out, int operand)
 {
-    return operandIsAlwaysLive(codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(codeBlock, out, operand);
+    return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(out, operand);
 }
 
 } // namespace JSC
index 92449f98d987b3dccb23f43bf08242162871a98c..250d322ce1c0d4239eb7dfd4161f149ce5d8fcc0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,7 @@ namespace JSC {
 
 template<typename Functor>
 void computeUsesForBytecodeOffset(
-    CodeBlock* codeBlock, unsigned bytecodeOffset, Functor& functor)
+    CodeBlock* codeBlock, unsigned bytecodeOffset, const Functor& functor)
 {
     Interpreter* interpreter = codeBlock->vm()->interpreter;
     Instruction* instructionsBegin = codeBlock->instructions().begin();
@@ -44,29 +44,24 @@ void computeUsesForBytecodeOffset(
     case op_new_array_buffer:
     case op_throw_static_error:
     case op_debug:
-    case op_resolve_scope:
-    case op_pop_scope:
     case op_jneq_ptr:
-    case op_new_func_exp:
     case op_loop_hint:
     case op_jmp:
     case op_new_object:
-    case op_init_lazy_reg:
-    case op_get_callee:
     case op_enter:
     case op_catch:
-    case op_touch_entry:
+    case op_profile_control_flow:
+    case op_create_direct_arguments:
+    case op_create_out_of_band_arguments:
         return;
-    case op_new_func:
-    case op_new_captured_func:
-    case op_create_activation: 
-    case op_create_arguments:
+    case op_get_scope:
     case op_to_this:
-    case op_tear_off_activation:
+    case op_check_tdz:
+    case op_pop_scope:
     case op_profile_will_call:
     case op_profile_did_call:
+    case op_profile_type:
     case op_throw:
-    case op_push_with_scope:
     case op_end:
     case op_ret:
     case op_jtrue:
@@ -78,7 +73,6 @@ void computeUsesForBytecodeOffset(
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         return;
     }
-    case op_ret_object_or_this:
     case op_jlesseq:
     case op_jgreater:
     case op_jgreatereq:
@@ -105,7 +99,10 @@ void computeUsesForBytecodeOffset(
     case op_put_by_id_transition_normal_out_of_line:
     case op_put_by_id_out_of_line:
     case op_put_by_id:
-    case op_put_to_scope: {
+    case op_put_getter_by_id:
+    case op_put_setter_by_id:
+    case op_put_to_scope:
+    case op_put_to_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
         return;
@@ -116,39 +113,51 @@ void computeUsesForBytecodeOffset(
         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
         return;
     }
+    case op_create_lexical_environment:
+    case op_get_property_enumerator:
+    case op_get_enumerable_length:
+    case op_new_func_exp:
+    case op_to_index_string:
     case op_init_global_const_nop:
     case op_init_global_const:
     case op_push_name_scope:
+    case op_push_with_scope:
+    case op_resolve_scope:
     case op_get_from_scope:
     case op_to_primitive:
     case op_get_by_id:
     case op_get_by_id_out_of_line:
     case op_get_array_length:
-    case op_get_arguments_length:
     case op_typeof:
     case op_is_undefined:
     case op_is_boolean:
     case op_is_number:
     case op_is_string:
     case op_is_object:
+    case op_is_object_or_null:
     case op_is_function:
     case op_to_number:
+    case op_to_string:
     case op_negate:
     case op_neq_null:
     case op_eq_null:
     case op_not:
     case op_mov:
-    case op_captured_mov:
     case op_new_array_with_size:
     case op_create_this:
-    case op_get_pnames:
     case op_del_by_id:
-    case op_unsigned: {
+    case op_unsigned:
+    case op_new_func:
+    case op_create_scoped_arguments:
+    case op_get_from_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
         return;
     }
+    case op_has_generic_property:
+    case op_has_indexed_property:
+    case op_enumerator_structure_pname:
+    case op_enumerator_generic_pname:
     case op_get_by_val:
-    case op_get_argument_by_val:
     case op_in:
     case op_instanceof:
     case op_check_has_instance:
@@ -176,6 +185,7 @@ void computeUsesForBytecodeOffset(
         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
         return;
     }
+    case op_has_structure_property:
     case op_construct_varargs:
     case op_call_varargs: {
         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
@@ -183,19 +193,11 @@ void computeUsesForBytecodeOffset(
         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
         return;
     }
-    case op_next_pname: {
-        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
-        return;
-    }
-    case op_get_by_pname: {
+    case op_get_direct_pname: {
         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
         functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[6].u.operand);
         return;
     }
     case op_switch_string:
@@ -219,16 +221,10 @@ void computeUsesForBytecodeOffset(
         int argCount = instruction[3].u.operand;
         int registerOffset = -instruction[4].u.operand;
         int lastArg = registerOffset + CallFrame::thisArgumentOffset();
-        for (int i = opcodeID == op_construct ? 1 : 0; i < argCount; i++)
+        for (int i = 0; i < argCount; i++)
             functor(codeBlock, instruction, opcodeID, lastArg + i);
         return;
     }
-    case op_tear_off_arguments: {
-        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
-        functor(codeBlock, instruction, opcodeID, unmodifiedArgumentsRegister(VirtualRegister(instruction[1].u.operand)).offset());
-        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
-        return;
-    }
     default:
         RELEASE_ASSERT_NOT_REACHED();
         break;
@@ -236,7 +232,7 @@ void computeUsesForBytecodeOffset(
 }
 
 template<typename Functor>
-void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, Functor& functor)
+void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, const Functor& functor)
 {
     Interpreter* interpreter = codeBlock->vm()->interpreter;
     Instruction* instructionsBegin = codeBlock->instructions().begin();
@@ -246,10 +242,7 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     // These don't define anything.
     case op_init_global_const:
     case op_init_global_const_nop:
-    case op_push_name_scope:
-    case op_push_with_scope:
     case op_put_to_scope:
-    case op_pop_scope:
     case op_end:
     case op_profile_will_call:
     case op_profile_did_call:
@@ -257,7 +250,6 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     case op_throw_static_error:
     case op_debug:
     case op_ret:
-    case op_ret_object_or_this:
     case op_jmp:
     case op_jtrue:
     case op_jfalse:
@@ -282,30 +274,41 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     case op_put_by_id_transition_direct_out_of_line:
     case op_put_by_id_transition_normal:
     case op_put_by_id_transition_normal_out_of_line:
+    case op_put_getter_by_id:
+    case op_put_setter_by_id:
     case op_put_getter_setter:
     case op_put_by_val:
     case op_put_by_val_direct:
     case op_put_by_index:
-    case op_tear_off_arguments:
-    case op_touch_entry:
+    case op_profile_type:
+    case op_profile_control_flow:
+    case op_put_to_arguments:
 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
 #undef LLINT_HELPER_OPCODES
         return;
     // These all have a single destination for the first argument.
-    case op_next_pname:
+    case op_to_index_string:
+    case op_get_enumerable_length:
+    case op_has_indexed_property:
+    case op_has_structure_property:
+    case op_has_generic_property:
+    case op_get_direct_pname:
+    case op_get_property_enumerator:
+    case op_enumerator_structure_pname:
+    case op_enumerator_generic_pname:
+    case op_pop_scope:
+    case op_push_name_scope:
+    case op_push_with_scope:
     case op_resolve_scope:
     case op_strcat:
-    case op_tear_off_activation:
     case op_to_primitive:
-    case op_catch:
     case op_create_this:
     case op_new_array:
     case op_new_array_buffer:
     case op_new_array_with_size:
     case op_new_regexp:
     case op_new_func:
-    case op_new_captured_func:
     case op_new_func_exp:
     case op_call_varargs:
     case op_construct_varargs:
@@ -319,18 +322,17 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     case op_check_has_instance:
     case op_instanceof:
     case op_get_by_val:
-    case op_get_argument_by_val:
-    case op_get_by_pname:
-    case op_get_arguments_length:
     case op_typeof:
     case op_is_undefined:
     case op_is_boolean:
     case op_is_number:
     case op_is_string:
     case op_is_object:
+    case op_is_object_or_null:
     case op_is_function:
     case op_in:
     case op_to_number:
+    case op_to_string:
     case op_negate:
     case op_add:
     case op_mul:
@@ -357,23 +359,24 @@ void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset,
     case op_eq_null:
     case op_not:
     case op_mov:
-    case op_captured_mov:
     case op_new_object:
     case op_to_this:
-    case op_get_callee:
-    case op_init_lazy_reg:
-    case op_create_activation:
-    case op_create_arguments:
+    case op_check_tdz:
+    case op_get_scope:
+    case op_create_direct_arguments:
+    case op_create_scoped_arguments:
+    case op_create_out_of_band_arguments:
     case op_del_by_id:
     case op_del_by_val:
-    case op_unsigned: {
+    case op_unsigned:
+    case op_get_from_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         return;
     }
-    case op_get_pnames: {
+    case op_catch:
+    case op_create_lexical_environment: {
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
-        functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
         return;
     }
     case op_enter: {
diff --git a/bytecode/CallEdge.cpp b/bytecode/CallEdge.cpp
new file mode 100644 (file)
index 0000000..dffff6d
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CallEdge.h"
+
+namespace JSC {
+
+void CallEdge::dump(PrintStream& out) const
+{
+    out.print("<", m_callee, ", count: ", m_count, ">");
+}
+
+} // namespace JSC
+
diff --git a/bytecode/CallEdge.h b/bytecode/CallEdge.h
new file mode 100644 (file)
index 0000000..3045209
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CallEdge_h
+#define CallEdge_h
+
+#include "CallVariant.h"
+
+namespace JSC {
+
+class CallEdge {
+public:
+    CallEdge();
+    CallEdge(CallVariant, uint32_t);
+    
+    bool operator!() const { return !m_callee; }
+    
+    CallVariant callee() const { return m_callee; }
+    uint32_t count() const { return m_count; }
+    
+    CallEdge despecifiedClosure() const
+    {
+        return CallEdge(m_callee.despecifiedClosure(), m_count);
+    }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    CallVariant m_callee;
+    uint32_t m_count;
+};
+
+inline CallEdge::CallEdge(CallVariant callee, uint32_t count)
+    : m_callee(callee)
+    , m_count(count)
+{
+}
+
+inline CallEdge::CallEdge()
+    : CallEdge(CallVariant(), 0)
+{
+}
+
+typedef Vector<CallEdge, 1> CallEdgeList;
+
+} // namespace JSC
+
+#endif // CallEdge_h
+
index 72575bddcfa09ce6028e972203c43d21342df7a2..d92009874a93857772c4366f4d009b546a33b9ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DFGOperations.h"
 #include "DFGThunks.h"
 #include "JSCInlines.h"
+#include "Repatch.h"
 #include "RepatchBuffer.h"
+#include <wtf/ListDump.h>
 #include <wtf/NeverDestroyed.h>
 
 #if ENABLE(JIT)
 namespace JSC {
 
+void CallLinkInfo::clearStub()
+{
+    if (!stub())
+        return;
+
+    m_stub->clearCallNodesFor(this);
+    m_stub = nullptr;
+}
+
 void CallLinkInfo::unlink(RepatchBuffer& repatchBuffer)
 {
-    ASSERT(isLinked());
+    if (!isLinked()) {
+        // We could be called even if we're not linked anymore because of how polymorphic calls
+        // work. Each callsite within the polymorphic call stub may separately ask us to unlink().
+        RELEASE_ASSERT(!isOnList());
+        return;
+    }
     
-    if (Options::showDisassembly())
-        dataLog("Unlinking call from ", callReturnLocation, " to ", pointerDump(repatchBuffer.codeBlock()), "\n");
-
-    repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(RepatchBuffer::startOfBranchPtrWithPatchOnRegister(hotPathBegin), static_cast<MacroAssembler::RegisterID>(calleeGPR), 0);
-    repatchBuffer.relink(
-        callReturnLocation,
-        repatchBuffer.codeBlock()->vm()->getCTIStub(linkThunkGeneratorFor(
-            (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
-            isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired)).code());
-    hasSeenShouldRepatch = false;
-    callee.clear();
-    stub.clear();
+    unlinkFor(
+        repatchBuffer, *this,
+        (m_callType == Construct || m_callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
+        m_isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired);
 
     // It will be on a list if the callee has a code block.
     if (isOnList())
@@ -59,31 +67,41 @@ void CallLinkInfo::unlink(RepatchBuffer& repatchBuffer)
 
 void CallLinkInfo::visitWeak(RepatchBuffer& repatchBuffer)
 {
+    auto handleSpecificCallee = [&] (JSFunction* callee) {
+        if (Heap::isMarked(callee->executable()))
+            m_hasSeenClosure = true;
+        else
+            m_clearedByGC = true;
+    };
+    
     if (isLinked()) {
-        if (stub) {
-            if (!Heap::isMarked(stub->structure())
-                || !Heap::isMarked(stub->executable())) {
+        if (stub()) {
+            if (!stub()->visitWeak(repatchBuffer)) {
                 if (Options::verboseOSR()) {
                     dataLog(
                         "Clearing closure call from ", *repatchBuffer.codeBlock(), " to ",
-                        stub->executable()->hashFor(specializationKind()),
-                        ", stub routine ", RawPointer(stub.get()), ".\n");
+                        listDump(stub()->variants()), ", stub routine ", RawPointer(stub()),
+                        ".\n");
                 }
                 unlink(repatchBuffer);
+                m_clearedByGC = true;
             }
-        } else if (!Heap::isMarked(callee.get())) {
+        } else if (!Heap::isMarked(m_callee.get())) {
             if (Options::verboseOSR()) {
                 dataLog(
                     "Clearing call from ", *repatchBuffer.codeBlock(), " to ",
-                    RawPointer(callee.get()), " (",
-                    callee.get()->executable()->hashFor(specializationKind()),
+                    RawPointer(m_callee.get()), " (",
+                    m_callee.get()->executable()->hashFor(specializationKind()),
                     ").\n");
             }
+            handleSpecificCallee(m_callee.get());
             unlink(repatchBuffer);
         }
     }
-    if (!!lastSeenCallee && !Heap::isMarked(lastSeenCallee.get()))
-        lastSeenCallee.clear();
+    if (haveLastSeenCallee() && !Heap::isMarked(lastSeenCallee())) {
+        handleSpecificCallee(lastSeenCallee());
+        clearLastSeenCallee();
+    }
 }
 
 CallLinkInfo& CallLinkInfo::dummy()
index 88094ff619e5279375acced9cf3fc7a66835111c..0277ecf977293e036679c01c37642f4d81fcea63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef CallLinkInfo_h
 #define CallLinkInfo_h
 
-#include "ClosureCallStubRoutine.h"
 #include "CodeLocation.h"
 #include "CodeSpecializationKind.h"
 #include "JITWriteBarrier.h"
 #include "JSFunction.h"
 #include "Opcode.h"
+#include "PolymorphicCallStubRoutine.h"
 #include "WriteBarrier.h"
 #include <wtf/SentinelLinkedList.h>
 
@@ -41,7 +41,8 @@ namespace JSC {
 
 class RepatchBuffer;
 
-struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+class CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+public:
     enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs };
     static CallType callTypeFor(OpcodeID opcodeID)
     {
@@ -54,62 +55,234 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
         ASSERT(opcodeID == op_call_varargs);
         return CallVarargs;
     }
-        
+    
     CallLinkInfo()
-        : isFTL(false)
-        , hasSeenShouldRepatch(false)
-        , hasSeenClosure(false)
-        , callType(None)
-        , slowPathCount(0)
+        : m_isFTL(false)
+        , m_hasSeenShouldRepatch(false)
+        , m_hasSeenClosure(false)
+        , m_clearedByGC(false)
+        , m_callType(None)
+        , m_maxNumArguments(0)
+        , m_slowPathCount(0)
     {
     }
         
     ~CallLinkInfo()
     {
+        clearStub();
+
         if (isOnList())
             remove();
     }
     
-    CodeSpecializationKind specializationKind() const
+    static CodeSpecializationKind specializationKindFor(CallType callType)
     {
         return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
     }
+    CodeSpecializationKind specializationKind() const
+    {
+        return specializationKindFor(static_cast<CallType>(m_callType));
+    }
 
-    CodeLocationNearCall callReturnLocation;
-    CodeLocationDataLabelPtr hotPathBegin;
-    CodeLocationNearCall hotPathOther;
-    JITWriteBarrier<JSFunction> callee;
-    WriteBarrier<JSFunction> lastSeenCallee;
-    RefPtr<ClosureCallStubRoutine> stub;
-    bool isFTL : 1;
-    bool hasSeenShouldRepatch : 1;
-    bool hasSeenClosure : 1;
-    unsigned callType : 5; // CallType
-    unsigned calleeGPR : 8;
-    unsigned slowPathCount;
-    CodeOrigin codeOrigin;
-
-    bool isLinked() { return stub || callee; }
+    bool isLinked() { return m_stub || m_callee; }
     void unlink(RepatchBuffer&);
 
+    void setUpCall(CallType callType, CodeOrigin codeOrigin, unsigned calleeGPR)
+    {
+        m_callType = callType;
+        m_codeOrigin = codeOrigin;
+        m_calleeGPR = calleeGPR;
+    }
+
+    void setCallLocations(CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+        CodeLocationNearCall hotPathOther)
+    {
+        m_callReturnLocation = callReturnLocation;
+        m_hotPathBegin = hotPathBegin;
+        m_hotPathOther = hotPathOther;
+    }
+
+    void setUpCallFromFTL(CallType callType, CodeOrigin codeOrigin,
+        CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+        CodeLocationNearCall hotPathOther, unsigned calleeGPR)
+    {
+        m_isFTL = true;
+        m_callType = callType;
+        m_codeOrigin = codeOrigin;
+        m_callReturnLocation = callReturnLocation;
+        m_hotPathBegin = hotPathBegin;
+        m_hotPathOther = hotPathOther;
+        m_calleeGPR = calleeGPR;
+    }
+
+    CodeLocationNearCall callReturnLocation()
+    {
+        return m_callReturnLocation;
+    }
+
+    CodeLocationDataLabelPtr hotPathBegin()
+    {
+        return m_hotPathBegin;
+    }
+
+    CodeLocationNearCall hotPathOther()
+    {
+        return m_hotPathOther;
+    }
+
+    void setCallee(VM& vm, CodeLocationDataLabelPtr location, JSCell* owner, JSFunction* callee)
+    {
+        m_callee.set(vm, location, owner, callee);
+    }
+
+    void clearCallee()
+    {
+        m_callee.clear();
+    }
+
+    JSFunction* callee()
+    {
+        return m_callee.get();
+    }
+
+    void setLastSeenCallee(VM& vm, const JSCell* owner, JSFunction* callee)
+    {
+        m_lastSeenCallee.set(vm, owner, callee);
+    }
+
+    void clearLastSeenCallee()
+    {
+        m_lastSeenCallee.clear();
+    }
+
+    JSFunction* lastSeenCallee()
+    {
+        return m_lastSeenCallee.get();
+    }
+
+    bool haveLastSeenCallee()
+    {
+        return !!m_lastSeenCallee;
+    }
+
+    void setStub(PassRefPtr<PolymorphicCallStubRoutine> newStub)
+    {
+        clearStub();
+        m_stub = newStub;
+    }
+
+    void clearStub();
+
+    PolymorphicCallStubRoutine* stub()
+    {
+        return m_stub.get();
+    }
+
     bool seenOnce()
     {
-        return hasSeenShouldRepatch;
+        return m_hasSeenShouldRepatch;
+    }
+
+    void clearSeen()
+    {
+        m_hasSeenShouldRepatch = false;
     }
 
     void setSeen()
     {
-        hasSeenShouldRepatch = true;
+        m_hasSeenShouldRepatch = true;
     }
-    
+
+    bool hasSeenClosure()
+    {
+        return m_hasSeenClosure;
+    }
+
+    void setHasSeenClosure()
+    {
+        m_hasSeenClosure = true;
+    }
+
+    bool clearedByGC()
+    {
+        return m_clearedByGC;
+    }
+
+    void setCallType(CallType callType)
+    {
+        m_callType = callType;
+    }
+
+    CallType callType()
+    {
+        return static_cast<CallType>(m_callType);
+    }
+
+    uint8_t* addressOfMaxNumArguments()
+    {
+        return &m_maxNumArguments;
+    }
+
+    uint8_t maxNumArguments()
+    {
+        return m_maxNumArguments;
+    }
+
+    static ptrdiff_t offsetOfSlowPathCount()
+    {
+        return OBJECT_OFFSETOF(CallLinkInfo, m_slowPathCount);
+    }
+
+    void setCalleeGPR(unsigned calleeGPR)
+    {
+        m_calleeGPR = calleeGPR;
+    }
+
+    unsigned calleeGPR()
+    {
+        return m_calleeGPR;
+    }
+
+    uint32_t slowPathCount()
+    {
+        return m_slowPathCount;
+    }
+
+    void setCodeOrigin(CodeOrigin codeOrigin)
+    {
+        m_codeOrigin = codeOrigin;
+    }
+
+    CodeOrigin codeOrigin()
+    {
+        return m_codeOrigin;
+    }
+
     void visitWeak(RepatchBuffer&);
-    
+
     static CallLinkInfo& dummy();
+
+private:
+    CodeLocationNearCall m_callReturnLocation;
+    CodeLocationDataLabelPtr m_hotPathBegin;
+    CodeLocationNearCall m_hotPathOther;
+    JITWriteBarrier<JSFunction> m_callee;
+    WriteBarrier<JSFunction> m_lastSeenCallee;
+    RefPtr<PolymorphicCallStubRoutine> m_stub;
+    bool m_isFTL : 1;
+    bool m_hasSeenShouldRepatch : 1;
+    bool m_hasSeenClosure : 1;
+    bool m_clearedByGC : 1;
+    unsigned m_callType : 4; // CallType
+    unsigned m_calleeGPR : 8;
+    uint8_t m_maxNumArguments; // Only used for varargs calls.
+    uint32_t m_slowPathCount;
+    CodeOrigin m_codeOrigin;
 };
 
 inline CodeOrigin getCallLinkInfoCodeOrigin(CallLinkInfo& callLinkInfo)
 {
-    return callLinkInfo.codeOrigin;
+    return callLinkInfo.codeOrigin();
 }
 
 typedef HashMap<CodeOrigin, CallLinkInfo*, CodeOriginApproximateHash> CallLinkInfoMap;
index 29a9237984840a7234161dce3cc2defa67f99df6..103a7f2b50651d8f9a04058fd5c98f12cf7f04c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "LLIntCallLinkInfo.h"
 #include "JSCInlines.h"
 #include <wtf/CommaPrinter.h>
+#include <wtf/ListDump.h>
 
 namespace JSC {
 
 static const bool verbose = false;
 
 CallLinkStatus::CallLinkStatus(JSValue value)
-    : m_callTarget(value)
-    , m_executable(0)
-    , m_structure(0)
-    , m_couldTakeSlowPath(false)
+    : m_couldTakeSlowPath(false)
     , m_isProved(false)
 {
-    if (!value || !value.isCell())
+    if (!value || !value.isCell()) {
+        m_couldTakeSlowPath = true;
         return;
+    }
     
-    m_structure = value.asCell()->structure();
-    
-    if (!value.asCell()->inherits(JSFunction::info()))
-        return;
-    
-    m_executable = jsCast<JSFunction*>(value.asCell())->executable();
-}
-
-JSFunction* CallLinkStatus::function() const
-{
-    if (!m_callTarget || !m_callTarget.isCell())
-        return 0;
-    
-    if (!m_callTarget.asCell()->inherits(JSFunction::info()))
-        return 0;
-    
-    return jsCast<JSFunction*>(m_callTarget.asCell());
-}
-
-InternalFunction* CallLinkStatus::internalFunction() const
-{
-    if (!m_callTarget || !m_callTarget.isCell())
-        return 0;
-    
-    if (!m_callTarget.asCell()->inherits(InternalFunction::info()))
-        return 0;
-    
-    return jsCast<InternalFunction*>(m_callTarget.asCell());
-}
-
-Intrinsic CallLinkStatus::intrinsicFor(CodeSpecializationKind kind) const
-{
-    if (!m_executable)
-        return NoIntrinsic;
-    
-    return m_executable->intrinsicFor(kind);
+    m_variants.append(CallVariant(value.asCell()));
 }
 
 CallLinkStatus CallLinkStatus::computeFromLLInt(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
@@ -90,7 +55,7 @@ CallLinkStatus CallLinkStatus::computeFromLLInt(const ConcurrentJITLocker& locke
     UNUSED_PARAM(profiledBlock);
     UNUSED_PARAM(bytecodeIndex);
 #if ENABLE(DFG_JIT)
-    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction))) {
+    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCell))) {
         // We could force this to be a closure call, but instead we'll just assume that it
         // takes slow path.
         return takesSlowPath();
@@ -120,31 +85,59 @@ CallLinkStatus CallLinkStatus::computeFor(
     UNUSED_PARAM(bytecodeIndex);
     UNUSED_PARAM(map);
 #if ENABLE(DFG_JIT)
-    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable)))
-        return takesSlowPath();
+    ExitSiteData exitSiteData = computeExitSiteData(locker, profiledBlock, bytecodeIndex);
     
     CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
-    if (!callLinkInfo)
-        return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
-    
-    CallLinkStatus result = computeFor(locker, *callLinkInfo);
-    if (!result)
+    if (!callLinkInfo) {
+        if (exitSiteData.m_takesSlowPath)
+            return takesSlowPath();
         return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
+    }
     
-    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction)))
-        result.makeClosureCall();
-    
-    return result;
+    return computeFor(locker, profiledBlock, *callLinkInfo, exitSiteData);
 #else
     return CallLinkStatus();
 #endif
 }
 
+CallLinkStatus::ExitSiteData CallLinkStatus::computeExitSiteData(
+    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
+{
+    ExitSiteData exitSiteData;
+    
+#if ENABLE(DFG_JIT)
+    exitSiteData.m_takesSlowPath =
+        profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadType))
+        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable));
+    exitSiteData.m_badFunction =
+        profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCell));
+#else
+    UNUSED_PARAM(locker);
+    UNUSED_PARAM(profiledBlock);
+    UNUSED_PARAM(bytecodeIndex);
+#endif
+    
+    return exitSiteData;
+}
+
 #if ENABLE(JIT)
-CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
+CallLinkStatus CallLinkStatus::computeFor(
+    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo)
+{
+    // We don't really need this, but anytime we have to debug this code, it becomes indispensable.
+    UNUSED_PARAM(profiledBlock);
+    
+    CallLinkStatus result = computeFromCallLinkInfo(locker, callLinkInfo);
+    result.m_maxNumArguments = callLinkInfo.maxNumArguments();
+    return result;
+}
+
+CallLinkStatus CallLinkStatus::computeFromCallLinkInfo(
+    const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
 {
+    if (callLinkInfo.clearedByGC())
+        return takesSlowPath();
+    
     // Note that despite requiring that the locker is held, this code is racy with respect
     // to the CallLinkInfo: it may get cleared while this code runs! This is because
     // CallLinkInfo::unlink() may be called from a different CodeBlock than the one that owns
@@ -158,20 +151,90 @@ CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&, CallLinkIn
     // that is still marginally valid (i.e. the pointers ain't stale). This kind of raciness
     // is probably OK for now.
     
-    if (callLinkInfo.slowPathCount >= Options::couldTakeSlowCaseMinimumCount())
-        return takesSlowPath();
+    // PolymorphicCallStubRoutine is a GCAwareJITStubRoutine, so if non-null, it will stay alive
+    // until next GC even if the CallLinkInfo is concurrently cleared. Also, the variants list is
+    // never mutated after the PolymorphicCallStubRoutine is instantiated. We have some conservative
+    // fencing in place to make sure that we see the variants list after construction.
+    if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub()) {
+        WTF::loadLoadFence();
+        
+        CallEdgeList edges = stub->edges();
+        
+        // Now that we've loaded the edges list, there are no further concurrency concerns. We will
+        // just manipulate and prune this list to our liking - mostly removing entries that are too
+        // infrequent and ensuring that it's sorted in descending order of frequency.
+        
+        RELEASE_ASSERT(edges.size());
+        
+        std::sort(
+            edges.begin(), edges.end(),
+            [] (CallEdge a, CallEdge b) {
+                return a.count() > b.count();
+            });
+        RELEASE_ASSERT(edges.first().count() >= edges.last().count());
+        
+        double totalCallsToKnown = 0;
+        double totalCallsToUnknown = callLinkInfo.slowPathCount();
+        CallVariantList variants;
+        for (size_t i = 0; i < edges.size(); ++i) {
+            CallEdge edge = edges[i];
+            // If the call is at the tail of the distribution, then we don't optimize it and we
+            // treat it as if it was a call to something unknown. We define the tail as being either
+            // a call that doesn't belong to the N most frequent callees (N =
+            // maxPolymorphicCallVariantsForInlining) or that has a total call count that is too
+            // small.
+            if (i >= Options::maxPolymorphicCallVariantsForInlining()
+                || edge.count() < Options::frequentCallThreshold())
+                totalCallsToUnknown += edge.count();
+            else {
+                totalCallsToKnown += edge.count();
+                variants.append(edge.callee());
+            }
+        }
+        
+        // Bail if we didn't find any calls that qualified.
+        RELEASE_ASSERT(!!totalCallsToKnown == !!variants.size());
+        if (variants.isEmpty())
+            return takesSlowPath();
+        
+        // We require that the distribution of callees is skewed towards a handful of common ones.
+        if (totalCallsToKnown / totalCallsToUnknown < Options::minimumCallToKnownRate())
+            return takesSlowPath();
+        
+        RELEASE_ASSERT(totalCallsToKnown);
+        RELEASE_ASSERT(variants.size());
+        
+        CallLinkStatus result;
+        result.m_variants = variants;
+        result.m_couldTakeSlowPath = !!totalCallsToUnknown;
+        return result;
+    }
     
-    if (ClosureCallStubRoutine* stub = callLinkInfo.stub.get())
-        return CallLinkStatus(stub->executable(), stub->structure());
+    CallLinkStatus result;
     
-    JSFunction* target = callLinkInfo.lastSeenCallee.get();
-    if (!target)
-        return CallLinkStatus();
+    if (JSFunction* target = callLinkInfo.lastSeenCallee()) {
+        CallVariant variant(target);
+        if (callLinkInfo.hasSeenClosure())
+            variant = variant.despecifiedClosure();
+        result.m_variants.append(variant);
+    }
     
-    if (callLinkInfo.hasSeenClosure)
-        return CallLinkStatus(target->executable(), target->structure());
+    result.m_couldTakeSlowPath = !!callLinkInfo.slowPathCount();
+
+    return result;
+}
 
-    return CallLinkStatus(target);
+CallLinkStatus CallLinkStatus::computeFor(
+    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo,
+    ExitSiteData exitSiteData)
+{
+    CallLinkStatus result = computeFor(locker, profiledBlock, callLinkInfo);
+    if (exitSiteData.m_badFunction)
+        result.makeClosureCall();
+    if (exitSiteData.m_takesSlowPath)
+        result.m_couldTakeSlowPath = true;
+    
+    return result;
 }
 #endif
 
@@ -183,10 +246,7 @@ void CallLinkStatus::computeDFGStatuses(
     CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
     for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
         CallLinkInfo& info = **iter;
-        CodeOrigin codeOrigin = info.codeOrigin;
-        
-        bool takeSlowPath;
-        bool badFunction;
+        CodeOrigin codeOrigin = info.codeOrigin();
         
         // Check if we had already previously made a terrible mistake in the FTL for this
         // code origin. Note that this is approximate because we could have a monovariant
@@ -197,28 +257,16 @@ void CallLinkStatus::computeDFGStatuses(
         // InlineCallFrames.
         CodeBlock* currentBaseline =
             baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
+        ExitSiteData exitSiteData;
         {
             ConcurrentJITLocker locker(currentBaseline->m_lock);
-            takeSlowPath =
-                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCache, ExitFromFTL))
-                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCacheWatchpoint, ExitFromFTL))
-                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadExecutable, ExitFromFTL));
-            badFunction =
-                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadFunction, ExitFromFTL));
+            exitSiteData = computeExitSiteData(
+                locker, currentBaseline, codeOrigin.bytecodeIndex);
         }
         
         {
             ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
-            if (takeSlowPath)
-                map.add(info.codeOrigin, takesSlowPath());
-            else {
-                CallLinkStatus status = computeFor(locker, info);
-                if (status.isSet()) {
-                    if (badFunction)
-                        status.makeClosureCall();
-                    map.add(info.codeOrigin, status);
-                }
-            }
+            map.add(info.codeOrigin(), computeFor(locker, dfgCodeBlock, info, exitSiteData));
         }
     }
 #else
@@ -247,6 +295,27 @@ CallLinkStatus CallLinkStatus::computeFor(
     return computeFor(profiledBlock, codeOrigin.bytecodeIndex, baselineMap);
 }
 
+void CallLinkStatus::setProvenConstantCallee(CallVariant variant)
+{
+    m_variants = CallVariantList{ variant };
+    m_couldTakeSlowPath = false;
+    m_isProved = true;
+}
+
+bool CallLinkStatus::isClosureCall() const
+{
+    for (unsigned i = m_variants.size(); i--;) {
+        if (m_variants[i].isClosureCall())
+            return true;
+    }
+    return false;
+}
+
+void CallLinkStatus::makeClosureCall()
+{
+    m_variants = despecifiedVariantList(m_variants);
+}
+
 void CallLinkStatus::dump(PrintStream& out) const
 {
     if (!isSet()) {
@@ -262,17 +331,11 @@ void CallLinkStatus::dump(PrintStream& out) const
     if (m_couldTakeSlowPath)
         out.print(comma, "Could Take Slow Path");
     
-    if (m_callTarget)
-        out.print(comma, "Known target: ", m_callTarget);
-    
-    if (m_executable) {
-        out.print(comma, "Executable/CallHash: ", RawPointer(m_executable));
-        if (!isCompilationThread())
-            out.print("/", m_executable->hashFor(CodeForCall));
-    }
+    if (!m_variants.isEmpty())
+        out.print(comma, listDump(m_variants));
     
-    if (m_structure)
-        out.print(comma, "Structure: ", RawPointer(m_structure));
+    if (m_maxNumArguments)
+        out.print(comma, "maxNumArguments = ", m_maxNumArguments);
 }
 
 } // namespace JSC
index 99b2fdc93fedb647dea617552248edeb53b4a7b3..a307ca0069b5c1886c296fdfa69473e7fc8b2a63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define CallLinkStatus_h
 
 #include "CallLinkInfo.h"
+#include "CallVariant.h"
 #include "CodeOrigin.h"
 #include "CodeSpecializationKind.h"
 #include "ConcurrentJITLock.h"
+#include "ExitingJITType.h"
 #include "Intrinsic.h"
 #include "JSCJSValue.h"
 
@@ -40,14 +42,12 @@ class ExecutableBase;
 class InternalFunction;
 class JSFunction;
 class Structure;
-struct CallLinkInfo;
+class CallLinkInfo;
 
 class CallLinkStatus {
 public:
     CallLinkStatus()
-        : m_executable(0)
-        , m_structure(0)
-        , m_couldTakeSlowPath(false)
+        : m_couldTakeSlowPath(false)
         , m_isProved(false)
     {
     }
@@ -61,28 +61,34 @@ public:
     
     explicit CallLinkStatus(JSValue);
     
-    CallLinkStatus(ExecutableBase* executable, Structure* structure)
-        : m_executable(executable)
-        , m_structure(structure)
+    CallLinkStatus(CallVariant variant)
+        : m_variants(1, variant)
         , m_couldTakeSlowPath(false)
         , m_isProved(false)
     {
-        ASSERT(!!executable == !!structure);
-    }
-    
-    CallLinkStatus& setIsProved(bool isProved)
-    {
-        m_isProved = isProved;
-        return *this;
     }
     
     static CallLinkStatus computeFor(
         CodeBlock*, unsigned bytecodeIndex, const CallLinkInfoMap&);
 
+    struct ExitSiteData {
+        ExitSiteData()
+            : m_takesSlowPath(false)
+            , m_badFunction(false)
+        {
+        }
+        
+        bool m_takesSlowPath;
+        bool m_badFunction;
+    };
+    static ExitSiteData computeExitSiteData(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
+    
 #if ENABLE(JIT)
     // Computes the status assuming that we never took slow path and never previously
     // exited.
-    static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&);
+    static CallLinkStatus computeFor(const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&);
+    static CallLinkStatus computeFor(
+        const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&, ExitSiteData);
 #endif
     
     typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap;
@@ -96,39 +102,40 @@ public:
     static CallLinkStatus computeFor(
         CodeBlock*, CodeOrigin, const CallLinkInfoMap&, const ContextMap&);
     
-    bool isSet() const { return m_callTarget || m_executable || m_couldTakeSlowPath; }
+    void setProvenConstantCallee(CallVariant);
+    
+    bool isSet() const { return !m_variants.isEmpty() || m_couldTakeSlowPath; }
     
     bool operator!() const { return !isSet(); }
     
     bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
-    bool isClosureCall() const { return m_executable && !m_callTarget; }
-    
-    JSValue callTarget() const { return m_callTarget; }
-    JSFunction* function() const;
-    InternalFunction* internalFunction() const;
-    Intrinsic intrinsicFor(CodeSpecializationKind) const;
-    ExecutableBase* executable() const { return m_executable; }
-    Structure* structure() const { return m_structure; }
+    
+    CallVariantList variants() const { return m_variants; }
+    unsigned size() const { return m_variants.size(); }
+    CallVariant at(unsigned i) const { return m_variants[i]; }
+    CallVariant operator[](unsigned i) const { return at(i); }
     bool isProved() const { return m_isProved; }
-    bool canOptimize() const { return (m_callTarget || m_executable) && !m_couldTakeSlowPath; }
+    bool canOptimize() const { return !m_variants.isEmpty(); }
+    
+    bool isClosureCall() const; // Returns true if any callee is a closure call.
+    
+    unsigned maxNumArguments() const { return m_maxNumArguments; }
     
     void dump(PrintStream&) const;
     
 private:
-    void makeClosureCall()
-    {
-        ASSERT(!m_isProved);
-        // Turn this into a closure call.
-        m_callTarget = JSValue();
-    }
+    void makeClosureCall();
     
     static CallLinkStatus computeFromLLInt(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
+#if ENABLE(JIT)
+    static CallLinkStatus computeFromCallLinkInfo(
+        const ConcurrentJITLocker&, CallLinkInfo&);
+#endif
     
-    JSValue m_callTarget;
-    ExecutableBase* m_executable;
-    Structure* m_structure;
+    CallVariantList m_variants;
     bool m_couldTakeSlowPath;
     bool m_isProved;
+    unsigned m_maxNumArguments;
 };
 
 } // namespace JSC
diff --git a/bytecode/CallVariant.cpp b/bytecode/CallVariant.cpp
new file mode 100644 (file)
index 0000000..9745dde
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CallVariant.h"
+
+#include "JSCInlines.h"
+#include <wtf/ListDump.h>
+
+namespace JSC {
+
+void CallVariant::dump(PrintStream& out) const
+{
+    if (!*this) {
+        out.print("null");
+        return;
+    }
+    
+    if (InternalFunction* internalFunction = this->internalFunction()) {
+        out.print("InternalFunction: ", JSValue(internalFunction));
+        return;
+    }
+    
+    if (JSFunction* function = this->function()) {
+        out.print("(Function: ", JSValue(function), "; Executable: ", *executable(), ")");
+        return;
+    }
+    
+    out.print("Executable: ", *executable());
+}
+
+CallVariantList variantListWithVariant(const CallVariantList& list, CallVariant variantToAdd)
+{
+    ASSERT(variantToAdd);
+    CallVariantList result;
+    for (CallVariant variant : list) {
+        ASSERT(variant);
+        if (!!variantToAdd) {
+            if (variant == variantToAdd)
+                variantToAdd = CallVariant();
+            else if (variant.despecifiedClosure() == variantToAdd.despecifiedClosure()) {
+                variant = variant.despecifiedClosure();
+                variantToAdd = CallVariant();
+            }
+        }
+        result.append(variant);
+    }
+    if (!!variantToAdd)
+        result.append(variantToAdd);
+    
+    if (!ASSERT_DISABLED) {
+        for (unsigned i = 0; i < result.size(); ++i) {
+            for (unsigned j = i + 1; j < result.size(); ++j) {
+                if (result[i] != result[j])
+                    continue;
+                
+                dataLog("variantListWithVariant(", listDump(list), ", ", variantToAdd, ") failed: got duplicates in result: ", listDump(result), "\n");
+                RELEASE_ASSERT_NOT_REACHED();
+            }
+        }
+    }
+    
+    return result;
+}
+
+CallVariantList despecifiedVariantList(const CallVariantList& list)
+{
+    CallVariantList result;
+    for (CallVariant variant : list)
+        result = variantListWithVariant(result, variant.despecifiedClosure());
+    return result;
+}
+
+} // namespace JSC
+
diff --git a/bytecode/CallVariant.h b/bytecode/CallVariant.h
new file mode 100644 (file)
index 0000000..2514f72
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CallVariant_h
+#define CallVariant_h
+
+#include "Executable.h"
+#include "JSCell.h"
+#include "JSFunction.h"
+
+namespace JSC {
+
+// The CallVariant class is meant to encapsulate a callee in a way that is useful for call linking
+// and inlining. Because JavaScript has closures, and because JSC implements the notion of internal
+// non-function objects that nevertheless provide call traps, the call machinery wants to see a
+// callee in one of the following four forms:
+//
+// JSFunction callee: This means that we expect the callsite to always call a particular function
+//     instance, that is associated with a particular lexical environment. This pinpoints not
+//     just the code that will be called (i.e. the executable) but also the scope within which
+//     the code runs.
+//
+// Executable callee: This corresponds to a call to a closure. In this case, we know that the
+//     callsite will call a JSFunction, but we do not know which particular JSFunction. We do know
+//     what code will be called - i.e. we know the executable.
+//
+// InternalFunction callee: JSC supports a special kind of native functions that support bizarre
+//     semantics. These are always singletons. If we know that the callee is an InternalFunction
+//     then we know both the code that will be called and the scope; in fact the "scope" is really
+//     just the InternalFunction itself.
+//
+// Something else: It's possible call all manner of rubbish in JavaScript. This implicitly supports
+//     bizarre object callees, but it can't really tell you anything interesting about them other
+//     than the fact that they don't fall into any of the above categories.
+//
+// This class serves as a kind of union over these four things. It does so by just holding a
+// JSCell*. We determine which of the modes its in by doing type checks on the cell. Note that we
+// cannot use WriteBarrier<> here because this gets used inside the compiler.
+
+class CallVariant {
+public:
+    explicit CallVariant(JSCell* callee = nullptr)
+        : m_callee(callee)
+    {
+    }
+    
+    CallVariant(WTF::HashTableDeletedValueType)
+        : m_callee(deletedToken())
+    {
+    }
+    
+    bool operator!() const { return !m_callee; }
+    
+    // If this variant refers to a function, change it to refer to its executable.
+    ALWAYS_INLINE CallVariant despecifiedClosure() const
+    {
+        if (m_callee->type() == JSFunctionType)
+            return CallVariant(jsCast<JSFunction*>(m_callee)->executable());
+        return *this;
+    }
+    
+    JSCell* rawCalleeCell() const { return m_callee; }
+    
+    InternalFunction* internalFunction() const
+    {
+        return jsDynamicCast<InternalFunction*>(m_callee);
+    }
+    
+    JSFunction* function() const
+    {
+        return jsDynamicCast<JSFunction*>(m_callee);
+    }
+    
+    bool isClosureCall() const { return !!jsDynamicCast<ExecutableBase*>(m_callee); }
+    
+    ExecutableBase* executable() const
+    {
+        if (JSFunction* function = this->function())
+            return function->executable();
+        return jsDynamicCast<ExecutableBase*>(m_callee);
+    }
+    
+    JSCell* nonExecutableCallee() const
+    {
+        RELEASE_ASSERT(!isClosureCall());
+        return m_callee;
+    }
+    
+    Intrinsic intrinsicFor(CodeSpecializationKind kind) const
+    {
+        if (ExecutableBase* executable = this->executable())
+            return executable->intrinsicFor(kind);
+        return NoIntrinsic;
+    }
+    
+    FunctionExecutable* functionExecutable() const
+    {
+        if (ExecutableBase* executable = this->executable())
+            return jsDynamicCast<FunctionExecutable*>(executable);
+        return nullptr;
+    }
+    
+    void dump(PrintStream& out) const;
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_callee == deletedToken();
+    }
+    
+    bool operator==(const CallVariant& other) const
+    {
+        return m_callee == other.m_callee;
+    }
+    
+    bool operator!=(const CallVariant& other) const
+    {
+        return !(*this == other);
+    }
+    
+    bool operator<(const CallVariant& other) const
+    {
+        return m_callee < other.m_callee;
+    }
+    
+    bool operator>(const CallVariant& other) const
+    {
+        return other < *this;
+    }
+    
+    bool operator<=(const CallVariant& other) const
+    {
+        return !(*this < other);
+    }
+    
+    bool operator>=(const CallVariant& other) const
+    {
+        return other <= *this;
+    }
+    
+    unsigned hash() const
+    {
+        return WTF::PtrHash<JSCell*>::hash(m_callee);
+    }
+    
+private:
+    static JSCell* deletedToken() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(1)); }
+    
+    JSCell* m_callee;
+};
+
+struct CallVariantHash {
+    static unsigned hash(const CallVariant& key) { return key.hash(); }
+    static bool equal(const CallVariant& a, const CallVariant& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+typedef Vector<CallVariant, 1> CallVariantList;
+
+// Returns a new variant list by attempting to either append the given variant or merge it with one
+// of the variants we already have by despecifying closures.
+CallVariantList variantListWithVariant(const CallVariantList&, CallVariant);
+
+// Returns a new list where every element is despecified, and the list is deduplicated.
+CallVariantList despecifiedVariantList(const CallVariantList&);
+
+} // namespace JSC
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::CallVariant> {
+    typedef JSC::CallVariantHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::CallVariant> : SimpleClassHashTraits<JSC::CallVariant> { };
+
+} // namespace WTF
+
+#endif // CallVariant_h
+
index da60b48a1c793fd75339a79c1a3b7e675f9a9962..3ad75276e2cc9d8bfa745ae193d3fb46ec8b5b6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2010, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "CodeBlock.h"
 
+#include "BasicBlockLocation.h"
 #include "BytecodeGenerator.h"
 #include "BytecodeUseDef.h"
 #include "CallLinkStatus.h"
 #include "DFGJITCode.h"
 #include "DFGWorklist.h"
 #include "Debugger.h"
+#include "FunctionExecutableDump.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITStubs.h"
-#include "JSActivation.h"
 #include "JSCJSValue.h"
 #include "JSFunction.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "LLIntEntrypoint.h"
 #include "LowLevelInterpreter.h"
 #include "Repatch.h"
 #include "RepatchBuffer.h"
 #include "SlotVisitorInlines.h"
+#include "StackVisitor.h"
+#include "TypeLocationCache.h"
+#include "TypeProfiler.h"
 #include "UnlinkedInstructionStream.h"
 #include <wtf/BagToHashMap.h>
 #include <wtf/CommaPrinter.h>
 #include <wtf/StringExtras.h>
 #include <wtf/StringPrintStream.h>
+#include <wtf/text/UniquedStringImpl.h>
 
 #if ENABLE(DFG_JIT)
 #include "DFGOperations.h"
@@ -148,9 +154,11 @@ void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType)
         out.print(specializationKind());
     out.print(", ", instructionCount());
     if (this->jitType() == JITCode::BaselineJIT && m_shouldAlwaysBeInlined)
-        out.print(" (SABI)");
+        out.print(" (ShouldAlwaysBeInlined)");
     if (ownerExecutable()->neverInline())
         out.print(" (NeverInline)");
+    if (ownerExecutable()->didTryToEnterInLoop())
+        out.print(" (DidTryToEnterInLoop)");
     if (ownerExecutable()->isStrictMode())
         out.print(" (StrictMode)");
     if (this->jitType() == JITCode::BaselineJIT && m_didFailFTLCompilation)
@@ -165,11 +173,6 @@ void CodeBlock::dump(PrintStream& out) const
     dumpAssumingJITType(out, jitType());
 }
 
-static CString constantName(int k, JSValue value)
-{
-    return toCString(value, "(@k", k - FirstConstantRegisterIndex, ")");
-}
-
 static CString idName(int id0, const Identifier& ident)
 {
     return toCString(ident.impl(), "(@id", id0, ")");
@@ -177,19 +180,16 @@ static CString idName(int id0, const Identifier& ident)
 
 CString CodeBlock::registerName(int r) const
 {
-    if (r == missingThisObjectMarker())
-        return "<null>";
-
     if (isConstantRegisterIndex(r))
-        return constantName(r, getConstant(r));
+        return constantName(r);
 
-    if (operandIsArgument(r)) {
-        if (!VirtualRegister(r).toArgument())
-            return "this";
-        return toCString("arg", VirtualRegister(r).toArgument());
-    }
+    return toCString(VirtualRegister(r));
+}
 
-    return toCString("loc", VirtualRegister(r).toLocal());
+CString CodeBlock::constantName(int index) const
+{
+    JSValue value = getConstant(index);
+    return toCString(value, "(", VirtualRegister(index), ")");
 }
 
 static CString regexpToSourceString(RegExp* regExp)
@@ -273,7 +273,9 @@ void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location,
         break;
     default:
         RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         op = 0;
+#endif
     }
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
@@ -283,20 +285,19 @@ void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location,
     it += 4; // Increment up to the value profiler.
 }
 
-static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, const Identifier& ident)
+static void dumpStructure(PrintStream& out, const char* name, Structure* structure, const Identifier& ident)
 {
     if (!structure)
         return;
     
     out.printf("%s = %p", name, structure);
     
-    PropertyOffset offset = structure->getConcurrently(exec->vm(), ident.impl());
+    PropertyOffset offset = structure->getConcurrently(ident.impl());
     if (offset != invalidOffset)
         out.printf(" (offset = %d)", offset);
 }
 
-#if ENABLE(JIT) // unused when not ENABLE(JIT), leading to silly warnings
-static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, const Identifier& ident)
+static void dumpChain(PrintStream& out, StructureChain* chain, const Identifier& ident)
 {
     out.printf("chain = %p: [", chain);
     bool first = true;
@@ -307,11 +308,10 @@ static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain,
             first = false;
         else
             out.printf(", ");
-        dumpStructure(out, "struct", exec, currentStructure->get(), ident);
+        dumpStructure(out, "struct", currentStructure->get(), ident);
     }
     out.printf("]");
 }
-#endif
 
 void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int location, const StubInfoMap& map)
 {
@@ -325,7 +325,7 @@ void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int l
         out.printf(" llint(array_length)");
     else if (Structure* structure = instruction[4].u.structure.get()) {
         out.printf(" llint(");
-        dumpStructure(out, "struct", exec, structure, ident);
+        dumpStructure(out, "struct", structure, ident);
         out.printf(")");
     }
 
@@ -348,11 +348,6 @@ void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int l
                 out.printf("self");
                 baseStructure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
                 break;
-            case access_get_by_id_chain:
-                out.printf("chain");
-                baseStructure = stubInfo.u.getByIdChain.baseObjectStructure.get();
-                chain = stubInfo.u.getByIdChain.chain.get();
-                break;
             case access_get_by_id_list:
                 out.printf("list");
                 list = stubInfo.u.getByIdList.list;
@@ -367,17 +362,17 @@ void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int l
             
             if (baseStructure) {
                 out.printf(", ");
-                dumpStructure(out, "struct", exec, baseStructure, ident);
+                dumpStructure(out, "struct", baseStructure, ident);
             }
             
             if (prototypeStructure) {
                 out.printf(", ");
-                dumpStructure(out, "prototypeStruct", exec, baseStructure, ident);
+                dumpStructure(out, "prototypeStruct", baseStructure, ident);
             }
             
             if (chain) {
                 out.printf(", ");
-                dumpChain(out, exec, chain, ident);
+                dumpChain(out, chain, ident);
             }
             
             if (list) {
@@ -386,10 +381,10 @@ void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int l
                     if (i)
                         out.printf(", ");
                     out.printf("(");
-                    dumpStructure(out, "base", exec, list->at(i).structure(), ident);
+                    dumpStructure(out, "base", list->at(i).structure(), ident);
                     if (list->at(i).chain()) {
                         out.printf(", ");
-                        dumpChain(out, exec, list->at(i).chain(), ident);
+                        dumpChain(out, list->at(i).chain(), ident);
                     }
                     out.printf(")");
                 }
@@ -403,6 +398,118 @@ void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int l
 #endif
 }
 
+void CodeBlock::printPutByIdCacheStatus(PrintStream& out, ExecState* exec, int location, const StubInfoMap& map)
+{
+    Instruction* instruction = instructions().begin() + location;
+
+    const Identifier& ident = identifier(instruction[2].u.operand);
+    
+    UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
+    
+    if (Structure* structure = instruction[4].u.structure.get()) {
+        switch (exec->interpreter()->getOpcodeID(instruction[0].u.opcode)) {
+        case op_put_by_id:
+        case op_put_by_id_out_of_line:
+            out.print(" llint(");
+            dumpStructure(out, "struct", structure, ident);
+            out.print(")");
+            break;
+            
+        case op_put_by_id_transition_direct:
+        case op_put_by_id_transition_normal:
+        case op_put_by_id_transition_direct_out_of_line:
+        case op_put_by_id_transition_normal_out_of_line:
+            out.print(" llint(");
+            dumpStructure(out, "prev", structure, ident);
+            out.print(", ");
+            dumpStructure(out, "next", instruction[6].u.structure.get(), ident);
+            if (StructureChain* chain = instruction[7].u.structureChain.get()) {
+                out.print(", ");
+                dumpChain(out, chain, ident);
+            }
+            out.print(")");
+            break;
+            
+        default:
+            out.print(" llint(unknown)");
+            break;
+        }
+    }
+
+#if ENABLE(JIT)
+    if (StructureStubInfo* stubPtr = map.get(CodeOrigin(location))) {
+        StructureStubInfo& stubInfo = *stubPtr;
+        if (stubInfo.resetByGC)
+            out.print(" (Reset By GC)");
+        
+        if (stubInfo.seen) {
+            out.printf(" jit(");
+            
+            switch (stubInfo.accessType) {
+            case access_put_by_id_replace:
+                out.print("replace, ");
+                dumpStructure(out, "struct", stubInfo.u.putByIdReplace.baseObjectStructure.get(), ident);
+                break;
+            case access_put_by_id_transition_normal:
+            case access_put_by_id_transition_direct:
+                out.print("transition, ");
+                dumpStructure(out, "prev", stubInfo.u.putByIdTransition.previousStructure.get(), ident);
+                out.print(", ");
+                dumpStructure(out, "next", stubInfo.u.putByIdTransition.structure.get(), ident);
+                if (StructureChain* chain = stubInfo.u.putByIdTransition.chain.get()) {
+                    out.print(", ");
+                    dumpChain(out, chain, ident);
+                }
+                break;
+            case access_put_by_id_list: {
+                out.printf("list = [");
+                PolymorphicPutByIdList* list = stubInfo.u.putByIdList.list;
+                CommaPrinter comma;
+                for (unsigned i = 0; i < list->size(); ++i) {
+                    out.print(comma, "(");
+                    const PutByIdAccess& access = list->at(i);
+                    
+                    if (access.isReplace()) {
+                        out.print("replace, ");
+                        dumpStructure(out, "struct", access.oldStructure(), ident);
+                    } else if (access.isSetter()) {
+                        out.print("setter, ");
+                        dumpStructure(out, "struct", access.oldStructure(), ident);
+                    } else if (access.isCustom()) {
+                        out.print("custom, ");
+                        dumpStructure(out, "struct", access.oldStructure(), ident);
+                    } else if (access.isTransition()) {
+                        out.print("transition, ");
+                        dumpStructure(out, "prev", access.oldStructure(), ident);
+                        out.print(", ");
+                        dumpStructure(out, "next", access.newStructure(), ident);
+                        if (access.chain()) {
+                            out.print(", ");
+                            dumpChain(out, access.chain(), ident);
+                        }
+                    } else
+                        out.print("unknown");
+                    
+                    out.print(")");
+                }
+                out.print("]");
+                break;
+            }
+            case access_unset:
+                out.printf("unset");
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            out.printf(")");
+        }
+    }
+#else
+    UNUSED_PARAM(map);
+#endif
+}
+
 void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap& map)
 {
     int dst = (++it)->u.operand;
@@ -421,11 +528,13 @@ void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, con
         }
 #if ENABLE(JIT)
         if (CallLinkInfo* info = map.get(CodeOrigin(location))) {
-            JSFunction* target = info->lastSeenCallee.get();
+            JSFunction* target = info->lastSeenCallee();
             if (target)
                 out.printf(" jit(%p, exec %p)", target, target->executable());
         }
-        out.print(" status(", CallLinkStatus::computeFor(this, location, map), ")");
+        
+        if (jitType() != JITCode::FTLJIT)
+            out.print(" status(", CallLinkStatus::computeFor(this, location, map), ")");
 #else
         UNUSED_PARAM(map);
 #endif
@@ -446,6 +555,31 @@ void CodeBlock::printPutByIdOp(PrintStream& out, ExecState* exec, int location,
     it += 5;
 }
 
+void CodeBlock::dumpSource()
+{
+    dumpSource(WTF::dataFile());
+}
+
+void CodeBlock::dumpSource(PrintStream& out)
+{
+    ScriptExecutable* executable = ownerExecutable();
+    if (executable->isFunctionExecutable()) {
+        FunctionExecutable* functionExecutable = reinterpret_cast<FunctionExecutable*>(executable);
+        String source = functionExecutable->source().provider()->getRange(
+            functionExecutable->parametersStartOffset(),
+            functionExecutable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'.
+        
+        out.print("function ", inferredName(), source);
+        return;
+    }
+    out.print(executable->source().toString());
+}
+
+void CodeBlock::dumpBytecode()
+{
+    dumpBytecode(WTF::dataFile());
+}
+
 void CodeBlock::dumpBytecode(PrintStream& out)
 {
     // We only use the ExecState* for things that don't actually lead to JS execution,
@@ -463,19 +597,8 @@ void CodeBlock::dumpBytecode(PrintStream& out)
         static_cast<unsigned long>(instructions().size()),
         static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
         m_numParameters, m_numCalleeRegisters, m_numVars);
-    if (symbolTable() && symbolTable()->captureCount()) {
-        out.printf(
-            "; %d captured var(s) (from r%d to r%d, inclusive)",
-            symbolTable()->captureCount(), symbolTable()->captureStart(), symbolTable()->captureEnd() + 1);
-    }
-    if (usesArguments()) {
-        out.printf(
-            "; uses arguments, in r%d, r%d",
-            argumentsRegister().offset(),
-            unmodifiedArgumentsRegister(argumentsRegister()).offset());
-    }
     if (needsActivation() && codeType() == FunctionCode)
-        out.printf("; activation in r%d", activationRegister().offset());
+        out.printf("; lexical environment in r%d", activationRegister().offset());
     out.printf("\n");
     
     StubInfoMap stubInfos;
@@ -501,7 +624,19 @@ void CodeBlock::dumpBytecode(PrintStream& out)
         out.printf("\nConstants:\n");
         size_t i = 0;
         do {
-            out.printf("   k%u = %s\n", static_cast<unsigned>(i), toCString(m_constantRegisters[i].get()).data());
+            const char* sourceCodeRepresentationDescription = nullptr;
+            switch (m_constantsSourceCodeRepresentation[i]) {
+            case SourceCodeRepresentation::Double:
+                sourceCodeRepresentationDescription = ": in source as double";
+                break;
+            case SourceCodeRepresentation::Integer:
+                sourceCodeRepresentationDescription = ": in source as integer";
+                break;
+            case SourceCodeRepresentation::Other:
+                sourceCodeRepresentationDescription = "";
+                break;
+            }
+            out.printf("   k%u = %s%s\n", static_cast<unsigned>(i), toCString(m_constantRegisters[i].get()).data(), sourceCodeRepresentationDescription);
             ++i;
         } while (i < m_constantRegisters.size());
     }
@@ -519,7 +654,9 @@ void CodeBlock::dumpBytecode(PrintStream& out)
         out.printf("\nException Handlers:\n");
         unsigned i = 0;
         do {
-            out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target, m_rareData->m_exceptionHandlers[i].scopeDepth);
+            HandlerInfo& handler = m_rareData->m_exceptionHandlers[i];
+            out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] } %s\n",
+                i + 1, handler.start, handler.end, handler.target, handler.scopeDepth, handler.typeName());
             ++i;
         } while (i < m_rareData->m_exceptionHandlers.size());
     }
@@ -626,37 +763,44 @@ void CodeBlock::dumpBytecode(
             printLocationAndOp(out, exec, location, it, "enter");
             break;
         }
-        case op_touch_entry: {
-            printLocationAndOp(out, exec, location, it, "touch_entry");
+        case op_create_lexical_environment: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "create_lexical_environment");
+            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
-        case op_create_activation: {
+        case op_get_scope: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "create_activation", r0);
+            printLocationOpAndRegisterOperand(out, exec, location, it, "get_scope", r0);
             break;
         }
-        case op_create_arguments: {
+        case op_create_direct_arguments: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "create_arguments", r0);
+            printLocationAndOp(out, exec, location, it, "create_direct_arguments");
+            out.printf("%s", registerName(r0).data());
             break;
         }
-        case op_init_lazy_reg: {
+        case op_create_scoped_arguments: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "init_lazy_reg", r0);
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "create_scoped_arguments");
+            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
-        case op_get_callee: {
+        case op_create_out_of_band_arguments: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "get_callee", r0);
-            ++it;
+            printLocationAndOp(out, exec, location, it, "create_out_of_band_arguments");
+            out.printf("%s", registerName(r0).data());
             break;
         }
         case op_create_this: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             unsigned inferredInlineCapacity = (++it)->u.operand;
+            unsigned cachedFunction = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "create_this");
-            out.printf("%s, %s, %u", registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity);
+            out.printf("%s, %s, %u, %u", registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity, cachedFunction);
             break;
         }
         case op_to_this: {
@@ -664,7 +808,13 @@ void CodeBlock::dumpBytecode(
             printLocationOpAndRegisterOperand(out, exec, location, it, "to_this", r0);
             Structure* structure = (++it)->u.structure.get();
             if (structure)
-                out.print(" cache(struct = ", RawPointer(structure), ")");
+                out.print(", cache(struct = ", RawPointer(structure), ")");
+            out.print(", ", (++it)->u.toThisStatus);
+            break;
+        }
+        case op_check_tdz: {
+            int r0 = (++it)->u.operand;
+            printLocationOpAndRegisterOperand(out, exec, location, it, "op_check_tdz", r0);
             break;
         }
         case op_new_object: {
@@ -719,12 +869,20 @@ void CodeBlock::dumpBytecode(
             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
-        case op_captured_mov: {
+        case op_profile_type: {
             int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "captured_mov");
-            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             ++it;
+            ++it;
+            ++it;
+            ++it;
+            printLocationAndOp(out, exec, location, it, "op_profile_type");
+            out.printf("%s", registerName(r0).data());
+            break;
+        }
+        case op_profile_control_flow: {
+            BasicBlockLocation* basicBlockLocation = (++it)->u.basicBlockLocation;
+            printLocationAndOp(out, exec, location, it, "profile_control_flow");
+            out.printf("[%d, %d]", basicBlockLocation->startOffset(), basicBlockLocation->endOffset());
             break;
         }
         case op_not: {
@@ -785,6 +943,10 @@ void CodeBlock::dumpBytecode(
             printUnaryOp(out, exec, location, it, "to_number");
             break;
         }
+        case op_to_string: {
+            printUnaryOp(out, exec, location, it, "to_string");
+            break;
+        }
         case op_negate: {
             printUnaryOp(out, exec, location, it, "negate");
             break;
@@ -885,6 +1047,10 @@ void CodeBlock::dumpBytecode(
             printUnaryOp(out, exec, location, it, "is_object");
             break;
         }
+        case op_is_object_or_null: {
+            printUnaryOp(out, exec, location, it, "is_object_or_null");
+            break;
+        }
         case op_is_function: {
             printUnaryOp(out, exec, location, it, "is_function");
             break;
@@ -902,10 +1068,10 @@ void CodeBlock::dumpBytecode(
             break;
         }
         case op_init_global_const: {
-            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
+            WriteBarrier<Unknown>* variablePointer = (++it)->u.variablePointer;
             int r0 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "init_global_const");
-            out.printf("g%d(%p), %s", m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(r0).data());
+            out.printf("g%d(%p), %s", m_globalObject->findVariableIndex(variablePointer).offset(), variablePointer, registerName(r0).data());
             it++;
             it++;
             break;
@@ -918,33 +1084,50 @@ void CodeBlock::dumpBytecode(
             dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
-        case op_get_arguments_length: {
-            printUnaryOp(out, exec, location, it, "get_arguments_length");
-            it++;
-            break;
-        }
         case op_put_by_id: {
             printPutByIdOp(out, exec, location, it, "put_by_id");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
             break;
         }
         case op_put_by_id_out_of_line: {
             printPutByIdOp(out, exec, location, it, "put_by_id_out_of_line");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
             break;
         }
         case op_put_by_id_transition_direct: {
             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
             break;
         }
         case op_put_by_id_transition_direct_out_of_line: {
             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct_out_of_line");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
             break;
         }
         case op_put_by_id_transition_normal: {
             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
             break;
         }
         case op_put_by_id_transition_normal_out_of_line: {
             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal_out_of_line");
+            printPutByIdCacheStatus(out, exec, location, stubInfos);
+            break;
+        }
+        case op_put_getter_by_id: {
+            int r0 = (++it)->u.operand;
+            int id0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "put_getter_by_id");
+            out.printf("%s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data());
+            break;
+        }
+        case op_put_setter_by_id: {
+            int r0 = (++it)->u.operand;
+            int id0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "put_setter_by_id");
+            out.printf("%s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data());
             break;
         }
         case op_put_getter_setter: {
@@ -974,27 +1157,6 @@ void CodeBlock::dumpBytecode(
             dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
-        case op_get_argument_by_val: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            int r2 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "get_argument_by_val");
-            out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
-            ++it;
-            dumpValueProfiling(out, it, hasPrintedProfiling);
-            break;
-        }
-        case op_get_by_pname: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            int r2 = (++it)->u.operand;
-            int r3 = (++it)->u.operand;
-            int r4 = (++it)->u.operand;
-            int r5 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "get_by_pname");
-            out.printf("%s, %s, %s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), registerName(r4).data(), registerName(r5).data());
-            break;
-        }
         case op_put_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -1153,25 +1315,18 @@ void CodeBlock::dumpBytecode(
         }
         case op_new_func: {
             int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
-            int shouldCheck = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "new_func");
-            out.printf("%s, f%d, %s", registerName(r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
-            break;
-        }
-        case op_new_captured_func: {
-            int r0 = (++it)->u.operand;
-            int f0 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "new_captured_func");
-            out.printf("%s, f%d", registerName(r0).data(), f0);
-            ++it;
+            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
             break;
         }
         case op_new_func_exp: {
             int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "new_func_exp");
-            out.printf("%s, f%d", registerName(r0).data(), f0);
+            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
             break;
         }
         case op_call: {
@@ -1197,31 +1352,12 @@ void CodeBlock::dumpBytecode(
             dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
-            
-        case op_tear_off_activation: {
-            int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "tear_off_activation", r0);
-            break;
-        }
-        case op_tear_off_arguments: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "tear_off_arguments");
-            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
-            break;
-        }
+
         case op_ret: {
             int r0 = (++it)->u.operand;
             printLocationOpAndRegisterOperand(out, exec, location, it, "ret", r0);
             break;
         }
-        case op_ret_object_or_this: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "constructor_ret");
-            out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
-            break;
-        }
         case op_construct: {
             printCallOp(out, exec, location, it, "construct", DumpCaches, hasPrintedProfiling, callLinkInfos);
             break;
@@ -1241,49 +1377,116 @@ void CodeBlock::dumpBytecode(
             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
-        case op_get_pnames: {
-            int r0 = it[1].u.operand;
-            int r1 = it[2].u.operand;
-            int r2 = it[3].u.operand;
-            int r3 = it[4].u.operand;
-            int offset = it[5].u.operand;
-            printLocationAndOp(out, exec, location, it, "get_pnames");
-            out.printf("%s, %s, %s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), offset, location + offset);
-            it += OPCODE_LENGTH(op_get_pnames) - 1;
+        case op_get_enumerable_length: {
+            int dst = it[1].u.operand;
+            int base = it[2].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_get_enumerable_length");
+            out.printf("%s, %s", registerName(dst).data(), registerName(base).data());
+            it += OPCODE_LENGTH(op_get_enumerable_length) - 1;
+            break;
+        }
+        case op_has_indexed_property: {
+            int dst = it[1].u.operand;
+            int base = it[2].u.operand;
+            int propertyName = it[3].u.operand;
+            ArrayProfile* arrayProfile = it[4].u.arrayProfile;
+            printLocationAndOp(out, exec, location, it, "op_has_indexed_property");
+            out.printf("%s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), arrayProfile);
+            it += OPCODE_LENGTH(op_has_indexed_property) - 1;
+            break;
+        }
+        case op_has_structure_property: {
+            int dst = it[1].u.operand;
+            int base = it[2].u.operand;
+            int propertyName = it[3].u.operand;
+            int enumerator = it[4].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_has_structure_property");
+            out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(enumerator).data());
+            it += OPCODE_LENGTH(op_has_structure_property) - 1;
+            break;
+        }
+        case op_has_generic_property: {
+            int dst = it[1].u.operand;
+            int base = it[2].u.operand;
+            int propertyName = it[3].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_has_generic_property");
+            out.printf("%s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data());
+            it += OPCODE_LENGTH(op_has_generic_property) - 1;
             break;
         }
-        case op_next_pname: {
-            int dest = it[1].u.operand;
+        case op_get_direct_pname: {
+            int dst = it[1].u.operand;
             int base = it[2].u.operand;
-            int i = it[3].u.operand;
-            int size = it[4].u.operand;
-            int iter = it[5].u.operand;
-            int offset = it[6].u.operand;
-            printLocationAndOp(out, exec, location, it, "next_pname");
-            out.printf("%s, %s, %s, %s, %s, %d(->%d)", registerName(dest).data(), registerName(base).data(), registerName(i).data(), registerName(size).data(), registerName(iter).data(), offset, location + offset);
-            it += OPCODE_LENGTH(op_next_pname) - 1;
+            int propertyName = it[3].u.operand;
+            int index = it[4].u.operand;
+            int enumerator = it[5].u.operand;
+            ValueProfile* profile = it[6].u.profile;
+            printLocationAndOp(out, exec, location, it, "op_get_direct_pname");
+            out.printf("%s, %s, %s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(index).data(), registerName(enumerator).data(), profile);
+            it += OPCODE_LENGTH(op_get_direct_pname) - 1;
+            break;
+
+        }
+        case op_get_property_enumerator: {
+            int dst = it[1].u.operand;
+            int base = it[2].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_get_property_enumerator");
+            out.printf("%s, %s", registerName(dst).data(), registerName(base).data());
+            it += OPCODE_LENGTH(op_get_property_enumerator) - 1;
+            break;
+        }
+        case op_enumerator_structure_pname: {
+            int dst = it[1].u.operand;
+            int enumerator = it[2].u.operand;
+            int index = it[3].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_enumerator_structure_pname");
+            out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data());
+            it += OPCODE_LENGTH(op_enumerator_structure_pname) - 1;
+            break;
+        }
+        case op_enumerator_generic_pname: {
+            int dst = it[1].u.operand;
+            int enumerator = it[2].u.operand;
+            int index = it[3].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_enumerator_generic_pname");
+            out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data());
+            it += OPCODE_LENGTH(op_enumerator_generic_pname) - 1;
+            break;
+        }
+        case op_to_index_string: {
+            int dst = it[1].u.operand;
+            int index = it[2].u.operand;
+            printLocationAndOp(out, exec, location, it, "op_to_index_string");
+            out.printf("%s, %s", registerName(dst).data(), registerName(index).data());
+            it += OPCODE_LENGTH(op_to_index_string) - 1;
             break;
         }
         case op_push_with_scope: {
-            int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "push_with_scope", r0);
+            int dst = (++it)->u.operand;
+            int newScope = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "push_with_scope");
+            out.printf("%s, %s", registerName(dst).data(), registerName(newScope).data());
             break;
         }
         case op_pop_scope: {
-            printLocationAndOp(out, exec, location, it, "pop_scope");
+            int r0 = (++it)->u.operand;
+            printLocationOpAndRegisterOperand(out, exec, location, it, "pop_scope", r0);
             break;
         }
         case op_push_name_scope: {
-            int id0 = (++it)->u.operand;
+            int dst = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            unsigned attributes = (++it)->u.operand;
+            int k0 = (++it)->u.operand;
+            JSNameScope::Type scopeType = (JSNameScope::Type)(++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "push_name_scope");
-            out.printf("%s, %s, %u", idName(id0, identifier(id0)).data(), registerName(r1).data(), attributes);
+            out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(r1).data(), constantName(k0).data(), (scopeType == JSNameScope::FunctionNameScope) ? "functionScope" : ((scopeType == JSNameScope::CatchScope) ? "catchScope" : "unknownScopeType"));
             break;
         }
         case op_catch: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "catch", r0);
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "catch");
+            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
         case op_throw: {
@@ -1295,7 +1498,7 @@ void CodeBlock::dumpBytecode(
             int k0 = (++it)->u.operand;
             int k1 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "throw_static_error");
-            out.printf("%s, %s", constantName(k0, getConstant(k0)).data(), k1 ? "true" : "false");
+            out.printf("%s, %s", constantName(k0).data(), k1 ? "true" : "false");
             break;
         }
         case op_debug: {
@@ -1322,11 +1525,12 @@ void CodeBlock::dumpBytecode(
         }
         case op_resolve_scope: {
             int r0 = (++it)->u.operand;
+            int scope = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
             int depth = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "resolve_scope");
-            out.printf("%s, %s, %u<%s|%s>, %d", registerName(r0).data(), idName(id0, identifier(id0)).data(),
+            out.printf("%s, %s, %s, %u<%s|%s>, %d", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data(),
                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
                 depth);
             ++it;
@@ -1339,12 +1543,14 @@ void CodeBlock::dumpBytecode(
             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
             ++it; // Structure
             int operand = (++it)->u.operand; // Operand
-            ++it; // Skip value profile.
             printLocationAndOp(out, exec, location, it, "get_from_scope");
-            out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
-                registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(),
-                modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
-                operand);
+            out.print(registerName(r0), ", ", registerName(r1));
+            if (static_cast<unsigned>(id0) == UINT_MAX)
+                out.print(", anonymous");
+            else
+                out.print(", ", idName(id0, identifier(id0)));
+            out.print(", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, ", operand);
+            dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
         case op_put_to_scope: {
@@ -1355,10 +1561,29 @@ void CodeBlock::dumpBytecode(
             ++it; // Structure
             int operand = (++it)->u.operand; // Operand
             printLocationAndOp(out, exec, location, it, "put_to_scope");
-            out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
-                registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
-                modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
-                operand);
+            out.print(registerName(r0));
+            if (static_cast<unsigned>(id0) == UINT_MAX)
+                out.print(", anonymous");
+            else
+                out.print(", ", idName(id0, identifier(id0)));
+            out.print(", ", registerName(r1), ", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, <structure>, ", operand);
+            break;
+        }
+        case op_get_from_arguments: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "get_from_arguments");
+            out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), offset);
+            dumpValueProfiling(out, it, hasPrintedProfiling);
+            break;
+        }
+        case op_put_to_arguments: {
+            int r0 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "put_to_arguments");
+            out.printf("%s, %d, %s", registerName(r0).data(), offset, registerName(r1).data());
             break;
         }
         default:
@@ -1416,6 +1641,28 @@ static size_t sizeInBytes(const Vector<T>& vector)
     return vector.capacity() * sizeof(T);
 }
 
+namespace {
+
+class PutToScopeFireDetail : public FireDetail {
+public:
+    PutToScopeFireDetail(CodeBlock* codeBlock, const Identifier& ident)
+        : m_codeBlock(codeBlock)
+        , m_ident(ident)
+    {
+    }
+    
+    virtual void dump(PrintStream& out) const override
+    {
+        out.print("Linking put_to_scope in ", FunctionExecutableDump(jsCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())), " for ", m_ident);
+    }
+    
+private:
+    CodeBlock* m_codeBlock;
+    const Identifier& m_ident;
+};
+
+} // anonymous namespace
+
 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
     : m_globalObject(other.m_globalObject)
     , m_heap(other.m_heap)
@@ -1433,17 +1680,17 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
     , m_vm(other.m_vm)
     , m_instructions(other.m_instructions)
     , m_thisRegister(other.m_thisRegister)
-    , m_argumentsRegister(other.m_argumentsRegister)
-    , m_activationRegister(other.m_activationRegister)
+    , m_scopeRegister(other.m_scopeRegister)
+    , m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
     , m_isStrictMode(other.m_isStrictMode)
     , m_needsActivation(other.m_needsActivation)
     , m_mayBeExecuting(false)
-    , m_visitAggregateHasBeenCalled(false)
     , m_source(other.m_source)
     , m_sourceOffset(other.m_sourceOffset)
     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
     , m_codeType(other.m_codeType)
     , m_constantRegisters(other.m_constantRegisters)
+    , m_constantsSourceCodeRepresentation(other.m_constantsSourceCodeRepresentation)
     , m_functionDecls(other.m_functionDecls)
     , m_functionExprs(other.m_functionExprs)
     , m_osrExitCounter(0)
@@ -1454,8 +1701,11 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
 #endif
 {
+    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+
     ASSERT(m_heap->isDeferred());
-    
+    ASSERT(m_scopeRegister.isLocal());
+
     if (SymbolTable* symbolTable = other.symbolTable())
         m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
     
@@ -1473,7 +1723,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
     }
     
     m_heap->m_codeBlocks.add(this);
-    m_heap->reportExtraMemoryCost(sizeof(CodeBlock));
+    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
 }
 
 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
@@ -1492,12 +1742,11 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
     , m_vm(unlinkedCodeBlock->vm())
     , m_thisRegister(unlinkedCodeBlock->thisRegister())
-    , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
-    , m_activationRegister(unlinkedCodeBlock->activationRegister())
+    , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
+    , m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
     , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
     , m_mayBeExecuting(false)
-    , m_visitAggregateHasBeenCalled(false)
     , m_source(sourceProvider)
     , m_sourceOffset(sourceOffset)
     , m_firstLineColumnOffset(firstLineColumnOffset)
@@ -1509,13 +1758,21 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
 #endif
 {
+    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+
     ASSERT(m_heap->isDeferred());
+    ASSERT(m_scopeRegister.isLocal());
 
     bool didCloneSymbolTable = false;
     
     if (SymbolTable* symbolTable = unlinkedCodeBlock->symbolTable()) {
-        if (codeType() == FunctionCode && symbolTable->captureCount()) {
-            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneCapturedNames(*m_vm));
+        if (m_vm->typeProfiler()) {
+            ConcurrentJITLocker locker(symbolTable->m_lock);
+            symbolTable->prepareForTypeProfiling(locker);
+        }
+
+        if (codeType() == FunctionCode && symbolTable->scopeSize()) {
+            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneScopePart(*m_vm));
             didCloneSymbolTable = true;
         } else
             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
@@ -1524,39 +1781,33 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
     ASSERT(m_source);
     setNumParameters(unlinkedCodeBlock->numParameters());
 
-    setConstantRegisters(unlinkedCodeBlock->constantRegisters());
+    if (vm()->typeProfiler() || vm()->controlFlowProfiler())
+        vm()->functionHasExecutedCache()->removeUnexecutedRange(m_ownerExecutable->sourceID(), m_ownerExecutable->typeProfilingStartOffset(), m_ownerExecutable->typeProfilingEndOffset());
+
+    setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
     if (unlinkedCodeBlock->usesGlobalObject())
         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
+
+    for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
+        LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
+        if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
+            m_constantRegisters[registerIndex].set(*m_vm, ownerExecutable, m_globalObject->jsCellForLinkTimeConstant(type));
+    }
+
     m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
-        unsigned lineCount = unlinkedExecutable->lineCount();
-        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
-        bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
-        unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
-        bool endColumnIsOnStartLine = !lineCount;
-        unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
-        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
-        unsigned sourceLength = unlinkedExecutable->sourceLength();
-        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
-        FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
-        m_functionDecls[i].set(*m_vm, ownerExecutable, executable);
+        if (vm()->typeProfiler() || vm()->controlFlowProfiler())
+            vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+        m_functionDecls[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
     m_functionExprs.resizeToFit(unlinkedCodeBlock->numberOfFunctionExprs());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
-        unsigned lineCount = unlinkedExecutable->lineCount();
-        unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
-        bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
-        unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
-        bool endColumnIsOnStartLine = !lineCount;
-        unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
-        unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
-        unsigned sourceLength = unlinkedExecutable->sourceLength();
-        SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
-        FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
-        m_functionExprs[i].set(*m_vm, ownerExecutable, executable);
+        if (vm()->typeProfiler() || vm()->controlFlowProfiler())
+            vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+        m_functionExprs[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
     if (unlinkedCodeBlock->hasRareData()) {
@@ -1572,13 +1823,13 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
             m_rareData->m_exceptionHandlers.resizeToFit(count);
             size_t nonLocalScopeDepth = scope->depth();
             for (size_t i = 0; i < count; i++) {
-                const UnlinkedHandlerInfo& handler = unlinkedCodeBlock->exceptionHandler(i);
-                m_rareData->m_exceptionHandlers[i].start = handler.start;
-                m_rareData->m_exceptionHandlers[i].end = handler.end;
-                m_rareData->m_exceptionHandlers[i].target = handler.target;
-                m_rareData->m_exceptionHandlers[i].scopeDepth = nonLocalScopeDepth + handler.scopeDepth;
+                const UnlinkedHandlerInfo& unlinkedHandler = unlinkedCodeBlock->exceptionHandler(i);
+                HandlerInfo& handler = m_rareData->m_exceptionHandlers[i];
 #if ENABLE(JIT)
-                m_rareData->m_exceptionHandlers[i].nativeCode = CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(op_catch)));
+                handler.initialize(unlinkedHandler, nonLocalScopeDepth,
+                    CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(op_catch))));
+#else
+                handler.initialize(unlinkedHandler, nonLocalScopeDepth);
 #endif
             }
         }
@@ -1636,17 +1887,25 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
             instructions[i + j].u.operand = pc[j].u.operand;
         }
         switch (pc[0].u.opcode) {
+        case op_has_indexed_property: {
+            int arrayProfileIndex = pc[opLength - 1].u.operand;
+            m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
+
+            instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
+            break;
+        }
         case op_call_varargs:
         case op_construct_varargs:
-        case op_get_by_val:
-        case op_get_argument_by_val: {
+        case op_get_by_val: {
             int arrayProfileIndex = pc[opLength - 2].u.operand;
             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
 
             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
             FALLTHROUGH;
         }
-        case op_get_by_id: {
+        case op_get_direct_pname:
+        case op_get_by_id:
+        case op_get_from_arguments: {
             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
             ASSERT(profile->m_bytecodeOffset == -1);
             profile->m_bytecodeOffset = i;
@@ -1716,19 +1975,20 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
                 break;
 
             instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const);
-            instructions[i + 1] = &m_globalObject->registerAt(entry.getIndex());
+            instructions[i + 1] = &m_globalObject->variableAt(entry.varOffset().scopeOffset());
             break;
         }
 
         case op_resolve_scope: {
-            const Identifier& ident = identifier(pc[2].u.operand);
-            ResolveType type = static_cast<ResolveType>(pc[3].u.operand);
+            const Identifier& ident = identifier(pc[3].u.operand);
+            ResolveType type = static_cast<ResolveType>(pc[4].u.operand);
+            RELEASE_ASSERT(type != LocalClosureVar);
 
-            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, type);
-            instructions[i + 3].u.operand = op.type;
-            instructions[i + 4].u.operand = op.depth;
-            if (op.activation)
-                instructions[i + 5].u.activation.set(*vm(), ownerExecutable, op.activation);
+            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, type);
+            instructions[i + 4].u.operand = op.type;
+            instructions[i + 5].u.operand = op.depth;
+            if (op.lexicalEnvironment)
+                instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable());
             break;
         }
 
@@ -1739,9 +1999,16 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
             instructions[i + opLength - 1] = profile;
 
             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
-            const Identifier& ident = identifier(pc[3].u.operand);
+
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
-            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, modeAndType.type());
+            if (modeAndType.type() == LocalClosureVar) {
+                instructions[i + 4] = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand();
+                break;
+            }
+
+            const Identifier& ident = identifier(pc[3].u.operand);
+
+            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, modeAndType.type());
 
             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
@@ -1754,35 +2021,130 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
 
         case op_put_to_scope: {
             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-            const Identifier& ident = identifier(pc[2].u.operand);
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
-            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Put, modeAndType.type());
+            if (modeAndType.type() == LocalClosureVar) {
+                // Only do watching if the property we're putting to is not anonymous.
+                if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
+                    RELEASE_ASSERT(didCloneSymbolTable);
+                    const Identifier& ident = identifier(pc[2].u.operand);
+                    ConcurrentJITLocker locker(m_symbolTable->m_lock);
+                    SymbolTable::Map::iterator iter = m_symbolTable->find(locker, ident.impl());
+                    ASSERT(iter != m_symbolTable->end(locker));
+                    iter->value.prepareToWatch();
+                    instructions[i + 5].u.watchpointSet = iter->value.watchpointSet();
+                } else
+                    instructions[i + 5].u.watchpointSet = nullptr;
+                break;
+            }
+
+            const Identifier& ident = identifier(pc[2].u.operand);
+
+            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Put, modeAndType.type());
 
             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
             else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) {
                 if (op.watchpointSet)
-                    op.watchpointSet->invalidate();
+                    op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident));
             } else if (op.structure)
                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
+
             break;
         }
-            
-        case op_captured_mov:
-        case op_new_captured_func: {
-            if (pc[3].u.index == UINT_MAX) {
-                instructions[i + 3].u.watchpointSet = 0;
+
+        case op_profile_type: {
+            RELEASE_ASSERT(vm()->typeProfiler());
+            // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
+            size_t instructionOffset = i + opLength - 1;
+            unsigned divotStart, divotEnd;
+            GlobalVariableID globalVariableID = 0;
+            RefPtr<TypeSet> globalTypeSet;
+            bool shouldAnalyze = m_unlinkedCode->typeProfilerExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
+            VirtualRegister profileRegister(pc[1].u.operand);
+            ProfileTypeBytecodeFlag flag = static_cast<ProfileTypeBytecodeFlag>(pc[3].u.operand);
+            SymbolTable* symbolTable = nullptr;
+
+            switch (flag) {
+            case ProfileTypeBytecodePutToScope:
+            case ProfileTypeBytecodeGetFromScope: {
+                const Identifier& ident = identifier(pc[4].u.operand);
+                ResolveType type = static_cast<ResolveType>(pc[5].u.operand);
+                ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, (flag == ProfileTypeBytecodeGetFromScope ? Get : Put), type);
+
+                // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
+                // https://bugs.webkit.org/show_bug.cgi?id=135184
+                if (op.type == ClosureVar)
+                    symbolTable = op.lexicalEnvironment->symbolTable();
+                else if (op.type == GlobalVar)
+                    symbolTable = m_globalObject.get()->symbolTable();
+                
+                if (symbolTable) {
+                    ConcurrentJITLocker locker(symbolTable->m_lock);
+                    // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
+                    symbolTable->prepareForTypeProfiling(locker);
+                    globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm());
+                    globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm());
+                } else
+                    globalVariableID = TypeProfilerNoGlobalIDExists;
+
+                break;
+            }
+            case ProfileTypeBytecodePutToLocalScope:
+            case ProfileTypeBytecodeGetFromLocalScope: {
+                const Identifier& ident = identifier(pc[4].u.operand);
+                symbolTable = m_symbolTable.get();
+                ConcurrentJITLocker locker(symbolTable->m_lock);
+                // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
+                symbolTable->prepareForTypeProfiling(locker);
+                globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm());
+                globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm());
+
+                break;
+            }
+
+            case ProfileTypeBytecodeHasGlobalID: {
+                symbolTable = m_symbolTable.get();
+                ConcurrentJITLocker locker(symbolTable->m_lock);
+                globalVariableID = symbolTable->uniqueIDForOffset(locker, VarOffset(profileRegister), *vm());
+                globalTypeSet = symbolTable->globalTypeSetForOffset(locker, VarOffset(profileRegister), *vm());
                 break;
             }
-            StringImpl* uid = identifier(pc[3].u.index).impl();
-            RELEASE_ASSERT(didCloneSymbolTable);
-            ConcurrentJITLocker locker(m_symbolTable->m_lock);
-            SymbolTable::Map::iterator iter = m_symbolTable->find(locker, uid);
-            ASSERT(iter != m_symbolTable->end(locker));
-            iter->value.prepareToWatch(symbolTable());
-            instructions[i + 3].u.watchpointSet = iter->value.watchpointSet();
+            case ProfileTypeBytecodeDoesNotHaveGlobalID: 
+            case ProfileTypeBytecodeFunctionArgument: {
+                globalVariableID = TypeProfilerNoGlobalIDExists;
+                break;
+            }
+            case ProfileTypeBytecodeFunctionReturnStatement: {
+                RELEASE_ASSERT(ownerExecutable->isFunctionExecutable());
+                globalTypeSet = jsCast<FunctionExecutable*>(ownerExecutable)->returnStatementTypeSet();
+                globalVariableID = TypeProfilerReturnStatement;
+                if (!shouldAnalyze) {
+                    // Because a return statement can be added implicitly to return undefined at the end of a function,
+                    // and these nodes don't emit expression ranges because they aren't in the actual source text of
+                    // the user's program, give the type profiler some range to identify these return statements.
+                    // Currently, the text offset that is used as identification is on the open brace of the function 
+                    // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable.
+                    divotStart = divotEnd = m_sourceOffset;
+                    shouldAnalyze = true;
+                }
+                break;
+            }
+            }
+
+            std::pair<TypeLocation*, bool> locationPair = vm()->typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
+                m_ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, vm());
+            TypeLocation* location = locationPair.first;
+            bool isNewLocation = locationPair.second;
+
+            if (flag == ProfileTypeBytecodeFunctionReturnStatement)
+                location->m_divotForFunctionOffsetIfReturnStatement = m_sourceOffset;
+
+            if (shouldAnalyze && isNewLocation)
+                vm()->typeProfiler()->insertNewLocation(location);
+
+            instructions[i + 2].u.location = location;
             break;
         }
 
@@ -1797,6 +2159,10 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
         }
         i += opLength;
     }
+
+    if (vm()->controlFlowProfiler())
+        insertBasicBlockBoundariesForControlFlowProfiler(instructions);
+
     m_instructions = WTF::RefCountedArray<Instruction>(instructions);
 
     // Set optimization thresholds only after m_instructions is initialized, since these
@@ -1814,7 +2180,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
         dumpBytecode();
     
     m_heap->m_codeBlocks.add(this);
-    m_heap->reportExtraMemoryCost(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
+    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
 }
 
 CodeBlock::~CodeBlock()
@@ -1836,6 +2202,8 @@ CodeBlock::~CodeBlock()
     // destructor will try to remove nodes from our (no longer valid) linked list.
     while (m_incomingCalls.begin() != m_incomingCalls.end())
         m_incomingCalls.begin()->remove();
+    while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
+        m_incomingPolymorphicCalls.begin()->remove();
     
     // Note that our outgoing calls will be removed from other CodeBlocks'
     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
@@ -1876,26 +2244,11 @@ void CodeBlock::visitAggregate(SlotVisitor& visitor)
 {
 #if ENABLE(PARALLEL_GC)
     // I may be asked to scan myself more than once, and it may even happen concurrently.
-    // To this end, use a CAS loop to check if I've been called already. Only one thread
-    // may proceed past this point - whichever one wins the CAS race.
-    unsigned oldValue;
-    do {
-        oldValue = m_visitAggregateHasBeenCalled;
-        if (oldValue) {
-            // Looks like someone else won! Return immediately to ensure that we don't
-            // trace the same CodeBlock concurrently. Doing so is hazardous since we will
-            // be mutating the state of ValueProfiles, which contain JSValues, which can
-            // have word-tearing on 32-bit, leading to awesome timing-dependent crashes
-            // that are nearly impossible to track down.
-            
-            // Also note that it must be safe to return early as soon as we see the
-            // value true (well, (unsigned)1), since once a GC thread is in this method
-            // and has won the CAS race (i.e. was responsible for setting the value true)
-            // it will definitely complete the rest of this method before declaring
-            // termination.
-            return;
-        }
-    } while (!WTF::weakCompareAndSwap(&m_visitAggregateHasBeenCalled, 0, 1));
+    // To this end, use an atomic operation to check (and set) if I've been called already.
+    // Only one thread may proceed past this point - whichever one wins the atomic set race.
+    bool setByMe = m_visitAggregateHasBeenCalled.compareExchangeStrong(false, true);
+    if (!setByMe)
+        return;
 #endif // ENABLE(PARALLEL_GC)
     
     if (!!m_alternative)
@@ -1904,15 +2257,15 @@ void CodeBlock::visitAggregate(SlotVisitor& visitor)
     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
         otherBlock->visitAggregate(visitor);
 
-    visitor.reportExtraMemoryUsage(ownerExecutable(), sizeof(CodeBlock));
+    visitor.reportExtraMemoryVisited(ownerExecutable(), sizeof(CodeBlock));
     if (m_jitCode)
-        visitor.reportExtraMemoryUsage(ownerExecutable(), m_jitCode->size());
+        visitor.reportExtraMemoryVisited(ownerExecutable(), m_jitCode->size());
     if (m_instructions.size()) {
         // Divide by refCount() because m_instructions points to something that is shared
         // by multiple CodeBlocks, and we only want to count it towards the heap size once.
         // Having each CodeBlock report only its proportional share of the size is one way
         // of accomplishing this.
-        visitor.reportExtraMemoryUsage(ownerExecutable(), m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
+        visitor.reportExtraMemoryVisited(ownerExecutable(), m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
     }
 
     visitor.append(&m_unlinkedCode);
@@ -2000,6 +2353,19 @@ bool CodeBlock::isKnownToBeLiveDuringGC()
 #endif
 }
 
+#if ENABLE(DFG_JIT)
+static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition)
+{
+    if (transition.m_codeOrigin && !Heap::isMarked(transition.m_codeOrigin.get()))
+        return false;
+    
+    if (!Heap::isMarked(transition.m_from.get()))
+        return false;
+    
+    return true;
+}
+#endif // ENABLE(DFG_JIT)
+
 void CodeBlock::propagateTransitions(SlotVisitor& visitor)
 {
     UNUSED_PARAM(visitor);
@@ -2076,21 +2442,28 @@ void CodeBlock::propagateTransitions(SlotVisitor& visitor)
 #if ENABLE(DFG_JIT)
     if (JITCode::isOptimizingJIT(jitType())) {
         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
+        
         for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
-            if ((!dfgCommon->transitions[i].m_codeOrigin
-                 || Heap::isMarked(dfgCommon->transitions[i].m_codeOrigin.get()))
-                && Heap::isMarked(dfgCommon->transitions[i].m_from.get())) {
+            if (shouldMarkTransition(dfgCommon->transitions[i])) {
                 // If the following three things are live, then the target of the
                 // transition is also live:
+                //
                 // - This code block. We know it's live already because otherwise
                 //   we wouldn't be scanning ourselves.
+                //
                 // - The code origin of the transition. Transitions may arise from
                 //   code that was inlined. They are not relevant if the user's
                 //   object that is required for the inlinee to run is no longer
                 //   live.
+                //
                 // - The source of the transition. The transition checks if some
                 //   heap location holds the source, and if so, stores the target.
                 //   Hence the source must be live for the transition to be live.
+                //
+                // We also short-circuit the liveness if the structure is harmless
+                // to mark (i.e. its global object and prototype are both already
+                // live).
+                
                 visitor.append(&dfgCommon->transitions[i].m_to);
             } else
                 allAreMarkedSoFar = false;
@@ -2125,6 +2498,14 @@ void CodeBlock::determineLiveness(SlotVisitor& visitor)
             break;
         }
     }
+    if (allAreLiveSoFar) {
+        for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) {
+            if (!Heap::isMarked(dfgCommon->weakStructureReferences[i].get())) {
+                allAreLiveSoFar = false;
+                break;
+            }
+        }
+    }
     
     // If some weak references are dead, then this fixpoint iteration was
     // unsuccessful.
@@ -2190,28 +2571,38 @@ void CodeBlock::finalizeUnconditionally()
                 if (Options::verboseOSR())
                     dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get());
                 curInstruction[2].u.structure.clear();
+                curInstruction[3].u.toThisStatus = merge(
+                    curInstruction[3].u.toThisStatus, ToThisClearedByGC);
                 break;
-            case op_get_callee:
-                if (!curInstruction[2].u.jsCell || Heap::isMarked(curInstruction[2].u.jsCell.get()))
+            case op_create_this: {
+                auto& cacheWriteBarrier = curInstruction[4].u.jsCell;
+                if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
+                    break;
+                JSCell* cachedFunction = cacheWriteBarrier.get();
+                if (Heap::isMarked(cachedFunction))
                     break;
                 if (Options::verboseOSR())
-                    dataLogF("Clearing LLInt get callee with function %p.\n", curInstruction[2].u.jsCell.get());
-                curInstruction[2].u.jsCell.clear();
+                    dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
+                cacheWriteBarrier.clear();
                 break;
+            }
             case op_resolve_scope: {
-                WriteBarrierBase<JSActivation>& activation = curInstruction[5].u.activation;
-                if (!activation || Heap::isMarked(activation.get()))
+                // Right now this isn't strictly necessary. Any symbol tables that this will refer to
+                // are for outer functions, and we refer to those functions strongly, and they refer
+                // to the symbol table strongly. But it's nice to be on the safe side.
+                WriteBarrierBase<SymbolTable>& symbolTable = curInstruction[6].u.symbolTable;
+                if (!symbolTable || Heap::isMarked(symbolTable.get()))
                     break;
                 if (Options::verboseOSR())
-                    dataLogF("Clearing dead activation %p.\n", activation.get());
-                activation.clear();
+                    dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
+                symbolTable.clear();
                 break;
             }
             case op_get_from_scope:
             case op_put_to_scope: {
                 ResolveModeAndType modeAndType =
                     ResolveModeAndType(curInstruction[4].u.operand);
-                if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks)
+                if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks || modeAndType.type() == LocalClosureVar)
                     continue;
                 WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
                 if (!structure || Heap::isMarked(structure.get()))
@@ -2222,7 +2613,8 @@ void CodeBlock::finalizeUnconditionally()
                 break;
             }
             default:
-                RELEASE_ASSERT_NOT_REACHED();
+                OpcodeID opcodeID = interpreter->getOpcodeID(curInstruction[0].u.opcode);
+                ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]);
             }
         }
 
@@ -2325,6 +2717,15 @@ StructureStubInfo* CodeBlock::addStubInfo()
     return m_stubInfos.add();
 }
 
+StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
+{
+    for (StructureStubInfo* stubInfo : m_stubInfos) {
+        if (stubInfo->codeOrigin == codeOrigin)
+            return stubInfo;
+    }
+    return nullptr;
+}
+
 CallLinkInfo* CodeBlock::addCallLinkInfo()
 {
     ConcurrentJITLocker locker(m_lock);
@@ -2375,7 +2776,7 @@ void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, Structur
 CallLinkInfo* CodeBlock::getCallLinkInfoForBytecodeIndex(unsigned index)
 {
     for (auto iter = m_callLinkInfos.begin(); !!iter; ++iter) {
-        if ((*iter)->codeOrigin == CodeOrigin(index))
+        if ((*iter)->codeOrigin() == CodeOrigin(index))
             return *iter;
     }
     return nullptr;
@@ -2400,6 +2801,13 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
 
 #if ENABLE(DFG_JIT)
     if (JITCode::isOptimizingJIT(jitType())) {
+        // FIXME: This is an antipattern for two reasons. References introduced by the DFG
+        // that aren't in the original CodeBlock being compiled should be weakly referenced.
+        // Inline call frames aren't in the original CodeBlock, so they qualify as weak. Also,
+        // those weak references should already be tracked in the DFG as weak FrozenValues. So,
+        // there is probably no need for this. We already have assertions that this should be
+        // unnecessary.
+        // https://bugs.webkit.org/show_bug.cgi?id=146613
         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
         if (dfgCommon->inlineCallFrames.get())
             dfgCommon->inlineCallFrames->visitAggregate(visitor);
@@ -2428,6 +2836,9 @@ void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
     
     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i)
         visitor.append(&dfgCommon->weakReferences[i]);
+
+    for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i)
+        visitor.append(&dfgCommon->weakStructureReferences[i]);
 #endif    
 }
 
@@ -2476,64 +2887,7 @@ bool CodeBlock::hasOptimizedReplacement()
 }
 #endif
 
-bool CodeBlock::isCaptured(VirtualRegister operand, InlineCallFrame* inlineCallFrame) const
-{
-    if (operand.isArgument())
-        return operand.toArgument() && usesArguments();
-
-    if (inlineCallFrame)
-        return inlineCallFrame->capturedVars.get(operand.toLocal());
-
-    // The activation object isn't in the captured region, but it's "captured"
-    // in the sense that stores to its location can be observed indirectly.
-    if (needsActivation() && operand == activationRegister())
-        return true;
-
-    // Ditto for the arguments object.
-    if (usesArguments() && operand == argumentsRegister())
-        return true;
-    if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
-        return true;
-
-    // We're in global code so there are no locals to capture
-    if (!symbolTable())
-        return false;
-
-    return symbolTable()->isCaptured(operand.offset());
-}
-
-int CodeBlock::framePointerOffsetToGetActivationRegisters(int machineCaptureStart)
-{
-    // We'll be adding this to the stack pointer to get a registers pointer that looks
-    // like it would have looked in the baseline engine. For example, if bytecode would
-    // have put the first captured variable at offset -5 but we put it at offset -1, then
-    // we'll have an offset of 4.
-    int32_t offset = 0;
-    
-    // Compute where we put the captured variables. This offset will point the registers
-    // pointer directly at the first captured var.
-    offset += machineCaptureStart;
-    
-    // Now compute the offset needed to make the runtime see the captured variables at the
-    // same offset that the bytecode would have used.
-    offset -= symbolTable()->captureStart();
-    
-    return offset;
-}
-
-int CodeBlock::framePointerOffsetToGetActivationRegisters()
-{
-    if (!JITCode::isOptimizingJIT(jitType()))
-        return 0;
-#if ENABLE(DFG_JIT)
-    return framePointerOffsetToGetActivationRegisters(jitCode()->dfgCommon()->machineCaptureStart);
-#else
-    RELEASE_ASSERT_NOT_REACHED();
-    return 0;
-#endif
-}
-
-HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
+HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler)
 {
     RELEASE_ASSERT(bytecodeOffset < instructions().size());
 
@@ -2542,10 +2896,14 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
     
     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
+        HandlerInfo& handler = exceptionHandlers[i];
+        if ((requiredHandler == RequiredHandler::CatchHandler) && !handler.isCatchHandler())
+            continue;
+
         // Handlers are ordered innermost first, so the first handler we encounter
         // that contains the source address is the correct handler to use.
-        if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end > bytecodeOffset)
-            return &exceptionHandlers[i];
+        if (handler.start <= bytecodeOffset && handler.end > bytecodeOffset)
+            return &handler;
     }
 
     return 0;
@@ -2554,7 +2912,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
 unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
 {
     RELEASE_ASSERT(bytecodeOffset < instructions().size());
-    return m_ownerExecutable->lineNo() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
+    return m_ownerExecutable->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
 }
 
 unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
@@ -2573,7 +2931,7 @@ void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& d
     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
     divot += m_sourceOffset;
     column += line ? 1 : firstLineColumnOffset();
-    line += m_ownerExecutable->lineNo();
+    line += m_ownerExecutable->firstLine();
 }
 
 bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column)
@@ -2604,6 +2962,7 @@ void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
     
     if (shrinkMode == EarlyShrink) {
         m_constantRegisters.shrinkToFit();
+        m_constantsSourceCodeRepresentation.shrinkToFit();
         
         if (m_rareData) {
             m_rareData->m_switchJumpTables.shrinkToFit();
@@ -2612,27 +2971,6 @@ void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
     } // else don't shrink these, because we would have already pointed pointers into these tables.
 }
 
-unsigned CodeBlock::addOrFindConstant(JSValue v)
-{
-    unsigned result;
-    if (findConstant(v, result))
-        return result;
-    return addConstant(v);
-}
-
-bool CodeBlock::findConstant(JSValue v, unsigned& index)
-{
-    unsigned numberOfConstants = numberOfConstantRegisters();
-    for (unsigned i = 0; i < numberOfConstants; ++i) {
-        if (getConstant(FirstConstantRegisterIndex + i) == v) {
-            index = i;
-            return true;
-        }
-    }
-    index = numberOfConstants;
-    return false;
-}
-
 #if ENABLE(JIT)
 void CodeBlock::unlinkCalls()
 {
@@ -2660,6 +2998,12 @@ void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming)
     noticeIncomingCall(callerFrame);
     m_incomingCalls.push(incoming);
 }
+
+void CodeBlock::linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode* incoming)
+{
+    noticeIncomingCall(callerFrame);
+    m_incomingPolymorphicCalls.push(incoming);
+}
 #endif // ENABLE(JIT)
 
 void CodeBlock::unlinkIncomingCalls()
@@ -2667,11 +3011,13 @@ void CodeBlock::unlinkIncomingCalls()
     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
         m_incomingLLIntCalls.begin()->unlink();
 #if ENABLE(JIT)
-    if (m_incomingCalls.isEmpty())
+    if (m_incomingCalls.isEmpty() && m_incomingPolymorphicCalls.isEmpty())
         return;
     RepatchBuffer repatchBuffer(this);
     while (m_incomingCalls.begin() != m_incomingCalls.end())
         m_incomingCalls.begin()->unlink(repatchBuffer);
+    while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
+        m_incomingPolymorphicCalls.begin()->unlink(repatchBuffer);
 #endif // ENABLE(JIT)
 }
 
@@ -2702,18 +3048,6 @@ PassRefPtr<CodeBlock> CodeBlock::newReplacement()
     return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
 }
 
-const SlowArgument* CodeBlock::machineSlowArguments()
-{
-    if (!JITCode::isOptimizingJIT(jitType()))
-        return symbolTable()->slowArguments();
-    
-#if ENABLE(DFG_JIT)
-    return jitCode()->dfgCommon()->slowArguments.get();
-#else // ENABLE(DFG_JIT)
-    return 0;
-#endif // ENABLE(DFG_JIT)
-}
-
 #if ENABLE(JIT)
 CodeBlock* ProgramCodeBlock::replacement()
 {
@@ -2748,7 +3082,7 @@ DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
 }
 #endif
 
-void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode)
+void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
 {
     RELEASE_ASSERT(reason != Profiler::NotJettisoned);
     
@@ -2757,14 +3091,17 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
         dataLog("Jettisoning ", *this);
         if (mode == CountReoptimization)
             dataLog(" and counting reoptimization");
-        dataLog(" due to ", reason, ".\n");
+        dataLog(" due to ", reason);
+        if (detail)
+            dataLog(", ", *detail);
+        dataLog(".\n");
     }
     
     DeferGCForAWhile deferGC(*m_heap);
     RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
     
     if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get())
-        compilation->setJettisonReason(reason);
+        compilation->setJettisonReason(reason, detail);
     
     // We want to accomplish two things here:
     // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
@@ -2805,6 +3142,7 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod
         dataLog("    Did install baseline version of ", *this, "\n");
 #else // ENABLE(DFG_JIT)
     UNUSED_PARAM(mode);
+    UNUSED_PARAM(detail);
     UNREACHABLE_FOR_PLATFORM();
 #endif // ENABLE(DFG_JIT)
 }
@@ -2816,17 +3154,64 @@ JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
     return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->eitherCodeBlock()->globalObject();
 }
 
+class RecursionCheckFunctor {
+public:
+    RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck)
+        : m_startCallFrame(startCallFrame)
+        , m_codeBlock(codeBlock)
+        , m_depthToCheck(depthToCheck)
+        , m_foundStartCallFrame(false)
+        , m_didRecurse(false)
+    { }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        CallFrame* currentCallFrame = visitor->callFrame();
+
+        if (currentCallFrame == m_startCallFrame)
+            m_foundStartCallFrame = true;
+
+        if (m_foundStartCallFrame) {
+            if (visitor->callFrame()->codeBlock() == m_codeBlock) {
+                m_didRecurse = true;
+                return StackVisitor::Done;
+            }
+
+            if (!m_depthToCheck--)
+                return StackVisitor::Done;
+        }
+
+        return StackVisitor::Continue;
+    }
+
+    bool didRecurse() const { return m_didRecurse; }
+
+private:
+    CallFrame* m_startCallFrame;
+    CodeBlock* m_codeBlock;
+    unsigned m_depthToCheck;
+    bool m_foundStartCallFrame;
+    bool m_didRecurse;
+};
+
 void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
 {
     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
     
     if (Options::verboseCallLink())
-        dataLog("Noticing call link from ", *callerCodeBlock, " to ", *this, "\n");
+        dataLog("Noticing call link from ", pointerDump(callerCodeBlock), " to ", *this, "\n");
     
+#if ENABLE(DFG_JIT)
     if (!m_shouldAlwaysBeInlined)
         return;
+    
+    if (!callerCodeBlock) {
+        m_shouldAlwaysBeInlined = false;
+        if (Options::verboseCallLink())
+            dataLog("    Clearing SABI because caller is native.\n");
+        return;
+    }
 
-#if ENABLE(DFG_JIT)
     if (!hasBaselineJITProfiling())
         return;
 
@@ -2854,6 +3239,13 @@ void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
         return;
     }
     
+    if (JITCode::isOptimizingJIT(callerCodeBlock->jitType())) {
+        m_shouldAlwaysBeInlined = false;
+        if (Options::verboseCallLink())
+            dataLog("    Clearing SABI bcause caller was already optimized.\n");
+        return;
+    }
+    
     if (callerCodeBlock->codeType() != FunctionCode) {
         // If the caller is either eval or global code, assume that that won't be
         // optimized anytime soon. For eval code this is particularly true since we
@@ -2863,21 +3255,22 @@ void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
             dataLog("    Clearing SABI because caller is not a function.\n");
         return;
     }
-    
-    ExecState* frame = callerFrame;
-    for (unsigned i = Options::maximumInliningDepth(); i--; frame = frame->callerFrame()) {
-        if (frame->isVMEntrySentinel())
-            break;
-        if (frame->codeBlock() == this) {
-            // Recursive calls won't be inlined.
-            if (Options::verboseCallLink())
-                dataLog("    Clearing SABI because recursion was detected.\n");
-            m_shouldAlwaysBeInlined = false;
-            return;
-        }
+
+    // Recursive calls won't be inlined.
+    RecursionCheckFunctor functor(callerFrame, this, Options::maximumInliningDepth());
+    vm()->topCallFrame->iterate(functor);
+
+    if (functor.didRecurse()) {
+        if (Options::verboseCallLink())
+            dataLog("    Clearing SABI because recursion was detected.\n");
+        m_shouldAlwaysBeInlined = false;
+        return;
     }
     
-    RELEASE_ASSERT(callerCodeBlock->m_capabilityLevelState != DFG::CapabilityLevelNotSet);
+    if (callerCodeBlock->m_capabilityLevelState == DFG::CapabilityLevelNotSet) {
+        dataLog("In call from ", *callerCodeBlock, " ", callerFrame->codeOrigin(), " to ", *this, ": caller's DFG capability level is not set.\n");
+        CRASH();
+    }
     
     if (canCompile(callerCodeBlock->m_capabilityLevelState))
         return;
@@ -3290,9 +3683,7 @@ void CodeBlock::tallyFrequentExitSites()
         DFG::JITCode* jitCode = m_jitCode->dfg();
         for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) {
             DFG::OSRExit& exit = jitCode->osrExit[i];
-            
-            if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
-                continue;
+            exit.considerAddingAsFrequentExitSite(profiledBlock);
         }
         break;
     }
@@ -3305,9 +3696,7 @@ void CodeBlock::tallyFrequentExitSites()
         FTL::JITCode* jitCode = m_jitCode->ftl();
         for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) {
             FTL::OSRExit& exit = jitCode->osrExit[i];
-            
-            if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
-                continue;
+            exit.considerAddingAsFrequentExitSite(profiledBlock);
         }
         break;
     }
@@ -3441,69 +3830,31 @@ String CodeBlock::nameForRegister(VirtualRegister virtualRegister)
     ConcurrentJITLocker locker(symbolTable()->m_lock);
     SymbolTable::Map::iterator end = symbolTable()->end(locker);
     for (SymbolTable::Map::iterator ptr = symbolTable()->begin(locker); ptr != end; ++ptr) {
-        if (ptr->value.getIndex() == virtualRegister.offset()) {
+        if (ptr->value.varOffset() == VarOffset(virtualRegister)) {
             // FIXME: This won't work from the compilation thread.
             // https://bugs.webkit.org/show_bug.cgi?id=115300
-            return String(ptr->key);
+            return ptr->key.get();
         }
     }
-    if (needsActivation() && virtualRegister == activationRegister())
-        return ASCIILiteral("activation");
     if (virtualRegister == thisRegister())
         return ASCIILiteral("this");
-    if (usesArguments()) {
-        if (virtualRegister == argumentsRegister())
-            return ASCIILiteral("arguments");
-        if (unmodifiedArgumentsRegister(argumentsRegister()) == virtualRegister)
-            return ASCIILiteral("real arguments");
-    }
     if (virtualRegister.isArgument())
-        return String::format("arguments[%3d]", virtualRegister.toArgument()).impl();
+        return String::format("arguments[%3d]", virtualRegister.toArgument());
 
     return "";
 }
 
-namespace {
-
-struct VerifyCapturedDef {
-    void operator()(CodeBlock* codeBlock, Instruction* instruction, OpcodeID opcodeID, int operand)
-    {
-        unsigned bytecodeOffset = instruction - codeBlock->instructions().begin();
-        
-        if (codeBlock->isConstantRegisterIndex(operand)) {
-            codeBlock->beginValidationDidFail();
-            dataLog("    At bc#", bytecodeOffset, " encountered a definition of a constant.\n");
-            codeBlock->endValidationDidFail();
-            return;
-        }
-
-        switch (opcodeID) {
-        case op_enter:
-        case op_captured_mov:
-        case op_init_lazy_reg:
-        case op_create_arguments:
-        case op_new_captured_func:
-            return;
-        default:
-            break;
-        }
-        
-        VirtualRegister virtualReg(operand);
-        if (!virtualReg.isLocal())
-            return;
-        
-        if (codeBlock->captureCount() && codeBlock->symbolTable()->isCaptured(operand)) {
-            codeBlock->beginValidationDidFail();
-            dataLog("    At bc#", bytecodeOffset, " encountered invalid assignment to captured variable loc", virtualReg.toLocal(), ".\n");
-            codeBlock->endValidationDidFail();
-            return;
-        }
-        
-        return;
-    }
-};
-
-} // anonymous namespace
+ValueProfile* CodeBlock::valueProfileForBytecodeOffset(int bytecodeOffset)
+{
+    ValueProfile* result = binarySearch<ValueProfile, int>(
+        m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
+        getValueProfileBytecodeOffset<ValueProfile>);
+    ASSERT(result->m_bytecodeOffset != -1);
+    ASSERT(instructions()[bytecodeOffset + opcodeLength(
+        m_vm->interpreter->getOpcodeID(
+            instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result);
+    return result;
+}
 
 void CodeBlock::validate()
 {
@@ -3520,38 +3871,15 @@ void CodeBlock::validate()
     }
     
     for (unsigned i = m_numCalleeRegisters; i--;) {
-        bool isCaptured = false;
         VirtualRegister reg = virtualRegisterForLocal(i);
         
-        if (captureCount())
-            isCaptured = reg.offset() <= captureStart() && reg.offset() > captureEnd();
-        
-        if (isCaptured) {
-            if (!liveAtHead.get(i)) {
-                beginValidationDidFail();
-                dataLog("    Variable loc", i, " is expected to be live because it is captured, but it isn't live.\n");
-                dataLog("    Result: ", liveAtHead, "\n");
-                endValidationDidFail();
-            }
-        } else {
-            if (liveAtHead.get(i)) {
-                beginValidationDidFail();
-                dataLog("    Variable loc", i, " is expected to be dead.\n");
-                dataLog("    Result: ", liveAtHead, "\n");
-                endValidationDidFail();
-            }
+        if (liveAtHead.get(i)) {
+            beginValidationDidFail();
+            dataLog("    Variable ", reg, " is expected to be dead.\n");
+            dataLog("    Result: ", liveAtHead, "\n");
+            endValidationDidFail();
         }
     }
-    
-    for (unsigned bytecodeOffset = 0; bytecodeOffset < instructions().size();) {
-        Instruction* currentInstruction = instructions().begin() + bytecodeOffset;
-        OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);
-        
-        VerifyCapturedDef verifyCapturedDef;
-        computeDefsForBytecodeOffset(this, bytecodeOffset, verifyCapturedDef);
-        
-        bytecodeOffset += opcodeLength(opcodeID);
-    }
 }
 
 void CodeBlock::beginValidationDidFail()
@@ -3600,4 +3928,71 @@ DFG::CapabilityLevel CodeBlock::capabilityLevel()
 }
 #endif
 
+void CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruction, 0, UnsafeVectorOverflow>& instructions)
+{
+    const Vector<size_t>& bytecodeOffsets = unlinkedCodeBlock()->opProfileControlFlowBytecodeOffsets();
+    for (size_t i = 0, offsetsLength = bytecodeOffsets.size(); i < offsetsLength; i++) {
+        // Because op_profile_control_flow is emitted at the beginning of every basic block, finding 
+        // the next op_profile_control_flow will give us the text range of a single basic block.
+        size_t startIdx = bytecodeOffsets[i];
+        RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[startIdx].u.opcode) == op_profile_control_flow);
+        int basicBlockStartOffset = instructions[startIdx + 1].u.operand;
+        int basicBlockEndOffset;
+        if (i + 1 < offsetsLength) {
+            size_t endIdx = bytecodeOffsets[i + 1];
+            RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[endIdx].u.opcode) == op_profile_control_flow);
+            basicBlockEndOffset = instructions[endIdx + 1].u.operand - 1;
+        } else {
+            basicBlockEndOffset = m_sourceOffset + m_ownerExecutable->source().length() - 1; // Offset before the closing brace.
+            basicBlockStartOffset = std::min(basicBlockStartOffset, basicBlockEndOffset); // Some start offsets may be at the closing brace, ensure it is the offset before.
+        }
+
+        // The following check allows for the same textual JavaScript basic block to have its bytecode emitted more
+        // than once and still play nice with the control flow profiler. When basicBlockStartOffset is larger than 
+        // basicBlockEndOffset, it indicates that the bytecode generator has emitted code for the same AST node 
+        // more than once (for example: ForInNode, Finally blocks in TryNode, etc). Though these are different 
+        // basic blocks at the bytecode level, they are generated from the same textual basic block in the JavaScript 
+        // program. The condition: 
+        // (basicBlockEndOffset < basicBlockStartOffset) 
+        // is encountered when op_profile_control_flow lies across the boundary of these duplicated bytecode basic 
+        // blocks and the textual offset goes from the end of the duplicated block back to the beginning. These 
+        // ranges are dummy ranges and are ignored. The duplicated bytecode basic blocks point to the same 
+        // internal data structure, so if any of them execute, it will record the same textual basic block in the 
+        // JavaScript program as executing.
+        // At the bytecode level, this situation looks like:
+        // j: op_profile_control_flow (from j->k, we have basicBlockEndOffset < basicBlockStartOffset)
+        // ...
+        // k: op_profile_control_flow (we want to skip over the j->k block and start fresh at offset k as the start of a new basic block k->m).
+        // ...
+        // m: op_profile_control_flow
+        if (basicBlockEndOffset < basicBlockStartOffset) {
+            RELEASE_ASSERT(i + 1 < offsetsLength); // We should never encounter dummy blocks at the end of a CodeBlock.
+            instructions[startIdx + 1].u.basicBlockLocation = vm()->controlFlowProfiler()->dummyBasicBlock();
+            continue;
+        }
+
+        BasicBlockLocation* basicBlockLocation = vm()->controlFlowProfiler()->getBasicBlockLocation(m_ownerExecutable->sourceID(), basicBlockStartOffset, basicBlockEndOffset);
+
+        // Find all functions that are enclosed within the range: [basicBlockStartOffset, basicBlockEndOffset]
+        // and insert these functions' start/end offsets as gaps in the current BasicBlockLocation.
+        // This is necessary because in the original source text of a JavaScript program, 
+        // function literals form new basic blocks boundaries, but they aren't represented 
+        // inside the CodeBlock's instruction stream.
+        auto insertFunctionGaps = [basicBlockLocation, basicBlockStartOffset, basicBlockEndOffset] (const WriteBarrier<FunctionExecutable>& functionExecutable) {
+            const UnlinkedFunctionExecutable* executable = functionExecutable->unlinkedExecutable();
+            int functionStart = executable->typeProfilingStartOffset();
+            int functionEnd = executable->typeProfilingEndOffset();
+            if (functionStart >= basicBlockStartOffset && functionEnd <= basicBlockEndOffset)
+                basicBlockLocation->insertGap(functionStart, functionEnd);
+        };
+
+        for (const WriteBarrier<FunctionExecutable>& executable : m_functionDecls)
+            insertFunctionGaps(executable);
+        for (const WriteBarrier<FunctionExecutable>& executable : m_functionExprs)
+            insertFunctionGaps(executable);
+
+        instructions[startIdx + 1].u.basicBlockLocation = basicBlockLocation;
+    }
+}
+
 } // namespace JSC
index 18ef0e3c22abeda24df3a6afcb325911cbf3122e..65dab955e68f14757c5ab1a29e197428d0cc8e98 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,7 +70,6 @@
 #include "Watchpoint.h"
 #include <wtf/Bag.h>
 #include <wtf/FastMalloc.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RefCountedArray.h>
 #include <wtf/RefPtr.h>
 #include <wtf/SegmentedVector.h>
@@ -82,10 +81,7 @@ namespace JSC {
 class ExecState;
 class LLIntOffsetsExtractor;
 class RepatchBuffer;
-
-inline VirtualRegister unmodifiedArgumentsRegister(VirtualRegister argumentsRegister) { return VirtualRegister(argumentsRegister.offset() + 1); }
-
-static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
+class TypeLocation;
 
 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
 
@@ -159,7 +155,11 @@ public:
 
     void visitAggregate(SlotVisitor&);
 
-    void dumpBytecode(PrintStream& = WTF::dataFile());
+    void dumpSource();
+    void dumpSource(PrintStream&);
+
+    void dumpBytecode();
+    void dumpBytecode(PrintStream&);
     void dumpBytecode(
         PrintStream&, unsigned bytecodeOffset,
         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
@@ -185,7 +185,11 @@ public:
         return index >= m_numVars;
     }
 
-    HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
+    enum class RequiredHandler {
+        CatchHandler,
+        AnyHandler
+    };
+    HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler = RequiredHandler::AnyHandler);
     unsigned lineNumberForBytecodeOffset(unsigned bytecodeOffset);
     unsigned columnNumberForBytecodeOffset(unsigned bytecodeOffset);
     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
@@ -201,6 +205,10 @@ public:
     StructureStubInfo* addStubInfo();
     Bag<StructureStubInfo>::iterator stubInfoBegin() { return m_stubInfos.begin(); }
     Bag<StructureStubInfo>::iterator stubInfoEnd() { return m_stubInfos.end(); }
+    
+    // O(n) operation. Use getStubInfoMap() unless you really only intend to get one
+    // stub info.
+    StructureStubInfo* findStubInfo(CodeOrigin);
 
     void resetStub(StructureStubInfo&);
     
@@ -225,18 +233,14 @@ public:
     void unlinkCalls();
         
     void linkIncomingCall(ExecState* callerFrame, CallLinkInfo*);
-        
-    bool isIncomingCallAlreadyLinked(CallLinkInfo* incoming)
-    {
-        return m_incomingCalls.isOnList(incoming);
-    }
+    void linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode*);
 #endif // ENABLE(JIT)
 
     void linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo*);
 
-    void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
+    void setJITCodeMap(std::unique_ptr<CompactJITCodeMap> jitCodeMap)
     {
-        m_jitCodeMap = jitCodeMap;
+        m_jitCodeMap = WTF::move(jitCodeMap);
     }
     CompactJITCodeMap* jitCodeMap()
     {
@@ -249,8 +253,6 @@ public:
         return static_cast<Instruction*>(returnAddress) - instructions().begin();
     }
 
-    bool isNumericCompareFunction() { return m_unlinkedCode->isNumericCompareFunction(); }
-
     unsigned numberOfInstructions() const { return m_instructions.size(); }
     RefCountedArray<Instruction>& instructions() { return m_instructions; }
     const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
@@ -261,11 +263,6 @@ public:
 
     unsigned instructionCount() const { return m_instructions.size(); }
 
-    int argumentIndexAfterCapture(size_t argument);
-    
-    bool hasSlowArguments();
-    const SlowArgument* machineSlowArguments();
-
     // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock);
     void install();
     
@@ -275,7 +272,7 @@ public:
     void setJITCode(PassRefPtr<JITCode> code)
     {
         ASSERT(m_heap->isDeferred());
-        m_heap->reportExtraMemoryCost(code->size());
+        m_heap->reportExtraMemoryAllocated(code->size());
         ConcurrentJITLocker locker(m_lock);
         WTF::storeStoreFence(); // This is probably not needed because the lock will also do something similar, but it's good to be paranoid.
         m_jitCode = code;
@@ -306,7 +303,7 @@ public:
     bool hasOptimizedReplacement(); // the typeToReplace is my JITType
 #endif
 
-    void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization);
+    void jettison(Profiler::JettisonReason, ReoptimizationMode = DontCountReoptimization, const FireDetail* = nullptr);
     
     ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
 
@@ -318,73 +315,39 @@ public:
 
     bool usesEval() const { return m_unlinkedCode->usesEval(); }
 
-    void setArgumentsRegister(VirtualRegister argumentsRegister)
+    void setScopeRegister(VirtualRegister scopeRegister)
     {
-        ASSERT(argumentsRegister.isValid());
-        m_argumentsRegister = argumentsRegister;
-        ASSERT(usesArguments());
+        ASSERT(scopeRegister.isLocal() || !scopeRegister.isValid());
+        m_scopeRegister = scopeRegister;
     }
-    VirtualRegister argumentsRegister() const
-    {
-        ASSERT(usesArguments());
-        return m_argumentsRegister;
-    }
-    VirtualRegister uncheckedArgumentsRegister()
+
+    VirtualRegister scopeRegister() const
     {
-        if (!usesArguments())
-            return VirtualRegister();
-        return argumentsRegister();
+        return m_scopeRegister;
     }
+
     void setActivationRegister(VirtualRegister activationRegister)
     {
-        m_activationRegister = activationRegister;
+        m_lexicalEnvironmentRegister = activationRegister;
     }
 
     VirtualRegister activationRegister() const
     {
-        ASSERT(m_activationRegister.isValid());
-        return m_activationRegister;
+        ASSERT(m_lexicalEnvironmentRegister.isValid());
+        return m_lexicalEnvironmentRegister;
     }
 
     VirtualRegister uncheckedActivationRegister()
     {
-        return m_activationRegister;
+        return m_lexicalEnvironmentRegister;
     }
 
-    bool usesArguments() const { return m_argumentsRegister.isValid(); }
-
     bool needsActivation() const
     {
-        ASSERT(m_activationRegister.isValid() == m_needsActivation);
+        ASSERT(m_lexicalEnvironmentRegister.isValid() == m_needsActivation);
         return m_needsActivation;
     }
     
-    unsigned captureCount() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureCount();
-    }
-    
-    int captureStart() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureStart();
-    }
-    
-    int captureEnd() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureEnd();
-    }
-
-    bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const;
-    
-    int framePointerOffsetToGetActivationRegisters(int machineCaptureStart);
-    int framePointerOffsetToGetActivationRegisters();
-
     CodeType codeType() const { return m_unlinkedCode->codeType(); }
     PutPropertySlot::Context putByIdContext() const
     {
@@ -425,17 +388,7 @@ public:
 
     unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
     ValueProfile* valueProfile(int index) { return &m_valueProfiles[index]; }
-    ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
-    {
-        ValueProfile* result = binarySearch<ValueProfile, int>(
-            m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
-            getValueProfileBytecodeOffset<ValueProfile>);
-        ASSERT(result->m_bytecodeOffset != -1);
-        ASSERT(instructions()[bytecodeOffset + opcodeLength(
-            m_vm->interpreter->getOpcodeID(
-                instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result);
-        return result;
-    }
+    ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset);
     SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJITLocker& locker, int bytecodeOffset)
     {
         return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction(locker);
@@ -618,12 +571,13 @@ public:
 #endif
 
     Vector<WriteBarrier<Unknown>>& constants() { return m_constantRegisters; }
-    size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
+    Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
     unsigned addConstant(JSValue v)
     {
         unsigned result = m_constantRegisters.size();
         m_constantRegisters.append(WriteBarrier<Unknown>());
         m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
+        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
         return result;
     }
 
@@ -631,19 +585,19 @@ public:
     {
         unsigned result = m_constantRegisters.size();
         m_constantRegisters.append(WriteBarrier<Unknown>());
+        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
         return result;
     }
 
-    bool findConstant(JSValue, unsigned& result);
-    unsigned addOrFindConstant(JSValue);
     WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
     ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
     ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
+    ALWAYS_INLINE SourceCodeRepresentation constantSourceCodeRepresentation(int index) const { return m_constantsSourceCodeRepresentation[index - FirstConstantRegisterIndex]; }
 
     FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
     int numberOfFunctionDecls() { return m_functionDecls.size(); }
     FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
-
+    
     RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
 
     unsigned numberOfConstantBuffers() const
@@ -937,6 +891,21 @@ public:
 
     bool isKnownToBeLiveDuringGC(); // Will only return valid results when called during GC. Assumes that you've already established that the owner executable is live.
 
+    struct RareData {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        Vector<HandlerInfo> m_exceptionHandlers;
+
+        // Buffers used for large array literals
+        Vector<Vector<JSValue>> m_constantBuffers;
+
+        // Jump Tables
+        Vector<SimpleJumpTable> m_switchJumpTables;
+        Vector<StringJumpTable> m_stringSwitchJumpTables;
+
+        EvalCodeCache m_evalCodeCache;
+    };
+
 protected:
     virtual void visitWeakReferences(SlotVisitor&) override;
     virtual void finalizeUnconditionally() override;
@@ -956,18 +925,16 @@ private:
     
     double optimizationThresholdScalingFactor();
 
-#if ENABLE(JIT)
-    ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
-#endif
-        
     void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
 
-    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants)
+    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
     {
+        ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
         size_t count = constants.size();
-        m_constantRegisters.resize(count);
+        m_constantRegisters.resizeToFit(count);
         for (size_t i = 0; i < count; i++)
             m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
+        m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
     }
 
     void dumpBytecode(
@@ -975,6 +942,7 @@ private:
         const StubInfoMap& = StubInfoMap(), const CallLinkInfoMap& = CallLinkInfoMap());
 
     CString registerName(int r) const;
+    CString constantName(int index) const;
     void printUnaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
     void printBinaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
     void printConditionalJump(PrintStream&, ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
@@ -983,6 +951,7 @@ private:
     enum CacheDumpMode { DumpCaches, DontDumpCaches };
     void printCallOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap&);
     void printPutByIdOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
+    void printPutByIdCacheStatus(PrintStream&, ExecState*, int location, const StubInfoMap&);
     void printLocationAndOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
     void printLocationOpAndRegisterOperand(PrintStream&, ExecState*, int location, const Instruction*& it, const char* op, int operand);
 
@@ -1002,9 +971,11 @@ private:
     void createRareDataIfNecessary()
     {
         if (!m_rareData)
-            m_rareData = adoptPtr(new RareData);
+            m_rareData = std::make_unique<RareData>();
     }
-    
+
+    void insertBasicBlockBoundariesForControlFlowProfiler(Vector<Instruction, 0, UnsafeVectorOverflow>&);
+
 #if ENABLE(JIT)
     void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
     void resetStubDuringGCInternal(RepatchBuffer&, StructureStubInfo&);
@@ -1025,13 +996,13 @@ private:
     RefCountedArray<Instruction> m_instructions;
     WriteBarrier<SymbolTable> m_symbolTable;
     VirtualRegister m_thisRegister;
-    VirtualRegister m_argumentsRegister;
-    VirtualRegister m_activationRegister;
+    VirtualRegister m_scopeRegister;
+    VirtualRegister m_lexicalEnvironmentRegister;
 
     bool m_isStrictMode;
     bool m_needsActivation;
     bool m_mayBeExecuting;
-    uint8_t m_visitAggregateHasBeenCalled;
+    Atomic<bool> m_visitAggregateHasBeenCalled;
 
     RefPtr<SourceProvider> m_source;
     unsigned m_sourceOffset;
@@ -1046,8 +1017,9 @@ private:
     Vector<ByValInfo> m_byValInfos;
     Bag<CallLinkInfo> m_callLinkInfos;
     SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo>> m_incomingCalls;
+    SentinelLinkedList<PolymorphicCallNode, BasicRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
 #endif
-    OwnPtr<CompactJITCodeMap> m_jitCodeMap;
+    std::unique_ptr<CompactJITCodeMap> m_jitCodeMap;
 #if ENABLE(DFG_JIT)
     // This is relevant to non-DFG code blocks that serve as the profiled code block
     // for DFG code blocks.
@@ -1067,6 +1039,7 @@ private:
     // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
     // it, so we're stuck with it for now.
     Vector<WriteBarrier<Unknown>> m_constantRegisters;
+    Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
     Vector<WriteBarrier<FunctionExecutable>> m_functionDecls;
     Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
 
@@ -1084,24 +1057,7 @@ private:
 
     std::unique_ptr<BytecodeLivenessAnalysis> m_livenessAnalysis;
 
-    struct RareData {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        Vector<HandlerInfo> m_exceptionHandlers;
-
-        // Buffers used for large array literals
-        Vector<Vector<JSValue>> m_constantBuffers;
-
-        // Jump Tables
-        Vector<SimpleJumpTable> m_switchJumpTables;
-        Vector<StringJumpTable> m_stringSwitchJumpTables;
-
-        EvalCodeCache m_evalCodeCache;
-    };
-#if COMPILER(MSVC)
-    friend void WTF::deleteOwnedPtr<RareData>(RareData*);
-#endif
-    OwnPtr<RareData> m_rareData;
+    std::unique_ptr<RareData> m_rareData;
 #if ENABLE(JIT)
     DFG::CapabilityLevel m_capabilityLevelState;
 #endif
@@ -1191,7 +1147,7 @@ inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCal
     RELEASE_ASSERT(inlineCallFrame);
     ExecutableBase* executable = inlineCallFrame->executable.get();
     RELEASE_ASSERT(executable->structure()->classInfo() == FunctionExecutable::info());
-    return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
+    return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->specializationKind());
 }
 
 inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
@@ -1201,24 +1157,6 @@ inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigi
     return baselineCodeBlock;
 }
 
-inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
-{
-    if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
-        return CallFrame::argumentOffset(argument);
-    
-    const SlowArgument* slowArguments = symbolTable()->slowArguments();
-    if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
-        return CallFrame::argumentOffset(argument);
-    
-    ASSERT(slowArguments[argument].status == SlowArgument::Captured);
-    return slowArguments[argument].index;
-}
-
-inline bool CodeBlock::hasSlowArguments()
-{
-    return !!symbolTable()->slowArguments();
-}
-
 inline Register& ExecState::r(int index)
 {
     CodeBlock* codeBlock = this->codeBlock();
@@ -1227,21 +1165,20 @@ inline Register& ExecState::r(int index)
     return this[index];
 }
 
+inline Register& ExecState::r(VirtualRegister reg)
+{
+    return r(reg.offset());
+}
+
 inline Register& ExecState::uncheckedR(int index)
 {
     RELEASE_ASSERT(index < FirstConstantRegisterIndex);
     return this[index];
 }
 
-inline JSValue ExecState::argumentAfterCapture(size_t argument)
+inline Register& ExecState::uncheckedR(VirtualRegister reg)
 {
-    if (argument >= argumentCount())
-        return jsUndefined();
-    
-    if (!codeBlock())
-        return this[argumentOffset(argument)].jsValue();
-    
-    return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
+    return uncheckedR(reg.offset());
 }
 
 inline void CodeBlockSet::mark(void* candidateCodeBlock)
@@ -1272,7 +1209,7 @@ inline void CodeBlockSet::mark(CodeBlock* codeBlock)
     
     codeBlock->m_mayBeExecuting = true;
     // We might not have cleared the marks for this CodeBlock, but we need to visit it.
-    codeBlock->m_visitAggregateHasBeenCalled = false;
+    codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
 #if ENABLE(GGC)
     m_currentlyExecuting.append(codeBlock);
 #endif
index 77ff647306c8a9fea0afd8a0625d59af63496e4c..177b24394a8cfa236fca0771cb7a207e9280b8d8 100644 (file)
 
 namespace JSC {
 
-void CodeBlockJettisoningWatchpoint::fireInternal()
+void CodeBlockJettisoningWatchpoint::fireInternal(const FireDetail& detail)
 {
     if (DFG::shouldShowDisassembly())
         dataLog("Firing watchpoint ", RawPointer(this), " on ", *m_codeBlock, "\n");
 
-    m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization);
+    m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &detail);
 
     if (isOnList())
         remove();
index 89d87f4d09d69c1887cc3f37825b370b05d135e5..df4fe7beb2c44a7dad07d66e361b2a5a3657b144 100644 (file)
@@ -45,7 +45,7 @@ public:
     }
     
 protected:
-    virtual void fireInternal() override;
+    virtual void fireInternal(const FireDetail&) override;
 
 private:
     CodeBlock* m_codeBlock;
index 7ec1ce261c081f568c31474f52b6a1314d9e2840..15f75916532b8a85cab66503bc239698b2654732 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -74,7 +74,7 @@ bool CodeOrigin::isApproximatelyEqualTo(const CodeOrigin& other) const
         if (!a.inlineCallFrame)
             return true;
         
-        if (a.inlineCallFrame->executable != b.inlineCallFrame->executable)
+        if (a.inlineCallFrame->executable.get() != b.inlineCallFrame->executable.get())
             return false;
         
         a = a.inlineCallFrame->caller;
@@ -141,6 +141,27 @@ void CodeOrigin::dumpInContext(PrintStream& out, DumpContext*) const
     dump(out);
 }
 
+JSFunction* InlineCallFrame::calleeConstant() const
+{
+    if (calleeRecovery.isConstant())
+        return jsCast<JSFunction*>(calleeRecovery.constant());
+    return nullptr;
+}
+
+void InlineCallFrame::visitAggregate(SlotVisitor& visitor)
+{
+    // FIXME: This is an antipattern for two reasons. References introduced by the DFG
+    // that aren't in the original CodeBlock being compiled should be weakly referenced.
+    // Inline call frames aren't in the original CodeBlock, so they qualify as weak. Also,
+    // those weak references should already be tracked in the DFG as weak FrozenValues. So,
+    // there is probably no need for this. We already have assertions that this should be
+    // unnecessary. Finally, just marking the executable and not anything else in the inline
+    // call frame is almost certainly insufficient for what this method thought it was going
+    // to accomplish.
+    // https://bugs.webkit.org/show_bug.cgi?id=146613
+    visitor.append(&executable);
+}
+
 JSFunction* InlineCallFrame::calleeForCallFrame(ExecState* exec) const
 {
     return jsCast<JSFunction*>(calleeRecovery.recover(exec));
@@ -178,14 +199,14 @@ void InlineCallFrame::dumpInContext(PrintStream& out, DumpContext* context) cons
     out.print(briefFunctionInformation(), ":<", RawPointer(executable.get()));
     if (executable->isStrictMode())
         out.print(" (StrictMode)");
-    out.print(", bc#", caller.bytecodeIndex, ", ", specializationKind());
+    out.print(", bc#", caller.bytecodeIndex, ", ", kind);
     if (isClosureCall)
         out.print(", closure call");
     else
         out.print(", known callee: ", inContext(calleeRecovery.constant(), context));
     out.print(", numArgs+this = ", arguments.size());
-    out.print(", stack < loc", VirtualRegister(stackOffset).toLocal());
-    out.print(">");
+    out.print(", stackOffset = ", stackOffset);
+    out.print(" (", virtualRegisterForLocal(0), " maps to ", virtualRegisterForLocal(0) + stackOffset, ")>");
 }
 
 void InlineCallFrame::dump(PrintStream& out) const
@@ -195,3 +216,32 @@ void InlineCallFrame::dump(PrintStream& out) const
 
 } // namespace JSC
 
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::InlineCallFrame::Kind kind)
+{
+    switch (kind) {
+    case JSC::InlineCallFrame::Call:
+        out.print("Call");
+        return;
+    case JSC::InlineCallFrame::Construct:
+        out.print("Construct");
+        return;
+    case JSC::InlineCallFrame::CallVarargs:
+        out.print("CallVarargs");
+        return;
+    case JSC::InlineCallFrame::ConstructVarargs:
+        out.print("ConstructVarargs");
+        return;
+    case JSC::InlineCallFrame::GetterCall:
+        out.print("GetterCall");
+        return;
+    case JSC::InlineCallFrame::SetterCall:
+        out.print("SetterCall");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
index cffd4eb9e55e8863e04dabc829d46357b4f6081b..d1879a32781a1563a2e461ebdbe7c4bec236bdde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
 
 #include "CodeBlockHash.h"
 #include "CodeSpecializationKind.h"
-#include "JSFunction.h"
 #include "ValueRecovery.h"
 #include "WriteBarrier.h"
 #include <wtf/BitVector.h>
@@ -118,39 +117,97 @@ private:
 };
 
 struct InlineCallFrame {
+    enum Kind {
+        Call,
+        Construct,
+        CallVarargs,
+        ConstructVarargs,
+        
+        // For these, the stackOffset incorporates the argument count plus the true return PC
+        // slot.
+        GetterCall,
+        SetterCall
+    };
+    
+    static Kind kindFor(CodeSpecializationKind kind)
+    {
+        switch (kind) {
+        case CodeForCall:
+            return Call;
+        case CodeForConstruct:
+            return Construct;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return Call;
+    }
+    
+    static Kind varargsKindFor(CodeSpecializationKind kind)
+    {
+        switch (kind) {
+        case CodeForCall:
+            return CallVarargs;
+        case CodeForConstruct:
+            return ConstructVarargs;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return Call;
+    }
+    
+    static CodeSpecializationKind specializationKindFor(Kind kind)
+    {
+        switch (kind) {
+        case Call:
+        case CallVarargs:
+        case GetterCall:
+        case SetterCall:
+            return CodeForCall;
+        case Construct:
+        case ConstructVarargs:
+            return CodeForConstruct;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return CodeForCall;
+    }
+    
+    static bool isVarargs(Kind kind)
+    {
+        switch (kind) {
+        case CallVarargs:
+        case ConstructVarargs:
+            return true;
+        default:
+            return false;
+        }
+    }
+    bool isVarargs() const
+    {
+        return isVarargs(static_cast<Kind>(kind));
+    }
+    
     Vector<ValueRecovery> arguments; // Includes 'this'.
     WriteBarrier<ScriptExecutable> executable;
     ValueRecovery calleeRecovery;
     CodeOrigin caller;
-    BitVector capturedVars; // Indexed by the machine call frame's variable numbering.
-    signed stackOffset : 30;
-    bool isCall : 1;
+
+    signed stackOffset : 28;
+    unsigned kind : 3; // real type is Kind
     bool isClosureCall : 1; // If false then we know that callee/scope are constants and the DFG won't treat them as variables, i.e. they have to be recovered manually.
-    VirtualRegister argumentsRegister; // This is only set if the code uses arguments. The unmodified arguments register follows the unmodifiedArgumentsRegister() convention (see CodeBlock.h).
+    VirtualRegister argumentCountRegister; // Only set when we inline a varargs call.
     
     // There is really no good notion of a "default" set of values for
     // InlineCallFrame's fields. This constructor is here just to reduce confusion if
     // we forgot to initialize explicitly.
     InlineCallFrame()
         : stackOffset(0)
-        , isCall(false)
+        , kind(Call)
         , isClosureCall(false)
     {
     }
     
-    CodeSpecializationKind specializationKind() const { return specializationFromIsCall(isCall); }
-
-    JSFunction* calleeConstant() const
-    {
-        if (calleeRecovery.isConstant())
-            return jsCast<JSFunction*>(calleeRecovery.constant());
-        return 0;
-    }
+    CodeSpecializationKind specializationKind() const { return specializationKindFor(static_cast<Kind>(kind)); }
 
-    void visitAggregate(SlotVisitor& visitor)
-    {
-        visitor.append(&executable);
-    }
+    JSFunction* calleeConstant() const;
+    void visitAggregate(SlotVisitor&);
     
     // Get the callee given a machine call frame to which this InlineCallFrame belongs.
     JSFunction* calleeForCallFrame(ExecState*) const;
@@ -161,6 +218,12 @@ struct InlineCallFrame {
     
     CodeBlock* baselineCodeBlock() const;
     
+    void setStackOffset(signed offset)
+    {
+        stackOffset = offset;
+        RELEASE_ASSERT(static_cast<signed>(stackOffset) == offset);
+    }
+
     ptrdiff_t callerFrameOffset() const { return stackOffset * sizeof(Register) + CallFrame::callerFrameOffset(); }
     ptrdiff_t returnPCOffset() const { return stackOffset * sizeof(Register) + CallFrame::returnPCOffset(); }
 
@@ -214,6 +277,8 @@ struct CodeOriginApproximateHash {
 
 namespace WTF {
 
+void printInternal(PrintStream&, JSC::InlineCallFrame::Kind);
+
 template<typename T> struct DefaultHash;
 template<> struct DefaultHash<JSC::CodeOrigin> {
     typedef JSC::CodeOriginHash Hash;
diff --git a/bytecode/ComplexGetStatus.cpp b/bytecode/ComplexGetStatus.cpp
new file mode 100644 (file)
index 0000000..d813a3d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ComplexGetStatus.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+ComplexGetStatus ComplexGetStatus::computeFor(
+    CodeBlock* profiledBlock, Structure* headStructure, StructureChain* chain,
+    unsigned chainCount, UniquedStringImpl* uid)
+{
+    // FIXME: We should assert that we never see a structure that
+    // hasImpureGetOwnPropertySlot() but for which we don't
+    // newImpurePropertyFiresWatchpoints(). We're not at a point where we can do
+    // that, yet.
+    // https://bugs.webkit.org/show_bug.cgi?id=131810
+    
+    if (headStructure->takesSlowPathInDFGForImpureProperty())
+        return takesSlowPath();
+    
+    ComplexGetStatus result;
+    result.m_kind = Inlineable;
+    
+    if (chain && chainCount) {
+        result.m_chain = adoptRef(new IntendedStructureChain(
+            profiledBlock, headStructure, chain, chainCount));
+        
+        if (!result.m_chain->isStillValid())
+            return skip();
+        
+        if (headStructure->takesSlowPathInDFGForImpureProperty()
+            || result.m_chain->takesSlowPathInDFGForImpureProperty())
+            return takesSlowPath();
+        
+        JSObject* currentObject = result.m_chain->terminalPrototype();
+        Structure* currentStructure = result.m_chain->last();
+        
+        ASSERT_UNUSED(currentObject, currentObject);
+        
+        result.m_offset = currentStructure->getConcurrently(uid, result.m_attributes);
+    } else {
+        result.m_offset = headStructure->getConcurrently(uid, result.m_attributes);
+    }
+    
+    if (!isValidOffset(result.m_offset))
+        return takesSlowPath();
+    
+    return result;
+}
+
+} // namespace JSC
+
+
diff --git a/bytecode/ComplexGetStatus.h b/bytecode/ComplexGetStatus.h
new file mode 100644 (file)
index 0000000..2620405
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ComplexGetStatus_h
+#define ComplexGetStatus_h
+
+#include "IntendedStructureChain.h"
+#include "JSCJSValue.h"
+#include "PropertyOffset.h"
+
+namespace JSC {
+
+class CodeBlock;
+class StructureChain;
+
+// This class is useful for figuring out how to inline a cached get-like access. We
+// say "get-like" because this is appropriate for loading the GetterSetter object in
+// a put_by_id that hits a setter. Notably, this doesn't figure out how to call
+// accessors, or even whether they should be called. What it gives us, is a way of
+// determining how to load the value from the requested property (identified by a
+// StringImpl* uid) from an object of the given structure in the given CodeBlock,
+// assuming that such an access had already been cached by Repatch (and so Repatch had
+// already done a bunch of safety checks). This doesn't reexecute any checks that
+// Repatch would have executed, and for prototype chain accesses, it doesn't ask the
+// objects in the prototype chain whether their getOwnPropertySlot would attempt to
+// intercept the access - so this really is only appropriate if you already know that
+// one of the JITOperations had OK'd this for caching and that Repatch concurred.
+//
+// The typical use pattern is something like:
+//
+//     ComplexGetStatus status = ComplexGetStatus::computeFor(...);
+//     switch (status.kind()) {
+//     case ComplexGetStatus::ShouldSkip:
+//         // Handle the case where this kind of access is possibly safe but wouldn't
+//         // pass the required safety checks. For example, if an IC gives us a list of
+//         // accesses and one of them is ShouldSkip, then we should pretend as if it
+//         // wasn't even there.
+//         break;
+//     case ComplexGetStatus::TakesSlowPath:
+//         // This kind of access is not safe to inline. Bail out of any attempst to
+//         // inline.
+//         break;
+//     case ComplexGetStatus::Inlineable:
+//         // The good stuff goes here. If it's Inlineable then the other properties of
+//         // the 'status' object will tell you everything you need to know about how
+//         // to execute the get-like operation.
+//         break;
+//     }
+
+class ComplexGetStatus {
+public:
+    enum Kind {
+        ShouldSkip,
+        TakesSlowPath,
+        Inlineable
+    };
+    
+    ComplexGetStatus()
+        : m_kind(ShouldSkip)
+        , m_offset(invalidOffset)
+        , m_attributes(UINT_MAX)
+    {
+    }
+    
+    static ComplexGetStatus skip()
+    {
+        return ComplexGetStatus();
+    }
+    
+    static ComplexGetStatus takesSlowPath()
+    {
+        ComplexGetStatus result;
+        result.m_kind = TakesSlowPath;
+        return result;
+    }
+    
+    static ComplexGetStatus computeFor(
+        CodeBlock* profiledBlock, Structure* headStructure, StructureChain* chain,
+        unsigned chainCount, UniquedStringImpl* uid);
+    
+    Kind kind() const { return m_kind; }
+    unsigned attributes() const { return m_attributes; }
+    JSValue specificValue() const { return m_specificValue; }
+    PropertyOffset offset() const { return m_offset; }
+    IntendedStructureChain* chain() const { return m_chain.get(); }
+    
+private:
+    Kind m_kind;
+    PropertyOffset m_offset;
+    unsigned m_attributes;
+    JSValue m_specificValue;
+    RefPtr<IntendedStructureChain> m_chain;
+};
+
+} // namespace JSC
+
+#endif // ComplexGetStatus_h
+
diff --git a/bytecode/ConstantStructureCheck.cpp b/bytecode/ConstantStructureCheck.cpp
new file mode 100644 (file)
index 0000000..d755c06
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ConstantStructureCheck.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+void ConstantStructureCheck::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    out.print(
+        "(Check if ", inContext(JSValue(m_constant), context), " has structure ",
+        pointerDumpInContext(m_structure, context), ")");
+}
+
+void ConstantStructureCheck::dump(PrintStream& out) const
+{
+    dumpInContext(out, nullptr);
+}
+
+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant)
+{
+    for (unsigned i = vector.size(); i--;) {
+        if (vector[i].constant() == constant)
+            return vector[i].structure();
+    }
+    return nullptr;
+}
+
+bool areCompatible(const ConstantStructureCheckVector& a, const ConstantStructureCheckVector& b)
+{
+    for (unsigned i = a.size(); i--;) {
+        Structure* otherStructure = structureFor(b, a[i].constant());
+        if (!otherStructure)
+            continue;
+        if (a[i].structure() != otherStructure)
+            return false;
+    }
+    return true;
+}
+
+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target)
+{
+    for (unsigned i = source.size(); i--;) {
+        if (structureFor(target, source[i].constant()))
+            continue;
+        target.append(source[i]);
+    }
+}
+
+} // namespace JSC
+
diff --git a/bytecode/ConstantStructureCheck.h b/bytecode/ConstantStructureCheck.h
new file mode 100644 (file)
index 0000000..b200c95
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ConstantStructureCheck_h
+#define ConstantStructureCheck_h
+
+#include "DumpContext.h"
+#include "JSCell.h"
+#include "Structure.h"
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class ConstantStructureCheck {
+public:
+    ConstantStructureCheck()
+        : m_constant(nullptr)
+        , m_structure(nullptr)
+    {
+    }
+    
+    ConstantStructureCheck(JSCell* constant, Structure* structure)
+        : m_constant(constant)
+        , m_structure(structure)
+    {
+        ASSERT(!!m_constant == !!m_structure);
+    }
+    
+    bool operator!() const { return !m_constant; }
+    
+    JSCell* constant() const { return m_constant; }
+    Structure* structure() const { return m_structure; }
+    
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
+    
+private:
+    JSCell* m_constant;
+    Structure* m_structure;
+};
+
+typedef Vector<ConstantStructureCheck, 2> ConstantStructureCheckVector;
+
+Structure* structureFor(const ConstantStructureCheckVector& vector, JSCell* constant);
+bool areCompatible(const ConstantStructureCheckVector&, const ConstantStructureCheckVector&);
+void mergeInto(const ConstantStructureCheckVector& source, ConstantStructureCheckVector& target);
+
+} // namespace JSC
+
+#endif // ConstantStructureCheck_h
+
index 73ba88cd0342a3fba302c30d376023b7cbe4971c..40a25ced61a2f59256fa029677f232c5565f91df 100644 (file)
@@ -28,8 +28,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include <wtf/PassOwnPtr.h>
-
 namespace JSC { namespace DFG {
 
 ExitProfile::ExitProfile() { }
@@ -42,7 +40,7 @@ bool ExitProfile::add(const ConcurrentJITLocker&, const FrequentExitSite& site)
     // If we've never seen any frequent exits then create the list and put this site
     // into it.
     if (!m_frequentExitSites) {
-        m_frequentExitSites = adoptPtr(new Vector<FrequentExitSite>());
+        m_frequentExitSites = std::make_unique<Vector<FrequentExitSite>>();
         m_frequentExitSites->append(site);
         return true;
     }
index 8e0df41e0c5937c38f230eb3225b7f541a18ba24..cdecbaf977bfefbbd51fb16da5142f2d1f6dbd03 100644 (file)
@@ -32,7 +32,6 @@
 #include "ExitKind.h"
 #include "ExitingJITType.h"
 #include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC { namespace DFG {
@@ -183,7 +182,7 @@ public:
 private:
     friend class QueryableExitProfile;
     
-    OwnPtr<Vector<FrequentExitSite>> m_frequentExitSites;
+    std::unique_ptr<Vector<FrequentExitSite>> m_frequentExitSites;
 };
 
 class QueryableExitProfile {
index bb9da4c576a014b6700898e127219d9ea2734a5a..6d7542e2d3d4a7e0e1fa8384b7a431373fb9d4af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,7 +56,6 @@ enum DataFormat {
     
     // Special data formats used only for OSR.
     DataFormatDead = 33, // Implies jsUndefined().
-    DataFormatArguments = 34 // Implies that the arguments object must be reified.
 };
 
 inline const char* dataFormatToString(DataFormat dataFormat)
@@ -90,8 +89,6 @@ inline const char* dataFormatToString(DataFormat dataFormat)
         return "JSBoolean";
     case DataFormatDead:
         return "Dead";
-    case DataFormatArguments:
-        return "Arguments";
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return "Unknown";
index 9d5acb996b5493f50e2c28421ed27ed663acf416..761e95b3f6704fa5db020b146b481a7f89ebbc5a 100644 (file)
@@ -35,6 +35,8 @@ DeferredCompilationCallback::~DeferredCompilationCallback() { }
 
 void DeferredCompilationCallback::compilationDidComplete(CodeBlock* codeBlock, CompilationResult result)
 {
+    dumpCompiledSourcesIfNeeded();
+
     switch (result) {
     case CompilationFailed:
     case CompilationInvalidated:
@@ -47,5 +49,25 @@ void DeferredCompilationCallback::compilationDidComplete(CodeBlock* codeBlock, C
     }
 }
 
+Vector<DeferredSourceDump>& DeferredCompilationCallback::ensureDeferredSourceDump()
+{
+    if (!m_deferredSourceDump)
+        m_deferredSourceDump = std::make_unique<Vector<DeferredSourceDump>>();
+    return *m_deferredSourceDump;
+}
+
+void DeferredCompilationCallback::dumpCompiledSourcesIfNeeded()
+{
+    if (!m_deferredSourceDump)
+        return;
+
+    ASSERT(Options::dumpSourceAtDFGTime());
+    unsigned index = 0;
+    for (auto& info : *m_deferredSourceDump) {
+        dataLog("[", ++index, "] ");
+        info.dump();
+    }
+}
+
 } // JSC
 
index 5d252ca7e74f0a547fb8664ae4e514f2cd5fbf86..37568d22212250bbded518f180dbb416e3bfbe9a 100644 (file)
@@ -27,7 +27,9 @@
 #define DeferredCompilationCallback_h
 
 #include "CompilationResult.h"
+#include "DeferredSourceDump.h"
 #include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
 
 namespace JSC {
 
@@ -42,6 +44,13 @@ public:
 
     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) = 0;
     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
+
+    Vector<DeferredSourceDump>& ensureDeferredSourceDump();
+
+private:
+    void dumpCompiledSourcesIfNeeded();
+
+    std::unique_ptr<Vector<DeferredSourceDump>> m_deferredSourceDump;
 };
 
 } // namespace JSC
diff --git a/bytecode/DeferredSourceDump.cpp b/bytecode/DeferredSourceDump.cpp
new file mode 100644 (file)
index 0000000..48079db
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DeferredSourceDump.h"
+
+#include "CodeBlock.h"
+#include "CodeBlockWithJITType.h"
+
+namespace JSC {
+
+DeferredSourceDump::DeferredSourceDump(CodeBlock* codeBlock)
+    : m_codeBlock(codeBlock)
+    , m_rootCodeBlock(nullptr)
+    , m_rootJITType(JITCode::None)
+{
+}
+
+DeferredSourceDump::DeferredSourceDump(CodeBlock* codeBlock, CodeBlock* rootCodeBlock, JITCode::JITType rootJITType, CodeOrigin callerCodeOrigin)
+    : m_codeBlock(codeBlock)
+    , m_rootCodeBlock(rootCodeBlock)
+    , m_rootJITType(rootJITType)
+    , m_callerCodeOrigin(callerCodeOrigin)
+{
+}
+
+void DeferredSourceDump::dump()
+{
+    bool isInlinedFrame = !!m_rootCodeBlock;
+    if (isInlinedFrame)
+        dataLog("Inlined ");
+    else
+        dataLog("Compiled ");
+    dataLog(*m_codeBlock);
+
+    if (isInlinedFrame)
+        dataLog(" at ", CodeBlockWithJITType(m_rootCodeBlock, m_rootJITType), " ", m_callerCodeOrigin);
+
+    dataLog("\n'''");
+    m_codeBlock->dumpSource();
+    dataLog("'''\n");
+}
+
+} // namespace JSC
diff --git a/bytecode/DeferredSourceDump.h b/bytecode/DeferredSourceDump.h
new file mode 100644 (file)
index 0000000..72cb6b3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DeferredSourceDump_h
+#define DeferredSourceDump_h
+
+#include "CodeOrigin.h"
+#include "JITCode.h"
+
+namespace JSC {
+
+class CodeBlock;
+
+class DeferredSourceDump {
+public:
+    DeferredSourceDump(CodeBlock*);
+    DeferredSourceDump(CodeBlock*, CodeBlock* rootCodeBlock, JITCode::JITType rootJITType, CodeOrigin callerCodeOrigin);
+
+    void dump();
+
+private:
+    CodeBlock* m_codeBlock;
+    CodeBlock* m_rootCodeBlock;
+    JITCode::JITType m_rootJITType;
+    CodeOrigin m_callerCodeOrigin;
+};
+
+} // namespace JSC
+
+#endif // DeferredSourceDump_h
index 65deb94f069bcbb380f79141b7ab5f70bf510827..b0e5aac98d8f2e702e71fee498e3a331cf103f60 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "Executable.h"
 #include "JSGlobalObject.h"
+#include "Options.h"
 #include "SourceCode.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
@@ -44,18 +45,18 @@ namespace JSC {
     public:
         EvalExecutable* tryGet(bool inStrictContext, const String& evalSource, JSScope* scope)
         {
-            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && scope->begin()->isVariableObject())
+            if (!inStrictContext && evalSource.length() < Options::maximumEvalCacheableSourceLength() && scope->begin()->isVariableObject())
                 return m_cacheMap.get(evalSource.impl()).get();
             return 0;
         }
         
-        EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope)
+        EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
         {
-            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
+            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext, thisTDZMode);
             if (!evalExecutable)
                 return 0;
 
-            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && scope->begin()->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
+            if (!inStrictContext && evalSource.length() < Options::maximumEvalCacheableSourceLength() && scope->begin()->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
                 m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->vm(), owner, evalExecutable));
             
             return evalExecutable;
@@ -71,7 +72,6 @@ namespace JSC {
         }
 
     private:
-        static const unsigned maxCacheableSourceLength = 256;
         static const int maxCacheEntries = 64;
 
         typedef HashMap<RefPtr<StringImpl>, WriteBarrier<EvalExecutable>> EvalCacheMap;
index bacb49e3370af5da23875d21cd8fab25496e456b..fe4e430f10c9b6993dbcae3cfaabe52ee24d3561 100644 (file)
@@ -136,8 +136,6 @@ bool ExecutionCounter<countingVariant>::setThreshold(CodeBlock* codeBlock)
         return false;
     }
         
-    ASSERT(!m_activeThreshold || !hasCrossedThreshold(codeBlock));
-        
     // Compute the true total count.
     double trueTotalCount = count();
     
index c6dab9ce732f5ba03168d0e426816aefdc230694..5002c6c6744fb7a1276c16de2d9de54abde6ea80 100644 (file)
@@ -110,7 +110,7 @@ public:
     // m_counter.
     float m_totalCount;
 
-    // This is the threshold we were originally targetting, without any correction for
+    // This is the threshold we were originally targeting, without any correction for
     // the memory usage heuristics.
     int32_t m_activeThreshold;
 };
index 350aa58572ee702a2789edd983661d3ea6c2d741..4f79f2c1c5e4e7fdbe043a049525100ad50ff47b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,18 +38,14 @@ const char* exitKindToString(ExitKind kind)
         return "Unset";
     case BadType:
         return "BadType";
-    case BadFunction:
-        return "BadFunction";
+    case BadCell:
+        return "BadCell";
     case BadExecutable:
         return "BadExecutable";
     case BadCache:
         return "BadCache";
-    case BadCacheWatchpoint:
-        return "BadCacheWatchpoint";
-    case BadWeakConstantCache:
-        return "BadWeakConstantCache";
-    case BadWeakConstantCacheWatchpoint:
-        return "BadWeakConstantCacheWatchpoint";
+    case BadConstantCache:
+        return "BadConstantCache";
     case BadIndexingType:
         return "BadIndexingType";
     case Overflow:
@@ -68,12 +64,16 @@ const char* exitKindToString(ExitKind kind)
         return "InadequateCoverage";
     case ArgumentsEscaped:
         return "ArgumentsEscaped";
+    case ExoticObjectMode:
+        return "ExoticObjectMode";
     case NotStringObject:
         return "NotStringObject";
+    case VarargsOverflow:
+        return "VarargsOverflow";
+    case TDZFailure:
+        return "TDZFailure";
     case Uncountable:
         return "Uncountable";
-    case UncountableWatchpoint:
-        return "UncountableWatchpoint";
     case UncountableInvalidation:
         return "UncountableInvalidation";
     case WatchdogTimerFired:
@@ -92,7 +92,6 @@ bool exitKindIsCountable(ExitKind kind)
         RELEASE_ASSERT_NOT_REACHED();
     case BadType:
     case Uncountable:
-    case UncountableWatchpoint:
     case LoadFromHole: // Already counted directly by the baseline JIT.
     case StoreToHole: // Already counted directly by the baseline JIT.
     case OutOfBounds: // Already counted directly by the baseline JIT.
index 6ac78a25437b04a7d64e501c20c85e5537426b78..59cbbf5a2b387797e3ee2ba81f36e1c61c03b923 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,12 +31,10 @@ namespace JSC {
 enum ExitKind : uint8_t {
     ExitKindUnset,
     BadType, // We exited because a type prediction was wrong.
-    BadFunction, // We exited because we made an incorrect assumption about what function we would see.
+    BadCell, // We exited because we made an incorrect assumption about what cell we would see. Usually used for function checks.
     BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
     BadCache, // We exited because an inline cache was wrong.
-    BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
-    BadCacheWatchpoint, // Same as BadCache but from a watchpoint.
-    BadWeakConstantCacheWatchpoint, // Same as BadWeakConstantCache but from a watchpoint.
+    BadConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
     BadIndexingType, // We exited because an indexing type was wrong.
     Overflow, // We exited because of overflow.
     NegativeZero, // We exited because we encountered negative zero.
@@ -46,10 +44,12 @@ enum ExitKind : uint8_t {
     OutOfBounds, // We had an out-of-bounds access to an array.
     InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
     ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
+    ExoticObjectMode, // We exited because some exotic object that we were accessing was in an exotic mode (like Arguments with slow arguments).
     NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
+    VarargsOverflow, // We exited because a varargs call passed more arguments than we expected.
+    TDZFailure, // We exited because we were in the TDZ and accessed the variable.
     Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
     UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
-    UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
     WatchdogTimerFired, // We exited because we need to service the watchdog timer.
     DebuggerEvent // We exited because we need to service the debugger.
 };
@@ -57,18 +57,6 @@ enum ExitKind : uint8_t {
 const char* exitKindToString(ExitKind);
 bool exitKindIsCountable(ExitKind);
 
-inline bool isWatchpoint(ExitKind kind)
-{
-    switch (kind) {
-    case BadCacheWatchpoint:
-    case BadWeakConstantCacheWatchpoint:
-    case UncountableWatchpoint:
-        return true;
-    default:
-        return false;
-    }
-}
-
 } // namespace JSC
 
 namespace WTF {
index d343921219af8354275077f1412a152b82b5f325..864af75747b0ccfb3cf39565dba09a3d51941f19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,32 +36,20 @@ typedef HashMap<unsigned, FastBitVector, WTF::IntHash<unsigned>, WTF::UnsignedWi
 
 class FullBytecodeLiveness {
 public:
-    FullBytecodeLiveness() : m_codeBlock(0) { }
-    
-    // We say "out" to refer to the bitvector that contains raw results for a bytecode
-    // instruction.
-    const FastBitVector& getOut(unsigned bytecodeIndex) const
+    const FastBitVector& getLiveness(unsigned bytecodeIndex) const
     {
-        BytecodeToBitmapMap::const_iterator iter = m_map.find(bytecodeIndex);
-        ASSERT(iter != m_map.end());
-        return iter->value;
+        return m_map[bytecodeIndex];
     }
     
     bool operandIsLive(int operand, unsigned bytecodeIndex) const
     {
-        return operandIsAlwaysLive(m_codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(m_codeBlock, getOut(bytecodeIndex), operand);
-    }
-    
-    FastBitVector getLiveness(unsigned bytecodeIndex) const
-    {
-        return getLivenessInfo(m_codeBlock, getOut(bytecodeIndex));
+        return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(getLiveness(bytecodeIndex), operand);
     }
     
 private:
     friend class BytecodeLivenessAnalysis;
     
-    CodeBlock* m_codeBlock;
-    BytecodeToBitmapMap m_map;
+    Vector<FastBitVector, 0, UnsafeVectorOverflow> m_map;
 };
 
 } // namespace JSC
index 235cdbd7247667e31a017572d802ef012217b7bf..7afaf923b773204e4299d0790f055ba8e30a654a 100644 (file)
@@ -26,7 +26,9 @@
 #include "config.h"
 #include "GetByIdStatus.h"
 
+#include "AccessorCallJITStubRoutine.h"
 #include "CodeBlock.h"
+#include "ComplexGetStatus.h"
 #include "JSCInlines.h"
 #include "JSScope.h"
 #include "LLIntData.h"
@@ -38,25 +40,33 @@ namespace JSC {
 
 bool GetByIdStatus::appendVariant(const GetByIdVariant& variant)
 {
+    // Attempt to merge this variant with an already existing variant.
+    for (unsigned i = 0; i < m_variants.size(); ++i) {
+        if (m_variants[i].attemptToMerge(variant))
+            return true;
+    }
+    
+    // Make sure there is no overlap. We should have pruned out opportunities for
+    // overlap but it's possible that an inline cache got into a weird state. We are
+    // defensive and bail if we detect crazy.
     for (unsigned i = 0; i < m_variants.size(); ++i) {
         if (m_variants[i].structureSet().overlaps(variant.structureSet()))
             return false;
     }
+    
     m_variants.append(variant);
     return true;
 }
 
 #if ENABLE(DFG_JIT)
-bool GetByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType jitType)
+bool GetByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
 {
-    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, jitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, jitType));
+    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
+        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache));
 }
 #endif
 
-GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, StringImpl* uid)
+GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, UniquedStringImpl* uid)
 {
     UNUSED_PARAM(profiledBlock);
     UNUSED_PARAM(bytecodeIndex);
@@ -74,69 +84,14 @@ GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
         return GetByIdStatus(NoInformation, false);
 
     unsigned attributesIgnored;
-    JSCell* specificValue;
-    PropertyOffset offset = structure->getConcurrently(
-        *profiledBlock->vm(), uid, attributesIgnored, specificValue);
-    if (structure->isDictionary())
-        specificValue = 0;
+    PropertyOffset offset = structure->getConcurrently(uid, attributesIgnored);
     if (!isValidOffset(offset))
         return GetByIdStatus(NoInformation, false);
     
-    return GetByIdStatus(Simple, false, GetByIdVariant(StructureSet(structure), offset, specificValue));
-}
-
-bool GetByIdStatus::computeForChain(CodeBlock* profiledBlock, StringImpl* uid, PassRefPtr<IntendedStructureChain> passedChain)
-{
-#if ENABLE(JIT)
-    RefPtr<IntendedStructureChain> chain = passedChain;
-    
-    // Validate the chain. If the chain is invalid, then currently the best thing
-    // we can do is to assume that TakesSlow is true. In the future, it might be
-    // worth exploring reifying the structure chain from the structure we've got
-    // instead of using the one from the cache, since that will do the right things
-    // if the structure chain has changed. But that may be harder, because we may
-    // then end up having a different type of access altogether. And it currently
-    // does not appear to be worth it to do so -- effectively, the heuristic we
-    // have now is that if the structure chain has changed between when it was
-    // cached on in the baseline JIT and when the DFG tried to inline the access,
-    // then we fall back on a polymorphic access.
-    if (!chain->isStillValid())
-        return false;
-
-    if (chain->head()->takesSlowPathInDFGForImpureProperty())
-        return false;
-    size_t chainSize = chain->size();
-    for (size_t i = 0; i < chainSize; i++) {
-        if (chain->at(i)->takesSlowPathInDFGForImpureProperty())
-            return false;
-    }
-
-    JSObject* currentObject = chain->terminalPrototype();
-    Structure* currentStructure = chain->last();
-    
-    ASSERT_UNUSED(currentObject, currentObject);
-    
-    unsigned attributesIgnored;
-    JSCell* specificValue;
-    
-    PropertyOffset offset = currentStructure->getConcurrently(
-        *profiledBlock->vm(), uid, attributesIgnored, specificValue);
-    if (currentStructure->isDictionary())
-        specificValue = 0;
-    if (!isValidOffset(offset))
-        return false;
-    
-    return appendVariant(GetByIdVariant(StructureSet(chain->head()), offset, specificValue, chain));
-#else // ENABLE(JIT)
-    UNUSED_PARAM(profiledBlock);
-    UNUSED_PARAM(uid);
-    UNUSED_PARAM(passedChain);
-    UNREACHABLE_FOR_PLATFORM();
-    return false;
-#endif // ENABLE(JIT)
+    return GetByIdStatus(Simple, false, GetByIdVariant(StructureSet(structure), offset));
 }
 
-GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, StringImpl* uid)
+GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, UniquedStringImpl* uid)
 {
     ConcurrentJITLocker locker(profiledBlock->m_lock);
 
@@ -144,12 +99,12 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& m
 
 #if ENABLE(DFG_JIT)
     result = computeForStubInfo(
-        locker, profiledBlock, map.get(CodeOrigin(bytecodeIndex)), uid);
+        locker, profiledBlock, map.get(CodeOrigin(bytecodeIndex)), uid,
+        CallLinkStatus::computeExitSiteData(locker, profiledBlock, bytecodeIndex));
     
     if (!result.takesSlowPath()
-        && (hasExitSite(locker, profiledBlock, bytecodeIndex)
-            || profiledBlock->likelyToTakeSlowCase(bytecodeIndex)))
-        return GetByIdStatus(TakesSlowPath, true);
+        && hasExitSite(locker, profiledBlock, bytecodeIndex))
+        return GetByIdStatus(result.makesCalls() ? MakesCalls : TakesSlowPath, true);
 #else
     UNUSED_PARAM(map);
 #endif
@@ -162,37 +117,29 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& m
 
 #if ENABLE(JIT)
 GetByIdStatus GetByIdStatus::computeForStubInfo(
-    const ConcurrentJITLocker&, CodeBlock* profiledBlock, StructureStubInfo* stubInfo,
-    StringImpl* uid)
+    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, UniquedStringImpl* uid,
+    CallLinkStatus::ExitSiteData callExitSiteData)
 {
-    if (!stubInfo || !stubInfo->seen)
+    if (!stubInfo)
+        return GetByIdStatus(NoInformation);
+    
+    if (!stubInfo->seen)
         return GetByIdStatus(NoInformation);
     
-    if (stubInfo->resetByGC)
-        return GetByIdStatus(TakesSlowPath, true);
-
     PolymorphicGetByIdList* list = 0;
+    State slowPathState = TakesSlowPath;
     if (stubInfo->accessType == access_get_by_id_list) {
         list = stubInfo->u.getByIdList.list;
-        bool makesCalls = false;
-        bool isWatched = false;
         for (unsigned i = 0; i < list->size(); ++i) {
             const GetByIdAccess& access = list->at(i);
-            if (access.doesCalls()) {
-                makesCalls = true;
-                break;
-            }
-            if (access.isWatched()) {
-                isWatched = true;
-                continue;
-            }
+            if (access.doesCalls())
+                slowPathState = MakesCalls;
         }
-        if (makesCalls)
-            return GetByIdStatus(MakesCalls, true);
-        if (isWatched)
-            return GetByIdStatus(TakesSlowPath, true);
     }
     
+    if (stubInfo->tookSlowPath)
+        return GetByIdStatus(slowPathState);
+    
     // Finally figure out if we can derive an access strategy.
     GetByIdStatus result;
     result.m_state = Simple;
@@ -204,103 +151,75 @@ GetByIdStatus GetByIdStatus::computeForStubInfo(
     case access_get_by_id_self: {
         Structure* structure = stubInfo->u.getByIdSelf.baseObjectStructure.get();
         if (structure->takesSlowPathInDFGForImpureProperty())
-            return GetByIdStatus(TakesSlowPath, true);
+            return GetByIdStatus(slowPathState, true);
         unsigned attributesIgnored;
-        JSCell* specificValue;
         GetByIdVariant variant;
-        variant.m_offset = structure->getConcurrently(
-            *profiledBlock->vm(), uid, attributesIgnored, specificValue);
+        variant.m_offset = structure->getConcurrently(uid, attributesIgnored);
         if (!isValidOffset(variant.m_offset))
-            return GetByIdStatus(TakesSlowPath, true);
-        
-        if (structure->isDictionary())
-            specificValue = 0;
+            return GetByIdStatus(slowPathState, true);
         
         variant.m_structureSet.add(structure);
-        variant.m_specificValue = JSValue(specificValue);
-        result.appendVariant(variant);
+        bool didAppend = result.appendVariant(variant);
+        ASSERT_UNUSED(didAppend, didAppend);
         return result;
     }
         
     case access_get_by_id_list: {
         for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
-            ASSERT(list->at(listIndex).isSimple());
-            
             Structure* structure = list->at(listIndex).structure();
             
-            // FIXME: We should assert that we never see a structure that
-            // hasImpureGetOwnPropertySlot() but for which we don't
-            // newImpurePropertyFiresWatchpoints(). We're not at a point where we can do
-            // that, yet.
-            // https://bugs.webkit.org/show_bug.cgi?id=131810
-            
-            if (structure->takesSlowPathInDFGForImpureProperty())
-                return GetByIdStatus(TakesSlowPath, true);
-            
-            if (list->at(listIndex).chain()) {
-                RefPtr<IntendedStructureChain> chain = adoptRef(new IntendedStructureChain(
-                    profiledBlock, structure, list->at(listIndex).chain(),
-                    list->at(listIndex).chainCount()));
-                if (!result.computeForChain(profiledBlock, uid, chain))
-                    return GetByIdStatus(TakesSlowPath, true);
+            ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
+                profiledBlock, structure, list->at(listIndex).chain(),
+                list->at(listIndex).chainCount(), uid);
+             
+            switch (complexGetStatus.kind()) {
+            case ComplexGetStatus::ShouldSkip:
                 continue;
-            }
-            
-            unsigned attributesIgnored;
-            JSCell* specificValue;
-            PropertyOffset myOffset = structure->getConcurrently(
-                *profiledBlock->vm(), uid, attributesIgnored, specificValue);
-            if (structure->isDictionary())
-                specificValue = 0;
-            
-            if (!isValidOffset(myOffset))
-                return GetByIdStatus(TakesSlowPath, true);
-
-            bool found = false;
-            for (unsigned variantIndex = 0; variantIndex < result.m_variants.size(); ++variantIndex) {
-                GetByIdVariant& variant = result.m_variants[variantIndex];
-                if (variant.m_chain)
-                    continue;
-                
-                if (variant.m_offset != myOffset)
-                    continue;
-
-                found = true;
-                if (variant.m_structureSet.contains(structure))
+                 
+            case ComplexGetStatus::TakesSlowPath:
+                return GetByIdStatus(slowPathState, true);
+                 
+            case ComplexGetStatus::Inlineable: {
+                std::unique_ptr<CallLinkStatus> callLinkStatus;
+                switch (list->at(listIndex).type()) {
+                case GetByIdAccess::SimpleInline:
+                case GetByIdAccess::SimpleStub: {
+                    break;
+                }
+                case GetByIdAccess::Getter: {
+                    AccessorCallJITStubRoutine* stub = static_cast<AccessorCallJITStubRoutine*>(
+                        list->at(listIndex).stubRoutine());
+                    callLinkStatus = std::make_unique<CallLinkStatus>(
+                        CallLinkStatus::computeFor(
+                            locker, profiledBlock, *stub->m_callLinkInfo, callExitSiteData));
                     break;
-                
-                if (variant.m_specificValue != JSValue(specificValue))
-                    variant.m_specificValue = JSValue();
-                
-                variant.m_structureSet.add(structure);
+                }
+                case GetByIdAccess::SimpleMiss:
+                case GetByIdAccess::CustomGetter:
+                case GetByIdAccess::WatchedStub:{
+                    // FIXME: It would be totally sweet to support this at some point in the future.
+                    // https://bugs.webkit.org/show_bug.cgi?id=133052
+                    return GetByIdStatus(slowPathState, true);
+                }
+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                }
+                 
+                GetByIdVariant variant(
+                    StructureSet(structure), complexGetStatus.offset(), complexGetStatus.chain(),
+                    WTF::move(callLinkStatus));
+                 
+                if (!result.appendVariant(variant))
+                    return GetByIdStatus(slowPathState, true);
                 break;
-            }
-            
-            if (found)
-                continue;
-            
-            if (!result.appendVariant(GetByIdVariant(StructureSet(structure), myOffset, specificValue)))
-                return GetByIdStatus(TakesSlowPath, true);
+            } }
         }
         
         return result;
     }
         
-    case access_get_by_id_chain: {
-        if (!stubInfo->u.getByIdChain.isDirect)
-            return GetByIdStatus(MakesCalls, true);
-        RefPtr<IntendedStructureChain> chain = adoptRef(new IntendedStructureChain(
-            profiledBlock,
-            stubInfo->u.getByIdChain.baseObjectStructure.get(),
-            stubInfo->u.getByIdChain.chain.get(),
-            stubInfo->u.getByIdChain.count));
-        if (result.computeForChain(profiledBlock, uid, chain))
-            return result;
-        return GetByIdStatus(TakesSlowPath, true);
-    }
-        
     default:
-        return GetByIdStatus(TakesSlowPath, true);
+        return GetByIdStatus(slowPathState, true);
     }
     
     RELEASE_ASSERT_NOT_REACHED();
@@ -310,14 +229,22 @@ GetByIdStatus GetByIdStatus::computeForStubInfo(
 
 GetByIdStatus GetByIdStatus::computeFor(
     CodeBlock* profiledBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap,
-    StubInfoMap& dfgMap, CodeOrigin codeOrigin, StringImpl* uid)
+    StubInfoMap& dfgMap, CodeOrigin codeOrigin, UniquedStringImpl* uid)
 {
 #if ENABLE(DFG_JIT)
     if (dfgBlock) {
+        CallLinkStatus::ExitSiteData exitSiteData;
+        {
+            ConcurrentJITLocker locker(profiledBlock->m_lock);
+            exitSiteData = CallLinkStatus::computeExitSiteData(
+                locker, profiledBlock, codeOrigin.bytecodeIndex);
+        }
+        
         GetByIdStatus result;
         {
             ConcurrentJITLocker locker(dfgBlock->m_lock);
-            result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
+            result = computeForStubInfo(
+                locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData);
         }
         
         if (result.takesSlowPath())
@@ -325,7 +252,7 @@ GetByIdStatus GetByIdStatus::computeFor(
     
         {
             ConcurrentJITLocker locker(profiledBlock->m_lock);
-            if (hasExitSite(locker, profiledBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
+            if (hasExitSite(locker, profiledBlock, codeOrigin.bytecodeIndex))
                 return GetByIdStatus(TakesSlowPath, true);
         }
         
@@ -340,34 +267,60 @@ GetByIdStatus GetByIdStatus::computeFor(
     return computeFor(profiledBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
 }
 
-GetByIdStatus GetByIdStatus::computeFor(VM& vm, Structure* structure, StringImpl* uid)
+GetByIdStatus GetByIdStatus::computeFor(const StructureSet& set, UniquedStringImpl* uid)
 {
     // For now we only handle the super simple self access case. We could handle the
     // prototype case in the future.
     
-    if (!structure)
-        return GetByIdStatus(TakesSlowPath);
+    if (set.isEmpty())
+        return GetByIdStatus();
 
-    if (toUInt32FromStringImpl(uid) != PropertyName::NotAnIndex)
+    if (parseIndex(*uid))
         return GetByIdStatus(TakesSlowPath);
     
-    if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType)
-        return GetByIdStatus(TakesSlowPath);
+    GetByIdStatus result;
+    result.m_state = Simple;
+    result.m_wasSeenInJIT = false;
+    for (unsigned i = 0; i < set.size(); ++i) {
+        Structure* structure = set[i];
+        if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType)
+            return GetByIdStatus(TakesSlowPath);
+        
+        if (!structure->propertyAccessesAreCacheable())
+            return GetByIdStatus(TakesSlowPath);
+        
+        unsigned attributes;
+        PropertyOffset offset = structure->getConcurrently(uid, attributes);
+        if (!isValidOffset(offset))
+            return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it.
+        if (attributes & Accessor)
+            return GetByIdStatus(MakesCalls); // We could be smarter here, like strenght-reducing this to a Call.
+        
+        if (!result.appendVariant(GetByIdVariant(structure, offset)))
+            return GetByIdStatus(TakesSlowPath);
+    }
     
-    if (!structure->propertyAccessesAreCacheable())
-        return GetByIdStatus(TakesSlowPath);
+    return result;
+}
 
-    unsigned attributes;
-    JSCell* specificValue;
-    PropertyOffset offset = structure->getConcurrently(vm, uid, attributes, specificValue);
-    if (!isValidOffset(offset))
-        return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it.
-    if (attributes & Accessor)
-        return GetByIdStatus(MakesCalls);
-    if (structure->isDictionary())
-        specificValue = 0;
-    return GetByIdStatus(
-        Simple, false, GetByIdVariant(StructureSet(structure), offset, specificValue));
+bool GetByIdStatus::makesCalls() const
+{
+    switch (m_state) {
+    case NoInformation:
+    case TakesSlowPath:
+        return false;
+    case Simple:
+        for (unsigned i = m_variants.size(); i--;) {
+            if (m_variants[i].callLinkStatus())
+                return true;
+        }
+        return false;
+    case MakesCalls:
+        return true;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+
+    return false;
 }
 
 void GetByIdStatus::dump(PrintStream& out) const
index c350e2c7ab2d11eeddee3eaee1aade210cac50ee..32372cddf5e25b0f388e6cfedc46620b2d38d2d0 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef GetByIdStatus_h
 #define GetByIdStatus_h
 
+#include "CallLinkStatus.h"
 #include "CodeOrigin.h"
 #include "ConcurrentJITLock.h"
 #include "ExitingJITType.h"
@@ -66,10 +67,10 @@ public:
         m_variants.append(variant);
     }
     
-    static GetByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, StringImpl* uid);
-    static GetByIdStatus computeFor(VM&, Structure*, StringImpl* uid);
+    static GetByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, UniquedStringImpl* uid);
+    static GetByIdStatus computeFor(const StructureSet&, UniquedStringImpl* uid);
     
-    static GetByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, StringImpl* uid);
+    static GetByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, UniquedStringImpl* uid);
     
     State state() const { return m_state; }
     
@@ -83,7 +84,7 @@ public:
     const GetByIdVariant& operator[](size_t index) const { return at(index); }
 
     bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
-    bool makesCalls() const { return m_state == MakesCalls; }
+    bool makesCalls() const;
     
     bool wasSeenInJIT() const { return m_wasSeenInJIT; }
     
@@ -91,13 +92,14 @@ public:
     
 private:
 #if ENABLE(DFG_JIT)
-    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
+    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
 #endif
 #if ENABLE(JIT)
-    static GetByIdStatus computeForStubInfo(const ConcurrentJITLocker&, CodeBlock*, StructureStubInfo*, StringImpl* uid);
+    static GetByIdStatus computeForStubInfo(
+        const ConcurrentJITLocker&, CodeBlock* profiledBlock, StructureStubInfo*,
+        UniquedStringImpl* uid, CallLinkStatus::ExitSiteData);
 #endif
-    bool computeForChain(CodeBlock*, StringImpl* uid, PassRefPtr<IntendedStructureChain>);
-    static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, StringImpl* uid);
+    static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, UniquedStringImpl* uid);
     
     bool appendVariant(const GetByIdVariant&);
     
index b8bedce4f0d23c2602e0afb803c9fc21b204e0f9..dd8e8dfb5e8e0cc5b35a46f01db963864b7d9871 100644 (file)
 #include "config.h"
 #include "GetByIdVariant.h"
 
+#include "CallLinkStatus.h"
 #include "JSCInlines.h"
+#include <wtf/ListDump.h>
 
 namespace JSC {
 
+GetByIdVariant::GetByIdVariant(
+    const StructureSet& structureSet, PropertyOffset offset,
+    const IntendedStructureChain* chain, std::unique_ptr<CallLinkStatus> callLinkStatus)
+    : m_structureSet(structureSet)
+    , m_alternateBase(nullptr)
+    , m_offset(offset)
+    , m_callLinkStatus(WTF::move(callLinkStatus))
+{
+    if (!structureSet.size()) {
+        ASSERT(offset == invalidOffset);
+        ASSERT(!chain);
+    }
+    
+    if (chain && chain->size()) {
+        m_alternateBase = chain->terminalPrototype();
+        chain->gatherChecks(m_constantChecks);
+    }
+}
+
+GetByIdVariant::~GetByIdVariant() { }
+
+GetByIdVariant::GetByIdVariant(const GetByIdVariant& other)
+    : GetByIdVariant()
+{
+    *this = other;
+}
+
+GetByIdVariant& GetByIdVariant::operator=(const GetByIdVariant& other)
+{
+    m_structureSet = other.m_structureSet;
+    m_constantChecks = other.m_constantChecks;
+    m_alternateBase = other.m_alternateBase;
+    m_offset = other.m_offset;
+    if (other.m_callLinkStatus)
+        m_callLinkStatus = std::make_unique<CallLinkStatus>(*other.m_callLinkStatus);
+    else
+        m_callLinkStatus = nullptr;
+    return *this;
+}
+
+StructureSet GetByIdVariant::baseStructure() const
+{
+    if (!m_alternateBase)
+        return structureSet();
+    
+    Structure* structure = structureFor(m_constantChecks, m_alternateBase);
+    RELEASE_ASSERT(structure);
+    return structure;
+}
+
+bool GetByIdVariant::attemptToMerge(const GetByIdVariant& other)
+{
+    if (m_alternateBase != other.m_alternateBase)
+        return false;
+    if (m_offset != other.m_offset)
+        return false;
+    if (m_callLinkStatus || other.m_callLinkStatus)
+        return false;
+    if (!areCompatible(m_constantChecks, other.m_constantChecks))
+        return false;
+    
+    mergeInto(other.m_constantChecks, m_constantChecks);
+    m_structureSet.merge(other.m_structureSet);
+    
+    return true;
+}
+
 void GetByIdVariant::dump(PrintStream& out) const
 {
     dumpInContext(out, 0);
@@ -44,8 +113,13 @@ void GetByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const
     
     out.print(
         "<", inContext(structureSet(), context), ", ",
-        pointerDumpInContext(chain(), context), ", ",
-        inContext(specificValue(), context), ", ", offset(), ">");
+        "[", listDumpInContext(m_constantChecks, context), "]");
+    if (m_alternateBase)
+        out.print(", alternateBase = ", inContext(JSValue(m_alternateBase), context));
+    out.print(", offset = ", offset());
+    if (m_callLinkStatus)
+        out.print(", call = ", *m_callLinkStatus);
+    out.print(">");
 }
 
 } // namespace JSC
index f0201eefbf54beee5c7ad85471c494bd57a673c8..8d1ade1f967261d8ec05f014c5f8d1889f371ecf 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef GetByIdVariant_h
 #define GetByIdVariant_h
 
+#include "CallLinkStatus.h"
+#include "ConstantStructureCheck.h"
 #include "IntendedStructureChain.h"
 #include "JSCJSValue.h"
 #include "PropertyOffset.h"
 
 namespace JSC {
 
+class CallLinkStatus;
 class GetByIdStatus;
 struct DumpContext;
 
 class GetByIdVariant {
 public:
     GetByIdVariant(
-        const StructureSet& structureSet = StructureSet(),
-        PropertyOffset offset = invalidOffset, JSValue specificValue = JSValue(),
-        PassRefPtr<IntendedStructureChain> chain = nullptr)
-        : m_structureSet(structureSet)
-        , m_chain(chain)
-        , m_specificValue(specificValue)
-        , m_offset(offset)
-    {
-        if (!structureSet.size()) {
-            ASSERT(offset == invalidOffset);
-            ASSERT(!specificValue);
-            ASSERT(!chain);
-        }
-    }
+        const StructureSet& structureSet = StructureSet(), PropertyOffset offset = invalidOffset,
+        const IntendedStructureChain* chain = nullptr,
+        std::unique_ptr<CallLinkStatus> callLinkStatus = nullptr);
+    
+    ~GetByIdVariant();
+    
+    GetByIdVariant(const GetByIdVariant&);
+    GetByIdVariant& operator=(const GetByIdVariant&);
     
     bool isSet() const { return !!m_structureSet.size(); }
     bool operator!() const { return !isSet(); }
     const StructureSet& structureSet() const { return m_structureSet; }
-    IntendedStructureChain* chain() const { return const_cast<IntendedStructureChain*>(m_chain.get()); }
-    JSValue specificValue() const { return m_specificValue; }
+    StructureSet& structureSet() { return m_structureSet; }
+    const ConstantStructureCheckVector& constantChecks() const { return m_constantChecks; }
+    JSObject* alternateBase() const { return m_alternateBase; }
+    StructureSet baseStructure() const;
     PropertyOffset offset() const { return m_offset; }
+    CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); }
+    
+    bool attemptToMerge(const GetByIdVariant& other);
     
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
@@ -68,9 +70,10 @@ private:
     friend class GetByIdStatus;
     
     StructureSet m_structureSet;
-    RefPtr<IntendedStructureChain> m_chain;
-    JSValue m_specificValue;
+    ConstantStructureCheckVector m_constantChecks;
+    JSObject* m_alternateBase;
     PropertyOffset m_offset;
+    std::unique_ptr<CallLinkStatus> m_callLinkStatus;
 };
 
 } // namespace JSC
index ec075e74a5f49d2c46b97b2f0045e76e48f54829..cae7ed9b4b09fcfe76cab6802daba60738ecdff7 100644 (file)
 
 namespace JSC {
 
-struct HandlerInfo {
+enum class HandlerType {
+    Illegal = 0,
+    Catch = 1,
+    Finally = 2,
+    SynthesizedFinally = 3
+};
+
+struct HandlerInfoBase {
+    HandlerType type() const { return static_cast<HandlerType>(typeBits); }
+    void setType(HandlerType type) { typeBits = static_cast<uint32_t>(type); }
+
+    const char* typeName()
+    {
+        switch (type()) {
+        case HandlerType::Catch:
+            return "catch";
+        case HandlerType::Finally:
+            return "finally";
+        case HandlerType::SynthesizedFinally:
+            return "synthesized finally";
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        return nullptr;
+    }
+
+    bool isCatchHandler() const { return type() == HandlerType::Catch; }
+
     uint32_t start;
     uint32_t end;
     uint32_t target;
-    uint32_t scopeDepth;
+    uint32_t scopeDepth : 30;
+    uint32_t typeBits : 2; // HandlerType
+};
+
+struct UnlinkedHandlerInfo : public HandlerInfoBase {
+    UnlinkedHandlerInfo(uint32_t start, uint32_t end, uint32_t target, uint32_t scopeDepth, HandlerType handlerType)
+    {
+        this->start = start;
+        this->end = end;
+        this->target = target;
+        this->scopeDepth = scopeDepth;
+        setType(handlerType);
+        ASSERT(type() == handlerType);
+    }
+};
+
+struct HandlerInfo : public HandlerInfoBase {
+    void initialize(const UnlinkedHandlerInfo& unlinkedInfo, size_t nonLocalScopeDepth)
+    {
+        start = unlinkedInfo.start;
+        end = unlinkedInfo.end;
+        target = unlinkedInfo.target;
+        scopeDepth = unlinkedInfo.scopeDepth + nonLocalScopeDepth;
+        typeBits = unlinkedInfo.typeBits;
+    }
+
 #if ENABLE(JIT)
+    void initialize(const UnlinkedHandlerInfo& unlinkedInfo, size_t nonLocalScopeDepth, CodeLocationLabel label)
+    {
+        initialize(unlinkedInfo, nonLocalScopeDepth);
+        nativeCode = label;
+    }
+
     CodeLocationLabel nativeCode;
 #endif
 };
index ca457758c459442bcbd1494aacd9d51553ae27e8..c20a4f7284ec1c58188486022b09bd640c231166 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef Instruction_h
 #define Instruction_h
 
+#include "BasicBlockLocation.h"
 #include "MacroAssembler.h"
 #include "Opcode.h"
+#include "SymbolTable.h"
+#include "TypeLocation.h"
 #include "PropertySlot.h"
 #include "SpecialPointer.h"
 #include "Structure.h"
 #include "StructureChain.h"
+#include "ToThisStatus.h"
 #include "VirtualRegister.h"
 #include <wtf/VectorTraits.h>
 
@@ -43,7 +47,7 @@ namespace JSC {
 class ArrayAllocationProfile;
 class ArrayProfile;
 class ObjectAllocationProfile;
-class VariableWatchpointSet;
+class WatchpointSet;
 struct LLIntCallLinkInfo;
 struct ValueProfile;
 
@@ -94,30 +98,33 @@ struct Instruction {
     Instruction(ArrayProfile* profile) { u.arrayProfile = profile; }
     Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; }
     Instruction(ObjectAllocationProfile* profile) { u.objectAllocationProfile = profile; }
-    Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; }
+    Instruction(WriteBarrier<Unknown>* variablePointer) { u.variablePointer = variablePointer; }
     Instruction(Special::Pointer pointer) { u.specialPointer = pointer; }
-    Instruction(StringImpl* uid) { u.uid = uid; }
+    Instruction(UniquedStringImpl* uid) { u.uid = uid; }
     Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; }
 
     union {
         Opcode opcode;
         int operand;
         WriteBarrierBase<Structure> structure;
+        WriteBarrierBase<SymbolTable> symbolTable;
         WriteBarrierBase<StructureChain> structureChain;
         WriteBarrierBase<JSCell> jsCell;
-        WriteBarrier<Unknown>* registerPointer;
+        WriteBarrier<Unknown>* variablePointer;
         Special::Pointer specialPointer;
         PropertySlot::GetValueFunc getterFunc;
         LLIntCallLinkInfo* callLinkInfo;
-        StringImpl* uid;
+        UniquedStringImpl* uid;
         ValueProfile* profile;
         ArrayProfile* arrayProfile;
         ArrayAllocationProfile* arrayAllocationProfile;
         ObjectAllocationProfile* objectAllocationProfile;
-        VariableWatchpointSet* watchpointSet;
-        WriteBarrierBase<JSActivation> activation;
+        WatchpointSet* watchpointSet;
         void* pointer;
         bool* predicatePointer;
+        ToThisStatus toThisStatus;
+        TypeLocation* location;
+        BasicBlockLocation* basicBlockLocation;
     } u;
         
 private:
index bfb9510187e8bde6e4e7f195007e33c0522e403f..2645dd5bea5e3d5812dcb5fd9c0fe0972f769b18 100644 (file)
@@ -45,7 +45,7 @@ struct LLIntCallLinkInfo : public BasicRawSentinelNode<LLIntCallLinkInfo> {
             remove();
     }
     
-    bool isLinked() { return callee; }
+    bool isLinked() { return !!callee; }
     
     void unlink()
     {
index e58420eeb889870e2085b59146490284f84a3aa7..de654db6881c2adcdf8aab05958d0371c812935a 100644 (file)
@@ -46,7 +46,7 @@ LazyOperandValueProfile* CompressedLazyOperandValueProfileHolder::add(
     const ConcurrentJITLocker&, const LazyOperandValueProfileKey& key)
 {
     if (!m_data)
-        m_data = adoptPtr(new LazyOperandValueProfile::List());
+        m_data = std::make_unique<LazyOperandValueProfile::List>();
     else {
         for (unsigned i = 0; i < m_data->size(); ++i) {
             if (m_data->at(i).key() == key)
index 95ef941cdcdc13c65e855cb6f09425c2bac82e28..74e4f331892e3f4f9be4303b485046d53bfac5e8 100644 (file)
@@ -31,7 +31,6 @@
 #include "VirtualRegister.h"
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/SegmentedVector.h>
 
 namespace JSC {
@@ -161,7 +160,7 @@ public:
     
 private:
     friend class LazyOperandValueProfileParser;
-    OwnPtr<LazyOperandValueProfile::List> m_data;
+    std::unique_ptr<LazyOperandValueProfile::List> m_data;
 };
 
 class LazyOperandValueProfileParser {
index 9a9db0bc70b9f135f65dd2d796de652896ae0fb1..cb4148ee4f5328631fec4c148fdf4c3354fc73dc 100644 (file)
@@ -89,13 +89,23 @@ public:
         if (inlineCapacity > JSFinalObject::maxInlineCapacity())
             inlineCapacity = JSFinalObject::maxInlineCapacity();
 
+        Structure* structure = vm.prototypeMap.emptyObjectStructureForPrototype(prototype, inlineCapacity);
+
+        // Ensure that if another thread sees the structure, it will see it properly created
+        WTF::storeStoreFence();
+
         m_allocator = allocator;
-        m_structure.set(vm, owner,
-            vm.prototypeMap.emptyObjectStructureForPrototype(prototype, inlineCapacity));
+        m_structure.set(vm, owner, structure);
     }
 
-    Structure* structure() { return m_structure.get(); }
-    unsigned inlineCapacity() { return m_structure->inlineCapacity(); }
+    Structure* structure()
+    {
+        Structure* structure = m_structure.get();
+        // Ensure that if we see the structure, it has been properly created
+        WTF::loadLoadFence();
+        return structure;
+    }
+    unsigned inlineCapacity() { return structure()->inlineCapacity(); }
 
     void clear()
     {
@@ -118,7 +128,7 @@ private:
 
         size_t count = 0;
         PropertyNameArray propertyNameArray(&vm);
-        prototype->structure()->getPropertyNamesFromStructure(vm, propertyNameArray, ExcludeDontEnumProperties);
+        prototype->structure()->getPropertyNamesFromStructure(vm, propertyNameArray, EnumerationMode());
         PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArray.data()->propertyNameVector();
         for (size_t i = 0; i < propertyNameVector.size(); ++i) {
             JSValue value = prototype->getDirect(vm, propertyNameVector[i]);
index f21e05f5fd292c6248fb48cddab08cba34ca59c0..78ddaa525442a593271a1845307e91576f6758a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,10 +52,10 @@ class Operands {
 public:
     Operands() { }
     
-    explicit Operands(size_t numArguments, size_t numLocals)
+    explicit Operands(size_t numArguments, size_t numLocals, const T& initialValue = Traits::defaultValue())
     {
-        m_arguments.fill(Traits::defaultValue(), numArguments);
-        m_locals.fill(Traits::defaultValue(), numLocals);
+        m_arguments.fill(initialValue, numArguments);
+        m_locals.fill(initialValue, numLocals);
     }
     
     template<typename U, typename OtherTraits>
@@ -96,7 +96,7 @@ public:
         return local(idx);
     }
     
-    void ensureLocals(size_t size)
+    void ensureLocals(size_t size, const T& ensuredValue = Traits::defaultValue())
     {
         if (size <= m_locals.size())
             return;
@@ -104,7 +104,7 @@ public:
         size_t oldSize = m_locals.size();
         m_locals.resize(size);
         for (size_t i = oldSize; i < m_locals.size(); ++i)
-            m_locals[i] = Traits::defaultValue();
+            m_locals[i] = ensuredValue;
     }
     
     void setLocal(size_t idx, const T& value)
@@ -149,6 +149,7 @@ public:
     }
 
     const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
+    const T& operand(VirtualRegister operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
     
     bool hasOperand(int operand) const
     {
@@ -209,6 +210,10 @@ public:
             return virtualRegisterForArgument(index).offset();
         return virtualRegisterForLocal(index - numberOfArguments()).offset();
     }
+    VirtualRegister virtualRegisterForIndex(size_t index) const
+    {
+        return VirtualRegister(operandForIndex(index));
+    }
     size_t indexForOperand(int operand) const
     {
         if (operandIsArgument(operand))
@@ -252,11 +257,7 @@ public:
     }
     
     void dumpInContext(PrintStream& out, DumpContext* context) const;
-    
-    void dump(PrintStream& out) const
-    {
-        dumpInContext(out, 0);
-    }
+    void dump(PrintStream& out) const;
     
 private:
     Vector<T, 8> m_arguments;
index 74ad60bc18a80c4b292f0b08ab1f1e98755bcc90..c9dee88c7a03e400c447e48d841b0c315ecfedf5 100644 (file)
@@ -47,6 +47,22 @@ void Operands<T, Traits>::dumpInContext(PrintStream& out, DumpContext* context)
     }
 }
 
+template<typename T, typename Traits>
+void Operands<T, Traits>::dump(PrintStream& out) const
+{
+    CommaPrinter comma(" ");
+    for (size_t argumentIndex = numberOfArguments(); argumentIndex--;) {
+        if (Traits::isEmptyForDump(argument(argumentIndex)))
+            continue;
+        out.print(comma, "arg", argumentIndex, ":", argument(argumentIndex));
+    }
+    for (size_t localIndex = 0; localIndex < numberOfLocals(); ++localIndex) {
+        if (Traits::isEmptyForDump(local(localIndex)))
+            continue;
+        out.print(comma, "loc", localIndex, ":", local(localIndex));
+    }
+}
+
 } // namespace JSC
 
 #endif // OperandsInlines_h
index c4005c07a2217c91a6a6c5e78a0c5994d7dab6c7..c1e5e67584769c5ae23fc1453c15da4ae2c460ab 100644 (file)
@@ -58,27 +58,11 @@ GetByIdAccess GetByIdAccess::fromStructureStubInfo(StructureStubInfo& stubInfo)
     
     GetByIdAccess result;
     
-    switch (stubInfo.accessType) {
-    case access_get_by_id_self:
-        result.m_type = SimpleInline;
-        result.m_structure.copyFrom(stubInfo.u.getByIdSelf.baseObjectStructure);
-        result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
-        break;
-        
-    case access_get_by_id_chain:
-        result.m_structure.copyFrom(stubInfo.u.getByIdChain.baseObjectStructure);
-        result.m_chain.copyFrom(stubInfo.u.getByIdChain.chain);
-        result.m_chainCount = stubInfo.u.getByIdChain.count;
-        result.m_stubRoutine = stubInfo.stubRoutine;
-        if (stubInfo.u.getByIdChain.isDirect)
-            result.m_type = SimpleStub;
-        else
-            result.m_type = Getter;
-        break;
-        
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
+    RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_self);
+    
+    result.m_type = SimpleInline;
+    result.m_structure.copyFrom(stubInfo.u.getByIdSelf.baseObjectStructure);
+    result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
     
     return result;
 }
@@ -109,7 +93,6 @@ PolymorphicGetByIdList* PolymorphicGetByIdList::from(StructureStubInfo& stubInfo
     
     ASSERT(
         stubInfo.accessType == access_get_by_id_self
-        || stubInfo.accessType == access_get_by_id_chain
         || stubInfo.accessType == access_unset);
     
     PolymorphicGetByIdList* result = new PolymorphicGetByIdList(stubInfo);
@@ -133,7 +116,7 @@ void PolymorphicGetByIdList::addAccess(const GetByIdAccess& access)
 {
     ASSERT(!isFull());
     // Make sure that the resizing optimizes for space, not time.
-    m_list.resize(m_list.size() + 1);
+    m_list.resizeToFit(m_list.size() + 1);
     m_list.last() = access;
 }
 
index 265b0ad24e83a7a54d18fd1644efd366c714d970..4867d43df55342f9b0eb8894e2fe589cc85bb182 100644 (file)
@@ -47,7 +47,8 @@ public:
         SimpleStub, // This is a stub.
         WatchedStub,
         Getter,
-        CustomGetter
+        CustomGetter,
+        SimpleMiss,
     };
     
     GetByIdAccess()
index 8605a507db1f1db86aec664b94ed45da876dc8ff..91b87d4e4c36743b922ba96273fc77ef1d86f744 100644 (file)
@@ -138,7 +138,7 @@ void PolymorphicPutByIdList::addAccess(const PutByIdAccess& putByIdAccess)
 {
     ASSERT(!isFull());
     // Make sure that the resizing optimizes for space, not time.
-    m_list.resize(m_list.size() + 1);
+    m_list.resizeToFit(m_list.size() + 1);
     m_list.last() = putByIdAccess;
 }
 
index 15d7bde31c9d1eb2a3a5ec1a3db1394f49e4c34a..2d35501d35ef4920fcc3973c46a3d9512b870c3a 100644 (file)
@@ -53,6 +53,7 @@ public:
     
     PutByIdAccess()
         : m_type(Invalid)
+        , m_chainCount(UINT_MAX)
     {
     }
     
@@ -95,6 +96,7 @@ public:
         AccessType accessType,
         Structure* structure,
         StructureChain* chain,
+        unsigned chainCount,
         PutPropertySlot::PutValueFunc customSetter,
         PassRefPtr<JITStubRoutine> stubRoutine)
     {
@@ -102,8 +104,10 @@ public:
         PutByIdAccess result;
         result.m_oldStructure.set(vm, owner, structure);
         result.m_type = accessType;
-        if (chain)
+        if (chain) {
             result.m_chain.set(vm, owner, chain);
+            result.m_chainCount = chainCount;
+        }
         result.m_customSetter = customSetter;
         result.m_stubRoutine = stubRoutine;
         return result;
@@ -132,7 +136,7 @@ public:
     
     Structure* structure() const
     {
-        ASSERT(isReplace());
+        ASSERT(isReplace() || isSetter() || isCustom());
         return m_oldStructure.get();
     }
     
@@ -148,6 +152,12 @@ public:
         return m_chain.get();
     }
     
+    unsigned chainCount() const
+    {
+        ASSERT(isSetter() || isCustom());
+        return m_chainCount;
+    }
+    
     JITStubRoutine* stubRoutine() const
     {
         ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
@@ -169,6 +179,7 @@ private:
     WriteBarrier<Structure> m_oldStructure;
     WriteBarrier<Structure> m_newStructure;
     WriteBarrier<StructureChain> m_chain;
+    unsigned m_chainCount;
     PutPropertySlot::PutValueFunc m_customSetter;
     RefPtr<JITStubRoutine> m_stubRoutine;
 };
index 87f2ceb05576236d5042a9b25366c1b805dff752..6bba492124dc4341b8d4d39562fff77dc7d1cd24 100644 (file)
@@ -73,12 +73,6 @@ static void getJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, Interpreter* i
         out.append(bytecodeOffset + current[2].u.operand);
         break;
     }
-    case op_get_pnames:
-        out.append(bytecodeOffset + current[5].u.operand);
-        break;
-    case op_next_pname:
-        out.append(bytecodeOffset + current[6].u.operand);
-        break;
     case op_check_has_instance:
         out.append(bytecodeOffset + current[4].u.operand);
         break;
diff --git a/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp b/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp
deleted file mode 100644 (file)
index 5d77099..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ProfiledCodeBlockJettisoningWatchpoint.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "CodeBlock.h"
-#include "DFGCommon.h"
-#include "DFGExitProfile.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-void ProfiledCodeBlockJettisoningWatchpoint::fireInternal()
-{
-    if (DFG::shouldShowDisassembly()) {
-        dataLog(
-            "Firing profiled watchpoint ", RawPointer(this), " on ", *m_codeBlock, " due to ",
-            m_exitKind, " at ", m_codeOrigin, "\n");
-    }
-    
-    // FIXME: Maybe this should call alternative().
-    // https://bugs.webkit.org/show_bug.cgi?id=123677
-    CodeBlock* machineBaselineCodeBlock = m_codeBlock->baselineAlternative();
-    CodeBlock* sourceBaselineCodeBlock =
-        baselineCodeBlockForOriginAndBaselineCodeBlock(
-            m_codeOrigin, machineBaselineCodeBlock);
-    
-    if (sourceBaselineCodeBlock) {
-        sourceBaselineCodeBlock->addFrequentExitSite(
-            DFG::FrequentExitSite(
-                m_codeOrigin.bytecodeIndex, m_exitKind,
-                exitingJITTypeFor(m_codeBlock->jitType())));
-    }
-    
-    m_codeBlock->jettison(Profiler::JettisonDueToProfiledWatchpoint, CountReoptimization);
-    
-    if (isOnList())
-        remove();
-}
-
-} // namespace JSC
-
-#endif // ENABLE(DFG_JIT)
diff --git a/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h b/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h
deleted file mode 100644 (file)
index 33c32bf..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ProfiledCodeBlockJettisoningWatchpoint_h
-#define ProfiledCodeBlockJettisoningWatchpoint_h
-
-#if ENABLE(DFG_JIT)
-
-#include "CodeOrigin.h"
-#include "ExitKind.h"
-#include "Watchpoint.h"
-
-namespace JSC {
-
-class CodeBlock;
-
-class ProfiledCodeBlockJettisoningWatchpoint : public Watchpoint {
-public:
-    ProfiledCodeBlockJettisoningWatchpoint()
-        : m_exitKind(ExitKindUnset)
-        , m_codeBlock(0)
-    {
-    }
-    
-    ProfiledCodeBlockJettisoningWatchpoint(
-        CodeOrigin codeOrigin, ExitKind exitKind, CodeBlock* codeBlock)
-        : m_codeOrigin(codeOrigin)
-        , m_exitKind(exitKind)
-        , m_codeBlock(codeBlock)
-    {
-    }
-    
-protected:
-    virtual void fireInternal() override;
-
-private:
-    CodeOrigin m_codeOrigin;
-    ExitKind m_exitKind;
-    CodeBlock* m_codeBlock;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // ProfiledCodeBlockJettisoningWatchpoint_h
-
index 5743750eb4957ca6019314356942097f4b413fae..9e219d2fdefa9650c82599919aca67b597133123 100644 (file)
@@ -26,7 +26,9 @@
 #include "config.h"
 #include "PutByIdStatus.h"
 
+#include "AccessorCallJITStubRoutine.h"
 #include "CodeBlock.h"
+#include "ComplexGetStatus.h"
 #include "LLIntData.h"
 #include "LowLevelInterpreter.h"
 #include "JSCInlines.h"
@@ -40,7 +42,11 @@ namespace JSC {
 bool PutByIdStatus::appendVariant(const PutByIdVariant& variant)
 {
     for (unsigned i = 0; i < m_variants.size(); ++i) {
-        if (m_variants[i].oldStructure() == variant.oldStructure())
+        if (m_variants[i].attemptToMerge(variant))
+            return true;
+    }
+    for (unsigned i = 0; i < m_variants.size(); ++i) {
+        if (m_variants[i].oldStructure().overlaps(variant.oldStructure()))
             return false;
     }
     m_variants.append(variant);
@@ -48,17 +54,15 @@ bool PutByIdStatus::appendVariant(const PutByIdVariant& variant)
 }
 
 #if ENABLE(DFG_JIT)
-bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType exitType)
+bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
 {
-    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, exitType))
-        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, exitType));
+    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
+        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache));
     
 }
 #endif
 
-PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, StringImpl* uid)
+PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, UniquedStringImpl* uid)
 {
     UNUSED_PARAM(profiledBlock);
     UNUSED_PARAM(bytecodeIndex);
@@ -71,7 +75,7 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
     
     if (instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id)
         || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_out_of_line)) {
-        PropertyOffset offset = structure->getConcurrently(*profiledBlock->vm(), uid);
+        PropertyOffset offset = structure->getConcurrently(uid);
         if (!isValidOffset(offset))
             return PutByIdStatus(NoInformation);
         
@@ -90,17 +94,18 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
     ASSERT(newStructure);
     ASSERT(chain);
     
-    PropertyOffset offset = newStructure->getConcurrently(*profiledBlock->vm(), uid);
+    PropertyOffset offset = newStructure->getConcurrently(uid);
     if (!isValidOffset(offset))
         return PutByIdStatus(NoInformation);
     
-    return PutByIdVariant::transition(
-        structure, newStructure,
-        chain ? adoptRef(new IntendedStructureChain(profiledBlock, structure, chain)) : 0,
-        offset);
+    RefPtr<IntendedStructureChain> intendedChain;
+    if (chain)
+        intendedChain = adoptRef(new IntendedStructureChain(profiledBlock, structure, chain));
+    
+    return PutByIdVariant::transition(structure, newStructure, intendedChain.get(), offset);
 }
 
-PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, StringImpl* uid)
+PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, UniquedStringImpl* uid)
 {
     ConcurrentJITLocker locker(profiledBlock->m_lock);
     
@@ -108,12 +113,13 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& m
     UNUSED_PARAM(bytecodeIndex);
     UNUSED_PARAM(uid);
 #if ENABLE(DFG_JIT)
-    if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex)
-        || hasExitSite(locker, profiledBlock, bytecodeIndex))
+    if (hasExitSite(locker, profiledBlock, bytecodeIndex))
         return PutByIdStatus(TakesSlowPath);
     
     StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex));
-    PutByIdStatus result = computeForStubInfo(locker, profiledBlock, stubInfo, uid);
+    PutByIdStatus result = computeForStubInfo(
+        locker, profiledBlock, stubInfo, uid,
+        CallLinkStatus::computeExitSiteData(locker, profiledBlock, bytecodeIndex));
     if (!result)
         return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
     
@@ -125,14 +131,19 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& m
 }
 
 #if ENABLE(JIT)
-PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, StringImpl* uid)
+PutByIdStatus PutByIdStatus::computeForStubInfo(
+    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo,
+    UniquedStringImpl* uid, CallLinkStatus::ExitSiteData callExitSiteData)
 {
-    if (!stubInfo || !stubInfo->seen)
+    if (!stubInfo)
         return PutByIdStatus();
     
-    if (stubInfo->resetByGC)
+    if (stubInfo->tookSlowPath)
         return PutByIdStatus(TakesSlowPath);
-
+    
+    if (!stubInfo->seen)
+        return PutByIdStatus();
+    
     switch (stubInfo->accessType) {
     case access_unset:
         // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
@@ -140,8 +151,7 @@ PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, Code
         
     case access_put_by_id_replace: {
         PropertyOffset offset =
-            stubInfo->u.putByIdReplace.baseObjectStructure->getConcurrently(
-                *profiledBlock->vm(), uid);
+            stubInfo->u.putByIdReplace.baseObjectStructure->getConcurrently(uid);
         if (isValidOffset(offset)) {
             return PutByIdVariant::replace(
                 stubInfo->u.putByIdReplace.baseObjectStructure.get(), offset);
@@ -153,16 +163,18 @@ PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, Code
     case access_put_by_id_transition_direct: {
         ASSERT(stubInfo->u.putByIdTransition.previousStructure->transitionWatchpointSetHasBeenInvalidated());
         PropertyOffset offset = 
-            stubInfo->u.putByIdTransition.structure->getConcurrently(
-                *profiledBlock->vm(), uid);
+            stubInfo->u.putByIdTransition.structure->getConcurrently(uid);
         if (isValidOffset(offset)) {
+            RefPtr<IntendedStructureChain> chain;
+            if (stubInfo->u.putByIdTransition.chain) {
+                chain = adoptRef(new IntendedStructureChain(
+                    profiledBlock, stubInfo->u.putByIdTransition.previousStructure.get(),
+                    stubInfo->u.putByIdTransition.chain.get()));
+            }
             return PutByIdVariant::transition(
                 stubInfo->u.putByIdTransition.previousStructure.get(),
                 stubInfo->u.putByIdTransition.structure.get(),
-                stubInfo->u.putByIdTransition.chain ? adoptRef(new IntendedStructureChain(
-                    profiledBlock, stubInfo->u.putByIdTransition.previousStructure.get(),
-                    stubInfo->u.putByIdTransition.chain.get())) : 0,
-                offset);
+                chain.get(), offset);
         }
         return PutByIdStatus(TakesSlowPath);
     }
@@ -173,41 +185,89 @@ PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, Code
         PutByIdStatus result;
         result.m_state = Simple;
         
+        State slowPathState = TakesSlowPath;
+        for (unsigned i = 0; i < list->size(); ++i) {
+            const PutByIdAccess& access = list->at(i);
+            
+            switch (access.type()) {
+            case PutByIdAccess::Setter:
+            case PutByIdAccess::CustomSetter:
+                slowPathState = MakesCalls;
+                break;
+            default:
+                break;
+            }
+        }
+        
         for (unsigned i = 0; i < list->size(); ++i) {
             const PutByIdAccess& access = list->at(i);
             
+            PutByIdVariant variant;
+            
             switch (access.type()) {
             case PutByIdAccess::Replace: {
                 Structure* structure = access.structure();
-                PropertyOffset offset = structure->getConcurrently(*profiledBlock->vm(), uid);
+                PropertyOffset offset = structure->getConcurrently(uid);
                 if (!isValidOffset(offset))
-                    return PutByIdStatus(TakesSlowPath);
-                if (!result.appendVariant(PutByIdVariant::replace(structure, offset)))
-                    return PutByIdStatus(TakesSlowPath);
+                    return PutByIdStatus(slowPathState);
+                variant = PutByIdVariant::replace(structure, offset);
                 break;
             }
                 
             case PutByIdAccess::Transition: {
                 PropertyOffset offset =
-                    access.newStructure()->getConcurrently(*profiledBlock->vm(), uid);
+                    access.newStructure()->getConcurrently(uid);
                 if (!isValidOffset(offset))
-                    return PutByIdStatus(TakesSlowPath);
-                bool ok = result.appendVariant(PutByIdVariant::transition(
-                    access.oldStructure(), access.newStructure(),
-                    access.chain() ? adoptRef(new IntendedStructureChain(
-                        profiledBlock, access.oldStructure(), access.chain())) : 0,
-                    offset));
-                if (!ok)
-                    return PutByIdStatus(TakesSlowPath);
+                    return PutByIdStatus(slowPathState);
+                RefPtr<IntendedStructureChain> chain;
+                if (access.chain()) {
+                    chain = adoptRef(new IntendedStructureChain(
+                        profiledBlock, access.oldStructure(), access.chain()));
+                    if (!chain->isStillValid())
+                        continue;
+                }
+                variant = PutByIdVariant::transition(
+                    access.oldStructure(), access.newStructure(), chain.get(), offset);
                 break;
             }
-            case PutByIdAccess::Setter:
+                
+            case PutByIdAccess::Setter: {
+                Structure* structure = access.structure();
+                
+                ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
+                    profiledBlock, structure, access.chain(), access.chainCount(), uid);
+                
+                switch (complexGetStatus.kind()) {
+                case ComplexGetStatus::ShouldSkip:
+                    continue;
+                    
+                case ComplexGetStatus::TakesSlowPath:
+                    return PutByIdStatus(slowPathState);
+                    
+                case ComplexGetStatus::Inlineable: {
+                    AccessorCallJITStubRoutine* stub = static_cast<AccessorCallJITStubRoutine*>(
+                        access.stubRoutine());
+                    std::unique_ptr<CallLinkStatus> callLinkStatus =
+                        std::make_unique<CallLinkStatus>(
+                            CallLinkStatus::computeFor(
+                                locker, profiledBlock, *stub->m_callLinkInfo, callExitSiteData));
+                    
+                    variant = PutByIdVariant::setter(
+                        structure, complexGetStatus.offset(), complexGetStatus.chain(),
+                        WTF::move(callLinkStatus));
+                } }
+                break;
+            }
+                
             case PutByIdAccess::CustomSetter:
                 return PutByIdStatus(MakesCalls);
 
             default:
-                return PutByIdStatus(TakesSlowPath);
+                return PutByIdStatus(slowPathState);
             }
+            
+            if (!result.appendVariant(variant))
+                return PutByIdStatus(slowPathState);
         }
         
         return result;
@@ -219,20 +279,24 @@ PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, Code
 }
 #endif
 
-PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin codeOrigin, StringImpl* uid)
+PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin codeOrigin, UniquedStringImpl* uid)
 {
 #if ENABLE(DFG_JIT)
     if (dfgBlock) {
+        CallLinkStatus::ExitSiteData exitSiteData;
         {
             ConcurrentJITLocker locker(baselineBlock->m_lock);
-            if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
+            if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex))
                 return PutByIdStatus(TakesSlowPath);
+            exitSiteData = CallLinkStatus::computeExitSiteData(
+                locker, baselineBlock, codeOrigin.bytecodeIndex);
         }
             
         PutByIdStatus result;
         {
             ConcurrentJITLocker locker(dfgBlock->m_lock);
-            result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
+            result = computeForStubInfo(
+                locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData);
         }
         
         // We use TakesSlowPath in some cases where the stub was unset. That's weird and
@@ -249,88 +313,109 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfg
     return computeFor(baselineBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
 }
 
-PutByIdStatus PutByIdStatus::computeFor(VM& vm, JSGlobalObject* globalObject, Structure* structure, StringImpl* uid, bool isDirect)
+PutByIdStatus PutByIdStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, UniquedStringImpl* uid, bool isDirect)
 {
-    if (toUInt32FromStringImpl(uid) != PropertyName::NotAnIndex)
+    if (parseIndex(*uid))
         return PutByIdStatus(TakesSlowPath);
 
-    if (!structure)
-        return PutByIdStatus(TakesSlowPath);
+    if (set.isEmpty())
+        return PutByIdStatus();
     
-    if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType)
-        return PutByIdStatus(TakesSlowPath);
+    PutByIdStatus result;
+    result.m_state = Simple;
+    for (unsigned i = 0; i < set.size(); ++i) {
+        Structure* structure = set[i];
+        
+        if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType)
+            return PutByIdStatus(TakesSlowPath);
 
-    if (!structure->propertyAccessesAreCacheable())
-        return PutByIdStatus(TakesSlowPath);
+        if (!structure->propertyAccessesAreCacheable())
+            return PutByIdStatus(TakesSlowPath);
     
-    unsigned attributes;
-    JSCell* specificValue;
-    PropertyOffset offset = structure->getConcurrently(vm, uid, attributes, specificValue);
-    if (isValidOffset(offset)) {
-        if (attributes & CustomAccessor)
-            return PutByIdStatus(MakesCalls);
+        unsigned attributes;
+        PropertyOffset offset = structure->getConcurrently(uid, attributes);
+        if (isValidOffset(offset)) {
+            if (attributes & CustomAccessor)
+                return PutByIdStatus(MakesCalls);
 
-        if (attributes & (Accessor | ReadOnly))
-            return PutByIdStatus(TakesSlowPath);
-        if (specificValue) {
-            // We need the PutById slow path to verify that we're storing the right value into
-            // the specialized slot.
-            return PutByIdStatus(TakesSlowPath);
+            if (attributes & (Accessor | ReadOnly))
+                return PutByIdStatus(TakesSlowPath);
+            
+            WatchpointSet* replaceSet = structure->propertyReplacementWatchpointSet(offset);
+            if (!replaceSet || replaceSet->isStillValid()) {
+                // When this executes, it'll create, and fire, this replacement watchpoint set.
+                // That means that  this has probably never executed or that something fishy is
+                // going on. Also, we cannot create or fire the watchpoint set from the concurrent
+                // JIT thread, so even if we wanted to do this, we'd need to have a lazy thingy.
+                // So, better leave this alone and take slow path.
+                return PutByIdStatus(TakesSlowPath);
+            }
+            
+            if (!result.appendVariant(PutByIdVariant::replace(structure, offset)))
+                return PutByIdStatus(TakesSlowPath);
+            continue;
         }
-        return PutByIdVariant::replace(structure, offset);
-    }
     
-    // Our hypothesis is that we're doing a transition. Before we prove that this is really
-    // true, we want to do some sanity checks.
+        // Our hypothesis is that we're doing a transition. Before we prove that this is really
+        // true, we want to do some sanity checks.
     
-    // Don't cache put transitions on dictionaries.
-    if (structure->isDictionary())
-        return PutByIdStatus(TakesSlowPath);
+        // Don't cache put transitions on dictionaries.
+        if (structure->isDictionary())
+            return PutByIdStatus(TakesSlowPath);
 
-    // If the structure corresponds to something that isn't an object, then give up, since
-    // we don't want to be adding properties to strings.
-    if (structure->typeInfo().type() == StringType)
-        return PutByIdStatus(TakesSlowPath);
+        // If the structure corresponds to something that isn't an object, then give up, since
+        // we don't want to be adding properties to strings.
+        if (!structure->typeInfo().isObject())
+            return PutByIdStatus(TakesSlowPath);
     
-    RefPtr<IntendedStructureChain> chain;
-    if (!isDirect) {
-        chain = adoptRef(new IntendedStructureChain(globalObject, structure));
+        RefPtr<IntendedStructureChain> chain;
+        if (!isDirect) {
+            chain = adoptRef(new IntendedStructureChain(globalObject, structure));
         
-        // If the prototype chain has setters or read-only properties, then give up.
-        if (chain->mayInterceptStoreTo(vm, uid))
-            return PutByIdStatus(TakesSlowPath);
+            // If the prototype chain has setters or read-only properties, then give up.
+            if (chain->mayInterceptStoreTo(uid))
+                return PutByIdStatus(TakesSlowPath);
         
-        // If the prototype chain hasn't been normalized (i.e. there are proxies or dictionaries)
-        // then give up. The dictionary case would only happen if this structure has not been
-        // used in an optimized put_by_id transition. And really the only reason why we would
-        // bail here is that I don't really feel like having the optimizing JIT go and flatten
-        // dictionaries if we have evidence to suggest that those objects were never used as
-        // prototypes in a cacheable prototype access - i.e. there's a good chance that some of
-        // the other checks below will fail.
-        if (!chain->isNormalized())
+            // If the prototype chain hasn't been normalized (i.e. there are proxies or dictionaries)
+            // then give up. The dictionary case would only happen if this structure has not been
+            // used in an optimized put_by_id transition. And really the only reason why we would
+            // bail here is that I don't really feel like having the optimizing JIT go and flatten
+            // dictionaries if we have evidence to suggest that those objects were never used as
+            // prototypes in a cacheable prototype access - i.e. there's a good chance that some of
+            // the other checks below will fail.
+            if (structure->isProxy() || !chain->isNormalized())
+                return PutByIdStatus(TakesSlowPath);
+        }
+    
+        // We only optimize if there is already a structure that the transition is cached to.
+        Structure* transition = Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, offset);
+        if (!transition)
+            return PutByIdStatus(TakesSlowPath);
+        ASSERT(isValidOffset(offset));
+    
+        bool didAppend = result.appendVariant(
+            PutByIdVariant::transition(structure, transition, chain.get(), offset));
+        if (!didAppend)
             return PutByIdStatus(TakesSlowPath);
     }
     
-    // We only optimize if there is already a structure that the transition is cached to.
-    // Among other things, this allows us to guard against a transition with a specific
-    // value.
-    //
-    // - If we're storing a value that could be specific: this would only be a problem if
-    //   the existing transition did have a specific value already, since if it didn't,
-    //   then we would behave "as if" we were not storing a specific value. If it did
-    //   have a specific value, then we'll know - the fact that we pass 0 for
-    //   specificValue will tell us.
-    //
-    // - If we're not storing a value that could be specific: again, this would only be a
-    //   problem if the existing transition did have a specific value, which we check for
-    //   by passing 0 for the specificValue.
-    Structure* transition = Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, 0, offset);
-    if (!transition)
-        return PutByIdStatus(TakesSlowPath); // This occurs in bizarre cases only. See above.
-    ASSERT(!transition->transitionDidInvolveSpecificValue());
-    ASSERT(isValidOffset(offset));
+    return result;
+}
+
+bool PutByIdStatus::makesCalls() const
+{
+    if (m_state == MakesCalls)
+        return true;
+    
+    if (m_state != Simple)
+        return false;
+    
+    for (unsigned i = m_variants.size(); i--;) {
+        if (m_variants[i].makesCalls())
+            return true;
+    }
     
-    return PutByIdVariant::transition(structure, transition, chain.release(), offset);
+    return false;
 }
 
 void PutByIdStatus::dump(PrintStream& out) const
index d2db7a6f43ff5465f8f55e946cce9bce3f7735f9..652ccc18a02fb3913e56a9a0a2a8b54515d99044 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef PutByIdStatus_h
 #define PutByIdStatus_h
 
+#include "CallLinkStatus.h"
 #include "ExitingJITType.h"
 #include "PutByIdVariant.h"
 #include "StructureStubInfo.h"
@@ -69,10 +70,10 @@ public:
         m_variants.append(variant);
     }
     
-    static PutByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, StringImpl* uid);
-    static PutByIdStatus computeFor(VM&, JSGlobalObject*, Structure*, StringImpl* uid, bool isDirect);
+    static PutByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, UniquedStringImpl* uid);
+    static PutByIdStatus computeFor(JSGlobalObject*, const StructureSet&, UniquedStringImpl* uid, bool isDirect);
     
-    static PutByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, StringImpl* uid);
+    static PutByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, UniquedStringImpl* uid);
     
     State state() const { return m_state; }
     
@@ -80,7 +81,7 @@ public:
     bool operator!() const { return m_state == NoInformation; }
     bool isSimple() const { return m_state == Simple; }
     bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
-    bool makesCalls() const { return m_state == MakesCalls; }
+    bool makesCalls() const;
     
     size_t numVariants() const { return m_variants.size(); }
     const Vector<PutByIdVariant, 1>& variants() const { return m_variants; }
@@ -91,12 +92,14 @@ public:
     
 private:
 #if ENABLE(DFG_JIT)
-    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
+    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
 #endif
 #if ENABLE(JIT)
-    static PutByIdStatus computeForStubInfo(const ConcurrentJITLocker&, CodeBlock*, StructureStubInfo*, StringImpl* uid);
+    static PutByIdStatus computeForStubInfo(
+        const ConcurrentJITLocker&, CodeBlock*, StructureStubInfo*, UniquedStringImpl* uid,
+        CallLinkStatus::ExitSiteData);
 #endif
-    static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, StringImpl* uid);
+    static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, UniquedStringImpl* uid);
     
     bool appendVariant(const PutByIdVariant&);
     
index f83c1026b9a52b8e94e5de3a363a3ab00d58fa64..e9d10df673b5d9d7a082ad89ee3063f8a41be7e7 100644 (file)
 #include "config.h"
 #include "PutByIdVariant.h"
 
+#include "CallLinkStatus.h"
+#include "JSCInlines.h"
+#include <wtf/ListDump.h>
+
 namespace JSC {
 
+PutByIdVariant::PutByIdVariant(const PutByIdVariant& other)
+    : PutByIdVariant()
+{
+    *this = other;
+}
+
+PutByIdVariant& PutByIdVariant::operator=(const PutByIdVariant& other)
+{
+    m_kind = other.m_kind;
+    m_oldStructure = other.m_oldStructure;
+    m_newStructure = other.m_newStructure;
+    m_constantChecks = other.m_constantChecks;
+    m_alternateBase = other.m_alternateBase;
+    m_offset = other.m_offset;
+    if (other.m_callLinkStatus)
+        m_callLinkStatus = std::make_unique<CallLinkStatus>(*other.m_callLinkStatus);
+    else
+        m_callLinkStatus = nullptr;
+    return *this;
+}
+
+PutByIdVariant PutByIdVariant::replace(const StructureSet& structure, PropertyOffset offset)
+{
+    PutByIdVariant result;
+    result.m_kind = Replace;
+    result.m_oldStructure = structure;
+    result.m_offset = offset;
+    return result;
+}
+
+PutByIdVariant PutByIdVariant::transition(
+    const StructureSet& oldStructure, Structure* newStructure,
+    const IntendedStructureChain* structureChain, PropertyOffset offset)
+{
+    PutByIdVariant result;
+    result.m_kind = Transition;
+    result.m_oldStructure = oldStructure;
+    result.m_newStructure = newStructure;
+    if (structureChain)
+        structureChain->gatherChecks(result.m_constantChecks);
+    result.m_offset = offset;
+    return result;
+}
+
+PutByIdVariant PutByIdVariant::setter(
+    const StructureSet& structure, PropertyOffset offset,
+    IntendedStructureChain* chain, std::unique_ptr<CallLinkStatus> callLinkStatus)
+{
+    PutByIdVariant result;
+    result.m_kind = Setter;
+    result.m_oldStructure = structure;
+    if (chain) {
+        chain->gatherChecks(result.m_constantChecks);
+        result.m_alternateBase = chain->terminalPrototype();
+    }
+    result.m_offset = offset;
+    result.m_callLinkStatus = WTF::move(callLinkStatus);
+    return result;
+}
+
+Structure* PutByIdVariant::oldStructureForTransition() const
+{
+    ASSERT(kind() == Transition);
+    ASSERT(m_oldStructure.size() <= 2);
+    for (unsigned i = m_oldStructure.size(); i--;) {
+        Structure* structure = m_oldStructure[i];
+        if (structure != m_newStructure)
+            return structure;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+
+    return nullptr;
+}
+
+bool PutByIdVariant::writesStructures() const
+{
+    switch (kind()) {
+    case Transition:
+    case Setter:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool PutByIdVariant::reallocatesStorage() const
+{
+    switch (kind()) {
+    case Transition:
+        return oldStructureForTransition()->outOfLineCapacity() != newStructure()->outOfLineCapacity();
+    case Setter:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool PutByIdVariant::makesCalls() const
+{
+    return kind() == Setter;
+}
+
+StructureSet PutByIdVariant::baseStructure() const
+{
+    ASSERT(kind() == Setter);
+    
+    if (!m_alternateBase)
+        return structure();
+    
+    Structure* structure = structureFor(m_constantChecks, m_alternateBase);
+    RELEASE_ASSERT(structure);
+    return structure;
+}
+
+bool PutByIdVariant::attemptToMerge(const PutByIdVariant& other)
+{
+    if (m_offset != other.m_offset)
+        return false;
+    
+    switch (m_kind) {
+    case Replace:
+        switch (other.m_kind) {
+        case Replace: {
+            ASSERT(m_constantChecks.isEmpty());
+            ASSERT(other.m_constantChecks.isEmpty());
+            
+            m_oldStructure.merge(other.m_oldStructure);
+            return true;
+        }
+            
+        case Transition: {
+            PutByIdVariant newVariant = other;
+            if (newVariant.attemptToMergeTransitionWithReplace(*this)) {
+                *this = newVariant;
+                return true;
+            }
+            return false;
+        }
+            
+        default:
+            return false;
+        }
+        
+    case Transition:
+        switch (other.m_kind) {
+        case Replace:
+            return attemptToMergeTransitionWithReplace(other);
+            
+        default:
+            return false;
+        }
+        
+    default:
+        return false;
+    }
+}
+
+bool PutByIdVariant::attemptToMergeTransitionWithReplace(const PutByIdVariant& replace)
+{
+    ASSERT(m_kind == Transition);
+    ASSERT(replace.m_kind == Replace);
+    ASSERT(m_offset == replace.m_offset);
+    ASSERT(!replace.writesStructures());
+    ASSERT(!replace.reallocatesStorage());
+    
+    // This sort of merging only works when we have one path along which we add a new field which
+    // transitions to structure S while the other path was already on structure S. This doesn't
+    // work if we need to reallocate anything or if the replace path is polymorphic.
+    
+    if (reallocatesStorage())
+        return false;
+    
+    if (replace.m_oldStructure.onlyStructure() != m_newStructure)
+        return false;
+    
+    m_oldStructure.merge(m_newStructure);
+    return true;
+}
+
 void PutByIdVariant::dump(PrintStream& out) const
 {
     dumpInContext(out, 0);
@@ -42,14 +225,25 @@ void PutByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const
         
     case Replace:
         out.print(
-            "<Replace: ", pointerDumpInContext(structure(), context), ", ", offset(), ">");
+            "<Replace: ", inContext(structure(), context), ", offset = ", offset(), ">");
         return;
         
     case Transition:
         out.print(
-            "<Transition: ", pointerDumpInContext(oldStructure(), context), " -> ",
-            pointerDumpInContext(newStructure(), context), ", ",
-            pointerDumpInContext(structureChain(), context), ", ", offset(), ">");
+            "<Transition: ", inContext(oldStructure(), context), " -> ",
+            pointerDumpInContext(newStructure(), context), ", [",
+            listDumpInContext(constantChecks(), context), "], offset = ", offset(), ">");
+        return;
+        
+    case Setter:
+        out.print(
+            "<Setter: ", inContext(structure(), context), ", [",
+            listDumpInContext(constantChecks(), context), "]");
+        if (m_alternateBase)
+            out.print(", alternateBase = ", inContext(JSValue(m_alternateBase), context));
+        out.print(", offset = ", m_offset);
+        out.print(", call = ", *m_callLinkStatus);
+        out.print(">");
         return;
     }
     
index eba95e8478ada437e57e467794bb5fdcafc6b1fd..9dfedbd3e6831d939899a30ce3d5b128a4efc354 100644 (file)
 
 #include "IntendedStructureChain.h"
 #include "PropertyOffset.h"
+#include "StructureSet.h"
 
 namespace JSC {
 
+class CallLinkStatus;
+
 class PutByIdVariant {
 public:
     enum Kind {
         NotSet,
         Replace,
-        Transition
+        Transition,
+        Setter
     };
     
     PutByIdVariant()
         : m_kind(NotSet)
-        , m_oldStructure(0)
-        , m_newStructure(0)
+        , m_newStructure(nullptr)
+        , m_alternateBase(nullptr)
         , m_offset(invalidOffset)
     {
     }
     
-    static PutByIdVariant replace(Structure* structure, PropertyOffset offset)
-    {
-        PutByIdVariant result;
-        result.m_kind = Replace;
-        result.m_oldStructure = structure;
-        result.m_offset = offset;
-        return result;
-    }
+    PutByIdVariant(const PutByIdVariant&);
+    PutByIdVariant& operator=(const PutByIdVariant&);
+
+    static PutByIdVariant replace(
+        const StructureSet& structure, PropertyOffset offset);
     
     static PutByIdVariant transition(
-        Structure* oldStructure, Structure* newStructure,
-        PassRefPtr<IntendedStructureChain> structureChain, PropertyOffset offset)
-    {
-        PutByIdVariant result;
-        result.m_kind = Transition;
-        result.m_oldStructure = oldStructure;
-        result.m_newStructure = newStructure;
-        result.m_structureChain = structureChain;
-        result.m_offset = offset;
-        return result;
-    }
+        const StructureSet& oldStructure, Structure* newStructure,
+        const IntendedStructureChain* structureChain, PropertyOffset offset);
+    
+    static PutByIdVariant setter(
+        const StructureSet& structure, PropertyOffset offset,
+        IntendedStructureChain* chain, std::unique_ptr<CallLinkStatus> callLinkStatus);
     
     Kind kind() const { return m_kind; }
     
     bool isSet() const { return kind() != NotSet; }
     bool operator!() const { return !isSet(); }
     
-    Structure* structure() const
+    const StructureSet& structure() const
+    {
+        ASSERT(kind() == Replace || kind() == Setter);
+        return m_oldStructure;
+    }
+    
+    const StructureSet& oldStructure() const
     {
-        ASSERT(kind() == Replace);
+        ASSERT(kind() == Transition || kind() == Replace || kind() == Setter);
         return m_oldStructure;
     }
     
-    Structure* oldStructure() const
+    StructureSet& oldStructure()
     {
-        ASSERT(kind() == Transition || kind() == Replace);
+        ASSERT(kind() == Transition || kind() == Replace || kind() == Setter);
         return m_oldStructure;
     }
     
+    Structure* oldStructureForTransition() const;
+    
     Structure* newStructure() const
     {
         ASSERT(kind() == Transition);
         return m_newStructure;
     }
+
+    bool writesStructures() const;
+    bool reallocatesStorage() const;
+    bool makesCalls() const;
     
-    IntendedStructureChain* structureChain() const
+    const ConstantStructureCheckVector& constantChecks() const
     {
-        ASSERT(kind() == Transition);
-        return m_structureChain.get();
+        return m_constantChecks;
     }
     
     PropertyOffset offset() const
@@ -104,15 +111,35 @@ public:
         return m_offset;
     }
     
+    JSObject* alternateBase() const
+    {
+        ASSERT(kind() == Setter);
+        return m_alternateBase;
+    }
+    
+    StructureSet baseStructure() const;
+    
+    CallLinkStatus* callLinkStatus() const
+    {
+        ASSERT(kind() == Setter);
+        return m_callLinkStatus.get();
+    }
+
+    bool attemptToMerge(const PutByIdVariant& other);
+    
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
 
 private:
+    bool attemptToMergeTransitionWithReplace(const PutByIdVariant& replace);
+    
     Kind m_kind;
-    Structure* m_oldStructure;
+    StructureSet m_oldStructure;
     Structure* m_newStructure;
-    RefPtr<IntendedStructureChain> m_structureChain;
+    ConstantStructureCheckVector m_constantChecks;
+    JSObject* m_alternateBase;
     PropertyOffset m_offset;
+    std::unique_ptr<CallLinkStatus> m_callLinkStatus;
 };
 
 } // namespace JSC
index 678af85a45ffb8a2b7bc20d4b3585e2100f9ab1f..7d9c54fde3b509376aabe0fd122c0f9ed0611071 100644 (file)
@@ -271,7 +271,7 @@ namespace JSC {
             , m_sampleCount(0)
             , m_opcodeSampleCount(0)
 #if ENABLE(CODEBLOCK_SAMPLING)
-            , m_scopeSampleMap(adoptPtr(new ScriptSampleRecordMap))
+            , m_scopeSampleMap(std::make_unique<ScriptSampleRecordMap>)
 #endif
         {
             memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples));
@@ -338,7 +338,7 @@ namespace JSC {
         
 #if ENABLE(CODEBLOCK_SAMPLING)
         Mutex m_scriptSampleMapMutex;
-        OwnPtr<ScriptSampleRecordMap> m_scopeSampleMap;
+        std::unique_ptr<ScriptSampleRecordMap> m_scopeSampleMap;
 #endif
     };
 
index c18a6e904d8eebda71a63fe31f36af55f302b075..64fb23fcf27d41250480219e8c8c41b7c41a7ef5 100644 (file)
@@ -41,6 +41,11 @@ enum Pointer {
 };
 } // namespace Special
 
+enum class LinkTimeConstant {
+    DefinePropertyFunction,
+};
+const unsigned LinkTimeConstantCount = 1;
+
 inline bool pointerIsFunction(Special::Pointer pointer)
 {
     ASSERT_UNUSED(pointer, pointer < Special::TableSize);
index 19aeab719b634722f932c94c30fb6ca06e2df751..ca9514c0113db604b425a7d071407f98cf0cdf28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "SpeculatedType.h"
 
-#include "Arguments.h"
+#include "DirectArguments.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSCInlines.h"
+#include "ScopedArguments.h"
 #include "StringObject.h"
 #include "ValueProfile.h"
-#include <wtf/BoundsCheckedPointer.h>
 #include <wtf/StringPrintStream.h>
 
 namespace JSC {
@@ -127,8 +127,13 @@ void dumpSpeculation(PrintStream& out, SpeculatedType value)
             else
                 isTop = false;
     
-            if (value & SpecArguments)
-                myOut.print("Arguments");
+            if (value & SpecDirectArguments)
+                myOut.print("Directarguments");
+            else
+                isTop = false;
+    
+            if (value & SpecScopedArguments)
+                myOut.print("Scopedarguments");
             else
                 isTop = false;
     
@@ -151,12 +156,26 @@ void dumpSpeculation(PrintStream& out, SpeculatedType value)
             else
                 isTop = false;
         }
+
+        if (value & SpecSymbol)
+            myOut.print("Symbol");
+        else
+            isTop = false;
     }
     
-    if (value & SpecInt32)
+    if (value == SpecInt32)
         myOut.print("Int32");
-    else
-        isTop = false;
+    else {
+        if (value & SpecBoolInt32)
+            myOut.print("Boolint32");
+        else
+            isTop = false;
+        
+        if (value & SpecNonBoolInt32)
+            myOut.print("Nonboolint32");
+        else
+            isTop = false;
+    }
     
     if (value & SpecInt52)
         myOut.print("Int52");
@@ -232,8 +251,10 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
         return "<Float32array>";
     if (isFloat64ArraySpeculation(prediction))
         return "<Float64array>";
-    if (isArgumentsSpeculation(prediction))
-        return "<Arguments>";
+    if (isDirectArgumentsSpeculation(prediction))
+        return "<DirectArguments>";
+    if (isScopedArgumentsSpeculation(prediction))
+        return "<ScopedArguments>";
     if (isStringObjectSpeculation(prediction))
         return "<StringObject>";
     if (isStringOrStringObjectSpeculation(prediction))
@@ -242,6 +263,8 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
         return "<Object>";
     if (isCellSpeculation(prediction))
         return "<Cell>";
+    if (isBoolInt32Speculation(prediction))
+        return "<BoolInt32>";
     if (isInt32Speculation(prediction))
         return "<Int32>";
     if (isInt52AsDoubleSpeculation(prediction))
@@ -305,8 +328,11 @@ SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
     if (classInfo == JSArray::info())
         return SpecArray;
     
-    if (classInfo == Arguments::info())
-        return SpecArguments;
+    if (classInfo == DirectArguments::info())
+        return SpecDirectArguments;
+    
+    if (classInfo == ScopedArguments::info())
+        return SpecScopedArguments;
     
     if (classInfo == StringObject::info())
         return SpecStringObject;
@@ -327,6 +353,8 @@ SpeculatedType speculationFromStructure(Structure* structure)
 {
     if (structure->typeInfo().type() == StringType)
         return SpecString;
+    if (structure->typeInfo().type() == SymbolType)
+        return SpecSymbol;
     return speculationFromClassInfo(structure->classInfo());
 }
 
@@ -346,8 +374,11 @@ SpeculatedType speculationFromValue(JSValue value)
 {
     if (value.isEmpty())
         return SpecEmpty;
-    if (value.isInt32())
-        return SpecInt32;
+    if (value.isInt32()) {
+        if (value.asInt32() & ~1)
+            return SpecNonBoolInt32;
+        return SpecBoolInt32;
+    }
     if (value.isDouble()) {
         double number = value.asNumber();
         if (number != number)
@@ -497,7 +528,7 @@ SpeculatedType typeOfDoubleAbs(SpeculatedType value)
     return typeOfDoubleNegation(value);
 }
 
-SpeculatedType typeOfDoubleFRound(SpeculatedType value)
+SpeculatedType typeOfDoubleRounding(SpeculatedType value)
 {
     // We might lose bits, which leads to a NaN being purified.
     if (value & SpecDoubleImpureNaN)
@@ -508,6 +539,15 @@ SpeculatedType typeOfDoubleFRound(SpeculatedType value)
     return value;
 }
 
+SpeculatedType typeOfDoublePow(SpeculatedType xValue, SpeculatedType yValue)
+{
+    // Math.pow() always return NaN if the exponent is NaN, unlike std::pow().
+    // We always set a pure NaN in that case.
+    if (yValue & SpecDoubleNaN)
+        xValue |= SpecDoublePureNaN;
+    return polluteDouble(xValue);
+}
+
 SpeculatedType typeOfDoubleBinaryOp(SpeculatedType a, SpeculatedType b)
 {
     return polluteDouble(a | b);
index 5e90635c4caea407dc02bccc6987d865afe6b57c..bd045c3ac445706f9bc85d4f5b383c688dc3ddc2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,20 +52,24 @@ static const SpeculatedType SpecUint32Array        = 0x00000200; // It's definit
 static const SpeculatedType SpecFloat32Array       = 0x00000400; // It's definitely an Uint16Array or one of its subclasses.
 static const SpeculatedType SpecFloat64Array       = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
 static const SpeculatedType SpecTypedArrayView     = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
-static const SpeculatedType SpecArguments          = 0x00001000; // It's definitely an Arguments object.
-static const SpeculatedType SpecStringObject       = 0x00002000; // It's definitely a StringObject.
+static const SpeculatedType SpecDirectArguments    = 0x00001000; // It's definitely a DirectArguments object.
+static const SpeculatedType SpecScopedArguments    = 0x00002000; // It's definitely a ScopedArguments object.
+static const SpeculatedType SpecStringObject       = 0x00004000; // It's definitely a StringObject.
 static const SpeculatedType SpecObjectOther        = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
 static const SpeculatedType SpecObject             = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
 static const SpeculatedType SpecStringIdent        = 0x00010000; // It's definitely a JSString, and it's an identifier.
 static const SpeculatedType SpecStringVar          = 0x00020000; // It's definitely a JSString, and it's not an identifier.
 static const SpeculatedType SpecString             = 0x00030000; // It's definitely a JSString.
-static const SpeculatedType SpecCellOther          = 0x00040000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
-static const SpeculatedType SpecCell               = 0x0007ffff; // It's definitely a JSCell.
-static const SpeculatedType SpecInt32              = 0x00200000; // It's definitely an Int32.
+static const SpeculatedType SpecSymbol             = 0x00040000; // It's definitely a Symbol.
+static const SpeculatedType SpecCellOther          = 0x00080000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=133078
+static const SpeculatedType SpecCell               = 0x000fffff; // It's definitely a JSCell.
+static const SpeculatedType SpecBoolInt32          = 0x00100000; // It's definitely an Int32 with value 0 or 1.
+static const SpeculatedType SpecNonBoolInt32       = 0x00200000; // It's definitely an Int32 with value other than 0 or 1.
+static const SpeculatedType SpecInt32              = 0x00300000; // It's definitely an Int32.
 static const SpeculatedType SpecInt52              = 0x00400000; // It's definitely an Int52 and we intend it to unbox it.
-static const SpeculatedType SpecMachineInt         = 0x00600000; // It's something that we can do machine int arithmetic on.
+static const SpeculatedType SpecMachineInt         = 0x00700000; // It's something that we can do machine int arithmetic on.
 static const SpeculatedType SpecInt52AsDouble      = 0x00800000; // It's definitely an Int52 and it's inside a double.
-static const SpeculatedType SpecInteger            = 0x00e00000; // It's definitely some kind of integer.
+static const SpeculatedType SpecInteger            = 0x00f00000; // It's definitely some kind of integer.
 static const SpeculatedType SpecNonIntAsDouble     = 0x01000000; // It's definitely not an Int52 but it's a real number and it's a double.
 static const SpeculatedType SpecDoubleReal         = 0x01800000; // It's definitely a non-NaN double.
 static const SpeculatedType SpecDoublePureNaN      = 0x02000000; // It's definitely a NaN that is sae to tag (i.e. pure).
@@ -73,10 +77,10 @@ static const SpeculatedType SpecDoubleImpureNaN    = 0x04000000; // It's definit
 static const SpeculatedType SpecDoubleNaN          = 0x06000000; // It's definitely some kind of NaN.
 static const SpeculatedType SpecBytecodeDouble     = 0x03800000; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
 static const SpeculatedType SpecFullDouble         = 0x07800000; // It's either a non-NaN or a NaN double.
-static const SpeculatedType SpecBytecodeRealNumber = 0x01a00000; // It's either an Int32 or a DoubleReal.
-static const SpeculatedType SpecFullRealNumber     = 0x01e00000; // It's either an Int32 or a DoubleReal, or a Int52.
-static const SpeculatedType SpecBytecodeNumber     = 0x03a00000; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
-static const SpeculatedType SpecFullNumber         = 0x07e00000; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
+static const SpeculatedType SpecBytecodeRealNumber = 0x01b00000; // It's either an Int32 or a DoubleReal.
+static const SpeculatedType SpecFullRealNumber     = 0x01f00000; // It's either an Int32 or a DoubleReal, or a Int52.
+static const SpeculatedType SpecBytecodeNumber     = 0x03b00000; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
+static const SpeculatedType SpecFullNumber         = 0x07f00000; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
 static const SpeculatedType SpecBoolean            = 0x10000000; // It's definitely a Boolean.
 static const SpeculatedType SpecOther              = 0x20000000; // It's definitely either Null or Undefined.
 static const SpeculatedType SpecMisc               = 0x30000000; // It's definitely either a boolean, Null, or Undefined.
@@ -98,6 +102,11 @@ inline bool isCellSpeculation(SpeculatedType value)
     return !!(value & SpecCell) && !(value & ~SpecCell);
 }
 
+inline bool isNotCellSpeculation(SpeculatedType value)
+{
+    return !(value & SpecCell) && value;
+}
+
 inline bool isObjectSpeculation(SpeculatedType value)
 {
     return !!(value & SpecObject) && !(value & ~SpecObject);
@@ -133,6 +142,11 @@ inline bool isStringSpeculation(SpeculatedType value)
     return !!value && (value & SpecString) == value;
 }
 
+inline bool isSymbolSpeculation(SpeculatedType value)
+{
+    return value == SpecSymbol;
+}
+
 inline bool isArraySpeculation(SpeculatedType value)
 {
     return value == SpecArray;
@@ -188,9 +202,14 @@ inline bool isFloat64ArraySpeculation(SpeculatedType value)
     return value == SpecFloat64Array;
 }
 
-inline bool isArgumentsSpeculation(SpeculatedType value)
+inline bool isDirectArgumentsSpeculation(SpeculatedType value)
 {
-    return !!value && (value & SpecArguments) == value;
+    return value == SpecDirectArguments;
+}
+
+inline bool isScopedArgumentsSpeculation(SpeculatedType value)
+{
+    return value == SpecScopedArguments;
 }
 
 inline bool isActionableIntMutableArraySpeculation(SpeculatedType value)
@@ -219,13 +238,14 @@ inline bool isActionableTypedMutableArraySpeculation(SpeculatedType value)
 inline bool isActionableMutableArraySpeculation(SpeculatedType value)
 {
     return isArraySpeculation(value)
-        || isArgumentsSpeculation(value)
         || isActionableTypedMutableArraySpeculation(value);
 }
 
 inline bool isActionableArraySpeculation(SpeculatedType value)
 {
     return isStringSpeculation(value)
+        || isDirectArgumentsSpeculation(value)
+        || isScopedArgumentsSpeculation(value)
         || isActionableMutableArraySpeculation(value);
 }
 
@@ -244,9 +264,14 @@ inline bool isStringOrStringObjectSpeculation(SpeculatedType value)
     return !!value && !(value & ~(SpecString | SpecStringObject));
 }
 
+inline bool isBoolInt32Speculation(SpeculatedType value)
+{
+    return value == SpecBoolInt32;
+}
+
 inline bool isInt32Speculation(SpeculatedType value)
 {
-    return value == SpecInt32;
+    return value && !(value & ~SpecInt32);
 }
 
 inline bool isInt32OrBooleanSpeculation(SpeculatedType value)
@@ -410,7 +435,8 @@ SpeculatedType typeOfDoubleQuotient(SpeculatedType, SpeculatedType);
 SpeculatedType typeOfDoubleMinMax(SpeculatedType, SpeculatedType);
 SpeculatedType typeOfDoubleNegation(SpeculatedType);
 SpeculatedType typeOfDoubleAbs(SpeculatedType);
-SpeculatedType typeOfDoubleFRound(SpeculatedType);
+SpeculatedType typeOfDoubleRounding(SpeculatedType);
+SpeculatedType typeOfDoublePow(SpeculatedType, SpeculatedType);
 
 // This conservatively models the behavior of arbitrary double operations.
 SpeculatedType typeOfDoubleBinaryOp(SpeculatedType, SpeculatedType);
diff --git a/bytecode/StructureSet.cpp b/bytecode/StructureSet.cpp
new file mode 100644 (file)
index 0000000..40fea8d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "StructureSet.h"
+
+#include "DFGAbstractValue.h"
+#include "TrackedReferences.h"
+#include <wtf/CommaPrinter.h>
+
+namespace JSC {
+
+#if ENABLE(DFG_JIT)
+
+void StructureSet::filter(const DFG::StructureAbstractValue& other)
+{
+    genericFilter([&] (Structure* structure) -> bool { return other.contains(structure); });
+}
+
+void StructureSet::filter(SpeculatedType type)
+{
+    genericFilter(
+        [&] (Structure* structure) -> bool {
+            return type & speculationFromStructure(structure);
+        });
+}
+
+void StructureSet::filterArrayModes(ArrayModes arrayModes)
+{
+    genericFilter(
+        [&] (Structure* structure) -> bool {
+            return arrayModes & arrayModeFromStructure(structure);
+        });
+}
+
+void StructureSet::filter(const DFG::AbstractValue& other)
+{
+    filter(other.m_structure);
+    filter(other.m_type);
+    filterArrayModes(other.m_arrayModes);
+}
+
+#endif // ENABLE(DFG_JIT)
+
+SpeculatedType StructureSet::speculationFromStructures() const
+{
+    SpeculatedType result = SpecNone;
+    forEach(
+        [&] (Structure* structure) {
+            mergeSpeculation(result, speculationFromStructure(structure));
+        });
+    return result;
+}
+
+ArrayModes StructureSet::arrayModesFromStructures() const
+{
+    ArrayModes result = 0;
+    forEach(
+        [&] (Structure* structure) {
+            mergeArrayModes(result, asArrayModes(structure->indexingType()));
+        });
+    return result;
+}
+
+void StructureSet::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    CommaPrinter comma;
+    out.print("[");
+    forEach([&] (Structure* structure) { out.print(comma, inContext(*structure, context)); });
+    out.print("]");
+}
+
+void StructureSet::dump(PrintStream& out) const
+{
+    dumpInContext(out, nullptr);
+}
+
+void StructureSet::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    forEach(
+        [&] (Structure* structure) {
+            trackedReferences.check(structure);
+        });
+}
+
+} // namespace JSC
+
index d7087b9dca3f6a07aebfba3faf8eec4cdc24b0f8..df19ec538c78a9d4128c25aeb69498c35045b138 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define StructureSet_h
 
 #include "ArrayProfile.h"
+#include "DumpContext.h"
 #include "SpeculatedType.h"
 #include "Structure.h"
-#include "DumpContext.h"
-#include <wtf/CommaPrinter.h>
-#include <wtf/Vector.h>
+#include <wtf/TinyPtrSet.h>
 
 namespace JSC {
 
+class TrackedReferences;
+
 namespace DFG {
 class StructureAbstractValue;
+struct AbstractValue;
 }
 
-class StructureSet {
+class StructureSet : public TinyPtrSet<Structure*> {
 public:
-    StructureSet() { }
-    
-    StructureSet(Structure* structure)
-    {
-        ASSERT(structure);
-        m_structures.append(structure);
-    }
-    
-    void clear()
-    {
-        m_structures.clear();
-    }
-    
-    void add(Structure* structure)
-    {
-        ASSERT(structure);
-        ASSERT(!contains(structure));
-        m_structures.append(structure);
-    }
-    
-    bool addAll(const StructureSet& other)
-    {
-        bool changed = false;
-        for (size_t i = 0; i < other.size(); ++i) {
-            if (contains(other[i]))
-                continue;
-            add(other[i]);
-            changed = true;
-        }
-        return changed;
-    }
-    
-    void remove(Structure* structure)
-    {
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (m_structures[i] != structure)
-                continue;
-            
-            m_structures[i] = m_structures.last();
-            m_structures.removeLast();
-            return;
-        }
-    }
-    
-    bool contains(Structure* structure) const
-    {
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (m_structures[i] == structure)
-                return true;
-        }
-        return false;
-    }
+    // I really want to do this:
+    // using TinyPtrSet::TinyPtrSet;
+    //
+    // But I can't because Windows.
     
-    bool containsOnly(Structure* structure) const
+    StructureSet()
     {
-        if (size() != 1)
-            return false;
-        return singletonStructure() == structure;
     }
     
-    bool isSubsetOf(const StructureSet& other) const
-    {
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (!other.contains(m_structures[i]))
-                return false;
-        }
-        return true;
-    }
-    
-    bool isSupersetOf(const StructureSet& other) const
-    {
-        return other.isSubsetOf(*this);
-    }
-    
-    bool overlaps(const StructureSet& other) const
-    {
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (other.contains(m_structures[i]))
-                return true;
-        }
-        return false;
-    }
-    
-    size_t size() const { return m_structures.size(); }
-    
-    // Call this if you know that the structure set must consist of exactly
-    // one structure.
-    Structure* singletonStructure() const
-    {
-        ASSERT(m_structures.size() == 1);
-        return m_structures[0];
-    }
-    
-    Structure* at(size_t i) const { return m_structures.at(i); }
-    
-    Structure* operator[](size_t i) const { return at(i); }
-    
-    Structure* last() const { return m_structures.last(); }
-
-    SpeculatedType speculationFromStructures() const
+    StructureSet(Structure* structure)
+        : TinyPtrSet(structure)
     {
-        SpeculatedType result = SpecNone;
-        
-        for (size_t i = 0; i < m_structures.size(); ++i)
-            mergeSpeculation(result, speculationFromStructure(m_structures[i]));
-        
-        return result;
     }
     
-    ArrayModes arrayModesFromStructures() const
+    ALWAYS_INLINE StructureSet(const StructureSet& other)
+        : TinyPtrSet(other)
     {
-        ArrayModes result = 0;
-        
-        for (size_t i = 0; i < m_structures.size(); ++i)
-            mergeArrayModes(result, asArrayModes(m_structures[i]->indexingType()));
-        
-        return result;
     }
     
-    bool operator==(const StructureSet& other) const
+    Structure* onlyStructure() const
     {
-        if (m_structures.size() != other.m_structures.size())
-            return false;
-        
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (!other.contains(m_structures[i]))
-                return false;
-        }
-        
-        return true;
+        return onlyEntry();
     }
     
-    void dumpInContext(PrintStream& out, DumpContext* context) const
-    {
-        CommaPrinter comma;
-        out.print("[");
-        for (size_t i = 0; i < m_structures.size(); ++i)
-            out.print(comma, inContext(*m_structures[i], context));
-        out.print("]");
-    }
+#if ENABLE(DFG_JIT)
+    void filter(const DFG::StructureAbstractValue&);
+    void filter(SpeculatedType);
+    void filterArrayModes(ArrayModes);
+    void filter(const DFG::AbstractValue&);
+#endif // ENABLE(DFG_JIT)
     
-    void dump(PrintStream& out) const
-    {
-        dumpInContext(out, 0);
-    }
+    SpeculatedType speculationFromStructures() const;
+    ArrayModes arrayModesFromStructures() const;
     
-private:
-    friend class DFG::StructureAbstractValue;
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
     
-    Vector<Structure*, 2> m_structures;
+    void validateReferences(const TrackedReferences&) const;
 };
 
 } // namespace JSC
index 9521fec55360bc59591e92a89f8eb62706229910..f08460d65710d335afe9d39edb935b89dbe97ab1 100644 (file)
@@ -38,13 +38,13 @@ StructureStubClearingWatchpoint::~StructureStubClearingWatchpoint() { }
 
 StructureStubClearingWatchpoint* StructureStubClearingWatchpoint::push(
     WatchpointsOnStructureStubInfo& holder,
-    OwnPtr<StructureStubClearingWatchpoint>& head)
+    std::unique_ptr<StructureStubClearingWatchpoint>& head)
 {
-    head = adoptPtr(new StructureStubClearingWatchpoint(holder, head.release()));
+    head = std::make_unique<StructureStubClearingWatchpoint>(holder, WTF::move(head));
     return head.get();
 }
 
-void StructureStubClearingWatchpoint::fireInternal()
+void StructureStubClearingWatchpoint::fireInternal(const FireDetail&)
 {
     // This will implicitly cause my own demise: stub reset removes all watchpoints.
     // That works, because deleting a watchpoint removes it from the set's list, and
index 07a66b6383bd0ecd6f050efe4856d95f83d55c8b..528e3ba2bdd089ffbca829e1ee1edb47b7661382 100644 (file)
@@ -32,8 +32,6 @@
 
 #include <wtf/FastMalloc.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
@@ -55,9 +53,9 @@ public:
     
     StructureStubClearingWatchpoint(
         WatchpointsOnStructureStubInfo& holder,
-        PassOwnPtr<StructureStubClearingWatchpoint> next)
+        std::unique_ptr<StructureStubClearingWatchpoint> next)
         : m_holder(holder)
-        , m_next(next)
+        , m_next(WTF::move(next))
     {
     }
     
@@ -65,14 +63,14 @@ public:
     
     static StructureStubClearingWatchpoint* push(
         WatchpointsOnStructureStubInfo& holder,
-        OwnPtr<StructureStubClearingWatchpoint>& head);
+        std::unique_ptr<StructureStubClearingWatchpoint>& head);
 
 protected:
-    virtual void fireInternal() override;
+    virtual void fireInternal(const FireDetail&) override;
 
 private:
     WatchpointsOnStructureStubInfo& m_holder;
-    OwnPtr<StructureStubClearingWatchpoint> m_next;
+    std::unique_ptr<StructureStubClearingWatchpoint> m_next;
 };
 
 class WatchpointsOnStructureStubInfo : public RefCounted<WatchpointsOnStructureStubInfo> {
@@ -97,7 +95,7 @@ public:
 private:
     CodeBlock* m_codeBlock;
     StructureStubInfo* m_stubInfo;
-    OwnPtr<StructureStubClearingWatchpoint> m_head;
+    std::unique_ptr<StructureStubClearingWatchpoint> m_head;
 };
 
 } // namespace JSC
index 4615a3cc100a883b40b5f20787ff297a03dbacd6..5ea530c8aa6bea90cda9a41cb85c4940b2250d7a 100644 (file)
@@ -49,7 +49,6 @@ void StructureStubInfo::deref()
         return;
     }
     case access_get_by_id_self:
-    case access_get_by_id_chain:
     case access_put_by_id_transition_normal:
     case access_put_by_id_transition_direct:
     case access_put_by_id_replace:
@@ -68,11 +67,6 @@ bool StructureStubInfo::visitWeakReferences(RepatchBuffer& repatchBuffer)
         if (!Heap::isMarked(u.getByIdSelf.baseObjectStructure.get()))
             return false;
         break;
-    case access_get_by_id_chain:
-        if (!Heap::isMarked(u.getByIdChain.baseObjectStructure.get())
-            || !Heap::isMarked(u.getByIdChain.chain.get()))
-            return false;
-        break;
     case access_get_by_id_list: {
         if (!u.getByIdList.list->visitWeak(repatchBuffer))
             return false;
index 008996663c26784714e8250b224714c2edb3095c..d402acee5793bb4f78669517164148e8a7a271c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,7 +36,6 @@
 #include "SpillRegistersMode.h"
 #include "Structure.h"
 #include "StructureStubClearingWatchpoint.h"
-#include <wtf/OwnPtr.h>
 
 namespace JSC {
 
@@ -47,7 +46,6 @@ class PolymorphicPutByIdList;
 
 enum AccessType {
     access_get_by_id_self,
-    access_get_by_id_chain,
     access_get_by_id_list,
     access_put_by_id_transition_normal,
     access_put_by_id_transition_direct,
@@ -61,7 +59,6 @@ inline bool isGetByIdAccess(AccessType accessType)
 {
     switch (accessType) {
     case access_get_by_id_self:
-    case access_get_by_id_chain:
     case access_get_by_id_list:
         return true;
     default:
@@ -97,6 +94,7 @@ struct StructureStubInfo {
         : accessType(access_unset)
         , seen(false)
         , resetByGC(false)
+        , tookSlowPath(false)
     {
     }
 
@@ -107,16 +105,6 @@ struct StructureStubInfo {
         u.getByIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
     }
 
-    void initGetByIdChain(VM& vm, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
-    {
-        accessType = access_get_by_id_chain;
-
-        u.getByIdChain.baseObjectStructure.set(vm, owner, baseObjectStructure);
-        u.getByIdChain.chain.set(vm, owner, chain);
-        u.getByIdChain.count = count;
-        u.getByIdChain.isDirect = isDirect;
-    }
-
     void initGetByIdList(PolymorphicGetByIdList* list)
     {
         accessType = access_get_by_id_list;
@@ -161,8 +149,8 @@ struct StructureStubInfo {
     {
         deref();
         accessType = access_unset;
-        stubRoutine.clear();
-        watchpoints.clear();
+        stubRoutine = nullptr;
+        watchpoints = nullptr;
     }
 
     void deref();
@@ -196,6 +184,7 @@ struct StructureStubInfo {
     int8_t accessType;
     bool seen : 1;
     bool resetByGC : 1;
+    bool tookSlowPath : 1;
 
     CodeOrigin codeOrigin;
 
diff --git a/bytecode/ToThisStatus.cpp b/bytecode/ToThisStatus.cpp
new file mode 100644 (file)
index 0000000..23d1e08
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ToThisStatus.h"
+
+namespace JSC {
+
+ToThisStatus merge(ToThisStatus a, ToThisStatus b)
+{
+    switch (a) {
+    case ToThisOK:
+        return b;
+    case ToThisConflicted:
+        return ToThisConflicted;
+    case ToThisClearedByGC:
+        if (b == ToThisConflicted)
+            return ToThisConflicted;
+        return ToThisClearedByGC;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return ToThisConflicted;
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, ToThisStatus status)
+{
+    switch (status) {
+    case ToThisOK:
+        out.print("OK");
+        return;
+    case ToThisConflicted:
+        out.print("Conflicted");
+        return;
+    case ToThisClearedByGC:
+        out.print("ClearedByGC");
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
diff --git a/bytecode/ToThisStatus.h b/bytecode/ToThisStatus.h
new file mode 100644 (file)
index 0000000..55d707c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ToThisStatus_h
+#define ToThisStatus_h
+
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+enum ToThisStatus {
+    ToThisOK,
+    ToThisConflicted,
+    ToThisClearedByGC
+};
+
+ToThisStatus merge(ToThisStatus, ToThisStatus);
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::ToThisStatus);
+
+} // namespace WTF
+
+#endif // ToThisStatus_h
+
diff --git a/bytecode/TrackedReferences.cpp b/bytecode/TrackedReferences.cpp
new file mode 100644 (file)
index 0000000..d98fa97
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "TrackedReferences.h"
+
+#include "JSCInlines.h"
+#include <wtf/CommaPrinter.h>
+
+namespace JSC {
+
+TrackedReferences::TrackedReferences()
+{
+}
+
+TrackedReferences::~TrackedReferences()
+{
+}
+
+void TrackedReferences::add(JSCell* cell)
+{
+    if (cell)
+        m_references.add(cell);
+}
+
+void TrackedReferences::add(JSValue value)
+{
+    if (value.isCell())
+        add(value.asCell());
+}
+
+void TrackedReferences::check(JSCell* cell) const
+{
+    if (!cell)
+        return;
+    
+    if (m_references.contains(cell))
+        return;
+    
+    dataLog("Found untracked reference: ", RawPointer(cell), "\n");
+    dataLog("All tracked references: ", *this, "\n");
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void TrackedReferences::check(JSValue value) const
+{
+    if (value.isCell())
+        check(value.asCell());
+}
+
+void TrackedReferences::dump(PrintStream& out) const
+{
+    CommaPrinter comma;
+    for (JSCell* cell : m_references)
+        out.print(comma, RawPointer(cell));
+}
+
+} // namespace JSC
+
diff --git a/bytecode/TrackedReferences.h b/bytecode/TrackedReferences.h
new file mode 100644 (file)
index 0000000..cc15e1e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef TrackedReferences_h
+#define TrackedReferences_h
+
+#include "JSCJSValue.h"
+#include "JSCell.h"
+#include <wtf/HashSet.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class TrackedReferences {
+public:
+    TrackedReferences();
+    ~TrackedReferences();
+    
+    void add(JSCell*);
+    void add(JSValue);
+    
+    void check(JSCell*) const;
+    void check(JSValue) const;
+    
+    void dump(PrintStream&) const;
+    
+private:
+    HashSet<JSCell*> m_references;
+};
+
+} // namespace JSC
+
+#endif // TrackedReferences_h
+
diff --git a/bytecode/TypeLocation.h b/bytecode/TypeLocation.h
new file mode 100644 (file)
index 0000000..ec07656
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeLocation_h
+#define TypeLocation_h
+
+#include "TypeSet.h"
+
+namespace JSC {
+
+enum TypeProfilerGlobalIDFlags {
+    TypeProfilerNeedsUniqueIDGeneration = -1,
+    TypeProfilerNoGlobalIDExists = -2,
+    TypeProfilerReturnStatement = -3
+};
+
+typedef intptr_t GlobalVariableID;
+
+class TypeLocation {
+public:
+    TypeLocation()
+        : m_lastSeenType(TypeNothing)
+        , m_divotForFunctionOffsetIfReturnStatement(UINT_MAX)
+        , m_instructionTypeSet(TypeSet::create())
+        , m_globalTypeSet(nullptr)
+    {
+    }
+
+    GlobalVariableID m_globalVariableID;
+    RuntimeType m_lastSeenType;
+    intptr_t m_sourceID;
+    unsigned m_divotStart;
+    unsigned m_divotEnd;
+    unsigned m_divotForFunctionOffsetIfReturnStatement;
+    RefPtr<TypeSet> m_instructionTypeSet;
+    RefPtr<TypeSet> m_globalTypeSet;
+};
+
+} //namespace JSC
+
+#endif //TypeLocation_h
index 5c2cc5f2c325209a07ab0b4bc062f3329693c17c..e262bc54f09f8c2e07abe3b8d71af489d2efeb38 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
 #include "ClassInfo.h"
 #include "CodeCache.h"
 #include "Executable.h"
+#include "FunctionOverrides.h"
 #include "JSString.h"
 #include "JSCInlines.h"
 #include "Parser.h"
 
 namespace JSC {
 
-const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", 0, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) };
-const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) };
-const ClassInfo UnlinkedGlobalCodeBlock::s_info = { "UnlinkedGlobalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedGlobalCodeBlock) };
-const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedProgramCodeBlock) };
-const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
-const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
+static_assert(sizeof(UnlinkedFunctionExecutable) <= 128, "UnlinkedFunctionExecutable should fit in a 128-byte cell.");
 
-static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, UnlinkedFunctionKind functionKind, bool bodyIncludesBraces, ParserError& error)
-{
-    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->toStrictness(), JSParseFunctionCode, error, 0, bodyIncludesBraces);
+const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) };
+const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) };
+const ClassInfo UnlinkedGlobalCodeBlock::s_info = { "UnlinkedGlobalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedGlobalCodeBlock) };
+const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedProgramCodeBlock) };
+const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
+const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
 
-    if (!body) {
-        ASSERT(error.m_type != ParserError::ErrorNone);
-        return 0;
+static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(
+    VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source,
+    CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode,
+    UnlinkedFunctionKind functionKind, ParserError& error)
+{
+    JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin;
+    JSParserStrictMode strictMode = executable->isInStrictContext() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
+    std::unique_ptr<FunctionNode> function = parse<FunctionNode>(
+        &vm, source, executable->parameters(), executable->name(), builtinMode,
+        strictMode, JSParserCodeType::Function, error, 0);
+
+    if (!function) {
+        ASSERT(error.isValid());
+        return nullptr;
     }
 
-    if (executable->forceUsesArguments())
-        body->setUsesArguments();
-    body->finishParsing(executable->parameters(), executable->name(), executable->functionMode());
-    executable->recordParse(body->features(), body->hasCapturedVariables());
+    function->finishParsing(executable->parameters(), executable->name(), executable->functionMode());
+    executable->recordParse(function->features(), function->hasCapturedVariables());
     
-    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction));
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, body.get(), result, debuggerMode, profilerMode)));
+    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode,
+        ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind()));
+    auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode));
     error = generator->generate();
-    body->destroyData();
-    if (error.m_type != ParserError::ErrorNone)
-        return 0;
+    if (error.isValid())
+        return nullptr;
     return result;
 }
 
-unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
-{
-    unsigned numberOfConstants = numberOfConstantRegisters();
-    for (unsigned i = 0; i < numberOfConstants; ++i) {
-        if (getConstant(FirstConstantRegisterIndex + i) == v)
-            return i;
-    }
-    return addConstant(v);
-}
-
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind kind)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode* node, UnlinkedFunctionKind kind)
     : Base(*vm, structure)
-    , m_numCapturedVariables(node->capturedVariableCount())
-    , m_forceUsesArguments(node->usesArguments())
-    , m_isInStrictContext(node->isStrictMode())
-    , m_hasCapturedVariables(node->hasCapturedVariables())
-    , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
     , m_name(node->ident())
     , m_inferredName(node->inferredName())
     , m_parameters(node->parameters())
+    , m_sourceOverride(WTF::move(sourceOverride))
     , m_firstLineOffset(node->firstLine() - source.firstLine())
     , m_lineCount(node->lastLine() - node->firstLine())
     , m_unlinkedFunctionNameStart(node->functionNameStart() - source.startOffset())
@@ -99,9 +93,17 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* struct
     , m_unlinkedBodyEndColumn(m_lineCount ? node->endColumn() : node->endColumn() - node->startColumn())
     , m_startOffset(node->source().startOffset() - source.startOffset())
     , m_sourceLength(node->source().length())
-    , m_features(node->features())
+    , m_parametersStartOffset(node->parametersStart())
+    , m_typeProfilingStartOffset(node->functionKeywordStart())
+    , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
+    , m_features(0)
+    , m_isInStrictContext(node->isInStrictContext())
+    , m_hasCapturedVariables(false)
+    , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
+    , m_constructorKind(static_cast<unsigned>(node->constructorKind()))
     , m_functionMode(node->functionMode())
 {
+    ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind()));
 }
 
 size_t UnlinkedFunctionExecutable::parameterCount() const
@@ -113,8 +115,6 @@ void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visito
 {
     UnlinkedFunctionExecutable* thisObject = jsCast<UnlinkedFunctionExecutable*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_codeBlockForCall);
     visitor.append(&thisObject->m_codeBlockForConstruct);
@@ -123,36 +123,72 @@ void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visito
     visitor.append(&thisObject->m_symbolTableForConstruct);
 }
 
-FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& source, size_t lineOffset)
+FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& ownerSource, int overrideLineNumber)
 {
-    unsigned firstLine = lineOffset + m_firstLineOffset;
+    SourceCode source = m_sourceOverride ? SourceCode(m_sourceOverride) : ownerSource;
+    unsigned firstLine = source.firstLine() + m_firstLineOffset;
+    unsigned startOffset = source.startOffset() + m_startOffset;
+    unsigned lineCount = m_lineCount;
+
+    // Adjust to one-based indexing.
     bool startColumnIsOnFirstSourceLine = !m_firstLineOffset;
     unsigned startColumn = m_unlinkedBodyStartColumn + (startColumnIsOnFirstSourceLine ? source.startColumn() : 1);
-    bool endColumnIsOnStartLine = !m_lineCount;
+    bool endColumnIsOnStartLine = !lineCount;
     unsigned endColumn = m_unlinkedBodyEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
-    SourceCode code(source.provider(), m_startOffset, m_startOffset + m_sourceLength, firstLine, startColumn);
-    return FunctionExecutable::create(vm, code, this, firstLine, firstLine + m_lineCount, startColumn, endColumn);
+
+    SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
+    FunctionOverrides::OverrideInfo overrideInfo;
+    bool hasFunctionOverride = false;
+
+    if (UNLIKELY(Options::functionOverrides())) {
+        hasFunctionOverride = FunctionOverrides::initializeOverrideFor(code, overrideInfo);
+        if (hasFunctionOverride) {
+            firstLine = overrideInfo.firstLine;
+            lineCount = overrideInfo.lineCount;
+            startColumn = overrideInfo.startColumn;
+            endColumn = overrideInfo.endColumn;
+            code = overrideInfo.sourceCode;
+        }
+    }
+
+    FunctionExecutable* result = FunctionExecutable::create(vm, code, this, firstLine, firstLine + lineCount, startColumn, endColumn);
+    if (overrideLineNumber != -1)
+        result->setOverrideLineNumber(overrideLineNumber);
+
+    if (UNLIKELY(hasFunctionOverride)) {
+        result->overrideParameterAndTypeProfilingStartEndOffsets(
+            overrideInfo.parametersStartOffset,
+            overrideInfo.typeProfilingStartOffset,
+            overrideInfo.typeProfilingEndOffset);
+    }
+
+    return result;
 }
 
-UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger*, const SourceCode& source, JSObject** exception)
+UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(
+    const Identifier& name, ExecState& exec, const SourceCode& source, 
+    JSObject*& exception, int overrideLineNumber)
 {
     ParserError error;
-    VM& vm = exec->vm();
+    VM& vm = exec.vm();
     CodeCache* codeCache = vm.codeCache();
     UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);
 
-    if (exec->lexicalGlobalObject()->hasDebugger())
-        exec->lexicalGlobalObject()->debugger()->sourceParsed(exec, source.provider(), error.m_line, error.m_message);
+    auto& globalObject = *exec.lexicalGlobalObject();
+    if (globalObject.hasDebugger())
+        globalObject.debugger()->sourceParsed(&exec, source.provider(), error.line(), error.message());
 
-    if (error.m_type != ParserError::ErrorNone) {
-        *exception = error.toErrorObject(exec->lexicalGlobalObject(), source);
-        return 0;
+    if (error.isValid()) {
+        exception = error.toErrorObject(&globalObject, source, overrideLineNumber);
+        return nullptr;
     }
 
     return executable;
 }
 
-UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, bool bodyIncludesBraces, ParserError& error)
+UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(
+    VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, 
+    DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
     switch (specializationKind) {
     case CodeForCall:
@@ -165,10 +201,13 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, cons
         break;
     }
 
-    UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, this, source, specializationKind, debuggerMode, profilerMode, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, bodyIncludesBraces, error);
+    UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(
+        vm, this, source, specializationKind, debuggerMode, profilerMode, 
+        isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, 
+        error);
     
-    if (error.m_type != ParserError::ErrorNone)
-        return 0;
+    if (error.isValid())
+        return nullptr;
 
     switch (specializationKind) {
     case CodeForCall:
@@ -183,33 +222,20 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, cons
     return result;
 }
 
-String UnlinkedFunctionExecutable::paramString() const
-{
-    FunctionParameters& parameters = *m_parameters;
-    StringBuilder builder;
-    for (size_t pos = 0; pos < parameters.size(); ++pos) {
-        if (!builder.isEmpty())
-            builder.appendLiteral(", ");
-        parameters.at(pos)->toString(builder);
-    }
-    return builder.toString();
-}
-
 UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
     : Base(*vm, structure)
     , m_numVars(0)
     , m_numCalleeRegisters(0)
     , m_numParameters(0)
     , m_vm(vm)
-    , m_argumentsRegister(VirtualRegister())
     , m_globalObjectRegister(VirtualRegister())
-    , m_needsFullScopeChain(info.m_needsActivation)
-    , m_usesEval(info.m_usesEval)
-    , m_isNumericCompareFunction(false)
-    , m_isStrictMode(info.m_isStrictMode)
-    , m_isConstructor(info.m_isConstructor)
+    , m_needsFullScopeChain(info.needsActivation())
+    , m_usesEval(info.usesEval())
+    , m_isStrictMode(info.isStrictMode())
+    , m_isConstructor(info.isConstructor())
     , m_hasCapturedVariables(false)
-    , m_isBuiltinFunction(info.m_isBuiltinFunction)
+    , m_isBuiltinFunction(info.isBuiltinFunction())
+    , m_constructorKind(static_cast<unsigned>(info.constructorKind()))
     , m_firstLine(0)
     , m_lineCount(0)
     , m_endColumn(UINT_MAX)
@@ -224,15 +250,15 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code
     , m_bytecodeCommentIterator(0)
 #endif
 {
-
+    for (auto& constantRegisterIndex : m_linkTimeConstants)
+        constantRegisterIndex = 0;
+    ASSERT(m_constructorKind == static_cast<unsigned>(info.constructorKind()));
 }
 
 void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     UnlinkedCodeBlock* thisObject = jsCast<UnlinkedCodeBlock*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_symbolTable);
     for (FunctionExpressionVector::iterator ptr = thisObject->m_functionDecls.begin(), end = thisObject->m_functionDecls.end(); ptr != end; ++ptr)
@@ -404,15 +430,37 @@ void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
     m_expressionInfo.append(info);
 }
 
+bool UnlinkedCodeBlock::typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot)
+{
+    static const bool verbose = false;
+    auto iter = m_typeProfilerInfoMap.find(bytecodeOffset);
+    if (iter == m_typeProfilerInfoMap.end()) {
+        if (verbose)
+            dataLogF("Don't have assignment info for offset:%u\n", bytecodeOffset);
+        startDivot = UINT_MAX;
+        endDivot = UINT_MAX;
+        return false;
+    }
+    
+    TypeProfilerExpressionRange& range = iter->value;
+    startDivot = range.m_startDivot;
+    endDivot = range.m_endDivot;
+    return true;
+}
+
+void UnlinkedCodeBlock::addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
+{
+    TypeProfilerExpressionRange range;
+    range.m_startDivot = startDivot;
+    range.m_endDivot = endDivot;
+    m_typeProfilerInfoMap.set(instructionOffset, range);  
+}
+
 void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     UnlinkedProgramCodeBlock* thisObject = jsCast<UnlinkedProgramCodeBlock*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
-    for (size_t i = 0, end = thisObject->m_functionDeclarations.size(); i != end; i++)
-        visitor.append(&thisObject->m_functionDeclarations[i].second);
 }
 
 UnlinkedCodeBlock::~UnlinkedCodeBlock()
index 38e793d4c23e7b9f0956679814d1ca62c0d5e96f..790442421c779c5935bf72f7619163a4a487d29e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
 #include "CodeSpecializationKind.h"
 #include "CodeType.h"
 #include "ExpressionRangeInfo.h"
+#include "HandlerInfo.h"
 #include "Identifier.h"
 #include "JSCell.h"
 #include "JSString.h"
@@ -39,7 +40,6 @@
 #include "SymbolTable.h"
 #include "VirtualRegister.h"
 
-#include <wtf/Compression.h>
 #include <wtf/RefCountedArray.h>
 #include <wtf/Vector.h>
 
@@ -50,7 +50,7 @@ class FunctionBodyNode;
 class FunctionExecutable;
 class FunctionParameters;
 class JSScope;
-struct ParserError;
+class ParserError;
 class ScriptExecutable;
 class SourceCode;
 class SourceProvider;
@@ -66,19 +66,31 @@ typedef unsigned UnlinkedObjectAllocationProfile;
 typedef unsigned UnlinkedLLIntCallLinkInfo;
 
 struct ExecutableInfo {
-    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction)
+    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind)
         : m_needsActivation(needsActivation)
         , m_usesEval(usesEval)
         , m_isStrictMode(isStrictMode)
         , m_isConstructor(isConstructor)
         , m_isBuiltinFunction(isBuiltinFunction)
+        , m_constructorKind(static_cast<unsigned>(constructorKind))
     {
+        ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
     }
-    bool m_needsActivation : 1;
-    bool m_usesEval : 1;
-    bool m_isStrictMode : 1;
-    bool m_isConstructor : 1;
-    bool m_isBuiltinFunction : 1;
+
+    bool needsActivation() const { return m_needsActivation; }
+    bool usesEval() const { return m_usesEval; }
+    bool isStrictMode() const { return m_isStrictMode; }
+    bool isConstructor() const { return m_isConstructor; }
+    bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
+
+private:
+    unsigned m_needsActivation : 1;
+    unsigned m_usesEval : 1;
+    unsigned m_isStrictMode : 1;
+    unsigned m_isConstructor : 1;
+    unsigned m_isBuiltinFunction : 1;
+    unsigned m_constructorKind : 2;
 };
 
 enum UnlinkedFunctionKind {
@@ -86,15 +98,19 @@ enum UnlinkedFunctionKind {
     UnlinkedBuiltinFunction,
 };
 
-class UnlinkedFunctionExecutable : public JSCell {
+class UnlinkedFunctionExecutable final : public JSCell {
 public:
     friend class BuiltinExecutables;
     friend class CodeCache;
     friend class VM;
+
     typedef JSCell Base;
-    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind)
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     {
-        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind);
+        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
+            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind);
         instance->finishCreation(*vm);
         return instance;
     }
@@ -108,31 +124,27 @@ public:
     }
     size_t parameterCount() const;
     bool isInStrictContext() const { return m_isInStrictContext; }
-    FunctionMode functionMode() const { return m_functionMode; }
-    JSParserStrictness toStrictness() const
-    {
-        if (m_isBuiltinFunction)
-            return JSParseBuiltin;
-        if (m_isInStrictContext)
-            return JSParseStrict;
-        return JSParseNormal;
-    }
+    FunctionMode functionMode() const { return static_cast<FunctionMode>(m_functionMode); }
+    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
 
-    unsigned firstLineOffset() const { return m_firstLineOffset; }
-    unsigned lineCount() const { return m_lineCount; }
     unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
     unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
     unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
     unsigned startOffset() const { return m_startOffset; }
     unsigned sourceLength() { return m_sourceLength; }
+    unsigned parametersStartOffset() const { return m_parametersStartOffset; }
+    unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
+    unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
 
-    String paramString() const;
-
-    UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, bool bodyIncludesBraces, ParserError&);
+    UnlinkedFunctionCodeBlock* codeBlockFor(
+        VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, 
+        ParserError&);
 
-    static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+    static UnlinkedFunctionExecutable* fromGlobalCode(
+        const Identifier&, ExecState&, const SourceCode&, JSObject*& exception, 
+        int overrideLineNumber);
 
-    FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset);
+    FunctionExecutable* link(VM&, const SourceCode&, int overrideLineNumber = -1);
 
     void clearCodeForRecompilation()
     {
@@ -150,34 +162,27 @@ public:
         m_hasCapturedVariables = hasCapturedVariables;
     }
 
-    bool forceUsesArguments() const { return m_forceUsesArguments; }
-
     CodeFeatures features() const { return m_features; }
     bool hasCapturedVariables() const { return m_hasCapturedVariables; }
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+    bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
 
 private:
-    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);
+    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind);
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
 
-    unsigned m_numCapturedVariables : 29;
-    bool m_forceUsesArguments : 1;
-    bool m_isInStrictContext : 1;
-    bool m_hasCapturedVariables : 1;
-    bool m_isBuiltinFunction : 1;
-
     Identifier m_name;
     Identifier m_inferredName;
     WriteBarrier<JSString> m_nameValue;
     WriteBarrier<SymbolTable> m_symbolTableForCall;
     WriteBarrier<SymbolTable> m_symbolTableForConstruct;
     RefPtr<FunctionParameters> m_parameters;
+    RefPtr<SourceProvider> m_sourceOverride;
     unsigned m_firstLineOffset;
     unsigned m_lineCount;
     unsigned m_unlinkedFunctionNameStart;
@@ -185,10 +190,17 @@ private:
     unsigned m_unlinkedBodyEndColumn;
     unsigned m_startOffset;
     unsigned m_sourceLength;
+    unsigned m_parametersStartOffset;
+    unsigned m_typeProfilingStartOffset;
+    unsigned m_typeProfilingEndOffset;
 
     CodeFeatures m_features;
 
-    FunctionMode m_functionMode;
+    unsigned m_isInStrictContext : 1;
+    unsigned m_hasCapturedVariables : 1;
+    unsigned m_isBuiltinFunction : 1;
+    unsigned m_constructorKind : 2;
+    unsigned m_functionMode : 1; // FunctionMode
 
 protected:
     void finishCreation(VM& vm)
@@ -205,8 +217,6 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | JSCell::StructureFlags;
-
     DECLARE_EXPORT_INFO;
 };
 
@@ -237,13 +247,6 @@ struct UnlinkedSimpleJumpTable {
     }
 };
 
-struct UnlinkedHandlerInfo {
-    uint32_t start;
-    uint32_t end;
-    uint32_t target;
-    uint32_t scopeDepth;
-};
-
 struct UnlinkedInstruction {
     UnlinkedInstruction() { u.operand = 0; }
     UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
@@ -258,8 +261,9 @@ struct UnlinkedInstruction {
 class UnlinkedCodeBlock : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
 
     enum { CallFunction, ApplyFunction };
 
@@ -272,16 +276,14 @@ public:
     void addExpressionInfo(unsigned instructionOffset, int divot,
         int startOffset, int endOffset, unsigned line, unsigned column);
 
+    void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot);
+
     bool hasExpressionInfo() { return m_expressionInfo.size(); }
 
     // Special registers
     void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
-    void setActivationRegister(VirtualRegister activationRegister) { m_activationRegister = activationRegister; }
-
-    void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
-    bool usesArguments() const { return m_argumentsRegister.isValid(); }
-    VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
-
+    void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
+    void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
 
     bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
     void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
@@ -314,19 +316,35 @@ public:
     const Identifier& identifier(int index) const { return m_identifiers[index]; }
     const Vector<Identifier>& identifiers() const { return m_identifiers; }
 
-    size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
-    unsigned addConstant(JSValue v)
+    unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
     {
         unsigned result = m_constantRegisters.size();
         m_constantRegisters.append(WriteBarrier<Unknown>());
         m_constantRegisters.last().set(*m_vm, this, v);
+        m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation);
+        return result;
+    }
+    unsigned addConstant(LinkTimeConstant type)
+    {
+        unsigned result = m_constantRegisters.size();
+        ASSERT(result);
+        unsigned index = static_cast<unsigned>(type);
+        ASSERT(index < LinkTimeConstantCount);
+        m_linkTimeConstants[index] = result;
+        m_constantRegisters.append(WriteBarrier<Unknown>());
+        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
         return result;
     }
-    unsigned addOrFindConstant(JSValue);
+    unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type)
+    {
+        unsigned index = static_cast<unsigned>(type);
+        ASSERT(index < LinkTimeConstantCount);
+        return m_linkTimeConstants[index];
+    }
     const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
     const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
     ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
-    ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
+    const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
 
     // Jumps
     size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
@@ -334,16 +352,16 @@ public:
     unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
     unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
 
-    void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
-    bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
-
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
-    
+
+    ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
+
     void shrinkToFit()
     {
         m_jumpTargets.shrinkToFit();
         m_identifiers.shrinkToFit();
         m_constantRegisters.shrinkToFit();
+        m_constantsSourceCodeRepresentation.shrinkToFit();
         m_functionDecls.shrinkToFit();
         m_functionExprs.shrinkToFit();
         m_propertyAccessInstructions.shrinkToFit();
@@ -400,7 +418,7 @@ public:
 
     // Exception handling support
     size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
-    void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
+    void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); }
     UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
 
     SymbolTable* symbolTable() const { return m_symbolTable.get(); }
@@ -423,8 +441,9 @@ public:
     CodeType codeType() const { return m_codeType; }
 
     VirtualRegister thisRegister() const { return m_thisRegister; }
-    VirtualRegister activationRegister() const { return m_activationRegister; }
-    bool hasActivationRegister() const { return m_activationRegister.isValid(); }
+    VirtualRegister scopeRegister() const { return m_scopeRegister; }
+    VirtualRegister activationRegister() const { return m_lexicalEnvironmentRegister; }
+    bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); }
 
     void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
     {
@@ -457,13 +476,15 @@ public:
         return m_rareData->m_constantBuffers[index];
     }
 
-    bool hasRareData() const { return m_rareData; }
+    bool hasRareData() const { return m_rareData.get(); }
 
     int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
 
     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
         int& startOffset, int& endOffset, unsigned& line, unsigned& column);
 
+    bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot);
+
     void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
     {
         m_features = features;
@@ -481,6 +502,9 @@ public:
     ALWAYS_INLINE unsigned startColumn() const { return 0; }
     unsigned endColumn() const { return m_endColumn; }
 
+    void addOpProfileControlFlowBytecodeOffset(size_t offset) { m_opProfileControlFlowBytecodeOffsets.append(offset); }
+    const Vector<size_t>& opProfileControlFlowBytecodeOffsets() const { return m_opProfileControlFlowBytecodeOffsets; }
+
     void dumpExpressionRangeInfo(); // For debugging purpose only.
 
 protected:
@@ -500,7 +524,7 @@ private:
     void createRareDataIfNecessary()
     {
         if (!m_rareData)
-            m_rareData = adoptPtr(new RareData);
+            m_rareData = std::make_unique<RareData>();
     }
 
     void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column);
@@ -511,17 +535,18 @@ private:
     VM* m_vm;
 
     VirtualRegister m_thisRegister;
-    VirtualRegister m_argumentsRegister;
-    VirtualRegister m_activationRegister;
+    VirtualRegister m_scopeRegister;
+    VirtualRegister m_lexicalEnvironmentRegister;
     VirtualRegister m_globalObjectRegister;
 
-    bool m_needsFullScopeChain : 1;
-    bool m_usesEval : 1;
-    bool m_isNumericCompareFunction : 1;
-    bool m_isStrictMode : 1;
-    bool m_isConstructor : 1;
-    bool m_hasCapturedVariables : 1;
-    bool m_isBuiltinFunction : 1;
+    unsigned m_needsFullScopeChain : 1;
+    unsigned m_usesEval : 1;
+    unsigned m_isStrictMode : 1;
+    unsigned m_isConstructor : 1;
+    unsigned m_hasCapturedVariables : 1;
+    unsigned m_isBuiltinFunction : 1;
+    unsigned m_constructorKind : 2;
+
     unsigned m_firstLine;
     unsigned m_lineCount;
     unsigned m_endColumn;
@@ -534,6 +559,8 @@ private:
     // Constant Pools
     Vector<Identifier> m_identifiers;
     Vector<WriteBarrier<Unknown>> m_constantRegisters;
+    Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
+    std::array<unsigned, LinkTimeConstantCount> m_linkTimeConstants;
     typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
     FunctionExpressionVector m_functionDecls;
     FunctionExpressionVector m_functionExprs;
@@ -573,12 +600,16 @@ public:
     };
 
 private:
-    OwnPtr<RareData> m_rareData;
+    std::unique_ptr<RareData> m_rareData;
     Vector<ExpressionRangeInfo> m_expressionInfo;
+    struct TypeProfilerExpressionRange {
+        unsigned m_startDivot;
+        unsigned m_endDivot;
+    };
+    HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap;
+    Vector<size_t> m_opProfileControlFlowBytecodeOffsets;
 
 protected:
-
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | Base::StructureFlags;
     static void visitChildren(JSCell*, SlotVisitor&);
 
 public:
@@ -595,12 +626,10 @@ protected:
     {
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     DECLARE_INFO;
 };
 
-class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
+class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock {
 private:
     friend class CodeCache;
     static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
@@ -612,12 +641,9 @@ private:
 
 public:
     typedef UnlinkedGlobalCodeBlock Base;
-    static void destroy(JSCell*);
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-    void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
-    {
-        m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
-    }
+    static void destroy(JSCell*);
 
     void addVariableDeclaration(const Identifier& name, bool isConstant)
     {
@@ -625,10 +651,8 @@ public:
     }
 
     typedef Vector<std::pair<Identifier, bool>> VariableDeclations;
-    typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;
 
     const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
-    const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -639,7 +663,6 @@ private:
     }
 
     VariableDeclations m_varDeclarations;
-    FunctionDeclations m_functionDeclarations;
 
 public:
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
@@ -647,12 +670,10 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info());
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     DECLARE_INFO;
 };
 
-class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
+class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock {
 private:
     friend class CodeCache;
 
@@ -665,6 +686,8 @@ private:
 
 public:
     typedef UnlinkedGlobalCodeBlock Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static void destroy(JSCell*);
 
     const Identifier& variable(unsigned index) { return m_variables[index]; }
@@ -689,13 +712,14 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info());
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     DECLARE_INFO;
 };
 
-class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
+class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock {
 public:
+    typedef UnlinkedCodeBlock Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
     {
         UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
@@ -703,7 +727,6 @@ public:
         return instance;
     }
 
-    typedef UnlinkedCodeBlock Base;
     static void destroy(JSCell*);
 
 private:
@@ -718,8 +741,6 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     DECLARE_INFO;
 };
 
index 2e952a41d06da4eba1dbecaa598b38d715b04b1e..568dbb6820d90c698f84120619317e4823a2d145 100644 (file)
@@ -75,7 +75,7 @@ static void append32(unsigned char*& ptr, unsigned value)
     *(ptr++) = (value >> 24) & 0xff;
 }
 
-UnlinkedInstructionStream::UnlinkedInstructionStream(const Vector<UnlinkedInstruction>& instructions)
+UnlinkedInstructionStream::UnlinkedInstructionStream(const Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions)
     : m_instructionCount(instructions.size())
 {
     Vector<unsigned char> buffer;
index 6649eca593a3ff59c5711114e76bbfc188d6ca00..6323c444bedfaf9ec5586bd2c54da1b56724910a 100644 (file)
@@ -35,7 +35,7 @@ namespace JSC {
 class UnlinkedInstructionStream {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit UnlinkedInstructionStream(const Vector<UnlinkedInstruction>&);
+    explicit UnlinkedInstructionStream(const Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>&);
 
     unsigned count() const { return m_instructionCount; }
 
index b7de34b93b13f2ae65f4329927b71a2b6c8ec35b..996fd3bfe64334a5830bc928e364a35230ad2e78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -92,28 +92,31 @@ void ValueRecovery::dumpInContext(PrintStream& out, DumpContext* context) const
         return;
 #endif
     case DisplacedInJSStack:
-        out.printf("*%d", virtualRegister().offset());
+        out.print("*", virtualRegister());
         return;
     case Int32DisplacedInJSStack:
-        out.printf("*int32(%d)", virtualRegister().offset());
+        out.print("*int32(", virtualRegister(), ")");
         return;
     case Int52DisplacedInJSStack:
-        out.printf("*int52(%d)", virtualRegister().offset());
+        out.print("*int52(", virtualRegister(), ")");
         return;
     case StrictInt52DisplacedInJSStack:
-        out.printf("*strictInt52(%d)", virtualRegister().offset());
+        out.print("*strictInt52(", virtualRegister(), ")");
         return;
     case DoubleDisplacedInJSStack:
-        out.printf("*double(%d)", virtualRegister().offset());
+        out.print("*double(", virtualRegister(), ")");
         return;
     case CellDisplacedInJSStack:
-        out.printf("*cell(%d)", virtualRegister().offset());
+        out.print("*cell(", virtualRegister(), ")");
         return;
     case BooleanDisplacedInJSStack:
-        out.printf("*bool(%d)", virtualRegister().offset());
+        out.print("*bool(", virtualRegister(), ")");
         return;
-    case ArgumentsThatWereNotCreated:
-        out.printf("arguments");
+    case DirectArgumentsThatWereNotCreated:
+        out.print("DirectArguments(", nodeID(), ")");
+        return;
+    case ClonedArgumentsThatWereNotCreated:
+        out.print("ClonedArguments(", nodeID(), ")");
         return;
     case Constant:
         out.print("[", inContext(constant(), context), "]");
index c30b97af297ac5f1025bb6cb08aec558b5f41a95..42651e2c7ee3901bc3eca01e3312eece122dd8d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #ifndef ValueRecovery_h
 #define ValueRecovery_h
 
+#include "DFGMinifiedID.h"
 #include "DataFormat.h"
 #if ENABLE(JIT)
 #include "GPRInfo.h"
@@ -38,6 +39,7 @@
 namespace JSC {
 
 struct DumpContext;
+struct InlineCallFrame;
 
 // Describes how to recover a given bytecode virtual register at a given
 // code point.
@@ -62,8 +64,9 @@ enum ValueRecoveryTechnique {
     DoubleDisplacedInJSStack,
     CellDisplacedInJSStack,
     BooleanDisplacedInJSStack,
-    // It's an Arguments object.
-    ArgumentsThatWereNotCreated,
+    // It's an Arguments object. This arises because of the simplified arguments simplification done by the DFG.
+    DirectArgumentsThatWereNotCreated,
+    ClonedArgumentsThatWereNotCreated,
     // It's a constant.
     Constant,
     // Don't know how to recover it.
@@ -167,10 +170,19 @@ public:
         return result;
     }
     
-    static ValueRecovery argumentsThatWereNotCreated()
+    static ValueRecovery directArgumentsThatWereNotCreated(DFG::MinifiedID id)
     {
         ValueRecovery result;
-        result.m_technique = ArgumentsThatWereNotCreated;
+        result.m_technique = DirectArgumentsThatWereNotCreated;
+        result.m_source.nodeID = id.bits();
+        return result;
+    }
+    
+    static ValueRecovery outOfBandArgumentsThatWereNotCreated(DFG::MinifiedID id)
+    {
+        ValueRecovery result;
+        result.m_technique = ClonedArgumentsThatWereNotCreated;
+        result.m_source.nodeID = id.bits();
         return result;
     }
     
@@ -256,6 +268,12 @@ public:
         return JSValue::decode(m_source.constant);
     }
     
+    DFG::MinifiedID nodeID() const
+    {
+        ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
+        return DFG::MinifiedID::fromBits(m_source.nodeID);
+    }
+    
     JSValue recover(ExecState*) const;
     
 #if ENABLE(JIT)
@@ -276,6 +294,7 @@ private:
 #endif
         int virtualReg;
         EncodedJSValue constant;
+        uintptr_t nodeID;
     } m_source;
 };
 
diff --git a/bytecode/VariableWatchpointSet.h b/bytecode/VariableWatchpointSet.h
deleted file mode 100644 (file)
index 34cefa0..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef VariableWatchpointSet_h
-#define VariableWatchpointSet_h
-
-#include "Watchpoint.h"
-#include "WriteBarrier.h"
-
-namespace JSC {
-
-class SymbolTable;
-
-class VariableWatchpointSet : public WatchpointSet {
-    friend class LLIntOffsetsExtractor;
-public:
-    VariableWatchpointSet(SymbolTable& symbolTable)
-        : WatchpointSet(ClearWatchpoint)
-        , m_symbolTable(symbolTable)
-    {
-    }
-    
-    ~VariableWatchpointSet() { }
-    
-    // For the purpose of deciding whether or not to watch this variable, you only need
-    // to inspect inferredValue(). If this returns something other than the empty
-    // value, then it means that at all future safepoints, this watchpoint set will be
-    // in one of these states:
-    //
-    //    IsWatched: in this case, the variable's value must still be the
-    //        inferredValue.
-    //
-    //    IsInvalidated: in this case the variable's value may be anything but you'll
-    //        either notice that it's invalidated and not install the watchpoint, or
-    //        you will have been notified that the watchpoint was fired.
-    JSValue inferredValue() const { return m_inferredValue.get(); }
-    
-    inline void notifyWrite(VM&, JSValue);
-    
-    void invalidate()
-    {
-        m_inferredValue.clear();
-        WatchpointSet::invalidate();
-    }
-    
-    void finalizeUnconditionally()
-    {
-        ASSERT(!!m_inferredValue == (state() == IsWatched));
-        if (!m_inferredValue)
-            return;
-        JSValue inferredValue = m_inferredValue.get();
-        if (!inferredValue.isCell())
-            return;
-        JSCell* cell = inferredValue.asCell();
-        if (Heap::isMarked(cell))
-            return;
-        invalidate();
-    }
-
-    WriteBarrier<Unknown>* addressOfInferredValue() { return &m_inferredValue; }
-    
-private:
-    SymbolTable& m_symbolTable;
-    WriteBarrier<Unknown> m_inferredValue;
-};
-
-} // namespace JSC
-
-#endif // VariableWatchpointSet_h
-
diff --git a/bytecode/VariableWatchpointSetInlines.h b/bytecode/VariableWatchpointSetInlines.h
deleted file mode 100644 (file)
index 7b3c569..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef VariableWatchpointSetInlines_h
-#define VariableWatchpointSetInlines_h
-
-#include "SymbolTable.h"
-#include "VariableWatchpointSet.h"
-
-namespace JSC {
-
-inline void VariableWatchpointSet::notifyWrite(VM& vm, JSValue value)
-{
-    ASSERT(!!value);
-    switch (state()) {
-    case ClearWatchpoint:
-        m_inferredValue.set(vm, &m_symbolTable, value);
-        startWatching();
-        return;
-
-    case IsWatched:
-        ASSERT(!!m_inferredValue);
-        if (value == m_inferredValue.get())
-            return;
-        invalidate();
-        return;
-            
-    case IsInvalidated:
-        ASSERT(!m_inferredValue);
-        return;
-    }
-        
-    ASSERT_NOT_REACHED();
-}
-    
-} // namespace JSC
-
-#endif // VariableWatchpointSetInlines_h
diff --git a/bytecode/VariableWriteFireDetail.cpp b/bytecode/VariableWriteFireDetail.cpp
new file mode 100644 (file)
index 0000000..b483ab2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "VariableWriteFireDetail.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+void VariableWriteFireDetail::dump(PrintStream& out) const
+{
+    out.print("Write to ", m_name, " in ", JSValue(m_object));
+}
+
+void VariableWriteFireDetail::touch(WatchpointSet* set, JSObject* object, const PropertyName& name)
+{
+    set->touch(VariableWriteFireDetail(object, name));
+}
+
+} // namespace JSC
+
diff --git a/bytecode/VariableWriteFireDetail.h b/bytecode/VariableWriteFireDetail.h
new file mode 100644 (file)
index 0000000..664f69c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef VariableWriteFireDetail_h
+#define VariableWriteFireDetail_h
+
+#include "Watchpoint.h"
+
+namespace JSC {
+
+class JSObject;
+class PropertyName;
+
+class VariableWriteFireDetail : public FireDetail {
+public:
+    VariableWriteFireDetail(JSObject* object, const PropertyName& name)
+        : m_object(object)
+        , m_name(name)
+    {
+    }
+    
+    virtual void dump(PrintStream&) const override;
+    
+    JS_EXPORT_PRIVATE static void touch(WatchpointSet*, JSObject*, const PropertyName&);
+
+private:
+    JSObject* m_object;
+    const PropertyName& m_name;
+};
+
+} // namespace JSC
+
+#endif // VariableWriteFireDetail_h
diff --git a/bytecode/VirtualRegister.cpp b/bytecode/VirtualRegister.cpp
new file mode 100644 (file)
index 0000000..57cdb62
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "VirtualRegister.h"
+
+namespace JSC {
+
+void VirtualRegister::dump(PrintStream& out) const
+{
+    if (!isValid()) {
+        out.print("<invalid>");
+        return;
+    }
+    
+    if (isHeader()) {
+        out.print("head", m_virtualRegister);
+        return;
+    }
+    
+    if (isConstant()) {
+        out.print("const", toConstantIndex());
+        return;
+    }
+    
+    if (isArgument()) {
+        if (!toArgument())
+            out.print("this");
+        else
+            out.print("arg", toArgument());
+        return;
+    }
+    
+    if (isLocal()) {
+        out.print("loc", toLocal());
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace JSC
+
index 26e525d48bd43e90b9f9b1134982dbf63f74d96c..613088ef60397aa20164f253f8b9060f577a53a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,6 +59,7 @@ public:
     bool isValid() const { return (m_virtualRegister != s_invalidVirtualRegister); }
     bool isLocal() const { return operandIsLocal(m_virtualRegister); }
     bool isArgument() const { return operandIsArgument(m_virtualRegister); }
+    bool isHeader() const { return m_virtualRegister >= 0 && m_virtualRegister < JSStack::ThisArgument; }
     bool isConstant() const { return m_virtualRegister >= s_firstConstantRegisterIndex; }
     int toLocal() const { ASSERT(isLocal()); return operandToLocal(m_virtualRegister); }
     int toArgument() const { ASSERT(isArgument()); return operandToArgument(m_virtualRegister); }
@@ -66,8 +67,39 @@ public:
     int offset() const { return m_virtualRegister; }
     int offsetInBytes() const { return m_virtualRegister * sizeof(Register); }
 
-    bool operator==(const VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
-    bool operator!=(const VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
+    bool operator==(VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
+    bool operator!=(VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
+    bool operator<(VirtualRegister other) const { return m_virtualRegister < other.m_virtualRegister; }
+    bool operator>(VirtualRegister other) const { return m_virtualRegister > other.m_virtualRegister; }
+    bool operator<=(VirtualRegister other) const { return m_virtualRegister <= other.m_virtualRegister; }
+    bool operator>=(VirtualRegister other) const { return m_virtualRegister >= other.m_virtualRegister; }
+    
+    VirtualRegister operator+(int value) const
+    {
+        return VirtualRegister(offset() + value);
+    }
+    VirtualRegister operator-(int value) const
+    {
+        return VirtualRegister(offset() - value);
+    }
+    VirtualRegister operator+(VirtualRegister value) const
+    {
+        return VirtualRegister(offset() + value.offset());
+    }
+    VirtualRegister operator-(VirtualRegister value) const
+    {
+        return VirtualRegister(offset() - value.offset());
+    }
+    VirtualRegister& operator+=(int value)
+    {
+        return *this = *this + value;
+    }
+    VirtualRegister& operator-=(int value)
+    {
+        return *this = *this - value;
+    }
+    
+    void dump(PrintStream& out) const;
 
 private:
     static const int s_invalidVirtualRegister = 0x3fffffff;
@@ -95,13 +127,4 @@ inline VirtualRegister virtualRegisterForArgument(int argument, int offset = 0)
 
 } // namespace JSC
 
-namespace WTF {
-
-inline void printInternal(PrintStream& out, JSC::VirtualRegister value)
-{
-    out.print(value.offset());
-}
-
-} // namespace WTF
-
 #endif // VirtualRegister_h
index 081654d5737abc6c83fcc1b9e795f003efb33ddb..3c5f93a83e84cd7268ee52b8dcf6e2d9398abb44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+void StringFireDetail::dump(PrintStream& out) const
+{
+    out.print(m_string);
+}
+
 Watchpoint::~Watchpoint()
 {
     if (isOnList())
@@ -64,20 +69,25 @@ void WatchpointSet::add(Watchpoint* watchpoint)
     m_state = IsWatched;
 }
 
-void WatchpointSet::fireAllSlow()
+void WatchpointSet::fireAllSlow(const FireDetail& detail)
 {
     ASSERT(state() == IsWatched);
     
     WTF::storeStoreFence();
-    fireAllWatchpoints();
+    fireAllWatchpoints(detail);
     m_state = IsInvalidated;
     WTF::storeStoreFence();
 }
 
-void WatchpointSet::fireAllWatchpoints()
+void WatchpointSet::fireAllSlow(const char* reason)
+{
+    fireAllSlow(StringFireDetail(reason));
+}
+
+void WatchpointSet::fireAllWatchpoints(const FireDetail& detail)
 {
     while (!m_set.isEmpty())
-        m_set.begin()->fire();
+        m_set.begin()->fire(detail);
 }
 
 void InlineWatchpointSet::add(Watchpoint* watchpoint)
@@ -85,6 +95,11 @@ void InlineWatchpointSet::add(Watchpoint* watchpoint)
     inflate()->add(watchpoint);
 }
 
+void InlineWatchpointSet::fireAll(const char* reason)
+{
+    fireAll(StringFireDetail(reason));
+}
+
 WatchpointSet* InlineWatchpointSet::inflateSlow()
 {
     ASSERT(isThin());
index 7659c0db8d4c040caa8cc4f93b5b87fbf5e8b91a..88573177ae8649d8adee26bef9b39dc576d27a6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define Watchpoint_h
 
 #include <wtf/Atomics.h>
+#include <wtf/PrintStream.h>
 #include <wtf/SentinelLinkedList.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
 namespace JSC {
 
+class FireDetail {
+    void* operator new(size_t) = delete;
+    
+public:
+    FireDetail()
+    {
+    }
+    
+    virtual ~FireDetail()
+    {
+    }
+    
+    virtual void dump(PrintStream&) const = 0;
+};
+
+class StringFireDetail : public FireDetail {
+public:
+    StringFireDetail(const char* string)
+        : m_string(string)
+    {
+    }
+    
+    virtual void dump(PrintStream& out) const override;
+
+private:
+    const char* m_string;
+};
+
 class Watchpoint : public BasicRawSentinelNode<Watchpoint> {
 public:
     Watchpoint()
@@ -40,10 +69,10 @@ public:
     
     virtual ~Watchpoint();
 
-    void fire() { fireInternal(); }
+    void fire(const FireDetail& detail) { fireInternal(detail); }
     
 protected:
-    virtual void fireInternal() = 0;
+    virtual void fireInternal(const FireDetail&) = 0;
 };
 
 enum WatchpointState {
@@ -60,6 +89,12 @@ public:
     JS_EXPORT_PRIVATE WatchpointSet(WatchpointState);
     JS_EXPORT_PRIVATE ~WatchpointSet(); // Note that this will not fire any of the watchpoints; if you need to know when a WatchpointSet dies then you need a separate mechanism for this.
     
+    // Fast way of getting the state, which only works from the main thread.
+    WatchpointState stateOnJSThread() const
+    {
+        return static_cast<WatchpointState>(m_state);
+    }
+    
     // It is safe to call this from another thread. It may return an old
     // state. Guarantees that if *first* read the state() of the thing being
     // watched and it returned IsWatched and *second* you actually read its
@@ -98,39 +133,61 @@ public:
     // set watchpoints that we believe will actually be fired.
     void startWatching()
     {
-        ASSERT(state() != IsInvalidated);
+        ASSERT(m_state != IsInvalidated);
+        if (m_state == IsWatched)
+            return;
+        WTF::storeStoreFence();
         m_state = IsWatched;
+        WTF::storeStoreFence();
     }
     
-    void fireAll()
+    void fireAll(const FireDetail& detail)
     {
-        if (state() != IsWatched)
+        if (LIKELY(m_state != IsWatched))
             return;
-        fireAllSlow();
+        fireAllSlow(detail);
     }
     
-    void touch()
+    void fireAll(const char* reason)
+    {
+        if (LIKELY(m_state != IsWatched))
+            return;
+        fireAllSlow(reason);
+    }
+    
+    void touch(const FireDetail& detail)
     {
         if (state() == ClearWatchpoint)
             startWatching();
         else
-            fireAll();
+            fireAll(detail);
     }
     
-    void invalidate()
+    void touch(const char* reason)
+    {
+        touch(StringFireDetail(reason));
+    }
+    
+    void invalidate(const FireDetail& detail)
     {
         if (state() == IsWatched)
-            fireAll();
+            fireAll(detail);
         m_state = IsInvalidated;
     }
-
+    
+    void invalidate(const char* reason)
+    {
+        invalidate(StringFireDetail(reason));
+    }
+    
     int8_t* addressOfState() { return &m_state; }
     int8_t* addressOfSetIsNotEmpty() { return &m_setIsNotEmpty; }
     
-    JS_EXPORT_PRIVATE void fireAllSlow(); // Call only if you've checked isWatched.
+    JS_EXPORT_PRIVATE void fireAllSlow(const FireDetail&); // Call only if you've checked isWatched.
+    JS_EXPORT_PRIVATE void fireAllSlow(const char* reason); // Ditto.
     
 private:
-    void fireAllWatchpoints();
+    void fireAllWatchpoints(const FireDetail&);
     
     friend class InlineWatchpointSet;
 
@@ -174,18 +231,34 @@ public:
         freeFat();
     }
     
+    // Fast way of getting the state, which only works from the main thread.
+    WatchpointState stateOnJSThread() const
+    {
+        uintptr_t data = m_data;
+        if (isFat(data))
+            return fat(data)->stateOnJSThread();
+        return decodeState(data);
+    }
+
+    // It is safe to call this from another thread. It may return a prior state,
+    // but that should be fine since you should only perform actions based on the
+    // state if you also add a watchpoint.
+    WatchpointState state() const
+    {
+        WTF::loadLoadFence();
+        uintptr_t data = m_data;
+        WTF::loadLoadFence();
+        if (isFat(data))
+            return fat(data)->state();
+        return decodeState(data);
+    }
+    
     // It is safe to call this from another thread.  It may return false
     // even if the set actually had been invalidated, but that ought to happen
     // only in the case of races, and should be rare.
     bool hasBeenInvalidated() const
     {
-        WTF::loadLoadFence();
-        uintptr_t data = m_data;
-        if (isFat(data)) {
-            WTF::loadLoadFence();
-            return fat(data)->hasBeenInvalidated();
-        }
-        return decodeState(data) == IsInvalidated;
+        return state() == IsInvalidated;
     }
     
     // Like hasBeenInvalidated(), may be called from another thread.
@@ -206,10 +279,10 @@ public:
         m_data = encodeState(IsWatched);
     }
     
-    void fireAll()
+    void fireAll(const FireDetail& detail)
     {
         if (isFat()) {
-            fat()->fireAll();
+            fat()->fireAll(detail);
             return;
         }
         if (decodeState(m_data) == ClearWatchpoint)
@@ -218,19 +291,38 @@ public:
         WTF::storeStoreFence();
     }
     
-    void touch()
+    void invalidate(const FireDetail& detail)
+    {
+        if (isFat())
+            fat()->invalidate(detail);
+        else
+            m_data = encodeState(IsInvalidated);
+    }
+    
+    JS_EXPORT_PRIVATE void fireAll(const char* reason);
+    
+    void touch(const FireDetail& detail)
     {
         if (isFat()) {
-            fat()->touch();
+            fat()->touch(detail);
             return;
         }
-        if (decodeState(m_data) == ClearWatchpoint)
+        uintptr_t data = m_data;
+        if (decodeState(data) == IsInvalidated)
+            return;
+        WTF::storeStoreFence();
+        if (decodeState(data) == ClearWatchpoint)
             m_data = encodeState(IsWatched);
         else
             m_data = encodeState(IsInvalidated);
         WTF::storeStoreFence();
     }
     
+    void touch(const char* reason)
+    {
+        touch(StringFireDetail(reason));
+    }
+    
 private:
     static const uintptr_t IsThinFlag        = 1;
     static const uintptr_t StateMask         = 6;
@@ -247,7 +339,7 @@ private:
     
     static uintptr_t encodeState(WatchpointState state)
     {
-        return (state << StateShift) | IsThinFlag;
+        return (static_cast<uintptr_t>(state) << StateShift) | IsThinFlag;
     }
     
     bool isThin() const { return isThin(m_data); }
index 734546ab98e187e0d0d8be1322763456599c9886..8b2f8e61fc1e6b06dfdc83fc9471c559f6389bd2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) 2012 Igalia, S.L.
  *
 #include "config.h"
 #include "BytecodeGenerator.h"
 
+#include "BuiltinExecutables.h"
 #include "Interpreter.h"
-#include "JSActivation.h"
 #include "JSFunction.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
+#include "JSTemplateRegistryKey.h"
 #include "LowLevelInterpreter.h"
 #include "JSCInlines.h"
 #include "Options.h"
@@ -55,7 +57,7 @@ void Label::setLocation(unsigned location)
     
     unsigned size = m_unresolvedJumps.size();
     for (unsigned i = 0; i < size; ++i)
-        m_generator->m_instructions[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
+        m_generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
 }
 
 ParserError BytecodeGenerator::generate()
@@ -63,12 +65,36 @@ ParserError BytecodeGenerator::generate()
     SamplingRegion samplingRegion("Bytecode Generation");
     
     m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
-    for (size_t i = 0; i < m_deconstructedParameters.size(); i++) {
-        auto& entry = m_deconstructedParameters[i];
+    
+    // If we have declared a variable named "arguments" and we are using arguments then we should
+    // perform that assignment now.
+    if (m_needToInitializeArguments)
+        initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
+
+    for (size_t i = 0; i < m_destructuringParameters.size(); i++) {
+        auto& entry = m_destructuringParameters[i];
         entry.second->bindValue(*this, entry.first.get());
     }
 
-    m_scopeNode->emitBytecode(*this);
+    {
+        RefPtr<RegisterID> temp = newTemporary();
+        RefPtr<RegisterID> globalScope = scopeRegister(); // FIXME: With lexical scoping, this won't always be the global object: https://bugs.webkit.org/show_bug.cgi?id=142944 
+        for (auto functionPair : m_functionsToInitialize) {
+            FunctionBodyNode* functionBody = functionPair.first;
+            FunctionVariableType functionType = functionPair.second;
+            emitNewFunction(temp.get(), functionBody);
+            if (functionType == NormalFunctionVariable)
+                initializeVariable(variable(functionBody->ident()) , temp.get());
+            else if (functionType == GlobalFunctionVariable)
+                emitPutToScope(globalScope.get(), Variable(functionBody->ident()), temp.get(), ThrowIfNotFound);
+            else
+                RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+    
+    bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor();
+    if (!callingClassConstructor)
+        m_scopeNode->emitBytecode(*this);
 
     m_staticPropertyAnalyzer.kill();
 
@@ -103,11 +129,10 @@ ParserError BytecodeGenerator::generate()
             continue;
         
         ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
-        UnlinkedHandlerInfo info = {
-            static_cast<uint32_t>(start), static_cast<uint32_t>(end),
-            static_cast<uint32_t>(range.tryData->target->bind()),
-            range.tryData->targetScopeDepth
-        };
+        ASSERT(range.tryData->handlerType != HandlerType::Illegal);
+        UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end),
+            static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->targetScopeDepth,
+            range.tryData->handlerType);
         m_codeBlock->addExceptionHandler(info);
     }
     
@@ -115,86 +140,38 @@ ParserError BytecodeGenerator::generate()
 
     m_codeBlock->shrinkToFit();
 
-    if (m_codeBlock->symbolTable())
-        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneCapturedNames(*m_codeBlock->vm()));
+    if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
+        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
 
     if (m_expressionTooDeep)
         return ParserError(ParserError::OutOfMemory);
     return ParserError(ParserError::ErrorNone);
 }
 
-bool BytecodeGenerator::addVar(
-    const Identifier& ident, ConstantMode constantMode, WatchMode watchMode, RegisterID*& r0)
-{
-    ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
-    
-    ConcurrentJITLocker locker(symbolTable().m_lock);
-    int index = virtualRegisterForLocal(m_calleeRegisters.size()).offset();
-    SymbolTableEntry newEntry(index, constantMode == IsConstant ? ReadOnly : 0);
-    SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
-
-    if (!result.isNewEntry) {
-        r0 = &registerFor(result.iterator->value.getIndex());
-        return false;
-    }
-    
-    if (watchMode == IsWatchable) {
-        while (m_watchableVariables.size() < static_cast<size_t>(m_codeBlock->m_numVars))
-            m_watchableVariables.append(Identifier());
-        m_watchableVariables.append(ident);
-    }
-    
-    r0 = addVar();
-    
-    ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
-    
-    return true;
-}
-
-void BytecodeGenerator::preserveLastVar()
-{
-    if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
-        m_lastVar = &m_calleeRegisters.last();
-}
-
 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
-    , m_symbolTable(0)
     , m_scopeNode(programNode)
     , m_codeBlock(vm, codeBlock)
     , m_thisRegister(CallFrame::thisArgumentOffset())
-    , m_activationRegister(0)
-    , m_emptyValueRegister(0)
-    , m_globalObjectRegister(0)
-    , m_finallyDepth(0)
-    , m_localScopeDepth(0)
     , m_codeType(GlobalCode)
-    , m_nextConstantOffset(0)
-    , m_globalConstantIndex(0)
-    , m_firstLazyFunction(0)
-    , m_lastLazyFunction(0)
-    , m_staticPropertyAnalyzer(&m_instructions)
     , m_vm(&vm)
-    , m_lastOpcodeID(op_end)
-#ifndef NDEBUG
-    , m_lastOpcodePosition(0)
-#endif
-    , m_usesExceptions(false)
-    , m_expressionTooDeep(false)
-    , m_isBuiltinFunction(false)
 {
+    for (auto& constantRegister : m_linkTimeConstantRegisters)
+        constantRegister = nullptr;
+
     m_codeBlock->setNumParameters(1); // Allocate space for "this"
 
     emitOpcode(op_enter);
 
+    allocateAndEmitScope();
+
     const VarStack& varStack = programNode->varStack();
     const FunctionStack& functionStack = programNode->functionStack();
 
     for (size_t i = 0; i < functionStack.size(); ++i) {
         FunctionBodyNode* function = functionStack[i];
-        UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function);
-        codeBlock->addFunctionDeclaration(*m_vm, function->ident(), unlinkedFunction);
+        m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));
     }
 
     for (size_t i = 0; i < varStack.size(); ++i)
@@ -202,38 +179,25 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
 
 }
 
-BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionBodyNode* functionBody, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
+BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
     , m_symbolTable(codeBlock->symbolTable())
-    , m_scopeNode(functionBody)
+    , m_scopeNode(functionNode)
     , m_codeBlock(vm, codeBlock)
-    , m_activationRegister(0)
-    , m_emptyValueRegister(0)
-    , m_globalObjectRegister(0)
-    , m_finallyDepth(0)
-    , m_localScopeDepth(0)
     , m_codeType(FunctionCode)
-    , m_nextConstantOffset(0)
-    , m_globalConstantIndex(0)
-    , m_firstLazyFunction(0)
-    , m_lastLazyFunction(0)
-    , m_staticPropertyAnalyzer(&m_instructions)
     , m_vm(&vm)
-    , m_lastOpcodeID(op_end)
-#ifndef NDEBUG
-    , m_lastOpcodePosition(0)
-#endif
-    , m_usesExceptions(false)
-    , m_expressionTooDeep(false)
     , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
 {
+    for (auto& constantRegister : m_linkTimeConstantRegisters)
+        constantRegister = nullptr;
+
     if (m_isBuiltinFunction)
         m_shouldEmitDebugHooks = false;
-
+    
     m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     Vector<Identifier> boundParameterProperties;
-    FunctionParameters& parameters = *functionBody->parameters();
+    FunctionParameters& parameters = *functionNode->parameters();
     for (size_t i = 0; i < parameters.size(); i++) {
         auto pattern = parameters.at(i);
         if (pattern->isBindingNode())
@@ -241,175 +205,295 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionBodyNode* functionBody, Unl
         pattern->collectBoundIdentifiers(boundParameterProperties);
         continue;
     }
-    m_symbolTable->setParameterCountIncludingThis(functionBody->parameters()->size() + 1);
 
-    emitOpcode(op_enter);
-    if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
-        m_activationRegister = addVar();
-        emitInitLazyRegister(m_activationRegister);
-        m_codeBlock->setActivationRegister(m_activationRegister->virtualRegister());
-    }
-
-    m_symbolTable->setCaptureStart(virtualRegisterForLocal(m_codeBlock->m_numVars).offset());
-
-    if (functionBody->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
-        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
-        RegisterID* argumentsRegister = addVar(propertyNames().arguments, IsVariable, NotWatchable); // Can be changed by assigning to 'arguments'.
+    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
+    bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
+    bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
+    
+    auto captures = [&] (UniquedStringImpl* uid) -> bool {
+        if (shouldCaptureAllOfTheThings)
+            return true;
+        if (!shouldCaptureSomeOfTheThings)
+            return false;
+        if (needsArguments && uid == propertyNames().arguments.impl()) {
+            // Actually, we only need to capture the arguments object when we "need full activation"
+            // because of name scopes. But historically we did it this way, so for now we just preserve
+            // the old behavior.
+            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
+            return true;
+        }
+        return functionNode->captures(uid);
+    };
+    auto varKind = [&] (UniquedStringImpl* uid) -> VarKind {
+        return captures(uid) ? VarKind::Scope : VarKind::Stack;
+    };
 
-        // We can save a little space by hard-coding the knowledge that the two
-        // 'arguments' values are stored in consecutive registers, and storing
-        // only the index of the assignable one.
-        codeBlock->setArgumentsRegister(argumentsRegister->virtualRegister());
-        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->virtualRegister() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
+    emitOpcode(op_enter);
 
-        emitInitLazyRegister(argumentsRegister);
-        emitInitLazyRegister(unmodifiedArgumentsRegister);
-        
-        if (shouldTearOffArgumentsEagerly()) {
-            emitOpcode(op_create_arguments);
-            instructions().append(argumentsRegister->index());
-        }
+    allocateAndEmitScope();
+    
+    m_calleeRegister.setIndex(JSStack::Callee);
+    
+    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
+        && functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())) {
+        // When we do this, we should make our local scope stack know about the function name symbol
+        // table. Currently this works because bytecode linking creates a phony name scope.
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141885
+        // Also, we could create the scope once per JSFunction instance that needs it. That wouldn't
+        // be any more correct, but it would be more performant.
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141887
+        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
     }
 
-    bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
-
+    if (shouldCaptureSomeOfTheThings) {
+        m_lexicalEnvironmentRegister = addVar();
+        m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
+        emitOpcode(op_create_lexical_environment);
+        instructions().append(m_lexicalEnvironmentRegister->index());
+        instructions().append(scopeRegister()->index());
+        emitOpcode(op_mov);
+        instructions().append(scopeRegister()->index());
+        instructions().append(m_lexicalEnvironmentRegister->index());
+    }
+    
+    // Make sure the code block knows about all of our parameters, and make sure that parameters
+    // needing destructuring are noted.
+    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
+    m_thisRegister.setIndex(initializeNextParameter()->index()); // this
+    for (unsigned i = 0; i < parameters.size(); ++i) {
+        auto pattern = parameters.at(i);
+        RegisterID* reg = initializeNextParameter();
+        if (!pattern->isBindingNode())
+            m_destructuringParameters.append(std::make_pair(reg, pattern));
+    }
+    
+    // Figure out some interesting facts about our arguments.
     bool capturesAnyArgumentByName = false;
-    Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
-    if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) {
-        FunctionParameters& parameters = *functionBody->parameters();
-        capturedArguments.resize(parameters.size());
+    if (functionNode->hasCapturedVariables()) {
+        FunctionParameters& parameters = *functionNode->parameters();
         for (size_t i = 0; i < parameters.size(); ++i) {
-            capturedArguments[i] = 0;
             auto pattern = parameters.at(i);
             if (!pattern->isBindingNode())
                 continue;
             const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
-            if (!functionBody->captures(ident) && !shouldCaptureAllTheThings)
-                continue;
-            capturesAnyArgumentByName = true;
-            capturedArguments[i] = addVar();
+            capturesAnyArgumentByName |= captures(ident.impl());
         }
     }
 
-    if (capturesAnyArgumentByName && !shouldTearOffArgumentsEagerly()) {
-        size_t parameterCount = m_symbolTable->parameterCount();
-        auto slowArguments = std::make_unique<SlowArgument[]>(parameterCount);
-        for (size_t i = 0; i < parameterCount; ++i) {
-            if (!capturedArguments[i]) {
-                ASSERT(slowArguments[i].status == SlowArgument::Normal);
-                slowArguments[i].index = CallFrame::argumentOffset(i);
-                continue;
-            }
-            slowArguments[i].status = SlowArgument::Captured;
-            slowArguments[i].index = capturedArguments[i]->index();
-        }
-        m_symbolTable->setSlowArguments(WTF::move(slowArguments));
+    if (capturesAnyArgumentByName)
+        ASSERT(m_lexicalEnvironmentRegister);
+    
+    // Need to know what our functions are called. Parameters have some goofy behaviors when it
+    // comes to functions of the same name.
+    for (FunctionBodyNode* function : functionNode->functionStack())
+        m_functions.add(function->ident().impl());
+    
+    if (needsArguments) {
+        // Create the arguments object now. We may put the arguments object into the activation if
+        // it is captured. Either way, we create two arguments object variables: one is our
+        // private variable that is immutable, and another that is the user-visible variable. The
+        // immutable one is only used here, or during formal parameter resolutions if we opt for
+        // DirectArguments.
+        
+        m_argumentsRegister = addVar();
+        m_argumentsRegister->ref();
     }
-
-    RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var.
-
-    const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
-    const DeclarationStacks::VarStack& varStack = functionBody->varStack();
-    IdentifierSet test;
-
-    // Captured variables and functions go first so that activations don't have
-    // to step over the non-captured locals to mark them.
-    if (functionBody->hasCapturedVariables()) {
-        for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-            const Identifier& ident = boundParameterProperties[i];
-            if (functionBody->captures(ident))
-                addVar(ident, IsVariable, IsWatchable);
-        }
-        for (size_t i = 0; i < functionStack.size(); ++i) {
-            FunctionBodyNode* function = functionStack[i];
-            const Identifier& ident = function->ident();
-            if (functionBody->captures(ident)) {
-                m_functions.add(ident.impl());
-                emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function);
+    
+    if (needsArguments && !codeBlock->isStrictMode()) {
+        // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
+        // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
+        // activation.
+        
+        if (capturesAnyArgumentByName) {
+            m_symbolTable->setArgumentsLength(vm, parameters.size());
+            
+            // For each parameter, we have two possibilities:
+            // Either it's a binding node with no function overlap, in which case it gets a name
+            // in the symbol table - or it just gets space reserved in the symbol table. Either
+            // way we lift the value into the scope.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+                m_symbolTable->setArgumentOffset(vm, i, offset);
+                if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i))) {
+                    VarOffset varOffset(offset);
+                    SymbolTableEntry entry(varOffset);
+                    // Stores to these variables via the ScopedArguments object will not do
+                    // notifyWrite(), since that would be cumbersome. Also, watching formal
+                    // parameters when "arguments" is in play is unlikely to be super profitable.
+                    // So, we just disable it.
+                    entry.disableWatching();
+                    m_symbolTable->set(name, entry);
+                }
+                emitOpcode(op_put_to_scope);
+                instructions().append(m_lexicalEnvironmentRegister->index());
+                instructions().append(UINT_MAX);
+                instructions().append(virtualRegisterForArgument(1 + i).offset());
+                instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+                instructions().append(0);
+                instructions().append(offset.offset());
             }
+            
+            // This creates a scoped arguments object and copies the overflow arguments into the
+            // scope. It's the equivalent of calling ScopedArguments::createByCopying().
+            emitOpcode(op_create_scoped_arguments);
+            instructions().append(m_argumentsRegister->index());
+            instructions().append(m_lexicalEnvironmentRegister->index());
+        } else {
+            // We're going to put all parameters into the DirectArguments object. First ensure
+            // that the symbol table knows that this is happening.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i)))
+                    m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
+            }
+            
+            emitOpcode(op_create_direct_arguments);
+            instructions().append(m_argumentsRegister->index());
         }
-        for (size_t i = 0; i < varStack.size(); ++i) {
-            const Identifier& ident = varStack[i].first;
-            if (functionBody->captures(ident))
-                addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable);
+    } else {
+        // Create the formal parameters the normal way. Any of them could be captured, or not. If
+        // captured, lift them into the scope.
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            UniquedStringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (!name)
+                continue;
+            
+            if (!captures(name)) {
+                // This is the easy case - just tell the symbol table about the argument. It will
+                // be accessed directly.
+                m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
+                continue;
+            }
+            
+            ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+            const Identifier& ident =
+                static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
+            m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(ident));
+            instructions().append(virtualRegisterForArgument(1 + i).offset());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
         }
     }
-
-    m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());
-
-    bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
-    m_firstLazyFunction = codeBlock->m_numVars;
-    for (size_t i = 0; i < functionStack.size(); ++i) {
-        FunctionBodyNode* function = functionStack[i];
+    
+    if (needsArguments && codeBlock->isStrictMode()) {
+        // Allocate an out-of-bands arguments object.
+        emitOpcode(op_create_out_of_band_arguments);
+        instructions().append(m_argumentsRegister->index());
+    }
+    
+    // Now declare all variables.
+    for (const Identifier& ident : boundParameterProperties)
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+    for (FunctionBodyNode* function : functionNode->functionStack()) {
         const Identifier& ident = function->ident();
-        if (!functionBody->captures(ident)) {
-            m_functions.add(ident.impl());
-            RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable);
-            // Don't lazily create functions that override the name 'arguments'
-            // as this would complicate lazy instantiation of actual arguments.
-            if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
-                emitNewFunction(reg.get(), NotCaptured, function);
-            else {
-                emitInitLazyRegister(reg.get());
-                m_lazyFunctions.set(reg->virtualRegister().toLocal(), function);
-            }
-        }
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+        m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
     }
-    m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
-    for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-        const Identifier& ident = boundParameterProperties[i];
-        if (!functionBody->captures(ident))
-            addVar(ident, IsVariable, IsWatchable);
+    for (auto& entry : functionNode->varStack()) {
+        ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
+        // Variables named "arguments" are never const.
+        if (entry.first == propertyNames().arguments)
+            constantMode = IsVariable;
+        createVariable(entry.first, varKind(entry.first.impl()), constantMode, IgnoreExisting);
     }
-    for (size_t i = 0; i < varStack.size(); ++i) {
-        const Identifier& ident = varStack[i].first;
-        if (!functionBody->captures(ident))
-            addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
+    
+    // There are some variables that need to be preinitialized to something other than Undefined:
+    //
+    // - "arguments": unless it's used as a function or parameter, this should refer to the
+    //   arguments object.
+    //
+    // - callee: unless it's used as a var, function, or parameter, this should refer to the
+    //   callee (i.e. our function).
+    //
+    // - functions: these always override everything else.
+    //
+    // The most logical way to do all of this is to initialize none of the variables until now,
+    // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
+    // for how these things override each other end up holding. We would initialize the callee
+    // first, then "arguments", then all arguments, then the functions.
+    //
+    // But some arguments are already initialized by default, since if they aren't captured and we
+    // don't have "arguments" then we just point the symbol table at the stack slot of those
+    // arguments. We end up initializing the rest of the arguments that have an uncomplicated
+    // binding (i.e. don't involve destructuring) above when figuring out how to lay them out,
+    // because that's just the simplest thing. This means that when we initialize them, we have to
+    // watch out for the things that override arguments (namely, functions).
+    //
+    // We also initialize callee here as well, just because it's so weird. We know whether we want
+    // to do this because we can just check if it's in the symbol table.
+    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
+        && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
+        && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
+        if (captures(functionNode->ident().impl())) {
+            ScopeOffset offset;
+            {
+                ConcurrentJITLocker locker(m_symbolTable->m_lock);
+                offset = m_symbolTable->takeNextScopeOffset(locker);
+                m_symbolTable->add(
+                    locker, functionNode->ident().impl(),
+                    SymbolTableEntry(VarOffset(offset), ReadOnly));
+            }
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(functionNode->ident()));
+            instructions().append(m_calleeRegister.index());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
+        } else {
+            m_symbolTable->add(
+                functionNode->ident().impl(),
+                SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
+        }
     }
-
-    if (shouldCaptureAllTheThings)
-        m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());
-
-    if (m_symbolTable->captureCount())
-        emitOpcode(op_touch_entry);
     
-    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
-
-    // Add "this" as a parameter
-    int nextParameterIndex = CallFrame::thisArgumentOffset();
-    m_thisRegister.setIndex(nextParameterIndex++);
-    m_codeBlock->addParameter();
-    for (size_t i = 0; i < parameters.size(); ++i, ++nextParameterIndex) {
-        int index = nextParameterIndex;
-        auto pattern = parameters.at(i);
-        if (!pattern->isBindingNode()) {
-            m_codeBlock->addParameter();
-            RegisterID& parameter = registerFor(index);
-            parameter.setIndex(index);
-            m_deconstructedParameters.append(std::make_pair(&parameter, pattern));
-            continue;
+    // This is our final act of weirdness. "arguments" is overridden by everything except the
+    // callee. We add it to the symbol table if it's not already there and it's not an argument.
+    if (needsArguments) {
+        // If "arguments" is overridden by a function or destructuring parameter name, then it's
+        // OK for us to call createVariable() because it won't change anything. It's also OK for
+        // us to them tell BytecodeGenerator::generate() to write to it because it will do so
+        // before it initializes functions and destructuring parameters. But if "arguments" is
+        // overridden by a "simple" function parameter, then we have to bail: createVariable()
+        // would assert and BytecodeGenerator::generate() would write the "arguments" after the
+        // argument value had already been properly initialized.
+        
+        bool haveParameterNamedArguments = false;
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            UniquedStringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (name == propertyNames().arguments.impl()) {
+                haveParameterNamedArguments = true;
+                break;
+            }
         }
-        auto simpleParameter = static_cast<const BindingNode*>(pattern);
-        if (capturedArguments.size() && capturedArguments[i]) {
-            ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(simpleParameter->boundProperty())) || shouldCaptureAllTheThings);
-            index = capturedArguments[i]->index();
-            RegisterID original(nextParameterIndex);
-            emitMove(capturedArguments[i], &original);
+        
+        if (!haveParameterNamedArguments) {
+            createVariable(
+                propertyNames().arguments, varKind(propertyNames().arguments.impl()), IsVariable);
+            m_needToInitializeArguments = true;
         }
-        addParameter(simpleParameter->boundProperty(), index);
     }
-    preserveLastVar();
-
-    // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
-    addCallee(functionBody, calleeRegister);
-
+    
     if (isConstructor()) {
-        emitCreateThis(&m_thisRegister);
-    } else if (functionBody->usesThis() || codeBlock->usesEval()) {
+        if (constructorKind() == ConstructorKind::Derived) {
+            m_newTargetRegister = addVar();
+            emitMove(m_newTargetRegister, &m_thisRegister);
+            emitMoveEmptyValue(&m_thisRegister);
+        } else
+            emitCreateThis(&m_thisRegister);
+    } else if (constructorKind() != ConstructorKind::None) {
+        emitThrowTypeError("Cannot call a class constructor");
+    } else if (functionNode->usesThis() || codeBlock->usesEval()) {
         m_codeBlock->addPropertyAccessInstruction(instructions().size());
         emitOpcode(op_to_this);
         instructions().append(kill(&m_thisRegister));
         instructions().append(0);
+        instructions().append(0);
     }
 }
 
@@ -420,31 +504,19 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
     , m_scopeNode(evalNode)
     , m_codeBlock(vm, codeBlock)
     , m_thisRegister(CallFrame::thisArgumentOffset())
-    , m_activationRegister(0)
-    , m_emptyValueRegister(0)
-    , m_globalObjectRegister(0)
-    , m_finallyDepth(0)
-    , m_localScopeDepth(0)
     , m_codeType(EvalCode)
-    , m_nextConstantOffset(0)
-    , m_globalConstantIndex(0)
-    , m_firstLazyFunction(0)
-    , m_lastLazyFunction(0)
-    , m_staticPropertyAnalyzer(&m_instructions)
     , m_vm(&vm)
-    , m_lastOpcodeID(op_end)
-#ifndef NDEBUG
-    , m_lastOpcodePosition(0)
-#endif
-    , m_usesExceptions(false)
-    , m_expressionTooDeep(false)
-    , m_isBuiltinFunction(false)
 {
+    for (auto& constantRegister : m_linkTimeConstantRegisters)
+        constantRegister = nullptr;
+
     m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     m_codeBlock->setNumParameters(1);
 
     emitOpcode(op_enter);
 
+    allocateAndEmitScope();
+
     const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
     for (size_t i = 0; i < functionStack.size(); ++i)
         m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
@@ -454,101 +526,33 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
     Vector<Identifier, 0, UnsafeVectorOverflow> variables;
     variables.reserveCapacity(numVariables);
     for (size_t i = 0; i < numVariables; ++i) {
-        ASSERT(varStack[i].first.impl()->isAtomic());
+        ASSERT(varStack[i].first.impl()->isAtomic() || varStack[i].first.impl()->isSymbol());
         variables.append(varStack[i].first);
     }
     codeBlock->adoptVariables(variables);
-    preserveLastVar();
 }
 
 BytecodeGenerator::~BytecodeGenerator()
 {
 }
 
-RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
-{
-    emitOpcode(op_init_lazy_reg);
-    instructions().append(reg->index());
-    ASSERT(!hasWatchableVariable(reg->index()));
-    return reg;
-}
-
-RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode)
-{
-    if (!functionNameIsInScope(functionBodyNode->ident(), functionBodyNode->functionMode()))
-        return 0;
-
-    if (functionNameScopeIsDynamic(m_codeBlock->usesEval(), m_codeBlock->isStrictMode()))
-        return 0;
-
-    m_calleeRegister.setIndex(JSStack::Callee);
-    if (functionBodyNode->captures(functionBodyNode->ident()))
-        return emitMove(addVar(), IsCaptured, &m_calleeRegister);
-
-    return &m_calleeRegister;
-}
-
-void BytecodeGenerator::addCallee(FunctionBodyNode* functionBodyNode, RegisterID* calleeRegister)
-{
-    if (!calleeRegister)
-        return;
-
-    symbolTable().add(functionBodyNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
-}
-
-void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
+RegisterID* BytecodeGenerator::initializeNextParameter()
 {
-    // Parameters overwrite var declarations, but not function declarations.
-    StringImpl* rep = ident.impl();
-    if (!m_functions.contains(rep)) {
-        symbolTable().set(rep, parameterIndex);
-        RegisterID& parameter = registerFor(parameterIndex);
-        parameter.setIndex(parameterIndex);
-    }
-
-    // To maintain the calling convention, we have to allocate unique space for
-    // each parameter, even if the parameter doesn't make it into the symbol table.
+    VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
+    RegisterID& parameter = registerFor(reg);
+    parameter.setIndex(reg.offset());
     m_codeBlock->addParameter();
+    return &parameter;
 }
 
-bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
-{
-    if (ident != propertyNames().arguments)
-        return false;
-    
-    if (!shouldOptimizeLocals())
-        return false;
-    
-    SymbolTableEntry entry = symbolTable().get(ident.impl());
-    if (entry.isNull())
-        return false;
-
-    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
-        return true;
-    
-    return false;
-}
-
-RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
-{
-    ASSERT(willResolveToArguments(propertyNames().arguments));
-
-    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl());
-    ASSERT(!entry.isNull());
-    return &registerFor(entry.getIndex());
-}
-
-RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
+UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
 {
-    if (!reg->virtualRegister().isLocal())
-        return reg;
-
-    int localVariableNumber = reg->virtualRegister().toLocal();
-
-    if (m_lastLazyFunction <= localVariableNumber || localVariableNumber < m_firstLazyFunction)
-        return reg;
-    emitLazyNewFunction(reg, m_lazyFunctions.get(localVariableNumber));
-    return reg;
+    if (pattern->isBindingNode()) {
+        const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
+        if (!m_functions.contains(ident.impl()))
+            return ident.impl();
+    }
+    return nullptr;
 }
 
 RegisterID* BytecodeGenerator::newRegister()
@@ -590,7 +594,7 @@ PassRefPtr<Label> BytecodeGenerator::newLabel()
         m_labels.removeLast();
 
     // Allocate new label ID.
-    m_labels.append(this);
+    m_labels.append(*this);
     return &m_labels.last();
 }
 
@@ -948,9 +952,15 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond
     return target;
 }
 
+bool BytecodeGenerator::hasConstant(const Identifier& ident) const
+{
+    UniquedStringImpl* rep = ident.impl();
+    return m_identifierMap.contains(rep);
+}
+
 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
 {
-    StringImpl* rep = ident.impl();
+    UniquedStringImpl* rep = ident.impl();
     IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
     if (result.isNewEntry)
         m_codeBlock->addIdentifier(ident);
@@ -972,42 +982,70 @@ RegisterID* BytecodeGenerator::addConstantEmptyValue()
     return m_emptyValueRegister;
 }
 
-RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
+RegisterID* BytecodeGenerator::addConstantValue(JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
 {
     if (!v)
         return addConstantEmptyValue();
 
     int index = m_nextConstantOffset;
-    JSValueMap::AddResult result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
+
+    EncodedJSValueWithRepresentation valueMapKey { JSValue::encode(v), sourceCodeRepresentation };
+    JSValueMap::AddResult result = m_jsValueMap.add(valueMapKey, m_nextConstantOffset);
     if (result.isNewEntry) {
         m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
         ++m_nextConstantOffset;
-        m_codeBlock->addConstant(v);
+        m_codeBlock->addConstant(v, sourceCodeRepresentation);
     } else
         index = result.iterator->value;
     return &m_constantPoolRegisters[index];
 }
 
+RegisterID* BytecodeGenerator::emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant type)
+{
+    unsigned constantIndex = static_cast<unsigned>(type);
+    if (!m_linkTimeConstantRegisters[constantIndex]) {
+        int index = m_nextConstantOffset;
+        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
+        ++m_nextConstantOffset;
+        m_codeBlock->addConstant(type);
+        m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
+    }
+
+    emitOpcode(op_mov);
+    instructions().append(dst->index());
+    instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
+
+    return dst;
+}
+
 unsigned BytecodeGenerator::addRegExp(RegExp* r)
 {
     return m_codeBlock->addRegExp(r);
 }
 
-RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, CaptureMode captureMode, RegisterID* src)
+RegisterID* BytecodeGenerator::emitMoveEmptyValue(RegisterID* dst)
 {
-    m_staticPropertyAnalyzer.mov(dst->index(), src->index());
+    RefPtr<RegisterID> emptyValue = addConstantEmptyValue();
 
-    emitOpcode(captureMode == IsCaptured ? op_captured_mov : op_mov);
+    emitOpcode(op_mov);
     instructions().append(dst->index());
-    instructions().append(src->index());
-    if (captureMode == IsCaptured)
-        instructions().append(watchableVariable(dst->index()));
+    instructions().append(emptyValue->index());
     return dst;
 }
 
 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
 {
-    return emitMove(dst, captureMode(dst->index()), src);
+    ASSERT(src != m_emptyValueRegister);
+
+    m_staticPropertyAnalyzer.mov(dst->index(), src->index());
+    emitOpcode(op_mov);
+    instructions().append(dst->index());
+    instructions().append(src->index());
+
+    if (!dst->isTemporary() && vm()->typeProfiler())
+        emitProfileType(dst, ProfileTypeBytecodeHasGlobalID, nullptr);
+
+    return dst;
 }
 
 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
@@ -1089,7 +1127,7 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst
             }
             if (value == "object") {
                 rewindUnaryOp();
-                emitOpcode(op_is_object);
+                emitOpcode(op_is_object_or_null);
                 instructions().append(dst->index());
                 instructions().append(srcIndex);
                 return dst;
@@ -1111,22 +1149,43 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
+void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot)
 {
-    return emitLoad(dst, jsBoolean(b));
+    unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
+    unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
+    unsigned instructionOffset = instructions().size() - 1;
+    m_codeBlock->addTypeProfilerExpressionInfo(instructionOffset, start, end);
+}
+
+void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const Identifier* identifier)
+{
+    if (flag == ProfileTypeBytecodeGetFromScope || flag == ProfileTypeBytecodePutToScope)
+        RELEASE_ASSERT(identifier);
+
+    // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
+    emitOpcode(op_profile_type);
+    instructions().append(registerToProfile->index());
+    instructions().append(0);
+    instructions().append(flag);
+    instructions().append(identifier ? addConstant(*identifier) : 0);
+    instructions().append(resolveType());
 }
 
-RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
+void BytecodeGenerator::emitProfileControlFlow(int textOffset)
 {
-    // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
-    // Later we can do the extra work to handle that like the other cases.  They also don't
-    // work correctly with NaN as a key.
-    if (std::isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
-        return emitLoad(dst, jsNumber(number));
-    JSValue& valueInMap = m_numberMap.add(number, JSValue()).iterator->value;
-    if (!valueInMap)
-        valueInMap = jsNumber(number);
-    return emitLoad(dst, valueInMap);
+    if (vm()->controlFlowProfiler()) {
+        RELEASE_ASSERT(textOffset >= 0);
+        size_t bytecodeOffset = instructions().size();
+        m_codeBlock->addOpProfileControlFlowBytecodeOffset(bytecodeOffset);
+
+        emitOpcode(op_profile_control_flow);
+        instructions().append(textOffset);
+    }
+}
+
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
+{
+    return emitLoad(dst, jsBoolean(b));
 }
 
 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
@@ -1137,9 +1196,9 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& ident
     return emitLoad(dst, JSValue(stringInMap));
 }
 
-RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v, SourceCodeRepresentation sourceCodeRepresentation)
 {
-    RegisterID* constantID = addConstantValue(v);
+    RegisterID* constantID = addConstantValue(v, sourceCodeRepresentation);
     if (dst)
         return emitMove(dst, constantID);
     return constantID;
@@ -1160,41 +1219,96 @@ RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
     return m_globalObjectRegister;
 }
 
-bool BytecodeGenerator::isCaptured(int operand)
+Variable BytecodeGenerator::variable(const Identifier& property)
 {
-    return m_symbolTable && m_symbolTable->isCaptured(operand);
-}
-
-Local BytecodeGenerator::local(const Identifier& property)
-{
-    if (property == propertyNames().thisIdentifier)
-        return Local(thisRegister(), ReadOnly, NotCaptured);
+    if (property == propertyNames().thisIdentifier) {
+        return Variable(
+            property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
+            ReadOnly, Variable::SpecialVariable);
+    }
     
-    if (property == propertyNames().arguments)
-        createArgumentsIfNecessary();
-
     if (!shouldOptimizeLocals())
-        return Local();
+        return Variable(property);
+    
+    SymbolTableEntry entry = symbolTable().get(property.impl());
+    if (entry.isNull())
+        return Variable(property);
+    
+    if (entry.varOffset().isScope() && m_localScopeDepth) {
+        // FIXME: We should be able to statically resolve through our local scopes.
+        // https://bugs.webkit.org/show_bug.cgi?id=141885
+        return Variable(property);
+    }
+    
+    return variableForLocalEntry(property, entry);
+}
 
+Variable BytecodeGenerator::variablePerSymbolTable(const Identifier& property)
+{
     SymbolTableEntry entry = symbolTable().get(property.impl());
     if (entry.isNull())
-        return Local();
+        return Variable(property);
+    
+    return variableForLocalEntry(property, entry);
+}
 
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
-    return Local(local, entry.getAttributes(), captureMode(local->index()));
+Variable BytecodeGenerator::variableForLocalEntry(
+    const Identifier& property, const SymbolTableEntry& entry)
+{
+    VarOffset offset = entry.varOffset();
+    
+    RegisterID* local;
+    if (offset.isStack())
+        local = &registerFor(offset.stackOffset());
+    else
+        local = nullptr;
+    
+    return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable);
 }
 
-Local BytecodeGenerator::constLocal(const Identifier& property)
+void BytecodeGenerator::createVariable(
+    const Identifier& property, VarKind varKind, ConstantMode constantMode,
+    ExistingVariableMode existingVariableMode)
 {
-    if (m_codeType != FunctionCode)
-        return Local();
+    ASSERT(property != propertyNames().thisIdentifier);
+    
+    ConcurrentJITLocker locker(symbolTable().m_lock);
+    SymbolTableEntry entry = symbolTable().get(locker, property.impl());
+    
+    if (!entry.isNull()) {
+        if (existingVariableMode == IgnoreExisting)
+            return;
+        
+        // Do some checks to ensure that the variable we're being asked to create is sufficiently
+        // compatible with the one we have already created.
 
-    SymbolTableEntry entry = symbolTable().get(property.impl());
-    if (entry.isNull())
-        return Local();
+        VarOffset offset = entry.varOffset();
+        
+        // We can't change our minds about whether it's captured.
+        if (offset.kind() != varKind || constantMode != entry.constantMode()) {
+            dataLog(
+                "Trying to add variable called ", property, " as ", varKind, "/", constantMode,
+                " but it was already added as ", offset, "/", entry.constantMode(), ".\n");
+            RELEASE_ASSERT_NOT_REACHED();
+        }
 
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
-    return Local(local, entry.getAttributes(), captureMode(local->index()));
+        return;
+    }
+    
+    VarOffset varOffset;
+    if (varKind == VarKind::Scope)
+        varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
+    else {
+        ASSERT(varKind == VarKind::Stack);
+        varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
+    }
+    SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
+    symbolTable().add(locker, property.impl(), newEntry);
+    
+    if (varKind == VarKind::Stack) {
+        RegisterID* local = addVar();
+        RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
+    }
 }
 
 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
@@ -1218,55 +1332,147 @@ ResolveType BytecodeGenerator::resolveType()
     return GlobalProperty;
 }
 
-RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier)
+RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
 {
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    ASSERT(!m_symbolTable || !m_symbolTable->contains(identifier.impl()) || resolveType() == Dynamic);
-
-    // resolve_scope dst, id, ResolveType, depth
-    emitOpcode(op_resolve_scope);
-    instructions().append(kill(dst));
-    instructions().append(addConstant(identifier));
-    instructions().append(resolveType());
-    instructions().append(0);
-    instructions().append(0);
-    return dst;
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return nullptr;
+        
+    case VarKind::DirectArgument:
+        return argumentsRegister();
+        
+    case VarKind::Scope:
+        // This always refers to the activation that *we* allocated, and not the current scope that code
+        // lives in. Note that this will change once we have proper support for block scoping. Once that
+        // changes, it will be correct for this code to return scopeRegister(). The only reason why we
+        // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
+        // requires weird things because it is a shameful pile of nonsense, but block scoping would make
+        // that code sensible and obviate the need for us to do bad things.
+        return m_lexicalEnvironmentRegister;
+        
+    case VarKind::Invalid:
+        // Indicates non-local resolution.
+        
+        ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
+        
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // resolve_scope dst, id, ResolveType, depth
+        emitOpcode(op_resolve_scope);
+        dst = tempDestination(dst);
+        instructions().append(kill(dst));
+        instructions().append(scopeRegister()->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(resolveType());
+        instructions().append(0);
+        instructions().append(0);
+        return dst;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
 }
 
-RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode)
+RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
 {
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return emitMove(dst, variable.local());
+        
+    case VarKind::DirectArgument: {
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(profile);
+        return dst;
+    }
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
+        instructions().append(0);
+        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
+        instructions().append(profile);
+        return dst;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
 
-    // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
-    instructions().append(kill(dst));
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-    instructions().append(0);
-    instructions().append(0);
-    instructions().append(profile);
-    return dst;
+RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
+{
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        emitMove(variable.local(), value);
+        return value;
+        
+    case VarKind::DirectArgument:
+        emitOpcode(op_put_to_arguments);
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(value->index());
+        return value;
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
+        emitOpcode(op_put_to_scope);
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(value->index());
+        ScopeOffset offset;
+        if (variable.offset().isScope()) {
+            offset = variable.offset().scopeOffset();
+            instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
+        } else {
+            ASSERT(resolveType() != LocalClosureVar);
+            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
+        }
+        instructions().append(0);
+        instructions().append(!!offset ? offset.offset() : 0);
+        return value;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
 }
 
-RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode)
+RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
 {
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
+    RegisterID* scope;
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        scope = nullptr;
+        break;
+        
+    case VarKind::DirectArgument:
+        scope = argumentsRegister();
+        break;
+        
+    case VarKind::Scope:
+        scope = scopeRegister();
+        break;
+        
+    default:
+        scope = nullptr;
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
 
-    // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-    emitOpcode(op_put_to_scope);
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(value->index());
-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-    instructions().append(0);
-    instructions().append(0);
-    return value;
+    return emitPutToScope(scope, variable, value, ThrowIfNotFound);
 }
 
 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
-{ 
+{
     emitOpcode(op_instanceof);
     instructions().append(dst->index());
     instructions().append(value->index());
@@ -1301,16 +1507,6 @@ RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, co
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
-{
-    emitOpcode(op_get_arguments_length);
-    instructions().append(dst->index());
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(addConstant(propertyNames().length));
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
 {
     unsigned propertyIndex = addConstant(property);
@@ -1328,11 +1524,13 @@ RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& p
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
+
     return value;
 }
 
-RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
+RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
 {
+    ASSERT(!parseIndex(property));
     unsigned propertyIndex = addConstant(property);
 
     m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
@@ -1347,12 +1545,32 @@ RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identif
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
-    instructions().append(
-        property != m_vm->propertyNames->underscoreProto
-        && PropertyName(property).asIndex() == PropertyName::NotAnIndex);
+    instructions().append(putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto);
     return value;
 }
 
+void BytecodeGenerator::emitPutGetterById(RegisterID* base, const Identifier& property, RegisterID* getter)
+{
+    unsigned propertyIndex = addConstant(property);
+    m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
+
+    emitOpcode(op_put_getter_by_id);
+    instructions().append(base->index());
+    instructions().append(propertyIndex);
+    instructions().append(getter->index());
+}
+
+void BytecodeGenerator::emitPutSetterById(RegisterID* base, const Identifier& property, RegisterID* setter)
+{
+    unsigned propertyIndex = addConstant(property);
+    m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
+
+    emitOpcode(op_put_setter_by_id);
+    instructions().append(base->index());
+    instructions().append(propertyIndex);
+    instructions().append(setter->index());
+}
+
 void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter)
 {
     unsigned propertyIndex = addConstant(property);
@@ -1375,34 +1593,33 @@ RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base,
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
-{
-    UnlinkedArrayProfile arrayProfile = newArrayProfile();
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
-    instructions().append(kill(dst));
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(property->index());
-    instructions().append(arrayProfile);
-    instructions().append(profile);
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
 {
     for (size_t i = m_forInContextStack.size(); i > 0; i--) {
-        ForInContext& context = m_forInContextStack[i - 1];
-        if (context.propertyRegister == property) {
-            emitOpcode(op_get_by_pname);
-            instructions().append(dst->index());
-            instructions().append(base->index());
-            instructions().append(property->index());
-            instructions().append(context.expectedSubscriptRegister->index());
-            instructions().append(context.iterRegister->index());
-            instructions().append(context.indexRegister->index());
-            return dst;
+        ForInContext* context = m_forInContextStack[i - 1].get();
+        if (context->local() != property)
+            continue;
+
+        if (!context->isValid())
+            break;
+
+        if (context->type() == ForInContext::IndexedForInContextType) {
+            property = static_cast<IndexedForInContext*>(context)->index();
+            break;
         }
+
+        ASSERT(context->type() == ForInContext::StructureForInContextType);
+        StructureForInContext* structureContext = static_cast<StructureForInContext*>(context);
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname);
+        instructions().append(kill(dst));
+        instructions().append(base->index());
+        instructions().append(property->index());
+        instructions().append(structureContext->index()->index());
+        instructions().append(structureContext->enumerator()->index());
+        instructions().append(profile);
+        return dst;
     }
+
     UnlinkedArrayProfile arrayProfile = newArrayProfile();
     UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
     instructions().append(kill(dst));
@@ -1416,14 +1633,12 @@ RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, R
 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
 {
     UnlinkedArrayProfile arrayProfile = newArrayProfile();
-    if (m_isBuiltinFunction)
-        emitOpcode(op_put_by_val_direct);
-    else
-        emitOpcode(op_put_by_val);
+    emitOpcode(op_put_by_val);
     instructions().append(base->index());
     instructions().append(property->index());
     instructions().append(value->index());
     instructions().append(arrayProfile);
+
     return value;
 }
 
@@ -1457,24 +1672,25 @@ RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index,
 }
 
 RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
-{
-    RefPtr<RegisterID> func = newTemporary(); 
-
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-    emitOpcode(op_get_callee);
-    instructions().append(func->index());
-    instructions().append(0);
-
+{
     size_t begin = instructions().size();
     m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3);
 
+    m_codeBlock->addPropertyAccessInstruction(instructions().size());
     emitOpcode(op_create_this); 
     instructions().append(m_thisRegister.index()); 
-    instructions().append(func->index()); 
+    instructions().append(m_thisRegister.index()); 
+    instructions().append(0);
     instructions().append(0);
     return dst;
 }
 
+void BytecodeGenerator::emitTDZCheck(RegisterID* target)
+{
+    emitOpcode(op_check_tdz);
+    instructions().append(target->index());
+}
+
 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
 {
     size_t begin = instructions().size();
@@ -1502,6 +1718,16 @@ JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
     return stringInMap;
 }
 
+JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey& templateRegistryKey)
+{
+    JSTemplateRegistryKey*& templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator->value;
+    if (!templateRegistryKeyInMap) {
+        templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
+        addConstantValue(templateRegistryKeyInMap);
+    }
+    return templateRegistryKeyInMap;
+}
+
 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
 {
 #if !ASSERT_DISABLED
@@ -1558,30 +1784,17 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, CaptureMode captureMode, FunctionBodyNode* function)
-{
-    return emitNewFunctionInternal(dst, captureMode, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
-}
-
-RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
+RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
 {
-    FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
-    if (ptr.isNewEntry)
-        ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
-    return emitNewFunctionInternal(dst, NotCaptured, ptr.iterator->value, true);
+    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)));
 }
 
-RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, CaptureMode captureMode, unsigned index, bool doNullCheck)
+RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index)
 {
-    createActivationIfNecessary();
-    emitOpcode(captureMode == IsCaptured ? op_new_captured_func : op_new_func);
+    emitOpcode(op_new_func);
     instructions().append(dst->index());
+    instructions().append(scopeRegister()->index());
     instructions().append(index);
-    if (captureMode == IsCaptured) {
-        ASSERT(!doNullCheck);
-        instructions().append(watchableVariable(dst->index()));
-    } else
-        instructions().append(doNullCheck);
     return dst;
 }
 
@@ -1597,54 +1810,42 @@ RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExp
 {
     FunctionBodyNode* function = n->body();
     unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
-    
-    createActivationIfNecessary();
+
     emitOpcode(op_new_func_exp);
     instructions().append(r0->index());
+    instructions().append(scopeRegister()->index());
     instructions().append(index);
     return r0;
 }
 
-RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
-{
-    return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
-}
-
-void BytecodeGenerator::createArgumentsIfNecessary()
+RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name)
 {
-    if (m_codeType != FunctionCode)
-        return;
-    
-    if (!m_codeBlock->usesArguments())
-        return;
+    UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name);
 
-    if (shouldTearOffArgumentsEagerly())
-        return;
+    unsigned index = m_codeBlock->addFunctionExpr(executable);
 
-    emitOpcode(op_create_arguments);
-    instructions().append(m_codeBlock->argumentsRegister().offset());
-    ASSERT(!hasWatchableVariable(m_codeBlock->argumentsRegister().offset()));
+    emitOpcode(op_new_func_exp);
+    instructions().append(dst->index());
+    instructions().append(scopeRegister()->index());
+    instructions().append(index);
+    return dst;
 }
 
-void BytecodeGenerator::createActivationIfNecessary()
+RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
-    if (!m_activationRegister)
-        return;
-    emitOpcode(op_create_activation);
-    instructions().append(m_activationRegister->index());
+    return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
 }
 
 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
-    createActivationIfNecessary();
     return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
 }
 
 ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
 {
-    if (identifier == m_vm->propertyNames->Object)
+    if (identifier == m_vm->propertyNames->Object || identifier == m_vm->propertyNames->ObjectPrivateName)
         return ExpectObjectConstructor;
-    if (identifier == m_vm->propertyNames->Array)
+    if (identifier == m_vm->propertyNames->Array || identifier == m_vm->propertyNames->ArrayPrivateName)
         return ExpectArrayConstructor;
     return NoExpectedFunction;
 }
@@ -1731,10 +1932,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArguments(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedRegisterForArguments();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
             RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
             return emitCallVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
@@ -1787,9 +1985,9 @@ RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func
     return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
 }
 
-RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
-    return emitCallVarargs(op_construct_varargs, dst, func, 0, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+    return emitCallVarargs(op_construct_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
 }
     
 RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
@@ -1821,28 +2019,65 @@ RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst,
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
+void BytecodeGenerator::emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
+    RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition& position)
 {
-    if (m_activationRegister) {
-        emitOpcode(op_tear_off_activation);
-        instructions().append(m_activationRegister->index());
-    }
+    RefPtr<RegisterID> descriptorRegister = emitNewObject(newTemporary());
 
-    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) {
-        emitOpcode(op_tear_off_arguments);
-        instructions().append(m_codeBlock->argumentsRegister().offset());
-        instructions().append(m_activationRegister ? m_activationRegister->index() : emitLoad(0, JSValue())->index());
+    RefPtr<RegisterID> trueRegister = emitLoad(newTemporary(), true);
+    if (options & PropertyConfigurable)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().configurable, trueRegister.get(), PropertyNode::Unknown);
+    if (options & PropertyWritable)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().writable, trueRegister.get(), PropertyNode::Unknown);
+    else if (valueRegister) {
+        RefPtr<RegisterID> falseRegister = emitLoad(newTemporary(), false);
+        emitDirectPutById(descriptorRegister.get(), propertyNames().writable, falseRegister.get(), PropertyNode::Unknown);
     }
+    if (options & PropertyEnumerable)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().enumerable, trueRegister.get(), PropertyNode::Unknown);
+
+    if (valueRegister)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().value, valueRegister, PropertyNode::Unknown);
+    if (getterRegister)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().get, getterRegister, PropertyNode::Unknown);
+    if (setterRegister)
+        emitDirectPutById(descriptorRegister.get(), propertyNames().set, setterRegister, PropertyNode::Unknown);
+
+    RefPtr<RegisterID> definePropertyRegister = emitMoveLinkTimeConstant(newTemporary(), LinkTimeConstant::DefinePropertyFunction);
+
+    CallArguments callArguments(*this, nullptr, 3);
+    emitLoad(callArguments.thisRegister(), jsUndefined());
+    emitMove(callArguments.argumentRegister(0), newObj);
+    emitMove(callArguments.argumentRegister(1), propertyNameRegister);
+    emitMove(callArguments.argumentRegister(2), descriptorRegister.get());
+
+    emitCall(newTemporary(), definePropertyRegister.get(), NoExpectedFunction, callArguments, position, position, position);
+}
+
+RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
+{
+    if (isConstructor()) {
+        bool derived = constructorKind() == ConstructorKind::Derived;
+        if (derived && src->index() == m_thisRegister.index())
+            emitTDZCheck(src);
+
+        RefPtr<Label> isObjectLabel = newLabel();
+        emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectLabel.get());
+
+        if (derived) {
+            RefPtr<Label> isUndefinedLabel = newLabel();
+            emitJumpIfTrue(emitIsUndefined(newTemporary(), src), isUndefinedLabel.get());
+            emitThrowTypeError("Cannot return a non-object type in the constructor of a derived class.");
+            emitLabel(isUndefinedLabel.get());
+            if (constructorKind() == ConstructorKind::Derived)
+                emitTDZCheck(&m_thisRegister);
+        }
 
-    // Constructors use op_ret_object_or_this to check the result is an
-    // object, unless we can trivially determine the check is not
-    // necessary (currently, if the return value is 'this').
-    if (isConstructor() && (src->index() != m_thisRegister.index())) {
-        emitOpcode(op_ret_object_or_this);
-        instructions().append(src->index());
-        instructions().append(m_thisRegister.index());
-        return src;
+        emitUnaryNoDstOp(op_ret, &m_thisRegister);
+
+        emitLabel(isObjectLabel.get());
     }
+
     return emitUnaryNoDstOp(op_ret, src);
 }
 
@@ -1869,11 +2104,8 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArguments(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedRegisterForArguments();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
-            return emitConstructVarargs(dst, func, argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
         
         for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
@@ -1934,23 +2166,29 @@ void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
     instructions().append(src->index());
 }
 
-RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* scope)
+void BytecodeGenerator::emitGetScope()
+{
+    emitOpcode(op_get_scope);
+    instructions().append(scopeRegister()->index());
+}
+
+RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* dst, RegisterID* scope)
 {
     ControlFlowContext context;
     context.isFinallyBlock = false;
     m_scopeContextStack.append(context);
     m_localScopeDepth++;
 
-    createActivationIfNecessary();
-    return emitUnaryNoDstOp(op_push_with_scope, scope);
+    return emitUnaryOp(op_push_with_scope, dst, scope);
 }
 
-void BytecodeGenerator::emitPopScope()
+void BytecodeGenerator::emitPopScope(RegisterID* srcDst)
 {
     ASSERT(m_scopeContextStack.size());
     ASSERT(!m_scopeContextStack.last().isFinallyBlock);
 
     emitOpcode(op_pop_scope);
+    instructions().append(srcDst->index());
 
     m_scopeContextStack.removeLast();
     m_localScopeDepth--;
@@ -1982,6 +2220,33 @@ void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
     scope.isFinallyBlock = true;
     FinallyContext context = {
         finallyBlock,
+        nullptr,
+        nullptr,
+        static_cast<unsigned>(m_scopeContextStack.size()),
+        static_cast<unsigned>(m_switchContextStack.size()),
+        static_cast<unsigned>(m_forInContextStack.size()),
+        static_cast<unsigned>(m_tryContextStack.size()),
+        static_cast<unsigned>(m_labelScopes.size()),
+        m_finallyDepth,
+        m_localScopeDepth
+    };
+    scope.finallyContext = context;
+    m_scopeContextStack.append(scope);
+    m_finallyDepth++;
+}
+
+void BytecodeGenerator::pushIteratorCloseContext(RegisterID* iterator, ThrowableExpressionData* node)
+{
+    // Reclaim free label scopes.
+    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
+        m_labelScopes.removeLast();
+
+    ControlFlowContext scope;
+    scope.isFinallyBlock = true;
+    FinallyContext context = {
+        nullptr,
+        iterator,
+        node,
         static_cast<unsigned>(m_scopeContextStack.size()),
         static_cast<unsigned>(m_switchContextStack.size()),
         static_cast<unsigned>(m_forInContextStack.size()),
@@ -1999,6 +2264,21 @@ void BytecodeGenerator::popFinallyContext()
 {
     ASSERT(m_scopeContextStack.size());
     ASSERT(m_scopeContextStack.last().isFinallyBlock);
+    ASSERT(m_scopeContextStack.last().finallyContext.finallyBlock);
+    ASSERT(!m_scopeContextStack.last().finallyContext.iterator);
+    ASSERT(!m_scopeContextStack.last().finallyContext.enumerationNode);
+    ASSERT(m_finallyDepth > 0);
+    m_scopeContextStack.removeLast();
+    m_finallyDepth--;
+}
+
+void BytecodeGenerator::popIteratorCloseContext()
+{
+    ASSERT(m_scopeContextStack.size());
+    ASSERT(m_scopeContextStack.last().isFinallyBlock);
+    ASSERT(!m_scopeContextStack.last().finallyContext.finallyBlock);
+    ASSERT(m_scopeContextStack.last().finallyContext.iterator);
+    ASSERT(m_scopeContextStack.last().finallyContext.enumerationNode);
     ASSERT(m_finallyDepth > 0);
     m_scopeContextStack.removeLast();
     m_finallyDepth--;
@@ -2081,7 +2361,15 @@ LabelScopePtr BytecodeGenerator::continueTarget(const Identifier& name)
     return LabelScopePtr::null();
 }
 
-void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, ControlFlowContext* bottomScope)
+void BytecodeGenerator::allocateAndEmitScope()
+{
+    m_scopeRegister = addVar();
+    m_scopeRegister->ref();
+    m_codeBlock->setScopeRegister(scopeRegister()->virtualRegister());
+    emitGetScope();
+}
+
+void BytecodeGenerator::emitComplexPopScopes(RegisterID* scope, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
 {
     while (topScope > bottomScope) {
         // First we count the number of dynamic scopes we need to remove to get
@@ -2097,8 +2385,10 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
         if (nNormalScopes) {
             // We need to remove a number of dynamic scopes to get to the next
             // finally block
-            while (nNormalScopes--)
+            while (nNormalScopes--) {
                 emitOpcode(op_pop_scope);
+                instructions().append(scope->index());
+            }
 
             // If topScope == bottomScope then there isn't a finally block left to emit.
             if (topScope == bottomScope)
@@ -2107,7 +2397,7 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
         
         Vector<ControlFlowContext> savedScopeContextStack;
         Vector<SwitchInfo> savedSwitchContextStack;
-        Vector<ForInContext> savedForInContextStack;
+        Vector<std::unique_ptr<ForInContext>> savedForInContextStack;
         Vector<TryContext> poppedTryContexts;
         LabelScopeStore savedLabelScopes;
         while (topScope > bottomScope && topScope->isFinallyBlock) {
@@ -2134,7 +2424,7 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
                 m_switchContextStack.shrink(finallyContext.switchContextStackSize);
             }
             if (flipForIns) {
-                savedForInContextStack = m_forInContextStack;
+                savedForInContextStack.swap(m_forInContextStack);
                 m_forInContextStack.shrink(finallyContext.forInContextStackSize);
             }
             if (flipTries) {
@@ -2160,9 +2450,15 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
             int savedDynamicScopeDepth = m_localScopeDepth;
             m_localScopeDepth = finallyContext.dynamicScopeDepth;
             
-            // Emit the finally block.
-            emitNode(finallyContext.finallyBlock);
-            
+            if (finallyContext.finallyBlock) {
+                // Emit the finally block.
+                emitNode(finallyContext.finallyBlock);
+            } else {
+                // Emit the IteratorClose block.
+                ASSERT(finallyContext.iterator);
+                emitIteratorClose(finallyContext.iterator, finallyContext.enumerationNode);
+            }
+
             RefPtr<Label> afterFinally = emitLabel(newLabel().get());
             
             // Restore the state of the world.
@@ -2174,7 +2470,7 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
             if (flipSwitches)
                 m_switchContextStack = savedSwitchContextStack;
             if (flipForIns)
-                m_forInContextStack = savedForInContextStack;
+                m_forInContextStack.swap(savedForInContextStack);
             if (flipTries) {
                 ASSERT(m_tryContextStack.size() == finallyContext.tryContextStackSize);
                 for (unsigned i = poppedTryContexts.size(); i--;) {
@@ -2194,7 +2490,7 @@ void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, Contr
     }
 }
 
-void BytecodeGenerator::emitPopScopes(int targetScopeDepth)
+void BytecodeGenerator::emitPopScopes(RegisterID* scope, int targetScopeDepth)
 {
     ASSERT(scopeDepth() - targetScopeDepth >= 0);
 
@@ -2204,39 +2500,14 @@ void BytecodeGenerator::emitPopScopes(int targetScopeDepth)
         return;
 
     if (!m_finallyDepth) {
-        while (scopeDelta--)
+        while (scopeDelta--) {
             emitOpcode(op_pop_scope);
+            instructions().append(scope->index());
+        }
         return;
     }
 
-    emitComplexPopScopes(&m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
-}
-
-RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
-{
-    size_t begin = instructions().size();
-
-    emitOpcode(op_get_pnames);
-    instructions().append(dst->index());
-    instructions().append(base->index());
-    instructions().append(i->index());
-    instructions().append(size->index());
-    instructions().append(breakTarget->bind(begin, instructions().size()));
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
-{
-    size_t begin = instructions().size();
-
-    emitOpcode(op_next_pname);
-    instructions().append(dst->index());
-    instructions().append(base->index());
-    instructions().append(i->index());
-    instructions().append(size->index());
-    instructions().append(iter->index());
-    instructions().append(target->bind(begin, instructions().size()));
-    return dst;
+    emitComplexPopScopes(scope, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
 }
 
 TryData* BytecodeGenerator::pushTry(Label* start)
@@ -2244,6 +2515,7 @@ TryData* BytecodeGenerator::pushTry(Label* start)
     TryData tryData;
     tryData.target = newLabel();
     tryData.targetScopeDepth = UINT_MAX;
+    tryData.handlerType = HandlerType::Illegal;
     m_tryData.append(tryData);
     TryData* result = &m_tryData.last();
     
@@ -2256,7 +2528,7 @@ TryData* BytecodeGenerator::pushTry(Label* start)
     return result;
 }
 
-RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* targetRegister, Label* end)
+void BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* exceptionRegister, RegisterID* thrownValueRegister, Label* end, HandlerType handlerType)
 {
     m_usesExceptions = true;
     
@@ -2271,40 +2543,48 @@ RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID*
     
     emitLabel(tryRange.tryData->target.get());
     tryRange.tryData->targetScopeDepth = m_localScopeDepth;
+    tryRange.tryData->handlerType = handlerType;
 
     emitOpcode(op_catch);
-    instructions().append(targetRegister->index());
-    return targetRegister;
+    instructions().append(exceptionRegister->index());
+    instructions().append(thrownValueRegister->index());
 }
 
 void BytecodeGenerator::emitThrowReferenceError(const String& message)
 {
     emitOpcode(op_throw_static_error);
-    instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, message)))->index());
+    instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
     instructions().append(true);
 }
 
-void BytecodeGenerator::emitPushFunctionNameScope(const Identifier& property, RegisterID* value, unsigned attributes)
+void BytecodeGenerator::emitThrowTypeError(const String& message)
+{
+    emitOpcode(op_throw_static_error);
+    instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
+    instructions().append(false);
+}
+
+void BytecodeGenerator::emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
 {
     emitOpcode(op_push_name_scope);
-    instructions().append(addConstant(property));
+    instructions().append(dst->index());
     instructions().append(value->index());
-    instructions().append(attributes);
+    instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
+    instructions().append(JSNameScope::FunctionNameScope);
 }
 
-void BytecodeGenerator::emitPushCatchScope(const Identifier& property, RegisterID* value, unsigned attributes)
+void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes)
 {
-    createActivationIfNecessary();
-
     ControlFlowContext context;
     context.isFinallyBlock = false;
     m_scopeContextStack.append(context);
     m_localScopeDepth++;
 
     emitOpcode(op_push_name_scope);
-    instructions().append(addConstant(property));
+    instructions().append(dst->index());
     instructions().append(value->index());
-    instructions().append(attributes);
+    instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
+    instructions().append(JSNameScope::CatchScope);
 }
 
 void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
@@ -2429,16 +2709,11 @@ RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
     return newTemporary();
 }
 
-void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
-{
-    m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
-}
-
 bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
 {
-    RegisterID* registerID = local(ident).get();
-    if (!registerID || registerID->index() >= 0)
-         return 0;
+    RegisterID* registerID = variable(ident).local();
+    if (!registerID)
+        return false;
     return registerID->index() == CallFrame::argumentOffset(argumentNumber);
 }
 
@@ -2447,64 +2722,286 @@ void BytecodeGenerator::emitReadOnlyExceptionIfNeeded()
     if (!isStrictMode())
         return;
     emitOpcode(op_throw_static_error);
-    instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
+    instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
     instructions().append(false);
 }
     
 void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
 {
-    if (subjectNode->isResolveNode()
-        && willResolveToArguments(static_cast<ResolveNode*>(subjectNode)->identifier())
-        && !symbolTable().slowArguments()) {
-        RefPtr<RegisterID> index = emitLoad(newTemporary(), jsNumber(0));
+    RefPtr<RegisterID> subject = newTemporary();
+    emitNode(subject.get(), subjectNode);
+    RefPtr<RegisterID> iterator = emitGetById(newTemporary(), subject.get(), propertyNames().iteratorSymbol);
+    {
+        CallArguments args(*this, nullptr);
+        emitMove(args.thisRegister(), subject.get());
+        emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, node->divot(), node->divotStart(), node->divotEnd());
+    }
 
+    RefPtr<Label> loopDone = newLabel();
+    // RefPtr<Register> iterator's lifetime must be longer than IteratorCloseContext.
+    pushIteratorCloseContext(iterator.get(), node);
+    {
         LabelScopePtr scope = newLabelScope(LabelScope::Loop);
-        RefPtr<RegisterID> value = emitLoad(newTemporary(), jsUndefined());
-        
-        RefPtr<Label> loopCondition = newLabel();
+        RefPtr<RegisterID> value = newTemporary();
+        emitLoad(value.get(), jsUndefined());
+
+        emitJump(scope->continueTarget());
+
         RefPtr<Label> loopStart = newLabel();
-        emitJump(loopCondition.get());
         emitLabel(loopStart.get());
         emitLoopHint();
-        emitGetArgumentByVal(value.get(), uncheckedRegisterForArguments(), index.get());
+
+        RefPtr<Label> tryStartLabel = newLabel();
+        emitLabel(tryStartLabel.get());
+        TryData* tryData = pushTry(tryStartLabel.get());
         callBack(*this, value.get());
-    
+        emitJump(scope->continueTarget());
+
+        // IteratorClose sequence for throw-ed control flow.
+        {
+            RefPtr<Label> catchHere = emitLabel(newLabel().get());
+            RefPtr<RegisterID> exceptionRegister = newTemporary();
+            RefPtr<RegisterID> thrownValueRegister = newTemporary();
+            popTryAndEmitCatch(tryData, exceptionRegister.get(),
+                thrownValueRegister.get(), catchHere.get(), HandlerType::SynthesizedFinally);
+
+            RefPtr<Label> catchDone = newLabel();
+
+            RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
+            emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), catchDone.get());
+
+            RefPtr<Label> returnCallTryStart = newLabel();
+            emitLabel(returnCallTryStart.get());
+            TryData* returnCallTryData = pushTry(returnCallTryStart.get());
+
+            CallArguments returnArguments(*this, nullptr);
+            emitMove(returnArguments.thisRegister(), iterator.get());
+            emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd());
+
+            emitLabel(catchDone.get());
+            emitThrow(exceptionRegister.get());
+
+            // Absorb exception.
+            popTryAndEmitCatch(returnCallTryData, newTemporary(),
+                newTemporary(), catchDone.get(), HandlerType::SynthesizedFinally);
+            emitThrow(exceptionRegister.get());
+        }
+
         emitLabel(scope->continueTarget());
-        emitInc(index.get());
-        emitLabel(loopCondition.get());
-        RefPtr<RegisterID> length = emitGetArgumentsLength(newTemporary(), uncheckedRegisterForArguments());
-        emitJumpIfTrue(emitEqualityOp(op_less, newTemporary(), index.get(), length.get()), loopStart.get());
+        {
+            emitIteratorNext(value.get(), iterator.get(), node);
+            emitJumpIfTrue(emitGetById(newTemporary(), value.get(), propertyNames().done), loopDone.get());
+            emitGetById(value.get(), value.get(), propertyNames().value);
+            emitJump(loopStart.get());
+        }
+
         emitLabel(scope->breakTarget());
-        return;
     }
 
-    LabelScopePtr scope = newLabelScope(LabelScope::Loop);
-    RefPtr<RegisterID> subject = newTemporary();
-    emitNode(subject.get(), subjectNode);
-    RefPtr<RegisterID> iterator = emitGetById(newTemporary(), subject.get(), propertyNames().iteratorPrivateName);
+    // IteratorClose sequence for break-ed control flow.
+    popIteratorCloseContext();
+    emitIteratorClose(iterator.get(), node);
+    emitLabel(loopDone.get());
+}
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+RegisterID* BytecodeGenerator::emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode* taggedTemplate)
+{
+    TemplateRegistryKey::StringVector rawStrings;
+    TemplateRegistryKey::StringVector cookedStrings;
+
+    TemplateStringListNode* templateString = taggedTemplate->templateLiteral()->templateStrings();
+    for (; templateString; templateString = templateString->next()) {
+        rawStrings.append(templateString->value()->raw().impl());
+        cookedStrings.append(templateString->value()->cooked().impl());
+    }
+
+    RefPtr<RegisterID> getTemplateObject = nullptr;
+    Variable var = variable(propertyNames().getTemplateObjectPrivateName);
+    if (RegisterID* local = var.local())
+        getTemplateObject = emitMove(newTemporary(), local);
+    else {
+        getTemplateObject = newTemporary();
+        RefPtr<RegisterID> scope = newTemporary();
+        moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), var));
+        emitGetFromScope(getTemplateObject.get(), scope.get(), var, ThrowIfNotFound);
+    }
+
+    CallArguments arguments(*this, nullptr);
+    emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(TemplateRegistryKey(rawStrings, cookedStrings))));
+    return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd());
+}
+#endif
+
+RegisterID* BytecodeGenerator::emitGetEnumerableLength(RegisterID* dst, RegisterID* base)
+{
+    emitOpcode(op_get_enumerable_length);
+    instructions().append(dst->index());
+    instructions().append(base->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName)
+{
+    emitOpcode(op_has_generic_property);
+    instructions().append(dst->index());
+    instructions().append(base->index());
+    instructions().append(propertyName->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName)
+{
+    UnlinkedArrayProfile arrayProfile = newArrayProfile();
+    emitOpcode(op_has_indexed_property);
+    instructions().append(dst->index());
+    instructions().append(base->index());
+    instructions().append(propertyName->index());
+    instructions().append(arrayProfile);
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator)
+{
+    emitOpcode(op_has_structure_property);
+    instructions().append(dst->index());
+    instructions().append(base->index());
+    instructions().append(propertyName->index());
+    instructions().append(enumerator->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base)
+{
+    emitOpcode(op_get_property_enumerator);
+    instructions().append(dst->index());
+    instructions().append(base->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
+{
+    emitOpcode(op_enumerator_structure_pname);
+    instructions().append(dst->index());
+    instructions().append(enumerator->index());
+    instructions().append(index->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
+{
+    emitOpcode(op_enumerator_generic_pname);
+    instructions().append(dst->index());
+    instructions().append(enumerator->index());
+    instructions().append(index->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitToIndexString(RegisterID* dst, RegisterID* index)
+{
+    emitOpcode(op_to_index_string);
+    instructions().append(dst->index());
+    instructions().append(index->index());
+    return dst;
+}
+
+
+RegisterID* BytecodeGenerator::emitIsObject(RegisterID* dst, RegisterID* src)
+{
+    emitOpcode(op_is_object);
+    instructions().append(dst->index());
+    instructions().append(src->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitIsUndefined(RegisterID* dst, RegisterID* src)
+{
+    emitOpcode(op_is_undefined);
+    instructions().append(dst->index());
+    instructions().append(src->index());
+    return dst;
+}
+
+RegisterID* BytecodeGenerator::emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node)
+{
     {
-        CallArguments args(*this, 0);
-        emitMove(args.thisRegister(), subject.get());
-        emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, node->divot(), node->divotStart(), node->divotEnd());
+        RefPtr<RegisterID> next = emitGetById(newTemporary(), iterator, propertyNames().next);
+        CallArguments nextArguments(*this, nullptr);
+        emitMove(nextArguments.thisRegister(), iterator);
+        emitCall(dst, next.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd());
+    }
+    {
+        RefPtr<Label> typeIsObject = newLabel();
+        emitJumpIfTrue(emitIsObject(newTemporary(), dst), typeIsObject.get());
+        emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object."));
+        emitLabel(typeIsObject.get());
     }
-    RefPtr<RegisterID> iteratorNext = emitGetById(newTemporary(), iterator.get(), propertyNames().iteratorNextPrivateName);
+    return dst;
+}
+
+void BytecodeGenerator::emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node)
+{
+    RefPtr<Label> done = newLabel();
+    RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator, propertyNames().returnKeyword);
+    emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), done.get());
+
     RefPtr<RegisterID> value = newTemporary();
-    emitLoad(value.get(), jsUndefined());
-    
-    emitJump(scope->continueTarget());
-    
-    RefPtr<Label> loopStart = newLabel();
-    emitLabel(loopStart.get());
-    emitLoopHint();
-    callBack(*this, value.get());
-    emitLabel(scope->continueTarget());
-    CallArguments nextArguments(*this, 0, 1);
-    emitMove(nextArguments.thisRegister(), iterator.get());
-    emitMove(nextArguments.argumentRegister(0), value.get());
-    emitCall(value.get(), iteratorNext.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd());
-    RefPtr<RegisterID> result = newTemporary();
-    emitJumpIfFalse(emitEqualityOp(op_stricteq, result.get(), value.get(), emitLoad(0, JSValue(vm()->iterationTerminator.get()))), loopStart.get());
-    emitLabel(scope->breakTarget());
+    CallArguments returnArguments(*this, nullptr);
+    emitMove(returnArguments.thisRegister(), iterator);
+    emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd());
+    emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), done.get());
+    emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object."));
+    emitLabel(done.get());
+}
+
+void BytecodeGenerator::pushIndexedForInScope(RegisterID* localRegister, RegisterID* indexRegister)
+{
+    if (!localRegister)
+        return;
+    m_forInContextStack.append(std::make_unique<IndexedForInContext>(localRegister, indexRegister));
+}
+
+void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister)
+{
+    if (!localRegister)
+        return;
+    m_forInContextStack.removeLast();
+}
+
+void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
+{
+    if (!localRegister)
+        return;
+    m_forInContextStack.append(std::make_unique<StructureForInContext>(localRegister, indexRegister, propertyRegister, enumeratorRegister));
+}
+
+void BytecodeGenerator::popStructureForInScope(RegisterID* localRegister)
+{
+    if (!localRegister)
+        return;
+    m_forInContextStack.removeLast();
+}
+
+void BytecodeGenerator::invalidateForInContextForLocal(RegisterID* localRegister)
+{
+    // Lexically invalidating ForInContexts is kind of weak sauce, but it only occurs if 
+    // either of the following conditions is true:
+    // 
+    // (1) The loop iteration variable is re-assigned within the body of the loop.
+    // (2) The loop iteration variable is captured in the lexical scope of the function.
+    //
+    // These two situations occur sufficiently rarely that it's okay to use this style of 
+    // "analysis" to make iteration faster. If we didn't want to do this, we would either have 
+    // to perform some flow-sensitive analysis to see if/when the loop iteration variable was 
+    // reassigned, or we'd have to resort to runtime checks to see if the variable had been 
+    // reassigned from its original value.
+    for (size_t i = m_forInContextStack.size(); i > 0; i--) {
+        ForInContext* context = m_forInContextStack[i - 1].get();
+        if (context->local() != localRegister)
+            continue;
+        context->invalidate();
+        break;
+    }
 }
 
 } // namespace JSC
index 5e5ed61416e536b62dfc7cde2c0bdd1fc2a94811..1a9771ef107979c49f51a3943984e63181c84de3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) 2012 Igalia, S.L.
  *
@@ -43,6 +43,7 @@
 #include "Debugger.h"
 #include "Nodes.h"
 #include "StaticPropertyAnalyzer.h"
+#include "TemplateRegistryKey.h"
 #include "UnlinkedCodeBlock.h"
 
 #include <functional>
@@ -55,7 +56,7 @@
 namespace JSC {
 
     class Identifier;
-    class Label;
+    class JSTemplateRegistryKey;
 
     enum ExpectedFunction {
         NoExpectedFunction,
@@ -83,6 +84,8 @@ namespace JSC {
 
     struct FinallyContext {
         StatementNode* finallyBlock;
+        RegisterID* iterator;
+        ThrowableExpressionData* enumerationNode;
         unsigned scopeContextStackSize;
         unsigned switchContextStackSize;
         unsigned forInContextStackSize;
@@ -97,16 +100,82 @@ namespace JSC {
         FinallyContext finallyContext;
     };
 
-    struct ForInContext {
-        RefPtr<RegisterID> expectedSubscriptRegister;
-        RefPtr<RegisterID> iterRegister;
-        RefPtr<RegisterID> indexRegister;
-        RefPtr<RegisterID> propertyRegister;
+    class ForInContext {
+    public:
+        ForInContext(RegisterID* localRegister)
+            : m_localRegister(localRegister)
+            , m_isValid(true)
+        {
+        }
+
+        virtual ~ForInContext()
+        {
+        }
+
+        bool isValid() const { return m_isValid; }
+        void invalidate() { m_isValid = false; }
+
+        enum ForInContextType {
+            StructureForInContextType,
+            IndexedForInContextType
+        };
+        virtual ForInContextType type() const = 0;
+
+        RegisterID* local() const { return m_localRegister.get(); }
+
+    private:
+        RefPtr<RegisterID> m_localRegister;
+        bool m_isValid;
+    };
+
+    class StructureForInContext : public ForInContext {
+    public:
+        StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
+            : ForInContext(localRegister)
+            , m_indexRegister(indexRegister)
+            , m_propertyRegister(propertyRegister)
+            , m_enumeratorRegister(enumeratorRegister)
+        {
+        }
+
+        virtual ForInContextType type() const
+        {
+            return StructureForInContextType;
+        }
+
+        RegisterID* index() const { return m_indexRegister.get(); }
+        RegisterID* property() const { return m_propertyRegister.get(); }
+        RegisterID* enumerator() const { return m_enumeratorRegister.get(); }
+
+    private:
+        RefPtr<RegisterID> m_indexRegister;
+        RefPtr<RegisterID> m_propertyRegister;
+        RefPtr<RegisterID> m_enumeratorRegister;
+    };
+
+    class IndexedForInContext : public ForInContext {
+    public:
+        IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister)
+            : ForInContext(localRegister)
+            , m_indexRegister(indexRegister)
+        {
+        }
+
+        virtual ForInContextType type() const
+        {
+            return IndexedForInContextType;
+        }
+
+        RegisterID* index() const { return m_indexRegister.get(); }
+
+    private:
+        RefPtr<RegisterID> m_indexRegister;
     };
 
     struct TryData {
         RefPtr<Label> target;
         unsigned targetScopeDepth;
+        HandlerType handlerType;
     };
 
     struct TryContext {
@@ -114,39 +183,55 @@ namespace JSC {
         TryData* tryData;
     };
 
-    enum CaptureMode {
-        NotCaptured,
-        IsCaptured
-    };
-
-    class Local {
+    class Variable {
     public:
-        Local()
-            : m_local(0)
+        enum VariableKind { NormalVariable, SpecialVariable };
+
+        Variable()
+            : m_offset()
+            , m_local(nullptr)
+            , m_attributes(0)
+            , m_kind(NormalVariable)
+        {
+        }
+        
+        Variable(const Identifier& ident)
+            : m_ident(ident)
+            , m_local(nullptr)
             , m_attributes(0)
+            , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
         {
         }
 
-        Local(RegisterID* local, unsigned attributes, CaptureMode captureMode)
-            : m_local(local)
+        Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind)
+            : m_ident(ident)
+            , m_offset(offset)
+            , m_local(local)
             , m_attributes(attributes)
-            , m_isCaptured(captureMode == IsCaptured)
+            , m_kind(kind)
         {
         }
 
-        operator bool() { return m_local; }
-
-        RegisterID* get() { return m_local; }
-
-        bool isReadOnly() { return m_attributes & ReadOnly; }
+        // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
+        // a stack variable, a scoped variable in the local scope, or a variable captured in the
+        // direct arguments object.
+        bool isResolved() const { return !!m_offset; }
+        
+        const Identifier& ident() const { return m_ident; }
         
-        bool isCaptured() { return m_isCaptured; }
-        CaptureMode captureMode() { return isCaptured() ? IsCaptured : NotCaptured; }
+        VarOffset offset() const { return m_offset; }
+        bool isLocal() const { return m_offset.isStack(); }
+        RegisterID* local() const { return m_local; }
+
+        bool isReadOnly() const { return m_attributes & ReadOnly; }
+        bool isSpecial() const { return m_kind != NormalVariable; }
 
     private:
+        Identifier m_ident;
+        VarOffset m_offset;
         RegisterID* m_local;
         unsigned m_attributes;
-        bool m_isCaptured;
+        VariableKind m_kind;
     };
 
     struct TryRange {
@@ -155,40 +240,59 @@ namespace JSC {
         TryData* tryData;
     };
 
+    enum ProfileTypeBytecodeFlag {
+        ProfileTypeBytecodePutToScope,
+        ProfileTypeBytecodeGetFromScope,
+        ProfileTypeBytecodePutToLocalScope,
+        ProfileTypeBytecodeGetFromLocalScope,
+        ProfileTypeBytecodeHasGlobalID,
+        ProfileTypeBytecodeDoesNotHaveGlobalID,
+        ProfileTypeBytecodeFunctionArgument,
+        ProfileTypeBytecodeFunctionReturnStatement
+    };
+
     class BytecodeGenerator {
         WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_NONCOPYABLE(BytecodeGenerator);
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
         BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, ProfilerMode);
-        BytecodeGenerator(VM&, FunctionBodyNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode);
+        BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode);
         BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, ProfilerMode);
 
         ~BytecodeGenerator();
         
         VM* vm() const { return m_vm; }
+        ParserArena& parserArena() const { return m_scopeNode->parserArena(); }
         const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
 
-        bool isConstructor() { return m_codeBlock->isConstructor(); }
+        bool isConstructor() const { return m_codeBlock->isConstructor(); }
+#if ENABLE(ES6_CLASS_SYNTAX)
+        ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
+#else
+        ConstructorKind constructorKind() const { return ConstructorKind::None; }
+#endif
 
         ParserError generate();
 
         bool isArgumentNumber(const Identifier&, int);
 
-        void setIsNumericCompareFunction(bool isNumericCompareFunction);
-
-        bool willResolveToArguments(const Identifier&);
-        RegisterID* uncheckedRegisterForArguments();
-
-        bool isCaptured(int operand);
-        CaptureMode captureMode(int operand) { return isCaptured(operand) ? IsCaptured : NotCaptured; }
+        Variable variable(const Identifier&);
+        
+        // Ignores the possibility of intervening scopes.
+        Variable variablePerSymbolTable(const Identifier&);
+        
+        enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
+        void createVariable(const Identifier&, VarKind, ConstantMode, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
         
-        Local local(const Identifier&);
-        Local constLocal(const Identifier&);
-
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
+        RegisterID* argumentsRegister() { return m_argumentsRegister; }
+        RegisterID* newTarget() { return m_newTargetRegister; }
+
+        RegisterID* scopeRegister() { return m_scopeRegister; }
 
         // Returns the next available temporary register. Registers returned by
         // newTemporary require a modified form of reference counting: any
@@ -244,8 +348,6 @@ namespace JSC {
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse()) {
                 emitThrowExpressionTooDeepException();
                 return;
@@ -262,8 +364,6 @@ namespace JSC {
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse())
                 return emitThrowExpressionTooDeepException();
             return n->emitBytecode(*this, dst);
@@ -316,6 +416,7 @@ namespace JSC {
                 m_codeBlock->addExpressionInfo(instructionOffset, divotOffset, startOffset, endOffset, line, column);
         }
 
+
         ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
         {
             return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain() || rightHasAssignments) && !rightIsPure;
@@ -332,10 +433,14 @@ namespace JSC {
             return emitNode(n);
         }
 
+        void emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot);
+        void emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag, const Identifier*);
+
+        void emitProfileControlFlow(int);
+
         RegisterID* emitLoad(RegisterID* dst, bool);
-        RegisterID* emitLoad(RegisterID* dst, double);
         RegisterID* emitLoad(RegisterID* dst, const Identifier&);
-        RegisterID* emitLoad(RegisterID* dst, JSValue);
+        RegisterID* emitLoad(RegisterID* dst, JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
         RegisterID* emitLoadGlobalObject(RegisterID* dst);
 
         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
@@ -344,19 +449,22 @@ namespace JSC {
         RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
 
         RegisterID* emitCreateThis(RegisterID* dst);
+        void emitTDZCheck(RegisterID* target);
         RegisterID* emitNewObject(RegisterID* dst);
         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
 
-        RegisterID* emitNewFunction(RegisterID* dst, CaptureMode, FunctionBodyNode*);
-        RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
-        RegisterID* emitNewFunctionInternal(RegisterID* dst, CaptureMode, unsigned index, bool shouldNullCheck);
+        RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode*);
+        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index);
         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
+        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name);
         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
 
-        RegisterID* emitMove(RegisterID* dst, CaptureMode, RegisterID* src);
+        RegisterID* emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant);
+        RegisterID* emitMoveEmptyValue(RegisterID* dst);
         RegisterID* emitMove(RegisterID* dst, RegisterID* src);
 
         RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_number, dst, src); }
+        RegisterID* emitToString(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_string, dst, src); }
         RegisterID* emitInc(RegisterID* srcDst);
         RegisterID* emitDec(RegisterID* srcDst);
 
@@ -368,9 +476,8 @@ namespace JSC {
         RegisterID* emitInitGlobalConst(const Identifier&, RegisterID* value);
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
-        RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
-        RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value);
+        RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
@@ -378,6 +485,9 @@ namespace JSC {
         RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
         RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
+
+        void emitPutGetterById(RegisterID* base, const Identifier& property, RegisterID* getter);
+        void emitPutSetterById(RegisterID* base, const Identifier& property, RegisterID* setter);
         void emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter);
         
         ExpectedFunction expectedFunctionForIdentifier(const Identifier&);
@@ -385,8 +495,20 @@ namespace JSC {
         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
         RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
+        enum PropertyDescriptorOption {
+            PropertyConfigurable = 1,
+            PropertyWritable     = 1 << 1,
+            PropertyEnumerable   = 1 << 2,
+        };
+        void emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
+            RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&);
+
         void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack);
-        
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+        RegisterID* emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode*);
+#endif
+
         RegisterID* emitReturn(RegisterID* src);
         RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
 
@@ -395,9 +517,11 @@ namespace JSC {
         void emitToPrimitive(RegisterID* dst, RegisterID* src);
 
         ResolveType resolveType();
-        RegisterID* emitResolveScope(RegisterID* dst, const Identifier&);
-        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode);
-        RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode);
+        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
+        RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
+        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
+        RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode);
+        RegisterID* initializeVariable(const Variable&, RegisterID* value);
 
         PassRefPtr<Label> emitLabel(Label*);
         void emitLoopHint();
@@ -406,17 +530,31 @@ namespace JSC {
         PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
         PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
         PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
-        void emitPopScopes(int targetScopeDepth);
+        void emitPopScopes(RegisterID* srcDst, int targetScopeDepth);
 
-        RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget);
-        RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target);
+        RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
+        RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
+        RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
+        RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base);
+        RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base);
+        RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length);
+        RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator);
+        RegisterID* emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
+        RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
+        RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
+
+        RegisterID* emitIsObject(RegisterID* dst, RegisterID* src);
+        RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src);
+
+        RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node);
+        void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node);
 
         void emitReadOnlyExceptionIfNeeded();
 
         // Start a try block. 'start' must have been emitted.
         TryData* pushTry(Label* start);
         // End a try block. 'end' must have been emitted.
-        RegisterID* popTryAndEmitCatch(TryData*, RegisterID* targetRegister, Label* end);
+        void popTryAndEmitCatch(TryData*, RegisterID* exceptionRegister, RegisterID* thrownValueRegister, Label* end, HandlerType);
 
         void emitThrow(RegisterID* exc)
         { 
@@ -425,12 +563,14 @@ namespace JSC {
         }
 
         void emitThrowReferenceError(const String& message);
+        void emitThrowTypeError(const String& message);
 
-        void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, unsigned attributes);
-        void emitPushCatchScope(const Identifier& property, RegisterID* value, unsigned attributes);
+        void emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes);
+        void emitPushCatchScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes);
 
-        RegisterID* emitPushWithScope(RegisterID* scope);
-        void emitPopScope();
+        void emitGetScope();
+        RegisterID* emitPushWithScope(RegisterID* dst, RegisterID* scope);
+        void emitPopScope(RegisterID* srcDst);
 
         void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
 
@@ -439,17 +579,14 @@ namespace JSC {
 
         void pushFinallyContext(StatementNode* finallyBlock);
         void popFinallyContext();
+        void pushIteratorCloseContext(RegisterID* iterator, ThrowableExpressionData* enumerationNode);
+        void popIteratorCloseContext();
 
-        void pushOptimisedForIn(RegisterID* expectedSubscript, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister)
-        {
-            ForInContext context = { expectedSubscript, iter, index, propertyRegister };
-            m_forInContextStack.append(context);
-        }
-
-        void popOptimisedForIn()
-        {
-            m_forInContextStack.removeLast();
-        }
+        void pushIndexedForInScope(RegisterID* local, RegisterID* index);
+        void popIndexedForInScope(RegisterID* local);
+        void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
+        void popStructureForInScope(RegisterID* local);
+        void invalidateForInContextForLocal(RegisterID* local);
 
         LabelScopePtr breakTarget(const Identifier&);
         LabelScopePtr continueTarget(const Identifier&);
@@ -465,10 +602,12 @@ namespace JSC {
         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
         
         bool isBuiltinFunction() const { return m_isBuiltinFunction; }
-        
+
+        OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
+
     private:
-        friend class Label;
-        
+        Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&);
+
         void emitOpcode(OpcodeID);
         UnlinkedArrayAllocationProfile newArrayAllocationProfile();
         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
@@ -486,10 +625,12 @@ namespace JSC {
         ALWAYS_INLINE void rewindBinaryOp();
         ALWAYS_INLINE void rewindUnaryOp();
 
-        void emitComplexPopScopes(ControlFlowContext* topScope, ControlFlowContext* bottomScope);
+        void allocateAndEmitScope();
+        void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
 
         typedef HashMap<double, JSValue> NumberMap;
-        typedef HashMap<StringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
+        typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
+        typedef HashMap<TemplateRegistryKey, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
         
         // Helper for emitCall() and emitConstruct(). This works because the set of
         // expected functions have identical behavior for both call and construct
@@ -500,46 +641,35 @@ namespace JSC {
 
         RegisterID* newRegister();
 
-        // Adds a var slot and maps it to the name ident in symbolTable().
-        enum WatchMode { IsWatchable, NotWatchable };
-        RegisterID* addVar(const Identifier& ident, ConstantMode constantMode, WatchMode watchMode)
-        {
-            RegisterID* local;
-            addVar(ident, constantMode, watchMode, local);
-            return local;
-        }
-
-        // Ditto. Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used.
-        bool addVar(const Identifier&, ConstantMode, WatchMode, RegisterID*&);
-        
-        // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
+        // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
         RegisterID* addVar()
         {
             ++m_codeBlock->m_numVars;
-            return newRegister();
+            RegisterID* result = newRegister();
+            ASSERT(VirtualRegister(result->index()).toLocal() == m_codeBlock->m_numVars - 1);
+            result->ref(); // We should never free this slot.
+            return result;
         }
 
-        // Returns the index of the added var.
-        void addParameter(const Identifier&, int parameterIndex);
-        RegisterID* resolveCallee(FunctionBodyNode*);
-        void addCallee(FunctionBodyNode*, RegisterID*);
-
-        void preserveLastVar();
-
-        RegisterID& registerFor(int index)
+        // Initializes the stack form the parameter; does nothing for the symbol table.
+        RegisterID* initializeNextParameter();
+        UniquedStringImpl* visibleNameForParameter(DestructuringPatternNode*);
+        
+        RegisterID& registerFor(VirtualRegister reg)
         {
-            if (operandIsLocal(index))
-                return m_calleeRegisters[VirtualRegister(index).toLocal()];
+            if (reg.isLocal())
+                return m_calleeRegisters[reg.toLocal()];
 
-            if (index == JSStack::Callee)
+            if (reg.offset() == JSStack::Callee)
                 return m_calleeRegister;
 
             ASSERT(m_parameters.size());
-            return m_parameters[VirtualRegister(index).toArgument()];
+            return m_parameters[reg.toArgument()];
         }
 
+        bool hasConstant(const Identifier&) const;
         unsigned addConstant(const Identifier&);
-        RegisterID* addConstantValue(JSValue);
+        RegisterID* addConstantValue(JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
         RegisterID* addConstantEmptyValue();
         unsigned addRegExp(RegExp*);
 
@@ -550,13 +680,12 @@ namespace JSC {
             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction);
         }
 
-        RegisterID* emitInitLazyRegister(RegisterID*);
-        
-        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
-        
+
     public:
         JSString* addStringConstant(const Identifier&);
+        JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&);
 
         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
 
@@ -587,104 +716,79 @@ namespace JSC {
             return true;
         }
 
-        bool shouldTearOffArgumentsEagerly()
-        {
-            return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter();
-        }
-
         RegisterID* emitThrowExpressionTooDeepException();
 
-        void createArgumentsIfNecessary();
-        void createActivationIfNecessary();
-        RegisterID* createLazyRegisterIfNecessary(RegisterID*);
-        
-        unsigned watchableVariable(int operand)
-        {
-            VirtualRegister reg(operand);
-            if (!reg.isLocal())
-                return UINT_MAX;
-            if (static_cast<size_t>(reg.toLocal()) >= m_watchableVariables.size())
-                return UINT_MAX;
-            Identifier& ident = m_watchableVariables[reg.toLocal()];
-            if (ident.isNull())
-                return UINT_MAX;
-            return addConstant(ident);
-        }
-        
-        bool hasWatchableVariable(int operand)
-        {
-            return watchableVariable(operand) != UINT_MAX;
-        }
-        
+    private:
         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
 
         bool m_shouldEmitDebugHooks;
         bool m_shouldEmitProfileHooks;
 
-        SymbolTable* m_symbolTable;
+        SymbolTable* m_symbolTable { nullptr };
 
-        ScopeNode* m_scopeNode;
+        ScopeNode* const m_scopeNode;
         Strong<UnlinkedCodeBlock> m_codeBlock;
 
         // Some of these objects keep pointers to one another. They are arranged
         // to ensure a sane destruction order that avoids references to freed memory.
-        HashSet<RefPtr<StringImpl>, IdentifierRepHash> m_functions;
+        HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_functions;
         RegisterID m_ignoredResultRegister;
         RegisterID m_thisRegister;
         RegisterID m_calleeRegister;
-        RegisterID* m_activationRegister;
-        RegisterID* m_emptyValueRegister;
-        RegisterID* m_globalObjectRegister;
-        Vector<Identifier, 16> m_watchableVariables;
+        RegisterID* m_scopeRegister { nullptr };
+        RegisterID* m_argumentsRegister { nullptr };
+        RegisterID* m_lexicalEnvironmentRegister { nullptr };
+        RegisterID* m_emptyValueRegister { nullptr };
+        RegisterID* m_globalObjectRegister { nullptr };
+        RegisterID* m_newTargetRegister { nullptr };
+        RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
+
         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
         SegmentedVector<RegisterID, 32> m_calleeRegisters;
         SegmentedVector<RegisterID, 32> m_parameters;
         SegmentedVector<Label, 32> m_labels;
         LabelScopeStore m_labelScopes;
-        RefPtr<RegisterID> m_lastVar;
-        int m_finallyDepth;
-        int m_localScopeDepth;
-        CodeType m_codeType;
+        int m_finallyDepth { 0 };
+        int m_localScopeDepth { 0 };
+        const CodeType m_codeType;
 
         Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
         Vector<SwitchInfo> m_switchContextStack;
-        Vector<ForInContext> m_forInContextStack;
+        Vector<std::unique_ptr<ForInContext>> m_forInContextStack;
         Vector<TryContext> m_tryContextStack;
-        Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters;
+        Vector<std::pair<RefPtr<RegisterID>, const DestructuringPatternNode*>> m_destructuringParameters;
+        enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };
+        Vector<std::pair<FunctionBodyNode*, FunctionVariableType>> m_functionsToInitialize;
+        bool m_needToInitializeArguments { false };
         
         Vector<TryRange> m_tryRanges;
         SegmentedVector<TryData, 8> m_tryData;
 
-        int m_firstConstantIndex;
-        int m_nextConstantOffset;
-        unsigned m_globalConstantIndex;
-
-        int m_globalVarStorageOffset;
+        int m_nextConstantOffset { 0 };
 
-        int m_firstLazyFunction;
-        int m_lastLazyFunction;
-        HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int>> m_lazyFunctions;
         typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
         FunctionOffsetMap m_functionOffsets;
         
         // Constant pool
         IdentifierMap m_identifierMap;
+
+        typedef HashMap<EncodedJSValueWithRepresentation, unsigned, EncodedJSValueWithRepresentationHash, EncodedJSValueWithRepresentationHashTraits> JSValueMap;
         JSValueMap m_jsValueMap;
-        NumberMap m_numberMap;
         IdentifierStringMap m_stringMap;
+        TemplateRegistryKeyMap m_templateRegistryKeyMap;
 
-        StaticPropertyAnalyzer m_staticPropertyAnalyzer;
+        StaticPropertyAnalyzer m_staticPropertyAnalyzer { &m_instructions };
 
         VM* m_vm;
 
-        OpcodeID m_lastOpcodeID;
+        OpcodeID m_lastOpcodeID = op_end;
 #ifndef NDEBUG
-        size_t m_lastOpcodePosition;
+        size_t m_lastOpcodePosition { 0 };
 #endif
 
-        bool m_usesExceptions;
-        bool m_expressionTooDeep;
-        bool m_isBuiltinFunction;
+        bool m_usesExceptions { false };
+        bool m_expressionTooDeep { false };
+        bool m_isBuiltinFunction { false };
     };
 
 }
index 81cdf3cc40ecb5f2e017827a045e5d18a2701118..b76c648bf1fc59ccca805ef826a917182da4ac07 100644 (file)
@@ -41,7 +41,7 @@ namespace JSC {
 
     class Label {
     public:
-        explicit Label(BytecodeGenerator* generator)
+        explicit Label(BytecodeGenerator& generator)
             : m_refCount(0)
             , m_location(invalidLocation)
             , m_generator(generator)
@@ -82,7 +82,7 @@ namespace JSC {
 
         int m_refCount;
         unsigned m_location;
-        BytecodeGenerator* m_generator;
+        BytecodeGenerator& m_generator;
         mutable JumpVector m_unresolvedJumps;
     };
 
index 0e81cfa6693c5a895d67a2623a3b0a9d5e0a77c6..cfd3ef1ff6e80752d980d690147c4507507e5f61 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
-*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
 *  Copyright (C) 2007 Maks Orlovich
 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
 #include "LabelScope.h"
 #include "Lexer.h"
 #include "JSCInlines.h"
+#include "JSTemplateRegistryKey.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "RegExpCache.h"
 #include "RegExpObject.h"
 #include "SamplingTool.h"
 #include "StackAlignment.h"
+#include "TemplateRegistryKey.h"
 #include <wtf/Assertions.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/Threading.h>
@@ -122,6 +124,15 @@ JSValue StringNode::jsValue(BytecodeGenerator& generator) const
     return generator.addStringConstant(m_value);
 }
 
+// ------------------------------ NumberNode ----------------------------------
+
+RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    if (dst == generator.ignoredResult())
+        return nullptr;
+    return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
+}
+
 // ------------------------------ RegExpNode -----------------------------------
 
 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -135,31 +146,184 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived)
+        generator.emitTDZCheck(generator.thisRegister());
+
     if (dst == generator.ignoredResult())
         return 0;
-    return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
+
+    RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(generator.thisRegister(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        static const unsigned thisLength = 4;
+        generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + thisLength, -1));
+    }
+    return result;
+}
+
+// ------------------------------ SuperNode -------------------------------------
+
+RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    if (dst == generator.ignoredResult())
+        return 0;
+
+    RegisterID callee;
+    callee.setIndex(JSStack::Callee);
+
+    RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
+    RefPtr<RegisterID> protoParent = generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
+    return generator.emitGetById(generator.finalDestination(dst), protoParent.get(), generator.propertyNames().constructor);
+}
+
+static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
+{
+    RegisterID callee;
+    callee.setIndex(JSStack::Callee);
+
+    RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
+    return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
 }
 
 // ------------------------------ ResolveNode ----------------------------------
 
 bool ResolveNode::isPure(BytecodeGenerator& generator) const
 {
-    return generator.local(m_ident).get();
+    return generator.variable(m_ident).offset().isStack();
 }
 
 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
-            return 0;
-        return generator.moveToDestinationIfNeeded(dst, local.get());
+            return nullptr;
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
+        }
+        return generator.moveToDestinationIfNeeded(dst, local);
     }
     
     JSTextPosition divot = m_start + m_ident.length();
     generator.emitExpressionInfo(divot, m_start, divot);
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
-    return generator.emitGetFromScope(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RegisterID* finalDest = generator.finalDestination(dst);
+    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+        generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
+    }
+    return result;
+}
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+// ------------------------------ TemplateStringNode -----------------------------------
+
+RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    if (dst == generator.ignoredResult())
+        return nullptr;
+    return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked())));
+}
+
+// ------------------------------ TemplateLiteralNode -----------------------------------
+
+RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    if (!m_templateExpressions) {
+        TemplateStringNode* templateString = m_templateStrings->value();
+        ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
+        return generator.emitNode(dst, templateString);
+    }
+
+    Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
+
+    TemplateStringListNode* templateString = m_templateStrings;
+    TemplateExpressionListNode* templateExpression = m_templateExpressions;
+    for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
+        // Evaluate TemplateString.
+        if (!templateString->value()->cooked().isEmpty()) {
+            temporaryRegisters.append(generator.newTemporary());
+            generator.emitNode(temporaryRegisters.last().get(), templateString->value());
+        }
+
+        // Evaluate Expression.
+        temporaryRegisters.append(generator.newTemporary());
+        generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
+        generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
+    }
+
+    // Evaluate tail TemplateString.
+    if (!templateString->value()->cooked().isEmpty()) {
+        temporaryRegisters.append(generator.newTemporary());
+        generator.emitNode(temporaryRegisters.last().get(), templateString->value());
+    }
+
+    return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
+}
+
+// ------------------------------ TaggedTemplateNode -----------------------------------
+
+RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ExpectedFunction expectedFunction = NoExpectedFunction;
+    RefPtr<RegisterID> tag = nullptr;
+    RefPtr<RegisterID> base = nullptr;
+    if (!m_tag->isLocation()) {
+        tag = generator.newTemporary();
+        tag = generator.emitNode(tag.get(), m_tag);
+    } else if (m_tag->isResolveNode()) {
+        ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
+        const Identifier& identifier = resolve->identifier();
+        expectedFunction = generator.expectedFunctionForIdentifier(identifier);
+
+        Variable var = generator.variable(identifier);
+        if (RegisterID* local = var.local())
+            tag = generator.emitMove(generator.newTemporary(), local);
+        else {
+            tag = generator.newTemporary();
+            base = generator.newTemporary();
+
+            JSTextPosition newDivot = divotStart() + identifier.length();
+            generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
+            generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
+            generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
+        }
+    } else if (m_tag->isBracketAccessorNode()) {
+        BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
+        base = generator.newTemporary();
+        base = generator.emitNode(base.get(), bracket->base());
+        RefPtr<RegisterID> property = generator.emitNode(bracket->subscript());
+        tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
+    } else {
+        ASSERT(m_tag->isDotAccessorNode());
+        DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
+        base = generator.newTemporary();
+        base = generator.emitNode(base.get(), dot->base());
+        tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
+    }
+
+    RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
+
+    unsigned expressionsCount = 0;
+    for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
+        ++expressionsCount;
+
+    CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
+    if (base)
+        generator.emitMove(callArguments.thisRegister(), base.get());
+    else
+        generator.emitLoad(callArguments.thisRegister(), jsUndefined());
+
+    unsigned argumentIndex = 0;
+    generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
+    for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
+        generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
+
+    return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
 }
+#endif
 
 // ------------------------------ ArrayNode ------------------------------------
 
@@ -232,7 +396,7 @@ bool ArrayNode::isSimpleArray() const
     return true;
 }
 
-ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPosition) const
+ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
 {
     ASSERT(!m_elision && !m_optional);
     ElementNode* ptr = m_element;
@@ -241,12 +405,12 @@ ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPos
     JSTokenLocation location;
     location.line = lineNumber;
     location.startOffset = startPosition;
-    ArgumentListNode* head = new (vm) ArgumentListNode(location, ptr->value());
+    ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
     ArgumentListNode* tail = head;
     ptr = ptr->next();
     for (; ptr; ptr = ptr->next()) {
         ASSERT(!ptr->elision());
-        tail = new (vm) ArgumentListNode(location, tail, ptr->value());
+        tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
     }
     return head;
 }
@@ -255,49 +419,59 @@ ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPos
 
 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-     if (!m_list) {
-         if (dst == generator.ignoredResult())
-             return 0;
-         return generator.emitNewObject(generator.finalDestination(dst));
-     }
-     return generator.emitNode(dst, m_list);
+    if (!m_list) {
+        if (dst == generator.ignoredResult())
+            return 0;
+        return generator.emitNewObject(generator.finalDestination(dst));
+    }
+    RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
+    generator.emitNode(newObj.get(), m_list);
+    return generator.moveToDestinationIfNeeded(dst, newObj.get());
 }
 
 // ------------------------------ PropertyListNode -----------------------------
 
+static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
+{
+    generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
+}
+
 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> newObj = generator.tempDestination(dst);
-    
-    generator.emitNewObject(newObj.get());
-    
     // Fast case: this loop just handles regular value properties.
     PropertyListNode* p = this;
-    for (; p && p->m_node->m_type == PropertyNode::Constant; p = p->m_next) {
-        if (p->m_node->m_name) {
-            generator.emitDirectPutById(newObj.get(), *p->m_node->name(), generator.emitNode(p->m_node->m_assign));
-            continue;
-        }
-        RefPtr<RegisterID> propertyName = generator.emitNode(p->m_node->m_expression);
-        generator.emitDirectPutByVal(newObj.get(), propertyName.get(), generator.emitNode(p->m_node->m_assign));
-    }
+    for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
+        emitPutConstantProperty(generator, dst, *p->m_node);
 
     // Were there any get/set properties?
     if (p) {
+        // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
+        // a computed property, just emit everything as that may override previous values.
+        bool hasComputedProperty = false;
+
         typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
-        typedef HashMap<StringImpl*, GetterSetterPair> GetterSetterMap;
+        typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
         GetterSetterMap map;
 
         // Build a map, pairing get/set values together.
         for (PropertyListNode* q = p; q; q = q->m_next) {
             PropertyNode* node = q->m_node;
-            if (node->m_type == PropertyNode::Constant)
+            if (node->m_type & PropertyNode::Computed) {
+                hasComputedProperty = true;
+                break;
+            }
+            if (node->m_type & PropertyNode::Constant)
                 continue;
 
-            GetterSetterPair pair(node, static_cast<PropertyNode*>(0));
+            // Duplicates are possible.
+            GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
             GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
-            if (!result.isNewEntry)
-                result.iterator->value.second = node;
+            if (!result.isNewEntry) {
+                if (result.iterator->value.first->m_type == node->m_type)
+                    result.iterator->value.first = node;
+                else
+                    result.iterator->value.second = node;
+            }
         }
 
         // Iterate over the remaining properties in the list.
@@ -305,20 +479,28 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
             PropertyNode* node = p->m_node;
 
             // Handle regular values.
-            if (node->m_type == PropertyNode::Constant) {
-                if (node->name()) {
-                    generator.emitDirectPutById(newObj.get(), *node->name(), generator.emitNode(node->m_assign));
-                    continue;
-                }
-                RefPtr<RegisterID> propertyName = generator.emitNode(p->m_node->m_expression);
-                generator.emitDirectPutByVal(newObj.get(), propertyName.get(), generator.emitNode(p->m_node->m_assign));
+            if (node->m_type & PropertyNode::Constant) {
+                emitPutConstantProperty(generator, dst, *node);
                 continue;
             }
-            
+
             RegisterID* value = generator.emitNode(node->m_assign);
+            bool isClassProperty = node->needsSuperBinding();
+            if (isClassProperty)
+                emitPutHomeObject(generator, value, dst);
+
+            ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
+
+            // This is a get/set property which may be overridden by a computed property later.
+            if (hasComputedProperty) {
+                if (node->m_type & PropertyNode::Getter)
+                    generator.emitPutGetterById(dst, *node->name(), value);
+                else
+                    generator.emitPutSetterById(dst, *node->name(), value);
+                continue;
+            }
 
-            // This is a get/set property, find its entry in the map.
-            ASSERT(node->m_type == PropertyNode::Getter || node->m_type == PropertyNode::Setter);
+            // This is a get/set property pair.
             GetterSetterMap::iterator it = map.find(node->name()->impl());
             ASSERT(it != map.end());
             GetterSetterPair& pair = it->value;
@@ -326,75 +508,129 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
             // Was this already generated as a part of its partner?
             if (pair.second == node)
                 continue;
-    
+
             // Generate the paired node now.
             RefPtr<RegisterID> getterReg;
             RefPtr<RegisterID> setterReg;
+            RegisterID* secondReg = nullptr;
 
-            if (node->m_type == PropertyNode::Getter) {
+            if (node->m_type & PropertyNode::Getter) {
                 getterReg = value;
                 if (pair.second) {
-                    ASSERT(pair.second->m_type == PropertyNode::Setter);
+                    ASSERT(pair.second->m_type & PropertyNode::Setter);
                     setterReg = generator.emitNode(pair.second->m_assign);
+                    secondReg = setterReg.get();
                 } else {
                     setterReg = generator.newTemporary();
                     generator.emitLoad(setterReg.get(), jsUndefined());
                 }
             } else {
-                ASSERT(node->m_type == PropertyNode::Setter);
+                ASSERT(node->m_type & PropertyNode::Setter);
                 setterReg = value;
                 if (pair.second) {
-                    ASSERT(pair.second->m_type == PropertyNode::Getter);
+                    ASSERT(pair.second->m_type & PropertyNode::Getter);
                     getterReg = generator.emitNode(pair.second->m_assign);
+                    secondReg = getterReg.get();
                 } else {
                     getterReg = generator.newTemporary();
                     generator.emitLoad(getterReg.get(), jsUndefined());
                 }
             }
 
-            generator.emitPutGetterSetter(newObj.get(), *node->name(), getterReg.get(), setterReg.get());
+            ASSERT(!pair.second || isClassProperty == pair.second->needsSuperBinding());
+            if (isClassProperty && pair.second)
+                emitPutHomeObject(generator, secondReg, dst);
+
+            if (isClassProperty) {
+                RefPtr<RegisterID> propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node->name());
+                generator.emitCallDefineProperty(dst, propertyNameRegister.get(),
+                    nullptr, getterReg.get(), setterReg.get(), BytecodeGenerator::PropertyConfigurable, m_position);
+            } else
+                generator.emitPutGetterSetter(dst, *node->name(), getterReg.get(), setterReg.get());
         }
     }
 
-    return generator.moveToDestinationIfNeeded(dst, newObj.get());
+    return dst;
+}
+
+void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
+{
+    RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
+    if (node.needsSuperBinding()) {
+        emitPutHomeObject(generator, value.get(), newObj);
+
+        RefPtr<RegisterID> propertyNameRegister;
+        if (node.name())
+            propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
+        else
+            propertyNameRegister = generator.emitNode(node.m_expression);
+
+        generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
+            value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
+        return;
+    }
+    if (const auto* identifier = node.name()) {
+        Optional<uint32_t> optionalIndex = parseIndex(*identifier);
+        if (!optionalIndex) {
+            generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
+            return;
+        }
+
+        RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
+        generator.emitDirectPutByVal(newObj, index.get(), value.get());
+        return;
+    }
+    RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
+    generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
 }
 
 // ------------------------------ BracketAccessorNode --------------------------------
 
 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (m_base->isResolveNode() 
-        && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        RefPtr<RegisterID> property = generator.emitNode(m_subscript);
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property.get());
+    if (m_base->isSuperNode()) {
+        // FIXME: Should we generate the profiler info?
+        if (m_subscript->isString()) {
+            const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
+            return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id);
+        }
+        return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
+    }
+
+    RegisterID* ret;
+    RegisterID* finalDest = generator.finalDestination(dst);
+
+    if (m_subscript->isString()) {
+        RefPtr<RegisterID> base = generator.emitNode(m_base);
+        ret = generator.emitGetById(finalDest, base.get(), static_cast<StringNode*>(m_subscript)->value());
+    } else {
+        RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
+        RegisterID* property = generator.emitNode(m_subscript);
+        ret = generator.emitGetByVal(finalDest, base.get(), property);
     }
 
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
-    RegisterID* property = generator.emitNode(m_subscript);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
+
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
 }
 
 // ------------------------------ DotAccessorNode --------------------------------
 
 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (m_ident == generator.propertyNames().length) {
-        if (!m_base->isResolveNode())
-            goto nonArgumentsPath;
-        ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
-        if (!generator.willResolveToArguments(resolveNode->identifier()))
-            goto nonArgumentsPath;
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments());
-    }
-
-nonArgumentsPath:
-    RefPtr<RegisterID> base = generator.emitNode(m_base);
+    RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    return generator.emitGetById(generator.finalDestination(dst), base.get(), m_ident);
+    RegisterID* finalDest = generator.finalDestination(dst);
+    RegisterID* ret = generator.emitGetById(finalDest, base.get(), m_ident);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
 }
 
 // ------------------------------ ArgumentListNode -----------------------------
@@ -417,6 +653,7 @@ RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
     RefPtr<RegisterID> func = generator.emitNode(m_expr);
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
     CallArguments callArguments(generator, m_args);
+    generator.emitMove(callArguments.thisRegister(), func.get());
     return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
 }
 
@@ -449,8 +686,9 @@ CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argume
 
 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(generator.propertyNames().eval)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(generator.propertyNames().eval);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
@@ -460,8 +698,10 @@ RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, Reg
     CallArguments callArguments(generator, m_args);
     JSTextPosition newDivot = divotStart() + 4;
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval);
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound);
+    generator.moveToDestinationIfNeeded(
+        callArguments.thisRegister(),
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
 }
 
@@ -472,8 +712,21 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re
     RefPtr<RegisterID> func = generator.emitNode(m_expr);
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
     CallArguments callArguments(generator, m_args);
+    if (m_expr->isSuperNode()) {
+        ASSERT(generator.isConstructor());
+        ASSERT(generator.constructorKind() == ConstructorKind::Derived);
+        generator.emitMove(callArguments.thisRegister(), generator.newTarget());
+        RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        generator.emitMove(generator.thisRegister(), ret);
+        return ret;
+    }
     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
-    return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
 }
 
 // ------------------------------ FunctionCallResolveNode ----------------------------------
@@ -482,14 +735,20 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
 {
     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
 
-    if (Local local = generator.local(m_ident)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         // This passes NoExpectedFunction because we expect that if the function is in a
         // local variable, then it's not one of our built-in constructors.
-        return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+        }
+        return ret;
     }
 
     RefPtr<RegisterID> func = generator.newTemporary();
@@ -498,23 +757,87 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
 
     JSTextPosition newDivot = divotStart() + m_ident.length();
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    generator.emitResolveScope(callArguments.thisRegister(), m_ident);
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound);
-    return generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    generator.moveToDestinationIfNeeded(
+        callArguments.thisRegister(),
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
+    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
+}
+
+// ------------------------------ BytecodeIntrinsicNode ----------------------------------
+
+RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    return (this->*m_emitter)(generator, dst);
+}
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> base = generator.emitNode(node);
+    node = node->m_next;
+    RefPtr<RegisterID> index = generator.emitNode(node);
+    node = node->m_next;
+    RefPtr<RegisterID> value = generator.emitNode(node);
+
+    ASSERT(!node->m_next);
+
+    return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
+}
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> src = generator.emitNode(node);
+    ASSERT(!node->m_next);
+
+    return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
 }
 
 // ------------------------------ FunctionCallBracketNode ----------------------------------
 
 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base);
-    RefPtr<RegisterID> property = generator.emitNode(m_subscript);
-    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
-    RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
+    bool baseIsSuper = m_base->isSuperNode();
+    bool subscriptIsString = m_subscript->isString();
+
+    RefPtr<RegisterID> base;
+    if (baseIsSuper)
+        base = emitSuperBaseForCallee(generator);
+    else {
+        if (subscriptIsString)
+            base = generator.emitNode(m_base);
+        else
+            base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
+    }
+
+    RefPtr<RegisterID> function;
+    if (subscriptIsString) {
+        generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
+        function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
+    } else {
+        RefPtr<RegisterID> property = generator.emitNode(m_subscript);
+        generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
+        function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
+    }
+
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
     CallArguments callArguments(generator, m_args);
-    generator.emitMove(callArguments.thisRegister(), base.get());
-    return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (baseIsSuper)
+        generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
+    else
+        generator.emitMove(callArguments.thisRegister(), base.get());
+    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
 }
 
 // ------------------------------ FunctionCallDotNode ----------------------------------
@@ -524,21 +847,19 @@ RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, Regi
     RefPtr<RegisterID> function = generator.tempDestination(dst);
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
     CallArguments callArguments(generator, m_args);
-    generator.emitNode(callArguments.thisRegister(), m_base);
+    bool baseIsSuper = m_base->isSuperNode();
+    if (baseIsSuper)
+        generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
+    else
+        generator.emitNode(callArguments.thisRegister(), m_base);
     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
-    generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
-    return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
-}
-
-static RegisterID* getArgumentByVal(BytecodeGenerator& generator, ExpressionNode* base, RegisterID* property, RegisterID* dst, JSTextPosition divot, JSTextPosition divotStart, JSTextPosition divotEnd)
-{
-    if (base->isResolveNode()
-        && generator.willResolveToArguments(static_cast<ResolveNode*>(base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        generator.emitExpressionInfo(divot, divotStart, divotEnd);
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
+    generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident);
+    RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
-    return nullptr;
+    return ret;
 }
 
 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -561,15 +882,10 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
                 profileHookRegister = generator.newTemporary();
             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
             ExpressionNode* subject = spread->expression();
-            RefPtr<RegisterID> thisRegister = getArgumentByVal(generator, subject, generator.emitLoad(0, jsNumber(0)), 0, spread->divot(), spread->divotStart(), spread->divotEnd());
             RefPtr<RegisterID> argumentsRegister;
-            if (thisRegister)
-                argumentsRegister = generator.uncheckedRegisterForArguments();
-            else {
-                argumentsRegister = generator.emitNode(subject);
-                generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
-                thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
-            }
+            argumentsRegister = generator.emitNode(subject);
+            generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
+            RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
             generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
             ArgumentListNode* oldList = m_args->m_listNode;
@@ -597,6 +913,10 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
         }
         generator.emitLabel(end.get());
     }
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return returnValue.get();
 }
 
@@ -659,7 +979,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
             } else if (m_args->m_listNode->m_next) {
                 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
                 ASSERT(!m_args->m_listNode->m_next->m_next);
-                m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0);
+                m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
                 CallArguments callArguments(generator, m_args);
                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
@@ -687,10 +1007,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
         RefPtr<RegisterID> argsRegister;
         ArgumentListNode* args = m_args->m_listNode->m_next;
-        if (args->m_expr->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(args->m_expr)->identifier()) && !generator.symbolTable().slowArguments())
-            argsRegister = generator.uncheckedRegisterForArguments();
-        else
-            argsRegister = generator.emitNode(args->m_expr);
+        argsRegister = generator.emitNode(args->m_expr);
 
         // Function.prototype.apply ignores extra arguments, but we still
         // need to evaluate them for side effects.
@@ -707,6 +1024,10 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
         generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
         generator.emitLabel(end.get());
     }
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return returnValue.get();
 }
 
@@ -735,12 +1056,13 @@ RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* d
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
-        } else if (local.isCaptured()) {
+            localReg = generator.emitMove(generator.tempDestination(dst), local);
+        } else if (generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
             ASSERT(dst != localReg);
             RefPtr<RegisterID> tempDstSrc = generator.newTemporary();
@@ -748,16 +1070,23 @@ RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* d
             generator.emitMove(tempDstSrc.get(), localReg.get());
             emitIncOrDec(generator, tempDstSrc.get(), m_operator);
             generator.emitMove(localReg.get(), tempDstSrc.get());
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return tempDst.get();
         }
         return emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), ident);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+
     return oldValue.get();
 }
 
@@ -779,6 +1108,10 @@ RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* d
     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitPutByVal(base.get(), property.get(), value.get());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, oldValue);
 }
 
@@ -799,6 +1132,10 @@ RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitPutById(base.get(), ident, value.get());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, oldValue);
 }
 
@@ -814,19 +1151,20 @@ RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
         return emitDot(generator, dst);
 
     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
-        ? "Postfix ++ operator applied to value that is not a reference."
-        : "Postfix -- operator applied to value that is not a reference.");
+        ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
+        : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
 }
 
 // ------------------------------ DeleteResolveNode -----------------------------------
 
 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (generator.local(m_ident).get())
+    Variable var = generator.variable(m_ident);
+    if (var.local())
         return generator.emitLoad(generator.finalDestination(dst), false);
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RefPtr<RegisterID> base = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
+    RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
 }
 
@@ -838,6 +1176,8 @@ RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
+    if (m_base->isSuperNode())
+        return emitThrowReferenceError(generator, "Cannot delete a super property");
     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
 }
 
@@ -848,6 +1188,8 @@ RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
+    if (m_base->isSuperNode())
+        return emitThrowReferenceError(generator, "Cannot delete a super property");
     return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
 }
 
@@ -873,18 +1215,19 @@ RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst
     return generator.emitLoad(dst, jsUndefined());
 }
 
-// ------------------------------ TypeOfValueNode -----------------------------------
+// ------------------------------ TypeOfResolveNode -----------------------------------
 
 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
             return 0;
-        return generator.emitTypeOf(generator.finalDestination(dst), local.get());
+        return generator.emitTypeOf(generator.finalDestination(dst), local);
     }
 
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
     if (dst == generator.ignoredResult())
         return 0;
     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
@@ -910,16 +1253,19 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
-        } else if (local.isCaptured()) {
+        } else if (generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
             generator.emitMove(tempDst.get(), localReg.get());
             emitIncOrDec(generator, tempDst.get(), m_operator);
             generator.emitMove(localReg.get(), tempDst.get());
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
         }
         emitIncOrDec(generator, localReg.get(), m_operator);
@@ -927,10 +1273,14 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), ident);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     emitIncOrDec(generator, value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, value.get());
 }
 
@@ -950,6 +1300,10 @@ RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* ds
     emitIncOrDec(generator, value, m_operator);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitPutByVal(base.get(), property.get(), value);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, propDst.get());
 }
 
@@ -968,6 +1322,10 @@ RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
     emitIncOrDec(generator, value, m_operator);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitPutById(base.get(), ident, value);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, propDst.get());
 }
 
@@ -983,8 +1341,8 @@ RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
         return emitDot(generator, dst);
 
     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
-        ? "Prefix ++ operator applied to value that is not a reference."
-        : "Prefix -- operator applied to value that is not a reference.");
+        ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
+        : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
 }
 
 // ------------------------------ Unary Operation Nodes -----------------------------------
@@ -1216,7 +1574,7 @@ RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
     }
 
     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
-    bool wasTypeof = generator.m_lastOpcodeID == op_typeof;
+    bool wasTypeof = generator.lastOpcodeID() == op_typeof;
     RefPtr<RegisterID> src2 = generator.emitNode(right);
     generator.emitExpressionInfo(position(), position(), position());
     if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
@@ -1335,14 +1693,18 @@ RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, Register
     generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
     generator.emitLabel(beforeThen.get());
 
+    generator.emitProfileControlFlow(m_expr1->startOffset());
     generator.emitNode(newDst.get(), m_expr1);
     generator.emitJump(afterElse.get());
 
     generator.emitLabel(beforeElse.get());
+    generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
     generator.emitNode(newDst.get(), m_expr2);
 
     generator.emitLabel(afterElse.get());
 
+    generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
+
     return newDst.get();
 }
 
@@ -1407,60 +1769,80 @@ static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& gen
 
 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    JSTextPosition newDivot = divotStart() + m_ident.length();
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         }
         
-        if (local.isCaptured()
+        if (generator.vm()->typeProfiler()
             || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
             RefPtr<RegisterID> result = generator.newTemporary();
-            generator.emitMove(result.get(), local.get());
+            generator.emitMove(result.get(), local);
             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-            generator.emitMove(local.get(), result.get());
+            generator.emitMove(local, result.get());
+            generator.invalidateForInContextForLocal(local);
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, result.get());
         }
         
-        RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
-    JSTextPosition newDivot = divotStart() + m_ident.length();
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
-    return generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return returnResult;
 }
 
 // ------------------------------ AssignResolveNode -----------------------------------
 
 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return generator.emitNode(dst, m_right);
         }
-        if (local.isCaptured()) {
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
             generator.emitNode(tempDst.get(), m_right);
-            generator.emitMove(local.get(), tempDst.get());
+            generator.emitMove(local, tempDst.get());
+            generator.invalidateForInContextForLocal(local);
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
         }
-        RegisterID* result = generator.emitNode(local.get(), m_right);
+        RegisterID* result = generator.emitNode(local, m_right);
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     if (dst == generator.ignoredResult())
         dst = 0;
     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    return generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    } 
+    return returnResult;
 }
 
 // ------------------------------ AssignDotNode -----------------------------------
@@ -1473,6 +1855,10 @@ RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
     generator.emitPutById(base.get(), m_ident, forwardResult);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, forwardResult);
 }
 
@@ -1487,14 +1873,19 @@ RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, Regist
     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast<JSC::Operator>(m_operator), OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    return generator.emitPutById(base.get(), m_ident, updatedValue);
+    RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
+    return ret;
 }
 
 // ------------------------------ AssignErrorNode -----------------------------------
 
 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
-    return emitThrowReferenceError(generator, "Left side of assignment is not a reference.");
+    return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
 }
 
 // ------------------------------ AssignBracketNode -----------------------------------
@@ -1508,7 +1899,16 @@ RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
-    generator.emitPutByVal(base.get(), property.get(), forwardResult);
+
+    if (m_subscript->isString())
+        generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
+    else
+        generator.emitPutByVal(base.get(), property.get(), forwardResult);
+
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return generator.moveToDestinationIfNeeded(dst, forwardResult);
 }
 
@@ -1525,6 +1925,10 @@ RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, Re
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitPutByVal(base.get(), property.get(), updatedValue);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
 
     return updatedValue;
 }
@@ -1533,10 +1937,10 @@ RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, Re
 
 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    ASSERT(m_expressions.size() > 1);
-    for (size_t i = 0; i < m_expressions.size() - 1; i++)
-        generator.emitNode(generator.ignoredResult(), m_expressions[i]);
-    return generator.emitNode(dst, m_expressions.last());
+    CommaNode* node = this;
+    for (; node && node->next(); node = node->next())
+        generator.emitNode(generator.ignoredResult(), node->m_expr);
+    return generator.emitNode(dst, node->m_expr);
 }
 
 // ------------------------------ ConstDeclNode ------------------------------------
@@ -1544,17 +1948,19 @@ RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
 {
     // FIXME: This code does not match the behavior of const in Firefox.
-    if (Local local = generator.constLocal(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (!m_init)
-            return local.get();
+            return local;
 
-        if (local.isCaptured()) {
+        // FIXME: Maybe call emitExpressionInfo here.
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.newTemporary();
             generator.emitNode(tempDst.get(), m_init);
-            return generator.emitMove(local.get(), tempDst.get());
+            return generator.emitMove(local, tempDst.get());
         }
         
-        return generator.emitNode(local.get(), m_init);
+        return generator.emitNode(local, m_init);
     }
 
     RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
@@ -1562,12 +1968,24 @@ RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
     if (generator.codeType() == GlobalCode)
         return generator.emitInitGlobalConst(m_ident, value.get());
 
-    if (generator.codeType() != EvalCode)
-        return value.get();
+    if (generator.codeType() != EvalCode) {
+        // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
+        // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
+        // behavior that JSC has had for a long time.
+        
+        ASSERT(generator.codeType() == FunctionCode);
+        
+        var = generator.variablePerSymbolTable(m_ident);
+        if (!var.isResolved())
+            return value.get();
+        
+        RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
+        return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
+    }
 
     // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
-    RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
-    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
 }
 
 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
@@ -1592,15 +2010,13 @@ void ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 
 inline StatementNode* SourceElements::lastStatement() const
 {
-    size_t size = m_statements.size();
-    return size ? m_statements[size - 1] : 0;
+    return m_tail;
 }
 
 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    size_t size = m_statements.size();
-    for (size_t i = 0; i < size; ++i)
-        generator.emitNode(dst, m_statements[i]);
+    for (StatementNode* statement = m_head; statement; statement = statement->next())
+        generator.emitNode(dst, statement);
 }
 
 // ------------------------------ BlockNode ------------------------------------
@@ -1610,7 +2026,7 @@ inline StatementNode* BlockNode::lastStatement() const
     return m_statements ? m_statements->lastStatement() : 0;
 }
 
-inline StatementNode* BlockNode::singleStatement() const
+StatementNode* BlockNode::singleStatement() const
 {
     return m_statements ? m_statements->singleStatement() : 0;
 }
@@ -1654,6 +2070,28 @@ void VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
     generator.emitNode(m_expr);
 }
 
+// ------------------------------ EmptyVarExpression ----------------------------
+
+RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+    if (!generator.vm()->typeProfiler())
+        return nullptr;
+
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local())
+        generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
+    else {
+        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+    }
+
+    generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
+
+    // It's safe to return null here because this node will always be a child node of VarStatementNode which ignores our return value.
+    return nullptr;
+}
+
 // ------------------------------ IfElseNode ---------------------------------------
 
 static inline StatementNode* singleStatement(StatementNode* statementNode)
@@ -1708,6 +2146,7 @@ void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
     generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
     generator.emitLabel(beforeThen.get());
+    generator.emitProfileControlFlow(m_ifBlock->startOffset());
 
     if (!didFoldIfBlock) {
         generator.emitNode(dst, m_ifBlock);
@@ -1717,10 +2156,14 @@ void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
     generator.emitLabel(beforeElse.get());
 
-    if (m_elseBlock)
+    if (m_elseBlock) {
+        generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
         generator.emitNode(dst, m_elseBlock);
+    }
 
     generator.emitLabel(afterElse.get());
+    StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
+    generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
 }
 
 // ------------------------------ DoWhileNode ----------------------------------
@@ -1750,12 +2193,13 @@ void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
     RefPtr<Label> topOfLoop = generator.newLabel();
 
-    generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->startOffset(), m_expr->lineStartOffset());
+    generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
 
     generator.emitLabel(topOfLoop.get());
     generator.emitLoopHint();
     
+    generator.emitProfileControlFlow(m_statement->startOffset());
     generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->continueTarget());
@@ -1764,6 +2208,8 @@ void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
 
     generator.emitLabel(scope->breakTarget());
+
+    generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
 }
 
 // ------------------------------ ForNode --------------------------------------
@@ -1783,6 +2229,7 @@ void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
     generator.emitLabel(topOfLoop.get());
     generator.emitLoopHint();
+    generator.emitProfileControlFlow(m_statement->startOffset());
 
     generator.emitNode(dst, m_statement);
 
@@ -1797,131 +2244,275 @@ void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
         generator.emitJump(topOfLoop.get());
 
     generator.emitLabel(scope->breakTarget());
+    generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
 }
 
 // ------------------------------ ForInNode ------------------------------------
 
-void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
 {
-    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
-
-    if (!m_lexpr->isAssignmentLocation()) {
-        emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
-        return;
+    if (m_lexpr->isResolveNode()) {
+        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
+        return generator.variable(ident).local();
     }
 
-    generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
+    if (m_lexpr->isDestructuringNode()) {
+        DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
+        auto binding = assignNode->bindings();
+        if (!binding->isBindingNode())
+            return nullptr;
 
-    RefPtr<RegisterID> base = generator.newTemporary();
-    generator.emitNode(base.get(), m_expr);
-    RefPtr<RegisterID> i = generator.newTemporary();
-    RefPtr<RegisterID> size = generator.newTemporary();
-    RefPtr<RegisterID> expectedSubscript;
-    RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget());
-    generator.emitJump(scope->continueTarget());
+        auto simpleBinding = static_cast<BindingNode*>(binding);
+        const Identifier& ident = simpleBinding->boundProperty();
+        Variable var = generator.variable(ident);
+        if (var.isSpecial())
+            return nullptr;
+        return var.local();
+    }
 
-    RefPtr<Label> loopStart = generator.newLabel();
-    generator.emitLabel(loopStart.get());
-    generator.emitLoopHint();
+    return nullptr;
+}
 
-    RegisterID* propertyName;
-    bool optimizedForinAccess = false;
+void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
+{
     if (m_lexpr->isResolveNode()) {
         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-        Local local = generator.local(ident);
-        if (!local.get()) {
-            propertyName = generator.newTemporary();
-            RefPtr<RegisterID> protect = propertyName;
+        Variable var = generator.variable(ident);
+        if (RegisterID* local = var.local())
+            generator.emitMove(local, propertyName);
+        else {
             if (generator.isStrictMode())
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
+            RegisterID* scope = generator.emitResolveScope(nullptr, var);
             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
-        } else {
-            expectedSubscript = generator.newTemporary();
-            propertyName = expectedSubscript.get();
-            generator.emitMove(local.get(), propertyName);
-            generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), local.get());
-            optimizedForinAccess = true;
+            generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+            if (generator.vm()->typeProfiler())
+                generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         }
-    } else if (m_lexpr->isDotAccessorNode()) {
+        if (generator.vm()->typeProfiler())
+            generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
+        return;
+    }
+    if (m_lexpr->isDotAccessorNode()) {
         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
         const Identifier& ident = assignNode->identifier();
-        propertyName = generator.newTemporary();
-        RefPtr<RegisterID> protect = propertyName;
         RegisterID* base = generator.emitNode(assignNode->base());
-
         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
         generator.emitPutById(base, ident, propertyName);
-    } else if (m_lexpr->isBracketAccessorNode()) {
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+        }
+        return;
+    }
+    if (m_lexpr->isBracketAccessorNode()) {
         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
-        propertyName = generator.newTemporary();
-        RefPtr<RegisterID> protect = propertyName;
         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
         RegisterID* subscript = generator.emitNode(assignNode->subscript());
-        
         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
         generator.emitPutByVal(base.get(), subscript, propertyName);
-    } else {
-        ASSERT(m_lexpr->isDeconstructionNode());
-        DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+        }
+        return;
+    }
+
+    if (m_lexpr->isDestructuringNode()) {
+        DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
         auto binding = assignNode->bindings();
-        if (binding->isBindingNode()) {
-            auto simpleBinding = static_cast<BindingNode*>(binding);
-            Identifier ident = simpleBinding->boundProperty();
-            Local local = generator.local(ident);
-            propertyName = local.get();
-            if (!propertyName || local.isCaptured())
-                goto genericBinding;
-            expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
-            generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
-            optimizedForinAccess = true;
-            goto completedSimpleBinding;
-        } else {
-        genericBinding:
-            propertyName = generator.newTemporary();
-            RefPtr<RegisterID> protect(propertyName);
+        if (!binding->isBindingNode()) {
             assignNode->bindings()->bindValue(generator, propertyName);
+            return;
         }
-        completedSimpleBinding:
-        ;
+
+        auto simpleBinding = static_cast<BindingNode*>(binding);
+        const Identifier& ident = simpleBinding->boundProperty();
+        Variable var = generator.variable(ident);
+        if (!var.local() || var.isSpecial()) {
+            assignNode->bindings()->bindValue(generator, propertyName);
+            return;
+        }
+        generator.emitMove(var.local(), propertyName);
+        if (generator.vm()->typeProfiler())
+            generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
+        return;
     }
 
-    generator.emitNode(dst, m_statement);
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    if (!m_lexpr->isAssignmentLocation()) {
+        emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
+        return;
+    }
 
-    if (optimizedForinAccess)
-        generator.popOptimisedForIn();
+    RefPtr<Label> end = generator.newLabel();
 
-    generator.emitLabel(scope->continueTarget());
-    generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
-    generator.emitLabel(scope->breakTarget());
+
+    RefPtr<RegisterID> base = generator.newTemporary();
+    RefPtr<RegisterID> length;
+    RefPtr<RegisterID> enumerator;
+    generator.emitNode(base.get(), m_expr);
+    RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
+    RefPtr<RegisterID> enumeratorIndex;
+
+    int profilerStartOffset = m_statement->startOffset();
+    int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
+
+    enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
+
+    // Indexed property loop.
+    {
+        LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
+        RefPtr<Label> loopStart = generator.newLabel();
+        RefPtr<Label> loopEnd = generator.newLabel();
+
+        length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
+        RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
+        RefPtr<RegisterID> propertyName = generator.newTemporary();
+
+        generator.emitLabel(loopStart.get());
+        generator.emitLoopHint();
+
+        RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
+        generator.emitJumpIfFalse(result.get(), loopEnd.get());
+        generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
+        generator.emitJumpIfFalse(result.get(), scope->continueTarget());
+
+        generator.emitToIndexString(propertyName.get(), i.get());
+        this->emitLoopHeader(generator, propertyName.get());
+
+        generator.emitProfileControlFlow(profilerStartOffset);
+
+        generator.pushIndexedForInScope(local.get(), i.get());
+        generator.emitNode(dst, m_statement);
+        generator.popIndexedForInScope(local.get());
+
+        generator.emitProfileControlFlow(profilerEndOffset);
+
+        generator.emitLabel(scope->continueTarget());
+        generator.emitInc(i.get());
+        generator.emitJump(loopStart.get());
+
+        generator.emitLabel(scope->breakTarget());
+        generator.emitJump(end.get());
+        generator.emitLabel(loopEnd.get());
+    }
+
+    // Structure property loop.
+    {
+        LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
+        RefPtr<Label> loopStart = generator.newLabel();
+        RefPtr<Label> loopEnd = generator.newLabel();
+
+        enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
+        RefPtr<RegisterID> propertyName = generator.newTemporary();
+        generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
+
+        generator.emitLabel(loopStart.get());
+        generator.emitLoopHint();
+
+        RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
+        generator.emitJumpIfTrue(result.get(), loopEnd.get());
+        generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
+        generator.emitJumpIfFalse(result.get(), scope->continueTarget());
+
+        this->emitLoopHeader(generator, propertyName.get());
+
+        generator.emitProfileControlFlow(profilerStartOffset);
+
+        generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
+        generator.emitNode(dst, m_statement);
+        generator.popStructureForInScope(local.get());
+
+        generator.emitProfileControlFlow(profilerEndOffset);
+
+        generator.emitLabel(scope->continueTarget());
+        generator.emitInc(enumeratorIndex.get());
+        generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
+        generator.emitJump(loopStart.get());
+        
+        generator.emitLabel(scope->breakTarget());
+        generator.emitJump(end.get());
+        generator.emitLabel(loopEnd.get());
+    }
+
+    // Generic property loop.
+    {
+        LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
+        RefPtr<Label> loopStart = generator.newLabel();
+        RefPtr<Label> loopEnd = generator.newLabel();
+
+        RefPtr<RegisterID> propertyName = generator.newTemporary();
+
+        generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
+
+        generator.emitLabel(loopStart.get());
+        generator.emitLoopHint();
+
+        RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
+        generator.emitJumpIfTrue(result.get(), loopEnd.get());
+
+        generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
+        generator.emitJumpIfFalse(result.get(), scope->continueTarget());
+
+        this->emitLoopHeader(generator, propertyName.get());
+
+        generator.emitProfileControlFlow(profilerStartOffset);
+
+        generator.emitNode(dst, m_statement);
+
+        generator.emitLabel(scope->continueTarget());
+        generator.emitInc(enumeratorIndex.get());
+        generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
+        generator.emitJump(loopStart.get());
+
+        generator.emitLabel(scope->breakTarget());
+        generator.emitJump(end.get());
+        generator.emitLabel(loopEnd.get());
+    }
+
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
+    generator.emitLabel(end.get());
+    generator.emitProfileControlFlow(profilerEndOffset);
+}
+
+void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    this->emitMultiLoopBytecode(generator, dst);
 }
 
 // ------------------------------ ForOfNode ------------------------------------
 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (!m_lexpr->isAssignmentLocation()) {
-        emitThrowReferenceError(generator, "Left side of for-of statement is not a reference.");
+        emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
         return;
     }
-    
-    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
-    
+
     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
     auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
     {
         if (m_lexpr->isResolveNode()) {
             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-            if (Local local = generator.local(ident))
-                generator.emitMove(local.get(), value);
+            Variable var = generator.variable(ident);
+            if (RegisterID* local = var.local())
+                generator.emitMove(local, value);
             else {
                 if (generator.isStrictMode())
                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
+                RegisterID* scope = generator.emitResolveScope(nullptr, var);
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+                generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+                if (generator.vm()->typeProfiler())
+                    generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
             }
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
         } else if (m_lexpr->isDotAccessorNode()) {
             DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
             const Identifier& ident = assignNode->identifier();
@@ -1929,6 +2520,10 @@ void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
             
             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
             generator.emitPutById(base.get(), ident, value);
+            if (generator.vm()->typeProfiler()) {
+                generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+                generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+            }
         } else if (m_lexpr->isBracketAccessorNode()) {
             BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
@@ -1936,14 +2531,20 @@ void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
             
             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
             generator.emitPutByVal(base.get(), subscript, value);
+            if (generator.vm()->typeProfiler()) {
+                generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+                generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+            }
         } else {
-            ASSERT(m_lexpr->isDeconstructionNode());
-            DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);
+            ASSERT(m_lexpr->isDestructuringNode());
+            DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
             assignNode->bindings()->bindValue(generator, value);
         }
+        generator.emitProfileControlFlow(m_statement->startOffset());
         generator.emitNode(dst, m_statement);
     };
     generator.emitEnumeration(this, m_expr, extractor);
+    generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
 }
 
 // ------------------------------ ContinueNode ---------------------------------
@@ -1969,8 +2570,10 @@ void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
     LabelScopePtr scope = generator.continueTarget(m_ident);
     ASSERT(scope);
 
-    generator.emitPopScopes(scope->scopeDepth());
+    generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
     generator.emitJump(scope->continueTarget());
+
+    generator.emitProfileControlFlow(endOffset());
 }
 
 // ------------------------------ BreakNode ------------------------------------
@@ -1996,8 +2599,10 @@ void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
     LabelScopePtr scope = generator.breakTarget(m_ident);
     ASSERT(scope);
 
-    generator.emitPopScopes(scope->scopeDepth());
+    generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
     generator.emitJump(scope->breakTarget());
+
+    generator.emitProfileControlFlow(endOffset());
 }
 
 // ------------------------------ ReturnNode -----------------------------------
@@ -2011,13 +2616,22 @@ void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
         dst = 0;
 
     RefPtr<RegisterID> returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     if (generator.scopeDepth()) {
         returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
-        generator.emitPopScopes(0);
+        generator.emitPopScopes(generator.scopeRegister(), 0);
     }
 
     generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
     generator.emitReturn(returnRegister.get());
+    generator.emitProfileControlFlow(endOffset()); 
+    // Emitting an unreachable return here is needed in case this op_profile_control_flow is the 
+    // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
+    if (generator.vm()->controlFlowProfiler())
+        generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
 }
 
 // ------------------------------ WithNode -------------------------------------
@@ -2028,15 +2642,16 @@ void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
     RefPtr<RegisterID> scope = generator.emitNode(m_expr);
     generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
-    generator.emitPushWithScope(scope.get());
+    generator.emitPushWithScope(generator.scopeRegister(), scope.get());
     generator.emitNode(dst, m_statement);
-    generator.emitPopScope();
+    generator.emitPopScope(generator.scopeRegister());
 }
 
 // ------------------------------ CaseClauseNode --------------------------------
 
 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitProfileControlFlow(m_startOffset);
     if (!m_statements)
         return;
     m_statements->emitBytecode(generator, dst);
@@ -2206,6 +2821,7 @@ void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     m_block->emitBytecodeForBlock(generator, r0.get(), dst);
 
     generator.emitLabel(scope->breakTarget());
+    generator.emitProfileControlFlow(endOffset());
 }
 
 // ------------------------------ LabelNode ------------------------------------
@@ -2233,6 +2849,8 @@ void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     generator.emitThrow(expr.get());
+
+    generator.emitProfileControlFlow(endOffset()); 
 }
 
 // ------------------------------ TryNode --------------------------------------
@@ -2263,17 +2881,20 @@ void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
         // Uncaught exception path: the catch block.
         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
-        RefPtr<RegisterID> exceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), here.get());
+        RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
+        RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
+        generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), here.get(), HandlerType::Catch);
         
         if (m_finallyBlock) {
             // If the catch block throws an exception and we have a finally block, then the finally
             // block should "catch" that exception.
             tryData = generator.pushTry(here.get());
         }
-        
-        generator.emitPushCatchScope(m_exceptionIdent, exceptionRegister.get(), DontDelete);
+
+        generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
+        generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
         generator.emitNode(dst, m_catchBlock);
-        generator.emitPopScope();
+        generator.emitPopScope(generator.scopeRegister());
         generator.emitLabel(catchEndLabel.get());
     }
 
@@ -2284,17 +2905,27 @@ void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
         RefPtr<Label> finallyEndLabel = generator.newLabel();
 
+        int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
+
         // Normal path: run the finally code, and jump to the end.
+        generator.emitProfileControlFlow(finallyStartOffset);
         generator.emitNode(dst, m_finallyBlock);
+        generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
         generator.emitJump(finallyEndLabel.get());
 
         // Uncaught exception path: invoke the finally block, then re-throw the exception.
-        RefPtr<RegisterID> tempExceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), preFinallyLabel.get());
+        RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
+        RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
+        generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
+        generator.emitProfileControlFlow(finallyStartOffset);
         generator.emitNode(dst, m_finallyBlock);
-        generator.emitThrow(tempExceptionRegister.get());
+        generator.emitThrow(exceptionRegister.get());
 
         generator.emitLabel(finallyEndLabel.get());
-    }
+        generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
+    } else
+        generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
+
 }
 
 // ------------------------------ ScopeNode -----------------------------
@@ -2314,6 +2945,7 @@ void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 
     RefPtr<RegisterID> dstRegister = generator.newTemporary();
     generator.emitLoad(dstRegister.get(), jsUndefined());
+    generator.emitProfileControlFlow(startStartOffset());
     emitStatementsBytecode(generator, dstRegister.get());
 
     generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
@@ -2336,8 +2968,25 @@ void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-void FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void FunctionBodyNode::emitBytecode(BytecodeGenerator&, RegisterID*)
 {
+}
+
+void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+    if (generator.vm()->typeProfiler()) {
+        for (size_t i = 0; i < m_parameters->size(); i++) {
+            // FIXME: Handle Destructuring assignments into arguments.
+            if (!m_parameters->at(i)->isBindingNode())
+                continue;
+            BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i));
+            RegisterID reg(CallFrame::argumentOffset(i));
+            generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, nullptr);
+            generator.emitTypeProfilerExpressionInfo(parameter->divotStart(), parameter->divotEnd());
+        }
+    }
+
+    generator.emitProfileControlFlow(startStartOffset());
     generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
     emitStatementsBytecode(generator, generator.ignoredResult());
 
@@ -2354,27 +3003,13 @@ void FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
     // If there is no return we must automatically insert one.
     if (!returnNode) {
         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
+        if (generator.vm()->typeProfiler())
+            generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement, nullptr); // Do not emit expression info for this profile because it's not in the user's source code.
         ASSERT(startOffset() >= lineStartOffset());
         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
         generator.emitReturn(r0);
         return;
     }
-
-    // If there is a return statment, and it is the only statement in the function, check if this is a numeric compare.
-    if (static_cast<BlockNode*>(singleStatement)->singleStatement()) {
-        ExpressionNode* returnValueExpression = returnNode->value();
-        if (returnValueExpression && returnValueExpression->isSubtract()) {
-            ExpressionNode* lhsExpression = static_cast<SubNode*>(returnValueExpression)->lhs();
-            ExpressionNode* rhsExpression = static_cast<SubNode*>(returnValueExpression)->rhs();
-            if (lhsExpression->isResolveNode()
-                && rhsExpression->isResolveNode()
-                && generator.isArgumentNumber(static_cast<ResolveNode*>(lhsExpression)->identifier(), 0)
-                && generator.isArgumentNumber(static_cast<ResolveNode*>(rhsExpression)->identifier(), 1)) {
-                
-                generator.setIsNumericCompareFunction(true);
-            }
-        }
-    }
 }
 
 // ------------------------------ FuncDeclNode ---------------------------------
@@ -2389,9 +3024,89 @@ RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
 {
     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
 }
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+// ------------------------------ ClassDeclNode ---------------------------------
+
+void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    generator.emitNode(dst, m_classDeclaration);
+}
+
+// ------------------------------ ClassExprNode ---------------------------------
+
+RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> superclass;
+    if (m_classHeritage) {
+        superclass = generator.newTemporary();
+        generator.emitNode(superclass.get(), m_classHeritage);
+    }
+
+    RefPtr<RegisterID> constructor;
+
+    // FIXME: Make the prototype non-configurable & non-writable.
+    if (m_constructorExpression)
+        constructor = generator.emitNode(dst, m_constructorExpression);
+    else {
+        constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
+            m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name);
+    }
+
+    const auto& propertyNames = generator.propertyNames();
+    RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
+
+    if (superclass) {
+        RefPtr<RegisterID> protoParent = generator.newTemporary();
+        generator.emitLoad(protoParent.get(), jsNull());
+
+        RefPtr<RegisterID> tempRegister = generator.newTemporary();
+
+        // FIXME: Throw TypeError if it's a generator function.
+        RefPtr<Label> superclassIsUndefinedLabel = generator.newLabel();
+        generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
+
+        RefPtr<Label> superclassIsNullLabel = generator.newLabel();
+        generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
+
+        RefPtr<Label> superclassIsObjectLabel = generator.newLabel();
+        generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
+        generator.emitLabel(superclassIsUndefinedLabel.get());
+        generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
+        generator.emitLabel(superclassIsObjectLabel.get());
+        generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
+
+        RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
+        generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
+        generator.emitThrowTypeError(ASCIILiteral("The superclass's prototype is not an object."));
+        generator.emitLabel(protoParentIsObjectOrNullLabel.get());
+
+        generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
+        generator.emitLabel(superclassIsNullLabel.get());
+        generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
+
+        emitPutHomeObject(generator, constructor.get(), prototype.get());
+    }
+
+    RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
+    generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
+        BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
+
+    RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
+    generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
+
+    if (m_staticMethods)
+        generator.emitNode(constructor.get(), m_staticMethods);
+
+    if (m_instanceMethods)
+        generator.emitNode(prototype.get(), m_instanceMethods);
+
+    return generator.moveToDestinationIfNeeded(dst, constructor.get());
+}
+#endif
     
-// ------------------------------ DeconstructingAssignmentNode -----------------
-RegisterID* DeconstructingAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+// ------------------------------ DestructuringAssignmentNode -----------------
+RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
         return result;
@@ -2401,43 +3116,106 @@ RegisterID* DeconstructingAssignmentNode::emitBytecode(BytecodeGenerator& genera
     return generator.moveToDestinationIfNeeded(dst, initializer.get());
 }
 
-DeconstructionPatternNode::~DeconstructionPatternNode()
+DestructuringPatternNode::~DestructuringPatternNode()
 {
 }
-    
+
+static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
+{
+    ASSERT(defaultValue);
+    RefPtr<Label> isNotUndefined = generator.newLabel();
+    generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
+    generator.emitNode(maybeUndefined, defaultValue);
+    generator.emitLabel(isNotUndefined.get());
+}
+
 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
 {
-    for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-        auto target = m_targetPatterns[i];
-        if (!target)
-            continue;
-        RefPtr<RegisterID> temp = generator.newTemporary();
-        generator.emitLoad(temp.get(), jsNumber(i));
-        generator.emitGetByVal(temp.get(), rhs, temp.get());
-        target->bindValue(generator, temp.get());
+    RefPtr<RegisterID> iterator = generator.newTemporary();
+    {
+        generator.emitGetById(iterator.get(), rhs, generator.propertyNames().iteratorSymbol);
+        CallArguments args(generator, nullptr);
+        generator.emitMove(args.thisRegister(), rhs);
+        generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd());
+    }
+
+    if (m_targetPatterns.isEmpty()) {
+        generator.emitIteratorClose(iterator.get(), this);
+        return;
+    }
+
+    RefPtr<RegisterID> done;
+    for (auto& target : m_targetPatterns) {
+        switch (target.bindingType) {
+        case BindingType::Elision:
+        case BindingType::Element: {
+            RefPtr<Label> iterationSkipped = generator.newLabel();
+            if (!done)
+                done = generator.newTemporary();
+            else
+                generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
+
+            RefPtr<RegisterID> value = generator.newTemporary();
+            generator.emitIteratorNext(value.get(), iterator.get(), this);
+            generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
+            generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
+            generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
+
+            {
+                RefPtr<Label> valueIsSet = generator.newLabel();
+                generator.emitJump(valueIsSet.get());
+                generator.emitLabel(iterationSkipped.get());
+                generator.emitLoad(value.get(), jsUndefined());
+                generator.emitLabel(valueIsSet.get());
+            }
+
+            if (target.bindingType == BindingType::Element) {
+                if (target.defaultValue)
+                    assignDefaultValueIfUndefined(generator, value.get(), target.defaultValue);
+                target.pattern->bindValue(generator, value.get());
+            }
+            break;
+        }
+
+        case BindingType::RestElement: {
+            RefPtr<RegisterID> array = generator.emitNewArray(generator.newTemporary(), 0, 0);
+
+            RefPtr<Label> iterationDone = generator.newLabel();
+            if (!done)
+                done = generator.newTemporary();
+            else
+                generator.emitJumpIfTrue(done.get(), iterationDone.get());
+
+            RefPtr<RegisterID> index = generator.newTemporary();
+            generator.emitLoad(index.get(), jsNumber(0));
+            RefPtr<Label> loopStart = generator.newLabel();
+            generator.emitLabel(loopStart.get());
+
+            RefPtr<RegisterID> value = generator.newTemporary();
+            generator.emitIteratorNext(value.get(), iterator.get(), this);
+            generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
+            generator.emitJumpIfTrue(done.get(), iterationDone.get());
+            generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
+
+            generator.emitDirectPutByVal(array.get(), index.get(), value.get());
+            generator.emitInc(index.get());
+            generator.emitJump(loopStart.get());
+
+            generator.emitLabel(iterationDone.get());
+            target.pattern->bindValue(generator, array.get());
+            break;
+        }
+        }
     }
+
+    RefPtr<Label> iteratorClosed = generator.newLabel();
+    generator.emitJumpIfTrue(done.get(), iteratorClosed.get());
+    generator.emitIteratorClose(iterator.get(), this);
+    generator.emitLabel(iteratorClosed.get());
 }
 
 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
 {
-    if (rhs->isResolveNode()
-        && generator.willResolveToArguments(static_cast<ResolveNode*>(rhs)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-            auto target = m_targetPatterns[i];
-            if (!target)
-                continue;
-            
-            RefPtr<RegisterID> temp = generator.newTemporary();
-            generator.emitLoad(temp.get(), jsNumber(i));
-            generator.emitGetArgumentByVal(temp.get(), generator.uncheckedRegisterForArguments(), temp.get());
-            target->bindValue(generator, temp.get());
-        }
-        if (dst == generator.ignoredResult() || !dst)
-            return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
-        Local local = generator.local(generator.vm()->propertyNames->arguments);
-        return generator.moveToDestinationIfNeeded(dst, local.get());
-    }
     if (!rhs->isSimpleArray())
         return 0;
 
@@ -2455,13 +3233,15 @@ RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, Re
     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
         registers.uncheckedAppend(generator.newTemporary());
         generator.emitNode(registers.last().get(), elements[i]);
+        if (m_targetPatterns[i].defaultValue)
+            assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
         if (resultRegister)
             generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
     }
     
     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-        if (m_targetPatterns[i])
-            m_targetPatterns[i]->bindValue(generator, registers[i].get());
+        if (m_targetPatterns[i].pattern)
+            m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
     }
     if (resultRegister)
         return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
@@ -2472,13 +3252,24 @@ void ArrayPatternNode::toString(StringBuilder& builder) const
 {
     builder.append('[');
     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-        if (!m_targetPatterns[i]) {
+        const auto& target = m_targetPatterns[i];
+
+        switch (target.bindingType) {
+        case BindingType::Elision:
             builder.append(',');
-            continue;
+            break;
+
+        case BindingType::Element:
+            target.pattern->toString(builder);
+            if (i < m_targetPatterns.size() - 1)
+                builder.append(',');
+            break;
+
+        case BindingType::RestElement:
+            builder.append("...");
+            target.pattern->toString(builder);
+            break;
         }
-        m_targetPatterns[i]->toString(builder);
-        if (i < m_targetPatterns.size() - 1)
-            builder.append(',');
     }
     builder.append(']');
 }
@@ -2486,7 +3277,7 @@ void ArrayPatternNode::toString(StringBuilder& builder) const
 void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
 {
     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-        if (DeconstructionPatternNode* node = m_targetPatterns[i].get())
+        if (DestructuringPatternNode* node = m_targetPatterns[i].pattern.get())
             node->collectBoundIdentifiers(identifiers);
     }
 }
@@ -2495,13 +3286,11 @@ void ObjectPatternNode::toString(StringBuilder& builder) const
 {
     builder.append('{');
     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-        if (m_targetPatterns[i].wasString) {
-            builder.append('"');
-            escapeStringToBuilder(builder, m_targetPatterns[i].propertyName.string());
-            builder.append('"');
-        } else
+        if (m_targetPatterns[i].wasString)
+            builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
+        else
             builder.append(m_targetPatterns[i].propertyName.string());
-        builder.append(":");
+        builder.append(':');
         m_targetPatterns[i].pattern->toString(builder);
         if (i < m_targetPatterns.size() - 1)
             builder.append(',');
@@ -2515,6 +3304,8 @@ void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs)
         auto& target = m_targetPatterns[i];
         RefPtr<RegisterID> temp = generator.newTemporary();
         generator.emitGetById(temp.get(), rhs, target.propertyName);
+        if (target.defaultValue)
+            assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue);
         target.pattern->bindValue(generator, temp.get());
     }
 }
@@ -2527,19 +3318,26 @@ void ObjectPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers)
 
 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
 {
-    if (Local local = generator.local(m_boundProperty)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_boundProperty);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return;
         }
-        generator.emitMove(local.get(), value);
+        generator.emitMove(local, value);
+        if (generator.vm()->typeProfiler())
+            generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
         return;
     }
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty);
+    RegisterID* scope = generator.emitResolveScope(nullptr, var);
     generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+    generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
+    if (generator.vm()->typeProfiler()) {
+        generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
+        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
+    }
     return;
 }
 
index 5ec7c448bbd0493609fd4674d7df2cfff73353cc..688c8b9c80f63c09eb11a011c65970b7331d4c43 100644 (file)
@@ -70,7 +70,6 @@ namespace JSC {
 
         void setIndex(int index)
         {
-            ASSERT(!m_refCount);
 #ifndef NDEBUG
             m_didSetIndex = true;
 #endif
index 293c22414a6210be1ff7e7b1e28fa4f352240000..5a9918dd1580acf79193bf1c4729abb24ae693e8 100644 (file)
@@ -35,9 +35,9 @@ namespace JSC {
 // Reference count indicates number of live registers that alias this object.
 class StaticPropertyAnalysis : public RefCounted<StaticPropertyAnalysis> {
 public:
-    static PassRefPtr<StaticPropertyAnalysis> create(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* instructions, unsigned target)
+    static Ref<StaticPropertyAnalysis> create(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* instructions, unsigned target)
     {
-        return adoptRef(new StaticPropertyAnalysis(instructions, target)); 
+        return adoptRef(*new StaticPropertyAnalysis(instructions, target)); 
     }
 
     void addPropertyIndex(unsigned propertyIndex) { m_propertyIndexes.add(propertyIndex); }
index 2761624b1c5882206bd3fcde64a29cf6fc50c5db..bea1bf0487f82e9b65f30c7fecb6814d25f0e104 100644 (file)
--- a/config.h
+++ b/config.h
 #if OS(WINDOWS)
 
 #ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0502
+#define _WIN32_WINNT 0x601
 #endif
 
 #ifndef WINVER
-#define WINVER 0x0502
+#define WINVER 0x0601
 #endif
 
-#if !COMPILER(MSVC7_OR_LOWER) && !OS(WINCE)
+#if !COMPILER(MSVC7_OR_LOWER)
 // We need to define this before the first #include of stdlib.h or it won't contain rand_s.
 #ifndef _CRT_RAND_S
 #define _CRT_RAND_S
 #endif
-#endif // !COMPILER(MSVC7_OR_LOWER) && !OS(WINCE)
+#endif // !COMPILER(MSVC7_OR_LOWER
 
 #endif // OS(WINDOWS)
 
-#define WTF_CHANGES 1
-
 #ifdef __cplusplus
 #undef new
 #undef delete
@@ -64,7 +62,3 @@
 #define SKIP_STATIC_CONSTRUCTORS_ON_GCC 1
 #endif
 
-// Enable the following if you want to use the MacroAssembler::probe() facility
-// to do JIT debugging.
-#define WTF_USE_MASM_PROBE 0
-
index 940fbb54a369807d8eedb7597f7ec7ea8b8021b4..70d254d2803842fc0f960959415edd836bb56441 100755 (executable)
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
 OBJ_DIR=${TARGET_TEMP_DIR}/Objects-${CURRENT_VARIANT}
-RUNTIME_DERIVED_SOURCES_DIR=${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCoreRuntime
+RUNTIME_INSTALL_DIR=${BUILT_PRODUCTS_DIR}/${JAVASCRIPTCORE_RESOURCES_DIR}/Runtime
 
 shopt -s nullglob
 for arch in $ARCHS;
 do
     if [ -d "$OBJ_DIR/$arch" ];
     then
-        mkdir -p "$RUNTIME_DERIVED_SOURCES_DIR/$arch"
+        mkdir -p "$RUNTIME_INSTALL_DIR/$arch"
+
         for file in "$OBJ_DIR/$arch"/*.o;
         do
             file_name=${file##*/}
-            gzip -9 -c "$file" > "$RUNTIME_DERIVED_SOURCES_DIR/$arch/${file_name%.o}.bc.gz"
+            cp "$file" "$RUNTIME_INSTALL_DIR/$arch/${file_name%.o}.bc"
         done
+        ${SRCROOT}/build-symbol-table-index.py $arch
     fi
 done
diff --git a/create-llvm-ir-from-source-file.py b/create-llvm-ir-from-source-file.py
new file mode 100644 (file)
index 0000000..f0aa4a0
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+
+# Copyright (C) 2014 University of Szeged. All rights reserved.
+# Copyright (C) 2014 Samsung Electronics. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import subprocess
+import sys
+
+JSC_SOURCE = sys.argv[1]
+RUNTIME_INSTALL_DIR = sys.argv[2]
+CLANG_EXE = sys.argv[3]
+INCLUDE_DIRS = "-I%s" % sys.argv[4]
+
+try:
+    os.mkdir(os.path.join(RUNTIME_INSTALL_DIR, "runtime"))
+except OSError:
+    pass
+
+subprocess.call([CLANG_EXE, "-emit-llvm", "-O3", "-std=c++11", "-fno-exceptions", "-fno-strict-aliasing", "-fno-rtti", "-ffunction-sections", "-fdata-sections", "-fno-rtti", "-fno-omit-frame-pointer", "-fPIC", "-DWTF_PLATFORM_EFL=1", "-o", os.path.join(RUNTIME_INSTALL_DIR, os.path.splitext(JSC_SOURCE)[0] + ".bc"), "-c", JSC_SOURCE] + INCLUDE_DIRS.split())
diff --git a/create-symbol-table-index.py b/create-symbol-table-index.py
new file mode 100755 (executable)
index 0000000..f5ba14d
--- /dev/null
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2014 University of Szeged. All rights reserved.
+# Copyright (C) 2014 Samsung Electronics. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import glob
+import os
+import subprocess
+import sys
+import shutil
+import re
+from sets import Set
+from operator import itemgetter
+
+print("Building Index Table")
+
+RUNTIME_INSTALL_DIR = sys.argv[1]
+JSC_DIR = sys.argv[2]
+DERIVED_SOURCES_DIR = sys.argv[3]
+LLVM_BINS = sys.argv[4]
+
+try:
+    os.mkdir(os.path.join(RUNTIME_INSTALL_DIR, "runtime"))
+except OSError:
+    pass
+
+symbol_table_location = os.path.join(RUNTIME_INSTALL_DIR, "runtime", "Runtime.symtbl")
+
+symbol_table = {}
+
+symbol_table_is_out_of_date = False
+
+symbol_table_modification_time = 0
+
+if os.path.isfile(symbol_table_location):
+    symbol_table_modification_time = os.path.getmtime(symbol_table_location)
+
+file_suffix = "bc"
+file_suffix_length = len(file_suffix)
+
+tested_symbols_location = os.path.join(JSC_DIR, "tested-symbols.symlst")
+include_symbol_table_location = os.path.join(DERIVED_SOURCES_DIR, "InlineRuntimeSymbolTable.h")
+
+tested_symbols = Set([])
+
+if os.path.isfile(tested_symbols_location):
+    with open(tested_symbols_location, 'r') as file:
+        print("Loading tested symbols")
+        for line in file:
+            tested_symbols.add(line[:-1])
+
+for bitcode_file in glob.iglob(os.path.join(RUNTIME_INSTALL_DIR, "runtime", "*." + file_suffix)):
+    bitcode_basename = os.path.basename(bitcode_file)
+
+    print("Appending symbols from " + bitcode_basename)
+    lines = subprocess.check_output([os.path.join(LLVM_BINS, "llvm-nm"), "--defined-only", bitcode_file]).splitlines()
+
+    for line in lines:
+        symbol = line.split()[1]
+        if (symbol[:1] == "_" and symbol[-3:] != ".eh" and (("_" + symbol in tested_symbols) or ("_" + symbol[:7] + "L" + symbol[7:] in tested_symbols))):
+            symbol_table[symbol] = bitcode_basename
+
+if os.path.isfile(symbol_table_location):
+    with open(symbol_table_location, 'r') as file:
+        print("Loading symbol table")
+        for line in file:
+            symbol, _, location = line[:-1].partition(" ")
+            # don't overwrite new symbols with old locations
+            if not symbol in symbol_table:
+                symbol_table[symbol] = location
+
+symbol_list = symbol_table.items()
+
+print("Writing symbol table: " + symbol_table_location)
+print("Writing inline file: " + include_symbol_table_location)
+
+with open(symbol_table_location, "w") as symbol_file:
+    with open(include_symbol_table_location, "w") as include_file:
+        include_file.write("#define FOR_EACH_LIBRARY_SYMBOL(macro)")
+        for symbol, location in symbol_list:
+            symbol_file.write("{} {}\n".format(symbol, location))
+            include_file.write(" \\\nmacro(\"{}\", \"{}\")".format(symbol, location))
+        include_file.write("\n")
+print("Done")
index 88e844704ddc34b0ad3b936e4138c401eb64b681..b26eed0cf8404cd88c4f0c1a56d402f3b38677cc 100755 (executable)
@@ -94,6 +94,11 @@ while (<IN>) {
         if ($att =~ m/Function/) {
             push(@values, { "type" => "Function", "function" => $val, "params" => (length($param) ? $param : "") });
             #printf STDERR "WARNING: Number of arguments missing for $key/$val\n" if (length($param) == 0);
+        } elsif ($att =~ m/Accessor/) {
+            my $get = $val;
+            my $put = "nullptr";
+            $hasSetter = "true";
+            push(@values, { "type" => "Accessor", "get" => $get, "put" => $put });
         } elsif (length($att)) {
             my $get = $val;
             my $put = "0";
@@ -285,6 +290,11 @@ sub output() {
             $firstCastStr = "static_cast<NativeFunction>";
             $firstValue = $values[$i]{"function"};
             $secondValue = $values[$i]{"params"};
+        } elsif ($values[$i]{"type"} eq "Accessor") {
+            $firstCastStr = "static_cast<NativeFunction>";
+            $secondCastStr = "static_cast<NativeFunction>";
+            $firstValue = $values[$i]{"get"};
+            $secondValue = $values[$i]{"put"};
         } elsif ($values[$i]{"type"} eq "Property") {
             $firstCastStr = "static_cast<PropertySlot::GetValueFunc>";
             $secondCastStr = "static_cast<PutPropertySlot::PutValueFunc>";
@@ -320,7 +330,7 @@ sub output() {
         $i++;
     }
     print "};\n\n";
-    print "extern const struct HashTable $name =\n";
+    print "JS_EXPORT_PRIVATE extern const struct HashTable $name =\n";
     print "    \{ $packedSize, $compactHashSizeMask, $hasSetter, $nameEntries, 0, $nameIndex \};\n";
     print "} // namespace\n";
 }
diff --git a/create_jit_stubs b/create_jit_stubs
deleted file mode 100644 (file)
index 404fa36..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
-# Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-use strict;
-use File::Basename;
-use Getopt::Long;
-
-my $usage = basename($0) . " --prefix prefix --header header file";
-
-my $rtype_template = quotemeta("#rtype#");
-my $op_template = quotemeta("#op#");
-
-my $prefix;
-my $header;
-my $enable_dfg = 0;
-my $file;
-
-my $getOptionsResult = GetOptions(
-    'prefix=s' => \$prefix,
-    'header=s' => \$header,
-    'dfg!' => \$enable_dfg
-);
-
-$file = $ARGV[0];
-
-die "$usage\n" unless ($header and $prefix and $file);
-
-my $stub_template = "";
-my $output_end = "";
-my $stub = "";
-
-my $rtype = "";
-my $op = "";
-my $if_counter = 0;
-my $dfg_begin = 0;
-
-print STDERR "Creating JIT stubs for $file \n";
-open(IN, $header) or die "No such file $header";
-
-while ( $_ = <IN> ) {
-    if ( /^$prefix\_BEGIN\((.*)\)/ ) {
-        $stub = $1;
-        print $stub . "\n";
-    }
-    if ( /^$prefix\((.*)\)/ ) {
-        $stub_template .= $1 . "\n";
-    }
-    if ( /^$prefix\_END\((.*)\)/ ) {
-        $output_end .= $1 . "\n";
-    }
-}
-
-close(IN);
-open(IN, $file) or die "No such file $file";
-
-while ( $_ = <IN> ) {
-    if ( /^#if (.*)/ ) {
-        $if_counter++;
-        if ( $1 eq "ENABLE(DFG_JIT)" ) {
-            $dfg_begin = $if_counter;
-        }
-    }
-    if ( /^#endif/ ) {
-        if ( $if_counter == $dfg_begin ) {
-            $dfg_begin = 0;
-        }
-        $if_counter--;
-    }
-    if ( /^DEFINE_STUB_FUNCTION\((.*), (.*)\)/ ) {
-        $stub = $stub_template;
-        $rtype = quotemeta($1);
-        $op = quotemeta($2);
-        $stub =~ s/$rtype_template/$rtype/g;
-        $stub =~ s/$op_template/$op/g;
-        $stub =~ s/\\\*/\*/g;
-        if ( $enable_dfg == 1 || $dfg_begin == 0 ) {
-            print $stub;
-        }
-    }
-}
-
-print $output_end;
-
-close(IN);
index 7544b75cd9c1df43c77b3e59cbc9c34b1818dea4..c6fd6eb7f3e3485a3c823cdb01cb221083247e73 100644 (file)
@@ -86,15 +86,15 @@ for name, classes in types.items():
     
     # Generate createFunction:
     function = "";
-    function += ("CharacterClass* %sCreate()\n" % name)
+    function += ("std::unique_ptr<CharacterClass> %sCreate()\n" % name)
     function += ("{\n")
     if emitTables and classes["UseTable"]:
         if "Inverse" in classes:
-            function += ("    CharacterClass* characterClass = new CharacterClass(_%sData, true);\n" % (classes["Inverse"]))
+            function += ("    auto characterClass = std::make_unique<CharacterClass>(_%sData, true);\n" % (classes["Inverse"]))
         else:
-            function += ("    CharacterClass* characterClass = new CharacterClass(_%sData, false);\n" % (name))
+            function += ("    auto characterClass = std::make_unique<CharacterClass>(_%sData, false);\n" % (name))
     else:
-        function += ("    CharacterClass* characterClass = new CharacterClass;\n")
+        function += ("    auto characterClass = std::make_unique<CharacterClass>();\n")
     for (min, max) in ranges:
         if (min == max):
             if (min > 127):
@@ -106,7 +106,7 @@ for name, classes in types.items():
             function += ("    characterClass->m_rangesUnicode.append(CharacterRange(0x%04x, 0x%04x));\n" % (min, max))
         else:
             function += ("    characterClass->m_ranges.append(CharacterRange(0x%02x, 0x%02x));\n" % (min, max))
-    function += ("    return characterClass;\n")
+    function += ("    return WTF::move(characterClass);\n")
     function += ("}\n\n")
     functions += function
 
index 60f4fd579b280dd37d5496ec4a34cfaba6ea83e1..8518ce469449fc732e760f25087a1f9ab11768d2 100644 (file)
@@ -43,7 +43,7 @@ struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
     {
     }
 
-    Breakpoint(SourceID sourceID, unsigned line, unsigned column, String condition, bool autoContinue)
+    Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue)
         : id(noBreakpointID)
         , sourceID(sourceID)
         , line(line)
index 168d7a3f43793a247fa98fbe3da21947013ca7f0..bc1b57e593a79930712892de65093106a3aa47d1 100644 (file)
@@ -25,7 +25,6 @@
 #include "CodeBlock.h"
 #include "DebuggerCallFrame.h"
 #include "Error.h"
-
 #include "HeapIterationScope.h"
 #include "Interpreter.h"
 #include "JSCJSValueInlines.h"
@@ -44,12 +43,14 @@ class Recompiler : public MarkedBlock::VoidFunctor {
 public:
     Recompiler(JSC::Debugger*);
     ~Recompiler();
-    void operator()(JSCell*);
+    IterationStatus operator()(JSCell*);
 
 private:
     typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
     typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
     
+    void visit(JSCell*);
+    
     JSC::Debugger* m_debugger;
     FunctionExecutableSet m_functionExecutables;
     SourceProviderMap m_sourceProviders;
@@ -69,7 +70,7 @@ inline Recompiler::~Recompiler()
         m_debugger->sourceParsed(iter->value, iter->key, -1, String());
 }
 
-inline void Recompiler::operator()(JSCell* cell)
+inline void Recompiler::visit(JSCell* cell)
 {
     if (!cell->inherits(JSFunction::info()))
         return;
@@ -86,19 +87,25 @@ inline void Recompiler::operator()(JSCell* cell)
         return;
 
     ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
-    executable->clearCodeIfNotCompiling();
-    executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
+    executable->clearCode();
+    executable->clearUnlinkedCodeForRecompilation();
     if (m_debugger == function->scope()->globalObject()->debugger())
         m_sourceProviders.add(executable->source().provider(), exec);
 }
 
+inline IterationStatus Recompiler::operator()(JSCell* cell)
+{
+    visit(cell);
+    return IterationStatus::Continue;
+}
+
 } // namespace
 
 namespace JSC {
 
-class DebuggerCallFrameScope {
+class DebuggerPausedScope {
 public:
-    DebuggerCallFrameScope(Debugger& debugger)
+    DebuggerPausedScope(Debugger& debugger)
         : m_debugger(debugger)
     {
         ASSERT(!m_debugger.m_currentDebuggerCallFrame);
@@ -106,11 +113,11 @@ public:
             m_debugger.m_currentDebuggerCallFrame = DebuggerCallFrame::create(debugger.m_currentCallFrame);
     }
 
-    ~DebuggerCallFrameScope()
+    ~DebuggerPausedScope()
     {
         if (m_debugger.m_currentDebuggerCallFrame) {
             m_debugger.m_currentDebuggerCallFrame->invalidate();
-            m_debugger.m_currentDebuggerCallFrame = 0;
+            m_debugger.m_currentDebuggerCallFrame = nullptr;
         }
     }
 
@@ -141,7 +148,7 @@ private:
 template<typename Functor>
 void Debugger::forEachCodeBlock(Functor& functor)
 {
-    m_vm->waitForCompilationsToComplete();
+    m_vm->prepareToDiscardCode();
     m_vm->heap.forEachCodeBlock(functor);
 }
 
@@ -160,6 +167,7 @@ Debugger::Debugger(bool isInWorkerThread)
     , m_lastExecutedLine(UINT_MAX)
     , m_lastExecutedSourceID(noSourceID)
     , m_topBreakpointID(noBreakpointID)
+    , m_pausingBreakpointID(noBreakpointID)
 {
 }
 
@@ -206,6 +214,11 @@ void Debugger::detach(JSGlobalObject* globalObject, ReasonForDetach reason)
         m_vm = nullptr;
 }
 
+bool Debugger::isAttached(JSGlobalObject* globalObject)
+{
+    return globalObject->debugger() == this;
+}
+
 class Debugger::SetSteppingModeFunctor {
 public:
     SetSteppingModeFunctor(Debugger* debugger, SteppingMode mode)
@@ -235,7 +248,7 @@ void Debugger::setSteppingMode(SteppingMode mode)
     if (mode == m_steppingMode || !m_vm)
         return;
 
-    m_vm->waitForCompilationsToComplete();
+    m_vm->prepareToDiscardCode();
 
     m_steppingMode = mode;
     SetSteppingModeFunctor functor(this, mode);
@@ -264,7 +277,7 @@ void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, Br
     unsigned line = breakpoint.line;
     unsigned column = breakpoint.column;
 
-    unsigned startLine = executable->lineNo();
+    unsigned startLine = executable->firstLine();
     unsigned startColumn = executable->startColumn();
     unsigned endLine = executable->lastLine();
     unsigned endColumn = executable->endColumn();
@@ -335,11 +348,17 @@ void Debugger::recompileAllJSFunctions(VM* vm)
     // If JavaScript is running, it's not safe to recompile, since we'll end
     // up throwing away code that is live on the stack.
     if (vm->entryScope) {
-        vm->entryScope->setRecompilationNeeded(true);
+        auto listener = [] (VM& vm, JSGlobalObject* globalObject) 
+        {
+            if (Debugger* debugger = globalObject->debugger())
+                debugger->recompileAllJSFunctions(&vm);
+        };
+
+        vm->entryScope->setEntryScopeDidPopListener(this, listener);
         return;
     }
 
-    vm->waitForCompilationsToComplete();
+    vm->prepareToDiscardCode();
 
     Recompiler recompiler(this);
     HeapIterationScope iterationScope(vm->heap);
@@ -467,7 +486,7 @@ bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Br
     // so make it looks like the debugger is already paused.
     TemporaryPausedState pausedState(*this);
 
-    JSValue exception;
+    NakedPtr<Exception> exception;
     DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame();
     JSValue result = debuggerCallFrame->evaluate(breakpoint->condition, exception);
 
@@ -601,7 +620,8 @@ void Debugger::stepOutOfFunction()
     if (!m_isPaused)
         return;
 
-    m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrameSkippingVMEntrySentinel() : 0;
+    VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
+    m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrame(topVMEntryFrame) : 0;
     notifyDoneProcessingDebuggerEvents();
 }
 
@@ -637,7 +657,7 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
     bool pauseNow = m_pauseOnNextStatement;
     pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame);
 
-    DebuggerCallFrameScope debuggerCallFrameScope(*this);
+    DebuggerPausedScope debuggerPausedScope(*this);
 
     intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame);
     TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame);
@@ -653,14 +673,20 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
     m_pauseOnNextStatement = false;
 
     if (didHitBreakpoint) {
-        handleBreakpointHit(breakpoint);
+        handleBreakpointHit(vmEntryGlobalObject, breakpoint);
         // Note that the actions can potentially stop the debugger, so we need to check that
         // we still have a current call frame when we get back.
         if (breakpoint.autoContinue || !m_currentCallFrame)
             return;
+        m_pausingBreakpointID = breakpoint.id;
     }
 
-    handlePause(m_reasonForPause, vmEntryGlobalObject);
+    {
+        PauseReasonDeclaration reason(*this, didHitBreakpoint ? PausedForBreakpoint : m_reasonForPause);
+        handlePause(vmEntryGlobalObject, m_reasonForPause);
+    }
+
+    m_pausingBreakpointID = noBreakpointID;
 
     if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) {
         setSteppingMode(SteppingModeDisabled);
@@ -668,13 +694,13 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
     }
 }
 
-void Debugger::exception(CallFrame* callFrame, JSValue exception, bool hasHandler)
+void Debugger::exception(CallFrame* callFrame, JSValue exception, bool hasCatchHandler)
 {
     if (m_isPaused)
         return;
 
     PauseReasonDeclaration reason(*this, PausedForException);
-    if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler)) {
+    if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasCatchHandler)) {
         m_pauseOnNextStatement = true;
         setSteppingMode(SteppingModeEnabled);
     }
@@ -717,10 +743,13 @@ void Debugger::returnEvent(CallFrame* callFrame)
         return;
 
     // Treat stepping over a return statement like stepping out.
-    if (m_currentCallFrame == m_pauseOnCallFrame)
-        m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
+    if (m_currentCallFrame == m_pauseOnCallFrame) {
+        VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
+        m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
+    }
 
-    m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
+    VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
+    m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
 }
 
 void Debugger::willExecuteProgram(CallFrame* callFrame)
@@ -750,11 +779,13 @@ void Debugger::didExecuteProgram(CallFrame* callFrame)
     if (!m_currentCallFrame)
         return;
     if (m_currentCallFrame == m_pauseOnCallFrame) {
-        m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
+        VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
+        m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
         if (!m_currentCallFrame)
             return;
     }
-    m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
+    VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
+    m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
 }
 
 void Debugger::didReachBreakpoint(CallFrame* callFrame)
@@ -762,7 +793,7 @@ void Debugger::didReachBreakpoint(CallFrame* callFrame)
     if (m_isPaused)
         return;
 
-    PauseReasonDeclaration reason(*this, PausedForBreakpoint);
+    PauseReasonDeclaration reason(*this, PausedForDebuggerStatement);
     m_pauseOnNextStatement = true;
     setSteppingMode(SteppingModeEnabled);
     updateCallFrameAndPauseIfNeeded(callFrame);
index 2e8524aaf54cd16eef29f326b308a040258c4320..d70f3b76f376a22a8d08a64893bfe46d2e3af4dc 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace JSC {
 
+class CodeBlock;
+class Exception;
 class ExecState;
 class JSGlobalObject;
 class SourceProvider;
@@ -59,12 +61,13 @@ public:
 
     bool needsExceptionCallbacks() const { return m_pauseOnExceptionsState != DontPauseOnExceptions; }
 
-    void attach(JSGlobalObject*);
     enum ReasonForDetach {
         TerminatingDebuggingSession,
         GlobalObjectIsDestructing
     };
-    virtual void detach(JSGlobalObject*, ReasonForDetach);
+    void attach(JSGlobalObject*);
+    void detach(JSGlobalObject*, ReasonForDetach);
+    bool isAttached(JSGlobalObject*);
 
     BreakpointID setBreakpoint(Breakpoint, unsigned& actualLine, unsigned& actualColumn);
     void removeBreakpoint(BreakpointID);
@@ -81,6 +84,20 @@ public:
     PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
     void setPauseOnExceptionsState(PauseOnExceptionsState);
 
+    enum ReasonForPause {
+        NotPaused,
+        PausedForException,
+        PausedAtStatement,
+        PausedAfterCall,
+        PausedBeforeReturn,
+        PausedAtStartOfProgram,
+        PausedAtEndOfProgram,
+        PausedForBreakpoint,
+        PausedForDebuggerStatement,
+    };
+    ReasonForPause reasonForPause() const { return m_reasonForPause; }
+    BreakpointID pausingBreakpointID() const { return m_pausingBreakpointID; }
+
     void setPauseOnNextStatement(bool);
     void breakProgram();
     void continueProgram();
@@ -88,12 +105,12 @@ public:
     void stepOverStatement();
     void stepOutOfFunction();
 
-    bool isPaused() { return m_isPaused; }
+    bool isPaused() const { return m_isPaused; }
     bool isStepping() const { return m_steppingMode == SteppingModeEnabled; }
 
     virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0;
 
-    void exception(CallFrame*, JSValue exceptionValue, bool hasHandler);
+    void exception(CallFrame*, JSValue exceptionValue, bool hasCatchHandler);
     void atStatement(CallFrame*);
     void callEvent(CallFrame*);
     void returnEvent(CallFrame*);
@@ -107,21 +124,9 @@ public:
 
 protected:
     virtual bool needPauseHandling(JSGlobalObject*) { return false; }
-    virtual void handleBreakpointHit(const Breakpoint&) { }
-    virtual void handleExceptionInBreakpointCondition(ExecState*, JSValue exception) const { UNUSED_PARAM(exception); }
-
-    enum ReasonForPause {
-        NotPaused,
-        PausedForException,
-        PausedAtStatement,
-        PausedAfterCall,
-        PausedBeforeReturn,
-        PausedAtStartOfProgram,
-        PausedAtEndOfProgram,
-        PausedForBreakpoint
-    };
-
-    virtual void handlePause(ReasonForPause, JSGlobalObject*) { }
+    virtual void handleBreakpointHit(JSGlobalObject*, const Breakpoint&) { }
+    virtual void handleExceptionInBreakpointCondition(ExecState*, Exception*) const { }
+    virtual void handlePause(JSGlobalObject*, ReasonForPause) { }
     virtual void notifyDoneProcessingDebuggerEvents() { }
 
 private:
@@ -191,7 +196,7 @@ private:
     bool m_breakpointsActivated : 1;
     bool m_hasHandlerForExceptionCallback : 1;
     bool m_isInWorkerThread : 1;
-    SteppingMode m_steppingMode : 1;
+    unsigned m_steppingMode : 1; // SteppingMode
 
     ReasonForPause m_reasonForPause;
     JSValue m_currentException;
@@ -201,12 +206,13 @@ private:
     SourceID m_lastExecutedSourceID;
 
     BreakpointID m_topBreakpointID;
+    BreakpointID m_pausingBreakpointID;
     BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint;
     SourceIDToBreakpointsMap m_sourceIDToBreakpoints;
 
     RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame;
 
-    friend class DebuggerCallFrameScope;
+    friend class DebuggerPausedScope;
     friend class TemporaryPausedState;
     friend class LLIntOffsetsExtractor;
 };
diff --git a/debugger/DebuggerActivation.cpp b/debugger/DebuggerActivation.cpp
deleted file mode 100644 (file)
index 1340ff7..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DebuggerActivation.h"
-
-#include "JSActivation.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DebuggerActivation);
-
-const ClassInfo DebuggerActivation::s_info = { "DebuggerActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(DebuggerActivation) };
-
-DebuggerActivation::DebuggerActivation(VM& vm)
-    : JSNonFinalObject(vm, vm.debuggerActivationStructure.get())
-{
-}
-
-void DebuggerActivation::finishCreation(VM& vm, JSObject* activation)
-{
-    Base::finishCreation(vm);
-    ASSERT(activation);
-    ASSERT(activation->isActivationObject());
-    m_activation.set(vm, this, jsCast<JSActivation*>(activation));
-}
-
-void DebuggerActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    JSObject::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_activation);
-}
-
-String DebuggerActivation::className(const JSObject* object)
-{
-    const DebuggerActivation* thisObject = jsCast<const DebuggerActivation*>(object);
-    return thisObject->m_activation->methodTable()->className(thisObject->m_activation.get());
-}
-
-bool DebuggerActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
-    return thisObject->m_activation->methodTable()->getOwnPropertySlot(thisObject->m_activation.get(), exec, propertyName, slot);
-}
-
-void DebuggerActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
-    thisObject->m_activation->methodTable()->put(thisObject->m_activation.get(), exec, propertyName, value, slot);
-}
-
-bool DebuggerActivation::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
-    return thisObject->m_activation->methodTable()->deleteProperty(thisObject->m_activation.get(), exec, propertyName);
-}
-
-void DebuggerActivation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
-    thisObject->m_activation->methodTable()->getPropertyNames(thisObject->m_activation.get(), exec, propertyNames, mode);
-}
-
-bool DebuggerActivation::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-{
-    DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
-    return thisObject->m_activation->methodTable()->defineOwnProperty(thisObject->m_activation.get(), exec, propertyName, descriptor, shouldThrow);
-}
-
-} // namespace JSC
diff --git a/debugger/DebuggerActivation.h b/debugger/DebuggerActivation.h
deleted file mode 100644 (file)
index e90383e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DebuggerActivation_h
-#define DebuggerActivation_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-class DebuggerActivation : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static DebuggerActivation* create(VM& vm, JSObject* object)
-    {
-        DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(vm.heap)) DebuggerActivation(vm);
-        activation->finishCreation(vm, object);
-        return activation;
-    }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-    static String className(const JSObject*);
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-
-    DECLARE_EXPORT_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
-    }
-
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | JSObject::StructureFlags;
-
-    JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* activation);
-
-private:
-    JS_EXPORT_PRIVATE DebuggerActivation(VM&);
-    WriteBarrier<JSActivation> m_activation;
-};
-
-} // namespace JSC
-
-#endif // DebuggerActivation_h
index 83fb67f3afcdde3875ad5c08fd8073f88b8f80d2..663fc03cdf93ff10421a8ab4b7b5683d635016cc 100644 (file)
 #include "DebuggerCallFrame.h"
 
 #include "CodeBlock.h"
+#include "DebuggerEvalEnabler.h"
+#include "DebuggerScope.h"
 #include "Interpreter.h"
-#include "JSActivation.h"
 #include "JSFunction.h"
+#include "JSLexicalEnvironment.h"
 #include "JSCInlines.h"
 #include "Parser.h"
 #include "StackVisitor.h"
+#include "StrongInlines.h"
 
 namespace JSC {
 
@@ -55,13 +58,36 @@ private:
     unsigned m_column;
 };
 
+class FindCallerMidStackFunctor {
+public:
+    FindCallerMidStackFunctor(CallFrame* callFrame)
+        : m_callFrame(callFrame)
+        , m_callerFrame(nullptr)
+    { }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        if (visitor->callFrame() == m_callFrame) {
+            m_callerFrame = visitor->callerFrame();
+            return StackVisitor::Done;
+        }
+        return StackVisitor::Continue;
+    }
+
+    CallFrame* getCallerFrame() const { return m_callerFrame; }
+
+private:
+    CallFrame* m_callFrame;
+    CallFrame* m_callerFrame;
+};
+
 DebuggerCallFrame::DebuggerCallFrame(CallFrame* callFrame)
     : m_callFrame(callFrame)
 {
     m_position = positionForCallFrame(m_callFrame);
 }
 
-PassRefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
+RefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
 {
     ASSERT(isValid());
     if (!isValid())
@@ -70,9 +96,12 @@ PassRefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
     if (m_caller)
         return m_caller;
 
-    CallFrame* callerFrame = m_callFrame->callerFrameSkippingVMEntrySentinel();
+    FindCallerMidStackFunctor functor(m_callFrame);
+    m_callFrame->vm().topCallFrame->iterate(functor);
+
+    CallFrame* callerFrame = functor.getCallerFrame();
     if (!callerFrame)
-        return 0;
+        return nullptr;
 
     m_caller = DebuggerCallFrame::create(callerFrame);
     return m_caller;
@@ -99,27 +128,33 @@ String DebuggerCallFrame::functionName() const
     ASSERT(isValid());
     if (!isValid())
         return String();
-    JSObject* function = m_callFrame->callee();
+    JSFunction* function = jsDynamicCast<JSFunction*>(m_callFrame->callee());
     if (!function)
         return String();
 
     return getCalculatedDisplayName(m_callFrame, function);
 }
 
-JSScope* DebuggerCallFrame::scope() const
+DebuggerScope* DebuggerCallFrame::scope()
 {
     ASSERT(isValid());
     if (!isValid())
         return 0;
 
-    CodeBlock* codeBlock = m_callFrame->codeBlock();
-    if (codeBlock && codeBlock->needsActivation() && !m_callFrame->hasActivation()) {
-        JSActivation* activation = JSActivation::create(*codeBlock->vm(), m_callFrame, codeBlock);
-        m_callFrame->setActivation(activation);
-        m_callFrame->setScope(activation);
+    if (!m_scope) {
+        VM& vm = m_callFrame->vm();
+        JSScope* scope;
+        CodeBlock* codeBlock = m_callFrame->codeBlock();
+        if (codeBlock && codeBlock->scopeRegister().isValid())
+            scope = m_callFrame->scope(codeBlock->scopeRegister().offset());
+        else if (JSCallee* callee = jsDynamicCast<JSCallee*>(m_callFrame->callee()))
+            scope = callee->scope();
+        else
+            scope = m_callFrame->lexicalGlobalObject();
+
+        m_scope.set(vm, DebuggerScope::create(vm, scope));
     }
-
-    return m_callFrame->scope();
+    return m_scope.get();
 }
 
 DebuggerCallFrame::Type DebuggerCallFrame::type() const
@@ -128,7 +163,7 @@ DebuggerCallFrame::Type DebuggerCallFrame::type() const
     if (!isValid())
         return ProgramType;
 
-    if (m_callFrame->callee())
+    if (jsDynamicCast<JSFunction*>(m_callFrame->callee()))
         return FunctionType;
 
     return ProgramType;
@@ -141,7 +176,7 @@ JSValue DebuggerCallFrame::thisValue() const
 }
 
 // Evaluate some JavaScript code in the scope of this frame.
-JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception)
+JSValue DebuggerCallFrame::evaluate(const String& script, NakedPtr<Exception>& exception)
 {
     ASSERT(isValid());
     CallFrame* callFrame = m_callFrame;
@@ -153,8 +188,11 @@ JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception)
     if (!callFrame->codeBlock())
         return JSValue();
     
+    DebuggerEvalEnabler evalEnabler(callFrame);
     VM& vm = callFrame->vm();
-    EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), callFrame->codeBlock()->isStrictMode());
+    auto& codeBlock = *callFrame->codeBlock();
+    ThisTDZMode thisTDZMode = codeBlock.unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
+    EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode);
     if (vm.exception()) {
         exception = vm.exception();
         vm.clearException();
@@ -162,7 +200,7 @@ JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception)
     }
 
     JSValue thisValue = thisValueForCallFrame(callFrame);
-    JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope());
+    JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope());
     if (vm.exception()) {
         exception = vm.exception();
         vm.clearException();
@@ -173,10 +211,13 @@ JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception)
 
 void DebuggerCallFrame::invalidate()
 {
-    m_callFrame = nullptr;
-    RefPtr<DebuggerCallFrame> frame = m_caller.release();
+    RefPtr<DebuggerCallFrame> frame = this;
     while (frame) {
         frame->m_callFrame = nullptr;
+        if (frame->m_scope) {
+            frame->m_scope->invalidateChain();
+            frame->m_scope.clear();
+        }
         frame = frame->m_caller.release();
     }
 }
index ca225695ad5f49a220ff60791498c541959bbec4..aa3cca52b04c2f3c048495ded7dbfcab71209f90 100644 (file)
 #ifndef DebuggerCallFrame_h
 #define DebuggerCallFrame_h
 
-#include "CallFrame.h"
 #include "DebuggerPrimitives.h"
+#include "Strong.h"
+#include <wtf/NakedPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/TextPosition.h>
 
 namespace JSC {
 
+class DebuggerScope;
+class Exception;
+class ExecState;
+typedef ExecState CallFrame;
+
 class DebuggerCallFrame : public RefCounted<DebuggerCallFrame> {
 public:
     enum Type { ProgramType, FunctionType };
 
-    static PassRefPtr<DebuggerCallFrame> create(CallFrame* callFrame)
+    static Ref<DebuggerCallFrame> create(CallFrame* callFrame)
     {
-        return adoptRef(new DebuggerCallFrame(callFrame));
+        return adoptRef(*new DebuggerCallFrame(callFrame));
     }
 
     JS_EXPORT_PRIVATE explicit DebuggerCallFrame(CallFrame*);
 
-    JS_EXPORT_PRIVATE PassRefPtr<DebuggerCallFrame> callerFrame();
+    JS_EXPORT_PRIVATE RefPtr<DebuggerCallFrame> callerFrame();
     ExecState* exec() const { return m_callFrame; }
     JS_EXPORT_PRIVATE SourceID sourceID() const;
 
@@ -58,11 +64,11 @@ public:
     JS_EXPORT_PRIVATE const TextPosition& position() const { return m_position; }
 
     JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject() const;
-    JS_EXPORT_PRIVATE JSScope* scope() const;
+    JS_EXPORT_PRIVATE DebuggerScope* scope();
     JS_EXPORT_PRIVATE String functionName() const;
     JS_EXPORT_PRIVATE Type type() const;
     JS_EXPORT_PRIVATE JSValue thisValue() const;
-    JSValue evaluate(const String&, JSValue& exception);
+    JSValue evaluate(const String&, NakedPtr<Exception>&);
 
     bool isValid() const { return !!m_callFrame; }
     JS_EXPORT_PRIVATE void invalidate();
@@ -78,6 +84,9 @@ private:
     CallFrame* m_callFrame;
     RefPtr<DebuggerCallFrame> m_caller;
     TextPosition m_position;
+    // The DebuggerPausedScope is responsible for calling invalidate() which,
+    // in turn, will clear this strong ref.
+    Strong<DebuggerScope> m_scope;
 };
 
 } // namespace JSC
diff --git a/debugger/DebuggerEvalEnabler.h b/debugger/DebuggerEvalEnabler.h
new file mode 100644 (file)
index 0000000..bb75b1f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DebuggerEvalEnabler_h
+#define DebuggerEvalEnabler_h
+
+#include "CallFrame.h"
+#include "JSGlobalObject.h"
+
+namespace JSC {
+
+class DebuggerEvalEnabler {
+public:
+    explicit DebuggerEvalEnabler(const ExecState* exec)
+        : m_exec(exec)
+        , m_evalWasDisabled(false)
+    {
+        if (exec) {
+            JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+            m_evalWasDisabled = !globalObject->evalEnabled();
+            if (m_evalWasDisabled)
+                globalObject->setEvalEnabled(true, globalObject->evalDisabledErrorMessage());
+        }
+    }
+
+    ~DebuggerEvalEnabler()
+    {
+        if (m_evalWasDisabled) {
+            JSGlobalObject* globalObject = m_exec->lexicalGlobalObject();
+            globalObject->setEvalEnabled(false, globalObject->evalDisabledErrorMessage());
+        }
+    }
+
+private:
+    const ExecState* m_exec;
+    bool m_evalWasDisabled;
+};
+
+} // namespace JSC
+
+#endif // DebuggerEvalEnabler_h
diff --git a/debugger/DebuggerScope.cpp b/debugger/DebuggerScope.cpp
new file mode 100644 (file)
index 0000000..d53a6a0
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2008-2009, 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DebuggerScope.h"
+
+#include "JSLexicalEnvironment.h"
+#include "JSCInlines.h"
+#include "JSNameScope.h"
+#include "JSWithScope.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DebuggerScope);
+
+const ClassInfo DebuggerScope::s_info = { "DebuggerScope", &Base::s_info, 0, CREATE_METHOD_TABLE(DebuggerScope) };
+
+DebuggerScope::DebuggerScope(VM& vm, JSScope* scope)
+    : JSNonFinalObject(vm, scope->globalObject()->debuggerScopeStructure())
+{
+    ASSERT(scope);
+    m_scope.set(vm, this, scope);
+}
+
+void DebuggerScope::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+}
+
+void DebuggerScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    DebuggerScope* thisObject = jsCast<DebuggerScope*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    JSObject::visitChildren(thisObject, visitor);
+    visitor.append(&thisObject->m_scope);
+    visitor.append(&thisObject->m_next);
+}
+
+String DebuggerScope::className(const JSObject* object)
+{
+    const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return String();
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    return thisObject->methodTable()->className(thisObject);
+}
+
+bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+    DebuggerScope* scope = jsCast<DebuggerScope*>(object);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    slot.setThisValue(JSValue(thisObject));
+
+    // By default, JSObject::getPropertySlot() will look in the DebuggerScope's prototype
+    // chain and not the wrapped scope, and JSObject::getPropertySlot() cannot be overridden
+    // to behave differently for the DebuggerScope.
+    //
+    // Instead, we'll treat all properties in the wrapped scope and its prototype chain as
+    // the own properties of the DebuggerScope. This is fine because the WebInspector
+    // does not presently need to distinguish between what's owned at each level in the
+    // prototype chain. Hence, we'll invoke getPropertySlot() on the wrapped scope here
+    // instead of getOwnPropertySlot().
+    return thisObject->getPropertySlot(exec, propertyName, slot);
+}
+
+void DebuggerScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+    DebuggerScope* scope = jsCast<DebuggerScope*>(cell);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return;
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    slot.setThisValue(JSValue(thisObject));
+    thisObject->methodTable()->put(thisObject, exec, propertyName, value, slot);
+}
+
+bool DebuggerScope::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+    DebuggerScope* scope = jsCast<DebuggerScope*>(cell);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    return thisObject->methodTable()->deleteProperty(thisObject, exec, propertyName);
+}
+
+void DebuggerScope::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    DebuggerScope* scope = jsCast<DebuggerScope*>(object);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return;
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    thisObject->methodTable()->getPropertyNames(thisObject, exec, propertyNames, mode);
+}
+
+bool DebuggerScope::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    DebuggerScope* scope = jsCast<DebuggerScope*>(object);
+    ASSERT(scope->isValid());
+    if (!scope->isValid())
+        return false;
+    JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
+    return thisObject->methodTable()->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
+}
+
+DebuggerScope* DebuggerScope::next()
+{
+    ASSERT(isValid());
+    if (!m_next && m_scope->next()) {
+        VM& vm = *m_scope->vm();
+        DebuggerScope* nextScope = create(vm, m_scope->next());
+        m_next.set(vm, this, nextScope);
+    }
+    return m_next.get();
+}
+
+void DebuggerScope::invalidateChain()
+{
+    if (!isValid())
+        return;
+
+    DebuggerScope* scope = this;
+    while (scope) {
+        DebuggerScope* nextScope = scope->m_next.get();
+        scope->m_next.clear();
+        scope->m_scope.clear(); // This also marks this scope as invalid.
+        scope = nextScope;
+    }
+}
+
+bool DebuggerScope::isCatchScope() const
+{
+    return m_scope->isCatchScopeObject();
+}
+
+bool DebuggerScope::isFunctionNameScope() const
+{
+    return m_scope->isFunctionNameScopeObject();
+}
+
+bool DebuggerScope::isWithScope() const
+{
+    return m_scope->isWithScope();
+}
+
+bool DebuggerScope::isGlobalScope() const
+{
+    return m_scope->isGlobalObject();
+}
+
+bool DebuggerScope::isFunctionOrEvalScope() const
+{
+    // In the current debugger implementation, every function or eval will create an
+    // lexical environment object. Hence, a lexical environment object implies a
+    // function or eval scope.
+    return m_scope->isActivationObject();
+}
+
+JSValue DebuggerScope::caughtValue() const
+{
+    ASSERT(isCatchScope());
+    return reinterpret_cast<JSNameScope*>(m_scope.get())->value();
+}
+
+} // namespace JSC
diff --git a/debugger/DebuggerScope.h b/debugger/DebuggerScope.h
new file mode 100644 (file)
index 0000000..4416684
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008-2009, 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DebuggerScope_h
+#define DebuggerScope_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class DebuggerCallFrame;
+class JSScope;
+
+class DebuggerScope : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+
+    static DebuggerScope* create(VM& vm, JSScope* scope)
+    {
+        DebuggerScope* debuggerScope = new (NotNull, allocateCell<DebuggerScope>(vm.heap)) DebuggerScope(vm, scope);
+        debuggerScope->finishCreation(vm);
+        return debuggerScope;
+    }
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+    static String className(const JSObject*);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) 
+    {
+        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info()); 
+    }
+
+    class iterator {
+    public:
+        iterator(DebuggerScope* node)
+            : m_node(node)
+        {
+        }
+
+        DebuggerScope* get() { return m_node; }
+        iterator& operator++() { m_node = m_node->next(); return *this; }
+        // postfix ++ intentionally omitted
+
+        bool operator==(const iterator& other) const { return m_node == other.m_node; }
+        bool operator!=(const iterator& other) const { return m_node != other.m_node; }
+
+    private:
+        DebuggerScope* m_node;
+    };
+
+    iterator begin();
+    iterator end();
+    DebuggerScope* next();
+
+    void invalidateChain();
+    bool isValid() const { return !!m_scope; }
+
+    bool isCatchScope() const;
+    bool isFunctionNameScope() const;
+    bool isWithScope() const;
+    bool isGlobalScope() const;
+    bool isFunctionOrEvalScope() const;
+
+    JSValue caughtValue() const;
+
+private:
+    JS_EXPORT_PRIVATE DebuggerScope(VM&, JSScope*);
+    JS_EXPORT_PRIVATE void finishCreation(VM&);
+
+    JSScope* jsScope() const { return m_scope.get(); }
+
+    WriteBarrier<JSScope> m_scope;
+    WriteBarrier<DebuggerScope> m_next;
+
+    friend class DebuggerCallFrame;
+};
+
+inline DebuggerScope::iterator DebuggerScope::begin()
+{
+    return iterator(this); 
+}
+
+inline DebuggerScope::iterator DebuggerScope::end()
+{ 
+    return iterator(0); 
+}
+
+} // namespace JSC
+
+#endif // DebuggerScope_h
index 05d90c4969c4c41fe3307c40e39a7e412e0b8488..1e1101902db25ead7f8d7ef99b49c4841c18d11d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@ void AbstractHeap::Payload::dump(PrintStream& out) const
 void AbstractHeap::dump(PrintStream& out) const
 {
     out.print(kind());
-    if (kind() == InvalidAbstractHeap || kind() == World || payload().isTop())
+    if (kind() == InvalidAbstractHeap || kind() == World || kind() == Heap || payload().isTop())
         return;
     out.print("(", payload(), ")");
 }
index 338c99e31dd5cfcfd3f48fd1a26416c2295dd5bf..4dafbc1cbc0e8962ed3c839faa47da4e053c244c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace DFG {
 
-// Implements a three-level type hierarchy:
+// Implements a four-level type hierarchy:
 // - World is the supertype of all of the things.
-// - Kind with TOP payload is the direct subtype of World.
-// - Kind with non-TOP payload is the direct subtype of its corresponding TOP Kind.
+// - Stack with a TOP payload is a direct subtype of World
+// - Stack with a non-TOP payload is a direct subtype of Stack with a TOP payload.
+// - Heap is a direct subtype of World.
+// - Any other kind with TOP payload is the direct subtype of Heap.
+// - Any other kind with non-TOP payload is the direct subtype of the same kind with a TOP payload.
 
 #define FOR_EACH_ABSTRACT_HEAP_KIND(macro) \
     macro(InvalidAbstractHeap) \
     macro(World) \
-    macro(Arguments_numArguments) \
-    macro(Arguments_overrideLength) \
-    macro(Arguments_registers) \
-    macro(Arguments_slowArguments) \
-    macro(ArrayBuffer_data) \
-    macro(Butterfly_arrayBuffer) \
+    macro(Stack) \
+    macro(Heap) \
     macro(Butterfly_publicLength) \
     macro(Butterfly_vectorLength) \
-    macro(JSArrayBufferView_length) \
-    macro(JSArrayBufferView_mode) \
-    macro(JSArrayBufferView_vector) \
+    macro(GetterSetter_getter) \
+    macro(GetterSetter_setter) \
     macro(JSCell_structureID) \
     macro(JSCell_indexingType) \
     macro(JSCell_typeInfoFlags) \
     macro(JSCell_typeInfoType) \
-    macro(JSFunction_executable) \
-    macro(JSFunction_scopeChain) \
     macro(JSObject_butterfly) \
-    macro(JSVariableObject_registers) \
+    macro(JSPropertyNameEnumerator_cachedPropertyNames) \
     macro(NamedProperties) \
     macro(IndexedInt32Properties) \
     macro(IndexedDoubleProperties) \
     macro(IndexedContiguousProperties) \
+    macro(IndexedArrayStorageProperties) \
     macro(ArrayStorageProperties) \
-    macro(Variables) \
+    macro(DirectArgumentsProperties) \
+    macro(ScopeProperties) \
     macro(TypedArrayProperties) \
-    macro(GCState) \
-    macro(BarrierState) \
+    macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\
     macro(RegExpState) \
     macro(InternalState) \
     macro(Absolute) \
     /* Use this for writes only, to indicate that this may fire watchpoints. Usually this is never directly written but instead we test to see if a node clobbers this; it just so happens that you have to write world to clobber it. */\
     macro(Watchpoint_fire) \
-    /* Use this for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
+    /* Use these for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
     macro(MiscFields) \
     /* Use this for writes only, just to indicate that hoisting the node is invalid. This works because we don't hoist anything that has any side effects at all. */\
     macro(SideState)
@@ -134,6 +131,11 @@ public:
             return m_value;
         }
         
+        int32_t value32() const
+        {
+            return static_cast<int32_t>(value());
+        }
+        
         bool operator==(const Payload& other) const
         {
             return m_isTop == other.m_isTop
@@ -188,7 +190,7 @@ public:
     
     AbstractHeap(AbstractHeapKind kind, Payload payload)
     {
-        ASSERT(kind != InvalidAbstractHeap && kind != World);
+        ASSERT(kind != InvalidAbstractHeap && kind != World && kind != Heap && kind != SideState);
         m_value = encode(kind, payload);
     }
     
@@ -206,32 +208,49 @@ public:
         return payloadImpl();
     }
     
-    bool isDisjoint(const AbstractHeap& other)
+    AbstractHeap supertype() const
     {
         ASSERT(kind() != InvalidAbstractHeap);
-        ASSERT(other.kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return false;
-        if (other.kind() == World)
-            return false;
-        if (kind() != other.kind())
-            return true;
-        return payload().isDisjoint(other.payload());
+        switch (kind()) {
+        case World:
+            return AbstractHeap();
+        case Heap:
+        case SideState:
+            return World;
+        default:
+            if (payload().isTop()) {
+                if (kind() == Stack)
+                    return World;
+                return Heap;
+            }
+            return AbstractHeap(kind());
+        }
     }
     
-    bool overlaps(const AbstractHeap& other)
+    bool isStrictSubtypeOf(const AbstractHeap& other) const
     {
-        return !isDisjoint(other);
+        AbstractHeap current = *this;
+        while (current.kind() != World) {
+            current = current.supertype();
+            if (current == other)
+                return true;
+        }
+        return false;
     }
     
-    AbstractHeap supertype() const
+    bool isSubtypeOf(const AbstractHeap& other) const
     {
-        ASSERT(kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return AbstractHeap();
-        if (payload().isTop())
-            return World;
-        return AbstractHeap(kind());
+        return *this == other || isStrictSubtypeOf(other);
+    }
+    
+    bool overlaps(const AbstractHeap& other) const
+    {
+        return *this == other || isStrictSubtypeOf(other) || other.isStrictSubtypeOf(*this);
+    }
+    
+    bool isDisjoint(const AbstractHeap& other) const
+    {
+        return !overlaps(other);
     }
     
     unsigned hash() const
index 97582ac319726c8177836c3becb957065e75b408..b3ebd68f18bec32a7667940c227736ab3ad0714d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 #include "DFGBranchDirection.h"
 #include "DFGGraph.h"
 #include "DFGNode.h"
+#include "DFGPhiChildren.h"
 
 namespace JSC { namespace DFG {
 
@@ -80,22 +81,15 @@ public:
     //
     // This is guaranteed to be equivalent to doing:
     //
-    // if (state.startExecuting(index)) {
-    //     state.executeEdges(index);
-    //     result = state.executeEffects(index);
-    // } else
-    //     result = true;
+    // state.startExecuting()
+    // state.executeEdges(index);
+    // result = state.executeEffects(index);
     bool execute(unsigned indexInBlock);
     bool execute(Node*);
     
-    // Indicate the start of execution of the node. It resets any state in the node,
-    // that is progressively built up by executeEdges() and executeEffects(). In
-    // particular, this resets canExit(), so if you want to "know" between calls of
-    // startExecuting() and executeEdges()/Effects() whether the last run of the
-    // analysis concluded that the node can exit, you should probably set that
-    // information aside prior to calling startExecuting().
-    bool startExecuting(Node*);
-    bool startExecuting(unsigned indexInBlock);
+    // Indicate the start of execution of a node. It resets any state in the node
+    // that is progressively built up by executeEdges() and executeEffects().
+    void startExecuting();
     
     // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
     // on all edges of the node. You can skip this step, if you have already used
@@ -103,10 +97,14 @@ public:
     void executeEdges(Node*);
     void executeEdges(unsigned indexInBlock);
     
-    ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge& edge)
+    ALWAYS_INLINE void filterEdgeByUse(Edge& edge)
     {
         ASSERT(mayHaveTypeCheck(edge.useKind()) || !needsTypeCheck(edge));
-        filterByType(node, edge, typeFilterFor(edge.useKind()));
+        filterByType(edge, typeFilterFor(edge.useKind()));
+    }
+    ALWAYS_INLINE void filterEdgeByUse(Node*, Edge& edge)
+    {
+        filterEdgeByUse(edge);
     }
     
     // Abstractly execute the effects of the given node. This changes the abstract
@@ -114,6 +112,7 @@ public:
     bool executeEffects(unsigned indexInBlock);
     bool executeEffects(unsigned clobberLimit, Node*);
     
+    void dump(PrintStream& out) const;
     void dump(PrintStream& out);
     
     template<typename T>
@@ -135,7 +134,7 @@ public:
     }
     
     template<typename T>
-    FiltrationResult filterByValue(T node, JSValue value)
+    FiltrationResult filterByValue(T node, FrozenValue value)
     {
         return filterByValue(forNode(node), value);
     }
@@ -143,12 +142,20 @@ public:
     FiltrationResult filter(AbstractValue&, const StructureSet&);
     FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
     FiltrationResult filter(AbstractValue&, SpeculatedType);
-    FiltrationResult filterByValue(AbstractValue&, JSValue);
+    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
+    
+    PhiChildren* phiChildren() { return m_phiChildren.get(); }
     
 private:
     void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
-    void clobberCapturedVars(const CodeOrigin&);
+    
+    template<typename Functor>
+    void forAllValues(unsigned indexInBlock, Functor&);
+    
     void clobberStructures(unsigned indexInBlock);
+    void observeTransition(unsigned indexInBlock, Structure* from, Structure* to);
+    void observeTransitions(unsigned indexInBlock, const TransitionVector&);
+    void setDidClobber();
     
     enum BooleanResult {
         UnknownBooleanResult,
@@ -157,26 +164,25 @@ private:
     };
     BooleanResult booleanResult(Node*, AbstractValue&);
     
-    void setBuiltInConstant(Node* node, JSValue value)
+    void setBuiltInConstant(Node* node, FrozenValue value)
     {
         AbstractValue& abstractValue = forNode(node);
-        abstractValue.set(m_graph, value);
-        abstractValue.fixTypeForRepresentation(node);
+        abstractValue.set(m_graph, value, m_state.structureClobberState());
+        abstractValue.fixTypeForRepresentation(m_graph, node);
     }
     
-    void setConstant(Node* node, JSValue value)
+    void setConstant(Node* node, FrozenValue value)
     {
         setBuiltInConstant(node, value);
         m_state.setFoundConstants(true);
     }
     
-    ALWAYS_INLINE void filterByType(Node* node, Edge& edge, SpeculatedType type)
+    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type)
     {
         AbstractValue& value = forNode(edge);
-        if (!value.isType(type)) {
-            node->setCanExit(true);
+        if (!value.isType(type))
             edge.setProofStatus(NeedsCheck);
-        else
+        else
             edge.setProofStatus(IsProved);
         
         filter(value, type);
@@ -188,6 +194,7 @@ private:
     CodeBlock* m_codeBlock;
     Graph& m_graph;
     AbstractStateType& m_state;
+    std::unique_ptr<PhiChildren> m_phiChildren;
 };
 
 } } // namespace JSC::DFG
index 0e9419444c672a165d73e9bd9446f34257072177..21ee0e4ac2f1656e9a73b7661fb33c8afb3e38da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,9 @@
 
 #include "DFGAbstractInterpreter.h"
 #include "GetByIdStatus.h"
+#include "GetterSetter.h"
+#include "JITOperations.h"
+#include "MathCommon.h"
 #include "Operations.h"
 #include "PutByIdStatus.h"
 #include "StringObject.h"
@@ -42,6 +45,8 @@ AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, Abstra
     , m_graph(graph)
     , m_state(state)
 {
+    if (m_graph.m_form == SSA)
+        m_phiChildren = std::make_unique<PhiChildren>(m_graph);
 }
 
 template<typename AbstractStateType>
@@ -62,11 +67,17 @@ AbstractInterpreter<AbstractStateType>::booleanResult(
     }
 
     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
-    if (isCellSpeculation(value.m_type)
-        && value.m_currentKnownStructure.hasSingleton()) {
-        Structure* structure = value.m_currentKnownStructure.singleton();
-        if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
-            && structure->typeInfo().type() != StringType)
+    if (isCellSpeculation(value.m_type) && !value.m_structure.isTop()) {
+        bool allTrue = true;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if (structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
+                || structure->typeInfo().type() == StringType) {
+                allTrue = false;
+                break;
+            }
+        }
+        if (allTrue)
             return DefinitelyTrue;
     }
     
@@ -74,22 +85,12 @@ AbstractInterpreter<AbstractStateType>::booleanResult(
 }
 
 template<typename AbstractStateType>
-bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
+void AbstractInterpreter<AbstractStateType>::startExecuting()
 {
     ASSERT(m_state.block());
     ASSERT(m_state.isValid());
     
     m_state.setDidClobber(false);
-    
-    node->setCanExit(false);
-    
-    return node->shouldGenerate();
-}
-
-template<typename AbstractStateType>
-bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
-{
-    return startExecuting(m_state.block()->at(indexInBlock));
 }
 
 template<typename AbstractStateType>
@@ -105,9 +106,12 @@ void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
 }
 
 template<typename AbstractStateType>
-void AbstractInterpreter<AbstractStateType>::verifyEdge(Node*, Edge edge)
+void AbstractInterpreter<AbstractStateType>::verifyEdge(Node* node, Edge edge)
 {
-    RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
+    if (!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())))
+        return;
+    
+    DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data());
 }
 
 template<typename AbstractStateType>
@@ -127,51 +131,39 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     switch (node->op()) {
     case JSConstant:
     case DoubleConstant:
-    case Int52Constant:
-    case WeakJSConstant:
-    case PhantomArguments: {
-        setBuiltInConstant(node, m_graph.valueOfJSConstant(node));
+    case Int52Constant: {
+        setBuiltInConstant(node, *node->constant());
         break;
     }
         
     case Identity: {
         forNode(node) = forNode(node->child1());
-        break;
-    }
-        
-    case GetArgument: {
-        ASSERT(m_graph.m_form == SSA);
-        VariableAccessData* variable = node->variableAccessData();
-        AbstractValue& value = m_state.variables().operand(variable->local().offset());
-        ASSERT(value.isHeapTop());
-        FiltrationResult result =
-            value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
-        ASSERT_UNUSED(result, result == FiltrationOK);
-        forNode(node) = value;
+        if (forNode(node).value())
+            m_state.setFoundConstants(true);
         break;
     }
         
     case ExtractOSREntryLocal: {
-        if (!(node->unlinkedLocal().isArgument())
-            && m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
-            // This is kind of pessimistic - we could know in some cases that the
-            // DFG code at the point of the OSR had already initialized the lazy
-            // variable. But maybe this is fine, since we're inserting OSR
-            // entrypoints very early in the pipeline - so any lazy initializations
-            // ought to be hoisted out anyway.
-            forNode(node).makeBytecodeTop();
-        } else
-            forNode(node).makeHeapTop();
+        forNode(node).makeBytecodeTop();
         break;
     }
             
     case GetLocal: {
         VariableAccessData* variableAccessData = node->variableAccessData();
         AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
-        if (!variableAccessData->isCaptured()) {
-            if (value.isClear())
-                node->setCanExit(true);
-        }
+        // The value in the local should already be checked.
+        DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(variableAccessData->flushFormat())));
+        if (value.value())
+            m_state.setFoundConstants(true);
+        forNode(node) = value;
+        break;
+    }
+        
+    case GetStack: {
+        StackAccessData* data = node->stackAccessData();
+        AbstractValue value = m_state.variables().operand(data->local);
+        // The value in the local should already be checked.
+        DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(data->format)));
         if (value.value())
             m_state.setFoundConstants(true);
         forNode(node) = value;
@@ -187,7 +179,12 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     }
         
     case SetLocal: {
-        m_state.variables().operand(node->local().offset()) = forNode(node->child1());
+        m_state.variables().operand(node->local()) = forNode(node->child1());
+        break;
+    }
+        
+    case PutStack: {
+        m_state.variables().operand(node->stackAccessData()->local) = forNode(node->child1());
         break;
     }
         
@@ -198,10 +195,31 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         break;
     }
         
+    case KillStack: {
+        // This is just a hint telling us that the OSR state of the local is no longer inside the
+        // flushed data.
+        break;
+    }
+        
     case SetArgument:
-        // Assert that the state of arguments has been set.
-        ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
+        // Assert that the state of arguments has been set. SetArgument means that someone set
+        // the argument values out-of-band, and currently this always means setting to a
+        // non-clear value.
+        ASSERT(!m_state.variables().operand(node->local()).isClear());
         break;
+        
+    case LoadVarargs:
+    case ForwardVarargs: {
+        // FIXME: ForwardVarargs should check if the count becomes known, and if it does, it should turn
+        // itself into a straight-line sequence of GetStack/PutStack.
+        // https://bugs.webkit.org/show_bug.cgi?id=143071
+        clobberWorld(node->origin.semantic, clobberLimit);
+        LoadVarargsData* data = node->loadVarargsData();
+        m_state.variables().operand(data->count).setType(SpecInt32);
+        for (unsigned i = data->limit - 1; i--;)
+            m_state.variables().operand(data->start.offset() + i).makeHeapTop();
+        break;
+    }
             
     case BitAnd:
     case BitOr:
@@ -239,6 +257,14 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             }
             break;
         }
+        
+        if (node->op() == BitAnd
+            && (isBoolInt32Speculation(forNode(node->child1()).m_type) ||
+                isBoolInt32Speculation(forNode(node->child2()).m_type))) {
+            forNode(node).setType(SpecBoolInt32);
+            break;
+        }
+        
         forNode(node).setType(SpecInt32);
         break;
     }
@@ -262,7 +288,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             }
         }
         forNode(node).setType(SpecInt32);
-        node->setCanExit(true);
         break;
     }
         
@@ -272,7 +297,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             if (concreteValue.isBoolean())
                 setConstant(node, jsNumber(concreteValue.asBoolean()));
             else
-                setConstant(node, concreteValue);
+                setConstant(node, *m_graph.freeze(concreteValue));
             break;
         }
         AbstractValue& value = forNode(node);
@@ -280,7 +305,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
             m_state.setFoundConstants(true);
         if (value.m_type & SpecBoolean) {
-            value.merge(SpecInt32);
+            value.merge(SpecBoolInt32);
             value.filter(~SpecBoolean);
         }
         break;
@@ -296,7 +321,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 break;
             }
         }
-        node->setCanExit(true);
         forNode(node).setType(SpecInt32);
         break;
     }
@@ -321,6 +345,11 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             }
         }
         
+        if (isBooleanSpeculation(forNode(node->child1()).m_type)) {
+            forNode(node).setType(SpecBoolInt32);
+            break;
+        }
+        
         forNode(node).setType(SpecInt32);
         break;
     }
@@ -331,8 +360,32 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             setConstant(node, jsDoubleNumber(child.asNumber()));
             break;
         }
-        forNode(node).setType(forNode(node->child1()).m_type);
-        forNode(node).fixTypeForRepresentation(node);
+
+        SpeculatedType type = forNode(node->child1()).m_type;
+        switch (node->child1().useKind()) {
+        case NotCellUse: {
+            if (type & SpecOther) {
+                type &= ~SpecOther;
+                type |= SpecDoublePureNaN | SpecBoolInt32; // Null becomes zero, undefined becomes NaN.
+            }
+            if (type & SpecBoolean) {
+                type &= ~SpecBoolean;
+                type |= SpecBoolInt32; // True becomes 1, false becomes 0.
+            }
+            type &= SpecBytecodeNumber;
+            break;
+        }
+
+        case Int52RepUse:
+        case NumberUse:
+        case RealNumberUse:
+            break;
+
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+        forNode(node).setType(type);
+        forNode(node).fixTypeForRepresentation(m_graph, node);
         break;
     }
         
@@ -354,15 +407,15 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             break;
         }
         
-        forNode(node).setType(forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
-        forNode(node).fixTypeForRepresentation(node);
+        forNode(node).setType(m_graph, forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
+        forNode(node).fixTypeForRepresentation(m_graph, node);
         break;
     }
         
     case ValueAdd: {
         ASSERT(node->binaryUseKind() == UntypedUse);
         clobberWorld(node->origin.semantic, clobberLimit);
-        forNode(node).setType(SpecString | SpecBytecodeNumber);
+        forNode(node).setType(m_graph, SpecString | SpecBytecodeNumber);
         break;
     }
         
@@ -383,8 +436,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -395,9 +446,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (!forNode(node->child1()).isType(SpecInt32)
-                || !forNode(node->child2()).isType(SpecInt32))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -414,9 +462,19 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         }
         break;
     }
-        
+
+    case ArithClz32: {
+        JSValue operand = forNode(node->child1()).value();
+        if (operand && operand.isNumber()) {
+            uint32_t value = toUInt32(operand.asNumber());
+            setConstant(node, jsNumber(clz32(value)));
+            break;
+        }
+        forNode(node).setType(SpecInt32);
+        break;
+    }
+
     case MakeRope: {
-        node->setCanExit(true);
         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
         break;
     }
@@ -438,8 +496,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -450,9 +506,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (!forNode(node->child1()).isType(SpecInt32)
-                || !forNode(node->child2()).isType(SpecInt32))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -491,8 +544,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (child && child.isMachineInt()) {
@@ -508,10 +559,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
-                node->setCanExit(true);
-            if (shouldCheckNegativeZero(node->arithMode()))
-                node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (child && child.isNumber()) {
@@ -549,8 +596,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            if (shouldCheckOverflow(node->arithMode()))
-                node->setCanExit(true);
             break;
         case Int52RepUse:
             if (left && right && left.isMachineInt() && right.isMachineInt()) {
@@ -564,7 +609,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecMachineInt);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -600,7 +644,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -636,7 +679,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -664,7 +706,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 break;
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -694,7 +735,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 break;
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (left && right && left.isNumber() && right.isNumber()) {
@@ -726,11 +766,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 }
             }
             forNode(node).setType(SpecInt32);
-            node->setCanExit(true);
             break;
         case DoubleRepUse:
             if (child && child.isNumber()) {
-                setConstant(node, jsDoubleNumber(child.asNumber()));
+                setConstant(node, jsDoubleNumber(fabs(child.asNumber())));
                 break;
             }
             forNode(node).setType(typeOfDoubleAbs(forNode(node->child1()).m_type));
@@ -741,6 +780,54 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         }
         break;
     }
+
+    case ArithPow: {
+        JSValue childY = forNode(node->child2()).value();
+        if (childY && childY.isNumber()) {
+            if (!childY.asNumber()) {
+                setConstant(node, jsDoubleNumber(1));
+                break;
+            }
+
+            JSValue childX = forNode(node->child1()).value();
+            if (childX && childX.isNumber()) {
+                setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
+                break;
+            }
+        }
+        forNode(node).setType(typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type));
+        break;
+    }
+
+    case ArithRound: {
+        JSValue operand = forNode(node->child1()).value();
+        if (operand && operand.isNumber()) {
+            double roundedValue = jsRound(operand.asNumber());
+
+            if (producesInteger(node->arithRoundingMode())) {
+                int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
+                if (roundedValueAsInt32 == roundedValue) {
+                    if (shouldCheckNegativeZero(node->arithRoundingMode())) {
+                        if (roundedValueAsInt32 || !std::signbit(roundedValue)) {
+                            setConstant(node, jsNumber(roundedValueAsInt32));
+                            break;
+                        }
+                    } else {
+                        setConstant(node, jsNumber(roundedValueAsInt32));
+                        break;
+                    }
+                }
+            } else {
+                setConstant(node, jsDoubleNumber(roundedValue));
+                break;
+            }
+        }
+        if (producesInteger(node->arithRoundingMode()))
+            forNode(node).setType(SpecInt32);
+        else
+            forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
+        break;
+    }
             
     case ArithSqrt: {
         JSValue child = forNode(node->child1()).value();
@@ -758,7 +845,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
             break;
         }
-        forNode(node).setType(typeOfDoubleFRound(forNode(node->child1()).m_type));
+        forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
         break;
     }
         
@@ -781,6 +868,16 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
         break;
     }
+
+    case ArithLog: {
+        JSValue child = forNode(node->child1()).value();
+        if (child && child.isNumber()) {
+            setConstant(node, jsDoubleNumber(log(child.asNumber())));
+            break;
+        }
+        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
+        break;
+    }
             
     case LogicalNot: {
         switch (booleanResult(node, forNode(node->child1()))) {
@@ -791,20 +888,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             setConstant(node, jsBoolean(true));
             break;
         default:
-            switch (node->child1().useKind()) {
-            case BooleanUse:
-            case Int32Use:
-            case DoubleRepUse:
-            case UntypedUse:
-            case StringUse:
-                break;
-            case ObjectOrOtherUse:
-                node->setCanExit(true);
-                break;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
-            }
             forNode(node).setType(SpecBoolean);
             break;
         }
@@ -816,35 +899,59 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     case IsNumber:
     case IsString:
     case IsObject:
+    case IsObjectOrNull:
     case IsFunction: {
-        node->setCanExit(
-            node->op() == IsUndefined
-            && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic));
-        JSValue child = forNode(node->child1()).value();
-        if (child) {
+        AbstractValue child = forNode(node->child1());
+        if (child.value()) {
             bool constantWasSet = true;
             switch (node->op()) {
             case IsUndefined:
                 setConstant(node, jsBoolean(
-                    child.isCell()
-                    ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
-                    : child.isUndefined()));
+                    child.value().isCell()
+                    ? child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
+                    : child.value().isUndefined()));
                 break;
             case IsBoolean:
-                setConstant(node, jsBoolean(child.isBoolean()));
+                setConstant(node, jsBoolean(child.value().isBoolean()));
                 break;
             case IsNumber:
-                setConstant(node, jsBoolean(child.isNumber()));
+                setConstant(node, jsBoolean(child.value().isNumber()));
                 break;
             case IsString:
-                setConstant(node, jsBoolean(isJSString(child)));
+                setConstant(node, jsBoolean(isJSString(child.value())));
                 break;
             case IsObject:
-                if (child.isNull() || !child.isObject()) {
-                    setConstant(node, jsBoolean(child.isNull()));
-                    break;
-                }
-                constantWasSet = false;
+                setConstant(node, jsBoolean(child.value().isObject()));
+                break;
+            case IsObjectOrNull:
+                if (child.value().isObject()) {
+                    JSObject* object = asObject(child.value());
+                    if (object->type() == JSFunctionType)
+                        setConstant(node, jsBoolean(false));
+                    else if (!(object->inlineTypeFlags() & TypeOfShouldCallGetCallData))
+                        setConstant(node, jsBoolean(!child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))));
+                    else {
+                        // FIXME: This could just call getCallData.
+                        // https://bugs.webkit.org/show_bug.cgi?id=144457
+                        constantWasSet = false;
+                    }
+                } else
+                    setConstant(node, jsBoolean(child.value().isNull()));
+                break;
+            case IsFunction:
+                if (child.value().isObject()) {
+                    JSObject* object = asObject(child.value());
+                    if (object->type() == JSFunctionType)
+                        setConstant(node, jsBoolean(true));
+                    else if (!(object->inlineTypeFlags() & TypeOfShouldCallGetCallData))
+                        setConstant(node, jsBoolean(false));
+                    else {
+                        // FIXME: This could just call getCallData.
+                        // https://bugs.webkit.org/show_bug.cgi?id=144457
+                        constantWasSet = false;
+                    }
+                } else
+                    setConstant(node, jsBoolean(false));
                 break;
             default:
                 constantWasSet = false;
@@ -853,7 +960,131 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             if (constantWasSet)
                 break;
         }
-
+        
+        // FIXME: This code should really use AbstractValue::isType() and
+        // AbstractValue::couldBeType().
+        // https://bugs.webkit.org/show_bug.cgi?id=146870
+        
+        bool constantWasSet = false;
+        switch (node->op()) {
+        case IsUndefined:
+            // FIXME: Use the masquerades-as-undefined watchpoint thingy.
+            // https://bugs.webkit.org/show_bug.cgi?id=144456
+            
+            if (!(child.m_type & (SpecOther | SpecObjectOther))) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsBoolean:
+            if (!(child.m_type & ~SpecBoolean)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            if (!(child.m_type & SpecBoolean)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsNumber:
+            if (!(child.m_type & ~SpecFullNumber)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            if (!(child.m_type & SpecFullNumber)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsString:
+            if (!(child.m_type & ~SpecString)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            if (!(child.m_type & SpecString)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsObject:
+            if (!(child.m_type & ~SpecObject)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            if (!(child.m_type & SpecObject)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsObjectOrNull:
+            // FIXME: Use the masquerades-as-undefined watchpoint thingy.
+            // https://bugs.webkit.org/show_bug.cgi?id=144456
+            
+            // These expressions are complicated to parse. A helpful way to parse this is that
+            // "!(T & ~S)" means "T is a subset of S". Conversely, "!(T & S)" means "T is a
+            // disjoint set from S". Things like "T - S" means that, provided that S is a
+            // subset of T, it's the "set of all things in T but not in S". Things like "T | S"
+            // mean the "union of T and S".
+            
+            // Is the child's type an object that isn't an other-object (i.e. object that could
+            // have masquaredes-as-undefined traps) and isn't a function?  Then: we should fold
+            // this to true.
+            if (!(child.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            // Is the child's type definitely not either of: an object that isn't a function,
+            // or either undefined or null?  Then: we should fold this to false.  This means
+            // for example that if it's any non-function object, including those that have
+            // masquerades-as-undefined traps, then we don't fold. It also means we won't fold
+            // if it's undefined-or-null, since the type bits don't distinguish between
+            // undefined (which should fold to false) and null (which should fold to true).
+            if (!(child.m_type & ((SpecObject - SpecFunction) | SpecOther))) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            
+            break;
+        case IsFunction:
+            if (!(child.m_type & ~SpecFunction)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+            
+            if (!(child.m_type & (SpecFunction | SpecObjectOther))) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+            break;
+        default:
+            break;
+        }
+        if (constantWasSet)
+            break;
+        
         forNode(node).setType(SpecBoolean);
         break;
     }
@@ -864,47 +1095,43 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         AbstractValue& abstractChild = forNode(node->child1());
         if (child) {
             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
-            setConstant(node, typeString);
+            setConstant(node, *m_graph.freeze(typeString));
             break;
         }
         
         if (isFullNumberSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.numberString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.numberString()));
             break;
         }
         
         if (isStringSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.stringString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.stringString()));
             break;
         }
-        
-        if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.objectString());
+
+        // FIXME: We could use the masquerades-as-undefined watchpoint here.
+        // https://bugs.webkit.org/show_bug.cgi?id=144456
+        if (!(abstractChild.m_type & ~(SpecObject - SpecObjectOther))) {
+            setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
             break;
         }
         
         if (isFunctionSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.functionString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.functionString()));
             break;
         }
         
         if (isBooleanSpeculation(abstractChild.m_type)) {
-            setConstant(node, vm->smallStrings.booleanString());
+            setConstant(node, *m_graph.freeze(vm->smallStrings.booleanString()));
             break;
         }
 
-        switch (node->child1().useKind()) {
-        case StringUse:
-        case CellUse:
-            node->setCanExit(true);
-            break;
-        case UntypedUse:
-            break;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
+        if (isSymbolSpeculation(abstractChild.m_type)) {
+            setConstant(node, *m_graph.freeze(vm->smallStrings.symbolString()));
             break;
         }
-        forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
+
+        forNode(node).setType(m_graph, SpecStringIdent);
         break;
     }
             
@@ -963,14 +1190,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         }
         
         forNode(node).setType(SpecBoolean);
-        
-        // This is overly conservative. But the only thing this prevents is store elimination,
-        // and how likely is it, really, that you'll have redundant stores across a comparison
-        // operation? Comparison operations are typically at the end of basic blocks, so
-        // unless we have global store elimination (super unlikely given how unprofitable that
-        // optimization is to begin with), you aren't going to be wanting to store eliminate
-        // across an equality op.
-        node->setCanExit(true);
         break;
     }
             
@@ -1003,26 +1222,22 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         }
         
         forNode(node).setType(SpecBoolean);
-        node->setCanExit(true); // This is overly conservative.
         break;
     }
         
     case StringCharCodeAt:
-        node->setCanExit(true);
         forNode(node).setType(SpecInt32);
         break;
         
     case StringFromCharCode:
-        forNode(node).setType(SpecString);
+        forNode(node).setType(m_graph, SpecString);
         break;
 
     case StringCharAt:
-        node->setCanExit(true);
         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
         break;
             
     case GetByVal: {
-        node->setCanExit(true);
         switch (node->arrayMode().type()) {
         case Array::SelectUsingPredictions:
         case Array::Unprofiled:
@@ -1053,7 +1268,8 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             } else
                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
             break;
-        case Array::Arguments:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             forNode(node).makeHeapTop();
             break;
         case Array::Int32:
@@ -1121,7 +1337,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     case PutByValDirect:
     case PutByVal:
     case PutByValAlias: {
-        node->setCanExit(true);
         switch (node->arrayMode().modeForPut().type()) {
         case Array::ForceExit:
             m_state.setIsValid(false);
@@ -1153,16 +1368,59 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     }
             
     case ArrayPush:
-        node->setCanExit(true);
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(SpecBytecodeNumber);
         break;
             
     case ArrayPop:
-        node->setCanExit(true);
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
+        
+    case GetMyArgumentByVal: {
+        JSValue index = forNode(node->child2()).m_value;
+        InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
+
+        if (index && index.isInt32()) {
+            // This pretends to return TOP for accesses that are actually proven out-of-bounds because
+            // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
+            // paths as unreachable, and it's almost certainly not worth the effort.
+            
+            if (inlineCallFrame) {
+                if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
+                    forNode(node) = m_state.variables().operand(
+                        virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            } else {
+                if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
+                    forNode(node) = m_state.variables().argument(index.asInt32() + 1);
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            }
+        }
+        
+        if (inlineCallFrame) {
+            // We have a bound on the types even though it's random access. Take advantage of this.
+            
+            AbstractValue result;
+            for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
+                result.merge(
+                    m_state.variables().operand(
+                        virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
+            }
+            
+            if (result.value())
+                m_state.setFoundConstants(true);
+            forNode(node) = result;
+            break;
+        }
+        
+        forNode(node).makeHeapTop();
+        break;
+    }
             
     case RegExpExec:
         forNode(node).makeHeapTop();
@@ -1190,7 +1448,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         // constant propagation, but we can do better:
         // We can specialize the source variable's value on each direction of
         // the branch.
-        node->setCanExit(true); // This is overly conservative.
         m_state.setBranchDirection(TakeBoth);
         break;
     }
@@ -1208,7 +1465,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     case Throw:
     case ThrowReferenceError:
         m_state.setIsValid(false);
-        node->setCanExit(true);
         break;
             
     case ToPrimitive: {
@@ -1225,7 +1481,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             break;
         }
         
-        if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString))) {
+        if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))) {
             m_state.setFoundConstants(true);
             forNode(node) = forNode(node->child1());
             break;
@@ -1233,11 +1489,12 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         
         clobberWorld(node->origin.semantic, clobberLimit);
         
-        forNode(node).setType((SpecHeapTop & ~SpecCell) | SpecString);
+        forNode(node).setType(m_graph, (SpecHeapTop & ~SpecCell) | SpecString | SpecSymbol);
         break;
     }
         
-    case ToString: {
+    case ToString:
+    case CallStringConstructor: {
         switch (node->child1().useKind()) {
         case StringObjectUse:
             // This also filters that the StringObject has the primordial StringObject
@@ -1245,10 +1502,8 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             filter(
                 node->child1(),
                 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
-            node->setCanExit(true); // We could be more precise but it's likely not worth it.
             break;
         case StringOrStringObjectUse:
-            node->setCanExit(true); // We could be more precise but it's likely not worth it.
             break;
         case CellUse:
         case UntypedUse:
@@ -1269,25 +1524,19 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     }
             
     case NewArray:
-        node->setCanExit(true);
         forNode(node).set(
             m_graph,
             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
-        m_state.setHaveStructures(true);
         break;
         
     case NewArrayBuffer:
-        node->setCanExit(true);
         forNode(node).set(
             m_graph,
             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
-        m_state.setHaveStructures(true);
         break;
 
     case NewArrayWithSize:
-        node->setCanExit(true);
-        forNode(node).setType(SpecArray);
-        m_state.setHaveStructures(true);
+        forNode(node).setType(m_graph, SpecArray);
         break;
         
     case NewTypedArray:
@@ -1305,12 +1554,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             m_graph,
             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(
                 node->typedArrayType()));
-        m_state.setHaveStructures(true);
         break;
             
     case NewRegexp:
         forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
-        m_state.setHaveStructures(true);
         break;
             
     case ToThis: {
@@ -1327,214 +1574,214 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     }
 
     case CreateThis: {
-        forNode(node).setType(SpecFinalObject);
+        // FIXME: We can fold this to NewObject if the incoming callee is a constant.
+        forNode(node).setType(m_graph, SpecFinalObject);
         break;
     }
         
-    case AllocationProfileWatchpoint:
-        node->setCanExit(true);
-        break;
-
     case NewObject:
         ASSERT(node->structure());
         forNode(node).set(m_graph, node->structure());
-        m_state.setHaveStructures(true);
         break;
         
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case BottomValue:
+        m_state.setDidClobber(true); // Prevent constant folding.
+        // This claims to return bottom.
+        break;
+        
+    case PutHint:
+        break;
+        
+    case MaterializeNewObject: {
+        StructureSet set;
+        
+        m_phiChildren->forAllTransitiveIncomingValues(
+            m_graph.varArgChild(node, 0).node(),
+            [&] (Node* incoming) {
+                set.add(incoming->castConstant<Structure*>());
+            });
+        
+        forNode(node).set(m_graph, set);
+        break;
+    }
+
     case CreateActivation:
+    case MaterializeCreateActivation:
         forNode(node).set(
             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
-        m_state.setHaveStructures(true);
         break;
         
-    case FunctionReentryWatchpoint:
-    case TypedArrayWatchpoint:
-        break;
-    
-    case CreateArguments:
-        forNode(node) = forNode(node->child1());
-        forNode(node).filter(~SpecEmpty);
-        forNode(node).merge(SpecArguments);
+    case CreateDirectArguments:
+        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
         break;
         
-    case TearOffActivation:
-    case TearOffArguments:
-        // Does nothing that is user-visible.
-        break;
-
-    case CheckArgumentsNotCreated:
-        if (isEmptySpeculation(
-                m_state.variables().operand(
-                    m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
-            m_state.setFoundConstants(true);
-        else
-            node->setCanExit(true);
-        break;
-        
-    case GetMyArgumentsLength:
-        // We know that this executable does not escape its arguments, so we can optimize
-        // the arguments a bit. Note that this is not sufficient to force constant folding
-        // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
-        // We perform further optimizations on this later on.
-        if (node->origin.semantic.inlineCallFrame) {
-            forNode(node).set(
-                m_graph, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
-        } else
-            forNode(node).setType(SpecInt32);
-        node->setCanExit(
-            !isEmptySpeculation(
-                m_state.variables().operand(
-                    m_graph.argumentsRegisterFor(node->origin.semantic)).m_type));
+    case CreateScopedArguments:
+        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
         break;
         
-    case GetMyArgumentsLengthSafe:
-        // This potentially clobbers all structures if the arguments object had a getter
-        // installed on the length property.
-        clobberWorld(node->origin.semantic, clobberLimit);
-        // We currently make no guarantee about what this returns because it does not
-        // speculate that the length property is actually a length.
-        forNode(node).makeHeapTop();
+    case CreateClonedArguments:
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
         
-    case GetMyArgumentByVal:
-        node->setCanExit(true);
-        // We know that this executable does not escape its arguments, so we can optimize
-        // the arguments a bit. Note that this ends up being further optimized by the
-        // ArgumentsSimplificationPhase.
-        forNode(node).makeHeapTop();
+    case NewFunction:
+        forNode(node).set(
+            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
         break;
         
-    case GetMyArgumentByValSafe:
-        node->setCanExit(true);
-        // This potentially clobbers all structures if the property we're accessing has
-        // a getter. We don't speculate against this.
-        clobberWorld(node->origin.semantic, clobberLimit);
-        // And the result is unknown.
-        forNode(node).makeHeapTop();
+    case GetCallee:
+        if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())) {
+            InferredValue* singleton = executable->singletonFunction();
+            if (JSValue value = singleton->inferredValue()) {
+                m_graph.watchpoints().addLazily(singleton);
+                JSFunction* function = jsCast<JSFunction*>(value);
+                setConstant(node, *m_graph.freeze(function));
+                break;
+            }
+        }
+        forNode(node).setType(m_graph, SpecFunction);
         break;
         
-    case NewFunction: {
-        AbstractValue& value = forNode(node);
-        value = forNode(node->child1());
+    case GetArgumentCount:
+        forNode(node).setType(SpecInt32);
+        break;
         
-        if (!(value.m_type & SpecEmpty)) {
-            m_state.setFoundConstants(true);
-            break;
+    case GetGetter: {
+        JSValue base = forNode(node->child1()).m_value;
+        if (base) {
+            GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
+            if (!getterSetter->isGetterNull()) {
+                setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
+                break;
+            }
         }
-
-        value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
+        
+        forNode(node).setType(m_graph, SpecObject);
         break;
     }
-
-    case NewFunctionExpression:
-    case NewFunctionNoCheck:
-        forNode(node).set(
-            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
-        m_state.setHaveStructures(true);
-        break;
         
-    case GetCallee:
-        forNode(node).setType(SpecFunction);
+    case GetSetter: {
+        JSValue base = forNode(node->child1()).m_value;
+        if (base) {
+            GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
+            if (!getterSetter->isSetterNull()) {
+                setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
+                break;
+            }
+        }
+        
+        forNode(node).setType(m_graph, SpecObject);
         break;
+    }
         
-    case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
-    case GetMyScope:
-    case SkipTopScope:
-        forNode(node).setType(SpecObjectOther);
+    case GetScope:
+        if (JSValue base = forNode(node->child1()).m_value) {
+            if (JSFunction* function = jsDynamicCast<JSFunction*>(base)) {
+                setConstant(node, *m_graph.freeze(function->scope()));
+                break;
+            }
+        }
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
 
     case SkipScope: {
         JSValue child = forNode(node->child1()).value();
         if (child) {
-            setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
+            setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
             break;
         }
-        forNode(node).setType(SpecObjectOther);
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
     }
 
-    case GetClosureRegisters:
-        forNode(node).clear(); // The result is not a JS value.
-        break;
-
     case GetClosureVar:
+        if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
+            setConstant(node, *m_graph.freeze(value));
+            break;
+        }
         forNode(node).makeHeapTop();
         break;
             
     case PutClosureVar:
-        clobberCapturedVars(node->origin.semantic);
+        break;
+        
+    case GetFromArguments:
+        forNode(node).makeHeapTop();
+        break;
+        
+    case PutToArguments:
         break;
             
     case GetById:
-    case GetByIdFlush:
-        node->setCanExit(true);
+    case GetByIdFlush: {
         if (!node->prediction()) {
             m_state.setIsValid(false);
             break;
         }
-        if (isCellSpeculation(node->child1()->prediction())) {
-            if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
-                GetByIdStatus status = GetByIdStatus::computeFor(
-                    m_graph.m_vm, structure,
-                    m_graph.identifiers()[node->identifierNumber()]);
-                if (status.isSimple() && status.numVariants() == 1) {
-                    // Assert things that we can't handle and that the computeFor() method
-                    // above won't be able to return.
-                    ASSERT(status[0].structureSet().size() == 1);
-                    ASSERT(!status[0].chain());
-                    
-                    if (status[0].specificValue())
-                        setConstant(node, status[0].specificValue());
-                    else
-                        forNode(node).makeHeapTop();
-                    filter(node->child1(), status[0].structureSet());
+        
+        AbstractValue& value = forNode(node->child1());
+        if (!value.m_structure.isTop() && !value.m_structure.isClobbered()
+            && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
+            GetByIdStatus status = GetByIdStatus::computeFor(
+                value.m_structure.set(), m_graph.identifiers()[node->identifierNumber()]);
+            if (status.isSimple()) {
+                // Figure out what the result is going to be - is it TOP, a constant, or maybe
+                // something more subtle?
+                AbstractValue result;
+                for (unsigned i = status.numVariants(); i--;) {
+                    DFG_ASSERT(m_graph, node, !status[i].alternateBase());
+                    JSValue constantResult =
+                        m_graph.tryGetConstantProperty(value, status[i].offset());
+                    if (!constantResult) {
+                        result.makeHeapTop();
+                        break;
+                    }
                     
-                    m_state.setFoundConstants(true);
-                    m_state.setHaveStructures(true);
-                    break;
+                    AbstractValue thisResult;
+                    thisResult.set(
+                        m_graph, *m_graph.freeze(constantResult),
+                        m_state.structureClobberState());
+                    result.merge(thisResult);
                 }
+                if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
+                    m_state.setFoundConstants(true);
+                forNode(node) = result;
+                break;
             }
         }
+
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
+    }
             
-    case GetArrayLength:
-        node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
+    case GetArrayLength: {
+        JSArrayBufferView* view = m_graph.tryGetFoldableView(
+            forNode(node->child1()).m_value, node->arrayMode());
+        if (view) {
+            setConstant(node, jsNumber(view->length()));
+            break;
+        }
         forNode(node).setType(SpecInt32);
         break;
-        
-    case CheckExecutable: {
-        // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
-        // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
-        // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
-        // https://bugs.webkit.org/show_bug.cgi?id=106201
-        node->setCanExit(true);
-        break;
     }
-
+        
     case CheckStructure: {
-        // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
         AbstractValue& value = forNode(node->child1());
         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
 
         StructureSet& set = node->structureSet();
-
-        if (value.m_currentKnownStructure.isSubsetOf(set)) {
-            m_state.setFoundConstants(true);
-            break;
-        }
-
-        node->setCanExit(true);
-        m_state.setHaveStructures(true);
-
-        // If this structure check is attempting to prove knowledge already held in
-        // the futurePossibleStructure set then the constant folding phase should
-        // turn this into a watchpoint instead.
-        if (value.m_futurePossibleStructure.isSubsetOf(set)
-            && value.m_futurePossibleStructure.hasSingleton()) {
+        
+        // It's interesting that we could have proven that the object has a larger structure set
+        // that includes the set we're testing. In that case we could make the structure check
+        // more efficient. We currently don't.
+        
+        if (value.m_structure.isSubsetOf(set)) {
             m_state.setFoundConstants(true);
-            filter(value, value.m_futurePossibleStructure.singleton());
             break;
         }
 
@@ -1542,21 +1789,59 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         break;
     }
         
-    case StructureTransitionWatchpoint: {
+    case CheckStructureImmediate: {
+        // FIXME: This currently can only reason about one structure at a time.
+        // https://bugs.webkit.org/show_bug.cgi?id=136988
+        
         AbstractValue& value = forNode(node->child1());
-
-        filter(value, node->structure());
-        m_state.setHaveStructures(true);
-        node->setCanExit(true);
+        StructureSet& set = node->structureSet();
+        
+        if (value.value()) {
+            if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
+                if (set.contains(structure)) {
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            }
+            m_state.setIsValid(false);
+            break;
+        }
+        
+        if (m_phiChildren) {
+            bool allGood = true;
+            m_phiChildren->forAllTransitiveIncomingValues(
+                node,
+                [&] (Node* incoming) {
+                    if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
+                        if (set.contains(structure))
+                            return;
+                    }
+                    allGood = false;
+                });
+            if (allGood) {
+                m_state.setFoundConstants(true);
+                break;
+            }
+        }
+            
+        if (Structure* structure = set.onlyStructure()) {
+            filterByValue(node->child1(), *m_graph.freeze(structure));
+            break;
+        }
+        
+        // Aw shucks, we can't do anything!
         break;
     }
-            
+        
     case PutStructure:
-    case PhantomPutStructure:
-        if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
-            clobberStructures(clobberLimit);
-            forNode(node->child1()).set(m_graph, node->structureTransitionData().newStructure);
-            m_state.setHaveStructures(true);
+        if (!forNode(node->child1()).m_structure.isClear()) {
+            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
+                m_state.setFoundConstants(true);
+            else {
+                observeTransition(
+                    clobberLimit, node->transition()->previous, node->transition()->next);
+                forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
+            }
         }
         break;
     case GetButterfly:
@@ -1569,7 +1854,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             m_state.setFoundConstants(true);
             break;
         }
-        node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
         switch (node->arrayMode().type()) {
         case Array::String:
             filter(node->child1(), SpecString);
@@ -1580,8 +1864,11 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
             break;
-        case Array::Arguments:
-            filter(node->child1(), SpecArguments);
+        case Array::DirectArguments:
+            filter(node->child1(), SpecDirectArguments);
+            break;
+        case Array::ScopedArguments:
+            filter(node->child1(), SpecScopedArguments);
             break;
         case Array::Int8Array:
             filter(node->child1(), SpecInt8Array);
@@ -1615,7 +1902,6 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             break;
         }
         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
-        m_state.setHaveStructures(true);
         break;
     }
     case Arrayify: {
@@ -1623,72 +1909,143 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             m_state.setFoundConstants(true);
             break;
         }
-        ASSERT(node->arrayMode().conversion() == Array::Convert
-            || node->arrayMode().conversion() == Array::RageConvert);
-        node->setCanExit(true);
+        ASSERT(node->arrayMode().conversion() == Array::Convert);
         clobberStructures(clobberLimit);
         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
-        m_state.setHaveStructures(true);
         break;
     }
     case ArrayifyToStructure: {
         AbstractValue& value = forNode(node->child1());
-        StructureSet set = node->structure();
-        if (value.m_futurePossibleStructure.isSubsetOf(set)
-            || value.m_currentKnownStructure.isSubsetOf(set))
+        if (value.m_structure.isSubsetOf(StructureSet(node->structure())))
             m_state.setFoundConstants(true);
-        node->setCanExit(true);
         clobberStructures(clobberLimit);
-        filter(value, set);
-        m_state.setHaveStructures(true);
+        
+        // We have a bunch of options of how to express the abstract set at this point. Let set S
+        // be the set of structures that the value had before clobbering and assume that all of
+        // them are watchable. The new value should be the least expressible upper bound of the
+        // intersection of "values that currently have structure = node->structure()" and "values
+        // that have structure in S plus any structure transition-reachable from S". Assume that
+        // node->structure() is not in S but it is transition-reachable from S. Then we would
+        // like to say that the result is "values that have structure = node->structure() until
+        // we invalidate", but there is no way to express this using the AbstractValue syntax. So
+        // we must choose between:
+        //
+        // 1) "values that currently have structure = node->structure()". This is a valid
+        //    superset of the value that we really want, and it's specific enough to satisfy the
+        //    preconditions of the array access that this is guarding. It's also specific enough
+        //    to allow relevant optimizations in the case that we didn't have a contradiction
+        //    like in this example. Notice that in the abscence of any contradiction, this result
+        //    is precise rather than being a conservative LUB.
+        //
+        // 2) "values that currently hava structure in S plus any structure transition-reachable
+        //    from S". This is also a valid superset of the value that we really want, but it's
+        //    not specific enough to satisfy the preconditions of the array access that this is
+        //    guarding - so playing such shenanigans would preclude us from having assertions on
+        //    the typing preconditions of any array accesses. This would also not be a desirable
+        //    answer in the absence of a contradiction.
+        //
+        // Note that it's tempting to simply say that the resulting value is BOTTOM because of
+        // the contradiction. That would be wrong, since we haven't hit an invalidation point,
+        // yet.
+        value.set(m_graph, node->structure());
+        break;
+    }
+    case GetIndexedPropertyStorage: {
+        JSArrayBufferView* view = m_graph.tryGetFoldableView(
+            forNode(node->child1()).m_value, node->arrayMode());
+        if (view)
+            m_state.setFoundConstants(true);
+        forNode(node).clear();
         break;
     }
-    case GetIndexedPropertyStorage:
     case ConstantStoragePointer: {
         forNode(node).clear();
         break; 
     }
         
     case GetTypedArrayByteOffset: {
+        JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
+        if (view) {
+            setConstant(node, jsNumber(view->byteOffset()));
+            break;
+        }
         forNode(node).setType(SpecInt32);
         break;
     }
         
     case GetByOffset: {
+        StorageAccessData& data = node->storageAccessData();
+        JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
+        if (result) {
+            setConstant(node, *m_graph.freeze(result));
+            break;
+        }
+        
         forNode(node).makeHeapTop();
         break;
     }
         
+    case GetGetterSetterByOffset: {
+        StorageAccessData& data = node->storageAccessData();
+        JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
+        if (result && jsDynamicCast<GetterSetter*>(result)) {
+            setConstant(node, *m_graph.freeze(result));
+            break;
+        }
+        
+        forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
+        break;
+    }
+        
     case MultiGetByOffset: {
-        AbstractValue& value = forNode(node->child1());
-        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
-
-        if (Structure* structure = value.bestProvenStructure()) {
-            bool done = false;
-            for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
-                const GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
-                if (!variant.structureSet().contains(structure))
-                    continue;
-                
-                if (variant.chain())
-                    break;
-                
-                filter(value, structure);
-                forNode(node).makeHeapTop();
-                m_state.setFoundConstants(true);
-                done = true;
-                break;
+        // This code will filter the base value in a manner that is possibly different (either more
+        // or less precise) than the way it would be filtered if this was strength-reduced to a
+        // CheckStructure. This is fine. It's legal for different passes over the code to prove
+        // different things about the code, so long as all of them are sound. That even includes
+        // one guy proving that code should never execute (due to a contradiction) and another guy
+        // not finding that contradiction. If someone ever proved that there would be a
+        // contradiction then there must always be a contradiction even if subsequent passes don't
+        // realize it. This is the case here.
+        
+        // Ordinarily you have to be careful with calling setFoundConstants()
+        // because of the effect on compile times, but this node is FTL-only.
+        m_state.setFoundConstants(true);
+        
+        AbstractValue base = forNode(node->child1());
+        StructureSet baseSet;
+        AbstractValue result;
+        for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
+            GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
+            StructureSet set = variant.structureSet();
+            set.filter(base);
+            if (set.isEmpty())
+                continue;
+            baseSet.merge(set);
+            
+            JSValue baseForLoad;
+            if (variant.alternateBase())
+                baseForLoad = variant.alternateBase();
+            else
+                baseForLoad = base.m_value;
+            JSValue constantResult =
+                m_graph.tryGetConstantProperty(
+                    baseForLoad, variant.baseStructure(), variant.offset());
+            if (!constantResult) {
+                result.makeHeapTop();
+                continue;
             }
-            if (done)
-                break;
+            AbstractValue thisResult;
+            thisResult.set(
+                m_graph,
+                *m_graph.freeze(constantResult),
+                m_state.structureClobberState());
+            result.merge(thisResult);
         }
         
-        StructureSet set;
-        for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
-            set.addAll(node->multiGetByOffsetData().variants[i].structureSet());
+        if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
+            m_state.setIsValid(false);
         
-        filter(node->child1(), set);
-        forNode(node).makeHeapTop();
+        forNode(node) = result;
         break;
     }
             
@@ -1697,71 +2054,74 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     }
         
     case MultiPutByOffset: {
-        AbstractValue& value = forNode(node->child1());
-        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
-
-        if (Structure* structure = value.bestProvenStructure()) {
-            bool done = false;
-            for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
-                const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
-                if (variant.oldStructure() != structure)
-                    continue;
-                
-                if (variant.kind() == PutByIdVariant::Replace) {
-                    filter(node->child1(), structure);
-                    m_state.setFoundConstants(true);
-                    m_state.setHaveStructures(true);
-                    done = true;
-                    break;
-                }
-                
-                ASSERT(variant.kind() == PutByIdVariant::Transition);
-                clobberStructures(clobberLimit);
-                forNode(node->child1()).set(m_graph, variant.newStructure());
-                m_state.setFoundConstants(true);
-                m_state.setHaveStructures(true);
-                done = true;
-                break;
-            }
-            if (done)
-                break;
-        }
+        StructureSet newSet;
+        TransitionVector transitions;
         
-        clobberStructures(clobberLimit);
+        // Ordinarily you have to be careful with calling setFoundConstants()
+        // because of the effect on compile times, but this node is FTL-only.
+        m_state.setFoundConstants(true);
+        
+        AbstractValue base = forNode(node->child1());
         
-        StructureSet newSet;
         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
-            if (variant.kind() == PutByIdVariant::Replace) {
-                if (value.m_currentKnownStructure.contains(variant.structure()))
-                    newSet.addAll(variant.structure());
+            StructureSet thisSet = variant.oldStructure();
+            thisSet.filter(base);
+            if (thisSet.isEmpty())
                 continue;
+            if (variant.kind() == PutByIdVariant::Transition) {
+                if (thisSet.onlyStructure() != variant.newStructure()) {
+                    transitions.append(
+                        Transition(variant.oldStructureForTransition(), variant.newStructure()));
+                } // else this is really a replace.
+                newSet.add(variant.newStructure());
+            } else {
+                ASSERT(variant.kind() == PutByIdVariant::Replace);
+                newSet.merge(thisSet);
             }
-            ASSERT(variant.kind() == PutByIdVariant::Transition);
-            if (value.m_currentKnownStructure.contains(variant.oldStructure()))
-                newSet.addAll(variant.newStructure());
         }
         
-        // Use filter(value, set) as a way of setting the structure set. This works because
-        // we would have already made the set be TOP before this. Filtering top is another 
-        // way of setting.
-        filter(node->child1(), newSet);
+        observeTransitions(clobberLimit, transitions);
+        if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
+            m_state.setIsValid(false);
+        break;
+    }
+        
+    case GetExecutable: {
+        JSValue value = forNode(node->child1()).value();
+        if (value) {
+            JSFunction* function = jsDynamicCast<JSFunction*>(value);
+            if (function) {
+                setConstant(node, *m_graph.freeze(function->executable()));
+                break;
+            }
+        }
+        forNode(node).setType(m_graph, SpecCellOther);
         break;
     }
     
-    case CheckFunction: {
+    case CheckCell: {
         JSValue value = forNode(node->child1()).value();
-        if (value == node->function()) {
+        if (value == node->cellOperand()->value()) {
             m_state.setFoundConstants(true);
             ASSERT(value);
             break;
         }
-        
-        node->setCanExit(true); // Lies! We can do better.
-        filterByValue(node->child1(), node->function());
+        filterByValue(node->child1(), *node->cellOperand());
         break;
     }
+
+    case CheckNotEmpty: {
+        AbstractValue& value = forNode(node->child1());
+        if (!(value.m_type & SpecEmpty)) {
+            m_state.setFoundConstants(true);
+            break;
+        }
         
+        filter(value, ~SpecEmpty);
+        break;
+    }
+
     case CheckInBounds: {
         JSValue left = forNode(node->child1()).value();
         JSValue right = forNode(node->child2()).value();
@@ -1770,82 +2130,140 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             m_state.setFoundConstants(true);
             break;
         }
-        
-        node->setCanExit(true);
         break;
     }
         
     case PutById:
     case PutByIdFlush:
-    case PutByIdDirect:
-        node->setCanExit(true);
-        if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
+    case PutByIdDirect: {
+        AbstractValue& value = forNode(node->child1());
+        if (!value.m_structure.isTop() && !value.m_structure.isClobbered()) {
             PutByIdStatus status = PutByIdStatus::computeFor(
-                m_graph.m_vm,
                 m_graph.globalObjectFor(node->origin.semantic),
-                structure,
+                value.m_structure.set(),
                 m_graph.identifiers()[node->identifierNumber()],
                 node->op() == PutByIdDirect);
-            if (status.isSimple() && status.numVariants() == 1) {
-                if (status[0].kind() == PutByIdVariant::Replace) {
-                    filter(node->child1(), structure);
-                    m_state.setFoundConstants(true);
-                    m_state.setHaveStructures(true);
-                    break;
+            
+            if (status.isSimple()) {
+                StructureSet newSet;
+                TransitionVector transitions;
+                
+                for (unsigned i = status.numVariants(); i--;) {
+                    const PutByIdVariant& variant = status[i];
+                    if (variant.kind() == PutByIdVariant::Transition) {
+                        transitions.append(
+                            Transition(
+                                variant.oldStructureForTransition(), variant.newStructure()));
+                        m_graph.registerStructure(variant.newStructure());
+                        newSet.add(variant.newStructure());
+                    } else {
+                        ASSERT(variant.kind() == PutByIdVariant::Replace);
+                        newSet.merge(variant.oldStructure());
+                    }
                 }
-                if (status[0].kind() == PutByIdVariant::Transition) {
-                    clobberStructures(clobberLimit);
-                    forNode(node->child1()).set(m_graph, status[0].newStructure());
-                    m_state.setHaveStructures(true);
+                
+                if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
                     m_state.setFoundConstants(true);
-                    break;
-                }
+                
+                observeTransitions(clobberLimit, transitions);
+                if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
+                    m_state.setIsValid(false);
+                break;
             }
         }
+        
         clobberWorld(node->origin.semantic, clobberLimit);
         break;
+    }
         
-    case In:
+    case In: {
         // FIXME: We can determine when the property definitely exists based on abstract
         // value information.
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(SpecBoolean);
         break;
+    }
             
+    case GetEnumerableLength: {
+        forNode(node).setType(SpecInt32);
+        break;
+    }
+    case HasGenericProperty: {
+        forNode(node).setType(SpecBoolean);
+        break;
+    }
+    case HasStructureProperty: {
+        forNode(node).setType(SpecBoolean);
+        break;
+    }
+    case HasIndexedProperty: {
+        ArrayMode mode = node->arrayMode();
+        switch (mode.type()) {
+        case Array::Int32:
+        case Array::Double:
+        case Array::Contiguous:
+        case Array::ArrayStorage: {
+            break;
+        }
+        default: {
+            clobberWorld(node->origin.semantic, clobberLimit);
+            break;
+        }
+        }
+        forNode(node).setType(SpecBoolean);
+        break;
+    }
+    case GetDirectPname: {
+        clobberWorld(node->origin.semantic, clobberLimit);
+        forNode(node).makeHeapTop();
+        break;
+    }
+    case GetPropertyEnumerator: {
+        forNode(node).setType(m_graph, SpecCell);
+        break;
+    }
+    case GetEnumeratorStructurePname: {
+        forNode(node).setType(m_graph, SpecString | SpecOther);
+        break;
+    }
+    case GetEnumeratorGenericPname: {
+        forNode(node).setType(m_graph, SpecString | SpecOther);
+        break;
+    }
+    case ToIndexString: {
+        forNode(node).setType(m_graph, SpecString);
+        break;
+    }
+
     case GetGlobalVar:
         forNode(node).makeHeapTop();
         break;
         
-    case VariableWatchpoint:
     case VarInjectionWatchpoint:
-        node->setCanExit(true);
-        break;
-            
     case PutGlobalVar:
     case NotifyWrite:
         break;
             
     case CheckHasInstance:
-        node->setCanExit(true);
         // Sadly, we don't propagate the fact that we've done CheckHasInstance
         break;
             
     case InstanceOf:
-        node->setCanExit(true);
         // Again, sadly, we don't propagate the fact that we've done InstanceOf
         forNode(node).setType(SpecBoolean);
         break;
             
     case Phi:
         RELEASE_ASSERT(m_graph.m_form == SSA);
-        // The state of this node would have already been decided.
+        // The state of this node would have already been decided, but it may have become a
+        // constant, in which case we'd like to know.
+        if (forNode(node).m_value)
+            m_state.setFoundConstants(true);
         break;
         
     case Upsilon: {
         m_state.createValueForNode(node->phi());
-        AbstractValue& value = forNode(node->child1());
-        forNode(node) = value;
-        forNode(node->phi()) = value;
+        forNode(node->phi()) = forNode(node->child1());
         break;
     }
         
@@ -1855,56 +2273,70 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             
     case Call:
     case Construct:
-        node->setCanExit(true);
+    case NativeCall:
+    case NativeConstruct:
+    case CallVarargs:
+    case CallForwardVarargs:
+    case ConstructVarargs:
+    case ConstructForwardVarargs:
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
 
     case ForceOSRExit:
-        node->setCanExit(true);
+    case CheckBadCell:
         m_state.setIsValid(false);
         break;
         
     case InvalidationPoint:
-        node->setCanExit(true);
+        forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
+        m_state.setStructureClobberState(StructuresAreWatched);
         break;
 
     case CheckWatchdogTimer:
-        node->setCanExit(true);
         break;
 
     case Breakpoint:
     case ProfileWillCall:
     case ProfileDidCall:
+    case ProfileType:
+    case ProfileControlFlow:
     case Phantom:
-    case HardPhantom:
-    case Check:
     case CountExecution:
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
         break;
 
-    case StoreBarrier: {
-        filter(node->child1(), SpecCell);
+    case Check: {
+        // Simplify out checks that don't actually do checking.
+        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+            Edge edge = node->children.child(i);
+            if (!edge)
+                break;
+            if (edge.isProved() || edge.willNotHaveCheck()) {
+                m_state.setFoundConstants(true);
+                break;
+            }
+        }
         break;
     }
 
-    case StoreBarrierWithNullCheck: {
+    case StoreBarrier: {
+        filter(node->child1(), SpecCell);
         break;
     }
 
     case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter:
     case LoopHint:
-        // We pretend that it can exit because it may want to get all state.
-        node->setCanExit(true);
+    case ZombieHint:
         break;
 
-    case ZombieHint:
     case Unreachable:
     case LastNodeType:
     case ArithIMul:
     case FiatInt52:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_graph, node, "Unexpected node type");
         break;
     }
     
@@ -1921,9 +2353,8 @@ template<typename AbstractStateType>
 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
 {
     Node* node = m_state.block()->at(indexInBlock);
-    if (!startExecuting(node))
-        return true;
     
+    startExecuting();
     executeEdges(node);
     return executeEffects(indexInBlock, node);
 }
@@ -1931,79 +2362,99 @@ bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
 template<typename AbstractStateType>
 bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
 {
-    if (!startExecuting(node))
-        return true;
-    
+    startExecuting();
     executeEdges(node);
     return executeEffects(UINT_MAX, node);
 }
 
 template<typename AbstractStateType>
 void AbstractInterpreter<AbstractStateType>::clobberWorld(
-    const CodeOrigin& codeOrigin, unsigned clobberLimit)
+    const CodeOrigin&, unsigned clobberLimit)
 {
-    clobberCapturedVars(codeOrigin);
     clobberStructures(clobberLimit);
 }
 
 template<typename AbstractStateType>
-void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
+template<typename Functor>
+void AbstractInterpreter<AbstractStateType>::forAllValues(
+    unsigned clobberLimit, Functor& functor)
 {
-    if (codeOrigin.inlineCallFrame) {
-        const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
-        for (size_t i = capturedVars.size(); i--;) {
-            if (!capturedVars.quickGet(i))
-                continue;
-            m_state.variables().local(i).makeHeapTop();
-        }
-    } else {
-        for (size_t i = m_codeBlock->m_numVars; i--;) {
-            if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
-                m_state.variables().local(i).makeHeapTop();
-        }
-    }
-
-    for (size_t i = m_state.variables().numberOfArguments(); i--;) {
-        if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
-            m_state.variables().argument(i).makeHeapTop();
-    }
-}
-
-template<typename AbstractStateType>
-void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
-{
-    if (!m_state.haveStructures())
-        return;
+    SamplingRegion samplingRegion("DFG AI For All Values");
     if (clobberLimit >= m_state.block()->size())
         clobberLimit = m_state.block()->size();
     else
         clobberLimit++;
     ASSERT(clobberLimit <= m_state.block()->size());
     for (size_t i = clobberLimit; i--;)
-        forNode(m_state.block()->at(i)).clobberStructures();
+        functor(forNode(m_state.block()->at(i)));
     if (m_graph.m_form == SSA) {
         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
         for (; iter != end; ++iter)
-            forNode(*iter).clobberStructures();
+            functor(forNode(*iter));
     }
     for (size_t i = m_state.variables().numberOfArguments(); i--;)
-        m_state.variables().argument(i).clobberStructures();
+        functor(m_state.variables().argument(i));
     for (size_t i = m_state.variables().numberOfLocals(); i--;)
-        m_state.variables().local(i).clobberStructures();
-    m_state.setHaveStructures(true);
+        functor(m_state.variables().local(i));
+}
+
+template<typename AbstractStateType>
+void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
+{
+    SamplingRegion samplingRegion("DFG AI Clobber Structures");
+    forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
+    setDidClobber();
+}
+
+template<typename AbstractStateType>
+void AbstractInterpreter<AbstractStateType>::observeTransition(
+    unsigned clobberLimit, Structure* from, Structure* to)
+{
+    AbstractValue::TransitionObserver transitionObserver(from, to);
+    forAllValues(clobberLimit, transitionObserver);
+    
+    ASSERT(!from->dfgShouldWatch()); // We don't need to claim to be in a clobbered state because 'from' was never watchable (during the time we were compiling), hence no constants ever introduced into the DFG IR that ever had a watchable structure would ever have the same structure as from.
+}
+
+template<typename AbstractStateType>
+void AbstractInterpreter<AbstractStateType>::observeTransitions(
+    unsigned clobberLimit, const TransitionVector& vector)
+{
+    AbstractValue::TransitionsObserver transitionsObserver(vector);
+    forAllValues(clobberLimit, transitionsObserver);
+    
+    if (!ASSERT_DISABLED) {
+        // We don't need to claim to be in a clobbered state because none of the Transition::previous structures are watchable.
+        for (unsigned i = vector.size(); i--;)
+            ASSERT(!vector[i].previous->dfgShouldWatch());
+    }
+}
+
+template<typename AbstractStateType>
+void AbstractInterpreter<AbstractStateType>::setDidClobber()
+{
     m_state.setDidClobber(true);
+    m_state.setStructureClobberState(StructuresAreClobbered);
+}
+
+template<typename AbstractStateType>
+void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out) const
+{
+    const_cast<AbstractInterpreter<AbstractStateType>*>(this)->dump(out);
 }
 
 template<typename AbstractStateType>
 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
 {
     CommaPrinter comma(" ");
+    HashSet<Node*> seen;
     if (m_graph.m_form == SSA) {
         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
         for (; iter != end; ++iter) {
             Node* node = *iter;
+            seen.add(node);
             AbstractValue& value = forNode(node);
             if (value.isClear())
                 continue;
@@ -2012,11 +2463,25 @@ void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
     }
     for (size_t i = 0; i < m_state.block()->size(); ++i) {
         Node* node = m_state.block()->at(i);
+        seen.add(node);
         AbstractValue& value = forNode(node);
         if (value.isClear())
             continue;
         out.print(comma, node, ":", value);
     }
+    if (m_graph.m_form == SSA) {
+        HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtTail.begin();
+        HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtTail.end();
+        for (; iter != end; ++iter) {
+            Node* node = *iter;
+            if (seen.contains(node))
+                continue;
+            AbstractValue& value = forNode(node);
+            if (value.isClear())
+                continue;
+            out.print(comma, node, ":", value);
+        }
+    }
 }
 
 template<typename AbstractStateType>
@@ -2051,7 +2516,7 @@ FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
 
 template<typename AbstractStateType>
 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
-    AbstractValue& abstractValue, JSValue concreteValue)
+    AbstractValue& abstractValue, FrozenValue concreteValue)
 {
     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
         return FiltrationOK;
index d39ca877c2105fec60511852c9f6f9aaba39b0fc..08466aacb301b49fe6d5595bfc441ccb598f4153 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "DFGGraph.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace DFG {
 
-void AbstractValue::setMostSpecific(Graph& graph, JSValue value)
+void AbstractValue::observeTransitions(const TransitionVector& vector)
 {
-    if (!!value && value.isCell()) {
-        Structure* structure = value.asCell()->structure();
-        m_currentKnownStructure = structure;
-        setFuturePossibleStructure(graph, structure);
-        m_arrayModes = asArrayModes(structure->indexingType());
-    } else {
-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
-        m_arrayModes = 0;
+    if (m_type & SpecCell) {
+        m_structure.observeTransitions(vector);
+        ArrayModes newModes = 0;
+        for (unsigned i = vector.size(); i--;) {
+            if (m_arrayModes & asArrayModes(vector[i].previous->indexingType()))
+                newModes |= asArrayModes(vector[i].next->indexingType());
+        }
+        m_arrayModes |= newModes;
     }
-        
-    m_type = speculationFromValue(value);
-    m_value = value;
-        
     checkConsistency();
 }
 
-void AbstractValue::set(Graph& graph, JSValue value)
+void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState)
 {
-    if (!!value && value.isCell()) {
-        m_currentKnownStructure.makeTop();
-        Structure* structure = value.asCell()->structure();
-        setFuturePossibleStructure(graph, structure);
-        m_arrayModes = asArrayModes(structure->indexingType());
-        clobberArrayModes();
+    if (!!value && value.value().isCell()) {
+        Structure* structure = value.structure();
+        if (graph.registerStructure(structure) == StructureRegisteredAndWatched) {
+            m_structure = structure;
+            if (clobberState == StructuresAreClobbered) {
+                m_arrayModes = ALL_ARRAY_MODES;
+                m_structure.clobber();
+            } else
+                m_arrayModes = asArrayModes(structure->indexingType());
+        } else {
+            m_structure.makeTop();
+            m_arrayModes = ALL_ARRAY_MODES;
+        }
     } else {
-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
+        m_structure.clear();
         m_arrayModes = 0;
     }
     
-    m_type = speculationFromValue(value);
-    m_value = value;
+    m_type = speculationFromValue(value.value());
+    m_value = value.value();
     
     checkConsistency();
+    assertIsRegistered(graph);
 }
 
 void AbstractValue::set(Graph& graph, Structure* structure)
 {
-    m_currentKnownStructure = structure;
-    setFuturePossibleStructure(graph, structure);
+    m_structure = structure;
     m_arrayModes = asArrayModes(structure->indexingType());
     m_type = speculationFromStructure(structure);
     m_value = JSValue();
     
     checkConsistency();
+    assertIsRegistered(graph);
+}
+
+void AbstractValue::set(Graph& graph, const StructureSet& set)
+{
+    m_structure = set;
+    m_arrayModes = set.arrayModesFromStructures();
+    m_type = set.speculationFromStructures();
+    m_value = JSValue();
+    
+    checkConsistency();
+    assertIsRegistered(graph);
 }
 
-void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
+void AbstractValue::setType(Graph& graph, SpeculatedType type)
+{
+    SpeculatedType cellType = type & SpecCell;
+    if (cellType) {
+        if (!(cellType & ~SpecString))
+            m_structure = graph.m_vm.stringStructure.get();
+        else if (isSymbolSpeculation(cellType))
+            m_structure = graph.m_vm.symbolStructure.get();
+        else
+            m_structure.makeTop();
+        m_arrayModes = ALL_ARRAY_MODES;
+    } else {
+        m_structure.clear();
+        m_arrayModes = 0;
+    }
+    m_type = type;
+    m_value = JSValue();
+    checkConsistency();
+}
+
+void AbstractValue::fixTypeForRepresentation(Graph& graph, NodeFlags representation, Node* node)
 {
     if (representation == NodeResultDouble) {
         if (m_value) {
@@ -95,39 +129,64 @@ void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
             m_type &= ~SpecMachineInt;
             m_type |= SpecInt52AsDouble;
         }
-        if (m_type & ~SpecFullDouble) {
-            startCrashing();
-            dataLog("Abstract value ", *this, " for double node has type outside SpecFullDouble.\n");
-            CRASH();
-        }
+        if (m_type & ~SpecFullDouble)
+            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for double node has type outside SpecFullDouble.\n").data());
     } else if (representation == NodeResultInt52) {
         if (m_type & SpecInt52AsDouble) {
             m_type &= ~SpecInt52AsDouble;
             m_type |= SpecInt52;
         }
-        if (m_type & ~SpecMachineInt) {
-            startCrashing();
-            dataLog("Abstract value ", *this, " for int52 node has type outside SpecMachineInt.\n");
-            CRASH();
-        }
+        if (m_type & ~SpecMachineInt)
+            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for int52 node has type outside SpecMachineInt.\n").data());
     } else {
         if (m_type & SpecInt52) {
             m_type &= ~SpecInt52;
             m_type |= SpecInt52AsDouble;
         }
-        if (m_type & ~SpecBytecodeTop) {
-            startCrashing();
-            dataLog("Abstract value ", *this, " for value node has type outside SpecBytecodeTop.\n");
-            CRASH();
-        }
+        if (m_type & ~SpecBytecodeTop)
+            DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for value node has type outside SpecBytecodeTop.\n").data());
     }
     
     checkConsistency();
 }
 
-void AbstractValue::fixTypeForRepresentation(Node* node)
+void AbstractValue::fixTypeForRepresentation(Graph& graph, Node* node)
 {
-    fixTypeForRepresentation(node->result());
+    fixTypeForRepresentation(graph, node->result(), node);
+}
+
+bool AbstractValue::mergeOSREntryValue(Graph& graph, JSValue value)
+{
+    AbstractValue oldMe = *this;
+    
+    if (isClear()) {
+        FrozenValue* frozenValue = graph.freeze(value);
+        if (frozenValue->pointsToHeap()) {
+            m_structure = frozenValue->structure();
+            m_arrayModes = asArrayModes(frozenValue->structure()->indexingType());
+        } else {
+            m_structure.clear();
+            m_arrayModes = 0;
+        }
+        
+        m_type = speculationFromValue(value);
+        m_value = value;
+    } else {
+        mergeSpeculation(m_type, speculationFromValue(value));
+        if (!!value && value.isCell()) {
+            Structure* structure = value.asCell()->structure();
+            graph.registerStructure(structure);
+            mergeArrayModes(m_arrayModes, asArrayModes(structure->indexingType()));
+            m_structure.merge(StructureSet(structure));
+        }
+        if (m_value != value)
+            m_value = JSValue();
+    }
+    
+    checkConsistency();
+    assertIsRegistered(graph);
+    
+    return oldMe != *this;
 }
 
 FiltrationResult AbstractValue::filter(Graph& graph, const StructureSet& other)
@@ -141,21 +200,29 @@ FiltrationResult AbstractValue::filter(Graph& graph, const StructureSet& other)
     
     m_type &= other.speculationFromStructures();
     m_arrayModes &= other.arrayModesFromStructures();
-    m_currentKnownStructure.filter(other);
+    m_structure.filter(other);
     
     // It's possible that prior to the above two statements we had (Foo, TOP), where
     // Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that
     // case, we will now have (None, [someStructure]). In general, we need to make
     // sure that new information gleaned from the SpeculatedType needs to be fed back
     // into the information gleaned from the StructureSet.
-    m_currentKnownStructure.filter(m_type);
+    m_structure.filter(m_type);
     
-    if (m_currentKnownStructure.hasSingleton())
-        setFuturePossibleStructure(graph, m_currentKnownStructure.singleton());
-        
     filterArrayModesByType();
     filterValueByType();
-    return normalizeClarity();
+    return normalizeClarity(graph);
+}
+
+FiltrationResult AbstractValue::changeStructure(Graph& graph, const StructureSet& other)
+{
+    m_type &= other.speculationFromStructures();
+    m_arrayModes = other.arrayModesFromStructures();
+    m_structure = other;
+    
+    filterValueByType();
+    
+    return normalizeClarity(graph);
 }
 
 FiltrationResult AbstractValue::filterArrayModes(ArrayModes arrayModes)
@@ -175,34 +242,77 @@ FiltrationResult AbstractValue::filter(SpeculatedType type)
     if ((m_type & type) == m_type)
         return FiltrationOK;
     
+    // Fast path for the case that we don't even have a cell.
+    if (!(m_type & SpecCell)) {
+        m_type &= type;
+        FiltrationResult result;
+        if (m_type == SpecNone) {
+            clear();
+            result = Contradiction;
+        } else
+            result = FiltrationOK;
+        checkConsistency();
+        return result;
+    }
+    
     m_type &= type;
     
     // It's possible that prior to this filter() call we had, say, (Final, TOP), and
     // the passed type is Array. At this point we'll have (None, TOP). The best way
     // to ensure that the structure filtering does the right thing is to filter on
     // the new type (None) rather than the one passed (Array).
-    m_currentKnownStructure.filter(m_type);
-    m_futurePossibleStructure.filter(m_type);
+    m_structure.filter(type);
     filterArrayModesByType();
     filterValueByType();
     return normalizeClarity();
 }
 
-FiltrationResult AbstractValue::filterByValue(JSValue value)
+FiltrationResult AbstractValue::filterByValue(const FrozenValue& value)
 {
-    FiltrationResult result = filter(speculationFromValue(value));
+    FiltrationResult result = filter(speculationFromValue(value.value()));
     if (m_type)
-        m_value = value;
+        m_value = value.value();
     return result;
 }
 
-void AbstractValue::setFuturePossibleStructure(Graph& graph, Structure* structure)
+bool AbstractValue::contains(Structure* structure) const
+{
+    return couldBeType(speculationFromStructure(structure))
+        && (m_arrayModes & arrayModeFromStructure(structure))
+        && m_structure.contains(structure);
+}
+
+FiltrationResult AbstractValue::filter(const AbstractValue& other)
 {
-    ASSERT(structure);
-    if (graph.watchpoints().isStillValid(structure->transitionWatchpointSet()))
-        m_futurePossibleStructure = structure;
-    else
-        m_futurePossibleStructure.makeTop();
+    m_type &= other.m_type;
+    m_structure.filter(other.m_structure);
+    m_arrayModes &= other.m_arrayModes;
+
+    m_structure.filter(m_type);
+    filterArrayModesByType();
+    filterValueByType();
+    
+    if (normalizeClarity() == Contradiction)
+        return Contradiction;
+    
+    if (m_value == other.m_value)
+        return FiltrationOK;
+    
+    // Neither of us are BOTTOM, so an empty value means TOP.
+    if (!m_value) {
+        // We previously didn't prove a value but now we have done so.
+        m_value = other.m_value; 
+        return FiltrationOK;
+    }
+    
+    if (!other.m_value) {
+        // We had proved a value but the other guy hadn't, so keep our proof.
+        return FiltrationOK;
+    }
+    
+    // We both proved there to be a specific value but they are different.
+    clear();
+    return Contradiction;
 }
 
 void AbstractValue::filterValueByType()
@@ -250,8 +360,7 @@ bool AbstractValue::shouldBeClear() const
         return true;
     
     if (!(m_type & ~SpecCell)
-        && (!m_arrayModes
-            || m_currentKnownStructure.isClear()))
+        && (!m_arrayModes || m_structure.isClear()))
         return true;
     
     return false;
@@ -275,12 +384,18 @@ FiltrationResult AbstractValue::normalizeClarity()
     return result;
 }
 
+FiltrationResult AbstractValue::normalizeClarity(Graph& graph)
+{
+    FiltrationResult result = normalizeClarity();
+    assertIsRegistered(graph);
+    return result;
+}
+
 #if !ASSERT_DISABLED
 void AbstractValue::checkConsistency() const
 {
     if (!(m_type & SpecCell)) {
-        ASSERT(m_currentKnownStructure.isClear());
-        ASSERT(m_futurePossibleStructure.isClear());
+        ASSERT(m_structure.isClear());
         ASSERT(!m_arrayModes);
     }
     
@@ -301,6 +416,11 @@ void AbstractValue::checkConsistency() const
     // we don't want to get pedantic about this as it would only increase the computational
     // complexity of the code.
 }
+
+void AbstractValue::assertIsRegistered(Graph& graph) const
+{
+    m_structure.assertIsRegistered(graph);
+}
 #endif
 
 void AbstractValue::dump(PrintStream& out) const
@@ -314,14 +434,19 @@ void AbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const
     if (m_type & SpecCell) {
         out.print(
             ", ", ArrayModesDump(m_arrayModes), ", ",
-            inContext(m_currentKnownStructure, context), ", ",
-            inContext(m_futurePossibleStructure, context));
+            inContext(m_structure, context));
     }
     if (!!m_value)
         out.print(", ", inContext(m_value, context));
     out.print(")");
 }
 
+void AbstractValue::validateReferences(const TrackedReferences& trackedReferences)
+{
+    trackedReferences.check(m_value);
+    m_structure.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index 14363dfa3f763b599f3413e1c7ce34754bbb7751..7318d0d44cbbc0d6375dd3a0ada8e803abe41c4a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "ArrayProfile.h"
 #include "DFGFiltrationResult.h"
+#include "DFGFrozenValue.h"
 #include "DFGNodeFlags.h"
 #include "DFGStructureAbstractValue.h"
+#include "DFGStructureClobberState.h"
 #include "JSCell.h"
 #include "SpeculatedType.h"
 #include "DumpContext.h"
 #include "StructureSet.h"
 
-namespace JSC { namespace DFG {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace DFG {
 
 class Graph;
 struct Node;
@@ -53,8 +59,7 @@ struct AbstractValue {
     {
         m_type = SpecNone;
         m_arrayModes = 0;
-        m_currentKnownStructure.clear();
-        m_futurePossibleStructure.clear();
+        m_structure.clear();
         m_value = JSValue();
         checkConsistency();
     }
@@ -72,18 +77,82 @@ struct AbstractValue {
         makeTop(SpecBytecodeTop);
     }
     
+    void makeFullTop()
+    {
+        makeTop(SpecFullTop);
+    }
+    
     void clobberStructures()
     {
         if (m_type & SpecCell) {
-            m_currentKnownStructure.makeTop();
+            m_structure.clobber();
             clobberArrayModes();
         } else {
-            ASSERT(m_currentKnownStructure.isClear());
+            ASSERT(m_structure.isClear());
             ASSERT(!m_arrayModes);
         }
         checkConsistency();
     }
+    
+    static void clobberStructuresFor(AbstractValue& value)
+    {
+        value.clobberStructures();
+    }
+    
+    void observeInvalidationPoint()
+    {
+        m_structure.observeInvalidationPoint();
+        checkConsistency();
+    }
+    
+    static void observeInvalidationPointFor(AbstractValue& value)
+    {
+        value.observeInvalidationPoint();
+    }
+    
+    void observeTransition(Structure* from, Structure* to)
+    {
+        if (m_type & SpecCell) {
+            m_structure.observeTransition(from, to);
+            observeIndexingTypeTransition(from->indexingType(), to->indexingType());
+        }
+        checkConsistency();
+    }
+    
+    void observeTransitions(const TransitionVector& vector);
+    
+    class TransitionObserver {
+    public:
+        TransitionObserver(Structure* from, Structure* to)
+            : m_from(from)
+            , m_to(to)
+        {
+        }
         
+        void operator()(AbstractValue& value)
+        {
+            value.observeTransition(m_from, m_to);
+        }
+    private:
+        Structure* m_from;
+        Structure* m_to;
+    };
+    
+    class TransitionsObserver {
+    public:
+        TransitionsObserver(const TransitionVector& vector)
+            : m_vector(vector)
+        {
+        }
+        
+        void operator()(AbstractValue& value)
+        {
+            value.observeTransitions(m_vector);
+        }
+    private:
+        const TransitionVector& m_vector;
+    };
+    
     void clobberValue()
     {
         m_value = JSValue();
@@ -91,7 +160,10 @@ struct AbstractValue {
     
     bool isHeapTop() const
     {
-        return (m_type | SpecHeapTop) == m_type && m_currentKnownStructure.isTop() && m_futurePossibleStructure.isTop();
+        return (m_type | SpecHeapTop) == m_type
+            && m_structure.isTop()
+            && m_arrayModes == ALL_ARRAY_MODES
+            && !m_value;
     }
     
     bool valueIsTop() const
@@ -111,35 +183,46 @@ struct AbstractValue {
         return result;
     }
     
-    void setMostSpecific(Graph&, JSValue);
-    void set(Graph&, JSValue);
+    static AbstractValue bytecodeTop()
+    {
+        AbstractValue result;
+        result.makeBytecodeTop();
+        return result;
+    }
+    
+    static AbstractValue fullTop()
+    {
+        AbstractValue result;
+        result.makeFullTop();
+        return result;
+    }
+    
+    void set(Graph&, const FrozenValue&, StructureClobberState);
     void set(Graph&, Structure*);
+    void set(Graph&, const StructureSet&);
     
+    // Set this value to represent the given set of types as precisely as possible.
+    void setType(Graph&, SpeculatedType);
+    
+    // As above, but only valid for non-cell types.
     void setType(SpeculatedType type)
     {
-        if (type & SpecCell) {
-            m_currentKnownStructure.makeTop();
-            m_futurePossibleStructure.makeTop();
-            m_arrayModes = ALL_ARRAY_MODES;
-        } else {
-            m_currentKnownStructure.clear();
-            m_futurePossibleStructure.clear();
-            m_arrayModes = 0;
-        }
+        RELEASE_ASSERT(!(type & SpecCell));
+        m_structure.clear();
+        m_arrayModes = 0;
         m_type = type;
         m_value = JSValue();
         checkConsistency();
     }
     
-    void fixTypeForRepresentation(NodeFlags representation);
-    void fixTypeForRepresentation(Node*);
+    void fixTypeForRepresentation(Graph&, NodeFlags representation, Node* = nullptr);
+    void fixTypeForRepresentation(Graph&, Node*);
     
     bool operator==(const AbstractValue& other) const
     {
         return m_type == other.m_type
             && m_arrayModes == other.m_arrayModes
-            && m_currentKnownStructure == other.m_currentKnownStructure
-            && m_futurePossibleStructure == other.m_futurePossibleStructure
+            && m_structure == other.m_structure
             && m_value == other.m_value;
     }
     bool operator!=(const AbstractValue& other) const
@@ -162,8 +245,7 @@ struct AbstractValue {
         } else {
             result |= mergeSpeculation(m_type, other.m_type);
             result |= mergeArrayModes(m_arrayModes, other.m_arrayModes);
-            result |= m_currentKnownStructure.addAll(other.m_currentKnownStructure);
-            result |= m_futurePossibleStructure.addAll(other.m_futurePossibleStructure);
+            result |= m_structure.merge(other.m_structure);
             if (m_value != other.m_value) {
                 result |= !!m_value;
                 m_value = JSValue();
@@ -174,13 +256,14 @@ struct AbstractValue {
         return result;
     }
     
+    bool mergeOSREntryValue(Graph&, JSValue);
+    
     void merge(SpeculatedType type)
     {
         mergeSpeculation(m_type, type);
         
         if (type & SpecCell) {
-            m_currentKnownStructure.makeTop();
-            m_futurePossibleStructure.makeTop();
+            m_structure.makeTop();
             m_arrayModes = ALL_ARRAY_MODES;
         }
         m_value = JSValue();
@@ -188,23 +271,25 @@ struct AbstractValue {
         checkConsistency();
     }
     
-    bool couldBeType(SpeculatedType desiredType)
+    bool couldBeType(SpeculatedType desiredType) const
     {
         return !!(m_type & desiredType);
     }
     
-    bool isType(SpeculatedType desiredType)
+    bool isType(SpeculatedType desiredType) const
     {
         return !(m_type & ~desiredType);
     }
     
     FiltrationResult filter(Graph&, const StructureSet&);
-    
     FiltrationResult filterArrayModes(ArrayModes);
-    
     FiltrationResult filter(SpeculatedType);
+    FiltrationResult filterByValue(const FrozenValue& value);
+    FiltrationResult filter(const AbstractValue&);
     
-    FiltrationResult filterByValue(JSValue);
+    FiltrationResult changeStructure(Graph&, const StructureSet&);
+    
+    bool contains(Structure*) const;
     
     bool validate(JSValue value) const
     {
@@ -225,75 +310,32 @@ struct AbstractValue {
         if (!!value && value.isCell()) {
             ASSERT(m_type & SpecCell);
             Structure* structure = value.asCell()->structure();
-            return m_currentKnownStructure.contains(structure)
-                && m_futurePossibleStructure.contains(structure)
+            return m_structure.contains(structure)
                 && (m_arrayModes & asArrayModes(structure->indexingType()));
         }
         
         return true;
     }
     
-    Structure* bestProvenStructure() const
-    {
-        if (m_currentKnownStructure.hasSingleton())
-            return m_currentKnownStructure.singleton();
-        if (m_futurePossibleStructure.hasSingleton())
-            return m_futurePossibleStructure.singleton();
-        return 0;
-    }
-    
     bool hasClobberableState() const
     {
-        return m_currentKnownStructure.isNeitherClearNorTop()
+        return m_structure.isNeitherClearNorTop()
             || !arrayModesAreClearOrTop(m_arrayModes);
     }
     
 #if ASSERT_DISABLED
     void checkConsistency() const { }
+    void assertIsRegistered(Graph&) const { }
 #else
     void checkConsistency() const;
+    void assertIsRegistered(Graph&) const;
 #endif
     
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
     
-    // A great way to think about the difference between m_currentKnownStructure and
-    // m_futurePossibleStructure is to consider these four examples:
-    //
-    // 1) x = foo();
-    //
-    //    In this case x's m_currentKnownStructure and m_futurePossibleStructure will
-    //    both be TOP, since we don't know anything about x for sure, yet.
-    //
-    // 2) x = foo();
-    //    y = x.f;
-    //
-    //    Where x will later have a new property added to it, 'g'. Because of the
-    //    known but not-yet-executed property addition, x's current structure will
-    //    not be watchpointable; hence we have no way of statically bounding the set
-    //    of possible structures that x may have if a clobbering event happens. So,
-    //    x's m_currentKnownStructure will be whatever structure we check to get
-    //    property 'f', and m_futurePossibleStructure will be TOP.
-    //
-    // 3) x = foo();
-    //    y = x.f;
-    //
-    //    Where x has a terminal structure that is still watchpointable. In this case,
-    //    x's m_currentKnownStructure and m_futurePossibleStructure will both be
-    //    whatever structure we checked for when getting 'f'.
-    //
-    // 4) x = foo();
-    //    y = x.f;
-    //    bar();
-    //
-    //    Where x has a terminal structure that is still watchpointable. In this
-    //    case, m_currentKnownStructure will be TOP because bar() may potentially
-    //    change x's structure and we have no way of proving otherwise, but
-    //    x's m_futurePossibleStructure will be whatever structure we had checked
-    //    when getting property 'f'.
-    
-    // NB. All fields in this struct must have trivial destructors.
-
+    void validateReferences(const TrackedReferences&);
+    
     // This is a proven constraint on the structures that this value can have right
     // now. The structure of the current value must belong to this set. The set may
     // be TOP, indicating that it is the set of all possible structures, in which
@@ -301,44 +343,25 @@ struct AbstractValue {
     // in which case this value cannot be a cell. This is all subject to change
     // anytime a new value is assigned to this one, anytime there is a control flow
     // merge, or most crucially, anytime a side-effect or structure check happens.
-    // In case of a side-effect, we typically must assume that any value may have
-    // had its structure changed, hence contravening our proof. We make the proof
-    // valid again by switching this to TOP (i.e. claiming that we have proved that
-    // this value may have any structure). Of note is that the proof represented by
-    // this field is not subject to structure transition watchpoints - even if one
-    // fires, we can be sure that this proof is still valid.
-    StructureAbstractValue m_currentKnownStructure;
-    
-    // This is a proven constraint on the structures that this value can have now
-    // or any time in the future subject to the structure transition watchpoints of
-    // all members of this set not having fired. This set is impervious to side-
-    // effects; even if one happens the side-effect can only cause the value to
-    // change to at worst another structure that is also a member of this set. But,
-    // the theorem being proved by this field is predicated upon there not being
-    // any new structure transitions introduced into any members of this set. In
-    // cases where there is no way for us to guard this happening, the set must be
-    // TOP. But in cases where we can guard new structure transitions (all members
-    // of the set have still-valid structure transition watchpoints) then this set
-    // will be finite. Anytime that we make use of the finite nature of this set,
-    // we must first issue a structure transition watchpoint, which will effectively
-    // result in m_currentKnownStructure being filtered according to
-    // m_futurePossibleStructure.
-    StructureAbstractValue m_futurePossibleStructure;
+    // In case of a side-effect, we must assume that any value with a structure that
+    // isn't being watched may have had its structure changed, hence contravening
+    // our proof. In such a case we make the proof valid again by switching this to
+    // TOP (i.e. claiming that we have proved that this value may have any
+    // structure).
+    StructureAbstractValue m_structure;
     
     // This is a proven constraint on the possible types that this value can have
     // now or any time in the future, unless it is reassigned. This field is
-    // impervious to side-effects unless the side-effect can reassign the value
-    // (for example if we're talking about a captured variable). The relationship
-    // between this field, and the structure fields above, is as follows. The
-    // fields above constraint the structures that a cell may have, but they say
-    // nothing about whether or not the value is known to be a cell. More formally,
-    // the m_currentKnownStructure is itself an abstract value that consists of the
-    // union of the set of all non-cell values and the set of cell values that have
-    // the given structure. This abstract value is then the intersection of the
-    // m_currentKnownStructure and the set of values whose type is m_type. So, for
-    // example if m_type is SpecFinal|SpecInt32 and m_currentKnownStructure is
-    // [0x12345] then this abstract value corresponds to the set of all integers
-    // unified with the set of all objects with structure 0x12345.
+    // impervious to side-effects. The relationship between this field, and the
+    // structure fields above, is as follows. The fields above constraint the
+    // structures that a cell may have, but they say nothing about whether or not
+    // the value is known to be a cell. More formally, the m_structure is itself an
+    // abstract value that consists of the union of the set of all non-cell values
+    // and the set of cell values that have the given structure. This abstract
+    // value is then the intersection of the m_structure and the set of values
+    // whose type is m_type. So, for example if m_type is SpecFinal|SpecInt32 and
+    // m_structure is [0x12345] then this abstract value corresponds to the set of
+    // all integers unified with the set of all objects with structure 0x12345.
     SpeculatedType m_type;
     
     // This is a proven constraint on the possible indexing types that this value
@@ -353,7 +376,11 @@ struct AbstractValue {
     // implies nothing about the structure. Oddly, JSValue() (i.e. the empty value)
     // means either BOTTOM or TOP depending on the state of m_type: if m_type is
     // BOTTOM then JSValue() means BOTTOM; if m_type is not BOTTOM then JSValue()
-    // means TOP.
+    // means TOP. Also note that this value isn't necessarily known to the GC
+    // (strongly or even weakly - it may be an "fragile" value, see
+    // DFGValueStrength.h). If you perform any optimization based on a cell m_value
+    // that requires that the value be kept alive, you must call freeze() on that
+    // value, which will turn it into a weak value.
     JSValue m_value;
 
 private:
@@ -364,6 +391,12 @@ private:
         m_arrayModes = ALL_ARRAY_MODES;
     }
     
+    void observeIndexingTypeTransition(IndexingType from, IndexingType to)
+    {
+        if (m_arrayModes & asArrayModes(from))
+            m_arrayModes |= asArrayModes(to);
+    }
+    
     bool validateType(JSValue value) const
     {
         if (isHeapTop())
@@ -391,19 +424,17 @@ private:
     {
         m_type |= top;
         m_arrayModes = ALL_ARRAY_MODES;
-        m_currentKnownStructure.makeTop();
-        m_futurePossibleStructure.makeTop();
+        m_structure.makeTop();
         m_value = JSValue();
         checkConsistency();
     }
     
-    void setFuturePossibleStructure(Graph&, Structure*);
-
     void filterValueByType();
     void filterArrayModesByType();
     
     bool shouldBeClear() const;
     FiltrationResult normalizeClarity();
+    FiltrationResult normalizeClarity(Graph&);
 };
 
 } } // namespace JSC::DFG
index 38e74dac5bdd01f05a98865e1322022542a74996..63ebef5fa6d801dd87d3e57d3c451aad3695930c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,7 +52,7 @@ public:
         }
     }
     
-    AdjacencyList(Kind kind, Edge child1, Edge child2, Edge child3)
+    AdjacencyList(Kind kind, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
     {
         ASSERT_UNUSED(kind, kind == Fixed);
         initialize(child1, child2, child3);
@@ -65,6 +65,8 @@ public:
         setNumChildren(numChildren);
     }
     
+    bool isEmpty() const { return !child1(); }
+    
     const Edge& child(unsigned i) const
     {
         ASSERT(i < Size);
@@ -130,7 +132,7 @@ public:
             setChild(i, child(i + 1));
         setChild(Size - 1, Edge());
     }
-
+    
     unsigned firstChild() const
     {
         return m_words[0].m_encodedWord;
@@ -149,6 +151,56 @@ public:
         m_words[1].m_encodedWord = numChildren;
     }
     
+    AdjacencyList sanitized() const
+    {
+        return AdjacencyList(Fixed, child1().sanitized(), child2().sanitized(), child3().sanitized());
+    }
+    
+    AdjacencyList justChecks() const
+    {
+        AdjacencyList result(Fixed);
+        unsigned sourceIndex = 0;
+        unsigned targetIndex = 0;
+        while (sourceIndex < AdjacencyList::Size) {
+            Edge edge = child(sourceIndex++);
+            if (!edge)
+                break;
+            if (edge.willHaveCheck())
+                result.child(targetIndex++) = edge;
+        }
+        return result;
+    }
+    
+    unsigned hash() const
+    {
+        unsigned result = 0;
+        if (!child1())
+            return result;
+        
+        result += child1().hash();
+        
+        if (!child2())
+            return result;
+        
+        result *= 3;
+        result += child2().hash();
+        
+        if (!child3())
+            return result;
+        
+        result *= 3;
+        result += child3().hash();
+        
+        return result;
+    }
+    
+    bool operator==(const AdjacencyList& other) const
+    {
+        return child1() == other.child1()
+            && child2() == other.child2()
+            && child3() == other.child3();
+    }
+    
 private:
     Edge m_words[Size];
 };
index 6e20fb3676caab727f89e4bdd08eafb2a0cd5142..f380df001c5f22a486d6ac8d389e7c239d0b59a4 100644 (file)
@@ -29,7 +29,6 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGCommon.h"
-#include <wtf/PageAllocationAligned.h>
 #include <wtf/StdLibExtras.h>
 
 namespace JSC { namespace DFG {
@@ -50,7 +49,7 @@ public:
     void* allocate(); // Use placement new to allocate, and avoid using this method.
     void free(T*); // Call this method to delete; never use 'delete' directly.
     
-    void freeAll(); // Only call this if T has a trivial destructor.
+    void freeAll(); // Only call this if you've either freed everything or if T has a trivial destructor.
     void reset(); // Like freeAll(), but also returns all memory to the OS.
     
     unsigned indexOf(const T*);
@@ -70,7 +69,7 @@ private:
         bool isInThisRegion(const T* pointer) { return static_cast<unsigned>(pointer - data()) < numberOfThingsPerRegion(); }
         static Region* regionFor(const T* pointer) { return bitwise_cast<Region*>(bitwise_cast<uintptr_t>(pointer) & ~(size() - 1)); }
         
-        PageAllocationAligned m_allocation;
+        void* m_allocation;
         Allocator* m_allocator;
         Region* m_next;
     };
@@ -201,11 +200,9 @@ void* Allocator<T>::allocateSlow()
     
     if (logCompilationChanges())
         dataLog("Allocating another allocator region.\n");
-    
-    PageAllocationAligned allocation = PageAllocationAligned::allocate(Region::size(), Region::size(), OSAllocator::JSGCHeapPages);
-    if (!static_cast<bool>(allocation))
-        CRASH();
-    Region* region = static_cast<Region*>(allocation.base());
+
+    void* allocation = fastAlignedMalloc(Region::size(), Region::size());
+    Region* region = static_cast<Region*>(allocation);
     region->m_allocation = allocation;
     region->m_allocator = this;
     startBumpingIn(region);
@@ -222,7 +219,7 @@ void Allocator<T>::freeRegionsStartingAt(typename Allocator<T>::Region* region)
 {
     while (region) {
         Region* nextRegion = region->m_next;
-        region->m_allocation.deallocate();
+        fastAlignedFree(region->m_allocation);
         region = nextRegion;
     }
 }
index 2b9d1499f4b3309028e76b52b73aab692bf42f5f..0df93d1d1aa890ebae3dd74d6407ecc25b276493 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,6 +53,8 @@ public:
     {
         if (m_valid)
             return;
+        // It's best to run dependent analyses from this method.
+        static_cast<T*>(this)->computeDependencies(graph);
         // Set to true early, since the analysis may choose to call its own methods in
         // compute() and it may want to ASSERT() validity in those methods.
         m_valid = true;
@@ -61,6 +63,12 @@ public:
     
     bool isValid() const { return m_valid; }
 
+    // Override this to compute any dependent analyses. See
+    // NaturalLoops::computeDependencies(Graph&) for an example. This isn't strictly necessary but
+    // it makes debug dumps in cases of error work a bit better because this analysis wouldn't yet
+    // be pretending to be valid.
+    void computeDependencies(Graph&) { }
+
 private:
     bool m_valid;
 };
index b4e4ade1531a2a515d6da7cadc21d39552f2f58d..a6983a735763198780a7a4952519f13be0a9412b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,6 +46,9 @@ public:
     void addVariable(VariableAccessData* variable)
     {
         m_variables.append(variable);
+        
+        // We may set this early. Merging it here saves us time in prediction propagation.
+        variable->mergeShouldNeverUnbox(m_shouldNeverUnbox);
     }
     
     VariableAccessData* someVariable() const
@@ -64,7 +67,7 @@ public:
     
     bool mergeShouldNeverUnbox(bool shouldNeverUnbox)
     {
-        return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | shouldNeverUnbox);
+        return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox || shouldNeverUnbox);
     }
     
     bool mergeArgumentPredictionAwareness()
@@ -93,7 +96,7 @@ public:
         bool changed = false;
         for (unsigned i = 0; i < m_variables.size(); ++i) {
             VariableAccessData* variable = m_variables[i]->find();
-            changed |= checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | variable->isProfitableToUnbox());
+            changed |= checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox || variable->isProfitableToUnbox());
         }
         if (!changed)
             return false;
@@ -123,10 +126,7 @@ public:
             if (i)
                 out.print(" ");
 
-            if (operand.isArgument())
-                out.print("arg", operand.toArgument(), "(", VariableAccessDataDump(*graph, variable), ")");
-            else
-                out.print("r", operand.toLocal(), "(", VariableAccessDataDump(*graph, variable), ")");
+            out.print(operand, "(", VariableAccessDataDump(*graph, variable), ")");
         }
         out.print("\n");
     }
diff --git a/dfg/DFGArgumentsEliminationPhase.cpp b/dfg/DFGArgumentsEliminationPhase.cpp
new file mode 100644 (file)
index 0000000..336a70c
--- /dev/null
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGArgumentsEliminationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "BytecodeLivenessAnalysisInlines.h"
+#include "DFGArgumentsUtilities.h"
+#include "DFGBasicBlockInlines.h"
+#include "DFGBlockMapInlines.h"
+#include "DFGClobberize.h"
+#include "DFGCombinedLiveness.h"
+#include "DFGForAllKills.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGLivenessAnalysisPhase.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class ArgumentsEliminationPhase : public Phase {
+public:
+    ArgumentsEliminationPhase(Graph& graph)
+        : Phase(graph, "arguments elimination")
+    {
+    }
+    
+    bool run()
+    {
+        // For now this phase only works on SSA. This could be changed; we could have a block-local
+        // version over LoadStore.
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
+        
+        if (verbose) {
+            dataLog("Graph before arguments elimination:\n");
+            m_graph.dump();
+        }
+        
+        identifyCandidates();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        eliminateCandidatesThatEscape();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        eliminateCandidatesThatInterfere();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        transform();
+        
+        return true;
+    }
+
+private:
+    // Just finds nodes that we know how to work with.
+    void identifyCandidates()
+    {
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case CreateDirectArguments:
+                case CreateClonedArguments:
+                    m_candidates.add(node);
+                    break;
+                    
+                case CreateScopedArguments:
+                    // FIXME: We could handle this if it wasn't for the fact that scoped arguments are
+                    // always stored into the activation.
+                    // https://bugs.webkit.org/show_bug.cgi?id=143072 and
+                    // https://bugs.webkit.org/show_bug.cgi?id=143073
+                    break;
+                    
+                default:
+                    break;
+                }
+            }
+        }
+        
+        if (verbose)
+            dataLog("Candidates: ", listDump(m_candidates), "\n");
+    }
+    
+    // Look for escaping sites, and remove from the candidates set if we see an escape.
+    void eliminateCandidatesThatEscape()
+    {
+        auto escape = [&] (Edge edge) {
+            if (!edge)
+                return;
+            m_candidates.remove(edge.node());
+        };
+        
+        auto escapeBasedOnArrayMode = [&] (ArrayMode mode, Edge edge) {
+            switch (mode.type()) {
+            case Array::DirectArguments:
+                if (edge->op() != CreateDirectArguments)
+                    escape(edge);
+                break;
+            
+            case Array::Int32:
+            case Array::Double:
+            case Array::Contiguous:
+                if (edge->op() != CreateClonedArguments)
+                    escape(edge);
+                break;
+            
+            default:
+                escape(edge);
+                break;
+            }
+        };
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case GetFromArguments:
+                    DFG_ASSERT(m_graph, node, node->child1()->op() == CreateDirectArguments);
+                    break;
+                    
+                case GetByVal:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    escape(node->child2());
+                    escape(node->child3());
+                    break;
+                    
+                case GetArrayLength:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    escape(node->child2());
+                    break;
+                    
+                case LoadVarargs:
+                    break;
+                    
+                case CallVarargs:
+                case ConstructVarargs:
+                    escape(node->child1());
+                    escape(node->child3());
+                    break;
+
+                case Check:
+                    m_graph.doToChildren(
+                        node,
+                        [&] (Edge edge) {
+                            if (edge.willNotHaveCheck())
+                                return;
+                            
+                            if (alreadyChecked(edge.useKind(), SpecObject))
+                                return;
+                            
+                            escape(edge);
+                        });
+                    break;
+                    
+                case MovHint:
+                case PutHint:
+                    break;
+                    
+                case GetButterfly:
+                    // This barely works. The danger is that the GetButterfly is used by something that
+                    // does something escaping to a candidate. Fortunately, the only butterfly-using ops
+                    // that we exempt here also use the candidate directly. If there ever was a
+                    // butterfly-using op that we wanted to exempt, then we'd have to look at the
+                    // butterfly's child and check if it's a candidate.
+                    break;
+                    
+                case CheckArray:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    break;
+                    
+                // FIXME: For cloned arguments, we'd like to allow GetByOffset on length to not be
+                // an escape.
+                // https://bugs.webkit.org/show_bug.cgi?id=143074
+                    
+                // FIXME: We should be able to handle GetById/GetByOffset on callee.
+                // https://bugs.webkit.org/show_bug.cgi?id=143075
+                    
+                default:
+                    m_graph.doToChildren(node, escape);
+                    break;
+                }
+            }
+        }
+
+        if (verbose)
+            dataLog("After escape analysis: ", listDump(m_candidates), "\n");
+    }
+
+    // Anywhere that a candidate is live (in bytecode or in DFG), check if there is a chance of
+    // interference between the stack area that the arguments object copies from and the arguments
+    // object's payload. Conservatively this means that the stack region doesn't get stored to.
+    void eliminateCandidatesThatInterfere()
+    {
+        performLivenessAnalysis(m_graph);
+        performOSRAvailabilityAnalysis(m_graph);
+        m_graph.initializeNodeOwners();
+        CombinedLiveness combinedLiveness(m_graph);
+        
+        BlockMap<Operands<bool>> clobberedByBlock(m_graph);
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            Operands<bool>& clobberedByThisBlock = clobberedByBlock[block];
+            clobberedByThisBlock = Operands<bool>(OperandsLike, m_graph.block(0)->variablesAtHead);
+            for (Node* node : *block) {
+                clobberize(
+                    m_graph, node, NoOpClobberize(),
+                    [&] (AbstractHeap heap) {
+                        if (heap.kind() != Stack) {
+                            ASSERT(!heap.overlaps(Stack));
+                            return;
+                        }
+                        ASSERT(!heap.payload().isTop());
+                        VirtualRegister reg(heap.payload().value32());
+                        clobberedByThisBlock.operand(reg) = true;
+                    },
+                    NoOpClobberize());
+            }
+        }
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            // Stop if we've already removed all candidates.
+            if (m_candidates.isEmpty())
+                return;
+            
+            // Ignore blocks that don't write to the stack.
+            bool writesToStack = false;
+            for (unsigned i = clobberedByBlock[block].size(); i--;) {
+                if (clobberedByBlock[block][i]) {
+                    writesToStack = true;
+                    break;
+                }
+            }
+            if (!writesToStack)
+                continue;
+            
+            forAllKillsInBlock(
+                m_graph, combinedLiveness, block,
+                [&] (unsigned nodeIndex, Node* candidate) {
+                    if (!m_candidates.contains(candidate))
+                        return;
+                    
+                    // Check if this block has any clobbers that affect this candidate. This is a fairly
+                    // fast check.
+                    bool isClobberedByBlock = false;
+                    Operands<bool>& clobberedByThisBlock = clobberedByBlock[block];
+                    
+                    if (InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame) {
+                        if (inlineCallFrame->isVarargs()) {
+                            isClobberedByBlock |= clobberedByThisBlock.operand(
+                                inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+                        }
+                        
+                        if (!isClobberedByBlock || inlineCallFrame->isClosureCall) {
+                            isClobberedByBlock |= clobberedByThisBlock.operand(
+                                inlineCallFrame->stackOffset + JSStack::Callee);
+                        }
+                        
+                        if (!isClobberedByBlock) {
+                            for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
+                                VirtualRegister reg =
+                                    VirtualRegister(inlineCallFrame->stackOffset) +
+                                    CallFrame::argumentOffset(i);
+                                if (clobberedByThisBlock.operand(reg)) {
+                                    isClobberedByBlock = true;
+                                    break;
+                                }
+                            }
+                        }
+                    } else {
+                        // We don't include the ArgumentCount or Callee in this case because we can be
+                        // damn sure that this won't be clobbered.
+                        for (unsigned i = 1; i < static_cast<unsigned>(codeBlock()->numParameters()); ++i) {
+                            if (clobberedByThisBlock.argument(i)) {
+                                isClobberedByBlock = true;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    if (!isClobberedByBlock)
+                        return;
+                    
+                    // Check if we can immediately eliminate this candidate. If the block has a clobber
+                    // for this arguments allocation, and we'd have to examine every node in the block,
+                    // then we can just eliminate the candidate.
+                    if (nodeIndex == block->size() && candidate->owner != block) {
+                        m_candidates.remove(candidate);
+                        return;
+                    }
+                    
+                    // This loop considers all nodes up to the nodeIndex, excluding the nodeIndex.
+                    while (nodeIndex--) {
+                        Node* node = block->at(nodeIndex);
+                        if (node == candidate)
+                            break;
+                        
+                        bool found = false;
+                        clobberize(
+                            m_graph, node, NoOpClobberize(),
+                            [&] (AbstractHeap heap) {
+                                if (heap.kind() == Stack && !heap.payload().isTop()) {
+                                    if (argumentsInvolveStackSlot(candidate, VirtualRegister(heap.payload().value32())))
+                                        found = true;
+                                    return;
+                                }
+                                if (heap.overlaps(Stack))
+                                    found = true;
+                            },
+                            NoOpClobberize());
+                        
+                        if (found) {
+                            m_candidates.remove(candidate);
+                            return;
+                        }
+                    }
+                });
+        }
+        
+        // Q: How do we handle OSR exit with a live PhantomArguments at a point where the inline call
+        // frame is dead?  A: Naively we could say that PhantomArguments must escape the stack slots. But
+        // that would break PutStack sinking, which in turn would break object allocation sinking, in
+        // cases where we have a varargs call to an otherwise pure method. So, we need something smarter.
+        // For the outermost arguments, we just have a PhantomArguments that magically knows that it
+        // should load the arguments from the call frame. For the inline arguments, we have the heap map
+        // in the availabiltiy map track each possible inline argument as a promoted heap location. If the
+        // PutStacks for those arguments aren't sunk, those heap locations will map to very trivial
+        // availabilities (they will be flush availabilities). But if sinking happens then those
+        // availabilities may become whatever. OSR exit should be able to handle this quite naturally,
+        // since those availabilities speak of the stack before the optimizing compiler stack frame is
+        // torn down.
+
+        if (verbose)
+            dataLog("After interference analysis: ", listDump(m_candidates), "\n");
+    }
+    
+    void transform()
+    {
+        InsertionSet insertionSet(m_graph);
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                
+                auto getArrayLength = [&] (Node* candidate) -> Node* {
+                    return emitCodeToGetArgumentsArrayLength(
+                        insertionSet, candidate, nodeIndex, node->origin);
+                };
+        
+                switch (node->op()) {
+                case CreateDirectArguments:
+                    if (!m_candidates.contains(node))
+                        break;
+                    
+                    node->setOpAndDefaultFlags(PhantomDirectArguments);
+                    break;
+                    
+                case CreateClonedArguments:
+                    if (!m_candidates.contains(node))
+                        break;
+                    
+                    node->setOpAndDefaultFlags(PhantomClonedArguments);
+                    break;
+                    
+                case GetFromArguments: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    DFG_ASSERT(
+                        m_graph, node,
+                        node->child1()->op() == CreateDirectArguments
+                        || node->child1()->op() == PhantomDirectArguments);
+                    VirtualRegister reg =
+                        virtualRegisterForArgument(node->capturedArgumentsOffset().offset() + 1) +
+                        node->origin.semantic.stackOffset();
+                    StackAccessData* data = m_graph.m_stackAccessData.add(reg, FlushedJSValue);
+                    node->convertToGetStack(data);
+                    break;
+                }
+                    
+                case GetArrayLength: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    // Meh, this is kind of hackish - we use an Identity so that we can reuse the
+                    // getArrayLength() helper.
+                    node->convertToIdentityOn(getArrayLength(candidate));
+                    break;
+                }
+                    
+                case GetByVal: {
+                    // FIXME: For ClonedArguments, we would have already done a separate bounds check.
+                    // This code will cause us to have two bounds checks - the original one that we
+                    // already factored out in SSALoweringPhase, and the new one we insert here, which is
+                    // often implicitly part of GetMyArgumentByVal. LLVM will probably eliminate the
+                    // second bounds check, but still - that's just silly.
+                    // https://bugs.webkit.org/show_bug.cgi?id=143076
+                    
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    Node* result = nullptr;
+                    if (node->child2()->isInt32Constant()) {
+                        unsigned index = node->child2()->asUInt32();
+                        InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                        
+                        bool safeToGetStack;
+                        if (inlineCallFrame)
+                            safeToGetStack = index < inlineCallFrame->arguments.size() - 1;
+                        else {
+                            safeToGetStack =
+                                index < static_cast<unsigned>(codeBlock()->numParameters()) - 1;
+                        }
+                        if (safeToGetStack) {
+                            StackAccessData* data;
+                            VirtualRegister arg = virtualRegisterForArgument(index + 1);
+                            if (inlineCallFrame)
+                                arg += inlineCallFrame->stackOffset;
+                            data = m_graph.m_stackAccessData.add(arg, FlushedJSValue);
+                            
+                            if (!inlineCallFrame || inlineCallFrame->isVarargs()
+                                || index >= inlineCallFrame->arguments.size() - 1) {
+                                insertionSet.insertNode(
+                                    nodeIndex, SpecNone, CheckInBounds, node->origin,
+                                    node->child2(), Edge(getArrayLength(candidate), Int32Use));
+                            }
+                            
+                            result = insertionSet.insertNode(
+                                nodeIndex, node->prediction(), GetStack, node->origin, OpInfo(data));
+                        }
+                    }
+                    
+                    if (!result) {
+                        result = insertionSet.insertNode(
+                            nodeIndex, node->prediction(), GetMyArgumentByVal, node->origin,
+                            node->child1(), node->child2());
+                    }
+                    
+                    // Need to do this because we may have a data format conversion here.
+                    node->convertToIdentityOn(result);
+                    break;
+                }
+                    
+                case LoadVarargs: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    LoadVarargsData* varargsData = node->loadVarargsData();
+                    InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                    if (inlineCallFrame
+                        && !inlineCallFrame->isVarargs()
+                        && inlineCallFrame->arguments.size() - varargsData->offset <= varargsData->limit) {
+                        Node* argumentCount = insertionSet.insertConstant(
+                            nodeIndex, node->origin,
+                            jsNumber(inlineCallFrame->arguments.size() - varargsData->offset));
+                        insertionSet.insertNode(
+                            nodeIndex, SpecNone, MovHint, node->origin,
+                            OpInfo(varargsData->count.offset()), Edge(argumentCount));
+                        insertionSet.insertNode(
+                            nodeIndex, SpecNone, PutStack, node->origin,
+                            OpInfo(m_graph.m_stackAccessData.add(varargsData->count, FlushedInt32)),
+                            Edge(argumentCount, Int32Use));
+                        
+                        DFG_ASSERT(m_graph, node, varargsData->limit - 1 >= varargsData->mandatoryMinimum);
+                        // Define our limit to not include "this", since that's a bit easier to reason about.
+                        unsigned limit = varargsData->limit - 1;
+                        Node* undefined = nullptr;
+                        for (unsigned storeIndex = 0; storeIndex < limit; ++storeIndex) {
+                            // First determine if we have an element we can load, and load it if
+                            // possible.
+                            
+                            unsigned loadIndex = storeIndex + varargsData->offset;
+                            
+                            Node* value;
+                            if (loadIndex + 1 < inlineCallFrame->arguments.size()) {
+                                VirtualRegister reg =
+                                    virtualRegisterForArgument(loadIndex + 1) +
+                                    inlineCallFrame->stackOffset;
+                                StackAccessData* data = m_graph.m_stackAccessData.add(
+                                    reg, FlushedJSValue);
+                                
+                                value = insertionSet.insertNode(
+                                    nodeIndex, SpecNone, GetStack, node->origin, OpInfo(data));
+                            } else {
+                                // FIXME: We shouldn't have to store anything if
+                                // storeIndex >= varargsData->mandatoryMinimum, but we will still
+                                // have GetStacks in that range. So if we don't do the stores, we'll
+                                // have degenerate IR: we'll have GetStacks of something that didn't
+                                // have PutStacks.
+                                // https://bugs.webkit.org/show_bug.cgi?id=147434
+                                
+                                if (!undefined) {
+                                    undefined = insertionSet.insertConstant(
+                                        nodeIndex, node->origin, jsUndefined());
+                                }
+                                value = undefined;
+                            }
+                            
+                            // Now that we have a value, store it.
+                            
+                            VirtualRegister reg = varargsData->start + storeIndex;
+                            StackAccessData* data =
+                                m_graph.m_stackAccessData.add(reg, FlushedJSValue);
+                            
+                            insertionSet.insertNode(
+                                nodeIndex, SpecNone, MovHint, node->origin, OpInfo(reg.offset()),
+                                Edge(value));
+                            insertionSet.insertNode(
+                                nodeIndex, SpecNone, PutStack, node->origin, OpInfo(data),
+                                Edge(value));
+                        }
+                        
+                        node->remove();
+                        break;
+                    }
+                    
+                    node->setOpAndDefaultFlags(ForwardVarargs);
+                    break;
+                }
+                    
+                case CallVarargs:
+                case ConstructVarargs: {
+                    Node* candidate = node->child2().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    CallVarargsData* varargsData = node->callVarargsData();
+                    InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                    if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+                        Vector<Node*> arguments;
+                        for (unsigned i = 1 + varargsData->firstVarArgOffset; i < inlineCallFrame->arguments.size(); ++i) {
+                            StackAccessData* data = m_graph.m_stackAccessData.add(
+                                virtualRegisterForArgument(i) + inlineCallFrame->stackOffset,
+                                FlushedJSValue);
+                            
+                            Node* value = insertionSet.insertNode(
+                                nodeIndex, SpecNone, GetStack, node->origin, OpInfo(data));
+                            
+                            arguments.append(value);
+                        }
+                        
+                        unsigned firstChild = m_graph.m_varArgChildren.size();
+                        m_graph.m_varArgChildren.append(node->child1());
+                        m_graph.m_varArgChildren.append(node->child3());
+                        for (Node* argument : arguments)
+                            m_graph.m_varArgChildren.append(Edge(argument));
+                        node->setOpAndDefaultFlags(
+                            node->op() == CallVarargs ? Call : Construct);
+                        node->children = AdjacencyList(
+                            AdjacencyList::Variable,
+                            firstChild, m_graph.m_varArgChildren.size() - firstChild);
+                        break;
+                    }
+                    
+                    node->setOpAndDefaultFlags(
+                        node->op() == CallVarargs ? CallForwardVarargs : ConstructForwardVarargs);
+                    break;
+                }
+                    
+                case CheckArray:
+                case GetButterfly: {
+                    if (!m_candidates.contains(node->child1().node()))
+                        break;
+                    node->remove();
+                    break;
+                }
+                    
+                default:
+                    break;
+                }
+            }
+            
+            insertionSet.execute(block);
+        }
+    }
+    
+    HashSet<Node*> m_candidates;
+};
+
+} // anonymous namespace
+
+bool performArgumentsElimination(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Arguments Elimination Phase");
+    return runPhase<ArgumentsEliminationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGArgumentsEliminationPhase.h b/dfg/DFGArgumentsEliminationPhase.h
new file mode 100644 (file)
index 0000000..520b228
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGArgumentsEliminationPhase_h
+#define DFGArgumentsEliminationPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Eliminates allocations of the Arguments-class objects when it can prove that the object doesn't escape
+// and none of the arguments are mutated (either via the object or via the stack).
+
+bool performArgumentsElimination(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGArgumentsEliminationPhase_h
+
diff --git a/dfg/DFGArgumentsSimplificationPhase.cpp b/dfg/DFGArgumentsSimplificationPhase.cpp
deleted file mode 100644 (file)
index 29572b9..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DFGArgumentsSimplificationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlock.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "DFGValidate.h"
-#include "DFGVariableAccessDataDump.h"
-#include "JSCInlines.h"
-#include <wtf/HashSet.h>
-#include <wtf/HashMap.h>
-
-namespace JSC { namespace DFG {
-
-namespace {
-
-struct ArgumentsAliasingData {
-    InlineCallFrame* callContext;
-    bool callContextSet;
-    bool multipleCallContexts;
-    
-    bool assignedFromArguments;
-    bool assignedFromManyThings;
-    
-    bool escapes;
-    
-    ArgumentsAliasingData()
-        : callContext(0)
-        , callContextSet(false)
-        , multipleCallContexts(false)
-        , assignedFromArguments(false)
-        , assignedFromManyThings(false)
-        , escapes(false)
-    {
-    }
-    
-    void mergeCallContext(InlineCallFrame* newCallContext)
-    {
-        if (multipleCallContexts)
-            return;
-        
-        if (!callContextSet) {
-            callContext = newCallContext;
-            callContextSet = true;
-            return;
-        }
-        
-        if (callContext == newCallContext)
-            return;
-        
-        multipleCallContexts = true;
-    }
-    
-    bool callContextIsValid()
-    {
-        return callContextSet && !multipleCallContexts;
-    }
-    
-    void mergeArgumentsAssignment()
-    {
-        assignedFromArguments = true;
-    }
-    
-    void mergeNonArgumentsAssignment()
-    {
-        assignedFromManyThings = true;
-    }
-    
-    bool argumentsAssignmentIsValid()
-    {
-        return assignedFromArguments && !assignedFromManyThings;
-    }
-    
-    bool isValid()
-    {
-        return callContextIsValid() && argumentsAssignmentIsValid() && !escapes;
-    }
-};
-
-} // end anonymous namespace
-
-class ArgumentsSimplificationPhase : public Phase {
-public:
-    ArgumentsSimplificationPhase(Graph& graph)
-        : Phase(graph, "arguments simplification")
-    {
-    }
-    
-    bool run()
-    {
-        if (!m_graph.m_hasArguments)
-            return false;
-        
-        bool changed = false;
-        
-        // Record which arguments are known to escape no matter what.
-        for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter)
-            pruneObviousArgumentCreations(*iter);
-        pruneObviousArgumentCreations(0); // the machine call frame.
-        
-        // Create data for variable access datas that we will want to analyze.
-        for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
-            VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
-            if (!variableAccessData->isRoot())
-                continue;
-            if (variableAccessData->isCaptured())
-                continue;
-            m_argumentsAliasing.add(variableAccessData, ArgumentsAliasingData());
-        }
-        
-        // Figure out which variables are live, using a conservative approximation of
-        // liveness.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case GetLocal:
-                case Flush:
-                case PhantomLocal:
-                    m_isLive.add(node->variableAccessData());
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-        
-        // Figure out which variables alias the arguments and nothing else, and are
-        // used only for GetByVal and GetArrayLength accesses. At the same time,
-        // identify uses of CreateArguments that are not consistent with the arguments
-        // being aliased only to variables that satisfy these constraints.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case CreateArguments: {
-                    // Ignore this op. If we see a lone CreateArguments then we want to
-                    // completely ignore it because:
-                    // 1) The default would be to see that the child is a GetLocal on the
-                    //    arguments register and conclude that we have an arguments escape.
-                    // 2) The fact that a CreateArguments exists does not mean that it
-                    //    will continue to exist after we're done with this phase. As far
-                    //    as this phase is concerned, a CreateArguments only "exists" if it
-                    //    is used in a manner that necessitates its existance.
-                    break;
-                }
-                    
-                case TearOffArguments: {
-                    // Ignore arguments tear off, because it's only relevant if we actually
-                    // need to create the arguments.
-                    break;
-                }
-                    
-                case SetLocal: {
-                    Node* source = node->child1().node();
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    VirtualRegister argumentsRegister =
-                        m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic);
-                    if (source->op() != CreateArguments && source->op() != PhantomArguments) {
-                        // Make sure that the source of the SetLocal knows that if it's
-                        // a variable that we think is aliased to the arguments, then it
-                        // may escape at this point. In future, we could track transitive
-                        // aliasing. But not yet.
-                        observeBadArgumentsUse(source);
-                        
-                        // If this is an assignment to the arguments register, then
-                        // pretend as if the arguments were created. We don't want to
-                        // optimize code that explicitly assigns to the arguments,
-                        // because that seems too ugly.
-                        
-                        // But, before getting rid of CreateArguments, we will have
-                        // an assignment to the arguments registers with JSValue().
-                        // That's because CSE will refuse to get rid of the
-                        // init_lazy_reg since it treats CreateArguments as reading
-                        // local variables. That could be fixed, but it's easier to
-                        // work around this here.
-                        if (source->op() == JSConstant
-                            && !source->valueOfJSConstant(codeBlock()))
-                            break;
-                        
-                        // If the variable is totally dead, then ignore it.
-                        if (!m_isLive.contains(variableAccessData))
-                            break;
-                        
-                        if (argumentsRegister.isValid()
-                            && (variableAccessData->local() == argumentsRegister
-                                || variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                            m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-                            break;
-                        }
-
-                        if (variableAccessData->isCaptured())
-                            break;
-                        
-                        // Make sure that if it's a variable that we think is aliased to
-                        // the arguments, that we know that it might actually not be.
-                        ArgumentsAliasingData& data =
-                            m_argumentsAliasing.find(variableAccessData)->value;
-                        data.mergeNonArgumentsAssignment();
-                        data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    if (argumentsRegister.isValid()
-                        && (variableAccessData->local() == argumentsRegister
-                            || variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                        if (node->origin.semantic.inlineCallFrame == source->origin.semantic.inlineCallFrame)
-                            break;
-                        m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    if (variableAccessData->isCaptured()) {
-                        m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeArgumentsAssignment();
-                    // This ensures that the variable's uses are in the same context as
-                    // the arguments it is aliasing.
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    data.mergeCallContext(source->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case GetLocal:
-                case Phi: /* FIXME: https://bugs.webkit.org/show_bug.cgi?id=108555 */ {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case Flush: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    
-                    // If a variable is used in a flush then by definition it escapes.
-                    data.escapes = true;
-                    break;
-                }
-                    
-                case SetArgument: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeNonArgumentsAssignment();
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case GetByVal: {
-                    if (node->arrayMode().type() != Array::Arguments) {
-                        observeBadArgumentsUses(node);
-                        break;
-                    }
-
-                    // That's so awful and pretty much impossible since it would
-                    // imply that the arguments were predicted integer, but it's
-                    // good to be defensive and thorough.
-                    observeBadArgumentsUse(node->child2().node());
-                    observeProperArgumentsUse(node, node->child1());
-                    break;
-                }
-                    
-                case GetArrayLength: {
-                    if (node->arrayMode().type() != Array::Arguments) {
-                        observeBadArgumentsUses(node);
-                        break;
-                    }
-                        
-                    observeProperArgumentsUse(node, node->child1());
-                    break;
-                }
-                    
-                case Phantom:
-                case HardPhantom:
-                    // We don't care about phantom uses, since phantom uses are all about
-                    // just keeping things alive for OSR exit. If something - like the
-                    // CreateArguments - is just being kept alive, then this transformation
-                    // will not break this, since the Phantom will now just keep alive a
-                    // PhantomArguments and OSR exit will still do the right things.
-                    break;
-                    
-                case CheckStructure:
-                case StructureTransitionWatchpoint:
-                case CheckArray:
-                    // We don't care about these because if we get uses of the relevant
-                    // variable then we can safely get rid of these, too. This of course
-                    // relies on there not being any information transferred by the CFA
-                    // from a CheckStructure on one variable to the information about the
-                    // structures of another variable.
-                    break;
-                    
-                case MovHint:
-                    // We don't care about MovHints at all, since they represent what happens
-                    // in bytecode. We rematerialize arguments objects on OSR exit anyway.
-                    break;
-                    
-                default:
-                    observeBadArgumentsUses(node);
-                    break;
-                }
-            }
-        }
-
-        // Now we know which variables are aliased to arguments. But if any of them are
-        // found to have escaped, or were otherwise invalidated, then we need to mark
-        // the arguments as requiring creation. This is a property of SetLocals to
-        // variables that are neither the correct arguments register nor are marked as
-        // being arguments-aliased.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != SetLocal)
-                    continue;
-                Node* source = node->child1().node();
-                if (source->op() != CreateArguments)
-                    continue;
-                VariableAccessData* variableAccessData = node->variableAccessData();
-                if (variableAccessData->isCaptured()) {
-                    // The captured case would have already been taken care of in the
-                    // previous pass.
-                    continue;
-                }
-                
-                ArgumentsAliasingData& data =
-                    m_argumentsAliasing.find(variableAccessData)->value;
-                if (data.isValid())
-                    continue;
-                
-                m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-            }
-        }
-        
-        InsertionSet insertionSet(m_graph);
-        
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); indexInBlock++) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case SetLocal: {
-                    Node* source = node->child1().node();
-                    if (source->op() != CreateArguments)
-                        break;
-                    
-                    if (m_createsArguments.contains(source->origin.semantic.inlineCallFrame))
-                        break;
-                    
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    
-                    if (variableAccessData->mergeIsArgumentsAlias(true)) {
-                        changed = true;
-                        
-                        // Make sure that the variable knows, that it may now hold non-cell values.
-                        variableAccessData->predict(SpecEmpty);
-                    }
-                    
-                    // Make sure that the SetLocal doesn't check that the input is a Cell.
-                    if (node->child1().useKind() != UntypedUse) {
-                        node->child1().setUseKind(UntypedUse);
-                        changed = true;
-                    }
-                    break;
-                }
-                    
-                case Flush: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    
-                    if (variableAccessData->isCaptured()
-                        || !m_argumentsAliasing.find(variableAccessData)->value.isValid()
-                        || m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                        break;
-                    
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
-                }
-                    
-                case Phantom:
-                case HardPhantom: {
-                    // It's highly likely that we will have a Phantom referencing either
-                    // CreateArguments, or a local op for the arguments register, or a
-                    // local op for an arguments-aliased variable. In any of those cases,
-                    // we should remove the phantom reference, since:
-                    // 1) Phantoms only exist to aid OSR exit. But arguments simplification
-                    //    has its own OSR exit story, which is to inform OSR exit to reify
-                    //    the arguments as necessary.
-                    // 2) The Phantom may keep the CreateArguments node alive, which is
-                    //    precisely what we don't want.
-                    for (unsigned i = 0; i < AdjacencyList::Size; ++i)
-                        detypeArgumentsReferencingPhantomChild(node, i);
-                    break;
-                }
-                    
-                case CheckStructure:
-                case StructureTransitionWatchpoint:
-                case CheckArray: {
-                    // We can just get rid of this node, if it references a phantom argument.
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    node->convertToPhantom();
-                    break;
-                }
-                    
-                case GetByVal: {
-                    if (node->arrayMode().type() != Array::Arguments)
-                        break;
-
-                    // This can be simplified to GetMyArgumentByVal if we know that
-                    // it satisfies either condition (1) or (2):
-                    // 1) Its first child is a valid ArgumentsAliasingData and the
-                    //    InlineCallFrame* is not marked as creating arguments.
-                    // 2) Its first child is CreateArguments and its InlineCallFrame*
-                    //    is not marked as creating arguments.
-                    
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, node->origin, node->child1());
-                    
-                    node->child1() = node->child2();
-                    node->child2() = Edge();
-                    node->setOpAndDefaultFlags(GetMyArgumentByVal);
-                    changed = true;
-                    --indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
-                    break;
-                }
-                    
-                case GetArrayLength: {
-                    if (node->arrayMode().type() != Array::Arguments)
-                        break;
-                    
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, node->origin, node->child1());
-                    
-                    node->child1() = Edge();
-                    node->setOpAndDefaultFlags(GetMyArgumentsLength);
-                    changed = true;
-                    --indexInBlock; // Force reconsideration of this op noew that it's a GetMyArgumentsLength.
-                    break;
-                }
-                    
-                case GetMyArgumentsLength:
-                case GetMyArgumentsLengthSafe: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame)) {
-                        ASSERT(node->op() == GetMyArgumentsLengthSafe);
-                        break;
-                    }
-                    if (node->op() == GetMyArgumentsLengthSafe) {
-                        node->setOp(GetMyArgumentsLength);
-                        changed = true;
-                    }
-                    
-                    NodeOrigin origin = node->origin;
-                    if (!origin.semantic.inlineCallFrame)
-                        break;
-                    
-                    // We know exactly what this will return. But only after we have checked
-                    // that nobody has escaped our arguments.
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
-                    
-                    m_graph.convertToConstant(
-                        node, jsNumber(origin.semantic.inlineCallFrame->arguments.size() - 1));
-                    changed = true;
-                    break;
-                }
-                    
-                case GetMyArgumentByVal:
-                case GetMyArgumentByValSafe: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame)) {
-                        ASSERT(node->op() == GetMyArgumentByValSafe);
-                        break;
-                    }
-                    if (node->op() == GetMyArgumentByValSafe) {
-                        node->setOp(GetMyArgumentByVal);
-                        changed = true;
-                    }
-                    if (!node->origin.semantic.inlineCallFrame)
-                        break;
-                    if (!node->child1()->hasConstant())
-                        break;
-                    JSValue value = node->child1()->valueOfJSConstant(codeBlock());
-                    if (!value.isInt32())
-                        break;
-                    int32_t index = value.asInt32();
-                    if (index < 0
-                        || static_cast<size_t>(index + 1) >=
-                            node->origin.semantic.inlineCallFrame->arguments.size())
-                        break;
-                    
-                    // We know which argument this is accessing. But only after we have checked
-                    // that nobody has escaped our arguments. We also need to ensure that the
-                    // index is kept alive. That's somewhat pointless since it's a constant, but
-                    // it's important because this is one of those invariants that we like to
-                    // have in the DFG. Note finally that we use the GetLocalUnlinked opcode
-                    // here, since this is being done _after_ the prediction propagation phase
-                    // has run - therefore it makes little sense to link the GetLocal operation
-                    // into the VariableAccessData and Phi graphs.
-
-                    NodeOrigin origin = node->origin;
-                    AdjacencyList children = node->children;
-                    
-                    node->convertToGetLocalUnlinked(
-                        VirtualRegister(
-                            origin.semantic.inlineCallFrame->stackOffset +
-                            m_graph.baselineCodeBlockFor(origin.semantic)->argumentIndexAfterCapture(index)));
-
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, origin, children);
-                    
-                    changed = true;
-                    break;
-                }
-                    
-                case TearOffArguments: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                        continue;
-                    
-                    node->convertToPhantom();
-                    break;
-                }
-                    
-                default:
-                    break;
-                }
-            }
-            insertionSet.execute(block);
-        }
-        
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != CreateArguments)
-                    continue;
-                // If this is a CreateArguments for an InlineCallFrame* that does
-                // not create arguments, then replace it with a PhantomArguments.
-                // PhantomArguments is a non-executing node that just indicates
-                // that the node should be reified as an arguments object on OSR
-                // exit.
-                if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                    continue;
-                insertionSet.insertNode(
-                    indexInBlock, SpecNone, Phantom, node->origin, node->children);
-                node->setOpAndDefaultFlags(PhantomArguments);
-                node->children.reset();
-                changed = true;
-            }
-            insertionSet.execute(block);
-        }
-        
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != Phantom)
-                    continue;
-                for (unsigned i = 0; i < AdjacencyList::Size; ++i)
-                    detypeArgumentsReferencingPhantomChild(node, i);
-            }
-        }
-        
-        if (changed) {
-            m_graph.dethread();
-            m_graph.m_form = LoadStore;
-        }
-        
-        return changed;
-    }
-    
-private:
-    HashSet<InlineCallFrame*,
-            DefaultHash<InlineCallFrame*>::Hash,
-            NullableHashTraits<InlineCallFrame*>> m_createsArguments;
-    HashMap<VariableAccessData*, ArgumentsAliasingData,
-            DefaultHash<VariableAccessData*>::Hash,
-            NullableHashTraits<VariableAccessData*>> m_argumentsAliasing;
-    HashSet<VariableAccessData*> m_isLive;
-
-    void pruneObviousArgumentCreations(InlineCallFrame* inlineCallFrame)
-    {
-        ScriptExecutable* executable = m_graph.executableFor(inlineCallFrame);
-        if (m_graph.m_executablesWhoseArgumentsEscaped.contains(executable)
-            || executable->isStrictMode())
-            m_createsArguments.add(inlineCallFrame);
-    }
-    
-    void observeBadArgumentsUse(Node* node)
-    {
-        if (!node)
-            return;
-        
-        switch (node->op()) {
-        case CreateArguments: {
-            m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-            break;
-        }
-            
-        case GetLocal: {
-            VirtualRegister argumentsRegister =
-                m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic);
-            if (argumentsRegister.isValid()
-                && (node->local() == argumentsRegister
-                    || node->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-                break;
-            }
-            
-            VariableAccessData* variableAccessData = node->variableAccessData();
-            if (variableAccessData->isCaptured())
-                break;
-            
-            ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value;
-            data.escapes = true;
-            break;
-        }
-            
-        default:
-            break;
-        }
-    }
-    
-    void observeBadArgumentsUses(Node* node)
-    {
-        for (unsigned i = m_graph.numChildren(node); i--;)
-            observeBadArgumentsUse(m_graph.child(node, i).node());
-    }
-    
-    void observeProperArgumentsUse(Node* node, Edge edge)
-    {
-        if (edge->op() != GetLocal) {
-            // When can this happen? At least two cases that I can think
-            // of:
-            //
-            // 1) Aliased use of arguments in the same basic block,
-            //    like:
-            //
-            //    var a = arguments;
-            //    var x = arguments[i];
-            //
-            // 2) If we're accessing arguments we got from the heap!
-                            
-            if (edge->op() == CreateArguments
-                && node->origin.semantic.inlineCallFrame
-                    != edge->origin.semantic.inlineCallFrame)
-                m_createsArguments.add(edge->origin.semantic.inlineCallFrame);
-            
-            return;
-        }
-                        
-        VariableAccessData* variableAccessData = edge->variableAccessData();
-        if (edge->local() == m_graph.uncheckedArgumentsRegisterFor(edge->origin.semantic)
-            && node->origin.semantic.inlineCallFrame != edge->origin.semantic.inlineCallFrame) {
-            m_createsArguments.add(edge->origin.semantic.inlineCallFrame);
-            return;
-        }
-
-        if (variableAccessData->isCaptured())
-            return;
-        
-        ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value;
-        data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-    }
-    
-    bool isOKToOptimize(Node* source)
-    {
-        if (m_createsArguments.contains(source->origin.semantic.inlineCallFrame))
-            return false;
-        
-        switch (source->op()) {
-        case GetLocal: {
-            VariableAccessData* variableAccessData = source->variableAccessData();
-            VirtualRegister argumentsRegister =
-                m_graph.uncheckedArgumentsRegisterFor(source->origin.semantic);
-            if (!argumentsRegister.isValid())
-                break;
-            if (argumentsRegister == variableAccessData->local())
-                return true;
-            if (unmodifiedArgumentsRegister(argumentsRegister) == variableAccessData->local())
-                return true;
-            if (variableAccessData->isCaptured())
-                break;
-            ArgumentsAliasingData& data =
-                m_argumentsAliasing.find(variableAccessData)->value;
-            if (!data.isValid())
-                break;
-                            
-            return true;
-        }
-                            
-        case CreateArguments: {
-            return true;
-        }
-                            
-        default:
-            break;
-        }
-        
-        return false;
-    }
-    
-    void detypeArgumentsReferencingPhantomChild(Node* node, unsigned edgeIndex)
-    {
-        Edge edge = node->children.child(edgeIndex);
-        if (!edge)
-            return;
-        
-        switch (edge->op()) {
-        case GetLocal: {
-            VariableAccessData* variableAccessData = edge->variableAccessData();
-            if (!variableAccessData->isArgumentsAlias())
-                break;
-            node->children.child(edgeIndex).setUseKind(UntypedUse);
-            break;
-        }
-            
-        case PhantomArguments: {
-            node->children.child(edgeIndex).setUseKind(UntypedUse);
-            break;
-        }
-            
-        default:
-            break;
-        }
-    }
-};
-
-bool performArgumentsSimplification(Graph& graph)
-{
-    SamplingRegion samplingRegion("DFG Arguments Simplification Phase");
-    return runPhase<ArgumentsSimplificationPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-
diff --git a/dfg/DFGArgumentsSimplificationPhase.h b/dfg/DFGArgumentsSimplificationPhase.h
deleted file mode 100644 (file)
index 25098ca..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
-
-#if ENABLE(DFG_JIT)
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
-
diff --git a/dfg/DFGArgumentsUtilities.cpp b/dfg/DFGArgumentsUtilities.cpp
new file mode 100644 (file)
index 0000000..5d512b1
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGArgumentsUtilities.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+bool argumentsInvolveStackSlot(InlineCallFrame* inlineCallFrame, VirtualRegister reg)
+{
+    if (!inlineCallFrame)
+        return (reg.isArgument() && reg.toArgument()) || reg.isHeader();
+    
+    if (inlineCallFrame->isClosureCall
+        && reg == VirtualRegister(inlineCallFrame->stackOffset + JSStack::Callee))
+        return true;
+    
+    if (inlineCallFrame->isVarargs()
+        && reg == VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount))
+        return true;
+    
+    unsigned numArguments = inlineCallFrame->arguments.size() - 1;
+    VirtualRegister argumentStart =
+        VirtualRegister(inlineCallFrame->stackOffset) + CallFrame::argumentOffset(0);
+    return reg >= argumentStart && reg < argumentStart + numArguments;
+}
+
+bool argumentsInvolveStackSlot(Node* candidate, VirtualRegister reg)
+{
+    return argumentsInvolveStackSlot(candidate->origin.semantic.inlineCallFrame, reg);
+}
+
+Node* emitCodeToGetArgumentsArrayLength(
+    InsertionSet& insertionSet, Node* arguments, unsigned nodeIndex, NodeOrigin origin)
+{
+    Graph& graph = insertionSet.graph();
+
+    DFG_ASSERT(
+        graph, arguments,
+        arguments->op() == CreateDirectArguments || arguments->op() == CreateScopedArguments
+        || arguments->op() == CreateClonedArguments || arguments->op() == PhantomDirectArguments
+        || arguments->op() == PhantomClonedArguments);
+    
+    InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
+    
+    if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+        return insertionSet.insertConstant(
+            nodeIndex, origin, jsNumber(inlineCallFrame->arguments.size() - 1));
+    }
+    
+    Node* argumentCount;
+    if (!inlineCallFrame)
+        argumentCount = insertionSet.insertNode(nodeIndex, SpecInt32, GetArgumentCount, origin);
+    else {
+        VirtualRegister argumentCountRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+        
+        argumentCount = insertionSet.insertNode(
+            nodeIndex, SpecInt32, GetStack, origin,
+            OpInfo(graph.m_stackAccessData.add(argumentCountRegister, FlushedInt32)));
+    }
+    
+    return insertionSet.insertNode(
+        nodeIndex, SpecInt32, ArithSub, origin, OpInfo(Arith::Unchecked),
+        Edge(argumentCount, Int32Use),
+        insertionSet.insertConstantForUse(
+            nodeIndex, origin, jsNumber(1), Int32Use));
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGArgumentsUtilities.h b/dfg/DFGArgumentsUtilities.h
new file mode 100644 (file)
index 0000000..82bfec3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGArgumentsUtilities_h
+#define DFGArgumentsUtilities_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+
+namespace JSC { namespace DFG {
+
+bool argumentsInvolveStackSlot(InlineCallFrame*, VirtualRegister);
+bool argumentsInvolveStackSlot(Node* candidate, VirtualRegister);
+
+Node* emitCodeToGetArgumentsArrayLength(
+    InsertionSet&, Node* arguments, unsigned nodeIndex, NodeOrigin);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGArgumentsUtilities_h
+
index 064f064e9cdffce42eb187d3e889a21c21657068..4e09ac3e93ab7f66a39dea4b83846215aaaa202f 100644 (file)
@@ -40,6 +40,14 @@ enum Mode {
     CheckOverflowAndNegativeZero, // Check for both overflow and negative zero.
     DoOverflow // Up-convert to the smallest type that soundly represents all possible results after input type speculation.
 };
+
+// Define the type of operation the rounding operation will perform.
+enum class RoundingMode {
+    Int32, // The round operation produces a integer and -0 is considered as 0.
+    Int32WithNegativeZeroCheck, // The round operation produces a integer and checks for -0.
+    Double // The round operation produce a double. The result can be -0, NaN or (+/-)Infinity.
+};
+
 } // namespace Arith
 
 inline bool doesOverflow(Arith::Mode mode)
@@ -122,6 +130,16 @@ inline bool subsumes(Arith::Mode earlier, Arith::Mode later)
     }
 }
 
+inline bool producesInteger(Arith::RoundingMode mode)
+{
+    return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck || mode == Arith::RoundingMode::Int32;
+}
+
+inline bool shouldCheckNegativeZero(Arith::RoundingMode mode)
+{
+    return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck;
+}
+
 } } // namespace JSC::DFG
 
 namespace WTF {
index 0cbdc7c433c0c80fd28858c6ae945d29d753a318..b0a4b049d3e57aab708edfcebc4f068c803b8ad7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -97,6 +97,24 @@ ArrayMode ArrayMode::fromObserved(const ConcurrentJITLocker& locker, ArrayProfil
     case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
     case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
         return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Int8ArrayMode:
+        return ArrayMode(Array::Int8Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Int16ArrayMode:
+        return ArrayMode(Array::Int16Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Int32ArrayMode:
+        return ArrayMode(Array::Int32Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Uint8ArrayMode:
+        return ArrayMode(Array::Uint8Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Uint8ClampedArrayMode:
+        return ArrayMode(Array::Uint8ClampedArray, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Uint16ArrayMode:
+        return ArrayMode(Array::Uint16Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Uint32ArrayMode:
+        return ArrayMode(Array::Uint32Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Float32ArrayMode:
+        return ArrayMode(Array::Float32Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
+    case Float64ArrayMode:
+        return ArrayMode(Array::Float64Array, nonArray, Array::AsIs).withProfile(locker, profile, makeSafe);
 
     default:
         if ((observed & asArrayModes(NonArray)) && profile->mayInterceptIndexedAccesses(locker))
@@ -133,8 +151,7 @@ ArrayMode ArrayMode::fromObserved(const ConcurrentJITLocker& locker, ArrayProfil
 
 ArrayMode ArrayMode::refine(
     Graph& graph, Node* node,
-    SpeculatedType base, SpeculatedType index, SpeculatedType value,
-    NodeFlags flags) const
+    SpeculatedType base, SpeculatedType index, SpeculatedType value) const
 {
     if (!base || !index) {
         // It can be that we had a legitimate arrayMode but no incoming predictions. That'll
@@ -147,6 +164,10 @@ ArrayMode ArrayMode::refine(
     if (!isInt32Speculation(index))
         return ArrayMode(Array::Generic);
     
+    // If we had exited because of an exotic object behavior, then don't try to specialize.
+    if (graph.hasExitSite(node->origin.semantic, ExoticObjectMode))
+        return ArrayMode(Array::Generic);
+    
     // Note: our profiling currently doesn't give us good information in case we have
     // an unlikely control flow path that sets the base to a non-cell value. Value
     // profiling and prediction propagation will probably tell us that the value is
@@ -158,9 +179,6 @@ ArrayMode ArrayMode::refine(
     // should just trust the array profile.
     
     switch (type()) {
-    case Array::Unprofiled:
-        return ArrayMode(Array::ForceExit);
-        
     case Array::Undecided:
         if (!value)
             return withType(Array::ForceExit);
@@ -178,25 +196,47 @@ ArrayMode ArrayMode::refine(
         return withTypeAndConversion(Array::Contiguous, Array::Convert);
         
     case Array::Double:
-        if (flags & NodeBytecodeUsesAsInt)
-            return withTypeAndConversion(Array::Contiguous, Array::RageConvert);
         if (!value || isFullNumberSpeculation(value))
             return *this;
         return withTypeAndConversion(Array::Contiguous, Array::Convert);
         
     case Array::Contiguous:
-        if (doesConversion() && (flags & NodeBytecodeUsesAsInt))
-            return withConversion(Array::RageConvert);
         return *this;
-        
+
+    case Array::Int8Array:
+    case Array::Int16Array:
+    case Array::Int32Array:
+    case Array::Uint8Array:
+    case Array::Uint8ClampedArray:
+    case Array::Uint16Array:
+    case Array::Uint32Array:
+    case Array::Float32Array:
+    case Array::Float64Array:
+        switch (node->op()) {
+        case PutByVal:
+            if (graph.hasExitSite(node->origin.semantic, OutOfBounds) || !isInBounds())
+                return withSpeculation(Array::OutOfBounds);
+            return withSpeculation(Array::InBounds);
+        default:
+            return withSpeculation(Array::InBounds);
+        }
+        return *this;
+    case Array::Unprofiled:
     case Array::SelectUsingPredictions: {
         base &= ~SpecOther;
         
         if (isStringSpeculation(base))
             return withType(Array::String);
         
-        if (isArgumentsSpeculation(base))
-            return withType(Array::Arguments);
+        if (isDirectArgumentsSpeculation(base) || isScopedArgumentsSpeculation(base)) {
+            // Handle out-of-bounds accesses as generic accesses.
+            if (graph.hasExitSite(node->origin.semantic, OutOfBounds) || !isInBounds())
+                return ArrayMode(Array::Generic);
+            
+            if (isDirectArgumentsSpeculation(base))
+                return withType(Array::DirectArguments);
+            return withType(Array::ScopedArguments);
+        }
         
         ArrayMode result;
         switch (node->op()) {
@@ -239,6 +279,8 @@ ArrayMode ArrayMode::refine(
         if (isFloat64ArraySpeculation(base))
             return result.withType(Array::Float64Array);
 
+        if (type() == Array::Unprofiled)
+            return ArrayMode(Array::ForceExit);
         return ArrayMode(Array::Generic);
     }
 
@@ -286,31 +328,54 @@ Structure* ArrayMode::originalArrayStructure(Graph& graph, Node* node) const
     return originalArrayStructure(graph, node->origin.semantic);
 }
 
-bool ArrayMode::alreadyChecked(Graph& graph, Node* node, AbstractValue& value, IndexingType shape) const
+bool ArrayMode::alreadyChecked(Graph& graph, Node* node, const AbstractValue& value, IndexingType shape) const
 {
     switch (arrayClass()) {
-    case Array::OriginalArray:
-        return value.m_currentKnownStructure.hasSingleton()
-            && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape
-            && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray)
-            && graph.globalObjectFor(node->origin.semantic)->isOriginalArrayStructure(value.m_currentKnownStructure.singleton());
+    case Array::OriginalArray: {
+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure->indexingType() & IndexingShapeMask) != shape)
+                return false;
+            if (!(structure->indexingType() & IsArray))
+                return false;
+            if (!graph.globalObjectFor(node->origin.semantic)->isOriginalArrayStructure(structure))
+                return false;
+        }
+        return true;
+    }
         
-    case Array::Array:
+    case Array::Array: {
         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
             return true;
-        return value.m_currentKnownStructure.hasSingleton()
-            && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape
-            && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure->indexingType() & IndexingShapeMask) != shape)
+                return false;
+            if (!(structure->indexingType() & IsArray))
+                return false;
+        }
+        return true;
+    }
         
-    default:
+    default: {
         if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray)))
             return true;
-        return value.m_currentKnownStructure.hasSingleton()
-            && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape;
-    }
+        if (value.m_structure.isTop())
+            return false;
+        for (unsigned i = value.m_structure.size(); i--;) {
+            Structure* structure = value.m_structure[i];
+            if ((structure->indexingType() & IndexingShapeMask) != shape)
+                return false;
+        }
+        return true;
+    } }
 }
 
-bool ArrayMode::alreadyChecked(Graph& graph, Node* node, AbstractValue& value) const
+bool ArrayMode::alreadyChecked(Graph& graph, Node* node, const AbstractValue& value) const
 {
     switch (type()) {
     case Array::Generic:
@@ -336,26 +401,44 @@ bool ArrayMode::alreadyChecked(Graph& graph, Node* node, AbstractValue& value) c
         
     case Array::SlowPutArrayStorage:
         switch (arrayClass()) {
-        case Array::OriginalArray:
+        case Array::OriginalArray: {
             CRASH();
             return false;
+        }
         
-        case Array::Array:
+        case Array::Array: {
             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
                 return true;
-            return value.m_currentKnownStructure.hasSingleton()
-                && hasAnyArrayStorage(value.m_currentKnownStructure.singleton()->indexingType())
-                && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+            if (value.m_structure.isTop())
+                return false;
+            for (unsigned i = value.m_structure.size(); i--;) {
+                Structure* structure = value.m_structure[i];
+                if (!hasAnyArrayStorage(structure->indexingType()))
+                    return false;
+                if (!(structure->indexingType() & IsArray))
+                    return false;
+            }
+            return true;
+        }
         
-        default:
+        default: {
             if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
                 return true;
-            return value.m_currentKnownStructure.hasSingleton()
-                && hasAnyArrayStorage(value.m_currentKnownStructure.singleton()->indexingType());
-        }
+            if (value.m_structure.isTop())
+                return false;
+            for (unsigned i = value.m_structure.size(); i--;) {
+                Structure* structure = value.m_structure[i];
+                if (!hasAnyArrayStorage(structure->indexingType()))
+                    return false;
+            }
+            return true;
+        } }
+        
+    case Array::DirectArguments:
+        return speculationChecked(value.m_type, SpecDirectArguments);
         
-    case Array::Arguments:
-        return speculationChecked(value.m_type, SpecArguments);
+    case Array::ScopedArguments:
+        return speculationChecked(value.m_type, SpecScopedArguments);
         
     case Array::Int8Array:
         return speculationChecked(value.m_type, SpecInt8Array);
@@ -419,8 +502,10 @@ const char* arrayTypeToString(Array::Type type)
         return "ArrayStorage";
     case Array::SlowPutArrayStorage:
         return "SlowPutArrayStorage";
-    case Array::Arguments:
-        return "Arguments";
+    case Array::DirectArguments:
+        return "DirectArguments";
+    case Array::ScopedArguments:
+        return "ScopedArguments";
     case Array::Int8Array:
         return "Int8Array";
     case Array::Int16Array:
@@ -489,8 +574,6 @@ const char* arrayConversionToString(Array::Conversion conversion)
         return "AsIs";
     case Array::Convert:
         return "Convert";
-    case Array::RageConvert:
-        return "RageConvert";
     default:
         return "Unknown!";
     }
index 084c985cef83fac6fcc566022fd62c6ee1729465..a77c888da752c83f10e4a412e75db9d52fe556d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,7 +65,9 @@ enum Type {
     ArrayStorage,
     SlowPutArrayStorage,
     
-    Arguments,
+    DirectArguments,
+    ScopedArguments,
+    
     Int8Array,
     Int16Array,
     Int32Array,
@@ -87,14 +89,14 @@ enum Class {
 
 enum Speculation {
     SaneChain, // In bounds and the array prototype chain is still intact, i.e. loading a hole doesn't require special treatment.
+    
     InBounds, // In bounds and not loading a hole.
     ToHole, // Potentially storing to a hole.
     OutOfBounds // Out-of-bounds access and anything can happen.
 };
 enum Conversion {
     AsIs,
-    Convert,
-    RageConvert
+    Convert
 };
 } // namespace Array
 
@@ -220,9 +222,9 @@ public:
         return ArrayMode(type, arrayClass(), speculation(), conversion);
     }
     
-    ArrayMode refine(Graph&, Node*, SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone, NodeFlags = 0) const;
+    ArrayMode refine(Graph&, Node*, SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone) const;
     
-    bool alreadyChecked(Graph&, Node*, AbstractValue&) const;
+    bool alreadyChecked(Graph&, Node*, const AbstractValue&) const;
     
     void dump(PrintStream&) const;
     
@@ -294,7 +296,8 @@ public:
         case Array::Unprofiled:
         case Array::ForceExit:
         case Array::Generic:
-        case Array::Arguments:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             return false;
         default:
             return true;
@@ -320,11 +323,9 @@ public:
     {
         switch (type()) {
         case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             return ArrayMode(Array::Generic);
-#if USE(JSVALUE32_64)
-        case Array::Arguments:
-            return ArrayMode(Array::Generic);
-#endif
         default:
             return *this;
         }
@@ -469,7 +470,7 @@ private:
         return arrayMode1 | arrayMode2;
     }
 
-    bool alreadyChecked(Graph&, Node*, AbstractValue&, IndexingType shape) const;
+    bool alreadyChecked(Graph&, Node*, const AbstractValue&, IndexingType shape) const;
     
     union {
         struct {
index 6d54b019b06aef367b67f345dc0025d8248002e7..9019eb18c592189b8824f937933c28a727361b2f 100644 (file)
@@ -101,10 +101,7 @@ protected:
             jit->callOperation(operationEnsureDouble, m_tempGPR, m_baseGPR);
             break;
         case Array::Contiguous:
-            if (m_arrayMode.conversion() == Array::RageConvert)
-                jit->callOperation(operationRageEnsureContiguous, m_tempGPR, m_baseGPR);
-            else
-                jit->callOperation(operationEnsureContiguous, m_tempGPR, m_baseGPR);
+            jit->callOperation(operationEnsureContiguous, m_tempGPR, m_baseGPR);
             break;
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
index ef6381e09ca9237a453998b9515c2f0df89e3590..9d8c710de69e9837608d054226700a39853da2d4 100644 (file)
@@ -32,8 +32,9 @@
 
 namespace JSC { namespace DFG {
 
-AtTailAbstractState::AtTailAbstractState()
-    : m_block(0)
+AtTailAbstractState::AtTailAbstractState(Graph& graph)
+    : m_graph(graph)
+    , m_block(0)
 {
 }
 
@@ -47,7 +48,7 @@ void AtTailAbstractState::createValueForNode(Node* node)
 AbstractValue& AtTailAbstractState::forNode(Node* node)
 {
     HashMap<Node*, AbstractValue>::iterator iter = m_block->ssa->valuesAtTail.find(node);
-    ASSERT(iter != m_block->ssa->valuesAtTail.end());
+    DFG_ASSERT(m_graph, node, iter != m_block->ssa->valuesAtTail.end());
     return iter->value;
 }
 
index 7a872f994824d2385f6dc69358dd2596e2d1173f..cd6a080016db500e0404d6661a0a2ce1068ce549 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC { namespace DFG {
 
 class AtTailAbstractState {
 public:
-    AtTailAbstractState();
+    AtTailAbstractState(Graph&);
     
     ~AtTailAbstractState();
     
@@ -54,14 +54,16 @@ public:
     
     bool isValid() { return m_block->cfaDidFinish; }
     
+    StructureClobberState structureClobberState() const { return m_block->cfaStructureClobberStateAtTail; }
+    
     void setDidClobber(bool) { }
+    void setStructureClobberState(StructureClobberState state) { RELEASE_ASSERT(state == m_block->cfaStructureClobberStateAtTail); }
     void setIsValid(bool isValid) { m_block->cfaDidFinish = isValid; }
     void setBranchDirection(BranchDirection) { }
     void setFoundConstants(bool) { }
-    bool haveStructures() const { return true; } // It's always safe to return true.
-    void setHaveStructures(bool) { }
 
 private:
+    Graph& m_graph;
     BasicBlock* m_block;
 };
 
index fd9bf6529836bea34a25e8613133e6959617126e..507d816aa66652a53a8ee601a257790424c8b4e1 100644 (file)
@@ -81,10 +81,26 @@ public:
         return withNode(unavailableMarker());
     }
     
+    void setFlush(FlushedAt flushedAt)
+    {
+        m_flushedAt = flushedAt;
+    }
+    
+    void setNode(Node* node)
+    {
+        m_node = node;
+    }
+    
+    void setNodeUnavailable()
+    {
+        m_node = unavailableMarker();
+    }
+    
     bool nodeIsUndecided() const { return !m_node; }
     bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
     
     bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
+    bool shouldUseNode() const { return !isFlushUseful() && hasNode(); }
     
     Node* node() const
     {
@@ -94,6 +110,12 @@ public:
     }
     
     FlushedAt flushedAt() const { return m_flushedAt; }
+    bool isFlushUseful() const
+    {
+        return flushedAt().format() != DeadFlush && flushedAt().format() != ConflictingFlush;
+    }
+    
+    bool isDead() const { return !isFlushUseful() && !hasNode(); }
     
     bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
 
@@ -103,6 +125,11 @@ public:
             && m_flushedAt == other.m_flushedAt;
     }
     
+    bool operator!=(const Availability& other) const
+    {
+        return !(*this == other);
+    }
+    
     Availability merge(const Availability& other) const
     {
         return Availability(
diff --git a/dfg/DFGAvailabilityMap.cpp b/dfg/DFGAvailabilityMap.cpp
new file mode 100644 (file)
index 0000000..e319dc6
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGAvailabilityMap.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "JSCInlines.h"
+#include "OperandsInlines.h"
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace DFG {
+
+void AvailabilityMap::pruneHeap()
+{
+    if (m_heap.isEmpty())
+        return;
+    
+    HashSet<Node*> possibleNodes;
+    
+    for (unsigned i = m_locals.size(); i--;) {
+        if (m_locals[i].hasNode())
+            possibleNodes.add(m_locals[i].node());
+    }
+
+    closeOverNodes(
+        [&] (Node* node) -> bool {
+            return possibleNodes.contains(node);
+        },
+        [&] (Node* node) -> bool {
+            return possibleNodes.add(node).isNewEntry;
+        });
+    
+    HashMap<PromotedHeapLocation, Availability> newHeap;
+    for (auto pair : m_heap) {
+        if (possibleNodes.contains(pair.key.base()))
+            newHeap.add(pair.key, pair.value);
+    }
+    m_heap = newHeap;
+}
+
+void AvailabilityMap::pruneByLiveness(Graph& graph, CodeOrigin where)
+{
+    Operands<Availability> localsCopy(OperandsLike, m_locals);
+    graph.forAllLiveInBytecode(
+        where,
+        [&] (VirtualRegister reg) {
+            localsCopy.operand(reg) = m_locals.operand(reg);
+        });
+    m_locals = localsCopy;
+    pruneHeap();
+}
+
+void AvailabilityMap::clear()
+{
+    m_locals.fill(Availability());
+    m_heap.clear();
+}
+
+void AvailabilityMap::dump(PrintStream& out) const
+{
+    out.print("{locals = ", m_locals, "; heap = ", mapDump(m_heap), "}");
+}
+
+bool AvailabilityMap::operator==(const AvailabilityMap& other) const
+{
+    return m_locals == other.m_locals
+        && m_heap == other.m_heap;
+}
+
+void AvailabilityMap::merge(const AvailabilityMap& other)
+{
+    for (unsigned i = other.m_locals.size(); i--;)
+        m_locals[i] = other.m_locals[i].merge(m_locals[i]);
+    
+    for (auto pair : other.m_heap) {
+        auto result = m_heap.add(pair.key, Availability());
+        result.iterator->value = pair.value.merge(result.iterator->value);
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGAvailabilityMap.h b/dfg/DFGAvailabilityMap.h
new file mode 100644 (file)
index 0000000..1cdd25b
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGAvailabilityMap_h
+#define DFGAvailabilityMap_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAvailability.h"
+#include "DFGPromotedHeapLocation.h"
+
+namespace JSC { namespace DFG {
+
+struct AvailabilityMap {
+    void pruneHeap();
+    void pruneByLiveness(Graph&, CodeOrigin);
+    void clear();
+    
+    void dump(PrintStream& out) const;
+    
+    bool operator==(const AvailabilityMap& other) const;
+    
+    void merge(const AvailabilityMap& other);
+    
+    template<typename Functor>
+    void forEachAvailability(const Functor& functor)
+    {
+        for (unsigned i = m_locals.size(); i--;)
+            functor(m_locals[i]);
+        for (auto pair : m_heap)
+            functor(pair.value);
+    }
+    
+    template<typename HasFunctor, typename AddFunctor>
+    void closeOverNodes(const HasFunctor& has, const AddFunctor& add)
+    {
+        bool changed;
+        do {
+            changed = false;
+            for (auto pair : m_heap) {
+                if (pair.value.hasNode() && has(pair.key.base()))
+                    changed |= add(pair.value.node());
+            }
+        } while (changed);
+    }
+    
+    template<typename HasFunctor, typename AddFunctor>
+    void closeStartingWithLocal(VirtualRegister reg, const HasFunctor& has, const AddFunctor& add)
+    {
+        Availability availability = m_locals.operand(reg);
+        if (!availability.hasNode())
+            return;
+        
+        if (!add(availability.node()))
+            return;
+        
+        closeOverNodes(has, add);
+    }
+    
+    Operands<Availability> m_locals;
+    HashMap<PromotedHeapLocation, Availability> m_heap;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGAvailabilityMap_h
+
index 9d063fd5b0549877338f79781e9195d84c22edef..2768f611fca8e5f74a2b6364d6591831cdc63886 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -67,17 +67,17 @@ public:
 private:
     bool isNotNegZero(Node* node)
     {
-        if (!m_graph.isNumberConstant(node))
+        if (!node->isNumberConstant())
             return false;
-        double value = m_graph.valueOfNumberConstant(node);
+        double value = node->asNumber();
         return (value || 1.0 / value > 0.0);
     }
     
     bool isNotPosZero(Node* node)
     {
-        if (!m_graph.isNumberConstant(node))
+        if (!node->isNumberConstant())
             return false;
-        double value = m_graph.valueOfNumberConstant(node);
+        double value = node->asNumber();
         return (value || 1.0 / value < 0.0);
     }
 
@@ -85,7 +85,7 @@ private:
     template<int power>
     bool isWithinPowerOfTwoForConstant(Node* node)
     {
-        JSValue immediateValue = node->valueOfJSConstant(codeBlock());
+        JSValue immediateValue = node->asJSValue();
         if (!immediateValue.isNumber())
             return false;
         double immediate = immediateValue.asNumber();
@@ -95,7 +95,7 @@ private:
     template<int power>
     bool isWithinPowerOfTwoNonRecursive(Node* node)
     {
-        if (node->op() != JSConstant)
+        if (!node->isNumberConstant())
             return false;
         return isWithinPowerOfTwoForConstant<power>(node);
     }
@@ -104,7 +104,9 @@ private:
     bool isWithinPowerOfTwo(Node* node)
     {
         switch (node->op()) {
-        case JSConstant: {
+        case DoubleConstant:
+        case JSConstant:
+        case Int52Constant: {
             return isWithinPowerOfTwoForConstant<power>(node);
         }
             
@@ -128,9 +130,9 @@ private:
                 return true;
             
             Node* shiftAmount = node->child2().node();
-            if (shiftAmount->op() != JSConstant)
+            if (!node->isNumberConstant())
                 return false;
-            JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock());
+            JSValue immediateValue = shiftAmount->asJSValue();
             if (!immediateValue.isInt32())
                 return false;
             return immediateValue.asInt32() > 32 - power;
@@ -257,7 +259,14 @@ private:
             node->child2()->mergeFlags(flags);
             break;
         }
-            
+
+        case ArithClz32: {
+            flags &= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther | ~NodeBytecodeUsesAsArrayIndex);
+            flags |= NodeBytecodeUsesAsInt;
+            node->child1()->mergeFlags(flags);
+            break;
+        }
+
         case ArithSub: {
             if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node()))
                 flags &= ~NodeBytecodeNeedsNegZero;
@@ -310,11 +319,11 @@ private:
         }
             
         case ArithMod: {
-            flags |= NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero;
+            flags |= NodeBytecodeUsesAsNumber;
             flags &= ~NodeBytecodeUsesAsOther;
 
             node->child1()->mergeFlags(flags);
-            node->child2()->mergeFlags(flags);
+            node->child2()->mergeFlags(flags & ~NodeBytecodeNeedsNegZero);
             break;
         }
             
@@ -324,11 +333,6 @@ private:
             break;
         }
             
-        case GetMyArgumentByValSafe: {
-            node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
-            break;
-        }
-            
         case NewArrayWithSize: {
             node->child1()->mergeFlags(NodeBytecodeUsesAsValue | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
             break;
@@ -348,7 +352,8 @@ private:
             break;
         }
             
-        case ToString: {
+        case ToString:
+        case CallStringConstructor: {
             node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
             break;
         }
@@ -389,6 +394,11 @@ private:
                 // then -0 and 0 are treated the same.
                 node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
                 break;
+            case SwitchCell:
+                // There is currently no point to being clever here since this is used for switching
+                // on objects.
+                mergeDefaultFlags(node);
+                break;
             }
             break;
         }
index 5f3b4805856bb7f9cca8c9c590cdbe6787071590..f83f50c469467d5cda0a7704ad47803c174c06ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,6 +41,8 @@ BasicBlock::BasicBlock(
     , cfaShouldRevisit(false)
     , cfaFoundConstants(false)
     , cfaDidFinish(true)
+    , cfaStructureClobberStateAtHead(StructuresAreWatched)
+    , cfaStructureClobberStateAtTail(StructuresAreWatched)
     , cfaBranchDirection(InvalidBranchDirection)
 #if !ASSERT_DISABLED
     , isLinked(false)
@@ -50,11 +52,15 @@ BasicBlock::BasicBlock(
     , variablesAtTail(numArguments, numLocals)
     , valuesAtHead(numArguments, numLocals)
     , valuesAtTail(numArguments, numLocals)
+    , intersectionOfPastValuesAtHead(numArguments, numLocals, AbstractValue::fullTop())
+    , intersectionOfCFAHasVisited(true)
     , executionCount(executionCount)
 {
 }
 
-BasicBlock::~BasicBlock() { }
+BasicBlock::~BasicBlock()
+{
+}
 
 void BasicBlock::ensureLocals(unsigned newNumLocals)
 {
@@ -62,6 +68,20 @@ void BasicBlock::ensureLocals(unsigned newNumLocals)
     variablesAtTail.ensureLocals(newNumLocals);
     valuesAtHead.ensureLocals(newNumLocals);
     valuesAtTail.ensureLocals(newNumLocals);
+    intersectionOfPastValuesAtHead.ensureLocals(newNumLocals, AbstractValue::fullTop());
+}
+
+void BasicBlock::replaceTerminal(Node* node)
+{
+    NodeAndIndex result = findTerminal();
+    if (!result)
+        append(node);
+    else {
+        m_nodes.insert(result.index + 1, node);
+        result.node->remove();
+    }
+    
+    ASSERT(terminal());
 }
 
 bool BasicBlock::isInPhis(Node* node) const
@@ -82,6 +102,21 @@ bool BasicBlock::isInBlock(Node* myNode) const
     return false;
 }
 
+Node* BasicBlock::firstOriginNode()
+{
+    for (Node* node : *this) {
+        if (node->origin.isSet())
+            return node;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+NodeOrigin BasicBlock::firstOrigin()
+{
+    return firstOriginNode()->origin;
+}
+
 void BasicBlock::removePredecessor(BasicBlock* block)
 {
     for (unsigned i = 0; i < predecessors.size(); ++i) {
@@ -111,9 +146,9 @@ void BasicBlock::dump(PrintStream& out) const
 }
 
 BasicBlock::SSAData::SSAData(BasicBlock* block)
-    : availabilityAtHead(OperandsLike, block->variablesAtHead)
-    , availabilityAtTail(OperandsLike, block->variablesAtHead)
 {
+    availabilityAtHead.m_locals = Operands<Availability>(OperandsLike, block->variablesAtHead);
+    availabilityAtTail.m_locals = Operands<Availability>(OperandsLike, block->variablesAtHead);
 }
 
 BasicBlock::SSAData::~SSAData() { }
index 19d5487a6a5ac01f6e9e261ce14018fe483f0f9a..420ff511c8b6e2250e3779de8639d3cd70a0822d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "DFGAbstractValue.h"
 #include "DFGAvailability.h"
+#include "DFGAvailabilityMap.h"
 #include "DFGBranchDirection.h"
 #include "DFGFlushedAt.h"
 #include "DFGNode.h"
+#include "DFGNodeOrigin.h"
+#include "DFGStructureClobberState.h"
 #include "Operands.h"
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC { namespace DFG {
@@ -45,6 +47,7 @@ class Graph;
 class InsertionSet;
 
 typedef Vector<BasicBlock*, 2> PredecessorList;
+typedef Vector<Node*, 8> BlockNodeList;
 
 struct BasicBlock : RefCounted<BasicBlock> {
     BasicBlock(
@@ -58,19 +61,72 @@ struct BasicBlock : RefCounted<BasicBlock> {
     bool isEmpty() const { return !size(); }
     Node*& at(size_t i) { return m_nodes[i]; }
     Node* at(size_t i) const { return m_nodes[i]; }
+    Node* tryAt(size_t i) const
+    {
+        if (i >= size())
+            return nullptr;
+        return at(i);
+    }
     Node*& operator[](size_t i) { return at(i); }
     Node* operator[](size_t i) const { return at(i); }
-    Node* last() const { return at(size() - 1); }
+    
+    // Use this to find both the index of the terminal and the terminal itself in one go. May
+    // return a clear NodeAndIndex if the basic block currently lacks a terminal. That may happen
+    // in the middle of IR transformations within a phase but should never be the case in between
+    // phases.
+    //
+    // The reason why this is more than just "at(size() - 1)" is that we may place non-terminal
+    // liveness marking instructions after the terminal. This is supposed to happen infrequently
+    // but some basic blocks - most notably return blocks - will have liveness markers for all of
+    // the flushed variables right after the return.
+    //
+    // It turns out that doing this linear search is basically perf-neutral, so long as we force
+    // the method to be inlined. Hence the ALWAYS_INLINE.
+    ALWAYS_INLINE NodeAndIndex findTerminal() const
+    {
+        size_t i = size();
+        while (i--) {
+            Node* node = at(i);
+            switch (node->op()) {
+            case Jump:
+            case Branch:
+            case Switch:
+            case Return:
+            case Unreachable:
+                return NodeAndIndex(node, i);
+            // The bitter end can contain Phantoms and the like. There will probably only be one or two nodes after the terminal. They are all no-ops and will not have any checked children.
+            case Check: // This is here because it's our universal no-op.
+            case Phantom:
+            case PhantomLocal:
+            case Flush:
+                break;
+            default:
+                return NodeAndIndex();
+            }
+        }
+        return NodeAndIndex();
+    }
+    
+    ALWAYS_INLINE Node* terminal() const
+    {
+        return findTerminal().node;
+    }
+    
     void resize(size_t size) { m_nodes.resize(size); }
     void grow(size_t size) { m_nodes.grow(size); }
     
     void append(Node* node) { m_nodes.append(node); }
-    void insertBeforeLast(Node* node)
+    void insertBeforeTerminal(Node* node)
     {
-        append(last());
-        at(size() - 2) = node;
+        NodeAndIndex result = findTerminal();
+        if (!result)
+            append(node);
+        else
+            m_nodes.insert(result.index, node);
     }
     
+    void replaceTerminal(Node*);
+    
     size_t numNodes() const { return phis.size() + size(); }
     Node* node(size_t i) const
     {
@@ -83,15 +139,26 @@ struct BasicBlock : RefCounted<BasicBlock> {
     bool isInPhis(Node* node) const;
     bool isInBlock(Node* myNode) const;
     
-    unsigned numSuccessors() { return last()->numSuccessors(); }
+    BlockNodeList::iterator begin() { return m_nodes.begin(); }
+    BlockNodeList::iterator end() { return m_nodes.end(); }
+    
+    Node* firstOriginNode();
+    NodeOrigin firstOrigin();
+    
+    unsigned numSuccessors() { return terminal()->numSuccessors(); }
     
     BasicBlock*& successor(unsigned index)
     {
-        return last()->successor(index);
+        return terminal()->successor(index);
     }
     BasicBlock*& successorForCondition(bool condition)
     {
-        return last()->successorForCondition(condition);
+        return terminal()->successorForCondition(condition);
+    }
+
+    Node::SuccessorsIterable successors()
+    {
+        return terminal()->successors();
     }
     
     void removePredecessor(BasicBlock* block);
@@ -103,8 +170,18 @@ struct BasicBlock : RefCounted<BasicBlock> {
     template<typename... Params>
     Node* appendNonTerminal(Graph&, SpeculatedType, Params...);
     
+    template<typename... Params>
+    Node* replaceTerminal(Graph&, SpeculatedType, Params...);
+    
     void dump(PrintStream& out) const;
     
+    void didLink()
+    {
+#if !ASSERT_DISABLED
+        isLinked = true;
+#endif
+    }
+    
     // This value is used internally for block linking and OSR entry. It is mostly meaningless
     // for other purposes due to inlining.
     unsigned bytecodeBegin;
@@ -116,6 +193,8 @@ struct BasicBlock : RefCounted<BasicBlock> {
     bool cfaShouldRevisit;
     bool cfaFoundConstants;
     bool cfaDidFinish;
+    StructureClobberState cfaStructureClobberStateAtHead;
+    StructureClobberState cfaStructureClobberStateAtTail;
     BranchDirection cfaBranchDirection;
 #if !ASSERT_DISABLED
     bool isLinked;
@@ -131,6 +210,26 @@ struct BasicBlock : RefCounted<BasicBlock> {
     Operands<AbstractValue> valuesAtHead;
     Operands<AbstractValue> valuesAtTail;
     
+    // The intersection of assumptions we have made previously at the head of this block. Note
+    // that under normal circumstances, each time we run the CFA, we will get strictly more precise
+    // results. But we don't actually require this to be the case. It's fine for the CFA to loosen
+    // up for any odd reason. It's fine when this happens, because anything that the CFA proves
+    // must be true from that point forward, except if some registered watchpoint fires, in which
+    // case the code won't ever run. So, the CFA proving something less precise later on is just an
+    // outcome of the CFA being imperfect; the more precise thing that it had proved earlier is no
+    // less true.
+    //
+    // But for the purpose of OSR entry, we need to make sure that we remember what assumptions we
+    // had used for optimizing any given basic block. That's what this is for.
+    //
+    // It's interesting that we could use this to make the CFA more precise: all future CFAs could
+    // filter their results with this thing to sort of maintain maximal precision. Because we
+    // expect CFA to usually be monotonically more precise each time we run it to fixpoint, this
+    // would not be a productive optimization: it would make setting up a basic block more
+    // expensive and would only benefit bizarre pathological cases.
+    Operands<AbstractValue> intersectionOfPastValuesAtHead;
+    bool intersectionOfCFAHasVisited;
+    
     float executionCount;
     
     // These fields are reserved for NaturalLoops.
@@ -138,8 +237,9 @@ struct BasicBlock : RefCounted<BasicBlock> {
     unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
 
     struct SSAData {
-        Operands<Availability> availabilityAtHead;
-        Operands<Availability> availabilityAtTail;
+        AvailabilityMap availabilityAtHead;
+        AvailabilityMap availabilityAtTail;
+        
         HashSet<Node*> liveAtHead;
         HashSet<Node*> liveAtTail;
         HashMap<Node*, AbstractValue> valuesAtHead;
@@ -148,13 +248,15 @@ struct BasicBlock : RefCounted<BasicBlock> {
         SSAData(BasicBlock*);
         ~SSAData();
     };
-    OwnPtr<SSAData> ssa;
-
+    std::unique_ptr<SSAData> ssa;
+    
 private:
     friend class InsertionSet;
-    Vector<Node*, 8> m_nodes;
+    BlockNodeList m_nodes;
 };
 
+typedef Vector<BasicBlock*, 5> BlockList;
+
 struct UnlinkedBlock {
     BasicBlock* m_block;
     bool m_needsNormalLinking;
index 4a0fe92fc6d5ab6ce1696279f07225e4d81b2c18..3423a0db35bf00e8b78df292f02dcb275849dd99 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,15 @@ template<typename... Params>
 Node* BasicBlock::appendNonTerminal(Graph& graph, SpeculatedType type, Params... params)
 {
     Node* result = graph.addNode(type, params...);
-    insertBeforeLast(result);
+    insertBeforeTerminal(result);
+    return result;
+}
+
+template<typename... Params>
+Node* BasicBlock::replaceTerminal(Graph& graph, SpeculatedType type, Params... params)
+{
+    Node* result = graph.addNode(type, params...);
+    replaceTerminal(result);
     return result;
 }
 
diff --git a/dfg/DFGBinarySwitch.cpp b/dfg/DFGBinarySwitch.cpp
deleted file mode 100644 (file)
index 5aa6b01..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DFGBinarySwitch.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-BinarySwitch::BinarySwitch(GPRReg value, const Vector<int64_t>& cases, Type type)
-    : m_value(value)
-    , m_index(0)
-    , m_caseIndex(UINT_MAX)
-    , m_medianBias(0)
-    , m_type(type)
-{
-    if (cases.isEmpty())
-        return;
-    
-    for (unsigned i = 0; i < cases.size(); ++i)
-        m_cases.append(Case(cases[i], i));
-    std::sort(m_cases.begin(), m_cases.end());
-    build(0, m_cases.size());
-}
-
-bool BinarySwitch::advance(MacroAssembler& jit)
-{
-    if (m_cases.isEmpty()) {
-        m_fallThrough.append(jit.jump());
-        return false;
-    }
-    
-    if (m_index == m_branches.size()) {
-        RELEASE_ASSERT(m_jumpStack.isEmpty());
-        return false;
-    }
-    
-    for (;;) {
-        const BranchCode& code = m_branches[m_index++];
-        switch (code.kind) {
-        case NotEqualToFallThrough:
-            switch (m_type) {
-            case Int32:
-                m_fallThrough.append(jit.branch32(
-                    MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
-                break;
-            case IntPtr:
-                m_fallThrough.append(jit.branchPtr(
-                    MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
-                break;
-            }
-            break;
-        case NotEqualToPush:
-            switch (m_type) {
-            case Int32:
-                m_jumpStack.append(jit.branch32(
-                    MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
-                break;
-            case IntPtr:
-                m_jumpStack.append(jit.branchPtr(
-                    MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
-                break;
-            }
-            break;
-        case LessThanToPush:
-            switch (m_type) {
-            case Int32:
-                m_jumpStack.append(jit.branch32(
-                    MacroAssembler::LessThan, m_value,
-                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
-                break;
-            case IntPtr:
-                m_jumpStack.append(jit.branchPtr(
-                    MacroAssembler::LessThan, m_value,
-                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
-                break;
-            }
-            break;
-        case Pop:
-            m_jumpStack.takeLast().link(&jit);
-            break;
-        case ExecuteCase:
-            m_caseIndex = code.index;
-            return true;
-        }
-    }
-}
-
-void BinarySwitch::build(unsigned start, unsigned end)
-{
-    unsigned size = end - start;
-    
-    switch (size) {
-    case 0: {
-        RELEASE_ASSERT_NOT_REACHED();
-        break;
-    }
-        
-    case 1: {
-        if (start
-            && m_cases[start - 1].value == m_cases[start].value - 1
-            && start + 1 < m_cases.size()
-            && m_cases[start + 1].value == m_cases[start].value + 1) {
-            m_branches.append(BranchCode(ExecuteCase, start));
-            break;
-        }
-        
-        m_branches.append(BranchCode(NotEqualToFallThrough, start));
-        m_branches.append(BranchCode(ExecuteCase, start));
-        break;
-    }
-        
-    case 2: {
-        if (m_cases[start].value + 1 == m_cases[start + 1].value
-            && start
-            && m_cases[start - 1].value == m_cases[start].value - 1
-            && start + 2 < m_cases.size()
-            && m_cases[start + 2].value == m_cases[start + 1].value + 1) {
-            m_branches.append(BranchCode(NotEqualToPush, start));
-            m_branches.append(BranchCode(ExecuteCase, start));
-            m_branches.append(BranchCode(Pop));
-            m_branches.append(BranchCode(ExecuteCase, start + 1));
-            break;
-        }
-        
-        unsigned firstCase = start;
-        unsigned secondCase = start + 1;
-        if (m_medianBias)
-            std::swap(firstCase, secondCase);
-        m_medianBias ^= 1;
-        
-        m_branches.append(BranchCode(NotEqualToPush, firstCase));
-        m_branches.append(BranchCode(ExecuteCase, firstCase));
-        m_branches.append(BranchCode(Pop));
-        m_branches.append(BranchCode(NotEqualToFallThrough, secondCase));
-        m_branches.append(BranchCode(ExecuteCase, secondCase));
-        break;
-    }
-        
-    default: {
-        unsigned medianIndex = (start + end) / 2;
-        if (!(size & 1)) {
-            // Because end is exclusive, in the even case, this rounds up by
-            // default. Hence median bias sometimes flips to subtracing one
-            // in order to get round-down behavior.
-            medianIndex -= m_medianBias;
-            m_medianBias ^= 1;
-        }
-        
-        RELEASE_ASSERT(medianIndex > start);
-        RELEASE_ASSERT(medianIndex + 1 < end);
-        
-        m_branches.append(BranchCode(LessThanToPush, medianIndex));
-        m_branches.append(BranchCode(NotEqualToPush, medianIndex));
-        m_branches.append(BranchCode(ExecuteCase, medianIndex));
-        
-        m_branches.append(BranchCode(Pop));
-        build(medianIndex + 1, end);
-        
-        m_branches.append(BranchCode(Pop));
-        build(start, medianIndex);
-        break;
-    } }
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/dfg/DFGBinarySwitch.h b/dfg/DFGBinarySwitch.h
deleted file mode 100644 (file)
index 45d4a6a..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DFGBinarySwitch_h
-#define DFGBinarySwitch_h
-
-#if ENABLE(DFG_JIT)
-
-#include "GPRInfo.h"
-#include "MacroAssembler.h"
-
-namespace JSC { namespace DFG {
-
-// The BinarySwitch class makes it easy to emit a switch statement over either
-// 32-bit integers or pointers, where the switch uses a tree of branches
-// rather than a jump table. This makes it particularly useful if the case
-// values are too far apart to make a jump table practical, or if there are
-// sufficiently few cases that the total cost of log(numCases) branches is
-// less than the cost of an indirected jump.
-//
-// In an effort to simplify the logic of emitting code for each case, this
-// uses an iterator style, rather than a functor callback style. This makes
-// sense because even the iterator implementation found herein is relatively
-// simple, whereas the code it's used from is usually quite complex - one
-// example being the trie-of-trees string switch implementation, where the
-// code emitted for each case involves recursing to emit code for a sub-trie.
-//
-// Use this like so:
-//
-// BinarySwitch switch(valueReg, casesVector, BinarySwitch::Int32);
-// while (switch.advance(jit)) {
-//     int value = switch.caseValue();
-//     unsigned index = switch.caseIndex(); // index into casesVector, above
-//     ... // generate code for this case
-// }
-// switch.fallThrough().link(&jit);
-
-class BinarySwitch {
-public:
-    enum Type {
-        Int32,
-        IntPtr
-    };
-    
-    BinarySwitch(GPRReg value, const Vector<int64_t>& cases, Type);
-    
-    unsigned caseIndex() const { return m_cases[m_caseIndex].index; }
-    int64_t caseValue() const { return m_cases[m_caseIndex].value; }
-    
-    bool advance(MacroAssembler&);
-    
-    MacroAssembler::JumpList& fallThrough() { return m_fallThrough; }
-    
-private:
-    void build(unsigned start, unsigned end);
-    
-    GPRReg m_value;
-    
-    struct Case {
-        Case() { }
-
-        Case(int64_t value, unsigned index)
-            : value(value)
-            , index(index)
-        {
-        }
-        
-        bool operator<(const Case& other) const
-        {
-            return value < other.value;
-        }
-        
-        int64_t value;
-        unsigned index;
-    };
-    
-    Vector<Case> m_cases;
-    
-    enum BranchKind {
-        NotEqualToFallThrough,
-        NotEqualToPush,
-        LessThanToPush,
-        Pop,
-        ExecuteCase
-    };
-        
-    struct BranchCode {
-        BranchCode() { }
-        
-        BranchCode(BranchKind kind, unsigned index = UINT_MAX)
-            : kind(kind)
-            , index(index)
-        {
-        }
-        
-        BranchKind kind;
-        unsigned index;
-    };
-    
-    Vector<BranchCode> m_branches;
-
-    unsigned m_index;
-    unsigned m_caseIndex;
-    Vector<MacroAssembler::Jump> m_jumpStack;
-    
-    MacroAssembler::JumpList m_fallThrough;
-    
-    unsigned m_medianBias;
-    
-    Type m_type;
-};
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGBinarySwitch_h
-
diff --git a/dfg/DFGBlockMap.h b/dfg/DFGBlockMap.h
new file mode 100644 (file)
index 0000000..aaf343c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGBlockMap_h
+#define DFGBlockMap_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+template<typename T>
+class BlockMap {
+public:
+    BlockMap()
+    {
+    }
+    
+    BlockMap(Graph&);
+    
+    BlockIndex size() const
+    {
+        return m_vector.size();
+    }
+    
+    T& atIndex(BlockIndex blockIndex)
+    {
+        return m_vector[blockIndex];
+    }
+    
+    const T& atIndex(BlockIndex blockIndex) const
+    {
+        return m_vector[blockIndex];
+    }
+    
+    T& at(BlockIndex blockIndex)
+    {
+        return m_vector[blockIndex];
+    }
+    
+    const T& at(BlockIndex blockIndex) const
+    {
+        return m_vector[blockIndex];
+    }
+    
+    T& at(BasicBlock* block)
+    {
+        return m_vector[block->index];
+    }
+    
+    const T& at(BasicBlock* block) const
+    {
+        return m_vector[block->index];
+    }
+
+    T& operator[](BlockIndex blockIndex)
+    {
+        return m_vector[blockIndex];
+    }
+    
+    const T& operator[](BlockIndex blockIndex) const
+    {
+        return m_vector[blockIndex];
+    }
+    
+    T& operator[](BasicBlock* block)
+    {
+        return m_vector[block->index];
+    }
+    
+    const T& operator[](BasicBlock* block) const
+    {
+        return m_vector[block->index];
+    }
+
+private:
+    Vector<T> m_vector;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBlockMap_h
+
diff --git a/dfg/DFGBlockMapInlines.h b/dfg/DFGBlockMapInlines.h
new file mode 100644 (file)
index 0000000..e61626d
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGBlockMapInlines_h
+#define DFGBlockMapInlines_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMap.h"
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+template<typename T>
+BlockMap<T>::BlockMap(Graph& graph)
+{
+    m_vector.resize(graph.numBlocks());
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBlockMapInlines_h
diff --git a/dfg/DFGBlockSet.cpp b/dfg/DFGBlockSet.cpp
new file mode 100644 (file)
index 0000000..790e380
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGBlockSet.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void BlockSet::dump(PrintStream& out) const
+{
+    CommaPrinter comma(" ");
+    for (BlockIndex blockIndex = m_set.findBit(0, true); blockIndex < m_set.size(); blockIndex = m_set.findBit(blockIndex + 1, true))
+        out.print(comma, "#", blockIndex);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGBlockSet.h b/dfg/DFGBlockSet.h
new file mode 100644 (file)
index 0000000..b09afec
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGBlockSet_h
+#define DFGBlockSet_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class BlockSet {
+public:
+    BlockSet() { }
+    
+    // Return true if the block was added, false if it was already present.
+    bool add(BasicBlock* block)
+    {
+        return !m_set.set(block->index);
+    }
+    
+    bool contains(BasicBlock* block) const
+    {
+        if (!block)
+            return false;
+        return m_set.get(block->index);
+    }
+    
+    class iterator {
+    public:
+        iterator()
+            : m_graph(nullptr)
+            , m_set(nullptr)
+            , m_index(0)
+        {
+        }
+        
+        iterator& operator++()
+        {
+            m_index = m_set->m_set.findBit(m_index + 1, true);
+            return *this;
+        }
+        
+        BasicBlock* operator*() const;
+        
+        bool operator==(const iterator& other) const
+        {
+            return m_index == other.m_index;
+        }
+        
+        bool operator!=(const iterator& other) const
+        {
+            return !(*this == other);
+        }
+        
+    private:
+        friend class BlockSet;
+        
+        Graph* m_graph;
+        const BlockSet* m_set;
+        size_t m_index;
+    };
+    
+    class Iterable {
+    public:
+        Iterable(Graph& graph, const BlockSet& set)
+            : m_graph(graph)
+            , m_set(set)
+        {
+        }
+        
+        iterator begin() const
+        {
+            iterator result;
+            result.m_graph = &m_graph;
+            result.m_set = &m_set;
+            result.m_index = m_set.m_set.findBit(0, true);
+            return result;
+        }
+        
+        iterator end() const
+        {
+            iterator result;
+            result.m_graph = &m_graph;
+            result.m_set = &m_set;
+            result.m_index = m_set.m_set.size();
+            return result;
+        }
+        
+    private:
+        Graph& m_graph;
+        const BlockSet& m_set;
+    };
+    
+    Iterable iterable(Graph& graph) const
+    {
+        return Iterable(graph, *this);
+    }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    BitVector m_set;
+};
+
+class BlockAdder {
+public:
+    BlockAdder(BlockSet& set)
+        : m_set(set)
+    {
+    }
+    
+    bool operator()(BasicBlock* block) const
+    {
+        return m_set.add(block);
+    }
+private:
+    BlockSet& m_set;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBlockSet_h
+
diff --git a/dfg/DFGBlockSetInlines.h b/dfg/DFGBlockSetInlines.h
new file mode 100644 (file)
index 0000000..df96285
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGBlockSetInlines_h
+#define DFGBlockSetInlines_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockSet.h"
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+inline BasicBlock* BlockSet::iterator::operator*() const
+{
+    return m_graph->block(m_index);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBlockSetInlines_h
+
diff --git a/dfg/DFGBlockWorklist.cpp b/dfg/DFGBlockWorklist.cpp
new file mode 100644 (file)
index 0000000..1caf9ca
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGBlockWorklist.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+
+namespace JSC { namespace DFG {
+
+BlockWorklist::BlockWorklist()
+{
+}
+
+BlockWorklist::~BlockWorklist()
+{
+}
+
+bool BlockWorklist::push(BasicBlock* block)
+{
+    if (!m_seen.add(block))
+        return false;
+    
+    m_stack.append(block);
+    return true;
+}
+
+BasicBlock* BlockWorklist::pop()
+{
+    if (m_stack.isEmpty())
+        return nullptr;
+    
+    return m_stack.takeLast();
+}
+
+PostOrderBlockWorklist::PostOrderBlockWorklist()
+{
+}
+
+PostOrderBlockWorklist::~PostOrderBlockWorklist()
+{
+}
+
+bool PostOrderBlockWorklist::pushPre(BasicBlock* block)
+{
+    return m_worklist.push(block, PreOrder);
+}
+
+void PostOrderBlockWorklist::pushPost(BasicBlock* block)
+{
+    m_worklist.forcePush(block, PostOrder);
+}
+
+BlockWithOrder PostOrderBlockWorklist::pop()
+{
+    BlockWith<VisitOrder> result = m_worklist.pop();
+    return BlockWithOrder(result.block, result.data);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGBlockWorklist.h b/dfg/DFGBlockWorklist.h
new file mode 100644 (file)
index 0000000..5b39e1c
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGBlockWorklist_h
+#define DFGBlockWorklist_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+#include "DFGBlockSet.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+struct BasicBlock;
+
+class BlockWorklist {
+public:
+    BlockWorklist();
+    ~BlockWorklist();
+    
+    bool push(BasicBlock*); // Returns true if we didn't know about the block before.
+    
+    bool notEmpty() const { return !m_stack.isEmpty(); }
+    BasicBlock* pop();
+    
+private:
+    BlockSet m_seen;
+    Vector<BasicBlock*, 16> m_stack;
+};
+
+// When you say BlockWith<int> you should read it as "block with an int".
+template<typename T>
+struct BlockWith {
+    BlockWith()
+        : block(nullptr)
+    {
+    }
+    
+    BlockWith(BasicBlock* block, const T& data)
+        : block(block)
+        , data(data)
+    {
+    }
+    
+    explicit operator bool() const { return block; }
+
+    BasicBlock* block;
+    T data;
+};
+
+// Extended block worklist is useful for enqueueing some meta-data along with the block. It also
+// permits forcibly enqueueing things even if the block has already been seen. It's useful for
+// things like building a spanning tree, in which case T (the auxiliary payload) would be the
+// successor index.
+template<typename T>
+class ExtendedBlockWorklist {
+public:
+    ExtendedBlockWorklist() { }
+    
+    void forcePush(const BlockWith<T>& entry)
+    {
+        m_stack.append(entry);
+    }
+    
+    void forcePush(BasicBlock* block, const T& data)
+    {
+        forcePush(BlockWith<T>(block, data));
+    }
+    
+    bool push(const BlockWith<T>& entry)
+    {
+        if (!m_seen.add(entry.block))
+            return false;
+        
+        forcePush(entry);
+        return true;
+    }
+    
+    bool push(BasicBlock* block, const T& data)
+    {
+        return push(BlockWith<T>(block, data));
+    }
+    
+    bool notEmpty() const { return !m_stack.isEmpty(); }
+    
+    BlockWith<T> pop()
+    {
+        if (m_stack.isEmpty())
+            return BlockWith<T>();
+        
+        return m_stack.takeLast();
+    }
+
+private:
+    BlockSet m_seen;
+    Vector<BlockWith<T>> m_stack;
+};
+
+enum VisitOrder {
+    PreOrder,
+    PostOrder
+};
+
+struct BlockWithOrder {
+    BlockWithOrder()
+        : block(nullptr)
+        , order(PreOrder)
+    {
+    }
+    
+    BlockWithOrder(BasicBlock* block, VisitOrder order)
+        : block(block)
+        , order(order)
+    {
+    }
+    
+    explicit operator bool() const { return block; }
+
+    BasicBlock* block;
+    VisitOrder order;
+};
+
+// Block worklist suitable for post-order traversal.
+class PostOrderBlockWorklist {
+public:
+    PostOrderBlockWorklist();
+    ~PostOrderBlockWorklist();
+    
+    bool pushPre(BasicBlock*);
+    void pushPost(BasicBlock*);
+    
+    bool push(BasicBlock* block, VisitOrder order = PreOrder)
+    {
+        switch (order) {
+        case PreOrder:
+            return pushPre(block);
+        case PostOrder:
+            pushPost(block);
+            return true;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return false;
+    }
+    bool push(const BlockWithOrder& data)
+    {
+        return push(data.block, data.order);
+    }
+    
+    bool notEmpty() const { return m_worklist.notEmpty(); }
+    BlockWithOrder pop();
+
+private:
+    ExtendedBlockWorklist<VisitOrder> m_worklist;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBlockWorklist_h
+
index 811c89807da9d7e6654f881af8f14ed4290e13cb..dcdde27f85cf01687b36104f0930c1ac7978428c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,7 +50,7 @@ static inline const char* branchDirectionToString(BranchDirection branchDirectio
 {
     switch (branchDirection) {
     case InvalidBranchDirection:
-        return "Invalid";
+        return "InvalidBranchDirection";
     case TakeTrue:
         return "TakeTrue";
     case TakeFalse:
@@ -58,6 +58,9 @@ static inline const char* branchDirectionToString(BranchDirection branchDirectio
     case TakeBoth:
         return "TakeBoth";
     }
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return "InvalidBranchDirection";
 }
     
 static inline bool isKnownDirection(BranchDirection branchDirection)
@@ -81,6 +84,15 @@ static inline bool branchCondition(BranchDirection branchDirection)
 
 } } // namespace JSC::DFG
 
+namespace WTF {
+
+inline void printInternal(PrintStream& out, JSC::DFG::BranchDirection direction)
+{
+    out.print(JSC::DFG::branchDirectionToString(direction));
+}
+
+} // namespace WTF
+
 #endif // ENABLE(DFG_JIT)
 
 #endif // DFGBranchDirection_h
index 7067480b3f6ae669bd795eeb4b7a933cadda24b4..2e37e697cf8c691b69698cbd5bc760556c40fdff 100644 (file)
@@ -1,5 +1,5 @@
- /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+/*
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #if ENABLE(DFG_JIT)
 
 #include "ArrayConstructor.h"
+#include "BasicBlockLocation.h"
 #include "CallLinkStatus.h"
 #include "CodeBlock.h"
 #include "CodeBlockWithJITType.h"
 #include "DFGArrayMode.h"
 #include "DFGCapabilities.h"
+#include "DFGGraph.h"
 #include "DFGJITCode.h"
 #include "GetByIdStatus.h"
 #include "Heap.h"
-#include "JSActivation.h"
+#include "JSLexicalEnvironment.h"
 #include "JSCInlines.h"
 #include "PreciseJumpTargets.h"
 #include "PutByIdStatus.h"
@@ -50,6 +52,8 @@
 
 namespace JSC { namespace DFG {
 
+static const bool verbose = false;
+
 class ConstantBufferKey {
 public:
     ConstantBufferKey()
@@ -132,19 +136,18 @@ public:
         , m_graph(graph)
         , m_currentBlock(0)
         , m_currentIndex(0)
-        , m_constantUndefined(UINT_MAX)
-        , m_constantNull(UINT_MAX)
-        , m_constantNaN(UINT_MAX)
-        , m_constant1(UINT_MAX)
-        , m_constants(m_codeBlock->numberOfConstantRegisters())
+        , m_constantUndefined(graph.freeze(jsUndefined()))
+        , m_constantNull(graph.freeze(jsNull()))
+        , m_constantNaN(graph.freeze(jsNumber(PNaN)))
+        , m_constantOne(graph.freeze(jsNumber(1)))
         , m_numArguments(m_codeBlock->numParameters())
         , m_numLocals(m_codeBlock->m_numCalleeRegisters)
         , m_parameterSlots(0)
         , m_numPassedVarArgs(0)
         , m_inlineStackTop(0)
         , m_haveBuiltOperandMaps(false)
-        , m_emptyJSValueIndex(UINT_MAX)
         , m_currentInstruction(0)
+        , m_hasDebuggerEnabled(graph.hasDebuggerEnabled())
     {
         ASSERT(m_profiledBlock);
     }
@@ -168,24 +171,40 @@ private:
     }
 
     // Helper for min and max.
-    bool handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis);
+    template<typename ChecksFunctor>
+    bool handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks);
     
     // Handle calls. This resolves issues surrounding inlining and intrinsics.
+    void handleCall(
+        int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
+        Node* callTarget, int argCount, int registerOffset, CallLinkStatus,
+        SpeculatedType prediction);
+    void handleCall(
+        int result, NodeType op, InlineCallFrame::Kind, unsigned instructionSize,
+        Node* callTarget, int argCount, int registerOffset, CallLinkStatus);
     void handleCall(int result, NodeType op, CodeSpecializationKind, unsigned instructionSize, int callee, int argCount, int registerOffset);
     void handleCall(Instruction* pc, NodeType op, CodeSpecializationKind);
-    void emitFunctionChecks(const CallLinkStatus&, Node* callTarget, int registerOffset, CodeSpecializationKind);
-    void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
+    void handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind);
+    void emitFunctionChecks(CallVariant, Node* callTarget, VirtualRegister thisArgumnt);
+    void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis);
+    unsigned inliningCost(CallVariant, int argumentCountIncludingThis, CodeSpecializationKind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1.
     // Handle inlining. Return true if it succeeded, false if we need to plant a call.
-    bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind);
+    bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, VirtualRegister thisArgument, VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis, unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind, SpeculatedType prediction);
+    enum CallerLinkability { CallerDoesNormalLinking, CallerLinksManually };
+    template<typename ChecksFunctor>
+    bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks);
+    template<typename ChecksFunctor>
+    void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability, const ChecksFunctor& insertChecks);
+    void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
     // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
-    bool handleIntrinsic(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
-    bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType);
-    bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
+    template<typename ChecksFunctor>
+    bool handleIntrinsic(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
+    template<typename ChecksFunctor>
+    bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor& insertChecks);
+    template<typename ChecksFunctor>
+    bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind, const ChecksFunctor& insertChecks);
     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, Node* value);
-    Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset);
-    void handleGetByOffset(
-        int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
-        PropertyOffset);
+    Node* handleGetByOffset(SpeculatedType, Node* base, const StructureSet&, unsigned identifierNumber, PropertyOffset, NodeType op = GetByOffset);
     void handleGetById(
         int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
         const GetByIdStatus&);
@@ -194,35 +213,29 @@ private:
     void handlePutById(
         Node* base, unsigned identifierNumber, Node* value, const PutByIdStatus&,
         bool isDirect);
-    Node* emitPrototypeChecks(Structure*, IntendedStructureChain*);
+    void emitChecks(const ConstantStructureCheckVector&);
 
-    Node* getScope(bool skipTop, unsigned skipCount);
-    
-    // Prepare to parse a block.
     void prepareToParseBlock();
+    void clearCaches();
+
     // Parse a single basic block of bytecode instructions.
     bool parseBlock(unsigned limit);
     // Link block successors.
     void linkBlock(BasicBlock*, Vector<BasicBlock*>& possibleTargets);
     void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
     
-    VariableAccessData* newVariableAccessData(VirtualRegister operand, bool isCaptured)
+    VariableAccessData* newVariableAccessData(VirtualRegister operand)
     {
         ASSERT(!operand.isConstant());
         
-        m_graph.m_variableAccessData.append(VariableAccessData(operand, isCaptured));
+        m_graph.m_variableAccessData.append(VariableAccessData(operand));
         return &m_graph.m_variableAccessData.last();
     }
     
     // Get/Set the operands/result of a bytecode instruction.
     Node* getDirect(VirtualRegister operand)
     {
-        // Is this a constant?
-        if (operand.isConstant()) {
-            unsigned constant = operand.toConstantIndex();
-            ASSERT(constant < m_constants.size());
-            return getJSConstant(constant);
-        }
+        ASSERT(!operand.isConstant());
 
         // Is this an argument?
         if (operand.isArgument())
@@ -234,18 +247,50 @@ private:
 
     Node* get(VirtualRegister operand)
     {
+        if (operand.isConstant()) {
+            unsigned constantIndex = operand.toConstantIndex();
+            unsigned oldSize = m_constants.size();
+            if (constantIndex >= oldSize || !m_constants[constantIndex]) {
+                const CodeBlock& codeBlock = *m_inlineStackTop->m_codeBlock;
+                JSValue value = codeBlock.getConstant(operand.offset());
+                SourceCodeRepresentation sourceCodeRepresentation = codeBlock.constantSourceCodeRepresentation(operand.offset());
+                if (constantIndex >= oldSize) {
+                    m_constants.grow(constantIndex + 1);
+                    for (unsigned i = oldSize; i < m_constants.size(); ++i)
+                        m_constants[i] = nullptr;
+                }
+
+                Node* constantNode = nullptr;
+                if (sourceCodeRepresentation == SourceCodeRepresentation::Double)
+                    constantNode = addToGraph(DoubleConstant, OpInfo(m_graph.freezeStrong(jsDoubleNumber(value.asNumber()))));
+                else
+                    constantNode = addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(value)));
+                m_constants[constantIndex] = constantNode;
+            }
+            ASSERT(m_constants[constantIndex]);
+            return m_constants[constantIndex];
+        }
+        
         if (inlineCallFrame()) {
             if (!inlineCallFrame()->isClosureCall) {
                 JSFunction* callee = inlineCallFrame()->calleeConstant();
                 if (operand.offset() == JSStack::Callee)
-                    return cellConstant(callee);
-                if (operand.offset() == JSStack::ScopeChain)
-                    return cellConstant(callee->scope());
+                    return weakJSConstant(callee);
+            }
+        } else if (operand.offset() == JSStack::Callee) {
+            // We have to do some constant-folding here because this enables CreateThis folding. Note
+            // that we don't have such watchpoint-based folding for inlined uses of Callee, since in that
+            // case if the function is a singleton then we already know it.
+            if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())) {
+                InferredValue* singleton = executable->singletonFunction();
+                if (JSValue value = singleton->inferredValue()) {
+                    m_graph.watchpoints().addLazily(singleton);
+                    JSFunction* function = jsCast<JSFunction*>(value);
+                    return weakJSConstant(function);
+                }
             }
-        } else if (operand.offset() == JSStack::Callee)
             return addToGraph(GetCallee);
-        else if (operand.offset() == JSStack::ScopeChain)
-            return addToGraph(GetMyScope);
+        }
         
         return getDirect(m_inlineStackTop->remapOperand(operand));
     }
@@ -272,8 +317,8 @@ private:
     Node* setDirect(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
     {
         addToGraph(MovHint, OpInfo(operand.offset()), value);
-        
-        DelayedSetLocal delayed = DelayedSetLocal(operand, value);
+
+        DelayedSetLocal delayed(currentCodeOrigin(), operand, value);
         
         if (setMode == NormalSet) {
             m_setLocalQueue.append(delayed);
@@ -282,6 +327,13 @@ private:
         
         return delayed.execute(this, setMode);
     }
+    
+    void processSetLocalQueue()
+    {
+        for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
+            m_setLocalQueue[i].execute(this);
+        m_setLocalQueue.resize(0);
+    }
 
     Node* set(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
     {
@@ -304,25 +356,7 @@ private:
     {
         unsigned local = operand.toLocal();
 
-        if (local < m_localWatchpoints.size()) {
-            if (VariableWatchpointSet* set = m_localWatchpoints[local]) {
-                if (JSValue value = set->inferredValue()) {
-                    addToGraph(FunctionReentryWatchpoint, OpInfo(m_codeBlock->symbolTable()));
-                    addToGraph(VariableWatchpoint, OpInfo(set));
-                    // Note: this is very special from an OSR exit standpoint. We wouldn't be
-                    // able to do this for most locals, but it works here because we're dealing
-                    // with a flushed local. For most locals we would need to issue a GetLocal
-                    // here and ensure that we have uses in DFG IR wherever there would have
-                    // been uses in bytecode. Clearly this optimization does not do this. But
-                    // that's fine, because we don't need to track liveness for captured
-                    // locals, and this optimization only kicks in for captured locals.
-                    return inferredConstant(value);
-                }
-            }
-        }
-
         Node* node = m_currentBlock->variablesAtTail.local(local);
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
         
         // This has two goals: 1) link together variable access datas, and 2)
         // try to avoid creating redundant GetLocals. (1) is required for
@@ -334,45 +368,47 @@ private:
         
         if (node) {
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
             
-            if (!isCaptured) {
-                switch (node->op()) {
-                case GetLocal:
-                    return node;
-                case SetLocal:
-                    return node->child1().node();
-                default:
-                    break;
-                }
+            switch (node->op()) {
+            case GetLocal:
+                return node;
+            case SetLocal:
+                return node->child1().node();
+            default:
+                break;
             }
         } else
-            variable = newVariableAccessData(operand, isCaptured);
+            variable = newVariableAccessData(operand);
         
         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
         m_currentBlock->variablesAtTail.local(local) = node;
         return node;
     }
 
-    Node* setLocal(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
+    Node* setLocal(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
     {
+        CodeOrigin oldSemanticOrigin = m_currentSemanticOrigin;
+        m_currentSemanticOrigin = semanticOrigin;
+
         unsigned local = operand.toLocal();
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
         
         if (setMode != ImmediateNakedSet) {
             ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
-            if (isCaptured || argumentPosition)
+            if (argumentPosition)
                 flushDirect(operand, argumentPosition);
+            else if (m_hasDebuggerEnabled && operand == m_codeBlock->scopeRegister())
+                flush(operand);
         }
 
-        VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+        VariableAccessData* variableAccessData = newVariableAccessData(operand);
         variableAccessData->mergeStructureCheckHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+            m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
         variableAccessData->mergeCheckArrayHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
+            m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
         m_currentBlock->variablesAtTail.local(local) = node;
+
+        m_currentSemanticOrigin = oldSemanticOrigin;
         return node;
     }
 
@@ -383,13 +419,11 @@ private:
         ASSERT(argument < m_numArguments);
         
         Node* node = m_currentBlock->variablesAtTail.argument(argument);
-        bool isCaptured = m_codeBlock->isCaptured(operand);
 
         VariableAccessData* variable;
         
         if (node) {
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
             
             switch (node->op()) {
             case GetLocal:
@@ -400,20 +434,21 @@ private:
                 break;
             }
         } else
-            variable = newVariableAccessData(operand, isCaptured);
+            variable = newVariableAccessData(operand);
         
         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
         m_currentBlock->variablesAtTail.argument(argument) = node;
         return node;
     }
-    Node* setArgument(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
+    Node* setArgument(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
     {
+        CodeOrigin oldSemanticOrigin = m_currentSemanticOrigin;
+        m_currentSemanticOrigin = semanticOrigin;
+
         unsigned argument = operand.toArgument();
         ASSERT(argument < m_numArguments);
         
-        bool isCaptured = m_codeBlock->isCaptured(operand);
-
-        VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+        VariableAccessData* variableAccessData = newVariableAccessData(operand);
 
         // Always flush arguments, except for 'this'. If 'this' is created by us,
         // then make sure that it's never unboxed.
@@ -424,12 +459,13 @@ private:
             variableAccessData->mergeShouldNeverUnbox(true);
         
         variableAccessData->mergeStructureCheckHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-            || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+            m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
         variableAccessData->mergeCheckArrayHoistingFailed(
-            m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
+            m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadIndexingType));
         Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
         m_currentBlock->variablesAtTail.argument(argument) = node;
+
+        m_currentSemanticOrigin = oldSemanticOrigin;
         return node;
     }
     
@@ -466,18 +502,6 @@ private:
         return findArgumentPositionForLocal(operand);
     }
 
-    void addConstant(JSValue value)
-    {
-        unsigned constantIndex = m_codeBlock->addConstantLazily();
-        initializeLazyWriteBarrierForConstant(
-            m_graph.m_plan.writeBarriers,
-            m_codeBlock->constants()[constantIndex],
-            m_codeBlock,
-            constantIndex,
-            m_codeBlock->ownerExecutable(), 
-            value);
-    }
-    
     void flush(VirtualRegister operand)
     {
         flushDirect(m_inlineStackTop->remapOperand(operand));
@@ -490,19 +514,16 @@ private:
     
     void flushDirect(VirtualRegister operand, ArgumentPosition* argumentPosition)
     {
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
-        
         ASSERT(!operand.isConstant());
         
         Node* node = m_currentBlock->variablesAtTail.operand(operand);
         
         VariableAccessData* variable;
         
-        if (node) {
+        if (node)
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
-        } else
-            variable = newVariableAccessData(operand, isCaptured);
+        else
+            variable = newVariableAccessData(operand);
         
         node = addToGraph(Flush, OpInfo(variable));
         m_currentBlock->variablesAtTail.operand(operand) = node;
@@ -514,20 +535,18 @@ private:
     {
         int numArguments;
         if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame) {
+            ASSERT(!m_hasDebuggerEnabled);
             numArguments = inlineCallFrame->arguments.size();
-            if (inlineCallFrame->isClosureCall) {
+            if (inlineCallFrame->isClosureCall)
                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::Callee)));
-                flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::ScopeChain)));
-            }
+            if (inlineCallFrame->isVarargs())
+                flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::ArgumentCount)));
         } else
             numArguments = inlineStackEntry->m_codeBlock->numParameters();
         for (unsigned argument = numArguments; argument-- > 1;)
             flushDirect(inlineStackEntry->remapOperand(virtualRegisterForArgument(argument)));
-        for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
-            if (!inlineStackEntry->m_codeBlock->isCaptured(virtualRegisterForLocal(local)))
-                continue;
-            flushDirect(inlineStackEntry->remapOperand(virtualRegisterForLocal(local)));
-        }
+        if (m_hasDebuggerEnabled)
+            flush(m_codeBlock->scopeRegister());
     }
 
     void flushForTerminal()
@@ -554,32 +573,15 @@ private:
         flushForTerminal();
     }
 
-    // NOTE: Only use this to construct constants that arise from non-speculative
-    // constant folding. I.e. creating constants using this if we had constant
-    // field inference would be a bad idea, since the bytecode parser's folding
-    // doesn't handle liveness preservation.
-    Node* getJSConstantForValue(JSValue constantValue)
+    // Assumes that the constant should be strongly marked.
+    Node* jsConstant(JSValue constantValue)
     {
-        unsigned constantIndex;
-        if (!m_codeBlock->findConstant(constantValue, constantIndex)) {
-            addConstant(constantValue);
-            m_constants.append(ConstantRecord());
-        }
-        
-        ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        
-        return getJSConstant(constantIndex);
+        return addToGraph(JSConstant, OpInfo(m_graph.freezeStrong(constantValue)));
     }
 
-    Node* getJSConstant(unsigned constant)
+    Node* weakJSConstant(JSValue constantValue)
     {
-        Node* node = m_constants[constant].asJSValue;
-        if (node)
-            return node;
-
-        Node* result = addToGraph(JSConstant, OpInfo(constant));
-        m_constants[constant].asJSValue = result;
-        return result;
+        return addToGraph(JSConstant, OpInfo(m_graph.freeze(constantValue)));
     }
 
     // Helper functions to get/set the this value.
@@ -593,149 +595,6 @@ private:
         set(m_inlineStackTop->m_codeBlock->thisRegister(), value);
     }
 
-    // Convenience methods for checking nodes for constants.
-    bool isJSConstant(Node* node)
-    {
-        return node->op() == JSConstant;
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return isJSConstant(node) && valueOfJSConstant(node).isInt32();
-    }
-    // Convenience methods for getting constant values.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        ASSERT(isJSConstant(node));
-        return m_codeBlock->getConstant(FirstConstantRegisterIndex + node->constantNumber());
-    }
-    int32_t valueOfInt32Constant(Node* node)
-    {
-        ASSERT(isInt32Constant(node));
-        return valueOfJSConstant(node).asInt32();
-    }
-    
-    // This method returns a JSConstant with the value 'undefined'.
-    Node* constantUndefined()
-    {
-        // Has m_constantUndefined been set up yet?
-        if (m_constantUndefined == UINT_MAX) {
-            // Search the constant pool for undefined, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
-            for (m_constantUndefined = 0; m_constantUndefined < numberOfConstants; ++m_constantUndefined) {
-                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined);
-                if (testMe.isUndefined())
-                    return getJSConstant(m_constantUndefined);
-            }
-
-            // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsUndefined());
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        }
-
-        // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantUndefined).isUndefined());
-        return getJSConstant(m_constantUndefined);
-    }
-
-    // This method returns a JSConstant with the value 'null'.
-    Node* constantNull()
-    {
-        // Has m_constantNull been set up yet?
-        if (m_constantNull == UINT_MAX) {
-            // Search the constant pool for null, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
-            for (m_constantNull = 0; m_constantNull < numberOfConstants; ++m_constantNull) {
-                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNull);
-                if (testMe.isNull())
-                    return getJSConstant(m_constantNull);
-            }
-
-            // Add null to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsNull());
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        }
-
-        // m_constantNull must refer to an entry in the CodeBlock's constant pool that has the value 'null'.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNull).isNull());
-        return getJSConstant(m_constantNull);
-    }
-
-    // This method returns a DoubleConstant with the value 1.
-    Node* one()
-    {
-        // Has m_constant1 been set up yet?
-        if (m_constant1 == UINT_MAX) {
-            // Search the constant pool for the value 1, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
-            for (m_constant1 = 0; m_constant1 < numberOfConstants; ++m_constant1) {
-                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1);
-                if (testMe.isInt32() && testMe.asInt32() == 1)
-                    return getJSConstant(m_constant1);
-            }
-
-            // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(jsNumber(1));
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        }
-
-        // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).asInt32() == 1);
-        return getJSConstant(m_constant1);
-    }
-    
-    // This method returns a DoubleConstant with the value NaN.
-    Node* constantNaN()
-    {
-        JSValue nan = jsNaN();
-        
-        // Has m_constantNaN been set up yet?
-        if (m_constantNaN == UINT_MAX) {
-            // Search the constant pool for the value NaN, if we find it, we can just reuse this!
-            unsigned numberOfConstants = m_codeBlock->numberOfConstantRegisters();
-            for (m_constantNaN = 0; m_constantNaN < numberOfConstants; ++m_constantNaN) {
-                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN);
-                if (JSValue::encode(testMe) == JSValue::encode(nan))
-                    return getJSConstant(m_constantNaN);
-            }
-
-            // Add the value nan to the CodeBlock's constants, and add a corresponding slot in m_constants.
-            ASSERT(m_constants.size() == numberOfConstants);
-            addConstant(nan);
-            m_constants.append(ConstantRecord());
-            ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
-        }
-
-        // m_constantNaN must refer to an entry in the CodeBlock's constant pool that has the value nan.
-        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).isDouble());
-        ASSERT(std::isnan(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
-        return getJSConstant(m_constantNaN);
-    }
-    
-    Node* cellConstant(JSCell* cell)
-    {
-        HashMap<JSCell*, Node*>::AddResult result = m_cellConstantNodes.add(cell, nullptr);
-        if (result.isNewEntry) {
-            ASSERT(!Heap::isZombified(cell));
-            result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell));
-        }
-        
-        return result.iterator->value;
-    }
-    
-    Node* inferredConstant(JSValue value)
-    {
-        if (value.isCell())
-            return cellConstant(value.asCell());
-        return getJSConstantForValue(value);
-    }
-    
     InlineCallFrame* inlineCallFrame()
     {
         return m_inlineStackTop->m_inlineCallFrame;
@@ -745,6 +604,15 @@ private:
     {
         return CodeOrigin(m_currentIndex, inlineCallFrame());
     }
+
+    NodeOrigin currentNodeOrigin()
+    {
+        // FIXME: We should set the forExit origin only on those nodes that can exit.
+        // https://bugs.webkit.org/show_bug.cgi?id=145204
+        if (m_currentSemanticOrigin.isSet())
+            return NodeOrigin(m_currentSemanticOrigin, currentCodeOrigin());
+        return NodeOrigin(currentCodeOrigin());
+    }
     
     BranchData* branchData(unsigned taken, unsigned notTaken)
     {
@@ -756,91 +624,94 @@ private:
         return data;
     }
     
+    Node* addToGraph(Node* node)
+    {
+        if (Options::verboseDFGByteCodeParsing())
+            dataLog("        appended ", node, " ", Graph::opName(node->op()), "\n");
+        m_currentBlock->append(node);
+        return node;
+    }
+    
     Node* addToGraph(NodeType op, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
     {
         Node* result = m_graph.addNode(
-            SpecNone, op, NodeOrigin(currentCodeOrigin()), Edge(child1), Edge(child2),
+            SpecNone, op, currentNodeOrigin(), Edge(child1), Edge(child2),
             Edge(child3));
-        ASSERT(op != Phi);
-        m_currentBlock->append(result);
-        return result;
+        return addToGraph(result);
     }
     Node* addToGraph(NodeType op, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
     {
         Node* result = m_graph.addNode(
-            SpecNone, op, NodeOrigin(currentCodeOrigin()), child1, child2, child3);
-        ASSERT(op != Phi);
-        m_currentBlock->append(result);
-        return result;
+            SpecNone, op, currentNodeOrigin(), child1, child2, child3);
+        return addToGraph(result);
     }
     Node* addToGraph(NodeType op, OpInfo info, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
     {
         Node* result = m_graph.addNode(
-            SpecNone, op, NodeOrigin(currentCodeOrigin()), info, Edge(child1), Edge(child2),
+            SpecNone, op, currentNodeOrigin(), info, Edge(child1), Edge(child2),
             Edge(child3));
-        ASSERT(op != Phi);
-        m_currentBlock->append(result);
-        return result;
+        return addToGraph(result);
     }
     Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
     {
         Node* result = m_graph.addNode(
-            SpecNone, op, NodeOrigin(currentCodeOrigin()), info1, info2,
+            SpecNone, op, currentNodeOrigin(), info1, info2,
             Edge(child1), Edge(child2), Edge(child3));
-        ASSERT(op != Phi);
-        m_currentBlock->append(result);
-        return result;
+        return addToGraph(result);
     }
     
     Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
     {
         Node* result = m_graph.addNode(
-            SpecNone, Node::VarArg, op, NodeOrigin(currentCodeOrigin()), info1, info2,
+            SpecNone, Node::VarArg, op, currentNodeOrigin(), info1, info2,
             m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs);
-        ASSERT(op != Phi);
-        m_currentBlock->append(result);
+        addToGraph(result);
         
         m_numPassedVarArgs = 0;
         
         return result;
     }
-
+    
     void addVarArgChild(Node* child)
     {
         m_graph.m_varArgChildren.append(Edge(child));
         m_numPassedVarArgs++;
     }
     
-    Node* addCall(int result, NodeType op, int callee, int argCount, int registerOffset)
+    Node* addCallWithoutSettingResult(
+        NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
+        SpeculatedType prediction)
     {
-        SpeculatedType prediction = getPrediction();
-        
-        addVarArgChild(get(VirtualRegister(callee)));
+        addVarArgChild(callee);
         size_t parameterSlots = JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + argCount;
         if (parameterSlots > m_parameterSlots)
             m_parameterSlots = parameterSlots;
 
-        int dummyThisArgument = op == Call ? 0 : 1;
-        for (int i = 0 + dummyThisArgument; i < argCount; ++i)
+        for (int i = 0; i < argCount; ++i)
             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
 
-        Node* call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
-        set(VirtualRegister(result), call);
+        return addToGraph(Node::VarArg, op, opInfo, OpInfo(prediction));
+    }
+    
+    Node* addCall(
+        int result, NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
+        SpeculatedType prediction)
+    {
+        Node* call = addCallWithoutSettingResult(
+            op, opInfo, callee, argCount, registerOffset, prediction);
+        VirtualRegister resultReg(result);
+        if (resultReg.isValid())
+            set(resultReg, call);
         return call;
     }
     
     Node* cellConstantWithStructureCheck(JSCell* object, Structure* structure)
     {
-        Node* objectNode = cellConstant(object);
+        Node* objectNode = weakJSConstant(object);
         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
         return objectNode;
     }
     
-    Node* cellConstantWithStructureCheck(JSCell* object)
-    {
-        return cellConstantWithStructureCheck(object, object->structure());
-    }
-
     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
     {
         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
@@ -874,7 +745,8 @@ private:
     {
         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
         profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
-        return ArrayMode::fromObserved(locker, profile, action, false);
+        bool makeSafe = profile->outOfBounds(locker);
+        return ArrayMode::fromObserved(locker, profile, action, makeSafe);
     }
     
     ArrayMode getArrayMode(ArrayProfile* profile)
@@ -882,21 +754,6 @@ private:
         return getArrayMode(profile, Array::Read);
     }
     
-    ArrayMode getArrayModeConsideringSlowPath(ArrayProfile* profile, Array::Action action)
-    {
-        ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
-        
-        profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
-        
-        bool makeSafe =
-            m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)
-            || profile->outOfBounds(locker);
-        
-        ArrayMode result = ArrayMode::fromObserved(locker, profile, action, makeSafe);
-        
-        return result;
-    }
-    
     Node* makeSafe(Node* node)
     {
         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
@@ -971,20 +828,14 @@ private:
         return node;
     }
     
-    bool structureChainIsStillValid(bool direct, Structure* previousStructure, StructureChain* chain)
+    void noticeArgumentsUse()
     {
-        if (direct)
-            return true;
-        
-        if (!previousStructure->storedPrototype().isNull() && previousStructure->storedPrototype().asCell()->structure() != chain->head()->get())
-            return false;
+        // All of the arguments in this function need to be formatted as JSValues because we will
+        // load from them in a random-access fashion and we don't want to have to switch on
+        // format.
         
-        for (WriteBarrier<Structure>* it = chain->head(); *it; ++it) {
-            if (!(*it)->storedPrototype().isNull() && (*it)->storedPrototype().asCell()->structure() != it[1].get())
-                return false;
-        }
-        
-        return true;
+        for (ArgumentPosition* argument : m_inlineStackTop->m_argumentPositions)
+            argument->mergeShouldNeverUnbox(true);
     }
     
     void buildOperandMapsIfNecessary();
@@ -998,37 +849,14 @@ private:
     BasicBlock* m_currentBlock;
     // The bytecode index of the current instruction being generated.
     unsigned m_currentIndex;
+    // The semantic origin of the current node if different from the current Index.
+    CodeOrigin m_currentSemanticOrigin;
 
-    // We use these values during code generation, and to avoid the need for
-    // special handling we make sure they are available as constants in the
-    // CodeBlock's constant pool. These variables are initialized to
-    // UINT_MAX, and lazily updated to hold an index into the CodeBlock's
-    // constant pool, as necessary.
-    unsigned m_constantUndefined;
-    unsigned m_constantNull;
-    unsigned m_constantNaN;
-    unsigned m_constant1;
-    HashMap<JSCell*, unsigned> m_cellConstants;
-    HashMap<JSCell*, Node*> m_cellConstantNodes;
-
-    // A constant in the constant pool may be represented by more than one
-    // node in the graph, depending on the context in which it is being used.
-    struct ConstantRecord {
-        ConstantRecord()
-            : asInt32(0)
-            , asNumeric(0)
-            , asJSValue(0)
-        {
-        }
-
-        Node* asInt32;
-        Node* asNumeric;
-        Node* asJSValue;
-    };
-
-    // Track the index of the node whose result is the current value for every
-    // register value in the bytecode - argument, local, and temporary.
-    Vector<ConstantRecord, 16> m_constants;
+    FrozenValue* m_constantUndefined;
+    FrozenValue* m_constantNull;
+    FrozenValue* m_constantNaN;
+    FrozenValue* m_constantOne;
+    Vector<Node*, 16> m_constants;
 
     // The number of arguments passed to the function.
     unsigned m_numArguments;
@@ -1045,8 +873,6 @@ private:
 
     HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
     
-    Vector<VariableWatchpointSet*, 16> m_localWatchpoints;
-    
     struct InlineStackEntry {
         ByteCodeParser* m_byteCodeParser;
         
@@ -1063,7 +889,6 @@ private:
         // (the machine code block, which is the transitive, though not necessarily
         // direct, caller).
         Vector<unsigned> m_identifierRemap;
-        Vector<unsigned> m_constantRemap;
         Vector<unsigned> m_constantBufferRemap;
         Vector<unsigned> m_switchRemap;
         
@@ -1075,8 +900,7 @@ private:
         Vector<UnlinkedBlock> m_unlinkedBlocks;
         
         // Potential block linking targets. Must be sorted by bytecodeBegin, and
-        // cannot have two blocks that have the same bytecodeBegin. For this very
-        // reason, this is not equivalent to 
+        // cannot have two blocks that have the same bytecodeBegin.
         Vector<BasicBlock*> m_blockLinkingTargets;
         
         // If the callsite's basic block was split into two, then this will be
@@ -1122,7 +946,7 @@ private:
             VirtualRegister returnValueVR,
             VirtualRegister inlineCallFrameStart,
             int argumentCountIncludingThis,
-            CodeSpecializationKind);
+            InlineCallFrame::Kind);
         
         ~InlineStackEntry()
         {
@@ -1134,11 +958,7 @@ private:
             if (!m_inlineCallFrame)
                 return operand;
             
-            if (operand.isConstant()) {
-                VirtualRegister result = VirtualRegister(m_constantRemap[operand.toConstantIndex()]);
-                ASSERT(result.isConstant());
-                return result;
-            }
+            ASSERT(!operand.isConstant());
 
             return VirtualRegister(operand.offset() + m_inlineCallFrame->stackOffset);
         }
@@ -1147,12 +967,14 @@ private:
     InlineStackEntry* m_inlineStackTop;
     
     struct DelayedSetLocal {
+        CodeOrigin m_origin;
         VirtualRegister m_operand;
         Node* m_value;
         
         DelayedSetLocal() { }
-        DelayedSetLocal(VirtualRegister operand, Node* value)
-            : m_operand(operand)
+        DelayedSetLocal(const CodeOrigin& origin, VirtualRegister operand, Node* value)
+            : m_origin(origin)
+            , m_operand(operand)
             , m_value(value)
         {
         }
@@ -1160,8 +982,8 @@ private:
         Node* execute(ByteCodeParser* parser, SetMode setMode = NormalSet)
         {
             if (m_operand.isArgument())
-                return parser->setArgument(m_operand, m_value, setMode);
-            return parser->setLocal(m_operand, m_value, setMode);
+                return parser->setArgument(m_origin, m_operand, m_value, setMode);
+            return parser->setLocal(m_origin, m_operand, m_value, setMode);
         }
     };
     
@@ -1172,17 +994,13 @@ private:
     bool m_haveBuiltOperandMaps;
     // Mapping between identifier names and numbers.
     BorrowedIdentifierMap m_identifierMap;
-    // Mapping between values and constant numbers.
-    JSValueMap m_jsValueMap;
-    // Index of the empty value, or UINT_MAX if there is no mapping. This is a horrible
-    // work-around for the fact that JSValueMap can't handle "empty" values.
-    unsigned m_emptyJSValueIndex;
     
     CodeBlock* m_dfgCodeBlock;
     CallLinkStatus::ContextMap m_callContextMap;
     StubInfoMap m_dfgStubInfos;
     
     Instruction* m_currentInstruction;
+    bool m_hasDebuggerEnabled;
 };
 
 #define NEXT_OPCODE(name) \
@@ -1205,148 +1023,206 @@ void ByteCodeParser::handleCall(
     int result, NodeType op, CodeSpecializationKind kind, unsigned instructionSize,
     int callee, int argumentCountIncludingThis, int registerOffset)
 {
-    ASSERT(registerOffset <= 0);
-    
     Node* callTarget = get(VirtualRegister(callee));
     
-    CallLinkStatus callLinkStatus;
+    CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
+        m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
+        m_inlineStackTop->m_callLinkInfos, m_callContextMap);
+    
+    handleCall(
+        result, op, InlineCallFrame::kindFor(kind), instructionSize, callTarget,
+        argumentCountIncludingThis, registerOffset, callLinkStatus);
+}
+    
+void ByteCodeParser::handleCall(
+    int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
+    Node* callTarget, int argumentCountIncludingThis, int registerOffset,
+    CallLinkStatus callLinkStatus)
+{
+    handleCall(
+        result, op, kind, instructionSize, callTarget, argumentCountIncludingThis,
+        registerOffset, callLinkStatus, getPrediction());
+}
 
-    if (m_graph.isConstant(callTarget)) {
-        callLinkStatus = CallLinkStatus(
-            m_graph.valueOfJSConstant(callTarget)).setIsProved(true);
-    } else {
-        callLinkStatus = CallLinkStatus::computeFor(
-            m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
-            m_inlineStackTop->m_callLinkInfos, m_callContextMap);
-    }
+void ByteCodeParser::handleCall(
+    int result, NodeType op, InlineCallFrame::Kind kind, unsigned instructionSize,
+    Node* callTarget, int argumentCountIncludingThis, int registerOffset,
+    CallLinkStatus callLinkStatus, SpeculatedType prediction)
+{
+    ASSERT(registerOffset <= 0);
+    
+    if (callTarget->isCellConstant())
+        callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
+    
+    if (Options::verboseDFGByteCodeParsing())
+        dataLog("    Handling call at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
     
     if (!callLinkStatus.canOptimize()) {
         // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
         // that we cannot optimize them.
         
-        addCall(result, op, callee, argumentCountIncludingThis, registerOffset);
+        addCall(result, op, OpInfo(), callTarget, argumentCountIncludingThis, registerOffset, prediction);
         return;
     }
     
     unsigned nextOffset = m_currentIndex + instructionSize;
-    SpeculatedType prediction = getPrediction();
-
-    if (InternalFunction* function = callLinkStatus.internalFunction()) {
-        if (handleConstantInternalFunction(result, function, registerOffset, argumentCountIncludingThis, prediction, kind)) {
-            // This phantoming has to be *after* the code for the intrinsic, to signify that
-            // the inputs must be kept alive whatever exits the intrinsic may do.
-            addToGraph(Phantom, callTarget);
-            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
-            return;
-        }
-        
-        // Can only handle this using the generic call handler.
-        addCall(result, op, callee, argumentCountIncludingThis, registerOffset);
+    
+    OpInfo callOpInfo;
+    
+    if (handleInlining(callTarget, result, callLinkStatus, registerOffset, virtualRegisterForArgument(0, registerOffset), VirtualRegister(), 0, argumentCountIncludingThis, nextOffset, op, kind, prediction)) {
+        if (m_graph.compilation())
+            m_graph.compilation()->noticeInlinedCall();
         return;
     }
-        
-    Intrinsic intrinsic = callLinkStatus.intrinsicFor(kind);
-    if (intrinsic != NoIntrinsic) {
-        emitFunctionChecks(callLinkStatus, callTarget, registerOffset, kind);
-            
-        if (handleIntrinsic(result, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
-            // This phantoming has to be *after* the code for the intrinsic, to signify that
-            // the inputs must be kept alive whatever exits the intrinsic may do.
-            addToGraph(Phantom, callTarget);
-            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
-            if (m_graph.compilation())
-                m_graph.compilation()->noticeInlinedCall();
-            return;
+    
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+    if (isFTL(m_graph.m_plan.mode) && Options::optimizeNativeCalls() && callLinkStatus.size() == 1 && !callLinkStatus.couldTakeSlowPath()) {
+        CallVariant callee = callLinkStatus[0];
+        JSFunction* function = callee.function();
+        CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
+        if (function && function->isHostFunction()) {
+            emitFunctionChecks(callee, callTarget, virtualRegisterForArgument(0, registerOffset));
+            callOpInfo = OpInfo(m_graph.freeze(function));
+
+            if (op == Call)
+                op = NativeCall;
+            else {
+                ASSERT(op == Construct);
+                op = NativeConstruct;
+            }
         }
-    } else if (handleInlining(callTarget, result, callLinkStatus, registerOffset, argumentCountIncludingThis, nextOffset, kind)) {
+    }
+#endif
+    
+    addCall(result, op, callOpInfo, callTarget, argumentCountIncludingThis, registerOffset, prediction);
+}
+
+void ByteCodeParser::handleVarargsCall(Instruction* pc, NodeType op, CodeSpecializationKind kind)
+{
+    ASSERT(OPCODE_LENGTH(op_call_varargs) == OPCODE_LENGTH(op_construct_varargs));
+    
+    int result = pc[1].u.operand;
+    int callee = pc[2].u.operand;
+    int thisReg = pc[3].u.operand;
+    int arguments = pc[4].u.operand;
+    int firstFreeReg = pc[5].u.operand;
+    int firstVarArgOffset = pc[6].u.operand;
+    
+    SpeculatedType prediction = getPrediction();
+    
+    Node* callTarget = get(VirtualRegister(callee));
+    
+    CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
+        m_inlineStackTop->m_profiledBlock, currentCodeOrigin(),
+        m_inlineStackTop->m_callLinkInfos, m_callContextMap);
+    if (callTarget->isCellConstant())
+        callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
+    
+    if (Options::verboseDFGByteCodeParsing())
+        dataLog("    Varargs call link status at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
+    
+    if (callLinkStatus.canOptimize()
+        && handleInlining(callTarget, result, callLinkStatus, firstFreeReg, VirtualRegister(thisReg), VirtualRegister(arguments), firstVarArgOffset, 0, m_currentIndex + OPCODE_LENGTH(op_call_varargs), op, InlineCallFrame::varargsKindFor(kind), prediction)) {
         if (m_graph.compilation())
             m_graph.compilation()->noticeInlinedCall();
         return;
     }
     
-    addCall(result, op, callee, argumentCountIncludingThis, registerOffset);
+    CallVarargsData* data = m_graph.m_callVarargsData.add();
+    data->firstVarArgOffset = firstVarArgOffset;
+    
+    Node* thisChild = get(VirtualRegister(thisReg));
+    
+    Node* call = addToGraph(op, OpInfo(data), OpInfo(prediction), callTarget, get(VirtualRegister(arguments)), thisChild);
+    VirtualRegister resultReg(result);
+    if (resultReg.isValid())
+        set(resultReg, call);
 }
 
-void ByteCodeParser::emitFunctionChecks(const CallLinkStatus& callLinkStatus, Node* callTarget, int registerOffset, CodeSpecializationKind kind)
+void ByteCodeParser::emitFunctionChecks(CallVariant callee, Node* callTarget, VirtualRegister thisArgumentReg)
 {
     Node* thisArgument;
-    if (kind == CodeForCall)
-        thisArgument = get(virtualRegisterForArgument(0, registerOffset));
+    if (thisArgumentReg.isValid())
+        thisArgument = get(thisArgumentReg);
     else
         thisArgument = 0;
 
-    if (callLinkStatus.isProved()) {
-        addToGraph(Phantom, callTarget, thisArgument);
-        return;
+    JSCell* calleeCell;
+    Node* callTargetForCheck;
+    if (callee.isClosureCall()) {
+        calleeCell = callee.executable();
+        callTargetForCheck = addToGraph(GetExecutable, callTarget);
+    } else {
+        calleeCell = callee.nonExecutableCallee();
+        callTargetForCheck = callTarget;
     }
     
-    ASSERT(callLinkStatus.canOptimize());
-    
-    if (JSFunction* function = callLinkStatus.function())
-        addToGraph(CheckFunction, OpInfo(function), callTarget, thisArgument);
-    else {
-        ASSERT(callLinkStatus.structure());
-        ASSERT(callLinkStatus.executable());
-        
-        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(callLinkStatus.structure())), callTarget);
-        addToGraph(CheckExecutable, OpInfo(callLinkStatus.executable()), callTarget, thisArgument);
-    }
+    ASSERT(calleeCell);
+    addToGraph(CheckCell, OpInfo(m_graph.freeze(calleeCell)), callTargetForCheck, thisArgument);
 }
 
-void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind kind)
+void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis)
 {
-    for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)
+    for (int i = 0; i < argumentCountIncludingThis; ++i)
         addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset)));
 }
 
-bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind kind)
+unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountIncludingThis, CodeSpecializationKind kind)
 {
-    static const bool verbose = false;
-    
     if (verbose)
-        dataLog("Considering inlining ", callLinkStatus, " into ", currentCodeOrigin(), "\n");
+        dataLog("Considering inlining ", callee, " into ", currentCodeOrigin(), "\n");
     
-    // First, the really simple checks: do we have an actual JS function?
-    if (!callLinkStatus.executable()) {
+    if (m_hasDebuggerEnabled) {
         if (verbose)
-            dataLog("    Failing because there is no executable.\n");
-        return false;
+            dataLog("    Failing because the debugger is in use.\n");
+        return UINT_MAX;
     }
-    if (callLinkStatus.executable()->isHostFunction()) {
+
+    FunctionExecutable* executable = callee.functionExecutable();
+    if (!executable) {
         if (verbose)
-            dataLog("    Failing because it's a host function.\n");
-        return false;
+            dataLog("    Failing because there is no function executable.\n");
+        return UINT_MAX;
     }
     
-    FunctionExecutable* executable = jsCast<FunctionExecutable*>(callLinkStatus.executable());
-    
     // Does the number of arguments we're passing match the arity of the target? We currently
     // inline only if the number of arguments passed is greater than or equal to the number
     // arguments expected.
     if (static_cast<int>(executable->parameterCount()) + 1 > argumentCountIncludingThis) {
         if (verbose)
             dataLog("    Failing because of arity mismatch.\n");
-        return false;
+        return UINT_MAX;
     }
     
     // Do we have a code block, and does the code block's size match the heuristics/requirements for
-    // being an inline candidate? We might not have a code block if code was thrown away or if we
-    // simply hadn't actually made this call yet. We could still theoretically attempt to inline it
-    // if we had a static proof of what was being called; this might happen for example if you call a
-    // global function, where watchpointing gives us static information. Overall, it's a rare case
-    // because we expect that any hot callees would have already been compiled.
+    // being an inline candidate? We might not have a code block (1) if code was thrown away,
+    // (2) if we simply hadn't actually made this call yet or (3) code is a builtin function and
+    // specialization kind is construct. In the former 2 cases, we could still theoretically attempt
+    // to inline it if we had a static proof of what was being called; this might happen for example
+    // if you call a global function, where watchpointing gives us static information. Overall,
+    // it's a rare case because we expect that any hot callees would have already been compiled.
     CodeBlock* codeBlock = executable->baselineCodeBlockFor(kind);
     if (!codeBlock) {
         if (verbose)
             dataLog("    Failing because no code block available.\n");
-        return false;
+        return UINT_MAX;
     }
     CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
-        codeBlock, kind, callLinkStatus.isClosureCall());
+        codeBlock, kind, callee.isClosureCall());
+    if (verbose) {
+        dataLog("    Kind: ", kind, "\n");
+        dataLog("    Is closure call: ", callee.isClosureCall(), "\n");
+        dataLog("    Capability level: ", capabilityLevel, "\n");
+        dataLog("    Might inline function: ", mightInlineFunctionFor(codeBlock, kind), "\n");
+        dataLog("    Might compile function: ", mightCompileFunctionFor(codeBlock, kind), "\n");
+        dataLog("    Is supported for inlining: ", isSupportedForInlining(codeBlock), "\n");
+        dataLog("    Needs activation: ", codeBlock->ownerExecutable()->needsActivation(), "\n");
+        dataLog("    Is inlining candidate: ", codeBlock->ownerExecutable()->isInliningCandidate(), "\n");
+    }
     if (!canInline(capabilityLevel)) {
         if (verbose)
             dataLog("    Failing because the function is not inlineable.\n");
-        return false;
+        return UINT_MAX;
     }
     
     // Check if the caller is already too large. We do this check here because that's just
@@ -1356,13 +1232,18 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
         codeBlock->m_shouldAlwaysBeInlined = false;
         if (verbose)
             dataLog("    Failing because the caller is too large.\n");
-        return false;
+        return UINT_MAX;
     }
     
     // FIXME: this should be better at predicting how much bloat we will introduce by inlining
     // this function.
     // https://bugs.webkit.org/show_bug.cgi?id=127627
     
+    // FIXME: We currently inline functions that have run in LLInt but not in Baseline. These
+    // functions have very low fidelity profiling, and presumably they weren't very hot if they
+    // haven't gotten to Baseline yet. Consider not inlining these functions.
+    // https://bugs.webkit.org/show_bug.cgi?id=145503
+    
     // Have we exceeded inline stack depth, or are we trying to inline a recursive call to
     // too many levels? If either of these are detected, then don't inline. We adjust our
     // heuristics if we are dealing with a function that cannot otherwise be compiled.
@@ -1375,7 +1256,7 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
         if (depth >= Options::maximumInliningDepth()) {
             if (verbose)
                 dataLog("    Failing because depth exceeded.\n");
-            return false;
+            return UINT_MAX;
         }
         
         if (entry->executable() == executable) {
@@ -1383,19 +1264,28 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
             if (recursion >= Options::maximumInliningRecursion()) {
                 if (verbose)
                     dataLog("    Failing because recursion detected.\n");
-                return false;
+                return UINT_MAX;
             }
         }
     }
     
     if (verbose)
-        dataLog("    Committing to inlining.\n");
+        dataLog("    Inlining should be possible.\n");
     
-    // Now we know without a doubt that we are committed to inlining. So begin the process
-    // by checking the callee (if necessary) and making sure that arguments and the callee
-    // are flushed.
-    emitFunctionChecks(callLinkStatus, callTargetNode, registerOffset, kind);
+    // It might be possible to inline.
+    return codeBlock->instructionCount();
+}
+
+template<typename ChecksFunctor>
+void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability, const ChecksFunctor& insertChecks)
+{
+    CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
+    
+    ASSERT(inliningCost(callee, argumentCountIncludingThis, specializationKind) != UINT_MAX);
     
+    CodeBlock* codeBlock = callee.functionExecutable()->baselineCodeBlockFor(specializationKind);
+    insertChecks(codeBlock);
+
     // FIXME: Don't flush constants!
     
     int inlineCallFrameStart = m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset() + JSStack::CallFrameHeaderSize;
@@ -1406,9 +1296,12 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
     
     size_t argumentPositionStart = m_graph.m_argumentPositions.size();
 
+    VirtualRegister resultReg(resultOperand);
+    if (resultReg.isValid())
+        resultReg = m_inlineStackTop->remapOperand(resultReg);
+    
     InlineStackEntry inlineStackEntry(
-        this, codeBlock, codeBlock, m_graph.lastBlock(), callLinkStatus.function(),
-        m_inlineStackTop->remapOperand(VirtualRegister(resultOperand)),
+        this, codeBlock, codeBlock, m_graph.lastBlock(), callee.function(), resultReg,
         (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
     
     // This is where the actual inlining really happens.
@@ -1422,15 +1315,12 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
     
     RELEASE_ASSERT(
         m_inlineStackTop->m_inlineCallFrame->isClosureCall
-        == callLinkStatus.isClosureCall());
-    if (callLinkStatus.isClosureCall()) {
+        == callee.isClosureCall());
+    if (callee.isClosureCall()) {
         VariableAccessData* calleeVariable =
             set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
-        VariableAccessData* scopeVariable =
-            set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateNakedSet)->variableAccessData();
         
         calleeVariable->mergeShouldNeverUnbox(true);
-        scopeVariable->mergeShouldNeverUnbox(true);
         
         inlineVariableData.calleeVariable = calleeVariable;
     }
@@ -1438,6 +1328,7 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
     m_graph.m_inlineVariableData.append(inlineVariableData);
     
     parseCodeBlock();
+    clearCaches(); // Reset our state now that we're back to the outer code.
     
     m_currentIndex = oldIndex;
     
@@ -1450,20 +1341,8 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
         else
             ASSERT(inlineStackEntry.m_callsiteBlockHead->isLinked);
         
-        // It's possible that the callsite block head is not owned by the caller.
-        if (!inlineStackEntry.m_caller->m_unlinkedBlocks.isEmpty()) {
-            // It's definitely owned by the caller, because the caller created new blocks.
-            // Assert that this all adds up.
-            ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_block == inlineStackEntry.m_callsiteBlockHead);
-            ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking);
-            inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking = false;
-        } else {
-            // It's definitely not owned by the caller. Tell the caller that he does not
-            // need to link his callsite block head, because we did it for him.
-            ASSERT(inlineStackEntry.m_caller->m_callsiteBlockHeadNeedsLinking);
-            ASSERT(inlineStackEntry.m_caller->m_callsiteBlockHead == inlineStackEntry.m_callsiteBlockHead);
-            inlineStackEntry.m_caller->m_callsiteBlockHeadNeedsLinking = false;
-        }
+        if (callerLinkability == CallerDoesNormalLinking)
+            cancelLinkingForBlock(inlineStackEntry.m_caller, inlineStackEntry.m_callsiteBlockHead);
         
         linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
     } else
@@ -1473,7 +1352,10 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
     // If there was a return, but no early returns, then we're done. We allow parsing of
     // the caller to continue in whatever basic block we're in right now.
     if (!inlineStackEntry.m_didEarlyReturn && inlineStackEntry.m_didReturn) {
-        ASSERT(lastBlock->isEmpty() || !lastBlock->last()->isTerminal());
+        if (Options::verboseDFGByteCodeParsing())
+            dataLog("    Allowing parsing to continue in last inlined block.\n");
+        
+        ASSERT(lastBlock->isEmpty() || !lastBlock->terminal());
         
         // If we created new blocks then the last block needs linking, but in the
         // caller. It doesn't need to be linked to, but it needs outgoing links.
@@ -1481,17 +1363,25 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
             // For debugging purposes, set the bytecodeBegin. Note that this doesn't matter
             // for release builds because this block will never serve as a potential target
             // in the linker's binary search.
+            if (Options::verboseDFGByteCodeParsing())
+                dataLog("        Repurposing last block from ", lastBlock->bytecodeBegin, " to ", m_currentIndex, "\n");
             lastBlock->bytecodeBegin = m_currentIndex;
-            m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
+            if (callerLinkability == CallerDoesNormalLinking) {
+                if (verbose)
+                    dataLog("Adding unlinked block ", RawPointer(m_graph.lastBlock()), " (one return)\n");
+                m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
+            }
         }
         
         m_currentBlock = m_graph.lastBlock();
-        return true;
+        return;
     }
     
+    if (Options::verboseDFGByteCodeParsing())
+        dataLog("    Creating new block after inlining.\n");
+
     // If we get to this point then all blocks must end in some sort of terminals.
-    ASSERT(lastBlock->last()->isTerminal());
-    
+    ASSERT(lastBlock->terminal());
 
     // Need to create a new basic block for the continuation at the caller.
     RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, PNaN));
@@ -1502,36 +1392,441 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
             continue;
         BasicBlock* blockToLink = inlineStackEntry.m_unlinkedBlocks[i].m_block;
         ASSERT(!blockToLink->isLinked);
-        Node* node = blockToLink->last();
+        Node* node = blockToLink->terminal();
         ASSERT(node->op() == Jump);
         ASSERT(!node->targetBlock());
         node->targetBlock() = block.get();
         inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
-#if !ASSERT_DISABLED
-        blockToLink->isLinked = true;
-#endif
+        if (verbose)
+            dataLog("Marking ", RawPointer(blockToLink), " as linked (jumps to return)\n");
+        blockToLink->didLink();
     }
     
     m_currentBlock = block.get();
     ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_caller->m_blockLinkingTargets.last()->bytecodeBegin < nextOffset);
-    m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
-    m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
+    if (verbose)
+        dataLog("Adding unlinked block ", RawPointer(block.get()), " (many returns)\n");
+    if (callerLinkability == CallerDoesNormalLinking) {
+        m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
+        m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
+    }
     m_graph.appendBlock(block);
     prepareToParseBlock();
+}
+
+void ByteCodeParser::cancelLinkingForBlock(InlineStackEntry* inlineStackEntry, BasicBlock* block)
+{
+    // It's possible that the callsite block head is not owned by the caller.
+    if (!inlineStackEntry->m_unlinkedBlocks.isEmpty()) {
+        // It's definitely owned by the caller, because the caller created new blocks.
+        // Assert that this all adds up.
+        ASSERT_UNUSED(block, inlineStackEntry->m_unlinkedBlocks.last().m_block == block);
+        ASSERT(inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking);
+        inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking = false;
+    } else {
+        // It's definitely not owned by the caller. Tell the caller that he does not
+        // need to link his callsite block head, because we did it for him.
+        ASSERT(inlineStackEntry->m_callsiteBlockHeadNeedsLinking);
+        ASSERT_UNUSED(block, inlineStackEntry->m_callsiteBlockHead == block);
+        inlineStackEntry->m_callsiteBlockHeadNeedsLinking = false;
+    }
+}
+
+template<typename ChecksFunctor>
+bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability, SpeculatedType prediction, unsigned& inliningBalance, const ChecksFunctor& insertChecks)
+{
+    CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
+    
+    if (!inliningBalance)
+        return false;
+    
+    bool didInsertChecks = false;
+    auto insertChecksWithAccounting = [&] () {
+        insertChecks(nullptr);
+        didInsertChecks = true;
+    };
+    
+    if (verbose)
+        dataLog("    Considering callee ", callee, "\n");
+    
+    // Intrinsics and internal functions can only be inlined if we're not doing varargs. This is because
+    // we currently don't have any way of getting profiling information for arguments to non-JS varargs
+    // calls. The prediction propagator won't be of any help because LoadVarargs obscures the data flow,
+    // and there are no callsite value profiles and native function won't have callee value profiles for
+    // those arguments. Even worse, if the intrinsic decides to exit, it won't really have anywhere to
+    // exit to: LoadVarargs is effectful and it's part of the op_call_varargs, so we can't exit without
+    // calling LoadVarargs twice.
+    if (!InlineCallFrame::isVarargs(kind)) {
+        if (InternalFunction* function = callee.internalFunction()) {
+            if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
+                RELEASE_ASSERT(didInsertChecks);
+                addToGraph(Phantom, callTargetNode);
+                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+                inliningBalance--;
+                return true;
+            }
+            RELEASE_ASSERT(!didInsertChecks);
+            return false;
+        }
+    
+        Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
+        if (intrinsic != NoIntrinsic) {
+            if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
+                RELEASE_ASSERT(didInsertChecks);
+                addToGraph(Phantom, callTargetNode);
+                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+                inliningBalance--;
+                return true;
+            }
+            RELEASE_ASSERT(!didInsertChecks);
+            return false;
+        }
+    }
     
-    // At this point we return and continue to generate code for the caller, but
-    // in the new basic block.
+    unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, specializationKind);
+    if (myInliningCost > inliningBalance)
+        return false;
+
+    Instruction* savedCurrentInstruction = m_currentInstruction;
+    inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, callerLinkability, insertChecks);
+    inliningBalance -= myInliningCost;
+    m_currentInstruction = savedCurrentInstruction;
     return true;
 }
 
-bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis)
+bool ByteCodeParser::handleInlining(
+    Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus,
+    int registerOffsetOrFirstFreeReg, VirtualRegister thisArgument,
+    VirtualRegister argumentsArgument, unsigned argumentsOffset, int argumentCountIncludingThis,
+    unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind kind, SpeculatedType prediction)
+{
+    if (verbose) {
+        dataLog("Handling inlining...\n");
+        dataLog("Stack: ", currentCodeOrigin(), "\n");
+    }
+    CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
+    
+    if (!callLinkStatus.size()) {
+        if (verbose)
+            dataLog("Bailing inlining.\n");
+        return false;
+    }
+    
+    if (InlineCallFrame::isVarargs(kind)
+        && callLinkStatus.maxNumArguments() > Options::maximumVarargsForInlining()) {
+        if (verbose)
+            dataLog("Bailing inlining because of varargs.\n");
+        return false;
+    }
+        
+    unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateInstructionCount();
+    if (specializationKind == CodeForConstruct)
+        inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateInstructionCount());
+    if (callLinkStatus.isClosureCall())
+        inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateInstructionCount());
+    
+    // First check if we can avoid creating control flow. Our inliner does some CFG
+    // simplification on the fly and this helps reduce compile times, but we can only leverage
+    // this in cases where we don't need control flow diamonds to check the callee.
+    if (!callLinkStatus.couldTakeSlowPath() && callLinkStatus.size() == 1) {
+        int registerOffset;
+        
+        // Only used for varargs calls.
+        unsigned mandatoryMinimum = 0;
+        unsigned maxNumArguments = 0;
+
+        if (InlineCallFrame::isVarargs(kind)) {
+            if (FunctionExecutable* functionExecutable = callLinkStatus[0].functionExecutable())
+                mandatoryMinimum = functionExecutable->parameterCount();
+            else
+                mandatoryMinimum = 0;
+            
+            // includes "this"
+            maxNumArguments = std::max(
+                callLinkStatus.maxNumArguments(),
+                mandatoryMinimum + 1);
+            
+            // We sort of pretend that this *is* the number of arguments that were passed.
+            argumentCountIncludingThis = maxNumArguments;
+            
+            registerOffset = registerOffsetOrFirstFreeReg + 1;
+            registerOffset -= maxNumArguments; // includes "this"
+            registerOffset -= JSStack::CallFrameHeaderSize;
+            registerOffset = -WTF::roundUpToMultipleOf(
+                stackAlignmentRegisters(),
+                -registerOffset);
+        } else
+            registerOffset = registerOffsetOrFirstFreeReg;
+        
+        bool result = attemptToInlineCall(
+            callTargetNode, resultOperand, callLinkStatus[0], registerOffset,
+            argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction,
+            inliningBalance, [&] (CodeBlock* codeBlock) {
+                emitFunctionChecks(callLinkStatus[0], callTargetNode, thisArgument);
+
+                // If we have a varargs call, we want to extract the arguments right now.
+                if (InlineCallFrame::isVarargs(kind)) {
+                    int remappedRegisterOffset =
+                        m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset();
+                    
+                    ensureLocals(VirtualRegister(remappedRegisterOffset).toLocal());
+                    
+                    int argumentStart = registerOffset + JSStack::CallFrameHeaderSize;
+                    int remappedArgumentStart =
+                        m_inlineStackTop->remapOperand(VirtualRegister(argumentStart)).offset();
+
+                    LoadVarargsData* data = m_graph.m_loadVarargsData.add();
+                    data->start = VirtualRegister(remappedArgumentStart + 1);
+                    data->count = VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount);
+                    data->offset = argumentsOffset;
+                    data->limit = maxNumArguments;
+                    data->mandatoryMinimum = mandatoryMinimum;
+            
+                    addToGraph(LoadVarargs, OpInfo(data), get(argumentsArgument));
+
+                    // LoadVarargs may OSR exit. Hence, we need to keep alive callTargetNode, thisArgument
+                    // and argumentsArgument for the baseline JIT. However, we only need a Phantom for
+                    // callTargetNode because the other 2 are still in use and alive at this point.
+                    addToGraph(Phantom, callTargetNode);
+
+                    // In DFG IR before SSA, we cannot insert control flow between after the
+                    // LoadVarargs and the last SetArgument. This isn't a problem once we get to DFG
+                    // SSA. Fortunately, we also have other reasons for not inserting control flow
+                    // before SSA.
+            
+                    VariableAccessData* countVariable = newVariableAccessData(
+                        VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount));
+                    // This is pretty lame, but it will force the count to be flushed as an int. This doesn't
+                    // matter very much, since our use of a SetArgument and Flushes for this local slot is
+                    // mostly just a formality.
+                    countVariable->predict(SpecInt32);
+                    countVariable->mergeIsProfitableToUnbox(true);
+                    Node* setArgumentCount = addToGraph(SetArgument, OpInfo(countVariable));
+                    m_currentBlock->variablesAtTail.setOperand(countVariable->local(), setArgumentCount);
+
+                    set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
+                    for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
+                        VariableAccessData* variable = newVariableAccessData(
+                            VirtualRegister(remappedArgumentStart + argument));
+                        variable->mergeShouldNeverUnbox(true); // We currently have nowhere to put the type check on the LoadVarargs. LoadVarargs is effectful, so after it finishes, we cannot exit.
+                        
+                        // For a while it had been my intention to do things like this inside the
+                        // prediction injection phase. But in this case it's really best to do it here,
+                        // because it's here that we have access to the variable access datas for the
+                        // inlining we're about to do.
+                        //
+                        // Something else that's interesting here is that we'd really love to get
+                        // predictions from the arguments loaded at the callsite, rather than the
+                        // arguments received inside the callee. But that probably won't matter for most
+                        // calls.
+                        if (codeBlock && argument < static_cast<unsigned>(codeBlock->numParameters())) {
+                            ConcurrentJITLocker locker(codeBlock->m_lock);
+                            if (ValueProfile* profile = codeBlock->valueProfileForArgument(argument))
+                                variable->predict(profile->computeUpdatedPrediction(locker));
+                        }
+                        
+                        Node* setArgument = addToGraph(SetArgument, OpInfo(variable));
+                        m_currentBlock->variablesAtTail.setOperand(variable->local(), setArgument);
+                    }
+                }
+            });
+        if (verbose) {
+            dataLog("Done inlining (simple).\n");
+            dataLog("Stack: ", currentCodeOrigin(), "\n");
+            dataLog("Result: ", result, "\n");
+        }
+        return result;
+    }
+    
+    // We need to create some kind of switch over callee. For now we only do this if we believe that
+    // we're in the top tier. We have two reasons for this: first, it provides us an opportunity to
+    // do more detailed polyvariant/polymorphic profiling; and second, it reduces compile times in
+    // the DFG. And by polyvariant profiling we mean polyvariant profiling of *this* call. Note that
+    // we could improve that aspect of this by doing polymorphic inlining but having the profiling
+    // also.
+    if (!isFTL(m_graph.m_plan.mode) || !Options::enablePolymorphicCallInlining()
+        || InlineCallFrame::isVarargs(kind)) {
+        if (verbose) {
+            dataLog("Bailing inlining (hard).\n");
+            dataLog("Stack: ", currentCodeOrigin(), "\n");
+        }
+        return false;
+    }
+    
+    unsigned oldOffset = m_currentIndex;
+    
+    bool allAreClosureCalls = true;
+    bool allAreDirectCalls = true;
+    for (unsigned i = callLinkStatus.size(); i--;) {
+        if (callLinkStatus[i].isClosureCall())
+            allAreDirectCalls = false;
+        else
+            allAreClosureCalls = false;
+    }
+    
+    Node* thingToSwitchOn;
+    if (allAreDirectCalls)
+        thingToSwitchOn = callTargetNode;
+    else if (allAreClosureCalls)
+        thingToSwitchOn = addToGraph(GetExecutable, callTargetNode);
+    else {
+        // FIXME: We should be able to handle this case, but it's tricky and we don't know of cases
+        // where it would be beneficial. It might be best to handle these cases as if all calls were
+        // closure calls.
+        // https://bugs.webkit.org/show_bug.cgi?id=136020
+        if (verbose) {
+            dataLog("Bailing inlining (mix).\n");
+            dataLog("Stack: ", currentCodeOrigin(), "\n");
+        }
+        return false;
+    }
+    
+    if (verbose) {
+        dataLog("Doing hard inlining...\n");
+        dataLog("Stack: ", currentCodeOrigin(), "\n");
+    }
+    
+    int registerOffset = registerOffsetOrFirstFreeReg;
+    
+    // This makes me wish that we were in SSA all the time. We need to pick a variable into which to
+    // store the callee so that it will be accessible to all of the blocks we're about to create. We
+    // get away with doing an immediate-set here because we wouldn't have performed any side effects
+    // yet.
+    if (verbose)
+        dataLog("Register offset: ", registerOffset);
+    VirtualRegister calleeReg(registerOffset + JSStack::Callee);
+    calleeReg = m_inlineStackTop->remapOperand(calleeReg);
+    if (verbose)
+        dataLog("Callee is going to be ", calleeReg, "\n");
+    setDirect(calleeReg, callTargetNode, ImmediateSetWithFlush);
+    
+    SwitchData& data = *m_graph.m_switchData.add();
+    data.kind = SwitchCell;
+    addToGraph(Switch, OpInfo(&data), thingToSwitchOn);
+    
+    BasicBlock* originBlock = m_currentBlock;
+    if (verbose)
+        dataLog("Marking ", RawPointer(originBlock), " as linked (origin of poly inline)\n");
+    originBlock->didLink();
+    cancelLinkingForBlock(m_inlineStackTop, originBlock);
+    
+    // Each inlined callee will have a landing block that it returns at. They should all have jumps
+    // to the continuation block, which we create last.
+    Vector<BasicBlock*> landingBlocks;
+    
+    // We may force this true if we give up on inlining any of the edges.
+    bool couldTakeSlowPath = callLinkStatus.couldTakeSlowPath();
+    
+    if (verbose)
+        dataLog("About to loop over functions at ", currentCodeOrigin(), ".\n");
+    
+    for (unsigned i = 0; i < callLinkStatus.size(); ++i) {
+        m_currentIndex = oldOffset;
+        RefPtr<BasicBlock> block = adoptRef(new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
+        m_currentBlock = block.get();
+        m_graph.appendBlock(block);
+        prepareToParseBlock();
+        
+        Node* myCallTargetNode = getDirect(calleeReg);
+        
+        bool inliningResult = attemptToInlineCall(
+            myCallTargetNode, resultOperand, callLinkStatus[i], registerOffset,
+            argumentCountIncludingThis, nextOffset, kind, CallerLinksManually, prediction,
+            inliningBalance, [&] (CodeBlock*) { });
+        
+        if (!inliningResult) {
+            // That failed so we let the block die. Nothing interesting should have been added to
+            // the block. We also give up on inlining any of the (less frequent) callees.
+            ASSERT(m_currentBlock == block.get());
+            ASSERT(m_graph.m_blocks.last() == block);
+            m_graph.killBlockAndItsContents(block.get());
+            m_graph.m_blocks.removeLast();
+            
+            // The fact that inlining failed means we need a slow path.
+            couldTakeSlowPath = true;
+            break;
+        }
+        
+        JSCell* thingToCaseOn;
+        if (allAreDirectCalls)
+            thingToCaseOn = callLinkStatus[i].nonExecutableCallee();
+        else {
+            ASSERT(allAreClosureCalls);
+            thingToCaseOn = callLinkStatus[i].executable();
+        }
+        data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), block.get()));
+        m_currentIndex = nextOffset;
+        processSetLocalQueue(); // This only comes into play for intrinsics, since normal inlined code will leave an empty queue.
+        addToGraph(Jump);
+        if (verbose)
+            dataLog("Marking ", RawPointer(m_currentBlock), " as linked (tail of poly inlinee)\n");
+        m_currentBlock->didLink();
+        landingBlocks.append(m_currentBlock);
+
+        if (verbose)
+            dataLog("Finished inlining ", callLinkStatus[i], " at ", currentCodeOrigin(), ".\n");
+    }
+    
+    RefPtr<BasicBlock> slowPathBlock = adoptRef(
+        new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
+    m_currentIndex = oldOffset;
+    data.fallThrough = BranchTarget(slowPathBlock.get());
+    m_graph.appendBlock(slowPathBlock);
+    if (verbose)
+        dataLog("Marking ", RawPointer(slowPathBlock.get()), " as linked (slow path block)\n");
+    slowPathBlock->didLink();
+    prepareToParseBlock();
+    m_currentBlock = slowPathBlock.get();
+    Node* myCallTargetNode = getDirect(calleeReg);
+    if (couldTakeSlowPath) {
+        addCall(
+            resultOperand, callOp, OpInfo(), myCallTargetNode, argumentCountIncludingThis,
+            registerOffset, prediction);
+    } else {
+        addToGraph(CheckBadCell);
+        addToGraph(Phantom, myCallTargetNode);
+        emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+        
+        set(VirtualRegister(resultOperand), addToGraph(BottomValue));
+    }
+
+    m_currentIndex = nextOffset;
+    processSetLocalQueue();
+    addToGraph(Jump);
+    landingBlocks.append(m_currentBlock);
+    
+    RefPtr<BasicBlock> continuationBlock = adoptRef(
+        new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
+    m_graph.appendBlock(continuationBlock);
+    if (verbose)
+        dataLog("Adding unlinked block ", RawPointer(continuationBlock.get()), " (continuation)\n");
+    m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(continuationBlock.get()));
+    prepareToParseBlock();
+    m_currentBlock = continuationBlock.get();
+    
+    for (unsigned i = landingBlocks.size(); i--;)
+        landingBlocks[i]->terminal()->targetBlock() = continuationBlock.get();
+    
+    m_currentIndex = oldOffset;
+    
+    if (verbose) {
+        dataLog("Done inlining (hard).\n");
+        dataLog("Stack: ", currentCodeOrigin(), "\n");
+    }
+    return true;
+}
+
+template<typename ChecksFunctor>
+bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis, const ChecksFunctor& insertChecks)
 {
     if (argumentCountIncludingThis == 1) { // Math.min()
-        set(VirtualRegister(resultOperand), constantNaN());
+        insertChecks();
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
         return true;
     }
      
     if (argumentCountIncludingThis == 2) { // Math.min(x)
+        insertChecks();
         Node* result = get(VirtualRegister(virtualRegisterForArgument(1, registerOffset)));
         addToGraph(Phantom, Edge(result, NumberUse));
         set(VirtualRegister(resultOperand), result);
@@ -1539,6 +1834,7 @@ bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOf
     }
     
     if (argumentCountIncludingThis == 3) { // Math.min(x, y)
+        insertChecks();
         set(VirtualRegister(resultOperand), addToGraph(op, get(virtualRegisterForArgument(1, registerOffset)), get(virtualRegisterForArgument(2, registerOffset))));
         return true;
     }
@@ -1547,18 +1843,21 @@ bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOf
     return false;
 }
 
-bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction)
+template<typename ChecksFunctor>
+bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
 {
     switch (intrinsic) {
     case AbsIntrinsic: {
         if (argumentCountIncludingThis == 1) { // Math.abs()
-            set(VirtualRegister(resultOperand), constantNaN());
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
             return true;
         }
 
         if (!MacroAssembler::supportsFloatingPointAbs())
             return false;
 
+        insertChecks();
         Node* node = addToGraph(ArithAbs, get(virtualRegisterForArgument(1, registerOffset)));
         if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
             node->mergeFlags(NodeMayOverflowInDFG);
@@ -1567,40 +1866,61 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
     }
 
     case MinIntrinsic:
-        return handleMinMax(resultOperand, ArithMin, registerOffset, argumentCountIncludingThis);
+        return handleMinMax(resultOperand, ArithMin, registerOffset, argumentCountIncludingThis, insertChecks);
         
     case MaxIntrinsic:
-        return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis);
-        
+        return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
+
     case SqrtIntrinsic:
     case CosIntrinsic:
-    case SinIntrinsic: {
+    case SinIntrinsic:
+    case LogIntrinsic: {
         if (argumentCountIncludingThis == 1) {
-            set(VirtualRegister(resultOperand), constantNaN());
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
             return true;
         }
         
         switch (intrinsic) {
         case SqrtIntrinsic:
-            if (!MacroAssembler::supportsFloatingPointSqrt())
-                return false;
-            
+            insertChecks();
             set(VirtualRegister(resultOperand), addToGraph(ArithSqrt, get(virtualRegisterForArgument(1, registerOffset))));
             return true;
             
         case CosIntrinsic:
+            insertChecks();
             set(VirtualRegister(resultOperand), addToGraph(ArithCos, get(virtualRegisterForArgument(1, registerOffset))));
             return true;
             
         case SinIntrinsic:
+            insertChecks();
             set(VirtualRegister(resultOperand), addToGraph(ArithSin, get(virtualRegisterForArgument(1, registerOffset))));
             return true;
+
+        case LogIntrinsic:
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(ArithLog, get(virtualRegisterForArgument(1, registerOffset))));
+            return true;
             
         default:
             RELEASE_ASSERT_NOT_REACHED();
             return false;
         }
     }
+
+    case PowIntrinsic: {
+        if (argumentCountIncludingThis < 3) {
+            // Math.pow() and Math.pow(x) return NaN.
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
+            return true;
+        }
+        insertChecks();
+        VirtualRegister xOperand = virtualRegisterForArgument(1, registerOffset);
+        VirtualRegister yOperand = virtualRegisterForArgument(2, registerOffset);
+        set(VirtualRegister(resultOperand), addToGraph(ArithPow, get(xOperand), get(yOperand)));
+        return true;
+    }
         
     case ArrayPushIntrinsic: {
         if (argumentCountIncludingThis != 2)
@@ -1615,6 +1935,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         case Array::Double:
         case Array::Contiguous:
         case Array::ArrayStorage: {
+            insertChecks();
             Node* arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
             set(VirtualRegister(resultOperand), arrayPush);
             
@@ -1638,6 +1959,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         case Array::Double:
         case Array::Contiguous:
         case Array::ArrayStorage: {
+            insertChecks();
             Node* arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)));
             set(VirtualRegister(resultOperand), arrayPop);
             return true;
@@ -1652,6 +1974,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         if (argumentCountIncludingThis != 2)
             return false;
 
+        insertChecks();
         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
         Node* charCode = addToGraph(StringCharCodeAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
@@ -1664,6 +1987,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         if (argumentCountIncludingThis != 2)
             return false;
 
+        insertChecks();
         VirtualRegister thisOperand = virtualRegisterForArgument(0, registerOffset);
         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
         Node* charCode = addToGraph(StringCharAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), get(indexOperand));
@@ -1671,10 +1995,21 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         set(VirtualRegister(resultOperand), charCode);
         return true;
     }
+    case Clz32Intrinsic: {
+        insertChecks();
+        if (argumentCountIncludingThis == 1)
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_graph.freeze(jsNumber(32)))));
+        else {
+            Node* operand = get(virtualRegisterForArgument(1, registerOffset));
+            set(VirtualRegister(resultOperand), addToGraph(ArithClz32, operand));
+        }
+        return true;
+    }
     case FromCharCodeIntrinsic: {
         if (argumentCountIncludingThis != 2)
             return false;
 
+        insertChecks();
         VirtualRegister indexOperand = virtualRegisterForArgument(1, registerOffset);
         Node* charCode = addToGraph(StringFromCharCode, get(indexOperand));
 
@@ -1687,6 +2022,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         if (argumentCountIncludingThis != 2)
             return false;
         
+        insertChecks();
         Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
         set(VirtualRegister(resultOperand), regExpExec);
         
@@ -1697,15 +2033,31 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
         if (argumentCountIncludingThis != 2)
             return false;
         
+        insertChecks();
         Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
         set(VirtualRegister(resultOperand), regExpExec);
         
         return true;
     }
-
+    case RoundIntrinsic: {
+        if (argumentCountIncludingThis == 1) {
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
+            return true;
+        }
+        if (argumentCountIncludingThis == 2) {
+            insertChecks();
+            Node* operand = get(virtualRegisterForArgument(1, registerOffset));
+            Node* roundNode = addToGraph(ArithRound, OpInfo(0), OpInfo(prediction), operand);
+            set(VirtualRegister(resultOperand), roundNode);
+            return true;
+        }
+        return false;
+    }
     case IMulIntrinsic: {
         if (argumentCountIncludingThis != 3)
             return false;
+        insertChecks();
         VirtualRegister leftOperand = virtualRegisterForArgument(1, registerOffset);
         VirtualRegister rightOperand = virtualRegisterForArgument(2, registerOffset);
         Node* left = get(leftOperand);
@@ -1717,41 +2069,57 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
     case FRoundIntrinsic: {
         if (argumentCountIncludingThis != 2)
             return false;
+        insertChecks();
         VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
         set(VirtualRegister(resultOperand), addToGraph(ArithFRound, get(operand)));
         return true;
     }
         
     case DFGTrueIntrinsic: {
-        set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
+        insertChecks();
+        set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
         return true;
     }
         
     case OSRExitIntrinsic: {
+        insertChecks();
         addToGraph(ForceOSRExit);
-        set(VirtualRegister(resultOperand), constantUndefined());
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
         return true;
     }
         
     case IsFinalTierIntrinsic: {
+        insertChecks();
         set(VirtualRegister(resultOperand),
-            getJSConstantForValue(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
+            jsConstant(jsBoolean(Options::useFTLJIT() ? isFTL(m_graph.m_plan.mode) : true)));
         return true;
     }
         
     case SetInt32HeapPredictionIntrinsic: {
+        insertChecks();
         for (int i = 1; i < argumentCountIncludingThis; ++i) {
             Node* node = get(virtualRegisterForArgument(i, registerOffset));
             if (node->hasHeapPrediction())
                 node->setHeapPrediction(SpecInt32);
         }
-        set(VirtualRegister(resultOperand), constantUndefined());
+        set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantUndefined)));
+        return true;
+    }
+        
+    case CheckInt32Intrinsic: {
+        insertChecks();
+        for (int i = 1; i < argumentCountIncludingThis; ++i) {
+            Node* node = get(virtualRegisterForArgument(i, registerOffset));
+            addToGraph(Phantom, Edge(node, Int32Use));
+        }
+        set(VirtualRegister(resultOperand), jsConstant(jsBoolean(true)));
         return true;
     }
         
     case FiatInt52Intrinsic: {
         if (argumentCountIncludingThis != 2)
             return false;
+        insertChecks();
         VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
         if (enableInt52())
             set(VirtualRegister(resultOperand), addToGraph(FiatInt52, get(operand)));
@@ -1765,9 +2133,10 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
     }
 }
 
+template<typename ChecksFunctor>
 bool ByteCodeParser::handleTypedArrayConstructor(
     int resultOperand, InternalFunction* function, int registerOffset,
-    int argumentCountIncludingThis, TypedArrayType type)
+    int argumentCountIncludingThis, TypedArrayType type, const ChecksFunctor& insertChecks)
 {
     if (!isTypedView(type))
         return false;
@@ -1811,16 +2180,21 @@ bool ByteCodeParser::handleTypedArrayConstructor(
     
     if (argumentCountIncludingThis != 2)
         return false;
-    
+
+    insertChecks();
     set(VirtualRegister(resultOperand),
         addToGraph(NewTypedArray, OpInfo(type), get(virtualRegisterForArgument(1, registerOffset))));
     return true;
 }
 
+template<typename ChecksFunctor>
 bool ByteCodeParser::handleConstantInternalFunction(
     int resultOperand, InternalFunction* function, int registerOffset,
-    int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind kind)
+    int argumentCountIncludingThis, CodeSpecializationKind kind, const ChecksFunctor& insertChecks)
 {
+    if (verbose)
+        dataLog("    Handling constant internal function ", JSValue(function), "\n");
+    
     // If we ever find that we have a lot of internal functions that we specialize for,
     // then we should probably have some sort of hashtable dispatch, or maybe even
     // dispatch straight through the MethodTable of the InternalFunction. But for now,
@@ -1828,18 +2202,18 @@ bool ByteCodeParser::handleConstantInternalFunction(
     // we know about is small enough, that having just a linear cascade of if statements
     // is good enough.
     
-    UNUSED_PARAM(prediction); // Remove this once we do more things.
-    
     if (function->classInfo() == ArrayConstructor::info()) {
         if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
             return false;
         
+        insertChecks();
         if (argumentCountIncludingThis == 2) {
             set(VirtualRegister(resultOperand),
                 addToGraph(NewArrayWithSize, OpInfo(ArrayWithUndecided), get(virtualRegisterForArgument(1, registerOffset))));
             return true;
         }
         
+        // FIXME: Array constructor should use "this" as newTarget.
         for (int i = 1; i < argumentCountIncludingThis; ++i)
             addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
         set(VirtualRegister(resultOperand),
@@ -1848,12 +2222,14 @@ bool ByteCodeParser::handleConstantInternalFunction(
     }
     
     if (function->classInfo() == StringConstructor::info()) {
+        insertChecks();
+        
         Node* result;
         
         if (argumentCountIncludingThis <= 1)
-            result = cellConstant(m_vm->smallStrings.emptyString());
+            result = jsConstant(m_vm->smallStrings.emptyString());
         else
-            result = addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset)));
+            result = addToGraph(CallStringConstructor, get(virtualRegisterForArgument(1, registerOffset)));
         
         if (kind == CodeForConstruct)
             result = addToGraph(NewStringObject, OpInfo(function->globalObject()->stringObjectStructure()), result);
@@ -1865,7 +2241,7 @@ bool ByteCodeParser::handleConstantInternalFunction(
     for (unsigned typeIndex = 0; typeIndex < NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
         bool result = handleTypedArrayConstructor(
             resultOperand, function, registerOffset, argumentCountIncludingThis,
-            indexToTypedArrayType(typeIndex));
+            indexToTypedArrayType(typeIndex), insertChecks);
         if (result)
             return true;
     }
@@ -1873,30 +2249,30 @@ bool ByteCodeParser::handleConstantInternalFunction(
     return false;
 }
 
-Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, unsigned identifierNumber, PropertyOffset offset)
+Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, const StructureSet& structureSet, unsigned identifierNumber, PropertyOffset offset, NodeType op)
 {
+    if (base->hasConstant()) {
+        if (JSValue constant = m_graph.tryGetConstantProperty(base->asJSValue(), structureSet, offset)) {
+            addToGraph(Phantom, base);
+            return weakJSConstant(constant);
+        }
+    }
+    
     Node* propertyStorage;
     if (isInlineOffset(offset))
         propertyStorage = base;
     else
         propertyStorage = addToGraph(GetButterfly, base);
-    Node* getByOffset = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), propertyStorage, base);
-
-    StorageAccessData storageAccessData;
-    storageAccessData.offset = offset;
-    storageAccessData.identifierNumber = identifierNumber;
-    m_graph.m_storageAccessData.append(storageAccessData);
+    
+    StorageAccessData* data = m_graph.m_storageAccessData.add();
+    data->offset = offset;
+    data->identifierNumber = identifierNumber;
+    
+    Node* getByOffset = addToGraph(op, OpInfo(data), OpInfo(prediction), propertyStorage, base);
 
     return getByOffset;
 }
 
-void ByteCodeParser::handleGetByOffset(
-    int destinationOperand, SpeculatedType prediction, Node* base, unsigned identifierNumber,
-    PropertyOffset offset)
-{
-    set(VirtualRegister(destinationOperand), handleGetByOffset(prediction, base, identifierNumber, offset));
-}
-
 Node* ByteCodeParser::handlePutByOffset(Node* base, unsigned identifier, PropertyOffset offset, Node* value)
 {
     Node* propertyStorage;
@@ -1904,47 +2280,39 @@ Node* ByteCodeParser::handlePutByOffset(Node* base, unsigned identifier, Propert
         propertyStorage = base;
     else
         propertyStorage = addToGraph(GetButterfly, base);
-    Node* result = addToGraph(PutByOffset, OpInfo(m_graph.m_storageAccessData.size()), propertyStorage, base, value);
     
-    StorageAccessData storageAccessData;
-    storageAccessData.offset = offset;
-    storageAccessData.identifierNumber = identifier;
-    m_graph.m_storageAccessData.append(storageAccessData);
-
+    StorageAccessData* data = m_graph.m_storageAccessData.add();
+    data->offset = offset;
+    data->identifierNumber = identifier;
+    
+    Node* result = addToGraph(PutByOffset, OpInfo(data), propertyStorage, base, value);
+    
     return result;
 }
 
-Node* ByteCodeParser::emitPrototypeChecks(
-    Structure* structure, IntendedStructureChain* chain)
+void ByteCodeParser::emitChecks(const ConstantStructureCheckVector& vector)
 {
-    Node* base = 0;
-    m_graph.chains().addLazily(chain);
-    Structure* currentStructure = structure;
-    JSObject* currentObject = 0;
-    for (unsigned i = 0; i < chain->size(); ++i) {
-        currentObject = asObject(currentStructure->prototypeForLookup(m_inlineStackTop->m_codeBlock));
-        currentStructure = chain->at(i);
-        base = cellConstantWithStructureCheck(currentObject, currentStructure);
-    }
-    return base;
+    for (unsigned i = 0; i < vector.size(); ++i)
+        cellConstantWithStructureCheck(vector[i].constant(), vector[i].structure());
 }
 
 void ByteCodeParser::handleGetById(
     int destinationOperand, SpeculatedType prediction, Node* base, unsigned identifierNumber,
     const GetByIdStatus& getByIdStatus)
 {
-    if (!getByIdStatus.isSimple() || !Options::enableAccessInlining()) {
+    NodeType getById = getByIdStatus.makesCalls() ? GetByIdFlush : GetById;
+    
+    if (!getByIdStatus.isSimple() || !getByIdStatus.numVariants() || !Options::enableAccessInlining()) {
         set(VirtualRegister(destinationOperand),
-            addToGraph(
-                getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
-                OpInfo(identifierNumber), OpInfo(prediction), base));
+            addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
         return;
     }
     
     if (getByIdStatus.numVariants() > 1) {
-        if (!isFTL(m_graph.m_plan.mode) || !Options::enablePolymorphicAccessInlining()) {
+        if (getByIdStatus.makesCalls() || !isFTL(m_graph.m_plan.mode)
+            || !Options::enablePolymorphicAccessInlining()) {
             set(VirtualRegister(destinationOperand),
-                addToGraph(GetById, OpInfo(identifierNumber), OpInfo(prediction), base));
+                addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
             return;
         }
         
@@ -1954,13 +2322,8 @@ void ByteCodeParser::handleGetById(
         // 1) Emit prototype structure checks for all chains. This could sort of maybe not be
         //    optimal, if there is some rarely executed case in the chain that requires a lot
         //    of checks and those checks are not watchpointable.
-        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;) {
-            if (getByIdStatus[variantIndex].chain()) {
-                emitPrototypeChecks(
-                    getByIdStatus[variantIndex].structureSet().singletonStructure(),
-                    getByIdStatus[variantIndex].chain());
-            }
-        }
+        for (unsigned variantIndex = getByIdStatus.numVariants(); variantIndex--;)
+            emitChecks(getByIdStatus[variantIndex].constantChecks());
         
         // 2) Emit a MultiGetByOffset
         MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add();
@@ -1977,33 +2340,68 @@ void ByteCodeParser::handleGetById(
     if (m_graph.compilation())
         m_graph.compilation()->noticeInlinedGetById();
     
-    Node* originalBaseForBaselineJIT = base;
+    Node* originalBase = base;
                 
     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), base);
     
-    if (variant.chain()) {
-        base = emitPrototypeChecks(
-            variant.structureSet().singletonStructure(), variant.chain());
-    }
+    emitChecks(variant.constantChecks());
+
+    if (variant.alternateBase())
+        base = weakJSConstant(variant.alternateBase());
     
     // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
     // ensure that the base of the original get_by_id is kept alive until we're done with
     // all of the speculations. We only insert the Phantom if there had been a CheckStructure
-    // on something other than the base following the CheckStructure on base, or if the
-    // access was compiled to a WeakJSConstant specific value, in which case we might not
-    // have any explicit use of the base at all.
-    if (variant.specificValue() || originalBaseForBaselineJIT != base)
-        addToGraph(Phantom, originalBaseForBaselineJIT);
+    // on something other than the base following the CheckStructure on base.
+    if (originalBase != base)
+        addToGraph(Phantom, originalBase);
     
-    if (variant.specificValue()) {
-        ASSERT(variant.specificValue().isCell());
-        
-        set(VirtualRegister(destinationOperand), cellConstant(variant.specificValue().asCell()));
+    Node* loadedValue = handleGetByOffset(
+        variant.callLinkStatus() ? SpecCellOther : prediction,
+        base, variant.baseStructure(), identifierNumber, variant.offset(),
+        variant.callLinkStatus() ? GetGetterSetterByOffset : GetByOffset);
+    
+    if (!variant.callLinkStatus()) {
+        set(VirtualRegister(destinationOperand), loadedValue);
         return;
     }
     
-    handleGetByOffset(
-        destinationOperand, prediction, base, identifierNumber, variant.offset());
+    Node* getter = addToGraph(GetGetter, loadedValue);
+    
+    // Make a call. We don't try to get fancy with using the smallest operand number because
+    // the stack layout phase should compress the stack anyway.
+    
+    unsigned numberOfParameters = 0;
+    numberOfParameters++; // The 'this' argument.
+    numberOfParameters++; // True return PC.
+    
+    // Start with a register offset that corresponds to the last in-use register.
+    int registerOffset = virtualRegisterForLocal(
+        m_inlineStackTop->m_profiledBlock->m_numCalleeRegisters - 1).offset();
+    registerOffset -= numberOfParameters;
+    registerOffset -= JSStack::CallFrameHeaderSize;
+    
+    // Get the alignment right.
+    registerOffset = -WTF::roundUpToMultipleOf(
+        stackAlignmentRegisters(),
+        -registerOffset);
+    
+    ensureLocals(
+        m_inlineStackTop->remapOperand(
+            VirtualRegister(registerOffset)).toLocal());
+    
+    // Issue SetLocals. This has two effects:
+    // 1) That's how handleCall() sees the arguments.
+    // 2) If we inline then this ensures that the arguments are flushed so that if you use
+    //    the dreaded arguments object on the getter, the right things happen. Well, sort of -
+    //    since we only really care about 'this' in this case. But we're not going to take that
+    //    shortcut.
+    int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
+    set(VirtualRegister(nextRegister++), originalBase, ImmediateNakedSet);
+    
+    handleCall(
+        destinationOperand, Call, InlineCallFrame::GetterCall, OPCODE_LENGTH(op_get_by_id),
+        getter, numberOfParameters - 1, registerOffset, *variant.callLinkStatus(), prediction);
 }
 
 void ByteCodeParser::emitPutById(
@@ -2019,7 +2417,7 @@ void ByteCodeParser::handlePutById(
     Node* base, unsigned identifierNumber, Node* value,
     const PutByIdStatus& putByIdStatus, bool isDirect)
 {
-    if (!putByIdStatus.isSimple() || !Options::enableAccessInlining()) {
+    if (!putByIdStatus.isSimple() || !putByIdStatus.numVariants() || !Options::enableAccessInlining()) {
         if (!putByIdStatus.isSet())
             addToGraph(ForceOSRExit);
         emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
@@ -2040,11 +2438,7 @@ void ByteCodeParser::handlePutById(
             for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) {
                 if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition)
                     continue;
-                if (!putByIdStatus[variantIndex].structureChain())
-                    continue;
-                emitPrototypeChecks(
-                    putByIdStatus[variantIndex].oldStructure(),
-                    putByIdStatus[variantIndex].structureChain());
+                emitChecks(putByIdStatus[variantIndex].constantChecks());
             }
         }
         
@@ -2058,7 +2452,8 @@ void ByteCodeParser::handlePutById(
     ASSERT(putByIdStatus.numVariants() == 1);
     const PutByIdVariant& variant = putByIdStatus[0];
     
-    if (variant.kind() == PutByIdVariant::Replace) {
+    switch (variant.kind()) {
+    case PutByIdVariant::Replace: {
         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structure())), base);
         handlePutByOffset(base, identifierNumber, variant.offset(), value);
         if (m_graph.compilation())
@@ -2066,85 +2461,124 @@ void ByteCodeParser::handlePutById(
         return;
     }
     
-    if (variant.kind() != PutByIdVariant::Transition) {
-        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
-        return;
-    }
-
-    if (variant.structureChain() && !variant.structureChain()->isStillValid()) {
-        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
-        return;
-    }
-    
-    m_graph.chains().addLazily(variant.structureChain());
-                
-    addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
-    if (!isDirect)
-        emitPrototypeChecks(variant.oldStructure(), variant.structureChain());
+    case PutByIdVariant::Transition: {
+        addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.oldStructure())), base);
+        emitChecks(variant.constantChecks());
 
-    ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
+        ASSERT(variant.oldStructureForTransition()->transitionWatchpointSetHasBeenInvalidated());
     
-    Node* propertyStorage;
-    StructureTransitionData* transitionData = m_graph.addStructureTransitionData(
-        StructureTransitionData(variant.oldStructure(), variant.newStructure()));
+        Node* propertyStorage;
+        Transition* transition = m_graph.m_transitions.add(
+            variant.oldStructureForTransition(), variant.newStructure());
 
-    if (variant.oldStructure()->outOfLineCapacity()
-        != variant.newStructure()->outOfLineCapacity()) {
+        if (variant.reallocatesStorage()) {
 
-        // If we're growing the property storage then it must be because we're
-        // storing into the out-of-line storage.
-        ASSERT(!isInlineOffset(variant.offset()));
+            // If we're growing the property storage then it must be because we're
+            // storing into the out-of-line storage.
+            ASSERT(!isInlineOffset(variant.offset()));
 
-        if (!variant.oldStructure()->outOfLineCapacity()) {
-            propertyStorage = addToGraph(
-                AllocatePropertyStorage, OpInfo(transitionData), base);
+            if (!variant.oldStructureForTransition()->outOfLineCapacity()) {
+                propertyStorage = addToGraph(
+                    AllocatePropertyStorage, OpInfo(transition), base);
+            } else {
+                propertyStorage = addToGraph(
+                    ReallocatePropertyStorage, OpInfo(transition),
+                    base, addToGraph(GetButterfly, base));
+            }
         } else {
-            propertyStorage = addToGraph(
-                ReallocatePropertyStorage, OpInfo(transitionData),
-                base, addToGraph(GetButterfly, base));
+            if (isInlineOffset(variant.offset()))
+                propertyStorage = base;
+            else
+                propertyStorage = addToGraph(GetButterfly, base);
         }
-    } else {
-        if (isInlineOffset(variant.offset()))
-            propertyStorage = base;
-        else
-            propertyStorage = addToGraph(GetButterfly, base);
-    }
 
-    addToGraph(PutStructure, OpInfo(transitionData), base);
-
-    addToGraph(
-        PutByOffset,
-        OpInfo(m_graph.m_storageAccessData.size()),
-        propertyStorage,
-        base,
-        value);
+        StorageAccessData* data = m_graph.m_storageAccessData.add();
+        data->offset = variant.offset();
+        data->identifierNumber = identifierNumber;
+        
+        addToGraph(
+            PutByOffset,
+            OpInfo(data),
+            propertyStorage,
+            base,
+            value);
 
-    StorageAccessData storageAccessData;
-    storageAccessData.offset = variant.offset();
-    storageAccessData.identifierNumber = identifierNumber;
-    m_graph.m_storageAccessData.append(storageAccessData);
+        // FIXME: PutStructure goes last until we fix either
+        // https://bugs.webkit.org/show_bug.cgi?id=142921 or
+        // https://bugs.webkit.org/show_bug.cgi?id=142924.
+        addToGraph(PutStructure, OpInfo(transition), base);
 
-    if (m_graph.compilation())
-        m_graph.compilation()->noticeInlinedPutById();
+        if (m_graph.compilation())
+            m_graph.compilation()->noticeInlinedPutById();
+        return;
+    }
+        
+    case PutByIdVariant::Setter: {
+        Node* originalBase = base;
+        
+        addToGraph(
+            CheckStructure, OpInfo(m_graph.addStructureSet(variant.structure())), base);
+        
+        emitChecks(variant.constantChecks());
+        
+        if (variant.alternateBase())
+            base = weakJSConstant(variant.alternateBase());
+        
+        Node* loadedValue = handleGetByOffset(
+            SpecCellOther, base, variant.baseStructure(), identifierNumber, variant.offset(),
+            GetGetterSetterByOffset);
+        
+        Node* setter = addToGraph(GetSetter, loadedValue);
+        
+        // Make a call. We don't try to get fancy with using the smallest operand number because
+        // the stack layout phase should compress the stack anyway.
+    
+        unsigned numberOfParameters = 0;
+        numberOfParameters++; // The 'this' argument.
+        numberOfParameters++; // The new value.
+        numberOfParameters++; // True return PC.
+    
+        // Start with a register offset that corresponds to the last in-use register.
+        int registerOffset = virtualRegisterForLocal(
+            m_inlineStackTop->m_profiledBlock->m_numCalleeRegisters - 1).offset();
+        registerOffset -= numberOfParameters;
+        registerOffset -= JSStack::CallFrameHeaderSize;
+    
+        // Get the alignment right.
+        registerOffset = -WTF::roundUpToMultipleOf(
+            stackAlignmentRegisters(),
+            -registerOffset);
+    
+        ensureLocals(
+            m_inlineStackTop->remapOperand(
+                VirtualRegister(registerOffset)).toLocal());
+    
+        int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
+        set(VirtualRegister(nextRegister++), originalBase, ImmediateNakedSet);
+        set(VirtualRegister(nextRegister++), value, ImmediateNakedSet);
+    
+        handleCall(
+            VirtualRegister().offset(), Call, InlineCallFrame::SetterCall,
+            OPCODE_LENGTH(op_put_by_id), setter, numberOfParameters - 1, registerOffset,
+            *variant.callLinkStatus(), SpecOther);
+        return;
+    }
+    
+    default: {
+        emitPutById(base, identifierNumber, value, putByIdStatus, isDirect);
+        return;
+    } }
 }
 
 void ByteCodeParser::prepareToParseBlock()
 {
-    for (unsigned i = 0; i < m_constants.size(); ++i)
-        m_constants[i] = ConstantRecord();
-    m_cellConstantNodes.clear();
+    clearCaches();
+    ASSERT(m_setLocalQueue.isEmpty());
 }
 
-Node* ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
+void ByteCodeParser::clearCaches()
 {
-    Node* localBase = get(VirtualRegister(JSStack::ScopeChain));
-    if (skipTop) {
-        ASSERT(!inlineCallFrame());
-        localBase = addToGraph(SkipTopScope, localBase);
-    }
-    for (unsigned n = skipCount; n--;)
-        localBase = addToGraph(SkipScope, localBase);
-    return localBase;
+    m_constants.resize(0);
 }
 
 bool ByteCodeParser::parseBlock(unsigned limit)
@@ -2162,10 +2596,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         m_graph.m_arguments.resize(m_numArguments);
         for (unsigned argument = 0; argument < m_numArguments; ++argument) {
             VariableAccessData* variable = newVariableAccessData(
-                virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
+                virtualRegisterForArgument(argument));
             variable->mergeStructureCheckHoistingFailed(
-                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
+                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
             variable->mergeCheckArrayHoistingFailed(
                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
             
@@ -2176,9 +2609,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
     }
 
     while (true) {
-        for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
-            m_setLocalQueue[i].execute(this);
-        m_setLocalQueue.resize(0);
+        processSetLocalQueue();
         
         // Don't extend over jump destinations.
         if (m_currentIndex == limit) {
@@ -2211,28 +2642,23 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
         // === Function entry opcodes ===
 
-        case op_enter:
+        case op_enter: {
+            Node* undefined = addToGraph(JSConstant, OpInfo(m_constantUndefined));
             // Initialize all locals to undefined.
             for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
-                set(virtualRegisterForLocal(i), constantUndefined(), ImmediateNakedSet);
-            if (m_inlineStackTop->m_codeBlock->specializationKind() == CodeForConstruct)
-                set(virtualRegisterForArgument(0), constantUndefined(), ImmediateNakedSet);
+                set(virtualRegisterForLocal(i), undefined, ImmediateNakedSet);
             NEXT_OPCODE(op_enter);
-            
-        case op_touch_entry:
-            if (m_inlineStackTop->m_codeBlock->symbolTable()->m_functionEnteredOnce.isStillValid())
-                addToGraph(ForceOSRExit);
-            NEXT_OPCODE(op_touch_entry);
+        }
             
         case op_to_this: {
             Node* op1 = getThis();
             if (op1->op() != ToThis) {
                 Structure* cachedStructure = currentInstruction[2].u.structure.get();
-                if (!cachedStructure
+                if (currentInstruction[2].u.toThisStatus != ToThisOK
+                    || !cachedStructure
                     || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis
                     || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
                     || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
-                    || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
                     || (op1->op() == GetLocal && op1->variableAccessData()->structureCheckHoistingFailed())) {
                     setThis(addToGraph(ToThis, op1));
                 } else {
@@ -2248,18 +2674,34 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_create_this: {
             int calleeOperand = currentInstruction[2].u.operand;
             Node* callee = get(VirtualRegister(calleeOperand));
+
+            JSFunction* function = callee->dynamicCastConstant<JSFunction*>();
+            if (!function) {
+                JSCell* cachedFunction = currentInstruction[4].u.jsCell.unvalidatedGet();
+                if (cachedFunction
+                    && cachedFunction != JSCell::seenMultipleCalleeObjects()
+                    && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
+                    ASSERT(cachedFunction->inherits(JSFunction::info()));
+
+                    FrozenValue* frozen = m_graph.freeze(cachedFunction);
+                    addToGraph(CheckCell, OpInfo(frozen), callee);
+                    set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
+
+                    function = static_cast<JSFunction*>(cachedFunction);
+                }
+            }
+
             bool alreadyEmitted = false;
-            if (callee->op() == WeakJSConstant) {
-                JSCell* cell = callee->weakConstant();
-                ASSERT(cell->inherits(JSFunction::info()));
-                
-                JSFunction* function = jsCast<JSFunction*>(cell);
-                if (Structure* structure = function->allocationStructure()) {
-                    addToGraph(AllocationProfileWatchpoint, OpInfo(function));
-                    // The callee is still live up to this point.
-                    addToGraph(Phantom, callee);
-                    set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
-                    alreadyEmitted = true;
+            if (function) {
+                if (FunctionRareData* rareData = function->rareData()) {
+                    if (Structure* structure = rareData->allocationStructure()) {
+                        m_graph.freeze(rareData);
+                        m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
+                        // The callee is still live up to this point.
+                        addToGraph(Phantom, callee);
+                        set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(NewObject, OpInfo(structure)));
+                        alreadyEmitted = true;
+                    }
                 }
             }
             if (!alreadyEmitted) {
@@ -2320,21 +2762,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             NEXT_OPCODE(op_new_regexp);
         }
             
-        case op_get_callee: {
-            JSCell* cachedFunction = currentInstruction[2].u.jsCell.get();
-            if (!cachedFunction 
-                || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
-                || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadFunction)) {
-                set(VirtualRegister(currentInstruction[1].u.operand), get(VirtualRegister(JSStack::Callee)));
-            } else {
-                ASSERT(cachedFunction->inherits(JSFunction::info()));
-                Node* actualCallee = get(VirtualRegister(JSStack::Callee));
-                addToGraph(CheckFunction, OpInfo(cachedFunction), actualCallee);
-                set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(WeakJSConstant, OpInfo(cachedFunction)));
-            }
-            NEXT_OPCODE(op_get_callee);
-        }
-
         // === Bitwise operations ===
 
         case op_bitand: {
@@ -2394,7 +2821,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             int srcDst = currentInstruction[1].u.operand;
             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
             Node* op = get(srcDstVirtualRegister);
-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, one())));
+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
             NEXT_OPCODE(op_inc);
         }
 
@@ -2402,7 +2829,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             int srcDst = currentInstruction[1].u.operand;
             VirtualRegister srcDstVirtualRegister = VirtualRegister(srcDst);
             Node* op = get(srcDstVirtualRegister);
-            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, one())));
+            set(srcDstVirtualRegister, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
             NEXT_OPCODE(op_dec);
         }
 
@@ -2474,15 +2901,11 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             set(VirtualRegister(currentInstruction[1].u.operand), op);
             NEXT_OPCODE(op_mov);
         }
-            
-        case op_captured_mov: {
-            Node* op = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet) {
-                if (set->state() != IsInvalidated)
-                    addToGraph(NotifyWrite, OpInfo(set), op);
-            }
-            set(VirtualRegister(currentInstruction[1].u.operand), op);
-            NEXT_OPCODE(op_captured_mov);
+
+        case op_check_tdz: {
+            Node* op = get(VirtualRegister(currentInstruction[1].u.operand));
+            addToGraph(CheckNotEmpty, op);
+            NEXT_OPCODE(op_check_tdz);
         }
 
         case op_check_has_instance:
@@ -2526,6 +2949,12 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             NEXT_OPCODE(op_is_object);
         }
 
+        case op_is_object_or_null: {
+            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsObjectOrNull, value));
+            NEXT_OPCODE(op_is_object_or_null);
+        }
+
         case op_is_function: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsFunction, value));
@@ -2619,7 +3048,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
         case op_eq_null: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, constantNull()));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull))));
             NEXT_OPCODE(op_eq_null);
         }
 
@@ -2639,7 +3068,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
         case op_neq_null: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, constantNull())));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)))));
             NEXT_OPCODE(op_neq_null);
         }
 
@@ -2655,10 +3084,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         // === Property access operations ===
 
         case op_get_by_val: {
-            SpeculatedType prediction = getPrediction();
+            SpeculatedType prediction = getPredictionWithoutOSRExit();
             
             Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
-            ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read);
+            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Read);
             Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
             Node* getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property);
             set(VirtualRegister(currentInstruction[1].u.operand), getByVal);
@@ -2670,7 +3099,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_put_by_val: {
             Node* base = get(VirtualRegister(currentInstruction[1].u.operand));
 
-            ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Write);
+            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Write);
             
             Node* property = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* value = get(VirtualRegister(currentInstruction[3].u.operand));
@@ -2693,7 +3122,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
             unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
             
-            StringImpl* uid = m_graph.identifiers()[identifierNumber];
+            UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
             GetByIdStatus getByIdStatus = GetByIdStatus::computeFor(
                 m_inlineStackTop->m_profiledBlock, m_dfgCodeBlock,
                 m_inlineStackTop->m_stubInfos, m_dfgStubInfos,
@@ -2730,20 +3159,33 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
         case op_init_global_const: {
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
+            JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
             addToGraph(
                 PutGlobalVar,
-                OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertRegisterIsInThisObject(currentInstruction[1].u.registerPointer)),
-                value);
+                OpInfo(globalObject->assertVariableIsInThisObject(currentInstruction[1].u.variablePointer)),
+                weakJSConstant(globalObject), value);
             NEXT_OPCODE(op_init_global_const);
         }
 
+        case op_profile_type: {
+            Node* valueToProfile = get(VirtualRegister(currentInstruction[1].u.operand));
+            addToGraph(ProfileType, OpInfo(currentInstruction[2].u.location), valueToProfile);
+            NEXT_OPCODE(op_profile_type);
+        }
+
+        case op_profile_control_flow: {
+            BasicBlockLocation* basicBlockLocation = currentInstruction[1].u.basicBlockLocation;
+            addToGraph(ProfileControlFlow, OpInfo(basicBlockLocation));
+            NEXT_OPCODE(op_profile_control_flow);
+        }
+
         // === Block terminators. ===
 
         case op_jmp: {
             int relativeOffset = currentInstruction[1].u.operand;
+            addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
             if (relativeOffset <= 0)
                 flushForTerminal();
-            addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
             LAST_OPCODE(op_jmp);
         }
 
@@ -2764,7 +3206,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_jeq_null: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jeq_null))), condition);
             LAST_OPCODE(op_jeq_null);
         }
@@ -2772,7 +3214,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_jneq_null: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
-            Node* condition = addToGraph(CompareEqConstant, value, constantNull());
+            Node* condition = addToGraph(CompareEqConstant, value, addToGraph(JSConstant, OpInfo(m_constantNull)));
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_null), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jneq_null);
         }
@@ -2861,10 +3303,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
                 unsigned target = m_currentIndex + table.branchOffsets[i];
                 if (target == data.fallThrough.bytecodeIndex())
                     continue;
-                data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(static_cast<int32_t>(table.min + i)), target));
+                data.cases.append(SwitchCase::withBytecodeIndex(m_graph.freeze(jsNumber(static_cast<int32_t>(table.min + i))), target));
             }
-            flushIfTerminal(data);
             addToGraph(Switch, OpInfo(&data), get(VirtualRegister(currentInstruction[3].u.operand)));
+            flushIfTerminal(data);
             LAST_OPCODE(op_switch_imm);
         }
             
@@ -2883,8 +3325,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
                 data.cases.append(
                     SwitchCase::withBytecodeIndex(LazyJSValue::singleCharacterString(table.min + i), target));
             }
-            flushIfTerminal(data);
             addToGraph(Switch, OpInfo(&data), get(VirtualRegister(currentInstruction[3].u.operand)));
+            flushIfTerminal(data);
             LAST_OPCODE(op_switch_char);
         }
 
@@ -2903,16 +3345,16 @@ bool ByteCodeParser::parseBlock(unsigned limit)
                 data.cases.append(
                     SwitchCase::withBytecodeIndex(LazyJSValue::knownStringImpl(iter->key.get()), target));
             }
-            flushIfTerminal(data);
             addToGraph(Switch, OpInfo(&data), get(VirtualRegister(currentInstruction[3].u.operand)));
+            flushIfTerminal(data);
             LAST_OPCODE(op_switch_string);
         }
 
         case op_ret:
-            flushForReturn();
             if (inlineCallFrame()) {
-                ASSERT(m_inlineStackTop->m_returnValue.isValid());
-                setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSetWithFlush);
+                flushForReturn();
+                if (m_inlineStackTop->m_returnValue.isValid())
+                    setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSetWithFlush);
                 m_inlineStackTop->m_didReturn = true;
                 if (m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
                     // If we're returning from the first block, then we're done parsing.
@@ -2934,12 +3376,13 @@ bool ByteCodeParser::parseBlock(unsigned limit)
                 LAST_OPCODE(op_ret);
             }
             addToGraph(Return, get(VirtualRegister(currentInstruction[1].u.operand)));
+            flushForReturn();
             LAST_OPCODE(op_ret);
             
         case op_end:
-            flushForReturn();
             ASSERT(!inlineCallFrame());
             addToGraph(Return, get(VirtualRegister(currentInstruction[1].u.operand)));
+            flushForReturn();
             LAST_OPCODE(op_end);
 
         case op_throw:
@@ -2956,6 +3399,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             
         case op_call:
             handleCall(currentInstruction, Call, CodeForCall);
+            // Verify that handleCall(), which could have inlined the callee, didn't trash m_currentInstruction
+            ASSERT(m_currentInstruction == currentInstruction);
             NEXT_OPCODE(op_call);
             
         case op_construct:
@@ -2963,64 +3408,32 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             NEXT_OPCODE(op_construct);
             
         case op_call_varargs: {
-            int result = currentInstruction[1].u.operand;
-            int callee = currentInstruction[2].u.operand;
-            int thisReg = currentInstruction[3].u.operand;
-            int arguments = currentInstruction[4].u.operand;
-            int firstFreeReg = currentInstruction[5].u.operand;
-            
-            ASSERT(inlineCallFrame());
-            ASSERT_UNUSED(arguments, arguments == m_inlineStackTop->m_codeBlock->argumentsRegister().offset());
-            ASSERT(!m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments());
-
-            addToGraph(CheckArgumentsNotCreated);
-
-            unsigned argCount = inlineCallFrame()->arguments.size();
-            
-            // Let's compute the register offset. We start with the last used register, and
-            // then adjust for the things we want in the call frame.
-            int registerOffset = firstFreeReg + 1;
-            registerOffset -= argCount; // We will be passing some arguments.
-            registerOffset -= JSStack::CallFrameHeaderSize; // We will pretend to have a call frame header.
-            
-            // Get the alignment right.
-            registerOffset = -WTF::roundUpToMultipleOf(
-                stackAlignmentRegisters(),
-                -registerOffset);
-
-            ensureLocals(
-                m_inlineStackTop->remapOperand(
-                    VirtualRegister(registerOffset)).toLocal());
-            
-            // The bytecode wouldn't have set up the arguments. But we'll do it and make it
-            // look like the bytecode had done it.
-            int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
-            set(VirtualRegister(nextRegister++), get(VirtualRegister(thisReg)), ImmediateNakedSet);
-            for (unsigned argument = 1; argument < argCount; ++argument)
-                set(VirtualRegister(nextRegister++), get(virtualRegisterForArgument(argument)), ImmediateNakedSet);
-            
-            handleCall(
-                result, Call, CodeForCall, OPCODE_LENGTH(op_call_varargs),
-                callee, argCount, registerOffset);
+            handleVarargsCall(currentInstruction, CallVarargs, CodeForCall);
             NEXT_OPCODE(op_call_varargs);
         }
             
+        case op_construct_varargs: {
+            handleVarargsCall(currentInstruction, ConstructVarargs, CodeForConstruct);
+            NEXT_OPCODE(op_construct_varargs);
+        }
+            
         case op_jneq_ptr:
             // Statically speculate for now. It makes sense to let speculate-only jneq_ptr
             // support simmer for a while before making it more general, since it's
             // already gnarly enough as it is.
             ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
             addToGraph(
-                CheckFunction,
-                OpInfo(actualPointerFor(m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)),
+                CheckCell,
+                OpInfo(m_graph.freeze(static_cast<JSCell*>(actualPointerFor(
+                    m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)))),
                 get(VirtualRegister(currentInstruction[1].u.operand)));
             addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
             LAST_OPCODE(op_jneq_ptr);
 
         case op_resolve_scope: {
             int dst = currentInstruction[1].u.operand;
-            ResolveType resolveType = static_cast<ResolveType>(currentInstruction[3].u.operand);
-            unsigned depth = currentInstruction[4].u.operand;
+            ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
+            unsigned depth = currentInstruction[5].u.operand;
 
             // get_from_scope and put_to_scope depend on this watchpoint forcing OSR exit, so they don't add their own watchpoints.
             if (needsVarInjectionChecks(resolveType))
@@ -3031,19 +3444,35 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             case GlobalVar:
             case GlobalPropertyWithVarInjectionChecks:
             case GlobalVarWithVarInjectionChecks:
-                set(VirtualRegister(dst), cellConstant(m_inlineStackTop->m_codeBlock->globalObject()));
+                set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop->m_codeBlock->globalObject()));
+                if (resolveType == GlobalPropertyWithVarInjectionChecks || resolveType == GlobalVarWithVarInjectionChecks)
+                    addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
                 break;
+            case LocalClosureVar:
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
-                JSActivation* activation = currentInstruction[5].u.activation.get();
-                if (activation
-                    && activation->symbolTable()->m_functionEnteredOnce.isStillValid()) {
-                    addToGraph(FunctionReentryWatchpoint, OpInfo(activation->symbolTable()));
-                    set(VirtualRegister(dst), cellConstant(activation));
+                Node* localBase = get(VirtualRegister(currentInstruction[2].u.operand));
+                addToGraph(Phantom, localBase); // OSR exit cannot handle resolve_scope on a DCE'd scope.
+                
+                // We have various forms of constant folding here. This is necessary to avoid
+                // spurious recompiles in dead-but-foldable code.
+                if (SymbolTable* symbolTable = currentInstruction[6].u.symbolTable.get()) {
+                    InferredValue* singleton = symbolTable->singletonScope();
+                    if (JSValue value = singleton->inferredValue()) {
+                        m_graph.watchpoints().addLazily(singleton);
+                        set(VirtualRegister(dst), weakJSConstant(value));
+                        break;
+                    }
+                }
+                if (JSScope* scope = localBase->dynamicCastConstant<JSScope*>()) {
+                    for (unsigned n = depth; n--;)
+                        scope = scope->next();
+                    set(VirtualRegister(dst), weakJSConstant(scope));
                     break;
                 }
-                set(VirtualRegister(dst),
-                    getScope(m_inlineStackTop->m_codeBlock->needsActivation(), depth));
+                for (unsigned n = depth; n--;)
+                    localBase = addToGraph(SkipScope, localBase);
+                set(VirtualRegister(dst), localBase);
                 break;
             }
             case Dynamic:
@@ -3057,7 +3486,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             int dst = currentInstruction[1].u.operand;
             int scope = currentInstruction[2].u.operand;
             unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
-            StringImpl* uid = m_graph.identifiers()[identifierNumber];
+            UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber];
             ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
 
             Structure* structure = 0;
@@ -3074,62 +3503,115 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
             UNUSED_PARAM(watchpoints); // We will use this in the future. For now we set it as a way of documenting the fact that that's what index 5 is in GlobalVar mode.
 
-            SpeculatedType prediction = getPrediction();
             JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
 
             switch (resolveType) {
             case GlobalProperty:
             case GlobalPropertyWithVarInjectionChecks: {
-                GetByIdStatus status = GetByIdStatus::computeFor(*m_vm, structure, uid);
-                if (status.state() != GetByIdStatus::Simple || status.numVariants() != 1) {
+                SpeculatedType prediction = getPrediction();
+                GetByIdStatus status = GetByIdStatus::computeFor(structure, uid);
+                if (status.state() != GetByIdStatus::Simple
+                    || status.numVariants() != 1
+                    || status[0].structureSet().size() != 1) {
                     set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
                     break;
                 }
-                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().singletonStructure());
+                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structureSet().onlyStructure());
                 addToGraph(Phantom, get(VirtualRegister(scope)));
-                if (JSValue specificValue = status[0].specificValue())
-                    set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
-                else
-                    set(VirtualRegister(dst), handleGetByOffset(prediction, base, identifierNumber, operand));
+                set(VirtualRegister(dst), handleGetByOffset(prediction, base, status[0].structureSet(), identifierNumber, operand));
                 break;
             }
             case GlobalVar:
             case GlobalVarWithVarInjectionChecks: {
                 addToGraph(Phantom, get(VirtualRegister(scope)));
-                SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
-                VariableWatchpointSet* watchpointSet = entry.watchpointSet();
-                JSValue specificValue =
-                    watchpointSet ? watchpointSet->inferredValue() : JSValue();
-                if (!specificValue) {
-                    set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
-                    break;
+                WatchpointSet* watchpointSet;
+                ScopeOffset offset;
+                {
+                    ConcurrentJITLocker locker(globalObject->symbolTable()->m_lock);
+                    SymbolTableEntry entry = globalObject->symbolTable()->get(locker, uid);
+                    watchpointSet = entry.watchpointSet();
+                    offset = entry.scopeOffset();
+                }
+                if (watchpointSet && watchpointSet->state() == IsWatched) {
+                    // This has a fun concurrency story. There is the possibility of a race in two
+                    // directions:
+                    //
+                    // We see that the set IsWatched, but in the meantime it gets invalidated: this is
+                    // fine because if we saw that it IsWatched then we add a watchpoint. If it gets
+                    // invalidated, then this compilation is invalidated. Note that in the meantime we
+                    // may load an absurd value from the global object. It's fine to load an absurd
+                    // value if the compilation is invalidated anyway.
+                    //
+                    // We see that the set IsWatched, but the value isn't yet initialized: this isn't
+                    // possible because of the ordering of operations.
+                    //
+                    // Here's how we order operations:
+                    //
+                    // Main thread stores to the global object: always store a value first, and only
+                    // after that do we touch the watchpoint set. There is a fence in the touch, that
+                    // ensures that the store to the global object always happens before the touch on the
+                    // set.
+                    //
+                    // Compilation thread: always first load the state of the watchpoint set, and then
+                    // load the value. The WatchpointSet::state() method does fences for us to ensure
+                    // that the load of the state happens before our load of the value.
+                    //
+                    // Finalizing compilation: this happens on the main thread and synchronously checks
+                    // validity of all watchpoint sets.
+                    //
+                    // We will only perform optimizations if the load of the state yields IsWatched. That
+                    // means that at least one store would have happened to initialize the original value
+                    // of the variable (that is, the value we'd like to constant fold to). There may be
+                    // other stores that happen after that, but those stores will invalidate the
+                    // watchpoint set and also the compilation.
+                    
+                    // Note that we need to use the operand, which is a direct pointer at the global,
+                    // rather than looking up the global by doing variableAt(offset). That's because the
+                    // internal data structures of JSSegmentedVariableObject are not thread-safe even
+                    // though accessing the global itself is. The segmentation involves a vector spine
+                    // that resizes with malloc/free, so if new globals unrelated to the one we are
+                    // reading are added, we might access freed memory if we do variableAt().
+                    WriteBarrier<Unknown>* pointer = bitwise_cast<WriteBarrier<Unknown>*>(operand);
+                    
+                    ASSERT(globalObject->findVariableIndex(pointer) == offset);
+                    
+                    JSValue value = pointer->get();
+                    if (value) {
+                        m_graph.watchpoints().addLazily(watchpointSet);
+                        set(VirtualRegister(dst), weakJSConstant(value));
+                        break;
+                    }
                 }
                 
-                addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
-                set(VirtualRegister(dst), inferredConstant(specificValue));
+                SpeculatedType prediction = getPrediction();
+                set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
                 break;
             }
+            case LocalClosureVar:
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
                 Node* scopeNode = get(VirtualRegister(scope));
-                if (JSActivation* activation = m_graph.tryGetActivation(scopeNode)) {
-                    SymbolTable* symbolTable = activation->symbolTable();
-                    ConcurrentJITLocker locker(symbolTable->m_lock);
-                    SymbolTable::Map::iterator iter = symbolTable->find(locker, uid);
-                    ASSERT(iter != symbolTable->end(locker));
-                    VariableWatchpointSet* watchpointSet = iter->value.watchpointSet();
-                    if (watchpointSet) {
-                        if (JSValue value = watchpointSet->inferredValue()) {
-                            addToGraph(Phantom, scopeNode);
-                            addToGraph(VariableWatchpoint, OpInfo(watchpointSet));
-                            set(VirtualRegister(dst), inferredConstant(value));
-                            break;
-                        }
-                    }
+                
+                // Ideally we wouldn't have to do this Phantom. But:
+                //
+                // For the constant case: we must do it because otherwise we would have no way of knowing
+                // that the scope is live at OSR here.
+                //
+                // For the non-constant case: GetClosureVar could be DCE'd, but baseline's implementation
+                // won't be able to handle an Undefined scope.
+                addToGraph(Phantom, scopeNode);
+                
+                // Constant folding in the bytecode parser is important for performance. This may not
+                // have executed yet. If it hasn't, then we won't have a prediction. Lacking a
+                // prediction, we'd otherwise think that it has to exit. Then when it did execute, we
+                // would recompile. But if we can fold it here, we avoid the exit.
+                if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, ScopeOffset(operand))) {
+                    set(VirtualRegister(dst), weakJSConstant(value));
+                    break;
                 }
+                SpeculatedType prediction = getPrediction();
                 set(VirtualRegister(dst),
-                    addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), 
-                        addToGraph(GetClosureRegisters, scopeNode)));
+                    addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), scopeNode));
                 break;
             }
             case Dynamic:
@@ -3141,17 +3623,23 @@ bool ByteCodeParser::parseBlock(unsigned limit)
 
         case op_put_to_scope: {
             unsigned scope = currentInstruction[1].u.operand;
-            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
+            unsigned identifierNumber = currentInstruction[2].u.operand;
+            if (identifierNumber != UINT_MAX)
+                identifierNumber = m_inlineStackTop->m_identifierRemap[identifierNumber];
             unsigned value = currentInstruction[3].u.operand;
             ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
-            StringImpl* uid = m_graph.identifiers()[identifierNumber];
-
-            Structure* structure = 0;
-            VariableWatchpointSet* watchpoints = 0;
+            UniquedStringImpl* uid;
+            if (identifierNumber != UINT_MAX)
+                uid = m_graph.identifiers()[identifierNumber];
+            else
+                uid = nullptr;
+            
+            Structure* structure = nullptr;
+            WatchpointSet* watchpoints = nullptr;
             uintptr_t operand;
             {
                 ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
-                if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
+                if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
                     watchpoints = currentInstruction[5].u.watchpointSet;
                 else
                     structure = currentInstruction[5].u.structure.get();
@@ -3163,12 +3651,19 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             switch (resolveType) {
             case GlobalProperty:
             case GlobalPropertyWithVarInjectionChecks: {
-                PutByIdStatus status = PutByIdStatus::computeFor(*m_vm, globalObject, structure, uid, false);
-                if (status.numVariants() != 1 || status[0].kind() != PutByIdVariant::Replace) {
+                PutByIdStatus status;
+                if (uid)
+                    status = PutByIdStatus::computeFor(globalObject, structure, uid, false);
+                else
+                    status = PutByIdStatus(PutByIdStatus::TakesSlowPath);
+                if (status.numVariants() != 1
+                    || status[0].kind() != PutByIdVariant::Replace
+                    || status[0].structure().size() != 1) {
                     addToGraph(PutById, OpInfo(identifierNumber), get(VirtualRegister(scope)), get(VirtualRegister(value)));
                     break;
                 }
-                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structure());
+                ASSERT(status[0].structure().onlyStructure() == structure);
+                Node* base = cellConstantWithStructureCheck(globalObject, structure);
                 addToGraph(Phantom, get(VirtualRegister(scope)));
                 handlePutByOffset(base, identifierNumber, static_cast<PropertyOffset>(operand), get(VirtualRegister(value)));
                 // Keep scope alive until after put.
@@ -3177,21 +3672,32 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             }
             case GlobalVar:
             case GlobalVarWithVarInjectionChecks: {
-                SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
-                ASSERT(watchpoints == entry.watchpointSet());
+                if (watchpoints) {
+                    SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
+                    ASSERT_UNUSED(entry, watchpoints == entry.watchpointSet());
+                }
                 Node* valueNode = get(VirtualRegister(value));
-                addToGraph(PutGlobalVar, OpInfo(operand), valueNode);
-                if (watchpoints->state() != IsInvalidated)
-                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
+                addToGraph(PutGlobalVar, OpInfo(operand), weakJSConstant(globalObject), valueNode);
+                if (watchpoints && watchpoints->state() != IsInvalidated) {
+                    // Must happen after the store. See comment for GetGlobalVar.
+                    addToGraph(NotifyWrite, OpInfo(watchpoints));
+                }
                 // Keep scope alive until after put.
                 addToGraph(Phantom, get(VirtualRegister(scope)));
                 break;
             }
+            case LocalClosureVar:
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
                 Node* scopeNode = get(VirtualRegister(scope));
-                Node* scopeRegisters = addToGraph(GetClosureRegisters, scopeNode);
-                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, get(VirtualRegister(value)));
+                Node* valueNode = get(VirtualRegister(value));
+
+                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, valueNode);
+
+                if (watchpoints && watchpoints->state() != IsInvalidated) {
+                    // Must happen after the store. See comment for GetGlobalVar.
+                    addToGraph(NotifyWrite, OpInfo(watchpoints));
+                }
                 break;
             }
             case Dynamic:
@@ -3221,78 +3727,82 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             NEXT_OPCODE(op_loop_hint);
         }
             
-        case op_init_lazy_reg: {
-            set(VirtualRegister(currentInstruction[1].u.operand), getJSConstantForValue(JSValue()));
-            ASSERT(operandIsLocal(currentInstruction[1].u.operand));
-            m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
-            NEXT_OPCODE(op_init_lazy_reg);
+        case op_create_lexical_environment: {
+            FrozenValue* symbolTable = m_graph.freezeStrong(m_graph.symbolTableFor(currentNodeOrigin().semantic));
+            Node* lexicalEnvironment = addToGraph(CreateActivation, OpInfo(symbolTable), get(VirtualRegister(currentInstruction[2].u.operand)));
+            set(VirtualRegister(currentInstruction[1].u.operand), lexicalEnvironment);
+            set(VirtualRegister(currentInstruction[2].u.operand), lexicalEnvironment);
+            NEXT_OPCODE(op_create_lexical_environment);
         }
             
-        case op_create_activation: {
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand))));
-            NEXT_OPCODE(op_create_activation);
+        case op_get_scope: {
+            // Help the later stages a bit by doing some small constant folding here. Note that this
+            // only helps for the first basic block. It's extremely important not to constant fold
+            // loads from the scope register later, as that would prevent the DFG from tracking the
+            // bytecode-level liveness of the scope register.
+            Node* callee = get(VirtualRegister(JSStack::Callee));
+            Node* result;
+            if (JSFunction* function = callee->dynamicCastConstant<JSFunction*>())
+                result = weakJSConstant(function->scope());
+            else
+                result = addToGraph(GetScope, callee);
+            set(VirtualRegister(currentInstruction[1].u.operand), result);
+            NEXT_OPCODE(op_get_scope);
         }
             
-        case op_create_arguments: {
-            m_graph.m_hasArguments = true;
-            Node* createArguments = addToGraph(CreateArguments, get(VirtualRegister(currentInstruction[1].u.operand)));
+        case op_create_direct_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateDirectArguments);
             set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
-            set(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand)), createArguments);
-            NEXT_OPCODE(op_create_arguments);
+            NEXT_OPCODE(op_create_direct_arguments);
         }
             
-        case op_tear_off_activation: {
-            addToGraph(TearOffActivation, get(VirtualRegister(currentInstruction[1].u.operand)));
-            NEXT_OPCODE(op_tear_off_activation);
+        case op_create_scoped_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateScopedArguments, get(VirtualRegister(currentInstruction[2].u.operand)));
+            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
+            NEXT_OPCODE(op_create_scoped_arguments);
         }
 
-        case op_tear_off_arguments: {
-            m_graph.m_hasArguments = true;
-            addToGraph(TearOffArguments, get(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand))), get(VirtualRegister(currentInstruction[2].u.operand)));
-            NEXT_OPCODE(op_tear_off_arguments);
-        }
-            
-        case op_get_arguments_length: {
-            m_graph.m_hasArguments = true;
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetMyArgumentsLengthSafe));
-            NEXT_OPCODE(op_get_arguments_length);
+        case op_create_out_of_band_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateClonedArguments);
+            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
+            NEXT_OPCODE(op_create_out_of_band_arguments);
         }
             
-        case op_get_argument_by_val: {
-            m_graph.m_hasArguments = true;
+        case op_get_from_arguments: {
             set(VirtualRegister(currentInstruction[1].u.operand),
                 addToGraph(
-                    GetMyArgumentByValSafe, OpInfo(0), OpInfo(getPrediction()),
-                    get(VirtualRegister(currentInstruction[3].u.operand))));
-            NEXT_OPCODE(op_get_argument_by_val);
+                    GetFromArguments,
+                    OpInfo(currentInstruction[3].u.operand),
+                    OpInfo(getPrediction()),
+                    get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_get_from_arguments);
         }
             
-        case op_new_func: {
-            if (!currentInstruction[3].u.operand) {
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    addToGraph(NewFunctionNoCheck, OpInfo(currentInstruction[2].u.operand)));
-            } else {
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    addToGraph(
-                        NewFunction,
-                        OpInfo(currentInstruction[2].u.operand),
-                        get(VirtualRegister(currentInstruction[1].u.operand))));
-            }
-            NEXT_OPCODE(op_new_func);
+        case op_put_to_arguments: {
+            addToGraph(
+                PutToArguments,
+                OpInfo(currentInstruction[2].u.operand),
+                get(VirtualRegister(currentInstruction[1].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand)));
+            NEXT_OPCODE(op_put_to_arguments);
         }
             
-        case op_new_captured_func: {
-            Node* function = addToGraph(
-                NewFunctionNoCheck, OpInfo(currentInstruction[2].u.operand));
-            if (VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet)
-                addToGraph(NotifyWrite, OpInfo(set), function);
-            set(VirtualRegister(currentInstruction[1].u.operand), function);
-            NEXT_OPCODE(op_new_captured_func);
+        case op_new_func: {
+            FunctionExecutable* decl = m_inlineStackTop->m_profiledBlock->functionDecl(currentInstruction[3].u.operand);
+            FrozenValue* frozen = m_graph.freezeStrong(decl);
+            set(VirtualRegister(currentInstruction[1].u.operand),
+                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_new_func);
         }
-            
+
         case op_new_func_exp: {
+            FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand);
+            FrozenValue* frozen = m_graph.freezeStrong(expr);
             set(VirtualRegister(currentInstruction[1].u.operand),
-                addToGraph(NewFunctionExpression, OpInfo(currentInstruction[2].u.operand)));
+                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
             NEXT_OPCODE(op_new_func_exp);
         }
 
@@ -3308,13 +3818,93 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             set(VirtualRegister(currentInstruction[1].u.operand), node);
             NEXT_OPCODE(op_to_number);
         }
-            
+
+        case op_to_string: {
+            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToString, value));
+            NEXT_OPCODE(op_to_string);
+        }
+
         case op_in: {
             set(VirtualRegister(currentInstruction[1].u.operand),
                 addToGraph(In, get(VirtualRegister(currentInstruction[2].u.operand)), get(VirtualRegister(currentInstruction[3].u.operand))));
             NEXT_OPCODE(op_in);
         }
 
+        case op_get_enumerable_length: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumerableLength, 
+                get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_get_enumerable_length);
+        }
+
+        case op_has_generic_property: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasGenericProperty, 
+                get(VirtualRegister(currentInstruction[2].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand))));
+            NEXT_OPCODE(op_has_generic_property);
+        }
+
+        case op_has_structure_property: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasStructureProperty, 
+                get(VirtualRegister(currentInstruction[2].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand)),
+                get(VirtualRegister(currentInstruction[4].u.operand))));
+            NEXT_OPCODE(op_has_structure_property);
+        }
+
+        case op_has_indexed_property: {
+            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
+            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Read);
+            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
+            Node* hasIterableProperty = addToGraph(HasIndexedProperty, OpInfo(arrayMode.asWord()), base, property);
+            set(VirtualRegister(currentInstruction[1].u.operand), hasIterableProperty);
+            NEXT_OPCODE(op_has_indexed_property);
+        }
+
+        case op_get_direct_pname: {
+            SpeculatedType prediction = getPredictionWithoutOSRExit();
+            
+            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
+            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
+            Node* index = get(VirtualRegister(currentInstruction[4].u.operand));
+            Node* enumerator = get(VirtualRegister(currentInstruction[5].u.operand));
+
+            addVarArgChild(base);
+            addVarArgChild(property);
+            addVarArgChild(index);
+            addVarArgChild(enumerator);
+            set(VirtualRegister(currentInstruction[1].u.operand), 
+                addToGraph(Node::VarArg, GetDirectPname, OpInfo(0), OpInfo(prediction)));
+
+            NEXT_OPCODE(op_get_direct_pname);
+        }
+
+        case op_get_property_enumerator: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetPropertyEnumerator, 
+                get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_get_property_enumerator);
+        }
+
+        case op_enumerator_structure_pname: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorStructurePname,
+                get(VirtualRegister(currentInstruction[2].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand))));
+            NEXT_OPCODE(op_enumerator_structure_pname);
+        }
+
+        case op_enumerator_generic_pname: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorGenericPname,
+                get(VirtualRegister(currentInstruction[2].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand))));
+            NEXT_OPCODE(op_enumerator_generic_pname);
+        }
+            
+        case op_to_index_string: {
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToIndexString, 
+                get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_to_index_string);
+        }
+
         default:
             // Parse failed! This should not happen because the capabilities checker
             // should have caught it.
@@ -3328,7 +3918,7 @@ void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BasicBlock*>& possibleT
 {
     ASSERT(!block->isLinked);
     ASSERT(!block->isEmpty());
-    Node* node = block->last();
+    Node* node = block->terminal();
     ASSERT(node->isTerminal());
     
     switch (node->op()) {
@@ -3355,15 +3945,19 @@ void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BasicBlock*>& possibleT
         break;
     }
     
-#if !ASSERT_DISABLED
-    block->isLinked = true;
-#endif
+    if (verbose)
+        dataLog("Marking ", RawPointer(block), " as linked (actually did linking)\n");
+    block->didLink();
 }
 
 void ByteCodeParser::linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets)
 {
     for (size_t i = 0; i < unlinkedBlocks.size(); ++i) {
+        if (verbose)
+            dataLog("Attempting to link ", RawPointer(unlinkedBlocks[i].m_block), "\n");
         if (unlinkedBlocks[i].m_needsNormalLinking) {
+            if (verbose)
+                dataLog("    Does need normal linking.\n");
             linkBlock(unlinkedBlocks[i].m_block, possibleTargets);
             unlinkedBlocks[i].m_needsNormalLinking = false;
         }
@@ -3377,13 +3971,6 @@ void ByteCodeParser::buildOperandMapsIfNecessary()
     
     for (size_t i = 0; i < m_codeBlock->numberOfIdentifiers(); ++i)
         m_identifierMap.add(m_codeBlock->identifier(i).impl(), i);
-    for (size_t i = 0; i < m_codeBlock->numberOfConstantRegisters(); ++i) {
-        JSValue value = m_codeBlock->getConstant(i + FirstConstantRegisterIndex);
-        if (!value)
-            m_emptyJSValueIndex = i + FirstConstantRegisterIndex;
-        else
-            m_jsValueMap.add(JSValue::encode(value), i + FirstConstantRegisterIndex);
-    }
     
     m_haveBuiltOperandMaps = true;
 }
@@ -3397,7 +3984,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
     VirtualRegister returnValueVR,
     VirtualRegister inlineCallFrameStart,
     int argumentCountIncludingThis,
-    CodeSpecializationKind kind)
+    InlineCallFrame::Kind kind)
     : m_byteCodeParser(byteCodeParser)
     , m_codeBlock(codeBlock)
     , m_profiledBlock(profiledBlock)
@@ -3428,12 +4015,6 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
         m_argumentPositions[i] = argumentPosition;
     }
     
-    // Track the code-block-global exit sites.
-    if (m_exitProfile.hasExitSite(ArgumentsEscaped)) {
-        byteCodeParser->m_graph.m_executablesWhoseArgumentsEscaped.add(
-            codeBlock->ownerExecutable());
-    }
-        
     if (m_caller) {
         // Inline case.
         ASSERT(codeBlock != byteCodeParser->m_codeBlock);
@@ -3441,6 +4022,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
         ASSERT(callsiteBlockHead);
         
         m_inlineCallFrame = byteCodeParser->m_graph.m_plan.inlineCallFrames->add();
+        byteCodeParser->m_graph.freeze(codeBlock->ownerExecutable());
         initializeLazyWriteBarrierForInlineCallFrameExecutable(
             byteCodeParser->m_graph.m_plan.writeBarriers,
             m_inlineCallFrame->executable,
@@ -3448,68 +4030,29 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
             m_inlineCallFrame,
             byteCodeParser->m_codeBlock->ownerExecutable(),
             codeBlock->ownerExecutable());
-        m_inlineCallFrame->stackOffset = inlineCallFrameStart.offset() - JSStack::CallFrameHeaderSize;
+        m_inlineCallFrame->setStackOffset(inlineCallFrameStart.offset() - JSStack::CallFrameHeaderSize);
         if (callee) {
             m_inlineCallFrame->calleeRecovery = ValueRecovery::constant(callee);
             m_inlineCallFrame->isClosureCall = false;
         } else
             m_inlineCallFrame->isClosureCall = true;
         m_inlineCallFrame->caller = byteCodeParser->currentCodeOrigin();
-        m_inlineCallFrame->arguments.resize(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet.
-        m_inlineCallFrame->isCall = isCall(kind);
+        m_inlineCallFrame->arguments.resizeToFit(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet.
+        m_inlineCallFrame->kind = kind;
         
-        if (m_inlineCallFrame->caller.inlineCallFrame)
-            m_inlineCallFrame->capturedVars = m_inlineCallFrame->caller.inlineCallFrame->capturedVars;
-        else {
-            for (int i = byteCodeParser->m_codeBlock->m_numVars; i--;) {
-                if (byteCodeParser->m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
-                    m_inlineCallFrame->capturedVars.set(i);
-            }
-        }
-
-        for (int i = argumentCountIncludingThis; i--;) {
-            VirtualRegister argument = virtualRegisterForArgument(i);
-            if (codeBlock->isCaptured(argument))
-                m_inlineCallFrame->capturedVars.set(VirtualRegister(argument.offset() + m_inlineCallFrame->stackOffset).toLocal());
-        }
-        for (size_t i = codeBlock->m_numVars; i--;) {
-            VirtualRegister local = virtualRegisterForLocal(i);
-            if (codeBlock->isCaptured(local))
-                m_inlineCallFrame->capturedVars.set(VirtualRegister(local.offset() + m_inlineCallFrame->stackOffset).toLocal());
-        }
-
         byteCodeParser->buildOperandMapsIfNecessary();
         
         m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
-        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
         m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
         m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
 
         for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) {
-            StringImpl* rep = codeBlock->identifier(i).impl();
+            UniquedStringImpl* rep = codeBlock->identifier(i).impl();
             BorrowedIdentifierMap::AddResult result = byteCodeParser->m_identifierMap.add(rep, byteCodeParser->m_graph.identifiers().numberOfIdentifiers());
             if (result.isNewEntry)
                 byteCodeParser->m_graph.identifiers().addLazily(rep);
             m_identifierRemap[i] = result.iterator->value;
         }
-        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
-            JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex);
-            if (!value) {
-                if (byteCodeParser->m_emptyJSValueIndex == UINT_MAX) {
-                    byteCodeParser->m_emptyJSValueIndex = byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex;
-                    byteCodeParser->addConstant(JSValue());
-                    byteCodeParser->m_constants.append(ConstantRecord());
-                }
-                m_constantRemap[i] = byteCodeParser->m_emptyJSValueIndex;
-                continue;
-            }
-            JSValueMap::AddResult result = byteCodeParser->m_jsValueMap.add(JSValue::encode(value), byteCodeParser->m_codeBlock->numberOfConstantRegisters() + FirstConstantRegisterIndex);
-            if (result.isNewEntry) {
-                byteCodeParser->addConstant(value);
-                byteCodeParser->m_constants.append(ConstantRecord());
-            }
-            m_constantRemap[i] = result.iterator->value;
-        }
         for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
             // If we inline the same code block multiple times, we don't want to needlessly
             // duplicate its constant buffers.
@@ -3540,13 +4083,10 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
         m_inlineCallFrame = 0;
 
         m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
-        m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
         m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
         m_switchRemap.resize(codeBlock->numberOfSwitchJumpTables());
         for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
             m_identifierRemap[i] = i;
-        for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
-            m_constantRemap[i] = i + FirstConstantRegisterIndex;
         for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
             m_constantBufferRemap[i] = i;
         for (size_t i = 0; i < codeBlock->numberOfSwitchJumpTables(); ++i)
@@ -3554,14 +4094,13 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
         m_callsiteBlockHeadNeedsLinking = false;
     }
     
-    for (size_t i = 0; i < m_constantRemap.size(); ++i)
-        ASSERT(m_constantRemap[i] >= static_cast<unsigned>(FirstConstantRegisterIndex));
-    
     byteCodeParser->m_inlineStackTop = this;
 }
 
 void ByteCodeParser::parseCodeBlock()
 {
+    clearCaches();
+    
     CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
     
     if (m_graph.compilation()) {
@@ -3569,8 +4108,16 @@ void ByteCodeParser::parseCodeBlock()
             *m_vm->m_perBytecodeProfiler, m_inlineStackTop->m_profiledBlock);
     }
     
-    bool shouldDumpBytecode = Options::dumpBytecodeAtDFGTime();
-    if (shouldDumpBytecode) {
+    if (UNLIKELY(Options::dumpSourceAtDFGTime())) {
+        Vector<DeferredSourceDump>& deferredSourceDump = m_graph.m_plan.callback->ensureDeferredSourceDump();
+        if (inlineCallFrame()) {
+            DeferredSourceDump dump(codeBlock->baselineVersion(), m_codeBlock, JITCode::DFGJIT, inlineCallFrame()->caller);
+            deferredSourceDump.append(dump);
+        } else
+            deferredSourceDump.append(DeferredSourceDump(codeBlock->baselineVersion()));
+    }
+
+    if (Options::dumpBytecodeAtDFGTime()) {
         dataLog("Parsing ", *codeBlock);
         if (inlineCallFrame()) {
             dataLog(
@@ -3578,8 +4125,7 @@ void ByteCodeParser::parseCodeBlock()
                 " ", inlineCallFrame()->caller);
         }
         dataLog(
-            ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
-            ", needsActivation = ", codeBlock->needsActivation(),
+            ": needsActivation = ", codeBlock->needsActivation(),
             ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
         codeBlock->baselineVersion()->dumpBytecode();
     }
@@ -3626,7 +4172,12 @@ void ByteCodeParser::parseCodeBlock()
                     // 2) If the bytecodeBegin is equal to the currentIndex, then we failed to do
                     //    a peephole coalescing of this block in the if statement above. So, we're
                     //    generating suboptimal code and leaving more work for the CFG simplifier.
-                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_inlineStackTop->m_unlinkedBlocks.last().m_block->bytecodeBegin < m_currentIndex);
+                    if (!m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
+                        unsigned lastBegin =
+                            m_inlineStackTop->m_unlinkedBlocks.last().m_block->bytecodeBegin;
+                        ASSERT_UNUSED(
+                            lastBegin, lastBegin == UINT_MAX || lastBegin < m_currentIndex);
+                    }
                     m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
                     m_inlineStackTop->m_blockLinkingTargets.append(block.get());
                     // The first block is definitely an OSR target.
@@ -3647,10 +4198,13 @@ void ByteCodeParser::parseCodeBlock()
             // are at the end of an inline function, or we realized that we
             // should stop parsing because there was a return in the first
             // basic block.
-            ASSERT(m_currentBlock->isEmpty() || m_currentBlock->last()->isTerminal() || (m_currentIndex == codeBlock->instructions().size() && inlineCallFrame()) || !shouldContinueParsing);
+            ASSERT(m_currentBlock->isEmpty() || m_currentBlock->terminal() || (m_currentIndex == codeBlock->instructions().size() && inlineCallFrame()) || !shouldContinueParsing);
 
-            if (!shouldContinueParsing)
+            if (!shouldContinueParsing) {
+                if (Options::verboseDFGByteCodeParsing())
+                    dataLog("Done parsing ", *codeBlock, "\n");
                 return;
+            }
             
             m_currentBlock = 0;
         } while (m_currentIndex < limit);
@@ -3658,6 +4212,9 @@ void ByteCodeParser::parseCodeBlock()
 
     // Should have reached the end of the instructions.
     ASSERT(m_currentIndex == codeBlock->instructions().size());
+    
+    if (Options::verboseDFGByteCodeParsing())
+        dataLog("Done parsing ", *codeBlock, " (fell off end)\n");
 }
 
 bool ByteCodeParser::parse()
@@ -3677,25 +4234,9 @@ bool ByteCodeParser::parse()
             m_dfgCodeBlock->getStubInfoMap(m_dfgStubInfos);
     }
     
-    if (m_codeBlock->captureCount()) {
-        SymbolTable* symbolTable = m_codeBlock->symbolTable();
-        ConcurrentJITLocker locker(symbolTable->m_lock);
-        SymbolTable::Map::iterator iter = symbolTable->begin(locker);
-        SymbolTable::Map::iterator end = symbolTable->end(locker);
-        for (; iter != end; ++iter) {
-            VariableWatchpointSet* set = iter->value.watchpointSet();
-            if (!set)
-                continue;
-            size_t index = static_cast<size_t>(VirtualRegister(iter->value.getIndex()).toLocal());
-            while (m_localWatchpoints.size() <= index)
-                m_localWatchpoints.append(nullptr);
-            m_localWatchpoints[index] = set;
-        }
-    }
-    
     InlineStackEntry inlineStackEntry(
         this, m_codeBlock, m_profiledBlock, 0, 0, VirtualRegister(), VirtualRegister(),
-        m_codeBlock->numParameters(), CodeForCall);
+        m_codeBlock->numParameters(), InlineCallFrame::Call);
     
     parseCodeBlock();
 
index cb8626998bec62107e798498f3d2c21c05e2cd6e..bd6888d70acfdb49d26ca4ef8fcf117e605c6061 100644 (file)
 
 #if ENABLE(DFG_JIT)
 
-#include "DFGGraph.h"
+namespace JSC { namespace DFG {
 
-namespace JSC {
+class Graph;
 
-class CodeBlock;
-class VM;
-
-namespace DFG {
-
-// Populate the Graph with a basic block of code from the CodeBlock,
-// starting at the provided bytecode index.
 bool parse(Graph&);
 
 } } // namespace JSC::DFG
index 5f69de18609c3101f42f87f25db237b141dce6d7..6bf4759ce5c13c8106e4417f8a1eaf930d7f60d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -79,6 +79,59 @@ public:
             performForwardCFA();
         } while (m_changed);
         
+        if (m_graph.m_form != SSA) {
+            ASSERT(!m_changed);
+            
+            // Widen the abstract values at the block that serves as the must-handle OSR entry.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                
+                if (!block->isOSRTarget)
+                    continue;
+                if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
+                    continue;
+                
+                bool changed = false;
+                for (size_t i = m_graph.m_plan.mustHandleValues.size(); i--;) {
+                    int operand = m_graph.m_plan.mustHandleValues.operandForIndex(i);
+                    JSValue value = m_graph.m_plan.mustHandleValues[i];
+                    Node* node = block->variablesAtHead.operand(operand);
+                    if (!node)
+                        continue;
+                    
+                    AbstractValue& target = block->valuesAtHead.operand(operand);
+                    changed |= target.mergeOSREntryValue(m_graph, value);
+                    target.fixTypeForRepresentation(
+                        m_graph, resultFor(node->variableAccessData()->flushFormat()));
+                }
+                
+                if (changed || !block->cfaHasVisited) {
+                    m_changed = true;
+                    block->cfaShouldRevisit = true;
+                }
+            }
+
+            // Propagate any of the changes we just introduced.
+            while (m_changed) {
+                m_changed = false;
+                performForwardCFA();
+            }
+            
+            // Make sure we record the intersection of all proofs that we ever allowed the
+            // compiler to rely upon.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                
+                block->intersectionOfCFAHasVisited &= block->cfaHasVisited;
+                for (unsigned i = block->intersectionOfPastValuesAtHead.size(); i--;)
+                    block->intersectionOfPastValuesAtHead[i].filter(block->valuesAtHead[i]);
+            }
+        }
+        
         return true;
     }
     
@@ -92,8 +145,11 @@ private:
         if (m_verbose)
             dataLog("   Block ", *block, ":\n");
         m_state.beginBasicBlock(block);
-        if (m_verbose)
+        if (m_verbose) {
             dataLog("      head vars: ", block->valuesAtHead, "\n");
+            if (m_graph.m_form == SSA)
+                dataLog("      head regs: ", mapDump(block->ssa->valuesAtHead), "\n");
+        }
         for (unsigned i = 0; i < block->size(); ++i) {
             if (m_verbose) {
                 Node* node = block->at(i);
@@ -102,10 +158,8 @@ private:
                 if (!safeToExecute(m_state, m_graph, node))
                     dataLog("(UNSAFE) ");
                 
-                m_interpreter.dump(WTF::dataFile());
+                dataLog(m_state.variables(), " ", m_interpreter);
                 
-                if (m_state.haveStructures())
-                    dataLog(" (Have Structures)");
                 dataLogF("\n");
             }
             if (!m_interpreter.execute(i)) {
@@ -121,8 +175,11 @@ private:
         }
         m_changed |= m_state.endBasicBlock(MergeToSuccessors);
         
-        if (m_verbose)
+        if (m_verbose) {
             dataLog("      tail vars: ", block->valuesAtTail, "\n");
+            if (m_graph.m_form == SSA)
+                dataLog("      head regs: ", mapDump(block->ssa->valuesAtTail), "\n");
+        }
     }
     
     void performForwardCFA()
index 8d29fbc28cae4b6421ff5c65b27394c497b2b271..34a13362460f45dd63f5695c818c936926036271 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,7 +59,7 @@ public:
                     continue;
                 ASSERT(block->isReachable);
             
-                switch (block->last()->op()) {
+                switch (block->terminal()->op()) {
                 case Jump: {
                     // Successor with one predecessor -> merge.
                     if (block->successor(0)->predecessors.size() == 1) {
@@ -99,17 +99,19 @@ public:
                             if (extremeLogging)
                                 m_graph.dump();
                             m_graph.dethread();
-                        
-                            ASSERT(block->last()->isTerminal());
-                            NodeOrigin boundaryNodeOrigin = block->last()->origin;
-                            block->last()->convertToPhantom();
-                            ASSERT(block->last()->refCount() == 1);
-                        
+                            
+                            Node* terminal = block->terminal();
+                            ASSERT(terminal->isTerminal());
+                            NodeOrigin boundaryNodeOrigin = terminal->origin;
+
                             jettisonBlock(block, jettisonedBlock, boundaryNodeOrigin);
-                        
-                            block->appendNode(
+
+                            block->replaceTerminal(
                                 m_graph, SpecNone, Jump, boundaryNodeOrigin,
                                 OpInfo(targetBlock));
+                            
+                            ASSERT(block->terminal());
+                        
                         }
                         innerChanged = outerChanged = true;
                         break;
@@ -129,7 +131,7 @@ public:
                 }
                     
                 case Switch: {
-                    SwitchData* data = block->last()->switchData();
+                    SwitchData* data = block->terminal()->switchData();
                     
                     // Prune out cases that end up jumping to default.
                     for (unsigned i = 0; i < data->cases.size(); ++i) {
@@ -149,8 +151,9 @@ public:
                     }
                     
                     // Switch on constant -> jettison all other targets and merge.
-                    if (block->last()->child1()->hasConstant()) {
-                        JSValue value = m_graph.valueOfJSConstant(block->last()->child1().node());
+                    Node* terminal = block->terminal();
+                    if (terminal->child1()->hasConstant()) {
+                        FrozenValue* value = terminal->child1()->constant();
                         TriState found = FalseTriState;
                         BasicBlock* targetBlock = 0;
                         for (unsigned i = data->cases.size(); found == FalseTriState && i--;) {
@@ -166,10 +169,9 @@ public:
                         ASSERT(targetBlock);
                         
                         Vector<BasicBlock*, 1> jettisonedBlocks;
-                        for (unsigned i = block->numSuccessors(); i--;) {
-                            BasicBlock* jettisonedBlock = block->successor(i);
-                            if (jettisonedBlock != targetBlock)
-                                jettisonedBlocks.append(jettisonedBlock);
+                        for (BasicBlock* successor : terminal->successors()) {
+                            if (successor != targetBlock)
+                                jettisonedBlocks.append(successor);
                         }
                         
                         if (targetBlock->predecessors.size() == 1) {
@@ -183,11 +185,12 @@ public:
                                 m_graph.dump();
                             m_graph.dethread();
                             
-                            NodeOrigin boundaryNodeOrigin = block->last()->origin;
-                            block->last()->convertToPhantom();
+                            NodeOrigin boundaryNodeOrigin = terminal->origin;
+
                             for (unsigned i = jettisonedBlocks.size(); i--;)
                                 jettisonBlock(block, jettisonedBlocks[i], boundaryNodeOrigin);
-                            block->appendNode(
+                            
+                            block->replaceTerminal(
                                 m_graph, SpecNone, Jump, boundaryNodeOrigin, OpInfo(targetBlock));
                         }
                         innerChanged = outerChanged = true;
@@ -253,13 +256,10 @@ private:
             m_graph.dethread();
             mergeBlocks(block, targetBlock, noBlocks());
         } else {
-            Node* branch = block->last();
-            ASSERT(branch->isTerminal());
+            Node* branch = block->terminal();
             ASSERT(branch->op() == Branch || branch->op() == Switch);
-            branch->convertToPhantom();
-            ASSERT(branch->refCount() == 1);
-            
-            block->appendNode(
+
+            block->replaceTerminal(
                 m_graph, SpecNone, Jump, branch->origin, OpInfo(targetBlock));
         }
     }
@@ -272,8 +272,13 @@ private:
         NodeType nodeType;
         if (livenessNode->flags() & NodeIsFlushed)
             nodeType = Flush;
-        else
+        else {
+            // This seems like it shouldn't be necessary because we could just rematerialize
+            // PhantomLocals or something similar using bytecode liveness. However, in ThreadedCPS, it's
+            // worth the sanity to maintain this eagerly. See
+            // https://bugs.webkit.org/show_bug.cgi?id=144086
             nodeType = PhantomLocal;
+        }
         block->appendNode(
             m_graph, SpecNone, nodeType, nodeOrigin, 
             OpInfo(livenessNode->variableAccessData()));
@@ -317,11 +322,12 @@ private:
         // kept alive.
         
         // Remove the terminal of firstBlock since we don't need it anymore. Well, we don't
-        // really remove it; we actually turn it into a Phantom.
-        ASSERT(firstBlock->last()->isTerminal());
-        NodeOrigin boundaryNodeOrigin = firstBlock->last()->origin;
-        firstBlock->last()->convertToPhantom();
-        ASSERT(firstBlock->last()->refCount() == 1);
+        // really remove it; we actually turn it into a check.
+        Node* terminal = firstBlock->terminal();
+        ASSERT(terminal->isTerminal());
+        NodeOrigin boundaryNodeOrigin = terminal->origin;
+        terminal->remove();
+        ASSERT(terminal->refCount() == 1);
         
         for (unsigned i = jettisonedBlocks.size(); i--;) {
             BasicBlock* jettisonedBlock = jettisonedBlocks[i];
@@ -342,7 +348,7 @@ private:
         for (size_t i = 0; i < secondBlock->size(); ++i)
             firstBlock->append(secondBlock->at(i));
         
-        ASSERT(firstBlock->last()->isTerminal());
+        ASSERT(firstBlock->terminal()->isTerminal());
         
         // Fix the predecessors of my new successors. This is tricky, since we are going to reset
         // all predecessors anyway due to reachability analysis. But we need to fix the
index 076ba250e47356d6c4e6fd4ce416d44ecd8a5f99..09dbf328bda4c80a47ecc1a854bc6f62e3102455 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,6 +53,7 @@ public:
         freeUnnecessaryNodes();
         m_graph.clearReplacements();
         canonicalizeLocalsInBlocks();
+        specialCaseArguments();
         propagatePhis<LocalOperand>();
         propagatePhis<ArgumentOperand>();
         computeIsFlushed();
@@ -90,13 +91,15 @@ private:
                     node->children.setChild1(Edge());
                     break;
                 case Phantom:
-                    if (!node->child1())
+                    if (!node->child1()) {
+                        m_graph.m_allocator.free(node);
                         continue;
+                    }
                     switch (node->child1()->op()) {
                     case Phi:
                     case SetArgument:
                     case SetLocal:
-                        node->convertToPhantomLocal();
+                        node->convertPhantomToPhantomLocal();
                         break;
                     default:
                         ASSERT(node->child1()->hasResult());
@@ -117,15 +120,15 @@ private:
     }
     
     template<OperandKind operandKind>
-    void clearVariablesAtHeadAndTail()
+    void clearVariables()
     {
         ASSERT(
             m_block->variablesAtHead.sizeFor<operandKind>()
             == m_block->variablesAtTail.sizeFor<operandKind>());
         
         for (unsigned i = m_block->variablesAtHead.sizeFor<operandKind>(); i--;) {
-            m_block->variablesAtHead.atFor<operandKind>(i) = 0;
-            m_block->variablesAtTail.atFor<operandKind>(i) = 0;
+            m_block->variablesAtHead.atFor<operandKind>(i) = nullptr;
+            m_block->variablesAtTail.atFor<operandKind>(i) = nullptr;
         }
     }
     
@@ -184,29 +187,14 @@ private:
                 return;
             }
             
-            if (variable->isCaptured()) {
-                variable->setIsLoadedFrom(true);
-                if (otherNode->op() == GetLocal)
-                    otherNode = otherNode->child1().node();
-                else
-                    ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument);
-                
-                ASSERT(otherNode->op() == Phi || otherNode->op() == SetLocal || otherNode->op() == SetArgument);
-                
-                // Keep this GetLocal but link it to the prior ones.
-                node->children.setChild1(Edge(otherNode));
-                m_block->variablesAtTail.atFor<operandKind>(idx) = node;
-                return;
-            }
-            
             if (otherNode->op() == GetLocal) {
                 // Replace all references to this GetLocal with otherNode.
-                node->misc.replacement = otherNode;
+                node->replaceWith(otherNode);
                 return;
             }
             
             ASSERT(otherNode->op() == SetLocal);
-            node->misc.replacement = otherNode->child1().node();
+            node->replaceWith(otherNode->child1().node());
             return;
         }
         
@@ -226,11 +214,6 @@ private:
             canonicalizeGetLocalFor<LocalOperand>(node, variable, variable->local().toLocal());
     }
     
-    void canonicalizeSetLocal(Node* node)
-    {
-        m_block->variablesAtTail.setOperand(node->local(), node);
-    }
-    
     template<NodeType nodeType, OperandKind operandKind>
     void canonicalizeFlushOrPhantomLocalFor(Node* node, VariableAccessData* variable, size_t idx)
     {
@@ -257,13 +240,9 @@ private:
                 // for the purpose of OSR. PhantomLocal(SetLocal) means: at this point I
                 // know that I would have read the value written by that SetLocal. This is
                 // redundant and inefficient, since really it just means that we want to
-                // be keeping the operand to the SetLocal alive. The SetLocal may die, and
-                // we'll be fine because OSR tracks dead SetLocals.
-                
-                // So we turn this into a Phantom on the child of the SetLocal.
+                // keep the last MovHinted value of that local alive.
                 
-                node->convertToPhantom();
-                node->children.setChild1(otherNode->child1());
+                node->remove();
                 return;
             }
             
@@ -294,13 +273,9 @@ private:
             canonicalizeFlushOrPhantomLocalFor<nodeType, LocalOperand>(node, variable, variable->local().toLocal());
     }
     
-    void canonicalizeSetArgument(Node* node)
+    void canonicalizeSet(Node* node)
     {
-        VirtualRegister local = node->local();
-        ASSERT(local.isArgument());
-        int argument = local.toArgument();
-        m_block->variablesAtHead.setArgumentFirstTime(argument, node);
-        m_block->variablesAtTail.setArgumentFirstTime(argument, node);
+        m_block->variablesAtTail.setOperand(node->local(), node);
     }
     
     void canonicalizeLocalsInBlock()
@@ -309,8 +284,8 @@ private:
             return;
         ASSERT(m_block->isReachable);
         
-        clearVariablesAtHeadAndTail<ArgumentOperand>();
-        clearVariablesAtHeadAndTail<LocalOperand>();
+        clearVariables<ArgumentOperand>();
+        clearVariables<LocalOperand>();
         
         // Assumes that all phi references have been removed. Assumes that things that
         // should be live have a non-zero ref count, but doesn't assume that the ref
@@ -339,10 +314,8 @@ private:
             // there ever was a SetLocal and it was followed by Flushes, then the tail
             // variable will be a SetLocal and not those subsequent Flushes.
             //
-            // Child of GetLocal: the operation that the GetLocal keeps alive. For
-            // uncaptured locals, it may be a Phi from the current block. For arguments,
-            // it may be a SetArgument. For captured locals and arguments it may also be
-            // a SetLocal.
+            // Child of GetLocal: the operation that the GetLocal keeps alive. It may be
+            // a Phi from the current block. For arguments, it may be a SetArgument.
             //
             // Child of SetLocal: must be a value producing node.
             //
@@ -365,7 +338,7 @@ private:
                 break;
                 
             case SetLocal:
-                canonicalizeSetLocal(node);
+                canonicalizeSet(node);
                 break;
                 
             case Flush:
@@ -377,7 +350,7 @@ private:
                 break;
                 
             case SetArgument:
-                canonicalizeSetArgument(node);
+                canonicalizeSet(node);
                 break;
                 
             default:
@@ -396,6 +369,16 @@ private:
         }
     }
     
+    void specialCaseArguments()
+    {
+        // Normally, a SetArgument denotes the start of a live range for a local's value on the stack.
+        // But those SetArguments used for the actual arguments to the machine CodeBlock get
+        // special-cased. We could have instead used two different node types - one for the arguments
+        // at the prologue case, and another for the other uses. But this seemed like IR overkill.
+        for (unsigned i = m_graph.m_arguments.size(); i--;)
+            m_graph.block(0)->variablesAtHead.setArgumentFirstTime(i, m_graph.m_arguments[i]);
+    }
+    
     template<OperandKind operandKind>
     void propagatePhis()
     {
@@ -500,8 +483,21 @@ private:
         }
         while (!m_flushedLocalOpWorklist.isEmpty()) {
             Node* node = m_flushedLocalOpWorklist.takeLast();
-            ASSERT(node->flags() & NodeIsFlushed);
-            DFG_NODE_DO_TO_CHILDREN(m_graph, node, addFlushedLocalEdge);
+            switch (node->op()) {
+            case SetLocal:
+            case SetArgument:
+                break;
+                
+            case Flush:
+            case Phi:
+                ASSERT(node->flags() & NodeIsFlushed);
+                DFG_NODE_DO_TO_CHILDREN(m_graph, node, addFlushedLocalEdge);
+                break;
+
+            default:
+                DFG_CRASH(m_graph, node, "Invalid node in flush graph");
+                break;
+            }
         }
     }
     
index d4e1023d048c99998e342cb6540cd51da61e89a2..a3b8676166d1da3fe188bfd73828dc82c5ab2e5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,8 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAbstractHeap.h"
+#include "DFGBlockMapInlines.h"
+#include "DFGClobberSet.h"
 #include "DFGClobberize.h"
 #include "DFGEdgeUsesStructure.h"
 #include "DFGGraph.h"
 
 namespace JSC { namespace DFG {
 
-enum CSEMode { NormalCSE, StoreElimination };
+// This file contains two CSE implementations: local and global. LocalCSE typically runs when we're
+// in DFG mode, i.e. we want to compile quickly. LocalCSE contains a lot of optimizations for
+// compile time. GlobalCSE, on the other hand, is fairly straight-forward. It will find more
+// optimization opportunities by virtue of being global.
 
-template<CSEMode cseMode>
-class CSEPhase : public Phase {
+namespace {
+
+const bool verbose = false;
+
+class ClobberFilter {
 public:
-    CSEPhase(Graph& graph)
-        : Phase(graph, cseMode == NormalCSE ? "common subexpression elimination" : "store elimination")
+    ClobberFilter(AbstractHeap heap)
+        : m_heap(heap)
+    {
+    }
+    
+    bool operator()(const ImpureMap::KeyValuePairType& pair) const
+    {
+        return m_heap.overlaps(pair.key.heap());
+    }
+    
+private:
+    AbstractHeap m_heap;
+};
+
+inline void clobber(ImpureMap& map, AbstractHeap heap)
+{
+    ClobberFilter filter(heap);
+    map.removeIf(filter);
+}
+
+class LocalCSEPhase : public Phase {
+public:
+    LocalCSEPhase(Graph& graph)
+        : Phase(graph, "local common subexpression elimination")
+        , m_smallBlock(graph)
+        , m_largeBlock(graph)
     {
     }
     
     bool run()
     {
-        ASSERT(m_graph.m_fixpointState != BeforeFixpoint);
+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        ASSERT(m_graph.m_form == ThreadedCPS || m_graph.m_form == LoadStore);
         
-        m_changed = false;
+        bool changed = false;
         
         m_graph.clearReplacements();
         
@@ -62,1477 +95,621 @@ public:
             if (!block)
                 continue;
             
-            // All Phis need to already be marked as relevant to OSR.
-            if (!ASSERT_DISABLED) {
-                for (unsigned i = 0; i < block->phis.size(); ++i)
-                    ASSERT(block->phis[i]->flags() & NodeRelevantToOSR);
-            }
-            
-            for (unsigned i = block->size(); i--;) {
-                Node* node = block->at(i);
-                
-                switch (node->op()) {
-                case SetLocal:
-                case GetLocal: // FIXME: The GetLocal case is only necessary until we do https://bugs.webkit.org/show_bug.cgi?id=106707.
-                    node->mergeFlags(NodeRelevantToOSR);
-                    break;
-                default:
-                    node->clearFlags(NodeRelevantToOSR);
-                    break;
-                }
-            }
+            if (block->size() <= SmallMaps::capacity)
+                changed |= m_smallBlock.run(block);
+            else
+                changed |= m_largeBlock.run(block);
         }
         
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            
-            for (unsigned i = block->size(); i--;) {
-                Node* node = block->at(i);
-                if (!node->containsMovHint())
-                    continue;
-                
-                ASSERT(node->op() != ZombieHint);
-                node->child1()->mergeFlags(NodeRelevantToOSR);
-            }
-        }
-        
-        if (m_graph.m_form == SSA) {
-            Vector<BasicBlock*> depthFirst;
-            m_graph.getBlocksInDepthFirstOrder(depthFirst);
-            for (unsigned i = 0; i < depthFirst.size(); ++i)
-                performBlockCSE(depthFirst[i]);
-        } else {
-            for (unsigned blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
-                performBlockCSE(m_graph.block(blockIndex));
-        }
-        
-        return m_changed;
+        return changed;
     }
     
 private:
+    class SmallMaps {
+    public:
+        // This permits SmallMaps to be used for blocks that have up to 100 nodes. In practice,
+        // fewer than half of the nodes in a block have pure defs, and even fewer have impure defs.
+        // Thus, a capacity limit of 100 probably means that somewhere around ~40 things may end up
+        // in one of these "small" list-based maps. That number still seems largeish, except that
+        // the overhead of HashMaps can be quite high currently: clearing them, or even removing
+        // enough things from them, deletes (or resizes) their backing store eagerly. Hence
+        // HashMaps induce a lot of malloc traffic.
+        static const unsigned capacity = 100;
     
-    unsigned endIndexForPureCSE()
-    {
-        unsigned result = m_lastSeen[m_currentNode->op()];
-        if (result == UINT_MAX)
-            result = 0;
-        else
-            result++;
-        ASSERT(result <= m_indexInBlock);
-        return result;
-    }
-
-    Node* pureCSE(Node* node)
-    {
-        Edge child1 = node->child1().sanitized();
-        Edge child2 = node->child2().sanitized();
-        Edge child3 = node->child3().sanitized();
-        
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock->at(i);
-            if (otherNode == child1 || otherNode == child2 || otherNode == child3)
-                break;
-
-            if (node->op() != otherNode->op())
-                continue;
-            
-            Edge otherChild = otherNode->child1().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child1)
-                continue;
-            
-            otherChild = otherNode->child2().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child2)
-                continue;
-            
-            otherChild = otherNode->child3().sanitized();
-            if (!otherChild)
-                return otherNode;
-            if (otherChild != child3)
-                continue;
-            
-            return otherNode;
-        }
-        return 0;
-    }
-    
-    Node* constantCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock->at(i);
-            if (otherNode->op() != node->op())
-                continue;
-            
-            if (otherNode->constantNumber() != node->constantNumber())
-                continue;
-            
-            return otherNode;
-        }
-        return 0;
-    }
-    
-    Node* weakConstantCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock->at(i);
-            if (otherNode->op() != WeakJSConstant)
-                continue;
-            
-            if (otherNode->weakConstant() != node->weakConstant())
-                continue;
-            
-            return otherNode;
-        }
-        return 0;
-    }
-    
-    Node* constantStoragePointerCSE(Node* node)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* otherNode = m_currentBlock->at(i);
-            if (otherNode->op() != ConstantStoragePointer)
-                continue;
-            
-            if (otherNode->storagePointer() != node->storagePointer())
-                continue;
-            
-            return otherNode;
+        SmallMaps()
+            : m_pureLength(0)
+            , m_impureLength(0)
+        {
         }
-        return 0;
-    }
     
-    Node* getCalleeLoadElimination()
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetCallee:
-                return node;
-            default:
-                break;
-            }
+        void clear()
+        {
+            m_pureLength = 0;
+            m_impureLength = 0;
         }
-        return 0;
-    }
     
-    Node* getArrayLengthElimination(Node* array)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetArrayLength:
-                if (node->child1() == array)
-                    return node;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                if (node->arrayMode().mayStoreToHole())
-                    return 0;
-                break;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
+        void write(AbstractHeap heap)
+        {
+            for (unsigned i = 0; i < m_impureLength; ++i) {
+                if (heap.overlaps(m_impureMap[i].key.heap()))
+                    m_impureMap[i--] = m_impureMap[--m_impureLength];
             }
         }
-        return 0;
-    }
     
-    Node* globalVarLoadElimination(WriteBarrier<Unknown>* registerPointer)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return node;
-                break;
-            case PutGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return node->child1().node();
-                break;
-            default:
-                break;
+        Node* addPure(PureValue value, Node* node)
+        {
+            for (unsigned i = m_pureLength; i--;) {
+                if (m_pureMap[i].key == value)
+                    return m_pureMap[i].value;
             }
-            if (m_graph.clobbersWorld(node))
-                break;
+        
+            ASSERT(m_pureLength < capacity);
+            m_pureMap[m_pureLength++] = WTF::KeyValuePair<PureValue, Node*>(value, node);
+            return nullptr;
         }
-        return 0;
-    }
-    
-    Node* scopedVarLoadElimination(Node* registers, int varNumber)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetClosureVar: {
-                if (node->child1() == registers && node->varNumber() == varNumber)
-                    return node;
-                break;
-            } 
-            case PutClosureVar: {
-                if (node->varNumber() != varNumber)
-                    break;
-                if (node->child2() == registers)
-                    return node->child3().node();
-                return 0;
-            }
-            case SetLocal: {
-                VariableAccessData* variableAccessData = node->variableAccessData();
-                if (variableAccessData->isCaptured()
-                    && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
-                    return 0;
-                break;
-            }
-            default:
-                break;
+        
+        LazyNode findReplacement(HeapLocation location)
+        {
+            for (unsigned i = m_impureLength; i--;) {
+                if (m_impureMap[i].key == location)
+                    return m_impureMap[i].value;
             }
-            if (m_graph.clobbersWorld(node))
-                break;
-        }
-        return 0;
-    }
-    
-    bool varInjectionWatchpointElimination()
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node->op() == VarInjectionWatchpoint)
-                return true;
-            if (m_graph.clobbersWorld(node))
-                break;
+            return nullptr;
         }
-        return false;
-    }
     
-    Node* globalVarStoreElimination(WriteBarrier<Unknown>* registerPointer)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case PutGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return node;
-                break;
-                
-            case GetGlobalVar:
-                if (node->registerPointer() == registerPointer)
-                    return 0;
-                break;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
+        LazyNode addImpure(HeapLocation location, LazyNode node)
+        {
+            // FIXME: If we are using small maps, we must not def() derived values.
+            // For now the only derived values we def() are constant-based.
+            if (location.index() && !location.index().isNode())
+                return nullptr;
+            if (LazyNode result = findReplacement(location))
+                return result;
+            ASSERT(m_impureLength < capacity);
+            m_impureMap[m_impureLength++] = WTF::KeyValuePair<HeapLocation, LazyNode>(location, node);
+            return nullptr;
         }
-        return 0;
-    }
     
-    Node* scopedVarStoreElimination(Node* scope, Node* registers, int varNumber)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case PutClosureVar: {
-                if (node->varNumber() != varNumber)
-                    break;
-                if (node->child1() == scope && node->child2() == registers)
-                    return node;
-                return 0;
-            }
-                
-            case GetClosureVar: {
-                // Let's be conservative.
-                if (node->varNumber() == varNumber)
-                    return 0;
-                break;
-            }
-                
-            case GetLocal:
-            case SetLocal: {
-                VariableAccessData* variableAccessData = node->variableAccessData();
-                if (variableAccessData->isCaptured()
-                    && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
-                    return 0;
-                break;
-            }
+    private:
+        WTF::KeyValuePair<PureValue, Node*> m_pureMap[capacity];
+        WTF::KeyValuePair<HeapLocation, LazyNode> m_impureMap[capacity];
+        unsigned m_pureLength;
+        unsigned m_impureLength;
+    };
 
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
+    class LargeMaps {
+    public:
+        LargeMaps()
+        {
         }
-        return 0;
-    }
     
-    Node* getByValLoadElimination(Node* child1, Node* child2, ArrayMode arrayMode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1 || node == child2) 
-                break;
-
-            switch (node->op()) {
-            case GetByVal:
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                if (node->child1() == child1
-                    && node->child2() == child2
-                    && node->arrayMode().type() == arrayMode.type())
-                    return node;
-                break;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias: {
-                if (!m_graph.byValIsPure(node))
-                    return 0;
-                // Typed arrays 
-                if (arrayMode.typedArrayType() != NotTypedArray)
-                    return 0;
-                if (m_graph.varArgChild(node, 0) == child1
-                    && m_graph.varArgChild(node, 1) == child2
-                    && node->arrayMode().type() == arrayMode.type())
-                    return m_graph.varArgChild(node, 2).node();
-                // We must assume that the PutByVal will clobber the location we're getting from.
-                // FIXME: We can do better; if we know that the PutByVal is accessing an array of a
-                // different type than the GetByVal, then we know that they won't clobber each other.
-                // ... except of course for typed arrays, where all typed arrays clobber all other
-                // typed arrays!  An Int32Array can alias a Float64Array for example, and so on.
-                return 0;
-            }
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
+        void clear()
+        {
+            m_pureMap.clear();
+            m_impureMap.clear();
         }
-        return 0;
-    }
-
-    bool checkFunctionElimination(JSCell* function, Node* child1)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
-
-            if (node->op() == CheckFunction && node->child1() == child1 && node->function() == function)
-                return true;
+    
+        void write(AbstractHeap heap)
+        {
+            clobber(m_impureMap, heap);
         }
-        return false;
-    }
     
-    bool checkExecutableElimination(ExecutableBase* executable, Node* child1)
-    {
-        for (unsigned i = endIndexForPureCSE(); i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1)
-                break;
-
-            if (node->op() == CheckExecutable && node->child1() == child1 && node->executable() == executable)
-                return true;
+        Node* addPure(PureValue value, Node* node)
+        {
+            auto result = m_pureMap.add(value, node);
+            if (result.isNewEntry)
+                return nullptr;
+            return result.iterator->value;
         }
-        return false;
-    }
-
-    bool checkStructureElimination(const StructureSet& structureSet, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
-
-            switch (node->op()) {
-            case CheckStructure:
-                if (node->child1() == child1
-                    && structureSet.isSupersetOf(node->structureSet()))
-                    return true;
-                break;
-                
-            case StructureTransitionWatchpoint:
-                if (node->child1() == child1
-                    && structureSet.contains(node->structure()))
-                    return true;
-                break;
-                
-            case PutStructure:
-                if (node->child1() == child1
-                    && structureSet.contains(node->structureTransitionData().newStructure))
-                    return true;
-                if (structureSet.contains(node->structureTransitionData().previousStructure))
-                    return false;
-                break;
-                
-            case PutByOffset:
-                // Setting a property cannot change the structure.
-                break;
-                
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().writesStructures())
-                    return false;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
+        
+        LazyNode findReplacement(HeapLocation location)
+        {
+            return m_impureMap.get(location);
+        }
+    
+        LazyNode addImpure(HeapLocation location, LazyNode node)
+        {
+            auto result = m_impureMap.add(location, node);
+            if (result.isNewEntry)
+                return nullptr;
+            return result.iterator->value;
+        }
+
+    private:
+        HashMap<PureValue, Node*> m_pureMap;
+        HashMap<HeapLocation, LazyNode> m_impureMap;
+    };
+
+    template<typename Maps>
+    class BlockCSE {
+    public:
+        BlockCSE(Graph& graph)
+            : m_graph(graph)
+            , m_insertionSet(graph)
+        {
+        }
+    
+        bool run(BasicBlock* block)
+        {
+            m_maps.clear();
+            m_changed = false;
+            m_block = block;
+        
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                m_node = block->at(nodeIndex);
+                m_graph.performSubstitution(m_node);
+            
+                if (m_node->op() == Identity) {
+                    m_node->replaceWith(m_node->child1().node());
+                    m_changed = true;
+                } else {
+                    // This rule only makes sense for local CSE, since in SSA form we have already
+                    // factored the bounds check out of the PutByVal. It's kind of gross, but we
+                    // still have reason to believe that PutByValAlias is a good optimization and
+                    // that it's better to do it with a single node rather than separating out the
+                    // CheckInBounds.
+                    if (m_node->op() == PutByVal || m_node->op() == PutByValDirect) {
+                        HeapLocation heap;
+                        
+                        Node* base = m_graph.varArgChild(m_node, 0).node();
+                        Node* index = m_graph.varArgChild(m_node, 1).node();
+                        
+                        ArrayMode mode = m_node->arrayMode();
+                        switch (mode.type()) {
+                        case Array::Int32:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedInt32Properties, base, index);
+                            break;
+                            
+                        case Array::Double:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedDoubleProperties, base, index);
+                            break;
+                            
+                        case Array::Contiguous:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, IndexedContiguousProperties, base, index);
+                            break;
+                            
+                        case Array::Int8Array:
+                        case Array::Int16Array:
+                        case Array::Int32Array:
+                        case Array::Uint8Array:
+                        case Array::Uint8ClampedArray:
+                        case Array::Uint16Array:
+                        case Array::Uint32Array:
+                        case Array::Float32Array:
+                        case Array::Float64Array:
+                            if (!mode.isInBounds())
+                                break;
+                            heap = HeapLocation(
+                                IndexedPropertyLoc, TypedArrayProperties, base, index);
+                            break;
+                            
+                        default:
+                            break;
+                        }
+
+                        if (!!heap && m_maps.findReplacement(heap))
+                            m_node->setOp(PutByValAlias);
+                    }
+
+                    clobberize(m_graph, m_node, *this);
                 }
-                return false;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our structures.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
             }
-        }
-        return false;
-    }
-    
-    bool structureTransitionWatchpointElimination(Structure* structure, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
 
-            switch (node->op()) {
-            case CheckStructure:
-                if (node->child1() == child1
-                    && node->structureSet().containsOnly(structure))
-                    return true;
-                break;
-                
-            case PutStructure:
-                ASSERT(node->structureTransitionData().previousStructure != structure);
-                break;
-                
-            case PutByOffset:
-                // Setting a property cannot change the structure.
-                break;
-                    
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().writesStructures())
-                    return false;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return false;
-                
-            case StructureTransitionWatchpoint:
-                if (node->structure() == structure && node->child1() == child1)
-                    return true;
-                break;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our structures.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
-            }
-        }
-        return false;
-    }
-    
-    Node* putStructureStoreElimination(Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1)
-                break;
-            switch (node->op()) {
-            case CheckStructure:
-                return 0;
-                
-            case PhantomPutStructure:
-                if (node->child1() == child1) // No need to retrace our steps.
-                    return 0;
-                break;
-                
-            case PutStructure:
-                if (node->child1() == child1)
-                    return node;
-                break;
-                
-            // PutStructure needs to execute if we GC. Hence this needs to
-            // be careful with respect to nodes that GC.
-            case CreateArguments:
-            case TearOffArguments:
-            case NewFunctionNoCheck:
-            case NewFunction:
-            case NewFunctionExpression:
-            case CreateActivation:
-            case TearOffActivation:
-            case ToPrimitive:
-            case NewRegexp:
-            case NewArrayBuffer:
-            case NewArray:
-            case NewObject:
-            case CreateThis:
-            case AllocatePropertyStorage:
-            case ReallocatePropertyStorage:
-            case TypeOf:
-            case ToString:
-            case NewStringObject:
-            case MakeRope:
-            case NewTypedArray:
-            case MultiPutByOffset:
-                return 0;
-                
-            // This either exits, causes a GC (lazy string allocation), or clobbers
-            // the world. The chances of it not doing any of those things are so
-            // slim that we might as well not even try to reason about it.
-            case GetByVal:
-                return 0;
-                
-            case GetIndexedPropertyStorage:
-                if (node->arrayMode().getIndexedPropertyStorageMayTriggerGC())
-                    return 0;
-                break;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node) || node->canExit())
-                return 0;
-            if (edgesUseStructure(m_graph, node))
-                return 0;
+            m_insertionSet.execute(block);
+        
+            return m_changed;
         }
-        return 0;
-    }
     
-    Node* getByOffsetLoadElimination(unsigned identifierNumber, Node* base)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == base)
-                break;
-
-            switch (node->op()) {
-            case GetByOffset:
-                if (node->child2() == base
-                    && m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return node;
-                break;
-                
-            case MultiGetByOffset:
-                if (node->child1() == base
-                    && node->multiGetByOffsetData().identifierNumber == identifierNumber)
-                    return node;
-                break;
-                
-            case PutByOffset:
-                if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber) {
-                    if (node->child2() == base) // Must be same property storage.
-                        return node->child3().node();
-                    return 0;
-                }
-                break;
-                
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().identifierNumber == identifierNumber) {
-                    if (node->child1() == base)
-                        return node->child2().node();
-                    return 0;
-                }
-                break;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
-        }
-        return 0;
-    }
+        void read(AbstractHeap) { }
     
-    Node* putByOffsetStoreElimination(unsigned identifierNumber, Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1)
-                break;
-
-            switch (node->op()) {
-            case GetByOffset:
-                if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return 0;
-                break;
-                
-            case PutByOffset:
-                if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber) {
-                    if (node->child1() == child1) // Must be same property storage.
-                        return node;
-                    return 0;
-                }
-                break;
-                
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().identifierNumber == identifierNumber)
-                    return 0;
-                break;
-                
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-            case GetByVal:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
-            if (node->canExit())
-                return 0;
+        void write(AbstractHeap heap)
+        {
+            m_maps.write(heap);
         }
-        return 0;
-    }
-    
-    Node* getPropertyStorageLoadElimination(Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
-
-            switch (node->op()) {
-            case GetButterfly:
-                if (node->child1() == child1)
-                    return node;
-                break;
+        
+        void def(PureValue value)
+        {
+            Node* match = m_maps.addPure(value, m_node);
+            if (!match)
+                return;
 
-            case AllocatePropertyStorage:
-            case ReallocatePropertyStorage:
-                // If we can cheaply prove this is a change to our object's storage, we
-                // can optimize and use its result.
-                if (node->child1() == child1)
-                    return node;
-                // Otherwise, we currently can't prove that this doesn't change our object's
-                // storage, so we conservatively assume that it may change the storage
-                // pointer of any object, including ours.
-                return 0;
-                    
-            case PutByValDirect:
-            case PutByVal:
-            case PutByValAlias:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return 0;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our butterfly.
-                // But that seems like it would take Effort.
-                return 0;
-                
-            case MultiPutByOffset:
-                if (node->multiPutByOffsetData().reallocatesStorage())
-                    return 0;
-                break;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
+            m_node->replaceWith(match);
+            m_changed = true;
         }
-        return 0;
-    }
     
-    bool checkArrayElimination(Node* child1, ArrayMode arrayMode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
-
-            switch (node->op()) {
-            case CheckArray:
-                if (node->child1() == child1 && node->arrayMode() == arrayMode)
-                    return true;
-                break;
-                
-            case Arrayify:
-            case ArrayifyToStructure:
-                // We could check if the arrayification could affect our array.
-                // But that seems like it would take Effort.
-                return false;
-                
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return false;
-                break;
-            }
-        }
-        return false;
-    }
-
-    Node* getIndexedPropertyStorageLoadElimination(Node* child1, ArrayMode arrayMode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
-
-            switch (node->op()) {
-            case GetIndexedPropertyStorage: {
-                if (node->child1() == child1 && node->arrayMode() == arrayMode)
-                    return node;
-                break;
+        void def(HeapLocation location, LazyNode value)
+        {
+            LazyNode match = m_maps.addImpure(location, value);
+            if (!match)
+                return;
+        
+            if (m_node->op() == GetLocal) {
+                // Usually the CPS rethreading phase does this. But it's OK for us to mess with
+                // locals so long as:
+                // 
+                // - We dethread the graph. Any changes we make may invalidate the assumptions of
+                //   our CPS form, particularly if this GetLocal is linked to the variablesAtTail.
+                //
+                // - We don't introduce a Phantom for the child of the GetLocal. This wouldn't be
+                //   totally wrong but it would pessimize the code. Just because there is a
+                //   GetLocal doesn't mean that the child was live. Simply rerouting the all uses
+                //   of this GetLocal will preserve the live-at-exit information just fine.
+                //
+                // We accomplish the latter by just clearing the child; then the Phantom that we
+                // introduce won't have children and so it will eventually just be deleted.
+            
+                m_node->child1() = Edge();
+                m_graph.dethread();
             }
-
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
+        
+            if (value.isNode() && value.asNode() == m_node) {
+                match.ensureIsNode(m_insertionSet, m_block, 0)->owner = m_block;
+                ASSERT(match.isNode());
+                m_node->replaceWith(match.asNode());
+                m_changed = true;
             }
         }
-        return 0;
-    }
     
-    Node* getTypedArrayByteOffsetLoadElimination(Node* child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node == child1) 
-                break;
+    private:
+        Graph& m_graph;
+        
+        bool m_changed;
+        Node* m_node;
+        BasicBlock* m_block;
+    
+        Maps m_maps;
 
-            switch (node->op()) {
-            case GetTypedArrayByteOffset: {
-                if (node->child1() == child1)
-                    return node;
-                break;
-            }
+        InsertionSet m_insertionSet;
+    };
 
-            default:
-                if (m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
-        }
-        return 0;
-    }
-    
-    Node* getMyScopeLoadElimination()
+    BlockCSE<SmallMaps> m_smallBlock;
+    BlockCSE<LargeMaps> m_largeBlock;
+};
+
+class GlobalCSEPhase : public Phase {
+public:
+    GlobalCSEPhase(Graph& graph)
+        : Phase(graph, "global common subexpression elimination")
+        , m_impureDataMap(graph)
+        , m_insertionSet(graph)
     {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case CreateActivation:
-                // This may cause us to return a different scope.
-                return 0;
-            case GetMyScope:
-                return node;
-            default:
-                break;
-            }
-        }
-        return 0;
     }
     
-    Node* getLocalLoadElimination(VirtualRegister local, Node*& relevantLocalOp, bool careAboutClobbering)
+    bool run()
     {
-        relevantLocalOp = 0;
+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        ASSERT(m_graph.m_form == SSA);
         
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetLocal:
-                if (node->local() == local) {
-                    relevantLocalOp = node;
-                    return node;
-                }
-                break;
-                
-            case GetLocalUnlinked:
-                if (node->unlinkedLocal() == local) {
-                    relevantLocalOp = node;
-                    return node;
-                }
-                break;
-                
-            case SetLocal:
-                if (node->local() == local) {
-                    relevantLocalOp = node;
-                    return node->child1().node();
-                }
-                break;
-                
-            case GetClosureVar:
-            case PutClosureVar:
-                if (static_cast<VirtualRegister>(node->varNumber()) == local)
-                    return 0;
-                break;
-                
-            default:
-                if (careAboutClobbering && m_graph.clobbersWorld(node))
-                    return 0;
-                break;
-            }
+        m_graph.initializeNodeOwners();
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        
+        m_preOrder = m_graph.blocksInPreOrder();
+        
+        // First figure out what gets clobbered by blocks. Node that this uses the preOrder list
+        // for convenience only.
+        for (unsigned i = m_preOrder.size(); i--;) {
+            m_block = m_preOrder[i];
+            m_impureData = &m_impureDataMap[m_block];
+            for (unsigned nodeIndex = m_block->size(); nodeIndex--;)
+                addWrites(m_graph, m_block->at(nodeIndex), m_impureData->writes);
         }
-        return 0;
+        
+        // Based on my experience doing this before, what follows might have to be made iterative.
+        // Right now it doesn't have to be iterative because everything is dominator-bsed. But when
+        // validation is enabled, we check if iterating would find new CSE opportunities.
+
+        bool changed = iterate();
+        
+        // FIXME: It should be possible to assert that CSE will not find any new opportunities if you
+        // run it a second time. Unfortunately, we cannot assert this right now. Note that if we did
+        // this, we'd have to first reset all of our state.
+        // https://bugs.webkit.org/show_bug.cgi?id=145853
+        
+        return changed;
     }
     
-    bool uncapturedSetLocalStoreElimination(VirtualRegister local, Node* expectedNode)
+    bool iterate()
     {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetLocal:
-            case Flush:
-                if (node->local() == local)
-                    return false;
-                break;
-                
-            case GetLocalUnlinked:
-                if (node->unlinkedLocal() == local)
-                    return false;
-                break;
-                
-            case SetLocal: {
-                if (node->local() != local)
-                    break;
-                if (node != expectedNode)
-                    return false;
-                return true;
-            }
-                
-            case GetClosureVar:
-            case PutClosureVar:
-                if (static_cast<VirtualRegister>(node->varNumber()) == local)
-                    return false;
-                break;
-                
-            case GetMyScope:
-            case SkipTopScope:
-                if (node->origin.semantic.inlineCallFrame)
-                    break;
-                if (m_graph.uncheckedActivationRegister() == local)
-                    return false;
-                break;
-                
-            case CheckArgumentsNotCreated:
-            case GetMyArgumentsLength:
-            case GetMyArgumentsLengthSafe:
-                if (m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic) == local)
-                    return false;
-                break;
-                
-            case GetMyArgumentByVal:
-            case GetMyArgumentByValSafe:
-                return false;
-                
-            case GetByVal:
-                // If this is accessing arguments then it's potentially accessing locals.
-                if (node->arrayMode().type() == Array::Arguments)
-                    return false;
-                break;
-                
-            case CreateArguments:
-            case TearOffActivation:
-            case TearOffArguments:
-                // If an activation is being torn off then it means that captured variables
-                // are live. We could be clever here and check if the local qualifies as an
-                // argument register. But that seems like it would buy us very little since
-                // any kind of tear offs are rare to begin with.
-                return false;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(node))
-                return false;
-        }
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
-    }
+        if (verbose)
+            dataLog("Performing iteration.\n");
+        
+        m_changed = false;
+        m_graph.clearReplacements();
+        
+        for (unsigned i = 0; i < m_preOrder.size(); ++i) {
+            m_block = m_preOrder[i];
+            m_impureData = &m_impureDataMap[m_block];
+            m_writesSoFar.clear();
+            
+            if (verbose)
+                dataLog("Processing block ", *m_block, ":\n");
 
-    bool capturedSetLocalStoreElimination(VirtualRegister local, Node* expectedNode)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            switch (node->op()) {
-            case GetLocal:
-            case Flush:
-                if (node->local() == local)
-                    return false;
-                break;
+            for (unsigned nodeIndex = 0; nodeIndex < m_block->size(); ++nodeIndex) {
+                m_nodeIndex = nodeIndex;
+                m_node = m_block->at(nodeIndex);
+                if (verbose)
+                    dataLog("  Looking at node ", m_node, ":\n");
                 
-            case GetLocalUnlinked:
-                if (node->unlinkedLocal() == local)
-                    return false;
-                break;
+                m_graph.performSubstitution(m_node);
                 
-            case SetLocal: {
-                if (node->local() != local)
-                    break;
-                if (node != expectedNode)
-                    return false;
-                return true;
-            }
-                
-            case Phantom:
-            case Check:
-            case HardPhantom:
-            case MovHint:
-            case JSConstant:
-            case DoubleConstant:
-            case Int52Constant:
-                break;
-                
-            default:
-                return false;
+                if (m_node->op() == Identity) {
+                    m_node->replaceWith(m_node->child1().node());
+                    m_changed = true;
+                } else
+                    clobberize(m_graph, m_node, *this);
             }
+
+            m_insertionSet.execute(m_block);
+            
+            m_impureData->didVisit = true;
         }
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
-    }
-    
-    bool setLocalStoreElimination(VariableAccessData* variableAccessData, Node* expectedNode)
-    {
-        if (variableAccessData->isCaptured())
-            return capturedSetLocalStoreElimination(variableAccessData->local(), expectedNode);
-        return uncapturedSetLocalStoreElimination(variableAccessData->local(), expectedNode);
+        
+        return m_changed;
     }
+
+    void read(AbstractHeap) { }
     
-    bool invalidationPointElimination()
+    void write(AbstractHeap heap)
     {
-        for (unsigned i = m_indexInBlock; i--;) {
-            Node* node = m_currentBlock->at(i);
-            if (node->op() == InvalidationPoint)
-                return true;
-            if (writesOverlap(m_graph, node, Watchpoint_fire))
-                break;
-        }
-        return false;
+        clobber(m_impureData->availableAtTail, heap);
+        m_writesSoFar.add(heap);
+        if (verbose)
+            dataLog("    Clobbered, new tail map: ", mapDump(m_impureData->availableAtTail), "\n");
     }
     
-    void eliminateIrrelevantPhantomChildren(Node* node)
+    void def(PureValue value)
     {
-        ASSERT(node->op() == Phantom);
-        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
-            Edge edge = node->children.child(i);
-            if (!edge)
-                continue;
-            if (edge.useKind() != UntypedUse)
-                continue; // Keep the type check.
-            if (edge->flags() & NodeRelevantToOSR)
-                continue;
-            
-            node->children.removeEdge(i--);
-            m_changed = true;
-        }
-    }
-    
-    bool setReplacement(Node* replacement)
-    {
-        if (!replacement)
-            return false;
+        // With pure values we do not have to worry about the possibility of some control flow path
+        // clobbering the value. So, we just search for all of the like values that have been
+        // computed. We pick one that is in a block that dominates ours. Note that this means that
+        // a PureValue will map to a list of nodes, since there may be many places in the control
+        // flow graph that compute a value but only one of them that dominates us. We may build up
+        // a large list of nodes that compute some value in the case of gnarly control flow. This
+        // is probably OK.
         
-        if (!ASSERT_DISABLED
-            && canonicalResultRepresentation(m_currentNode->result()) != canonicalResultRepresentation(replacement->result())) {
-            startCrashing();
-            dataLog("CSE attempting to replace a node with a mismatched result: ", m_currentNode, " with ", replacement, "\n");
-            dataLog("\n");
-            m_graph.dump();
-            RELEASE_ASSERT_NOT_REACHED();
+        auto result = m_pureValues.add(value, Vector<Node*>());
+        if (result.isNewEntry) {
+            result.iterator->value.append(m_node);
+            return;
         }
         
-        m_currentNode->convertToPhantom();
-        eliminateIrrelevantPhantomChildren(m_currentNode);
-        
-        // At this point we will eliminate all references to this node.
-        m_currentNode->misc.replacement = replacement;
-        
-        m_changed = true;
+        for (unsigned i = result.iterator->value.size(); i--;) {
+            Node* candidate = result.iterator->value[i];
+            if (m_graph.m_dominators.dominates(candidate->owner, m_block)) {
+                m_node->replaceWith(candidate);
+                m_changed = true;
+                return;
+            }
+        }
         
-        return true;
+        result.iterator->value.append(m_node);
     }
     
-    void eliminate()
+    LazyNode findReplacement(HeapLocation location)
     {
-        ASSERT(m_currentNode->mustGenerate());
-        m_currentNode->convertToPhantom();
-        eliminateIrrelevantPhantomChildren(m_currentNode);
+        // At this instant, our "availableAtTail" reflects the set of things that are available in
+        // this block so far. We check this map to find block-local CSE opportunities before doing
+        // a global search.
+        LazyNode match = m_impureData->availableAtTail.get(location);
+        if (!!match) {
+            if (verbose)
+                dataLog("      Found local match: ", match, "\n");
+            return match;
+        }
         
-        m_changed = true;
-    }
-    
-    void eliminate(Node* node, NodeType phantomType = Phantom)
-    {
-        if (!node)
-            return;
-        ASSERT(node->mustGenerate());
-        node->setOpAndDefaultFlags(phantomType);
-        if (phantomType == Phantom)
-            eliminateIrrelevantPhantomChildren(node);
+        // If it's not available at this point in the block, and at some prior point in the block
+        // we have clobbered this heap location, then there is no point in doing a global search.
+        if (m_writesSoFar.overlaps(location.heap())) {
+            if (verbose)
+                dataLog("      Not looking globally because of local clobber: ", m_writesSoFar, "\n");
+            return nullptr;
+        }
         
-        m_changed = true;
-    }
-    
-    void performNodeCSE(Node* node)
-    {
-        if (cseMode == NormalCSE)
-            m_graph.performSubstitution(node);
+        // This perfoms a backward search over the control flow graph to find some possible
+        // non-local def() that matches our heap location. Such a match is only valid if there does
+        // not exist any path from that def() to our block that contains a write() that overlaps
+        // our heap. This algorithm looks for both of these things (the matching def and the
+        // overlapping writes) in one backwards DFS pass.
+        //
+        // This starts by looking at the starting block's predecessors, and then it continues along
+        // their predecessors. As soon as this finds a possible def() - one that defines the heap
+        // location we want while dominating our starting block - it assumes that this one must be
+        // the match. It then lets the DFS over predecessors complete, but it doesn't add the
+        // def()'s predecessors; this ensures that any blocks we visit thereafter are on some path
+        // from the def() to us. As soon as the DFG finds a write() that overlaps the location's
+        // heap, it stops, assuming that there is no possible match. Note that the write() case may
+        // trigger before we find a def(), or after. Either way, the write() case causes this
+        // function to immediately return nullptr.
+        //
+        // If the write() is found before we find the def(), then we know that any def() we would
+        // find would have a path to us that trips over the write() and hence becomes invalid. This
+        // is just a direct outcome of us looking for a def() that dominates us. Given a block A
+        // that dominates block B - so that A is the one that would have the def() and B is our
+        // starting block - we know that any other block must either be on the path from A to B, or
+        // it must be on a path from the root to A, but not both. So, if we haven't found A yet but
+        // we already have found a block C that has a write(), then C must be on some path from A
+        // to B, which means that A's def() is invalid for our purposes. Hence, before we find the
+        // def(), stopping on write() is the right thing to do.
+        //
+        // Stopping on write() is also the right thing to do after we find the def(). After we find
+        // the def(), we don't add that block's predecessors to the search worklist. That means
+        // that henceforth the only blocks we will see in the search are blocks on the path from
+        // the def() to us. If any such block has a write() that clobbers our heap then we should
+        // give up.
+        //
+        // Hence this graph search algorithm ends up being deceptively simple: any overlapping
+        // write() causes us to immediately return nullptr, and a matching def() means that we just
+        // record it and neglect to visit its precessors.
         
-        switch (node->op()) {
+        Vector<BasicBlock*, 8> worklist;
+        Vector<BasicBlock*, 8> seenList;
+        BitVector seen;
         
-        case Identity:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(node->child1().node());
-            break;
-            
-        // Handle the pure nodes. These nodes never have any side-effects.
-        case BitAnd:
-        case BitOr:
-        case BitXor:
-        case BitRShift:
-        case BitLShift:
-        case BitURShift:
-        case ArithAbs:
-        case ArithMin:
-        case ArithMax:
-        case ArithSqrt:
-        case ArithFRound:
-        case ArithSin:
-        case ArithCos:
-        case StringCharAt:
-        case StringCharCodeAt:
-        case IsUndefined:
-        case IsBoolean:
-        case IsNumber:
-        case IsString:
-        case IsObject:
-        case IsFunction:
-        case LogicalNot:
-        case SkipTopScope:
-        case SkipScope:
-        case GetClosureRegisters:
-        case GetScope:
-        case TypeOf:
-        case CompareEqConstant:
-        case ValueToInt32:
-        case MakeRope:
-        case DoubleRep:
-        case ValueRep:
-        case Int52Rep:
-        case BooleanToNumber:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(pureCSE(node));
-            break;
-            
-        case ArithAdd:
-        case ArithSub:
-        case ArithNegate:
-        case ArithMul:
-        case ArithDiv:
-        case ArithMod:
-        case UInt32ToNumber:
-        case DoubleAsInt32: {
-            if (cseMode == StoreElimination)
-                break;
-            Node* candidate = pureCSE(node);
-            if (!candidate)
-                break;
-            if (!subsumes(candidate->arithMode(), node->arithMode())) {
-                if (!subsumes(node->arithMode(), candidate->arithMode()))
-                    break;
-                candidate->setArithMode(node->arithMode());
+        for (unsigned i = m_block->predecessors.size(); i--;) {
+            BasicBlock* predecessor = m_block->predecessors[i];
+            if (!seen.get(predecessor->index)) {
+                worklist.append(predecessor);
+                seen.set(predecessor->index);
             }
-            setReplacement(candidate);
-            break;
-        }
-            
-        case GetCallee:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getCalleeLoadElimination());
-            break;
-
-        case GetLocal: {
-            if (cseMode == StoreElimination)
-                break;
-            VariableAccessData* variableAccessData = node->variableAccessData();
-            if (!variableAccessData->isCaptured())
-                break;
-            Node* relevantLocalOp;
-            Node* possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp, variableAccessData->isCaptured());
-            if (!relevantLocalOp)
-                break;
-            if (relevantLocalOp->op() != GetLocalUnlinked
-                && relevantLocalOp->variableAccessData() != variableAccessData)
-                break;
-            Node* phi = node->child1().node();
-            if (!setReplacement(possibleReplacement))
-                break;
-            
-            m_graph.dethread();
-            
-            // If we replace a GetLocal with a GetLocalUnlinked, then turn the GetLocalUnlinked
-            // into a GetLocal.
-            if (relevantLocalOp->op() == GetLocalUnlinked)
-                relevantLocalOp->convertToGetLocal(variableAccessData, phi);
-
-            m_changed = true;
-            break;
-        }
-            
-        case GetLocalUnlinked: {
-            if (cseMode == StoreElimination)
-                break;
-            Node* relevantLocalOpIgnored;
-            setReplacement(getLocalLoadElimination(node->unlinkedLocal(), relevantLocalOpIgnored, true));
-            break;
         }
-            
-        case Flush: {
-            ASSERT(m_graph.m_form != SSA);
-            VariableAccessData* variableAccessData = node->variableAccessData();
-            if (!node->child1()) {
-                // FIXME: It's silly that we punt on flush-eliminating here. We don't really
-                // need child1 to figure out what's going on.
-                // https://bugs.webkit.org/show_bug.cgi?id=130521
-                break;
-            }
-            Node* replacement = node->child1().node();
-            if (replacement->op() != SetLocal)
-                break;
-            ASSERT(replacement->variableAccessData() == variableAccessData);
-            // FIXME: We should be able to remove SetLocals that can exit; we just need
-            // to replace them with appropriate type checks.
-            if (cseMode == NormalCSE) {
-                // Need to be conservative at this time; if the SetLocal has any chance of performing
-                // any speculations then we cannot do anything.
-                FlushFormat format = variableAccessData->flushFormat();
-                ASSERT(format != DeadFlush);
-                if (format != FlushedJSValue)
-                    break;
-            } else {
-                if (replacement->canExit())
-                    break;
+        
+        while (!worklist.isEmpty()) {
+            BasicBlock* block = worklist.takeLast();
+            seenList.append(block);
+            
+            if (verbose)
+                dataLog("      Searching in block ", *block, "\n");
+            ImpureBlockData& data = m_impureDataMap[block];
+            
+            // We require strict domination because this would only see things in our own block if
+            // they came *after* our position in the block. Clearly, while our block dominates
+            // itself, the things in the block after us don't dominate us.
+            if (m_graph.m_dominators.strictlyDominates(block, m_block)) {
+                if (verbose)
+                    dataLog("        It strictly dominates.\n");
+                DFG_ASSERT(m_graph, m_node, data.didVisit);
+                DFG_ASSERT(m_graph, m_node, !match);
+                if (verbose)
+                    dataLog("        Availability map: ", mapDump(data.availableAtTail), "\n");
+                match = data.availableAtTail.get(location);
+                if (verbose)
+                    dataLog("        Availability: ", match, "\n");
+                if (!!match) {
+                    // Don't examine the predecessors of a match. At this point we just want to
+                    // establish that other blocks on the path from here to there don't clobber
+                    // the location we're interested in.
+                    continue;
+                }
             }
-            if (!setLocalStoreElimination(variableAccessData, replacement))
-                break;
-            ASSERT(replacement->op() == SetLocal);
-            node->convertToPhantom();
-            Node* dataNode = replacement->child1().node();
-            ASSERT(dataNode->hasResult());
-            node->child1() = dataNode->defaultEdge();
-            m_graph.dethread();
-            m_changed = true;
-            break;
-        }
-            
-        case JSConstant:
-        case DoubleConstant:
-        case Int52Constant:
-            if (cseMode == StoreElimination)
-                break;
-            // This is strange, but necessary. Some phases will convert nodes to constants,
-            // which may result in duplicated constants. We use CSE to clean this up.
-            setReplacement(constantCSE(node));
-            break;
             
-        case WeakJSConstant:
-            if (cseMode == StoreElimination)
-                break;
-            // FIXME: have CSE for weak constants against strong constants and vice-versa.
-            setReplacement(weakConstantCSE(node));
-            break;
-            
-        case ConstantStoragePointer:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(constantStoragePointerCSE(node));
-            break;
-            
-        case GetArrayLength:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getArrayLengthElimination(node->child1().node()));
-            break;
-
-        case GetMyScope:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getMyScopeLoadElimination());
-            break;
-            
-        // Handle nodes that are conditionally pure: these are pure, and can
-        // be CSE'd, so long as the prediction is the one we want.
-        case CompareLess:
-        case CompareLessEq:
-        case CompareGreater:
-        case CompareGreaterEq:
-        case CompareEq: {
-            if (cseMode == StoreElimination)
-                break;
-            if (m_graph.isPredictedNumerical(node)) {
-                Node* replacement = pureCSE(node);
-                if (replacement && m_graph.isPredictedNumerical(replacement))
-                    setReplacement(replacement);
+            if (verbose)
+                dataLog("        Dealing with write set ", data.writes, "\n");
+            if (data.writes.overlaps(location.heap())) {
+                if (verbose)
+                    dataLog("        Clobbered.\n");
+                return nullptr;
             }
-            break;
-        }
-            
-        // Finally handle heap accesses. These are not quite pure, but we can still
-        // optimize them provided that some subtle conditions are met.
-        case GetGlobalVar:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(globalVarLoadElimination(node->registerPointer()));
-            break;
-
-        case GetClosureVar: {
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(scopedVarLoadElimination(node->child1().node(), node->varNumber()));
-            break;
-        }
-
-        case VarInjectionWatchpoint:
-            if (cseMode == StoreElimination)
-                break;
-            if (varInjectionWatchpointElimination())
-                eliminate();
-            break;
-            
-        case PutGlobalVar:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(globalVarStoreElimination(node->registerPointer()));
-            break;
             
-        case PutClosureVar: {
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(scopedVarStoreElimination(node->child1().node(), node->child2().node(), node->varNumber()));
-            break;
-        }
-
-        case GetByVal:
-            if (cseMode == StoreElimination)
-                break;
-            if (m_graph.byValIsPure(node))
-                setReplacement(getByValLoadElimination(node->child1().node(), node->child2().node(), node->arrayMode()));
-            break;
-                
-        case PutByValDirect:
-        case PutByVal: {
-            if (cseMode == StoreElimination)
-                break;
-            Edge child1 = m_graph.varArgChild(node, 0);
-            Edge child2 = m_graph.varArgChild(node, 1);
-            if (node->arrayMode().canCSEStorage()) {
-                Node* replacement = getByValLoadElimination(child1.node(), child2.node(), node->arrayMode());
-                if (!replacement)
-                    break;
-                node->setOp(PutByValAlias);
+            for (unsigned i = block->predecessors.size(); i--;) {
+                BasicBlock* predecessor = block->predecessors[i];
+                if (!seen.get(predecessor->index)) {
+                    worklist.append(predecessor);
+                    seen.set(predecessor->index);
+                }
             }
-            break;
-        }
-            
-        case CheckStructure:
-            if (cseMode == StoreElimination)
-                break;
-            if (checkStructureElimination(node->structureSet(), node->child1().node()))
-                eliminate();
-            break;
-            
-        case StructureTransitionWatchpoint:
-            if (cseMode == StoreElimination)
-                break;
-            if (structureTransitionWatchpointElimination(node->structure(), node->child1().node()))
-                eliminate();
-            break;
-            
-        case PutStructure:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(putStructureStoreElimination(node->child1().node()), PhantomPutStructure);
-            break;
-
-        case CheckFunction:
-            if (cseMode == StoreElimination)
-                break;
-            if (checkFunctionElimination(node->function(), node->child1().node()))
-                eliminate();
-            break;
-                
-        case CheckExecutable:
-            if (cseMode == StoreElimination)
-                break;
-            if (checkExecutableElimination(node->executable(), node->child1().node()))
-                eliminate();
-            break;
-                
-        case CheckArray:
-            if (cseMode == StoreElimination)
-                break;
-            if (checkArrayElimination(node->child1().node(), node->arrayMode()))
-                eliminate();
-            break;
-            
-        case GetIndexedPropertyStorage: {
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getIndexedPropertyStorageLoadElimination(node->child1().node(), node->arrayMode()));
-            break;
-        }
-            
-        case GetTypedArrayByteOffset: {
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getTypedArrayByteOffsetLoadElimination(node->child1().node()));
-            break;
-        }
-
-        case GetButterfly:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getPropertyStorageLoadElimination(node->child1().node()));
-            break;
-
-        case GetByOffset:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child2().node()));
-            break;
-            
-        case MultiGetByOffset:
-            if (cseMode == StoreElimination)
-                break;
-            setReplacement(getByOffsetLoadElimination(node->multiGetByOffsetData().identifierNumber, node->child1().node()));
-            break;
-            
-        case PutByOffset:
-            if (cseMode == NormalCSE)
-                break;
-            eliminate(putByOffsetStoreElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child1().node()));
-            break;
-            
-        case InvalidationPoint:
-            if (invalidationPointElimination())
-                eliminate();
-            break;
-            
-        case Phantom:
-            // FIXME: we ought to remove Phantom's that have no children.
-            // NB. It would be incorrect to do this for HardPhantom. In fact, the whole point
-            // of HardPhantom is that we *don't* do this for HardPhantoms, since they signify
-            // a more strict kind of liveness than the Phantom bytecode liveness.
-            eliminateIrrelevantPhantomChildren(node);
-            break;
-            
-        default:
-            // do nothing.
-            break;
         }
         
-        m_lastSeen[node->op()] = m_indexInBlock;
+        if (!match)
+            return nullptr;
+        
+        // Cache the results for next time. We cache them both for this block and for all of our
+        // predecessors, since even though we've already visited our predecessors, our predecessors
+        // probably have successors other than us.
+        // FIXME: Consider caching failed searches as well, when match is null. It's not clear that
+        // the reduction in compile time would warrant the increase in complexity, though.
+        // https://bugs.webkit.org/show_bug.cgi?id=134876
+        for (BasicBlock* block : seenList)
+            m_impureDataMap[block].availableAtTail.add(location, match);
+        m_impureData->availableAtTail.add(location, match);
+        
+        return match;
     }
     
-    void performBlockCSE(BasicBlock* block)
+    void def(HeapLocation location, LazyNode value)
     {
-        if (!block)
-            return;
-        if (!block->isReachable)
-            return;
+        if (verbose)
+            dataLog("    Got heap location def: ", location, " -> ", value, "\n");
         
-        m_currentBlock = block;
-        for (unsigned i = 0; i < LastNodeType; ++i)
-            m_lastSeen[i] = UINT_MAX;
+        LazyNode match = findReplacement(location);
         
-        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
-            m_currentNode = block->at(m_indexInBlock);
-            performNodeCSE(m_currentNode);
-        }
+        if (verbose)
+            dataLog("      Got match: ", match, "\n");
         
-        if (!ASSERT_DISABLED && cseMode == StoreElimination) {
-            // Nobody should have replacements set.
-            for (unsigned i = 0; i < block->size(); ++i)
-                ASSERT(!block->at(i)->misc.replacement);
+        if (!match) {
+            if (verbose)
+                dataLog("      Adding at-tail mapping: ", location, " -> ", value, "\n");
+            auto result = m_impureData->availableAtTail.add(location, value);
+            ASSERT_UNUSED(result, result.isNewEntry);
+            return;
+        }
+
+        if (value.isNode() && value.asNode() == m_node) {
+            if (!match.isNode()) {
+                // We need to properly record the constant in order to use an existing one if applicable.
+                // This ensures that re-running GCSE will not find new optimizations.
+                match.ensureIsNode(m_insertionSet, m_block, m_nodeIndex)->owner = m_block;
+                auto result = m_pureValues.add(PureValue(match.asNode(), match->constant()), Vector<Node*>());
+                bool replaced = false;
+                if (!result.isNewEntry) {
+                    for (unsigned i = result.iterator->value.size(); i--;) {
+                        Node* candidate = result.iterator->value[i];
+                        if (m_graph.m_dominators.dominates(candidate->owner, m_block)) {
+                            ASSERT(candidate);
+                            match->replaceWith(candidate);
+                            match.setNode(candidate);
+                            replaced = true;
+                            break;
+                        }
+                    }
+                }
+                if (!replaced)
+                    result.iterator->value.append(match.asNode());
+            }
+            ASSERT(match.asNode());
+            m_node->replaceWith(match.asNode());
+            m_changed = true;
         }
     }
     
-    BasicBlock* m_currentBlock;
-    Node* m_currentNode;
-    unsigned m_indexInBlock;
-    std::array<unsigned, LastNodeType> m_lastSeen;
-    bool m_changed; // Only tracks changes that have a substantive effect on other optimizations.
+    struct ImpureBlockData {
+        ImpureBlockData()
+            : didVisit(false)
+        {
+        }
+        
+        ClobberSet writes;
+        ImpureMap availableAtTail;
+        bool didVisit;
+    };
+    
+    Vector<BasicBlock*> m_preOrder;
+
+    PureMultiMap m_pureValues;
+    BlockMap<ImpureBlockData> m_impureDataMap;
+    
+    BasicBlock* m_block;
+    Node* m_node;
+    unsigned m_nodeIndex;
+    ImpureBlockData* m_impureData;
+    ClobberSet m_writesSoFar;
+    InsertionSet m_insertionSet;
+    
+    bool m_changed;
 };
 
-bool performCSE(Graph& graph)
+} // anonymous namespace
+
+bool performLocalCSE(Graph& graph)
 {
-    SamplingRegion samplingRegion("DFG CSE Phase");
-    return runPhase<CSEPhase<NormalCSE>>(graph);
+    SamplingRegion samplingRegion("DFG LocalCSE Phase");
+    return runPhase<LocalCSEPhase>(graph);
 }
 
-bool performStoreElimination(Graph& graph)
+bool performGlobalCSE(Graph& graph)
 {
-    SamplingRegion samplingRegion("DFG Store Elimination Phase");
-    return runPhase<CSEPhase<StoreElimination>>(graph);
+    SamplingRegion samplingRegion("DFG GlobalCSE Phase");
+    return runPhase<GlobalCSEPhase>(graph);
 }
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
-
-
index 8f857ad97e43dfdc555ee2b01616bf2600bbab72..562fd9bcaae84c1112387785ffb710b8440fa494 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,14 +34,20 @@ namespace JSC { namespace DFG {
 
 class Graph;
 
-// Block-local common subexpression elimination. This is an optional phase, but
-// it is rather profitable. It has fairly accurate heap modeling and will match
-// a wide range of subexpression similarities. It's known to produce big wins
-// on a few benchmarks, and is relatively cheap to run.
-bool performCSE(Graph&);
-
-// Perform just block-local store elimination.
-bool performStoreElimination(Graph&);
+// Block-local common subexpression elimination. It uses clobberize() for heap
+// modeling, which is quite precise. This phase is known to produce big wins on
+// a few benchmarks, and is relatively cheap to run.
+//
+// Note that this phase also gets rid of Identity nodes, which means that it's
+// currently not an optional phase. Basically, DFG IR doesn't have use-lists,
+// so there is no instantaneous replaceAllUsesWith operation. Instead, you turn
+// a node into an Identity and wait for CSE to clean it up.
+bool performLocalCSE(Graph&);
+
+// Same, but global. Only works for SSA. This will find common subexpressions
+// both in the same block and in any block that dominates the current block. It
+// has no limits on how far it will look for load-elimination opportunities.
+bool performGlobalCSE(Graph&);
 
 } } // namespace JSC::DFG
 
index 02abdfdfb6ab02670c6303abf74129c209a4bcc1..9780e5029016f55aa1e055f0c589729aea4f31bd 100644 (file)
@@ -96,7 +96,7 @@ protected:
         for (unsigned i = 0; i < m_plans.size(); ++i)
             jit->silentSpill(m_plans[i]);
         GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR);
-        MacroAssembler::Jump bigLength = jit->m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_SPARSE_ARRAY_INDEX));
+        MacroAssembler::Jump bigLength = jit->m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
         jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR);
         MacroAssembler::Jump done = jit->m_jit.jump();
         bigLength.link(&jit->m_jit);
diff --git a/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h b/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h
new file mode 100644 (file)
index 0000000..871854c
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGCallCreateDirectArgumentsSlowPathGenerator_h
+#define DFGCallCreateDirectArgumentsSlowPathGenerator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "DFGOperations.h"
+#include "DFGSlowPathGenerator.h"
+#include "DFGSpeculativeJIT.h"
+#include "DirectArguments.h"
+
+namespace JSC { namespace DFG {
+
+// This calls operationCreateDirectArguments but then restores the value of lengthGPR.
+class CallCreateDirectArgumentsSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> {
+public:
+    CallCreateDirectArgumentsSlowPathGenerator(
+        MacroAssembler::JumpList from, SpeculativeJIT* jit, GPRReg resultGPR, Structure* structure,
+        GPRReg lengthGPR, unsigned minCapacity)
+        : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit)
+        , m_resultGPR(resultGPR)
+        , m_structure(structure)
+        , m_lengthGPR(lengthGPR)
+        , m_minCapacity(minCapacity)
+    {
+        jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR);
+    }
+
+protected:
+    void generateInternal(SpeculativeJIT* jit) override
+    {
+        linkFrom(jit);
+        for (unsigned i = 0; i < m_plans.size(); ++i)
+            jit->silentSpill(m_plans[i]);
+        jit->callOperation(
+            operationCreateDirectArguments, m_resultGPR, m_structure, m_lengthGPR, m_minCapacity);
+        GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR);
+        for (unsigned i = m_plans.size(); i--;)
+            jit->silentFill(m_plans[i], canTrample);
+        jit->m_jit.loadPtr(
+            MacroAssembler::Address(m_resultGPR, DirectArguments::offsetOfLength()), m_lengthGPR);
+        jumpTo(jit);
+    }
+    
+private:
+    GPRReg m_resultGPR;
+    Structure* m_structure;
+    GPRReg m_lengthGPR;
+    unsigned m_minCapacity;
+    Vector<SilentRegisterSavePlan, 2> m_plans;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGCallCreateDirectArgumentsSlowPathGenerator_h
+
index ab0fd2504138ea2724b2636087d4632b27ec6451..ef4c24749b78fa6e09a4c3d9c29013eaa65daa92 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "CodeBlock.h"
 #include "DFGCommon.h"
-#include "DFGFunctionWhitelist.h"
 #include "Interpreter.h"
 #include "JSCInlines.h"
 #include "Options.h"
 
 namespace JSC { namespace DFG {
 
-bool isSupported(CodeBlock* codeBlock)
+bool isSupported()
 {
     return Options::useDFGJIT()
-        && MacroAssembler::supportsFloatingPoint()
-        && Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount())
-        && FunctionWhitelist::ensureGlobalWhitelist().contains(codeBlock);
+        && MacroAssembler::supportsFloatingPoint();
+}
+
+bool isSupportedForInlining(CodeBlock* codeBlock)
+{
+    return codeBlock->ownerExecutable()->isInliningCandidate();
 }
 
 bool mightCompileEval(CodeBlock* codeBlock)
 {
-    return isSupported(codeBlock)
+    return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
 }
 bool mightCompileProgram(CodeBlock* codeBlock)
 {
-    return isSupported(codeBlock)
+    return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
 }
 bool mightCompileFunctionForCall(CodeBlock* codeBlock)
 {
-    return isSupported(codeBlock)
+    return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
 }
 bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
 {
-    return isSupported(codeBlock)
+    return isSupported()
         && codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
 }
 
 bool mightInlineFunctionForCall(CodeBlock* codeBlock)
 {
     return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
-        && !codeBlock->ownerExecutable()->needsActivation()
-        && codeBlock->ownerExecutable()->isInliningCandidate();
+        && isSupportedForInlining(codeBlock);
 }
 bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
 {
     return codeBlock->instructionCount() <= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount()
-        && !codeBlock->ownerExecutable()->needsActivation()
-        && codeBlock->ownerExecutable()->isInliningCandidate();
+        && isSupportedForInlining(codeBlock);
 }
 bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
 {
     return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
-        && !codeBlock->ownerExecutable()->needsActivation()
-        && codeBlock->ownerExecutable()->isInliningCandidate();
+        && isSupportedForInlining(codeBlock);
 }
 
 inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
@@ -93,12 +92,13 @@ inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel r
 
 CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc)
 {
+    UNUSED_PARAM(codeBlock); // This function does some bytecode parsing. Ordinarily bytecode parsing requires the owning CodeBlock. It's sort of strange that we don't use it here right now.
+    
     switch (opcodeID) {
     case op_enter:
-    case op_touch_entry:
     case op_to_this:
+    case op_check_tdz:
     case op_create_this:
-    case op_get_callee:
     case op_bitand:
     case op_bitor:
     case op_bitxor:
@@ -117,8 +117,9 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
     case op_debug:
     case op_profile_will_call:
     case op_profile_did_call:
+    case op_profile_type:
+    case op_profile_control_flow:
     case op_mov:
-    case op_captured_mov:
     case op_check_has_instance:
     case op_instanceof:
     case op_is_undefined:
@@ -126,6 +127,7 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
     case op_is_number:
     case op_is_string:
     case op_is_object:
+    case op_is_object_or_null:
     case op_is_function:
     case op_not:
     case op_less:
@@ -178,18 +180,34 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
     case op_throw_static_error:
     case op_call:
     case op_construct:
-    case op_init_lazy_reg:
-    case op_create_arguments:
-    case op_tear_off_arguments:
-    case op_get_argument_by_val:
-    case op_get_arguments_length:
+    case op_call_varargs:
+    case op_construct_varargs:
+    case op_create_direct_arguments:
+    case op_create_scoped_arguments:
+    case op_create_out_of_band_arguments:
+    case op_get_from_arguments:
+    case op_put_to_arguments:
     case op_jneq_ptr:
     case op_typeof:
     case op_to_number:
+    case op_to_string:
     case op_switch_imm:
     case op_switch_char:
     case op_in:
+    case op_get_scope:
     case op_get_from_scope:
+    case op_get_enumerable_length:
+    case op_has_generic_property:
+    case op_has_structure_property:
+    case op_has_indexed_property:
+    case op_get_direct_pname:
+    case op_get_property_enumerator:
+    case op_enumerator_structure_pname:
+    case op_enumerator_generic_pname:
+    case op_to_index_string:
+    case op_new_func:
+    case op_new_func_exp:
+    case op_create_lexical_environment:
         return CanCompileAndInline;
 
     case op_put_to_scope: {
@@ -203,26 +221,13 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
 
     case op_resolve_scope: {
         // We don't compile 'catch' or 'with', so there's no point in compiling variable resolution within them.
-        ResolveType resolveType = ResolveModeAndType(pc[3].u.operand).type();
+        ResolveType resolveType = ResolveModeAndType(pc[4].u.operand).type();
         if (resolveType == Dynamic)
             return CannotCompile;
         return CanCompileAndInline;
     }
 
-    case op_call_varargs:
-        if (codeBlock->usesArguments() && pc[4].u.operand == codeBlock->argumentsRegister().offset()
-            && !pc[6].u.operand)
-            return CanInline;
-        // FIXME: We should handle this.
-        // https://bugs.webkit.org/show_bug.cgi?id=127626
-        return CannotCompile;
-
-    case op_new_regexp: 
-    case op_create_activation:
-    case op_tear_off_activation:
-    case op_new_func:
-    case op_new_captured_func:
-    case op_new_func_exp:
+    case op_new_regexp:
     case op_switch_string: // Don't inline because we don't want to copy string tables in the concurrent JIT.
         return CanCompile;
 
index b01f04464fe1f57535f7b55fa29bcc73f824b959..4010bb291dd32b2cb17f7aad7943476d1180aea0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,8 @@ namespace JSC { namespace DFG {
 #if ENABLE(DFG_JIT)
 // Fast check functions; if they return true it is still necessary to
 // check opcodes.
-bool isSupported(CodeBlock*);
+bool isSupported();
+bool isSupportedForInlining(CodeBlock*);
 bool mightCompileEval(CodeBlock*);
 bool mightCompileProgram(CodeBlock*);
 bool mightCompileFunctionForCall(CodeBlock*);
@@ -85,9 +86,7 @@ inline CapabilityLevel functionCapabilityLevel(bool mightCompile, bool mightInli
         return leastUpperBound(CanCompileAndInline, computedCapabilityLevel);
     if (mightCompile && !mightInline)
         return leastUpperBound(CanCompile, computedCapabilityLevel);
-    if (!mightCompile && mightInline)
-        return leastUpperBound(CanInline, computedCapabilityLevel);
-    if (!mightCompile && !mightInline)
+    if (!mightCompile)
         return CannotCompile;
     RELEASE_ASSERT_NOT_REACHED();
     return CannotCompile;
@@ -141,6 +140,14 @@ inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind
     return mightInlineFunctionForConstruct(codeBlock);
 }
 
+inline bool mightCompileFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
+{
+    if (kind == CodeForCall)
+        return mightCompileFunctionForCall(codeBlock);
+    ASSERT(kind == CodeForConstruct);
+    return mightCompileFunctionForConstruct(codeBlock);
+}
+
 inline bool mightInlineFunction(CodeBlock* codeBlock)
 {
     return mightInlineFunctionFor(codeBlock, codeBlock->specializationKind());
diff --git a/dfg/DFGCleanUpPhase.cpp b/dfg/DFGCleanUpPhase.cpp
new file mode 100644 (file)
index 0000000..313094c
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGCleanUpPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+class CleanUpPhase : public Phase {
+public:
+    CleanUpPhase(Graph& graph)
+        : Phase(graph, "clean up")
+    {
+    }
+    
+    bool run()
+    {
+        bool changed = false;
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            unsigned sourceIndex = 0;
+            unsigned targetIndex = 0;
+            while (sourceIndex < block->size()) {
+                Node* node = block->at(sourceIndex++);
+                bool kill = false;
+                
+                if (node->op() == Check)
+                    node->children = node->children.justChecks();
+                
+                switch (node->op()) {
+                case Phantom:
+                case Check:
+                    if (node->children.isEmpty())
+                        kill = true;
+                    break;
+                default:
+                    break;
+                }
+                
+                if (kill)
+                    m_graph.m_allocator.free(node);
+                else
+                    block->at(targetIndex++) = node;
+            }
+            block->resize(targetIndex);
+        }
+        
+        return changed;
+    }
+};
+    
+bool performCleanUp(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Clean Up Phase");
+    return runPhase<CleanUpPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGCleanUpPhase.h b/dfg/DFGCleanUpPhase.h
new file mode 100644 (file)
index 0000000..3a1bc69
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGCleanUpPhase_h
+#define DFGCleanUpPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Cleans up unneeded nodes, like empty Checks and Phantoms.
+
+bool performCleanUp(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGCleanUpPhase_h
index 997c4d2ca937539a7c881362d6290a535fdb18cf..d4630e370cb0bac23d9942f5ffce38fb58da2dec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -122,37 +122,38 @@ HashSet<AbstractHeap> ClobberSet::setOf(bool direct) const
 void addReads(Graph& graph, Node* node, ClobberSet& readSet)
 {
     ClobberSetAdd addRead(readSet);
-    NoOpClobberize addWrite;
-    clobberize(graph, node, addRead, addWrite);
+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, noOp, noOp);
 }
 
 void addWrites(Graph& graph, Node* node, ClobberSet& writeSet)
 {
-    NoOpClobberize addRead;
+    NoOpClobberize noOp;
     ClobberSetAdd addWrite(writeSet);
-    clobberize(graph, node, addRead, addWrite);
+    clobberize(graph, node, noOp, addWrite, noOp);
 }
 
 void addReadsAndWrites(Graph& graph, Node* node, ClobberSet& readSet, ClobberSet& writeSet)
 {
     ClobberSetAdd addRead(readSet);
     ClobberSetAdd addWrite(writeSet);
-    clobberize(graph, node, addRead, addWrite);
+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, addWrite, noOp);
 }
 
 bool readsOverlap(Graph& graph, Node* node, ClobberSet& readSet)
 {
     ClobberSetOverlaps addRead(readSet);
-    NoOpClobberize addWrite;
-    clobberize(graph, node, addRead, addWrite);
+    NoOpClobberize noOp;
+    clobberize(graph, node, addRead, noOp, noOp);
     return addRead.result();
 }
 
 bool writesOverlap(Graph& graph, Node* node, ClobberSet& writeSet)
 {
-    NoOpClobberize addRead;
+    NoOpClobberize noOp;
     ClobberSetOverlaps addWrite(writeSet);
-    clobberize(graph, node, addRead, addWrite);
+    clobberize(graph, node, noOp, addWrite, noOp);
     return addWrite.result();
 }
 
index 5dfe495fafee24eb0b66f94b4b53dd3cfc432f20..d76d3559d943613718618ecd9a56e7f9bf2ebda3 100644 (file)
@@ -80,7 +80,7 @@ public:
     {
     }
     
-    void operator()(AbstractHeap heap)
+    void operator()(AbstractHeap heap) const
     {
         m_set.add(heap);
     }
@@ -96,7 +96,7 @@ public:
     {
     }
     
-    void operator()(AbstractHeap heap)
+    void operator()(AbstractHeap heap) const
     {
         m_result |= m_set.overlaps(heap);
     }
@@ -105,7 +105,7 @@ public:
     
 private:
     const ClobberSet& m_set;
-    bool m_result;
+    mutable bool m_result;
 };
 
 void addReads(Graph&, Node*, ClobberSet&);
index 18ca74e40ab0557ebd75866429bc739bdd9cd886..a693ba41b73bd0ffee838295782f5d59d24e6340 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,20 +34,47 @@ namespace JSC { namespace DFG {
 
 bool doesWrites(Graph& graph, Node* node)
 {
-    NoOpClobberize addRead;
+    NoOpClobberize noOp;
     CheckClobberize addWrite;
-    clobberize(graph, node, addRead, addWrite);
+    clobberize(graph, node, noOp, addWrite, noOp);
     return addWrite.result();
 }
 
+bool accessesOverlap(Graph& graph, Node* node, AbstractHeap heap)
+{
+    NoOpClobberize noOp;
+    AbstractHeapOverlaps addAccess(heap);
+    clobberize(graph, node, addAccess, addAccess, noOp);
+    return addAccess.result();
+}
+
 bool writesOverlap(Graph& graph, Node* node, AbstractHeap heap)
 {
-    NoOpClobberize addRead;
+    NoOpClobberize noOp;
     AbstractHeapOverlaps addWrite(heap);
-    clobberize(graph, node, addRead, addWrite);
+    clobberize(graph, node, noOp, addWrite, noOp);
     return addWrite.result();
 }
 
+bool clobbersHeap(Graph& graph, Node* node)
+{
+    bool result = false;
+    clobberize(
+        graph, node, NoOpClobberize(),
+        [&] (AbstractHeap heap) {
+            switch (heap.kind()) {
+            case World:
+            case Heap:
+                result = true;
+                break;
+            default:
+                break;
+            }
+        },
+        NoOpClobberize());
+    return result;
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index 9e464cfb8a304133e3c6dbed68f7cdfb29da74ee..5c6d17dcd854fa391e255065686daff09ccbf434 100644 (file)
@@ -1,5 +1,5 @@
- /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+/*
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DFGAbstractHeap.h"
 #include "DFGEdgeUsesStructure.h"
 #include "DFGGraph.h"
+#include "DFGHeapLocation.h"
+#include "DFGLazyNode.h"
+#include "DFGPureValue.h"
 
 namespace JSC { namespace DFG {
 
-template<typename ReadFunctor, typename WriteFunctor>
-void clobberizeForAllocation(ReadFunctor& read, WriteFunctor& write)
-{
-    read(GCState);
-    read(BarrierState);
-    write(GCState);
-    write(BarrierState);
-}
-
-template<typename ReadFunctor, typename WriteFunctor>
-void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write)
+template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
+void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def)
 {
     // Some notes:
     //
+    // - The canonical way of clobbering the world is to read world and write
+    //   heap. This is because World subsumes Heap and Stack, and Stack can be
+    //   read by anyone but only written to by explicit stack writing operations.
+    //   Of course, claiming to also write World is not wrong; it'll just
+    //   pessimise some important optimizations.
+    //
     // - We cannot hoist, or sink, anything that has effects. This means that the
     //   easiest way of indicating that something cannot be hoisted is to claim
     //   that it side-effects some miscellaneous thing.
@@ -60,9 +60,9 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     //   versions of those nodes that backward-exit instead, but I'm not convinced
     //   of the soundness.
     //
-    // - Some nodes lie, and claim that they do not read the JSCell_structureID, JSCell_typeInfoFlags, etc.
-    //   These are nodes that use the structure in a way that does not depend on
-    //   things that change under structure transitions.
+    // - Some nodes lie, and claim that they do not read the JSCell_structureID,
+    //   JSCell_typeInfoFlags, etc. These are nodes that use the structure in a way
+    //   that does not depend on things that change under structure transitions.
     //
     // - It's implicitly understood that OSR exits read the world. This is why we
     //   generally don't move or eliminate stores. Every node can exit, so the
@@ -77,7 +77,33 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     //   can use it for IR dumps. No promises on whether the answers are sound
     //   prior to type inference - though they probably could be if we did some
     //   small hacking.
+    //
+    // - If you do read(Stack) or read(World), then make sure that readTop() in
+    //   PreciseLocalClobberize is correct.
     
+    // While read() and write() are fairly self-explanatory - they track what sorts of things the
+    // node may read or write - the def() functor is more tricky. It tells you the heap locations
+    // (not just abstract heaps) that are defined by a node. A heap location comprises an abstract
+    // heap, some nodes, and a LocationKind. Briefly, a location defined by a node is a location
+    // whose value can be deduced from looking at the node itself. The locations returned must obey
+    // the following properties:
+    //
+    // - If someone wants to CSE a load from the heap, then a HeapLocation object should be
+    //   sufficient to find a single matching node.
+    //
+    // - The abstract heap is the only abstract heap that could be clobbered to invalidate any such
+    //   CSE attempt. I.e. if clobberize() reports that on every path between some node and a node
+    //   that defines a HeapLocation that it wanted, there were no writes to any abstract heap that
+    //   overlap the location's heap, then we have a sound match. Effectively, the semantics of
+    //   write() and def() are intertwined such that for them to be sound they must agree on what
+    //   is CSEable.
+    //
+    // read(), write(), and def() for heap locations is enough to do GCSE on effectful things. To
+    // keep things simple, this code will also def() pure things. def() must be overloaded to also
+    // accept PureValue. This way, a client of clobberize() can implement GCSE entirely using the
+    // information that clobberize() passes to write() and def(). Other clients of clobberize() can
+    // just ignore def() by using a NoOpClobberize functor.
+
     if (edgesUseStructure(graph, node))
         read(JSCell_structureID);
     
@@ -85,34 +111,35 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
+        def(PureValue(node, node->constant()));
+        return;
+        
     case Identity:
     case Phantom:
-    case HardPhantom:
+    case Check:
+    case ExtractOSREntryLocal:
+    case CheckStructureImmediate:
+        return;
+        
     case BitAnd:
     case BitOr:
     case BitXor:
     case BitLShift:
     case BitRShift:
     case BitURShift:
-    case ValueToInt32:
-    case ArithAdd:
-    case ArithSub:
-    case ArithNegate:
-    case ArithMul:
     case ArithIMul:
-    case ArithDiv:
-    case ArithMod:
     case ArithAbs:
+    case ArithClz32:
     case ArithMin:
     case ArithMax:
+    case ArithPow:
     case ArithSqrt:
     case ArithFRound:
     case ArithSin:
     case ArithCos:
+    case ArithLog:
     case GetScope:
     case SkipScope:
-    case CheckFunction:
     case StringCharCodeAt:
     case StringFromCharCode:
     case CompareEqConstant:
@@ -121,80 +148,224 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     case IsBoolean:
     case IsNumber:
     case IsString:
+    case IsObject:
     case LogicalNot:
-    case ExtractOSREntryLocal:
     case CheckInBounds:
-    case ConstantStoragePointer:
-    case UInt32ToNumber:
-    case DoubleAsInt32:
-    case Check:
     case DoubleRep:
     case ValueRep:
     case Int52Rep:
     case BooleanToNumber:
     case FiatInt52:
+    case MakeRope:
+    case ValueToInt32:
+    case GetExecutable:
+    case BottomValue:
+    case TypeOf:
+        def(PureValue(node));
         return;
         
+    case HasGenericProperty:
+    case HasStructureProperty:
+    case GetEnumerableLength:
+    case GetPropertyEnumerator: {
+        read(Heap);
+        write(SideState);
+        return;
+    }
+
+    case GetDirectPname: {
+        // This reads and writes heap because it can end up calling a generic getByVal 
+        // if the Structure changed, which could in turn end up calling a getter.
+        read(World);
+        write(Heap);
+        return;
+    }
+
+    case ToIndexString:
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname: {
+        def(PureValue(node));
+        return;
+    }
+
+    case HasIndexedProperty: {
+        read(JSObject_butterfly);
+        ArrayMode mode = node->arrayMode();
+        switch (mode.type()) {
+        case Array::Int32: {
+            if (mode.isInBounds()) {
+                read(Butterfly_publicLength);
+                read(IndexedInt32Properties);
+                def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), LazyNode(node));
+                return;
+            }
+            read(Heap);
+            return;
+        }
+            
+        case Array::Double: {
+            if (mode.isInBounds()) {
+                read(Butterfly_publicLength);
+                read(IndexedDoubleProperties);
+                def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), LazyNode(node));
+                return;
+            }
+            read(Heap);
+            return;
+        }
+            
+        case Array::Contiguous: {
+            if (mode.isInBounds()) {
+                read(Butterfly_publicLength);
+                read(IndexedContiguousProperties);
+                def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), LazyNode(node));
+                return;
+            }
+            read(Heap);
+            return;
+        }
+
+        case Array::ArrayStorage: {
+            if (mode.isInBounds()) {
+                read(Butterfly_vectorLength);
+                read(IndexedArrayStorageProperties);
+                return;
+            }
+            read(Heap);
+            return;
+        }
+
+        default: {
+            read(World);
+            write(Heap);
+            return;
+        }
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return;
+    }
+
+    case ArithAdd:
+    case ArithSub:
+    case ArithNegate:
+    case ArithMul:
+    case ArithDiv:
+    case ArithMod:
+    case DoubleAsInt32:
+    case UInt32ToNumber:
+        def(PureValue(node, node->arithMode()));
+        return;
+
+    case ArithRound:
+        def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
+        return;
+
+    case CheckCell:
+        def(PureValue(CheckCell, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->cellOperand()));
+        return;
+
+    case CheckNotEmpty:
+        def(PureValue(CheckNotEmpty, AdjacencyList(AdjacencyList::Fixed, node->child1())));
+        return;
+
+    case ConstantStoragePointer:
+        def(PureValue(node, node->storagePointer()));
+        return;
+         
     case MovHint:
     case ZombieHint:
+    case KillStack:
     case Upsilon:
     case Phi:
-    case Flush:
     case PhantomLocal:
     case SetArgument:
-    case PhantomArguments:
     case Jump:
     case Branch:
     case Switch:
     case Throw:
     case ForceOSRExit:
+    case CheckBadCell:
     case Return:
     case Unreachable:
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
     case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter:
     case LoopHint:
-    case InvalidationPoint:
     case Breakpoint:
     case ProfileWillCall:
     case ProfileDidCall:
+    case ProfileType:
+    case ProfileControlFlow:
+    case StoreBarrier:
+    case PutHint:
         write(SideState);
         return;
         
-    case VariableWatchpoint:
-    case TypedArrayWatchpoint:
-        read(Watchpoint_fire);
+    case InvalidationPoint:
         write(SideState);
+        def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), LazyNode(node));
         return;
-        
+
+    case Flush:
+        read(AbstractHeap(Stack, node->local()));
+        write(SideState);
+        return;
+
     case NotifyWrite:
         write(Watchpoint_fire);
         write(SideState);
         return;
 
-    case CreateActivation:
-    case CreateArguments:
-        clobberizeForAllocation(read, write);
-        write(SideState);
-        write(Watchpoint_fire);
+    case CreateActivation: {
+        SymbolTable* table = node->castOperand<SymbolTable*>();
+        if (table->singletonScope()->isStillValid())
+            write(Watchpoint_fire);
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+    }
+        
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+        read(Stack);
+        read(HeapObjectCount);
+        write(HeapObjectCount);
         return;
+
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+        // DFG backend requires that the locals that this reads are flushed. FTL backend can handle those
+        // locals being promoted.
+        if (!isFTL(graph.m_plan.mode))
+            read(Stack);
         
-    case FunctionReentryWatchpoint:
-        read(Watchpoint_fire);
+        // Even though it's phantom, it still has the property that one can't be replaced with another.
+        read(HeapObjectCount);
+        write(HeapObjectCount);
         return;
 
     case ToThis:
     case CreateThis:
         read(MiscFields);
-        clobberizeForAllocation(read, write);
+        read(HeapObjectCount);
+        write(HeapObjectCount);
         return;
 
     case VarInjectionWatchpoint:
-    case AllocationProfileWatchpoint:
-    case IsObject:
+        read(MiscFields);
+        def(HeapLocation(VarInjectionWatchpointLoc, MiscFields), LazyNode(node));
+        return;
+
+    case IsObjectOrNull:
+        read(MiscFields);
+        def(HeapLocation(IsObjectOrNullLoc, MiscFields, node->child1()), LazyNode(node));
+        return;
+        
     case IsFunction:
-    case TypeOf:
         read(MiscFields);
+        def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node));
         return;
         
     case GetById:
@@ -206,30 +377,87 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     case ArrayPop:
     case Call:
     case Construct:
+    case NativeCall:
+    case NativeConstruct:
+    case CallVarargs:
+    case CallForwardVarargs:
+    case ConstructVarargs:
+    case ConstructForwardVarargs:
     case ToPrimitive:
     case In:
-    case GetMyArgumentsLengthSafe:
-    case GetMyArgumentByValSafe:
     case ValueAdd:
         read(World);
-        write(World);
+        write(Heap);
+        return;
+        
+    case GetGetter:
+        read(GetterSetter_getter);
+        def(HeapLocation(GetterLoc, GetterSetter_getter, node->child1()), LazyNode(node));
+        return;
+        
+    case GetSetter:
+        read(GetterSetter_setter);
+        def(HeapLocation(SetterLoc, GetterSetter_setter, node->child1()), LazyNode(node));
         return;
         
     case GetCallee:
-        read(AbstractHeap(Variables, JSStack::Callee));
+        read(AbstractHeap(Stack, JSStack::Callee));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, JSStack::Callee)), LazyNode(node));
+        return;
+        
+    case GetArgumentCount:
+        read(AbstractHeap(Stack, JSStack::ArgumentCount));
+        def(HeapLocation(StackPayloadLoc, AbstractHeap(Stack, JSStack::ArgumentCount)), LazyNode(node));
         return;
         
     case GetLocal:
-    case GetArgument:
-        read(AbstractHeap(Variables, node->local()));
+        read(AbstractHeap(Stack, node->local()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), LazyNode(node));
         return;
         
     case SetLocal:
-        write(AbstractHeap(Variables, node->local()));
+        write(AbstractHeap(Stack, node->local()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), LazyNode(node->child1().node()));
+        return;
+        
+    case GetStack: {
+        AbstractHeap heap(Stack, node->stackAccessData()->local);
+        read(heap);
+        def(HeapLocation(StackLoc, heap), LazyNode(node));
         return;
+    }
+        
+    case PutStack: {
+        AbstractHeap heap(Stack, node->stackAccessData()->local);
+        write(heap);
+        def(HeapLocation(StackLoc, heap), LazyNode(node->child1().node()));
+        return;
+    }
+        
+    case LoadVarargs: {
+        read(World);
+        write(Heap);
+        LoadVarargsData* data = node->loadVarargsData();
+        write(AbstractHeap(Stack, data->count.offset()));
+        for (unsigned i = data->limit; i--;)
+            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
+        return;
+    }
+        
+    case ForwardVarargs: {
+        // We could be way more precise here.
+        read(Stack);
+        
+        LoadVarargsData* data = node->loadVarargsData();
+        write(AbstractHeap(Stack, data->count.offset()));
+        for (unsigned i = data->limit; i--;)
+            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
+        return;
+    }
         
     case GetLocalUnlinked:
-        read(AbstractHeap(Variables, node->unlinkedLocal()));
+        read(AbstractHeap(Stack, node->unlinkedLocal()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->unlinkedLocal())), LazyNode(node));
         return;
         
     case GetByVal: {
@@ -240,7 +468,7 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         case Array::Undecided:
             // Assume the worst since we don't have profiling yet.
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::ForceExit:
@@ -249,61 +477,71 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
             
         case Array::Generic:
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::String:
             if (mode.isOutOfBounds()) {
                 read(World);
-                write(World);
+                write(Heap);
                 return;
             }
             // This appears to read nothing because it's only reading immutable data.
+            def(PureValue(node, mode.asWord()));
             return;
             
-        case Array::Arguments:
-            read(Arguments_registers);
-            read(Variables);
+        case Array::DirectArguments:
+            read(DirectArgumentsProperties);
+            def(HeapLocation(IndexedPropertyLoc, DirectArgumentsProperties, node->child1(), node->child2()), LazyNode(node));
+            return;
+            
+        case Array::ScopedArguments:
+            read(ScopeProperties);
+            def(HeapLocation(IndexedPropertyLoc, ScopeProperties, node->child1(), node->child2()), LazyNode(node));
             return;
             
         case Array::Int32:
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
-                read(Butterfly_vectorLength);
                 read(IndexedInt32Properties);
+                def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), LazyNode(node));
                 return;
             }
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::Double:
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
-                read(Butterfly_vectorLength);
                 read(IndexedDoubleProperties);
+                def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), LazyNode(node));
                 return;
             }
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::Contiguous:
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
-                read(Butterfly_vectorLength);
                 read(IndexedContiguousProperties);
+                def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), LazyNode(node));
                 return;
             }
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
-            // Give up on life for now.
+            if (mode.isInBounds()) {
+                read(Butterfly_vectorLength);
+                read(IndexedArrayStorageProperties);
+                return;
+            }
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::Int8Array:
@@ -316,26 +554,35 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         case Array::Float32Array:
         case Array::Float64Array:
             read(TypedArrayProperties);
-            read(JSArrayBufferView_vector);
-            read(JSArrayBufferView_length);
+            read(MiscFields);
+            def(HeapLocation(IndexedPropertyLoc, TypedArrayProperties, node->child1(), node->child2()), LazyNode(node));
             return;
         }
         RELEASE_ASSERT_NOT_REACHED();
         return;
     }
+        
+    case GetMyArgumentByVal: {
+        read(Stack);
+        // FIXME: It would be trivial to have a def here.
+        // https://bugs.webkit.org/show_bug.cgi?id=143077
+        return;
+    }
 
     case PutByValDirect:
     case PutByVal:
     case PutByValAlias: {
         ArrayMode mode = node->arrayMode();
+        Node* base = graph.varArgChild(node, 0).node();
+        Node* index = graph.varArgChild(node, 1).node();
+        Node* value = graph.varArgChild(node, 2).node();
         switch (mode.modeForPut().type()) {
         case Array::SelectUsingPredictions:
         case Array::Unprofiled:
         case Array::Undecided:
-        case Array::String:
             // Assume the worst since we don't have profiling yet.
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         case Array::ForceExit:
@@ -344,57 +591,59 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
             
         case Array::Generic:
             read(World);
-            write(World);
-            return;
-            
-        case Array::Arguments:
-            read(Arguments_registers);
-            read(Arguments_numArguments);
-            read(Arguments_slowArguments);
-            write(Variables);
+            write(Heap);
             return;
             
         case Array::Int32:
             if (node->arrayMode().isOutOfBounds()) {
                 read(World);
-                write(World);
+                write(Heap);
                 return;
             }
             read(Butterfly_publicLength);
             read(Butterfly_vectorLength);
             read(IndexedInt32Properties);
             write(IndexedInt32Properties);
+            if (node->arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, base, index), LazyNode(value));
             return;
             
         case Array::Double:
             if (node->arrayMode().isOutOfBounds()) {
                 read(World);
-                write(World);
+                write(Heap);
                 return;
             }
             read(Butterfly_publicLength);
             read(Butterfly_vectorLength);
             read(IndexedDoubleProperties);
             write(IndexedDoubleProperties);
+            if (node->arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, base, index), LazyNode(value));
             return;
             
         case Array::Contiguous:
             if (node->arrayMode().isOutOfBounds()) {
                 read(World);
-                write(World);
+                write(Heap);
                 return;
             }
             read(Butterfly_publicLength);
             read(Butterfly_vectorLength);
             read(IndexedContiguousProperties);
             write(IndexedContiguousProperties);
+            if (node->arrayMode().mayStoreToHole())
+                write(Butterfly_publicLength);
+            def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, base, index), LazyNode(value));
             return;
             
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
             // Give up on life for now.
             read(World);
-            write(World);
+            write(Heap);
             return;
 
         case Array::Int8Array:
@@ -406,9 +655,15 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         case Array::Uint32Array:
         case Array::Float32Array:
         case Array::Float64Array:
-            read(JSArrayBufferView_vector);
-            read(JSArrayBufferView_length);
+            read(MiscFields);
             write(TypedArrayProperties);
+            // FIXME: We can't def() anything here because these operations truncate their inputs.
+            // https://bugs.webkit.org/show_bug.cgi?id=134737
+            return;
+        case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
+            DFG_CRASH(graph, node, "impossible array mode for put");
             return;
         }
         RELEASE_ASSERT_NOT_REACHED();
@@ -416,8 +671,6 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     }
         
     case CheckStructure:
-    case StructureTransitionWatchpoint:
-    case InstanceOf:
         read(JSCell_structureID);
         return;
 
@@ -429,14 +682,15 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
 
     case CheckHasInstance:
         read(JSCell_typeInfoFlags);
+        def(HeapLocation(CheckHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
         return;
 
-    case CheckExecutable:
-        read(JSFunction_executable);
+    case InstanceOf:
+        read(JSCell_structureID);
+        def(HeapLocation(InstanceOfLoc, JSCell_structureID, node->child1(), node->child2()), LazyNode(node));
         return;
-        
+
     case PutStructure:
-    case PhantomPutStructure:
         write(JSCell_structureID);
         write(JSCell_typeInfoType);
         write(JSCell_typeInfoFlags);
@@ -445,17 +699,18 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         
     case AllocatePropertyStorage:
         write(JSObject_butterfly);
-        clobberizeForAllocation(read, write);
+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
         return;
         
     case ReallocatePropertyStorage:
         read(JSObject_butterfly);
         write(JSObject_butterfly);
-        clobberizeForAllocation(read, write);
+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
         return;
         
     case GetButterfly:
         read(JSObject_butterfly);
+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
         return;
         
     case Arrayify:
@@ -467,47 +722,60 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         write(JSCell_indexingType);
         write(JSObject_butterfly);
         write(Watchpoint_fire);
-        clobberizeForAllocation(read, write);
         return;
         
     case GetIndexedPropertyStorage:
-        if (node->arrayMode().type() == Array::String)
+        if (node->arrayMode().type() == Array::String) {
+            def(PureValue(node, node->arrayMode().asWord()));
             return;
-        read(JSArrayBufferView_vector);
+        }
+        read(MiscFields);
+        def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node->child1()), LazyNode(node));
         return;
         
     case GetTypedArrayByteOffset:
-        read(JSArrayBufferView_vector);
-        read(JSArrayBufferView_mode);
-        read(Butterfly_arrayBuffer);
-        read(ArrayBuffer_data);
+        read(MiscFields);
+        def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node->child1()), LazyNode(node));
         return;
         
     case GetByOffset:
-        read(AbstractHeap(NamedProperties, graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber));
+    case GetGetterSetterByOffset: {
+        unsigned identifierNumber = node->storageAccessData().identifierNumber;
+        AbstractHeap heap(NamedProperties, identifierNumber);
+        read(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node->child2()), LazyNode(node));
         return;
+    }
         
-    case MultiGetByOffset:
+    case MultiGetByOffset: {
         read(JSCell_structureID);
         read(JSObject_butterfly);
-        read(AbstractHeap(NamedProperties, node->multiGetByOffsetData().identifierNumber));
+        AbstractHeap heap(NamedProperties, node->multiGetByOffsetData().identifierNumber);
+        read(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node->child1()), LazyNode(node));
         return;
+    }
         
-    case MultiPutByOffset:
+    case MultiPutByOffset: {
         read(JSCell_structureID);
         read(JSObject_butterfly);
-        write(AbstractHeap(NamedProperties, node->multiPutByOffsetData().identifierNumber));
+        AbstractHeap heap(NamedProperties, node->multiPutByOffsetData().identifierNumber);
+        write(heap);
         if (node->multiPutByOffsetData().writesStructures())
             write(JSCell_structureID);
-        if (node->multiPutByOffsetData().reallocatesStorage()) {
+        if (node->multiPutByOffsetData().reallocatesStorage())
             write(JSObject_butterfly);
-            clobberizeForAllocation(read, write);
-        }
+        def(HeapLocation(NamedPropertyLoc, heap, node->child1()), LazyNode(node->child2().node()));
         return;
+    }
         
-    case PutByOffset:
-        write(AbstractHeap(NamedProperties, graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber));
+    case PutByOffset: {
+        unsigned identifierNumber = node->storageAccessData().identifierNumber;
+        AbstractHeap heap(NamedProperties, identifierNumber);
+        write(heap);
+        def(HeapLocation(NamedPropertyLoc, heap, node->child2()), LazyNode(node->child3().node()));
         return;
+    }
         
     case GetArrayLength: {
         ArrayMode mode = node->arrayMode();
@@ -518,77 +786,179 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
             read(Butterfly_publicLength);
+            def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node->child1()), LazyNode(node));
             return;
             
         case Array::String:
+            def(PureValue(node, mode.asWord()));
             return;
             
-        case Array::Arguments:
-            read(Arguments_overrideLength);
-            read(Arguments_numArguments);
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
+            read(MiscFields);
+            def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), LazyNode(node));
             return;
             
         default:
-            read(JSArrayBufferView_length);
+            ASSERT(mode.typedArrayType() != NotTypedArray);
+            read(MiscFields);
+            def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), LazyNode(node));
             return;
         }
     }
         
-    case GetMyScope:
-        read(AbstractHeap(Variables, JSStack::ScopeChain));
-        return;
-        
-    case SkipTopScope:
-        read(AbstractHeap(Variables, graph.activationRegister()));
+    case GetClosureVar:
+        read(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), LazyNode(node));
         return;
         
-    case GetClosureRegisters:
-        read(JSVariableObject_registers);
+    case PutClosureVar:
+        write(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), LazyNode(node->child2().node()));
         return;
         
-    case GetClosureVar:
-        read(AbstractHeap(Variables, node->varNumber()));
+    case GetFromArguments: {
+        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
+        read(heap);
+        def(HeapLocation(DirectArgumentsLoc, heap, node->child1()), LazyNode(node));
         return;
+    }
         
-    case PutClosureVar:
-        write(AbstractHeap(Variables, node->varNumber()));
+    case PutToArguments: {
+        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
+        write(heap);
+        def(HeapLocation(DirectArgumentsLoc, heap, node->child1()), LazyNode(node->child2().node()));
         return;
+    }
         
     case GetGlobalVar:
-        read(AbstractHeap(Absolute, node->registerPointer()));
+        read(AbstractHeap(Absolute, node->variablePointer()));
+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node));
         return;
         
     case PutGlobalVar:
-        write(AbstractHeap(Absolute, node->registerPointer()));
+        write(AbstractHeap(Absolute, node->variablePointer()));
+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node->child2().node()));
         return;
 
-    case NewObject:
-    case NewArray:
     case NewArrayWithSize:
-    case NewArrayBuffer:
-    case NewRegexp:
-    case NewStringObject:
-    case MakeRope:
-    case NewFunctionNoCheck:
-    case NewFunction:
-    case NewFunctionExpression:
-        clobberizeForAllocation(read, write);
-        return;
-        
     case NewTypedArray:
-        clobberizeForAllocation(read, write);
-        switch (node->child1().useKind()) {
-        case Int32Use:
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+
+    case NewArray: {
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+
+        unsigned numElements = node->numChildren();
+
+        def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
+            LazyNode(graph.freeze(jsNumber(numElements))));
+
+        if (!numElements)
             return;
-        case UntypedUse:
-            read(World);
-            write(World);
+
+        AbstractHeap heap;
+        switch (node->indexingType()) {
+        case ALL_DOUBLE_INDEXING_TYPES:
+            heap = IndexedDoubleProperties;
+            break;
+
+        case ALL_INT32_INDEXING_TYPES:
+            heap = IndexedInt32Properties;
+            break;
+
+        case ALL_CONTIGUOUS_INDEXING_TYPES:
+            heap = IndexedContiguousProperties;
+            break;
+
+        default:
             return;
+        }
+
+        if (numElements < graph.m_uint32ValuesInUse.size()) {
+            for (unsigned operandIdx = 0; operandIdx < numElements; ++operandIdx) {
+                Edge use = graph.m_varArgChildren[node->firstChild() + operandIdx];
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
+                    LazyNode(use.node()));
+            }
+        } else {
+            for (uint32_t operandIdx : graph.m_uint32ValuesInUse) {
+                if (operandIdx >= numElements)
+                    continue;
+                Edge use = graph.m_varArgChildren[node->firstChild() + operandIdx];
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
+                    LazyNode(use.node()));
+            }
+        }
+        return;
+    }
+
+    case NewArrayBuffer: {
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+
+        unsigned numElements = node->numConstants();
+        def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
+            LazyNode(graph.freeze(jsNumber(numElements))));
+
+        AbstractHeap heap;
+        NodeType op = JSConstant;
+        switch (node->indexingType()) {
+        case ALL_DOUBLE_INDEXING_TYPES:
+            heap = IndexedDoubleProperties;
+            op = DoubleConstant;
+            break;
+
+        case ALL_INT32_INDEXING_TYPES:
+            heap = IndexedInt32Properties;
+            break;
+
+        case ALL_CONTIGUOUS_INDEXING_TYPES:
+            heap = IndexedContiguousProperties;
+            break;
+
         default:
-            RELEASE_ASSERT_NOT_REACHED();
             return;
         }
+
+        JSValue* data = graph.m_codeBlock->constantBuffer(node->startConstant());
+        if (numElements < graph.m_uint32ValuesInUse.size()) {
+            for (unsigned index = 0; index < numElements; ++index) {
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
+                    LazyNode(graph.freeze(data[index]), op));
+            }
+        } else {
+            for (uint32_t index : graph.m_uint32ValuesInUse) {
+                if (index >= numElements)
+                    continue;
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
+                    LazyNode(graph.freeze(data[index]), op));
+            }
+        }
+        return;
+    }
+
+    case NewObject:
+    case NewRegexp:
+    case NewStringObject:
+    case PhantomNewObject:
+    case MaterializeNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case MaterializeCreateActivation:
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
         
+    case NewFunction:
+        if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid())
+            write(Watchpoint_fire);
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+
     case RegExpExec:
     case RegExpTest:
         read(RegExpState);
@@ -598,9 +968,10 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     case StringCharAt:
         if (node->arrayMode().isOutOfBounds()) {
             read(World);
-            write(World);
+            write(Heap);
             return;
         }
+        def(PureValue(node));
         return;
         
     case CompareEq:
@@ -608,53 +979,38 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
     case CompareLessEq:
     case CompareGreater:
     case CompareGreaterEq:
-        if (!node->isBinaryUseKind(UntypedUse))
+        if (!node->isBinaryUseKind(UntypedUse)) {
+            def(PureValue(node));
             return;
+        }
         read(World);
-        write(World);
+        write(Heap);
         return;
         
     case ToString:
+    case CallStringConstructor:
         switch (node->child1().useKind()) {
         case StringObjectUse:
         case StringOrStringObjectUse:
+            // These don't def a pure value, unfortunately. I'll avoid load-eliminating these for
+            // now.
             return;
             
         case CellUse:
         case UntypedUse:
             read(World);
-            write(World);
+            write(Heap);
             return;
             
         default:
             RELEASE_ASSERT_NOT_REACHED();
             return;
         }
-
-    case TearOffActivation:
-        write(JSVariableObject_registers);
-        return;
-        
-    case TearOffArguments:
-        write(Arguments_registers);
-        return;
-        
-    case GetMyArgumentsLength:
-        read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
-        read(AbstractHeap(Variables, JSStack::ArgumentCount));
-        return;
         
-    case GetMyArgumentByVal:
-        read(Variables);
-        return;
-        
-    case CheckArgumentsNotCreated:
-        read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
-        return;
-
     case ThrowReferenceError:
         write(SideState);
-        clobberizeForAllocation(read, write);
+        read(HeapObjectCount);
+        write(HeapObjectCount);
         return;
         
     case CountExecution:
@@ -662,25 +1018,20 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
         read(InternalState);
         write(InternalState);
         return;
-
-    case StoreBarrier:
-    case StoreBarrierWithNullCheck:
-        read(BarrierState);
-        write(BarrierState);
-        return;
         
     case LastNodeType:
         RELEASE_ASSERT_NOT_REACHED();
         return;
     }
     
-    RELEASE_ASSERT_NOT_REACHED();
+    DFG_CRASH(graph, node, toCString("Unrecognized node type: ", Graph::opName(node->op())).data());
 }
 
 class NoOpClobberize {
 public:
     NoOpClobberize() { }
-    void operator()(AbstractHeap) { }
+    template<typename... T>
+    void operator()(T...) const { }
 };
 
 class CheckClobberize {
@@ -690,12 +1041,13 @@ public:
     {
     }
     
-    void operator()(AbstractHeap) { m_result = true; }
+    template<typename... T>
+    void operator()(T...) const { m_result = true; }
     
     bool result() const { return m_result; }
     
 private:
-    bool m_result;
+    mutable bool m_result;
 };
 
 bool doesWrites(Graph&, Node*);
@@ -708,7 +1060,7 @@ public:
     {
     }
     
-    void operator()(AbstractHeap otherHeap)
+    void operator()(AbstractHeap otherHeap) const
     {
         if (m_result)
             return;
@@ -719,11 +1071,80 @@ public:
 
 private:
     AbstractHeap m_heap;
-    bool m_result;
+    mutable bool m_result;
 };
 
+bool accessesOverlap(Graph&, Node*, AbstractHeap);
 bool writesOverlap(Graph&, Node*, AbstractHeap);
 
+bool clobbersHeap(Graph&, Node*);
+
+// We would have used bind() for these, but because of the overlaoding that we are doing,
+// it's quite a bit of clearer to just write this out the traditional way.
+
+template<typename T>
+class ReadMethodClobberize {
+public:
+    ReadMethodClobberize(T& value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(AbstractHeap heap) const
+    {
+        m_value.read(heap);
+    }
+private:
+    T& m_value;
+};
+
+template<typename T>
+class WriteMethodClobberize {
+public:
+    WriteMethodClobberize(T& value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(AbstractHeap heap) const
+    {
+        m_value.write(heap);
+    }
+private:
+    T& m_value;
+};
+
+template<typename T>
+class DefMethodClobberize {
+public:
+    DefMethodClobberize(T& value)
+        : m_value(value)
+    {
+    }
+    
+    void operator()(PureValue value) const
+    {
+        m_value.def(value);
+    }
+    
+    void operator()(HeapLocation location, LazyNode node) const
+    {
+        m_value.def(location, node);
+    }
+
+private:
+    T& m_value;
+};
+
+template<typename Adaptor>
+void clobberize(Graph& graph, Node* node, Adaptor& adaptor)
+{
+    ReadMethodClobberize<Adaptor> read(adaptor);
+    WriteMethodClobberize<Adaptor> write(adaptor);
+    DefMethodClobberize<Adaptor> def(adaptor);
+    clobberize(graph, node, read, write, def);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGCombinedLiveness.cpp b/dfg/DFGCombinedLiveness.cpp
new file mode 100644 (file)
index 0000000..ccf9433
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGCombinedLiveness.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAvailabilityMap.h"
+#include "DFGBlockMapInlines.h"
+#include "FullBytecodeLiveness.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+HashSet<Node*> liveNodesAtHead(Graph& graph, BasicBlock* block)
+{
+    HashSet<Node*> seen;
+    for (Node* node : block->ssa->liveAtHead)
+        seen.add(node);
+    
+    AvailabilityMap& availabilityMap = block->ssa->availabilityAtHead;
+    graph.forAllLocalsLiveInBytecode(
+        block->firstOrigin().forExit,
+        [&] (VirtualRegister reg) {
+            availabilityMap.closeStartingWithLocal(
+                reg,
+                [&] (Node* node) -> bool {
+                    return seen.contains(node);
+                },
+                [&] (Node* node) -> bool {
+                    return seen.add(node).isNewEntry;
+                });
+        });
+    
+    return seen;
+}
+
+CombinedLiveness::CombinedLiveness(Graph& graph)
+    : liveAtHead(graph)
+    , liveAtTail(graph)
+{
+    // First compute the liveAtHead for each block.
+    for (BasicBlock* block : graph.blocksInNaturalOrder())
+        liveAtHead[block] = liveNodesAtHead(graph, block);
+    
+    // Now compute the liveAtTail by unifying the liveAtHead of the successors.
+    for (BasicBlock* block : graph.blocksInNaturalOrder()) {
+        for (BasicBlock* successor : block->successors()) {
+            for (Node* node : liveAtHead[successor])
+                liveAtTail[block].add(node);
+        }
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGCombinedLiveness.h b/dfg/DFGCombinedLiveness.h
new file mode 100644 (file)
index 0000000..ff761cf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGCombinedLiveness_h
+#define DFGCombinedLiveness_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMap.h"
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+// Returns the set of nodes live at tail, both due to due DFG and due to bytecode (i.e. OSR exit).
+HashSet<Node*> liveNodesAtHead(Graph&, BasicBlock*);
+
+struct CombinedLiveness {
+    CombinedLiveness() { }
+    
+    CombinedLiveness(Graph&);
+    
+    BlockMap<HashSet<Node*>> liveAtHead;
+    BlockMap<HashSet<Node*>> liveAtTail;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGCombinedLiveness_h
+
index 09ac3402f9d916b3b31b70f9bbc8c3284c0f490b..96ac252df6ff16d85620ac48b68e4b68d8cc1810 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "DFGCommon.h"
 
-#if ENABLE(DFG_JIT)
-
 #include "DFGNode.h"
 #include "JSCInlines.h"
+#include <wtf/PrintStream.h>
+
+#if ENABLE(DFG_JIT)
 
 namespace JSC { namespace DFG {
 
+static StaticSpinLock crashLock;
+
 void startCrashing()
 {
-#if ENABLE(COMPARE_AND_SWAP)
-    static unsigned lock;
-    while (!WTF::weakCompareAndSwap(&lock, 0, 1))
-        std::this_thread::yield();
-#endif
+    crashLock.lock();
+}
+
+bool isCrashing()
+{
+    return crashLock.isLocked();
+}
+
+bool stringLessThan(StringImpl& a, StringImpl& b)
+{
+    unsigned minLength = std::min(a.length(), b.length());
+    for (unsigned i = 0; i < minLength; ++i) {
+        if (a[i] == b[i])
+            continue;
+        return a[i] < b[i];
+    }
+    return a.length() < b.length();
 }
 
 } } // namespace JSC::DFG
@@ -123,3 +138,28 @@ void printInternal(PrintStream& out, ProofStatus status)
 
 #endif // ENABLE(DFG_JIT)
 
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, CapabilityLevel capabilityLevel)
+{
+    switch (capabilityLevel) {
+    case CannotCompile:
+        out.print("CannotCompile");
+        return;
+    case CanCompile:
+        out.print("CanCompile");
+        return;
+    case CanCompileAndInline:
+        out.print("CanCompileAndInline");
+        return;
+    case CapabilityLevelNotSet:
+        out.print("CapabilityLevelNotSet");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
index dbe7ca278b330ef0b51cb3edda634dc1531c12de..df8c8ef0d319389bf348e2eafcafe7b5597c720f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "CodeOrigin.h"
 #include "Options.h"
 #include "VirtualRegister.h"
 
@@ -63,6 +62,13 @@ enum RefNodeMode {
     DontRefNode
 };
 
+enum SwitchKind {
+    SwitchImm,
+    SwitchChar,
+    SwitchString,
+    SwitchCell
+};
+
 inline bool verboseCompilationEnabled(CompilationMode mode = DFGMode)
 {
     return Options::verboseCompilation() || Options::dumpGraphAtEachPhase() || (isFTL(mode) && Options::verboseFTLCompilation());
@@ -146,6 +152,10 @@ enum PredictionPass {
     FixupPass
 };
 
+enum StructureRegistrationState { HaveNotStartedRegistering, AllStructuresAreRegistered };
+
+enum StructureRegistrationResult { StructureRegisteredNormally, StructureRegisteredAndWatched };
+
 enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
 
 // Describes the form you can expect the entire graph to be in.
@@ -182,12 +192,10 @@ enum GraphForm {
     // expect to be live at the head, and which locals they make available at the
     // tail. ThreadedCPS form also implies that:
     //
-    // - GetLocals and SetLocals to uncaptured variables are not redundant within
-    //   a basic block.
+    // - GetLocals and SetLocals are not redundant within a basic block.
     //
     // - All GetLocals and Flushes are linked directly to the last access point
-    //   of the variable, which must not be another GetLocal if the variable is
-    //   uncaptured.
+    //   of the variable, which must not be another GetLocal.
     //
     // - Phantom(Phi) is not legal, but PhantomLocal is.
     //
@@ -245,6 +253,11 @@ inline KillStatus killStatusForDoesKill(bool doesKill)
     return doesKill ? DoesKill : DoesNotKill;
 }
 
+enum class PlanStage {
+    Initial,
+    AfterFixup
+};
+
 template<typename T, typename U>
 bool checkAndSet(T& left, U right)
 {
@@ -259,6 +272,35 @@ bool checkAndSet(T& left, U right)
 // when you're forcing a crash with diagnostics.
 void startCrashing();
 
+JS_EXPORT_PRIVATE bool isCrashing();
+
+struct NodeAndIndex {
+    NodeAndIndex()
+        : node(nullptr)
+        , index(UINT_MAX)
+    {
+    }
+    
+    NodeAndIndex(Node* node, unsigned index)
+        : node(node)
+        , index(index)
+    {
+        ASSERT(!node == (index == UINT_MAX));
+    }
+    
+    bool operator!() const
+    {
+        return !node;
+    }
+    
+    Node* node;
+    unsigned index;
+};
+
+// A less-than operator for strings that is useful for generating string switches. Sorts by <
+// relation on characters. Ensures that if a is a prefix of b, then a < b.
+bool stringLessThan(StringImpl& a, StringImpl& b);
+
 } } // namespace JSC::DFG
 
 namespace WTF {
@@ -279,7 +321,6 @@ namespace JSC { namespace DFG {
 
 enum CapabilityLevel {
     CannotCompile,
-    CanInline,
     CanCompile,
     CanCompileAndInline,
     CapabilityLevelNotSet
@@ -299,7 +340,6 @@ inline bool canCompile(CapabilityLevel level)
 inline bool canInline(CapabilityLevel level)
 {
     switch (level) {
-    case CanInline:
     case CanCompileAndInline:
         return true;
     default:
@@ -312,14 +352,6 @@ inline CapabilityLevel leastUpperBound(CapabilityLevel a, CapabilityLevel b)
     switch (a) {
     case CannotCompile:
         return CannotCompile;
-    case CanInline:
-        switch (b) {
-        case CanInline:
-        case CanCompileAndInline:
-            return CanInline;
-        default:
-            return CannotCompile;
-        }
     case CanCompile:
         switch (b) {
         case CanCompile:
@@ -351,5 +383,11 @@ inline bool shouldShowDisassembly(CompilationMode mode = DFGMode)
 
 } } // namespace JSC::DFG
 
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::CapabilityLevel);
+
+} // namespace WTF
+
 #endif // DFGCommon_h
 
index ad4d09daafafd8cdee1786a7f399d84837b522d6..73860a1c761ee06395400e99284eada4b1d36326 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 #include "DFGNode.h"
 #include "DFGPlan.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 #include "VM.h"
 
 namespace JSC { namespace DFG {
@@ -41,8 +42,8 @@ void CommonData::notifyCompilingStructureTransition(Plan& plan, CodeBlock* codeB
     plan.transitions.addLazily(
         codeBlock,
         node->origin.semantic.codeOriginOwner(),
-        node->structureTransitionData().previousStructure,
-        node->structureTransitionData().newStructure);
+        node->transition()->previous,
+        node->transition()->next);
 }
 
 unsigned CommonData::addCodeOrigin(CodeOrigin codeOrigin)
@@ -72,6 +73,24 @@ bool CommonData::invalidate()
     return true;
 }
 
+void CommonData::validateReferences(const TrackedReferences& trackedReferences)
+{
+    if (InlineCallFrameSet* set = inlineCallFrames.get()) {
+        for (InlineCallFrame* inlineCallFrame : *set) {
+            for (ValueRecovery& recovery : inlineCallFrame->arguments) {
+                if (recovery.isConstant())
+                    trackedReferences.check(recovery.constant());
+            }
+            
+            if (ScriptExecutable* executable = inlineCallFrame->executable.get())
+                trackedReferences.check(executable);
+            
+            if (inlineCallFrame->calleeRecovery.isConstant())
+                trackedReferences.check(inlineCallFrame->calleeRecovery.constant());
+        }
+    }
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index af5c38dee77234a9683fed7cab50992a841dad30..af4812d9a9bb67a53c79a5475d643b6a92c5e8f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,6 @@
 #include "DFGJumpReplacement.h"
 #include "InlineCallFrameSet.h"
 #include "JSCell.h"
-#include "ProfiledCodeBlockJettisoningWatchpoint.h"
 #include "ProfilerCompilation.h"
 #include "SymbolTable.h"
 #include <wtf/Bag.h>
@@ -42,6 +41,7 @@ namespace JSC {
 
 class CodeBlock;
 class Identifier;
+class TrackedReferences;
 
 namespace DFG {
 
@@ -72,7 +72,6 @@ class CommonData {
 public:
     CommonData()
         : isStillValid(true)
-        , machineCaptureStart(std::numeric_limits<int>::max())
         , frameRegisterCount(std::numeric_limits<unsigned>::max())
         , requiredRegisterCountForExit(std::numeric_limits<unsigned>::max())
     { }
@@ -88,6 +87,8 @@ public:
     {
         return std::max(frameRegisterCount, requiredRegisterCountForExit);
     }
+    
+    void validateReferences(const TrackedReferences&);
 
     RefPtr<InlineCallFrameSet> inlineCallFrames;
     Vector<CodeOrigin, 0, UnsafeVectorOverflow> codeOrigins;
@@ -95,8 +96,8 @@ public:
     Vector<Identifier> dfgIdentifiers;
     Vector<WeakReferenceTransition> transitions;
     Vector<WriteBarrier<JSCell>> weakReferences;
-    SegmentedVector<CodeBlockJettisoningWatchpoint, 1, 0> watchpoints;
-    SegmentedVector<ProfiledCodeBlockJettisoningWatchpoint, 1, 0> profiledWatchpoints;
+    Vector<WriteBarrier<Structure>> weakStructureReferences;
+    SegmentedVector<CodeBlockJettisoningWatchpoint, 1> watchpoints;
     Vector<JumpReplacement> jumpReplacements;
     
     RefPtr<Profiler::Compilation> compilation;
@@ -104,9 +105,6 @@ public:
     bool allTransitionsHaveBeenMarked; // Initialized and used on every GC.
     bool isStillValid;
     
-    int machineCaptureStart;
-    std::unique_ptr<SlowArgument[]> slowArguments;
-
 #if USE(JSVALUE32_64)
     std::unique_ptr<Bag<double>> doubleConstants;
 #endif
index d0059a8362da0e383ba518513ecd3a4dafea28a7..fd8df4d99418c637d48dfa19a38830a5fec238c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAbstractInterpreterInlines.h"
+#include "DFGArgumentsUtilities.h"
 #include "DFGBasicBlock.h"
 #include "DFGGraph.h"
 #include "DFGInPlaceAbstractState.h"
@@ -62,6 +63,16 @@ public:
                 changed |= foldConstants(block);
         }
         
+        if (changed && m_graph.m_form == SSA) {
+            // It's now possible that we have Upsilons pointed at JSConstants. Fix that.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                fixUpsilons(block);
+            }
+        }
+         
         return changed;
     }
 
@@ -76,6 +87,7 @@ private:
             
             Node* node = block->at(indexInBlock);
 
+            bool alreadyHandled = false;
             bool eliminated = false;
                     
             switch (node->op()) {
@@ -86,16 +98,6 @@ private:
                 break;
             }
                 
-            case CheckArgumentsNotCreated: {
-                if (!isEmptySpeculation(
-                        m_state.variables().operand(
-                            m_graph.argumentsRegisterFor(node->origin.semantic)).m_type))
-                    break;
-                node->convertToPhantom();
-                eliminated = true;
-                break;
-            }
-                    
             case CheckStructure:
             case ArrayifyToStructure: {
                 AbstractValue& value = m_state.forNode(node->child1());
@@ -104,27 +106,71 @@ private:
                     set = node->structure();
                 else
                     set = node->structureSet();
-                if (value.m_currentKnownStructure.isSubsetOf(set)) {
+                if (value.m_structure.isSubsetOf(set)) {
                     m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
-                    node->convertToPhantom();
+                    node->remove();
                     eliminated = true;
                     break;
                 }
-                StructureAbstractValue& structureValue = value.m_futurePossibleStructure;
-                if (structureValue.isSubsetOf(set)
-                    && structureValue.hasSingleton()) {
-                    Structure* structure = structureValue.singleton();
-                    m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
-                    AdjacencyList children = node->children;
-                    children.removeEdge(0);
-                    if (!!children.child1())
-                        m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->origin, children);
-                    node->children.setChild2(Edge());
-                    node->children.setChild3(Edge());
-                    node->convertToStructureTransitionWatchpoint(structure);
-                    eliminated = true;
+                break;
+            }
+                
+            case GetIndexedPropertyStorage: {
+                JSArrayBufferView* view = m_graph.tryGetFoldableView(
+                    m_state.forNode(node->child1()).m_value, node->arrayMode());
+                if (!view)
+                    break;
+                
+                if (view->mode() == FastTypedArray) {
+                    // FIXME: It would be awesome to be able to fold the property storage for
+                    // these GC-allocated typed arrays. For now it doesn't matter because the
+                    // most common use-cases for constant typed arrays involve large arrays with
+                    // aliased buffer views.
+                    // https://bugs.webkit.org/show_bug.cgi?id=125425
                     break;
                 }
+                
+                m_interpreter.execute(indexInBlock);
+                eliminated = true;
+                
+                m_insertionSet.insertCheck(indexInBlock, node->origin, node->children);
+                node->convertToConstantStoragePointer(view->vector());
+                break;
+            }
+                
+            case CheckStructureImmediate: {
+                AbstractValue& value = m_state.forNode(node->child1());
+                StructureSet& set = node->structureSet();
+                
+                if (value.value()) {
+                    if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
+                        if (set.contains(structure)) {
+                            m_interpreter.execute(indexInBlock);
+                            node->remove();
+                            eliminated = true;
+                            break;
+                        }
+                    }
+                }
+                
+                if (PhiChildren* phiChildren = m_interpreter.phiChildren()) {
+                    bool allGood = true;
+                    phiChildren->forAllTransitiveIncomingValues(
+                        node,
+                        [&] (Node* incoming) {
+                            if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
+                                if (set.contains(structure))
+                                    return;
+                            }
+                            allGood = false;
+                        });
+                    if (allGood) {
+                        m_interpreter.execute(indexInBlock);
+                        node->remove();
+                        eliminated = true;
+                        break;
+                    }
+                }
                 break;
             }
                 
@@ -132,25 +178,42 @@ private:
             case Arrayify: {
                 if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
                     break;
-                node->convertToPhantom();
+                node->remove();
                 eliminated = true;
                 break;
             }
                 
-            case CheckFunction: {
-                if (m_state.forNode(node->child1()).value() != node->function())
+            case PutStructure: {
+                if (m_state.forNode(node->child1()).m_structure.onlyStructure() != node->transition()->next)
                     break;
-                node->convertToPhantom();
+                
+                node->remove();
                 eliminated = true;
                 break;
             }
                 
+            case CheckCell: {
+                if (m_state.forNode(node->child1()).value() != node->cellOperand()->value())
+                    break;
+                node->remove();
+                eliminated = true;
+                break;
+            }
+
+            case CheckNotEmpty: {
+                if (m_state.forNode(node->child1()).m_type & SpecEmpty)
+                    break;
+                node->remove();
+                eliminated = true;
+                break;
+            }
+
             case CheckInBounds: {
                 JSValue left = m_state.forNode(node->child1()).value();
                 JSValue right = m_state.forNode(node->child2()).value();
                 if (left && right && left.isInt32() && right.isInt32()
                     && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
-                    node->convertToPhantom();
+                    node->remove();
                     eliminated = true;
                     break;
                 }
@@ -158,48 +221,135 @@ private:
                 break;
             }
                 
-            case MultiGetByOffset: {
-                Edge childEdge = node->child1();
-                Node* child = childEdge.node();
-                MultiGetByOffsetData& data = node->multiGetByOffsetData();
-
-                Structure* structure = m_state.forNode(child).bestProvenStructure();
-                if (!structure)
+            case GetMyArgumentByVal: {
+                JSValue index = m_state.forNode(node->child2()).value();
+                if (!index || !index.isInt32())
                     break;
                 
-                for (unsigned i = data.variants.size(); i--;) {
-                    const GetByIdVariant& variant = data.variants[i];
-                    if (!variant.structureSet().contains(structure))
-                        continue;
-                    
-                    if (variant.chain())
+                Node* arguments = node->child1().node();
+                InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
+                
+                // Don't try to do anything if the index is known to be outside our static bounds. Note
+                // that our static bounds are usually strictly larger than the dynamic bounds. The
+                // exception is something like this, assuming foo() is not inlined:
+                //
+                // function foo() { return arguments[5]; }
+                //
+                // Here the static bound on number of arguments is 0, and we're accessing index 5. We
+                // will not strength-reduce this to GetStack because GetStack is otherwise assumed by the
+                // compiler to access those variables that are statically accounted for; for example if
+                // we emitted a GetStack on arg6 we would have out-of-bounds access crashes anywhere that
+                // uses an Operands<> map. There is not much cost to continuing to use a
+                // GetMyArgumentByVal in such statically-out-of-bounds accesses; we just lose CFA unless
+                // GCSE removes the access entirely.
+                if (inlineCallFrame) {
+                    if (index.asUInt32() >= inlineCallFrame->arguments.size() - 1)
                         break;
-                    
-                    emitGetByOffset(indexInBlock, node, structure, variant, data.identifierNumber);
+                } else {
+                    if (index.asUInt32() >= m_state.variables().numberOfArguments() - 1)
+                        break;
+                }
+                
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                
+                StackAccessData* data;
+                if (inlineCallFrame) {
+                    data = m_graph.m_stackAccessData.add(
+                        VirtualRegister(
+                            inlineCallFrame->stackOffset +
+                            CallFrame::argumentOffset(index.asInt32())),
+                        FlushedJSValue);
+                } else {
+                    data = m_graph.m_stackAccessData.add(
+                        virtualRegisterForArgument(index.asInt32() + 1), FlushedJSValue);
+                }
+                
+                if (inlineCallFrame && !inlineCallFrame->isVarargs()
+                    && index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
+                    node->convertToGetStack(data);
                     eliminated = true;
                     break;
                 }
+                
+                Node* length = emitCodeToGetArgumentsArrayLength(
+                    m_insertionSet, arguments, indexInBlock, node->origin);
+                m_insertionSet.insertNode(
+                    indexInBlock, SpecNone, CheckInBounds, node->origin,
+                    node->child2(), Edge(length, Int32Use));
+                node->convertToGetStack(data);
+                eliminated = true;
+                break;
+            }
+                
+            case MultiGetByOffset: {
+                Edge baseEdge = node->child1();
+                Node* base = baseEdge.node();
+                MultiGetByOffsetData& data = node->multiGetByOffsetData();
+
+                // First prune the variants, then check if the MultiGetByOffset can be
+                // strength-reduced to a GetByOffset.
+                
+                AbstractValue baseValue = m_state.forNode(base);
+                
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
+                
+                for (unsigned i = 0; i < data.variants.size(); ++i) {
+                    GetByIdVariant& variant = data.variants[i];
+                    variant.structureSet().filter(baseValue);
+                    if (variant.structureSet().isEmpty()) {
+                        data.variants[i--] = data.variants.last();
+                        data.variants.removeLast();
+                        changed = true;
+                    }
+                }
+                
+                if (data.variants.size() != 1)
+                    break;
+                
+                emitGetByOffset(
+                    indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
+                changed = true;
                 break;
             }
                 
             case MultiPutByOffset: {
-                Edge childEdge = node->child1();
-                Node* child = childEdge.node();
+                Edge baseEdge = node->child1();
+                Node* base = baseEdge.node();
                 MultiPutByOffsetData& data = node->multiPutByOffsetData();
+                
+                AbstractValue baseValue = m_state.forNode(base);
 
-                Structure* structure = m_state.forNode(child).bestProvenStructure();
-                if (!structure)
-                    break;
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
                 
-                for (unsigned i = data.variants.size(); i--;) {
-                    const PutByIdVariant& variant = data.variants[i];
-                    if (variant.oldStructure() != structure)
+
+                for (unsigned i = 0; i < data.variants.size(); ++i) {
+                    PutByIdVariant& variant = data.variants[i];
+                    variant.oldStructure().filter(baseValue);
+                    
+                    if (variant.oldStructure().isEmpty()) {
+                        data.variants[i--] = data.variants.last();
+                        data.variants.removeLast();
+                        changed = true;
                         continue;
+                    }
                     
-                    emitPutByOffset(indexInBlock, node, structure, variant, data.identifierNumber);
-                    eliminated = true;
-                    break;
+                    if (variant.kind() == PutByIdVariant::Transition
+                        && variant.oldStructure().onlyStructure() == variant.newStructure()) {
+                        variant = PutByIdVariant::replace(
+                            variant.oldStructure(),
+                            variant.offset());
+                        changed = true;
+                    }
                 }
+
+                if (data.variants.size() != 1)
+                    break;
+                
+                emitPutByOffset(
+                    indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
+                changed = true;
                 break;
             }
         
@@ -209,29 +359,49 @@ private:
                 Node* child = childEdge.node();
                 unsigned identifierNumber = node->identifierNumber();
                 
-                if (childEdge.useKind() != CellUse)
+                AbstractValue baseValue = m_state.forNode(child);
+
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
+
+                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered()
+                    || (node->child1().useKind() == UntypedUse || (baseValue.m_type & ~SpecCell)))
                     break;
                 
-                Structure* structure = m_state.forNode(child).bestProvenStructure();
-                if (!structure)
-                    break;
-
                 GetByIdStatus status = GetByIdStatus::computeFor(
-                    vm(), structure, m_graph.identifiers()[identifierNumber]);
+                    baseValue.m_structure.set(), m_graph.identifiers()[identifierNumber]);
+                if (!status.isSimple())
+                    break;
+                
+                for (unsigned i = status.numVariants(); i--;) {
+                    if (!status[i].constantChecks().isEmpty()
+                        || status[i].alternateBase()) {
+                        // FIXME: We could handle prototype cases.
+                        // https://bugs.webkit.org/show_bug.cgi?id=110386
+                        break;
+                    }
+                }
                 
-                if (!status.isSimple() || status.numVariants() != 1) {
-                    // FIXME: We could handle prototype cases.
-                    // https://bugs.webkit.org/show_bug.cgi?id=110386
+                if (status.numVariants() == 1) {
+                    emitGetByOffset(indexInBlock, node, baseValue, status[0], identifierNumber);
+                    changed = true;
                     break;
                 }
                 
-                emitGetByOffset(indexInBlock, node, structure, status[0], identifierNumber);
-                eliminated = true;
+                if (!isFTL(m_graph.m_plan.mode))
+                    break;
+                
+                MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add();
+                data->variants = status.variants();
+                data->identifierNumber = identifierNumber;
+                node->convertToMultiGetByOffset(data);
+                changed = true;
                 break;
             }
                 
             case PutById:
-            case PutByIdDirect: {
+            case PutByIdDirect:
+            case PutByIdFlush: {
                 NodeOrigin origin = node->origin;
                 Edge childEdge = node->child1();
                 Node* child = childEdge.node();
@@ -239,44 +409,83 @@ private:
                 
                 ASSERT(childEdge.useKind() == CellUse);
                 
-                Structure* structure = m_state.forNode(child).bestProvenStructure();
-                if (!structure)
+                AbstractValue baseValue = m_state.forNode(child);
+
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
+
+                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered())
                     break;
                 
                 PutByIdStatus status = PutByIdStatus::computeFor(
-                    vm(),
                     m_graph.globalObjectFor(origin.semantic),
-                    structure,
+                    baseValue.m_structure.set(),
                     m_graph.identifiers()[identifierNumber],
                     node->op() == PutByIdDirect);
                 
                 if (!status.isSimple())
                     break;
-                if (status.numVariants() != 1)
+                
+                ASSERT(status.numVariants());
+                
+                if (status.numVariants() > 1 && !isFTL(m_graph.m_plan.mode))
+                    break;
+                
+                changed = true;
+                
+                for (unsigned i = status.numVariants(); i--;)
+                    addChecks(origin, indexInBlock, status[i].constantChecks());
+                
+                if (status.numVariants() == 1) {
+                    emitPutByOffset(indexInBlock, node, baseValue, status[0], identifierNumber);
                     break;
+                }
                 
-                emitPutByOffset(indexInBlock, node, structure, status[0], identifierNumber);
-                eliminated = true;
+                ASSERT(isFTL(m_graph.m_plan.mode));
+
+                MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add();
+                data->variants = status.variants();
+                data->identifierNumber = identifierNumber;
+                node->convertToMultiPutByOffset(data);
                 break;
             }
 
             case ToPrimitive: {
-                if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString))
+                if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))
                     break;
                 
                 node->convertToIdentity();
+                changed = true;
                 break;
             }
-
-            default:
+                
+            case Check: {
+                alreadyHandled = true;
+                m_interpreter.execute(indexInBlock);
+                for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+                    Edge edge = node->children.child(i);
+                    if (!edge)
+                        break;
+                    if (edge.isProved() || edge.willNotHaveCheck()) {
+                        node->children.removeEdge(i--);
+                        changed = true;
+                    }
+                }
                 break;
             }
                 
+            default:
+                break;
+            }
+            
             if (eliminated) {
                 changed = true;
                 continue;
             }
                 
+            if (alreadyHandled)
+                continue;
+            
             m_interpreter.execute(indexInBlock);
             if (!m_state.isValid()) {
                 // If we invalidated then we shouldn't attempt to constant-fold. Here's an
@@ -295,32 +504,23 @@ private:
             }
             if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant())
                 continue;
-            JSValue value = m_state.forNode(node).value();
-            if (!value)
-                continue;
             
-            // Check if merging the abstract value of the constant into the abstract value
-            // we've proven for this node wouldn't widen the proof. If it widens the proof
-            // (i.e. says that the set contains more things in it than it previously did)
-            // then we refuse to fold.
-            AbstractValue oldValue = m_state.forNode(node);
-            AbstractValue constantValue;
-            constantValue.set(m_graph, value);
-            constantValue.fixTypeForRepresentation(node);
-            if (oldValue.merge(constantValue))
+            // Interesting fact: this freezing that we do right here may turn an fragile value into
+            // a weak value. See DFGValueStrength.h.
+            FrozenValue* value = m_graph.freeze(m_state.forNode(node).value());
+            if (!*value)
                 continue;
-                
-            NodeOrigin origin = node->origin;
-            AdjacencyList children = node->children;
             
-            if (node->op() == GetLocal)
+            if (node->op() == GetLocal) {
+                // Need to preserve bytecode liveness in ThreadedCPS form. This wouldn't be necessary
+                // if it wasn't for https://bugs.webkit.org/show_bug.cgi?id=144086.
+                m_insertionSet.insertNode(
+                    indexInBlock, SpecNone, PhantomLocal, node->origin,
+                    OpInfo(node->variableAccessData()));
                 m_graph.dethread();
-            else
-                ASSERT(!node->hasVariableAccessData(m_graph));
-            
+            } else
+                m_insertionSet.insertCheck(indexInBlock, node->origin, node->children);
             m_graph.convertToConstant(node, value);
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, Phantom, origin, children);
             
             changed = true;
         }
@@ -330,38 +530,28 @@ private:
         return changed;
     }
         
-    void emitGetByOffset(unsigned indexInBlock, Node* node, Structure* structure, const GetByIdVariant& variant, unsigned identifierNumber)
+    void emitGetByOffset(unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const GetByIdVariant& variant, unsigned identifierNumber)
     {
         NodeOrigin origin = node->origin;
         Edge childEdge = node->child1();
-        Node* child = childEdge.node();
 
-        bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
-        bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
+        addBaseCheck(indexInBlock, node, baseValue, variant.structureSet());
         
-        ASSERT(!variant.chain());
-        ASSERT(variant.structureSet().contains(structure));
-        
-        // Now before we do anything else, push the CFA forward over the GetById
-        // and make sure we signal to the loop that it should continue and not
-        // do any eliminations.
-        m_interpreter.execute(indexInBlock);
-        
-        if (needsWatchpoint) {
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(structure), childEdge);
-        } else if (needsCellCheck) {
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, Phantom, origin, childEdge);
-        }
-        
-        if (variant.specificValue()) {
-            m_graph.convertToConstant(node, variant.specificValue());
+        JSValue baseForLoad;
+        if (variant.alternateBase())
+            baseForLoad = variant.alternateBase();
+        else
+            baseForLoad = baseValue.m_value;
+        if (JSValue value = m_graph.tryGetConstantProperty(baseForLoad, variant.baseStructure(), variant.offset())) {
+            m_graph.convertToConstant(node, m_graph.freeze(value));
             return;
         }
         
-        childEdge.setUseKind(KnownCellUse);
+        if (variant.alternateBase()) {
+            Node* child = m_insertionSet.insertConstant(indexInBlock, origin, variant.alternateBase());
+            childEdge = Edge(child, KnownCellUse);
+        } else
+            childEdge.setUseKind(KnownCellUse);
         
         Edge propertyStorage;
         
@@ -372,129 +562,131 @@ private:
                 indexInBlock, SpecNone, GetButterfly, origin, childEdge));
         }
         
-        node->convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
+        StorageAccessData& data = *m_graph.m_storageAccessData.add();
+        data.offset = variant.offset();
+        data.identifierNumber = identifierNumber;
         
-        StorageAccessData storageAccessData;
-        storageAccessData.offset = variant.offset();
-        storageAccessData.identifierNumber = identifierNumber;
-        m_graph.m_storageAccessData.append(storageAccessData);
+        node->convertToGetByOffset(data, propertyStorage);
     }
 
-    void emitPutByOffset(unsigned indexInBlock, Node* node, Structure* structure, const PutByIdVariant& variant, unsigned identifierNumber)
+    void emitPutByOffset(unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const PutByIdVariant& variant, unsigned identifierNumber)
     {
         NodeOrigin origin = node->origin;
         Edge childEdge = node->child1();
-        Node* child = childEdge.node();
-
-        ASSERT(variant.oldStructure() == structure);
         
-        bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
-        bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
-        
-        // Now before we do anything else, push the CFA forward over the PutById
-        // and make sure we signal to the loop that it should continue and not
-        // do any eliminations.
-        m_interpreter.execute(indexInBlock);
-
-        if (needsWatchpoint) {
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(structure), childEdge);
-        } else if (needsCellCheck) {
-            m_insertionSet.insertNode(
-                indexInBlock, SpecNone, Phantom, origin, childEdge);
-        }
+        addBaseCheck(indexInBlock, node, baseValue, variant.oldStructure());
 
         childEdge.setUseKind(KnownCellUse);
 
-        StructureTransitionData* transitionData = 0;
+        Transition* transition = 0;
         if (variant.kind() == PutByIdVariant::Transition) {
-            transitionData = m_graph.addStructureTransitionData(
-                StructureTransitionData(structure, variant.newStructure()));
-
-            if (node->op() == PutById) {
-                if (!structure->storedPrototype().isNull()) {
-                    addStructureTransitionCheck(
-                        origin, indexInBlock,
-                        structure->storedPrototype().asCell());
-                }
-
-                m_graph.chains().addLazily(variant.structureChain());
-
-                for (unsigned i = 0; i < variant.structureChain()->size(); ++i) {
-                    JSValue prototype = variant.structureChain()->at(i)->storedPrototype();
-                    if (prototype.isNull())
-                        continue;
-                    ASSERT(prototype.isCell());
-                    addStructureTransitionCheck(
-                        origin, indexInBlock, prototype.asCell());
-                }
-            }
+            transition = m_graph.m_transitions.add(
+                variant.oldStructureForTransition(), variant.newStructure());
         }
 
         Edge propertyStorage;
 
         if (isInlineOffset(variant.offset()))
             propertyStorage = childEdge;
-        else if (
-            variant.kind() == PutByIdVariant::Replace
-            || structure->outOfLineCapacity() == variant.newStructure()->outOfLineCapacity()) {
+        else if (!variant.reallocatesStorage()) {
             propertyStorage = Edge(m_insertionSet.insertNode(
                 indexInBlock, SpecNone, GetButterfly, origin, childEdge));
-        } else if (!structure->outOfLineCapacity()) {
+        } else if (!variant.oldStructureForTransition()->outOfLineCapacity()) {
             ASSERT(variant.newStructure()->outOfLineCapacity());
             ASSERT(!isInlineOffset(variant.offset()));
             Node* allocatePropertyStorage = m_insertionSet.insertNode(
                 indexInBlock, SpecNone, AllocatePropertyStorage,
-                origin, OpInfo(transitionData), childEdge);
-            m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node->child1().node(), KnownCellUse));
+                origin, OpInfo(transition), childEdge);
             propertyStorage = Edge(allocatePropertyStorage);
         } else {
-            ASSERT(structure->outOfLineCapacity());
-            ASSERT(variant.newStructure()->outOfLineCapacity() > structure->outOfLineCapacity());
+            ASSERT(variant.oldStructureForTransition()->outOfLineCapacity());
+            ASSERT(variant.newStructure()->outOfLineCapacity() > variant.oldStructureForTransition()->outOfLineCapacity());
             ASSERT(!isInlineOffset(variant.offset()));
 
             Node* reallocatePropertyStorage = m_insertionSet.insertNode(
                 indexInBlock, SpecNone, ReallocatePropertyStorage, origin,
-                OpInfo(transitionData), childEdge,
+                OpInfo(transition), childEdge,
                 Edge(m_insertionSet.insertNode(
                     indexInBlock, SpecNone, GetButterfly, origin, childEdge)));
-            m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node->child1().node(), KnownCellUse));
             propertyStorage = Edge(reallocatePropertyStorage);
         }
 
+        StorageAccessData& data = *m_graph.m_storageAccessData.add();
+        data.offset = variant.offset();
+        data.identifierNumber = identifierNumber;
+        
+        node->convertToPutByOffset(data, propertyStorage);
+
         if (variant.kind() == PutByIdVariant::Transition) {
-            Node* putStructure = m_graph.addNode(SpecNone, PutStructure, origin, OpInfo(transitionData), childEdge);
-            m_insertionSet.insertNode(indexInBlock, SpecNone, StoreBarrier, origin, Edge(node->child1().node(), KnownCellUse));
-            m_insertionSet.insert(indexInBlock, putStructure);
+            // FIXME: PutStructure goes last until we fix either
+            // https://bugs.webkit.org/show_bug.cgi?id=142921 or
+            // https://bugs.webkit.org/show_bug.cgi?id=142924.
+            m_insertionSet.insertNode(
+                indexInBlock + 1, SpecNone, PutStructure, origin, OpInfo(transition), childEdge);
         }
-
-        node->convertToPutByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
-        m_insertionSet.insertNode(
-            indexInBlock, SpecNone, StoreBarrier, origin, 
-            Edge(node->child2().node(), KnownCellUse));
-
-        StorageAccessData storageAccessData;
-        storageAccessData.offset = variant.offset();
-        storageAccessData.identifierNumber = identifierNumber;
-        m_graph.m_storageAccessData.append(storageAccessData);
     }
-
-    void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell)
+    
+    void addBaseCheck(
+        unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const StructureSet& set)
     {
-        Node* weakConstant = m_insertionSet.insertNode(
-            indexInBlock, speculationFromValue(cell), WeakJSConstant, origin, OpInfo(cell));
-        
-        if (m_graph.watchpoints().isStillValid(cell->structure()->transitionWatchpointSet())) {
+        if (!baseValue.m_structure.isSubsetOf(set)) {
+            // Arises when we prune MultiGetByOffset. We could have a
+            // MultiGetByOffset with a single variant that checks for structure S,
+            // and the input has structures S and T, for example.
             m_insertionSet.insertNode(
-                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
-                OpInfo(cell->structure()), Edge(weakConstant, CellUse));
+                indexInBlock, SpecNone, CheckStructure, node->origin,
+                OpInfo(m_graph.addStructureSet(set)), node->child1());
             return;
         }
+        
+        if (baseValue.m_type & ~SpecCell)
+            m_insertionSet.insertCheck(indexInBlock, node->origin, node->child1());
+    }
+    
+    void addChecks(
+        NodeOrigin origin, unsigned indexInBlock, const ConstantStructureCheckVector& checks)
+    {
+        for (unsigned i = 0; i < checks.size(); ++i) {
+            addStructureTransitionCheck(
+                origin, indexInBlock, checks[i].constant(), checks[i].structure());
+        }
+    }
 
+    void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure)
+    {
+        if (m_graph.registerStructure(cell->structure()) == StructureRegisteredAndWatched)
+            return;
+        
+        m_graph.registerStructure(structure);
+
+        Node* weakConstant = m_insertionSet.insertNode(
+            indexInBlock, speculationFromValue(cell), JSConstant, origin,
+            OpInfo(m_graph.freeze(cell)));
+        
         m_insertionSet.insertNode(
             indexInBlock, SpecNone, CheckStructure, origin,
-            OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse));
+            OpInfo(m_graph.addStructureSet(structure)), Edge(weakConstant, CellUse));
+    }
+    
+    void fixUpsilons(BasicBlock* block)
+    {
+        for (unsigned nodeIndex = block->size(); nodeIndex--;) {
+            Node* node = block->at(nodeIndex);
+            if (node->op() != Upsilon)
+                continue;
+            switch (node->phi()->op()) {
+            case Phi:
+                break;
+            case JSConstant:
+            case DoubleConstant:
+            case Int52Constant:
+                node->remove();
+                break;
+            default:
+                DFG_CRASH(m_graph, node, "Bad Upsilon phi() pointer");
+                break;
+            }
+        }
     }
     
     InPlaceAbstractState m_state;
diff --git a/dfg/DFGConstantHoistingPhase.cpp b/dfg/DFGConstantHoistingPhase.cpp
new file mode 100644 (file)
index 0000000..68f3651
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGConstantHoistingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+class ConstantHoistingPhase : public Phase {
+public:
+    ConstantHoistingPhase(Graph& graph)
+        : Phase(graph, "constant hoisting")
+    {
+    }
+    
+    bool run()
+    {
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
+        
+        m_graph.clearReplacements();
+        
+        HashMap<FrozenValue*, Node*> jsValues;
+        HashMap<FrozenValue*, Node*> doubleValues;
+        HashMap<FrozenValue*, Node*> int52Values;
+        
+        auto valuesFor = [&] (NodeType op) -> HashMap<FrozenValue*, Node*>& {
+            // Use a roundabout approach because clang thinks that this closure returning a
+            // reference to a stack-allocated value in outer scope is a bug. It's not.
+            HashMap<FrozenValue*, Node*>* result;
+            
+            switch (op) {
+            case JSConstant:
+                result = &jsValues;
+                break;
+            case DoubleConstant:
+                result = &doubleValues;
+                break;
+            case Int52Constant:
+                result = &int52Values;
+                break;
+            default:
+                DFG_CRASH(m_graph, nullptr, "Invalid node type in valuesFor()");
+                result = nullptr;
+                break;
+            }
+            
+            return *result;
+        };
+        
+        Vector<Node*> toFree;
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            unsigned sourceIndex = 0;
+            unsigned targetIndex = 0;
+            while (sourceIndex < block->size()) {
+                Node* node = block->at(sourceIndex++);
+                switch (node->op()) {
+                case JSConstant:
+                case DoubleConstant:
+                case Int52Constant: {
+                    HashMap<FrozenValue*, Node*>& values = valuesFor(node->op());
+                    auto result = values.add(node->constant(), node);
+                    if (result.isNewEntry)
+                        node->origin = NodeOrigin();
+                    else {
+                        node->setReplacement(result.iterator->value);
+                        toFree.append(node);
+                    }
+                    break;
+                }
+                default:
+                    block->at(targetIndex++) = node;
+                    break;
+                }
+            }
+            block->resize(targetIndex);
+        }
+        
+        // Insert the constants into the root block.
+        InsertionSet insertionSet(m_graph);
+        auto insertConstants = [&] (const HashMap<FrozenValue*, Node*>& values) {
+            for (auto& entry : values)
+                insertionSet.insert(0, entry.value);
+        };
+        insertConstants(jsValues);
+        insertConstants(doubleValues);
+        insertConstants(int52Values);
+        insertionSet.execute(m_graph.block(0));
+        
+        // Perform all of the substitutions. We want all instances of the removed constants to
+        // point at their replacements.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block)
+                m_graph.performSubstitution(node);
+        }
+        
+        // And finally free the constants that we removed.
+        for (Node* node : toFree)
+            m_graph.m_allocator.free(node);
+        
+        return true;
+    }
+};
+
+} // anonymous namespace
+    
+bool performConstantHoisting(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Constant Hoisting Phase");
+    return runPhase<ConstantHoistingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGConstantHoistingPhase.h b/dfg/DFGConstantHoistingPhase.h
new file mode 100644 (file)
index 0000000..5124f16
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGConstantHoistingPhase_h
+#define DFGConstantHoistingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Hoists all constants to the top of the root block.
+
+bool performConstantHoisting(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGConstantHoistingPhase_h
index 16567742ae7eddc754cf4560369c72df653dcd2e..18f6f5ebc8b083d272adcd667f83dcd109384988 100644 (file)
@@ -77,7 +77,7 @@ private:
         // don't know its execution frequency.
         BasicBlock* pad = m_insertionSet.insertBefore(*successor, PNaN);
         pad->appendNode(
-            m_graph, SpecNone, Jump, (*successor)->at(0)->origin, OpInfo(*successor));
+            m_graph, SpecNone, Jump, (*successor)->firstOrigin(), OpInfo(*successor));
         pad->predecessors.append(predecessor);
         (*successor)->replacePredecessor(predecessor, pad);
         
index e8cf933cc0be413d6d35025287b8be0c59f388ac..5290f242278b0eeb79203f54a6bea9de62b71197 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,75 +48,34 @@ public:
     {
         ASSERT(m_graph.m_form == ThreadedCPS || m_graph.m_form == SSA);
         
-        // First reset the counts to 0 for all nodes.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = block->size(); indexInBlock--;)
-                block->at(indexInBlock)->setRefCount(0);
-            for (unsigned phiIndex = block->phis.size(); phiIndex--;)
-                block->phis[phiIndex]->setRefCount(0);
-        }
-    
-        // Now find the roots:
-        // - Nodes that are must-generate.
-        // - Nodes that are reachable from type checks.
-        // Set their ref counts to 1 and put them on the worklist.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+        m_graph.computeRefCounts();
+        
+        for (BasicBlock* block : m_graph.blocksInPreOrder())
+            fixupBlock(block);
+        
+        cleanVariables(m_graph.m_arguments);
+
+        // Just do a basic Phantom/Check clean-up.
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
-            for (unsigned indexInBlock = block->size(); indexInBlock--;) {
-                Node* node = block->at(indexInBlock);
-                DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
-                if (!(node->flags() & NodeMustGenerate))
-                    continue;
-                if (!node->postfixRef())
-                    m_worklist.append(node);
-            }
-        }
-        
-        while (!m_worklist.isEmpty()) {
-            while (!m_worklist.isEmpty()) {
-                Node* node = m_worklist.last();
-                m_worklist.removeLast();
-                ASSERT(node->shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
-                DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
-            }
-            
-            if (m_graph.m_form == SSA) {
-                // Find Phi->Upsilon edges, which are represented as meta-data in the
-                // Upsilon.
-                for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-                    BasicBlock* block = m_graph.block(blockIndex);
-                    if (!block)
+            unsigned sourceIndex = 0;
+            unsigned targetIndex = 0;
+            while (sourceIndex < block->size()) {
+                Node* node = block->at(sourceIndex++);
+                switch (node->op()) {
+                case Check:
+                case Phantom:
+                    if (node->children.isEmpty())
                         continue;
-                    for (unsigned nodeIndex = block->size(); nodeIndex--;) {
-                        Node* node = block->at(nodeIndex);
-                        if (node->op() != Upsilon)
-                            continue;
-                        if (node->shouldGenerate())
-                            continue;
-                        if (node->phi()->shouldGenerate())
-                            countNode(node);
-                    }
+                    break;
+                default:
+                    break;
                 }
+                block->at(targetIndex++) = node;
             }
-        }
-        
-        if (m_graph.m_form == SSA) {
-            Vector<BasicBlock*> depthFirst;
-            m_graph.getBlocksInDepthFirstOrder(depthFirst);
-            for (unsigned i = 0; i < depthFirst.size(); ++i)
-                fixupBlock(depthFirst[i]);
-        } else {
-            RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
-            
-            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
-                fixupBlock(m_graph.block(blockIndex));
-            
-            cleanVariables(m_graph.m_arguments);
+            block->resize(targetIndex);
         }
         
         m_graph.m_refCountState = ExactRefCount;
@@ -125,51 +84,16 @@ public:
     }
 
 private:
-    void findTypeCheckRoot(Node*, Edge edge)
-    {
-        // We may have an "unproved" untyped use for code that is unreachable. The CFA
-        // will just not have gotten around to it.
-        if (edge.willNotHaveCheck())
-            return;
-        if (!edge->postfixRef())
-            m_worklist.append(edge.node());
-    }
-    
-    void countNode(Node* node)
-    {
-        if (node->postfixRef())
-            return;
-        m_worklist.append(node);
-    }
-    
-    void countEdge(Node*, Edge edge)
-    {
-        // Don't count edges that are already counted for their type checks.
-        if (edge.willHaveCheck())
-            return;
-        countNode(edge.node());
-    }
-    
     void fixupBlock(BasicBlock* block)
     {
         if (!block)
             return;
-        
-        switch (m_graph.m_form) {
-        case SSA:
-            break;
-            
-        case ThreadedCPS: {
-            // Clean up variable links for the block. We need to do this before the actual DCE
-            // because we need to see GetLocals, so we can bypass them in situations where the
-            // vars-at-tail point to a GetLocal, the GetLocal is dead, but the Phi it points
-            // to is alive.
-            
+
+        if (m_graph.m_form == ThreadedCPS) {
             for (unsigned phiIndex = 0; phiIndex < block->phis.size(); ++phiIndex) {
-                if (!block->phis[phiIndex]->shouldGenerate()) {
-                    // FIXME: We could actually free nodes here. Except that it probably
-                    // doesn't matter, since we don't add any nodes after this phase.
-                    // https://bugs.webkit.org/show_bug.cgi?id=126239
+                Node* phi = block->phis[phiIndex];
+                if (!phi->shouldGenerate()) {
+                    m_graph.m_allocator.free(phi);
                     block->phis[phiIndex--] = block->phis.last();
                     block->phis.removeLast();
                 }
@@ -177,12 +101,6 @@ private:
             
             cleanVariables(block->variablesAtHead);
             cleanVariables(block->variablesAtTail);
-            break;
-        }
-            
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return;
         }
 
         // This has to be a forward loop because we are using the insertion set.
@@ -191,62 +109,29 @@ private:
             if (node->shouldGenerate())
                 continue;
                 
-            switch (node->op()) {
-            case MovHint: {
-                // Check if the child is dead. MovHint's child would only be a Phantom
-                // if we had just killed it.
-                if (node->child1()->op() == Phantom) {
-                    node->setOpAndDefaultFlags(ZombieHint);
-                    node->child1() = Edge();
-                    break;
+            if (node->flags() & NodeHasVarArgs) {
+                for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
+                    Edge edge = m_graph.m_varArgChildren[childIdx];
+                    
+                    if (!edge || edge.willNotHaveCheck())
+                        continue;
+                    
+                    m_insertionSet.insertNode(indexInBlock, SpecNone, Check, node->origin, edge);
                 }
-                break;
-            }
                 
-            case ZombieHint: {
-                // Currently we assume that DCE runs only once.
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
+                node->setOpAndDefaultFlags(Check);
+                node->children.reset();
+                node->setRefCount(1);
+                continue;
             }
             
-            default: {
-                if (node->flags() & NodeHasVarArgs) {
-                    for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
-                        Edge edge = m_graph.m_varArgChildren[childIdx];
-
-                        if (!edge || edge.willNotHaveCheck())
-                            continue;
-
-                        m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->origin, edge);
-                    }
-
-                    node->convertToPhantomUnchecked();
-                    node->children.reset();
-                    node->setRefCount(1);
-                    break;
-                }
-
-                node->convertToPhantom();
-                eliminateIrrelevantPhantomChildren(node);
-                node->setRefCount(1);
-                break;
-            } }
+            node->remove();
+            node->setRefCount(1);
         }
 
         m_insertionSet.execute(block);
     }
     
-    void eliminateIrrelevantPhantomChildren(Node* node)
-    {
-        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
-            Edge edge = node->children.child(i);
-            if (!edge)
-                continue;
-            if (edge.willNotHaveCheck())
-                node->children.removeEdge(i--);
-        }
-    }
-    
     template<typename VariablesVectorType>
     void cleanVariables(VariablesVectorType& variables)
     {
@@ -254,53 +139,12 @@ private:
             Node* node = variables[i];
             if (!node)
                 continue;
-            if (node->op() != Phantom && node->shouldGenerate())
+            if (node->op() != Check && node->shouldGenerate())
                 continue;
-            if (node->op() == GetLocal) {
-                node = node->child1().node();
-                
-                // FIXME: In the case that the variable is captured, we really want to be able
-                // to replace the variable-at-tail with the last use of the variable in the same
-                // way that CPS rethreading would do. The child of the GetLocal isn't necessarily
-                // the same as what CPS rethreading would do. For example, we may have:
-                //
-                // a: SetLocal(...) // live
-                // b: GetLocal(@a) // live
-                // c: GetLocal(@a) // dead
-                //
-                // When killing @c, the code below will set the variable-at-tail to @a, while CPS
-                // rethreading would have set @b. This is a benign bug, since all clients of CPS
-                // only use the variable-at-tail of captured variables to get the
-                // VariableAccessData and observe that it is in fact captured. But, this feels
-                // like it could cause bugs in the future.
-                //
-                // It's tempting to just dethread and then invoke CPS rethreading, but CPS
-                // rethreading fails to preserve exact ref-counts. So we would need a fixpoint.
-                // It's probably the case that this fixpoint will be guaranteed to converge after
-                // the second iteration (i.e. the second run of DCE will not kill anything and so
-                // will not need to dethread), but for now the safest approach is probably just to
-                // allow for this tiny bit of sloppiness.
-                //
-                // Another possible solution would be to simply say that DCE dethreads but then
-                // we never rethread before going to the backend. That feels intuitively right
-                // because it's unlikely that any of the phases after DCE in the backend rely on
-                // ThreadedCPS.
-                //
-                // https://bugs.webkit.org/show_bug.cgi?id=130115
-                ASSERT(
-                    node->op() == Phi || node->op() == SetArgument
-                    || node->variableAccessData()->isCaptured());
-                
-                if (node->shouldGenerate()) {
-                    variables[i] = node;
-                    continue;
-                }
-            }
-            variables[i] = 0;
+            variables[i] = nullptr;
         }
     }
     
-    Vector<Node*, 128> m_worklist;
     InsertionSet m_insertionSet;
 };
 
index dfa8faac21aa8f7fc4cd7fe2e77b1f3f0e2cacb1..74e246851366f098dcc87f2bc01d8b78b47a0e81 100644 (file)
@@ -52,14 +52,14 @@ unsigned DesiredIdentifiers::numberOfIdentifiers()
     return m_codeBlock->numberOfIdentifiers() + m_addedIdentifiers.size();
 }
 
-void DesiredIdentifiers::addLazily(StringImpl* rep)
+void DesiredIdentifiers::addLazily(UniquedStringImpl* rep)
 {
     m_addedIdentifiers.append(rep);
 }
 
-StringImpl* DesiredIdentifiers::at(unsigned index) const
+UniquedStringImpl* DesiredIdentifiers::at(unsigned index) const
 {
-    StringImpl* result;
+    UniquedStringImpl* result;
     if (index < m_codeBlock->numberOfIdentifiers())
         result = m_codeBlock->identifier(index).impl();
     else
@@ -71,9 +71,9 @@ StringImpl* DesiredIdentifiers::at(unsigned index) const
 void DesiredIdentifiers::reallyAdd(VM& vm, CommonData* commonData)
 {
     for (unsigned i = 0; i < m_addedIdentifiers.size(); ++i) {
-        StringImpl* rep = m_addedIdentifiers[i];
+        auto rep = m_addedIdentifiers[i];
         ASSERT(rep->hasAtLeastOneRef());
-        commonData->dfgIdentifiers.append(Identifier(&vm, rep));
+        commonData->dfgIdentifiers.append(Identifier::fromUid(&vm, rep));
     }
 }
 
index 10c21590a125104be99a2de6c9cf6964c829c94d..3a2a34857f3b0f72ee1c9af3164f2e49443ca625 100644 (file)
@@ -45,17 +45,17 @@ public:
     ~DesiredIdentifiers();
     
     unsigned numberOfIdentifiers();
-    void addLazily(StringImpl*);
+    void addLazily(UniquedStringImpl*);
     
-    StringImpl* at(unsigned index) const;
+    UniquedStringImpl* at(unsigned index) const;
     
-    StringImpl* operator[](unsigned index) const { return at(index); }
+    UniquedStringImpl* operator[](unsigned index) const { return at(index); }
     
     void reallyAdd(VM&, CommonData*);
     
 private:
     CodeBlock* m_codeBlock;
-    Vector<StringImpl*> m_addedIdentifiers;
+    Vector<UniquedStringImpl*> m_addedIdentifiers;
 };
 
 } } // namespace JSC::DFG
diff --git a/dfg/DFGDesiredStructureChains.cpp b/dfg/DFGDesiredStructureChains.cpp
deleted file mode 100644 (file)
index 259a5db..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DFGDesiredStructureChains.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-DesiredStructureChains::DesiredStructureChains() { }
-DesiredStructureChains::~DesiredStructureChains() { }
-
-bool DesiredStructureChains::areStillValid() const
-{
-    for (unsigned i = 0; i < m_vector.size(); ++i) {
-        if (!m_vector[i]->isStillValid())
-            return false;
-    }
-    return true;
-}
-
-void DesiredStructureChains::visitChildren(SlotVisitor& visitor)
-{
-    for (unsigned i = m_vector.size(); i--;)
-        m_vector[i]->visitChildren(visitor);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/dfg/DFGDesiredStructureChains.h b/dfg/DFGDesiredStructureChains.h
deleted file mode 100644 (file)
index 9343710..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DFGDesiredStructureChains_h
-#define DFGDesiredStructureChains_h
-
-#if ENABLE(DFG_JIT)
-
-#include "IntendedStructureChain.h"
-#include <wtf/Vector.h>
-
-namespace JSC { namespace DFG {
-
-class DesiredStructureChains {
-public:
-    DesiredStructureChains();
-    ~DesiredStructureChains();
-    
-    void addLazily(PassRefPtr<IntendedStructureChain> chain)
-    {
-        m_vector.append(chain);
-    }
-    
-    bool areStillValid() const;
-    
-    void visitChildren(SlotVisitor&);
-    
-private:
-    Vector<RefPtr<IntendedStructureChain>> m_vector;
-};
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGDesiredStructureChains_h
-
index a7704f44f3a1ea404b9fb472b86901a91cee4617..7f5b01caf8df0ca01860b5bf89957301e5620917 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,6 +44,13 @@ void ArrayBufferViewWatchpointAdaptor::add(
     codeBlock->vm()->heap.addReference(neuteringWatchpoint, view->buffer());
 }
 
+void InferredValueAdaptor::add(
+    CodeBlock* codeBlock, InferredValue* inferredValue, Watchpoint* watchpoint)
+{
+    codeBlock->addConstant(inferredValue); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
+    inferredValue->add(watchpoint);
+}
+
 DesiredWatchpoints::DesiredWatchpoints() { }
 DesiredWatchpoints::~DesiredWatchpoints() { }
 
@@ -57,25 +64,29 @@ void DesiredWatchpoints::addLazily(InlineWatchpointSet& set)
     m_inlineSets.addLazily(&set);
 }
 
-void DesiredWatchpoints::addLazily(JSArrayBufferView* view)
+void DesiredWatchpoints::addLazily(InferredValue* inferredValue)
 {
-    m_bufferViews.addLazily(view);
+    m_inferredValues.addLazily(inferredValue);
 }
 
-void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSet* set)
+void DesiredWatchpoints::addLazily(JSArrayBufferView* view)
 {
-    m_sets.addLazily(codeOrigin, exitKind, set);
+    m_bufferViews.addLazily(view);
 }
 
-void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, InlineWatchpointSet& set)
+bool DesiredWatchpoints::consider(Structure* structure)
 {
-    m_inlineSets.addLazily(codeOrigin, exitKind, &set);
+    if (!structure->dfgShouldWatch())
+        return false;
+    addLazily(structure->transitionWatchpointSet());
+    return true;
 }
 
 void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, CommonData& commonData)
 {
     m_sets.reallyAdd(codeBlock, commonData);
     m_inlineSets.reallyAdd(codeBlock, commonData);
+    m_inferredValues.reallyAdd(codeBlock, commonData);
     m_bufferViews.reallyAdd(codeBlock, commonData);
 }
 
@@ -83,6 +94,7 @@ bool DesiredWatchpoints::areStillValid() const
 {
     return m_sets.areStillValid()
         && m_inlineSets.areStillValid()
+        && m_inferredValues.areStillValid()
         && m_bufferViews.areStillValid();
 }
 
index 3e07f9b1e9985ce8591c5f002213156542bfbf3d..ce89a04552ac6ec476dc9e13c6a37347c9bc6835 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
 
 #include "CodeOrigin.h"
 #include "DFGCommonData.h"
+#include "InferredValue.h"
 #include "JSArrayBufferView.h"
 #include "Watchpoint.h"
 #include <wtf/HashMap.h>
 
 namespace JSC { namespace DFG {
 
-template<typename WatchpointSetType>
-struct WatchpointForGenericWatchpointSet {
-    WatchpointForGenericWatchpointSet()
-        : m_exitKind(ExitKindUnset)
-        , m_set(0)
-    {
-    }
-    
-    WatchpointForGenericWatchpointSet(
-        CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set)
-        : m_codeOrigin(codeOrigin)
-        , m_exitKind(exitKind)
-        , m_set(set)
-    {
-    }
-    
-    CodeOrigin m_codeOrigin;
-    ExitKind m_exitKind;
-    WatchpointSetType* m_set;
-};
+class Graph;
 
 template<typename T>
 struct GenericSetAdaptor {
@@ -69,6 +51,14 @@ struct GenericSetAdaptor {
     static bool hasBeenInvalidated(T* set) { return set->hasBeenInvalidated(); }
 };
 
+struct InferredValueAdaptor {
+    static void add(CodeBlock*, InferredValue*, Watchpoint*);
+    static bool hasBeenInvalidated(InferredValue* inferredValue)
+    {
+        return inferredValue->hasBeenInvalidated();
+    }
+};
+
 struct ArrayBufferViewWatchpointAdaptor {
     static void add(CodeBlock*, JSArrayBufferView*, Watchpoint*);
     static bool hasBeenInvalidated(JSArrayBufferView* view)
@@ -95,12 +85,6 @@ public:
         m_sets.add(set);
     }
     
-    void addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set)
-    {
-        m_profiledWatchpoints.append(
-            WatchpointForGenericWatchpointSet<WatchpointSetType>(codeOrigin, exitKind, set));
-    }
-    
     void reallyAdd(CodeBlock* codeBlock, CommonData& common)
     {
         RELEASE_ASSERT(!m_reallyAdded);
@@ -112,14 +96,6 @@ public:
             Adaptor::add(codeBlock, *iter, &common.watchpoints.last());
         }
         
-        for (unsigned i = m_profiledWatchpoints.size(); i--;) {
-            WatchpointForGenericWatchpointSet<WatchpointSetType> watchpoint =
-                m_profiledWatchpoints[i];
-            common.profiledWatchpoints.append(
-                ProfiledCodeBlockJettisoningWatchpoint(watchpoint.m_codeOrigin, watchpoint.m_exitKind, codeBlock));
-            Adaptor::add(codeBlock, watchpoint.m_set, &common.profiledWatchpoints.last());
-        }
-        
         m_reallyAdded = true;
     }
     
@@ -132,53 +108,16 @@ public:
                 return false;
         }
         
-        for (unsigned i = m_profiledWatchpoints.size(); i--;) {
-            if (Adaptor::hasBeenInvalidated(m_profiledWatchpoints[i].m_set))
-                return false;
-        }
-        
         return true;
     }
     
-#if ASSERT_DISABLED
-    bool isStillValid(WatchpointSetType* set)
-    {
-        return !Adaptor::hasBeenInvalidated(set);
-    }
-    
-    bool shouldAssumeMixedState(WatchpointSetType*)
+    bool isWatched(WatchpointSetType* set) const
     {
-        return true;
-    }
-#else
-    bool isStillValid(WatchpointSetType* set)
-    {
-        bool result = !Adaptor::hasBeenInvalidated(set);
-        m_firstKnownState.add(set, result);
-        return result;
-    }
-    
-    bool shouldAssumeMixedState(WatchpointSetType* set)
-    {
-        typename StateMap::iterator iter = m_firstKnownState.find(set);
-        if (iter == m_firstKnownState.end())
-            return false;
-        
-        return iter->value != !Adaptor::hasBeenInvalidated(set);
-    }
-#endif
-    
-    bool isValidOrMixed(WatchpointSetType* set)
-    {
-        return isStillValid(set) || shouldAssumeMixedState(set);
+        return m_sets.contains(set);
     }
 
 private:
-    Vector<WatchpointForGenericWatchpointSet<WatchpointSetType>> m_profiledWatchpoints;
     HashSet<WatchpointSetType*> m_sets;
-#if !ASSERT_DISABLED
-    StateMap m_firstKnownState;
-#endif
     bool m_reallyAdded;
 };
 
@@ -189,54 +128,36 @@ public:
     
     void addLazily(WatchpointSet*);
     void addLazily(InlineWatchpointSet&);
+    void addLazily(InferredValue*);
     void addLazily(JSArrayBufferView*);
-    void addLazily(CodeOrigin, ExitKind, WatchpointSet*);
-    void addLazily(CodeOrigin, ExitKind, InlineWatchpointSet&);
+    
+    bool consider(Structure*);
     
     void reallyAdd(CodeBlock*, CommonData&);
     
     bool areStillValid() const;
     
-    bool isStillValid(WatchpointSet* set)
-    {
-        return m_sets.isStillValid(set);
-    }
-    bool isStillValid(InlineWatchpointSet& set)
-    {
-        return m_inlineSets.isStillValid(&set);
-    }
-    bool isStillValid(JSArrayBufferView* view)
-    {
-        return m_bufferViews.isStillValid(view);
-    }
-    bool shouldAssumeMixedState(WatchpointSet* set)
-    {
-        return m_sets.shouldAssumeMixedState(set);
-    }
-    bool shouldAssumeMixedState(InlineWatchpointSet& set)
-    {
-        return m_inlineSets.shouldAssumeMixedState(&set);
-    }
-    bool shouldAssumeMixedState(JSArrayBufferView* view)
+    bool isWatched(WatchpointSet* set)
     {
-        return m_bufferViews.shouldAssumeMixedState(view);
+        return m_sets.isWatched(set);
     }
-    bool isValidOrMixed(WatchpointSet* set)
+    bool isWatched(InlineWatchpointSet& set)
     {
-        return m_sets.isValidOrMixed(set);
+        return m_inlineSets.isWatched(&set);
     }
-    bool isValidOrMixed(InlineWatchpointSet& set)
+    bool isWatched(InferredValue* inferredValue)
     {
-        return m_inlineSets.isValidOrMixed(&set);
+        return m_inferredValues.isWatched(inferredValue);
     }
-    bool isValidOrMixed(JSArrayBufferView* view)
+    bool isWatched(JSArrayBufferView* view)
     {
-        return m_bufferViews.isValidOrMixed(view);
+        return m_bufferViews.isWatched(view);
     }
     
 private:
     GenericDesiredWatchpoints<WatchpointSet> m_sets;
     GenericDesiredWatchpoints<InlineWatchpointSet> m_inlineSets;
+    GenericDesiredWatchpoints<InferredValue, InferredValueAdaptor> m_inferredValues;
     GenericDesiredWatchpoints<JSArrayBufferView, ArrayBufferViewWatchpointAdaptor> m_bufferViews;
 };
 
index 1ee02ba0e7af316fd6356f5262575287fb42a5ee..f14968c5a109f5f446db06f62b0deb4f694b1c4d 100644 (file)
@@ -50,21 +50,31 @@ DesiredWeakReferences::~DesiredWeakReferences()
 
 void DesiredWeakReferences::addLazily(JSCell* cell)
 {
-    m_references.append(cell);
+    m_references.add(cell);
+}
+
+bool DesiredWeakReferences::contains(JSCell* cell)
+{
+    return m_references.contains(cell);
 }
 
 void DesiredWeakReferences::reallyAdd(VM& vm, CommonData* common)
 {
-    for (unsigned i = 0; i < m_references.size(); i++) {
-        JSCell* target = m_references[i];
-        common->weakReferences.append(WriteBarrier<JSCell>(vm, m_codeBlock->ownerExecutable(), target));
+    for (JSCell* target : m_references) {
+        if (Structure* structure = jsDynamicCast<Structure*>(target)) {
+            common->weakStructureReferences.append(
+                WriteBarrier<Structure>(vm, m_codeBlock->ownerExecutable(), structure));
+        } else {
+            common->weakReferences.append(
+                WriteBarrier<JSCell>(vm, m_codeBlock->ownerExecutable(), target));
+        }
     }
 }
 
 void DesiredWeakReferences::visitChildren(SlotVisitor& visitor)
 {
-    for (unsigned i = m_references.size(); i--;)
-        visitor.appendUnbarrieredPointer(&m_references[i]);
+    for (JSCell* target : m_references)
+        visitor.appendUnbarrieredPointer(&target);
 }
 
 } } // namespace JSC::DFG
index 48ad44ca6e80191ed9819952d8ce730a8ccb30af..e312255c86cda359b7c57cbe9ec2d4ce23d58131 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef DFGDesiredWeakReferences_h
 #define DFGDesiredWeakReferences_h
 
-#include <wtf/Vector.h>
+#include <wtf/HashSet.h>
 
 #if ENABLE(DFG_JIT)
 
@@ -48,13 +48,15 @@ public:
     ~DesiredWeakReferences();
 
     void addLazily(JSCell*);
+    bool contains(JSCell*);
+    
     void reallyAdd(VM&, CommonData*);
     
     void visitChildren(SlotVisitor&);
 
 private:
     CodeBlock* m_codeBlock;
-    Vector<JSCell*> m_references;
+    HashSet<JSCell*> m_references;
 };
 
 } } // namespace JSC::DFG
index 317610035bee72629382bc520e6a1a676e4d80bf..e221c4c4fe682a961c1006f06eb7d86efb31f4d8 100644 (file)
@@ -112,8 +112,6 @@ Vector<Disassembler::DumpedOp> Disassembler::createDumpList(LinkBuffer& linkBuff
         append(result, out, previousOrigin);
         Node* lastNodeForDisassembly = block->at(0);
         for (size_t i = 0; i < block->size(); ++i) {
-            if (!block->at(i)->willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
-                continue;
             MacroAssembler::Label currentLabel;
             HashMap<Node*, MacroAssembler::Label>::iterator iter = m_labelForNode.find(block->at(i));
             if (iter != m_labelForNode.end())
index 7844fc23755ea5dfaca23a7a63510198043b0211..7b31946f9a4960b22d2837e8b6e1185379435b5d 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "CodeOrigin.h"
 #include "DFGCommon.h"
 #include "DumpContext.h"
 #include "MacroAssembler.h"
diff --git a/dfg/DFGDoesGC.cpp b/dfg/DFGDoesGC.cpp
new file mode 100644 (file)
index 0000000..5946840
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGDoesGC.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGClobberize.h"
+#include "DFGGraph.h"
+#include "DFGNode.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+bool doesGC(Graph& graph, Node* node)
+{
+    if (clobbersHeap(graph, node))
+        return true;
+    
+    // Now consider nodes that don't clobber the world but that still may GC. This includes all
+    // nodes. By convention we put world-clobbering nodes in the block of "false" cases but we can
+    // put them anywhere.
+    switch (node->op()) {
+    case JSConstant:
+    case DoubleConstant:
+    case Int52Constant:
+    case Identity:
+    case GetCallee:
+    case GetArgumentCount:
+    case GetLocal:
+    case SetLocal:
+    case MovHint:
+    case ZombieHint:
+    case Phantom:
+    case Upsilon:
+    case Phi:
+    case Flush:
+    case PhantomLocal:
+    case GetLocalUnlinked:
+    case SetArgument:
+    case BitAnd:
+    case BitOr:
+    case BitXor:
+    case BitLShift:
+    case BitRShift:
+    case BitURShift:
+    case ValueToInt32:
+    case UInt32ToNumber:
+    case DoubleAsInt32:
+    case ArithAdd:
+    case ArithClz32:
+    case ArithSub:
+    case ArithNegate:
+    case ArithMul:
+    case ArithIMul:
+    case ArithDiv:
+    case ArithMod:
+    case ArithAbs:
+    case ArithMin:
+    case ArithMax:
+    case ArithPow:
+    case ArithSqrt:
+    case ArithRound:
+    case ArithFRound:
+    case ArithSin:
+    case ArithCos:
+    case ArithLog:
+    case ValueAdd:
+    case GetById:
+    case GetByIdFlush:
+    case PutById:
+    case PutByIdFlush:
+    case PutByIdDirect:
+    case CheckStructure:
+    case GetExecutable:
+    case GetButterfly:
+    case CheckArray:
+    case GetScope:
+    case SkipScope:
+    case GetClosureVar:
+    case PutClosureVar:
+    case GetGlobalVar:
+    case PutGlobalVar:
+    case VarInjectionWatchpoint:
+    case CheckCell:
+    case CheckNotEmpty:
+    case RegExpExec:
+    case RegExpTest:
+    case CompareLess:
+    case CompareLessEq:
+    case CompareGreater:
+    case CompareGreaterEq:
+    case CompareEq:
+    case CompareEqConstant:
+    case CompareStrictEq:
+    case Call:
+    case Construct:
+    case CallVarargs:
+    case ConstructVarargs:
+    case LoadVarargs:
+    case CallForwardVarargs:
+    case ConstructForwardVarargs:
+    case NativeCall:
+    case NativeConstruct:
+    case Breakpoint:
+    case ProfileWillCall:
+    case ProfileDidCall:
+    case ProfileType:
+    case ProfileControlFlow:
+    case CheckHasInstance:
+    case InstanceOf:
+    case IsUndefined:
+    case IsBoolean:
+    case IsNumber:
+    case IsString:
+    case IsObject:
+    case IsObjectOrNull:
+    case IsFunction:
+    case TypeOf:
+    case LogicalNot:
+    case ToPrimitive:
+    case ToString:
+    case CallStringConstructor:
+    case In:
+    case Jump:
+    case Branch:
+    case Switch:
+    case Return:
+    case Throw:
+    case CountExecution:
+    case ForceOSRExit:
+    case CheckWatchdogTimer:
+    case StringFromCharCode:
+    case Unreachable:
+    case ExtractOSREntryLocal:
+    case CheckTierUpInLoop:
+    case CheckTierUpAtReturn:
+    case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter:
+    case LoopHint:
+    case StoreBarrier:
+    case InvalidationPoint:
+    case NotifyWrite:
+    case CheckInBounds:
+    case ConstantStoragePointer:
+    case Check:
+    case MultiGetByOffset:
+    case ValueRep:
+    case DoubleRep:
+    case Int52Rep:
+    case GetGetter:
+    case GetSetter:
+    case GetByVal:
+    case GetIndexedPropertyStorage:
+    case GetArrayLength:
+    case ArrayPush:
+    case ArrayPop:
+    case StringCharAt:
+    case StringCharCodeAt:
+    case GetTypedArrayByteOffset:
+    case PutByValDirect:
+    case PutByVal:
+    case PutByValAlias:
+    case PutStructure:
+    case GetByOffset:
+    case GetGetterSetterByOffset:
+    case PutByOffset:
+    case GetEnumerableLength:
+    case HasGenericProperty:
+    case HasStructureProperty:
+    case HasIndexedProperty:
+    case GetDirectPname:
+    case FiatInt52:
+    case BooleanToNumber:
+    case CheckBadCell:
+    case BottomValue:
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
+    case PutHint:
+    case CheckStructureImmediate:
+    case PutStack:
+    case KillStack:
+    case GetStack:
+    case GetFromArguments:
+    case PutToArguments:
+        return false;
+
+    case CreateActivation:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+    case ToThis:
+    case CreateThis:
+    case AllocatePropertyStorage:
+    case ReallocatePropertyStorage:
+    case Arrayify:
+    case ArrayifyToStructure:
+    case NewObject:
+    case NewArray:
+    case NewArrayWithSize:
+    case NewArrayBuffer:
+    case NewRegexp:
+    case NewStringObject:
+    case MakeRope:
+    case NewFunction:
+    case NewTypedArray:
+    case ThrowReferenceError:
+    case GetPropertyEnumerator:
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname:
+    case ToIndexString:
+    case MaterializeNewObject:
+    case MaterializeCreateActivation:
+        return true;
+        
+    case MultiPutByOffset:
+        return node->multiPutByOffsetData().reallocatesStorage();
+
+    case LastNodeType:
+        RELEASE_ASSERT_NOT_REACHED();
+        return true;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return true;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGDoesGC.h b/dfg/DFGDoesGC.h
new file mode 100644 (file)
index 0000000..4503d21
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGDoesGC_h
+#define DFGDoesGC_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+struct Node;
+
+bool doesGC(Graph&, Node*);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGDoesGC_h
+
index bdd6a6a5baeb8cf1eec7573ce33148bfaa476fcd..4c67e8b9e70a901337cb3bd67589f1c2310519da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGBlockMapInlines.h"
+#include "DFGBlockWorklist.h"
 #include "DFGGraph.h"
+#include "DFGNaiveDominators.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace DFG {
@@ -41,91 +44,429 @@ Dominators::~Dominators()
 {
 }
 
-void Dominators::compute(Graph& graph)
-{
-    // This implements a naive dominator solver.
+namespace {
+
+// This implements Lengauer and Tarjan's "A Fast Algorithm for Finding Dominators in a Flowgraph"
+// (TOPLAS 1979). It uses the "simple" implementation of LINK and EVAL, which yields an O(n log n)
+// solution. The full paper is linked below; this code attempts to closely follow the algorithm as
+// it is presented in the paper; in particular sections 3 and 4 as well as appendix B.
+// https://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/a%20fast%20algorithm%20for%20finding.pdf
+//
+// This code is very subtle. The Lengauer-Tarjan algorithm is incredibly deep to begin with. The
+// goal of this code is to follow the code in the paper, however our implementation must deviate
+// from the paper when it comes to recursion. The authors had used recursion to implement DFS, and
+// also to implement the "simple" EVAL. We convert both of those into worklist-based solutions.
+// Finally, once the algorithm gives us immediate dominators, we implement dominance tests by
+// walking the dominator tree and computing pre and post numbers. We then use the range inclusion
+// check trick that was first discovered by Paul F. Dietz in 1982 in "Maintaining order in a linked
+// list" (see http://dl.acm.org/citation.cfm?id=802184).
+
+class LengauerTarjan {
+public:
+    LengauerTarjan(Graph& graph)
+        : m_graph(graph)
+        , m_data(graph)
+    {
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            m_data[block].label = block;
+        }
+    }
     
-    ASSERT(graph.block(0)->predecessors.isEmpty());
+    void compute()
+    {
+        computeDepthFirstPreNumbering(); // Step 1.
+        computeSemiDominatorsAndImplicitImmediateDominators(); // Steps 2 and 3.
+        computeExplicitImmediateDominators(); // Step 4.
+    }
     
-    unsigned numBlocks = graph.numBlocks();
+    BasicBlock* immediateDominator(BasicBlock* block)
+    {
+        return m_data[block].dom;
+    }
+
+private:
+    void computeDepthFirstPreNumbering()
+    {
+        // Use a block worklist that also tracks the index inside the successor list. This is
+        // necessary for ensuring that we don't attempt to visit a successor until the previous
+        // successors that we had visited are fully processed. This ends up being revealed in the
+        // output of this method because the first time we see an edge to a block, we set the
+        // block's parent. So, if we have:
+        //
+        // A -> B
+        // A -> C
+        // B -> C
+        //
+        // And we're processing A, then we want to ensure that if we see A->B first (and hence set
+        // B's prenumber before we set C's) then we also end up setting C's parent to B by virtue
+        // of not noticing A->C until we're done processing B.
+        
+        ExtendedBlockWorklist<unsigned> worklist;
+        worklist.push(m_graph.block(0), 0);
+        
+        while (BlockWith<unsigned> item = worklist.pop()) {
+            BasicBlock* block = item.block;
+            unsigned successorIndex = item.data;
+            
+            // We initially push with successorIndex = 0 regardless of whether or not we have any
+            // successors. This is so that we can assign our prenumber. Subsequently we get pushed
+            // with higher successorIndex values, but only if they are in range.
+            ASSERT(!successorIndex || successorIndex < block->numSuccessors());
+
+            if (!successorIndex) {
+                m_data[block].semiNumber = m_blockByPreNumber.size();
+                m_blockByPreNumber.append(block);
+            }
+            
+            if (successorIndex < block->numSuccessors()) {
+                unsigned nextSuccessorIndex = successorIndex + 1;
+                if (nextSuccessorIndex < block->numSuccessors())
+                    worklist.forcePush(block, nextSuccessorIndex);
+
+                BasicBlock* successorBlock = block->successor(successorIndex);
+                if (worklist.push(successorBlock, 0))
+                    m_data[successorBlock].parent = block;
+            }
+        }
+    }
     
-    // Allocate storage for the dense dominance matrix. 
-    if (numBlocks > m_results.size()) {
-        m_results.grow(numBlocks);
-        for (unsigned i = numBlocks; i--;)
-            m_results[i].resize(numBlocks);
-        m_scratch.resize(numBlocks);
+    void computeSemiDominatorsAndImplicitImmediateDominators()
+    {
+        for (unsigned currentPreNumber = m_blockByPreNumber.size(); currentPreNumber-- > 1;) {
+            BasicBlock* block = m_blockByPreNumber[currentPreNumber];
+            BlockData& blockData = m_data[block];
+            
+            // Step 2:
+            for (BasicBlock* predecessorBlock : block->predecessors) {
+                BasicBlock* intermediateBlock = eval(predecessorBlock);
+                blockData.semiNumber = std::min(
+                    m_data[intermediateBlock].semiNumber, blockData.semiNumber);
+            }
+            unsigned bucketPreNumber = blockData.semiNumber;
+            ASSERT(bucketPreNumber <= currentPreNumber);
+            m_data[m_blockByPreNumber[bucketPreNumber]].bucket.append(block);
+            link(blockData.parent, block);
+            
+            // Step 3:
+            for (BasicBlock* semiDominee : m_data[blockData.parent].bucket) {
+                BasicBlock* possibleDominator = eval(semiDominee);
+                BlockData& semiDomineeData = m_data[semiDominee];
+                ASSERT(m_blockByPreNumber[semiDomineeData.semiNumber] == blockData.parent);
+                BlockData& possibleDominatorData = m_data[possibleDominator];
+                if (possibleDominatorData.semiNumber < semiDomineeData.semiNumber)
+                    semiDomineeData.dom = possibleDominator;
+                else
+                    semiDomineeData.dom = blockData.parent;
+            }
+            m_data[blockData.parent].bucket.clear();
+        }
+    }
+    
+    void computeExplicitImmediateDominators()
+    {
+        for (unsigned currentPreNumber = 1; currentPreNumber < m_blockByPreNumber.size(); ++currentPreNumber) {
+            BasicBlock* block = m_blockByPreNumber[currentPreNumber];
+            BlockData& blockData = m_data[block];
+            
+            if (blockData.dom != m_blockByPreNumber[blockData.semiNumber])
+                blockData.dom = m_data[blockData.dom].dom;
+        }
+    }
+    
+    void link(BasicBlock* from, BasicBlock* to)
+    {
+        m_data[to].ancestor = from;
+    }
+    
+    BasicBlock* eval(BasicBlock* block)
+    {
+        if (!m_data[block].ancestor)
+            return block;
+        
+        compress(block);
+        return m_data[block].label;
+    }
+    
+    void compress(BasicBlock* initialBlock)
+    {
+        // This was meant to be a recursive function, but we don't like recursion because we don't
+        // want to blow the stack. The original function will call compress() recursively on the
+        // ancestor of anything that has an ancestor. So, we populate our worklist with the
+        // recursive ancestors of initialBlock. Then we process the list starting from the block
+        // that is furthest up the ancestor chain.
+        
+        BasicBlock* ancestor = m_data[initialBlock].ancestor;
+        ASSERT(ancestor);
+        if (!m_data[ancestor].ancestor)
+            return;
+        
+        Vector<BasicBlock*, 16> stack;
+        for (BasicBlock* block = initialBlock; block; block = m_data[block].ancestor)
+            stack.append(block);
+        
+        // We only care about blocks that have an ancestor that has an ancestor. The last two
+        // elements in the stack won't satisfy this property.
+        ASSERT(stack.size() >= 2);
+        ASSERT(!m_data[stack[stack.size() - 1]].ancestor);
+        ASSERT(!m_data[m_data[stack[stack.size() - 2]].ancestor].ancestor);
+        
+        for (unsigned i = stack.size() - 2; i--;) {
+            BasicBlock* block = stack[i];
+            BasicBlock*& labelOfBlock = m_data[block].label;
+            BasicBlock*& ancestorOfBlock = m_data[block].ancestor;
+            ASSERT(ancestorOfBlock);
+            ASSERT(m_data[ancestorOfBlock].ancestor);
+            
+            BasicBlock* labelOfAncestorOfBlock = m_data[ancestorOfBlock].label;
+            
+            if (m_data[labelOfAncestorOfBlock].semiNumber < m_data[labelOfBlock].semiNumber)
+                labelOfBlock = labelOfAncestorOfBlock;
+            ancestorOfBlock = m_data[ancestorOfBlock].ancestor;
+        }
     }
 
-    // We know that the entry block is only dominated by itself.
-    m_results[0].clearAll();
-    m_results[0].set(0);
+    struct BlockData {
+        BlockData()
+            : parent(nullptr)
+            , preNumber(UINT_MAX)
+            , semiNumber(UINT_MAX)
+            , ancestor(nullptr)
+            , label(nullptr)
+            , dom(nullptr)
+        {
+        }
+        
+        BasicBlock* parent;
+        unsigned preNumber;
+        unsigned semiNumber;
+        BasicBlock* ancestor;
+        BasicBlock* label;
+        Vector<BasicBlock*> bucket;
+        BasicBlock* dom;
+    };
+    
+    Graph& m_graph;
+    BlockMap<BlockData> m_data;
+    Vector<BasicBlock*> m_blockByPreNumber;
+};
 
-    // Find all of the valid blocks.
-    m_scratch.clearAll();
-    for (unsigned i = numBlocks; i--;) {
-        if (!graph.block(i))
-            continue;
-        m_scratch.set(i);
+struct ValidationContext {
+    ValidationContext(Graph& graph, Dominators& dominators)
+        : graph(graph)
+        , dominators(dominators)
+    {
     }
     
-    // Mark all nodes as dominated by everything.
-    for (unsigned i = numBlocks; i-- > 1;) {
-        if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
-            m_results[i].clearAll();
-        else
-            m_results[i].set(m_scratch);
+    void reportError(BasicBlock* from, BasicBlock* to, const char* message)
+    {
+        Error error;
+        error.from = from;
+        error.to = to;
+        error.message = message;
+        errors.append(error);
     }
+    
+    void handleErrors()
+    {
+        if (errors.isEmpty())
+            return;
+        
+        startCrashing();
+        dataLog("DFG DOMINATOR VALIDATION FAILED:\n");
+        dataLog("\n");
+        dataLog("For block domination relationships:\n");
+        for (unsigned i = 0; i < errors.size(); ++i) {
+            dataLog(
+                "    ", pointerDump(errors[i].from), " -> ", pointerDump(errors[i].to),
+                " (", errors[i].message, ")\n");
+        }
+        dataLog("\n");
+        dataLog("Control flow graph:\n");
+        for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = graph.block(blockIndex);
+            if (!block)
+                continue;
+            dataLog("    Block #", blockIndex, ": successors = [");
+            CommaPrinter comma;
+            for (unsigned i = 0; i < block->numSuccessors(); ++i)
+                dataLog(comma, *block->successor(i));
+            dataLog("], predecessors = [");
+            comma = CommaPrinter();
+            for (unsigned i = 0; i < block->predecessors.size(); ++i)
+                dataLog(comma, *block->predecessors[i]);
+            dataLog("]\n");
+        }
+        dataLog("\n");
+        dataLog("Lengauer-Tarjan Dominators:\n");
+        dataLog(dominators);
+        dataLog("\n");
+        dataLog("Naive Dominators:\n");
+        naiveDominators.dump(graph, WTF::dataFile());
+        dataLog("\n");
+        dataLog("Graph at time of failure:\n");
+        graph.dump();
+        dataLog("\n");
+        dataLog("DFG DOMINATOR VALIDATION FAILIED!\n");
+        CRASH();
+    }
+    
+    Graph& graph;
+    Dominators& dominators;
+    NaiveDominators naiveDominators;
+    
+    struct Error {
+        BasicBlock* from;
+        BasicBlock* to;
+        const char* message;
+    };
+    
+    Vector<Error> errors;
+};
+
+} // anonymous namespace
 
-    // Iteratively eliminate nodes that are not dominator.
-    bool changed;
-    do {
-        changed = false;
-        // Prune dominators in all non entry blocks: forward scan.
-        for (unsigned i = 1; i < numBlocks; ++i)
-            changed |= pruneDominators(graph, i);
+void Dominators::compute(Graph& graph)
+{
+    LengauerTarjan lengauerTarjan(graph);
+    lengauerTarjan.compute();
 
-        if (!changed)
+    m_data = BlockMap<BlockData>(graph);
+    
+    // From here we want to build a spanning tree with both upward and downward links and we want
+    // to do a search over this tree to compute pre and post numbers that can be used for dominance
+    // tests.
+    
+    for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
+        BasicBlock* block = graph.block(blockIndex);
+        if (!block)
+            continue;
+        
+        BasicBlock* idomBlock = lengauerTarjan.immediateDominator(block);
+        m_data[block].idomParent = idomBlock;
+        if (idomBlock)
+            m_data[idomBlock].idomKids.append(block);
+    }
+    
+    unsigned nextPreNumber = 0;
+    unsigned nextPostNumber = 0;
+    
+    // Plain stack-based worklist because we are guaranteed to see each block exactly once anyway.
+    Vector<BlockWithOrder> worklist;
+    worklist.append(BlockWithOrder(graph.block(0), PreOrder));
+    while (!worklist.isEmpty()) {
+        BlockWithOrder item = worklist.takeLast();
+        switch (item.order) {
+        case PreOrder:
+            m_data[item.block].preNumber = nextPreNumber++;
+            worklist.append(BlockWithOrder(item.block, PostOrder));
+            for (BasicBlock* kid : m_data[item.block].idomKids)
+                worklist.append(BlockWithOrder(kid, PreOrder));
             break;
+        case PostOrder:
+            m_data[item.block].postNumber = nextPostNumber++;
+            break;
+        }
+    }
+    
+    if (validationEnabled()) {
+        // Check our dominator calculation:
+        // 1) Check that our range-based ancestry test is the same as a naive ancestry test.
+        // 2) Check that our notion of who dominates whom is identical to a naive (not
+        //    Lengauer-Tarjan) dominator calculation.
+        
+        ValidationContext context(graph, *this);
+        context.naiveDominators.compute(graph);
+        
+        for (BlockIndex fromBlockIndex = graph.numBlocks(); fromBlockIndex--;) {
+            BasicBlock* fromBlock = graph.block(fromBlockIndex);
+            if (!fromBlock || m_data[fromBlock].preNumber == UINT_MAX)
+                continue;
+            for (BlockIndex toBlockIndex = graph.numBlocks(); toBlockIndex--;) {
+                BasicBlock* toBlock = graph.block(toBlockIndex);
+                if (!toBlock || m_data[toBlock].preNumber == UINT_MAX)
+                    continue;
+                
+                if (dominates(fromBlock, toBlock) != naiveDominates(fromBlock, toBlock))
+                    context.reportError(fromBlock, toBlock, "Range-based domination check is broken");
+                if (dominates(fromBlock, toBlock) != context.naiveDominators.dominates(fromBlock, toBlock))
+                    context.reportError(fromBlock, toBlock, "Lengauer-Tarjan domination is broken");
+            }
+        }
+        
+        context.handleErrors();
+    }
+}
 
-        // Prune dominators in all non entry blocks: backward scan.
-        changed = false;
-        for (unsigned i = numBlocks; i-- > 1;)
-            changed |= pruneDominators(graph, i);
-    } while (changed);
+BlockSet Dominators::strictDominatorsOf(BasicBlock* to) const
+{
+    BlockSet result;
+    forAllStrictDominatorsOf(to, BlockAdder(result));
+    return result;
 }
 
-bool Dominators::pruneDominators(Graph& graph, BlockIndex idx)
+BlockSet Dominators::dominatorsOf(BasicBlock* to) const
 {
-    BasicBlock* block = graph.block(idx);
+    BlockSet result;
+    forAllDominatorsOf(to, BlockAdder(result));
+    return result;
+}
 
-    if (!block || block->predecessors.isEmpty())
-        return false;
+BlockSet Dominators::blocksStrictlyDominatedBy(BasicBlock* from) const
+{
+    BlockSet result;
+    forAllBlocksStrictlyDominatedBy(from, BlockAdder(result));
+    return result;
+}
 
-    // Find the intersection of dom(preds).
-    m_scratch.set(m_results[block->predecessors[0]->index]);
-    for (unsigned j = block->predecessors.size(); j-- > 1;)
-        m_scratch.filter(m_results[block->predecessors[j]->index]);
+BlockSet Dominators::blocksDominatedBy(BasicBlock* from) const
+{
+    BlockSet result;
+    forAllBlocksDominatedBy(from, BlockAdder(result));
+    return result;
+}
 
-    // The block is also dominated by itself.
-    m_scratch.set(idx);
+BlockSet Dominators::dominanceFrontierOf(BasicBlock* from) const
+{
+    BlockSet result;
+    forAllBlocksInDominanceFrontierOfImpl(from, BlockAdder(result));
+    return result;
+}
 
-    return m_results[idx].setAndCheck(m_scratch);
+BlockSet Dominators::iteratedDominanceFrontierOf(const BlockList& from) const
+{
+    BlockSet result;
+    forAllBlocksInIteratedDominanceFrontierOfImpl(from, BlockAdder(result));
+    return result;
 }
 
-void Dominators::dump(Graph& graph, PrintStream& out) const
+bool Dominators::naiveDominates(BasicBlock* from, BasicBlock* to) const
 {
-    for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
-        BasicBlock* block = graph.block(blockIndex);
-        if (!block)
+    for (BasicBlock* block = to; block; block = m_data[block].idomParent) {
+        if (block == from)
+            return true;
+    }
+    return false;
+}
+
+void Dominators::dump(PrintStream& out) const
+{
+    if (!isValid()) {
+        out.print("    Not Valid.\n");
+        return;
+    }
+    
+    for (BlockIndex blockIndex = 0; blockIndex < m_data.size(); ++blockIndex) {
+        if (m_data[blockIndex].preNumber == UINT_MAX)
             continue;
-        out.print("    Block ", *block, ":");
-        for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
-            if (!dominates(block->index, otherIndex))
-                continue;
-            out.print(" #", otherIndex);
-        }
-        out.print("\n");
+        
+        out.print("    Block #", blockIndex, ": idom = ", pointerDump(m_data[blockIndex].idomParent), ", idomKids = [");
+        CommaPrinter comma;
+        for (unsigned i = 0; i < m_data[blockIndex].idomKids.size(); ++i)
+            out.print(comma, *m_data[blockIndex].idomKids[i]);
+        out.print("], pre/post = ", m_data[blockIndex].preNumber, "/", m_data[blockIndex].postNumber, "\n");
     }
 }
 
index e9dc5c70f1b3f1f9e39ef3e7b4083a995658e710..e218ba792f261c1ad3f3055c7b0486eb1a9caa60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,8 +30,9 @@
 
 #include "DFGAnalysis.h"
 #include "DFGBasicBlock.h"
+#include "DFGBlockMap.h"
+#include "DFGBlockSet.h"
 #include "DFGCommon.h"
-#include <wtf/FastBitVector.h>
 
 namespace JSC { namespace DFG {
 
@@ -44,24 +45,173 @@ public:
     
     void compute(Graph&);
     
-    bool dominates(BlockIndex from, BlockIndex to) const
+    bool strictlyDominates(BasicBlock* from, BasicBlock* to) const
     {
         ASSERT(isValid());
-        return m_results[to].get(from);
+        return m_data[to].preNumber > m_data[from].preNumber
+            && m_data[to].postNumber < m_data[from].postNumber;
     }
     
     bool dominates(BasicBlock* from, BasicBlock* to) const
     {
-        return dominates(from->index, to->index);
+        return from == to || strictlyDominates(from, to);
     }
     
-    void dump(Graph&, PrintStream&) const;
+    BasicBlock* immediateDominatorOf(BasicBlock* block) const
+    {
+        return m_data[block].idomParent;
+    }
+    
+    template<typename Functor>
+    void forAllStrictDominatorsOf(BasicBlock* to, const Functor& functor) const
+    {
+        for (BasicBlock* block = m_data[to].idomParent; block; block = m_data[block].idomParent)
+            functor(block);
+    }
+    
+    template<typename Functor>
+    void forAllDominatorsOf(BasicBlock* to, const Functor& functor) const
+    {
+        for (BasicBlock* block = to; block; block = m_data[block].idomParent)
+            functor(block);
+    }
+    
+    template<typename Functor>
+    void forAllBlocksStrictlyDominatedBy(BasicBlock* from, const Functor& functor) const
+    {
+        Vector<BasicBlock*, 16> worklist;
+        worklist.appendVector(m_data[from].idomKids);
+        while (!worklist.isEmpty()) {
+            BasicBlock* block = worklist.takeLast();
+            functor(block);
+            worklist.appendVector(m_data[block].idomKids);
+        }
+    }
+    
+    template<typename Functor>
+    void forAllBlocksDominatedBy(BasicBlock* from, const Functor& functor) const
+    {
+        Vector<BasicBlock*, 16> worklist;
+        worklist.append(from);
+        while (!worklist.isEmpty()) {
+            BasicBlock* block = worklist.takeLast();
+            functor(block);
+            worklist.appendVector(m_data[block].idomKids);
+        }
+    }
+    
+    BlockSet strictDominatorsOf(BasicBlock* to) const;
+    BlockSet dominatorsOf(BasicBlock* to) const;
+    BlockSet blocksStrictlyDominatedBy(BasicBlock* from) const;
+    BlockSet blocksDominatedBy(BasicBlock* from) const;
+    
+    template<typename Functor>
+    void forAllBlocksInDominanceFrontierOf(
+        BasicBlock* from, const Functor& functor) const
+    {
+        BlockSet set;
+        forAllBlocksInDominanceFrontierOfImpl(
+            from,
+            [&] (BasicBlock* block) {
+                if (set.add(block))
+                    functor(block);
+            });
+    }
+    
+    BlockSet dominanceFrontierOf(BasicBlock* from) const;
+    
+    template<typename Functor>
+    void forAllBlocksInIteratedDominanceFrontierOf(
+        const BlockList& from, const Functor& functor)
+    {
+        forAllBlocksInPrunedIteratedDominanceFrontierOf(
+            from,
+            [&] (BasicBlock* block) -> bool {
+                functor(block);
+                return true;
+            });
+    }
+    
+    // This is a close relative of forAllBlocksInIteratedDominanceFrontierOf(), which allows the
+    // given functor to return false to indicate that we don't wish to consider the given block.
+    // Useful for computing pruned SSA form.
+    template<typename Functor>
+    void forAllBlocksInPrunedIteratedDominanceFrontierOf(
+        const BlockList& from, const Functor& functor)
+    {
+        BlockSet set;
+        forAllBlocksInIteratedDominanceFrontierOfImpl(
+            from,
+            [&] (BasicBlock* block) -> bool {
+                if (!set.add(block))
+                    return false;
+                return functor(block);
+            });
+    }
+    
+    BlockSet iteratedDominanceFrontierOf(const BlockList& from) const;
+    
+    void dump(PrintStream&) const;
     
 private:
-    bool pruneDominators(Graph&, BlockIndex);
+    bool naiveDominates(BasicBlock* from, BasicBlock* to) const;
+    
+    template<typename Functor>
+    void forAllBlocksInDominanceFrontierOfImpl(
+        BasicBlock* from, const Functor& functor) const
+    {
+        // Paraphrasing from http://en.wikipedia.org/wiki/Dominator_(graph_theory):
+        //     "The dominance frontier of a block 'from' is the set of all blocks 'to' such that
+        //     'from' dominates an immediate predecessor of 'to', but 'from' does not strictly
+        //     dominate 'to'."
+        //
+        // A useful corner case to remember: a block may be in its own dominance frontier if it has
+        // a loop edge to itself, since it dominates itself and so it dominates its own immediate
+        // predecessor, and a block never strictly dominates itself.
+        
+        forAllBlocksDominatedBy(
+            from,
+            [&] (BasicBlock* block) {
+                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
+                    BasicBlock* to = block->successor(successorIndex);
+                    if (!strictlyDominates(from, to))
+                        functor(to);
+                }
+            });
+    }
+    
+    template<typename Functor>
+    void forAllBlocksInIteratedDominanceFrontierOfImpl(
+        const BlockList& from, const Functor& functor) const
+    {
+        BlockList worklist = from;
+        while (!worklist.isEmpty()) {
+            BasicBlock* block = worklist.takeLast();
+            forAllBlocksInDominanceFrontierOfImpl(
+                block,
+                [&] (BasicBlock* otherBlock) {
+                    if (functor(otherBlock))
+                        worklist.append(otherBlock);
+                });
+        }
+    }
+    
+    struct BlockData {
+        BlockData()
+            : idomParent(nullptr)
+            , preNumber(UINT_MAX)
+            , postNumber(UINT_MAX)
+        {
+        }
+        
+        Vector<BasicBlock*> idomKids;
+        BasicBlock* idomParent;
+        
+        unsigned preNumber;
+        unsigned postNumber;
+    };
     
-    Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
-    FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
+    BlockMap<BlockData> m_data;
 };
 
 } } // namespace JSC::DFG
index 30b4f3888e99100b0d236afe610bdff71d72e3a0..5b83f69900f9125edb161515d1f55ba41f62ce7c 100644 (file)
@@ -30,6 +30,7 @@
 #include "JSString.h"
 
 #include "CodeBlock.h"
+#include "DFGFunctionWhitelist.h"
 #include "DFGJITCode.h"
 #include "DFGPlan.h"
 #include "DFGThunks.h"
@@ -38,6 +39,7 @@
 #include "JSCInlines.h"
 #include "Options.h"
 #include "SamplingTool.h"
+#include "TypeProfilerLog.h"
 #include <wtf/Atomics.h>
 
 #if ENABLE(FTL_JIT)
@@ -61,6 +63,10 @@ static CompilationResult compileImpl(
 {
     SamplingRegion samplingRegion("DFG Compilation (Driver)");
     
+    if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount())
+        || !FunctionWhitelist::ensureGlobalWhitelist().contains(codeBlock))
+        return CompilationFailed;
+    
     numCompilations++;
     
     ASSERT(codeBlock);
@@ -78,23 +84,26 @@ static CompilationResult compileImpl(
     if (mode == DFGMode) {
         vm.getCTIStub(linkCallThunkGenerator);
         vm.getCTIStub(linkConstructThunkGenerator);
-        vm.getCTIStub(linkClosureCallThunkGenerator);
+        vm.getCTIStub(linkPolymorphicCallThunkGenerator);
         vm.getCTIStub(virtualCallThunkGenerator);
         vm.getCTIStub(virtualConstructThunkGenerator);
     } else {
         vm.getCTIStub(linkCallThatPreservesRegsThunkGenerator);
         vm.getCTIStub(linkConstructThatPreservesRegsThunkGenerator);
-        vm.getCTIStub(linkClosureCallThatPreservesRegsThunkGenerator);
+        vm.getCTIStub(linkPolymorphicCallThatPreservesRegsThunkGenerator);
         vm.getCTIStub(virtualCallThatPreservesRegsThunkGenerator);
         vm.getCTIStub(virtualConstructThatPreservesRegsThunkGenerator);
     }
     
+    if (vm.typeProfiler())
+        vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Preparing for DFG compilation."));
+    
     RefPtr<Plan> plan = adoptRef(
         new Plan(codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues));
     
+    plan->callback = callback;
     if (Options::enableConcurrentJIT()) {
         Worklist* worklist = ensureGlobalWorklistFor(mode);
-        plan->callback = callback;
         if (logCompilationChanges(mode))
             dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", worklist->queueLength(), ".\n");
         worklist->enqueue(plan);
index bf05f350291442507692de6a3cf4247b398a02e9..154401e4d36be7d054435cc465b5939a01e31051 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,7 +36,7 @@ namespace JSC { namespace DFG {
 void Edge::dump(PrintStream& out) const
 {
     if (useKindUnchecked() != UntypedUse) {
-        if (needsCheck())
+        if (!isProved())
             out.print("Check:");
         out.print(useKind(), ":");
     }
index 4ceda0cbaa733bac78e4043dd8a41b11a732dee2..7a05fabae05e4faf329ecfa86735ebf60c741765 100644 (file)
@@ -115,10 +115,6 @@ public:
     {
         return proofStatus() == IsProved;
     }
-    bool needsCheck() const
-    {
-        return proofStatus() == NeedsCheck;
-    }
     
     bool willNotHaveCheck() const
     {
@@ -205,13 +201,13 @@ private:
         ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
         ASSERT(useKind >= 0 && useKind < LastUseKind);
         ASSERT((static_cast<uintptr_t>(LastUseKind) << 2) <= (static_cast<uintptr_t>(2) << shift()));
-        return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
+        return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
     }
     
 #else
     static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
     {
-        return (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
+        return (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | static_cast<uintptr_t>(DFG::isProved(proofStatus));
     }
     
     Node* m_node;
index 0af2e98e0376018555323eb68a5af9ad654a06d0..d95c79df2d194324e9eaf8467b68498e24369839 100644 (file)
@@ -45,10 +45,10 @@ public:
     
     void operator()(Node*, Edge edge)
     {
-        bool result = m_graph.m_dominators.dominates(edge.node()->misc.owner, m_block);
+        bool result = m_graph.m_dominators.dominates(edge.node()->owner, m_block);
         if (verbose) {
             dataLog(
-                "Checking if ", edge, " in ", *edge.node()->misc.owner,
+                "Checking if ", edge, " in ", *edge.node()->owner,
                 " dominates ", *m_block, ": ", result, "\n");
         }
         m_result &= result;
diff --git a/dfg/DFGEpoch.cpp b/dfg/DFGEpoch.cpp
new file mode 100644 (file)
index 0000000..7da1deb
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGEpoch.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void Epoch::dump(PrintStream& out) const
+{
+    if (!*this)
+        out.print("none");
+    else
+        out.print(m_epoch);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGEpoch.h b/dfg/DFGEpoch.h
new file mode 100644 (file)
index 0000000..9865dd7
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGEpoch_h
+#define DFGEpoch_h
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+// Utility class for epoch-based analyses.
+
+class Epoch {
+public:
+    Epoch()
+        : m_epoch(s_none)
+    {
+    }
+    
+    static Epoch fromUnsigned(unsigned value)
+    {
+        Epoch result;
+        result.m_epoch = value;
+        return result;
+    }
+    
+    unsigned toUnsigned() const
+    {
+        return m_epoch;
+    }
+    
+    static Epoch first()
+    {
+        Epoch result;
+        result.m_epoch = s_first;
+        return result;
+    }
+    
+    bool operator!() const
+    {
+        return m_epoch == s_none;
+    }
+    
+    Epoch next() const
+    {
+        Epoch result;
+        result.m_epoch = m_epoch + 1;
+        return result;
+    }
+    
+    void bump()
+    {
+        *this = next();
+    }
+    
+    bool operator==(const Epoch& other) const
+    {
+        return m_epoch == other.m_epoch;
+    }
+    
+    bool operator!=(const Epoch& other) const
+    {
+        return !(*this == other);
+    }
+    
+    bool operator<(const Epoch& other) const
+    {
+        return m_epoch < other.m_epoch;
+    }
+    
+    bool operator>(const Epoch& other) const
+    {
+        return other < *this;
+    }
+    
+    bool operator<=(const Epoch& other) const
+    {
+        return !(*this > other);
+    }
+    
+    bool operator>=(const Epoch& other) const
+    {
+        return !(*this < other);
+    }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    static const unsigned s_none = 0;
+    static const unsigned s_first = 1;
+    
+    unsigned m_epoch;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGEpoch_h
+
index f51aecd505593ccdf1f0f693cc9c44fdc4b69153..ad0bf4d2e547f28ac03ef90bd779e531932e5381 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace DFG {
 
+// Tells you if an operation that filters type (i.e. does a type check/speculation) will always
+// exit. Formally, this means that the proven type of a value prior to the filter was not
+// bottom (i.e. not "clear" or "SpecEmpty") but becomes bottom as a result of executing the
+// filter.
+//
+// Note that per this definition, a filter will not return Contradiction if the node's proven
+// type was already bottom. This is necessary because we have this yucky convention of using
+// a proven type of bottom for nodes that don't hold JS values, like Phi nodes in ThreadedCPS
+// and storage nodes.
 enum FiltrationResult {
+    // Means that this operation may not always exit.
     FiltrationOK,
+    
+    // Means taht this operation will always exit.
     Contradiction
 };
 
index 5223b5956ead4a68a0b6beeb2cb6f33db6b463b0..1affa1ab8fe9c1302381e82a1e2ee47a2ffe62c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
+#include "ArrayPrototype.h"
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
 #include "DFGPhase.h"
 #include "DFGPredictionPropagationPhase.h"
 #include "DFGVariableAccessDataDump.h"
 #include "JSCInlines.h"
+#include "TypeLocation.h"
 
 namespace JSC { namespace DFG {
 
@@ -66,7 +68,9 @@ public:
         
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
             injectTypeConversionsInBlock(m_graph.block(blockIndex));
-        
+
+        m_graph.m_planStage = PlanStage::AfterFixup;
+
         return true;
     }
 
@@ -79,10 +83,8 @@ private:
         m_block = block;
         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
             m_currentNode = block->at(m_indexInBlock);
-            addPhantomsIfNecessary();
             fixupNode(m_currentNode);
         }
-        clearPhantomsAtEnd();
         m_insertionSet.execute(block);
     }
     
@@ -92,7 +94,7 @@ private:
 
         switch (op) {
         case SetLocal: {
-            // This gets handled by fixupSetLocalsInBlock().
+            // This gets handled by fixupGetAndSetLocalsInBlock().
             return;
         }
             
@@ -116,6 +118,12 @@ private:
             node->child2().setUseKind(Int32Use);
             break;
         }
+
+        case ArithClz32: {
+            fixIntConvertingEdge(node->child1());
+            node->setArithMode(Arith::Unchecked);
+            break;
+        }
             
         case UInt32ToNumber: {
             fixIntConvertingEdge(node->child1());
@@ -133,14 +141,12 @@ private:
         case ValueAdd: {
             if (attemptToMakeIntegerAdd(node)) {
                 node->setOp(ArithAdd);
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
                 break;
             }
             if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
                 fixDoubleOrBooleanEdge(node->child1());
                 fixDoubleOrBooleanEdge(node->child2());
                 node->setOp(ArithAdd);
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
                 node->setResult(NodeResultDouble);
                 break;
             }
@@ -243,7 +249,7 @@ private:
         case ArithMod: {
             if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
                 && node->canSpeculateInt32(FixupPass)) {
-                if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7s()) {
+                if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
                     fixIntOrBooleanEdge(node->child1());
                     fixIntOrBooleanEdge(node->child2());
                     if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
@@ -259,12 +265,6 @@ private:
                 fixDoubleOrBooleanEdge(node->child1());
                 fixDoubleOrBooleanEdge(node->child2());
                 
-                // But we have to make sure that everything is phantom'd until after the
-                // DoubleAsInt32 node, which occurs after the Div/Mod node that the conversions
-                // will be insered on.
-                addRequiredPhantom(node->child1().node());
-                addRequiredPhantom(node->child2().node());
-
                 // We don't need to do ref'ing on the children because we're stealing them from
                 // the original division.
                 Node* newDivision = m_insertionSet.insertNode(
@@ -309,11 +309,47 @@ private:
             node->setResult(NodeResultDouble);
             break;
         }
+
+        case ArithPow: {
+            node->setResult(NodeResultDouble);
+            if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
+                fixDoubleOrBooleanEdge(node->child1());
+                fixIntOrBooleanEdge(node->child2());
+                break;
+            }
+
+            fixDoubleOrBooleanEdge(node->child1());
+            fixDoubleOrBooleanEdge(node->child2());
+            break;
+        }
+
+        case ArithRound: {
+            if (node->child1()->shouldSpeculateInt32OrBooleanForArithmetic() && node->canSpeculateInt32(FixupPass)) {
+                fixIntOrBooleanEdge(node->child1());
+                insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
+                node->convertToIdentity();
+                break;
+            }
+            fixDoubleOrBooleanEdge(node->child1());
+
+            if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
+                node->setResult(NodeResultInt32);
+                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+                    node->setArithRoundingMode(Arith::RoundingMode::Int32);
+                else
+                    node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
+            } else {
+                node->setResult(NodeResultDouble);
+                node->setArithRoundingMode(Arith::RoundingMode::Double);
+            }
+            break;
+        }
             
         case ArithSqrt:
         case ArithFRound:
         case ArithSin:
-        case ArithCos: {
+        case ArithCos:
+        case ArithLog: {
             fixDoubleOrBooleanEdge(node->child1());
             node->setResult(NodeResultDouble);
             break;
@@ -333,14 +369,6 @@ private:
             break;
         }
             
-        case TypeOf: {
-            if (node->child1()->shouldSpeculateString())
-                fixEdge<StringUse>(node->child1());
-            else if (node->child1()->shouldSpeculateCell())
-                fixEdge<CellUse>(node->child1());
-            break;
-        }
-            
         case CompareEqConstant: {
             break;
         }
@@ -354,26 +382,26 @@ private:
                 && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
                 fixEdge<BooleanUse>(node->child1());
                 fixEdge<BooleanUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
                 fixIntOrBooleanEdge(node->child1());
                 fixIntOrBooleanEdge(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (enableInt52()
                 && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
                 fixEdge<Int52RepUse>(node->child1());
                 fixEdge<Int52RepUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
                 fixDoubleOrBooleanEdge(node->child1());
                 fixDoubleOrBooleanEdge(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (node->op() != CompareEq)
@@ -381,31 +409,31 @@ private:
             if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
                 fixEdge<StringIdentUse>(node->child1());
                 fixEdge<StringIdentUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
                 fixEdge<StringUse>(node->child1());
                 fixEdge<StringUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
                 fixEdge<ObjectUse>(node->child1());
                 fixEdge<ObjectUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
                 fixEdge<ObjectUse>(node->child1());
                 fixEdge<ObjectOrOtherUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
                 fixEdge<ObjectOrOtherUse>(node->child1());
                 fixEdge<ObjectUse>(node->child2());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             break;
@@ -438,12 +466,26 @@ private:
                 fixEdge<StringIdentUse>(node->child2());
                 break;
             }
-            if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 7 || isFTL(m_graph.m_plan.mode))) {
+            if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || isFTL(m_graph.m_plan.mode))) {
                 fixEdge<StringUse>(node->child1());
                 fixEdge<StringUse>(node->child2());
                 break;
             }
-            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
+            WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
+            if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
+                
+                if (node->child1()->shouldSpeculateObject()) {
+                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+                    fixEdge<ObjectUse>(node->child1());
+                    break;
+                }
+                if (node->child2()->shouldSpeculateObject()) {
+                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+                    fixEdge<ObjectUse>(node->child2());
+                    break;
+                }
+                
+            } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
                 fixEdge<ObjectUse>(node->child1());
                 fixEdge<ObjectUse>(node->child2());
                 break;
@@ -468,11 +510,11 @@ private:
                 fixEdge<NotStringVarUse>(node->child1());
                 break;
             }
-            if (node->child1()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 8 || isFTL(m_graph.m_plan.mode))) {
+            if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
                 fixEdge<StringUse>(node->child1());
                 break;
             }
-            if (node->child2()->shouldSpeculateString() && (GPRInfo::numberOfRegisters >= 8 || isFTL(m_graph.m_plan.mode))) {
+            if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || isFTL(m_graph.m_plan.mode))) {
                 fixEdge<StringUse>(node->child2());
                 break;
             }
@@ -494,23 +536,79 @@ private:
         }
 
         case GetByVal: {
+            if (!node->prediction()) {
+                m_insertionSet.insertNode(
+                    m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
+            }
+            
             node->setArrayMode(
                 node->arrayMode().refine(
                     m_graph, node,
                     node->child1()->prediction(),
                     node->child2()->prediction(),
-                    SpecNone, node->flags()));
+                    SpecNone));
             
             blessArrayOperation(node->child1(), node->child2(), node->child3());
             
             ArrayMode arrayMode = node->arrayMode();
             switch (arrayMode.type()) {
+            case Array::Contiguous:
             case Array::Double:
                 if (arrayMode.arrayClass() == Array::OriginalArray
-                    && arrayMode.speculation() == Array::InBounds
-                    && m_graph.globalObjectFor(node->origin.semantic)->arrayPrototypeChainIsSane()
-                    && !(node->flags() & NodeBytecodeUsesAsOther))
-                    node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
+                    && arrayMode.speculation() == Array::InBounds) {
+                    JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
+                    if (globalObject->arrayPrototypeChainIsSane()) {
+                        // Check if SaneChain will work on a per-type basis. Note that:
+                        //
+                        // 1) We don't want double arrays to sometimes return undefined, since
+                        // that would require a change to the return type and it would pessimise
+                        // things a lot. So, we'd only want to do that if we actually had
+                        // evidence that we could read from a hole. That's pretty annoying.
+                        // Likely the best way to handle that case is with an equivalent of
+                        // SaneChain for OutOfBounds. For now we just detect when Undefined and
+                        // NaN are indistinguishable according to backwards propagation, and just
+                        // use SaneChain in that case. This happens to catch a lot of cases.
+                        //
+                        // 2) We don't want int32 array loads to have to do a hole check just to
+                        // coerce to Undefined, since that would mean twice the checks.
+                        //
+                        // This has two implications. First, we have to do more checks than we'd
+                        // like. It's unfortunate that we have to do the hole check. Second,
+                        // some accesses that hit a hole will now need to take the full-blown
+                        // out-of-bounds slow path. We can fix that with:
+                        // https://bugs.webkit.org/show_bug.cgi?id=144668
+                        
+                        bool canDoSaneChain = false;
+                        switch (arrayMode.type()) {
+                        case Array::Contiguous:
+                            // This is happens to be entirely natural. We already would have
+                            // returned any JSValue, and now we'll return Undefined. We still do
+                            // the check but it doesn't require taking any kind of slow path.
+                            canDoSaneChain = true;
+                            break;
+                            
+                        case Array::Double:
+                            if (!(node->flags() & NodeBytecodeUsesAsOther)) {
+                                // Holes look like NaN already, so if the user doesn't care
+                                // about the difference between Undefined and NaN then we can
+                                // do this.
+                                canDoSaneChain = true;
+                            }
+                            break;
+                            
+                        default:
+                            break;
+                        }
+                        
+                        if (canDoSaneChain) {
+                            m_graph.watchpoints().addLazily(
+                                globalObject->arrayPrototype()->structure()->transitionWatchpointSet());
+                            m_graph.watchpoints().addLazily(
+                                globalObject->objectPrototype()->structure()->transitionWatchpointSet());
+                            node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
+                        }
+                    }
+                }
                 break;
                 
             case Array::String:
@@ -636,10 +734,9 @@ private:
             case Array::Contiguous:
             case Array::ArrayStorage:
             case Array::SlowPutArrayStorage:
-            case Array::Arguments:
                 fixEdge<KnownCellUse>(child1);
                 fixEdge<Int32Use>(child2);
-                insertStoreBarrier(m_indexInBlock, child1);
+                speculateForBarrier(child3);
                 break;
             default:
                 fixEdge<KnownCellUse>(child1);
@@ -677,7 +774,7 @@ private:
                 break;
             case Array::Contiguous:
             case Array::ArrayStorage:
-                insertStoreBarrier(m_indexInBlock, node->child1());
+                speculateForBarrier(node->child2());
                 break;
             default:
                 break;
@@ -703,46 +800,12 @@ private:
                 fixEdge<BooleanUse>(node->child1());
             else if (node->child1()->shouldSpeculateObjectOrOther())
                 fixEdge<ObjectOrOtherUse>(node->child1());
-            // FIXME: We should just be able to do shouldSpeculateInt32OrBoolean() and
-            // shouldSpeculateNumberOrBoolean() here, but we can't because then the Branch
-            // could speculate on the result of a non-speculative conversion node.
-            // https://bugs.webkit.org/show_bug.cgi?id=126778
-            else if (node->child1()->shouldSpeculateInt32())
-                fixEdge<Int32Use>(node->child1());
+            else if (node->child1()->shouldSpeculateInt32OrBoolean())
+                fixIntOrBooleanEdge(node->child1());
             else if (node->child1()->shouldSpeculateNumber())
                 fixEdge<DoubleRepUse>(node->child1());
-
-            Node* logicalNot = node->child1().node();
-            if (logicalNot->op() == LogicalNot) {
-                
-                // Make sure that OSR exit can't observe the LogicalNot. If it can,
-                // then we must compute it and cannot peephole around it.
-                bool found = false;
-                bool ok = true;
-                for (unsigned i = m_indexInBlock; i--;) {
-                    Node* candidate = m_block->at(i);
-                    if (candidate == logicalNot) {
-                        found = true;
-                        break;
-                    }
-                    if (candidate->canExit()) {
-                        ok = false;
-                        found = true;
-                        break;
-                    }
-                }
-                ASSERT_UNUSED(found, found);
-                
-                if (ok) {
-                    Edge newChildEdge = logicalNot->child1();
-                    if (newChildEdge->hasBooleanResult()) {
-                        node->children.setChild1(newChildEdge);
-                        
-                        BranchData* data = node->branchData();
-                        std::swap(data->taken, data->notTaken);
-                    }
-                }
-            }
+            else if (node->child1()->shouldSpeculateString())
+                fixEdge<StringUse>(node->child1());
             break;
         }
             
@@ -763,6 +826,12 @@ private:
                 else if (node->child1()->shouldSpeculateString())
                     fixEdge<StringUse>(node->child1());
                 break;
+            case SwitchCell:
+                if (node->child1()->shouldSpeculateCell())
+                    fixEdge<CellUse>(node->child1());
+                // else it's fine for this to have UntypedUse; we will handle this by just making
+                // non-cells take the default case.
+                break;
             }
             break;
         }
@@ -772,8 +841,9 @@ private:
             break;
         }
             
-        case ToString: {
-            fixupToString(node);
+        case ToString:
+        case CallStringConstructor: {
+            fixupToStringOrCallStringConstructor(node);
             break;
         }
             
@@ -822,7 +892,7 @@ private:
         case NewTypedArray: {
             if (node->child1()->shouldSpeculateInt32()) {
                 fixEdge<Int32Use>(node->child1());
-                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+                node->clearFlags(NodeMustGenerate);
                 break;
             }
             break;
@@ -844,10 +914,11 @@ private:
                 }
 
                 m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Phantom, node->origin,
+                    m_indexInBlock, SpecNone, Check, node->origin,
                     Edge(node->child1().node(), OtherUse));
                 observeUseKindOnNode<OtherUse>(node->child1().node());
-                node->convertToWeakConstant(m_graph.globalThisObjectFor(node->origin.semantic));
+                m_graph.convertToConstant(
+                    node, m_graph.globalThisObjectFor(node->origin.semantic));
                 break;
             }
             
@@ -860,28 +931,28 @@ private:
             break;
         }
             
-        case GetMyArgumentByVal:
-        case GetMyArgumentByValSafe: {
-            fixEdge<Int32Use>(node->child1());
+        case PutStructure: {
+            fixEdge<KnownCellUse>(node->child1());
             break;
         }
             
-        case PutStructure: {
+        case GetClosureVar:
+        case GetFromArguments: {
             fixEdge<KnownCellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
             break;
         }
 
-        case PutClosureVar: {
+        case PutClosureVar:
+        case PutToArguments: {
             fixEdge<KnownCellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            speculateForBarrier(node->child2());
             break;
         }
-
-        case GetClosureRegisters:
-        case SkipTopScope:
+            
         case SkipScope:
-        case GetScope: {
+        case GetScope:
+        case GetGetter:
+        case GetSetter: {
             fixEdge<KnownCellUse>(node->child1());
             break;
         }
@@ -889,7 +960,6 @@ private:
         case AllocatePropertyStorage:
         case ReallocatePropertyStorage: {
             fixEdge<KnownCellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock + 1, node->child1());
             break;
         }
 
@@ -897,18 +967,25 @@ private:
         case GetByIdFlush: {
             if (!node->child1()->shouldSpeculateCell())
                 break;
-            StringImpl* impl = m_graph.identifiers()[node->identifierNumber()];
-            if (impl == vm().propertyNames->length.impl()) {
-                attemptToMakeGetArrayLength(node);
-                break;
-            }
-            if (impl == vm().propertyNames->byteLength.impl()) {
-                attemptToMakeGetTypedArrayByteLength(node);
-                break;
-            }
-            if (impl == vm().propertyNames->byteOffset.impl()) {
-                attemptToMakeGetTypedArrayByteOffset(node);
-                break;
+
+            // If we hadn't exited because of BadCache, BadIndexingType, or ExoticObjectMode, then
+            // leave this as a GetById.
+            if (!m_graph.hasExitSite(node->origin.semantic, BadCache)
+                && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
+                && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
+                auto uid = m_graph.identifiers()[node->identifierNumber()];
+                if (uid == vm().propertyNames->length.impl()) {
+                    attemptToMakeGetArrayLength(node);
+                    break;
+                }
+                if (uid == vm().propertyNames->byteLength.impl()) {
+                    attemptToMakeGetTypedArrayByteLength(node);
+                    break;
+                }
+                if (uid == vm().propertyNames->byteOffset.impl()) {
+                    attemptToMakeGetTypedArrayByteOffset(node);
+                    break;
+                }
             }
             fixEdge<CellUse>(node->child1());
             break;
@@ -918,14 +995,17 @@ private:
         case PutByIdFlush:
         case PutByIdDirect: {
             fixEdge<CellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            speculateForBarrier(node->child2());
             break;
         }
 
-        case CheckExecutable:
+        case GetExecutable: {
+            fixEdge<FunctionUse>(node->child1());
+            break;
+        }
+            
         case CheckStructure:
-        case StructureTransitionWatchpoint:
-        case CheckFunction:
+        case CheckCell:
         case CheckHasInstance:
         case CreateThis:
         case GetButterfly: {
@@ -941,7 +1021,8 @@ private:
             break;
         }
             
-        case GetByOffset: {
+        case GetByOffset:
+        case GetGetterSetterByOffset: {
             if (!node->child1()->hasStorageResult())
                 fixEdge<KnownCellUse>(node->child1());
             fixEdge<KnownCellUse>(node->child2());
@@ -957,13 +1038,13 @@ private:
             if (!node->child1()->hasStorageResult())
                 fixEdge<KnownCellUse>(node->child1());
             fixEdge<KnownCellUse>(node->child2());
-            insertStoreBarrier(m_indexInBlock, node->child2());
+            speculateForBarrier(node->child3());
             break;
         }
             
         case MultiPutByOffset: {
             fixEdge<CellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1());
+            speculateForBarrier(node->child2());
             break;
         }
             
@@ -982,20 +1063,28 @@ private:
             break;
         }
 
-        case Phantom:
         case Check: {
-            switch (node->child1().useKind()) {
-            case NumberUse:
-                if (node->child1()->shouldSpeculateInt32ForArithmetic())
-                    node->child1().setUseKind(Int32Use);
-                break;
-            default:
-                break;
-            }
-            observeUseKindOnEdge(node->child1());
+            m_graph.doToChildren(
+                node,
+                [&] (Edge& edge) {
+                    switch (edge.useKind()) {
+                    case NumberUse:
+                        if (edge->shouldSpeculateInt32ForArithmetic())
+                            edge.setUseKind(Int32Use);
+                        break;
+                    default:
+                        break;
+                    }
+                    observeUseKindOnEdge(edge);
+                });
             break;
         }
 
+        case Phantom:
+            // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
+            node->remove();
+            break;
+
         case FiatInt52: {
             RELEASE_ASSERT(enableInt52());
             node->convertToIdentity();
@@ -1007,82 +1096,197 @@ private:
         case GetArrayLength:
         case Phi:
         case Upsilon:
-        case GetArgument:
-        case PhantomPutStructure:
         case GetIndexedPropertyStorage:
         case GetTypedArrayByteOffset:
         case LastNodeType:
         case CheckTierUpInLoop:
         case CheckTierUpAtReturn:
         case CheckTierUpAndOSREnter:
+        case CheckTierUpWithNestedTriggerAndOSREnter:
         case InvalidationPoint:
         case CheckArray:
         case CheckInBounds:
         case ConstantStoragePointer:
         case DoubleAsInt32:
         case ValueToInt32:
-        case HardPhantom: // HardPhantom would be trivial to handle but anyway we assert that we won't see it here yet.
         case DoubleRep:
         case ValueRep:
         case Int52Rep:
-        case DoubleConstant:
         case Int52Constant:
         case Identity: // This should have been cleaned up.
         case BooleanToNumber:
+        case PhantomNewObject:
+        case PhantomNewFunction:
+        case PhantomCreateActivation:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case ForwardVarargs:
+        case GetMyArgumentByVal:
+        case PutHint:
+        case CheckStructureImmediate:
+        case MaterializeNewObject:
+        case MaterializeCreateActivation:
+        case PutStack:
+        case KillStack:
+        case GetStack:
+        case StoreBarrier:
             // These are just nodes that we don't currently expect to see during fixup.
             // If we ever wanted to insert them prior to fixup, then we just have to create
             // fixup rules for them.
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_graph, node, "Unexpected node during fixup");
             break;
         
         case PutGlobalVar: {
-            Node* globalObjectNode = m_insertionSet.insertNode(
-                m_indexInBlock, SpecNone, WeakJSConstant, node->origin, 
-                OpInfo(m_graph.globalObjectFor(node->origin.semantic)));
-            Node* barrierNode = m_graph.addNode(
-                SpecNone, StoreBarrier, m_currentNode->origin, 
-                Edge(globalObjectNode, KnownCellUse));
-            m_insertionSet.insert(m_indexInBlock, barrierNode);
-            break;
-        }
-
-        case TearOffActivation: {
-            Node* barrierNode = m_graph.addNode(
-                SpecNone, StoreBarrierWithNullCheck, m_currentNode->origin, 
-                Edge(node->child1().node(), UntypedUse));
-            m_insertionSet.insert(m_indexInBlock, barrierNode);
+            fixEdge<CellUse>(node->child1());
+            speculateForBarrier(node->child2());
             break;
         }
 
         case IsString:
             if (node->child1()->shouldSpeculateString()) {
                 m_insertionSet.insertNode(
-                    m_indexInBlock, SpecNone, Phantom, node->origin,
+                    m_indexInBlock, SpecNone, Check, node->origin,
                     Edge(node->child1().node(), StringUse));
                 m_graph.convertToConstant(node, jsBoolean(true));
                 observeUseKindOnNode<StringUse>(node);
             }
             break;
+
+        case IsObject:
+            if (node->child1()->shouldSpeculateObject()) {
+                m_insertionSet.insertNode(
+                    m_indexInBlock, SpecNone, Check, node->origin,
+                    Edge(node->child1().node(), ObjectUse));
+                m_graph.convertToConstant(node, jsBoolean(true));
+                observeUseKindOnNode<ObjectUse>(node);
+            }
+            break;
+
+        case GetEnumerableLength: {
+            fixEdge<CellUse>(node->child1());
+            break;
+        }
+        case HasGenericProperty: {
+            fixEdge<CellUse>(node->child2());
+            break;
+        }
+        case HasStructureProperty: {
+            fixEdge<StringUse>(node->child2());
+            fixEdge<KnownCellUse>(node->child3());
+            break;
+        }
+        case HasIndexedProperty: {
+            node->setArrayMode(
+                node->arrayMode().refine(
+                    m_graph, node,
+                    node->child1()->prediction(),
+                    node->child2()->prediction(),
+                    SpecNone));
+            
+            blessArrayOperation(node->child1(), node->child2(), node->child3());
+            fixEdge<CellUse>(node->child1());
+            fixEdge<KnownInt32Use>(node->child2());
+            break;
+        }
+        case GetDirectPname: {
+            Edge& base = m_graph.varArgChild(node, 0);
+            Edge& property = m_graph.varArgChild(node, 1);
+            Edge& index = m_graph.varArgChild(node, 2);
+            Edge& enumerator = m_graph.varArgChild(node, 3);
+            fixEdge<CellUse>(base);
+            fixEdge<KnownCellUse>(property);
+            fixEdge<KnownInt32Use>(index);
+            fixEdge<KnownCellUse>(enumerator);
+            break;
+        }
+        case GetPropertyEnumerator: {
+            fixEdge<CellUse>(node->child1());
+            break;
+        }
+        case GetEnumeratorStructurePname: {
+            fixEdge<KnownCellUse>(node->child1());
+            fixEdge<KnownInt32Use>(node->child2());
+            break;
+        }
+        case GetEnumeratorGenericPname: {
+            fixEdge<KnownCellUse>(node->child1());
+            fixEdge<KnownInt32Use>(node->child2());
+            break;
+        }
+        case ToIndexString: {
+            fixEdge<KnownInt32Use>(node->child1());
+            break;
+        }
+        case ProfileType: {
+            // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
+            // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
+            // type T for the instructionTypeSet, the global type set must also have information for type T.
+            // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T 
+            // in the globalTypeSet would've also succeeded.
+            // (The other direction does not hold in general).
+
+            RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
+            RuntimeTypeMask seenTypes = typeSet->seenTypes();
+            if (typeSet->doesTypeConformTo(TypeMachineInt)) {
+                if (node->child1()->shouldSpeculateInt32())
+                    fixEdge<Int32Use>(node->child1());
+                else
+                    fixEdge<MachineIntUse>(node->child1());
+                node->remove();
+            } else if (typeSet->doesTypeConformTo(TypeNumber | TypeMachineInt)) {
+                fixEdge<NumberUse>(node->child1());
+                node->remove();
+            } else if (typeSet->doesTypeConformTo(TypeString)) {
+                fixEdge<StringUse>(node->child1());
+                node->remove();
+            } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
+                fixEdge<BooleanUse>(node->child1());
+                node->remove();
+            } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
+                fixEdge<OtherUse>(node->child1());
+                node->remove();
+            } else if (typeSet->doesTypeConformTo(TypeObject)) {
+                StructureSet set = typeSet->structureSet();
+                if (!set.isEmpty()) {
+                    fixEdge<CellUse>(node->child1());
+                    node->convertToCheckStructure(m_graph.addStructureSet(set));
+                }
+            }
+
+            break;
+        }
+
+        case CreateScopedArguments:
+        case CreateActivation:
+        case NewFunction: {
+            fixEdge<CellUse>(node->child1());
+            break;
+        }
             
 #if !ASSERT_DISABLED
         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
         case SetArgument:
         case JSConstant:
-        case WeakJSConstant:
+        case DoubleConstant:
         case GetLocal:
         case GetCallee:
+        case GetArgumentCount:
         case Flush:
         case PhantomLocal:
         case GetLocalUnlinked:
-        case GetMyScope:
-        case GetClosureVar:
         case GetGlobalVar:
         case NotifyWrite:
-        case VariableWatchpoint:
         case VarInjectionWatchpoint:
-        case AllocationProfileWatchpoint:
         case Call:
         case Construct:
+        case CallVarargs:
+        case ConstructVarargs:
+        case CallForwardVarargs:
+        case ConstructForwardVarargs:
+        case LoadVarargs:
+        case ProfileControlFlow:
+        case NativeCall:
+        case NativeConstruct:
         case NewObject:
         case NewArrayBuffer:
         case NewRegexp:
@@ -1092,34 +1296,26 @@ private:
         case IsUndefined:
         case IsBoolean:
         case IsNumber:
-        case IsObject:
+        case IsObjectOrNull:
         case IsFunction:
-        case CreateActivation:
-        case CreateArguments:
-        case PhantomArguments:
-        case TearOffArguments:
-        case GetMyArgumentsLength:
-        case GetMyArgumentsLengthSafe:
-        case CheckArgumentsNotCreated:
-        case NewFunction:
-        case NewFunctionNoCheck:
-        case NewFunctionExpression:
+        case CreateDirectArguments:
+        case CreateClonedArguments:
         case Jump:
         case Return:
         case Throw:
         case ThrowReferenceError:
         case CountExecution:
         case ForceOSRExit:
+        case CheckBadCell:
+        case CheckNotEmpty:
         case CheckWatchdogTimer:
         case Unreachable:
         case ExtractOSREntryLocal:
         case LoopHint:
-        case StoreBarrier:
-        case StoreBarrierWithNullCheck:
-        case FunctionReentryWatchpoint:
-        case TypedArrayWatchpoint:
         case MovHint:
         case ZombieHint:
+        case BottomValue:
+        case TypeOf:
             break;
 #else
         default:
@@ -1169,7 +1365,7 @@ private:
             // decision process much easier.
             observeUseKindOnNode<StringUse>(edge.node());
             m_insertionSet.insertNode(
-                m_indexInBlock, SpecNone, Phantom, node->origin,
+                m_indexInBlock, SpecNone, Check, node->origin,
                 Edge(edge.node(), StringUse));
             edge.setUseKind(KnownStringUse);
             return;
@@ -1194,9 +1390,9 @@ private:
             if (!edge)
                 break;
             edge.setUseKind(KnownStringUse);
-            if (!m_graph.isConstant(edge.node()))
+            JSString* string = edge->dynamicCastConstant<JSString*>();
+            if (!string)
                 continue;
-            JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
             if (string->length())
                 continue;
             
@@ -1242,7 +1438,7 @@ private:
         }
     }
     
-    void fixupToString(Node* node)
+    void fixupToStringOrCallStringConstructor(Node* node)
     {
         if (node->child1()->shouldSpeculateString()) {
             fixEdge<StringUse>(node->child1());
@@ -1271,9 +1467,6 @@ private:
     template<UseKind leftUseKind>
     bool attemptToMakeFastStringAdd(Node* node, Edge& left, Edge& right)
     {
-        Node* originalLeft = left.node();
-        Node* originalRight = right.node();
-        
         ASSERT(leftUseKind == StringUse || leftUseKind == StringObjectUse || leftUseKind == StringOrStringObjectUse);
         
         if (isStringObjectUse<leftUseKind>() && !canOptimizeStringObjectAccess(node->origin.semantic))
@@ -1303,37 +1496,37 @@ private:
                 m_indexInBlock, SpecString, ToString, node->origin, Edge(toPrimitive));
             
             fixupToPrimitive(toPrimitive);
-            fixupToString(toString);
-            
+
+            // Don't fix up ToString. ToString and ToPrimitive are originated from the same bytecode and
+            // ToPrimitive may have an observable side effect. ToString should not be converted into Check
+            // with speculative type check because OSR exit reproduce an observable side effect done in
+            // ToPrimitive.
+
             right.setNode(toString);
         }
         
-        // We're doing checks up there, so we need to make sure that the
-        // *original* inputs to the addition are live up to here.
-        m_insertionSet.insertNode(
-            m_indexInBlock, SpecNone, Phantom, node->origin,
-            Edge(originalLeft), Edge(originalRight));
-        
         convertToMakeRope(node);
         return true;
     }
     
-    bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, StringImpl* uid)
+    bool isStringPrototypeMethodSane(
+        JSObject* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl* uid)
     {
         unsigned attributesUnused;
-        JSCell* specificValue;
-        PropertyOffset offset = stringPrototypeStructure->getConcurrently(
-            vm(), uid, attributesUnused, specificValue);
+        PropertyOffset offset =
+            stringPrototypeStructure->getConcurrently(uid, attributesUnused);
         if (!isValidOffset(offset))
             return false;
         
-        if (!specificValue)
+        JSValue value = m_graph.tryGetConstantProperty(
+            stringPrototype, stringPrototypeStructure, offset);
+        if (!value)
             return false;
         
-        if (!specificValue->inherits(JSFunction::info()))
+        JSFunction* function = jsDynamicCast<JSFunction*>(value);
+        if (!function)
             return false;
         
-        JSFunction* function = jsCast<JSFunction*>(specificValue);
         if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
             return false;
         
@@ -1351,7 +1544,7 @@ private:
         
         JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
         Structure* stringPrototypeStructure = stringPrototypeObject->structure();
-        if (!m_graph.watchpoints().isStillValid(stringPrototypeStructure->transitionWatchpointSet()))
+        if (m_graph.registerStructure(stringPrototypeStructure) != StructureRegisteredAndWatched)
             return false;
         
         if (stringPrototypeStructure->isDictionary())
@@ -1362,9 +1555,9 @@ private:
         // (that would call toString()). We don't want the DFG to have to distinguish
         // between the two, just because that seems like it would get confusing. So we
         // just require both methods to be sane.
-        if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
+        if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->valueOf.impl()))
             return false;
-        if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->toString.impl()))
+        if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, vm().propertyNames->toString.impl()))
             return false;
         
         return true;
@@ -1435,12 +1628,14 @@ private:
         
         if (arrayMode.type() == Array::String) {
             m_insertionSet.insertNode(
-                m_indexInBlock, SpecNone, Phantom, origin, Edge(array, StringUse));
+                m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
         } else {
+            // Note that we only need to be using a structure check if we opt for SaneChain, since
+            // that needs to protect against JSArray's __proto__ being changed.
             Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
         
             Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
-        
+            
             if (arrayMode.doesConversion()) {
                 if (structure) {
                     m_insertionSet.insertNode(
@@ -1546,6 +1741,7 @@ private:
                 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
             break;
         case NumberUse:
+        case RealNumberUse:
         case DoubleRepUse:
         case DoubleRepRealUse:
             if (variable->doubleFormatState() == UsingDoubleFormat)
@@ -1563,6 +1759,7 @@ private:
         case CellUse:
         case KnownCellUse:
         case ObjectUse:
+        case FunctionUse:
         case StringUse:
         case KnownStringUse:
         case StringObjectUse:
@@ -1583,10 +1780,44 @@ private:
         edge.setUseKind(useKind);
     }
     
-    void insertStoreBarrier(unsigned indexInBlock, Edge child1)
+    void speculateForBarrier(Edge value)
     {
-        Node* barrierNode = m_graph.addNode(SpecNone, StoreBarrier, m_currentNode->origin, child1);
-        m_insertionSet.insert(indexInBlock, barrierNode);
+        // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
+        // the DFG anyway because if such a speculation would be wrong, we want to know before
+        // we do an expensive compile.
+        
+        if (value->shouldSpeculateInt32()) {
+            insertCheck<Int32Use>(m_indexInBlock, value.node());
+            return;
+        }
+            
+        if (value->shouldSpeculateBoolean()) {
+            insertCheck<BooleanUse>(m_indexInBlock, value.node());
+            return;
+        }
+            
+        if (value->shouldSpeculateOther()) {
+            insertCheck<OtherUse>(m_indexInBlock, value.node());
+            return;
+        }
+            
+        if (value->shouldSpeculateNumber()) {
+            insertCheck<NumberUse>(m_indexInBlock, value.node());
+            return;
+        }
+            
+        if (value->shouldSpeculateNotCell()) {
+            insertCheck<NotCellUse>(m_indexInBlock, value.node());
+            return;
+        }
+    }
+    
+    template<UseKind useKind>
+    void insertCheck(unsigned indexInBlock, Node* node)
+    {
+        observeUseKindOnNode<useKind>(node);
+        m_insertionSet.insertNode(
+            indexInBlock, SpecNone, Check, m_currentNode->origin, Edge(node, useKind));
     }
 
     void fixIntConvertingEdge(Edge& edge)
@@ -1610,7 +1841,6 @@ private:
         observeUseKindOnNode(node, useKind);
         
         edge = Edge(newNode, KnownInt32Use);
-        addRequiredPhantom(node);
     }
     
     void fixIntOrBooleanEdge(Edge& edge)
@@ -1632,7 +1862,6 @@ private:
         observeUseKindOnNode(node, useKind);
         
         edge = Edge(newNode, Int32Use);
-        addRequiredPhantom(node);
     }
     
     void fixDoubleOrBooleanEdge(Edge& edge)
@@ -1654,34 +1883,21 @@ private:
         observeUseKindOnNode(node, useKind);
         
         edge = Edge(newNode, DoubleRepUse);
-        addRequiredPhantom(node);
     }
     
     void truncateConstantToInt32(Edge& edge)
     {
         Node* oldNode = edge.node();
         
-        ASSERT(oldNode->hasConstant());
-        JSValue value = m_graph.valueOfJSConstant(oldNode);
+        JSValue value = oldNode->asJSValue();
         if (value.isInt32())
             return;
         
         value = jsNumber(JSC::toInt32(value.asNumber()));
         ASSERT(value.isInt32());
-        unsigned constantRegister;
-        if (!codeBlock()->findConstant(value, constantRegister)) {
-            constantRegister = codeBlock()->addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_graph.m_plan.writeBarriers,
-                codeBlock()->constants()[constantRegister],
-                codeBlock(),
-                constantRegister,
-                codeBlock()->ownerExecutable(),
-                value);
-        }
         edge.setNode(m_insertionSet.insertNode(
             m_indexInBlock, SpecInt32, JSConstant, m_currentNode->origin,
-            OpInfo(constantRegister)));
+            OpInfo(m_graph.freeze(value))));
     }
     
     void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
@@ -1784,12 +2000,12 @@ private:
         
         Node* shiftAmount = m_insertionSet.insertNode(
             m_indexInBlock, SpecInt32, JSConstant, node->origin,
-            OpInfo(m_graph.constantRegisterForConstant(jsNumber(logElementSize(type)))));
+            OpInfo(m_graph.freeze(jsNumber(logElementSize(type)))));
         
         // We can use a BitLShift here because typed arrays will never have a byteLength
         // that overflows int32.
         node->setOp(BitLShift);
-        node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+        node->clearFlags(NodeMustGenerate);
         observeUseKindOnNode(length, Int32Use);
         observeUseKindOnNode(shiftAmount, Int32Use);
         node->child1() = Edge(length, Int32Use);
@@ -1800,7 +2016,7 @@ private:
     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
     {
         node->setOp(GetArrayLength);
-        node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+        node->clearFlags(NodeMustGenerate);
         fixEdge<KnownCellUse>(node->child1());
         node->setArrayMode(arrayMode);
             
@@ -1833,7 +2049,7 @@ private:
             0, neverNeedsStorage);
         
         node->setOp(GetTypedArrayByteOffset);
-        node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+        node->clearFlags(NodeMustGenerate);
         fixEdge<KnownCellUse>(node->child1());
         return true;
     }
@@ -1846,11 +2062,9 @@ private:
         m_block = block;
         for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
             m_currentNode = block->at(m_indexInBlock);
-            addPhantomsIfNecessary();
             tryToRelaxRepresentation(m_currentNode);
             DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, injectTypeConversionsForEdge);
         }
-        clearPhantomsAtEnd();
         m_insertionSet.execute(block);
     }
     
@@ -1864,9 +2078,7 @@ private:
         
         switch (node->op()) {
         case MovHint:
-        case Phantom:
         case Check:
-        case HardPhantom:
             DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, fixEdgeRepresentation);
             break;
             
@@ -1909,6 +2121,13 @@ private:
                 edge.setUseKind(Int52RepUse);
             break;
             
+        case RealNumberUse:
+            if (edge->hasDoubleResult())
+                edge.setUseKind(DoubleRepRealUse);
+            else if (edge->hasInt52Result())
+                edge.setUseKind(Int52RepUse);
+            break;
+            
         default:
             break;
         }
@@ -1926,21 +2145,26 @@ private:
             if (edge->hasDoubleResult())
                 break;
             
-            addRequiredPhantom(edge.node());
-
-            if (edge->op() == JSConstant && m_graph.isNumberConstant(edge.node())) {
+            if (edge->isNumberConstant()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecBytecodeDouble, DoubleConstant, node->origin,
-                    OpInfo(m_graph.constantRegisterForConstant(
-                        jsDoubleNumber(m_graph.valueOfNumberConstant(edge.node())))));
+                    OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
             } else if (edge->hasInt52Result()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecInt52AsDouble, DoubleRep, node->origin,
                     Edge(edge.node(), Int52RepUse));
             } else {
+                UseKind useKind;
+                if (edge->shouldSpeculateDoubleReal())
+                    useKind = RealNumberUse;
+                else if (edge->shouldSpeculateNumber())
+                    useKind = NumberUse;
+                else
+                    useKind = NotCellUse;
+
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecBytecodeDouble, DoubleRep, node->origin,
-                    Edge(edge.node(), NumberUse));
+                    Edge(edge.node(), useKind));
             }
 
             edge.setNode(result);
@@ -1951,12 +2175,10 @@ private:
             if (edge->hasInt52Result())
                 break;
             
-            addRequiredPhantom(edge.node());
-
-            if (edge->op() == JSConstant && m_graph.isMachineIntConstant(edge.node())) {
+            if (edge->isMachineIntConstant()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecMachineInt, Int52Constant, node->origin,
-                    OpInfo(edge->constantNumber()));
+                    OpInfo(edge->constant()));
             } else if (edge->hasDoubleResult()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecMachineInt, Int52Rep, node->origin,
@@ -1979,8 +2201,6 @@ private:
             if (!edge->hasDoubleResult() && !edge->hasInt52Result())
                 break;
             
-            addRequiredPhantom(edge.node());
-            
             if (edge->hasDoubleResult()) {
                 result = m_insertionSet.insertNode(
                     m_indexInBlock, SpecBytecodeDouble, ValueRep, node->origin,
@@ -1996,47 +2216,11 @@ private:
         } }
     }
     
-    void addRequiredPhantom(Node* node)
-    {
-        m_requiredPhantoms.append(node);
-    }
-
-    void addPhantomsIfNecessary()
-    {
-        if (m_requiredPhantoms.isEmpty())
-            return;
-        
-        for (unsigned i = m_requiredPhantoms.size(); i--;) {
-            Node* node = m_requiredPhantoms[i];
-            m_insertionSet.insertNode(
-                m_indexInBlock, SpecNone, Phantom, m_currentNode->origin,
-                node->defaultEdge());
-        }
-        
-        m_requiredPhantoms.resize(0);
-    }
-    
-    void clearPhantomsAtEnd()
-    {
-        // Terminal nodes don't need post-phantoms, and inserting them would violate
-        // the current requirement that a terminal is the last thing in a block. We
-        // should eventually change that requirement. Currently we get around this by
-        // ensuring that all terminals accept just one input, and if that input is a
-        // conversion node then no further speculations will be performed. See
-        // references to the bug, below, for places where we have to have hacks to
-        // work around this.
-        // FIXME: Get rid of this by allowing Phantoms after terminals.
-        // https://bugs.webkit.org/show_bug.cgi?id=126778
-        
-        m_requiredPhantoms.resize(0);
-    }
-    
     BasicBlock* m_block;
     unsigned m_indexInBlock;
     Node* m_currentNode;
     InsertionSet m_insertionSet;
     bool m_profitabilityChanged;
-    Vector<Node*, 3> m_requiredPhantoms;
 };
     
 bool performFixup(Graph& graph)
index 0bf55ba86ce9b69c4751a9a9b7a92ca4bd624832..fa483ac6c3e32ea8bbd5ab73aba105bfded1e57f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -58,9 +58,6 @@ void printInternal(PrintStream& out, FlushFormat format)
     case FlushedJSValue:
         out.print("FlushedJSValue");
         return;
-    case FlushedArguments:
-        out.print("FlushedArguments");
-        return;
     case ConflictingFlush:
         out.print("ConflictingFlush");
         return;
index 10e3c0090ae32944f5bd52f439e8254b53e481d3..480944ba6ee7a4abb02a8959cd5ce001ca22d6f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,7 +44,6 @@ enum FlushFormat {
     FlushedCell,
     FlushedBoolean,
     FlushedJSValue,
-    FlushedArguments,
     ConflictingFlush
 };
 
@@ -55,7 +54,6 @@ inline NodeFlags resultFor(FlushFormat format)
     case FlushedJSValue:
     case FlushedCell:
     case ConflictingFlush:
-    case FlushedArguments:
         return NodeResultJS;
     case FlushedInt32:
         return NodeResultInt32;
@@ -76,7 +74,6 @@ inline UseKind useKindFor(FlushFormat format)
     case DeadFlush:
     case FlushedJSValue:
     case ConflictingFlush:
-    case FlushedArguments:
         return UntypedUse;
     case FlushedCell:
         return CellUse;
@@ -93,6 +90,11 @@ inline UseKind useKindFor(FlushFormat format)
     return UntypedUse;
 }
 
+inline SpeculatedType typeFilterFor(FlushFormat format)
+{
+    return typeFilterFor(useKindFor(format));
+}
+
 inline DataFormat dataFormatFor(FlushFormat format)
 {
     switch (format) {
@@ -111,13 +113,27 @@ inline DataFormat dataFormatFor(FlushFormat format)
         return DataFormatCell;
     case FlushedBoolean:
         return DataFormatBoolean;
-    case FlushedArguments:
-        return DataFormatArguments;
     }
     RELEASE_ASSERT_NOT_REACHED();
     return DataFormatDead;
 }
 
+inline FlushFormat merge(FlushFormat a, FlushFormat b)
+{
+    if (a == DeadFlush)
+        return b;
+    if (b == DeadFlush)
+        return a;
+    if (a == b)
+        return a;
+    return ConflictingFlush;
+}
+
+inline bool isConcrete(FlushFormat format)
+{
+    return format != DeadFlush && format != ConflictingFlush;
+}
+
 } } // namespace JSC::DFG
 
 namespace WTF {
index 984a38d400858dfb60e1b004c6d508132c21259f..c15a2e6b03609bc3f5b3bc31e924c069c103f65e 100644 (file)
@@ -36,8 +36,10 @@ void FlushedAt::dump(PrintStream& out) const
 {
     if (m_format == DeadFlush || m_format == ConflictingFlush)
         out.print(m_format);
+    else if (m_virtualRegister.isValid())
+        out.print(m_virtualRegister, ":", m_format);
     else
-        out.print("r", m_virtualRegister, ":", m_format);
+        out.print(m_format);
 }
 
 void FlushedAt::dumpInContext(PrintStream& out, DumpContext*) const
index 3bc1cee64b63036777eaa1d9d10508b8bd163ba7..ea913dd51af118e0b25460530a8b68794d404350 100644 (file)
@@ -52,8 +52,6 @@ public:
     {
         if (format == DeadFlush)
             ASSERT(!virtualRegister.isValid());
-        else
-            ASSERT(virtualRegister.isValid());
     }
     
     bool operator!() const { return m_format == DeadFlush; }
diff --git a/dfg/DFGForAllKills.h b/dfg/DFGForAllKills.h
new file mode 100644 (file)
index 0000000..bb630cd
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGForAllKills_h
+#define DFGForAllKills_h
+
+#include "DFGCombinedLiveness.h"
+#include "DFGGraph.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "FullBytecodeLiveness.h"
+
+namespace JSC { namespace DFG {
+
+// Utilities for finding the last points where a node is live in DFG SSA. This accounts for liveness due
+// to OSR exit. This is usually used for enumerating over all of the program points where a node is live,
+// by exploring all blocks where the node is live at tail and then exploring all program points where the
+// node is killed. A prerequisite to using these utilities is having liveness and OSR availability
+// computed.
+
+// This tells you those things that die on the boundary between nodeBefore and nodeAfter. It is
+// conservative in the sense that it might resort to telling you some things that are still live at
+// nodeAfter.
+template<typename Functor>
+void forAllKilledOperands(Graph& graph, Node* nodeBefore, Node* nodeAfter, const Functor& functor)
+{
+    CodeOrigin before = nodeBefore->origin.forExit;
+
+    if (!nodeAfter) {
+        graph.forAllLiveInBytecode(before, functor);
+        return;
+    }
+    
+    CodeOrigin after = nodeAfter->origin.forExit;
+    
+    VirtualRegister alreadyNoted;
+    if (!!after) {
+        // If we MovHint something that is live at the time, then we kill the old value.
+        if (nodeAfter->containsMovHint()) {
+            VirtualRegister reg = nodeAfter->unlinkedLocal();
+            if (graph.isLiveInBytecode(reg, after)) {
+                functor(reg);
+                alreadyNoted = reg;
+            }
+        }
+    }
+    
+    if (!before) {
+        if (!after)
+            return;
+        // The true before-origin is the origin at predecessors that jump to us. But there can be
+        // many such predecessors and they will likely all have a different origin. So, it's better
+        // to do the conservative thing.
+        graph.forAllLocalsLiveInBytecode(after, functor);
+        return;
+    }
+    
+    if (before == after)
+        return;
+    
+    // before could be unset even if after is, but the opposite cannot happen.
+    ASSERT(!!after);
+    
+    // It's easier to do this if the inline call frames are the same. This is way faster than the
+    // other loop, below.
+    if (before.inlineCallFrame == after.inlineCallFrame) {
+        int stackOffset = before.inlineCallFrame ? before.inlineCallFrame->stackOffset : 0;
+        CodeBlock* codeBlock = graph.baselineCodeBlockFor(before.inlineCallFrame);
+        FullBytecodeLiveness& fullLiveness = graph.livenessFor(codeBlock);
+        const FastBitVector& liveBefore = fullLiveness.getLiveness(before.bytecodeIndex);
+        const FastBitVector& liveAfter = fullLiveness.getLiveness(after.bytecodeIndex);
+        
+        for (unsigned relativeLocal = codeBlock->m_numCalleeRegisters; relativeLocal--;) {
+            if (liveBefore.get(relativeLocal) && !liveAfter.get(relativeLocal))
+                functor(virtualRegisterForLocal(relativeLocal) + stackOffset);
+        }
+        
+        return;
+    }
+    
+    // Detect kills the super conservative way: it is killed if it was live before and dead after.
+    BitVector liveAfter = graph.localsLiveInBytecode(after);
+    graph.forAllLocalsLiveInBytecode(
+        before,
+        [&] (VirtualRegister reg) {
+            if (reg == alreadyNoted)
+                return;
+            if (liveAfter.get(reg.toLocal()))
+                return;
+            functor(reg);
+        });
+}
+    
+// Tells you all of the nodes that would no longer be live across the node at this nodeIndex.
+template<typename Functor>
+void forAllKilledNodesAtNodeIndex(
+    Graph& graph, AvailabilityMap& availabilityMap, BasicBlock* block, unsigned nodeIndex,
+    const Functor& functor)
+{
+    static const unsigned seenInClosureFlag = 1;
+    static const unsigned calledFunctorFlag = 2;
+    HashMap<Node*, unsigned> flags;
+    
+    Node* node = block->at(nodeIndex);
+    
+    graph.doToChildren(
+        node,
+        [&] (Edge edge) {
+            if (edge.doesKill()) {
+                auto& result = flags.add(edge.node(), 0).iterator->value;
+                if (!(result & calledFunctorFlag)) {
+                    functor(edge.node());
+                    result |= calledFunctorFlag;
+                }
+            }
+        });
+
+    Node* before = nullptr;
+    if (nodeIndex)
+        before = block->at(nodeIndex - 1);
+
+    forAllKilledOperands(
+        graph, before, node,
+        [&] (VirtualRegister reg) {
+            availabilityMap.closeStartingWithLocal(
+                reg,
+                [&] (Node* node) -> bool {
+                    return flags.get(node) & seenInClosureFlag;
+                },
+                [&] (Node* node) -> bool {
+                    auto& resultFlags = flags.add(node, 0).iterator->value;
+                    bool result = resultFlags & seenInClosureFlag;
+                    if (!(resultFlags & calledFunctorFlag))
+                        functor(node);
+                    resultFlags |= seenInClosureFlag | calledFunctorFlag;
+                    return result;
+                });
+        });
+}
+
+// Tells you all of the places to start searching from in a basic block. Gives you the node index at which
+// the value is either no longer live. This pretends that nodes are dead at the end of the block, so that
+// you can use this to do per-basic-block analyses.
+template<typename Functor>
+void forAllKillsInBlock(
+    Graph& graph, const CombinedLiveness& combinedLiveness, BasicBlock* block,
+    const Functor& functor)
+{
+    for (Node* node : combinedLiveness.liveAtTail[block])
+        functor(block->size(), node);
+    
+    LocalOSRAvailabilityCalculator localAvailability;
+    localAvailability.beginBlock(block);
+    // Start at the second node, because the functor is expected to only inspect nodes from the start of
+    // the block up to nodeIndex (exclusive), so if nodeIndex is zero then the functor has nothing to do.
+    for (unsigned nodeIndex = 1; nodeIndex < block->size(); ++nodeIndex) {
+        forAllKilledNodesAtNodeIndex(
+            graph, localAvailability.m_availability, block, nodeIndex,
+            [&] (Node* node) {
+                functor(nodeIndex, node);
+            });
+        localAvailability.executeNode(block->at(nodeIndex));
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // DFGForAllKills_h
+
diff --git a/dfg/DFGFrozenValue.cpp b/dfg/DFGFrozenValue.cpp
new file mode 100644 (file)
index 0000000..a62c38d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGFrozenValue.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+FrozenValue* FrozenValue::emptySingleton()
+{
+    static FrozenValue empty;
+    return &empty;
+}
+
+void FrozenValue::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    if (!!m_value && m_value.isCell())
+        out.print(m_strength, ":");
+    m_value.dumpInContextAssumingStructure(out, context, m_structure);
+}
+
+void FrozenValue::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGFrozenValue.h b/dfg/DFGFrozenValue.h
new file mode 100644 (file)
index 0000000..094356f
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGFrozenValue_h
+#define DFGFrozenValue_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGValueStrength.h"
+#include "JSCell.h"
+#include "JSCJSValue.h"
+#include "Structure.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class FrozenValue {
+public:
+    FrozenValue()
+        : m_structure(nullptr)
+        , m_strength(WeakValue)
+    {
+    }
+    
+    FrozenValue(JSValue value)
+        : m_value(value)
+        , m_structure(nullptr)
+        , m_strength(WeakValue)
+    {
+        RELEASE_ASSERT(!value || !value.isCell());
+    }
+    
+    FrozenValue(JSValue value, Structure* structure, ValueStrength strength)
+        : m_value(value)
+        , m_structure(structure)
+        , m_strength(strength)
+    {
+        ASSERT((!!value && value.isCell()) == !!structure);
+        ASSERT(!value || !value.isCell() || value.asCell()->classInfo() == structure->classInfo());
+        ASSERT(!!structure || (strength == WeakValue));
+    }
+    
+    static FrozenValue* emptySingleton();
+    
+    bool operator!() const { return !m_value; }
+    
+    JSValue value() const { return m_value; }
+    JSCell* cell() const { return m_value.asCell(); }
+    
+    template<typename T>
+    T dynamicCast()
+    {
+        return jsDynamicCast<T>(value());
+    }
+    template<typename T>
+    T cast()
+    {
+        return jsCast<T>(value());
+    }
+    
+    Structure* structure() const { return m_structure; }
+    
+    void strengthenTo(ValueStrength strength)
+    {
+        if (!!m_value && m_value.isCell())
+            m_strength = merge(m_strength, strength);
+    }
+    
+    bool pointsToHeap() const { return !!value() && value().isCell(); }
+    
+    // The strength of the value itself. The structure is almost always weak.
+    ValueStrength strength() const { return m_strength; }
+    
+    void dumpInContext(PrintStream& out, DumpContext* context) const;
+    void dump(PrintStream& out) const;
+    
+private:
+    friend class Graph;
+    
+    // This is a utility method for DFG::Graph::freeze(). You should almost always call
+    // Graph::freeze() directly. Calling this instead of Graph::freeze() can result in
+    // the same constant being viewed as having different structures during the course
+    // of compilation, which can sometimes cause bad things to happen. For example, we
+    // may observe that one version of the constant has an unwatchable structure but
+    // then a later version may start to have a watchable structure due to a transition.
+    // The point of freezing is to ensure that we generally only see one version of
+    // constants, but that requires freezing through the Graph.
+    static FrozenValue freeze(JSValue value)
+    {
+        return FrozenValue(
+            value,
+            (!!value && value.isCell()) ? value.asCell()->structure() : nullptr,
+            WeakValue);
+    }
+
+    JSValue m_value;
+    Structure* m_structure;
+    ValueStrength m_strength;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGFrozenValue_h
+
index f618499aec3482b2e0fcb35554127f00b4a3f2bf..57dc109d48dcfd2cff12339d6aa4aed160307f7e 100644 (file)
@@ -42,7 +42,7 @@ FunctionWhitelist& FunctionWhitelist::ensureGlobalWhitelist()
     static LazyNeverDestroyed<FunctionWhitelist> functionWhitelist;
     static std::once_flag initializeWhitelistFlag;
     std::call_once(initializeWhitelistFlag, [] {
-        const char* functionWhitelistFile = Options::dfgFunctionWhitelistFile();
+        const char* functionWhitelistFile = Options::dfgWhitelist();
         functionWhitelist.construct(functionWhitelistFile);
     });
     return functionWhitelist;
@@ -92,7 +92,7 @@ void FunctionWhitelist::parseFunctionNamesInFile(const char* filename)
 bool FunctionWhitelist::contains(CodeBlock* codeBlock) const 
 {
     ASSERT(!isCompilationThread());
-    if (!Options::dfgFunctionWhitelistFile())
+    if (!Options::dfgWhitelist())
         return true;
 
     if (m_entries.isEmpty())
@@ -106,10 +106,7 @@ bool FunctionWhitelist::contains(CodeBlock* codeBlock) const
     if (m_entries.contains(hash))
         return true;
 
-    String nameAndHash = name;
-    nameAndHash.append('#');
-    nameAndHash.append(hash);
-    return m_entries.contains(nameAndHash);
+    return m_entries.contains(name + '#' + hash);
 }
 
 } } // namespace JSC::DFG
index e3330fa3b4567675f48c4007f5852157a38e24ef..b30f3508d72dea7ae49e7b9a82a254b232d820ad 100644 (file)
@@ -38,9 +38,9 @@ namespace JSC { namespace DFG {
 
 // === GenerationInfo ===
 //
-// This class is used to track the current status of live values during code generation.
+// This class is used to track the current status of live values during code generation.
 // Can provide information as to whether a value is in machine registers, and if so which,
-// whether a value has been spilled to the RegsiterFile, and if so may be able to provide
+// whether a value has been spilled to the RegisterFile, and if so may be able to provide
 // details of the format in memory (all values are spilled in a boxed form, but we may be
 // able to track the type of box), and tracks how many outstanding uses of a value remain,
 // so that we know when the value is dead and the machine registers associated with it
@@ -153,8 +153,6 @@ public:
     
     void noticeOSRBirth(VariableEventStream& stream, Node* node, VirtualRegister virtualRegister)
     {
-        if (m_isConstant)
-            return;
         if (m_node != node)
             return;
         if (!alive())
@@ -164,7 +162,9 @@ public:
         
         m_bornForOSR = true;
         
-        if (m_registerFormat != DataFormatNone)
+        if (m_isConstant)
+            appendBirth(stream);
+        else if (m_registerFormat != DataFormatNone)
             appendFill(BirthToFill, stream);
         else if (m_spillFormat != DataFormatNone)
             appendSpill(BirthToSpill, stream, virtualRegister);
@@ -379,6 +379,11 @@ public:
     }
 
 private:
+    void appendBirth(VariableEventStream& stream)
+    {
+        stream.appendAndLog(VariableEvent::birth(MinifiedID(m_node)));
+    }
+    
     void appendFill(VariableEventKind kind, VariableEventStream& stream)
     {
         ASSERT(m_bornForOSR);
index 0156c8b361782e06fe1ddf3b1a197e5b4c5ceb0e..74aca3b9211746c7bd26667fb6d877d934e8a46f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
+#include "BytecodeKills.h"
 #include "BytecodeLivenessAnalysisInlines.h"
 #include "CodeBlock.h"
 #include "CodeBlockWithJITType.h"
+#include "DFGBlockWorklist.h"
 #include "DFGClobberSet.h"
 #include "DFGJITCode.h"
 #include "DFGVariableAccessDataDump.h"
 #include "FullBytecodeLiveness.h"
 #include "FunctionExecutableDump.h"
 #include "JIT.h"
-#include "JSActivation.h"
+#include "JSLexicalEnvironment.h"
 #include "MaxFrameExtentForSlowPathCall.h"
 #include "OperandsInlines.h"
 #include "JSCInlines.h"
@@ -60,23 +62,31 @@ Graph::Graph(VM& vm, Plan& plan, LongLivedState& longLivedState)
     , m_codeBlock(m_plan.codeBlock.get())
     , m_profiledBlock(m_codeBlock->alternative())
     , m_allocator(longLivedState.m_allocator)
-    , m_mustHandleAbstractValues(OperandsLike, plan.mustHandleValues)
-    , m_hasArguments(false)
     , m_nextMachineLocal(0)
-    , m_machineCaptureStart(std::numeric_limits<int>::max())
     , m_fixpointState(BeforeFixpoint)
+    , m_structureRegistrationState(HaveNotStartedRegistering)
     , m_form(LoadStore)
     , m_unificationState(LocallyUnified)
     , m_refCountState(EverythingIsLive)
 {
     ASSERT(m_profiledBlock);
     
-    for (unsigned i = m_mustHandleAbstractValues.size(); i--;)
-        m_mustHandleAbstractValues[i].setMostSpecific(*this, plan.mustHandleValues[i]);
+    m_hasDebuggerEnabled = m_profiledBlock->globalObject()->hasDebugger()
+        || Options::forceDebuggerBytecodeGeneration();
 }
 
 Graph::~Graph()
 {
+    for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
+        BasicBlock* block = this->block(blockIndex);
+        if (!block)
+            continue;
+
+        for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+            m_allocator.free(block->phis[phiIndex]);
+        for (unsigned nodeIndex = block->size(); nodeIndex--;)
+            m_allocator.free(block->at(nodeIndex));
+    }
     m_allocator.freeAll();
 }
 
@@ -146,7 +156,6 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
     NodeType op = node->op();
 
     unsigned refCount = node->refCount();
-    bool skipped = !refCount;
     bool mustGenerate = node->mustGenerate();
     if (mustGenerate)
         --refCount;
@@ -168,11 +177,10 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
     // (5) The arguments to the operation. The may be of the form:
     //         @#   - a NodeIndex referencing a prior node in the graph.
     //         arg# - an argument number.
-    //         $#   - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
     //         id#  - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
     //         var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
-    out.printf("% 4d:%s<%c%u:", (int)node->index(), skipped ? "  skipped  " : "           ", mustGenerate ? '!' : ' ', refCount);
-    if (node->hasResult() && !skipped && node->hasVirtualRegister())
+    out.printf("% 4d:<%c%u:", (int)node->index(), mustGenerate ? '!' : ' ', refCount);
+    if (node->hasResult() && node->hasVirtualRegister() && node->virtualRegister().isValid())
         out.print(node->virtualRegister());
     else
         out.print("-");
@@ -201,46 +209,48 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
         out.print(comma, node->arrayMode());
     if (node->hasArithMode())
         out.print(comma, node->arithMode());
-    if (node->hasVarNumber())
-        out.print(comma, node->varNumber());
+    if (node->hasScopeOffset())
+        out.print(comma, node->scopeOffset());
+    if (node->hasDirectArgumentsOffset())
+        out.print(comma, node->capturedArgumentsOffset());
     if (node->hasRegisterPointer())
-        out.print(comma, "global", globalObjectFor(node->origin.semantic)->findRegisterIndex(node->registerPointer()), "(", RawPointer(node->registerPointer()), ")");
+        out.print(comma, "global", globalObjectFor(node->origin.semantic)->findVariableIndex(node->variablePointer()), "(", RawPointer(node->variablePointer()), ")");
     if (node->hasIdentifier())
         out.print(comma, "id", node->identifierNumber(), "{", identifiers()[node->identifierNumber()], "}");
+    if (node->hasPromotedLocationDescriptor())
+        out.print(comma, node->promotedLocationDescriptor());
     if (node->hasStructureSet())
         out.print(comma, inContext(node->structureSet(), context));
     if (node->hasStructure())
         out.print(comma, inContext(*node->structure(), context));
-    if (node->hasStructureTransitionData())
-        out.print(comma, inContext(*node->structureTransitionData().previousStructure, context), " -> ", inContext(*node->structureTransitionData().newStructure, context));
-    if (node->hasFunction()) {
-        out.print(comma, "function(", RawPointer(node->function()), ", ");
-        if (node->function()->inherits(JSFunction::info())) {
-            JSFunction* function = jsCast<JSFunction*>(node->function());
-            if (function->isHostFunction())
-                out.print("<host function>");
-            else
-                out.print(FunctionExecutableDump(function->jsExecutable()));
-        } else
-            out.print("<not JSFunction>");
-        out.print(")");
-    }
-    if (node->hasExecutable()) {
-        if (node->executable()->inherits(FunctionExecutable::info()))
-            out.print(comma, "executable(", FunctionExecutableDump(jsCast<FunctionExecutable*>(node->executable())), ")");
-        else
-            out.print(comma, "executable(not function: ", RawPointer(node->executable()), ")");
+    if (node->hasTransition()) {
+        out.print(comma, pointerDumpInContext(node->transition(), context));
+#if USE(JSVALUE64)
+        out.print(", ID:", node->transition()->next->id());
+#else
+        out.print(", ID:", RawPointer(node->transition()->next));
+#endif
     }
-    if (node->hasFunctionDeclIndex()) {
-        FunctionExecutable* executable = m_codeBlock->functionDecl(node->functionDeclIndex());
-        out.print(comma, FunctionExecutableDump(executable));
-    }
-    if (node->hasFunctionExprIndex()) {
-        FunctionExecutable* executable = m_codeBlock->functionExpr(node->functionExprIndex());
-        out.print(comma, FunctionExecutableDump(executable));
+    if (node->hasCellOperand()) {
+        if (!node->cellOperand()->value() || !node->cellOperand()->value().isCell())
+            out.print(comma, "invalid cell operand: ", node->cellOperand()->value());
+        else {
+            out.print(comma, pointerDump(node->cellOperand()->value().asCell()));
+            if (node->cellOperand()->value().isCell()) {
+                CallVariant variant(node->cellOperand()->value().asCell());
+                if (ExecutableBase* executable = variant.executable()) {
+                    if (executable->isHostFunction())
+                        out.print(comma, "<host function>");
+                    else if (FunctionExecutable* functionExecutable = jsDynamicCast<FunctionExecutable*>(executable))
+                        out.print(comma, FunctionExecutableDump(functionExecutable));
+                    else
+                        out.print(comma, "<non-function executable>");
+                }
+            }
+        }
     }
     if (node->hasStorageAccessData()) {
-        StorageAccessData& storageAccessData = m_storageAccessData[node->storageAccessDataIndex()];
+        StorageAccessData& storageAccessData = node->storageAccessData();
         out.print(comma, "id", storageAccessData.identifierNumber, "{", identifiers()[storageAccessData.identifierNumber], "}");
         out.print(", ", static_cast<ptrdiff_t>(storageAccessData.offset));
     }
@@ -261,42 +271,32 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
         VariableAccessData* variableAccessData = node->tryGetVariableAccessData();
         if (variableAccessData) {
             VirtualRegister operand = variableAccessData->local();
-            if (operand.isArgument())
-                out.print(comma, "arg", operand.toArgument(), "(", VariableAccessDataDump(*this, variableAccessData), ")");
-            else
-                out.print(comma, "loc", operand.toLocal(), "(", VariableAccessDataDump(*this, variableAccessData), ")");
-            
+            out.print(comma, variableAccessData->local(), "(", VariableAccessDataDump(*this, variableAccessData), ")");
             operand = variableAccessData->machineLocal();
-            if (operand.isValid()) {
-                if (operand.isArgument())
-                    out.print(comma, "machine:arg", operand.toArgument());
-                else
-                    out.print(comma, "machine:loc", operand.toLocal());
-            }
+            if (operand.isValid())
+                out.print(comma, "machine:", operand);
         }
     }
-    if (node->hasUnlinkedLocal()) {
-        VirtualRegister operand = node->unlinkedLocal();
-        if (operand.isArgument())
-            out.print(comma, "arg", operand.toArgument());
-        else
-            out.print(comma, "loc", operand.toLocal());
+    if (node->hasStackAccessData()) {
+        StackAccessData* data = node->stackAccessData();
+        out.print(comma, data->local);
+        if (data->machineLocal.isValid())
+            out.print(comma, "machine:", data->machineLocal);
+        out.print(comma, data->format);
     }
+    if (node->hasUnlinkedLocal()) 
+        out.print(comma, node->unlinkedLocal());
     if (node->hasUnlinkedMachineLocal()) {
         VirtualRegister operand = node->unlinkedMachineLocal();
-        if (operand.isValid()) {
-            if (operand.isArgument())
-                out.print(comma, "machine:arg", operand.toArgument());
-            else
-                out.print(comma, "machine:loc", operand.toLocal());
-        }
+        if (operand.isValid())
+            out.print(comma, "machine:", operand);
     }
     if (node->hasConstantBuffer()) {
         out.print(comma);
         out.print(node->startConstant(), ":[");
         CommaPrinter anotherComma;
         for (unsigned i = 0; i < node->numConstants(); ++i)
-            out.print(anotherComma, inContext(m_codeBlock->constantBuffer(node->startConstant())[i], context));
+            out.print(anotherComma, pointerDumpInContext(freeze(m_codeBlock->constantBuffer(node->startConstant())[i]), context));
         out.print("]");
     }
     if (node->hasIndexingType())
@@ -307,19 +307,26 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
         out.print(comma, "^", node->phi()->index());
     if (node->hasExecutionCounter())
         out.print(comma, RawPointer(node->executionCounter()));
-    if (node->hasVariableWatchpointSet())
-        out.print(comma, RawPointer(node->variableWatchpointSet()));
-    if (node->hasTypedArray())
-        out.print(comma, inContext(JSValue(node->typedArray()), context));
+    if (node->hasWatchpointSet())
+        out.print(comma, RawPointer(node->watchpointSet()));
     if (node->hasStoragePointer())
         out.print(comma, RawPointer(node->storagePointer()));
-    if (node->isConstant()) {
-        out.print(comma, "$", node->constantNumber());
-        JSValue value = valueOfJSConstant(node);
-        out.print(" = ", inContext(value, context));
+    if (node->hasObjectMaterializationData())
+        out.print(comma, node->objectMaterializationData());
+    if (node->hasCallVarargsData())
+        out.print(comma, "firstVarArgOffset = ", node->callVarargsData()->firstVarArgOffset);
+    if (node->hasLoadVarargsData()) {
+        LoadVarargsData* data = node->loadVarargsData();
+        out.print(comma, "start = ", data->start, ", count = ", data->count);
+        if (data->machineStart.isValid())
+            out.print(", machineStart = ", data->machineStart);
+        if (data->machineCount.isValid())
+            out.print(", machineCount = ", data->machineCount);
+        out.print(", offset = ", data->offset, ", mandatoryMinimum = ", data->mandatoryMinimum);
+        out.print(", limit = ", data->limit);
     }
-    if (op == WeakJSConstant)
-        out.print(comma, RawPointer(node->weakConstant()), " (", inContext(*node->weakConstant()->structure(), context), ")");
+    if (node->isConstant())
+        out.print(comma, pointerDumpInContext(node->constant(), context));
     if (node->isJump())
         out.print(comma, "T:", *node->targetBlock());
     if (node->isBranch())
@@ -338,47 +345,58 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
         out.print(comma, "R:", sortedListDump(reads.direct(), ","));
     if (!writes.isEmpty())
         out.print(comma, "W:", sortedListDump(writes.direct(), ","));
-    out.print(comma, "bc#", node->origin.semantic.bytecodeIndex);
-    if (node->origin.semantic != node->origin.forExit)
-        out.print(comma, "exit: ", node->origin.forExit);
+    if (node->origin.isSet()) {
+        out.print(comma, "bc#", node->origin.semantic.bytecodeIndex);
+        if (node->origin.semantic != node->origin.forExit)
+            out.print(comma, "exit: ", node->origin.forExit);
+    }
     
     out.print(")");
 
-    if (!skipped) {
-        if (node->hasVariableAccessData(*this) && node->tryGetVariableAccessData())
-            out.print("  predicting ", SpeculationDump(node->tryGetVariableAccessData()->prediction()));
-        else if (node->hasHeapPrediction())
-            out.print("  predicting ", SpeculationDump(node->getHeapPrediction()));
-    }
+    if (node->hasVariableAccessData(*this) && node->tryGetVariableAccessData())
+        out.print("  predicting ", SpeculationDump(node->tryGetVariableAccessData()->prediction()));
+    else if (node->hasHeapPrediction())
+        out.print("  predicting ", SpeculationDump(node->getHeapPrediction()));
     
     out.print("\n");
 }
 
+bool Graph::terminalsAreValid()
+{
+    for (BasicBlock* block : blocksInNaturalOrder()) {
+        if (!block->terminal())
+            return false;
+    }
+    return true;
+}
+
 void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode, DumpContext* context)
 {
-    out.print(prefix, "Block ", *block, " (", inContext(block->at(0)->origin.semantic, context), "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
+    out.print(prefix, "Block ", *block, " (", inContext(block->at(0)->origin.semantic, context), "):", block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
     if (block->executionCount == block->executionCount)
         out.print(prefix, "  Execution count: ", block->executionCount, "\n");
     out.print(prefix, "  Predecessors:");
     for (size_t i = 0; i < block->predecessors.size(); ++i)
         out.print(" ", *block->predecessors[i]);
     out.print("\n");
-    if (m_dominators.isValid()) {
-        out.print(prefix, "  Dominated by:");
-        for (size_t i = 0; i < m_blocks.size(); ++i) {
-            if (!m_dominators.dominates(i, block->index))
-                continue;
-            out.print(" #", i);
+    out.print(prefix, "  Successors:");
+    if (block->terminal()) {
+        for (BasicBlock* successor : block->successors()) {
+            out.print(" ", *successor);
+            if (m_prePostNumbering.isValid())
+                out.print(" (", m_prePostNumbering.edgeKind(block, successor), ")");
         }
-        out.print("\n");
-        out.print(prefix, "  Dominates:");
-        for (size_t i = 0; i < m_blocks.size(); ++i) {
-            if (!m_dominators.dominates(block->index, i))
-                continue;
-            out.print(" #", i);
-        }
-        out.print("\n");
+    } else
+        out.print(" <invalid>");
+    out.print("\n");
+    if (m_dominators.isValid() && terminalsAreValid()) {
+        out.print(prefix, "  Dominated by: ", m_dominators.dominatorsOf(block), "\n");
+        out.print(prefix, "  Dominates: ", m_dominators.blocksDominatedBy(block), "\n");
+        out.print(prefix, "  Dominance Frontier: ", m_dominators.dominanceFrontierOf(block), "\n");
+        out.print(prefix, "  Iterated Dominance Frontier: ", m_dominators.iteratedDominanceFrontierOf(BlockList(1, block)), "\n");
     }
+    if (m_prePostNumbering.isValid())
+        out.print(prefix, "  Pre/Post Numbering: ", m_prePostNumbering.preNumber(block), "/", m_prePostNumbering.postNumber(block), "\n");
     if (m_naturalLoops.isValid()) {
         if (const NaturalLoop* loop = m_naturalLoops.headerOf(block)) {
             out.print(prefix, "  Loop header, contains:");
@@ -406,7 +424,7 @@ void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* bl
             Node* phiNode = block->phis[i];
             if (!phiNode->shouldGenerate() && phiNodeDumpMode == DumpLivePhisOnly)
                 continue;
-            out.print(" @", phiNode->index(), "<", phiNode->refCount(), ">->(");
+            out.print(" @", phiNode->index(), "<", phiNode->local(), ",", phiNode->refCount(), ">->(");
             if (phiNode->child1()) {
                 out.print("@", phiNode->child1()->index());
                 if (phiNode->child2()) {
@@ -428,10 +446,14 @@ void Graph::dump(PrintStream& out, DumpContext* context)
     if (!context)
         context = &myContext;
     
-    dataLog("\n");
-    dataLog("DFG for ", CodeBlockWithJITType(m_codeBlock, JITCode::DFGJIT), ":\n");
-    dataLog("  Fixpoint state: ", m_fixpointState, "; Form: ", m_form, "; Unification state: ", m_unificationState, "; Ref count state: ", m_refCountState, "\n");
-    dataLog("\n");
+    out.print("\n");
+    out.print("DFG for ", CodeBlockWithJITType(m_codeBlock, JITCode::DFGJIT), ":\n");
+    out.print("  Fixpoint state: ", m_fixpointState, "; Form: ", m_form, "; Unification state: ", m_unificationState, "; Ref count state: ", m_refCountState, "\n");
+    if (m_form == SSA)
+        out.print("  Argument formats: ", listDump(m_argumentFormats), "\n");
+    else
+        out.print("  Arguments: ", listDump(m_arguments), "\n");
+    out.print("\n");
     
     Node* lastNode = 0;
     for (size_t b = 0; b < m_blocks.size(); ++b) {
@@ -439,16 +461,28 @@ void Graph::dump(PrintStream& out, DumpContext* context)
         if (!block)
             continue;
         dumpBlockHeader(out, "", block, DumpAllPhis, context);
+        out.print("  States: ", block->cfaStructureClobberStateAtHead);
+        if (!block->cfaHasVisited)
+            out.print(", CurrentlyCFAUnreachable");
+        if (!block->intersectionOfCFAHasVisited)
+            out.print(", CFAUnreachable");
+        out.print("\n");
         switch (m_form) {
         case LoadStore:
         case ThreadedCPS: {
-            out.print("  vars before: ");
+            out.print("  Vars Before: ");
             if (block->cfaHasVisited)
                 out.print(inContext(block->valuesAtHead, context));
             else
                 out.print("<empty>");
             out.print("\n");
-            out.print("  var links: ", block->variablesAtHead, "\n");
+            out.print("  Intersected Vars Before: ");
+            if (block->intersectionOfCFAHasVisited)
+                out.print(inContext(block->intersectionOfPastValuesAtHead, context));
+            else
+                out.print("<empty>");
+            out.print("\n");
+            out.print("  Var Links: ", block->variablesAtHead, "\n");
             break;
         }
             
@@ -464,16 +498,20 @@ void Graph::dump(PrintStream& out, DumpContext* context)
             dump(out, "", block->at(i), context);
             lastNode = block->at(i);
         }
+        out.print("  States: ", block->cfaBranchDirection, ", ", block->cfaStructureClobberStateAtTail);
+        if (!block->cfaDidFinish)
+            out.print(", CFAInvalidated");
+        out.print("\n");
         switch (m_form) {
         case LoadStore:
         case ThreadedCPS: {
-            out.print("  vars after: ");
+            out.print("  Vars After: ");
             if (block->cfaHasVisited)
                 out.print(inContext(block->valuesAtTail, context));
             else
                 out.print("<empty>");
             out.print("\n");
-            out.print("  var links: ", block->variablesAtTail, "\n");
+            out.print("  Var Links: ", block->variablesAtTail, "\n");
             break;
         }
             
@@ -484,12 +522,18 @@ void Graph::dump(PrintStream& out, DumpContext* context)
             out.print("  Values: ", nodeMapDump(block->ssa->valuesAtTail, context), "\n");
             break;
         } }
-        dataLog("\n");
+        out.print("\n");
+    }
+    
+    out.print("GC Values:\n");
+    for (FrozenValue* value : m_frozenValues) {
+        if (value->pointsToHeap())
+            out.print("    ", inContext(*value, &myContext), "\n");
     }
     
     if (!myContext.isEmpty()) {
-        myContext.dump(WTF::dataFile());
-        dataLog("\n");
+        myContext.dump(out);
+        out.print("\n");
     }
 }
 
@@ -551,6 +595,113 @@ void Graph::resetReachability()
     determineReachability();
 }
 
+namespace {
+
+class RefCountCalculator {
+public:
+    RefCountCalculator(Graph& graph)
+        : m_graph(graph)
+    {
+    }
+    
+    void calculate()
+    {
+        // First reset the counts to 0 for all nodes.
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            for (unsigned indexInBlock = block->size(); indexInBlock--;)
+                block->at(indexInBlock)->setRefCount(0);
+            for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+                block->phis[phiIndex]->setRefCount(0);
+        }
+    
+        // Now find the roots:
+        // - Nodes that are must-generate.
+        // - Nodes that are reachable from type checks.
+        // Set their ref counts to 1 and put them on the worklist.
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            for (unsigned indexInBlock = block->size(); indexInBlock--;) {
+                Node* node = block->at(indexInBlock);
+                DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
+                if (!(node->flags() & NodeMustGenerate))
+                    continue;
+                if (!node->postfixRef())
+                    m_worklist.append(node);
+            }
+        }
+        
+        while (!m_worklist.isEmpty()) {
+            while (!m_worklist.isEmpty()) {
+                Node* node = m_worklist.last();
+                m_worklist.removeLast();
+                ASSERT(node->shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
+                DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
+            }
+            
+            if (m_graph.m_form == SSA) {
+                // Find Phi->Upsilon edges, which are represented as meta-data in the
+                // Upsilon.
+                for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                    BasicBlock* block = m_graph.block(blockIndex);
+                    if (!block)
+                        continue;
+                    for (unsigned nodeIndex = block->size(); nodeIndex--;) {
+                        Node* node = block->at(nodeIndex);
+                        if (node->op() != Upsilon)
+                            continue;
+                        if (node->shouldGenerate())
+                            continue;
+                        if (node->phi()->shouldGenerate())
+                            countNode(node);
+                    }
+                }
+            }
+        }
+    }
+    
+private:
+    void findTypeCheckRoot(Node*, Edge edge)
+    {
+        // We may have an "unproved" untyped use for code that is unreachable. The CFA
+        // will just not have gotten around to it.
+        if (edge.isProved() || edge.willNotHaveCheck())
+            return;
+        if (!edge->postfixRef())
+            m_worklist.append(edge.node());
+    }
+    
+    void countNode(Node* node)
+    {
+        if (node->postfixRef())
+            return;
+        m_worklist.append(node);
+    }
+    
+    void countEdge(Node*, Edge edge)
+    {
+        // Don't count edges that are already counted for their type checks.
+        if (!(edge.isProved() || edge.willNotHaveCheck()))
+            return;
+        countNode(edge.node());
+    }
+    
+    Graph& m_graph;
+    Vector<Node*, 128> m_worklist;
+};
+
+} // anonymous namespace
+
+void Graph::computeRefCounts()
+{
+    RefCountCalculator calculator(*this);
+    calculator.calculate();
+}
+
 void Graph::killBlockAndItsContents(BasicBlock* block)
 {
     for (unsigned phiIndex = block->phis.size(); phiIndex--;)
@@ -574,29 +725,15 @@ void Graph::killUnreachableBlocks()
     }
 }
 
-void Graph::resetExitStates()
-{
-    for (BlockIndex blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_blocks[blockIndex].get();
-        if (!block)
-            continue;
-        for (unsigned indexInBlock = block->size(); indexInBlock--;)
-            block->at(indexInBlock)->setCanExit(true);
-    }
-}
-
 void Graph::invalidateCFG()
 {
     m_dominators.invalidate();
     m_naturalLoops.invalidate();
+    m_prePostNumbering.invalidate();
 }
 
 void Graph::substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal)
 {
-    if (variableAccessData->isCaptured()) {
-        // Let CSE worry about this one.
-        return;
-    }
     for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
         Node* node = block[indexInBlock];
         bool shouldContinue = true;
@@ -626,26 +763,37 @@ void Graph::substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, Va
     }
 }
 
-void Graph::addForDepthFirstSort(Vector<BasicBlock*>& result, Vector<BasicBlock*, 16>& worklist, HashSet<BasicBlock*>& seen, BasicBlock* block)
+BlockList Graph::blocksInPreOrder()
 {
-    if (seen.contains(block))
-        return;
-    
-    result.append(block);
-    worklist.append(block);
-    seen.add(block);
+    BlockList result;
+    BlockWorklist worklist;
+    worklist.push(block(0));
+    while (BasicBlock* block = worklist.pop()) {
+        result.append(block);
+        for (unsigned i = block->numSuccessors(); i--;)
+            worklist.push(block->successor(i));
+    }
+    return result;
 }
 
-void Graph::getBlocksInDepthFirstOrder(Vector<BasicBlock*>& result)
+BlockList Graph::blocksInPostOrder()
 {
-    Vector<BasicBlock*, 16> worklist;
-    HashSet<BasicBlock*> seen;
-    addForDepthFirstSort(result, worklist, seen, block(0));
-    while (!worklist.isEmpty()) {
-        BasicBlock* block = worklist.takeLast();
-        for (unsigned i = block->numSuccessors(); i--;)
-            addForDepthFirstSort(result, worklist, seen, block->successor(i));
+    BlockList result;
+    PostOrderBlockWorklist worklist;
+    worklist.push(block(0));
+    while (BlockWithOrder item = worklist.pop()) {
+        switch (item.order) {
+        case PreOrder:
+            worklist.pushPost(item.block);
+            for (unsigned i = item.block->numSuccessors(); i--;)
+                worklist.push(item.block->successor(i));
+            break;
+        case PostOrder:
+            result.append(item.block);
+            break;
+        }
     }
+    return result;
 }
 
 void Graph::clearReplacements()
@@ -655,9 +803,22 @@ void Graph::clearReplacements()
         if (!block)
             continue;
         for (unsigned phiIndex = block->phis.size(); phiIndex--;)
-            block->phis[phiIndex]->misc.replacement = 0;
+            block->phis[phiIndex]->setReplacement(nullptr);
         for (unsigned nodeIndex = block->size(); nodeIndex--;)
-            block->at(nodeIndex)->misc.replacement = 0;
+            block->at(nodeIndex)->setReplacement(nullptr);
+    }
+}
+
+void Graph::clearEpochs()
+{
+    for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
+        BasicBlock* block = m_blocks[blockIndex].get();
+        if (!block)
+            continue;
+        for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+            block->phis[phiIndex]->setEpoch(Epoch());
+        for (unsigned nodeIndex = block->size(); nodeIndex--;)
+            block->at(nodeIndex)->setEpoch(Epoch());
     }
 }
 
@@ -668,9 +829,9 @@ void Graph::initializeNodeOwners()
         if (!block)
             continue;
         for (unsigned phiIndex = block->phis.size(); phiIndex--;)
-            block->phis[phiIndex]->misc.owner = block;
+            block->phis[phiIndex]->owner = block;
         for (unsigned nodeIndex = block->size(); nodeIndex--;)
-            block->at(nodeIndex)->misc.owner = block;
+            block->at(nodeIndex)->owner = block;
     }
 }
 
@@ -705,6 +866,24 @@ FullBytecodeLiveness& Graph::livenessFor(InlineCallFrame* inlineCallFrame)
     return livenessFor(baselineCodeBlockFor(inlineCallFrame));
 }
 
+BytecodeKills& Graph::killsFor(CodeBlock* codeBlock)
+{
+    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>>::iterator iter = m_bytecodeKills.find(codeBlock);
+    if (iter != m_bytecodeKills.end())
+        return *iter->value;
+    
+    std::unique_ptr<BytecodeKills> kills = std::make_unique<BytecodeKills>();
+    codeBlock->livenessAnalysis().computeKills(*kills);
+    BytecodeKills& result = *kills;
+    m_bytecodeKills.add(codeBlock, WTF::move(kills));
+    return result;
+}
+
+BytecodeKills& Graph::killsFor(InlineCallFrame* inlineCallFrame)
+{
+    return killsFor(baselineCodeBlockFor(inlineCallFrame));
+}
+
 bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
 {
     for (;;) {
@@ -715,12 +894,12 @@ bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
             if (reg.isArgument()) {
                 RELEASE_ASSERT(reg.offset() < JSStack::CallFrameHeaderSize);
                 
-                if (!codeOrigin.inlineCallFrame->isClosureCall)
-                    return false;
-                
-                if (reg.offset() == JSStack::Callee)
+                if (codeOrigin.inlineCallFrame->isClosureCall
+                    && reg.offset() == JSStack::Callee)
                     return true;
-                if (reg.offset() == JSStack::ScopeChain)
+                
+                if (codeOrigin.inlineCallFrame->isVarargs()
+                    && reg.offset() == JSStack::ArgumentCount)
                     return true;
                 
                 return false;
@@ -736,8 +915,6 @@ bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
 
         // Arguments are always live. This would be redundant if it wasn't for our
         // op_call_varargs inlining.
-        // FIXME: 'this' might not be live, but we don't have a way of knowing.
-        // https://bugs.webkit.org/show_bug.cgi?id=128519
         if (reg.isArgument()
             && static_cast<size_t>(reg.toArgument()) < inlineCallFrame->arguments.size())
             return true;
@@ -748,6 +925,19 @@ bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
     return true;
 }
 
+BitVector Graph::localsLiveInBytecode(CodeOrigin codeOrigin)
+{
+    BitVector result;
+    result.ensureSize(block(0)->variablesAtHead.numberOfLocals());
+    forAllLocalsLiveInBytecode(
+        codeOrigin,
+        [&] (VirtualRegister reg) {
+            ASSERT(reg.isLocal());
+            result.quickSet(reg.toLocal());
+        });
+    return result;
+}
+
 unsigned Graph::frameRegisterCount()
 {
     unsigned result = m_nextMachineLocal + std::max(m_parameterSlots, static_cast<unsigned>(maxFrameExtentForSlowPathCallInRegisters));
@@ -776,49 +966,182 @@ unsigned Graph::requiredRegisterCountForExecutionAndExit()
     return std::max(frameRegisterCount(), requiredRegisterCountForExit());
 }
 
-JSActivation* Graph::tryGetActivation(Node* node)
+JSValue Graph::tryGetConstantProperty(
+    JSValue base, const StructureSet& structureSet, PropertyOffset offset)
 {
-    if (!node->hasConstant())
-        return 0;
-    return jsDynamicCast<JSActivation*>(valueOfJSConstant(node));
+    if (!base || !base.isObject())
+        return JSValue();
+    
+    JSObject* object = asObject(base);
+    
+    for (unsigned i = structureSet.size(); i--;) {
+        Structure* structure = structureSet[i];
+        WatchpointSet* set = structure->propertyReplacementWatchpointSet(offset);
+        if (!set || !set->isStillValid())
+            return JSValue();
+        
+        ASSERT(structure->isValidOffset(offset));
+        ASSERT(!structure->isUncacheableDictionary());
+        
+        watchpoints().addLazily(set);
+    }
+    
+    // What follows may require some extra thought. We need this load to load a valid JSValue. If
+    // our profiling makes sense and we're still on track to generate code that won't be
+    // invalidated, then we have nothing to worry about. We do, however, have to worry about
+    // loading - and then using - an invalid JSValue in the case that unbeknownst to us our code
+    // is doomed.
+    //
+    // One argument in favor of this code is that it should definitely work because the butterfly
+    // is always set before the structure. However, we don't currently have a fence between those
+    // stores. It's not clear if this matters, however. We don't ever shrink the property storage.
+    // So, for this to fail, you'd need an access on a constant object pointer such that the inline
+    // caches told us that the object had a structure that it did not *yet* have, and then later,
+    // the object transitioned to that structure that the inline caches had alraedy seen. And then
+    // the processor reordered the stores. Seems unlikely and difficult to test. I believe that
+    // this is worth revisiting but it isn't worth losing sleep over. Filed:
+    // https://bugs.webkit.org/show_bug.cgi?id=134641
+    //
+    // For now, we just do the minimal thing: defend against the structure right now being
+    // incompatible with the getDirect we're trying to do. The easiest way to do that is to
+    // determine if the structure belongs to the proven set.
+    
+    if (!structureSet.contains(object->structure()))
+        return JSValue();
+    
+    return object->getDirect(offset);
+}
+
+JSValue Graph::tryGetConstantProperty(JSValue base, Structure* structure, PropertyOffset offset)
+{
+    return tryGetConstantProperty(base, StructureSet(structure), offset);
 }
 
-WriteBarrierBase<Unknown>* Graph::tryGetRegisters(Node* node)
+JSValue Graph::tryGetConstantProperty(
+    JSValue base, const StructureAbstractValue& structure, PropertyOffset offset)
 {
-    JSActivation* activation = tryGetActivation(node);
+    if (structure.isTop() || structure.isClobbered())
+        return JSValue();
+    
+    return tryGetConstantProperty(base, structure.set(), offset);
+}
+
+JSValue Graph::tryGetConstantProperty(const AbstractValue& base, PropertyOffset offset)
+{
+    return tryGetConstantProperty(base.m_value, base.m_structure, offset);
+}
+
+JSValue Graph::tryGetConstantClosureVar(JSValue base, ScopeOffset offset)
+{
+    // This has an awesome concurrency story. See comment for GetGlobalVar in ByteCodeParser.
+    
+    if (!base)
+        return JSValue();
+    
+    JSLexicalEnvironment* activation = jsDynamicCast<JSLexicalEnvironment*>(base);
     if (!activation)
-        return 0;
-    if (!activation->isTornOff())
-        return 0;
-    return activation->registers();
+        return JSValue();
+    
+    SymbolTable* symbolTable = activation->symbolTable();
+    JSValue value;
+    WatchpointSet* set;
+    {
+        ConcurrentJITLocker locker(symbolTable->m_lock);
+        
+        SymbolTableEntry* entry = symbolTable->entryFor(locker, offset);
+        if (!entry)
+            return JSValue();
+        
+        set = entry->watchpointSet();
+        if (!set)
+            return JSValue();
+        
+        if (set->state() != IsWatched)
+            return JSValue();
+        
+        ASSERT(entry->scopeOffset() == offset);
+        value = activation->variableAt(offset).get();
+        if (!value)
+            return JSValue();
+    }
+    
+    watchpoints().addLazily(set);
+    
+    return value;
 }
 
-JSArrayBufferView* Graph::tryGetFoldableView(Node* node)
+JSValue Graph::tryGetConstantClosureVar(const AbstractValue& value, ScopeOffset offset)
+{
+    return tryGetConstantClosureVar(value.m_value, offset);
+}
+
+JSValue Graph::tryGetConstantClosureVar(Node* node, ScopeOffset offset)
 {
     if (!node->hasConstant())
-        return 0;
-    JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(valueOfJSConstant(node));
-    if (!view)
-        return 0;
-    if (!watchpoints().isStillValid(view))
-        return 0;
+        return JSValue();
+    return tryGetConstantClosureVar(node->asJSValue(), offset);
+}
+
+JSArrayBufferView* Graph::tryGetFoldableView(JSValue value)
+{
+    if (!value)
+        return nullptr;
+    JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(value);
+    if (!value)
+        return nullptr;
+    if (!view->length())
+        return nullptr;
+    WTF::loadLoadFence();
+    watchpoints().addLazily(view);
     return view;
 }
 
-JSArrayBufferView* Graph::tryGetFoldableView(Node* node, ArrayMode arrayMode)
+JSArrayBufferView* Graph::tryGetFoldableView(JSValue value, ArrayMode arrayMode)
 {
     if (arrayMode.typedArrayType() == NotTypedArray)
-        return 0;
-    return tryGetFoldableView(node);
+        return nullptr;
+    return tryGetFoldableView(value);
 }
 
-JSArrayBufferView* Graph::tryGetFoldableViewForChild1(Node* node)
+void Graph::registerFrozenValues()
 {
-    return tryGetFoldableView(child(node, 0).node(), node->arrayMode());
+    m_codeBlock->constants().resize(0);
+    m_codeBlock->constantsSourceCodeRepresentation().resize(0);
+    for (FrozenValue* value : m_frozenValues) {
+        if (!value->pointsToHeap())
+            continue;
+        
+        ASSERT(value->structure());
+        ASSERT(m_plan.weakReferences.contains(value->structure()));
+        
+        switch (value->strength()) {
+        case WeakValue: {
+            m_plan.weakReferences.addLazily(value->value().asCell());
+            break;
+        }
+        case StrongValue: {
+            unsigned constantIndex = m_codeBlock->addConstantLazily();
+            initializeLazyWriteBarrierForConstant(
+                m_plan.writeBarriers,
+                m_codeBlock->constants()[constantIndex],
+                m_codeBlock,
+                constantIndex,
+                m_codeBlock->ownerExecutable(),
+                value->value());
+            break;
+        } }
+    }
+    m_codeBlock->constants().shrinkToFit();
+    m_codeBlock->constantsSourceCodeRepresentation().shrinkToFit();
 }
 
 void Graph::visitChildren(SlotVisitor& visitor)
 {
+    for (FrozenValue* value : m_frozenValues) {
+        visitor.appendUnbarrieredReadOnlyValue(value->value());
+        visitor.appendUnbarrieredReadOnlyPointer(value->structure());
+    }
+    
     for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
         BasicBlock* block = this->block(blockIndex);
         if (!block)
@@ -828,25 +1151,11 @@ void Graph::visitChildren(SlotVisitor& visitor)
             Node* node = block->at(nodeIndex);
             
             switch (node->op()) {
-            case JSConstant:
-            case WeakJSConstant:
-                visitor.appendUnbarrieredReadOnlyValue(valueOfJSConstant(node));
-                break;
-                
-            case CheckFunction:
-                visitor.appendUnbarrieredReadOnlyPointer(node->function());
-                break;
-                
-            case CheckExecutable:
-                visitor.appendUnbarrieredReadOnlyPointer(node->executable());
-                break;
-                
             case CheckStructure:
                 for (unsigned i = node->structureSet().size(); i--;)
                     visitor.appendUnbarrieredReadOnlyPointer(node->structureSet()[i]);
                 break;
                 
-            case StructureTransitionWatchpoint:
             case NewObject:
             case ArrayifyToStructure:
             case NewStringObject:
@@ -854,13 +1163,38 @@ void Graph::visitChildren(SlotVisitor& visitor)
                 break;
                 
             case PutStructure:
-            case PhantomPutStructure:
             case AllocatePropertyStorage:
             case ReallocatePropertyStorage:
                 visitor.appendUnbarrieredReadOnlyPointer(
-                    node->structureTransitionData().previousStructure);
+                    node->transition()->previous);
                 visitor.appendUnbarrieredReadOnlyPointer(
-                    node->structureTransitionData().newStructure);
+                    node->transition()->next);
+                break;
+                
+            case MultiGetByOffset:
+                for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
+                    GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
+                    const StructureSet& set = variant.structureSet();
+                    for (unsigned j = set.size(); j--;)
+                        visitor.appendUnbarrieredReadOnlyPointer(set[j]);
+
+                    // Don't need to mark anything in the structure chain because that would
+                    // have been decomposed into CheckStructure's. Don't need to mark the
+                    // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
+                    // variants did that.
+                    ASSERT(!variant.callLinkStatus());
+                }
+                break;
+                    
+            case MultiPutByOffset:
+                for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
+                    PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
+                    const StructureSet& set = variant.oldStructure();
+                    for (unsigned j = set.size(); j--;)
+                        visitor.appendUnbarrieredReadOnlyPointer(set[j]);
+                    if (variant.kind() == PutByIdVariant::Transition)
+                        visitor.appendUnbarrieredReadOnlyPointer(variant.newStructure());
+                }
                 break;
                 
             default:
@@ -870,6 +1204,156 @@ void Graph::visitChildren(SlotVisitor& visitor)
     }
 }
 
+FrozenValue* Graph::freeze(JSValue value)
+{
+    if (UNLIKELY(!value))
+        return FrozenValue::emptySingleton();
+    
+    auto result = m_frozenValueMap.add(JSValue::encode(value), nullptr);
+    if (LIKELY(!result.isNewEntry))
+        return result.iterator->value;
+
+    if (value.isUInt32())
+        m_uint32ValuesInUse.append(value.asUInt32());
+    
+    FrozenValue frozenValue = FrozenValue::freeze(value);
+    if (Structure* structure = frozenValue.structure())
+        registerStructure(structure);
+    
+    return result.iterator->value = m_frozenValues.add(frozenValue);
+}
+
+FrozenValue* Graph::freezeStrong(JSValue value)
+{
+    FrozenValue* result = freeze(value);
+    result->strengthenTo(StrongValue);
+    return result;
+}
+
+void Graph::convertToConstant(Node* node, FrozenValue* value)
+{
+    if (value->structure())
+        assertIsRegistered(value->structure());
+    node->convertToConstant(value);
+}
+
+void Graph::convertToConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freeze(value));
+}
+
+void Graph::convertToStrongConstant(Node* node, JSValue value)
+{
+    convertToConstant(node, freezeStrong(value));
+}
+
+StructureRegistrationResult Graph::registerStructure(Structure* structure)
+{
+    m_plan.weakReferences.addLazily(structure);
+    if (m_plan.watchpoints.consider(structure))
+        return StructureRegisteredAndWatched;
+    return StructureRegisteredNormally;
+}
+
+void Graph::assertIsRegistered(Structure* structure)
+{
+    // It's convenient to be able to call this with a maybe-null structure.
+    if (!structure)
+        return;
+    
+    if (m_structureRegistrationState == HaveNotStartedRegistering)
+        return;
+    
+    DFG_ASSERT(*this, nullptr, m_plan.weakReferences.contains(structure));
+    
+    if (!structure->dfgShouldWatch())
+        return;
+    if (watchpoints().isWatched(structure->transitionWatchpointSet()))
+        return;
+    
+    DFG_CRASH(*this, nullptr, toCString("Structure ", pointerDump(structure), " is watchable but isn't being watched.").data());
+}
+
+NO_RETURN_DUE_TO_CRASH static void crash(
+    Graph& graph, const CString& whileText, const char* file, int line, const char* function,
+    const char* assertion)
+{
+    startCrashing();
+    dataLog("DFG ASSERTION FAILED: ", assertion, "\n");
+    dataLog(file, "(", line, ") : ", function, "\n");
+    dataLog("\n");
+    dataLog(whileText);
+    dataLog("Graph at time of failure:\n");
+    graph.dump();
+    dataLog("\n");
+    dataLog("DFG ASSERTION FAILED: ", assertion, "\n");
+    dataLog(file, "(", line, ") : ", function, "\n");
+    CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+void Graph::handleAssertionFailure(
+    std::nullptr_t, const char* file, int line, const char* function, const char* assertion)
+{
+    crash(*this, "", file, line, function, assertion);
+}
+
+void Graph::handleAssertionFailure(
+    Node* node, const char* file, int line, const char* function, const char* assertion)
+{
+    crash(*this, toCString("While handling node ", node, "\n\n"), file, line, function, assertion);
+}
+
+void Graph::handleAssertionFailure(
+    BasicBlock* block, const char* file, int line, const char* function, const char* assertion)
+{
+    crash(*this, toCString("While handling block ", pointerDump(block), "\n\n"), file, line, function, assertion);
+}
+
+ValueProfile* Graph::valueProfileFor(Node* node)
+{
+    if (!node)
+        return nullptr;
+        
+    CodeBlock* profiledBlock = baselineCodeBlockFor(node->origin.semantic);
+        
+    if (node->hasLocal(*this)) {
+        if (!node->local().isArgument())
+            return nullptr;
+        int argument = node->local().toArgument();
+        Node* argumentNode = m_arguments[argument];
+        if (!argumentNode)
+            return nullptr;
+        if (node->variableAccessData() != argumentNode->variableAccessData())
+            return nullptr;
+        return profiledBlock->valueProfileForArgument(argument);
+    }
+        
+    if (node->hasHeapPrediction())
+        return profiledBlock->valueProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
+        
+    return nullptr;
+}
+
+MethodOfGettingAValueProfile Graph::methodOfGettingAValueProfileFor(Node* node)
+{
+    if (!node)
+        return MethodOfGettingAValueProfile();
+    
+    if (ValueProfile* valueProfile = valueProfileFor(node))
+        return MethodOfGettingAValueProfile(valueProfile);
+    
+    if (node->op() == GetLocal) {
+        CodeBlock* profiledBlock = baselineCodeBlockFor(node->origin.semantic);
+        
+        return MethodOfGettingAValueProfile::fromLazyOperand(
+            profiledBlock,
+            LazyOperandValueProfileKey(
+                node->origin.semantic.bytecodeIndex, node->local()));
+    }
+    
+    return MethodOfGettingAValueProfile();
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index aa1a8541f7135519c9f53d5ae998dd06cfda1901..e19ad1f026060c253d0f7fc592c357412d1793cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #if ENABLE(DFG_JIT)
 
 #include "AssemblyHelpers.h"
+#include "BytecodeLivenessAnalysisInlines.h"
 #include "CodeBlock.h"
 #include "DFGArgumentPosition.h"
 #include "DFGBasicBlock.h"
 #include "DFGDominators.h"
+#include "DFGFrozenValue.h"
 #include "DFGLongLivedState.h"
 #include "DFGNaturalLoops.h"
 #include "DFGNode.h"
 #include "DFGNodeAllocator.h"
 #include "DFGPlan.h"
+#include "DFGPrePostNumbering.h"
 #include "DFGScannable.h"
+#include "FullBytecodeLiveness.h"
 #include "JSStack.h"
 #include "MethodOfGettingAValueProfile.h"
 #include <unordered_map>
@@ -54,10 +58,47 @@ class ExecState;
 
 namespace DFG {
 
-struct StorageAccessData {
-    PropertyOffset offset;
-    unsigned identifierNumber;
-};
+#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
+        Node* _node = (node);                                           \
+        if (_node->flags() & NodeHasVarArgs) {                          \
+            for (unsigned _childIdx = _node->firstChild();              \
+                _childIdx < _node->firstChild() + _node->numChildren(); \
+                _childIdx++) {                                          \
+                if (!!(graph).m_varArgChildren[_childIdx])              \
+                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
+            }                                                           \
+        } else {                                                        \
+            if (!_node->child1()) {                                     \
+                ASSERT(                                                 \
+                    !_node->child2()                                    \
+                    && !_node->child3());                               \
+                break;                                                  \
+            }                                                           \
+            thingToDo(_node, _node->child1());                          \
+                                                                        \
+            if (!_node->child2()) {                                     \
+                ASSERT(!_node->child3());                               \
+                break;                                                  \
+            }                                                           \
+            thingToDo(_node, _node->child2());                          \
+                                                                        \
+            if (!_node->child3())                                       \
+                break;                                                  \
+            thingToDo(_node, _node->child3());                          \
+        }                                                               \
+    } while (false)
+
+#define DFG_ASSERT(graph, node, assertion) do {                         \
+        if (!!(assertion))                                              \
+            break;                                                      \
+        (graph).handleAssertionFailure(                                 \
+            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
+    } while (false)
+
+#define DFG_CRASH(graph, node, reason) do {                             \
+        (graph).handleAssertionFailure(                                 \
+            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason)); \
+    } while (false)
 
 struct InlineVariableData {
     InlineCallFrame* inlineCallFrame;
@@ -124,7 +165,7 @@ public:
             return;
         
         // Check if there is any replacement.
-        Node* replacement = child->misc.replacement;
+        Node* replacement = child->replacement();
         if (!replacement)
             return;
         
@@ -132,7 +173,7 @@ public:
         
         // There is definitely a replacement. Assert that the replacement does not
         // have a replacement.
-        ASSERT(!child->misc.replacement);
+        ASSERT(!child->replacement());
     }
     
     template<typename... Params>
@@ -145,41 +186,21 @@ public:
 
     void dethread();
     
-    void convertToConstant(Node* node, unsigned constantNumber)
-    {
-        if (node->op() == GetLocal)
-            dethread();
-        else
-            ASSERT(!node->hasVariableAccessData(*this));
-        node->convertToConstant(constantNumber);
-    }
-    
-    unsigned constantRegisterForConstant(JSValue value)
-    {
-        unsigned constantRegister;
-        if (!m_codeBlock->findConstant(value, constantRegister)) {
-            constantRegister = m_codeBlock->addConstantLazily();
-            initializeLazyWriteBarrierForConstant(
-                m_plan.writeBarriers,
-                m_codeBlock->constants()[constantRegister],
-                m_codeBlock,
-                constantRegister,
-                m_codeBlock->ownerExecutable(),
-                value);
-        }
-        return constantRegister;
-    }
+    FrozenValue* freeze(JSValue); // We use weak freezing by default.
+    FrozenValue* freezeStrong(JSValue); // Shorthand for freeze(value)->strengthenTo(StrongValue).
+    
+    void convertToConstant(Node* node, FrozenValue* value);
+    void convertToConstant(Node* node, JSValue value);
+    void convertToStrongConstant(Node* node, JSValue value);
+    
+    StructureRegistrationResult registerStructure(Structure* structure);
+    void assertIsRegistered(Structure* structure);
     
-    void convertToConstant(Node* node, JSValue value)
-    {
-        if (value.isObject())
-            node->convertToWeakConstant(value.asCell());
-        else
-            convertToConstant(node, constantRegisterForConstant(value));
-    }
-
     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
     void dump(PrintStream& = WTF::dataFile(), DumpContext* = 0);
+    
+    bool terminalsAreValid();
+    
     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
     void dumpBlockHeader(PrintStream&, const char* prefix, BasicBlock*, PhiNodeDumpMode, DumpContext*);
     void dump(PrintStream&, Edge);
@@ -191,11 +212,6 @@ public:
     // preceding node. Returns true if anything was printed.
     bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode, DumpContext*);
 
-    SpeculatedType getJSConstantSpeculation(Node* node)
-    {
-        return speculationFromValue(node->valueOfJSConstant(m_codeBlock));
-    }
-    
     AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInt32, bool rightShouldSpeculateInt32, PredictionPass pass)
     {
         ASSERT(add->op() == ValueAdd || add->op() == ArithAdd || add->op() == ArithSub);
@@ -206,9 +222,9 @@ public:
         Node* right = add->child2().node();
         
         if (left->hasConstant())
-            return addImmediateShouldSpeculateInt32(add, rightShouldSpeculateInt32, left, source);
+            return addImmediateShouldSpeculateInt32(add, rightShouldSpeculateInt32, right, left, source);
         if (right->hasConstant())
-            return addImmediateShouldSpeculateInt32(add, leftShouldSpeculateInt32, right, source);
+            return addImmediateShouldSpeculateInt32(add, leftShouldSpeculateInt32, left, right, source);
         
         return (leftShouldSpeculateInt32 && rightShouldSpeculateInt32 && add->canSpeculateInt32(source)) ? SpeculateInt32 : DontSpeculateInt32;
     }
@@ -252,12 +268,7 @@ public:
         Node* left = add->child1().node();
         Node* right = add->child2().node();
 
-        bool speculation;
-        if (add->op() == ValueAdd)
-            speculation = Node::shouldSpeculateMachineInt(left, right);
-        else
-            speculation = Node::shouldSpeculateMachineInt(left, right);
-
+        bool speculation = Node::shouldSpeculateMachineInt(left, right);
         return speculation && !hasExitSite(add, Int52Overflow);
     }
     
@@ -303,100 +314,13 @@ public:
             && !hasExitSite(negate, Int52Overflow)
             && negate->canSpeculateInt52(pass);
     }
-    
-    VirtualRegister bytecodeRegisterForArgument(CodeOrigin codeOrigin, int argument)
+
+    bool roundShouldSpeculateInt32(Node* arithRound, PredictionPass pass)
     {
-        return VirtualRegister(
-            codeOrigin.inlineCallFrame->stackOffset +
-            baselineCodeBlockFor(codeOrigin)->argumentIndexAfterCapture(argument));
+        ASSERT(arithRound->op() == ArithRound);
+        return arithRound->canSpeculateInt32(pass) && !hasExitSite(arithRound->origin.semantic, Overflow) && !hasExitSite(arithRound->origin.semantic, NegativeZero);
     }
     
-    // Helper methods to check nodes for constants.
-    bool isConstant(Node* node)
-    {
-        return node->hasConstant();
-    }
-    bool isJSConstant(Node* node)
-    {
-        return node->hasConstant();
-    }
-    bool isInt32Constant(Node* node)
-    {
-        return node->isInt32Constant(m_codeBlock);
-    }
-    bool isDoubleConstant(Node* node)
-    {
-        return node->isDoubleConstant(m_codeBlock);
-    }
-    bool isNumberConstant(Node* node)
-    {
-        return node->isNumberConstant(m_codeBlock);
-    }
-    bool isMachineIntConstant(Node* node)
-    {
-        return node->isMachineIntConstant(m_codeBlock);
-    }
-    bool isBooleanConstant(Node* node)
-    {
-        return node->isBooleanConstant(m_codeBlock);
-    }
-    bool isCellConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        JSValue value = valueOfJSConstant(node);
-        return value.isCell() && !!value;
-    }
-    bool isFunctionConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        if (!getJSFunction(valueOfJSConstant(node)))
-            return false;
-        return true;
-    }
-    bool isInternalFunctionConstant(Node* node)
-    {
-        if (!isJSConstant(node))
-            return false;
-        JSValue value = valueOfJSConstant(node);
-        if (!value.isCell() || !value)
-            return false;
-        JSCell* cell = value.asCell();
-        if (!cell->inherits(InternalFunction::info()))
-            return false;
-        return true;
-    }
-    // Helper methods get constant values from nodes.
-    JSValue valueOfJSConstant(Node* node)
-    {
-        return node->valueOfJSConstant(m_codeBlock);
-    }
-    int32_t valueOfInt32Constant(Node* node)
-    {
-        JSValue value = valueOfJSConstant(node);
-        if (!value.isInt32()) {
-            dataLog("Value isn't int32: ", value, "\n");
-            dump();
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-        return value.asInt32();
-    }
-    double valueOfNumberConstant(Node* node)
-    {
-        return valueOfJSConstant(node).asNumber();
-    }
-    bool valueOfBooleanConstant(Node* node)
-    {
-        return valueOfJSConstant(node).asBoolean();
-    }
-    JSFunction* valueOfFunctionConstant(Node* node)
-    {
-        JSCell* function = getJSFunction(valueOfJSConstant(node));
-        ASSERT(function);
-        return jsCast<JSFunction*>(function);
-    }
-
     static const char *opName(NodeType);
     
     StructureSet* addStructureSet(const StructureSet& structureSet)
@@ -406,12 +330,6 @@ public:
         return &m_structureSet.last();
     }
     
-    StructureTransitionData* addStructureTransitionData(const StructureTransitionData& structureTransitionData)
-    {
-        m_structureTransitionData.append(structureTransitionData);
-        return &m_structureTransitionData.last();
-    }
-    
     JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
     {
         return m_codeBlock->globalObjectFor(codeOrigin);
@@ -448,6 +366,16 @@ public:
         return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
     }
     
+    SymbolTable* symbolTableFor(InlineCallFrame* inlineCallFrame)
+    {
+        return baselineCodeBlockFor(inlineCallFrame)->symbolTable();
+    }
+    
+    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
+    {
+        return symbolTableFor(codeOrigin.inlineCallFrame);
+    }
+    
     bool isStrictModeFor(CodeOrigin codeOrigin)
     {
         if (!codeOrigin.inlineCallFrame)
@@ -462,8 +390,7 @@ public:
     
     bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
     {
-        return m_plan.watchpoints.isStillValid(
-            globalObjectFor(codeOrigin)->masqueradesAsUndefinedWatchpoint());
+        return globalObjectFor(codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
     }
     
     bool hasGlobalExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
@@ -481,60 +408,6 @@ public:
         return hasExitSite(node->origin.semantic, exitKind);
     }
     
-    bool usesArguments(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->usesArguments();
-        
-        return baselineCodeBlockForInlineCallFrame(inlineCallFrame)->usesArguments();
-    }
-    
-    VirtualRegister argumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->argumentsRegister();
-        
-        return VirtualRegister(baselineCodeBlockForInlineCallFrame(
-            inlineCallFrame)->argumentsRegister().offset() +
-            inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister argumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return argumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
-    VirtualRegister machineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_codeBlock->argumentsRegister();
-        
-        return inlineCallFrame->argumentsRegister;
-    }
-    
-    VirtualRegister machineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return machineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
-    VirtualRegister uncheckedArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->uncheckedArgumentsRegister();
-        
-        CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
-        if (!codeBlock->usesArguments())
-            return VirtualRegister();
-        
-        return VirtualRegister(codeBlock->argumentsRegister().offset() +
-            inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister uncheckedArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return uncheckedArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
     VirtualRegister activationRegister()
     {
         return m_profiledBlock->activationRegister();
@@ -555,54 +428,8 @@ public:
         return m_profiledBlock->uncheckedActivationRegister();
     }
     
-    ValueProfile* valueProfileFor(Node* node)
-    {
-        if (!node)
-            return 0;
-        
-        CodeBlock* profiledBlock = baselineCodeBlockFor(node->origin.semantic);
-        
-        if (node->op() == GetArgument)
-            return profiledBlock->valueProfileForArgument(node->local().toArgument());
-        
-        if (node->hasLocal(*this)) {
-            if (m_form == SSA)
-                return 0;
-            if (!node->local().isArgument())
-                return 0;
-            int argument = node->local().toArgument();
-            if (node->variableAccessData() != m_arguments[argument]->variableAccessData())
-                return 0;
-            return profiledBlock->valueProfileForArgument(argument);
-        }
-        
-        if (node->hasHeapPrediction())
-            return profiledBlock->valueProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
-        
-        return 0;
-    }
-    
-    MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node* node)
-    {
-        if (!node)
-            return MethodOfGettingAValueProfile();
-        
-        CodeBlock* profiledBlock = baselineCodeBlockFor(node->origin.semantic);
-        
-        if (node->op() == GetLocal) {
-            return MethodOfGettingAValueProfile::fromLazyOperand(
-                profiledBlock,
-                LazyOperandValueProfileKey(
-                    node->origin.semantic.bytecodeIndex, node->local()));
-        }
-        
-        return MethodOfGettingAValueProfile(valueProfileFor(node));
-    }
-    
-    bool usesArguments() const
-    {
-        return m_codeBlock->usesArguments();
-    }
+    ValueProfile* valueProfileFor(Node*);
+    MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node*);
     
     BlockIndex numBlocks() const { return m_blocks.size(); }
     BasicBlock* block(BlockIndex blockIndex) const { return m_blocks[blockIndex].get(); }
@@ -616,7 +443,7 @@ public:
     
     void killBlock(BlockIndex blockIndex)
     {
-        m_blocks[blockIndex].clear();
+        m_blocks[blockIndex] = nullptr;
     }
     
     void killBlock(BasicBlock* basicBlock)
@@ -628,76 +455,10 @@ public:
     
     void killUnreachableBlocks();
     
-    bool isPredictedNumerical(Node* node)
-    {
-        return isNumerical(node->child1().useKind()) && isNumerical(node->child2().useKind());
-    }
-    
-    // Note that a 'true' return does not actually mean that the ByVal access clobbers nothing.
-    // It really means that it will not clobber the entire world. It's still up to you to
-    // carefully consider things like:
-    // - PutByVal definitely changes the array it stores to, and may even change its length.
-    // - PutByOffset definitely changes the object it stores to.
-    // - and so on.
-    bool byValIsPure(Node* node)
-    {
-        switch (node->arrayMode().type()) {
-        case Array::Generic:
-            return false;
-        case Array::Int32:
-        case Array::Double:
-        case Array::Contiguous:
-        case Array::ArrayStorage:
-            return !node->arrayMode().isOutOfBounds();
-        case Array::SlowPutArrayStorage:
-            return !node->arrayMode().mayStoreToHole();
-        case Array::String:
-            return node->op() == GetByVal && node->arrayMode().isInBounds();
-#if USE(JSVALUE32_64)
-        case Array::Arguments:
-            if (node->op() == GetByVal)
-                return true;
-            return false;
-#endif // USE(JSVALUE32_64)
-        default:
-            return true;
-        }
-    }
-    
-    bool clobbersWorld(Node* node)
-    {
-        if (node->flags() & NodeClobbersWorld)
-            return true;
-        if (!(node->flags() & NodeMightClobber))
-            return false;
-        switch (node->op()) {
-        case GetByVal:
-        case PutByValDirect:
-        case PutByVal:
-        case PutByValAlias:
-            return !byValIsPure(node);
-        case ToString:
-            switch (node->child1().useKind()) {
-            case StringObjectUse:
-            case StringOrStringObjectUse:
-                return false;
-            case CellUse:
-            case UntypedUse:
-                return true;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                return true;
-            }
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return true; // If by some oddity we hit this case in release build it's safer to have CSE assume the worst.
-        }
-    }
-    
     void determineReachability();
     void resetReachability();
     
-    void resetExitStates();
+    void computeRefCounts();
     
     unsigned varArgNumChildren(Node* node)
     {
@@ -803,34 +564,234 @@ public:
     void clearFlagsOnAllNodes(NodeFlags);
     
     void clearReplacements();
+    void clearEpochs();
     void initializeNodeOwners();
     
-    void getBlocksInDepthFirstOrder(Vector<BasicBlock*>& result);
+    BlockList blocksInPreOrder();
+    BlockList blocksInPostOrder();
+    
+    class NaturalBlockIterable {
+    public:
+        NaturalBlockIterable()
+            : m_graph(nullptr)
+        {
+        }
+        
+        NaturalBlockIterable(Graph& graph)
+            : m_graph(&graph)
+        {
+        }
+        
+        class iterator {
+        public:
+            iterator()
+                : m_graph(nullptr)
+                , m_index(0)
+            {
+            }
+            
+            iterator(Graph& graph, BlockIndex index)
+                : m_graph(&graph)
+                , m_index(findNext(index))
+            {
+            }
+            
+            BasicBlock *operator*()
+            {
+                return m_graph->block(m_index);
+            }
+            
+            iterator& operator++()
+            {
+                m_index = findNext(m_index + 1);
+                return *this;
+            }
+            
+            bool operator==(const iterator& other) const
+            {
+                return m_index == other.m_index;
+            }
+            
+            bool operator!=(const iterator& other) const
+            {
+                return !(*this == other);
+            }
+            
+        private:
+            BlockIndex findNext(BlockIndex index)
+            {
+                while (index < m_graph->numBlocks() && !m_graph->block(index))
+                    index++;
+                return index;
+            }
+            
+            Graph* m_graph;
+            BlockIndex m_index;
+        };
+        
+        iterator begin()
+        {
+            return iterator(*m_graph, 0);
+        }
+        
+        iterator end()
+        {
+            return iterator(*m_graph, m_graph->numBlocks());
+        }
+        
+    private:
+        Graph* m_graph;
+    };
+    
+    NaturalBlockIterable blocksInNaturalOrder()
+    {
+        return NaturalBlockIterable(*this);
+    }
+    
+    template<typename ChildFunctor>
+    void doToChildrenWithNode(Node* node, const ChildFunctor& functor)
+    {
+        DFG_NODE_DO_TO_CHILDREN(*this, node, functor);
+    }
+    
+    template<typename ChildFunctor>
+    void doToChildren(Node* node, const ChildFunctor& functor)
+    {
+        doToChildrenWithNode(
+            node,
+            [&functor] (Node*, Edge& edge) {
+                functor(edge);
+            });
+    }
+    
+    bool uses(Node* node, Node* child)
+    {
+        bool result = false;
+        doToChildren(node, [&] (Edge edge) { result |= edge == child; });
+        return result;
+    }
     
     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
     
     DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
     DesiredWatchpoints& watchpoints() { return m_plan.watchpoints; }
-    DesiredStructureChains& chains() { return m_plan.chains; }
     
     FullBytecodeLiveness& livenessFor(CodeBlock*);
     FullBytecodeLiveness& livenessFor(InlineCallFrame*);
+    
+    // Quickly query if a single local is live at the given point. This is faster than calling
+    // forAllLiveInBytecode() if you will only query one local. But, if you want to know all of the
+    // locals live, then calling this for each local is much slower than forAllLiveInBytecode().
     bool isLiveInBytecode(VirtualRegister, CodeOrigin);
     
+    // Quickly get all of the non-argument locals live at the given point. This doesn't give you
+    // any arguments because those are all presumed live. You can call forAllLiveInBytecode() to
+    // also get the arguments. This is much faster than calling isLiveInBytecode() for each local.
+    template<typename Functor>
+    void forAllLocalsLiveInBytecode(CodeOrigin codeOrigin, const Functor& functor)
+    {
+        // Support for not redundantly reporting arguments. Necessary because in case of a varargs
+        // call, only the callee knows that arguments are live while in the case of a non-varargs
+        // call, both callee and caller will see the variables live.
+        VirtualRegister exclusionStart;
+        VirtualRegister exclusionEnd;
+        
+        for (;;) {
+            InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame;
+            VirtualRegister stackOffset(inlineCallFrame ? inlineCallFrame->stackOffset : 0);
+            
+            if (inlineCallFrame) {
+                if (inlineCallFrame->isClosureCall)
+                    functor(stackOffset + JSStack::Callee);
+                if (inlineCallFrame->isVarargs())
+                    functor(stackOffset + JSStack::ArgumentCount);
+            }
+            
+            CodeBlock* codeBlock = baselineCodeBlockFor(inlineCallFrame);
+            FullBytecodeLiveness& fullLiveness = livenessFor(codeBlock);
+            const FastBitVector& liveness = fullLiveness.getLiveness(codeOrigin.bytecodeIndex);
+            for (unsigned relativeLocal = codeBlock->m_numCalleeRegisters; relativeLocal--;) {
+                VirtualRegister reg = stackOffset + virtualRegisterForLocal(relativeLocal);
+                
+                // Don't report if our callee already reported.
+                if (reg >= exclusionStart && reg < exclusionEnd)
+                    continue;
+                
+                if (liveness.get(relativeLocal))
+                    functor(reg);
+            }
+            
+            if (!inlineCallFrame)
+                break;
+
+            // Arguments are always live. This would be redundant if it wasn't for our
+            // op_call_varargs inlining. See the comment above.
+            exclusionStart = stackOffset + CallFrame::argumentOffsetIncludingThis(0);
+            exclusionEnd = stackOffset + CallFrame::argumentOffsetIncludingThis(inlineCallFrame->arguments.size());
+            
+            // We will always have a "this" argument and exclusionStart should be a smaller stack
+            // offset than exclusionEnd.
+            ASSERT(exclusionStart < exclusionEnd);
+
+            for (VirtualRegister reg = exclusionStart; reg < exclusionEnd; reg += 1)
+                functor(reg);
+            
+            codeOrigin = inlineCallFrame->caller;
+        }
+    }
+    
+    // Get a BitVector of all of the non-argument locals live right now. This is mostly useful if
+    // you want to compare two sets of live locals from two different CodeOrigins.
+    BitVector localsLiveInBytecode(CodeOrigin);
+    
+    // Tells you all of the arguments and locals live at the given CodeOrigin. This is a small
+    // extension to forAllLocalsLiveInBytecode(), since all arguments are always presumed live.
+    template<typename Functor>
+    void forAllLiveInBytecode(CodeOrigin codeOrigin, const Functor& functor)
+    {
+        forAllLocalsLiveInBytecode(codeOrigin, functor);
+        
+        // Report all arguments as being live.
+        for (unsigned argument = block(0)->variablesAtHead.numberOfArguments(); argument--;)
+            functor(virtualRegisterForArgument(argument));
+    }
+    
+    BytecodeKills& killsFor(CodeBlock*);
+    BytecodeKills& killsFor(InlineCallFrame*);
+    
     unsigned frameRegisterCount();
     unsigned stackPointerOffset();
     unsigned requiredRegisterCountForExit();
     unsigned requiredRegisterCountForExecutionAndExit();
     
-    JSActivation* tryGetActivation(Node*);
-    WriteBarrierBase<Unknown>* tryGetRegisters(Node*);
+    JSValue tryGetConstantProperty(JSValue base, const StructureSet&, PropertyOffset);
+    JSValue tryGetConstantProperty(JSValue base, Structure*, PropertyOffset);
+    JSValue tryGetConstantProperty(JSValue base, const StructureAbstractValue&, PropertyOffset);
+    JSValue tryGetConstantProperty(const AbstractValue&, PropertyOffset);
+    
+    JSValue tryGetConstantClosureVar(JSValue base, ScopeOffset);
+    JSValue tryGetConstantClosureVar(const AbstractValue&, ScopeOffset);
+    JSValue tryGetConstantClosureVar(Node*, ScopeOffset);
     
-    JSArrayBufferView* tryGetFoldableView(Node*);
-    JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode);
-    JSArrayBufferView* tryGetFoldableViewForChild1(Node*);
+    JSArrayBufferView* tryGetFoldableView(JSValue);
+    JSArrayBufferView* tryGetFoldableView(JSValue, ArrayMode arrayMode);
+    
+    void registerFrozenValues();
     
     virtual void visitChildren(SlotVisitor&) override;
     
+    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
+        std::nullptr_t, const char* file, int line, const char* function,
+        const char* assertion);
+    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
+        Node*, const char* file, int line, const char* function,
+        const char* assertion);
+    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
+        BasicBlock*, const char* file, int line, const char* function,
+        const char* assertion);
+
+    bool hasDebuggerEnabled() const { return m_hasDebuggerEnabled; }
+
     VM& m_vm;
     Plan& m_plan;
     CodeBlock* m_codeBlock;
@@ -838,33 +799,68 @@ public:
     
     NodeAllocator& m_allocator;
 
-    Operands<AbstractValue> m_mustHandleAbstractValues;
-    
     Vector< RefPtr<BasicBlock> , 8> m_blocks;
     Vector<Edge, 16> m_varArgChildren;
-    Vector<StorageAccessData> m_storageAccessData;
+
+    HashMap<EncodedJSValue, FrozenValue*, EncodedJSValueHash, EncodedJSValueHashTraits> m_frozenValueMap;
+    Bag<FrozenValue> m_frozenValues;
+
+    Vector<uint32_t> m_uint32ValuesInUse;
+    
+    Bag<StorageAccessData> m_storageAccessData;
+    
+    // In CPS, this is all of the SetArgument nodes for the arguments in the machine code block
+    // that survived DCE. All of them except maybe "this" will survive DCE, because of the Flush
+    // nodes.
+    //
+    // In SSA, this is all of the GetStack nodes for the arguments in the machine code block that
+    // may have some speculation in the prologue and survived DCE. Note that to get the speculation
+    // for an argument in SSA, you must use m_argumentFormats, since we still have to speculate
+    // even if the argument got killed. For example:
+    //
+    //     function foo(x) {
+    //        var tmp = x + 1;
+    //     }
+    //
+    // Assume that x is always int during profiling. The ArithAdd for "x + 1" will be dead and will
+    // have a proven check for the edge to "x". So, we will not insert a Check node and we will
+    // kill the GetStack for "x". But, we must do the int check in the progolue, because that's the
+    // thing we used to allow DCE of ArithAdd. Otherwise the add could be impure:
+    //
+    //     var o = {
+    //         valueOf: function() { do side effects; }
+    //     };
+    //     foo(o);
+    //
+    // If we DCE the ArithAdd and we remove the int check on x, then this won't do the side
+    // effects.
     Vector<Node*, 8> m_arguments;
+    
+    // In CPS, this is meaningless. In SSA, this is the argument speculation that we've locked in.
+    Vector<FlushFormat> m_argumentFormats;
+    
     SegmentedVector<VariableAccessData, 16> m_variableAccessData;
     SegmentedVector<ArgumentPosition, 8> m_argumentPositions;
     SegmentedVector<StructureSet, 16> m_structureSet;
-    SegmentedVector<StructureTransitionData, 8> m_structureTransitionData;
+    Bag<Transition> m_transitions;
     SegmentedVector<NewArrayBufferData, 4> m_newArrayBufferData;
     Bag<BranchData> m_branchData;
     Bag<SwitchData> m_switchData;
     Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
     Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
+    Bag<ObjectMaterializationData> m_objectMaterializationData;
+    Bag<CallVarargsData> m_callVarargsData;
+    Bag<LoadVarargsData> m_loadVarargsData;
+    Bag<StackAccessData> m_stackAccessData;
     Vector<InlineVariableData, 4> m_inlineVariableData;
     HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
-    bool m_hasArguments;
-    HashSet<ExecutableBase*> m_executablesWhoseArgumentsEscaped;
-    BitVector m_lazyVars;
+    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>> m_bytecodeKills;
     Dominators m_dominators;
+    PrePostNumbering m_prePostNumbering;
     NaturalLoops m_naturalLoops;
     unsigned m_localVars;
     unsigned m_nextMachineLocal;
     unsigned m_parameterSlots;
-    int m_machineCaptureStart;
-    std::unique_ptr<SlowArgument[]> m_slowArguments;
 
 #if USE(JSVALUE32_64)
     std::unordered_map<int64_t, double*> m_doubleConstantsMap;
@@ -872,26 +868,34 @@ public:
 #endif
     
     OptimizationFixpointState m_fixpointState;
+    StructureRegistrationState m_structureRegistrationState;
     GraphForm m_form;
     UnificationState m_unificationState;
+    PlanStage m_planStage { PlanStage::Initial };
     RefCountState m_refCountState;
+    bool m_hasDebuggerEnabled;
 private:
     
     void handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock*, BasicBlock* successor);
-    void addForDepthFirstSort(Vector<BasicBlock*>& result, Vector<BasicBlock*, 16>& worklist, HashSet<BasicBlock*>& seen, BasicBlock*);
     
-    AddSpeculationMode addImmediateShouldSpeculateInt32(Node* add, bool variableShouldSpeculateInt32, Node* immediate, RareCaseProfilingSource source)
+    AddSpeculationMode addImmediateShouldSpeculateInt32(Node* add, bool variableShouldSpeculateInt32, Node* operand, Node*immediate, RareCaseProfilingSource source)
     {
         ASSERT(immediate->hasConstant());
         
-        JSValue immediateValue = immediate->valueOfJSConstant(m_codeBlock);
+        JSValue immediateValue = immediate->asJSValue();
         if (!immediateValue.isNumber() && !immediateValue.isBoolean())
             return DontSpeculateInt32;
         
         if (!variableShouldSpeculateInt32)
             return DontSpeculateInt32;
+
+        // Integer constants can be typed Double if they are written like a double in the source code (e.g. 42.0).
+        // In that case, we stay conservative unless the other operand was explicitly typed as integer.
+        NodeFlags operandResultType = operand->result();
+        if (operandResultType != NodeResultInt32 && immediateValue.isDouble())
+            return DontSpeculateInt32;
         
-        if (immediateValue.isInt32() || immediateValue.isBoolean())
+        if (immediateValue.isBoolean() || jsNumber(immediateValue.asNumber()).isInt32())
             return add->canSpeculateInt32(source) ? SpeculateInt32 : DontSpeculateInt32;
         
         double doubleImmediate = immediateValue.asDouble();
@@ -903,36 +907,6 @@ private:
     }
 };
 
-#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
-        Node* _node = (node);                                           \
-        if (_node->flags() & NodeHasVarArgs) {                          \
-            for (unsigned _childIdx = _node->firstChild();              \
-                _childIdx < _node->firstChild() + _node->numChildren(); \
-                _childIdx++) {                                          \
-                if (!!(graph).m_varArgChildren[_childIdx])              \
-                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
-            }                                                           \
-        } else {                                                        \
-            if (!_node->child1()) {                                     \
-                ASSERT(                                                 \
-                    !_node->child2()                                    \
-                    && !_node->child3());                               \
-                break;                                                  \
-            }                                                           \
-            thingToDo(_node, _node->child1());                          \
-                                                                        \
-            if (!_node->child2()) {                                     \
-                ASSERT(!_node->child3());                               \
-                break;                                                  \
-            }                                                           \
-            thingToDo(_node, _node->child2());                          \
-                                                                        \
-            if (!_node->child3())                                       \
-                break;                                                  \
-            thingToDo(_node, _node->child3());                          \
-        }                                                               \
-    } while (false)
-
 } } // namespace JSC::DFG
 
 #endif
diff --git a/dfg/DFGHeapLocation.cpp b/dfg/DFGHeapLocation.cpp
new file mode 100644 (file)
index 0000000..2ca344a
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGHeapLocation.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void HeapLocation::dump(PrintStream& out) const
+{
+    out.print(m_kind, ":", m_heap);
+    
+    if (!m_base)
+        return;
+    
+    out.print("[", m_base);
+    if (m_index)
+        out.print(", ", m_index);
+    out.print("]");
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, LocationKind kind)
+{
+    switch (kind) {
+    case InvalidLocationKind:
+        out.print("InvalidLocationKind");
+        return;
+        
+    case InvalidationPointLoc:
+        out.print("InvalidationPointLoc");
+        return;
+        
+    case IsObjectOrNullLoc:
+        out.print("IsObjectOrNullLoc");
+        return;
+
+    case IsFunctionLoc:
+        out.print("IsFunctionLoc");
+        return;
+        
+    case GetterLoc:
+        out.print("GetterLoc");
+        return;
+        
+    case SetterLoc:
+        out.print("SetterLoc");
+        return;
+        
+    case StackLoc:
+        out.print("StackLoc");
+        return;
+        
+    case StackPayloadLoc:
+        out.print("StackPayloadLoc");
+        return;
+        
+    case ArrayLengthLoc:
+        out.print("ArrayLengthLoc");
+        return;
+        
+    case ButterflyLoc:
+        out.print("ButterflyLoc");
+        return;
+        
+    case CheckHasInstanceLoc:
+        out.print("CheckHasInstanceLoc");
+        return;
+        
+    case ClosureVariableLoc:
+        out.print("ClosureVariableLoc");
+        return;
+        
+    case DirectArgumentsLoc:
+        out.print("DirectArgumentsLoc");
+        return;
+        
+    case GlobalVariableLoc:
+        out.print("GlobalVariableLoc");
+        return;
+        
+    case HasIndexedPropertyLoc:
+        out.print("HasIndexedPorpertyLoc");
+        return;
+        
+    case IndexedPropertyLoc:
+        out.print("IndexedPorpertyLoc");
+        return;
+        
+    case IndexedPropertyStorageLoc:
+        out.print("IndexedPropertyStorageLoc");
+        return;
+        
+    case InstanceOfLoc:
+        out.print("InstanceOfLoc");
+        return;
+        
+    case NamedPropertyLoc:
+        out.print("NamedPropertyLoc");
+        return;
+        
+    case TypedArrayByteOffsetLoc:
+        out.print("TypedArrayByteOffsetLoc");
+        return;
+        
+    case VarInjectionWatchpointLoc:
+        out.print("VarInjectionWatchpointLoc");
+        return;
+        
+    case StructureLoc:
+        out.print("StructureLoc");
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGHeapLocation.h b/dfg/DFGHeapLocation.h
new file mode 100644 (file)
index 0000000..3d3a94c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGHeapLocation_h
+#define DFGHeapLocation_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAbstractHeap.h"
+#include "DFGLazyNode.h"
+#include "DFGNode.h"
+
+namespace JSC { namespace DFG {
+
+enum LocationKind {
+    InvalidLocationKind,
+    
+    ArrayLengthLoc,
+    ButterflyLoc,
+    CheckHasInstanceLoc,
+    ClosureVariableLoc,
+    DirectArgumentsLoc,
+    GetterLoc,
+    GlobalVariableLoc,
+    HasIndexedPropertyLoc,
+    IndexedPropertyLoc,
+    IndexedPropertyStorageLoc,
+    InstanceOfLoc,
+    InvalidationPointLoc,
+    IsFunctionLoc,
+    IsObjectOrNullLoc,
+    NamedPropertyLoc,
+    SetterLoc,
+    StructureLoc,
+    TypedArrayByteOffsetLoc,
+    VarInjectionWatchpointLoc,
+    StackLoc,
+    StackPayloadLoc
+};
+
+class HeapLocation {
+public:
+    HeapLocation(
+        LocationKind kind = InvalidLocationKind,
+        AbstractHeap heap = AbstractHeap(),
+        Node* base = nullptr, LazyNode index = LazyNode())
+        : m_kind(kind)
+        , m_heap(heap)
+        , m_base(base)
+        , m_index(index)
+    {
+        ASSERT((kind == InvalidLocationKind) == !heap);
+        ASSERT(!!m_heap || !m_base);
+        ASSERT(m_base || !m_index);
+    }
+
+    HeapLocation(LocationKind kind, AbstractHeap heap, Node* base, Node* index)
+        : HeapLocation(kind, heap, base, LazyNode(index))
+    {
+    }
+    
+    HeapLocation(LocationKind kind, AbstractHeap heap, Edge base, Edge index = Edge())
+        : HeapLocation(kind, heap, base.node(), index.node())
+    {
+    }
+    
+    HeapLocation(WTF::HashTableDeletedValueType)
+        : m_kind(InvalidLocationKind)
+        , m_heap(WTF::HashTableDeletedValue)
+        , m_base(nullptr)
+        , m_index(nullptr)
+    {
+    }
+    
+    bool operator!() const { return !m_heap; }
+    
+    LocationKind kind() const { return m_kind; }
+    AbstractHeap heap() const { return m_heap; }
+    Node* base() const { return m_base; }
+    LazyNode index() const { return m_index; }
+    
+    unsigned hash() const
+    {
+        return m_kind + m_heap.hash() + m_index.hash() + m_kind;
+    }
+    
+    bool operator==(const HeapLocation& other) const
+    {
+        return m_kind == other.m_kind
+            && m_heap == other.m_heap
+            && m_base == other.m_base
+            && m_index == other.m_index;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_heap.isHashTableDeletedValue();
+    }
+    
+    void dump(PrintStream& out) const;
+    
+private:
+    LocationKind m_kind;
+    AbstractHeap m_heap;
+    Node* m_base;
+    LazyNode m_index;
+};
+
+struct HeapLocationHash {
+    static unsigned hash(const HeapLocation& key) { return key.hash(); }
+    static bool equal(const HeapLocation& a, const HeapLocation& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::LocationKind);
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::DFG::HeapLocation> {
+    typedef JSC::DFG::HeapLocationHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::HeapLocation> : SimpleClassHashTraits<JSC::DFG::HeapLocation> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+namespace JSC { namespace DFG {
+
+typedef HashMap<HeapLocation, LazyNode> ImpureMap;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGHeapLocation_h
+
index 1121305b00cd8c70e58579a5f4257a53b89abb22..b1269c1b700c9b8909e2823628a32daae3ae8ca2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +37,8 @@
 
 namespace JSC { namespace DFG {
 
+static const bool verbose = false;
+
 InPlaceAbstractState::InPlaceAbstractState(Graph& graph)
     : m_graph(graph)
     , m_variables(m_graph.m_codeBlock->numParameters(), graph.m_localVars)
@@ -58,36 +60,20 @@ void InPlaceAbstractState::beginBasicBlock(BasicBlock* basicBlock)
         forNode(basicBlock->at(i)).clear();
 
     m_variables = basicBlock->valuesAtHead;
-    m_haveStructures = false;
-    for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) {
-        if (m_variables.argument(i).hasClobberableState()) {
-            m_haveStructures = true;
-            break;
-        }
-    }
-    for (size_t i = 0; i < m_variables.numberOfLocals(); ++i) {
-        if (m_variables.local(i).hasClobberableState()) {
-            m_haveStructures = true;
-            break;
-        }
-    }
     
     if (m_graph.m_form == SSA) {
         HashMap<Node*, AbstractValue>::iterator iter = basicBlock->ssa->valuesAtHead.begin();
         HashMap<Node*, AbstractValue>::iterator end = basicBlock->ssa->valuesAtHead.end();
-        for (; iter != end; ++iter) {
+        for (; iter != end; ++iter)
             forNode(iter->key) = iter->value;
-            if (iter->value.hasClobberableState())
-                m_haveStructures = true;
-        }
     }
-    
     basicBlock->cfaShouldRevisit = false;
     basicBlock->cfaHasVisited = true;
     m_block = basicBlock;
     m_isValid = true;
     m_foundConstants = false;
     m_branchDirection = InvalidBranchDirection;
+    m_structureClobberState = basicBlock->cfaStructureClobberStateAtHead;
 }
 
 static void setLiveValues(HashMap<Node*, AbstractValue>& values, HashSet<Node*>& live)
@@ -106,37 +92,44 @@ void InPlaceAbstractState::initialize()
     root->cfaShouldRevisit = true;
     root->cfaHasVisited = false;
     root->cfaFoundConstants = false;
+    root->cfaStructureClobberStateAtHead = StructuresAreWatched;
+    root->cfaStructureClobberStateAtTail = StructuresAreWatched;
     for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) {
         root->valuesAtTail.argument(i).clear();
-        if (m_graph.m_form == SSA) {
-            root->valuesAtHead.argument(i).makeHeapTop();
-            continue;
-        }
-        
-        Node* node = root->variablesAtHead.argument(i);
-        ASSERT(node->op() == SetArgument);
-        if (!node->variableAccessData()->shouldUnboxIfPossible()) {
-            root->valuesAtHead.argument(i).makeHeapTop();
-            continue;
+
+        FlushFormat format;
+        if (m_graph.m_form == SSA)
+            format = m_graph.m_argumentFormats[i];
+        else {
+            Node* node = m_graph.m_arguments[i];
+            if (!node)
+                format = FlushedJSValue;
+            else {
+                ASSERT(node->op() == SetArgument);
+                format = node->variableAccessData()->flushFormat();
+            }
         }
         
-        SpeculatedType prediction =
-            node->variableAccessData()->argumentAwarePrediction();
-        if (isInt32Speculation(prediction))
+        switch (format) {
+        case FlushedInt32:
             root->valuesAtHead.argument(i).setType(SpecInt32);
-        else if (isBooleanSpeculation(prediction))
+            break;
+        case FlushedBoolean:
             root->valuesAtHead.argument(i).setType(SpecBoolean);
-        else if (isCellSpeculation(prediction))
-            root->valuesAtHead.argument(i).setType(SpecCell);
-        else
+            break;
+        case FlushedCell:
+            root->valuesAtHead.argument(i).setType(m_graph, SpecCell);
+            break;
+        case FlushedJSValue:
             root->valuesAtHead.argument(i).makeHeapTop();
+            break;
+        default:
+            DFG_CRASH(m_graph, nullptr, "Bad flush format for argument");
+            break;
+        }
     }
     for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
-        Node* node = root->variablesAtHead.local(i);
-        if (node && node->variableAccessData()->isCaptured())
-            root->valuesAtHead.local(i).makeHeapTop();
-        else
-            root->valuesAtHead.local(i).clear();
+        root->valuesAtHead.local(i).clear();
         root->valuesAtTail.local(i).clear();
     }
     for (BlockIndex blockIndex = 1 ; blockIndex < m_graph.numBlocks(); ++blockIndex) {
@@ -147,6 +140,8 @@ void InPlaceAbstractState::initialize()
         block->cfaShouldRevisit = false;
         block->cfaHasVisited = false;
         block->cfaFoundConstants = false;
+        block->cfaStructureClobberStateAtHead = StructuresAreWatched;
+        block->cfaStructureClobberStateAtTail = StructuresAreWatched;
         for (size_t i = 0; i < block->valuesAtHead.numberOfArguments(); ++i) {
             block->valuesAtHead.argument(i).clear();
             block->valuesAtTail.argument(i).clear();
@@ -155,25 +150,6 @@ void InPlaceAbstractState::initialize()
             block->valuesAtHead.local(i).clear();
             block->valuesAtTail.local(i).clear();
         }
-        if (m_graph.m_form == SSA)
-            continue;
-        if (!block->isOSRTarget)
-            continue;
-        if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
-            continue;
-        for (size_t i = 0; i < m_graph.m_mustHandleAbstractValues.size(); ++i) {
-            int operand = m_graph.m_mustHandleAbstractValues.operandForIndex(i);
-            Node* node = block->variablesAtHead.operand(operand);
-            if (!node)
-                continue;
-            AbstractValue value = m_graph.m_mustHandleAbstractValues[i];
-            AbstractValue& abstractValue = block->valuesAtHead.operand(operand);
-            VariableAccessData* variable = node->variableAccessData();
-            FlushFormat format = variable->flushFormat();
-            abstractValue.merge(value);
-            abstractValue.fixTypeForRepresentation(resultFor(format));
-        }
-        block->cfaShouldRevisit = true;
     }
     if (m_graph.m_form == SSA) {
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
@@ -203,7 +179,9 @@ bool InPlaceAbstractState::endBasicBlock(MergeMode mergeMode)
     
     bool changed = false;
     
-    if (mergeMode != DontMerge || !ASSERT_DISABLED) {
+    if ((mergeMode != DontMerge) || !ASSERT_DISABLED) {
+        changed |= checkAndSet(block->cfaStructureClobberStateAtTail, m_structureClobberState);
+    
         switch (m_graph.m_form) {
         case ThreadedCPS: {
             for (size_t argument = 0; argument < block->variablesAtTail.numberOfArguments(); ++argument) {
@@ -251,6 +229,7 @@ void InPlaceAbstractState::reset()
     m_block = 0;
     m_isValid = false;
     m_branchDirection = InvalidBranchDirection;
+    m_structureClobberState = StructuresAreWatched;
 }
 
 bool InPlaceAbstractState::mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, Node* node)
@@ -260,40 +239,31 @@ bool InPlaceAbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
         
     AbstractValue source;
     
-    if (node->variableAccessData()->isCaptured()) {
-        // If it's captured then we know that whatever value was stored into the variable last is the
-        // one we care about. This is true even if the variable at tail is dead, which might happen if
-        // the last thing we did to the variable was a GetLocal and then ended up not using the
-        // GetLocal's result.
-        
+    switch (node->op()) {
+    case Phi:
+    case SetArgument:
+    case PhantomLocal:
+    case Flush:
+        // The block transfers the value from head to tail.
         source = inVariable;
-    } else {
-        switch (node->op()) {
-        case Phi:
-        case SetArgument:
-        case PhantomLocal:
-        case Flush:
-            // The block transfers the value from head to tail.
-            source = inVariable;
-            break;
+        break;
             
-        case GetLocal:
-            // The block refines the value with additional speculations.
-            source = forNode(node);
-            break;
+    case GetLocal:
+        // The block refines the value with additional speculations.
+        source = forNode(node);
+        break;
             
-        case SetLocal:
-            // The block sets the variable, and potentially refines it, both
-            // before and after setting it.
-            source = forNode(node->child1());
-            if (node->variableAccessData()->flushFormat() == FlushedDouble)
-                RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
-            break;
+    case SetLocal:
+        // The block sets the variable, and potentially refines it, both
+        // before and after setting it.
+        source = forNode(node->child1());
+        if (node->variableAccessData()->flushFormat() == FlushedDouble)
+            RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
+        break;
         
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-        }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
     }
     
     if (destination == source) {
@@ -311,11 +281,17 @@ bool InPlaceAbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
 
 bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to)
 {
+    if (verbose)
+        dataLog("   Merging from ", pointerDump(from), " to ", pointerDump(to), "\n");
     ASSERT(from->variablesAtTail.numberOfArguments() == to->variablesAtHead.numberOfArguments());
     ASSERT(from->variablesAtTail.numberOfLocals() == to->variablesAtHead.numberOfLocals());
     
     bool changed = false;
     
+    changed |= checkAndSet(
+        to->cfaStructureClobberStateAtHead,
+        DFG::merge(from->cfaStructureClobberStateAtTail, to->cfaStructureClobberStateAtHead));
+    
     switch (m_graph.m_form) {
     case ThreadedCPS: {
         for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) {
@@ -338,8 +314,12 @@ bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to)
         HashSet<Node*>::iterator end = to->ssa->liveAtHead.end();
         for (; iter != end; ++iter) {
             Node* node = *iter;
+            if (verbose)
+                dataLog("      Merging for ", node, ": from ", from->ssa->valuesAtTail.find(node)->value, " to ", to->ssa->valuesAtHead.find(node)->value, "\n");
             changed |= to->ssa->valuesAtHead.find(node)->value.merge(
                 from->ssa->valuesAtTail.find(node)->value);
+            if (verbose)
+                dataLog("         Result: ", to->ssa->valuesAtHead.find(node)->value, "\n");
         }
         break;
     }
@@ -352,6 +332,8 @@ bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to)
     if (!to->cfaHasVisited)
         changed = true;
     
+    if (verbose)
+        dataLog("      Will revisit: ", changed, "\n");
     to->cfaShouldRevisit |= changed;
     
     return changed;
@@ -359,7 +341,7 @@ bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to)
 
 inline bool InPlaceAbstractState::mergeToSuccessors(BasicBlock* basicBlock)
 {
-    Node* terminal = basicBlock->last();
+    Node* terminal = basicBlock->terminal();
     
     ASSERT(terminal->isTerminal());
     
index 48da3aa02f42c466fbdbfed36f7d715bb77c48c3..297418f2ac280147230923ca6082717a282c1065 100644 (file)
@@ -103,6 +103,9 @@ public:
     // Did the last executed node clobber the world?
     bool didClobber() const { return m_didClobber; }
     
+    // Are structures currently clobbered?
+    StructureClobberState structureClobberState() const { return m_structureClobberState; }
+    
     // Is the execution state still valid? This will be false if execute() has
     // returned false previously.
     bool isValid() const { return m_isValid; }
@@ -122,11 +125,16 @@ public:
     
     // Methods intended to be called from AbstractInterpreter.
     void setDidClobber(bool didClobber) { m_didClobber = didClobber; }
+    void setStructureClobberState(StructureClobberState value) { m_structureClobberState = value; }
     void setIsValid(bool isValid) { m_isValid = isValid; }
     void setBranchDirection(BranchDirection branchDirection) { m_branchDirection = branchDirection; }
+    
+    // This method is evil - it causes a huge maintenance headache and there is a gross amount of
+    // code devoted to it. It would be much nicer to just always run the constant folder on each
+    // block. But, the last time we did it, it was a 1% SunSpider regression:
+    // https://bugs.webkit.org/show_bug.cgi?id=133947
+    // So, we should probably keep this method.
     void setFoundConstants(bool foundConstants) { m_foundConstants = foundConstants; }
-    bool haveStructures() const { return m_haveStructures; } // It's always safe to return true.
-    void setHaveStructures(bool haveStructures) { m_haveStructures = haveStructures; }
 
 private:
     bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, Node*);
@@ -138,11 +146,11 @@ private:
     Operands<AbstractValue> m_variables;
     BasicBlock* m_block;
     
-    bool m_haveStructures;
     bool m_foundConstants;
     
     bool m_isValid;
     bool m_didClobber;
+    StructureClobberState m_structureClobberState;
     
     BranchDirection m_branchDirection; // This is only set for blocks that end in Branch and that execute to completion (i.e. m_isValid == true).
 };
diff --git a/dfg/DFGInsertOSRHintsForUpdate.cpp b/dfg/DFGInsertOSRHintsForUpdate.cpp
new file mode 100644 (file)
index 0000000..a187678
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGInsertOSRHintsForUpdate.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+void insertOSRHintsForUpdate(
+    InsertionSet& insertionSet, unsigned nodeIndex, NodeOrigin origin,
+    AvailabilityMap& availability, Node* originalNode, Node* newNode)
+{
+    for (unsigned i = availability.m_locals.size(); i--;) {
+        int operand = availability.m_locals.operandForIndex(i);
+        
+        if (availability.m_locals[i].hasNode() && availability.m_locals[i].node() == originalNode) {
+            insertionSet.insertNode(
+                nodeIndex, SpecNone, MovHint, origin, OpInfo(operand),
+                newNode->defaultEdge());
+        }
+    }
+    
+    for (auto pair : availability.m_heap) {
+        if (pair.value.hasNode() && pair.value.node() == originalNode) {
+            insertionSet.insert(
+                nodeIndex, pair.key.createHint(insertionSet.graph(), origin, newNode));
+        }
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGInsertOSRHintsForUpdate.h b/dfg/DFGInsertOSRHintsForUpdate.h
new file mode 100644 (file)
index 0000000..4e42b49
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGInsertOSRHintsForUpdate_h
+#define DFGInsertOSRHintsForUpdate_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAvailabilityMap.h"
+#include "DFGInsertionSet.h"
+
+namespace JSC { namespace DFG {
+
+void insertOSRHintsForUpdate(
+    InsertionSet&, unsigned nodeIndex, NodeOrigin, AvailabilityMap&,
+    Node* originalNode, Node* newNode);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGInsertOSRHintsForUpdate_h
+
index a44616b212c2eb4ac40da5ec25a2361f6a298f78..c5ed4c207afb0b86843e037cb0b2c42fd47d15c6 100644 (file)
@@ -43,6 +43,8 @@ public:
     {
     }
     
+    Graph& graph() { return m_graph; }
+    
     Node* insert(const Insertion& insertion)
     {
         ASSERT(!m_insertions.size() || m_insertions.last().index() <= insertion.index());
@@ -62,23 +64,21 @@ public:
     }
     
     Node* insertConstant(
-        size_t index, NodeOrigin origin, JSValue value,
+        size_t index, NodeOrigin origin, FrozenValue* value,
         NodeType op = JSConstant)
     {
-        unsigned constantReg =
-            m_graph.constantRegisterForConstant(value);
         return insertNode(
-            index, speculationFromValue(value), op, origin, OpInfo(constantReg));
+            index, speculationFromValue(value->value()), op, origin, OpInfo(value));
     }
     
     Node* insertConstant(
-        size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
+        size_t index, CodeOrigin origin, FrozenValue* value, NodeType op = JSConstant)
     {
         return insertConstant(index, NodeOrigin(origin), value, op);
     }
     
     Edge insertConstantForUse(
-        size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
+        size_t index, NodeOrigin origin, FrozenValue* value, UseKind useKind)
     {
         NodeType op;
         if (isDouble(useKind))
@@ -91,11 +91,60 @@ public:
     }
     
     Edge insertConstantForUse(
-        size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
+        size_t index, CodeOrigin origin, FrozenValue* value, UseKind useKind)
     {
         return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
     }
 
+    Node* insertConstant(size_t index, NodeOrigin origin, JSValue value, NodeType op = JSConstant)
+    {
+        return insertConstant(index, origin, m_graph.freeze(value), op);
+    }
+    
+    Node* insertConstant(size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
+    {
+        return insertConstant(index, origin, m_graph.freeze(value), op);
+    }
+    
+    Edge insertConstantForUse(size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
+    {
+        return insertConstantForUse(index, origin, m_graph.freeze(value), useKind);
+    }
+    
+    Edge insertConstantForUse(size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
+    {
+        return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
+    }
+    
+    Edge insertBottomConstantForUse(size_t index, NodeOrigin origin, UseKind useKind)
+    {
+        if (isDouble(useKind))
+            return insertConstantForUse(index, origin, jsNumber(PNaN), useKind);
+        if (useKind == Int52RepUse)
+            return insertConstantForUse(index, origin, jsNumber(0), useKind);
+        return insertConstantForUse(index, origin, jsUndefined(), useKind);
+    }
+    
+    Node* insertCheck(size_t index, NodeOrigin origin, AdjacencyList children)
+    {
+        children = children.justChecks();
+        if (children.isEmpty())
+            return nullptr;
+        return insertNode(index, SpecNone, Check, origin, children);
+    }
+    
+    Node* insertCheck(size_t index, Node* node)
+    {
+        return insertCheck(index, node->origin, node->children);
+    }
+    
+    Node* insertCheck(size_t index, NodeOrigin origin, Edge edge)
+    {
+        if (edge.willHaveCheck())
+            return insertNode(index, SpecNone, Check, origin, edge);
+        return nullptr;
+    }
+    
     void execute(BasicBlock* block)
     {
         executeInsertions(*block, m_insertions);
index 96fdc68373ffe74c19e00cf8d6e70b9af7183e4d..5ddda089d249c95c38688e89497798845d9d8469 100644 (file)
@@ -236,12 +236,12 @@ private:
                 switch (data.m_key.m_kind) {
                 case Addition: {
                     if (range.m_minBound < 0) {
-                        insertMustAdd(
+                        insertAdd(
                             nodeIndex, NodeOrigin(range.m_minOrigin, node->origin.forExit),
                             data.m_key.m_source, range.m_minBound);
                     }
                     if (range.m_maxBound > 0) {
-                        insertMustAdd(
+                        insertAdd(
                             nodeIndex, NodeOrigin(range.m_maxOrigin, node->origin.forExit),
                             data.m_key.m_source, range.m_maxBound);
                     }
@@ -292,7 +292,7 @@ private:
                 break;
                 
             case ArrayBounds:
-                node->convertToPhantom();
+                node->remove();
                 m_changed = true;
                 break;
                 
@@ -311,11 +311,11 @@ private:
             if (node->arithMode() != Arith::CheckOverflow
                 && node->arithMode() != Arith::CheckOverflowAndNegativeZero)
                 break;
-            if (!m_graph.isInt32Constant(node->child2().node()))
+            if (!node->child2()->isInt32Constant())
                 break;
             return RangeKeyAndAddend(
                 RangeKey::addition(node->child1()),
-                m_graph.valueOfInt32Constant(node->child2().node()));
+                node->child2()->asInt32());
         }
                 
         case CheckInBounds: {
@@ -325,15 +325,15 @@ private:
             
             Edge index = node->child1();
             
-            if (m_graph.isInt32Constant(index.node())) {
+            if (index->isInt32Constant()) {
                 source = Edge();
-                addend = m_graph.valueOfInt32Constant(index.node());
+                addend = index->asInt32();
             } else if (
                 index->op() == ArithAdd
                 && index->isBinaryUseKind(Int32Use)
-                && m_graph.isInt32Constant(index->child2().node())) {
+                && index->child2()->isInt32Constant()) {
                 source = index->child1();
-                addend = m_graph.valueOfInt32Constant(index->child2().node());
+                addend = index->child2()->asInt32();
             } else {
                 source = index;
                 addend = 0;
@@ -341,7 +341,7 @@ private:
             
             return RangeKeyAndAddend(RangeKey::arrayBounds(source, key), addend);
         }
-                
+            
         default:
             break;
         }
@@ -355,8 +355,17 @@ private:
             return false;
         
         switch (key.m_kind) {
-        case ArrayBounds:
-            return (range.m_maxBound - range.m_minBound) >= 0;
+        case ArrayBounds: {
+            // Have to do this carefully because C++ compilers are too smart. But all we're really doing is detecting if
+            // the difference between the bounds is 2^31 or more. If it was, then we'd have to worry about wrap-around.
+            // The way we'd like to write this expression is (range.m_maxBound - range.m_minBound) >= 0, but that is a
+            // signed subtraction and compare, which allows the C++ compiler to do anything it wants in case of
+            // wrap-around.
+            uint32_t maxBound = range.m_maxBound;
+            uint32_t minBound = range.m_minBound;
+            uint32_t unsignedDifference = maxBound - minBound;
+            return !(unsignedDifference >> 31);
+        }
             
         default:
             return true;
@@ -376,15 +385,6 @@ private:
                 nodeIndex, origin, jsNumber(addend), source.useKind()));
     }
     
-    Node* insertMustAdd(
-        unsigned nodeIndex, NodeOrigin origin, Edge source, int32_t addend)
-    {
-        Node* result = insertAdd(nodeIndex, origin, source, addend);
-        m_insertionSet.insertNode(
-            nodeIndex, SpecNone, HardPhantom, origin, result->defaultEdge());
-        return result;
-    }
-    
     typedef std::unordered_map<RangeKey, Range, HashMethod<RangeKey>> RangeMap;
     RangeMap m_map;
     
diff --git a/dfg/DFGIntegerRangeOptimizationPhase.cpp b/dfg/DFGIntegerRangeOptimizationPhase.cpp
new file mode 100644 (file)
index 0000000..c47dbc3
--- /dev/null
@@ -0,0 +1,1337 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGIntegerRangeOptimizationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMapInlines.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+const bool verbose = false;
+
+int64_t clampedSumImpl() { return 0; }
+
+template<typename... Args>
+int64_t clampedSumImpl(int left, Args... args)
+{
+    return static_cast<int64_t>(left) + clampedSumImpl(args...);
+}
+
+template<typename... Args>
+int clampedSum(Args... args)
+{
+    int64_t result = clampedSumImpl(args...);
+    return static_cast<int>(std::min(
+        static_cast<int64_t>(std::numeric_limits<int>::max()),
+        std::max(
+            static_cast<int64_t>(std::numeric_limits<int>::min()),
+            result)));
+}
+
+class Relationship {
+public:
+    enum Kind {
+        LessThan,
+        Equal,
+        NotEqual,
+        GreaterThan
+    };
+    
+    static Kind flipped(Kind kind)
+    {
+        switch (kind) {
+        case LessThan:
+            return GreaterThan;
+        case Equal:
+            return Equal;
+        case NotEqual:
+            return NotEqual;
+        case GreaterThan:
+            return LessThan;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return kind;
+    }
+    
+    Relationship()
+        : m_left(nullptr)
+        , m_right(nullptr)
+        , m_kind(Equal)
+        , m_offset(0)
+    {
+    }
+    
+    Relationship(Node* left, Node* right, Kind kind, int offset = 0)
+        : m_left(left)
+        , m_right(right)
+        , m_kind(kind)
+        , m_offset(offset)
+    {
+        RELEASE_ASSERT(m_left);
+        RELEASE_ASSERT(m_right);
+        RELEASE_ASSERT(m_left != m_right);
+    }
+    
+    static Relationship safeCreate(Node* left, Node* right, Kind kind, int offset = 0)
+    {
+        if (!left || !right || left == right)
+            return Relationship();
+        return Relationship(left, right, kind, offset);
+    }
+    
+    typedef void* (Relationship::*UnspecifiedBoolType);
+
+    explicit operator bool() const { return m_left; }
+    
+    Node* left() const { return m_left; }
+    Node* right() const { return m_right; }
+    Kind kind() const { return m_kind; }
+    int offset() const { return m_offset; }
+    
+    Relationship flipped() const
+    {
+        if (!*this)
+            return Relationship();
+        
+        // This should return Relationship() if -m_offset overflows. For example:
+        //
+        //     @a > @b - 2**31
+        //
+        // If we flip it we get:
+        //
+        //     @b < @a + 2**31
+        //
+        // Except that the sign gets flipped since it's INT_MIN:
+        //
+        //     @b < @a - 2**31
+        //
+        // And that makes no sense. To see how little sense it makes, consider:
+        //
+        //     @a > @zero - 2**31
+        //
+        // We would flip it to mean:
+        //
+        //     @zero < @a - 2**31
+        //
+        // Which is absurd.
+        
+        if (m_offset == std::numeric_limits<int>::min())
+            return Relationship();
+        
+        return Relationship(m_right, m_left, flipped(m_kind), -m_offset);
+    }
+    
+    Relationship inverse() const
+    {
+        if (!*this)
+            return *this;
+        
+        switch (m_kind) {
+        case Equal:
+            return Relationship(m_left, m_right, NotEqual, m_offset);
+        case NotEqual:
+            return Relationship(m_left, m_right, Equal, m_offset);
+        case LessThan:
+            if (sumOverflows<int>(m_offset, -1))
+                return Relationship();
+            return Relationship(m_left, m_right, GreaterThan, m_offset - 1);
+        case GreaterThan:
+            if (sumOverflows<int>(m_offset, 1))
+                return Relationship();
+            return Relationship(m_left, m_right, LessThan, m_offset + 1);
+        }
+        
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    bool isCanonical() const { return m_left < m_right; }
+    
+    Relationship canonical() const
+    {
+        if (isCanonical())
+            return *this;
+        return flipped();
+    }
+    
+    bool sameNodesAs(const Relationship& other) const
+    {
+        return m_left == other.m_left
+            && m_right == other.m_right;
+    }
+    
+    bool operator==(const Relationship& other) const
+    {
+        return sameNodesAs(other)
+            && m_kind == other.m_kind
+            && m_offset == other.m_offset;
+    }
+    
+    bool operator!=(const Relationship& other) const
+    {
+        return !(*this == other);
+    }
+    
+    bool operator<(const Relationship& other) const
+    {
+        if (m_left != other.m_left)
+            return m_left < other.m_left;
+        if (m_right != other.m_right)
+            return m_right < other.m_right;
+        if (m_kind != other.m_kind)
+            return m_kind < other.m_kind;
+        return m_offset < other.m_offset;
+    }
+    
+    // If possible, returns a form of this relationship where the given node is the left
+    // side. Returns a null relationship if this relationship cannot say anything about this
+    // node.
+    Relationship forNode(Node* node) const
+    {
+        if (m_left == node)
+            return *this;
+        if (m_right == node)
+            return flipped();
+        return Relationship();
+    }
+    
+    void setLeft(Node* left)
+    {
+        RELEASE_ASSERT(left != m_right);
+        m_left = left;
+    }
+    bool addToOffset(int offset)
+    {
+        if (sumOverflows<int>(m_offset, offset))
+            return false;
+        m_offset += offset;
+        return true;
+    }
+
+    // Attempts to create a relationship that summarizes the union of this relationship and
+    // the other relationship. The null relationship is returned to indicate TOP. This is used
+    // for merging the current relationship-at-head for some pair of nodes and a new
+    // relationship-at-head being proposed by a predecessor. We wish to create a new
+    // relationship that is true whenever either of them are true, which ensuring that we don't
+    // do this forever. Anytime we create a relationship that is not equal to either of the
+    // previous ones, we will cause the analysis fixpoint to reexecute.
+    //
+    // If *this and other are identical, we just return it.
+    //
+    // If they are different, we pick from a finite set of "general" relationships:
+    //
+    // Eq: this == other + C, where C is -1, 0, or 1.
+    // Lt: this < other + C, where C is -1, 0, or 1.
+    // Gt: this > other + C, where C is -1, 0, or 1.
+    // Ne: this != other + C, where C is -1, 0, or 1.
+    // TOP: the null relationship.
+    //
+    // Constraining C to -1,0,1 is necessary to ensure that the set of general relationships is
+    // finite. This finite set of relationships forms a pretty simple lattice where a
+    // relA->relB means "relB is more general than relA". For example, this<other+1 is more
+    // general than this==other. I'll leave it as an exercise for the reader to see that a
+    // graph between the 13 general relationships is indeed a lattice. The fact that the set of
+    // general relationships is a finite lattice ensures monotonicity of the fixpoint, since
+    // any merge over not-identical relationships returns a relationship that is closer to the
+    // TOP relationship than either of the original relationships. Here's how convergence is
+    // achieved for any pair of relationships over the same nodes:
+    //
+    // - If they are identical, then returning *this means that we won't be responsible for
+    //   causing another fixpoint iteration. Once all merges reach this point, we're done.
+    //
+    // - If they are different, then we pick the most constraining of the 13 general
+    //   relationships that is true if either *this or other are true. This means that if the
+    //   relationships are not identical, the merged relationship will be closer to TOP than
+    //   either of the originals. Returning a different relationship means that we will be
+    //   responsible for the fixpoint to reloop, but we can only do this at most 13 times since
+    //   that's how "deep" the general relationship lattice is.
+    //
+    // Note that C being constrained to -1,0,1 also ensures that we never have to return a
+    // combination of Lt and Gt, as in for example this<other+C && this>other-D. That's why
+    // this function can return zero or one relationships rather than a list of relationships.
+    // The only possible values of C and D where this would work are -1 and 1, but in that case
+    // we just say this==other. That said, the logic for merging two == relationships, like
+    // this==other+C || this==other+D is to attempt to create these two relationships:
+    // this>other+min(C,D)-1 && this<other+max(C,D)+1. But only one of these relationships will
+    // belong to the set of general relationships.
+    //
+    // Here's an example of this in action:
+    //
+    // for (var i = a; ; ++i) { }
+    //
+    // Without C being constrained to -1,0,1, we could end up looping forever: first we'd say
+    // that i==a, then we might say that i<a+2, then i<a+3, then i<a+4, etc. We won't do this
+    // because i<a+2 is not a valid general relationship: so when we merge i==a from the first
+    // iteration and i==a+1 from the second iteration, we create i>a-1 and i<a+2 but then
+    // realize that only i>a-1 is a valid general relationship. This gives us exactly what we
+    // want: a statement that i>=a.
+    Relationship merge(const Relationship& other) const
+    {
+        if (!sameNodesAs(other))
+            return Relationship();
+        
+        // Handle the super obvious case first.
+        if (*this == other)
+            return *this;
+        
+        // This does some interesting permutations to reduce the amount of duplicate code. For
+        // example:
+        //
+        // initially: @a != @b, @a > @b
+        //            @b != @a, @b < @a
+        //            @b < @a, @b != @a
+        //   finally: @b != a, @b < @a
+        //
+        // Another example:
+        //
+        // initially: @a < @b, @a != @b
+        //   finally: @a != @b, @a < @b
+
+        Relationship a = *this;
+        Relationship b = other;
+        bool needFlip = false;
+        
+        // Get rid of GreaterThan.
+        if (a.m_kind == GreaterThan || b.m_kind == GreaterThan) {
+            a = a.flipped();
+            b = b.flipped();
+            
+            // In rare cases, we might not be able to flip. Just give up on life in those
+            // cases.
+            if (!a || !b)
+                return Relationship();
+            
+            needFlip = true;
+            
+            // If we still have GreaterThan, then it means that we started with @a < @b and
+            // @a > @b. That's pretty much always a tautology; we don't attempt to do smart
+            // things for that case for now.
+            if (a.m_kind == GreaterThan || b.m_kind == GreaterThan)
+                return Relationship();
+        }
+        
+        // Make sure that if we have a LessThan, then it's first.
+        if (b.m_kind == LessThan)
+            std::swap(a, b);
+        
+        // Make sure that if we have a NotEqual, then it's first.
+        if (b.m_kind == NotEqual)
+            std::swap(a, b);
+        
+        Relationship result = a.mergeImpl(b);
+        
+        if (needFlip)
+            return result.flipped();
+        
+        return result;
+    }
+    
+    // Attempts to construct one Relationship that adequately summarizes the intersection of
+    // this and other. Returns a null relationship if the filtration should be expressed as two
+    // different relationships. Returning null is always safe because relationship lists in
+    // this phase always imply intersection. So, you could soundly skip calling this method and
+    // just put both relationships into the list. But, that could lead the fixpoint to diverge.
+    // Hence this will attempt to combine the two relationships into one as a convergence hack.
+    // In some cases, it will do something conservative. It's always safe for this to return
+    // *this, or to return other. It'll do that sometimes, mainly to accelerate convergence for
+    // things that we don't think are important enough to slow down the analysis.
+    Relationship filter(const Relationship& other) const
+    {
+        // We are only interested in merging relationships over the same nodes.
+        ASSERT(sameNodesAs(other));
+        
+        if (*this == other)
+            return *this;
+        
+        // From here we can assume that the two relationships are not identical. Usually we use
+        // this to assume that we have different offsets anytime that everything but the offset
+        // is identical.
+        
+        // We want equality to take precedent over everything else, and we don't want multiple
+        // independent claims of equality. That would just be a contradiction. When it does
+        // happen, we will be conservative in the sense that we will pick one.
+        if (m_kind == Equal)
+            return *this;
+        if (other.m_kind == Equal)
+            return other;
+        
+        // Useful helper for flipping.
+        auto filterFlipped = [&] () -> Relationship {
+            // If we cannot flip, then just conservatively return *this.
+            Relationship a = flipped();
+            Relationship b = other.flipped();
+            if (!a || !b)
+                return *this;
+            Relationship result = a.filter(b);
+            if (!result)
+                return Relationship();
+            result = result.flipped();
+            if (!result)
+                return *this;
+            return result;
+        };
+        
+        if (m_kind == NotEqual) {
+            if (other.m_kind == NotEqual) {
+                // We could do something smarter here. We could even keep both NotEqual's. We
+                // would need to make sure that we correctly collapsed them when merging. But
+                // for now, we just pick one of them and hope for the best.
+                return *this;
+            }
+            
+            if (other.m_kind == GreaterThan) {
+                // Implement this in terms of NotEqual.filter(LessThan). 
+                return filterFlipped();
+            }
+            
+            ASSERT(other.m_kind == LessThan);
+            // We have two claims:
+            //     @a != @b + C
+            //     @a  < @b + D
+            //
+            // If C >= D, then the NotEqual is redundant.
+            // If C < D - 1, then we could keep both, but for now we just keep the LessThan.
+            // If C == D - 1, then the LessThan can be turned into:
+            //
+            //     @a < @b + C
+            //
+            // Note that C == this.m_offset, D == other.m_offset.
+            
+            if (m_offset == other.m_offset - 1)
+                return Relationship(m_left, m_right, LessThan, m_offset);
+            
+            return other;
+        }
+        
+        if (other.m_kind == NotEqual)
+            return other.filter(*this);
+        
+        if (m_kind == LessThan) {
+            if (other.m_kind == LessThan) {
+                return Relationship(
+                    m_left, m_right, LessThan, std::min(m_offset, other.m_offset));
+            }
+            
+            ASSERT(other.m_kind == GreaterThan);
+            if (sumOverflows<int>(m_offset, -1))
+                return Relationship();
+            if (sumOverflows<int>(other.m_offset, 1))
+                return Relationship();
+            if (m_offset - 1 == other.m_offset + 1)
+                return Relationship(m_left, m_right, Equal, m_offset - 1);
+            
+            return Relationship();
+        }
+        
+        ASSERT(m_kind == GreaterThan);
+        return filterFlipped();
+    }
+    
+    int minValueOfLeft() const
+    {
+        if (m_left->isInt32Constant())
+            return m_left->asInt32();
+        
+        if (m_kind == LessThan || m_kind == NotEqual)
+            return std::numeric_limits<int>::min();
+        
+        int minRightValue = std::numeric_limits<int>::min();
+        if (m_right->isInt32Constant())
+            minRightValue = m_right->asInt32();
+        
+        if (m_kind == GreaterThan)
+            return clampedSum(minRightValue, m_offset, 1);
+        ASSERT(m_kind == Equal);
+        return clampedSum(minRightValue, m_offset);
+    }
+    
+    int maxValueOfLeft() const
+    {
+        if (m_left->isInt32Constant())
+            return m_left->asInt32();
+        
+        if (m_kind == GreaterThan || m_kind == NotEqual)
+            return std::numeric_limits<int>::max();
+        
+        int maxRightValue = std::numeric_limits<int>::max();
+        if (m_right->isInt32Constant())
+            maxRightValue = m_right->asInt32();
+        
+        if (m_kind == LessThan)
+            return clampedSum(maxRightValue, m_offset, -1);
+        ASSERT(m_kind == Equal);
+        return clampedSum(maxRightValue, m_offset);
+    }
+    
+    void dump(PrintStream& out) const
+    {
+        // This prints out the relationship without any whitespace, like @x<@y+42. This
+        // optimizes for the clarity of a list of relationships. It's easier to read something
+        // like [@1<@2+3, @4==@5-6] than it would be if there was whitespace inside the
+        // relationships.
+        
+        if (!*this) {
+            out.print("null");
+            return;
+        }
+        
+        out.print(m_left);
+        switch (m_kind) {
+        case LessThan:
+            out.print("<");
+            break;
+        case Equal:
+            out.print("==");
+            break;
+        case NotEqual:
+            out.print("!=");
+            break;
+        case GreaterThan:
+            out.print(">");
+            break;
+        }
+        out.print(m_right);
+        if (m_offset > 0)
+            out.print("+", m_offset);
+        else if (m_offset < 0)
+            out.print("-", -static_cast<int64_t>(m_offset));
+    }
+    
+private:
+    Relationship mergeImpl(const Relationship& other) const
+    {
+        ASSERT(sameNodesAs(other));
+        ASSERT(m_kind != GreaterThan);
+        ASSERT(other.m_kind != GreaterThan);
+        ASSERT(*this != other);
+        
+        // The purpose of this method is to guarantee that:
+        //
+        // - We avoid having more than one Relationship over the same two nodes. Therefore, if
+        //   the merge could be expressed as two Relationships, we prefer to instead pick the
+        //   less precise single Relationship form even if that means TOP.
+        //
+        // - If the difference between two Relationships is just the m_offset, then we create a
+        //   Relationship that has an offset of -1, 0, or 1. This is an essential convergence
+        //   hack. We need -1 and 1 to support <= and >=.
+        
+        // From here we can assume that the two relationships are not identical. Usually we use
+        // this to assume that we have different offsets anytime that everything but the offset
+        // is identical.
+        
+        if (m_kind == NotEqual) {
+            if (other.m_kind == NotEqual)
+                return Relationship(); // Different offsets, so tautology.
+            
+            if (other.m_kind == Equal) {
+                if (m_offset != other.m_offset) {
+                    // Saying that you might be B when you've already said that you're anything
+                    // but A, where A and B are different, is a tautology. You could just say
+                    // that you're anything but A. Adding "(a == b + 1)" to "(a != b + 5)" has
+                    // no value.
+                    return *this;
+                }
+                // Otherwise, same offsets: we're saying that you're either A or you're not
+                // equal to A.
+                
+                return Relationship();
+            }
+            
+            RELEASE_ASSERT(other.m_kind == LessThan);
+            // We have these claims, and we're merging them:
+            //     @a != @b + C
+            //     @a < @b + D
+            //
+            // If we have C == D, then the merge is clearly just the NotEqual.
+            // If we have C < D, then the merge is a tautology.
+            // If we have C > D, then we could keep both claims, but we are cheap, so we
+            // don't. We just use the NotEqual.
+            
+            if (m_offset < other.m_offset)
+                return Relationship();
+            
+            return *this;
+        }
+        
+        if (m_kind == LessThan) {
+            if (other.m_kind == LessThan) {
+                // Figure out what offset to select to merge them. The appropriate offsets are
+                // -1, 0, or 1.
+                
+                // First figure out what offset we'd like to use.
+                int bestOffset = std::max(m_offset, other.m_offset);
+                
+                // We have something like @a < @b + 2. We can't represent this under the
+                // -1,0,1 rule.
+                if (bestOffset <= 1)
+                    return Relationship(m_left, m_right, LessThan, std::max(bestOffset, -1));
+                
+                return Relationship();
+            }
+            
+            // The only thing left is Equal. We would have eliminated the GreaterThan's, and
+            // if we merge LessThan and NotEqual, the NotEqual always comes first.
+            RELEASE_ASSERT(other.m_kind == Equal);
+            
+            // This is the really interesting case. We have:
+            //
+            //     @a < @b + C
+            //
+            // and:
+            //
+            //     @a == @b + D
+            //
+            // Therefore we'd like to return:
+            //
+            //     @a < @b + max(C, D + 1)
+            
+            int bestOffset = std::max(m_offset, other.m_offset + 1);
+            
+            // We have something like @a < @b + 2. We can't do it.
+            if (bestOffset <= 1)
+                return Relationship(m_left, m_right, LessThan, std::max(bestOffset, -1));
+
+            return Relationship();
+        }
+        
+        // The only thing left is Equal, since we would have gotten rid of the GreaterThan's.
+        RELEASE_ASSERT(m_kind == Equal);
+        
+        // We would never see NotEqual, because those always come first. We would never
+        // see GreaterThan, because we would have eliminated those. We would never see
+        // LessThan, because those always come first.
+        
+        RELEASE_ASSERT(other.m_kind == Equal);
+        // We have @a == @b + C and @a == @b + D, where C != D. Turn this into some
+        // inequality that involves a constant that is -1,0,1. Note that we will never have
+        // lessThan and greaterThan because the constants are constrained to -1,0,1. The only
+        // way for both of them to be valid is a<b+1 and a>b-1, but then we would have said
+        // a==b.
+
+        Relationship lessThan;
+        Relationship greaterThan;
+        
+        int lessThanEqOffset = std::max(m_offset, other.m_offset);
+        if (lessThanEqOffset >= -2 && lessThanEqOffset <= 0) {
+            lessThan = Relationship(
+                m_left, other.m_right, LessThan, lessThanEqOffset + 1);
+            
+            ASSERT(lessThan.offset() >= -1 && lessThan.offset() <= 1);
+        }
+        
+        int greaterThanEqOffset = std::min(m_offset, other.m_offset);
+        if (greaterThanEqOffset >= 0 && greaterThanEqOffset <= 2) {
+            greaterThan = Relationship(
+                m_left, other.m_right, GreaterThan, greaterThanEqOffset - 1);
+            
+            ASSERT(greaterThan.offset() >= -1 && greaterThan.offset() <= 1);
+        }
+        
+        if (lessThan) {
+            // Both relationships cannot be valid; see above.
+            RELEASE_ASSERT(!greaterThan);
+            
+            return lessThan;
+        }
+        
+        return greaterThan;
+    }
+    
+    Node* m_left;
+    Node* m_right;
+    Kind m_kind;
+    int m_offset; // This offset can be arbitrarily large.
+};
+
+typedef HashMap<Node*, Vector<Relationship>> RelationshipMap;
+
+class IntegerRangeOptimizationPhase : public Phase {
+public:
+    IntegerRangeOptimizationPhase(Graph& graph)
+        : Phase(graph, "integer range optimization")
+        , m_zero(nullptr)
+        , m_relationshipsAtHead(graph)
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        ASSERT(m_graph.m_form == SSA);
+        
+        // Before we do anything, make sure that we have a zero constant at the top.
+        for (Node* node : *m_graph.block(0)) {
+            if (node->isInt32Constant() && !node->asInt32()) {
+                m_zero = node;
+                break;
+            }
+        }
+        if (!m_zero) {
+            m_zero = m_insertionSet.insertConstant(0, NodeOrigin(), jsNumber(0));
+            m_insertionSet.execute(m_graph.block(0));
+        }
+        
+        if (verbose) {
+            dataLog("Graph before integer range optimization:\n");
+            m_graph.dump();
+        }
+        
+        // This performs a fixpoint over the blocks in reverse post-order. Logically, we
+        // maintain a list of relationships at each point in the program. The list should be
+        // read as an intersection. For example if we have {rel1, rel2, ..., relN}, you should
+        // read this as:
+        //
+        //     TOP && rel1 && rel2 && ... && relN
+        //
+        // This allows us to express things like:
+        //
+        //     @a > @b - 42 && @a < @b + 25
+        //
+        // But not things like:
+        //
+        //     @a < @b - 42 || @a > @b + 25
+        //
+        // We merge two lists by merging each relationship in one list with each relationship
+        // in the other list. Merging two relationships will yield a relationship list; as with
+        // all such lists it is an intersction. Merging relationships over different variables
+        // always yields the empty list (i.e. TOP). This merge style is sound because if we
+        // have:
+        //
+        //     (A && B && C) || (D && E && F)
+        //
+        // Then a valid merge is just one that will return true if A, B, C are all true, or
+        // that will return true if D, E, F are all true. Our merge style essentially does:
+        //
+        //     (A || D) && (A || E) && (A || F) && (B || D) && (B || E) && (B || F) &&
+        //         (C || D) && (C || E) && (C || F)
+        //
+        // If A && B && C is true, then this returns true. If D && E && F is true, this also
+        // returns true.
+        //
+        // While this appears at first like a kind of expression explosion, in practice it
+        // isn't. The code that handles this knows that the merge of two relationships over
+        // different variables is TOP (i.e. the empty list). For example if A above is @a < @b
+        // and B above is @c > @d, where @a, @b, @c, and @d are different nodes, the merge will
+        // yield nothing. In fact, the merge algorithm will skip such merges entirely because
+        // the relationship lists are actually keyed by node.
+        //
+        // Note that it's always safe to drop any of relationship from the relationship list.
+        // This merely increases the likelihood of the "expression" yielding true, i.e. being
+        // closer to TOP. Optimizations are only performed if we can establish that the
+        // expression implied by the relationship list is false for all of those cases where
+        // some check would have failed.
+        //
+        // There is no notion of BOTTOM because we treat blocks that haven't had their
+        // state-at-head set as a special case: we just transfer all live relationships to such
+        // a block. After the head of a block is set, we perform the merging as above. In all
+        // other places where we would ordinarily need BOTTOM, we approximate it by having some
+        // non-BOTTOM relationship.
+        
+        BlockList postOrder = m_graph.blocksInPostOrder();
+
+        // This loop analyzes the IR to give us m_relationshipsAtHead for each block. This
+        // may reexecute blocks many times, but it is guaranteed to converge. The state of
+        // the relationshipsAtHead over any pair of nodes converge monotonically towards the
+        // TOP relationship (i.e. no relationships in the relationship list). The merge rule
+        // when between the current relationshipsAtHead and the relationships being propagated
+        // from a predecessor ensures monotonicity by converting disagreements into one of a
+        // small set of "general" relationships. There are 12 such relationshis, plus TOP. See
+        // the comment above Relationship::merge() for details.
+        bool changed = true;
+        while (changed) {
+            changed = false;
+            for (unsigned postOrderIndex = postOrder.size(); postOrderIndex--;) {
+                BasicBlock* block = postOrder[postOrderIndex];
+                DFG_ASSERT(
+                    m_graph, nullptr,
+                    block == m_graph.block(0) || m_seenBlocks.contains(block));
+            
+                m_relationships = m_relationshipsAtHead[block];
+            
+                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                    Node* node = block->at(nodeIndex);
+                    if (verbose)
+                        dataLog("Analysis: at ", node, ": ", listDump(sortedRelationships()), "\n");
+                    executeNode(node);
+                }
+                
+                // Now comes perhaps the most important piece of cleverness: if we Branch, and
+                // the predicate involves some relation over integers, we propagate different
+                // information to the taken and notTaken paths. This handles:
+                // - Branch on int32.
+                // - Branch on LogicalNot on int32.
+                // - Branch on compare on int32's.
+                // - Branch on LogicalNot of compare on int32's.
+                Node* terminal = block->terminal();
+                bool alreadyMerged = false;
+                if (terminal->op() == Branch) {
+                    Relationship relationshipForTrue;
+                    BranchData* branchData = terminal->branchData();
+                    
+                    bool invert = false;
+                    if (terminal->child1()->op() == LogicalNot) {
+                        terminal = terminal->child1().node();
+                        invert = true;
+                    }
+                    
+                    if (terminal->child1().useKind() == Int32Use) {
+                        relationshipForTrue = Relationship::safeCreate(
+                            terminal->child1().node(), m_zero, Relationship::NotEqual, 0);
+                    } else {
+                        Node* compare = terminal->child1().node();
+                        switch (compare->op()) {
+                        case CompareEq:
+                        case CompareStrictEq:
+                        case CompareLess:
+                        case CompareLessEq:
+                        case CompareGreater:
+                        case CompareGreaterEq: {
+                            if (!compare->isBinaryUseKind(Int32Use))
+                                break;
+                    
+                            switch (compare->op()) {
+                            case CompareEq:
+                            case CompareStrictEq:
+                                relationshipForTrue = Relationship::safeCreate(
+                                    compare->child1().node(), compare->child2().node(),
+                                    Relationship::Equal, 0);
+                                break;
+                            case CompareLess:
+                                relationshipForTrue = Relationship::safeCreate(
+                                    compare->child1().node(), compare->child2().node(),
+                                    Relationship::LessThan, 0);
+                                break;
+                            case CompareLessEq:
+                                relationshipForTrue = Relationship::safeCreate(
+                                    compare->child1().node(), compare->child2().node(),
+                                    Relationship::LessThan, 1);
+                                break;
+                            case CompareGreater:
+                                relationshipForTrue = Relationship::safeCreate(
+                                    compare->child1().node(), compare->child2().node(),
+                                    Relationship::GreaterThan, 0);
+                                break;
+                            case CompareGreaterEq:
+                                relationshipForTrue = Relationship::safeCreate(
+                                    compare->child1().node(), compare->child2().node(),
+                                    Relationship::GreaterThan, -1);
+                                break;
+                            default:
+                                DFG_CRASH(m_graph, compare, "Invalid comparison node type");
+                                break;
+                            }
+                            break;
+                        }
+                    
+                        default:
+                            break;
+                        }
+                    }
+                    
+                    if (invert)
+                        relationshipForTrue = relationshipForTrue.inverse();
+                    
+                    if (relationshipForTrue) {
+                        RelationshipMap forTrue = m_relationships;
+                        RelationshipMap forFalse = m_relationships;
+                        
+                        if (verbose)
+                            dataLog("Dealing with true:\n");
+                        setRelationship(forTrue, relationshipForTrue);
+                        if (Relationship relationshipForFalse = relationshipForTrue.inverse()) {
+                            if (verbose)
+                                dataLog("Dealing with false:\n");
+                            setRelationship(forFalse, relationshipForFalse);
+                        }
+                        
+                        changed |= mergeTo(forTrue, branchData->taken.block);
+                        changed |= mergeTo(forFalse, branchData->notTaken.block);
+                        alreadyMerged = true;
+                    }
+                }
+
+                if (!alreadyMerged) {
+                    for (BasicBlock* successor : block->successors())
+                        changed |= mergeTo(m_relationships, successor);
+                }
+            }
+        }
+        
+        // Now we transform the code based on the results computed in the previous loop.
+        changed = false;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            m_relationships = m_relationshipsAtHead[block];
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                if (verbose)
+                    dataLog("Transformation: at ", node, ": ", listDump(sortedRelationships()), "\n");
+                
+                // This ends up being pretty awkward to write because we need to decide if we
+                // optimize by using the relationships before the operation, but we need to
+                // call executeNode() before we optimize.
+                switch (node->op()) {
+                case ArithAdd: {
+                    if (!node->isBinaryUseKind(Int32Use))
+                        break;
+                    if (node->arithMode() != Arith::CheckOverflow)
+                        break;
+                    if (!node->child2()->isInt32Constant())
+                        break;
+                    
+                    auto iter = m_relationships.find(node->child1().node());
+                    if (iter == m_relationships.end())
+                        break;
+                    
+                    int minValue = std::numeric_limits<int>::min();
+                    int maxValue = std::numeric_limits<int>::max();
+                    for (Relationship relationship : iter->value) {
+                        minValue = std::max(minValue, relationship.minValueOfLeft());
+                        maxValue = std::min(maxValue, relationship.maxValueOfLeft());
+                    }
+                    
+                    if (sumOverflows<int>(minValue, node->child2()->asInt32()) ||
+                        sumOverflows<int>(maxValue, node->child2()->asInt32()))
+                        break;
+                    
+                    executeNode(block->at(nodeIndex));
+                    node->setArithMode(Arith::Unchecked);
+                    changed = true;
+                    break;
+                }
+                    
+                case CheckInBounds: {
+                    auto iter = m_relationships.find(node->child1().node());
+                    if (iter == m_relationships.end())
+                        break;
+                    
+                    bool nonNegative = false;
+                    bool lessThanLength = false;
+                    for (Relationship relationship : iter->value) {
+                        if (relationship.minValueOfLeft() >= 0)
+                            nonNegative = true;
+                        
+                        if (relationship.right() == node->child2()) {
+                            if (relationship.kind() == Relationship::Equal
+                                && relationship.offset() < 0)
+                                lessThanLength = true;
+                            
+                            if (relationship.kind() == Relationship::LessThan
+                                && relationship.offset() <= 0)
+                                lessThanLength = true;
+                        }
+                    }
+                    
+                    if (nonNegative && lessThanLength) {
+                        executeNode(block->at(nodeIndex));
+                        node->remove();
+                        changed = true;
+                    }
+                    break;
+                }
+                    
+                default:
+                    break;
+                }
+                
+                executeNode(block->at(nodeIndex));
+            }
+        }
+        
+        return changed;
+    }
+
+private:
+    void executeNode(Node* node)
+    {
+        switch (node->op()) {
+        case CheckInBounds: {
+            setRelationship(Relationship::safeCreate(node->child1().node(), node->child2().node(), Relationship::LessThan));
+            setRelationship(Relationship::safeCreate(node->child1().node(), m_zero, Relationship::GreaterThan, -1));
+            break;
+        }
+            
+        case ArithAdd: {
+            // We're only interested in int32 additions and we currently only know how to
+            // handle the non-wrapping ones.
+            if (!node->isBinaryUseKind(Int32Use))
+                break;
+            
+            // FIXME: We could handle the unchecked arithmetic case. We just do it don't right
+            // now.
+            if (node->arithMode() != Arith::CheckOverflow)
+                break;
+            
+            // Handle add: @value + constant.
+            if (!node->child2()->isInt32Constant())
+                break;
+            
+            int offset = node->child2()->asInt32();
+            
+            // We add a relationship for @add == @value + constant, and then we copy the
+            // relationships for @value. This gives us a one-deep view of @value's existing
+            // relationships, which matches the one-deep search in setRelationship().
+            
+            setRelationship(
+                Relationship(node, node->child1().node(), Relationship::Equal, offset));
+            
+            auto iter = m_relationships.find(node->child1().node());
+            if (iter != m_relationships.end()) {
+                Vector<Relationship> toAdd;
+                for (Relationship relationship : iter->value) {
+                    // We have:
+                    //     add: ArithAdd(@x, C)
+                    //     @x op @y + D
+                    //
+                    // The following certainly holds:
+                    //     @x == @add - C
+                    //
+                    // Which allows us to substitute:
+                    //     @add - C op @y + D
+                    //
+                    // And then carry the C over:
+                    //     @add op @y + D + C
+                    
+                    Relationship newRelationship = relationship;
+                    ASSERT(newRelationship.left() == node->child1().node());
+                    
+                    if (newRelationship.right() == node)
+                        continue;
+                    newRelationship.setLeft(node);
+                    if (newRelationship.addToOffset(offset))
+                        toAdd.append(newRelationship);
+                }
+                for (Relationship relationship : toAdd)
+                    setRelationship(relationship, 0);
+            }
+            
+            // Now we want to establish that both the input and the output of the addition are
+            // within a particular range of integers.
+            
+            if (offset > 0) {
+                // If we have "add: @value + 1" then we know that @value <= max - 1, i.e. that
+                // @value < max.
+                if (!sumOverflows<int>(std::numeric_limits<int>::max(), -offset, 1)) {
+                    setRelationship(
+                        Relationship::safeCreate(
+                            node->child1().node(), m_zero, Relationship::LessThan,
+                            std::numeric_limits<int>::max() - offset + 1),
+                        0);
+                }
+                    
+                // If we have "add: @value + 1" then we know that @add >= min + 1, i.e. that
+                // @add > min.
+                if (!sumOverflows<int>(std::numeric_limits<int>::min(), offset, -1)) {
+                    setRelationship(
+                        Relationship(
+                            node, m_zero, Relationship::GreaterThan,
+                            std::numeric_limits<int>::min() + offset - 1),
+                        0);
+                }
+            }
+            
+            if (offset < 0 && offset != std::numeric_limits<int>::min()) {
+                // If we have "add: @value - 1" then we know that @value >= min + 1, i.e. that
+                // @value > min.
+                if (!sumOverflows<int>(std::numeric_limits<int>::min(), offset, -1)) {
+                    setRelationship(
+                        Relationship::safeCreate(
+                            node->child1().node(), m_zero, Relationship::GreaterThan,
+                            std::numeric_limits<int>::min() + offset - 1),
+                        0);
+                }
+                
+                // If we have "add: @value + 1" then we know that @add <= max - 1, i.e. that
+                // @add < max.
+                if (!sumOverflows<int>(std::numeric_limits<int>::max(), -offset, 1)) {
+                    setRelationship(
+                        Relationship(
+                            node, m_zero, Relationship::LessThan,
+                            std::numeric_limits<int>::max() - offset + 1),
+                        0);
+                }
+            }
+            break;
+        }
+            
+        case GetArrayLength: {
+            setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1));
+            break;
+        }
+            
+        case Upsilon: {
+            setRelationship(
+                Relationship::safeCreate(
+                    node->child1().node(), node->phi(), Relationship::Equal, 0));
+            
+            auto iter = m_relationships.find(node->child1().node());
+            if (iter != m_relationships.end()) {
+                Vector<Relationship> toAdd;
+                for (Relationship relationship : iter->value) {
+                    Relationship newRelationship = relationship;
+                    if (node->phi() == newRelationship.right())
+                        continue;
+                    newRelationship.setLeft(node->phi());
+                    toAdd.append(newRelationship);
+                }
+                for (Relationship relationship : toAdd)
+                    setRelationship(relationship);
+            }
+            break;
+        }
+            
+        default:
+            break;
+        }
+    }
+    
+    void setRelationship(Relationship relationship, unsigned timeToLive = 1)
+    {
+        setRelationship(m_relationships, relationship, timeToLive);
+    }
+    
+    void setRelationship(
+        RelationshipMap& relationshipMap, Relationship relationship, unsigned timeToLive = 1)
+    {
+        setOneSide(relationshipMap, relationship, timeToLive);
+        setOneSide(relationshipMap, relationship.flipped(), timeToLive);
+    }
+    
+    void setOneSide(
+        RelationshipMap& relationshipMap, Relationship relationship, unsigned timeToLive = 1)
+    {
+        if (!relationship)
+            return;
+        
+        if (verbose)
+            dataLog("    Setting: ", relationship, " (ttl = ", timeToLive, ")\n");
+
+        auto result = relationshipMap.add(
+            relationship.left(), Vector<Relationship>());
+        Vector<Relationship>& relationships = result.iterator->value;
+        Vector<Relationship> toAdd;
+        bool found = false;
+        for (Relationship& otherRelationship : relationships) {
+            if (otherRelationship.sameNodesAs(relationship)) {
+                if (Relationship filtered = otherRelationship.filter(relationship)) {
+                    ASSERT(filtered.left() == relationship.left());
+                    otherRelationship = filtered;
+                    found = true;
+                }
+            }
+            
+            if (timeToLive && otherRelationship.kind() == Relationship::Equal) {
+                if (verbose)
+                    dataLog("      Considering: ", otherRelationship, "\n");
+                
+                // We have:
+                //     @a op @b + C
+                //     @a == @c + D
+                //
+                // This implies:
+                //     @c + D op @b + C
+                //     @c op @b + C - D
+                //
+                // Where: @a == relationship.left(), @b == relationship.right(),
+                // @a == otherRelationship.left(), @c == otherRelationship.right().
+                
+                if (otherRelationship.offset() != std::numeric_limits<int>::min()) {
+                    Relationship newRelationship = relationship;
+                    if (newRelationship.right() != otherRelationship.right()) {
+                        newRelationship.setLeft(otherRelationship.right());
+                        if (newRelationship.addToOffset(-otherRelationship.offset()))
+                            toAdd.append(newRelationship);
+                    }
+                }
+            }
+        }
+        
+        if (!found)
+            relationships.append(relationship);
+        
+        for (Relationship anotherRelationship : toAdd) {
+            ASSERT(timeToLive);
+            setOneSide(relationshipMap, anotherRelationship, timeToLive - 1);
+        }
+    }
+    
+    bool mergeTo(RelationshipMap& relationshipMap, BasicBlock* target)
+    {
+        if (verbose) {
+            dataLog("Merging to ", pointerDump(target), ":\n");
+            dataLog("    Incoming: ", listDump(sortedRelationships(relationshipMap)), "\n");
+            dataLog("    At head: ", listDump(sortedRelationships(m_relationshipsAtHead[target])), "\n");
+        }
+        
+        if (m_seenBlocks.add(target)) {
+            // This is a new block. We copy subject to liveness pruning.
+            auto isLive = [&] (Node* node) {
+                if (node == m_zero)
+                    return true;
+                return target->ssa->liveAtHead.contains(node);
+            };
+            
+            for (auto& entry : relationshipMap) {
+                if (!isLive(entry.key))
+                    continue;
+                
+                Vector<Relationship> values;
+                for (Relationship relationship : entry.value) {
+                    ASSERT(relationship.left() == entry.key);
+                    if (isLive(relationship.right())) {
+                        if (verbose)
+                            dataLog("  Propagating ", relationship, "\n");
+                        values.append(relationship);
+                    }
+                }
+                
+                std::sort(values.begin(), values.end());
+                m_relationshipsAtHead[target].add(entry.key, values);
+            }
+            return true;
+        }
+        
+        // Merge by intersecting. We have no notion of BOTTOM, so we use the omission of
+        // relationships for a pair of nodes to mean TOP. The reason why we don't need BOTTOM
+        // is (1) we just overapproximate contradictions and (2) a value never having been
+        // assigned would only happen if we have not processed the node's predecessor. We
+        // shouldn't process blocks until we have processed the block's predecessor because we
+        // are using reverse postorder.
+        Vector<Node*> toRemove;
+        bool changed = false;
+        for (auto& entry : m_relationshipsAtHead[target]) {
+            auto iter = relationshipMap.find(entry.key);
+            if (iter == relationshipMap.end()) {
+                toRemove.append(entry.key);
+                changed = true;
+                continue;
+            }
+            
+            Vector<Relationship> mergedRelationships;
+            for (Relationship targetRelationship : entry.value) {
+                for (Relationship sourceRelationship : iter->value) {
+                    if (verbose)
+                        dataLog("  Merging ", targetRelationship, " and ", sourceRelationship, ":\n");
+                    Relationship newRelationship =
+                        targetRelationship.merge(sourceRelationship);
+                    
+                    if (verbose)
+                        dataLog("    Got ", newRelationship, "\n");
+                    
+                    if (!newRelationship)
+                        continue;
+                    
+                    // We need to filter() to avoid exponential explosion of identical
+                    // relationships. We do this here to avoid making setOneSide() do
+                    // more work, since we expect setOneSide() will be called more
+                    // frequently. Here's an example. At some point someone might start
+                    // with two relationships like @a > @b - C and @a < @b + D. Then
+                    // someone does a setRelationship() passing something that turns
+                    // both of these into @a == @b. Now we have @a == @b duplicated.
+                    // Let's say that this duplicate @a == @b ends up at the head of a
+                    // loop. If we didn't have this rule, then the loop would propagate
+                    // duplicate @a == @b's onto the existing duplicate @a == @b's.
+                    // There would be four pairs of @a == @b, each of which would
+                    // create a new @a == @b. Now we'd have four of these duplicates
+                    // and the next time around we'd have 8, then 16, etc. We avoid
+                    // this here by doing this filtration. That might be a bit of
+                    // overkill, since it's probably just the identical duplicate
+                    // relationship case we want' to avoid. But, I'll keep this until
+                    // we have evidence that this is a performance problem. Remember -
+                    // we are already dealing with a list that is pruned down to
+                    // relationships with identical left operand. It shouldn't be a
+                    // large list.
+                    bool found = false;
+                    for (Relationship& existingRelationship : mergedRelationships) {
+                        if (existingRelationship.sameNodesAs(newRelationship)) {
+                            Relationship filtered =
+                                existingRelationship.filter(newRelationship);
+                            if (filtered) {
+                                existingRelationship = filtered;
+                                found = true;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    if (!found)
+                        mergedRelationships.append(newRelationship);
+                }
+            }
+            std::sort(mergedRelationships.begin(), mergedRelationships.end());
+            if (entry.value == mergedRelationships)
+                continue;
+            
+            entry.value = mergedRelationships;
+            changed = true;
+        }
+        for (Node* node : toRemove)
+            m_relationshipsAtHead[target].remove(node);
+        
+        return changed;
+    }
+        
+    Vector<Relationship> sortedRelationships(const RelationshipMap& relationships)
+    {
+        Vector<Relationship> result;
+        for (auto& entry : relationships)
+            result.appendVector(entry.value);
+        std::sort(result.begin(), result.end());
+        return result;
+    }
+    
+    Vector<Relationship> sortedRelationships()
+    {
+        return sortedRelationships(m_relationships);
+    }
+    
+    Node* m_zero;
+    RelationshipMap m_relationships;
+    BlockSet m_seenBlocks;
+    BlockMap<RelationshipMap> m_relationshipsAtHead;
+    InsertionSet m_insertionSet;
+};
+    
+} // anonymous namespace
+
+bool performIntegerRangeOptimization(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Integer Range Optimization Phase");
+    return runPhase<IntegerRangeOptimizationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGIntegerRangeOptimizationPhase.h b/dfg/DFGIntegerRangeOptimizationPhase.h
new file mode 100644 (file)
index 0000000..fe0615e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGIntegerRangeOptimizationPhase_h
+#define DFGIntegerRangeOptimizationPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Removes overflow checks and out-of-bounds checks by doing a forward flow analysis to prove
+// inequalities. It will remove the overflow and bounds checks in loops like:
+//
+// for (var i = 0; i < array.length; ++i) array[i];
+
+bool performIntegerRangeOptimization(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGIntegerRangeOptimizationPhase_h
+
index 510ed5c3d49390d63af603d9b1486330647caeb7..9228001cc5397315a7dd1c6ea27d6f56a48e0331 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGBlockSetInlines.h"
 #include "DFGClobberize.h"
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
@@ -50,7 +51,7 @@ public:
     {
         ASSERT(m_graph.m_form != SSA);
         
-        BitVector blocksThatNeedInvalidationPoints;
+        BlockSet blocksThatNeedInvalidationPoints;
         
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
@@ -63,17 +64,13 @@ public:
             // Note: this assumes that control flow occurs at bytecode instruction boundaries.
             if (m_originThatHadFire.isSet()) {
                 for (unsigned i = block->numSuccessors(); i--;)
-                    blocksThatNeedInvalidationPoints.set(block->successor(i)->index);
+                    blocksThatNeedInvalidationPoints.add(block->successor(i));
             }
             
             m_insertionSet.execute(block);
         }
-        
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            if (!blocksThatNeedInvalidationPoints.get(blockIndex))
-                continue;
-            
-            BasicBlock* block = m_graph.block(blockIndex);
+
+        for (BasicBlock* block : blocksThatNeedInvalidationPoints.iterable(m_graph)) {
             insertInvalidationCheck(0, block->at(0));
             m_insertionSet.execute(block);
         }
index 0d690791840211258d3b3f072ed23110da006e51..db044e53e5c0cf83fdb3fc8613ca9a4bb1782445 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "CodeBlock.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace DFG {
 
@@ -82,24 +83,8 @@ void JITCode::reconstruct(
     reconstruct(codeBlock, codeOrigin, streamIndex, recoveries);
     
     result = Operands<JSValue>(OperandsLike, recoveries);
-    for (size_t i = result.size(); i--;) {
-        int operand = result.operandForIndex(i);
-        
-        if (codeOrigin == CodeOrigin(0)
-            && operandIsArgument(operand)
-            && !VirtualRegister(operand).toArgument()
-            && codeBlock->codeType() == FunctionCode
-            && codeBlock->specializationKind() == CodeForConstruct) {
-            // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
-            // also never be used. It doesn't matter what we put into the value for this,
-            // but it has to be an actual value that can be grokked by subsequent DFG passes,
-            // so we sanitize it here by turning it into Undefined.
-            result[i] = jsUndefined();
-            continue;
-        }
-        
+    for (size_t i = result.size(); i--;)
         result[i] = recoveries[i].recover(exec);
-    }
 }
 
 #if ENABLE(FTL_JIT)
@@ -186,6 +171,18 @@ void JITCode::setOptimizationThresholdBasedOnCompilationResult(
 }
 #endif // ENABLE(FTL_JIT)
 
+void JITCode::validateReferences(const TrackedReferences& trackedReferences)
+{
+    common.validateReferences(trackedReferences);
+    
+    for (OSREntryData& entry : osrEntry) {
+        for (unsigned i = entry.m_expectedValues.size(); i--;)
+            entry.m_expectedValues[i].validateReferences(trackedReferences);
+    }
+    
+    minifiedDFG.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index 4d3136fd749143dbc350a6f46e01f03ca6093a0b..266a7cece4edd985b02481fe6fa3bf24e2e718ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JITCode.h"
 #include <wtf/SegmentedVector.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace DFG {
 
 class JITCompiler;
 
@@ -107,6 +111,8 @@ public:
     void setOptimizationThresholdBasedOnCompilationResult(CodeBlock*, CompilationResult);
 #endif // ENABLE(FTL_JIT)
     
+    void validateReferences(const TrackedReferences&) override;
+    
     void shrinkToFit();
     
 private:
@@ -120,6 +126,7 @@ public:
     DFG::VariableEventStream variableEventStream;
     DFG::MinifiedGraph minifiedDFG;
 #if ENABLE(FTL_JIT)
+    uint8_t nestedTriggerIsSet { 0 };
     UpperTierExecutionCounter tierUpCounter;
     RefPtr<CodeBlock> osrEntryBlock;
     unsigned osrEntryRetry;
index c54746e6ba98b38d8a7cad2fedff45c32b658441..cf35be6b6cddab04ce890a9c65641163ca02ec2e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,7 +55,7 @@ JITCompiler::JITCompiler(Graph& dfg)
     , m_blockHeads(dfg.numBlocks())
 {
     if (shouldShowDisassembly() || m_graph.m_vm.m_perBytecodeProfiler)
-        m_disassembler = adoptPtr(new Disassembler(dfg));
+        m_disassembler = std::make_unique<Disassembler>(dfg);
 }
 
 JITCompiler::~JITCompiler()
@@ -116,35 +116,40 @@ void JITCompiler::compileBody()
 
 void JITCompiler::compileExceptionHandlers()
 {
-    if (m_exceptionChecks.empty() && m_exceptionChecksWithCallFrameRollback.empty())
-        return;
-
-    Jump doLookup;
-
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
-        emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        doLookup = jump();
-    }
 
-    if (!m_exceptionChecks.empty())
-        m_exceptionChecks.link(this);
+        // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+        addPtr(TrustedImm32(m_graph.stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
+
+#if CPU(X86)
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
+#endif
+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandlerFromCallerFrame));
 
-    // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
-    move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+        jumpToExceptionHandler();
+    }
 
-    if (doLookup.isSet())
-        doLookup.link(this);
+    if (!m_exceptionChecks.empty()) {
+        m_exceptionChecks.link(this);
 
-    move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
 
 #if CPU(X86)
-    // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
-    poke(GPRInfo::argumentGPR0);
-    poke(GPRInfo::argumentGPR1, 1);
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
 #endif
-    m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
-    jumpToExceptionHandler();
+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
+
+        jumpToExceptionHandler();
+    }
 }
 
 void JITCompiler::link(LinkBuffer& linkBuffer)
@@ -156,12 +161,11 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
     if (!m_graph.m_plan.inlineCallFrames->isEmpty())
         m_jitCode->common.inlineCallFrames = m_graph.m_plan.inlineCallFrames;
     
-    m_jitCode->common.machineCaptureStart = m_graph.m_machineCaptureStart;
-    m_jitCode->common.slowArguments = WTF::move(m_graph.m_slowArguments);
-
 #if USE(JSVALUE32_64)
     m_jitCode->common.doubleConstants = WTF::move(m_graph.m_doubleConstants);
 #endif
+    
+    m_graph.registerFrozenValues();
 
     BitVector usedJumpTables;
     for (Bag<SwitchData>::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
@@ -182,7 +186,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
             table.ctiOffsets[j] = table.ctiDefault;
         for (unsigned j = data.cases.size(); j--;) {
             SwitchCase& myCase = data.cases[j];
-            table.ctiOffsets[myCase.value.switchLookupValue() - table.min] =
+            table.ctiOffsets[myCase.value.switchLookupValue(data.kind) - table.min] =
                 linkBuffer.locationOf(m_blockHeads[myCase.target.block->index]);
         }
     }
@@ -241,12 +245,12 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
         JSCallRecord& record = m_jsCalls[i];
         CallLinkInfo& info = *record.m_info;
         ThunkGenerator generator = linkThunkGeneratorFor(
-            info.callType == CallLinkInfo::Construct ? CodeForConstruct : CodeForCall,
+            info.specializationKind(),
             RegisterPreservationNotRequired);
         linkBuffer.link(record.m_slowCall, FunctionPtr(m_vm->getCTIStub(generator).code().executableAddress()));
-        info.callReturnLocation = linkBuffer.locationOfNearCall(record.m_slowCall);
-        info.hotPathBegin = linkBuffer.locationOf(record.m_targetToCheck);
-        info.hotPathOther = linkBuffer.locationOfNearCall(record.m_fastCall);
+        info.setCallLocations(linkBuffer.locationOfNearCall(record.m_slowCall),
+            linkBuffer.locationOf(record.m_targetToCheck),
+            linkBuffer.locationOfNearCall(record.m_fastCall));
     }
     
     MacroAssemblerCodeRef osrExitThunk = vm()->getCTIStub(osrExitGenerationThunkGenerator);
@@ -285,12 +289,30 @@ void JITCompiler::compile()
 
     setStartOfCode();
     compileEntry();
-    m_speculative = adoptPtr(new SpeculativeJIT(*this));
+    m_speculative = std::make_unique<SpeculativeJIT>(*this);
+
+    // Plant a check that sufficient space is available in the JSStack.
+    addPtr(TrustedImm32(virtualRegisterForLocal(m_graph.requiredRegisterCountForExecutionAndExit() - 1).offset() * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1);
+    Jump stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), GPRInfo::regT1);
+
     addPtr(TrustedImm32(m_graph.stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
     checkStackPointerAlignment();
     compileBody();
     setEndOfMainPath();
 
+    // === Footer code generation ===
+    //
+    // Generate the stack overflow handling; if the stack check in the entry head fails,
+    // we need to call out to a helper function to throw the StackOverflowError.
+    stackOverflow.link(this);
+
+    emitStoreCodeOrigin(CodeOrigin(0));
+
+    if (maxFrameExtentForSlowPathCall)
+        addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
+
+    m_speculative->callOperationWithCallFrameRollbackOnException(operationThrowStackOverflowError, m_codeBlock);
+
     // Generate slow path code.
     m_speculative->runSlowPathGenerators();
     
@@ -300,13 +322,10 @@ void JITCompiler::compile()
     // Create OSR entry trampolines if necessary.
     m_speculative->createOSREntries();
     setEndOfCode();
-}
 
-void JITCompiler::link()
-{
-    OwnPtr<LinkBuffer> linkBuffer = adoptPtr(new LinkBuffer(*m_vm, *this, m_codeBlock, JITCompilationCanFail));
+    auto linkBuffer = std::make_unique<LinkBuffer>(*m_vm, *this, m_codeBlock, JITCompilationCanFail);
     if (linkBuffer->didFailToAllocate()) {
-        m_graph.m_plan.finalizer = adoptPtr(new FailedFinalizer(m_graph.m_plan));
+        m_graph.m_plan.finalizer = std::make_unique<FailedFinalizer>(m_graph.m_plan);
         return;
     }
     
@@ -318,8 +337,8 @@ void JITCompiler::link()
 
     disassemble(*linkBuffer);
     
-    m_graph.m_plan.finalizer = adoptPtr(new JITFinalizer(
-        m_graph.m_plan, m_jitCode.release(), linkBuffer.release()));
+    m_graph.m_plan.finalizer = std::make_unique<JITFinalizer>(
+        m_graph.m_plan, m_jitCode.release(), WTF::move(linkBuffer));
 }
 
 void JITCompiler::compileFunction()
@@ -343,7 +362,7 @@ void JITCompiler::compileFunction()
     checkStackPointerAlignment();
 
     // === Function body code generation ===
-    m_speculative = adoptPtr(new SpeculativeJIT(*this));
+    m_speculative = std::make_unique<SpeculativeJIT>(*this);
     compileBody();
     setEndOfMainPath();
 
@@ -387,7 +406,9 @@ void JITCompiler::compileFunction()
 #else
     thunkReg = GPRInfo::regT5;
 #endif
-    move(TrustedImmPtr(m_vm->arityCheckFailReturnThunks->returnPCsFor(*m_vm, m_codeBlock->numParameters())), thunkReg);
+    CodeLocationLabel* arityThunkLabels =
+        m_vm->arityCheckFailReturnThunks->returnPCsFor(*m_vm, m_codeBlock->numParameters());
+    move(TrustedImmPtr(arityThunkLabels), thunkReg);
     loadPtr(BaseIndex(thunkReg, GPRInfo::regT0, timesPtr()), thunkReg);
     m_callArityFixup = call();
     jump(fromArityCheck);
@@ -401,14 +422,11 @@ void JITCompiler::compileFunction()
     // Create OSR entry trampolines if necessary.
     m_speculative->createOSREntries();
     setEndOfCode();
-}
 
-void JITCompiler::linkFunction()
-{
     // === Link ===
-    OwnPtr<LinkBuffer> linkBuffer = adoptPtr(new LinkBuffer(*m_vm, *this, m_codeBlock, JITCompilationCanFail));
+    auto linkBuffer = std::make_unique<LinkBuffer>(*m_vm, *this, m_codeBlock, JITCompilationCanFail);
     if (linkBuffer->didFailToAllocate()) {
-        m_graph.m_plan.finalizer = adoptPtr(new FailedFinalizer(m_graph.m_plan));
+        m_graph.m_plan.finalizer = std::make_unique<FailedFinalizer>(m_graph.m_plan);
         return;
     }
     link(*linkBuffer);
@@ -417,20 +435,22 @@ void JITCompiler::linkFunction()
     m_jitCode->shrinkToFit();
     codeBlock()->shrinkToFit(CodeBlock::LateShrink);
     
-    linkBuffer->link(m_callArityFixup, FunctionPtr((m_vm->getCTIStub(arityFixup)).code().executableAddress()));
+    linkBuffer->link(m_callArityFixup, FunctionPtr((m_vm->getCTIStub(arityFixupGenerator)).code().executableAddress()));
     
     disassemble(*linkBuffer);
 
     MacroAssemblerCodePtr withArityCheck = linkBuffer->locationOf(m_arityCheck);
 
-    m_graph.m_plan.finalizer = adoptPtr(new JITFinalizer(
-        m_graph.m_plan, m_jitCode.release(), linkBuffer.release(), withArityCheck));
+    m_graph.m_plan.finalizer = std::make_unique<JITFinalizer>(
+        m_graph.m_plan, m_jitCode.release(), WTF::move(linkBuffer), withArityCheck);
 }
 
 void JITCompiler::disassemble(LinkBuffer& linkBuffer)
 {
-    if (shouldShowDisassembly())
+    if (shouldShowDisassembly()) {
         m_disassembler->dump(linkBuffer);
+        linkBuffer.didAlreadyDisassemble();
+    }
     
     if (m_graph.m_plan.compilation)
         m_disassembler->reportToProfiler(m_graph.m_plan.compilation.get(), linkBuffer);
@@ -439,11 +459,7 @@ void JITCompiler::disassemble(LinkBuffer& linkBuffer)
 #if USE(JSVALUE32_64)
 void* JITCompiler::addressOfDoubleConstant(Node* node)
 {
-    ASSERT(m_graph.isNumberConstant(node));
-    JSValue jsvalue = node->valueOfJSConstant(codeBlock());
-    ASSERT(jsvalue.isDouble());
-
-    double value = jsvalue.asDouble();
+    double value = node->asNumber();
     int64_t valueBits = bitwise_cast<int64_t>(value);
     auto it = m_graph.m_doubleConstantsMap.find(valueBits);
     if (it != m_graph.m_doubleConstantsMap.end())
@@ -459,6 +475,54 @@ void* JITCompiler::addressOfDoubleConstant(Node* node)
 }
 #endif
 
+void JITCompiler::noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
+{
+    // OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
+    if (!basicBlock.intersectionOfCFAHasVisited)
+        return;
+        
+    OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
+    
+    entry->m_expectedValues = basicBlock.intersectionOfPastValuesAtHead;
+        
+    // Fix the expected values: in our protocol, a dead variable will have an expected
+    // value of (None, []). But the old JIT may stash some values there. So we really
+    // need (Top, TOP).
+    for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
+        Node* node = basicBlock.variablesAtHead.argument(argument);
+        if (!node || !node->shouldGenerate())
+            entry->m_expectedValues.argument(argument).makeHeapTop();
+    }
+    for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
+        Node* node = basicBlock.variablesAtHead.local(local);
+        if (!node || !node->shouldGenerate())
+            entry->m_expectedValues.local(local).makeHeapTop();
+        else {
+            VariableAccessData* variable = node->variableAccessData();
+            entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
+                
+            switch (variable->flushFormat()) {
+            case FlushedDouble:
+                entry->m_localsForcedDouble.set(local);
+                break;
+            case FlushedInt52:
+                entry->m_localsForcedMachineInt.set(local);
+                break;
+            default:
+                break;
+            }
+            
+            if (variable->local() != variable->machineLocal()) {
+                entry->m_reshufflings.append(
+                    OSREntryReshuffling(
+                        variable->local().offset(), variable->machineLocal().offset()));
+            }
+        }
+    }
+        
+    entry->m_reshufflings.shrinkToFit();
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index 24c27de30cd6efc398e4a4968338efc7743cb436..9710ebaf4b4e6060d937486ed6ae116586f9f2d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -111,9 +111,6 @@ public:
     void compile();
     void compileFunction();
     
-    void link();
-    void linkFunction();
-
     // Accessors for properties.
     Graph& graph() { return m_graph; }
     
@@ -268,55 +265,9 @@ public:
 #endif
     }
 
-    void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
-    {
-        // OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
-        if (!basicBlock.cfaHasVisited)
-            return;
-        
-        OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
-        
-        entry->m_expectedValues = basicBlock.valuesAtHead;
-        
-        // Fix the expected values: in our protocol, a dead variable will have an expected
-        // value of (None, []). But the old JIT may stash some values there. So we really
-        // need (Top, TOP).
-        for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
-            Node* node = basicBlock.variablesAtHead.argument(argument);
-            if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.argument(argument).makeHeapTop();
-        }
-        for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
-            Node* node = basicBlock.variablesAtHead.local(local);
-            if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.local(local).makeHeapTop();
-            else {
-                VariableAccessData* variable = node->variableAccessData();
-                entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
-                
-                switch (variable->flushFormat()) {
-                case FlushedDouble:
-                    entry->m_localsForcedDouble.set(local);
-                    break;
-                case FlushedInt52:
-                    entry->m_localsForcedMachineInt.set(local);
-                    break;
-                default:
-                    break;
-                }
-                
-                if (variable->local() != variable->machineLocal()) {
-                    entry->m_reshufflings.append(
-                        OSREntryReshuffling(
-                            variable->local().offset(), variable->machineLocal().offset()));
-                }
-            }
-        }
-        
-        entry->m_reshufflings.shrinkToFit();
-    }
+    void noticeOSREntry(BasicBlock&, JITCompiler::Label blockHead, LinkBuffer&);
     
-    PassRefPtr<JITCode> jitCode() { return m_jitCode; }
+    RefPtr<JITCode> jitCode() { return m_jitCode; }
     
     Vector<Label>& blockHeads() { return m_blockHeads; }
 
@@ -336,7 +287,7 @@ private:
     // The dataflow graph currently being generated.
     Graph& m_graph;
 
-    OwnPtr<Disassembler> m_disassembler;
+    std::unique_ptr<Disassembler> m_disassembler;
     
     RefPtr<JITCode> m_jitCode;
     
@@ -372,7 +323,7 @@ private:
     
     Call m_callArityFixup;
     Label m_arityCheck;
-    OwnPtr<SpeculativeJIT> m_speculative;
+    std::unique_ptr<SpeculativeJIT> m_speculative;
 };
 
 } } // namespace JSC::DFG
index 8be38e4071413e052574a23447bac01e4786d053..836c0e048a7f2463072628f6bfe63cc02801af61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlock.h"
+#include "CodeBlockWithJITType.h"
 #include "DFGCommon.h"
 #include "DFGPlan.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace DFG {
 
-JITFinalizer::JITFinalizer(Plan& plan, PassRefPtr<JITCode> jitCode, PassOwnPtr<LinkBuffer> linkBuffer, MacroAssemblerCodePtr withArityCheck)
+JITFinalizer::JITFinalizer(Plan& plan, PassRefPtr<JITCode> jitCode, std::unique_ptr<LinkBuffer> linkBuffer, MacroAssemblerCodePtr withArityCheck)
     : Finalizer(plan)
     , m_jitCode(jitCode)
-    , m_linkBuffer(linkBuffer)
+    , m_linkBuffer(WTF::move(linkBuffer))
     , m_withArityCheck(withArityCheck)
 {
 }
@@ -56,7 +57,9 @@ size_t JITFinalizer::codeSize()
 bool JITFinalizer::finalize()
 {
     m_jitCode->initializeCodeRef(
-        m_linkBuffer->finalizeCodeWithoutDisassembly(), MacroAssemblerCodePtr());
+        FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())),
+        MacroAssemblerCodePtr());
+    
     m_plan.codeBlock->setJITCode(m_jitCode);
     
     finalizeCommon();
@@ -68,7 +71,8 @@ bool JITFinalizer::finalizeFunction()
 {
     RELEASE_ASSERT(!m_withArityCheck.isEmptyValue());
     m_jitCode->initializeCodeRef(
-        m_linkBuffer->finalizeCodeWithoutDisassembly(), m_withArityCheck);
+        FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())),
+        m_withArityCheck);
     m_plan.codeBlock->setJITCode(m_jitCode);
     
     finalizeCommon();
index 76bb6d5af1be203b20b6eaee1fe6f0c999bd2f86..110442fe48aee99470919e4abe37f5447a1368d8 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC { namespace DFG {
 
 class JITFinalizer : public Finalizer {
 public:
-    JITFinalizer(Plan&, PassRefPtr<JITCode>, PassOwnPtr<LinkBuffer>, MacroAssemblerCodePtr withArityCheck = MacroAssemblerCodePtr(MacroAssemblerCodePtr::EmptyValue));
+    JITFinalizer(Plan&, PassRefPtr<JITCode>, std::unique_ptr<LinkBuffer>, MacroAssemblerCodePtr withArityCheck = MacroAssemblerCodePtr(MacroAssemblerCodePtr::EmptyValue));
     virtual ~JITFinalizer();
     
     virtual size_t codeSize() override;
@@ -48,7 +48,7 @@ private:
     void finalizeCommon();
     
     RefPtr<JITCode> m_jitCode;
-    OwnPtr<LinkBuffer> m_linkBuffer;
+    std::unique_ptr<LinkBuffer> m_linkBuffer;
     MacroAssemblerCodePtr m_withArityCheck;
 };
 
index 334e6bac56da10eb139b0297d5e3f83e93c9d0ae..62cde8adb428e3079fcb233a26459b297dbe6598 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,13 +62,14 @@ class LICMPhase : public Phase {
 public:
     LICMPhase(Graph& graph)
         : Phase(graph, "LICM")
+        , m_state(graph)
         , m_interpreter(graph, m_state)
     {
     }
     
     bool run()
     {
-        ASSERT(m_graph.m_form == SSA);
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
         
         m_graph.m_dominators.computeIfNecessary(m_graph);
         m_graph.m_naturalLoops.computeIfNecessary(m_graph);
@@ -123,11 +124,17 @@ public:
                 BasicBlock* predecessor = header->predecessors[i];
                 if (m_graph.m_dominators.dominates(header, predecessor))
                     continue;
-                RELEASE_ASSERT(!preHeader || preHeader == predecessor);
+                DFG_ASSERT(m_graph, nullptr, !preHeader || preHeader == predecessor);
                 preHeader = predecessor;
             }
             
-            RELEASE_ASSERT(preHeader->last()->op() == Jump);
+            DFG_ASSERT(m_graph, preHeader->terminal(), preHeader->terminal()->op() == Jump);
+            
+            // We should validate the pre-header. If we placed forExit origins on nodes only if
+            // at the top of that node it is legal to exit, then we would simply check if Jump
+            // had a forExit. We should disable hoisting to pre-headers that don't validate.
+            // Or, we could only allow hoisting of things that definitely don't exit.
+            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=145204
             
             data.preHeader = preHeader;
         }
@@ -149,16 +156,9 @@ public:
         //
         // For maximum profit, we walk blocks in DFS order to ensure that we generally
         // tend to hoist dominators before dominatees.
-        Vector<BasicBlock*> depthFirst;
-        m_graph.getBlocksInDepthFirstOrder(depthFirst);
         Vector<const NaturalLoop*> loopStack;
         bool changed = false;
-        for (
-            unsigned depthFirstIndex = 0;
-            depthFirstIndex < depthFirst.size();
-            ++depthFirstIndex) {
-            
-            BasicBlock* block = depthFirst[depthFirstIndex];
+        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
             const NaturalLoop* loop = m_graph.m_naturalLoops.innerMostLoopOf(block);
             if (!loop)
                 continue;
@@ -219,6 +219,47 @@ private:
             return false;
         }
         
+        // FIXME: At this point if the hoisting of the full node fails but the node has type checks,
+        // we could still hoist just the checks.
+        // https://bugs.webkit.org/show_bug.cgi?id=144525
+        
+        // FIXME: If a node has a type check - even something like a CheckStructure - then we should
+        // only hoist the node if we know that it will execute on every loop iteration or if we know
+        // that the type check will always succeed at the loop pre-header through some other means
+        // (like looking at prediction propagation results). Otherwise, we might make a mistake like
+        // this:
+        //
+        // var o = ...; // sometimes null and sometimes an object with structure S1.
+        // for (...) {
+        //     if (o)
+        //         ... = o.f; // CheckStructure and GetByOffset, which we will currently hoist.
+        // }
+        //
+        // When we encounter such code, we'll hoist the CheckStructure and GetByOffset and then we
+        // will have a recompile. We'll then end up thinking that the get_by_id needs to be
+        // polymorphic, which is false.
+        //
+        // We can counter this by either having a control flow equivalence check, or by consulting
+        // prediction propagation to see if the check would always succeed. Prediction propagation
+        // would not be enough for things like:
+        //
+        // var p = ...; // some boolean predicate
+        // var o = {};
+        // if (p)
+        //     o.f = 42;
+        // for (...) {
+        //     if (p)
+        //         ... = o.f;
+        // }
+        //
+        // Prediction propagation can't tell us anything about the structure, and the CheckStructure
+        // will appear to be hoistable because the loop doesn't clobber structures. The cell check
+        // in the CheckStructure will be hoistable though, since prediction propagation can tell us
+        // that o is always SpecFinalObject. In cases like this, control flow equivalence is the
+        // only effective guard.
+        //
+        // https://bugs.webkit.org/show_bug.cgi?id=144527
+        
         if (readsOverlap(m_graph, node, data.writes)) {
             if (verbose) {
                 dataLog(
@@ -243,10 +284,12 @@ private:
                 "\n");
         }
         
-        data.preHeader->insertBeforeLast(node);
-        node->misc.owner = data.preHeader;
+        data.preHeader->insertBeforeTerminal(node);
+        node->owner = data.preHeader;
         NodeOrigin originalOrigin = node->origin;
-        node->origin.forExit = data.preHeader->last()->origin.forExit;
+        node->origin.forExit = data.preHeader->terminal()->origin.forExit;
+        if (!node->origin.semantic.isSet())
+            node->origin.semantic = node->origin.forExit;
         
         // Modify the states at the end of the preHeader of the loop we hoisted to,
         // and all pre-headers inside the loop.
@@ -267,9 +310,9 @@ private:
         // It just so happens that all of the nodes we currently know how to hoist
         // don't have var-arg children. That may change and then we can fix this
         // code. But for now we just assert that's the case.
-        RELEASE_ASSERT(!(node->flags() & NodeHasVarArgs));
+        DFG_ASSERT(m_graph, node, !(node->flags() & NodeHasVarArgs));
         
-        nodeRef = m_graph.addNode(SpecNone, Phantom, originalOrigin, node->children);
+        nodeRef = m_graph.addNode(SpecNone, Check, originalOrigin, node->children);
         
         return true;
     }
index 76d2c51e81d596b300a3c98870354fa61d47dbe9..6011490c97f52ddfe4310127fd082ce9466d3a11 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,14 +36,14 @@ JSValue LazyJSValue::getValue(VM& vm) const
 {
     switch (m_kind) {
     case KnownValue:
-        return value();
+        return value()->value();
     case SingleCharacterString:
         return jsSingleCharacterString(&vm, u.character);
     case KnownStringImpl:
         return jsString(&vm, u.stringImpl);
     }
     RELEASE_ASSERT_NOT_REACHED();
-    return value();
+    return JSValue();
 }
 
 static TriState equalToSingleCharacter(JSValue value, UChar character)
@@ -81,11 +81,11 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const
     case KnownValue:
         switch (other.m_kind) {
         case KnownValue:
-            return JSValue::pureStrictEqual(value(), other.value());
+            return JSValue::pureStrictEqual(value()->value(), other.value()->value());
         case SingleCharacterString:
-            return equalToSingleCharacter(value(), other.character());
+            return equalToSingleCharacter(value()->value(), other.character());
         case KnownStringImpl:
-            return equalToStringImpl(value(), other.stringImpl());
+            return equalToStringImpl(value()->value(), other.stringImpl());
         }
         break;
     case SingleCharacterString:
@@ -113,11 +113,41 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const
     return FalseTriState;
 }
 
+uintptr_t LazyJSValue::switchLookupValue(SwitchKind kind) const
+{
+    // NB. Not every kind of JSValue will be able to give you a switch lookup
+    // value, and this method will assert, or do bad things, if you use it
+    // for a kind of value that can't.
+    switch (m_kind) {
+    case KnownValue:
+        switch (kind) {
+        case SwitchImm:
+            return value()->value().asInt32();
+        case SwitchCell:
+            return bitwise_cast<uintptr_t>(value()->value().asCell());
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return 0;
+        }
+    case SingleCharacterString:
+        switch (kind) {
+        case SwitchChar:
+            return character();
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return 0;
+        }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return 0;
+    }
+}
+
 void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     switch (m_kind) {
     case KnownValue:
-        value().dumpInContext(out, context);
+        value()->dumpInContext(out, context);
         return;
     case SingleCharacterString:
         out.print("Lazy:SingleCharacterString(");
index a391855f715b355493786d2957a866b711e04d8f..a1231db04f25ec4e47eef03d9e84f4aeff6616cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,8 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "JSCJSValue.h"
+#include "DFGCommon.h"
+#include "DFGFrozenValue.h"
 #include <wtf/text/StringImpl.h>
 
 namespace JSC { namespace DFG {
@@ -44,10 +45,10 @@ enum LazinessKind {
 
 class LazyJSValue {
 public:
-    LazyJSValue(JSValue value = JSValue())
+    LazyJSValue(FrozenValue* value = FrozenValue::emptySingleton())
         : m_kind(KnownValue)
     {
-        u.value = JSValue::encode(value);
+        u.value = value;
     }
     
     static LazyJSValue singleCharacterString(UChar character)
@@ -66,19 +67,19 @@ public:
         return result;
     }
     
-    JSValue tryGetValue() const
+    FrozenValue* tryGetValue(Graph&) const
     {
         if (m_kind == KnownValue)
             return value();
-        return JSValue();
+        return nullptr;
     }
     
     JSValue getValue(VM&) const;
     
-    JSValue value() const
+    FrozenValue* value() const
     {
         ASSERT(m_kind == KnownValue);
-        return JSValue::decode(u.value);
+        return u.value;
     }
     
     UChar character() const
@@ -95,28 +96,14 @@ public:
     
     TriState strictEqual(const LazyJSValue& other) const;
     
-    unsigned switchLookupValue() const
-    {
-        // NB. Not every kind of JSValue will be able to give you a switch lookup
-        // value, and this method will assert, or do bad things, if you use it
-        // for a kind of value that can't.
-        switch (m_kind) {
-        case KnownValue:
-            return value().asInt32();
-        case SingleCharacterString:
-            return character();
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return 0;
-        }
-    }
+    uintptr_t switchLookupValue(SwitchKind) const;
     
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
 private:
     union {
-        EncodedJSValue value;
+        FrozenValue* value;
         UChar character;
         StringImpl* stringImpl;
     } u;
diff --git a/dfg/DFGLazyNode.cpp b/dfg/DFGLazyNode.cpp
new file mode 100644 (file)
index 0000000..954ed98
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGLazyNode.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void LazyNode::dump(PrintStream& out) const
+{
+    if (!*this)
+        out.print("LazyNode:0");
+    else {
+        if (isNode())
+            out.print("LazyNode:@", asNode()->index());
+        else
+            out.print("LazyNode:FrozenValue:", Graph::opName(op()), ", ", pointerDump(asValue()));
+        out.print(")");
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGLazyNode.h b/dfg/DFGLazyNode.h
new file mode 100644 (file)
index 0000000..ffd572f
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGLazyNode_h
+#define DFGLazyNode_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "DFGInsertionSet.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+class LazyNode {
+public:
+    static const size_t jsConstantTag = 0;
+    static const size_t doubleConstantTag = 1;
+    static const size_t int52ConstantTag = 2;
+
+    static const uintptr_t tagMask = 0x3;
+    static const uintptr_t pointerMask = ~tagMask;
+
+    explicit LazyNode(Node* node = nullptr)
+        : m_node(node)
+        , m_value(reinterpret_cast<uintptr_t>(nullptr))
+    {
+        if (node && node->isConstant())
+            setFrozenValue(node->constant(), node->op());
+    }
+
+    explicit LazyNode(FrozenValue* value, NodeType op = JSConstant)
+        : m_node(nullptr)
+        , m_value(reinterpret_cast<uintptr_t>(nullptr))
+    {
+        setFrozenValue(value, op);
+    }
+
+    LazyNode(std::nullptr_t)
+        : m_node(nullptr)
+        , m_value(reinterpret_cast<uintptr_t>(nullptr))
+    {
+    }
+
+    LazyNode(WTF::HashTableDeletedValueType)
+        : m_node(reinterpret_cast<Node*>(-1))
+    {
+    }
+
+    void setNode(Node* node)
+    {
+        m_node = node;
+        if (node && node->isConstant())
+            setFrozenValue(node->constant(), node->op());
+    }
+
+    bool isHashTableDeletedValue() const { return m_node == reinterpret_cast<Node*>(-1); }
+
+    bool isNode() const { return m_node; }
+
+    NodeType op() const
+    {
+        if (m_node)
+            return m_node->op();
+
+        switch (m_value & tagMask) {
+        case jsConstantTag:
+            return JSConstant;
+        case doubleConstantTag:
+            return DoubleConstant;
+        case int52ConstantTag:
+            return Int52Constant;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+
+    Node* asNode() const
+    {
+        ASSERT(m_node || !asValue());
+        return m_node;
+    }
+
+    FrozenValue* asValue() const
+    {
+        return reinterpret_cast<FrozenValue*>(m_value & pointerMask);
+    }
+
+    unsigned hash() const
+    {
+        if (asValue())
+            return WTF::PtrHash<FrozenValue*>::hash(asValue());
+        return WTF::PtrHash<Node*>::hash(m_node);
+    }
+
+    bool operator==(const LazyNode& other) const
+    {
+        if (asValue() || other.asValue())
+            return m_value == other.m_value;
+        return m_node == other.m_node;
+    }
+
+    bool operator!=(const LazyNode& other) const
+    {
+        return !(*this == other);
+    }
+
+    Node* ensureIsNode(InsertionSet& insertionSet, BasicBlock* block, unsigned nodeIndex)
+    {
+        if (!m_node)
+            m_node = insertionSet.insertConstant(nodeIndex, block->at(nodeIndex)->origin, asValue(), op());
+
+        return asNode();
+    }
+
+    Node* operator->() const { return asNode(); }
+
+    Node& operator*() const { return *asNode(); }
+
+    bool operator!() const { return !asValue() && !asNode(); }
+
+    explicit operator bool() const { return !!*this; }
+
+    void dump(PrintStream& out) const;
+
+private:
+    void setFrozenValue(FrozenValue* value, NodeType op)
+    {
+        ASSERT(value);
+        m_value = reinterpret_cast<uintptr_t>(value);
+        ASSERT(m_value == (m_value & pointerMask));
+        switch (op) {
+        case JSConstant:
+            m_value |= jsConstantTag;
+            break;
+        case DoubleConstant:
+            m_value |= doubleConstantTag;
+            break;
+        case Int52Constant:
+            m_value |= int52ConstantTag;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+
+    Node* m_node;
+    uintptr_t m_value;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::LazyNode> : SimpleClassHashTraits<JSC::DFG::LazyNode> {
+    static const bool emptyValueIsZero = true;
+};
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGLazyNode_h
index b3131a4a59480175374bcce8f72b47b3b1870f77..b2dc4d2b0f77609ea84ad70bd231561bbb377fcb 100644 (file)
@@ -68,13 +68,11 @@ public:
         } while (m_changed);
         
         if (!m_graph.block(0)->ssa->liveAtHead.isEmpty()) {
-            startCrashing();
-            dataLog(
-                "Bad liveness analysis result: live at root is not empty: ",
-                nodeListDump(m_graph.block(0)->ssa->liveAtHead), "\n");
-            dataLog("IR at time of error:\n");
-            m_graph.dump();
-            CRASH();
+            DFG_CRASH(
+                m_graph, nullptr,
+                toCString(
+                    "Bad liveness analysis result: live at root is not empty: ",
+                    nodeListDump(m_graph.block(0)->ssa->liveAtHead)).data());
         }
         
         return true;
index b11b2dbc5ade8d042720847a498ecaccbf1574d9..340ef2d187b80780b8a9e97144e4c2b1d2b5ac47 100644 (file)
@@ -42,7 +42,7 @@ BasicBlock* createPreHeader(Graph& graph, BlockInsertionSet& insertionSet, Basic
     // Don't bother to preserve execution frequencies for now.
     BasicBlock* preHeader = insertionSet.insertBefore(block, PNaN);
     preHeader->appendNode(
-        graph, SpecNone, Jump, block->at(0)->origin, OpInfo(block));
+        graph, SpecNone, Jump, block->firstOrigin(), OpInfo(block));
     
     for (unsigned predecessorIndex = 0; predecessorIndex < block->predecessors.size(); predecessorIndex++) {
         BasicBlock* predecessor = block->predecessors[predecessorIndex];
@@ -88,11 +88,23 @@ public:
                     existingPreHeader = predecessor;
                     continue;
                 }
-                if (existingPreHeader == predecessor)
-                    continue;
+                // We won't have duplicate entries in the predecessors list.
+                DFG_ASSERT(m_graph, nullptr, existingPreHeader != predecessor);
                 needsNewPreHeader = true;
                 break;
             }
+            
+            // This phase should only be run on a DFG where unreachable blocks have been pruned.
+            // We also don't allow loops back to root. This means that every loop header has got
+            // to have a pre-header.
+            DFG_ASSERT(m_graph, nullptr, existingPreHeader);
+            
+            // We are looking at the predecessors of a loop header. A loop header has to have
+            // some predecessor other than the pre-header. We must have broken critical edges
+            // because that is the DFG SSA convention. Therefore, each predecessor of the loop
+            // header must have only one successor.
+            DFG_ASSERT(m_graph, nullptr, existingPreHeader->terminal()->op() == Jump);
+            
             if (!needsNewPreHeader)
                 continue;
             
diff --git a/dfg/DFGMayExit.cpp b/dfg/DFGMayExit.cpp
new file mode 100644 (file)
index 0000000..4631ecd
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGMayExit.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGNode.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+class EdgeMayExit {
+public:
+    EdgeMayExit()
+        : m_result(false)
+    {
+    }
+    
+    void operator()(Node*, Edge edge)
+    {
+        if (edge.willHaveCheck()) {
+            m_result = true;
+            return;
+        }
+
+        switch (edge.useKind()) {
+        // These are shady because nodes that have these use kinds will typically exit for
+        // unrelated reasons. For example CompareEq doesn't usually exit, but if it uses ObjectUse
+        // then it will.
+        case ObjectUse:
+        case ObjectOrOtherUse:
+            m_result = true;
+            break;
+            
+        // These are shady because they check the structure even if the type of the child node
+        // passes the StringObject type filter.
+        case StringObjectUse:
+        case StringOrStringObjectUse:
+            m_result = true;
+            break;
+            
+        default:
+            break;
+        }
+    }
+    
+    bool result() const { return m_result; }
+    
+private:
+    bool m_result;
+};
+
+} // anonymous namespace
+
+bool mayExit(Graph& graph, Node* node)
+{
+    switch (node->op()) {
+    // This is a carefully curated list of nodes that definitely do not exit. We try to be very
+    // conservative when maintaining this list, because adding new node types to it doesn't
+    // generally make things a lot better but it might introduce insanely subtle bugs.
+    case SetArgument:
+    case JSConstant:
+    case DoubleConstant:
+    case Int52Constant:
+    case MovHint:
+    case SetLocal:
+    case Flush:
+    case Phantom:
+    case Check:
+    case GetLocal:
+    case LoopHint:
+    case Phi:
+    case Upsilon:
+    case ZombieHint:
+    case BottomValue:
+    case PutHint:
+    case PhantomNewObject:
+    case PutStack:
+    case KillStack:
+    case GetStack:
+    case GetCallee:
+    case GetArgumentCount:
+    case GetScope:
+    case PhantomLocal:
+    case CountExecution:
+    case Jump:
+    case Branch:
+    case Unreachable:
+    case DoubleRep:
+    case Int52Rep:
+    case ValueRep:
+        break;
+        
+    default:
+        // If in doubt, return true.
+        return true;
+    }
+
+    EdgeMayExit functor;
+    DFG_NODE_DO_TO_CHILDREN(graph, node, functor);
+    return functor.result();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGMayExit.h b/dfg/DFGMayExit.h
new file mode 100644 (file)
index 0000000..e5ae040
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGMayExit_h
+#define DFGMayExit_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+struct Node;
+
+// A *very* conservative approximation of whether or not a node could possibly exit. Usually
+// returns true except in cases where we obviously don't expect an exit.
+
+bool mayExit(Graph&, Node*);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGMayExit_h
+
diff --git a/dfg/DFGMinifiedGraph.cpp b/dfg/DFGMinifiedGraph.cpp
new file mode 100644 (file)
index 0000000..61f331f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGMinifiedGraph.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+#include "TrackedReferences.h"
+
+namespace JSC { namespace DFG {
+
+void MinifiedGraph::prepareAndShrink()
+{
+    std::sort(m_list.begin(), m_list.end(), MinifiedNode::compareByNodeIndex);
+    m_list.shrinkToFit();
+}
+
+void MinifiedGraph::validateReferences(const TrackedReferences& trackedReferences)
+{
+    for (MinifiedNode& node : m_list) {
+        if (node.hasConstant())
+            trackedReferences.check(node.constant());
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
index bc1497068b284f210c8076ab9e762e482a5355c2..4fc44f8cc5977fd397f8065c2e1a4fac169cc84e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace DFG {
 
 class MinifiedGraph {
 public:
@@ -50,11 +54,9 @@ public:
         m_list.append(node);
     }
     
-    void prepareAndShrink()
-    {
-        std::sort(m_list.begin(), m_list.end(), MinifiedNode::compareByNodeIndex);
-        m_list.shrinkToFit();
-    }
+    void prepareAndShrink();
+    
+    void validateReferences(const TrackedReferences&);
     
 private:
     Vector<MinifiedNode> m_list;
index 5f947d1c4dd2f259aa70831cf22f66b601805e6e..bdb312d819e7b6828fa9c854bac862d10c4047d5 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef DFGMinifiedID_h
 #define DFGMinifiedID_h
 
-#if ENABLE(DFG_JIT)
-
 #include "DFGCommon.h"
 #include <wtf/HashMap.h>
 #include <wtf/PrintStream.h>
@@ -37,6 +35,7 @@ namespace JSC { namespace DFG {
 class Graph;
 class MinifiedNode;
 class ValueSource;
+struct Node;
 
 class MinifiedID {
 public:
@@ -98,11 +97,11 @@ template<> struct DefaultHash<JSC::DFG::MinifiedID> {
 };
 
 template<typename T> struct HashTraits;
-template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> { };
+template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> {
+    static const bool emptyValueIsZero = false;
+};
 
 } // namespace WTF
 
-#endif // ENABLE(DFG_JIT)
-
 #endif // DFGMinifiedID_h
 
index 4d433aa773f4777feb145a5a4f53914cc38cef23..80795c2fe70f03cf1939db317f5309cc76a9272b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,13 +39,11 @@ MinifiedNode MinifiedNode::fromNode(Node* node)
     MinifiedNode result;
     result.m_id = MinifiedID(node);
     result.m_op = node->op();
-    if (hasConstantNumber(node->op()))
-        result.m_info = node->constantNumber();
-    else if (hasWeakConstant(node->op()))
-        result.m_info = bitwise_cast<uintptr_t>(node->weakConstant());
+    if (hasConstant(node->op()))
+        result.m_info = JSValue::encode(node->asJSValue());
     else {
-        ASSERT(node->op() == PhantomArguments);
-        result.m_info = 0;
+        ASSERT(node->op() == PhantomDirectArguments || node->op() == PhantomClonedArguments);
+        result.m_info = bitwise_cast<uintptr_t>(node->origin.semantic.inlineCallFrame);
     }
     return result;
 }
index 0cc35ef88aef738ed295dc33d85384b6b1c79f51..29798bc221c6bbc4937152036c1c484b3ef1222f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,8 +42,8 @@ inline bool belongsInMinifiedGraph(NodeType type)
     case JSConstant:
     case Int52Constant:
     case DoubleConstant:
-    case WeakJSConstant:
-    case PhantomArguments:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         return true;
     default:
         return false;
@@ -59,22 +59,18 @@ public:
     MinifiedID id() const { return m_id; }
     NodeType op() const { return m_op; }
     
-    bool hasConstant() const { return hasConstantNumber() || hasWeakConstant(); }
+    bool hasConstant() const { return hasConstant(m_op); }
     
-    bool hasConstantNumber() const { return hasConstantNumber(m_op); }
-    
-    unsigned constantNumber() const
+    JSValue constant() const
     {
-        ASSERT(hasConstantNumber(m_op));
-        return m_info;
+        return JSValue::decode(bitwise_cast<EncodedJSValue>(m_info));
     }
     
-    bool hasWeakConstant() const { return hasWeakConstant(m_op); }
+    bool hasInlineCallFrame() const { return hasInlineCallFrame(m_op); }
     
-    JSCell* weakConstant() const
+    InlineCallFrame* inlineCallFrame() const
     {
-        ASSERT(hasWeakConstant(m_op));
-        return bitwise_cast<JSCell*>(m_info);
+        return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(m_info));
     }
     
     static MinifiedID getID(MinifiedNode* node) { return node->id(); }
@@ -84,17 +80,18 @@ public:
     }
     
 private:
-    static bool hasConstantNumber(NodeType type)
+    static bool hasConstant(NodeType type)
     {
         return type == JSConstant || type == Int52Constant || type == DoubleConstant;
     }
-    static bool hasWeakConstant(NodeType type)
+    
+    static bool hasInlineCallFrame(NodeType type)
     {
-        return type == WeakJSConstant;
+        return type == PhantomDirectArguments || type == PhantomClonedArguments;
     }
     
     MinifiedID m_id;
-    uintptr_t m_info;
+    uint64_t m_info;
     NodeType m_op;
 };
 
diff --git a/dfg/DFGMovHintRemovalPhase.cpp b/dfg/DFGMovHintRemovalPhase.cpp
new file mode 100644 (file)
index 0000000..e2cf37e
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGMovHintRemovalPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "BytecodeLivenessAnalysisInlines.h"
+#include "DFGEpoch.h"
+#include "DFGForAllKills.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGMayExit.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+#include "OperandsInlines.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class MovHintRemovalPhase : public Phase {
+public:
+    MovHintRemovalPhase(Graph& graph)
+        : Phase(graph, "MovHint removal")
+        , m_state(OperandsLike, graph.block(0)->variablesAtHead)
+        , m_changed(false)
+    {
+    }
+    
+    bool run()
+    {
+        if (verbose) {
+            dataLog("Graph before MovHint removal:\n");
+            m_graph.dump();
+        }
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+            handleBlock(block);
+        
+        return m_changed;
+    }
+
+private:
+    void handleBlock(BasicBlock* block)
+    {
+        if (verbose)
+            dataLog("Handing block ", pointerDump(block), "\n");
+        
+        // A MovHint is unnecessary if the local dies before it is used. We answer this question by
+        // maintaining the current exit epoch, and associating an epoch with each local. When a
+        // local dies, it gets the current exit epoch. If a MovHint occurs in the same epoch as its
+        // local, then it means there was no exit between the local's death and the MovHint - i.e.
+        // the MovHint is unnecessary.
+        
+        Epoch currentEpoch = Epoch::first();
+        
+        m_state.fill(Epoch());
+        m_graph.forAllLiveInBytecode(
+            block->terminal()->origin.forExit,
+            [&] (VirtualRegister reg) {
+                m_state.operand(reg) = currentEpoch;
+            });
+        
+        if (verbose)
+            dataLog("    Locals: ", m_state, "\n");
+        
+        // Assume that blocks after us exit.
+        currentEpoch.bump();
+        
+        for (unsigned nodeIndex = block->size(); nodeIndex--;) {
+            Node* node = block->at(nodeIndex);
+            
+            if (node->op() == MovHint) {
+                Epoch localEpoch = m_state.operand(node->unlinkedLocal());
+                if (verbose)
+                    dataLog("    At ", node, ": current = ", currentEpoch, ", local = ", localEpoch, "\n");
+                if (!localEpoch || localEpoch == currentEpoch) {
+                    node->setOpAndDefaultFlags(ZombieHint);
+                    node->child1() = Edge();
+                    m_changed = true;
+                }
+                m_state.operand(node->unlinkedLocal()) = Epoch();
+            }
+            
+            if (mayExit(m_graph, node))
+                currentEpoch.bump();
+            
+            if (nodeIndex) {
+                forAllKilledOperands(
+                    m_graph, block->at(nodeIndex - 1), node,
+                    [&] (VirtualRegister reg) {
+                        // This function is a bit sloppy - it might claim to kill a local even if
+                        // it's still live after. We need to protect against that.
+                        if (!!m_state.operand(reg))
+                            return;
+                        
+                        if (verbose)
+                            dataLog("    Killed operand at ", node, ": ", reg, "\n");
+                        m_state.operand(reg) = currentEpoch;
+                    });
+            }
+        }
+    }
+    
+    Operands<Epoch> m_state;
+    bool m_changed;
+};
+
+} // anonymous namespace
+    
+bool performMovHintRemoval(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG MovHint Removal Phase");
+    return runPhase<MovHintRemovalPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGMovHintRemovalPhase.h b/dfg/DFGMovHintRemovalPhase.h
new file mode 100644 (file)
index 0000000..dd4c206
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGMovHintRemovalPhase_h
+#define DFGMovHintRemovalPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Cleans up unnecessary MovHints. A MovHint is necessary if the variable dies before there is an
+// exit.
+
+bool performMovHintRemoval(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGMovHintRemovalPhase_h
diff --git a/dfg/DFGNaiveDominators.cpp b/dfg/DFGNaiveDominators.cpp
new file mode 100644 (file)
index 0000000..eb8c63a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGNaiveDominators.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+NaiveDominators::NaiveDominators()
+{
+}
+
+NaiveDominators::~NaiveDominators()
+{
+}
+
+void NaiveDominators::compute(Graph& graph)
+{
+    // This implements a naive dominator solver.
+    
+    ASSERT(graph.block(0)->predecessors.isEmpty());
+    
+    unsigned numBlocks = graph.numBlocks();
+    
+    // Allocate storage for the dense dominance matrix. 
+    if (numBlocks > m_results.size()) {
+        m_results.grow(numBlocks);
+        for (unsigned i = numBlocks; i--;)
+            m_results[i].resize(numBlocks);
+        m_scratch.resize(numBlocks);
+    }
+
+    // We know that the entry block is only dominated by itself.
+    m_results[0].clearAll();
+    m_results[0].set(0);
+
+    // Find all of the valid blocks.
+    m_scratch.clearAll();
+    for (unsigned i = numBlocks; i--;) {
+        if (!graph.block(i))
+            continue;
+        m_scratch.set(i);
+    }
+    
+    // Mark all nodes as dominated by everything.
+    for (unsigned i = numBlocks; i-- > 1;) {
+        if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
+            m_results[i].clearAll();
+        else
+            m_results[i].set(m_scratch);
+    }
+
+    // Iteratively eliminate nodes that are not dominator.
+    bool changed;
+    do {
+        changed = false;
+        // Prune dominators in all non entry blocks: forward scan.
+        for (unsigned i = 1; i < numBlocks; ++i)
+            changed |= pruneDominators(graph, i);
+
+        if (!changed)
+            break;
+
+        // Prune dominators in all non entry blocks: backward scan.
+        changed = false;
+        for (unsigned i = numBlocks; i-- > 1;)
+            changed |= pruneDominators(graph, i);
+    } while (changed);
+}
+
+bool NaiveDominators::pruneDominators(Graph& graph, BlockIndex idx)
+{
+    BasicBlock* block = graph.block(idx);
+
+    if (!block || block->predecessors.isEmpty())
+        return false;
+
+    // Find the intersection of dom(preds).
+    m_scratch.set(m_results[block->predecessors[0]->index]);
+    for (unsigned j = block->predecessors.size(); j-- > 1;)
+        m_scratch.filter(m_results[block->predecessors[j]->index]);
+
+    // The block is also dominated by itself.
+    m_scratch.set(idx);
+
+    return m_results[idx].setAndCheck(m_scratch);
+}
+
+void NaiveDominators::dump(Graph& graph, PrintStream& out) const
+{
+    for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
+        BasicBlock* block = graph.block(blockIndex);
+        if (!block)
+            continue;
+        out.print("    Block ", *block, ":");
+        for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
+            if (!dominates(block->index, otherIndex))
+                continue;
+            out.print(" #", otherIndex);
+        }
+        out.print("\n");
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGNaiveDominators.h b/dfg/DFGNaiveDominators.h
new file mode 100644 (file)
index 0000000..d88dd3a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGNaiveDominators_h
+#define DFGNaiveDominators_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+#include "DFGCommon.h"
+#include <wtf/FastBitVector.h>
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// This class is only used for validating the real dominators implementation.
+
+class NaiveDominators {
+public:
+    NaiveDominators();
+    ~NaiveDominators();
+    
+    void compute(Graph&);
+    
+    bool dominates(BlockIndex from, BlockIndex to) const
+    {
+        return m_results[to].get(from);
+    }
+    
+    bool dominates(BasicBlock* from, BasicBlock* to) const
+    {
+        return dominates(from->index, to->index);
+    }
+    
+    void dump(Graph&, PrintStream&) const;
+    
+private:
+    bool pruneDominators(Graph&, BlockIndex);
+    
+    Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
+    FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNaiveDominators_h
index b43ba95e587efccf0b6f49325e2cd996f5df2a3f..edb78cf5e5d158b1a46dc8013fdfd10bdf7ac2e0 100644 (file)
@@ -45,6 +45,11 @@ void NaturalLoop::dump(PrintStream& out) const
 NaturalLoops::NaturalLoops() { }
 NaturalLoops::~NaturalLoops() { }
 
+void NaturalLoops::computeDependencies(Graph& graph)
+{
+    graph.m_dominators.computeIfNecessary(graph);
+}
+
 void NaturalLoops::compute(Graph& graph)
 {
     // Implement the classic dominator-based natural loop finder. The first
@@ -57,11 +62,9 @@ void NaturalLoops::compute(Graph& graph)
     
     static const bool verbose = false;
     
-    graph.m_dominators.computeIfNecessary(graph);
-    
     if (verbose) {
         dataLog("Dominators:\n");
-        graph.m_dominators.dump(graph, WTF::dataFile());
+        graph.m_dominators.dump(WTF::dataFile());
     }
     
     m_loops.resize(0);
index 1ac67acf5b920edee2baf402bcdc659290bdbccc..57225e36fd3a1d975b946ae0c610a36c01c26d48 100644 (file)
@@ -93,6 +93,7 @@ public:
     NaturalLoops();
     ~NaturalLoops();
     
+    void computeDependencies(Graph&);
     void compute(Graph&);
     
     unsigned numLoops() const
index 933664a562c8268dcc031a71753e2d33509aa725..6a98534246871ba6b959c0b324e7777a29b42a23 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "DFGGraph.h"
 #include "DFGNodeAllocator.h"
+#include "DFGPromotedHeapLocation.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace DFG {
@@ -37,7 +38,7 @@ namespace JSC { namespace DFG {
 bool MultiPutByOffsetData::writesStructures() const
 {
     for (unsigned i = variants.size(); i--;) {
-        if (variants[i].kind() == PutByIdVariant::Transition)
+        if (variants[i].writesStructures())
             return true;
     }
     return false;
@@ -46,14 +47,8 @@ bool MultiPutByOffsetData::writesStructures() const
 bool MultiPutByOffsetData::reallocatesStorage() const
 {
     for (unsigned i = variants.size(); i--;) {
-        if (variants[i].kind() != PutByIdVariant::Transition)
-            continue;
-        
-        if (variants[i].oldStructure()->outOfLineCapacity() ==
-            variants[i].newStructure()->outOfLineCapacity())
-            continue;
-        
-        return true;
+        if (variants[i].reallocatesStorage())
+            return true;
     }
     return false;
 }
@@ -80,7 +75,6 @@ bool Node::hasVariableAccessData(Graph& graph)
     case Phi:
         return graph.m_form != SSA;
     case GetLocal:
-    case GetArgument:
     case SetLocal:
     case SetArgument:
     case Flush:
@@ -91,6 +85,15 @@ bool Node::hasVariableAccessData(Graph& graph)
     }
 }
 
+void Node::remove()
+{
+    ASSERT(!(flags() & NodeHasVarArgs));
+    
+    children = children.justChecks();
+    
+    setOpAndDefaultFlags(Check);
+}
+
 void Node::convertToIdentity()
 {
     RELEASE_ASSERT(child1());
@@ -100,6 +103,101 @@ void Node::convertToIdentity()
     setResult(result);
 }
 
+void Node::convertToIdentityOn(Node* child)
+{
+    children.reset();
+    child1() = child->defaultEdge();
+    NodeFlags output = canonicalResultRepresentation(this->result());
+    NodeFlags input = canonicalResultRepresentation(child->result());
+    if (output == input) {
+        setOpAndDefaultFlags(Identity);
+        setResult(output);
+        return;
+    }
+    switch (output) {
+    case NodeResultDouble:
+        setOpAndDefaultFlags(DoubleRep);
+        switch (input) {
+        case NodeResultInt52:
+            child1().setUseKind(Int52RepUse);
+            return;
+        case NodeResultJS:
+            child1().setUseKind(NumberUse);
+            return;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+    case NodeResultInt52:
+        setOpAndDefaultFlags(Int52Rep);
+        switch (input) {
+        case NodeResultDouble:
+            child1().setUseKind(DoubleRepMachineIntUse);
+            return;
+        case NodeResultJS:
+            child1().setUseKind(MachineIntUse);
+            return;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+    case NodeResultJS:
+        setOpAndDefaultFlags(ValueRep);
+        switch (input) {
+        case NodeResultDouble:
+            child1().setUseKind(DoubleRepUse);
+            return;
+        case NodeResultInt52:
+            child1().setUseKind(Int52RepUse);
+            return;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return;
+    }
+}
+
+void Node::convertToPutHint(const PromotedLocationDescriptor& descriptor, Node* base, Node* value)
+{
+    m_op = PutHint;
+    m_opInfo = descriptor.imm1().m_value;
+    m_opInfo2 = descriptor.imm2().m_value;
+    child1() = base->defaultEdge();
+    child2() = value->defaultEdge();
+    child3() = Edge();
+}
+
+void Node::convertToPutStructureHint(Node* structure)
+{
+    ASSERT(m_op == PutStructure);
+    ASSERT(structure->castConstant<Structure*>() == transition()->next);
+    convertToPutHint(StructurePLoc, child1().node(), structure);
+}
+
+void Node::convertToPutByOffsetHint()
+{
+    ASSERT(m_op == PutByOffset);
+    convertToPutHint(
+        PromotedLocationDescriptor(NamedPropertyPLoc, storageAccessData().identifierNumber),
+        child2().node(), child3().node());
+}
+
+void Node::convertToPutClosureVarHint()
+{
+    ASSERT(m_op == PutClosureVar);
+    convertToPutHint(
+        PromotedLocationDescriptor(ClosureVarPLoc, scopeOffset().offset()),
+        child1().node(), child2().node());
+}
+
+PromotedLocationDescriptor Node::promotedLocationDescriptor()
+{
+    return PromotedLocationDescriptor(static_cast<PromotedLocationKind>(m_opInfo), m_opInfo2);
+}
+
 } } // namespace JSC::DFG
 
 namespace WTF {
@@ -119,6 +217,9 @@ void printInternal(PrintStream& out, SwitchKind kind)
     case SwitchString:
         out.print("SwitchString");
         return;
+    case SwitchCell:
+        out.print("SwitchCell");
+        return;
     }
     RELEASE_ASSERT_NOT_REACHED();
 }
index 36881421a624855f789e59942f1f4cb95188cf8b..9ca2cdc6818a23bc2a6b7c13630c4b922bbed31f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
+#include "BasicBlockLocation.h"
 #include "CodeBlock.h"
 #include "DFGAbstractValue.h"
 #include "DFGAdjacencyList.h"
 #include "DFGArithMode.h"
 #include "DFGArrayMode.h"
 #include "DFGCommon.h"
+#include "DFGEpoch.h"
 #include "DFGLazyJSValue.h"
 #include "DFGNodeFlags.h"
 #include "DFGNodeOrigin.h"
 #include "DFGNodeType.h"
+#include "DFGObjectMaterializationData.h"
+#include "DFGTransition.h"
 #include "DFGUseKind.h"
 #include "DFGVariableAccessData.h"
 #include "GetByIdVariant.h"
 #include "PutByIdVariant.h"
 #include "SpeculatedType.h"
 #include "StructureSet.h"
+#include "TypeLocation.h"
 #include "ValueProfile.h"
 #include <wtf/ListDump.h>
 
 namespace JSC { namespace DFG {
 
 class Graph;
+class PromotedLocationDescriptor;
 struct BasicBlock;
 
+struct StorageAccessData {
+    PropertyOffset offset;
+    unsigned identifierNumber;
+};
+
 struct MultiGetByOffsetData {
     unsigned identifierNumber;
     Vector<GetByIdVariant, 2> variants;
@@ -67,19 +78,6 @@ struct MultiPutByOffsetData {
     bool reallocatesStorage() const;
 };
 
-struct StructureTransitionData {
-    Structure* previousStructure;
-    Structure* newStructure;
-    
-    StructureTransitionData() { }
-    
-    StructureTransitionData(Structure* previousStructure, Structure* newStructure)
-        : previousStructure(previousStructure)
-        , newStructure(newStructure)
-    {
-    }
-};
-
 struct NewArrayBufferData {
     unsigned startConstant;
     unsigned numConstants;
@@ -169,12 +167,6 @@ struct SwitchCase {
     BranchTarget target;
 };
 
-enum SwitchKind {
-    SwitchImm,
-    SwitchChar,
-    SwitchString
-};
-
 struct SwitchData {
     // Initializes most fields to obviously invalid values. Anyone
     // constructing this should make sure to initialize everything they
@@ -193,10 +185,44 @@ struct SwitchData {
     bool didUseJumpTable;
 };
 
+struct CallVarargsData {
+    int firstVarArgOffset;
+};
+
+struct LoadVarargsData {
+    VirtualRegister start; // Local for the first element. This is the first actual argument, not this.
+    VirtualRegister count; // Local for the count.
+    VirtualRegister machineStart;
+    VirtualRegister machineCount;
+    unsigned offset; // Which array element to start with. Usually this is 0.
+    unsigned mandatoryMinimum; // The number of elements on the stack that must be initialized; if the array is too short then the missing elements must get undefined. Does not include "this".
+    unsigned limit; // Maximum number of elements to load. Includes "this".
+};
+
+struct StackAccessData {
+    StackAccessData()
+        : format(DeadFlush)
+    {
+    }
+    
+    StackAccessData(VirtualRegister local, FlushFormat format)
+        : local(local)
+        , format(format)
+    {
+    }
+    
+    VirtualRegister local;
+    VirtualRegister machineLocal;
+    FlushFormat format;
+    
+    FlushedAt flushedAt() { return FlushedAt(format, machineLocal); }
+};
+
 // This type used in passing an immediate argument to Node constructor;
 // distinguishes an immediate value (typically an index into a CodeBlock data structure - 
 // a constant index, argument, or identifier) from a Node*.
 struct OpInfo {
+    OpInfo() : m_value(0) { }
     explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
     explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
 #if OS(DARWIN) || USE(JSVALUE64)
@@ -220,8 +246,9 @@ struct Node {
         , m_virtualRegister(VirtualRegister())
         , m_refCount(1)
         , m_prediction(SpecNone)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
     }
     
@@ -234,8 +261,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(0)
         , m_opInfo2(0)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         ASSERT(!(m_flags & NodeHasVarArgs));
     }
@@ -249,8 +277,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(0)
         , m_opInfo2(0)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         setResult(result);
         ASSERT(!(m_flags & NodeHasVarArgs));
@@ -265,8 +294,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(imm.m_value)
         , m_opInfo2(0)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         ASSERT(!(m_flags & NodeHasVarArgs));
     }
@@ -280,8 +310,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(imm.m_value)
         , m_opInfo2(0)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         setResult(result);
         ASSERT(!(m_flags & NodeHasVarArgs));
@@ -296,8 +327,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(imm1.m_value)
         , m_opInfo2(imm2.m_value)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         ASSERT(!(m_flags & NodeHasVarArgs));
     }
@@ -311,8 +343,9 @@ struct Node {
         , m_prediction(SpecNone)
         , m_opInfo(imm1.m_value)
         , m_opInfo2(imm2.m_value)
+        , owner(nullptr)
     {
-        misc.replacement = 0;
+        m_misc.replacement = nullptr;
         setOpAndDefaultFlags(op);
         ASSERT(m_flags & NodeHasVarArgs);
     }
@@ -335,7 +368,6 @@ struct Node {
     
     bool mergeFlags(NodeFlags flags)
     {
-        ASSERT(!(flags & NodeDoesNotExit));
         NodeFlags newFlags = m_flags | flags;
         if (newFlags == m_flags)
             return false;
@@ -345,7 +377,6 @@ struct Node {
     
     bool filterFlags(NodeFlags flags)
     {
-        ASSERT(flags & NodeDoesNotExit);
         NodeFlags newFlags = m_flags & flags;
         if (newFlags == m_flags)
             return false;
@@ -376,36 +407,35 @@ struct Node {
         m_flags = defaultFlags(op);
     }
 
-    void convertToPhantom()
+    void remove();
+
+    void convertToCheckStructure(StructureSet* set)
     {
-        setOpAndDefaultFlags(Phantom);
+        setOpAndDefaultFlags(CheckStructure);
+        m_opInfo = bitwise_cast<uintptr_t>(set); 
     }
 
-    void convertToPhantomUnchecked()
+    void convertToCheckStructureImmediate(Node* structure)
     {
-        setOpAndDefaultFlags(Phantom);
+        ASSERT(op() == CheckStructure);
+        m_op = CheckStructureImmediate;
+        children.setChild1(Edge(structure, CellUse));
+    }
+    
+    void replaceWith(Node* other)
+    {
+        remove();
+        setReplacement(other);
     }
 
     void convertToIdentity();
+    void convertToIdentityOn(Node*);
 
     bool mustGenerate()
     {
         return m_flags & NodeMustGenerate;
     }
     
-    void setCanExit(bool exits)
-    {
-        if (exits)
-            m_flags &= ~NodeDoesNotExit;
-        else
-            m_flags |= NodeDoesNotExit;
-    }
-    
-    bool canExit()
-    {
-        return !(m_flags & NodeDoesNotExit);
-    }
-    
     bool isConstant()
     {
         switch (op()) {
@@ -418,37 +448,40 @@ struct Node {
         }
     }
     
-    bool isWeakConstant()
-    {
-        return op() == WeakJSConstant;
-    }
-    
-    bool isPhantomArguments()
-    {
-        return op() == PhantomArguments;
-    }
-    
     bool hasConstant()
     {
         switch (op()) {
         case JSConstant:
         case DoubleConstant:
         case Int52Constant:
-        case WeakJSConstant:
-        case PhantomArguments:
             return true;
+            
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+            // These pretend to be the empty value constant for the benefit of the DFG backend, which
+            // otherwise wouldn't take kindly to a node that doesn't compute a value.
+            return true;
+            
         default:
             return false;
         }
     }
 
-    unsigned constantNumber()
+    FrozenValue* constant()
     {
-        ASSERT(isConstant());
-        return m_opInfo;
+        ASSERT(hasConstant());
+        
+        if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
+            // These pretend to be the empty value constant for the benefit of the DFG backend, which
+            // otherwise wouldn't take kindly to a node that doesn't compute a value.
+            return FrozenValue::emptySingleton();
+        }
+        
+        return bitwise_cast<FrozenValue*>(m_opInfo);
     }
     
-    void convertToConstant(unsigned constantNumber)
+    // Don't call this directly - use Graph::convertToConstant() instead!
+    void convertToConstant(FrozenValue* value)
     {
         if (hasDoubleResult())
             m_op = DoubleConstant;
@@ -456,16 +489,8 @@ struct Node {
             m_op = Int52Constant;
         else
             m_op = JSConstant;
-        m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
-        m_opInfo = constantNumber;
-        children.reset();
-    }
-    
-    void convertToWeakConstant(JSCell* cell)
-    {
-        m_op = WeakJSConstant;
-        m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
-        m_opInfo = bitwise_cast<uintptr_t>(cell);
+        m_flags &= ~NodeMustGenerate;
+        m_opInfo = bitwise_cast<uintptr_t>(value);
         children.reset();
     }
     
@@ -474,54 +499,111 @@ struct Node {
         ASSERT(op() == GetIndexedPropertyStorage);
         m_op = ConstantStoragePointer;
         m_opInfo = bitwise_cast<uintptr_t>(pointer);
+        children.reset();
     }
     
     void convertToGetLocalUnlinked(VirtualRegister local)
     {
         m_op = GetLocalUnlinked;
-        m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
+        m_flags &= ~NodeMustGenerate;
         m_opInfo = local.offset();
         m_opInfo2 = VirtualRegister().offset();
         children.reset();
     }
     
-    void convertToStructureTransitionWatchpoint(Structure* structure)
+    void convertToPutStack(StackAccessData* data)
     {
-        ASSERT(m_op == CheckStructure || m_op == ArrayifyToStructure);
-        ASSERT(!child2());
-        ASSERT(!child3());
-        m_opInfo = bitwise_cast<uintptr_t>(structure);
-        m_op = StructureTransitionWatchpoint;
+        m_op = PutStack;
+        m_flags |= NodeMustGenerate;
+        m_opInfo = bitwise_cast<uintptr_t>(data);
+        m_opInfo2 = 0;
     }
     
-    void convertToStructureTransitionWatchpoint()
+    void convertToGetStack(StackAccessData* data)
     {
-        convertToStructureTransitionWatchpoint(structureSet().singletonStructure());
+        m_op = GetStack;
+        m_flags &= ~NodeMustGenerate;
+        m_opInfo = bitwise_cast<uintptr_t>(data);
+        m_opInfo2 = 0;
+        children.reset();
     }
     
-    void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
+    void convertToGetByOffset(StorageAccessData& data, Edge storage)
     {
         ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
-        m_opInfo = storageAccessDataIndex;
+        m_opInfo = bitwise_cast<uintptr_t>(&data);
         children.setChild2(children.child1());
         children.child2().setUseKind(KnownCellUse);
         children.setChild1(storage);
         m_op = GetByOffset;
-        m_flags &= ~NodeClobbersWorld;
+        m_flags &= ~NodeMustGenerate;
     }
     
-    void convertToPutByOffset(unsigned storageAccessDataIndex, Edge storage)
+    void convertToMultiGetByOffset(MultiGetByOffsetData* data)
     {
-        ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == MultiPutByOffset);
-        m_opInfo = storageAccessDataIndex;
+        ASSERT(m_op == GetById || m_op == GetByIdFlush);
+        m_opInfo = bitwise_cast<intptr_t>(data);
+        child1().setUseKind(CellUse);
+        m_op = MultiGetByOffset;
+        ASSERT(m_flags & NodeMustGenerate);
+    }
+    
+    void convertToPutByOffset(StorageAccessData& data, Edge storage)
+    {
+        ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
+        m_opInfo = bitwise_cast<uintptr_t>(&data);
         children.setChild3(children.child2());
         children.setChild2(children.child1());
         children.setChild1(storage);
         m_op = PutByOffset;
-        m_flags &= ~NodeClobbersWorld;
     }
     
-    void convertToPhantomLocal()
+    void convertToMultiPutByOffset(MultiPutByOffsetData* data)
+    {
+        ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
+        m_opInfo = bitwise_cast<intptr_t>(data);
+        m_op = MultiPutByOffset;
+    }
+    
+    void convertToPutHint(const PromotedLocationDescriptor&, Node* base, Node* value);
+    
+    void convertToPutByOffsetHint();
+    void convertToPutStructureHint(Node* structure);
+    void convertToPutClosureVarHint();
+    
+    void convertToPhantomNewObject()
+    {
+        ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
+        m_op = PhantomNewObject;
+        m_flags &= ~NodeHasVarArgs;
+        m_flags |= NodeMustGenerate;
+        m_opInfo = 0;
+        m_opInfo2 = 0;
+        children = AdjacencyList();
+    }
+
+    void convertToPhantomNewFunction()
+    {
+        ASSERT(m_op == NewFunction);
+        m_op = PhantomNewFunction;
+        m_flags |= NodeMustGenerate;
+        m_opInfo = 0;
+        m_opInfo2 = 0;
+        children = AdjacencyList();
+    }
+
+    void convertToPhantomCreateActivation()
+    {
+        ASSERT(m_op == CreateActivation || m_op == MaterializeCreateActivation);
+        m_op = PhantomCreateActivation;
+        m_flags &= ~NodeHasVarArgs;
+        m_flags |= NodeMustGenerate;
+        m_opInfo = 0;
+        m_opInfo2 = 0;
+        children = AdjacencyList();
+    }
+
+    void convertPhantomToPhantomLocal()
     {
         ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
         m_op = PhantomLocal;
@@ -529,6 +611,13 @@ struct Node {
         children.setChild1(Edge());
     }
     
+    void convertFlushToPhantomLocal()
+    {
+        ASSERT(m_op == Flush);
+        m_op = PhantomLocal;
+        children = AdjacencyList();
+    }
+    
     void convertToGetLocal(VariableAccessData* variable, Node* phi)
     {
         ASSERT(m_op == GetLocalUnlinked);
@@ -543,60 +632,95 @@ struct Node {
         ASSERT(m_op == ToPrimitive);
         m_op = ToString;
     }
-    
-    JSCell* weakConstant()
+
+    void convertToArithSqrt()
     {
-        ASSERT(op() == WeakJSConstant);
-        return bitwise_cast<JSCell*>(m_opInfo);
+        ASSERT(m_op == ArithPow);
+        child2() = Edge();
+        m_op = ArithSqrt;
     }
     
-    JSValue valueOfJSConstant(CodeBlock* codeBlock)
+    JSValue asJSValue()
     {
-        switch (op()) {
-        case WeakJSConstant:
-            return JSValue(weakConstant());
-        case JSConstant:
-        case DoubleConstant:
-        case Int52Constant:
-            return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
-        case PhantomArguments:
-            return JSValue();
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return JSValue(); // Have to return something in release mode.
-        }
+        return constant()->value();
     }
-
-    bool isInt32Constant(CodeBlock* codeBlock)
+     
+    bool isInt32Constant()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isInt32();
+        return isConstant() && constant()->value().isInt32();
     }
-    
-    bool isDoubleConstant(CodeBlock* codeBlock)
+     
+    int32_t asInt32()
     {
-        bool result = isConstant() && valueOfJSConstant(codeBlock).isDouble();
-        if (result)
-            ASSERT(!isInt32Constant(codeBlock));
-        return result;
+        return asJSValue().asInt32();
     }
-    
-    bool isNumberConstant(CodeBlock* codeBlock)
+     
+    uint32_t asUInt32()
     {
-        bool result = isConstant() && valueOfJSConstant(codeBlock).isNumber();
-        ASSERT(result == (isInt32Constant(codeBlock) || isDoubleConstant(codeBlock)));
-        return result;
+        return asInt32();
     }
-    
-    bool isMachineIntConstant(CodeBlock* codeBlock)
+     
+    bool isDoubleConstant()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isMachineInt();
+        return isConstant() && constant()->value().isDouble();
+    }
+     
+    bool isNumberConstant()
+    {
+        return isConstant() && constant()->value().isNumber();
     }
     
-    bool isBooleanConstant(CodeBlock* codeBlock)
+    double asNumber()
     {
-        return isConstant() && valueOfJSConstant(codeBlock).isBoolean();
+        return asJSValue().asNumber();
+    }
+     
+    bool isMachineIntConstant()
+    {
+        return isConstant() && constant()->value().isMachineInt();
+    }
+     
+    int64_t asMachineInt()
+    {
+        return asJSValue().asMachineInt();
+    }
+     
+    bool isBooleanConstant()
+    {
+        return isConstant() && constant()->value().isBoolean();
+    }
+     
+    bool asBoolean()
+    {
+        return constant()->value().asBoolean();
+    }
+     
+    bool isCellConstant()
+    {
+        return isConstant() && constant()->value() && constant()->value().isCell();
+    }
+     
+    JSCell* asCell()
+    {
+        return constant()->value().asCell();
+    }
+     
+    template<typename T>
+    T dynamicCastConstant()
+    {
+        if (!isCellConstant())
+            return nullptr;
+        return jsDynamicCast<T>(asCell());
     }
     
+    template<typename T>
+    T castConstant()
+    {
+        T result = dynamicCastConstant<T>();
+        RELEASE_ASSERT(result);
+        return result;
+    }
+     
     bool containsMovHint()
     {
         switch (op()) {
@@ -646,6 +770,7 @@ struct Node {
         case ExtractOSREntryLocal:
         case MovHint:
         case ZombieHint:
+        case KillStack:
             return true;
         default:
             return false;
@@ -675,6 +800,23 @@ struct Node {
         return VirtualRegister(m_opInfo2);
     }
     
+    bool hasStackAccessData()
+    {
+        switch (op()) {
+        case PutStack:
+        case GetStack:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
+    StackAccessData* stackAccessData()
+    {
+        ASSERT(hasStackAccessData());
+        return bitwise_cast<StackAccessData*>(m_opInfo);
+    }
+    
     bool hasPhi()
     {
         return op() == Upsilon;
@@ -688,13 +830,7 @@ struct Node {
 
     bool isStoreBarrier()
     {
-        switch (op()) {
-        case StoreBarrier:
-        case StoreBarrierWithNullCheck:
-            return true;
-        default:
-            return false;
-        }
+        return op() == StoreBarrier;
     }
 
     bool hasIdentifier()
@@ -717,33 +853,20 @@ struct Node {
         return m_opInfo;
     }
     
-    bool hasArithNodeFlags()
+    bool hasPromotedLocationDescriptor()
     {
-        switch (op()) {
-        case UInt32ToNumber:
-        case ArithAdd:
-        case ArithSub:
-        case ArithNegate:
-        case ArithMul:
-        case ArithAbs:
-        case ArithMin:
-        case ArithMax:
-        case ArithMod:
-        case ArithDiv:
-        case ValueAdd:
-            return true;
-        default:
-            return false;
-        }
+        return op() == PutHint;
     }
     
+    PromotedLocationDescriptor promotedLocationDescriptor();
+    
     // This corrects the arithmetic node flags, so that irrelevant bits are
     // ignored. In particular, anything other than ArithMul does not need
     // to know if it can speculate on negative zero.
     NodeFlags arithNodeFlags()
     {
         NodeFlags result = m_flags & NodeArithFlagsMask;
-        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == DoubleAsInt32)
+        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
             return result;
         return result & ~NodeBytecodeNeedsNegZero;
     }
@@ -835,15 +958,26 @@ struct Node {
         return m_opInfo;
     }
     
-    bool hasVarNumber()
+    bool hasScopeOffset()
     {
         return op() == GetClosureVar || op() == PutClosureVar;
     }
 
-    int varNumber()
+    ScopeOffset scopeOffset()
     {
-        ASSERT(hasVarNumber());
-        return m_opInfo;
+        ASSERT(hasScopeOffset());
+        return ScopeOffset(m_opInfo);
+    }
+    
+    bool hasDirectArgumentsOffset()
+    {
+        return op() == GetFromArguments || op() == PutToArguments;
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffset()
+    {
+        ASSERT(hasDirectArgumentsOffset());
+        return DirectArgumentsOffset(m_opInfo);
     }
     
     bool hasRegisterPointer()
@@ -851,11 +985,41 @@ struct Node {
         return op() == GetGlobalVar || op() == PutGlobalVar;
     }
     
-    WriteBarrier<Unknown>* registerPointer()
+    WriteBarrier<Unknown>* variablePointer()
     {
         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
     }
     
+    bool hasCallVarargsData()
+    {
+        switch (op()) {
+        case CallVarargs:
+        case CallForwardVarargs:
+        case ConstructVarargs:
+        case ConstructForwardVarargs:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
+    CallVarargsData* callVarargsData()
+    {
+        ASSERT(hasCallVarargsData());
+        return bitwise_cast<CallVarargsData*>(m_opInfo);
+    }
+    
+    bool hasLoadVarargsData()
+    {
+        return op() == LoadVarargs || op() == ForwardVarargs;
+    }
+    
+    LoadVarargsData* loadVarargsData()
+    {
+        ASSERT(hasLoadVarargsData());
+        return bitwise_cast<LoadVarargsData*>(m_opInfo);
+    }
+    
     bool hasResult()
     {
         return !!result();
@@ -994,6 +1158,76 @@ struct Node {
         }
     }
     
+    class SuccessorsIterable {
+    public:
+        SuccessorsIterable()
+            : m_terminal(nullptr)
+        {
+        }
+        
+        SuccessorsIterable(Node* terminal)
+            : m_terminal(terminal)
+        {
+        }
+        
+        class iterator {
+        public:
+            iterator()
+                : m_terminal(nullptr)
+                , m_index(UINT_MAX)
+            {
+            }
+            
+            iterator(Node* terminal, unsigned index)
+                : m_terminal(terminal)
+                , m_index(index)
+            {
+            }
+            
+            BasicBlock* operator*()
+            {
+                return m_terminal->successor(m_index);
+            }
+            
+            iterator& operator++()
+            {
+                m_index++;
+                return *this;
+            }
+            
+            bool operator==(const iterator& other) const
+            {
+                return m_index == other.m_index;
+            }
+            
+            bool operator!=(const iterator& other) const
+            {
+                return !(*this == other);
+            }
+        private:
+            Node* m_terminal;
+            unsigned m_index;
+        };
+        
+        iterator begin()
+        {
+            return iterator(m_terminal, 0);
+        }
+        
+        iterator end()
+        {
+            return iterator(m_terminal, m_terminal->numSuccessors());
+        }
+        
+    private:
+        Node* m_terminal;
+    };
+    
+    SuccessorsIterable successors()
+    {
+        return SuccessorsIterable(this);
+    }
+    
     BasicBlock*& successorForCondition(bool condition)
     {
         return branchData()->forCondition(condition);
@@ -1002,16 +1236,22 @@ struct Node {
     bool hasHeapPrediction()
     {
         switch (op()) {
+        case ArithRound:
+        case GetDirectPname:
         case GetById:
         case GetByIdFlush:
         case GetByVal:
-        case GetMyArgumentByVal:
-        case GetMyArgumentByValSafe:
         case Call:
         case Construct:
+        case CallVarargs:
+        case ConstructVarargs:
+        case CallForwardVarargs:
+        case NativeCall:
+        case NativeConstruct:
         case GetByOffset:
         case MultiGetByOffset:
         case GetClosureVar:
+        case GetFromArguments:
         case ArrayPop:
         case ArrayPush:
         case RegExpExec:
@@ -1028,67 +1268,61 @@ struct Node {
         ASSERT(hasHeapPrediction());
         return static_cast<SpeculatedType>(m_opInfo2);
     }
-    
-    bool predictHeap(SpeculatedType prediction)
-    {
-        ASSERT(hasHeapPrediction());
-        
-        return mergeSpeculation(m_opInfo2, prediction);
-    }
-    
+
     void setHeapPrediction(SpeculatedType prediction)
     {
         ASSERT(hasHeapPrediction());
         m_opInfo2 = prediction;
     }
     
-    bool hasFunction()
+    bool hasCellOperand()
     {
         switch (op()) {
-        case CheckFunction:
-        case AllocationProfileWatchpoint:
+        case CheckCell:
+        case NativeConstruct:
+        case NativeCall:
+        case NewFunction:
+        case CreateActivation:
+        case MaterializeCreateActivation:
             return true;
         default:
             return false;
         }
     }
 
-    JSCell* function()
+    FrozenValue* cellOperand()
     {
-        ASSERT(hasFunction());
-        JSCell* result = reinterpret_cast<JSFunction*>(m_opInfo);
-        ASSERT(JSValue(result).isFunction());
-        return result;
-    }
-    
-    bool hasExecutable()
-    {
-        return op() == CheckExecutable;
-    }
-    
-    ExecutableBase* executable()
-    {
-        return jsCast<ExecutableBase*>(reinterpret_cast<JSCell*>(m_opInfo));
+        ASSERT(hasCellOperand());
+        switch (op()) {
+        case MaterializeCreateActivation:
+            return reinterpret_cast<FrozenValue*>(m_opInfo2);
+        default:
+            return reinterpret_cast<FrozenValue*>(m_opInfo);
+        }
+        RELEASE_ASSERT_NOT_REACHED();
     }
     
-    bool hasVariableWatchpointSet()
+    template<typename T>
+    T castOperand()
     {
-        return op() == NotifyWrite || op() == VariableWatchpoint;
+        return cellOperand()->cast<T>();
     }
     
-    VariableWatchpointSet* variableWatchpointSet()
+    void setCellOperand(FrozenValue* value)
     {
-        return reinterpret_cast<VariableWatchpointSet*>(m_opInfo);
+        ASSERT(hasCellOperand());
+        m_opInfo = bitwise_cast<uintptr_t>(value);
     }
     
-    bool hasTypedArray()
+    bool hasWatchpointSet()
     {
-        return op() == TypedArrayWatchpoint;
+        return op() == NotifyWrite;
     }
     
-    JSArrayBufferView* typedArray()
+    WatchpointSet* watchpointSet()
     {
-        return reinterpret_cast<JSArrayBufferView*>(m_opInfo);
+        ASSERT(hasWatchpointSet());
+        return reinterpret_cast<WatchpointSet*>(m_opInfo);
     }
     
     bool hasStoragePointer()
@@ -1098,14 +1332,14 @@ struct Node {
     
     void* storagePointer()
     {
+        ASSERT(hasStoragePointer());
         return reinterpret_cast<void*>(m_opInfo);
     }
 
-    bool hasStructureTransitionData()
+    bool hasTransition()
     {
         switch (op()) {
         case PutStructure:
-        case PhantomPutStructure:
         case AllocatePropertyStorage:
         case ReallocatePropertyStorage:
             return true;
@@ -1114,16 +1348,17 @@ struct Node {
         }
     }
     
-    StructureTransitionData& structureTransitionData()
+    Transition* transition()
     {
-        ASSERT(hasStructureTransitionData());
-        return *reinterpret_cast<StructureTransitionData*>(m_opInfo);
+        ASSERT(hasTransition());
+        return reinterpret_cast<Transition*>(m_opInfo);
     }
     
     bool hasStructureSet()
     {
         switch (op()) {
         case CheckStructure:
+        case CheckStructureImmediate:
             return true;
         default:
             return false;
@@ -1139,7 +1374,6 @@ struct Node {
     bool hasStructure()
     {
         switch (op()) {
-        case StructureTransitionWatchpoint:
         case ArrayifyToStructure:
         case NewObject:
         case NewStringObject:
@@ -1157,13 +1391,20 @@ struct Node {
     
     bool hasStorageAccessData()
     {
-        return op() == GetByOffset || op() == PutByOffset;
+        switch (op()) {
+        case GetByOffset:
+        case PutByOffset:
+        case GetGetterSetterByOffset:
+            return true;
+        default:
+            return false;
+        }
     }
     
-    unsigned storageAccessDataIndex()
+    StorageAccessData& storageAccessData()
     {
         ASSERT(hasStorageAccessData());
-        return m_opInfo;
+        return *bitwise_cast<StorageAccessData*>(m_opInfo);
     }
     
     bool hasMultiGetByOffsetData()
@@ -1173,6 +1414,7 @@ struct Node {
     
     MultiGetByOffsetData& multiGetByOffsetData()
     {
+        ASSERT(hasMultiGetByOffsetData());
         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
     }
     
@@ -1183,41 +1425,102 @@ struct Node {
     
     MultiPutByOffsetData& multiPutByOffsetData()
     {
+        ASSERT(hasMultiPutByOffsetData());
         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
     }
     
-    bool hasFunctionDeclIndex()
+    bool hasObjectMaterializationData()
     {
-        return op() == NewFunction
-            || op() == NewFunctionNoCheck;
+        switch (op()) {
+        case MaterializeNewObject:
+        case MaterializeCreateActivation:
+            return true;
+
+        default:
+            return false;
+        }
     }
     
-    unsigned functionDeclIndex()
+    ObjectMaterializationData& objectMaterializationData()
     {
-        ASSERT(hasFunctionDeclIndex());
-        return m_opInfo;
+        ASSERT(hasObjectMaterializationData());
+        return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
     }
-    
-    bool hasFunctionExprIndex()
+
+    bool isObjectAllocation()
     {
-        return op() == NewFunctionExpression;
+        switch (op()) {
+        case NewObject:
+        case MaterializeNewObject:
+            return true;
+        default:
+            return false;
+        }
     }
     
-    unsigned functionExprIndex()
+    bool isPhantomObjectAllocation()
     {
-        ASSERT(hasFunctionExprIndex());
-        return m_opInfo;
+        switch (op()) {
+        case PhantomNewObject:
+            return true;
+        default:
+            return false;
+        }
     }
     
-    bool hasSymbolTable()
+    bool isActivationAllocation()
     {
-        return op() == FunctionReentryWatchpoint;
+        switch (op()) {
+        case CreateActivation:
+        case MaterializeCreateActivation:
+            return true;
+        default:
+            return false;
+        }
     }
-    
-    SymbolTable* symbolTable()
+
+    bool isPhantomActivationAllocation()
+    {
+        switch (op()) {
+        case PhantomCreateActivation:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isFunctionAllocation()
+    {
+        switch (op()) {
+        case NewFunction:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isPhantomFunctionAllocation()
     {
-        ASSERT(hasSymbolTable());
-        return reinterpret_cast<SymbolTable*>(m_opInfo);
+        switch (op()) {
+        case PhantomNewFunction:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isPhantomAllocation()
+    {
+        switch (op()) {
+        case PhantomNewObject:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case PhantomNewFunction:
+        case PhantomCreateActivation:
+            return true;
+        default:
+            return false;
+        }
     }
     
     bool hasArrayMode()
@@ -1236,6 +1539,7 @@ struct Node {
         case ArrayifyToStructure:
         case ArrayPush:
         case ArrayPop:
+        case HasIndexedProperty:
             return true;
         default:
             return false;
@@ -1286,6 +1590,23 @@ struct Node {
     {
         m_opInfo = mode;
     }
+
+    bool hasArithRoundingMode()
+    {
+        return op() == ArithRound;
+    }
+
+    Arith::RoundingMode arithRoundingMode()
+    {
+        ASSERT(hasArithRoundingMode());
+        return static_cast<Arith::RoundingMode>(m_opInfo);
+    }
+
+    void setArithRoundingMode(Arith::RoundingMode mode)
+    {
+        ASSERT(hasArithRoundingMode());
+        m_opInfo = static_cast<uintptr_t>(mode);
+    }
     
     bool hasVirtualRegister()
     {
@@ -1321,22 +1642,6 @@ struct Node {
         return m_refCount;
     }
     
-    bool willHaveCodeGenOrOSR()
-    {
-        switch (op()) {
-        case SetLocal:
-        case MovHint:
-        case ZombieHint:
-        case PhantomArguments:
-            return true;
-        case Phantom:
-        case HardPhantom:
-            return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
-        default:
-            return shouldGenerate();
-        }
-    }
-    
     bool isSemanticallySkippable()
     {
         return op() == CountExecution;
@@ -1477,6 +1782,11 @@ struct Node {
         return isDoubleSpeculation(prediction());
     }
     
+    bool shouldSpeculateDoubleReal()
+    {
+        return isDoubleRealSpeculation(prediction());
+    }
+    
     bool shouldSpeculateNumber()
     {
         return isFullNumberSpeculation(prediction());
@@ -1547,9 +1857,14 @@ struct Node {
         return isArraySpeculation(prediction());
     }
     
-    bool shouldSpeculateArguments()
+    bool shouldSpeculateDirectArguments()
+    {
+        return isDirectArgumentsSpeculation(prediction());
+    }
+    
+    bool shouldSpeculateScopedArguments()
     {
-        return isArgumentsSpeculation(prediction());
+        return isScopedArgumentsSpeculation(prediction());
     }
     
     bool shouldSpeculateInt8Array()
@@ -1617,6 +1932,11 @@ struct Node {
         return isCellSpeculation(prediction());
     }
     
+    bool shouldSpeculateNotCell()
+    {
+        return isNotCellSpeculation(prediction());
+    }
+    
     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
     {
         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
@@ -1703,6 +2023,48 @@ struct Node {
     {
         return canSpeculateInt52(sourceFor(pass));
     }
+
+    bool hasTypeLocation()
+    {
+        return op() == ProfileType;
+    }
+
+    TypeLocation* typeLocation()
+    {
+        ASSERT(hasTypeLocation());
+        return reinterpret_cast<TypeLocation*>(m_opInfo);
+    }
+
+    bool hasBasicBlockLocation()
+    {
+        return op() == ProfileControlFlow;
+    }
+
+    BasicBlockLocation* basicBlockLocation()
+    {
+        ASSERT(hasBasicBlockLocation());
+        return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
+    }
+    
+    Node* replacement() const
+    {
+        return m_misc.replacement;
+    }
+    
+    void setReplacement(Node* replacement)
+    {
+        m_misc.replacement = replacement;
+    }
+    
+    Epoch epoch() const
+    {
+        return Epoch::fromUnsigned(m_misc.epoch);
+    }
+    
+    void setEpoch(Epoch epoch)
+    {
+        m_misc.epoch = epoch.toUnsigned();
+    }
     
     void dumpChildren(PrintStream& out)
     {
@@ -1743,19 +2105,22 @@ public:
     AbstractValue value;
     
     // Miscellaneous data that is usually meaningless, but can hold some analysis results
-    // if you ask right. For example, if you do Graph::initializeNodeOwners(), misc.owner
+    // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
     // will tell you which basic block a node belongs to. You cannot rely on this persisting
     // across transformations unless you do the maintenance work yourself. Other phases use
-    // misc.replacement, but they do so manually: first you do Graph::clearReplacements()
-    // and then you set, and use, replacement's yourself.
+    // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
+    // and then you set, and use, replacement's yourself. Same thing for epoch.
     //
     // Bottom line: don't use these fields unless you initialize them yourself, or by
     // calling some appropriate methods that initialize them the way you want. Otherwise,
     // these fields are meaningless.
+private:
     union {
         Node* replacement;
-        BasicBlock* owner;
-    } misc;
+        unsigned epoch;
+    } m_misc;
+public:
+    BasicBlock* owner;
 };
 
 inline bool nodeComparator(Node* a, Node* b)
index e3181ca2f17c53653aae56d64c09341fbfdc4ad3..366fbecebb8b42af1b72a02eca1674c8cc8b6293 100644 (file)
@@ -74,12 +74,6 @@ void dumpNodeFlags(PrintStream& actualOut, NodeFlags flags)
     if (flags & NodeHasVarArgs)
         out.print(comma, "VarArgs");
     
-    if (flags & NodeClobbersWorld)
-        out.print(comma, "Clobbers");
-    
-    if (flags & NodeMightClobber)
-        out.print(comma, "MightClobber");
-    
     if (flags & NodeResultMask) {
         if (!(flags & NodeBytecodeUsesAsNumber) && !(flags & NodeBytecodeNeedsNegZero))
             out.print(comma, "PureInt");
@@ -109,9 +103,6 @@ void dumpNodeFlags(PrintStream& actualOut, NodeFlags flags)
     if (flags & NodeBytecodeUsesAsArrayIndex)
         out.print(comma, "ReallyWantsInt");
     
-    if (!(flags & NodeDoesNotExit))
-        out.print(comma, "CanExit");
-    
     if (flags & NodeIsFlushed)
         out.print(comma, "IsFlushed");
     
index 8243b751fedfe58bb67a830460fd48c284a3b16f..4db2a43e73412d28b069094e79a5847f67bb84be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,8 +46,7 @@ namespace JSC { namespace DFG {
                                 
 #define NodeMustGenerate                 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
 #define NodeHasVarArgs                   0x0010
-#define NodeClobbersWorld                0x0020
-#define NodeMightClobber                 0x0040
+// 0x0020 and 0x0040 are free.
                                 
 #define NodeBehaviorMask                 0x0780
 #define NodeMayOverflowInBaseline        0x0080
@@ -66,11 +65,11 @@ namespace JSC { namespace DFG {
 
 #define NodeArithFlagsMask               (NodeBehaviorMask | NodeBytecodeBackPropMask)
 
-#define NodeDoesNotExit                 0x10000 // This flag is negated to make it natural for the default to be that a node does exit.
+#define NodeIsFlushed                   0x10000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
 
-#define NodeRelevantToOSR               0x20000
-
-#define NodeIsFlushed                   0x40000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
+#define NodeMiscFlag1                   0x20000
+#define NodeMiscFlag2                   0x40000
+#define NodeMiscFlag3                   0x80000
 
 typedef uint32_t NodeFlags;
 
@@ -97,7 +96,7 @@ enum RareCaseProfilingSource {
 
 static inline bool nodeMayOverflow(NodeFlags flags, RareCaseProfilingSource source)
 {
-    NodeFlags mask;
+    NodeFlags mask = 0;
     switch (source) {
     case BaselineRareCase:
         mask = NodeMayOverflowInBaseline;
@@ -114,7 +113,7 @@ static inline bool nodeMayOverflow(NodeFlags flags, RareCaseProfilingSource sour
 
 static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source)
 {
-    NodeFlags mask;
+    NodeFlags mask = 0;
     switch (source) {
     case BaselineRareCase:
         mask = NodeMayNegZeroInBaseline;
index 472f134d85af8569c1e7a105aa7f642dce14a85a..12cc064dc9aa887b402c520c1e095023f8d9b4b9 100644 (file)
@@ -49,6 +49,7 @@ struct NodeOrigin {
     
     bool isSet() const
     {
+        ASSERT(semantic.isSet() == forExit.isSet());
         return semantic.isSet();
     }
     
index 37433e365a5e6bab7b61091e25504470ee62b3ac..69f6ae5ec996bbc8c9450d3448b0684a829bf690 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,15 +35,11 @@ namespace JSC { namespace DFG {
 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
 #define FOR_EACH_DFG_OP(macro) \
     /* A constant in the CodeBlock's constant pool. */\
-    macro(JSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(JSConstant, NodeResultJS) \
     \
     /* Constants with specific representations. */\
-    macro(DoubleConstant, NodeResultDouble | NodeDoesNotExit) \
-    macro(Int52Constant, NodeResultInt52 | NodeDoesNotExit) \
-    \
-    /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
-    /* code block. */\
-    macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(DoubleConstant, NodeResultDouble) \
+    macro(Int52Constant, NodeResultInt52) \
     \
     /* Marker to indicate that an operation was optimized entirely and all that is left */\
     /* is to make one node alias another. CSE will later usually eliminate this node, */\
@@ -54,22 +50,33 @@ namespace JSC { namespace DFG {
     macro(ToThis, NodeResultJS) \
     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
     macro(GetCallee, NodeResultJS) \
+    macro(GetArgumentCount, NodeResultInt32) \
     \
     /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
     /* Any two nodes that are part of the same Phi graph will share the same */\
-    /* VariableAccessData, and thus will share predictions. */\
-    macro(GetLocal, NodeResultJS) \
+    /* VariableAccessData, and thus will share predictions. FIXME: We should come up with */\
+    /* better names for a lot of these. https://bugs.webkit.org/show_bug.cgi?id=137307. */\
+    /* Note that GetLocal is MustGenerate because it's our only way of knowing that some other */\
+    /* basic block might have read a local variable in bytecode. We only remove GetLocals if it */\
+    /* is redundant because of an earlier GetLocal or SetLocal in the same block. We could make */\
+    /* these not MustGenerate and use a more sophisticated analysis to insert PhantomLocals in */\
+    /* the same way that we insert Phantoms. That's hard and probably not profitable. See */\
+    /* https://bugs.webkit.org/show_bug.cgi?id=144086 */\
+    macro(GetLocal, NodeResultJS | NodeMustGenerate) \
     macro(SetLocal, 0) \
-    macro(MovHint, NodeDoesNotExit) \
-    macro(ZombieHint, NodeDoesNotExit) \
-    macro(GetArgument, NodeResultJS | NodeMustGenerate) \
+    \
+    macro(PutStack, NodeMustGenerate) \
+    macro(KillStack, NodeMustGenerate) \
+    macro(GetStack, NodeResultJS) \
+    \
+    macro(MovHint, NodeMustGenerate) \
+    macro(ZombieHint, NodeMustGenerate) \
     macro(Phantom, NodeMustGenerate) \
-    macro(HardPhantom, NodeMustGenerate) /* Like Phantom, but we never remove any of its children. */ \
-    macro(Check, 0) /* Used if we want just a type check but not liveness. DCE eithers kills this or converts it to Phantom. */\
-    macro(Upsilon, NodeDoesNotExit | NodeRelevantToOSR) \
-    macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \
-    macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
-    macro(PhantomLocal, NodeMustGenerate | NodeDoesNotExit) \
+    macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
+    macro(Upsilon, 0) \
+    macro(Phi, 0) \
+    macro(Flush, NodeMustGenerate) \
+    macro(PhantomLocal, NodeMustGenerate) \
     \
     /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\
     /* will exist even in inlined loops. This has no execution semantics but it must */\
@@ -84,6 +91,7 @@ namespace JSC { namespace DFG {
     /* Tier-up checks from the DFG to the FTL. */\
     macro(CheckTierUpInLoop, NodeMustGenerate) \
     macro(CheckTierUpAndOSREnter, NodeMustGenerate) \
+    macro(CheckTierUpWithNestedTriggerAndOSREnter, NodeMustGenerate) \
     macro(CheckTierUpAtReturn, NodeMustGenerate) \
     \
     /* Get the value of a local variable, without linking into the VariableAccessData */\
@@ -92,7 +100,7 @@ namespace JSC { namespace DFG {
     macro(GetLocalUnlinked, NodeResultJS) \
     \
     /* Marker for an argument being set at the prologue of a function. */\
-    macro(SetArgument, NodeDoesNotExit) \
+    macro(SetArgument, 0) \
     \
     /* Marker of location in the IR where we may possibly perform jump replacement to */\
     /* invalidate this code block. */\
@@ -123,90 +131,88 @@ namespace JSC { namespace DFG {
     /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
     macro(FiatInt52, NodeResultJS) \
     \
-    /* Nodes for arithmetic operations. */\
-    macro(ArithAdd, NodeResultNumber) \
-    macro(ArithSub, NodeResultNumber) \
-    macro(ArithNegate, NodeResultNumber) \
-    macro(ArithMul, NodeResultNumber) \
+    /* Nodes for arithmetic operations. Note that if they do checks other than just type checks, */\
+    /* then they are MustGenerate. This is probably stricter than it needs to be - for example */\
+    /* they won't do checks if they are speculated double. Also, we could kill these if we do it */\
+    /* before AI starts eliminating downstream operations based on proofs, for example in the */\
+    /* case of "var tmp = a + b; return (tmp | 0) == tmp;". If a, b are speculated integer then */\
+    /* this is only true if we do the overflow check - hence the need to keep it alive. More */\
+    /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
+    macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithClz32, NodeResultInt32) \
+    macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
     macro(ArithIMul, NodeResultInt32) \
-    macro(ArithDiv, NodeResultNumber) \
-    macro(ArithMod, NodeResultNumber) \
-    macro(ArithAbs, NodeResultNumber) \
+    macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
     macro(ArithMin, NodeResultNumber) \
     macro(ArithMax, NodeResultNumber) \
     macro(ArithFRound, NodeResultNumber) \
+    macro(ArithPow, NodeResultNumber) \
+    macro(ArithRound, NodeResultNumber) \
     macro(ArithSqrt, NodeResultNumber) \
     macro(ArithSin, NodeResultNumber) \
     macro(ArithCos, NodeResultNumber) \
+    macro(ArithLog, NodeResultNumber) \
     \
     /* Add of values may either be arithmetic, or result in string concatenation. */\
-    macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
+    macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
     \
     /* Property access. */\
     /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
     /* Since a put to 'length' may invalidate optimizations here, */\
     /* this must be the directly subsequent property put. Note that PutByVal */\
     /* opcodes use VarArgs beause they may have up to 4 children. */\
-    macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
-    macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
-    macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
-    macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
-    macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
-    macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate | NodeClobbersWorld) \
-    macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
+    macro(GetByVal, NodeResultJS | NodeMustGenerate) \
+    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
+    macro(LoadVarargs, NodeMustGenerate) \
+    macro(ForwardVarargs, NodeMustGenerate) \
+    macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
+    macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
+    macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \
+    macro(GetById, NodeResultJS | NodeMustGenerate) \
+    macro(GetByIdFlush, NodeResultJS | NodeMustGenerate) \
+    macro(PutById, NodeMustGenerate) \
+    macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate) \
+    macro(PutByIdDirect, NodeMustGenerate) \
     macro(CheckStructure, NodeMustGenerate) \
-    macro(CheckExecutable, NodeMustGenerate) \
-    /* Transition watchpoints are a contract between the party setting the watchpoint */\
-    /* and the runtime system, where the party promises that the child object once had */\
-    /* the structure being watched, and the runtime system in turn promises that the */\
-    /* watchpoint will be turned into an OSR exit if any object with that structure */\
-    /* ever transitions to a different structure. Hence, the child object must have */\
-    /* previously had a CheckStructure executed on it or we're dealing with an object */\
-    /* constant (WeakJSConstant) and the object was known to have that structure at */\
-    /* compile-time. In the latter case this means that no structure checks have to be */\
-    /* performed for this object by JITted code. In the former case this means that*/\
-    /* the object's structure does not need to be rechecked due to side-effecting */\
-    /* (clobbering) operations. */\
-    macro(StructureTransitionWatchpoint, NodeMustGenerate) \
+    macro(GetExecutable, NodeResultJS) \
     macro(PutStructure, NodeMustGenerate) \
-    macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
-    macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
-    macro(ReallocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
+    macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
+    macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
     macro(GetButterfly, NodeResultStorage) \
     macro(CheckArray, NodeMustGenerate) \
     macro(Arrayify, NodeMustGenerate) \
     macro(ArrayifyToStructure, NodeMustGenerate) \
     macro(GetIndexedPropertyStorage, NodeResultStorage) \
     macro(ConstantStoragePointer, NodeResultStorage) \
-    macro(TypedArrayWatchpoint, NodeMustGenerate) \
+    macro(GetGetter, NodeResultJS) \
+    macro(GetSetter, NodeResultJS) \
     macro(GetByOffset, NodeResultJS) \
-    macro(MultiGetByOffset, NodeResultJS) \
+    macro(GetGetterSetterByOffset, NodeResultJS) \
+    macro(MultiGetByOffset, NodeResultJS | NodeMustGenerate) \
     macro(PutByOffset, NodeMustGenerate) \
     macro(MultiPutByOffset, NodeMustGenerate) \
     macro(GetArrayLength, NodeResultInt32) \
     macro(GetTypedArrayByteOffset, NodeResultInt32) \
     macro(GetScope, NodeResultJS) \
-    macro(GetMyScope, NodeResultJS) \
-    macro(SkipTopScope, NodeResultJS) \
     macro(SkipScope, NodeResultJS) \
-    macro(GetClosureRegisters, NodeResultStorage) \
     macro(GetClosureVar, NodeResultJS) \
     macro(PutClosureVar, NodeMustGenerate) \
     macro(GetGlobalVar, NodeResultJS) \
     macro(PutGlobalVar, NodeMustGenerate) \
     macro(NotifyWrite, NodeMustGenerate) \
-    macro(VariableWatchpoint, NodeMustGenerate) \
     macro(VarInjectionWatchpoint, NodeMustGenerate) \
-    macro(FunctionReentryWatchpoint, NodeMustGenerate) \
-    macro(CheckFunction, NodeMustGenerate) \
-    macro(AllocationProfileWatchpoint, NodeMustGenerate) \
+    macro(CheckCell, NodeMustGenerate) \
+    macro(CheckNotEmpty, NodeMustGenerate) \
+    macro(CheckBadCell, NodeMustGenerate) \
     macro(CheckInBounds, NodeMustGenerate) \
     \
     /* Optimizations for array mutation. */\
-    macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
+    macro(ArrayPush, NodeResultJS | NodeMustGenerate) \
+    macro(ArrayPop, NodeResultJS | NodeMustGenerate) \
     \
     /* Optimizations for regular expression matching. */\
     macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
@@ -218,26 +224,41 @@ namespace JSC { namespace DFG {
     macro(StringFromCharCode, NodeResultJS) \
     \
     /* Nodes for comparison operations. */\
-    macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
-    macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
-    macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
-    macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
-    macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+    macro(CompareLess, NodeResultBoolean | NodeMustGenerate) \
+    macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate) \
+    macro(CompareGreater, NodeResultBoolean | NodeMustGenerate) \
+    macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \
+    macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \
     macro(CompareEqConstant, NodeResultBoolean) \
     macro(CompareStrictEq, NodeResultBoolean) \
     \
     /* Calls. */\
-    macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
-    macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
+    macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
+    macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
+    macro(CallVarargs, NodeResultJS | NodeMustGenerate) \
+    macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
+    macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
+    macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
+    macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
+    macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     \
     /* Allocations. */\
     macro(NewObject, NodeResultJS) \
     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
     macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
     macro(NewArrayBuffer, NodeResultJS) \
-    macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
+    macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
     macro(NewRegexp, NodeResultJS) \
     \
+    /* Support for allocation sinking. */\
+    macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
+    macro(PutHint, NodeMustGenerate) \
+    macro(CheckStructureImmediate, NodeMustGenerate) \
+    macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
+    macro(PhantomNewFunction, NodeResultJS | NodeMustGenerate) \
+    macro(PhantomCreateActivation, NodeResultJS | NodeMustGenerate) \
+    macro(MaterializeCreateActivation, NodeResultJS | NodeHasVarArgs) \
+    \
     /* Nodes for misc operations. */\
     macro(Breakpoint, NodeMustGenerate) \
     macro(ProfileWillCall, NodeMustGenerate) \
@@ -249,36 +270,30 @@ namespace JSC { namespace DFG {
     macro(IsNumber, NodeResultBoolean) \
     macro(IsString, NodeResultBoolean) \
     macro(IsObject, NodeResultBoolean) \
+    macro(IsObjectOrNull, NodeResultBoolean) \
     macro(IsFunction, NodeResultBoolean) \
     macro(TypeOf, NodeResultJS) \
     macro(LogicalNot, NodeResultBoolean) \
-    macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
+    macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
+    macro(ToString, NodeResultJS | NodeMustGenerate) \
+    macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
     macro(NewStringObject, NodeResultJS) \
     macro(MakeRope, NodeResultJS) \
-    macro(In, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+    macro(In, NodeResultBoolean | NodeMustGenerate) \
+    macro(ProfileType, NodeMustGenerate) \
+    macro(ProfileControlFlow, NodeMustGenerate) \
     \
-    /* Nodes used for activations. Activation support works by having it anchored at */\
-    /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
-    /* being threaded with each other. */\
     macro(CreateActivation, NodeResultJS) \
-    macro(TearOffActivation, NodeMustGenerate) \
-    \
-    /* Nodes used for arguments. Similar to activation support, only it makes even less */\
-    /* sense. */\
-    macro(CreateArguments, NodeResultJS) \
-    macro(PhantomArguments, NodeResultJS | NodeDoesNotExit) \
-    macro(TearOffArguments, NodeMustGenerate) \
-    macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
-    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
-    macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
-    macro(CheckArgumentsNotCreated, NodeMustGenerate) \
     \
-    /* Nodes for creating functions. */\
-    macro(NewFunctionNoCheck, NodeResultJS) \
+    macro(CreateDirectArguments, NodeResultJS) \
+    macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
+    macro(CreateScopedArguments, NodeResultJS) \
+    macro(CreateClonedArguments, NodeResultJS) \
+    macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
+    macro(GetFromArguments, NodeResultJS) \
+    macro(PutToArguments, NodeMustGenerate) \
+    \
     macro(NewFunction, NodeResultJS) \
-    macro(NewFunctionExpression, NodeResultJS) \
     \
     /* These aren't terminals but always exit */ \
     macro(Throw, NodeMustGenerate) \
@@ -299,12 +314,27 @@ namespace JSC { namespace DFG {
     /* different compiler. */\
     macro(ForceOSRExit, NodeMustGenerate) \
     \
+    /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
+    /* where we know that we would have exited but we'd like to still track the control */\
+    /* flow. */\
+    macro(BottomValue, NodeResultJS) \
+    \
     /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \
     /* baseline JIT to redo the watchdog timer check, and service the timer. */ \
     macro(CheckWatchdogTimer, NodeMustGenerate) \
     /* Write barriers ! */\
     macro(StoreBarrier, NodeMustGenerate) \
-    macro(StoreBarrierWithNullCheck, NodeMustGenerate) \
+    \
+    /* For-in enumeration opcodes */\
+    macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
+    macro(HasIndexedProperty, NodeResultBoolean) \
+    macro(HasStructureProperty, NodeResultBoolean) \
+    macro(HasGenericProperty, NodeResultBoolean) \
+    macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
+    macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
+    macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
+    macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
+    macro(ToIndexString, NodeResultJS)
 
 // This enum generates a monotonically increasing id for all Node types,
 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
index fbb2e1f37dad72f9309125c19b1f03672475079a..ff5fd95a7c0c8515f3d7717cf6a5e64d46f1d27b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
 #include "DFGPhase.h"
+#include "DFGPromoteHeapAccess.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace DFG {
@@ -51,27 +52,22 @@ public:
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
-            block->ssa->availabilityAtHead.fill(Availability());
-            block->ssa->availabilityAtTail.fill(Availability());
+            block->ssa->availabilityAtHead.clear();
+            block->ssa->availabilityAtTail.clear();
         }
         
         BasicBlock* root = m_graph.block(0);
-        for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
-            root->ssa->availabilityAtHead.argument(argument) =
-                Availability::unavailable().withFlush(
-                    FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
+        root->ssa->availabilityAtHead.m_locals.fill(Availability::unavailable());
+        for (unsigned argument = m_graph.m_argumentFormats.size(); argument--;) {
+            FlushedAt flushedAt = FlushedAt(
+                m_graph.m_argumentFormats[argument],
+                virtualRegisterForArgument(argument));
+            root->ssa->availabilityAtHead.m_locals.argument(argument) = Availability(flushedAt);
         }
 
-        if (m_graph.m_plan.mode == FTLForOSREntryMode) {
-            for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;)
-                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
-        } else {
-            for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
-                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
-        }
-        
         // This could be made more efficient by processing blocks in reverse postorder.
-        Operands<Availability> availability;
+        
+        LocalOSRAvailabilityCalculator calculator;
         bool changed;
         do {
             changed = false;
@@ -81,55 +77,22 @@ public:
                 if (!block)
                     continue;
                 
-                availability = block->ssa->availabilityAtHead;
+                calculator.beginBlock(block);
                 
-                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
-                    Node* node = block->at(nodeIndex);
-                    
-                    switch (node->op()) {
-                    case SetLocal: {
-                        VariableAccessData* variable = node->variableAccessData();
-                        availability.operand(variable->local()) =
-                            Availability(node->child1().node(), variable->flushedAt());
-                        break;
-                    }
-                        
-                    case GetArgument: {
-                        VariableAccessData* variable = node->variableAccessData();
-                        availability.operand(variable->local()) =
-                            Availability(node, variable->flushedAt());
-                        break;
-                    }
-                        
-                    case MovHint: {
-                        availability.operand(node->unlinkedLocal()) =
-                            Availability(node->child1().node());
-                        break;
-                    }
-                        
-                    case ZombieHint: {
-                        availability.operand(node->unlinkedLocal()) =
-                            Availability::unavailable();
-                        break;
-                    }
-                        
-                    default:
-                        break;
-                    }
-                }
+                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
+                    calculator.executeNode(block->at(nodeIndex));
                 
-                if (availability == block->ssa->availabilityAtTail)
+                if (calculator.m_availability == block->ssa->availabilityAtTail)
                     continue;
                 
-                block->ssa->availabilityAtTail = availability;
+                block->ssa->availabilityAtTail = calculator.m_availability;
                 changed = true;
                 
                 for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
                     BasicBlock* successor = block->successor(successorIndex);
-                    for (unsigned i = availability.size(); i--;) {
-                        successor->ssa->availabilityAtHead[i] = availability[i].merge(
-                            successor->ssa->availabilityAtHead[i]);
-                    }
+                    successor->ssa->availabilityAtHead.merge(calculator.m_availability);
+                    successor->ssa->availabilityAtHead.pruneByLiveness(
+                        m_graph, successor->firstOrigin().forExit);
                 }
             }
         } while (changed);
@@ -144,6 +107,110 @@ bool performOSRAvailabilityAnalysis(Graph& graph)
     return runPhase<OSRAvailabilityAnalysisPhase>(graph);
 }
 
+LocalOSRAvailabilityCalculator::LocalOSRAvailabilityCalculator()
+{
+}
+
+LocalOSRAvailabilityCalculator::~LocalOSRAvailabilityCalculator()
+{
+}
+
+void LocalOSRAvailabilityCalculator::beginBlock(BasicBlock* block)
+{
+    m_availability = block->ssa->availabilityAtHead;
+}
+
+void LocalOSRAvailabilityCalculator::endBlock(BasicBlock* block)
+{
+    m_availability = block->ssa->availabilityAtTail;
+}
+
+void LocalOSRAvailabilityCalculator::executeNode(Node* node)
+{
+    switch (node->op()) {
+    case PutStack: {
+        StackAccessData* data = node->stackAccessData();
+        m_availability.m_locals.operand(data->local).setFlush(data->flushedAt());
+        break;
+    }
+        
+    case KillStack: {
+        m_availability.m_locals.operand(node->unlinkedLocal()).setFlush(FlushedAt(ConflictingFlush));
+        break;
+    }
+
+    case GetStack: {
+        StackAccessData* data = node->stackAccessData();
+        m_availability.m_locals.operand(data->local) = Availability(node, data->flushedAt());
+        break;
+    }
+
+    case MovHint: {
+        m_availability.m_locals.operand(node->unlinkedLocal()).setNode(node->child1().node());
+        break;
+    }
+
+    case ZombieHint: {
+        m_availability.m_locals.operand(node->unlinkedLocal()).setNodeUnavailable();
+        break;
+    }
+        
+    case LoadVarargs:
+    case ForwardVarargs: {
+        LoadVarargsData* data = node->loadVarargsData();
+        m_availability.m_locals.operand(data->count) =
+            Availability(FlushedAt(FlushedInt32, data->machineCount));
+        for (unsigned i = data->limit; i--;) {
+            m_availability.m_locals.operand(VirtualRegister(data->start.offset() + i)) =
+                Availability(FlushedAt(FlushedJSValue, VirtualRegister(data->machineStart.offset() + i)));
+        }
+        break;
+    }
+        
+    case PhantomDirectArguments:
+    case PhantomClonedArguments: {
+        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
+        if (!inlineCallFrame) {
+            // We don't need to record anything about how the arguments are to be recovered. It's just a
+            // given that we can read them from the stack.
+            break;
+        }
+        
+        if (inlineCallFrame->isVarargs()) {
+            // Record how to read each argument and the argument count.
+            Availability argumentCount =
+                m_availability.m_locals.operand(inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+            
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentCountPLoc, node), argumentCount);
+        }
+        
+        if (inlineCallFrame->isClosureCall) {
+            Availability callee = m_availability.m_locals.operand(
+                inlineCallFrame->stackOffset + JSStack::Callee);
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
+        }
+        
+        for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
+            Availability argument = m_availability.m_locals.operand(
+                inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));
+            
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentPLoc, node, i), argument);
+        }
+        break;
+    }
+        
+    case PutHint: {
+        m_availability.m_heap.set(
+            PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
+            Availability(node->child2().node()));
+        break;
+    }
+        
+    default:
+        break;
+    }
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index a5ec71bab7b314953b10f04080061c666bbf86f3..064bec03c47df65e0d5efb4e2832936ed1cd1dcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGBasicBlock.h"
 #include "DFGCommon.h"
 
 namespace JSC { namespace DFG {
@@ -35,10 +36,27 @@ namespace JSC { namespace DFG {
 class Graph;
 
 // Computes BasicBlock::ssa->availabiltiyAtHead/Tail. This is a forward flow type inference
-// over MovHints and SetLocals.
+// over MovHints and SetLocals. This analysis is run directly by the Plan for preparing for
+// lowering to LLVM IR, but it can also be used as a utility. Note that if you run it before
+// stack layout, all of the flush availability will omit the virtual register - but it will
+// tell you the format.
 
 bool performOSRAvailabilityAnalysis(Graph&);
 
+// Local calculator for figuring out the availability at any node in a basic block. Requires
+// having run the availability analysis.
+class LocalOSRAvailabilityCalculator {
+public:
+    LocalOSRAvailabilityCalculator();
+    ~LocalOSRAvailabilityCalculator();
+    
+    void beginBlock(BasicBlock*);
+    void endBlock(BasicBlock*); // Useful if you want to get data for the end of the block. You don't need to call this if you did beginBlock() and then executeNode() for every node.
+    void executeNode(Node*);
+    
+    AvailabilityMap m_availability;
+};
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index e5cd42da8a08fefd4e569bf3644ca459fd6a4cf2..a2142e8ad1592659e8f4ebd5d54e55323149bd7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JIT.h"
 #include "JSStackInlines.h"
 #include "JSCInlines.h"
+#include <wtf/CommaPrinter.h>
 
 namespace JSC { namespace DFG {
 
+void OSREntryData::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    out.print("bc#", m_bytecodeIndex, ", machine code offset = ", m_machineCodeOffset);
+    out.print(", stack rules = [");
+    
+    auto printOperand = [&] (VirtualRegister reg) {
+        out.print(inContext(m_expectedValues.operand(reg), context), " (");
+        VirtualRegister toReg;
+        bool overwritten = false;
+        for (OSREntryReshuffling reshuffling : m_reshufflings) {
+            if (reg == VirtualRegister(reshuffling.fromOffset)) {
+                toReg = VirtualRegister(reshuffling.toOffset);
+                break;
+            }
+            if (reg == VirtualRegister(reshuffling.toOffset))
+                overwritten = true;
+        }
+        if (!overwritten && !toReg.isValid())
+            toReg = reg;
+        if (toReg.isValid()) {
+            if (toReg.isLocal() && !m_machineStackUsed.get(toReg.toLocal()))
+                out.print("ignored");
+            else
+                out.print("maps to ", toReg);
+        } else
+            out.print("overwritten");
+        if (reg.isLocal() && m_localsForcedDouble.get(reg.toLocal()))
+            out.print(", forced double");
+        if (reg.isLocal() && m_localsForcedMachineInt.get(reg.toLocal()))
+            out.print(", forced machine int");
+        out.print(")");
+    };
+    
+    CommaPrinter comma;
+    for (size_t argumentIndex = m_expectedValues.numberOfArguments(); argumentIndex--;) {
+        out.print(comma, "arg", argumentIndex, ":");
+        printOperand(virtualRegisterForArgument(argumentIndex));
+    }
+    for (size_t localIndex = 0; localIndex < m_expectedValues.numberOfLocals(); ++localIndex) {
+        out.print(comma, "loc", localIndex, ":");
+        printOperand(virtualRegisterForLocal(localIndex));
+    }
+    
+    out.print("], machine stack used = ", m_machineStackUsed);
+}
+
+void OSREntryData::dump(PrintStream& out) const
+{
+    dumpInContext(out, nullptr);
+}
+
 void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIndex)
 {
     ASSERT(JITCode::isOptimizingJIT(codeBlock->jitType()));
@@ -58,6 +110,9 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
 
     sanitizeStackForVM(vm);
     
+    if (bytecodeIndex)
+        codeBlock->ownerExecutable()->setDidTryToEnterInLoop(true);
+    
     if (codeBlock->jitType() != JITCode::DFGJIT) {
         RELEASE_ASSERT(codeBlock->jitType() == JITCode::FTLJIT);
         
index 4f860a2da45eb01a718b72012942264a241135bf..04aaabfee12f81d2840081d194e8132e1c757cd3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,6 +60,9 @@ struct OSREntryData {
     BitVector m_localsForcedMachineInt;
     Vector<OSREntryReshuffling> m_reshufflings;
     BitVector m_machineStackUsed;
+    
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
 };
 
 inline unsigned getOSREntryDataBytecodeIndex(OSREntryData* osrEntryData)
index a0235342014bc5ed229c60a7d34b54277a7b5a5c..d336d04433907352a1bf1e168604f0322c4868f2 100644 (file)
@@ -32,7 +32,6 @@
 #include "DFGCommon.h"
 #include "DFGExitProfile.h"
 #include "DFGOSRExitBase.h"
-#include "DFGValueRecoveryOverride.h"
 #include "GPRInfo.h"
 #include "MacroAssembler.h"
 #include "MethodOfGettingAValueProfile.h"
@@ -102,11 +101,9 @@ struct OSRExit : public OSRExitBase {
 
     unsigned m_streamIndex;
     
-    RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
-    
-    bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
+    void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
     {
-        return OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromDFG);
+        OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromDFG);
     }
 };
 
index e2f206644e5b1eebef2a2a9e0470eb38cff5fbb9..afc50e83bf01b1758fda2fb04ca671d2c49a4f6a 100644 (file)
 
 namespace JSC { namespace DFG {
 
-bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
+void OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
 {
     CodeBlock* sourceProfiledCodeBlock =
         baselineCodeBlockForOriginAndBaselineCodeBlock(
             m_codeOriginForExitProfile, profiledCodeBlock);
-    if (!sourceProfiledCodeBlock)
-        return false;
-    return sourceProfiledCodeBlock->addFrequentExitSite(
-        FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind, jitType));
+    if (sourceProfiledCodeBlock)
+        sourceProfiledCodeBlock->addFrequentExitSite(FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind, jitType));
 }
 
 } } // namespace JSC::DFG
index 03df1dbb81ba0578e8cd54a11df192d527948f94..099b2d522ed7fcf30c865e92502ead19ee2971de 100644 (file)
@@ -57,15 +57,14 @@ struct OSRExitBase {
     CodeOrigin m_codeOriginForExitProfile;
 
 protected:
-    bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
+    void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
     {
-        if (!m_count)
-            return false;
-        return considerAddingAsFrequentExitSiteSlow(profiledCodeBlock, jitType);
+        if (m_count)
+            considerAddingAsFrequentExitSiteSlow(profiledCodeBlock, jitType);
     }
 
 private:
-    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType);
+    void considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock, ExitingJITType);
 };
 
 } } // namespace JSC::DFG
index 6f7ef0dfaf193f0063aa7e6b91ac8061aac8afc0..23d51c68ef9fce1c8a1521001b929ea74f33422e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace DFG {
 
+void OSRExitCompiler::emitRestoreArguments(const Operands<ValueRecovery>& operands)
+{
+    HashMap<MinifiedID, int> alreadyAllocatedArguments; // Maps phantom arguments node ID to operand.
+    for (size_t index = 0; index < operands.size(); ++index) {
+        const ValueRecovery& recovery = operands[index];
+        int operand = operands.operandForIndex(index);
+        
+        if (recovery.technique() != DirectArgumentsThatWereNotCreated
+            && recovery.technique() != ClonedArgumentsThatWereNotCreated)
+            continue;
+        
+        MinifiedID id = recovery.nodeID();
+        auto iter = alreadyAllocatedArguments.find(id);
+        if (iter != alreadyAllocatedArguments.end()) {
+            JSValueRegs regs = JSValueRegs::withTwoAvailableRegs(GPRInfo::regT0, GPRInfo::regT1);
+            m_jit.loadValue(CCallHelpers::addressFor(iter->value), regs);
+            m_jit.storeValue(regs, CCallHelpers::addressFor(operand));
+            continue;
+        }
+        
+        InlineCallFrame* inlineCallFrame =
+            m_jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();
+
+        int stackOffset;
+        if (inlineCallFrame)
+            stackOffset = inlineCallFrame->stackOffset;
+        else
+            stackOffset = 0;
+        
+        if (!inlineCallFrame || inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                AssemblyHelpers::addressFor(stackOffset + JSStack::Callee),
+                GPRInfo::regT0);
+        } else {
+            m_jit.move(
+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeRecovery.constant().asCell()),
+                GPRInfo::regT0);
+        }
+        
+        if (!inlineCallFrame || inlineCallFrame->isVarargs()) {
+            m_jit.load32(
+                AssemblyHelpers::payloadFor(stackOffset + JSStack::ArgumentCount),
+                GPRInfo::regT1);
+        } else {
+            m_jit.move(
+                AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()),
+                GPRInfo::regT1);
+        }
+        
+        m_jit.setupArgumentsWithExecState(
+            AssemblyHelpers::TrustedImmPtr(inlineCallFrame), GPRInfo::regT0, GPRInfo::regT1);
+        switch (recovery.technique()) {
+        case DirectArgumentsThatWereNotCreated:
+            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+            break;
+        case ClonedArgumentsThatWereNotCreated:
+            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+        m_jit.call(GPRInfo::nonArgGPR0);
+        m_jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));
+        
+        alreadyAllocatedArguments.add(id, operand);
+    }
+}
+
 extern "C" {
 
 void compileOSRExit(ExecState* exec)
@@ -66,12 +135,6 @@ void compileOSRExit(ExecState* exec)
     Operands<ValueRecovery> operands;
     codeBlock->jitCode()->dfg()->variableEventStream.reconstruct(codeBlock, exit.m_codeOrigin, codeBlock->jitCode()->dfg()->minifiedDFG, exit.m_streamIndex, operands);
     
-    // There may be an override, for forward speculations.
-    if (!!exit.m_valueRecoveryOverride) {
-        operands.setOperand(
-            exit.m_valueRecoveryOverride->operand, exit.m_valueRecoveryOverride->recovery);
-    }
-    
     SpeculationRecovery* recovery = 0;
     if (exit.m_recoveryIndex != UINT_MAX)
         recovery = &codeBlock->jitCode()->dfg()->speculationRecovery[exit.m_recoveryIndex];
@@ -88,7 +151,7 @@ void compileOSRExit(ExecState* exec)
             
             Profiler::OSRExit* profilerExit = compilation->addOSRExit(
                 exitIndex, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
-                exit.m_kind, isWatchpoint(exit.m_kind));
+                exit.m_kind, exit.m_kind == UncountableInvalidation);
             jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
         }
         
index 556fe0bf26c41e22dbbc463017741a2538d85ada..cb262d427111ec4427f67f13b367275d96e0d356 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -49,28 +49,9 @@ public:
     void compileExit(const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*);
 
 private:
-#if !ASSERT_DISABLED
-    static unsigned badIndex() { return static_cast<unsigned>(-1); };
-#endif
-    
-    void initializePoisoned(unsigned size)
-    {
-#if ASSERT_DISABLED
-        m_poisonScratchIndices.resize(size);
-#else
-        m_poisonScratchIndices.fill(badIndex(), size);
-#endif
-    }
-    
-    unsigned poisonIndex(unsigned index)
-    {
-        unsigned result = m_poisonScratchIndices[index];
-        ASSERT(result != badIndex());
-        return result;
-    }
+    void emitRestoreArguments(const Operands<ValueRecovery>&);
     
     CCallHelpers& m_jit;
-    Vector<unsigned> m_poisonScratchIndices;
 };
 
 extern "C" {
index 346eeb5ab377413858b99f2820afd48870730c13..0851a58cf46474268550dee444f6c1071462a8c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,7 @@ namespace JSC { namespace DFG {
 
 void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
 {
-    // 1) Pro-forma stuff.
+    // Pro-forma stuff.
     if (Options::printEachOSRExit()) {
         SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
         debugInfo->codeBlock = m_jit.codeBlock();
@@ -48,14 +48,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
     }
     
-    // Need to ensure that the stack pointer accounts for the worst-case stack usage at exit.
-    m_jit.addPtr(
-        CCallHelpers::TrustedImm32(
-            -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
-        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
-    
-    // 2) Perform speculation recovery. This only comes into play when an operation
-    //    starts mutating state before verifying the speculation it has already made.
+    // Perform speculation recovery. This only comes into play when an operation
+    // starts mutating state before verifying the speculation it has already made.
     
     if (recovery) {
         switch (recovery->type()) {
@@ -71,7 +65,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         }
     }
 
-    // 3) Refine some value profile, if appropriate.
+    // Refine some value profile, if appropriate.
     
     if (!!exit.m_jsValueSource) {
         if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) {
@@ -108,13 +102,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 scratch1 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2);
                 scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2, scratch1);
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch1);
-                m_jit.pushToSave(scratch2);
-#else
                 m_jit.push(scratch1);
                 m_jit.push(scratch2);
-#endif
                 
                 GPRReg value;
                 if (exit.m_jsValueSource.isAddress()) {
@@ -130,13 +119,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 m_jit.lshift32(scratch1, scratch2);
                 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch2);
-                m_jit.popToRestore(scratch1);
-#else
                 m_jit.pop(scratch2);
                 m_jit.pop(scratch1);
-#endif
             }
         }
         
@@ -147,22 +131,14 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 // Save a register so we can use it.
                 GPRReg scratch = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base());
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch);
-#else
                 m_jit.push(scratch);
-#endif
 
                 m_jit.load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), scratch);
                 m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
                 m_jit.load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), scratch);
                 m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch);
-#else
                 m_jit.pop(scratch);
-#endif
             } else if (exit.m_jsValueSource.hasKnownTag()) {
                 m_jit.store32(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
                 m_jit.store32(exit.m_jsValueSource.payloadGPR(), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
@@ -176,7 +152,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     // Do a simplified OSR exit. See DFGOSRExitCompiler64.cpp's comment regarding how and wny we
     // do this simple approach.
 
-    // 4) Save all state from GPRs into the scratch buffer.
+    // Save all state from GPRs into the scratch buffer.
     
     ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
@@ -209,7 +185,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     
     // Now all GPRs are free to reuse.
     
-    // 5) Save all state from FPRs into the scratch buffer.
+    // Save all state from FPRs into the scratch buffer.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -227,9 +203,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     
     // Now all FPRs are free to reuse.
     
-    // 6) Save all state from the stack into the scratch buffer. For simplicity we
-    //    do this even for state that's already in the right place on the stack.
-    //    It makes things simpler later.
+    // Save all state from the stack into the scratch buffer. For simplicity we
+    // do this even for state that's already in the right place on the stack.
+    // It makes things simpler later.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -259,9 +235,15 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         }
     }
     
-    // 7) Do all data format conversions and store the results into the stack.
+    // Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This
+    // could toast some stack that the DFG used. We need to do it before storing to stack offsets
+    // used by baseline.
+    m_jit.addPtr(
+        CCallHelpers::TrustedImm32(
+            -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
+        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
     
-    bool haveArguments = false;
+    // Do all data format conversions and store the results into the stack.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -340,14 +322,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 AssemblyHelpers::payloadFor(operand));
             break;
             
-        case ArgumentsThatWereNotCreated:
-            haveArguments = true;
-            m_jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue().tag()),
-                AssemblyHelpers::tagFor(operand));
-            m_jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue().payload()),
-                AssemblyHelpers::payloadFor(operand));
+        case DirectArgumentsThatWereNotCreated:
+        case ClonedArgumentsThatWereNotCreated:
+            // Don't do this, yet.
             break;
             
         default:
@@ -355,64 +332,57 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         }
     }
     
-    // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
-    //    that all new calls into this code will go to the new JIT, so the execute
-    //    counter only affects call frames that performed OSR exit and call frames
-    //    that were still executing the old JIT at the time of another call frame's
-    //    OSR exit. We want to ensure that the following is true:
+    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
+    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
+    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
+    // Note that we also roughly assume that the arguments might still be materialized outside of its
+    // inline call frame scope - but for now the DFG wouldn't do that.
+    
+    emitRestoreArguments(operands);
+
+    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
+    // that all new calls into this code will go to the new JIT, so the execute
+    // counter only affects call frames that performed OSR exit and call frames
+    // that were still executing the old JIT at the time of another call frame's
+    // OSR exit. We want to ensure that the following is true:
     //
-    //    (a) Code the performs an OSR exit gets a chance to reenter optimized
-    //        code eventually, since optimized code is faster. But we don't
-    //        want to do such reentery too aggressively (see (c) below).
+    // (a) Code the performs an OSR exit gets a chance to reenter optimized
+    //     code eventually, since optimized code is faster. But we don't
+    //     want to do such reentery too aggressively (see (c) below).
     //
-    //    (b) If there is code on the call stack that is still running the old
-    //        JIT's code and has never OSR'd, then it should get a chance to
-    //        perform OSR entry despite the fact that we've exited.
+    // (b) If there is code on the call stack that is still running the old
+    //     JIT's code and has never OSR'd, then it should get a chance to
+    //     perform OSR entry despite the fact that we've exited.
     //
-    //    (c) Code the performs an OSR exit should not immediately retry OSR
-    //        entry, since both forms of OSR are expensive. OSR entry is
-    //        particularly expensive.
+    // (c) Code the performs an OSR exit should not immediately retry OSR
+    //     entry, since both forms of OSR are expensive. OSR entry is
+    //     particularly expensive.
     //
-    //    (d) Frequent OSR failures, even those that do not result in the code
-    //        running in a hot loop, result in recompilation getting triggered.
+    // (d) Frequent OSR failures, even those that do not result in the code
+    //     running in a hot loop, result in recompilation getting triggered.
     //
-    //    To ensure (c), we'd like to set the execute counter to
-    //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
-    //    (a) and (b), since then every OSR exit would delay the opportunity for
-    //    every call frame to perform OSR entry. Essentially, if OSR exit happens
-    //    frequently and the function has few loops, then the counter will never
-    //    become non-negative and OSR entry will never be triggered. OSR entry
-    //    will only happen if a loop gets hot in the old JIT, which does a pretty
-    //    good job of ensuring (a) and (b). But that doesn't take care of (d),
-    //    since each speculation failure would reset the execute counter.
-    //    So we check here if the number of speculation failures is significantly
-    //    larger than the number of successes (we want 90% success rate), and if
-    //    there have been a large enough number of failures. If so, we set the
-    //    counter to 0; otherwise we set the counter to
-    //    counterValueForOptimizeAfterWarmUp().
+    // To ensure (c), we'd like to set the execute counter to
+    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
+    // (a) and (b), since then every OSR exit would delay the opportunity for
+    // every call frame to perform OSR entry. Essentially, if OSR exit happens
+    // frequently and the function has few loops, then the counter will never
+    // become non-negative and OSR entry will never be triggered. OSR entry
+    // will only happen if a loop gets hot in the old JIT, which does a pretty
+    // good job of ensuring (a) and (b). But that doesn't take care of (d),
+    // since each speculation failure would reset the execute counter.
+    // So we check here if the number of speculation failures is significantly
+    // larger than the number of successes (we want 90% success rate), and if
+    // there have been a large enough number of failures. If so, we set the
+    // counter to 0; otherwise we set the counter to
+    // counterValueForOptimizeAfterWarmUp().
     
     handleExitCounts(m_jit, exit);
     
-    // 9) Reify inlined call frames.
+    // Reify inlined call frames.
     
     reifyInlinedCallFrames(m_jit, exit);
     
-    // 10) Create arguments if necessary and place them into the appropriate aliased
-    //     registers.
-    
-    if (haveArguments) {
-        ArgumentsRecoveryGenerator argumentsRecovery;
-
-        for (size_t index = 0; index < operands.size(); ++index) {
-            const ValueRecovery& recovery = operands[index];
-            if (recovery.technique() != ArgumentsThatWereNotCreated)
-                continue;
-            argumentsRecovery.generateFor(
-                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
-        }
-    }
-
-    // 12) And finish.
+    // And finish.
     adjustAndJumpToTarget(m_jit, exit);
 }
 
index 3e2c4a62a4b4c12e130b59b166bd37e87cfc244a..5bb0a4f50497fde8a4a62198b02572487fec87d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
 {
     m_jit.jitAssertTagsInPlace();
 
-    // 1) Pro-forma stuff.
+    // Pro-forma stuff.
     if (Options::printEachOSRExit()) {
         SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
         debugInfo->codeBlock = m_jit.codeBlock();
@@ -52,14 +52,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
     }
     
-    // Need to ensure that the stack pointer accounts for the worst-case stack usage at exit.
-    m_jit.addPtr(
-        CCallHelpers::TrustedImm32(
-            -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
-        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
-    
-    // 2) Perform speculation recovery. This only comes into play when an operation
-    //    starts mutating state before verifying the speculation it has already made.
+    // Perform speculation recovery. This only comes into play when an operation
+    // starts mutating state before verifying the speculation it has already made.
     
     if (recovery) {
         switch (recovery->type()) {
@@ -77,7 +71,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         }
     }
 
-    // 3) Refine some array and/or value profile, if appropriate.
+    // Refine some array and/or value profile, if appropriate.
     
     if (!!exit.m_jsValueSource) {
         if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) {
@@ -103,13 +97,13 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 scratch1 = AssemblyHelpers::selectScratchGPR(usedRegister);
                 scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister, scratch1);
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch1);
-                m_jit.pushToSave(scratch2);
-#else
-                m_jit.push(scratch1);
-                m_jit.push(scratch2);
-#endif
+                if (isARM64()) {
+                    m_jit.pushToSave(scratch1);
+                    m_jit.pushToSave(scratch2);
+                } else {
+                    m_jit.push(scratch1);
+                    m_jit.push(scratch2);
+                }
                 
                 GPRReg value;
                 if (exit.m_jsValueSource.isAddress()) {
@@ -125,13 +119,13 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 m_jit.lshift32(scratch1, scratch2);
                 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch2);
-                m_jit.popToRestore(scratch1);
-#else
-                m_jit.pop(scratch2);
-                m_jit.pop(scratch1);
-#endif
+                if (isARM64()) {
+                    m_jit.popToRestore(scratch2);
+                    m_jit.popToRestore(scratch1);
+                } else {
+                    m_jit.pop(scratch2);
+                    m_jit.pop(scratch1);
+                }
             }
         }
         
@@ -185,7 +179,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     // variable" from "how was it represented", which will make it more difficult to add
     // features in the future and it will make it harder to reason about bugs.
 
-    // 4) Save all state from GPRs into the scratch buffer.
+    // Save all state from GPRs into the scratch buffer.
     
     ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
@@ -209,7 +203,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     
     // And voila, all GPRs are free to reuse.
     
-    // 5) Save all state from FPRs into the scratch buffer.
+    // Save all state from FPRs into the scratch buffer.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -227,9 +221,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     
     // Now, all FPRs are also free.
     
-    // 6) Save all state from the stack into the scratch buffer. For simplicity we
-    //    do this even for state that's already in the right place on the stack.
-    //    It makes things simpler later.
+    // Save all state from the stack into the scratch buffer. For simplicity we
+    // do this even for state that's already in the right place on the stack.
+    // It makes things simpler later.
 
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -251,9 +245,15 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         }
     }
     
-    // 7) Do all data format conversions and store the results into the stack.
+    // Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This
+    // could toast some stack that the DFG used. We need to do it before storing to stack offsets
+    // used by baseline.
+    m_jit.addPtr(
+        CCallHelpers::TrustedImm32(
+            -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
+        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
     
-    bool haveArguments = false;
+    // Do all data format conversions and store the results into the stack.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -308,78 +308,68 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 AssemblyHelpers::addressFor(operand));
             break;
             
-        case ArgumentsThatWereNotCreated:
-            haveArguments = true;
-            // We can't restore this yet but we can make sure that the stack appears
-            // sane.
-            m_jit.store64(
-                AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue())),
-                AssemblyHelpers::addressFor(operand));
+        case DirectArgumentsThatWereNotCreated:
+        case ClonedArgumentsThatWereNotCreated:
+            // Don't do this, yet.
             break;
             
         default:
+            RELEASE_ASSERT_NOT_REACHED();
             break;
         }
     }
     
-    // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
-    //    that all new calls into this code will go to the new JIT, so the execute
-    //    counter only affects call frames that performed OSR exit and call frames
-    //    that were still executing the old JIT at the time of another call frame's
-    //    OSR exit. We want to ensure that the following is true:
+    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
+    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
+    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
+    // Note that we also roughly assume that the arguments might still be materialized outside of its
+    // inline call frame scope - but for now the DFG wouldn't do that.
+    
+    emitRestoreArguments(operands);
+    
+    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
+    // that all new calls into this code will go to the new JIT, so the execute
+    // counter only affects call frames that performed OSR exit and call frames
+    // that were still executing the old JIT at the time of another call frame's
+    // OSR exit. We want to ensure that the following is true:
     //
-    //    (a) Code the performs an OSR exit gets a chance to reenter optimized
-    //        code eventually, since optimized code is faster. But we don't
-    //        want to do such reentery too aggressively (see (c) below).
+    // (a) Code the performs an OSR exit gets a chance to reenter optimized
+    //     code eventually, since optimized code is faster. But we don't
+    //     want to do such reentery too aggressively (see (c) below).
     //
-    //    (b) If there is code on the call stack that is still running the old
-    //        JIT's code and has never OSR'd, then it should get a chance to
-    //        perform OSR entry despite the fact that we've exited.
+    // (b) If there is code on the call stack that is still running the old
+    //     JIT's code and has never OSR'd, then it should get a chance to
+    //     perform OSR entry despite the fact that we've exited.
     //
-    //    (c) Code the performs an OSR exit should not immediately retry OSR
-    //        entry, since both forms of OSR are expensive. OSR entry is
-    //        particularly expensive.
+    // (c) Code the performs an OSR exit should not immediately retry OSR
+    //     entry, since both forms of OSR are expensive. OSR entry is
+    //     particularly expensive.
     //
-    //    (d) Frequent OSR failures, even those that do not result in the code
-    //        running in a hot loop, result in recompilation getting triggered.
+    // (d) Frequent OSR failures, even those that do not result in the code
+    //     running in a hot loop, result in recompilation getting triggered.
     //
-    //    To ensure (c), we'd like to set the execute counter to
-    //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
-    //    (a) and (b), since then every OSR exit would delay the opportunity for
-    //    every call frame to perform OSR entry. Essentially, if OSR exit happens
-    //    frequently and the function has few loops, then the counter will never
-    //    become non-negative and OSR entry will never be triggered. OSR entry
-    //    will only happen if a loop gets hot in the old JIT, which does a pretty
-    //    good job of ensuring (a) and (b). But that doesn't take care of (d),
-    //    since each speculation failure would reset the execute counter.
-    //    So we check here if the number of speculation failures is significantly
-    //    larger than the number of successes (we want 90% success rate), and if
-    //    there have been a large enough number of failures. If so, we set the
-    //    counter to 0; otherwise we set the counter to
-    //    counterValueForOptimizeAfterWarmUp().
+    // To ensure (c), we'd like to set the execute counter to
+    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
+    // (a) and (b), since then every OSR exit would delay the opportunity for
+    // every call frame to perform OSR entry. Essentially, if OSR exit happens
+    // frequently and the function has few loops, then the counter will never
+    // become non-negative and OSR entry will never be triggered. OSR entry
+    // will only happen if a loop gets hot in the old JIT, which does a pretty
+    // good job of ensuring (a) and (b). But that doesn't take care of (d),
+    // since each speculation failure would reset the execute counter.
+    // So we check here if the number of speculation failures is significantly
+    // larger than the number of successes (we want 90% success rate), and if
+    // there have been a large enough number of failures. If so, we set the
+    // counter to 0; otherwise we set the counter to
+    // counterValueForOptimizeAfterWarmUp().
     
     handleExitCounts(m_jit, exit);
     
-    // 9) Reify inlined call frames.
+    // Reify inlined call frames.
     
     reifyInlinedCallFrames(m_jit, exit);
     
-    // 10) Create arguments if necessary and place them into the appropriate aliased
-    //     registers.
-    
-    if (haveArguments) {
-        ArgumentsRecoveryGenerator argumentsRecovery;
-
-        for (size_t index = 0; index < operands.size(); ++index) {
-            const ValueRecovery& recovery = operands[index];
-            if (recovery.technique() != ArgumentsThatWereNotCreated)
-                continue;
-            argumentsRecovery.generateFor(
-                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
-        }
-    }
-
-    // 12) And finish.
+    // And finish.
     adjustAndJumpToTarget(m_jit, exit);
 }
 
index 5b78cb20190294f2afe268f183b94dc9f723307c..39b5bb5fc4c82dd3402315e471ba9d5d21fd7d3e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
 #include "DFGJITCode.h"
 #include "DFGOperations.h"
 #include "JIT.h"
@@ -54,20 +53,55 @@ void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
         AssemblyHelpers::GreaterThanOrEqual,
         AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()),
         AssemblyHelpers::TrustedImm32(0));
+    
+    // We want to figure out if there's a possibility that we're in a loop. For the outermost
+    // code block in the inline stack, we handle this appropriately by having the loop OSR trigger
+    // check the exit count of the replacement of the CodeBlock from which we are OSRing. The
+    // problem is the inlined functions, which might also have loops, but whose baseline versions
+    // don't know where to look for the exit count. Figure out if those loops are severe enough
+    // that we had tried to OSR enter. If so, then we should use the loop reoptimization trigger.
+    // Otherwise, we should use the normal reoptimization trigger.
+    
+    AssemblyHelpers::JumpList loopThreshold;
+    
+    for (InlineCallFrame* inlineCallFrame = exit.m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
+        loopThreshold.append(
+            jit.branchTest8(
+                AssemblyHelpers::NonZero,
+                AssemblyHelpers::AbsoluteAddress(
+                    inlineCallFrame->executable->addressOfDidTryToEnterInLoop())));
+    }
+    
+    jit.move(
+        AssemblyHelpers::TrustedImm32(jit.codeBlock()->exitCountThresholdForReoptimization()),
+        GPRInfo::regT1);
+    
+    if (!loopThreshold.empty()) {
+        AssemblyHelpers::Jump done = jit.jump();
+
+        loopThreshold.link(&jit);
+        jit.move(
+            AssemblyHelpers::TrustedImm32(
+                jit.codeBlock()->exitCountThresholdForReoptimizationFromLoop()),
+            GPRInfo::regT1);
         
-    tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(jit.codeBlock()->exitCountThresholdForReoptimization()));
+        done.link(&jit);
+    }
+    
+    tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
     
     reoptimizeNow.link(&jit);
     
     // Reoptimize as soon as possible.
 #if !NUMBER_OF_ARGUMENT_REGISTERS
     jit.poke(GPRInfo::regT0);
+    jit.poke(AssemblyHelpers::TrustedImmPtr(&exit), 1);
 #else
     jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
-    ASSERT(GPRInfo::argumentGPR0 != GPRInfo::regT1);
+    jit.move(AssemblyHelpers::TrustedImmPtr(&exit), GPRInfo::argumentGPR1);
 #endif
-    jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::regT1);
-    jit.call(GPRInfo::regT1);
+    jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::nonArgGPR0);
+    jit.call(GPRInfo::nonArgGPR0);
     AssemblyHelpers::Jump doneAdjusting = jit.jump();
     
     tooFewFails.link(&jit);
@@ -88,7 +122,9 @@ void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
         break;
     default:
         RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         clippedValue = 0; // Make some compilers, and mhahnenberg, happy.
+#endif
         break;
     }
     jit.store32(AssemblyHelpers::TrustedImm32(-clippedValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
@@ -108,12 +144,46 @@ void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
         InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame;
         CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(codeOrigin);
         CodeBlock* baselineCodeBlockForCaller = jit.baselineCodeBlockFor(inlineCallFrame->caller);
+        void* jumpTarget = nullptr;
+        void* trueReturnPC = nullptr;
+        
         unsigned callBytecodeIndex = inlineCallFrame->caller.bytecodeIndex;
-        CallLinkInfo* callLinkInfo =
-            baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
-        RELEASE_ASSERT(callLinkInfo);
         
-        void* jumpTarget = callLinkInfo->callReturnLocation.executableAddress();
+        switch (inlineCallFrame->kind) {
+        case InlineCallFrame::Call:
+        case InlineCallFrame::Construct:
+        case InlineCallFrame::CallVarargs:
+        case InlineCallFrame::ConstructVarargs: {
+            CallLinkInfo* callLinkInfo =
+                baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
+            RELEASE_ASSERT(callLinkInfo);
+            
+            jumpTarget = callLinkInfo->callReturnLocation().executableAddress();
+            break;
+        }
+            
+        case InlineCallFrame::GetterCall:
+        case InlineCallFrame::SetterCall: {
+            StructureStubInfo* stubInfo =
+                baselineCodeBlockForCaller->findStubInfo(CodeOrigin(callBytecodeIndex));
+            RELEASE_ASSERT(stubInfo);
+            
+            switch (inlineCallFrame->kind) {
+            case InlineCallFrame::GetterCall:
+                jumpTarget = jit.vm()->getCTIStub(baselineGetterReturnThunkGenerator).code().executableAddress();
+                break;
+            case InlineCallFrame::SetterCall:
+                jumpTarget = jit.vm()->getCTIStub(baselineSetterReturnThunkGenerator).code().executableAddress();
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            
+            trueReturnPC = stubInfo->callReturnLocation.labelAtOffset(
+                stubInfo->patch.deltaCallToDone).executableAddress();
+            break;
+        } }
 
         GPRReg callerFrameGPR;
         if (inlineCallFrame->caller.inlineCallFrame) {
@@ -122,47 +192,28 @@ void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
         } else
             callerFrameGPR = GPRInfo::callFrameRegister;
         
-#if USE(JSVALUE64)
+        jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
+        if (trueReturnPC)
+            jit.storePtr(AssemblyHelpers::TrustedImmPtr(trueReturnPC), AssemblyHelpers::addressFor(inlineCallFrame->stackOffset + virtualRegisterForArgument(inlineCallFrame->arguments.size()).offset()));
+                         
         jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
-        if (!inlineCallFrame->isClosureCall)
-            jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()->scope()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
+        if (!inlineCallFrame->isVarargs())
+            jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
+#if USE(JSVALUE64)
         jit.store64(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
-        jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
         uint32_t locationBits = CallFrame::Location::encodeAsBytecodeOffset(codeOrigin.bytecodeIndex);
         jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
-        jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
         if (!inlineCallFrame->isClosureCall)
             jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-        
-        // Leave the captured arguments in regT3.
-        if (baselineCodeBlock->usesArguments())
-            jit.loadPtr(AssemblyHelpers::addressFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
 #else // USE(JSVALUE64) // so this is the 32-bit part
-        jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
-        jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
-        if (!inlineCallFrame->isClosureCall)
-            jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
         jit.storePtr(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
-        jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
         Instruction* instruction = baselineCodeBlock->instructions().begin() + codeOrigin.bytecodeIndex;
         uint32_t locationBits = CallFrame::Location::encodeAsBytecodeInstruction(instruction);
         jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
-        jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
         jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
         if (!inlineCallFrame->isClosureCall)
             jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-
-        // Leave the captured arguments in regT3.
-        if (baselineCodeBlock->usesArguments())
-            jit.loadPtr(AssemblyHelpers::payloadFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
 #endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
-        
-        if (baselineCodeBlock->usesArguments()) {
-            AssemblyHelpers::Jump noArguments = jit.branchTestPtr(AssemblyHelpers::Zero, GPRInfo::regT3);
-            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
-            jit.storePtr(GPRInfo::regT0, AssemblyHelpers::Address(GPRInfo::regT3, Arguments::offsetOfRegisters()));
-            noArguments.link(&jit);
-        }
     }
 
 #if USE(JSVALUE64)
@@ -177,7 +228,7 @@ void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
 #if ENABLE(GGC)
 static void osrWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch)
 {
-    AssemblyHelpers::Jump ownerNotMarkedOrAlreadyRemembered = jit.checkMarkByte(owner);
+    AssemblyHelpers::Jump ownerIsRememberedOrInEden = jit.jumpIfIsRememberedOrInEden(owner);
 
     // We need these extra slots because setupArgumentsWithExecState will use poke on x86.
 #if CPU(X86)
@@ -192,14 +243,13 @@ static void osrWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch)
     jit.addPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
 #endif
 
-    ownerNotMarkedOrAlreadyRemembered.link(&jit);
+    ownerIsRememberedOrInEden.link(&jit);
 }
 #endif // ENABLE(GGC)
 
 void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
 {
 #if ENABLE(GGC) 
-    // 11) Write barrier the owner executables because we're jumping into a different block.
     jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()->ownerExecutable()), GPRInfo::nonArgGPR0);
     osrWriteBarrier(jit, GPRInfo::nonArgGPR0, GPRInfo::nonArgGPR1);
     InlineCallFrameSet* inlineCallFrames = jit.codeBlock()->jitCode()->dfgCommon()->inlineCallFrames.get();
@@ -233,89 +283,6 @@ void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
     jit.jump(GPRInfo::regT2);
 }
 
-ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
-ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
-
-void ArgumentsRecoveryGenerator::generateFor(
-    int operand, CodeOrigin codeOrigin, CCallHelpers& jit)
-{
-    // Find the right inline call frame.
-    InlineCallFrame* inlineCallFrame = 0;
-    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
-         current;
-         current = current->caller.inlineCallFrame) {
-        if (current->stackOffset >= operand) {
-            inlineCallFrame = current;
-            break;
-        }
-    }
-
-    if (!jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
-        return;
-    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
-    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
-        // We know this call frame optimized out an arguments object that
-        // the baseline JIT would have created. Do that creation now.
-#if USE(JSVALUE64)
-        if (inlineCallFrame) {
-            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
-            jit.setupArguments(GPRInfo::regT0);
-        } else
-            jit.setupArgumentsExecState();
-        jit.move(
-            AssemblyHelpers::TrustedImmPtr(
-                bitwise_cast<void*>(operationCreateArgumentsDuringOSRExit)),
-            GPRInfo::nonArgGPR0);
-        jit.call(GPRInfo::nonArgGPR0);
-        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
-        jit.store64(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-#else // USE(JSVALUE64) -> so the 32_64 part
-        if (inlineCallFrame) {
-            jit.setupArgumentsWithExecState(
-                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
-            jit.move(
-                AssemblyHelpers::TrustedImmPtr(
-                    bitwise_cast<void*>(operationCreateInlinedArgumentsDuringOSRExit)),
-                GPRInfo::nonArgGPR0);
-        } else {
-            jit.setupArgumentsExecState();
-            jit.move(
-                AssemblyHelpers::TrustedImmPtr(
-                    bitwise_cast<void*>(operationCreateArgumentsDuringOSRExit)),
-                GPRInfo::nonArgGPR0);
-        }
-        jit.call(GPRInfo::nonArgGPR0);
-        jit.store32(
-            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-            AssemblyHelpers::tagFor(argumentsRegister));
-        jit.store32(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::payloadFor(argumentsRegister));
-        jit.store32(
-            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.store32(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-#endif // USE(JSVALUE64)
-    }
-
-#if USE(JSVALUE64)
-    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
-    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
-#else // USE(JSVALUE64) -> so the 32_64 part
-    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
-    jit.store32(
-        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-        AssemblyHelpers::tagFor(operand));
-    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
-#endif // USE(JSVALUE64)
-}
-    
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
index 93ecf472edb698ed5e207e02660faa729efdb844..ce1836fa17714b6e14bb85a65460ac224e84aca4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,18 +37,6 @@ void handleExitCounts(CCallHelpers&, const OSRExitBase&);
 void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
 void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
 
-class ArgumentsRecoveryGenerator {
-public:
-    ArgumentsRecoveryGenerator();
-    ~ArgumentsRecoveryGenerator();
-    
-    void generateFor(int operand, CodeOrigin, CCallHelpers&);
-    
-private:
-    HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
-        NullableHashTraits<InlineCallFrame*>> m_didCreateArgumentsObject;
-};
-
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGOSRExitFuzz.cpp b/dfg/DFGOSRExitFuzz.cpp
new file mode 100644 (file)
index 0000000..570a6a0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGOSRExitFuzz.h"
+
+#include "TestRunnerUtils.h"
+
+namespace JSC { namespace DFG {
+
+unsigned g_numberOfStaticOSRExitFuzzChecks;
+unsigned g_numberOfOSRExitFuzzChecks;
+
+} // namespace DFG
+
+unsigned numberOfStaticOSRExitFuzzChecks()
+{
+    return DFG::g_numberOfStaticOSRExitFuzzChecks;
+}
+
+unsigned numberOfOSRExitFuzzChecks()
+{
+    return DFG::g_numberOfOSRExitFuzzChecks;
+}
+
+} // namespace JSC
+
+
diff --git a/dfg/DFGOSRExitFuzz.h b/dfg/DFGOSRExitFuzz.h
new file mode 100644 (file)
index 0000000..2feee59
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGOSRExitFuzz_h
+#define DFGOSRExitFuzz_h
+
+#include "Options.h"
+
+namespace JSC { namespace DFG {
+
+extern unsigned g_numberOfStaticOSRExitFuzzChecks;
+
+inline bool doOSRExitFuzzing()
+{
+    if (!Options::enableOSRExitFuzz())
+        return false;
+    
+    g_numberOfStaticOSRExitFuzzChecks++;
+    if (unsigned atStatic = Options::fireOSRExitFuzzAtStatic())
+        return atStatic == g_numberOfStaticOSRExitFuzzChecks;
+    
+    return true;
+}
+
+// DFG- and FTL-generated code will query this on every speculation.
+extern unsigned g_numberOfOSRExitFuzzChecks;
+
+} } // namespace JSC::DFG
+
+#endif // DFGOSRExitFuzz_h
+
index 43dd9f3574122e9e090addda575c3bf7ad7f4a68..51d6e5a0d6aee2d486ae302f9e85fe5d9a51e655 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@ void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin)
         FunctionExecutable* executable =
             static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get());
         CodeBlock* codeBlock = executable->baselineCodeBlockFor(
-            codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
+            codeOrigin.inlineCallFrame->specializationKind());
         
         if (codeBlock->jitType() == JSC::JITCode::BaselineJIT)
             continue;
diff --git a/dfg/DFGObjectAllocationSinkingPhase.cpp b/dfg/DFGObjectAllocationSinkingPhase.cpp
new file mode 100644 (file)
index 0000000..422382f
--- /dev/null
@@ -0,0 +1,1165 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGObjectAllocationSinkingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAbstractHeap.h"
+#include "DFGBlockMapInlines.h"
+#include "DFGClobberize.h"
+#include "DFGCombinedLiveness.h"
+#include "DFGGraph.h"
+#include "DFGInsertOSRHintsForUpdate.h"
+#include "DFGInsertionSet.h"
+#include "DFGLivenessAnalysisPhase.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "DFGPhase.h"
+#include "DFGPromoteHeapAccess.h"
+#include "DFGSSACalculator.h"
+#include "DFGValidate.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+static bool verbose = false;
+
+class ObjectAllocationSinkingPhase : public Phase {
+public:
+    ObjectAllocationSinkingPhase(Graph& graph)
+        : Phase(graph, "object allocation sinking")
+        , m_ssaCalculator(graph)
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
+        
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        
+        // Logically we wish to consider every NewObject and sink it. However it's probably not
+        // profitable to sink a NewObject that will always escape. So, first we do a very simple
+        // forward flow analysis that determines the set of NewObject nodes that have any chance
+        // of benefiting from object allocation sinking. Then we fixpoint the following rules:
+        //
+        // - For each NewObject, we turn the original NewObject into a PhantomNewObject and then
+        //   we insert MaterializeNewObject just before those escaping sites that come before any
+        //   other escaping sites - that is, there is no path between the allocation and those sites
+        //   that would see any other escape. Note that Upsilons constitute escaping sites. Then we
+        //   insert additional MaterializeNewObject nodes on Upsilons that feed into Phis that mix
+        //   materializations and the original PhantomNewObject. We then turn each PutByOffset over a
+        //   PhantomNewObject into a PutHint.
+        //
+        // - We perform the same optimization for MaterializeNewObject. This allows us to cover
+        //   cases where we had MaterializeNewObject flowing into a PutHint.
+        //
+        // We could also add this rule:
+        //
+        // - If all of the Upsilons of a Phi have a MaterializeNewObject that isn't used by anyone
+        //   else, then replace the Phi with the MaterializeNewObject.
+        //
+        //   FIXME: Implement this. Note that this totally doable but it requires some gnarly
+        //   code, and to be effective the pruner needs to be aware of it. Currently any Upsilon
+        //   is considered to be an escape even by the pruner, so it's unlikely that we'll see
+        //   many cases of Phi over Materializations.
+        //   https://bugs.webkit.org/show_bug.cgi?id=136927
+        
+        if (!performSinking())
+            return false;
+        
+        while (performSinking()) { }
+        
+        if (verbose) {
+            dataLog("Graph after sinking:\n");
+            m_graph.dump();
+        }
+        
+        return true;
+    }
+
+private:
+    bool performSinking()
+    {
+        m_graph.computeRefCounts();
+        performLivenessAnalysis(m_graph);
+        performOSRAvailabilityAnalysis(m_graph);
+        m_combinedLiveness = CombinedLiveness(m_graph);
+        
+        CString graphBeforeSinking;
+        if (Options::verboseValidationFailure() && Options::validateGraphAtEachPhase()) {
+            StringPrintStream out;
+            m_graph.dump(out);
+            graphBeforeSinking = out.toCString();
+        }
+        
+        if (verbose) {
+            dataLog("Graph before sinking:\n");
+            m_graph.dump();
+        }
+        
+        determineMaterializationPoints();
+        if (m_sinkCandidates.isEmpty())
+            return false;
+        
+        // At this point we are committed to sinking the sinking candidates.
+        placeMaterializationPoints();
+        lowerNonReadingOperationsOnPhantomAllocations();
+        promoteSunkenFields();
+        
+        if (Options::validateGraphAtEachPhase())
+            validate(m_graph, DumpGraph, graphBeforeSinking);
+        
+        if (verbose)
+            dataLog("Sinking iteration changed the graph.\n");
+        return true;
+    }
+    
+    void determineMaterializationPoints()
+    {
+        // The premise of this pass is that if there exists a point in the program where some
+        // path from a phantom allocation site to that point causes materialization, then *all*
+        // paths cause materialization. This should mean that there are never any redundant
+        // materializations.
+        
+        m_sinkCandidates.clear();
+        m_materializationToEscapee.clear();
+        m_materializationSiteToMaterializations.clear();
+        
+        BlockMap<HashMap<Node*, bool>> materializedAtHead(m_graph);
+        BlockMap<HashMap<Node*, bool>> materializedAtTail(m_graph);
+        
+        bool changed;
+        do {
+            if (verbose)
+                dataLog("Doing iteration of materialization point placement.\n");
+            changed = false;
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+                HashMap<Node*, bool> materialized = materializedAtHead[block];
+                if (verbose)
+                    dataLog("    Looking at block ", pointerDump(block), "\n");
+                for (Node* node : *block) {
+                    handleNode(
+                        node,
+                        [&] () {
+                            materialized.add(node, false);
+                        },
+                        [&] (Node* escapee) {
+                            auto iter = materialized.find(escapee);
+                            if (iter != materialized.end()) {
+                                if (verbose)
+                                    dataLog("    ", escapee, " escapes at ", node, "\n");
+                                iter->value = true;
+                            }
+                        });
+                }
+                
+                if (verbose)
+                    dataLog("    Materialized at tail of ", pointerDump(block), ": ", mapDump(materialized), "\n");
+                
+                if (materialized == materializedAtTail[block])
+                    continue;
+                
+                materializedAtTail[block] = materialized;
+                changed = true;
+                
+                // Only propagate things to our successors if they are alive in all successors.
+                // So, we prune materialized-at-tail to only include things that are live.
+                Vector<Node*> toRemove;
+                for (auto pair : materialized) {
+                    if (!m_combinedLiveness.liveAtTail[block].contains(pair.key))
+                        toRemove.append(pair.key);
+                }
+                for (Node* key : toRemove)
+                    materialized.remove(key);
+                
+                for (BasicBlock* successorBlock : block->successors()) {
+                    for (auto pair : materialized) {
+                        materializedAtHead[successorBlock].add(
+                            pair.key, false).iterator->value |= pair.value;
+                    }
+                }
+            }
+        } while (changed);
+        
+        // Determine the sink candidates. Broadly, a sink candidate is a node that handleNode()
+        // believes is sinkable, and one of the following is true:
+        //
+        // 1) There exists a basic block with only backward outgoing edges (or no outgoing edges)
+        //    in which the node wasn't materialized. This is meant to catch effectively-infinite
+        //    loops in which we don't need to have allocated the object.
+        //
+        // 2) There exists a basic block at the tail of which the node is not materialized and the
+        //    node is dead.
+        //
+        // 3) The sum of execution counts of the materializations is less than the sum of
+        //    execution counts of the original node.
+        //
+        // We currently implement only rule #2.
+        // FIXME: Implement the two other rules.
+        // https://bugs.webkit.org/show_bug.cgi?id=137073 (rule #1)
+        // https://bugs.webkit.org/show_bug.cgi?id=137074 (rule #3)
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (auto pair : materializedAtTail[block]) {
+                if (pair.value)
+                    continue; // It was materialized.
+                
+                if (m_combinedLiveness.liveAtTail[block].contains(pair.key))
+                    continue; // It might still get materialized in all of the successors.
+                
+                // We know that it died in this block and it wasn't materialized. That means that
+                // if we sink this allocation, then *this* will be a path along which we never
+                // have to allocate. Profit!
+                m_sinkCandidates.add(pair.key);
+            }
+        }
+        
+        if (m_sinkCandidates.isEmpty())
+            return;
+        
+        // A materialization edge exists at any point where a node escapes but hasn't been
+        // materialized yet. We do this in two parts. First we find all of the nodes that cause
+        // escaping to happen, where the escapee had not yet been materialized. This catches
+        // everything but loops. We then catch loops - as well as weirder control flow constructs -
+        // in a subsequent pass that looks at places in the CFG where an edge exists from a block
+        // that hasn't materialized to a block that has. We insert the materialization along such an
+        // edge, and we rely on the fact that critical edges were already broken so that we actually
+        // either insert the materialization at the head of the successor or the tail of the
+        // predecessor.
+        //
+        // FIXME: This can create duplicate allocations when we really only needed to perform one.
+        // For example:
+        //
+        //     var o = new Object();
+        //     if (rare) {
+        //         if (stuff)
+        //             call(o); // o escapes here.
+        //         return;
+        //     }
+        //     // o doesn't escape down here.
+        //
+        // In this example, we would place a materialization point at call(o) and then we would find
+        // ourselves having to insert another one at the implicit else case of that if statement
+        // ('cause we've broken critical edges). We would instead really like to just have one
+        // materialization point right at the top of the then case of "if (rare)". To do this, we can
+        // find the LCA of the various materializations in the dom tree.
+        // https://bugs.webkit.org/show_bug.cgi?id=137124
+        
+        // First pass: find intra-block materialization points.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            HashSet<Node*> materialized;
+            for (auto pair : materializedAtHead[block]) {
+                if (pair.value && m_sinkCandidates.contains(pair.key))
+                    materialized.add(pair.key);
+            }
+            
+            if (verbose)
+                dataLog("Placing materialization points in ", pointerDump(block), " with materialization set ", listDump(materialized), "\n");
+            
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                
+                handleNode(
+                    node,
+                    [&] () { },
+                    [&] (Node* escapee) {
+                        if (verbose)
+                            dataLog("Seeing ", escapee, " escape at ", node, "\n");
+                        
+                        if (!m_sinkCandidates.contains(escapee)) {
+                            if (verbose)
+                                dataLog("    It's not a sink candidate.\n");
+                            return;
+                        }
+                        
+                        if (!materialized.add(escapee).isNewEntry) {
+                            if (verbose)
+                                dataLog("   It's already materialized.\n");
+                            return;
+                        }
+                        
+                        createMaterialize(escapee, node);
+                    });
+            }
+        }
+        
+        // Second pass: find CFG edge materialization points.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (BasicBlock* successorBlock : block->successors()) {
+                for (auto pair : materializedAtHead[successorBlock]) {
+                    Node* allocation = pair.key;
+                    
+                    // We only care if it is materialized in the successor.
+                    if (!pair.value)
+                        continue;
+                    
+                    // We only care about sinking candidates.
+                    if (!m_sinkCandidates.contains(allocation))
+                        continue;
+                    
+                    // We only care if it isn't materialized in the predecessor.
+                    if (materializedAtTail[block].get(allocation))
+                        continue;
+                    
+                    // We need to decide if we put the materialization at the head of the successor,
+                    // or the tail of the predecessor. It needs to be placed so that the allocation
+                    // is never materialized before, and always materialized after.
+                    
+                    // Is it never materialized in any of successor's predecessors? I like to think
+                    // of "successors' predecessors" and "predecessor's successors" as the "shadow",
+                    // because of what it looks like when you draw it.
+                    bool neverMaterializedInShadow = true;
+                    for (BasicBlock* shadowBlock : successorBlock->predecessors) {
+                        if (materializedAtTail[shadowBlock].get(allocation)) {
+                            neverMaterializedInShadow = false;
+                            break;
+                        }
+                    }
+                    
+                    if (neverMaterializedInShadow) {
+                        createMaterialize(allocation, successorBlock->firstOriginNode());
+                        continue;
+                    }
+                    
+                    // Because we had broken critical edges, it must be the case that the
+                    // predecessor's successors all materialize the object. This is because the
+                    // previous case is guaranteed to catch the case where the successor only has
+                    // one predecessor. When critical edges are broken, this is also the only case
+                    // where the predecessor could have had multiple successors. Therefore we have
+                    // already handled the case where the predecessor has multiple successors.
+                    DFG_ASSERT(m_graph, block, block->numSuccessors() == 1);
+                    
+                    createMaterialize(allocation, block->terminal());
+                }
+            }
+        }
+    }
+    
+    void placeMaterializationPoints()
+    {
+        m_ssaCalculator.reset();
+        
+        // The "variables" are the object allocations that we are sinking. So, nodeToVariable maps
+        // sink candidates (aka escapees) to the SSACalculator's notion of Variable, and indexToNode
+        // maps in the opposite direction using the SSACalculator::Variable::index() as the key.
+        HashMap<Node*, SSACalculator::Variable*> nodeToVariable;
+        Vector<Node*> indexToNode;
+        
+        for (Node* node : m_sinkCandidates) {
+            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
+            nodeToVariable.add(node, variable);
+            ASSERT(indexToNode.size() == variable->index());
+            indexToNode.append(node);
+        }
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                if (SSACalculator::Variable* variable = nodeToVariable.get(node))
+                    m_ssaCalculator.newDef(variable, block, node);
+                
+                for (Node* materialize : m_materializationSiteToMaterializations.get(node)) {
+                    m_ssaCalculator.newDef(
+                        nodeToVariable.get(m_materializationToEscapee.get(materialize)),
+                        block, materialize);
+                }
+            }
+        }
+        
+        m_ssaCalculator.computePhis(
+            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
+                Node* allocation = indexToNode[variable->index()];
+                if (!m_combinedLiveness.liveAtHead[block].contains(allocation))
+                    return nullptr;
+                
+                Node* phiNode = m_graph.addNode(allocation->prediction(), Phi, NodeOrigin());
+                phiNode->mergeFlags(NodeResultJS);
+                return phiNode;
+            });
+        
+        // Place Phis in the right places. Replace all uses of any allocation with the appropriate
+        // materialization. Create the appropriate Upsilon nodes.
+        LocalOSRAvailabilityCalculator availabilityCalculator;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            HashMap<Node*, Node*> mapping;
+            
+            for (Node* candidate : m_combinedLiveness.liveAtHead[block]) {
+                SSACalculator::Variable* variable = nodeToVariable.get(candidate);
+                if (!variable)
+                    continue;
+                
+                SSACalculator::Def* def = m_ssaCalculator.reachingDefAtHead(block, variable);
+                if (!def)
+                    continue;
+                
+                mapping.set(indexToNode[variable->index()], def->value());
+            }
+            
+            availabilityCalculator.beginBlock(block);
+            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
+                m_insertionSet.insert(0, phiDef->value());
+                
+                Node* originalNode = indexToNode[phiDef->variable()->index()];
+                insertOSRHintsForUpdate(
+                    m_insertionSet, 0, NodeOrigin(), availabilityCalculator.m_availability,
+                    originalNode, phiDef->value());
+
+                mapping.set(originalNode, phiDef->value());
+            }
+            
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+
+                for (Node* materialize : m_materializationSiteToMaterializations.get(node)) {
+                    Node* escapee = m_materializationToEscapee.get(materialize);
+                    m_insertionSet.insert(nodeIndex, materialize);
+                    insertOSRHintsForUpdate(
+                        m_insertionSet, nodeIndex, node->origin,
+                        availabilityCalculator.m_availability, escapee, materialize);
+                    mapping.set(escapee, materialize);
+                }
+                    
+                availabilityCalculator.executeNode(node);
+                
+                m_graph.doToChildren(
+                    node,
+                    [&] (Edge& edge) {
+                        if (Node* materialize = mapping.get(edge.node()))
+                            edge.setNode(materialize);
+                    });
+                
+                // If you cause an escape, you shouldn't see the original escapee.
+                if (validationEnabled()) {
+                    handleNode(
+                        node,
+                        [&] () { },
+                        [&] (Node* escapee) {
+                            DFG_ASSERT(m_graph, node, !m_sinkCandidates.contains(escapee));
+                        });
+                }
+            }
+            
+            NodeAndIndex terminal = block->findTerminal();
+            size_t upsilonInsertionPoint = terminal.index;
+            Node* upsilonWhere = terminal.node;
+            NodeOrigin upsilonOrigin = upsilonWhere->origin;
+            for (BasicBlock* successorBlock : block->successors()) {
+                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef->value();
+                    SSACalculator::Variable* variable = phiDef->variable();
+                    Node* allocation = indexToNode[variable->index()];
+                    
+                    Node* incoming = mapping.get(allocation);
+                    DFG_ASSERT(m_graph, incoming, incoming != allocation);
+                    
+                    m_insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), incoming->defaultEdge());
+                }
+            }
+            
+            m_insertionSet.execute(block);
+        }
+        
+        // At this point we have dummy materialization nodes along with edges to them. This means
+        // that the part of the control flow graph that prefers to see actual object allocations
+        // is completely fixed up, except for the materializations themselves.
+    }
+    
+    void lowerNonReadingOperationsOnPhantomAllocations()
+    {
+        // Lower everything but reading operations on phantom allocations. We absolutely have to
+        // lower all writes so as to reveal them to the SSA calculator. We cannot lower reads
+        // because the whole point is that those go away completely.
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                switch (node->op()) {
+                case PutByOffset: {
+                    Node* target = node->child2().node();
+                    if (m_sinkCandidates.contains(target)) {
+                        ASSERT(target->isPhantomObjectAllocation());
+                        node->convertToPutByOffsetHint();
+                    }
+                    break;
+                }
+
+                case PutClosureVar: {
+                    Node* target = node->child1().node();
+                    if (m_sinkCandidates.contains(target)) {
+                        ASSERT(target->isPhantomActivationAllocation());
+                        node->convertToPutClosureVarHint();
+                    }
+                    break;
+                }
+                    
+                case PutStructure: {
+                    Node* target = node->child1().node();
+                    if (m_sinkCandidates.contains(target)) {
+                        ASSERT(target->isPhantomObjectAllocation());
+                        Node* structure = m_insertionSet.insertConstant(
+                            nodeIndex, node->origin, JSValue(node->transition()->next));
+                        node->convertToPutStructureHint(structure);
+                    }
+                    break;
+                }
+                    
+                case NewObject: {
+                    if (m_sinkCandidates.contains(node)) {
+                        Node* structure = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, JSValue(node->structure()));
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(StructurePLoc, node).createHint(
+                                m_graph, node->origin, structure));
+                        node->convertToPhantomNewObject();
+                    }
+                    break;
+                }
+                    
+                case MaterializeNewObject: {
+                    if (m_sinkCandidates.contains(node)) {
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(StructurePLoc, node).createHint(
+                                m_graph, node->origin, m_graph.varArgChild(node, 0).node()));
+                        for (unsigned i = 0; i < node->objectMaterializationData().m_properties.size(); ++i) {
+                            unsigned identifierNumber =
+                                node->objectMaterializationData().m_properties[i].m_identifierNumber;
+                            m_insertionSet.insert(
+                                nodeIndex + 1,
+                                PromotedHeapLocation(
+                                    NamedPropertyPLoc, node, identifierNumber).createHint(
+                                    m_graph, node->origin,
+                                    m_graph.varArgChild(node, i + 1).node()));
+                        }
+                        node->convertToPhantomNewObject();
+                    }
+                    break;
+                }
+
+                case NewFunction: {
+                    if (m_sinkCandidates.contains(node)) {
+                        Node* executable = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, node->cellOperand());
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(FunctionExecutablePLoc, node).createHint(
+                                m_graph, node->origin, executable));
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(FunctionActivationPLoc, node).createHint(
+                                m_graph, node->origin, node->child1().node()));
+                        node->convertToPhantomNewFunction();
+                    }
+                    break;
+                }
+
+                case CreateActivation: {
+                    if (m_sinkCandidates.contains(node)) {
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationScopePLoc, node).createHint(
+                                m_graph, node->origin, node->child1().node()));
+                        Node* symbolTableNode = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, node->cellOperand());
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationSymbolTablePLoc, node).createHint(
+                                m_graph, node->origin, symbolTableNode));
+
+                        {
+                            SymbolTable* symbolTable = node->castOperand<SymbolTable*>();
+                            Node* undefined = m_insertionSet.insertConstant(
+                                nodeIndex + 1, node->origin, jsUndefined());
+                            ConcurrentJITLocker locker(symbolTable->m_lock);
+                            for (auto iter = symbolTable->begin(locker), end = symbolTable->end(locker); iter != end; ++iter) {
+                                m_insertionSet.insert(
+                                    nodeIndex + 1,
+                                    PromotedHeapLocation(
+                                        ClosureVarPLoc, node, iter->value.scopeOffset().offset()).createHint(
+                                        m_graph, node->origin, undefined));
+                            }
+                        }
+
+                        node->convertToPhantomCreateActivation();
+                    }
+                    break;
+                }
+
+                case MaterializeCreateActivation: {
+                    if (m_sinkCandidates.contains(node)) {
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationScopePLoc, node).createHint(
+                                m_graph, node->origin, m_graph.varArgChild(node, 0).node()));
+                        Node* symbolTableNode = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, node->cellOperand());
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationSymbolTablePLoc, node).createHint(
+                                m_graph, node->origin, symbolTableNode));
+                        ObjectMaterializationData& data = node->objectMaterializationData();
+                        for (unsigned i = 0; i < data.m_properties.size(); ++i) {
+                            unsigned identifierNumber = data.m_properties[i].m_identifierNumber;
+                            m_insertionSet.insert(
+                                nodeIndex + 1,
+                                PromotedHeapLocation(
+                                    ClosureVarPLoc, node, identifierNumber).createHint(
+                                    m_graph, node->origin,
+                                    m_graph.varArgChild(node, i + 1).node()));
+                        }
+                        node->convertToPhantomCreateActivation();
+                    }
+                    break;
+                }
+
+                case StoreBarrier: {
+                    DFG_CRASH(m_graph, node, "Unexpected store barrier during sinking.");
+                    break;
+                }
+                    
+                default:
+                    break;
+                }
+                
+                m_graph.doToChildren(
+                    node,
+                    [&] (Edge& edge) {
+                        if (m_sinkCandidates.contains(edge.node()))
+                            edge.setUseKind(KnownCellUse);
+                    });
+            }
+            m_insertionSet.execute(block);
+        }
+    }
+    
+    void promoteSunkenFields()
+    {
+        // Collect the set of heap locations that we will be operating over.
+        HashSet<PromotedHeapLocation> locations;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                promoteHeapAccess(
+                    node,
+                    [&] (PromotedHeapLocation location, Edge) {
+                        if (m_sinkCandidates.contains(location.base()))
+                            locations.add(location);
+                    },
+                    [&] (PromotedHeapLocation location) {
+                        if (m_sinkCandidates.contains(location.base()))
+                            locations.add(location);
+                    });
+            }
+        }
+        
+        // Figure out which locations belong to which allocations.
+        m_locationsForAllocation.clear();
+        for (PromotedHeapLocation location : locations) {
+            auto result = m_locationsForAllocation.add(location.base(), Vector<PromotedHeapLocation>());
+            ASSERT(!result.iterator->value.contains(location));
+            result.iterator->value.append(location);
+        }
+        
+        // For each sunken thingy, make sure we create Bottom values for all of its fields.
+        // Note that this has the hilarious slight inefficiency of creating redundant hints for
+        // things that were previously materializations. This should only impact compile times and
+        // not code quality, and it's necessary for soundness without some data structure hackage.
+        // For example, a MaterializeNewObject that we choose to sink may have new fields added to
+        // it conditionally. That would necessitate Bottoms.
+        Node* bottom = nullptr;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            if (block == m_graph.block(0))
+                bottom = m_insertionSet.insertConstant(0, NodeOrigin(), jsUndefined());
+            
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                for (PromotedHeapLocation location : m_locationsForAllocation.get(node)) {
+                    m_insertionSet.insert(
+                        nodeIndex + 1, location.createHint(m_graph, node->origin, bottom));
+                }
+            }
+            m_insertionSet.execute(block);
+        }
+
+        m_ssaCalculator.reset();
+
+        // Collect the set of "variables" that we will be sinking.
+        m_locationToVariable.clear();
+        m_indexToLocation.clear();
+        for (PromotedHeapLocation location : locations) {
+            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
+            m_locationToVariable.add(location, variable);
+            ASSERT(m_indexToLocation.size() == variable->index());
+            m_indexToLocation.append(location);
+        }
+        
+        // Create Defs from the existing hints.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                promoteHeapAccess(
+                    node,
+                    [&] (PromotedHeapLocation location, Edge value) {
+                        if (!m_sinkCandidates.contains(location.base()))
+                            return;
+                        SSACalculator::Variable* variable = m_locationToVariable.get(location);
+                        m_ssaCalculator.newDef(variable, block, value.node());
+                    },
+                    [&] (PromotedHeapLocation) { });
+            }
+        }
+        
+        // OMG run the SSA calculator to create Phis!
+        m_ssaCalculator.computePhis(
+            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
+                PromotedHeapLocation location = m_indexToLocation[variable->index()];
+                if (!m_combinedLiveness.liveAtHead[block].contains(location.base()))
+                    return nullptr;
+                
+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
+                phiNode->mergeFlags(NodeResultJS);
+                return phiNode;
+            });
+        
+        // Place Phis in the right places, replace all uses of any load with the appropriate
+        // value, and create the appropriate Upsilon nodes.
+        m_graph.clearReplacements();
+        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
+            // This mapping table is intended to be lazy. If something is omitted from the table,
+            // it means that there haven't been any local stores to that promoted heap location.
+            m_localMapping.clear();
+            
+            // Insert the Phi functions that we had previously created.
+            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
+                PromotedHeapLocation location = m_indexToLocation[phiDef->variable()->index()];
+                
+                m_insertionSet.insert(
+                    0, phiDef->value());
+                m_insertionSet.insert(
+                    0, location.createHint(m_graph, NodeOrigin(), phiDef->value()));
+                m_localMapping.add(location, phiDef->value());
+            }
+            
+            if (verbose)
+                dataLog("Local mapping at ", pointerDump(block), ": ", mapDump(m_localMapping), "\n");
+            
+            // Process the block and replace all uses of loads with the promoted value.
+            for (Node* node : *block) {
+                m_graph.performSubstitution(node);
+                
+                if (Node* escapee = m_materializationToEscapee.get(node))
+                    populateMaterialize(block, node, escapee);
+                
+                promoteHeapAccess(
+                    node,
+                    [&] (PromotedHeapLocation location, Edge value) {
+                        if (m_sinkCandidates.contains(location.base()))
+                            m_localMapping.set(location, value.node());
+                    },
+                    [&] (PromotedHeapLocation location) {
+                        if (m_sinkCandidates.contains(location.base())) {
+                            switch (node->op()) {
+                            case CheckStructure:
+                                node->convertToCheckStructureImmediate(resolve(block, location));
+                                break;
+
+                            default:
+                                node->replaceWith(resolve(block, location));
+                                break;
+                            }
+                        }
+                    });
+            }
+            
+            // Gotta drop some Upsilons.
+            NodeAndIndex terminal = block->findTerminal();
+            size_t upsilonInsertionPoint = terminal.index;
+            NodeOrigin upsilonOrigin = terminal.node->origin;
+            for (BasicBlock* successorBlock : block->successors()) {
+                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef->value();
+                    SSACalculator::Variable* variable = phiDef->variable();
+                    PromotedHeapLocation location = m_indexToLocation[variable->index()];
+                    Node* incoming = resolve(block, location);
+                    
+                    m_insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), incoming->defaultEdge());
+                }
+            }
+            
+            m_insertionSet.execute(block);
+        }
+    }
+    
+    Node* resolve(BasicBlock* block, PromotedHeapLocation location)
+    {
+        if (Node* result = m_localMapping.get(location))
+            return result;
+        
+        // This implies that there is no local mapping. Find a non-local mapping.
+        SSACalculator::Def* def = m_ssaCalculator.nonLocalReachingDef(
+            block, m_locationToVariable.get(location));
+        ASSERT(def);
+        ASSERT(def->value());
+        m_localMapping.add(location, def->value());
+        return def->value();
+    }
+
+    template<typename SinkCandidateFunctor, typename EscapeFunctor>
+    void handleNode(
+        Node* node,
+        const SinkCandidateFunctor& sinkCandidate,
+        const EscapeFunctor& escape)
+    {
+        switch (node->op()) {
+        case NewObject:
+        case MaterializeNewObject:
+        case MaterializeCreateActivation:
+            sinkCandidate();
+            m_graph.doToChildren(
+                node,
+                [&] (Edge edge) {
+                    escape(edge.node());
+                });
+            break;
+
+        case NewFunction:
+            if (!node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid())
+                sinkCandidate();
+            escape(node->child1().node());
+            break;
+
+        case CreateActivation:
+            if (!node->castOperand<SymbolTable*>()->singletonScope()->isStillValid())
+                sinkCandidate();
+            escape(node->child1().node());
+            break;
+
+        case Check:
+            m_graph.doToChildren(
+                node,
+                [&] (Edge edge) {
+                    if (edge.willNotHaveCheck())
+                        return;
+                    
+                    if (alreadyChecked(edge.useKind(), SpecObject))
+                        return;
+                    
+                    escape(edge.node());
+                });
+            break;
+
+        case MovHint:
+        case PutHint:
+            break;
+
+        case PutStructure:
+        case CheckStructure:
+        case GetByOffset:
+        case MultiGetByOffset:
+        case GetGetterSetterByOffset: {
+            Node* target = node->child1().node();
+            if (!target->isObjectAllocation())
+                escape(target);
+            break;
+        }
+            
+        case PutByOffset: {
+            Node* target = node->child2().node();
+            if (!target->isObjectAllocation()) {
+                escape(target);
+                escape(node->child1().node());
+            }
+            escape(node->child3().node());
+            break;
+        }
+
+        case GetClosureVar: {
+            Node* target = node->child1().node();
+            if (!target->isActivationAllocation())
+                escape(target);
+            break;
+        }
+
+        case PutClosureVar: {
+            Node* target = node->child1().node();
+            if (!target->isActivationAllocation())
+                escape(target);
+            escape(node->child2().node());
+            break;
+        }
+
+        case GetScope: {
+            Node* target = node->child1().node();
+            if (!target->isFunctionAllocation())
+                escape(target);
+            break;
+        }
+
+        case GetExecutable: {
+            Node* target = node->child1().node();
+            if (!target->isFunctionAllocation())
+                escape(target);
+            break;
+        }
+
+        case SkipScope: {
+            Node* target = node->child1().node();
+            if (!target->isActivationAllocation())
+                escape(target);
+            break;
+        }
+            
+        case MultiPutByOffset:
+            // FIXME: In the future we should be able to handle this. It's just a matter of
+            // building the appropriate *Hint variant of this instruction, along with a
+            // PhantomStructureSelect node - since this transforms the Structure in a conditional
+            // way.
+            // https://bugs.webkit.org/show_bug.cgi?id=136924
+            escape(node->child1().node());
+            escape(node->child2().node());
+            break;
+
+        default:
+            m_graph.doToChildren(
+                node,
+                [&] (Edge edge) {
+                    escape(edge.node());
+                });
+            break;
+        }
+    }
+    
+    Node* createMaterialize(Node* escapee, Node* where)
+    {
+        Node* result = nullptr;
+        
+        switch (escapee->op()) {
+        case NewObject:
+        case MaterializeNewObject: {
+            ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
+            
+            result = m_graph.addNode(
+                escapee->prediction(), Node::VarArg, MaterializeNewObject,
+                NodeOrigin(
+                    escapee->origin.semantic,
+                    where->origin.forExit),
+                OpInfo(data), OpInfo(), 0, 0);
+            break;
+        }
+
+        case NewFunction:
+            result = m_graph.addNode(
+                escapee->prediction(), NewFunction,
+                NodeOrigin(
+                    escapee->origin.semantic,
+                    where->origin.forExit),
+                OpInfo(escapee->cellOperand()),
+                escapee->child1());
+            break;
+
+        case CreateActivation:
+        case MaterializeCreateActivation: {
+            ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
+            FrozenValue* symbolTable = escapee->cellOperand();
+            result = m_graph.addNode(
+                escapee->prediction(), Node::VarArg, MaterializeCreateActivation,
+                NodeOrigin(
+                    escapee->origin.semantic,
+                    where->origin.forExit),
+                OpInfo(data), OpInfo(symbolTable), 0, 0);
+            break;
+        }
+
+        default:
+            DFG_CRASH(m_graph, escapee, "Bad escapee op");
+            break;
+        }
+        
+        if (verbose)
+            dataLog("Creating materialization point at ", where, " for ", escapee, ": ", result, "\n");
+        
+        m_materializationToEscapee.add(result, escapee);
+        m_materializationSiteToMaterializations.add(
+            where, Vector<Node*>()).iterator->value.append(result);
+        
+        return result;
+    }
+    
+    void populateMaterialize(BasicBlock* block, Node* node, Node* escapee)
+    {
+        switch (node->op()) {
+        case MaterializeNewObject: {
+            ObjectMaterializationData& data = node->objectMaterializationData();
+            unsigned firstChild = m_graph.m_varArgChildren.size();
+            
+            Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
+            
+            PromotedHeapLocation structure(StructurePLoc, escapee);
+            ASSERT(locations.contains(structure));
+            
+            m_graph.m_varArgChildren.append(Edge(resolve(block, structure), KnownCellUse));
+            
+            for (unsigned i = 0; i < locations.size(); ++i) {
+                switch (locations[i].kind()) {
+                case StructurePLoc: {
+                    ASSERT(locations[i] == structure);
+                    break;
+                }
+                    
+                case NamedPropertyPLoc: {
+                    Node* value = resolve(block, locations[i]);
+                    if (value->op() == BottomValue) {
+                        // We can skip Bottoms entirely.
+                        break;
+                    }
+                    
+                    data.m_properties.append(PhantomPropertyValue(locations[i].info()));
+                    m_graph.m_varArgChildren.append(value);
+                    break;
+                }
+                    
+                default:
+                    DFG_CRASH(m_graph, node, "Bad location kind");
+                }
+            }
+            
+            node->children = AdjacencyList(
+                AdjacencyList::Variable,
+                firstChild, m_graph.m_varArgChildren.size() - firstChild);
+            break;
+        }
+
+        case MaterializeCreateActivation: {
+            ObjectMaterializationData& data = node->objectMaterializationData();
+
+            unsigned firstChild = m_graph.m_varArgChildren.size();
+
+            Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
+
+            PromotedHeapLocation scope(ActivationScopePLoc, escapee);
+            PromotedHeapLocation symbolTable(ActivationSymbolTablePLoc, escapee);
+            ASSERT(locations.contains(scope));
+
+            m_graph.m_varArgChildren.append(Edge(resolve(block, scope), KnownCellUse));
+
+            for (unsigned i = 0; i < locations.size(); ++i) {
+                switch (locations[i].kind()) {
+                case ActivationScopePLoc: {
+                    ASSERT(locations[i] == scope);
+                    break;
+                }
+
+                case ActivationSymbolTablePLoc: {
+                    ASSERT(locations[i] == symbolTable);
+                    break;
+                }
+
+                case ClosureVarPLoc: {
+                    Node* value = resolve(block, locations[i]);
+                    if (value->op() == BottomValue)
+                        break;
+
+                    data.m_properties.append(PhantomPropertyValue(locations[i].info()));
+                    m_graph.m_varArgChildren.append(value);
+                    break;
+                }
+
+                default:
+                    DFG_CRASH(m_graph, node, "Bad location kind");
+                }
+            }
+
+            node->children = AdjacencyList(
+                AdjacencyList::Variable,
+                firstChild, m_graph.m_varArgChildren.size() - firstChild);
+            break;
+        }
+
+        case NewFunction: {
+            if (!ASSERT_DISABLED) {
+                Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
+
+                ASSERT(locations.size() == 2);
+
+                PromotedHeapLocation executable(FunctionExecutablePLoc, escapee);
+                ASSERT(locations.contains(executable));
+
+                PromotedHeapLocation activation(FunctionActivationPLoc, escapee);
+                ASSERT(locations.contains(activation));
+
+                for (unsigned i = 0; i < locations.size(); ++i) {
+                    switch (locations[i].kind()) {
+                    case FunctionExecutablePLoc: {
+                        ASSERT(locations[i] == executable);
+                        break;
+                    }
+
+                    case FunctionActivationPLoc: {
+                        ASSERT(locations[i] == activation);
+                        break;
+                    }
+
+                    default:
+                        DFG_CRASH(m_graph, node, "Bad location kind");
+                    }
+                }
+            }
+
+            break;
+        }
+
+        default:
+            DFG_CRASH(m_graph, node, "Bad materialize op");
+            break;
+        }
+    }
+    
+    CombinedLiveness m_combinedLiveness;
+    SSACalculator m_ssaCalculator;
+    HashSet<Node*> m_sinkCandidates;
+    HashMap<Node*, Node*> m_materializationToEscapee;
+    HashMap<Node*, Vector<Node*>> m_materializationSiteToMaterializations;
+    HashMap<Node*, Vector<PromotedHeapLocation>> m_locationsForAllocation;
+    HashMap<PromotedHeapLocation, SSACalculator::Variable*> m_locationToVariable;
+    Vector<PromotedHeapLocation> m_indexToLocation;
+    HashMap<PromotedHeapLocation, Node*> m_localMapping;
+    InsertionSet m_insertionSet;
+};
+    
+bool performObjectAllocationSinking(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Object Allocation Sinking Phase");
+    return runPhase<ObjectAllocationSinkingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGObjectAllocationSinkingPhase.h b/dfg/DFGObjectAllocationSinkingPhase.h
new file mode 100644 (file)
index 0000000..1630f66
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGObjectAllocationSinkingPhase_h
+#define DFGObjectAllocationSinkingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Sinks object allocations down to their uses. This will sink the allocations over OSR exits, by
+// replacing all stores to those objects with store hints so that OSR exit can materialize the
+// object. This may sink allocations past returns, creating control flow paths along which the
+// objects are not allocated at all. Replaces all uses of the objects' fields with SSA data flow.
+
+bool performObjectAllocationSinking(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGObjectAllocationSinkingPhase_h
+
diff --git a/dfg/DFGObjectMaterializationData.cpp b/dfg/DFGObjectMaterializationData.cpp
new file mode 100644 (file)
index 0000000..3abdbe6
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGObjectMaterializationData.h"
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace DFG {
+
+void PhantomPropertyValue::dump(PrintStream& out) const
+{
+    out.print("id", m_identifierNumber);
+}
+
+void ObjectMaterializationData::dump(PrintStream& out) const
+{
+    out.print("[", listDump(m_properties), "]");
+}
+
+float ObjectMaterializationData::oneWaySimilarityScore(
+    const ObjectMaterializationData& other) const
+{
+    unsigned numHits = 0;
+    for (PhantomPropertyValue value : m_properties) {
+        if (other.m_properties.contains(value))
+            numHits++;
+    }
+    return static_cast<float>(numHits) / static_cast<float>(m_properties.size());
+}
+
+float ObjectMaterializationData::similarityScore(const ObjectMaterializationData& other) const
+{
+    return std::min(oneWaySimilarityScore(other), other.oneWaySimilarityScore(*this));
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGObjectMaterializationData.h b/dfg/DFGObjectMaterializationData.h
new file mode 100644 (file)
index 0000000..1c4febe
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGObjectMaterializationData_h
+#define DFGObjectMaterializationData_h
+
+#if ENABLE(DFG_JIT)
+
+#include <limits.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+struct PhantomPropertyValue {
+    PhantomPropertyValue()
+        : m_identifierNumber(UINT_MAX)
+    {
+    }
+    
+    PhantomPropertyValue(unsigned identifierNumber)
+        : m_identifierNumber(identifierNumber)
+    {
+    }
+    
+    unsigned m_identifierNumber;
+    
+    bool operator==(const PhantomPropertyValue& other) const
+    {
+        return m_identifierNumber == other.m_identifierNumber;
+    }
+    
+    void dump(PrintStream&) const;
+};
+
+struct ObjectMaterializationData {
+    // Determines the meaning of the passed nodes.
+    Vector<PhantomPropertyValue> m_properties;
+    
+    void dump(PrintStream&) const;
+    
+    // The fraction of my properties that the other data has.
+    float oneWaySimilarityScore(const ObjectMaterializationData&) const;
+    
+    // The minimum of the two possible one-way scores.
+    float similarityScore(const ObjectMaterializationData&) const;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGObjectMaterializationData_h
+
index 15cb4f5c45caa1d282da2c7e874bfcf0cd62d910..6f9512ba534c490d4bf998af5d0824412dbb914e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "DFGOperations.h"
 
-#include "Arguments.h"
 #include "ButterflyInlines.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CommonSlowPaths.h"
 #include "CopiedSpaceInlines.h"
@@ -38,6 +38,7 @@
 #include "DFGToFTLDeferredCompilationCallback.h"
 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
 #include "DFGWorklist.h"
+#include "DirectArguments.h"
 #include "FTLForOSREntryJITCode.h"
 #include "FTLOSREntry.h"
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITExceptions.h"
-#include "JSActivation.h"
-#include "VM.h"
+#include "JSCInlines.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
-#include "NameInstance.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "Repatch.h"
+#include "ScopedArguments.h"
 #include "StringConstructor.h"
+#include "Symbol.h"
+#include "TypeProfilerLog.h"
 #include "TypedArrayInlines.h"
+#include "VM.h"
 #include <wtf/InlineASM.h>
 
 #if ENABLE(JIT)
@@ -66,6 +69,7 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
+    ASSERT(isIndex(index));
     if (direct) {
         RELEASE_ASSERT(baseValue.isObject());
         asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
@@ -96,6 +100,8 @@ ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exe
     JSValue value = JSValue::decode(encodedValue);
 
     if (LIKELY(property.isUInt32())) {
+        // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
+        ASSERT(isIndex(property.asUInt32()));
         putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
         return;
     }
@@ -103,32 +109,26 @@ ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exe
     if (property.isDouble()) {
         double propertyAsDouble = property.asDouble();
         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
-        if (propertyAsDouble == propertyAsUInt32) {
+        if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
             putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
             return;
         }
     }
 
-    if (isName(property)) {
-        PutPropertySlot slot(baseValue, strict);
-        if (direct) {
-            RELEASE_ASSERT(baseValue.isObject());
-            asObject(baseValue)->putDirect(*vm, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
-        } else
-            baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
+    // Don't put to an object if toString throws an exception.
+    auto propertyName = property.toPropertyKey(exec);
+    if (vm->exception())
         return;
-    }
 
-    // Don't put to an object if toString throws an exception.
-    Identifier ident = property.toString(exec)->toIdentifier(exec);
-    if (!vm->exception()) {
-        PutPropertySlot slot(baseValue, strict);
-        if (direct) {
-            RELEASE_ASSERT(baseValue.isObject());
-            asObject(baseValue)->putDirect(*vm, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
-        } else
-            baseValue.put(exec, ident, value, slot);
-    }
+    PutPropertySlot slot(baseValue, strict);
+    if (direct) {
+        RELEASE_ASSERT(baseValue.isObject());
+        if (Optional<uint32_t> index = parseIndex(propertyName))
+            asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+        else
+            asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
+    } else
+        baseValue.put(exec, propertyName, value, slot);
 }
 
 template<typename ViewClass>
@@ -137,7 +137,7 @@ char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     if (size < 0) {
-        vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
+        vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
         return 0;
     }
     return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
@@ -156,7 +156,7 @@ char* newTypedArrayWithOneArgument(
         RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
         
         if (buffer->byteLength() % ViewClass::elementSize) {
-            vm.throwException(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"));
+            vm.throwException(exec, createRangeError(exec, ASCIILiteral("ArrayBuffer length minus the byteOffset is not a multiple of the element size")));
             return 0;
         }
         return bitwise_cast<char*>(
@@ -183,18 +183,18 @@ char* newTypedArrayWithOneArgument(
     if (value.isInt32())
         length = value.asInt32();
     else if (!value.isNumber()) {
-        vm.throwException(exec, createTypeError(exec, "Invalid array length argument"));
+        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument")));
         return 0;
     } else {
         length = static_cast<int>(value.asNumber());
         if (length != value.asNumber()) {
-            vm.throwException(exec, createTypeError(exec, "Invalid array length argument (fractional lengths not allowed)"));
+            vm.throwException(exec, createTypeError(exec, ASCIILiteral("Invalid array length argument (fractional lengths not allowed)")));
             return 0;
         }
     }
     
     if (length < 0) {
-        vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
+        vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
         return 0;
     }
     
@@ -229,7 +229,7 @@ JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor
     ASSERT(jsCast<JSFunction*>(constructor)->methodTable(vm)->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
 #endif
     
-    return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
+    return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->allocationProfile()->structure());
 }
 
 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
@@ -292,22 +292,26 @@ EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e
         } else if (property.isDouble()) {
             double propertyAsDouble = property.asDouble();
             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
-            if (propertyAsUInt32 == propertyAsDouble)
+            if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
                 return getByVal(exec, base, propertyAsUInt32);
         } else if (property.isString()) {
             Structure& structure = *base->structure(vm);
             if (JSCell::canUseFastGetOwnProperty(structure)) {
-                if (JSValue result = base->fastGetOwnProperty(vm, structure, asString(property)->value(exec)))
-                    return JSValue::encode(result);
+                if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
+                    if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
+                        return JSValue::encode(result);
+                }
             }
         }
     }
 
-    if (isName(property))
-        return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
-
-    Identifier ident = property.toString(exec)->toIdentifier(exec);
-    return JSValue::encode(baseValue.get(exec, ident));
+    baseValue.requireObjectCoercible(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    auto propertyName = property.toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(baseValue.get(exec, propertyName));
 }
 
 EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
@@ -327,16 +331,17 @@ EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base
     } else if (property.isString()) {
         Structure& structure = *base->structure(vm);
         if (JSCell::canUseFastGetOwnProperty(structure)) {
-            if (JSValue result = base->fastGetOwnProperty(vm, structure, asString(property)->value(exec)))
-                return JSValue::encode(result);
+            if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
+                if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
+                    return JSValue::encode(result);
+            }
         }
     }
 
-    if (isName(property))
-        return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
-
-    Identifier ident = property.toString(exec)->toIdentifier(exec);
-    return JSValue::encode(JSValue(base).get(exec, ident));
+    auto propertyName = property.toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(JSValue(base).get(exec, propertyName));
 }
 
 ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
@@ -757,87 +762,182 @@ char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
     return newTypedArrayWithOneArgument<JSFloat64Array>(exec, structure, encodedValue);
 }
 
-JSCell* JIT_OPERATION operationCreateInlinedArguments(
-    ExecState* exec, InlineCallFrame* inlineCallFrame)
+JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    // NB: This needs to be exceedingly careful with top call frame tracking, since it
-    // may be called from OSR exit, while the state of the call stack is bizarre.
-    Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
-    ASSERT(!vm.exception());
+    return JSLexicalEnvironment::create(vm, structure, scope, table);
+}
+
+JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    DirectArguments* result = DirectArguments::create(
+        vm, structure, length, std::max(length, minCapacity));
+    // The caller will store to this object without barriers. Most likely, at this point, this is
+    // still a young object and so no barriers are needed. But it's good to be careful anyway,
+    // since the GC should be allowed to do crazy (like pretenuring, for example).
+    vm.heap.writeBarrier(result);
     return result;
 }
 
-JSCell* JIT_OPERATION operationCreateInlinedArgumentsDuringOSRExit(ExecState* exec, InlineCallFrame* inlineCallFrame)
+JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
 {
-    DeferGCForAWhile(exec->vm().heap);
-    return operationCreateInlinedArguments(exec, inlineCallFrame);
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    
+    // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
+    // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
+    ScopedArgumentsTable* table = scope->symbolTable()->arguments();
+    
+    return ScopedArguments::createByCopyingFrom(
+        vm, structure, argumentStart, length, callee, table, scope);
 }
 
-void JIT_OPERATION operationTearOffInlinedArguments(
-    ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
+JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
 {
-    ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
-    jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    return ClonedArguments::createByCopyingFrom(
+        exec, structure, argumentStart, length, callee);
 }
 
-EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
+JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
 {
     VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
+    NativeCallFrameTracer target(&vm, exec);
+    
+    DeferGCForAWhile deferGC(vm.heap);
+    
+    CodeBlock* codeBlock;
+    if (inlineCallFrame)
+        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
+    else
+        codeBlock = exec->codeBlock();
+    
+    unsigned length = argumentCount - 1;
+    unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
+    DirectArguments* result = DirectArguments::create(
+        vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
+    
+    result->callee().set(vm, result, callee);
+    
+    Register* arguments =
+        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
+        CallFrame::argumentOffset(0);
+    for (unsigned i = length; i--;)
+        result->setIndexQuickly(vm, i, arguments[i].jsValue());
+    
+    return result;
+}
 
-    JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
+JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    
+    DeferGCForAWhile deferGC(vm.heap);
     
-    // If there are no arguments, and we're accessing out of bounds, then we have to create the
-    // arguments in case someone has installed a getter on a numeric property.
-    if (!argumentsValue)
-        exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
+    CodeBlock* codeBlock;
+    if (inlineCallFrame)
+        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
+    else
+        codeBlock = exec->codeBlock();
     
-    return JSValue::encode(argumentsValue.get(exec, index));
+    unsigned length = argumentCount - 1;
+    ClonedArguments* result = ClonedArguments::createEmpty(
+        vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
+    
+    Register* arguments =
+        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
+        CallFrame::argumentOffset(0);
+    for (unsigned i = length; i--;)
+        result->putDirectIndex(exec, i, arguments[i].jsValue());
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    
+    return result;
 }
 
-EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(
-    ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
+size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
-    JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
+    ASSERT(jsDynamicCast<JSObject*>(object));
     
-    // If there are no arguments, and we're accessing out of bounds, then we have to create the
-    // arguments in case someone has installed a getter on a numeric property.
-    if (!argumentsValue) {
-        exec->uncheckedR(argumentsRegister) = argumentsValue =
-            Arguments::create(exec->vm(), exec, inlineCallFrame);
+    if (object->structure(vm)->masqueradesAsUndefined(globalObject))
+        return false;
+    if (object->type() == JSFunctionType)
+        return false;
+    if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+        CallData callData;
+        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+            return false;
     }
     
-    return JSValue::encode(argumentsValue.get(exec, index));
+    return true;
 }
 
-JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSCell* functionExecutable)
+size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
 {
-    ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    return JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
-}
 
-size_t JIT_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
-{
-    return jsIsObjectType(exec, JSValue::decode(value));
+    ASSERT(jsDynamicCast<JSObject*>(object));
+    
+    if (object->structure(vm)->masqueradesAsUndefined(globalObject))
+        return false;
+    if (object->type() == JSFunctionType)
+        return true;
+    if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+        CallData callData;
+        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+            return true;
+    }
+    
+    return false;
 }
 
-size_t JIT_OPERATION operationIsFunction(EncodedJSValue value)
+JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
 {
-    return jsIsFunctionType(JSValue::decode(value));
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    ASSERT(jsDynamicCast<JSObject*>(object));
+    
+    if (object->structure(vm)->masqueradesAsUndefined(globalObject))
+        return vm.smallStrings.undefinedString();
+    if (object->type() == JSFunctionType)
+        return vm.smallStrings.functionString();
+    if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+        CallData callData;
+        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+            return vm.smallStrings.functionString();
+    }
+    
+    return vm.smallStrings.objectString();
 }
 
-JSCell* JIT_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
+int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    return jsTypeStringForValue(exec, JSValue(value)).asCell();
+
+    ASSERT(jsDynamicCast<JSObject*>(object));
+    
+    if (object->structure(vm)->masqueradesAsUndefined(globalObject))
+        return static_cast<int32_t>(TypeofType::Undefined);
+    if (object->type() == JSFunctionType)
+        return static_cast<int32_t>(TypeofType::Function);
+    if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+        CallData callData;
+        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+            return static_cast<int32_t>(TypeofType::Function);
+    }
+    
+    return static_cast<int32_t>(TypeofType::Object);
 }
 
 char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
@@ -914,17 +1014,6 @@ char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
     return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
 }
 
-char* JIT_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    
-    if (!cell->isObject())
-        return 0;
-    
-    return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
-}
-
 char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
 {
     VM& vm = exec->vm();
@@ -976,6 +1065,22 @@ JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
     return JSValue::decode(value).toString(exec);
 }
 
+JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    return stringConstructor(exec, cell);
+}
+
+JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    return stringConstructor(exec, JSValue::decode(value));
+}
+
 JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
 {
     VM& vm = exec->vm();
@@ -1024,13 +1129,48 @@ char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JS
     return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
 }
 
-void JIT_OPERATION operationNotifyWrite(ExecState* exec, VariableWatchpointSet* set, EncodedJSValue encodedValue)
+int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    JSValue value = JSValue::decode(encodedValue);
 
-    set->notifyWrite(vm, value);
+    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
+}
+
+void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    set->touch("Executed NotifyWrite");
+}
+
+void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    throwStackOverflowError(exec);
+}
+
+int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue arguments = JSValue::decode(encodedArguments);
+    
+    return sizeOfVarargs(exec, arguments, firstVarArgOffset);
+}
+
+void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue arguments = JSValue::decode(encodedArguments);
+    
+    loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
+    
+    for (int32_t i = length; i < mandatoryMinimum; ++i)
+        exec->r(firstElementDest + i) = jsUndefined();
 }
 
 double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
@@ -1058,6 +1198,11 @@ int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
     return tryConvertToInt52(value);
 }
 
+void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec) 
+{
+    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
+}
+
 size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
 {
     VM* vm = &exec->vm();
@@ -1105,7 +1250,7 @@ void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void*
     dataLog("\n");
 }
 
-extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
+extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
 {
     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
     // really be profitable.
@@ -1129,13 +1274,21 @@ extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
     ASSERT(codeBlock->hasOptimizedReplacement());
     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
+    
+    bool didTryToEnterIntoInlinedLoops = false;
+    for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
+        if (inlineCallFrame->executable->didTryToEnterInLoop()) {
+            didTryToEnterIntoInlinedLoops = true;
+            break;
+        }
+    }
 
     // In order to trigger reoptimization, one of two things must have happened:
     // 1) We exited more than some number of times.
     // 2) We exited and got stuck in a loop, and now we're exiting again.
     bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
     bool didGetStuckInLoop =
-        codeBlock->checkIfOptimizationThresholdReached()
+        (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
         && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
     
     if (!didExitABunch && !didGetStuckInLoop) {
@@ -1198,13 +1351,18 @@ static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode*
         Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
 }
 
-void JIT_OPERATION triggerTierUpNow(ExecState* exec)
+static void triggerTierUpNowCommon(ExecState* exec, bool inLoop)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     DeferGC deferGC(vm->heap);
     CodeBlock* codeBlock = exec->codeBlock();
     
+    if (codeBlock->jitType() != JITCode::DFGJIT) {
+        dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
     JITCode* jitCode = codeBlock->jitCode()->dfg();
     
     if (Options::verboseOSR()) {
@@ -1212,10 +1370,22 @@ void JIT_OPERATION triggerTierUpNow(ExecState* exec)
             *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
             jitCode->tierUpCounter, "\n");
     }
-    
+    if (inLoop)
+        jitCode->nestedTriggerIsSet = 1;
+
     triggerFTLReplacementCompile(vm, codeBlock, jitCode);
 }
 
+void JIT_OPERATION triggerTierUpNow(ExecState* exec)
+{
+    triggerTierUpNowCommon(exec, false);
+}
+
+void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec)
+{
+    triggerTierUpNowCommon(exec, true);
+}
+
 char* JIT_OPERATION triggerOSREntryNow(
     ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
 {
@@ -1224,11 +1394,17 @@ char* JIT_OPERATION triggerOSREntryNow(
     DeferGC deferGC(vm->heap);
     CodeBlock* codeBlock = exec->codeBlock();
     
+    if (codeBlock->jitType() != JITCode::DFGJIT) {
+        dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
     JITCode* jitCode = codeBlock->jitCode()->dfg();
+    jitCode->nestedTriggerIsSet = 0;
     
     if (Options::verboseOSR()) {
         dataLog(
-            *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
+            *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
             jitCode->tierUpCounter, "\n");
     }
     
@@ -1271,7 +1447,7 @@ char* JIT_OPERATION triggerOSREntryNow(
         
         // OSR entry failed. Oh no! This implies that we need to retry. We retry
         // without exponential backoff and we only do this for the entry code block.
-        jitCode->osrEntryBlock.clear();
+        jitCode->osrEntryBlock = nullptr;
         jitCode->osrEntryRetry = 0;
         return 0;
     }
index 720b60a9c9bf9e67affa1cbb43fae38e34cdcfc0..c102b87ad3b74edd909fd3d031341060606f0d10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,9 +31,9 @@
 #include "JITOperations.h"
 #include "PutKind.h"
 
-namespace JSC {
+namespace JSC { namespace DFG {
 
-namespace DFG {
+struct OSRExitBase;
 
 extern "C" {
 
@@ -96,16 +96,17 @@ EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, JSCell*, JSCell*) W
 size_t JIT_OPERATION operationRegExpTest(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateInlinedArguments(ExecState*, InlineCallFrame*) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateInlinedArgumentsDuringOSRExit(ExecState*, InlineCallFrame*) WTF_INTERNAL;
-void JIT_OPERATION operationTearOffInlinedArguments(ExecState*, JSCell*, JSCell*, InlineCallFrame*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(ExecState*, int32_t, InlineCallFrame*, int32_t) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int32_t) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState*, JSCell*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*);
+JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
+JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
+JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment*);
+JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
+JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee);
 double JIT_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
-size_t JIT_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
-size_t JIT_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationTypeOf(ExecState*, JSCell*) WTF_INTERNAL;
+size_t JIT_OPERATION operationObjectIsObject(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
+size_t JIT_OPERATION operationObjectIsFunction(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationTypeOfObject(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
+int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
 char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
 char* JIT_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
 char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL;
@@ -113,7 +114,6 @@ char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*
 char* JIT_OPERATION operationEnsureInt32(ExecState*, JSCell*);
 char* JIT_OPERATION operationEnsureDouble(ExecState*, JSCell*);
 char* JIT_OPERATION operationEnsureContiguous(ExecState*, JSCell*);
-char* JIT_OPERATION operationRageEnsureContiguous(ExecState*, JSCell*);
 char* JIT_OPERATION operationEnsureArrayStorage(ExecState*, JSCell*);
 StringImpl* JIT_OPERATION operationResolveRope(ExecState*, JSString*);
 JSString* JIT_OPERATION operationSingleCharacterString(ExecState*, int32_t);
@@ -121,25 +121,34 @@ JSString* JIT_OPERATION operationSingleCharacterString(ExecState*, int32_t);
 JSCell* JIT_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
 JSCell* JIT_OPERATION operationToStringOnCell(ExecState*, JSCell*);
 JSCell* JIT_OPERATION operationToString(ExecState*, EncodedJSValue);
+JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState*, JSCell*);
+JSCell* JIT_OPERATION operationCallStringConstructor(ExecState*, EncodedJSValue);
 JSCell* JIT_OPERATION operationMakeRope2(ExecState*, JSString*, JSString*);
 JSCell* JIT_OPERATION operationMakeRope3(ExecState*, JSString*, JSString*, JSString*);
 char* JIT_OPERATION operationFindSwitchImmTargetForDouble(ExecState*, EncodedJSValue, size_t tableIndex);
 char* JIT_OPERATION operationSwitchString(ExecState*, size_t tableIndex, JSString*);
-void JIT_OPERATION operationNotifyWrite(ExecState*, VariableWatchpointSet*, EncodedJSValue);
+int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState*, size_t tableIndex, JSString*);
+void JIT_OPERATION operationNotifyWrite(ExecState*, WatchpointSet*);
+void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState*) WTF_INTERNAL;
+int32_t JIT_OPERATION operationSizeOfVarargs(ExecState*, EncodedJSValue arguments, int32_t firstVarArgOffset);
+void JIT_OPERATION operationLoadVarargs(ExecState*, int32_t firstElementDest, EncodedJSValue arguments, int32_t offset, int32_t length, int32_t mandatoryMinimum);
 
 int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue);
 int64_t JIT_OPERATION operationConvertDoubleToInt52(double);
 
+void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState*) WTF_INTERNAL;
+
 // These operations implement the implicitly called ToInt32 and ToBoolean conversions from ES5.
 // This conversion returns an int32_t within a size_t such that the value is zero extended to fill the register.
 size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState*, EncodedJSValue) WTF_INTERNAL;
 
 void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*, void*) WTF_INTERNAL;
 
-void JIT_OPERATION triggerReoptimizationNow(CodeBlock*) WTF_INTERNAL;
+void JIT_OPERATION triggerReoptimizationNow(CodeBlock*, OSRExitBase*) WTF_INTERNAL;
 
 #if ENABLE(FTL_JIT)
 void JIT_OPERATION triggerTierUpNow(ExecState*) WTF_INTERNAL;
+void JIT_OPERATION triggerTierUpNowInLoop(ExecState*) WTF_INTERNAL;
 char* JIT_OPERATION triggerOSREntryNow(ExecState*, int32_t bytecodeIndex, int32_t streamIndex) WTF_INTERNAL;
 #endif // ENABLE(FTL_JIT)
 
diff --git a/dfg/DFGPhantomInsertionPhase.cpp b/dfg/DFGPhantomInsertionPhase.cpp
new file mode 100644 (file)
index 0000000..b9e023f
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPhantomInsertionPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "BytecodeLivenessAnalysisInlines.h"
+#include "DFGForAllKills.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGMayExit.h"
+#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "JSCInlines.h"
+#include "OperandsInlines.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class PhantomInsertionPhase : public Phase {
+public:
+    PhantomInsertionPhase(Graph& graph)
+        : Phase(graph, "phantom insertion")
+        , m_insertionSet(graph)
+        , m_values(OperandsLike, graph.block(0)->variablesAtHead)
+    {
+    }
+    
+    bool run()
+    {
+        // We assume that DCE has already run. If we run before DCE then we think that all
+        // SetLocals execute, which is inaccurate. That causes us to insert too few Phantoms.
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_refCountState == ExactRefCount);
+        
+        if (verbose) {
+            dataLog("Graph before Phantom insertion:\n");
+            m_graph.dump();
+        }
+        
+        m_graph.clearEpochs();
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+            handleBlock(block);
+        
+        if (verbose) {
+            dataLog("Graph after Phantom insertion:\n");
+            m_graph.dump();
+        }
+        
+        return true;
+    }
+
+private:
+    void handleBlock(BasicBlock* block)
+    {
+        // FIXME: For blocks that have low register pressure, it would make the most sense to
+        // simply insert Phantoms at the last point possible since that would obviate the need to
+        // query bytecode liveness:
+        //
+        // - If we MovHint @x into loc42 then put a Phantom on the last MovHinted value in loc42.
+        // - At the end of the block put Phantoms for each MovHinted value.
+        //
+        // This will definitely not work if there are any phantom allocations. For those blocks
+        // where this would be legal, it remains to be seen how profitable it would be even if there
+        // was high register pressure. After all, a Phantom would cause a spill but it wouldn't
+        // cause a fill.
+        //
+        // https://bugs.webkit.org/show_bug.cgi?id=144524
+        
+        m_values.fill(nullptr);
+
+        Epoch currentEpoch = Epoch::first();
+        unsigned lastExitingIndex = 0;
+        for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            if (verbose)
+                dataLog("Considering ", node, "\n");
+            
+            switch (node->op()) {
+            case MovHint:
+                m_values.operand(node->unlinkedLocal()) = node->child1().node();
+                break;
+                
+            case ZombieHint:
+                m_values.operand(node->unlinkedLocal()) = nullptr;
+                break;
+
+            case SetLocal:
+            case GetLocal:
+            case SetArgument:
+                m_values.operand(node->local()) = nullptr;
+                break;
+                
+            default:
+                break;
+            }
+            
+            if (mayExit(m_graph, node)) {
+                currentEpoch.bump();
+                lastExitingIndex = nodeIndex;
+            }
+            
+            m_graph.doToChildren(
+                node,
+                [&] (Edge edge) {
+                    edge->setEpoch(currentEpoch);
+                });
+            
+            node->setEpoch(currentEpoch);
+
+            forAllKilledOperands(
+                m_graph, node, block->tryAt(nodeIndex + 1),
+                [&] (VirtualRegister reg) {
+                    if (verbose)
+                        dataLog("    Killed operand: ", reg, "\n");
+                    
+                    Node* killedNode = m_values.operand(reg);
+                    if (!killedNode)
+                        return;
+                    
+                    // We only need to insert a Phantom if the node hasn't been used since the last
+                    // exit, and was born before the last exit.
+                    if (killedNode->epoch() == currentEpoch)
+                        return;
+                    
+                    if (verbose) {
+                        dataLog(
+                            "    Inserting Phantom on ", killedNode, " after ",
+                            block->at(lastExitingIndex), "\n");
+                    }
+                    
+                    // We have exact ref counts, so creating a new use means that we have to
+                    // increment the ref count.
+                    killedNode->postfixRef();
+                    
+                    m_insertionSet.insertNode(
+                        lastExitingIndex + 1, SpecNone, Phantom,
+                        block->at(lastExitingIndex)->origin, killedNode->defaultEdge());
+            });
+        }
+        
+        m_insertionSet.execute(block);
+    }
+    
+    InsertionSet m_insertionSet;
+    Operands<Node*> m_values;
+};
+
+} // anonymous namespace
+    
+bool performPhantomInsertion(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Phantom Insertion Phase");
+    return runPhase<PhantomInsertionPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPhantomInsertionPhase.h b/dfg/DFGPhantomInsertionPhase.h
new file mode 100644 (file)
index 0000000..902975b
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPhantomInsertionPhase_h
+#define DFGPhantomInsertionPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Inserts Phantoms based on bytecode liveness.
+
+bool performPhantomInsertion(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPhantomInsertionPhase_h
index 15c413a569a00993308ea15bc59f708742333372..c13c8c449140e070b6898273db739f6824b23732 100644 (file)
@@ -35,8 +35,15 @@ namespace JSC { namespace DFG {
 
 void Phase::beginPhase()
 {
+    if (Options::verboseValidationFailure()) {
+        StringPrintStream out;
+        m_graph.dump(out);
+        m_graphDumpBeforePhase = out.toCString();
+    }
+    
     if (!shouldDumpGraphAtEachPhase())
         return;
+    
     dataLog("Beginning DFG phase ", m_name, ".\n");
     dataLog("Before ", m_name, ":\n");
     m_graph.dump();
@@ -46,7 +53,7 @@ void Phase::endPhase()
 {
     if (!Options::validateGraphAtEachPhase())
         return;
-    validate(m_graph, DumpGraph);
+    validate(m_graph, DumpGraph, m_graphDumpBeforePhase);
 }
 
 } } // namespace JSC::DFG
index fc9e0d188c6e387fbd46e875718be8f38dcf1662..5e8b329fa08a06e139165d098e9fe3732a5dfea2 100644 (file)
@@ -67,6 +67,8 @@ private:
     // Call these hooks when starting and finishing.
     void beginPhase();
     void endPhase();
+    
+    CString m_graphDumpBeforePhase;
 };
 
 template<typename PhaseType>
diff --git a/dfg/DFGPhiChildren.cpp b/dfg/DFGPhiChildren.cpp
new file mode 100644 (file)
index 0000000..de078d0
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPhiChildren.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+PhiChildren::PhiChildren()
+{
+}
+
+PhiChildren::PhiChildren(Graph& graph)
+{
+    for (BasicBlock* block : graph.blocksInNaturalOrder()) {
+        for (Node* node : *block) {
+            if (node->op() != Upsilon)
+                continue;
+            
+            m_children.add(node->phi(), List()).iterator->value.append(node);
+        }
+    }
+}
+
+PhiChildren::~PhiChildren()
+{
+}
+
+const PhiChildren::List& PhiChildren::upsilonsOf(Node* node) const
+{
+    ASSERT(node->op() == Phi);
+    return m_children.find(node)->value;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPhiChildren.h b/dfg/DFGPhiChildren.h
new file mode 100644 (file)
index 0000000..808512e
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPhiChildren_h
+#define DFGPhiChildren_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNode.h"
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class PhiChildren {
+public:
+    typedef Vector<Node*, 3> List;
+    
+    PhiChildren();
+    PhiChildren(Graph&);
+    ~PhiChildren();
+    
+    // The list of Upsilons that point to the children of the Phi.
+    const List& upsilonsOf(Node*) const;
+    
+    template<typename Functor>
+    void forAllIncomingValues(Node* node, const Functor& functor)
+    {
+        for (Node* upsilon : upsilonsOf(node))
+            functor(upsilon->child1().node());
+    }
+    
+    // This walks the Phi graph.
+    template<typename Functor>
+    void forAllTransitiveIncomingValues(Node* node, const Functor& functor)
+    {
+        if (node->op() != Phi) {
+            functor(node);
+            return;
+        }
+        HashSet<Node*> seen;
+        Vector<Node*> worklist;
+        seen.add(node);
+        worklist.append(node);
+        while (!worklist.isEmpty()) {
+            Node* currentNode = worklist.takeLast();
+            forAllIncomingValues(
+                currentNode,
+                [&] (Node* incomingNode) {
+                    if (incomingNode->op() == Phi) {
+                        if (seen.add(incomingNode).isNewEntry)
+                            worklist.append(incomingNode);
+                    } else
+                        functor(incomingNode);
+                });
+        }
+    }
+    
+private:
+    HashMap<Node*, List> m_children;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPhiChildren_h
+
index 6de782c2a292f6193e0d45ef2e9629fa0a67c5f8..bf7b7dd176ed5a7cefa3cb5fa3547ae52b381006 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
-#include "DFGArgumentsSimplificationPhase.h"
+#include "DFGArgumentsEliminationPhase.h"
 #include "DFGBackwardsPropagationPhase.h"
 #include "DFGByteCodeParser.h"
 #include "DFGCFAPhase.h"
 #include "DFGCFGSimplificationPhase.h"
 #include "DFGCPSRethreadingPhase.h"
 #include "DFGCSEPhase.h"
+#include "DFGCleanUpPhase.h"
 #include "DFGConstantFoldingPhase.h"
+#include "DFGConstantHoistingPhase.h"
 #include "DFGCriticalEdgeBreakingPhase.h"
 #include "DFGDCEPhase.h"
 #include "DFGFailedFinalizer.h"
 #include "DFGFixupPhase.h"
 #include "DFGGraphSafepoint.h"
 #include "DFGIntegerCheckCombiningPhase.h"
+#include "DFGIntegerRangeOptimizationPhase.h"
 #include "DFGInvalidationPointInjectionPhase.h"
 #include "DFGJITCompiler.h"
 #include "DFGLICMPhase.h"
 #include "DFGLivenessAnalysisPhase.h"
 #include "DFGLoopPreHeaderCreationPhase.h"
+#include "DFGMovHintRemovalPhase.h"
 #include "DFGOSRAvailabilityAnalysisPhase.h"
 #include "DFGOSREntrypointCreationPhase.h"
+#include "DFGObjectAllocationSinkingPhase.h"
+#include "DFGPhantomInsertionPhase.h"
 #include "DFGPredictionInjectionPhase.h"
 #include "DFGPredictionPropagationPhase.h"
-#include "DFGResurrectionForValidationPhase.h"
+#include "DFGPutStackSinkingPhase.h"
 #include "DFGSSAConversionPhase.h"
 #include "DFGSSALoweringPhase.h"
 #include "DFGStackLayoutPhase.h"
 #include "DFGStaticExecutionCountEstimationPhase.h"
-#include "DFGStoreBarrierElisionPhase.h"
+#include "DFGStoreBarrierInsertionPhase.h"
 #include "DFGStrengthReductionPhase.h"
+#include "DFGStructureRegistrationPhase.h"
 #include "DFGTierUpCheckInjectionPhase.h"
 #include "DFGTypeCheckHoistingPhase.h"
 #include "DFGUnificationPhase.h"
 #include "DFGValidate.h"
+#include "DFGVarargsForwardingPhase.h"
 #include "DFGVirtualRegisterAllocationPhase.h"
 #include "DFGWatchpointCollectionPhase.h"
 #include "Debugger.h"
 #include "JSCInlines.h"
 #include "OperandsInlines.h"
 #include "ProfilerDatabase.h"
+#include "TrackedReferences.h"
 #include <wtf/CurrentTime.h>
 
 #if ENABLE(FTL_JIT)
 
 namespace JSC { namespace DFG {
 
-static void dumpAndVerifyGraph(Graph& graph, const char* text)
+static void dumpAndVerifyGraph(Graph& graph, const char* text, bool forceDump = false)
 {
     GraphDumpMode modeForFinalValidate = DumpGraph;
-    if (verboseCompilationEnabled(graph.m_plan.mode)) {
+    if (verboseCompilationEnabled(graph.m_plan.mode) || forceDump) {
         dataLog(text, "\n");
         graph.dump();
         modeForFinalValidate = DontDumpGraph;
@@ -146,7 +155,7 @@ void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadDat
     double before = 0;
     CString codeBlockName;
     if (reportCompileTimes()) {
-        before = currentTimeMS();
+        before = monotonicallyIncreasingTimeMS();
         codeBlockName = toCString(*codeBlock);
     }
     
@@ -178,13 +187,15 @@ void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadDat
             break;
         default:
             RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
             pathName = "";
+#endif
             break;
         }
-        double now = currentTimeMS();
+        double now = monotonicallyIncreasingTimeMS();
         dataLog("Optimized ", codeBlockName, " using ", mode, " with ", pathName, " into ", finalizer ? finalizer->codeSize() : 0, " bytes in ", now - before, " ms");
         if (path == FTLPath)
-            dataLog(" (DFG: ", beforeFTL - before, ", LLVM: ", now - beforeFTL, ")");
+            dataLog(" (DFG: ", m_timeBeforeFTL - before, ", LLVM: ", now - m_timeBeforeFTL, ")");
         dataLog(".\n");
     }
 }
@@ -200,7 +211,7 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     Graph dfg(vm, *this, longLivedState);
     
     if (!parse(dfg)) {
-        finalizer = adoptPtr(new FailedFinalizer(*this));
+        finalizer = std::make_unique<FailedFinalizer>(*this);
         return FailPath;
     }
     
@@ -213,6 +224,11 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     if (validationEnabled())
         validate(dfg);
     
+    if (Options::dumpGraphAfterParsing()) {
+        dataLog("Graph after parsing:\n");
+        dfg.dump();
+    }
+    
     performCPSRethreading(dfg);
     performUnification(dfg);
     performPredictionInjection(dfg);
@@ -222,7 +238,7 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     if (mode == FTLForOSREntryMode) {
         bool result = performOSREntrypointCreation(dfg);
         if (!result) {
-            finalizer = adoptPtr(new FailedFinalizer(*this));
+            finalizer = std::make_unique<FailedFinalizer>(*this);
             return FailPath;
         }
         performCPSRethreading(dfg);
@@ -234,65 +250,89 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     performBackwardsPropagation(dfg);
     performPredictionPropagation(dfg);
     performFixup(dfg);
+    performStructureRegistration(dfg);
     performInvalidationPointInjection(dfg);
     performTypeCheckHoisting(dfg);
     
-    unsigned count = 1;
     dfg.m_fixpointState = FixpointNotConverged;
-    for (;; ++count) {
-        if (logCompilationChanges(mode))
-            dataLogF("DFG beginning optimization fixpoint iteration #%u.\n", count);
-        bool changed = false;
+    
+    // For now we're back to avoiding a fixpoint. Note that we've ping-ponged on this decision
+    // many times. For maximum throughput, it's best to fixpoint. But the throughput benefit is
+    // small and not likely to show up in FTL anyway. On the other hand, not fixpointing means
+    // that the compiler compiles more quickly. We want the third tier to compile quickly, which
+    // not fixpointing accomplishes; and the fourth tier shouldn't need a fixpoint.
+    if (validationEnabled())
+        validate(dfg);
         
-        if (validationEnabled())
-            validate(dfg);
+    performStrengthReduction(dfg);
+    performLocalCSE(dfg);
+    performCPSRethreading(dfg);
+    performCFA(dfg);
+    performConstantFolding(dfg);
+    bool changed = false;
+    changed |= performCFGSimplification(dfg);
+    changed |= performLocalCSE(dfg);
+    
+    if (validationEnabled())
+        validate(dfg);
+    
+    performCPSRethreading(dfg);
+    if (!isFTL(mode)) {
+        // Only run this if we're not FTLing, because currently for a LoadVarargs that is forwardable and
+        // in a non-varargs inlined call frame, this will generate ForwardVarargs while the FTL
+        // ArgumentsEliminationPhase will create a sequence of GetStack+PutStacks. The GetStack+PutStack
+        // sequence then gets sunk, eliminating anything that looks like an escape for subsequent phases,
+        // while the ForwardVarargs doesn't get simplified until later (or not at all) and looks like an
+        // escape for all of the arguments. This then disables object allocation sinking.
+        //
+        // So, for now, we just disable this phase for the FTL.
+        //
+        // If we wanted to enable it, we'd have to do any of the following:
+        // - Enable ForwardVarargs->GetStack+PutStack strength reduction, and have that run before
+        //   PutStack sinking and object allocation sinking.
+        // - Make VarargsForwarding emit a GetLocal+SetLocal sequence, that we can later turn into
+        //   GetStack+PutStack.
+        //
+        // But, it's not super valuable to enable those optimizations, since the FTL
+        // ArgumentsEliminationPhase does everything that this phase does, and it doesn't introduce this
+        // pathology.
         
-        changed |= performStrengthReduction(dfg);
+        changed |= performVarargsForwarding(dfg); // Do this after CFG simplification and CPS rethreading.
+    }
+    if (changed) {
         performCFA(dfg);
-        changed |= performConstantFolding(dfg);
-        changed |= performArgumentsSimplification(dfg);
-        changed |= performCFGSimplification(dfg);
-        changed |= performCSE(dfg);
-        
-        if (!changed)
-            break;
-        
-        performCPSRethreading(dfg);
+        performConstantFolding(dfg);
     }
     
-    if (logCompilationChanges(mode))
-        dataLogF("DFG optimization fixpoint converged in %u iterations.\n", count);
-
-    dfg.m_fixpointState = FixpointConverged;
-
     // If we're doing validation, then run some analyses, to give them an opportunity
     // to self-validate. Now is as good a time as any to do this.
     if (validationEnabled()) {
         dfg.m_dominators.computeIfNecessary(dfg);
         dfg.m_naturalLoops.computeIfNecessary(dfg);
+        dfg.m_prePostNumbering.computeIfNecessary(dfg);
     }
 
     switch (mode) {
     case DFGMode: {
+        dfg.m_fixpointState = FixpointConverged;
+    
         performTierUpCheckInjection(dfg);
 
-        performStoreBarrierElision(dfg);
-        performStoreElimination(dfg);
+        performFastStoreBarrierInsertion(dfg);
+        performCleanUp(dfg);
         performCPSRethreading(dfg);
         performDCE(dfg);
+        performPhantomInsertion(dfg);
         performStackLayout(dfg);
         performVirtualRegisterAllocation(dfg);
         performWatchpointCollection(dfg);
         dumpAndVerifyGraph(dfg, "Graph after optimization:");
         
         JITCompiler dataFlowJIT(dfg);
-        if (codeBlock->codeType() == FunctionCode) {
+        if (codeBlock->codeType() == FunctionCode)
             dataFlowJIT.compileFunction();
-            dataFlowJIT.linkFunction();
-        } else {
+        else
             dataFlowJIT.compile();
-            dataFlowJIT.link();
-        }
         
         return DFGPath;
     }
@@ -301,37 +341,76 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     case FTLForOSREntryMode: {
 #if ENABLE(FTL_JIT)
         if (FTL::canCompile(dfg) == FTL::CannotCompile) {
-            finalizer = adoptPtr(new FailedFinalizer(*this));
+            finalizer = std::make_unique<FailedFinalizer>(*this);
             return FailPath;
         }
         
+        performCleanUp(dfg); // Reduce the graph size a bit.
         performCriticalEdgeBreaking(dfg);
         performLoopPreHeaderCreation(dfg);
         performCPSRethreading(dfg);
         performSSAConversion(dfg);
         performSSALowering(dfg);
-        performCSE(dfg);
+        
+        // Ideally, these would be run to fixpoint with the object allocation sinking phase.
+        performArgumentsElimination(dfg);
+        performPutStackSinking(dfg);
+        
+        performConstantHoisting(dfg);
+        performGlobalCSE(dfg);
+        performLivenessAnalysis(dfg);
+        performIntegerRangeOptimization(dfg);
         performLivenessAnalysis(dfg);
         performCFA(dfg);
+        performConstantFolding(dfg);
+        performCleanUp(dfg); // Reduce the graph size a lot.
+        changed = false;
+        changed |= performStrengthReduction(dfg);
+        if (Options::enableObjectAllocationSinking()) {
+            changed |= performCriticalEdgeBreaking(dfg);
+            changed |= performObjectAllocationSinking(dfg);
+        }
+        if (changed) {
+            // State-at-tail and state-at-head will be invalid if we did strength reduction since
+            // it might increase live ranges.
+            performLivenessAnalysis(dfg);
+            performCFA(dfg);
+            performConstantFolding(dfg);
+        }
+        
+        // Currently, this relies on pre-headers still being valid. That precludes running CFG
+        // simplification before it, unless we re-created the pre-headers. There wouldn't be anything
+        // wrong with running LICM earlier, if we wanted to put other CFG transforms above this point.
+        // Alternatively, we could run loop pre-header creation after SSA conversion - but if we did that
+        // then we'd need to do some simple SSA fix-up.
         performLICM(dfg);
+        
+        performCleanUp(dfg);
         performIntegerCheckCombining(dfg);
-        performCSE(dfg);
+        performGlobalCSE(dfg);
         
         // At this point we're not allowed to do any further code motion because our reasoning
         // about code motion assumes that it's OK to insert GC points in random places.
+        dfg.m_fixpointState = FixpointConverged;
         
-        performStoreBarrierElision(dfg);
         performLivenessAnalysis(dfg);
         performCFA(dfg);
-        if (Options::validateFTLOSRExitLiveness())
-            performResurrectionForValidation(dfg);
-        performDCE(dfg); // We rely on this to convert dead SetLocals into the appropriate hint, and to kill dead code that won't be recognized as dead by LLVM.
+        performGlobalStoreBarrierInsertion(dfg);
+        if (Options::enableMovHintRemoval())
+            performMovHintRemoval(dfg);
+        performCleanUp(dfg);
+        performDCE(dfg); // We rely on this to kill dead code that won't be recognized as dead by LLVM.
         performStackLayout(dfg);
         performLivenessAnalysis(dfg);
         performOSRAvailabilityAnalysis(dfg);
         performWatchpointCollection(dfg);
         
-        dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:");
+        if (FTL::canCompile(dfg) == FTL::CannotCompile) {
+            finalizer = std::make_unique<FailedFinalizer>(*this);
+            return FailPath;
+        }
+
+        dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:", shouldShowDisassembly(mode));
         
         bool haveLLVM;
         Safepoint::Result safepointResult;
@@ -343,18 +422,19 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
             return CancelPath;
         
         if (!haveLLVM) {
-            finalizer = adoptPtr(new FailedFinalizer(*this));
+            if (Options::ftlCrashesIfCantInitializeLLVM()) {
+                dataLog("LLVM can't be initialized.\n");
+                CRASH();
+            }
+            finalizer = std::make_unique<FailedFinalizer>(*this);
             return FailPath;
         }
-            
+
         FTL::State state(dfg);
-        if (!FTL::lowerDFGToLLVM(state)) {
-            FTL::fail(state);
-            return FTLPath;
-        }
+        FTL::lowerDFGToLLVM(state);
         
         if (reportCompileTimes())
-            beforeFTL = currentTimeMS();
+            m_timeBeforeFTL = monotonicallyIncreasingTimeMS();
         
         if (Options::llvmAlwaysFailsBeforeCompile()) {
             FTL::fail(state);
@@ -369,6 +449,11 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
             FTL::fail(state);
             return FTLPath;
         }
+        
+        if (state.allocationFailed) {
+            FTL::fail(state);
+            return FTLPath;
+        }
 
         if (state.jitCode->stackmaps.stackSize() > Options::llvmMaxStackSize()) {
             FTL::fail(state);
@@ -376,6 +461,12 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
         }
 
         FTL::link(state);
+        
+        if (state.allocationFailed) {
+            FTL::fail(state);
+            return FTLPath;
+        }
+        
         return FTLPath;
 #else
         RELEASE_ASSERT_NOT_REACHED();
@@ -402,8 +493,6 @@ bool Plan::isStillValid()
         return false;
     if (!watchpoints.areStillValid())
         return false;
-    if (!chains.areStillValid())
-        return false;
     return true;
 }
 
@@ -448,6 +537,21 @@ CompilationResult Plan::finalizeWithoutNotifyingCallback()
     
     reallyAdd(codeBlock->jitCode()->dfgCommon());
     
+    if (validationEnabled()) {
+        TrackedReferences trackedReferences;
+        
+        for (WriteBarrier<JSCell>& reference : codeBlock->jitCode()->dfgCommon()->weakReferences)
+            trackedReferences.add(reference.get());
+        for (WriteBarrier<Structure>& reference : codeBlock->jitCode()->dfgCommon()->weakStructureReferences)
+            trackedReferences.add(reference.get());
+        for (WriteBarrier<Unknown>& constant : codeBlock->constants())
+            trackedReferences.add(constant.get());
+        
+        // Check that any other references that we have anywhere in the JITCode are also
+        // tracked either strongly or weakly.
+        codeBlock->jitCode()->validateReferences(trackedReferences);
+    }
+    
     return CompilationSuccessful;
 }
 
@@ -473,7 +577,6 @@ void Plan::checkLivenessAndVisitChildren(SlotVisitor& visitor, CodeBlockSet& cod
     codeBlocks.mark(codeBlock.get());
     codeBlocks.mark(profiledDFGCodeBlock.get());
     
-    chains.visitChildren(visitor);
     weakReferences.visitChildren(visitor);
     writeBarriers.visitChildren(visitor);
     transitions.visitChildren(visitor);
@@ -498,11 +601,10 @@ void Plan::cancel()
     profiledDFGCodeBlock = nullptr;
     mustHandleValues.clear();
     compilation = nullptr;
-    finalizer.clear();
+    finalizer = nullptr;
     inlineCallFrames = nullptr;
     watchpoints = DesiredWatchpoints();
     identifiers = DesiredIdentifiers();
-    chains = DesiredStructureChains();
     weakReferences = DesiredWeakReferences();
     writeBarriers = DesiredWriteBarriers();
     transitions = DesiredTransitions();
index a2fdced1e8a34800364eb7533269bec910644b3a..6e7b53f3a122faccf34adf65dfee82e869291df0 100644 (file)
@@ -30,7 +30,6 @@
 #include "DFGCompilationKey.h"
 #include "DFGCompilationMode.h"
 #include "DFGDesiredIdentifiers.h"
-#include "DFGDesiredStructureChains.h"
 #include "DFGDesiredTransitions.h"
 #include "DFGDesiredWatchpoints.h"
 #include "DFGDesiredWeakReferences.h"
@@ -87,20 +86,17 @@ struct Plan : public ThreadSafeRefCounted<Plan> {
 
     RefPtr<Profiler::Compilation> compilation;
 
-    OwnPtr<Finalizer> finalizer;
+    std::unique_ptr<Finalizer> finalizer;
     
     RefPtr<InlineCallFrameSet> inlineCallFrames;
     DesiredWatchpoints watchpoints;
     DesiredIdentifiers identifiers;
-    DesiredStructureChains chains;
     DesiredWeakReferences weakReferences;
     DesiredWriteBarriers writeBarriers;
     DesiredTransitions transitions;
     
     bool willTryToTierUp;
 
-    double beforeFTL;
-
     enum Stage { Preparing, Compiling, Compiled, Ready, Cancelled };
     Stage stage;
 
@@ -114,6 +110,8 @@ private:
     
     bool isStillValid();
     void reallyAdd(CommonData*);
+
+    double m_timeBeforeFTL;
 };
 
 #else // ENABLE(DFG_JIT)
diff --git a/dfg/DFGPrePostNumbering.cpp b/dfg/DFGPrePostNumbering.cpp
new file mode 100644 (file)
index 0000000..166ff45
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPrePostNumbering.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMapInlines.h"
+#include "DFGBlockWorklist.h"
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+PrePostNumbering::PrePostNumbering() { }
+PrePostNumbering::~PrePostNumbering() { }
+
+void PrePostNumbering::compute(Graph& graph)
+{
+    m_map = BlockMap<Numbering>(graph);
+    
+    PostOrderBlockWorklist worklist;
+    worklist.push(graph.block(0));
+    unsigned nextPreNumber = 0;
+    unsigned nextPostNumber = 0;
+    while (BlockWithOrder item = worklist.pop()) {
+        switch (item.order) {
+        case PreOrder:
+            m_map[item.block].m_preNumber = nextPreNumber++;
+            worklist.pushPost(item.block);
+            for (BasicBlock* successor : item.block->successors())
+                worklist.push(successor);
+            break;
+        case PostOrder:
+            m_map[item.block].m_postNumber = nextPostNumber++;
+            break;
+        }
+    }
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, EdgeKind kind)
+{
+    switch (kind) {
+    case ForwardEdge:
+        out.print("ForwardEdge");
+        return;
+    case CrossEdge:
+        out.print("CrossEdge");
+        return;
+    case BackEdge:
+        out.print("BackEdge");
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPrePostNumbering.h b/dfg/DFGPrePostNumbering.h
new file mode 100644 (file)
index 0000000..286bf62
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPrePostNumbering_h
+#define DFGPrePostNumbering_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAnalysis.h"
+#include "DFGBasicBlock.h"
+#include "DFGBlockMap.h"
+
+namespace JSC { namespace DFG {
+
+enum EdgeKind {
+    ForwardEdge,
+    CrossEdge,
+    BackEdge
+};
+
+class PrePostNumbering : public Analysis<PrePostNumbering> {
+public:
+    PrePostNumbering();
+    ~PrePostNumbering();
+
+    void compute(Graph&);
+    
+    unsigned preNumber(BasicBlock* block) const { return m_map[block].m_preNumber; }
+    unsigned postNumber(BasicBlock* block) const { return m_map[block].m_postNumber; }
+    
+    // Is from a strict ancestor of to?
+    bool isStrictAncestorOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return preNumber(from) < preNumber(to)
+            && postNumber(from) > postNumber(to);
+    }
+    
+    bool isAncestorOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return from == to || isStrictAncestorOf(from, to);
+    }
+    
+    bool isStrictDescendantOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return isStrictAncestorOf(to, from);
+    }
+    
+    bool isDescendantOf(BasicBlock* from, BasicBlock* to) const
+    {
+        return isAncestorOf(to, from);
+    }
+    
+    // This will give a bogus answer if there is actually no such edge. If you want to determine
+    // if there is any such edge, you have to do it yourself.
+    EdgeKind edgeKind(BasicBlock* from, BasicBlock* to) const
+    {
+        if (isStrictDescendantOf(to, from))
+            return ForwardEdge;
+        
+        if (isAncestorOf(to, from))
+            return BackEdge;
+        
+        return CrossEdge;
+    }
+    
+private:
+    struct Numbering {
+        unsigned m_preNumber;
+        unsigned m_postNumber;
+    };
+    
+    BlockMap<Numbering> m_map;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::EdgeKind);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPrePostNumbering_h
+
diff --git a/dfg/DFGPreciseLocalClobberize.h b/dfg/DFGPreciseLocalClobberize.h
new file mode 100644 (file)
index 0000000..1cd6b09
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPreciseLocalClobberize_h
+#define DFGPreciseLocalClobberize_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGClobberize.h"
+#include "DFGMayExit.h"
+
+namespace JSC { namespace DFG {
+
+template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
+class PreciseLocalClobberizeAdaptor {
+public:
+    PreciseLocalClobberizeAdaptor(
+        Graph& graph, Node* node,
+        const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def)
+        : m_graph(graph)
+        , m_node(node)
+        , m_read(read)
+        , m_write(write)
+        , m_def(def)
+    {
+    }
+    
+    void read(AbstractHeap heap)
+    {
+        if (heap.kind() == Stack) {
+            if (heap.payload().isTop()) {
+                readTop();
+                return;
+            }
+            
+            callIfAppropriate(m_read, VirtualRegister(heap.payload().value32()));
+            return;
+        }
+        
+        if (heap.overlaps(Stack)) {
+            readTop();
+            return;
+        }
+    }
+    
+    void write(AbstractHeap heap)
+    {
+        // We expect stack writes to already be precisely characterized by DFG::clobberize().
+        if (heap.kind() == Stack) {
+            RELEASE_ASSERT(!heap.payload().isTop());
+            callIfAppropriate(m_write, VirtualRegister(heap.payload().value32()));
+            return;
+        }
+        
+        RELEASE_ASSERT(!heap.overlaps(Stack));
+    }
+    
+    void def(PureValue)
+    {
+        // PureValue defs never have anything to do with locals, so ignore this.
+    }
+    
+    void def(HeapLocation location, LazyNode node)
+    {
+        if (location.kind() != StackLoc)
+            return;
+        
+        RELEASE_ASSERT(location.heap().kind() == Stack);
+        
+        m_def(VirtualRegister(location.heap().payload().value32()), node);
+    }
+    
+private:
+    template<typename Functor>
+    void callIfAppropriate(const Functor& functor, VirtualRegister operand)
+    {
+        if (operand.isLocal() && static_cast<unsigned>(operand.toLocal()) >= m_graph.block(0)->variablesAtHead.numberOfLocals())
+            return;
+        
+        if (operand.isArgument() && !operand.isHeader() && static_cast<unsigned>(operand.toArgument()) >= m_graph.block(0)->variablesAtHead.numberOfArguments())
+            return;
+        
+        functor(operand);
+    }
+    
+    void readTop()
+    {
+        switch (m_node->op()) {
+        case GetMyArgumentByVal:
+        case ForwardVarargs:
+        case CallForwardVarargs:
+        case ConstructForwardVarargs: {
+            InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
+            if (!inlineCallFrame) {
+                // Read the outermost arguments and argument count.
+                for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
+                    m_read(virtualRegisterForArgument(i));
+                m_read(VirtualRegister(JSStack::ArgumentCount));
+                break;
+            }
+            
+            for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
+                m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
+            if (inlineCallFrame->isVarargs())
+                m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
+            break;
+        }
+            
+        default: {
+            // All of the outermost arguments, except this, are definitely read.
+            for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
+                m_read(virtualRegisterForArgument(i));
+        
+            // The stack header is read.
+            for (unsigned i = 0; i < JSStack::ThisArgument; ++i)
+                m_read(VirtualRegister(i));
+        
+            // Read all of the inline arguments and call frame headers that we didn't already capture.
+            for (InlineCallFrame* inlineCallFrame = m_node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
+                for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
+                    m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
+                if (inlineCallFrame->isClosureCall)
+                    m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::Callee));
+                if (inlineCallFrame->isVarargs())
+                    m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
+            }
+            break;
+        } }
+    }
+    
+    Graph& m_graph;
+    Node* m_node;
+    const ReadFunctor& m_read;
+    const WriteFunctor& m_write;
+    const DefFunctor& m_def;
+};
+
+template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
+void preciseLocalClobberize(
+    Graph& graph, Node* node,
+    const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def)
+{
+    PreciseLocalClobberizeAdaptor<ReadFunctor, WriteFunctor, DefFunctor>
+        adaptor(graph, node, read, write, def);
+    clobberize(graph, node, adaptor);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPreciseLocalClobberize_h
+
index 6a35b9cbd7edab74dc4cbf3c388e8ab33ecc0a8a..cde09bf121b21f8a4feb60dfa24fb420b6a9baba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,6 +57,8 @@ public:
         ASSERT(m_graph.m_form == ThreadedCPS);
         ASSERT(m_graph.m_unificationState == GloballyUnified);
 
+        propagateThroughArgumentPositions();
+
         m_pass = PrimaryPass;
         propagateToFixpoint();
         
@@ -141,14 +143,18 @@ private:
         bool changed = false;
         
         switch (op) {
-        case JSConstant:
-        case WeakJSConstant: {
-            SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node));
+        case JSConstant: {
+            SpeculatedType type = speculationFromValue(node->asJSValue());
             if (type == SpecInt52AsDouble && enableInt52())
                 type = SpecInt52;
             changed |= setPrediction(type);
             break;
         }
+        case DoubleConstant: {
+            SpeculatedType type = speculationFromValue(node->asJSValue());
+            changed |= setPrediction(type);
+            break;
+        }
             
         case GetLocal: {
             VariableAccessData* variable = node->variableAccessData();
@@ -172,7 +178,8 @@ private:
         case BitRShift:
         case BitLShift:
         case BitURShift:
-        case ArithIMul: {
+        case ArithIMul:
+        case ArithClz32: {
             changed |= setPrediction(SpecInt32);
             break;
         }
@@ -183,16 +190,42 @@ private:
         case RegExpTest:
         case GetById:
         case GetByIdFlush:
-        case GetMyArgumentByValSafe:
         case GetByOffset:
         case MultiGetByOffset:
+        case GetDirectPname:
         case Call:
         case Construct:
+        case CallVarargs:
+        case ConstructVarargs:
+        case CallForwardVarargs:
+        case ConstructForwardVarargs:
+        case NativeCall:
+        case NativeConstruct:
         case GetGlobalVar:
-        case GetClosureVar: {
+        case GetClosureVar:
+        case GetFromArguments: {
             changed |= setPrediction(node->getHeapPrediction());
             break;
         }
+            
+        case GetGetterSetterByOffset:
+        case GetExecutable: {
+            changed |= setPrediction(SpecCellOther);
+            break;
+        }
+
+        case GetGetter:
+        case GetSetter:
+        case GetCallee:
+        case NewFunction: {
+            changed |= setPrediction(SpecFunction);
+            break;
+        }
+            
+        case GetArgumentCount: {
+            changed |= setPrediction(SpecInt32);
+            break;
+        }
 
         case StringCharCodeAt: {
             changed |= setPrediction(SpecInt32);
@@ -232,22 +265,8 @@ private:
             }
             break;
         }
-            
-        case ArithAdd: {
-            SpeculatedType left = node->child1()->prediction();
-            SpeculatedType right = node->child2()->prediction();
-            
-            if (left && right) {
-                if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
-                    changed |= mergePrediction(SpecInt32);
-                else if (m_graph.addShouldSpeculateMachineInt(node))
-                    changed |= mergePrediction(SpecInt52);
-                else
-                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
-            }
-            break;
-        }
-            
+
+        case ArithAdd:
         case ArithSub: {
             SpeculatedType left = node->child1()->prediction();
             SpeculatedType right = node->child2()->prediction();
@@ -303,21 +322,8 @@ private:
             }
             break;
         }
-            
-        case ArithDiv: {
-            SpeculatedType left = node->child1()->prediction();
-            SpeculatedType right = node->child2()->prediction();
-            
-            if (left && right) {
-                if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
-                    && node->canSpeculateInt32(m_pass))
-                    changed |= mergePrediction(SpecInt32);
-                else
-                    changed |= mergePrediction(SpecBytecodeDouble);
-            }
-            break;
-        }
-            
+
+        case ArithDiv:
         case ArithMod: {
             SpeculatedType left = node->child1()->prediction();
             SpeculatedType right = node->child2()->prediction();
@@ -331,15 +337,25 @@ private:
             }
             break;
         }
-            
+
+        case ArithPow:
         case ArithSqrt:
         case ArithFRound:
         case ArithSin:
-        case ArithCos: {
+        case ArithCos:
+        case ArithLog: {
             changed |= setPrediction(SpecBytecodeDouble);
             break;
         }
-            
+
+        case ArithRound: {
+            if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass))
+                changed |= setPrediction(SpecInt32);
+            else
+                changed |= setPrediction(SpecBytecodeDouble);
+            break;
+        }
+
         case ArithAbs: {
             SpeculatedType child = node->child1()->prediction();
             if (isInt32OrBooleanSpeculationForArithmetic(child)
@@ -364,13 +380,14 @@ private:
         case IsNumber:
         case IsString:
         case IsObject:
+        case IsObjectOrNull:
         case IsFunction: {
             changed |= setPrediction(SpecBoolean);
             break;
         }
 
         case TypeOf: {
-            changed |= setPrediction(SpecString);
+            changed |= setPrediction(SpecStringIdent);
             break;
         }
 
@@ -382,9 +399,15 @@ private:
                 m_graph, node,
                 node->child1()->prediction(),
                 node->child2()->prediction(),
-                SpecNone, node->flags());
+                SpecNone);
             
             switch (arrayMode.type()) {
+            case Array::Int32:
+                if (arrayMode.isOutOfBounds())
+                    changed |= mergePrediction(node->getHeapPrediction() | SpecInt32);
+                else
+                    changed |= mergePrediction(SpecInt32);
+                break;
             case Array::Double:
                 if (arrayMode.isOutOfBounds())
                     changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
@@ -396,13 +419,20 @@ private:
                 changed |= mergePrediction(SpecFullDouble);
                 break;
             case Array::Uint32Array:
-                if (isInt32Speculation(node->getHeapPrediction()))
+                if (isInt32SpeculationForArithmetic(node->getHeapPrediction()))
                     changed |= mergePrediction(SpecInt32);
                 else if (enableInt52())
                     changed |= mergePrediction(SpecMachineInt);
                 else
                     changed |= mergePrediction(SpecInt32 | SpecInt52AsDouble);
                 break;
+            case Array::Int8Array:
+            case Array::Uint8Array:
+            case Array::Int16Array:
+            case Array::Uint16Array:
+            case Array::Int32Array:
+                changed |= mergePrediction(SpecInt32);
+                break;
             default:
                 changed |= mergePrediction(node->getHeapPrediction());
                 break;
@@ -410,12 +440,6 @@ private:
             break;
         }
             
-        case GetMyArgumentsLengthSafe: {
-            changed |= setPrediction(SpecInt32);
-            break;
-        }
-
-        case GetClosureRegisters:            
         case GetButterfly: 
         case GetIndexedPropertyStorage:
         case AllocatePropertyStorage:
@@ -436,18 +460,11 @@ private:
             break;
         }
             
-        case GetMyScope:
-        case SkipTopScope:
         case SkipScope: {
             changed |= setPrediction(SpecObjectOther);
             break;
         }
             
-        case GetCallee: {
-            changed |= setPrediction(SpecFunction);
-            break;
-        }
-            
         case CreateThis:
         case NewObject: {
             changed |= setPrediction(SpecFinalObject);
@@ -478,6 +495,7 @@ private:
             break;
         }
         case StringCharAt:
+        case CallStringConstructor:
         case ToString:
         case MakeRope: {
             changed |= setPrediction(SpecString);
@@ -496,23 +514,18 @@ private:
             break;
         }
             
-        case CreateArguments: {
-            changed |= setPrediction(SpecArguments);
+        case CreateDirectArguments: {
+            changed |= setPrediction(SpecDirectArguments);
             break;
         }
             
-        case NewFunction: {
-            SpeculatedType child = node->child1()->prediction();
-            if (child & SpecEmpty)
-                changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
-            else
-                changed |= mergePrediction(child);
+        case CreateScopedArguments: {
+            changed |= setPrediction(SpecScopedArguments);
             break;
         }
             
-        case NewFunctionNoCheck:
-        case NewFunctionExpression: {
-            changed |= setPrediction(SpecFunction);
+        case CreateClonedArguments: {
+            changed |= setPrediction(SpecObjectOther);
             break;
         }
             
@@ -527,30 +540,40 @@ private:
         case GetTypedArrayByteOffset:
         case DoubleAsInt32:
         case GetLocalUnlinked:
-        case GetMyArgumentsLength:
-        case GetMyArgumentByVal:
-        case PhantomPutStructure:
-        case PhantomArguments:
         case CheckArray:
         case Arrayify:
         case ArrayifyToStructure:
         case CheckTierUpInLoop:
         case CheckTierUpAtReturn:
         case CheckTierUpAndOSREnter:
+        case CheckTierUpWithNestedTriggerAndOSREnter:
         case InvalidationPoint:
         case CheckInBounds:
         case ValueToInt32:
-        case HardPhantom:
         case DoubleRep:
         case ValueRep:
         case Int52Rep:
-        case DoubleConstant:
         case Int52Constant:
         case Identity:
-        case BooleanToNumber: {
+        case BooleanToNumber:
+        case PhantomNewObject:
+        case PhantomNewFunction:
+        case PhantomCreateActivation:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case GetMyArgumentByVal:
+        case ForwardVarargs:
+        case PutHint:
+        case CheckStructureImmediate:
+        case MaterializeNewObject:
+        case MaterializeCreateActivation:
+        case PutStack:
+        case KillStack:
+        case StoreBarrier:
+        case GetStack: {
             // This node should never be visible at this stage of compilation. It is
             // inserted by fixup(), which follows this phase.
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_graph, node, "Unexpected node during prediction propagation");
             break;
         }
         
@@ -561,7 +584,6 @@ private:
             break;
             
         case Upsilon:
-        case GetArgument:
             // These don't get inserted until we go into SSA.
             RELEASE_ASSERT_NOT_REACHED();
             break;
@@ -574,13 +596,39 @@ private:
             changed |= setPrediction(SpecBoolean);
             break;
 
+        case GetEnumerableLength: {
+            changed |= setPrediction(SpecInt32);
+            break;
+        }
+        case HasGenericProperty:
+        case HasStructureProperty:
+        case HasIndexedProperty: {
+            changed |= setPrediction(SpecBoolean);
+            break;
+        }
+        case GetPropertyEnumerator: {
+            changed |= setPrediction(SpecCell);
+            break;
+        }
+        case GetEnumeratorStructurePname: {
+            changed |= setPrediction(SpecCell | SpecOther);
+            break;
+        }
+        case GetEnumeratorGenericPname: {
+            changed |= setPrediction(SpecCell | SpecOther);
+            break;
+        }
+        case ToIndexString: {
+            changed |= setPrediction(SpecString);
+            break;
+        }
+
 #ifndef NDEBUG
         // These get ignored because they don't return anything.
-        case StoreBarrier:
-        case StoreBarrierWithNullCheck:
         case PutByValDirect:
         case PutByVal:
         case PutClosureVar:
+        case PutToArguments:
         case Return:
         case Throw:
         case PutById:
@@ -594,21 +642,18 @@ private:
         case Breakpoint:
         case ProfileWillCall:
         case ProfileDidCall:
+        case ProfileType:
+        case ProfileControlFlow:
         case CheckHasInstance:
         case ThrowReferenceError:
         case ForceOSRExit:
         case SetArgument:
         case CheckStructure:
-        case CheckExecutable:
-        case StructureTransitionWatchpoint:
-        case CheckFunction:
+        case CheckCell:
+        case CheckNotEmpty:
+        case CheckBadCell:
         case PutStructure:
-        case TearOffActivation:
-        case TearOffArguments:
-        case CheckArgumentsNotCreated:
-        case VariableWatchpoint:
         case VarInjectionWatchpoint:
-        case AllocationProfileWatchpoint:
         case Phantom:
         case Check:
         case PutGlobalVar:
@@ -616,11 +661,14 @@ private:
         case Unreachable:
         case LoopHint:
         case NotifyWrite:
-        case FunctionReentryWatchpoint:
-        case TypedArrayWatchpoint:
         case ConstantStoragePointer:
         case MovHint:
         case ZombieHint:
+        case LoadVarargs:
+            break;
+            
+        // This gets ignored because it only pretends to produce a value.
+        case BottomValue:
             break;
             
         // This gets ignored because it already has a prediction.
@@ -757,6 +805,7 @@ private:
         case ArithSqrt:
         case ArithCos:
         case ArithSin:
+        case ArithLog:
             if (node->child1()->shouldSpeculateNumber())
                 m_graph.voteNode(node->child1(), VoteDouble, weight);
             else
@@ -823,8 +872,7 @@ private:
                 continue;
             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
         }
-        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
-            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
+        propagateThroughArgumentPositions();
         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
             if (!variableAccessData->isRoot())
@@ -833,6 +881,12 @@ private:
         }
     }
     
+    void propagateThroughArgumentPositions()
+    {
+        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
+            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
+    }
+    
     Node* m_currentNode;
     bool m_changed;
     PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
diff --git a/dfg/DFGPromoteHeapAccess.h b/dfg/DFGPromoteHeapAccess.h
new file mode 100644 (file)
index 0000000..2bf2875
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPromoteHeapAccess_h
+#define DFGPromoteHeapAccess_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNode.h"
+#include "DFGPromotedHeapLocation.h"
+
+namespace JSC { namespace DFG {
+
+template<typename WriteFunctor, typename ReadFunctor>
+void promoteHeapAccess(Node* node, const WriteFunctor& write, const ReadFunctor& read)
+{
+    switch (node->op()) {
+    case CheckStructure: {
+        if (node->child1()->isPhantomObjectAllocation())
+            read(PromotedHeapLocation(StructurePLoc, node->child1()));
+        break;
+    }
+    
+    case GetByOffset:
+    case GetGetterSetterByOffset: {
+        if (node->child2()->isPhantomObjectAllocation()) {
+            unsigned identifierNumber = node->storageAccessData().identifierNumber;
+            read(PromotedHeapLocation(NamedPropertyPLoc, node->child2(), identifierNumber));
+        }
+        break;
+    }
+
+    case MultiGetByOffset: {
+        if (node->child1()->isPhantomObjectAllocation()) {
+            unsigned identifierNumber = node->multiGetByOffsetData().identifierNumber;
+            read(PromotedHeapLocation(NamedPropertyPLoc, node->child1(), identifierNumber));
+        }
+        break;
+    }
+
+    case GetClosureVar:
+        if (node->child1()->isPhantomActivationAllocation())
+            read(PromotedHeapLocation(ClosureVarPLoc, node->child1(), node->scopeOffset().offset()));
+        break;
+
+    case SkipScope:
+        if (node->child1()->isPhantomActivationAllocation())
+            read(PromotedHeapLocation(ActivationScopePLoc, node->child1()));
+        break;
+
+    case GetScope:
+        if (node->child1()->isPhantomFunctionAllocation())
+            read(PromotedHeapLocation(FunctionActivationPLoc, node->child1()));
+        break;
+
+    case GetExecutable:
+        if (node->child1()->isPhantomFunctionAllocation())
+            read(PromotedHeapLocation(FunctionExecutablePLoc, node->child1()));
+        break;
+
+    case PutHint: {
+        ASSERT(node->child1()->isPhantomAllocation());
+        write(
+            PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
+            node->child2());
+        break;
+    }
+
+    default:
+        break;
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPromoteHeapAccess_h
+
diff --git a/dfg/DFGPromotedHeapLocation.cpp b/dfg/DFGPromotedHeapLocation.cpp
new file mode 100644 (file)
index 0000000..24f6977
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPromotedHeapLocation.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+void PromotedLocationDescriptor::dump(PrintStream& out) const
+{
+    out.print(m_kind, "(", m_info, ")");
+}
+
+Node* PromotedHeapLocation::createHint(Graph& graph, NodeOrigin origin, Node* value)
+{
+    return graph.addNode(
+        SpecNone, PutHint, origin, OpInfo(descriptor().imm1()), OpInfo(descriptor().imm2()),
+        base()->defaultEdge(), value->defaultEdge());
+}
+
+void PromotedHeapLocation::dump(PrintStream& out) const
+{
+    out.print(kind(), "(", m_base, ", ", info(), ")");
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, PromotedLocationKind kind)
+{
+    switch (kind) {
+    case InvalidPromotedLocationKind:
+        out.print("InvalidPromotedLocationKind");
+        return;
+        
+    case StructurePLoc:
+        out.print("StructurePLoc");
+        return;
+
+    case ActivationSymbolTablePLoc:
+        out.print("ActivationSymbolTablePLoc");
+        return;
+        
+    case NamedPropertyPLoc:
+        out.print("NamedPropertyPLoc");
+        return;
+        
+    case ArgumentPLoc:
+        out.print("ArgumentPLoc");
+        return;
+        
+    case ArgumentCountPLoc:
+        out.print("ArgumentCountPLoc");
+        return;
+        
+    case ArgumentsCalleePLoc:
+        out.print("ArgumentsCalleePLoc");
+        return;
+
+    case FunctionExecutablePLoc:
+        out.print("FunctionExecutablePLoc");
+        return;
+
+    case FunctionActivationPLoc:
+        out.print("FunctionActivationPLoc");
+        return;
+
+    case ActivationScopePLoc:
+        out.print("ActivationScopePLoc");
+        return;
+
+    case ClosureVarPLoc:
+        out.print("ClosureVarPLoc");
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF;
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPromotedHeapLocation.h b/dfg/DFGPromotedHeapLocation.h
new file mode 100644 (file)
index 0000000..bc15158
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPromotedHeapLocation_h
+#define DFGPromotedHeapLocation_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNode.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+enum PromotedLocationKind {
+    InvalidPromotedLocationKind,
+    
+    StructurePLoc,
+    ActivationSymbolTablePLoc,
+    NamedPropertyPLoc,
+    ArgumentPLoc,
+    ArgumentCountPLoc,
+    ArgumentsCalleePLoc,
+
+    FunctionExecutablePLoc,
+    FunctionActivationPLoc,
+    ActivationScopePLoc,
+    ClosureVarPLoc,
+};
+
+class PromotedLocationDescriptor {
+public:
+    PromotedLocationDescriptor(
+        PromotedLocationKind kind = InvalidPromotedLocationKind, unsigned info = 0)
+        : m_kind(kind)
+        , m_info(info)
+    {
+    }
+    
+    bool operator!() const { return m_kind == InvalidPromotedLocationKind; }
+    
+    PromotedLocationKind kind() const { return m_kind; }
+    unsigned info() const { return m_info; }
+    
+    OpInfo imm1() const { return OpInfo(static_cast<uint32_t>(m_kind)); }
+    OpInfo imm2() const { return OpInfo(static_cast<uint32_t>(m_info)); }
+    
+    unsigned hash() const
+    {
+        return m_kind + m_info;
+    }
+    
+    bool operator==(const PromotedLocationDescriptor& other) const
+    {
+        return m_kind == other.m_kind
+            && m_info == other.m_info;
+    }
+    
+    bool operator!=(const PromotedLocationDescriptor& other) const
+    {
+        return !(*this == other);
+    }
+
+    bool isHashTableDeletedValue() const
+    {
+        return m_kind == InvalidPromotedLocationKind && m_info;
+    }
+    
+    void dump(PrintStream& out) const;
+
+private:
+    PromotedLocationKind m_kind;
+    unsigned m_info;
+};
+
+class PromotedHeapLocation {
+public:
+    PromotedHeapLocation(
+        PromotedLocationKind kind = InvalidPromotedLocationKind,
+        Node* base = nullptr, unsigned info = 0)
+        : m_base(base)
+        , m_meta(kind, info)
+    {
+    }
+    
+    PromotedHeapLocation(
+        PromotedLocationKind kind, Edge base, unsigned info = 0)
+        : PromotedHeapLocation(kind, base.node(), info)
+    {
+    }
+    
+    PromotedHeapLocation(Node* base, PromotedLocationDescriptor meta)
+        : m_base(base)
+        , m_meta(meta)
+    {
+    }
+    
+    PromotedHeapLocation(WTF::HashTableDeletedValueType)
+        : m_base(nullptr)
+        , m_meta(InvalidPromotedLocationKind, 1)
+    {
+    }
+    
+    Node* createHint(Graph&, NodeOrigin, Node* value);
+    
+    bool operator!() const { return kind() == InvalidPromotedLocationKind; }
+    
+    PromotedLocationKind kind() const { return m_meta.kind(); }
+    Node* base() const { return m_base; }
+    unsigned info() const { return m_meta.info(); }
+    PromotedLocationDescriptor descriptor() const { return m_meta; }
+    
+    unsigned hash() const
+    {
+        return m_meta.hash() + WTF::PtrHash<Node*>::hash(m_base);
+    }
+    
+    bool operator==(const PromotedHeapLocation& other) const
+    {
+        return m_base == other.m_base
+            && m_meta == other.m_meta;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_meta.isHashTableDeletedValue();
+    }
+    
+    void dump(PrintStream& out) const;
+    
+private:
+    Node* m_base;
+    PromotedLocationDescriptor m_meta;
+};
+
+struct PromotedHeapLocationHash {
+    static unsigned hash(const PromotedHeapLocation& key) { return key.hash(); }
+    static bool equal(const PromotedHeapLocation& a, const PromotedHeapLocation& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::PromotedLocationKind);
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::DFG::PromotedHeapLocation> {
+    typedef JSC::DFG::PromotedHeapLocationHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::PromotedHeapLocation> : SimpleClassHashTraits<JSC::DFG::PromotedHeapLocation> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPromotedHeapLocation_h
+
diff --git a/dfg/DFGPureValue.cpp b/dfg/DFGPureValue.cpp
new file mode 100644 (file)
index 0000000..4c9f60c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPureValue.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+void PureValue::dump(PrintStream& out) const
+{
+    out.print(Graph::opName(op()));
+    out.print("(");
+    CommaPrinter comma;
+    for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+        if (children().child(i))
+            out.print(comma, children().child(i));
+    }
+    if (m_info)
+        out.print(comma, m_info);
+    out.print(")");
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPureValue.h b/dfg/DFGPureValue.h
new file mode 100644 (file)
index 0000000..e7d6a3d
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPureValue_h
+#define DFGPureValue_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNode.h"
+
+namespace JSC { namespace DFG {
+
+class PureValue {
+public:
+    PureValue()
+        : m_op(LastNodeType)
+        , m_info(0)
+    {
+    }
+    
+    PureValue(NodeType op, const AdjacencyList& children, uintptr_t info)
+        : m_op(op)
+        , m_children(children.sanitized())
+        , m_info(info)
+    {
+        ASSERT(!(defaultFlags(op) & NodeHasVarArgs));
+    }
+    
+    PureValue(NodeType op, const AdjacencyList& children, const void* ptr)
+        : PureValue(op, children, bitwise_cast<uintptr_t>(ptr))
+    {
+    }
+    
+    PureValue(NodeType op, const AdjacencyList& children)
+        : PureValue(op, children, static_cast<uintptr_t>(0))
+    {
+    }
+    
+    PureValue(Node* node, uintptr_t info)
+        : PureValue(node->op(), node->children, info)
+    {
+    }
+    
+    PureValue(Node* node, const void* ptr)
+        : PureValue(node->op(), node->children, ptr)
+    {
+    }
+    
+    PureValue(Node* node)
+        : PureValue(node->op(), node->children)
+    {
+    }
+    
+    PureValue(WTF::HashTableDeletedValueType)
+        : m_op(LastNodeType)
+        , m_info(1)
+    {
+    }
+    
+    bool operator!() const { return m_op == LastNodeType && !m_info; }
+    
+    NodeType op() const { return m_op; }
+    const AdjacencyList& children() const { return m_children; }
+    uintptr_t info() const { return m_info; }
+
+    unsigned hash() const
+    {
+        return WTF::IntHash<int>::hash(static_cast<int>(m_op)) + m_children.hash() + m_info;
+    }
+    
+    bool operator==(const PureValue& other) const
+    {
+        return m_op == other.m_op
+            && m_children == other.m_children
+            && m_info == other.m_info;
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_op == LastNodeType && m_info;
+    }
+    
+    void dump(PrintStream& out) const;
+    
+private:
+    NodeType m_op;
+    AdjacencyList m_children;
+    uintptr_t m_info;
+};
+
+struct PureValueHash {
+    static unsigned hash(const PureValue& key) { return key.hash(); }
+    static bool equal(const PureValue& a, const PureValue& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::DFG::PureValue> {
+    typedef JSC::DFG::PureValueHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::PureValue> : SimpleClassHashTraits<JSC::DFG::PureValue> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+namespace JSC { namespace DFG {
+
+typedef HashMap<PureValue, Node*> PureMap;
+typedef HashMap<PureValue, Vector<Node*>> PureMultiMap;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPureValue_h
+
diff --git a/dfg/DFGPutStackSinkingPhase.cpp b/dfg/DFGPutStackSinkingPhase.cpp
new file mode 100644 (file)
index 0000000..06bd4e2
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGPutStackSinkingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMapInlines.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPreciseLocalClobberize.h"
+#include "DFGSSACalculator.h"
+#include "DFGValidate.h"
+#include "JSCInlines.h"
+#include "OperandsInlines.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class PutStackSinkingPhase : public Phase {
+public:
+    PutStackSinkingPhase(Graph& graph)
+        : Phase(graph, "PutStack sinking")
+    {
+    }
+    
+    bool run()
+    {
+        // FIXME: One of the problems of this approach is that it will create a duplicate Phi graph
+        // for sunken PutStacks in the presence of interesting control flow merges, and where the
+        // value being PutStack'd is also otherwise live in the DFG code. We could work around this
+        // by doing the sinking over CPS, or maybe just by doing really smart hoisting. It's also
+        // possible that the duplicate Phi graph can be deduplicated by LLVM. It would be best if we
+        // could observe that there is already a Phi graph in place that does what we want. In
+        // principle if we have a request to place a Phi at a particular place, we could just check
+        // if there is already a Phi that does what we want. Because PutStackSinkingPhase runs just
+        // after SSA conversion, we have almost a guarantee that the Phi graph we produce here would
+        // be trivially redundant to the one we already have.
+        
+        // FIXME: This phase doesn't adequately use KillStacks. KillStack can be viewed as a def.
+        // This is mostly inconsequential; it would be a bug to have a local live at a KillStack.
+        // More important is that KillStack should swallow any deferral. After a KillStack, the
+        // local should behave like a TOP deferral because it would be invalid for anyone to trust
+        // the stack. It's not clear to me if this is important or not.
+        // https://bugs.webkit.org/show_bug.cgi?id=145296
+        
+        if (verbose) {
+            dataLog("Graph before PutStack sinking:\n");
+            m_graph.dump();
+        }
+        
+        SSACalculator ssaCalculator(m_graph);
+        InsertionSet insertionSet(m_graph);
+        
+        // First figure out where various locals are live.
+        BlockMap<Operands<bool>> liveAtHead(m_graph);
+        BlockMap<Operands<bool>> liveAtTail(m_graph);
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            liveAtHead[block] = Operands<bool>(OperandsLike, block->variablesAtHead);
+            liveAtTail[block] = Operands<bool>(OperandsLike, block->variablesAtHead);
+            
+            liveAtHead[block].fill(false);
+            liveAtTail[block].fill(false);
+        }
+        
+        bool changed;
+        do {
+            changed = false;
+            
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                
+                Operands<bool> live = liveAtTail[block];
+                for (unsigned nodeIndex = block->size(); nodeIndex--;) {
+                    Node* node = block->at(nodeIndex);
+                    if (verbose)
+                        dataLog("Live at ", node, ": ", live, "\n");
+                    
+                    auto escapeHandler = [&] (VirtualRegister operand) {
+                        if (operand.isHeader())
+                            return;
+                        if (verbose)
+                            dataLog("    ", operand, " is live at ", node, "\n");
+                        live.operand(operand) = true;
+                    };
+                    
+                    // FIXME: This might mishandle LoadVarargs and ForwardVarargs. It might make us
+                    // think that the locals being written are stack-live here. They aren't. This
+                    // should be harmless since we overwrite them anyway, but still, it's sloppy.
+                    // https://bugs.webkit.org/show_bug.cgi?id=145295
+                    preciseLocalClobberize(
+                        m_graph, node, escapeHandler, escapeHandler,
+                        [&] (VirtualRegister operand, LazyNode source) {
+                            RELEASE_ASSERT(source.isNode());
+
+                            if (source.asNode() == node) {
+                                // This is a load. Ignore it.
+                                return;
+                            }
+                            
+                            RELEASE_ASSERT(node->op() == PutStack);
+                            live.operand(operand) = false;
+                        });
+                }
+                
+                if (live == liveAtHead[block])
+                    continue;
+                
+                liveAtHead[block] = live;
+                changed = true;
+                
+                for (BasicBlock* predecessor : block->predecessors) {
+                    for (size_t i = live.size(); i--;)
+                        liveAtTail[predecessor][i] |= live[i];
+                }
+            }
+            
+        } while (changed);
+        
+        // All of the arguments should be live at head of root. Note that we may find that some
+        // locals are live at head of root. This seems wrong but isn't. This will happen for example
+        // if the function accesses closure variable #42 for some other function and we either don't
+        // have variable #42 at all or we haven't set it at root, for whatever reason. Basically this
+        // arises since our aliasing for closure variables is conservatively based on variable number
+        // and ignores the owning symbol table. We should probably fix this eventually and make our
+        // aliasing more precise.
+        //
+        // For our purposes here, the imprecision in the aliasing is harmless. It just means that we
+        // may not do as much Phi pruning as we wanted.
+        for (size_t i = liveAtHead.atIndex(0).numberOfArguments(); i--;)
+            DFG_ASSERT(m_graph, nullptr, liveAtHead.atIndex(0).argument(i));
+        
+        // Next identify where we would want to sink PutStacks to. We say that there is a deferred
+        // flush if we had a PutStack with a given FlushFormat but it hasn't been materialized yet.
+        // Deferrals have the following lattice; but it's worth noting that the TOP part of the
+        // lattice serves an entirely different purpose than the rest of the lattice: it just means
+        // that we're in a region of code where nobody should have been relying on the value. The
+        // rest of the lattice means that we either have a PutStack that is deferred (i.e. still
+        // needs to be executed) or there isn't one (because we've alraedy executed it).
+        //
+        // Bottom:
+        //     Represented as DeadFlush. 
+        //     Means that all previous PutStacks have been executed so there is nothing deferred.
+        //     During merging this is subordinate to the other kinds of deferrals, because it
+        //     represents the fact that we've already executed all necessary PutStacks. This implies
+        //     that there *had* been some PutStacks that we should have executed.
+        //
+        // Top:
+        //     Represented as ConflictingFlush.
+        //     Represents the fact that we know, via forward flow, that there isn't any value in the
+        //     given local that anyone should have been relying on. This comes into play at the
+        //     prologue (because in SSA form at the prologue no local has any value) or when we merge
+        //     deferrals for different formats's. A lexical scope in which a local had some semantic
+        //     meaning will by this point share the same format; if we had stores from different
+        //     lexical scopes that got merged together then we may have a conflicting format. Hence
+        //     a conflicting format proves that we're no longer in an area in which the variable was
+        //     in scope. Note that this is all approximate and only precise enough to later answer
+        //     questions pertinent to sinking. For example, this doesn't always detect when a local
+        //     is no longer semantically relevant - we may well have a deferral from inside some
+        //     inlined call survive outside of that inlined code, and this is generally OK. In the
+        //     worst case it means that we might think that a deferral that is actually dead must
+        //     still be executed. But we usually catch that with liveness. Liveness usually catches
+        //     such cases, but that's not guaranteed since liveness is conservative.
+        //
+        //     What Top does give us is detects situations where we both don't need to care about a
+        //     deferral and there is no way that we could reason about it anyway. If we merged
+        //     deferrals for different formats then we wouldn't know the format to use. So, we use
+        //     Top in that case because that's also a case where we know that we can ignore the
+        //     deferral.
+        //
+        // Deferral with a concrete format:
+        //     Represented by format values other than DeadFlush or ConflictingFlush.
+        //     Represents the fact that the original code would have done a PutStack but we haven't
+        //     identified an operation that would have observed that PutStack.
+        //
+        // This code has some interesting quirks because of the fact that neither liveness nor
+        // deferrals are very precise. They are only precise enough to be able to correctly tell us
+        // when we may [sic] need to execute PutStacks. This means that they may report the need to
+        // execute a PutStack in cases where we actually don't really need it, and that's totally OK.
+        BlockMap<Operands<FlushFormat>> deferredAtHead(m_graph);
+        BlockMap<Operands<FlushFormat>> deferredAtTail(m_graph);
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            deferredAtHead[block] =
+                Operands<FlushFormat>(OperandsLike, block->variablesAtHead);
+            deferredAtTail[block] =
+                Operands<FlushFormat>(OperandsLike, block->variablesAtHead);
+        }
+        
+        deferredAtHead.atIndex(0).fill(ConflictingFlush);
+        
+        do {
+            changed = false;
+            
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+                Operands<FlushFormat> deferred = deferredAtHead[block];
+                
+                for (Node* node : *block) {
+                    if (verbose)
+                        dataLog("Deferred at ", node, ":", deferred, "\n");
+                    
+                    if (node->op() == GetStack) {
+                        // A GetStack doesn't affect anything, since we know which local we are reading
+                        // from.
+                        continue;
+                    }
+                    
+                    auto escapeHandler = [&] (VirtualRegister operand) {
+                        if (operand.isHeader())
+                            return;
+                        // We will materialize just before any reads.
+                        deferred.operand(operand) = DeadFlush;
+                    };
+                    
+                    preciseLocalClobberize(
+                        m_graph, node, escapeHandler, escapeHandler,
+                        [&] (VirtualRegister operand, LazyNode source) {
+                            RELEASE_ASSERT(source.isNode());
+
+                            if (source.asNode() == node) {
+                                // This is a load. Ignore it.
+                                return;
+                            }
+                            
+                            deferred.operand(operand) = node->stackAccessData()->format;
+                        });
+                }
+                
+                if (deferred == deferredAtTail[block])
+                    continue;
+                
+                deferredAtTail[block] = deferred;
+                changed = true;
+                
+                for (BasicBlock* successor : block->successors()) {
+                    for (size_t i = deferred.size(); i--;) {
+                        if (verbose)
+                            dataLog("Considering ", VirtualRegister(deferred.operandForIndex(i)), " at ", pointerDump(block), "->", pointerDump(successor), ": ", deferred[i], " and ", deferredAtHead[successor][i], " merges to ");
+
+                        deferredAtHead[successor][i] =
+                            merge(deferredAtHead[successor][i], deferred[i]);
+                        
+                        if (verbose)
+                            dataLog(deferredAtHead[successor][i], "\n");
+                    }
+                }
+            }
+            
+        } while (changed);
+        
+        // We wish to insert PutStacks at all of the materialization points, which are defined
+        // implicitly as the places where we set deferred to Dead while it was previously not Dead.
+        // To do this, we may need to build some Phi functions to handle stuff like this:
+        //
+        // Before:
+        //
+        //     if (p)
+        //         PutStack(r42, @x)
+        //     else
+        //         PutStack(r42, @y)
+        //
+        // After:
+        //
+        //     if (p)
+        //         Upsilon(@x, ^z)
+        //     else
+        //         Upsilon(@y, ^z)
+        //     z: Phi()
+        //     PutStack(r42, @z)
+        //
+        // This means that we have an SSACalculator::Variable for each local, and a Def is any
+        // PutStack in the original program. The original PutStacks will simply vanish.
+        
+        Operands<SSACalculator::Variable*> operandToVariable(
+            OperandsLike, m_graph.block(0)->variablesAtHead);
+        Vector<VirtualRegister> indexToOperand;
+        for (size_t i = m_graph.block(0)->variablesAtHead.size(); i--;) {
+            VirtualRegister operand(m_graph.block(0)->variablesAtHead.operandForIndex(i));
+            
+            SSACalculator::Variable* variable = ssaCalculator.newVariable();
+            operandToVariable.operand(operand) = variable;
+            ASSERT(indexToOperand.size() == variable->index());
+            indexToOperand.append(operand);
+        }
+        
+        HashSet<Node*> putLocalsToSink;
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case PutStack:
+                    putLocalsToSink.add(node);
+                    ssaCalculator.newDef(
+                        operandToVariable.operand(node->stackAccessData()->local),
+                        block, node->child1().node());
+                    break;
+                case GetStack:
+                    ssaCalculator.newDef(
+                        operandToVariable.operand(node->stackAccessData()->local),
+                        block, node);
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        
+        ssaCalculator.computePhis(
+            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
+                VirtualRegister operand = indexToOperand[variable->index()];
+                
+                if (!liveAtHead[block].operand(operand))
+                    return nullptr;
+                
+                FlushFormat format = deferredAtHead[block].operand(operand);
+
+                // We could have an invalid deferral because liveness is imprecise.
+                if (!isConcrete(format))
+                    return nullptr;
+
+                if (verbose)
+                    dataLog("Adding Phi for ", operand, " at ", pointerDump(block), "\n");
+                
+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
+                phiNode->mergeFlags(resultFor(format));
+                return phiNode;
+            });
+        
+        Operands<Node*> mapping(OperandsLike, m_graph.block(0)->variablesAtHead);
+        Operands<FlushFormat> deferred;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            mapping.fill(nullptr);
+            
+            for (size_t i = mapping.size(); i--;) {
+                VirtualRegister operand(mapping.operandForIndex(i));
+                
+                SSACalculator::Variable* variable = operandToVariable.operand(operand);
+                SSACalculator::Def* def = ssaCalculator.reachingDefAtHead(block, variable);
+                if (!def)
+                    continue;
+                
+                mapping.operand(operand) = def->value();
+            }
+            
+            if (verbose)
+                dataLog("Mapping at top of ", pointerDump(block), ": ", mapping, "\n");
+            
+            for (SSACalculator::Def* phiDef : ssaCalculator.phisForBlock(block)) {
+                VirtualRegister operand = indexToOperand[phiDef->variable()->index()];
+                
+                insertionSet.insert(0, phiDef->value());
+                
+                if (verbose)
+                    dataLog("   Mapping ", operand, " to ", phiDef->value(), "\n");
+                mapping.operand(operand) = phiDef->value();
+            }
+            
+            deferred = deferredAtHead[block];
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                if (verbose)
+                    dataLog("Deferred at ", node, ":", deferred, "\n");
+                
+                switch (node->op()) {
+                case PutStack: {
+                    StackAccessData* data = node->stackAccessData();
+                    VirtualRegister operand = data->local;
+                    deferred.operand(operand) = data->format;
+                    if (verbose)
+                        dataLog("   Mapping ", operand, " to ", node->child1().node(), " at ", node, "\n");
+                    mapping.operand(operand) = node->child1().node();
+                    break;
+                }
+                    
+                case GetStack: {
+                    StackAccessData* data = node->stackAccessData();
+                    FlushFormat format = deferred.operand(data->local);
+                    if (!isConcrete(format)) {
+                        // This means there is no deferral. No deferral means that the most
+                        // authoritative value for this stack slot is what is stored in the stack. So,
+                        // keep the GetStack.
+                        mapping.operand(data->local) = node;
+                        break;
+                    }
+                    
+                    // We have a concrete deferral, which means a PutStack that hasn't executed yet. It
+                    // would have stored a value with a certain format. That format must match our
+                    // format. But more importantly, we can simply use the value that the PutStack would
+                    // have stored and get rid of the GetStack.
+                    DFG_ASSERT(m_graph, node, format == data->format);
+                    
+                    Node* incoming = mapping.operand(data->local);
+                    node->child1() = incoming->defaultEdge();
+                    node->convertToIdentity();
+                    break;
+                }
+                
+                default: {
+                    auto escapeHandler = [&] (VirtualRegister operand) {
+                        if (operand.isHeader())
+                            return;
+                    
+                        FlushFormat format = deferred.operand(operand);
+                        if (!isConcrete(format))
+                            return;
+                    
+                        // Gotta insert a PutStack.
+                        if (verbose)
+                            dataLog("Inserting a PutStack for ", operand, " at ", node, "\n");
+
+                        Node* incoming = mapping.operand(operand);
+                        DFG_ASSERT(m_graph, node, incoming);
+                    
+                        insertionSet.insertNode(
+                            nodeIndex, SpecNone, PutStack, node->origin,
+                            OpInfo(m_graph.m_stackAccessData.add(operand, format)),
+                            Edge(incoming, useKindFor(format)));
+                    
+                        deferred.operand(operand) = DeadFlush;
+                    };
+                
+                    preciseLocalClobberize(
+                        m_graph, node, escapeHandler, escapeHandler,
+                        [&] (VirtualRegister, LazyNode) { });
+                    break;
+                } }
+            }
+            
+            NodeAndIndex terminal = block->findTerminal();
+            size_t upsilonInsertionPoint = terminal.index;
+            NodeOrigin upsilonOrigin = terminal.node->origin;
+            for (BasicBlock* successorBlock : block->successors()) {
+                for (SSACalculator::Def* phiDef : ssaCalculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef->value();
+                    SSACalculator::Variable* variable = phiDef->variable();
+                    VirtualRegister operand = indexToOperand[variable->index()];
+                    if (verbose)
+                        dataLog("Creating Upsilon for ", operand, " at ", pointerDump(block), "->", pointerDump(successorBlock), "\n");
+                    FlushFormat format = deferredAtHead[successorBlock].operand(operand);
+                    DFG_ASSERT(m_graph, nullptr, isConcrete(format));
+                    UseKind useKind = useKindFor(format);
+                    
+                    // We need to get a value for the stack slot. This phase doesn't really have a
+                    // good way of determining if a stack location got clobbered. It just knows if
+                    // there is a deferral. The lack of a deferral might mean that a PutStack or
+                    // GetStack had never happened, or it might mean that the value was read, or
+                    // that it was written. It's OK for us to make some bad decisions here, since
+                    // GCSE will clean it up anyway.
+                    Node* incoming;
+                    if (isConcrete(deferred.operand(operand))) {
+                        incoming = mapping.operand(operand);
+                        DFG_ASSERT(m_graph, phiNode, incoming);
+                    } else {
+                        // Issue a GetStack to get the value. This might introduce some redundancy
+                        // into the code, but if it's bad enough, GCSE will clean it up.
+                        incoming = insertionSet.insertNode(
+                            upsilonInsertionPoint, SpecNone, GetStack, upsilonOrigin,
+                            OpInfo(m_graph.m_stackAccessData.add(operand, format)));
+                        incoming->setResult(resultFor(format));
+                    }
+                    
+                    insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), Edge(incoming, useKind));
+                }
+            }
+            
+            insertionSet.execute(block);
+        }
+        
+        // Finally eliminate the sunken PutStacks by turning them into Checks. This keeps whatever
+        // type check they were doing. Also prepend KillStacks to them to ensure that we know that
+        // the relevant value was *not* stored to the stack.
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                
+                if (!putLocalsToSink.contains(node))
+                    continue;
+                
+                insertionSet.insertNode(
+                    nodeIndex, SpecNone, KillStack, node->origin, OpInfo(node->stackAccessData()->local.offset()));
+                node->remove();
+            }
+            
+            insertionSet.execute(block);
+        }
+        
+        if (verbose) {
+            dataLog("Graph after PutStack sinking:\n");
+            m_graph.dump();
+        }
+        
+        return true;
+    }
+};
+
+} // anonymous namespace
+    
+bool performPutStackSinking(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG PutStack Sinking Phase");
+    return runPhase<PutStackSinkingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGPutStackSinkingPhase.h b/dfg/DFGPutStackSinkingPhase.h
new file mode 100644 (file)
index 0000000..24bbb81
--- /dev/null
@@ -0,0 +1,46 @@
+ /*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGPutStackSinkingPhase_h
+#define DFGPutStackSinkingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Sinks PutStacks to the absolute latest point where they can possibly happen, which is usually
+// side-effects that may observe them. This eliminates PutStacks if it sinks them past the point of
+// their deaths.
+
+bool performPutStackSinking(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPutStackSinkingPhase_h
+
diff --git a/dfg/DFGResurrectionForValidationPhase.cpp b/dfg/DFGResurrectionForValidationPhase.cpp
deleted file mode 100644 (file)
index 710ad0f..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DFGResurrectionForValidationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlockInlines.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-class ResurrectionForValidationPhase : public Phase {
-public:
-    ResurrectionForValidationPhase(Graph& graph)
-        : Phase(graph, "resurrection for validation")
-    {
-    }
-    
-    bool run()
-    {
-        InsertionSet insertionSet(m_graph);
-        
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-
-            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
-                Node* node = block->at(nodeIndex);
-                if (!node->hasResult())
-                    continue;
-                insertionSet.insertNode(
-                    nodeIndex + 1, SpecNone, Phantom, node->origin, node->defaultEdge());
-            }
-            
-            insertionSet.execute(block);
-        }
-        
-        return true;
-    }
-};
-
-bool performResurrectionForValidation(Graph& graph)
-{
-    SamplingRegion samplingRegion("DFG Resurrection For Validation Phase");
-    return runPhase<ResurrectionForValidationPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/dfg/DFGResurrectionForValidationPhase.h b/dfg/DFGResurrectionForValidationPhase.h
deleted file mode 100644 (file)
index 64f3b2b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DFGResurrectionForValidationPhase_h
-#define DFGResurrectionForValidationPhase_h
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGCommon.h"
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Places a Phantom after every value-producing node, thereby disabling DCE from killing it.
-// This is useful for validating our OSR exit machinery by instituting the requirement that
-// any live-in-bytecode variable should be OSR-available. Without this phase, it's impossible
-// to make such an assertion because our DCE is more aggressive than the bytecode liveness
-// analysis.
-
-bool performResurrectionForValidation(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGResurrectionForValidationPhase_h
-
diff --git a/dfg/DFGSSACalculator.cpp b/dfg/DFGSSACalculator.cpp
new file mode 100644 (file)
index 0000000..263cd2a
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGSSACalculator.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBlockMapInlines.h"
+#include <wtf/CommaPrinter.h>
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace DFG {
+
+void SSACalculator::Variable::dump(PrintStream& out) const
+{
+    out.print("var", m_index);
+}
+
+void SSACalculator::Variable::dumpVerbose(PrintStream& out) const
+{
+    dump(out);
+    if (!m_blocksWithDefs.isEmpty()) {
+        out.print("(defs: ");
+        CommaPrinter comma;
+        for (BasicBlock* block : m_blocksWithDefs)
+            out.print(comma, *block);
+        out.print(")");
+    }
+}
+
+void SSACalculator::Def::dump(PrintStream& out) const
+{
+    out.print("def(", *m_variable, ", ", *m_block, ", ", m_value, ")");
+}
+
+SSACalculator::SSACalculator(Graph& graph)
+    : m_data(graph)
+    , m_graph(graph)
+{
+}
+
+SSACalculator::~SSACalculator()
+{
+}
+
+void SSACalculator::reset()
+{
+    m_variables.clear();
+    m_defs.clear();
+    m_phis.clear();
+    for (BlockIndex blockIndex = m_data.size(); blockIndex--;) {
+        m_data[blockIndex].m_defs.clear();
+        m_data[blockIndex].m_phis.clear();
+    }
+}
+
+SSACalculator::Variable* SSACalculator::newVariable()
+{
+    return &m_variables.alloc(Variable(m_variables.size()));
+}
+
+SSACalculator::Def* SSACalculator::newDef(Variable* variable, BasicBlock* block, Node* value)
+{
+    Def* def = m_defs.add(Def(variable, block, value));
+    auto result = m_data[block].m_defs.add(variable, def);
+    if (result.isNewEntry)
+        variable->m_blocksWithDefs.append(block);
+    else
+        result.iterator->value = def;
+    return def;
+}
+
+SSACalculator::Def* SSACalculator::nonLocalReachingDef(BasicBlock* block, Variable* variable)
+{
+    return reachingDefAtTail(m_graph.m_dominators.immediateDominatorOf(block), variable);
+}
+
+SSACalculator::Def* SSACalculator::reachingDefAtTail(BasicBlock* block, Variable* variable)
+{
+    for (; block; block = m_graph.m_dominators.immediateDominatorOf(block)) {
+        if (Def* def = m_data[block].m_defs.get(variable))
+            return def;
+    }
+    return nullptr;
+}
+
+void SSACalculator::dump(PrintStream& out) const
+{
+    out.print("<Variables: [");
+    CommaPrinter comma;
+    for (unsigned i = 0; i < m_variables.size(); ++i) {
+        out.print(comma);
+        m_variables[i].dumpVerbose(out);
+    }
+    out.print("], Defs: [");
+    comma = CommaPrinter();
+    for (Def* def : const_cast<SSACalculator*>(this)->m_defs)
+        out.print(comma, *def);
+    out.print("], Phis: [");
+    comma = CommaPrinter();
+    for (Def* def : const_cast<SSACalculator*>(this)->m_phis)
+        out.print(comma, *def);
+    out.print("], Block data: [");
+    comma = CommaPrinter();
+    for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+        BasicBlock* block = m_graph.block(blockIndex);
+        if (!block)
+            continue;
+        
+        out.print(comma, *block, "=>(");
+        out.print("Defs: {");
+        CommaPrinter innerComma;
+        for (auto entry : m_data[block].m_defs)
+            out.print(innerComma, *entry.key, "->", *entry.value);
+        out.print("}, Phis: {");
+        innerComma = CommaPrinter();
+        for (Def* def : m_data[block].m_phis)
+            out.print(innerComma, *def);
+        out.print("})");
+    }
+    out.print("]>");
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGSSACalculator.h b/dfg/DFGSSACalculator.h
new file mode 100644 (file)
index 0000000..4f4f865
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGSSACalculator_h
+#define DFGSSACalculator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGDominators.h"
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+// SSACalculator provides a reusable tool for using the Cytron, Ferrante, Rosen, Wegman, and
+// Zadeck "Efficiently Computing Static Single Assignment Form and the Control Dependence Graph"
+// (TOPLAS'91) algorithm for computing SSA. SSACalculator doesn't magically do everything for you
+// but it maintains the major data structures and handles most of the non-local reasoning. Here's
+// the workflow of using SSACalculator to execute this algorithm:
+//
+// 0) Create a fresh SSACalculator instance. You will need this instance only for as long as
+//    you're not yet done computing SSA.
+//
+// 1) Create an SSACalculator::Variable for every variable that you want to do Phi insertion
+//    on. SSACalculator::Variable::index() is a dense indexing of the Variables that you
+//    created, so you can easily use a Vector to map the SSACalculator::Variables to your
+//    variables.
+//
+// 2) Create a SSACalculator::Def for every assignment to those variables. A Def knows about the
+//    variable, the block, and the DFG::Node* that has the value being put into the variable.
+//    Note that creating a Def in block B for variable V if block B already has a def for variable
+//    V will overwrite the previous Def's DFG::Node* value. This enables you to create Defs by
+//    processing basic blocks in forward order. If a block has multiple Defs of a variable, this
+//    "just works" because each block will then remember the last Def of each variable.
+//
+// 3) Call SSACalculator::computePhis(). This takes a functor that will create the Phi nodes. The
+//    functor returns either the Phi node it created, or nullptr, if it chooses to prune. (As an
+//    aside, it's always sound not to prune, and the safest reason for pruning is liveness.) The
+//    computePhis() code will record the created Phi nodes as Defs, and it will separately record
+//    the list of Phis inserted at each block. It's OK for the functor you pass here to modify the
+//    DFG::Graph on the fly, but the easiest way to write this is to just create the Phi nodes by
+//    doing Graph::addNode() and return them. It's then best to insert all Phi nodes for a block
+//    in bulk as part of the pass you do below, in step (4).
+//
+// 4) Modify the graph to create the SSA data flow. For each block, this should:
+//
+//    4.0) Compute the set of reaching defs (aka available values) for each variable by calling
+//         SSACalculator::reachingDefAtHead() for each variable. Record this in a local table that
+//         will be incrementally updated as you proceed through the block in forward order in the
+//         next steps:
+//
+//         FIXME: It might be better to compute reaching defs for all live variables in one go, to
+//         avoid doing repeated dom tree traversals.
+//         https://bugs.webkit.org/show_bug.cgi?id=136610
+//
+//    4.1) Insert all of the Phi nodes for the block by using SSACalculator::phisForBlock(), and
+//         record those Phi nodes as being available values.
+//
+//    4.2) Process the block in forward order. For each load from a variable, replace it with the
+//         available SSA value for that variable. For each store, delete it and record the stored
+//         value as being available.
+//
+//         Note that you have two options of how to replace loads with SSA values. You can replace
+//         the load with an Identity node; this will end up working fairly naturally so long as
+//         you run GCSE after your phase. Or, you can replace all uses of the load with the SSA
+//         value yourself (using the Graph::performSubstitution() idiom), but that requires that
+//         your loop over basic blocks proceeds in the appropriate graph order, for example
+//         preorder.
+//
+//         FIXME: Make it easier to do this, that doesn't involve rerunning GCSE.
+//         https://bugs.webkit.org/show_bug.cgi?id=136639
+//
+//    4.3) Insert Upsilons for each Phi in each successor block. Use the available values table to
+//         decide the source value for each Phi's variable. Note that you could also use
+//         SSACalculator::reachingDefAtTail() instead of the available values table, though your
+//         local available values table is likely to be more efficient.
+//
+// The most obvious use of SSACalculator is for the CPS->SSA conversion itself, but it's meant to
+// also be used for SSA update and for things like the promotion of heap fields to local SSA
+// variables.
+
+class SSACalculator {
+public:
+    SSACalculator(Graph&);
+    ~SSACalculator();
+    
+    void reset();
+    
+    class Variable {
+    public:
+        unsigned index() const { return m_index; }
+        
+        void dump(PrintStream&) const;
+        void dumpVerbose(PrintStream&) const;
+        
+    private:
+        friend class SSACalculator;
+        
+        Variable()
+            : m_index(UINT_MAX)
+        {
+        }
+        
+        Variable(unsigned index)
+            : m_index(index)
+        {
+        }
+
+        BlockList m_blocksWithDefs;
+        unsigned m_index;
+    };
+    
+    class Def {
+    public:
+        Variable* variable() const { return m_variable; }
+        BasicBlock* block() const { return m_block; }
+        
+        Node* value() const { return m_value; }
+        
+        void dump(PrintStream&) const;
+        
+    private:
+        friend class SSACalculator;
+        
+        Def()
+            : m_variable(nullptr)
+            , m_block(nullptr)
+            , m_value(nullptr)
+        {
+        }
+        
+        Def(Variable* variable, BasicBlock* block, Node* value)
+            : m_variable(variable)
+            , m_block(block)
+            , m_value(value)
+        {
+        }
+        
+        Variable* m_variable;
+        BasicBlock* m_block;
+        Node* m_value;
+    };
+    
+    Variable* newVariable();
+    Def* newDef(Variable*, BasicBlock*, Node*);
+    
+    Variable* variable(unsigned index) { return &m_variables[index]; }
+    
+    // The PhiInsertionFunctor takes a Variable and a BasicBlock and either inserts a Phi and
+    // returns the Node for that Phi, or it decides that it's not worth it to insert a Phi at that
+    // block because of some additional pruning condition (typically liveness) and returns
+    // nullptr. If a non-null Node* is returned, a new Def is created, so that
+    // nonLocalReachingDef() will find it later. Note that it is generally always sound to not
+    // prune any Phis (that is, to always have the functor insert a Phi and never return nullptr).
+    template<typename PhiInsertionFunctor>
+    void computePhis(const PhiInsertionFunctor& functor)
+    {
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_dominators.isValid());
+        
+        for (Variable& variable : m_variables) {
+            m_graph.m_dominators.forAllBlocksInPrunedIteratedDominanceFrontierOf(
+                variable.m_blocksWithDefs,
+                [&] (BasicBlock* block) -> bool {
+                    Node* phiNode = functor(&variable, block);
+                    if (!phiNode)
+                        return false;
+                    
+                    BlockData& data = m_data[block];
+                    Def* phiDef = m_phis.add(Def(&variable, block, phiNode));
+                    data.m_phis.append(phiDef);
+                    
+                    // Note that it's possible to have a block that looks like this before SSA
+                    // conversion:
+                    //
+                    // label:
+                    //     print(x);
+                    //     ...
+                    //     x = 42;
+                    //     goto label;
+                    //
+                    // And it may look like this after SSA conversion:
+                    //
+                    // label:
+                    //     x1: Phi()
+                    //     ...
+                    //     Upsilon(42, ^x1)
+                    //     goto label;
+                    //
+                    // In this case, we will want to insert a Phi in this block, and the block
+                    // will already have a Def for the variable. When this happens, we don't want
+                    // the Phi to override the original Def, since the Phi is at the top, the
+                    // original Def in the m_defs table would have been at the bottom, and we want
+                    // m_defs to tell us about defs at tail.
+                    //
+                    // So, we rely on the fact that HashMap::add() does nothing if the key was
+                    // already present.
+                    data.m_defs.add(&variable, phiDef);
+                    return true;
+                });
+        }
+    }
+    
+    const Vector<Def*>& phisForBlock(BasicBlock* block)
+    {
+        return m_data[block].m_phis;
+    }
+    
+    // Ignores defs within the given block; it assumes that you've taken care of those
+    // yourself.
+    Def* nonLocalReachingDef(BasicBlock*, Variable*);
+    Def* reachingDefAtHead(BasicBlock* block, Variable* variable)
+    {
+        return nonLocalReachingDef(block, variable);
+    }
+    
+    // Considers the def within the given block, but only works at the tail of the block.
+    Def* reachingDefAtTail(BasicBlock*, Variable*);
+    
+    void dump(PrintStream&) const;
+    
+private:
+    SegmentedVector<Variable> m_variables;
+    Bag<Def> m_defs;
+    
+    Bag<Def> m_phis;
+    
+    struct BlockData {
+        HashMap<Variable*, Def*> m_defs;
+        Vector<Def*> m_phis;
+    };
+    
+    BlockMap<BlockData> m_data;
+    
+    Graph& m_graph;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGSSACalculator_h
+
index e194ea8139979ce2eae582ae7c166c5cdbd48883..6993bfcac58883e96788b292a4fd1c6f1aa32aea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
 #include "DFGPhase.h"
+#include "DFGSSACalculator.h"
+#include "DFGVariableAccessDataDump.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace DFG {
 
 class SSAConversionPhase : public Phase {
     static const bool verbose = false;
-    static const bool dumpGraph = false;
     
 public:
     SSAConversionPhase(Graph& graph)
         : Phase(graph, "SSA conversion")
+        , m_calculator(graph)
         , m_insertionSet(graph)
-        , m_changed(false)
     {
     }
     
@@ -52,338 +53,310 @@ public:
     {
         RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
         
-        if (dumpGraph) {
-            dataLog("Graph dump at top of SSA conversion:\n");
+        m_graph.clearReplacements();
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        
+        if (verbose) {
+            dataLog("Graph before SSA transformation:\n");
             m_graph.dump();
         }
+
+        // Create a SSACalculator::Variable for every root VariableAccessData.
+        for (VariableAccessData& variable : m_graph.m_variableAccessData) {
+            if (!variable.isRoot())
+                continue;
+            
+            SSACalculator::Variable* ssaVariable = m_calculator.newVariable();
+            ASSERT(ssaVariable->index() == m_variableForSSAIndex.size());
+            m_variableForSSAIndex.append(&variable);
+            m_ssaVariableForVariable.add(&variable, ssaVariable);
+        }
         
-        // Eliminate all duplicate or self-pointing Phi edges. This means that
-        // we transform:
-        //
-        // p: Phi(@n1, @n2, @n3)
-        //
-        // into:
-        //
-        // p: Phi(@x)
-        //
-        // if each @ni in {@n1, @n2, @n3} is either equal to @p to is equal
-        // to @x, for exactly one other @x. Additionally, trivial Phis (i.e.
-        // p: Phi(@x)) are forwarded, so that if have an edge to such @p, we
-        // replace it with @x. This loop does this for Phis only; later we do
-        // such forwarding for Phi references found in other nodes.
-        //
-        // See Aycock and Horspool in CC'00 for a better description of what
-        // we're doing here.
-        do {
-            m_changed = false;
-            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-                BasicBlock* block = m_graph.block(blockIndex);
-                if (!block)
-                    continue;
-                for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
-                    Node* phi = block->phis[phiIndex];
-                    if (phi->variableAccessData()->isCaptured())
-                        continue;
-                    forwardPhiChildren(phi);
-                    deduplicateChildren(phi);
-                }
-            }
-        } while (m_changed);
-        
-        // For each basic block, for each local live at the head of that block,
-        // figure out what node we should be referring to instead of that local.
-        // If it turns out to be a non-trivial Phi, make sure that we create an
-        // SSA Phi and Upsilons in predecessor blocks. We reuse
-        // BasicBlock::variablesAtHead for tracking which nodes to refer to.
-        Operands<bool> nonTrivialPhis(OperandsLike, m_graph.block(0)->variablesAtHead);
+        // Find all SetLocals and create Defs for them. We handle SetArgument by creating a
+        // GetLocal, and recording the flush format.
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
-
-            nonTrivialPhis.fill(false);
-            for (unsigned i = block->phis.size(); i--;) {
-                Node* phi = block->phis[i];
-                if (!phi->children.justOneChild())
-                    nonTrivialPhis.operand(phi->local()) = true;
-            }
-                
-            for (unsigned i = block->variablesAtHead.size(); i--;) {
-                Node* node = block->variablesAtHead[i];
-                if (!node)
+            
+            // Must process the block in forward direction because we want to see the last
+            // assignment for every local.
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                if (node->op() != SetLocal && node->op() != SetArgument)
                     continue;
                 
-                if (verbose)
-                    dataLog("At block #", blockIndex, " for operand r", block->variablesAtHead.operandForIndex(i), " have node ", node, "\n");
-                
                 VariableAccessData* variable = node->variableAccessData();
-                if (variable->isCaptured()) {
-                    // Poison this entry in variablesAtHead because we don't
-                    // want anyone to try to refer to it, if the variable is
-                    // captured.
-                    block->variablesAtHead[i] = 0;
-                    continue;
-                }
-                
-                switch (node->op()) {
-                case Phi:
-                case SetArgument:
-                    break;
-                case Flush:
-                case GetLocal:
-                case PhantomLocal:
-                    node = node->child1().node();
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
-                RELEASE_ASSERT(node->op() == Phi || node->op() == SetArgument);
-                
-                bool isFlushed = !!(node->flags() & NodeIsFlushed);
                 
-                if (node->op() == Phi) {
-                    if (!nonTrivialPhis.operand(node->local())) {
-                        Edge edge = node->children.justOneChild();
-                        ASSERT(edge);
-                        if (verbose)
-                            dataLog("    One child: ", edge, ", ", RawPointer(edge.node()), "\n");
-                        node = edge.node(); // It's something from a different basic block.
-                    } else {
-                        if (verbose)
-                            dataLog("    Non-trivial.\n");
-                        // It's a non-trivial Phi.
-                        FlushFormat format = variable->flushFormat();
-                        NodeFlags result = resultFor(format);
-                        UseKind useKind = useKindFor(format);
-                        
-                        node = m_insertionSet.insertNode(0, SpecNone, Phi, NodeOrigin());
-                        if (verbose)
-                            dataLog("    Inserted new node: ", node, "\n");
-                        node->mergeFlags(result);
-                        RELEASE_ASSERT((node->flags() & NodeResultMask) == result);
-                        
-                        for (unsigned j = block->predecessors.size(); j--;) {
-                            BasicBlock* predecessor = block->predecessors[j];
-                            predecessor->appendNonTerminal(
-                                m_graph, SpecNone, Upsilon, predecessor->last()->origin,
-                                OpInfo(node), Edge(predecessor->variablesAtTail[i], useKind));
-                        }
-                        
-                        if (isFlushed) {
-                            // Do nothing. For multiple reasons.
-                            
-                            // Reason #1: If the local is flushed then we don't need to bother
-                            // with a MovHint since every path to this point in the code will
-                            // have flushed the bytecode variable using a SetLocal and hence
-                            // the Availability::flushedAt() will agree, and that will be
-                            // sufficient for figuring out how to recover the variable's value.
-                            
-                            // Reason #2: If we had inserted a MovHint and the Phi function had
-                            // died (because the only user of the value was the "flush" - i.e.
-                            // some asynchronous runtime thingy) then the MovHint would turn
-                            // into a ZombieHint, which would fool us into thinking that the
-                            // variable is dead.
-                            
-                            // Reason #3: If we had inserted a MovHint then even if the Phi
-                            // stayed alive, we would still end up generating inefficient code
-                            // since we would be telling the OSR exit compiler to use some SSA
-                            // value for the bytecode variable rather than just telling it that
-                            // the value was already on the stack.
-                        } else {
-                            m_insertionSet.insertNode(
-                                0, SpecNone, MovHint, NodeOrigin(),
-                                OpInfo(variable->local().offset()), node->defaultEdge());
-                        }
-                    }
+                Node* childNode;
+                if (node->op() == SetLocal)
+                    childNode = node->child1().node();
+                else {
+                    ASSERT(node->op() == SetArgument);
+                    childNode = m_insertionSet.insertNode(
+                        nodeIndex, node->variableAccessData()->prediction(),
+                        GetStack, node->origin,
+                        OpInfo(m_graph.m_stackAccessData.add(variable->local(), variable->flushFormat())));
+                    if (!ASSERT_DISABLED)
+                        m_argumentGetters.add(childNode);
+                    m_argumentMapping.add(node, childNode);
                 }
                 
-                block->variablesAtHead[i] = node;
+                m_calculator.newDef(
+                    m_ssaVariableForVariable.get(variable), block, childNode);
             }
-
+            
             m_insertionSet.execute(block);
         }
         
+        // Decide where Phis are to be inserted. This creates the Phi's but doesn't insert them
+        // yet. We will later know where to insert them because SSACalculator is such a bro.
+        m_calculator.computePhis(
+            [&] (SSACalculator::Variable* ssaVariable, BasicBlock* block) -> Node* {
+                VariableAccessData* variable = m_variableForSSAIndex[ssaVariable->index()];
+                
+                // Prune by liveness. This doesn't buy us much other than compile times.
+                Node* headNode = block->variablesAtHead.operand(variable->local());
+                if (!headNode)
+                    return nullptr;
+
+                // There is the possibiltiy of "rebirths". The SSA calculator will already prune
+                // rebirths for the same VariableAccessData. But it will not be able to prune
+                // rebirths that arose from the same local variable number but a different
+                // VariableAccessData. We do that pruning here.
+                //
+                // Here's an example of a rebirth that this would catch:
+                //
+                //     var x;
+                //     if (foo) {
+                //         if (bar) {
+                //             x = 42;
+                //         } else {
+                //             x = 43;
+                //         }
+                //         print(x);
+                //         x = 44;
+                //     } else {
+                //         x = 45;
+                //     }
+                //     print(x); // Without this check, we'd have a Phi for x = 42|43 here.
+                //
+                // FIXME: Consider feeding local variable numbers, not VariableAccessData*'s, as
+                // the "variables" for SSACalculator. That would allow us to eliminate this
+                // special case.
+                // https://bugs.webkit.org/show_bug.cgi?id=136641
+                if (headNode->variableAccessData() != variable)
+                    return nullptr;
+                
+                Node* phiNode = m_graph.addNode(
+                    variable->prediction(), Phi, NodeOrigin());
+                FlushFormat format = variable->flushFormat();
+                NodeFlags result = resultFor(format);
+                phiNode->mergeFlags(result);
+                return phiNode;
+            });
+        
         if (verbose) {
-            dataLog("Variables at head after SSA Phi insertion:\n");
-            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-                BasicBlock* block = m_graph.block(blockIndex);
-                if (!block)
-                    continue;
-                dataLog("    ", *block, ": ", block->variablesAtHead, "\n");
-            }
+            dataLog("Computed Phis, about to transform the graph.\n");
+            dataLog("\n");
+            dataLog("Graph:\n");
+            m_graph.dump();
+            dataLog("\n");
+            dataLog("Mappings:\n");
+            for (unsigned i = 0; i < m_variableForSSAIndex.size(); ++i)
+                dataLog("    ", i, ": ", VariableAccessDataDump(m_graph, m_variableForSSAIndex[i]), "\n");
+            dataLog("\n");
+            dataLog("SSA calculator: ", m_calculator, "\n");
         }
         
-        // At this point variablesAtHead in each block refers to either:
+        // Do the bulk of the SSA conversion. For each block, this tracks the operand->Node
+        // mapping based on a combination of what the SSACalculator tells us, and us walking over
+        // the block in forward order. We use our own data structure, valueForOperand, for
+        // determining the local mapping, but we rely on SSACalculator for the non-local mapping.
         //
-        // 1) A new SSA phi in the current block.
-        // 2) A SetArgument, which will soon get converted into a GetArgument.
-        // 3) An old CPS phi in a different block.
+        // This does three things at once:
         //
-        // We don't have to do anything for (1) and (2), but we do need to
-        // do a replacement for (3).
-        
-        // Clear all replacements, since other phases may have used them.
-        m_graph.clearReplacements();
-        
-        if (dumpGraph) {
-            dataLog("Graph just before identifying replacements:\n");
-            m_graph.dump();
-        }
-        
-        // For all of the old CPS Phis, figure out what they correspond to in SSA.
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            if (verbose)
-                dataLog("Dealing with block #", blockIndex, "\n");
-            for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
-                Node* phi = block->phis[phiIndex];
-                if (verbose) {
-                    dataLog(
-                        "Considering ", phi, " (", RawPointer(phi), "), for r",
-                        phi->local(), ", and its replacement in ", *block, ", ",
-                        block->variablesAtHead.operand(phi->local()), "\n");
-                }
-                ASSERT(phi != block->variablesAtHead.operand(phi->local()));
-                phi->misc.replacement = block->variablesAtHead.operand(phi->local());
-            }
-        }
-        
-        // Now make sure that all variablesAtHead in each block points to the
-        // canonical SSA value. Prior to this, variablesAtHead[local] may point to
-        // an old CPS Phi in a different block.
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (size_t i = block->variablesAtHead.size(); i--;) {
-                Node* node = block->variablesAtHead[i];
-                if (!node)
-                    continue;
-                while (node->misc.replacement) {
-                    ASSERT(node != node->misc.replacement);
-                    node = node->misc.replacement;
+        // - Inserts the Phis in all of the places where they need to go. We've already created
+        //   them and they are accounted for in the SSACalculator's data structures, but we
+        //   haven't inserted them yet, mostly because we want to insert all of a block's Phis in
+        //   one go to amortize the cost of node insertion.
+        //
+        // - Create and insert Upsilons.
+        //
+        // - Convert all of the preexisting SSA nodes (other than the old CPS Phi nodes) into SSA
+        //   form by replacing as follows:
+        //
+        //   - MovHint has KillLocal prepended to it.
+        //
+        //   - GetLocal die and get replaced with references to the node specified by
+        //     valueForOperand.
+        //
+        //   - SetLocal turns into PutStack if it's flushed, or turns into a Check otherwise.
+        //
+        //   - Flush loses its children and turns into a Phantom.
+        //
+        //   - PhantomLocal becomes Phantom, and its child is whatever is specified by
+        //     valueForOperand.
+        //
+        //   - SetArgument is removed. Note that GetStack nodes have already been inserted.
+        Operands<Node*> valueForOperand(OperandsLike, m_graph.block(0)->variablesAtHead);
+        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
+            valueForOperand.clear();
+            
+            // CPS will claim that the root block has all arguments live. But we have already done
+            // the first step of SSA conversion: argument locals are no longer live at head;
+            // instead we have GetStack nodes for extracting the values of arguments. So, we
+            // skip the at-head available value calculation for the root block.
+            if (block != m_graph.block(0)) {
+                for (size_t i = valueForOperand.size(); i--;) {
+                    Node* nodeAtHead = block->variablesAtHead[i];
+                    if (!nodeAtHead)
+                        continue;
+                    
+                    VariableAccessData* variable = nodeAtHead->variableAccessData();
+                    
+                    if (verbose)
+                        dataLog("Considering live variable ", VariableAccessDataDump(m_graph, variable), " at head of block ", *block, "\n");
+                    
+                    SSACalculator::Variable* ssaVariable = m_ssaVariableForVariable.get(variable);
+                    SSACalculator::Def* def = m_calculator.reachingDefAtHead(block, ssaVariable);
+                    if (!def) {
+                        // If we are required to insert a Phi, then we won't have a reaching def
+                        // at head.
+                        continue;
+                    }
+                    
+                    Node* node = def->value();
+                    if (node->replacement()) {
+                        // This will occur when a SetLocal had a GetLocal as its source. The
+                        // GetLocal would get replaced with an actual SSA value by the time we get
+                        // here. Note that the SSA value with which the GetLocal got replaced
+                        // would not in turn have a replacement.
+                        node = node->replacement();
+                        ASSERT(!node->replacement());
+                    }
+                    if (verbose)
+                        dataLog("Mapping: ", VirtualRegister(valueForOperand.operandForIndex(i)), " -> ", node, "\n");
+                    valueForOperand[i] = node;
                 }
-                block->variablesAtHead[i] = node;
             }
-        }
-        
-        if (verbose) {
-            dataLog("Variables at head after convergence:\n");
-            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-                BasicBlock* block = m_graph.block(blockIndex);
-                if (!block)
-                    continue;
-                dataLog("    ", *block, ": ", block->variablesAtHead, "\n");
-            }
-        }
-        
-        // Convert operations over locals into operations over SSA nodes.
-        // - GetLocal over captured variables lose their phis.
-        // - GetLocal over uncaptured variables die and get replaced with references
-        //   to the node specified by variablesAtHead.
-        // - SetLocal gets NodeMustGenerate if it's flushed, or turns into a
-        //   Check otherwise.
-        // - Flush loses its children and turns into a Phantom.
-        // - PhantomLocal becomes Phantom, and its child is whatever is specified
-        //   by variablesAtHead.
-        // - SetArgument turns into GetArgument unless it's a captured variable.
-        // - Upsilons get their children fixed to refer to the true value of that local
-        //   at the end of the block. Prior to this loop, Upsilons will refer to
-        //   variableAtTail[operand], which may be any of Flush, PhantomLocal, GetLocal,
-        //   SetLocal, SetArgument, or Phi. We accomplish this by setting the
-        //   replacement pointers of all of those nodes to refer to either
-        //   variablesAtHead[operand], or the child of the SetLocal.
-        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
             
-            for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
-                block->phis[phiIndex]->misc.replacement =
-                    block->variablesAtHead.operand(block->phis[phiIndex]->local());
+            // Insert Phis by asking the calculator what phis there are in this block. Also update
+            // valueForOperand with those Phis. For Phis associated with variables that are not
+            // flushed, we also insert a MovHint.
+            size_t phiInsertionPoint = 0;
+            for (SSACalculator::Def* phiDef : m_calculator.phisForBlock(block)) {
+                VariableAccessData* variable = m_variableForSSAIndex[phiDef->variable()->index()];
+                
+                m_insertionSet.insert(phiInsertionPoint, phiDef->value());
+                valueForOperand.operand(variable->local()) = phiDef->value();
+                
+                m_insertionSet.insertNode(
+                    phiInsertionPoint, SpecNone, MovHint, NodeOrigin(),
+                    OpInfo(variable->local().offset()), phiDef->value()->defaultEdge());
             }
-            for (unsigned nodeIndex = block->size(); nodeIndex--;)
-                ASSERT(!block->at(nodeIndex)->misc.replacement);
             
             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
                 
+                if (verbose) {
+                    dataLog("Processing node ", node, ":\n");
+                    m_graph.dump(WTF::dataFile(), "    ", node);
+                }
+                
                 m_graph.performSubstitution(node);
                 
                 switch (node->op()) {
+                case MovHint: {
+                    m_insertionSet.insertNode(
+                        nodeIndex, SpecNone, KillStack, node->origin,
+                        OpInfo(node->unlinkedLocal().offset()));
+                    break;
+                }
+                    
                 case SetLocal: {
                     VariableAccessData* variable = node->variableAccessData();
-                    if (variable->isCaptured() || !!(node->flags() & NodeIsFlushed))
-                        node->mergeFlags(NodeMustGenerate);
-                    else
-                        node->setOpAndDefaultFlags(Check);
-                    node->misc.replacement = node->child1().node(); // Only for Upsilons.
+                    Node* child = node->child1().node();
+                    
+                    if (!!(node->flags() & NodeIsFlushed)) {
+                        node->convertToPutStack(
+                            m_graph.m_stackAccessData.add(
+                                variable->local(), variable->flushFormat()));
+                    } else
+                        node->remove();
+                    
+                    if (verbose)
+                        dataLog("Mapping: ", variable->local(), " -> ", child, "\n");
+                    valueForOperand.operand(variable->local()) = child;
+                    break;
+                }
+                    
+                case GetStack: {
+                    ASSERT(m_argumentGetters.contains(node));
+                    valueForOperand.operand(node->stackAccessData()->local) = node;
                     break;
                 }
                     
                 case GetLocal: {
-                    // It seems tempting to just do forwardPhi(GetLocal), except that we
-                    // could have created a new (SSA) Phi, and the GetLocal could still be
-                    // referring to an old (CPS) Phi. Uses variablesAtHead to tell us what
-                    // to refer to.
-                    node->children.reset();
                     VariableAccessData* variable = node->variableAccessData();
-                    if (variable->isCaptured())
-                        break;
-                    node->convertToPhantom();
-                    node->misc.replacement = block->variablesAtHead.operand(variable->local());
+                    node->children.reset();
+                    
+                    node->remove();
+                    if (verbose)
+                        dataLog("Replacing node ", node, " with ", valueForOperand.operand(variable->local()), "\n");
+                    node->setReplacement(valueForOperand.operand(variable->local()));
                     break;
                 }
                     
                 case Flush: {
                     node->children.reset();
-                    node->convertToPhantom();
-                    // This is only for Upsilons. An Upsilon will only refer to a Flush if
-                    // there were no SetLocals or GetLocals in the block.
-                    node->misc.replacement = block->variablesAtHead.operand(node->local());
+                    node->remove();
                     break;
                 }
                     
                 case PhantomLocal: {
                     ASSERT(node->child1().useKind() == UntypedUse);
                     VariableAccessData* variable = node->variableAccessData();
-                    if (variable->isCaptured()) {
-                        // This is a fun case. We could have a captured variable that had some
-                        // or all of its uses strength reduced to phantoms rather than flushes.
-                        // SSA conversion will currently still treat it as flushed, in the sense
-                        // that it will just keep the SetLocal. Therefore, there is nothing that
-                        // needs to be done here: we don't need to also keep the source value
-                        // alive. And even if we did want to keep the source value alive, we
-                        // wouldn't be able to, because the variablesAtHead value for a captured
-                        // local wouldn't have been computed by the Phi reduction algorithm
-                        // above.
-                        node->children.reset();
-                    } else {
-                        node->child1() =
-                            block->variablesAtHead.operand(variable->local())->defaultEdge();
-                    }
-                    node->convertToPhantom();
-                    // This is only for Upsilons. An Upsilon will only refer to a
-                    // PhantomLocal if there were no SetLocals or GetLocals in the block.
-                    node->misc.replacement = block->variablesAtHead.operand(variable->local());
+                    node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
+                    node->remove();
                     break;
                 }
                     
                 case SetArgument: {
-                    VariableAccessData* variable = node->variableAccessData();
-                    if (variable->isCaptured())
-                        break;
-                    node->setOpAndDefaultFlags(GetArgument);
-                    node->setResult(resultFor(node->variableAccessData()->flushFormat()));
+                    node->remove();
                     break;
                 }
-
+                    
                 default:
                     break;
                 }
             }
+            
+            // We want to insert Upsilons just before the end of the block. On the surface this
+            // seems dangerous because the Upsilon will have a checking UseKind. But, we will not
+            // actually be performing the check at the point of the Upsilon; the check will
+            // already have been performed at the point where the original SetLocal was.
+            NodeAndIndex terminal = block->findTerminal();
+            size_t upsilonInsertionPoint = terminal.index;
+            NodeOrigin upsilonOrigin = terminal.node->origin;
+            for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
+                BasicBlock* successorBlock = block->successor(successorIndex);
+                for (SSACalculator::Def* phiDef : m_calculator.phisForBlock(successorBlock)) {
+                    Node* phiNode = phiDef->value();
+                    SSACalculator::Variable* ssaVariable = phiDef->variable();
+                    VariableAccessData* variable = m_variableForSSAIndex[ssaVariable->index()];
+                    FlushFormat format = variable->flushFormat();
+                    UseKind useKind = useKindFor(format);
+                    
+                    m_insertionSet.insertNode(
+                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
+                        OpInfo(phiNode), Edge(
+                            valueForOperand.operand(variable->local()),
+                            useKind));
+                }
+            }
+            
+            m_insertionSet.execute(block);
         }
         
         // Free all CPS phis and reset variables vectors.
@@ -398,80 +371,39 @@ public:
             block->variablesAtTail.clear();
             block->valuesAtHead.clear();
             block->valuesAtHead.clear();
-            block->ssa = adoptPtr(new BasicBlock::SSAData(block));
+            block->ssa = std::make_unique<BasicBlock::SSAData>(block);
         }
         
-        m_graph.m_arguments.clear();
+        m_graph.m_argumentFormats.resize(m_graph.m_arguments.size());
+        for (unsigned i = m_graph.m_arguments.size(); i--;) {
+            FlushFormat format = FlushedJSValue;
+
+            Node* node = m_argumentMapping.get(m_graph.m_arguments[i]);
+            
+            RELEASE_ASSERT(node);
+            format = node->stackAccessData()->format;
+            
+            m_graph.m_argumentFormats[i] = format;
+            m_graph.m_arguments[i] = node; // Record the load that loads the arguments for the benefit of exit profiling.
+        }
         
         m_graph.m_form = SSA;
-        return true;
-    }
 
-private:
-    void forwardPhiChildren(Node* node)
-    {
-        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
-            Edge& edge = node->children.child(i);
-            if (!edge)
-                break;
-            m_changed |= forwardPhiEdge(edge);
-        }
-    }
-    
-    Node* forwardPhi(Node* node)
-    {
-        for (;;) {
-            switch (node->op()) {
-            case Phi: {
-                Edge edge = node->children.justOneChild();
-                if (!edge)
-                    return node;
-                node = edge.node();
-                break;
-            }
-            case GetLocal:
-            case SetLocal:
-                if (node->variableAccessData()->isCaptured())
-                    return node;
-                node = node->child1().node();
-                break;
-            default:
-                return node;
-            }
+        if (verbose) {
+            dataLog("Graph after SSA transformation:\n");
+            m_graph.dump();
         }
-    }
-    
-    bool forwardPhiEdge(Edge& edge)
-    {
-        Node* newNode = forwardPhi(edge.node());
-        if (newNode == edge.node())
-            return false;
-        edge.setNode(newNode);
+
         return true;
     }
-    
-    void deduplicateChildren(Node* node)
-    {
-        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
-            Edge edge = node->children.child(i);
-            if (!edge)
-                break;
-            if (edge == node) {
-                node->children.removeEdge(i--);
-                m_changed = true;
-                continue;
-            }
-            for (unsigned j = i + 1; j < AdjacencyList::Size; ++j) {
-                if (node->children.child(j) == edge) {
-                    node->children.removeEdge(j--);
-                    m_changed = true;
-                }
-            }
-        }
-    }
-    
+
+private:
+    SSACalculator m_calculator;
     InsertionSet m_insertionSet;
-    bool m_changed;
+    HashMap<VariableAccessData*, SSACalculator::Variable*> m_ssaVariableForVariable;
+    HashMap<Node*, Node*> m_argumentMapping;
+    HashSet<Node*> m_argumentGetters;
+    Vector<VariableAccessData*> m_variableForSSAIndex;
 };
 
 bool performSSAConversion(Graph& graph)
index 42b24e54ffc64140c01d6ae3013b4fe9b5e4f844..86c999d7082f5521853a2772684ab0d2acd6d5bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,10 +34,9 @@ class Graph;
 
 // Convert ThreadedCPS form into SSA form. This results in a form that has:
 //
-// - Roughly minimal Phi's. We use the Aycock & Horspool fixpoint for
-//   converting the CPS maximal Phis into SSA minimal Phis, with the caveat
-//   that irreducible control flow may result in some missed opportunities
-//   for Phi reduction.
+// - Minimal Phi's. We use the the Cytron et al (TOPLAS'91) algorithm for
+//   Phi insertion. Most of the algorithm is implemented in SSACalculator
+//   and Dominators.
 //
 // - No uses of GetLocal/SetLocal except for captured variables and flushes.
 //   After this, any remaining SetLocal means Flush. PhantomLocals become
index 993ec1b1ec4ef803d73450d46a18be7f48682ade..c4b67a36167657199d04b831377ba6be07c2d13d 100644 (file)
@@ -69,6 +69,7 @@ private:
     {
         switch (m_node->op()) {
         case GetByVal:
+        case HasIndexedProperty:
             lowerBoundsCheck(m_node->child1(), m_node->child2(), m_node->child3());
             break;
             
index 52bbfe4799f8df9f318df33b8eafa47e517fc929..953b54c21f739d07de4645db6b7475c1f07bae61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,9 +50,11 @@ public:
         case DoubleRepRealUse:
         case Int52RepUse:
         case NumberUse:
+        case RealNumberUse:
         case BooleanUse:
         case CellUse:
         case ObjectUse:
+        case FunctionUse:
         case FinalObjectUse:
         case ObjectOrOtherUse:
         case StringIdentUse:
@@ -111,18 +113,19 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-    case WeakJSConstant:
     case Identity:
     case ToThis:
     case CreateThis:
     case GetCallee:
+    case GetArgumentCount:
     case GetLocal:
     case SetLocal:
+    case PutStack:
+    case KillStack:
+    case GetStack:
     case MovHint:
     case ZombieHint:
-    case GetArgument:
     case Phantom:
-    case HardPhantom:
     case Upsilon:
     case Phi:
     case Flush:
@@ -139,6 +142,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case UInt32ToNumber:
     case DoubleAsInt32:
     case ArithAdd:
+    case ArithClz32:
     case ArithSub:
     case ArithNegate:
     case ArithMul:
@@ -148,10 +152,13 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case ArithAbs:
     case ArithMin:
     case ArithMax:
+    case ArithPow:
     case ArithSqrt:
     case ArithFRound:
+    case ArithRound:
     case ArithSin:
     case ArithCos:
+    case ArithLog:
     case ValueAdd:
     case GetById:
     case GetByIdFlush:
@@ -159,24 +166,21 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case PutByIdFlush:
     case PutByIdDirect:
     case CheckStructure:
-    case CheckExecutable:
+    case GetExecutable:
     case GetButterfly:
     case CheckArray:
     case Arrayify:
     case ArrayifyToStructure:
     case GetScope:
-    case GetMyScope:
-    case SkipTopScope:
     case SkipScope:
-    case GetClosureRegisters:
     case GetClosureVar:
     case PutClosureVar:
     case GetGlobalVar:
     case PutGlobalVar:
-    case VariableWatchpoint:
     case VarInjectionWatchpoint:
-    case CheckFunction:
-    case AllocationProfileWatchpoint:
+    case CheckCell:
+    case CheckBadCell:
+    case CheckNotEmpty:
     case RegExpExec:
     case RegExpTest:
     case CompareLess:
@@ -188,6 +192,11 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case CompareStrictEq:
     case Call:
     case Construct:
+    case CallVarargs:
+    case ConstructVarargs:
+    case LoadVarargs:
+    case CallForwardVarargs:
+    case ConstructForwardVarargs:
     case NewObject:
     case NewArray:
     case NewArrayWithSize:
@@ -196,6 +205,8 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case Breakpoint:
     case ProfileWillCall:
     case ProfileDidCall:
+    case ProfileType:
+    case ProfileControlFlow:
     case CheckHasInstance:
     case InstanceOf:
     case IsUndefined:
@@ -203,27 +214,23 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case IsNumber:
     case IsString:
     case IsObject:
+    case IsObjectOrNull:
     case IsFunction:
     case TypeOf:
     case LogicalNot:
     case ToPrimitive:
     case ToString:
+    case CallStringConstructor:
     case NewStringObject:
     case MakeRope:
     case In:
     case CreateActivation:
-    case TearOffActivation:
-    case CreateArguments:
-    case PhantomArguments:
-    case TearOffArguments:
-    case GetMyArgumentsLength:
-    case GetMyArgumentByVal:
-    case GetMyArgumentsLengthSafe:
-    case GetMyArgumentByValSafe:
-    case CheckArgumentsNotCreated:
-    case NewFunctionNoCheck:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+    case GetFromArguments:
+    case PutToArguments:
     case NewFunction:
-    case NewFunctionExpression:
     case Jump:
     case Branch:
     case Switch:
@@ -240,13 +247,11 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
     case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter:
     case LoopHint:
     case StoreBarrier:
-    case StoreBarrierWithNullCheck:
     case InvalidationPoint:
     case NotifyWrite:
-    case FunctionReentryWatchpoint:
-    case TypedArrayWatchpoint:
     case CheckInBounds:
     case ConstantStoragePointer:
     case Check:
@@ -257,8 +262,39 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case Int52Rep:
     case BooleanToNumber:
     case FiatInt52:
+    case GetGetter:
+    case GetSetter:
+    case GetEnumerableLength:
+    case HasGenericProperty:
+    case HasStructureProperty:
+    case HasIndexedProperty:
+    case GetDirectPname:
+    case GetPropertyEnumerator:
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname:
+    case ToIndexString:
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case PutHint:
+    case CheckStructureImmediate:
+    case MaterializeNewObject:
+    case MaterializeCreateActivation:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
         return true;
-        
+
+    case NativeCall:
+    case NativeConstruct:
+        return false; // TODO: add a check for already checked.  https://bugs.webkit.org/show_bug.cgi?id=133769
+
+    case BottomValue:
+        // If in doubt, assume that this isn't safe to execute, just because we have no way of
+        // compiling this node.
+        return false;
+
     case GetByVal:
     case GetIndexedPropertyStorage:
     case GetArrayLength:
@@ -277,21 +313,25 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
         return node->arrayMode().modeForPut().alreadyChecked(
             graph, node, state.forNode(graph.varArgChild(node, 0)));
 
-    case StructureTransitionWatchpoint:
-        return state.forNode(node->child1()).m_futurePossibleStructure.isSubsetOf(
-            StructureSet(node->structure()));
-        
     case PutStructure:
-    case PhantomPutStructure:
     case AllocatePropertyStorage:
     case ReallocatePropertyStorage:
-        return state.forNode(node->child1()).m_currentKnownStructure.isSubsetOf(
-            StructureSet(node->structureTransitionData().previousStructure));
+        return state.forNode(node->child1()).m_structure.isSubsetOf(
+            StructureSet(node->transition()->previous));
         
     case GetByOffset:
-    case PutByOffset:
-        return state.forNode(node->child1()).m_currentKnownStructure.isValidOffset(
-            graph.m_storageAccessData[node->storageAccessDataIndex()].offset);
+    case GetGetterSetterByOffset:
+    case PutByOffset: {
+        StructureAbstractValue& value = state.forNode(node->child1()).m_structure;
+        if (value.isTop())
+            return false;
+        PropertyOffset offset = node->storageAccessData().offset;
+        for (unsigned i = value.size(); i--;) {
+            if (!value[i]->isValidOffset(offset))
+                return false;
+        }
+        return true;
+    }
         
     case LastNodeType:
         RELEASE_ASSERT_NOT_REACHED();
index 15af609a9eebce8d2bdc2b0754c4d9b410d85f4c..c8795c8a448adda936873ce56a76ba4a065916f6 100644 (file)
@@ -55,21 +55,27 @@ public:
         assertClear();
     }
     
+    void sortFree()
+    {
+        std::sort(m_free.begin(), m_free.end());
+    }
+    
     void assertClear()
     {
-#if !ASSERT_DISABLED
+        if (ASSERT_DISABLED)
+            return;
+        
         // For every entry in the used list the use count of the virtual register should be zero, or max, due to it being a preserved local.
         for (size_t i = 0; i < m_used.size(); ++i)
-            ASSERT(!m_used[i] || m_used[i] == max());
+            RELEASE_ASSERT(!m_used[i] || m_used[i] == max());
         // For every entry in the free list, the use count should be zero.
         for (size_t i = 0; i < m_free.size(); ++i)
-            ASSERT(!m_used[m_free[i]]);
+            RELEASE_ASSERT(!m_used[m_free[i]]);
         // There must not be duplicates in the free list.
         for (size_t i = 0; i < m_free.size(); ++i) {
             for (size_t j = i + 1; j < m_free.size(); ++j)
-                ASSERT(m_free[i] != m_free[j]);
+                RELEASE_ASSERT(m_free[i] != m_free[j]);
         }
-#endif
     }
 
     VirtualRegister allocate()
index 4e87d4fd5118a7bfadd52bbf4bfa36be99d6eb35..add1a23f2c5b2b0b689f0c02ab115650aef809e7 100644 (file)
@@ -32,7 +32,6 @@
 #include "DFGSilentRegisterSavePlan.h"
 #include "DFGSpeculativeJIT.h"
 #include <wtf/FastMalloc.h>
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC { namespace DFG {
 
@@ -329,94 +328,77 @@ protected:
 };
 
 template<typename JumpType, typename FunctionType, typename ResultType>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndNoArgumentsSlowPathGenerator<
-            JumpType, FunctionType, ResultType>(
-                from, jit, function, spillMode, result));
+    return std::make_unique<CallResultAndNoArgumentsSlowPathGenerator<JumpType, FunctionType, ResultType>>(
+        from, jit, function, spillMode, result);
 }
 
 template<
     typename JumpType, typename FunctionType, typename ResultType,
     typename ArgumentType1>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, ArgumentType1 argument1,
     SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndOneArgumentSlowPathGenerator<
-            JumpType, FunctionType, ResultType, ArgumentType1>(
-                from, jit, function, spillMode, result, argument1));
+    return std::make_unique<CallResultAndOneArgumentSlowPathGenerator<JumpType, FunctionType, ResultType, ArgumentType1>>(
+        from, jit, function, spillMode, result, argument1);
 }
 
 template<
     typename JumpType, typename FunctionType, typename ResultType,
     typename ArgumentType1, typename ArgumentType2>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, ArgumentType1 argument1, ArgumentType2 argument2,
     SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndTwoArgumentsSlowPathGenerator<
-            JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2>(
-                from, jit, function, spillMode, result, argument1, argument2));
+    return std::make_unique<CallResultAndTwoArgumentsSlowPathGenerator<JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2>>(
+        from, jit, function, spillMode, result, argument1, argument2);
 }
 
 template<
     typename JumpType, typename FunctionType, typename ResultType,
     typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, ArgumentType1 argument1, ArgumentType2 argument2,
     ArgumentType3 argument3, SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndThreeArgumentsSlowPathGenerator<
-            JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
-            ArgumentType3>(
-                from, jit, function, spillMode, result, argument1, argument2,
-                argument3));
+    return std::make_unique<CallResultAndThreeArgumentsSlowPathGenerator<JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
+        ArgumentType3>>(from, jit, function, spillMode, result, argument1, argument2, argument3);
 }
 
 template<
     typename JumpType, typename FunctionType, typename ResultType,
     typename ArgumentType1, typename ArgumentType2, typename ArgumentType3,
     typename ArgumentType4>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, ArgumentType1 argument1, ArgumentType2 argument2,
     ArgumentType3 argument3, ArgumentType4 argument4,
     SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndFourArgumentsSlowPathGenerator<
-            JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
-            ArgumentType3, ArgumentType4>(
-                from, jit, function, spillMode, result, argument1, argument2,
-                argument3, argument4));
+    return std::make_unique<CallResultAndFourArgumentsSlowPathGenerator<JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
+        ArgumentType3, ArgumentType4>>(from, jit, function, spillMode, result, argument1, argument2, argument3, argument4);
 }
 
 template<
     typename JumpType, typename FunctionType, typename ResultType,
     typename ArgumentType1, typename ArgumentType2, typename ArgumentType3,
     typename ArgumentType4, typename ArgumentType5>
-inline PassOwnPtr<SlowPathGenerator> slowPathCall(
+inline std::unique_ptr<SlowPathGenerator> slowPathCall(
     JumpType from, SpeculativeJIT* jit, FunctionType function,
     ResultType result, ArgumentType1 argument1, ArgumentType2 argument2,
     ArgumentType3 argument3, ArgumentType4 argument4, ArgumentType5 argument5,
     SpillRegistersMode spillMode = NeedToSpill)
 {
-    return adoptPtr(
-        new CallResultAndFiveArgumentsSlowPathGenerator<
-            JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
-            ArgumentType3, ArgumentType4, ArgumentType5>(
-                from, jit, function, spillMode, result, argument1, argument2,
-                argument3, argument4, argument5));
+    return std::make_unique<CallResultAndFiveArgumentsSlowPathGenerator<JumpType, FunctionType, ResultType, ArgumentType1, ArgumentType2,
+        ArgumentType3, ArgumentType4, ArgumentType5>>(from, jit, function, spillMode, result, argument1, argument2, argument3,
+        argument4, argument5);
 }
 
 template<typename JumpType, typename DestinationType, typename SourceType, unsigned numberOfAssignments>
@@ -449,37 +431,31 @@ private:
 };
 
 template<typename JumpType, typename DestinationType, typename SourceType, unsigned numberOfAssignments>
-inline PassOwnPtr<SlowPathGenerator> slowPathMove(
+inline std::unique_ptr<SlowPathGenerator> slowPathMove(
     JumpType from, SpeculativeJIT* jit, SourceType source[numberOfAssignments], DestinationType destination[numberOfAssignments])
 {
-    return adoptPtr(
-        new AssigningSlowPathGenerator<
-            JumpType, DestinationType, SourceType, numberOfAssignments>(
-                from, jit, destination, source));
+    return std::make_unique<AssigningSlowPathGenerator<JumpType, DestinationType, SourceType, numberOfAssignments>>(
+        from, jit, destination, source);
 }
 
 template<typename JumpType, typename DestinationType, typename SourceType>
-inline PassOwnPtr<SlowPathGenerator> slowPathMove(
+inline std::unique_ptr<SlowPathGenerator> slowPathMove(
     JumpType from, SpeculativeJIT* jit, SourceType source, DestinationType destination)
 {
     SourceType sourceArray[1] = { source };
     DestinationType destinationArray[1] = { destination };
-    return adoptPtr(
-        new AssigningSlowPathGenerator<
-            JumpType, DestinationType, SourceType, 1>(
-                from, jit, destinationArray, sourceArray));
+    return std::make_unique<AssigningSlowPathGenerator<JumpType, DestinationType, SourceType, 1>>(
+        from, jit, destinationArray, sourceArray);
 }
 
 template<typename JumpType, typename DestinationType, typename SourceType>
-inline PassOwnPtr<SlowPathGenerator> slowPathMove(
+inline std::unique_ptr<SlowPathGenerator> slowPathMove(
     JumpType from, SpeculativeJIT* jit, SourceType source1, DestinationType destination1, SourceType source2, DestinationType destination2)
 {
     SourceType sourceArray[2] = { source1, source2 };
     DestinationType destinationArray[2] = { destination1, destination2 };
-    return adoptPtr(
-        new AssigningSlowPathGenerator<
-            JumpType, DestinationType, SourceType, 2>(
-                from, jit, destinationArray, sourceArray));
+    return std::make_unique<AssigningSlowPathGenerator<JumpType, DestinationType, SourceType, 2>>(
+        from, jit, destinationArray, sourceArray);
 }
 
 } } // namespace JSC::DFG
index 83b07e8fb63ec17d4752b91dac2b227cb8c05181..96449953241b30da7e1bffd7c82b3edcf9d48c32 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
+#include "BinarySwitch.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGArrayifySlowPathGenerator.h"
-#include "DFGBinarySwitch.h"
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
+#include "DFGCallCreateDirectArgumentsSlowPathGenerator.h"
+#include "DFGMayExit.h"
+#include "DFGOSRExitFuzz.h"
 #include "DFGSaneStringGetByValSlowPathGenerator.h"
 #include "DFGSlowPathGenerator.h"
-#include "LinkBuffer.h"
+#include "DirectArguments.h"
 #include "JSCInlines.h"
+#include "JSEnvironmentRecord.h"
+#include "JSLexicalEnvironment.h"
+#include "LinkBuffer.h"
+#include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
 #include "WriteBarrierBuffer.h"
 #include <wtf/MathExtras.h>
@@ -101,33 +107,88 @@ void SpeculativeJIT::emitAllocateJSArray(GPRReg resultGPR, Structure* structure,
     // I want a slow path that also loads out the storage pointer, and that's
     // what this custom CallArrayAllocatorSlowPathGenerator gives me. It's a lot
     // of work for a very small piece of functionality. :-/
-    addSlowPathGenerator(adoptPtr(
-        new CallArrayAllocatorSlowPathGenerator(
-            slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
-            structure, numElements)));
+    addSlowPathGenerator(std::make_unique<CallArrayAllocatorSlowPathGenerator>(
+        slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
+        structure, numElements));
 }
 
-void SpeculativeJIT::emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
+void SpeculativeJIT::emitGetLength(InlineCallFrame* inlineCallFrame, GPRReg lengthGPR, bool includeThis)
 {
-    Structure* structure = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)->argumentsStructure();
-    emitAllocateDestructibleObject<Arguments>(resultGPR, structure, scratchGPR1, scratchGPR2, slowPath);
-
-    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfActivation()));
+    if (inlineCallFrame && !inlineCallFrame->isVarargs())
+        m_jit.move(TrustedImm32(inlineCallFrame->arguments.size() - !includeThis), lengthGPR);
+    else {
+        VirtualRegister argumentCountRegister;
+        if (!inlineCallFrame)
+            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+        else
+            argumentCountRegister = inlineCallFrame->argumentCountRegister;
+        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
+        if (!includeThis)
+            m_jit.sub32(TrustedImm32(1), lengthGPR);
+    }
+}
 
-    m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
-    m_jit.sub32(TrustedImm32(1), scratchGPR1);
-    m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
+void SpeculativeJIT::emitGetLength(CodeOrigin origin, GPRReg lengthGPR, bool includeThis)
+{
+    emitGetLength(origin.inlineCallFrame, lengthGPR, includeThis);
+}
 
-    m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
-    if (m_jit.isStrictModeFor(m_currentNode->origin.semantic))
-        m_jit.store8(TrustedImm32(1), MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
+void SpeculativeJIT::emitGetCallee(CodeOrigin origin, GPRReg calleeGPR)
+{
+    if (origin.inlineCallFrame) {
+        if (origin.inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                JITCompiler::addressFor(origin.inlineCallFrame->calleeRecovery.virtualRegister()),
+                calleeGPR);
+        } else {
+            m_jit.move(
+                TrustedImmPtr(origin.inlineCallFrame->calleeRecovery.constant().asCell()),
+                calleeGPR);
+        }
+    } else
+        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), calleeGPR);
+}
 
-    m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
-    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisterArray()));
-    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfSlowArgumentData()));
+void SpeculativeJIT::emitGetArgumentStart(CodeOrigin origin, GPRReg startGPR)
+{
+    m_jit.addPtr(
+        TrustedImm32(
+            JITCompiler::argumentsStart(origin).offset() * static_cast<int>(sizeof(Register))),
+        GPRInfo::callFrameRegister, startGPR);
+}
 
-    m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratchGPR1);
-    m_jit.storePtr(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfCallee()));
+MacroAssembler::Jump SpeculativeJIT::emitOSRExitFuzzCheck()
+{
+    if (!doOSRExitFuzzing())
+        return MacroAssembler::Jump();
+    
+    MacroAssembler::Jump result;
+    
+    m_jit.pushToSave(GPRInfo::regT0);
+    m_jit.load32(&g_numberOfOSRExitFuzzChecks, GPRInfo::regT0);
+    m_jit.add32(TrustedImm32(1), GPRInfo::regT0);
+    m_jit.store32(GPRInfo::regT0, &g_numberOfOSRExitFuzzChecks);
+    unsigned atOrAfter = Options::fireOSRExitFuzzAtOrAfter();
+    unsigned at = Options::fireOSRExitFuzzAt();
+    if (at || atOrAfter) {
+        unsigned threshold;
+        MacroAssembler::RelationalCondition condition;
+        if (atOrAfter) {
+            threshold = atOrAfter;
+            condition = MacroAssembler::Below;
+        } else {
+            threshold = at;
+            condition = MacroAssembler::NotEqual;
+        }
+        MacroAssembler::Jump ok = m_jit.branch32(
+            condition, GPRInfo::regT0, MacroAssembler::TrustedImm32(threshold));
+        m_jit.popToRestore(GPRInfo::regT0);
+        result = m_jit.jump();
+        ok.link(&m_jit);
+    }
+    m_jit.popToRestore(GPRInfo::regT0);
+    
+    return result;
 }
 
 void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
@@ -135,7 +196,14 @@ void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource
     if (!m_compileOkay)
         return;
     ASSERT(m_isCheckingArgumentTypes || m_canExit);
-    m_jit.appendExitInfo(jumpToFail);
+    JITCompiler::Jump fuzzJump = emitOSRExitFuzzCheck();
+    if (fuzzJump.isSet()) {
+        JITCompiler::JumpList jumpsToFail;
+        jumpsToFail.append(fuzzJump);
+        jumpsToFail.append(jumpToFail);
+        m_jit.appendExitInfo(jumpsToFail);
+    } else
+        m_jit.appendExitInfo(jumpToFail);
     m_jit.jitCode()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
 }
 
@@ -144,7 +212,14 @@ void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource
     if (!m_compileOkay)
         return;
     ASSERT(m_isCheckingArgumentTypes || m_canExit);
-    m_jit.appendExitInfo(jumpsToFail);
+    JITCompiler::Jump fuzzJump = emitOSRExitFuzzCheck();
+    if (fuzzJump.isSet()) {
+        JITCompiler::JumpList myJumpsToFail;
+        myJumpsToFail.append(jumpsToFail);
+        myJumpsToFail.append(fuzzJump);
+        m_jit.appendExitInfo(myJumpsToFail);
+    } else
+        m_jit.appendExitInfo(jumpsToFail);
     m_jit.jitCode()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
 }
 
@@ -215,6 +290,8 @@ void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs js
         return;
     speculationCheck(kind, jsValueRegs, node, m_jit.jump());
     m_compileOkay = false;
+    if (verboseCompilationEnabled())
+        dataLog("Bailing compilation.\n");
 }
 
 void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
@@ -250,9 +327,9 @@ RegisterSet SpeculativeJIT::usedRegisters()
     return result;
 }
 
-void SpeculativeJIT::addSlowPathGenerator(PassOwnPtr<SlowPathGenerator> slowPathGenerator)
+void SpeculativeJIT::addSlowPathGenerator(std::unique_ptr<SlowPathGenerator> slowPathGenerator)
 {
-    m_slowPathGenerators.append(slowPathGenerator);
+    m_slowPathGenerators.append(WTF::move(slowPathGenerator));
 }
 
 void SpeculativeJIT::runSlowPathGenerators()
@@ -321,18 +398,20 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spil
         ASSERT(info.gpr() == source);
         ASSERT(isJSInt32(info.registerFormat()));
         if (node->hasConstant()) {
-            ASSERT(isInt32Constant(node));
+            ASSERT(node->isInt32Constant());
             fillAction = SetInt32Constant;
         } else
             fillAction = Load32Payload;
     } else if (registerFormat == DataFormatBoolean) {
 #if USE(JSVALUE64)
         RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         fillAction = DoNothingForFill;
+#endif
 #elif USE(JSVALUE32_64)
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            ASSERT(isBooleanConstant(node));
+            ASSERT(node->isBooleanConstant());
             fillAction = SetBooleanConstant;
         } else
             fillAction = Load32Payload;
@@ -340,8 +419,8 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spil
     } else if (registerFormat == DataFormatCell) {
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            JSValue value = valueOfJSConstant(node);
-            ASSERT_UNUSED(value, value.isCell());
+            DFG_ASSERT(m_jit.graph(), m_currentNode, node->isCellConstant());
+            node->asCell(); // To get the assertion.
             fillAction = SetCellConstant;
         } else {
 #if USE(JSVALUE64)
@@ -364,7 +443,9 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spil
             fillAction = Load64;
         else {
             RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
             fillAction = Load64; // Make GCC happy.
+#endif
         }
     } else if (registerFormat == DataFormatStrictInt52) {
         if (node->hasConstant())
@@ -377,15 +458,18 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spil
             fillAction = Load64;
         else {
             RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
             fillAction = Load64; // Make GCC happy.
+#endif
         }
     } else {
         ASSERT(registerFormat & DataFormatJS);
 #if USE(JSVALUE64)
         ASSERT(info.gpr() == source);
         if (node->hasConstant()) {
-            if (valueOfJSConstant(node).isCell())
+            if (node->isCellConstant())
                 fillAction = SetTrustedJSConstant;
+            else
                 fillAction = SetJSConstant;
         } else if (info.spillFormat() == DataFormatInt32) {
             ASSERT(registerFormat == DataFormatJSInt32);
@@ -443,7 +527,7 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForFPR(VirtualRegister spil
         
 #if USE(JSVALUE64)
     if (node->hasConstant()) {
-        ASSERT(isNumberConstant(node));
+        node->asNumber(); // To get the assertion.
         fillAction = SetDoubleConstant;
     } else {
         ASSERT(info.spillFormat() == DataFormatNone || info.spillFormat() == DataFormatDouble);
@@ -452,7 +536,7 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForFPR(VirtualRegister spil
 #elif USE(JSVALUE32_64)
     ASSERT(info.registerFormat() == DataFormatDouble);
     if (node->hasConstant()) {
-        ASSERT(isNumberConstant(node));
+        node->asNumber(); // To get the assertion.
         fillAction = SetDoubleConstant;
     } else
         fillAction = LoadDouble;
@@ -497,21 +581,21 @@ void SpeculativeJIT::silentFill(const SilentRegisterSavePlan& plan, GPRReg canTr
     case DoNothingForFill:
         break;
     case SetInt32Constant:
-        m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asInt32()), plan.gpr());
         break;
 #if USE(JSVALUE64)
     case SetInt52Constant:
-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt() << JSValue::int52ShiftAmount), plan.gpr());
+        m_jit.move(Imm64(plan.node()->asMachineInt() << JSValue::int52ShiftAmount), plan.gpr());
         break;
     case SetStrictInt52Constant:
-        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt()), plan.gpr());
+        m_jit.move(Imm64(plan.node()->asMachineInt()), plan.gpr());
         break;
 #endif // USE(JSVALUE64)
     case SetBooleanConstant:
-        m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr());
+        m_jit.move(TrustedImm32(plan.node()->asBoolean()), plan.gpr());
         break;
     case SetCellConstant:
-        m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.node()).asCell()), plan.gpr());
+        m_jit.move(TrustedImmPtr(plan.node()->asCell()), plan.gpr());
         break;
 #if USE(JSVALUE64)
     case SetTrustedJSConstant:
@@ -521,7 +605,7 @@ void SpeculativeJIT::silentFill(const SilentRegisterSavePlan& plan, GPRReg canTr
         m_jit.move(valueOfJSConstantAsImm64(plan.node()), plan.gpr());
         break;
     case SetDoubleConstant:
-        m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.node()))), canTrample);
+        m_jit.move(Imm64(reinterpretDoubleToInt64(plan.node()->asNumber())), canTrample);
         m_jit.move64ToDouble(canTrample, plan.fpr());
         break;
     case Load32PayloadBoxInt:
@@ -539,10 +623,10 @@ void SpeculativeJIT::silentFill(const SilentRegisterSavePlan& plan, GPRReg canTr
         break;
 #else
     case SetJSConstantTag:
-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).tag()), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asJSValue().tag()), plan.gpr());
         break;
     case SetJSConstantPayload:
-        m_jit.move(Imm32(valueOfJSConstant(plan.node()).payload()), plan.gpr());
+        m_jit.move(Imm32(plan.node()->asJSValue().payload()), plan.gpr());
         break;
     case SetInt32Tag:
         m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
@@ -554,7 +638,7 @@ void SpeculativeJIT::silentFill(const SilentRegisterSavePlan& plan, GPRReg canTr
         m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
         break;
     case SetDoubleConstant:
-        m_jit.loadDouble(TrustedImmPtr(addressOfDoubleConstant(plan.node())), plan.fpr());
+        m_jit.loadDouble(TrustedImmPtr(m_jit.addressOfDoubleConstant(plan.node())), plan.fpr());
         break;
 #endif
     case Load32Tag:
@@ -592,8 +676,10 @@ JITCompiler::Jump SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, A
     switch (arrayMode.arrayClass()) {
     case Array::OriginalArray: {
         CRASH();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         JITCompiler::Jump result; // I already know that VC++ takes unkindly to the expression "return Jump()", so I'm doing it this way in anticipation of someone eventually using VC++ to compile the DFG.
         return result;
+#endif
     }
         
     case Array::Array:
@@ -707,21 +793,18 @@ void SpeculativeJIT::checkArray(Node* node)
         noResult(m_currentNode);
         return;
     }
-    case Array::Arguments:
-        speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node,
-            m_jit.branch8(
-                MacroAssembler::NotEqual,
-                MacroAssembler::Address(baseReg, JSCell::typeInfoTypeOffset()),
-                MacroAssembler::TrustedImm32(ArgumentsType)));
-
+    case Array::DirectArguments:
+        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, DirectArgumentsType);
+        noResult(m_currentNode);
+        return;
+    case Array::ScopedArguments:
+        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ScopedArgumentsType);
         noResult(m_currentNode);
         return;
     default:
-        speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node,
-            m_jit.branch8(
-                MacroAssembler::NotEqual,
-                MacroAssembler::Address(baseReg, JSCell::typeInfoTypeOffset()),
-                MacroAssembler::TrustedImm32(typeForTypedArrayType(node->arrayMode().typedArrayType()))));
+        speculateCellTypeWithoutTypeFiltering(
+            node->child1(), baseReg,
+            typeForTypedArrayType(node->arrayMode().typedArrayType()));
         noResult(m_currentNode);
         return;
     }
@@ -771,8 +854,8 @@ void SpeculativeJIT::arrayify(Node* node, GPRReg baseReg, GPRReg propertyReg)
         slowPath.append(jumpSlowForUnwantedArrayMode(tempGPR, node->arrayMode()));
     }
     
-    addSlowPathGenerator(adoptPtr(new ArrayifySlowPathGenerator(
-        slowPath, this, node, baseReg, propertyReg, tempGPR, structureGPR)));
+    addSlowPathGenerator(std::make_unique<ArrayifySlowPathGenerator>(
+        slowPath, this, node, baseReg, propertyReg, tempGPR, structureGPR));
     
     noResult(m_currentNode);
 }
@@ -856,12 +939,9 @@ void SpeculativeJIT::compileIn(Node* node)
 {
     SpeculateCellOperand base(this, node->child2());
     GPRReg baseGPR = base.gpr();
-        
-    if (isConstant(node->child1().node())) {
-        JSString* string =
-            jsDynamicCast<JSString*>(valueOfJSConstant(node->child1().node()));
-        if (string && string->tryGetValueImpl()
-            && string->tryGetValueImpl()->isAtomic()) {
+    
+    if (JSString* string = node->child1()->dynamicCastConstant<JSString*>()) {
+        if (string->tryGetValueImpl() && string->tryGetValueImpl()->isAtomic()) {
             StructureStubInfo* stubInfo = m_jit.codeBlock()->addStubInfo();
             
             GPRTemporary result(this);
@@ -872,31 +952,33 @@ void SpeculativeJIT::compileIn(Node* node)
             MacroAssembler::PatchableJump jump = m_jit.patchableJump();
             MacroAssembler::Label done = m_jit.label();
             
-            OwnPtr<SlowPathGenerator> slowPath = slowPathCall(
+            // Since this block is executed only when the result of string->tryGetValueImpl() is atomic,
+            // we can cast it to const AtomicStringImpl* safely.
+            auto slowPath = slowPathCall(
                 jump.m_jump, this, operationInOptimize,
                 JSValueRegs::payloadOnly(resultGPR), stubInfo, baseGPR,
-                string->tryGetValueImpl());
+                static_cast<const AtomicStringImpl*>(string->tryGetValueImpl()));
             
             stubInfo->codeOrigin = node->origin.semantic;
             stubInfo->patch.baseGPR = static_cast<int8_t>(baseGPR);
             stubInfo->patch.valueGPR = static_cast<int8_t>(resultGPR);
             stubInfo->patch.usedRegisters = usedRegisters();
             stubInfo->patch.spillMode = NeedToSpill;
-            
+
             m_jit.addIn(InRecord(jump, done, slowPath.get(), stubInfo));
-            addSlowPathGenerator(slowPath.release());
-                
+            addSlowPathGenerator(WTF::move(slowPath));
+
             base.use();
-            
+
             blessedBooleanResult(resultGPR, node, UseChildrenCalledExplicitly);
             return;
         }
     }
-        
+
     JSValueOperand key(this, node->child1());
     JSValueRegs regs = key.jsValueRegs();
         
-    GPRResult result(this);
+    GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
         
     base.use();
@@ -1151,33 +1233,17 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node* node, Node* branchNode)
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
             speculationCheck(
-                BadType, JSValueSource::unboxedCell(op1GPR), node->child1(), 
-                m_jit.branchStructurePtr(
-                    MacroAssembler::Equal, 
-                    MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                    m_jit.vm()->stringStructure.get()));
+                BadType, JSValueSource::unboxedCell(op1GPR), node->child1(), m_jit.branchIfNotObject(op1GPR));
         }
         if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
             speculationCheck(
-                BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
-                m_jit.branchStructurePtr(
-                    MacroAssembler::Equal, 
-                    MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                    m_jit.vm()->stringStructure.get()));
+                BadType, JSValueSource::unboxedCell(op2GPR), node->child2(), m_jit.branchIfNotObject(op2GPR));
         }
     } else {
-        GPRTemporary structure(this);
-        GPRTemporary temp(this);
-        GPRReg structureGPR = structure.gpr();
-
-        m_jit.emitLoadStructure(op1GPR, structureGPR, temp.gpr());
         if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
             speculationCheck(
                 BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
-                m_jit.branchPtr(
-                    MacroAssembler::Equal, 
-                    structureGPR, 
-                    MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+                m_jit.branchIfNotObject(op1GPR));
         }
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
             m_jit.branchTest8(
@@ -1185,14 +1251,10 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node* node, Node* branchNode)
                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
 
-        m_jit.emitLoadStructure(op2GPR, structureGPR, temp.gpr());
         if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
             speculationCheck(
                 BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
-                m_jit.branchPtr(
-                    MacroAssembler::Equal, 
-                    structureGPR, 
-                    MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+                m_jit.branchIfNotObject(op2GPR));
         }
         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
             m_jit.branchTest8(
@@ -1219,13 +1281,13 @@ void SpeculativeJIT::compilePeepHoleBooleanBranch(Node* node, Node* branchNode,
         notTaken = tmp;
     }
 
-    if (isBooleanConstant(node->child1().node())) {
-        bool imm = valueOfBooleanConstant(node->child1().node());
+    if (node->child1()->isBooleanConstant()) {
+        bool imm = node->child1()->asBoolean();
         SpeculateBooleanOperand op2(this, node->child2());
         branch32(condition, JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), op2.gpr(), taken);
-    } else if (isBooleanConstant(node->child2().node())) {
+    } else if (node->child2()->isBooleanConstant()) {
         SpeculateBooleanOperand op1(this, node->child1());
-        bool imm = valueOfBooleanConstant(node->child2().node());
+        bool imm = node->child2()->asBoolean();
         branch32(condition, op1.gpr(), JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), taken);
     } else {
         SpeculateBooleanOperand op1(this, node->child1());
@@ -1250,13 +1312,13 @@ void SpeculativeJIT::compilePeepHoleInt32Branch(Node* node, Node* branchNode, JI
         notTaken = tmp;
     }
 
-    if (isInt32Constant(node->child1().node())) {
-        int32_t imm = valueOfInt32Constant(node->child1().node());
+    if (node->child1()->isInt32Constant()) {
+        int32_t imm = node->child1()->asInt32();
         SpeculateInt32Operand op2(this, node->child2());
         branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
-    } else if (isInt32Constant(node->child2().node())) {
+    } else if (node->child2()->isInt32Constant()) {
         SpeculateInt32Operand op1(this, node->child1());
-        int32_t imm = valueOfInt32Constant(node->child2().node());
+        int32_t imm = node->child2()->asInt32();
         branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
     } else {
         SpeculateInt32Operand op1(this, node->child1());
@@ -1341,6 +1403,8 @@ void SpeculativeJIT::compileMovHint(Node* node)
 
 void SpeculativeJIT::bail(AbortReason reason)
 {
+    if (verboseCompilationEnabled())
+        dataLog("Bailing compilation.\n");
     m_compileOkay = true;
     m_jit.abortWithReason(reason, m_lastGeneratedNode);
     clearGenerationInfo();
@@ -1357,7 +1421,7 @@ void SpeculativeJIT::compileCurrentBlock()
     
     m_jit.blockHeads()[m_block->index] = m_jit.label();
 
-    if (!m_block->cfaHasVisited) {
+    if (!m_block->intersectionOfCFAHasVisited) {
         // Don't generate code for basic blocks that are unreachable according to CFA.
         // But to be sure that nobody has generated a jump to this block, drop in a
         // breakpoint here.
@@ -1404,72 +1468,44 @@ void SpeculativeJIT::compileCurrentBlock()
             bail(DFGBailedAtTopOfBlock);
             return;
         }
+
+        if (ASSERT_DISABLED)
+            m_canExit = true; // Essentially disable the assertions.
+        else
+            m_canExit = mayExit(m_jit.graph(), m_currentNode);
         
-        m_canExit = m_currentNode->canExit();
-        bool shouldExecuteEffects = m_interpreter.startExecuting(m_currentNode);
+        m_interpreter.startExecuting();
         m_jit.setForNode(m_currentNode);
         m_codeOriginForExitTarget = m_currentNode->origin.forExit;
         m_codeOriginForExitProfile = m_currentNode->origin.semantic;
         m_lastGeneratedNode = m_currentNode->op();
-        if (!m_currentNode->shouldGenerate()) {
-            switch (m_currentNode->op()) {
-            case JSConstant:
-                m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
-                break;
-                
-            case WeakJSConstant:
-                m_jit.addWeakReference(m_currentNode->weakConstant());
-                m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
-                break;
-                
-            case SetLocal:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
-                
-            case MovHint:
-                compileMovHint(m_currentNode);
-                break;
-                
-            case ZombieHint: {
-                recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
-                break;
-            }
-
-            default:
-                if (belongsInMinifiedGraph(m_currentNode->op()))
-                    m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
-                break;
-            }
-        } else {
-            
-            if (verboseCompilationEnabled()) {
-                dataLogF(
-                    "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x",
-                    (int)m_currentNode->index(),
-                    m_currentNode->origin.semantic.bytecodeIndex, m_jit.debugOffset());
-                dataLog("\n");
-            }
-            
-            compile(m_currentNode);
-
+        
+        ASSERT(m_currentNode->shouldGenerate());
+        
+        if (verboseCompilationEnabled()) {
+            dataLogF(
+                "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x",
+                (int)m_currentNode->index(),
+                m_currentNode->origin.semantic.bytecodeIndex, m_jit.debugOffset());
+            dataLog("\n");
+        }
+        
+        compile(m_currentNode);
+        
+        if (belongsInMinifiedGraph(m_currentNode->op()))
+            m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
+        
 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
-            m_jit.clearRegisterAllocationOffsets();
+        m_jit.clearRegisterAllocationOffsets();
 #endif
-
-            if (!m_compileOkay) {
-                bail(DFGBailedAtEndOfNode);
-                return;
-            }
-            
-            if (belongsInMinifiedGraph(m_currentNode->op())) {
-                m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
-                noticeOSRBirth(m_currentNode);
-            }
+        
+        if (!m_compileOkay) {
+            bail(DFGBailedAtEndOfNode);
+            return;
         }
         
         // Make sure that the abstract state is rematerialized for the next node.
-        if (shouldExecuteEffects)
-            m_interpreter.executeEffects(m_indexInBlock);
+        m_interpreter.executeEffects(m_indexInBlock);
     }
     
     // Perform the most basic verification that children have been used correctly.
@@ -1595,6 +1631,15 @@ void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
         m_jit.noticeOSREntry(*block, m_osrEntryHeads[osrEntryIndex++], linkBuffer);
     }
     ASSERT(osrEntryIndex == m_osrEntryHeads.size());
+    
+    if (verboseCompilationEnabled()) {
+        DumpContext dumpContext;
+        dataLog("OSR Entries:\n");
+        for (OSREntryData& entryData : m_jit.jitCode()->osrEntry)
+            dataLog("    ", inContext(entryData, &dumpContext), "\n");
+        if (!dumpContext.isEmpty())
+            dumpContext.dump(WTF::dataFile());
+    }
 }
 
 void SpeculativeJIT::compileDoublePutByVal(Node* node, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property)
@@ -1771,13 +1816,22 @@ void SpeculativeJIT::compileGetByValOnString(Node* node)
 
         JSGlobalObject* globalObject = m_jit.globalObjectFor(node->origin.semantic);
         if (globalObject->stringPrototypeChainIsSane()) {
+            // FIXME: This could be captured using a Speculation mode that means "out-of-bounds
+            // loads return a trivial value". Something like SaneChainOutOfBounds. This should
+            // speculate that we don't take negative out-of-bounds, or better yet, it should rely
+            // on a stringPrototypeChainIsSane() guaranteeing that the prototypes have no negative
+            // indexed properties either.
+            // https://bugs.webkit.org/show_bug.cgi?id=144668
+            m_jit.graph().watchpoints().addLazily(globalObject->stringPrototype()->structure()->transitionWatchpointSet());
+            m_jit.graph().watchpoints().addLazily(globalObject->objectPrototype()->structure()->transitionWatchpointSet());
+            
 #if USE(JSVALUE64)
-            addSlowPathGenerator(adoptPtr(new SaneStringGetByValSlowPathGenerator(
-                outOfBounds, this, JSValueRegs(scratchReg), baseReg, propertyReg)));
+            addSlowPathGenerator(std::make_unique<SaneStringGetByValSlowPathGenerator>(
+                outOfBounds, this, JSValueRegs(scratchReg), baseReg, propertyReg));
 #else
-            addSlowPathGenerator(adoptPtr(new SaneStringGetByValSlowPathGenerator(
+            addSlowPathGenerator(std::make_unique<SaneStringGetByValSlowPathGenerator>(
                 outOfBounds, this, JSValueRegs(resultTagReg, scratchReg),
-                baseReg, propertyReg)));
+                baseReg, propertyReg));
 #endif
         } else {
 #if USE(JSVALUE64)
@@ -1912,7 +1966,7 @@ void SpeculativeJIT::compileValueToInt32(Node* node)
                 JITCompiler::Jump isNumber = m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagTypeNumberRegister);
                 
                 DFG_TYPE_CHECK(
-                    JSValueRegs(gpr), node->child1(), ~SpecCell, branchIsCell(JSValueRegs(gpr)));
+                    JSValueRegs(gpr), node->child1(), ~SpecCell, m_jit.branchIfCell(JSValueRegs(gpr)));
                 
                 // It's not a cell: so true turns into 1 and all else turns into 0.
                 m_jit.compare64(JITCompiler::Equal, gpr, TrustedImm32(ValueTrue), resultGpr);
@@ -1968,7 +2022,7 @@ void SpeculativeJIT::compileValueToInt32(Node* node)
                     
                     DFG_TYPE_CHECK(
                         op1.jsValueRegs(), node->child1(), ~SpecCell,
-                        branchIsCell(op1.jsValueRegs()));
+                        m_jit.branchIfCell(op1.jsValueRegs()));
                     
                     // It's not a cell: so true turns into 1 and all else turns into 0.
                     JITCompiler::Jump isBoolean = m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::BooleanTag));
@@ -2070,31 +2124,89 @@ void SpeculativeJIT::compileDoubleAsInt32(Node* node)
 void SpeculativeJIT::compileDoubleRep(Node* node)
 {
     switch (node->child1().useKind()) {
-    case NumberUse: {
-        ASSERT(!isNumberConstant(node->child1().node())); // This should have been constant folded.
+    case RealNumberUse: {
+        JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
+        FPRTemporary result(this);
+        
+        JSValueRegs op1Regs = op1.jsValueRegs();
+        FPRReg resultFPR = result.fpr();
+        
+#if USE(JSVALUE64)
+        GPRTemporary temp(this);
+        GPRReg tempGPR = temp.gpr();
+        m_jit.move(op1Regs.gpr(), tempGPR);
+        m_jit.unboxDoubleWithoutAssertions(tempGPR, resultFPR);
+#else
+        FPRTemporary temp(this);
+        FPRReg tempFPR = temp.fpr();
+        unboxDouble(op1Regs.tagGPR(), op1Regs.payloadGPR(), resultFPR, tempFPR);
+#endif
+        
+        JITCompiler::Jump done = m_jit.branchDouble(
+            JITCompiler::DoubleEqual, resultFPR, resultFPR);
+        
+        DFG_TYPE_CHECK(
+            op1Regs, node->child1(), SpecBytecodeRealNumber, m_jit.branchIfNotInt32(op1Regs));
+        m_jit.convertInt32ToDouble(op1Regs.payloadGPR(), resultFPR);
+        
+        done.link(&m_jit);
+        
+        doubleResult(resultFPR, node);
+        return;
+    }
     
-        if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
+    case NotCellUse:
+    case NumberUse: {
+        ASSERT(!node->child1()->isNumberConstant()); // This should have been constant folded.
+
+        SpeculatedType possibleTypes = m_state.forNode(node->child1()).m_type;
+        if (isInt32Speculation(possibleTypes)) {
             SpeculateInt32Operand op1(this, node->child1(), ManualOperandSpeculation);
             FPRTemporary result(this);
             m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
             doubleResult(result.fpr(), node);
             return;
         }
-    
+
         JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
         FPRTemporary result(this);
-    
+
 #if USE(JSVALUE64)
         GPRTemporary temp(this);
 
         GPRReg op1GPR = op1.gpr();
         GPRReg tempGPR = temp.gpr();
         FPRReg resultFPR = result.fpr();
-    
+        JITCompiler::JumpList done;
+
         JITCompiler::Jump isInteger = m_jit.branch64(
             MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
-    
-        if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
+
+        if (node->child1().useKind() == NotCellUse) {
+            JITCompiler::Jump isNumber = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagTypeNumberRegister);
+            JITCompiler::Jump isUndefined = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueUndefined));
+
+            static const double zero = 0;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&zero), resultFPR);
+
+            JITCompiler::Jump isNull = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueNull));
+            done.append(isNull);
+
+            DFG_TYPE_CHECK(JSValueRegs(op1GPR), node->child1(), ~SpecCell,
+                m_jit.branchTest64(JITCompiler::NonZero, op1GPR, TrustedImm32(static_cast<int32_t>(~1))));
+
+            JITCompiler::Jump isFalse = m_jit.branch64(JITCompiler::Equal, op1GPR, TrustedImm64(ValueFalse));
+            static const double one = 1;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR);
+            done.append(isFalse);
+
+            isUndefined.link(&m_jit);
+            static const double NaN = PNaN;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&NaN), resultFPR);
+            done.append(m_jit.jump());
+
+            isNumber.link(&m_jit);
+        } else if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
             typeCheck(
                 JSValueRegs(op1GPR), node->child1(), SpecBytecodeNumber,
                 m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
@@ -2102,7 +2214,7 @@ void SpeculativeJIT::compileDoubleRep(Node* node)
     
         m_jit.move(op1GPR, tempGPR);
         unboxDouble(tempGPR, resultFPR);
-        JITCompiler::Jump done = m_jit.jump();
+        done.append(m_jit.jump());
     
         isInteger.link(&m_jit);
         m_jit.convertInt32ToDouble(op1GPR, resultFPR);
@@ -2114,18 +2226,42 @@ void SpeculativeJIT::compileDoubleRep(Node* node)
         GPRReg op1PayloadGPR = op1.payloadGPR();
         FPRReg tempFPR = temp.fpr();
         FPRReg resultFPR = result.fpr();
+        JITCompiler::JumpList done;
     
         JITCompiler::Jump isInteger = m_jit.branch32(
             MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
-    
-        if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
+
+        if (node->child1().useKind() == NotCellUse) {
+            JITCompiler::Jump isNumber = m_jit.branch32(JITCompiler::Below, op1TagGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
+            JITCompiler::Jump isUndefined = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::UndefinedTag));
+
+            static const double zero = 0;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&zero), resultFPR);
+
+            JITCompiler::Jump isNull = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::NullTag));
+            done.append(isNull);
+
+            DFG_TYPE_CHECK(JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), ~SpecCell, m_jit.branch32(JITCompiler::NotEqual, op1TagGPR, TrustedImm32(JSValue::BooleanTag)));
+
+            JITCompiler::Jump isFalse = m_jit.branchTest32(JITCompiler::Zero, op1PayloadGPR, TrustedImm32(1));
+            static const double one = 1;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&one), resultFPR);
+            done.append(isFalse);
+
+            isUndefined.link(&m_jit);
+            static const double NaN = PNaN;
+            m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&NaN), resultFPR);
+            done.append(m_jit.jump());
+
+            isNumber.link(&m_jit);
+        } else if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
             typeCheck(
                 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecBytecodeNumber,
                 m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
         }
-    
+
         unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
-        JITCompiler::Jump done = m_jit.jump();
+        done.append(m_jit.jump());
     
         isInteger.link(&m_jit);
         m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
@@ -2174,14 +2310,6 @@ void SpeculativeJIT::compileValueRep(Node* node)
         if (needsTypeCheck(node->child1(), ~SpecDoubleImpureNaN))
             m_jit.purifyNaN(valueFPR);
 
-#if CPU(X86)
-        // boxDouble() on X86 clobbers the source, so we need to copy.
-        // FIXME: Don't do that! https://bugs.webkit.org/show_bug.cgi?id=131690
-        FPRTemporary temp(this);
-        m_jit.moveDouble(valueFPR, temp.fpr());
-        valueFPR = temp.fpr();
-#endif
-        
         boxDouble(valueFPR, resultRegs);
         
         jsValueResult(resultRegs, node);
@@ -2265,10 +2393,12 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayOutOfBounds(Node* node, GPRRe
 {
     if (node->op() == PutByValAlias)
         return JITCompiler::Jump();
-    if (JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node)) {
+    JSArrayBufferView* view = m_jit.graph().tryGetFoldableView(
+        m_state.forNode(m_jit.graph().child(node, 0)).m_value, node->arrayMode());
+    if (view) {
         uint32_t length = view->length();
         Node* indexNode = m_jit.graph().child(node, 1).node();
-        if (m_jit.graph().isInt32Constant(indexNode) && static_cast<uint32_t>(m_jit.graph().valueOfInt32Constant(indexNode)) < length)
+        if (indexNode->isInt32Constant() && indexNode->asUInt32() < length)
             return JITCompiler::Jump();
         return m_jit.branch32(
             MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Imm32(length));
@@ -2307,13 +2437,13 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(Node* node, TypedArrayType t
     switch (elementSize(type)) {
     case 1:
         if (isSigned(type))
-            m_jit.load8Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
+            m_jit.load8SignedExtendTo32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
         else
             m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
         break;
     case 2:
         if (isSigned(type))
-            m_jit.load16Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
+            m_jit.load16SignedExtendTo32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
         else
             m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
         break;
@@ -2364,7 +2494,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(GPRReg base, GPRReg propert
     GPRReg valueGPR = InvalidGPRReg;
     
     if (valueUse->isConstant()) {
-        JSValue jsValue = valueOfJSConstant(valueUse.node());
+        JSValue jsValue = valueUse->asJSValue();
         if (!jsValue.isNumber()) {
             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
             noResult(node);
@@ -2564,7 +2694,7 @@ void SpeculativeJIT::compilePutByValForFloatTypedArray(GPRReg base, GPRReg prope
 void SpeculativeJIT::compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg, GPRReg scratch2Reg)
 {
     // Check that prototype is an object.
-    speculationCheck(BadType, JSValueRegs(), 0, m_jit.branchIfCellNotObject(prototypeReg));
+    speculationCheck(BadType, JSValueRegs(), 0, m_jit.branchIfNotObject(prototypeReg));
     
     // Initialize scratchReg with the value being checked.
     m_jit.move(valueReg, scratchReg);
@@ -2575,7 +2705,7 @@ void SpeculativeJIT::compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg p
     m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset() + CellPayloadOffset), scratchReg);
     MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
 #if USE(JSVALUE64)
-    branchIsCell(JSValueRegs(scratchReg)).linkTo(loop, &m_jit);
+    m_jit.branchIfCell(JSValueRegs(scratchReg)).linkTo(loop, &m_jit);
 #else
     m_jit.branchTestPtr(MacroAssembler::NonZero, scratchReg).linkTo(loop, &m_jit);
 #endif
@@ -2614,7 +2744,7 @@ void SpeculativeJIT::compileInstanceOf(Node* node)
         GPRReg scratchReg = scratch.gpr();
         GPRReg scratch2Reg = scratch2.gpr();
         
-        MacroAssembler::Jump isCell = branchIsCell(value.jsValueRegs());
+        MacroAssembler::Jump isCell = m_jit.branchIfCell(value.jsValueRegs());
         GPRReg valueReg = value.jsValueRegs().payloadGPR();
         moveFalseTo(scratchReg);
 
@@ -2652,8 +2782,8 @@ void SpeculativeJIT::compileAdd(Node* node)
     case Int32Use: {
         ASSERT(!shouldCheckNegativeZero(node->arithMode()));
         
-        if (isInt32Constant(node->child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node->child1().node());
+        if (node->child1()->isInt32Constant()) {
+            int32_t imm1 = node->child1()->asInt32();
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this);
 
@@ -2667,9 +2797,9 @@ void SpeculativeJIT::compileAdd(Node* node)
             return;
         }
         
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
-            int32_t imm2 = valueOfInt32Constant(node->child2().node());
+            int32_t imm2 = node->child2()->asInt32();
             GPRTemporary result(this);
                 
             if (!shouldCheckOverflow(node->arithMode())) {
@@ -2790,7 +2920,7 @@ void SpeculativeJIT::compileMakeRope(Node* node)
     GPRReg scratchGPR = scratch.gpr();
     
     JITCompiler::JumpList slowPath;
-    MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(JSRopeString));
+    MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
     m_jit.move(TrustedImmPtr(&markedAllocator), allocatorGPR);
     emitAllocateJSCell(resultGPR, allocatorGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()), scratchGPR, slowPath);
         
@@ -2842,15 +2972,26 @@ void SpeculativeJIT::compileMakeRope(Node* node)
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileArithClz32(Node* node)
+{
+    ASSERT_WITH_MESSAGE(node->child1().useKind() == Int32Use || node->child1().useKind() == KnownInt32Use, "The Fixup phase should have enforced a Int32 operand.");
+    SpeculateInt32Operand value(this, node->child1());
+    GPRTemporary result(this, Reuse, value);
+    GPRReg valueReg = value.gpr();
+    GPRReg resultReg = result.gpr();
+    m_jit.countLeadingZeros32(valueReg, resultReg);
+    int32Result(resultReg, node);
+}
+
 void SpeculativeJIT::compileArithSub(Node* node)
 {
     switch (node->binaryUseKind()) {
     case Int32Use: {
         ASSERT(!shouldCheckNegativeZero(node->arithMode()));
         
-        if (isNumberConstant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
-            int32_t imm2 = valueOfInt32Constant(node->child2().node());
+            int32_t imm2 = node->child2()->asInt32();
             GPRTemporary result(this);
 
             if (!shouldCheckOverflow(node->arithMode())) {
@@ -2865,8 +3006,8 @@ void SpeculativeJIT::compileArithSub(Node* node)
             return;
         }
             
-        if (isNumberConstant(node->child1().node())) {
-            int32_t imm1 = valueOfInt32Constant(node->child1().node());
+        if (node->child1()->isInt32Constant()) {
+            int32_t imm1 = node->child1()->asInt32();
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this);
                 
@@ -3220,7 +3361,7 @@ void SpeculativeJIT::compileArithDiv(Node* node)
         
         done.link(&m_jit);
         int32Result(eax.gpr(), node);
-#elif CPU(APPLE_ARMV7S) || CPU(ARM64)
+#elif HAVE(ARM_IDIV_INSTRUCTIONS) || CPU(ARM64)
         SpeculateInt32Operand op1(this, node->child1());
         SpeculateInt32Operand op2(this, node->child2());
         GPRReg op1GPR = op1.gpr();
@@ -3279,8 +3420,8 @@ void SpeculativeJIT::compileArithMod(Node* node)
         // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
         SpeculateStrictInt32Operand op1(this, node->child1());
         
-        if (isInt32Constant(node->child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node->child2().node());
+        if (node->child2()->isInt32Constant()) {
+            int32_t divisor = node->child2()->asInt32();
             if (divisor > 1 && hasOneBitSet(divisor)) {
                 unsigned logarithm = WTF::fastLog2(divisor);
                 GPRReg dividendGPR = op1.gpr();
@@ -3341,8 +3482,8 @@ void SpeculativeJIT::compileArithMod(Node* node)
         }
         
 #if CPU(X86) || CPU(X86_64)
-        if (isInt32Constant(node->child2().node())) {
-            int32_t divisor = valueOfInt32Constant(node->child2().node());
+        if (node->child2()->isInt32Constant()) {
+            int32_t divisor = node->child2()->asInt32();
             if (divisor && divisor != -1) {
                 GPRReg op1Gpr = op1.gpr();
 
@@ -3473,7 +3614,7 @@ void SpeculativeJIT::compileArithMod(Node* node)
         done.link(&m_jit);
         int32Result(edx.gpr(), node);
 
-#elif CPU(ARM64) || CPU(APPLE_ARMV7S)
+#elif HAVE(ARM_IDIV_INSTRUCTIONS) || CPU(ARM64)
         GPRTemporary temp(this);
         GPRTemporary quotientThenRemainder(this);
         GPRTemporary multiplyAnswer(this);
@@ -3498,7 +3639,7 @@ void SpeculativeJIT::compileArithMod(Node* node)
         // arithMode() == Arith::Unchecked?
         // https://bugs.webkit.org/show_bug.cgi?id=126444
         speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR));
-#if CPU(APPLE_ARMV7S)
+#if HAVE(ARM_IDIV_INSTRUCTIONS)
         m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
 #else
         m_jit.assembler().sub<32>(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
@@ -3545,6 +3686,160 @@ void SpeculativeJIT::compileArithMod(Node* node)
     }
 }
 
+void SpeculativeJIT::compileArithRound(Node* node)
+{
+    ASSERT(node->child1().useKind() == DoubleRepUse);
+
+    SpeculateDoubleOperand value(this, node->child1());
+    FPRReg valueFPR = value.fpr();
+
+    if (producesInteger(node->arithRoundingMode()) && !shouldCheckNegativeZero(node->arithRoundingMode())) {
+        FPRTemporary oneHalf(this);
+        GPRTemporary roundedResultAsInt32(this);
+        FPRReg oneHalfFPR = oneHalf.fpr();
+        GPRReg resultGPR = roundedResultAsInt32.gpr();
+
+        static const double halfConstant = 0.5;
+        m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), oneHalfFPR);
+        m_jit.addDouble(valueFPR, oneHalfFPR);
+
+        JITCompiler::Jump truncationFailed = m_jit.branchTruncateDoubleToInt32(oneHalfFPR, resultGPR);
+        speculationCheck(Overflow, JSValueRegs(), node, truncationFailed);
+        int32Result(resultGPR, node);
+        return;
+    }
+
+    flushRegisters();
+    FPRResult roundedResultAsDouble(this);
+    FPRReg resultFPR = roundedResultAsDouble.fpr();
+    callOperation(jsRound, resultFPR, valueFPR);
+    if (producesInteger(node->arithRoundingMode())) {
+        GPRTemporary roundedResultAsInt32(this);
+        FPRTemporary scratch(this);
+        FPRReg scratchFPR = scratch.fpr();
+        GPRReg resultGPR = roundedResultAsInt32.gpr();
+        JITCompiler::JumpList failureCases;
+        m_jit.branchConvertDoubleToInt32(resultFPR, resultGPR, failureCases, scratchFPR);
+        speculationCheck(Overflow, JSValueRegs(), node, failureCases);
+
+        int32Result(resultGPR, node);
+    } else
+        doubleResult(resultFPR, node);
+}
+
+void SpeculativeJIT::compileArithSqrt(Node* node)
+{
+    SpeculateDoubleOperand op1(this, node->child1());
+    FPRReg op1FPR = op1.fpr();
+
+    if (!MacroAssembler::supportsFloatingPointSqrt() || !Options::enableArchitectureSpecificOptimizations()) {
+        flushRegisters();
+        FPRResult result(this);
+        callOperation(sqrt, result.fpr(), op1FPR);
+        doubleResult(result.fpr(), node);
+    } else {
+        FPRTemporary result(this, op1);
+        m_jit.sqrtDouble(op1.fpr(), result.fpr());
+        doubleResult(result.fpr(), node);
+    }
+}
+
+// For small positive integers , it is worth doing a tiny inline loop to exponentiate the base.
+// Every register is clobbered by this helper.
+static MacroAssembler::Jump compileArithPowIntegerFastPath(JITCompiler& assembler, FPRReg xOperand, GPRReg yOperand, FPRReg result)
+{
+    MacroAssembler::JumpList skipFastPath;
+    skipFastPath.append(assembler.branch32(MacroAssembler::LessThan, yOperand, MacroAssembler::TrustedImm32(0)));
+    skipFastPath.append(assembler.branch32(MacroAssembler::GreaterThan, yOperand, MacroAssembler::TrustedImm32(1000)));
+
+    static const double oneConstant = 1.0;
+    assembler.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), result);
+
+    MacroAssembler::Label startLoop(assembler.label());
+    MacroAssembler::Jump exponentIsEven = assembler.branchTest32(MacroAssembler::Zero, yOperand, MacroAssembler::TrustedImm32(1));
+    assembler.mulDouble(xOperand, result);
+    exponentIsEven.link(&assembler);
+    assembler.mulDouble(xOperand, xOperand);
+    assembler.rshift32(MacroAssembler::TrustedImm32(1), yOperand);
+    assembler.branchTest32(MacroAssembler::NonZero, yOperand).linkTo(startLoop, &assembler);
+
+    MacroAssembler::Jump skipSlowPath = assembler.jump();
+    skipFastPath.link(&assembler);
+
+    return skipSlowPath;
+}
+
+void SpeculativeJIT::compileArithPow(Node* node)
+{
+    if (node->child2().useKind() == Int32Use) {
+        SpeculateDoubleOperand xOperand(this, node->child1());
+        SpeculateInt32Operand yOperand(this, node->child2());
+        FPRReg xOperandfpr = xOperand.fpr();
+        GPRReg yOperandGpr = yOperand.gpr();
+        FPRTemporary yOperandfpr(this);
+
+        flushRegisters();
+
+        FPRResult result(this);
+        FPRReg resultFpr = result.fpr();
+
+        FPRTemporary xOperandCopy(this);
+        FPRReg xOperandCopyFpr = xOperandCopy.fpr();
+        m_jit.moveDouble(xOperandfpr, xOperandCopyFpr);
+
+        GPRTemporary counter(this);
+        GPRReg counterGpr = counter.gpr();
+        m_jit.move(yOperandGpr, counterGpr);
+
+        MacroAssembler::Jump skipFallback = compileArithPowIntegerFastPath(m_jit, xOperandCopyFpr, counterGpr, resultFpr);
+        m_jit.convertInt32ToDouble(yOperandGpr, yOperandfpr.fpr());
+        callOperation(operationMathPow, resultFpr, xOperandfpr, yOperandfpr.fpr());
+
+        skipFallback.link(&m_jit);
+        doubleResult(resultFpr, node);
+        return;
+    }
+
+    SpeculateDoubleOperand xOperand(this, node->child1());
+    SpeculateDoubleOperand yOperand(this, node->child2());
+    FPRReg xOperandfpr = xOperand.fpr();
+    FPRReg yOperandfpr = yOperand.fpr();
+
+    flushRegisters();
+
+    FPRResult result(this);
+    FPRReg resultFpr = result.fpr();
+
+    FPRTemporary xOperandCopy(this);
+    FPRReg xOperandCopyFpr = xOperandCopy.fpr();
+
+    FPRTemporary scratch(this);
+    FPRReg scratchFpr = scratch.fpr();
+
+    GPRTemporary yOperandInteger(this);
+    GPRReg yOperandIntegerGpr = yOperandInteger.gpr();
+    MacroAssembler::JumpList failedExponentConversionToInteger;
+    m_jit.branchConvertDoubleToInt32(yOperandfpr, yOperandIntegerGpr, failedExponentConversionToInteger, scratchFpr, false);
+
+    m_jit.moveDouble(xOperandfpr, xOperandCopyFpr);
+    MacroAssembler::Jump skipFallback = compileArithPowIntegerFastPath(m_jit, xOperandCopyFpr, yOperandInteger.gpr(), resultFpr);
+    failedExponentConversionToInteger.link(&m_jit);
+
+    callOperation(operationMathPow, resultFpr, xOperandfpr, yOperandfpr);
+    skipFallback.link(&m_jit);
+    doubleResult(resultFpr, node);
+}
+
+void SpeculativeJIT::compileArithLog(Node* node)
+{
+    SpeculateDoubleOperand op1(this, node->child1());
+    FPRReg op1FPR = op1.fpr();
+    flushRegisters();
+    FPRResult result(this);
+    callOperation(log, result.fpr(), op1FPR);
+    doubleResult(result.fpr(), node);
+}
+
 // Returns true if the compare is fused with a subsequent branch.
 bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_JITOperation_EJJ operation)
 {
@@ -3678,6 +3973,36 @@ bool SpeculativeJIT::compileStrictEq(Node* node)
         return false;
     }
 
+    if (node->isBinaryUseKind(ObjectUse, UntypedUse)) {
+        unsigned branchIndexInBlock = detectPeepHoleBranch();
+        if (branchIndexInBlock != UINT_MAX) {
+            Node* branchNode = m_block->at(branchIndexInBlock);
+            compilePeepHoleObjectStrictEquality(node->child1(), node->child2(), branchNode);
+            use(node->child1());
+            use(node->child2());
+            m_indexInBlock = branchIndexInBlock;
+            m_currentNode = branchNode;
+            return true;
+        }
+        compileObjectStrictEquality(node->child1(), node->child2());
+        return false;
+    }
+    
+    if (node->isBinaryUseKind(UntypedUse, ObjectUse)) {
+        unsigned branchIndexInBlock = detectPeepHoleBranch();
+        if (branchIndexInBlock != UINT_MAX) {
+            Node* branchNode = m_block->at(branchIndexInBlock);
+            compilePeepHoleObjectStrictEquality(node->child2(), node->child1(), branchNode);
+            use(node->child1());
+            use(node->child2());
+            m_indexInBlock = branchIndexInBlock;
+            m_currentNode = branchNode;
+            return true;
+        }
+        compileObjectStrictEquality(node->child2(), node->child1());
+        return false;
+    }
+
     if (node->isBinaryUseKind(ObjectUse)) {
         unsigned branchIndexInBlock = detectPeepHoleBranch();
         if (branchIndexInBlock != UINT_MAX) {
@@ -3855,17 +4180,14 @@ void SpeculativeJIT::compileStringToUntypedEquality(Node* node, Edge stringEdge,
     JITCompiler::JumpList fastTrue;
     JITCompiler::JumpList fastFalse;
     
-    fastFalse.append(branchNotCell(rightRegs));
+    fastFalse.append(m_jit.branchIfNotCell(rightRegs));
     
     // It's safe to branch around the type check below, since proving that the values are
     // equal does indeed prove that the right value is a string.
     fastTrue.append(m_jit.branchPtr(
         MacroAssembler::Equal, leftGPR, rightRegs.payloadGPR()));
     
-    fastFalse.append(m_jit.branchStructurePtr(
-        MacroAssembler::NotEqual, 
-        MacroAssembler::Address(rightRegs.payloadGPR(), JSCell::structureIDOffset()), 
-        m_jit.vm()->stringStructure.get()));
+    fastFalse.append(m_jit.branchIfNotString(rightRegs.payloadGPR()));
     
     compileStringEquality(
         node, leftGPR, rightRegs.payloadGPR(), lengthGPR, leftTempGPR, rightTempGPR, leftTemp2GPR,
@@ -3912,11 +4234,8 @@ void SpeculativeJIT::compileStringIdentToNotStringVarEquality(
 
     moveFalseTo(rightTempGPR);
     JITCompiler::JumpList notString;
-    notString.append(branchNotCell(rightRegs));
-    notString.append(m_jit.branchStructurePtr(
-        MacroAssembler::NotEqual, 
-        MacroAssembler::Address(rightRegs.payloadGPR(), JSCell::structureIDOffset()), 
-        m_jit.vm()->stringStructure.get()));
+    notString.append(m_jit.branchIfNotCell(rightRegs));
+    notString.append(m_jit.branchIfNotString(rightRegs.payloadGPR()));
     
     speculateStringIdentAndLoadStorage(notStringVarEdge, rightRegs.payloadGPR(), rightTempGPR);
     
@@ -3943,6 +4262,15 @@ void SpeculativeJIT::compileStringZeroLength(Node* node)
     unblessedBooleanResult(eqGPR, node);
 }
 
+void SpeculativeJIT::emitStringBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
+{
+    SpeculateCellOperand str(this, nodeUse);
+    speculateString(nodeUse, str.gpr());
+    branchTest32(JITCompiler::NonZero, MacroAssembler::Address(str.gpr(), JSString::offsetOfLength()), taken);
+    jump(notTaken);
+    noResult(m_currentNode);
+}
+
 void SpeculativeJIT::compileConstantStoragePointer(Node* node)
 {
     GPRTemporary storage(this);
@@ -4013,7 +4341,7 @@ void SpeculativeJIT::compileGetTypedArrayByteOffset(Node* node)
     int32Result(vectorGPR, node);
 }
 
-void SpeculativeJIT::compileGetByValOnArguments(Node* node)
+void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node)
 {
     SpeculateCellOperand base(this, node->child1());
     SpeculateStrictInt32Operand property(this, node->child2());
@@ -4021,87 +4349,134 @@ void SpeculativeJIT::compileGetByValOnArguments(Node* node)
 #if USE(JSVALUE32_64)
     GPRTemporary resultTag(this);
 #endif
-    GPRTemporary scratch(this);
     
     GPRReg baseReg = base.gpr();
     GPRReg propertyReg = property.gpr();
     GPRReg resultReg = result.gpr();
 #if USE(JSVALUE32_64)
     GPRReg resultTagReg = resultTag.gpr();
+    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
+#else
+    JSValueRegs resultRegs = JSValueRegs(resultReg);
 #endif
-    GPRReg scratchReg = scratch.gpr();
     
     if (!m_compileOkay)
         return;
-  
-    ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     
-    // Two really lame checks.
-    speculationCheck(
-        Uncountable, JSValueSource(), 0,
-        m_jit.branch32(
-            MacroAssembler::AboveOrEqual, propertyReg,
-            MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
+    ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+    
     speculationCheck(
-        Uncountable, JSValueSource(), 0,
+        ExoticObjectMode, JSValueSource(), 0,
         m_jit.branchTestPtr(
             MacroAssembler::NonZero,
-            MacroAssembler::Address(
-                baseReg, Arguments::offsetOfSlowArgumentData())));
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
+    speculationCheck(
+        ExoticObjectMode, JSValueSource(), 0,
+        m_jit.branch32(
+            MacroAssembler::AboveOrEqual, propertyReg,
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength())));
     
-    m_jit.move(propertyReg, resultReg);
-    m_jit.signExtend32ToPtr(resultReg, resultReg);
-    m_jit.loadPtr(
-        MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
-        scratchReg);
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            baseReg, propertyReg, MacroAssembler::TimesEight, DirectArguments::storageOffset()),
+        resultRegs);
     
-#if USE(JSVALUE32_64)
-    m_jit.load32(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
-            OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
-        resultTagReg);
-    m_jit.load32(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
-            OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
-        resultReg);
-    jsValueResult(resultTagReg, resultReg, node);
-#else
-    m_jit.load64(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)),
-        resultReg);
-    jsValueResult(resultReg, node);
-#endif
+    jsValueResult(resultRegs, node);
 }
 
-void SpeculativeJIT::compileGetArgumentsLength(Node* node)
+void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node)
 {
     SpeculateCellOperand base(this, node->child1());
-    GPRTemporary result(this, Reuse, base);
+    SpeculateStrictInt32Operand property(this, node->child2());
+    GPRTemporary result(this);
+#if USE(JSVALUE32_64)
+    GPRTemporary resultTag(this);
+#endif
+    GPRTemporary scratch(this);
+    GPRTemporary scratch2(this);
     
     GPRReg baseReg = base.gpr();
+    GPRReg propertyReg = property.gpr();
     GPRReg resultReg = result.gpr();
+#if USE(JSVALUE32_64)
+    GPRReg resultTagReg = resultTag.gpr();
+    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
+#else
+    JSValueRegs resultRegs = JSValueRegs(resultReg);
+#endif
+    GPRReg scratchReg = scratch.gpr();
+    GPRReg scratch2Reg = scratch2.gpr();
     
     if (!m_compileOkay)
         return;
     
-    ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+    ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     
     speculationCheck(
-        Uncountable, JSValueSource(), 0,
-        m_jit.branchTest8(
-            MacroAssembler::NonZero,
-            MacroAssembler::Address(baseReg, Arguments::offsetOfOverrodeLength())));
+        ExoticObjectMode, JSValueSource(), nullptr,
+        m_jit.branch32(
+            MacroAssembler::AboveOrEqual, propertyReg,
+            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength())));
     
+    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTable()), scratchReg);
     m_jit.load32(
-        MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments()),
-        resultReg);
-    int32Result(resultReg, node);
+        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfLength()), scratch2Reg);
+    
+    MacroAssembler::Jump overflowArgument = m_jit.branch32(
+        MacroAssembler::AboveOrEqual, propertyReg, scratch2Reg);
+    
+    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfScope()), scratch2Reg);
+
+    m_jit.loadPtr(
+        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfArguments()),
+        scratchReg);
+    m_jit.load32(
+        MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesFour),
+        scratchReg);
+    
+    speculationCheck(
+        ExoticObjectMode, JSValueSource(), nullptr,
+        m_jit.branch32(
+            MacroAssembler::Equal, scratchReg, TrustedImm32(ScopeOffset::invalidOffset)));
+    
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            scratch2Reg, propertyReg, MacroAssembler::TimesEight,
+            JSEnvironmentRecord::offsetOfVariables()),
+        resultRegs);
+    
+    MacroAssembler::Jump done = m_jit.jump();
+    overflowArgument.link(&m_jit);
+    
+    m_jit.sub32(propertyReg, scratch2Reg);
+    m_jit.neg32(scratch2Reg);
+    
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            baseReg, scratch2Reg, MacroAssembler::TimesEight,
+            ScopedArguments::overflowStorageOffset()),
+        resultRegs);
+    speculationCheck(ExoticObjectMode, JSValueSource(), nullptr, m_jit.branchIfEmpty(resultRegs));
+    
+    done.link(&m_jit);
+    
+    jsValueResult(resultRegs, node);
+}
+
+void SpeculativeJIT::compileGetScope(Node* node)
+{
+    SpeculateCellOperand function(this, node->child1());
+    GPRTemporary result(this, Reuse, function);
+    m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
+    cellResult(result.gpr(), node);
+}
+
+void SpeculativeJIT::compileSkipScope(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRTemporary result(this, Reuse, scope);
+    m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSScope::offsetOfNext()), result.gpr());
+    cellResult(result.gpr(), node);
 }
 
 void SpeculativeJIT::compileGetArrayLength(Node* node)
@@ -4141,8 +4516,52 @@ void SpeculativeJIT::compileGetArrayLength(Node* node)
         int32Result(resultGPR, node);
         break;
     }
-    case Array::Arguments: {
-        compileGetArgumentsLength(node);
+    case Array::DirectArguments: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary result(this, Reuse, base);
+        
+        GPRReg baseReg = base.gpr();
+        GPRReg resultReg = result.gpr();
+        
+        if (!m_compileOkay)
+            return;
+        
+        ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+        
+        speculationCheck(
+            ExoticObjectMode, JSValueSource(), 0,
+            m_jit.branchTestPtr(
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
+        
+        m_jit.load32(
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength()), resultReg);
+        
+        int32Result(resultReg, node);
+        break;
+    }
+    case Array::ScopedArguments: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary result(this, Reuse, base);
+        
+        GPRReg baseReg = base.gpr();
+        GPRReg resultReg = result.gpr();
+        
+        if (!m_compileOkay)
+            return;
+        
+        ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+        
+        speculationCheck(
+            ExoticObjectMode, JSValueSource(), 0,
+            m_jit.branchTest8(
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(baseReg, ScopedArguments::offsetOfOverrodeThings())));
+        
+        m_jit.load32(
+            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength()), resultReg);
+        
+        int32Result(resultReg, node);
         break;
     }
     default: {
@@ -4157,28 +4576,428 @@ void SpeculativeJIT::compileGetArrayLength(Node* node)
     } }
 }
 
-void SpeculativeJIT::compileNewFunctionNoCheck(Node* node)
+void SpeculativeJIT::compileNewFunction(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeGPR = scope.gpr();
+
+    FunctionExecutable* executable = node->castOperand<FunctionExecutable*>();
+
+    if (executable->singletonFunction()->isStillValid()) {
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+
+        callOperation(operationNewFunction, resultGPR, scopeGPR, executable);
+        cellResult(resultGPR, node);
+        return;
+    }
+
+    Structure* structure = m_jit.graph().globalObjectFor(
+        node->origin.semantic)->functionStructure();
+
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+
+    JITCompiler::JumpList slowPath;
+    emitAllocateJSObjectWithKnownSize<JSFunction>(
+        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0),
+        scratch1GPR, scratch2GPR, slowPath, JSFunction::allocationSize(0));
+
+    // Don't need a memory barriers since we just fast-created the function, so it
+    // must be young.
+    m_jit.storePtr(
+        scopeGPR,
+        JITCompiler::Address(resultGPR, JSFunction::offsetOfScopeChain()));
+    m_jit.storePtr(
+        TrustedImmPtr(executable),
+        JITCompiler::Address(resultGPR, JSFunction::offsetOfExecutable()));
+    m_jit.storePtr(
+        TrustedImmPtr(0),
+        JITCompiler::Address(resultGPR, JSFunction::offsetOfRareData()));
+
+
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationNewFunctionWithInvalidatedReallocationWatchpoint, resultGPR, scopeGPR, executable));
+
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileForwardVarargs(Node* node)
+{
+    LoadVarargsData* data = node->loadVarargsData();
+    InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
+        
+    GPRTemporary length(this);
+    JSValueRegsTemporary temp(this);
+    GPRReg lengthGPR = length.gpr();
+    JSValueRegs tempRegs = temp.regs();
+        
+    emitGetLength(inlineCallFrame, lengthGPR, /* includeThis = */ true);
+    if (data->offset)
+        m_jit.sub32(TrustedImm32(data->offset), lengthGPR);
+        
+    speculationCheck(
+        VarargsOverflow, JSValueSource(), Edge(), m_jit.branch32(
+            MacroAssembler::Above,
+            lengthGPR, TrustedImm32(data->limit)));
+        
+    m_jit.store32(lengthGPR, JITCompiler::payloadFor(data->machineCount));
+        
+    VirtualRegister sourceStart = JITCompiler::argumentsStart(inlineCallFrame) + data->offset;
+    VirtualRegister targetStart = data->machineStart;
+
+    m_jit.sub32(TrustedImm32(1), lengthGPR);
+        
+    // First have a loop that fills in the undefined slots in case of an arity check failure.
+    m_jit.move(TrustedImm32(data->mandatoryMinimum), tempRegs.payloadGPR());
+    JITCompiler::Jump done = m_jit.branch32(JITCompiler::BelowOrEqual, tempRegs.payloadGPR(), lengthGPR);
+        
+    JITCompiler::Label loop = m_jit.label();
+    m_jit.sub32(TrustedImm32(1), tempRegs.payloadGPR());
+    m_jit.storeTrustedValue(
+        jsUndefined(),
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, tempRegs.payloadGPR(), JITCompiler::TimesEight,
+            targetStart.offset() * sizeof(EncodedJSValue)));
+    m_jit.branch32(JITCompiler::Above, tempRegs.payloadGPR(), lengthGPR).linkTo(loop, &m_jit);
+    done.link(&m_jit);
+        
+    // And then fill in the actual argument values.
+    done = m_jit.branchTest32(JITCompiler::Zero, lengthGPR);
+        
+    loop = m_jit.label();
+    m_jit.sub32(TrustedImm32(1), lengthGPR);
+    m_jit.loadValue(
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+            sourceStart.offset() * sizeof(EncodedJSValue)),
+        tempRegs);
+    m_jit.storeValue(
+        tempRegs,
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+            targetStart.offset() * sizeof(EncodedJSValue)));
+    m_jit.branchTest32(JITCompiler::NonZero, lengthGPR).linkTo(loop, &m_jit);
+        
+    done.link(&m_jit);
+        
+    noResult(node);
+}
+
+void SpeculativeJIT::compileCreateActivation(Node* node)
+{
+    SymbolTable* table = node->castOperand<SymbolTable*>();
+    Structure* structure = m_jit.graph().globalObjectFor(
+        node->origin.semantic)->activationStructure();
+        
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeGPR = scope.gpr();
+    
+    if (table->singletonScope()->isStillValid()) {
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+        
+        flushRegisters();
+        
+        callOperation(operationCreateActivationDirect, resultGPR, structure, scopeGPR, table);
+        cellResult(resultGPR, node);
+        return;
+    }
+    
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+        
+    JITCompiler::JumpList slowPath;
+    emitAllocateJSObjectWithKnownSize<JSLexicalEnvironment>(
+        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
+        slowPath, JSLexicalEnvironment::allocationSize(table));
+        
+    // Don't need a memory barriers since we just fast-created the activation, so the
+    // activation must be young.
+    m_jit.storePtr(scopeGPR, JITCompiler::Address(resultGPR, JSScope::offsetOfNext()));
+    m_jit.storePtr(
+        TrustedImmPtr(table),
+        JITCompiler::Address(resultGPR, JSLexicalEnvironment::offsetOfSymbolTable()));
+        
+    // Must initialize all members to undefined.
+    for (unsigned i = 0; i < table->scopeSize(); ++i) {
+        m_jit.storeTrustedValue(
+            jsUndefined(),
+            JITCompiler::Address(
+                resultGPR, JSLexicalEnvironment::offsetOfVariable(ScopeOffset(i))));
+    }
+
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationCreateActivationDirect, resultGPR, structure, scopeGPR, table));
+
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileCreateDirectArguments(Node* node)
 {
-    GPRResult result(this);
+    // FIXME: A more effective way of dealing with the argument count and callee is to have
+    // them be explicit arguments to this node.
+    // https://bugs.webkit.org/show_bug.cgi?id=142207
+    
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+    GPRTemporary length;
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+    GPRReg lengthGPR = InvalidGPRReg;
+    JSValueRegs valueRegs = JSValueRegs::withTwoAvailableRegs(scratch1GPR, scratch2GPR);
+        
+    unsigned minCapacity = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->numParameters() - 1;
+        
+    unsigned knownLength;
+    bool lengthIsKnown; // if false, lengthGPR will have the length.
+    if (node->origin.semantic.inlineCallFrame
+        && !node->origin.semantic.inlineCallFrame->isVarargs()) {
+        knownLength = node->origin.semantic.inlineCallFrame->arguments.size() - 1;
+        lengthIsKnown = true;
+    } else {
+        knownLength = UINT_MAX;
+        lengthIsKnown = false;
+            
+        GPRTemporary realLength(this);
+        length.adopt(realLength);
+        lengthGPR = length.gpr();
+
+        VirtualRegister argumentCountRegister;
+        if (!node->origin.semantic.inlineCallFrame)
+            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+        else
+            argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
+        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
+        m_jit.sub32(TrustedImm32(1), lengthGPR);
+    }
+        
+    Structure* structure =
+        m_jit.graph().globalObjectFor(node->origin.semantic)->directArgumentsStructure();
+        
+    // Use a different strategy for allocating the object depending on whether we know its
+    // size statically.
+    JITCompiler::JumpList slowPath;
+    if (lengthIsKnown) {
+        emitAllocateJSObjectWithKnownSize<DirectArguments>(
+            resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
+            slowPath, DirectArguments::allocationSize(std::max(knownLength, minCapacity)));
+            
+        m_jit.store32(
+            TrustedImm32(knownLength),
+            JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
+    } else {
+        JITCompiler::Jump tooFewArguments;
+        if (minCapacity) {
+            tooFewArguments =
+                m_jit.branch32(JITCompiler::Below, lengthGPR, TrustedImm32(minCapacity));
+        }
+        m_jit.lshift32(lengthGPR, TrustedImm32(3), scratch1GPR);
+        m_jit.add32(TrustedImm32(DirectArguments::storageOffset()), scratch1GPR);
+        if (minCapacity) {
+            JITCompiler::Jump done = m_jit.jump();
+            tooFewArguments.link(&m_jit);
+            m_jit.move(TrustedImm32(DirectArguments::allocationSize(minCapacity)), scratch1GPR);
+            done.link(&m_jit);
+        }
+            
+        emitAllocateVariableSizedJSObject<DirectArguments>(
+            resultGPR, TrustedImmPtr(structure), scratch1GPR, scratch1GPR, scratch2GPR,
+            slowPath);
+            
+        m_jit.store32(
+            lengthGPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
+    }
+        
+    m_jit.store32(
+        TrustedImm32(minCapacity),
+        JITCompiler::Address(resultGPR, DirectArguments::offsetOfMinCapacity()));
+        
+    m_jit.storePtr(
+        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
+        
+    if (lengthIsKnown) {
+        addSlowPathGenerator(
+            slowPathCall(
+                slowPath, this, operationCreateDirectArguments, resultGPR, structure,
+                knownLength, minCapacity));
+    } else {
+        auto generator = std::make_unique<CallCreateDirectArgumentsSlowPathGenerator>(
+            slowPath, this, resultGPR, structure, lengthGPR, minCapacity);
+        addSlowPathGenerator(WTF::move(generator));
+    }
+        
+    if (node->origin.semantic.inlineCallFrame) {
+        if (node->origin.semantic.inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                JITCompiler::addressFor(
+                    node->origin.semantic.inlineCallFrame->calleeRecovery.virtualRegister()),
+                scratch1GPR);
+        } else {
+            m_jit.move(
+                TrustedImmPtr(
+                    node->origin.semantic.inlineCallFrame->calleeRecovery.constant().asCell()),
+                scratch1GPR);
+        }
+    } else
+        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratch1GPR);
+
+    // Don't need a memory barriers since we just fast-created the activation, so the
+    // activation must be young.
+    m_jit.storePtr(
+        scratch1GPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfCallee()));
+        
+    VirtualRegister start = m_jit.argumentsStart(node->origin.semantic);
+    if (lengthIsKnown) {
+        for (unsigned i = 0; i < std::max(knownLength, minCapacity); ++i) {
+            m_jit.loadValue(JITCompiler::addressFor(start + i), valueRegs);
+            m_jit.storeValue(
+                valueRegs, JITCompiler::Address(resultGPR, DirectArguments::offsetOfSlot(i)));
+        }
+    } else {
+        JITCompiler::Jump done;
+        if (minCapacity) {
+            JITCompiler::Jump startLoop = m_jit.branch32(
+                JITCompiler::AboveOrEqual, lengthGPR, TrustedImm32(minCapacity));
+            m_jit.move(TrustedImm32(minCapacity), lengthGPR);
+            startLoop.link(&m_jit);
+        } else
+            done = m_jit.branchTest32(MacroAssembler::Zero, lengthGPR);
+        JITCompiler::Label loop = m_jit.label();
+        m_jit.sub32(TrustedImm32(1), lengthGPR);
+        m_jit.loadValue(
+            JITCompiler::BaseIndex(
+                GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+                start.offset() * static_cast<int>(sizeof(Register))),
+            valueRegs);
+        m_jit.storeValue(
+            valueRegs,
+            JITCompiler::BaseIndex(
+                resultGPR, lengthGPR, JITCompiler::TimesEight,
+                DirectArguments::storageOffset()));
+        m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loop, &m_jit);
+        if (done.isSet())
+            done.link(&m_jit);
+    }
+        
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileGetFromArguments(Node* node)
+{
+    SpeculateCellOperand arguments(this, node->child1());
+    JSValueRegsTemporary result(this);
+    
+    GPRReg argumentsGPR = arguments.gpr();
+    JSValueRegs resultRegs = result.regs();
+    
+    m_jit.loadValue(JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())), resultRegs);
+    jsValueResult(resultRegs, node);
+}
+
+void SpeculativeJIT::compilePutToArguments(Node* node)
+{
+    SpeculateCellOperand arguments(this, node->child1());
+    JSValueOperand value(this, node->child2());
+    
+    GPRReg argumentsGPR = arguments.gpr();
+    JSValueRegs valueRegs = value.jsValueRegs();
+    
+    m_jit.storeValue(valueRegs, JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())));
+    noResult(node);
+}
+
+void SpeculativeJIT::compileCreateScopedArguments(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeGPR = scope.gpr();
+    
+    GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
     flushRegisters();
-    callOperation(
-        operationNewFunctionNoCheck, resultGPR, m_jit.codeBlock()->functionDecl(node->functionDeclIndex()));
+    
+    // We set up the arguments ourselves, because we have the whole register file and we can
+    // set them up directly into the argument registers. This also means that we don't have to
+    // invent a four-argument-register shuffle.
+    
+    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee, 5:scope
+    
+    // Do the scopeGPR first, since it might alias an argument register.
+    m_jit.setupArgument(5, [&] (GPRReg destGPR) { m_jit.move(scopeGPR, destGPR); });
+    
+    // These other things could be done in any order.
+    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(
+        1, [&] (GPRReg destGPR) {
+            m_jit.move(
+                TrustedImmPtr(m_jit.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure()),
+                destGPR);
+        });
+    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
+    
+    appendCallWithExceptionCheckSetResult(operationCreateScopedArguments, resultGPR);
+    
     cellResult(resultGPR, node);
 }
 
-void SpeculativeJIT::compileNewFunctionExpression(Node* node)
+void SpeculativeJIT::compileCreateClonedArguments(Node* node)
 {
-    GPRResult result(this);
+    GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
     flushRegisters();
-    callOperation(
-        operationNewFunctionNoCheck,
-        resultGPR,
-        m_jit.codeBlock()->functionExpr(node->functionExprIndex()));
+    
+    // We set up the arguments ourselves, because we have the whole register file and we can
+    // set them up directly into the argument registers.
+    
+    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee
+    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(
+        1, [&] (GPRReg destGPR) {
+            m_jit.move(
+                TrustedImmPtr(
+                    m_jit.globalObjectFor(node->origin.semantic)->outOfBandArgumentsStructure()),
+                destGPR);
+        });
+    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
+    
+    appendCallWithExceptionCheckSetResult(operationCreateClonedArguments, resultGPR);
+    
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileNotifyWrite(Node* node)
+{
+    WatchpointSet* set = node->watchpointSet();
+    
+    JITCompiler::Jump slowCase = m_jit.branch8(
+        JITCompiler::NotEqual,
+        JITCompiler::AbsoluteAddress(set->addressOfState()),
+        TrustedImm32(IsInvalidated));
+    
+    addSlowPathGenerator(
+        slowPathCall(slowCase, this, operationNotifyWrite, NoResult, set));
+    
+    noResult(node);
+}
+
 bool SpeculativeJIT::compileRegExpExec(Node* node)
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();
@@ -4204,7 +5023,7 @@ bool SpeculativeJIT::compileRegExpExec(Node* node)
     GPRReg argumentGPR = argument.gpr();
     
     flushRegisters();
-    GPRResult result(this);
+    GPRFlushedCallResult result(this);
     callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
 
     branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, result.gpr(), taken);
@@ -4218,16 +5037,128 @@ bool SpeculativeJIT::compileRegExpExec(Node* node)
     return true;
 }
 
+void SpeculativeJIT::compileIsObjectOrNull(Node* node)
+{
+    JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+    
+    JSValueOperand value(this, node->child1());
+    JSValueRegs valueRegs = value.jsValueRegs();
+    
+    GPRTemporary result(this);
+    GPRReg resultGPR = result.gpr();
+    
+    JITCompiler::Jump isCell = m_jit.branchIfCell(valueRegs);
+    
+    JITCompiler::Jump isNull = m_jit.branchIfEqual(valueRegs, jsNull());
+    JITCompiler::Jump isNonNullNonCell = m_jit.jump();
+    
+    isCell.link(&m_jit);
+    JITCompiler::Jump isFunction = m_jit.branchIfFunction(valueRegs.payloadGPR());
+    JITCompiler::Jump notObject = m_jit.branchIfNotObject(valueRegs.payloadGPR());
+    
+    JITCompiler::Jump slowPath = m_jit.branchTest8(
+        JITCompiler::NonZero,
+        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoFlagsOffset()),
+        TrustedImm32(MasqueradesAsUndefined | TypeOfShouldCallGetCallData));
+    
+    isNull.link(&m_jit);
+    m_jit.move(TrustedImm32(1), resultGPR);
+    JITCompiler::Jump done = m_jit.jump();
+    
+    isNonNullNonCell.link(&m_jit);
+    isFunction.link(&m_jit);
+    notObject.link(&m_jit);
+    m_jit.move(TrustedImm32(0), resultGPR);
+    
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationObjectIsObject, resultGPR, globalObject,
+            valueRegs.payloadGPR()));
+    
+    done.link(&m_jit);
+    
+    unblessedBooleanResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileIsFunction(Node* node)
+{
+    JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+    
+    JSValueOperand value(this, node->child1());
+    JSValueRegs valueRegs = value.jsValueRegs();
+    
+    GPRTemporary result(this);
+    GPRReg resultGPR = result.gpr();
+    
+    JITCompiler::Jump notCell = m_jit.branchIfNotCell(valueRegs);
+    JITCompiler::Jump isFunction = m_jit.branchIfFunction(valueRegs.payloadGPR());
+    JITCompiler::Jump notObject = m_jit.branchIfNotObject(valueRegs.payloadGPR());
+    
+    JITCompiler::Jump slowPath = m_jit.branchTest8(
+        JITCompiler::NonZero,
+        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoFlagsOffset()),
+        TrustedImm32(MasqueradesAsUndefined | TypeOfShouldCallGetCallData));
+    
+    notCell.link(&m_jit);
+    notObject.link(&m_jit);
+    m_jit.move(TrustedImm32(0), resultGPR);
+    JITCompiler::Jump done = m_jit.jump();
+    
+    isFunction.link(&m_jit);
+    m_jit.move(TrustedImm32(1), resultGPR);
+    
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationObjectIsFunction, resultGPR, globalObject,
+            valueRegs.payloadGPR()));
+    
+    done.link(&m_jit);
+    
+    unblessedBooleanResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileTypeOf(Node* node)
+{
+    JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+    
+    JSValueOperand value(this, node->child1());
+    JSValueRegs valueRegs = value.jsValueRegs();
+    
+    GPRTemporary result(this);
+    GPRReg resultGPR = result.gpr();
+    
+    JITCompiler::JumpList done;
+    JITCompiler::Jump slowPath;
+    m_jit.emitTypeOf(
+        valueRegs, resultGPR,
+        [&] (TypeofType type, bool fallsThrough) {
+            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.typeString(type)), resultGPR);
+            if (!fallsThrough)
+                done.append(m_jit.jump());
+        },
+        [&] (JITCompiler::Jump theSlowPath) {
+            slowPath = theSlowPath;
+        });
+    done.link(&m_jit);
+
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationTypeOfObject, resultGPR, globalObject,
+            valueRegs.payloadGPR()));
+    
+    cellResult(resultGPR, node);
+}
+
 void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
 {
-    if (node->structureTransitionData().previousStructure->couldHaveIndexingHeader()) {
+    if (node->transition()->previous->couldHaveIndexingHeader()) {
         SpeculateCellOperand base(this, node->child1());
         
         GPRReg baseGPR = base.gpr();
         
         flushRegisters();
 
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         callOperation(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity, result.gpr(), baseGPR);
         
         storageResult(result.gpr(), node);
@@ -4240,8 +5171,8 @@ void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
     GPRReg baseGPR = base.gpr();
     GPRReg scratchGPR1 = scratch1.gpr();
         
-    ASSERT(!node->structureTransitionData().previousStructure->outOfLineCapacity());
-    ASSERT(initialOutOfLineCapacity == node->structureTransitionData().newStructure->outOfLineCapacity());
+    ASSERT(!node->transition()->previous->outOfLineCapacity());
+    ASSERT(initialOutOfLineCapacity == node->transition()->next->outOfLineCapacity());
     
     JITCompiler::Jump slowPath =
         emitAllocateBasicStorage(
@@ -4259,18 +5190,18 @@ void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
 
 void SpeculativeJIT::compileReallocatePropertyStorage(Node* node)
 {
-    size_t oldSize = node->structureTransitionData().previousStructure->outOfLineCapacity() * sizeof(JSValue);
+    size_t oldSize = node->transition()->previous->outOfLineCapacity() * sizeof(JSValue);
     size_t newSize = oldSize * outOfLineGrowthFactor;
-    ASSERT(newSize == node->structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
+    ASSERT(newSize == node->transition()->next->outOfLineCapacity() * sizeof(JSValue));
 
-    if (node->structureTransitionData().previousStructure->couldHaveIndexingHeader()) {
+    if (node->transition()->previous->couldHaveIndexingHeader()) {
         SpeculateCellOperand base(this, node->child1());
         
         GPRReg baseGPR = base.gpr();
         
         flushRegisters();
 
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         callOperation(operationReallocateButterflyToGrowPropertyStorage, result.gpr(), baseGPR, newSize / sizeof(JSValue));
 
         storageResult(result.gpr(), node);
@@ -4315,7 +5246,7 @@ GPRReg SpeculativeJIT::temporaryRegisterForPutByVal(GPRTemporary& temporary, Arr
     return temporary.gpr();
 }
 
-void SpeculativeJIT::compileToStringOnCell(Node* node)
+void SpeculativeJIT::compileToStringOrCallStringConstructorOnCell(Node* node)
 {
     SpeculateCellOperand op1(this, node->child1());
     GPRReg op1GPR = op1.gpr();
@@ -4339,10 +5270,10 @@ void SpeculativeJIT::compileToStringOnCell(Node* node)
 
         m_jit.load32(JITCompiler::Address(op1GPR, JSCell::structureIDOffset()), resultGPR);
         JITCompiler::Jump isString = m_jit.branchStructurePtr(
-            JITCompiler::Equal, 
+            JITCompiler::Equal,
             resultGPR,
             m_jit.vm()->stringStructure.get());
-        
+
         speculateStringObjectForStructure(node->child1(), resultGPR);
         
         m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
@@ -4359,7 +5290,7 @@ void SpeculativeJIT::compileToStringOnCell(Node* node)
     }
         
     case CellUse: {
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
         
         // We flush registers instead of silent spill/fill because in this mode we
@@ -4368,15 +5299,17 @@ void SpeculativeJIT::compileToStringOnCell(Node* node)
         flushRegisters();
         JITCompiler::Jump done;
         if (node->child1()->prediction() & SpecString) {
-            JITCompiler::Jump needCall = m_jit.branchStructurePtr(
-                JITCompiler::NotEqual,
-                JITCompiler::Address(op1GPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get());
+            JITCompiler::Jump needCall = m_jit.branchIfNotString(op1GPR);
             m_jit.move(op1GPR, resultGPR);
             done = m_jit.jump();
             needCall.link(&m_jit);
         }
-        callOperation(operationToStringOnCell, resultGPR, op1GPR);
+        if (node->op() == ToString)
+            callOperation(operationToStringOnCell, resultGPR, op1GPR);
+        else {
+            ASSERT(node->op() == CallStringConstructor);
+            callOperation(operationCallStringConstructorOnCell, resultGPR, op1GPR);
+        }
         if (done.isSet())
             done.link(&m_jit);
         cellResult(resultGPR, node);
@@ -4506,6 +5439,28 @@ void SpeculativeJIT::compileNewTypedArray(Node* node)
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::speculateCellTypeWithoutTypeFiltering(
+    Edge edge, GPRReg cellGPR, JSType jsType)
+{
+    speculationCheck(
+        BadType, JSValueSource::unboxedCell(cellGPR), edge,
+        m_jit.branch8(
+            MacroAssembler::NotEqual,
+            MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
+            MacroAssembler::TrustedImm32(jsType)));
+}
+
+void SpeculativeJIT::speculateCellType(
+    Edge edge, GPRReg cellGPR, SpeculatedType specType, JSType jsType)
+{
+    DFG_TYPE_CHECK(
+        JSValueSource::unboxedCell(cellGPR), edge, specType,
+        m_jit.branch8(
+            MacroAssembler::NotEqual,
+            MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
+            TrustedImm32(jsType)));
+}
+
 void SpeculativeJIT::speculateInt32(Edge edge)
 {
     if (!needsTypeCheck(edge, SpecInt32))
@@ -4536,7 +5491,37 @@ void SpeculativeJIT::speculateNumber(Edge edge)
 #endif
 }
 
-void SpeculativeJIT::speculateDoubleReal(Edge edge)
+void SpeculativeJIT::speculateRealNumber(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecBytecodeRealNumber))
+        return;
+    
+    JSValueOperand op1(this, edge, ManualOperandSpeculation);
+    FPRTemporary result(this);
+    
+    JSValueRegs op1Regs = op1.jsValueRegs();
+    FPRReg resultFPR = result.fpr();
+    
+#if USE(JSVALUE64)
+    GPRTemporary temp(this);
+    GPRReg tempGPR = temp.gpr();
+    m_jit.move(op1Regs.gpr(), tempGPR);
+    m_jit.unboxDoubleWithoutAssertions(tempGPR, resultFPR);
+#else
+    FPRTemporary temp(this);
+    FPRReg tempFPR = temp.fpr();
+    unboxDouble(op1Regs.tagGPR(), op1Regs.payloadGPR(), resultFPR, tempFPR);
+#endif
+    
+    JITCompiler::Jump done = m_jit.branchDouble(
+        JITCompiler::DoubleEqual, resultFPR, resultFPR);
+
+    typeCheck(op1Regs, edge, SpecBytecodeRealNumber, m_jit.branchIfNotInt32(op1Regs));
+    
+    done.link(&m_jit);
+}
+
+void SpeculativeJIT::speculateDoubleRepReal(Edge edge)
 {
     if (!needsTypeCheck(edge, SpecDoubleReal))
         return;
@@ -4573,10 +5558,16 @@ void SpeculativeJIT::speculateObject(Edge edge)
     SpeculateCellOperand operand(this, edge);
     GPRReg gpr = operand.gpr();
     DFG_TYPE_CHECK(
-        JSValueSource::unboxedCell(gpr), edge, SpecObject, m_jit.branchStructurePtr(
-            MacroAssembler::Equal, 
-            MacroAssembler::Address(gpr, JSCell::structureIDOffset()), 
-            m_jit.vm()->stringStructure.get()));
+        JSValueSource::unboxedCell(gpr), edge, SpecObject, m_jit.branchIfNotObject(gpr));
+}
+
+void SpeculativeJIT::speculateFunction(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecFunction))
+        return;
+    
+    SpeculateCellOperand operand(this, edge);
+    speculateCellType(edge, operand.gpr(), SpecFunction, JSFunctionType);
 }
 
 void SpeculativeJIT::speculateFinalObject(Edge edge)
@@ -4585,12 +5576,7 @@ void SpeculativeJIT::speculateFinalObject(Edge edge)
         return;
     
     SpeculateCellOperand operand(this, edge);
-    GPRReg gpr = operand.gpr();
-    DFG_TYPE_CHECK(
-        JSValueSource::unboxedCell(gpr), edge, SpecFinalObject, m_jit.branch8(
-            MacroAssembler::NotEqual,
-            MacroAssembler::Address(gpr, JSCell::typeInfoTypeOffset()),
-            TrustedImm32(FinalObjectType)));
+    speculateCellType(edge, operand.gpr(), SpecFinalObject, FinalObjectType);
 }
 
 void SpeculativeJIT::speculateObjectOrOther(Edge edge)
@@ -4601,19 +5587,16 @@ void SpeculativeJIT::speculateObjectOrOther(Edge edge)
     JSValueOperand operand(this, edge, ManualOperandSpeculation);
     GPRTemporary temp(this);
     GPRReg tempGPR = temp.gpr();
-    MacroAssembler::Jump notCell = branchNotCell(operand.jsValueRegs());
+    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(operand.jsValueRegs());
     GPRReg gpr = operand.jsValueRegs().payloadGPR();
     DFG_TYPE_CHECK(
-        operand.jsValueRegs(), edge, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-            MacroAssembler::Equal, 
-            MacroAssembler::Address(gpr, JSCell::structureIDOffset()), 
-            m_jit.vm()->stringStructure.get()));
+        operand.jsValueRegs(), edge, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(gpr));
     MacroAssembler::Jump done = m_jit.jump();
     notCell.link(&m_jit);
     if (needsTypeCheck(edge, SpecCell | SpecOther)) {
         typeCheck(
             operand.jsValueRegs(), edge, SpecCell | SpecOther,
-            branchNotOther(operand.jsValueRegs(), tempGPR));
+            m_jit.branchIfNotOther(operand.jsValueRegs(), tempGPR));
     }
     done.link(&m_jit);
 }
@@ -4621,11 +5604,7 @@ void SpeculativeJIT::speculateObjectOrOther(Edge edge)
 void SpeculativeJIT::speculateString(Edge edge, GPRReg cell)
 {
     DFG_TYPE_CHECK(
-        JSValueSource::unboxedCell(cell), edge, SpecString | ~SpecCell,
-        m_jit.branchStructurePtr(
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(cell, JSCell::structureIDOffset()), 
-            m_jit.vm()->stringStructure.get()));
+        JSValueSource::unboxedCell(cell), edge, SpecString | ~SpecCell, m_jit.branchIfNotString(cell));
 }
 
 void SpeculativeJIT::speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage)
@@ -4727,13 +5706,10 @@ void SpeculativeJIT::speculateNotStringVar(Edge edge)
     GPRTemporary temp(this);
     GPRReg tempGPR = temp.gpr();
     
-    JITCompiler::Jump notCell = branchNotCell(operand.jsValueRegs());
+    JITCompiler::Jump notCell = m_jit.branchIfNotCell(operand.jsValueRegs());
     GPRReg cell = operand.jsValueRegs().payloadGPR();
     
-    JITCompiler::Jump notString = m_jit.branchStructurePtr(
-        MacroAssembler::NotEqual,
-        MacroAssembler::Address(cell, JSCell::structureIDOffset()),
-        m_jit.vm()->stringStructure.get());
+    JITCompiler::Jump notString = m_jit.branchIfNotString(cell);
     
     speculateStringIdentAndLoadStorage(edge, cell, tempGPR);
     
@@ -4747,7 +5723,7 @@ void SpeculativeJIT::speculateNotCell(Edge edge)
         return;
     
     JSValueOperand operand(this, edge, ManualOperandSpeculation); 
-    typeCheck(operand.jsValueRegs(), edge, ~SpecCell, branchIsCell(operand.jsValueRegs()));
+    typeCheck(operand.jsValueRegs(), edge, ~SpecCell, m_jit.branchIfCell(operand.jsValueRegs()));
 }
 
 void SpeculativeJIT::speculateOther(Edge edge)
@@ -4760,7 +5736,7 @@ void SpeculativeJIT::speculateOther(Edge edge)
     GPRReg tempGPR = temp.gpr();
     typeCheck(
         operand.jsValueRegs(), edge, SpecOther,
-        branchNotOther(operand.jsValueRegs(), tempGPR));
+        m_jit.branchIfNotOther(operand.jsValueRegs(), tempGPR));
 }
 
 void SpeculativeJIT::speculateMisc(Edge edge, JSValueRegs regs)
@@ -4814,8 +5790,11 @@ void SpeculativeJIT::speculate(Node*, Edge edge)
     case NumberUse:
         speculateNumber(edge);
         break;
+    case RealNumberUse:
+        speculateRealNumber(edge);
+        break;
     case DoubleRepRealUse:
-        speculateDoubleReal(edge);
+        speculateDoubleRepReal(edge);
         break;
 #if USE(JSVALUE64)
     case MachineIntUse:
@@ -4834,6 +5813,9 @@ void SpeculativeJIT::speculate(Node*, Edge edge)
     case ObjectUse:
         speculateObject(edge);
         break;
+    case FunctionUse:
+        speculateFunction(edge);
+        break;
     case FinalObjectUse:
         speculateFinalObject(edge);
         break;
@@ -5004,14 +5986,9 @@ void SpeculativeJIT::emitSwitchChar(Node* node, SwitchData* data)
         
         op1.use();
         
-        addBranch(branchNotCell(op1Regs), data->fallThrough.block);
+        addBranch(m_jit.branchIfNotCell(op1Regs), data->fallThrough.block);
         
-        addBranch(
-            m_jit.branchStructurePtr(
-                MacroAssembler::NotEqual,
-                MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()),
-            data->fallThrough.block);
+        addBranch(m_jit.branchIfNotString(op1Regs.payloadGPR()), data->fallThrough.block);
         
         emitSwitchCharStringJump(data, op1Regs.payloadGPR(), tempGPR);
         noResult(node, UseChildrenCalledExplicitly);
@@ -5024,18 +6001,6 @@ void SpeculativeJIT::emitSwitchChar(Node* node, SwitchData* data)
     }
 }
 
-bool SpeculativeJIT::StringSwitchCase::operator<(
-    const SpeculativeJIT::StringSwitchCase& other) const
-{
-    unsigned minLength = std::min(string->length(), other.string->length());
-    for (unsigned i = 0; i < minLength; ++i) {
-        if (string->at(i) == other.string->at(i))
-            continue;
-        return string->at(i) < other.string->at(i);
-    }
-    return string->length() < other.string->length();
-}
-
 namespace {
 
 struct CharacterCase {
@@ -5294,14 +6259,9 @@ void SpeculativeJIT::emitSwitchString(Node* node, SwitchData* data)
         
         op1.use();
         
-        addBranch(branchNotCell(op1Regs), data->fallThrough.block);
+        addBranch(m_jit.branchIfNotCell(op1Regs), data->fallThrough.block);
         
-        addBranch(
-            m_jit.branchStructurePtr(
-                MacroAssembler::NotEqual,
-                MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()),
-            data->fallThrough.block);
+        addBranch(m_jit.branchIfNotString(op1Regs.payloadGPR()), data->fallThrough.block);
         
         emitSwitchStringOnString(data, op1Regs.payloadGPR());
         noResult(node, UseChildrenCalledExplicitly);
@@ -5329,6 +6289,10 @@ void SpeculativeJIT::emitSwitch(Node* node)
     case SwitchString: {
         emitSwitchString(node, data);
         return;
+    }
+    case SwitchCell: {
+        DFG_CRASH(m_jit.graph(), node, "Bad switch kind");
+        return;
     } }
     RELEASE_ASSERT_NOT_REACHED();
 }
@@ -5350,36 +6314,13 @@ void SpeculativeJIT::linkBranches()
 #if ENABLE(GGC)
 void SpeculativeJIT::compileStoreBarrier(Node* node)
 {
-    switch (node->op()) {
-    case StoreBarrier: {
-        SpeculateCellOperand base(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
+    ASSERT(node->op() == StoreBarrier);
     
-        writeBarrier(base.gpr(), scratch1.gpr(), scratch2.gpr());
-        break;
-    }
-
-    case StoreBarrierWithNullCheck: {
-        JSValueOperand base(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
+    SpeculateCellOperand base(this, node->child1());
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
     
-#if USE(JSVALUE64)
-        JITCompiler::Jump isNull = m_jit.branchTest64(JITCompiler::Zero, base.gpr());
-        writeBarrier(base.gpr(), scratch1.gpr(), scratch2.gpr());
-#else
-        JITCompiler::Jump isNull = m_jit.branch32(JITCompiler::Equal, base.tagGPR(), TrustedImm32(JSValue::EmptyValueTag));
-        writeBarrier(base.payloadGPR(), scratch1.gpr(), scratch2.gpr());
-#endif
-        isNull.link(&m_jit);
-        break;
-    }
-
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        break;
-    }
+    writeBarrier(base.gpr(), scratch1.gpr(), scratch2.gpr());
 
     noResult(node);
 }
@@ -5387,15 +6328,14 @@ void SpeculativeJIT::compileStoreBarrier(Node* node)
 void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2)
 {
     ASSERT(scratch1 != scratch2);
-    WriteBarrierBuffer* writeBarrierBuffer = &m_jit.vm()->heap.m_writeBarrierBuffer;
-    m_jit.move(TrustedImmPtr(writeBarrierBuffer), scratch1);
-    m_jit.load32(MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()), scratch2);
-    JITCompiler::Jump needToFlush = m_jit.branch32(MacroAssembler::AboveOrEqual, scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::capacityOffset()));
+    WriteBarrierBuffer& writeBarrierBuffer = m_jit.vm()->heap.m_writeBarrierBuffer;
+    m_jit.load32(writeBarrierBuffer.currentIndexAddress(), scratch2);
+    JITCompiler::Jump needToFlush = m_jit.branch32(MacroAssembler::AboveOrEqual, scratch2, MacroAssembler::TrustedImm32(writeBarrierBuffer.capacity()));
 
     m_jit.add32(TrustedImm32(1), scratch2);
-    m_jit.store32(scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()));
+    m_jit.store32(scratch2, writeBarrierBuffer.currentIndexAddress());
 
-    m_jit.loadPtr(MacroAssembler::Address(scratch1, WriteBarrierBuffer::bufferOffset()), scratch1);
+    m_jit.move(TrustedImmPtr(writeBarrierBuffer.buffer()), scratch1);
     // We use an offset of -sizeof(void*) because we already added 1 to scratch2.
     m_jit.storePtr(cell, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::ScalePtr, static_cast<int32_t>(-sizeof(void*))));
 
@@ -5409,47 +6349,11 @@ void SpeculativeJIT::storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPR
     done.link(&m_jit);
 }
 
-void SpeculativeJIT::storeToWriteBarrierBuffer(JSCell* cell, GPRReg scratch1, GPRReg scratch2)
-{
-    ASSERT(scratch1 != scratch2);
-    WriteBarrierBuffer* writeBarrierBuffer = &m_jit.vm()->heap.m_writeBarrierBuffer;
-    m_jit.move(TrustedImmPtr(writeBarrierBuffer), scratch1);
-    m_jit.load32(MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()), scratch2);
-    JITCompiler::Jump needToFlush = m_jit.branch32(MacroAssembler::AboveOrEqual, scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::capacityOffset()));
-
-    m_jit.add32(TrustedImm32(1), scratch2);
-    m_jit.store32(scratch2, MacroAssembler::Address(scratch1, WriteBarrierBuffer::currentIndexOffset()));
-
-    m_jit.loadPtr(MacroAssembler::Address(scratch1, WriteBarrierBuffer::bufferOffset()), scratch1);
-    // We use an offset of -sizeof(void*) because we already added 1 to scratch2.
-    m_jit.storePtr(TrustedImmPtr(cell), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::ScalePtr, static_cast<int32_t>(-sizeof(void*))));
-
-    JITCompiler::Jump done = m_jit.jump();
-    needToFlush.link(&m_jit);
-
-    // Call C slow path
-    silentSpillAllRegisters(InvalidGPRReg);
-    callOperation(operationFlushWriteBarrierBuffer, cell);
-    silentFillAllRegisters(InvalidGPRReg);
-
-    done.link(&m_jit);
-}
-
-void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, GPRReg scratch1, GPRReg scratch2)
-{
-    if (Heap::isMarked(value))
-        return;
-
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
-    storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
-}
-
 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg scratch1, GPRReg scratch2)
 {
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
+    JITCompiler::Jump ownerIsRememberedOrInEden = m_jit.jumpIfIsRememberedOrInEden(ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
+    ownerIsRememberedOrInEden.link(&m_jit);
 }
 #else
 void SpeculativeJIT::compileStoreBarrier(Node* node)
index da17fb3642627e793adb7c890eca7e6c77d55f36..8798b6dddedb7bbccb47bbb0f69f111a1ae35cd9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -291,13 +291,10 @@ public:
 
 #if ENABLE(GGC)
     void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
-    void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
 
     void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
-    void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
 
     void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
-    void writeBarrier(JSCell* owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
 #endif
     void compileStoreBarrier(Node*);
 
@@ -316,7 +313,7 @@ public:
     GPRReg fillSpeculateBoolean(Edge);
     GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
 
-    void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>);
+    void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>);
     void runSlowPathGenerators();
     
     void compile(Node*);
@@ -556,30 +553,7 @@ public:
     bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
     bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
     
-    // Checks/accessors for constant values.
-    bool isConstant(Node* node) { return m_jit.graph().isConstant(node); }
-    bool isJSConstant(Node* node) { return m_jit.graph().isJSConstant(node); }
-    bool isInt32Constant(Node* node) { return m_jit.graph().isInt32Constant(node); }
-    bool isDoubleConstant(Node* node) { return m_jit.graph().isDoubleConstant(node); }
-    bool isNumberConstant(Node* node) { return m_jit.graph().isNumberConstant(node); }
-    bool isBooleanConstant(Node* node) { return m_jit.graph().isBooleanConstant(node); }
-    bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); }
-    int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); }
-    double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); }
-#if USE(JSVALUE32_64)
-    void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); }
-#endif
-    JSValue valueOfJSConstant(Node* node) { return m_jit.graph().valueOfJSConstant(node); }
-    bool valueOfBooleanConstant(Node* node) { return m_jit.graph().valueOfBooleanConstant(node); }
-    JSFunction* valueOfFunctionConstant(Node* node) { return m_jit.graph().valueOfFunctionConstant(node); }
-    bool isNullConstant(Node* node)
-    {
-        if (!isConstant(node))
-            return false;
-        return valueOfJSConstant(node).isNull();
-    }
-
-    StringImpl* identifierUID(unsigned index)
+    UniquedStringImpl* identifierUID(unsigned index)
     {
         return m_jit.graph().identifiers()[index];
     }
@@ -601,7 +575,6 @@ public:
         }
     }
 
-#ifndef NDEBUG
     // Used to ASSERT flushRegisters() has been called prior to
     // calling out from JIT code to a C helper function.
     bool isFlushed()
@@ -616,12 +589,11 @@ public:
         }
         return true;
     }
-#endif
 
 #if USE(JSVALUE64)
-    MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
+    static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
     {
-        return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node)));
+        return MacroAssembler::Imm64(JSValue::encode(node->asJSValue()));
     }
 #endif
 
@@ -706,7 +678,7 @@ public:
         }
 
         // Check if the lastNode is a branch on this node.
-        Node* lastNode = m_block->last();
+        Node* lastNode = m_block->terminal();
         return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
     }
     
@@ -740,57 +712,8 @@ public:
     void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
     void compileInstanceOf(Node*);
     
-    ptrdiff_t calleeFrameOffset(int numArgs)
-    {
-        return virtualRegisterForLocal(m_jit.graph().m_nextMachineLocal - 1 + JSStack::CallFrameHeaderSize + numArgs).offset() * sizeof(Register);
-    }
-    
-    // Access to our fixed callee CallFrame.
-    MacroAssembler::Address calleeFrameSlot(int slot)
-    {
-        ASSERT(slot >= JSStack::CallerFrameAndPCSize);
-        return MacroAssembler::Address(MacroAssembler::stackPointerRegister, sizeof(Register) * (slot - JSStack::CallerFrameAndPCSize));
-    }
-
-    // Access to our fixed callee CallFrame.
-    MacroAssembler::Address calleeArgumentSlot(int argument)
-    {
-        return calleeFrameSlot(virtualRegisterForArgument(argument).offset());
-    }
-
-    MacroAssembler::Address calleeFrameTagSlot(int slot)
-    {
-        return calleeFrameSlot(slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-    }
-
-    MacroAssembler::Address calleeFramePayloadSlot(int slot)
-    {
-        return calleeFrameSlot(slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
-    }
-
-    MacroAssembler::Address calleeArgumentTagSlot(int argument)
-    {
-        return calleeArgumentSlot(argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-    }
-
-    MacroAssembler::Address calleeArgumentPayloadSlot(int argument)
-    {
-        return calleeArgumentSlot(argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
-    }
-
-    MacroAssembler::Address calleeFrameCallerFrame()
-    {
-        return calleeFrameSlot(0).withOffset(CallFrame::callerFrameOffset());
-    }
-
     void emitCall(Node*);
     
-    int32_t framePointerOffsetToGetActivationRegisters()
-    {
-        return m_jit.codeBlock()->framePointerOffsetToGetActivationRegisters(
-            m_jit.graph().m_machineCaptureStart);
-    }
-    
     // Called once a node has completed code generation but prior to setting
     // its result, to free up its children. (This must happen prior to setting
     // the nodes result, since the node may have the same VirtualRegister as
@@ -866,13 +789,7 @@ public:
 #if USE(JSVALUE64)
         jsValueResult(reg, node, DataFormatJSBoolean, mode);
 #else
-        if (mode == CallUseChildren)
-            useChildren(node);
-
-        VirtualRegister virtualRegister = node->virtualRegister();
-        m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
-        GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
-        info.initBoolean(node, node->refCount(), reg);
+        booleanResult(reg, node, mode);
 #endif
     }
     void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
@@ -957,7 +874,7 @@ public:
     }
     void initConstantInfo(Node* node)
     {
-        ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
+        ASSERT(node->hasConstant());
         generationInfo(node).initConstant(node, node->refCount());
     }
     
@@ -967,6 +884,11 @@ public:
     // machine registers, and delegate the calling convention specific
     // decision as to how to fill the regsiters to setupArguments* methods.
 
+    JITCompiler::Call callOperation(V_JITOperation_E operation)
+    {
+        m_jit.setupArgumentsExecState();
+        return appendCallWithExceptionCheck(operation);
+    }
     JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
     {
         m_jit.setupArgumentsExecState();
@@ -1057,7 +979,17 @@ public:
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(C_JITOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
+    JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
     {
         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
         return appendCallWithExceptionCheckSetResult(operation, result);
@@ -1072,6 +1004,31 @@ public:
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtab operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
     {
         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
@@ -1094,6 +1051,18 @@ public:
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+
     JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
     {
         m_jit.setupArgumentsWithExecState(arg1);
@@ -1155,7 +1124,17 @@ public:
         m_jit.setupArgumentsExecState();
         return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(arg1);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
 
+    template<typename FunctionType>
+    JITCompiler::Call callOperation(FunctionType operation, NoResultTag)
+    {
+        return callOperation(operation);
+    }
     template<typename FunctionType, typename ArgumentType1>
     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
     {
@@ -1197,11 +1176,16 @@ public:
         m_jit.setupArguments(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(I_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
+    JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
     {
         m_jit.setupArgumentsWithExecState(arg1);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_EJscZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
     {
         m_jit.setupArgumentsWithExecState(arg1);
@@ -1213,6 +1197,18 @@ public:
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
+        return appendCall(operation);
+    }
+
 #if USE(JSVALUE64)
     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
     {
@@ -1241,7 +1237,7 @@ public:
         m_jit.setupArguments(value);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, result);
@@ -1281,12 +1277,17 @@ public:
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, result);
@@ -1296,6 +1297,16 @@ public:
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2);
@@ -1344,6 +1355,21 @@ public:
         m_jit.setupArgumentsWithExecState(arg1);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1)
     {
         m_jit.setupArguments(arg1);
@@ -1416,7 +1442,7 @@ public:
         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
         return appendCallWithExceptionCheck(operation);
     }
-    JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, StringImpl* uid)
+    JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid));
         return appendCallWithExceptionCheck(operation);
@@ -1443,18 +1469,32 @@ public:
         return appendCallWithExceptionCheck(operation);
     }
 
-    JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg arg)
-    {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), arg);
-        return appendCall(operation);
-    }
-
     JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1)
     {
         m_jit.setupArgumentsWithExecState(arg1);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, unsigned arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2, unsigned arg3, GPRReg arg4, unsigned arg5)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
+        return appendCallWithExceptionCheck(operation);
+    }
 #else // USE(JSVALUE32_64)
 
 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
@@ -1502,7 +1542,7 @@ public:
         m_jit.setupArgumentsWithExecState(arg1);
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
@@ -1517,6 +1557,16 @@ public:
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
+    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(arg1);
+        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+    }
     JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2);
@@ -1548,17 +1598,27 @@ public:
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
-    JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, JSCell* cell)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
+        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
-    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
-    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, StringImpl* uid)
+    JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid));
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
@@ -1658,6 +1718,11 @@ public:
         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     }
+    JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Payload)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, MacroAssembler::TrustedImm32(JSValue::CellTag));
+        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+    }
     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
@@ -1686,7 +1751,7 @@ public:
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
         return appendCallWithExceptionCheck(operation);
     }
-    JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, StringImpl* uid)
+    JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid));
         return appendCallWithExceptionCheck(operation);
@@ -1714,18 +1779,32 @@ public:
         return appendCallWithExceptionCheck(operation);
     }
 
-    JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg argTag, GPRReg argPayload)
-    {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), argPayload, argTag);
-        return appendCall(operation);
-    }
-
     JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
     {
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2, unsigned arg3)
+    {
+        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG  arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2)
+    {
+        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4, unsigned arg5)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2Payload, arg2Tag, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
+        return appendCallWithExceptionCheck(operation);
+    }
 #undef EABI_32BIT_DUMMY_ARG
 #undef SH4_32BIT_DUMMY_ARG
     
@@ -1993,17 +2072,6 @@ public:
 
     void dump(const char* label = 0);
 
-    bool isInteger(Node* node)
-    {
-        if (node->hasInt32Result())
-            return true;
-
-        if (isInt32Constant(node))
-            return true;
-
-        return generationInfo(node).isJSInt32();
-    }
-    
     bool betterUseStrictInt52(Node* node)
     {
         return !generationInfo(node).isInt52();
@@ -2020,8 +2088,10 @@ public:
     void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
     void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
     void compilePeepHoleObjectEquality(Node*, Node* branchNode);
+    void compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode);
     void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
     void compileObjectEquality(Node*);
+    void compileObjectStrictEquality(Edge objectChild, Edge otherChild);
     void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
     void compileObjectOrOtherLogicalNot(Edge value);
     void compileLogicalNot(Node*);
@@ -2038,6 +2108,7 @@ public:
     void compileMiscStrictEq(Node*);
 
     void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
+    void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
     void emitBranch(Node*);
     
     struct StringSwitchCase {
@@ -2049,7 +2120,10 @@ public:
         {
         }
         
-        bool operator<(const StringSwitchCase& other) const;
+        bool operator<(const StringSwitchCase& other) const
+        {
+            return stringLessThan(*string, *other.string);
+        }
         
         StringImpl* string;
         BasicBlock* target;
@@ -2067,7 +2141,7 @@ public:
     void emitSwitchString(Node*, SwitchData*);
     void emitSwitch(Node*);
     
-    void compileToStringOnCell(Node*);
+    void compileToStringOrCallStringConstructorOnCell(Node*);
     void compileNewStringObject(Node*);
     
     void compileNewTypedArray(Node*);
@@ -2101,9 +2175,12 @@ public:
     void compileGetByValOnString(Node*);
     void compileFromCharCode(Node*); 
 
-    void compileGetByValOnArguments(Node*);
-    void compileGetArgumentsLength(Node*);
+    void compileGetByValOnDirectArguments(Node*);
+    void compileGetByValOnScopedArguments(Node*);
     
+    void compileGetScope(Node*);
+    void compileSkipScope(Node*);
+
     void compileGetArrayLength(Node*);
     
     void compileValueRep(Node*);
@@ -2114,11 +2191,16 @@ public:
     void compileDoubleAsInt32(Node*);
     void compileAdd(Node*);
     void compileMakeRope(Node*);
+    void compileArithClz32(Node*);
     void compileArithSub(Node*);
     void compileArithNegate(Node*);
     void compileArithMul(Node*);
     void compileArithDiv(Node*);
     void compileArithMod(Node*);
+    void compileArithPow(Node*);
+    void compileArithRound(Node*);
+    void compileArithSqrt(Node*);
+    void compileArithLog(Node*);
     void compileConstantStoragePointer(Node*);
     void compileGetIndexedPropertyStorage(Node*);
     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
@@ -2128,14 +2210,19 @@ public:
     void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
     void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
     void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
-    void compileNewFunctionNoCheck(Node*);
-    void compileNewFunctionExpression(Node*);
+    void compileNewFunction(Node*);
+    void compileForwardVarargs(Node*);
+    void compileCreateActivation(Node*);
+    void compileCreateDirectArguments(Node*);
+    void compileGetFromArguments(Node*);
+    void compilePutToArguments(Node*);
+    void compileCreateScopedArguments(Node*);
+    void compileCreateClonedArguments(Node*);
+    void compileNotifyWrite(Node*);
     bool compileRegExpExec(Node*);
-    
-    JITCompiler::Jump branchIsCell(JSValueRegs);
-    JITCompiler::Jump branchNotCell(JSValueRegs);
-    JITCompiler::Jump branchIsOther(JSValueRegs, GPRReg tempGPR);
-    JITCompiler::Jump branchNotOther(JSValueRegs, GPRReg tempGPR);
+    void compileIsObjectOrNull(Node*);
+    void compileIsFunction(Node*);
+    void compileTypeOf(Node*);
     
     void moveTrueTo(GPRReg);
     void moveFalseTo(GPRReg);
@@ -2194,21 +2281,49 @@ public:
         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
     }
 
+    template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
+    void emitAllocateJSObjectWithKnownSize(
+        GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
+        GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size)
+    {
+        MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
+        m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
+        emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
+    }
+
     // Convenience allocator for a built-in object.
     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
     void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
     {
-        MarkedAllocator* allocator = 0;
-        size_t size = ClassType::allocationSize(0);
-        if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
-            allocator = &m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
-        else if (ClassType::needsDestruction)
-            allocator = &m_jit.vm()->heap.allocatorForObjectWithNormalDestructor(size);
-        else
-            allocator = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(size);
-        m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
-        emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
+        emitAllocateJSObjectWithKnownSize<ClassType>(
+            resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
+            ClassType::allocationSize(0));
+    }
+
+    template <typename ClassType, typename StructureType> // StructureType and StorageType can be GPR or ImmPtr.
+    void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
+    {
+        static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
+        static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
+
+        MarkedSpace::Subspace& subspace = m_jit.vm()->heap.subspaceForObjectOfType<ClassType>();
+        m_jit.add32(TrustedImm32(MarkedSpace::preciseStep - 1), allocationSize);
+        MacroAssembler::Jump notSmall = m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::preciseCutoff));
+        m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::preciseStep)), scratchGPR1);
+        m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
+        m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.preciseAllocators[0]), scratchGPR1);
+
+        MacroAssembler::Jump selectedSmallSpace = m_jit.jump();
+        notSmall.link(&m_jit);
+        slowPath.append(m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::impreciseCutoff)));
+        m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::impreciseStep)), scratchGPR1);
+        m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
+        m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.impreciseAllocators[0]), scratchGPR1);
+
+        selectedSmallSpace.link(&m_jit);
+
+        emitAllocateJSObject(resultGPR, scratchGPR1, structure, TrustedImmPtr(0), scratchGPR2, slowPath);
     }
 
     template <typename T>
@@ -2220,8 +2335,16 @@ public:
     }
 
     void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
-    void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
-
+    
+    void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
+    void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
+    void emitGetCallee(CodeOrigin, GPRReg calleeGPR);
+    void emitGetArgumentStart(CodeOrigin, GPRReg startGPR);
+    
+    // Generate an OSR exit fuzz check. Returns Jump() if OSR exit fuzz is not enabled, or if
+    // it's in training mode.
+    MacroAssembler::Jump emitOSRExitFuzzCheck();
+    
     // Add a speculation check.
     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
     void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
@@ -2245,6 +2368,9 @@ public:
     bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
     void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
     
+    void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
+    void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
+    
     void speculateInt32(Edge);
 #if USE(JSVALUE64)
     void convertMachineInt(Edge, GPRReg resultGPR);
@@ -2252,10 +2378,12 @@ public:
     void speculateDoubleRepMachineInt(Edge);
 #endif // USE(JSVALUE64)
     void speculateNumber(Edge);
-    void speculateDoubleReal(Edge);
+    void speculateRealNumber(Edge);
+    void speculateDoubleRepReal(Edge);
     void speculateBoolean(Edge);
     void speculateCell(Edge);
     void speculateObject(Edge);
+    void speculateFunction(Edge);
     void speculateFinalObject(Edge);
     void speculateObjectOrOther(Edge);
     void speculateString(Edge edge, GPRReg cell);
@@ -2356,7 +2484,7 @@ public:
     
     bool m_isCheckingArgumentTypes;
     
-    Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators;
+    Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
     Vector<SilentRegisterSavePlan> m_plans;
 };
 
@@ -2655,18 +2783,18 @@ private:
 //
 // These classes lock the result of a call to a C++ helper function.
 
-class GPRResult : public GPRTemporary {
+class GPRFlushedCallResult : public GPRTemporary {
 public:
-    GPRResult(SpeculativeJIT* jit)
+    GPRFlushedCallResult(SpeculativeJIT* jit)
         : GPRTemporary(jit, GPRInfo::returnValueGPR)
     {
     }
 };
 
 #if USE(JSVALUE32_64)
-class GPRResult2 : public GPRTemporary {
+class GPRFlushedCallResult2 : public GPRTemporary {
 public:
-    GPRResult2(SpeculativeJIT* jit)
+    GPRFlushedCallResult2(SpeculativeJIT* jit)
         : GPRTemporary(jit, GPRInfo::returnValueGPR2)
     {
     }
@@ -3130,7 +3258,7 @@ void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocat
     Structure* stringObjectStructure =
         m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure();
     
-    if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure))) {
+    if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
         speculationCheck(
             NotStringObject, JSValueRegs(), 0,
             m_jit.branchStructurePtr(
index 8b2b6965d9aa57a60dd18cb3e1b9389f591286bb..7e08d9bfdb6571a84b243f519fc5ad7dfde55cdc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Intel Corporation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
 #include "Debugger.h"
-#include "JSActivation.h"
+#include "DirectArguments.h"
+#include "GetterSetter.h"
+#include "JSEnvironmentRecord.h"
+#include "JSLexicalEnvironment.h"
+#include "JSPropertyNameEnumerator.h"
 #include "ObjectPrototype.h"
 #include "JSCInlines.h"
+#include "SetupVarargsFrame.h"
+#include "TypeProfilerLog.h"
 
 namespace JSC { namespace DFG {
 
@@ -57,11 +63,12 @@ bool SpeculativeJIT::fillJSValue(Edge edge, GPRReg& tagGPR, GPRReg& payloadGPR,
         if (edge->hasConstant()) {
             tagGPR = allocate();
             payloadGPR = allocate();
-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).tag()), tagGPR);
-            m_jit.move(Imm32(valueOfJSConstant(edge.node()).payload()), payloadGPR);
+            JSValue value = edge->asJSValue();
+            m_jit.move(Imm32(value.tag()), tagGPR);
+            m_jit.move(Imm32(value.payload()), payloadGPR);
             m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
-            info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(edge.node()) ? DataFormatJSInt32 : DataFormatJS);
+            info.fillJSValue(*m_stream, tagGPR, payloadGPR, DataFormatJS);
         } else {
             DataFormat spillFormat = info.spillFormat();
             ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);
@@ -106,7 +113,7 @@ bool SpeculativeJIT::fillJSValue(Edge edge, GPRReg& tagGPR, GPRReg& payloadGPR,
             m_gprs.lock(gpr);
         }
         tagGPR = allocate();
-        uint32_t tag = JSValue::EmptyValueTag;
+        int32_t tag = JSValue::EmptyValueTag;
         DataFormat fillFormat = DataFormatJS;
         switch (info.registerFormat()) {
         case DataFormatInt32:
@@ -185,8 +192,8 @@ void SpeculativeJIT::cachedGetById(
     if (slowPathTarget.isSet())
         slowCases.append(slowPathTarget);
     slowCases.append(gen.slowPathJump());
-    
-    OwnPtr<SlowPathGenerator> slowPath;
+
+    std::unique_ptr<SlowPathGenerator> slowPath;
     if (baseTagGPROrNone == InvalidGPRReg) {
         slowPath = slowPathCall(
             slowCases, this, operationGetByIdOptimize,
@@ -199,9 +206,9 @@ void SpeculativeJIT::cachedGetById(
             JSValueRegs(resultTagGPR, resultPayloadGPR), gen.stubInfo(), baseTagGPROrNone,
             basePayloadGPR, identifierUID(identifierNumber));
     }
-    
+
     m_jit.addGetById(gen, slowPath.get());
-    addSlowPathGenerator(slowPath.release());
+    addSlowPathGenerator(WTF::move(slowPath));
 }
 
 void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
@@ -218,12 +225,12 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR,
         slowCases.append(slowPathTarget);
     slowCases.append(gen.slowPathJump());
 
-    OwnPtr<SlowPathGenerator> slowPath = slowPathCall(
+    auto slowPath = slowPathCall(
         slowCases, this, gen.slowPathFunction(), NoResult, gen.stubInfo(), valueTagGPR,
         valuePayloadGPR, basePayloadGPR, identifierUID(identifierNumber));
 
     m_jit.addPutById(gen, slowPath.get());
-    addSlowPathGenerator(slowPath.release());
+    addSlowPathGenerator(WTF::move(slowPath));
 }
 
 void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert)
@@ -239,7 +246,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
     JITCompiler::Jump notMasqueradesAsUndefined;   
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(arg.jsValueRegs());
+            notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
         
         m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultPayloadGPR);
         notMasqueradesAsUndefined = m_jit.jump();
@@ -248,7 +255,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
         GPRTemporary remoteGlobalObject(this);
 
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(arg.jsValueRegs());
+            notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
         
         JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(
             JITCompiler::NonZero, 
@@ -273,8 +280,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
         notCell.link(&m_jit);
         // null or undefined?
         COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
-        m_jit.move(argTagGPR, resultPayloadGPR);
-        m_jit.or32(TrustedImm32(1), resultPayloadGPR);
+        m_jit.or32(TrustedImm32(1), argTagGPR, resultPayloadGPR);
         m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultPayloadGPR, TrustedImm32(JSValue::NullTag), resultPayloadGPR);
 
         done.link(&m_jit);
@@ -308,7 +314,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
 
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(arg.jsValueRegs());
+            notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
         
         jump(invert ? taken : notTaken, ForceJump);
     } else {
@@ -316,7 +322,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
         GPRTemporary remoteGlobalObject(this);
 
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(arg.jsValueRegs());
+            notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
         
         branchTest8(JITCompiler::Zero, 
             JITCompiler::Address(argPayloadGPR, JSCell::typeInfoFlagsOffset()), 
@@ -337,8 +343,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
         notCell.link(&m_jit);
         // null or undefined?
         COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
-        m_jit.move(argTagGPR, resultGPR);
-        m_jit.or32(TrustedImm32(1), resultGPR);
+        m_jit.or32(TrustedImm32(1), argTagGPR, resultGPR);
         branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(JSValue::NullTag), taken);
     }
     
@@ -395,7 +400,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode,
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
 
         arg1.use();
@@ -486,7 +491,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultPayloadGPR = result.gpr();
     
         arg1.use();
@@ -511,10 +516,9 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler
         m_jit.compare32(cond, arg1PayloadGPR, arg2PayloadGPR, resultPayloadGPR);
     
         if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
-            addSlowPathGenerator(adoptPtr(
-                new CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>(
+            addSlowPathGenerator(std::make_unique<CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>>(
                     slowPath, this, helperFunction, resultPayloadGPR, arg1TagGPR,
-                    arg1PayloadGPR, arg2TagGPR, arg2PayloadGPR)));
+                    arg1PayloadGPR, arg2TagGPR, arg2PayloadGPR));
         }
         
         booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
@@ -637,46 +641,154 @@ void SpeculativeJIT::compileMiscStrictEq(Node* node)
 
 void SpeculativeJIT::emitCall(Node* node)
 {
-    if (node->op() != Call)
-        ASSERT(node->op() == Construct);
+    CallLinkInfo::CallType callType;
+    bool isVarargs = false;
+    bool isForwardVarargs = false;
+    switch (node->op()) {
+    case Call:
+        callType = CallLinkInfo::Call;
+        break;
+    case Construct:
+        callType = CallLinkInfo::Construct;
+        break;
+    case CallVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isVarargs = true;
+        break;
+    case ConstructVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isVarargs = true;
+        break;
+    case CallForwardVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isForwardVarargs = true;
+        break;
+    case ConstructForwardVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isForwardVarargs = true;
+        break;
+    default:
+        DFG_CRASH(m_jit.graph(), node, "bad node type");
+        break;
+    }
+
+    Edge calleeEdge = m_jit.graph().child(node, 0);
+    
+    // Gotta load the arguments somehow. Varargs is trickier.
+    if (isVarargs || isForwardVarargs) {
+        CallVarargsData* data = node->callVarargsData();
 
-    // For constructors, the this argument is not passed but we have to make space
-    // for it.
-    int dummyThisArgument = node->op() == Call ? 0 : 1;
+        GPRReg resultGPR;
+        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
+        
+        if (isForwardVarargs) {
+            flushRegisters();
+            use(node->child2());
+            
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            scratchGPR1 = JITCompiler::selectScratchGPR();
+            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
+            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
+            
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
+            JITCompiler::JumpList slowCase;
+            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+            JITCompiler::Jump done = m_jit.jump();
+            slowCase.link(&m_jit);
+            callOperation(operationThrowStackOverflowForVarargs);
+            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+            done.link(&m_jit);
+            resultGPR = scratchGPR2;
+        } else {
+            GPRReg argumentsPayloadGPR;
+            GPRReg argumentsTagGPR;
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+        
+            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
+                if (reservedGPR != InvalidGPRReg)
+                    lock(reservedGPR);
+                JSValueOperand arguments(this, node->child2());
+                argumentsTagGPR = arguments.tagGPR();
+                argumentsPayloadGPR = arguments.payloadGPR();
+                if (reservedGPR != InvalidGPRReg)
+                    unlock(reservedGPR);
+                flushRegisters();
+                
+                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
+                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
+                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
+            };
+            
+            loadArgumentsGPR(InvalidGPRReg);
+        
+            DFG_ASSERT(m_jit.graph(), node, isFlushed());
 
-    CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+            // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
+            // flushed.
+            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, numUsedStackSlots, data->firstVarArgOffset);
+            
+            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
+            // Reconstruct the arguments operand while preserving the callee frame.
+            loadArgumentsGPR(GPRInfo::returnValueGPR);
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
+            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
+            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
+            
+            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsTagGPR, argumentsPayloadGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
+            resultGPR = GPRInfo::returnValueGPR;
+        }
+            
+        m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
+        
+        DFG_ASSERT(m_jit.graph(), node, isFlushed());
+        
+        // We don't need the arguments array anymore.
+        if (isVarargs)
+            use(node->child2());
+
+        // Now set up the "this" argument.
+        JSValueOperand thisArgument(this, node->child3());
+        GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
+        GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
+        thisArgument.use();
+        
+        m_jit.store32(thisArgumentTagGPR, JITCompiler::calleeArgumentTagSlot(0));
+        m_jit.store32(thisArgumentPayloadGPR, JITCompiler::calleeArgumentPayloadSlot(0));
+    } else {        
+        // The call instruction's first child is either the function (normal call) or the
+        // receiver (method call). subsequent children are the arguments.
+        int numPassedArgs = node->numChildren() - 1;
+
+        m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), m_jit.calleeFramePayloadSlot(JSStack::ArgumentCount));
+        
+        for (int i = 0; i < numPassedArgs; i++) {
+            Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
+            JSValueOperand arg(this, argEdge);
+            GPRReg argTagGPR = arg.tagGPR();
+            GPRReg argPayloadGPR = arg.payloadGPR();
+            use(argEdge);
+            
+            m_jit.store32(argTagGPR, m_jit.calleeArgumentTagSlot(i));
+            m_jit.store32(argPayloadGPR, m_jit.calleeArgumentPayloadSlot(i));
+        }
+    }
 
-    Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
     JSValueOperand callee(this, calleeEdge);
     GPRReg calleeTagGPR = callee.tagGPR();
     GPRReg calleePayloadGPR = callee.payloadGPR();
     use(calleeEdge);
-
-    // The call instruction's first child is either the function (normal call) or the
-    // receiver (method call). subsequent children are the arguments.
-    int numPassedArgs = node->numChildren() - 1;
-    
-    int numArgs = numPassedArgs + dummyThisArgument;
-
-    m_jit.store32(MacroAssembler::TrustedImm32(numArgs), calleeFramePayloadSlot(JSStack::ArgumentCount));
-    m_jit.store32(calleePayloadGPR, calleeFramePayloadSlot(JSStack::Callee));
-    m_jit.store32(calleeTagGPR, calleeFrameTagSlot(JSStack::Callee));
-
-    for (int i = 0; i < numPassedArgs; i++) {
-        Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
-        JSValueOperand arg(this, argEdge);
-        GPRReg argTagGPR = arg.tagGPR();
-        GPRReg argPayloadGPR = arg.payloadGPR();
-        use(argEdge);
-
-        m_jit.store32(argTagGPR, calleeArgumentTagSlot(i + dummyThisArgument));
-        m_jit.store32(argPayloadGPR, calleeArgumentPayloadSlot(i + dummyThisArgument));
-    }
+    m_jit.store32(calleePayloadGPR, m_jit.calleeFramePayloadSlot(JSStack::Callee));
+    m_jit.store32(calleeTagGPR, m_jit.calleeFrameTagSlot(JSStack::Callee));
 
     flushRegisters();
 
-    GPRResult resultPayload(this);
-    GPRResult2 resultTag(this);
+    GPRFlushedCallResult resultPayload(this);
+    GPRFlushedCallResult2 resultTag(this);
     GPRReg resultPayloadGPR = resultPayload.gpr();
     GPRReg resultTagGPR = resultTag.gpr();
 
@@ -685,11 +797,10 @@ void SpeculativeJIT::emitCall(Node* node)
 
     m_jit.emitStoreCodeOrigin(node->origin.semantic);
     
-    slowPath.append(branchNotCell(callee.jsValueRegs()));
+    CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
+
+    slowPath.append(m_jit.branchIfNotCell(callee.jsValueRegs()));
     slowPath.append(m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck));
-    m_jit.loadPtr(MacroAssembler::Address(calleePayloadGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultPayloadGPR);
-    m_jit.storePtr(resultPayloadGPR, calleeFramePayloadSlot(JSStack::ScopeChain));
-    m_jit.storePtr(MacroAssembler::TrustedImm32(JSValue::CellTag), calleeFrameTagSlot(JSStack::ScopeChain));
 
     JITCompiler::Call fastCall = m_jit.nearCall();
 
@@ -709,7 +820,6 @@ void SpeculativeJIT::emitCall(Node* node)
         m_jit.move(calleePayloadGPR, GPRInfo::regT0);
         m_jit.move(calleeTagGPR, GPRInfo::regT1);
     }
-    CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
     m_jit.move(MacroAssembler::TrustedImmPtr(info), GPRInfo::regT2);
     JITCompiler::Call slowCall = m_jit.nearCall();
 
@@ -719,10 +829,12 @@ void SpeculativeJIT::emitCall(Node* node)
 
     jsValueResult(resultTagGPR, resultPayloadGPR, node, DataFormatJS, UseChildrenCalledExplicitly);
 
-    info->callType = callType;
-    info->codeOrigin = node->origin.semantic;
-    info->calleeGPR = calleePayloadGPR;
+    info->setUpCall(callType, node->origin.semantic, calleePayloadGPR);
     m_jit.addJSCall(fastCall, slowCall, targetToCheck, info);
+    
+    // If we were varargs, then after the calls are done, we need to reestablish our stack pointer.
+    if (isVarargs || isForwardVarargs)
+        m_jit.addPtr(TrustedImm32(m_jit.graph().stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, JITCompiler::stackPointerRegister);
 }
 
 template<bool strict>
@@ -731,22 +843,23 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
     ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
-    m_interpreter.filter(value, SpecInt32);
-    VirtualRegister virtualRegister = edge->virtualRegister();
-    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
-    if (edge->hasConstant() && !isInt32Constant(edge.node())) {
+    m_interpreter.filter(value, SpecInt32);
+    if (value.isClear()) {
         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
         returnFormat = DataFormatInt32;
         return allocate();
     }
-    
+
+    VirtualRegister virtualRegister = edge->virtualRegister();
+    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
+
     switch (info.registerFormat()) {
     case DataFormatNone: {
         if (edge->hasConstant()) {
-            ASSERT(isInt32Constant(edge.node()));
+            ASSERT(edge->isInt32Constant());
             GPRReg gpr = allocate();
-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
+            m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
             info.fillInt32(*m_stream, gpr);
             returnFormat = DataFormatInt32;
@@ -754,6 +867,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
         }
 
         DataFormat spillFormat = info.spillFormat();
+
         ASSERT_UNUSED(spillFormat, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
 
         // If we know this was spilled as an integer we can fill without checking.
@@ -799,10 +913,6 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
     case DataFormatJSDouble:
     case DataFormatJSCell:
     case DataFormatJSBoolean:
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        returnFormat = DataFormatInt32;
-        return allocate();
-
     case DataFormatDouble:
     case DataFormatStorage:
     default:
@@ -834,9 +944,9 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
     if (info.registerFormat() == DataFormatNone) {
 
         if (edge->hasConstant()) {
-            RELEASE_ASSERT(isNumberConstant(edge.node()));
+            RELEASE_ASSERT(edge->isNumberConstant());
             FPRReg fpr = fprAllocate();
-            m_jit.loadDouble(TrustedImmPtr(addressOfDoubleConstant(edge.node())), fpr);
+            m_jit.loadDouble(TrustedImmPtr(m_jit.addressOfDoubleConstant(edge.node())), fpr);
             m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
             info.fillDouble(*m_stream, fpr);
             return fpr;
@@ -861,27 +971,24 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
     ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
+
     m_interpreter.filter(value, SpecCell);
+    if (value.isClear()) {
+        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+        return allocate();
+    }
+
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
-        if (info.spillFormat() == DataFormatInt32) {
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-            return allocate();
-        }
-
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             GPRReg gpr = allocate();
-            if (jsValue.isCell()) {
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
-                info.fillCell(*m_stream, gpr);
-                return gpr;
-            }
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+            m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
+            info.fillCell(*m_stream, gpr);
             return gpr;
         }
 
@@ -918,7 +1025,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
         if (type & ~SpecCell) {
             speculationCheck(
                 BadType, JSValueRegs(tagGPR, payloadGPR), edge,
-                branchNotCell(info.jsValueRegs()));
+                m_jit.branchIfNotCell(info.jsValueRegs()));
         }
         m_gprs.unlock(tagGPR);
         m_gprs.release(tagGPR);
@@ -933,9 +1040,6 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
     case DataFormatJSDouble:
     case DataFormatJSBoolean:
     case DataFormatBoolean:
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        return allocate();
-
     case DataFormatDouble:
     case DataFormatStorage:
         RELEASE_ASSERT_NOT_REACHED();
@@ -950,27 +1054,24 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
 {
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
+
     m_interpreter.filter(value, SpecBoolean);
+    if (value.isClear()) {
+        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+        return allocate();
+    }
+
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
-        if (info.spillFormat() == DataFormatInt32) {
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-            return allocate();
-        }
-        
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             GPRReg gpr = allocate();
-            if (jsValue.isBoolean()) {
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
-                info.fillBoolean(*m_stream, gpr);
-                return gpr;
-            }
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+            m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
+            info.fillBoolean(*m_stream, gpr);
             return gpr;
         }
 
@@ -1014,9 +1115,6 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
     case DataFormatJSDouble:
     case DataFormatJSCell:
     case DataFormatCell:
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        return allocate();
-
     case DataFormatDouble:
     case DataFormatStorage:
         RELEASE_ASSERT_NOT_REACHED();
@@ -1053,36 +1151,24 @@ void SpeculativeJIT::compileObjectEquality(Node* node)
     
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
-        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(), 
+            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
-                MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
+                MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()),
                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
 
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
-        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(), 
+            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
+        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
             m_jit.branchTest8(
-                MacroAssembler::NonZero, 
-                MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()), 
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()),
                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
     }
     
@@ -1099,6 +1185,57 @@ void SpeculativeJIT::compileObjectEquality(Node* node)
     booleanResult(resultPayloadGPR, node);
 }
 
+void SpeculativeJIT::compileObjectStrictEquality(Edge objectChild, Edge otherChild)
+{
+    SpeculateCellOperand op1(this, objectChild);
+    JSValueOperand op2(this, otherChild);
+
+    GPRReg op1GPR = op1.gpr();
+    GPRReg op2GPR = op2.payloadGPR();
+
+    DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
+
+    GPRTemporary resultPayload(this, Reuse, op1);
+    GPRReg resultPayloadGPR = resultPayload.gpr();
+    
+    MacroAssembler::Jump op2CellJump = m_jit.branchIfCell(op2.jsValueRegs());
+    
+    m_jit.move(TrustedImm32(0), resultPayloadGPR);
+    MacroAssembler::Jump op2NotCellJump = m_jit.jump();
+    
+    // At this point we know that we can perform a straight-forward equality comparison on pointer
+    // values because we are doing strict equality.
+    op2CellJump.link(&m_jit);
+    m_jit.compare32(MacroAssembler::Equal, op1GPR, op2GPR, resultPayloadGPR);
+    
+    op2NotCellJump.link(&m_jit);
+    booleanResult(resultPayloadGPR, m_currentNode);
+}
+    
+void SpeculativeJIT::compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode)
+{
+    BasicBlock* taken = branchNode->branchData()->taken.block;
+    BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
+
+    SpeculateCellOperand op1(this, objectChild);
+    JSValueOperand op2(this, otherChild);
+    
+    GPRReg op1GPR = op1.gpr();
+    GPRReg op2GPR = op2.payloadGPR();
+
+    DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
+
+    branch32(MacroAssembler::NotEqual, op2.tagGPR(), TrustedImm32(JSValue::CellTag), notTaken);
+    
+    if (taken == nextBlock()) {
+        branch32(MacroAssembler::NotEqual, op1GPR, op2GPR, notTaken);
+        jump(taken);
+    } else {
+        branch32(MacroAssembler::Equal, op1GPR, op2GPR, taken);
+        jump(notTaken);
+    }
+}
+
 void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
 {
     SpeculateCellOperand op1(this, leftChild);
@@ -1115,16 +1252,10 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild, 
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1135,23 +1266,15 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
     
     // It seems that most of the time when programs do a == b where b may be either null/undefined
     // or an object, b is usually an object. Balance the branches to make that case fast.
-    MacroAssembler::Jump rightNotCell = branchNotCell(op2.jsValueRegs());
+    MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(op2.jsValueRegs());
     
     // We know that within this branch, rightChild must be a cell.
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2PayloadGPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2PayloadGPR));
         speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, 
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1170,8 +1293,7 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
     // We know that within this branch, rightChild must not be a cell. Check if that is enough to
     // prove that it is either null or undefined.
     if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
-        m_jit.move(op2TagGPR, resultGPR);
-        m_jit.or32(TrustedImm32(1), resultGPR);
+        m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
         
         typeCheck(
             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
@@ -1209,16 +1331,10 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1228,23 +1344,17 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
     
     // It seems that most of the time when programs do a == b where b may be either null/undefined
     // or an object, b is usually an object. Balance the branches to make that case fast.
-    MacroAssembler::Jump rightNotCell = branchNotCell(op2.jsValueRegs());
+    MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(op2.jsValueRegs());
     
     // We know that within this branch, rightChild must be a cell.
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(op2PayloadGPR));
     } else {
         DFG_TYPE_CHECK(
             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(op2PayloadGPR));
         speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1265,8 +1375,7 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
         jump(notTaken, ForceJump);
         
         rightNotCell.link(&m_jit);
-        m_jit.move(op2TagGPR, resultGPR);
-        m_jit.or32(TrustedImm32(1), resultGPR);
+        m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
         
         typeCheck(
             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
@@ -1325,23 +1434,15 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
         structureGPR = structure.gpr();
     }
 
-    MacroAssembler::Jump notCell = branchNotCell(value.jsValueRegs());
+    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(value.jsValueRegs());
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()),
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(valuePayloadGPR));
     } else {
-        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), structureGPR);
-
         DFG_TYPE_CHECK(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal,
-                structureGPR,
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(valuePayloadGPR));
 
         MacroAssembler::Jump isNotMasqueradesAsUndefined = 
             m_jit.branchTest8(
@@ -1349,6 +1450,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
                 MacroAssembler::Address(valuePayloadGPR, JSCell::typeInfoFlagsOffset()), 
                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined));
 
+        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), structureGPR);
         speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, 
             m_jit.branchPtr(
                 MacroAssembler::Equal, 
@@ -1364,8 +1466,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
  
     COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
-        m_jit.move(valueTagGPR, resultPayloadGPR);
-        m_jit.or32(TrustedImm32(1), resultPayloadGPR);
+        m_jit.or32(TrustedImm32(1), valueTagGPR, resultPayloadGPR);
         typeCheck(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
             m_jit.branch32(
@@ -1455,29 +1556,22 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, Ba
     GPRReg valuePayloadGPR = value.payloadGPR();
     GPRReg scratchGPR = scratch.gpr();
     
-    MacroAssembler::Jump notCell = branchNotCell(value.jsValueRegs());
+    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(value.jsValueRegs());
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         DFG_TYPE_CHECK(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), 
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(valuePayloadGPR));
     } else {
-        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
-
         DFG_TYPE_CHECK(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
-            m_jit.branchPtr(
-                MacroAssembler::Equal, 
-                scratchGPR,
-                MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+            m_jit.branchIfNotObject(valuePayloadGPR));
 
         JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
             JITCompiler::Zero, 
             MacroAssembler::Address(valuePayloadGPR, JSCell::typeInfoFlagsOffset()), 
             TrustedImm32(MasqueradesAsUndefined));
 
+        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
         speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
             m_jit.branchPtr(
                 MacroAssembler::Equal, 
@@ -1492,8 +1586,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, Ba
     
     COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
-        m_jit.move(valueTagGPR, scratchGPR);
-        m_jit.or32(TrustedImm32(1), scratchGPR);
+        m_jit.or32(TrustedImm32(1), valueTagGPR, scratchGPR);
         typeCheck(
             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
             m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
@@ -1532,7 +1625,12 @@ void SpeculativeJIT::emitBranch(Node* node)
         emitObjectOrOtherBranch(node->child1(), taken, notTaken);
         return;
     }
-    
+
+    case StringUse: {
+        emitStringBranch(node->child1(), taken, notTaken);
+        return;
+    }
+
     case DoubleRepUse:
     case Int32Use: {
         if (node->child1().useKind() == Int32Use) {
@@ -1675,20 +1773,32 @@ void SpeculativeJIT::compile(Node* node)
     switch (op) {
     case JSConstant:
     case DoubleConstant:
-        initConstantInfo(node);
-        break;
-
-    case PhantomArguments:
-        initConstantInfo(node);
-        break;
-
-    case WeakJSConstant:
-        m_jit.addWeakReference(node->weakConstant());
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         initConstantInfo(node);
         break;
 
     case Identity: {
-        RELEASE_ASSERT_NOT_REACHED();
+        speculate(node, node->child1());
+        switch (node->child1().useKind()) {
+        case DoubleRepUse:
+        case DoubleRepRealUse: {
+            SpeculateDoubleOperand op(this, node->child1());
+            doubleResult(op.fpr(), node);
+            break;
+        }
+        case Int52RepUse: 
+        case MachineIntUse:
+        case DoubleRepMachineIntUse: {
+            RELEASE_ASSERT_NOT_REACHED();   
+            break;
+        }
+        default: {
+            JSValueOperand op(this, node->child1());
+            jsValueResult(op.tagGPR(), op.payloadGPR(), node);
+            break;
+        }
+        } // switch
         break;
     }
 
@@ -1698,9 +1808,7 @@ void SpeculativeJIT::compile(Node* node)
         // If the CFA is tracking this variable and it found that the variable
         // cannot have been assigned, then don't attempt to proceed.
         if (value.isClear()) {
-            // FIXME: We should trap instead.
-            // https://bugs.webkit.org/show_bug.cgi?id=110383
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+            m_compileOkay = false;
             break;
         }
         
@@ -1750,8 +1858,7 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             GPRTemporary result(this);
             GPRTemporary tag(this);
             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
@@ -1782,13 +1889,18 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
-    case MovHint:
-    case ZombieHint:
-    case Check: {
-        RELEASE_ASSERT_NOT_REACHED();
+    case MovHint: {
+        compileMovHint(m_currentNode);
+        noResult(node);
         break;
     }
-
+        
+    case ZombieHint: {
+        recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
+        noResult(node);
+        break;
+    }
+        
     case SetLocal: {
         switch (node->variableAccessData()->flushFormat()) {
         case FlushedDouble: {
@@ -1827,8 +1939,7 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             JSValueOperand value(this, node->child1());
             m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
             m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->machineLocal()));
@@ -1855,18 +1966,18 @@ void SpeculativeJIT::compile(Node* node)
     case BitAnd:
     case BitOr:
     case BitXor:
-        if (isInt32Constant(node->child1().node())) {
+        if (node->child1()->isInt32Constant()) {
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this, Reuse, op2);
 
-            bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
+            bitOp(op, node->child1()->asInt32(), op2.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
-        } else if (isInt32Constant(node->child2().node())) {
+        } else if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
+            bitOp(op, node->child2()->asInt32(), op1.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -1885,11 +1996,11 @@ void SpeculativeJIT::compile(Node* node)
     case BitRShift:
     case BitLShift:
     case BitURShift:
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
+            shiftOp(op, op1.gpr(), node->child2()->asInt32() & 0x1f, result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -1942,8 +2053,8 @@ void SpeculativeJIT::compile(Node* node)
         
         flushRegisters();
         
-        GPRResult2 resultTag(this);
-        GPRResult resultPayload(this);
+        GPRFlushedCallResult2 resultTag(this);
+        GPRFlushedCallResult resultPayload(this);
         if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
             callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
         else
@@ -1957,6 +2068,10 @@ void SpeculativeJIT::compile(Node* node)
         compileAdd(node);
         break;
 
+    case ArithClz32:
+        compileArithClz32(node);
+        break;
+
     case MakeRope:
         compileMakeRope(node);
         break;
@@ -1983,6 +2098,11 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ArithPow: {
+        compileArithPow(node);
+        break;
+    }
+
     case ArithAbs: {
         switch (node->child1().useKind()) {
         case Int32Use: {
@@ -2086,17 +2206,11 @@ void SpeculativeJIT::compile(Node* node)
         }
         break;
     }
-        
-    case ArithSqrt: {
-        SpeculateDoubleOperand op1(this, node->child1());
-        FPRTemporary result(this, op1);
-        
-        m_jit.sqrtDouble(op1.fpr(), result.fpr());
-        
-        doubleResult(result.fpr(), node);
+
+    case ArithSqrt:
+        compileArithSqrt(node);
         break;
-    }
-        
+
     case ArithFRound: {
         SpeculateDoubleOperand op1(this, node->child1());
         FPRTemporary result(this, op1);
@@ -2108,6 +2222,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ArithRound:
+        compileArithRound(node);
+        break;
+
     case ArithSin: {
         SpeculateDoubleOperand op1(this, node->child1());
         FPRReg op1FPR = op1.fpr();
@@ -2132,6 +2250,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ArithLog:
+        compileArithLog(node);
+        break;
+
     case LogicalNot:
         compileLogicalNot(node);
         break;
@@ -2157,7 +2279,7 @@ void SpeculativeJIT::compile(Node* node)
         break;
         
     case CompareEqConstant:
-        ASSERT(isNullConstant(node->child2().node()));
+        ASSERT(node->child2()->asJSValue().isNull());
         if (nonSpeculativeCompareNull(node, node->child1()))
             return;
         break;
@@ -2204,7 +2326,9 @@ void SpeculativeJIT::compile(Node* node)
         case Array::SelectUsingPredictions:
         case Array::ForceExit:
             RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+#endif
             break;
         case Array::Generic: {
             SpeculateCellOperand base(this, node->child1()); // Save a register, speculate cell. We'll probably be right.
@@ -2214,8 +2338,8 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg propertyPayloadGPR = property.payloadGPR();
             
             flushRegisters();
-            GPRResult2 resultTag(this);
-            GPRResult resultPayload(this);
+            GPRFlushedCallResult2 resultTag(this);
+            GPRFlushedCallResult resultPayload(this);
             callOperation(operationGetByValCell, resultTag.gpr(), resultPayload.gpr(), baseGPR, propertyTagGPR, propertyPayloadGPR);
             
             jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
@@ -2237,21 +2361,46 @@ void SpeculativeJIT::compile(Node* node)
             
                 GPRTemporary resultPayload(this);
                 if (node->arrayMode().type() == Array::Int32) {
+                    ASSERT(!node->arrayMode().isSaneChain());
+                    
                     speculationCheck(
                         OutOfBounds, JSValueRegs(), 0,
                         m_jit.branch32(
                             MacroAssembler::Equal,
-                            MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
+                            MacroAssembler::BaseIndex(
+                                storageReg, propertyReg, MacroAssembler::TimesEight, TagOffset),
                             TrustedImm32(JSValue::EmptyValueTag)));
-                    m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
+                    m_jit.load32(
+                        MacroAssembler::BaseIndex(
+                            storageReg, propertyReg, MacroAssembler::TimesEight, PayloadOffset),
+                        resultPayload.gpr());
                     int32Result(resultPayload.gpr(), node);
                     break;
                 }
                 
                 GPRTemporary resultTag(this);
-                m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
-                speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
-                m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
+                m_jit.load32(
+                    MacroAssembler::BaseIndex(
+                        storageReg, propertyReg, MacroAssembler::TimesEight, TagOffset),
+                    resultTag.gpr());
+                m_jit.load32(
+                    MacroAssembler::BaseIndex(
+                        storageReg, propertyReg, MacroAssembler::TimesEight, PayloadOffset),
+                    resultPayload.gpr());
+                if (node->arrayMode().isSaneChain()) {
+                    JITCompiler::Jump notHole = m_jit.branch32(
+                        MacroAssembler::NotEqual, resultTag.gpr(),
+                        TrustedImm32(JSValue::EmptyValueTag));
+                    m_jit.move(TrustedImm32(JSValue::UndefinedTag), resultTag.gpr());
+                    m_jit.move(TrustedImm32(0), resultPayload.gpr());
+                    notHole.link(&m_jit);
+                } else {
+                    speculationCheck(
+                        LoadFromHole, JSValueRegs(), 0,
+                        m_jit.branch32(
+                            MacroAssembler::Equal, resultTag.gpr(),
+                            TrustedImm32(JSValue::EmptyValueTag)));
+                }
                 jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
                 break;
             }
@@ -2406,8 +2555,11 @@ void SpeculativeJIT::compile(Node* node)
         case Array::String:
             compileGetByValOnString(node);
             break;
-        case Array::Arguments:
-            compileGetByValOnArguments(node);
+        case Array::DirectArguments:
+            compileGetByValOnDirectArguments(node);
+            break;
+        case Array::ScopedArguments:
+            compileGetByValOnScopedArguments(node);
             break;
         default: {
             TypedArrayType type = node->arrayMode().typedArrayType();
@@ -2434,8 +2586,10 @@ void SpeculativeJIT::compile(Node* node)
         case Array::SelectUsingPredictions:
         case Array::ForceExit:
             RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
             alreadyHandled = true;
+#endif
             break;
         case Array::Generic: {
             ASSERT(node->op() == PutByVal || node->op() == PutByValDirect);
@@ -2584,12 +2738,6 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
             
-        case Array::Arguments:
-            // FIXME: we could at some point make this work. Right now we're assuming that the register
-            // pressure would be too great.
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-            
         default: {
             TypedArrayType type = arrayMode.typedArrayType();
             if (isInt(type))
@@ -2611,7 +2759,7 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg argumentGPR = argument.gpr();
             
             flushRegisters();
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
             
             // Must use jsValueResult because otherwise we screw up register
@@ -2626,8 +2774,8 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg argumentGPR = argument.gpr();
         
         flushRegisters();
-        GPRResult2 resultTag(this);
-        GPRResult resultPayload(this);
+        GPRFlushedCallResult2 resultTag(this);
+        GPRFlushedCallResult resultPayload(this);
         callOperation(operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentGPR);
         
         jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
@@ -2641,7 +2789,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg argumentGPR = argument.gpr();
         
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
         
         // If we add a DataFormatBool, we should use it here.
@@ -2962,6 +3110,18 @@ void SpeculativeJIT::compile(Node* node)
             
         case UntypedUse: {
             JSValueOperand value(this, node->child1());
+            
+            if (!m_interpreter.needsTypeCheck(node->child1(), SpecBoolInt32 | SpecBoolean)) {
+                GPRTemporary result(this);
+                
+                GPRReg valueGPR = value.payloadGPR();
+                GPRReg resultGPR = result.gpr();
+                
+                m_jit.move(valueGPR, resultGPR);
+                int32Result(result.gpr(), node);
+                break;
+            }
+            
             GPRTemporary resultTag(this);
             GPRTemporary resultPayload(this);
             
@@ -3007,8 +3167,8 @@ void SpeculativeJIT::compile(Node* node)
             m_jit.move(op1TagGPR, resultTagGPR);
             m_jit.move(op1PayloadGPR, resultPayloadGPR);
         } else {
-            MacroAssembler::Jump alreadyPrimitive = branchNotCell(op1.jsValueRegs());
-            MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureIDOffset()), MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+            MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(op1.jsValueRegs());
+            MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(op1PayloadGPR);
             
             alreadyPrimitive.link(&m_jit);
             m_jit.move(op1TagGPR, resultTagGPR);
@@ -3024,37 +3184,40 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case ToString: {
+    case ToString:
+    case CallStringConstructor: {
         if (node->child1().useKind() == UntypedUse) {
             JSValueOperand op1(this, node->child1());
             GPRReg op1PayloadGPR = op1.payloadGPR();
             GPRReg op1TagGPR = op1.tagGPR();
             
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
             
             flushRegisters();
             
             JITCompiler::Jump done;
             if (node->child1()->prediction() & SpecString) {
-                JITCompiler::Jump slowPath1 = branchNotCell(op1.jsValueRegs());
-                JITCompiler::Jump slowPath2 = m_jit.branchPtr(
-                    JITCompiler::NotEqual,
-                    JITCompiler::Address(op1PayloadGPR, JSCell::structureIDOffset()),
-                    TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+                JITCompiler::Jump slowPath1 = m_jit.branchIfNotCell(op1.jsValueRegs());
+                JITCompiler::Jump slowPath2 = m_jit.branchIfNotString(op1PayloadGPR);
                 m_jit.move(op1PayloadGPR, resultGPR);
                 done = m_jit.jump();
                 slowPath1.link(&m_jit);
                 slowPath2.link(&m_jit);
             }
-            callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
+            if (op == ToString)
+                callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
+            else {
+                ASSERT(op == CallStringConstructor);
+                callOperation(operationCallStringConstructor, resultGPR, op1TagGPR, op1PayloadGPR);
+            }
             if (done.isSet())
                 done.link(&m_jit);
             cellResult(resultGPR, node);
             break;
         }
         
-        compileToStringOnCell(node);
+        compileToStringOrCallStringConstructorOnCell(node);
         break;
     }
         
@@ -3139,7 +3302,7 @@ void SpeculativeJIT::compile(Node* node)
         
         if (!node->numChildren()) {
             flushRegisters();
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             callOperation(
                 operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
             cellResult(result.gpr(), node);
@@ -3214,7 +3377,7 @@ void SpeculativeJIT::compile(Node* node)
             m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
         }
 
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         
         callOperation(
             operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
@@ -3247,7 +3410,7 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg scratch2GPR = scratch2.gpr();
             
             MacroAssembler::JumpList slowCases;
-            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
+            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)));
             
             ASSERT((1 << 3) == sizeof(JSValue));
             m_jit.move(sizeGPR, scratchGPR);
@@ -3275,12 +3438,11 @@ void SpeculativeJIT::compile(Node* node)
                 done.link(&m_jit);
             }
             
-            addSlowPathGenerator(adoptPtr(
-                new CallArrayAllocatorWithVariableSizeSlowPathGenerator(
+            addSlowPathGenerator(std::make_unique<CallArrayAllocatorWithVariableSizeSlowPathGenerator>(
                     slowCases, this, operationNewArrayWithSize, resultGPR,
                     globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
                     globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage),
-                    sizeGPR)));
+                    sizeGPR));
             
             cellResult(resultGPR, node);
             break;
@@ -3289,10 +3451,10 @@ void SpeculativeJIT::compile(Node* node)
         SpeculateStrictInt32Operand size(this, node->child1());
         GPRReg sizeGPR = size.gpr();
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
         GPRReg structureGPR = selectScratchGPR(sizeGPR);
-        MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX));
+        MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
         m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())), structureGPR);
         MacroAssembler::Jump done = m_jit.jump();
         bigLength.link(&m_jit);
@@ -3342,7 +3504,7 @@ void SpeculativeJIT::compile(Node* node)
         }
         
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         
         callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()), node->startConstant(), node->numConstants());
         
@@ -3362,7 +3524,7 @@ void SpeculativeJIT::compile(Node* node)
             
             flushRegisters();
             
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
             
             JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
@@ -3383,8 +3545,8 @@ void SpeculativeJIT::compile(Node* node)
         
     case NewRegexp: {
         flushRegisters();
-        GPRResult resultPayload(this);
-        GPRResult2 resultTag(this);
+        GPRFlushedCallResult resultPayload(this);
+        GPRFlushedCallResult2 resultTag(this);
         
         callOperation(operationNewRegexp, resultTag.gpr(), resultPayload.gpr(), m_jit.codeBlock()->regexp(node->regexpIndex()));
         
@@ -3404,7 +3566,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg tempTagGPR = tempTag.gpr();
         
         MacroAssembler::JumpList slowCases;
-        slowCases.append(branchNotCell(thisValue.jsValueRegs()));
+        slowCases.append(m_jit.branchIfNotCell(thisValue.jsValueRegs()));
         slowCases.append(m_jit.branch8(
             MacroAssembler::NotEqual,
             MacroAssembler::Address(thisValuePayloadGPR, JSCell::typeInfoTypeOffset()),
@@ -3443,11 +3605,16 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg allocatorGPR = allocator.gpr();
         GPRReg structureGPR = structure.gpr();
         GPRReg scratchGPR = scratch.gpr();
+        // Rare data is only used to access the allocator & structure
+        // We can avoid using an additional GPR this way
+        GPRReg rareDataGPR = structureGPR;
         
         MacroAssembler::JumpList slowPath;
 
-        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
-        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
+        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfRareData()), rareDataGPR);
+        slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR));
+        m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
+        m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR));
         emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);
 
@@ -3457,12 +3624,6 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
-    case AllocationProfileWatchpoint:
-    case TypedArrayWatchpoint: {
-        noResult(node);
-        break;
-    }
-
     case NewObject: {
         GPRTemporary result(this);
         GPRTemporary allocator(this);
@@ -3494,90 +3655,44 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case GetScope: {
-        SpeculateCellOperand function(this, node->child1());
-        GPRTemporary result(this, Reuse, function);
-        m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
-        cellResult(result.gpr(), node);
-        break;
-    }
-        
-    case GetMyScope: {
+    case GetArgumentCount: {
         GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.loadPtr(JITCompiler::payloadFor(JSStack::ScopeChain), resultGPR);
-        cellResult(resultGPR, node);
+        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
+        int32Result(result.gpr(), node);
         break;
     }
         
-    case SkipTopScope: {
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this, Reuse, scope);
-        GPRReg resultGPR = result.gpr();
-        m_jit.move(scope.gpr(), resultGPR);
-        JITCompiler::Jump activationNotCreated =
-            m_jit.branchTestPtr(
-                JITCompiler::Zero,
-                JITCompiler::payloadFor(
-                    static_cast<VirtualRegister>(m_jit.graph().machineActivationRegister())));
-        m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
-        activationNotCreated.link(&m_jit);
-        cellResult(resultGPR, node);
+    case GetScope:
+        compileGetScope(node);
         break;
-    }
         
-    case SkipScope: {
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this, Reuse, scope);
-        m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSScope::offsetOfNext()), result.gpr());
-        cellResult(result.gpr(), node);
+    case SkipScope:
+        compileSkipScope(node);
         break;
-    }
-        
-    case GetClosureRegisters: {
-        if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
-            GPRTemporary result(this);
-            GPRReg resultGPR = result.gpr();
-            m_jit.move(TrustedImmPtr(registers), resultGPR);
-            storageResult(resultGPR, node);
-            break;
-        }
         
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg scopeGPR = scope.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
-        storageResult(resultGPR, node);
-        break;
-    }
     case GetClosureVar: {
-        StorageOperand registers(this, node->child1());
+        SpeculateCellOperand base(this, node->child1());
         GPRTemporary resultTag(this);
         GPRTemporary resultPayload(this);
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg resultTagGPR = resultTag.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
-        m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-        m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
+        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset), resultTagGPR);
+        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset), resultPayloadGPR);
         jsValueResult(resultTagGPR, resultPayloadGPR, node);
         break;
     }
+    
     case PutClosureVar: {
-        StorageOperand registers(this, node->child2());
-        JSValueOperand value(this, node->child3());
-        GPRTemporary scratchRegister(this);
+        SpeculateCellOperand base(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg valueTagGPR = value.tagGPR();
         GPRReg valuePayloadGPR = value.payloadGPR();
 
-        speculate(node, node->child1());
-
-        m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-        m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        m_jit.store32(valueTagGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset));
+        m_jit.store32(valuePayloadGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset));
         noResult(node);
         break;
     }
@@ -3615,7 +3730,7 @@ void SpeculativeJIT::compile(Node* node)
         
             base.use();
         
-            JITCompiler::Jump notCell = branchNotCell(base.jsValueRegs());
+            JITCompiler::Jump notCell = m_jit.branchIfNotCell(base.jsValueRegs());
         
             cachedGetById(node->origin.semantic, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
         
@@ -3642,8 +3757,8 @@ void SpeculativeJIT::compile(Node* node)
             
             GPRReg baseGPR = base.gpr();
 
-            GPRResult resultPayload(this);
-            GPRResult2 resultTag(this);
+            GPRFlushedCallResult resultPayload(this);
+            GPRFlushedCallResult2 resultTag(this);
             GPRReg resultPayloadGPR = resultPayload.gpr();
             GPRReg resultTagGPR = resultTag.gpr();
 
@@ -3662,8 +3777,8 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg baseTagGPR = base.tagGPR();
             GPRReg basePayloadGPR = base.payloadGPR();
 
-            GPRResult resultPayload(this);
-            GPRResult2 resultTag(this);
+            GPRFlushedCallResult resultPayload(this);
+            GPRFlushedCallResult2 resultTag(this);
             GPRReg resultPayloadGPR = resultPayload.gpr();
             GPRReg resultTagGPR = resultTag.gpr();
 
@@ -3671,7 +3786,7 @@ void SpeculativeJIT::compile(Node* node)
         
             flushRegisters();
         
-            JITCompiler::Jump notCell = branchNotCell(base.jsValueRegs());
+            JITCompiler::Jump notCell = m_jit.branchIfNotCell(base.jsValueRegs());
         
             cachedGetById(node->origin.semantic, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
         
@@ -3690,23 +3805,35 @@ void SpeculativeJIT::compile(Node* node)
         compileGetArrayLength(node);
         break;
         
-    case CheckFunction: {
-        SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+    case CheckCell: {
+        SpeculateCellOperand cell(this, node->child1());
+        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node->cellOperand()->cell()));
         noResult(node);
         break;
     }
 
-    case CheckExecutable: {
-        SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+    case CheckNotEmpty: {
+        JSValueOperand operand(this, node->child1());
+        GPRReg tagGPR = operand.tagGPR();
+        speculationCheck(TDZFailure, JSValueSource(), nullptr, m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::EmptyValueTag)));
         noResult(node);
         break;
     }
-        
-    case CheckStructure: {
-        SpeculateCellOperand base(this, node->child1());
-        
+
+    case GetExecutable: {
+        SpeculateCellOperand function(this, node->child1());
+        GPRTemporary result(this, Reuse, function);
+        GPRReg functionGPR = function.gpr();
+        GPRReg resultGPR = result.gpr();
+        speculateCellType(node->child1(), functionGPR, SpecFunction, JSFunctionType);
+        m_jit.loadPtr(JITCompiler::Address(functionGPR, JSFunction::offsetOfExecutable()), resultGPR);
+        cellResult(resultGPR, node);
+        break;
+    }
+        
+    case CheckStructure: {
+        SpeculateCellOperand base(this, node->child1());
+        
         ASSERT(node->structureSet().size());
         
         if (node->structureSet().size() == 1) {
@@ -3738,43 +3865,19 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case StructureTransitionWatchpoint: {
-        // There is a fascinating question here of what to do about array profiling.
-        // We *could* try to tell the OSR exit about where the base of the access is.
-        // The DFG will have kept it alive, though it may not be in a register, and
-        // we shouldn't really load it since that could be a waste. For now though,
-        // we'll just rely on the fact that when a watchpoint fires then that's
-        // quite a hint already.
-        
-        m_jit.addWeakReference(node->structure());
-        
-#if !ASSERT_DISABLED
-        SpeculateCellOperand op1(this, node->child1());
-        JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), TrustedImmPtr(node->structure()));
-        m_jit.abortWithReason(DFGIneffectiveWatchpoint);
-        isOK.link(&m_jit);
-#else
-        speculateCell(node->child1());
-#endif
-
-        noResult(node);
-        break;
-    }
-        
-    case PhantomPutStructure: {
-        ASSERT(isKnownCell(node->child1().node()));
-        m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
-        noResult(node);
-        break;
-    }
-
     case PutStructure: {
+        Structure* oldStructure = node->transition()->previous;
+        Structure* newStructure = node->transition()->next;
+
         m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
 
         SpeculateCellOperand base(this, node->child1());
         GPRReg baseGPR = base.gpr();
         
-        m_jit.storePtr(MacroAssembler::TrustedImmPtr(node->structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
+        ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
+        ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
+        ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
+        m_jit.storePtr(MacroAssembler::TrustedImmPtr(newStructure), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
         
         noResult(node);
         break;
@@ -3825,7 +3928,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg resultTagGPR = resultTag.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
         
-        StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
+        StorageAccessData& storageAccessData = node->storageAccessData();
         
         m_jit.load32(JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
         m_jit.load32(JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
@@ -3834,6 +3937,47 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
+    case GetGetterSetterByOffset: {
+        StorageOperand storage(this, node->child1());
+        GPRTemporary resultPayload(this);
+        
+        GPRReg storageGPR = storage.gpr();
+        GPRReg resultPayloadGPR = resultPayload.gpr();
+        
+        StorageAccessData& storageAccessData = node->storageAccessData();
+        
+        m_jit.load32(JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
+        
+        cellResult(resultPayloadGPR, node);
+        break;
+    }
+        
+    case GetGetter: {
+        SpeculateCellOperand op1(this, node->child1());
+        GPRTemporary result(this, Reuse, op1);
+        
+        GPRReg op1GPR = op1.gpr();
+        GPRReg resultGPR = result.gpr();
+        
+        m_jit.loadPtr(JITCompiler::Address(op1GPR, GetterSetter::offsetOfGetter()), resultGPR);
+        
+        cellResult(resultGPR, node);
+        break;
+    }
+        
+    case GetSetter: {
+        SpeculateCellOperand op1(this, node->child1());
+        GPRTemporary result(this, Reuse, op1);
+        
+        GPRReg op1GPR = op1.gpr();
+        GPRReg resultGPR = result.gpr();
+        
+        m_jit.loadPtr(JITCompiler::Address(op1GPR, GetterSetter::offsetOfSetter()), resultGPR);
+        
+        cellResult(resultGPR, node);
+        break;
+    }
+        
     case PutByOffset: {
         StorageOperand storage(this, node->child1());
         JSValueOperand value(this, node->child3());
@@ -3844,7 +3988,7 @@ void SpeculativeJIT::compile(Node* node)
 
         speculate(node, node->child2());
 
-        StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
+        StorageAccessData& storageAccessData = node->storageAccessData();
         
         m_jit.storePtr(valueTagGPR, JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
         m_jit.storePtr(valuePayloadGPR, JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
@@ -3906,7 +4050,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRTemporary resultPayload(this);
         GPRTemporary resultTag(this);
 
-        m_jit.move(TrustedImmPtr(node->registerPointer()), resultPayload.gpr());
+        m_jit.move(TrustedImmPtr(node->variablePointer()), resultPayload.gpr());
         m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTag.gpr());
         m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayload.gpr());
 
@@ -3915,51 +4059,25 @@ void SpeculativeJIT::compile(Node* node)
     }
 
     case PutGlobalVar: {
-        JSValueOperand value(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
         // FIXME: if we happen to have a spare register - and _ONLY_ if we happen to have
         // a spare register - a good optimization would be to put the register pointer into
         // a register and then do a zero offset store followed by a four-offset store (or
         // vice-versa depending on endianness).
-        m_jit.store32(value.tagGPR(), node->registerPointer()->tagPointer());
-        m_jit.store32(value.payloadGPR(), node->registerPointer()->payloadPointer());
+        m_jit.store32(value.tagGPR(), node->variablePointer()->tagPointer());
+        m_jit.store32(value.payloadGPR(), node->variablePointer()->payloadPointer());
 
         noResult(node);
         break;
     }
 
     case NotifyWrite: {
-        VariableWatchpointSet* set = node->variableWatchpointSet();
-    
-        JSValueOperand value(this, node->child1());
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-    
-        GPRTemporary temp(this);
-        GPRReg tempGPR = temp.gpr();
-    
-        m_jit.load8(set->addressOfState(), tempGPR);
-    
-        JITCompiler::Jump isDone = m_jit.branch32(JITCompiler::Equal, tempGPR, TrustedImm32(IsInvalidated));
-        JITCompiler::JumpList notifySlow;
-        notifySlow.append(m_jit.branch32(
-            JITCompiler::NotEqual,
-            JITCompiler::AbsoluteAddress(set->addressOfInferredValue()->payloadPointer()),
-            valuePayloadGPR));
-        notifySlow.append(m_jit.branch32(
-            JITCompiler::NotEqual, 
-            JITCompiler::AbsoluteAddress(set->addressOfInferredValue()->tagPointer()),
-            valueTagGPR));
-        addSlowPathGenerator(
-            slowPathCall(notifySlow, this, operationNotifyWrite, NoResult, set, valueTagGPR, valuePayloadGPR));
-        isDone.link(&m_jit);
-    
-        noResult(node);
+        compileNotifyWrite(node);
         break;
     }
 
-    case VarInjectionWatchpoint:
-    case VariableWatchpoint: {
+    case VarInjectionWatchpoint: {
         noResult(node);
         break;
     }
@@ -3989,7 +4107,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRTemporary localGlobalObject(this);
         GPRTemporary remoteGlobalObject(this);
 
-        JITCompiler::Jump isCell = branchIsCell(value.jsValueRegs());
+        JITCompiler::Jump isCell = m_jit.branchIfCell(value.jsValueRegs());
         
         m_jit.compare32(JITCompiler::Equal, value.tagGPR(), TrustedImm32(JSValue::UndefinedTag), result.gpr());
         JITCompiler::Jump done = m_jit.jump();
@@ -4045,7 +4163,7 @@ void SpeculativeJIT::compile(Node* node)
         JSValueOperand value(this, node->child1());
         GPRTemporary result(this, Reuse, value, TagWord);
         
-        JITCompiler::Jump isNotCell = branchNotCell(value.jsValueRegs());
+        JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(value.jsValueRegs());
         
         m_jit.compare8(JITCompiler::Equal, 
             JITCompiler::Address(value.payloadGPR(), JSCell::typeInfoTypeOffset()), 
@@ -4063,88 +4181,35 @@ void SpeculativeJIT::compile(Node* node)
 
     case IsObject: {
         JSValueOperand value(this, node->child1());
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        flushRegisters();
-        callOperation(operationIsObject, resultGPR, valueTagGPR, valuePayloadGPR);
+        GPRTemporary result(this, Reuse, value, TagWord);
+
+        JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(value.jsValueRegs());
+
+        m_jit.compare8(JITCompiler::AboveOrEqual,
+            JITCompiler::Address(value.payloadGPR(), JSCell::typeInfoTypeOffset()),
+            TrustedImm32(ObjectType),
+            result.gpr());
+        JITCompiler::Jump done = m_jit.jump();
+
+        isNotCell.link(&m_jit);
+        m_jit.move(TrustedImm32(0), result.gpr());
+
+        done.link(&m_jit);
         booleanResult(result.gpr(), node);
         break;
     }
 
+    case IsObjectOrNull: {
+        compileIsObjectOrNull(node);
+        break;
+    }
+
     case IsFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        flushRegisters();
-        callOperation(operationIsFunction, resultGPR, valueTagGPR, valuePayloadGPR);
-        booleanResult(result.gpr(), node);
+        compileIsFunction(node);
         break;
     }
     case TypeOf: {
-        JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
-        GPRReg tagGPR = value.tagGPR();
-        GPRReg payloadGPR = value.payloadGPR();
-        GPRTemporary temp(this);
-        GPRReg tempGPR = temp.gpr();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        JITCompiler::JumpList doneJumps;
-
-        flushRegisters();
-
-        ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
-
-        JITCompiler::Jump isNotCell = branchNotCell(value.jsValueRegs());
-        if (node->child1().useKind() != UntypedUse)
-            DFG_TYPE_CHECK(JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecCell, isNotCell);
-
-        if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
-            JITCompiler::Jump notString = m_jit.branch8(
-                JITCompiler::NotEqual, 
-                JITCompiler::Address(payloadGPR, JSCell::typeInfoTypeOffset()), 
-                TrustedImm32(StringType));
-            if (node->child1().useKind() == StringUse)
-                DFG_TYPE_CHECK(JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecString, notString);
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.stringString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            if (node->child1().useKind() != StringUse) {
-                notString.link(&m_jit);
-                callOperation(operationTypeOf, resultGPR, payloadGPR);
-                doneJumps.append(m_jit.jump());
-            }
-        } else {
-            callOperation(operationTypeOf, resultGPR, payloadGPR);
-            doneJumps.append(m_jit.jump());
-        }
-
-        if (node->child1().useKind() == UntypedUse) {
-            isNotCell.link(&m_jit);
-
-            m_jit.add32(TrustedImm32(1), tagGPR, tempGPR);
-            JITCompiler::Jump notNumber = m_jit.branch32(JITCompiler::AboveOrEqual, tempGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.numberString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notNumber.link(&m_jit);
-
-            JITCompiler::Jump notUndefined = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::UndefinedTag));
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.undefinedString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notUndefined.link(&m_jit);
-
-            JITCompiler::Jump notNull = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::NullTag));
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.objectString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notNull.link(&m_jit);
-
-            // Only boolean left
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.booleanString()), resultGPR);
-        }
-        doneJumps.link(&m_jit);
-        cellResult(resultGPR, node);
+        compileTypeOf(node);
         break;
     }
 
@@ -4153,433 +4218,410 @@ void SpeculativeJIT::compile(Node* node)
 
     case Call:
     case Construct:
+    case CallVarargs:
+    case CallForwardVarargs:
+    case ConstructVarargs:
+    case ConstructForwardVarargs:
         emitCall(node);
         break;
 
-    case CreateActivation: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary result(this, Reuse, value, PayloadWord);
+    case LoadVarargs: {
+        LoadVarargsData* data = node->loadVarargsData();
         
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRReg resultGPR = result.gpr();
+        GPRReg argumentsTagGPR;
+        GPRReg argumentsPayloadGPR;
+        {
+            JSValueOperand arguments(this, node->child1());
+            argumentsTagGPR = arguments.tagGPR();
+            argumentsPayloadGPR = arguments.payloadGPR();
+            flushRegisters();
+        }
         
-        m_jit.move(valuePayloadGPR, resultGPR);
+        callOperation(operationSizeOfVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, data->offset);
         
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+        lock(GPRInfo::returnValueGPR);
+        {
+            JSValueOperand arguments(this, node->child1());
+            argumentsTagGPR = arguments.tagGPR();
+            argumentsPayloadGPR = arguments.payloadGPR();
+            flushRegisters();
+        }
+        unlock(GPRInfo::returnValueGPR);
         
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationCreateActivation, resultGPR,
-                framePointerOffsetToGetActivationRegisters()));
+        // FIXME: There is a chance that we will call an effectful length property twice. This is safe
+        // from the standpoint of the VM's integrity, but it's subtly wrong from a spec compliance
+        // standpoint. The best solution would be one where we can exit *into* the op_call_varargs right
+        // past the sizing.
+        // https://bugs.webkit.org/show_bug.cgi?id=141448
+
+        GPRReg argCountIncludingThisGPR =
+            JITCompiler::selectScratchGPR(GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR);
         
-        cellResult(resultGPR, node);
-        break;
-    }
+        m_jit.add32(TrustedImm32(1), GPRInfo::returnValueGPR, argCountIncludingThisGPR);
+        speculationCheck(
+            VarargsOverflow, JSValueSource(), Edge(), m_jit.branch32(
+                MacroAssembler::Above,
+                argCountIncludingThisGPR,
+                TrustedImm32(data->limit)));
+        
+        m_jit.store32(argCountIncludingThisGPR, JITCompiler::payloadFor(data->machineCount));
+        
+        callOperation(operationLoadVarargs, data->machineStart.offset(), argumentsTagGPR, argumentsPayloadGPR, data->offset, GPRInfo::returnValueGPR, data->mandatoryMinimum);
         
-    case FunctionReentryWatchpoint: {
         noResult(node);
         break;
     }
         
-    case CreateArguments: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
-        GPRTemporary result(this, Reuse, value, PayloadWord);
-        
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRReg scratch1GPR = scratch1.gpr();
-        GPRReg scratch2GPR = scratch2.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valuePayloadGPR, resultGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-            addSlowPathGenerator(
-                slowPathCall(
-                    notCreated, this, operationCreateInlinedArguments, resultGPR,
-                    node->origin.semantic.inlineCallFrame));
-            cellResult(resultGPR, node);
-            break;
-        } 
-
-        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
-        if (m_jit.codeBlock()->hasSlowArguments()
-            || executable->isStrictMode() 
-            || !executable->parameterCount()) {
-            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-            addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
-            cellResult(resultGPR, node);
-            break;
-        }
-
-        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-
-        MacroAssembler::JumpList slowPaths;
-        emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
-            addSlowPathGenerator(
-                slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
-
-        alreadyCreated.link(&m_jit); 
-        cellResult(resultGPR, node);
+    case ForwardVarargs: {
+        compileForwardVarargs(node);
         break;
     }
         
-    case TearOffActivation: {
-        JSValueOperand activationValue(this, node->child1());
-        GPRTemporary scratch(this);
-        
-        GPRReg activationValueTagGPR = activationValue.tagGPR();
-        GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
-        GPRReg scratchGPR = scratch.gpr();
-
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-
-        SymbolTable* symbolTable = m_jit.symbolTableFor(node->origin.semantic);
-        int registersOffset = JSActivation::registersOffset(symbolTable);
-
-        int bytecodeCaptureStart = symbolTable->captureStart();
-        int machineCaptureStart = m_jit.graph().m_machineCaptureStart;
-        for (int i = symbolTable->captureCount(); i--;) {
-            m_jit.loadPtr(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                scratchGPR);
-            m_jit.storePtr(
-                scratchGPR, JITCompiler::Address(
-                    activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-            m_jit.loadPtr(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                scratchGPR);
-            m_jit.storePtr(
-                scratchGPR, JITCompiler::Address(
-                    activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        }
-        m_jit.addPtr(TrustedImm32(registersOffset), activationValuePayloadGPR, scratchGPR);
-        m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValuePayloadGPR, JSActivation::offsetOfRegisters()));
-        
-        notCreated.link(&m_jit);
-        noResult(node);
+    case CreateActivation: {
+        compileCreateActivation(node);
         break;
     }
         
-    case TearOffArguments: {
-        JSValueOperand unmodifiedArgumentsValue(this, node->child1());
-        JSValueOperand activationValue(this, node->child2());
-        GPRReg unmodifiedArgumentsValuePayloadGPR = unmodifiedArgumentsValue.payloadGPR();
-        GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
-        
-        JITCompiler::Jump created = m_jit.branchTest32(
-            JITCompiler::NonZero, unmodifiedArgumentsValuePayloadGPR);
+    case CreateDirectArguments: {
+        compileCreateDirectArguments(node);
+        break;
+    }
         
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffInlinedArguments, NoResult,
-                    unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR, node->origin.semantic.inlineCallFrame));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffArguments, NoResult,
-                    unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR));
-        }
+    case GetFromArguments: {
+        compileGetFromArguments(node);
+        break;
+    }
         
-        noResult(node);
+    case PutToArguments: {
+        compilePutToArguments(node);
         break;
     }
         
-    case CheckArgumentsNotCreated: {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
-        speculationCheck(
-            Uncountable, JSValueRegs(), 0,
-            m_jit.branch32(
-                JITCompiler::NotEqual,
-                JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                TrustedImm32(JSValue::EmptyValueTag)));
-        noResult(node);
+    case CreateScopedArguments: {
+        compileCreateScopedArguments(node);
         break;
     }
         
-    case GetMyArgumentsLength: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
+    case CreateClonedArguments: {
+        compileCreateClonedArguments(node);
+        break;
+    }
         
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::NotEqual,
-                    JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    TrustedImm32(JSValue::EmptyValueTag)));
-        }
+    case NewFunction:
+        compileNewFunction(node);
+        break;
         
-        ASSERT(!node->origin.semantic.inlineCallFrame);
-        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
-        m_jit.sub32(TrustedImm32(1), resultGPR);
+    case In:
+        compileIn(node);
+        break;
+
+    case StoreBarrier: {
+        compileStoreBarrier(node);
+        break;
+    }
+
+    case GetEnumerableLength: {
+        SpeculateCellOperand enumerator(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
         int32Result(resultGPR, node);
         break;
     }
-        
-    case GetMyArgumentsLengthSafe: {
+    case HasGenericProperty: {
+        JSValueOperand base(this, node->child1());
+        SpeculateCellOperand property(this, node->child2());
+        GPRFlushedCallResult resultPayload(this);
+        GPRFlushedCallResult2 resultTag(this);
+        GPRReg basePayloadGPR = base.payloadGPR();
+        GPRReg baseTagGPR = base.tagGPR();
+        GPRReg resultPayloadGPR = resultPayload.gpr();
+        GPRReg resultTagGPR = resultTag.gpr();
+
+        flushRegisters();
+        callOperation(operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, property.gpr());
+        booleanResult(resultPayloadGPR, node);
+        break;
+    }
+    case HasStructureProperty: {
+        JSValueOperand base(this, node->child1());
+        SpeculateCellOperand property(this, node->child2());
+        SpeculateCellOperand enumerator(this, node->child3());
         GPRTemporary resultPayload(this);
         GPRTemporary resultTag(this);
+
+        GPRReg baseTagGPR = base.tagGPR();
+        GPRReg basePayloadGPR = base.payloadGPR();
+        GPRReg propertyGPR = property.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
         GPRReg resultTagGPR = resultTag.gpr();
-        
-        JITCompiler::Jump created = m_jit.branch32(
-            JITCompiler::NotEqual,
-            JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-            TrustedImm32(JSValue::EmptyValueTag));
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            m_jit.move(
-                Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
-                resultPayloadGPR);
-        } else {
-            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultPayloadGPR);
-            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
-        }
-        m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR);
-        
-        // FIXME: the slow path generator should perform a forward speculation that the
-        // result is an integer. For now we postpone the speculation by having this return
-        // a JSValue.
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                created, this, operationGetArgumentsLength,
-                JSValueRegs(resultTagGPR, resultPayloadGPR),
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
-        
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
+
+        m_jit.load32(MacroAssembler::Address(basePayloadGPR, JSCell::structureIDOffset()), resultTagGPR);
+        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 
+            resultTagGPR,
+            MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset()));
+
+        moveTrueTo(resultPayloadGPR);
+        MacroAssembler::Jump done = m_jit.jump();
+
+        done.link(&m_jit);
+
+        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, propertyGPR));
+        booleanResult(resultPayloadGPR, node);
         break;
     }
-        
-    case GetMyArgumentByVal: {
-        SpeculateStrictInt32Operand index(this, node->child1());
+    case HasIndexedProperty: {
+        SpeculateCellOperand base(this, node->child1());
+        SpeculateInt32Operand index(this, node->child2());
         GPRTemporary resultPayload(this);
         GPRTemporary resultTag(this);
+
+        GPRReg baseGPR = base.gpr();
         GPRReg indexGPR = index.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
         GPRReg resultTagGPR = resultTag.gpr();
-        
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::NotEqual,
-                    JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    TrustedImm32(JSValue::EmptyValueTag)));
-        }
-            
-        m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
+
+        MacroAssembler::JumpList slowCases;
+        ArrayMode mode = node->arrayMode();
+        switch (mode.type()) {
+        case Array::Int32:
+        case Array::Contiguous: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            GPRTemporary scratch(this);
             
-        if (node->origin.semantic.inlineCallFrame) {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultPayloadGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
-        } else {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultPayloadGPR,
-                    JITCompiler::payloadFor(JSStack::ArgumentCount)));
+            GPRReg storageGPR = storage.gpr();
+            GPRReg scratchGPR = scratch.gpr();
+
+            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())));
+            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
+            slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag)));
+            break;
         }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
+        case Array::Double: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            FPRTemporary scratch(this);
+            FPRReg scratchFPR = scratch.fpr();
+            GPRReg storageGPR = storage.gpr();
 
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultPayloadGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultPayloadGPR);
+            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())));
+            m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR);
+            slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR));
+            break;
+        }
+        case Array::ArrayStorage: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            GPRTemporary scratch(this);
 
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                resultTagGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                resultPayloadGPR);
-            slowArgument.append(m_jit.jump());
+            GPRReg storageGPR = storage.gpr();
+            GPRReg scratchGPR = scratch.gpr();
+
+            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())));
+            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
+            slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag)));
+            break;
         }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-            resultTagGPR);
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-            resultPayloadGPR);
-            
-        slowArgument.link(&m_jit);
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
+        default: {
+            slowCases.append(m_jit.jump());
+            break;
+        }
+        }
+
+        moveTrueTo(resultPayloadGPR);
+        MacroAssembler::Jump done = m_jit.jump();
+
+        addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultTagGPR, resultPayloadGPR, baseGPR, indexGPR));
+        
+        done.link(&m_jit);
+        booleanResult(resultPayloadGPR, node);
         break;
     }
-    case GetMyArgumentByValSafe: {
-        SpeculateStrictInt32Operand index(this, node->child1());
+    case GetDirectPname: {
+        Edge& baseEdge = m_jit.graph().varArgChild(node, 0);
+        Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
+
+        SpeculateCellOperand base(this, baseEdge);
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRReg baseGPR = base.gpr();
+        GPRReg propertyGPR = property.gpr();
+
+#if CPU(X86)
+        GPRFlushedCallResult resultPayload(this);
+        GPRFlushedCallResult2 resultTag(this);
+        GPRTemporary scratch(this);
+
+        GPRReg resultTagGPR = resultTag.gpr();
+        GPRReg resultPayloadGPR = resultPayload.gpr();
+        GPRReg scratchGPR = scratch.gpr();
+
+        // Not enough registers on X86 for this code, so always use the slow path.
+        flushRegisters();
+        m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), scratchGPR);
+        callOperation(operationGetByValCell, resultTagGPR, resultPayloadGPR, baseGPR, scratchGPR, propertyGPR);
+#else
         GPRTemporary resultPayload(this);
         GPRTemporary resultTag(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
+        GPRTemporary scratch(this);
+
         GPRReg resultTagGPR = resultTag.gpr();
+        GPRReg resultPayloadGPR = resultPayload.gpr();
+        GPRReg scratchGPR = scratch.gpr();
+
+        Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
+        Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
+
+        SpeculateInt32Operand index(this, indexEdge);
+        SpeculateCellOperand enumerator(this, enumeratorEdge);
+
+        GPRReg indexGPR = index.gpr();
+        GPRReg enumeratorGPR = enumerator.gpr();
+
+        // Check the structure
+        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratchGPR);
+        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 
+            scratchGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
         
-        JITCompiler::JumpList slowPath;
-        slowPath.append(
-            m_jit.branch32(
-                JITCompiler::NotEqual,
-                JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                TrustedImm32(JSValue::EmptyValueTag)));
-        
-        m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
-        if (node->origin.semantic.inlineCallFrame) {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultPayloadGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
-        } else {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultPayloadGPR,
-                    JITCompiler::payloadFor(JSStack::ArgumentCount)));
-        }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
+        // Compute the offset
+        // If index is less than the enumerator's cached inline storage, then it's an inline access
+        MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual, 
+            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
 
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultPayloadGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                resultTagGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                resultPayloadGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-            resultTagGPR);
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-            resultPayloadGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetInlinedArgumentByVal,
-                    JSValueRegs(resultTagGPR, resultPayloadGPR),
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    node->origin.semantic.inlineCallFrame, indexGPR));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetArgumentByVal,
-                    JSValueRegs(resultTagGPR, resultPayloadGPR),
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    indexGPR));
-        }
+        m_jit.move(indexGPR, scratchGPR);
+        m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
+        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
+        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+
+        MacroAssembler::Jump done = m_jit.jump();
         
-        slowArgument.link(&m_jit);
+        // Otherwise it's out of line
+        outOfLineAccess.link(&m_jit);
+        m_jit.move(indexGPR, scratchGPR);
+        m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
+        m_jit.neg32(scratchGPR);
+        m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
+        // We use resultPayloadGPR as a temporary here. We have to make sure clobber it after getting the 
+        // value out of indexGPR and enumeratorGPR because resultPayloadGPR could reuse either of those registers.
+        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultPayloadGPR); 
+        int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
+        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
+        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+
+        done.link(&m_jit);
+
+        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByValCell, resultTagGPR, resultPayloadGPR, baseGPR, propertyGPR));
+#endif
+
         jsValueResult(resultTagGPR, resultPayloadGPR, node);
         break;
     }
-        
-    case NewFunctionNoCheck:
-        compileNewFunctionNoCheck(node);
+    case GetPropertyEnumerator: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+        callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
+        cellResult(resultGPR, node);
         break;
-        
-    case NewFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary resultTag(this, Reuse, value, TagWord);
-        GPRTemporary resultPayload(this, Reuse, value, PayloadWord);
-        
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
+    }
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname: {
+        SpeculateCellOperand enumerator(this, node->child1());
+        SpeculateInt32Operand index(this, node->child2());
+        GPRTemporary scratch(this);
+        GPRTemporary resultPayload(this);
+        GPRTemporary resultTag(this);
+
+        GPRReg enumeratorGPR = enumerator.gpr();
+        GPRReg indexGPR = index.gpr();
+        GPRReg scratchGPR = scratch.gpr();
         GPRReg resultTagGPR = resultTag.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
-        
-        m_jit.move(valuePayloadGPR, resultPayloadGPR);
-        m_jit.move(valueTagGPR, resultTagGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationNewFunction, JSValueRegs(resultTagGPR, resultPayloadGPR),
-                m_jit.codeBlock()->functionDecl(node->functionDeclIndex())));
-        
+
+        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
+            MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
+                ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
+                : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
+
+        m_jit.move(MacroAssembler::TrustedImm32(JSValue::NullTag), resultTagGPR);
+        m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR);
+
+        MacroAssembler::Jump done = m_jit.jump();
+        inBounds.link(&m_jit);
+
+        m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratchGPR);
+        m_jit.loadPtr(MacroAssembler::BaseIndex(scratchGPR, indexGPR, MacroAssembler::ScalePtr), resultPayloadGPR);
+        m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), resultTagGPR);
+
+        done.link(&m_jit);
         jsValueResult(resultTagGPR, resultPayloadGPR, node);
         break;
     }
-        
-    case NewFunctionExpression:
-        compileNewFunctionExpression(node);
-        break;
-        
-    case In:
-        compileIn(node);
+    case ToIndexString: {
+        SpeculateInt32Operand index(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+        callOperation(operationToIndexString, resultGPR, index.gpr());
+        cellResult(resultGPR, node);
         break;
+    }
+    case ProfileType: {
+        JSValueOperand value(this, node->child1());
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
+        GPRTemporary scratch3(this);
 
-    case StoreBarrier:
-    case StoreBarrierWithNullCheck: {
-        compileStoreBarrier(node);
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg scratch2GPR = scratch2.gpr();
+        GPRReg scratch3GPR = scratch3.gpr();
+
+        // Load the TypeProfilerLog into Scratch2.
+        TypeProfilerLog* cachedTypeProfilerLog = m_jit.vm()->typeProfilerLog();
+        m_jit.move(TrustedImmPtr(cachedTypeProfilerLog), scratch2GPR);
+
+        // Load the next LogEntry into Scratch1.
+        m_jit.loadPtr(MacroAssembler::Address(scratch2GPR, TypeProfilerLog::currentLogEntryOffset()), scratch1GPR);
+
+        // Store the JSValue onto the log entry.
+        m_jit.store32(value.tagGPR(), MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+        m_jit.store32(value.payloadGPR(), MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+
+        // Store the structureID of the cell if valueGPR is a cell, otherwise, store 0 on the log entry.
+        MacroAssembler::Jump isNotCell = m_jit.branchIfNotCell(value.jsValueRegs());
+        m_jit.load32(MacroAssembler::Address(value.payloadGPR(), JSCell::structureIDOffset()), scratch3GPR);
+        m_jit.store32(scratch3GPR, MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::structureIDOffset()));
+        MacroAssembler::Jump skipIsCell = m_jit.jump();
+        isNotCell.link(&m_jit);
+        m_jit.store32(TrustedImm32(0), MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::structureIDOffset()));
+        skipIsCell.link(&m_jit);
+
+        // Store the typeLocation on the log entry.
+        TypeLocation* cachedTypeLocation = node->typeLocation();
+        m_jit.move(TrustedImmPtr(cachedTypeLocation), scratch3GPR);
+        m_jit.storePtr(scratch3GPR, MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::locationOffset()));
+
+        // Increment the current log entry.
+        m_jit.addPtr(TrustedImm32(sizeof(TypeProfilerLog::LogEntry)), scratch1GPR);
+        m_jit.storePtr(scratch1GPR, MacroAssembler::Address(scratch2GPR, TypeProfilerLog::currentLogEntryOffset()));
+        MacroAssembler::Jump clearLog = m_jit.branchPtr(MacroAssembler::Equal, scratch1GPR, TrustedImmPtr(cachedTypeProfilerLog->logEndPtr()));
+        addSlowPathGenerator(
+            slowPathCall(clearLog, this, operationProcessTypeProfilerLogDFG, NoResult));
+
+        noResult(node);
+        break;
+    }
+    case ProfileControlFlow: {
+        BasicBlockLocation* basicBlockLocation = node->basicBlockLocation();
+        if (!basicBlockLocation->hasExecuted()) {
+            GPRTemporary scratch1(this);
+            basicBlockLocation->emitExecuteCode(m_jit, scratch1.gpr());
+        }
+        noResult(node);
         break;
     }
 
@@ -4606,7 +4648,7 @@ void SpeculativeJIT::compile(Node* node)
         break;
 
     case Phantom:
-    case HardPhantom:
+    case Check:
         DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
         noResult(node);
         break;
@@ -4619,7 +4661,8 @@ void SpeculativeJIT::compile(Node* node)
         // This is a no-op.
         noResult(node);
         break;
-
+        
+        
     case Unreachable:
         RELEASE_ASSERT_NOT_REACHED();
         break;
@@ -4627,11 +4670,11 @@ void SpeculativeJIT::compile(Node* node)
     case LastNodeType:
     case Phi:
     case Upsilon:
-    case GetArgument:
     case ExtractOSREntryLocal:
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
     case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter:
     case Int52Rep:
     case FiatInt52:
     case Int52Constant:
@@ -4639,7 +4682,22 @@ void SpeculativeJIT::compile(Node* node)
     case ArithIMul:
     case MultiGetByOffset:
     case MultiPutByOffset:
-        RELEASE_ASSERT_NOT_REACHED();
+    case NativeCall:
+    case NativeConstruct:
+    case CheckBadCell:
+    case BottomValue:
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case PutHint:
+    case CheckStructureImmediate:
+    case MaterializeNewObject:
+    case MaterializeCreateActivation:
+    case PutStack:
+    case KillStack:
+    case GetStack:
+    case GetMyArgumentByVal:
+        DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
         break;
     }
 
@@ -4657,57 +4715,15 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueTagGPR, Edge valu
     if (!isKnownCell(valueUse.node()))
         isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
 
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
+    JITCompiler::Jump ownerIsRememberedOrInEden = m_jit.jumpIfIsRememberedOrInEden(ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
-
-    if (!isKnownCell(valueUse.node()))
-        isNotCell.link(&m_jit);
-}
-
-void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueTagGPR, Edge valueUse, GPRReg scratch1, GPRReg scratch2)
-{
-    JITCompiler::Jump isNotCell;
-    if (!isKnownCell(valueUse.node()))
-        isNotCell = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
-
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(owner);
-    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
+    ownerIsRememberedOrInEden.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);
 }
 #endif // ENABLE(GGC)
 
-JITCompiler::Jump SpeculativeJIT::branchIsCell(JSValueRegs regs)
-{
-    return m_jit.branch32(MacroAssembler::Equal, regs.tagGPR(), TrustedImm32(JSValue::CellTag));
-}
-
-JITCompiler::Jump SpeculativeJIT::branchNotCell(JSValueRegs regs)
-{
-    return m_jit.branch32(MacroAssembler::NotEqual, regs.tagGPR(), TrustedImm32(JSValue::CellTag));
-}
-
-JITCompiler::Jump SpeculativeJIT::branchIsOther(JSValueRegs regs, GPRReg tempGPR)
-{
-    m_jit.move(regs.tagGPR(), tempGPR);
-    m_jit.or32(TrustedImm32(1), tempGPR);
-    return m_jit.branch32(
-        MacroAssembler::Equal, tempGPR,
-        MacroAssembler::TrustedImm32(JSValue::NullTag));
-}
-
-JITCompiler::Jump SpeculativeJIT::branchNotOther(JSValueRegs regs, GPRReg tempGPR)
-{
-    m_jit.move(regs.tagGPR(), tempGPR);
-    m_jit.or32(TrustedImm32(1), tempGPR);
-    return m_jit.branch32(
-        MacroAssembler::NotEqual, tempGPR,
-        MacroAssembler::TrustedImm32(JSValue::NullTag));
-}
-
 void SpeculativeJIT::moveTrueTo(GPRReg gpr)
 {
     m_jit.move(TrustedImm32(1), gpr);
index eb117964b15cfa8257f9d0d773078f73564d680e..2c78f9a2213859f7cd8d0ef017e561549f194d78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
 #include "ArrayPrototype.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
+#include "GetterSetter.h"
 #include "JSCInlines.h"
+#include "JSEnvironmentRecord.h"
+#include "JSLexicalEnvironment.h"
+#include "JSPropertyNameEnumerator.h"
 #include "ObjectPrototype.h"
+#include "SetupVarargsFrame.h"
 #include "SpillRegistersMode.h"
+#include "TypeProfilerLog.h"
 
 namespace JSC { namespace DFG {
 
@@ -79,21 +85,9 @@ GPRReg SpeculativeJIT::fillJSValue(Edge edge)
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            if (isInt32Constant(edge.node())) {
-                info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
-                JSValue jsValue = jsNumber(valueOfInt32Constant(edge.node()));
-                m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
-            } else if (isNumberConstant(edge.node())) {
-                info.fillJSValue(*m_stream, gpr, DataFormatJSDouble);
-                JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(edge.node()));
-                m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
-            } else {
-                ASSERT(isJSConstant(edge.node()));
-                JSValue jsValue = valueOfJSConstant(edge.node());
-                m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
-                info.fillJSValue(*m_stream, gpr, DataFormatJS);
-            }
-
+            JSValue jsValue = edge->asJSValue();
+            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
+            info.fillJSValue(*m_stream, gpr, DataFormatJS);
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
         } else {
             DataFormat spillFormat = info.spillFormat();
@@ -108,7 +102,7 @@ GPRReg SpeculativeJIT::fillJSValue(Edge edge)
                 
             default:
                 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
-                RELEASE_ASSERT(spillFormat & DataFormatJS);
+                DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat & DataFormatJS);
                 break;
             }
             info.fillJSValue(*m_stream, gpr, spillFormat);
@@ -148,10 +142,10 @@ GPRReg SpeculativeJIT::fillJSValue(Edge edge)
     case DataFormatDouble:
     case DataFormatInt52:
         // this type currently never occurs
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
         
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
         return InvalidGPRReg;
     }
 }
@@ -168,12 +162,12 @@ void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg
         slowCases.append(slowPathTarget);
     slowCases.append(gen.slowPathJump());
     
-    OwnPtr<SlowPathGenerator> slowPath = slowPathCall(
+    auto slowPath = slowPathCall(
         slowCases, this, operationGetByIdOptimize, resultGPR, gen.stubInfo(), baseGPR,
         identifierUID(identifierNumber), spillMode);
     
     m_jit.addGetById(gen, slowPath.get());
-    addSlowPathGenerator(slowPath.release());
+    addSlowPathGenerator(WTF::move(slowPath));
 }
 
 void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
@@ -189,12 +183,12 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg
         slowCases.append(slowPathTarget);
     slowCases.append(gen.slowPathJump());
     
-    OwnPtr<SlowPathGenerator> slowPath = slowPathCall(
+    auto slowPath = slowPathCall(
         slowCases, this, gen.slowPathFunction(), NoResult, gen.stubInfo(), valueGPR, baseGPR,
         identifierUID(identifierNumber));
 
     m_jit.addPutById(gen, slowPath.get());
-    addSlowPathGenerator(slowPath.release());
+    addSlowPathGenerator(WTF::move(slowPath));
 }
 
 void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert)
@@ -210,7 +204,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
     JITCompiler::Jump notMasqueradesAsUndefined;
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(JSValueRegs(argGPR));
+            notCell = m_jit.branchIfNotCell(JSValueRegs(argGPR));
 
         m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultGPR);
         notMasqueradesAsUndefined = m_jit.jump();
@@ -220,7 +214,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
         GPRTemporary scratch(this);
 
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(JSValueRegs(argGPR));
+            notCell = m_jit.branchIfNotCell(JSValueRegs(argGPR));
         
         JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(
             JITCompiler::NonZero, 
@@ -279,7 +273,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
     
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(JSValueRegs(argGPR));
+            notCell = m_jit.branchIfNotCell(JSValueRegs(argGPR));
         
         jump(invert ? taken : notTaken, ForceJump);
     } else {
@@ -288,7 +282,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
         GPRTemporary scratch(this);
 
         if (!isKnownCell(operand.node()))
-            notCell = branchNotCell(JSValueRegs(argGPR));
+            notCell = m_jit.branchIfNotCell(JSValueRegs(argGPR));
         
         branchTest8(JITCompiler::Zero, 
             JITCompiler::Address(argGPR, JSCell::typeInfoFlagsOffset()), 
@@ -322,7 +316,7 @@ bool SpeculativeJIT::nonSpeculativeCompareNull(Node* node, Edge operand, bool in
     if (branchIndexInBlock != UINT_MAX) {
         Node* branchNode = m_block->at(branchIndexInBlock);
 
-        RELEASE_ASSERT(node->adjustedRefCount() == 1);
+        DFG_ASSERT(m_jit.graph(), node, node->adjustedRefCount() == 1);
         
         nonSpeculativePeepholeBranchNull(operand, branchNode, invert);
     
@@ -364,7 +358,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode,
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
     
         arg1.use();
@@ -447,7 +441,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
     
         arg1.use();
@@ -474,9 +468,8 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler
         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
         
         if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
-            addSlowPathGenerator(adoptPtr(
-                new CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>(
-                    slowPath, this, helperFunction, resultGPR, arg1GPR, arg2GPR)));
+            addSlowPathGenerator(std::make_unique<CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>>(
+                slowPath, this, helperFunction, resultGPR, arg1GPR, arg2GPR));
         }
 
         jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
@@ -606,11 +599,9 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
         
         m_jit.move(JITCompiler::TrustedImm64(JSValue::encode(jsBoolean(!invert))), resultGPR);
         
-        addSlowPathGenerator(
-            adoptPtr(
-                new CompareAndBoxBooleanSlowPathGenerator<MacroAssembler::JumpList>(
+        addSlowPathGenerator(std::make_unique<CompareAndBoxBooleanSlowPathGenerator<MacroAssembler::JumpList>>(
                     slowPathCases, this, operationCompareStrictEq, resultGPR, arg1GPR,
-                    arg2GPR)));
+                    arg2GPR));
         
         done.link(&m_jit);
     }
@@ -636,41 +627,144 @@ void SpeculativeJIT::compileMiscStrictEq(Node* node)
 
 void SpeculativeJIT::emitCall(Node* node)
 {
-    if (node->op() != Call)
-        RELEASE_ASSERT(node->op() == Construct);
+    CallLinkInfo::CallType callType;
+    bool isVarargs = false;
+    bool isForwardVarargs = false;
+    switch (node->op()) {
+    case Call:
+        callType = CallLinkInfo::Call;
+        break;
+    case Construct:
+        callType = CallLinkInfo::Construct;
+        break;
+    case CallVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isVarargs = true;
+        break;
+    case ConstructVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isVarargs = true;
+        break;
+    case CallForwardVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isForwardVarargs = true;
+        break;
+    case ConstructForwardVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isForwardVarargs = true;
+        break;
+    default:
+        DFG_CRASH(m_jit.graph(), node, "bad node type");
+        break;
+    }
 
-    // For constructors, the this argument is not passed but we have to make space
-    // for it.
-    int dummyThisArgument = node->op() == Call ? 0 : 1;
-    
-    CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+    Edge calleeEdge = m_jit.graph().child(node, 0);
     
-    Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
-    JSValueOperand callee(this, calleeEdge);
-    GPRReg calleeGPR = callee.gpr();
-    use(calleeEdge);
-    
-    // The call instruction's first child is the function; the subsequent children are the
-    // arguments.
-    int numPassedArgs = node->numChildren() - 1;
-    
-    int numArgs = numPassedArgs + dummyThisArgument;
-    
-    m_jit.store32(MacroAssembler::TrustedImm32(numArgs), calleeFramePayloadSlot(JSStack::ArgumentCount));
-    m_jit.store64(calleeGPR, calleeFrameSlot(JSStack::Callee));
+    // Gotta load the arguments somehow. Varargs is trickier.
+    if (isVarargs || isForwardVarargs) {
+        CallVarargsData* data = node->callVarargsData();
+
+        GPRReg resultGPR;
+        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
+        
+        if (isForwardVarargs) {
+            flushRegisters();
+            use(node->child2());
+            
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            scratchGPR1 = JITCompiler::selectScratchGPR();
+            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
+            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
+            
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
+            JITCompiler::JumpList slowCase;
+            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+            JITCompiler::Jump done = m_jit.jump();
+            slowCase.link(&m_jit);
+            callOperation(operationThrowStackOverflowForVarargs);
+            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+            done.link(&m_jit);
+            resultGPR = scratchGPR2;
+        } else {
+            GPRReg argumentsGPR;
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
+                if (reservedGPR != InvalidGPRReg)
+                    lock(reservedGPR);
+                JSValueOperand arguments(this, node->child2());
+                argumentsGPR = arguments.gpr();
+                if (reservedGPR != InvalidGPRReg)
+                    unlock(reservedGPR);
+                flushRegisters();
+                
+                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsGPR, reservedGPR);
+                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, reservedGPR);
+                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, scratchGPR2, reservedGPR);
+            };
+            
+            loadArgumentsGPR(InvalidGPRReg);
+            
+            DFG_ASSERT(m_jit.graph(), node, isFlushed());
+            
+            // Right now, arguments is in argumentsGPR and the register file is flushed.
+            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsGPR, numUsedStackSlots, data->firstVarArgOffset);
+            
+            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
+            // Reconstruct the arguments operand while preserving the callee frame.
+            loadArgumentsGPR(GPRInfo::returnValueGPR);
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
+            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
+            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
+            
+            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
+            resultGPR = GPRInfo::returnValueGPR;
+        }
+        
+        m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
+        
+        DFG_ASSERT(m_jit.graph(), node, isFlushed());
+        
+        // We don't need the arguments array anymore.
+        if (isVarargs)
+            use(node->child2());
+
+        // Now set up the "this" argument.
+        JSValueOperand thisArgument(this, node->child3());
+        GPRReg thisArgumentGPR = thisArgument.gpr();
+        thisArgument.use();
+        
+        m_jit.store64(thisArgumentGPR, JITCompiler::calleeArgumentSlot(0));
+    } else {
+        // The call instruction's first child is the function; the subsequent children are the
+        // arguments.
+        int numPassedArgs = node->numChildren() - 1;
+
+        m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), JITCompiler::calleeFramePayloadSlot(JSStack::ArgumentCount));
     
-    for (int i = 0; i < numPassedArgs; i++) {
-        Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
-        JSValueOperand arg(this, argEdge);
-        GPRReg argGPR = arg.gpr();
-        use(argEdge);
+        for (int i = 0; i < numPassedArgs; i++) {
+            Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
+            JSValueOperand arg(this, argEdge);
+            GPRReg argGPR = arg.gpr();
+            use(argEdge);
         
-        m_jit.store64(argGPR, calleeArgumentSlot(i + dummyThisArgument));
+            m_jit.store64(argGPR, JITCompiler::calleeArgumentSlot(i));
+        }
     }
 
+    JSValueOperand callee(this, calleeEdge);
+    GPRReg calleeGPR = callee.gpr();
+    callee.use();
+    m_jit.store64(calleeGPR, JITCompiler::calleeFrameSlot(JSStack::Callee));
+    
     flushRegisters();
 
-    GPRResult result(this);
+    GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
 
     JITCompiler::DataLabelPtr targetToCheck;
@@ -678,11 +772,10 @@ void SpeculativeJIT::emitCall(Node* node)
 
     m_jit.emitStoreCodeOrigin(node->origin.semantic);
     
+    CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo();
+    
     slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(0));
 
-    m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultGPR);
-    m_jit.store64(resultGPR, calleeFrameSlot(JSStack::ScopeChain));
-
     JITCompiler::Call fastCall = m_jit.nearCall();
 
     JITCompiler::Jump done = m_jit.jump();
@@ -690,7 +783,6 @@ void SpeculativeJIT::emitCall(Node* node)
     slowPath.link(&m_jit);
     
     m_jit.move(calleeGPR, GPRInfo::regT0); // Callee needs to be in regT0
-    CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo();
     m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2
     JITCompiler::Call slowCall = m_jit.nearCall();
     
@@ -700,11 +792,12 @@ void SpeculativeJIT::emitCall(Node* node)
     
     jsValueResult(resultGPR, m_currentNode, DataFormatJS, UseChildrenCalledExplicitly);
     
-    callLinkInfo->callType = callType;
-    callLinkInfo->codeOrigin = m_currentNode->origin.semantic;
-    callLinkInfo->calleeGPR = calleeGPR;
-    
+    callLinkInfo->setUpCall(callType, m_currentNode->origin.semantic,  calleeGPR);    
     m_jit.addJSCall(fastCall, slowCall, targetToCheck, callLinkInfo);
+    
+    // If we were varargs, then after the calls are done, we need to reestablish our stack pointer.
+    if (isVarargs || isForwardVarargs)
+        m_jit.addPtr(TrustedImm32(m_jit.graph().stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, JITCompiler::stackPointerRegister);
 }
 
 // Clang should allow unreachable [[clang::fallthrough]] in template functions if any template expansion uses it
@@ -721,28 +814,25 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
     ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
-    m_interpreter.filter(value, SpecInt32);
-    VirtualRegister virtualRegister = edge->virtualRegister();
-    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
-    if (edge->hasConstant() && !isInt32Constant(edge.node())) {
-        // Protect the silent spill/fill logic by failing early. If we "speculate" on
-        // the constant then the silent filler may think that we have an int32 and a
-        // constant, so it will try to fill this as an int32 constant. Bad things will
-        // happen.
+    m_interpreter.filter(value, SpecInt32);
+    if (value.isClear()) {
         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
         returnFormat = DataFormatInt32;
         return allocate();
     }
-    
+
+    VirtualRegister virtualRegister = edge->virtualRegister();
+    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
+
     switch (info.registerFormat()) {
     case DataFormatNone: {
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-            ASSERT(isInt32Constant(edge.node()));
-            m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
+            ASSERT(edge->isInt32Constant());
+            m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
             info.fillInt32(*m_stream, gpr);
             returnFormat = DataFormatInt32;
             return gpr;
@@ -750,7 +840,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
         
         DataFormat spillFormat = info.spillFormat();
         
-        RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
+        DFG_ASSERT(m_jit.graph(), m_currentNode, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
         
         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
         
@@ -780,7 +870,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
     }
 
     case DataFormatJS: {
-        RELEASE_ASSERT(!(type & SpecInt52));
+        DFG_ASSERT(m_jit.graph(), m_currentNode, !(type & SpecInt52));
         // Check the value is an integer.
         GPRReg gpr = info.gpr();
         m_gprs.lock(gpr);
@@ -833,20 +923,15 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnF
     case DataFormatCell:
     case DataFormatBoolean:
     case DataFormatJSCell:
-    case DataFormatJSBoolean: {
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        returnFormat = DataFormatInt32;
-        return allocate();
-    }
-
+    case DataFormatJSBoolean:
     case DataFormatDouble:
     case DataFormatStorage:
     case DataFormatInt52:
     case DataFormatStrictInt52:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
         
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
         return InvalidGPRReg;
     }
 }
@@ -863,7 +948,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt32Strict(Edge edge)
 {
     DataFormat mustBeDataFormatInt32;
     GPRReg result = fillSpeculateInt32Internal<true>(edge, mustBeDataFormatInt32);
-    RELEASE_ASSERT(mustBeDataFormatInt32 == DataFormatInt32);
+    DFG_ASSERT(m_jit.graph(), m_currentNode, mustBeDataFormatInt32 == DataFormatInt32);
     return result;
 }
 
@@ -871,21 +956,22 @@ GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)
 {
     ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
     AbstractValue& value = m_state.forNode(edge);
+
     m_interpreter.filter(value, SpecMachineInt);
+    if (value.isClear()) {
+        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+        return allocate();
+    }
+
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
-        if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt())) {
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-            return allocate();
-        }
-        
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
+            JSValue jsValue = edge->asJSValue();
             ASSERT(jsValue.isMachineInt());
             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
             int64_t value = jsValue.asMachineInt();
@@ -898,7 +984,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)
         
         DataFormat spillFormat = info.spillFormat();
         
-        RELEASE_ASSERT(spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
+        DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
         
         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
         
@@ -950,7 +1036,7 @@ GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)
     }
 
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
         return InvalidGPRReg;
     }
 }
@@ -966,9 +1052,9 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
         if (edge->hasConstant()) {
             GPRReg gpr = allocate();
 
-            if (isNumberConstant(edge.node())) {
+            if (edge->isNumberConstant()) {
                 FPRReg fpr = fprAllocate();
-                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(edge.node()))), gpr);
+                m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(edge->asNumber())), gpr);
                 m_jit.move64ToDouble(gpr, fpr);
                 unlock(gpr);
 
@@ -981,7 +1067,13 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
         }
         
         DataFormat spillFormat = info.spillFormat();
-        RELEASE_ASSERT(spillFormat == DataFormatDouble);
+        if (spillFormat != DataFormatDouble) {
+            DFG_CRASH(
+                m_jit.graph(), m_currentNode, toCString(
+                    "Expected ", edge, " to have double format but instead it is spilled as ",
+                    dataFormatToString(spillFormat)).data());
+        }
+        DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatDouble);
         FPRReg fpr = fprAllocate();
         m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
@@ -989,7 +1081,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
         return fpr;
     }
 
-    RELEASE_ASSERT(info.registerFormat() == DataFormatDouble);
+    DFG_ASSERT(m_jit.graph(), m_currentNode, info.registerFormat() == DataFormatDouble);
     FPRReg fpr = info.fpr();
     m_fprs.lock(fpr);
     return fpr;
@@ -1000,7 +1092,13 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
     ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
+
     m_interpreter.filter(value, SpecCell);
+    if (value.isClear()) {
+        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+        return allocate();
+    }
+
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
@@ -1009,28 +1107,19 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
-            if (jsValue.isCell()) {
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
-                info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
-                return gpr;
-            }
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-            return gpr;
-        }
-        
-        if (!(info.spillFormat() & DataFormatJS)) {
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+            JSValue jsValue = edge->asJSValue();
+            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
+            info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
             return gpr;
         }
-        
+
         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
 
         info.fillJSValue(*m_stream, gpr, DataFormatJS);
         if (type & ~SpecCell)
-            speculationCheck(BadType, JSValueRegs(gpr), edge, branchNotCell(JSValueRegs(gpr)));
+            speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchIfNotCell(JSValueRegs(gpr)));
         info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
         return gpr;
     }
@@ -1040,7 +1129,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
         GPRReg gpr = info.gpr();
         m_gprs.lock(gpr);
         if (!ASSERT_DISABLED) {
-            MacroAssembler::Jump checkCell = branchIsCell(JSValueRegs(gpr));
+            MacroAssembler::Jump checkCell = m_jit.branchIfCell(JSValueRegs(gpr));
             m_jit.abortWithReason(DFGIsNotCell);
             checkCell.link(&m_jit);
         }
@@ -1051,7 +1140,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
         GPRReg gpr = info.gpr();
         m_gprs.lock(gpr);
         if (type & ~SpecCell)
-            speculationCheck(BadType, JSValueRegs(gpr), edge, branchNotCell(JSValueRegs(gpr)));
+            speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchIfNotCell(JSValueRegs(gpr)));
         info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
         return gpr;
     }
@@ -1060,19 +1149,15 @@ GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
     case DataFormatInt32:
     case DataFormatJSDouble:
     case DataFormatJSBoolean:
-    case DataFormatBoolean: {
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        return allocate();
-    }
-
+    case DataFormatBoolean:
     case DataFormatDouble:
     case DataFormatStorage:
     case DataFormatInt52:
     case DataFormatStrictInt52:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
         
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
         return InvalidGPRReg;
     }
 }
@@ -1081,31 +1166,28 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
 {
     AbstractValue& value = m_state.forNode(edge);
     SpeculatedType type = value.m_type;
+
     m_interpreter.filter(value, SpecBoolean);
+    if (value.isClear()) {
+        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+        return allocate();
+    }
+
     VirtualRegister virtualRegister = edge->virtualRegister();
     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
-        if (info.spillFormat() == DataFormatInt32) {
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-            return allocate();
-        }
-        
         GPRReg gpr = allocate();
 
         if (edge->hasConstant()) {
-            JSValue jsValue = valueOfJSConstant(edge.node());
-            if (jsValue.isBoolean()) {
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
-                info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
-                return gpr;
-            }
-            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+            JSValue jsValue = edge->asJSValue();
+            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
+            info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
             return gpr;
         }
-        RELEASE_ASSERT(info.spillFormat() & DataFormatJS);
+        DFG_ASSERT(m_jit.graph(), m_currentNode, info.spillFormat() & DataFormatJS);
         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
 
@@ -1143,17 +1225,14 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
     case DataFormatJSDouble:
     case DataFormatJSCell:
     case DataFormatCell:
-        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
-        return allocate();
-        
     case DataFormatDouble:
     case DataFormatStorage:
     case DataFormatInt52:
     case DataFormatStrictInt52:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
         
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
         return InvalidGPRReg;
     }
 }
@@ -1187,21 +1266,12 @@ void SpeculativeJIT::compileObjectEquality(Node* node)
    
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1209,10 +1279,7 @@ void SpeculativeJIT::compileObjectEquality(Node* node)
                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
 
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1230,6 +1297,47 @@ void SpeculativeJIT::compileObjectEquality(Node* node)
     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
 }
 
+void SpeculativeJIT::compileObjectStrictEquality(Edge objectChild, Edge otherChild)
+{
+    SpeculateCellOperand op1(this, objectChild);
+    JSValueOperand op2(this, otherChild);
+    GPRTemporary result(this);
+
+    GPRReg op1GPR = op1.gpr();
+    GPRReg op2GPR = op2.gpr();
+    GPRReg resultGPR = result.gpr();
+
+    DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
+
+    // At this point we know that we can perform a straight-forward equality comparison on pointer
+    // values because we are doing strict equality.
+    m_jit.compare64(MacroAssembler::Equal, op1GPR, op2GPR, resultGPR);
+    m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+    jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
+}
+    
+void SpeculativeJIT::compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode)
+{
+    BasicBlock* taken = branchNode->branchData()->taken.block;
+    BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
+    
+    SpeculateCellOperand op1(this, objectChild);
+    JSValueOperand op2(this, otherChild);
+    
+    GPRReg op1GPR = op1.gpr();
+    GPRReg op2GPR = op2.gpr();
+    
+    DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
+
+    if (taken == nextBlock()) {
+        branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR, notTaken);
+        jump(taken);
+    } else {
+        branchPtr(MacroAssembler::Equal, op1GPR, op2GPR, taken);
+        jump(notTaken);
+    }
+}
+
 void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
 {
     SpeculateCellOperand op1(this, leftChild);
@@ -1245,16 +1353,10 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1264,21 +1366,15 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
     
     // It seems that most of the time when programs do a == b where b may be either null/undefined
     // or an object, b is usually an object. Balance the branches to make that case fast.
-    MacroAssembler::Jump rightNotCell = branchNotCell(JSValueRegs(op2GPR));
+    MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(JSValueRegs(op2GPR));
     
     // We know that within this branch, rightChild must be a cell. 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2GPR));
         speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1335,16 +1431,10 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));
+            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild, 
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1354,21 +1444,15 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
 
     // It seems that most of the time when programs do a == b where b may be either null/undefined
     // or an object, b is usually an object. Balance the branches to make that case fast.
-    MacroAssembler::Jump rightNotCell = branchNotCell(JSValueRegs(op2GPR));
+    MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(JSValueRegs(op2GPR));
     
     // We know that within this branch, rightChild must be a cell. 
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2GPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2GPR));
         speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
             m_jit.branchTest8(
                 MacroAssembler::NonZero, 
@@ -1487,19 +1571,13 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
         scratchGPR = scratch.gpr();
     }
 
-    MacroAssembler::Jump notCell = branchNotCell(JSValueRegs(valueGPR));
+    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
     if (masqueradesAsUndefinedWatchpointValid) {
         DFG_TYPE_CHECK(
-            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal,
-                MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()), 
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
 
         MacroAssembler::Jump isNotMasqueradesAsUndefined = 
             m_jit.branchTest8(
@@ -1617,7 +1695,7 @@ void SpeculativeJIT::compileLogicalNot(Node* node)
         return compileStringZeroLength(node);
 
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), node, "Bad use kind");
         break;
     }
 }
@@ -1637,19 +1715,13 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, Ba
         structureGPR = structure.gpr();
     }
 
-    MacroAssembler::Jump notCell = branchNotCell(JSValueRegs(valueGPR));
+    MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
         DFG_TYPE_CHECK(
-            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));                
+            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
     } else {
         DFG_TYPE_CHECK(
-            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
-                MacroAssembler::Equal, 
-                MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
-                m_jit.vm()->stringStructure.get()));
+            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
 
         JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
             JITCompiler::Zero, 
@@ -1718,6 +1790,11 @@ void SpeculativeJIT::emitBranch(Node* node)
         return;
     }
 
+    case StringUse: {
+        emitStringBranch(node->child1(), taken, notTaken);
+        return;
+    }
+
     case UntypedUse:
     case BooleanUse: {
         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
@@ -1772,7 +1849,7 @@ void SpeculativeJIT::emitBranch(Node* node)
     }
         
     default:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), m_currentNode, "Bad use kind");
     }
 }
 
@@ -1788,21 +1865,38 @@ void SpeculativeJIT::compile(Node* node)
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         initConstantInfo(node);
         break;
 
-    case PhantomArguments:
-        initConstantInfo(node);
-        break;
-
-    case WeakJSConstant:
-        m_jit.addWeakReference(node->weakConstant());
-        initConstantInfo(node);
-        break;
-        
     case Identity: {
-        // CSE should always eliminate this.
-        RELEASE_ASSERT_NOT_REACHED();
+        speculate(node, node->child1());
+        switch (node->child1().useKind()) {
+        case DoubleRepUse:
+        case DoubleRepRealUse:
+        case DoubleRepMachineIntUse: {
+            SpeculateDoubleOperand op(this, node->child1());
+            FPRTemporary scratch(this, op);
+            m_jit.moveDouble(op.fpr(), scratch.fpr());
+            doubleResult(scratch.fpr(), node);
+            break;
+        }
+        case Int52RepUse: {
+            SpeculateInt52Operand op(this, node->child1());
+            GPRTemporary result(this, Reuse, op);
+            m_jit.move(op.gpr(), result.gpr());
+            int52Result(result.gpr(), node);
+            break;
+        }
+        default: {
+            JSValueOperand op(this, node->child1());
+            GPRTemporary result(this, Reuse, op);
+            m_jit.move(op.gpr(), result.gpr());
+            jsValueResult(result.gpr(), node);
+            break;
+        }
+        } // switch
         break;
     }
 
@@ -1812,9 +1906,7 @@ void SpeculativeJIT::compile(Node* node)
         // If the CFA is tracking this variable and it found that the variable
         // cannot have been assigned, then don't attempt to proceed.
         if (value.isClear()) {
-            // FIXME: We should trap instead.
-            // https://bugs.webkit.org/show_bug.cgi?id=110383
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+            m_compileOkay = false;
             break;
         }
         
@@ -1882,13 +1974,18 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case MovHint:
-    case ZombieHint:
-    case Check: {
-        RELEASE_ASSERT_NOT_REACHED();
+    case MovHint: {
+        compileMovHint(m_currentNode);
+        noResult(node);
+        break;
+    }
+        
+    case ZombieHint: {
+        recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
+        noResult(node);
         break;
     }
-
+        
     case SetLocal: {
         switch (node->variableAccessData()->flushFormat()) {
         case FlushedDouble: {
@@ -1935,8 +2032,7 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             JSValueOperand value(this, node->child1());
             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
             noResult(node);
@@ -1945,7 +2041,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad flush format");
             break;
         }
 
@@ -1963,18 +2059,18 @@ void SpeculativeJIT::compile(Node* node)
     case BitAnd:
     case BitOr:
     case BitXor:
-        if (isInt32Constant(node->child1().node())) {
+        if (node->child1()->isInt32Constant()) {
             SpeculateInt32Operand op2(this, node->child2());
             GPRTemporary result(this, Reuse, op2);
 
-            bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
+            bitOp(op, node->child1()->asInt32(), op2.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
-        } else if (isInt32Constant(node->child2().node())) {
+        } else if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
+            bitOp(op, node->child2()->asInt32(), op1.gpr(), result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -1993,11 +2089,11 @@ void SpeculativeJIT::compile(Node* node)
     case BitRShift:
     case BitLShift:
     case BitURShift:
-        if (isInt32Constant(node->child2().node())) {
+        if (node->child2()->isInt32Constant()) {
             SpeculateInt32Operand op1(this, node->child1());
             GPRTemporary result(this, Reuse, op1);
 
-            shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
+            shiftOp(op, op1.gpr(), node->child2()->asInt32() & 0x1f, result.gpr());
 
             int32Result(result.gpr(), node);
         } else {
@@ -2052,7 +2148,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         case MachineIntUse: {
-            GPRResult result(this);
+            GPRTemporary result(this);
             GPRReg resultGPR = result.gpr();
             
             convertMachineInt(node->child1(), resultGPR);
@@ -2065,7 +2161,7 @@ void SpeculativeJIT::compile(Node* node)
             SpeculateDoubleOperand value(this, node->child1());
             FPRReg valueFPR = value.fpr();
             
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
             
             flushRegisters();
@@ -2083,7 +2179,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
         }
         break;
     }
@@ -2097,7 +2193,7 @@ void SpeculativeJIT::compile(Node* node)
         
         flushRegisters();
         
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
         else
@@ -2110,6 +2206,10 @@ void SpeculativeJIT::compile(Node* node)
     case ArithAdd:
         compileAdd(node);
         break;
+
+    case ArithClz32:
+        compileArithClz32(node);
+        break;
         
     case MakeRope:
         compileMakeRope(node);
@@ -2163,7 +2263,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
@@ -2230,22 +2330,20 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
     }
-        
-    case ArithSqrt: {
-        SpeculateDoubleOperand op1(this, node->child1());
-        FPRTemporary result(this, op1);
-        
-        m_jit.sqrtDouble(op1.fpr(), result.fpr());
-        
-        doubleResult(result.fpr(), node);
+
+    case ArithPow:
+        compileArithPow(node);
         break;
-    }
-        
+
+    case ArithSqrt:
+        compileArithSqrt(node);
+        break;
+
     case ArithFRound: {
         SpeculateDoubleOperand op1(this, node->child1());
         FPRTemporary result(this, op1);
@@ -2257,6 +2355,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ArithRound:
+        compileArithRound(node);
+        break;
+
     case ArithSin: {
         SpeculateDoubleOperand op1(this, node->child1());
         FPRReg op1FPR = op1.fpr();
@@ -2281,6 +2383,10 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ArithLog:
+        compileArithLog(node);
+        break;
+
     case LogicalNot:
         compileLogicalNot(node);
         break;
@@ -2306,7 +2412,7 @@ void SpeculativeJIT::compile(Node* node)
         break;
         
     case CompareEqConstant:
-        ASSERT(isNullConstant(node->child2().node()));
+        ASSERT(node->child2()->asJSValue().isNull());
         if (nonSpeculativeCompareNull(node, node->child1()))
             return;
         break;
@@ -2352,8 +2458,7 @@ void SpeculativeJIT::compile(Node* node)
         switch (node->arrayMode().type()) {
         case Array::SelectUsingPredictions:
         case Array::ForceExit:
-            RELEASE_ASSERT_NOT_REACHED();
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+            DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
             break;
         case Array::Generic: {
             JSValueOperand base(this, node->child1());
@@ -2362,7 +2467,7 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg propertyGPR = property.gpr();
             
             flushRegisters();
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
             
             jsValueResult(result.gpr(), node);
@@ -2384,7 +2489,17 @@ void SpeculativeJIT::compile(Node* node)
                 
                 GPRTemporary result(this);
                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr());
-                speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
+                if (node->arrayMode().isSaneChain()) {
+                    ASSERT(node->arrayMode().type() == Array::Contiguous);
+                    JITCompiler::Jump notHole = m_jit.branchTest64(
+                        MacroAssembler::NonZero, result.gpr());
+                    m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), result.gpr());
+                    notHole.link(&m_jit);
+                } else {
+                    speculationCheck(
+                        LoadFromHole, JSValueRegs(), 0,
+                        m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
+                }
                 jsValueResult(result.gpr(), node, node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
                 break;
             }
@@ -2527,8 +2642,11 @@ void SpeculativeJIT::compile(Node* node)
         case Array::String:
             compileGetByValOnString(node);
             break;
-        case Array::Arguments:
-            compileGetByValOnArguments(node);
+        case Array::DirectArguments:
+            compileGetByValOnDirectArguments(node);
+            break;
+        case Array::ScopedArguments:
+            compileGetByValOnScopedArguments(node);
             break;
         default: {
             TypedArrayType type = node->arrayMode().typedArrayType();
@@ -2554,12 +2672,10 @@ void SpeculativeJIT::compile(Node* node)
         switch (arrayMode.type()) {
         case Array::SelectUsingPredictions:
         case Array::ForceExit:
-            RELEASE_ASSERT_NOT_REACHED();
-            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
-            alreadyHandled = true;
+            DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
             break;
         case Array::Generic: {
-            RELEASE_ASSERT(node->op() == PutByVal);
+            DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal || node->op() == PutByValDirect);
             
             JSValueOperand arg1(this, child1);
             JSValueOperand arg2(this, child2);
@@ -2760,47 +2876,6 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
             
-        case Array::Arguments: {
-            JSValueOperand value(this, child3);
-            GPRTemporary scratch(this);
-            GPRTemporary scratch2(this);
-            
-            GPRReg valueReg = value.gpr();
-            GPRReg scratchReg = scratch.gpr();
-            GPRReg scratch2Reg = scratch2.gpr();
-            
-            if (!m_compileOkay)
-                return;
-
-            // Two really lame checks.
-            speculationCheck(
-                Uncountable, JSValueSource(), 0,
-                m_jit.branch32(
-                    MacroAssembler::AboveOrEqual, propertyReg,
-                    MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
-            speculationCheck(
-                Uncountable, JSValueSource(), 0,
-                m_jit.branchTestPtr(
-                    MacroAssembler::NonZero,
-                    MacroAssembler::Address(
-                        baseReg, Arguments::offsetOfSlowArgumentData())));
-
-            m_jit.move(propertyReg, scratch2Reg);
-            m_jit.signExtend32ToPtr(scratch2Reg, scratch2Reg);
-            m_jit.loadPtr(
-                MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
-                scratchReg);
-            
-            m_jit.store64(
-                valueReg,
-                MacroAssembler::BaseIndex(
-                    scratchReg, scratch2Reg, MacroAssembler::TimesEight,
-                    CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)));
-            
-            noResult(node);
-            break;
-        }
-            
         default: {
             TypedArrayType type = arrayMode.typedArrayType();
             if (isInt(type))
@@ -2822,7 +2897,7 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg argumentGPR = argument.gpr();
             
             flushRegisters();
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
             
             // Must use jsValueResult because otherwise we screw up register
@@ -2837,7 +2912,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg argumentGPR = argument.gpr();
         
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         callOperation(operationRegExpExec, result.gpr(), baseGPR, argumentGPR);
         
         jsValueResult(result.gpr(), node);
@@ -2851,7 +2926,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg argumentGPR = argument.gpr();
         
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
         
         // If we add a DataFormatBool, we should use it here.
@@ -3117,6 +3192,13 @@ void SpeculativeJIT::compile(Node* node)
             JSValueOperand value(this, node->child1());
             GPRTemporary result(this);
             
+            if (!m_interpreter.needsTypeCheck(node->child1(), SpecBoolInt32 | SpecBoolean)) {
+                m_jit.move(value.gpr(), result.gpr());
+                m_jit.and32(TrustedImm32(1), result.gpr());
+                int32Result(result.gpr(), node);
+                break;
+            }
+            
             m_jit.move(value.gpr(), result.gpr());
             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
             JITCompiler::Jump isBoolean = m_jit.branchTest64(
@@ -3132,14 +3214,14 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
     }
         
     case ToPrimitive: {
-        RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
+        DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
         JSValueOperand op1(this, node->child1());
         GPRTemporary result(this, Reuse, op1);
         
@@ -3148,11 +3230,8 @@ void SpeculativeJIT::compile(Node* node)
         
         op1.use();
         
-        MacroAssembler::Jump alreadyPrimitive = branchNotCell(JSValueRegs(op1GPR));
-        MacroAssembler::Jump notPrimitive = m_jit.branchStructurePtr(
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()), 
-            m_jit.vm()->stringStructure.get());
+        MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(JSValueRegs(op1GPR));
+        MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(op1GPR);
         
         alreadyPrimitive.link(&m_jit);
         m_jit.move(op1GPR, resultGPR);
@@ -3164,36 +3243,39 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case ToString: {
+    case ToString:
+    case CallStringConstructor: {
         if (node->child1().useKind() == UntypedUse) {
             JSValueOperand op1(this, node->child1());
             GPRReg op1GPR = op1.gpr();
             
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
             
             flushRegisters();
             
             JITCompiler::Jump done;
             if (node->child1()->prediction() & SpecString) {
-                JITCompiler::Jump slowPath1 = branchNotCell(JSValueRegs(op1GPR));
-                JITCompiler::Jump slowPath2 = m_jit.branchStructurePtr(
-                    JITCompiler::NotEqual,
-                    JITCompiler::Address(op1GPR, JSCell::structureIDOffset()),
-                    m_jit.vm()->stringStructure.get());
+                JITCompiler::Jump slowPath1 = m_jit.branchIfNotCell(JSValueRegs(op1GPR));
+                JITCompiler::Jump slowPath2 = m_jit.branchIfNotString(op1GPR);
                 m_jit.move(op1GPR, resultGPR);
                 done = m_jit.jump();
                 slowPath1.link(&m_jit);
                 slowPath2.link(&m_jit);
             }
-            callOperation(operationToString, resultGPR, op1GPR);
+            if (op == ToString)
+                callOperation(operationToString, resultGPR, op1GPR);
+            else {
+                ASSERT(op == CallStringConstructor);
+                callOperation(operationCallStringConstructor, resultGPR, op1GPR);
+            }
             if (done.isSet())
                 done.link(&m_jit);
             cellResult(resultGPR, node);
             break;
         }
         
-        compileToStringOnCell(node);
+        compileToStringOrCallStringConstructorOnCell(node);
         break;
     }
         
@@ -3206,7 +3288,7 @@ void SpeculativeJIT::compile(Node* node)
         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(node->indexingType())) {
             Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
-            RELEASE_ASSERT(structure->indexingType() == node->indexingType());
+            DFG_ASSERT(m_jit.graph(), node, structure->indexingType() == node->indexingType());
             ASSERT(
                 hasUndecided(structure->indexingType())
                 || hasInt32(structure->indexingType())
@@ -3277,7 +3359,7 @@ void SpeculativeJIT::compile(Node* node)
         
         if (!node->numChildren()) {
             flushRegisters();
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
             cellResult(result.gpr(), node);
             break;
@@ -3356,7 +3438,7 @@ void SpeculativeJIT::compile(Node* node)
             m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
         }
 
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         
         callOperation(
             operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
@@ -3389,7 +3471,7 @@ void SpeculativeJIT::compile(Node* node)
             GPRReg scratch2GPR = scratch2.gpr();
             
             MacroAssembler::JumpList slowCases;
-            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
+            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)));
             
             ASSERT((1 << 3) == sizeof(JSValue));
             m_jit.move(sizeGPR, scratchGPR);
@@ -3415,12 +3497,11 @@ void SpeculativeJIT::compile(Node* node)
                 done.link(&m_jit);
             }
             
-            addSlowPathGenerator(adoptPtr(
-                new CallArrayAllocatorWithVariableSizeSlowPathGenerator(
+            addSlowPathGenerator(std::make_unique<CallArrayAllocatorWithVariableSizeSlowPathGenerator>(
                     slowCases, this, operationNewArrayWithSize, resultGPR,
                     globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
                     globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage),
-                    sizeGPR)));
+                    sizeGPR));
             
             cellResult(resultGPR, node);
             break;
@@ -3429,10 +3510,10 @@ void SpeculativeJIT::compile(Node* node)
         SpeculateStrictInt32Operand size(this, node->child1());
         GPRReg sizeGPR = size.gpr();
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
         GPRReg structureGPR = selectScratchGPR(sizeGPR);
-        MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX));
+        MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
         m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())), structureGPR);
         MacroAssembler::Jump done = m_jit.jump();
         bigLength.link(&m_jit);
@@ -3457,7 +3538,7 @@ void SpeculativeJIT::compile(Node* node)
 
             emitAllocateJSArray(resultGPR, globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements);
             
-            RELEASE_ASSERT(indexingType & IsArray);
+            DFG_ASSERT(m_jit.graph(), node, indexingType & IsArray);
             JSValue* data = m_jit.codeBlock()->constantBuffer(node->startConstant());
             if (indexingType == ArrayWithDouble) {
                 for (unsigned index = 0; index < node->numConstants(); ++index) {
@@ -3479,7 +3560,7 @@ void SpeculativeJIT::compile(Node* node)
         }
         
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         
         callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()), node->startConstant(), node->numConstants());
         
@@ -3498,7 +3579,7 @@ void SpeculativeJIT::compile(Node* node)
             
             flushRegisters();
             
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
             
             JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
@@ -3511,7 +3592,7 @@ void SpeculativeJIT::compile(Node* node)
             break;
         }
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
@@ -3519,7 +3600,7 @@ void SpeculativeJIT::compile(Node* node)
         
     case NewRegexp: {
         flushRegisters();
-        GPRResult result(this);
+        GPRFlushedCallResult result(this);
         
         callOperation(operationNewRegexp, result.gpr(), m_jit.codeBlock()->regexp(node->regexpIndex()));
         
@@ -3535,7 +3616,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg tempGPR = temp.gpr();
         
         MacroAssembler::JumpList slowCases;
-        slowCases.append(branchNotCell(JSValueRegs(thisValueGPR)));
+        slowCases.append(m_jit.branchIfNotCell(JSValueRegs(thisValueGPR)));
         slowCases.append(m_jit.branch8(
             MacroAssembler::NotEqual,
             MacroAssembler::Address(thisValueGPR, JSCell::typeInfoTypeOffset()),
@@ -3571,11 +3652,16 @@ void SpeculativeJIT::compile(Node* node)
         GPRReg allocatorGPR = allocator.gpr();
         GPRReg structureGPR = structure.gpr();
         GPRReg scratchGPR = scratch.gpr();
+        // Rare data is only used to access the allocator & structure
+        // We can avoid using an additional GPR this way
+        GPRReg rareDataGPR = structureGPR;
 
         MacroAssembler::JumpList slowPath;
 
-        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
-        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
+        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfRareData()), rareDataGPR);
+        slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, rareDataGPR));
+        m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
+        m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR));
         emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);
 
@@ -3585,12 +3671,6 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case AllocationProfileWatchpoint:
-    case TypedArrayWatchpoint: {
-        noResult(node);
-        break;
-    }
-
     case NewObject: {
         GPRTemporary result(this);
         GPRTemporary allocator(this);
@@ -3622,85 +3702,39 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case GetScope: {
-        SpeculateCellOperand function(this, node->child1());
-        GPRTemporary result(this, Reuse, function);
-        m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
-        cellResult(result.gpr(), node);
-        break;
-    }
-        
-    case GetMyScope: {
+    case GetArgumentCount: {
         GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.loadPtr(JITCompiler::addressFor(JSStack::ScopeChain), resultGPR);
-        cellResult(resultGPR, node);
+        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
+        int32Result(result.gpr(), node);
         break;
     }
         
-    case SkipTopScope: {
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this, Reuse, scope);
-        GPRReg resultGPR = result.gpr();
-        m_jit.move(scope.gpr(), resultGPR);
-        JITCompiler::Jump activationNotCreated =
-            m_jit.branchTest64(
-                JITCompiler::Zero,
-                JITCompiler::addressFor(
-                    static_cast<VirtualRegister>(m_jit.graph().machineActivationRegister())));
-        m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
-        activationNotCreated.link(&m_jit);
-        cellResult(resultGPR, node);
+    case GetScope:
+        compileGetScope(node);
         break;
-    }
         
-    case SkipScope: {
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this, Reuse, scope);
-        m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSScope::offsetOfNext()), result.gpr());
-        cellResult(result.gpr(), node);
+    case SkipScope:
+        compileSkipScope(node);
         break;
-    }
         
-    case GetClosureRegisters: {
-        if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
-            GPRTemporary result(this);
-            GPRReg resultGPR = result.gpr();
-            m_jit.move(TrustedImmPtr(registers), resultGPR);
-            storageResult(resultGPR, node);
-            break;
-        }
-        
-        SpeculateCellOperand scope(this, node->child1());
+    case GetClosureVar: {
+        SpeculateCellOperand base(this, node->child1());
         GPRTemporary result(this);
-        GPRReg scopeGPR = scope.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
 
-        m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
-        storageResult(resultGPR, node);
-        break;
-    }
-    case GetClosureVar: {
-        StorageOperand registers(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg registersGPR = registers.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.load64(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)), resultGPR);
+        m_jit.load64(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())), resultGPR);
         jsValueResult(resultGPR, node);
         break;
     }
     case PutClosureVar: {
-        StorageOperand registers(this, node->child2());
-        JSValueOperand value(this, node->child3());
+        SpeculateCellOperand base(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg valueGPR = value.gpr();
 
-        speculate(node, node->child1());
-
-        m_jit.store64(valueGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)));
+        m_jit.store64(valueGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())));
         noResult(node);
         break;
     }
@@ -3732,7 +3766,7 @@ void SpeculativeJIT::compile(Node* node)
         
             base.use();
         
-            JITCompiler::Jump notCell = branchNotCell(JSValueRegs(baseGPR));
+            JITCompiler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(baseGPR));
         
             cachedGetById(node->origin.semantic, baseGPR, resultGPR, node->identifierNumber(), notCell);
         
@@ -3741,7 +3775,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
@@ -3758,7 +3792,7 @@ void SpeculativeJIT::compile(Node* node)
             SpeculateCellOperand base(this, node->child1());
             GPRReg baseGPR = base.gpr();
 
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             
             GPRReg resultGPR = result.gpr();
             
@@ -3776,13 +3810,13 @@ void SpeculativeJIT::compile(Node* node)
             JSValueOperand base(this, node->child1());
             GPRReg baseGPR = base.gpr();
 
-            GPRResult result(this);
+            GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
         
             base.use();
             flushRegisters();
         
-            JITCompiler::Jump notCell = branchNotCell(JSValueRegs(baseGPR));
+            JITCompiler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(baseGPR));
         
             cachedGetById(node->origin.semantic, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
         
@@ -3791,7 +3825,7 @@ void SpeculativeJIT::compile(Node* node)
         }
             
         default:
-            RELEASE_ASSERT_NOT_REACHED();
+            DFG_CRASH(m_jit.graph(), node, "Bad use kind");
             break;
         }
         break;
@@ -3801,19 +3835,31 @@ void SpeculativeJIT::compile(Node* node)
         compileGetArrayLength(node);
         break;
         
-    case CheckFunction: {
-        SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+    case CheckCell: {
+        SpeculateCellOperand cell(this, node->child1());
+        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node->cellOperand()->cell()));
         noResult(node);
         break;
     }
-        
-    case CheckExecutable: {
-        SpeculateCellOperand function(this, node->child1());
-        speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+
+    case CheckNotEmpty: {
+        JSValueOperand operand(this, node->child1());
+        GPRReg gpr = operand.gpr();
+        speculationCheck(TDZFailure, JSValueSource(), nullptr, m_jit.branchTest64(JITCompiler::Zero, gpr));
         noResult(node);
         break;
     }
+
+    case GetExecutable: {
+        SpeculateCellOperand function(this, node->child1());
+        GPRTemporary result(this, Reuse, function);
+        GPRReg functionGPR = function.gpr();
+        GPRReg resultGPR = result.gpr();
+        speculateCellType(node->child1(), functionGPR, SpecFunction, JSFunctionType);
+        m_jit.loadPtr(JITCompiler::Address(functionGPR, JSFunction::offsetOfExecutable()), resultGPR);
+        cellResult(resultGPR, node);
+        break;
+    }
         
     case CheckStructure: {
         SpeculateCellOperand base(this, node->child1());
@@ -3821,8 +3867,8 @@ void SpeculativeJIT::compile(Node* node)
         ASSERT(node->structureSet().size());
         
         ExitKind exitKind;
-        if (node->child1()->op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
+        if (node->child1()->hasConstant())
+            exitKind = BadConstantCache;
         else
             exitKind = BadCache;
         
@@ -3851,42 +3897,9 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case StructureTransitionWatchpoint: {
-        // There is a fascinating question here of what to do about array profiling.
-        // We *could* try to tell the OSR exit about where the base of the access is.
-        // The DFG will have kept it alive, though it may not be in a register, and
-        // we shouldn't really load it since that could be a waste. For now though,
-        // we'll just rely on the fact that when a watchpoint fires then that's
-        // quite a hint already.
-
-        m_jit.addWeakReference(node->structure());
-
-#if !ASSERT_DISABLED
-        SpeculateCellOperand op1(this, node->child1());
-        JITCompiler::Jump isOK = m_jit.branchStructurePtr(
-            JITCompiler::Equal, 
-            JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), 
-            node->structure());
-        m_jit.abortWithReason(DFGIneffectiveWatchpoint);
-        isOK.link(&m_jit);
-#else
-        speculateCell(node->child1());
-#endif
-        
-        noResult(node);
-        break;
-    }
-        
-    case PhantomPutStructure: {
-        ASSERT(isKnownCell(node->child1().node()));
-        m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
-        noResult(node);
-        break;
-    }
-        
     case PutStructure: {
-        Structure* oldStructure = node->structureTransitionData().previousStructure;
-        Structure* newStructure = node->structureTransitionData().newStructure;
+        Structure* oldStructure = node->transition()->previous;
+        Structure* newStructure = node->transition()->next;
 
         m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
 
@@ -3938,14 +3951,15 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case GetByOffset: {
+    case GetByOffset:
+    case GetGetterSetterByOffset: {
         StorageOperand storage(this, node->child1());
         GPRTemporary result(this, Reuse, storage);
         
         GPRReg storageGPR = storage.gpr();
         GPRReg resultGPR = result.gpr();
         
-        StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
+        StorageAccessData& storageAccessData = node->storageAccessData();
         
         m_jit.load64(JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset)), resultGPR);
         
@@ -3953,6 +3967,32 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
+    case GetGetter: {
+        SpeculateCellOperand op1(this, node->child1());
+        GPRTemporary result(this, Reuse, op1);
+        
+        GPRReg op1GPR = op1.gpr();
+        GPRReg resultGPR = result.gpr();
+        
+        m_jit.loadPtr(JITCompiler::Address(op1GPR, GetterSetter::offsetOfGetter()), resultGPR);
+        
+        cellResult(resultGPR, node);
+        break;
+    }
+        
+    case GetSetter: {
+        SpeculateCellOperand op1(this, node->child1());
+        GPRTemporary result(this, Reuse, op1);
+        
+        GPRReg op1GPR = op1.gpr();
+        GPRReg resultGPR = result.gpr();
+        
+        m_jit.loadPtr(JITCompiler::Address(op1GPR, GetterSetter::offsetOfSetter()), resultGPR);
+        
+        cellResult(resultGPR, node);
+        break;
+    }
+        
     case PutByOffset: {
         StorageOperand storage(this, node->child1());
         JSValueOperand value(this, node->child3());
@@ -3964,7 +4004,7 @@ void SpeculativeJIT::compile(Node* node)
 
         speculate(node, node->child2());
 
-        StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
+        StorageAccessData& storageAccessData = node->storageAccessData();
         
         m_jit.store64(valueGPR, JITCompiler::Address(storageGPR, offsetRelativeToBase(storageAccessData.offset)));
 
@@ -4021,47 +4061,27 @@ void SpeculativeJIT::compile(Node* node)
     case GetGlobalVar: {
         GPRTemporary result(this);
 
-        m_jit.load64(node->registerPointer(), result.gpr());
+        m_jit.load64(node->variablePointer(), result.gpr());
 
         jsValueResult(result.gpr(), node);
         break;
     }
 
     case PutGlobalVar: {
-        JSValueOperand value(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
-        m_jit.store64(value.gpr(), node->registerPointer());
+        m_jit.store64(value.gpr(), node->variablePointer());
 
         noResult(node);
         break;
     }
 
     case NotifyWrite: {
-        VariableWatchpointSet* set = node->variableWatchpointSet();
-    
-        JSValueOperand value(this, node->child1());
-        GPRReg valueGPR = value.gpr();
-    
-        GPRTemporary temp(this);
-        GPRReg tempGPR = temp.gpr();
-    
-        m_jit.load8(set->addressOfState(), tempGPR);
-    
-        JITCompiler::Jump isDone =
-            m_jit.branch32(JITCompiler::Equal, tempGPR, TrustedImm32(IsInvalidated));
-        JITCompiler::Jump slowCase = m_jit.branch64(JITCompiler::NotEqual,
-            JITCompiler::AbsoluteAddress(set->addressOfInferredValue()), valueGPR);
-        isDone.link(&m_jit);
-    
-        addSlowPathGenerator(
-            slowPathCall(slowCase, this, operationNotifyWrite, NoResult, set, valueGPR));
-
-        noResult(node);
+        compileNotifyWrite(node);
         break;
     }
 
-    case VarInjectionWatchpoint:
-    case VariableWatchpoint: {
+    case VarInjectionWatchpoint: {
         noResult(node);
         break;
     }
@@ -4092,7 +4112,7 @@ void SpeculativeJIT::compile(Node* node)
         GPRTemporary remoteGlobalObject(this);
         GPRTemporary scratch(this);
 
-        JITCompiler::Jump isCell = branchIsCell(value.jsValueRegs());
+        JITCompiler::Jump isCell = m_jit.branchIfCell(value.jsValueRegs());
 
         m_jit.compare64(JITCompiler::Equal, value.gpr(), TrustedImm32(ValueUndefined), result.gpr());
         JITCompiler::Jump done = m_jit.jump();
@@ -4152,7 +4172,7 @@ void SpeculativeJIT::compile(Node* node)
         JSValueOperand value(this, node->child1());
         GPRTemporary result(this, Reuse, value);
         
-        JITCompiler::Jump isNotCell = branchNotCell(value.jsValueRegs());
+        JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(value.jsValueRegs());
         
         m_jit.compare8(JITCompiler::Equal, 
             JITCompiler::Address(value.gpr(), JSCell::typeInfoTypeOffset()), 
@@ -4168,87 +4188,40 @@ void SpeculativeJIT::compile(Node* node)
         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
         break;
     }
-        
+
     case IsObject: {
         JSValueOperand value(this, node->child1());
-        GPRReg valueGPR = value.gpr();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        flushRegisters();
-        callOperation(operationIsObject, resultGPR, valueGPR);
-        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+        GPRTemporary result(this, Reuse, value);
+
+        JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(value.jsValueRegs());
+
+        m_jit.compare8(JITCompiler::AboveOrEqual,
+            JITCompiler::Address(value.gpr(), JSCell::typeInfoTypeOffset()),
+            TrustedImm32(ObjectType),
+            result.gpr());
+        m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+        JITCompiler::Jump done = m_jit.jump();
+
+        isNotCell.link(&m_jit);
+        m_jit.move(TrustedImm32(ValueFalse), result.gpr());
+
+        done.link(&m_jit);
         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
         break;
     }
 
+    case IsObjectOrNull: {
+        compileIsObjectOrNull(node);
+        break;
+    }
+
     case IsFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRReg valueGPR = value.gpr();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        flushRegisters();
-        callOperation(operationIsFunction, resultGPR, valueGPR);
-        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
-        jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+        compileIsFunction(node);
         break;
     }
 
     case TypeOf: {
-        JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
-        GPRReg valueGPR = value.gpr();
-        GPRResult result(this);
-        GPRReg resultGPR = result.gpr();
-        JITCompiler::JumpList doneJumps;
-
-        flushRegisters();
-        
-        ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
-
-        JITCompiler::Jump isNotCell = branchNotCell(JSValueRegs(valueGPR));
-        if (node->child1().useKind() != UntypedUse)
-            DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecCell, isNotCell);
-
-        if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
-            JITCompiler::Jump notString = m_jit.branch8(
-                JITCompiler::NotEqual, 
-                JITCompiler::Address(valueGPR, JSCell::typeInfoTypeOffset()), 
-                TrustedImm32(StringType));
-            if (node->child1().useKind() == StringUse)
-                DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecString, notString);
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.stringString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            if (node->child1().useKind() != StringUse) {
-                notString.link(&m_jit);
-                callOperation(operationTypeOf, resultGPR, valueGPR);
-                doneJumps.append(m_jit.jump());
-            }
-        } else {
-            callOperation(operationTypeOf, resultGPR, valueGPR);
-            doneJumps.append(m_jit.jump());
-        }
-
-        if (node->child1().useKind() == UntypedUse) {
-            isNotCell.link(&m_jit);
-            JITCompiler::Jump notNumber = m_jit.branchTest64(JITCompiler::Zero, valueGPR, GPRInfo::tagTypeNumberRegister);
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.numberString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notNumber.link(&m_jit);
-
-            JITCompiler::Jump notUndefined = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueUndefined));
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.undefinedString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notUndefined.link(&m_jit);
-
-            JITCompiler::Jump notNull = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueNull));
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.objectString()), resultGPR);
-            doneJumps.append(m_jit.jump());
-            notNull.link(&m_jit);
-
-            // Only boolean left
-            m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.booleanString()), resultGPR);
-        }
-        doneJumps.link(&m_jit);
-        cellResult(resultGPR, node);
+        compileTypeOf(node);
         break;
     }
 
@@ -4257,389 +4230,94 @@ void SpeculativeJIT::compile(Node* node)
 
     case Call:
     case Construct:
+    case CallVarargs:
+    case CallForwardVarargs:
+    case ConstructVarargs:
+    case ConstructForwardVarargs:
         emitCall(node);
         break;
-
-    case CreateActivation: {
-        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
         
-        JSValueOperand value(this, node->child1());
-        GPRTemporary result(this, Reuse, value);
+    case LoadVarargs: {
+        LoadVarargsData* data = node->loadVarargsData();
         
-        GPRReg valueGPR = value.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valueGPR, resultGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
+        GPRReg argumentsGPR;
+        {
+            JSValueOperand arguments(this, node->child1());
+            argumentsGPR = arguments.gpr();
+            flushRegisters();
+        }
         
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationCreateActivation, resultGPR,
-                framePointerOffsetToGetActivationRegisters()));
+        callOperation(operationSizeOfVarargs, GPRInfo::returnValueGPR, argumentsGPR, data->offset);
         
-        cellResult(resultGPR, node);
-        break;
-    }
+        lock(GPRInfo::returnValueGPR);
+        {
+            JSValueOperand arguments(this, node->child1());
+            argumentsGPR = arguments.gpr();
+            flushRegisters();
+        }
+        unlock(GPRInfo::returnValueGPR);
         
-    case FunctionReentryWatchpoint: {
-        noResult(node);
-        break;
-    }
+        // FIXME: There is a chance that we will call an effectful length property twice. This is safe
+        // from the standpoint of the VM's integrity, but it's subtly wrong from a spec compliance
+        // standpoint. The best solution would be one where we can exit *into* the op_call_varargs right
+        // past the sizing.
+        // https://bugs.webkit.org/show_bug.cgi?id=141448
+
+        GPRReg argCountIncludingThisGPR =
+            JITCompiler::selectScratchGPR(GPRInfo::returnValueGPR, argumentsGPR);
         
-    case CreateArguments: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
-        GPRTemporary result(this, Reuse, value);
+        m_jit.add32(TrustedImm32(1), GPRInfo::returnValueGPR, argCountIncludingThisGPR);
+        speculationCheck(
+            VarargsOverflow, JSValueSource(), Edge(), m_jit.branch32(
+                MacroAssembler::Above,
+                argCountIncludingThisGPR,
+                TrustedImm32(data->limit)));
         
-        GPRReg valueGPR = value.gpr();
-        GPRReg scratchGPR1 = scratch1.gpr();
-        GPRReg scratchGPR2 = scratch2.gpr();
-        GPRReg resultGPR = result.gpr();
+        m_jit.store32(argCountIncludingThisGPR, JITCompiler::payloadFor(data->machineCount));
         
-        m_jit.move(valueGPR, resultGPR);
+        callOperation(operationLoadVarargs, data->machineStart.offset(), argumentsGPR, data->offset, GPRInfo::returnValueGPR, data->mandatoryMinimum);
         
-        if (node->origin.semantic.inlineCallFrame) {
-            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-            addSlowPathGenerator(
-                slowPathCall(
-                    notCreated, this, operationCreateInlinedArguments, resultGPR,
-                    node->origin.semantic.inlineCallFrame));
-            cellResult(resultGPR, node);
-            break;
-        } 
-
-        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
-        if (m_jit.codeBlock()->hasSlowArguments()
-            || executable->isStrictMode() 
-            || !executable->parameterCount()) {
-            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-            addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
-            cellResult(resultGPR, node);
-            break;
-        }
-
-        JITCompiler::Jump alreadyCreated = m_jit.branchTest64(JITCompiler::NonZero, resultGPR);
-
-        MacroAssembler::JumpList slowPaths;
-        emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
-        addSlowPathGenerator(
-            slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
-
-        alreadyCreated.link(&m_jit);
-        cellResult(resultGPR, node);
-        break;
-    }
-
-    case TearOffActivation: {
-        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-
-        JSValueOperand activationValue(this, node->child1());
-        GPRTemporary scratch(this);
-        GPRReg activationValueGPR = activationValue.gpr();
-        GPRReg scratchGPR = scratch.gpr();
-
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, activationValueGPR);
-
-        SymbolTable* symbolTable = m_jit.symbolTableFor(node->origin.semantic);
-        int registersOffset = JSActivation::registersOffset(symbolTable);
-
-        int bytecodeCaptureStart = symbolTable->captureStart();
-        int machineCaptureStart = m_jit.graph().m_machineCaptureStart;
-        for (int i = symbolTable->captureCount(); i--;) {
-            m_jit.load64(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister,
-                    (machineCaptureStart - i) * sizeof(Register)),
-                scratchGPR);
-            m_jit.store64(
-                scratchGPR,
-                JITCompiler::Address(
-                    activationValueGPR,
-                    registersOffset + (bytecodeCaptureStart - i) * sizeof(Register)));
-        }
-        m_jit.addPtr(TrustedImm32(registersOffset), activationValueGPR, scratchGPR);
-        m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValueGPR, JSActivation::offsetOfRegisters()));
-
-        notCreated.link(&m_jit);
         noResult(node);
         break;
     }
-
-    case TearOffArguments: {
-        JSValueOperand unmodifiedArgumentsValue(this, node->child1());
-        JSValueOperand activationValue(this, node->child2());
-        GPRReg unmodifiedArgumentsValueGPR = unmodifiedArgumentsValue.gpr();
-        GPRReg activationValueGPR = activationValue.gpr();
-
-        JITCompiler::Jump created = m_jit.branchTest64(JITCompiler::NonZero, unmodifiedArgumentsValueGPR);
-
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffInlinedArguments, NoResult,
-                    unmodifiedArgumentsValueGPR, activationValueGPR, node->origin.semantic.inlineCallFrame));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffArguments, NoResult, unmodifiedArgumentsValueGPR, activationValueGPR));
-        }
         
-        noResult(node);
+    case ForwardVarargs: {
+        compileForwardVarargs(node);
         break;
     }
         
-    case GetMyArgumentsLength: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branchTest64(
-                    JITCompiler::NonZero,
-                    JITCompiler::addressFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        }
-        
-        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
-        m_jit.sub32(TrustedImm32(1), resultGPR);
-        int32Result(resultGPR, node);
+    case CreateActivation: {
+        compileCreateActivation(node);
         break;
     }
         
-    case GetMyArgumentsLengthSafe: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        
-        JITCompiler::Jump created = m_jit.branchTest64(
-            JITCompiler::NonZero,
-            JITCompiler::addressFor(
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)));
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            m_jit.move(
-                Imm64(JSValue::encode(jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1))),
-                resultGPR);
-        } else {
-            m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-            m_jit.or64(GPRInfo::tagTypeNumberRegister, resultGPR);
-        }
-        
-        // FIXME: the slow path generator should perform a forward speculation that the
-        // result is an integer. For now we postpone the speculation by having this return
-        // a JSValue.
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                created, this, operationGetArgumentsLength, resultGPR,
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
-        
-        jsValueResult(resultGPR, node);
+    case CreateDirectArguments: {
+        compileCreateDirectArguments(node);
         break;
     }
         
-    case GetMyArgumentByVal: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branchTest64(
-                    JITCompiler::NonZero,
-                    JITCompiler::addressFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        }
-
-        m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
-        if (node->origin.semantic.inlineCallFrame) {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
-        } else {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultGPR,
-                    JITCompiler::payloadFor(JSStack::ArgumentCount)));
-        }
-
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)),
-                resultGPR);
-            m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-            m_jit.load64(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
-                resultGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-            
-        m_jit.load64(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic)),
-            resultGPR);
-
-        slowArgument.link(&m_jit);
-        jsValueResult(resultGPR, node);
+    case GetFromArguments: {
+        compileGetFromArguments(node);
         break;
     }
         
-    case GetMyArgumentByValSafe: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        JITCompiler::JumpList slowPath;
-        slowPath.append(
-            m_jit.branchTest64(
-                JITCompiler::NonZero,
-                JITCompiler::addressFor(
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        
-        m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
-        if (node->origin.semantic.inlineCallFrame) {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size())));
-        } else {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultGPR,
-                    JITCompiler::payloadFor(JSStack::ArgumentCount)));
-        }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultGPR);
-            m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-            m_jit.load64(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
-                resultGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-        
-        m_jit.load64(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->origin.semantic)),
-            resultGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetInlinedArgumentByVal, resultGPR, 
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    node->origin.semantic.inlineCallFrame,
-                    indexGPR));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetArgumentByVal, resultGPR, 
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    indexGPR));
-        }
-        
-        slowArgument.link(&m_jit);
-        jsValueResult(resultGPR, node);
+    case PutToArguments: {
+        compilePutToArguments(node);
         break;
     }
         
-    case CheckArgumentsNotCreated: {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
-        speculationCheck(
-            ArgumentsEscaped, JSValueRegs(), 0,
-            m_jit.branchTest64(
-                JITCompiler::NonZero,
-                JITCompiler::addressFor(
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        noResult(node);
+    case CreateScopedArguments: {
+        compileCreateScopedArguments(node);
         break;
     }
         
-    case NewFunctionNoCheck:
-        compileNewFunctionNoCheck(node);
-        break;
-        
-    case NewFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary result(this, Reuse, value);
-        
-        GPRReg valueGPR = value.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valueGPR, resultGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationNewFunction,
-                resultGPR, m_jit.codeBlock()->functionDecl(node->functionDeclIndex())));
-        
-        jsValueResult(resultGPR, node);
+    case CreateClonedArguments: {
+        compileCreateClonedArguments(node);
         break;
     }
         
-    case NewFunctionExpression:
-        compileNewFunctionExpression(node);
+    case NewFunction:
+        compileNewFunction(node);
         break;
         
     case In:
@@ -4669,7 +4347,7 @@ void SpeculativeJIT::compile(Node* node)
         break;
 
     case Phantom:
-    case HardPhantom:
+    case Check:
         DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
         noResult(node);
         break;
@@ -4684,15 +4362,319 @@ void SpeculativeJIT::compile(Node* node)
         break;
 
     case Unreachable:
-        RELEASE_ASSERT_NOT_REACHED();
+        DFG_CRASH(m_jit.graph(), node, "Unexpected Unreachable node");
         break;
 
-    case StoreBarrier:
-    case StoreBarrierWithNullCheck: {
+    case StoreBarrier: {
         compileStoreBarrier(node);
         break;
     }
 
+    case GetEnumerableLength: {
+        SpeculateCellOperand enumerator(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
+        int32Result(resultGPR, node);
+        break;
+    }
+    case HasGenericProperty: {
+        JSValueOperand base(this, node->child1());
+        SpeculateCellOperand property(this, node->child2());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+        callOperation(operationHasGenericProperty, resultGPR, base.gpr(), property.gpr());
+        jsValueResult(resultGPR, node, DataFormatJSBoolean);
+        break;
+    }
+    case HasStructureProperty: {
+        JSValueOperand base(this, node->child1());
+        SpeculateCellOperand property(this, node->child2());
+        SpeculateCellOperand enumerator(this, node->child3());
+        GPRTemporary result(this);
+
+        GPRReg baseGPR = base.gpr();
+        GPRReg propertyGPR = property.gpr();
+        GPRReg resultGPR = result.gpr();
+
+        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), resultGPR);
+        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 
+            resultGPR, 
+            MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset()));
+
+        moveTrueTo(resultGPR);
+        MacroAssembler::Jump done = m_jit.jump();
+
+        done.link(&m_jit);
+
+        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultGPR, baseGPR, propertyGPR));
+        jsValueResult(resultGPR, node, DataFormatJSBoolean);
+        break;
+    }
+    case HasIndexedProperty: {
+        SpeculateCellOperand base(this, node->child1());
+        SpeculateStrictInt32Operand index(this, node->child2());
+        GPRTemporary result(this);
+
+        GPRReg baseGPR = base.gpr();
+        GPRReg indexGPR = index.gpr();
+        GPRReg resultGPR = result.gpr();
+
+        MacroAssembler::JumpList slowCases;
+        ArrayMode mode = node->arrayMode();
+        switch (mode.type()) {
+        case Array::Int32:
+        case Array::Contiguous: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            GPRTemporary scratch(this);
+            
+            GPRReg storageGPR = storage.gpr();
+            GPRReg scratchGPR = scratch.gpr();
+
+            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            if (mode.isInBounds())
+                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
+            else
+                slowCases.append(outOfBounds);
+
+            m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchGPR);
+            slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR));
+            moveTrueTo(resultGPR);
+            break;
+        }
+        case Array::Double: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            FPRTemporary scratch(this);
+            FPRReg scratchFPR = scratch.fpr();
+            GPRReg storageGPR = storage.gpr();
+
+            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            if (mode.isInBounds())
+                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
+            else
+                slowCases.append(outOfBounds);
+
+            m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR);
+            slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR));
+            moveTrueTo(resultGPR);
+            break;
+        }
+        case Array::ArrayStorage: {
+            ASSERT(!!node->child3());
+            StorageOperand storage(this, node->child3());
+            GPRTemporary scratch(this);
+
+            GPRReg storageGPR = storage.gpr();
+            GPRReg scratchGPR = scratch.gpr();
+
+            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
+            if (mode.isInBounds())
+                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
+            else    
+                slowCases.append(outOfBounds);
+
+            m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), scratchGPR);
+            slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR));
+            moveTrueTo(resultGPR);
+            break;
+        }
+        default: {
+            slowCases.append(m_jit.jump());
+            break;
+        }
+        }
+
+        addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultGPR, baseGPR, indexGPR));
+        
+        jsValueResult(resultGPR, node, DataFormatJSBoolean);
+        break;
+    }
+    case GetDirectPname: {
+        Edge& baseEdge = m_jit.graph().varArgChild(node, 0);
+        Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
+        Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
+        Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
+
+        SpeculateCellOperand base(this, baseEdge);
+        SpeculateCellOperand property(this, propertyEdge);
+        SpeculateStrictInt32Operand index(this, indexEdge);
+        SpeculateCellOperand enumerator(this, enumeratorEdge);
+        GPRTemporary result(this);
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
+
+        GPRReg baseGPR = base.gpr();
+        GPRReg propertyGPR = property.gpr();
+        GPRReg indexGPR = index.gpr();
+        GPRReg enumeratorGPR = enumerator.gpr();
+        GPRReg resultGPR = result.gpr();
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg scratch2GPR = scratch2.gpr();
+
+        // Check the structure
+        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratch1GPR);
+        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 
+            scratch1GPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
+        
+        // Compute the offset
+        // If index is less than the enumerator's cached inline storage, then it's an inline access
+        MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual, 
+            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
+
+        m_jit.load64(MacroAssembler::BaseIndex(baseGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultGPR);
+
+        MacroAssembler::Jump done = m_jit.jump();
+        
+        // Otherwise it's out of line
+        outOfLineAccess.link(&m_jit);
+        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratch2GPR);
+        m_jit.move(indexGPR, scratch1GPR);
+        m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratch1GPR);
+        m_jit.neg32(scratch1GPR);
+        m_jit.signExtend32ToPtr(scratch1GPR, scratch1GPR);
+        int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
+        m_jit.load64(MacroAssembler::BaseIndex(scratch2GPR, scratch1GPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultGPR);
+
+        done.link(&m_jit);
+
+        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByVal, resultGPR, baseGPR, propertyGPR));
+
+        jsValueResult(resultGPR, node);
+        break;
+    }
+    case GetPropertyEnumerator: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+        callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
+        cellResult(resultGPR, node);
+        break;
+    }
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname: {
+        SpeculateCellOperand enumerator(this, node->child1());
+        SpeculateStrictInt32Operand index(this, node->child2());
+        GPRTemporary scratch1(this);
+        GPRTemporary result(this);
+
+        GPRReg enumeratorGPR = enumerator.gpr();
+        GPRReg indexGPR = index.gpr();
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg resultGPR = result.gpr();
+
+        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
+            MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
+                ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
+                : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
+
+        m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNull())), resultGPR);
+
+        MacroAssembler::Jump done = m_jit.jump();
+        inBounds.link(&m_jit);
+
+        m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratch1GPR);
+        m_jit.load64(MacroAssembler::BaseIndex(scratch1GPR, indexGPR, MacroAssembler::TimesEight), resultGPR);
+
+        done.link(&m_jit);
+        jsValueResult(resultGPR, node);
+        break;
+    }
+    case ToIndexString: {
+        SpeculateInt32Operand index(this, node->child1());
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+
+        flushRegisters();
+        callOperation(operationToIndexString, resultGPR, index.gpr());
+        cellResult(resultGPR, node);
+        break;
+    }
+    case ProfileType: {
+        JSValueOperand value(this, node->child1());
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
+        GPRTemporary scratch3(this);
+
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg scratch2GPR = scratch2.gpr();
+        GPRReg scratch3GPR = scratch3.gpr();
+        GPRReg valueGPR = value.gpr();
+
+        MacroAssembler::JumpList jumpToEnd;
+
+        TypeLocation* cachedTypeLocation = node->typeLocation();
+        // Compile in a predictive type check, if possible, to see if we can skip writing to the log.
+        // These typechecks are inlined to match those of the 64-bit JSValue type checks.
+        if (cachedTypeLocation->m_lastSeenType == TypeUndefined)
+            jumpToEnd.append(m_jit.branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined()))));
+        else if (cachedTypeLocation->m_lastSeenType == TypeNull)
+            jumpToEnd.append(m_jit.branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNull()))));
+        else if (cachedTypeLocation->m_lastSeenType == TypeBoolean) {
+            m_jit.move(valueGPR, scratch2GPR);
+            m_jit.and64(TrustedImm32(~1), scratch2GPR);
+            jumpToEnd.append(m_jit.branch64(MacroAssembler::Equal, scratch2GPR, MacroAssembler::TrustedImm64(ValueFalse)));
+        } else if (cachedTypeLocation->m_lastSeenType == TypeMachineInt)
+            jumpToEnd.append(m_jit.branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister));
+        else if (cachedTypeLocation->m_lastSeenType == TypeNumber)
+            jumpToEnd.append(m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagTypeNumberRegister));
+        else if (cachedTypeLocation->m_lastSeenType == TypeString) {
+            MacroAssembler::Jump isNotCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
+            jumpToEnd.append(m_jit.branchIfString(valueGPR));
+            isNotCell.link(&m_jit);
+        }
+
+        // Load the TypeProfilerLog into Scratch2.
+        TypeProfilerLog* cachedTypeProfilerLog = m_jit.vm()->typeProfilerLog();
+        m_jit.move(TrustedImmPtr(cachedTypeProfilerLog), scratch2GPR);
+
+        // Load the next LogEntry into Scratch1.
+        m_jit.loadPtr(MacroAssembler::Address(scratch2GPR, TypeProfilerLog::currentLogEntryOffset()), scratch1GPR);
+
+        // Store the JSValue onto the log entry.
+        m_jit.store64(valueGPR, MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::valueOffset()));
+
+        // Store the structureID of the cell if valueGPR is a cell, otherwise, store 0 on the log entry.
+        MacroAssembler::Jump isNotCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
+        m_jit.load32(MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()), scratch3GPR);
+        m_jit.store32(scratch3GPR, MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::structureIDOffset()));
+        MacroAssembler::Jump skipIsCell = m_jit.jump();
+        isNotCell.link(&m_jit);
+        m_jit.store32(TrustedImm32(0), MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::structureIDOffset()));
+        skipIsCell.link(&m_jit);
+
+        // Store the typeLocation on the log entry.
+        m_jit.move(TrustedImmPtr(cachedTypeLocation), scratch3GPR);
+        m_jit.storePtr(scratch3GPR, MacroAssembler::Address(scratch1GPR, TypeProfilerLog::LogEntry::locationOffset()));
+
+        // Increment the current log entry.
+        m_jit.addPtr(TrustedImm32(sizeof(TypeProfilerLog::LogEntry)), scratch1GPR);
+        m_jit.storePtr(scratch1GPR, MacroAssembler::Address(scratch2GPR, TypeProfilerLog::currentLogEntryOffset()));
+        MacroAssembler::Jump clearLog = m_jit.branchPtr(MacroAssembler::Equal, scratch1GPR, TrustedImmPtr(cachedTypeProfilerLog->logEndPtr()));
+        addSlowPathGenerator(
+            slowPathCall(clearLog, this, operationProcessTypeProfilerLogDFG, NoResult));
+
+        jumpToEnd.link(&m_jit);
+
+        noResult(node);
+        break;
+    }
+    case ProfileControlFlow: {
+        BasicBlockLocation* basicBlockLocation = node->basicBlockLocation();
+        if (!basicBlockLocation->hasExecuted()) {
+            GPRTemporary scratch1(this);
+            basicBlockLocation->emitExecuteCode(m_jit, scratch1.gpr());
+        }
+        noResult(node);
+        break;
+    }
+
 #if ENABLE(FTL_JIT)        
     case CheckTierUpInLoop: {
         MacroAssembler::Jump done = m_jit.branchAdd32(
@@ -4702,7 +4684,7 @@ void SpeculativeJIT::compile(Node* node)
         
         silentSpillAllRegisters(InvalidGPRReg);
         m_jit.setupArgumentsExecState();
-        appendCall(triggerTierUpNow);
+        appendCall(triggerTierUpNowInLoop);
         silentFillAllRegisters(InvalidGPRReg);
         
         done.link(&m_jit);
@@ -4724,17 +4706,24 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
         
-    case CheckTierUpAndOSREnter: {
+    case CheckTierUpAndOSREnter:
+    case CheckTierUpWithNestedTriggerAndOSREnter: {
         ASSERT(!node->origin.semantic.inlineCallFrame);
         
         GPRTemporary temp(this);
         GPRReg tempGPR = temp.gpr();
+
+        MacroAssembler::Jump forceOSREntry;
+        if (op == CheckTierUpWithNestedTriggerAndOSREnter)
+            forceOSREntry = m_jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(&m_jit.jitCode()->nestedTriggerIsSet));
         
         MacroAssembler::Jump done = m_jit.branchAdd32(
             MacroAssembler::Signed,
             TrustedImm32(Options::ftlTierUpCounterIncrementForLoop()),
             MacroAssembler::AbsoluteAddress(&m_jit.jitCode()->tierUpCounter.m_counter));
-        
+
+        if (forceOSREntry.isSet())
+            forceOSREntry.link(&m_jit);
         silentSpillAllRegisters(tempGPR);
         m_jit.setupArgumentsWithExecState(
             TrustedImm32(node->origin.semantic.bytecodeIndex),
@@ -4752,21 +4741,36 @@ void SpeculativeJIT::compile(Node* node)
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
     case CheckTierUpAndOSREnter:
-        RELEASE_ASSERT_NOT_REACHED();
+    case CheckTierUpWithNestedTriggerAndOSREnter:
+        DFG_CRASH(m_jit.graph(), node, "Unexpected tier-up node");
         break;
 #endif // ENABLE(FTL_JIT)
-        
+
+    case NativeCall:
+    case NativeConstruct:    
     case LastNodeType:
     case Phi:
     case Upsilon:
-    case GetArgument:
     case ExtractOSREntryLocal:
     case CheckInBounds:
     case ArithIMul:
     case MultiGetByOffset:
     case MultiPutByOffset:
     case FiatInt52:
-        RELEASE_ASSERT_NOT_REACHED();
+    case CheckBadCell:
+    case BottomValue:
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case GetMyArgumentByVal:
+    case PutHint:
+    case CheckStructureImmediate:
+    case MaterializeNewObject:
+    case MaterializeCreateActivation:
+    case PutStack:
+    case KillStack:
+    case GetStack:
+        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
         break;
     }
 
@@ -4782,59 +4786,17 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUs
 {
     JITCompiler::Jump isNotCell;
     if (!isKnownCell(valueUse.node()))
-        isNotCell = branchNotCell(JSValueRegs(valueGPR));
+        isNotCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
     
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(ownerGPR);
+    JITCompiler::Jump ownerIsRememberedOrInEden = m_jit.jumpIfIsRememberedOrInEden(ownerGPR);
     storeToWriteBarrierBuffer(ownerGPR, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
-
-    if (!isKnownCell(valueUse.node()))
-        isNotCell.link(&m_jit);
-}
-
-void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, Edge valueUse, GPRReg scratch1, GPRReg scratch2)
-{
-    JITCompiler::Jump isNotCell;
-    if (!isKnownCell(valueUse.node()))
-        isNotCell = branchNotCell(JSValueRegs(valueGPR));
-    
-    JITCompiler::Jump ownerNotMarkedOrAlreadyRemembered = m_jit.checkMarkByte(owner);
-    storeToWriteBarrierBuffer(owner, scratch1, scratch2);
-    ownerNotMarkedOrAlreadyRemembered.link(&m_jit);
+    ownerIsRememberedOrInEden.link(&m_jit);
 
     if (!isKnownCell(valueUse.node()))
         isNotCell.link(&m_jit);
 }
 #endif // ENABLE(GGC)
 
-JITCompiler::Jump SpeculativeJIT::branchIsCell(JSValueRegs regs)
-{
-    return m_jit.branchTest64(MacroAssembler::Zero, regs.gpr(), GPRInfo::tagMaskRegister);
-}
-
-JITCompiler::Jump SpeculativeJIT::branchNotCell(JSValueRegs regs)
-{
-    return m_jit.branchTest64(MacroAssembler::NonZero, regs.gpr(), GPRInfo::tagMaskRegister);
-}
-
-JITCompiler::Jump SpeculativeJIT::branchIsOther(JSValueRegs regs, GPRReg tempGPR)
-{
-    m_jit.move(regs.gpr(), tempGPR);
-    m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
-    return m_jit.branch64(
-        MacroAssembler::Equal, tempGPR,
-        MacroAssembler::TrustedImm64(ValueNull));
-}
-
-JITCompiler::Jump SpeculativeJIT::branchNotOther(JSValueRegs regs, GPRReg tempGPR)
-{
-    m_jit.move(regs.gpr(), tempGPR);
-    m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
-    return m_jit.branch64(
-        MacroAssembler::NotEqual, tempGPR,
-        MacroAssembler::TrustedImm64(ValueNull));
-}
-
 void SpeculativeJIT::moveTrueTo(GPRReg gpr)
 {
     m_jit.move(TrustedImm32(ValueTrue), gpr);
@@ -4891,7 +4853,7 @@ void SpeculativeJIT::speculateDoubleRepMachineInt(Edge edge)
     SpeculateDoubleOperand value(this, edge);
     FPRReg valueFPR = value.fpr();
     
-    GPRResult result(this);
+    GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
     
     flushRegisters();
index 0722bfa23477911c8024952ed17b1ea65867470b..0713720b592814861591a9359324eb330c38d5e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,8 +46,6 @@ public:
     
     bool run()
     {
-        SymbolTable* symbolTable = codeBlock()->symbolTable();
-
         // This enumerates the locals that we actually care about and packs them. So for example
         // if we use local 1, 3, 4, 5, 7, then we remap them: 1->0, 3->1, 4->2, 5->3, 7->4. We
         // treat a variable as being "used" if there exists an access to it (SetLocal, GetLocal,
@@ -56,7 +54,7 @@ public:
         BitVector usedLocals;
         
         // Collect those variables that are used from IR.
-        bool hasGetLocalUnlinked = false;
+        bool hasNodesThatNeedFixup = false;
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
@@ -80,7 +78,32 @@ public:
                     if (operand.isArgument())
                         break;
                     usedLocals.set(operand.toLocal());
-                    hasGetLocalUnlinked = true;
+                    hasNodesThatNeedFixup = true;
+                    break;
+                }
+                    
+                case LoadVarargs:
+                case ForwardVarargs: {
+                    LoadVarargsData* data = node->loadVarargsData();
+                    if (data->count.isLocal())
+                        usedLocals.set(data->count.toLocal());
+                    if (data->start.isLocal()) {
+                        // This part really relies on the contiguity of stack layout
+                        // assignments.
+                        ASSERT(VirtualRegister(data->start.offset() + data->limit - 1).isLocal());
+                        for (unsigned i = data->limit; i--;) 
+                            usedLocals.set(VirtualRegister(data->start.offset() + i).toLocal());
+                    } // the else case shouldn't happen.
+                    hasNodesThatNeedFixup = true;
+                    break;
+                }
+                    
+                case PutStack:
+                case GetStack: {
+                    StackAccessData* stack = node->stackAccessData();
+                    if (stack->local.isArgument())
+                        break;
+                    usedLocals.set(stack->local.toLocal());
                     break;
                 }
                     
@@ -90,27 +113,13 @@ public:
             }
         }
         
-        // Ensure that captured variables and captured inline arguments are pinned down.
-        // They should have been because of flushes, except that the flushes can be optimized
-        // away.
-        if (symbolTable) {
-            for (int i = symbolTable->captureStart(); i > symbolTable->captureEnd(); i--)
-                usedLocals.set(VirtualRegister(i).toLocal());
-        }
-        if (codeBlock()->usesArguments()) {
-            usedLocals.set(codeBlock()->argumentsRegister().toLocal());
-            usedLocals.set(unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()).toLocal());
-        }
-        if (codeBlock()->uncheckedActivationRegister().isValid())
-            usedLocals.set(codeBlock()->activationRegister().toLocal());
         for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter) {
             InlineCallFrame* inlineCallFrame = *iter;
-            if (!m_graph.usesArguments(inlineCallFrame))
-                continue;
             
-            VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(inlineCallFrame);
-            usedLocals.set(argumentsRegister.toLocal());
-            usedLocals.set(unmodifiedArgumentsRegister(argumentsRegister).toLocal());
+            if (inlineCallFrame->isVarargs()) {
+                usedLocals.set(VirtualRegister(
+                    JSStack::ArgumentCount + inlineCallFrame->stackOffset).toLocal());
+            }
             
             for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
                 usedLocals.set(VirtualRegister(
@@ -147,38 +156,37 @@ public:
             if (allocation[local] == UINT_MAX)
                 continue;
             
-            variable->machineLocal() = virtualRegisterForLocal(
-                allocation[variable->local().toLocal()]);
-        }
-        
-        if (codeBlock()->usesArguments()) {
-            VirtualRegister argumentsRegister = virtualRegisterForLocal(
-                allocation[codeBlock()->argumentsRegister().toLocal()]);
-            RELEASE_ASSERT(
-                virtualRegisterForLocal(allocation[
-                    unmodifiedArgumentsRegister(
-                        codeBlock()->argumentsRegister()).toLocal()])
-                == unmodifiedArgumentsRegister(argumentsRegister));
-            codeBlock()->setArgumentsRegister(argumentsRegister);
+            variable->machineLocal() = assign(allocation, variable->local());
         }
         
-        if (codeBlock()->uncheckedActivationRegister().isValid()) {
-            codeBlock()->setActivationRegister(
-                virtualRegisterForLocal(allocation[codeBlock()->activationRegister().toLocal()]));
+        for (StackAccessData* data : m_graph.m_stackAccessData) {
+            if (!data->local.isLocal()) {
+                data->machineLocal = data->local;
+                continue;
+            }
+            
+            if (static_cast<size_t>(data->local.toLocal()) >= allocation.size())
+                continue;
+            if (allocation[data->local.toLocal()] == UINT_MAX)
+                continue;
+            
+            data->machineLocal = assign(allocation, data->local);
         }
         
+        // This register is never valid for DFG code blocks.
+        codeBlock()->setActivationRegister(VirtualRegister());
+        if (LIKELY(!m_graph.hasDebuggerEnabled()))
+            codeBlock()->setScopeRegister(VirtualRegister());
+        else
+            codeBlock()->setScopeRegister(assign(allocation, codeBlock()->scopeRegister()));
+
         for (unsigned i = m_graph.m_inlineVariableData.size(); i--;) {
             InlineVariableData data = m_graph.m_inlineVariableData[i];
             InlineCallFrame* inlineCallFrame = data.inlineCallFrame;
             
-            if (m_graph.usesArguments(inlineCallFrame)) {
-                inlineCallFrame->argumentsRegister = virtualRegisterForLocal(
-                    allocation[m_graph.argumentsRegisterFor(inlineCallFrame).toLocal()]);
-
-                RELEASE_ASSERT(
-                    virtualRegisterForLocal(allocation[unmodifiedArgumentsRegister(
-                        m_graph.argumentsRegisterFor(inlineCallFrame)).toLocal()])
-                    == unmodifiedArgumentsRegister(inlineCallFrame->argumentsRegister));
+            if (inlineCallFrame->isVarargs()) {
+                inlineCallFrame->argumentCountRegister = assign(
+                    allocation, VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
             }
             
             for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
@@ -206,34 +214,8 @@ public:
                 RELEASE_ASSERT(inlineCallFrame->calleeRecovery.isConstant());
         }
         
-        if (symbolTable) {
-            if (symbolTable->captureCount()) {
-                unsigned captureStartLocal = allocation[
-                    VirtualRegister(codeBlock()->symbolTable()->captureStart()).toLocal()];
-                ASSERT(captureStartLocal != UINT_MAX);
-                m_graph.m_machineCaptureStart = virtualRegisterForLocal(captureStartLocal).offset();
-            } else
-                m_graph.m_machineCaptureStart = virtualRegisterForLocal(0).offset();
-        
-            // This is an abomination. If we had captured an argument then the argument ends
-            // up being "slow", meaning that loads of the argument go through an extra lookup
-            // table.
-            if (const SlowArgument* slowArguments = symbolTable->slowArguments()) {
-                auto newSlowArguments = std::make_unique<SlowArgument[]>(
-                    symbolTable->parameterCount());
-                for (size_t i = symbolTable->parameterCount(); i--;) {
-                    newSlowArguments[i] = slowArguments[i];
-                    VirtualRegister reg = VirtualRegister(slowArguments[i].index);
-                    if (reg.isLocal())
-                        newSlowArguments[i].index = virtualRegisterForLocal(allocation[reg.toLocal()]).offset();
-                }
-            
-                m_graph.m_slowArguments = WTF::move(newSlowArguments);
-            }
-        }
-        
         // Fix GetLocalUnlinked's variable references.
-        if (hasGetLocalUnlinked) {
+        if (hasNodesThatNeedFixup) {
             for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
                 BasicBlock* block = m_graph.block(blockIndex);
                 if (!block)
@@ -242,10 +224,15 @@ public:
                     Node* node = block->at(nodeIndex);
                     switch (node->op()) {
                     case GetLocalUnlinked: {
-                        VirtualRegister operand = node->unlinkedLocal();
-                        if (operand.isLocal())
-                            operand = virtualRegisterForLocal(allocation[operand.toLocal()]);
-                        node->setUnlinkedMachineLocal(operand);
+                        node->setUnlinkedMachineLocal(assign(allocation, node->unlinkedLocal()));
+                        break;
+                    }
+                        
+                    case LoadVarargs:
+                    case ForwardVarargs: {
+                        LoadVarargsData* data = node->loadVarargsData();
+                        data->machineCount = assign(allocation, data->count);
+                        data->machineStart = assign(allocation, data->start);
                         break;
                     }
                         
@@ -258,6 +245,20 @@ public:
         
         return true;
     }
+
+private:
+    VirtualRegister assign(const Vector<unsigned>& allocation, VirtualRegister src)
+    {
+        VirtualRegister result = src;
+        if (result.isLocal()) {
+            unsigned myAllocation = allocation[result.toLocal()];
+            if (myAllocation == UINT_MAX)
+                result = VirtualRegister();
+            else
+                result = virtualRegisterForLocal(myAllocation);
+        }
+        return result;
+    }
 };
 
 bool performStackLayout(Graph& graph)
index 6baa3ce73cf739469f6bb39224e6f81196b5b43e..b5e1a364f6a73ca1328033981ff68f0c1c4e10cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,16 +63,17 @@ public:
             if (!block)
                 continue;
             
-            switch (block->last()->op()) {
+            Node* terminal = block->terminal();
+            switch (terminal->op()) {
             case Branch: {
-                BranchData* data = block->last()->branchData();
+                BranchData* data = terminal->branchData();
                 applyCounts(data->taken);
                 applyCounts(data->notTaken);
                 break;
             }
                 
             case Switch: {
-                SwitchData* data = block->last()->switchData();
+                SwitchData* data = terminal->switchData();
                 for (unsigned i = data->cases.size(); i--;)
                     applyCounts(data->cases[i].target);
                 applyCounts(data->fallThrough);
diff --git a/dfg/DFGStoreBarrierElisionPhase.cpp b/dfg/DFGStoreBarrierElisionPhase.cpp
deleted file mode 100644 (file)
index 4217552..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DFGStoreBarrierElisionPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlock.h"
-#include "DFGClobberize.h"
-#include "DFGGraph.h"
-#include "DFGPhase.h"
-#include "JSCInlines.h"
-#include <wtf/HashSet.h>
-
-namespace JSC { namespace DFG {
-
-class StoreBarrierElisionPhase : public Phase {
-public:
-    StoreBarrierElisionPhase(Graph& graph)
-        : Phase(graph, "store barrier elision")
-        , m_currentBlock(0)
-        , m_currentIndex(0)
-    {
-    }
-
-    bool run()
-    {
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
-            m_currentBlock = m_graph.block(blockIndex);
-            if (!m_currentBlock)
-                continue;
-            handleBlock(m_currentBlock);
-        }
-        return true;
-    }
-
-private:
-    bool couldCauseGC(Node* node)
-    {
-        return writesOverlap(m_graph, node, GCState);
-    }
-
-    bool allocatesFreshObject(Node* node)
-    {
-        switch (node->op()) {
-        case NewObject:
-        case NewArray:
-        case NewArrayWithSize:
-        case NewArrayBuffer:
-        case NewTypedArray:
-        case NewRegexp:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    void noticeFreshObject(HashSet<Node*>& dontNeedBarriers, Node* node)
-    {
-        ASSERT(allocatesFreshObject(node));
-        dontNeedBarriers.add(node);
-    }
-
-    Node* getBaseOfStore(Node* barrierNode)
-    {
-        ASSERT(barrierNode->isStoreBarrier());
-        return barrierNode->child1().node();
-    }
-
-    bool shouldBeElided(HashSet<Node*>& dontNeedBarriers, Node* node)
-    {
-        ASSERT(node->isStoreBarrier());
-        return dontNeedBarriers.contains(node->child1().node());
-    }
-
-    void elideBarrier(Node* node)
-    {
-        ASSERT(node->isStoreBarrier());
-        node->convertToPhantom();
-    }
-
-    void handleNode(HashSet<Node*>& dontNeedBarriers, Node* node)
-    {
-        if (couldCauseGC(node))
-            dontNeedBarriers.clear();
-
-        if (allocatesFreshObject(node))
-            noticeFreshObject(dontNeedBarriers, node);
-
-        if (!node->isStoreBarrier())
-            return;
-
-        if (shouldBeElided(dontNeedBarriers, node)) {
-            elideBarrier(node);
-            return;
-        }
-
-        Node* base = getBaseOfStore(node);
-        if (!base)
-            return;
-
-        if (dontNeedBarriers.contains(base))
-            return;
-        dontNeedBarriers.add(base);
-    }
-
-    bool handleBlock(BasicBlock* block)
-    {
-        HashSet<Node*> dontNeedBarriers;
-        for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-            m_currentIndex = indexInBlock;
-            Node* node = block->at(indexInBlock);
-            handleNode(dontNeedBarriers, node);
-        }
-        return true;
-    }
-
-    BasicBlock* m_currentBlock;
-    unsigned m_currentIndex;
-};
-    
-bool performStoreBarrierElision(Graph& graph)
-{
-    SamplingRegion samplingRegion("DFG Store Barrier Elision Phase");
-    return runPhase<StoreBarrierElisionPhase>(graph);
-}
-
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
diff --git a/dfg/DFGStoreBarrierElisionPhase.h b/dfg/DFGStoreBarrierElisionPhase.h
deleted file mode 100644 (file)
index 94276be..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DFGStoreBarrierElisionPhase_h
-#define DFGStoreBarrierElisionPhase_h
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-bool performStoreBarrierElision(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // DFGStoreBarrierElisionPhase_h
diff --git a/dfg/DFGStoreBarrierInsertionPhase.cpp b/dfg/DFGStoreBarrierInsertionPhase.cpp
new file mode 100644 (file)
index 0000000..66acda2
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGStoreBarrierInsertionPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAbstractInterpreterInlines.h"
+#include "DFGBlockMapInlines.h"
+#include "DFGDoesGC.h"
+#include "DFGGraph.h"
+#include "DFGInPlaceAbstractState.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+#include <wtf/CommaPrinter.h>
+#include <wtf/HashSet.h>
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+enum class PhaseMode {
+    // Does only a local analysis for store barrier insertion and assumes that pointers live
+    // from predecessor blocks may need barriers. Assumes CPS conventions. Does not use AI for
+    // eliminating store barriers, but does a best effort to eliminate barriers when you're
+    // storing a non-cell value by using Node::result() and by looking at constants. The local
+    // analysis is based on GC epochs, so it will eliminate a lot of locally redundant barriers.
+    Fast,
+        
+    // Does a global analysis for store barrier insertion. Reuses the GC-epoch-based analysis
+    // used by Fast, but adds a conservative merge rule for propagating information from one
+    // block to the next. This will ensure for example that if a value V coming from multiple
+    // predecessors in B didn't need any more barriers at the end of each predecessor (either
+    // because it was the last allocated object in that predecessor or because it just had a
+    // barrier executed), then until we hit another GC point in B, we won't need another barrier
+    // on V. Uses AI for eliminating barriers when we know that the value being stored is not a
+    // cell. Assumes SSA conventions.
+    Global
+};
+
+template<PhaseMode mode>
+class StoreBarrierInsertionPhase : public Phase {
+public:
+    StoreBarrierInsertionPhase(Graph& graph)
+        : Phase(graph, mode == PhaseMode::Fast ? "fast store barrier insertion" : "global store barrier insertion")
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        if (verbose) {
+            dataLog("Starting store barrier insertion:\n");
+            m_graph.dump();
+        }
+        
+        switch (mode) {
+        case PhaseMode::Fast: {
+            DFG_ASSERT(m_graph, nullptr, m_graph.m_form != SSA);
+            
+            m_graph.clearEpochs();
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+                handleBlock(block);
+            return true;
+        }
+            
+        case PhaseMode::Global: {
+            DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
+
+            m_state = std::make_unique<InPlaceAbstractState>(m_graph);
+            m_interpreter = std::make_unique<AbstractInterpreter<InPlaceAbstractState>>(m_graph, *m_state);
+            
+            m_isConverged = false;
+            
+            // First run the analysis. Inside basic blocks we use an epoch-based analysis that
+            // is very precise. At block boundaries, we just propagate which nodes may need a
+            // barrier. This gives us a very nice bottom->top fixpoint: we start out assuming
+            // that no node needs any barriers at block boundaries, and then we converge
+            // towards believing that all nodes need barriers. "Needing a barrier" is like
+            // saying that the node is in a past epoch. "Not needing a barrier" is like saying
+            // that the node is in the current epoch.
+            m_stateAtHead = std::make_unique<BlockMap<HashSet<Node*>>>(m_graph);
+            m_stateAtTail = std::make_unique<BlockMap<HashSet<Node*>>>(m_graph);
+            
+            BlockList postOrder = m_graph.blocksInPostOrder();
+            
+            bool changed = true;
+            while (changed) {
+                changed = false;
+                
+                // Intentional backwards loop because we are using RPO.
+                for (unsigned blockIndex = postOrder.size(); blockIndex--;) {
+                    BasicBlock* block = postOrder[blockIndex];
+                    
+                    if (!handleBlock(block)) {
+                        // If the block didn't finish, then it cannot affect the fixpoint.
+                        continue;
+                    }
+                    
+                    // Construct the state-at-tail based on the epochs of live nodes and the
+                    // current epoch. We grow state-at-tail monotonically to ensure convergence.
+                    bool thisBlockChanged = false;
+                    for (Node* node : block->ssa->liveAtTail) {
+                        if (node->epoch() != m_currentEpoch) {
+                            // If the node is older than the current epoch, then we may need to
+                            // run a barrier on it in the future. So, add it to the state.
+                            thisBlockChanged |= m_stateAtTail->at(block).add(node).isNewEntry;
+                        }
+                    }
+                    
+                    if (!thisBlockChanged) {
+                        // This iteration didn't learn anything new about this block.
+                        continue;
+                    }
+                    
+                    // Changed things. Make sure that we loop one more time.
+                    changed = true;
+                    
+                    for (BasicBlock* successor : block->successors()) {
+                        for (Node* node : m_stateAtTail->at(block))
+                            m_stateAtHead->at(successor).add(node);
+                    }
+                }
+            }
+            
+            // Tell handleBlock() that it's time to actually insert barriers for real.
+            m_isConverged = true;
+            
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+                handleBlock(block);
+            
+            return true;
+        } }
+        
+        RELEASE_ASSERT_NOT_REACHED();
+        return false;
+    }
+
+private:
+    bool handleBlock(BasicBlock* block)
+    {
+        if (verbose) {
+            dataLog("Dealing with block ", pointerDump(block), "\n");
+            if (reallyInsertBarriers())
+                dataLog("    Really inserting barriers.\n");
+        }
+        
+        m_currentEpoch = Epoch::first();
+        
+        if (mode == PhaseMode::Global) {
+            if (!block->cfaHasVisited)
+                return false;
+            m_state->beginBasicBlock(block);
+            
+            for (Node* node : block->ssa->liveAtHead) {
+                if (m_stateAtHead->at(block).contains(node)) {
+                    // If previous blocks tell us that this node may need a barrier in the
+                    // future, then put it in the ancient primordial epoch. This forces us to
+                    // emit a barrier on any possibly-cell store, regardless of the epoch of the
+                    // stored value.
+                    node->setEpoch(Epoch());
+                } else {
+                    // If previous blocks aren't requiring us to run a barrier on this node,
+                    // then put it in the current epoch. This means that we will skip barriers
+                    // on this node so long as we don't allocate. It also means that we won't
+                    // run barriers on stores to on one such node into another such node. That's
+                    // fine, because nodes would be excluded from the state set if at the tails
+                    // of all predecessors they always had the current epoch.
+                    node->setEpoch(m_currentEpoch);
+                }
+            }
+        }
+
+        bool result = true;
+        
+        for (m_nodeIndex = 0; m_nodeIndex < block->size(); ++m_nodeIndex) {
+            m_node = block->at(m_nodeIndex);
+            
+            if (verbose) {
+                dataLog(
+                    "    ", m_currentEpoch, ": Looking at node ", m_node, " with children: ");
+                CommaPrinter comma;
+                m_graph.doToChildren(
+                    m_node,
+                    [&] (Edge edge) {
+                        dataLog(comma, edge, " (", edge->epoch(), ")");
+                    });
+                dataLog("\n");
+            }
+            
+            if (mode == PhaseMode::Global) {
+                // Execute edges separately because we don't want to insert barriers if the
+                // operation doing the store does a check that ensures that the child is not
+                // a cell.
+                m_interpreter->startExecuting();
+                m_interpreter->executeEdges(m_node);
+            }
+            
+            switch (m_node->op()) {
+            case PutByValDirect:
+            case PutByVal:
+            case PutByValAlias: {
+                switch (m_node->arrayMode().modeForPut().type()) {
+                case Array::Contiguous:
+                case Array::ArrayStorage:
+                case Array::SlowPutArrayStorage: {
+                    Edge child1 = m_graph.varArgChild(m_node, 0);
+                    Edge child3 = m_graph.varArgChild(m_node, 2);
+                    considerBarrier(child1, child3);
+                    break;
+                }
+                default:
+                    break;
+                }
+                break;
+            }
+                
+            case ArrayPush: {
+                switch (m_node->arrayMode().type()) {
+                case Array::Contiguous:
+                case Array::ArrayStorage:
+                    considerBarrier(m_node->child1(), m_node->child2());
+                    break;
+                default:
+                    break;
+                }
+                break;
+            }
+                
+            case PutStructure: {
+                considerBarrier(m_node->child1());
+                break;
+            }
+                
+            case PutClosureVar:
+            case PutToArguments:
+            case PutById:
+            case PutByIdFlush:
+            case PutByIdDirect:
+            case MultiPutByOffset: {
+                considerBarrier(m_node->child1(), m_node->child2());
+                break;
+            }
+                
+            case PutByOffset: {
+                considerBarrier(m_node->child2(), m_node->child3());
+                break;
+            }
+                
+            case PutGlobalVar: {
+                considerBarrier(m_node->child1(), m_node->child2());
+                break;
+            }
+                
+            default:
+                break;
+            }
+            
+            if (doesGC(m_graph, m_node))
+                m_currentEpoch.bump();
+            
+            switch (m_node->op()) {
+            case NewObject:
+            case NewArray:
+            case NewArrayWithSize:
+            case NewArrayBuffer:
+            case NewTypedArray:
+            case NewRegexp:
+            case MaterializeNewObject:
+            case MaterializeCreateActivation:
+            case NewStringObject:
+            case MakeRope:
+            case CreateActivation:
+            case CreateDirectArguments:
+            case CreateScopedArguments:
+            case CreateClonedArguments:
+            case NewFunction:
+                // Nodes that allocate get to set their epoch because for those nodes we know
+                // that they will be the newest object in the heap.
+                m_node->setEpoch(m_currentEpoch);
+                break;
+                
+            case AllocatePropertyStorage:
+            case ReallocatePropertyStorage:
+                // These allocate but then run their own barrier.
+                insertBarrier(m_nodeIndex + 1, m_node->child1().node());
+                m_node->setEpoch(Epoch());
+                break;
+                
+            case Upsilon:
+                m_node->phi()->setEpoch(m_node->epoch());
+                m_node->setEpoch(Epoch());
+                break;
+                
+            default:
+                // For nodes that aren't guaranteed to allocate, we say that their return value
+                // (if there is one) could be arbitrarily old.
+                m_node->setEpoch(Epoch());
+                break;
+            }
+            
+            if (verbose) {
+                dataLog(
+                    "    ", m_currentEpoch, ": Done with node ", m_node, " (", m_node->epoch(),
+                    ") with children: ");
+                CommaPrinter comma;
+                m_graph.doToChildren(
+                    m_node,
+                    [&] (Edge edge) {
+                        dataLog(comma, edge, " (", edge->epoch(), ")");
+                    });
+                dataLog("\n");
+            }
+            
+            if (mode == PhaseMode::Global) {
+                if (!m_interpreter->executeEffects(m_nodeIndex, m_node)) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        
+        if (mode == PhaseMode::Global)
+            m_state->reset();
+
+        if (reallyInsertBarriers())
+            m_insertionSet.execute(block);
+        
+        return result;
+    }
+    
+    void considerBarrier(Edge base, Edge child)
+    {
+        if (verbose)
+            dataLog("        Considering adding barrier ", base, " => ", child, "\n");
+        
+        // We don't need a store barrier if the child is guaranteed to not be a cell.
+        switch (mode) {
+        case PhaseMode::Fast: {
+            // Don't try too hard because it's too expensive to run AI.
+            if (child->hasConstant()) {
+                if (!child->asJSValue().isCell()) {
+                    if (verbose)
+                        dataLog("            Rejecting because of constant type.\n");
+                    return;
+                }
+            } else {
+                switch (child->result()) {
+                case NodeResultNumber:
+                case NodeResultDouble:
+                case NodeResultInt32:
+                case NodeResultInt52:
+                case NodeResultBoolean:
+                    if (verbose)
+                        dataLog("            Rejecting because of result type.\n");
+                    return;
+                default:
+                    break;
+                }
+            }
+            break;
+        }
+            
+        case PhaseMode::Global: {
+            // Go into rage mode to eliminate any chance of a barrier with a non-cell child. We
+            // can afford to keep around AI in Global mode.
+            if (!m_interpreter->needsTypeCheck(child, ~SpecCell)) {
+                if (verbose)
+                    dataLog("            Rejecting because of AI type.\n");
+                return;
+            }
+            break;
+        } }
+        
+        // We don't need a store barrier if the base is at least as new as the child. For
+        // example this won't need a barrier:
+        //
+        // var o = {}
+        // var p = {}
+        // p.f = o
+        //
+        // This is stronger than the currentEpoch rule in considerBarrier(Edge), because it will
+        // also eliminate barriers in cases like this:
+        //
+        // var o = {} // o.epoch = 1, currentEpoch = 1
+        // var p = {} // o.epoch = 1, p.epoch = 2, currentEpoch = 2
+        // var q = {} // o.epoch = 1, p.epoch = 2, q.epoch = 3, currentEpoch = 3
+        // p.f = o // p.epoch >= o.epoch
+        //
+        // This relationship works because if it holds then we are in one of the following
+        // scenarios. Note that we don't know *which* of these scenarios we are in, but it's
+        // one of them (though without loss of generality, you can replace "a GC happened" with
+        // "many GCs happened").
+        //
+        // 1) There is no GC between the allocation/last-barrier of base, child and now. Then
+        //    we definitely don't need a barrier.
+        //
+        // 2) There was a GC after child was allocated but before base was allocated. Then we
+        //    don't need a barrier, because base is still a new object.
+        //
+        // 3) There was a GC after both child and base were allocated. Then they are both old.
+        //    We don't need barriers on stores of old into old. Note that in this case it
+        //    doesn't matter if there was also a GC between the allocation of child and base.
+        //
+        // Note that barriers will lift an object into the current epoch. This is sort of weird.
+        // It means that later if you store that object into some other object, and that other
+        // object was previously newer object, you'll think that you need a barrier. We could
+        // avoid this by tracking allocation epoch and barrier epoch separately. For now I think
+        // that this would be overkill. But this does mean that there are the following
+        // possibilities when this relationship holds:
+        //
+        // 4) Base is allocated first. A GC happens and base becomes old. Then we allocate
+        //    child. (Note that alternatively the GC could happen during the allocation of
+        //    child.) Then we run a barrier on base. Base will appear to be as new as child
+        //    (same epoch). At this point, we don't need another barrier on base.
+        //
+        // 5) Base is allocated first. Then we allocate child. Then we run a GC. Then we run a
+        //    barrier on base. Base will appear newer than child. We don't need a barrier
+        //    because both objects are old.
+        //
+        // Something we watch out for here is that the null epoch is a catch-all for objects
+        // allocated before we did any epoch tracking. Two objects being in the null epoch
+        // means that we don't know their epoch relationship.
+        if (!!base->epoch() && base->epoch() >= child->epoch()) {
+            if (verbose)
+                dataLog("            Rejecting because of epoch ordering.\n");
+            return;
+        }
+        
+        considerBarrier(base);
+    }
+    
+    void considerBarrier(Edge base)
+    {
+        if (verbose)
+            dataLog("        Considering adding barrier on ", base, "\n");
+        
+        // We don't need a store barrier if the epoch of the base is identical to the current
+        // epoch. That means that we either just allocated the object and so it's guaranteed to
+        // be in newgen, or we just ran a barrier on it so it's guaranteed to be remembered
+        // already.
+        if (base->epoch() == m_currentEpoch) {
+            if (verbose)
+                dataLog("            Rejecting because it's in the current epoch.\n");
+            return;
+        }
+        
+        if (verbose)
+            dataLog("            Inserting barrier.\n");
+        insertBarrier(m_nodeIndex, base.node());
+    }
+    
+    void insertBarrier(unsigned nodeIndex, Node* base)
+    {
+        // If we're in global mode, we should only insert the barriers once we have converged.
+        if (!reallyInsertBarriers())
+            return;
+        
+        // FIXME: We could support StoreBarrier(UntypedUse:). That would be sort of cool.
+        // But right now we don't need it.
+        m_insertionSet.insertNode(
+            nodeIndex, SpecNone, StoreBarrier, m_node->origin, Edge(base, CellUse));
+
+        base->setEpoch(m_currentEpoch);
+    }
+    
+    bool reallyInsertBarriers()
+    {
+        return mode == PhaseMode::Fast || m_isConverged;
+    }
+    
+    InsertionSet m_insertionSet;
+    Epoch m_currentEpoch;
+    unsigned m_nodeIndex;
+    Node* m_node;
+    
+    // Things we only use in Global mode.
+    std::unique_ptr<InPlaceAbstractState> m_state;
+    std::unique_ptr<AbstractInterpreter<InPlaceAbstractState>> m_interpreter;
+    std::unique_ptr<BlockMap<HashSet<Node*>>> m_stateAtHead;
+    std::unique_ptr<BlockMap<HashSet<Node*>>> m_stateAtTail;
+    bool m_isConverged;
+};
+
+} // anonymous namespace
+
+bool performFastStoreBarrierInsertion(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Fast Store Barrier Insertion Phase");
+    return runPhase<StoreBarrierInsertionPhase<PhaseMode::Fast>>(graph);
+}
+
+bool performGlobalStoreBarrierInsertion(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Global Store Barrier Insertion Phase");
+    return runPhase<StoreBarrierInsertionPhase<PhaseMode::Global>>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGStoreBarrierInsertionPhase.h b/dfg/DFGStoreBarrierInsertionPhase.h
new file mode 100644 (file)
index 0000000..352759e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGStoreBarrierInsertionPhase_h
+#define DFGStoreBarrierInsertionPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Inserts store barriers in a block-local manner without consulting the abstract interpreter.
+// Uses a simple epoch-based analysis to avoid inserting redundant barriers. This phase requires
+// that we are not in SSA.
+bool performFastStoreBarrierInsertion(Graph&);
+
+// Inserts store barriers using a global analysis and consults the abstract interpreter. Uses a
+// simple epoch-based analysis to avoid inserting redundant barriers, but only propagates "same
+// epoch as current" property from one block to the next. This phase requires SSA. This phase
+// also requires having valid AI and liveness.
+bool performGlobalStoreBarrierInsertion(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStoreBarrierInsertionPhase_h
+
index 1f837d3d38689932efd54e1b3c1b3076f008359d..03515d52af5285ea3d2fceece29767f027be2bfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,8 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGAbstractHeap.h"
+#include "DFGClobberize.h"
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
 #include "DFGPhase.h"
@@ -72,12 +74,9 @@ private:
         case BitOr:
             handleCommutativity();
 
-            if (m_node->child2()->isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
-                if (op2.isInt32() && !op2.asInt32()) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !m_node->child2()->asInt32()) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
@@ -89,39 +88,29 @@ private:
         case BitLShift:
         case BitRShift:
         case BitURShift:
-            if (m_node->child2()->isConstant()) {
-                JSValue op2 = m_graph.valueOfJSConstant(m_node->child2().node());
-                if (op2.isInt32() && !(op2.asInt32() & 0x1f)) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
         case UInt32ToNumber:
             if (m_node->child1()->op() == BitURShift
-                && m_node->child1()->child2()->isConstant()) {
-                JSValue shiftAmount = m_graph.valueOfJSConstant(
-                    m_node->child1()->child2().node());
-                if (shiftAmount.isInt32() && (shiftAmount.asInt32() & 0x1f)
-                    && m_node->arithMode() != Arith::DoOverflow) {
-                    m_node->convertToIdentity();
-                    m_changed = true;
-                    break;
-                }
+                && m_node->child1()->child2()->isInt32Constant()
+                && (m_node->child1()->child2()->asInt32() & 0x1f)
+                && m_node->arithMode() != Arith::DoOverflow) {
+                m_node->convertToIdentity();
+                m_changed = true;
+                break;
             }
             break;
             
         case ArithAdd:
             handleCommutativity();
             
-            if (m_graph.isInt32Constant(m_node->child2().node())) {
-                int32_t value = m_graph.valueOfInt32Constant(
-                    m_node->child2().node());
-                if (!value) {
-                    convertToIdentityOverChild1();
-                    break;
-                }
+            if (m_node->child2()->isInt32Constant() && !m_node->child2()->asInt32()) {
+                convertToIdentityOverChild1();
+                break;
             }
             break;
             
@@ -130,9 +119,9 @@ private:
             break;
             
         case ArithSub:
-            if (m_graph.isInt32Constant(m_node->child2().node())
+            if (m_node->child2()->isInt32Constant()
                 && m_node->isBinaryUseKind(Int32Use)) {
-                int32_t value = m_graph.valueOfInt32Constant(m_node->child2().node());
+                int32_t value = m_node->child2()->asInt32();
                 if (-value != value) {
                     m_node->setOp(ArithAdd);
                     m_node->child2().setNode(
@@ -143,34 +132,20 @@ private:
                 }
             }
             break;
-            
-        case GetArrayLength:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))
-                foldTypedArrayPropertyToConstant(view, jsNumber(view->length()));
-            break;
-            
-        case GetTypedArrayByteOffset:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node->child1().node()))
-                foldTypedArrayPropertyToConstant(view, jsNumber(view->byteOffset()));
-            break;
-            
-        case GetIndexedPropertyStorage:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
-                if (view->mode() != FastTypedArray) {
-                    prepareToFoldTypedArray(view);
-                    m_node->convertToConstantStoragePointer(view->vector());
+
+        case ArithPow:
+            if (m_node->child2()->isNumberConstant()) {
+                double yOperandValue = m_node->child2()->asNumber();
+                if (yOperandValue == 1) {
+                    convertToIdentityOverChild1();
+                } else if (yOperandValue == 0.5) {
+                    m_insertionSet.insertCheck(m_nodeIndex, m_node);
+                    m_node->convertToArithSqrt();
                     m_changed = true;
-                    break;
-                } else {
-                    // FIXME: It would be awesome to be able to fold the property storage for
-                    // these GC-allocated typed arrays. For now it doesn't matter because the
-                    // most common use-cases for constant typed arrays involve large arrays with
-                    // aliased buffer views.
-                    // https://bugs.webkit.org/show_bug.cgi?id=125425
                 }
             }
             break;
-            
+
         case ValueRep:
         case Int52Rep:
         case DoubleRep: {
@@ -191,8 +166,7 @@ private:
             for (Node* node = m_node->child1().node(); ; node = node->child1().node()) {
                 if (canonicalResultRepresentation(node->result()) ==
                     canonicalResultRepresentation(m_node->result())) {
-                    m_insertionSet.insertNode(
-                        m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->child1());
+                    m_insertionSet.insertCheck(m_nodeIndex, m_node);
                     if (hadInt32Check) {
                         // FIXME: Consider adding Int52RepInt32Use or even DoubleRepInt32Use,
                         // which would be super weird. The latter would only arise in some
@@ -200,9 +174,8 @@ private:
                         if (canonicalResultRepresentation(node->result()) != NodeResultJS)
                             break;
                         
-                        m_insertionSet.insertNode(
-                            m_nodeIndex, SpecNone, Phantom, m_node->origin,
-                            Edge(node, Int32Use));
+                        m_insertionSet.insertCheck(
+                            m_nodeIndex, m_node->origin, Edge(node, Int32Use));
                     }
                     m_node->child1() = node->defaultEdge();
                     m_node->convertToIdentity();
@@ -229,6 +202,34 @@ private:
             break;
         }
             
+        case Flush: {
+            ASSERT(m_graph.m_form != SSA);
+            
+            Node* setLocal = nullptr;
+            VirtualRegister local = m_node->local();
+            
+            for (unsigned i = m_nodeIndex; i--;) {
+                Node* node = m_block->at(i);
+                if (node->op() == SetLocal && node->local() == local) {
+                    setLocal = node;
+                    break;
+                }
+                if (accessesOverlap(m_graph, node, AbstractHeap(Stack, local)))
+                    break;
+            }
+            
+            if (!setLocal)
+                break;
+            
+            // The Flush should become a PhantomLocal at this point. This means that we want the
+            // local's value during OSR, but we don't care if the value is stored to the stack. CPS
+            // rethreading can canonicalize PhantomLocals for us.
+            m_node->convertFlushToPhantomLocal();
+            m_graph.dethread();
+            m_changed = true;
+            break;
+        }
+            
         default:
             break;
         }
@@ -236,8 +237,7 @@ private:
             
     void convertToIdentityOverChild(unsigned childIndex)
     {
-        m_insertionSet.insertNode(
-            m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->children);
+        m_insertionSet.insertCheck(m_nodeIndex, m_node);
         m_node->children.removeEdge(childIndex ^ 1);
         m_node->convertToIdentity();
         m_changed = true;
@@ -253,22 +253,6 @@ private:
         convertToIdentityOverChild(1);
     }
     
-    void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)
-    {
-        prepareToFoldTypedArray(view);
-        m_graph.convertToConstant(m_node, constant);
-        m_changed = true;
-    }
-    
-    void prepareToFoldTypedArray(JSArrayBufferView* view)
-    {
-        m_insertionSet.insertNode(
-            m_nodeIndex, SpecNone, TypedArrayWatchpoint, m_node->origin,
-            OpInfo(view));
-        m_insertionSet.insertNode(
-            m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->children);
-    }
-    
     void handleCommutativity()
     {
         // If the right side is a constant then there is nothing left to do.
diff --git a/dfg/DFGStructureAbstractValue.cpp b/dfg/DFGStructureAbstractValue.cpp
new file mode 100644 (file)
index 0000000..87baa57
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGStructureAbstractValue.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+// Comment out the empty SAMPLE() definition, and uncomment the one that uses SamplingRegion, if
+// you want extremely fine-grained profiling in this code.
+#define SAMPLE(name) 
+//#define SAMPLE(name) SamplingRegion samplingRegion(name)
+
+#if !ASSERT_DISABLED
+void StructureAbstractValue::assertIsRegistered(Graph& graph) const
+{
+    SAMPLE("StructureAbstractValue assertIsRegistered");
+
+    if (isTop())
+        return;
+    
+    for (unsigned i = size(); i--;)
+        graph.assertIsRegistered(at(i));
+}
+#endif // !ASSERT_DISABLED
+
+void StructureAbstractValue::clobber()
+{
+    SAMPLE("StructureAbstractValue clobber");
+
+    // The premise of this approach to clobbering is that anytime we introduce
+    // a watchable structure into an abstract value, we watchpoint it. You can assert
+    // that this holds by calling assertIsWatched().
+        
+    if (isTop())
+        return;
+
+    setClobbered(true);
+        
+    if (m_set.isThin()) {
+        if (!m_set.singleEntry())
+            return;
+        if (!m_set.singleEntry()->dfgShouldWatch())
+            makeTopWhenThin();
+        return;
+    }
+    
+    StructureSet::OutOfLineList* list = m_set.list();
+    for (unsigned i = list->m_length; i--;) {
+        if (!list->list()[i]->dfgShouldWatch()) {
+            makeTop();
+            return;
+        }
+    }
+}
+
+void StructureAbstractValue::observeTransition(Structure* from, Structure* to)
+{
+    SAMPLE("StructureAbstractValue observeTransition");
+    
+    ASSERT(!from->dfgShouldWatch());
+
+    if (isTop())
+        return;
+    
+    if (!m_set.contains(from))
+        return;
+    
+    if (!m_set.add(to))
+        return;
+    
+    if (m_set.size() > polymorphismLimit)
+        makeTop();
+}
+
+void StructureAbstractValue::observeTransitions(const TransitionVector& vector)
+{
+    SAMPLE("StructureAbstractValue observeTransitions");
+
+    if (isTop())
+        return;
+    
+    StructureSet newStructures;
+    for (unsigned i = vector.size(); i--;) {
+        ASSERT(!vector[i].previous->dfgShouldWatch());
+
+        if (!m_set.contains(vector[i].previous))
+            continue;
+        
+        newStructures.add(vector[i].next);
+    }
+    
+    if (!m_set.merge(newStructures))
+        return;
+    
+    if (m_set.size() > polymorphismLimit)
+        makeTop();
+}
+
+bool StructureAbstractValue::add(Structure* structure)
+{
+    SAMPLE("StructureAbstractValue add");
+
+    if (isTop())
+        return false;
+    
+    if (!m_set.add(structure))
+        return false;
+    
+    if (m_set.size() > polymorphismLimit)
+        makeTop();
+    
+    return true;
+}
+
+bool StructureAbstractValue::merge(const StructureSet& other)
+{
+    SAMPLE("StructureAbstractValue merge set");
+
+    if (isTop())
+        return false;
+    
+    return mergeNotTop(other);
+}
+
+bool StructureAbstractValue::mergeSlow(const StructureAbstractValue& other)
+{
+    SAMPLE("StructureAbstractValue merge value slow");
+
+    // It isn't immediately obvious that the code below is doing the right thing, so let's go
+    // through it.
+    //
+    // This not clobbered, other not clobbered: Clearly, we don't want to make anything clobbered
+    // since we just have two sets and we are merging them. mergeNotTop() can handle this just
+    // fine.
+    //
+    // This clobbered, other clobbered: Clobbered means that we have a set of things, plus we
+    // temporarily have the set of all things but the latter will go away once we hit the next
+    // invalidation point. This allows us to merge two clobbered sets the natural way. For now
+    // the set will still be TOP (and so we keep the clobbered bit set), but we know that after
+    // invalidation, we will have the union of the this and other.
+    //
+    // This clobbered, other not clobbered: It's safe to merge in other for both before and after
+    // invalidation, so long as we leave the clobbered bit set. Before invalidation this has no
+    // effect since the set will still appear to have all things in it. The way to think about
+    // what invalidation would do is imagine if we had a set A that was clobbered and a set B
+    // that wasn't and we considered the following two cases. Note that we expect A to be the
+    // same at the end in both cases:
+    //
+    //            A.merge(B)                             InvalidationPoint
+    //            InvalidationPoint                      A.merge(B)
+    //
+    // The fact that we expect A to be the same in both cases means that we want to merge other
+    // into this but keep the clobbered bit.
+    //
+    // This not clobbered, other clobbered: This is just the converse of the previous case. We
+    // want to merge other into this and set the clobbered bit.
+    
+    bool changed = false;
+    
+    if (!isClobbered() && other.isClobbered()) {
+        setClobbered(true);
+        changed = true;
+    }
+    
+    changed |= mergeNotTop(other.m_set);
+    
+    return changed;
+}
+
+bool StructureAbstractValue::mergeNotTop(const StructureSet& other)
+{
+    SAMPLE("StructureAbstractValue merge not top");
+
+    if (!m_set.merge(other))
+        return false;
+    
+    if (m_set.size() > polymorphismLimit)
+        makeTop();
+    
+    return true;
+}
+
+void StructureAbstractValue::filter(const StructureSet& other)
+{
+    SAMPLE("StructureAbstractValue filter set");
+
+    if (isTop()) {
+        m_set = other;
+        return;
+    }
+    
+    if (isClobbered()) {
+        // We have two choices here:
+        //
+        // Do nothing: It's legal to keep our set intact, which would essentially mean that for
+        // now, our set would behave like TOP but after the next invalidation point it wold be
+        // a finite set again. This may be a good choice if 'other' is much bigger than our
+        // m_set.
+        //
+        // Replace m_set with other and clear the clobber bit: This is also legal, and means that
+        // we're no longer clobbered. This is usually better because it immediately gives us a
+        // smaller set.
+        //
+        // This scenario should come up rarely. We usually don't do anything to an abstract value
+        // after it is clobbered. But we apply some heuristics.
+        
+        if (other.size() > m_set.size() + clobberedSupremacyThreshold)
+            return; // Keep the clobbered set.
+        
+        m_set = other;
+        setClobbered(false);
+        return;
+    }
+    
+    m_set.filter(other);
+}
+
+void StructureAbstractValue::filter(const StructureAbstractValue& other)
+{
+    SAMPLE("StructureAbstractValue filter value");
+
+    if (other.isTop())
+        return;
+    
+    if (other.isClobbered()) {
+        if (isTop())
+            return;
+        
+        if (!isClobbered()) {
+            // See justification in filter(const StructureSet&), above. An unclobbered set is
+            // almost always better.
+            if (m_set.size() > other.m_set.size() + clobberedSupremacyThreshold)
+                *this = other; // Keep the clobbered set.
+            return;
+        }
+
+        m_set.filter(other.m_set);
+        return;
+    }
+    
+    filter(other.m_set);
+}
+
+void StructureAbstractValue::filterSlow(SpeculatedType type)
+{
+    SAMPLE("StructureAbstractValue filter type slow");
+
+    if (!(type & SpecCell)) {
+        clear();
+        return;
+    }
+    
+    ASSERT(!isTop());
+    
+    m_set.genericFilter(
+        [&] (Structure* structure) {
+            return !!(speculationFromStructure(structure) & type);
+        });
+}
+
+bool StructureAbstractValue::contains(Structure* structure) const
+{
+    SAMPLE("StructureAbstractValue contains");
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.contains(structure);
+}
+
+bool StructureAbstractValue::isSubsetOf(const StructureSet& other) const
+{
+    SAMPLE("StructureAbstractValue isSubsetOf set");
+
+    if (isTop() || isClobbered())
+        return false;
+    
+    return m_set.isSubsetOf(other);
+}
+
+bool StructureAbstractValue::isSubsetOf(const StructureAbstractValue& other) const
+{
+    SAMPLE("StructureAbstractValue isSubsetOf value");
+
+    if (isTop())
+        return false;
+    
+    if (other.isTop())
+        return true;
+    
+    if (isClobbered() == other.isClobbered())
+        return m_set.isSubsetOf(other.m_set);
+    
+    // Here it gets tricky. If in doubt, return false!
+    
+    if (isClobbered())
+        return false; // A clobbered set is never a subset of an unclobbered set.
+    
+    // An unclobbered set is currently a subset of a clobbered set, but it may not be so after
+    // invalidation.
+    return m_set.isSubsetOf(other.m_set);
+}
+
+bool StructureAbstractValue::isSupersetOf(const StructureSet& other) const
+{
+    SAMPLE("StructureAbstractValue isSupersetOf set");
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.isSupersetOf(other);
+}
+
+bool StructureAbstractValue::overlaps(const StructureSet& other) const
+{
+    SAMPLE("StructureAbstractValue overlaps set");
+
+    if (isTop() || isClobbered())
+        return true;
+    
+    return m_set.overlaps(other);
+}
+
+bool StructureAbstractValue::overlaps(const StructureAbstractValue& other) const
+{
+    SAMPLE("StructureAbstractValue overlaps value");
+
+    if (other.isTop() || other.isClobbered())
+        return true;
+    
+    return overlaps(other.m_set);
+}
+
+bool StructureAbstractValue::equalsSlow(const StructureAbstractValue& other) const
+{
+    SAMPLE("StructureAbstractValue equalsSlow");
+
+    ASSERT(m_set.m_pointer != other.m_set.m_pointer);
+    ASSERT(!isTop());
+    ASSERT(!other.isTop());
+    
+    return m_set == other.m_set
+        && isClobbered() == other.isClobbered();
+}
+
+void StructureAbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    if (isClobbered())
+        out.print("Clobbered:");
+    
+    if (isTop())
+        out.print("TOP");
+    else
+        out.print(inContext(m_set, context));
+}
+
+void StructureAbstractValue::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
+void StructureAbstractValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    if (isTop())
+        return;
+    m_set.validateReferences(trackedReferences);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
index 10e476c6e0afc45adee9417403cbf6ed128c746a..2b87cdcda5253783ae6f2d33486175be4fb7e042 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGTransition.h"
 #include "JSCell.h"
 #include "SpeculatedType.h"
 #include "DumpContext.h"
 #include "StructureSet.h"
 
-namespace JSC { namespace DFG {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace DFG {
 
 class StructureAbstractValue {
 public:
-    StructureAbstractValue()
-        : m_structure(0)
-    {
-    }
-    
+    StructureAbstractValue() { }
     StructureAbstractValue(Structure* structure)
-        : m_structure(structure)
+        : m_set(StructureSet(structure))
     {
+        setClobbered(false);
     }
-    
-    StructureAbstractValue(const StructureSet& set)
+    StructureAbstractValue(const StructureSet& other)
+        : m_set(other)
     {
-        switch (set.size()) {
-        case 0:
-            m_structure = 0;
-            break;
-            
-        case 1:
-            m_structure = set[0];
-            break;
-            
-        default:
-            m_structure = topValue();
-            break;
-        }
+        setClobbered(false);
     }
-    
-    void clear()
+    ALWAYS_INLINE StructureAbstractValue(const StructureAbstractValue& other)
+        : m_set(other.m_set)
     {
-        m_structure = 0;
+        setClobbered(other.isClobbered());
     }
     
-    void makeTop()
+    ALWAYS_INLINE StructureAbstractValue& operator=(Structure* structure)
     {
-        m_structure = topValue();
+        m_set = StructureSet(structure);
+        setClobbered(false);
+        return *this;
     }
-    
-    static StructureAbstractValue top()
+    ALWAYS_INLINE StructureAbstractValue& operator=(const StructureSet& other)
     {
-        StructureAbstractValue value;
-        value.makeTop();
-        return value;
+        m_set = other;
+        setClobbered(false);
+        return *this;
     }
-    
-    void add(Structure* structure)
+    ALWAYS_INLINE StructureAbstractValue& operator=(const StructureAbstractValue& other)
     {
-        ASSERT(!contains(structure) && !isTop());
-        if (m_structure)
-            makeTop();
-        else
-            m_structure = structure;
+        m_set = other.m_set;
+        setClobbered(other.isClobbered());
+        return *this;
     }
     
-    bool addAll(const StructureSet& other)
+    void clear()
     {
-        if (isTop() || !other.size())
-            return false;
-        if (other.size() > 1) {
-            makeTop();
-            return true;
-        }
-        if (!m_structure) {
-            m_structure = other[0];
-            return true;
-        }
-        if (m_structure == other[0])
-            return false;
-        makeTop();
-        return true;
+        m_set.clear();
+        setClobbered(false);
     }
     
-    bool addAll(const StructureAbstractValue& other)
+    void makeTop()
     {
-        if (!other.m_structure)
-            return false;
-        if (isTop())
-            return false;
-        if (other.isTop()) {
-            makeTop();
-            return true;
-        }
-        if (m_structure) {
-            if (m_structure == other.m_structure)
-                return false;
-            makeTop();
-            return true;
-        }
-        m_structure = other.m_structure;
-        return true;
+        m_set.deleteListIfNecessary();
+        m_set.m_pointer = topValue;
     }
     
-    bool contains(Structure* structure) const
-    {
-        if (isTop())
-            return true;
-        if (m_structure == structure)
-            return true;
-        return false;
-    }
+#if ASSERT_DISABLED
+    void assertIsRegistered(Graph&) const { }
+#else
+    void assertIsRegistered(Graph&) const;
+#endif
     
-    bool isSubsetOf(const StructureSet& other) const
-    {
-        if (isTop())
-            return false;
-        if (!m_structure)
-            return true;
-        return other.contains(m_structure);
-    }
+    void clobber();
+    void observeInvalidationPoint() { setClobbered(false); }
     
-    bool doesNotContainAnyOtherThan(Structure* structure) const
-    {
-        if (isTop())
-            return false;
-        if (!m_structure)
-            return true;
-        return m_structure == structure;
-    }
+    void observeTransition(Structure* from, Structure* to);
+    void observeTransitions(const TransitionVector&);
     
-    bool isSupersetOf(const StructureSet& other) const
+    static StructureAbstractValue top()
     {
-        if (isTop())
-            return true;
-        if (!other.size())
-            return true;
-        if (other.size() > 1)
-            return false;
-        return m_structure == other[0];
+        StructureAbstractValue result;
+        result.m_set.m_pointer = topValue;
+        return result;
     }
     
-    bool isSubsetOf(const StructureAbstractValue& other) const
-    {
-        if (other.isTop())
-            return true;
-        if (isTop())
-            return false;
-        if (m_structure) {
-            if (other.m_structure)
-                return m_structure == other.m_structure;
-            return false;
-        }
-        return true;
-    }
+    bool isClear() const { return m_set.isEmpty(); }
+    bool isTop() const { return m_set.m_pointer == topValue; }
+    bool isNeitherClearNorTop() const { return !isClear() && !isTop(); }
     
-    bool isSupersetOf(const StructureAbstractValue& other) const
-    {
-        return other.isSubsetOf(*this);
-    }
+    // A clobbered abstract value means that the set currently contains the m_set set of
+    // structures plus TOP, except that the "plus TOP" will go away at the next invalidation
+    // point. Note that it's tempting to think of this as "the set of structures in m_set plus
+    // the set of structures transition-reachable from m_set" - but this isn't really correct,
+    // since if we add an unwatchable structure after clobbering, the two definitions are not
+    // equivalent. If we do this, the new unwatchable structure will be added to m_set.
+    // Invalidation points do not try to "clip" the set of transition-reachable structures from
+    // m_set by looking at reachability as this would mean that the new set is TOP. Instead they
+    // literally assume that the set is just m_set rather than m_set plus TOP.
+    bool isClobbered() const { return m_set.getReservedFlag(); }
     
-    void filter(const StructureSet& other)
+    bool add(Structure* structure);
+    
+    bool merge(const StructureSet& other);
+    
+    ALWAYS_INLINE bool merge(const StructureAbstractValue& other)
     {
-        if (!m_structure)
-            return;
+        if (other.isClear())
+            return false;
         
-        if (isTop()) {
-            switch (other.size()) {
-            case 0:
-                m_structure = 0;
-                return;
-                
-            case 1:
-                m_structure = other[0];
-                return;
-                
-            default:
-                return;
-            }
-        }
+        if (isTop())
+            return false;
         
-        if (other.contains(m_structure))
-            return;
+        if (other.isTop()) {
+            makeTop();
+            return true;
+        }
         
-        m_structure = 0;
+        return mergeSlow(other);
     }
     
-    void filter(const StructureAbstractValue& other)
+    void filter(const StructureSet& other);
+    void filter(const StructureAbstractValue& other);
+    
+    ALWAYS_INLINE void filter(SpeculatedType type)
     {
-        if (isTop()) {
-            m_structure = other.m_structure;
+        if (!(type & SpecCell)) {
+            clear();
             return;
         }
-        if (m_structure == other.m_structure)
-            return;
-        if (other.isTop())
-            return;
-        m_structure = 0;
+        if (isNeitherClearNorTop())
+            filterSlow(type);
     }
     
-    void filter(SpeculatedType other)
+    ALWAYS_INLINE bool operator==(const StructureAbstractValue& other) const
     {
-        if (!(other & SpecCell)) {
-            clear();
-            return;
-        }
+        if ((m_set.isThin() && other.m_set.isThin()) || isTop() || other.isTop())
+            return m_set.m_pointer == other.m_set.m_pointer;
         
-        if (isClearOrTop())
-            return;
-
-        if (!(speculationFromStructure(m_structure) & other))
-            m_structure = 0;
+        return equalsSlow(other);
     }
     
-    bool isClear() const
+    const StructureSet& set() const
     {
-        return !m_structure;
+        ASSERT(!isTop());
+        return m_set;
     }
     
-    bool isTop() const { return m_structure == topValue(); }
-    
-    bool isClearOrTop() const { return m_structure <= topValue(); }
-    bool isNeitherClearNorTop() const { return !isClearOrTop(); }
-    
     size_t size() const
     {
         ASSERT(!isTop());
-        return !!m_structure;
+        return m_set.size();
     }
     
     Structure* at(size_t i) const
     {
         ASSERT(!isTop());
-        ASSERT(m_structure);
-        ASSERT_UNUSED(i, !i);
-        return m_structure;
+        return m_set.at(i);
     }
     
-    Structure* operator[](size_t i) const
-    {
-        return at(i);
-    }
+    Structure* operator[](size_t i) const { return at(i); }
     
-    Structure* last() const
+    // In most cases, what you really want to do is verify whether the set is top or clobbered, and
+    // if not, enumerate the set of structures. Use this only in cases where the singleton case is
+    // meaningfully special, like for transitions.
+    Structure* onlyStructure() const
     {
-        return at(0);
+        if (isTop() || isClobbered())
+            return nullptr;
+        return m_set.onlyStructure();
     }
     
-    SpeculatedType speculationFromStructures() const
-    {
-        if (isTop())
-            return SpecCell;
-        if (isClear())
-            return SpecNone;
-        return speculationFromStructure(m_structure);
-    }
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
     
-    bool isValidOffset(PropertyOffset offset)
-    {
-        if (isTop())
-            return false;
-        if (isClear())
-            return true;
-        return m_structure->isValidOffset(offset);
-    }
+    // The methods below are all conservative and err on the side of making 'this' appear bigger
+    // than it is. For example, contains() may return true if the set is clobbered or TOP.
+    // isSubsetOf() may return false in case of ambiguities. Therefore you should only perform
+    // optimizations as a consequence of the "this is smaller" return value - so false for
+    // contains(), true for isSubsetOf(), false for isSupersetOf(), and false for overlaps().
+
+    bool contains(Structure* structure) const;
     
-    bool hasSingleton() const
-    {
-        return isNeitherClearNorTop();
-    }
+    bool isSubsetOf(const StructureSet& other) const;
+    bool isSubsetOf(const StructureAbstractValue& other) const;
     
-    Structure* singleton() const
+    bool isSupersetOf(const StructureSet& other) const;
+    bool isSupersetOf(const StructureAbstractValue& other) const
     {
-        ASSERT(isNeitherClearNorTop());
-        return m_structure;
+        return other.isSubsetOf(*this);
     }
     
-    bool operator==(const StructureAbstractValue& other) const
-    {
-        return m_structure == other.m_structure;
-    }
+    bool overlaps(const StructureSet& other) const;
+    bool overlaps(const StructureAbstractValue& other) const;
     
-    void dumpInContext(PrintStream& out, DumpContext* context) const
+    void validateReferences(const TrackedReferences&) const;
+    
+private:
+    static const uintptr_t clobberedFlag = StructureSet::reservedFlag;
+    static const uintptr_t topValue = StructureSet::reservedValue;
+    static const unsigned polymorphismLimit = 10;
+    static const unsigned clobberedSupremacyThreshold = 2;
+    
+    void filterSlow(SpeculatedType type);
+    bool mergeSlow(const StructureAbstractValue& other);
+    
+    bool equalsSlow(const StructureAbstractValue& other) const;
+    
+    void makeTopWhenThin()
     {
-        if (isTop()) {
-            out.print("TOP");
-            return;
-        }
-        
-        out.print("[");
-        if (m_structure)
-            out.print(inContext(*m_structure, context));
-        out.print("]");
+        ASSERT(m_set.isThin());
+        m_set.m_pointer = topValue;
     }
-
-    void dump(PrintStream& out) const
+    
+    bool mergeNotTop(const StructureSet& other);
+    
+    void setClobbered(bool clobbered)
     {
-        dumpInContext(out, 0);
+        ASSERT(!isTop() || !clobbered);
+        m_set.setReservedFlag(clobbered);
     }
-
-private:
-    static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
-    
-    // NB. This must have a trivial destructor.
     
-    // This can only remember one structure at a time.
-    Structure* m_structure;
+    StructureSet m_set;
 };
 
 } } // namespace JSC::DFG
diff --git a/dfg/DFGStructureClobberState.h b/dfg/DFGStructureClobberState.h
new file mode 100644 (file)
index 0000000..ac4275a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGStructureClobberState_h
+#define DFGStructureClobberState_h
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+enum StructureClobberState {
+    StructuresAreWatched, // Constants with watchable structures must have those structures.
+    StructuresAreClobbered // Constants with watchable structures could have any structure.
+};
+
+inline StructureClobberState merge(StructureClobberState a, StructureClobberState b)
+{
+    switch (a) {
+    case StructuresAreWatched:
+        return b;
+    case StructuresAreClobbered:
+        return StructuresAreClobbered;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return StructuresAreClobbered;
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+inline void printInternal(PrintStream& out, JSC::DFG::StructureClobberState state)
+{
+    switch (state) {
+    case JSC::DFG::StructuresAreWatched:
+        out.print("StructuresAreWatched");
+        return;
+    case JSC::DFG::StructuresAreClobbered:
+        out.print("StructuresAreClobbered");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStructureClobberState_h
diff --git a/dfg/DFGStructureRegistrationPhase.cpp b/dfg/DFGStructureRegistrationPhase.cpp
new file mode 100644 (file)
index 0000000..875e0d3
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGStructureRegistrationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+class StructureRegistrationPhase : public Phase {
+public:
+    StructureRegistrationPhase(Graph& graph)
+        : Phase(graph, "structure registration")
+    {
+    }
+    
+    bool run()
+    {
+        // We need to set this before this phase finishes. This phase doesn't do anything
+        // conditioned on this field, except for assertIsRegistered() below. We intend for that
+        // method to behave as if the phase was already finished. So, we set this up here.
+        m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
+        
+        // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
+        // have to watch these because there is no way to transition away from it, but they are
+        // watchable and so we will assert if they aren't watched.
+        registerStructure(m_graph.m_vm.structureStructure.get());
+        registerStructure(m_graph.m_vm.stringStructure.get());
+        registerStructure(m_graph.m_vm.getterSetterStructure.get());
+        
+        for (FrozenValue* value : m_graph.m_frozenValues)
+            m_graph.assertIsRegistered(value->structure());
+        
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+        
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+            
+                switch (node->op()) {
+                case CheckStructure:
+                    registerStructures(node->structureSet());
+                    break;
+                
+                case NewObject:
+                case ArrayifyToStructure:
+                case NewStringObject:
+                    registerStructure(node->structure());
+                    break;
+                
+                case PutStructure:
+                case AllocatePropertyStorage:
+                case ReallocatePropertyStorage:
+                    registerStructure(node->transition()->previous);
+                    registerStructure(node->transition()->next);
+                    break;
+                    
+                case MultiGetByOffset:
+                    for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
+                        GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
+                        registerStructures(variant.structureSet());
+                        // Don't need to watch anything in the structure chain because that would
+                        // have been decomposed into CheckStructure's. Don't need to watch the
+                        // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
+                        // variants did that.
+                        ASSERT(!variant.callLinkStatus());
+                    }
+                    break;
+                    
+                case MultiPutByOffset:
+                    for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
+                        PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
+                        registerStructures(variant.oldStructure());
+                        if (variant.kind() == PutByIdVariant::Transition)
+                            registerStructure(variant.newStructure());
+                    }
+                    break;
+                    
+                case NewArray:
+                case NewArrayBuffer:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
+                    break;
+                    
+                case NewTypedArray:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
+                    break;
+                    
+                case ToString:
+                case CallStringConstructor:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
+                    break;
+                    
+                case CreateActivation:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
+                    break;
+                    
+                case CreateDirectArguments:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
+                    break;
+                    
+                case CreateScopedArguments:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
+                    break;
+                    
+                case NewRegexp:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
+                    break;
+                    
+                case NewFunction:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
+                    break;
+                    
+                default:
+                    break;
+                }
+            }
+        }
+        
+        return true;
+    }
+
+private:
+    void registerStructures(const StructureSet& set)
+    {
+        for (unsigned i = set.size(); i--;)
+            registerStructure(set[i]);
+    }
+    
+    void registerStructure(Structure* structure)
+    {
+        if (structure)
+            m_graph.registerStructure(structure);
+    }
+};
+
+bool performStructureRegistration(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Structure Registration Phase");
+    return runPhase<StructureRegistrationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGStructureRegistrationPhase.h b/dfg/DFGStructureRegistrationPhase.h
new file mode 100644 (file)
index 0000000..bba7891
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGStructureRegistrationPhase_h
+#define DFGStructureRegistrationPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Registers any structures we know about as weak references, and sets watchpoints on any
+// such structures that we know of that are currently watchable. It's somewhat
+// counterintuitive, but this ends up being the cleanest and most effective way of reducing
+// structure checks on terminal structures:
+//
+// - We used to only set watchpoints on watchable structures if we knew that this would
+//   remove a structure check. Experiments show that switching from that, to blindly
+//   setting watchpoints on all watchable structures, was not a regression.
+//
+// - It makes abstract interpretation a whole lot easier. We just assume that watchable
+//   structures are unclobberable without having to do any other logic.
+
+bool performStructureRegistration(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStructureRegistrationPhase_h
+
index 09c22b8c04ff96b1c1e530dd68dc9cbfeb027ec9..5f509c41e0cf11ba6e44dccf3a41c3ab2781837a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,6 +60,13 @@ public:
         
         if (!Options::enableOSREntryToFTL())
             level = FTL::CanCompile;
+
+        // First we find all the loops that contain a LoopHint for which we cannot OSR enter.
+        // We use that information to decide if we need CheckTierUpAndOSREnter or CheckTierUpWithNestedTriggerAndOSREnter.
+        NaturalLoops& naturalLoops = m_graph.m_naturalLoops;
+        naturalLoops.computeIfNecessary(m_graph);
+
+        HashSet<const NaturalLoop*> loopsContainingLoopHintWithoutOSREnter = findLoopsContainingLoopHintWithoutOSREnter(naturalLoops, level);
         
         InsertionSet insertionSet(m_graph);
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
@@ -71,41 +78,23 @@ public:
                 Node* node = block->at(nodeIndex);
                 if (node->op() != LoopHint)
                     continue;
-                
-                // We only put OSR checks for the first LoopHint in the block. Note that
-                // more than one LoopHint could happen in cases where we did a lot of CFG
-                // simplification in the bytecode parser, but it should be very rare.
-                
+
                 NodeOrigin origin = node->origin;
-                
-                if (level != FTL::CanCompileAndOSREnter || origin.semantic.inlineCallFrame) {
-                    insertionSet.insertNode(
-                        nodeIndex + 1, SpecNone, CheckTierUpInLoop, origin);
-                    break;
-                }
-                
-                bool isAtTop = true;
-                for (unsigned subNodeIndex = nodeIndex; subNodeIndex--;) {
-                    if (!block->at(subNodeIndex)->isSemanticallySkippable()) {
-                        isAtTop = false;
-                        break;
-                    }
-                }
-                
-                if (!isAtTop) {
-                    insertionSet.insertNode(
-                        nodeIndex + 1, SpecNone, CheckTierUpInLoop, origin);
-                    break;
-                }
-                
-                insertionSet.insertNode(
-                    nodeIndex + 1, SpecNone, CheckTierUpAndOSREnter, origin);
+                if (canOSREnterAtLoopHint(level, block, nodeIndex)) {
+                    const NaturalLoop* loop = naturalLoops.innerMostLoopOf(block);
+                    if (loop && loopsContainingLoopHintWithoutOSREnter.contains(loop))
+                        insertionSet.insertNode(nodeIndex + 1, SpecNone, CheckTierUpWithNestedTriggerAndOSREnter, origin);
+                    else
+                        insertionSet.insertNode(nodeIndex + 1, SpecNone, CheckTierUpAndOSREnter, origin);
+                } else
+                    insertionSet.insertNode(nodeIndex + 1, SpecNone, CheckTierUpInLoop, origin);
                 break;
             }
             
-            if (block->last()->op() == Return) {
+            NodeAndIndex terminal = block->findTerminal();
+            if (terminal.node->op() == Return) {
                 insertionSet.insertNode(
-                    block->size() - 1, SpecNone, CheckTierUpAtReturn, block->last()->origin);
+                    terminal.index, SpecNone, CheckTierUpAtReturn, terminal.node->origin);
             }
             
             insertionSet.execute(block);
@@ -118,6 +107,49 @@ public:
         return false;
 #endif // ENABLE(FTL_JIT)
     }
+
+private:
+#if ENABLE(FTL_JIT)
+    bool canOSREnterAtLoopHint(FTL::CapabilityLevel level, const BasicBlock* block, unsigned nodeIndex)
+    {
+        Node* node = block->at(nodeIndex);
+        ASSERT(node->op() == LoopHint);
+
+        NodeOrigin origin = node->origin;
+        if (level != FTL::CanCompileAndOSREnter || origin.semantic.inlineCallFrame)
+            return false;
+
+        // We only put OSR checks for the first LoopHint in the block. Note that
+        // more than one LoopHint could happen in cases where we did a lot of CFG
+        // simplification in the bytecode parser, but it should be very rare.
+        for (unsigned subNodeIndex = nodeIndex; subNodeIndex--;) {
+            if (!block->at(subNodeIndex)->isSemanticallySkippable())
+                return false;
+        }
+        return true;
+    }
+
+    HashSet<const NaturalLoop*> findLoopsContainingLoopHintWithoutOSREnter(const NaturalLoops& naturalLoops, FTL::CapabilityLevel level)
+    {
+        HashSet<const NaturalLoop*> loopsContainingLoopHintWithoutOSREnter;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                if (node->op() != LoopHint)
+                    continue;
+
+                if (!canOSREnterAtLoopHint(level, block, nodeIndex)) {
+                    const NaturalLoop* loop = naturalLoops.innerMostLoopOf(block);
+                    while (loop) {
+                        loopsContainingLoopHintWithoutOSREnter.add(loop);
+                        loop = naturalLoops.innerMostOuterLoop(*loop);
+                    }
+                }
+            }
+        }
+        return loopsContainingLoopHintWithoutOSREnter;
+    }
+#endif
 };
 
 bool performTierUpCheckInjection(Graph& graph)
index d0162b79e5f461a588a9b2cfd4f0d026f1f65b0f..dd8108a76099f8a67fd3fb7dde3311f759599732 100644 (file)
@@ -43,10 +43,9 @@ ToFTLDeferredCompilationCallback::ToFTLDeferredCompilationCallback(
 
 ToFTLDeferredCompilationCallback::~ToFTLDeferredCompilationCallback() { }
 
-PassRefPtr<ToFTLDeferredCompilationCallback> ToFTLDeferredCompilationCallback::create(
-    PassRefPtr<CodeBlock> dfgCodeBlock)
+Ref<ToFTLDeferredCompilationCallback> ToFTLDeferredCompilationCallback::create(PassRefPtr<CodeBlock> dfgCodeBlock)
 {
-    return adoptRef(new ToFTLDeferredCompilationCallback(dfgCodeBlock));
+    return adoptRef(*new ToFTLDeferredCompilationCallback(dfgCodeBlock));
 }
 
 void ToFTLDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
index f1ac4a68fc649730a65b6dac08ed69581bd3992f..3e0ea02d0fa22364b8c690fb17151579f114f17d 100644 (file)
@@ -45,8 +45,7 @@ protected:
 public:
     virtual ~ToFTLDeferredCompilationCallback();
 
-    static PassRefPtr<ToFTLDeferredCompilationCallback> create(
-        PassRefPtr<CodeBlock> dfgCodeBlock);
+    static Ref<ToFTLDeferredCompilationCallback> create(PassRefPtr<CodeBlock> dfgCodeBlock);
     
     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
index 47c4fbbec51eef96285252b44800b069c3ec4dca..70cc82502262e173c303f6487185d03fdd1f5f2a 100644 (file)
@@ -45,11 +45,10 @@ ToFTLForOSREntryDeferredCompilationCallback::~ToFTLForOSREntryDeferredCompilatio
 {
 }
 
-PassRefPtr<ToFTLForOSREntryDeferredCompilationCallback>
-ToFTLForOSREntryDeferredCompilationCallback::create(
+Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create(
     PassRefPtr<CodeBlock> dfgCodeBlock)
 {
-    return adoptRef(new ToFTLForOSREntryDeferredCompilationCallback(dfgCodeBlock));
+    return adoptRef(*new ToFTLForOSREntryDeferredCompilationCallback(dfgCodeBlock));
 }
 
 void ToFTLForOSREntryDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
index c53df91f769d7f8026a5b4abcf677ec196cf84e4..c9dcf6d7c01fc1e4856009b8fd7321c089e3e4c4 100644 (file)
@@ -45,8 +45,7 @@ protected:
 public:
     virtual ~ToFTLForOSREntryDeferredCompilationCallback();
 
-    static PassRefPtr<ToFTLForOSREntryDeferredCompilationCallback> create(
-        PassRefPtr<CodeBlock> dfgCodeBlock);
+    static Ref<ToFTLForOSREntryDeferredCompilationCallback> create(PassRefPtr<CodeBlock> dfgCodeBlock);
     
     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
diff --git a/dfg/DFGTransition.cpp b/dfg/DFGTransition.cpp
new file mode 100644 (file)
index 0000000..80d9b99
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGTransition.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+void Transition::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    out.print(pointerDumpInContext(previous, context), " -> ", pointerDumpInContext(next, context));
+}
+
+void Transition::dump(PrintStream& out) const
+{
+    dumpInContext(out, 0);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGTransition.h b/dfg/DFGTransition.h
new file mode 100644 (file)
index 0000000..49a6544
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGTransition_h
+#define DFGTransition_h
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class Structure;
+struct DumpContext;
+
+namespace DFG {
+
+struct Transition {
+    Structure* previous;
+    Structure* next;
+    
+    Transition()
+        : previous(nullptr)
+        , next(nullptr)
+    {
+    }
+    
+    Transition(Structure* previous, Structure* next)
+        : previous(previous)
+        , next(next)
+    {
+    }
+    
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
+};
+
+typedef Vector<Transition, 3> TransitionVector;
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGTransition_h
+
index ad509cfeb48d07479b44ba1aa96d19fa3c2479fd..3416edfe3ae02c937dc7523d6af1ccb1db6f128f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -115,7 +115,6 @@ public:
                 // from the node, before doing any appending.
                 switch (node->op()) {
                 case SetArgument: {
-                    ASSERT(!blockIndex);
                     // Insert a GetLocal and a CheckStructure immediately following this
                     // SetArgument, if the variable was a candidate for structure hoisting.
                     // If the basic block previously only had the SetArgument as its
@@ -127,6 +126,9 @@ public:
                     if (!iter->value.m_structure && !iter->value.m_arrayModeIsValid)
                         break;
 
+                    // Currently we should only be doing this hoisting for SetArguments at the prologue.
+                    ASSERT(!blockIndex);
+
                     NodeOrigin origin = node->origin;
                     
                     Node* getLocal = insertionSet.insertNode(
@@ -215,8 +217,7 @@ private:
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                 Node* node = block->at(indexInBlock);
                 switch (node->op()) {
-                case CheckStructure:
-                case StructureTransitionWatchpoint: {
+                case CheckStructure: {
                     Node* child = node->child1().node();
                     if (child->op() != GetLocal)
                         break;
@@ -227,7 +228,9 @@ private:
                     noticeStructureCheck(variable, node->structureSet());
                     break;
                 }
-                    
+
+                case ArrayifyToStructure:
+                case Arrayify:
                 case GetByOffset:
                 case PutByOffset:
                 case PutStructure:
@@ -243,29 +246,12 @@ private:
                 case GetIndexedPropertyStorage:
                 case GetTypedArrayByteOffset:
                 case Phantom:
-                case HardPhantom:
                 case MovHint:
                 case MultiGetByOffset:
                 case MultiPutByOffset:
                     // Don't count these uses.
                     break;
                     
-                case ArrayifyToStructure:
-                case Arrayify:
-                    if (node->arrayMode().conversion() == Array::RageConvert) {
-                        // Rage conversion changes structures. We should avoid tying to do
-                        // any kind of hoisting when rage conversion is in play.
-                        Node* child = node->child1().node();
-                        if (child->op() != GetLocal)
-                            break;
-                        VariableAccessData* variable = child->variableAccessData();
-                        variable->vote(VoteOther);
-                        if (!shouldConsiderForHoisting<StructureTypeCheck>(variable))
-                            break;
-                        noticeStructureCheck(variable, 0);
-                    }
-                    break;
-                    
                 case SetLocal: {
                     // Find all uses of the source of the SetLocal. If any of them are a
                     // kind of CheckStructure, then we should notice them to ensure that
@@ -285,13 +271,6 @@ private:
                             noticeStructureCheck(variable, subNode->structureSet());
                             break;
                         }
-                        case StructureTransitionWatchpoint: {
-                            if (subNode->child1() != source)
-                                break;
-                            
-                            noticeStructureCheck(variable, subNode->structure());
-                            break;
-                        }
                         default:
                             break;
                         }
@@ -331,7 +310,6 @@ private:
                 }
 
                 case CheckStructure:
-                case StructureTransitionWatchpoint:
                 case GetByOffset:
                 case PutByOffset:
                 case PutStructure:
@@ -344,7 +322,6 @@ private:
                 case GetArrayLength:
                 case GetIndexedPropertyStorage:
                 case Phantom:
-                case HardPhantom:
                 case MovHint:
                 case MultiGetByOffset:
                 case MultiPutByOffset:
@@ -386,13 +363,6 @@ private:
                             noticeStructureCheckAccountingForArrayMode(variable, subNode->structureSet());
                             break;
                         }
-                        case StructureTransitionWatchpoint: {
-                            if (subNode->child1() != source)
-                                break;
-                            
-                            noticeStructureCheckAccountingForArrayMode(variable, subNode->structure());
-                            break;
-                        }
                         case CheckArray: {
                             if (subNode->child1() != source)
                                 break;
@@ -503,7 +473,7 @@ private:
             noticeStructureCheck(variable, 0);
             return;
         }
-        noticeStructureCheck(variable, set.singletonStructure());
+        noticeStructureCheck(variable, set.onlyStructure());
     }
 
     void noticeCheckArray(VariableAccessData* variable, ArrayMode arrayMode)
index 4e43eeb643eb71f3ce1c7fe102655dbc63d5b15b..0722dd9cb175299ed9bc4baccfb605aa765828e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -70,7 +70,6 @@ public:
         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
             VariableAccessData* data = &m_graph.m_variableAccessData[i];
             data->find()->predict(data->nonUnifiedPrediction());
-            data->find()->mergeIsCaptured(data->isCaptured());
             data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
             data->find()->mergeCheckArrayHoistingFailed(data->checkArrayHoistingFailed());
             data->find()->mergeShouldNeverUnbox(data->shouldNeverUnbox());
index 913a7154af96577d1c2b0b2690506b9a000f6441..efa104f3d07000b7d7bc473bcdf206d1053fc9b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,80 +39,87 @@ void printInternal(PrintStream& out, UseKind useKind)
     switch (useKind) {
     case UntypedUse:
         out.print("Untyped");
-        break;
+        return;
     case Int32Use:
         out.print("Int32");
-        break;
+        return;
     case KnownInt32Use:
         out.print("KnownInt32");
-        break;
+        return;
     case Int52RepUse:
         out.print("Int52Rep");
-        break;
+        return;
     case MachineIntUse:
         out.print("MachineInt");
-        break;
+        return;
     case NumberUse:
         out.print("Number");
-        break;
+        return;
+    case RealNumberUse:
+        out.print("RealNumber");
+        return;
     case DoubleRepUse:
         out.print("DoubleRep");
-        break;
+        return;
     case DoubleRepRealUse:
         out.print("DoubleRepReal");
-        break;
+        return;
     case DoubleRepMachineIntUse:
         out.print("DoubleRepMachineInt");
-        break;
+        return;
     case BooleanUse:
         out.print("Boolean");
-        break;
+        return;
     case CellUse:
         out.print("Cell");
-        break;
+        return;
     case KnownCellUse:
         out.print("KnownCell");
-        break;
+        return;
     case ObjectUse:
         out.print("Object");
-        break;
+        return;
+    case FunctionUse:
+        out.print("Function");
+        return;
     case FinalObjectUse:
         out.print("FinalObject");
-        break;
+        return;
     case ObjectOrOtherUse:
         out.print("ObjectOrOther");
-        break;
+        return;
     case StringIdentUse:
         out.print("StringIdent");
-        break;
+        return;
     case StringUse:
         out.print("String");
-        break;
+        return;
     case KnownStringUse:
         out.print("KnownString");
-        break;
+        return;
     case StringObjectUse:
         out.print("StringObject");
-        break;
+        return;
     case StringOrStringObjectUse:
         out.print("StringOrStringObject");
-        break;
+        return;
     case NotStringVarUse:
         out.print("NotStringVar");
-        break;
+        return;
     case NotCellUse:
         out.print("NotCell");
-        break;
+        return;
     case OtherUse:
         out.print("Other");
-        break;
+        return;
     case MiscUse:
         out.print("Misc");
-        break;
-    default:
+        return;
+    case LastUseKind:
         RELEASE_ASSERT_NOT_REACHED();
-        break;
+        return;
     }
+    RELEASE_ASSERT_NOT_REACHED();
 }
 
 } // namespace WTF
index d6eeef7d19f454be9ba29ad1f16df60c254e966a..ebf99dae600c8825d22cbac63822d15b5560035a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 namespace JSC { namespace DFG {
 
 enum UseKind {
-    UntypedUse,
+    // The DFG has 3 representations of values used:
+
+    // 1. The JSValue representation for a JSValue that must be stored in a GP
+    //    register (or a GP register pair), and follows rules for boxing and unboxing
+    //    that allow the JSValue to be stored as either fully boxed JSValues, or
+    //    unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate.
+    UntypedUse, // UntypedUse must come first (value 0).
     Int32Use,
     KnownInt32Use,
-    Int52RepUse,
     MachineIntUse,
     NumberUse,
-    DoubleRepUse,
-    DoubleRepRealUse,
-    DoubleRepMachineIntUse,
+    RealNumberUse,
     BooleanUse,
     CellUse,
     KnownCellUse,
     ObjectUse,
+    FunctionUse,
     FinalObjectUse,
     ObjectOrOtherUse,
     StringIdentUse,
@@ -59,6 +63,17 @@ enum UseKind {
     NotCellUse,
     OtherUse,
     MiscUse,
+
+    // 2. The Double representation for an unboxed double value that must be stored
+    //    in an FP register.
+    DoubleRepUse,
+    DoubleRepRealUse,
+    DoubleRepMachineIntUse,
+
+    // 3. The Int52 representation for an unboxed integer value that must be stored
+    //    in a GP register.
+    Int52RepUse,
+
     LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
 };
 
@@ -76,6 +91,8 @@ inline SpeculatedType typeFilterFor(UseKind useKind)
         return SpecInt32 | SpecInt52AsDouble;
     case NumberUse:
         return SpecBytecodeNumber;
+    case RealNumberUse:
+        return SpecBytecodeRealNumber;
     case DoubleRepUse:
         return SpecFullDouble;
     case DoubleRepRealUse:
@@ -89,6 +106,8 @@ inline SpeculatedType typeFilterFor(UseKind useKind)
         return SpecCell;
     case ObjectUse:
         return SpecObject;
+    case FunctionUse:
+        return SpecFunction;
     case FinalObjectUse:
         return SpecFinalObject;
     case ObjectOrOtherUse:
@@ -142,6 +161,7 @@ inline bool isNumerical(UseKind kind)
     case Int32Use:
     case KnownInt32Use:
     case NumberUse:
+    case RealNumberUse:
     case Int52RepUse:
     case DoubleRepUse:
     case DoubleRepRealUse:
@@ -171,6 +191,7 @@ inline bool isCell(UseKind kind)
     case CellUse:
     case KnownCellUse:
     case ObjectUse:
+    case FunctionUse:
     case FinalObjectUse:
     case StringIdentUse:
     case StringUse:
@@ -196,6 +217,17 @@ inline bool usesStructure(UseKind kind)
     }
 }
 
+// Returns true if we've already guaranteed the type 
+inline bool alreadyChecked(UseKind kind, SpeculatedType type)
+{
+    // If the check involves the structure then we need to know more than just the type to be sure
+    // that the check is done.
+    if (usesStructure(kind))
+        return false;
+    
+    return !(type & ~typeFilterFor(kind));
+}
+
 inline UseKind useKindForResult(NodeFlags result)
 {
     ASSERT(!(result & ~NodeResultMask));
index ecd4d870858cc0065bd5d7588cf36927387fb55b..6748f5fb99dc846f41a755d6b21b66edb717c743 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlockWithJITType.h"
+#include "DFGMayExit.h"
 #include "JSCInlines.h"
 #include <wtf/Assertions.h>
 #include <wtf/BitVector.h>
@@ -37,9 +38,10 @@ namespace JSC { namespace DFG {
 
 class Validate {
 public:
-    Validate(Graph& graph, GraphDumpMode graphDumpMode)
+    Validate(Graph& graph, GraphDumpMode graphDumpMode, CString graphDumpBeforePhase)
         : m_graph(graph)
         , m_graphDumpMode(graphDumpMode)
+        , m_graphDumpBeforePhase(graphDumpBeforePhase)
     {
     }
     
@@ -48,7 +50,7 @@ public:
             startCrashing(); \
             dataLogF("\n\n\nAt "); \
             reportValidationContext context; \
-            dataLogF(": validation %s (%s:%d) failed.\n", #assertion, __FILE__, __LINE__); \
+            dataLogF(": validation failed: %s (%s:%d).\n", #assertion, __FILE__, __LINE__); \
             dumpGraphIfAppropriate(); \
             WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
             CRASH(); \
@@ -60,11 +62,11 @@ public:
             startCrashing(); \
             dataLogF("\n\n\nAt "); \
             reportValidationContext context; \
-            dataLogF(": validation (%s = ", #left); \
+            dataLogF(": validation failed: (%s = ", #left); \
             dataLog(left); \
             dataLogF(") == (%s = ", #right); \
             dataLog(right); \
-            dataLogF(") (%s:%d) failed.\n", __FILE__, __LINE__); \
+            dataLogF(") (%s:%d).\n", __FILE__, __LINE__); \
             dumpGraphIfAppropriate(); \
             WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #left " == " #right); \
             CRASH(); \
@@ -72,7 +74,7 @@ public:
     } while (0)
 
     #define notSet (static_cast<size_t>(-1))
-
+        
     void validate()
     {
         // NB. This code is not written for performance, since it is not intended to run
@@ -116,8 +118,8 @@ public:
                         continue;
                     
                     m_myRefCounts.find(edge.node())->value++;
-                    
-                    VALIDATE((node, edge), edge->hasDoubleResult() == (edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepMachineIntUse));
+
+                    validateEdgeWithDoubleResultIfNecessary(node, edge);
                     VALIDATE((node, edge), edge->hasInt52Result() == (edge.useKind() == Int52RepUse));
                     
                     if (m_graph.m_form == SSA) {
@@ -144,31 +146,6 @@ public:
                             break;
                         VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
                         break;
-                    case Phantom:
-                        switch (m_graph.m_form) {
-                        case LoadStore:
-                            if (j) {
-                                VALIDATE((node, edge), edge->hasResult());
-                                break;
-                            }
-                            switch (edge->op()) {
-                            case Phi:
-                            case SetArgument:
-                            case SetLocal:
-                                break;
-                            default:
-                                VALIDATE((node, edge), edge->hasResult());
-                                break;
-                            }
-                            break;
-                        case ThreadedCPS:
-                            VALIDATE((node, edge), edge->hasResult());
-                            break;
-                        case SSA:
-                            RELEASE_ASSERT_NOT_REACHED();
-                            break;
-                        }
-                        break;
                     default:
                         VALIDATE((node, edge), edge->hasResult());
                         break;
@@ -185,25 +162,100 @@ public:
                 Node* node = block->node(i);
                 if (m_graph.m_refCountState == ExactRefCount)
                     V_EQUAL((node), m_myRefCounts.get(node), node->adjustedRefCount());
-                else
-                    V_EQUAL((node), node->refCount(), 1);
             }
             
-            for (size_t i = 0 ; i < block->size() - 1; ++i) {
+            bool foundTerminal = false;
+            for (size_t i = 0 ; i < block->size(); ++i) {
                 Node* node = block->at(i);
-                VALIDATE((node), !node->isTerminal());
+                if (node->isTerminal()) {
+                    foundTerminal = true;
+                    for (size_t j = i + 1; j < block->size(); ++j) {
+                        node = block->at(j);
+                        VALIDATE((node), node->op() == Phantom || node->op() == PhantomLocal || node->op() == Flush || node->op() == Check);
+                        m_graph.doToChildren(
+                            node,
+                            [&] (Edge edge) {
+                                VALIDATE((node, edge), shouldNotHaveTypeCheck(edge.useKind()));
+                            });
+                    }
+                    break;
+                }
             }
+            VALIDATE((block), foundTerminal);
             
             for (size_t i = 0; i < block->size(); ++i) {
                 Node* node = block->at(i);
                 
-                if (node->hasStructure())
-                    VALIDATE((node), !!node->structure());
-                
+                VALIDATE((node), node->origin.semantic.isSet() == node->origin.forExit.isSet());
+                VALIDATE((node), !mayExit(m_graph, node) || node->origin.forExit.isSet());
+                VALIDATE((node), !node->hasStructure() || !!node->structure());
+                VALIDATE((node), !node->hasCellOperand() || node->cellOperand()->value().isCell());
+                VALIDATE((node), !node->hasCellOperand() || !!node->cellOperand()->value());
+                 
+                if (!(node->flags() & NodeHasVarArgs)) {
+                    if (!node->child2())
+                        VALIDATE((node), !node->child3());
+                    if (!node->child1())
+                        VALIDATE((node), !node->child2());
+                }
+                 
                 switch (node->op()) {
                 case Identity:
                     VALIDATE((node), canonicalResultRepresentation(node->result()) == canonicalResultRepresentation(node->child1()->result()));
                     break;
+                case SetLocal:
+                case PutStack:
+                case Upsilon:
+                    VALIDATE((node), !!node->child1());
+                    switch (node->child1().useKind()) {
+                    case UntypedUse:
+                    case CellUse:
+                    case Int32Use:
+                    case Int52RepUse:
+                    case DoubleRepUse:
+                    case BooleanUse:
+                        break;
+                    default:
+                        VALIDATE((node), !"Bad use kind");
+                        break;
+                    }
+                    break;
+                case MakeRope:
+                case ValueAdd:
+                case ArithAdd:
+                case ArithSub:
+                case ArithMul:
+                case ArithIMul:
+                case ArithDiv:
+                case ArithMod:
+                case ArithMin:
+                case ArithMax:
+                case ArithPow:
+                case CompareLess:
+                case CompareLessEq:
+                case CompareGreater:
+                case CompareGreaterEq:
+                case CompareEq:
+                case CompareEqConstant:
+                case CompareStrictEq:
+                    VALIDATE((node), !!node->child1());
+                    VALIDATE((node), !!node->child2());
+                    break;
+                case PutStructure:
+                    VALIDATE((node), !node->transition()->previous->dfgShouldWatch());
+                    break;
+                case MultiPutByOffset:
+                    for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
+                        const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
+                        if (variant.kind() != PutByIdVariant::Transition)
+                            continue;
+                        VALIDATE((node), !variant.oldStructureForTransition()->dfgShouldWatch());
+                    }
+                    break;
+                case DoubleConstant:
+                case Int52Constant:
+                    VALIDATE((node), node->isNumberConstant());
+                    break;
                 default:
                     break;
                 }
@@ -225,6 +277,7 @@ public:
 private:
     Graph& m_graph;
     GraphDumpMode m_graphDumpMode;
+    CString m_graphDumpBeforePhase;
     
     HashMap<Node*, unsigned> m_myRefCounts;
     HashSet<Node*> m_acceptableNodes;
@@ -354,6 +407,7 @@ private:
                 Node* node = block->at(i);
                 ASSERT(nodesInThisBlock.contains(node));
                 VALIDATE((node), node->op() != Phi);
+                VALIDATE((node), node->origin.forExit.isSet());
                 for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
                     Edge edge = m_graph.child(node, j);
                     if (!edge)
@@ -364,39 +418,63 @@ private:
                     case GetLocal:
                     case Flush:
                         break;
-                    case Phantom:
-                        if (m_graph.m_form == LoadStore && !j)
-                            break;
-                        FALLTHROUGH;
                     default:
                         VALIDATE((node, edge), !phisInThisBlock.contains(edge.node()));
                         break;
                     }
                 }
                 
+                switch (node->op()) {
+                case Phi:
+                case Upsilon:
+                case CheckInBounds:
+                case PhantomNewObject:
+                case PhantomNewFunction:
+                case PhantomCreateActivation:
+                case GetMyArgumentByVal:
+                case PutHint:
+                case CheckStructureImmediate:
+                case MaterializeNewObject:
+                case MaterializeCreateActivation:
+                case PutStack:
+                case KillStack:
+                case GetStack:
+                    VALIDATE((node), !"unexpected node type in CPS");
+                    break;
+                case Phantom:
+                    VALIDATE((node), m_graph.m_fixpointState != FixpointNotConverged);
+                    break;
+                default:
+                    break;
+                }
+                
                 if (!node->shouldGenerate())
                     continue;
                 switch (node->op()) {
                 case GetLocal:
-                    if (node->variableAccessData()->isCaptured())
-                        break;
                     // Ignore GetLocal's that we know to be dead, but that the graph
                     // doesn't yet know to be dead.
                     if (!m_myRefCounts.get(node))
                         break;
-                    if (m_graph.m_form == ThreadedCPS)
+                    if (m_graph.m_form == ThreadedCPS) {
                         VALIDATE((node, block), getLocalPositions.operand(node->local()) == notSet);
+                        VALIDATE((node, block), !!node->child1());
+                    }
                     getLocalPositions.operand(node->local()) = i;
                     break;
                 case SetLocal:
-                    if (node->variableAccessData()->isCaptured())
-                        break;
                     // Only record the first SetLocal. There may be multiple SetLocals
                     // because of flushing.
                     if (setLocalPositions.operand(node->local()) != notSet)
                         break;
                     setLocalPositions.operand(node->local()) = i;
                     break;
+                case SetArgument:
+                    // This acts like a reset. It's ok to have a second GetLocal for a local in the same
+                    // block if we had a SetArgument for that local.
+                    getLocalPositions.operand(node->local()) = notSet;
+                    setLocalPositions.operand(node->local()) = notSet;
+                    break;
                 default:
                     break;
                 }
@@ -426,19 +504,29 @@ private:
             if (!block)
                 continue;
             
+            VALIDATE((block), block->phis.isEmpty());
+            
             unsigned nodeIndex = 0;
-            for (; nodeIndex < block->size() && !block->at(nodeIndex)->origin.isSet(); nodeIndex++) { }
+            for (; nodeIndex < block->size() && !block->at(nodeIndex)->origin.forExit.isSet(); nodeIndex++) { }
             
             VALIDATE((block), nodeIndex < block->size());
             
             for (; nodeIndex < block->size(); nodeIndex++)
-                VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->origin.isSet());
+                VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->origin.forExit.isSet());
             
             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
                 switch (node->op()) {
                 case Phi:
-                    VALIDATE((node), !node->origin.isSet());
+                    VALIDATE((node), !node->origin.forExit.isSet());
+                    break;
+                    
+                case GetLocal:
+                case SetLocal:
+                case GetLocalUnlinked:
+                case SetArgument:
+                case Phantom:
+                    VALIDATE((node), !"bad node type for SSA");
                     break;
                     
                 default:
@@ -449,7 +537,18 @@ private:
             }
         }
     }
-    
+
+    void validateEdgeWithDoubleResultIfNecessary(Node* node, Edge edge)
+    {
+        if (!edge->hasDoubleResult())
+            return;
+
+        if (m_graph.m_planStage < PlanStage::AfterFixup)
+            return;
+        
+        VALIDATE((node, edge), edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepMachineIntUse);
+    }
+
     void checkOperand(
         BasicBlock* block, Operands<size_t>& getLocalPositions,
         Operands<size_t>& setLocalPositions, VirtualRegister operand)
@@ -484,23 +583,23 @@ private:
     void reportValidationContext(VirtualRegister local, BasicBlock* block)
     {
         if (!block) {
-            dataLog("r", local, " in null Block ");
+            dataLog(local, " in null Block ");
             return;
         }
 
-        dataLog("r", local, " in Block ", *block);
+        dataLog(local, " in Block ", *block);
     }
     
     void reportValidationContext(
         VirtualRegister local, BasicBlock* sourceBlock, BasicBlock* destinationBlock)
     {
-        dataLog("r", local, " in Block ", *sourceBlock, " -> ", *destinationBlock);
+        dataLog(local, " in Block ", *sourceBlock, " -> ", *destinationBlock);
     }
     
     void reportValidationContext(
         VirtualRegister local, BasicBlock* sourceBlock, Node* prevNode)
     {
-        dataLog(prevNode, " for r", local, " in Block ", *sourceBlock);
+        dataLog(prevNode, " for ", local, " in Block ", *sourceBlock);
     }
     
     void reportValidationContext(Node* node, BasicBlock* block)
@@ -523,14 +622,19 @@ private:
     {
         if (m_graphDumpMode == DontDumpGraph)
             return;
+        dataLog("\n");
+        if (!m_graphDumpBeforePhase.isNull()) {
+            dataLog("Before phase:\n");
+            dataLog(m_graphDumpBeforePhase);
+        }
         dataLog("At time of failure:\n");
         m_graph.dump();
     }
 };
 
-void validate(Graph& graph, GraphDumpMode graphDumpMode)
+void validate(Graph& graph, GraphDumpMode graphDumpMode, CString graphDumpBeforePhase)
 {
-    Validate validationObject(graph, graphDumpMode);
+    Validate validationObject(graph, graphDumpMode, graphDumpBeforePhase);
     validationObject.validate();
 }
 
index dd7b22248373bb9c94cc3e26f08f7ca6e19a2665..ff4d06bdd678362d59bd9d36930993cc95e17039 100644 (file)
@@ -35,7 +35,7 @@ namespace JSC { namespace DFG {
 
 enum GraphDumpMode { DontDumpGraph, DumpGraph };
 
-void validate(Graph&, GraphDumpMode = DumpGraph);
+void validate(Graph&, GraphDumpMode = DumpGraph, CString graphDumpBeforePhase = CString());
 
 } } // namespace JSC::DFG
 
diff --git a/dfg/DFGValueRecoveryOverride.h b/dfg/DFGValueRecoveryOverride.h
deleted file mode 100644 (file)
index 009f98a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef DFGValueRecoveryOverride_h
-#define DFGValueRecoveryOverride_h
-
-#if ENABLE(DFG_JIT)
-
-#include "ValueRecovery.h"
-#include <wtf/RefCounted.h>
-
-namespace JSC { namespace DFG {
-
-class ValueRecoveryOverride : public RefCounted<ValueRecoveryOverride> {
-public:
-    ValueRecoveryOverride() { }
-    
-    ValueRecoveryOverride(VirtualRegister operand, const ValueRecovery& recovery)
-        : operand(operand)
-        , recovery(recovery)
-    {
-    }
-    
-    VirtualRegister operand;
-    ValueRecovery recovery;
-};
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGValueRecoveryOverride_h
-
index 207a4d7f7b2deaad4aa52bb068ab05413e3e1781..41d8b475a5f944aab5ffdcac605ba259bcbd9608 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,25 +42,22 @@ void ValueSource::dump(PrintStream& out) const
         out.print("IsDead");
         break;
     case ValueInJSStack:
-        out.print("JS:r", virtualRegister());
+        out.print("JS:", virtualRegister());
         break;
     case Int32InJSStack:
-        out.print("Int32:r", virtualRegister());
+        out.print("Int32:", virtualRegister());
         break;
     case Int52InJSStack:
-        out.print("Int52:r", virtualRegister());
+        out.print("Int52:", virtualRegister());
         break;
     case CellInJSStack:
-        out.print("Cell:r", virtualRegister());
+        out.print("Cell:", virtualRegister());
         break;
     case BooleanInJSStack:
-        out.print("Bool:r", virtualRegister());
+        out.print("Bool:", virtualRegister());
         break;
     case DoubleInJSStack:
-        out.print("Double:r", virtualRegister());
-        break;
-    case ArgumentsSource:
-        out.print("Arguments");
+        out.print("Double:", virtualRegister());
         break;
     case HaveNode:
         out.print("Node(", m_value, ")");
index 33bb457bd4fcd3aa56b17da795e19ca8a0b4dce7..1b55797d5659152dc9454e64ad7f368440d683a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,6 @@ enum ValueSourceKind {
     CellInJSStack,
     BooleanInJSStack,
     DoubleInJSStack,
-    ArgumentsSource,
     SourceIsDead,
     HaveNode
 };
@@ -65,8 +64,6 @@ static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat)
         return CellInJSStack;
     case DataFormatDead:
         return SourceIsDead;
-    case DataFormatArguments:
-        return ArgumentsSource;
     default:
         RELEASE_ASSERT(dataFormat & DataFormatJS);
         return ValueInJSStack;
@@ -88,8 +85,6 @@ static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind)
         return DataFormatBoolean;
     case DoubleInJSStack:
         return DataFormatDouble;
-    case ArgumentsSource:
-        return DataFormatArguments;
     case SourceIsDead:
         return DataFormatDead;
     default:
@@ -120,7 +115,7 @@ public:
     explicit ValueSource(ValueSourceKind valueSourceKind)
         : m_kind(valueSourceKind)
     {
-        ASSERT(kind() == ArgumentsSource || kind() == SourceIsDead || kind() == ArgumentsSource);
+        ASSERT(kind() == SourceIsDead);
     }
     
     explicit ValueSource(MinifiedID id)
@@ -157,8 +152,6 @@ public:
             return ValueSource(CellInJSStack, where);
         case FlushedBoolean:
             return ValueSource(BooleanInJSStack, where);
-        case FlushedArguments:
-            return ValueSource(ArgumentsSource);
         }
         RELEASE_ASSERT_NOT_REACHED();
         return ValueSource();
@@ -196,9 +189,6 @@ public:
         case SourceIsDead:
             return ValueRecovery::constant(jsUndefined());
             
-        case ArgumentsSource:
-            return ValueRecovery::argumentsThatWereNotCreated();
-            
         default:
             return ValueRecovery::displacedInJSStack(virtualRegister(), dataFormat());
         }
diff --git a/dfg/DFGValueStrength.cpp b/dfg/DFGValueStrength.cpp
new file mode 100644 (file)
index 0000000..2c6e612
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGValueStrength.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, ValueStrength strength)
+{
+    switch (strength) {
+    case WeakValue:
+        out.print("Weak");
+        return;
+    case StrongValue:
+        out.print("Strong");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGValueStrength.h b/dfg/DFGValueStrength.h
new file mode 100644 (file)
index 0000000..72cd71c
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGValueStrength_h
+#define DFGValueStrength_h
+
+#if ENABLE(DFG_JIT)
+
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+enum ValueStrength {
+    // The value has been used for optimization and it arose through inference. We don't want the
+    // fact that we optimized the code to result in the GC keeping this value alive unnecessarily,
+    // so we'd rather kill the code and recompile than keep the object alive longer.
+    WeakValue,
+    
+    // The code will keep this value alive. This is true of constants that were present in the
+    // source. String constants tend to be strong.
+    StrongValue
+};
+
+inline ValueStrength merge(ValueStrength a, ValueStrength b)
+{
+    switch (a) {
+    case WeakValue:
+        return b;
+    case StrongValue:
+        return StrongValue;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+
+    return WeakValue;
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::ValueStrength);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGValueStrength_h
+
diff --git a/dfg/DFGVarargsForwardingPhase.cpp b/dfg/DFGVarargsForwardingPhase.cpp
new file mode 100644 (file)
index 0000000..9371de5
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGVarargsForwardingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGArgumentsUtilities.h"
+#include "DFGClobberize.h"
+#include "DFGForAllKills.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+#include <wtf/ListDump.h>
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class VarargsForwardingPhase : public Phase {
+public:
+    VarargsForwardingPhase(Graph& graph)
+        : Phase(graph, "varargs forwarding")
+    {
+    }
+    
+    bool run()
+    {
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form != SSA);
+        
+        if (verbose) {
+            dataLog("Graph before varargs forwarding:\n");
+            m_graph.dump();
+        }
+        
+        m_changed = false;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+            handleBlock(block);
+        return m_changed;
+    }
+
+private:
+    void handleBlock(BasicBlock* block)
+    {
+        for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            switch (node->op()) {
+            case CreateDirectArguments:
+            case CreateClonedArguments:
+                handleCandidate(block, nodeIndex);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+    
+    void handleCandidate(BasicBlock* block, unsigned candidateNodeIndex)
+    {
+        // We expect calls into this function to be rare. So, this is written in a simple O(n) manner.
+        
+        Node* candidate = block->at(candidateNodeIndex);
+        if (verbose)
+            dataLog("Handling candidate ", candidate, "\n");
+        
+        // Find the index of the last node in this block to use the candidate, and look for escaping
+        // sites.
+        unsigned lastUserIndex = candidateNodeIndex;
+        Vector<VirtualRegister, 2> relevantLocals; // This is a set. We expect it to be a small set.
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex < block->size(); ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            
+            switch (node->op()) {
+            case MovHint:
+                if (node->child1() != candidate)
+                    break;
+                lastUserIndex = nodeIndex;
+                if (!relevantLocals.contains(node->unlinkedLocal()))
+                    relevantLocals.append(node->unlinkedLocal());
+                break;
+                
+            case Check: {
+                bool sawEscape = false;
+                m_graph.doToChildren(
+                    node,
+                    [&] (Edge edge) {
+                        if (edge == candidate)
+                            lastUserIndex = nodeIndex;
+                        
+                        if (edge.willNotHaveCheck())
+                            return;
+                        
+                        if (alreadyChecked(edge.useKind(), SpecObject))
+                            return;
+                        
+                        sawEscape = true;
+                    });
+                if (sawEscape) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+                break;
+            }
+                
+            case LoadVarargs:
+                if (m_graph.uses(node, candidate))
+                    lastUserIndex = nodeIndex;
+                break;
+                
+            case CallVarargs:
+            case ConstructVarargs:
+                if (node->child1() == candidate || node->child3() == candidate) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+                if (node->child2() == candidate)
+                    lastUserIndex = nodeIndex;
+                break;
+                
+            case SetLocal:
+                if (node->child1() == candidate && node->variableAccessData()->isLoadedFrom()) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            default:
+                if (m_graph.uses(node, candidate)) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+            }
+            
+            forAllKilledOperands(
+                m_graph, node, block->tryAt(nodeIndex + 1),
+                [&] (VirtualRegister reg) {
+                    if (verbose)
+                        dataLog("    Killing ", reg, " while we are interested in ", listDump(relevantLocals), "\n");
+                    for (unsigned i = 0; i < relevantLocals.size(); ++i) {
+                        if (relevantLocals[i] == reg) {
+                            relevantLocals[i--] = relevantLocals.last();
+                            relevantLocals.removeLast();
+                            lastUserIndex = nodeIndex;
+                        }
+                    }
+                });
+        }
+        if (verbose)
+            dataLog("Selected lastUserIndex = ", lastUserIndex, ", ", block->at(lastUserIndex), "\n");
+        
+        // We're still in business. Determine if between the candidate and the last user there is any
+        // effect that could interfere with sinking.
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex <= lastUserIndex; ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            
+            // We have our own custom switch to detect some interferences that clobberize() wouldn't know
+            // about, and also some of the common ones, too. In particular, clobberize() doesn't know
+            // that Flush, MovHint, ZombieHint, and KillStack are bad because it's not worried about
+            // what gets read on OSR exit.
+            switch (node->op()) {
+            case MovHint:
+            case ZombieHint:
+            case KillStack:
+                if (argumentsInvolveStackSlot(candidate, node->unlinkedLocal())) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            case PutStack:
+                if (argumentsInvolveStackSlot(candidate, node->stackAccessData()->local)) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            case SetLocal:
+            case Flush:
+                if (argumentsInvolveStackSlot(candidate, node->local())) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            default: {
+                bool doesInterfere = false;
+                clobberize(
+                    m_graph, node, NoOpClobberize(),
+                    [&] (AbstractHeap heap) {
+                        if (heap.kind() != Stack) {
+                            ASSERT(!heap.overlaps(Stack));
+                            return;
+                        }
+                        ASSERT(!heap.payload().isTop());
+                        VirtualRegister reg(heap.payload().value32());
+                        if (argumentsInvolveStackSlot(candidate, reg))
+                            doesInterfere = true;
+                    },
+                    NoOpClobberize());
+                if (doesInterfere) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+            } }
+        }
+        
+        // We can make this work.
+        if (verbose)
+            dataLog("    Will do forwarding!\n");
+        m_changed = true;
+        
+        // Transform the program.
+        switch (candidate->op()) {
+        case CreateDirectArguments:
+            candidate->setOpAndDefaultFlags(PhantomDirectArguments);
+            break;
+
+        case CreateClonedArguments:
+            candidate->setOpAndDefaultFlags(PhantomClonedArguments);
+            break;
+            
+        default:
+            DFG_CRASH(m_graph, candidate, "bad node type");
+            break;
+        }
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex <= lastUserIndex; ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            switch (node->op()) {
+            case Check:
+            case MovHint:
+            case PutHint:
+                // We don't need to change anything with these.
+                break;
+                
+            case LoadVarargs:
+                if (node->child1() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(ForwardVarargs);
+                break;
+                
+            case CallVarargs:
+                if (node->child2() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(CallForwardVarargs);
+                break;
+                
+            case ConstructVarargs:
+                if (node->child2() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(ConstructForwardVarargs);
+                break;
+                
+            case SetLocal:
+                // This is super odd. We don't have to do anything here, since in DFG IR, the phantom
+                // arguments nodes do produce a JSValue. Also, we know that if this SetLocal referenecs a
+                // candidate then the SetLocal - along with all of its references - will die off pretty
+                // soon, since it has no real users. DCE will surely kill it. If we make it to SSA, then
+                // SSA conversion will kill it.
+                break;
+                
+            default:
+                if (ASSERT_DISABLED)
+                    break;
+                m_graph.doToChildren(
+                    node,
+                    [&] (Edge edge) {
+                        DFG_ASSERT(m_graph, node, edge != candidate);
+                    });
+                break;
+            }
+        }
+    }
+    
+    bool m_changed;
+};
+
+} // anonymous namespace
+
+bool performVarargsForwarding(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Varargs Forwarding Phase");
+    return runPhase<VarargsForwardingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/dfg/DFGVarargsForwardingPhase.h b/dfg/DFGVarargsForwardingPhase.h
new file mode 100644 (file)
index 0000000..ece3747
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGVarargsForwardingPhase_h
+#define DFGVarargsForwardingPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Eliminates allocations of Arguments-class objects when they flow into CallVarargs, ConstructVarargs,
+// or LoadVarargs.
+
+bool performVarargsForwarding(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGVarargsForwardingPhase_h
+
index 82784c8704174b9689f026fed7561693293cf09e..bd1ba87eeb2e526d8b4c05eb736d3efeaed2be85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,9 +35,7 @@ VariableAccessData::VariableAccessData()
     , m_prediction(SpecNone)
     , m_argumentAwarePrediction(SpecNone)
     , m_flags(0)
-    , m_isCaptured(false)
     , m_shouldNeverUnbox(false)
-    , m_isArgumentsAlias(false)
     , m_structureCheckHoistingFailed(false)
     , m_checkArrayHoistingFailed(false)
     , m_isProfitableToUnbox(false)
@@ -47,14 +45,12 @@ VariableAccessData::VariableAccessData()
     clearVotes();
 }
 
-VariableAccessData::VariableAccessData(VirtualRegister local, bool isCaptured)
+VariableAccessData::VariableAccessData(VirtualRegister local)
     : m_local(local)
     , m_prediction(SpecNone)
     , m_argumentAwarePrediction(SpecNone)
     , m_flags(0)
-    , m_isCaptured(isCaptured)
-    , m_shouldNeverUnbox(isCaptured)
-    , m_isArgumentsAlias(false)
+    , m_shouldNeverUnbox(false)
     , m_structureCheckHoistingFailed(false)
     , m_checkArrayHoistingFailed(false)
     , m_isProfitableToUnbox(false)
@@ -64,12 +60,6 @@ VariableAccessData::VariableAccessData(VirtualRegister local, bool isCaptured)
     clearVotes();
 }
 
-bool VariableAccessData::mergeIsCaptured(bool isCaptured)
-{
-    return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured)
-        | checkAndSet(m_isCaptured, m_isCaptured | isCaptured);
-}
-
 bool VariableAccessData::mergeShouldNeverUnbox(bool shouldNeverUnbox)
 {
     bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox;
@@ -198,9 +188,6 @@ FlushFormat VariableAccessData::flushFormat()
 {
     ASSERT(find() == this);
     
-    if (isArgumentsAlias())
-        return FlushedArguments;
-    
     if (!shouldUnboxIfPossible())
         return FlushedJSValue;
     
index cfdd2647ecaa78fff5fe12b43dfab8dbc48efd6f..0f817561cd23bd58a12879cb1fbe7c8f0ce09ac3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,7 +48,7 @@ enum DoubleBallot { VoteValue, VoteDouble };
 class VariableAccessData : public UnionFind<VariableAccessData> {
 public:
     VariableAccessData();
-    VariableAccessData(VirtualRegister local, bool isCaptured);
+    VariableAccessData(VirtualRegister local);
     
     VirtualRegister local()
     {
@@ -62,16 +62,9 @@ public:
         return m_machineLocal;
     }
 
-    bool mergeIsCaptured(bool isCaptured);
-    
-    bool isCaptured()
-    {
-        return m_isCaptured;
-    }
-    
     bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
     {
-        return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox);
+        return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox || isProfitableToUnbox);
     }
     
     bool isProfitableToUnbox()
@@ -86,7 +79,6 @@ public:
     // mean that we have actually done so.
     bool shouldNeverUnbox()
     {
-        ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
         return m_shouldNeverUnbox;
     }
     
@@ -100,12 +92,12 @@ public:
 
     bool mergeStructureCheckHoistingFailed(bool failed)
     {
-        return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed);
+        return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed || failed);
     }
     
     bool mergeCheckArrayHoistingFailed(bool failed)
     {
-        return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed | failed);
+        return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed || failed);
     }
     
     bool structureCheckHoistingFailed()
@@ -118,19 +110,9 @@ public:
         return m_checkArrayHoistingFailed;
     }
     
-    bool mergeIsArgumentsAlias(bool isArgumentsAlias)
-    {
-        return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias);
-    }
-    
-    bool isArgumentsAlias()
-    {
-        return m_isArgumentsAlias;
-    }
-    
     bool mergeIsLoadedFrom(bool isLoadedFrom)
     {
-        return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom);
+        return checkAndSet(m_isLoadedFrom, m_isLoadedFrom || isLoadedFrom);
     }
     
     void setIsLoadedFrom(bool isLoadedFrom)
@@ -193,7 +175,6 @@ public:
         ASSERT(isRoot());
         bool doubleState = m_doubleFormatState == UsingDoubleFormat;
         ASSERT(!(doubleState && shouldNeverUnbox()));
-        ASSERT(!(doubleState && isCaptured()));
         return doubleState && isProfitableToUnbox();
     }
     
@@ -233,9 +214,7 @@ private:
     SpeculatedType m_argumentAwarePrediction;
     NodeFlags m_flags;
 
-    bool m_isCaptured;
     bool m_shouldNeverUnbox;
-    bool m_isArgumentsAlias;
     bool m_structureCheckHoistingFailed;
     bool m_checkArrayHoistingFailed;
     bool m_isProfitableToUnbox;
index 105964cfa40b79af533caf69f9c902a4a3677f1e..00621737e28b9feb99f867520acd52722c499dcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,9 +62,7 @@ void VariableAccessDataDump::dump(PrintStream& out) const
         index /= 26;
     }
     
-    if (m_data->isCaptured())
-        out.print("*");
-    else if (m_data->shouldNeverUnbox())
+    if (m_data->shouldNeverUnbox())
         out.print("!");
     else if (!m_data->shouldUnboxIfPossible())
         out.print("~");
index fd64e1a1908f1b19c96cf8a69ec4473f0c6ba3d1..fd53fcd2cbf0e6efdd9ff0d7b9f84eee58301b80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index b71f4e7ae5fda206e50587d693074c8f3c9a61aa..28e437fd51fea4969eb48ecf0c0508f0a37df835 100644 (file)
@@ -46,6 +46,9 @@ void VariableEvent::dump(PrintStream& out) const
     case BirthToSpill:
         dumpSpillInfo("BirthToSpill", out);
         break;
+    case Birth:
+        out.print("Birth(", id(), ")");
+        break;
     case Fill:
         dumpFillInfo("Fill", out);
         break;
@@ -56,11 +59,11 @@ void VariableEvent::dump(PrintStream& out) const
         out.print("Death(", id(), ")");
         break;
     case MovHintEvent:
-        out.print("MovHint(", id(), ", r", bytecodeRegister(), ")");
+        out.print("MovHint(", id(), ", ", bytecodeRegister(), ")");
         break;
     case SetLocalEvent:
         out.print(
-            "SetLocal(machine:r", machineRegister(), " -> bytecode:r", bytecodeRegister(),
+            "SetLocal(machine:", machineRegister(), " -> bytecode:", bytecodeRegister(),
             ", ", dataFormatToString(dataFormat()), ")");
         break;
     default:
@@ -85,7 +88,7 @@ void VariableEvent::dumpFillInfo(const char* name, PrintStream& out) const
 
 void VariableEvent::dumpSpillInfo(const char* name, PrintStream& out) const
 {
-    out.print(name, "(", id(), ", r", spillRegister(), ", ", dataFormatToString(dataFormat()), ")");
+    out.print(name, "(", id(), ", ", spillRegister(), ", ", dataFormatToString(dataFormat()), ")");
 }
 
 } } // namespace JSC::DFG
index 9e76e558e68a4f82518541af828c5e74508ff800..5fa4bb6865fb9e5b64b2b5882f212a0b73e4ac91 100644 (file)
@@ -47,6 +47,7 @@ enum VariableEventKind {
     // that we start to care about this node.
     BirthToFill,
     BirthToSpill,
+    Birth,
     
     // Events related to how a node is represented.
     Fill,
@@ -133,6 +134,14 @@ public:
         return event;
     }
     
+    static VariableEvent birth(MinifiedID id)
+    {
+        VariableEvent event;
+        event.m_which.id = id.bits();
+        event.m_kind = Birth;
+        return event;
+    }
+    
     static VariableEvent spill(VariableEventKind kind, MinifiedID id, VirtualRegister virtualRegister, DataFormat format)
     {
         ASSERT(kind == BirthToSpill || kind == Spill);
@@ -179,17 +188,17 @@ public:
     
     MinifiedID id() const
     {
-        ASSERT(m_kind == BirthToFill || m_kind == Fill
-               || m_kind == BirthToSpill || m_kind == Spill
-               || m_kind == Death || m_kind == MovHintEvent);
+        ASSERT(
+            m_kind == BirthToFill || m_kind == Fill || m_kind == BirthToSpill || m_kind == Spill
+            || m_kind == Death || m_kind == MovHintEvent || m_kind == Birth);
         return MinifiedID::fromBits(m_which.id);
     }
     
     DataFormat dataFormat() const
     {
-        ASSERT(m_kind == BirthToFill || m_kind == Fill
-               || m_kind == BirthToSpill || m_kind == Spill
-               || m_kind == SetLocalEvent);
+        ASSERT(
+            m_kind == BirthToFill || m_kind == Fill || m_kind == BirthToSpill || m_kind == Spill
+            || m_kind == SetLocalEvent);
         return static_cast<DataFormat>(m_dataFormat);
     }
     
index c209ce45b2e4047b9c2036324f0259f4034f6331..e3f413c3b8ff2ff6a10250333ea40ca28879faf8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,11 +48,14 @@ namespace {
 
 struct MinifiedGenerationInfo {
     bool filled; // true -> in gpr/fpr/pair, false -> spilled
+    bool alive;
     VariableRepresentation u;
     DataFormat format;
     
     MinifiedGenerationInfo()
-        : format(DataFormatNone)
+        : filled(false)
+        , alive(false)
+        , format(DataFormatNone)
     {
     }
     
@@ -62,13 +65,19 @@ struct MinifiedGenerationInfo {
         case BirthToFill:
         case Fill:
             filled = true;
+            alive = true;
             break;
         case BirthToSpill:
         case Spill:
             filled = false;
+            alive = true;
             break;
+        case Birth:
+            alive = true;
+            return;
         case Death:
             format = DataFormatNone;
+            alive = false;
             return;
         default:
             return;
@@ -81,25 +90,23 @@ struct MinifiedGenerationInfo {
 
 } // namespace
 
-bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, CodeBlock* codeBlock, MinifiedNode* node) const
+bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, MinifiedNode* node) const
 {
     if (!node)
         return false;
     
-    if (node->hasConstantNumber()) {
-        recovery = ValueRecovery::constant(
-            codeBlock->constantRegister(
-                FirstConstantRegisterIndex + node->constantNumber()).get());
+    if (node->hasConstant()) {
+        recovery = ValueRecovery::constant(node->constant());
         return true;
     }
     
-    if (node->hasWeakConstant()) {
-        recovery = ValueRecovery::constant(node->weakConstant());
+    if (node->op() == PhantomDirectArguments) {
+        recovery = ValueRecovery::directArgumentsThatWereNotCreated(node->id());
         return true;
     }
     
-    if (node->op() == PhantomArguments) {
-        recovery = ValueRecovery::argumentsThatWereNotCreated();
+    if (node->op() == PhantomClonedArguments) {
+        recovery = ValueRecovery::outOfBandArgumentsThatWereNotCreated(node->id());
         return true;
     }
     
@@ -148,7 +155,8 @@ void VariableEventStream::reconstruct(
             // nothing to do.
             break;
         case BirthToFill:
-        case BirthToSpill: {
+        case BirthToSpill:
+        case Birth: {
             MinifiedGenerationInfo info;
             info.update(event);
             generationInfos.add(event.id(), info);
@@ -187,14 +195,14 @@ void VariableEventStream::reconstruct(
         
         ASSERT(source.kind() == HaveNode);
         MinifiedNode* node = graph.at(source.id());
-        if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, node))
-            continue;
-        
         MinifiedGenerationInfo info = generationInfos.get(source.id());
-        if (info.format == DataFormatNone) {
+        if (!info.alive) {
             valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
             continue;
         }
+
+        if (tryToSetConstantRecovery(valueRecoveries[i], node))
+            continue;
         
         ASSERT(info.format != DataFormatNone);
         
index 2bcf549bde1a4557ec72a18ae4bde7d232009cea..b0e4afac50af80420ea80ce3fd2d71dfdcbef216 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 #include "DFGMinifiedGraph.h"
 #include "DFGVariableEvent.h"
 #include "Operands.h"
+#include "ValueRecovery.h"
 #include <wtf/Vector.h>
 
 namespace JSC { namespace DFG {
@@ -48,7 +49,7 @@ public:
         unsigned index, Operands<ValueRecovery>&) const;
 
 private:
-    bool tryToSetConstantRecovery(ValueRecovery&, CodeBlock*, MinifiedNode*) const;
+    bool tryToSetConstantRecovery(ValueRecovery&, MinifiedNode*) const;
     
     void logEvent(const VariableEvent&);
 };
index 29310d3abd01282eeeae0c2dd909bb2ef7d3aebc..e5e133d43b54c222e400343035484246f1339c0b 100644 (file)
@@ -45,6 +45,8 @@ public:
     
     bool run()
     {
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == ThreadedCPS);
+        
         ScoreBoard scoreBoard(m_graph.m_nextMachineLocal);
         scoreBoard.assertClear();
         for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
@@ -53,6 +55,10 @@ public:
                 continue;
             if (!block->isReachable)
                 continue;
+            if (!ASSERT_DISABLED) {
+                // Force usage of highest-numbered virtual registers.
+                scoreBoard.sortFree();
+            }
             for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                 Node* node = block->at(indexInBlock);
         
index 43e1b2d89d3920103acbb3c11906931f2b0d8046..f924e4a2ce9219a880c2ec2418f9a70fa3b9f7d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DFGPhase.h"
 #include "JSCInlines.h"
 
+// FIXME: Remove this phase entirely by moving the addLazily() calls into either the backend or
+// into the phase that performs the optimization. Moving the calls into the backend makes the most
+// sense when the intermediate phases don't need to know that the watchpoint was set. Moving the
+// calls earlier usually only makes sense if the node's only purpose was to convey the need for
+// the watchpoint (like VarInjectionWatchpoint). But, it can also make sense if the fact that the
+// watchpoint was set enables other optimizations.
+// https://bugs.webkit.org/show_bug.cgi?id=144669
+
 namespace JSC { namespace DFG {
 
 class WatchpointCollectionPhase : public Phase {
@@ -64,8 +72,6 @@ public:
 private:
     void handle()
     {
-        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, handleEdge);
-        
         switch (m_node->op()) {
         case CompareEqConstant:
         case IsUndefined:
@@ -81,31 +87,14 @@ private:
             
         case LogicalNot:
         case Branch:
-            if (m_node->child1().useKind() == ObjectOrOtherUse)
+            switch (m_node->child1().useKind()) {
+            case ObjectOrOtherUse:
+            case UntypedUse:
                 handleMasqueradesAsUndefined();
-            break;
-            
-        case GetByVal:
-            if (m_node->arrayMode().type() == Array::Double
-                && m_node->arrayMode().isSaneChain()) {
-                addLazily(globalObject()->arrayPrototype()->structure()->transitionWatchpointSet());
-                addLazily(globalObject()->objectPrototype()->structure()->transitionWatchpointSet());
+                break;
+            default:
+                break;
             }
-            
-            if (m_node->arrayMode().type() == Array::String)
-                handleStringGetByVal();
-
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))
-                addLazily(view);
-            break;
-            
-        case PutByVal:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node))
-                addLazily(view);
-            break;
-            
-        case StringCharAt:
-            handleStringGetByVal();
             break;
             
         case NewArray:
@@ -115,53 +104,10 @@ private:
                 addLazily(globalObject()->havingABadTimeWatchpoint());
             break;
             
-        case AllocationProfileWatchpoint:
-            addLazily(jsCast<JSFunction*>(m_node->function())->allocationProfileWatchpointSet());
-            break;
-            
-        case StructureTransitionWatchpoint:
-            m_graph.watchpoints().addLazily(
-                m_node->origin.semantic,
-                m_node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint,
-                m_node->structure()->transitionWatchpointSet());
-            break;
-            
-        case VariableWatchpoint:
-            addLazily(m_node->variableWatchpointSet());
-            break;
-            
         case VarInjectionWatchpoint:
             addLazily(globalObject()->varInjectionWatchpoint());
             break;
             
-        case FunctionReentryWatchpoint:
-            addLazily(m_node->symbolTable()->m_functionEnteredOnce);
-            break;
-            
-        case TypedArrayWatchpoint:
-            addLazily(m_node->typedArray());
-            break;
-            
-        default:
-            break;
-        }
-    }
-    
-    void handleEdge(Node*, Edge edge)
-    {
-        switch (edge.useKind()) {
-        case StringObjectUse:
-        case StringOrStringObjectUse: {
-            Structure* stringObjectStructure = globalObject()->stringObjectStructure();
-            Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
-            ASSERT(m_graph.watchpoints().isValidOrMixed(stringPrototypeStructure->transitionWatchpointSet()));
-            
-            m_graph.watchpoints().addLazily(
-                m_node->origin.semantic, NotStringObject,
-                stringPrototypeStructure->transitionWatchpointSet());
-            break;
-        }
-            
         default:
             break;
         }
@@ -173,16 +119,6 @@ private:
             addLazily(globalObject()->masqueradesAsUndefinedWatchpoint());
     }
     
-    void handleStringGetByVal()
-    {
-        if (!m_node->arrayMode().isOutOfBounds())
-            return;
-        if (!globalObject()->stringPrototypeChainIsSane())
-            return;
-        addLazily(globalObject()->stringPrototype()->structure()->transitionWatchpointSet());
-        addLazily(globalObject()->objectPrototype()->structure()->transitionWatchpointSet());
-    }
-
     void addLazily(WatchpointSet* set)
     {
         m_graph.watchpoints().addLazily(set);
@@ -191,10 +127,6 @@ private:
     {
         m_graph.watchpoints().addLazily(set);
     }
-    void addLazily(JSArrayBufferView* view)
-    {
-        m_graph.watchpoints().addLazily(view);
-    }
     
     JSGlobalObject* globalObject()
     {
index 4aa1428a6cdd6da0857ff3555c27f5d1d43263a1..4a8f572248d0cbb6d88e21f4eba6abf4df4d1686 100644 (file)
@@ -68,9 +68,9 @@ void Worklist::finishCreation(unsigned numberOfThreads, int relativePriority)
     }
 }
 
-PassRefPtr<Worklist> Worklist::create(CString worklistName, unsigned numberOfThreads, int relativePriority)
+Ref<Worklist> Worklist::create(CString worklistName, unsigned numberOfThreads, int relativePriority)
 {
-    RefPtr<Worklist> result = adoptRef(new Worklist(worklistName));
+    Ref<Worklist> result = adoptRef(*new Worklist(worklistName));
     result->finishCreation(numberOfThreads, relativePriority);
     return result;
 }
@@ -406,7 +406,7 @@ Worklist* ensureGlobalDFGWorklist()
 {
     static std::once_flag initializeGlobalWorklistOnceFlag;
     std::call_once(initializeGlobalWorklistOnceFlag, [] {
-        theGlobalDFGWorklist = Worklist::create("DFG Worklist", Options::numberOfDFGCompilerThreads(), Options::priorityDeltaOfDFGCompilerThreads()).leakRef();
+        theGlobalDFGWorklist = &Worklist::create("DFG Worklist", Options::numberOfDFGCompilerThreads(), Options::priorityDeltaOfDFGCompilerThreads()).leakRef();
     });
     return theGlobalDFGWorklist;
 }
@@ -422,7 +422,7 @@ Worklist* ensureGlobalFTLWorklist()
 {
     static std::once_flag initializeGlobalWorklistOnceFlag;
     std::call_once(initializeGlobalWorklistOnceFlag, [] {
-        theGlobalFTLWorklist = Worklist::create("FTL Worklist", Options::numberOfFTLCompilerThreads(), Options::priorityDeltaOfFTLCompilerThreads()).leakRef();
+        theGlobalFTLWorklist = &Worklist::create("FTL Worklist", Options::numberOfFTLCompilerThreads(), Options::priorityDeltaOfFTLCompilerThreads()).leakRef();
     });
     return theGlobalFTLWorklist;
 }
index 3d0b5d6eed2d8d002b10ee91e122c0121a2a1627..bd6e6fa75f6240e27d30e633296d1a565250fd03 100644 (file)
@@ -33,7 +33,6 @@
 #include <wtf/Deque.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/ThreadingPrimitives.h>
 
 namespace JSC {
@@ -49,7 +48,7 @@ public:
 
     ~Worklist();
     
-    static PassRefPtr<Worklist> create(CString worklistName, unsigned numberOfThreads, int relativePriority = 0);
+    static Ref<Worklist> create(CString worklistName, unsigned numberOfThreads, int relativePriority = 0);
     
     void enqueue(PassRefPtr<Plan>);
     
index 415dbdb8e02ded4e318c82715df6542f5b1342ac..52a92c669c8327935d713bfa3fe735a7fa269ca7 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define __STDC_FORMAT_MACROS
 #include "config.h"
+
+#if USE(ARM64_DISASSEMBLER)
+
 #include "A64DOpcode.h"
 
 #include <stdarg.h>
@@ -1194,3 +1198,5 @@ const char* A64DOpcodeUnconditionalBranchRegister::format()
 }
 
 } } // namespace JSC::ARM64Disassembler
+
+#endif // USE(ARM64_DISASSEMBLER)
index 1c6ac431906694a755bae0bcaaa2e5ea6b1c9642..5bb7db9f12b34fb25323b8f14924b0254bbb07d4 100644 (file)
@@ -172,12 +172,12 @@ protected:
 
     void appendUnsignedImmediate64(uint64_t immediate)
     {
-        bufferPrintf("#0x%llx", immediate);
+        bufferPrintf("#0x%" PRIx64, immediate);
     }
 
     void appendPCRelativeOffset(uint32_t* pc, int32_t immediate)
     {
-        bufferPrintf("0x%llx", reinterpret_cast<uint64_t>(pc + immediate));
+        bufferPrintf("0x%" PRIx64, reinterpret_cast<uint64_t>(pc + immediate));
     }
 
     void appendShiftAmount(unsigned amount)
index 7b86bf0e8cb28d424e8522a0ef081b8cc373c95c..900b87ef700aa8813b2a847d61719dd200d9e188 100644 (file)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define __STDC_FORMAT_MACROS
 #include "config.h"
 #include "Disassembler.h"
 
index c11acf8cb2dca3663ee334cf0388860f58954301..3175cccbd914235f0cfb70cd1a75c865875e5694 100644 (file)
@@ -113,11 +113,16 @@ static Opcode16GroupInitializer opcode16BitGroupList[] = {
 };
 
 static Opcode32GroupInitializer opcode32BitGroupList[] = {
+    OPCODE_GROUP_ENTRY(0x4, ARMv7DOpcodeDataPopMultiple),
+    OPCODE_GROUP_ENTRY(0x4, ARMv7DOpcodeDataPushMultiple),
     OPCODE_GROUP_ENTRY(0x5, ARMv7DOpcodeDataProcessingShiftedReg),
+    OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeVLDR),
     OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeVMOVSinglePrecision),
     OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeVMOVDoublePrecision),
     OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeFPTransfer),
     OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVMSR),
+    OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVCMP),
+    OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVCVTBetweenFPAndInt),
     OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeDataProcessingModifiedImmediate),
     OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeConditionalBranchT3),
     OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeBranchOrBranchLink),
@@ -133,6 +138,8 @@ static Opcode32GroupInitializer opcode32BitGroupList[] = {
     OPCODE_GROUP_ENTRY(0xb, ARMv7DOpcodeBranchOrBranchLink),
     OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeLoadRegister),
     OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeDataPushPopSingle), // Should be before StoreSingle*
+    OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeDataPopMultiple),
+    OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeDataPushMultiple),
     OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleRegister),
     OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleImmediate12),
     OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleImmediate8),
@@ -143,6 +150,9 @@ static Opcode32GroupInitializer opcode32BitGroupList[] = {
     OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegExtend),
     OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegParallel),
     OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegMisc),
+    OPCODE_GROUP_ENTRY(0xe, ARMv7DOpcodeVLDR),
+    OPCODE_GROUP_ENTRY(0xf, ARMv7DOpcodeVCMP),
+    OPCODE_GROUP_ENTRY(0xf, ARMv7DOpcodeVCVTBetweenFPAndInt),
 };
 
 bool ARMv7DOpcode::s_initialized = false;
@@ -1444,6 +1454,46 @@ const char* ARMv7DOpcodeDataPushPopSingle::format()
     return m_formatBuffer;
 }
 
+void ARMv7DOpcodeDataPushPopMultiple::appendRegisterList()
+{
+    unsigned registers = registerList();
+
+    appendCharacter('{');
+    bool needSeparator = false;
+
+    for (unsigned i = 0; i < 16; i++) {
+        if (registers & (1 << i)) {
+            if (needSeparator)
+                appendSeparator();
+            appendRegisterName(i);
+            needSeparator = true;
+        }
+    }
+    appendCharacter('}');
+}
+
+const char* ARMv7DOpcodeDataPopMultiple::format()
+{
+    if (condition() != 0xe)
+        bufferPrintf("   pop%-4.4s", conditionName(condition()));
+    else
+        appendInstructionName("pop");
+    appendRegisterList();
+
+    return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeDataPushMultiple::format()
+{
+    if (condition() != 0xe)
+        bufferPrintf("   push%-3.3s", conditionName(condition()));
+    else
+        appendInstructionName("push");
+    appendRegisterList();
+
+    return m_formatBuffer;
+}
+
 const char* ARMv7DOpcodeStoreSingleImmediate12::format()
 {
     appendInstructionName(opName());
@@ -1513,6 +1563,104 @@ const char* ARMv7DOpcodeStoreSingleRegister::format()
     return m_formatBuffer;
 }
 
+const char* ARMv7DOpcodeVCMP::format()
+{
+    bufferPrintf("   vcmp");
+
+    if (eBit())
+        appendCharacter('e'); // Raise exception on qNaN
+
+    if (condition() != 0xe)
+        appendString(conditionName(condition()));
+
+    appendCharacter('.');
+    appendString(szBit() ? "f64" : "f32");
+    appendCharacter(' ');
+    if (szBit()) {
+        appendFPRegisterName('d', (dBit() << 4) | vd());
+        appendSeparator();
+        appendFPRegisterName('d', (mBit() << 4) | vm());
+    } else {
+        appendFPRegisterName('s', (vd() << 1) | dBit());
+        appendSeparator();
+        appendFPRegisterName('s', (vm() << 1) | mBit());
+    }
+
+    return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVCVTBetweenFPAndInt::format()
+{
+    bufferPrintf("   vcvt");
+    bool convertToInteger = op2() & 0x4;
+
+    if (convertToInteger) {
+        if (!op())
+            appendCharacter('r'); // Round using mode in FPSCR
+        if (condition() != 0xe)
+            appendString(conditionName(condition()));
+        appendCharacter('.');
+        appendCharacter((op2() & 1) ? 's' : 'u');
+        appendString("32.f");
+        appendString(szBit() ? "64" : "32");
+        appendCharacter(' ');
+        appendFPRegisterName('s', (vd() << 1) | dBit());
+        appendSeparator();
+        if (szBit())
+            appendFPRegisterName('d', (mBit() << 4) | vm());
+        else
+            appendFPRegisterName('s', (vm() << 1) | mBit());
+    } else {
+        if (condition() != 0xe)
+            appendString(conditionName(condition()));
+        appendCharacter('.');
+        appendString(szBit() ? "f64." : "f32.");
+        appendString(op() ? "s32" : "u32");
+        appendCharacter(' ');
+        if (szBit())
+            appendFPRegisterName('d', (dBit() << 4) | vd());
+        else
+            appendFPRegisterName('s', (vd() << 1) | dBit());
+        appendSeparator();
+        appendFPRegisterName('s', (vm() << 1) | mBit());
+    }
+
+    return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVLDR::format()
+{
+    if (condition() != 0xe)
+        bufferPrintf("   vldr%-3.3s", conditionName(condition()));
+    else
+        appendInstructionName("vldr");
+
+    appendFPRegisterName(doubleReg() ? 'd' : 's', vd());
+    appendSeparator();
+
+    int immediate = immediate8() * 4;
+
+    if (!uBit())
+        immediate = -immediate;
+
+    appendCharacter('[');
+
+    if (rn() == RegPC)
+        appendPCRelativeOffset(immediate);
+    else {
+        appendRegisterName(rn());
+
+        if (immediate) {
+            appendSeparator();
+            appendSignedImmediate(immediate);
+        }
+    }
+
+    appendCharacter(']');
+
+    return m_formatBuffer;
+}
+
 const char* ARMv7DOpcodeVMOVDoublePrecision::format()
 {
     appendInstructionName("vmov");
index 4273c31dcc8b77cc40f2efac4cb355790b18e7ae..13e209db77ccedd82975049ded74d678c9105c6a 100644 (file)
@@ -1019,6 +1019,36 @@ protected:
     unsigned op() { return (m_opcode >> 20) & 0x1; }
 };
 
+class ARMv7DOpcodeDataPushPopMultiple : public ARMv7D32BitOpcode {
+protected:
+    void appendRegisterList();
+
+    unsigned registerList() { return m_opcode & 0xffff; }
+    unsigned condition() { return m_opcode >> 28; }
+};
+
+class ARMv7DOpcodeDataPopMultiple : public ARMv7DOpcodeDataPushPopMultiple {
+public:
+    static const uint32_t s_mask = 0x0fff0000;
+    static const uint32_t s_pattern = 0x08bd0000;
+
+    DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPopMultiple, thisObj);
+
+protected:
+    const char* format();
+};
+
+class ARMv7DOpcodeDataPushMultiple : public ARMv7DOpcodeDataPushPopMultiple {
+public:
+    static const uint32_t s_mask = 0xfe7f0000;
+    static const uint32_t s_pattern = 0xe82d0000;
+
+    DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushMultiple, thisObj);
+
+protected:
+    const char* format();
+};
+
 class ARMv7DOpcodeDataStoreSingle : public ARMv7D32BitOpcode {
 protected:
     static const char* const s_opNames[4];
@@ -1094,6 +1124,63 @@ protected:
     unsigned immediate16() { return ((m_opcode >> 4) & 0xf000) | ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
 };
 
+class ARMv7DOpcodeVCMP : public ARMv7D32BitOpcode {
+public:
+    static const uint32_t s_mask = 0x0fbf0e50;
+    static const uint32_t s_pattern = 0x0eb40a40;
+
+    DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCMP, thisObj);
+
+protected:
+    const char* format();
+
+    unsigned condition() { return m_opcode >> 28; }
+    unsigned dBit() { return (m_opcode >> 22) & 0x1; }
+    unsigned vd() { return (m_opcode >> 12) & 0xf; }
+    unsigned szBit() { return (m_opcode >> 8) & 0x1; }
+    unsigned eBit() { return (m_opcode >> 7) & 0x1; }
+    unsigned mBit() { return (m_opcode >> 5) & 0x1; }
+    unsigned vm() { return m_opcode & 0xf; }
+};
+
+class ARMv7DOpcodeVCVTBetweenFPAndInt : public ARMv7D32BitOpcode {
+public:
+    static const uint32_t s_mask = 0x0fb80e50;
+    static const uint32_t s_pattern = 0x0eb80a40;
+
+    DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVCVTBetweenFPAndInt, thisObj);
+
+protected:
+    const char* format();
+
+    unsigned condition() { return m_opcode >> 28; }
+    unsigned dBit() { return (m_opcode >> 22) & 0x1; }
+    unsigned op2() { return (m_opcode >> 16) & 0x7; }
+    unsigned vd() { return (m_opcode >> 12) & 0xf; }
+    unsigned szBit() { return (m_opcode >> 8) & 0x1; }
+    unsigned op() { return (m_opcode >> 7) & 0x1; }
+    unsigned mBit() { return (m_opcode >> 5) & 0x1; }
+    unsigned vm() { return m_opcode & 0xf; }
+};
+
+class ARMv7DOpcodeVLDR : public ARMv7D32BitOpcode {
+public:
+    static const uint32_t s_mask = 0x0f300e00;
+    static const uint32_t s_pattern = 0x0d100a00;
+
+    DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVLDR, thisObj);
+
+protected:
+    const char* format();
+
+    unsigned condition() { return m_opcode >> 28; }
+    unsigned uBit() { return (m_opcode >> 23) & 0x1; }
+    unsigned rn() { return (m_opcode >> 16) & 0xf; }
+    unsigned vd() { return ((m_opcode >> 18) & 0x10) | ((m_opcode >> 12) & 0xf); }
+    bool doubleReg() { return !!(m_opcode & 0x100); }
+    unsigned immediate8() { return m_opcode & 0xff; }
+};
+
 class ARMv7DOpcodeVMOVDoublePrecision : public ARMv7D32BitOpcode {
 public:
     static const uint32_t s_mask = 0xffe00fd0;
index 8bf3d15d62ec3b8af8088fdac57afd7253f19019..8f357423ac81ace6e14d36d80571ca2440c7396f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "MacroAssemblerCodeRef.h"
 #include <wtf/DataLog.h>
+#include <wtf/Deque.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/StringPrintStream.h>
+#include <wtf/Threading.h>
+#include <wtf/ThreadingPrimitives.h>
 
 namespace JSC {
 
@@ -39,5 +44,112 @@ void disassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char*
     out.printf("%sdisassembly not available for range %p...%p\n", prefix, codePtr.executableAddress(), static_cast<char*>(codePtr.executableAddress()) + size);
 }
 
+namespace {
+
+// This is really a struct, except that it should be a class because that's what the WTF_* macros
+// expect.
+class DisassemblyTask {
+    WTF_MAKE_NONCOPYABLE(DisassemblyTask);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    DisassemblyTask()
+    {
+    }
+    
+    ~DisassemblyTask()
+    {
+        if (header)
+            free(header); // free() because it would have been copied by strdup.
+    }
+    
+    char* header { nullptr };
+    MacroAssemblerCodeRef codeRef;
+    size_t size { 0 };
+    const char* prefix { nullptr };
+    InstructionSubsetHint subsetHint { MacroAssemblerSubset };
+};
+
+class AsynchronousDisassembler {
+public:
+    AsynchronousDisassembler()
+    {
+        createThread("Asynchronous Disassembler", [&] () { run(); });
+    }
+    
+    void enqueue(std::unique_ptr<DisassemblyTask> task)
+    {
+        MutexLocker locker(m_lock);
+        m_queue.append(WTF::move(task));
+        m_condition.broadcast();
+    }
+    
+    void waitUntilEmpty()
+    {
+        MutexLocker locker(m_lock);
+        while (!m_queue.isEmpty() || m_working)
+            m_condition.wait(m_lock);
+    }
+    
+private:
+    NO_RETURN void run()
+    {
+        for (;;) {
+            std::unique_ptr<DisassemblyTask> task;
+            {
+                MutexLocker locker(m_lock);
+                m_working = false;
+                m_condition.broadcast();
+                while (m_queue.isEmpty())
+                    m_condition.wait(m_lock);
+                task = m_queue.takeFirst();
+                m_working = true;
+            }
+
+            dataLog(task->header);
+            disassemble(
+                task->codeRef.code(), task->size, task->prefix, WTF::dataFile(),
+                task->subsetHint);
+        }
+    }
+    
+    Mutex m_lock;
+    ThreadCondition m_condition;
+    Deque<std::unique_ptr<DisassemblyTask>> m_queue;
+    bool m_working { false };
+};
+
+bool hadAnyAsynchronousDisassembly = false;
+
+AsynchronousDisassembler& asynchronousDisassembler()
+{
+    static NeverDestroyed<AsynchronousDisassembler> disassembler;
+    hadAnyAsynchronousDisassembly = true;
+    return disassembler.get();
+}
+
+} // anonymous namespace
+
+void disassembleAsynchronously(
+    const CString& header, const MacroAssemblerCodeRef& codeRef, size_t size, const char* prefix,
+    InstructionSubsetHint subsetHint)
+{
+    std::unique_ptr<DisassemblyTask> task = std::make_unique<DisassemblyTask>();
+    task->header = strdup(header.data()); // Yuck! We need this because CString does racy refcounting.
+    task->codeRef = codeRef;
+    task->size = size;
+    task->prefix = prefix;
+    task->subsetHint = subsetHint;
+    
+    asynchronousDisassembler().enqueue(WTF::move(task));
+}
+
+void waitForAsynchronousDisassembly()
+{
+    if (!hadAnyAsynchronousDisassembly)
+        return;
+    
+    asynchronousDisassembler().waitUntilEmpty();
+}
+
 } // namespace JSC
 
index d086c8383b5a907c06e2991e598a5503579cacfb..6eaf7b616432792c75cf8c9b92b3d56e9fc19958 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef Disassembler_h
 #define Disassembler_h
 
+#include <functional>
 #include <wtf/PrintStream.h>
+#include <wtf/text/CString.h>
 
 namespace JSC {
 
 class MacroAssemblerCodePtr;
+class MacroAssemblerCodeRef;
 
 enum InstructionSubsetHint { MacroAssemblerSubset, LLVMSubset };
 
@@ -47,6 +50,14 @@ inline bool tryToDisassemble(const MacroAssemblerCodePtr&, size_t, const char*,
 // the range of machine code addresses.
 void disassemble(const MacroAssemblerCodePtr&, size_t, const char* prefix, PrintStream& out, InstructionSubsetHint = MacroAssemblerSubset);
 
+// Asynchronous disassembly. This happens on another thread, and calls the provided
+// callback when the disassembly is done.
+void disassembleAsynchronously(
+    const CString& header, const MacroAssemblerCodeRef&, size_t, const char* prefix,
+    InstructionSubsetHint = MacroAssemblerSubset);
+
+JS_EXPORT_PRIVATE void waitForAsynchronousDisassembly();
+
 } // namespace JSC
 
 #endif // Disassembler_h
diff --git a/features.json b/features.json
new file mode 100644 (file)
index 0000000..e44b767
--- /dev/null
@@ -0,0 +1,211 @@
+{
+    "specification": [
+    {
+        "name": "ES6",
+        "url": "http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts",
+        "keywords": ["es6", "es2015", "ecmascript"]
+    },
+    {
+        "name": "ES7",
+        "url": "https://github.com/tc39/ecma262",
+        "keywords": ["es7", "ecmascript"]
+    }
+    ],
+
+    "features": [
+    {
+        "name": "ASM.js",
+        "status": {
+            "status": "Continuously improving",
+            "enabled-by-default": true
+        },
+        "url": "http://asmjs.org",
+        "description": "ASM.js defines a subset of JavaScript that enforce stronger typing and has specific patterns of memory access. ASM.js is rarely hand-written, it is typically generated from other languages by compiler such as Emscripten.",
+        "comment": "There is no \"use asm\" mode in JavaScriptCore. Instead WebKit integrates ASM.js optimizations directly in the optimizer. As a result, it is possible to mix ASM-style typing with regular code and still get great performance and power efficiency."
+    },
+    {
+        "name": "Array.prototype.copyWithin",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.copywithin",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=145107",
+        "specification": "ES6",
+        "contact": {
+            "name": "Yusuke Suzuki",
+            "email": "utatane.tea@gmail.com"
+        }
+    },
+    {
+        "name": "Array.prototype.includes",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://github.com/tc39/Array.prototype.includes",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=142707",
+        "specification": "ES7"
+    },
+    {
+        "name": "Classes",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-class-definitions",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=142774",
+        "specification": "ES6",
+        "description": "The new class syntax of ES6 provides a new syntax to define and extend JavaScript objects. The class syntax is a new notation, objects still use prototypal inheritance."
+    },
+    {
+        "name": "Map data structure",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-constructor",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=120333",
+        "description": "Map provides an <a href=\"https://en.wikipedia.org/wiki/Associative_array\">associative array data</a> structure that maps keys to values.",
+        "specification": "ES6"
+    },
+    {
+        "name": "Number extensions (ES6)",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number-objects",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=131707",
+        "specification": "ES6",
+        "description": "ES6 extend Number with the methods Number.isFinite(), Number.isInteger(), Number.isSafeInteger(), Number.isNaN() and the attributes Number.EPSILON, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER."
+    },
+    {
+        "name": "Octal and binary literals",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-numeric-literals",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=142681",
+        "specification": "ES6",
+        "description": "New syntax for number literals. Numbers can be provided as binary (e.g. 0b001001) or octal (e.g. 0o24)."
+    },
+    {
+        "name": "Promise Objects",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true,
+            "shipped": ["ios8-safari", "osx-safari-7.1"]
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=120260",
+        "specification": "ES6"
+    },
+    {
+        "name": "Set data structure",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-constructor",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=120549",
+        "description": "Set is a collection of unique objects.",
+        "specification": "ES6"
+    },
+    {
+        "name": "Symbol Objects",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "https://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-objects",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=140435",
+        "specification": "ES6",
+        "contact": {
+            "name": "Yusuke Suzuki",
+            "email": "utatane.tea@gmail.com"
+        }
+    },
+    {
+        "name": "Tagged templates",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tagged-templates",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=143183",
+        "description": "The tagged-templates (like String.raw`Hello ${World}`) provides a way to modify the produced string from a given template-literals with a function.",
+        "specification": "ES6",
+        "contact": {
+            "name": "Yusuke Suzuki",
+            "email": "utatane.tea@gmail.com"
+        }
+    },
+    {
+        "name": "Template literals",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literals",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=142691",
+        "description": "The template-literals (like `Hello ${World}`) provides string interpolation feature. Line terminators are also allowed in the template-literals.",
+        "specification": "ES6",
+        "contact": {
+            "name": "Yusuke Suzuki",
+            "email": "utatane.tea@gmail.com"
+        }
+    },
+    {
+        "name": "WeakMap",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakmap-objects",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=120912",
+        "description": "WeakMap provides an <a href=\"https://en.wikipedia.org/wiki/Associative_array\">associative array data</a> structure that maps keys to values. WeakMap's keys must be objects.",
+        "specification": "ES6"
+    },
+    {
+        "name": "WeakSet",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakset-objects",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet",
+        "webkit-url": "https://bugs.webkit.org/show_bug.cgi?id=142408",
+        "description": "WeakSet is a collection of unique objects. Keys stored in WeakSet are referenced weakly.",
+        "specification": "ES6",
+        "contact": {
+            "name": "Yusuke Suzuki",
+            "email": "utatane.tea@gmail.com"
+        }
+    },
+    {
+        "name": "for...of loops",
+        "status": {
+            "status": "Done",
+            "enabled-by-default": true
+        },
+        "url": "http://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-in-and-for-of-statements",
+        "documentation-url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of",
+        "description": "The for...of loops iterate over the values provided by the iterator of the target object.",
+        "specification": "ES6",
+        "comment": "Older versions of WebKit only supported iterating JavaScript arrays."
+    }
+    ]
+}
index e824f87808fcbd4fbc4169cfc912e42f73305c13..2b9361909c22892de81651dddbda4e52170a46ed 100644 (file)
@@ -43,6 +43,7 @@ typedef LLVMModuleRef LModule;
 typedef LLVMRealPredicate LRealPredicate;
 typedef LLVMTypeRef LType;
 typedef LLVMValueRef LValue;
+typedef LLVMMemoryBufferRef LMemoryBuffer;
 
 } } // namespace JSC::FTL
 
index 78a7bf5ec82f15182399e7bc87fe755f4451902a..d3bff4cc1c88782b66d20a089b8dd5bd975f89df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -77,6 +77,9 @@ static inline LType structType(LContext context, LType element1, LType element2,
     return structType(context, elements, 2, packing);
 }
 
+// FIXME: Make the Variadicity argument not be the last argument to functionType() so that this function
+// can use C++11 variadic templates
+// https://bugs.webkit.org/show_bug.cgi?id=141575
 enum Variadicity { NotVariadic, Variadic };
 static inline LType functionType(LType returnType, const LType* paramTypes, unsigned paramCount, Variadicity variadicity)
 {
@@ -110,9 +113,21 @@ static inline LType functionType(LType returnType, LType param1, LType param2, L
     LType paramTypes[] = { param1, param2, param3, param4 };
     return functionType(returnType, paramTypes, 4, variadicity);
 }
+static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, LType param4, LType param5, Variadicity variadicity = NotVariadic)
+{
+    LType paramTypes[] = { param1, param2, param3, param4, param5 };
+    return functionType(returnType, paramTypes, 5, variadicity);
+}
+static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, LType param4, LType param5, LType param6, Variadicity variadicity = NotVariadic)
+{
+    LType paramTypes[] = { param1, param2, param3, param4, param5, param6 };
+    return functionType(returnType, paramTypes, 6, variadicity);
+}
 
 static inline LType typeOf(LValue value) { return llvm->TypeOf(value); }
 
+static inline LType getElementType(LType value) { return llvm->GetElementType(value); }
+
 static inline unsigned mdKindID(LContext context, const char* string) { return llvm->GetMDKindIDInContext(context, string, std::strlen(string)); }
 static inline LValue mdString(LContext context, const char* string, unsigned length) { return llvm->MDStringInContext(context, string, length); }
 static inline LValue mdString(LContext context, const char* string) { return mdString(context, string, std::strlen(string)); }
@@ -134,10 +149,31 @@ static inline LValue mdNode(LContext context, LValue arg1, LValue arg2, LValue a
 
 static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { llvm->SetMetadata(instruction, kind, metadata); }
 
+static inline LValue getFirstInstruction(LBasicBlock block) { return llvm->GetFirstInstruction(block); }
+static inline LValue getNextInstruction(LValue instruction) { return llvm->GetNextInstruction(instruction); }
+
+
 static inline LValue addFunction(LModule module, const char* name, LType type) { return llvm->AddFunction(module, name, type); }
-static inline void setLinkage(LValue global, LLinkage linkage) { llvm->SetLinkage(global, linkage); }
+static inline LValue getNamedFunction(LModule module, const char* name) { return llvm->GetNamedFunction(module, name); }
+static inline LValue getFirstFunction(LModule module) { return llvm->GetFirstFunction(module); }
+static inline LValue getNextFunction(LValue function) { return llvm->GetNextFunction(function); }
+
 static inline void setFunctionCallingConv(LValue function, LCallConv convention) { llvm->SetFunctionCallConv(function, convention); }
 static inline void addTargetDependentFunctionAttr(LValue function, const char* key, const char* value) { llvm->AddTargetDependentFunctionAttr(function, key, value); }
+static inline void removeFunctionAttr(LValue function, LLVMAttribute pa) { llvm->RemoveFunctionAttr(function, pa); }
+
+static inline LLVMLinkage getLinkage(LValue global) { return llvm->GetLinkage(global); }
+static inline void setLinkage(LValue global, LLVMLinkage linkage) { llvm->SetLinkage(global, linkage); }
+static inline void setVisibility(LValue global, LLVMVisibility viz) { llvm->SetVisibility(global, viz); }
+static inline LLVMBool isDeclaration(LValue global) { return llvm->IsDeclaration(global); }
+
+static inline LLVMBool linkModules(LModule dest, LModule str, LLVMLinkerMode mode, char** outMessage) { return llvm->LinkModules(dest, str, mode, outMessage); }
+
+static inline const char * getValueName(LValue global) { return llvm->GetValueName(global); }
+
+static inline LValue getNamedGlobal(LModule module, const char* name) { return llvm->GetNamedGlobal(module, name); }
+static inline LValue getFirstGlobal(LModule module) { return llvm->GetFirstGlobal(module); }
+static inline LValue getNextGlobal(LValue global) { return llvm->GetNextGlobal(global); }
 
 static inline LValue addExternFunction(LModule module, const char* name, LType type)
 {
@@ -146,7 +182,29 @@ static inline LValue addExternFunction(LModule module, const char* name, LType t
     return result;
 }
 
+static inline LLVMBool createMemoryBufferWithContentsOfFile(const char* path, LLVMMemoryBufferRef* outMemBuf, char** outMessage) 
+{ 
+    return llvm->CreateMemoryBufferWithContentsOfFile(path, outMemBuf, outMessage); 
+}
+
+
+static inline LLVMBool parseBitcodeInContext(LLVMContextRef contextRef, LLVMMemoryBufferRef memBuf, LModule *outModule, char **outMessage)
+{ 
+    return llvm->ParseBitcodeInContext(contextRef, memBuf, outModule, outMessage); 
+}
+
+
+static inline void disposeMemoryBuffer(LLVMMemoryBufferRef memBuf){ llvm->DisposeMemoryBuffer(memBuf); }
+
+
+static inline LModule moduleCreateWithNameInContext(const char* moduleID, LContext context){ return llvm->ModuleCreateWithNameInContext(moduleID, context); }
+static inline void disposeModule(LModule m){ llvm->DisposeModule(m); }
+
+static inline void disposeMessage(char* outMsg) { llvm->DisposeMessage(outMsg); }
+
 static inline LValue getParam(LValue function, unsigned index) { return llvm->GetParam(function, index); }
+
+static inline void getParamTypes(LType function, LType* dest) { return llvm->GetParamTypes(function, dest); }
 static inline LValue getUndef(LType type) { return llvm->GetUndef(type); }
 
 enum BitExtension { ZeroExtend, SignExtend };
@@ -156,6 +214,9 @@ static inline LValue constIntToPtr(LValue value, LType type) { return llvm->Cons
 static inline LValue constNull(LType type) { return llvm->ConstNull(type); }
 static inline LValue constBitCast(LValue value, LType type) { return llvm->ConstBitCast(value, type); }
 
+static inline LBasicBlock getFirstBasicBlock(LValue function) { return llvm->GetFirstBasicBlock(function); }
+static inline LBasicBlock getNextBasicBlock(LBasicBlock block) { return llvm->GetNextBasicBlock(block); }
+
 static inline LBasicBlock appendBasicBlock(LContext context, LValue function, const char* name = "") { return llvm->AppendBasicBlockInContext(context, function, name); }
 static inline LBasicBlock insertBasicBlock(LContext context, LBasicBlock beforeBasicBlock, const char* name = "") { return llvm->InsertBasicBlockInContext(context, beforeBasicBlock, name); }
 
@@ -250,41 +311,13 @@ static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1)
 {
     return buildCall(builder, function, &arg1, 1);
 }
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2)
-{
-    LValue args[] = { arg1, arg2 };
-    return buildCall(builder, function, args, 2);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3)
-{
-    LValue args[] = { arg1, arg2, arg3 };
-    return buildCall(builder, function, args, 3);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4)
+template<typename... Args>
+LValue buildCall(LBuilder builder, LValue function, LValue arg1, Args... args)
 {
-    LValue args[] = { arg1, arg2, arg3, arg4 };
-    return buildCall(builder, function, args, 4);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5)
-{
-    LValue args[] = { arg1, arg2, arg3, arg4, arg5 };
-    return buildCall(builder, function, args, 5);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6)
-{
-    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
-    return buildCall(builder, function, args, 6);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7)
-{
-    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
-    return buildCall(builder, function, args, 7);
-}
-static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8)
-{
-    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
-    return buildCall(builder, function, args, 8);
+    LValue argsArray[] = { arg1, args... };
+    return buildCall(builder, function, argsArray, sizeof(argsArray) / sizeof(LValue));
 }
+
 static inline void setInstructionCallingConvention(LValue instruction, LCallConv callingConvention) { llvm->SetInstructionCallConv(instruction, callingConvention); }
 static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return llvm->BuildExtractValue(builder, aggVal, index, ""); }
 static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return llvm->BuildSelect(builder, condition, taken, notTaken, ""); }
index dfbbeb18c93da7e8da710213d4bc50b1edecc573..ce9fa0f04d7d17a282692dfd72c36965e6b592ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,6 +53,20 @@ void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRep
     setMetadata(instruction, repository.m_tbaaKind, tbaaMetadata(repository));
 }
 
+void AbstractHeap::dump(PrintStream& out) const
+{
+    out.print(heapName());
+    if (m_parent)
+        out.print("->", *m_parent);
+}
+
+void AbstractField::dump(PrintStream& out) const
+{
+    out.print(heapName(), "(", m_offset, ")");
+    if (parent())
+        out.print("->", *parent());
+}
+
 IndexedAbstractHeap::IndexedAbstractHeap(LContext context, AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
     : m_heapForAnyIndex(parent, heapName)
     , m_heapNameLength(strlen(heapName))
@@ -102,7 +116,7 @@ const AbstractField& IndexedAbstractHeap::atSlow(ptrdiff_t index)
     ASSERT(static_cast<size_t>(index) >= m_smallIndices.size());
     
     if (UNLIKELY(!m_largeIndices))
-        m_largeIndices = adoptPtr(new MapType());
+        m_largeIndices = std::make_unique<MapType>();
 
     std::unique_ptr<AbstractField>& field = m_largeIndices->add(index, nullptr).iterator->value;
     if (!field) {
@@ -176,6 +190,11 @@ void IndexedAbstractHeap::initialize(AbstractField& field, ptrdiff_t signedIndex
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void IndexedAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Indexed:", atAnyIndex());
+}
+
 NumberedAbstractHeap::NumberedAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
     : m_indexedHeap(context, heap, heapName, 0, 1)
 {
@@ -185,6 +204,11 @@ NumberedAbstractHeap::~NumberedAbstractHeap()
 {
 }
 
+void NumberedAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Numbered: ", atAnyNumber());
+}
+
 AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
     : m_indexedHeap(context, heap, heapName, 0, 1)
 {
@@ -194,6 +218,11 @@ AbsoluteAbstractHeap::~AbsoluteAbstractHeap()
 {
 }
 
+void AbsoluteAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Absolute:", atAnyAddress());
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index c3e29077c890f1be2e2271051f5faaac35be83dd..a19ce38a5328e07518476aaaf96c3404ed2855a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,7 +34,6 @@
 #include <wtf/FastMalloc.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/text/CString.h>
 
@@ -72,6 +71,11 @@ public:
         m_parent = parent;
         m_heapName = heapName;
     }
+    
+    void changeParent(AbstractHeap* parent)
+    {
+        m_parent = parent;
+    }
 
     AbstractHeap* parent() const
     {
@@ -95,6 +99,8 @@ public:
     
     void decorateInstruction(LValue instruction, const AbstractHeapRepository&) const;
 
+    void dump(PrintStream&) const;
+
 private:
     friend class AbstractHeapRepository;
     
@@ -131,6 +137,8 @@ public:
         return m_offset;
     }
     
+    void dump(PrintStream&) const;
+
 private:
     ptrdiff_t m_offset;
 };
@@ -153,6 +161,8 @@ public:
     
     TypedPointer baseIndex(Output& out, LValue base, LValue index, JSValue indexAsConstant = JSValue(), ptrdiff_t offset = 0);
     
+    void dump(PrintStream&) const;
+
 private:
     const AbstractField& returnInitialized(AbstractField& field, ptrdiff_t index)
     {
@@ -178,7 +188,7 @@ private:
     };
     typedef HashMap<ptrdiff_t, std::unique_ptr<AbstractField>, WTF::IntHash<ptrdiff_t>, WithoutZeroOrOneHashTraits> MapType;
     
-    OwnPtr<MapType> m_largeIndices;
+    std::unique_ptr<MapType> m_largeIndices;
     Vector<CString, 16> m_largeIndexNames;
 };
 
@@ -197,6 +207,8 @@ public:
     const AbstractHeap& at(unsigned number) { return m_indexedHeap.at(number); }
     const AbstractHeap& operator[](unsigned number) { return at(number); }
 
+    void dump(PrintStream&) const;
+
 private:
     
     // We use the fact that the indexed heap already has a superset of the
@@ -218,6 +230,8 @@ public:
     
     const AbstractHeap& operator[](void* address) { return at(address); }
 
+    void dump(PrintStream&) const;
+
 private:
     // The trick here is that the indexed heap is "indexed" by a pointer-width
     // integer. Pointers are themselves pointer-width integers. So we can reuse
index 2189cd9471762e73718c4f0e17c1200039b53b6b..e416fdaafee2229f653b9ae06248000999875a00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(FTL_JIT)
 
+#include "DirectArguments.h"
+#include "GetterSetter.h"
+#include "JSEnvironmentRecord.h"
+#include "JSPropertyNameEnumerator.h"
 #include "JSScope.h"
-#include "JSVariableObject.h"
 #include "JSCInlines.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 
 namespace JSC { namespace FTL {
 
@@ -59,6 +64,17 @@ AbstractHeapRepository::AbstractHeapRepository(LContext context)
     , m_context(context)
     , m_tbaaKind(mdKindID(m_context, "tbaa"))
 {
+    // Make sure that our explicit assumptions about the StructureIDBlob match reality.
+    RELEASE_ASSERT(!(JSCell_indexingType.offset() & (sizeof(int32_t) - 1)));
+    RELEASE_ASSERT(JSCell_indexingType.offset() + 1 == JSCell_typeInfoType.offset());
+    RELEASE_ASSERT(JSCell_indexingType.offset() + 2 == JSCell_typeInfoFlags.offset());
+    RELEASE_ASSERT(JSCell_indexingType.offset() + 3 == JSCell_gcData.offset());
+
+    JSCell_indexingType.changeParent(&JSCell_usefulBytes);
+    JSCell_typeInfoType.changeParent(&JSCell_usefulBytes);
+    JSCell_typeInfoFlags.changeParent(&JSCell_usefulBytes);
+    JSCell_gcData.changeParent(&JSCell_usefulBytes);
+    
     root.m_tbaaMetadata = mdNode(m_context, mdString(m_context, root.m_heapName));
     
     RELEASE_ASSERT(m_tbaaKind);
index d59ad6ae52ef87cd69ea19cf7a9954e40aef97ab..912754dfc40152b0ed24836ac75b8f96984399bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 namespace JSC { namespace FTL {
 
 #define FOR_EACH_ABSTRACT_HEAP(macro) \
-    macro(length) \
-    macro(structureTable) \
-    macro(typedArrayProperties) \
-    macro(WriteBarrierBuffer_bufferContents)
+    macro(typedArrayProperties)
 
 #define FOR_EACH_ABSTRACT_FIELD(macro) \
     macro(ArrayBuffer_data, ArrayBuffer::offsetOfData()) \
@@ -46,25 +43,45 @@ namespace JSC { namespace FTL {
     macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength()) \
     macro(Butterfly_vectorLength, Butterfly::offsetOfVectorLength()) \
     macro(CallFrame_callerFrame, CallFrame::callerFrameOffset()) \
+    macro(DirectArguments_callee, DirectArguments::offsetOfCallee()) \
+    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
+    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
+    macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
+    macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
+    macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
     macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
     macro(JSArrayBufferView_mode, JSArrayBufferView::offsetOfMode()) \
     macro(JSArrayBufferView_vector, JSArrayBufferView::offsetOfVector()) \
     macro(JSCell_structureID, JSCell::structureIDOffset()) \
+    macro(JSCell_usefulBytes, JSCell::indexingTypeOffset()) \
     macro(JSCell_typeInfoFlags, JSCell::typeInfoFlagsOffset()) \
     macro(JSCell_typeInfoType, JSCell::typeInfoTypeOffset()) \
     macro(JSCell_indexingType, JSCell::indexingTypeOffset()) \
     macro(JSCell_gcData, JSCell::gcDataOffset()) \
     macro(JSFunction_executable, JSFunction::offsetOfExecutable()) \
     macro(JSFunction_scope, JSFunction::offsetOfScopeChain()) \
+    macro(JSFunction_rareData, JSFunction::offsetOfRareData()) \
     macro(JSObject_butterfly, JSObject::butterflyOffset()) \
+    macro(JSPropertyNameEnumerator_cachedInlineCapacity, JSPropertyNameEnumerator::cachedInlineCapacityOffset()) \
+    macro(JSPropertyNameEnumerator_cachedPropertyNamesVector, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()) \
+    macro(JSPropertyNameEnumerator_cachedStructureID, JSPropertyNameEnumerator::cachedStructureIDOffset()) \
+    macro(JSPropertyNameEnumerator_endGenericPropertyIndex, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()) \
+    macro(JSPropertyNameEnumerator_endStructurePropertyIndex, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()) \
+    macro(JSPropertyNameEnumerator_indexLength, JSPropertyNameEnumerator::indexedLengthOffset()) \
     macro(JSScope_next, JSScope::offsetOfNext()) \
     macro(JSString_flags, JSString::offsetOfFlags()) \
     macro(JSString_length, JSString::offsetOfLength()) \
     macro(JSString_value, JSString::offsetOfValue()) \
-    macro(JSVariableObject_registers, JSVariableObject::offsetOfRegisters()) \
+    macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
     macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
     macro(MarkedAllocator_freeListHead, MarkedAllocator::offsetOfFreeListHead()) \
     macro(MarkedBlock_markBits, MarkedBlock::offsetOfMarks()) \
+    macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
+    macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
+    macro(ScopedArguments_table, ScopedArguments::offsetOfTable()) \
+    macro(ScopedArguments_totalLength, ScopedArguments::offsetOfTotalLength()) \
+    macro(ScopedArgumentsTable_arguments, ScopedArgumentsTable::offsetOfArguments()) \
+    macro(ScopedArgumentsTable_length, ScopedArgumentsTable::offsetOfLength()) \
     macro(StringImpl_data, StringImpl::dataOffset()) \
     macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
     macro(Structure_classInfo, Structure::classInfoOffset()) \
@@ -73,14 +90,23 @@ namespace JSC { namespace FTL {
     macro(Structure_structureID, Structure::structureIDOffset())
 
 #define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
+    macro(DirectArguments_storage, DirectArguments::storageOffset(), sizeof(EncodedJSValue)) \
+    macro(JSEnvironmentRecord_variables, JSEnvironmentRecord::offsetOfVariables(), sizeof(EncodedJSValue)) \
+    macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier<JSString>)) \
     macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \
+    macro(MarkedSpace_Subspace_impreciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, impreciseAllocators), sizeof(MarkedAllocator)) \
+    macro(MarkedSpace_Subspace_preciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, preciseAllocators), sizeof(MarkedAllocator)) \
+    macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \
+    macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \
     macro(characters8, 0, sizeof(LChar)) \
     macro(characters16, 0, sizeof(UChar)) \
     macro(indexedInt32Properties, 0, sizeof(EncodedJSValue)) \
     macro(indexedDoubleProperties, 0, sizeof(double)) \
     macro(indexedContiguousProperties, 0, sizeof(EncodedJSValue)) \
     macro(indexedArrayStorageProperties, 0, sizeof(EncodedJSValue)) \
+    macro(scopedArgumentsTableArguments, 0, sizeof(int32_t)) \
     macro(singleCharacterStrings, 0, sizeof(JSString*)) \
+    macro(structureTable, 0, sizeof(Structure*)) \
     macro(variables, 0, sizeof(Register))
     
 #define FOR_EACH_NUMBERED_ABSTRACT_HEAP(macro) \
index 3c0254770ccac5b9e1254924e5d6082b36788eb0..1fe7987f83d6efa7c2723598d65c39312970fffa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,14 +44,14 @@ inline CapabilityLevel canCompile(Node* node)
     
     switch (node->op()) {
     case JSConstant:
-    case WeakJSConstant:
-    case GetMyArgumentsLength:
     case GetLocal:
     case SetLocal:
+    case PutStack:
+    case KillStack:
+    case GetStack:
     case MovHint:
     case ZombieHint:
     case Phantom:
-    case HardPhantom:
     case Flush:
     case PhantomLocal:
     case SetArgument:
@@ -63,20 +63,23 @@ inline CapabilityLevel canCompile(Node* node)
     case BitLShift:
     case BitURShift:
     case CheckStructure:
-    case StructureTransitionWatchpoint:
+    case DoubleAsInt32:
     case ArrayifyToStructure:
     case PutStructure:
-    case PhantomPutStructure:
     case GetButterfly:
     case NewObject:
     case NewArray:
     case NewArrayBuffer:
     case GetByOffset:
+    case GetGetterSetterByOffset:
+    case GetGetter:
+    case GetSetter:
     case PutByOffset:
     case GetGlobalVar:
     case PutGlobalVar:
     case ValueAdd:
     case ArithAdd:
+    case ArithClz32:
     case ArithSub:
     case ArithMul:
     case ArithDiv:
@@ -86,7 +89,10 @@ inline CapabilityLevel canCompile(Node* node)
     case ArithAbs:
     case ArithSin:
     case ArithCos:
+    case ArithPow:
+    case ArithRound:
     case ArithSqrt:
+    case ArithLog:
     case ArithFRound:
     case ArithNegate:
     case UInt32ToNumber:
@@ -97,26 +103,36 @@ inline CapabilityLevel canCompile(Node* node)
     case Upsilon:
     case ExtractOSREntryLocal:
     case LoopHint:
-    case GetMyScope:
     case SkipScope:
-    case GetClosureRegisters:
+    case CreateActivation:
+    case NewFunction:
     case GetClosureVar:
     case PutClosureVar:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+    case GetFromArguments:
+    case PutToArguments:
     case InvalidationPoint:
     case StringCharAt:
-    case CheckFunction:
+    case CheckCell:
+    case CheckBadCell:
+    case CheckNotEmpty:
     case StringCharCodeAt:
     case AllocatePropertyStorage:
     case ReallocatePropertyStorage:
-    case FunctionReentryWatchpoint:
-    case TypedArrayWatchpoint:
     case GetTypedArrayByteOffset:
-    case VariableWatchpoint:
     case NotifyWrite:
     case StoreBarrier:
-    case StoreBarrierWithNullCheck:
     case Call:
     case Construct:
+    case CallVarargs:
+    case CallForwardVarargs:
+    case ConstructVarargs:
+    case ConstructForwardVarargs:
+    case LoadVarargs:
+    case NativeCall:
+    case NativeConstruct:
     case ValueToInt32:
     case Branch:
     case LogicalNot:
@@ -124,12 +140,12 @@ inline CapabilityLevel canCompile(Node* node)
     case ConstantStoragePointer:
     case Check:
     case CountExecution:
-    case CheckExecutable:
+    case GetExecutable:
     case GetScope:
-    case AllocationProfileWatchpoint:
-    case CheckArgumentsNotCreated:
     case GetCallee:
+    case GetArgumentCount:
     case ToString:
+    case CallStringConstructor:
     case MakeRope:
     case NewArrayWithSize:
     case GetById:
@@ -137,16 +153,15 @@ inline CapabilityLevel canCompile(Node* node)
     case MultiGetByOffset:
     case MultiPutByOffset:
     case ToPrimitive:
-    case PhantomArguments:
     case Throw:
     case ThrowReferenceError:
     case Unreachable:
-    case GetMyArgumentByVal:
     case IsUndefined:
     case IsBoolean:
     case IsNumber:
     case IsString:
     case IsObject:
+    case IsObjectOrNull:
     case IsFunction:
     case CheckHasInstance:
     case InstanceOf:
@@ -156,6 +171,28 @@ inline CapabilityLevel canCompile(Node* node)
     case DoubleConstant:
     case Int52Constant:
     case BooleanToNumber:
+    case HasGenericProperty:
+    case HasStructureProperty:
+    case GetDirectPname:
+    case GetEnumerableLength:
+    case GetPropertyEnumerator:
+    case GetEnumeratorStructurePname:
+    case GetEnumeratorGenericPname:
+    case ToIndexString:
+    case BottomValue:
+    case PhantomNewObject:
+    case PhantomNewFunction:
+    case PhantomCreateActivation:
+    case PutHint:
+    case CheckStructureImmediate:
+    case MaterializeNewObject:
+    case MaterializeCreateActivation:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
+    case Switch:
+    case TypeOf:
         // These are OK.
         break;
     case Identity:
@@ -164,6 +201,10 @@ inline CapabilityLevel canCompile(Node* node)
         // case because it would prevent us from catching bugs where the FTL backend
         // pipeline failed to optimize out an Identity.
         break;
+    case In:
+        if (node->child2().useKind() == CellUse)
+            break;
+        return CannotCompile;
     case PutByIdDirect:
     case PutById:
         if (node->child1().useKind() == CellUse)
@@ -180,6 +221,8 @@ inline CapabilityLevel canCompile(Node* node)
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -193,6 +236,8 @@ inline CapabilityLevel canCompile(Node* node)
         case Array::Double:
         case Array::Contiguous:
         case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -200,6 +245,17 @@ inline CapabilityLevel canCompile(Node* node)
             return CannotCompile;
         }
         break;
+    case HasIndexedProperty:
+        switch (node->arrayMode().type()) {
+        case Array::ForceExit:
+        case Array::Int32:
+        case Array::Double:
+        case Array::Contiguous:
+            break;
+        default:
+            return CannotCompile;
+        }
+        break;
     case GetByVal:
         switch (node->arrayMode().type()) {
         case Array::ForceExit:
@@ -208,6 +264,8 @@ inline CapabilityLevel canCompile(Node* node)
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -271,6 +329,10 @@ inline CapabilityLevel canCompile(Node* node)
             break;
         if (node->isBinaryUseKind(StringIdentUse))
             break;
+        if (node->isBinaryUseKind(ObjectUse, UntypedUse))
+            break;
+        if (node->isBinaryUseKind(UntypedUse, ObjectUse))
+            break;
         if (node->isBinaryUseKind(ObjectUse))
             break;
         if (node->isBinaryUseKind(BooleanUse))
@@ -297,15 +359,6 @@ inline CapabilityLevel canCompile(Node* node)
         if (node->isBinaryUseKind(UntypedUse))
             break;
         return CannotCompile;
-    case Switch:
-        switch (node->switchData()->kind) {
-        case SwitchImm:
-        case SwitchChar:
-            break;
-        default:
-            return CannotCompile;
-        }
-        break;
     default:
         // Don't know how to handle anything else.
         return CannotCompile;
@@ -327,17 +380,6 @@ CapabilityLevel canCompile(Graph& graph)
         return CannotCompile;
     }
     
-    if (graph.m_codeBlock->needsActivation()) {
-        // Need this because although we also don't support
-        // CreateActivation/TearOffActivation, we might not see those nodes in case of
-        // OSR entry.
-        // FIXME: Support activations.
-        // https://bugs.webkit.org/show_bug.cgi?id=129576
-        if (verboseCapabilities())
-            dataLog("FTL rejecting ", *graph.m_codeBlock, " because it uses activations.\n");
-        return CannotCompile;
-    }
-    
     CapabilityLevel result = CanCompileAndOSREnter;
     
     for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
@@ -362,12 +404,14 @@ CapabilityLevel canCompile(Graph& graph)
                 case KnownInt32Use:
                 case Int52RepUse:
                 case NumberUse:
+                case RealNumberUse:
                 case DoubleRepUse:
                 case DoubleRepRealUse:
                 case BooleanUse:
                 case CellUse:
                 case KnownCellUse:
                 case ObjectUse:
+                case FunctionUse:
                 case ObjectOrOtherUse:
                 case StringUse:
                 case KnownStringUse:
index feab9bd128446c58afd4a3278aa71750bd1bff73..c6fcca05ef93756a8d9e4abc2b7bbb2f39e8b57a 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics
+ * Copyright (C) 2014 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,13 +59,23 @@ static uint8_t* mmAllocateCodeSection(
     
     RefPtr<ExecutableMemoryHandle> result =
         state.graph.m_vm.executableAllocator.allocate(
-            state.graph.m_vm, size, state.graph.m_codeBlock, JITCompilationMustSucceed);
+            state.graph.m_vm, size, state.graph.m_codeBlock, JITCompilationCanFail);
+    
+    if (!result) {
+        // Signal failure. This compilation will get tossed.
+        state.allocationFailed = true;
+        
+        // Fake an allocation, since LLVM cannot handle failures in the memory manager.
+        RefPtr<DataSection> fakeSection = adoptRef(new DataSection(size, jitAllocationGranule));
+        state.jitCode->addDataSection(fakeSection);
+        return bitwise_cast<uint8_t*>(fakeSection->base());
+    }
     
     // LLVM used to put __compact_unwind in a code section. We keep this here defensively,
     // for clients that use older LLVMs.
-    if (!strcmp(sectionName, "__compact_unwind")) {
-        state.compactUnwind = result->start();
-        state.compactUnwindSize = result->sizeInBytes();
+    if (!strcmp(sectionName, SECTION_NAME("compact_unwind"))) {
+        state.unwindDataSection = result->start();
+        state.unwindDataSectionSize = result->sizeInBytes();
     }
     
     state.jitCode->addHandle(result);
@@ -80,21 +92,27 @@ static uint8_t* mmAllocateDataSection(
     UNUSED_PARAM(isReadOnly);
 
     // Allocate the GOT in the code section to make it reachable for all code.
-    if (!strcmp(sectionName, "__got"))
+    if (!strcmp(sectionName, SECTION_NAME("got")))
         return mmAllocateCodeSection(opaqueState, size, alignment, sectionID, sectionName);
 
     State& state = *static_cast<State*>(opaqueState);
 
     RefPtr<DataSection> section = adoptRef(new DataSection(size, alignment));
 
-    if (!strcmp(sectionName, "__llvm_stackmaps"))
+    if (!strcmp(sectionName, SECTION_NAME("llvm_stackmaps")))
         state.stackmapsSection = section;
     else {
         state.jitCode->addDataSection(section);
         state.dataSectionNames.append(sectionName);
-        if (!strcmp(sectionName, "__compact_unwind")) {
-            state.compactUnwind = section->base();
-            state.compactUnwindSize = size;
+#if OS(DARWIN)
+        if (!strcmp(sectionName, SECTION_NAME("compact_unwind"))) {
+#elif OS(LINUX)
+        if (!strcmp(sectionName, SECTION_NAME("eh_frame"))) {
+#else
+#error "Unrecognized OS"
+#endif
+            state.unwindDataSection = section->base();
+            state.unwindDataSectionSize = size;
         }
     }
 
@@ -120,6 +138,66 @@ static void dumpDataSection(DataSection* section, const char* prefix)
     }
 }
 
+static int offsetOfStackRegion(StackMaps::RecordMap& recordMap, uint32_t stackmapID)
+{
+    if (stackmapID == UINT_MAX)
+        return 0;
+    
+    StackMaps::RecordMap::iterator iter = recordMap.find(stackmapID);
+    RELEASE_ASSERT(iter != recordMap.end());
+    RELEASE_ASSERT(iter->value.size() == 1);
+    RELEASE_ASSERT(iter->value[0].locations.size() == 1);
+    Location capturedLocation =
+        Location::forStackmaps(nullptr, iter->value[0].locations[0]);
+    RELEASE_ASSERT(capturedLocation.kind() == Location::Register);
+    RELEASE_ASSERT(capturedLocation.gpr() == GPRInfo::callFrameRegister);
+    RELEASE_ASSERT(!(capturedLocation.addend() % sizeof(Register)));
+    return capturedLocation.addend() / sizeof(Register);
+}
+
+static void generateInlineIfPossibleOutOfLineIfNot(State& state, VM& vm, CodeBlock* codeBlock, CCallHelpers& code, char* startOfInlineCode, size_t sizeOfInlineCode, const char* codeDescription, const std::function<void(LinkBuffer&, CCallHelpers&, bool wasCompiledInline)>& callback)
+{
+    std::unique_ptr<LinkBuffer> codeLinkBuffer;
+    size_t actualCodeSize = code.m_assembler.buffer().codeSize();
+
+    if (actualCodeSize <= sizeOfInlineCode) {
+        LinkBuffer codeLinkBuffer(vm, code, startOfInlineCode, sizeOfInlineCode);
+
+        // Fill the remainder of the inline space with nops to avoid confusing the disassembler.
+        MacroAssembler::AssemblerType_T::fillNops(bitwise_cast<char*>(startOfInlineCode) + actualCodeSize, sizeOfInlineCode - actualCodeSize);
+
+        callback(codeLinkBuffer, code, true);
+
+        return;
+    }
+
+    // If there isn't enough space in the provided inline code area, allocate out of line
+    // executable memory to link the provided code. Place a jump at the beginning of the
+    // inline area and jump to the out of line code. Similarly return by appending a jump
+    // to the provided code that goes to the instruction after the inline code.
+    // Fill the middle with nop's.
+    MacroAssembler::Jump returnToMainline = code.jump();
+
+    // Allocate out of line executable memory and link the provided code there.
+    codeLinkBuffer = std::make_unique<LinkBuffer>(vm, code, codeBlock, JITCompilationMustSucceed);
+
+    // Plant a jmp in the inline buffer to the out of line code.
+    MacroAssembler callToOutOfLineCode;
+    MacroAssembler::Jump jumpToOutOfLine = callToOutOfLineCode.jump();
+    LinkBuffer inlineBuffer(vm, callToOutOfLineCode, startOfInlineCode, sizeOfInlineCode);
+    inlineBuffer.link(jumpToOutOfLine, codeLinkBuffer->entrypoint());
+
+    // Fill the remainder of the inline space with nops to avoid confusing the disassembler.
+    MacroAssembler::AssemblerType_T::fillNops(bitwise_cast<char*>(startOfInlineCode) + inlineBuffer.size(), sizeOfInlineCode - inlineBuffer.size());
+
+    // Link the end of the out of line code to right after the inline area.
+    codeLinkBuffer->link(returnToMainline, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(startOfInlineCode)).labelAtOffset(sizeOfInlineCode));
+
+    callback(*codeLinkBuffer.get(), code, false);
+
+    state.finalizer->outOfLineCodeInfos.append(OutOfLineCodeInfo(WTF::move(codeLinkBuffer), codeDescription));
+}
+
 template<typename DescriptorType>
 void generateICFastPath(
     State& state, CodeBlock* codeBlock, GeneratedFunction generatedFunction,
@@ -146,26 +224,77 @@ void generateICFastPath(
         
         char* startOfIC =
             bitwise_cast<char*>(generatedFunction) + record.instructionOffset;
+
+        generateInlineIfPossibleOutOfLineIfNot(state, vm, codeBlock, fastPathJIT, startOfIC, sizeOfIC, "inline cache fast path", [&] (LinkBuffer& linkBuffer, CCallHelpers&, bool) {
+            state.finalizer->sideCodeLinkBuffer->link(ic.m_slowPathDone[i],
+                CodeLocationLabel(startOfIC + sizeOfIC));
+
+            linkBuffer.link(generator.slowPathJump(),
+                state.finalizer->sideCodeLinkBuffer->locationOf(generator.slowPathBegin()));
+
+            generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer);
+        });
+    }
+}
+
+static void generateCheckInICFastPath(
+    State& state, CodeBlock* codeBlock, GeneratedFunction generatedFunction,
+    StackMaps::RecordMap& recordMap, CheckInDescriptor& ic, size_t sizeOfIC)
+{
+    VM& vm = state.graph.m_vm;
+
+    StackMaps::RecordMap::iterator iter = recordMap.find(ic.stackmapID());
+    if (iter == recordMap.end()) {
+        // It was optimized out.
+        return;
+    }
+    
+    Vector<StackMaps::Record>& records = iter->value;
+    
+    RELEASE_ASSERT(records.size() == ic.m_generators.size());
+
+    for (unsigned i = records.size(); i--;) {
+        StackMaps::Record& record = records[i];
+        auto generator = ic.m_generators[i];
+
+        StructureStubInfo& stubInfo = *generator.m_stub;
+        auto call = generator.m_slowCall;
+        auto slowPathBegin = generator.m_beginLabel;
+
+        CCallHelpers fastPathJIT(&vm, codeBlock);
         
-        LinkBuffer linkBuffer(vm, fastPathJIT, startOfIC, sizeOfIC);
-        // Note: we could handle the !isValid() case. We just don't appear to have a
-        // reason to do so, yet.
-        RELEASE_ASSERT(linkBuffer.isValid());
-        
-        MacroAssembler::AssemblerType_T::fillNops(
-            startOfIC + linkBuffer.size(), sizeOfIC - linkBuffer.size());
-        
-        state.finalizer->sideCodeLinkBuffer->link(
-            ic.m_slowPathDone[i], CodeLocationLabel(startOfIC + sizeOfIC));
-        
-        linkBuffer.link(
-            generator.slowPathJump(),
-            state.finalizer->sideCodeLinkBuffer->locationOf(generator.slowPathBegin()));
-        
-        generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer);
+        auto jump = fastPathJIT.patchableJump();
+        auto done = fastPathJIT.label();
+
+        char* startOfIC =
+            bitwise_cast<char*>(generatedFunction) + record.instructionOffset;
+
+        auto postLink = [&] (LinkBuffer& fastPath, CCallHelpers&, bool) {
+            LinkBuffer& slowPath = *state.finalizer->sideCodeLinkBuffer;
+
+            state.finalizer->sideCodeLinkBuffer->link(
+                ic.m_slowPathDone[i], CodeLocationLabel(startOfIC + sizeOfIC));
+
+            CodeLocationLabel slowPathBeginLoc = slowPath.locationOf(slowPathBegin);
+            fastPath.link(jump, slowPathBeginLoc);
+
+            CodeLocationCall callReturnLocation = slowPath.locationOf(call);
+
+            stubInfo.patch.deltaCallToDone = MacroAssembler::differenceBetweenCodePtr(
+                callReturnLocation, fastPath.locationOf(done));
+
+            stubInfo.patch.deltaCallToJump = MacroAssembler::differenceBetweenCodePtr(
+                callReturnLocation, fastPath.locationOf(jump));
+            stubInfo.callReturnLocation = callReturnLocation;
+            stubInfo.patch.deltaCallToSlowCase = MacroAssembler::differenceBetweenCodePtr(
+                callReturnLocation, slowPathBeginLoc);
+        };
+
+        generateInlineIfPossibleOutOfLineIfNot(state, vm, codeBlock, fastPathJIT, startOfIC, sizeOfIC, "CheckIn inline cache", postLink);
     }
 }
 
+
 static RegisterSet usedRegistersFor(const StackMaps::Record& record)
 {
     if (Options::assumeAllRegsInFTLICAreLive())
@@ -173,6 +302,32 @@ static RegisterSet usedRegistersFor(const StackMaps::Record& record)
     return RegisterSet(record.usedRegisterSet(), RegisterSet::calleeSaveRegisters());
 }
 
+template<typename CallType>
+void adjustCallICsForStackmaps(Vector<CallType>& calls, StackMaps::RecordMap& recordMap)
+{
+    // Handling JS calls is weird: we need to ensure that we sort them by the PC in LLVM
+    // generated code. That implies first pruning the ones that LLVM didn't generate.
+
+    Vector<CallType> oldCalls;
+    oldCalls.swap(calls);
+    
+    for (unsigned i = 0; i < oldCalls.size(); ++i) {
+        CallType& call = oldCalls[i];
+        
+        StackMaps::RecordMap::iterator iter = recordMap.find(call.stackmapID());
+        if (iter == recordMap.end())
+            continue;
+        
+        for (unsigned j = 0; j < iter->value.size(); ++j) {
+            CallType copy = call;
+            copy.m_instructionOffset = iter->value[j].instructionOffset;
+            calls.append(copy);
+        }
+    }
+
+    std::sort(calls.begin(), calls.end());
+}
+
 static void fixFunctionBasedOnStackMaps(
     State& state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction,
     StackMaps::RecordMap& recordMap, bool didSeeUnwindInfo)
@@ -181,24 +336,14 @@ static void fixFunctionBasedOnStackMaps(
     VM& vm = graph.m_vm;
     StackMaps stackmaps = jitCode->stackmaps;
     
-    StackMaps::RecordMap::iterator iter = recordMap.find(state.capturedStackmapID);
-    RELEASE_ASSERT(iter != recordMap.end());
-    RELEASE_ASSERT(iter->value.size() == 1);
-    RELEASE_ASSERT(iter->value[0].locations.size() == 1);
-    Location capturedLocation =
-        Location::forStackmaps(&jitCode->stackmaps, iter->value[0].locations[0]);
-    RELEASE_ASSERT(capturedLocation.kind() == Location::Register);
-    RELEASE_ASSERT(capturedLocation.gpr() == GPRInfo::callFrameRegister);
-    RELEASE_ASSERT(!(capturedLocation.addend() % sizeof(Register)));
-    int32_t localsOffset = capturedLocation.addend() / sizeof(Register) + graph.m_nextMachineLocal;
+    int localsOffset = offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal;
+    int varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID);
     
     for (unsigned i = graph.m_inlineVariableData.size(); i--;) {
         InlineCallFrame* inlineCallFrame = graph.m_inlineVariableData[i].inlineCallFrame;
         
-        if (inlineCallFrame->argumentsRegister.isValid()) {
-            inlineCallFrame->argumentsRegister = VirtualRegister(
-                inlineCallFrame->argumentsRegister.offset() + localsOffset);
-        }
+        if (inlineCallFrame->argumentCountRegister.isValid())
+            inlineCallFrame->argumentCountRegister += localsOffset;
         
         for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
             inlineCallFrame->arguments[argument] =
@@ -209,13 +354,11 @@ static void fixFunctionBasedOnStackMaps(
             inlineCallFrame->calleeRecovery =
                 inlineCallFrame->calleeRecovery.withLocalsOffset(localsOffset);
         }
+
+        if (graph.hasDebuggerEnabled())
+            codeBlock->setScopeRegister(codeBlock->scopeRegister() + localsOffset);
     }
     
-    if (codeBlock->usesArguments()) {
-        codeBlock->setArgumentsRegister(
-            VirtualRegister(codeBlock->argumentsRegister().offset() + localsOffset));
-    }
-
     MacroAssembler::Label stackOverflowException;
 
     {
@@ -223,25 +366,27 @@ static void fixFunctionBasedOnStackMaps(
         
         // At this point it's perfectly fair to just blow away all state and restore the
         // JS JIT view of the universe.
+        checkJIT.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0);
         checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+        MacroAssembler::Call callLookupExceptionHandler = checkJIT.call();
+        checkJIT.jumpToExceptionHandler();
 
-        MacroAssembler::Label exceptionContinueArg1Set = checkJIT.label();
-        checkJIT.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
-        checkJIT.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);
-
+        stackOverflowException = checkJIT.label();
         checkJIT.move(MacroAssembler::TrustedImmPtr(&vm), GPRInfo::argumentGPR0);
-        MacroAssembler::Call call = checkJIT.call();
+        checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+        MacroAssembler::Call callLookupExceptionHandlerFromCallerFrame = checkJIT.call();
         checkJIT.jumpToExceptionHandler();
 
-        stackOverflowException = checkJIT.label();
-        checkJIT.emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        checkJIT.jump(exceptionContinueArg1Set);
+        auto linkBuffer = std::make_unique<LinkBuffer>(
+            vm, checkJIT, codeBlock, JITCompilationCanFail);
+        if (linkBuffer->didFailToAllocate()) {
+            state.allocationFailed = true;
+            return;
+        }
+        linkBuffer->link(callLookupExceptionHandler, FunctionPtr(lookupExceptionHandler));
+        linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, FunctionPtr(lookupExceptionHandlerFromCallerFrame));
 
-        OwnPtr<LinkBuffer> linkBuffer = adoptPtr(new LinkBuffer(
-            vm, checkJIT, codeBlock, JITCompilationMustSucceed));
-        linkBuffer->link(call, FunctionPtr(lookupExceptionHandler));
-        
-        state.finalizer->handleExceptionsLinkBuffer = linkBuffer.release();
+        state.finalizer->handleExceptionsLinkBuffer = WTF::move(linkBuffer);
     }
 
     ExitThunkGenerator exitThunkGenerator(state);
@@ -250,8 +395,12 @@ static void fixFunctionBasedOnStackMaps(
         RELEASE_ASSERT(state.finalizer->osrExit.size());
         RELEASE_ASSERT(didSeeUnwindInfo);
         
-        OwnPtr<LinkBuffer> linkBuffer = adoptPtr(new LinkBuffer(
-            vm, exitThunkGenerator, codeBlock, JITCompilationMustSucceed));
+        auto linkBuffer = std::make_unique<LinkBuffer>(
+            vm, exitThunkGenerator, codeBlock, JITCompilationCanFail);
+        if (linkBuffer->didFailToAllocate()) {
+            state.allocationFailed = true;
+            return;
+        }
         
         RELEASE_ASSERT(state.finalizer->osrExit.size() == state.jitCode->osrExit.size());
         
@@ -262,7 +411,7 @@ static void fixFunctionBasedOnStackMaps(
             if (verboseCompilationEnabled())
                 dataLog("Handling OSR stackmap #", exit.m_stackmapID, " for ", exit.m_codeOrigin, "\n");
 
-            iter = recordMap.find(exit.m_stackmapID);
+            auto iter = recordMap.find(exit.m_stackmapID);
             if (iter == recordMap.end()) {
                 // It was optimized out.
                 continue;
@@ -271,26 +420,26 @@ static void fixFunctionBasedOnStackMaps(
             info.m_thunkAddress = linkBuffer->locationOf(info.m_thunkLabel);
             exit.m_patchableCodeOffset = linkBuffer->offsetOf(info.m_thunkJump);
             
-            for (unsigned j = exit.m_values.size(); j--;) {
-                ExitValue value = exit.m_values[j];
-                if (!value.isInJSStackSomehow())
-                    continue;
-                if (!value.virtualRegister().isLocal())
-                    continue;
-                exit.m_values[j] = value.withVirtualRegister(
-                    VirtualRegister(value.virtualRegister().offset() + localsOffset));
-            }
+            for (unsigned j = exit.m_values.size(); j--;)
+                exit.m_values[j] = exit.m_values[j].withLocalsOffset(localsOffset);
+            for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+                materialization->accountForLocalsOffset(localsOffset);
             
             if (verboseCompilationEnabled()) {
                 DumpContext context;
                 dataLog("    Exit values: ", inContext(exit.m_values, &context), "\n");
+                if (!exit.m_materializations.isEmpty()) {
+                    dataLog("    Materializations: \n");
+                    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+                        dataLog("        Materialize(", pointerDump(materialization), ")\n");
+                }
             }
         }
         
-        state.finalizer->exitThunksLinkBuffer = linkBuffer.release();
+        state.finalizer->exitThunksLinkBuffer = WTF::move(linkBuffer);
     }
 
-    if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty()) {
+    if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty() || !state.checkIns.isEmpty()) {
         CCallHelpers slowPathJIT(&vm, codeBlock);
         
         CCallHelpers::JumpList exceptionTarget;
@@ -301,7 +450,7 @@ static void fixFunctionBasedOnStackMaps(
             if (verboseCompilationEnabled())
                 dataLog("Handling GetById stackmap #", getById.stackmapID(), "\n");
             
-            iter = recordMap.find(getById.stackmapID());
+            auto iter = recordMap.find(getById.stackmapID());
             if (iter == recordMap.end()) {
                 // It was optimized out.
                 continue;
@@ -320,13 +469,13 @@ static void fixFunctionBasedOnStackMaps(
                     JSValueRegs(result), NeedToSpill);
                 
                 MacroAssembler::Label begin = slowPathJIT.label();
-                
+
                 MacroAssembler::Call call = callOperation(
                     state, usedRegisters, slowPathJIT, getById.codeOrigin(), &exceptionTarget,
                     operationGetByIdOptimize, result, gen.stubInfo(), base, getById.uid());
-                
+
                 gen.reportSlowPathCall(begin, call);
-                
+
                 getById.m_slowPathDone.append(slowPathJIT.jump());
                 getById.m_generators.append(gen);
             }
@@ -338,7 +487,7 @@ static void fixFunctionBasedOnStackMaps(
             if (verboseCompilationEnabled())
                 dataLog("Handling PutById stackmap #", putById.stackmapID(), "\n");
             
-            iter = recordMap.find(putById.stackmapID());
+            auto iter = recordMap.find(putById.stackmapID());
             if (iter == recordMap.end()) {
                 // It was optimized out.
                 continue;
@@ -369,12 +518,51 @@ static void fixFunctionBasedOnStackMaps(
                 putById.m_generators.append(gen);
             }
         }
+
+        for (unsigned i = state.checkIns.size(); i--;) {
+            CheckInDescriptor& checkIn = state.checkIns[i];
+            
+            if (verboseCompilationEnabled())
+                dataLog("Handling checkIn stackmap #", checkIn.stackmapID(), "\n");
+            
+            auto iter = recordMap.find(checkIn.stackmapID());
+            if (iter == recordMap.end()) {
+                // It was optimized out.
+                continue;
+            }
+            
+            for (unsigned i = 0; i < iter->value.size(); ++i) {
+                StackMaps::Record& record = iter->value[i];
+                RegisterSet usedRegisters = usedRegistersFor(record);
+                GPRReg result = record.locations[0].directGPR();
+                GPRReg obj = record.locations[1].directGPR();
+                StructureStubInfo* stubInfo = codeBlock->addStubInfo(); 
+                stubInfo->codeOrigin = checkIn.codeOrigin();
+                stubInfo->patch.baseGPR = static_cast<int8_t>(obj);
+                stubInfo->patch.valueGPR = static_cast<int8_t>(result);
+                stubInfo->patch.usedRegisters = usedRegisters;
+                stubInfo->patch.spillMode = NeedToSpill;
+
+                MacroAssembler::Label begin = slowPathJIT.label();
+
+                MacroAssembler::Call slowCall = callOperation(
+                    state, usedRegisters, slowPathJIT, checkIn.codeOrigin(), &exceptionTarget,
+                    operationInOptimize, result, stubInfo, obj, checkIn.m_uid);
+
+                checkIn.m_slowPathDone.append(slowPathJIT.jump());
+                
+                checkIn.m_generators.append(CheckInGenerator(stubInfo, slowCall, begin));
+            }
+        }
         
         exceptionTarget.link(&slowPathJIT);
         MacroAssembler::Jump exceptionJump = slowPathJIT.jump();
         
-        state.finalizer->sideCodeLinkBuffer = adoptPtr(
-            new LinkBuffer(vm, slowPathJIT, codeBlock, JITCompilationMustSucceed));
+        state.finalizer->sideCodeLinkBuffer = std::make_unique<LinkBuffer>(vm, slowPathJIT, codeBlock, JITCompilationCanFail);
+        if (state.finalizer->sideCodeLinkBuffer->didFailToAllocate()) {
+            state.allocationFailed = true;
+            return;
+        }
         state.finalizer->sideCodeLinkBuffer->link(
             exceptionJump, state.finalizer->handleExceptionsLinkBuffer->entrypoint());
         
@@ -388,51 +576,48 @@ static void fixFunctionBasedOnStackMaps(
                 state, codeBlock, generatedFunction, recordMap, state.putByIds[i],
                 sizeOfPutById());
         }
-    }
-    
-    // Handling JS calls is weird: we need to ensure that we sort them by the PC in LLVM
-    // generated code. That implies first pruning the ones that LLVM didn't generate.
-    Vector<JSCall> oldCalls = state.jsCalls;
-    state.jsCalls.resize(0);
-    for (unsigned i = 0; i < oldCalls.size(); ++i) {
-        JSCall& call = oldCalls[i];
-        
-        StackMaps::RecordMap::iterator iter = recordMap.find(call.stackmapID());
-        if (iter == recordMap.end())
-            continue;
 
-        for (unsigned j = 0; j < iter->value.size(); ++j) {
-            JSCall copy = call;
-            copy.m_instructionOffset = iter->value[j].instructionOffset;
-            state.jsCalls.append(copy);
-        }
+        for (unsigned i = state.checkIns.size(); i--;) {
+            generateCheckInICFastPath(
+                state, codeBlock, generatedFunction, recordMap, state.checkIns[i],
+                sizeOfIn()); 
+        } 
     }
     
-    std::sort(state.jsCalls.begin(), state.jsCalls.end());
+    adjustCallICsForStackmaps(state.jsCalls, recordMap);
     
     for (unsigned i = state.jsCalls.size(); i--;) {
         JSCall& call = state.jsCalls[i];
 
         CCallHelpers fastPathJIT(&vm, codeBlock);
         call.emit(fastPathJIT);
-        
+
         char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
+
+        generateInlineIfPossibleOutOfLineIfNot(state, vm, codeBlock, fastPathJIT, startOfIC, sizeOfCall(), "JSCall inline cache", [&] (LinkBuffer& linkBuffer, CCallHelpers&, bool) {
+            call.link(vm, linkBuffer);
+        });
+    }
+    
+    adjustCallICsForStackmaps(state.jsCallVarargses, recordMap);
+    
+    for (unsigned i = state.jsCallVarargses.size(); i--;) {
+        JSCallVarargs& call = state.jsCallVarargses[i];
         
-        LinkBuffer linkBuffer(vm, fastPathJIT, startOfIC, sizeOfCall());
-        if (!linkBuffer.isValid()) {
-            dataLog("Failed to insert inline cache for call because we thought the size would be ", sizeOfCall(), " but it ended up being ", fastPathJIT.m_assembler.codeSize(), " prior to compaction.\n");
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-        
-        MacroAssembler::AssemblerType_T::fillNops(
-            startOfIC + linkBuffer.size(), sizeOfCall() - linkBuffer.size());
-        
-        call.link(vm, linkBuffer);
+        CCallHelpers fastPathJIT(&vm, codeBlock);
+        call.emit(fastPathJIT, varargsSpillSlotsOffset);
+
+        char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
+        size_t sizeOfIC = sizeOfICFor(call.node());
+
+        generateInlineIfPossibleOutOfLineIfNot(state, vm, codeBlock, fastPathJIT, startOfIC, sizeOfIC, "varargs call inline cache", [&] (LinkBuffer& linkBuffer, CCallHelpers&, bool) {
+            call.link(vm, linkBuffer, state.finalizer->handleExceptionsLinkBuffer->entrypoint());
+        });
     }
     
     RepatchBuffer repatchBuffer(codeBlock);
 
-    iter = recordMap.find(state.handleStackOverflowExceptionStackmapID);
+    auto iter = recordMap.find(state.handleStackOverflowExceptionStackmapID);
     // It's sort of remotely possible that we won't have an in-band exception handling
     // path, for some kinds of functions.
     if (iter != recordMap.end()) {
@@ -503,41 +688,73 @@ void compile(State& state, Safepoint::Result& safepointResult)
         options.NoFramePointerElim = true;
         if (Options::useLLVMSmallCodeModel())
             options.CodeModel = LLVMCodeModelSmall;
-        options.EnableFastISel = Options::enableLLVMFastISel();
+        options.EnableFastISel = enableLLVMFastISel;
         options.MCJMM = llvm->CreateSimpleMCJITMemoryManager(
             &state, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy);
     
         LLVMExecutionEngineRef engine;
         
-        if (isARM64())
+        if (isARM64()) {
+#if OS(DARWIN)
             llvm->SetTarget(state.module, "arm64-apple-ios");
-        
+#elif OS(LINUX)
+            llvm->SetTarget(state.module, "aarch64-linux-gnu");
+#else
+#error "Unrecognized OS"
+#endif
+        }
+
         if (llvm->CreateMCJITCompilerForModule(&engine, state.module, &options, sizeof(options), &error)) {
             dataLog("FATAL: Could not create LLVM execution engine: ", error, "\n");
             CRASH();
         }
+        
+        // At this point we no longer own the module.
+        LModule module = state.module;
+        state.module = nullptr;
+
+        // The data layout also has to be set in the module. Get the data layout from the MCJIT and apply
+        // it to the module.
+        LLVMTargetMachineRef targetMachine = llvm->GetExecutionEngineTargetMachine(engine);
+        LLVMTargetDataRef targetData = llvm->GetExecutionEngineTargetData(engine);
+        char* stringRepOfTargetData = llvm->CopyStringRepOfTargetData(targetData);
+        llvm->SetDataLayout(module, stringRepOfTargetData);
+        free(stringRepOfTargetData);
 
         LLVMPassManagerRef functionPasses = 0;
         LLVMPassManagerRef modulePasses;
-    
+
         if (Options::llvmSimpleOpt()) {
             modulePasses = llvm->CreatePassManager();
-            llvm->AddTargetData(llvm->GetExecutionEngineTargetData(engine), modulePasses);
+            llvm->AddTargetData(targetData, modulePasses);
+            llvm->AddAnalysisPasses(targetMachine, modulePasses);
             llvm->AddPromoteMemoryToRegisterPass(modulePasses);
+            llvm->AddGlobalOptimizerPass(modulePasses);
+            llvm->AddFunctionInliningPass(modulePasses);
+            llvm->AddPruneEHPass(modulePasses);
+            llvm->AddGlobalDCEPass(modulePasses);
             llvm->AddConstantPropagationPass(modulePasses);
+            llvm->AddAggressiveDCEPass(modulePasses);
             llvm->AddInstructionCombiningPass(modulePasses);
+            // BEGIN - DO NOT CHANGE THE ORDER OF THE ALIAS ANALYSIS PASSES
             llvm->AddTypeBasedAliasAnalysisPass(modulePasses);
             llvm->AddBasicAliasAnalysisPass(modulePasses);
+            // END - DO NOT CHANGE THE ORDER OF THE ALIAS ANALYSIS PASSES
             llvm->AddGVNPass(modulePasses);
             llvm->AddCFGSimplificationPass(modulePasses);
             llvm->AddDeadStoreEliminationPass(modulePasses);
-            llvm->RunPassManager(modulePasses, state.module);
+            
+            if (enableLLVMFastISel)
+                llvm->AddLowerSwitchPass(modulePasses);
+
+            llvm->RunPassManager(modulePasses, module);
         } else {
             LLVMPassManagerBuilderRef passBuilder = llvm->PassManagerBuilderCreate();
             llvm->PassManagerBuilderSetOptLevel(passBuilder, Options::llvmOptimizationLevel());
+            llvm->PassManagerBuilderUseInlinerWithThreshold(passBuilder, 275);
             llvm->PassManagerBuilderSetSizeLevel(passBuilder, Options::llvmSizeLevel());
         
-            functionPasses = llvm->CreateFunctionPassManagerForModule(state.module);
+            functionPasses = llvm->CreateFunctionPassManagerForModule(module);
             modulePasses = llvm->CreatePassManager();
         
             llvm->AddTargetData(llvm->GetExecutionEngineTargetData(engine), modulePasses);
@@ -548,16 +765,16 @@ void compile(State& state, Safepoint::Result& safepointResult)
             llvm->PassManagerBuilderDispose(passBuilder);
         
             llvm->InitializeFunctionPassManager(functionPasses);
-            for (LValue function = llvm->GetFirstFunction(state.module); function; function = llvm->GetNextFunction(function))
+            for (LValue function = llvm->GetFirstFunction(module); function; function = llvm->GetNextFunction(function))
                 llvm->RunFunctionPassManager(functionPasses, function);
             llvm->FinalizeFunctionPassManager(functionPasses);
         
-            llvm->RunPassManager(modulePasses, state.module);
+            llvm->RunPassManager(modulePasses, module);
         }
 
         if (shouldShowDisassembly() || verboseCompilationEnabled())
-            state.dumpState("after optimization");
-    
+            state.dumpState(module, "after optimization");
+        
         // FIXME: Need to add support for the case where JIT memory allocation failed.
         // https://bugs.webkit.org/show_bug.cgi?id=113620
         state.generatedFunction = reinterpret_cast<GeneratedFunction>(llvm->GetPointerToGlobal(engine, state.function));
@@ -566,10 +783,14 @@ void compile(State& state, Safepoint::Result& safepointResult)
         llvm->DisposePassManager(modulePasses);
         llvm->DisposeExecutionEngine(engine);
     }
+
     if (safepointResult.didGetCancelled())
         return;
     RELEASE_ASSERT(!state.graph.m_vm.heap.isCollecting());
     
+    if (state.allocationFailed)
+        return;
+    
     if (shouldShowDisassembly()) {
         for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) {
             ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
@@ -593,7 +814,8 @@ void compile(State& state, Safepoint::Result& safepointResult)
     }
     
     bool didSeeUnwindInfo = state.jitCode->unwindInfo.parse(
-        state.compactUnwind, state.compactUnwindSize, state.generatedFunction);
+        state.unwindDataSection, state.unwindDataSectionSize,
+        state.generatedFunction);
     if (shouldShowDisassembly()) {
         dataLog("Unwind info for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ":\n");
         if (didSeeUnwindInfo)
@@ -624,26 +846,36 @@ void compile(State& state, Safepoint::Result& safepointResult)
         fixFunctionBasedOnStackMaps(
             state, state.graph.m_codeBlock, state.jitCode.get(), state.generatedFunction,
             recordMap, didSeeUnwindInfo);
+        if (state.allocationFailed)
+            return;
         
-        if (shouldShowDisassembly()) {
+        if (shouldShowDisassembly() || Options::asyncDisassembly()) {
             for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) {
-                if (state.codeSectionNames[i] != "__text")
+                if (state.codeSectionNames[i] != SECTION_NAME("text"))
                     continue;
                 
                 ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
-                dataLog(
+                
+                CString header = toCString(
                     "Generated LLVM code after stackmap-based fix-up for ",
                     CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT),
                     " in ", state.graph.m_plan.mode, " #", i, ", ",
                     state.codeSectionNames[i], ":\n");
+                
+                if (Options::asyncDisassembly()) {
+                    disassembleAsynchronously(
+                        header, MacroAssemblerCodeRef(handle), handle->sizeInBytes(), "    ",
+                        LLVMSubset);
+                    continue;
+                }
+                
+                dataLog(header);
                 disassemble(
                     MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),
                     "    ", WTF::dataFile(), LLVMSubset);
             }
         }
     }
-    
-    state.module = 0; // We no longer own the module.
 }
 
 } } // namespace JSC::FTL
index cbe0de7fde22808c258c9899cf19734466c0a710..381b3d3a4d0ab38abc80b0fbaeb49843a5e3daed 100644 (file)
@@ -32,7 +32,7 @@ namespace JSC { namespace FTL {
 
 void ExitArgument::dump(PrintStream& out) const
 {
-    out.print("arg", argument(), " as ", format());
+    out.print("#", argument(), " as ", format());
 }
 
 } } // namespace JSC::FTL
index 775abe18f08042d733d052887ea915e5b859bc9b..074e7a69ec54dbff49462c0b4668eac1034e17a7 100644 (file)
@@ -32,7 +32,7 @@ namespace JSC { namespace FTL {
 
 void ExitArgumentForOperand::dump(PrintStream& out) const
 {
-    out.print(m_exitArgument, " for r", m_operand);
+    out.print(m_exitArgument, " for ", m_operand);
 }
 
 } } // namespace JSC::FTL
diff --git a/ftl/FTLExitPropertyValue.cpp b/ftl/FTLExitPropertyValue.cpp
new file mode 100644 (file)
index 0000000..d57db74
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLExitPropertyValue.h"
+
+#if ENABLE(FTL_JIT)
+
+namespace JSC { namespace FTL {
+
+ExitPropertyValue ExitPropertyValue::withLocalsOffset(int offset) const
+{
+    return ExitPropertyValue(m_location, m_value.withLocalsOffset(offset));
+}
+
+void ExitPropertyValue::dump(PrintStream& out) const
+{
+    out.print(m_location, " => ", m_value);
+}
+
+void ExitPropertyValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    m_value.validateReferences(trackedReferences);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/ftl/FTLExitPropertyValue.h b/ftl/FTLExitPropertyValue.h
new file mode 100644 (file)
index 0000000..76fd00c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLExitPropertyValue_h
+#define FTLExitPropertyValue_h
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGPromotedHeapLocation.h"
+#include "FTLExitValue.h"
+
+namespace JSC {
+
+class TrackedReferences;
+
+namespace FTL {
+
+class ExitPropertyValue {
+public:
+    ExitPropertyValue()
+    {
+    }
+    
+    ExitPropertyValue(DFG::PromotedLocationDescriptor location, const ExitValue& value)
+        : m_location(location)
+        , m_value(value)
+    {
+        ASSERT(!!location == !!value);
+    }
+    
+    bool operator!() const { return !m_location; }
+    
+    DFG::PromotedLocationDescriptor location() const { return m_location; }
+    const ExitValue& value() const { return m_value; }
+    
+    ExitPropertyValue withLocalsOffset(int offset) const;
+    
+    void dump(PrintStream& out) const;
+    
+    void validateReferences(const TrackedReferences&) const;
+
+private:
+    DFG::PromotedLocationDescriptor m_location;
+    ExitValue m_value;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLExitPropertyValue_h
+
diff --git a/ftl/FTLExitTimeObjectMaterialization.cpp b/ftl/FTLExitTimeObjectMaterialization.cpp
new file mode 100644 (file)
index 0000000..858d1ba
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLExitTimeObjectMaterialization.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace FTL {
+
+using namespace JSC::DFG;
+
+ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type, CodeOrigin codeOrigin)
+    : m_type(type)
+    , m_origin(codeOrigin)
+{
+}
+
+ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization()
+{
+}
+
+void ExitTimeObjectMaterialization::add(
+    PromotedLocationDescriptor location, const ExitValue& value)
+{
+    m_properties.append(ExitPropertyValue(location, value));
+}
+
+ExitValue ExitTimeObjectMaterialization::get(PromotedLocationDescriptor location) const
+{
+    for (ExitPropertyValue value : m_properties) {
+        if (value.location() == location)
+            return value.value();
+    }
+    return ExitValue();
+}
+
+void ExitTimeObjectMaterialization::accountForLocalsOffset(int offset)
+{
+    for (ExitPropertyValue& property : m_properties)
+        property = property.withLocalsOffset(offset);
+}
+
+void ExitTimeObjectMaterialization::dump(PrintStream& out) const
+{
+    out.print(RawPointer(this), ":", Graph::opName(m_type), "(", listDump(m_properties), ")");
+}
+
+void ExitTimeObjectMaterialization::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    for (ExitPropertyValue value : m_properties)
+        value.validateReferences(trackedReferences);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/ftl/FTLExitTimeObjectMaterialization.h b/ftl/FTLExitTimeObjectMaterialization.h
new file mode 100644 (file)
index 0000000..e2003c6
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLExitTimeObjectMaterialization_h
+#define FTLExitTimeObjectMaterialization_h
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGNodeType.h"
+#include "FTLExitPropertyValue.h"
+#include "FTLExitValue.h"
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class TrackedReferences;
+
+namespace FTL {
+
+class ExitTimeObjectMaterialization {
+    WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
+public:
+    ExitTimeObjectMaterialization(DFG::NodeType, CodeOrigin);
+    ~ExitTimeObjectMaterialization();
+    
+    void add(DFG::PromotedLocationDescriptor, const ExitValue&);
+    
+    DFG::NodeType type() const { return m_type; }
+    CodeOrigin origin() const { return m_origin; }
+    
+    ExitValue get(DFG::PromotedLocationDescriptor) const;
+    const Vector<ExitPropertyValue>& properties() const { return m_properties; }
+    
+    void accountForLocalsOffset(int offset);
+    
+    void dump(PrintStream& out) const;
+    
+    void validateReferences(const TrackedReferences&) const;
+    
+private:
+    DFG::NodeType m_type;
+    CodeOrigin m_origin;
+    Vector<ExitPropertyValue> m_properties;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLExitTimeObjectMaterialization_h
+
index 81df770b2494e6988f55b25a7948ab9b3ce155fc..24a0f3c22c9b2f4a84acc7957f57ae321ac58ccc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(FTL_JIT)
 
+#include "FTLExitTimeObjectMaterialization.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace FTL {
 
+ExitValue ExitValue::materializeNewObject(ExitTimeObjectMaterialization* data)
+{
+    ExitValue result;
+    result.m_kind = ExitValueMaterializeNewObject;
+    result.u.newObjectMaterializationData = data;
+    return result;
+}
+
+ExitValue ExitValue::withLocalsOffset(int offset) const
+{
+    if (!isInJSStackSomehow())
+        return *this;
+    if (!virtualRegister().isLocal())
+        return *this;
+    return withVirtualRegister(virtualRegister() + offset);
+}
+
+ValueFormat ExitValue::valueFormat() const
+{
+    switch (kind()) {
+    case InvalidExitValue:
+        RELEASE_ASSERT_NOT_REACHED();
+        return InvalidValueFormat;
+            
+    case ExitValueDead:
+    case ExitValueConstant:
+    case ExitValueInJSStack:
+    case ExitValueMaterializeNewObject:
+        return ValueFormatJSValue;
+            
+    case ExitValueArgument:
+        return exitArgument().format();
+            
+    case ExitValueInJSStackAsInt32:
+        return ValueFormatInt32;
+            
+    case ExitValueInJSStackAsInt52:
+        return ValueFormatInt52;
+            
+    case ExitValueInJSStackAsDouble:
+        return ValueFormatDouble;
+            
+    case ExitValueRecovery:
+        return recoveryFormat();
+    }
+        
+    RELEASE_ASSERT_NOT_REACHED();
+    return InvalidValueFormat;
+}
+
 void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     switch (kind()) {
@@ -48,23 +100,23 @@ void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
         out.print("Constant(", inContext(constant(), context), ")");
         return;
     case ExitValueInJSStack:
-        out.print("InJSStack:r", virtualRegister());
+        out.print("InJSStack:", virtualRegister());
         return;
     case ExitValueInJSStackAsInt32:
-        out.print("InJSStackAsInt32:r", virtualRegister());
+        out.print("InJSStackAsInt32:", virtualRegister());
         return;
     case ExitValueInJSStackAsInt52:
-        out.print("InJSStackAsInt52:r", virtualRegister());
+        out.print("InJSStackAsInt52:", virtualRegister());
         return;
     case ExitValueInJSStackAsDouble:
-        out.print("InJSStackAsDouble:r", virtualRegister());
-        return;
-    case ExitValueArgumentsObjectThatWasNotCreated:
-        out.print("ArgumentsObjectThatWasNotCreated");
+        out.print("InJSStackAsDouble:", virtualRegister());
         return;
     case ExitValueRecovery:
         out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
         return;
+    case ExitValueMaterializeNewObject:
+        out.print("Materialize(", WTF::RawPointer(objectMaterialization()), ")");
+        return;
     }
     
     RELEASE_ASSERT_NOT_REACHED();
@@ -75,6 +127,12 @@ void ExitValue::dump(PrintStream& out) const
     dumpInContext(out, 0);
 }
 
+void ExitValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    if (isConstant())
+        trackedReferences.check(constant());
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index 043e1b7620a679ff097a7f4a831a4118c072e1d6..13e6e09f4563a7e507ce5ff323f510012d5ead06 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "VirtualRegister.h"
 #include <wtf/PrintStream.h>
 
-namespace JSC { namespace FTL {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace FTL {
 
 // This is like ValueRecovery, but respects the way that the FTL does OSR
 // exit: the live non-constant non-flushed values are passed as arguments
@@ -51,10 +55,12 @@ enum ExitValueKind {
     ExitValueInJSStackAsInt32,
     ExitValueInJSStackAsInt52,
     ExitValueInJSStackAsDouble,
-    ExitValueArgumentsObjectThatWasNotCreated,
-    ExitValueRecovery
+    ExitValueRecovery,
+    ExitValueMaterializeNewObject
 };
 
+class ExitTimeObjectMaterialization;
+
 class ExitValue {
 public:
     ExitValue()
@@ -119,13 +125,6 @@ public:
         return result;
     }
     
-    static ExitValue argumentsObjectThatWasNotCreated()
-    {
-        ExitValue result;
-        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
-        return result;
-    }
-    
     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
     {
         ExitValue result;
@@ -137,6 +136,8 @@ public:
         return result;
     }
     
+    static ExitValue materializeNewObject(ExitTimeObjectMaterialization*);
+    
     ExitValueKind kind() const { return m_kind; }
     
     bool isDead() const { return kind() == ExitValueDead; }
@@ -154,8 +155,8 @@ public:
     }
     bool isConstant() const { return kind() == ExitValueConstant; }
     bool isArgument() const { return kind() == ExitValueArgument; }
-    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
     bool isRecovery() const { return kind() == ExitValueRecovery; }
+    bool isObjectMaterialization() const { return kind() == ExitValueMaterializeNewObject; }
     
     ExitArgument exitArgument() const
     {
@@ -199,7 +200,13 @@ public:
         return VirtualRegister(u.virtualRegister);
     }
     
-    ExitValue withVirtualRegister(VirtualRegister virtualRegister)
+    ExitTimeObjectMaterialization* objectMaterialization() const
+    {
+        ASSERT(isObjectMaterialization());
+        return u.newObjectMaterializationData;
+    }
+
+    ExitValue withVirtualRegister(VirtualRegister virtualRegister) const
     {
         ASSERT(isInJSStackSomehow());
         ExitValue result;
@@ -207,47 +214,20 @@ public:
         result.u.virtualRegister = virtualRegister.offset();
         return result;
     }
-
+    
+    ExitValue withLocalsOffset(int offset) const;
+    
     // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
     // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
     // will claim to be a JSValue. If it's an argument then it will tell you the argument's
     // format.
-    ValueFormat valueFormat() const
-    {
-        switch (kind()) {
-        case InvalidExitValue:
-            RELEASE_ASSERT_NOT_REACHED();
-            return InvalidValueFormat;
-            
-        case ExitValueDead:
-        case ExitValueConstant:
-        case ExitValueInJSStack:
-        case ExitValueArgumentsObjectThatWasNotCreated:
-            return ValueFormatJSValue;
-            
-        case ExitValueArgument:
-            return exitArgument().format();
-            
-        case ExitValueInJSStackAsInt32:
-            return ValueFormatInt32;
-            
-        case ExitValueInJSStackAsInt52:
-            return ValueFormatInt52;
-            
-        case ExitValueInJSStackAsDouble:
-            return ValueFormatDouble;
-            
-        case ExitValueRecovery:
-            return recoveryFormat();
-        }
-        
-        RELEASE_ASSERT_NOT_REACHED();
-        return InvalidValueFormat;
-    }
+    ValueFormat valueFormat() const;
 
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
+    void validateReferences(const TrackedReferences&) const;
+    
 private:
     ExitValueKind m_kind;
     union {
@@ -260,6 +240,7 @@ private:
             uint16_t opcode;
             uint16_t format;
         } recovery;
+        ExitTimeObjectMaterialization* newObjectMaterializationData;
     } u;
 };
 
index 1345c6fa13ed4afd0344af9723b79be331bd6810..ac2fc07eba1e43cdc0c42aea138e5c6e380a4593 100644 (file)
@@ -38,7 +38,7 @@ using namespace DFG;
 
 void fail(State& state)
 {
-    state.graph.m_plan.finalizer = adoptPtr(new FailedFinalizer(state.graph.m_plan));
+    state.graph.m_plan.finalizer = std::make_unique<FailedFinalizer>(state.graph.m_plan);
     
     if (state.module)
         llvm->DisposeModule(state.module);
index 708bedc38a9ffa3c4ad8d8064e3cb6913d996615..29f05e51d461fdf6e014383199c918f6415e8cea 100644 (file)
@@ -31,6 +31,8 @@
 namespace JSC { namespace FTL {
 
 ForOSREntryJITCode::ForOSREntryJITCode()
+    : m_bytecodeIndex(UINT_MAX)
+    , m_entryFailureCount(0)
 {
 }
 
index df0d71122ff62f591bf40ee8fd42f74c0109eeb3..6793e74b036e4f771c392e149a62f3b9fde0e2e3 100644 (file)
@@ -31,7 +31,7 @@
 #include "CodeOrigin.h"
 #include "JITInlineCacheGenerator.h"
 #include "MacroAssembler.h"
-#include <wtf/text/StringImpl.h>
+#include <wtf/text/UniquedStringImpl.h>
 
 namespace JSC { namespace FTL {
 
@@ -39,7 +39,7 @@ class InlineCacheDescriptor {
 public:
     InlineCacheDescriptor() { }
     
-    InlineCacheDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid)
+    InlineCacheDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, UniquedStringImpl* uid)
         : m_stackmapID(stackmapID)
         , m_codeOrigin(codeOrigin)
         , m_uid(uid)
@@ -48,12 +48,12 @@ public:
     
     unsigned stackmapID() const { return m_stackmapID; }
     CodeOrigin codeOrigin() const { return m_codeOrigin; }
-    StringImpl* uid() const { return m_uid; }
+    UniquedStringImpl* uid() const { return m_uid; }
     
 private:
     unsigned m_stackmapID;
     CodeOrigin m_codeOrigin;
-    StringImpl* m_uid;
+    UniquedStringImpl* m_uid;
     
 public:
     Vector<MacroAssembler::Jump> m_slowPathDone;
@@ -63,7 +63,7 @@ class GetByIdDescriptor : public InlineCacheDescriptor {
 public:
     GetByIdDescriptor() { }
     
-    GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid)
+    GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, UniquedStringImpl* uid)
         : InlineCacheDescriptor(stackmapID, codeOrigin, uid)
     {
     }
@@ -76,7 +76,7 @@ public:
     PutByIdDescriptor() { }
     
     PutByIdDescriptor(
-        unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid,
+        unsigned stackmapID, CodeOrigin codeOrigin, UniquedStringImpl* uid,
         ECMAMode ecmaMode, PutKind putKind)
         : InlineCacheDescriptor(stackmapID, codeOrigin, uid)
         , m_ecmaMode(ecmaMode)
@@ -94,6 +94,35 @@ private:
     PutKind m_putKind;
 };
 
+struct CheckInGenerator {
+    StructureStubInfo* m_stub;
+    MacroAssembler::Call m_slowCall;
+    MacroAssembler::Label m_beginLabel;
+
+    CheckInGenerator(StructureStubInfo* stub, MacroAssembler::Call slowCall, MacroAssembler::Label beginLabel)
+        : m_stub(stub) 
+        , m_slowCall(slowCall)
+        , m_beginLabel(beginLabel)
+    {
+    }
+};
+
+class CheckInDescriptor : public InlineCacheDescriptor {
+public:
+    CheckInDescriptor() { }
+    
+    CheckInDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, const UniquedStringImpl* uid)
+        : InlineCacheDescriptor(stackmapID, codeOrigin, nullptr)
+        , m_uid(uid)
+    {
+    }
+
+    
+    const UniquedStringImpl* m_uid;
+    Vector<CheckInGenerator> m_generators;
+};
+
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index 6d444141eda13884bcd2bfbb03ee51cb64cbf933..5cd637602d80f4084499fbf6ec8ee93aa4cc5fde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(FTL_JIT)
 
+#include "DFGNode.h"
 #include "JITInlineCacheGenerator.h"
 #include "MacroAssembler.h"
 
 namespace JSC { namespace FTL {
 
+using namespace DFG;
+
 // The default sizes are x86-64-specific, and were found empirically. They have to cover the worst
 // possible combination of registers leading to the largest possible encoding of each instruction in
 // the IC.
@@ -70,6 +73,68 @@ size_t sizeOfCall()
 #endif
 }
 
+size_t sizeOfCallVarargs()
+{
+#if CPU(ARM64)
+    return 332;
+#else
+    return 275;
+#endif
+}
+
+size_t sizeOfCallForwardVarargs()
+{
+#if CPU(ARM64)
+    return 312;
+#else
+    return 262;
+#endif
+}
+
+size_t sizeOfConstructVarargs()
+{
+    return sizeOfCallVarargs(); // Should be the same size.
+}
+
+size_t sizeOfConstructForwardVarargs()
+{
+    return sizeOfCallForwardVarargs(); // Should be the same size.
+}
+
+size_t sizeOfIn()
+{
+#if CPU(ARM64)
+    return 4;
+#else
+    return 5; 
+#endif
+}
+
+size_t sizeOfICFor(Node* node)
+{
+    switch (node->op()) {
+    case GetById:
+        return sizeOfGetById();
+    case PutById:
+        return sizeOfPutById();
+    case Call:
+    case Construct:
+        return sizeOfCall();
+    case CallVarargs:
+        return sizeOfCallVarargs();
+    case CallForwardVarargs:
+        return sizeOfCallForwardVarargs();
+    case ConstructVarargs:
+        return sizeOfConstructVarargs();
+    case ConstructForwardVarargs:
+        return sizeOfConstructForwardVarargs();
+    case In:
+        return sizeOfIn();
+    default:
+        return 0;
+    }
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index 7c7c189725e4cac74c71c6c8b4279e2b03e75288..82f3bbc7469daedaebda30ec5f650eba329d55e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(FTL_JIT)
 
-namespace JSC { namespace FTL {
+namespace JSC {
+
+namespace DFG {
+struct Node;
+}
+
+namespace FTL {
 
 size_t sizeOfGetById();
 size_t sizeOfPutById();
 size_t sizeOfCall();
+size_t sizeOfCallVarargs();
+size_t sizeOfCallForwardVarargs();
+size_t sizeOfConstructVarargs();
+size_t sizeOfConstructForwardVarargs();
+size_t sizeOfIn();
+
+size_t sizeOfICFor(DFG::Node*);
 
 } } // namespace JSC::FTL
 
index 667e3fb640bee9c8b25ef32a76b44acf86cf73dc..3e62d302f8e4ca6f99b7db7280863c3b3f07c922 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 namespace JSC { namespace FTL {
 
 #define FOR_EACH_FTL_INTRINSIC(macro) \
+    macro(ceil64, "llvm.ceil.f64", functionType(doubleType, doubleType)) \
+    macro(ctlz32, "llvm.ctlz.i32", functionType(int32, int32, boolean)) \
     macro(addWithOverflow32, "llvm.sadd.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     macro(addWithOverflow64, "llvm.sadd.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
     macro(doubleAbs, "llvm.fabs.f64", functionType(doubleType, doubleType)) \
     macro(doubleSin, "llvm.sin.f64", functionType(doubleType, doubleType)) \
     macro(doubleCos, "llvm.cos.f64", functionType(doubleType, doubleType)) \
+    macro(doublePow, "llvm.pow.f64", functionType(doubleType, doubleType, doubleType)) \
+    macro(doublePowi, "llvm.powi.f64", functionType(doubleType, doubleType, int32)) \
     macro(doubleSqrt, "llvm.sqrt.f64", functionType(doubleType, doubleType)) \
+    macro(doubleLog, "llvm.log.f64", functionType(doubleType, doubleType)) \
     macro(frameAddress, "llvm.frameaddress", functionType(pointerType(int8), int32)) \
     macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     macro(mulWithOverflow64, "llvm.smul.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
@@ -54,19 +59,33 @@ namespace JSC { namespace FTL {
 
 #define FOR_EACH_FUNCTION_TYPE(macro) \
     macro(C_JITOperation_EC, functionType(intPtr, intPtr, intPtr)) \
+    macro(C_JITOperation_ECZ, functionType(intPtr, intPtr, intPtr, int32)) \
+    macro(C_JITOperation_ECZC, functionType(intPtr, intPtr, intPtr, int32, intPtr)) \
+    macro(C_JITOperation_EGC, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(C_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \
     macro(C_JITOperation_EJssJss, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(C_JITOperation_EJssJssJss, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
     macro(C_JITOperation_ESt, functionType(intPtr, intPtr, intPtr)) \
+    macro(C_JITOperation_EStJscSymtab, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
+    macro(C_JITOperation_EStRZJsf, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr)) \
+    macro(C_JITOperation_EStRZJsfL, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr, intPtr)) \
+    macro(C_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
+    macro(C_JITOperation_EStZZ, functionType(intPtr, intPtr, intPtr, int32, int32)) \
+    macro(C_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
     macro(D_JITOperation_D, functionType(doubleType, doubleType)) \
-    macro(I_JITOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
+    macro(T_JITOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
     macro(J_JITOperation_E, functionType(int64, intPtr)) \
     macro(J_JITOperation_EA, functionType(int64, intPtr, intPtr)) \
     macro(J_JITOperation_EAZ, functionType(int64, intPtr, intPtr, int32)) \
+    macro(J_JITOperation_ECJ, functionType(int64, intPtr, intPtr, int64)) \
+    macro(J_JITOperation_ECZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_EDA, functionType(int64, intPtr, doubleType, intPtr)) \
     macro(J_JITOperation_EJ, functionType(int64, intPtr, int64)) \
     macro(J_JITOperation_EJA, functionType(int64, intPtr, int64, intPtr)) \
+    macro(J_JITOperation_EJC, functionType(int64, intPtr, int64, intPtr)) \
+    macro(J_JITOperation_EJI, functionType(int64, intPtr, int64, intPtr)) \
     macro(J_JITOperation_EJJ, functionType(int64, intPtr, int64, int64)) \
+    macro(J_JITOperation_EJscC, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(J_JITOperation_EJssZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_ESsiJI, functionType(int64, intPtr, intPtr, int64, intPtr)) \
     macro(Jss_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
@@ -81,6 +100,7 @@ namespace JSC { namespace FTL {
     macro(P_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
     macro(Q_JITOperation_D, functionType(int64, doubleType)) \
     macro(Q_JITOperation_J, functionType(int64, int64)) \
+    macro(S_JITOperation_EGC, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(S_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \
     macro(S_JITOperation_EJJ, functionType(intPtr, intPtr, int64, int64)) \
     macro(S_JITOperation_J, functionType(intPtr, int64)) \
@@ -90,9 +110,16 @@ namespace JSC { namespace FTL {
     macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \
     macro(V_JITOperation_EC, functionType(voidType, intPtr, intPtr)) \
     macro(V_JITOperation_ECb, functionType(voidType, intPtr, intPtr)) \
-    macro(V_JITOperation_EVwsJ, functionType(voidType, intPtr, intPtr, int64)) \
-    macro(Z_JITOperation_D, functionType(int32, doubleType))
-
+    macro(V_JITOperation_EWs, functionType(voidType, intPtr, intPtr)) \
+    macro(V_JITOperation_EZJZZZ, functionType(voidType, intPtr, int32, int64, int32, int32, int32)) \
+    macro(V_JITOperation_J, functionType(voidType, int64)) \
+    macro(V_JITOperation_Z, functionType(voidType, int32)) \
+    macro(Z_JITOperation_D, functionType(int32, doubleType)) \
+    macro(Z_JITOperation_EC, functionType(int32, intPtr, intPtr)) \
+    macro(Z_JITOperation_EGC, functionType(int32, intPtr, intPtr, intPtr)) \
+    macro(Z_JITOperation_EJZ, functionType(int32, intPtr, int64, int32)) \
+    macro(Z_JITOperation_ESJss, functionType(int32, intPtr, intPtr, int64)) \
+    
 class IntrinsicRepository : public CommonValues {
 public:
     IntrinsicRepository(LContext);
index c031609dc71d883a6b887dcaf648a02fc47143bc..6120f0520fab5630e61419028c68b14a72ee6700 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -125,6 +125,14 @@ DFG::CommonData* JITCode::dfgCommon()
     return &common;
 }
 
+void JITCode::validateReferences(const TrackedReferences& trackedReferences)
+{
+    common.validateReferences(trackedReferences);
+    
+    for (OSRExit& exit : osrExit)
+        exit.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index 9894d4c3d68e355117ae237c5b5ec7992a230fbb..6a4d15205f060d0609e5b299fe9a8e0ca193edb2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "LLVMAPI.h"
 #include <wtf/RefCountedArray.h>
 
-namespace JSC { namespace FTL {
+#if OS(DARWIN)
+#define SECTION_NAME_PREFIX "__"
+#elif OS(LINUX)
+#define SECTION_NAME_PREFIX "."
+#else
+#error "Unsupported platform"
+#endif
+
+#define SECTION_NAME(NAME) (SECTION_NAME_PREFIX NAME)
+
+namespace JSC {
+
+class TrackedReferences;
+
+namespace FTL {
 
 class JITCode : public JSC::JITCode {
 public:
@@ -57,13 +71,15 @@ public:
     void initializeArityCheckEntrypoint(CodeRef);
     void initializeAddressForCall(CodePtr);
     
+    void validateReferences(const TrackedReferences&) override;
+    
     const Vector<RefPtr<ExecutableMemoryHandle>>& handles() const { return m_handles; }
     const Vector<RefPtr<DataSection>>& dataSections() const { return m_dataSections; }
     
     CodePtr exitThunks();
     
-    JITCode* ftl();
-    DFG::CommonData* dfgCommon();
+    JITCode* ftl() override;
+    DFG::CommonData* dfgCommon() override;
     
     DFG::CommonData common;
     SegmentedVector<OSRExit, 8> osrExit;
index 691cf777d2653aeb7f6ddd8d3564c3e6dc7aa844..3da48486accae3bd1a8754eee7ddc4f0202d321f 100644 (file)
@@ -127,7 +127,13 @@ bool JITFinalizer::finalizeFunction()
                 toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data()))
             .executableMemory());
     }
-    
+
+    for (unsigned i = 0; i < outOfLineCodeInfos.size(); ++i) {
+        jitCode->addHandle(FINALIZE_DFG_CODE(
+            *outOfLineCodeInfos[i].m_linkBuffer,
+            ("FTL out of line code for %s", outOfLineCodeInfos[i].m_codeDescription)).executableMemory());
+    }
+
     jitCode->initializeArityCheckEntrypoint(
         FINALIZE_DFG_CODE(
             *entrypointLinkBuffer,
index 97f1b96b3007700177d1c3dce1c5a9317bad0730..a1e0d034f4577a8734b1fed61e75cd61d5d7176a 100644 (file)
 
 namespace JSC { namespace FTL {
 
+class OutOfLineCodeInfo {
+public:
+    OutOfLineCodeInfo(std::unique_ptr<LinkBuffer> linkBuffer, const char* codeDescription)
+        : m_linkBuffer(WTF::move(linkBuffer))
+        , m_codeDescription(codeDescription)
+    {
+    }
+
+    std::unique_ptr<LinkBuffer> m_linkBuffer;
+    const char* m_codeDescription;
+};
+
 class JITFinalizer : public DFG::Finalizer {
 public:
     JITFinalizer(DFG::Plan&);
     virtual ~JITFinalizer();
-    
+
     size_t codeSize() override;
     bool finalize() override;
     bool finalizeFunction() override;
 
-    OwnPtr<LinkBuffer> exitThunksLinkBuffer;
-    OwnPtr<LinkBuffer> entrypointLinkBuffer;
-    OwnPtr<LinkBuffer> sideCodeLinkBuffer;
-    OwnPtr<LinkBuffer> handleExceptionsLinkBuffer;
+    std::unique_ptr<LinkBuffer> exitThunksLinkBuffer;
+    std::unique_ptr<LinkBuffer> entrypointLinkBuffer;
+    std::unique_ptr<LinkBuffer> sideCodeLinkBuffer;
+    std::unique_ptr<LinkBuffer> handleExceptionsLinkBuffer;
+    Vector<OutOfLineCodeInfo> outOfLineCodeInfos;
     Vector<SlowPathCall> slowPathCalls; // Calls inside the side code.
     Vector<OSRExitCompilationInfo> osrExit;
     GeneratedFunction function;
index 76cd2dc547bb9b6ad289b5ef8e9886f8778f2e46..e6f6bda476e20de0f9779f907b95146771a33e86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace FTL {
 
+using namespace DFG;
+
 JSCall::JSCall()
     : m_stackmapID(UINT_MAX)
-    , m_node(nullptr)
-    , m_callLinkInfo(nullptr)
     , m_instructionOffset(UINT_MAX)
 {
 }
 
-JSCall::JSCall(unsigned stackmapID, DFG::Node* node)
-    : m_stackmapID(stackmapID)
-    , m_node(node)
-    , m_callLinkInfo(nullptr)
+JSCall::JSCall(unsigned stackmapID, Node* node)
+    : JSCallBase(
+        node->op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call,
+        node->origin.semantic)
+    , m_stackmapID(stackmapID)
     , m_instructionOffset(0)
 {
-}
-
-void JSCall::emit(CCallHelpers& jit)
-{
-    m_callLinkInfo = jit.codeBlock()->addCallLinkInfo();
-    
-    CCallHelpers::Jump slowPath = jit.branchPtrWithPatch(
-        CCallHelpers::NotEqual, GPRInfo::regT0, m_targetToCheck,
-        CCallHelpers::TrustedImmPtr(0));
-    
-    jit.loadPtr(
-        CCallHelpers::Address(GPRInfo::regT0, JSFunction::offsetOfScopeChain()),
-        GPRInfo::regT1);
-    jit.store64(
-        GPRInfo::regT1,
-        CCallHelpers::Address(
-            CCallHelpers::stackPointerRegister,
-            sizeof(Register) * (JSStack::ScopeChain - JSStack::CallerFrameAndPCSize)));
-    
-    m_fastCall = jit.nearCall();
-    CCallHelpers::Jump done = jit.jump();
-    
-    slowPath.link(&jit);
-    
-    jit.move(CCallHelpers::TrustedImmPtr(m_callLinkInfo), GPRInfo::regT2);
-    m_slowCall = jit.nearCall();
-    
-    done.link(&jit);
-}
-
-void JSCall::link(VM& vm, LinkBuffer& linkBuffer)
-{
-    ThunkGenerator generator = linkThunkGeneratorFor(
-        m_node->op() == DFG::Construct ? CodeForConstruct : CodeForCall,
-        MustPreserveRegisters);
-    
-    linkBuffer.link(
-        m_slowCall, FunctionPtr(vm.getCTIStub(generator).code().executableAddress()));
-    
-    m_callLinkInfo->isFTL = true;
-    m_callLinkInfo->callType = m_node->op() == DFG::Construct ? CallLinkInfo::Construct : CallLinkInfo::Call;
-    m_callLinkInfo->codeOrigin = m_node->origin.semantic;
-    m_callLinkInfo->callReturnLocation = linkBuffer.locationOfNearCall(m_slowCall);
-    m_callLinkInfo->hotPathBegin = linkBuffer.locationOf(m_targetToCheck);
-    m_callLinkInfo->hotPathOther = linkBuffer.locationOfNearCall(m_fastCall);
-    m_callLinkInfo->calleeGPR = GPRInfo::regT0;
+    ASSERT(node->op() == Call || node->op() == Construct);
 }
 
 } } // namespace JSC::FTL
index bc2758daa0193c6b1cfcbe7af6788e1f8dbc0512..2f5e64aea839db90aeac68afaddf351de0c8f5a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(FTL_JIT)
 
-#include "CCallHelpers.h"
-#include "CallLinkInfo.h"
-#include "CodeOrigin.h"
+#include "FTLJSCallBase.h"
 
 namespace JSC {
 
-class LinkBuffer;
-
 namespace DFG {
 struct Node;
 }
 
 namespace FTL {
 
-class JSCall {
+class JSCall : public JSCallBase {
 public:
     JSCall();
     JSCall(unsigned stackmapID, DFG::Node*);
     
-    void emit(CCallHelpers&);
-    void link(VM&, LinkBuffer&);
-    
     unsigned stackmapID() const { return m_stackmapID; }
     
     bool operator<(const JSCall& other) const
@@ -59,11 +52,6 @@ public:
     
 private:
     unsigned m_stackmapID;
-    DFG::Node* m_node;
-    CCallHelpers::DataLabelPtr m_targetToCheck;
-    CCallHelpers::Call m_fastCall;
-    CCallHelpers::Call m_slowCall;
-    CallLinkInfo* m_callLinkInfo;
 
 public:
     uint32_t m_instructionOffset;
diff --git a/ftl/FTLJSCallBase.cpp b/ftl/FTLJSCallBase.cpp
new file mode 100644 (file)
index 0000000..3279093
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLJSCallBase.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGNode.h"
+#include "LinkBuffer.h"
+
+namespace JSC { namespace FTL {
+
+using namespace DFG;
+
+JSCallBase::JSCallBase()
+    : m_type(CallLinkInfo::None)
+    , m_callLinkInfo(nullptr)
+{
+}
+
+JSCallBase::JSCallBase(CallLinkInfo::CallType type, CodeOrigin origin)
+    : m_type(type)
+    , m_origin(origin)
+    , m_callLinkInfo(nullptr)
+{
+}
+
+void JSCallBase::emit(CCallHelpers& jit)
+{
+    m_callLinkInfo = jit.codeBlock()->addCallLinkInfo();
+    
+    CCallHelpers::Jump slowPath = jit.branchPtrWithPatch(
+        CCallHelpers::NotEqual, GPRInfo::regT0, m_targetToCheck,
+        CCallHelpers::TrustedImmPtr(0));
+    
+    m_fastCall = jit.nearCall();
+    CCallHelpers::Jump done = jit.jump();
+    
+    slowPath.link(&jit);
+    
+    jit.move(CCallHelpers::TrustedImmPtr(m_callLinkInfo), GPRInfo::regT2);
+    m_slowCall = jit.nearCall();
+    
+    done.link(&jit);
+}
+
+void JSCallBase::link(VM& vm, LinkBuffer& linkBuffer)
+{
+    ThunkGenerator generator = linkThunkGeneratorFor(
+        CallLinkInfo::specializationKindFor(m_type), MustPreserveRegisters);
+    
+    linkBuffer.link(
+        m_slowCall, FunctionPtr(vm.getCTIStub(generator).code().executableAddress()));
+
+    m_callLinkInfo->setUpCallFromFTL(m_type, m_origin, linkBuffer.locationOfNearCall(m_slowCall),
+        linkBuffer.locationOf(m_targetToCheck), linkBuffer.locationOfNearCall(m_fastCall),
+        GPRInfo::regT0);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/ftl/FTLJSCallBase.h b/ftl/FTLJSCallBase.h
new file mode 100644 (file)
index 0000000..595ac69
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLJSCallBase_h
+#define FTLJSCallBase_h
+
+#if ENABLE(FTL_JIT)
+
+#include "CCallHelpers.h"
+#include "CallLinkInfo.h"
+#include "CodeOrigin.h"
+
+namespace JSC {
+
+class LinkBuffer;
+
+namespace DFG {
+struct Node;
+}
+
+namespace FTL {
+
+class JSCallBase {
+public:
+    JSCallBase();
+    JSCallBase(CallLinkInfo::CallType, CodeOrigin);
+    
+    void emit(CCallHelpers&);
+    void link(VM&, LinkBuffer&);
+    
+private:
+    CallLinkInfo::CallType m_type;
+    CodeOrigin m_origin;
+    CCallHelpers::DataLabelPtr m_targetToCheck;
+    CCallHelpers::Call m_fastCall;
+    CCallHelpers::Call m_slowCall;
+    CallLinkInfo* m_callLinkInfo;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLJSCallBase_h
+
diff --git a/ftl/FTLJSCallVarargs.cpp b/ftl/FTLJSCallVarargs.cpp
new file mode 100644 (file)
index 0000000..ac87a3c
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLJSCallVarargs.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGNode.h"
+#include "DFGOperations.h"
+#include "JSCInlines.h"
+#include "LinkBuffer.h"
+#include "ScratchRegisterAllocator.h"
+#include "SetupVarargsFrame.h"
+
+namespace JSC { namespace FTL {
+
+using namespace DFG;
+
+JSCallVarargs::JSCallVarargs()
+    : m_stackmapID(UINT_MAX)
+    , m_node(nullptr)
+    , m_instructionOffset(UINT_MAX)
+{
+}
+
+JSCallVarargs::JSCallVarargs(unsigned stackmapID, Node* node)
+    : m_stackmapID(stackmapID)
+    , m_node(node)
+    , m_callBase(
+        (node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs)
+        ? CallLinkInfo::ConstructVarargs : CallLinkInfo::CallVarargs,
+        node->origin.semantic)
+    , m_instructionOffset(0)
+{
+    ASSERT(
+        node->op() == CallVarargs || node->op() == CallForwardVarargs
+        || node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs);
+}
+
+unsigned JSCallVarargs::numSpillSlotsNeeded()
+{
+    return 4;
+}
+
+void JSCallVarargs::emit(CCallHelpers& jit, int32_t spillSlotsOffset)
+{
+    // We are passed three pieces of information:
+    // - The callee.
+    // - The arguments object, if it's not a forwarding call.
+    // - The "this" value, if it's a constructor call.
+
+    CallVarargsData* data = m_node->callVarargsData();
+    
+    GPRReg calleeGPR = GPRInfo::argumentGPR0;
+    
+    GPRReg argumentsGPR = InvalidGPRReg;
+    GPRReg thisGPR = InvalidGPRReg;
+    
+    bool forwarding = false;
+    
+    switch (m_node->op()) {
+    case CallVarargs:
+    case ConstructVarargs:
+        argumentsGPR = GPRInfo::argumentGPR1;
+        thisGPR = GPRInfo::argumentGPR2;
+        break;
+    case CallForwardVarargs:
+    case ConstructForwardVarargs:
+        thisGPR = GPRInfo::argumentGPR1;
+        forwarding = true;
+        break;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+    
+    const unsigned calleeSpillSlot = 0;
+    const unsigned argumentsSpillSlot = 1;
+    const unsigned thisSpillSlot = 2;
+    const unsigned stackPointerSpillSlot = 3;
+    
+    // Get some scratch registers.
+    RegisterSet usedRegisters;
+    usedRegisters.merge(RegisterSet::stackRegisters());
+    usedRegisters.merge(RegisterSet::reservedHardwareRegisters());
+    usedRegisters.merge(RegisterSet::calleeSaveRegisters());
+    usedRegisters.set(calleeGPR);
+    if (argumentsGPR != InvalidGPRReg)
+        usedRegisters.set(argumentsGPR);
+    ASSERT(thisGPR);
+    usedRegisters.set(thisGPR);
+    ScratchRegisterAllocator allocator(usedRegisters);
+    GPRReg scratchGPR1 = allocator.allocateScratchGPR();
+    GPRReg scratchGPR2 = allocator.allocateScratchGPR();
+    GPRReg scratchGPR3 = allocator.allocateScratchGPR();
+
+    RELEASE_ASSERT(!allocator.numberOfReusedRegisters());
+    
+    auto computeUsedStack = [&] (GPRReg targetGPR, unsigned extra) {
+        if (isARM64()) {
+            // Have to do this the weird way because $sp on ARM64 means zero when used in a subtraction.
+            jit.move(CCallHelpers::stackPointerRegister, targetGPR);
+            jit.negPtr(targetGPR);
+            jit.addPtr(GPRInfo::callFrameRegister, targetGPR);
+        } else {
+            jit.move(GPRInfo::callFrameRegister, targetGPR);
+            jit.subPtr(CCallHelpers::stackPointerRegister, targetGPR);
+        }
+        if (extra)
+            jit.subPtr(CCallHelpers::TrustedImm32(extra), targetGPR);
+        jit.urshiftPtr(CCallHelpers::Imm32(3), targetGPR);
+    };
+    
+    auto callWithExceptionCheck = [&] (void* callee) {
+        jit.move(CCallHelpers::TrustedImmPtr(callee), GPRInfo::nonPreservedNonArgumentGPR);
+        jit.call(GPRInfo::nonPreservedNonArgumentGPR);
+        m_exceptions.append(jit.emitExceptionCheck(AssemblyHelpers::NormalExceptionCheck, AssemblyHelpers::FarJumpWidth));
+    };
+    
+    if (isARM64()) {
+        jit.move(CCallHelpers::stackPointerRegister, scratchGPR1);
+        jit.storePtr(scratchGPR1, CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot));
+    } else
+        jit.storePtr(CCallHelpers::stackPointerRegister, CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot));
+
+    unsigned extraStack = sizeof(CallerFrameAndPC) +
+        WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*));
+
+    if (forwarding) {
+        CCallHelpers::JumpList slowCase;
+        computeUsedStack(scratchGPR2, 0);
+        emitSetupVarargsFrameFastCase(jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, m_node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+        
+        CCallHelpers::Jump done = jit.jump();
+        slowCase.link(&jit);
+        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsExecState();
+        callWithExceptionCheck(bitwise_cast<void*>(operationThrowStackOverflowForVarargs));
+        jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+        
+        done.link(&jit);
+        jit.move(calleeGPR, GPRInfo::regT0);
+    } else {
+        // Gotta spill the callee, arguments, and this because we will need them later and we will have some
+        // calls that clobber them.
+        jit.store64(calleeGPR, CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot));
+        jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
+        jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
+    
+        computeUsedStack(scratchGPR1, 0);
+        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsWithExecState(argumentsGPR, scratchGPR1, CCallHelpers::TrustedImm32(data->firstVarArgOffset));
+        callWithExceptionCheck(bitwise_cast<void*>(operationSizeFrameForVarargs));
+    
+        jit.move(GPRInfo::returnValueGPR, scratchGPR1);
+        computeUsedStack(scratchGPR2, extraStack);
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot), argumentsGPR);
+        emitSetVarargsFrame(jit, scratchGPR1, false, scratchGPR2, scratchGPR2);
+        jit.addPtr(CCallHelpers::TrustedImm32(-extraStack), scratchGPR2, CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsWithExecState(scratchGPR2, argumentsGPR, CCallHelpers::TrustedImm32(data->firstVarArgOffset), scratchGPR1);
+        callWithExceptionCheck(bitwise_cast<void*>(operationSetupVarargsFrame));
+    
+        jit.move(GPRInfo::returnValueGPR, scratchGPR2);
+
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
+    }
+    
+    jit.addPtr(CCallHelpers::TrustedImm32(sizeof(CallerFrameAndPC)), scratchGPR2, CCallHelpers::stackPointerRegister);
+
+    jit.store64(thisGPR, CCallHelpers::calleeArgumentSlot(0));
+    
+    // Henceforth we make the call. The base FTL call machinery expects the callee in regT0 and for the
+    // stack frame to already be set up, which it is.
+    jit.store64(GPRInfo::regT0, CCallHelpers::calleeFrameSlot(JSStack::Callee));
+    
+    m_callBase.emit(jit);
+    
+    // Undo the damage we've done.
+    if (isARM64()) {
+        GPRReg scratchGPRAtReturn = CCallHelpers::selectScratchGPR(GPRInfo::returnValueGPR);
+        jit.loadPtr(CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot), scratchGPRAtReturn);
+        jit.move(scratchGPRAtReturn, CCallHelpers::stackPointerRegister);
+    } else
+        jit.loadPtr(CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot), CCallHelpers::stackPointerRegister);
+}
+
+void JSCallVarargs::link(VM& vm, LinkBuffer& linkBuffer, CodeLocationLabel exceptionHandler)
+{
+    m_callBase.link(vm, linkBuffer);
+    linkBuffer.link(m_exceptions, exceptionHandler);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/ftl/FTLJSCallVarargs.h b/ftl/FTLJSCallVarargs.h
new file mode 100644 (file)
index 0000000..5128ff8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLJSCallVarargs_h
+#define FTLJSCallVarargs_h
+
+#if ENABLE(FTL_JIT)
+
+#include "FTLJSCallBase.h"
+
+namespace JSC {
+
+class LinkBuffer;
+
+namespace DFG {
+struct Node;
+}
+
+namespace FTL {
+
+class JSCallVarargs {
+public:
+    JSCallVarargs();
+    JSCallVarargs(unsigned stackmapID, DFG::Node*);
+    
+    DFG::Node* node() const { return m_node; }
+    
+    static unsigned numSpillSlotsNeeded();
+    
+    void emit(CCallHelpers&, int32_t spillSlotsOffset);
+    void link(VM&, LinkBuffer&, CodeLocationLabel exceptionHandler);
+    
+    unsigned stackmapID() const { return m_stackmapID; }
+    
+    bool operator<(const JSCallVarargs& other) const
+    {
+        return m_instructionOffset < other.m_instructionOffset;
+    }
+    
+private:
+    unsigned m_stackmapID;
+    DFG::Node* m_node;
+    JSCallBase m_callBase;
+    CCallHelpers::JumpList m_exceptions;
+
+public:
+    uint32_t m_instructionOffset;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLJSCallVarargs_h
+
index d23cecea030808d135859f94a7dd7a149caa6ca8..188afe5f0c674b63c33acb3d730445583521f6fb 100644 (file)
@@ -63,11 +63,13 @@ void link(State& state)
     if (!graph.m_plan.inlineCallFrames->isEmpty())
         state.jitCode->common.inlineCallFrames = graph.m_plan.inlineCallFrames;
     
+    graph.registerFrozenValues();
+
     // Create the entrypoint. Note that we use this entrypoint totally differently
     // depending on whether we're doing OSR entry or not.
     CCallHelpers jit(&vm, codeBlock);
     
-    OwnPtr<LinkBuffer> linkBuffer;
+    std::unique_ptr<LinkBuffer> linkBuffer;
 
     CCallHelpers::Address frame = CCallHelpers::Address(
         CCallHelpers::stackPointerRegister, -static_cast<int32_t>(AssemblyHelpers::prologueStackPointerDelta()));
@@ -96,8 +98,6 @@ void link(State& state)
             
             for (size_t nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
-                if (!node->willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
-                    continue;
                 
                 Profiler::OriginStack stack;
                 
@@ -126,13 +126,13 @@ void link(State& state)
         
         out.print("    Disassembly:\n");
         for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) {
-            if (state.codeSectionNames[i] != "__text")
+            if (state.codeSectionNames[i] != SECTION_NAME("text"))
                 continue;
             
-                ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
-                disassemble(
-                    MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),
-                    "      ", out, LLVMSubset);
+            ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
+            disassemble(
+                MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),
+                "      ", out, LLVMSubset);
         }
         compilation->addDescription(Profiler::OriginStack(), out.toCString());
         out.reset();
@@ -169,15 +169,21 @@ void link(State& state)
         jit.emitFunctionEpilogue();
         mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::regT0));
         jit.emitFunctionPrologue();
-        jit.move(CCallHelpers::TrustedImmPtr(vm.arityCheckFailReturnThunks->returnPCsFor(vm, codeBlock->numParameters())), GPRInfo::regT7);
+        CodeLocationLabel* arityThunkLabels =
+            vm.arityCheckFailReturnThunks->returnPCsFor(vm, codeBlock->numParameters());
+        jit.move(CCallHelpers::TrustedImmPtr(arityThunkLabels), GPRInfo::regT7);
         jit.loadPtr(CCallHelpers::BaseIndex(GPRInfo::regT7, GPRInfo::regT0, CCallHelpers::timesPtr()), GPRInfo::regT7);
         CCallHelpers::Call callArityFixup = jit.call();
         jit.emitFunctionEpilogue();
         mainPathJumps.append(jit.jump());
 
-        linkBuffer = adoptPtr(new LinkBuffer(vm, jit, codeBlock, JITCompilationMustSucceed));
+        linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
+        if (linkBuffer->didFailToAllocate()) {
+            state.allocationFailed = true;
+            return;
+        }
         linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
-        linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixup)).code().executableAddress()));
+        linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
         linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
 
         state.jitCode->initializeAddressForCall(MacroAssemblerCodePtr(bitwise_cast<void*>(state.generatedFunction)));
@@ -193,7 +199,11 @@ void link(State& state)
         jit.emitFunctionEpilogue();
         CCallHelpers::Jump mainPathJump = jit.jump();
         
-        linkBuffer = adoptPtr(new LinkBuffer(vm, jit, codeBlock, JITCompilationMustSucceed));
+        linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
+        if (linkBuffer->didFailToAllocate()) {
+            state.allocationFailed = true;
+            return;
+        }
         linkBuffer->link(mainPathJump, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
 
         state.jitCode->initializeAddressForCall(linkBuffer->locationOf(start));
@@ -205,7 +215,7 @@ void link(State& state)
         break;
     }
     
-    state.finalizer->entrypointLinkBuffer = linkBuffer.release();
+    state.finalizer->entrypointLinkBuffer = WTF::move(linkBuffer);
     state.finalizer->function = state.generatedFunction;
     state.finalizer->jitCode = state.jitCode;
 }
index ecb1513f808dbc3167f2fdffaf72d09d5bbe64fc..64b0abdc09a9efb18fc6b0343c8636a48713cbe1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "CodeBlockWithJITType.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGInPlaceAbstractState.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "DFGOSRExitFuzz.h"
+#include "DirectArguments.h"
 #include "FTLAbstractHeapRepository.h"
 #include "FTLAvailableRecovery.h"
 #include "FTLForOSREntryJITCode.h"
 #include "FTLFormattedValue.h"
 #include "FTLInlineCacheSize.h"
 #include "FTLLoweredNodeValue.h"
+#include "FTLOperations.h"
 #include "FTLOutput.h"
 #include "FTLThunks.h"
 #include "FTLWeightedTarget.h"
-#include "OperandsInlines.h"
 #include "JSCInlines.h"
+#include "JSLexicalEnvironment.h"
+#include "OperandsInlines.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 #include "VirtualRegister.h"
 #include <atomic>
+#include <dlfcn.h>
+#include <llvm/InitializeLLVM.h>
+#include <unordered_set>
 #include <wtf/ProcessID.h>
 
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+#include "BundlePath.h"
+#endif
+
 namespace JSC { namespace FTL {
 
 using namespace DFG;
 
-static std::atomic<int> compileCounter;
+namespace {
+
+std::atomic<int> compileCounter;
+
+#if ASSERT_DISABLED
+NO_RETURN_DUE_TO_CRASH static void ftlUnreachable()
+{
+    CRASH();
+}
+#else
+NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
+    CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
+{
+    dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
+    if (nodeIndex != UINT_MAX)
+        dataLog(", node @", nodeIndex);
+    dataLog(".\n");
+    CRASH();
+}
+#endif
 
 // Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
 // significantly less dead code.
@@ -68,21 +101,17 @@ public:
     LowerDFGToLLVM(State& state)
         : m_graph(state.graph)
         , m_ftlState(state)
-        , m_loweringSucceeded(true)
         , m_heaps(state.context)
         , m_out(state.context)
-        , m_availability(OperandsLike, state.graph.block(0)->variablesAtHead)
         , m_state(state.graph)
         , m_interpreter(state.graph, m_state)
         , m_stackmapIDs(0)
+        , m_tbaaKind(mdKindID(state.context, "tbaa"))
+        , m_tbaaStructKind(mdKindID(state.context, "tbaa.struct"))
     {
     }
-
-
-#define LOWERING_FAILED(node, reason)                                  \
-    loweringFailed((node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason));
-
-    bool lower()
+    
+    void lower()
     {
         CString name;
         if (verboseCompilationEnabled()) {
@@ -95,7 +124,7 @@ public:
         m_graph.m_dominators.computeIfNecessary(m_graph);
         
         m_ftlState.module =
-            llvm->ModuleCreateWithNameInContext(name.data(), m_ftlState.context);
+            moduleCreateWithNameInContext(name.data(), m_ftlState.context);
         
         m_ftlState.function = addFunction(
             m_ftlState.module, name.data(), functionType(m_out.int64));
@@ -114,6 +143,8 @@ public:
         m_prologue = FTL_NEW_BLOCK(m_out, ("Prologue"));
         LBasicBlock stackOverflow = FTL_NEW_BLOCK(m_out, ("Stack overflow"));
         m_handleExceptions = FTL_NEW_BLOCK(m_out, ("Handle Exceptions"));
+        
+        LBasicBlock checkArguments = FTL_NEW_BLOCK(m_out, ("Check arguments"));
 
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
             m_highBlock = m_graph.block(blockIndex);
@@ -124,19 +155,71 @@ public:
         
         m_out.appendTo(m_prologue, stackOverflow);
         createPhiVariables();
+
+        auto preOrder = m_graph.blocksInPreOrder();
+
+        int maxNumberOfArguments = -1;
+        for (BasicBlock* block : preOrder) {
+            for (unsigned nodeIndex = block->size(); nodeIndex--; ) {
+                Node* node = block->at(nodeIndex);
+                switch (node->op()) {
+                case NativeCall:
+                case NativeConstruct: {
+                    int numArgs = node->numChildren();
+                    if (numArgs > maxNumberOfArguments)
+                        maxNumberOfArguments = numArgs;
+                    break;
+                }
+                default:
+                    break;
+                }
+            }
+        }
+        
+        if (maxNumberOfArguments >= 0) {
+            m_execState = m_out.alloca(arrayType(m_out.int64, JSStack::CallFrameHeaderSize + maxNumberOfArguments));
+            m_execStorage = m_out.ptrToInt(m_execState, m_out.intPtr);        
+        }
+
         LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
+        
         m_captured = m_out.add(
             m_out.ptrToInt(capturedAlloca, m_out.intPtr),
             m_out.constIntPtr(m_graph.m_nextMachineLocal * sizeof(Register)));
         
-        // We should not create any alloca's after this point, since they will cease to
-        // be mem2reg candidates.
-        
         m_ftlState.capturedStackmapID = m_stackmapIDs++;
         m_out.call(
             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.capturedStackmapID),
             m_out.int32Zero, capturedAlloca);
         
+        // If we have any CallVarargs then we nee to have a spill slot for it.
+        bool hasVarargs = false;
+        for (BasicBlock* block : preOrder) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case CallVarargs:
+                case CallForwardVarargs:
+                case ConstructVarargs:
+                case ConstructForwardVarargs:
+                    hasVarargs = true;
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        if (hasVarargs) {
+            LValue varargsSpillSlots = m_out.alloca(
+                arrayType(m_out.int64, JSCallVarargs::numSpillSlotsNeeded()));
+            m_ftlState.varargsSpillSlotsStackmapID = m_stackmapIDs++;
+            m_out.call(
+                m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.varargsSpillSlotsStackmapID),
+                m_out.int32Zero, varargsSpillSlots);
+        }
+        
+        // We should not create any alloca's after this point, since they will cease to
+        // be mem2reg candidates.
+        
         m_callFrame = m_out.ptrToInt(
             m_out.call(m_out.frameAddressIntrinsic(), m_out.int32Zero), m_out.intPtr);
         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
@@ -145,7 +228,7 @@ public:
         m_out.storePtr(m_out.constIntPtr(codeBlock()), addressFor(JSStack::CodeBlock));
         
         m_out.branch(
-            didOverflowStack(), rarely(stackOverflow), usually(lowBlock(m_graph.block(0))));
+            didOverflowStack(), rarely(stackOverflow), usually(checkArguments));
         
         m_out.appendTo(stackOverflow, m_handleExceptions);
         m_out.call(m_out.operation(operationThrowStackOverflowError), m_callFrame, m_out.constIntPtr(codeBlock()));
@@ -155,23 +238,60 @@ public:
             m_out.constInt32(MacroAssembler::maxJumpReplacementSize()));
         m_out.unreachable();
         
-        m_out.appendTo(m_handleExceptions, lowBlock(m_graph.block(0)));
+        m_out.appendTo(m_handleExceptions, checkArguments);
         m_ftlState.handleExceptionStackmapID = m_stackmapIDs++;
         m_out.call(
             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.handleExceptionStackmapID),
             m_out.constInt32(MacroAssembler::maxJumpReplacementSize()));
         m_out.unreachable();
         
-        if (!m_loweringSucceeded)
-            return m_loweringSucceeded;
-
-        Vector<BasicBlock*> depthFirst;
-        m_graph.getBlocksInDepthFirstOrder(depthFirst);
-        for (unsigned i = 0; i < depthFirst.size(); ++i) {
-            compileBlock(depthFirst[i]);
-            if (!m_loweringSucceeded)
-                return m_loweringSucceeded;
+        m_out.appendTo(checkArguments, lowBlock(m_graph.block(0)));
+        availabilityMap().clear();
+        availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
+        for (unsigned i = codeBlock()->numParameters(); i--;) {
+            availabilityMap().m_locals.argument(i) =
+                Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
+        }
+        m_codeOriginForExitTarget = CodeOrigin(0);
+        m_codeOriginForExitProfile = CodeOrigin(0);
+        m_node = nullptr;
+        for (unsigned i = codeBlock()->numParameters(); i--;) {
+            Node* node = m_graph.m_arguments[i];
+            VirtualRegister operand = virtualRegisterForArgument(i);
+            
+            LValue jsValue = m_out.load64(addressFor(operand));
+            
+            if (node) {
+                DFG_ASSERT(m_graph, node, operand == node->stackAccessData()->machineLocal);
+                
+                // This is a hack, but it's an effective one. It allows us to do CSE on the
+                // primordial load of arguments. This assumes that the GetLocal that got put in
+                // place of the original SetArgument doesn't have any effects before it. This
+                // should hold true.
+                m_loadedArgumentValues.add(node, jsValue);
+            }
+            
+            switch (m_graph.m_argumentFormats[i]) {
+            case FlushedInt32:
+                speculate(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
+                break;
+            case FlushedBoolean:
+                speculate(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
+                break;
+            case FlushedCell:
+                speculate(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
+                break;
+            case FlushedJSValue:
+                break;
+            default:
+                DFG_CRASH(m_graph, node, "Bad flush format for argument");
+                break;
+            }
         }
+        m_out.jump(lowBlock(m_graph.block(0)));
+        
+        for (BasicBlock* block : preOrder)
+            compileBlock(block);
         
         if (Options::dumpLLVMIR())
             dumpModule(m_ftlState.module);
@@ -180,8 +300,6 @@ public:
             m_ftlState.dumpState("after lowering");
         if (validationEnabled())
             verifyModule(m_ftlState.module);
-
-        return m_loweringSucceeded;
     }
 
 private:
@@ -214,8 +332,8 @@ private:
                     type = m_out.int64;
                     break;
                 default:
-                    LOWERING_FAILED(node, "Bad Phi node result type");
-                    return;
+                    DFG_CRASH(m_graph, node, "Bad Phi node result type");
+                    break;
                 }
                 m_phis.add(node, buildAlloca(m_out.m_builder, type));
             }
@@ -249,14 +367,16 @@ private:
         m_out.appendTo(lowBlock, m_nextLowBlock);
         
         if (Options::ftlCrashes())
-            m_out.crashNonTerminal();
+            m_out.trap();
         
         if (!m_highBlock->cfaHasVisited) {
-            m_out.crash();
+            if (verboseCompilationEnabled())
+                dataLog("Bailing because CFA didn't reach.\n");
+            crash(m_highBlock->index, UINT_MAX);
             return;
         }
         
-        initializeOSRExitStateForBlock();
+        m_availabilityCalculator.beginBlock(m_highBlock);
         
         m_state.reset();
         m_state.beginBasicBlock(m_highBlock);
@@ -266,11 +386,34 @@ private:
                 break;
         }
     }
-    
+
+    void safelyInvalidateAfterTermination()
+    {
+        if (verboseCompilationEnabled())
+            dataLog("Bailing.\n");
+        crash();
+
+        // Invalidate dominated blocks. Under normal circumstances we would expect
+        // them to be invalidated already. But you can have the CFA become more
+        // precise over time because the structures of objects change on the main
+        // thread. Failing to do this would result in weird crashes due to a value
+        // being used but not defined. Race conditions FTW!
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* target = m_graph.block(blockIndex);
+            if (!target)
+                continue;
+            if (m_graph.m_dominators.dominates(m_highBlock, target)) {
+                if (verboseCompilationEnabled())
+                    dataLog("Block ", *target, " will bail also.\n");
+                target->cfaHasVisited = false;
+            }
+        }
+    }
+
     bool compileNode(unsigned nodeIndex)
     {
         if (!m_state.isValid()) {
-            m_out.unreachable();
+            safelyInvalidateAfterTermination();
             return false;
         }
         
@@ -283,7 +426,7 @@ private:
         
         m_availableRecoveries.resize(0);
         
-        bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
+        m_interpreter.startExecuting();
         
         switch (m_node->op()) {
         case Upsilon:
@@ -300,15 +443,12 @@ private:
         case Int52Constant:
             compileInt52Constant();
             break;
-        case WeakJSConstant:
-            compileWeakJSConstant();
-            break;
-        case PhantomArguments:
-            compilePhantomArguments();
-            break;
         case DoubleRep:
             compileDoubleRep();
             break;
+        case DoubleAsInt32:
+            compileDoubleAsInt32();
+            break;
         case ValueRep:
             compileValueRep();
             break;
@@ -321,33 +461,17 @@ private:
         case BooleanToNumber:
             compileBooleanToNumber();
             break;
-        case GetArgument:
-            compileGetArgument();
-            break;
         case ExtractOSREntryLocal:
             compileExtractOSREntryLocal();
             break;
-        case GetLocal:
-            compileGetLocal();
-            break;
-        case SetLocal:
-            compileSetLocal();
-            break;
-        case MovHint:
-            compileMovHint();
-            break;
-        case GetMyArgumentsLength:
-            compileGetMyArgumentsLength();
-            break;
-        case GetMyArgumentByVal:
-            compileGetMyArgumentByVal();
+        case GetStack:
+            compileGetStack();
             break;
-        case ZombieHint:
-            compileZombieHint();
+        case PutStack:
+            compilePutStack();
             break;
-        case Phantom:
-        case HardPhantom:
-            compilePhantom();
+        case Check:
+            compileNoOp();
             break;
         case ToThis:
             compileToThis();
@@ -359,6 +483,9 @@ private:
         case ArithSub:
             compileArithAddOrSub();
             break;
+        case ArithClz32:
+            compileArithClz32();
+            break;
         case ArithMul:
             compileArithMul();
             break;
@@ -381,9 +508,18 @@ private:
         case ArithCos:
             compileArithCos();
             break;
+        case ArithPow:
+            compileArithPow();
+            break;
+        case ArithRound:
+            compileArithRound();
+            break;
         case ArithSqrt:
             compileArithSqrt();
             break;
+        case ArithLog:
+            compileArithLog();
+            break;
         case ArithFRound:
             compileArithFRound();
             break;
@@ -414,14 +550,17 @@ private:
         case CheckStructure:
             compileCheckStructure();
             break;
-        case StructureTransitionWatchpoint:
-            compileStructureTransitionWatchpoint();
+        case CheckCell:
+            compileCheckCell();
+            break;
+        case CheckNotEmpty:
+            compileCheckNotEmpty();
             break;
-        case CheckFunction:
-            compileCheckFunction();
+        case CheckBadCell:
+            compileCheckBadCell();
             break;
-        case CheckExecutable:
-            compileCheckExecutable();
+        case GetExecutable:
+            compileGetExecutable();
             break;
         case ArrayifyToStructure:
             compileArrayifyToStructure();
@@ -429,14 +568,14 @@ private:
         case PutStructure:
             compilePutStructure();
             break;
-        case PhantomPutStructure:
-            compilePhantomPutStructure();
-            break;
         case GetById:
             compileGetById();
             break;
-        case PutByIdDirect:
+        case In:
+            compileIn();
+            break;
         case PutById:
+        case PutByIdDirect:
             compilePutById();
             break;
         case GetButterfly:
@@ -460,6 +599,9 @@ private:
         case GetByVal:
             compileGetByVal();
             break;
+        case GetMyArgumentByVal:
+            compileGetMyArgumentByVal();
+            break;
         case PutByVal:
         case PutByValAlias:
         case PutByValDirect:
@@ -471,6 +613,21 @@ private:
         case ArrayPop:
             compileArrayPop();
             break;
+        case CreateActivation:
+            compileCreateActivation();
+            break;
+        case NewFunction:
+            compileNewFunction();
+            break;
+        case CreateDirectArguments:
+            compileCreateDirectArguments();
+            break;
+        case CreateScopedArguments:
+            compileCreateScopedArguments();
+            break;
+        case CreateClonedArguments:
+            compileCreateClonedArguments();
+            break;
         case NewObject:
             compileNewObject();
             break;
@@ -493,7 +650,8 @@ private:
             compileReallocatePropertyStorage();
             break;
         case ToString:
-            compileToString();
+        case CallStringConstructor:
+            compileToStringOrCallStringConstructor();
             break;
         case ToPrimitive:
             compileToPrimitive();
@@ -508,8 +666,15 @@ private:
             compileStringCharCodeAt();
             break;
         case GetByOffset:
+        case GetGetterSetterByOffset:
             compileGetByOffset();
             break;
+        case GetGetter:
+            compileGetGetter();
+            break;
+        case GetSetter:
+            compileGetSetter();
+            break;
         case MultiGetByOffset:
             compileMultiGetByOffset();
             break;
@@ -531,24 +696,27 @@ private:
         case GetCallee:
             compileGetCallee();
             break;
+        case GetArgumentCount:
+            compileGetArgumentCount();
+            break;
         case GetScope:
             compileGetScope();
             break;
-        case GetMyScope:
-            compileGetMyScope();
-            break;
         case SkipScope:
             compileSkipScope();
             break;
-        case GetClosureRegisters:
-            compileGetClosureRegisters();
-            break;
         case GetClosureVar:
             compileGetClosureVar();
             break;
         case PutClosureVar:
             compilePutClosureVar();
             break;
+        case GetFromArguments:
+            compileGetFromArguments();
+            break;
+        case PutToArguments:
+            compilePutToArguments();
+            break;
         case CompareEq:
             compileCompareEq();
             break;
@@ -577,6 +745,24 @@ private:
         case Construct:
             compileCallOrConstruct();
             break;
+        case CallVarargs:
+        case CallForwardVarargs:
+        case ConstructVarargs:
+        case ConstructForwardVarargs:
+            compileCallOrConstructVarargs();
+            break;
+        case LoadVarargs:
+            compileLoadVarargs();
+            break;
+        case ForwardVarargs:
+            compileForwardVarargs();
+            break;
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+        case NativeCall:
+        case NativeConstruct:
+            compileNativeCallOrConstruct();
+            break;
+#endif
         case Jump:
             compileJump();
             break;
@@ -599,9 +785,6 @@ private:
         case InvalidationPoint:
             compileInvalidationPoint();
             break;
-        case CheckArgumentsNotCreated:
-            compileCheckArgumentsNotCreated();
-            break;
         case IsUndefined:
             compileIsUndefined();
             break;
@@ -617,9 +800,15 @@ private:
         case IsObject:
             compileIsObject();
             break;
+        case IsObjectOrNull:
+            compileIsObjectOrNull();
+            break;
         case IsFunction:
             compileIsFunction();
             break;
+        case TypeOf:
+            compileTypeOf();
+            break;
         case CheckHasInstance:
             compileCheckHasInstance();
             break;
@@ -632,27 +821,71 @@ private:
         case StoreBarrier:
             compileStoreBarrier();
             break;
-        case StoreBarrierWithNullCheck:
-            compileStoreBarrierWithNullCheck();
+        case HasIndexedProperty:
+            compileHasIndexedProperty();
+            break;
+        case HasGenericProperty:
+            compileHasGenericProperty();
+            break;
+        case HasStructureProperty:
+            compileHasStructureProperty();
+            break;
+        case GetDirectPname:
+            compileGetDirectPname();
             break;
+        case GetEnumerableLength:
+            compileGetEnumerableLength();
+            break;
+        case GetPropertyEnumerator:
+            compileGetPropertyEnumerator();
+            break;
+        case GetEnumeratorStructurePname:
+            compileGetEnumeratorStructurePname();
+            break;
+        case GetEnumeratorGenericPname:
+            compileGetEnumeratorGenericPname();
+            break;
+        case ToIndexString:
+            compileToIndexString();
+            break;
+        case CheckStructureImmediate:
+            compileCheckStructureImmediate();
+            break;
+        case MaterializeNewObject:
+            compileMaterializeNewObject();
+            break;
+        case MaterializeCreateActivation:
+            compileMaterializeCreateActivation();
+            break;
+
         case PhantomLocal:
-        case SetArgument:
         case LoopHint:
-        case VariableWatchpoint:
-        case FunctionReentryWatchpoint:
-        case TypedArrayWatchpoint:
-        case AllocationProfileWatchpoint:
+        case MovHint:
+        case ZombieHint:
+        case PhantomNewObject:
+        case PhantomNewFunction:
+        case PhantomCreateActivation:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case PutHint:
+        case BottomValue:
+        case KillStack:
             break;
         default:
-            LOWERING_FAILED(m_node, "Unrecognized node in FTL backend");
+            DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
             break;
         }
         
-        if (!m_loweringSucceeded)
+        if (m_node->isTerminal())
+            return false;
+        
+        if (!m_state.isValid()) {
+            safelyInvalidateAfterTermination();
             return false;
+        }
 
-        if (shouldExecuteEffects)
-            m_interpreter.executeEffects(nodeIndex);
+        m_availabilityCalculator.executeNode(m_node);
+        m_interpreter.executeEffects(nodeIndex);
         
         return true;
     }
@@ -681,7 +914,7 @@ private:
             m_out.set(lowJSValue(m_node->child1()), destination);
             break;
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -707,40 +940,134 @@ private:
             setJSValue(m_out.get(source));
             break;
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
     
     void compileDoubleConstant()
     {
-        setDouble(m_out.constDouble(m_graph.valueOfNumberConstant(m_node)));
+        setDouble(m_out.constDouble(m_node->asNumber()));
     }
     
     void compileInt52Constant()
     {
-        int64_t value = m_graph.valueOfJSConstant(m_node).asMachineInt();
+        int64_t value = m_node->asMachineInt();
         
         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
         setStrictInt52(m_out.constInt64(value));
     }
 
-    void compileWeakJSConstant()
-    {
-        setJSValue(weakPointer(m_node->weakConstant()));
-    }
-    
-    void compilePhantomArguments()
-    {
-        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
-    }
-    
     void compileDoubleRep()
     {
         switch (m_node->child1().useKind()) {
+        case RealNumberUse: {
+            LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
+            
+            LValue doubleValue = unboxDouble(value);
+            
+            LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep RealNumberUse int case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep continuation"));
+            
+            ValueFromBlock fastResult = m_out.anchor(doubleValue);
+            m_out.branch(
+                m_out.doubleEqual(doubleValue, doubleValue),
+                usually(continuation), rarely(intCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
+            
+            FTL_TYPE_CHECK(
+                jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
+                isNotInt32(value, provenType(m_node->child1()) & ~SpecFullDouble));
+            ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            
+            setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
+            return;
+        }
+            
+        case NotCellUse:
         case NumberUse: {
+            bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
+            
             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
-            setDouble(jsValueToDouble(m_node->child1(), value));
+
+            LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
+            LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing double case"));
+            LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
+            LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing undefined case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
+            
+            m_out.branch(
+                isNotInt32(value, provenType(m_node->child1())),
+                unsure(doubleTesting), unsure(intCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
+            
+            ValueFromBlock intToDouble = m_out.anchor(
+                m_out.intToDouble(unboxInt32(value)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(doubleTesting, doubleCase);
+            LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
+            m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
+
+            m_out.appendTo(doubleCase, nonDoubleCase);
+            ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
+            m_out.jump(continuation);
+
+            if (shouldConvertNonNumber) {
+                LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting undefined case"));
+                LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing null case"));
+                LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting null case"));
+                LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing boolean true case"));
+                LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean true case"));
+                LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean false case"));
+
+                m_out.appendTo(nonDoubleCase, undefinedCase);
+                LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
+                m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
+
+                m_out.appendTo(undefinedCase, testNullCase);
+                ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
+                m_out.jump(continuation);
+
+                m_out.appendTo(testNullCase, nullCase);
+                LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
+                m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
+
+                m_out.appendTo(nullCase, testBooleanTrueCase);
+                ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
+                m_out.jump(continuation);
+
+                m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
+                LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
+                m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
+
+                m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
+                ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
+                m_out.jump(continuation);
+
+                m_out.appendTo(convertBooleanFalseCase, continuation);
+
+                LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
+                FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
+                ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
+                m_out.jump(continuation);
+
+                m_out.appendTo(continuation, lastNext);
+                setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
+                return;
+            }
+            m_out.appendTo(nonDoubleCase, continuation);
+            FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
+            m_out.unreachable();
+
+            m_out.appendTo(continuation, lastNext);
+
+            setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
             return;
         }
             
@@ -750,10 +1077,16 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
         }
     }
-    
+
+    void compileDoubleAsInt32()
+    {
+        LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
+        setInt32(integerValue);
+    }
+
     void compileValueRep()
     {
         switch (m_node->child1().useKind()) {
@@ -775,7 +1108,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
         }
     }
     
@@ -799,7 +1132,7 @@ private:
             return;
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            RELEASE_ASSERT_NOT_REACHED();
         }
     }
     
@@ -838,7 +1171,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -854,11 +1187,18 @@ private:
         case UntypedUse: {
             LValue value = lowJSValue(m_node->child1());
             
+            if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
+                setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
+                return;
+            }
+            
             LBasicBlock booleanCase = FTL_NEW_BLOCK(m_out, ("BooleanToNumber boolean case"));
             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("BooleanToNumber continuation"));
             
             ValueFromBlock notBooleanResult = m_out.anchor(value);
-            m_out.branch(isBoolean(value), unsure(booleanCase), unsure(continuation));
+            m_out.branch(
+                isBoolean(value, provenType(m_node->child1())),
+                unsure(booleanCase), unsure(continuation));
             
             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
@@ -871,41 +1211,11 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad flush format");
+            RELEASE_ASSERT_NOT_REACHED();
             return;
         }
     }
 
-    void compileGetArgument()
-    {
-        VariableAccessData* variable = m_node->variableAccessData();
-        VirtualRegister operand = variable->machineLocal();
-        RELEASE_ASSERT(operand.isArgument());
-
-        LValue jsValue = m_out.load64(addressFor(operand));
-
-        switch (useKindFor(variable->flushFormat())) {
-        case Int32Use:
-            speculate(BadType, jsValueValue(jsValue), m_node, isNotInt32(jsValue));
-            setInt32(unboxInt32(jsValue));
-            break;
-        case CellUse:
-            speculate(BadType, jsValueValue(jsValue), m_node, isNotCell(jsValue));
-            setJSValue(jsValue);
-            break;
-        case BooleanUse:
-            speculate(BadType, jsValueValue(jsValue), m_node, isNotBoolean(jsValue));
-            setBoolean(unboxBoolean(jsValue));
-            break;
-        case UntypedUse:
-            setJSValue(jsValue);
-            break;
-        default:
-            LOWERING_FAILED(m_node, "Bad use kind");
-            break;
-        }
-    }
-    
     void compileExtractOSREntryLocal()
     {
         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
@@ -913,53 +1223,58 @@ private:
         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
     }
     
-    void compileGetLocal()
+    void compileGetStack()
     {
-        // GetLocals arise only for captured variables.
+        // GetLocals arise only for captured variables and arguments. For arguments, we might have
+        // already loaded it.
+        if (LValue value = m_loadedArgumentValues.get(m_node)) {
+            setJSValue(value);
+            return;
+        }
         
-        VariableAccessData* variable = m_node->variableAccessData();
-        AbstractValue& value = m_state.variables().operand(variable->local());
+        StackAccessData* data = m_node->stackAccessData();
+        AbstractValue& value = m_state.variables().operand(data->local);
         
-        RELEASE_ASSERT(variable->isCaptured());
+        DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
+        DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
         
         if (isInt32Speculation(value.m_type))
-            setInt32(m_out.load32(payloadFor(variable->machineLocal())));
+            setInt32(m_out.load32(payloadFor(data->machineLocal)));
         else
-            setJSValue(m_out.load64(addressFor(variable->machineLocal())));
+            setJSValue(m_out.load64(addressFor(data->machineLocal)));
     }
     
-    void compileSetLocal()
+    void compilePutStack()
     {
-        VariableAccessData* variable = m_node->variableAccessData();
-        switch (variable->flushFormat()) {
-        case FlushedJSValue:
-        case FlushedArguments: {
+        StackAccessData* data = m_node->stackAccessData();
+        switch (data->format) {
+        case FlushedJSValue: {
             LValue value = lowJSValue(m_node->child1());
-            m_out.store64(value, addressFor(variable->machineLocal()));
+            m_out.store64(value, addressFor(data->machineLocal));
             break;
         }
             
         case FlushedDouble: {
             LValue value = lowDouble(m_node->child1());
-            m_out.storeDouble(value, addressFor(variable->machineLocal()));
+            m_out.storeDouble(value, addressFor(data->machineLocal));
             break;
         }
             
         case FlushedInt32: {
             LValue value = lowInt32(m_node->child1());
-            m_out.store32(value, payloadFor(variable->machineLocal()));
+            m_out.store32(value, payloadFor(data->machineLocal));
             break;
         }
             
         case FlushedInt52: {
             LValue value = lowInt52(m_node->child1());
-            m_out.store64(value, addressFor(variable->machineLocal()));
+            m_out.store64(value, addressFor(data->machineLocal));
             break;
         }
             
         case FlushedCell: {
             LValue value = lowCell(m_node->child1());
-            m_out.store64(value, addressFor(variable->machineLocal()));
+            m_out.store64(value, addressFor(data->machineLocal));
             break;
         }
             
@@ -967,33 +1282,17 @@ private:
             speculateBoolean(m_node->child1());
             m_out.store64(
                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
-                addressFor(variable->machineLocal()));
+                addressFor(data->machineLocal));
             break;
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad flush format for argument");
-            return;
+            DFG_CRASH(m_graph, m_node, "Bad flush format");
+            break;
         }
-        
-        m_availability.operand(variable->local()) = Availability(variable->flushedAt());
-    }
-    
-    void compileMovHint()
-    {
-        ASSERT(m_node->containsMovHint());
-        ASSERT(m_node->op() != ZombieHint);
-        
-        VirtualRegister operand = m_node->unlinkedLocal();
-        m_availability.operand(operand) = Availability(m_node->child1().node());
-    }
-    
-    void compileZombieHint()
-    {
-        m_availability.operand(m_node->unlinkedLocal()) = Availability::unavailable();
     }
     
-    void compilePhantom()
+    void compileNoOp()
     {
         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
     }
@@ -1006,7 +1305,8 @@ private:
         LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ToThis slow case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ToThis continuation"));
         
-        m_out.branch(isCell(value), usually(isCellCase), rarely(slowCase));
+        m_out.branch(
+            isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
         ValueFromBlock fastResult = m_out.anchor(value);
@@ -1029,8 +1329,8 @@ private:
     void compileValueAdd()
     {
         J_JITOperation_EJJ operation;
-        if (!(m_state.forNode(m_node->child1()).m_type & SpecFullNumber)
-            && !(m_state.forNode(m_node->child2()).m_type & SpecFullNumber))
+        if (!(provenType(m_node->child1()) & SpecFullNumber)
+            && !(provenType(m_node->child2()) & SpecFullNumber))
             operation = operationValueAddNotNumber;
         else
             operation = operationValueAdd;
@@ -1090,8 +1390,8 @@ private:
         }
             
         case Int52RepUse: {
-            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
-                && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
+            if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)
+                && !abstractValue(m_node->child2()).couldBeType(SpecInt52)) {
                 Int52Kind kind;
                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
                 LValue right = lowInt52(m_node->child2(), kind);
@@ -1148,10 +1448,17 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
+
+    void compileArithClz32()
+    {
+        LValue operand = lowInt32(m_node->child1());
+        LValue isZeroUndef = m_out.booleanFalse;
+        setInt32(m_out.ctlz32(operand, isZeroUndef));
+    }
     
     void compileArithMul()
     {
@@ -1222,7 +1529,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1325,7 +1632,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1423,7 +1730,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1474,7 +1781,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1500,7 +1807,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1509,23 +1816,119 @@ private:
 
     void compileArithCos() { setDouble(m_out.doubleCos(lowDouble(m_node->child1()))); }
 
-    void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
-    
-    void compileArithFRound()
-    {
-        LValue floatValue = m_out.fpCast(lowDouble(m_node->child1()), m_out.floatType);
-        setDouble(m_out.fpCast(floatValue, m_out.doubleType));
-    }
-    
-    void compileArithNegate()
+    void compileArithPow()
     {
-        switch (m_node->child1().useKind()) {
-        case Int32Use: {
-            LValue value = lowInt32(m_node->child1());
-            
-            LValue result;
-            if (!shouldCheckOverflow(m_node->arithMode()))
-                result = m_out.neg(value);
+        // FIXME: investigate llvm.powi to better understand its performance characteristics.
+        // It might be better to have the inline loop in DFG too.
+        if (m_node->child2().useKind() == Int32Use)
+            setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
+        else {
+            LValue base = lowDouble(m_node->child1());
+            LValue exponent = lowDouble(m_node->child2());
+
+            LBasicBlock integerExponentIsSmallBlock = FTL_NEW_BLOCK(m_out, ("ArithPow test integer exponent is small."));
+            LBasicBlock integerExponentPowBlock = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, (int)double)."));
+            LBasicBlock doubleExponentPowBlockEntry = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, double)."));
+            LBasicBlock nanExceptionExponentIsInfinity = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check exponent is infinity."));
+            LBasicBlock nanExceptionBaseIsOne = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check base is one."));
+            LBasicBlock powBlock = FTL_NEW_BLOCK(m_out, ("ArithPow regular pow"));
+            LBasicBlock nanExceptionResultIsNaN = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, result is NaN."));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithPow continuation"));
+
+            LValue integerExponent = m_out.fpToInt32(exponent);
+            LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
+            LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
+            m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
+
+            LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
+            LValue integerExponentBelow1000 = m_out.below(integerExponent, m_out.constInt32(1000));
+            m_out.branch(integerExponentBelow1000, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
+
+            m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
+            ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
+            m_out.jump(continuation);
+
+            // If y is NaN, the result is NaN.
+            m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionExponentIsInfinity);
+            LValue exponentIsNaN;
+            if (provenType(m_node->child2()) & SpecDoubleNaN)
+                exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
+            else
+                exponentIsNaN = m_out.booleanFalse;
+            m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionExponentIsInfinity));
+
+            // If abs(x) is 1 and y is +infinity, the result is NaN.
+            // If abs(x) is 1 and y is -infinity, the result is NaN.
+            m_out.appendTo(nanExceptionExponentIsInfinity, nanExceptionBaseIsOne);
+            LValue absoluteExponent = m_out.doubleAbs(exponent);
+            LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
+            m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionBaseIsOne), usually(powBlock));
+
+            m_out.appendTo(nanExceptionBaseIsOne, powBlock);
+            LValue absoluteBase = m_out.doubleAbs(base);
+            LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
+            m_out.branch(absoluteBaseIsOne, unsure(nanExceptionResultIsNaN), unsure(powBlock));
+
+            m_out.appendTo(powBlock, nanExceptionResultIsNaN);
+            ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
+            m_out.jump(continuation);
+
+            m_out.appendTo(nanExceptionResultIsNaN, continuation);
+            ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
+            m_out.jump(continuation);
+
+            m_out.appendTo(continuation, lastNext);
+            setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, powResult, pureNan));
+        }
+    }
+
+    void compileArithRound()
+    {
+        LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, ("ArithRound should round down"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithRound continuation"));
+
+        LValue value = lowDouble(m_node->child1());
+        LValue integerValue = m_out.ceil64(value);
+        ValueFromBlock integerValueResult = m_out.anchor(integerValue);
+
+        LValue realPart = m_out.doubleSub(integerValue, value);
+
+        m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
+        LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
+        ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
+        m_out.jump(continuation);
+        m_out.appendTo(continuation, lastNext);
+
+        LValue result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
+
+        if (producesInteger(m_node->arithRoundingMode())) {
+            LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
+            setInt32(integerValue);
+        } else
+            setDouble(result);
+    }
+
+    void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
+
+    void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
+    
+    void compileArithFRound()
+    {
+        LValue floatValue = m_out.fpCast(lowDouble(m_node->child1()), m_out.floatType);
+        setDouble(m_out.fpCast(floatValue, m_out.doubleType));
+    }
+    
+    void compileArithNegate()
+    {
+        switch (m_node->child1().useKind()) {
+        case Int32Use: {
+            LValue value = lowInt32(m_node->child1());
+            
+            LValue result;
+            if (!shouldCheckOverflow(m_node->arithMode()))
+                result = m_out.neg(value);
             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
                 // We don't have a negate-with-overflow intrinsic. Hopefully this
                 // does the trick, though.
@@ -1542,7 +1945,7 @@ private:
         }
             
         case Int52RepUse: {
-            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) {
+            if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)) {
                 Int52Kind kind;
                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
                 LValue result = m_out.neg(value);
@@ -1567,7 +1970,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             break;
         }
     }
@@ -1626,63 +2029,44 @@ private:
         LValue cell = lowCell(m_node->child1());
         
         ExitKind exitKind;
-        if (m_node->child1()->op() == WeakJSConstant)
-            exitKind = BadWeakConstantCache;
+        if (m_node->child1()->hasConstant())
+            exitKind = BadConstantCache;
         else
             exitKind = BadCache;
         
         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
         
-        if (m_node->structureSet().size() == 1) {
-            speculate(
-                exitKind, jsValueValue(cell), 0,
-                m_out.notEqual(structureID, weakStructure(m_node->structureSet()[0])));
-            return;
-        }
-        
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckStructure continuation"));
-        
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
-        for (unsigned i = 0; i < m_node->structureSet().size() - 1; ++i) {
-            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("CheckStructure nextStructure"));
-            m_out.branch(
-                m_out.equal(structureID, weakStructure(m_node->structureSet()[i])),
-                unsure(continuation), unsure(nextStructure));
-            m_out.appendTo(nextStructure);
-        }
-        
-        speculate(
-            exitKind, jsValueValue(cell), 0,
-            m_out.notEqual(structureID, weakStructure(m_node->structureSet().last())));
-        
-        m_out.jump(continuation);
-        m_out.appendTo(continuation, lastNext);
+        checkStructure(
+            structureID, jsValueValue(cell), exitKind, m_node->structureSet(),
+            [this] (Structure* structure) {
+                return weakStructureID(structure);
+            });
     }
     
-    void compileStructureTransitionWatchpoint()
-    {
-        addWeakReference(m_node->structure());
-        speculateCell(m_node->child1());
-    }
-    
-    void compileCheckFunction()
+    void compileCheckCell()
     {
         LValue cell = lowCell(m_node->child1());
         
         speculate(
-            BadFunction, jsValueValue(cell), m_node->child1().node(),
-            m_out.notEqual(cell, weakPointer(m_node->function())));
+            BadCell, jsValueValue(cell), m_node->child1().node(),
+            m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
     }
     
-    void compileCheckExecutable()
+    void compileCheckBadCell()
+    {
+        terminate(BadCell);
+    }
+
+    void compileCheckNotEmpty()
+    {
+        speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
+    }
+
+    void compileGetExecutable()
     {
         LValue cell = lowCell(m_node->child1());
-        
-        speculate(
-            BadExecutable, jsValueValue(cell), m_node->child1().node(),
-            m_out.notEqual(
-                m_out.loadPtr(cell, m_heaps.JSFunction_executable),
-                weakPointer(m_node->executable())));
+        speculateFunction(m_node->child1(), cell);
+        setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
     }
     
     void compileArrayifyToStructure()
@@ -1696,7 +2080,7 @@ private:
         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
         
         m_out.branch(
-            m_out.notEqual(structureID, weakStructure(m_node->structure())),
+            m_out.notEqual(structureID, weakStructureID(m_node->structure())),
             rarely(unexpectedStructure), usually(continuation));
         
         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
@@ -1723,24 +2107,21 @@ private:
             vmCall(m_out.operation(operationEnsureDouble), m_callFrame, cell);
             break;
         case Array::Contiguous:
-            if (m_node->arrayMode().conversion() == Array::RageConvert)
-                vmCall(m_out.operation(operationRageEnsureContiguous), m_callFrame, cell);
-            else
-                vmCall(m_out.operation(operationEnsureContiguous), m_callFrame, cell);
+            vmCall(m_out.operation(operationEnsureContiguous), m_callFrame, cell);
             break;
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
             vmCall(m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
             break;
         default:
-            LOWERING_FAILED(m_node, "Bad array type");
-            return;
+            DFG_CRASH(m_graph, m_node, "Bad array type");
+            break;
         }
         
         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
         speculate(
             BadIndexingType, jsValueValue(cell), 0,
-            m_out.notEqual(structureID, weakStructure(m_node->structure())));
+            m_out.notEqual(structureID, weakStructureID(m_node->structure())));
         m_out.jump(continuation);
         
         m_out.appendTo(continuation, lastNext);
@@ -1750,23 +2131,18 @@ private:
     {
         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
 
-        Structure* oldStructure = m_node->structureTransitionData().previousStructure;
-        Structure* newStructure = m_node->structureTransitionData().newStructure;
+        Structure* oldStructure = m_node->transition()->previous;
+        Structure* newStructure = m_node->transition()->next;
         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
 
         LValue cell = lowCell(m_node->child1()); 
         m_out.store32(
-            weakStructure(newStructure),
+            weakStructureID(newStructure),
             cell, m_heaps.JSCell_structureID);
     }
     
-    void compilePhantomPutStructure()
-    {
-        m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
-    }
-    
     void compileGetById()
     {
         // Pretty much the only reason why we don't also support GetByIdFlush is because:
@@ -1788,7 +2164,8 @@ private:
             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped not cell case"));
             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetById untyped continuation"));
             
-            m_out.branch(isCell(value), unsure(cellCase), unsure(notCellCase));
+            m_out.branch(
+                isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
             
             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
             ValueFromBlock cellResult = m_out.anchor(getById(value));
@@ -1796,8 +2173,8 @@ private:
             
             m_out.appendTo(notCellCase, continuation);
             ValueFromBlock notCellResult = m_out.anchor(vmCall(
-                m_out.operation(operationGetById),
-                m_callFrame, getUndef(m_out.intPtr), value,
+                m_out.operation(operationGetByIdGeneric),
+                m_callFrame, value,
                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
             m_out.jump(continuation);
             
@@ -1807,7 +2184,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             return;
         }
     }
@@ -1819,12 +2196,12 @@ private:
         
         LValue base = lowCell(m_node->child1());
         LValue value = lowJSValue(m_node->child2());
-        StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
+        auto uid = m_graph.identifiers()[m_node->identifierNumber()];
 
         // Arguments: id, bytes, target, numArgs, args...
         unsigned stackmapID = m_stackmapIDs++;
 
-        if (Options::verboseCompilation())
+        if (verboseCompilationEnabled())
             dataLog("    Emitting PutById patchpoint with stackmap #", stackmapID, "\n");
         
         LValue call = m_out.call(
@@ -1884,7 +2261,7 @@ private:
         Edge edge = m_node->child1();
         LValue cell = lowCell(edge);
         
-        if (m_node->arrayMode().alreadyChecked(m_graph, m_node, m_state.forNode(edge)))
+        if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
             return;
         
         speculate(
@@ -1900,9 +2277,9 @@ private:
         LBasicBlock wastefulCase = FTL_NEW_BLOCK(m_out, ("wasteful typed array"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("continuation branch"));
         
-        LValue baseAddress = m_out.addPtr(basePtr, JSArrayBufferView::offsetOfMode());
+        LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
         m_out.branch(
-            m_out.notEqual(baseAddress , m_out.constIntPtr(WastefulTypedArray)),
+            m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
             unsure(simpleCase), unsure(wastefulCase));
 
         // begin simple case        
@@ -1920,7 +2297,7 @@ private:
         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
 
-        ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(dataPtr, vectorPtr));        
+        ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
 
         m_out.jump(continuation);
         m_out.appendTo(continuation, lastNext);
@@ -1929,56 +2306,6 @@ private:
         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
     }
     
-    void compileGetMyArgumentsLength() 
-    {
-        checkArgumentsNotCreated();
-
-        RELEASE_ASSERT(!m_node->origin.semantic.inlineCallFrame);
-        setInt32(m_out.add(m_out.load32NonNegative(payloadFor(JSStack::ArgumentCount)), m_out.constInt32(-1)));
-    }
-    
-    void compileGetMyArgumentByVal()
-    {
-        checkArgumentsNotCreated();
-        
-        CodeOrigin codeOrigin = m_node->origin.semantic;
-        
-        LValue zeroBasedIndex = lowInt32(m_node->child1());
-        LValue oneBasedIndex = m_out.add(zeroBasedIndex, m_out.int32One);
-        
-        LValue limit;
-        if (codeOrigin.inlineCallFrame)
-            limit = m_out.constInt32(codeOrigin.inlineCallFrame->arguments.size());
-        else
-            limit = m_out.load32(payloadFor(JSStack::ArgumentCount));
-        
-        speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(oneBasedIndex, limit));
-        
-        SymbolTable* symbolTable = m_graph.baselineCodeBlockFor(codeOrigin)->symbolTable();
-        if (symbolTable->slowArguments()) {
-            // FIXME: FTL should support activations.
-            // https://bugs.webkit.org/show_bug.cgi?id=129576
-            
-            LOWERING_FAILED(m_node, "Unimplemented");
-            return;
-        }
-        
-        TypedPointer base;
-        if (codeOrigin.inlineCallFrame) {
-            VirtualRegister reg;
-            if (codeOrigin.inlineCallFrame->arguments.size() <= 1)
-                reg = virtualRegisterForLocal(0); // Doesn't matter what we do since we would have exited anyway.
-            else
-                reg = codeOrigin.inlineCallFrame->arguments[1].virtualRegister();
-            base = addressFor(reg);
-        } else
-            base = addressFor(virtualRegisterForArgument(1));
-        
-        LValue pointer = m_out.baseIndex(
-            base.value(), m_out.zeroExt(zeroBasedIndex, m_out.intPtr), ScaleEight);
-        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
-    }
-
     void compileGetArrayLength()
     {
         switch (m_node->arrayMode().type()) {
@@ -1995,6 +2322,24 @@ private:
             return;
         }
             
+        case Array::DirectArguments: {
+            LValue arguments = lowCell(m_node->child1());
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
+            setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
+            return;
+        }
+            
+        case Array::ScopedArguments: {
+            LValue arguments = lowCell(m_node->child1());
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notZero8(m_out.load8(arguments, m_heaps.ScopedArguments_overrodeThings)));
+            setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
+            return;
+        }
+            
         default:
             if (isTypedView(m_node->arrayMode().typedArrayType())) {
                 setInt32(
@@ -2002,7 +2347,7 @@ private:
                 return;
             }
             
-            LOWERING_FAILED(m_node, "Bad array type");
+            DFG_CRASH(m_graph, m_node, "Bad array type");
             return;
         }
     }
@@ -2027,7 +2372,14 @@ private:
             
             if (m_node->arrayMode().isInBounds()) {
                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
-                speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
+                LValue isHole = m_out.isZero64(result);
+                if (m_node->arrayMode().isSaneChain()) {
+                    DFG_ASSERT(
+                        m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
+                    result = m_out.select(
+                        isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
+                } else
+                    speculate(LoadFromHole, noValue(), 0, isHole);
                 setJSValue(result);
                 return;
             }
@@ -2112,6 +2464,78 @@ private:
             return;
         }
             
+        case Array::DirectArguments: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.aboveOrEqual(
+                    index,
+                    m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
+
+            TypedPointer address = m_out.baseIndex(
+                m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
+            setJSValue(m_out.load64(address));
+            return;
+        }
+            
+        case Array::ScopedArguments: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.aboveOrEqual(
+                    index,
+                    m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
+            
+            LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
+            LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
+            
+            LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
+            LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
+            
+            LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
+            LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
+            
+            TypedPointer address = m_out.baseIndex(
+                m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
+            LValue scopeOffset = m_out.load32(address);
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
+            
+            address = m_out.baseIndex(
+                m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
+            ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(overflowCase, continuation);
+            
+            address = m_out.baseIndex(
+                m_heaps.ScopedArguments_overflowStorage, base,
+                m_out.zeroExtPtr(m_out.sub(index, namedLength)));
+            LValue overflowValue = m_out.load64(address);
+            speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
+            ValueFromBlock overflowResult = m_out.anchor(overflowValue);
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
+            return;
+        }
+            
         case Array::Generic: {
             setJSValue(vmCall(
                 m_out.operation(operationGetByVal), m_callFrame,
@@ -2136,7 +2560,7 @@ private:
                     m_out.add(
                         storage,
                         m_out.shl(
-                            m_out.zeroExt(index, m_out.intPtr),
+                            m_out.zeroExtPtr(index),
                             m_out.constIntPtr(logElementSize(type)))));
                 
                 if (isInt(type)) {
@@ -2152,8 +2576,7 @@ private:
                         result = m_out.load32(pointer);
                         break;
                     default:
-                        LOWERING_FAILED(m_node, "Bad element size");
-                        return;
+                        DFG_CRASH(m_graph, m_node, "Bad element size");
                     }
                     
                     if (elementSize(type) < 4) {
@@ -2197,19 +2620,58 @@ private:
                     result = m_out.loadDouble(pointer);
                     break;
                 default:
-                    LOWERING_FAILED(m_node, "Bad typed array type");
-                    return;
+                    DFG_CRASH(m_graph, m_node, "Bad typed array type");
                 }
                 
                 setDouble(result);
                 return;
             }
             
-            LOWERING_FAILED(m_node, "Bad array type");
+            DFG_CRASH(m_graph, m_node, "Bad array type");
             return;
         } }
     }
     
+    void compileGetMyArgumentByVal()
+    {
+        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
+        
+        LValue index = lowInt32(m_node->child2());
+        
+        LValue limit;
+        if (inlineCallFrame && !inlineCallFrame->isVarargs())
+            limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
+        else {
+            VirtualRegister argumentCountRegister;
+            if (!inlineCallFrame)
+                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+            else
+                argumentCountRegister = inlineCallFrame->argumentCountRegister;
+            limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
+        }
+        
+        speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
+        
+        TypedPointer base;
+        if (inlineCallFrame) {
+            if (inlineCallFrame->arguments.size() <= 1) {
+                // We should have already exited due to the bounds check, above. Just tell the
+                // compiler that anything dominated by this instruction is not reachable, so
+                // that we don't waste time generating such code. This will also plant some
+                // kind of crashing instruction so that if by some fluke the bounds check didn't
+                // work, we'll crash in an easy-to-see way.
+                didAlreadyTerminate();
+                return;
+            }
+            base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
+        } else
+            base = addressFor(virtualRegisterForArgument(1));
+        
+        LValue pointer = m_out.baseIndex(
+            base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
+        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
+    }
+    
     void compilePutByVal()
     {
         Edge child1 = m_graph.varArgChild(m_node, 0);
@@ -2265,8 +2727,7 @@ private:
                 TypedPointer elementPointer = m_out.baseIndex(
                     m_node->arrayMode().type() == Array::Int32 ?
                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(child2).m_value);
+                    storage, m_out.zeroExtPtr(index), provenValue(child2));
                 
                 if (m_node->op() == PutByValAlias) {
                     m_out.store64(value, elementPointer);
@@ -2291,9 +2752,8 @@ private:
                     m_out.doubleNotEqualOrUnordered(value, value));
                 
                 TypedPointer elementPointer = m_out.baseIndex(
-                    m_heaps.indexedDoubleProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(child2).m_value);
+                    m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
+                    provenValue(child2));
                 
                 if (m_node->op() == PutByValAlias) {
                     m_out.storeDouble(value, elementPointer);
@@ -2311,8 +2771,7 @@ private:
             }
                 
             default:
-                LOWERING_FAILED(m_node, "Bad array type");
-                return;
+                DFG_CRASH(m_graph, m_node, "Bad array type");
             }
 
             m_out.jump(continuation);
@@ -2405,8 +2864,7 @@ private:
                     }
                         
                     default:
-                        LOWERING_FAILED(m_node, "Bad use kind");
-                        return;
+                        DFG_CRASH(m_graph, m_node, "Bad use kind");
                     }
                     
                     switch (elementSize(type)) {
@@ -2423,8 +2881,7 @@ private:
                         refType = m_out.ref32;
                         break;
                     default:
-                        LOWERING_FAILED(m_node, "Bad element size");
-                        return;
+                        DFG_CRASH(m_graph, m_node, "Bad element size");
                     }
                 } else /* !isInt(type) */ {
                     LValue value = lowDouble(child3);
@@ -2438,8 +2895,7 @@ private:
                         refType = m_out.refDouble;
                         break;
                     default:
-                        LOWERING_FAILED(m_node, "Bad typed array type");
-                        return;
+                        DFG_CRASH(m_graph, m_node, "Bad typed array type");
                     }
                 }
                 
@@ -2463,8 +2919,8 @@ private:
                 return;
             }
             
-            LOWERING_FAILED(m_node, "Bad array type");
-            return;
+            DFG_CRASH(m_graph, m_node, "Bad array type");
+            break;
         }
     }
     
@@ -2510,9 +2966,7 @@ private:
             
             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
             m_out.store(
-                value,
-                m_out.baseIndex(heap, storage, m_out.zeroExt(prevLength, m_out.intPtr)),
-                refType);
+                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), refType);
             LValue newLength = m_out.add(prevLength, m_out.int32One);
             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
             
@@ -2535,7 +2989,7 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad array type");
+            DFG_CRASH(m_graph, m_node, "Bad array type");
             return;
         }
     }
@@ -2565,8 +3019,7 @@ private:
             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
             LValue newLength = m_out.sub(prevLength, m_out.int32One);
             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
-            TypedPointer pointer = m_out.baseIndex(
-                heap, storage, m_out.zeroExt(newLength, m_out.intPtr));
+            TypedPointer pointer = m_out.baseIndex(heap, storage, m_out.zeroExtPtr(newLength));
             if (m_node->arrayMode().type() != Array::Double) {
                 LValue result = m_out.load64(pointer);
                 m_out.store64(m_out.int64Zero, pointer);
@@ -2593,101 +3046,290 @@ private:
         }
 
         default:
-            LOWERING_FAILED(m_node, "Bad array type");
+            DFG_CRASH(m_graph, m_node, "Bad array type");
             return;
         }
     }
     
-    void compileNewObject()
+    void compileCreateActivation()
     {
-        Structure* structure = m_node->structure();
-        size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
-        MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
+        LValue scope = lowCell(m_node->child1());
+        SymbolTable* table = m_node->castOperand<SymbolTable*>();
+        Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure();
+        
+        if (table->singletonScope()->isStillValid()) {
+            LValue callResult = vmCall(
+                m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
+                scope, weakPointer(table));
+            setJSValue(callResult);
+            return;
+        }
         
-        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("NewObject slow path"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewObject continuation"));
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateActivation slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateActivation continuation"));
         
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
         
-        ValueFromBlock fastResult = m_out.anchor(allocateObject(
-            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
+        LValue fastObject = allocateObject<JSLexicalEnvironment>(
+            JSLexicalEnvironment::allocationSize(table), structure, m_out.intPtrZero, slowPath);
+        
+        // We don't need memory barriers since we just fast-created the activation, so the
+        // activation must be young.
+        m_out.storePtr(scope, fastObject, m_heaps.JSScope_next);
+        m_out.storePtr(weakPointer(table), fastObject, m_heaps.JSSymbolTableObject_symbolTable);
         
+        for (unsigned i = 0; i < table->scopeSize(); ++i) {
+            m_out.store64(
+                m_out.constInt64(JSValue::encode(jsUndefined())),
+                fastObject, m_heaps.JSEnvironmentRecord_variables[i]);
+        }
+        
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
         m_out.jump(continuation);
         
         m_out.appendTo(slowPath, continuation);
-        
-        ValueFromBlock slowResult = m_out.anchor(vmCall(
-            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
+        LValue callResult = vmCall(
+            m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
+            scope, weakPointer(table));
+        ValueFromBlock slowResult = m_out.anchor(callResult);
         m_out.jump(continuation);
         
         m_out.appendTo(continuation, lastNext);
         setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
     }
     
-    void compileNewArray()
+    void compileNewFunction()
     {
-        // First speculate appropriately on all of the children. Do this unconditionally up here
-        // because some of the slow paths may otherwise forget to do it. It's sort of arguable
-        // that doing the speculations up here might be unprofitable for RA - so we can consider
-        // sinking this to below the allocation fast path if we find that this has a lot of
-        // register pressure.
-        for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex)
-            speculate(m_graph.varArgChild(m_node, operandIndex));
+        LValue scope = lowCell(m_node->child1());
+        FunctionExecutable* executable = m_node->castOperand<FunctionExecutable*>();
+        if (executable->singletonFunction()->isStillValid()) {
+            LValue callResult = vmCall(
+                m_out.operation(operationNewFunction), m_callFrame, scope, weakPointer(executable));
+            setJSValue(callResult);
+            return;
+        }
         
-        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
-        Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(
-            m_node->indexingType());
+        Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->functionStructure();
         
-        RELEASE_ASSERT(structure->indexingType() == m_node->indexingType());
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("NewFunction slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewFunction continuation"));
         
-        if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(m_node->indexingType())) {
-            unsigned numElements = m_node->numChildren();
-            
-            ArrayValues arrayValues = allocateJSArray(structure, numElements);
-            
-            for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) {
-                Edge edge = m_graph.varArgChild(m_node, operandIndex);
-                
-                switch (m_node->indexingType()) {
-                case ALL_BLANK_INDEXING_TYPES:
-                case ALL_UNDECIDED_INDEXING_TYPES:
-                    CRASH();
-                    break;
-                    
-                case ALL_DOUBLE_INDEXING_TYPES:
-                    m_out.storeDouble(
-                        lowDouble(edge),
-                        arrayValues.butterfly, m_heaps.indexedDoubleProperties[operandIndex]);
-                    break;
-                    
-                case ALL_INT32_INDEXING_TYPES:
-                case ALL_CONTIGUOUS_INDEXING_TYPES:
-                    m_out.store64(
-                        lowJSValue(edge, ManualOperandSpeculation),
-                        arrayValues.butterfly,
-                        m_heaps.forIndexingType(m_node->indexingType())->at(operandIndex));
-                    break;
-                    
-                default:
-                    CRASH();
-                }
-            }
-            
-            setJSValue(arrayValues.array);
-            return;
-        }
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
         
-        if (!m_node->numChildren()) {
-            setJSValue(vmCall(
-                m_out.operation(operationNewEmptyArray), m_callFrame,
-                m_out.constIntPtr(structure)));
-            return;
-        }
+        LValue fastObject = allocateObject<JSFunction>(
+            structure, m_out.intPtrZero, slowPath);
         
-        size_t scratchSize = sizeof(EncodedJSValue) * m_node->numChildren();
-        ASSERT(scratchSize);
-        ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
-        EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
+        // We don't need memory barriers since we just fast-created the function, so it
+        // must be young.
+        m_out.storePtr(scope, fastObject, m_heaps.JSFunction_scope);
+        m_out.storePtr(weakPointer(executable), fastObject, m_heaps.JSFunction_executable);
+        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.JSFunction_rareData);
+        
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        LValue callResult = vmCall(
+            m_out.operation(operationNewFunctionWithInvalidatedReallocationWatchpoint),
+            m_callFrame, scope, weakPointer(executable));
+        ValueFromBlock slowResult = m_out.anchor(callResult);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
+    }
+    
+    void compileCreateDirectArguments()
+    {
+        // FIXME: A more effective way of dealing with the argument count and callee is to have
+        // them be explicit arguments to this node.
+        // https://bugs.webkit.org/show_bug.cgi?id=142207
+        
+        Structure* structure =
+            m_graph.globalObjectFor(m_node->origin.semantic)->directArgumentsStructure();
+        
+        unsigned minCapacity = m_graph.baselineCodeBlockFor(m_node->origin.semantic)->numParameters() - 1;
+        
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments continuation"));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+        
+        ArgumentsLength length = getArgumentsLength();
+        
+        LValue fastObject;
+        if (length.isKnown) {
+            fastObject = allocateObject<DirectArguments>(
+                DirectArguments::allocationSize(std::max(length.known, minCapacity)), structure,
+                m_out.intPtrZero, slowPath);
+        } else {
+            LValue size = m_out.add(
+                m_out.shl(length.value, m_out.constInt32(3)),
+                m_out.constInt32(DirectArguments::storageOffset()));
+            
+            size = m_out.select(
+                m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
+                size, m_out.constInt32(DirectArguments::allocationSize(minCapacity)));
+            
+            fastObject = allocateVariableSizedObject<DirectArguments>(
+                size, structure, m_out.intPtrZero, slowPath);
+        }
+        
+        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
+        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
+        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
+        
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        LValue callResult = vmCall(
+            m_out.operation(operationCreateDirectArguments), m_callFrame, weakPointer(structure),
+            length.value, m_out.constInt32(minCapacity));
+        ValueFromBlock slowResult = m_out.anchor(callResult);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(m_out.intPtr, fastResult, slowResult);
+
+        m_out.storePtr(getCurrentCallee(), result, m_heaps.DirectArguments_callee);
+        
+        if (length.isKnown) {
+            VirtualRegister start = AssemblyHelpers::argumentsStart(m_node->origin.semantic);
+            for (unsigned i = 0; i < std::max(length.known, minCapacity); ++i) {
+                m_out.store64(
+                    m_out.load64(addressFor(start + i)),
+                    result, m_heaps.DirectArguments_storage[i]);
+            }
+        } else {
+            LValue stackBase = getArgumentsStart();
+            
+            LBasicBlock loop = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop body"));
+            LBasicBlock end = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop end"));
+            
+            ValueFromBlock originalLength;
+            if (minCapacity) {
+                LValue capacity = m_out.select(
+                    m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
+                    length.value,
+                    m_out.constInt32(minCapacity));
+                originalLength = m_out.anchor(m_out.zeroExtPtr(capacity));
+                m_out.jump(loop);
+            } else {
+                originalLength = m_out.anchor(m_out.zeroExtPtr(length.value));
+                m_out.branch(m_out.isNull(originalLength.value()), unsure(end), unsure(loop));
+            }
+            
+            lastNext = m_out.appendTo(loop, end);
+            LValue previousIndex = m_out.phi(m_out.intPtr, originalLength);
+            LValue index = m_out.sub(previousIndex, m_out.intPtrOne);
+            m_out.store64(
+                m_out.load64(m_out.baseIndex(m_heaps.variables, stackBase, index)),
+                m_out.baseIndex(m_heaps.DirectArguments_storage, result, index));
+            ValueFromBlock nextIndex = m_out.anchor(index);
+            addIncoming(previousIndex, nextIndex);
+            m_out.branch(m_out.isNull(index), unsure(end), unsure(loop));
+            
+            m_out.appendTo(end, lastNext);
+        }
+        
+        setJSValue(result);
+    }
+    
+    void compileCreateScopedArguments()
+    {
+        LValue scope = lowCell(m_node->child1());
+        
+        LValue result = vmCall(
+            m_out.operation(operationCreateScopedArguments), m_callFrame,
+            weakPointer(
+                m_graph.globalObjectFor(m_node->origin.semantic)->scopedArgumentsStructure()),
+            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee(), scope);
+        
+        setJSValue(result);
+    }
+    
+    void compileCreateClonedArguments()
+    {
+        LValue result = vmCall(
+            m_out.operation(operationCreateClonedArguments), m_callFrame,
+            weakPointer(
+                m_graph.globalObjectFor(m_node->origin.semantic)->outOfBandArgumentsStructure()),
+            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee());
+        
+        setJSValue(result);
+    }
+    
+    void compileNewObject()
+    {
+        setJSValue(allocateObject(m_node->structure()));
+    }
+    
+    void compileNewArray()
+    {
+        // First speculate appropriately on all of the children. Do this unconditionally up here
+        // because some of the slow paths may otherwise forget to do it. It's sort of arguable
+        // that doing the speculations up here might be unprofitable for RA - so we can consider
+        // sinking this to below the allocation fast path if we find that this has a lot of
+        // register pressure.
+        for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex)
+            speculate(m_graph.varArgChild(m_node, operandIndex));
+        
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+        Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(
+            m_node->indexingType());
+        
+        DFG_ASSERT(m_graph, m_node, structure->indexingType() == m_node->indexingType());
+        
+        if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(m_node->indexingType())) {
+            unsigned numElements = m_node->numChildren();
+            
+            ArrayValues arrayValues = allocateJSArray(structure, numElements);
+            
+            for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) {
+                Edge edge = m_graph.varArgChild(m_node, operandIndex);
+                
+                switch (m_node->indexingType()) {
+                case ALL_BLANK_INDEXING_TYPES:
+                case ALL_UNDECIDED_INDEXING_TYPES:
+                    DFG_CRASH(m_graph, m_node, "Bad indexing type");
+                    break;
+                    
+                case ALL_DOUBLE_INDEXING_TYPES:
+                    m_out.storeDouble(
+                        lowDouble(edge),
+                        arrayValues.butterfly, m_heaps.indexedDoubleProperties[operandIndex]);
+                    break;
+                    
+                case ALL_INT32_INDEXING_TYPES:
+                case ALL_CONTIGUOUS_INDEXING_TYPES:
+                    m_out.store64(
+                        lowJSValue(edge, ManualOperandSpeculation),
+                        arrayValues.butterfly,
+                        m_heaps.forIndexingType(m_node->indexingType())->at(operandIndex));
+                    break;
+                    
+                default:
+                    DFG_CRASH(m_graph, m_node, "Corrupt indexing type");
+                    break;
+                }
+            }
+            
+            setJSValue(arrayValues.array);
+            return;
+        }
+        
+        if (!m_node->numChildren()) {
+            setJSValue(vmCall(
+                m_out.operation(operationNewEmptyArray), m_callFrame,
+                m_out.constIntPtr(structure)));
+            return;
+        }
+        
+        size_t scratchSize = sizeof(EncodedJSValue) * m_node->numChildren();
+        ASSERT(scratchSize);
+        ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
+        EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
         
         for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) {
             Edge edge = m_graph.varArgChild(m_node, operandIndex);
@@ -2715,7 +3357,7 @@ private:
         Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(
             m_node->indexingType());
         
-        RELEASE_ASSERT(structure->indexingType() == m_node->indexingType());
+        DFG_ASSERT(m_graph, m_node, structure->indexingType() == m_node->indexingType());
         
         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(m_node->indexingType())) {
             unsigned numElements = m_node->numConstants();
@@ -2768,7 +3410,7 @@ private:
             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewArrayWithSize continuation"));
             
             m_out.branch(
-                m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)),
+                m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)),
                 rarely(largeCase), usually(fastCase));
 
             LBasicBlock lastNext = m_out.appendTo(fastCase, largeCase);
@@ -2844,7 +3486,7 @@ private:
         }
         
         LValue structureValue = m_out.select(
-            m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)),
+            m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)),
             m_out.constIntPtr(
                 globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)),
             m_out.constIntPtr(structure));
@@ -2853,24 +3495,22 @@ private:
     
     void compileAllocatePropertyStorage()
     {
-        StructureTransitionData& data = m_node->structureTransitionData();
         LValue object = lowCell(m_node->child1());
-        
-        setStorage(allocatePropertyStorage(object, data.previousStructure));
+        setStorage(allocatePropertyStorage(object, m_node->transition()->previous));
     }
 
     void compileReallocatePropertyStorage()
     {
-        StructureTransitionData& data = m_node->structureTransitionData();
+        Transition* transition = m_node->transition();
         LValue object = lowCell(m_node->child1());
         LValue oldStorage = lowStorage(m_node->child2());
         
         setStorage(
             reallocatePropertyStorage(
-                object, oldStorage, data.previousStructure, data.newStructure));
+                object, oldStorage, transition->previous, transition->next));
     }
     
-    void compileToString()
+    void compileToStringOrCallStringConstructor()
     {
         switch (m_node->child1().useKind()) {
         case StringObjectUse: {
@@ -2923,16 +3563,14 @@ private:
             if (m_node->child1().useKind() == CellUse)
                 isCellPredicate = m_out.booleanTrue;
             else
-                isCellPredicate = this->isCell(value);
+                isCellPredicate = this->isCell(value, provenType(m_node->child1()));
             m_out.branch(isCellPredicate, unsure(isCell), unsure(notString));
             
             LBasicBlock lastNext = m_out.appendTo(isCell, notString);
             ValueFromBlock simpleResult = m_out.anchor(value);
             LValue isStringPredicate;
             if (m_node->child1()->prediction() & SpecString) {
-                isStringPredicate = m_out.equal(
-                    m_out.load32(value, m_heaps.JSCell_structureID),
-                    m_out.constInt32(vm().stringStructure->id()));
+                isStringPredicate = isString(value, provenType(m_node->child1()));
             } else
                 isStringPredicate = m_out.booleanFalse;
             m_out.branch(isStringPredicate, unsure(continuation), unsure(notString));
@@ -2940,9 +3578,9 @@ private:
             m_out.appendTo(notString, continuation);
             LValue operation;
             if (m_node->child1().useKind() == CellUse)
-                operation = m_out.operation(operationToStringOnCell);
+                operation = m_out.operation(m_node->op() == ToString ? operationToStringOnCell : operationCallStringConstructorOnCell);
             else
-                operation = m_out.operation(operationToString);
+                operation = m_out.operation(m_node->op() == ToString ? operationToString : operationCallStringConstructor);
             ValueFromBlock convertedResult = m_out.anchor(vmCall(operation, m_callFrame, value));
             m_out.jump(continuation);
             
@@ -2952,8 +3590,8 @@ private:
         }
             
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
-            return;
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
+            break;
         }
     }
     
@@ -2968,11 +3606,14 @@ private:
         Vector<ValueFromBlock, 3> results;
         
         results.append(m_out.anchor(value));
-        m_out.branch(isCell(value), unsure(isCellCase), unsure(continuation));
+        m_out.branch(
+            isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation));
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, isObjectCase);
         results.append(m_out.anchor(value));
-        m_out.branch(isObject(value), unsure(isObjectCase), unsure(continuation));
+        m_out.branch(
+            isObject(value, provenType(m_node->child1())),
+            unsure(isObjectCase), unsure(continuation));
         
         m_out.appendTo(isObjectCase, continuation);
         results.append(m_out.anchor(vmCall(
@@ -3003,7 +3644,7 @@ private:
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
         
         MarkedAllocator& allocator =
-            vm().heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(JSRopeString));
+            vm().heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
         
         LValue result = allocateCell(
             m_out.constIntPtr(&allocator),
@@ -3044,8 +3685,7 @@ private:
                 m_out.operation(operationMakeRope3), m_callFrame, kids[0], kids[1], kids[2]));
             break;
         default:
-            LOWERING_FAILED(m_node, "Bad number of children");
-            return;
+            DFG_CRASH(m_graph, m_node, "Bad number of children");
             break;
         }
         m_out.jump(continuation);
@@ -3088,9 +3728,8 @@ private:
             
         ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
             m_out.load8(m_out.baseIndex(
-                m_heaps.characters8,
-                storage, m_out.zeroExt(index, m_out.intPtr),
-                m_state.forNode(m_node->child2()).m_value)),
+                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
+                provenValue(m_node->child2()))),
             m_out.int32));
         m_out.jump(bitsContinuation);
             
@@ -3098,9 +3737,8 @@ private:
             
         ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
             m_out.load16(m_out.baseIndex(
-                m_heaps.characters16,
-                storage, m_out.zeroExt(index, m_out.intPtr),
-                m_state.forNode(m_node->child2()).m_value)),
+                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
+                provenValue(m_node->child2()))),
             m_out.int32));
         m_out.branch(
             m_out.aboveOrEqual(char16Bit.value(), m_out.constInt32(0x100)),
@@ -3121,8 +3759,7 @@ private:
         LValue smallStrings = m_out.constIntPtr(vm().smallStrings.singleCharacterStrings());
             
         results.append(m_out.anchor(m_out.loadPtr(m_out.baseIndex(
-            m_heaps.singleCharacterStrings, smallStrings,
-            m_out.zeroExt(character, m_out.intPtr)))));
+            m_heaps.singleCharacterStrings, smallStrings, m_out.zeroExtPtr(character)))));
         m_out.jump(continuation);
             
         m_out.appendTo(slowPath, continuation);
@@ -3134,6 +3771,14 @@ private:
             JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
                 
             if (globalObject->stringPrototypeChainIsSane()) {
+                // FIXME: This could be captured using a Speculation mode that means
+                // "out-of-bounds loads return a trivial value", something like
+                // SaneChainOutOfBounds.
+                // https://bugs.webkit.org/show_bug.cgi?id=144668
+                
+                m_graph.watchpoints().addLazily(globalObject->stringPrototype()->structure()->transitionWatchpointSet());
+                m_graph.watchpoints().addLazily(globalObject->objectPrototype()->structure()->transitionWatchpointSet());
+                
                 LBasicBlock negativeIndex = FTL_NEW_BLOCK(m_out, ("GetByVal String negative index"));
                     
                 results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined()))));
@@ -3181,9 +3826,8 @@ private:
             
         ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
             m_out.load8(m_out.baseIndex(
-                m_heaps.characters8,
-                storage, m_out.zeroExt(index, m_out.intPtr),
-                m_state.forNode(m_node->child2()).m_value)),
+                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
+                provenValue(m_node->child2()))),
             m_out.int32));
         m_out.jump(continuation);
             
@@ -3191,9 +3835,8 @@ private:
             
         ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
             m_out.load16(m_out.baseIndex(
-                m_heaps.characters16,
-                storage, m_out.zeroExt(index, m_out.intPtr),
-                m_state.forNode(m_node->child2()).m_value)),
+                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
+                provenValue(m_node->child2()))),
             m_out.int32));
         m_out.jump(continuation);
         
@@ -3204,18 +3847,33 @@ private:
     
     void compileGetByOffset()
     {
-        StorageAccessData& data =
-            m_graph.m_storageAccessData[m_node->storageAccessDataIndex()];
+        StorageAccessData& data = m_node->storageAccessData();
         
         setJSValue(loadProperty(
             lowStorage(m_node->child1()), data.identifierNumber, data.offset));
     }
     
+    void compileGetGetter()
+    {
+        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.GetterSetter_getter));
+    }
+    
+    void compileGetSetter()
+    {
+        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.GetterSetter_setter));
+    }
+    
     void compileMultiGetByOffset()
     {
         LValue base = lowCell(m_node->child1());
         
         MultiGetByOffsetData& data = m_node->multiGetByOffsetData();
+
+        if (data.variants.isEmpty()) {
+            // Protect against creating a Phi function with zero inputs. LLVM doesn't like that.
+            terminate(BadCache);
+            return;
+        }
         
         Vector<LBasicBlock, 2> blocks(data.variants.size());
         for (unsigned i = data.variants.size(); i--;)
@@ -3224,11 +3882,13 @@ private:
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MultiGetByOffset continuation"));
         
         Vector<SwitchCase, 2> cases;
+        StructureSet baseSet;
         for (unsigned i = data.variants.size(); i--;) {
             GetByIdVariant variant = data.variants[i];
             for (unsigned j = variant.structureSet().size(); j--;) {
-                cases.append(SwitchCase(
-                    weakStructure(variant.structureSet()[j]), blocks[i], Weight(1)));
+                Structure* structure = variant.structureSet()[j];
+                baseSet.add(structure);
+                cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
             }
         }
         m_out.switchInstruction(
@@ -3241,13 +3901,19 @@ private:
             m_out.appendTo(blocks[i], i + 1 < data.variants.size() ? blocks[i + 1] : exit);
             
             GetByIdVariant variant = data.variants[i];
+            baseSet.merge(variant.structureSet());
             LValue result;
-            if (variant.specificValue())
-                result = m_out.constInt64(JSValue::encode(variant.specificValue()));
+            JSValue constantResult;
+            if (variant.alternateBase()) {
+                constantResult = m_graph.tryGetConstantProperty(
+                    variant.alternateBase(), variant.baseStructure(), variant.offset());
+            }
+            if (constantResult)
+                result = m_out.constInt64(JSValue::encode(constantResult));
             else {
                 LValue propertyBase;
-                if (variant.chain())
-                    propertyBase = weakPointer(variant.chain()->terminalPrototype());
+                if (variant.alternateBase())
+                    propertyBase = weakPointer(variant.alternateBase());
                 else
                     propertyBase = base;
                 if (!isInlineOffset(variant.offset()))
@@ -3260,7 +3926,8 @@ private:
         }
         
         m_out.appendTo(exit, continuation);
-        terminate(BadCache);
+        if (!m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet))
+            speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
         m_out.unreachable();
         
         m_out.appendTo(continuation, lastNext);
@@ -3269,8 +3936,7 @@ private:
     
     void compilePutByOffset()
     {
-        StorageAccessData& data =
-            m_graph.m_storageAccessData[m_node->storageAccessDataIndex()];
+        StorageAccessData& data = m_node->storageAccessData();
         
         storeProperty(
             lowJSValue(m_node->child3()),
@@ -3291,10 +3957,14 @@ private:
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MultiPutByOffset continuation"));
         
         Vector<SwitchCase, 2> cases;
+        StructureSet baseSet;
         for (unsigned i = data.variants.size(); i--;) {
             PutByIdVariant variant = data.variants[i];
-            cases.append(
-                SwitchCase(weakStructure(variant.oldStructure()), blocks[i], Weight(1)));
+            for (unsigned j = variant.oldStructure().size(); j--;) {
+                Structure* structure = variant.oldStructure()[j];
+                baseSet.add(structure);
+                cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
+            }
         }
         m_out.switchInstruction(
             m_out.load32(base, m_heaps.JSCell_structureID), cases, exit, Weight(0));
@@ -3302,7 +3972,7 @@ private:
         LBasicBlock lastNext = m_out.m_nextBlock;
         
         for (unsigned i = data.variants.size(); i--;) {
-            m_out.appendTo(blocks[i], i  + 1 < data.variants.size() ? blocks[i + 1] : exit);
+            m_out.appendTo(blocks[i], i + 1 < data.variants.size() ? blocks[i + 1] : exit);
             
             PutByIdVariant variant = data.variants[i];
             
@@ -3315,16 +3985,17 @@ private:
             } else {
                 m_graph.m_plan.transitions.addLazily(
                     codeBlock(), m_node->origin.semantic.codeOriginOwner(),
-                    variant.oldStructure(), variant.newStructure());
+                    variant.oldStructureForTransition(), variant.newStructure());
                 
                 storage = storageForTransition(
-                    base, variant.offset(), variant.oldStructure(), variant.newStructure());
+                    base, variant.offset(),
+                    variant.oldStructureForTransition(), variant.newStructure());
 
-                ASSERT(variant.oldStructure()->indexingType() == variant.newStructure()->indexingType());
-                ASSERT(variant.oldStructure()->typeInfo().inlineTypeFlags() == variant.newStructure()->typeInfo().inlineTypeFlags());
-                ASSERT(variant.oldStructure()->typeInfo().type() == variant.newStructure()->typeInfo().type());
+                ASSERT(variant.oldStructureForTransition()->indexingType() == variant.newStructure()->indexingType());
+                ASSERT(variant.oldStructureForTransition()->typeInfo().inlineTypeFlags() == variant.newStructure()->typeInfo().inlineTypeFlags());
+                ASSERT(variant.oldStructureForTransition()->typeInfo().type() == variant.newStructure()->typeInfo().type());
                 m_out.store32(
-                    weakStructure(variant.newStructure()), base, m_heaps.JSCell_structureID);
+                    weakStructureID(variant.newStructure()), base, m_heaps.JSCell_structureID);
             }
             
             storeProperty(value, storage, data.identifierNumber, variant.offset());
@@ -3332,7 +4003,8 @@ private:
         }
         
         m_out.appendTo(exit, continuation);
-        terminate(BadCache);
+        if (!m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet))
+            speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
         m_out.unreachable();
         
         m_out.appendTo(continuation, lastNext);
@@ -3340,40 +4012,30 @@ private:
     
     void compileGetGlobalVar()
     {
-        setJSValue(m_out.load64(m_out.absolute(m_node->registerPointer())));
+        setJSValue(m_out.load64(m_out.absolute(m_node->variablePointer())));
     }
     
     void compilePutGlobalVar()
     {
         m_out.store64(
-            lowJSValue(m_node->child1()), m_out.absolute(m_node->registerPointer()));
+            lowJSValue(m_node->child2()), m_out.absolute(m_node->variablePointer()));
     }
     
     void compileNotifyWrite()
     {
-        VariableWatchpointSet* set = m_node->variableWatchpointSet();
-        
-        LValue value = lowJSValue(m_node->child1());
+        WatchpointSet* set = m_node->watchpointSet();
         
         LBasicBlock isNotInvalidated = FTL_NEW_BLOCK(m_out, ("NotifyWrite not invalidated case"));
-        LBasicBlock notifySlow = FTL_NEW_BLOCK(m_out, ("NotifyWrite notify slow case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NotifyWrite continuation"));
         
         LValue state = m_out.load8(m_out.absolute(set->addressOfState()));
-        
         m_out.branch(
             m_out.equal(state, m_out.constInt8(IsInvalidated)),
             usually(continuation), rarely(isNotInvalidated));
         
-        LBasicBlock lastNext = m_out.appendTo(isNotInvalidated, notifySlow);
-
-        m_out.branch(
-            m_out.equal(value, m_out.load64(m_out.absolute(set->addressOfInferredValue()))),
-            unsure(continuation), unsure(notifySlow));
-
-        m_out.appendTo(notifySlow, continuation);
+        LBasicBlock lastNext = m_out.appendTo(isNotInvalidated, continuation);
 
-        vmCall(m_out.operation(operationNotifyWrite), m_callFrame, m_out.constIntPtr(set), value);
+        vmCall(m_out.operation(operationNotifyWrite), m_callFrame, m_out.constIntPtr(set));
         m_out.jump(continuation);
         
         m_out.appendTo(continuation, lastNext);
@@ -3384,15 +4046,14 @@ private:
         setJSValue(m_out.loadPtr(addressFor(JSStack::Callee)));
     }
     
-    void compileGetScope()
+    void compileGetArgumentCount()
     {
-        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSFunction_scope));
+        setInt32(m_out.load32(payloadFor(JSStack::ArgumentCount)));
     }
     
-    void compileGetMyScope()
+    void compileGetScope()
     {
-        setJSValue(m_out.loadPtr(addressFor(
-            m_node->origin.semantic.stackOffset() + JSStack::ScopeChain)));
+        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSFunction_scope));
     }
     
     void compileSkipScope()
@@ -3400,28 +4061,36 @@ private:
         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSScope_next));
     }
     
-    void compileGetClosureRegisters()
+    void compileGetClosureVar()
     {
-        if (WriteBarrierBase<Unknown>* registers = m_graph.tryGetRegisters(m_node->child1().node())) {
-            setStorage(m_out.constIntPtr(registers));
-            return;
-        }
-        
-        setStorage(m_out.loadPtr(
-            lowCell(m_node->child1()), m_heaps.JSVariableObject_registers));
+        setJSValue(
+            m_out.load64(
+                lowCell(m_node->child1()),
+                m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]));
     }
     
-    void compileGetClosureVar()
+    void compilePutClosureVar()
     {
-        setJSValue(m_out.load64(
-            addressFor(lowStorage(m_node->child1()), m_node->varNumber())));
+        m_out.store64(
+            lowJSValue(m_node->child2()),
+            lowCell(m_node->child1()),
+            m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]);
     }
     
-    void compilePutClosureVar()
+    void compileGetFromArguments()
+    {
+        setJSValue(
+            m_out.load64(
+                lowCell(m_node->child1()),
+                m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]));
+    }
+    
+    void compilePutToArguments()
     {
         m_out.store64(
-            lowJSValue(m_node->child3()),
-            addressFor(lowStorage(m_node->child2()), m_node->varNumber()));
+            lowJSValue(m_node->child2()),
+            lowCell(m_node->child1()),
+            m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]);
     }
     
     void compileCompareEq()
@@ -3450,13 +4119,13 @@ private:
             nonSpeculativeCompare(LLVMIntEQ, operationCompareEq);
             return;
         }
-
-        LOWERING_FAILED(m_node, "Bad use kinds");
+        
+        DFG_CRASH(m_graph, m_node, "Bad use kinds");
     }
     
     void compileCompareEqConstant()
     {
-        ASSERT(m_graph.valueOfJSConstant(m_node->child2().node()).isNull());
+        ASSERT(m_node->child2()->asJSValue().isNull());
         setBoolean(
             equalNullOrUndefined(
                 m_node->child1(), AllCellsAreFalse, EqualNullOrUndefined));
@@ -3489,7 +4158,23 @@ private:
                 m_out.equal(lowStringIdent(m_node->child1()), lowStringIdent(m_node->child2())));
             return;
         }
+
+        if (m_node->isBinaryUseKind(ObjectUse, UntypedUse)) {
+            setBoolean(
+                m_out.equal(
+                    lowNonNullObject(m_node->child1()),
+                    lowJSValue(m_node->child2())));
+            return;
+        }
         
+        if (m_node->isBinaryUseKind(UntypedUse, ObjectUse)) {
+            setBoolean(
+                m_out.equal(
+                    lowNonNullObject(m_node->child2()),
+                    lowJSValue(m_node->child1())));
+            return;
+        }
+
         if (m_node->isBinaryUseKind(ObjectUse)) {
             setBoolean(
                 m_out.equal(
@@ -3527,11 +4212,15 @@ private:
             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CompareStrictEq StringIdent to NotStringVar continuation"));
             
             ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
-            m_out.branch(isCell(rightValue), unsure(isCellCase), unsure(continuation));
+            m_out.branch(
+                isCell(rightValue, provenType(rightEdge)),
+                unsure(isCellCase), unsure(continuation));
             
             LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
             ValueFromBlock notStringResult = m_out.anchor(m_out.booleanFalse);
-            m_out.branch(isString(rightValue), unsure(isStringCase), unsure(continuation));
+            m_out.branch(
+                isString(rightValue, provenType(rightEdge)),
+                unsure(isStringCase), unsure(continuation));
             
             m_out.appendTo(isStringCase, continuation);
             LValue right = m_out.loadPtr(rightValue, m_heaps.JSString_value);
@@ -3544,12 +4233,12 @@ private:
             return;
         }
         
-        LOWERING_FAILED(m_node, "Bad use kinds");
+        DFG_CRASH(m_graph, m_node, "Bad use kinds");
     }
     
     void compileCompareStrictEqConstant()
     {
-        JSValue constant = m_graph.valueOfJSConstant(m_node->child2().node());
+        JSValue constant = m_node->child2()->asJSValue();
 
         setBoolean(
             m_out.equal(
@@ -3581,15 +4270,61 @@ private:
     {
         setBoolean(m_out.bitNot(boolify(m_node->child1())));
     }
-    
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+    void compileNativeCallOrConstruct() 
+    {
+        int numPassedArgs = m_node->numChildren() - 1;
+        int numArgs = numPassedArgs;
+
+        JSFunction* knownFunction = m_node->castOperand<JSFunction*>();
+        NativeFunction function = knownFunction->nativeFunction();
+
+        Dl_info info;
+        if (!dladdr((void*)function, &info))
+            ASSERT(false); // if we couldn't find the native function this doesn't bode well.
+
+        LValue callee = getFunctionBySymbol(info.dli_sname);
+
+        bool notInlinable;
+        if ((notInlinable = !callee))
+            callee = m_out.operation(function);
+
+        m_out.storePtr(m_callFrame, m_execStorage, m_heaps.CallFrame_callerFrame);
+        m_out.storePtr(constNull(m_out.intPtr), addressFor(m_execStorage, JSStack::CodeBlock));
+        m_out.storePtr(weakPointer(knownFunction), addressFor(m_execStorage, JSStack::Callee));
+
+        m_out.store64(m_out.constInt64(numArgs), addressFor(m_execStorage, JSStack::ArgumentCount));
+
+        for (int i = 0; i < numPassedArgs; ++i) {
+            m_out.storePtr(lowJSValue(m_graph.varArgChild(m_node, 1 + i)),
+                addressFor(m_execStorage, JSStack::ThisArgument, i * sizeof(Register)));
+        }
+
+        LValue calleeCallFrame = m_out.address(m_execState, m_heaps.CallFrame_callerFrame).value();
+        m_out.storePtr(m_out.ptrToInt(calleeCallFrame, m_out.intPtr), m_out.absolute(&vm().topCallFrame));
+
+        LType typeCalleeArg;
+        getParamTypes(getElementType(typeOf(callee)), &typeCalleeArg);
+
+        LValue argument = notInlinable 
+            ? m_out.ptrToInt(calleeCallFrame, typeCalleeArg) 
+            : m_out.bitCast(calleeCallFrame, typeCalleeArg);
+        LValue call = vmCall(callee, argument);
+
+        if (verboseCompilationEnabled())
+            dataLog("Native calling: ", info.dli_sname, "\n");
+
+        setJSValue(call);
+    }
+#endif
+
     void compileCallOrConstruct()
     {
-        int dummyThisArgument = m_node->op() == Call ? 0 : 1;
         int numPassedArgs = m_node->numChildren() - 1;
-        int numArgs = numPassedArgs + dummyThisArgument;
-        
-        LValue callee = lowJSValue(m_graph.varArgChild(m_node, 0));
-        
+        int numArgs = numPassedArgs;
+
+        LValue jsCallee = lowJSValue(m_graph.varArgChild(m_node, 0));
+
         unsigned stackmapID = m_stackmapIDs++;
         
         Vector<LValue> arguments;
@@ -3597,13 +4332,10 @@ private:
         arguments.append(m_out.constInt32(sizeOfCall()));
         arguments.append(constNull(m_out.ref8));
         arguments.append(m_out.constInt32(1 + JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + numArgs));
-        arguments.append(callee); // callee -> %rax
+        arguments.append(jsCallee); // callee -> %rax
         arguments.append(getUndef(m_out.int64)); // code block
-        arguments.append(getUndef(m_out.int64)); // scope chain
-        arguments.append(callee); // callee -> stack
+        arguments.append(jsCallee); // callee -> stack
         arguments.append(m_out.constInt64(numArgs)); // argument count and zeros for the tag
-        if (dummyThisArgument)
-            arguments.append(getUndef(m_out.int64));
         for (int i = 0; i < numPassedArgs; ++i)
             arguments.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
         
@@ -3617,6 +4349,141 @@ private:
         setJSValue(call);
     }
     
+    void compileCallOrConstructVarargs()
+    {
+        LValue jsCallee = lowJSValue(m_node->child1());
+        LValue thisArg = lowJSValue(m_node->child3());
+        
+        LValue jsArguments = nullptr;
+        
+        switch (m_node->op()) {
+        case CallVarargs:
+        case ConstructVarargs:
+            jsArguments = lowJSValue(m_node->child2());
+            break;
+        case CallForwardVarargs:
+        case ConstructForwardVarargs:
+            break;
+        default:
+            DFG_CRASH(m_graph, m_node, "bad node type");
+            break;
+        }
+        
+        unsigned stackmapID = m_stackmapIDs++;
+        
+        Vector<LValue> arguments;
+        arguments.append(m_out.constInt64(stackmapID));
+        arguments.append(m_out.constInt32(sizeOfICFor(m_node)));
+        arguments.append(constNull(m_out.ref8));
+        arguments.append(m_out.constInt32(2 + !!jsArguments));
+        arguments.append(jsCallee);
+        if (jsArguments)
+            arguments.append(jsArguments);
+        ASSERT(thisArg);
+        arguments.append(thisArg);
+        
+        callPreflight();
+        
+        LValue call = m_out.call(m_out.patchpointInt64Intrinsic(), arguments);
+        setInstructionCallingConvention(call, LLVMCCallConv);
+        
+        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node));
+        
+        setJSValue(call);
+    }
+    
+    void compileLoadVarargs()
+    {
+        LoadVarargsData* data = m_node->loadVarargsData();
+        LValue jsArguments = lowJSValue(m_node->child1());
+        
+        LValue length = vmCall(
+            m_out.operation(operationSizeOfVarargs), m_callFrame, jsArguments,
+            m_out.constInt32(data->offset));
+        
+        // FIXME: There is a chance that we will call an effectful length property twice. This is safe
+        // from the standpoint of the VM's integrity, but it's subtly wrong from a spec compliance
+        // standpoint. The best solution would be one where we can exit *into* the op_call_varargs right
+        // past the sizing.
+        // https://bugs.webkit.org/show_bug.cgi?id=141448
+        
+        LValue lengthIncludingThis = m_out.add(length, m_out.int32One);
+        speculate(
+            VarargsOverflow, noValue(), nullptr,
+            m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
+        
+        m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
+        
+        // FIXME: This computation is rather silly. If operationLaodVarargs just took a pointer instead
+        // of a VirtualRegister, we wouldn't have to do this.
+        // https://bugs.webkit.org/show_bug.cgi?id=141660
+        LValue machineStart = m_out.lShr(
+            m_out.sub(addressFor(data->machineStart.offset()).value(), m_callFrame),
+            m_out.constIntPtr(3));
+        
+        vmCall(
+            m_out.operation(operationLoadVarargs), m_callFrame,
+            m_out.castToInt32(machineStart), jsArguments, m_out.constInt32(data->offset),
+            length, m_out.constInt32(data->mandatoryMinimum));
+    }
+    
+    void compileForwardVarargs()
+    {
+        LoadVarargsData* data = m_node->loadVarargsData();
+        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
+        
+        LValue length = getArgumentsLength(inlineCallFrame).value;
+        LValue lengthIncludingThis = m_out.add(length, m_out.constInt32(1 - data->offset));
+        
+        speculate(
+            VarargsOverflow, noValue(), nullptr,
+            m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
+        
+        m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
+        
+        LValue sourceStart = getArgumentsStart(inlineCallFrame);
+        LValue targetStart = addressFor(data->machineStart).value();
+
+        LBasicBlock undefinedLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs undefined loop body"));
+        LBasicBlock mainLoopEntry = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop entry"));
+        LBasicBlock mainLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop body"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ForwardVarargs continuation"));
+        
+        LValue lengthAsPtr = m_out.zeroExtPtr(length);
+        ValueFromBlock loopBound = m_out.anchor(m_out.constIntPtr(data->mandatoryMinimum));
+        m_out.branch(
+            m_out.above(loopBound.value(), lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
+        
+        LBasicBlock lastNext = m_out.appendTo(undefinedLoop, mainLoopEntry);
+        LValue previousIndex = m_out.phi(m_out.intPtr, loopBound);
+        LValue currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
+        m_out.store64(
+            m_out.constInt64(JSValue::encode(jsUndefined())),
+            m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
+        ValueFromBlock nextIndex = m_out.anchor(currentIndex);
+        addIncoming(previousIndex, nextIndex);
+        m_out.branch(
+            m_out.above(currentIndex, lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
+        
+        m_out.appendTo(mainLoopEntry, mainLoop);
+        loopBound = m_out.anchor(lengthAsPtr);
+        m_out.branch(m_out.notNull(loopBound.value()), unsure(mainLoop), unsure(continuation));
+        
+        m_out.appendTo(mainLoop, continuation);
+        previousIndex = m_out.phi(m_out.intPtr, loopBound);
+        currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
+        LValue value = m_out.load64(
+            m_out.baseIndex(
+                m_heaps.variables, sourceStart,
+                m_out.add(currentIndex, m_out.constIntPtr(data->offset))));
+        m_out.store64(value, m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
+        nextIndex = m_out.anchor(currentIndex);
+        addIncoming(previousIndex, nextIndex);
+        m_out.branch(m_out.isNull(currentIndex), unsure(continuation), unsure(mainLoop));
+        
+        m_out.appendTo(continuation, lastNext);
+    }
+
     void compileJump()
     {
         m_out.jump(lowBlock(m_node->targetBlock()));
@@ -3666,7 +4533,7 @@ private:
                 
                 m_out.appendTo(isNotInt, isDouble);
                 m_out.branch(
-                    isCellOrMisc(boxedValue),
+                    isCellOrMisc(boxedValue, provenType(m_node->child1())),
                     usually(lowBlock(data->fallThrough.block)), rarely(isDouble));
                 
                 m_out.appendTo(isDouble, innerLastNext);
@@ -3680,8 +4547,8 @@ private:
             }
                 
             default:
-                LOWERING_FAILED(m_node, "Bad use kind");
-                return;
+                DFG_CRASH(m_graph, m_node, "Bad use kind");
+                break;
             }
             
             m_out.appendTo(switchOnInts, lastNext);
@@ -3711,13 +4578,13 @@ private:
                 LBasicBlock isStringCase = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar is string"));
                 
                 m_out.branch(
-                    isNotCell(unboxedValue),
+                    isNotCell(unboxedValue, provenType(m_node->child1())),
                     unsure(lowBlock(data->fallThrough.block)), unsure(isCellCase));
                 
                 LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
                 LValue cellValue = unboxedValue;
                 m_out.branch(
-                    isNotString(cellValue),
+                    isNotString(cellValue, provenType(m_node->child1())),
                     unsure(lowBlock(data->fallThrough.block)), unsure(isStringCase));
                 
                 m_out.appendTo(isStringCase, lastNext);
@@ -3726,8 +4593,8 @@ private:
             }
                 
             default:
-                LOWERING_FAILED(m_node, "Bad use kind");
-                return;
+                DFG_CRASH(m_graph, m_node, "Bad use kind");
+                break;
             }
             
             LBasicBlock lengthIs1 = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar length is 1"));
@@ -3778,12 +4645,88 @@ private:
             return;
         }
         
-        case SwitchString:
-            LOWERING_FAILED(m_node, "Unimplemented");
-            break;
+        case SwitchString: {
+            switch (m_node->child1().useKind()) {
+            case StringIdentUse: {
+                LValue stringImpl = lowStringIdent(m_node->child1());
+                
+                Vector<SwitchCase> cases;
+                for (unsigned i = 0; i < data->cases.size(); ++i) {
+                    LValue value = m_out.constIntPtr(data->cases[i].value.stringImpl());
+                    LBasicBlock block = lowBlock(data->cases[i].target.block);
+                    Weight weight = Weight(data->cases[i].target.count);
+                    cases.append(SwitchCase(value, block, weight));
+                }
+                
+                m_out.switchInstruction(
+                    stringImpl, cases, lowBlock(data->fallThrough.block),
+                    Weight(data->fallThrough.count));
+                return;
+            }
+                
+            case StringUse: {
+                switchString(data, lowString(m_node->child1()));
+                return;
+            }
+                
+            case UntypedUse: {
+                LValue value = lowJSValue(m_node->child1());
+                
+                LBasicBlock isCellBlock = FTL_NEW_BLOCK(m_out, ("Switch/SwitchString Untyped cell case"));
+                LBasicBlock isStringBlock = FTL_NEW_BLOCK(m_out, ("Switch/SwitchString Untyped string case"));
+                
+                m_out.branch(
+                    isCell(value, provenType(m_node->child1())),
+                    unsure(isCellBlock), unsure(lowBlock(data->fallThrough.block)));
+                
+                LBasicBlock lastNext = m_out.appendTo(isCellBlock, isStringBlock);
+                
+                m_out.branch(
+                    isString(value, provenType(m_node->child1())),
+                    unsure(isStringBlock), unsure(lowBlock(data->fallThrough.block)));
+                
+                m_out.appendTo(isStringBlock, lastNext);
+                
+                switchString(data, value);
+                return;
+            }
+                
+            default:
+                DFG_CRASH(m_graph, m_node, "Bad use kind");
+                return;
+            }
+            return;
         }
+            
+        case SwitchCell: {
+            LValue cell;
+            switch (m_node->child1().useKind()) {
+            case CellUse: {
+                cell = lowCell(m_node->child1());
+                break;
+            }
+                
+            case UntypedUse: {
+                LValue value = lowJSValue(m_node->child1());
+                LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("Switch/SwitchCell cell case"));
+                m_out.branch(
+                    isCell(value, provenType(m_node->child1())),
+                    unsure(cellCase), unsure(lowBlock(data->fallThrough.block)));
+                m_out.appendTo(cellCase);
+                cell = value;
+                break;
+            }
+                
+            default:
+                DFG_CRASH(m_graph, m_node, "Bad use kind");
+                return;
+            }
+            
+            buildSwitch(m_node->switchData(), m_out.intPtr, cell);
+            return;
+        } }
         
-        LOWERING_FAILED(m_node, "Bad switch kind");
+        DFG_CRASH(m_graph, m_node, "Bad switch kind");
     }
     
     void compileReturn()
@@ -3804,12 +4747,13 @@ private:
     void compileInvalidationPoint()
     {
         if (verboseCompilationEnabled())
-            dataLog("    Invalidation point with availability: ", m_availability, "\n");
+            dataLog("    Invalidation point with availability: ", availabilityMap(), "\n");
         
         m_ftlState.jitCode->osrExit.append(OSRExit(
             UncountableInvalidation, InvalidValueFormat, MethodOfGettingAValueProfile(),
             m_codeOriginForExitTarget, m_codeOriginForExitProfile,
-            m_availability.numberOfArguments(), m_availability.numberOfLocals()));
+            availabilityMap().m_locals.numberOfArguments(),
+            availabilityMap().m_locals.numberOfLocals()));
         m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
         
         OSRExit& exit = m_ftlState.jitCode->osrExit.last();
@@ -3823,15 +4767,6 @@ private:
         info.m_isInvalidationPoint = true;
     }
     
-    void compileCheckArgumentsNotCreated()
-    {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_graph.argumentsRegisterFor(m_node->origin.semantic)).m_type));
-        
-        checkArgumentsNotCreated();
-    }
-    
     void compileIsUndefined()
     {
         setBoolean(equalNullOrUndefined(m_node->child1(), AllCellsAreFalse, EqualUndefined));
@@ -3839,12 +4774,12 @@ private:
     
     void compileIsBoolean()
     {
-        setBoolean(isBoolean(lowJSValue(m_node->child1())));
+        setBoolean(isBoolean(lowJSValue(m_node->child1()), provenType(m_node->child1())));
     }
     
     void compileIsNumber()
     {
-        setBoolean(isNumber(lowJSValue(m_node->child1())));
+        setBoolean(isNumber(lowJSValue(m_node->child1()), provenType(m_node->child1())));
     }
     
     void compileIsString()
@@ -3855,30 +4790,178 @@ private:
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("IsString continuation"));
         
         ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
-        m_out.branch(isCell(value), unsure(isCellCase), unsure(continuation));
+        m_out.branch(
+            isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation));
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
-        ValueFromBlock cellResult = m_out.anchor(isString(value));
+        ValueFromBlock cellResult = m_out.anchor(isString(value, provenType(m_node->child1())));
         m_out.jump(continuation);
         
         m_out.appendTo(continuation, lastNext);
         setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
     }
-    
+
     void compileIsObject()
     {
-        LValue pointerResult = vmCall(
-            m_out.operation(operationIsObject), m_callFrame, lowJSValue(m_node->child1()));
-        setBoolean(m_out.notNull(pointerResult));
+        LValue value = lowJSValue(m_node->child1());
+
+        LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("IsObject cell case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("IsObject continuation"));
+
+        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
+        ValueFromBlock cellResult = m_out.anchor(isObject(value, provenType(m_node->child1())));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
+    }
+
+    void compileIsObjectOrNull()
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+        
+        Edge child = m_node->child1();
+        LValue value = lowJSValue(child);
+        
+        LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull cell case"));
+        LBasicBlock notFunctionCase = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull not function case"));
+        LBasicBlock objectCase = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull object case"));
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull slow path"));
+        LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull not cell case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("IsObjectOrNull continuation"));
+        
+        m_out.branch(isCell(value, provenType(child)), unsure(cellCase), unsure(notCellCase));
+        
+        LBasicBlock lastNext = m_out.appendTo(cellCase, notFunctionCase);
+        ValueFromBlock isFunctionResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isFunction(value, provenType(child)),
+            unsure(continuation), unsure(notFunctionCase));
+        
+        m_out.appendTo(notFunctionCase, objectCase);
+        ValueFromBlock notObjectResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isObject(value, provenType(child)),
+            unsure(objectCase), unsure(continuation));
+        
+        m_out.appendTo(objectCase, slowPath);
+        ValueFromBlock objectResult = m_out.anchor(m_out.booleanTrue);
+        m_out.branch(
+            isExoticForTypeof(value, provenType(child)),
+            rarely(slowPath), usually(continuation));
+        
+        m_out.appendTo(slowPath, notCellCase);
+        LValue slowResultValue = vmCall(
+            m_out.operation(operationObjectIsObject), m_callFrame, weakPointer(globalObject),
+            value);
+        ValueFromBlock slowResult = m_out.anchor(m_out.notNull(slowResultValue));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(notCellCase, continuation);
+        LValue notCellResultValue = m_out.equal(value, m_out.constInt64(JSValue::encode(jsNull())));
+        ValueFromBlock notCellResult = m_out.anchor(notCellResultValue);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(
+            m_out.boolean,
+            isFunctionResult, notObjectResult, objectResult, slowResult, notCellResult);
+        setBoolean(result);
     }
     
     void compileIsFunction()
     {
-        LValue pointerResult = vmCall(
-            m_out.operation(operationIsFunction), lowJSValue(m_node->child1()));
-        setBoolean(m_out.notNull(pointerResult));
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+        
+        Edge child = m_node->child1();
+        LValue value = lowJSValue(child);
+        
+        LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("IsFunction cell case"));
+        LBasicBlock notFunctionCase = FTL_NEW_BLOCK(m_out, ("IsFunction not function case"));
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("IsFunction slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("IsFunction continuation"));
+        
+        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isCell(value, provenType(child)), unsure(cellCase), unsure(continuation));
+        
+        LBasicBlock lastNext = m_out.appendTo(cellCase, notFunctionCase);
+        ValueFromBlock functionResult = m_out.anchor(m_out.booleanTrue);
+        m_out.branch(
+            isFunction(value, provenType(child)),
+            unsure(continuation), unsure(notFunctionCase));
+        
+        m_out.appendTo(notFunctionCase, slowPath);
+        ValueFromBlock objectResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isExoticForTypeof(value, provenType(child)),
+            rarely(slowPath), usually(continuation));
+        
+        m_out.appendTo(slowPath, continuation);
+        LValue slowResultValue = vmCall(
+            m_out.operation(operationObjectIsFunction), m_callFrame, weakPointer(globalObject),
+            value);
+        ValueFromBlock slowResult = m_out.anchor(m_out.notNull(slowResultValue));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(
+            m_out.boolean, notCellResult, functionResult, objectResult, slowResult);
+        setBoolean(result);
     }
     
+    void compileTypeOf()
+    {
+        Edge child = m_node->child1();
+        LValue value = lowJSValue(child);
+        
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("TypeOf continuation"));
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
+        
+        Vector<ValueFromBlock> results;
+        
+        buildTypeOf(
+            child, value,
+            [&] (TypeofType type) {
+                results.append(m_out.anchor(weakPointer(vm().smallStrings.typeString(type))));
+                m_out.jump(continuation);
+            });
+        
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, results));
+    }
+    
+    void compileIn()
+    {
+        Edge base = m_node->child2();
+        LValue cell = lowCell(base);
+        speculateObject(base, cell);
+        if (JSString* string = m_node->child1()->dynamicCastConstant<JSString*>()) {
+            if (string->tryGetValueImpl() && string->tryGetValueImpl()->isAtomic()) {
+
+                const auto str = static_cast<const AtomicStringImpl*>(string->tryGetValueImpl());
+                unsigned stackmapID = m_stackmapIDs++;
+            
+                LValue call = m_out.call(
+                    m_out.patchpointInt64Intrinsic(),
+                    m_out.constInt64(stackmapID), m_out.constInt32(sizeOfIn()),
+                    constNull(m_out.ref8), m_out.constInt32(1), cell);
+
+                setInstructionCallingConvention(call, LLVMAnyRegCallConv);
+
+                m_ftlState.checkIns.append(CheckInDescriptor(stackmapID, m_node->origin.semantic, str));
+                setJSValue(call);
+                return;
+            }
+        } 
+
+        setJSValue(vmCall(m_out.operation(operationGenericIn), m_callFrame, cell, lowJSValue(m_node->child1())));
+    }
+
     void compileCheckHasInstance()
     {
         speculate(
@@ -3906,7 +4989,7 @@ private:
         
         LValue condition;
         if (m_node->child1().useKind() == UntypedUse)
-            condition = isCell(cell);
+            condition = isCell(cell, provenType(m_node->child1()));
         else
             condition = m_out.booleanTrue;
         
@@ -3915,7 +4998,7 @@ private:
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, loop);
         
-        speculate(BadType, noValue(), 0, isNotObject(prototype));
+        speculate(BadType, noValue(), 0, isNotObject(prototype, provenType(m_node->child2())));
         
         ValueFromBlock originalValue = m_out.anchor(cell);
         m_out.jump(loop);
@@ -3950,20 +5033,547 @@ private:
         emitStoreBarrier(lowCell(m_node->child1()));
     }
 
-    void compileStoreBarrierWithNullCheck()
+    void compileHasIndexedProperty()
     {
-#if ENABLE(GGC)
-        LBasicBlock isNotNull = FTL_NEW_BLOCK(m_out, ("Store barrier with null check value not null"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Store barrier continuation"));
+        switch (m_node->arrayMode().type()) {
+        case Array::Int32:
+        case Array::Contiguous: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            LValue storage = lowStorage(m_node->child3());
+
+            IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
+                m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
+
+            LBasicBlock checkHole = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous check hole"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty int/contiguous continuation"));
+
+            if (!m_node->arrayMode().isInBounds()) {
+                m_out.branch(
+                    m_out.aboveOrEqual(
+                        index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
+                    rarely(slowCase), usually(checkHole));
+            } else
+                m_out.jump(checkHole);
+
+            LBasicBlock lastNext = m_out.appendTo(checkHole, slowCase); 
+            ValueFromBlock checkHoleResult = m_out.anchor(
+                m_out.notZero64(m_out.load64(baseIndex(heap, storage, index, m_node->child2()))));
+            m_out.branch(checkHoleResult.value(), usually(continuation), rarely(slowCase));
+
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(m_out.equal(
+                m_out.constInt64(JSValue::encode(jsBoolean(true))), 
+                vmCall(m_out.operation(operationHasIndexedProperty), m_callFrame, base, index)));
+            m_out.jump(continuation);
+
+            m_out.appendTo(continuation, lastNext);
+            setBoolean(m_out.phi(m_out.boolean, checkHoleResult, slowResult));
+            return;
+        }
+        case Array::Double: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            LValue storage = lowStorage(m_node->child3());
+            
+            IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
+            
+            LBasicBlock checkHole = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double check hole"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasIndexedProperty double continuation"));
+            
+            if (!m_node->arrayMode().isInBounds()) {
+                m_out.branch(
+                    m_out.aboveOrEqual(
+                        index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
+                    rarely(slowCase), usually(checkHole));
+            } else
+                m_out.jump(checkHole);
 
+            LBasicBlock lastNext = m_out.appendTo(checkHole, slowCase);
+            LValue doubleValue = m_out.loadDouble(baseIndex(heap, storage, index, m_node->child2()));
+            ValueFromBlock checkHoleResult = m_out.anchor(m_out.doubleEqual(doubleValue, doubleValue));
+            m_out.branch(checkHoleResult.value(), usually(continuation), rarely(slowCase));
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(m_out.equal(
+                m_out.constInt64(JSValue::encode(jsBoolean(true))), 
+                vmCall(m_out.operation(operationHasIndexedProperty), m_callFrame, base, index)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setBoolean(m_out.phi(m_out.boolean, checkHoleResult, slowResult));
+            return;
+        }
+            
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+    }
+
+    void compileHasGenericProperty()
+    {
         LValue base = lowJSValue(m_node->child1());
-        m_out.branch(m_out.isZero64(base), unsure(continuation), unsure(isNotNull));
-        LBasicBlock lastNext = m_out.appendTo(isNotNull, continuation);
-        emitStoreBarrier(base);
+        LValue property = lowCell(m_node->child2());
+        setJSValue(vmCall(m_out.operation(operationHasGenericProperty), m_callFrame, base, property));
+    }
+
+    void compileHasStructureProperty()
+    {
+        LValue base = lowJSValue(m_node->child1());
+        LValue property = lowString(m_node->child2());
+        LValue enumerator = lowCell(m_node->child3());
+
+        LBasicBlock correctStructure = FTL_NEW_BLOCK(m_out, ("HasStructureProperty correct structure"));
+        LBasicBlock wrongStructure = FTL_NEW_BLOCK(m_out, ("HasStructureProperty wrong structure"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("HasStructureProperty continuation"));
+
+        m_out.branch(m_out.notEqual(
+            m_out.load32(base, m_heaps.JSCell_structureID),
+            m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedStructureID)),
+            rarely(wrongStructure), usually(correctStructure));
+
+        LBasicBlock lastNext = m_out.appendTo(correctStructure, wrongStructure);
+        ValueFromBlock correctStructureResult = m_out.anchor(m_out.booleanTrue);
+        m_out.jump(continuation);
+
+        m_out.appendTo(wrongStructure, continuation);
+        ValueFromBlock wrongStructureResult = m_out.anchor(
+            m_out.equal(
+                m_out.constInt64(JSValue::encode(jsBoolean(true))), 
+                vmCall(m_out.operation(operationHasGenericProperty), m_callFrame, base, property)));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setBoolean(m_out.phi(m_out.boolean, correctStructureResult, wrongStructureResult));
+    }
+
+    void compileGetDirectPname()
+    {
+        LValue base = lowCell(m_graph.varArgChild(m_node, 0));
+        LValue property = lowCell(m_graph.varArgChild(m_node, 1));
+        LValue index = lowInt32(m_graph.varArgChild(m_node, 2));
+        LValue enumerator = lowCell(m_graph.varArgChild(m_node, 3));
+
+        LBasicBlock checkOffset = FTL_NEW_BLOCK(m_out, ("GetDirectPname check offset"));
+        LBasicBlock inlineLoad = FTL_NEW_BLOCK(m_out, ("GetDirectPname inline load"));
+        LBasicBlock outOfLineLoad = FTL_NEW_BLOCK(m_out, ("GetDirectPname out-of-line load"));
+        LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetDirectPname slow case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetDirectPname continuation"));
+
+        m_out.branch(m_out.notEqual(
+            m_out.load32(base, m_heaps.JSCell_structureID),
+            m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedStructureID)),
+            rarely(slowCase), usually(checkOffset));
+
+        LBasicBlock lastNext = m_out.appendTo(checkOffset, inlineLoad);
+        m_out.branch(m_out.aboveOrEqual(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedInlineCapacity)),
+            unsure(outOfLineLoad), unsure(inlineLoad));
+
+        m_out.appendTo(inlineLoad, outOfLineLoad);
+        ValueFromBlock inlineResult = m_out.anchor(
+            m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), 
+                base, m_out.zeroExt(index, m_out.int64), ScaleEight, JSObject::offsetOfInlineStorage())));
+        m_out.jump(continuation);
+
+        m_out.appendTo(outOfLineLoad, slowCase);
+        LValue storage = m_out.loadPtr(base, m_heaps.JSObject_butterfly);
+        LValue realIndex = m_out.signExt(
+            m_out.neg(m_out.sub(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedInlineCapacity))), 
+            m_out.int64);
+        int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
+        ValueFromBlock outOfLineResult = m_out.anchor(
+            m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), storage, realIndex, ScaleEight, offsetOfFirstProperty)));
+        m_out.jump(continuation);
+
+        m_out.appendTo(slowCase, continuation);
+        ValueFromBlock slowCaseResult = m_out.anchor(
+            vmCall(m_out.operation(operationGetByVal), m_callFrame, base, property));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, inlineResult, outOfLineResult, slowCaseResult));
+    }
+
+    void compileGetEnumerableLength()
+    {
+        LValue enumerator = lowCell(m_node->child1());
+        setInt32(m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_indexLength));
+    }
+
+    void compileGetPropertyEnumerator()
+    {
+        LValue base = lowCell(m_node->child1());
+        setJSValue(vmCall(m_out.operation(operationGetPropertyEnumerator), m_callFrame, base));
+    }
+
+    void compileGetEnumeratorStructurePname()
+    {
+        LValue enumerator = lowCell(m_node->child1());
+        LValue index = lowInt32(m_node->child2());
+
+        LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname in bounds"));
+        LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname out of bounds"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname continuation"));
+
+        m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_endStructurePropertyIndex)),
+            usually(inBounds), rarely(outOfBounds));
+
+        LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
+        LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
+        ValueFromBlock inBoundsResult = m_out.anchor(
+            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
+        m_out.jump(continuation);
+
+        m_out.appendTo(outOfBounds, continuation);
+        ValueFromBlock outOfBoundsResult = m_out.anchor(m_out.constInt64(ValueNull));
+        m_out.jump(continuation);
+        
         m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, inBoundsResult, outOfBoundsResult));
+    }
+
+    void compileGetEnumeratorGenericPname()
+    {
+        LValue enumerator = lowCell(m_node->child1());
+        LValue index = lowInt32(m_node->child2());
+
+        LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname in bounds"));
+        LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname out of bounds"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname continuation"));
+
+        m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_endGenericPropertyIndex)),
+            usually(inBounds), rarely(outOfBounds));
+
+        LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
+        LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
+        ValueFromBlock inBoundsResult = m_out.anchor(
+            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
+        m_out.jump(continuation);
+
+        m_out.appendTo(outOfBounds, continuation);
+        ValueFromBlock outOfBoundsResult = m_out.anchor(m_out.constInt64(ValueNull));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, inBoundsResult, outOfBoundsResult));
+    }
+    
+    void compileToIndexString()
+    {
+        LValue index = lowInt32(m_node->child1());
+        setJSValue(vmCall(m_out.operation(operationToIndexString), m_callFrame, index));
+    }
+    
+    void compileCheckStructureImmediate()
+    {
+        LValue structure = lowCell(m_node->child1());
+        checkStructure(
+            structure, noValue(), BadCache, m_node->structureSet(),
+            [this] (Structure* structure) {
+                return weakStructure(structure);
+            });
+    }
+    
+    void compileMaterializeNewObject()
+    {
+        ObjectMaterializationData& data = m_node->objectMaterializationData();
+        
+        // Lower the values first, to avoid creating values inside a control flow diamond.
+        
+        Vector<LValue, 8> values;
+        for (unsigned i = 0; i < data.m_properties.size(); ++i)
+            values.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
+        
+        StructureSet set;
+        m_interpreter.phiChildren()->forAllTransitiveIncomingValues(
+            m_graph.varArgChild(m_node, 0).node(),
+            [&] (Node* incoming) {
+                set.add(incoming->castConstant<Structure*>());
+            });
+        
+        Vector<LBasicBlock, 1> blocks(set.size());
+        for (unsigned i = set.size(); i--;)
+            blocks[i] = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject case ", i));
+        LBasicBlock dummyDefault = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject default case"));
+        LBasicBlock outerContinuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject continuation"));
+        
+        Vector<SwitchCase, 1> cases(set.size());
+        for (unsigned i = set.size(); i--;)
+            cases[i] = SwitchCase(weakStructure(set[i]), blocks[i], Weight(1));
+        m_out.switchInstruction(
+            lowCell(m_graph.varArgChild(m_node, 0)), cases, dummyDefault, Weight(0));
+        
+        LBasicBlock outerLastNext = m_out.m_nextBlock;
+        
+        Vector<ValueFromBlock, 1> results;
+        
+        for (unsigned i = set.size(); i--;) {
+            m_out.appendTo(blocks[i], i + 1 < set.size() ? blocks[i + 1] : dummyDefault);
+            
+            Structure* structure = set[i];
+            
+            LValue object;
+            LValue butterfly;
+            
+            if (structure->outOfLineCapacity()) {
+                size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
+                MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
+                
+                LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation slow path"));
+                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation continuation"));
+                
+                LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+                
+                LValue endOfStorage = allocateBasicStorageAndGetEnd(
+                    m_out.constIntPtr(structure->outOfLineCapacity() * sizeof(JSValue)),
+                    slowPath);
+                
+                LValue fastButterflyValue = m_out.add(
+                    m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage);
+                
+                LValue fastObjectValue = allocateObject(
+                    m_out.constIntPtr(allocator), structure, fastButterflyValue, slowPath);
+
+                ValueFromBlock fastObject = m_out.anchor(fastObjectValue);
+                ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue);
+                m_out.jump(continuation);
+                
+                m_out.appendTo(slowPath, continuation);
+                
+                ValueFromBlock slowObject = m_out.anchor(vmCall(
+                    m_out.operation(operationNewObjectWithButterfly),
+                    m_callFrame, m_out.constIntPtr(structure)));
+                ValueFromBlock slowButterfly = m_out.anchor(
+                    m_out.loadPtr(slowObject.value(), m_heaps.JSObject_butterfly));
+                
+                m_out.jump(continuation);
+                
+                m_out.appendTo(continuation, lastNext);
+                
+                object = m_out.phi(m_out.intPtr, fastObject, slowObject);
+                butterfly = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
+            } else {
+                // In the easy case where we can do a one-shot allocation, we simply allocate the
+                // object to directly have the desired structure.
+                object = allocateObject(structure);
+                butterfly = nullptr; // Don't have one, don't need one.
+            }
+            
+            for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
+                for (unsigned i = data.m_properties.size(); i--;) {
+                    PhantomPropertyValue value = data.m_properties[i];
+                    if (m_graph.identifiers()[value.m_identifierNumber] != entry.key)
+                        continue;
+                    
+                    LValue base = isInlineOffset(entry.offset) ? object : butterfly;
+                    storeProperty(values[i], base, value.m_identifierNumber, entry.offset);
+                    break;
+                }
+            }
+            
+            results.append(m_out.anchor(object));
+            m_out.jump(outerContinuation);
+        }
+        
+        m_out.appendTo(dummyDefault, outerContinuation);
+        m_out.unreachable();
+        
+        m_out.appendTo(outerContinuation, outerLastNext);
+        setJSValue(m_out.phi(m_out.intPtr, results));
+    }
+
+    void compileMaterializeCreateActivation()
+    {
+        ObjectMaterializationData& data = m_node->objectMaterializationData();
+
+        Vector<LValue, 8> values;
+        for (unsigned i = 0; i < data.m_properties.size(); ++i)
+            values.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
+
+        LValue scope = lowCell(m_graph.varArgChild(m_node, 0));
+        SymbolTable* table = m_node->castOperand<SymbolTable*>();
+        Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure();
+
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("MaterializeCreateActivation slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MaterializeCreateActivation continuation"));
+
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+
+        LValue fastObject = allocateObject<JSLexicalEnvironment>(
+            JSLexicalEnvironment::allocationSize(table), structure, m_out.intPtrZero, slowPath);
+
+        m_out.storePtr(scope, fastObject, m_heaps.JSScope_next);
+        m_out.storePtr(weakPointer(table), fastObject, m_heaps.JSSymbolTableObject_symbolTable);
+
+
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
+        m_out.jump(continuation);
+
+        m_out.appendTo(slowPath, continuation);
+        LValue callResult = vmCall(
+            m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
+            scope, weakPointer(table));
+        ValueFromBlock slowResult =  m_out.anchor(callResult);
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        LValue activation = m_out.phi(m_out.intPtr, fastResult, slowResult);
+        RELEASE_ASSERT(data.m_properties.size() == table->scopeSize());
+        for (unsigned i = 0; i < data.m_properties.size(); ++i) {
+            m_out.store64(values[i],
+                activation,
+                m_heaps.JSEnvironmentRecord_variables[data.m_properties[i].m_identifierNumber]);
+        }
+
+        if (validationEnabled()) {
+            // Validate to make sure every slot in the scope has one value.
+            ConcurrentJITLocker locker(table->m_lock);
+            for (auto iter = table->begin(locker), end = table->end(locker); iter != end; ++iter) {
+                bool found = false;
+                for (unsigned i = 0; i < data.m_properties.size(); ++i) {
+                    if (iter->value.scopeOffset().offset() == data.m_properties[i].m_identifierNumber) {
+                        found = true;
+                        break;
+                    }
+                }
+                ASSERT_UNUSED(found, found);
+            }
+        }
+
+        setJSValue(activation);
+    }
+
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+    LValue getFunctionBySymbol(const CString symbol)
+    {
+        if (!m_ftlState.symbolTable.contains(symbol)) 
+            return nullptr;
+        if (!getModuleByPathForSymbol(m_ftlState.symbolTable.get(symbol), symbol))
+            return nullptr;
+        return getNamedFunction(m_ftlState.module, symbol.data());
+    }
+
+    bool getModuleByPathForSymbol(const CString path, const CString symbol)
+    {
+        if (m_ftlState.nativeLoadedLibraries.contains(path)) {
+            LValue function = getNamedFunction(m_ftlState.module, symbol.data());
+            if (!isInlinableSize(function)) {
+                // We had no choice but to compile this function, but don't try to inline it ever again.
+                m_ftlState.symbolTable.remove(symbol);
+                return false;
+            }
+            return true;
+        }
+
+        LMemoryBuffer memBuf;
+        
+        ASSERT(isX86() || isARM64());
+
+#if PLATFORM(EFL)
+        const CString actualPath = toCString(bundlePath().data(), "/runtime/", path.data());
 #else
-        speculate(m_node->child1());
+        const CString actualPath = toCString(bundlePath().data(), 
+            isX86() ? "/Resources/Runtime/x86_64/" : "/Resources/Runtime/arm64/",
+            path.data());
 #endif
+
+        char* outMsg;
+        
+        if (createMemoryBufferWithContentsOfFile(actualPath.data(), &memBuf, &outMsg)) {
+            if (Options::verboseFTLFailure())
+                dataLog("Failed to load module at ", actualPath, "\n for symbol ", symbol, "\nERROR: ", outMsg, "\n");
+            disposeMessage(outMsg);
+            return false;
+        }
+
+        LModule module;
+
+        if (parseBitcodeInContext(m_ftlState.context, memBuf, &module, &outMsg)) {
+            if (Options::verboseFTLFailure())
+                dataLog("Failed to parse module at ", actualPath, "\n for symbol ", symbol, "\nERROR: ", outMsg, "\n");
+            disposeMemoryBuffer(memBuf);
+            disposeMessage(outMsg);
+            return false;
+        }
+
+        disposeMemoryBuffer(memBuf);
+
+        if (LValue function = getNamedFunction(m_ftlState.module, symbol.data())) {
+            if (!isInlinableSize(function)) {
+                m_ftlState.symbolTable.remove(symbol);
+                disposeModule(module);
+                return false;
+            }
+        }
+
+        Vector<CString> namedFunctions;
+        for (LValue function = getFirstFunction(module); function; function = getNextFunction(function)) {
+            CString functionName(getValueName(function));
+            namedFunctions.append(functionName);
+            
+            for (LBasicBlock basicBlock = getFirstBasicBlock(function); basicBlock; basicBlock = getNextBasicBlock(basicBlock)) {
+                for (LValue instruction = getFirstInstruction(basicBlock); instruction; instruction = getNextInstruction(instruction)) {
+                    setMetadata(instruction, m_tbaaKind, nullptr);
+                    setMetadata(instruction, m_tbaaStructKind, nullptr);
+                }
+            }
+        }
+
+        Vector<CString> namedGlobals;
+        for (LValue global = getFirstGlobal(module); global; global = getNextGlobal(global)) {
+            CString globalName(getValueName(global));
+            namedGlobals.append(globalName);
+        }
+
+        if (linkModules(m_ftlState.module, module, LLVMLinkerDestroySource, &outMsg)) {
+            if (Options::verboseFTLFailure())
+                dataLog("Failed to link module at ", actualPath, "\n for symbol ", symbol, "\nERROR: ", outMsg, "\n");
+            disposeMessage(outMsg);
+            return false;
+        }
+        
+        for (CString* symbol = namedFunctions.begin(); symbol != namedFunctions.end(); ++symbol) {
+            LValue function = getNamedFunction(m_ftlState.module, symbol->data());
+            LLVMLinkage linkage = getLinkage(function);
+            if (linkage != LLVMInternalLinkage && linkage != LLVMPrivateLinkage)
+                setVisibility(function, LLVMHiddenVisibility);
+            if (!isDeclaration(function)) {
+                setLinkage(function, LLVMPrivateLinkage);
+                setLinkage(function, LLVMAvailableExternallyLinkage);
+
+                if (ASSERT_DISABLED)
+                    removeFunctionAttr(function, LLVMStackProtectAttribute);
+            }
+        }
+
+        for (CString* symbol = namedGlobals.begin(); symbol != namedGlobals.end(); ++symbol) {
+            LValue global = getNamedGlobal(m_ftlState.module, symbol->data());
+            LLVMLinkage linkage = getLinkage(global);
+            if (linkage != LLVMInternalLinkage && linkage != LLVMPrivateLinkage)
+                setVisibility(global, LLVMHiddenVisibility);
+            if (!isDeclaration(global))
+                setLinkage(global, LLVMPrivateLinkage);
+        }
+
+        m_ftlState.nativeLoadedLibraries.add(path);
+        return true;
+    }
+#endif
+
+    bool isInlinableSize(LValue function)
+    {
+        size_t instructionCount = 0;
+        size_t maxSize = Options::maximumLLVMInstructionCountForNativeInlining();
+        for (LBasicBlock basicBlock = getFirstBasicBlock(function); basicBlock; basicBlock = getNextBasicBlock(basicBlock)) {
+            for (LValue instruction = getFirstInstruction(basicBlock); instruction; instruction = getNextInstruction(instruction)) {
+                if (++instructionCount >= maxSize)
+                    return false;
+            }
+        }
+        return true;
     }
 
     LValue didOverflowStack()
@@ -3988,6 +5598,8 @@ private:
                 case PutById:
                 case Call:
                 case Construct:
+                case NativeCall:
+                case NativeConstruct:
                     return m_out.below(
                         m_callFrame,
                         m_out.loadPtr(
@@ -4002,6 +5614,98 @@ private:
         return m_out.booleanFalse;
     }
     
+    struct ArgumentsLength {
+        ArgumentsLength()
+            : isKnown(false)
+            , known(UINT_MAX)
+            , value(nullptr)
+        {
+        }
+        
+        bool isKnown;
+        unsigned known;
+        LValue value;
+    };
+    ArgumentsLength getArgumentsLength(InlineCallFrame* inlineCallFrame)
+    {
+        ArgumentsLength length;
+
+        if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+            length.known = inlineCallFrame->arguments.size() - 1;
+            length.isKnown = true;
+            length.value = m_out.constInt32(length.known);
+        } else {
+            length.known = UINT_MAX;
+            length.isKnown = false;
+            
+            VirtualRegister argumentCountRegister;
+            if (!inlineCallFrame)
+                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+            else
+                argumentCountRegister = inlineCallFrame->argumentCountRegister;
+            length.value = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
+        }
+        
+        return length;
+    }
+    
+    ArgumentsLength getArgumentsLength()
+    {
+        return getArgumentsLength(m_node->origin.semantic.inlineCallFrame);
+    }
+    
+    LValue getCurrentCallee()
+    {
+        if (InlineCallFrame* frame = m_node->origin.semantic.inlineCallFrame) {
+            if (frame->isClosureCall)
+                return m_out.loadPtr(addressFor(frame->calleeRecovery.virtualRegister()));
+            return weakPointer(frame->calleeRecovery.constant().asCell());
+        }
+        return m_out.loadPtr(addressFor(JSStack::Callee));
+    }
+    
+    LValue getArgumentsStart(InlineCallFrame* inlineCallFrame)
+    {
+        VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame);
+        return addressFor(start).value();
+    }
+    
+    LValue getArgumentsStart()
+    {
+        return getArgumentsStart(m_node->origin.semantic.inlineCallFrame);
+    }
+    
+    template<typename Functor>
+    void checkStructure(
+        LValue structureDiscriminant, const FormattedValue& formattedValue, ExitKind exitKind,
+        const StructureSet& set, const Functor& weakStructureDiscriminant)
+    {
+        if (set.size() == 1) {
+            speculate(
+                exitKind, formattedValue, 0,
+                m_out.notEqual(structureDiscriminant, weakStructureDiscriminant(set[0])));
+            return;
+        }
+        
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("checkStructure continuation"));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
+        for (unsigned i = 0; i < set.size() - 1; ++i) {
+            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("checkStructure nextStructure"));
+            m_out.branch(
+                m_out.equal(structureDiscriminant, weakStructureDiscriminant(set[i])),
+                unsure(continuation), unsure(nextStructure));
+            m_out.appendTo(nextStructure);
+        }
+        
+        speculate(
+            exitKind, formattedValue, 0,
+            m_out.notEqual(structureDiscriminant, weakStructureDiscriminant(set.last())));
+        
+        m_out.jump(continuation);
+        m_out.appendTo(continuation, lastNext);
+    }
+    
     LValue numberOrNotCellToInt32(Edge edge, LValue value)
     {
         LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
@@ -4029,7 +5733,8 @@ private:
             m_out.jump(continuation);
         } else {
             m_out.appendTo(notIntCase, doubleCase);
-            m_out.branch(isCellOrMisc(value), unsure(notNumberCase), unsure(doubleCase));
+            m_out.branch(
+                isCellOrMisc(value, provenType(edge)), unsure(notNumberCase), unsure(doubleCase));
             
             m_out.appendTo(doubleCase, notNumberCase);
             results.append(m_out.anchor(doubleToInt32(unboxDouble(value))));
@@ -4093,97 +5798,87 @@ private:
     }
     
     LValue allocatePropertyStorage(LValue object, Structure* previousStructure)
-    {
-        if (previousStructure->couldHaveIndexingHeader()) {
-            return vmCall(
-                m_out.operation(
-                    operationReallocateButterflyToHavePropertyStorageWithInitialCapacity),
-                m_callFrame, object);
-        }
-        
-        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorage slow path"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorage continuation"));
-        
-        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
-        
-        LValue endOfStorage = allocateBasicStorageAndGetEnd(
-            m_out.constIntPtr(initialOutOfLineCapacity * sizeof(JSValue)), slowPath);
-        
-        ValueFromBlock fastButterfly = m_out.anchor(
-            m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
-        
-        m_out.jump(continuation);
-        
-        m_out.appendTo(slowPath, continuation);
-        
-        ValueFromBlock slowButterfly = m_out.anchor(vmCall(
-            m_out.operation(operationAllocatePropertyStorageWithInitialCapacity), m_callFrame));
-        
-        m_out.jump(continuation);
-        
-        m_out.appendTo(continuation, lastNext);
+    {
+        if (previousStructure->couldHaveIndexingHeader()) {
+            return vmCall(
+                m_out.operation(
+                    operationReallocateButterflyToHavePropertyStorageWithInitialCapacity),
+                m_callFrame, object);
+        }
         
-        LValue result = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
+        LValue result = allocatePropertyStorageWithSizeImpl(initialOutOfLineCapacity);
         m_out.storePtr(result, object, m_heaps.JSObject_butterfly);
-        
         return result;
     }
     
     LValue reallocatePropertyStorage(
         LValue object, LValue oldStorage, Structure* previous, Structure* next)
     {
-        size_t oldSize = previous->outOfLineCapacity() * sizeof(JSValue);
+        size_t oldSize = previous->outOfLineCapacity();
         size_t newSize = oldSize * outOfLineGrowthFactor; 
 
-        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity() * sizeof(JSValue));
+        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity());
         
         if (previous->couldHaveIndexingHeader()) {
-            LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));                    
+            LValue newAllocSize = m_out.constIntPtr(newSize);                    
             return vmCall(m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
         }
         
-        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage slow path"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage continuation"));
+        LValue result = allocatePropertyStorageWithSizeImpl(newSize);
+
+        ptrdiff_t headerSize = -sizeof(IndexingHeader) - sizeof(void*);
+        ptrdiff_t endStorage = headerSize - static_cast<ptrdiff_t>(oldSize * sizeof(JSValue));
+
+        for (ptrdiff_t offset = headerSize; offset > endStorage; offset -= sizeof(void*)) {
+            LValue loaded = 
+                m_out.loadPtr(m_out.address(m_heaps.properties.atAnyNumber(), oldStorage, offset));
+            m_out.storePtr(loaded, m_out.address(m_heaps.properties.atAnyNumber(), result, offset));
+        }
+        
+        m_out.storePtr(result, m_out.address(object, m_heaps.JSObject_butterfly));
+        
+        return result;
+    }
+    
+    LValue allocatePropertyStorageWithSizeImpl(size_t sizeInValues)
+    {
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl continuation"));
+        
         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
         
-        LValue endOfStorage = 
-            allocateBasicStorageAndGetEnd(m_out.constIntPtr(newSize), slowPath);
+        LValue endOfStorage = allocateBasicStorageAndGetEnd(
+            m_out.constIntPtr(sizeInValues * sizeof(JSValue)), slowPath);
         
-        ValueFromBlock fastButterfly = m_out.anchor(m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
+        ValueFromBlock fastButterfly = m_out.anchor(
+            m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
         
         m_out.jump(continuation);
         
         m_out.appendTo(slowPath, continuation);
         
-        LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));       
-        
-        LValue storageLocation = vmCall(m_out.operation(operationAllocatePropertyStorage), m_callFrame, newAllocSize);
-        
-        ValueFromBlock slowButterfly = m_out.anchor(storageLocation);
+        LValue slowButterflyValue;
+        if (sizeInValues == initialOutOfLineCapacity) {
+            slowButterflyValue = vmCall(
+                m_out.operation(operationAllocatePropertyStorageWithInitialCapacity),
+                m_callFrame);
+        } else {
+            slowButterflyValue = vmCall(
+                m_out.operation(operationAllocatePropertyStorage),
+                m_callFrame, m_out.constIntPtr(sizeInValues));
+        }
+        ValueFromBlock slowButterfly = m_out.anchor(slowButterflyValue);
         
         m_out.jump(continuation);
         
         m_out.appendTo(continuation, lastNext);
         
-        LValue result = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
-
-        ptrdiff_t headerSize = -sizeof(JSValue) - sizeof(void *);
-        ptrdiff_t endStorage = headerSize - static_cast<ptrdiff_t>(oldSize);
-
-        for (ptrdiff_t offset = headerSize; offset > endStorage; offset -= sizeof(void*)) {
-            LValue loaded = 
-                m_out.loadPtr(m_out.address(m_heaps.properties.atAnyNumber(), oldStorage, offset));
-            m_out.storePtr(loaded, m_out.address(m_heaps.properties.atAnyNumber(), result, offset));
-        }
-        
-        m_out.storePtr(result, m_out.address(object, m_heaps.JSObject_butterfly));
-        
-        return result;
+        return m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
     }
     
     LValue getById(LValue base)
     {
-        StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
+        auto uid = m_graph.identifiers()[m_node->identifierNumber()];
 
         // Arguments: id, bytes, target, numArgs, args...
         unsigned stackmapID = m_stackmapIDs++;
@@ -4202,11 +5897,10 @@ private:
         return call;
     }
     
-    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
+    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge, ptrdiff_t offset = 0)
     {
         return m_out.baseIndex(
-            heap, storage, m_out.zeroExt(index, m_out.intPtr),
-            m_state.forNode(edge).m_value);
+            heap, storage, m_out.zeroExtPtr(index), provenValue(edge), offset);
     }
     
     void compare(
@@ -4240,7 +5934,7 @@ private:
             return;
         }
         
-        LOWERING_FAILED(m_node, "Bad use kinds");
+        DFG_CRASH(m_graph, m_node, "Bad use kinds");
     }
     
     void compareEqObjectOrOtherToObject(Edge leftChild, Edge rightChild)
@@ -4254,7 +5948,9 @@ private:
         LBasicBlock leftNotCellCase = FTL_NEW_BLOCK(m_out, ("CompareEqObjectOrOtherToObject left not cell case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CompareEqObjectOrOtherToObject continuation"));
         
-        m_out.branch(isCell(leftValue), unsure(leftCellCase), unsure(leftNotCellCase));
+        m_out.branch(
+            isCell(leftValue, provenType(leftChild)),
+            unsure(leftCellCase), unsure(leftNotCellCase));
         
         LBasicBlock lastNext = m_out.appendTo(leftCellCase, leftNotCellCase);
         speculateTruthyObject(leftChild, leftValue, SpecObject | (~SpecCell));
@@ -4278,10 +5974,7 @@ private:
             return;
         }
         
-        LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
-        FTL_TYPE_CHECK(
-            jsValueValue(cell), edge, filter,
-            m_out.equal(structureID, m_out.constInt32(vm().stringStructure->id())));
+        FTL_TYPE_CHECK(jsValueValue(cell), edge, filter, isNotObject(cell));
         speculate(
             BadType, jsValueValue(cell), edge.node(),
             m_out.testNonZero8(
@@ -4318,7 +6011,7 @@ private:
         setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
     }
 
-    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
+    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
     {
         LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
         
@@ -4333,12 +6026,21 @@ private:
             m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
             allocator, m_heaps.MarkedAllocator_freeListHead);
         
-        m_out.store32(m_out.constInt32(structure->id()), result, m_heaps.JSCell_structureID);
-        m_out.store8(m_out.constInt8(structure->indexingType()), result, m_heaps.JSCell_indexingType);
-        m_out.store8(m_out.constInt8(structure->typeInfo().type()), result, m_heaps.JSCell_typeInfoType);
-        m_out.store8(m_out.constInt8(structure->typeInfo().inlineTypeFlags()), result, m_heaps.JSCell_typeInfoFlags);
-        m_out.store8(m_out.constInt8(JSCell::NotMarked), result, m_heaps.JSCell_gcData);
-        
+        return result;
+    }
+    
+    void storeStructure(LValue object, Structure* structure)
+    {
+        m_out.store32(m_out.constInt32(structure->id()), object, m_heaps.JSCell_structureID);
+        m_out.store32(
+            m_out.constInt32(structure->objectInitializationBlob()),
+            object, m_heaps.JSCell_usefulBytes);
+    }
+
+    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
+    {
+        LValue result = allocateCell(allocator, slowPath);
+        storeStructure(result, structure);
         return result;
     }
 
@@ -4351,19 +6053,63 @@ private:
     }
     
     template<typename ClassType>
-    LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    LValue allocateObject(
+        size_t size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
     {
-        MarkedAllocator* allocator;
-        size_t size = ClassType::allocationSize(0);
-        if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
-            allocator = &vm().heap.allocatorForObjectWithImmortalStructureDestructor(size);
-        else if (ClassType::needsDestruction)
-            allocator = &vm().heap.allocatorForObjectWithNormalDestructor(size);
-        else
-            allocator = &vm().heap.allocatorForObjectWithoutDestructor(size);
+        MarkedAllocator* allocator = &vm().heap.allocatorForObjectOfType<ClassType>(size);
         return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath);
     }
     
+    template<typename ClassType>
+    LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    {
+        return allocateObject<ClassType>(
+            ClassType::allocationSize(0), structure, butterfly, slowPath);
+    }
+    
+    template<typename ClassType>
+    LValue allocateVariableSizedObject(
+        LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    {
+        static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
+        static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
+
+        LValue subspace = m_out.constIntPtr(&vm().heap.subspaceForObjectOfType<ClassType>());
+        
+        LBasicBlock smallCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject small case"));
+        LBasicBlock largeOrOversizeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large or oversize case"));
+        LBasicBlock largeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject continuation"));
+        
+        LValue uproundedSize = m_out.add(size, m_out.constInt32(MarkedSpace::preciseStep - 1));
+        LValue isSmall = m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::preciseCutoff));
+        m_out.branch(isSmall, unsure(smallCaseBlock), unsure(largeOrOversizeCaseBlock));
+        
+        LBasicBlock lastNext = m_out.appendTo(smallCaseBlock, largeOrOversizeCaseBlock);
+        TypedPointer address = m_out.baseIndex(
+            m_heaps.MarkedSpace_Subspace_preciseAllocators, subspace,
+            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::preciseStep)))));
+        ValueFromBlock smallAllocator = m_out.anchor(address.value());
+        m_out.jump(continuation);
+        
+        m_out.appendTo(largeOrOversizeCaseBlock, largeCaseBlock);
+        m_out.branch(
+            m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::impreciseCutoff)),
+            usually(largeCaseBlock), rarely(slowPath));
+        
+        m_out.appendTo(largeCaseBlock, continuation);
+        address = m_out.baseIndex(
+            m_heaps.MarkedSpace_Subspace_impreciseAllocators, subspace,
+            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::impreciseStep)))));
+        ValueFromBlock largeAllocator = m_out.anchor(address.value());
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue allocator = m_out.phi(m_out.intPtr, smallAllocator, largeAllocator);
+        
+        return allocateObject(allocator, structure, butterfly, slowPath);
+    }
+    
     // Returns a pointer to the end of the allocation.
     LValue allocateBasicStorageAndGetEnd(LValue size, LBasicBlock slowPath)
     {
@@ -4385,6 +6131,31 @@ private:
             m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
     }
     
+    LValue allocateObject(Structure* structure)
+    {
+        size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
+        MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
+        
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocateObject slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateObject continuation"));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+        
+        ValueFromBlock fastResult = m_out.anchor(allocateObject(
+            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
+        
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        
+        ValueFromBlock slowResult = m_out.anchor(vmCall(
+            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        return m_out.phi(m_out.intPtr, fastResult, slowResult);
+    }
+    
     struct ArrayValues {
         ArrayValues()
             : array(0)
@@ -4468,7 +6239,8 @@ private:
     
     LValue typedArrayLength(Edge baseEdge, ArrayMode arrayMode, LValue base)
     {
-        if (JSArrayBufferView* view = m_graph.tryGetFoldableView(baseEdge.node(), arrayMode))
+        JSArrayBufferView* view = m_graph.tryGetFoldableView(provenValue(baseEdge), arrayMode);
+        if (view)
             return m_out.constInt32(view->length());
         return m_out.load32NonNegative(base, m_heaps.JSArrayBufferView_length);
     }
@@ -4482,9 +6254,9 @@ private:
     {
         switch (edge.useKind()) {
         case BooleanUse:
-            return lowBoolean(m_node->child1());
+            return lowBoolean(edge);
         case Int32Use:
-            return m_out.notZero32(lowInt32(m_node->child1()));
+            return m_out.notZero32(lowInt32(edge));
         case DoubleRepUse:
             return m_out.doubleNotEqual(lowDouble(edge), m_out.doubleZero);
         case ObjectOrOtherUse:
@@ -4493,33 +6265,111 @@ private:
                     edge, CellCaseSpeculatesObject, SpeculateNullOrUndefined,
                     ManualOperandSpeculation));
         case StringUse: {
-            LValue stringValue = lowString(m_node->child1());
+            LValue stringValue = lowString(edge);
             LValue length = m_out.load32NonNegative(stringValue, m_heaps.JSString_length);
             return m_out.notEqual(length, m_out.int32Zero);
         }
         case UntypedUse: {
-            LValue value = lowJSValue(m_node->child1());
-            
-            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped slow case"));
-            LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped fast case"));
+            LValue value = lowJSValue(edge);
+            
+            // Implements the following control flow structure:
+            // if (value is cell) {
+            //     if (value is string)
+            //         result = !!value->length
+            //     else {
+            //         do evil things for masquerades-as-undefined
+            //         result = true
+            //     }
+            // } else if (value is int32) {
+            //     result = !!unboxInt32(value)
+            // } else if (value is number) {
+            //     result = !!unboxDouble(value)
+            // } else {
+            //     result = value == jsTrue
+            // }
+            
+            LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped cell case"));
+            LBasicBlock stringCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped string case"));
+            LBasicBlock notStringCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped not string case"));
+            LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped not cell case"));
+            LBasicBlock int32Case = FTL_NEW_BLOCK(m_out, ("Boolify untyped int32 case"));
+            LBasicBlock notInt32Case = FTL_NEW_BLOCK(m_out, ("Boolify untyped not int32 case"));
+            LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped double case"));
+            LBasicBlock notDoubleCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped not double case"));
             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Boolify untyped continuation"));
             
-            m_out.branch(isNotBoolean(value), rarely(slowCase), usually(fastCase));
+            Vector<ValueFromBlock> results;
             
-            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
-            ValueFromBlock fastResult = m_out.anchor(unboxBoolean(value));
+            m_out.branch(isCell(value, provenType(edge)), unsure(cellCase), unsure(notCellCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(cellCase, stringCase);
+            m_out.branch(
+                isString(value, provenType(edge) & SpecCell),
+                unsure(stringCase), unsure(notStringCase));
+            
+            m_out.appendTo(stringCase, notStringCase);
+            LValue nonEmptyString = m_out.notZero32(
+                m_out.load32NonNegative(value, m_heaps.JSString_length));
+            results.append(m_out.anchor(nonEmptyString));
             m_out.jump(continuation);
             
-            m_out.appendTo(slowCase, continuation);
-            ValueFromBlock slowResult = m_out.anchor(m_out.notNull(vmCall(
-                m_out.operation(operationConvertJSValueToBoolean), m_callFrame, value)));
+            m_out.appendTo(notStringCase, notCellCase);
+            LValue isTruthyObject;
+            if (masqueradesAsUndefinedWatchpointIsStillValid())
+                isTruthyObject = m_out.booleanTrue;
+            else {
+                LBasicBlock masqueradesCase = FTL_NEW_BLOCK(m_out, ("Boolify untyped masquerades case"));
+                
+                results.append(m_out.anchor(m_out.booleanTrue));
+                
+                m_out.branch(
+                    m_out.testIsZero8(
+                        m_out.load8(value, m_heaps.JSCell_typeInfoFlags),
+                        m_out.constInt8(MasqueradesAsUndefined)),
+                    usually(continuation), rarely(masqueradesCase));
+                
+                m_out.appendTo(masqueradesCase);
+                
+                isTruthyObject = m_out.notEqual(
+                    m_out.constIntPtr(m_graph.globalObjectFor(m_node->origin.semantic)),
+                    m_out.loadPtr(loadStructure(value), m_heaps.Structure_globalObject));
+            }
+            results.append(m_out.anchor(isTruthyObject));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(notCellCase, int32Case);
+            m_out.branch(
+                isInt32(value, provenType(edge) & ~SpecCell),
+                unsure(int32Case), unsure(notInt32Case));
+            
+            m_out.appendTo(int32Case, notInt32Case);
+            results.append(m_out.anchor(m_out.notZero32(unboxInt32(value))));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(notInt32Case, doubleCase);
+            m_out.branch(
+                isNumber(value, provenType(edge) & ~SpecCell),
+                unsure(doubleCase), unsure(notDoubleCase));
+            
+            m_out.appendTo(doubleCase, notDoubleCase);
+            // Note that doubleNotEqual() really means not-equal-and-ordered. It will return false
+            // if value is NaN.
+            LValue doubleIsTruthy = m_out.doubleNotEqual(
+                unboxDouble(value), m_out.constDouble(0));
+            results.append(m_out.anchor(doubleIsTruthy));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(notDoubleCase, continuation);
+            LValue miscIsTruthy = m_out.equal(
+                value, m_out.constInt64(JSValue::encode(jsBoolean(true))));
+            results.append(m_out.anchor(miscIsTruthy));
             m_out.jump(continuation);
             
             m_out.appendTo(continuation, lastNext);
-            return m_out.phi(m_out.boolean, fastResult, slowResult);
+            return m_out.phi(m_out.boolean, results);
         }
         default:
-            LOWERING_FAILED(m_node, "Bad use kind");
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
             return 0;
         }
     }
@@ -4546,7 +6396,7 @@ private:
         LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined primitive case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined continuation"));
         
-        m_out.branch(isNotCell(value), unsure(primitiveCase), unsure(cellCase));
+        m_out.branch(isNotCell(value, provenType(edge)), unsure(primitiveCase), unsure(cellCase));
         
         LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
         
@@ -4557,10 +6407,7 @@ private:
             break;
         case CellCaseSpeculatesObject:
             FTL_TYPE_CHECK(
-                jsValueValue(value), edge, (~SpecCell) | SpecObject,
-                m_out.equal(
-                    m_out.load32(value, m_heaps.JSCell_structureID),
-                    m_out.constInt32(vm().stringStructure->id())));
+                jsValueValue(value), edge, (~SpecCell) | SpecObject, isNotObject(value));
             break;
         }
         
@@ -4601,7 +6448,7 @@ private:
             primitiveResult = m_out.equal(value, m_out.constInt64(ValueUndefined));
             break;
         case EqualNullOrUndefined:
-            primitiveResult = isOther(value);
+            primitiveResult = isOther(value, provenType(edge));
             break;
         case SpeculateNullOrUndefined:
             FTL_TYPE_CHECK(
@@ -4672,7 +6519,7 @@ private:
         Vector<SwitchCase> cases;
         for (unsigned i = 0; i < data->cases.size(); ++i) {
             cases.append(SwitchCase(
-                constInt(type, data->cases[i].value.switchLookupValue()),
+                constInt(type, data->cases[i].value.switchLookupValue(data->kind)),
                 lowBlock(data->cases[i].target.block), Weight(data->cases[i].target.count)));
         }
         
@@ -4681,6 +6528,434 @@ private:
             lowBlock(data->fallThrough.block), Weight(data->fallThrough.count));
     }
     
+    void switchString(SwitchData* data, LValue string)
+    {
+        bool canDoBinarySwitch = true;
+        unsigned totalLength = 0;
+        
+        for (DFG::SwitchCase myCase : data->cases) {
+            StringImpl* string = myCase.value.stringImpl();
+            if (!string->is8Bit()) {
+                canDoBinarySwitch = false;
+                break;
+            }
+            if (string->length() > Options::maximumBinaryStringSwitchCaseLength()) {
+                canDoBinarySwitch = false;
+                break;
+            }
+            totalLength += string->length();
+        }
+        
+        if (!canDoBinarySwitch || totalLength > Options::maximumBinaryStringSwitchTotalLength()) {
+            switchStringSlow(data, string);
+            return;
+        }
+        
+        LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
+        LValue length = m_out.load32(string, m_heaps.JSString_length);
+        
+        LBasicBlock hasImplBlock = FTL_NEW_BLOCK(m_out, ("Switch/SwitchString has impl case"));
+        LBasicBlock is8BitBlock = FTL_NEW_BLOCK(m_out, ("Switch/SwitchString is 8 bit case"));
+        LBasicBlock slowBlock = FTL_NEW_BLOCK(m_out, ("Switch/SwitchString slow case"));
+        
+        m_out.branch(m_out.isNull(stringImpl), unsure(slowBlock), unsure(hasImplBlock));
+        
+        LBasicBlock lastNext = m_out.appendTo(hasImplBlock, is8BitBlock);
+        
+        m_out.branch(
+            m_out.testIsZero32(
+                m_out.load32(stringImpl, m_heaps.StringImpl_hashAndFlags),
+                m_out.constInt32(StringImpl::flagIs8Bit())),
+            unsure(slowBlock), unsure(is8BitBlock));
+        
+        m_out.appendTo(is8BitBlock, slowBlock);
+        
+        LValue buffer = m_out.loadPtr(stringImpl, m_heaps.StringImpl_data);
+        
+        // FIXME: We should propagate branch weight data to the cases of this switch.
+        // https://bugs.webkit.org/show_bug.cgi?id=144368
+        
+        Vector<StringSwitchCase> cases;
+        for (DFG::SwitchCase myCase : data->cases)
+            cases.append(StringSwitchCase(myCase.value.stringImpl(), lowBlock(myCase.target.block)));
+        std::sort(cases.begin(), cases.end());
+        switchStringRecurse(data, buffer, length, cases, 0, 0, cases.size(), 0, false);
+
+        m_out.appendTo(slowBlock, lastNext);
+        switchStringSlow(data, string);
+    }
+    
+    // The code for string switching is based closely on the same code in the DFG backend. While it
+    // would be nice to reduce the amount of similar-looking code, it seems like this is one of
+    // those algorithms where factoring out the common bits would result in more code than just
+    // duplicating.
+    
+    struct StringSwitchCase {
+        StringSwitchCase() { }
+        
+        StringSwitchCase(StringImpl* string, LBasicBlock target)
+            : string(string)
+            , target(target)
+        {
+        }
+
+        bool operator<(const StringSwitchCase& other) const
+        {
+            return stringLessThan(*string, *other.string);
+        }
+        
+        StringImpl* string;
+        LBasicBlock target;
+    };
+    
+    struct CharacterCase {
+        CharacterCase()
+            : character(0)
+            , begin(0)
+            , end(0)
+        {
+        }
+        
+        CharacterCase(LChar character, unsigned begin, unsigned end)
+            : character(character)
+            , begin(begin)
+            , end(end)
+        {
+        }
+        
+        bool operator<(const CharacterCase& other) const
+        {
+            return character < other.character;
+        }
+        
+        LChar character;
+        unsigned begin;
+        unsigned end;
+    };
+    
+    void switchStringRecurse(
+        SwitchData* data, LValue buffer, LValue length, const Vector<StringSwitchCase>& cases,
+        unsigned numChecked, unsigned begin, unsigned end, unsigned alreadyCheckedLength,
+        unsigned checkedExactLength)
+    {
+        LBasicBlock fallThrough = lowBlock(data->fallThrough.block);
+        
+        if (begin == end) {
+            m_out.jump(fallThrough);
+            return;
+        }
+        
+        unsigned minLength = cases[begin].string->length();
+        unsigned commonChars = minLength;
+        bool allLengthsEqual = true;
+        for (unsigned i = begin + 1; i < end; ++i) {
+            unsigned myCommonChars = numChecked;
+            unsigned limit = std::min(cases[begin].string->length(), cases[i].string->length());
+            for (unsigned j = numChecked; j < limit; ++j) {
+                if (cases[begin].string->at(j) != cases[i].string->at(j))
+                    break;
+                myCommonChars++;
+            }
+            commonChars = std::min(commonChars, myCommonChars);
+            if (minLength != cases[i].string->length())
+                allLengthsEqual = false;
+            minLength = std::min(minLength, cases[i].string->length());
+        }
+        
+        if (checkedExactLength) {
+            DFG_ASSERT(m_graph, m_node, alreadyCheckedLength == minLength);
+            DFG_ASSERT(m_graph, m_node, allLengthsEqual);
+        }
+        
+        DFG_ASSERT(m_graph, m_node, minLength >= commonChars);
+        
+        if (!allLengthsEqual && alreadyCheckedLength < minLength)
+            m_out.check(m_out.below(length, m_out.constInt32(minLength)), unsure(fallThrough));
+        if (allLengthsEqual && (alreadyCheckedLength < minLength || !checkedExactLength))
+            m_out.check(m_out.notEqual(length, m_out.constInt32(minLength)), unsure(fallThrough));
+        
+        for (unsigned i = numChecked; i < commonChars; ++i) {
+            m_out.check(
+                m_out.notEqual(
+                    m_out.load8(buffer, m_heaps.characters8[i]),
+                    m_out.constInt8(cases[begin].string->at(i))),
+                unsure(fallThrough));
+        }
+        
+        if (minLength == commonChars) {
+            // This is the case where one of the cases is a prefix of all of the other cases.
+            // We've already checked that the input string is a prefix of all of the cases,
+            // so we just check length to jump to that case.
+            
+            DFG_ASSERT(m_graph, m_node, cases[begin].string->length() == commonChars);
+            for (unsigned i = begin + 1; i < end; ++i)
+                DFG_ASSERT(m_graph, m_node, cases[i].string->length() > commonChars);
+            
+            if (allLengthsEqual) {
+                DFG_ASSERT(m_graph, m_node, end == begin + 1);
+                m_out.jump(cases[begin].target);
+                return;
+            }
+            
+            m_out.check(
+                m_out.equal(length, m_out.constInt32(commonChars)),
+                unsure(cases[begin].target));
+            
+            // We've checked if the length is >= minLength, and then we checked if the length is
+            // == commonChars. We get to this point if it is >= minLength but not == commonChars.
+            // Hence we know that it now must be > minLength, i.e. that it's >= minLength + 1.
+            switchStringRecurse(
+                data, buffer, length, cases, commonChars, begin + 1, end, minLength + 1, false);
+            return;
+        }
+        
+        // At this point we know that the string is longer than commonChars, and we've only verified
+        // commonChars. Use a binary switch on the next unchecked character, i.e.
+        // string[commonChars].
+        
+        DFG_ASSERT(m_graph, m_node, end >= begin + 2);
+        
+        LValue uncheckedChar = m_out.load8(buffer, m_heaps.characters8[commonChars]);
+        
+        Vector<CharacterCase> characterCases;
+        CharacterCase currentCase(cases[begin].string->at(commonChars), begin, begin + 1);
+        for (unsigned i = begin + 1; i < end; ++i) {
+            LChar currentChar = cases[i].string->at(commonChars);
+            if (currentChar != currentCase.character) {
+                currentCase.end = i;
+                characterCases.append(currentCase);
+                currentCase = CharacterCase(currentChar, i, i + 1);
+            } else
+                currentCase.end = i + 1;
+        }
+        characterCases.append(currentCase);
+        
+        Vector<LBasicBlock> characterBlocks;
+        for (CharacterCase& myCase : characterCases)
+            characterBlocks.append(FTL_NEW_BLOCK(m_out, ("Switch/SwitchString case for ", myCase.character, " at index ", commonChars)));
+        
+        Vector<SwitchCase> switchCases;
+        for (unsigned i = 0; i < characterCases.size(); ++i) {
+            if (i)
+                DFG_ASSERT(m_graph, m_node, characterCases[i - 1].character < characterCases[i].character);
+            switchCases.append(SwitchCase(
+                m_out.constInt8(characterCases[i].character), characterBlocks[i], Weight()));
+        }
+        m_out.switchInstruction(uncheckedChar, switchCases, fallThrough, Weight());
+        
+        LBasicBlock lastNext = m_out.m_nextBlock;
+        characterBlocks.append(lastNext); // Makes it convenient to set nextBlock.
+        for (unsigned i = 0; i < characterCases.size(); ++i) {
+            m_out.appendTo(characterBlocks[i], characterBlocks[i + 1]);
+            switchStringRecurse(
+                data, buffer, length, cases, commonChars + 1,
+                characterCases[i].begin, characterCases[i].end, minLength, allLengthsEqual);
+        }
+        
+        DFG_ASSERT(m_graph, m_node, m_out.m_nextBlock == lastNext);
+    }
+    
+    void switchStringSlow(SwitchData* data, LValue string)
+    {
+        // FIXME: We ought to be able to use computed gotos here. We would save the labels of the
+        // blocks we want to jump to, and then request their addresses after compilation completes.
+        // https://bugs.webkit.org/show_bug.cgi?id=144369
+        
+        LValue branchOffset = vmCall(
+            m_out.operation(operationSwitchStringAndGetBranchOffset),
+            m_callFrame, m_out.constIntPtr(data->switchTableIndex), string);
+        
+        StringJumpTable& table = codeBlock()->stringSwitchJumpTable(data->switchTableIndex);
+        
+        Vector<SwitchCase> cases;
+        std::unordered_set<int32_t> alreadyHandled; // These may be negative, or zero, or probably other stuff, too. We don't want to mess with HashSet's corner cases and we don't really care about throughput here.
+        for (unsigned i = 0; i < data->cases.size(); ++i) {
+            // FIXME: The fact that we're using the bytecode's switch table means that the
+            // following DFG IR transformation would be invalid.
+            //
+            // Original code:
+            //     switch (v) {
+            //     case "foo":
+            //     case "bar":
+            //         things();
+            //         break;
+            //     default:
+            //         break;
+            //     }
+            //
+            // New code:
+            //     switch (v) {
+            //     case "foo":
+            //         instrumentFoo();
+            //         goto _things;
+            //     case "bar":
+            //         instrumentBar();
+            //     _things:
+            //         things();
+            //         break;
+            //     default:
+            //         break;
+            //     }
+            //
+            // Luckily, we don't currently do any such transformation. But it's kind of silly that
+            // this is an issue.
+            // https://bugs.webkit.org/show_bug.cgi?id=144635
+            
+            DFG::SwitchCase myCase = data->cases[i];
+            StringJumpTable::StringOffsetTable::iterator iter =
+                table.offsetTable.find(myCase.value.stringImpl());
+            DFG_ASSERT(m_graph, m_node, iter != table.offsetTable.end());
+            
+            if (!alreadyHandled.insert(iter->value.branchOffset).second)
+                continue;
+
+            cases.append(SwitchCase(
+                m_out.constInt32(iter->value.branchOffset),
+                lowBlock(myCase.target.block), Weight(myCase.target.count)));
+        }
+        
+        m_out.switchInstruction(
+            branchOffset, cases, lowBlock(data->fallThrough.block),
+            Weight(data->fallThrough.count));
+    }
+    
+    // Calls the functor at the point of code generation where we know what the result type is.
+    // You can emit whatever code you like at that point. Expects you to terminate the basic block.
+    // When buildTypeOf() returns, it will have terminated all basic blocks that it created. So, if
+    // you aren't using this as the terminator of a high-level block, you should create your own
+    // contination and set it as the nextBlock (m_out.insertNewBlocksBefore(continuation)) before
+    // calling this. For example:
+    //
+    // LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("My continuation"));
+    // LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
+    // buildTypeOf(
+    //     child, value,
+    //     [&] (TypeofType type) {
+    //          do things;
+    //          m_out.jump(continuation);
+    //     });
+    // m_out.appendTo(continuation, lastNext);
+    template<typename Functor>
+    void buildTypeOf(Edge child, LValue value, const Functor& functor)
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+        
+        // Implements the following branching structure:
+        //
+        // if (is cell) {
+        //     if (is object) {
+        //         if (is function) {
+        //             return function;
+        //         } else if (doesn't have call trap and doesn't masquerade as undefined) {
+        //             return object
+        //         } else {
+        //             return slowPath();
+        //         }
+        //     } else if (is string) {
+        //         return string
+        //     } else {
+        //         return symbol
+        //     }
+        // } else if (is number) {
+        //     return number
+        // } else if (is null) {
+        //     return object
+        // } else if (is boolean) {
+        //     return boolean
+        // } else {
+        //     return undefined
+        // }
+        
+        LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf cell case"));
+        LBasicBlock objectCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf object case"));
+        LBasicBlock functionCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf function case"));
+        LBasicBlock notFunctionCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf not function case"));
+        LBasicBlock reallyObjectCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf really object case"));
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("buildTypeOf slow path"));
+        LBasicBlock unreachable = FTL_NEW_BLOCK(m_out, ("buildTypeOf unreachable"));
+        LBasicBlock notObjectCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf not object case"));
+        LBasicBlock stringCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf string case"));
+        LBasicBlock symbolCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf symbol case"));
+        LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf not cell case"));
+        LBasicBlock numberCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf number case"));
+        LBasicBlock notNumberCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf not number case"));
+        LBasicBlock notNullCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf not null case"));
+        LBasicBlock booleanCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf boolean case"));
+        LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("buildTypeOf undefined case"));
+        
+        m_out.branch(isCell(value, provenType(child)), unsure(cellCase), unsure(notCellCase));
+        
+        LBasicBlock lastNext = m_out.appendTo(cellCase, objectCase);
+        m_out.branch(isObject(value, provenType(child)), unsure(objectCase), unsure(notObjectCase));
+        
+        m_out.appendTo(objectCase, functionCase);
+        m_out.branch(
+            isFunction(value, provenType(child) & SpecObject),
+            unsure(functionCase), unsure(notFunctionCase));
+        
+        m_out.appendTo(functionCase, notFunctionCase);
+        functor(TypeofType::Function);
+        
+        m_out.appendTo(notFunctionCase, reallyObjectCase);
+        m_out.branch(
+            isExoticForTypeof(value, provenType(child) & (SpecObject - SpecFunction)),
+            rarely(slowPath), usually(reallyObjectCase));
+        
+        m_out.appendTo(reallyObjectCase, slowPath);
+        functor(TypeofType::Object);
+        
+        m_out.appendTo(slowPath, unreachable);
+        LValue result = vmCall(
+            m_out.operation(operationTypeOfObjectAsTypeofType), m_callFrame,
+            weakPointer(globalObject), value);
+        Vector<SwitchCase, 3> cases;
+        cases.append(SwitchCase(m_out.constInt32(static_cast<int32_t>(TypeofType::Undefined)), undefinedCase));
+        cases.append(SwitchCase(m_out.constInt32(static_cast<int32_t>(TypeofType::Object)), reallyObjectCase));
+        cases.append(SwitchCase(m_out.constInt32(static_cast<int32_t>(TypeofType::Function)), functionCase));
+        m_out.switchInstruction(result, cases, unreachable, Weight());
+        
+        m_out.appendTo(unreachable, notObjectCase);
+        m_out.unreachable();
+        
+        m_out.appendTo(notObjectCase, stringCase);
+        m_out.branch(
+            isString(value, provenType(child) & (SpecCell - SpecObject)),
+            unsure(stringCase), unsure(symbolCase));
+        
+        m_out.appendTo(stringCase, symbolCase);
+        functor(TypeofType::String);
+        
+        m_out.appendTo(symbolCase, notCellCase);
+        functor(TypeofType::Symbol);
+        
+        m_out.appendTo(notCellCase, numberCase);
+        m_out.branch(
+            isNumber(value, provenType(child) & ~SpecCell),
+            unsure(numberCase), unsure(notNumberCase));
+        
+        m_out.appendTo(numberCase, notNumberCase);
+        functor(TypeofType::Number);
+        
+        m_out.appendTo(notNumberCase, notNullCase);
+        LValue isNull;
+        if (provenType(child) & SpecOther)
+            isNull = m_out.equal(value, m_out.constInt64(ValueNull));
+        else
+            isNull = m_out.booleanFalse;
+        m_out.branch(isNull, unsure(reallyObjectCase), unsure(notNullCase));
+        
+        m_out.appendTo(notNullCase, booleanCase);
+        m_out.branch(
+            isBoolean(value, provenType(child) & ~(SpecCell | SpecFullNumber)),
+            unsure(booleanCase), unsure(undefinedCase));
+        
+        m_out.appendTo(booleanCase, undefinedCase);
+        functor(TypeofType::Boolean);
+        
+        m_out.appendTo(undefinedCase, lastNext);
+        functor(TypeofType::Undefined);
+    }
+    
     LValue doubleToInt32(LValue doubleValue, double low, double high, bool isSigned = true)
     {
         LBasicBlock greatEnough = FTL_NEW_BLOCK(m_out, ("doubleToInt32 greatEnough"));
@@ -4745,19 +7020,6 @@ private:
         return m_out.phi(m_out.int32, fastResult, slowResult);
     }
     
-    void checkArgumentsNotCreated()
-    {
-        CodeOrigin codeOrigin = m_node->origin.semantic;
-        VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(codeOrigin);
-        if (isEmptySpeculation(m_state.variables().operand(argumentsRegister).m_type))
-            return;
-        
-        VirtualRegister argsReg = m_graph.machineArgumentsRegisterFor(codeOrigin);
-        speculate(
-            ArgumentsEscaped, noValue(), 0,
-            m_out.notZero64(m_out.load64(addressFor(argsReg))));
-    }
-    
     void speculate(
         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
     {
@@ -4766,7 +7028,13 @@ private:
     
     void terminate(ExitKind kind)
     {
-        speculate(kind, noValue(), 0, m_out.booleanTrue);
+        speculate(kind, noValue(), nullptr, m_out.booleanTrue);
+        didAlreadyTerminate();
+    }
+    
+    void didAlreadyTerminate()
+    {
+        m_state.setIsValid(false);
     }
     
     void typeCheck(
@@ -4792,7 +7060,7 @@ private:
         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
         
         if (edge->hasConstant()) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isInt32()) {
                 terminate(Uncountable);
                 return m_out.int32Zero;
@@ -4822,7 +7090,7 @@ private:
             return result;
         }
 
-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt32));
+        DFG_ASSERT(m_graph, m_node, !(provenType(edge) & SpecInt32));
         terminate(Uncountable);
         return m_out.int32Zero;
     }
@@ -4830,7 +7098,7 @@ private:
     enum Int52Kind { StrictInt52, Int52 };
     LValue lowInt52(Edge edge, Int52Kind kind)
     {
-        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
+        DFG_ASSERT(m_graph, m_node, edge.useKind() == Int52RepUse);
         
         LoweredNodeValue value;
         
@@ -4856,7 +7124,7 @@ private:
             break;
         }
 
-        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
+        DFG_ASSERT(m_graph, m_node, !provenType(edge));
         terminate(Uncountable);
         return m_out.int64Zero;
     }
@@ -4892,7 +7160,7 @@ private:
         case StrictInt52:
             return Int52;
         }
-        LOWERING_FAILED(m_node, "Bad use kind");
+        DFG_CRASH(m_graph, m_node, "Bad use kind");
         return Int52;
     }
     
@@ -4904,10 +7172,10 @@ private:
     
     LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     {
-        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
+        DFG_ASSERT(m_graph, m_node, mode == ManualOperandSpeculation || DFG::isCell(edge.useKind()));
         
         if (edge->op() == JSConstant) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isCell()) {
                 terminate(Uncountable);
                 return m_out.intPtrZero;
@@ -4923,7 +7191,7 @@ private:
             return uncheckedValue;
         }
         
-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecCell));
+        DFG_ASSERT(m_graph, m_node, !(provenType(edge) & SpecCell));
         terminate(Uncountable);
         return m_out.intPtrZero;
     }
@@ -4970,7 +7238,7 @@ private:
         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
         
         if (edge->hasConstant()) {
-            JSValue value = m_graph.valueOfJSConstant(edge.node());
+            JSValue value = edge->asJSValue();
             if (!value.isBoolean()) {
                 terminate(Uncountable);
                 return m_out.booleanFalse;
@@ -4992,33 +7260,32 @@ private:
             return result;
         }
         
-        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecBoolean));
+        DFG_ASSERT(m_graph, m_node, !(provenType(edge) & SpecBoolean));
         terminate(Uncountable);
         return m_out.booleanFalse;
     }
     
     LValue lowDouble(Edge edge)
     {
-        RELEASE_ASSERT(isDouble(edge.useKind()));
+        DFG_ASSERT(m_graph, m_node, isDouble(edge.useKind()));
         
         LoweredNodeValue value = m_doubleValues.get(edge.node());
         if (isValid(value))
             return value.value();
-        
-        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
+        DFG_ASSERT(m_graph, m_node, !provenType(edge));
         terminate(Uncountable);
         return m_out.doubleZero;
     }
     
     LValue lowJSValue(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     {
-        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
-        RELEASE_ASSERT(!isDouble(edge.useKind()));
-        RELEASE_ASSERT(edge.useKind() != Int52RepUse);
+        DFG_ASSERT(m_graph, m_node, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
+        DFG_ASSERT(m_graph, m_node, !isDouble(edge.useKind()));
+        DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse);
         
         if (edge->hasConstant())
-            return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
-        
+            return m_out.constInt64(JSValue::encode(edge->asJSValue()));
+
         LoweredNodeValue value = m_jsValueValues.get(edge.node());
         if (isValid(value))
             return value.value();
@@ -5037,7 +7304,7 @@ private:
             return result;
         }
         
-        LOWERING_FAILED(m_node, "Corrupt array class");
+        DFG_CRASH(m_graph, m_node, "Value not defined");
         return 0;
     }
     
@@ -5104,8 +7371,16 @@ private:
         return m_out.aShr(value, m_out.constInt64(JSValue::int52ShiftAmount));
     }
     
-    LValue isNotInt32(LValue jsValue)
+    LValue isInt32(LValue jsValue, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type, SpecInt32))
+            return proven;
+        return m_out.aboveOrEqual(jsValue, m_tagTypeNumber);
+    }
+    LValue isNotInt32(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecInt32))
+            return proven;
         return m_out.below(jsValue, m_tagTypeNumber);
     }
     LValue unboxInt32(LValue jsValue)
@@ -5117,12 +7392,16 @@ private:
         return m_out.add(m_out.zeroExt(value, m_out.int64), m_tagTypeNumber);
     }
     
-    LValue isCellOrMisc(LValue jsValue)
+    LValue isCellOrMisc(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecCell | SpecMisc))
+            return proven;
         return m_out.testIsZero64(jsValue, m_tagTypeNumber);
     }
-    LValue isNotCellOrMisc(LValue jsValue)
+    LValue isNotCellOrMisc(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~(SpecCell | SpecMisc)))
+            return proven;
         return m_out.testNonZero64(jsValue, m_tagTypeNumber);
     }
     
@@ -5134,39 +7413,6 @@ private:
     {
         return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
     }
-    LValue jsValueToDouble(Edge edge, LValue boxedValue)
-    {
-        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
-        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
-            
-        LValue isNotInt32;
-        if (!m_interpreter.needsTypeCheck(edge, SpecInt32))
-            isNotInt32 = m_out.booleanFalse;
-        else if (!m_interpreter.needsTypeCheck(edge, ~SpecInt32))
-            isNotInt32 = m_out.booleanTrue;
-        else
-            isNotInt32 = this->isNotInt32(boxedValue);
-        m_out.branch(isNotInt32, unsure(doubleCase), unsure(intCase));
-            
-        LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
-            
-        ValueFromBlock intToDouble = m_out.anchor(
-            m_out.intToDouble(unboxInt32(boxedValue)));
-        m_out.jump(continuation);
-            
-        m_out.appendTo(doubleCase, continuation);
-            
-        FTL_TYPE_CHECK(
-            jsValueValue(boxedValue), edge, SpecBytecodeNumber, isCellOrMisc(boxedValue));
-            
-        ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
-        m_out.jump(continuation);
-            
-        m_out.appendTo(continuation, lastNext);
-            
-        return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
-    }
     
     LValue jsValueToStrictInt52(Edge edge, LValue boxedValue)
     {
@@ -5215,44 +7461,84 @@ private:
         
         return possibleResult;
     }
-    
-    LValue isNumber(LValue jsValue)
+
+    LValue convertDoubleToInt32(LValue value, bool shouldCheckNegativeZero)
+    {
+        LValue integerValue = m_out.fpToInt32(value);
+        LValue integerValueConvertedToDouble = m_out.intToDouble(integerValue);
+        LValue valueNotConvertibleToInteger = m_out.doubleNotEqualOrUnordered(value, integerValueConvertedToDouble);
+        speculate(Overflow, FormattedValue(ValueFormatDouble, value), m_node, valueNotConvertibleToInteger);
+
+        if (shouldCheckNegativeZero) {
+            LBasicBlock valueIsZero = FTL_NEW_BLOCK(m_out, ("ConvertDoubleToInt32 on zero"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ConvertDoubleToInt32 continuation"));
+            m_out.branch(m_out.isZero32(integerValue), unsure(valueIsZero), unsure(continuation));
+
+            LBasicBlock lastNext = m_out.appendTo(valueIsZero, continuation);
+
+            LValue doubleBitcastToInt64 = m_out.bitCast(value, m_out.int64);
+            LValue signBitSet = m_out.lessThan(doubleBitcastToInt64, m_out.constInt64(0));
+
+            speculate(NegativeZero, FormattedValue(ValueFormatDouble, value), m_node, signBitSet);
+            m_out.jump(continuation);
+            m_out.appendTo(continuation, lastNext);
+        }
+        return integerValue;
+    }
+
+    LValue isNumber(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecFullNumber))
+            return proven;
         return isNotCellOrMisc(jsValue);
     }
-    LValue isNotNumber(LValue jsValue)
+    LValue isNotNumber(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecFullNumber))
+            return proven;
         return isCellOrMisc(jsValue);
     }
     
-    LValue isNotCell(LValue jsValue)
+    LValue isNotCell(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecCell))
+            return proven;
         return m_out.testNonZero64(jsValue, m_tagMask);
     }
     
-    LValue isCell(LValue jsValue)
+    LValue isCell(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecCell))
+            return proven;
         return m_out.testIsZero64(jsValue, m_tagMask);
     }
     
-    LValue isNotMisc(LValue value)
+    LValue isNotMisc(LValue value, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecMisc))
+            return proven;
         return m_out.above(value, m_out.constInt64(TagBitTypeOther | TagBitBool | TagBitUndefined));
     }
     
-    LValue isMisc(LValue value)
+    LValue isMisc(LValue value, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecMisc))
+            return proven;
         return m_out.bitNot(isNotMisc(value));
     }
     
-    LValue isNotBoolean(LValue jsValue)
+    LValue isNotBoolean(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecBoolean))
+            return proven;
         return m_out.testNonZero64(
             m_out.bitXor(jsValue, m_out.constInt64(ValueFalse)),
             m_out.constInt64(~1));
     }
-    LValue isBoolean(LValue jsValue)
+    LValue isBoolean(LValue jsValue, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecBoolean))
+            return proven;
         return m_out.bitNot(isNotBoolean(jsValue));
     }
     LValue unboxBoolean(LValue jsValue)
@@ -5267,18 +7553,31 @@ private:
             value, m_out.constInt64(ValueTrue), m_out.constInt64(ValueFalse));
     }
     
-    LValue isNotOther(LValue value)
+    LValue isNotOther(LValue value, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, ~SpecOther))
+            return proven;
         return m_out.notEqual(
             m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
             m_out.constInt64(ValueNull));
     }
-    LValue isOther(LValue value)
+    LValue isOther(LValue value, SpeculatedType type = SpecFullTop)
     {
+        if (LValue proven = isProvenValue(type, SpecOther))
+            return proven;
         return m_out.equal(
             m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
             m_out.constInt64(ValueNull));
     }
+    
+    LValue isProvenValue(SpeculatedType provenType, SpeculatedType wantedType)
+    {
+        if (!(provenType & ~wantedType))
+            return m_out.booleanTrue;
+        if (!(provenType & wantedType))
+            return m_out.booleanFalse;
+        return nullptr;
+    }
 
     void speculate(Edge edge)
     {
@@ -5306,6 +7605,9 @@ private:
         case ObjectUse:
             speculateObject(edge);
             break;
+        case FunctionUse:
+            speculateFunction(edge);
+            break;
         case ObjectOrOtherUse:
             speculateObjectOrOther(edge);
             break;
@@ -5327,8 +7629,11 @@ private:
         case NumberUse:
             speculateNumber(edge);
             break;
+        case RealNumberUse:
+            speculateRealNumber(edge);
+            break;
         case DoubleRepRealUse:
-            speculateDoubleReal(edge);
+            speculateDoubleRepReal(edge);
             break;
         case DoubleRepMachineIntUse:
             speculateDoubleRepMachineInt(edge);
@@ -5349,8 +7654,7 @@ private:
             speculateMisc(edge);
             break;
         default:
-            LOWERING_FAILED(m_node, "Unsupported speculation use kind");
-            return;
+            DFG_CRASH(m_graph, m_node, "Unsupported speculation use kind");
         }
     }
     
@@ -5377,28 +7681,40 @@ private:
         jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
     }
     
-    LValue isObject(LValue cell)
+    LValue isObject(LValue cell, SpeculatedType type = SpecFullTop)
     {
-        return m_out.notEqual(
-            m_out.load32(cell, m_heaps.JSCell_structureID),
-            m_out.constInt32(vm().stringStructure->id()));
+        if (LValue proven = isProvenValue(type & SpecCell, SpecObject))
+            return proven;
+        return m_out.aboveOrEqual(
+            m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+            m_out.constInt8(ObjectType));
     }
-    
-    LValue isNotString(LValue cell)
+
+    LValue isNotObject(LValue cell, SpeculatedType type = SpecFullTop)
     {
-        return isObject(cell);
+        if (LValue proven = isProvenValue(type & SpecCell, ~SpecObject))
+            return proven;
+        return m_out.below(
+            m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+            m_out.constInt8(ObjectType));
     }
-    
-    LValue isString(LValue cell)
+
+    LValue isNotString(LValue cell, SpeculatedType type = SpecFullTop)
     {
-        return m_out.equal(
+        if (LValue proven = isProvenValue(type & SpecCell, ~SpecString))
+            return proven;
+        return m_out.notEqual(
             m_out.load32(cell, m_heaps.JSCell_structureID),
             m_out.constInt32(vm().stringStructure->id()));
     }
     
-    LValue isNotObject(LValue cell)
+    LValue isString(LValue cell, SpeculatedType type = SpecFullTop)
     {
-        return isString(cell);
+        if (LValue proven = isProvenValue(type & SpecCell, SpecString))
+            return proven;
+        return m_out.equal(
+            m_out.load32(cell, m_heaps.JSCell_structureID),
+            m_out.constInt32(vm().stringStructure->id()));
     }
     
     LValue isArrayType(LValue cell, ArrayMode arrayMode)
@@ -5411,7 +7727,7 @@ private:
             
             switch (arrayMode.arrayClass()) {
             case Array::OriginalArray:
-                LOWERING_FAILED(m_node, "Unexpected original array");
+                DFG_CRASH(m_graph, m_node, "Unexpected original array");
                 return 0;
                 
             case Array::Array:
@@ -5431,10 +7747,19 @@ private:
                     m_out.constInt8(arrayMode.shapeMask()));
             }
             
-            LOWERING_FAILED(m_node, "Corrupt array class");
-            return 0;
+            DFG_CRASH(m_graph, m_node, "Corrupt array class");
         }
             
+        case Array::DirectArguments:
+            return m_out.equal(
+                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+                m_out.constInt8(DirectArgumentsType));
+            
+        case Array::ScopedArguments:
+            return m_out.equal(
+                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+                m_out.constInt8(ScopedArgumentsType));
+            
         default:
             return m_out.equal(
                 m_out.load8(cell, m_heaps.JSCell_typeInfoType), 
@@ -5442,6 +7767,28 @@ private:
         }
     }
     
+    LValue isFunction(LValue cell, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type & SpecCell, SpecFunction))
+            return proven;
+        return isType(cell, JSFunctionType);
+    }
+    LValue isNotFunction(LValue cell, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type & SpecCell, ~SpecFunction))
+            return proven;
+        return isNotType(cell, JSFunctionType);
+    }
+            
+    LValue isExoticForTypeof(LValue cell, SpeculatedType type = SpecFullTop)
+    {
+        if (!(type & SpecObjectOther))
+            return m_out.booleanFalse;
+        return m_out.testNonZero8(
+            m_out.load8(cell, m_heaps.JSCell_typeInfoFlags),
+            m_out.constInt8(MasqueradesAsUndefined | TypeOfShouldCallGetCallData));
+    }
+    
     LValue isType(LValue cell, JSType type)
     {
         return m_out.equal(
@@ -5464,18 +7811,28 @@ private:
         speculateObject(edge, lowCell(edge));
     }
     
+    void speculateFunction(Edge edge, LValue cell)
+    {
+        FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecFunction, isNotFunction(cell));
+    }
+    
+    void speculateFunction(Edge edge)
+    {
+        speculateFunction(edge, lowCell(edge));
+    }
+    
     void speculateObjectOrOther(Edge edge)
     {
         if (!m_interpreter.needsTypeCheck(edge))
             return;
         
-        LValue value = lowJSValue(edge);
+        LValue value = lowJSValue(edge, ManualOperandSpeculation);
         
         LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther cell case"));
         LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther primitive case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther continuation"));
         
-        m_out.branch(isNotCell(value), unsure(primitiveCase), unsure(cellCase));
+        m_out.branch(isNotCell(value, provenType(edge)), unsure(primitiveCase), unsure(cellCase));
         
         LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
         
@@ -5575,21 +7932,17 @@ private:
         Structure* stringObjectStructure =
             m_graph.globalObjectFor(m_node->origin.semantic)->stringObjectStructure();
         
-        if (m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure)))
+        if (abstractStructure(edge).isSubsetOf(StructureSet(stringObjectStructure)))
             return;
         
         speculate(
             NotStringObject, noValue(), 0,
-            m_out.notEqual(structureID, weakStructure(stringObjectStructure)));
+            m_out.notEqual(structureID, weakStructureID(stringObjectStructure)));
     }
     
     void speculateNonNullObject(Edge edge, LValue cell)
     {
-        FTL_TYPE_CHECK(
-            jsValueValue(cell), edge, SpecObject, 
-            m_out.equal(
-                m_out.load32(cell, m_heaps.JSCell_structureID),
-                m_out.constInt32(vm().stringStructure->id())));
+        FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecObject, isNotObject(cell));
         if (masqueradesAsUndefinedWatchpointIsStillValid())
             return;
         
@@ -5606,7 +7959,33 @@ private:
         FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBytecodeNumber, isNotNumber(value));
     }
     
-    void speculateDoubleReal(Edge edge)
+    void speculateRealNumber(Edge edge)
+    {
+        // Do an early return here because lowDouble() can create a lot of control flow.
+        if (!m_interpreter.needsTypeCheck(edge))
+            return;
+        
+        LValue value = lowJSValue(edge, ManualOperandSpeculation);
+        LValue doubleValue = unboxDouble(value);
+        
+        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("speculateRealNumber int case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("speculateRealNumber continuation"));
+        
+        m_out.branch(
+            m_out.doubleEqual(doubleValue, doubleValue),
+            usually(continuation), rarely(intCase));
+        
+        LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
+        
+        typeCheck(
+            jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
+            isNotInt32(value, provenType(m_node->child1()) & ~SpecFullDouble));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+    }
+    
+    void speculateDoubleRepReal(Edge edge)
     {
         // Do an early return here because lowDouble() can create a lot of control flow.
         if (!m_interpreter.needsTypeCheck(edge))
@@ -5642,10 +8021,10 @@ private:
         LBasicBlock isStringCase = FTL_NEW_BLOCK(m_out, ("Speculate NotStringVar is string case"));
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Speculate NotStringVar continuation"));
         
-        m_out.branch(isCell(value), unsure(isCellCase), unsure(continuation));
+        m_out.branch(isCell(value, provenType(edge)), unsure(isCellCase), unsure(continuation));
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
-        m_out.branch(isString(value), unsure(isStringCase), unsure(continuation));
+        m_out.branch(isString(value, provenType(edge)), unsure(isStringCase), unsure(continuation));
         
         m_out.appendTo(isStringCase, continuation);
         speculateStringIdent(edge, value, m_out.loadPtr(value, m_heaps.JSString_value));
@@ -5705,22 +8084,22 @@ private:
 
         // Append to the write barrier buffer.
         LBasicBlock lastNext = m_out.appendTo(isMarkedAndNotRemembered, bufferHasSpace);
-        LValue currentBufferIndex = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
-        LValue bufferCapacity = m_out.load32(m_out.absolute(&vm().heap.writeBarrierBuffer().m_capacity));
+        LValue currentBufferIndex = m_out.load32(m_out.absolute(vm().heap.writeBarrierBuffer().currentIndexAddress()));
+        LValue bufferCapacity = m_out.constInt32(vm().heap.writeBarrierBuffer().capacity());
         m_out.branch(
             m_out.lessThan(currentBufferIndex, bufferCapacity),
             usually(bufferHasSpace), rarely(bufferIsFull));
 
         // Buffer has space, store to it.
         m_out.appendTo(bufferHasSpace, bufferIsFull);
-        LValue writeBarrierBufferBase = m_out.loadPtr(m_out.absolute(&vm().heap.writeBarrierBuffer().m_buffer));
-        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExt(currentBufferIndex, m_out.intPtr), ScalePtr));
-        m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
+        LValue writeBarrierBufferBase = m_out.constIntPtr(vm().heap.writeBarrierBuffer().buffer());
+        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExtPtr(currentBufferIndex)));
+        m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(vm().heap.writeBarrierBuffer().currentIndexAddress()));
         m_out.jump(continuation);
 
         // Buffer is out of space, flush it.
         m_out.appendTo(bufferIsFull, continuation);
-        vmCall(m_out.operation(operationFlushWriteBarrierBuffer), m_callFrame, base, NoExceptions);
+        vmCallNoExceptions(m_out.operation(operationFlushWriteBarrierBuffer), m_callFrame, base);
         m_out.jump(continuation);
 
         m_out.appendTo(continuation, lastNext);
@@ -5729,44 +8108,23 @@ private:
 #endif
     }
 
-    enum ExceptionCheckMode { NoExceptions, CheckExceptions };
-    
-    LValue vmCall(LValue function, ExceptionCheckMode mode = CheckExceptions)
-    {
-        callPreflight();
-        LValue result = m_out.call(function);
-        callCheck(mode);
-        return result;
-    }
-    LValue vmCall(LValue function, LValue arg1, ExceptionCheckMode mode = CheckExceptions)
-    {
-        callPreflight();
-        LValue result = m_out.call(function, arg1);
-        callCheck(mode);
-        return result;
-    }
-    LValue vmCall(LValue function, LValue arg1, LValue arg2, ExceptionCheckMode mode = CheckExceptions)
-    {
-        callPreflight();
-        LValue result = m_out.call(function, arg1, arg2);
-        callCheck(mode);
-        return result;
-    }
-    LValue vmCall(LValue function, LValue arg1, LValue arg2, LValue arg3, ExceptionCheckMode mode = CheckExceptions)
+    template<typename... Args>
+    LValue vmCall(LValue function, Args... args)
     {
         callPreflight();
-        LValue result = m_out.call(function, arg1, arg2, arg3);
-        callCheck(mode);
+        LValue result = m_out.call(function, args...);
+        callCheck();
         return result;
     }
-    LValue vmCall(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, ExceptionCheckMode mode = CheckExceptions)
+    
+    template<typename... Args>
+    LValue vmCallNoExceptions(LValue function, Args... args)
     {
         callPreflight();
-        LValue result = m_out.call(function, arg1, arg2, arg3, arg4);
-        callCheck(mode);
+        LValue result = m_out.call(function, args...);
         return result;
     }
-    
+
     void callPreflight(CodeOrigin codeOrigin)
     {
         m_out.store32(
@@ -5780,19 +8138,17 @@ private:
         callPreflight(m_node->origin.semantic);
     }
     
-    void callCheck(ExceptionCheckMode mode = CheckExceptions)
+    void callCheck()
     {
-        if (mode == NoExceptions)
-            return;
-        
         if (Options::enableExceptionFuzz())
             m_out.call(m_out.operation(operationExceptionFuzz));
         
         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Exception check continuation"));
         
+        LValue exception = m_out.load64(m_out.absolute(vm().addressOfException()));
+        
         m_out.branch(
-            m_out.notZero64(m_out.load64(m_out.absolute(vm().addressOfException()))),
-            rarely(m_handleExceptions), usually(continuation));
+            m_out.notZero64(exception), rarely(m_handleExceptions), usually(continuation));
         
         m_out.appendTo(continuation);
     }
@@ -5802,32 +8158,47 @@ private:
         return m_blocks.get(block);
     }
     
-    void initializeOSRExitStateForBlock()
-    {
-        m_availability = m_highBlock->ssa->availabilityAtHead;
-    }
-    
     void appendOSRExit(
         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
     {
         if (verboseCompilationEnabled()) {
-            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", m_availability, "\n");
+            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", availabilityMap(), "\n");
             if (!m_availableRecoveries.isEmpty())
                 dataLog("        Available recoveries: ", listDump(m_availableRecoveries), "\n");
         }
+        
+        if (doOSRExitFuzzing()) {
+            LValue numberOfFuzzChecks = m_out.add(
+                m_out.load32(m_out.absolute(&g_numberOfOSRExitFuzzChecks)),
+                m_out.int32One);
+            
+            m_out.store32(numberOfFuzzChecks, m_out.absolute(&g_numberOfOSRExitFuzzChecks));
+            
+            if (unsigned atOrAfter = Options::fireOSRExitFuzzAtOrAfter()) {
+                failCondition = m_out.bitOr(
+                    failCondition,
+                    m_out.aboveOrEqual(numberOfFuzzChecks, m_out.constInt32(atOrAfter)));
+            }
+            if (unsigned at = Options::fireOSRExitFuzzAt()) {
+                failCondition = m_out.bitOr(
+                    failCondition,
+                    m_out.equal(numberOfFuzzChecks, m_out.constInt32(at)));
+            }
+        }
 
         ASSERT(m_ftlState.jitCode->osrExit.size() == m_ftlState.finalizer->osrExit.size());
         
         m_ftlState.jitCode->osrExit.append(OSRExit(
             kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
             m_codeOriginForExitTarget, m_codeOriginForExitProfile,
-            m_availability.numberOfArguments(), m_availability.numberOfLocals()));
+            availabilityMap().m_locals.numberOfArguments(),
+            availabilityMap().m_locals.numberOfLocals()));
         m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
         
         OSRExit& exit = m_ftlState.jitCode->osrExit.last();
 
-        LBasicBlock lastNext = 0;
-        LBasicBlock continuation = 0;
+        LBasicBlock lastNext = nullptr;
+        LBasicBlock continuation = nullptr;
         
         LBasicBlock failCase = FTL_NEW_BLOCK(m_out, ("OSR exit failCase for ", m_node));
         continuation = FTL_NEW_BLOCK(m_out, ("OSR exit continuation for ", m_node));
@@ -5861,62 +8232,56 @@ private:
         if (!!lowValue)
             arguments.append(lowValue.value());
         
+        AvailabilityMap availabilityMap = this->availabilityMap();
+        availabilityMap.pruneByLiveness(m_graph, codeOrigin);
+        
+        HashMap<Node*, ExitTimeObjectMaterialization*> map;
+        availabilityMap.forEachAvailability(
+            [&] (Availability availability) {
+                if (!availability.shouldUseNode())
+                    return;
+                
+                Node* node = availability.node();
+                if (!node->isPhantomAllocation())
+                    return;
+                
+                auto result = map.add(node, nullptr);
+                if (result.isNewEntry) {
+                    result.iterator->value =
+                        exit.m_materializations.add(node->op(), node->origin.semantic);
+                }
+            });
+        
         for (unsigned i = 0; i < exit.m_values.size(); ++i) {
             int operand = exit.m_values.operandForIndex(i);
-            bool isLive = m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin);
-            if (!isLive) {
-                exit.m_values[i] = ExitValue::dead();
-                continue;
-            }
             
-            Availability availability = m_availability[i];
-            FlushedAt flush = availability.flushedAt();
-            switch (flush.format()) {
-            case DeadFlush:
-            case ConflictingFlush:
-                if (availability.hasNode()) {
-                    addExitArgumentForNode(exit, arguments, i, availability.node());
-                    break;
-                }
-                
-                if (Options::validateFTLOSRExitLiveness()) {
-                    dataLog("Expected r", operand, " to be available but it wasn't.\n");
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
-                
-                // This means that the DFG's DCE proved that the value is dead in bytecode
-                // even though the bytecode liveness analysis thinks it's live. This is
-                // acceptable since the DFG's DCE is by design more aggressive while still
-                // being sound.
-                exit.m_values[i] = ExitValue::dead();
-                break;
-
-            case FlushedJSValue:
-            case FlushedCell:
-            case FlushedBoolean:
-                exit.m_values[i] = ExitValue::inJSStack(flush.virtualRegister());
-                break;
-                
-            case FlushedInt32:
-                exit.m_values[i] = ExitValue::inJSStackAsInt32(flush.virtualRegister());
-                break;
-                
-            case FlushedInt52:
-                exit.m_values[i] = ExitValue::inJSStackAsInt52(flush.virtualRegister());
-                break;
-                
-            case FlushedDouble:
-                exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
-                break;
-                
-            case FlushedArguments:
-                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
-                break;
+            Availability availability = availabilityMap.m_locals[i];
+            
+            if (Options::validateFTLOSRExitLiveness()) {
+                DFG_ASSERT(
+                    m_graph, m_node,
+                    (!(availability.isDead() && m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin))) || m_graph.m_plan.mode == FTLForOSREntryMode);
             }
+            
+            exit.m_values[i] = exitValueForAvailability(arguments, map, availability);
         }
         
-        if (verboseCompilationEnabled())
+        for (auto heapPair : availabilityMap.m_heap) {
+            Node* node = heapPair.key.base();
+            ExitTimeObjectMaterialization* materialization = map.get(node);
+            materialization->add(
+                heapPair.key.descriptor(),
+                exitValueForAvailability(arguments, map, heapPair.value));
+        }
+        
+        if (verboseCompilationEnabled()) {
             dataLog("        Exit values: ", exit.m_values, "\n");
+            if (!exit.m_materializations.isEmpty()) {
+                dataLog("        Materializations: \n");
+                for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+                    dataLog("            ", pointerDump(materialization), "\n");
+            }
+        }
     }
     
     void callStackmap(OSRExit& exit, ExitArgumentList& arguments)
@@ -5928,97 +8293,115 @@ private:
         m_out.call(m_out.stackmapIntrinsic(), arguments);
     }
     
-    void addExitArgumentForNode(
-        OSRExit& exit, ExitArgumentList& arguments, unsigned index, Node* node)
+    ExitValue exitValueForAvailability(
+        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
+        Availability availability)
+    {
+        FlushedAt flush = availability.flushedAt();
+        switch (flush.format()) {
+        case DeadFlush:
+        case ConflictingFlush:
+            if (availability.hasNode())
+                return exitValueForNode(arguments, map, availability.node());
+            
+            // This means that the value is dead. It could be dead in bytecode or it could have
+            // been killed by our DCE, which can sometimes kill things even if they were live in
+            // bytecode.
+            return ExitValue::dead();
+
+        case FlushedJSValue:
+        case FlushedCell:
+        case FlushedBoolean:
+            return ExitValue::inJSStack(flush.virtualRegister());
+                
+        case FlushedInt32:
+            return ExitValue::inJSStackAsInt32(flush.virtualRegister());
+                
+        case FlushedInt52:
+            return ExitValue::inJSStackAsInt52(flush.virtualRegister());
+                
+        case FlushedDouble:
+            return ExitValue::inJSStackAsDouble(flush.virtualRegister());
+        }
+        
+        DFG_CRASH(m_graph, m_node, "Invalid flush format");
+        return ExitValue::dead();
+    }
+    
+    ExitValue exitValueForNode(
+        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
+        Node* node)
     {
         ASSERT(node->shouldGenerate());
         ASSERT(node->hasResult());
 
-        if (tryToSetConstantExitArgument(exit, index, node))
-            return;
+        if (node) {
+            switch (node->op()) {
+            case BottomValue:
+                // This might arise in object materializations. I actually doubt that it would,
+                // but it seems worthwhile to be conservative.
+                return ExitValue::dead();
+                
+            case JSConstant:
+            case Int52Constant:
+            case DoubleConstant:
+                return ExitValue::constant(node->asJSValue());
+                
+            default:
+                if (node->isPhantomAllocation())
+                    return ExitValue::materializeNewObject(map.get(node));
+                break;
+            }
+        }
         
         for (unsigned i = 0; i < m_availableRecoveries.size(); ++i) {
             AvailableRecovery recovery = m_availableRecoveries[i];
             if (recovery.node() != node)
                 continue;
             
-            exit.m_values[index] = ExitValue::recovery(
+            ExitValue result = ExitValue::recovery(
                 recovery.opcode(), arguments.size(), arguments.size() + 1,
                 recovery.format());
             arguments.append(recovery.left());
             arguments.append(recovery.right());
-            return;
+            return result;
         }
         
         LoweredNodeValue value = m_int32Values.get(node);
-        if (isValid(value)) {
-            addExitArgument(exit, arguments, index, ValueFormatInt32, value.value());
-            return;
-        }
+        if (isValid(value))
+            return exitArgument(arguments, ValueFormatInt32, value.value());
         
         value = m_int52Values.get(node);
-        if (isValid(value)) {
-            addExitArgument(exit, arguments, index, ValueFormatInt52, value.value());
-            return;
-        }
+        if (isValid(value))
+            return exitArgument(arguments, ValueFormatInt52, value.value());
         
         value = m_strictInt52Values.get(node);
-        if (isValid(value)) {
-            addExitArgument(exit, arguments, index, ValueFormatStrictInt52, value.value());
-            return;
-        }
+        if (isValid(value))
+            return exitArgument(arguments, ValueFormatStrictInt52, value.value());
         
         value = m_booleanValues.get(node);
         if (isValid(value)) {
             LValue valueToPass = m_out.zeroExt(value.value(), m_out.int32);
-            addExitArgument(exit, arguments, index, ValueFormatBoolean, valueToPass);
-            return;
+            return exitArgument(arguments, ValueFormatBoolean, valueToPass);
         }
         
         value = m_jsValueValues.get(node);
-        if (isValid(value)) {
-            addExitArgument(exit, arguments, index, ValueFormatJSValue, value.value());
-            return;
-        }
+        if (isValid(value))
+            return exitArgument(arguments, ValueFormatJSValue, value.value());
         
         value = m_doubleValues.get(node);
-        if (isValid(value)) {
-            addExitArgument(exit, arguments, index, ValueFormatDouble, value.value());
-            return;
-        }
+        if (isValid(value))
+            return exitArgument(arguments, ValueFormatDouble, value.value());
 
-        startCrashing();
-        dataLog("Cannot find value for node: ", node, " while compiling exit at ", exit.m_codeOrigin, " in node ", m_node, "\n");
-        m_graph.dump();
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    
-    bool tryToSetConstantExitArgument(OSRExit& exit, unsigned index, Node* node)
-    {
-        if (!node)
-            return false;
-        
-        switch (node->op()) {
-        case JSConstant:
-        case Int52Constant:
-        case DoubleConstant:
-        case WeakJSConstant:
-            exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
-            return true;
-        case PhantomArguments:
-            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
-            return true;
-        default:
-            return false;
-        }
+        DFG_CRASH(m_graph, m_node, toCString("Cannot find value for node: ", node).data());
+        return ExitValue::dead();
     }
     
-    void addExitArgument(
-        OSRExit& exit, ExitArgumentList& arguments, unsigned index, ValueFormat format,
-        LValue value)
+    ExitValue exitArgument(ExitArgumentList& arguments, ValueFormat format, LValue value)
     {
-        exit.m_values[index] = ExitValue::exitArgument(ExitArgument(format, arguments.size()));
+        ExitValue result = ExitValue::exitArgument(ExitArgument(format, arguments.size()));
         arguments.append(value);
+        return result;
     }
     
     bool doesKill(Edge edge)
@@ -6068,7 +8451,7 @@ private:
             return;
         }
         
-        LOWERING_FAILED(m_node, "Corrupt int52 kind");
+        DFG_CRASH(m_graph, m_node, "Corrupt int52 kind");
     }
     void setJSValue(Node* node, LValue value)
     {
@@ -6139,9 +8522,9 @@ private:
         LValue tableIndex = m_out.load32(value, m_heaps.JSCell_structureID);
         LValue tableBase = m_out.loadPtr(
             m_out.absolute(vm().heap.structureIDTable().base()));
-        LValue pointerIntoTable = m_out.baseIndex(
-            tableBase, m_out.zeroExt(tableIndex, m_out.intPtr), ScaleEight);
-        return m_out.loadPtr(TypedPointer(m_heaps.structureTable, pointerIntoTable));
+        TypedPointer address = m_out.baseIndex(
+            m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex));
+        return m_out.loadPtr(address);
     }
 
     LValue weakPointer(JSCell* pointer)
@@ -6150,12 +8533,17 @@ private:
         return m_out.constIntPtr(pointer);
     }
 
-    LValue weakStructure(Structure* structure)
+    LValue weakStructureID(Structure* structure)
     {
         addWeakReference(structure);
         return m_out.constInt32(structure->id());
     }
     
+    LValue weakStructure(Structure* structure)
+    {
+        return weakPointer(structure);
+    }
+    
     TypedPointer addressFor(LValue base, int operand, ptrdiff_t offset = 0)
     {
         return m_out.address(base, m_heaps.variables[operand], offset);
@@ -6195,24 +8583,72 @@ private:
         return addressFor(operand, TagOffset);
     }
     
-    NO_RETURN_DUE_TO_ASSERT void loweringFailed(Node* node, const char* file, int line, const char* function, const char* assertion)
+    AbstractValue abstractValue(Node* node)
     {
-        if (!ASSERT_DISABLED) {
-            dataLog("FTL ASSERTION FAILED: ", assertion, "\n");
-            dataLog(file, "(", line, ") : ", function, "\n");
-            dataLog("While handling node ", node, "\n");
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-
-        m_loweringSucceeded = false;
+        return m_state.forNode(node);
+    }
+    AbstractValue abstractValue(Edge edge)
+    {
+        return abstractValue(edge.node());
+    }
+    
+    SpeculatedType provenType(Node* node)
+    {
+        return abstractValue(node).m_type;
+    }
+    SpeculatedType provenType(Edge edge)
+    {
+        return provenType(edge.node());
+    }
+    
+    JSValue provenValue(Node* node)
+    {
+        return abstractValue(node).m_value;
+    }
+    JSValue provenValue(Edge edge)
+    {
+        return provenValue(edge.node());
+    }
+    
+    StructureAbstractValue abstractStructure(Node* node)
+    {
+        return abstractValue(node).m_structure;
+    }
+    StructureAbstractValue abstractStructure(Edge edge)
+    {
+        return abstractStructure(edge.node());
+    }
+    
+    void crash()
+    {
+        crash(m_highBlock->index, m_node->index());
+    }
+    void crash(BlockIndex blockIndex, unsigned nodeIndex)
+    {
+#if ASSERT_DISABLED
+        m_out.call(m_out.operation(ftlUnreachable));
+        UNUSED_PARAM(blockIndex);
+        UNUSED_PARAM(nodeIndex);
+#else
+        m_out.call(
+            m_out.intToPtr(
+                m_out.constIntPtr(ftlUnreachable),
+                pointerType(
+                    functionType(
+                        m_out.voidType, m_out.intPtr, m_out.int32, m_out.int32))),
+            m_out.constIntPtr(codeBlock()), m_out.constInt32(blockIndex),
+            m_out.constInt32(nodeIndex));
+#endif
+        m_out.unreachable();
     }
 
+    AvailabilityMap& availabilityMap() { return m_availabilityCalculator.m_availability; }
+    
     VM& vm() { return m_graph.m_vm; }
     CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
     
     Graph& m_graph;
     State& m_ftlState;
-    bool m_loweringSucceeded;
     AbstractHeapRepository m_heaps;
     Output m_out;
     
@@ -6220,6 +8656,8 @@ private:
     LBasicBlock m_handleExceptions;
     HashMap<BasicBlock*, LBasicBlock> m_blocks;
     
+    LValue m_execState;
+    LValue m_execStorage;
     LValue m_callFrame;
     LValue m_captured;
     LValue m_tagTypeNumber;
@@ -6233,9 +8671,14 @@ private:
     HashMap<Node*, LoweredNodeValue> m_storageValues;
     HashMap<Node*, LoweredNodeValue> m_doubleValues;
     
+    // This is a bit of a hack. It prevents LLVM from having to do CSE on loading of arguments.
+    // It's nice to have these optimizations on our end because we can guarantee them a bit better.
+    // Probably also saves LLVM compile time.
+    HashMap<Node*, LValue> m_loadedArgumentValues;
+    
     HashMap<Node*, LValue> m_phis;
     
-    Operands<Availability> m_availability;
+    LocalOSRAvailabilityCalculator m_availabilityCalculator;
     
     Vector<AvailableRecovery, 3> m_availableRecoveries;
     
@@ -6251,12 +8694,16 @@ private:
     Node* m_node;
     
     uint32_t m_stackmapIDs;
+    unsigned m_tbaaKind;
+    unsigned m_tbaaStructKind;
 };
 
-bool lowerDFGToLLVM(State& state)
+} // anonymous namespace
+
+void lowerDFGToLLVM(State& state)
 {
     LowerDFGToLLVM lowering(state);
-    return lowering.lower();
+    lowering.lower();
 }
 
 } } // namespace JSC::FTL
index 141b625c8d4c98c1e716f0052269845628d0f4a7..0e38d7ba98d6243e3e3a7de3c8cdb4f39ba576bb 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace JSC { namespace FTL {
 
-bool lowerDFGToLLVM(State&);
+void lowerDFGToLLVM(State&);
 
 } } // namespace JSC::FTL
 
index c31d77c12182c55f30d76c49b134fa1a9c051bf5..8e9d4f4a76c3ba9d99ec517f7b3ab53afbcd021f 100644 (file)
@@ -54,9 +54,12 @@ void* prepareOSREntry(
             bytecodeIndex, ".\n");
     }
     
+    if (bytecodeIndex)
+        jsCast<ScriptExecutable*>(executable)->setDidTryToEnterInLoop(true);
+
     if (bytecodeIndex != entryCode->bytecodeIndex()) {
         if (Options::verboseOSR())
-            dataLog("    OSR failed because we don't have an entrypoint for bc#", bytecodeIndex, "; ours is for bc#", entryCode->bytecodeIndex());
+            dataLog("    OSR failed because we don't have an entrypoint for bc#", bytecodeIndex, "; ours is for bc#", entryCode->bytecodeIndex(), "\n");
         return 0;
     }
     
index 6132ea1bb1012141c3ed417a9bd5d0252eba31de..3d96f39447a8dff0ec03a13cf121adfc668ef084 100644 (file)
@@ -61,6 +61,15 @@ CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
         m_patchableCodeOffset);
 }
 
+void OSRExit::validateReferences(const TrackedReferences& trackedReferences)
+{
+    for (unsigned i = m_values.size(); i--;)
+        m_values[i].validateReferences(trackedReferences);
+    
+    for (ExitTimeObjectMaterialization* materialization : m_materializations)
+        materialization->validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
index c623199f1adef15f22c59c2f19f91a8d1f898226..337c618405a6acdf0067e2414097e7a94507c8ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 #include "DFGOSRExitBase.h"
 #include "FTLAbbreviations.h"
 #include "FTLExitArgumentList.h"
+#include "FTLExitTimeObjectMaterialization.h"
 #include "FTLExitValue.h"
 #include "FTLFormattedValue.h"
 #include "MethodOfGettingAValueProfile.h"
 #include "ValueProfile.h"
 #include "VirtualRegister.h"
 
-namespace JSC { namespace FTL {
+namespace JSC {
+
+class TrackedReferences;
+
+namespace FTL {
 
 // Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing
 // the crazy that is OSR down to simple SSA CFG primitives that any compiler backend
-// (including of course LLVM) can grok and do meaningful things to. Except for
-// watchpoint-based exits, which haven't yet been implemented (see webkit.org/b/113647),
-// an exit is just a conditional branch in the emitted code where one destination is the
-// continuation and the other is a basic block that performs a no-return tail-call to an
-// exit thunk. This thunk takes as its arguments the live non-constant
-// not-already-accounted-for bytecode state. To appreciate how this works consider the
-// following JavaScript program, and its lowering down to LLVM IR including the relevant
-// exits:
+// (including of course LLVM) can grok and do meaningful things to. An exit is just a
+// conditional branch in the emitted code where one destination is the continuation and
+// the other is a basic block that performs a no-return tail-call to an  exit thunk.
+// This thunk takes as its arguments the live non-constant not-already-accounted-for
+// bytecode state. To appreciate how this works consider the following JavaScript
+// program, and its lowering down to LLVM IR including the relevant exits:
 //
 // function foo(o) {
 //     var a = o.a; // predicted int
@@ -65,10 +68,10 @@ namespace JSC { namespace FTL {
 //
 // BitOr(Check:Int32:@a, Int32:5)
 //
-// Where @a is the node for the GetLocal node that gets the value of the 'a' variable.
-// Conceptually, this node can be further broken down to the following (note that this
-// particular lowering never actually happens - we skip this step and go straight to
-// LLVM IR - but it's still useful to see this):
+// Where @a is the node for the value of the 'a' variable. Conceptually, this node can
+// be further broken down to the following (note that this particular lowering never
+// actually happens - we skip this step and go straight to LLVM IR - but it's still
+// useful to see this):
 //
 // exitIf(@a is not int32);
 // continuation;
@@ -123,22 +126,12 @@ namespace JSC { namespace FTL {
 //   arguments into argument position), the backend could choose to simply inform us
 //   where it had placed the arguments and expect the callee (i.e. the exit thunk) to
 //   figure it out from there. It could also tell us what we need to do to pop stack,
-//   although again, it doesn't have to; it could just emit that code normally. Though
-//   we don't support this yet, we could; the only thing that would change on our end
-//   is that we'd need feedback from the backend about the location of the arguments
-//   and a description of the things that need to be done to pop stack. This would
-//   involve switching the m_values array to use something more akin to ValueRecovery
-//   rather than the current ExitValue, albeit possibly with some hacks to better
-//   understand the kinds of places where the LLVM backend would put values.
+//   although again, it doesn't have to; it could just emit that code normally. We do
+//   all of these things through the patchpoint/stackmap LLVM intrinsics.
 //
 // - It could be extended to allow the backend to do its own exit hoisting, by using
 //   intrinsics (or meta-data, or something) to inform the backend that it's safe to
 //   make the predicate passed to 'exitIf()' more truthy.
-//
-// - It could be extended to support watchpoints (see webkit.org/b/113647) by making
-//   the predicate passed to 'exitIf()' be an intrinsic that the backend knows to be
-//   true at compile-time. The backend could then turn the conditional branch into a
-//   replaceable jump, much like the DFG does.
 
 struct OSRExit : public DFG::OSRExitBase {
     OSRExit(
@@ -160,15 +153,18 @@ struct OSRExit : public DFG::OSRExitBase {
     unsigned m_patchableCodeOffset;
     
     Operands<ExitValue> m_values;
+    Bag<ExitTimeObjectMaterialization> m_materializations;
     
     uint32_t m_stackmapID;
     
     CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
     
-    bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
+    void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
     {
-        return OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromFTL);
+        OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromFTL);
     }
+    
+    void validateReferences(const TrackedReferences&);
 };
 
 } } // namespace JSC::FTL
index 62e3b999f3e3284622a94347e101ffd2ea918871..27788e7f6a5a9fb9e53069ec54c0900decd9ec7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 #include "FTLExitArgumentForOperand.h"
 #include "FTLJITCode.h"
 #include "FTLOSRExit.h"
+#include "FTLOperations.h"
 #include "FTLState.h"
 #include "FTLSaveRestore.h"
 #include "LinkBuffer.h"
@@ -46,6 +47,83 @@ namespace JSC { namespace FTL {
 
 using namespace DFG;
 
+static void compileRecovery(
+    CCallHelpers& jit, const ExitValue& value, StackMaps::Record* record, StackMaps& stackmaps,
+    char* registerScratch,
+    const HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*>& materializationToPointer)
+{
+    switch (value.kind()) {
+    case ExitValueDead:
+        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
+        break;
+            
+    case ExitValueConstant:
+        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
+        break;
+            
+    case ExitValueArgument:
+        record->locations[value.exitArgument().argument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT0);
+        break;
+            
+    case ExitValueInJSStack:
+    case ExitValueInJSStackAsInt32:
+    case ExitValueInJSStackAsInt52:
+    case ExitValueInJSStackAsDouble:
+        jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
+        break;
+            
+    case ExitValueRecovery:
+        record->locations[value.rightRecoveryArgument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT1);
+        record->locations[value.leftRecoveryArgument()].restoreInto(
+            jit, stackmaps, registerScratch, GPRInfo::regT0);
+        switch (value.recoveryOpcode()) {
+        case AddRecovery:
+            switch (value.recoveryFormat()) {
+            case ValueFormatInt32:
+                jit.add32(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            case ValueFormatInt52:
+                jit.add64(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            break;
+        case SubRecovery:
+            switch (value.recoveryFormat()) {
+            case ValueFormatInt32:
+                jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            case ValueFormatInt52:
+                jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+        break;
+        
+    case ExitValueMaterializeNewObject:
+        jit.loadPtr(materializationToPointer.get(value.objectMaterialization()), GPRInfo::regT0);
+        break;
+            
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+        
+    reboxAccordingToFormat(
+        value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
+}
+
 static void compileStub(
     unsigned exitID, JITCode* jitCode, OSRExit& exit, VM* vm, CodeBlock* codeBlock)
 {
@@ -64,13 +142,39 @@ static void compileStub(
 
     CCallHelpers jit(vm, codeBlock);
     
-    // We need scratch space to save all registers and to build up the JSStack.
-    // Use a scratch buffer to transfer all values.
-    ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(sizeof(EncodedJSValue) * exit.m_values.size() + requiredScratchMemorySizeInBytes() + jitCode->unwindInfo.m_registers.size() * sizeof(uint64_t));
+    // We need scratch space to save all registers, to build up the JS stack, to deal with unwind
+    // fixup, pointers to all of the objects we materialize, and the elements inside those objects
+    // that we materialize.
+    
+    // Figure out how much space we need for those object allocations.
+    unsigned numMaterializations = 0;
+    size_t maxMaterializationNumArguments = 0;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
+        numMaterializations++;
+        
+        maxMaterializationNumArguments = std::max(
+            maxMaterializationNumArguments,
+            materialization->properties().size());
+    }
+    
+    ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(
+        sizeof(EncodedJSValue) * (
+            exit.m_values.size() + numMaterializations + maxMaterializationNumArguments) +
+        requiredScratchMemorySizeInBytes() +
+        jitCode->unwindInfo.m_registers.size() * sizeof(uint64_t));
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
-    char* registerScratch = bitwise_cast<char*>(scratch + exit.m_values.size());
+    EncodedJSValue* materializationPointers = scratch + exit.m_values.size();
+    EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
+    char* registerScratch = bitwise_cast<char*>(materializationArguments + maxMaterializationNumArguments);
     uint64_t* unwindScratch = bitwise_cast<uint64_t*>(registerScratch + requiredScratchMemorySizeInBytes());
     
+    HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*> materializationToPointer;
+    unsigned materializationCount = 0;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
+        materializationToPointer.add(
+            materialization, materializationPointers + materializationCount++);
+    }
+    
     // Note that we come in here, the stack used to be as LLVM left it except that someone called pushToSave().
     // We don't care about the value they saved. But, we do appreciate the fact that they did it, because we use
     // that slot for saveAllRegisters().
@@ -87,7 +191,7 @@ static void compileStub(
         
         Profiler::OSRExit* profilerExit = compilation->addOSRExit(
             exitID, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
-            exit.m_kind, isWatchpoint(exit.m_kind));
+            exit.m_kind, exit.m_kind == UncountableInvalidation);
         jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
     }
 
@@ -120,83 +224,73 @@ static void compileStub(
         if (!!exit.m_valueProfile)
             jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
     }
-
-    // Save all state from wherever the exit data tells us it was, into the appropriate place in
-    // the scratch buffer. This doesn't rebox any values yet.
     
-    for (unsigned index = exit.m_values.size(); index--;) {
-        ExitValue value = exit.m_values[index];
+    // Materialize all objects. Don't materialize an object until all of the objects it needs
+    // have been materialized. Curiously, this is the only place that we have an algorithm that prevents
+    // OSR exit from handling cyclic object materializations. Of course, object allocation sinking
+    // currently wouldn't recognize a cycle as being sinkable - but if it did then the only thing that
+    // would ahve to change is this fixpoint. Instead we would allocate the objects first and populate
+    // them with data later.
+    HashSet<ExitTimeObjectMaterialization*> toMaterialize;
+    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+        toMaterialize.add(materialization);
+    
+    while (!toMaterialize.isEmpty()) {
+        unsigned previousToMaterializeSize = toMaterialize.size();
         
-        switch (value.kind()) {
-        case ExitValueDead:
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueConstant:
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueArgument:
-            record->locations[value.exitArgument().argument()].restoreInto(
-                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
-            break;
-            
-        case ExitValueInJSStack:
-        case ExitValueInJSStackAsInt32:
-        case ExitValueInJSStackAsInt52:
-        case ExitValueInJSStackAsDouble:
-            jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
-            break;
-            
-        case ExitValueArgumentsObjectThatWasNotCreated:
-            // We can't actually recover this yet, but we can make the stack look sane. This is
-            // a prerequisite to running the actual arguments recovery.
-            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
-            break;
-            
-        case ExitValueRecovery:
-            record->locations[value.rightRecoveryArgument()].restoreInto(
-                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT1);
-            record->locations[value.leftRecoveryArgument()].restoreInto(
-                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
-            switch (value.recoveryOpcode()) {
-            case AddRecovery:
-                switch (value.recoveryFormat()) {
-                case ValueFormatInt32:
-                    jit.add32(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                case ValueFormatInt52:
-                    jit.add64(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
-                }
-                break;
-            case SubRecovery:
-                switch (value.recoveryFormat()) {
-                case ValueFormatInt32:
-                    jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                case ValueFormatInt52:
-                    jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
+        Vector<ExitTimeObjectMaterialization*> worklist;
+        worklist.appendRange(toMaterialize.begin(), toMaterialize.end());
+        for (ExitTimeObjectMaterialization* materialization : worklist) {
+            // Check if we can do anything about this right now.
+            bool allGood = true;
+            for (ExitPropertyValue value : materialization->properties()) {
+                if (!value.value().isObjectMaterialization())
+                    continue;
+                if (toMaterialize.contains(value.value().objectMaterialization())) {
+                    // Gotta skip this one, since one of its fields points to a materialization
+                    // that hasn't been materialized.
+                    allGood = false;
                     break;
                 }
-                break;
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
             }
-            break;
+            if (!allGood)
+                continue;
             
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
+            // All systems go for materializing the object. First we recover the values of all of
+            // its fields and then we call a function to actually allocate the beast.
+            for (unsigned propertyIndex = materialization->properties().size(); propertyIndex--;) {
+                const ExitValue& value = materialization->properties()[propertyIndex].value();
+                compileRecovery(
+                    jit, value, record, jitCode->stackmaps, registerScratch,
+                    materializationToPointer);
+                jit.storePtr(GPRInfo::regT0, materializationArguments + propertyIndex);
+            }
+            
+            // This call assumes that we don't pass arguments on the stack.
+            jit.setupArgumentsWithExecState(
+                CCallHelpers::TrustedImmPtr(materialization),
+                CCallHelpers::TrustedImmPtr(materializationArguments));
+            jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(operationMaterializeObjectInOSR)), GPRInfo::nonArgGPR0);
+            jit.call(GPRInfo::nonArgGPR0);
+            jit.storePtr(GPRInfo::returnValueGPR, materializationToPointer.get(materialization));
+            
+            // Let everyone know that we're done.
+            toMaterialize.remove(materialization);
         }
         
+        // We expect progress! This ensures that we crash rather than looping infinitely if there
+        // is something broken about this fixpoint. Or, this could happen if we ever violate the
+        // "materializations form a DAG" rule.
+        RELEASE_ASSERT(toMaterialize.size() < previousToMaterializeSize);
+    }
+
+    // Save all state from wherever the exit data tells us it was, into the appropriate place in
+    // the scratch buffer. This also does the reboxing.
+    
+    for (unsigned index = exit.m_values.size(); index--;) {
+        compileRecovery(
+            jit, exit.m_values[index], record, jitCode->stackmaps, registerScratch,
+            materializationToPointer);
         jit.store64(GPRInfo::regT0, scratch + index);
     }
     
@@ -338,29 +432,17 @@ static void compileStub(
     
     arityReturnPCReady.link(&jit);
     
-    // Now get state out of the scratch buffer and place it back into the stack. This part does
-    // all reboxing.
+    // Now get state out of the scratch buffer and place it back into the stack. The values are
+    // already reboxed so we just move them.
     for (unsigned index = exit.m_values.size(); index--;) {
         int operand = exit.m_values.operandForIndex(index);
-        ExitValue value = exit.m_values[index];
         
         jit.load64(scratch + index, GPRInfo::regT0);
-        reboxAccordingToFormat(
-            value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
         jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(static_cast<VirtualRegister>(operand)));
     }
     
     handleExitCounts(jit, exit);
     reifyInlinedCallFrames(jit, exit);
-    
-    ArgumentsRecoveryGenerator argumentsRecovery;
-    for (unsigned index = exit.m_values.size(); index--;) {
-        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
-            continue;
-        int operand = exit.m_values.operandForIndex(index);
-        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
-    }
-    
     adjustAndJumpToTarget(jit, exit);
     
     LinkBuffer patchBuffer(*vm, jit, codeBlock);
@@ -395,6 +477,19 @@ extern "C" void* compileFTLOSRExit(ExecState* exec, unsigned exitID)
     JITCode* jitCode = codeBlock->jitCode()->ftl();
     OSRExit& exit = jitCode->osrExit[exitID];
     
+    if (shouldShowDisassembly() || Options::verboseOSR() || Options::verboseFTLOSRExit()) {
+        dataLog("    Owning block: ", pointerDump(codeBlock), "\n");
+        dataLog("    Origin: ", exit.m_codeOrigin, "\n");
+        if (exit.m_codeOriginForExitProfile != exit.m_codeOrigin)
+            dataLog("    Origin for exit profile: ", exit.m_codeOriginForExitProfile, "\n");
+        dataLog("    Exit values: ", exit.m_values, "\n");
+        if (!exit.m_materializations.isEmpty()) {
+            dataLog("    Materializations:\n");
+            for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+                dataLog("        ", pointerDump(materialization), "\n");
+        }
+    }
+
     prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
     
     compileStub(exitID, jitCode, exit, vm, codeBlock);
diff --git a/ftl/FTLOperations.cpp b/ftl/FTLOperations.cpp
new file mode 100644 (file)
index 0000000..4e5c8b3
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FTLOperations.h"
+
+#if ENABLE(FTL_JIT)
+
+#include "ClonedArguments.h"
+#include "DirectArguments.h"
+#include "JSCInlines.h"
+#include "JSLexicalEnvironment.h"
+
+namespace JSC { namespace FTL {
+
+using namespace JSC::DFG;
+
+extern "C" JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    
+    Butterfly* butterfly = Butterfly::create(
+        vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
+    
+    return JSFinalObject::create(exec, structure, butterfly);
+}
+
+extern "C" JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
+    ExecState* exec, ExitTimeObjectMaterialization* materialization, EncodedJSValue* values)
+{
+    VM& vm = exec->vm();
+    CodeBlock* codeBlock = exec->codeBlock();
+
+    // We cannot GC. We've got pointers in evil places.
+    DeferGCForAWhile deferGC(vm.heap);
+    
+    switch (materialization->type()) {
+    case PhantomNewObject: {
+        // First figure out what the structure is.
+        Structure* structure = nullptr;
+        for (unsigned i = materialization->properties().size(); i--;) {
+            const ExitPropertyValue& property = materialization->properties()[i];
+            if (property.location() != PromotedLocationDescriptor(StructurePLoc))
+                continue;
+        
+            structure = jsCast<Structure*>(JSValue::decode(values[i]));
+            break;
+        }
+        RELEASE_ASSERT(structure);
+    
+        // Let's create that object!
+        JSFinalObject* result = JSFinalObject::create(vm, structure);
+    
+        // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
+        // because that happens to be lower-level and more convenient. It doesn't change the
+        // materialization of the property table. We want to have minimal visible effects on the
+        // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
+        // exit.
+        for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != NamedPropertyPLoc)
+                    continue;
+                if (codeBlock->identifier(property.location().info()).impl() != entry.key)
+                    continue;
+            
+                result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
+            }
+        }
+    
+        return result;
+    }
+
+    case PhantomNewFunction: {
+        // Figure out what the executable and activation are
+        FunctionExecutable* executable = nullptr;
+        JSScope* activation = nullptr;
+        for (unsigned i = materialization->properties().size(); i--;) {
+            const ExitPropertyValue& property = materialization->properties()[i];
+            if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc))
+                executable = jsCast<FunctionExecutable*>(JSValue::decode(values[i]));
+            if (property.location() == PromotedLocationDescriptor(FunctionActivationPLoc))
+                activation = jsCast<JSScope*>(JSValue::decode(values[i]));
+        }
+        RELEASE_ASSERT(executable && activation);
+
+        JSFunction* result = JSFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation);
+
+        return result;
+    }
+
+    case PhantomCreateActivation: {
+        // Figure out where the scope is
+        JSScope* scope = nullptr;
+        SymbolTable* table = nullptr;
+        for (unsigned i = materialization->properties().size(); i--;) {
+            const ExitPropertyValue& property = materialization->properties()[i];
+            if (property.location() == PromotedLocationDescriptor(ActivationScopePLoc))
+                scope = jsCast<JSScope*>(JSValue::decode(values[i]));
+            else if (property.location() == PromotedLocationDescriptor(ActivationSymbolTablePLoc))
+                table = jsCast<SymbolTable*>(JSValue::decode(values[i]));
+        }
+        RELEASE_ASSERT(scope);
+        RELEASE_ASSERT(table);
+
+        CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(
+            materialization->origin(), exec->codeBlock());
+        Structure* structure = codeBlock->globalObject()->activationStructure();
+
+        JSLexicalEnvironment* result = JSLexicalEnvironment::create(vm, structure, scope, table);
+
+        RELEASE_ASSERT(materialization->properties().size() - 2 == table->scopeSize());
+        // Figure out what to populate the activation with
+        for (unsigned i = materialization->properties().size(); i--;) {
+            const ExitPropertyValue& property = materialization->properties()[i];
+            if (property.location().kind() != ClosureVarPLoc)
+                continue;
+
+            result->variableAt(ScopeOffset(property.location().info())).set(exec->vm(), result, JSValue::decode(values[i]));
+        }
+
+        if (validationEnabled()) {
+            // Validate to make sure every slot in the scope has one value.
+            ConcurrentJITLocker locker(table->m_lock);
+            for (auto iter = table->begin(locker), end = table->end(locker); iter != end; ++iter) {
+                bool found = false;
+                for (unsigned i = materialization->properties().size(); i--;) {
+                    const ExitPropertyValue& property = materialization->properties()[i];
+                    if (property.location().kind() != ClosureVarPLoc)
+                        continue;
+                    if (ScopeOffset(property.location().info()) == iter->value.scopeOffset()) {
+                        found = true;
+                        break;
+                    }
+                }
+                ASSERT_UNUSED(found, found);
+            }
+            unsigned numberOfClosureVarPloc = 0;
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() == ClosureVarPLoc)
+                    numberOfClosureVarPloc++;
+            }
+            ASSERT(numberOfClosureVarPloc == table->scopeSize());
+        }
+
+        return result;
+    }
+
+    case PhantomDirectArguments:
+    case PhantomClonedArguments: {
+        if (!materialization->origin().inlineCallFrame) {
+            switch (materialization->type()) {
+            case PhantomDirectArguments:
+                return DirectArguments::createByCopying(exec);
+            case PhantomClonedArguments:
+                return ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned);
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                return nullptr;
+            }
+        }
+
+        // First figure out the argument count. If there isn't one then we represent the machine frame.
+        unsigned argumentCount = 0;
+        if (materialization->origin().inlineCallFrame->isVarargs()) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location() != PromotedLocationDescriptor(ArgumentCountPLoc))
+                    continue;
+                
+                argumentCount = JSValue::decode(values[i]).asUInt32();
+                RELEASE_ASSERT(argumentCount);
+                break;
+            }
+            RELEASE_ASSERT(argumentCount);
+        } else
+            argumentCount = materialization->origin().inlineCallFrame->arguments.size();
+        
+        JSFunction* callee = nullptr;
+        if (materialization->origin().inlineCallFrame->isClosureCall) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location() != PromotedLocationDescriptor(ArgumentsCalleePLoc))
+                    continue;
+                
+                callee = jsCast<JSFunction*>(JSValue::decode(values[i]));
+                break;
+            }
+        } else
+            callee = materialization->origin().inlineCallFrame->calleeConstant();
+        RELEASE_ASSERT(callee);
+        
+        CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(
+            materialization->origin(), exec->codeBlock());
+        
+        // We have an inline frame and we have all of the data we need to recreate it.
+        switch (materialization->type()) {
+        case PhantomDirectArguments: {
+            unsigned length = argumentCount - 1;
+            unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
+            DirectArguments* result = DirectArguments::create(
+                vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
+            result->callee().set(vm, result, callee);
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != ArgumentPLoc)
+                    continue;
+                
+                unsigned index = property.location().info();
+                if (index >= capacity)
+                    continue;
+                
+                // We don't want to use setIndexQuickly(), since that's only for the passed-in
+                // arguments but sometimes the number of named arguments is greater. For
+                // example:
+                //
+                // function foo(a, b, c) { ... }
+                // foo();
+                //
+                // setIndexQuickly() would fail for indices 0, 1, 2 - but we need to recover
+                // those here.
+                result->argument(DirectArgumentsOffset(index)).set(
+                    vm, result, JSValue::decode(values[i]));
+            }
+            return result;
+        }
+        case PhantomClonedArguments: {
+            unsigned length = argumentCount - 1;
+            ClonedArguments* result = ClonedArguments::createEmpty(
+                vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
+            
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != ArgumentPLoc)
+                    continue;
+                
+                unsigned index = property.location().info();
+                if (index >= length)
+                    continue;
+                result->putDirectIndex(exec, index, JSValue::decode(values[i]));
+            }
+            
+            result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+            return result;
+        }
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return nullptr;
+        }
+    }
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
diff --git a/ftl/FTLOperations.h b/ftl/FTLOperations.h
new file mode 100644 (file)
index 0000000..d15f18e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLOperations_h
+#define FTLOperations_h
+
+#if ENABLE(FTL_JIT)
+
+#include "DFGOperations.h"
+#include "FTLExitTimeObjectMaterialization.h"
+
+namespace JSC { namespace FTL {
+
+extern "C" {
+
+JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure*) WTF_INTERNAL;
+
+JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
+    ExecState*, ExitTimeObjectMaterialization*, EncodedJSValue*) WTF_INTERNAL;
+
+} // extern "C"
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLOperations_h
+
index 986d3747dfa6954fc9b0ed5c7beb813123b7f7fb..30d5fbd507139d4921701b112c884ca923da1438 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -138,9 +138,16 @@ void Output::branch(LValue condition, LBasicBlock taken, Weight takenWeight, LBa
             constInt32(notTakenWeight.scaleToTotal(total))));
 }
 
-void Output::crashNonTerminal()
+void Output::check(LValue condition, WeightedTarget taken, Weight notTakenWeight)
 {
-    call(intToPtr(constIntPtr(abort), pointerType(functionType(voidType))));
+    LBasicBlock continuation = FTL_NEW_BLOCK(*this, ("Output::check continuation"));
+    branch(condition, taken, WeightedTarget(continuation, notTakenWeight));
+    appendTo(continuation);
+}
+
+void Output::check(LValue condition, WeightedTarget taken)
+{
+    check(condition, taken, taken.weight().inverse());
 }
 
 } } // namespace JSC::FTL
index f71b9c6a92329ec73b295c618b62b61e75da3102..e2d973d3c23150413a999639a00f913fccc06cc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -133,12 +133,20 @@ public:
     LValue bitOr(LValue left, LValue right) { return buildOr(m_builder, left, right); }
     LValue bitXor(LValue left, LValue right) { return buildXor(m_builder, left, right); }
     LValue shl(LValue left, LValue right) { return buildShl(m_builder, left, right); }
-    LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); }
-    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); }
+    LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); } // arithmetic = signed
+    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); } // logical = unsigned
     LValue bitNot(LValue value) { return buildNot(m_builder, value); }
     
     LValue insertElement(LValue vector, LValue element, LValue index) { return buildInsertElement(m_builder, vector, element, index); }
-    
+
+    LValue ceil64(LValue operand)
+    {
+        return call(ceil64Intrinsic(), operand);
+    }
+    LValue ctlz32(LValue xOperand, LValue yOperand)
+    {
+        return call(ctlz32Intrinsic(), xOperand, yOperand);
+    }
     LValue addWithOverflow32(LValue left, LValue right)
     {
         return call(addWithOverflow32Intrinsic(), left, right);
@@ -177,16 +185,32 @@ public:
         return call(doubleCosIntrinsic(), value);
     }
 
+    LValue doublePow(LValue xOperand, LValue yOperand)
+    {
+        return call(doublePowIntrinsic(), xOperand, yOperand);
+    }
+
+    LValue doublePowi(LValue xOperand, LValue yOperand)
+    {
+        return call(doublePowiIntrinsic(), xOperand, yOperand);
+    }
+
     LValue doubleSqrt(LValue value)
     {
         return call(doubleSqrtIntrinsic(), value);
     }
 
+    LValue doubleLog(LValue value)
+    {
+        return call(doubleLogIntrinsic(), value);
+    }
+
     static bool hasSensibleDoubleToInt() { return isX86(); }
     LValue sensibleDoubleToInt(LValue);
     
     LValue signExt(LValue value, LType type) { return buildSExt(m_builder, value, type); }
     LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
+    LValue zeroExtPtr(LValue value) { return zeroExt(value, intPtr); }
     LValue fpToInt(LValue value, LType type) { return buildFPToSI(m_builder, value, type); }
     LValue fpToUInt(LValue value, LType type) { return buildFPToUI(m_builder, value, type); }
     LValue fpToInt32(LValue value) { return fpToInt(value, int32); }
@@ -202,6 +226,8 @@ public:
     LValue ptrToInt(LValue value, LType type) { return buildPtrToInt(m_builder, value, type); }
     LValue bitCast(LValue value, LType type) { return buildBitCast(m_builder, value, type); }
     
+    // Hilariously, the #define machinery in the stdlib means that this method is actually called
+    // __builtin_alloca. So far this appears benign. :-|
     LValue alloca(LType type) { return buildAlloca(m_builder, type); }
     
     // Access the value of an alloca. Also used as a low-level implementation primitive for
@@ -347,13 +373,8 @@ public:
     LValue call(LValue function, const VectorType& vector) { return buildCall(m_builder, function, vector); }
     LValue call(LValue function) { return buildCall(m_builder, function); }
     LValue call(LValue function, LValue arg1) { return buildCall(m_builder, function, arg1); }
-    LValue call(LValue function, LValue arg1, LValue arg2) { return buildCall(m_builder, function, arg1, arg2); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3) { return buildCall(m_builder, function, arg1, arg2, arg3); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7); }
-    LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
+    template<typename... Args>
+    LValue call(LValue function, LValue arg1, Args... args) { return buildCall(m_builder, function, arg1, args...); }
     
     template<typename FunctionType>
     LValue operation(FunctionType function)
@@ -367,6 +388,13 @@ public:
     {
         branch(condition, taken.target(), taken.weight(), notTaken.target(), notTaken.weight());
     }
+
+    // Branches to an already-created handler if true, "falls through" if false. Fall-through is
+    // simulated by creating a continuation for you.
+    void check(LValue condition, WeightedTarget taken, Weight notTakenWeight);
+    
+    // Same as check(), but uses Weight::inverse() to compute the notTakenWeight.
+    void check(LValue condition, WeightedTarget taken);
     
     template<typename VectorType>
     void switchInstruction(LValue value, const VectorType& cases, LBasicBlock fallThrough, Weight fallThroughWeight)
@@ -401,14 +429,6 @@ public:
         call(trapIntrinsic());
     }
     
-    void crashNonTerminal();
-
-    void crash()
-    {
-        crashNonTerminal();
-        unreachable();
-    }
-    
     ValueFromBlock anchor(LValue value)
     {
         return ValueFromBlock(value, m_block);
index e48f8622fed9ce42f019b0a305ddfb2516d20314..ffbd474b622aa7e790c26eb1b8134a73d176af5d 100644 (file)
@@ -173,11 +173,24 @@ void storeCodeOrigin(State& state, CCallHelpers& jit, CodeOrigin codeOrigin)
         CCallHelpers::tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
 }
 
+MacroAssembler::Call callOperation(
+    State& state, const RegisterSet& usedRegisters, CCallHelpers& jit,
+    CodeOrigin codeOrigin, MacroAssembler::JumpList* exceptionTarget,
+    J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo,
+    GPRReg object, const UniquedStringImpl* uid)
+{
+    storeCodeOrigin(state, jit, codeOrigin);
+    CallContext context(state, usedRegisters, jit, 4, result);
+    jit.setupArgumentsWithExecState(
+        CCallHelpers::TrustedImmPtr(stubInfo), object, CCallHelpers::TrustedImmPtr(uid));
+    return context.makeCall(bitwise_cast<void*>(operation), exceptionTarget);
+}
+
 MacroAssembler::Call callOperation(
     State& state, const RegisterSet& usedRegisters, CCallHelpers& jit,
     CodeOrigin codeOrigin, MacroAssembler::JumpList* exceptionTarget,
     J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo,
-    GPRReg object, StringImpl* uid)
+    GPRReg object, UniquedStringImpl* uid)
 {
     storeCodeOrigin(state, jit, codeOrigin);
     CallContext context(state, usedRegisters, jit, 4, result);
@@ -191,7 +204,7 @@ MacroAssembler::Call callOperation(
     State& state, const RegisterSet& usedRegisters, CCallHelpers& jit, 
     CodeOrigin codeOrigin, MacroAssembler::JumpList* exceptionTarget,
     V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg value,
-    GPRReg object, StringImpl* uid)
+    GPRReg object, UniquedStringImpl* uid)
 {
     storeCodeOrigin(state, jit, codeOrigin);
     CallContext context(state, usedRegisters, jit, 5, InvalidGPRReg);
index 68e09e66b97ec40f49ff5f97b8c4881c74da331f..818ef6464c7b1cfaf6f5f92b0d01c0bd0e11b50d 100644 (file)
@@ -57,14 +57,18 @@ private:
 
 void storeCodeOrigin(State&, CCallHelpers&, CodeOrigin);
 
+MacroAssembler::Call callOperation(
+    State&, const RegisterSet&, CCallHelpers&, CodeOrigin, CCallHelpers::JumpList*,
+    J_JITOperation_ESsiCI, GPRReg, StructureStubInfo*, GPRReg,
+    const UniquedStringImpl* uid);
 MacroAssembler::Call callOperation(
     State&, const RegisterSet&, CCallHelpers&, CodeOrigin, CCallHelpers::JumpList*,
     J_JITOperation_ESsiJI, GPRReg result, StructureStubInfo*, GPRReg object,
-    StringImpl* uid);
+    UniquedStringImpl* uid);
 MacroAssembler::Call callOperation(
     State&, const RegisterSet&, CCallHelpers&, CodeOrigin, CCallHelpers::JumpList*,
     V_JITOperation_ESsiJJI, StructureStubInfo*, GPRReg value, GPRReg object,
-    StringImpl* uid);
+    UniquedStringImpl* uid);
 
 } } // namespace JSC::FTL
 
index 32944d6b433fb99db203e9d5be9bc34a1faaca28..038e9b11098f6436be5d98d092b70e00078859f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "FTLForOSREntryJITCode.h"
 #include "FTLJITCode.h"
 #include "FTLJITFinalizer.h"
+#include <llvm/InitializeLLVM.h>
+#include <stdio.h>
+
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+#include "InlineRuntimeSymbolTable.h"
+#endif
 
 namespace JSC { namespace FTL {
 
@@ -43,9 +49,21 @@ State::State(Graph& graph)
     , module(0)
     , function(0)
     , generatedFunction(0)
-    , compactUnwind(0)
-    , compactUnwindSize(0)
+    , handleStackOverflowExceptionStackmapID(UINT_MAX)
+    , handleExceptionStackmapID(UINT_MAX)
+    , capturedStackmapID(UINT_MAX)
+    , varargsSpillSlotsStackmapID(UINT_MAX)
+    , unwindDataSection(0)
+    , unwindDataSectionSize(0)
 {
+
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+#define SYMBOL_TABLE_ADD(symbol, file) \
+    symbolTable.fastAdd(symbol, file);
+    FOR_EACH_LIBRARY_SYMBOL(SYMBOL_TABLE_ADD)
+#undef SYMBOL_TABLE_ADD
+#endif
+    
     switch (graph.m_plan.mode) {
     case FTLMode: {
         jitCode = adoptRef(new JITCode());
@@ -62,9 +80,9 @@ State::State(Graph& graph)
         RELEASE_ASSERT_NOT_REACHED();
         break;
     }
-    
-    finalizer = new JITFinalizer(graph.m_plan);
-    graph.m_plan.finalizer = adoptPtr(finalizer);
+
+    graph.m_plan.finalizer = std::make_unique<JITFinalizer>(graph.m_plan);
+    finalizer = static_cast<JITFinalizer*>(graph.m_plan.finalizer.get());
 }
 
 State::~State()
@@ -73,6 +91,11 @@ State::~State()
 }
 
 void State::dumpState(const char* when)
+{
+    dumpState(module, when);
+}
+
+void State::dumpState(LModule module, const char* when)
 {
     dataLog("LLVM IR for ", CodeBlockWithJITType(graph.m_codeBlock, FTL::JITCode::FTLJIT), " ", when, ":\n");
     dumpModule(module);
index 5219e2957118abe3b4951c5010631ab411edbc61..8a0679b227a4366292a4a0956d9a2ff1a5b7ed65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
 #include "FTLJITCode.h"
 #include "FTLJITFinalizer.h"
 #include "FTLJSCall.h"
+#include "FTLJSCallVarargs.h"
 #include "FTLStackMaps.h"
 #include "FTLState.h"
 #include <wtf/Noncopyable.h>
@@ -65,22 +66,33 @@ public:
     LContext context;
     LModule module;
     LValue function;
+    bool allocationFailed { false }; // Throw out the compilation once LLVM returns.
     RefPtr<JITCode> jitCode;
     GeneratedFunction generatedFunction;
     JITFinalizer* finalizer;
     unsigned handleStackOverflowExceptionStackmapID;
     unsigned handleExceptionStackmapID;
     unsigned capturedStackmapID;
+    unsigned varargsSpillSlotsStackmapID;
     SegmentedVector<GetByIdDescriptor> getByIds;
     SegmentedVector<PutByIdDescriptor> putByIds;
+    SegmentedVector<CheckInDescriptor> checkIns;
     Vector<JSCall> jsCalls;
+    Vector<JSCallVarargs> jsCallVarargses;
     Vector<CString> codeSectionNames;
     Vector<CString> dataSectionNames;
-    void* compactUnwind;
-    size_t compactUnwindSize;
+    void* unwindDataSection;
+    size_t unwindDataSectionSize;
     RefPtr<DataSection> stackmapsSection;
     
     void dumpState(const char* when);
+    void dumpState(LModule, const char* when);
+
+    HashSet<CString> nativeLoadedLibraries;
+
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+    HashMap<CString, CString> symbolTable;
+#endif
 };
 
 } } // namespace JSC::FTL
index 123a4753a8e607a939e7e20b800ab9f596b2fc84..cd6bc078db56de23d1d6b8330fd096801ce33999 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,13 @@ namespace JSC { namespace FTL {
 
 class SwitchCase {
 public:
-    SwitchCase(LValue value, LBasicBlock target, Weight weight)
+    SwitchCase()
+        : m_value(nullptr)
+        , m_target(nullptr)
+    {
+    }
+
+    SwitchCase(LValue value, LBasicBlock target, Weight weight = Weight())
         : m_value(value)
         , m_target(target)
         , m_weight(weight)
index 98c18316d3ef9a1b3eefa2f338fe7ad4d99b917d..2867a7245e89bf4f134e0c0d53624052e38ddd27 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics
+ * Copyright (C) 2014 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ==============================================================================
+ *
+ * University of Illinois/NCSA
+ * Open Source License
+ *
+ * Copyright (c) 2009-2014 by the contributors of LLVM/libc++abi project.
+ *
+ * All rights reserved.
+ *
+ * Developed by:
+ *
+ *    LLVM Team
+ *
+ *    University of Illinois at Urbana-Champaign
+ *
+ *    http://llvm.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal with
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ *    * Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimers.
+ *
+ *    * Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimers in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ *    * Neither the names of the LLVM Team, University of Illinois at
+ *      Urbana-Champaign, nor the names of its contributors may be used to
+ *      endorse or promote products derived from this Software without specific
+ *      prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ * SOFTWARE.
+ *
+ * ==============================================================================
+ *
+ * Copyright (c) 2009-2014 by the contributors of LLVM/libc++abi project.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "config.h"
@@ -28,7 +96,9 @@
 
 #if ENABLE(FTL_JIT)
 
+#if OS(DARWIN)
 #include <mach-o/compact_unwind_encoding.h>
+#endif
 #include <wtf/ListDump.h>
 
 namespace JSC { namespace FTL {
@@ -36,8 +106,9 @@ namespace JSC { namespace FTL {
 UnwindInfo::UnwindInfo() { }
 UnwindInfo::~UnwindInfo() { }
 
-namespace {
 
+namespace {
+#if OS(DARWIN)
 struct CompactUnwind {
     void* function;
     uint32_t size;
@@ -45,17 +116,552 @@ struct CompactUnwind {
     void* personality;
     void* lsda;
 };
+#elif OS(LINUX)
+// DWARF unwind instructions
+enum {
+    DW_CFA_nop                 = 0x0,
+    DW_CFA_set_loc             = 0x1,
+    DW_CFA_advance_loc1        = 0x2,
+    DW_CFA_advance_loc2        = 0x3,
+    DW_CFA_advance_loc4        = 0x4,
+    DW_CFA_offset_extended     = 0x5,
+    DW_CFA_def_cfa             = 0xC,
+    DW_CFA_def_cfa_register    = 0xD,
+    DW_CFA_def_cfa_offset      = 0xE,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf         = 0x12,
+    DW_CFA_def_cfa_offset_sf  = 0x13,
+    // high 2 bits are 0x1, lower 6 bits are delta
+    DW_CFA_advance_loc        = 0x40,
+    // high 2 bits are 0x2, lower 6 bits are register
+    DW_CFA_offset             = 0x80
+};
+
+enum {
+    DW_CFA_operand_mask = 0x3F // low 6 bits mask for opcode-encoded operands in DW_CFA_advance_loc and DW_CFA_offset
+};
+
+// FSF exception handling Pointer-Encoding constants
+enum {
+    DW_EH_PE_ptr       = 0x00,
+    DW_EH_PE_uleb128   = 0x01,
+    DW_EH_PE_udata2    = 0x02,
+    DW_EH_PE_udata4    = 0x03,
+    DW_EH_PE_udata8    = 0x04,
+    DW_EH_PE_sleb128   = 0x09,
+    DW_EH_PE_sdata2    = 0x0A,
+    DW_EH_PE_sdata4    = 0x0B,
+    DW_EH_PE_sdata8    = 0x0C,
+    DW_EH_PE_absptr    = 0x00,
+    DW_EH_PE_pcrel     = 0x10,
+    DW_EH_PE_indirect  = 0x80
+};
+
+enum {
+    DW_EH_PE_relative_mask = 0x70
+};
+
+// 64-bit x86_64 registers
+enum {
+    UNW_X86_64_rbx =  3,
+    UNW_X86_64_rbp =  6,
+    UNW_X86_64_r12 = 12,
+    UNW_X86_64_r13 = 13,
+    UNW_X86_64_r14 = 14,
+    UNW_X86_64_r15 = 15
+};
+
+enum {
+    DW_X86_64_RET_addr = 16
+};
+
+enum {
+    UNW_ARM64_x0 = 0,
+    UNW_ARM64_x1 = 1,
+    UNW_ARM64_x2 = 2,
+    UNW_ARM64_x3 = 3,
+    UNW_ARM64_x4 = 4,
+    UNW_ARM64_x5 = 5,
+    UNW_ARM64_x6 = 6,
+    UNW_ARM64_x7 = 7,
+    UNW_ARM64_x8 = 8,
+    UNW_ARM64_x9 = 9,
+    UNW_ARM64_x10 = 10,
+    UNW_ARM64_x11 = 11,
+    UNW_ARM64_x12 = 12,
+    UNW_ARM64_x13 = 13,
+    UNW_ARM64_x14 = 14,
+    UNW_ARM64_x15 = 15,
+    UNW_ARM64_x16 = 16,
+    UNW_ARM64_x17 = 17,
+    UNW_ARM64_x18 = 18,
+    UNW_ARM64_x19 = 19,
+    UNW_ARM64_x20 = 20,
+    UNW_ARM64_x21 = 21,
+    UNW_ARM64_x22 = 22,
+    UNW_ARM64_x23 = 23,
+    UNW_ARM64_x24 = 24,
+    UNW_ARM64_x25 = 25,
+    UNW_ARM64_x26 = 26,
+    UNW_ARM64_x27 = 27,
+    UNW_ARM64_x28 = 28,
+    UNW_ARM64_fp = 29,
+    UNW_ARM64_x30 = 30,
+    UNW_ARM64_sp = 31,
+    UNW_ARM64_v0 = 64,
+    UNW_ARM64_v1 = 65,
+    UNW_ARM64_v2 = 66,
+    UNW_ARM64_v3 = 67,
+    UNW_ARM64_v4 = 68,
+    UNW_ARM64_v5 = 69,
+    UNW_ARM64_v6 = 70,
+    UNW_ARM64_v7 = 71,
+    UNW_ARM64_v8 = 72,
+    UNW_ARM64_v9 = 73,
+    UNW_ARM64_v10 = 74,
+    UNW_ARM64_v11 = 75,
+    UNW_ARM64_v12 = 76,
+    UNW_ARM64_v13 = 77,
+    UNW_ARM64_v14 = 78,
+    UNW_ARM64_v15 = 79,
+    UNW_ARM64_v16 = 80,
+    UNW_ARM64_v17 = 81,
+    UNW_ARM64_v18 = 82,
+    UNW_ARM64_v19 = 83,
+    UNW_ARM64_v20 = 84,
+    UNW_ARM64_v21 = 85,
+    UNW_ARM64_v22 = 86,
+    UNW_ARM64_v23 = 87,
+    UNW_ARM64_v24 = 88,
+    UNW_ARM64_v25 = 89,
+    UNW_ARM64_v26 = 90,
+    UNW_ARM64_v27 = 91,
+    UNW_ARM64_v28 = 92,
+    UNW_ARM64_v29 = 93,
+    UNW_ARM64_v30 = 94,
+    UNW_ARM64_v31 = 95
+};
+
+static uint8_t get8(uintptr_t addr)    { return *((uint8_t*)addr); }
+static uint16_t get16(uintptr_t addr)  { return *((uint16_t*)addr); }
+static uint32_t get32(uintptr_t addr)  { return *((uint32_t*)addr); }
+static uint64_t get64(uintptr_t addr)  { return *((uint64_t*)addr); }
+
+static uintptr_t getP(uintptr_t addr)
+{
+    // FIXME: add support for 32 bit pointers on 32 bit architectures
+    return get64(addr);
+}
+
+static uint64_t getULEB128(uintptr_t& addr, uintptr_t end)
+{
+    const uint8_t* p = (uint8_t*)addr;
+    const uint8_t* pend = (uint8_t*)end;
+    uint64_t result = 0;
+    int bit = 0;
+    do  {
+        uint64_t b;
+
+        RELEASE_ASSERT(p != pend); // truncated uleb128 expression
+
+        b = *p & 0x7f;
+
+        RELEASE_ASSERT(!(bit >= 64 || b << bit >> bit != b)); // malformed uleb128 expression
+
+        result |= b << bit;
+        bit += 7;
+    } while (*p++ >= 0x80);
+    addr = (uintptr_t)p;
+    return result;
+}
+
+static int64_t getSLEB128(uintptr_t& addr, uintptr_t end)
+{
+    const uint8_t* p = (uint8_t*)addr;
+    const uint8_t* pend = (uint8_t*)end;
+
+    int64_t result = 0;
+    int bit = 0;
+    uint8_t byte;
+    do {
+        RELEASE_ASSERT(p != pend); // truncated sleb128 expression
+
+        byte = *p++;
+        result |= ((byte & 0x7f) << bit);
+        bit += 7;
+    } while (byte & 0x80);
+    // sign extend negative numbers
+    if ((byte & 0x40))
+        result |= (-1LL) << bit;
+    addr = (uintptr_t)p;
+    return result;
+}
+
+static uintptr_t getEncodedP(uintptr_t& addr, uintptr_t end, uint8_t encoding)
+{
+    uintptr_t startAddr = addr;
+    const uint8_t* p = (uint8_t*)addr;
+    uintptr_t result;
+
+    // first get value
+    switch (encoding & 0x0F) {
+    case DW_EH_PE_ptr:
+        result = getP(addr);
+        p += sizeof(uintptr_t);
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_uleb128:
+        result = getULEB128(addr, end);
+        break;
+    case DW_EH_PE_udata2:
+        result = get16(addr);
+        p += 2;
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_udata4:
+        result = get32(addr);
+        p += 4;
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_udata8:
+        result = get64(addr);
+        p += 8;
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_sleb128:
+        result = getSLEB128(addr, end);
+        break;
+    case DW_EH_PE_sdata2:
+        result = (int16_t)get16(addr);
+        p += 2;
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_sdata4:
+        result = (int32_t)get32(addr);
+        p += 4;
+        addr = (uintptr_t)p;
+        break;
+    case DW_EH_PE_sdata8:
+        result = get64(addr);
+        p += 8;
+        addr = (uintptr_t)p;
+        break;
+    default:
+        RELEASE_ASSERT_NOT_REACHED(); // unknown pointer encoding
+    }
+
+    // then add relative offset
+    switch (encoding & DW_EH_PE_relative_mask) {
+    case DW_EH_PE_absptr:
+        // do nothing
+        break;
+    case DW_EH_PE_pcrel:
+        result += startAddr;
+        break;
+    default:
+        RELEASE_ASSERT_NOT_REACHED(); // unsupported or unknown pointer encoding
+    }
+
+    if (encoding & DW_EH_PE_indirect)
+        result = getP(result);
+
+    return result;
+}
+
+// Information encoded in a CIE (Common Information Entry)
+struct CIE_Info {
+    uintptr_t cieStart;
+    uintptr_t cieLength;
+    uintptr_t cieInstructions;
+    uint8_t pointerEncoding;
+    uint8_t lsdaEncoding;
+    uint8_t personalityEncoding;
+    uint8_t personalityOffsetInCIE;
+    uintptr_t personality;
+    int dataAlignFactor;
+    bool fdesHaveAugmentationData;
+};
+
+// Information about an FDE (Frame Description Entry)
+struct FDE_Info {
+    uintptr_t fdeStart;
+    uintptr_t fdeLength;
+    uintptr_t fdeInstructions;
+    uintptr_t lsda;
+};
+
+// Information about a frame layout and registers saved determined
+// by "running" the dwarf FDE "instructions"
+#if CPU(ARM64)
+enum { MaxRegisterNumber = 120 };
+#elif CPU(X86_64)
+enum { MaxRegisterNumber = 17 };
+#else
+#error "Unrecognized architecture"
+#endif
+
+struct RegisterLocation {
+    bool saved;
+    int64_t offset;
+};
 
+struct PrologInfo {
+    uint32_t cfaRegister;
+    int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
+    RegisterLocation savedRegisters[MaxRegisterNumber]; // from where to restore registers
+};
+
+static void parseCIE(uintptr_t cie, CIE_Info* cieInfo)
+{
+    cieInfo->pointerEncoding = 0;
+    cieInfo->lsdaEncoding = 0;
+    cieInfo->personalityEncoding = 0;
+    cieInfo->personalityOffsetInCIE = 0;
+    cieInfo->personality = 0;
+    cieInfo->dataAlignFactor = 0;
+    cieInfo->fdesHaveAugmentationData = false;
+    cieInfo->cieStart = cie;
+
+    uintptr_t p = cie;
+    uint64_t cieLength = get32(p);
+    p += 4;
+    uintptr_t cieContentEnd = p + cieLength;
+    if (cieLength == 0xffffffff) {
+        // 0xffffffff means length is really next 8 bytes
+        cieLength = get64(p);
+        p += 8;
+        cieContentEnd = p + cieLength;
+    }
+
+    RELEASE_ASSERT(cieLength);
+
+    // CIE ID is always 0
+    RELEASE_ASSERT(!get32(p)); // CIE ID is not zero
+    p += 4;
+    // Version is always 1 or 3
+    uint8_t version = get8(p);
+    RELEASE_ASSERT((version == 1) || (version == 3)); // CIE version is not 1 or 3
+
+    ++p;
+    // save start of augmentation string and find end
+    uintptr_t strStart = p;
+    while (get8(p))
+        ++p;
+    ++p;
+    // parse code aligment factor
+    getULEB128(p, cieContentEnd);
+    // parse data alignment factor
+    cieInfo->dataAlignFactor = getSLEB128(p, cieContentEnd);
+    // parse return address register
+    getULEB128(p, cieContentEnd);
+    // parse augmentation data based on augmentation string
+    if (get8(strStart) == 'z') {
+        // parse augmentation data length
+        getULEB128(p, cieContentEnd);
+        for (uintptr_t s = strStart; get8(s) != '\0'; ++s) {
+            switch (get8(s)) {
+            case 'z':
+                cieInfo->fdesHaveAugmentationData = true;
+                break;
+            case 'P': // FIXME: should assert on personality (just to keep in sync with the CU behaviour)
+                cieInfo->personalityEncoding = get8(p);
+                ++p;
+                cieInfo->personalityOffsetInCIE = p - cie;
+                cieInfo->personality = getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding);
+                break;
+            case 'L': // FIXME: should assert on LSDA (just to keep in sync with the CU behaviour)
+                cieInfo->lsdaEncoding = get8(p);
+                ++p;
+                break;
+            case 'R':
+                cieInfo->pointerEncoding = get8(p);
+                ++p;
+                break;
+            default:
+                // ignore unknown letters
+                break;
+            }
+        }
+    }
+    cieInfo->cieLength = cieContentEnd - cieInfo->cieStart;
+    cieInfo->cieInstructions = p;
+}
+
+static void findFDE(uintptr_t pc, uintptr_t ehSectionStart, uint32_t sectionLength, FDE_Info* fdeInfo, CIE_Info* cieInfo)
+{
+    uintptr_t p = ehSectionStart;
+    const uintptr_t ehSectionEnd = p + sectionLength;
+    while (p < ehSectionEnd) {
+        uintptr_t currentCFI = p;
+        uint64_t cfiLength = get32(p);
+        p += 4;
+        if (cfiLength == 0xffffffff) {
+            // 0xffffffff means length is really next 8 bytes
+            cfiLength = get64(p);
+            p += 8;
+        }
+        RELEASE_ASSERT(cfiLength); // end marker reached before finding FDE for pc
+
+        uint32_t id = get32(p);
+        if (!id) {
+            // skip over CIEs
+            p += cfiLength;
+        } else {
+            // process FDE to see if it covers pc
+            uintptr_t nextCFI = p + cfiLength;
+            uint32_t ciePointer = get32(p);
+            uintptr_t cieStart = p - ciePointer;
+            // validate pointer to CIE is within section
+            RELEASE_ASSERT((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)); // malformed FDE. CIE is bad
+
+            parseCIE(cieStart, cieInfo);
+
+            p += 4;
+            // parse pc begin and range
+            uintptr_t pcStart = getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
+            uintptr_t pcRange = getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F);
+
+            // test if pc is within the function this FDE covers
+            // if pc is not in begin/range, skip this FDE
+            if ((pcStart <= pc) && (pc < pcStart+pcRange)) {
+                // parse rest of info
+                fdeInfo->lsda = 0;
+                // check for augmentation length
+                if (cieInfo->fdesHaveAugmentationData) {
+                    uintptr_t augLen = getULEB128(p, nextCFI);
+                    uintptr_t endOfAug = p + augLen;
+                    if (cieInfo->lsdaEncoding) {
+                        // peek at value (without indirection). Zero means no lsda
+                        uintptr_t lsdaStart = p;
+                        if (getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F)) {
+                            // reset pointer and re-parse lsda address
+                            p = lsdaStart;
+                            fdeInfo->lsda = getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
+                        }
+                    }
+                    p = endOfAug;
+                }
+                fdeInfo->fdeStart = currentCFI;
+                fdeInfo->fdeLength = nextCFI - currentCFI;
+                fdeInfo->fdeInstructions = p;
+
+                return; // FDE found
+            }
+
+            p = nextCFI;
+        }
+    }
+
+    RELEASE_ASSERT_NOT_REACHED(); // no FDE found for pc
+}
+
+static void executeDefCFARegister(uint64_t reg, PrologInfo* results)
+{
+    RELEASE_ASSERT(reg <= MaxRegisterNumber); // reg too big
+    results->cfaRegister = reg;
+}
+
+static void executeDefCFAOffset(int64_t offset, PrologInfo* results)
+{
+    RELEASE_ASSERT(offset <= 0x80000000); // cfa has negative offset (dwarf might contain epilog)
+    results->cfaRegisterOffset = offset;
+}
+
+static void executeOffset(uint64_t reg, int64_t offset, PrologInfo *results)
+{
+    if (reg > MaxRegisterNumber)
+        return;
+
+    RELEASE_ASSERT(!results->savedRegisters[reg].saved);
+    results->savedRegisters[reg].saved = true;
+    results->savedRegisters[reg].offset = offset;
+}
+
+static void parseInstructions(uintptr_t instructions, uintptr_t instructionsEnd, const CIE_Info& cieInfo, PrologInfo* results)
+{
+    uintptr_t p = instructions;
+
+    // see Dwarf Spec, section 6.4.2 for details on unwind opcodes
+    while ((p < instructionsEnd)) {
+        uint64_t reg;
+        uint8_t opcode = get8(p);
+        uint8_t operand;
+        ++p;
+        switch (opcode) {
+        case DW_CFA_nop:
+            break;
+        case DW_CFA_set_loc:
+            getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);
+            break;
+        case DW_CFA_advance_loc1:
+            p += 1;
+            break;
+        case DW_CFA_advance_loc2:
+            p += 2;
+            break;
+        case DW_CFA_advance_loc4:
+            p += 4;
+            break;
+        case DW_CFA_def_cfa:
+            executeDefCFARegister(getULEB128(p, instructionsEnd), results);
+            executeDefCFAOffset(getULEB128(p, instructionsEnd), results);
+            break;
+        case DW_CFA_def_cfa_sf:
+            executeDefCFARegister(getULEB128(p, instructionsEnd), results);
+            executeDefCFAOffset(getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results);
+            break;
+        case DW_CFA_def_cfa_register:
+            executeDefCFARegister(getULEB128(p, instructionsEnd), results);
+            break;
+        case DW_CFA_def_cfa_offset:
+            executeDefCFAOffset(getULEB128(p, instructionsEnd), results);
+            break;
+        case DW_CFA_def_cfa_offset_sf:
+            executeDefCFAOffset(getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results);
+            break;
+        case DW_CFA_offset_extended:
+            reg = getULEB128(p, instructionsEnd);
+            executeOffset(reg, getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results);
+            break;
+        case DW_CFA_offset_extended_sf:
+            reg = getULEB128(p, instructionsEnd);
+            executeOffset(reg, getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results);
+            break;
+        default:
+            operand = opcode & DW_CFA_operand_mask;
+            switch (opcode & ~DW_CFA_operand_mask) {
+            case DW_CFA_offset:
+                executeOffset(operand, getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results);
+                break;
+            case DW_CFA_advance_loc:
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED(); // unknown or unsupported CFA opcode
+            }
+        }
+    }
+}
+
+static void parseFDEInstructions(const FDE_Info& fdeInfo, const CIE_Info& cieInfo, PrologInfo* results)
+{
+    // clear results
+    bzero(results, sizeof(PrologInfo));
+
+    // parse CIE then FDE instructions
+    parseInstructions(cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength, cieInfo, results);
+    parseInstructions(fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo, results);
+}
+#endif
 } // anonymous namespace
 
 bool UnwindInfo::parse(void* section, size_t size, GeneratedFunction generatedFunction)
 {
     m_registers.clear();
-    
-    RELEASE_ASSERT(!!section == !!size);
+    RELEASE_ASSERT(!!section);
     if (!section)
         return false;
-    
+
+#if OS(DARWIN)
     RELEASE_ASSERT(size >= sizeof(CompactUnwind));
     
     CompactUnwind* data = bitwise_cast<CompactUnwind*>(section);
@@ -157,7 +763,260 @@ bool UnwindInfo::parse(void* section, size_t size, GeneratedFunction generatedFu
 #else
 #error "Unrecognized architecture"
 #endif
-    
+
+#elif OS(LINUX)
+    FDE_Info fdeInfo;
+    CIE_Info cieInfo;
+    PrologInfo prolog;
+
+    findFDE((uintptr_t)generatedFunction, (uintptr_t)section, size, &fdeInfo, &cieInfo);
+    parseFDEInstructions(fdeInfo, cieInfo, &prolog);
+
+#if CPU(X86_64)
+    RELEASE_ASSERT(prolog.cfaRegister == UNW_X86_64_rbp);
+    RELEASE_ASSERT(prolog.cfaRegisterOffset == 16);
+    RELEASE_ASSERT(prolog.savedRegisters[UNW_X86_64_rbp].saved);
+    RELEASE_ASSERT(prolog.savedRegisters[UNW_X86_64_rbp].offset == -prolog.cfaRegisterOffset);
+
+    for (int i = 0; i < MaxRegisterNumber; ++i) {
+        if (prolog.savedRegisters[i].saved) {
+            switch (i) {
+            case UNW_X86_64_rbx:
+                m_registers.append(RegisterAtOffset(X86Registers::ebx, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_X86_64_r12:
+                m_registers.append(RegisterAtOffset(X86Registers::r12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_X86_64_r13:
+                m_registers.append(RegisterAtOffset(X86Registers::r13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_X86_64_r14:
+                m_registers.append(RegisterAtOffset(X86Registers::r14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_X86_64_r15:
+                m_registers.append(RegisterAtOffset(X86Registers::r15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_X86_64_rbp:
+                m_registers.append(RegisterAtOffset(X86Registers::ebp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case DW_X86_64_RET_addr:
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED(); // non-standard register being saved in prolog
+            }
+        }
+    }
+#elif CPU(ARM64)
+    RELEASE_ASSERT(prolog.cfaRegister == UNW_ARM64_fp);
+    RELEASE_ASSERT(prolog.cfaRegisterOffset == 16);
+    RELEASE_ASSERT(prolog.savedRegisters[UNW_ARM64_fp].saved);
+    RELEASE_ASSERT(prolog.savedRegisters[UNW_ARM64_fp].offset == -prolog.cfaRegisterOffset);
+
+    for (int i = 0; i < MaxRegisterNumber; ++i) {
+        if (prolog.savedRegisters[i].saved) {
+            switch (i) {
+            case UNW_ARM64_x0:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x1:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x2:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x3:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x4:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x5:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x6:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x7:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x8:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x9:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x10:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x11:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x12:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x13:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x14:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x15:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x16:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x17:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x18:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x19:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x20:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x21:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x22:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x23:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x24:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x25:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x26:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x27:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x28:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_fp:
+                m_registers.append(RegisterAtOffset(ARM64Registers::fp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_x30:
+                m_registers.append(RegisterAtOffset(ARM64Registers::x30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_sp:
+                m_registers.append(RegisterAtOffset(ARM64Registers::sp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v0:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q0, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v1:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q1, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v2:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q2, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v3:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q3, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v4:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q4, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v5:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q5, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v6:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q6, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v7:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q7, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v8:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q8, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v9:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q9, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v10:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q10, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v11:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q11, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v12:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v13:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v14:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v15:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v16:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q16, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v17:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q17, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v18:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q18, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v19:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q19, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v20:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q20, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v21:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q21, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v22:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q22, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v23:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q23, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v24:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q24, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v25:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q25, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v26:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q26, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v27:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q27, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v28:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q28, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v29:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q29, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v30:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q30, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            case UNW_ARM64_v31:
+                m_registers.append(RegisterAtOffset(ARM64Registers::q31, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset));
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED(); // non-standard register being saved in prolog
+            }
+        }
+    }
+#else
+#error "Unrecognized architecture"
+#endif
+
+#endif
     std::sort(m_registers.begin(), m_registers.end());
     return true;
 }
index a4e7abd167198b58f4368f493abe5c8d19ce57ce..6d2bf63c6856d4a608aac176941074b15d8d4983 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics
+ * Copyright (C) 2014 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index 9b50681913abca29e8c3cc4a7cdb306491c7e5bf..34eb37c914aa196d4d232c60ddc6306f68ac2a40 100644 (file)
@@ -62,6 +62,16 @@ public:
         return static_cast<unsigned>(result);
     }
     
+    // Inverse weight for a two-target branch.
+    Weight inverse() const
+    {
+        if (!isSet())
+            return Weight();
+        if (value())
+            return Weight(0);
+        return Weight(1);
+    }
+    
 private:
     float m_value;
 };
index 613a207b133b84757fee7129a5081bad60cd1c05..446b4971ee24442e5594777e3146bc8d50b7cf89 100644 (file)
@@ -22,6 +22,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import argparse
 import filecmp
 import fnmatch
 import os
@@ -31,6 +32,12 @@ import sys
 import datetime
 import json
 
+parser = argparse.ArgumentParser()
+parser.add_argument('input_file', nargs='*', help='Input JS files which builtins generated from')
+parser.add_argument('--input-directory', help='All JS files will be used as input from this directory.')
+parser.add_argument('--output', help='path to output cpp or h file')
+args = parser.parse_args()
+
 copyrightText = """ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,7 +66,7 @@ generatorString = "/* Generated by %s do not hand edit. */\n" % os.path.basename
 
 functionHeadRegExp = re.compile(r"function\s+\w+\s*\(.*?\)", re.MULTILINE | re.S)
 functionNameRegExp = re.compile(r"function\s+(\w+)\s*\(", re.MULTILINE | re.S)
-functionParameterFinder = re.compile(r"^function\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\)", re.MULTILINE | re.S)
+functionParameterFinder = re.compile(r"^function\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\s*\)", re.MULTILINE | re.S)
 
 multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.S)
 singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.S)
@@ -151,13 +158,14 @@ def mangleName(object, name):
     return mangledName
 
 builtins = []
+copyrights = []
+(output_base, _) = os.path.splitext(args.output)
 
-baseName = sys.argv[-1]
-builtin_definitions = sys.argv[1:-1]
-(output_base, _) = os.path.splitext(sys.argv[-1])
+if args.input_directory:
+    for file in os.listdir(args.input_directory):
+        args.input_file.append(os.path.join(args.input_directory, file))
 
-copyrights = []
-for file in builtin_definitions:
+for file in args.input_file:
     if fnmatch.fnmatch(file, '*.js'):
         (baseName, functions, objectCopyrights) = generateCode(file)
         copyrights.extend(objectCopyrights)
@@ -264,24 +272,10 @@ for (codeReference, name, source) in codeReferences:
     builtinsImplementation.write("const int s_%sLength = %d;\n\n" % (codeReference, sourceLength + 1)) # + 1 for \n
 
 builtinsImplementation.write("""
-FunctionExecutable* createBuiltinExecutable(VM& vm, UnlinkedFunctionExecutable* unlinkedExecutable, const SourceCode& source)
-{
-    unsigned lineCount = unlinkedExecutable->lineCount();
-    unsigned startColumn = 1;
-    unsigned sourceLength = unlinkedExecutable->sourceLength();
-    bool endColumnIsOnStartLine = !lineCount;
-    unsigned endColumnExcludingBraces = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? 0 : 1);
-    unsigned startOffset = unlinkedExecutable->startOffset();
-    unsigned startOffsetExcludingOpenBrace = startOffset + 1;
-    unsigned endOffsetExcludingCloseBrace = startOffset + sourceLength - 1;
-    SourceCode bodySource(source.provider(), startOffsetExcludingOpenBrace, endOffsetExcludingCloseBrace, 0, startColumn);
-    return FunctionExecutable::create(vm, bodySource, unlinkedExecutable, 0, lineCount, startColumn, endColumnExcludingBraces, false);
-}
-
 #define JSC_DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\
 FunctionExecutable* codeName##Generator(VM& vm) \\
 { \\
-    return createBuiltinExecutable(vm, vm.builtinExecutables()->codeName##Executable(), vm.builtinExecutables()->codeName##Source()); \\
+    return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source()); \\
 }
 
 JSC_FOREACH_BUILTIN(JSC_DEFINE_BUILTIN_GENERATOR)
@@ -294,11 +288,15 @@ builtinsHeader.close()
 builtinsImplementation.close()
 
 if (not os.path.exists(output_base + ".h")) or (not filecmp.cmp(output_base + ".h.tmp", output_base + ".h", shallow=False)):
+    if (os.path.exists(output_base + ".h")):
+        os.remove(output_base + ".h")
     os.rename(output_base + ".h.tmp", output_base + ".h")
 else:
     os.remove(output_base + ".h.tmp")
 
 if (not os.path.exists(output_base + ".cpp")) or (not filecmp.cmp(output_base + ".cpp.tmp", output_base + ".cpp", shallow=False)):
+    if (os.path.exists(output_base + ".cpp")):
+        os.remove(output_base + ".cpp")
     os.rename(output_base + ".cpp.tmp", output_base + ".cpp")
 else:
     os.remove(output_base + ".cpp.tmp")
diff --git a/heap/BlockAllocator.cpp b/heap/BlockAllocator.cpp
deleted file mode 100644 (file)
index bf408f8..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "BlockAllocator.h"
-
-#include "CopiedBlock.h"
-#include "CopyWorkList.h"
-#include "MarkedBlock.h"
-#include "JSCInlines.h"
-#include "WeakBlock.h"
-#include <wtf/CurrentTime.h>
-
-namespace JSC {
-
-inline ThreadIdentifier createBlockFreeingThread(BlockAllocator* allocator)
-{
-    if (!GCActivityCallback::s_shouldCreateGCTimer)
-        return 0; // No block freeing thread.
-    ThreadIdentifier identifier = createThread(allocator->blockFreeingThreadStartFunc, allocator, "JavaScriptCore::BlockFree");
-    RELEASE_ASSERT(identifier);
-    return identifier;
-}
-
-BlockAllocator::BlockAllocator()
-    : m_superRegion()
-    , m_copiedRegionSet(CopiedBlock::blockSize)
-    , m_markedRegionSet(MarkedBlock::blockSize)
-    , m_fourKBBlockRegionSet(WeakBlock::blockSize)
-    , m_workListRegionSet(CopyWorkListSegment::blockSize)
-    , m_numberOfEmptyRegions(0)
-    , m_isCurrentlyAllocating(false)
-    , m_blockFreeingThreadShouldQuit(false)
-    , m_blockFreeingThread(createBlockFreeingThread(this))
-{
-    m_regionLock.Init();
-}
-
-BlockAllocator::~BlockAllocator()
-{
-    releaseFreeRegions();
-    {
-        std::lock_guard<std::mutex> lock(m_emptyRegionConditionMutex);
-        m_blockFreeingThreadShouldQuit = true;
-        m_emptyRegionCondition.notify_all();
-    }
-    if (m_blockFreeingThread)
-        waitForThreadCompletion(m_blockFreeingThread);
-    ASSERT(allRegionSetsAreEmpty());
-    ASSERT(m_emptyRegions.isEmpty());
-}
-
-bool BlockAllocator::allRegionSetsAreEmpty() const
-{
-    return m_copiedRegionSet.isEmpty()
-        && m_markedRegionSet.isEmpty()
-        && m_fourKBBlockRegionSet.isEmpty()
-        && m_workListRegionSet.isEmpty();
-}
-
-void BlockAllocator::releaseFreeRegions()
-{
-    while (true) {
-        Region* region;
-        {
-            SpinLockHolder locker(&m_regionLock);
-            if (!m_numberOfEmptyRegions)
-                region = 0;
-            else {
-                region = m_emptyRegions.removeHead();
-                RELEASE_ASSERT(region);
-                m_numberOfEmptyRegions--;
-            }
-        }
-        
-        if (!region)
-            break;
-
-        region->destroy();
-    }
-}
-
-void BlockAllocator::waitForDuration(std::chrono::milliseconds duration)
-{
-    std::unique_lock<std::mutex> lock(m_emptyRegionConditionMutex);
-
-    // If this returns early, that's fine, so long as it doesn't do it too
-    // frequently. It would only be a bug if this function failed to return
-    // when it was asked to do so.
-    if (m_blockFreeingThreadShouldQuit)
-        return;
-
-    m_emptyRegionCondition.wait_for(lock, duration);
-}
-
-void BlockAllocator::blockFreeingThreadStartFunc(void* blockAllocator)
-{
-    static_cast<BlockAllocator*>(blockAllocator)->blockFreeingThreadMain();
-}
-
-void BlockAllocator::blockFreeingThreadMain()
-{
-    size_t currentNumberOfEmptyRegions;
-    while (!m_blockFreeingThreadShouldQuit) {
-        // Generally wait for one second before scavenging free blocks. This
-        // may return early, particularly when we're being asked to quit.
-        waitForDuration(std::chrono::seconds(1));
-        if (m_blockFreeingThreadShouldQuit)
-            break;
-        
-        if (m_isCurrentlyAllocating) {
-            m_isCurrentlyAllocating = false;
-            continue;
-        }
-
-        // Sleep until there is actually work to do rather than waking up every second to check.
-        {
-            std::unique_lock<std::mutex> lock(m_emptyRegionConditionMutex);
-            SpinLockHolder regionLocker(&m_regionLock);
-            while (!m_numberOfEmptyRegions && !m_blockFreeingThreadShouldQuit) {
-                m_regionLock.Unlock();
-                m_emptyRegionCondition.wait(lock);
-                m_regionLock.Lock();
-            }
-            currentNumberOfEmptyRegions = m_numberOfEmptyRegions;
-        }
-        
-        size_t desiredNumberOfEmptyRegions = currentNumberOfEmptyRegions / 2;
-        
-        while (!m_blockFreeingThreadShouldQuit) {
-            Region* region;
-            {
-                SpinLockHolder locker(&m_regionLock);
-                if (m_numberOfEmptyRegions <= desiredNumberOfEmptyRegions)
-                    region = 0;
-                else {
-                    region = m_emptyRegions.removeHead();
-                    RELEASE_ASSERT(region);
-                    m_numberOfEmptyRegions--;
-                }
-            }
-            
-            if (!region)
-                break;
-            
-            region->destroy();
-        }
-    }
-}
-
-} // namespace JSC
diff --git a/heap/BlockAllocator.h b/heap/BlockAllocator.h
deleted file mode 100644 (file)
index eb6867f..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BlockAllocator_h
-#define BlockAllocator_h
-
-#include "GCActivityCallback.h"
-#include "HeapBlock.h"
-#include "Region.h"
-#include <condition_variable>
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/Forward.h>
-#include <wtf/PageAllocationAligned.h>
-#include <wtf/TCSpinLock.h>
-#include <wtf/Threading.h>
-
-namespace JSC {
-
-class BlockAllocator;
-class CodeBlock;
-class CopiedBlock;
-class CopyWorkListSegment;
-template <typename T> class GCArraySegment;
-class HandleBlock;
-class JSCell;
-class VM;
-class MarkedBlock;
-class WeakBlock;
-
-// Simple allocator to reduce VM cost by holding onto blocks of memory for
-// short periods of time and then freeing them on a secondary thread.
-
-class BlockAllocator {
-public:
-    BlockAllocator();
-    ~BlockAllocator();
-
-    template <typename T> DeadBlock* allocate();
-    DeadBlock* allocateCustomSize(size_t blockSize, size_t blockAlignment);
-    template <typename T> void deallocate(T*);
-    template <typename T> void deallocateCustomSize(T*);
-
-    JS_EXPORT_PRIVATE void releaseFreeRegions();
-
-private:
-    void waitForDuration(std::chrono::milliseconds);
-
-    friend ThreadIdentifier createBlockFreeingThread(BlockAllocator*);
-    void blockFreeingThreadMain();
-    static void blockFreeingThreadStartFunc(void* heap);
-
-    struct RegionSet {
-        RegionSet(size_t blockSize)
-            : m_numberOfPartialRegions(0)
-            , m_blockSize(blockSize)
-        {
-        }
-
-        bool isEmpty() const
-        {
-            return m_fullRegions.isEmpty() && m_partialRegions.isEmpty();
-        }
-
-        DoublyLinkedList<Region> m_fullRegions;
-        DoublyLinkedList<Region> m_partialRegions;
-        size_t m_numberOfPartialRegions;
-        size_t m_blockSize;
-    };
-
-    DeadBlock* tryAllocateFromRegion(RegionSet&, DoublyLinkedList<Region>&, size_t&);
-
-    bool allRegionSetsAreEmpty() const;
-
-    template <typename T> RegionSet& regionSetFor();
-
-    SuperRegion m_superRegion;
-    RegionSet m_copiedRegionSet;
-    RegionSet m_markedRegionSet;
-    // WeakBlocks and GCArraySegments use the same RegionSet since they're the same size.
-    RegionSet m_fourKBBlockRegionSet;
-    RegionSet m_workListRegionSet;
-
-    DoublyLinkedList<Region> m_emptyRegions;
-    size_t m_numberOfEmptyRegions;
-
-    bool m_isCurrentlyAllocating;
-    bool m_blockFreeingThreadShouldQuit;
-    SpinLock m_regionLock;
-    std::mutex m_emptyRegionConditionMutex;
-    std::condition_variable m_emptyRegionCondition;
-    ThreadIdentifier m_blockFreeingThread;
-};
-
-inline DeadBlock* BlockAllocator::tryAllocateFromRegion(RegionSet& set, DoublyLinkedList<Region>& regions, size_t& numberOfRegions)
-{
-    if (numberOfRegions) {
-        ASSERT(!regions.isEmpty());
-        Region* region = regions.head();
-        ASSERT(!region->isFull());
-
-        if (region->isEmpty()) {
-            ASSERT(region == m_emptyRegions.head());
-            m_numberOfEmptyRegions--;
-            set.m_numberOfPartialRegions++;
-            region = m_emptyRegions.removeHead()->reset(set.m_blockSize);
-            set.m_partialRegions.push(region);
-        }
-
-        DeadBlock* block = region->allocate();
-
-        if (region->isFull()) {
-            set.m_numberOfPartialRegions--;
-            set.m_fullRegions.push(set.m_partialRegions.removeHead());
-        }
-
-        return block;
-    }
-    return 0;
-}
-
-template<typename T>
-inline DeadBlock* BlockAllocator::allocate()
-{
-    RegionSet& set = regionSetFor<T>();
-    DeadBlock* block;
-    m_isCurrentlyAllocating = true;
-    {
-        SpinLockHolder locker(&m_regionLock);
-        if ((block = tryAllocateFromRegion(set, set.m_partialRegions, set.m_numberOfPartialRegions)))
-            return block;
-        if ((block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions)))
-            return block;
-    }
-
-    Region* newRegion = Region::create(&m_superRegion, T::blockSize);
-
-    SpinLockHolder locker(&m_regionLock);
-    m_emptyRegions.push(newRegion);
-    m_numberOfEmptyRegions++;
-    block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions);
-    ASSERT(block);
-    return block;
-}
-
-inline DeadBlock* BlockAllocator::allocateCustomSize(size_t blockSize, size_t blockAlignment)
-{
-    size_t realSize = WTF::roundUpToMultipleOf(blockAlignment, blockSize);
-    Region* newRegion = Region::createCustomSize(&m_superRegion, realSize, blockAlignment);
-    DeadBlock* block = newRegion->allocate();
-    ASSERT(block);
-    return block;
-}
-
-template<typename T>
-inline void BlockAllocator::deallocate(T* block)
-{
-    RegionSet& set = regionSetFor<T>();
-    bool shouldWakeBlockFreeingThread = false;
-    {
-        SpinLockHolder locker(&m_regionLock);
-        Region* region = block->region();
-        ASSERT(!region->isEmpty());
-        if (region->isFull())
-            set.m_fullRegions.remove(region);
-        else {
-            set.m_partialRegions.remove(region);
-            set.m_numberOfPartialRegions--;
-        }
-
-        region->deallocate(block);
-
-        if (region->isEmpty()) {
-            m_emptyRegions.push(region);
-            shouldWakeBlockFreeingThread = !m_numberOfEmptyRegions;
-            m_numberOfEmptyRegions++;
-        } else {
-            set.m_partialRegions.push(region);
-            set.m_numberOfPartialRegions++;
-        }
-    }
-
-    if (shouldWakeBlockFreeingThread) {
-        std::lock_guard<std::mutex> lock(m_emptyRegionConditionMutex);
-        m_emptyRegionCondition.notify_one();
-    }
-
-    if (!m_blockFreeingThread)
-        releaseFreeRegions();
-}
-
-template<typename T>
-inline void BlockAllocator::deallocateCustomSize(T* block)
-{
-    Region* region = block->region();
-    ASSERT(region->isCustomSize());
-    region->deallocate(block);
-    region->destroy();
-}
-
-#define REGION_SET_FOR(blockType, set) \
-    template <> \
-    inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<blockType>() \
-    { \
-        return set; \
-    } \
-    template <> \
-    inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<blockType>>() \
-    { \
-        return set; \
-    } \
-
-REGION_SET_FOR(MarkedBlock, m_markedRegionSet);
-REGION_SET_FOR(CopiedBlock, m_copiedRegionSet);
-REGION_SET_FOR(WeakBlock, m_fourKBBlockRegionSet);
-REGION_SET_FOR(GCArraySegment<const JSCell*>, m_fourKBBlockRegionSet);
-REGION_SET_FOR(GCArraySegment<CodeBlock*>, m_fourKBBlockRegionSet);
-REGION_SET_FOR(CopyWorkListSegment, m_workListRegionSet);
-REGION_SET_FOR(HandleBlock, m_fourKBBlockRegionSet);
-
-#undef REGION_SET_FOR
-
-template <typename T>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor()
-{
-    RELEASE_ASSERT_NOT_REACHED();
-    return *(RegionSet*)0;
-}
-
-} // namespace JSC
-
-#endif // BlockAllocator_h
index 2a818f0e1ac8bdbc99885f020ff057bb970ecd72..9cfce4f97b9279e4b4a9f55c0d5c80d011070c31 100644 (file)
@@ -35,8 +35,7 @@ namespace JSC {
 
 static const bool verbose = false;
 
-CodeBlockSet::CodeBlockSet(BlockAllocator& blockAllocator)
-    : m_currentlyExecuting(blockAllocator)
+CodeBlockSet::CodeBlockSet()
 {
 }
 
@@ -66,7 +65,7 @@ void CodeBlockSet::clearMarksForFullCollection()
 {
     for (CodeBlock* codeBlock : m_oldCodeBlocks) {
         codeBlock->m_mayBeExecuting = false;
-        codeBlock->m_visitAggregateHasBeenCalled = false;
+        codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     }
 
     // We promote after we clear marks on the old generation CodeBlocks because
@@ -83,7 +82,7 @@ void CodeBlockSet::clearMarksForEdenCollection(const Vector<const JSCell*>& reme
             continue;
         executable->forEachCodeBlock([](CodeBlock* codeBlock) {
             codeBlock->m_mayBeExecuting = false;
-            codeBlock->m_visitAggregateHasBeenCalled = false;
+            codeBlock->m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
         });
     }
 }
index e00cefe7a0bf063451bf02615e2fa1f058acd6ef..6cab875c9f5e0380eeb3d4da67b6c44cf982ef53 100644 (file)
@@ -36,7 +36,6 @@
 
 namespace JSC {
 
-class BlockAllocator;
 class CodeBlock;
 class Heap;
 class JSCell;
@@ -50,7 +49,7 @@ class CodeBlockSet {
     WTF_MAKE_NONCOPYABLE(CodeBlockSet);
 
 public:
-    CodeBlockSet(BlockAllocator&);
+    CodeBlockSet();
     ~CodeBlockSet();
     
     // Add a CodeBlock. This is only called by CodeBlock constructors.
@@ -110,7 +109,7 @@ private:
     // and all, but that seemed like overkill.
     HashSet<CodeBlock*> m_oldCodeBlocks;
     HashSet<CodeBlock*> m_newCodeBlocks;
-    GCSegmentedArray<CodeBlock*> m_currentlyExecuting;
+    Vector<CodeBlock*> m_currentlyExecuting;
 };
 
 } // namespace JSC
index 4685e23133596f2755857893a107fe20fe1f0cde..f636529a43cb63addbfb7ad45188ec27d7c6284e 100644 (file)
 #ifndef CopiedBlock_h
 #define CopiedBlock_h
 
-#include "BlockAllocator.h"
 #include "CopyWorkList.h"
-#include "HeapBlock.h"
 #include "JSCJSValue.h"
 #include "Options.h"
 #include <wtf/Atomics.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/SpinLock.h>
 
 namespace JSC {
 
 class CopiedSpace;
 
-class CopiedBlock : public HeapBlock<CopiedBlock> {
+class CopiedBlock : public DoublyLinkedListNode<CopiedBlock> {
+    friend class WTF::DoublyLinkedListNode<CopiedBlock>;
     friend class CopiedSpace;
     friend class CopiedAllocator;
 public:
-    static CopiedBlock* create(DeadBlock*);
-    static CopiedBlock* createNoZeroFill(DeadBlock*);
+    static CopiedBlock* create(size_t = blockSize);
+    static CopiedBlock* createNoZeroFill(size_t = blockSize);
+    static void destroy(CopiedBlock*);
 
     void pin();
     bool isPinned();
@@ -88,13 +88,18 @@ public:
     SpinLock& workListLock() { return m_workListLock; }
 
 private:
-    CopiedBlock(Region*);
+    CopiedBlock(size_t);
     void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
 
     void checkConsistency();
 
+    CopiedBlock* m_prev;
+    CopiedBlock* m_next;
+
+    size_t m_capacity;
+
     SpinLock m_workListLock;
-    OwnPtr<CopyWorkList> m_workList;
+    std::unique_ptr<CopyWorkList> m_workList;
 
     size_t m_remaining;
     bool m_isPinned : 1;
@@ -105,15 +110,20 @@ private:
 #endif
 };
 
-inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block)
+inline CopiedBlock* CopiedBlock::createNoZeroFill(size_t capacity)
+{
+    return new(NotNull, fastAlignedMalloc(CopiedBlock::blockSize, capacity)) CopiedBlock(capacity);
+}
+
+inline void CopiedBlock::destroy(CopiedBlock* copiedBlock)
 {
-    Region* region = block->region();
-    return new(NotNull, block) CopiedBlock(region);
+    copiedBlock->~CopiedBlock();
+    fastAlignedFree(copiedBlock);
 }
 
-inline CopiedBlock* CopiedBlock::create(DeadBlock* block)
+inline CopiedBlock* CopiedBlock::create(size_t capacity)
 {
-    CopiedBlock* newBlock = createNoZeroFill(block);
+    CopiedBlock* newBlock = createNoZeroFill(capacity);
     newBlock->zeroFillWilderness();
     return newBlock;
 }
@@ -130,8 +140,9 @@ inline void CopiedBlock::zeroFillWilderness()
 #endif
 }
 
-inline CopiedBlock::CopiedBlock(Region* region)
-    : HeapBlock<CopiedBlock>(region)
+inline CopiedBlock::CopiedBlock(size_t capacity)
+    : DoublyLinkedListNode<CopiedBlock>()
+    , m_capacity(capacity)
     , m_remaining(payloadCapacity())
     , m_isPinned(false)
     , m_isOld(false)
@@ -140,7 +151,6 @@ inline CopiedBlock::CopiedBlock(Region* region)
     , m_liveObjects(0)
 #endif
 {
-    m_workListLock.Init();
     ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining)));
 }
 
@@ -154,7 +164,7 @@ inline void CopiedBlock::didSurviveGC()
 #endif
     m_isPinned = false;
     if (m_workList)
-        m_workList.clear();
+        m_workList = nullptr;
 }
 
 inline void CopiedBlock::didEvacuateBytes(unsigned bytes)
@@ -185,7 +195,7 @@ inline void CopiedBlock::pin()
 {
     m_isPinned = true;
     if (m_workList)
-        m_workList.clear();
+        m_workList = nullptr;
 }
 
 inline bool CopiedBlock::isPinned()
@@ -205,7 +215,7 @@ inline void CopiedBlock::didPromote()
 
 inline bool CopiedBlock::isOversize()
 {
-    return region()->isCustomSize();
+    return m_capacity != blockSize;
 }
 
 inline unsigned CopiedBlock::liveBytes()
@@ -216,12 +226,12 @@ inline unsigned CopiedBlock::liveBytes()
 
 inline char* CopiedBlock::payload()
 {
-    return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
+    return reinterpret_cast<char*>(this) + WTF::roundUpToMultipleOf<sizeof(double)>(sizeof(CopiedBlock));
 }
 
 inline char* CopiedBlock::payloadEnd()
 {
-    return reinterpret_cast<char*>(this) + region()->blockSize();
+    return reinterpret_cast<char*>(this) + m_capacity;
 }
 
 inline size_t CopiedBlock::payloadCapacity()
@@ -266,7 +276,7 @@ inline size_t CopiedBlock::size()
 
 inline size_t CopiedBlock::capacity()
 {
-    return region()->blockSize();
+    return m_capacity;
 }
 
 inline bool CopiedBlock::hasWorkList()
index 256f7a6062c6f27c3f8249cb03197469645d7402..2db0cd12ac84bf128dc6b5d7123dbb326fedb011 100644 (file)
@@ -51,7 +51,7 @@ inline void CopiedBlock::reportLiveBytes(SpinLockHolder&, JSCell* owner, CopyTok
 #endif
     m_liveBytes += bytes;
     checkConsistency();
-    ASSERT(m_liveBytes <= CopiedBlock::blockSize);
+    ASSERT(m_liveBytes <= m_capacity);
 
     if (isPinned())
         return;
@@ -62,7 +62,7 @@ inline void CopiedBlock::reportLiveBytes(SpinLockHolder&, JSCell* owner, CopyTok
     }
 
     if (!m_workList)
-        m_workList = adoptPtr(new CopyWorkList(Heap::heap(owner)->blockAllocator()));
+        m_workList = std::make_unique<CopyWorkList>();
 
     m_workList->append(CopyWorklistItem(owner, token));
 }
index cb1a656b63334591e2e784898a3b0b54d988257a..9592eaab9a5837fe6fa4ae683bd3a23eed7953d9 100644 (file)
@@ -38,29 +38,29 @@ CopiedSpace::CopiedSpace(Heap* heap)
     , m_inCopyingPhase(false)
     , m_shouldDoCopyPhase(false)
     , m_numberOfLoanedBlocks(0)
+    , m_bytesRemovedFromOldSpaceDueToReallocation(0)
 {
-    m_toSpaceLock.Init();
 }
 
 CopiedSpace::~CopiedSpace()
 {
     while (!m_oldGen.toSpace->isEmpty())
-        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_oldGen.toSpace->removeHead()));
+        CopiedBlock::destroy(m_oldGen.toSpace->removeHead());
 
     while (!m_oldGen.fromSpace->isEmpty())
-        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_oldGen.fromSpace->removeHead()));
+        CopiedBlock::destroy(m_oldGen.fromSpace->removeHead());
 
     while (!m_oldGen.oversizeBlocks.isEmpty())
-        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_oldGen.oversizeBlocks.removeHead()));
+        CopiedBlock::destroy(m_oldGen.oversizeBlocks.removeHead());
 
     while (!m_newGen.toSpace->isEmpty())
-        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_newGen.toSpace->removeHead()));
+        CopiedBlock::destroy(m_newGen.toSpace->removeHead());
 
     while (!m_newGen.fromSpace->isEmpty())
-        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_newGen.fromSpace->removeHead()));
+        CopiedBlock::destroy(m_newGen.fromSpace->removeHead());
 
     while (!m_newGen.oversizeBlocks.isEmpty())
-        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_newGen.oversizeBlocks.removeHead()));
+        CopiedBlock::destroy(m_newGen.oversizeBlocks.removeHead());
 
     ASSERT(m_oldGen.toSpace->isEmpty());
     ASSERT(m_oldGen.fromSpace->isEmpty());
@@ -99,7 +99,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
 {
     ASSERT(isOversize(bytes));
     
-    CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, CopiedBlock::blockSize));
+    CopiedBlock* block = CopiedBlock::create(WTF::roundUpToMultipleOf<sizeof(double)>(sizeof(CopiedBlock) + bytes));
     m_newGen.oversizeBlocks.push(block);
     m_newGen.blockFilter.add(reinterpret_cast<Bits>(block));
     m_blockSet.add(block);
@@ -110,7 +110,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
     *outPtr = allocator.forceAllocate(bytes);
     allocator.resetCurrentBlock();
 
-    m_heap->didAllocate(block->region()->blockSize());
+    m_heap->didAllocate(block->capacity());
 
     return true;
 }
@@ -156,12 +156,16 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si
 
     CopiedBlock* oldBlock = CopiedSpace::blockFor(oldPtr);
     if (oldBlock->isOversize()) {
-        if (oldBlock->isOld())
+        // FIXME: Eagerly deallocating the old space block probably buys more confusion than
+        // value.
+        // https://bugs.webkit.org/show_bug.cgi?id=144750
+        if (oldBlock->isOld()) {
+            m_bytesRemovedFromOldSpaceDueToReallocation += oldBlock->size();
             m_oldGen.oversizeBlocks.remove(oldBlock);
-        else
+        else
             m_newGen.oversizeBlocks.remove(oldBlock);
         m_blockSet.remove(oldBlock);
-        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(oldBlock));
+        CopiedBlock::destroy(oldBlock);
     }
     
     *ptr = newPtr;
index c0a59a27e054246e70c72d508addd1333f4e8e4c..db1be188f00af4d315e742e373a32dcbc453134e 100644 (file)
@@ -27,7 +27,6 @@
 #define CopiedSpace_h
 
 #include "CopiedAllocator.h"
-#include "HeapBlock.h"
 #include "HeapOperation.h"
 #include "TinyBloomFilter.h"
 #include <wtf/Assertions.h>
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/HashSet.h>
 #include <wtf/OSAllocator.h>
-#include <wtf/PageAllocationAligned.h>
 #include <wtf/PageBlock.h>
+#include <wtf/SpinLock.h>
 #include <wtf/StdLibExtras.h>
-#include <wtf/TCSpinLock.h>
 #include <wtf/ThreadingPrimitives.h>
 
 namespace JSC {
@@ -87,6 +85,13 @@ public:
     static CopiedBlock* blockFor(void*);
 
     Heap* heap() const { return m_heap; }
+    
+    size_t takeBytesRemovedFromOldSpaceDueToReallocation()
+    {
+        size_t result = 0;
+        std::swap(m_bytesRemovedFromOldSpaceDueToReallocation, result);
+        return result;
+    }
 
 private:
     static bool isOversize(size_t);
@@ -136,6 +141,8 @@ private:
     Mutex m_loanedBlocksLock; 
     ThreadCondition m_loanedBlocksCondition;
     size_t m_numberOfLoanedBlocks;
+    
+    size_t m_bytesRemovedFromOldSpaceDueToReallocation;
 
     static const size_t s_maxAllocationSize = CopiedBlock::blockSize / 2;
     static const size_t s_initialBlockNum = 16;
index ec33f582fc609e882e10dedc551357fcf0bbfb58..3faf342434ab4dedfd404b34e4f3ae75c92ad9e6 100644 (file)
@@ -29,7 +29,6 @@
 #include "CopiedBlock.h"
 #include "CopiedSpace.h"
 #include "Heap.h"
-#include "HeapBlock.h"
 #include "VM.h"
 #include <wtf/CheckedBoolean.h>
 
@@ -106,12 +105,12 @@ inline void CopiedSpace::recycleEvacuatedBlock(CopiedBlock* block, HeapOperation
         else
             m_oldGen.fromSpace->remove(block);
     }
-    m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block));
+    CopiedBlock::destroy(block);
 }
 
 inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block)
 {
-    m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block));
+    CopiedBlock::destroy(block);
 
     {
         MutexLocker locker(m_loanedBlocksLock);
@@ -126,7 +125,7 @@ inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block)
 inline CopiedBlock* CopiedSpace::allocateBlockForCopyingPhase()
 {
     ASSERT(m_inCopyingPhase);
-    CopiedBlock* block = CopiedBlock::createNoZeroFill(m_heap->blockAllocator().allocate<CopiedBlock>());
+    CopiedBlock* block = CopiedBlock::createNoZeroFill();
 
     {
         MutexLocker locker(m_loanedBlocksLock);
@@ -143,7 +142,7 @@ inline void CopiedSpace::allocateBlock()
 
     m_allocator.resetCurrentBlock();
     
-    CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate<CopiedBlock>());
+    CopiedBlock* block = CopiedBlock::create();
         
     m_newGen.toSpace->push(block);
     m_newGen.blockFilter.add(reinterpret_cast<Bits>(block));
@@ -235,7 +234,7 @@ inline void CopiedSpace::startedCopying()
         } else {
             oversizeBlocks->remove(block);
             m_blockSet.remove(block);
-            m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(block));
+            CopiedBlock::destroy(block);
         } 
         block = next;
     }
index bba5e91a80b951997fd223a1ac5f9e81631db110..5aceb5ba7a9efa05efff6baf605296bf8ced3beb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,8 +32,7 @@ enum CopyToken {
     ButterflyCopyToken,
     TypedArrayVectorCopyToken,
     MapBackingStoreCopyToken,
-    ArgumentsRegisterArrayCopyToken,
-    ArgumentsSlowArgumentDataCopyToken
+    DirectArgumentsOverridesCopyToken
 };
 
 } // namespace JSC
index 76f1c3d6b7120d181ade961791b83e8548af487f..8308667c5af77201b6a6db3458e703001640081d 100644 (file)
@@ -27,6 +27,7 @@
 #define CopyWorkList_h
 
 #include "CopyToken.h"
+#include <wtf/DoublyLinkedList.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -57,11 +58,18 @@ private:
     uintptr_t m_value;
 };
 
-class CopyWorkListSegment : public HeapBlock<CopyWorkListSegment> {
+class CopyWorkListSegment : public DoublyLinkedListNode<CopyWorkListSegment> {
+    friend class WTF::DoublyLinkedListNode<CopyWorkListSegment>;
 public:
-    static CopyWorkListSegment* create(DeadBlock* block)
+    static CopyWorkListSegment* create()
     {
-        return new (NotNull, block) CopyWorkListSegment(block->region());
+        return new (NotNull, fastMalloc(blockSize)) CopyWorkListSegment();
+    }
+    
+    static void destroy(CopyWorkListSegment* segment)
+    {
+        segment->~CopyWorkListSegment();
+        fastFree(segment);
     }
 
     size_t size() { return m_size; }
@@ -78,8 +86,8 @@ public:
     static const size_t blockSize = 512;
 
 private:
-    CopyWorkListSegment(Region* region)
-        : HeapBlock<CopyWorkListSegment>(region)
+    CopyWorkListSegment()
+        : DoublyLinkedListNode<CopyWorkListSegment>()
         , m_size(0)
     {
     }
@@ -87,6 +95,8 @@ private:
     CopyWorklistItem* data() { return reinterpret_cast<CopyWorklistItem*>(this + 1); }
     char* endOfBlock() { return reinterpret_cast<char*>(this) + blockSize; }
 
+    CopyWorkListSegment* m_prev;
+    CopyWorkListSegment* m_next;
     size_t m_size;
 };
 
@@ -143,7 +153,7 @@ class CopyWorkList {
 public:
     typedef CopyWorkListIterator iterator;
 
-    CopyWorkList(BlockAllocator&);
+    CopyWorkList();
     ~CopyWorkList();
 
     void append(CopyWorklistItem);
@@ -152,24 +162,22 @@ public:
 
 private:
     DoublyLinkedList<CopyWorkListSegment> m_segments;
-    BlockAllocator& m_blockAllocator;
 };
 
-inline CopyWorkList::CopyWorkList(BlockAllocator& blockAllocator)
-    : m_blockAllocator(blockAllocator)
+inline CopyWorkList::CopyWorkList()
 {
 }
 
 inline CopyWorkList::~CopyWorkList()
 {
     while (!m_segments.isEmpty())
-        m_blockAllocator.deallocate(CopyWorkListSegment::destroy(m_segments.removeHead()));
+        CopyWorkListSegment::destroy(m_segments.removeHead());
 }
 
 inline void CopyWorkList::append(CopyWorklistItem item)
 {
     if (m_segments.isEmpty() || m_segments.tail()->isFull())
-        m_segments.append(CopyWorkListSegment::create(m_blockAllocator.allocate<CopyWorkListSegment>()));
+        m_segments.append(CopyWorkListSegment::create());
 
     ASSERT(!m_segments.tail()->isFull());
 
index eeef1d70e462a70e272906e79d2bb8a67e8a819d..b014fcdf50fee7934906c15a5b702988e18df8b9 100644 (file)
@@ -50,8 +50,7 @@ public:
     
     bool operator!() const { return !m_value; }
     
-    typedef T* (CopyWriteBarrier::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return m_value ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return m_value; }
     
     T* get() const
     {
diff --git a/heap/DelayedReleaseScope.h b/heap/DelayedReleaseScope.h
deleted file mode 100644 (file)
index 883c661..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DelayedReleaseScope_h
-#define DelayedReleaseScope_h
-
-#include "Heap.h"
-#include "JSLock.h"
-#include "MarkedSpace.h"
-
-namespace JSC {
-
-#if USE(CF)
-
-class DelayedReleaseScope {
-public:
-    DelayedReleaseScope(MarkedSpace& markedSpace)
-        : m_markedSpace(markedSpace)
-    {
-        ASSERT(!m_markedSpace.m_currentDelayedReleaseScope);
-        m_markedSpace.m_currentDelayedReleaseScope = this;
-    }
-
-    ~DelayedReleaseScope()
-    {
-        ASSERT(m_markedSpace.m_currentDelayedReleaseScope == this);
-        m_markedSpace.m_currentDelayedReleaseScope = nullptr;
-
-        HeapOperation operationInProgress = NoOperation;
-        std::swap(operationInProgress, m_markedSpace.m_heap->m_operationInProgress);
-
-        {
-            JSLock::DropAllLocks dropAllLocks(*m_markedSpace.m_heap->vm());
-            m_delayedReleaseObjects.clear();
-        }
-
-        std::swap(operationInProgress, m_markedSpace.m_heap->m_operationInProgress);
-    }
-
-    template <typename T>
-    void releaseSoon(RetainPtr<T>&& object)
-    {
-        m_delayedReleaseObjects.append(WTF::move(object));
-    }
-
-    static bool isInEffectFor(MarkedSpace& markedSpace)
-    {
-        return markedSpace.m_currentDelayedReleaseScope;
-    }
-
-private:
-    MarkedSpace& m_markedSpace;
-    Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
-};
-
-template <typename T>
-inline void MarkedSpace::releaseSoon(RetainPtr<T>&& object)
-{
-    ASSERT(m_currentDelayedReleaseScope);
-    m_currentDelayedReleaseScope->releaseSoon(WTF::move(object));
-}
-
-#else // USE(CF)
-
-class DelayedReleaseScope {
-public:
-    DelayedReleaseScope(MarkedSpace&)
-    {
-    }
-
-    static bool isInEffectFor(MarkedSpace&)
-    {
-        return true;
-    }
-};
-
-#endif // USE(CF)
-
-} // namespace JSC
-
-#endif // DelayedReleaseScope_h
index 28cfddb77eb8393583b2c8b7efb85e1d2629c5f6..214ab43dca0e8cbaec9995afae23d3b7f32d025c 100644 (file)
@@ -49,7 +49,7 @@ protected:
     virtual double deathRate() override;
 };
 
-inline PassRefPtr<GCActivityCallback> GCActivityCallback::createEdenTimer(Heap* heap)
+inline RefPtr<GCActivityCallback> GCActivityCallback::createEdenTimer(Heap* heap)
 {
     return s_shouldCreateGCTimer ? adoptRef(new EdenGCActivityCallback(heap)) : nullptr;
 }
index 76c678dd6b986e2882a0e631bff593df95d58e38..07ebbbd225869d79db4ccc747a03873555b84980 100644 (file)
@@ -43,18 +43,19 @@ FullGCActivityCallback::FullGCActivityCallback(Heap* heap)
 
 void FullGCActivityCallback::doCollection()
 {
-    Heap* heap = &m_vm->heap;
+    Heap& heap = m_vm->heap;
+    m_didSyncGCRecently = false;
 
 #if !PLATFORM(IOS)
     double startTime = WTF::monotonicallyIncreasingTime();
-    if (heap->isPagedOut(startTime + pagingTimeOut)) {
+    if (heap.isPagedOut(startTime + pagingTimeOut)) {
         cancel();
-        heap->increaseLastFullGCLength(pagingTimeOut);
+        heap.increaseLastFullGCLength(pagingTimeOut);
         return;
     }
 #endif
 
-    heap->collect(FullCollection);
+    heap.collect(FullCollection);
 }
 
 double FullGCActivityCallback::lastGCLength()
index 88cebd9d959673703e58fda676bfa6d833ef9ccf..e727592e278ebbd9c630356617fd3e5a20ef3838 100644 (file)
@@ -36,6 +36,9 @@ public:
 
     virtual void doCollection() override;
 
+    bool didSyncGCRecently() const { return m_didSyncGCRecently; }
+    void setDidSyncGCRecently() { m_didSyncGCRecently = true; }
+
 protected:
 #if USE(CF)
     FullGCActivityCallback(Heap* heap, CFRunLoopRef runLoop)
@@ -47,9 +50,11 @@ protected:
     virtual double lastGCLength() override;
     virtual double gcTimeSlice(size_t bytes) override;
     virtual double deathRate() override;
+
+    bool m_didSyncGCRecently { false };
 };
 
-inline PassRefPtr<GCActivityCallback> GCActivityCallback::createFullTimer(Heap* heap)
+inline RefPtr<FullGCActivityCallback> GCActivityCallback::createFullTimer(Heap* heap)
 {
     return s_shouldCreateGCTimer ? adoptRef(new FullGCActivityCallback(heap)) : nullptr;
 }
index 8d802aadc9d582a97a2a4c6e2ef9bcdb12cda395..73d0e8907d9c07a99bfd2d1281348ceadcee372a 100644 (file)
@@ -30,8 +30,7 @@
 #define GCActivityCallback_h
 
 #include "HeapTimer.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
 
 #if USE(CF)
 #include <CoreFoundation/CoreFoundation.h>
 
 namespace JSC {
 
+class FullGCActivityCallback;
 class Heap;
 
 class JS_EXPORT_PRIVATE GCActivityCallback : public HeapTimer, public ThreadSafeRefCounted<GCActivityCallback> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassRefPtr<GCActivityCallback> createFullTimer(Heap*);
-    static PassRefPtr<GCActivityCallback> createEdenTimer(Heap*);
+    static RefPtr<FullGCActivityCallback> createFullTimer(Heap*);
+    static RefPtr<GCActivityCallback> createEdenTimer(Heap*);
 
     GCActivityCallback(Heap*);
 
index 4c16a3395e84ff15f210b647680faca120018e8d..b8ed121aae79f539c2dd727b6630b1d5abb52a86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
 #include "HeapIterationScope.h"
 #include "JSCell.h"
 #include "JSCellInlines.h"
+#include <wtf/PrintStream.h>
 
 namespace JSC {
 
@@ -63,10 +64,11 @@ public:
         reviveCells();
     }
 
-    void operator()(JSCell* cell)
+    IterationStatus operator()(JSCell* cell)
     {
         m_liveCells.append(cell);
         MarkedBlock::blockFor(cell)->clearMarked(cell);
+        return IterationStatus::Continue;
     }
 
     void log()
@@ -112,3 +114,26 @@ void GCLogging::dumpObjectGraph(Heap* heap)
 }
 
 } // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::GCLogging::Level level)
+{
+    switch (level) {
+    case JSC::GCLogging::Level::None:
+        out.print("None");
+        return;
+    case JSC::GCLogging::Level::Basic:
+        out.print("Basic");
+        return;
+    case JSC::GCLogging::Level::Verbose:
+        out.print("Verbose");
+        return;
+    default:
+        out.print("Level=", level - JSC::GCLogging::Level::None);
+        return;
+    }
+}
+
+} // namespace WTF
+
index 77730750f1e92000a3129ff5dd2b645ac46d36da..650d3fc0474a97d0d742963ff1e4d6d68e819ca2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,4 +48,12 @@ typedef GCLogging::Level gcLogLevel;
 
 } // namespace JSC
 
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&, JSC::GCLogging::Level);
+
+} // namespace WTF
+
 #endif // GCLogging_h
index 8faf16be9b2c2d6f3ba58479bee3dd071d94a163..8aeba1025817eeedf87e336f21a19af40bd68ffc 100644 (file)
 #ifndef GCSegmentedArray_h
 #define GCSegmentedArray_h
 
-#include "HeapBlock.h"
+#include <wtf/DoublyLinkedList.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
 
-class BlockAllocator;
-class DeadBlock;
-
 template <typename T>
-class GCArraySegment : public HeapBlock<GCArraySegment<T>> {
+class GCArraySegment : public DoublyLinkedListNode<GCArraySegment<T>> {
+    friend class WTF::DoublyLinkedListNode<GCArraySegment<T>>;
 public:
-    GCArraySegment(Region* region)
-        : HeapBlock<GCArraySegment>(region)
+    GCArraySegment()
+        : DoublyLinkedListNode<GCArraySegment<T>>()
 #if !ASSERT_DISABLED
         , m_top(0)
 #endif
     {
     }
 
-    static GCArraySegment* create(DeadBlock*);
+    static GCArraySegment* create();
+    static void destroy(GCArraySegment*);
 
     T* data()
     {
@@ -54,6 +53,8 @@ public:
 
     static const size_t blockSize = 4 * KB;
 
+    GCArraySegment* m_prev;
+    GCArraySegment* m_next;
 #if !ASSERT_DISABLED
     size_t m_top;
 #endif
@@ -66,7 +67,7 @@ class GCSegmentedArray {
     friend class GCSegmentedArrayIterator<T>;
     friend class GCSegmentedArrayIterator<const T>;
 public:
-    GCSegmentedArray(BlockAllocator&);
+    GCSegmentedArray();
     ~GCSegmentedArray();
 
     void append(T);
@@ -101,7 +102,6 @@ protected:
     void validatePrevious();
 
     DoublyLinkedList<GCArraySegment<T>> m_segments;
-    BlockAllocator& m_blockAllocator;
 
     JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<GCArraySegment<T>::blockSize>::value;
     size_t m_top;
index e2eff4d87804330e9bd19d1f8fdfc9d46e49dcaa..88e43cc9baff3c3d9369270943798fad30481eec 100644 (file)
 #ifndef GCSegmentedArrayInlines_h
 #define GCSegmentedArrayInlines_h
 
-#include "BlockAllocator.h"
 #include "GCSegmentedArray.h"
 
 namespace JSC {
 
 template <typename T>
-GCSegmentedArray<T>::GCSegmentedArray(BlockAllocator& blockAllocator)
-    : m_blockAllocator(blockAllocator)
-    , m_top(0)
+GCSegmentedArray<T>::GCSegmentedArray()
+    : m_top(0)
     , m_numberOfSegments(0)
 {
-    m_segments.push(GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>()));
+    m_segments.push(GCArraySegment<T>::create());
     m_numberOfSegments++;
 }
 
@@ -46,7 +44,7 @@ GCSegmentedArray<T>::~GCSegmentedArray()
 {
     ASSERT(m_numberOfSegments == 1);
     ASSERT(m_segments.size() == 1);
-    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
+    GCArraySegment<T>::destroy(m_segments.removeHead());
     m_numberOfSegments--;
     ASSERT(!m_numberOfSegments);
     ASSERT(!m_segments.size());
@@ -61,7 +59,7 @@ void GCSegmentedArray<T>::clear()
     for (GCArraySegment<T>* current = m_segments.head(); current->next(); current = next) {
         next = current->next();
         m_segments.remove(current);
-        m_blockAllocator.deallocate(GCArraySegment<T>::destroy(current));
+        GCArraySegment<T>::destroy(current);
     }
     m_top = 0;
     m_numberOfSegments = 1;
@@ -75,7 +73,7 @@ void GCSegmentedArray<T>::expand()
 {
     ASSERT(m_segments.head()->m_top == s_segmentCapacity);
     
-    GCArraySegment<T>* nextSegment = GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>());
+    GCArraySegment<T>* nextSegment = GCArraySegment<T>::create();
     m_numberOfSegments++;
     
 #if !ASSERT_DISABLED
@@ -93,7 +91,7 @@ bool GCSegmentedArray<T>::refill()
     validatePrevious();
     if (top())
         return true;
-    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
+    GCArraySegment<T>::destroy(m_segments.removeHead());
     ASSERT(m_numberOfSegments > 1);
     m_numberOfSegments--;
     setTopForFullSegment();
@@ -127,9 +125,16 @@ void GCSegmentedArray<T>::fillVector(Vector<T>& vector)
 }
 
 template <typename T>
-inline GCArraySegment<T>* GCArraySegment<T>::create(DeadBlock* block)
+inline GCArraySegment<T>* GCArraySegment<T>::create()
 {
-    return new (NotNull, block) GCArraySegment<T>(block->region());
+    return new (NotNull, fastMalloc(blockSize)) GCArraySegment<T>();
+}
+
+template <typename T>
+inline void GCArraySegment<T>::destroy(GCArraySegment* segment)
+{
+    segment->~GCArraySegment();
+    fastFree(segment);
 }
 
 template <typename T>
index cf496a1b67f5e3134cb923004e2ef458cc4a99be..3a3dcea66e715c9b463562ccd259fce46ab685a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JSCInlines.h"
 #include "SlotVisitor.h"
 #include <wtf/MainThread.h>
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 
-GCThread::GCThread(GCThreadSharedData& shared, SlotVisitor* slotVisitor, CopyVisitor* copyVisitor)
+GCThread::GCThread(GCThreadSharedData& shared, std::unique_ptr<SlotVisitor> slotVisitor, std::unique_ptr<CopyVisitor> copyVisitor)
     : m_threadID(0)
     , m_shared(shared)
-    , m_slotVisitor(WTF::adoptPtr(slotVisitor))
-    , m_copyVisitor(WTF::adoptPtr(copyVisitor))
+    , m_slotVisitor(WTF::move(slotVisitor))
+    , m_copyVisitor(WTF::move(copyVisitor))
 {
 }
 
@@ -116,6 +115,9 @@ void GCThread::gcThreadMain()
                 // all of the blocks that the GCThreads borrowed have been returned. doneCopying() 
                 // returns our borrowed CopiedBlock, allowing the copying phase to finish.
                 m_copyVisitor->doneCopying();
+
+                WTF::releaseFastMallocFreeMemoryForThisThread();
+
                 break;
             case NoPhase:
                 RELEASE_ASSERT_NOT_REACHED();
index 0d218f9757237b25bbd7c4c852c558ccb64485ef..b7277992c9f8c24aa52cc073c025dbb93c283c71 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <GCThreadSharedData.h>
 #include <wtf/Deque.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/Threading.h>
 
 namespace JSC {
@@ -39,7 +38,7 @@ class SlotVisitor;
 
 class GCThread {
 public:
-    GCThread(GCThreadSharedData&, SlotVisitor*, CopyVisitor*);
+    GCThread(GCThreadSharedData&, std::unique_ptr<SlotVisitor>, std::unique_ptr<CopyVisitor>);
 
     SlotVisitor* slotVisitor();
     CopyVisitor* copyVisitor();
@@ -54,8 +53,8 @@ private:
 
     ThreadIdentifier m_threadID;
     GCThreadSharedData& m_shared;
-    OwnPtr<SlotVisitor> m_slotVisitor;
-    OwnPtr<CopyVisitor> m_copyVisitor;
+    std::unique_ptr<SlotVisitor> m_slotVisitor;
+    std::unique_ptr<CopyVisitor> m_copyVisitor;
 };
 
 } // namespace JSC
index 27e59e8ec90204655d3cf2dab2fec75351fdd7b1..2286370f1dd67d2057877c3eefc5981e809ad720 100644 (file)
@@ -73,7 +73,7 @@ GCThreadSharedData::GCThreadSharedData(VM* vm)
     : m_vm(vm)
     , m_copiedSpace(&vm->heap.m_storageSpace)
     , m_shouldHashCons(false)
-    , m_sharedMarkStack(vm->heap.blockAllocator())
+    , m_sharedMarkStack()
     , m_numberOfActiveParallelMarkers(0)
     , m_parallelMarkersShouldExit(false)
     , m_copyIndex(0)
@@ -81,15 +81,12 @@ GCThreadSharedData::GCThreadSharedData(VM* vm)
     , m_gcThreadsShouldWait(false)
     , m_currentPhase(NoPhase)
 {
-    m_copyLock.Init();
 #if ENABLE(PARALLEL_GC)
     // Grab the lock so the new GC threads can be properly initialized before they start running.
     std::unique_lock<std::mutex> lock(m_phaseMutex);
     for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) {
         m_numberOfActiveGCThreads++;
-        SlotVisitor* slotVisitor = new SlotVisitor(*this);
-        CopyVisitor* copyVisitor = new CopyVisitor(*this);
-        GCThread* newThread = new GCThread(*this, slotVisitor, copyVisitor);
+        GCThread* newThread = new GCThread(*this, std::make_unique<SlotVisitor>(*this), std::make_unique<CopyVisitor>(*this));
         ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking");
         newThread->initializeThreadID(threadID);
         m_gcThreads.append(newThread);
index 32c06bda347f375c6478fefd915920a65e12a746..d6c960aa4a328de5cf9b583c971689a7e0a4b891 100644 (file)
 #include "WeakReferenceHarvester.h"
 #include <condition_variable>
 #include <wtf/HashSet.h>
-#include <wtf/TCSpinLock.h>
+#include <wtf/SpinLock.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
 
-class GCThread;
-class VM;
+class CopiedBlock;
 class CopiedSpace;
 class CopyVisitor;
+class GCThread;
+class VM;
 
 enum GCPhase {
     NoPhase,
index 28ac30cd9ccb8db90ce39dec665bf38f8a69d61c..c924e041d6ad95fb6ba478cf7115d4967ce1138b 100644 (file)
@@ -52,9 +52,7 @@ class HandleBase {
 public:
     bool operator!() const { return !m_slot || !*m_slot; }
 
-    // This conversion operator allows implicit conversion to bool but not to other integer types.
-    typedef JSValue (HandleBase::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return (m_slot && *m_slot) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return m_slot && *m_slot; }
 
     HandleSlot slot() const { return m_slot; }
 
index 962d37c5e3919ce580ed814ee883633dcbda606f..fb8c10511ac4ccb39f003fdfecc58c478d095af0 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef HandleBlock_h
 #define HandleBlock_h
 
-#include "HeapBlock.h"
+#include <wtf/DoublyLinkedList.h>
 
 namespace JSC {
 
@@ -34,9 +34,11 @@ class DeadBlock;
 class HandleSet;
 class HandleNode;
 
-class HandleBlock : public HeapBlock<HandleBlock> {
+class HandleBlock : public DoublyLinkedListNode<HandleBlock> {
+    friend class WTF::DoublyLinkedListNode<HandleBlock>;
 public:
-    static HandleBlock* create(DeadBlock*, HandleSet*);
+    static HandleBlock* create(HandleSet*);
+    static void destroy(HandleBlock*);
     static HandleBlock* blockFor(HandleNode*);
 
     static const size_t blockSize = 4 * KB;
@@ -48,13 +50,15 @@ public:
     unsigned nodeCapacity();
 
 private:
-    HandleBlock(Region*, HandleSet*);
+    HandleBlock(HandleSet*);
 
     char* payload();
     char* payloadEnd();
 
     static const size_t s_blockMask = ~(blockSize - 1);
 
+    HandleBlock* m_prev;
+    HandleBlock* m_next;
     HandleSet* m_handleSet;
 };
 
index 7c771935e0e2c3dca6b305a6b4f02c698e892d5d..9e29bffd1b25775fc31f36aa6234a866ab0b952c 100644 (file)
 #ifndef HandleBlockInlines_h
 #define HandleBlockInlines_h
 
-#include "BlockAllocator.h"
 #include "HandleBlock.h"
+#include <wtf/FastMalloc.h>
 
 namespace JSC {
 
-inline HandleBlock* HandleBlock::create(DeadBlock* block, HandleSet* handleSet)
+inline HandleBlock* HandleBlock::create(HandleSet* handleSet)
 {
-    Region* region = block->region();
-    return new (NotNull, block) HandleBlock(region, handleSet);
+    return new (NotNull, fastAlignedMalloc(blockSize, blockSize)) HandleBlock(handleSet);
 }
 
-inline HandleBlock::HandleBlock(Region* region, HandleSet* handleSet)
-    : HeapBlock<HandleBlock>(region)
+inline void HandleBlock::destroy(HandleBlock* block)
+{
+    block->~HandleBlock();
+    fastAlignedFree(block);
+}
+
+inline HandleBlock::HandleBlock(HandleSet* handleSet)
+    : DoublyLinkedListNode<HandleBlock>()
     , m_handleSet(handleSet)
 {
 }
 
 inline char* HandleBlock::payloadEnd()
 {
-    return reinterpret_cast<char*>(this) + region()->blockSize();
+    return reinterpret_cast<char*>(this) + blockSize;
 }
 
 inline char* HandleBlock::payload()
index be667e8202fc9c0edd6e3e4493331c20db06f1e1..dec8370ebe4bf01c792981be703ca396e7acc152 100644 (file)
@@ -44,12 +44,12 @@ HandleSet::HandleSet(VM* vm)
 HandleSet::~HandleSet()
 {
     while (!m_blockList.isEmpty())
-        m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
+        HandleBlock::destroy(m_blockList.removeHead());
 }
 
 void HandleSet::grow()
 {
-    HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this);
+    HandleBlock* newBlock = HandleBlock::create(this);
     m_blockList.append(newBlock);
 
     for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
index a7ce97650018719ec7d6733a3b066096b39bff2f..8df8684ece4faacfbde819a2c50c5f53879f243d 100644 (file)
@@ -53,7 +53,7 @@ public:
     void visit(HeapRootVisitor&);
 
 private:
-    void grow();
+    JS_EXPORT_PRIVATE void grow();
     void zapTo(Frame&);
     HandleSlot findFirstAfter(HandleSlot);
 
index 447383b667882fc29e7e805d039dd3d53ee2d6ec..b1f6625e294976c3dc1c86f03851654c617161ad 100644 (file)
@@ -27,7 +27,6 @@
 #include "CopiedSpaceInlines.h"
 #include "CopyVisitorInlines.h"
 #include "DFGWorklist.h"
-#include "DelayedReleaseScope.h"
 #include "EdenGCActivityCallback.h"
 #include "FullGCActivityCallback.h"
 #include "GCActivityCallback.h"
@@ -35,6 +34,7 @@
 #include "HeapIterationScope.h"
 #include "HeapRootVisitor.h"
 #include "HeapStatistics.h"
+#include "HeapVerifier.h"
 #include "IncrementalSweeper.h"
 #include "Interpreter.h"
 #include "JSGlobalObject.h"
@@ -44,6 +44,7 @@
 #include "JSVirtualMachineInternal.h"
 #include "RecursiveAllocationScope.h"
 #include "Tracing.h"
+#include "TypeProfilerLog.h"
 #include "UnlinkedCodeBlock.h"
 #include "VM.h"
 #include "WeakSetInlines.h"
@@ -79,115 +80,125 @@ static type name arguments;
 
 struct GCTimer {
     GCTimer(const char* name)
-        : m_name(name)
+        : name(name)
     {
     }
     ~GCTimer()
     {
-        logData(m_allCollectionData, "(All)");
-        logData(m_edenCollectionData, "(Eden)");
-        logData(m_fullCollectionData, "(Full)");
+        logData(allCollectionData, "(All)");
+        logData(edenCollectionData, "(Eden)");
+        logData(fullCollectionData, "(Full)");
     }
 
     struct TimeRecord {
         TimeRecord()
-            : m_time(0)
-            , m_min(std::numeric_limits<double>::infinity())
-            , m_max(0)
-            , m_count(0)
+            : time(0)
+            , min(std::numeric_limits<double>::infinity())
+            , max(0)
+            , count(0)
         {
         }
 
-        double m_time;
-        double m_min;
-        double m_max;
-        size_t m_count;
+        double time;
+        double min;
+        double max;
+        size_t count;
     };
 
     void logData(const TimeRecord& data, const char* extra)
     {
-        dataLogF("[%d] %s %s: %.2lfms (avg. %.2lf, min. %.2lf, max. %.2lf, count %lu)\n", 
+        dataLogF("[%d] %s (Parent: %s) %s: %.2lfms (avg. %.2lf, min. %.2lf, max. %.2lf, count %lu)\n", 
             getCurrentProcessID(),
-            m_name, extra, 
-            data.m_time * 1000, 
-            data.m_time * 1000 / data.m_count, 
-            data.m_min * 1000, 
-            data.m_max * 1000,
-            data.m_count);
+            name,
+            parent ? parent->name : "nullptr",
+            extra, 
+            data.time * 1000, 
+            data.time * 1000 / data.count, 
+            data.min * 1000, 
+            data.max * 1000,
+            data.count);
     }
 
     void updateData(TimeRecord& data, double duration)
     {
-        if (duration < data.m_min)
-            data.m_min = duration;
-        if (duration > data.m_max)
-            data.m_max = duration;
-        data.m_count++;
-        data.m_time += duration;
+        if (duration < data.min)
+            data.min = duration;
+        if (duration > data.max)
+            data.max = duration;
+        data.count++;
+        data.time += duration;
     }
 
     void didFinishPhase(HeapOperation collectionType, double duration)
     {
-        TimeRecord& data = collectionType == EdenCollection ? m_edenCollectionData : m_fullCollectionData;
+        TimeRecord& data = collectionType == EdenCollection ? edenCollectionData : fullCollectionData;
         updateData(data, duration);
-        updateData(m_allCollectionData, duration);
+        updateData(allCollectionData, duration);
     }
 
-    TimeRecord m_allCollectionData;
-    TimeRecord m_fullCollectionData;
-    TimeRecord m_edenCollectionData;
-    const char* m_name;
+    static GCTimer* s_currentGlobalTimer;
+
+    TimeRecord allCollectionData;
+    TimeRecord fullCollectionData;
+    TimeRecord edenCollectionData;
+    const char* name;
+    GCTimer* parent { nullptr };
 };
 
+GCTimer* GCTimer::s_currentGlobalTimer = nullptr;
+
 struct GCTimerScope {
-    GCTimerScope(GCTimer* timer, HeapOperation collectionType)
-        : m_timer(timer)
-        , m_start(WTF::monotonicallyIncreasingTime())
-        , m_collectionType(collectionType)
+    GCTimerScope(GCTimer& timer, HeapOperation collectionType)
+        : timer(timer)
+        , start(WTF::monotonicallyIncreasingTime())
+        , collectionType(collectionType)
     {
+        timer.parent = GCTimer::s_currentGlobalTimer;
+        GCTimer::s_currentGlobalTimer = &timer;
     }
     ~GCTimerScope()
     {
-        double delta = WTF::monotonicallyIncreasingTime() - m_start;
-        m_timer->didFinishPhase(m_collectionType, delta);
+        double delta = WTF::monotonicallyIncreasingTime() - start;
+        timer.didFinishPhase(collectionType, delta);
+        GCTimer::s_currentGlobalTimer = timer.parent;
     }
-    GCTimer* m_timer;
-    double m_start;
-    HeapOperation m_collectionType;
+    GCTimertimer;
+    double start;
+    HeapOperation collectionType;
 };
 
 struct GCCounter {
     GCCounter(const char* name)
-        : m_name(name)
-        , m_count(0)
-        , m_total(0)
-        , m_min(10000000)
-        , m_max(0)
+        : name(name)
+        , count(0)
+        , total(0)
+        , min(10000000)
+        , max(0)
     {
     }
     
-    void count(size_t amount)
+    void add(size_t amount)
     {
-        m_count++;
-        m_total += amount;
-        if (amount < m_min)
-            m_min = amount;
-        if (amount > m_max)
-            m_max = amount;
+        count++;
+        total += amount;
+        if (amount < min)
+            min = amount;
+        if (amount > max)
+            max = amount;
     }
     ~GCCounter()
     {
-        dataLogF("[%d] %s: %zu values (avg. %zu, min. %zu, max. %zu)\n", getCurrentProcessID(), m_name, m_total, m_total / m_count, m_min, m_max);
+        dataLogF("[%d] %s: %zu values (avg. %zu, min. %zu, max. %zu)\n", getCurrentProcessID(), name, total, total / count, min, max);
     }
-    const char* m_name;
-    size_t m_count;
-    size_t m_total;
-    size_t m_min;
-    size_t m_max;
+    const char* name;
+    size_t count;
+    size_t total;
+    size_t min;
+    size_t max;
 };
 
-#define GCPHASE(name) DEFINE_GC_LOGGING_GLOBAL(GCTimer, name##Timer, (#name)); GCTimerScope name##TimerScope(&name##Timer, m_operationInProgress)
-#define GCCOUNTER(name, value) do { DEFINE_GC_LOGGING_GLOBAL(GCCounter, name##Counter, (#name)); name##Counter.count(value); } while (false)
+#define GCPHASE(name) DEFINE_GC_LOGGING_GLOBAL(GCTimer, name##Timer, (#name)); GCTimerScope name##TimerScope(name##Timer, m_operationInProgress)
+#define GCCOUNTER(name, value) do { DEFINE_GC_LOGGING_GLOBAL(GCCounter, name##Counter, (#name)); name##Counter.add(value); } while (false)
     
 #else
 
@@ -229,12 +240,17 @@ static inline bool isValidThreadState(VM* vm)
 }
 
 struct MarkObject : public MarkedBlock::VoidFunctor {
-    void operator()(JSCell* cell)
+    inline void visit(JSCell* cell)
     {
         if (cell->isZapped())
             return;
         Heap::heap(cell)->setMarked(cell);
     }
+    IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
+    }
 };
 
 struct Count : public MarkedBlock::CountFunctor {
@@ -242,30 +258,36 @@ struct Count : public MarkedBlock::CountFunctor {
 };
 
 struct CountIfGlobalObject : MarkedBlock::CountFunctor {
-    void operator()(JSCell* cell) {
+    inline void visit(JSCell* cell)
+    {
         if (!cell->isObject())
             return;
         if (!asObject(cell)->isGlobalObject())
             return;
         count(1);
     }
+    IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
+    }
 };
 
 class RecordType {
 public:
-    typedef PassOwnPtr<TypeCountSet> ReturnType;
+    typedef std::unique_ptr<TypeCountSet> ReturnType;
 
     RecordType();
-    void operator()(JSCell*);
+    IterationStatus operator()(JSCell*);
     ReturnType returnValue();
 
 private:
     const char* typeName(JSCell*);
-    OwnPtr<TypeCountSet> m_typeCountSet;
+    std::unique_ptr<TypeCountSet> m_typeCountSet;
 };
 
 inline RecordType::RecordType()
-    : m_typeCountSet(adoptPtr(new TypeCountSet))
+    : m_typeCountSet(std::make_unique<TypeCountSet>())
 {
 }
 
@@ -277,21 +299,22 @@ inline const char* RecordType::typeName(JSCell* cell)
     return info->className;
 }
 
-inline void RecordType::operator()(JSCell* cell)
+inline IterationStatus RecordType::operator()(JSCell* cell)
 {
     m_typeCountSet->add(typeName(cell));
+    return IterationStatus::Continue;
 }
 
-inline PassOwnPtr<TypeCountSet> RecordType::returnValue()
+inline std::unique_ptr<TypeCountSet> RecordType::returnValue()
 {
-    return m_typeCountSet.release();
+    return WTF::move(m_typeCountSet);
 }
 
 } // anonymous namespace
 
 Heap::Heap(VM* vm, HeapType heapType)
     : m_heapType(heapType)
-    , m_ramSize(ramSize())
+    , m_ramSize(Options::forceRAMSize() ? Options::forceRAMSize() : ramSize())
     , m_minBytesPerCycle(minHeapSize(m_heapType, m_ramSize))
     , m_sizeAfterLastCollect(0)
     , m_sizeAfterLastFullCollect(0)
@@ -306,16 +329,15 @@ Heap::Heap(VM* vm, HeapType heapType)
     , m_totalBytesVisited(0)
     , m_totalBytesCopied(0)
     , m_operationInProgress(NoOperation)
-    , m_blockAllocator()
     , m_objectSpace(this)
     , m_storageSpace(this)
-    , m_extraMemoryUsage(0)
+    , m_extraMemorySize(0)
+    , m_deprecatedExtraMemorySize(0)
     , m_machineThreads(this)
     , m_sharedData(vm)
     , m_slotVisitor(m_sharedData)
     , m_copyVisitor(m_sharedData)
     , m_handleSet(vm)
-    , m_codeBlocks(m_blockAllocator)
     , m_isSafeToCollect(false)
     , m_writeBarrierBuffer(256)
     , m_vm(vm)
@@ -330,14 +352,25 @@ Heap::Heap(VM* vm, HeapType heapType)
 #else
     , m_edenActivityCallback(m_fullActivityCallback)
 #endif
-    , m_sweeper(IncrementalSweeper::create(this))
+#if USE(CF)
+    , m_sweeper(std::make_unique<IncrementalSweeper>(this, CFRunLoopGetCurrent()))
+#else
+    , m_sweeper(std::make_unique<IncrementalSweeper>(this->vm()))
+#endif
     , m_deferralDepth(0)
+#if USE(CF)
+    , m_delayedReleaseRecursionCount(0)
+#endif
 {
     m_storageSpace.init();
+    if (Options::verifyHeap())
+        m_verifier = std::make_unique<HeapVerifier>(this, Options::numberOfGCCyclesToRecordForVerification());
 }
 
 Heap::~Heap()
 {
+    for (WeakBlock* block : m_logicallyEmptyWeakBlocks)
+        WeakBlock::destroy(block);
 }
 
 bool Heap::isPagedOut(double deadline)
@@ -353,25 +386,51 @@ void Heap::lastChanceToFinalize()
     RELEASE_ASSERT(m_operationInProgress == NoOperation);
 
     m_objectSpace.lastChanceToFinalize();
+    releaseDelayedReleasedObjects();
+
+    sweepAllLogicallyEmptyWeakBlocks();
 }
 
-void Heap::reportExtraMemoryCostSlowCase(size_t cost)
+void Heap::releaseDelayedReleasedObjects()
 {
-    // Our frequency of garbage collection tries to balance memory use against speed
-    // by collecting based on the number of newly created values. However, for values
-    // that hold on to a great deal of memory that's not in the form of other JS values,
-    // that is not good enough - in some cases a lot of those objects can pile up and
-    // use crazy amounts of memory without a GC happening. So we track these extra
-    // memory costs. Only unusually large objects are noted, and we only keep track
-    // of this extra cost until the next GC. In garbage collected languages, most values
-    // are either very short lived temporaries, or have extremely long lifetimes. So
-    // if a large value survives one garbage collection, there is not much point to
-    // collecting more frequently as long as it stays alive.
+#if USE(CF)
+    // We need to guard against the case that releasing an object can create more objects due to the
+    // release calling into JS. When those JS call(s) exit and all locks are being dropped we end up
+    // back here and could try to recursively release objects. We guard that with a recursive entry
+    // count. Only the initial call will release objects, recursive calls simple return and let the
+    // the initial call to the function take care of any objects created during release time.
+    // This also means that we need to loop until there are no objects in m_delayedReleaseObjects
+    // and use a temp Vector for the actual releasing.
+    if (!m_delayedReleaseRecursionCount++) {
+        while (!m_delayedReleaseObjects.isEmpty()) {
+            ASSERT(m_vm->currentThreadIsHoldingAPILock());
+
+            Vector<RetainPtr<CFTypeRef>> objectsToRelease = WTF::move(m_delayedReleaseObjects);
+
+            {
+                // We need to drop locks before calling out to arbitrary code.
+                JSLock::DropAllLocks dropAllLocks(m_vm);
+
+                objectsToRelease.clear();
+            }
+        }
+    }
+    m_delayedReleaseRecursionCount--;
+#endif
+}
 
-    didAllocate(cost);
+void Heap::reportExtraMemoryAllocatedSlowCase(size_t size)
+{
+    didAllocate(size);
     collectIfNecessaryOrDefer();
 }
 
+void Heap::deprecatedReportExtraMemorySlowCase(size_t size)
+{
+    m_deprecatedExtraMemorySize += size;
+    reportExtraMemoryAllocatedSlowCase(size);
+}
+
 void Heap::reportAbandonedObjectGraph()
 {
     // Our clients don't know exactly how much memory they
@@ -424,17 +483,6 @@ void Heap::addReference(JSCell* cell, ArrayBuffer* buffer)
     }
 }
 
-void Heap::pushTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempVector)
-{
-    m_tempSortingVectors.append(tempVector);
-}
-
-void Heap::popTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempVector)
-{
-    ASSERT_UNUSED(tempVector, tempVector == m_tempSortingVectors.last());
-    m_tempSortingVectors.removeLast();
-}
-
 void Heap::harvestWeakReferences()
 {
     m_slotVisitor.harvestWeakReferences();
@@ -475,7 +523,7 @@ void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
     }
 }
 
-void Heap::markRoots(double gcStartTime)
+void Heap::markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
 {
     SamplingRegion samplingRegion("Garbage Collection: Marking");
 
@@ -496,15 +544,11 @@ void Heap::markRoots(double gcStartTime)
 
     // We gather conservative roots before clearing mark bits because conservative
     // gathering uses the mark bits to determine whether a reference is valid.
-    void* dummy;
-    ALLOCATE_AND_GET_REGISTER_STATE(registers);
     ConservativeRoots conservativeRoots(&m_objectSpace.blocks(), &m_storageSpace);
-    gatherStackRoots(conservativeRoots, &dummy, registers);
+    gatherStackRoots(conservativeRoots, stackOrigin, stackTop, calleeSavedRegisters);
     gatherJSStackRoots(conservativeRoots);
     gatherScratchBufferRoots(conservativeRoots);
 
-    sanitizeStackForVM(m_vm);
-
     clearLivenessData();
 
     m_sharedData.didStartMarking();
@@ -518,7 +562,6 @@ void Heap::markRoots(double gcStartTime)
         visitSmallStrings();
         visitConservativeRoots(conservativeRoots);
         visitProtectedObjects(heapRootVisitor);
-        visitTempSortVectors(heapRootVisitor);
         visitArgumentBuffers(heapRootVisitor);
         visitException(heapRootVisitor);
         visitStrongHandles(heapRootVisitor);
@@ -539,6 +582,7 @@ void Heap::markRoots(double gcStartTime)
 
 void Heap::copyBackingStores()
 {
+    GCPHASE(CopyBackingStores);
     if (m_operationInProgress == EdenCollection)
         m_storageSpace.startedCopying<EdenCollection>();
     else {
@@ -559,11 +603,11 @@ void Heap::copyBackingStores()
         m_storageSpace.doneCopying();
 }
 
-void Heap::gatherStackRoots(ConservativeRoots& roots, void** dummy, MachineThreads::RegisterState& registers)
+void Heap::gatherStackRoots(ConservativeRoots& roots, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
 {
     GCPHASE(GatherStackRoots);
     m_jitStubRoutines.clearMarks();
-    m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, dummy, registers);
+    m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, stackOrigin, stackTop, calleeSavedRegisters);
 }
 
 void Heap::gatherJSStackRoots(ConservativeRoots& roots)
@@ -603,11 +647,12 @@ void Heap::visitExternalRememberedSet()
 void Heap::visitSmallStrings()
 {
     GCPHASE(VisitSmallStrings);
-    m_vm->smallStrings.visitStrongReferences(m_slotVisitor);
+    if (!m_vm->smallStrings.needsToBeVisited(m_operationInProgress))
+        return;
 
+    m_vm->smallStrings.visitStrongReferences(m_slotVisitor);
     if (Options::logGC() == GCLogging::Verbose)
         dataLog("Small strings:\n", m_slotVisitor);
-
     m_slotVisitor.donateAndDrain();
 }
 
@@ -655,24 +700,6 @@ void Heap::visitProtectedObjects(HeapRootVisitor& heapRootVisitor)
     m_slotVisitor.donateAndDrain();
 }
 
-void Heap::visitTempSortVectors(HeapRootVisitor& heapRootVisitor)
-{
-    GCPHASE(VisitTempSortVectors);
-    typedef Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>*> VectorOfValueStringVectors;
-
-    for (auto* vector : m_tempSortingVectors) {
-        for (auto& valueStringPair : *vector) {
-            if (valueStringPair.first)
-                heapRootVisitor.visit(&valueStringPair.first);
-        }
-    }
-
-    if (Options::logGC() == GCLogging::Verbose)
-        dataLog("Temp Sort Vectors:\n", m_slotVisitor);
-
-    m_slotVisitor.donateAndDrain();
-}
-
 void Heap::visitArgumentBuffers(HeapRootVisitor& visitor)
 {
     GCPHASE(MarkingArgumentBuffers);
@@ -690,10 +717,11 @@ void Heap::visitArgumentBuffers(HeapRootVisitor& visitor)
 void Heap::visitException(HeapRootVisitor& visitor)
 {
     GCPHASE(MarkingException);
-    if (!m_vm->exception())
+    if (!m_vm->exception() && !m_vm->lastException())
         return;
 
     visitor.visit(m_vm->addressOfException());
+    visitor.visit(m_vm->addressOfLastException());
 
     if (Options::logGC() == GCLogging::Verbose)
         dataLog("Exceptions:\n", m_slotVisitor);
@@ -771,10 +799,8 @@ void Heap::clearRememberedSet(Vector<const JSCell*>& rememberedSet)
 {
 #if ENABLE(GGC)
     GCPHASE(ClearRememberedSet);
-    for (auto* cell : rememberedSet) {
-        MarkedBlock::blockFor(cell)->clearRemembered(cell);
+    for (auto* cell : rememberedSet)
         const_cast<JSCell*>(cell)->setRemembered(false);
-    }
 #else
     UNUSED_PARAM(rememberedSet);
 #endif
@@ -791,15 +817,18 @@ void Heap::updateObjectCounts(double gcStartTime)
 #endif
         dataLogF("\nNumber of live Objects after GC %lu, took %.6f secs\n", static_cast<unsigned long>(visitCount), WTF::monotonicallyIncreasingTime() - gcStartTime);
     }
-
-    if (m_operationInProgress == EdenCollection) {
-        m_totalBytesVisited += m_slotVisitor.bytesVisited();
-        m_totalBytesCopied += m_slotVisitor.bytesCopied();
-    } else {
-        ASSERT(m_operationInProgress == FullCollection);
-        m_totalBytesVisited = m_slotVisitor.bytesVisited();
-        m_totalBytesCopied = m_slotVisitor.bytesCopied();
-    }
+    
+    size_t bytesRemovedFromOldSpaceDueToReallocation =
+        m_storageSpace.takeBytesRemovedFromOldSpaceDueToReallocation();
+    
+    if (m_operationInProgress == FullCollection) {
+        m_totalBytesVisited = 0;
+        m_totalBytesCopied = 0;
+    } else
+        m_totalBytesCopied -= bytesRemovedFromOldSpaceDueToReallocation;
+    
+    m_totalBytesVisited += m_slotVisitor.bytesVisited();
+    m_totalBytesCopied += m_slotVisitor.bytesCopied();
 #if ENABLE(PARALLEL_GC)
     m_totalBytesVisited += m_sharedData.childBytesVisited();
     m_totalBytesCopied += m_sharedData.childBytesCopied();
@@ -820,19 +849,19 @@ size_t Heap::objectCount()
     return m_objectSpace.objectCount();
 }
 
-size_t Heap::extraSize()
+size_t Heap::extraMemorySize()
 {
-    return m_extraMemoryUsage + m_arrayBuffers.size();
+    return m_extraMemorySize + m_deprecatedExtraMemorySize + m_arrayBuffers.size();
 }
 
 size_t Heap::size()
 {
-    return m_objectSpace.size() + m_storageSpace.size() + extraSize();
+    return m_objectSpace.size() + m_storageSpace.size() + extraMemorySize();
 }
 
 size_t Heap::capacity()
 {
-    return m_objectSpace.capacity() + m_storageSpace.capacity() + extraSize();
+    return m_objectSpace.capacity() + m_storageSpace.capacity() + extraMemorySize();
 }
 
 size_t Heap::sizeAfterCollect()
@@ -842,7 +871,7 @@ size_t Heap::sizeAfterCollect()
     // rather than all used (including dead) copied bytes, thus it's 
     // always the case that m_totalBytesCopied <= m_storageSpace.size(). 
     ASSERT(m_totalBytesCopied <= m_storageSpace.size());
-    return m_totalBytesVisited + m_totalBytesCopied + extraSize();
+    return m_totalBytesVisited + m_totalBytesCopied + extraMemorySize();
 }
 
 size_t Heap::protectedGlobalObjectCount()
@@ -861,12 +890,12 @@ size_t Heap::protectedObjectCount()
     return forEachProtectedCell<Count>();
 }
 
-PassOwnPtr<TypeCountSet> Heap::protectedObjectTypeCounts()
+std::unique_ptr<TypeCountSet> Heap::protectedObjectTypeCounts()
 {
     return forEachProtectedCell<RecordType>();
 }
 
-PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
+std::unique_ptr<TypeCountSet> Heap::objectTypeCounts()
 {
     HeapIterationScope iterationScope(*this);
     return m_objectSpace.forEachLiveCell<RecordType>(iterationScope);
@@ -895,10 +924,10 @@ void Heap::deleteAllCompiledCode()
     }
 #endif // ENABLE(DFG_JIT)
 
-    for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
+    for (ExecutableBase* current : m_compiledCode) {
         if (!current->isFunctionExecutable())
             continue;
-        static_cast<FunctionExecutable*>(current)->clearCodeIfNotCompiling();
+        static_cast<FunctionExecutable*>(current)->clearCode();
     }
 
     ASSERT(m_operationInProgress == FullCollection || m_operationInProgress == NoOperation);
@@ -908,26 +937,26 @@ void Heap::deleteAllCompiledCode()
 
 void Heap::deleteAllUnlinkedFunctionCode()
 {
-    for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
+    for (ExecutableBase* current : m_compiledCode) {
         if (!current->isFunctionExecutable())
             continue;
-        static_cast<FunctionExecutable*>(current)->clearUnlinkedCodeForRecompilationIfNotCompiling();
+        static_cast<FunctionExecutable*>(current)->clearUnlinkedCodeForRecompilation();
     }
 }
 
 void Heap::clearUnmarkedExecutables()
 {
     GCPHASE(ClearUnmarkedExecutables);
-    ExecutableBase* next;
-    for (ExecutableBase* current = m_compiledCode.head(); current; current = next) {
-        next = current->next();
+    for (unsigned i = m_compiledCode.size(); i--;) {
+        ExecutableBase* current = m_compiledCode[i];
         if (isMarked(current))
             continue;
 
         // We do this because executable memory is limited on some platforms and because
         // CodeBlock requires eager finalization.
         ExecutableBase::clearCodeVirtual(current);
-        m_compiledCode.remove(current);
+        std::swap(m_compiledCode[i], m_compiledCode.last());
+        m_compiledCode.removeLast();
     }
 }
 
@@ -945,27 +974,39 @@ void Heap::addToRememberedSet(const JSCell* cell)
     ASSERT(!Options::enableConcurrentJIT() || !isCompilationThread());
     if (isRemembered(cell))
         return;
-    MarkedBlock::blockFor(cell)->setRemembered(cell);
     const_cast<JSCell*>(cell)->setRemembered(true);
     m_slotVisitor.unconditionallyAppend(const_cast<JSCell*>(cell));
 }
 
-void Heap::collectAllGarbage()
+void Heap::collectAndSweep(HeapOperation collectionType)
 {
     if (!m_isSafeToCollect)
         return;
 
-    collect(FullCollection);
+    collect(collectionType);
 
     SamplingRegion samplingRegion("Garbage Collection: Sweeping");
-    DelayedReleaseScope delayedReleaseScope(m_objectSpace);
+
+    DeferGCForAWhile deferGC(*this);
     m_objectSpace.sweep();
     m_objectSpace.shrink();
+
+    sweepAllLogicallyEmptyWeakBlocks();
 }
 
 static double minute = 60.0;
 
-void Heap::collect(HeapOperation collectionType)
+NEVER_INLINE void Heap::collect(HeapOperation collectionType)
+{
+    void* stackTop;
+    ALLOCATE_AND_GET_REGISTER_STATE(registers);
+
+    collectImpl(collectionType, wtfThreadData().stack().origin(), &stackTop, registers);
+
+    sanitizeStackForVM(m_vm);
+}
+
+NEVER_INLINE void Heap::collectImpl(HeapOperation collectionType, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
 {
 #if ENABLE(ALLOCATION_LOGGING)
     dataLogF("JSC GC starting collection.\n");
@@ -979,6 +1020,11 @@ void Heap::collect(HeapOperation collectionType)
     
     SamplingRegion samplingRegion("Garbage Collection");
     
+    if (vm()->typeProfiler()) {
+        DeferGCForAWhile awhile(*this);
+        vm()->typeProfilerLog()->processLogEntries(ASCIILiteral("GC"));
+    }
+    
     RELEASE_ASSERT(!m_deferralDepth);
     ASSERT(vm()->currentThreadIsHoldingAPILock());
     RELEASE_ASSERT(vm()->atomicStringTable() == wtfThreadData().atomicStringTable());
@@ -991,17 +1037,33 @@ void Heap::collect(HeapOperation collectionType)
     GCPHASE(Collect);
 
     double gcStartTime = WTF::monotonicallyIncreasingTime();
+    if (m_verifier) {
+        // Verify that live objects from the last GC cycle haven't been corrupted by
+        // mutators before we begin this new GC cycle.
+        m_verifier->verify(HeapVerifier::Phase::BeforeGC);
+
+        m_verifier->initializeGCCycle();
+        m_verifier->gatherLiveObjects(HeapVerifier::Phase::BeforeMarking);
+    }
 
     deleteOldCode(gcStartTime);
     flushOldStructureIDTables();
     stopAllocation();
     flushWriteBarrierBuffer();
 
-    markRoots(gcStartTime);
+    markRoots(gcStartTime, stackOrigin, stackTop, calleeSavedRegisters);
 
+    if (m_verifier) {
+        m_verifier->gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
+        m_verifier->verify(HeapVerifier::Phase::AfterMarking);
+    }
     JAVASCRIPTCORE_GC_MARKED();
 
+    if (vm()->typeProfiler())
+        vm()->typeProfiler()->invalidateTypeSetCache();
+
     reapWeakHandles();
+    pruneStaleEntriesFromWeakGCMaps();
     sweepArrayBuffers();
     snapshotMarkedSpace();
 
@@ -1019,6 +1081,11 @@ void Heap::collect(HeapOperation collectionType)
     didFinishCollection(gcStartTime);
     resumeCompilerThreads();
 
+    if (m_verifier) {
+        m_verifier->trimDeadObjects();
+        m_verifier->verify(HeapVerifier::Phase::AfterGC);
+    }
+
     if (Options::logGC()) {
         double after = currentTimeMS();
         dataLog(after - before, " ms]\n");
@@ -1055,7 +1122,8 @@ void Heap::willStartCollection(HeapOperation collectionType)
     }
     if (m_operationInProgress == FullCollection) {
         m_sizeBeforeLastFullCollect = m_sizeAfterLastCollect + m_bytesAllocatedThisCycle;
-        m_extraMemoryUsage = 0;
+        m_extraMemorySize = 0;
+        m_deprecatedExtraMemorySize = 0;
 
         if (m_fullActivityCallback)
             m_fullActivityCallback->willCollect();
@@ -1110,6 +1178,15 @@ void Heap::reapWeakHandles()
     m_objectSpace.reapWeakSets();
 }
 
+void Heap::pruneStaleEntriesFromWeakGCMaps()
+{
+    GCPHASE(PruningStaleEntriesFromWeakGCMaps);
+    if (m_operationInProgress != FullCollection)
+        return;
+    for (auto& pruneCallback : m_weakGCMaps.values())
+        pruneCallback();
+}
+
 void Heap::sweepArrayBuffers()
 {
     GCPHASE(SweepingArrayBuffers);
@@ -1132,12 +1209,17 @@ struct MarkedBlockSnapshotFunctor : public MarkedBlock::VoidFunctor {
 void Heap::snapshotMarkedSpace()
 {
     GCPHASE(SnapshotMarkedSpace);
-    if (m_operationInProgress != FullCollection)
-        return;
 
-    m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
-    MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
-    m_objectSpace.forEachBlock(functor);
+    if (m_operationInProgress == EdenCollection) {
+        m_blockSnapshot.appendVector(m_objectSpace.blocksWithNewObjects());
+        // Sort and deduplicate the block snapshot since we might be appending to an unfinished work list.
+        std::sort(m_blockSnapshot.begin(), m_blockSnapshot.end());
+        m_blockSnapshot.shrink(std::unique(m_blockSnapshot.begin(), m_blockSnapshot.end()) - m_blockSnapshot.begin());
+    } else {
+        m_blockSnapshot.resizeToFit(m_objectSpace.blocks().set().size());
+        MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
+        m_objectSpace.forEachBlock(functor);
+    }
 }
 
 void Heap::deleteSourceProviderCaches()
@@ -1149,9 +1231,13 @@ void Heap::deleteSourceProviderCaches()
 void Heap::notifyIncrementalSweeper()
 {
     GCPHASE(NotifyIncrementalSweeper);
-    if (m_operationInProgress != FullCollection)
-        return;
-    m_sweeper->startSweeping(m_blockSnapshot);
+
+    if (m_operationInProgress == FullCollection) {
+        if (!m_logicallyEmptyWeakBlocks.isEmpty())
+            m_indexOfNextLogicallyEmptyWeakBlockToSweep = 0;
+    }
+
+    m_sweeper->startSweeping();
 }
 
 void Heap::rememberCurrentlyExecutingCodeBlocks()
@@ -1215,10 +1301,6 @@ void Heap::didFinishCollection(double gcStartTime)
 
     if (Options::recordGCPauseTimes())
         HeapStatistics::recordGCPauseTime(gcStartTime, gcEndTime);
-    RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
-
-    m_operationInProgress = NoOperation;
-    JAVASCRIPTCORE_GC_END();
 
     if (Options::useZombieMode())
         zombifyDeadObjects();
@@ -1231,6 +1313,10 @@ void Heap::didFinishCollection(double gcStartTime)
 
     if (Options::logGC() == GCLogging::Verbose)
         GCLogging::dumpObjectGraph(this);
+
+    RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
+    m_operationInProgress = NoOperation;
+    JAVASCRIPTCORE_GC_END();
 }
 
 void Heap::resumeCompilerThreads()
@@ -1269,9 +1355,9 @@ GCActivityCallback* Heap::edenActivityCallback()
     return m_edenActivityCallback.get();
 }
 
-void Heap::setIncrementalSweeper(PassOwnPtr<IncrementalSweeper> sweeper)
+void Heap::setIncrementalSweeper(std::unique_ptr<IncrementalSweeper> sweeper)
 {
-    m_sweeper = sweeper;
+    m_sweeper = WTF::move(sweeper);
 }
 
 IncrementalSweeper* Heap::sweeper()
@@ -1323,9 +1409,26 @@ void Heap::addCompiledCode(ExecutableBase* executable)
     m_compiledCode.append(executable);
 }
 
+void Heap::collectAllGarbageIfNotDoneRecently()
+{
+    if (!m_fullActivityCallback) {
+        collectAllGarbage();
+        return;
+    }
+
+    if (m_fullActivityCallback->didSyncGCRecently()) {
+        // A synchronous GC was already requested recently so we merely accelerate next collection.
+        reportAbandonedObjectGraph();
+        return;
+    }
+
+    m_fullActivityCallback->setDidSyncGCRecently();
+    collectAllGarbage();
+}
+
 class Zombify : public MarkedBlock::VoidFunctor {
 public:
-    void operator()(JSCell* cell)
+    inline void visit(JSCell* cell)
     {
         void** current = reinterpret_cast<void**>(cell);
 
@@ -1338,6 +1441,11 @@ public:
         for (; current < limit; current++)
             *current = zombifiedBits;
     }
+    IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
+    }
 };
 
 void Heap::zombifyDeadObjects()
@@ -1345,7 +1453,6 @@ void Heap::zombifyDeadObjects()
     // Sweep now because destructors will crash once we're zombified.
     {
         SamplingRegion samplingRegion("Garbage Collection: Sweeping");
-        DelayedReleaseScope delayedReleaseScope(m_objectSpace);
         m_objectSpace.zombifySweep();
     }
     HeapIterationScope iterationScope(*this);
@@ -1387,4 +1494,41 @@ bool Heap::shouldDoFullCollection(HeapOperation requestedCollectionType) const
 #endif
 }
 
+void Heap::addLogicallyEmptyWeakBlock(WeakBlock* block)
+{
+    m_logicallyEmptyWeakBlocks.append(block);
+}
+
+void Heap::sweepAllLogicallyEmptyWeakBlocks()
+{
+    if (m_logicallyEmptyWeakBlocks.isEmpty())
+        return;
+
+    m_indexOfNextLogicallyEmptyWeakBlockToSweep = 0;
+    while (sweepNextLogicallyEmptyWeakBlock()) { }
+}
+
+bool Heap::sweepNextLogicallyEmptyWeakBlock()
+{
+    if (m_indexOfNextLogicallyEmptyWeakBlockToSweep == WTF::notFound)
+        return false;
+
+    WeakBlock* block = m_logicallyEmptyWeakBlocks[m_indexOfNextLogicallyEmptyWeakBlockToSweep];
+
+    block->sweep();
+    if (block->isEmpty()) {
+        std::swap(m_logicallyEmptyWeakBlocks[m_indexOfNextLogicallyEmptyWeakBlockToSweep], m_logicallyEmptyWeakBlocks.last());
+        m_logicallyEmptyWeakBlocks.removeLast();
+        WeakBlock::destroy(block);
+    } else
+        m_indexOfNextLogicallyEmptyWeakBlockToSweep++;
+
+    if (m_indexOfNextLogicallyEmptyWeakBlockToSweep >= m_logicallyEmptyWeakBlocks.size()) {
+        m_indexOfNextLogicallyEmptyWeakBlockToSweep = WTF::notFound;
+        return false;
+    }
+
+    return true;
+}
+
 } // namespace JSC
index 2f2e3e9fc245e1ff18ac4f54c96fd28f6582bb60..878fb5c5a4661866bf16ebb12272122ee6252c71 100644 (file)
@@ -23,7 +23,6 @@
 #define Heap_h
 
 #include "ArrayBuffer.h"
-#include "BlockAllocator.h"
 #include "CodeBlockSet.h"
 #include "CopyVisitor.h"
 #include "GCIncomingRefCountedSet.h"
@@ -57,6 +56,7 @@ class GCAwareJITStubRoutine;
 class GlobalCodeBlock;
 class Heap;
 class HeapRootVisitor;
+class HeapVerifier;
 class IncrementalSweeper;
 class JITStubRoutine;
 class JSCell;
@@ -75,7 +75,6 @@ class Worklist;
 
 static void* const zombifiedBits = reinterpret_cast<void*>(0xdeadbeef);
 
-typedef std::pair<JSValue, WTF::String> ValueStringPair;
 typedef HashCountedSet<JSCell*> ProtectCountSet;
 typedef HashCountedSet<const char*> TypeCountSet;
 
@@ -114,9 +113,11 @@ public:
     Heap(VM*, HeapType);
     ~Heap();
     JS_EXPORT_PRIVATE void lastChanceToFinalize();
+    void releaseDelayedReleasedObjects();
 
     VM* vm() const { return m_vm; }
     MarkedSpace& objectSpace() { return m_objectSpace; }
+    CopiedSpace& storageSpace() { return m_storageSpace; }
     MachineThreads& machineThreads() { return m_machineThreads; }
 
     const SlotVisitor& slotVisitor() const { return m_slotVisitor; }
@@ -128,17 +129,19 @@ public:
     JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
 
     JS_EXPORT_PRIVATE IncrementalSweeper* sweeper();
-    JS_EXPORT_PRIVATE void setIncrementalSweeper(PassOwnPtr<IncrementalSweeper>);
+    JS_EXPORT_PRIVATE void setIncrementalSweeper(std::unique_ptr<IncrementalSweeper>);
 
     // true if collection is in progress
     bool isCollecting();
     HeapOperation operationInProgress() { return m_operationInProgress; }
     // true if an allocation or collection is in progress
     bool isBusy();
-    
+    MarkedSpace::Subspace& subspaceForObjectWithoutDestructor() { return m_objectSpace.subspaceForObjectsWithoutDestructor(); }
+    MarkedSpace::Subspace& subspaceForObjectDestructor() { return m_objectSpace.subspaceForObjectsWithDestructor(); }
+    template<typename ClassType> MarkedSpace::Subspace& subspaceForObjectOfType();
     MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
-    MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); }
-    MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); }
+    MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
+    template<typename ClassType> MarkedAllocator& allocatorForObjectOfType(size_t bytes);
     CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
     CheckedBoolean tryAllocateStorage(JSCell* intendedOwner, size_t, void**);
     CheckedBoolean tryReallocateStorage(JSCell* intendedOwner, void**, size_t, size_t);
@@ -151,31 +154,38 @@ public:
     void notifyIsSafeToCollect() { m_isSafeToCollect = true; }
     bool isSafeToCollect() const { return m_isSafeToCollect; }
 
-    JS_EXPORT_PRIVATE void collectAllGarbage();
+    JS_EXPORT_PRIVATE void collectAllGarbageIfNotDoneRecently();
+    void collectAllGarbage() { collectAndSweep(FullCollection); }
+    JS_EXPORT_PRIVATE void collectAndSweep(HeapOperation collectionType = AnyCollection);
     bool shouldCollect();
     JS_EXPORT_PRIVATE void collect(HeapOperation collectionType = AnyCollection);
     bool collectIfNecessaryOrDefer(); // Returns true if it did collect.
 
-    void reportExtraMemoryCost(size_t cost);
+    // Use this API to report non-GC memory referenced by GC objects. Be sure to
+    // call both of these functions: Calling only one may trigger catastropic
+    // memory growth.
+    void reportExtraMemoryAllocated(size_t);
+    void reportExtraMemoryVisited(JSCell*, size_t);
+
+    // Use this API to report non-GC memory if you can't use the better API above.
+    void deprecatedReportExtraMemory(size_t);
+
     JS_EXPORT_PRIVATE void reportAbandonedObjectGraph();
 
     JS_EXPORT_PRIVATE void protect(JSValue);
     JS_EXPORT_PRIVATE bool unprotect(JSValue); // True when the protect count drops to 0.
     
-    size_t extraSize(); // extra memory usage outside of pages allocated by the heap
+    size_t extraMemorySize(); // Non-GC memory referenced by GC objects.
     JS_EXPORT_PRIVATE size_t size();
     JS_EXPORT_PRIVATE size_t capacity();
     JS_EXPORT_PRIVATE size_t objectCount();
     JS_EXPORT_PRIVATE size_t globalObjectCount();
     JS_EXPORT_PRIVATE size_t protectedObjectCount();
     JS_EXPORT_PRIVATE size_t protectedGlobalObjectCount();
-    JS_EXPORT_PRIVATE PassOwnPtr<TypeCountSet> protectedObjectTypeCounts();
-    JS_EXPORT_PRIVATE PassOwnPtr<TypeCountSet> objectTypeCounts();
+    JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> protectedObjectTypeCounts();
+    JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> objectTypeCounts();
     void showStatistics();
 
-    void pushTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>*);
-    void popTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>*);
-
     HashSet<MarkedArgumentBuffer*>& markListSet();
     
     template<typename Functor> typename Functor::ReturnType forEachProtectedCell(Functor&);
@@ -212,7 +222,6 @@ public:
     
     bool isDeferred() const { return !!m_deferralDepth || Options::disableGC(); }
 
-    BlockAllocator& blockAllocator();
     StructureIDTable& structureIDTable() { return m_structureIDTable; }
 
 #if USE(CF)
@@ -223,15 +232,20 @@ public:
 
     static bool isZombified(JSCell* cell) { return *(void**)cell == zombifiedBits; }
 
+    void registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback);
+    void unregisterWeakGCMap(void* weakGCMap);
+
+    void addLogicallyEmptyWeakBlock(WeakBlock*);
+
 private:
     friend class CodeBlock;
     friend class CopiedBlock;
     friend class DeferGC;
     friend class DeferGCForAWhile;
-    friend class DelayedReleaseScope;
     friend class GCAwareJITStubRoutine;
     friend class GCLogging;
     friend class HandleSet;
+    friend class HeapVerifier;
     friend class JITStubRoutine;
     friend class LLIntOffsetsExtractor;
     friend class MarkedSpace;
@@ -249,19 +263,21 @@ private:
     template<typename T> friend void* allocateCell(Heap&);
     template<typename T> friend void* allocateCell(Heap&, size_t);
 
-    void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die.
-    void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject.
+    void* allocateWithDestructor(size_t); // For use with objects with destructors.
     void* allocateWithoutDestructor(size_t); // For use with objects without destructors.
+    template<typename ClassType> void* allocateObjectOfType(size_t); // Chooses one of the methods above based on type.
 
-    static const size_t minExtraCost = 256;
-    static const size_t maxExtraCost = 1024 * 1024;
+    static const size_t minExtraMemory = 256;
     
     class FinalizerOwner : public WeakHandleOwner {
         virtual void finalize(Handle<Unknown>, void* context) override;
     };
 
     JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
-    JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);
+    JS_EXPORT_PRIVATE void reportExtraMemoryAllocatedSlowCase(size_t);
+    JS_EXPORT_PRIVATE void deprecatedReportExtraMemorySlowCase(size_t);
+
+    void collectImpl(HeapOperation, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
 
     void suspendCompilerThreads();
     void willStartCollection(HeapOperation collectionType);
@@ -270,8 +286,8 @@ private:
     void flushWriteBarrierBuffer();
     void stopAllocation();
 
-    void markRoots(double gcStartTime);
-    void gatherStackRoots(ConservativeRoots&, void** dummy, MachineThreads::RegisterState& registers);
+    void markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
+    void gatherStackRoots(ConservativeRoots&, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
     void gatherJSStackRoots(ConservativeRoots&);
     void gatherScratchBufferRoots(ConservativeRoots&);
     void clearLivenessData();
@@ -281,7 +297,6 @@ private:
     void visitCompilerWorklistWeakReferences();
     void removeDeadCompilerWorklistEntries();
     void visitProtectedObjects(HeapRootVisitor&);
-    void visitTempSortVectors(HeapRootVisitor&);
     void visitArgumentBuffers(HeapRootVisitor&);
     void visitException(HeapRootVisitor&);
     void visitStrongHandles(HeapRootVisitor&);
@@ -294,6 +309,7 @@ private:
     void resetVisitors();
 
     void reapWeakHandles();
+    void pruneStaleEntriesFromWeakGCMaps();
     void sweepArrayBuffers();
     void snapshotMarkedSpace();
     void deleteSourceProviderCaches();
@@ -311,6 +327,9 @@ private:
     void zombifyDeadObjects();
     void markDeadObjects();
 
+    void sweepAllLogicallyEmptyWeakBlocks();
+    bool sweepNextLogicallyEmptyWeakBlock();
+
     bool shouldDoFullCollection(HeapOperation requestedCollectionType) const;
     size_t sizeAfterCollect();
 
@@ -338,18 +357,17 @@ private:
     size_t m_totalBytesCopied;
     
     HeapOperation m_operationInProgress;
-    BlockAllocator m_blockAllocator;
     StructureIDTable m_structureIDTable;
     MarkedSpace m_objectSpace;
     CopiedSpace m_storageSpace;
     GCIncomingRefCountedSet<ArrayBuffer> m_arrayBuffers;
-    size_t m_extraMemoryUsage;
+    size_t m_extraMemorySize;
+    size_t m_deprecatedExtraMemorySize;
 
     HashSet<const JSCell*> m_copyingRememberedSet;
 
     ProtectCountSet m_protectedValues;
-    Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>*> m_tempSortingVectors;
-    OwnPtr<HashSet<MarkedArgumentBuffer*>> m_markListSet;
+    std::unique_ptr<HashSet<MarkedArgumentBuffer*>> m_markListSet;
 
     MachineThreads m_machineThreads;
     
@@ -372,15 +390,26 @@ private:
     double m_lastEdenGCLength;
     double m_lastCodeDiscardTime;
 
-    DoublyLinkedList<ExecutableBase> m_compiledCode;
+    Vector<ExecutableBase*> m_compiledCode;
+
+    Vector<WeakBlock*> m_logicallyEmptyWeakBlocks;
+    size_t m_indexOfNextLogicallyEmptyWeakBlockToSweep { WTF::notFound };
     
-    RefPtr<GCActivityCallback> m_fullActivityCallback;
+    RefPtr<FullGCActivityCallback> m_fullActivityCallback;
     RefPtr<GCActivityCallback> m_edenActivityCallback;
-    OwnPtr<IncrementalSweeper> m_sweeper;
+    std::unique_ptr<IncrementalSweeper> m_sweeper;
     Vector<MarkedBlock*> m_blockSnapshot;
     
     unsigned m_deferralDepth;
     Vector<DFG::Worklist*> m_suspendedCompilerWorklists;
+
+    std::unique_ptr<HeapVerifier> m_verifier;
+#if USE(CF)
+    Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
+    unsigned m_delayedReleaseRecursionCount;
+#endif
+
+    HashMap<void*, std::function<void()>> m_weakGCMaps;
 };
 
 } // namespace JSC
diff --git a/heap/HeapBlock.h b/heap/HeapBlock.h
deleted file mode 100644 (file)
index a5b8d7e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef HeapBlock_h
-#define HeapBlock_h
-
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/StdLibExtras.h>
-
-namespace JSC {
-
-enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
-
-class Region;
-
-template<typename T>
-class HeapBlock : public DoublyLinkedListNode<T> {
-    friend class WTF::DoublyLinkedListNode<T>;
-public:
-    static HeapBlock* destroy(HeapBlock* block) WARN_UNUSED_RETURN
-    {
-        static_cast<T*>(block)->~T();
-        return block;
-    }
-
-    HeapBlock(Region* region)
-        : DoublyLinkedListNode<T>()
-        , m_region(region)
-        , m_prev(0)
-        , m_next(0)
-    {
-        ASSERT(m_region);
-    }
-
-    Region* region() const { return m_region; }
-
-private:
-    Region* m_region;
-    T* m_prev;
-    T* m_next;
-};
-
-} // namespace JSC
-
-#endif    
index 56fb3d798395e2049760af08892e5855101667a3..c7e9735cecf5461a5a4c200065467ee8f9143110 100644 (file)
@@ -29,6 +29,8 @@
 #include "Heap.h"
 #include "JSCell.h"
 #include "Structure.h"
+#include <type_traits>
+#include <wtf/Assertions.h>
 
 namespace JSC {
 
@@ -73,7 +75,6 @@ inline bool Heap::isRemembered(const void* ptr)
     const JSCell* cell = static_cast<const JSCell*>(ptr);
     ASSERT(cell);
     ASSERT(!Options::enableConcurrentJIT() || !isCompilationThread());
-    ASSERT(MarkedBlock::blockFor(cell)->isRemembered(cell) == cell->isRemembered());
     return cell->isRemembered();
 }
 
@@ -152,10 +153,39 @@ inline void Heap::writeBarrier(const JSCell* from)
 #endif
 }
 
-inline void Heap::reportExtraMemoryCost(size_t cost)
+inline void Heap::reportExtraMemoryAllocated(size_t size)
 {
-    if (cost > minExtraCost) 
-        reportExtraMemoryCostSlowCase(cost);
+    if (size > minExtraMemory) 
+        reportExtraMemoryAllocatedSlowCase(size);
+}
+
+inline void Heap::reportExtraMemoryVisited(JSCell* owner, size_t size)
+{
+#if ENABLE(GGC)
+    // We don't want to double-count the extra memory that was reported in previous collections.
+    if (operationInProgress() == EdenCollection && Heap::isRemembered(owner))
+        return;
+#else
+    UNUSED_PARAM(owner);
+#endif
+
+    size_t* counter = &m_extraMemorySize;
+    
+#if ENABLE(COMPARE_AND_SWAP)
+    for (;;) {
+        size_t oldSize = *counter;
+        if (WTF::weakCompareAndSwapSize(counter, oldSize, oldSize + size))
+            return;
+    }
+#else
+    (*counter) += size;
+#endif
+}
+
+inline void Heap::deprecatedReportExtraMemory(size_t size)
+{
+    if (size > minExtraMemory) 
+        deprecatedReportExtraMemorySlowCase(size);
 }
 
 template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell(Functor& functor)
@@ -178,22 +208,13 @@ template<typename Functor> inline void Heap::forEachCodeBlock(Functor& functor)
     return m_codeBlocks.iterate<Functor>(functor);
 }
 
-inline void* Heap::allocateWithNormalDestructor(size_t bytes)
+inline void* Heap::allocateWithDestructor(size_t bytes)
 {
 #if ENABLE(ALLOCATION_LOGGING)
     dataLogF("JSC GC allocating %lu bytes with normal destructor.\n", bytes);
 #endif
     ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithNormalDestructor(bytes);
-}
-
-inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes)
-{
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF("JSC GC allocating %lu bytes with immortal structure destructor.\n", bytes);
-#endif
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithImmortalStructureDestructor(bytes);
+    return m_objectSpace.allocateWithDestructor(bytes);
 }
 
 inline void* Heap::allocateWithoutDestructor(size_t bytes)
@@ -205,6 +226,39 @@ inline void* Heap::allocateWithoutDestructor(size_t bytes)
     return m_objectSpace.allocateWithoutDestructor(bytes);
 }
 
+template<typename ClassType>
+void* Heap::allocateObjectOfType(size_t bytes)
+{
+    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
+
+    if (ClassType::needsDestruction)
+        return allocateWithDestructor(bytes);
+    return allocateWithoutDestructor(bytes);
+}
+
+template<typename ClassType>
+MarkedSpace::Subspace& Heap::subspaceForObjectOfType()
+{
+    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
+    
+    if (ClassType::needsDestruction)
+        return subspaceForObjectDestructor();
+    return subspaceForObjectWithoutDestructor();
+}
+
+template<typename ClassType>
+MarkedAllocator& Heap::allocatorForObjectOfType(size_t bytes)
+{
+    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
+    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
+    
+    if (ClassType::needsDestruction)
+        return allocatorForObjectWithDestructor(bytes);
+    return allocatorForObjectWithoutDestructor(bytes);
+}
+
 inline CheckedBoolean Heap::tryAllocateStorage(JSCell* intendedOwner, size_t bytes, void** outPtr)
 {
     CheckedBoolean result = m_storageSpace.tryAllocate(bytes, outPtr);
@@ -240,16 +294,11 @@ inline void Heap::ascribeOwner(JSCell* intendedOwner, void* storage)
 #endif
 }
 
-inline BlockAllocator& Heap::blockAllocator()
-{
-    return m_blockAllocator;
-}
-
 #if USE(CF)
 template <typename T>
 inline void Heap::releaseSoon(RetainPtr<T>&& object)
 {
-    m_objectSpace.releaseSoon(WTF::move(object));
+    m_delayedReleaseObjects.append(WTF::move(object));
 }
 #endif
 
@@ -286,9 +335,19 @@ inline void Heap::decrementDeferralDepthAndGCIfNeeded()
 inline HashSet<MarkedArgumentBuffer*>& Heap::markListSet()
 {
     if (!m_markListSet)
-        m_markListSet = adoptPtr(new HashSet<MarkedArgumentBuffer*>); 
+        m_markListSet = std::make_unique<HashSet<MarkedArgumentBuffer*>>();
     return *m_markListSet;
 }
+
+inline void Heap::registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback)
+{
+    m_weakGCMaps.add(weakGCMap, WTF::move(pruningCallback));
+}
+
+inline void Heap::unregisterWeakGCMap(void* weakGCMap)
+{
+    m_weakGCMaps.remove(weakGCMap);
+}
     
 } // namespace JSC
 
index f351f6ab5136445198a9a2aa94258161d44890b8..bc5465fb928bb44629e8f54b51888548a1f3d627 100644 (file)
@@ -28,8 +28,8 @@
 
 #include "Heap.h"
 #include "HeapIterationScope.h"
-#include "JSObject.h"
 #include "JSCInlines.h"
+#include "JSObject.h"
 #include "Options.h"
 #include <stdlib.h>
 #if OS(UNIX)
@@ -132,6 +132,7 @@ void HeapStatistics::logStatistics()
 
 void HeapStatistics::exitWithFailure()
 {
+    exit(-1);
 }
 
 void HeapStatistics::reportSuccess()
@@ -166,7 +167,7 @@ class StorageStatistics : public MarkedBlock::VoidFunctor {
 public:
     StorageStatistics();
 
-    void operator()(JSCell*);
+    IterationStatus operator()(JSCell*);
 
     size_t objectWithOutOfLineStorageCount();
     size_t objectCount();
@@ -175,6 +176,8 @@ public:
     size_t storageCapacity();
 
 private:
+    void visit(JSCell*);
+
     size_t m_objectWithOutOfLineStorageCount;
     size_t m_objectCount;
     size_t m_storageSize;
@@ -189,7 +192,7 @@ inline StorageStatistics::StorageStatistics()
 {
 }
 
-inline void StorageStatistics::operator()(JSCell* cell)
+inline void StorageStatistics::visit(JSCell* cell)
 {
     if (!cell->isObject())
         return;
@@ -208,6 +211,12 @@ inline void StorageStatistics::operator()(JSCell* cell)
     m_storageCapacity += object->structure()->totalStorageCapacity() * sizeof(WriteBarrierBase<Unknown>); 
 }
 
+inline IterationStatus StorageStatistics::operator()(JSCell* cell)
+{
+    visit(cell);
+    return IterationStatus::Continue;
+}
+
 inline size_t StorageStatistics::objectWithOutOfLineStorageCount()
 {
     return m_objectWithOutOfLineStorageCount;
@@ -233,25 +242,26 @@ void HeapStatistics::showObjectStatistics(Heap* heap)
     dataLogF("\n=== Heap Statistics: ===\n");
     dataLogF("size: %ldkB\n", static_cast<long>(heap->m_sizeAfterLastCollect / KB));
     dataLogF("capacity: %ldkB\n", static_cast<long>(heap->capacity() / KB));
-    dataLogF("pause time: %lfms\n\n", heap->m_lastFullGCLength);
+    dataLogF("pause time: %lfs\n\n", heap->m_lastFullGCLength);
 
     StorageStatistics storageStatistics;
     {
         HeapIterationScope iterationScope(*heap);
         heap->m_objectSpace.forEachLiveCell(iterationScope, storageStatistics);
     }
-    dataLogF("wasted .property storage: %ldkB (%ld%%)\n",
-        static_cast<long>(
-            (storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB),
-        static_cast<long>(
-            (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100
-                / storageStatistics.storageCapacity()));
-    dataLogF("objects with out-of-line .property storage: %ld (%ld%%)\n",
-        static_cast<long>(
-            storageStatistics.objectWithOutOfLineStorageCount()),
-        static_cast<long>(
-            storageStatistics.objectWithOutOfLineStorageCount() * 100
-                / storageStatistics.objectCount()));
+    long wastedPropertyStorageBytes = 0;
+    long wastedPropertyStoragePercent = 0;
+    long objectWithOutOfLineStorageCount = 0;
+    long objectsWithOutOfLineStoragePercent = 0;
+    if ((storageStatistics.storageCapacity() > 0) && (storageStatistics.objectCount() > 0)) {
+        wastedPropertyStorageBytes = static_cast<long>((storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB);
+        wastedPropertyStoragePercent = static_cast<long>(
+            (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100 / storageStatistics.storageCapacity());
+        objectWithOutOfLineStorageCount = static_cast<long>(storageStatistics.objectWithOutOfLineStorageCount());
+        objectsWithOutOfLineStoragePercent = objectWithOutOfLineStorageCount * 100 / storageStatistics.objectCount();
+    }
+    dataLogF("wasted .property storage: %ldkB (%ld%%)\n", wastedPropertyStorageBytes, wastedPropertyStoragePercent);
+    dataLogF("objects with out-of-line .property storage: %ld (%ld%%)\n", objectWithOutOfLineStorageCount, objectsWithOutOfLineStoragePercent);
 }
 
 } // namespace JSC
index 9660d662165268476d5737bca2ad7f6523d1f92a..15e5484db72a2721fffd8f2a23fcd74b1347c5bd 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "HeapTimer.h"
 
+#include "GCActivityCallback.h"
 #include "IncrementalSweeper.h"
 #include "JSObject.h"
 #include "JSString.h"
@@ -62,7 +63,7 @@ HeapTimer::HeapTimer(VM* vm, CFRunLoopRef runLoop)
     m_context.info = &vm->apiLock();
     m_context.retain = retainAPILock;
     m_context.release = releaseAPILock;
-    m_timer = adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
+    m_timer = adoptCF(CFRunLoopTimerCreate(kCFAllocatorDefault, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
     CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
 }
 
diff --git a/heap/HeapVerifier.cpp b/heap/HeapVerifier.cpp
new file mode 100644 (file)
index 0000000..df92661
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "HeapVerifier.h"
+
+#include "ButterflyInlines.h"
+#include "CopiedSpaceInlines.h"
+#include "HeapIterationScope.h"
+#include "JSCInlines.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+LiveObjectData* LiveObjectList::findObject(JSObject* obj)
+{
+    for (size_t i = 0; i < liveObjects.size(); i++) {
+        LiveObjectData& data = liveObjects[i];
+        if (obj == data.obj)
+            return &data;
+    }
+    return nullptr;
+}
+
+HeapVerifier::HeapVerifier(Heap* heap, unsigned numberOfGCCyclesToRecord)
+    : m_heap(heap)
+    , m_currentCycle(0)
+    , m_numberOfCycles(numberOfGCCyclesToRecord)
+{
+    RELEASE_ASSERT(m_numberOfCycles > 0);
+    m_cycles = std::make_unique<GCCycle[]>(m_numberOfCycles);
+}
+
+const char* HeapVerifier::collectionTypeName(HeapOperation type)
+{
+    switch (type) {
+    case NoOperation:
+        return "NoOperation";
+    case AnyCollection:
+        return "AnyCollection";
+    case Allocation:
+        return "Allocation";
+    case EdenCollection:
+        return "EdenCollection";
+    case FullCollection:
+        return "FullCollection";
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+const char* HeapVerifier::phaseName(HeapVerifier::Phase phase)
+{
+    switch (phase) {
+    case Phase::BeforeGC:
+        return "BeforeGC";
+    case Phase::BeforeMarking:
+        return "BeforeMarking";
+    case Phase::AfterMarking:
+        return "AfterMarking";
+    case Phase::AfterGC:
+        return "AfterGC";
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+static void getButterflyDetails(JSObject* obj, void*& butterflyBase, size_t& butterflyCapacityInBytes, CopiedBlock*& butterflyBlock)
+{
+    Structure* structure = obj->structure();
+    Butterfly* butterfly = obj->butterfly();
+    butterflyBase = butterfly->base(structure);
+    butterflyBlock = CopiedSpace::blockFor(butterflyBase);
+
+    size_t propertyCapacity = structure->outOfLineCapacity();
+    size_t preCapacity;
+    size_t indexingPayloadSizeInBytes;
+    bool hasIndexingHeader = obj->hasIndexingHeader();
+    if (UNLIKELY(hasIndexingHeader)) {
+        preCapacity = butterfly->indexingHeader()->preCapacity(structure);
+        indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure);
+    } else {
+        preCapacity = 0;
+        indexingPayloadSizeInBytes = 0;
+    }
+    butterflyCapacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+}
+
+void HeapVerifier::initializeGCCycle()
+{
+    Heap* heap = m_heap;
+    incrementCycle();
+    currentCycle().collectionType = heap->operationInProgress();
+}
+
+struct GatherLiveObjFunctor : MarkedBlock::CountFunctor {
+    GatherLiveObjFunctor(LiveObjectList& list)
+        : m_list(list)
+    {
+        ASSERT(!list.liveObjects.size());
+    }
+
+    inline void visit(JSCell* cell)
+    {
+        if (!cell->isObject())
+            return;        
+        LiveObjectData data(asObject(cell));
+        m_list.liveObjects.append(data);
+    }
+
+    IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
+    }
+
+    LiveObjectList& m_list;
+};
+
+void HeapVerifier::gatherLiveObjects(HeapVerifier::Phase phase)
+{
+    Heap* heap = m_heap;
+    LiveObjectList& list = *liveObjectListForGathering(phase);
+
+    HeapIterationScope iterationScope(*heap);
+    list.reset();
+    GatherLiveObjFunctor functor(list);
+    heap->m_objectSpace.forEachLiveCell(iterationScope, functor);
+}
+
+LiveObjectList* HeapVerifier::liveObjectListForGathering(HeapVerifier::Phase phase)
+{
+    switch (phase) {
+    case Phase::BeforeMarking:
+        return &currentCycle().before;
+    case Phase::AfterMarking:
+        return &currentCycle().after;
+    case Phase::BeforeGC:
+    case Phase::AfterGC:
+        // We should not be gathering live objects during these phases.
+        break;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+static void trimDeadObjectsFromList(HashSet<JSObject*>& knownLiveSet, LiveObjectList& list)
+{
+    if (!list.hasLiveObjects)
+        return;
+
+    size_t liveObjectsFound = 0;
+    for (size_t i = 0; i < list.liveObjects.size(); i++) {
+        LiveObjectData& objData = list.liveObjects[i];
+        if (objData.isConfirmedDead)
+            continue; // Don't "resurrect" known dead objects.
+        if (!knownLiveSet.contains(objData.obj)) {
+            objData.isConfirmedDead = true;
+            continue;
+        }
+        liveObjectsFound++;
+    }
+    list.hasLiveObjects = !!liveObjectsFound;
+}
+
+void HeapVerifier::trimDeadObjects()
+{
+    HashSet<JSObject*> knownLiveSet;
+
+    LiveObjectList& after = currentCycle().after;
+    for (size_t i = 0; i < after.liveObjects.size(); i++) {
+        LiveObjectData& objData = after.liveObjects[i];
+        knownLiveSet.add(objData.obj);
+    }
+
+    trimDeadObjectsFromList(knownLiveSet, currentCycle().before);
+
+    for (int i = -1; i > -m_numberOfCycles; i--) {
+        trimDeadObjectsFromList(knownLiveSet, cycleForIndex(i).before);
+        trimDeadObjectsFromList(knownLiveSet, cycleForIndex(i).after);
+    }
+}
+
+bool HeapVerifier::verifyButterflyIsInStorageSpace(Phase phase, LiveObjectList& list)
+{
+    auto& liveObjects = list.liveObjects;
+
+    CopiedSpace& storageSpace = m_heap->m_storageSpace;
+    bool listNamePrinted = false;
+    bool success = true;
+    for (size_t i = 0; i < liveObjects.size(); i++) {
+        LiveObjectData& objectData = liveObjects[i];
+        if (objectData.isConfirmedDead)
+            continue;
+
+        JSObject* obj = objectData.obj;
+        Butterfly* butterfly = obj->butterfly();
+        if (butterfly) {
+            void* butterflyBase;
+            size_t butterflyCapacityInBytes;
+            CopiedBlock* butterflyBlock;
+            getButterflyDetails(obj, butterflyBase, butterflyCapacityInBytes, butterflyBlock);
+
+            if (!storageSpace.contains(butterflyBlock)) {
+                if (!listNamePrinted) {
+                    dataLogF("Verification @ phase %s FAILED in object list '%s' (size %zu)\n",
+                        phaseName(phase), list.name, liveObjects.size());
+                    listNamePrinted = true;
+                }
+
+                Structure* structure = obj->structure();
+                const char* structureClassName = structure->classInfo()->className;
+                dataLogF("    butterfly %p (base %p size %zu block %p) NOT in StorageSpace | obj %p type '%s'\n",
+                    butterfly, butterflyBase, butterflyCapacityInBytes, butterflyBlock, obj, structureClassName);
+                success = false;
+            }
+        }
+    }
+    return success;
+}
+
+void HeapVerifier::verify(HeapVerifier::Phase phase)
+{
+    bool beforeVerified = verifyButterflyIsInStorageSpace(phase, currentCycle().before);
+    bool afterVerified = verifyButterflyIsInStorageSpace(phase, currentCycle().after);
+    RELEASE_ASSERT(beforeVerified && afterVerified);
+}
+
+void HeapVerifier::reportObject(LiveObjectData& objData, int cycleIndex, HeapVerifier::GCCycle& cycle, LiveObjectList& list)
+{
+    JSObject* obj = objData.obj;
+
+    if (objData.isConfirmedDead) {
+        dataLogF("FOUND dead obj %p in GC[%d] %s list '%s'\n",
+            obj, cycleIndex, cycle.collectionTypeName(), list.name);
+        return;
+    }
+
+    Structure* structure = obj->structure();
+    Butterfly* butterfly = obj->butterfly();
+    void* butterflyBase;
+    size_t butterflyCapacityInBytes;
+    CopiedBlock* butterflyBlock;
+    getButterflyDetails(obj, butterflyBase, butterflyCapacityInBytes, butterflyBlock);
+
+    dataLogF("FOUND obj %p type '%s' butterfly %p (base %p size %zu block %p) in GC[%d] %s list '%s'\n",
+        obj, structure->classInfo()->className,
+        butterfly, butterflyBase, butterflyCapacityInBytes, butterflyBlock,
+        cycleIndex, cycle.collectionTypeName(), list.name);
+}
+
+void HeapVerifier::checkIfRecorded(JSObject* obj)
+{
+    bool found = false;
+
+    for (int cycleIndex = 0; cycleIndex > -m_numberOfCycles; cycleIndex--) {
+        GCCycle& cycle = cycleForIndex(cycleIndex);
+        LiveObjectList& beforeList = cycle.before; 
+        LiveObjectList& afterList = cycle.after; 
+
+        LiveObjectData* objData;
+        objData = beforeList.findObject(obj);
+        if (objData) {
+            reportObject(*objData, cycleIndex, cycle, beforeList);
+            found = true;
+        }
+        objData = afterList.findObject(obj);
+        if (objData) {
+            reportObject(*objData, cycleIndex, cycle, afterList);
+            found = true;
+        }
+    }
+
+    if (!found)
+        dataLogF("obj %p NOT FOUND\n", obj);
+}
+
+} // namespace JSC
diff --git a/heap/HeapVerifier.h b/heap/HeapVerifier.h
new file mode 100644 (file)
index 0000000..f6ec1d9
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef HeapVerifier_h
+#define HeapVerifier_h
+
+#include "Heap.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class JSObject;
+class MarkedBlock;
+
+struct LiveObjectData {
+    LiveObjectData(JSObject* obj, bool isConfirmedDead = false)
+        : obj(obj)
+        , isConfirmedDead(isConfirmedDead)
+    {
+    }
+
+    JSObject* obj;
+    bool isConfirmedDead;
+};
+
+struct LiveObjectList {
+    LiveObjectList(const char* name)
+        : name(name)
+        , hasLiveObjects(true)
+    {
+    }
+
+    void reset()
+    {
+        liveObjects.clear();
+        hasLiveObjects = true; // Presume to have live objects until the list is trimmed.
+    }
+
+    LiveObjectData* findObject(JSObject*);
+
+    const char* name;
+    Vector<LiveObjectData> liveObjects;
+    bool hasLiveObjects;
+};
+
+class HeapVerifier {
+public:
+    enum class Phase {
+        BeforeGC,
+        BeforeMarking,
+        AfterMarking,
+        AfterGC
+    };
+
+    HeapVerifier(Heap*, unsigned numberOfGCCyclesToRecord);
+
+    void initializeGCCycle();
+    void gatherLiveObjects(Phase);
+    void trimDeadObjects();
+    void verify(Phase);
+
+    // Scans all previously recorded LiveObjectLists and checks if the specified
+    // object was in any of those lists.
+    JS_EXPORT_PRIVATE void checkIfRecorded(JSObject*);
+
+    static const char* collectionTypeName(HeapOperation);
+    static const char* phaseName(Phase);
+
+private:
+    struct GCCycle {
+        GCCycle()
+            : before("Before Marking")
+            , after("After Marking")
+        {
+        }
+
+        HeapOperation collectionType;
+        LiveObjectList before;
+        LiveObjectList after;
+
+        const char* collectionTypeName() const
+        {
+            return HeapVerifier::collectionTypeName(collectionType);
+        }
+    };
+
+    void incrementCycle() { m_currentCycle = (m_currentCycle + 1) % m_numberOfCycles; }
+    GCCycle& currentCycle() { return m_cycles[m_currentCycle]; }
+    GCCycle& cycleForIndex(int cycleIndex)
+    {
+        ASSERT(cycleIndex <= 0 && cycleIndex > -m_numberOfCycles);
+        cycleIndex += m_currentCycle;
+        if (cycleIndex < 0)
+            cycleIndex += m_numberOfCycles;
+        ASSERT(cycleIndex < m_numberOfCycles);
+        return m_cycles[cycleIndex];
+    }
+
+    LiveObjectList* liveObjectListForGathering(Phase);
+    bool verifyButterflyIsInStorageSpace(Phase, LiveObjectList&);
+
+    static void reportObject(LiveObjectData&, int cycleIndex, HeapVerifier::GCCycle&, LiveObjectList&);
+
+    Heap* m_heap;
+    int m_currentCycle;
+    int m_numberOfCycles;
+    std::unique_ptr<GCCycle[]> m_cycles;
+};
+
+} // namespace JSC
+
+#endif // HeapVerifier
index 76cec8ff1f6ef0a5f1a072dfab26f11e178c4bfb..e0783d615f5325484fbe9526819556b46e97e0ff 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "IncrementalSweeper.h"
 
-#include "DelayedReleaseScope.h"
 #include "Heap.h"
 #include "JSObject.h"
 #include "JSString.h"
@@ -46,16 +45,10 @@ static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal;
 
 IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
     : HeapTimer(heap->vm(), runLoop)
-    , m_currentBlockToSweepIndex(0)
     , m_blocksToSweep(heap->m_blockSnapshot)
 {
 }
 
-PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
-{
-    return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent()));
-}
-
 void IncrementalSweeper::scheduleTimer()
 {
     CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (sweepTimeSlice * sweepTimeMultiplier));
@@ -73,10 +66,7 @@ void IncrementalSweeper::doWork()
 
 void IncrementalSweeper::doSweep(double sweepBeginTime)
 {
-    DelayedReleaseScope scope(m_vm->heap.m_objectSpace);
-    while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
-        sweepNextBlock();
-
+    while (sweepNextBlock()) {
         double elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime;
         if (elapsedTime < sweepTimeSlice)
             continue;
@@ -89,30 +79,30 @@ void IncrementalSweeper::doSweep(double sweepBeginTime)
     cancelTimer();
 }
 
-void IncrementalSweeper::sweepNextBlock()
+bool IncrementalSweeper::sweepNextBlock()
 {
-    while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
-        MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++];
+    while (!m_blocksToSweep.isEmpty()) {
+        MarkedBlock* block = m_blocksToSweep.takeLast();
 
         if (!block->needsSweeping())
             continue;
 
+        DeferGCForAWhile deferGC(m_vm->heap);
         block->sweep();
         m_vm->heap.objectSpace().freeOrShrinkBlock(block);
-        return;
+        return true;
     }
+
+    return m_vm->heap.sweepNextLogicallyEmptyWeakBlock();
 }
 
-void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>& blockSnapshot)
+void IncrementalSweeper::startSweeping()
 {
-    m_blocksToSweep = blockSnapshot;
-    m_currentBlockToSweepIndex = 0;
     scheduleTimer();
 }
 
 void IncrementalSweeper::willFinishSweeping()
 {
-    m_currentBlockToSweepIndex = 0;
     m_blocksToSweep.clear();
     if (m_vm)
         cancelTimer();
@@ -129,12 +119,7 @@ void IncrementalSweeper::doWork()
 {
 }
 
-PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
-{
-    return adoptPtr(new IncrementalSweeper(heap->vm()));
-}
-
-void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>&)
+void IncrementalSweeper::startSweeping()
 {
 }
 
@@ -142,8 +127,9 @@ void IncrementalSweeper::willFinishSweeping()
 {
 }
 
-void IncrementalSweeper::sweepNextBlock()
+bool IncrementalSweeper::sweepNextBlock()
 {
+    return false;
 }
 
 #endif
index 0ac145cbd0f843164d6955f5f07588bc10b951fb..a86fd1ce4b78990379a8efc183e56c446e5181c1 100644 (file)
@@ -27,7 +27,6 @@
 #define IncrementalSweeper_h
 
 #include "HeapTimer.h"
-#include <wtf/PassOwnPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -36,27 +35,26 @@ class Heap;
 class MarkedBlock;
 
 class IncrementalSweeper : public HeapTimer {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<IncrementalSweeper> create(Heap*);
-    void startSweeping(Vector<MarkedBlock*>&);
-    JS_EXPORT_PRIVATE virtual void doWork() override;
-    void sweepNextBlock();
-    void willFinishSweeping();
-
-protected:
 #if USE(CF)
     JS_EXPORT_PRIVATE IncrementalSweeper(Heap*, CFRunLoopRef);
 #else
-    IncrementalSweeper(VM*);
+    explicit IncrementalSweeper(VM*);
 #endif
 
+    void startSweeping();
+
+    JS_EXPORT_PRIVATE virtual void doWork() override;
+    bool sweepNextBlock();
+    void willFinishSweeping();
+
 #if USE(CF)
 private:
     void doSweep(double startTime);
     void scheduleTimer();
     void cancelTimer();
     
-    unsigned m_currentBlockToSweepIndex;
     Vector<MarkedBlock*>& m_blocksToSweep;
 #endif
 };
index 16c34146cf452407f352e928e43753dff3b40e0e..560a3562b83d6f3a2b28237a97f617c2ce6aa0a1 100644 (file)
@@ -23,8 +23,8 @@
 #include <stdint.h>
 #include <wtf/Locker.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/SpinLock.h>
 #include <wtf/ThreadingPrimitives.h>
-#include <wtf/TCSpinLock.h>
 
 namespace JSC {
 
@@ -61,7 +61,6 @@ private:
         List()
             : m_first(0)
         {
-            m_lock.Init();
         }
         
         void addThreadSafe(T* handler)
index c354e7754be1d477d141bfa3b878cc549074f401..4ae16a9cad9091ea7e178574ae9061ece62bee65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2009, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  *  Copyright (C) 2009 Acision BV. All rights reserved.
  *
@@ -69,22 +69,10 @@ using namespace WTF;
 
 namespace JSC {
 
-static inline void swapIfBackwards(void*& begin, void*& end)
-{
-#if OS(WINCE)
-    if (begin <= end)
-        return;
-    std::swap(begin, end);
-#else
-UNUSED_PARAM(begin);
-UNUSED_PARAM(end);
-#endif
-}
-
 #if OS(DARWIN)
 typedef mach_port_t PlatformThread;
 #elif OS(WINDOWS)
-typedef HANDLE PlatformThread;
+typedef DWORD PlatformThread;
 #elif USE(PTHREADS)
 typedef pthread_t PlatformThread;
 static const int SigThreadSuspendResume = SIGUSR2;
@@ -100,9 +88,78 @@ static void pthreadSignalHandlerSuspendResume(int)
 #endif
 #endif
 
+class ActiveMachineThreadsManager;
+static ActiveMachineThreadsManager& activeMachineThreadsManager();
+
+class ActiveMachineThreadsManager {
+    WTF_MAKE_NONCOPYABLE(ActiveMachineThreadsManager);
+public:
+
+    class Locker {
+    public:
+        Locker(ActiveMachineThreadsManager& manager)
+            : m_locker(manager.m_lock)
+        {
+        }
+
+    private:
+        MutexLocker m_locker;
+    };
+
+    void add(MachineThreads* machineThreads)
+    {
+        MutexLocker managerLock(m_lock);
+        m_set.add(machineThreads);
+    }
+
+    void remove(MachineThreads* machineThreads)
+    {
+        MutexLocker managerLock(m_lock);
+        auto recordedMachineThreads = m_set.take(machineThreads);
+        RELEASE_ASSERT(recordedMachineThreads = machineThreads);
+    }
+
+    bool contains(MachineThreads* machineThreads)
+    {
+        return m_set.contains(machineThreads);
+    }
+
+private:
+    typedef HashSet<MachineThreads*> MachineThreadsSet;
+
+    ActiveMachineThreadsManager() { }
+    
+    Mutex m_lock;
+    MachineThreadsSet m_set;
+
+    friend ActiveMachineThreadsManager& activeMachineThreadsManager();
+};
+
+static ActiveMachineThreadsManager& activeMachineThreadsManager()
+{
+    static std::once_flag initializeManagerOnceFlag;
+    static ActiveMachineThreadsManager* manager = nullptr;
+
+    std::call_once(initializeManagerOnceFlag, [] {
+        manager = new ActiveMachineThreadsManager();
+    });
+    return *manager;
+}
+    
+static inline PlatformThread getCurrentPlatformThread()
+{
+#if OS(DARWIN)
+    return pthread_mach_thread_np(pthread_self());
+#elif OS(WINDOWS)
+    return GetCurrentThreadId();
+#elif USE(PTHREADS)
+    return pthread_self();
+#endif
+}
+
 class MachineThreads::Thread {
     WTF_MAKE_FAST_ALLOCATED;
-public:
+
     Thread(const PlatformThread& platThread, void* base)
         : platformThread(platThread)
         , stackBase(base)
@@ -119,12 +176,74 @@ public:
         sigemptyset(&mask);
         sigaddset(&mask, SigThreadSuspendResume);
         pthread_sigmask(SIG_UNBLOCK, &mask, 0);
+#elif OS(WINDOWS)
+        ASSERT(platformThread == GetCurrentThreadId());
+        bool isSuccessful =
+            DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),
+                &platformThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
+        RELEASE_ASSERT(isSuccessful);
+#endif
+    }
+
+public:
+    ~Thread()
+    {
+#if OS(WINDOWS)
+        CloseHandle(platformThreadHandle);
 #endif
     }
 
+    static Thread* createForCurrentThread()
+    {
+        return new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
+    }
+
+    struct Registers {
+        inline void* stackPointer() const;
+        
+#if OS(DARWIN)
+#if CPU(X86)
+        typedef i386_thread_state_t PlatformRegisters;
+#elif CPU(X86_64)
+        typedef x86_thread_state64_t PlatformRegisters;
+#elif CPU(PPC)
+        typedef ppc_thread_state_t PlatformRegisters;
+#elif CPU(PPC64)
+        typedef ppc_thread_state64_t PlatformRegisters;
+#elif CPU(ARM)
+        typedef arm_thread_state_t PlatformRegisters;
+#elif CPU(ARM64)
+        typedef arm_thread_state64_t PlatformRegisters;
+#else
+#error Unknown Architecture
+#endif
+        
+#elif OS(WINDOWS)
+        typedef CONTEXT PlatformRegisters;
+#elif USE(PTHREADS)
+        typedef pthread_attr_t PlatformRegisters;
+#else
+#error Need a thread register struct for this platform
+#endif
+        
+        PlatformRegisters regs;
+    };
+    
+    inline bool operator==(const PlatformThread& other) const;
+    inline bool operator!=(const PlatformThread& other) const { return !(*this == other); }
+
+    inline bool suspend();
+    inline void resume();
+    size_t getRegisters(Registers&);
+    void freeRegisters(Registers&);
+    std::pair<void*, size_t> captureStack(void* stackTop);
+
     Thread* next;
     PlatformThread platformThread;
     void* stackBase;
+#if OS(WINDOWS)
+    HANDLE platformThreadHandle;
+#endif
 };
 
 MachineThreads::MachineThreads(Heap* heap)
@@ -135,12 +254,14 @@ MachineThreads::MachineThreads(Heap* heap)
 #endif
 {
     UNUSED_PARAM(heap);
+    threadSpecificKeyCreate(&m_threadSpecific, removeThread);
+    activeMachineThreadsManager().add(this);
 }
 
 MachineThreads::~MachineThreads()
 {
-    if (m_threadSpecific)
-        threadSpecificKeyDelete(m_threadSpecific);
+    activeMachineThreadsManager().remove(this);
+    threadSpecificKeyDelete(m_threadSpecific);
 
     MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
     for (Thread* t = m_registeredThreads; t;) {
@@ -150,45 +271,28 @@ MachineThreads::~MachineThreads()
     }
 }
 
-static inline PlatformThread getCurrentPlatformThread()
-{
-#if OS(DARWIN)
-    return pthread_mach_thread_np(pthread_self());
-#elif OS(WINDOWS)
-    return GetCurrentThread();
-#elif USE(PTHREADS)
-    return pthread_self();
-#endif
-}
-
-static inline bool equalThread(const PlatformThread& first, const PlatformThread& second)
+inline bool MachineThreads::Thread::operator==(const PlatformThread& other) const
 {
 #if OS(DARWIN) || OS(WINDOWS)
-    return first == second;
+    return platformThread == other;
 #elif USE(PTHREADS)
-    return !!pthread_equal(first, second);
+    return !!pthread_equal(platformThread, other);
 #else
 #error Need a way to compare threads on this platform
 #endif
 }
 
-void MachineThreads::makeUsableFromMultipleThreads()
-{
-    if (m_threadSpecific)
-        return;
-
-    threadSpecificKeyCreate(&m_threadSpecific, removeThread);
-}
-
 void MachineThreads::addCurrentThread()
 {
     ASSERT(!m_heap->vm()->hasExclusiveThread() || m_heap->vm()->exclusiveThread() == std::this_thread::get_id());
 
-    if (!m_threadSpecific || threadSpecificGet(m_threadSpecific))
+    if (threadSpecificGet(m_threadSpecific)) {
+        ASSERT(threadSpecificGet(m_threadSpecific) == this);
         return;
+    }
 
     threadSpecificSet(m_threadSpecific, this);
-    Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
+    Thread* thread = Thread::createForCurrentThread();
 
     MutexLocker lock(m_registeredThreadsMutex);
 
@@ -198,55 +302,56 @@ void MachineThreads::addCurrentThread()
 
 void MachineThreads::removeThread(void* p)
 {
-    if (p)
-        static_cast<MachineThreads*>(p)->removeCurrentThread();
+    auto& manager = activeMachineThreadsManager();
+    ActiveMachineThreadsManager::Locker lock(manager);
+    auto machineThreads = static_cast<MachineThreads*>(p);
+    if (manager.contains(machineThreads)) {
+        // There's a chance that the MachineThreads registry that this thread
+        // was registered with was already destructed, and another one happened
+        // to be instantiated at the same address. Hence, this thread may or
+        // may not be found in this MachineThreads registry. We only need to
+        // do a removal if this thread is found in it.
+        machineThreads->removeThreadIfFound(getCurrentPlatformThread());
+    }
 }
 
-void MachineThreads::removeCurrentThread()
+template<typename PlatformThread>
+void MachineThreads::removeThreadIfFound(PlatformThread platformThread)
 {
-    PlatformThread currentPlatformThread = getCurrentPlatformThread();
-
     MutexLocker lock(m_registeredThreadsMutex);
-
-    if (equalThread(currentPlatformThread, m_registeredThreads->platformThread)) {
-        Thread* t = m_registeredThreads;
+    Thread* t = m_registeredThreads;
+    if (*t == platformThread) {
         m_registeredThreads = m_registeredThreads->next;
         delete t;
     } else {
         Thread* last = m_registeredThreads;
-        Thread* t;
         for (t = m_registeredThreads->next; t; t = t->next) {
-            if (equalThread(t->platformThread, currentPlatformThread)) {
+            if (*t == platformThread) {
                 last->next = t->next;
                 break;
             }
             last = t;
         }
-        ASSERT(t); // If t is NULL, we never found ourselves in the list.
         delete t;
     }
 }
-
-void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackCurrent, RegisterState& registers)
+    
+void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters)
 {
-    void* registersBegin = &registers;
-    void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 1)));
-    swapIfBackwards(registersBegin, registersEnd);
+    void* registersBegin = &calleeSavedRegisters;
+    void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&calleeSavedRegisters + 1)));
     conservativeRoots.add(registersBegin, registersEnd, jitStubRoutines, codeBlocks);
 
-    void* stackBegin = stackCurrent;
-    void* stackEnd = wtfThreadData().stack().origin();
-    swapIfBackwards(stackBegin, stackEnd);
-    conservativeRoots.add(stackBegin, stackEnd, jitStubRoutines, codeBlocks);
+    conservativeRoots.add(stackTop, stackOrigin, jitStubRoutines, codeBlocks);
 }
 
-static inline bool suspendThread(const PlatformThread& platformThread)
+inline bool MachineThreads::Thread::suspend()
 {
 #if OS(DARWIN)
     kern_return_t result = thread_suspend(platformThread);
     return result == KERN_SUCCESS;
 #elif OS(WINDOWS)
-    bool threadIsSuspended = (SuspendThread(platformThread) != (DWORD)-1);
+    bool threadIsSuspended = (SuspendThread(platformThreadHandle) != (DWORD)-1);
     ASSERT(threadIsSuspended);
     return threadIsSuspended;
 #elif USE(PTHREADS)
@@ -257,12 +362,12 @@ static inline bool suspendThread(const PlatformThread& platformThread)
 #endif
 }
 
-static inline void resumeThread(const PlatformThread& platformThread)
+inline void MachineThreads::Thread::resume()
 {
 #if OS(DARWIN)
     thread_resume(platformThread);
 #elif OS(WINDOWS)
-    ResumeThread(platformThread);
+    ResumeThread(platformThreadHandle);
 #elif USE(PTHREADS)
     pthread_kill(platformThread, SigThreadSuspendResume);
 #else
@@ -270,38 +375,10 @@ static inline void resumeThread(const PlatformThread& platformThread)
 #endif
 }
 
-typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
-
-#if OS(DARWIN)
-
-#if CPU(X86)
-typedef i386_thread_state_t PlatformThreadRegisters;
-#elif CPU(X86_64)
-typedef x86_thread_state64_t PlatformThreadRegisters;
-#elif CPU(PPC)
-typedef ppc_thread_state_t PlatformThreadRegisters;
-#elif CPU(PPC64)
-typedef ppc_thread_state64_t PlatformThreadRegisters;
-#elif CPU(ARM)
-typedef arm_thread_state_t PlatformThreadRegisters;
-#elif CPU(ARM64)
-typedef arm_thread_state64_t PlatformThreadRegisters;
-#else
-#error Unknown Architecture
-#endif
-
-#elif OS(WINDOWS)
-typedef CONTEXT PlatformThreadRegisters;
-#elif USE(PTHREADS)
-typedef pthread_attr_t PlatformThreadRegisters;
-#else
-#error Need a thread register struct for this platform
-#endif
-
-static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
+size_t MachineThreads::Thread::getRegisters(MachineThreads::Thread::Registers& registers)
 {
+    Thread::Registers::PlatformRegisters& regs = registers.regs;
 #if OS(DARWIN)
-
 #if CPU(X86)
     unsigned user_count = sizeof(regs)/sizeof(int);
     thread_state_flavor_t flavor = i386_THREAD_STATE;
@@ -330,12 +407,12 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P
                             "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result);
         CRASH();
     }
-    return user_count * sizeof(usword_t);
+    return user_count * sizeof(uintptr_t);
 // end OS(DARWIN)
 
 #elif OS(WINDOWS)
     regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
-    GetThreadContext(platformThread, &regs);
+    GetThreadContext(platformThreadHandle, &regs);
     return sizeof(CONTEXT);
 #elif USE(PTHREADS)
     pthread_attr_init(&regs);
@@ -354,7 +431,7 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P
 #endif
 }
 
-static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
+inline void* MachineThreads::Thread::Registers::stackPointer() const
 {
 #if OS(DARWIN)
 
@@ -422,8 +499,9 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
 #endif
 }
 
-static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
+void MachineThreads::Thread::freeRegisters(MachineThreads::Thread::Registers& registers)
 {
+    Thread::Registers::PlatformRegisters& regs = registers.regs;
 #if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
     pthread_attr_destroy(&regs);
 #else
@@ -431,106 +509,164 @@ static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
 #endif
 }
 
-void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks)
+std::pair<void*, size_t> MachineThreads::Thread::captureStack(void* stackTop)
 {
-    PlatformThreadRegisters regs;
-    size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
+    void* begin = stackBase;
+    void* end = reinterpret_cast<void*>(
+        WTF::roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(stackTop)));
+    if (begin > end)
+        std::swap(begin, end);
+    return std::make_pair(begin, static_cast<char*>(end) - static_cast<char*>(begin));
+}
 
-    conservativeRoots.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize), jitStubRoutines, codeBlocks);
+static void copyMemory(void* dst, const void* src, size_t size)
+{
+    size_t dstAsSize = reinterpret_cast<size_t>(dst);
+    size_t srcAsSize = reinterpret_cast<size_t>(src);
+    RELEASE_ASSERT(dstAsSize == WTF::roundUpToMultipleOf<sizeof(intptr_t)>(dstAsSize));
+    RELEASE_ASSERT(srcAsSize == WTF::roundUpToMultipleOf<sizeof(intptr_t)>(srcAsSize));
+    RELEASE_ASSERT(size == WTF::roundUpToMultipleOf<sizeof(intptr_t)>(size));
+
+    intptr_t* dstPtr = reinterpret_cast<intptr_t*>(dst);
+    const intptr_t* srcPtr = reinterpret_cast<const intptr_t*>(src);
+    size /= sizeof(intptr_t);
+    while (size--)
+        *dstPtr++ = *srcPtr++;
+}
+    
+
+
+// This function must not call malloc(), free(), or any other function that might
+// acquire a lock. Since 'thread' is suspended, trying to acquire a lock
+// will deadlock if 'thread' holds that lock.
+// This function, specifically the memory copying, was causing problems with Address Sanitizer in
+// apps. Since we cannot blacklist the system memcpy we must use our own naive implementation,
+// copyMemory, for ASan to work on either instrumented or non-instrumented builds. This is not a
+// significant performance loss as tryCopyOtherThreadStack is only called as part of an O(heapsize)
+// operation. As the heap is generally much larger than the stack the performance hit is minimal.
+// See: https://bugs.webkit.org/show_bug.cgi?id=146297
+void MachineThreads::tryCopyOtherThreadStack(Thread* thread, void* buffer, size_t capacity, size_t* size)
+{
+    Thread::Registers registers;
+    size_t registersSize = thread->getRegisters(registers);
+    std::pair<void*, size_t> stack = thread->captureStack(registers.stackPointer());
 
-    void* stackPointer = otherThreadStackPointer(regs);
-    void* stackBase = thread->stackBase;
-    swapIfBackwards(stackPointer, stackBase);
-    stackPointer = reinterpret_cast<void*>(WTF::roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(stackPointer)));
-    conservativeRoots.add(stackPointer, stackBase, jitStubRoutines, codeBlocks);
+    bool canCopy = *size + registersSize + stack.second <= capacity;
 
-    freePlatformThreadRegisters(regs);
-}
+    if (canCopy)
+        copyMemory(static_cast<char*>(buffer) + *size, &registers, registersSize);
+    *size += registersSize;
 
-void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackCurrent, RegisterState& registers)
-{
-    gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackCurrent, registers);
+    if (canCopy)
+        copyMemory(static_cast<char*>(buffer) + *size, stack.first, stack.second);
+    *size += stack.second;
 
-    if (m_threadSpecific) {
-        PlatformThread currentPlatformThread = getCurrentPlatformThread();
+    thread->freeRegisters(registers);
+}
 
-        MutexLocker lock(m_registeredThreadsMutex);
+bool MachineThreads::tryCopyOtherThreadStacks(MutexLocker&, void* buffer, size_t capacity, size_t* size)
+{
+    // Prevent two VMs from suspending each other's threads at the same time,
+    // which can cause deadlock: <rdar://problem/20300842>.
+    static StaticSpinLock mutex;
+    std::lock_guard<StaticSpinLock> lock(mutex);
 
-        Thread* threadsToBeDeleted = nullptr;
+    *size = 0;
 
-#ifndef NDEBUG
-        // Forbid malloc during the gather phase. The gather phase suspends
-        // threads, so a malloc during gather would risk a deadlock with a
-        // thread that had been suspended while holding the malloc lock.
-        fastMallocForbid();
-#endif
-        int numberOfThreads = 0; // Using 0 to denote that we haven't counted the number of threads yet.
-        int index = 1;
-        Thread* previousThread = nullptr;
-        for (Thread* thread = m_registeredThreads; thread; index++) {
-            if (!equalThread(thread->platformThread, currentPlatformThread)) {
-                bool success = suspendThread(thread->platformThread);
+    PlatformThread currentPlatformThread = getCurrentPlatformThread();
+    int numberOfThreads = 0; // Using 0 to denote that we haven't counted the number of threads yet.
+    int index = 1;
+    Thread* threadsToBeDeleted = nullptr;
+
+    Thread* previousThread = nullptr;
+    for (Thread* thread = m_registeredThreads; thread; index++) {
+        if (*thread != currentPlatformThread) {
+            bool success = thread->suspend();
 #if OS(DARWIN)
-                if (!success) {
-                    if (!numberOfThreads) {
-                        for (Thread* countedThread = m_registeredThreads; countedThread; countedThread = countedThread->next)
-                            numberOfThreads++;
-                    }
-                    
-                    // Re-do the suspension to get the actual failure result for logging.
-                    kern_return_t error = thread_suspend(thread->platformThread);
-                    ASSERT(error != KERN_SUCCESS);
-                    
-                    WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION,
-                        "JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] platformThread %p.",
-                        error, index, numberOfThreads, thread, reinterpret_cast<void*>(thread->platformThread));
-                    
-                    // Put the invalid thread on the threadsToBeDeleted list.
-                    // We can't just delete it here because we have suspended other
-                    // threads, and they may still be holding the C heap lock which
-                    // we need for deleting the invalid thread. Hence, we need to
-                    // defer the deletion till after we have resumed all threads.
-                    Thread* nextThread = thread->next;
-                    thread->next = threadsToBeDeleted;
-                    threadsToBeDeleted = thread;
-                    
-                    if (previousThread)
-                        previousThread->next = nextThread;
-                    else
-                        m_registeredThreads = nextThread;
-                    thread = nextThread;
-                    continue;
+            if (!success) {
+                if (!numberOfThreads) {
+                    for (Thread* countedThread = m_registeredThreads; countedThread; countedThread = countedThread->next)
+                        numberOfThreads++;
                 }
+                
+                // Re-do the suspension to get the actual failure result for logging.
+                kern_return_t error = thread_suspend(thread->platformThread);
+                ASSERT(error != KERN_SUCCESS);
+
+                WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION,
+                    "JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] platformThread %p.",
+                    error, index, numberOfThreads, thread, reinterpret_cast<void*>(thread->platformThread));
+
+                // Put the invalid thread on the threadsToBeDeleted list.
+                // We can't just delete it here because we have suspended other
+                // threads, and they may still be holding the C heap lock which
+                // we need for deleting the invalid thread. Hence, we need to
+                // defer the deletion till after we have resumed all threads.
+                Thread* nextThread = thread->next;
+                thread->next = threadsToBeDeleted;
+                threadsToBeDeleted = thread;
+
+                if (previousThread)
+                    previousThread->next = nextThread;
+                else
+                    m_registeredThreads = nextThread;
+                thread = nextThread;
+                continue;
+            }
 #else
-                UNUSED_PARAM(numberOfThreads);
-                ASSERT_UNUSED(success, success);
+            UNUSED_PARAM(numberOfThreads);
+            UNUSED_PARAM(previousThread);
+            ASSERT_UNUSED(success, success);
 #endif
-            }
-            previousThread = thread;
-            thread = thread->next;
         }
+        previousThread = thread;
+        thread = thread->next;
+    }
 
-        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
-        // and since this is a shared heap, they are real locks.
-        for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
-            if (!equalThread(thread->platformThread, currentPlatformThread))
-                gatherFromOtherThread(conservativeRoots, thread, jitStubRoutines, codeBlocks);
-        }
+    for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+        if (*thread != currentPlatformThread)
+            tryCopyOtherThreadStack(thread, buffer, capacity, size);
+    }
 
-        for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
-            if (!equalThread(thread->platformThread, currentPlatformThread))
-                resumeThread(thread->platformThread);
-        }
+    for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+        if (*thread != currentPlatformThread)
+            thread->resume();
+    }
 
-#ifndef NDEBUG
-        fastMallocAllow();
-#endif
-        for (Thread* thread = threadsToBeDeleted; thread; ) {
-            Thread* nextThread = thread->next;
-            delete thread;
-            thread = nextThread;
-        }
+    for (Thread* thread = threadsToBeDeleted; thread; ) {
+        Thread* nextThread = thread->next;
+        delete thread;
+        thread = nextThread;
     }
+    
+    return *size <= capacity;
+}
+
+static void growBuffer(size_t size, void** buffer, size_t* capacity)
+{
+    if (*buffer)
+        fastFree(*buffer);
+
+    *capacity = WTF::roundUpToMultipleOf(WTF::pageSize(), size * 2);
+    *buffer = fastMalloc(*capacity);
+}
+
+void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters)
+{
+    gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackOrigin, stackTop, calleeSavedRegisters);
+
+    size_t size;
+    size_t capacity = 0;
+    void* buffer = nullptr;
+    MutexLocker lock(m_registeredThreadsMutex);
+    while (!tryCopyOtherThreadStacks(lock, buffer, capacity, &size))
+        growBuffer(size, &buffer, &capacity);
+
+    if (!buffer)
+        return;
+
+    conservativeRoots.add(buffer, static_cast<char*>(buffer) + size, jitStubRoutines, codeBlocks);
+    fastFree(buffer);
 }
 
 } // namespace JSC
index 22b1d222ead4863223e7ac3fc11de1f60a065cc7..9b6b7327b62e8bbb0e3baf64841104b41e4d42fc 100644 (file)
@@ -42,20 +42,22 @@ namespace JSC {
         MachineThreads(Heap*);
         ~MachineThreads();
 
-        void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackCurrent, RegisterState& registers);
+        void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters);
 
-        JS_EXPORT_PRIVATE void makeUsableFromMultipleThreads();
         JS_EXPORT_PRIVATE void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
 
     private:
-        void gatherFromCurrentThread(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackCurrent, RegisterState& registers);
-
         class Thread;
 
+        void gatherFromCurrentThread(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters);
+
+        void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
+        bool tryCopyOtherThreadStacks(MutexLocker&, void*, size_t capacity, size_t*);
+
         static void removeThread(void*);
-        void removeCurrentThread();
 
-        void gatherFromOtherThread(ConservativeRoots&, Thread*, JITStubRoutineSet&, CodeBlockSet&);
+        template<typename PlatformThread>
+        void removeThreadIfFound(PlatformThread);
 
         Mutex m_registeredThreadsMutex;
         Thread* m_registeredThreads;
index 66201f4f107449165ee9f0e6e540e64df58af034..da6ef94723d0b5e7604a10ea9b7f7b5ef25f4e38 100644 (file)
@@ -30,8 +30,8 @@
 
 namespace JSC {
 
-MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
-    : GCSegmentedArray<const JSCell*>(blockAllocator)
+MarkStackArray::MarkStackArray()
+    : GCSegmentedArray<const JSCell*>()
 {
 }
 
index 17a60194530b4d765235324c703c32a56622dea8..04f19c62c3d67373a8531756a2f8e7f4ad3530d1 100644 (file)
@@ -34,7 +34,7 @@ class JSCell;
 
 class MarkStackArray : public GCSegmentedArray<const JSCell*> {
 public:
-    MarkStackArray(BlockAllocator&);
+    MarkStackArray();
 
     void donateSomeCellsTo(MarkStackArray& other);
     void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount);
index b8f01fd187920f36053a948adf6009468839c3ea..2dbf8ae7f509f9e9eed1782729c1056f81c66e1c 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "MarkedAllocator.h"
 
-#include "DelayedReleaseScope.h"
 #include "GCActivityCallback.h"
 #include "Heap.h"
 #include "IncrementalSweeper.h"
@@ -62,46 +61,40 @@ bool MarkedAllocator::isPagedOut(double deadline)
 
 inline void* MarkedAllocator::tryAllocateHelper(size_t bytes)
 {
-    // We need a while loop to check the free list because the DelayedReleaseScope 
-    // could cause arbitrary code to execute and exhaust the free list that we 
-    // thought had elements in it.
-    while (!m_freeList.head) {
-        DelayedReleaseScope delayedReleaseScope(*m_markedSpace);
-        if (m_currentBlock) {
-            ASSERT(m_currentBlock == m_nextBlockToSweep);
-            m_currentBlock->didConsumeFreeList();
-            m_nextBlockToSweep = m_currentBlock->next();
-        }
+    if (m_currentBlock) {
+        ASSERT(m_currentBlock == m_nextBlockToSweep);
+        m_currentBlock->didConsumeFreeList();
+        m_nextBlockToSweep = m_currentBlock->next();
+    }
 
-        MarkedBlock* next;
-        for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) {
-            next = block->next();
-
-            MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
-            
-            double utilization = ((double)MarkedBlock::blockSize - (double)freeList.bytes) / (double)MarkedBlock::blockSize;
-            if (utilization >= Options::minMarkedBlockUtilization()) {
-                ASSERT(freeList.bytes || !freeList.head);
-                m_blockList.remove(block);
-                m_retiredBlocks.push(block);
-                block->didRetireBlock(freeList);
-                continue;
-            }
-
-            if (bytes > block->cellSize()) {
-                block->stopAllocating(freeList);
-                continue;
-            }
-
-            m_currentBlock = block;
-            m_freeList = freeList;
-            break;
-        }
+    MarkedBlock* next;
+    for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) {
+        next = block->next();
+
+        MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
         
-        if (!m_freeList.head) {
-            m_currentBlock = 0;
-            return 0;
+        double utilization = ((double)MarkedBlock::blockSize - (double)freeList.bytes) / (double)MarkedBlock::blockSize;
+        if (utilization >= Options::minMarkedBlockUtilization()) {
+            ASSERT(freeList.bytes || !freeList.head);
+            m_blockList.remove(block);
+            m_retiredBlocks.push(block);
+            block->didRetireBlock(freeList);
+            continue;
         }
+
+        if (bytes > block->cellSize()) {
+            block->stopAllocating(freeList);
+            continue;
+        }
+
+        m_currentBlock = block;
+        m_freeList = freeList;
+        break;
+    }
+    
+    if (!m_freeList.head) {
+        m_currentBlock = 0;
+        return 0;
     }
 
     ASSERT(m_freeList.head);
@@ -128,17 +121,6 @@ inline void* MarkedAllocator::tryAllocate(size_t bytes)
     m_heap->m_operationInProgress = Allocation;
     void* result = tryAllocateHelper(bytes);
 
-    // Due to the DelayedReleaseScope in tryAllocateHelper, some other thread might have
-    // created a new block after we thought we didn't find any free cells. 
-    while (!result && m_currentBlock) {
-        // A new block was added by another thread so try popping the free list.
-        result = tryPopFreeList(bytes);
-        if (result)
-            break;
-        // The free list was empty, so call tryAllocateHelper to do the normal sweeping stuff.
-        result = tryAllocateHelper(bytes);
-    }
-
     m_heap->m_operationInProgress = NoOperation;
     ASSERT(result || !m_currentBlock);
     return result;
@@ -198,9 +180,7 @@ MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
 
     size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
 
-    if (blockSize == MarkedBlock::blockSize)
-        return MarkedBlock::create(m_heap->blockAllocator().allocate<MarkedBlock>(), this, cellSize, m_destructorType);
-    return MarkedBlock::create(m_heap->blockAllocator().allocateCustomSize(blockSize, MarkedBlock::blockSize), this, cellSize, m_destructorType);
+    return MarkedBlock::create(this, blockSize, cellSize, m_needsDestruction);
 }
 
 void MarkedAllocator::addBlock(MarkedBlock* block)
index b497f8febd6c6f5ae09939acfd5bd3ca5727d34b..161af480f974c90c7664fa1f77b7685fea6c39e5 100644 (file)
@@ -26,7 +26,7 @@ public:
     void stopAllocating();
     void resumeAllocating();
     size_t cellSize() { return m_cellSize; }
-    MarkedBlock::DestructorType destructorType() { return m_destructorType; }
+    bool needsDestruction() { return m_needsDestruction; }
     void* allocate(size_t);
     Heap* heap() { return m_heap; }
     MarkedBlock* takeLastActiveBlock()
@@ -40,7 +40,7 @@ public:
     
     void addBlock(MarkedBlock*);
     void removeBlock(MarkedBlock*);
-    void init(Heap*, MarkedSpace*, size_t cellSize, MarkedBlock::DestructorType);
+    void init(Heap*, MarkedSpace*, size_t cellSize, bool needsDestruction);
 
     bool isPagedOut(double deadline);
    
@@ -59,7 +59,7 @@ private:
     DoublyLinkedList<MarkedBlock> m_blockList;
     DoublyLinkedList<MarkedBlock> m_retiredBlocks;
     size_t m_cellSize;
-    MarkedBlock::DestructorType m_destructorType;
+    bool m_needsDestruction { false };
     Heap* m_heap;
     MarkedSpace* m_markedSpace;
 };
@@ -74,18 +74,17 @@ inline MarkedAllocator::MarkedAllocator()
     , m_lastActiveBlock(0)
     , m_nextBlockToSweep(0)
     , m_cellSize(0)
-    , m_destructorType(MarkedBlock::None)
     , m_heap(0)
     , m_markedSpace(0)
 {
 }
 
-inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType)
+inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool needsDestruction)
 {
     m_heap = heap;
     m_markedSpace = markedSpace;
     m_cellSize = cellSize;
-    m_destructorType = destructorType;
+    m_needsDestruction = needsDestruction;
 }
 
 inline void* MarkedAllocator::allocate(size_t bytes)
index f4d39fc7dd43be7956b9ff6ee32f35cead38190b..b9c3f9ff9f0ab39f5ddc2e26352ab389b764050c 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "MarkedBlock.h"
 
-#include "DelayedReleaseScope.h"
 #include "IncrementalSweeper.h"
 #include "JSCell.h"
 #include "JSDestructibleObject.h"
 
 namespace JSC {
 
-MarkedBlock* MarkedBlock::create(DeadBlock* block, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
+MarkedBlock* MarkedBlock::create(MarkedAllocator* allocator, size_t capacity, size_t cellSize, bool needsDestruction)
 {
-    ASSERT(reinterpret_cast<size_t>(block) == (reinterpret_cast<size_t>(block) & blockMask));
-    Region* region = block->region();
-    return new (NotNull, block) MarkedBlock(region, allocator, cellSize, destructorType);
+    return new (NotNull, fastAlignedMalloc(blockSize, capacity)) MarkedBlock(allocator, capacity, cellSize, needsDestruction);
 }
 
-MarkedBlock::MarkedBlock(Region* region, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
-    : HeapBlock<MarkedBlock>(region)
+void MarkedBlock::destroy(MarkedBlock* block)
+{
+    block->~MarkedBlock();
+    fastAlignedFree(block);
+}
+
+MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t capacity, size_t cellSize, bool needsDestruction)
+    : DoublyLinkedListNode<MarkedBlock>()
     , m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
-    , m_endAtom((allocator->cellSize() ? atomsPerBlock : region->blockSize() / atomSize) - m_atomsPerCell + 1)
-    , m_destructorType(destructorType)
+    , m_endAtom((allocator->cellSize() ? atomsPerBlock - m_atomsPerCell : firstAtom()) + 1)
+    , m_capacity(capacity)
+    , m_needsDestruction(needsDestruction)
     , m_allocator(allocator)
     , m_state(New) // All cells start out unmarked.
-    , m_weakSet(allocator->heap()->vm())
+    , m_weakSet(allocator->heap()->vm(), *this)
 {
     ASSERT(allocator);
     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
 }
 
-template<MarkedBlock::DestructorType dtorType>
 inline void MarkedBlock::callDestructor(JSCell* cell)
 {
     // A previous eager sweep may already have run cell's destructor.
     if (cell->isZapped())
         return;
 
-    if (dtorType == MarkedBlock::Normal)
-        jsCast<JSDestructibleObject*>(cell)->classInfo()->methodTable.destroy(cell);
-    else
+    ASSERT(cell->structureID());
+    if (cell->inlineTypeFlags() & StructureIsImmortal)
         cell->structure(*vm())->classInfo()->methodTable.destroy(cell);
+    else
+        jsCast<JSDestructibleObject*>(cell)->classInfo()->methodTable.destroy(cell);
     cell->zap();
 }
 
-template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, MarkedBlock::DestructorType dtorType>
+template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool callDestructors>
 MarkedBlock::FreeList MarkedBlock::specializedSweep()
 {
     ASSERT(blockState != Allocated && blockState != FreeListed);
-    ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly));
+    ASSERT(!(!callDestructors && sweepMode == SweepOnly));
 
+    SamplingRegion samplingRegion((!callDestructors && blockState != New) ? "Calling destructors" : "sweeping");
+    
     // This produces a free list that is ordered in reverse through the block.
     // This is fine, since the allocation code makes no assumptions about the
     // order of the free list.
@@ -85,8 +91,8 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
 
         JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
 
-        if (dtorType != MarkedBlock::None && blockState != New)
-            callDestructor<dtorType>(cell);
+        if (callDestructors && blockState != New)
+            callDestructor(cell);
 
         if (sweepMode == SweepToFreeList) {
             FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell);
@@ -99,7 +105,7 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
     // We only want to discard the newlyAllocated bits if we're creating a FreeList,
     // otherwise we would lose information on what's currently alive.
     if (sweepMode == SweepToFreeList && m_newlyAllocated)
-        m_newlyAllocated.clear();
+        m_newlyAllocated = nullptr;
 
     m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked);
     return FreeList(head, count * cellSize());
@@ -107,28 +113,25 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
 
 MarkedBlock::FreeList MarkedBlock::sweep(SweepMode sweepMode)
 {
-    ASSERT(DelayedReleaseScope::isInEffectFor(heap()->m_objectSpace));
     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
 
     m_weakSet.sweep();
 
-    if (sweepMode == SweepOnly && m_destructorType == MarkedBlock::None)
+    if (sweepMode == SweepOnly && !m_needsDestruction)
         return FreeList();
 
-    if (m_destructorType == MarkedBlock::ImmortalStructure)
-        return sweepHelper<MarkedBlock::ImmortalStructure>(sweepMode);
-    if (m_destructorType == MarkedBlock::Normal)
-        return sweepHelper<MarkedBlock::Normal>(sweepMode);
-    return sweepHelper<MarkedBlock::None>(sweepMode);
+    if (m_needsDestruction)
+        return sweepHelper<true>(sweepMode);
+    return sweepHelper<false>(sweepMode);
 }
 
-template<MarkedBlock::DestructorType dtorType>
+template<bool callDestructors>
 MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
 {
     switch (m_state) {
     case New:
         ASSERT(sweepMode == SweepToFreeList);
-        return specializedSweep<New, SweepToFreeList, dtorType>();
+        return specializedSweep<New, SweepToFreeList, callDestructors>();
     case FreeListed:
         // Happens when a block transitions to fully allocated.
         ASSERT(sweepMode == SweepToFreeList);
@@ -139,8 +142,8 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
         return FreeList();
     case Marked:
         return sweepMode == SweepToFreeList
-            ? specializedSweep<Marked, SweepToFreeList, dtorType>()
-            : specializedSweep<Marked, SweepOnly, dtorType>();
+            ? specializedSweep<Marked, SweepToFreeList, callDestructors>()
+            : specializedSweep<Marked, SweepOnly, callDestructors>();
     }
 
     RELEASE_ASSERT_NOT_REACHED();
@@ -154,10 +157,11 @@ public:
     {
     }
 
-    void operator()(JSCell* cell)
+    IterationStatus operator()(JSCell* cell)
     {
         ASSERT(MarkedBlock::blockFor(cell) == m_block);
         m_block->setNewlyAllocated(cell);
+        return IterationStatus::Continue;
     }
 
 private:
@@ -187,7 +191,7 @@ void MarkedBlock::stopAllocating(const FreeList& freeList)
     // way to tell what's live vs dead. 
     
     ASSERT(!m_newlyAllocated);
-    m_newlyAllocated = adoptPtr(new WTF::Bitmap<atomsPerBlock>());
+    m_newlyAllocated = std::make_unique<WTF::Bitmap<atomsPerBlock>>();
 
     SetNewlyAllocatedFunctor functor(this);
     forEachCell(functor);
@@ -214,11 +218,6 @@ void MarkedBlock::clearMarks()
 #endif
 }
 
-void MarkedBlock::clearRememberedSet()
-{
-    m_rememberedSet.clearAll();
-}
-
 template <HeapOperation collectionType>
 void MarkedBlock::clearMarksWithCollectionType()
 {
@@ -228,9 +227,6 @@ void MarkedBlock::clearMarksWithCollectionType()
     ASSERT(m_state != New && m_state != FreeListed);
     if (collectionType == FullCollection) {
         m_marks.clearAll();
-#if ENABLE(GGC)
-        m_rememberedSet.clearAll();
-#endif
         // This will become true at the end of the mark phase. We set it now to
         // avoid an extra pass to do so later.
         m_state = Marked;
index f2626b70bc1dec14241790f821451aefdf392002..839099da04eb44d07ad13616d269a1bbf686b951 100644 (file)
 #ifndef MarkedBlock_h
 #define MarkedBlock_h
 
-#include "BlockAllocator.h"
-#include "HeapBlock.h"
-
 #include "HeapOperation.h"
+#include "IterationStatus.h"
 #include "WeakSet.h"
 #include <wtf/Bitmap.h>
 #include <wtf/DataLog.h>
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/HashFunctions.h>
-#include <wtf/PageAllocationAligned.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
 
@@ -69,13 +66,14 @@ namespace JSC {
     // size is equal to the difference between the cell size and the object
     // size.
 
-    class MarkedBlock : public HeapBlock<MarkedBlock> {
+    class MarkedBlock : public DoublyLinkedListNode<MarkedBlock> {
+        friend class WTF::DoublyLinkedListNode<MarkedBlock>;
         friend class LLIntOffsetsExtractor;
         friend struct VerifyMarkedOrRetired;
     public:
         static const size_t atomSize = 16; // bytes
         static const size_t atomShiftAmount = 4; // log_2(atomSize) FIXME: Change atomSize to 16.
-        static const size_t blockSize = 64 * KB;
+        static const size_t blockSize = 16 * KB;
         static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
 
         static const size_t atomsPerBlock = blockSize / atomSize;
@@ -112,8 +110,8 @@ namespace JSC {
             ReturnType m_count;
         };
 
-        enum DestructorType { None, ImmortalStructure, Normal };
-        static MarkedBlock* create(DeadBlock*, MarkedAllocator*, size_t cellSize, DestructorType);
+        static MarkedBlock* create(MarkedAllocator*, size_t capacity, size_t cellSize, bool needsDestruction);
+        static void destroy(MarkedBlock*);
 
         static bool isAtomAligned(const void*);
         static MarkedBlock* blockFor(const void*);
@@ -147,7 +145,6 @@ namespace JSC {
         // and was successfully cleared and false otherwise.
         bool clearNewlyAllocated();
         void clearMarks();
-        void clearRememberedSet();
         template <HeapOperation collectionType>
         void clearMarksWithCollectionType();
 
@@ -155,7 +152,7 @@ namespace JSC {
         bool isEmpty();
 
         size_t cellSize();
-        DestructorType destructorType();
+        bool needsDestruction() const;
 
         size_t size();
         size_t capacity();
@@ -164,6 +161,7 @@ namespace JSC {
         bool testAndSetMarked(const void*);
         bool isLive(const JSCell*);
         bool isLiveCell(const void*);
+        bool isMarkedOrNewlyAllocated(const JSCell*);
         void setMarked(const void*);
         void clearMarked(const void*);
 
@@ -176,13 +174,14 @@ namespace JSC {
         void setNewlyAllocated(const void*);
         void clearNewlyAllocated(const void*);
 
+        bool isAllocated() const;
         bool needsSweeping();
         void didRetireBlock(const FreeList&);
         void willRemoveBlock();
 
-        template <typename Functor> void forEachCell(Functor&);
-        template <typename Functor> void forEachLiveCell(Functor&);
-        template <typename Functor> void forEachDeadCell(Functor&);
+        template <typename Functor> IterationStatus forEachCell(Functor&);
+        template <typename Functor> IterationStatus forEachLiveCell(Functor&);
+        template <typename Functor> IterationStatus forEachDeadCell(Functor&);
 
         static ptrdiff_t offsetOfMarks() { return OBJECT_OFFSETOF(MarkedBlock, m_marks); }
 
@@ -190,28 +189,30 @@ namespace JSC {
         static const size_t atomAlignmentMask = atomSize - 1; // atomSize must be a power of two.
 
         enum BlockState { New, FreeListed, Allocated, Marked, Retired };
-        template<DestructorType> FreeList sweepHelper(SweepMode = SweepOnly);
+        template<bool callDestructors> FreeList sweepHelper(SweepMode = SweepOnly);
 
         typedef char Atom[atomSize];
 
-        MarkedBlock(Region*, MarkedAllocator*, size_t cellSize, DestructorType);
+        MarkedBlock(MarkedAllocator*, size_t capacity, size_t cellSize, bool needsDestruction);
         Atom* atoms();
         size_t atomNumber(const void*);
-        template<DestructorType> void callDestructor(JSCell*);
-        template<BlockState, SweepMode, DestructorType> FreeList specializedSweep();
+        void callDestructor(JSCell*);
+        template<BlockState, SweepMode, bool callDestructors> FreeList specializedSweep();
         
+        MarkedBlock* m_prev;
+        MarkedBlock* m_next;
+
         size_t m_atomsPerCell;
         size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom.
 #if ENABLE(PARALLEL_GC)
         WTF::Bitmap<atomsPerBlock, WTF::BitmapAtomic, uint8_t> m_marks;
-        WTF::Bitmap<atomsPerBlock, WTF::BitmapAtomic, uint8_t> m_rememberedSet;
 #else
         WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic, uint8_t> m_marks;
-        WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic, uint8_t> m_rememberedSet;
 #endif
-        OwnPtr<WTF::Bitmap<atomsPerBlock>> m_newlyAllocated;
+        std::unique_ptr<WTF::Bitmap<atomsPerBlock>> m_newlyAllocated;
 
-        DestructorType m_destructorType;
+        size_t m_capacity;
+        bool m_needsDestruction;
         MarkedAllocator* m_allocator;
         BlockState m_state;
         WeakSet m_weakSet;
@@ -321,9 +322,9 @@ namespace JSC {
         return m_atomsPerCell * atomSize;
     }
 
-    inline MarkedBlock::DestructorType MarkedBlock::destructorType()
+    inline bool MarkedBlock::needsDestruction() const
     {
-        return m_destructorType; 
+        return m_needsDestruction;
     }
 
     inline size_t MarkedBlock::size()
@@ -333,7 +334,7 @@ namespace JSC {
 
     inline size_t MarkedBlock::capacity()
     {
-        return region()->blockSize();
+        return m_capacity;
     }
 
     inline size_t MarkedBlock::atomNumber(const void* p)
@@ -341,26 +342,6 @@ namespace JSC {
         return (reinterpret_cast<Bits>(p) - reinterpret_cast<Bits>(this)) / atomSize;
     }
 
-    inline void MarkedBlock::setRemembered(const void* p)
-    {
-        m_rememberedSet.set(atomNumber(p));
-    }
-
-    inline void MarkedBlock::clearRemembered(const void* p)
-    {
-        m_rememberedSet.clear(atomNumber(p));
-    }
-
-    inline void MarkedBlock::atomicClearRemembered(const void* p)
-    {
-        m_rememberedSet.concurrentTestAndClear(atomNumber(p));
-    }
-
-    inline bool MarkedBlock::isRemembered(const void* p)
-    {
-        return m_rememberedSet.get(atomNumber(p));
-    }
-
     inline bool MarkedBlock::isMarked(const void* p)
     {
         return m_marks.get(atomNumber(p));
@@ -400,12 +381,18 @@ namespace JSC {
     inline bool MarkedBlock::clearNewlyAllocated()
     {
         if (m_newlyAllocated) {
-            m_newlyAllocated.clear();
+            m_newlyAllocated = nullptr;
             return true;
         }
         return false;
     }
 
+    inline bool MarkedBlock::isMarkedOrNewlyAllocated(const JSCell* cell)
+    {
+        ASSERT(m_state == Retired || m_state == Marked);
+        return m_marks.get(atomNumber(cell)) || (m_newlyAllocated && isNewlyAllocated(cell));
+    }
+
     inline bool MarkedBlock::isLive(const JSCell* cell)
     {
         switch (m_state) {
@@ -414,7 +401,7 @@ namespace JSC {
 
         case Retired:
         case Marked:
-            return m_marks.get(atomNumber(cell)) || (m_newlyAllocated && isNewlyAllocated(cell));
+            return isMarkedOrNewlyAllocated(cell);
 
         case New:
         case FreeListed:
@@ -441,34 +428,40 @@ namespace JSC {
         return isLive(static_cast<const JSCell*>(p));
     }
 
-    template <typename Functor> inline void MarkedBlock::forEachCell(Functor& functor)
+    template <typename Functor> inline IterationStatus MarkedBlock::forEachCell(Functor& functor)
     {
         for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
             JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
-            functor(cell);
+            if (functor(cell) == IterationStatus::Done)
+                return IterationStatus::Done;
         }
+        return IterationStatus::Continue;
     }
 
-    template <typename Functor> inline void MarkedBlock::forEachLiveCell(Functor& functor)
+    template <typename Functor> inline IterationStatus MarkedBlock::forEachLiveCell(Functor& functor)
     {
         for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
             JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
             if (!isLive(cell))
                 continue;
 
-            functor(cell);
+            if (functor(cell) == IterationStatus::Done)
+                return IterationStatus::Done;
         }
+        return IterationStatus::Continue;
     }
 
-    template <typename Functor> inline void MarkedBlock::forEachDeadCell(Functor& functor)
+    template <typename Functor> inline IterationStatus MarkedBlock::forEachDeadCell(Functor& functor)
     {
         for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
             JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
             if (isLive(cell))
                 continue;
 
-            functor(cell);
+            if (functor(cell) == IterationStatus::Done)
+                return IterationStatus::Done;
         }
+        return IterationStatus::Continue;
     }
 
     inline bool MarkedBlock::needsSweeping()
@@ -476,6 +469,11 @@ namespace JSC {
         return m_state == Marked;
     }
 
+    inline bool MarkedBlock::isAllocated() const
+    {
+        return m_state == Allocated;
+    }
+
 } // namespace JSC
 
 namespace WTF {
index 022a173899570888760e03b79138201b27e769a0..9cf19088ccd25e7bd12e18dcc2b94e32cda22db2 100644 (file)
@@ -57,7 +57,7 @@ inline void MarkedBlockSet::add(MarkedBlock* block)
 
 inline void MarkedBlockSet::remove(MarkedBlock* block)
 {
-    int oldCapacity = m_set.capacity();
+    unsigned oldCapacity = m_set.capacity();
     m_set.remove(block);
     if (m_set.capacity() != oldCapacity) // Indicates we've removed a lot of blocks.
         recomputeFilter();
index 8a8fbf6b8d5931b94dc2044af9b4cebc30c03c19..4f308900f2307defeb56a45206e36f0993e68446 100644 (file)
@@ -21,7 +21,6 @@
 #include "config.h"
 #include "MarkedSpace.h"
 
-#include "DelayedReleaseScope.h"
 #include "IncrementalSweeper.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
@@ -82,23 +81,19 @@ MarkedSpace::MarkedSpace(Heap* heap)
     : m_heap(heap)
     , m_capacity(0)
     , m_isIterating(false)
-    , m_currentDelayedReleaseScope(nullptr)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
-        allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
-        normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
-        immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
-        allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
-        normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
-        immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
     }
 
-    m_normalSpace.largeAllocator.init(heap, this, 0, MarkedBlock::None);
-    m_normalDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::Normal);
-    m_immortalStructureDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::ImmortalStructure);
+    m_normalSpace.largeAllocator.init(heap, this, 0, false);
+    m_destructorSpace.largeAllocator.init(heap, this, 0, true);
 }
 
 MarkedSpace::~MarkedSpace()
@@ -114,15 +109,12 @@ struct LastChanceToFinalize {
 
 void MarkedSpace::lastChanceToFinalize()
 {
-    DelayedReleaseScope delayedReleaseScope(*this);
     stopAllocating();
     forEachAllocator<LastChanceToFinalize>();
 }
 
 void MarkedSpace::sweep()
 {
-    if (Options::logGC())
-        dataLog("Eagerly sweeping...");
     m_heap->sweeper()->willFinishSweeping();
     forEachBlock<Sweep>();
 }
@@ -139,19 +131,16 @@ void MarkedSpace::resetAllocators()
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         allocatorFor(cellSize).reset();
-        normalDestructorAllocatorFor(cellSize).reset();
-        immortalStructureDestructorAllocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         allocatorFor(cellSize).reset();
-        normalDestructorAllocatorFor(cellSize).reset();
-        immortalStructureDestructorAllocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
     }
 
     m_normalSpace.largeAllocator.reset();
-    m_normalDestructorSpace.largeAllocator.reset();
-    m_immortalStructureDestructorSpace.largeAllocator.reset();
+    m_destructorSpace.largeAllocator.reset();
 
 #if ENABLE(GGC)
     m_blocksWithNewObjects.clear();
@@ -189,19 +178,16 @@ void MarkedSpace::forEachAllocator(Functor& functor)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         functor(allocatorFor(cellSize));
-        functor(normalDestructorAllocatorFor(cellSize));
-        functor(immortalStructureDestructorAllocatorFor(cellSize));
+        functor(destructorAllocatorFor(cellSize));
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         functor(allocatorFor(cellSize));
-        functor(normalDestructorAllocatorFor(cellSize));
-        functor(immortalStructureDestructorAllocatorFor(cellSize));
+        functor(destructorAllocatorFor(cellSize));
     }
 
     functor(m_normalSpace.largeAllocator);
-    functor(m_normalDestructorSpace.largeAllocator);
-    functor(m_immortalStructureDestructorSpace.largeAllocator);
+    functor(m_destructorSpace.largeAllocator);
 }
 
 struct StopAllocatingFunctor {
@@ -228,21 +214,18 @@ bool MarkedSpace::isPagedOut(double deadline)
 {
     for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
         if (allocatorFor(cellSize).isPagedOut(deadline) 
-            || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 
-            || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
+            || destructorAllocatorFor(cellSize).isPagedOut(deadline))
             return true;
     }
 
     for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
         if (allocatorFor(cellSize).isPagedOut(deadline) 
-            || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 
-            || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
+            || destructorAllocatorFor(cellSize).isPagedOut(deadline))
             return true;
     }
 
     if (m_normalSpace.largeAllocator.isPagedOut(deadline)
-        || m_normalDestructorSpace.largeAllocator.isPagedOut(deadline)
-        || m_immortalStructureDestructorSpace.largeAllocator.isPagedOut(deadline))
+        || m_destructorSpace.largeAllocator.isPagedOut(deadline))
         return true;
 
     return false;
@@ -253,11 +236,7 @@ void MarkedSpace::freeBlock(MarkedBlock* block)
     block->allocator()->removeBlock(block);
     m_capacity -= block->capacity();
     m_blocks.remove(block);
-    if (block->capacity() == MarkedBlock::blockSize) {
-        m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block));
-        return;
-    }
-    m_heap->blockAllocator().deallocateCustomSize(MarkedBlock::destroy(block));
+    MarkedBlock::destroy(block);
 }
 
 void MarkedSpace::freeOrShrinkBlock(MarkedBlock* block)
@@ -301,14 +280,12 @@ void MarkedSpace::clearNewlyAllocated()
 {
     for (size_t i = 0; i < preciseCount; ++i) {
         clearNewlyAllocatedInBlock(m_normalSpace.preciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_normalDestructorSpace.preciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_immortalStructureDestructorSpace.preciseAllocators[i].takeLastActiveBlock());
+        clearNewlyAllocatedInBlock(m_destructorSpace.preciseAllocators[i].takeLastActiveBlock());
     }
 
     for (size_t i = 0; i < impreciseCount; ++i) {
         clearNewlyAllocatedInBlock(m_normalSpace.impreciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_normalDestructorSpace.impreciseAllocators[i].takeLastActiveBlock());
-        clearNewlyAllocatedInBlock(m_immortalStructureDestructorSpace.impreciseAllocators[i].takeLastActiveBlock());
+        clearNewlyAllocatedInBlock(m_destructorSpace.impreciseAllocators[i].takeLastActiveBlock());
     }
 
     // We have to iterate all of the blocks in the large allocators because they are
@@ -316,8 +293,7 @@ void MarkedSpace::clearNewlyAllocated()
     // which creates the m_newlyAllocated bitmap.
     ClearNewlyAllocated functor;
     m_normalSpace.largeAllocator.forEachBlock(functor);
-    m_normalDestructorSpace.largeAllocator.forEachBlock(functor);
-    m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor);
+    m_destructorSpace.largeAllocator.forEachBlock(functor);
 
 #ifndef NDEBUG
     VerifyNewlyAllocated verifyFunctor;
@@ -364,7 +340,6 @@ void MarkedSpace::willStartIterating()
 void MarkedSpace::didFinishIterating()
 {
     ASSERT(isIterating());
-    DelayedReleaseScope scope(*this);
     resumeAllocating();
     m_isIterating = false;
 }
index 253d2f1454d4761bd0c7e6cc65e7da2d528cb704..bb388dd703248e1087b288570a327c3a8fe8f229 100644 (file)
 #include "MarkedBlock.h"
 #include "MarkedBlockSet.h"
 #include <array>
-#include <wtf/PageAllocationAligned.h>
 #include <wtf/Bitmap.h>
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
 
-class DelayedReleaseScope;
 class Heap;
 class HeapIterationScope;
 class JSCell;
@@ -52,13 +51,6 @@ struct ClearMarks : MarkedBlock::VoidFunctor {
     }
 };
 
-struct ClearRememberedSet : MarkedBlock::VoidFunctor {
-    void operator()(MarkedBlock* block)
-    {
-        block->clearRememberedSet();
-    }
-};
-
 struct Sweep : MarkedBlock::VoidFunctor {
     void operator()(MarkedBlock* block) { block->sweep(); }
 };
@@ -82,18 +74,35 @@ struct Size : MarkedBlock::CountFunctor {
 class MarkedSpace {
     WTF_MAKE_NONCOPYABLE(MarkedSpace);
 public:
+    // [ 32... 128 ]
+    static const size_t preciseStep = MarkedBlock::atomSize;
+    static const size_t preciseCutoff = 128;
+    static const size_t preciseCount = preciseCutoff / preciseStep;
+
+    // [ 1024... blockSize ]
+    static const size_t impreciseStep = 2 * preciseCutoff;
+    static const size_t impreciseCutoff = MarkedBlock::blockSize / 2;
+    static const size_t impreciseCount = impreciseCutoff / impreciseStep;
+
+    struct Subspace {
+        std::array<MarkedAllocator, preciseCount> preciseAllocators;
+        std::array<MarkedAllocator, impreciseCount> impreciseAllocators;
+        MarkedAllocator largeAllocator;
+    };
+
     MarkedSpace(Heap*);
     ~MarkedSpace();
     void lastChanceToFinalize();
 
     MarkedAllocator& firstAllocator();
     MarkedAllocator& allocatorFor(size_t);
-    MarkedAllocator& immortalStructureDestructorAllocatorFor(size_t);
-    MarkedAllocator& normalDestructorAllocatorFor(size_t);
-    void* allocateWithNormalDestructor(size_t);
-    void* allocateWithImmortalStructureDestructor(size_t);
+    MarkedAllocator& destructorAllocatorFor(size_t);
+    void* allocateWithDestructor(size_t);
     void* allocateWithoutDestructor(size_t);
+
+    Subspace& subspaceForObjectsWithDestructor() { return m_destructorSpace; }
+    Subspace& subspaceForObjectsWithoutDestructor() { return m_normalSpace; }
+
     void resetAllocators();
 
     void visitWeakSets(HeapRootVisitor&);
@@ -126,7 +135,6 @@ public:
     void didAllocateInBlock(MarkedBlock*);
 
     void clearMarks();
-    void clearRememberedSet();
     void clearNewlyAllocated();
     void sweep();
     void zombifySweep();
@@ -140,31 +148,16 @@ public:
     template<typename T> void releaseSoon(RetainPtr<T>&&);
 #endif
 
+    const Vector<MarkedBlock*>& blocksWithNewObjects() const { return m_blocksWithNewObjects; }
+
 private:
-    friend class DelayedReleaseScope;
     friend class LLIntOffsetsExtractor;
+    friend class JIT;
 
     template<typename Functor> void forEachAllocator(Functor&);
     template<typename Functor> void forEachAllocator();
 
-    // [ 32... 128 ]
-    static const size_t preciseStep = MarkedBlock::atomSize;
-    static const size_t preciseCutoff = 128;
-    static const size_t preciseCount = preciseCutoff / preciseStep;
-
-    // [ 1024... blockSize ]
-    static const size_t impreciseStep = 2 * preciseCutoff;
-    static const size_t impreciseCutoff = MarkedBlock::blockSize / 2;
-    static const size_t impreciseCount = impreciseCutoff / impreciseStep;
-
-    struct Subspace {
-        std::array<MarkedAllocator, preciseCount> preciseAllocators;
-        std::array<MarkedAllocator, impreciseCount> impreciseAllocators;
-        MarkedAllocator largeAllocator;
-    };
-
-    Subspace m_normalDestructorSpace;
-    Subspace m_immortalStructureDestructorSpace;
+    Subspace m_destructorSpace;
     Subspace m_normalSpace;
 
     Heap* m_heap;
@@ -172,16 +165,16 @@ private:
     bool m_isIterating;
     MarkedBlockSet m_blocks;
     Vector<MarkedBlock*> m_blocksWithNewObjects;
-
-    DelayedReleaseScope* m_currentDelayedReleaseScope;
 };
 
 template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachLiveCell(HeapIterationScope&, Functor& functor)
 {
     ASSERT(isIterating());
     BlockIterator end = m_blocks.set().end();
-    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
-        (*it)->forEachLiveCell(functor);
+    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) {
+        if ((*it)->forEachLiveCell(functor) == IterationStatus::Done)
+            break;
+    }
     return functor.returnValue();
 }
 
@@ -195,8 +188,10 @@ template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forE
 {
     ASSERT(isIterating());
     BlockIterator end = m_blocks.set().end();
-    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
-        (*it)->forEachDeadCell(functor);
+    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) {
+        if ((*it)->forEachDeadCell(functor) == IterationStatus::Done)
+            break;
+    }
     return functor.returnValue();
 }
 
@@ -216,24 +211,14 @@ inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
     return m_normalSpace.largeAllocator;
 }
 
-inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes)
+inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes)
 {
     ASSERT(bytes);
     if (bytes <= preciseCutoff)
-        return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
+        return m_destructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
     if (bytes <= impreciseCutoff)
-        return m_immortalStructureDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
-    return m_immortalStructureDestructorSpace.largeAllocator;
-}
-
-inline MarkedAllocator& MarkedSpace::normalDestructorAllocatorFor(size_t bytes)
-{
-    ASSERT(bytes);
-    if (bytes <= preciseCutoff)
-        return m_normalDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
-    if (bytes <= impreciseCutoff)
-        return m_normalDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
-    return m_normalDestructorSpace.largeAllocator;
+        return m_destructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep];
+    return m_destructorSpace.largeAllocator;
 }
 
 inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes)
@@ -241,14 +226,9 @@ inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes)
     return allocatorFor(bytes).allocate(bytes);
 }
 
-inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes)
-{
-    return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes);
-}
-
-inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes)
+inline void* MarkedSpace::allocateWithDestructor(size_t bytes)
 {
-    return normalDestructorAllocatorFor(bytes).allocate(bytes);
+    return destructorAllocatorFor(bytes).allocate(bytes);
 }
 
 template <typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachBlock(Functor& functor)
@@ -260,16 +240,10 @@ template <typename Functor> inline typename Functor::ReturnType MarkedSpace::for
     m_normalSpace.largeAllocator.forEachBlock(functor);
 
     for (size_t i = 0; i < preciseCount; ++i)
-        m_normalDestructorSpace.preciseAllocators[i].forEachBlock(functor);
-    for (size_t i = 0; i < impreciseCount; ++i)
-        m_normalDestructorSpace.impreciseAllocators[i].forEachBlock(functor);
-    m_normalDestructorSpace.largeAllocator.forEachBlock(functor);
-
-    for (size_t i = 0; i < preciseCount; ++i)
-        m_immortalStructureDestructorSpace.preciseAllocators[i].forEachBlock(functor);
+        m_destructorSpace.preciseAllocators[i].forEachBlock(functor);
     for (size_t i = 0; i < impreciseCount; ++i)
-        m_immortalStructureDestructorSpace.impreciseAllocators[i].forEachBlock(functor);
-    m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor);
+        m_destructorSpace.impreciseAllocators[i].forEachBlock(functor);
+    m_destructorSpace.largeAllocator.forEachBlock(functor);
 
     return functor.returnValue();
 }
@@ -295,11 +269,6 @@ inline void MarkedSpace::didAllocateInBlock(MarkedBlock* block)
 #endif
 }
 
-inline void MarkedSpace::clearRememberedSet()
-{
-    forEachBlock<ClearRememberedSet>();
-}
-
 inline size_t MarkedSpace::objectCount()
 {
     return forEachBlock<MarkCount>();
diff --git a/heap/Region.h b/heap/Region.h
deleted file mode 100644 (file)
index 3255f56..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSC_Region_h
-#define JSC_Region_h
-
-#include "HeapBlock.h"
-#include "SuperRegion.h"
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/MetaAllocatorHandle.h>
-#include <wtf/PageAllocationAligned.h>
-
-#define HEAP_MEMORY_ID reinterpret_cast<void*>(static_cast<intptr_t>(-3))
-
-#define ENABLE_SUPER_REGION 0
-
-#ifndef ENABLE_SUPER_REGION
-#if USE(JSVALUE64) && !CPU(ARM64)
-#define ENABLE_SUPER_REGION 1
-#else
-#define ENABLE_SUPER_REGION 0
-#endif
-#endif
-
-namespace JSC {
-
-class DeadBlock : public HeapBlock<DeadBlock> {
-public:
-    DeadBlock(Region*);
-};
-
-inline DeadBlock::DeadBlock(Region* region)
-    : HeapBlock<DeadBlock>(region)
-{
-}
-
-class Region : public DoublyLinkedListNode<Region> {
-    WTF_MAKE_FAST_ALLOCATED;
-
-    friend class WTF::DoublyLinkedListNode<Region>;
-    friend class BlockAllocator;
-public:
-    ~Region();
-    static Region* create(SuperRegion*, size_t blockSize);
-    static Region* createCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
-    Region* reset(size_t blockSize);
-    void destroy();
-
-    size_t blockSize() const { return m_blockSize; }
-    bool isFull() const { return m_blocksInUse == m_totalBlocks; }
-    bool isEmpty() const { return !m_blocksInUse; }
-    bool isCustomSize() const { return m_isCustomSize; }
-
-    DeadBlock* allocate();
-    void deallocate(void*);
-
-    static const size_t s_regionSize = 64 * KB;
-    static const size_t s_regionMask = ~(s_regionSize - 1);
-
-protected:
-    Region(size_t blockSize, size_t totalBlocks, bool isExcess);
-    void initializeBlockList();
-
-    bool m_isExcess;
-
-private:
-    void* base();
-    size_t size();
-
-    size_t m_totalBlocks;
-    size_t m_blocksInUse;
-    size_t m_blockSize;
-    bool m_isCustomSize;
-    Region* m_prev;
-    Region* m_next;
-    DoublyLinkedList<DeadBlock> m_deadBlocks;
-};
-
-
-class NormalRegion : public Region {
-    friend class Region;
-private:
-    NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle>, size_t blockSize, size_t totalBlocks);
-
-    static NormalRegion* tryCreate(SuperRegion*, size_t blockSize);
-    static NormalRegion* tryCreateCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
-
-    void* base() { return m_allocation->start(); }
-    size_t size() { return m_allocation->sizeInBytes(); }
-
-    NormalRegion* reset(size_t blockSize);
-
-    RefPtr<WTF::MetaAllocatorHandle> m_allocation;
-};
-
-class ExcessRegion : public Region {
-    friend class Region;
-private:
-    ExcessRegion(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
-
-    ~ExcessRegion();
-
-    static ExcessRegion* create(size_t blockSize);
-    static ExcessRegion* createCustomSize(size_t blockSize, size_t blockAlignment);
-
-    void* base() { return m_allocation.base(); }
-    size_t size() { return m_allocation.size(); }
-
-    ExcessRegion* reset(size_t blockSize);
-
-    PageAllocationAligned m_allocation;
-};
-
-inline NormalRegion::NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle> allocation, size_t blockSize, size_t totalBlocks)
-    : Region(blockSize, totalBlocks, false)
-    , m_allocation(allocation)
-{
-    initializeBlockList();
-}
-
-inline NormalRegion* NormalRegion::tryCreate(SuperRegion* superRegion, size_t blockSize)
-{
-    RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(s_regionSize, HEAP_MEMORY_ID);
-    if (!allocation)
-        return 0;
-    return new NormalRegion(allocation, blockSize, s_regionSize / blockSize);
-}
-
-inline NormalRegion* NormalRegion::tryCreateCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
-{
-    ASSERT_UNUSED(blockAlignment, blockAlignment <= s_regionSize);
-    RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(blockSize, HEAP_MEMORY_ID);
-    if (!allocation)
-        return 0;
-    return new NormalRegion(allocation, blockSize, 1);
-}
-
-inline NormalRegion* NormalRegion::reset(size_t blockSize)
-{
-    ASSERT(!m_isExcess);
-    RefPtr<WTF::MetaAllocatorHandle> allocation = m_allocation.release();
-    return new (NotNull, this) NormalRegion(allocation.release(), blockSize, s_regionSize / blockSize);
-}
-
-inline ExcessRegion::ExcessRegion(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
-    : Region(blockSize, totalBlocks, true)
-    , m_allocation(allocation)
-{
-    initializeBlockList();
-}
-
-inline ExcessRegion::~ExcessRegion()
-{
-    m_allocation.deallocate();
-}
-
-inline ExcessRegion* ExcessRegion::create(size_t blockSize)
-{
-    PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
-    ASSERT(static_cast<bool>(allocation));
-    return new ExcessRegion(allocation, blockSize, s_regionSize / blockSize); 
-}
-
-inline ExcessRegion* ExcessRegion::createCustomSize(size_t blockSize, size_t blockAlignment)
-{
-    PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
-    ASSERT(static_cast<bool>(allocation));
-    return new ExcessRegion(allocation, blockSize, 1);
-}
-
-inline ExcessRegion* ExcessRegion::reset(size_t blockSize)
-{
-    ASSERT(m_isExcess);
-    PageAllocationAligned allocation = m_allocation;
-    return new (NotNull, this) ExcessRegion(allocation, blockSize, s_regionSize / blockSize);
-}
-
-inline Region::Region(size_t blockSize, size_t totalBlocks, bool isExcess)
-    : DoublyLinkedListNode<Region>()
-    , m_isExcess(isExcess)
-    , m_totalBlocks(totalBlocks)
-    , m_blocksInUse(0)
-    , m_blockSize(blockSize)
-    , m_isCustomSize(false)
-    , m_prev(0)
-    , m_next(0)
-{
-}
-
-inline void Region::initializeBlockList()
-{
-    char* start = static_cast<char*>(base());
-    char* current = start;
-    for (size_t i = 0; i < m_totalBlocks; i++) {
-        ASSERT(current < start + size());
-        m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
-        current += m_blockSize;
-    }
-}
-
-inline Region* Region::create(SuperRegion* superRegion, size_t blockSize)
-{
-#if ENABLE(SUPER_REGION)
-    ASSERT(blockSize <= s_regionSize);
-    ASSERT(!(s_regionSize % blockSize));
-    Region* region = NormalRegion::tryCreate(superRegion, blockSize);
-    if (LIKELY(!!region))
-        return region;
-#else
-    UNUSED_PARAM(superRegion);
-#endif
-    return ExcessRegion::create(blockSize);
-}
-
-inline Region* Region::createCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
-{
-#if ENABLE(SUPER_REGION)
-    Region* region = NormalRegion::tryCreateCustomSize(superRegion, blockSize, blockAlignment);
-    if (UNLIKELY(!region))
-        region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
-#else
-    UNUSED_PARAM(superRegion);
-    Region* region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
-#endif
-    region->m_isCustomSize = true;
-    return region;
-}
-
-inline Region::~Region()
-{
-    ASSERT(isEmpty());
-}
-
-inline void Region::destroy()
-{
-#if ENABLE(SUPER_REGION)
-    if (UNLIKELY(m_isExcess))
-        delete static_cast<ExcessRegion*>(this);
-    else
-        delete static_cast<NormalRegion*>(this);
-#else
-    delete static_cast<ExcessRegion*>(this);
-#endif
-}
-
-inline Region* Region::reset(size_t blockSize)
-{
-#if ENABLE(SUPER_REGION)
-    ASSERT(isEmpty());
-    if (UNLIKELY(m_isExcess))
-        return static_cast<ExcessRegion*>(this)->reset(blockSize);
-    return static_cast<NormalRegion*>(this)->reset(blockSize);
-#else
-    return static_cast<ExcessRegion*>(this)->reset(blockSize);
-#endif
-}
-
-inline DeadBlock* Region::allocate()
-{
-    ASSERT(!isFull());
-    m_blocksInUse++;
-    return m_deadBlocks.removeHead();
-}
-
-inline void Region::deallocate(void* base)
-{
-    ASSERT(base);
-    ASSERT(m_blocksInUse);
-    ASSERT(base >= this->base() && base < static_cast<char*>(this->base()) + size());
-    DeadBlock* block = new (NotNull, base) DeadBlock(this);
-    m_deadBlocks.push(block);
-    m_blocksInUse--;
-}
-
-inline void* Region::base()
-{
-#if ENABLE(SUPER_REGION)
-    if (UNLIKELY(m_isExcess))
-        return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
-    return static_cast<NormalRegion*>(this)->NormalRegion::base();
-#else
-    return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
-#endif
-}
-
-inline size_t Region::size()
-{
-#if ENABLE(SUPER_REGION)
-    if (UNLIKELY(m_isExcess))
-        return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
-    return static_cast<NormalRegion*>(this)->NormalRegion::size();
-#else
-    return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
-#endif
-}
-
-} // namespace JSC
-
-#endif // JSC_Region_h
index d45c381aac444a76ae56619b1360fb3bb8b600b0..4de496668ce563e5eb9d69db786c957a8831f0e2 100644 (file)
@@ -17,7 +17,7 @@
 namespace JSC {
 
 SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
-    : m_stack(shared.m_vm->heap.blockAllocator())
+    : m_stack()
     , m_bytesVisited(0)
     , m_bytesCopied(0)
     , m_visitCount(0)
index 25e32ea2c8967c790822a948e58c0d9321b2e596..5152be22b4a570646a6373d160f9b23d99ed89c0 100644 (file)
@@ -105,7 +105,7 @@ public:
 
     void copyLater(JSCell*, CopyToken, void*, size_t);
     
-    void reportExtraMemoryUsage(JSCell* owner, size_t);
+    void reportExtraMemoryVisited(JSCell* owner, size_t);
     
     void addWeakReferenceHarvester(WeakReferenceHarvester*);
     void addUnconditionalFinalizer(UnconditionalFinalizer*);
index f3355a58f56146ff9fb6b52b38280044e4cc5c33..1d688f850ebde968effdd8f3fe04e93ef0aa2fab 100644 (file)
@@ -239,8 +239,13 @@ inline void SlotVisitor::copyLater(JSCell* owner, CopyToken token, void* ptr, si
     ASSERT(bytes);
     CopiedBlock* block = CopiedSpace::blockFor(ptr);
     if (block->isOversize()) {
+        ASSERT(bytes <= block->size());
+        // FIXME: We should be able to shrink the allocation if bytes went below the block size.
+        // For now, we just make sure that our accounting of how much memory we are actually using
+        // is correct.
+        // https://bugs.webkit.org/show_bug.cgi?id=144749
+        bytes = block->size();
         m_shared.m_copiedSpace->pin(block);
-        return;
     }
 
     ASSERT(heap()->m_storageSpace.contains(block));
@@ -252,27 +257,9 @@ inline void SlotVisitor::copyLater(JSCell* owner, CopyToken token, void* ptr, si
     }
 }
     
-inline void SlotVisitor::reportExtraMemoryUsage(JSCell* owner, size_t size)
+inline void SlotVisitor::reportExtraMemoryVisited(JSCell* owner, size_t size)
 {
-#if ENABLE(GGC)
-    // We don't want to double-count the extra memory that was reported in previous collections.
-    if (heap()->operationInProgress() == EdenCollection && Heap::isRemembered(owner))
-        return;
-#else
-    UNUSED_PARAM(owner);
-#endif
-
-    size_t* counter = &m_shared.m_vm->heap.m_extraMemoryUsage;
-    
-#if ENABLE(COMPARE_AND_SWAP)
-    for (;;) {
-        size_t oldSize = *counter;
-        if (WTF::weakCompareAndSwapSize(counter, oldSize, oldSize + size))
-            return;
-    }
-#else
-    (*counter) += size;
-#endif
+    heap()->reportExtraMemoryVisited(owner, size);
 }
 
 inline Heap* SlotVisitor::heap() const
index 27ab5d31f997b208846da9644351d2bd32e038cc..5c0f832678cddf9616725f04824a5ab4ab415840 100644 (file)
@@ -84,9 +84,7 @@ public:
 
     bool operator!() const { return !slot() || !*slot(); }
 
-    // This conversion operator allows implicit conversion to bool but not to other integer types.
-    typedef JSValue (HandleBase::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return !!*this ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return !!*this; }
 
     void swap(Strong& other)
     {
diff --git a/heap/SuperRegion.cpp b/heap/SuperRegion.cpp
deleted file mode 100644 (file)
index 157fe2e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "SuperRegion.h"
-
-#include "JSCInlines.h"
-#include "Region.h"
-
-namespace JSC {
-
-const uint64_t SuperRegion::s_fixedHeapMemoryPoolSize = 4 * 1024 * static_cast<uint64_t>(MB);
-
-SuperRegion::SuperRegion()
-    : MetaAllocator(Region::s_regionSize, Region::s_regionSize)
-    , m_reservationBase(0)
-{
-#if ENABLE(SUPER_REGION)
-    // Over-allocate so that we can make sure that we're aligned to the size of Regions.
-    m_reservation = PageReservation::reserve(s_fixedHeapMemoryPoolSize + Region::s_regionSize, OSAllocator::JSGCHeapPages);
-    m_reservationBase = getAlignedBase(m_reservation);
-    addFreshFreeSpace(m_reservationBase, s_fixedHeapMemoryPoolSize);
-#else
-    UNUSED_PARAM(m_reservation);
-    UNUSED_PARAM(m_reservationBase);
-#endif
-}
-
-SuperRegion::~SuperRegion()
-{
-#if ENABLE(SUPER_REGION)
-    m_reservation.deallocate();
-#endif
-}
-
-void* SuperRegion::getAlignedBase(PageReservation& reservation)
-{
-    for (char* current = static_cast<char*>(reservation.base()); current < static_cast<char*>(reservation.base()) + Region::s_regionSize; current += pageSize()) {
-        if (!(reinterpret_cast<size_t>(current) & ~Region::s_regionMask))
-            return current;
-    }
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-void* SuperRegion::allocateNewSpace(size_t&)
-{
-    return 0;
-}
-
-void SuperRegion::notifyNeedPage(void* page)
-{
-    m_reservation.commit(page, Region::s_regionSize);
-}
-
-void SuperRegion::notifyPageIsFree(void* page)
-{
-    m_reservation.decommit(page, Region::s_regionSize);
-}
-
-} // namespace JSC
diff --git a/heap/SuperRegion.h b/heap/SuperRegion.h
deleted file mode 100644 (file)
index e21526b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SuperRegion_h
-#define SuperRegion_h
-
-#include <wtf/MetaAllocator.h>
-#include <wtf/PageBlock.h>
-#include <wtf/PageReservation.h>
-
-namespace JSC {
-
-class VM;
-
-class SuperRegion : public WTF::MetaAllocator {
-public:
-    SuperRegion();
-    virtual ~SuperRegion();
-
-protected:
-    virtual void* allocateNewSpace(size_t&) override;
-    virtual void notifyNeedPage(void*) override;
-    virtual void notifyPageIsFree(void*) override;
-
-private:
-    static const uint64_t s_fixedHeapMemoryPoolSize;
-
-    static void* getAlignedBase(PageReservation&);
-
-    PageReservation m_reservation;
-    void* m_reservationBase;
-};
-
-} // namespace JSC
-
-#endif // SuperRegion_h
index 54127ca00ec4b61bbb56a84d1f52acd28210b844..7c7d86c59225f4c3c2219bdb14f8afe472f5302a 100644 (file)
 
 namespace JSC {
 
-WeakBlock* WeakBlock::create(DeadBlock* block)
+WeakBlock* WeakBlock::create(MarkedBlock& markedBlock)
 {
-    Region* region = block->region();
-    return new (NotNull, block) WeakBlock(region);
+    return new (NotNull, fastMalloc(blockSize)) WeakBlock(markedBlock);
 }
 
-WeakBlock::WeakBlock(Region* region)
-    : HeapBlock<WeakBlock>(region)
+void WeakBlock::destroy(WeakBlock* block)
+{
+    block->~WeakBlock();
+    fastFree(block);
+}
+
+WeakBlock::WeakBlock(MarkedBlock& markedBlock)
+    : DoublyLinkedListNode<WeakBlock>()
+    , m_markedBlock(&markedBlock)
 {
     for (size_t i = 0; i < weakImplCount(); ++i) {
         WeakImpl* weakImpl = &weakImpls()[i];
@@ -76,8 +82,11 @@ void WeakBlock::sweep()
             finalize(weakImpl);
         if (weakImpl->state() == WeakImpl::Deallocated)
             addToFreeList(&sweepResult.freeList, weakImpl);
-        else
+        else {
             sweepResult.blockIsFree = false;
+            if (weakImpl->state() == WeakImpl::Live)
+                sweepResult.blockIsLogicallyEmpty = false;
+        }
     }
 
     m_sweepResult = sweepResult;
@@ -90,6 +99,12 @@ void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
     if (isEmpty())
         return;
 
+    // If this WeakBlock doesn't belong to a MarkedBlock, we won't even be here.
+    ASSERT(m_markedBlock);
+
+    if (m_markedBlock->isAllocated())
+        return;
+
     SlotVisitor& visitor = heapRootVisitor.visitor();
 
     for (size_t i = 0; i < weakImplCount(); ++i) {
@@ -98,7 +113,7 @@ void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
             continue;
 
         const JSValue& jsValue = weakImpl->jsValue();
-        if (Heap::isLive(jsValue.asCell()))
+        if (m_markedBlock->isMarkedOrNewlyAllocated(jsValue.asCell()))
             continue;
 
         WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
@@ -118,12 +133,18 @@ void WeakBlock::reap()
     if (isEmpty())
         return;
 
+    // If this WeakBlock doesn't belong to a MarkedBlock, we won't even be here.
+    ASSERT(m_markedBlock);
+
+    if (m_markedBlock->isAllocated())
+        return;
+
     for (size_t i = 0; i < weakImplCount(); ++i) {
         WeakImpl* weakImpl = &weakImpls()[i];
         if (weakImpl->state() > WeakImpl::Dead)
             continue;
 
-        if (Heap::isLive(weakImpl->jsValue().asCell())) {
+        if (m_markedBlock->isMarkedOrNewlyAllocated(weakImpl->jsValue().asCell())) {
             ASSERT(weakImpl->state() == WeakImpl::Live);
             continue;
         }
index b6b631e27b100049ee5a9b18a13350e086264c75..b829e9dbe26c707b555cc075926cda0d87a84565 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef WeakBlock_h
 #define WeakBlock_h
 
-#include "HeapBlock.h"
+#include <wtf/DoublyLinkedList.h>
 #include "WeakHandleOwner.h"
 #include "WeakImpl.h"
 #include <wtf/DoublyLinkedList.h>
 
 namespace JSC {
 
-class DeadBlock;
 class HeapRootVisitor;
 class JSValue;
+class MarkedBlock;
 class WeakHandleOwner;
 
-class WeakBlock : public HeapBlock<WeakBlock> {
+class WeakBlock : public DoublyLinkedListNode<WeakBlock> {
 public:
     friend class WTF::DoublyLinkedListNode<WeakBlock>;
-    static const size_t blockSize = 4 * KB; // 5% of MarkedBlock size
+    static const size_t blockSize = 1 * KB; // 1/16 of MarkedBlock size
 
     struct FreeCell {
         FreeCell* next;
     };
 
     struct SweepResult {
-        SweepResult();
         bool isNull() const;
 
-        bool blockIsFree;
-        FreeCell* freeList;
+        bool blockIsFree { true };
+        bool blockIsLogicallyEmpty { true };
+        FreeCell* freeList { nullptr };
     };
 
-    static WeakBlock* create(DeadBlock*);
+    static WeakBlock* create(MarkedBlock&);
+    static void destroy(WeakBlock*);
 
     static WeakImpl* asWeakImpl(FreeCell*);
 
     bool isEmpty();
+    bool isLogicallyEmptyButNotFree() const;
 
     void sweep();
     SweepResult takeSweepResult();
@@ -69,27 +71,24 @@ public:
     void reap();
 
     void lastChanceToFinalize();
+    void disconnectMarkedBlock() { m_markedBlock = nullptr; }
 
 private:
     static FreeCell* asFreeCell(WeakImpl*);
 
-    WeakBlock(Region*);
+    explicit WeakBlock(MarkedBlock&);
     WeakImpl* firstWeakImpl();
     void finalize(WeakImpl*);
     WeakImpl* weakImpls();
     size_t weakImplCount();
     void addToFreeList(FreeCell**, WeakImpl*);
 
+    MarkedBlock* m_markedBlock;
+    WeakBlock* m_prev;
+    WeakBlock* m_next;
     SweepResult m_sweepResult;
 };
 
-inline WeakBlock::SweepResult::SweepResult()
-    : blockIsFree(true)
-    , freeList(0)
-{
-    ASSERT(isNull());
-}
-
 inline bool WeakBlock::SweepResult::isNull() const
 {
     return blockIsFree && !freeList; // This state is impossible, so we can use it to mean null.
@@ -138,6 +137,11 @@ inline bool WeakBlock::isEmpty()
     return !m_sweepResult.isNull() && m_sweepResult.blockIsFree;
 }
 
+inline bool WeakBlock::isLogicallyEmptyButNotFree() const
+{
+    return !m_sweepResult.isNull() && !m_sweepResult.blockIsFree && m_sweepResult.blockIsLogicallyEmpty;
+}
+
 } // namespace JSC
 
 #endif // WeakBlock_h
index 556c8515bd23a71117cf866b81dec8a19ec55bb6..1eed8c37ac0a7927e5904d6b122179b327088c78 100644 (file)
@@ -37,15 +37,26 @@ WeakSet::~WeakSet()
     WeakBlock* next = 0;
     for (WeakBlock* block = m_blocks.head(); block; block = next) {
         next = block->next();
-        heap()->blockAllocator().deallocate(WeakBlock::destroy(block));
+        WeakBlock::destroy(block);
     }
     m_blocks.clear();
 }
 
 void WeakSet::sweep()
 {
-    for (WeakBlock* block = m_blocks.head(); block; block = block->next())
+    for (WeakBlock* block = m_blocks.head(); block;) {
+        WeakBlock* nextBlock = block->next();
         block->sweep();
+        if (block->isLogicallyEmptyButNotFree()) {
+            // If this WeakBlock is logically empty, but still has Weaks pointing into it,
+            // we can't destroy it just yet. Detach it from the WeakSet and hand ownership
+            // to the Heap so we don't pin down the entire 64kB MarkedBlock.
+            m_blocks.remove(block);
+            heap()->addLogicallyEmptyWeakBlock(block);
+            block->disconnectMarkedBlock();
+        }
+        block = nextBlock;
+    }
 
     resetAllocator();
 }
@@ -74,7 +85,7 @@ WeakBlock::FreeCell* WeakSet::tryFindAllocator()
 
 WeakBlock::FreeCell* WeakSet::addAllocator()
 {
-    WeakBlock* block = WeakBlock::create(heap()->blockAllocator().allocate<WeakBlock>());
+    WeakBlock* block = WeakBlock::create(m_markedBlock);
     heap()->didAllocate(WeakBlock::blockSize);
     m_blocks.append(block);
     WeakBlock::SweepResult sweepResult = block->takeSweepResult();
@@ -85,7 +96,7 @@ WeakBlock::FreeCell* WeakSet::addAllocator()
 void WeakSet::removeAllocator(WeakBlock* block)
 {
     m_blocks.remove(block);
-    heap()->blockAllocator().deallocate(WeakBlock::destroy(block));
+    WeakBlock::destroy(block);
 }
 
 } // namespace JSC
index a5ddcaffa11a529c7ec077f97d9a70a2e897f1a2..dbde5108bcde94efce7c60a2ae4a349ba8f52f59 100644 (file)
@@ -31,6 +31,7 @@
 namespace JSC {
 
 class Heap;
+class MarkedBlock;
 class WeakImpl;
 
 class WeakSet {
@@ -40,7 +41,7 @@ public:
     static WeakImpl* allocate(JSValue, WeakHandleOwner* = 0, void* context = 0);
     static void deallocate(WeakImpl*);
 
-    WeakSet(VM*);
+    WeakSet(VM*, MarkedBlock&);
     ~WeakSet();
     void lastChanceToFinalize();
 
@@ -65,12 +66,14 @@ private:
     WeakBlock* m_nextAllocator;
     DoublyLinkedList<WeakBlock> m_blocks;
     VM* m_vm;
+    MarkedBlock& m_markedBlock;
 };
 
-inline WeakSet::WeakSet(VM* vm)
+inline WeakSet::WeakSet(VM* vm, MarkedBlock& markedBlock)
     : m_allocator(0)
     , m_nextAllocator(0)
     , m_vm(vm)
+    , m_markedBlock(markedBlock)
 {
 }
 
index 93afa735a58bb818ea5e1e651715e78965176aa6..10b7430ecaef6a208b7e448261597bbb1da0e65e 100644 (file)
@@ -44,7 +44,6 @@ WriteBarrierBuffer::WriteBarrierBuffer(unsigned capacity)
 WriteBarrierBuffer::~WriteBarrierBuffer()
 {
     fastFree(m_buffer);
-    m_buffer = 0;
 }
 
 void WriteBarrierBuffer::flush(Heap& heap)
index 9126bdbe99bf985b165e9dc2c36bc40a8ab59e41..7359083cd92d3f18e3f7770feba487b247fbb841 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,10 +33,7 @@ namespace JSC {
 class Heap;
 class JSCell;
 
-namespace FTL { class LowerDFGToLLVM; }
-
 class WriteBarrierBuffer {
-    friend class FTL::LowerDFGToLLVM;
 public:
     WriteBarrierBuffer(unsigned capacity);
     ~WriteBarrierBuffer();
@@ -45,25 +42,25 @@ public:
     void flush(Heap&);
     void reset();
 
-    static ptrdiff_t currentIndexOffset()
+    unsigned* currentIndexAddress()
     {
-        return OBJECT_OFFSETOF(WriteBarrierBuffer, m_currentIndex);
+        return &m_currentIndex;
     }
 
-    static ptrdiff_t capacityOffset()
+    unsigned capacity() const
     {
-        return OBJECT_OFFSETOF(WriteBarrierBuffer, m_capacity);
+        return m_capacity;
     }
 
-    static ptrdiff_t bufferOffset()
+    JSCell** buffer()
     {
-        return OBJECT_OFFSETOF(WriteBarrierBuffer, m_buffer);
+        return m_buffer;
     }
 
 private:
     unsigned m_currentIndex;
-    unsigned m_capacity;
-    JSCell** m_buffer;
+    const unsigned m_capacity;
+    JSCell** const m_buffer;
 };
 
 } // namespace JSC
index 40790bf5d9e591be0e35f62a451878bcd572c7f6..9ac0ddee2dc90baf818fae3a2d416dd58aa91445 100644 (file)
@@ -31,8 +31,6 @@
 #include "config.h"
 #include "ConsoleMessage.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "IdentifiersFactory.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
@@ -131,60 +129,63 @@ void ConsoleMessage::autogenerateMetadata(JSC::ExecState* state)
     }
 }
 
-static Inspector::TypeBuilder::Console::ConsoleMessage::Source::Enum messageSourceValue(MessageSource source)
+static Inspector::Protocol::Console::ConsoleMessage::Source messageSourceValue(MessageSource source)
 {
     switch (source) {
-    case MessageSource::XML: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::XML;
-    case MessageSource::JS: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Javascript;
-    case MessageSource::Network: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Network;
-    case MessageSource::ConsoleAPI: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::ConsoleAPI;
-    case MessageSource::Storage: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Storage;
-    case MessageSource::AppCache: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Appcache;
-    case MessageSource::Rendering: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Rendering;
-    case MessageSource::CSS: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::CSS;
-    case MessageSource::Security: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Security;
-    case MessageSource::Other: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Other;
+    case MessageSource::XML: return Inspector::Protocol::Console::ConsoleMessage::Source::XML;
+    case MessageSource::JS: return Inspector::Protocol::Console::ConsoleMessage::Source::Javascript;
+    case MessageSource::Network: return Inspector::Protocol::Console::ConsoleMessage::Source::Network;
+    case MessageSource::ConsoleAPI: return Inspector::Protocol::Console::ConsoleMessage::Source::ConsoleAPI;
+    case MessageSource::Storage: return Inspector::Protocol::Console::ConsoleMessage::Source::Storage;
+    case MessageSource::AppCache: return Inspector::Protocol::Console::ConsoleMessage::Source::Appcache;
+    case MessageSource::Rendering: return Inspector::Protocol::Console::ConsoleMessage::Source::Rendering;
+    case MessageSource::CSS: return Inspector::Protocol::Console::ConsoleMessage::Source::CSS;
+    case MessageSource::Security: return Inspector::Protocol::Console::ConsoleMessage::Source::Security;
+    case MessageSource::ContentBlocker: return Inspector::Protocol::Console::ConsoleMessage::Source::ContentBlocker;
+    case MessageSource::Other: return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
     }
-    return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Other;
+    return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
 }
 
-static Inspector::TypeBuilder::Console::ConsoleMessage::Type::Enum messageTypeValue(MessageType type)
+static Inspector::Protocol::Console::ConsoleMessage::Type messageTypeValue(MessageType type)
 {
     switch (type) {
-    case MessageType::Log: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Log;
-    case MessageType::Clear: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Clear;
-    case MessageType::Dir: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Dir;
-    case MessageType::DirXML: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::DirXML;
-    case MessageType::Table: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Table;
-    case MessageType::Trace: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Trace;
-    case MessageType::StartGroup: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::StartGroup;
-    case MessageType::StartGroupCollapsed: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::StartGroupCollapsed;
-    case MessageType::EndGroup: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::EndGroup;
-    case MessageType::Assert: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Assert;
-    case MessageType::Timing: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Timing;
-    case MessageType::Profile: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Profile;
-    case MessageType::ProfileEnd: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::ProfileEnd;
+    case MessageType::Log: return Inspector::Protocol::Console::ConsoleMessage::Type::Log;
+    case MessageType::Clear: return Inspector::Protocol::Console::ConsoleMessage::Type::Clear;
+    case MessageType::Dir: return Inspector::Protocol::Console::ConsoleMessage::Type::Dir;
+    case MessageType::DirXML: return Inspector::Protocol::Console::ConsoleMessage::Type::DirXML;
+    case MessageType::Table: return Inspector::Protocol::Console::ConsoleMessage::Type::Table;
+    case MessageType::Trace: return Inspector::Protocol::Console::ConsoleMessage::Type::Trace;
+    case MessageType::StartGroup: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroup;
+    case MessageType::StartGroupCollapsed: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroupCollapsed;
+    case MessageType::EndGroup: return Inspector::Protocol::Console::ConsoleMessage::Type::EndGroup;
+    case MessageType::Assert: return Inspector::Protocol::Console::ConsoleMessage::Type::Assert;
+    case MessageType::Timing: return Inspector::Protocol::Console::ConsoleMessage::Type::Timing;
+    case MessageType::Profile: return Inspector::Protocol::Console::ConsoleMessage::Type::Profile;
+    case MessageType::ProfileEnd: return Inspector::Protocol::Console::ConsoleMessage::Type::ProfileEnd;
     }
-    return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Log;
+    return Inspector::Protocol::Console::ConsoleMessage::Type::Log;
 }
 
-static Inspector::TypeBuilder::Console::ConsoleMessage::Level::Enum messageLevelValue(MessageLevel level)
+static Inspector::Protocol::Console::ConsoleMessage::Level messageLevelValue(MessageLevel level)
 {
     switch (level) {
-    case MessageLevel::Log: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Log;
-    case MessageLevel::Warning: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Warning;
-    case MessageLevel::Error: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Error;
-    case MessageLevel::Debug: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Debug;
+    case MessageLevel::Log: return Inspector::Protocol::Console::ConsoleMessage::Level::Log;
+    case MessageLevel::Info: return Inspector::Protocol::Console::ConsoleMessage::Level::Info;
+    case MessageLevel::Warning: return Inspector::Protocol::Console::ConsoleMessage::Level::Warning;
+    case MessageLevel::Error: return Inspector::Protocol::Console::ConsoleMessage::Level::Error;
+    case MessageLevel::Debug: return Inspector::Protocol::Console::ConsoleMessage::Level::Debug;
     }
-    return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Log;
+    return Inspector::Protocol::Console::ConsoleMessage::Level::Log;
 }
 
-void ConsoleMessage::addToFrontend(InspectorConsoleFrontendDispatcher* consoleFrontendDispatcher, Inspector::InjectedScriptManager* injectedScriptManager, bool generatePreview)
+void ConsoleMessage::addToFrontend(ConsoleFrontendDispatcher* consoleFrontendDispatcher, InjectedScriptManager* injectedScriptManager, bool generatePreview)
 {
-    RefPtr<Inspector::TypeBuilder::Console::ConsoleMessage> jsonObj = Inspector::TypeBuilder::Console::ConsoleMessage::create()
+    Ref<Inspector::Protocol::Console::ConsoleMessage> jsonObj = Inspector::Protocol::Console::ConsoleMessage::create()
         .setSource(messageSourceValue(m_source))
         .setLevel(messageLevelValue(m_level))
-        .setText(m_message);
+        .setText(m_message)
+        .release();
 
     // FIXME: only send out type for ConsoleAPI source messages.
     jsonObj->setType(messageTypeValue(m_type));
@@ -199,37 +200,39 @@ void ConsoleMessage::addToFrontend(InspectorConsoleFrontendDispatcher* consoleFr
     if (m_arguments && m_arguments->argumentCount()) {
         InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->globalState());
         if (!injectedScript.hasNoValue()) {
-            RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::RemoteObject>> jsonArgs = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::RemoteObject>::create();
+            Ref<Inspector::Protocol::Array<Inspector::Protocol::Runtime::RemoteObject>> jsonArgs = Inspector::Protocol::Array<Inspector::Protocol::Runtime::RemoteObject>::create();
             if (m_type == MessageType::Table && generatePreview && m_arguments->argumentCount()) {
                 Deprecated::ScriptValue table = m_arguments->argumentAt(0);
                 Deprecated::ScriptValue columns = m_arguments->argumentCount() > 1 ? m_arguments->argumentAt(1) : Deprecated::ScriptValue();
-                RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns);
+                RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns);
                 if (!inspectorValue) {
                     ASSERT_NOT_REACHED();
                     return;
                 }
-                jsonArgs->addItem(inspectorValue);
+                jsonArgs->addItem(inspectorValue.copyRef());
+                if (m_arguments->argumentCount() > 1)
+                    jsonArgs->addItem(injectedScript.wrapObject(columns, ASCIILiteral("console"), true));
             } else {
                 for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) {
-                    RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), "console", generatePreview);
+                    RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), ASCIILiteral("console"), generatePreview);
                     if (!inspectorValue) {
                         ASSERT_NOT_REACHED();
                         return;
                     }
-                    jsonArgs->addItem(inspectorValue);
+                    jsonArgs->addItem(inspectorValue.copyRef());
                 }
             }
-            jsonObj->setParameters(jsonArgs);
+            jsonObj->setParameters(WTF::move(jsonArgs));
         }
     }
 
     if (m_callStack)
         jsonObj->setStackTrace(m_callStack->buildInspectorArray());
 
-    consoleFrontendDispatcher->messageAdded(jsonObj);
+    consoleFrontendDispatcher->messageAdded(WTF::move(jsonObj));
 }
 
-void ConsoleMessage::updateRepeatCountInConsole(InspectorConsoleFrontendDispatcher* consoleFrontendDispatcher)
+void ConsoleMessage::updateRepeatCountInConsole(ConsoleFrontendDispatcher* consoleFrontendDispatcher)
 {
     consoleFrontendDispatcher->messageRepeatCountUpdated(m_repeatCount);
 }
@@ -270,7 +273,7 @@ void ConsoleMessage::clear()
         m_message = ASCIILiteral("<message collected>");
 
     if (m_arguments)
-        m_arguments.clear();
+        m_arguments = nullptr;
 }
 
 JSC::ExecState* ConsoleMessage::scriptState() const
@@ -290,5 +293,3 @@ unsigned ConsoleMessage::argumentCount() const
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 2e6c44c924d071c48dcf75be72e631eed8d9a6bd..a73e28630afc9d78d9b9409468fa484539919ce9 100644 (file)
 #ifndef ConsoleMessage_h
 #define ConsoleMessage_h
 
-#if ENABLE(INSPECTOR)
-
 #include "ConsoleTypes.h"
-#include "InspectorJSFrontendDispatchers.h"
+#include "InspectorFrontendDispatchers.h"
 #include <wtf/Forward.h>
 
 namespace JSC {
@@ -57,13 +55,16 @@ public:
     ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments>, JSC::ExecState*, unsigned long requestIdentifier = 0);
     ~ConsoleMessage();
 
-    void addToFrontend(InspectorConsoleFrontendDispatcher*, InjectedScriptManager*, bool generatePreview);
-    void updateRepeatCountInConsole(InspectorConsoleFrontendDispatcher*);
+    void addToFrontend(ConsoleFrontendDispatcher*, InjectedScriptManager*, bool generatePreview);
+    void updateRepeatCountInConsole(ConsoleFrontendDispatcher*);
 
     MessageSource source() const { return m_source; }
     const String& message() const { return m_message; }
     MessageType type() const { return m_type; }
     JSC::ExecState* scriptState() const;
+    const String& url() const { return m_url; }
+    unsigned line() const { return m_line; }
+    unsigned column() const { return m_column; }
 
     void incrementCount() { ++m_repeatCount; }
 
@@ -92,5 +93,3 @@ private:
 } // namespace Inspector
 
 #endif // ConsoleMessage_h
-
-#endif // ENABLE(INSPECTOR)
index bcd691bb1e36bbf62e261c199cb884a93cf5346e..ed32a15982d5d0edb4cf0f7a90d264c5477b22c4 100644 (file)
@@ -29,9 +29,6 @@
 #include "config.h"
 #include "ContentSearchUtilities.h"
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSTypeBuilders.h"
 #include "InspectorValues.h"
 #include "RegularExpression.h"
 #include "Yarr.h"
@@ -121,9 +118,9 @@ std::unique_ptr<Vector<size_t>> lineEndings(const String& text)
     return result;
 }
 
-static PassRefPtr<Inspector::TypeBuilder::GenericTypes::SearchMatch> buildObjectForSearchMatch(size_t lineNumber, const String& lineContent)
+static Ref<Inspector::Protocol::GenericTypes::SearchMatch> buildObjectForSearchMatch(size_t lineNumber, const String& lineContent)
 {
-    return Inspector::TypeBuilder::GenericTypes::SearchMatch::create()
+    return Inspector::Protocol::GenericTypes::SearchMatch::create()
         .setLineNumber(lineNumber)
         .setLineContent(lineContent)
         .release();
@@ -154,15 +151,17 @@ int countRegularExpressionMatches(const JSC::Yarr::RegularExpression& regex, con
     return result;
 }
 
-PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>> searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex)
+Ref<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>> searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex)
 {
-    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>::create();
+    Ref<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>> result = Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>::create();
 
     JSC::Yarr::RegularExpression regex = ContentSearchUtilities::createSearchRegex(query, caseSensitive, isRegex);
     Vector<std::pair<size_t, String>> matches = getRegularExpressionMatchesByLines(regex, text);
 
-    for (const auto& match : matches)
-        result->addItem(buildObjectForSearchMatch(match.first, match.second));
+    for (const auto& match : matches) {
+        Ref<Inspector::Protocol::GenericTypes::SearchMatch> matchObject = buildObjectForSearchMatch(match.first, match.second);
+        result->addItem(WTF::move(matchObject));
+    }
 
     return result;
 }
@@ -181,11 +180,12 @@ static String stylesheetCommentPattern(const String& name)
 
 static String findMagicComment(const String& content, const String& patternString)
 {
+    ASSERT(!content.isNull());
     const char* error = nullptr;
     JSC::Yarr::YarrPattern pattern(patternString, false, true, &error);
     ASSERT(!error);
     BumpPointerAllocator regexAllocator;
-    OwnPtr<JSC::Yarr::BytecodePattern> bytecodePattern = JSC::Yarr::byteCompile(pattern, &regexAllocator);
+    auto bytecodePattern = JSC::Yarr::byteCompile(pattern, &regexAllocator);
     ASSERT(bytecodePattern);
 
     ASSERT(pattern.m_numSubpatterns == 1);
@@ -216,5 +216,3 @@ String findStylesheetSourceMapURL(const String& content)
 
 } // namespace ContentSearchUtilities
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 2bc2d3c7c0dd2de2f1c22a3c2db6fa11a6b322f0..542065fdadc57ad574d70aec2c22ced04f9bdc8b 100644 (file)
@@ -29,9 +29,7 @@
 #ifndef ContentSearchUtilities_h
 #define ContentSearchUtilities_h
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSTypeBuilders.h"
+#include "InspectorProtocolObjects.h"
 #include <wtf/Vector.h>
 #include <wtf/text/TextPosition.h>
 #include <wtf/text/WTFString.h>
@@ -46,7 +44,7 @@ namespace ContentSearchUtilities {
 
 JS_EXPORT_PRIVATE JSC::Yarr::RegularExpression createSearchRegex(const String& query, bool caseSensitive, bool isRegex);
 JS_EXPORT_PRIVATE int countRegularExpressionMatches(const JSC::Yarr::RegularExpression&, const String&);
-JS_EXPORT_PRIVATE PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>> searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex);
+JS_EXPORT_PRIVATE Ref<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>> searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex);
 JS_EXPORT_PRIVATE TextPosition textPositionFromOffset(size_t offset, const Vector<size_t>& lineEndings);
 JS_EXPORT_PRIVATE std::unique_ptr<Vector<size_t>> lineEndings(const String&);
 
@@ -58,6 +56,4 @@ JS_EXPORT_PRIVATE String findStylesheetSourceMapURL(const String& content);
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(ContentSearchUtilities_h)
index 321b5ee925057d6688ef2c58d2105edffa3d8e26..7e145be3ed10af154db56e0b40fffafb031d7a05 100644 (file)
@@ -27,8 +27,6 @@
 #include "config.h"
 #include "IdentifiersFactory.h"
 
-#if ENABLE(INSPECTOR)
-
 #include <wtf/text/StringBuilder.h>
 
 namespace Inspector {
@@ -62,4 +60,3 @@ String IdentifiersFactory::addProcessIdPrefixTo(const String& id)
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 0d5611dc293d28451485fa7d4a4521ada4fbdff9..d81c79a4ae3ec28b2322aa329f0bebc1076dd5c8 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef IdentifiersFactory_h
 #define IdentifiersFactory_h
 
-#if ENABLE(INSPECTOR)
-
 #include <wtf/text/WTFString.h>
 
 namespace Inspector {
@@ -47,5 +45,3 @@ private:
 } // namespace Inspector
 
 #endif // !defined(IdentifiersFactory_h)
-
-#endif // ENABLE(INSPECTOR)
index 1a2b9309897d475a9737b72362b69c9ef432e58f..492060e68ecd93813c6253a2434f8dcf0042bbd6 100644 (file)
 #include "config.h"
 #include "InjectedScript.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorValues.h"
 #include "JSCInlines.h"
 #include "ScriptFunctionCall.h"
 #include "ScriptObject.h"
 #include <wtf/text/WTFString.h>
 
-using Inspector::TypeBuilder::Array;
+using Inspector::Protocol::Array;
 
 namespace Inspector {
 
@@ -58,7 +56,7 @@ InjectedScript::~InjectedScript()
 {
 }
 
-void InjectedScript::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>* result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InjectedScript::evaluate(ErrorString& errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("evaluate"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(expression);
@@ -66,10 +64,11 @@ void InjectedScript::evaluate(ErrorString* errorString, const String& expression
     function.appendArgument(includeCommandLineAPI);
     function.appendArgument(returnByValue);
     function.appendArgument(generatePreview);
-    makeEvalCall(errorString, function, result, wasThrown);
+    function.appendArgument(saveResult);
+    makeEvalCall(errorString, function, result, wasThrown, savedResultIndex);
 }
 
-void InjectedScript::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>* result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InjectedScript::callFunctionOn(ErrorString& errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("callFunctionOn"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(objectId);
@@ -80,7 +79,7 @@ void InjectedScript::callFunctionOn(ErrorString* errorString, const String& obje
     makeEvalCall(errorString, function, result, wasThrown);
 }
 
-void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>* result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InjectedScript::evaluateOnCallFrame(ErrorString& errorString, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("evaluateOnCallFrame"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(callFrames);
@@ -90,60 +89,112 @@ void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const Depreca
     function.appendArgument(includeCommandLineAPI);
     function.appendArgument(returnByValue);
     function.appendArgument(generatePreview);
-    makeEvalCall(errorString, function, result, wasThrown);
+    function.appendArgument(saveResult);
+    makeEvalCall(errorString, function, result, wasThrown, savedResultIndex);
 }
 
-void InjectedScript::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<Inspector::TypeBuilder::Debugger::FunctionDetails>* result)
+void InjectedScript::getFunctionDetails(ErrorString& errorString, const String& functionId, RefPtr<Inspector::Protocol::Debugger::FunctionDetails>* result)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getFunctionDetails"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(functionId);
 
     RefPtr<InspectorValue> resultValue;
     makeCall(function, &resultValue);
-    if (!resultValue || resultValue->type() != InspectorValue::TypeObject) {
+    if (!resultValue || resultValue->type() != InspectorValue::Type::Object) {
         if (!resultValue->asString(errorString))
-            *errorString = ASCIILiteral("Internal error");
+            errorString = ASCIILiteral("Internal error");
         return;
     }
 
-    *result = Inspector::TypeBuilder::Debugger::FunctionDetails::runtimeCast(resultValue);
+    *result = BindingTraits<Inspector::Protocol::Debugger::FunctionDetails>::runtimeCast(WTF::move(resultValue));
 }
 
-void InjectedScript::getProperties(ErrorString* errorString, const String& objectId, bool ownProperties, bool ownAndGetterProperties, RefPtr<Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor>>* properties)
+void InjectedScript::getProperties(ErrorString& errorString, const String& objectId, bool ownProperties, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getProperties"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(objectId);
     function.appendArgument(ownProperties);
-    function.appendArgument(ownAndGetterProperties);
+    function.appendArgument(generatePreview);
+
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
+    if (!result || result->type() != InspectorValue::Type::Array) {
+        errorString = ASCIILiteral("Internal error");
+        return;
+    }
+
+    *properties = BindingTraits<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>::runtimeCast(WTF::move(result));
+}
+
+void InjectedScript::getDisplayableProperties(ErrorString& errorString, const String& objectId, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties)
+{
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getDisplayableProperties"), inspectorEnvironment()->functionCallHandler());
+    function.appendArgument(objectId);
+    function.appendArgument(generatePreview);
 
     RefPtr<InspectorValue> result;
     makeCall(function, &result);
-    if (!result || result->type() != InspectorValue::TypeArray) {
-        *errorString = ASCIILiteral("Internal error");
+    if (!result || result->type() != InspectorValue::Type::Array) {
+        errorString = ASCIILiteral("Internal error");
         return;
     }
 
-    *properties = Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor>::runtimeCast(result);
+    *properties = BindingTraits<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>::runtimeCast(WTF::move(result));
 }
 
-void InjectedScript::getInternalProperties(ErrorString* errorString, const String& objectId, RefPtr<Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>>* properties)
+void InjectedScript::getInternalProperties(ErrorString& errorString, const String& objectId, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>* properties)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getInternalProperties"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(objectId);
+    function.appendArgument(generatePreview);
 
     RefPtr<InspectorValue> result;
     makeCall(function, &result);
-    if (!result || result->type() != InspectorValue::TypeArray) {
-        *errorString = ASCIILiteral("Internal error");
+    if (!result || result->type() != InspectorValue::Type::Array) {
+        errorString = ASCIILiteral("Internal error");
         return;
     }
 
-    RefPtr<Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>> array = Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>::runtimeCast(result);
-    if (array->length() > 0)
-        *properties = array;
+    auto array = BindingTraits<Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>::runtimeCast(WTF::move(result));
+    *properties = array->length() > 0 ? array : nullptr;
 }
 
-PassRefPtr<Array<Inspector::TypeBuilder::Debugger::CallFrame>> InjectedScript::wrapCallFrames(const Deprecated::ScriptValue& callFrames)
+void InjectedScript::getCollectionEntries(ErrorString& errorString, const String& objectId, const String& objectGroup, int startIndex, int numberToFetch, RefPtr<Protocol::Array<Protocol::Runtime::CollectionEntry>>* entries)
+{
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getCollectionEntries"), inspectorEnvironment()->functionCallHandler());
+    function.appendArgument(objectId);
+    function.appendArgument(objectGroup);
+    function.appendArgument(startIndex);
+    function.appendArgument(numberToFetch);
+
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
+    if (!result || result->type() != InspectorValue::Type::Array) {
+        errorString = ASCIILiteral("Internal error");
+        return;
+    }
+
+    *entries = BindingTraits<Array<Protocol::Runtime::CollectionEntry>>::runtimeCast(WTF::move(result));
+}
+
+void InjectedScript::saveResult(ErrorString& errorString, const String& callArgumentJSON, Inspector::Protocol::OptOutput<int>* savedResultIndex)
+{
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("saveResult"), inspectorEnvironment()->functionCallHandler());
+    function.appendArgument(callArgumentJSON);
+
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
+    if (!result || result->type() != InspectorValue::Type::Integer) {
+        errorString = ASCIILiteral("Internal error");
+        return;
+    }
+
+    int savedResultIndexInt = 0;
+    if (result->asInteger(savedResultIndexInt) && savedResultIndexInt > 0)
+        *savedResultIndex = savedResultIndexInt;
+}
+
+Ref<Array<Inspector::Protocol::Debugger::CallFrame>> InjectedScript::wrapCallFrames(const Deprecated::ScriptValue& callFrames)
 {
     ASSERT(!hasNoValue());
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("wrapCallFrames"), inspectorEnvironment()->functionCallHandler());
@@ -153,13 +204,13 @@ PassRefPtr<Array<Inspector::TypeBuilder::Debugger::CallFrame>> InjectedScript::w
     Deprecated::ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException);
     ASSERT(!hadException);
     RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(scriptState());
-    if (result->type() == InspectorValue::TypeArray)
-        return Array<Inspector::TypeBuilder::Debugger::CallFrame>::runtimeCast(result);
+    if (result->type() == InspectorValue::Type::Array)
+        return BindingTraits<Array<Inspector::Protocol::Debugger::CallFrame>>::runtimeCast(WTF::move(result)).releaseNonNull();
 
-    return Array<Inspector::TypeBuilder::Debugger::CallFrame>::create();
+    return Array<Inspector::Protocol::Debugger::CallFrame>::create();
 }
 
-PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(const Deprecated::ScriptValue& value, const String& groupName, bool generatePreview) const
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapObject(const Deprecated::ScriptValue& value, const String& groupName, bool generatePreview) const
 {
     ASSERT(!hasNoValue());
     Deprecated::ScriptFunctionCall wrapFunction(injectedScriptObject(), ASCIILiteral("wrapObject"), inspectorEnvironment()->functionCallHandler());
@@ -173,11 +224,14 @@ PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapOb
     if (hadException)
         return nullptr;
 
-    RefPtr<InspectorObject> rawResult = r.toInspectorValue(scriptState())->asObject();
-    return Inspector::TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
+    RefPtr<InspectorObject> resultObject;
+    bool castSucceeded = r.toInspectorValue(scriptState())->asObject(resultObject);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+    return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
 }
 
-PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTable(const Deprecated::ScriptValue& table, const Deprecated::ScriptValue& columns) const
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapTable(const Deprecated::ScriptValue& table, const Deprecated::ScriptValue& columns) const
 {
     ASSERT(!hasNoValue());
     Deprecated::ScriptFunctionCall wrapFunction(injectedScriptObject(), ASCIILiteral("wrapTable"), inspectorEnvironment()->functionCallHandler());
@@ -193,8 +247,28 @@ PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTa
     if (hadException)
         return nullptr;
 
-    RefPtr<InspectorObject> rawResult = r.toInspectorValue(scriptState())->asObject();
-    return Inspector::TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
+    RefPtr<InspectorObject> resultObject;
+    bool castSucceeded = r.toInspectorValue(scriptState())->asObject(resultObject);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+    return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
+}
+
+void InjectedScript::setExceptionValue(const Deprecated::ScriptValue& value)
+{
+    ASSERT(!hasNoValue());
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("setExceptionValue"), inspectorEnvironment()->functionCallHandler());
+    function.appendArgument(value);
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
+}
+
+void InjectedScript::clearExceptionValue()
+{
+    ASSERT(!hasNoValue());
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("clearExceptionValue"), inspectorEnvironment()->functionCallHandler());
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
 }
 
 Deprecated::ScriptValue InjectedScript::findObjectById(const String& objectId) const
@@ -240,4 +314,3 @@ void InjectedScript::releaseObjectGroup(const String& objectGroup)
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index fce17fc6306c950e3e0e79375eaf652f570a98bb..bd43f720ce41a4064e0a5ddcf79ee6e85b6f3353 100644 (file)
 #ifndef InjectedScript_h
 #define InjectedScript_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InjectedScriptBase.h"
-#include "InspectorJSTypeBuilders.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 
 namespace Deprecated {
@@ -56,16 +52,22 @@ public:
     InjectedScript(Deprecated::ScriptObject, InspectorEnvironment*);
     virtual ~InjectedScript();
 
-    void evaluate(ErrorString*, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown);
-    void callFunctionOn(ErrorString*, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown);
-    void evaluateOnCallFrame(ErrorString*, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown);
-    void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>* result);
-    void getProperties(ErrorString*, const String& objectId, bool ownProperties, bool ownAndGetterProperties, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor>>* result);
-    void getInternalProperties(ErrorString*, const String& objectId, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor>>* result);
+    void evaluate(ErrorString&, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex);
+    void callFunctionOn(ErrorString&, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown);
+    void evaluateOnCallFrame(ErrorString&, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex);
+    void getFunctionDetails(ErrorString&, const String& functionId, RefPtr<Protocol::Debugger::FunctionDetails>* result);
+    void getProperties(ErrorString&, const String& objectId, bool ownProperties, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::PropertyDescriptor>>* result);
+    void getDisplayableProperties(ErrorString&, const String& objectId, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::PropertyDescriptor>>* result);
+    void getInternalProperties(ErrorString&, const String& objectId, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::InternalPropertyDescriptor>>* result);
+    void getCollectionEntries(ErrorString&, const String& objectId, const String& objectGroup, int startIndex, int numberToFetch, RefPtr<Protocol::Array<Protocol::Runtime::CollectionEntry>>* entries);
+    void saveResult(ErrorString&, const String& callArgumentJSON, Inspector::Protocol::OptOutput<int>* savedResultIndex);
+
+    Ref<Protocol::Array<Protocol::Debugger::CallFrame>> wrapCallFrames(const Deprecated::ScriptValue&);
+    RefPtr<Protocol::Runtime::RemoteObject> wrapObject(const Deprecated::ScriptValue&, const String& groupName, bool generatePreview = false) const;
+    RefPtr<Protocol::Runtime::RemoteObject> wrapTable(const Deprecated::ScriptValue& table, const Deprecated::ScriptValue& columns) const;
 
-    PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame>> wrapCallFrames(const Deprecated::ScriptValue&);
-    PassRefPtr<TypeBuilder::Runtime::RemoteObject> wrapObject(const Deprecated::ScriptValue&, const String& groupName, bool generatePreview = false) const;
-    PassRefPtr<TypeBuilder::Runtime::RemoteObject> wrapTable(const Deprecated::ScriptValue& table, const Deprecated::ScriptValue& columns) const;
+    void setExceptionValue(const Deprecated::ScriptValue&);
+    void clearExceptionValue();
 
     Deprecated::ScriptValue findObjectById(const String& objectId) const;
     void inspectObject(Deprecated::ScriptValue);
@@ -78,6 +80,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // InjectedScript_h
index d9561e1f4a786f96550e22daa34237ec93aecf1b..2dd5643dea49ab64e16575bb6bd071e68b33b35d 100644 (file)
@@ -32,8 +32,7 @@
 #include "config.h"
 #include "InjectedScriptBase.h"
 
-#if ENABLE(INSPECTOR)
-
+#include "DebuggerEvalEnabler.h"
 #include "InspectorValues.h"
 #include "JSCInlines.h"
 #include "JSGlobalObject.h"
@@ -81,18 +80,12 @@ Deprecated::ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(Deprecat
         m_environment->willCallInjectedScriptFunction(m_injectedScriptObject.scriptState(), name(), 1);
 
     JSC::ExecState* scriptState = m_injectedScriptObject.scriptState();
-    bool evalIsDisabled = false;
-    if (scriptState) {
-        evalIsDisabled = !scriptState->lexicalGlobalObject()->evalEnabled();
-        // Temporarily enable allow evals for inspector.
-        if (evalIsDisabled)
-            scriptState->lexicalGlobalObject()->setEvalEnabled(true);
-    }
-
-    Deprecated::ScriptValue resultValue = function.call(hadException);
+    Deprecated::ScriptValue resultValue;
 
-    if (evalIsDisabled)
-        scriptState->lexicalGlobalObject()->setEvalEnabled(false);
+    {
+        JSC::DebuggerEvalEnabler evalEnabler(scriptState);
+        resultValue = function.call(hadException);
+    }
 
     if (m_environment)
         m_environment->didCallInjectedScriptFunction(m_injectedScriptObject.scriptState());
@@ -119,38 +112,48 @@ void InjectedScriptBase::makeCall(Deprecated::ScriptFunctionCall& function, RefP
         *result = InspectorString::create("Exception while making a call.");
 }
 
-void InjectedScriptBase::makeEvalCall(ErrorString* errorString, Deprecated::ScriptFunctionCall& function, RefPtr<TypeBuilder::Runtime::RemoteObject>* objectResult, TypeBuilder::OptOutput<bool>* wasThrown)
+void InjectedScriptBase::makeEvalCall(ErrorString& errorString, Deprecated::ScriptFunctionCall& function, RefPtr<Protocol::Runtime::RemoteObject>* objectResult, Protocol::OptOutput<bool>* wasThrown, Protocol::OptOutput<int>* savedResultIndex)
 {
     RefPtr<InspectorValue> result;
     makeCall(function, &result);
     if (!result) {
-        *errorString = ASCIILiteral("Internal error: result value is empty");
+        errorString = ASCIILiteral("Internal error: result value is empty");
         return;
     }
 
-    if (result->type() == InspectorValue::TypeString) {
+    if (result->type() == InspectorValue::Type::String) {
         result->asString(errorString);
-        ASSERT(errorString->length());
+        ASSERT(errorString.length());
         return;
     }
 
-    RefPtr<InspectorObject> resultPair = result->asObject();
-    if (!resultPair) {
-        *errorString = ASCIILiteral("Internal error: result is not an Object");
+    RefPtr<InspectorObject> resultTuple;
+    if (!result->asObject(resultTuple)) {
+        errorString = ASCIILiteral("Internal error: result is not an Object");
         return;
     }
 
-    RefPtr<InspectorObject> resultObj = resultPair->getObject(ASCIILiteral("result"));
-    bool wasThrownVal = false;
-    if (!resultObj || !resultPair->getBoolean(ASCIILiteral("wasThrown"), &wasThrownVal)) {
-        *errorString = ASCIILiteral("Internal error: result is not a pair of value and wasThrown flag");
+    RefPtr<InspectorObject> resultObject;
+    if (!resultTuple->getObject(ASCIILiteral("result"), resultObject)) {
+        errorString = ASCIILiteral("Internal error: result is not a pair of value and wasThrown flag");
         return;
     }
 
-    *objectResult = TypeBuilder::Runtime::RemoteObject::runtimeCast(resultObj);
-    *wasThrown = wasThrownVal;
+    bool wasThrownValue = false;
+    if (!resultTuple->getBoolean(ASCIILiteral("wasThrown"), wasThrownValue)) {
+        errorString = ASCIILiteral("Internal error: result is not a pair of value and wasThrown flag");
+        return;
+    }
+
+    *objectResult = BindingTraits<Protocol::Runtime::RemoteObject>::runtimeCast(resultObject);
+    *wasThrown = wasThrownValue;
+
+    if (savedResultIndex) {
+        int savedIndex = 0;
+        if (resultTuple->getInteger(ASCIILiteral("savedResultIndex"), savedIndex))
+            *savedResultIndex = savedIndex;
+    }
 }
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 034e0c20a4f8ec4a7b1426967c88903511d5db7b..06c3f5664a549900592a8b208c2d97dd94e79fd4 100644 (file)
 #ifndef InjectedScriptBase_h
 #define InjectedScriptBase_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorEnvironment.h"
-#include "InspectorJSTypeBuilders.h"
+#include "InspectorProtocolObjects.h"
 #include "bindings/ScriptObject.h"
 #include <wtf/Forward.h>
 #include <wtf/RefPtr.h>
@@ -68,7 +66,7 @@ protected:
     const Deprecated::ScriptObject& injectedScriptObject() const;
     Deprecated::ScriptValue callFunctionWithEvalEnabled(Deprecated::ScriptFunctionCall&, bool& hadException) const;
     void makeCall(Deprecated::ScriptFunctionCall&, RefPtr<InspectorValue>* result);
-    void makeEvalCall(ErrorString*, Deprecated::ScriptFunctionCall&, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown);
+    void makeEvalCall(ErrorString&, Deprecated::ScriptFunctionCall&, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown, Protocol::OptOutput<int>* savedResult = nullptr);
 
 private:
     String m_name;
@@ -78,6 +76,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // InjectedScriptBase_h
index db917f859c1089fc2e3bf36d23a41142de39747c..6351472e07e9a9f61773b71ccfdb086141eec13e 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "InjectedScriptHost.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "JSInjectedScriptHost.h"
 
 using namespace JSC;
@@ -79,5 +77,3 @@ void InjectedScriptHost::clearAllWrappers()
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index db93f8631bf8bc0ea88c4996dbfc491e3cc30fba..ae530a202720b218599f8c9651008e78a76441b8 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef InjectedScriptHost_h
 #define InjectedScriptHost_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSCJSValueInlines.h"
 #include "Strong.h"
 #include "StrongInlines.h"
@@ -38,10 +36,10 @@ namespace Inspector {
 
 class JS_EXPORT_PRIVATE InjectedScriptHost : public RefCounted<InjectedScriptHost> {
 public:
-    static PassRefPtr<InjectedScriptHost> create() { return adoptRef(new InjectedScriptHost); }
+    static Ref<InjectedScriptHost> create() { return adoptRef(*new InjectedScriptHost); }
     virtual ~InjectedScriptHost();
 
-    virtual JSC::JSValue type(JSC::ExecState*, JSC::JSValue) { return JSC::jsUndefined(); }
+    virtual JSC::JSValue subtype(JSC::ExecState*, JSC::JSValue) { return JSC::jsUndefined(); }
     virtual bool isHTMLAllCollection(JSC::JSValue) { return false; }
 
     JSC::JSValue jsWrapper(JSC::ExecState*, JSC::JSGlobalObject*);
@@ -54,6 +52,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(InjectedScriptHost_h)
index ef0d9a374734d2564ec0c81b6384d6c7d034ea1d..1bac2ecbd2ef052d16661f43b5e70d92492d3b58 100644 (file)
@@ -31,8 +31,6 @@
 #include "config.h"
 #include "InjectedScriptManager.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "Completion.h"
 #include "InjectedScriptHost.h"
 #include "InjectedScriptSource.h"
@@ -94,15 +92,19 @@ int InjectedScriptManager::injectedScriptIdFor(ExecState* scriptState)
 
 InjectedScript InjectedScriptManager::injectedScriptForObjectId(const String& objectId)
 {
-    RefPtr<InspectorValue> parsedObjectId = InspectorValue::parseJSON(objectId);
-    if (parsedObjectId && parsedObjectId->type() == InspectorValue::TypeObject) {
-        long injectedScriptId = 0;
-        bool success = parsedObjectId->asObject()->getNumber(ASCIILiteral("injectedScriptId"), &injectedScriptId);
-        if (success)
-            return m_idToInjectedScript.get(injectedScriptId);
-    }
+    RefPtr<InspectorValue> parsedObjectId;
+    if (!InspectorValue::parseJSON(objectId, parsedObjectId))
+        return InjectedScript();
 
-    return InjectedScript();
+    RefPtr<InspectorObject> resultObject;
+    if (!parsedObjectId->asObject(resultObject))
+        return InjectedScript();
+
+    long injectedScriptId = 0;
+    if (!resultObject->getInteger(ASCIILiteral("injectedScriptId"), injectedScriptId))
+        return InjectedScript();
+
+    return m_idToInjectedScript.get(injectedScriptId);
 }
 
 void InjectedScriptManager::discardInjectedScripts()
@@ -114,13 +116,19 @@ void InjectedScriptManager::discardInjectedScripts()
 
 void InjectedScriptManager::releaseObjectGroup(const String& objectGroup)
 {
-    for (auto it = m_idToInjectedScript.begin(); it != m_idToInjectedScript.end(); ++it)
-        it->value.releaseObjectGroup(objectGroup);
+    for (auto& injectedScript : m_idToInjectedScript.values())
+        injectedScript.releaseObjectGroup(objectGroup);
+}
+
+void InjectedScriptManager::clearExceptionValue()
+{
+    for (auto& injectedScript : m_idToInjectedScript.values())
+        injectedScript.clearExceptionValue();
 }
 
 String InjectedScriptManager::injectedScriptSource()
 {
-    return String(reinterpret_cast<const char*>(InjectedScriptSource_js), sizeof(InjectedScriptSource_js));
+    return StringImpl::createWithoutCopying(InjectedScriptSource_js, sizeof(InjectedScriptSource_js));
 }
 
 Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ExecState* scriptState, int id)
@@ -131,9 +139,9 @@ Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const Strin
     JSGlobalObject* globalObject = scriptState->lexicalGlobalObject();
     JSValue globalThisValue = scriptState->globalThisValue();
 
-    JSValue evaluationException;
+    NakedPtr<Exception> evaluationException;
     InspectorEvaluateHandler evaluateHandler = m_environment.evaluateHandler();
-    JSValue functionValue = evaluateHandler(scriptState, sourceCode, globalThisValue, &evaluationException);
+    JSValue functionValue = evaluateHandler(scriptState, sourceCode, globalThisValue, evaluationException);
     if (evaluationException)
         return Deprecated::ScriptObject();
 
@@ -148,6 +156,7 @@ Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const Strin
     args.append(jsNumber(id));
 
     JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
+    scriptState->clearException();
     if (result.isObject())
         return Deprecated::ScriptObject(scriptState, result.getObject());
 
@@ -181,4 +190,3 @@ void InjectedScriptManager::didCreateInjectedScript(InjectedScript)
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 33a6084c331ef2f5d7de7c054f82f8874206b5d7..cb6c9b3b98c54b531341f5a7c0d757bc3191b215 100644 (file)
@@ -30,8 +30,6 @@
 #ifndef InjectedScriptManager_h
 #define InjectedScriptManager_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InjectedScript.h"
 #include "InjectedScriptHost.h"
 #include "InspectorEnvironment.h"
@@ -66,6 +64,7 @@ public:
     InjectedScript injectedScriptForObjectId(const String& objectId);
     void discardInjectedScripts();
     void releaseObjectGroup(const String& objectGroup);
+    void clearExceptionValue();
 
 protected:
     virtual void didCreateInjectedScript(InjectedScript);
@@ -84,6 +83,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(InjectedScriptManager_h)
index a3cfb32002e1ed9d5e6a84007a9f81b830f1a311..5ba27e08023b5af7acd6a4e3e6ae912b851b39f8 100644 (file)
@@ -32,8 +32,6 @@
 #include "config.h"
 #include "InjectedScriptModule.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
 #include "ScriptFunctionCall.h"
@@ -88,5 +86,3 @@ void InjectedScriptModule::ensureInjected(InjectedScriptManager* injectedScriptM
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index a170e798dc92dfa7dd12f53e13eab0a52369bfec..e8881b9ec626c9dcbca69434cb3eb85e885b84f2 100644 (file)
@@ -35,8 +35,6 @@
 #include "InjectedScriptBase.h"
 #include <wtf/text/WTFString.h>
 
-#if ENABLE(INSPECTOR)
-
 namespace JSC {
 class JSValue;
 }
@@ -64,6 +62,4 @@ protected:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // InjectedScriptModule_h
index a7a1e5cb1045b132a0655d2013717a89ebc21686..e576139b7b9d8f71769a402cbe2bd7e96d8a4e99 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2007, 2014-2015 Apple Inc.  All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 //# sourceURL=__WebInspectorInjectedScript__
 
-/**
- * @param {InjectedScriptHost} InjectedScriptHost
- * @param {GlobalObject} inspectedGlobalObject
- * @param {number} injectedScriptId
- */
 (function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId) {
 
 // Protect against Object overwritten by the user code.
 var Object = {}.constructor;
 
-/**
- * @constructor
- */
+function toString(obj)
+{
+    return String(obj);
+}
+
+function toStringDescription(obj)
+{
+    if (obj === 0 && 1 / obj < 0)
+        return "-0";
+
+    return toString(obj);
+}
+
+function isUInt32(obj)
+{
+    if (typeof obj === "number")
+        return obj >>> 0 === obj && (obj > 0 || 1 / obj > 0);
+    return "" + (obj >>> 0) === obj;
+}
+
+function isSymbol(obj)
+{
+    return typeof obj === "symbol";
+}
+
 var InjectedScript = function()
 {
     this._lastBoundObjectId = 1;
@@ -48,37 +66,30 @@ var InjectedScript = function()
     this._idToObjectGroupName = {};
     this._objectGroups = {};
     this._modules = {};
+    this._nextSavedResultIndex = 1;
+    this._savedResults = [];
 }
 
-/**
- * @type {Object.<string, boolean>}
- * @const
- */
 InjectedScript.primitiveTypes = {
     undefined: true,
     boolean: true,
     number: true,
-    string: true
+    string: true,
+}
+
+InjectedScript.CollectionMode = {
+    OwnProperties: 1 << 0,          // own properties.
+    NativeGetterProperties: 1 << 1, // native getter properties in the prototype chain.
+    AllProperties: 1 << 2,          // all properties in the prototype chain.
 }
 
 InjectedScript.prototype = {
-    /**
-     * @param {*} object
-     * @return {boolean}
-     */
     isPrimitiveValue: function(object)
     {
         // FIXME(33716): typeof document.all is always 'undefined'.
         return InjectedScript.primitiveTypes[typeof object] && !this._isHTMLAllCollection(object);
     },
 
-    /**
-     * @param {*} object
-     * @param {string} groupName
-     * @param {boolean} canAccessInspectedGlobalObject
-     * @param {boolean} generatePreview
-     * @return {!RuntimeAgent.RemoteObject}
-     */
     wrapObject: function(object, groupName, canAccessInspectedGlobalObject, generatePreview)
     {
         if (canAccessInspectedGlobalObject)
@@ -86,10 +97,16 @@ InjectedScript.prototype = {
         return this._fallbackWrapper(object);
     },
 
-    /**
-     * @param {*} object
-     * @return {!RuntimeAgent.RemoteObject}
-     */
+    setExceptionValue: function(value)
+    {
+        this._exceptionValue = value;
+    },
+
+    clearExceptionValue: function()
+    {
+        delete this._exceptionValue;
+    },
+
     _fallbackWrapper: function(object)
     {
         var result = {};
@@ -97,50 +114,38 @@ InjectedScript.prototype = {
         if (this.isPrimitiveValue(object))
             result.value = object;
         else
-            result.description = this._toString(object);
-        return /** @type {!RuntimeAgent.RemoteObject} */ (result);
+            result.description = toString(object);
+        return result;
     },
 
-    /**
-     * @param {boolean} canAccessInspectedGlobalObject
-     * @param {Object} table
-     * @param {Array.<string>|string|boolean} columns
-     * @return {!RuntimeAgent.RemoteObject}
-     */
     wrapTable: function(canAccessInspectedGlobalObject, table, columns)
     {
         if (!canAccessInspectedGlobalObject)
             return this._fallbackWrapper(table);
+
+        // FIXME: Currently columns are ignored. Instead, the frontend filters all
+        // properties based on the provided column names and in the provided order.
+        // Should we filter here too?
+
         var columnNames = null;
         if (typeof columns === "string")
             columns = [columns];
-        if (InjectedScriptHost.type(columns) == "array") {
+
+        if (InjectedScriptHost.subtype(columns) === "array") {
             columnNames = [];
             for (var i = 0; i < columns.length; ++i)
-                columnNames.push(String(columns[i]));
+                columnNames.push(toString(columns[i]));
         }
+
         return this._wrapObject(table, "console", false, true, columnNames);
     },
 
-    /**
-     * @param {*} object
-     */
     inspectObject: function(object)
     {
         if (this._commandLineAPIImpl)
             this._commandLineAPIImpl.inspect(object);
     },
 
-    /**
-     * This method cannot throw.
-     * @param {*} object
-     * @param {string=} objectGroupName
-     * @param {boolean=} forceValueType
-     * @param {boolean=} generatePreview
-     * @param {?Array.<string>=} columnNames
-     * @return {!RuntimeAgent.RemoteObject}
-     * @suppress {checkTypes}
-     */
     _wrapObject: function(object, objectGroupName, forceValueType, generatePreview, columnNames)
     {
         try {
@@ -155,11 +160,6 @@ InjectedScript.prototype = {
         }
     },
 
-    /**
-     * @param {*} object
-     * @param {string=} objectGroupName
-     * @return {string}
-     */
     _bind: function(object, objectGroupName)
     {
         var id = this._lastBoundObjectId++;
@@ -177,33 +177,29 @@ InjectedScript.prototype = {
         return objectId;
     },
 
-    /**
-     * @param {string} objectId
-     * @return {Object}
-     */
     _parseObjectId: function(objectId)
     {
         return InjectedScriptHost.evaluate("(" + objectId + ")");
     },
 
-    /**
-     * @param {string} objectGroupName
-     */
     releaseObjectGroup: function(objectGroupName)
     {
+        if (objectGroupName === "console") {
+            delete this._lastResult;
+            this._nextSavedResultIndex = 1;
+            this._savedResults = [];
+        }
+
         var group = this._objectGroups[objectGroupName];
         if (!group)
             return;
+
         for (var i = 0; i < group.length; i++)
             this._releaseObject(group[i]);
+
         delete this._objectGroups[objectGroupName];
     },
 
-    /**
-     * @param {string} methodName
-     * @param {string} args
-     * @return {*}
-     */
     dispatch: function(methodName, args)
     {
         var argsArray = InjectedScriptHost.evaluate("(" + args + ")");
@@ -216,7 +212,7 @@ InjectedScript.prototype = {
         return result;
     },
 
-    getProperties: function(objectId, ownProperties, ownAndGetterProperties)
+    _getProperties: function(objectId, collectionMode, generatePreview)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         var object = this._objectForId(parsedObjectId);
@@ -225,7 +221,10 @@ InjectedScript.prototype = {
         if (!this._isDefined(object))
             return false;
 
-        var descriptors = this._propertyDescriptors(object, ownProperties, ownAndGetterProperties);
+        if (isSymbol(object))
+            return false;
+
+        var descriptors = this._propertyDescriptors(object, collectionMode);
 
         // Go over properties, wrap object values.
         for (var i = 0; i < descriptors.length; ++i) {
@@ -235,46 +234,90 @@ InjectedScript.prototype = {
             if ("set" in descriptor)
                 descriptor.set = this._wrapObject(descriptor.set, objectGroupName);
             if ("value" in descriptor)
-                descriptor.value = this._wrapObject(descriptor.value, objectGroupName);
+                descriptor.value = this._wrapObject(descriptor.value, objectGroupName, false, generatePreview);
             if (!("configurable" in descriptor))
                 descriptor.configurable = false;
             if (!("enumerable" in descriptor))
                 descriptor.enumerable = false;
+            if ("symbol" in descriptor)
+                descriptor.symbol = this._wrapObject(descriptor.symbol, objectGroupName);
         }
 
         return descriptors;
     },
 
-    /**
-     * @param {string} objectId
-     * @return {Array.<Object>|boolean}
-     */
-    getInternalProperties: function(objectId, ownProperties)
+    getProperties: function(objectId, ownProperties, generatePreview)
+    {
+        var collectionMode = ownProperties ? InjectedScript.CollectionMode.OwnProperties : InjectedScript.CollectionMode.AllProperties;
+        return this._getProperties(objectId, collectionMode, generatePreview);
+    },
+
+    getDisplayableProperties: function(objectId, generatePreview)
+    {
+        var collectionMode = InjectedScript.CollectionMode.OwnProperties | InjectedScript.CollectionMode.NativeGetterProperties;
+        return this._getProperties(objectId, collectionMode, generatePreview);
+    },
+
+    getInternalProperties: function(objectId, generatePreview)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         var object = this._objectForId(parsedObjectId);
         var objectGroupName = this._idToObjectGroupName[parsedObjectId.id];
+
         if (!this._isDefined(object))
             return false;
-        var descriptors = [];
-        var internalProperties = InjectedScriptHost.getInternalProperties(object);
-        if (internalProperties) {
-            for (var i = 0; i < internalProperties.length; i++) {
-                var property = internalProperties[i];
-                var descriptor = {
-                    name: property.name,
-                    value: this._wrapObject(property.value, objectGroupName)
-                };
-                descriptors.push(descriptor);
-            }
+
+        if (isSymbol(object))
+            return false;
+
+        var descriptors = this._internalPropertyDescriptors(object);
+        if (!descriptors)
+            return [];
+
+        // Go over properties, wrap object values.
+        for (var i = 0; i < descriptors.length; ++i) {
+            var descriptor = descriptors[i];
+            if ("value" in descriptor)
+                descriptor.value = this._wrapObject(descriptor.value, objectGroupName, false, generatePreview);
         }
+
         return descriptors;
     },
 
-    /**
-     * @param {string} functionId
-     * @return {!DebuggerAgent.FunctionDetails|string}
-     */
+    getCollectionEntries: function(objectId, objectGroupName, startIndex, numberToFetch)
+    {
+        var parsedObjectId = this._parseObjectId(objectId);
+        var object = this._objectForId(parsedObjectId);
+        var objectGroupName = objectGroupName || this._idToObjectGroupName[parsedObjectId.id];
+
+        if (!this._isDefined(object))
+            return;
+
+        if (typeof object !== "object")
+            return;
+
+        var entries = this._entries(object, InjectedScriptHost.subtype(object), startIndex, numberToFetch);
+        return entries.map(function(entry) {
+            entry.value = injectedScript._wrapObject(entry.value, objectGroupName, false, true);
+            if ("key" in entry)
+                entry.key = injectedScript._wrapObject(entry.key, objectGroupName, false, true);
+            return entry;
+        });
+    },
+
+    saveResult: function(callArgumentJSON)
+    {
+        this._savedResultIndex = 0;
+
+        try {
+            var callArgument = InjectedScriptHost.evaluate("(" + callArgumentJSON + ")");
+            var value = this._resolveCallArgument(callArgument);
+            this._saveResult(value);
+        } catch (e) {}
+
+        return this._savedResultIndex;
+    },
+
     getFunctionDetails: function(functionId)
     {
         var parsedFunctionId = this._parseObjectId(functionId);
@@ -296,44 +339,24 @@ InjectedScript.prototype = {
         return details;
     },
 
-    /**
-     * @param {string} objectId
-     */
     releaseObject: function(objectId)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         this._releaseObject(parsedObjectId.id);
     },
 
-    /**
-     * @param {string} id
-     */
     _releaseObject: function(id)
     {
         delete this._idToWrappedObject[id];
         delete this._idToObjectGroupName[id];
     },
 
-    /**
-     * @param {string} expression
-     * @param {string} objectGroup
-     * @param {boolean} injectCommandLineAPI
-     * @param {boolean} returnByValue
-     * @param {boolean} generatePreview
-     * @return {*}
-     */
-    evaluate: function(expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview)
+    evaluate: function(expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview, saveResult)
     {
-        return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI, returnByValue, generatePreview);
+        return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI, returnByValue, generatePreview, saveResult);
     },
 
-    /**
-     * @param {string} objectId
-     * @param {string} expression
-     * @param {boolean} returnByValue
-     * @return {Object|string}
-     */
-    callFunctionOn: function(objectId, expression, args, returnByValue)
+    callFunctionOn: function(objectId, expression, args, returnByValue, generatePreview)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         var object = this._objectForId(parsedObjectId);
@@ -342,15 +365,13 @@ InjectedScript.prototype = {
 
         if (args) {
             var resolvedArgs = [];
-            args = InjectedScriptHost.evaluate(args);
-            for (var i = 0; i < args.length; ++i) {
-                var resolvedCallArgument;
+            var callArgs = InjectedScriptHost.evaluate(args);
+            for (var i = 0; i < callArgs.length; ++i) {
                 try {
-                    resolvedCallArgument = this._resolveCallArgument(args[i]);
+                    resolvedArgs[i] = this._resolveCallArgument(callArgs[i]);
                 } catch (e) {
                     return String(e);
                 }
-                resolvedArgs.push(resolvedCallArgument)
             }
         }
 
@@ -360,21 +381,21 @@ InjectedScript.prototype = {
             if (typeof func !== "function")
                 return "Given expression does not evaluate to a function";
 
-            return { wasThrown: false,
-                     result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup, returnByValue) };
+            return {
+                wasThrown: false,
+                result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup, returnByValue, generatePreview)
+            };
         } catch (e) {
             return this._createThrownValue(e, objectGroup);
         }
     },
 
-    /**
-     * Resolves a value from CallArgument description.
-     * @param {RuntimeAgent.CallArgument} callArgumentJson
-     * @return {*} resolved value
-     * @throws {string} error message
-     */
-    _resolveCallArgument: function(callArgumentJson) {
-        var objectId = callArgumentJson.objectId;
+    _resolveCallArgument: function(callArgumentJSON)
+    {
+        if ("value" in callArgumentJSON)
+            return callArgumentJSON.value;
+
+        var objectId = callArgumentJSON.objectId;
         if (objectId) {
             var parsedArgId = this._parseObjectId(objectId);
             if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScriptId)
@@ -385,57 +406,43 @@ InjectedScript.prototype = {
                 throw "Could not find object with given id";
 
             return resolvedArg;
-        } else if ("value" in callArgumentJson)
-            return callArgumentJson.value;
-        else
-            return undefined;
+        }
+
+        return undefined;
     },
 
-    /**
-     * @param {Function} evalFunction
-     * @param {Object} object
-     * @param {string} objectGroup
-     * @param {boolean} isEvalOnCallFrame
-     * @param {boolean} injectCommandLineAPI
-     * @param {boolean} returnByValue
-     * @param {boolean} generatePreview
-     * @return {*}
-     */
-    _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview)
+    _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview, saveResult)
     {
         try {
-            return { wasThrown: false,
-                     result: this._wrapObject(this._evaluateOn(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGroup, returnByValue, generatePreview) };
+            this._savedResultIndex = 0;
+
+            var returnObject = {
+                wasThrown: false,
+                result: this._wrapObject(this._evaluateOn(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI, saveResult), objectGroup, returnByValue, generatePreview)
+            };
+
+            if (saveResult && this._savedResultIndex)
+                returnObject.savedResultIndex = this._savedResultIndex;
+
+            return returnObject;
         } catch (e) {
             return this._createThrownValue(e, objectGroup);
         }
     },
 
-    /**
-     * @param {*} value
-     * @param {string} objectGroup
-     * @return {Object}
-     */
     _createThrownValue: function(value, objectGroup)
     {
         var remoteObject = this._wrapObject(value, objectGroup);
         try {
-            remoteObject.description = this._toString(value);
+            remoteObject.description = toStringDescription(value);
         } catch (e) {}
-        return { wasThrown: true,
-                 result: remoteObject };
+        return {
+            wasThrown: true,
+            result: remoteObject
+        };
     },
 
-    /**
-     * @param {Function} evalFunction
-     * @param {Object} object
-     * @param {string} objectGroup
-     * @param {string} expression
-     * @param {boolean} isEvalOnCallFrame
-     * @param {boolean} injectCommandLineAPI
-     * @return {*}
-     */
-    _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI)
+    _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI, saveResult)
     {
         var commandLineAPI = null;
         if (injectCommandLineAPI) {
@@ -480,8 +487,8 @@ InjectedScript.prototype = {
             var expressionFunction = evalFunction.call(object, boundExpressionFunctionString);
             var result = expressionFunction.apply(null, parameters);
 
-            if (objectGroup === "console")
-                this._lastResult = result;
+            if (objectGroup === "console" && saveResult)
+                this._saveResult(result);
 
             return result;
         }
@@ -500,8 +507,8 @@ InjectedScript.prototype = {
 
             var result = evalFunction.call(inspectedGlobalObject, expression);
 
-            if (objectGroup === "console")
-                this._lastResult = result;
+            if (objectGroup === "console" && saveResult)
+                this._saveResult(result);
 
             return result;
         } finally {
@@ -514,10 +521,6 @@ InjectedScript.prototype = {
         }
     },
 
-    /**
-     * @param {Object} callFrame
-     * @return {Array.<InjectedScript.CallFrameProxy>|boolean}
-     */
     wrapCallFrames: function(callFrame)
     {
         if (!callFrame)
@@ -532,29 +535,14 @@ InjectedScript.prototype = {
         return result;
     },
 
-    /**
-     * @param {Object} topCallFrame
-     * @param {string} callFrameId
-     * @param {string} expression
-     * @param {string} objectGroup
-     * @param {boolean} injectCommandLineAPI
-     * @param {boolean} returnByValue
-     * @param {boolean} generatePreview
-     * @return {*}
-     */
-    evaluateOnCallFrame: function(topCallFrame, callFrameId, expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview)
+    evaluateOnCallFrame: function(topCallFrame, callFrameId, expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview, saveResult)
     {
         var callFrame = this._callFrameForId(topCallFrame, callFrameId);
         if (!callFrame)
             return "Could not find call frame with given id";
-        return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generatePreview);
+        return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generatePreview, saveResult);
     },
 
-    /**
-     * @param {Object} topCallFrame
-     * @param {string} callFrameId
-     * @return {Object}
-     */
     _callFrameForId: function(topCallFrame, callFrameId)
     {
         var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")");
@@ -565,118 +553,129 @@ InjectedScript.prototype = {
         return callFrame;
     },
 
-    /**
-     * @param {Object} objectId
-     * @return {Object}
-     */
     _objectForId: function(objectId)
     {
         return this._idToWrappedObject[objectId.id];
     },
 
-    /**
-     * @param {string} objectId
-     * @return {Object}
-     */
     findObjectById: function(objectId)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         return this._objectForId(parsedObjectId);
     },
 
-    /**
-     * @param {string} name
-     * @return {Object}
-     */
     module: function(name)
     {
         return this._modules[name];
     },
 
-    /**
-     * @param {string} name
-     * @param {string} source
-     * @return {Object}
-     */
     injectModule: function(name, source, host)
     {
         delete this._modules[name];
+
         var moduleFunction = InjectedScriptHost.evaluate("(" + source + ")");
         if (typeof moduleFunction !== "function") {
             if (inspectedGlobalObject.console)
                 inspectedGlobalObject.console.error("Web Inspector error: A function was expected for module %s evaluation", name);
             return null;
         }
+
         var module = moduleFunction.call(inspectedGlobalObject, InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, host);
         this._modules[name] = module;
         return module;
     },
 
-    _propertyDescriptors: function(object, ownProperties, ownAndGetterProperties)
+    _internalPropertyDescriptors: function(object, completeDescriptor)
     {
-        // Modes:
-        //  - ownProperties - only own properties and __proto__
-        //  - ownAndGetterProperties - own properties, __proto__, and getters in the prototype chain
-        //  - neither - get all properties in the prototype chain, exclude __proto__
+        var internalProperties = InjectedScriptHost.getInternalProperties(object);
+        if (!internalProperties)
+            return null;
+
+        var descriptors = [];
+        for (var i = 0; i < internalProperties.length; i++) {
+            var property = internalProperties[i];
+            var descriptor = {name: property.name, value: property.value};
+            if (completeDescriptor) {
+                descriptor.writable = false;
+                descriptor.configurable = false;
+                descriptor.enumerable = false;
+                descriptor.isOwn = true;
+            }
+            descriptors.push(descriptor);
+        }
+        return descriptors;
+    },
 
+    _propertyDescriptors: function(object, collectionMode)
+    {
         var descriptors = [];
-        var nameProcessed = {};
-        nameProcessed["__proto__"] = null;
+        var nameProcessed = new Set;
 
-        function createFakeValueDescriptor(name, descriptor, isOwnProperty)
+        function createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, possibleNativeBindingGetter)
         {
             try {
-                return {name: name, value: object[name], writable: descriptor.writable || false, configurable: descriptor.configurable || false, enumerable: descriptor.enumerable || false};
+                var descriptor = {name, value: object[name], writable: descriptor.writable || false, configurable: descriptor.configurable || false, enumerable: descriptor.enumerable || false};
+                if (possibleNativeBindingGetter)
+                    descriptor.nativeGetter = true;
+                if (isOwnProperty)
+                    descriptor.isOwn = true;
+                if (symbol)
+                    descriptor.symbol = symbol;
+                return descriptor;
             } catch (e) {
-                var errorDescriptor = {name: name, value: e, wasThrown: true};
+                var errorDescriptor = {name, value: e, wasThrown: true};
                 if (isOwnProperty)
                     errorDescriptor.isOwn = true;
+                if (symbol)
+                    errorDescriptor.symbol = symbol;
                 return errorDescriptor;
             }
         }
 
         function processDescriptor(descriptor, isOwnProperty, possibleNativeBindingGetter)
         {
-            // Own properties only.
-            if (ownProperties) {
-                if (isOwnProperty)
-                    descriptors.push(descriptor);
+            // All properties.
+            if (collectionMode & InjectedScript.CollectionMode.AllProperties) {
+                descriptors.push(descriptor);
                 return;
             }
 
-            // Own and getter properties.
-            if (ownAndGetterProperties) {
-                if (isOwnProperty) {
-                    // Own property, include the descriptor as is.
-                    descriptors.push(descriptor);
-                } else if (descriptor.hasOwnProperty("get") && descriptor.get) {
-                    // Getter property in the prototype chain. Create a fake value descriptor.
-                    descriptors.push(createFakeValueDescriptor(descriptor.name, descriptor, isOwnProperty));
-                } else if (possibleNativeBindingGetter) {
+            // Own properties.
+            if (collectionMode & InjectedScript.CollectionMode.OwnProperties && isOwnProperty) {
+                descriptors.push(descriptor);
+                return;
+            }
+
+            // Native Getter properties.
+            if (collectionMode & InjectedScript.CollectionMode.NativeGetterProperties) {
+                // FIXME: <https://webkit.org/b/140575> Web Inspector: Native Bindings Descriptors are Incomplete
+                // if (descriptor.hasOwnProperty("get") && descriptor.get && isNativeFunction(descriptor.get)) { ... }
+
+                if (possibleNativeBindingGetter) {
                     // Possible getter property in the prototype chain.
                     descriptors.push(descriptor);
+                    return;
                 }
-                return;
             }
-
-            // All properties.
-            descriptors.push(descriptor);
         }
 
-        function processPropertyNames(o, names, isOwnProperty)
+        function processProperties(o, properties, isOwnProperty)
         {
-            for (var i = 0; i < names.length; ++i) {
-                var name = names[i];
-                if (nameProcessed[name] || name === "__proto__")
+            for (var i = 0; i < properties.length; ++i) {
+                var property = properties[i];
+                if (nameProcessed.has(property) || property === "__proto__")
                     continue;
 
-                nameProcessed[name] = true;
+                nameProcessed.add(property);
+
+                var name = toString(property);
+                var symbol = isSymbol(property) ? property : null;
 
-                var descriptor = Object.getOwnPropertyDescriptor(o, name);
+                var descriptor = Object.getOwnPropertyDescriptor(o, property);
                 if (!descriptor) {
                     // FIXME: Bad descriptor. Can we get here?
                     // Fall back to very restrictive settings.
-                    var fakeDescriptor = createFakeValueDescriptor(name, {writable: false, configurable: false, enumerable: false}, isOwnProperty);
+                    var fakeDescriptor = createFakeValueDescriptor(name, symbol, {writable: false, configurable: false, enumerable: false}, isOwnProperty);
                     processDescriptor(fakeDescriptor, isOwnProperty);
                     continue;
                 }
@@ -685,7 +684,7 @@ InjectedScript.prototype = {
                     // FIXME: <https://webkit.org/b/140575> Web Inspector: Native Bindings Descriptors are Incomplete
                     // Developers may create such a descriptors, so we should be resilient:
                     // var x = {}; Object.defineProperty(x, "p", {get:undefined}); Object.getOwnPropertyDescriptor(x, "p")
-                    var fakeDescriptor = createFakeValueDescriptor(name, descriptor, isOwnProperty);
+                    var fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, true);
                     processDescriptor(fakeDescriptor, isOwnProperty, true);
                     continue;
                 }
@@ -693,19 +692,45 @@ InjectedScript.prototype = {
                 descriptor.name = name;
                 if (isOwnProperty)
                     descriptor.isOwn = true;
+                if (symbol)
+                    descriptor.symbol = symbol;
                 processDescriptor(descriptor, isOwnProperty);
             }
         }
 
-        // Iterate prototype chain.
+        function arrayIndexPropertyNames(o, length)
+        {
+            var array = new Array(length);
+            for (var i = 0; i < length; ++i) {
+                if (i in o)
+                    array.push("" + i);
+            }
+            return array;
+        }
+
+        // FIXME: <https://webkit.org/b/143589> Web Inspector: Better handling for large collections in Object Trees
+        // For array types with a large length we attempt to skip getOwnPropertyNames and instead just sublist of indexes.
+        var isArrayTypeWithLargeLength = false;
+        try {
+            isArrayTypeWithLargeLength = injectedScript._subtype(object) === "array" && isFinite(object.length) && object.length > 100;
+        } catch(e) {}
+
         for (var o = object; this._isDefined(o); o = o.__proto__) {
             var isOwnProperty = o === object;
-            processPropertyNames(o, Object.getOwnPropertyNames(o), isOwnProperty);
-            if (ownProperties)
+
+            if (isArrayTypeWithLargeLength && isOwnProperty)
+                processProperties(o, arrayIndexPropertyNames(o, 100), isOwnProperty);
+            else {
+                processProperties(o, Object.getOwnPropertyNames(o), isOwnProperty);
+                if (Object.getOwnPropertySymbols)
+                    processProperties(o, Object.getOwnPropertySymbols(o), isOwnProperty);
+            }
+
+            if (collectionMode === InjectedScript.CollectionMode.OwnProperties)
                 break;
         }
-        
-        // Include __proto__ at the end.
+
+        // Always include __proto__ at the end.
         try {
             if (object.__proto__)
                 descriptors.push({name: "__proto__", value: object.__proto__, writable: true, configurable: true, enumerable: false, isOwn: true});
@@ -714,41 +739,29 @@ InjectedScript.prototype = {
         return descriptors;
     },
 
-    /**
-     * @param {*} object
-     * @return {boolean}
-     */
     _isDefined: function(object)
     {
         return !!object || this._isHTMLAllCollection(object);
     },
 
-    /**
-     * @param {*} object
-     * @return {boolean}
-     */
     _isHTMLAllCollection: function(object)
     {
         // document.all is reported as undefined, but we still want to process it.
         return (typeof object === "undefined") && InjectedScriptHost.isHTMLAllCollection(object);
     },
 
-    /**
-     * @param {Object=} obj
-     * @return {string?}
-     */
     _subtype: function(obj)
     {
         if (obj === null)
             return "null";
 
-        if (this.isPrimitiveValue(obj))
+        if (this.isPrimitiveValue(obj) || isSymbol(obj))
             return null;
 
         if (this._isHTMLAllCollection(obj))
             return "array";
 
-        var preciseType = InjectedScriptHost.type(obj);
+        var preciseType = InjectedScriptHost.subtype(obj);
         if (preciseType)
             return preciseType;
 
@@ -756,321 +769,621 @@ InjectedScript.prototype = {
         try {
             if (typeof obj.splice === "function" && isFinite(obj.length))
                 return "array";
-            if (Object.prototype.toString.call(obj) === "[object Arguments]" && isFinite(obj.length)) // arguments.
-                return "array";
         } catch (e) {
         }
 
-        // If owning frame has navigated to somewhere else window properties will be undefined.
         return null;
     },
 
-    /**
-     * @param {*} obj
-     * @return {string?}
-     */
+    _nodeDescription: function(node)
+    {
+        var isXMLDocument = node.ownerDocument && !!node.ownerDocument.xmlVersion;
+        var description = isXMLDocument ? node.nodeName : node.nodeName.toLowerCase();
+
+        switch (node.nodeType) {
+        case 1: // Node.ELEMENT_NODE
+            if (node.id)
+                description += "#" + node.id;
+            if (node.hasAttribute("class")) {
+                // Using .getAttribute() is a workaround for SVG*Element.className returning SVGAnimatedString,
+                // which doesn't have any useful String methods. See <https://webkit.org/b/145363/>.
+                description += "." + node.getAttribute("class").trim().replace(/\s+/g, ".");
+            }
+            return description;
+
+        default:
+            return description;
+        }
+    },
+
+    _classPreview: function(classConstructorValue)
+    {
+        return "class " + classConstructorValue.name;
+    },
+
+    _nodePreview: function(node)
+    {
+        var isXMLDocument = node.ownerDocument && !!node.ownerDocument.xmlVersion;
+        var nodeName = isXMLDocument ? node.nodeName : node.nodeName.toLowerCase();
+
+        switch (node.nodeType) {
+        case 1: // Node.ELEMENT_NODE
+            if (node.id)
+                return "<" + nodeName + " id=\"" + node.id + "\">";
+            if (node.className)
+                return "<" + nodeName + " class=\"" + node.className + "\">";
+            if (nodeName === "input" && node.type)
+                return "<" + nodeName + " type=\"" + node.type + "\">";
+            return "<" + nodeName + ">";
+
+        case 3: // Node.TEXT_NODE
+            return nodeName + " \"" + node.nodeValue + "\"";
+
+        case 8: // Node.COMMENT_NODE
+            return "<!--" + node.nodeValue + "-->";
+
+        case 10: // Node.DOCUMENT_TYPE_NODE
+            return "<!DOCTYPE " + nodeName + ">";
+
+        default:
+            return nodeName;
+        }
+    },
+
     _describe: function(obj)
     {
         if (this.isPrimitiveValue(obj))
             return null;
 
-        obj = /** @type {Object} */ (obj);
+        if (isSymbol(obj))
+            return toString(obj);
 
-        // Type is object, get subtype.
         var subtype = this._subtype(obj);
 
         if (subtype === "regexp")
-            return this._toString(obj);
+            return toString(obj);
 
         if (subtype === "date")
-            return this._toString(obj);
-
-        if (subtype === "node") {
-            var description = obj.nodeName.toLowerCase();
-            switch (obj.nodeType) {
-            case 1 /* Node.ELEMENT_NODE */:
-                description += obj.id ? "#" + obj.id : "";
-                var className = obj.className;
-                description += className ? "." + className : "";
-                break;
-            case 10 /*Node.DOCUMENT_TYPE_NODE */:
-                description = "<!DOCTYPE " + description + ">";
-                break;
-            }
-            return description;
-        }
+            return toString(obj);
+
+        if (subtype === "error")
+            return toString(obj);
+
+        if (subtype === "node")
+            return this._nodeDescription(obj);
 
         var className = InjectedScriptHost.internalConstructorName(obj);
-        if (subtype === "array") {
-            if (typeof obj.length === "number")
-                className += "[" + obj.length + "]";
+        if (subtype === "array")
             return className;
-        }
 
         // NodeList in JSC is a function, check for array prior to this.
         if (typeof obj === "function")
-            return this._toString(obj);
+            return toString(obj);
 
+        // If Object, try for a better name from the constructor.
         if (className === "Object") {
-            // In Chromium DOM wrapper prototypes will have Object as their constructor name,
-            // get the real DOM wrapper name from the constructor property.
             var constructorName = obj.constructor && obj.constructor.name;
             if (constructorName)
                 return constructorName;
         }
+
         return className;
     },
 
-    /**
-     * @param {*} obj
-     * @return {string}
-     */
-    _toString: function(obj)
+    _getSetEntries: function(object, skip, numberToFetch)
+    {
+        var entries = [];
+
+        for (var value of object) {
+            if (skip > 0) {
+                skip--;
+                continue;
+            }
+
+            entries.push({value});
+
+            if (numberToFetch && entries.length === numberToFetch)
+                break;
+        }
+
+        return entries;
+    },
+
+    _getMapEntries: function(object, skip, numberToFetch)
     {
-        // We don't use String(obj) because inspectedGlobalObject.String is undefined if owning frame navigated to another page.
-        return "" + obj;
+        var entries = [];
+
+        for (var [key, value] of object) {
+            if (skip > 0) {
+                skip--;
+                continue;
+            }
+
+            entries.push({key, value});
+
+            if (numberToFetch && entries.length === numberToFetch)
+                break;
+        }
+
+        return entries;
+    },
+
+    _getWeakMapEntries: function(object, numberToFetch)
+    {
+        return InjectedScriptHost.weakMapEntries(object, numberToFetch);
+    },
+
+    _getWeakSetEntries: function(object, numberToFetch)
+    {
+        return InjectedScriptHost.weakSetEntries(object, numberToFetch);
+    },
+
+    _getIteratorEntries: function(object, numberToFetch)
+    {
+        return InjectedScriptHost.iteratorEntries(object, numberToFetch);
+    },
+
+    _entries: function(object, subtype, startIndex, numberToFetch)
+    {
+        if (subtype === "set")
+            return this._getSetEntries(object, startIndex, numberToFetch);
+        if (subtype === "map")
+            return this._getMapEntries(object, startIndex, numberToFetch);
+        if (subtype === "weakmap")
+            return this._getWeakMapEntries(object, numberToFetch);
+        if (subtype === "weakset")
+            return this._getWeakSetEntries(object, numberToFetch);
+        if (subtype === "iterator")
+            return this._getIteratorEntries(object, numberToFetch);
+
+        throw "unexpected type";
+    },
+
+    _saveResult: function(result)
+    {
+        this._lastResult = result;
+
+        if (result === undefined || result === null)
+            return;
+
+        var existingIndex = this._savedResults.indexOf(result);
+        if (existingIndex !== -1) {
+            this._savedResultIndex = existingIndex;
+            return;
+        }
+
+        this._savedResultIndex = this._nextSavedResultIndex;
+        this._savedResults[this._nextSavedResultIndex++] = result;
+
+        // $n is limited from $1-$99. $0 is special.
+        if (this._nextSavedResultIndex >= 100)
+            this._nextSavedResultIndex = 1;
+    },
+
+    _savedResult: function(index)
+    {
+        return this._savedResults[index];
     }
 }
 
-/**
- * @type {InjectedScript}
- * @const
- */
-var injectedScript = new InjectedScript();
-
-/**
- * @constructor
- * @param {*} object
- * @param {string=} objectGroupName
- * @param {boolean=} forceValueType
- * @param {boolean=} generatePreview
- * @param {?Array.<string>=} columnNames
- */
+var injectedScript = new InjectedScript;
+
+
 InjectedScript.RemoteObject = function(object, objectGroupName, forceValueType, generatePreview, columnNames)
 {
     this.type = typeof object;
+
+    if (this.type === "undefined" && injectedScript._isHTMLAllCollection(object))
+        this.type = "object";
+
     if (injectedScript.isPrimitiveValue(object) || object === null || forceValueType) {
         // We don't send undefined values over JSON.
-        if (typeof object !== "undefined")
+        if (this.type !== "undefined")
             this.value = object;
 
-        // Null object is object with 'null' subtype'
+        // Null object is object with 'null' subtype.
         if (object === null)
             this.subtype = "null";
 
         // Provide user-friendly number values.
-        if (typeof object === "number")
-            this.description = object + "";
+        if (this.type === "number")
+            this.description = toStringDescription(object);
         return;
     }
 
-    object = /** @type {Object} */ (object);
-
     this.objectId = injectedScript._bind(object, objectGroupName);
+
     var subtype = injectedScript._subtype(object);
     if (subtype)
         this.subtype = subtype;
+
     this.className = InjectedScriptHost.internalConstructorName(object);
     this.description = injectedScript._describe(object);
 
-    if (generatePreview && (this.type === "object" || injectedScript._isHTMLAllCollection(object)))
+    if (subtype === "array")
+        this.size = typeof object.length === "number" ? object.length : 0;
+    else if (subtype === "set" || subtype === "map")
+        this.size = object.size;
+    else if (subtype === "weakmap")
+        this.size = InjectedScriptHost.weakMapSize(object);
+    else if (subtype === "weakset")
+        this.size = InjectedScriptHost.weakSetSize(object);
+    else if (subtype === "class") {
+        this.classPrototype = injectedScript._wrapObject(object.prototype, objectGroupName);
+        this.className = object.name;
+    }
+
+    if (generatePreview && this.type === "object")
         this.preview = this._generatePreview(object, undefined, columnNames);
 }
 
 InjectedScript.RemoteObject.prototype = {
-    /**
-     * @param {Object} object
-     * @param {Array.<string>=} firstLevelKeys
-     * @param {?Array.<string>=} secondLevelKeys
-     * @return {Object} preview
-     */
+    _emptyPreview: function()
+    {
+        var preview = {
+            type: this.type,
+            description: this.description || toString(this.value),
+            lossless: true,
+        };
+
+        if (this.subtype) {
+            preview.subtype = this.subtype;
+            if (this.subtype !== "null") {
+                preview.overflow = false;
+                preview.properties = [];
+            }
+        }
+
+        if ("size" in this)
+            preview.size = this.size;
+
+        return preview;
+    },
+
+    _createObjectPreviewForValue: function(value)
+    {
+        var remoteObject = new InjectedScript.RemoteObject(value, undefined, false, true, undefined);
+        if (remoteObject.objectId)
+            injectedScript.releaseObject(remoteObject.objectId);
+        if (remoteObject.classPrototype && remoteObject.classPrototype.objectId)
+            injectedScript.releaseObject(remoteObject.classPrototype.objectId);
+
+        return remoteObject.preview || remoteObject._emptyPreview();
+    },
+
     _generatePreview: function(object, firstLevelKeys, secondLevelKeys)
     {
-        var preview = {};
-        preview.lossless = true;
-        preview.overflow = false;
-        preview.properties = [];
+        var preview = this._emptyPreview();
+
+        // Primitives just have a value.
+        if (this.type !== "object")
+            return;
 
         var isTableRowsRequest = secondLevelKeys === null || secondLevelKeys;
         var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;
 
         var propertiesThreshold = {
             properties: isTableRowsRequest ? 1000 : Math.max(5, firstLevelKeysCount),
-            indexes: isTableRowsRequest ? 1000 : Math.max(100, firstLevelKeysCount)
+            indexes: isTableRowsRequest ? 1000 : Math.max(10, firstLevelKeysCount)
         };
-        for (var o = object; injectedScript._isDefined(o); o = o.__proto__)
-            this._generateProtoPreview(o, preview, propertiesThreshold, firstLevelKeys, secondLevelKeys);
+
+        try {
+            // Maps, Sets, and Iterators have entries.
+            if (this.subtype === "map" || this.subtype === "set" || this.subtype === "weakmap" || this.subtype === "weakset" || this.subtype === "iterator")
+                this._appendEntryPreviews(object, preview);
+
+            preview.properties = [];
+
+            // Internal Properties.
+            var internalPropertyDescriptors = injectedScript._internalPropertyDescriptors(object, true);
+            if (internalPropertyDescriptors) {
+                this._appendPropertyPreviews(preview, internalPropertyDescriptors, true, propertiesThreshold, firstLevelKeys, secondLevelKeys);
+                if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
+                    return preview;
+            }
+
+            if (preview.entries)
+                return preview;
+
+            // Properties.
+            var descriptors = injectedScript._propertyDescriptors(object, InjectedScript.CollectionMode.AllProperties);
+            this._appendPropertyPreviews(preview, descriptors, false, propertiesThreshold, firstLevelKeys, secondLevelKeys);
+            if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
+                return preview;
+        } catch (e) {
+            preview.lossless = false;
+        }
+
         return preview;
     },
 
-    /**
-     * @param {Object} object
-     * @param {Object} preview
-     * @param {Object} propertiesThreshold
-     * @param {Array.<string>=} firstLevelKeys
-     * @param {Array.<string>=} secondLevelKeys
-     */
-    _generateProtoPreview: function(object, preview, propertiesThreshold, firstLevelKeys, secondLevelKeys)
+    _appendPropertyPreviews: function(preview, descriptors, internal, propertiesThreshold, firstLevelKeys, secondLevelKeys)
     {
-        var propertyNames = firstLevelKeys ? firstLevelKeys : Object.keys(/** @type {!Object} */(object));
-        try {
-            for (var i = 0; i < propertyNames.length; ++i) {
-                if (!propertiesThreshold.properties || !propertiesThreshold.indexes) {
-                    preview.overflow = true;
+        for (var descriptor of descriptors) {
+            // Seen enough.
+            if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
+                break;
+
+            // Error in descriptor.
+            if (descriptor.wasThrown) {
+                preview.lossless = false;
+                continue;
+            }
+
+            // Do not show "__proto__" in preview.
+            var name = descriptor.name;
+            if (name === "__proto__")
+                continue;
+
+            // For arrays, only allow indexes.
+            if (this.subtype === "array" && !isUInt32(name))
+                continue;
+
+            // Do not show non-enumerable non-own properties. Special case to allow array indexes that may be on the prototype.
+            if (!descriptor.enumerable && !descriptor.isOwn && this.subtype !== "array")
+                continue;
+
+            // If we have a filter, only show properties in the filter.
+            // FIXME: Currently these filters do nothing on the backend.
+            if (firstLevelKeys && !firstLevelKeys.includes(name))
+                continue;
+
+            // Getter/setter.
+            if (!("value" in descriptor)) {
+                preview.lossless = false;
+                this._appendPropertyPreview(preview, internal, {name, type: "accessor"}, propertiesThreshold);
+                continue;
+            }
+
+            // Null value.
+            var value = descriptor.value;
+            if (value === null) {
+                this._appendPropertyPreview(preview, internal, {name, type: "object", subtype: "null", value: "null"}, propertiesThreshold);
+                continue;
+            }
+
+            // Ignore non-enumerable functions.
+            var type = typeof value;
+            if (!descriptor.enumerable && type === "function")
+                continue;
+
+            // Fix type of document.all.
+            if (type === "undefined" && injectedScript._isHTMLAllCollection(value))
+                type = "object";
+
+            // Primitive.
+            const maxLength = 100;
+            if (InjectedScript.primitiveTypes[type]) {
+                if (type === "string" && value.length > maxLength) {
+                    value = this._abbreviateString(value, maxLength, true);
                     preview.lossless = false;
-                    break;
                 }
-                var name = propertyNames[i];
-                if (this.subtype === "array" && name === "length")
-                    continue;
+                this._appendPropertyPreview(preview, internal, {name, type, value: toStringDescription(value)}, propertiesThreshold);
+                continue;
+            }
 
-                var descriptor = Object.getOwnPropertyDescriptor(/** @type {!Object} */(object), name);
-                if (!("value" in descriptor) || !descriptor.enumerable) {
+            // Symbol.
+            if (isSymbol(value)) {
+                var symbolString = toString(value);
+                if (symbolString.length > maxLength) {
+                    symbolString = this._abbreviateString(symbolString, maxLength, true);
                     preview.lossless = false;
-                    continue;
                 }
+                this._appendPropertyPreview(preview, internal, {name, type, value: symbolString}, propertiesThreshold);
+                return;
+            }
 
-                var value = descriptor.value;
-                if (value === null) {
-                    this._appendPropertyPreview(preview, { name: name, type: "object", value: "null" }, propertiesThreshold);
-                    continue;
+            // Object.
+            var property = {name, type};
+            var subtype = injectedScript._subtype(value);
+            if (subtype)
+                property.subtype = subtype;
+
+            // Second level.
+            if ((secondLevelKeys === null || secondLevelKeys) || this._isPreviewableObject(value)) {
+                // FIXME: If we want secondLevelKeys filter to continue we would need some refactoring.
+                var subPreview = this._createObjectPreviewForValue(value);
+                property.valuePreview = subPreview;
+                if (!subPreview.lossless)
+                    preview.lossless = false;
+                if (subPreview.overflow)
+                    preview.overflow = true;
+            } else {
+                var description = "";
+                if (type !== "function" || subtype === "class") {
+                    var fullDescription;
+                    if (subtype === "class")
+                        fullDescription = "class " + value.name;
+                    else if (subtype === "node")
+                        fullDescription = injectedScript._nodePreview(value);
+                    else
+                        fullDescription = injectedScript._describe(value);
+                    description = this._abbreviateString(fullDescription, maxLength, subtype === "regexp");
                 }
+                property.value = description;
+                preview.lossless = false;
+            }
 
-                const maxLength = 100;
-                var type = typeof value;
-
-                if (InjectedScript.primitiveTypes[type]) {
-                    if (type === "string") {
-                        if (value.length > maxLength) {
-                            value = this._abbreviateString(value, maxLength, true);
-                            preview.lossless = false;
-                        }
-                        value = value.replace(/\n/g, "\u21B5");
-                    }
-                    this._appendPropertyPreview(preview, { name: name, type: type, value: value + "" }, propertiesThreshold);
-                    continue;
-                }
+            this._appendPropertyPreview(preview, internal, property, propertiesThreshold);
+        }
+    },
 
-                if (secondLevelKeys === null || secondLevelKeys) {
-                    var subPreview = this._generatePreview(value, secondLevelKeys || undefined);
-                    var property = { name: name, type: type, valuePreview: subPreview };
-                    this._appendPropertyPreview(preview, property, propertiesThreshold);
-                    if (!subPreview.lossless)
-                        preview.lossless = false;
-                    if (subPreview.overflow)
-                        preview.overflow = true;
-                    continue;
-                }
+    _appendPropertyPreview: function(preview, internal, property, propertiesThreshold)
+    {
+        if (toString(property.name >>> 0) === property.name)
+            propertiesThreshold.indexes--;
+        else
+            propertiesThreshold.properties--;
 
-                preview.lossless = false;
+        if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
+            preview.overflow = true;
+            preview.lossless = false;
+            return;
+        }
 
-                var subtype = injectedScript._subtype(value);
-                var description = "";
-                if (type !== "function")
-                    description = this._abbreviateString(/** @type {string} */ (injectedScript._describe(value)), maxLength, subtype === "regexp");
+        if (internal)
+            property.internal = true;
 
-                var property = { name: name, type: type, value: description };
-                if (subtype)
-                    property.subtype = subtype;
-                this._appendPropertyPreview(preview, property, propertiesThreshold);
-            }
-        } catch (e) {
+        preview.properties.push(property);
+    },
+
+    _appendEntryPreviews: function(object, preview)
+    {
+        // Fetch 6, but only return 5, so we can tell if we overflowed.
+        var entries = injectedScript._entries(object, this.subtype, 0, 6);
+        if (!entries)
+            return;
+
+        if (entries.length > 5) {
+            entries.pop();
+            preview.overflow = true;
+            preview.lossless = false;
         }
+
+        preview.entries = entries.map(function(entry) {
+            entry.value = this._createObjectPreviewForValue(entry.value);
+            if ("key" in entry)
+                entry.key = this._createObjectPreviewForValue(entry.key);
+            return entry;
+        }, this);
     },
 
-    /**
-     * @param {Object} preview
-     * @param {Object} property
-     * @param {Object} propertiesThreshold
-     */
-    _appendPropertyPreview: function(preview, property, propertiesThreshold)
+    _isPreviewableObject: function(object)
     {
-        if (isNaN(property.name))
-            propertiesThreshold.properties--;
-        else
-            propertiesThreshold.indexes--;
-        preview.properties.push(property);
+        return this._isPreviewableObjectInternal(object, new Set, 1);
+    },
+
+    _isPreviewableObjectInternal: function(object, knownObjects, depth)
+    {
+        // Deep object.
+        if (depth > 3)
+            return false;
+
+        // Primitive.
+        if (injectedScript.isPrimitiveValue(object) || isSymbol(object))
+            return true;
+
+        // Null.
+        if (object === null)
+            return true;
+
+        // Cyclic objects.
+        if (knownObjects.has(object))
+            return false;
+
+        ++depth;
+        knownObjects.add(object);
+
+        // Arrays are simple if they have 5 or less simple objects.
+        var subtype = injectedScript._subtype(object);
+        if (subtype === "array") {
+            var length = object.length;
+            if (length > 5)
+                return false;
+            for (var i = 0; i < length; ++i) {
+                if (!this._isPreviewableObjectInternal(object[i], knownObjects, depth))
+                    return false;
+            }
+            return true;
+        }
+
+        // Not a basic object.
+        if (object.__proto__ && object.__proto__.__proto__)
+            return false;
+
+        // Objects are simple if they have 3 or less simple properties.
+        var ownPropertyNames = Object.getOwnPropertyNames(object);
+        if (ownPropertyNames.length > 3)
+            return false;
+        for (var propertyName of ownPropertyNames) {
+            if (!this._isPreviewableObjectInternal(object[propertyName], knownObjects, depth))
+                return false;
+        }
+
+        return true;
     },
 
-    /**
-     * @param {string} string
-     * @param {number} maxLength
-     * @param {boolean=} middle
-     * @returns
-     */
     _abbreviateString: function(string, maxLength, middle)
     {
         if (string.length <= maxLength)
             return string;
+
         if (middle) {
             var leftHalf = maxLength >> 1;
             var rightHalf = maxLength - leftHalf - 1;
             return string.substr(0, leftHalf) + "\u2026" + string.substr(string.length - rightHalf, rightHalf);
         }
+
         return string.substr(0, maxLength) + "\u2026";
     }
 }
-/**
- * @constructor
- * @param {number} ordinal
- * @param {Object} callFrame
- */
+
 InjectedScript.CallFrameProxy = function(ordinal, callFrame)
 {
     this.callFrameId = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + injectedScriptId + "}";
     this.functionName = (callFrame.type === "function" ? callFrame.functionName : "");
-    this.location = { scriptId: String(callFrame.sourceID), lineNumber: callFrame.line, columnNumber: callFrame.column };
+    this.location = {scriptId: String(callFrame.sourceID), lineNumber: callFrame.line, columnNumber: callFrame.column};
     this.scopeChain = this._wrapScopeChain(callFrame);
     this.this = injectedScript._wrapObject(callFrame.thisObject, "backtrace");
 }
 
 InjectedScript.CallFrameProxy.prototype = {
-    /**
-     * @param {Object} callFrame
-     * @return {!Array.<DebuggerAgent.Scope>}
-     */
     _wrapScopeChain: function(callFrame)
     {
         var scopeChain = callFrame.scopeChain;
         var scopeChainProxy = [];
-        for (var i = 0; i < scopeChain.length; i++) {
-            var scope = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
-            scopeChainProxy.push(scope);
-        }
+        for (var i = 0; i < scopeChain.length; i++)
+            scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
         return scopeChainProxy;
     }
 }
 
-/**
- * @param {number} scopeTypeCode
- * @param {*} scopeObject
- * @param {string} groupId
- * @return {!DebuggerAgent.Scope}
- */
-InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId) {
-    const GLOBAL_SCOPE = 0;
-    const LOCAL_SCOPE = 1;
-    const WITH_SCOPE = 2;
-    const CLOSURE_SCOPE = 3;
-    const CATCH_SCOPE = 4;
-
-    /** @type {!Object.<number, string>} */
-    var scopeTypeNames = {};
-    scopeTypeNames[GLOBAL_SCOPE] = "global";
-    scopeTypeNames[LOCAL_SCOPE] = "local";
-    scopeTypeNames[WITH_SCOPE] = "with";
-    scopeTypeNames[CLOSURE_SCOPE] = "closure";
-    scopeTypeNames[CATCH_SCOPE] = "catch";
+InjectedScript.CallFrameProxy._scopeTypeNames = {
+    0: "global", // GLOBAL_SCOPE
+    1: "local", // LOCAL_SCOPE
+    2: "with", // WITH_SCOPE
+    3: "closure", // CLOSURE_SCOPE
+    4: "catch", // CATCH_SCOPE
+    5: "functionName", // FUNCTION_NAME_SCOPE
+}
 
+InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId)
+{
     return {
         object: injectedScript._wrapObject(scopeObject, groupId),
-        type: /** @type {DebuggerAgent.ScopeType} */ (scopeTypeNames[scopeTypeCode])
+        type: InjectedScript.CallFrameProxy._scopeTypeNames[scopeTypeCode]
     };
 }
 
+
+function slice(array, index)
+{
+    var result = [];
+    for (var i = index || 0; i < array.length; ++i)
+        result.push(array[i]);
+    return result;
+}
+
+function bind(func, thisObject, var_args)
+{
+    var args = slice(arguments, 2);
+    return function(var_args) {
+        return func.apply(thisObject, args.concat(slice(arguments)));
+    }
+}
+
 function BasicCommandLineAPI()
 {
     this.$_ = injectedScript._lastResult;
+    this.$exception = injectedScript._exceptionValue;
+
+    // $1-$99
+    for (var i = 1; i <= injectedScript._savedResults.length; ++i) {
+        var member = "$" + i;
+        if (member in inspectedGlobalObject)
+            continue;
+        this.__defineGetter__("$" + i, bind(injectedScript._savedResult, injectedScript, i));
+    }
 }
 
 return injectedScript;
index f6b6c55cbcf5849f2672d3665213ed072d397a6e..63404cf54254ad6a3eaa1a5f27c49b91772c8514 100644 (file)
 
 namespace Inspector {
 
-class InspectorBackendDispatcher;
-class InspectorFrontendChannel;
+class BackendDispatcher;
+class FrontendChannel;
 
-enum class InspectorDisconnectReason {
+enum class DisconnectReason {
     InspectedTargetDestroyed,
     InspectorDestroyed
 };
@@ -43,8 +43,10 @@ class InspectorAgentBase {
 public:
     virtual ~InspectorAgentBase() { }
 
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) = 0;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason reason) = 0;
+    String domainName() const { return m_name; }
+
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*) = 0;
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) = 0;
     virtual void discardAgent() { }
 
 protected:
@@ -55,7 +57,7 @@ protected:
 
     String m_name;
 };
-    
+
 } // namespace Inspector
 
 #endif // !defined(InspectorAgentBase_h)
index 4124cfe76317caf7a489105822701731b673aba5..bcc0988214a61df1ea67343d532261525e7ef439 100644 (file)
 #include "config.h"
 #include "InspectorAgentRegistry.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorAgentBase.h"
 
 namespace Inspector {
 
-InspectorAgentRegistry::InspectorAgentRegistry()
+AgentRegistry::AgentRegistry()
 {
 }
 
-void InspectorAgentRegistry::append(std::unique_ptr<InspectorAgentBase> agent)
+void AgentRegistry::append(std::unique_ptr<InspectorAgentBase> agent)
 {
     m_agents.append(WTF::move(agent));
 }
 
-void InspectorAgentRegistry::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+void AgentRegistry::appendExtraAgent(std::unique_ptr<InspectorAgentBase> agent)
+{
+    m_extraDomains.append(agent->domainName());
+
+    append(WTF::move(agent));
+}
+#endif
+
+void AgentRegistry::didCreateFrontendAndBackend(FrontendChannel* frontendChannel, BackendDispatcher* backendDispatcher)
 {
     for (size_t i = 0; i < m_agents.size(); i++)
         m_agents[i]->didCreateFrontendAndBackend(frontendChannel, backendDispatcher);
 }
 
-void InspectorAgentRegistry::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
+void AgentRegistry::willDestroyFrontendAndBackend(DisconnectReason reason)
 {
     for (size_t i = 0; i < m_agents.size(); i++)
         m_agents[i]->willDestroyFrontendAndBackend(reason);
 }
 
-void InspectorAgentRegistry::discardAgents()
+void AgentRegistry::discardAgents()
 {
     for (size_t i = 0; i < m_agents.size(); i++)
         m_agents[i]->discardAgent();
@@ -62,4 +69,3 @@ void InspectorAgentRegistry::discardAgents()
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 17d65e71a627b234bafb60b329b668724f5527b4..962f006df72713c2d947fe875794c87980956c47 100644 (file)
 #define InspectorAgentRegistry_h
 
 #include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
 
 namespace Inspector {
 
+class BackendDispatcher;
+class FrontendChannel;
 class InspectorAgentBase;
-class InspectorBackendDispatcher;
-class InspectorFrontendChannel;
-enum class InspectorDisconnectReason;
 
-class JS_EXPORT_PRIVATE InspectorAgentRegistry {
+enum class DisconnectReason;
+
+class JS_EXPORT_PRIVATE AgentRegistry {
 public:
-    InspectorAgentRegistry();
+    AgentRegistry();
 
     void append(std::unique_ptr<InspectorAgentBase>);
 
-    void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*);
-    void willDestroyFrontendAndBackend(InspectorDisconnectReason reason);
+    void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*);
+    void willDestroyFrontendAndBackend(DisconnectReason);
     void discardAgents();
 
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    void appendExtraAgent(std::unique_ptr<InspectorAgentBase>);
+    Vector<String> extraDomains() const { return m_extraDomains; }
+#endif
+
 private:
     // These are declared here to avoid MSVC from trying to create default iplementations which would
     // involve generating a copy constructor and copy assignment operator for the Vector of std::unique_ptrs.
-    InspectorAgentRegistry(const InspectorAgentRegistry&) = delete;
-    InspectorAgentRegistry& operator=(const InspectorAgentRegistry&) = delete;
+    AgentRegistry(const AgentRegistry&) = delete;
+    AgentRegistry& operator=(const AgentRegistry&) = delete;
 
     Vector<std::unique_ptr<InspectorAgentBase>> m_agents;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    Vector<String> m_extraDomains;
+#endif
 };
 
 } // namespace Inspector
index 30a66f7b3a1a836c6f46656d59cd25c6cf58123b..f88cfbdabc1dc9ceaf8f5030c675d494d7603819 100644 (file)
@@ -27,8 +27,6 @@
 #include "config.h"
 #include "InspectorBackendDispatcher.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorFrontendChannel.h"
 #include "InspectorValues.h"
 #include <wtf/text/CString.h>
 
 namespace Inspector {
 
-InspectorBackendDispatcher::CallbackBase::CallbackBase(PassRefPtr<InspectorBackendDispatcher> backendDispatcher, int id)
-    : m_backendDispatcher(backendDispatcher)
+BackendDispatcher::CallbackBase::CallbackBase(Ref<BackendDispatcher>&& backendDispatcher, int id)
+    : m_backendDispatcher(WTF::move(backendDispatcher))
     , m_id(id)
     , m_alreadySent(false)
 {
 }
 
-bool InspectorBackendDispatcher::CallbackBase::isActive() const
+bool BackendDispatcher::CallbackBase::isActive() const
 {
     return !m_alreadySent && m_backendDispatcher->isActive();
 }
 
-void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
+void BackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
 {
     ASSERT(error.length());
     sendIfActive(nullptr, error);
 }
 
-void InspectorBackendDispatcher::CallbackBase::sendIfActive(PassRefPtr<InspectorObject> partialMessage, const ErrorString& invocationError)
+void BackendDispatcher::CallbackBase::sendIfActive(RefPtr<InspectorObject>&& partialMessage, const ErrorString& invocationError)
 {
     if (m_alreadySent)
         return;
 
-    m_backendDispatcher->sendResponse(m_id, partialMessage, invocationError);
+    m_backendDispatcher->sendResponse(m_id, WTF::move(partialMessage), invocationError);
     m_alreadySent = true;
 }
 
-PassRefPtr<InspectorBackendDispatcher> InspectorBackendDispatcher::create(InspectorFrontendChannel* inspectorFrontendChannel)
+Ref<BackendDispatcher> BackendDispatcher::create(FrontendChannel* frontendChannel)
 {
-    return adoptRef(new InspectorBackendDispatcher(inspectorFrontendChannel));
+    return adoptRef(*new BackendDispatcher(frontendChannel));
 }
 
-void InspectorBackendDispatcher::registerDispatcherForDomain(const String& domain, InspectorSupplementalBackendDispatcher* dispatcher)
+void BackendDispatcher::registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher* dispatcher)
 {
     auto result = m_dispatchers.add(domain, dispatcher);
     ASSERT_UNUSED(result, result.isNewEntry);
 }
 
-void InspectorBackendDispatcher::dispatch(const String& message)
+void BackendDispatcher::dispatch(const String& message)
 {
-    Ref<InspectorBackendDispatcher> protect(*this);
+    Ref<BackendDispatcher> protect(*this);
 
-    RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
-    if (!parsedMessage) {
+    RefPtr<InspectorValue> parsedMessage;
+    if (!InspectorValue::parseJSON(message, parsedMessage)) {
         reportProtocolError(nullptr, ParseError, ASCIILiteral("Message must be in JSON format"));
         return;
     }
 
-    RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
-    if (!messageObject) {
+    RefPtr<InspectorObject> messageObject;
+    if (!parsedMessage->asObject(messageObject)) {
         reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("Message must be a JSONified object"));
         return;
     }
 
-    RefPtr<InspectorValue> callIdValue = messageObject->get("id");
-    if (!callIdValue) {
+    RefPtr<InspectorValue> callIdValue;
+    if (!messageObject->getValue(ASCIILiteral("id"), callIdValue)) {
         reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("'id' property was not found"));
         return;
     }
 
     long callId = 0;
-    if (!callIdValue->asNumber(&callId)) {
-        reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("The type of 'id' property must be number"));
+    if (!callIdValue->asInteger(callId)) {
+        reportProtocolError(nullptr, InvalidRequest, ASCIILiteral("The type of 'id' property must be integer"));
         return;
     }
 
-    RefPtr<InspectorValue> methodValue = messageObject->get("method");
-    if (!methodValue) {
+    RefPtr<InspectorValue> methodValue;
+    if (!messageObject->getValue(ASCIILiteral("method"), methodValue)) {
         reportProtocolError(&callId, InvalidRequest, ASCIILiteral("'method' property wasn't found"));
         return;
     }
 
     String method;
-    if (!methodValue->asString(&method)) {
+    if (!methodValue->asString(method)) {
         reportProtocolError(&callId, InvalidRequest, ASCIILiteral("The type of 'method' property must be string"));
         return;
     }
@@ -121,19 +119,19 @@ void InspectorBackendDispatcher::dispatch(const String& message)
     }
 
     String domain = method.substring(0, position);
-    InspectorSupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
+    SupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
     if (!domainDispatcher) {
         reportProtocolError(&callId, MethodNotFound, "'" + domain + "' domain was not found");
         return;
     }
 
     String domainMethod = method.substring(position + 1);
-    domainDispatcher->dispatch(callId, domainMethod, messageObject.release());
+    domainDispatcher->dispatch(callId, domainMethod, messageObject.releaseNonNull());
 }
 
-void InspectorBackendDispatcher::sendResponse(long callId, PassRefPtr<InspectorObject> result, const ErrorString& invocationError)
+void BackendDispatcher::sendResponse(long callId, RefPtr<InspectorObject>&& result, const ErrorString& invocationError)
 {
-    if (!m_inspectorFrontendChannel)
+    if (!m_frontendChannel)
         return;
 
     if (invocationError.length()) {
@@ -141,18 +139,18 @@ void InspectorBackendDispatcher::sendResponse(long callId, PassRefPtr<InspectorO
         return;
     }
 
-    RefPtr<InspectorObject> responseMessage = InspectorObject::create();
+    Ref<InspectorObject> responseMessage = InspectorObject::create();
     responseMessage->setObject(ASCIILiteral("result"), result);
-    responseMessage->setNumber(ASCIILiteral("id"), callId);
-    m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
+    responseMessage->setInteger(ASCIILiteral("id"), callId);
+    m_frontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
 }
 
-void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage) const
+void BackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage) const
 {
     reportProtocolError(callId, errorCode, errorMessage, nullptr);
 }
 
-void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage, PassRefPtr<InspectorArray> data) const
+void BackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode errorCode, const String& errorMessage, RefPtr<Inspector::Protocol::Array<String>>&& data) const
 {
     static const int errorCodes[] = {
         -32700, // ParseError
@@ -163,102 +161,105 @@ void InspectorBackendDispatcher::reportProtocolError(const long* const callId, C
         -32000, // ServerError
     };
 
-    ASSERT(errorCode >= 0);
-    ASSERT((unsigned)errorCode < WTF_ARRAY_LENGTH(errorCodes));
-    ASSERT(errorCodes[errorCode]);
+    ASSERT_ARG(errorCode, errorCode >= 0);
+    ASSERT_ARG(errorCode, (unsigned)errorCode < WTF_ARRAY_LENGTH(errorCodes));
+    ASSERT_ARG(errorCode, errorCodes[errorCode]);
 
-    if (!m_inspectorFrontendChannel)
+    if (!m_frontendChannel)
         return;
 
-    RefPtr<InspectorObject> error = InspectorObject::create();
-    error->setNumber(ASCIILiteral("code"), errorCodes[errorCode]);
+    Ref<InspectorObject> error = InspectorObject::create();
+    error->setInteger(ASCIILiteral("code"), errorCodes[errorCode]);
     error->setString(ASCIILiteral("message"), errorMessage);
     if (data)
-        error->setArray(ASCIILiteral("data"), data);
+        error->setArray(ASCIILiteral("data"), WTF::move(data));
 
-    RefPtr<InspectorObject> message = InspectorObject::create();
-    message->setObject(ASCIILiteral("error"), error.release());
+    Ref<InspectorObject> message = InspectorObject::create();
+    message->setObject(ASCIILiteral("error"), WTF::move(error));
     if (callId)
-        message->setNumber(ASCIILiteral("id"), *callId);
+        message->setInteger(ASCIILiteral("id"), *callId);
     else
         message->setValue(ASCIILiteral("id"), InspectorValue::null());
 
-    m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
+    m_frontendChannel->sendMessageToFrontend(message->toJSONString());
 }
 
 template<typename ReturnValueType, typename ValueType, typename DefaultValueType>
-static ReturnValueType getPropertyValue(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors, DefaultValueType defaultValue, bool (*asMethod)(InspectorValue*, ValueType*), const char* typeName)
+static ReturnValueType getPropertyValue(InspectorObject* object, const String& name, bool* out_optionalValueFound, Inspector::Protocol::Array<String>& protocolErrors, DefaultValueType defaultValue, bool (*asMethod)(InspectorValue&, ValueType&), const char* typeName)
 {
-    ASSERT(protocolErrors);
-
-    ValueType value = defaultValue;
-    if (valueFound)
-        *valueFound = false;
+    ValueType result = defaultValue;
+    // out_optionalValueFound signals to the caller whether an optional property was found.
+    // if out_optionalValueFound == nullptr, then this is a required property.
+    if (out_optionalValueFound)
+        *out_optionalValueFound = false;
 
     if (!object) {
-        if (!valueFound)
-            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type '%s'.", name.utf8().data(), typeName));
-        return value;
+        if (!out_optionalValueFound)
+            protocolErrors.addItem(String::format("'params' object must contain required parameter '%s' with type '%s'.", name.utf8().data(), typeName));
+        return result;
     }
 
-    InspectorObject::const_iterator end = object->end();
-    InspectorObject::const_iterator valueIterator = object->find(name);
-    if (valueIterator == end) {
-        if (!valueFound)
-            protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name.utf8().data(), typeName));
-        return value;
+    auto findResult = object->find(name);
+    if (findResult == object->end()) {
+        if (!out_optionalValueFound)
+            protocolErrors.addItem(String::format("Parameter '%s' with type '%s' was not found.", name.utf8().data(), typeName));
+        return result;
     }
 
-    if (!asMethod(valueIterator->value.get(), &value)) {
-        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be '%s'.", name.utf8().data(), typeName));
-        return value;
+    if (!asMethod(*findResult->value, result)) {
+        protocolErrors.addItem(String::format("Parameter '%s' has wrong type. It must be '%s'.", name.utf8().data(), typeName));
+        return result;
     }
 
-    if (valueFound)
-        *valueFound = true;
+    if (out_optionalValueFound)
+        *out_optionalValueFound = true;
 
-    return value;
+    return result;
 }
 
 struct AsMethodBridges {
-    static bool asInt(InspectorValue* value, int* output) { return value->asNumber(output); }
-    static bool asDouble(InspectorValue* value, double* output) { return value->asNumber(output); }
-    static bool asString(InspectorValue* value, String* output) { return value->asString(output); }
-    static bool asBoolean(InspectorValue* value, bool* output) { return value->asBoolean(output); }
-    static bool asObject(InspectorValue* value, RefPtr<InspectorObject>* output) { return value->asObject(output); }
-    static bool asArray(InspectorValue* value, RefPtr<InspectorArray>* output) { return value->asArray(output); }
+    static bool asInteger(InspectorValue& value, int& output) { return value.asInteger(output); }
+    static bool asDouble(InspectorValue& value, double& output) { return value.asDouble(output); }
+    static bool asString(InspectorValue& value, String& output) { return value.asString(output); }
+    static bool asBoolean(InspectorValue& value, bool& output) { return value.asBoolean(output); }
+    static bool asObject(InspectorValue& value, RefPtr<InspectorObject>& output) { return value.asObject(output); }
+    static bool asArray(InspectorValue& value, RefPtr<InspectorArray>& output) { return value.asArray(output); }
+    static bool asValue(InspectorValue& value, RefPtr<InspectorValue>& output) { return value.asValue(output); }
 };
 
-int InspectorBackendDispatcher::getInt(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+int BackendDispatcher::getInteger(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
-    return getPropertyValue<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInt, "Number");
+    return getPropertyValue<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInteger, "Integer");
 }
 
-double InspectorBackendDispatcher::getDouble(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+double BackendDispatcher::getDouble(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
     return getPropertyValue<double, double, double>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asDouble, "Number");
 }
 
-String InspectorBackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+String BackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
     return getPropertyValue<String, String, String>(object, name, valueFound, protocolErrors, "", AsMethodBridges::asString, "String");
 }
 
-bool InspectorBackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+bool BackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
     return getPropertyValue<bool, bool, bool>(object, name, valueFound, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean");
 }
 
-PassRefPtr<InspectorObject> InspectorBackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+RefPtr<InspectorObject> BackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
-    return getPropertyValue<PassRefPtr<InspectorObject>, RefPtr<InspectorObject>, InspectorObject*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asObject, "Object");
+    return getPropertyValue<RefPtr<InspectorObject>, RefPtr<InspectorObject>, InspectorObject*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asObject, "Object");
 }
 
-PassRefPtr<InspectorArray> InspectorBackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+RefPtr<InspectorArray> BackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
 {
-    return getPropertyValue<PassRefPtr<InspectorArray>, RefPtr<InspectorArray>, InspectorArray*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asArray, "Array");
+    return getPropertyValue<RefPtr<InspectorArray>, RefPtr<InspectorArray>, InspectorArray*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asArray, "Array");
 }
 
-} // namespace Inspector
+RefPtr<InspectorValue> BackendDispatcher::getValue(InspectorObject* object, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors)
+{
+    return getPropertyValue<RefPtr<InspectorValue>, RefPtr<InspectorValue>, InspectorValue*>(object, name, valueFound, protocolErrors, nullptr, AsMethodBridges::asValue, "Value");
+}
 
-#endif // ENABLE(INSPECTOR)
+} // namespace Inspector
index 0a55a1c96ae45981ccf8f4341801efa7939efb7e..b303700a209bb22266bae8f4e4de8dd326fb94b7 100644 (file)
 #ifndef InspectorBackendDispatcher_h
 #define InspectorBackendDispatcher_h
 
-#include "InspectorValues.h"
-#include <wtf/PassRefPtr.h>
+#include "InspectorProtocolTypes.h"
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
 namespace Inspector {
 
-class InspectorBackendDispatcher;
-class InspectorFrontendChannel;
+class BackendDispatcher;
+class FrontendChannel;
+
 typedef String ErrorString;
 
-class InspectorSupplementalBackendDispatcher : public RefCounted<InspectorSupplementalBackendDispatcher> {
+class SupplementalBackendDispatcher : public RefCounted<SupplementalBackendDispatcher> {
 public:
-    InspectorSupplementalBackendDispatcher(InspectorBackendDispatcher* backendDispatcher) : m_backendDispatcher(backendDispatcher) { }
-    virtual ~InspectorSupplementalBackendDispatcher() { }
-    virtual void dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message) = 0;
+    SupplementalBackendDispatcher(BackendDispatcher& backendDispatcher)
+        : m_backendDispatcher(backendDispatcher) { }
+    virtual ~SupplementalBackendDispatcher() { }
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) = 0;
 protected:
-    RefPtr<InspectorBackendDispatcher> m_backendDispatcher;
+    Ref<BackendDispatcher> m_backendDispatcher;
 };
 
-class JS_EXPORT_PRIVATE InspectorBackendDispatcher : public RefCounted<InspectorBackendDispatcher> {
+class JS_EXPORT_PRIVATE BackendDispatcher : public RefCounted<BackendDispatcher> {
 public:
-    static PassRefPtr<InspectorBackendDispatcher> create(InspectorFrontendChannel*);
+    static Ref<BackendDispatcher> create(FrontendChannel*);
 
     class JS_EXPORT_PRIVATE CallbackBase : public RefCounted<CallbackBase> {
     public:
-        CallbackBase(PassRefPtr<InspectorBackendDispatcher>, int id);
+        CallbackBase(Ref<BackendDispatcher>&&, int id);
 
         bool isActive() const;
         void sendFailure(const ErrorString&);
         void disable() { m_alreadySent = true; }
 
     protected:
-        void sendIfActive(PassRefPtr<InspectorObject> partialMessage, const ErrorString& invocationError);
+        void sendIfActive(RefPtr<InspectorObject>&& partialMessage, const ErrorString& invocationError);
 
     private:
-        RefPtr<InspectorBackendDispatcher> m_backendDispatcher;
+        Ref<BackendDispatcher> m_backendDispatcher;
         int m_id;
         bool m_alreadySent;
     };
 
-    void clearFrontend() { m_inspectorFrontendChannel = nullptr; }
-    bool isActive() const { return !!m_inspectorFrontendChannel; }
+    void clearFrontend() { m_frontendChannel = nullptr; }
+    bool isActive() const { return !!m_frontendChannel; }
 
     enum CommonErrorCode {
         ParseError = 0,
@@ -80,24 +81,26 @@ public:
         ServerError
     };
 
-    void registerDispatcherForDomain(const String& domain, InspectorSupplementalBackendDispatcher*);
+    void registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher*);
     void dispatch(const String& message);
-    void sendResponse(long callId, PassRefPtr<InspectorObject> result, const ErrorString& invocationError);
+    void sendResponse(long callId, RefPtr<InspectorObject>&& result, const ErrorString& invocationError);
     void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;
-    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<InspectorArray> data) const;
+    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, RefPtr<Inspector::Protocol::Array<String>>&& data) const;
 
-    static int getInt(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
-    static double getDouble(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
-    static String getString(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
-    static bool getBoolean(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
-    static PassRefPtr<InspectorObject> getObject(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
-    static PassRefPtr<InspectorArray> getArray(InspectorObject*, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    static int getInteger(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static double getDouble(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static String getString(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static bool getBoolean(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static RefPtr<InspectorValue> getValue(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static RefPtr<InspectorObject> getObject(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
+    static RefPtr<InspectorArray> getArray(InspectorObject*, const String& name, bool* valueFound, Inspector::Protocol::Array<String>& protocolErrors);
 
 private:
-    InspectorBackendDispatcher(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
+    BackendDispatcher(FrontendChannel* FrontendChannel)
+        : m_frontendChannel(FrontendChannel) { }
 
-    InspectorFrontendChannel* m_inspectorFrontendChannel;
-    HashMap<String, InspectorSupplementalBackendDispatcher*> m_dispatchers;
+    FrontendChannel* m_frontendChannel;
+    HashMap<String, SupplementalBackendDispatcher*> m_dispatchers;
 };
 
 } // namespace Inspector
index 588d7a125c1bfb08e738247faadd04bdee84d0a5..cb48771bfc52a8f235844c61dab3cff0c65bd779 100644 (file)
 
 #include "CallData.h"
 
+namespace WTF {
+class Stopwatch;
+}
+
 namespace JSC {
+class Exception;
 class SourceCode;
 }
 
 namespace Inspector {
 
-typedef JSC::JSValue (*InspectorFunctionCallHandler)(JSC::ExecState* exec, JSC::JSValue functionObject, JSC::CallType callType, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args, JSC::JSValue* exception);
-typedef JSC::JSValue (*InspectorEvaluateHandler)(JSC::ExecState*, const JSC::SourceCode&, JSC::JSValue thisValue, JSC::JSValue* exception);
+typedef JSC::JSValue (*InspectorFunctionCallHandler)(JSC::ExecState* exec, JSC::JSValue functionObject, JSC::CallType callType, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args, NakedPtr<JSC::Exception>& returnedException);
+typedef JSC::JSValue (*InspectorEvaluateHandler)(JSC::ExecState*, const JSC::SourceCode&, JSC::JSValue thisValue, NakedPtr<JSC::Exception>& returnedException);
 
 class InspectorEnvironment {
 public:
@@ -46,6 +51,8 @@ public:
     virtual InspectorEvaluateHandler evaluateHandler() const = 0;
     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String& scriptName, int scriptLine) = 0;
     virtual void didCallInjectedScriptFunction(JSC::ExecState*) = 0;
+    virtual void frontendInitialized() = 0;
+    virtual Ref<WTF::Stopwatch> executionStopwatch() = 0;
 };
 
 } // namespace Inspector
index fa0a8eae839f5fe47174e4cbbc9de57432a6b961..a2bf6f3c24fe9a330da3cfdaea7b2ccf68c38366 100644 (file)
@@ -30,9 +30,9 @@
 
 namespace Inspector {
 
-class InspectorFrontendChannel {
+class FrontendChannel {
 public:
-    virtual ~InspectorFrontendChannel() { }
+    virtual ~FrontendChannel() { }
     virtual bool sendMessageToFrontend(const String& message) = 0;
 };
 
diff --git a/inspector/InspectorProtocolTypes.h b/inspector/InspectorProtocolTypes.h
new file mode 100644 (file)
index 0000000..6f06296
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2011 The Chromium Authors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorProtocolTypes_h
+#define InspectorProtocolTypes_h
+
+#include "InspectorValues.h"
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+template<typename T> struct BindingTraits;
+
+template<typename T>
+class OptOutput {
+public:
+    OptOutput() : m_assigned(false) { }
+
+    void operator=(T value)
+    {
+        m_value = value;
+        m_assigned = true;
+    }
+
+    bool isAssigned() const { return m_assigned; }
+
+    T getValue()
+    {
+        ASSERT(isAssigned());
+        return m_value;
+    }
+
+private:
+    T m_value;
+    bool m_assigned;
+
+    WTF_MAKE_NONCOPYABLE(OptOutput);
+};
+
+template<typename T>
+class Array : public InspectorArrayBase {
+private:
+    Array() { }
+
+    InspectorArray& openAccessors()
+    {
+        COMPILE_ASSERT(sizeof(InspectorArray) == sizeof(Array<T>), cannot_cast);
+        return *static_cast<InspectorArray*>(static_cast<InspectorArrayBase*>(this));
+    }
+
+public:
+    void addItem(Ref<T>&& value)
+    {
+        openAccessors().pushValue(&value.get());
+    }
+
+    void addItem(RefPtr<T>&& value)
+    {
+        openAccessors().pushValue(WTF::move(value));
+    }
+    
+    void addItem(const String& value)
+    {
+        openAccessors().pushString(value);
+    }
+
+    void addItem(int value)
+    {
+        openAccessors().pushInteger(value);
+    }
+    
+    static Ref<Array<T>> create()
+    {
+        return adoptRef(*new Array<T>());
+    }
+};
+
+// Helper methods for Protocol and other Inspector types are provided by
+// specializations of BindingTraits<T>. Some are generated for protocol types.
+
+template<typename T>
+struct BindingTraits {
+    typedef T BindingType;
+
+    static void push(InspectorArray&, BindingType&);
+    static InspectorValue::Type typeTag();
+    static RefPtr<T> runtimeCast(RefPtr<InspectorObject>&&);
+#if !ASSERT_DISABLED
+    static void assertValueHasExpectedType(InspectorValue*);
+#endif // !ASSERT_DISABLED
+};
+
+template<InspectorValue::Type TYPE>
+struct PrimitiveBindingTraits {
+#if !ASSERT_DISABLED
+    static void assertValueHasExpectedType(InspectorValue* value)
+    {
+        ASSERT_ARG(value, value && value->type() == TYPE);
+    }
+#endif // !ASSERT_DISABLED
+};
+
+template<typename T>
+struct BindingTraits<Protocol::Array<T>> {
+    static RefPtr<Array<T>> runtimeCast(RefPtr<InspectorValue>&& value)
+    {
+        ASSERT_ARG(value, value);
+        RefPtr<InspectorArray> array;
+        bool castSucceeded = value->asArray(array);
+        ASSERT_UNUSED(castSucceeded, castSucceeded);
+#if !ASSERT_DISABLED
+        assertValueHasExpectedType(array.get());
+#endif // !ASSERT_DISABLED
+        COMPILE_ASSERT(sizeof(Array<T>) == sizeof(InspectorArray), type_cast_problem);
+        return static_cast<Array<T>*>(static_cast<InspectorArrayBase*>(array.get()));
+    }
+
+#if !ASSERT_DISABLED
+    static void assertValueHasExpectedType(InspectorValue* value)
+    {
+        ASSERT_ARG(value, value);
+        RefPtr<InspectorArray> array;
+        bool castSucceeded = value->asArray(array);
+        ASSERT_UNUSED(castSucceeded, castSucceeded);
+        for (unsigned i = 0; i < array->length(); i++)
+            BindingTraits<T>::assertValueHasExpectedType(array->get(i).get());
+    }
+#endif // !ASSERT_DISABLED
+};
+
+template<>
+struct BindingTraits<InspectorValue> {
+#if !ASSERT_DISABLED
+    static void assertValueHasExpectedType(InspectorValue*)
+    {
+    }
+#endif // !ASSERT_DISABLED
+};
+
+template<> struct BindingTraits<InspectorArray> : public PrimitiveBindingTraits<InspectorValue::Type::Array> { };
+template<> struct BindingTraits<InspectorObject> : public PrimitiveBindingTraits<InspectorValue::Type::Object> { };
+template<> struct BindingTraits<String> : public PrimitiveBindingTraits<InspectorValue::Type::String> { };
+template<> struct BindingTraits<bool> : public PrimitiveBindingTraits<InspectorValue::Type::Boolean> { };
+template<> struct BindingTraits<double> : public PrimitiveBindingTraits<InspectorValue::Type::Double> { };
+template<> struct BindingTraits<int> : public PrimitiveBindingTraits<InspectorValue::Type::Integer> { };
+
+} // namespace Protocol
+
+using Protocol::BindingTraits;
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolTypes_h)
diff --git a/inspector/InspectorTypeBuilder.h b/inspector/InspectorTypeBuilder.h
deleted file mode 100644 (file)
index 8ea76ec..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
- * Copyright (C) 2011 The Chromium Authors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorTypeBuilder_h
-#define InspectorTypeBuilder_h
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorValues.h"
-#include <wtf/Assertions.h>
-#include <wtf/PassRefPtr.h>
-
-namespace Inspector {
-
-namespace TypeBuilder {
-
-template<typename T>
-class OptOutput {
-public:
-    OptOutput() : m_assigned(false) { }
-
-    void operator=(T value)
-    {
-        m_value = value;
-        m_assigned = true;
-    }
-
-    bool isAssigned() const { return m_assigned; }
-
-    T getValue()
-    {
-        ASSERT(isAssigned());
-        return m_value;
-    }
-
-private:
-    T m_value;
-    bool m_assigned;
-
-    WTF_MAKE_NONCOPYABLE(OptOutput);
-};
-
-
-// A small transient wrapper around int type, that can be used as a funciton parameter type
-// cleverly disallowing C++ implicit casts from float or double.
-class ExactlyInt {
-public:
-    template<typename T>
-    ExactlyInt(T t) : m_value(cast_to_int<T>(t)) { }
-    ExactlyInt() { }
-
-    operator int() { return m_value; }
-
-private:
-    int m_value;
-
-    template<typename T>
-    static int cast_to_int(T) { return T::default_case_cast_is_not_supported(); }
-};
-
-template<>
-inline int ExactlyInt::cast_to_int<int>(int i) { return i; }
-
-template<>
-inline int ExactlyInt::cast_to_int<unsigned int>(unsigned int i) { return i; }
-
-#if !ASSERT_DISABLED
-class RuntimeCastHelper {
-public:
-    template<InspectorValue::Type TYPE>
-    static void assertType(InspectorValue* value)
-    {
-        ASSERT(value->type() == TYPE);
-    }
-
-    static void assertAny(InspectorValue*)
-    {
-    }
-
-    static void assertInt(InspectorValue* value)
-    {
-        double v;
-        bool castRes = value->asNumber(&v);
-        ASSERT_UNUSED(castRes, castRes);
-        ASSERT(static_cast<double>(static_cast<int>(v)) == v);
-    }
-};
-#endif
-
-
-// This class provides "Traits" type for the input type T. It is programmed using C++ template specialization
-// technique. By default it simply takes "ItemTraits" type from T, but it doesn't work with the base types.
-template<typename T>
-struct ArrayItemHelper {
-    typedef typename T::ItemTraits Traits;
-};
-
-template<typename T>
-class Array : public InspectorArrayBase {
-private:
-    Array() { }
-
-    InspectorArray* openAccessors()
-    {
-        COMPILE_ASSERT(sizeof(InspectorArray) == sizeof(Array<T>), cannot_cast);
-        return static_cast<InspectorArray*>(static_cast<InspectorArrayBase*>(this));
-    }
-
-public:
-    void addItem(PassRefPtr<T> value)
-    {
-        ArrayItemHelper<T>::Traits::pushRefPtr(this->openAccessors(), value);
-    }
-
-    void addItem(T value)
-    {
-        ArrayItemHelper<T>::Traits::pushRaw(this->openAccessors(), value);
-    }
-
-    static PassRefPtr<Array<T>> create()
-    {
-        return adoptRef(new Array<T>());
-    }
-
-    static PassRefPtr<Array<T>> runtimeCast(PassRefPtr<InspectorValue> value)
-    {
-        RefPtr<InspectorArray> array;
-        bool castRes = value->asArray(&array);
-        ASSERT_UNUSED(castRes, castRes);
-#if !ASSERT_DISABLED
-        assertCorrectValue(array.get());
-#endif // !ASSERT_DISABLED
-        COMPILE_ASSERT(sizeof(Array<T>) == sizeof(InspectorArray), type_cast_problem);
-        return static_cast<Array<T>*>(static_cast<InspectorArrayBase*>(array.get()));
-    }
-
-#if !ASSERT_DISABLED
-    static void assertCorrectValue(InspectorValue* value)
-    {
-        RefPtr<InspectorArray> array;
-        bool castRes = value->asArray(&array);
-        ASSERT_UNUSED(castRes, castRes);
-        for (unsigned i = 0; i < array->length(); i++)
-            ArrayItemHelper<T>::Traits::template assertCorrectValue<T>(array->get(i).get());
-    }
-#endif // !ASSERT_DISABLED
-};
-
-struct StructItemTraits {
-    static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
-    {
-        array->pushValue(value);
-    }
-
-#if !ASSERT_DISABLED
-    template<typename T>
-    static void assertCorrectValue(InspectorValue* value)
-    {
-        T::assertCorrectValue(value);
-    }
-#endif // !ASSERT_DISABLED
-};
-
-template<>
-struct ArrayItemHelper<String> {
-    struct Traits {
-        static void pushRaw(InspectorArray* array, const String& value)
-        {
-            array->pushString(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertType<InspectorValue::TypeString>(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<int> {
-    struct Traits {
-        static void pushRaw(InspectorArray* array, int value)
-        {
-            array->pushInt(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertInt(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<double> {
-    struct Traits {
-        static void pushRaw(InspectorArray* array, double value)
-        {
-            array->pushNumber(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertType<InspectorValue::TypeNumber>(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<bool> {
-    struct Traits {
-        static void pushRaw(InspectorArray* array, bool value)
-        {
-            array->pushBoolean(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertType<InspectorValue::TypeBoolean>(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<InspectorValue> {
-    struct Traits {
-        static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
-        {
-            array->pushValue(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertAny(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<InspectorObject> {
-    struct Traits {
-        static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
-        {
-            array->pushValue(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertType<InspectorValue::TypeObject>(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<>
-struct ArrayItemHelper<InspectorArray> {
-    struct Traits {
-        static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorArray> value)
-        {
-            array->pushArray(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename T>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            RuntimeCastHelper::assertType<InspectorValue::TypeArray>(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-template<typename T>
-struct ArrayItemHelper<TypeBuilder::Array<T>> {
-    struct Traits {
-        static void pushRefPtr(InspectorArray* array, PassRefPtr<TypeBuilder::Array<T>> value)
-        {
-            array->pushValue(value);
-        }
-
-#if !ASSERT_DISABLED
-        template<typename S>
-        static void assertCorrectValue(InspectorValue* value)
-        {
-            S::assertCorrectValue(value);
-        }
-#endif // !ASSERT_DISABLED
-    };
-};
-
-} // namespace TypeBuilder
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // !defined(InspectorTypeBuilder_h)
index 192fb6c9d90924e617c5d32c5d2e3bb9fccd3e1a..5896ad6e6d02f26dbb1aaed9caf3529c73fa8425 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -63,8 +64,10 @@ const char* const falseString = "false";
 bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token)
 {
     while (start < end && *token != '\0' && *start++ == *token++) { }
+
     if (*token != '\0')
         return false;
+
     *tokenEnd = start;
     return true;
 }
@@ -73,16 +76,20 @@ bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool
 {
     if (start == end)
         return false;
+
     bool haveLeadingZero = '0' == *start;
     int length = 0;
     while (start < end && '0' <= *start && *start <= '9') {
         ++start;
         ++length;
     }
+
     if (!length)
         return false;
+
     if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
         return false;
+
     *tokenEnd = start;
     return true;
 }
@@ -93,12 +100,14 @@ bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenE
     // According   to RFC4627, a valid number is: [minus] int [frac] [exp]
     if (start == end)
         return false;
+
     UChar c = *start;
     if ('-' == c)
         ++start;
 
     if (!readInt(start, end, &start, false))
         return false;
+
     if (start == end) {
         *tokenEnd = start;
         return true;
@@ -140,11 +149,13 @@ bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd,
 {
     if (end - start < digits)
         return false;
+
     for (int i = 0; i < digits; ++i) {
         UChar c = *start++;
         if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
             return false;
     }
+
     *tokenEnd = start;
     return true;
 }
@@ -183,6 +194,7 @@ bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenE
             return true;
         }
     }
+
     return false;
 }
 
@@ -246,6 +258,7 @@ Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart,
             return STRING;
         break;
     }
+
     return INVALID_TOKEN;
 }
 
@@ -257,16 +270,17 @@ inline int hexToInt(UChar c)
         return c - 'A' + 10;
     if ('a' <= c && c <= 'f')
         return c - 'a' + 10;
+
     ASSERT_NOT_REACHED();
     return 0;
 }
 
-bool decodeString(const UChar* start, const UChar* end, StringBuilder* output)
+bool decodeString(const UChar* start, const UChar* end, StringBuilder& output)
 {
     while (start < end) {
         UChar c = *start++;
         if ('\\' != c) {
-            output->append(c);
+            output.append(c);
             continue;
         }
         c = *start++;
@@ -308,28 +322,32 @@ bool decodeString(const UChar* start, const UChar* end, StringBuilder* output)
         default:
             return false;
         }
-        output->append(c);
+        output.append(c);
     }
+
     return true;
 }
 
-bool decodeString(const UChar* start, const UChar* end, String* output)
+bool decodeString(const UChar* start, const UChar* end, String& output)
 {
     if (start == end) {
-        *output = "";
+        output = emptyString();
         return true;
     }
+
     if (start > end)
         return false;
+
     StringBuilder buffer;
     buffer.reserveCapacity(end - start);
-    if (!decodeString(start, end, &buffer))
+    if (!decodeString(start, end, buffer))
         return false;
-    *output = buffer.toString();
+
+    output = buffer.toString();
     return true;
 }
 
-PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth)
+RefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth)
 {
     if (depth > stackLimit)
         return nullptr;
@@ -360,21 +378,21 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons
     }
     case STRING: {
         String value;
-        bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
+        bool ok = decodeString(tokenStart + 1, tokenEnd - 1, value);
         if (!ok)
             return nullptr;
         result = InspectorString::create(value);
         break;
     }
     case ARRAY_BEGIN: {
-        RefPtr<InspectorArray> array = InspectorArray::create();
+        Ref<InspectorArray> array = InspectorArray::create();
         start = tokenEnd;
         token = parseToken(start, end, &tokenStart, &tokenEnd);
         while (token != ARRAY_END) {
             RefPtr<InspectorValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
             if (!arrayNode)
                 return nullptr;
-            array->pushValue(arrayNode);
+            array->pushValue(WTF::move(arrayNode));
 
             // After a list value, we expect a comma or the end of the list.
             start = tokenEnd;
@@ -391,18 +409,18 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons
         }
         if (token != ARRAY_END)
             return nullptr;
-        result = array.release();
+        result = WTF::move(array);
         break;
     }
     case OBJECT_BEGIN: {
-        RefPtr<InspectorObject> object = InspectorObject::create();
+        Ref<InspectorObject> object = InspectorObject::create();
         start = tokenEnd;
         token = parseToken(start, end, &tokenStart, &tokenEnd);
         while (token != OBJECT_END) {
             if (token != STRING)
                 return nullptr;
             String key;
-            if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
+            if (!decodeString(tokenStart + 1, tokenEnd - 1, key))
                 return nullptr;
             start = tokenEnd;
 
@@ -414,7 +432,7 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons
             RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, depth + 1);
             if (!value)
                 return nullptr;
-            object->setValue(key, value);
+            object->setValue(key, WTF::move(value));
             start = tokenEnd;
 
             // After a key/value pair, we expect a comma or the end of the
@@ -432,7 +450,7 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons
         }
         if (token != OBJECT_END)
             return nullptr;
-        result = object.release();
+        result = WTF::move(object);
         break;
     }
 
@@ -444,25 +462,25 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons
     return result.release();
 }
 
-inline bool escapeChar(UChar c, StringBuilder* dst)
+inline bool escapeChar(UChar c, StringBuilder& dst)
 {
     switch (c) {
-    case '\b': dst->append("\\b", 2); break;
-    case '\f': dst->append("\\f", 2); break;
-    case '\n': dst->append("\\n", 2); break;
-    case '\r': dst->append("\\r", 2); break;
-    case '\t': dst->append("\\t", 2); break;
-    case '\\': dst->append("\\\\", 2); break;
-    case '"': dst->append("\\\"", 2); break;
+    case '\b': dst.appendLiteral("\\b"); break;
+    case '\f': dst.appendLiteral("\\f"); break;
+    case '\n': dst.appendLiteral("\\n"); break;
+    case '\r': dst.appendLiteral("\\r"); break;
+    case '\t': dst.appendLiteral("\\t"); break;
+    case '\\': dst.appendLiteral("\\\\"); break;
+    case '"': dst.appendLiteral("\\\""); break;
     default:
         return false;
     }
     return true;
 }
 
-inline void doubleQuoteString(const String& str, StringBuilder* dst)
+inline void doubleQuoteString(const String& str, StringBuilder& dst)
 {
-    dst->append('"');
+    dst.append('"');
     for (unsigned i = 0; i < str.length(); ++i) {
         UChar c = str[i];
         if (!escapeChar(c, dst)) {
@@ -470,203 +488,206 @@ inline void doubleQuoteString(const String& str, StringBuilder* dst)
                 // 1. Escaping <, > to prevent script execution.
                 // 2. Technically, we could also pass through c > 126 as UTF8, but this
                 //    is also optional.  It would also be a pain to implement here.
-                dst->append(String::format("\\u%04X", c));
+                dst.append(String::format("\\u%04X", c));
             } else
-                dst->append(c);
+                dst.append(c);
         }
     }
-    dst->append('"');
+    dst.append('"');
 }
 
 } // anonymous namespace
 
-bool InspectorValue::asBoolean(bool*) const
+bool InspectorValue::asBoolean(bool&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(double*) const
+bool InspectorValue::asDouble(double&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(float*) const
+bool InspectorValue::asDouble(float&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(int*) const
+bool InspectorValue::asInteger(int&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(unsigned*) const
+bool InspectorValue::asInteger(unsigned&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(long*) const
+bool InspectorValue::asInteger(long&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(long long*) const
+bool InspectorValue::asInteger(long long&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(unsigned long*) const
+bool InspectorValue::asInteger(unsigned long&) const
 {
     return false;
 }
 
-bool InspectorValue::asNumber(unsigned long long*) const
+bool InspectorValue::asInteger(unsigned long long&) const
 {
     return false;
 }
 
-bool InspectorValue::asString(String*) const
+bool InspectorValue::asString(String&) const
 {
     return false;
 }
 
-bool InspectorValue::asValue(RefPtr<InspectorValue>* output)
+bool InspectorValue::asValue(RefPtr<InspectorValue>& output)
 {
-    *output = this;
+    output = this;
     return true;
 }
 
-bool InspectorValue::asObject(RefPtr<InspectorObject>*)
+bool InspectorValue::asObject(RefPtr<InspectorObject>&)
 {
     return false;
 }
 
-bool InspectorValue::asArray(RefPtr<InspectorArray>*)
+bool InspectorValue::asArray(RefPtr<InspectorArray>&)
 {
     return false;
 }
 
-PassRefPtr<InspectorObject> InspectorValue::asObject()
-{
-    return nullptr;
-}
-
-PassRefPtr<InspectorArray> InspectorValue::asArray()
-{
-    return nullptr;
-}
-
-PassRefPtr<InspectorValue> InspectorValue::parseJSON(const String& json)
+bool InspectorValue::parseJSON(const String& jsonInput, RefPtr<InspectorValue>& output)
 {
     // FIXME: This whole file should just use StringView instead of UChar/length and avoid upconverting.
-    auto characters = StringView(json).upconvertedCharacters();
+    auto characters = StringView(jsonInput).upconvertedCharacters();
     const UChar* start = characters;
-    const UChar* end = start + json.length();
+    const UChar* end = start + jsonInput.length();
     const UChar* tokenEnd;
-    RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, 0);
-    if (!value || tokenEnd != end)
-        return nullptr;
-    return value.release();
+    RefPtr<InspectorValue> result = buildValue(start, end, &tokenEnd, 0);
+    if (!result || tokenEnd != end)
+        return false;
+
+    output = result.release();
+    return true;
 }
 
 String InspectorValue::toJSONString() const
 {
     StringBuilder result;
     result.reserveCapacity(512);
-    writeJSON(&result);
+    writeJSON(result);
     return result.toString();
 }
 
-void InspectorValue::writeJSON(StringBuilder* output) const
+void InspectorValue::writeJSON(StringBuilder& output) const
 {
-    ASSERT(m_type == TypeNull);
-    output->append(nullString, 4);
+    ASSERT(m_type == Type::Null);
+
+    output.appendLiteral("null");
 }
 
-bool InspectorBasicValue::asBoolean(bool* output) const
+bool InspectorBasicValue::asBoolean(bool& output) const
 {
-    if (type() != TypeBoolean)
+    if (type() != Type::Boolean)
         return false;
-    *output = m_boolValue;
+
+    output = m_booleanValue;
     return true;
 }
 
-bool InspectorBasicValue::asNumber(double* output) const
+bool InspectorBasicValue::asDouble(double& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Double)
         return false;
-    *output = m_doubleValue;
+
+    output = m_doubleValue;
     return true;
 }
 
-bool InspectorBasicValue::asNumber(float* output) const
+bool InspectorBasicValue::asDouble(float& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Double)
         return false;
-    *output = static_cast<float>(m_doubleValue);
+
+    output = static_cast<float>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(int* output) const
+bool InspectorBasicValue::asInteger(int& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<int>(m_doubleValue);
+
+    output = static_cast<int>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(unsigned* output) const
+bool InspectorBasicValue::asInteger(unsigned& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<unsigned>(m_doubleValue);
+
+    output = static_cast<unsigned>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(long* output) const
+bool InspectorBasicValue::asInteger(long& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<long>(m_doubleValue);
+
+    output = static_cast<long>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(long long* output) const
+bool InspectorBasicValue::asInteger(long long& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<long long>(m_doubleValue);
+
+    output = static_cast<long long>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(unsigned long* output) const
+bool InspectorBasicValue::asInteger(unsigned long& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<unsigned long>(m_doubleValue);
+
+    output = static_cast<unsigned long>(m_doubleValue);
     return true;
 }
 
-bool InspectorBasicValue::asNumber(unsigned long long* output) const
+bool InspectorBasicValue::asInteger(unsigned long long& output) const
 {
-    if (type() != TypeNumber)
+    if (type() != Type::Integer && type() != Type::Double)
         return false;
-    *output = static_cast<unsigned long long>(m_doubleValue);
+
+    output = static_cast<unsigned long long>(m_doubleValue);
     return true;
 }
 
-void InspectorBasicValue::writeJSON(StringBuilder* output) const
+void InspectorBasicValue::writeJSON(StringBuilder& output) const
 {
-    ASSERT(type() == TypeBoolean || type() == TypeNumber);
-    if (type() == TypeBoolean) {
-        if (m_boolValue)
-            output->append(trueString, 4);
+    ASSERT(type() == Type::Boolean || type() == Type::Double || type() == Type::Integer);
+
+    if (type() == Type::Boolean) {
+        if (m_booleanValue)
+            output.appendLiteral("true");
         else
-            output->append(falseString, 5);
-    } else if (type() == TypeNumber) {
+            output.appendLiteral("false");
+    } else if (type() == Type::Double || type() == Type::Integer) {
         NumberToLStringBuffer buffer;
         if (!std::isfinite(m_doubleValue)) {
-            output->append(nullString, 4);
+            output.appendLiteral("null");
             return;
         }
         DecimalNumber decimal = m_doubleValue;
@@ -675,25 +696,25 @@ void InspectorBasicValue::writeJSON(StringBuilder* output) const
             // Not enough room for decimal. Use exponential format.
             if (decimal.bufferLengthForStringExponential() > WTF::NumberToStringBufferLength) {
                 // Fallback for an abnormal case if it's too little even for exponential.
-                output->append("NaN", 3);
+                output.appendLiteral("NaN");
                 return;
             }
             length = decimal.toStringExponential(buffer, WTF::NumberToStringBufferLength);
         } else
             length = decimal.toStringDecimal(buffer, WTF::NumberToStringBufferLength);
-        output->append(buffer, length);
+        output.append(buffer, length);
     }
 }
 
-bool InspectorString::asString(String* output) const
+bool InspectorString::asString(String& output) const
 {
-    *output = m_stringValue;
+    output = m_stringValue;
     return true;
 }
 
-void InspectorString::writeJSON(StringBuilder* output) const
+void InspectorString::writeJSON(StringBuilder& output) const
 {
-    ASSERT(type() == TypeString);
+    ASSERT(type() == Type::String);
     doubleQuoteString(m_stringValue, output);
 }
 
@@ -701,92 +722,90 @@ InspectorObjectBase::~InspectorObjectBase()
 {
 }
 
-bool InspectorObjectBase::asObject(RefPtr<InspectorObject>* output)
+bool InspectorObjectBase::asObject(RefPtr<InspectorObject>& output)
 {
     COMPILE_ASSERT(sizeof(InspectorObject) == sizeof(InspectorObjectBase), cannot_cast);
-    *output = static_cast<InspectorObject*>(this);
-    return true;
-}
 
-PassRefPtr<InspectorObject> InspectorObjectBase::asObject()
-{
-    return openAccessors();
+    output = static_cast<InspectorObject*>(this);
+    return true;
 }
 
 InspectorObject* InspectorObjectBase::openAccessors()
 {
     COMPILE_ASSERT(sizeof(InspectorObject) == sizeof(InspectorObjectBase), cannot_cast);
+
     return static_cast<InspectorObject*>(this);
 }
 
-bool InspectorObjectBase::getBoolean(const String& name, bool* output) const
+bool InspectorObjectBase::getBoolean(const String& name, bool& output) const
 {
-    RefPtr<InspectorValue> value = get(name);
-    if (!value)
+    RefPtr<InspectorValue> value;
+    if (!getValue(name, value))
         return false;
+
     return value->asBoolean(output);
 }
 
-bool InspectorObjectBase::getString(const String& name, String* output) const
+bool InspectorObjectBase::getString(const String& name, String& output) const
 {
-    RefPtr<InspectorValue> value = get(name);
-    if (!value)
+    RefPtr<InspectorValue> value;
+    if (!getValue(name, value))
         return false;
+
     return value->asString(output);
 }
 
-PassRefPtr<InspectorObject> InspectorObjectBase::getObject(const String& name) const
+bool InspectorObjectBase::getObject(const String& name, RefPtr<InspectorObject>& output) const
 {
-    PassRefPtr<InspectorValue> value = get(name);
-    if (!value)
-        return nullptr;
-    return value->asObject();
+    RefPtr<InspectorValue> value;
+    if (!getValue(name, value))
+        return false;
+
+    return value->asObject(output);
 }
 
-PassRefPtr<InspectorArray> InspectorObjectBase::getArray(const String& name) const
+bool InspectorObjectBase::getArray(const String& name, RefPtr<InspectorArray>& output) const
 {
-    PassRefPtr<InspectorValue> value = get(name);
-    if (!value)
-        return nullptr;
-    return value->asArray();
+    RefPtr<InspectorValue> value;
+    if (!getValue(name, value))
+        return false;
+
+    return value->asArray(output);
 }
 
-PassRefPtr<InspectorValue> InspectorObjectBase::get(const String& name) const
+bool InspectorObjectBase::getValue(const String& name, RefPtr<InspectorValue>& output) const
 {
-    Dictionary::const_iterator it = m_data.find(name);
-    if (it == m_data.end())
-        return nullptr;
-    return it->value;
+    Dictionary::const_iterator findResult = m_data.find(name);
+    if (findResult == m_data.end())
+        return false;
+
+    output = findResult->value;
+    return true;
 }
 
 void InspectorObjectBase::remove(const String& name)
 {
     m_data.remove(name);
-    for (size_t i = 0; i < m_order.size(); ++i) {
-        if (m_order[i] == name) {
-            m_order.remove(i);
-            break;
-        }
-    }
+    m_order.removeFirst(name);
 }
 
-void InspectorObjectBase::writeJSON(StringBuilder* output) const
+void InspectorObjectBase::writeJSON(StringBuilder& output) const
 {
-    output->append('{');
+    output.append('{');
     for (size_t i = 0; i < m_order.size(); ++i) {
-        Dictionary::const_iterator it = m_data.find(m_order[i]);
-        ASSERT(it != m_data.end());
+        auto findResult = m_data.find(m_order[i]);
+        ASSERT(findResult != m_data.end());
         if (i)
-            output->append(',');
-        doubleQuoteString(it->key, output);
-        output->append(':');
-        it->value->writeJSON(output);
+            output.append(',');
+        doubleQuoteString(findResult->key, output);
+        output.append(':');
+        findResult->value->writeJSON(output);
     }
-    output->append('}');
+    output.append('}');
 }
 
 InspectorObjectBase::InspectorObjectBase()
-    : InspectorValue(TypeObject)
+    : InspectorValue(Type::Object)
     , m_data()
     , m_order()
 {
@@ -796,80 +815,74 @@ InspectorArrayBase::~InspectorArrayBase()
 {
 }
 
-bool InspectorArrayBase::asArray(RefPtr<InspectorArray>* output)
+bool InspectorArrayBase::asArray(RefPtr<InspectorArray>& output)
 {
     COMPILE_ASSERT(sizeof(InspectorArrayBase) == sizeof(InspectorArray), cannot_cast);
-    *output = static_cast<InspectorArray*>(this);
+    output = static_cast<InspectorArray*>(this);
     return true;
 }
 
-PassRefPtr<InspectorArray> InspectorArrayBase::asArray()
-{
-    COMPILE_ASSERT(sizeof(InspectorArrayBase) == sizeof(InspectorArray), cannot_cast);
-    return static_cast<InspectorArray*>(this);
-}
-
-void InspectorArrayBase::writeJSON(StringBuilder* output) const
+void InspectorArrayBase::writeJSON(StringBuilder& output) const
 {
-    output->append('[');
+    output.append('[');
     for (Vector<RefPtr<InspectorValue>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
         if (it != m_data.begin())
-            output->append(',');
+            output.append(',');
         (*it)->writeJSON(output);
     }
-    output->append(']');
+    output.append(']');
 }
 
 InspectorArrayBase::InspectorArrayBase()
-    : InspectorValue(TypeArray)
+    : InspectorValue(Type::Array)
     , m_data()
 {
 }
 
-PassRefPtr<InspectorValue> InspectorArrayBase::get(size_t index)
+RefPtr<InspectorValue> InspectorArrayBase::get(size_t index) const
 {
     ASSERT_WITH_SECURITY_IMPLICATION(index < m_data.size());
     return m_data[index];
 }
 
-PassRefPtr<InspectorObject> InspectorObject::create()
+Ref<InspectorObject> InspectorObject::create()
 {
-    return adoptRef(new InspectorObject);
+    return adoptRef(*new InspectorObject);
 }
 
-PassRefPtr<InspectorArray> InspectorArray::create()
+Ref<InspectorArray> InspectorArray::create()
 {
-    return adoptRef(new InspectorArray);
+    return adoptRef(*new InspectorArray);
 }
 
-PassRefPtr<InspectorValue> InspectorValue::null()
+Ref<InspectorValue> InspectorValue::null()
 {
-    return adoptRef(new InspectorValue);
+    return adoptRef(*new InspectorValue);
 }
 
-PassRefPtr<InspectorString> InspectorString::create(const String& value)
+Ref<InspectorString> InspectorString::create(const String& value)
 {
-    return adoptRef(new InspectorString(value));
+    return adoptRef(*new InspectorString(value));
 }
 
-PassRefPtr<InspectorString> InspectorString::create(const char* value)
+Ref<InspectorString> InspectorString::create(const char* value)
 {
-    return adoptRef(new InspectorString(value));
+    return adoptRef(*new InspectorString(value));
 }
 
-PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(bool value)
+Ref<InspectorBasicValue> InspectorBasicValue::create(bool value)
 {
-    return adoptRef(new InspectorBasicValue(value));
+    return adoptRef(*new InspectorBasicValue(value));
 }
 
-PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(int value)
+Ref<InspectorBasicValue> InspectorBasicValue::create(int value)
 {
-    return adoptRef(new InspectorBasicValue(value));
+    return adoptRef(*new InspectorBasicValue(value));
 }
 
-PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(double value)
+Ref<InspectorBasicValue> InspectorBasicValue::create(double value)
 {
-    return adoptRef(new InspectorBasicValue(value));
+    return adoptRef(*new InspectorBasicValue(value));
 }
 
 } // namespace Inspector
index 3b861664da3379deb5689bc00134de26eba673da..db05036d0c0dc5237a46b587283cd6e610b715e8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
 #ifndef InspectorValues_h
 #define InspectorValues_h
 
-#include <wtf/Forward.h>
+#include <wtf/Assertions.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 namespace Inspector {
 
 class InspectorArray;
+class InspectorArrayBase;
 class InspectorObject;
+class InspectorObjectBase;
 
 class JS_EXPORT_PRIVATE InspectorValue : public RefCounted<InspectorValue> {
 public:
     static const int maxDepth = 1000;
 
-    InspectorValue() : m_type(TypeNull) { }
+    InspectorValue()
+        : m_type(Type::Null) { }
     virtual ~InspectorValue() { }
 
-    static PassRefPtr<InspectorValue> null();
+    static Ref<InspectorValue> null();
 
-    typedef enum {
-        TypeNull = 0,
-        TypeBoolean,
-        TypeNumber,
-        TypeString,
-        TypeObject,
-        TypeArray
-    } Type;
+    enum class Type {
+        Null = 0,
+        Boolean,
+        Double,
+        Integer,
+        String,
+        Object,
+        Array
+    };
 
     Type type() const { return m_type; }
 
-    bool isNull() const { return m_type == TypeNull; }
-
-    virtual bool asBoolean(bool* output) const;
-    virtual bool asNumber(double* output) const;
-    virtual bool asNumber(float* output) const;
-    virtual bool asNumber(int* output) const;
-    virtual bool asNumber(unsigned* output) const;
-    virtual bool asNumber(long* output) const;
-    virtual bool asNumber(long long* output) const;
-    virtual bool asNumber(unsigned long* output) const;
-    virtual bool asNumber(unsigned long long* output) const;
-    virtual bool asString(String* output) const;
-    virtual bool asValue(RefPtr<InspectorValue>* output);
-    virtual bool asObject(RefPtr<InspectorObject>* output);
-    virtual bool asArray(RefPtr<InspectorArray>* output);
-    virtual PassRefPtr<InspectorObject> asObject();
-    virtual PassRefPtr<InspectorArray> asArray();
-
-    static PassRefPtr<InspectorValue> parseJSON(const String& json);
+    bool isNull() const { return m_type == Type::Null; }
+
+    virtual bool asBoolean(bool&) const;
+    virtual bool asInteger(int&) const;
+    virtual bool asInteger(unsigned&) const;
+    virtual bool asInteger(long&) const;
+    virtual bool asInteger(long long&) const;
+    virtual bool asInteger(unsigned long&) const;
+    virtual bool asInteger(unsigned long long&) const;
+    virtual bool asDouble(double&) const;
+    virtual bool asDouble(float&) const;
+    virtual bool asString(String&) const;
+    virtual bool asValue(RefPtr<InspectorValue>&);
+    virtual bool asObject(RefPtr<InspectorObject>&);
+    virtual bool asArray(RefPtr<InspectorArray>&);
+
+    static bool parseJSON(const String& jsonInput, RefPtr<InspectorValue>& output);
 
     String toJSONString() const;
-    virtual void writeJSON(StringBuilder* output) const;
+    virtual void writeJSON(StringBuilder& output) const;
 
 protected:
     explicit InspectorValue(Type type) : m_type(type) { }
@@ -96,45 +99,60 @@ private:
 class JS_EXPORT_PRIVATE InspectorBasicValue : public InspectorValue {
 public:
 
-    static PassRefPtr<InspectorBasicValue> create(bool);
-    static PassRefPtr<InspectorBasicValue> create(int);
-    static PassRefPtr<InspectorBasicValue> create(double);
+    static Ref<InspectorBasicValue> create(bool);
+    static Ref<InspectorBasicValue> create(int);
+    static Ref<InspectorBasicValue> create(double);
 
-    virtual bool asBoolean(bool* output) const override;
-    virtual bool asNumber(double* output) const override;
-    virtual bool asNumber(float* output) const override;
-    virtual bool asNumber(int* output) const override;
-    virtual bool asNumber(unsigned* output) const override;
-    virtual bool asNumber(long* output) const override;
-    virtual bool asNumber(long long* output) const override;
-    virtual bool asNumber(unsigned long* output) const override;
-    virtual bool asNumber(unsigned long long* output) const override;
+    virtual bool asBoolean(bool&) const override;
+    // Numbers from the frontend are always parsed as doubles, so we allow
+    // clients to convert to integral values with this function.
+    virtual bool asInteger(int&) const override;
+    virtual bool asInteger(unsigned&) const override;
+    virtual bool asInteger(long&) const override;
+    virtual bool asInteger(long long&) const override;
+    virtual bool asInteger(unsigned long&) const override;
+    virtual bool asInteger(unsigned long long&) const override;
+    virtual bool asDouble(double&) const override;
+    virtual bool asDouble(float&) const override;
 
-    virtual void writeJSON(StringBuilder* output) const override;
+    virtual void writeJSON(StringBuilder& output) const override;
 
 private:
-    explicit InspectorBasicValue(bool value) : InspectorValue(TypeBoolean), m_boolValue(value) { }
-    explicit InspectorBasicValue(int value) : InspectorValue(TypeNumber), m_doubleValue((double)value) { }
-    explicit InspectorBasicValue(double value) : InspectorValue(TypeNumber), m_doubleValue(value) { }
+    explicit InspectorBasicValue(bool value)
+        : InspectorValue(Type::Boolean)
+        , m_booleanValue(value) { }
+
+    explicit InspectorBasicValue(int value)
+        : InspectorValue(Type::Integer)
+        , m_doubleValue(static_cast<double>(value)) { }
+
+    explicit InspectorBasicValue(double value)
+        : InspectorValue(Type::Double)
+        , m_doubleValue(value) { }
 
     union {
-        bool m_boolValue;
+        bool m_booleanValue;
         double m_doubleValue;
     };
 };
 
 class JS_EXPORT_PRIVATE InspectorString : public InspectorValue {
 public:
-    static PassRefPtr<InspectorString> create(const String&);
-    static PassRefPtr<InspectorString> create(const char*);
+    static Ref<InspectorString> create(const String&);
+    static Ref<InspectorString> create(const char*);
 
-    virtual bool asString(String* output) const override;
+    virtual bool asString(String& output) const override;
 
-    virtual void writeJSON(StringBuilder* output) const override;
+    virtual void writeJSON(StringBuilder& output) const override;
 
 private:
-    explicit InspectorString(const String& value) : InspectorValue(TypeString), m_stringValue(value) { }
-    explicit InspectorString(const char* value) : InspectorValue(TypeString), m_stringValue(value) { }
+    explicit InspectorString(const String& value)
+        : InspectorValue(Type::String)
+        , m_stringValue(value) { }
+
+    explicit InspectorString(const char* value)
+        : InspectorValue(Type::String)
+        , m_stringValue(value) { }
 
     String m_stringValue;
 };
@@ -147,39 +165,52 @@ public:
     typedef Dictionary::iterator iterator;
     typedef Dictionary::const_iterator const_iterator;
 
-    virtual PassRefPtr<InspectorObject> asObject() override;
     InspectorObject* openAccessors();
 
 protected:
     virtual ~InspectorObjectBase();
 
-    virtual bool asObject(RefPtr<InspectorObject>* output) override;
+    virtual bool asObject(RefPtr<InspectorObject>& output) override;
 
+    // FIXME: use templates to reduce the amount of duplicated set*() methods.
     void setBoolean(const String& name, bool);
-    void setNumber(const String& name, double);
+    void setInteger(const String& name, int);
+    void setDouble(const String& name, double);
     void setString(const String& name, const String&);
-    void setValue(const String& name, PassRefPtr<InspectorValue>);
-    void setObject(const String& name, PassRefPtr<InspectorObject>);
-    void setArray(const String& name, PassRefPtr<InspectorArray>);
+    void setValue(const String& name, RefPtr<InspectorValue>&&);
+    void setObject(const String& name, RefPtr<InspectorObjectBase>&&);
+    void setArray(const String& name, RefPtr<InspectorArrayBase>&&);
 
     iterator find(const String& name);
     const_iterator find(const String& name) const;
-    bool getBoolean(const String& name, bool* output) const;
-    template<class T> bool getNumber(const String& name, T* output) const
+
+    // FIXME: use templates to reduce the amount of duplicated get*() methods.
+    bool getBoolean(const String& name, bool& output) const;
+    template<class T> bool getDouble(const String& name, T& output) const
+    {
+        RefPtr<InspectorValue> value;
+        if (!getValue(name, value))
+            return false;
+
+        return value->asDouble(output);
+    }
+    template<class T> bool getInteger(const String& name, T& output) const
     {
-        RefPtr<InspectorValue> value = get(name);
-        if (!value)
+        RefPtr<InspectorValue> value;
+        if (!getValue(name, value))
             return false;
-        return value->asNumber(output);
+
+        return value->asInteger(output);
     }
-    bool getString(const String& name, String* output) const;
-    PassRefPtr<InspectorObject> getObject(const String& name) const;
-    PassRefPtr<InspectorArray> getArray(const String& name) const;
-    PassRefPtr<InspectorValue> get(const String& name) const;
+
+    bool getString(const String& name, String& output) const;
+    bool getObject(const String& name, RefPtr<InspectorObject>&) const;
+    bool getArray(const String& name, RefPtr<InspectorArray>&) const;
+    bool getValue(const String& name, RefPtr<InspectorValue>&) const;
 
     void remove(const String& name);
 
-    virtual void writeJSON(StringBuilder* output) const override;
+    virtual void writeJSON(StringBuilder& output) const override;
 
     iterator begin() { return m_data.begin(); }
     iterator end() { return m_data.end(); }
@@ -198,12 +229,13 @@ private:
 
 class InspectorObject : public InspectorObjectBase {
 public:
-    static JS_EXPORT_PRIVATE PassRefPtr<InspectorObject> create();
+    static JS_EXPORT_PRIVATE Ref<InspectorObject> create();
 
     using InspectorObjectBase::asObject;
 
     using InspectorObjectBase::setBoolean;
-    using InspectorObjectBase::setNumber;
+    using InspectorObjectBase::setInteger;
+    using InspectorObjectBase::setDouble;
     using InspectorObjectBase::setString;
     using InspectorObjectBase::setValue;
     using InspectorObjectBase::setObject;
@@ -211,11 +243,12 @@ public:
 
     using InspectorObjectBase::find;
     using InspectorObjectBase::getBoolean;
-    using InspectorObjectBase::getNumber;
+    using InspectorObjectBase::getInteger;
+    using InspectorObjectBase::getDouble;
     using InspectorObjectBase::getString;
     using InspectorObjectBase::getObject;
     using InspectorObjectBase::getArray;
-    using InspectorObjectBase::get;
+    using InspectorObjectBase::getValue;
 
     using InspectorObjectBase::remove;
 
@@ -231,26 +264,24 @@ public:
     typedef Vector<RefPtr<InspectorValue>>::iterator iterator;
     typedef Vector<RefPtr<InspectorValue>>::const_iterator const_iterator;
 
-    virtual PassRefPtr<InspectorArray> asArray() override;
-
-    unsigned length() const { return m_data.size(); }
+    unsigned length() const { return static_cast<unsigned>(m_data.size()); }
 
 protected:
     virtual ~InspectorArrayBase();
 
-    virtual bool asArray(RefPtr<InspectorArray>* output) override;
+    virtual bool asArray(RefPtr<InspectorArray>&) override;
 
     void pushBoolean(bool);
-    void pushInt(int);
-    void pushNumber(double);
+    void pushInteger(int);
+    void pushDouble(double);
     void pushString(const String&);
-    void pushValue(PassRefPtr<InspectorValue>);
-    void pushObject(PassRefPtr<InspectorObject>);
-    void pushArray(PassRefPtr<InspectorArray>);
+    void pushValue(RefPtr<InspectorValue>&&);
+    void pushObject(RefPtr<InspectorObjectBase>&&);
+    void pushArray(RefPtr<InspectorArrayBase>&&);
 
-    PassRefPtr<InspectorValue> get(size_t index);
+    RefPtr<InspectorValue> get(size_t index) const;
 
-    virtual void writeJSON(StringBuilder* output) const override;
+    virtual void writeJSON(StringBuilder& output) const override;
 
     iterator begin() { return m_data.begin(); }
     iterator end() { return m_data.end(); }
@@ -266,13 +297,13 @@ private:
 
 class InspectorArray : public InspectorArrayBase {
 public:
-    static JS_EXPORT_PRIVATE PassRefPtr<InspectorArray> create();
+    static JS_EXPORT_PRIVATE Ref<InspectorArray> create();
 
     using InspectorArrayBase::asArray;
 
     using InspectorArrayBase::pushBoolean;
-    using InspectorArrayBase::pushInt;
-    using InspectorArrayBase::pushNumber;
+    using InspectorArrayBase::pushInteger;
+    using InspectorArrayBase::pushDouble;
     using InspectorArrayBase::pushString;
     using InspectorArrayBase::pushValue;
     using InspectorArrayBase::pushObject;
@@ -300,7 +331,12 @@ inline void InspectorObjectBase::setBoolean(const String& name, bool value)
     setValue(name, InspectorBasicValue::create(value));
 }
 
-inline void InspectorObjectBase::setNumber(const String& name, double value)
+inline void InspectorObjectBase::setInteger(const String& name, int value)
+{
+    setValue(name, InspectorBasicValue::create(value));
+}
+
+inline void InspectorObjectBase::setDouble(const String& name, double value)
 {
     setValue(name, InspectorBasicValue::create(value));
 }
@@ -310,24 +346,24 @@ inline void InspectorObjectBase::setString(const String& name, const String& val
     setValue(name, InspectorString::create(value));
 }
 
-inline void InspectorObjectBase::setValue(const String& name, PassRefPtr<InspectorValue> value)
+inline void InspectorObjectBase::setValue(const String& name, RefPtr<InspectorValue>&& value)
 {
     ASSERT(value);
-    if (m_data.set(name, value).isNewEntry)
+    if (m_data.set(name, WTF::move(value)).isNewEntry)
         m_order.append(name);
 }
 
-inline void InspectorObjectBase::setObject(const String& name, PassRefPtr<InspectorObject> value)
+inline void InspectorObjectBase::setObject(const String& name, RefPtr<InspectorObjectBase>&& value)
 {
     ASSERT(value);
-    if (m_data.set(name, value).isNewEntry)
+    if (m_data.set(name, WTF::move(value)).isNewEntry)
         m_order.append(name);
 }
 
-inline void InspectorObjectBase::setArray(const String& name, PassRefPtr<InspectorArray> value)
+inline void InspectorObjectBase::setArray(const String& name, RefPtr<InspectorArrayBase>&& value)
 {
     ASSERT(value);
-    if (m_data.set(name, value).isNewEntry)
+    if (m_data.set(name, WTF::move(value)).isNewEntry)
         m_order.append(name);
 }
 
@@ -336,12 +372,12 @@ inline void InspectorArrayBase::pushBoolean(bool value)
     m_data.append(InspectorBasicValue::create(value));
 }
 
-inline void InspectorArrayBase::pushInt(int value)
+inline void InspectorArrayBase::pushInteger(int value)
 {
     m_data.append(InspectorBasicValue::create(value));
 }
 
-inline void InspectorArrayBase::pushNumber(double value)
+inline void InspectorArrayBase::pushDouble(double value)
 {
     m_data.append(InspectorBasicValue::create(value));
 }
@@ -351,22 +387,22 @@ inline void InspectorArrayBase::pushString(const String& value)
     m_data.append(InspectorString::create(value));
 }
 
-inline void InspectorArrayBase::pushValue(PassRefPtr<InspectorValue> value)
+inline void InspectorArrayBase::pushValue(RefPtr<InspectorValue>&& value)
 {
     ASSERT(value);
-    m_data.append(value);
+    m_data.append(WTF::move(value));
 }
 
-inline void InspectorArrayBase::pushObject(PassRefPtr<InspectorObject> value)
+inline void InspectorArrayBase::pushObject(RefPtr<InspectorObjectBase>&& value)
 {
     ASSERT(value);
-    m_data.append(value);
+    m_data.append(WTF::move(value));
 }
 
-inline void InspectorArrayBase::pushArray(PassRefPtr<InspectorArray> value)
+inline void InspectorArrayBase::pushArray(RefPtr<InspectorArrayBase>&& value)
 {
     ASSERT(value);
-    m_data.append(value);
+    m_data.append(WTF::move(value));
 }
 
 } // namespace Inspector
diff --git a/inspector/JSConsoleClient.cpp b/inspector/JSConsoleClient.cpp
deleted file mode 100644 (file)
index 019dba0..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSConsoleClient.h"
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorConsoleAgent.h"
-#include "InspectorProfilerAgent.h"
-#include "ScriptArguments.h"
-#include "ScriptCallStack.h"
-#include "ScriptCallStackFactory.h"
-
-#if USE(CF)
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-using namespace JSC;
-
-namespace Inspector {
-
-static bool sLogToSystemConsole = false;
-
-bool JSConsoleClient::logToSystemConsole()
-{
-    return sLogToSystemConsole;
-}
-
-void JSConsoleClient::setLogToSystemConsole(bool shouldLog)
-{
-    sLogToSystemConsole = shouldLog;
-}
-
-void JSConsoleClient::initializeLogToSystemConsole()
-{
-#if !LOG_DISABLED
-    sLogToSystemConsole = true;
-#elif USE(CF)
-    Boolean keyExistsAndHasValidFormat = false;
-    Boolean preference = CFPreferencesGetAppBooleanValue(CFSTR("JavaScriptCoreOutputConsoleMessagesToSystemConsole"), kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat);
-    if (keyExistsAndHasValidFormat)
-        sLogToSystemConsole = preference;
-#endif
-}
-
-JSConsoleClient::JSConsoleClient(InspectorConsoleAgent* consoleAgent, InspectorProfilerAgent* profilerAgent)
-    : ConsoleClient()
-    , m_consoleAgent(consoleAgent)
-    , m_profilerAgent(profilerAgent)
-{
-    static std::once_flag initializeLogging;
-    std::call_once(initializeLogging, []{
-        JSConsoleClient::initializeLogToSystemConsole();
-    });
-}
-
-void JSConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments)
-{
-    RefPtr<ScriptArguments> arguments = prpArguments;
-
-    if (JSConsoleClient::logToSystemConsole())
-        ConsoleClient::printConsoleMessageWithArguments(MessageSource::ConsoleAPI, type, level, exec, arguments);
-
-    String message;
-    arguments->getFirstArgumentAsString(message);
-    m_consoleAgent->addMessageToConsole(MessageSource::ConsoleAPI, type, level, message, exec, arguments.release());
-}
-
-void JSConsoleClient::count(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
-{
-    m_consoleAgent->count(exec, arguments);
-}
-
-void JSConsoleClient::profile(JSC::ExecState* exec, const String& title)
-{
-    if (!m_profilerAgent->enabled())
-        return;
-
-    String resolvedTitle = m_profilerAgent->startProfiling(title);
-
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, 1));
-    m_consoleAgent->addMessageToConsole(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Debug, resolvedTitle, callStack);
-}
-
-void JSConsoleClient::profileEnd(JSC::ExecState* exec, const String& title)
-{
-    if (!m_profilerAgent->enabled())
-        return;
-
-    RefPtr<JSC::Profile> profile = m_profilerAgent->stopProfiling(title);
-    if (!profile)
-        return;
-
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, 1));
-    String message = makeString(profile->title(), '#', String::number(profile->uid()));
-    m_consoleAgent->addMessageToConsole(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Debug, message, callStack);
-}
-
-void JSConsoleClient::time(ExecState*, const String& title)
-{
-    m_consoleAgent->startTiming(title);
-}
-
-void JSConsoleClient::timeEnd(ExecState* exec, const String& title)
-{
-    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, 1));
-    m_consoleAgent->stopTiming(title, callStack.release());
-}
-
-void JSConsoleClient::timeStamp(ExecState*, PassRefPtr<ScriptArguments>)
-{
-    // FIXME: JSContext inspection needs a timeline.
-    warnUnimplemented(ASCIILiteral("console.timeStamp"));
-}
-
-void JSConsoleClient::warnUnimplemented(const String& method)
-{
-    String message = method + " is currently ignored in JavaScript context inspection.";
-    m_consoleAgent->addMessageToConsole(MessageSource::ConsoleAPI, MessageType::Log, MessageLevel::Warning, message, nullptr, nullptr);
-}
-
-} // namespace Inspector
-
-#endif
diff --git a/inspector/JSConsoleClient.h b/inspector/JSConsoleClient.h
deleted file mode 100644 (file)
index 74132c6..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSConsoleClient_h
-#define JSConsoleClient_h
-
-#include "ConsoleClient.h"
-
-namespace Inspector {
-
-class InspectorConsoleAgent;
-class InspectorProfilerAgent;
-
-class JSConsoleClient final : public JSC::ConsoleClient {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit JSConsoleClient(InspectorConsoleAgent*, InspectorProfilerAgent*);
-    virtual ~JSConsoleClient() { }
-
-    static bool logToSystemConsole();
-    static void setLogToSystemConsole(bool);
-    static void initializeLogToSystemConsole();
-
-protected:
-    virtual void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, PassRefPtr<ScriptArguments>) override;
-    virtual void count(JSC::ExecState*, PassRefPtr<ScriptArguments>) override;
-    virtual void profile(JSC::ExecState*, const String& title) override;
-    virtual void profileEnd(JSC::ExecState*, const String& title) override;
-    virtual void time(JSC::ExecState*, const String& title) override;
-    virtual void timeEnd(JSC::ExecState*, const String& title) override;
-    virtual void timeStamp(JSC::ExecState*, PassRefPtr<ScriptArguments>) override;
-
-private:
-    void warnUnimplemented(const String& method);
-    void internalAddMessage(MessageType, MessageLevel, JSC::ExecState*, PassRefPtr<ScriptArguments>);
-
-    InspectorConsoleAgent* m_consoleAgent;
-    InspectorProfilerAgent* m_profilerAgent;
-};
-
-}
-
-#endif // !defined(JSConsoleClient_h)
diff --git a/inspector/JSGlobalObjectConsoleClient.cpp b/inspector/JSGlobalObjectConsoleClient.cpp
new file mode 100644 (file)
index 0000000..75b805f
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalObjectConsoleClient.h"
+
+#include "ConsoleMessage.h"
+#include "InspectorConsoleAgent.h"
+#include "ScriptArguments.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
+
+using namespace JSC;
+
+namespace Inspector {
+
+#if !LOG_DISABLED
+static bool sLogToSystemConsole = true;
+#else
+static bool sLogToSystemConsole = false;
+#endif
+
+bool JSGlobalObjectConsoleClient::logToSystemConsole()
+{
+    return sLogToSystemConsole;
+}
+
+void JSGlobalObjectConsoleClient::setLogToSystemConsole(bool shouldLog)
+{
+    sLogToSystemConsole = shouldLog;
+}
+
+JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient(InspectorConsoleAgent* consoleAgent)
+    : ConsoleClient()
+    , m_consoleAgent(consoleAgent)
+{
+}
+
+void JSGlobalObjectConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& arguments)
+{
+    if (JSGlobalObjectConsoleClient::logToSystemConsole())
+        ConsoleClient::printConsoleMessageWithArguments(MessageSource::ConsoleAPI, type, level, exec, arguments.copyRef());
+
+    String message;
+    arguments->getFirstArgumentAsString(message);
+    m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, type, level, message, WTF::move(arguments), exec));
+}
+
+void JSGlobalObjectConsoleClient::count(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
+{
+    m_consoleAgent->count(exec, arguments);
+}
+
+void JSGlobalObjectConsoleClient::profile(JSC::ExecState*, const String&)
+{
+    // FIXME: support |console.profile| for JSContexts. <https://webkit.org/b/136466>
+}
+
+void JSGlobalObjectConsoleClient::profileEnd(JSC::ExecState*, const String&)
+{
+    // FIXME: support |console.profile| for JSContexts. <https://webkit.org/b/136466>
+}
+
+void JSGlobalObjectConsoleClient::time(ExecState*, const String& title)
+{
+    m_consoleAgent->startTiming(title);
+}
+
+void JSGlobalObjectConsoleClient::timeEnd(ExecState* exec, const String& title)
+{
+    RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, 1));
+    m_consoleAgent->stopTiming(title, WTF::move(callStack));
+}
+
+void JSGlobalObjectConsoleClient::timeStamp(ExecState*, RefPtr<ScriptArguments>&&)
+{
+    // FIXME: JSContext inspection needs a timeline.
+    warnUnimplemented(ASCIILiteral("console.timeStamp"));
+}
+
+void JSGlobalObjectConsoleClient::warnUnimplemented(const String& method)
+{
+    String message = method + " is currently ignored in JavaScript context inspection.";
+    m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Log, MessageLevel::Warning, message, nullptr, nullptr));
+}
+
+} // namespace Inspector
diff --git a/inspector/JSGlobalObjectConsoleClient.h b/inspector/JSGlobalObjectConsoleClient.h
new file mode 100644 (file)
index 0000000..12e1e41
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSGlobalObjectConsoleClient_h
+#define JSGlobalObjectConsoleClient_h
+
+#include "ConsoleClient.h"
+
+namespace Inspector {
+
+class InspectorConsoleAgent;
+
+class JSGlobalObjectConsoleClient final : public JSC::ConsoleClient {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit JSGlobalObjectConsoleClient(InspectorConsoleAgent*);
+    virtual ~JSGlobalObjectConsoleClient() { }
+
+    static bool logToSystemConsole();
+    static void setLogToSystemConsole(bool);
+
+protected:
+    virtual void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, RefPtr<ScriptArguments>&&) override;
+    virtual void count(JSC::ExecState*, RefPtr<ScriptArguments>&&) override;
+    virtual void profile(JSC::ExecState*, const String& title) override;
+    virtual void profileEnd(JSC::ExecState*, const String& title) override;
+    virtual void time(JSC::ExecState*, const String& title) override;
+    virtual void timeEnd(JSC::ExecState*, const String& title) override;
+    virtual void timeStamp(JSC::ExecState*, RefPtr<ScriptArguments>&&) override;
+
+private:
+    void warnUnimplemented(const String& method);
+    void internalAddMessage(MessageType, MessageLevel, JSC::ExecState*, RefPtr<ScriptArguments>&&);
+
+    InspectorConsoleAgent* m_consoleAgent;
+};
+
+}
+
+#endif // !defined(JSGlobalObjectConsoleClient_h)
index ebdd1809625bdc85695bfe2e95c6c8a3dbc235a4..11d86ed3297503173716a85d935808fc677b5d48 100644 (file)
 #include "config.h"
 #include "JSGlobalObjectInspectorController.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "Completion.h"
+#include "ConsoleMessage.h"
 #include "ErrorHandlingScope.h"
+#include "Exception.h"
 #include "InjectedScriptHost.h"
 #include "InjectedScriptManager.h"
 #include "InspectorAgent.h"
 #include "InspectorBackendDispatcher.h"
 #include "InspectorFrontendChannel.h"
-#include "JSConsoleClient.h"
 #include "JSGlobalObject.h"
 #include "JSGlobalObjectConsoleAgent.h"
+#include "JSGlobalObjectConsoleClient.h"
 #include "JSGlobalObjectDebuggerAgent.h"
-#include "JSGlobalObjectProfilerAgent.h"
 #include "JSGlobalObjectRuntimeAgent.h"
 #include "ScriptArguments.h"
 #include "ScriptCallStack.h"
 #include "ScriptCallStackFactory.h"
+#include <wtf/Stopwatch.h>
+
 #include <cxxabi.h>
+#if OS(DARWIN) || (OS(LINUX) && !PLATFORM(GTK))
 #include <dlfcn.h>
 #include <execinfo.h>
+#endif
 
 #if ENABLE(REMOTE_INSPECTOR)
 #include "JSGlobalObjectDebuggable.h"
@@ -60,24 +63,32 @@ namespace Inspector {
 JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObject& globalObject)
     : m_globalObject(globalObject)
     , m_injectedScriptManager(std::make_unique<InjectedScriptManager>(*this, InjectedScriptHost::create()))
-    , m_inspectorFrontendChannel(nullptr)
+    , m_frontendChannel(nullptr)
+    , m_executionStopwatch(Stopwatch::create())
     , m_includeNativeCallStackWithExceptions(true)
+    , m_isAutomaticInspection(false)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_augmentingClient(nullptr)
+#endif
 {
+    auto inspectorAgent = std::make_unique<InspectorAgent>(*this);
     auto runtimeAgent = std::make_unique<JSGlobalObjectRuntimeAgent>(m_injectedScriptManager.get(), m_globalObject);
     auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(m_injectedScriptManager.get());
     auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get());
-    auto profilerAgent = std::make_unique<JSGlobalObjectProfilerAgent>(m_globalObject);
 
+    m_inspectorAgent = inspectorAgent.get();
+    m_debuggerAgent = debuggerAgent.get();
     m_consoleAgent = consoleAgent.get();
-    m_consoleClient = std::make_unique<JSConsoleClient>(m_consoleAgent, profilerAgent.get());
+    m_consoleClient = std::make_unique<JSGlobalObjectConsoleClient>(m_consoleAgent);
 
     runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer());
-    profilerAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer());
 
-    m_agents.append(std::make_unique<InspectorAgent>());
+    m_agents.append(WTF::move(inspectorAgent));
     m_agents.append(WTF::move(runtimeAgent));
     m_agents.append(WTF::move(consoleAgent));
     m_agents.append(WTF::move(debuggerAgent));
+
+    m_executionStopwatch->start();
 }
 
 JSGlobalObjectInspectorController::~JSGlobalObjectInspectorController()
@@ -87,42 +98,69 @@ JSGlobalObjectInspectorController::~JSGlobalObjectInspectorController()
 
 void JSGlobalObjectInspectorController::globalObjectDestroyed()
 {
-    disconnectFrontend(InspectorDisconnectReason::InspectedTargetDestroyed);
+    disconnectFrontend(DisconnectReason::InspectedTargetDestroyed);
 
     m_injectedScriptManager->disconnect();
 }
 
-void JSGlobalObjectInspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
+void JSGlobalObjectInspectorController::connectFrontend(FrontendChannel* frontendChannel, bool isAutomaticInspection)
 {
-    ASSERT(!m_inspectorFrontendChannel);
-    ASSERT(!m_inspectorBackendDispatcher);
+    ASSERT(!m_frontendChannel);
+    ASSERT(!m_backendDispatcher);
 
-    m_inspectorFrontendChannel = frontendChannel;
-    m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel);
+    m_isAutomaticInspection = isAutomaticInspection;
 
-    m_agents.didCreateFrontendAndBackend(frontendChannel, m_inspectorBackendDispatcher.get());
+    m_frontendChannel = frontendChannel;
+    m_backendDispatcher = BackendDispatcher::create(frontendChannel);
+
+    m_agents.didCreateFrontendAndBackend(frontendChannel, m_backendDispatcher.get());
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    m_inspectorAgent->activateExtraDomains(m_agents.extraDomains());
+
+    if (m_augmentingClient)
+        m_augmentingClient->inspectorConnected();
+#endif
 }
 
-void JSGlobalObjectInspectorController::disconnectFrontend(InspectorDisconnectReason reason)
+void JSGlobalObjectInspectorController::disconnectFrontend(DisconnectReason reason)
 {
-    if (!m_inspectorFrontendChannel)
+    if (!m_frontendChannel)
         return;
 
     m_agents.willDestroyFrontendAndBackend(reason);
 
-    m_inspectorBackendDispatcher->clearFrontend();
-    m_inspectorBackendDispatcher.clear();
-    m_inspectorFrontendChannel = nullptr;
+    m_backendDispatcher->clearFrontend();
+    m_backendDispatcher = nullptr;
+    m_frontendChannel = nullptr;
+
+    m_isAutomaticInspection = false;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_augmentingClient)
+        m_augmentingClient->inspectorDisconnected();
+#endif
 }
 
 void JSGlobalObjectInspectorController::dispatchMessageFromFrontend(const String& message)
 {
-    if (m_inspectorBackendDispatcher)
-        m_inspectorBackendDispatcher->dispatch(message);
+    if (m_backendDispatcher)
+        m_backendDispatcher->dispatch(message);
+}
+
+void JSGlobalObjectInspectorController::pause()
+{
+    if (!m_frontendChannel)
+        return;
+
+    ErrorString dummyError;
+    m_debuggerAgent->enable(dummyError);
+    m_debuggerAgent->pause(dummyError);
 }
 
 void JSGlobalObjectInspectorController::appendAPIBacktrace(ScriptCallStack* callStack)
 {
+#if OS(DARWIN) || (OS(LINUX) && !PLATFORM(GTK))
     static const int framesToShow = 31;
     static const int framesToSkip = 3; // WTFGetBacktrace, appendAPIBacktrace, reportAPIException.
 
@@ -146,9 +184,12 @@ void JSGlobalObjectInspectorController::appendAPIBacktrace(ScriptCallStack* call
             callStack->append(ScriptCallFrame(ASCIILiteral("?"), ASCIILiteral("[native code]"), 0, 0));
         free(cxaDemangled);
     }
+#else
+    UNUSED_PARAM(callStack);
+#endif
 }
 
-void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, JSValue exception)
+void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, Exception* exception)
 {
     if (isTerminatedExecutionException(exception))
         return;
@@ -161,10 +202,10 @@ void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, JSVa
 
     // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not evaluate JavaScript handling exceptions
     // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception.
-    String errorMessage = exception.toString(exec)->value(exec);
+    String errorMessage = exception->value().toString(exec)->value(exec);
     exec->clearException();
 
-    if (JSConsoleClient::logToSystemConsole()) {
+    if (JSGlobalObjectConsoleClient::logToSystemConsole()) {
         if (callStack->size()) {
             const ScriptCallFrame& callFrame = callStack->at(0);
             ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber());
@@ -172,7 +213,7 @@ void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, JSVa
             ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, String(), 0, 0);
     }
 
-    m_consoleAgent->addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callStack);
+    m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callStack));
 }
 
 ConsoleClient* JSGlobalObjectInspectorController::consoleClient() const
@@ -183,7 +224,7 @@ ConsoleClient* JSGlobalObjectInspectorController::consoleClient() const
 bool JSGlobalObjectInspectorController::developerExtrasEnabled() const
 {
 #if ENABLE(REMOTE_INSPECTOR)
-    if (!RemoteInspector::shared().enabled())
+    if (!RemoteInspector::singleton().enabled())
         return false;
 
     if (!m_globalObject.inspectorDebuggable().remoteDebuggingAllowed())
@@ -203,6 +244,33 @@ InspectorEvaluateHandler JSGlobalObjectInspectorController::evaluateHandler() co
     return JSC::evaluate;
 }
 
+void JSGlobalObjectInspectorController::frontendInitialized()
+{
+#if ENABLE(REMOTE_INSPECTOR)
+    if (m_isAutomaticInspection)
+        m_globalObject.inspectorDebuggable().unpauseForInitializedInspector();
+#endif
+}
+
+Ref<Stopwatch> JSGlobalObjectInspectorController::executionStopwatch()
+{
+    return m_executionStopwatch.copyRef();
+}
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+void JSGlobalObjectInspectorController::appendExtraAgent(std::unique_ptr<InspectorAgentBase> agent)
+{
+    String domainName = agent->domainName();
+
+    if (m_frontendChannel)
+        agent->didCreateFrontendAndBackend(m_frontendChannel, m_backendDispatcher.get());
+
+    m_agents.appendExtraAgent(WTF::move(agent));
+
+    if (m_frontendChannel)
+        m_inspectorAgent->activateExtraDomain(domainName);
+}
+#endif
+
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 61ab1c13c2b70462e4d27a7cbf41df23ceaacacf..6e3f94eac234ec8983698ceac73f16e03604cbcf 100644 (file)
 #ifndef JSGlobalObjectInspectorController_h
 #define JSGlobalObjectInspectorController_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorAgentRegistry.h"
 #include "InspectorEnvironment.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "AugmentableInspectorController.h"
+#endif
+
+namespace WTF {
+class Stopwatch;
+}
+
+
 namespace JSC {
 class ConsoleClient;
+class Exception;
 class ExecState;
 class JSGlobalObject;
 class JSValue;
@@ -43,23 +51,29 @@ class JSValue;
 
 namespace Inspector {
 
+class BackendDispatcher;
+class FrontendChannel;
 class InjectedScriptManager;
+class InspectorAgent;
 class InspectorConsoleAgent;
-class InspectorBackendDispatcher;
-class InspectorConsoleAgent;
-class InspectorFrontendChannel;
-class JSConsoleClient;
+class InspectorDebuggerAgent;
+class JSGlobalObjectConsoleClient;
 class ScriptCallStack;
 
-class JSGlobalObjectInspectorController final : public InspectorEnvironment {
+class JSGlobalObjectInspectorController final
+    : public InspectorEnvironment
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , public AugmentableInspectorController
+#endif
+{
     WTF_MAKE_NONCOPYABLE(JSGlobalObjectInspectorController);
     WTF_MAKE_FAST_ALLOCATED;
 public:
     JSGlobalObjectInspectorController(JSC::JSGlobalObject&);
     ~JSGlobalObjectInspectorController();
 
-    void connectFrontend(InspectorFrontendChannel*);
-    void disconnectFrontend(InspectorDisconnectReason reason);
+    void connectFrontend(FrontendChannel*, bool isAutomaticInspection);
+    void disconnectFrontend(DisconnectReason);
     void dispatchMessageFromFrontend(const String&);
 
     void globalObjectDestroyed();
@@ -67,7 +81,8 @@ public:
     bool includesNativeCallStackWhenReportingExceptions() const { return m_includeNativeCallStackWithExceptions; }
     void setIncludesNativeCallStackWhenReportingExceptions(bool includesNativeCallStack) { m_includeNativeCallStackWithExceptions = includesNativeCallStack; }
 
-    void reportAPIException(JSC::ExecState*, JSC::JSValue exception);
+    void pause();
+    void reportAPIException(JSC::ExecState*, JSC::Exception*);
 
     JSC::ConsoleClient* consoleClient() const;
 
@@ -77,22 +92,38 @@ public:
     virtual InspectorEvaluateHandler evaluateHandler() const override;
     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String&, int) override { }
     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override { }
+    virtual void frontendInitialized() override;
+    virtual Ref<WTF::Stopwatch> executionStopwatch() override;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const override { return m_augmentingClient; } 
+    virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient* client) override { m_augmentingClient = client; }
+
+    virtual FrontendChannel* frontendChannel() const override { return m_frontendChannel; }
+    virtual void appendExtraAgent(std::unique_ptr<InspectorAgentBase>) override;
+#endif
 
 private:
     void appendAPIBacktrace(ScriptCallStack* callStack);
 
     JSC::JSGlobalObject& m_globalObject;
     std::unique_ptr<InjectedScriptManager> m_injectedScriptManager;
-    std::unique_ptr<JSConsoleClient> m_consoleClient;
+    std::unique_ptr<JSGlobalObjectConsoleClient> m_consoleClient;
+    InspectorAgent* m_inspectorAgent;
     InspectorConsoleAgent* m_consoleAgent;
-    InspectorAgentRegistry m_agents;
-    InspectorFrontendChannel* m_inspectorFrontendChannel;
-    RefPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
+    InspectorDebuggerAgent* m_debuggerAgent;
+    AgentRegistry m_agents;
+    FrontendChannel* m_frontendChannel;
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+    Ref<WTF::Stopwatch> m_executionStopwatch;
     bool m_includeNativeCallStackWithExceptions;
+    bool m_isAutomaticInspection;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    AugmentableInspectorControllerClient* m_augmentingClient;
+#endif
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSGlobalObjectInspectorController_h)
index ff061ed0b4c3d8a429281df95197545a994db433..0e968f73055244eea142797fc710445986e22f23 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSGlobalObjectScriptDebugServer.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "EventLoop.h"
 #include "JSCInlines.h"
 #include "JSLock.h"
@@ -89,4 +87,3 @@ void JSGlobalObjectScriptDebugServer::runEventLoopWhilePaused()
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index d309e5913d46aa9f42a55f430f5d1143d5a0934f..901b67397b0ddf68303c13c6cfae099ff2d778d8 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSGlobalObjectScriptDebugServer_h
 #define JSGlobalObjectScriptDebugServer_h
 
-#if ENABLE(INSPECTOR)
-
 #include "ScriptDebugServer.h"
 #include <wtf/Forward.h>
 
@@ -47,7 +45,7 @@ public:
     virtual void recompileAllJSFunctions() override;
 
 private:
-    virtual ListenerSet* getListenersForGlobalObject(JSC::JSGlobalObject*) override { return &m_listeners; }
+    virtual ListenerSet& getListeners() override { return m_listeners; }
     virtual void didPause(JSC::JSGlobalObject*) override { }
     virtual void didContinue(JSC::JSGlobalObject*) override { }
     virtual void runEventLoopWhilePaused() override;
@@ -56,7 +54,7 @@ private:
     // NOTE: Currently all exceptions are reported at the API boundary through reportAPIException.
     // Until a time comes where an exception can be caused outside of the API (e.g. setTimeout
     // or some other async operation in a pure JSContext) we can ignore exceptions reported here.
-    virtual void reportException(JSC::ExecState*, JSC::JSValue) const override { }
+    virtual void reportException(JSC::ExecState*, JSC::Exception*) const override { }
 
     ListenerSet m_listeners;
     JSC::JSGlobalObject& m_globalObject;
@@ -64,6 +62,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // JSGlobalObjectScriptDebugServer_h
index 0e9555fb9e63295ad98321241b7ad8502e94e590..a17ba98625581e1bc9c37e63d7aa7c8045c546a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "JSInjectedScriptHost.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "DateInstance.h"
+#include "DirectArguments.h"
 #include "Error.h"
 #include "InjectedScriptHost.h"
+#include "IteratorOperations.h"
 #include "JSArray.h"
+#include "JSArrayIterator.h"
+#include "JSBoundFunction.h"
+#include "JSCInlines.h"
 #include "JSFunction.h"
 #include "JSInjectedScriptHostPrototype.h"
+#include "JSMap.h"
+#include "JSMapIterator.h"
+#include "JSSet.h"
+#include "JSSetIterator.h"
+#include "JSStringIterator.h"
 #include "JSTypedArrays.h"
+#include "JSWeakMap.h"
+#include "JSWeakSet.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "RegExpObject.h"
+#include "ScopedArguments.h"
 #include "SourceCode.h"
 #include "TypedArrayInlines.h"
+#include "WeakMapData.h"
+
+#if ENABLE(PROMISES)
+#include "JSPromise.h"
+#endif
 
 using namespace JSC;
 
 namespace Inspector {
 
-const ClassInfo JSInjectedScriptHost::s_info = { "InjectedScriptHost", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSInjectedScriptHost) };
+const ClassInfo JSInjectedScriptHost::s_info = { "InjectedScriptHost", &Base::s_info, 0, CREATE_METHOD_TABLE(JSInjectedScriptHost) };
 
 JSInjectedScriptHost::JSInjectedScriptHost(VM& vm, Structure* structure, PassRefPtr<InjectedScriptHost> impl)
     : JSDestructibleObject(vm, structure)
@@ -72,10 +87,8 @@ void JSInjectedScriptHost::destroy(JSC::JSCell* cell)
 
 void JSInjectedScriptHost::releaseImpl()
 {
-    if (m_impl) {
-        m_impl->deref();
-        m_impl = nullptr;
-    }
+    if (auto impl = std::exchange(m_impl, nullptr))
+        impl->deref();
 }
 
 JSInjectedScriptHost::~JSInjectedScriptHost()
@@ -94,9 +107,8 @@ JSValue JSInjectedScriptHost::internalConstructorName(ExecState* exec)
     if (exec->argumentCount() < 1)
         return jsUndefined();
 
-    JSObject* thisObject = jsCast<JSObject*>(exec->uncheckedArgument(0).toThis(exec, NotStrictMode));
-    String result = thisObject->methodTable()->className(thisObject);
-    return jsString(exec, result);
+    JSObject* object = jsCast<JSObject*>(exec->uncheckedArgument(0).toThis(exec, NotStrictMode));
+    return jsString(exec, JSObject::calculatedClassName(object));
 }
 
 JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
@@ -108,7 +120,7 @@ JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
     return jsBoolean(impl().isHTMLAllCollection(value));
 }
 
-JSValue JSInjectedScriptHost::type(ExecState* exec)
+JSValue JSInjectedScriptHost::subtype(ExecState* exec)
 {
     if (exec->argumentCount() < 1)
         return jsUndefined();
@@ -120,13 +132,45 @@ JSValue JSInjectedScriptHost::type(ExecState* exec)
         return exec->vm().smallStrings.booleanString();
     if (value.isNumber())
         return exec->vm().smallStrings.numberString();
+    if (value.isSymbol())
+        return exec->vm().smallStrings.symbolString();
+
+    JSObject* object = asObject(value);
+    if (object) {
+        if (object->isErrorInstance())
+            return jsNontrivialString(exec, ASCIILiteral("error"));
+
+        // Consider class constructor functions class objects.
+        JSFunction* function = jsDynamicCast<JSFunction*>(value);
+        if (function && function->isClassConstructorFunction())
+            return jsNontrivialString(exec, ASCIILiteral("class"));
+    }
 
     if (value.inherits(JSArray::info()))
         return jsNontrivialString(exec, ASCIILiteral("array"));
+    if (value.inherits(DirectArguments::info()) || value.inherits(ScopedArguments::info()))
+        return jsNontrivialString(exec, ASCIILiteral("array"));
+
     if (value.inherits(DateInstance::info()))
         return jsNontrivialString(exec, ASCIILiteral("date"));
     if (value.inherits(RegExpObject::info()))
         return jsNontrivialString(exec, ASCIILiteral("regexp"));
+
+    if (value.inherits(JSMap::info()))
+        return jsNontrivialString(exec, ASCIILiteral("map"));
+    if (value.inherits(JSSet::info()))
+        return jsNontrivialString(exec, ASCIILiteral("set"));
+    if (value.inherits(JSWeakMap::info()))
+        return jsNontrivialString(exec, ASCIILiteral("weakmap"));
+    if (value.inherits(JSWeakSet::info()))
+        return jsNontrivialString(exec, ASCIILiteral("weakset"));
+
+    if (value.inherits(JSArrayIterator::info())
+        || value.inherits(JSMapIterator::info())
+        || value.inherits(JSSetIterator::info())
+        || value.inherits(JSStringIterator::info()))
+        return jsNontrivialString(exec, ASCIILiteral("iterator"));
+
     if (value.inherits(JSInt8Array::info()) || value.inherits(JSInt16Array::info()) || value.inherits(JSInt32Array::info()))
         return jsNontrivialString(exec, ASCIILiteral("array"));
     if (value.inherits(JSUint8Array::info()) || value.inherits(JSUint16Array::info()) || value.inherits(JSUint32Array::info()))
@@ -134,7 +178,7 @@ JSValue JSInjectedScriptHost::type(ExecState* exec)
     if (value.inherits(JSFloat32Array::info()) || value.inherits(JSFloat64Array::info()))
         return jsNontrivialString(exec, ASCIILiteral("array"));
 
-    return impl().type(exec, value);
+    return impl().subtype(exec, value);
 }
 
 JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
@@ -146,30 +190,37 @@ JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
     if (!value.asCell()->inherits(JSFunction::info()))
         return jsUndefined();
 
+    // FIXME: This should provide better details for JSBoundFunctions.
+
     JSFunction* function = jsCast<JSFunction*>(value);
     const SourceCode* sourceCode = function->sourceCode();
     if (!sourceCode)
         return jsUndefined();
 
+    // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
     int lineNumber = sourceCode->firstLine();
     if (lineNumber)
-        lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
+        lineNumber -= 1;
+    int columnNumber = sourceCode->startColumn();
+    if (columnNumber)
+        columnNumber -= 1;
 
     String scriptID = String::number(sourceCode->provider()->asID());
     JSObject* location = constructEmptyObject(exec);
-    location->putDirect(exec->vm(), Identifier(exec, "lineNumber"), jsNumber(lineNumber));
-    location->putDirect(exec->vm(), Identifier(exec, "scriptId"), jsString(exec, scriptID));
+    location->putDirect(exec->vm(), Identifier::fromString(exec, "scriptId"), jsString(exec, scriptID));
+    location->putDirect(exec->vm(), Identifier::fromString(exec, "lineNumber"), jsNumber(lineNumber));
+    location->putDirect(exec->vm(), Identifier::fromString(exec, "columnNumber"), jsNumber(columnNumber));
 
     JSObject* result = constructEmptyObject(exec);
-    result->putDirect(exec->vm(), Identifier(exec, "location"), location);
+    result->putDirect(exec->vm(), Identifier::fromString(exec, "location"), location);
 
     String name = function->name(exec);
     if (!name.isEmpty())
-        result->putDirect(exec->vm(), Identifier(exec, "name"), jsString(exec, name));
+        result->putDirect(exec->vm(), Identifier::fromString(exec, "name"), jsString(exec, name));
 
     String displayName = function->displayName(exec);
     if (!displayName.isEmpty())
-        result->putDirect(exec->vm(), Identifier(exec, "displayName"), jsString(exec, displayName));
+        result->putDirect(exec->vm(), Identifier::fromString(exec, "displayName"), jsString(exec, displayName));
 
     // FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
     // <https://webkit.org/b/87192> [JSC] expose function (closure) inner context to debugger
@@ -177,12 +228,256 @@ JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
     return result;
 }
 
-JSValue JSInjectedScriptHost::getInternalProperties(ExecState*)
+static JSObject* constructInternalProperty(ExecState* exec, const String& name, JSValue value)
 {
-    // FIXME: <https://webkit.org/b/94533> [JSC] expose object inner properties to debugger
+    JSObject* result = constructEmptyObject(exec);
+    result->putDirect(exec->vm(), Identifier::fromString(exec, "name"), jsString(exec, name));
+    result->putDirect(exec->vm(), Identifier::fromString(exec, "value"), value);
+    return result;
+}
+
+JSValue JSInjectedScriptHost::getInternalProperties(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue value = exec->uncheckedArgument(0);
+
+#if ENABLE(PROMISES)
+    if (JSPromise* promise = jsDynamicCast<JSPromise*>(value)) {
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr);
+        switch (promise->status(exec->vm())) {
+        case JSPromise::Status::Pending:
+            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("pending"))));
+            break;
+        case JSPromise::Status::Fulfilled:
+            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("resolved"))));
+            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
+            break;
+        case JSPromise::Status::Rejected:
+            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("rejected"))));
+            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
+            break;
+        }
+        // FIXME: <https://webkit.org/b/141664> Web Inspector: ES6: Improved Support for Promises - Promise Reactions
+        return array;
+    }
+#endif
+
+    if (JSBoundFunction* boundFunction = jsDynamicCast<JSBoundFunction*>(value)) {
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr, 3);
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "targetFunction", boundFunction->targetFunction()));
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundThis", boundFunction->boundThis()));
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundArgs", boundFunction->boundArgs()));
+        return array;
+    }
+
+    if (JSArrayIterator* arrayIterator = jsDynamicCast<JSArrayIterator*>(value)) {
+        String kind;
+        switch (arrayIterator->kind(exec)) {
+        case ArrayIterateKey:
+            kind = ASCIILiteral("key");
+            break;
+        case ArrayIterateValue:
+            kind = ASCIILiteral("value");
+            break;
+        case ArrayIterateKeyValue:
+            kind = ASCIILiteral("key+value");
+            break;
+        }
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr, 2);
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "array", arrayIterator->iteratedValue(exec)));
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
+        return array;
+    }
+
+    if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(value)) {
+        String kind;
+        switch (mapIterator->kind()) {
+        case MapIterateKey:
+            kind = ASCIILiteral("key");
+            break;
+        case MapIterateValue:
+            kind = ASCIILiteral("value");
+            break;
+        case MapIterateKeyValue:
+            kind = ASCIILiteral("key+value");
+            break;
+        }
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr, 2);
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "map", mapIterator->iteratedValue()));
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
+        return array;
+    }
+        
+    if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(value)) {
+        String kind;
+        switch (setIterator->kind()) {
+        case SetIterateKey:
+            kind = ASCIILiteral("key");
+            break;
+        case SetIterateValue:
+            kind = ASCIILiteral("value");
+            break;
+        case SetIterateKeyValue:
+            kind = ASCIILiteral("key+value");
+            break;
+        }
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr, 2);
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "set", setIterator->iteratedValue()));
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
+        return array;
+    }
+
+    if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(value)) {
+        unsigned index = 0;
+        JSArray* array = constructEmptyArray(exec, nullptr, 1);
+        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "string", stringIterator->iteratedValue(exec)));
+        return array;
+    }
+
     return jsUndefined();
 }
 
+JSValue JSInjectedScriptHost::weakMapSize(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue value = exec->uncheckedArgument(0);
+    JSWeakMap* weakMap = jsDynamicCast<JSWeakMap*>(value);
+    if (!weakMap)
+        return jsUndefined();
+
+    return jsNumber(weakMap->weakMapData()->size());
+}
+
+JSValue JSInjectedScriptHost::weakMapEntries(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue value = exec->uncheckedArgument(0);
+    JSWeakMap* weakMap = jsDynamicCast<JSWeakMap*>(value);
+    if (!weakMap)
+        return jsUndefined();
+
+    unsigned fetched = 0;
+    unsigned numberToFetch = 100;
+
+    JSValue numberToFetchArg = exec->argument(1);
+    double fetchDouble = numberToFetchArg.toInteger(exec);
+    if (fetchDouble >= 0)
+        numberToFetch = static_cast<unsigned>(fetchDouble);
+
+    JSArray* array = constructEmptyArray(exec, nullptr);
+    for (auto it = weakMap->weakMapData()->begin(); it != weakMap->weakMapData()->end(); ++it) {
+        JSObject* entry = constructEmptyObject(exec);
+        entry->putDirect(exec->vm(), Identifier::fromString(exec, "key"), it->key);
+        entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), it->value.get());
+        array->putDirectIndex(exec, fetched++, entry);
+        if (numberToFetch && fetched >= numberToFetch)
+            break;
+    }
+
+    return array;
+}
+
+JSValue JSInjectedScriptHost::weakSetSize(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue value = exec->uncheckedArgument(0);
+    JSWeakSet* weakSet = jsDynamicCast<JSWeakSet*>(value);
+    if (!weakSet)
+        return jsUndefined();
+
+    return jsNumber(weakSet->weakMapData()->size());
+}
+
+JSValue JSInjectedScriptHost::weakSetEntries(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue value = exec->uncheckedArgument(0);
+    JSWeakSet* weakSet = jsDynamicCast<JSWeakSet*>(value);
+    if (!weakSet)
+        return jsUndefined();
+
+    unsigned fetched = 0;
+    unsigned numberToFetch = 100;
+
+    JSValue numberToFetchArg = exec->argument(1);
+    double fetchDouble = numberToFetchArg.toInteger(exec);
+    if (fetchDouble >= 0)
+        numberToFetch = static_cast<unsigned>(fetchDouble);
+
+    JSArray* array = constructEmptyArray(exec, nullptr);
+    for (auto it = weakSet->weakMapData()->begin(); it != weakSet->weakMapData()->end(); ++it) {
+        JSObject* entry = constructEmptyObject(exec);
+        entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), it->key);
+        array->putDirectIndex(exec, fetched++, entry);
+        if (numberToFetch && fetched >= numberToFetch)
+            break;
+    }
+
+    return array;
+}
+
+JSValue JSInjectedScriptHost::iteratorEntries(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return jsUndefined();
+
+    JSValue iterator;
+    JSValue value = exec->uncheckedArgument(0);
+    if (JSArrayIterator* arrayIterator = jsDynamicCast<JSArrayIterator*>(value))
+        iterator = arrayIterator->clone(exec);
+    else if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(value))
+        iterator = mapIterator->clone(exec);
+    else if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(value))
+        iterator = setIterator->clone(exec);
+    else if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(value))
+        iterator = stringIterator->clone(exec);
+    else
+        return jsUndefined();
+
+    unsigned numberToFetch = 5;
+    JSValue numberToFetchArg = exec->argument(1);
+    double fetchDouble = numberToFetchArg.toInteger(exec);
+    if (fetchDouble >= 0)
+        numberToFetch = static_cast<unsigned>(fetchDouble);
+
+    JSArray* array = constructEmptyArray(exec, nullptr);
+
+    for (unsigned i = 0; i < numberToFetch; ++i) {
+        JSValue next = iteratorStep(exec, iterator);
+        if (exec->hadException())
+            break;
+        if (next.isFalse())
+            break;
+
+        JSValue nextValue = iteratorValue(exec, next);
+        if (exec->hadException())
+            break;
+
+        JSObject* entry = constructEmptyObject(exec);
+        entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), nextValue);
+        array->putDirectIndex(exec, i, entry);
+    }
+
+    iteratorClose(exec, iterator);
+
+    return array;
+}
+
 JSValue toJS(ExecState* exec, JSGlobalObject* globalObject, InjectedScriptHost* impl)
 {
     if (!impl)
@@ -201,5 +496,3 @@ JSInjectedScriptHost* toJSInjectedScriptHost(JSValue value)
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index dc23568029323e630c74be120a0fd91425159757..86891516fde41bb1a345890fd7937c580fb6c7f5 100644 (file)
 #ifndef JSInjectedScriptHost_h
 #define JSInjectedScriptHost_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSDestructibleObject.h"
 
+namespace JSC {
+class WeakMapData;
+}
+
 namespace Inspector {
 
 class InjectedScriptHost;
@@ -37,6 +39,7 @@ class InjectedScriptHost;
 class JSInjectedScriptHost : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     DECLARE_INFO;
 
@@ -64,13 +67,16 @@ public:
     // Functions.
     JSC::JSValue internalConstructorName(JSC::ExecState*);
     JSC::JSValue isHTMLAllCollection(JSC::ExecState*);
-    JSC::JSValue type(JSC::ExecState*);
+    JSC::JSValue subtype(JSC::ExecState*);
     JSC::JSValue functionDetails(JSC::ExecState*);
     JSC::JSValue getInternalProperties(JSC::ExecState*);
+    JSC::JSValue weakMapSize(JSC::ExecState*);
+    JSC::JSValue weakMapEntries(JSC::ExecState*);
+    JSC::JSValue weakSetSize(JSC::ExecState*);
+    JSC::JSValue weakSetEntries(JSC::ExecState*);
+    JSC::JSValue iteratorEntries(JSC::ExecState*);
 
 protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     void finishCreation(JSC::VM&);
 
 private:
@@ -85,6 +91,4 @@ JSInjectedScriptHost* toJSInjectedScriptHost(JSC::JSValue);
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSInjectedScriptHost_h)
index b07970ae1c57f619079b7cb1f22d0f28876367d6..b86a2e011a290cb905bdea8d1bef1de50bf85c5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSInjectedScriptHostPrototype.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "Error.h"
 #include "GetterSetter.h"
 #include "Identifier.h"
@@ -40,15 +38,20 @@ using namespace JSC;
 
 namespace Inspector {
 
-static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionType(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionSubtype(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionFunctionDetails(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionGetInternalProperties(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionInternalConstructorName(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapSize(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapEntries(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakSetSize(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakSetEntries(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIteratorEntries(ExecState*);
 
 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeAttributeEvaluate(ExecState*);
 
-const ClassInfo JSInjectedScriptHostPrototype::s_info = { "InjectedScriptHost", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSInjectedScriptHostPrototype) };
+const ClassInfo JSInjectedScriptHostPrototype::s_info = { "InjectedScriptHost", &Base::s_info, 0, CREATE_METHOD_TABLE(JSInjectedScriptHostPrototype) };
 
 void JSInjectedScriptHostPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
@@ -56,16 +59,21 @@ void JSInjectedScriptHostPrototype::finishCreation(VM& vm, JSGlobalObject* globa
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
 
-    JSC_NATIVE_FUNCTION("type", jsInjectedScriptHostPrototypeFunctionType, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("subtype", jsInjectedScriptHostPrototypeFunctionSubtype, DontEnum, 1);
     JSC_NATIVE_FUNCTION("functionDetails", jsInjectedScriptHostPrototypeFunctionFunctionDetails, DontEnum, 1);
     JSC_NATIVE_FUNCTION("getInternalProperties", jsInjectedScriptHostPrototypeFunctionGetInternalProperties, DontEnum, 1);
     JSC_NATIVE_FUNCTION("internalConstructorName", jsInjectedScriptHostPrototypeFunctionInternalConstructorName, DontEnum, 1);
     JSC_NATIVE_FUNCTION("isHTMLAllCollection", jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection, DontEnum, 1);
-
-    Identifier evaluateIdentifier(&vm, "evaluate");
-    GetterSetter* accessor = GetterSetter::create(vm);
+    JSC_NATIVE_FUNCTION("weakMapSize", jsInjectedScriptHostPrototypeFunctionWeakMapSize, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("weakMapEntries", jsInjectedScriptHostPrototypeFunctionWeakMapEntries, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("weakSetSize", jsInjectedScriptHostPrototypeFunctionWeakSetSize, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("weakSetEntries", jsInjectedScriptHostPrototypeFunctionWeakSetEntries, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("iteratorEntries", jsInjectedScriptHostPrototypeFunctionIteratorEntries, DontEnum, 1);
+
+    Identifier evaluateIdentifier = Identifier::fromString(&vm, "evaluate");
+    GetterSetter* accessor = GetterSetter::create(vm, globalObject);
     JSFunction* function = JSFunction::create(vm, globalObject, 0, evaluateIdentifier.string(), jsInjectedScriptHostPrototypeAttributeEvaluate);
-    accessor->setGetter(vm, function);
+    accessor->setGetter(vm, globalObject, function);
     putDirectNonIndexAccessor(vm, evaluateIdentifier, accessor, DontEnum | Accessor);
 }
 
@@ -102,7 +110,62 @@ EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsHTMLAllColle
     return JSValue::encode(castedThis->isHTMLAllCollection(exec));
 }
 
-EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionType(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapSize(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+    if (!castedThis)
+        return throwVMTypeError(exec);
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+    return JSValue::encode(castedThis->weakMapSize(exec));
+}
+
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapEntries(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+    if (!castedThis)
+        return throwVMTypeError(exec);
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+    return JSValue::encode(castedThis->weakMapEntries(exec));
+}
+
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakSetSize(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+    if (!castedThis)
+        return throwVMTypeError(exec);
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+    return JSValue::encode(castedThis->weakSetSize(exec));
+}
+
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakSetEntries(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+    if (!castedThis)
+        return throwVMTypeError(exec);
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+    return JSValue::encode(castedThis->weakSetEntries(exec));
+}
+
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIteratorEntries(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+    if (!castedThis)
+        return throwVMTypeError(exec);
+
+    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+    return JSValue::encode(castedThis->iteratorEntries(exec));
+}
+
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionSubtype(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
     JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
@@ -110,7 +173,7 @@ EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionType(ExecState
         return throwVMTypeError(exec);
 
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
-    return JSValue::encode(castedThis->type(exec));
+    return JSValue::encode(castedThis->subtype(exec));
 }
 
 EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionFunctionDetails(ExecState* exec)
@@ -137,4 +200,3 @@ EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionGetInternalPro
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index 9d0b7b666fd383a6ea89d4ba3c4b0035ebaf2fc1..aa4963ed549b6921bfad7c2545265bd5925d9320 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSInjectedScriptHostPrototype_h
 #define JSInjectedScriptHostPrototype_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSObject.h"
 
 namespace Inspector {
@@ -35,6 +33,7 @@ namespace Inspector {
 class JSInjectedScriptHostPrototype : public JSC::JSNonFinalObject {
 public:
     typedef JSC::JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
 
     DECLARE_INFO;
 
@@ -50,9 +49,6 @@ public:
         return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     JSInjectedScriptHostPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
         : JSC::JSNonFinalObject(vm, structure)
@@ -63,6 +59,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSInjectedScriptHostPrototype_h)
index 08fd618a804d516dd415db673a524d702cc3e6be..cb1f9d1c1fadb7a3c2849967ffc72c5844e5d066 100644 (file)
@@ -26,8 +26,7 @@
 #include "config.h"
 #include "JSJavaScriptCallFrame.h"
 
-#if ENABLE(INSPECTOR)
-
+#include "DebuggerScope.h"
 #include "Error.h"
 #include "JSCJSValue.h"
 #include "JSCellInlines.h"
@@ -38,7 +37,7 @@ using namespace JSC;
 
 namespace Inspector {
 
-const ClassInfo JSJavaScriptCallFrame::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFrame) };
+const ClassInfo JSJavaScriptCallFrame::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFrame) };
 
 JSJavaScriptCallFrame::JSJavaScriptCallFrame(VM& vm, Structure* structure, PassRefPtr<JavaScriptCallFrame> impl)
     : JSDestructibleObject(vm, structure)
@@ -65,10 +64,8 @@ void JSJavaScriptCallFrame::destroy(JSC::JSCell* cell)
 
 void JSJavaScriptCallFrame::releaseImpl()
 {
-    if (m_impl) {
-        m_impl->deref();
-        m_impl = nullptr;
-    }
+    if (auto impl = std::exchange(m_impl, nullptr))
+        impl->deref();
 }
 
 JSJavaScriptCallFrame::~JSJavaScriptCallFrame()
@@ -78,7 +75,7 @@ JSJavaScriptCallFrame::~JSJavaScriptCallFrame()
 
 JSValue JSJavaScriptCallFrame::evaluate(ExecState* exec)
 {
-    JSValue exception;
+    NakedPtr<Exception> exception;
     JSValue result = impl().evaluate(exec->argument(0).toString(exec)->value(exec), exception);
     if (exception)
         exec->vm().throwException(exec, exception);
@@ -95,29 +92,33 @@ JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
         return jsUndefined();
     int index = exec->argument(0).asInt32();
 
-    JSScope* scopeChain = impl().scopeChain();
-    ScopeChainIterator end = scopeChain->end();
-
-    // FIXME: We should be identifying and returning CATCH_SCOPE appropriately.
+    DebuggerScope* scopeChain = impl().scopeChain();
+    DebuggerScope::iterator end = scopeChain->end();
 
     bool foundLocalScope = false;
-    for (ScopeChainIterator iter = scopeChain->begin(); iter != end; ++iter) {
-        JSObject* scope = iter.get();
-        if (scope->isActivationObject()) {
-            if (!foundLocalScope) {
-                // First activation object is local scope, each successive activation object is closure.
-                if (!index)
-                    return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
-                foundLocalScope = true;
-            } else if (!index)
-                return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
+    for (DebuggerScope::iterator iter = scopeChain->begin(); iter != end; ++iter) {
+        DebuggerScope* scope = iter.get();
+
+        if (!foundLocalScope && scope->isFunctionOrEvalScope()) {
+            // First function scope is the local scope, each successive one is a closure.
+            if (!index)
+                return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
+            foundLocalScope = true;
         }
 
         if (!index) {
-            // Last in the chain is global scope.
-            if (++iter == end)
+            if (scope->isCatchScope())
+                return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE);
+            if (scope->isFunctionNameScope())
+                return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE);
+            if (scope->isWithScope())
+                return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
+            if (scope->isGlobalScope()) {
+                ASSERT(++iter == end);
                 return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
-            return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
+            }
+            ASSERT(scope->isFunctionOrEvalScope());
+            return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
         }
 
         --index;
@@ -157,9 +158,9 @@ JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
     if (!impl().scopeChain())
         return jsNull();
 
-    JSScope* scopeChain = impl().scopeChain();
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator end = scopeChain->end();
+    DebuggerScope* scopeChain = impl().scopeChain();
+    DebuggerScope::iterator iter = scopeChain->begin();
+    DebuggerScope::iterator end = scopeChain->end();
 
     // We must always have something in the scope chain.
     ASSERT(iter != end);
@@ -210,4 +211,3 @@ JSJavaScriptCallFrame* toJSJavaScriptCallFrame(JSValue value)
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index dbbb93fa2dc18b3002005d0ffe8b15bda0bf18fb..b77c06ebf80aa36b3578be3e7aa07d6baa17ee72 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSJavaScriptCallFrame_h
 #define JSJavaScriptCallFrame_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSDestructibleObject.h"
 #include "JavaScriptCallFrame.h"
 
@@ -36,6 +34,7 @@ namespace Inspector {
 class JSJavaScriptCallFrame : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     DECLARE_INFO;
 
@@ -77,10 +76,9 @@ public:
     static const unsigned short WITH_SCOPE = 2;
     static const unsigned short CLOSURE_SCOPE = 3;
     static const unsigned short CATCH_SCOPE = 4;
+    static const unsigned short FUNCTION_NAME_SCOPE = 5;
 
 protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
     void finishCreation(JSC::VM&);
 
 private:
@@ -95,6 +93,4 @@ JSJavaScriptCallFrame* toJSJavaScriptCallFrame(JSC::JSValue);
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSJavaScriptCallFrame_h)
index f7fc21ea33d18bbe15699abb18dfb6416ed5b49e..4828386524dc26ab46c841356831c70dc6e9ff31 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSJavaScriptCallFramePrototype.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "Error.h"
 #include "GetterSetter.h"
 #include "Identifier.h"
@@ -59,15 +57,16 @@ static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantLOCAL_SCOPE(Exe
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantWITH_SCOPE(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCLOSURE_SCOPE(ExecState*);
 static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCATCH_SCOPE(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE(ExecState*);
 
-const ClassInfo JSJavaScriptCallFramePrototype::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFramePrototype) };
+const ClassInfo JSJavaScriptCallFramePrototype::s_info = { "JavaScriptCallFrame", &Base::s_info, 0, CREATE_METHOD_TABLE(JSJavaScriptCallFramePrototype) };
 
 #define JSC_NATIVE_NON_INDEX_ACCESSOR(jsName, cppName, attributes) \
     { \
-        Identifier identifier(&vm, jsName); \
-        GetterSetter* accessor = GetterSetter::create(vm); \
+        Identifier identifier = Identifier::fromString(&vm, jsName); \
+        GetterSetter* accessor = GetterSetter::create(vm, globalObject); \
         JSFunction* function = JSFunction::create(vm, globalObject, 0, identifier.string(), cppName); \
-        accessor->setGetter(vm, function); \
+        accessor->setGetter(vm, globalObject, function); \
         putDirectNonIndexAccessor(vm, identifier, accessor, (attributes)); \
     }
 
@@ -94,6 +93,7 @@ void JSJavaScriptCallFramePrototype::finishCreation(VM& vm, JSGlobalObject* glob
     JSC_NATIVE_NON_INDEX_ACCESSOR("WITH_SCOPE", jsJavaScriptCallFrameConstantWITH_SCOPE, DontEnum | Accessor);
     JSC_NATIVE_NON_INDEX_ACCESSOR("CLOSURE_SCOPE", jsJavaScriptCallFrameConstantCLOSURE_SCOPE, DontEnum | Accessor);
     JSC_NATIVE_NON_INDEX_ACCESSOR("CATCH_SCOPE", jsJavaScriptCallFrameConstantCATCH_SCOPE, DontEnum | Accessor);
+    JSC_NATIVE_NON_INDEX_ACCESSOR("FUNCTION_NAME_SCOPE", jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE, DontEnum | Accessor);
 }
 
 EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFramePrototypeFunctionEvaluate(ExecState* exec)
@@ -231,6 +231,9 @@ EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantCATCH_SCOPE(ExecState*
     return JSValue::encode(jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE));
 }
 
-} // namespace Inspector
+EncodedJSValue JSC_HOST_CALL jsJavaScriptCallFrameConstantFUNCTION_NAME_SCOPE(ExecState*)
+{
+    return JSValue::encode(jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE));
+}
 
-#endif // ENABLE(INSPECTOR)
+} // namespace Inspector
index b868c53e253f7483e5f5dff64e56024692c51824..0811c24628ce1e9670a4696a040072e47f41c48a 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSJavaScriptCallFramePrototype_h
 #define JSJavaScriptCallFramePrototype_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSObject.h"
 
 namespace Inspector {
@@ -35,6 +33,7 @@ namespace Inspector {
 class JSJavaScriptCallFramePrototype : public JSC::JSNonFinalObject {
 public:
     typedef JSC::JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
 
     DECLARE_INFO;
 
@@ -50,9 +49,6 @@ public:
         return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
     }
 
-protected:
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     JSJavaScriptCallFramePrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
         : JSC::JSNonFinalObject(vm, structure)
@@ -63,6 +59,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSJavaScriptCallFramePrototype_h)
index f735a8aa61298973de3916d7b61df35154cca97b..d5f73d5405069aaaab7c83c107f009efb81aa072 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JavaScriptCallFrame.h"
 
-#if ENABLE(INSPECTOR)
-
 using namespace JSC;
 
 namespace Inspector {
@@ -52,4 +50,3 @@ JavaScriptCallFrame* JavaScriptCallFrame::caller()
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
index b584067a2746313812d99831a0680693df727dd6..c7d037b18fdd6ed305105e0ac2e439300f217111 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2013-2014 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,6 @@
 #ifndef JavaScriptCallFrame_h
 #define JavaScriptCallFrame_h
 
-#if ENABLE(INSPECTOR)
-
 #include "JSCJSValueInlines.h"
 #include "debugger/DebuggerCallFrame.h"
 #include "interpreter/CallFrame.h"
@@ -40,9 +38,9 @@ namespace Inspector {
 
 class JavaScriptCallFrame : public RefCounted<JavaScriptCallFrame> {
 public:
-    static PassRefPtr<JavaScriptCallFrame> create(PassRefPtr<JSC::DebuggerCallFrame> debuggerCallFrame)
+    static Ref<JavaScriptCallFrame> create(PassRefPtr<JSC::DebuggerCallFrame> debuggerCallFrame)
     {
-        return adoptRef(new JavaScriptCallFrame(debuggerCallFrame));
+        return adoptRef(*new JavaScriptCallFrame(debuggerCallFrame));
     }
 
     JavaScriptCallFrame* caller();
@@ -53,11 +51,11 @@ public:
 
     String functionName() const { return m_debuggerCallFrame->functionName(); }
     JSC::DebuggerCallFrame::Type type() const { return m_debuggerCallFrame->type(); }
-    JSC::JSScope* scopeChain() const { return m_debuggerCallFrame->scope(); }
+    JSC::DebuggerScope* scopeChain() const { return m_debuggerCallFrame->scope(); }
     JSC::JSGlobalObject* vmEntryGlobalObject() const { return m_debuggerCallFrame->vmEntryGlobalObject(); }
 
     JSC::JSValue thisValue() const { return m_debuggerCallFrame->thisValue(); }
-    JSC::JSValue evaluate(const String& script, JSC::JSValue& exception) const  { return m_debuggerCallFrame->evaluate(script, exception); }
+    JSC::JSValue evaluate(const String& script, NakedPtr<JSC::Exception>& exception) const  { return m_debuggerCallFrame->evaluate(script, exception); }
 
 private:
     JavaScriptCallFrame(PassRefPtr<JSC::DebuggerCallFrame>);
@@ -68,6 +66,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // JavaScriptCallFrame_h
index 4100a3f995e933664a93710c30e8c214a0b3b8eb..51d1fe658d56a95aad5bdba4339fc2c92aaea3c4 100644 (file)
@@ -37,9 +37,9 @@
 
 namespace Inspector {
 
-PassRefPtr<ScriptArguments> ScriptArguments::create(JSC::ExecState* scriptState, Vector<Deprecated::ScriptValue>& arguments)
+Ref<ScriptArguments> ScriptArguments::create(JSC::ExecState* scriptState, Vector<Deprecated::ScriptValue>& arguments)
 {
-    return adoptRef(new ScriptArguments(scriptState, arguments));
+    return adoptRef(*new ScriptArguments(scriptState, arguments));
 }
 
 ScriptArguments::ScriptArguments(JSC::ExecState* execState, Vector<Deprecated::ScriptValue>& arguments)
index 5337e019e09c39517803b84d779fdbfa3212a790..7200ab48ad6543dda7271689229a3583cd40d901 100644 (file)
@@ -51,7 +51,7 @@ namespace Inspector {
 
 class JS_EXPORT_PRIVATE ScriptArguments : public RefCounted<ScriptArguments> {
 public:
-    static PassRefPtr<ScriptArguments> create(JSC::ExecState*, Vector<Deprecated::ScriptValue>& arguments);
+    static Ref<ScriptArguments> create(JSC::ExecState*, Vector<Deprecated::ScriptValue>& arguments);
     ~ScriptArguments();
 
     const Deprecated::ScriptValue& argumentAt(size_t) const;
index c7a822ef9ef439952ab7ff20b84459eb81fa11d3..96a06ff62e64cb7edf20992d354962ead7a94a7a 100644 (file)
@@ -33,7 +33,6 @@
 #include "ScriptCallFrame.h"
 
 #include "InspectorValues.h"
-#include <wtf/PassRefPtr.h>
 
 namespace Inspector {
 
@@ -57,16 +56,14 @@ bool ScriptCallFrame::isEqual(const ScriptCallFrame& o) const
         && m_column == o.m_column;
 }
 
-#if ENABLE(INSPECTOR)
-PassRefPtr<Inspector::TypeBuilder::Console::CallFrame> ScriptCallFrame::buildInspectorObject() const
+Ref<Inspector::Protocol::Console::CallFrame> ScriptCallFrame::buildInspectorObject() const
 {
-    return Inspector::TypeBuilder::Console::CallFrame::create()
+    return Inspector::Protocol::Console::CallFrame::create()
         .setFunctionName(m_functionName)
         .setUrl(m_scriptName)
         .setLineNumber(m_lineNumber)
         .setColumnNumber(m_column)
         .release();
 }
-#endif
 
 } // namespace Inspector
index 00524dc501d0eb35b8db3e421cf6d46f9dfbfbbc..99ac489a77462cc49c7cbd0f994efdd5c7c0c7ed 100644 (file)
 
 #include <wtf/Forward.h>
 #include <wtf/text/WTFString.h>
-
-#if ENABLE(INSPECTOR)
-#include "InspectorJSTypeBuilders.h"
-#endif
+#include "InspectorProtocolObjects.h"
 
 namespace Inspector {
 
@@ -53,9 +50,7 @@ public:
 
     bool isEqual(const ScriptCallFrame&) const;
 
-#if ENABLE(INSPECTOR)
-    PassRefPtr<Inspector::TypeBuilder::Console::CallFrame> buildInspectorObject() const;
-#endif
+    Ref<Inspector::Protocol::Console::CallFrame> buildInspectorObject() const;
 
 private:
     String m_functionName;
index 9b3cca1dfa9caa8bef4bae3c3132414125a4df88..49b0719f5a4a71b95abd2ec0c75a8e7571a194c2 100644 (file)
 
 namespace Inspector {
 
-PassRefPtr<ScriptCallStack> ScriptCallStack::create()
+Ref<ScriptCallStack> ScriptCallStack::create()
 {
-    return adoptRef(new ScriptCallStack);
+    return adoptRef(*new ScriptCallStack);
 }
 
-PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
+Ref<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
 {
-    return adoptRef(new ScriptCallStack(frames));
+    return adoptRef(*new ScriptCallStack(frames));
 }
 
 ScriptCallStack::ScriptCallStack()
@@ -106,14 +106,12 @@ bool ScriptCallStack::isEqual(ScriptCallStack* o) const
     return true;
 }
 
-#if ENABLE(INSPECTOR)
-PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> ScriptCallStack::buildInspectorArray() const
+Ref<Inspector::Protocol::Console::StackTrace> ScriptCallStack::buildInspectorArray() const
 {
-    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> frames = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>::create();
+    auto frames = Inspector::Protocol::Console::StackTrace::create();
     for (size_t i = 0; i < m_frames.size(); i++)
         frames->addItem(m_frames.at(i).buildInspectorObject());
-    return frames;
+    return WTF::move(frames);
 }
-#endif
 
 } // namespace Inspector
index 9c2a534d8e82858823451d1b068aac7c48d17229..d2cbb65961bb38d9e95b9559d75288f176d0002a 100644 (file)
 #ifndef ScriptCallStack_h
 #define ScriptCallStack_h
 
+#include "InspectorProtocolObjects.h"
 #include "ScriptCallFrame.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
-#if ENABLE(INSPECTOR)
-#include "InspectorJSTypeBuilders.h"
-#endif
-
 namespace Inspector {
 
 class JS_EXPORT_PRIVATE ScriptCallStack : public RefCounted<ScriptCallStack> {
 public:
     static const size_t maxCallStackSizeToCapture = 200;
     
-    static PassRefPtr<ScriptCallStack> create();
-    static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&);
+    static Ref<ScriptCallStack> create();
+    static Ref<ScriptCallStack> create(Vector<ScriptCallFrame>&);
 
     ~ScriptCallStack();
 
@@ -61,9 +58,7 @@ public:
 
     bool isEqual(ScriptCallStack*) const;
 
-#if ENABLE(INSPECTOR)
-    PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> buildInspectorArray() const;
-#endif
+    Ref<Inspector::Protocol::Console::StackTrace> buildInspectorArray() const;
 
 private:
     ScriptCallStack();
index 2f06279d36290c7f39d27e041c2319aaabf5d0df..f33d405cbacd6631cb2946f05ed9bf331a23fa49 100644 (file)
@@ -34,6 +34,7 @@
 #include "ScriptCallStackFactory.h"
 
 #include "CallFrame.h"
+#include "Exception.h"
 #include "JSCJSValue.h"
 #include "JSCInlines.h"
 #include "ScriptArguments.h"
@@ -83,7 +84,7 @@ private:
     size_t m_remainingCapacityForFrameCapture;
 };
 
-PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
+Ref<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
 {
     if (!exec)
         return ScriptCallStack::create();
@@ -97,7 +98,7 @@ PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t m
     return ScriptCallStack::create(frames);
 }
 
-PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec, size_t maxStackSize)
+Ref<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec, size_t maxStackSize)
 {
     if (!exec)
         return ScriptCallStack::create();
@@ -119,19 +120,19 @@ PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState* exec
 static void extractSourceInformationFromException(JSC::ExecState* exec, JSObject* exceptionObject, int* lineNumber, int* columnNumber, String* sourceURL)
 {
     // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not need to evaluate JavaScript handling exceptions
-    JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
+    JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier::fromString(exec, "line"));
     *lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
-    JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
+    JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier::fromString(exec, "column"));
     *columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
-    JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
-    *sourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : String("undefined");
+    JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier::fromString(exec, "sourceURL"));
+    *sourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
     exec->clearException();
 }
 
-PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* exec, JSC::JSValue& exception, size_t maxStackSize)
+Ref<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* exec, JSC::Exception* exception, size_t maxStackSize)
 {
     Vector<ScriptCallFrame> frames;
-    RefCountedArray<StackFrame> stackTrace = exec->vm().exceptionStack();
+    RefCountedArray<StackFrame> stackTrace = exception->stack();
     for (size_t i = 0; i < stackTrace.size() && i < maxStackSize; i++) {
         unsigned line;
         unsigned column;
@@ -141,8 +142,8 @@ PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* e
     }
 
     // Fallback to getting at least the line and sourceURL from the exception object if it has values and the exceptionStack doesn't.
-    JSObject* exceptionObject = exception.toObject(exec);
-    if (exception.isObject()) {
+    if (exception->value().isObject()) {
+        JSObject* exceptionObject = exception->value().toObject(exec);
         int lineNumber;
         int columnNumber;
         String exceptionSourceURL;
@@ -161,7 +162,7 @@ PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* e
     return ScriptCallStack::create(frames);
 }
 
-PassRefPtr<ScriptArguments> createScriptArguments(JSC::ExecState* exec, unsigned skipArgumentCount)
+Ref<ScriptArguments> createScriptArguments(JSC::ExecState* exec, unsigned skipArgumentCount)
 {
     Vector<Deprecated::ScriptValue> arguments;
     size_t argumentCount = exec->argumentCount();
index 07c15863d459733ad11a3191fc481f9b9516e9e6..b0c0dc01b13186b296a703ccf71ebb3e9859a255 100644 (file)
@@ -35,6 +35,7 @@
 #include <wtf/Forward.h>
 
 namespace JSC {
+class Exception;
 class ExecState;
 class JSValue;
 }
@@ -45,10 +46,10 @@ class ScriptArguments;
 class ScriptCallStack;
 
 // FIXME: The subtle differences between these should be eliminated.
-JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState*, size_t maxStackSize);
-JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState*, size_t maxStackSize);
-JS_EXPORT_PRIVATE PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState*, JSC::JSValue& exception, size_t maxStackSize);
-JS_EXPORT_PRIVATE PassRefPtr<ScriptArguments> createScriptArguments(JSC::ExecState*, unsigned skipArgumentCount);
+JS_EXPORT_PRIVATE Ref<ScriptCallStack> createScriptCallStack(JSC::ExecState*, size_t maxStackSize);
+JS_EXPORT_PRIVATE Ref<ScriptCallStack> createScriptCallStackForConsole(JSC::ExecState*, size_t maxStackSize);
+JS_EXPORT_PRIVATE Ref<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState*, JSC::Exception*, size_t maxStackSize);
+JS_EXPORT_PRIVATE Ref<ScriptArguments> createScriptArguments(JSC::ExecState*, unsigned skipArgumentCount);
 
 } // namespace Inspector
 
index 3bdbcd823fb9148fa2b6f3ceb2527fae9a39e2aa..dfd9e0ab4462767d1c49ed6e49faaa81a5ed0458 100644 (file)
@@ -75,7 +75,7 @@ public:
 
     virtual void breakpointActionLog(JSC::ExecState*, const String&) = 0;
     virtual void breakpointActionSound(int breakpointActionIdentifier) = 0;
-    virtual void breakpointActionProbe(JSC::ExecState*, const ScriptBreakpointAction&, int hitCount, const Deprecated::ScriptValue& result) = 0;
+    virtual void breakpointActionProbe(JSC::ExecState*, const ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, const Deprecated::ScriptValue& result) = 0;
 };
 
 } // namespace Inspector
index d2798933f93b4d355623e4089d15c2c11ccd5a76..74602c521886707c79fc9a14311664d6efa0b603 100644 (file)
@@ -31,9 +31,9 @@
 #include "config.h"
 #include "ScriptDebugServer.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "DebuggerCallFrame.h"
+#include "DebuggerScope.h"
+#include "Exception.h"
 #include "JSJavaScriptCallFrame.h"
 #include "JSLock.h"
 #include "JavaScriptCallFrame.h"
@@ -49,8 +49,6 @@ namespace Inspector {
 
 ScriptDebugServer::ScriptDebugServer(bool isInWorkerThread)
     : Debugger(isInWorkerThread)
-    , m_doneProcessingDebuggerEvents(true)
-    , m_callingListeners(false)
 {
 }
 
@@ -96,7 +94,7 @@ bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& b
         break;
     }
     case ScriptBreakpointActionTypeEvaluate: {
-        JSValue exception;
+        NakedPtr<Exception> exception;
         debuggerCallFrame->evaluate(breakpointAction.data, exception);
         if (exception)
             reportException(debuggerCallFrame->exec(), exception);
@@ -106,13 +104,13 @@ bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& b
         dispatchBreakpointActionSound(debuggerCallFrame->exec(), breakpointAction.identifier);
         break;
     case ScriptBreakpointActionTypeProbe: {
-        JSValue exception;
+        NakedPtr<Exception> exception;
         JSValue result = debuggerCallFrame->evaluate(breakpointAction.data, exception);
         if (exception)
             reportException(debuggerCallFrame->exec(), exception);
         
         JSC::ExecState* state = debuggerCallFrame->scope()->globalObject()->globalExec();
-        Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception : result);
+        Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception->value() : result);
         dispatchBreakpointActionProbe(state, breakpointAction, wrappedResult);
         break;
     }
@@ -137,7 +135,8 @@ void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener)
     JSC::ExecState* state = globalObject->globalExec();
     RefPtr<JavaScriptCallFrame> javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame);
     JSValue jsCallFrame = toJS(state, globalObject, javaScriptCallFrame.get());
-    listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), Deprecated::ScriptValue());
+
+    listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), exceptionOrCaughtValue(state));
 }
 
 void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const String& message)
@@ -145,53 +144,52 @@ void ScriptDebugServer::dispatchBreakpointActionLog(ExecState* exec, const Strin
     if (m_callingListeners)
         return;
 
-    ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject());
-    if (!listeners)
+    ListenerSet& listeners = getListeners();
+    if (listeners.isEmpty())
         return;
-    ASSERT(!listeners->isEmpty());
 
     TemporaryChange<bool> change(m_callingListeners, true);
 
     Vector<ScriptDebugListener*> listenersCopy;
-    copyToVector(*listeners, listenersCopy);
+    copyToVector(listeners, listenersCopy);
     for (auto* listener : listenersCopy)
         listener->breakpointActionLog(exec, message);
 }
 
-void ScriptDebugServer::dispatchBreakpointActionSound(ExecState* exec, int breakpointActionIdentifier)
+void ScriptDebugServer::dispatchBreakpointActionSound(ExecState*, int breakpointActionIdentifier)
 {
     if (m_callingListeners)
         return;
 
-    ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject());
-    if (!listeners)
+    ListenerSet& listeners = getListeners();
+    if (listeners.isEmpty())
         return;
-    ASSERT(!listeners->isEmpty());
 
     TemporaryChange<bool> change(m_callingListeners, true);
 
     Vector<ScriptDebugListener*> listenersCopy;
-    copyToVector(*listeners, listenersCopy);
+    copyToVector(listeners, listenersCopy);
     for (auto* listener : listenersCopy)
         listener->breakpointActionSound(breakpointActionIdentifier);
 }
 
-void ScriptDebugServer::dispatchBreakpointActionProbe(ExecState* exec, const ScriptBreakpointAction& action, const Deprecated::ScriptValue& sample)
+void ScriptDebugServer::dispatchBreakpointActionProbe(ExecState* exec, const ScriptBreakpointAction& action, const Deprecated::ScriptValue& sampleValue)
 {
     if (m_callingListeners)
         return;
 
-    ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject());
-    if (!listeners)
+    ListenerSet& listeners = getListeners();
+    if (listeners.isEmpty())
         return;
-    ASSERT(!listeners->isEmpty());
 
     TemporaryChange<bool> change(m_callingListeners, true);
 
+    unsigned sampleId = m_nextProbeSampleId++;
+
     Vector<ScriptDebugListener*> listenersCopy;
-    copyToVector(*listeners, listenersCopy);
+    copyToVector(listeners, listenersCopy);
     for (auto* listener : listenersCopy)
-        listener->breakpointActionProbe(exec, action, m_hitCount, sample);
+        listener->breakpointActionProbe(exec, action, m_currentProbeBatchId, sampleId, sampleValue);
 }
 
 void ScriptDebugServer::dispatchDidContinue(ScriptDebugListener* listener)
@@ -249,79 +247,77 @@ void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProv
     if (m_callingListeners)
         return;
 
-    ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject());
-    if (!listeners)
+    ListenerSet& listeners = getListeners();
+    if (listeners.isEmpty())
         return;
-    ASSERT(!listeners->isEmpty());
 
     TemporaryChange<bool> change(m_callingListeners, true);
 
     bool isError = errorLine != -1;
     if (isError)
-        dispatchFailedToParseSource(*listeners, sourceProvider, errorLine, errorMessage);
+        dispatchFailedToParseSource(listeners, sourceProvider, errorLine, errorMessage);
     else
-        dispatchDidParseSource(*listeners, sourceProvider, isContentScript(exec));
+        dispatchDidParseSource(listeners, sourceProvider, isContentScript(exec));
 }
 
-void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback)
-{
-    Vector<ScriptDebugListener*> copy;
-    copyToVector(listeners, copy);
-    for (size_t i = 0; i < copy.size(); ++i)
-        (this->*callback)(copy[i]);
-}
-
-void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, JSGlobalObject* globalObject)
+void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback)
 {
     if (m_callingListeners)
         return;
 
     TemporaryChange<bool> change(m_callingListeners, true);
 
-    if (ListenerSet* listeners = getListenersForGlobalObject(globalObject)) {
-        if (!listeners->isEmpty())
-            dispatchFunctionToListeners(*listeners, callback);
-    }
+    ListenerSet& listeners = getListeners();
+    if (!listeners.isEmpty())
+        dispatchFunctionToListeners(listeners, callback);
 }
 
-void ScriptDebugServer::notifyDoneProcessingDebuggerEvents()
+void ScriptDebugServer::dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback callback)
 {
-    m_doneProcessingDebuggerEvents = true;
+    Vector<ScriptDebugListener*> copy;
+    copyToVector(listeners, copy);
+    for (size_t i = 0; i < copy.size(); ++i)
+        (this->*callback)(copy[i]);
 }
 
-bool ScriptDebugServer::needPauseHandling(JSGlobalObject* globalObject)
+void ScriptDebugServer::notifyDoneProcessingDebuggerEvents()
 {
-    return !!getListenersForGlobalObject(globalObject);
+    m_doneProcessingDebuggerEvents = true;
 }
 
-void ScriptDebugServer::handleBreakpointHit(const JSC::Breakpoint& breakpoint)
+void ScriptDebugServer::handleBreakpointHit(JSC::JSGlobalObject* globalObject, const JSC::Breakpoint& breakpoint)
 {
-    m_hitCount++;
+    ASSERT(isAttached(globalObject));
+
+    m_currentProbeBatchId++;
+
     BreakpointIDToActionsMap::iterator it = m_breakpointIDToActions.find(breakpoint.id);
     if (it != m_breakpointIDToActions.end()) {
-        BreakpointActions& actions = it->value;
+        BreakpointActions actions = it->value;
         for (size_t i = 0; i < actions.size(); ++i) {
             if (!evaluateBreakpointAction(actions[i]))
                 return;
+            if (!isAttached(globalObject))
+                return;
         }
     }
 }
 
-void ScriptDebugServer::handleExceptionInBreakpointCondition(JSC::ExecState* exec, JSC::JSValue exception) const
+void ScriptDebugServer::handleExceptionInBreakpointCondition(JSC::ExecState* exec, JSC::Exception* exception) const
 {
     reportException(exec, exception);
 }
 
-void ScriptDebugServer::handlePause(Debugger::ReasonForPause, JSGlobalObject* vmEntryGlobalObject)
+void ScriptDebugServer::handlePause(JSGlobalObject* vmEntryGlobalObject, Debugger::ReasonForPause)
 {
-    dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, vmEntryGlobalObject);
+    dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause);
     didPause(vmEntryGlobalObject);
 
     m_doneProcessingDebuggerEvents = false;
     runEventLoopWhilePaused();
 
     didContinue(vmEntryGlobalObject);
-    dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, vmEntryGlobalObject);
+    dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue);
 }
 
 const BreakpointActions& ScriptDebugServer::getActionsForBreakpoint(JSC::BreakpointID breakpointID)
@@ -335,6 +331,20 @@ const BreakpointActions& ScriptDebugServer::getActionsForBreakpoint(JSC::Breakpo
     return emptyActionVector;
 }
 
-} // namespace Inspector
+Deprecated::ScriptValue ScriptDebugServer::exceptionOrCaughtValue(JSC::ExecState* state)
+{
+    if (reasonForPause() == PausedForException)
+        return Deprecated::ScriptValue(state->vm(), currentException());
+
+    RefPtr<DebuggerCallFrame> debuggerCallFrame = currentDebuggerCallFrame();
+    while (debuggerCallFrame) {
+        DebuggerScope* scope = debuggerCallFrame->scope();
+        if (scope->isCatchScope())
+            return Deprecated::ScriptValue(state->vm(), scope->caughtValue());
+        debuggerCallFrame = debuggerCallFrame->callerFrame();
+    }
 
-#endif // ENABLE(INSPECTOR)
+    return Deprecated::ScriptValue();
+}
+
+} // namespace Inspector
index a7bf8ef84594242a9d6009b9112f616000a5c1fa..99eb7230ca2bee05847bf0f6e552be3b24213bd4 100644 (file)
@@ -74,16 +74,16 @@ protected:
     ScriptDebugServer(bool isInWorkerThread = false);
     ~ScriptDebugServer();
 
-    virtual ListenerSet* getListenersForGlobalObject(JSC::JSGlobalObject*) = 0;
+    virtual ListenerSet& getListeners() = 0;
     virtual void didPause(JSC::JSGlobalObject*) = 0;
     virtual void didContinue(JSC::JSGlobalObject*) = 0;
     virtual void runEventLoopWhilePaused() = 0;
     virtual bool isContentScript(JSC::ExecState*) const = 0;
-    virtual void reportException(JSC::ExecState*, JSC::JSValue) const = 0;
+    virtual void reportException(JSC::ExecState*, JSC::Exception*) const = 0;
 
     bool evaluateBreakpointAction(const ScriptBreakpointAction&);
 
-    void dispatchFunctionToListeners(JavaScriptExecutionCallback, JSC::JSGlobalObject*);
+    void dispatchFunctionToListeners(JavaScriptExecutionCallback);
     void dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptExecutionCallback);
     void dispatchDidPause(ScriptDebugListener*);
     void dispatchDidContinue(ScriptDebugListener*);
@@ -93,21 +93,26 @@ protected:
     void dispatchBreakpointActionSound(JSC::ExecState*, int breakpointActionIdentifier);
     void dispatchBreakpointActionProbe(JSC::ExecState*, const ScriptBreakpointAction&, const Deprecated::ScriptValue& sample);
 
-    bool m_doneProcessingDebuggerEvents;
+    bool m_doneProcessingDebuggerEvents {true};
 
 private:
     typedef HashMap<JSC::BreakpointID, BreakpointActions> BreakpointIDToActionsMap;
 
     virtual void sourceParsed(JSC::ExecState*, JSC::SourceProvider*, int errorLine, const String& errorMsg) override final;
-    virtual bool needPauseHandling(JSC::JSGlobalObject*) override final;
-    virtual void handleBreakpointHit(const JSC::Breakpoint&) override final;
-    virtual void handleExceptionInBreakpointCondition(JSC::ExecState*, JSC::JSValue exception) const override final;
-    virtual void handlePause(JSC::Debugger::ReasonForPause, JSC::JSGlobalObject*) override final;
+    virtual bool needPauseHandling(JSC::JSGlobalObject*) override final { return true; }
+    virtual void handleBreakpointHit(JSC::JSGlobalObject*, const JSC::Breakpoint&) override final;
+    virtual void handleExceptionInBreakpointCondition(JSC::ExecState*, JSC::Exception*) const override final;
+    virtual void handlePause(JSC::JSGlobalObject*, JSC::Debugger::ReasonForPause) override final;
     virtual void notifyDoneProcessingDebuggerEvents() override final;
 
-    unsigned m_hitCount;
-    bool m_callingListeners;
+    Deprecated::ScriptValue exceptionOrCaughtValue(JSC::ExecState*);
+
+    bool m_callingListeners {false};
+
     BreakpointIDToActionsMap m_breakpointIDToActions;
+
+    unsigned m_nextProbeSampleId {1};
+    unsigned m_currentProbeBatchId {0};
 };
 
 } // namespace Inspector
index be096116117a577160d9758d3977b8f76177185e..05386901e61e7fbcdece0bc15290d9f5bace0188 100644 (file)
 #include "config.h"
 #include "InspectorAgent.h"
 
-#if ENABLE(INSPECTOR)
-
+#include "InspectorEnvironment.h"
 #include "InspectorValues.h"
 #include "ScriptValue.h"
 
 namespace Inspector {
 
-InspectorAgent::InspectorAgent()
+InspectorAgent::InspectorAgent(InspectorEnvironment& environment)
     : InspectorAgentBase(ASCIILiteral("Inspector"))
+    , m_environment(environment)
     , m_enabled(false)
 {
 }
@@ -48,29 +48,34 @@ InspectorAgent::~InspectorAgent()
 {
 }
 
-void InspectorAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+void InspectorAgent::didCreateFrontendAndBackend(FrontendChannel* frontendChannel, BackendDispatcher* backendDispatcher)
 {
-    m_frontendDispatcher = std::make_unique<InspectorInspectorFrontendDispatcher>(frontendChannel);
-    m_backendDispatcher = InspectorInspectorBackendDispatcher::create(backendDispatcher, this);
+    m_frontendDispatcher = std::make_unique<InspectorFrontendDispatcher>(frontendChannel);
+    m_backendDispatcher = InspectorBackendDispatcher::create(backendDispatcher, this);
 }
 
-void InspectorAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
+void InspectorAgent::willDestroyFrontendAndBackend(DisconnectReason)
 {
     m_frontendDispatcher = nullptr;
-    m_backendDispatcher.clear();
+    m_backendDispatcher = nullptr;
 
     m_pendingEvaluateTestCommands.clear();
 
-    ErrorString error;
-    disable(&error);
+    ErrorString unused;
+    disable(unused);
 }
 
-void InspectorAgent::enable(ErrorString*)
+void InspectorAgent::enable(ErrorString&)
 {
     m_enabled = true;
 
     if (m_pendingInspectData.first)
-        inspect(m_pendingInspectData.first, m_pendingInspectData.second);
+        inspect(m_pendingInspectData.first.copyRef(), m_pendingInspectData.second.copyRef());
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_pendingExtraDomainsData)
+        m_frontendDispatcher->activateExtraDomains(m_pendingExtraDomainsData);
+#endif
 
     for (auto& testCommand : m_pendingEvaluateTestCommands) {
         if (!m_frontendDispatcher)
@@ -82,12 +87,17 @@ void InspectorAgent::enable(ErrorString*)
     m_pendingEvaluateTestCommands.clear();
 }
 
-void InspectorAgent::disable(ErrorString*)
+void InspectorAgent::disable(ErrorString&)
 {
     m_enabled = false;
 }
 
-void InspectorAgent::inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<InspectorObject> hints)
+void InspectorAgent::initialized(ErrorString&)
+{
+    m_environment.frontendInitialized();
+}
+
+void InspectorAgent::inspect(RefPtr<Protocol::Runtime::RemoteObject>&& objectToInspect, RefPtr<InspectorObject>&& hints)
 {
     if (m_enabled && m_frontendDispatcher) {
         m_frontendDispatcher->inspect(objectToInspect, hints);
@@ -108,6 +118,35 @@ void InspectorAgent::evaluateForTestInFrontend(const String& script)
         m_pendingEvaluateTestCommands.append(script);
 }
 
-} // namespace Inspector
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+void InspectorAgent::activateExtraDomain(const String& domainName)
+{
+    if (!m_enabled) {
+        if (!m_pendingExtraDomainsData)
+            m_pendingExtraDomainsData = Inspector::Protocol::Array<String>::create();
+        m_pendingExtraDomainsData->addItem(domainName);
+        return;
+    }
 
-#endif // ENABLE(INSPECTOR)
+    Ref<Inspector::Protocol::Array<String>> domainNames = Inspector::Protocol::Array<String>::create();
+    domainNames->addItem(domainName);
+    m_frontendDispatcher->activateExtraDomains(WTF::move(domainNames));
+}
+
+void InspectorAgent::activateExtraDomains(const Vector<String>& extraDomains)
+{
+    if (extraDomains.isEmpty())
+        return;
+
+    RefPtr<Inspector::Protocol::Array<String>> domainNames = Inspector::Protocol::Array<String>::create();
+    for (auto domainName : extraDomains)
+        domainNames->addItem(domainName);
+
+    if (!m_enabled)
+        m_pendingExtraDomainsData = domainNames.release();
+    else
+        m_frontendDispatcher->activateExtraDomains(domainNames.release());
+}
+#endif
+
+} // namespace Inspector
index 1d30e2e016959b408a83a4ed95954a6c5c52a9a2..4c6ef782c177fe2c85b28adea5e64dc73669f9c5 100644 (file)
 #ifndef InspectorAgent_h
 #define InspectorAgent_h
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSBackendDispatchers.h"
-#include "InspectorJSFrontendDispatchers.h"
+#include "InspectorBackendDispatchers.h"
+#include "InspectorFrontendDispatchers.h"
 #include "inspector/InspectorAgentBase.h"
 #include <wtf/Forward.h>
 #include <wtf/Vector.h>
 
 namespace Inspector {
 
+class BackendDispatcher;
+class InspectorEnvironment;
 class InspectorObject;
-class InstrumentingAgents;
-class InspectorInspectorBackendDispatcher;
-class InspectorInspectorFrontendDispatchers;
 
 typedef String ErrorString;
 
-class JS_EXPORT_PRIVATE InspectorAgent final : public InspectorAgentBase, public InspectorInspectorBackendDispatcherHandler {
+class JS_EXPORT_PRIVATE InspectorAgent final : public InspectorAgentBase, public InspectorBackendDispatcherHandler {
     WTF_MAKE_NONCOPYABLE(InspectorAgent);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    InspectorAgent();
+    InspectorAgent(InspectorEnvironment&);
     virtual ~InspectorAgent();
 
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) override;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason reason) override;
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*) override;
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
 
-    virtual void enable(ErrorString*) override;
-    virtual void disable(ErrorString*) override;
+    virtual void enable(ErrorString&) override;
+    virtual void disable(ErrorString&) override;
+    virtual void initialized(ErrorString&) override;
 
-    void inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<InspectorObject> hints);
+    void inspect(RefPtr<Protocol::Runtime::RemoteObject>&& objectToInspect, RefPtr<InspectorObject>&& hints);
     void evaluateForTestInFrontend(const String& script);
 
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    void activateExtraDomain(const String&);
+    void activateExtraDomains(const Vector<String>&);
+#endif
+
 private:
-    std::unique_ptr<InspectorInspectorFrontendDispatcher> m_frontendDispatcher;
-    RefPtr<InspectorInspectorBackendDispatcher> m_backendDispatcher;
+    InspectorEnvironment& m_environment;
+    std::unique_ptr<InspectorFrontendDispatcher> m_frontendDispatcher;
+    RefPtr<InspectorBackendDispatcher> m_backendDispatcher;
     Vector<String> m_pendingEvaluateTestCommands;
-    std::pair<RefPtr<TypeBuilder::Runtime::RemoteObject>, RefPtr<InspectorObject>> m_pendingInspectData;
+    std::pair<RefPtr<Protocol::Runtime::RemoteObject>, RefPtr<InspectorObject>> m_pendingInspectData;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    RefPtr<Inspector::Protocol::Array<String>> m_pendingExtraDomainsData;
+#endif
     bool m_enabled;
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(InspectorAgent_h)
index 2ddec37108b8d6661daa12077276be8481dae364..9ffd0484f28062c29bcadb4b9b9d370b1f71137f 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "InspectorConsoleAgent.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "ConsoleMessage.h"
 #include "InjectedScriptManager.h"
 #include "ScriptArguments.h"
@@ -57,22 +55,22 @@ InspectorConsoleAgent::~InspectorConsoleAgent()
 {
 }
 
-void InspectorConsoleAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+void InspectorConsoleAgent::didCreateFrontendAndBackend(FrontendChannel* frontendChannel, BackendDispatcher* backendDispatcher)
 {
-    m_frontendDispatcher = std::make_unique<InspectorConsoleFrontendDispatcher>(frontendChannel);
-    m_backendDispatcher = InspectorConsoleBackendDispatcher::create(backendDispatcher, this);
+    m_frontendDispatcher = std::make_unique<ConsoleFrontendDispatcher>(frontendChannel);
+    m_backendDispatcher = ConsoleBackendDispatcher::create(backendDispatcher, this);
 }
 
-void InspectorConsoleAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
+void InspectorConsoleAgent::willDestroyFrontendAndBackend(DisconnectReason)
 {
     m_frontendDispatcher = nullptr;
-    m_backendDispatcher.clear();
+    m_backendDispatcher = nullptr;
 
     String errorString;
-    disable(&errorString);
+    disable(errorString);
 }
 
-void InspectorConsoleAgent::enable(ErrorString*)
+void InspectorConsoleAgent::enable(ErrorString&)
 {
     if (m_enabled)
         return;
@@ -89,7 +87,7 @@ void InspectorConsoleAgent::enable(ErrorString*)
         m_consoleMessages[i]->addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, false);
 }
 
-void InspectorConsoleAgent::disable(ErrorString*)
+void InspectorConsoleAgent::disable(ErrorString&)
 {
     if (!m_enabled)
         return;
@@ -97,7 +95,7 @@ void InspectorConsoleAgent::disable(ErrorString*)
     m_enabled = false;
 }
 
-void InspectorConsoleAgent::clearMessages(ErrorString*)
+void InspectorConsoleAgent::clearMessages(ErrorString&)
 {
     m_consoleMessages.clear();
     m_expiredConsoleMessageCount = 0;
@@ -111,50 +109,24 @@ void InspectorConsoleAgent::clearMessages(ErrorString*)
 
 void InspectorConsoleAgent::reset()
 {
-    ErrorString error;
-    clearMessages(&error);
+    ErrorString unused;
+    clearMessages(unused);
 
     m_times.clear();
     m_counts.clear();
 }
 
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
-{
-    if (!m_injectedScriptManager->inspectorEnvironment().developerExtrasEnabled())
-        return;
-
-    if (type == MessageType::Clear) {
-        ErrorString error;
-        clearMessages(&error);
-    }
-
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, callStack, requestIdentifier));
-}
-
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier)
+void InspectorConsoleAgent::addMessageToConsole(std::unique_ptr<ConsoleMessage> message)
 {
     if (!m_injectedScriptManager->inspectorEnvironment().developerExtrasEnabled())
         return;
 
-    if (type == MessageType::Clear) {
-        ErrorString error;
-        clearMessages(&error);
+    if (message->type() == MessageType::Clear) {
+        ErrorString unused;
+        clearMessages(unused);
     }
 
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, arguments, state, requestIdentifier));
-}
-
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier)
-{
-    if (!m_injectedScriptManager->inspectorEnvironment().developerExtrasEnabled())
-        return;
-
-    if (type == MessageType::Clear) {
-        ErrorString error;
-        clearMessages(&error);
-    }
-
-    addConsoleMessage(std::make_unique<ConsoleMessage>(source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier));
+    addConsoleMessage(WTF::move(message));
 }
 
 Vector<unsigned> InspectorConsoleAgent::consoleMessageArgumentCounts() const
@@ -191,7 +163,7 @@ void InspectorConsoleAgent::stopTiming(const String& title, PassRefPtr<ScriptCal
 
     double elapsed = monotonicallyIncreasingTime() - startTime;
     String message = title + String::format(": %.3fms", elapsed * 1000);
-    addMessageToConsole(MessageSource::ConsoleAPI, MessageType::Timing, MessageLevel::Debug, message, callStack);
+    addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Timing, MessageLevel::Debug, message, callStack));
 }
 
 void InspectorConsoleAgent::count(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
@@ -216,7 +188,7 @@ void InspectorConsoleAgent::count(JSC::ExecState* state, PassRefPtr<ScriptArgume
     m_counts.add(identifier, count);
 
     String message = title + ": " + String::number(count);
-    addMessageToConsole(MessageSource::ConsoleAPI, MessageType::Log, MessageLevel::Debug, message, callStack);
+    addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Log, MessageLevel::Debug, message, callStack));
 }
 
 static bool isGroupMessage(MessageType type)
@@ -249,5 +221,3 @@ void InspectorConsoleAgent::addConsoleMessage(std::unique_ptr<ConsoleMessage> co
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 913a7d00218ccf30714af3266a5581e01ecc56a6..b9da99d382efcb1b26d97c257e6d0d4c505f2120 100644 (file)
 #ifndef InspectorConsoleAgent_h
 #define InspectorConsoleAgent_h
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSBackendDispatchers.h"
-#include "InspectorJSFrontendDispatchers.h"
+#include "InspectorBackendDispatchers.h"
+#include "InspectorFrontendDispatchers.h"
 #include "inspector/InspectorAgentBase.h"
 #include "runtime/ConsoleTypes.h"
 #include <wtf/Forward.h>
@@ -50,30 +48,28 @@ class ScriptArguments;
 class ScriptCallStack;
 typedef String ErrorString;
 
-class JS_EXPORT_PRIVATE InspectorConsoleAgent : public InspectorAgentBase, public InspectorConsoleBackendDispatcherHandler {
+class JS_EXPORT_PRIVATE InspectorConsoleAgent : public InspectorAgentBase, public ConsoleBackendDispatcherHandler {
     WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent);
     WTF_MAKE_FAST_ALLOCATED;
 public:
     InspectorConsoleAgent(InjectedScriptManager*);
     virtual ~InspectorConsoleAgent();
 
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) override;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason) override;
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*) override;
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
 
-    virtual void enable(ErrorString*) override;
-    virtual void disable(ErrorString*) override;
-    virtual void clearMessages(ErrorString*) override;
-    virtual void setMonitoringXHREnabled(ErrorString*, bool enabled) = 0;
-    virtual void addInspectedNode(ErrorString*, int nodeId) = 0;
+    virtual void enable(ErrorString&) override;
+    virtual void disable(ErrorString&) override;
+    virtual void clearMessages(ErrorString&) override;
+    virtual void setMonitoringXHREnabled(ErrorString&, bool enabled) override = 0;
+    virtual void addInspectedNode(ErrorString&, int nodeId) override = 0;
 
     virtual bool isWorkerAgent() const = 0;
 
     bool enabled() const { return m_enabled; }
     void reset();
 
-    void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, JSC::ExecState*, PassRefPtr<ScriptArguments>, unsigned long requestIdentifier = 0);
-    void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
-    void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0);
+    void addMessageToConsole(std::unique_ptr<ConsoleMessage>);
 
     Vector<unsigned> consoleMessageArgumentCounts() const;
 
@@ -85,8 +81,8 @@ protected:
     void addConsoleMessage(std::unique_ptr<ConsoleMessage>);
 
     InjectedScriptManager* m_injectedScriptManager;
-    std::unique_ptr<InspectorConsoleFrontendDispatcher> m_frontendDispatcher;
-    RefPtr<InspectorConsoleBackendDispatcher> m_backendDispatcher;
+    std::unique_ptr<ConsoleFrontendDispatcher> m_frontendDispatcher;
+    RefPtr<ConsoleBackendDispatcher> m_backendDispatcher;
     ConsoleMessage* m_previousMessage;
     Vector<std::unique_ptr<ConsoleMessage>> m_consoleMessages;
     int m_expiredConsoleMessageCount;
@@ -97,6 +93,4 @@ protected:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(InspectorConsoleAgent_h)
index 5096a6c99d2a9120438c68fdc88758f6cbfaeb9f..f0f0b48dd4d47cde3a0f2a8822c46325de5aab4f 100644 (file)
@@ -30,8 +30,6 @@
 #include "config.h"
 #include "InspectorDebuggerAgent.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "ContentSearchUtilities.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
@@ -40,6 +38,7 @@
 #include "ScriptDebugServer.h"
 #include "ScriptObject.h"
 #include "ScriptValue.h"
+#include <wtf/Stopwatch.h>
 #include <wtf/text/WTFString.h>
 
 namespace Inspector {
@@ -59,12 +58,7 @@ static String objectGroupForBreakpointAction(const ScriptBreakpointAction& actio
 InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedScriptManager)
     : InspectorAgentBase(ASCIILiteral("Debugger"))
     , m_injectedScriptManager(injectedScriptManager)
-    , m_listener(nullptr)
-    , m_pausedScriptState(nullptr)
     , m_continueToLocationBreakpointID(JSC::noBreakpointID)
-    , m_enabled(false)
-    , m_javaScriptPauseScheduled(false)
-    , m_nextProbeSampleId(1)
 {
     // FIXME: make breakReason optional so that there was no need to init it with "other".
     clearBreakDetails();
@@ -74,18 +68,18 @@ InspectorDebuggerAgent::~InspectorDebuggerAgent()
 {
 }
 
-void InspectorDebuggerAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+void InspectorDebuggerAgent::didCreateFrontendAndBackend(FrontendChannel* frontendChannel, BackendDispatcher* backendDispatcher)
 {
-    m_frontendDispatcher = std::make_unique<InspectorDebuggerFrontendDispatcher>(frontendChannel);
-    m_backendDispatcher = InspectorDebuggerBackendDispatcher::create(backendDispatcher, this);
+    m_frontendDispatcher = std::make_unique<DebuggerFrontendDispatcher>(frontendChannel);
+    m_backendDispatcher = DebuggerBackendDispatcher::create(backendDispatcher, this);
 }
 
-void InspectorDebuggerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
+void InspectorDebuggerAgent::willDestroyFrontendAndBackend(DisconnectReason reason)
 {
     m_frontendDispatcher = nullptr;
-    m_backendDispatcher.clear();
+    m_backendDispatcher = nullptr;
 
-    bool skipRecompile = reason == InspectorDisconnectReason::InspectedTargetDestroyed;
+    bool skipRecompile = reason == DisconnectReason::InspectedTargetDestroyed;
     disable(skipRecompile);
 }
 
@@ -119,17 +113,17 @@ void InspectorDebuggerAgent::disable(bool isBeingDestroyed)
     m_enabled = false;
 }
 
-void InspectorDebuggerAgent::enable(ErrorString*)
+void InspectorDebuggerAgent::enable(ErrorString&)
 {
     enable();
 }
 
-void InspectorDebuggerAgent::disable(ErrorString*)
+void InspectorDebuggerAgent::disable(ErrorString&)
 {
     disable(false);
 }
 
-void InspectorDebuggerAgent::setBreakpointsActive(ErrorString*, bool active)
+void InspectorDebuggerAgent::setBreakpointsActive(ErrorString&, bool active)
 {
     if (active)
         scriptDebugServer().activateBreakpoints();
@@ -142,18 +136,60 @@ bool InspectorDebuggerAgent::isPaused()
     return scriptDebugServer().isPaused();
 }
 
-void InspectorDebuggerAgent::handleConsoleAssert()
+static RefPtr<InspectorObject> buildAssertPauseReason(const String& message)
+{
+    auto reason = Inspector::Protocol::Debugger::AssertPauseReason::create().release();
+    if (!message.isNull())
+        reason->setMessage(message);
+    return reason->openAccessors();
+}
+
+static RefPtr<InspectorObject> buildCSPViolationPauseReason(const String& directiveText)
+{
+    auto reason = Inspector::Protocol::Debugger::CSPViolationPauseReason::create()
+        .setDirective(directiveText)
+        .release();
+    return reason->openAccessors();
+}
+
+RefPtr<InspectorObject> InspectorDebuggerAgent::buildBreakpointPauseReason(JSC::BreakpointID debuggerBreakpointIdentifier)
+{
+    ASSERT(debuggerBreakpointIdentifier != JSC::noBreakpointID);
+    auto it = m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.find(debuggerBreakpointIdentifier);
+    if (it == m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.end())
+        return nullptr;
+
+    auto reason = Inspector::Protocol::Debugger::BreakpointPauseReason::create()
+        .setBreakpointId(it->value)
+        .release();
+    return reason->openAccessors();
+}
+
+RefPtr<InspectorObject> InspectorDebuggerAgent::buildExceptionPauseReason(const Deprecated::ScriptValue& exception, const InjectedScript& injectedScript)
+{
+    ASSERT(!exception.hasNoValue());
+    if (exception.hasNoValue())
+        return nullptr;
+
+    ASSERT(!injectedScript.hasNoValue());
+    if (injectedScript.hasNoValue())
+        return nullptr;
+
+    return injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
+}
+
+void InspectorDebuggerAgent::handleConsoleAssert(const String& message)
 {
     if (scriptDebugServer().pauseOnExceptionsState() != JSC::Debugger::DontPauseOnExceptions)
-        breakProgram(InspectorDebuggerFrontendDispatcher::Reason::Assert, nullptr);
+        breakProgram(DebuggerFrontendDispatcher::Reason::Assert, buildAssertPauseReason(message));
 }
 
-static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue)
+static Ref<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue)
 {
-    RefPtr<InspectorObject> breakpointObject = InspectorObject::create();
+    Ref<InspectorObject> breakpointObject = InspectorObject::create();
     breakpointObject->setString(ASCIILiteral("url"), url);
-    breakpointObject->setNumber(ASCIILiteral("lineNumber"), lineNumber);
-    breakpointObject->setNumber(ASCIILiteral("columnNumber"), columnNumber);
+    breakpointObject->setInteger(ASCIILiteral("lineNumber"), lineNumber);
+    breakpointObject->setInteger(ASCIILiteral("columnNumber"), columnNumber);
     breakpointObject->setString(ASCIILiteral("condition"), condition);
     breakpointObject->setBoolean(ASCIILiteral("isRegex"), isRegex);
     breakpointObject->setBoolean(ASCIILiteral("autoContinue"), autoContinue);
@@ -175,19 +211,19 @@ static bool matches(const String& url, const String& pattern, bool isRegex)
 
 static bool breakpointActionTypeForString(const String& typeString, ScriptBreakpointActionType* output)
 {
-    if (typeString == Inspector::TypeBuilder::getJSEnumConstantValue(Inspector::TypeBuilder::Debugger::BreakpointAction::Type::Log)) {
+    if (typeString == Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Debugger::BreakpointAction::Type::Log)) {
         *output = ScriptBreakpointActionTypeLog;
         return true;
     }
-    if (typeString == Inspector::TypeBuilder::getJSEnumConstantValue(Inspector::TypeBuilder::Debugger::BreakpointAction::Type::Evaluate)) {
+    if (typeString == Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Debugger::BreakpointAction::Type::Evaluate)) {
         *output = ScriptBreakpointActionTypeEvaluate;
         return true;
     }
-    if (typeString == Inspector::TypeBuilder::getJSEnumConstantValue(Inspector::TypeBuilder::Debugger::BreakpointAction::Type::Sound)) {
+    if (typeString == Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Debugger::BreakpointAction::Type::Sound)) {
         *output = ScriptBreakpointActionTypeSound;
         return true;
     }
-    if (typeString == Inspector::TypeBuilder::getJSEnumConstantValue(Inspector::TypeBuilder::Debugger::BreakpointAction::Type::Probe)) {
+    if (typeString == Inspector::Protocol::getEnumConstantValue(Inspector::Protocol::Debugger::BreakpointAction::Type::Probe)) {
         *output = ScriptBreakpointActionTypeProbe;
         return true;
     }
@@ -195,7 +231,7 @@ static bool breakpointActionTypeForString(const String& typeString, ScriptBreakp
     return false;
 }
 
-bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString* errorString, RefPtr<InspectorArray>& actions, BreakpointActions* result)
+bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString& errorString, RefPtr<InspectorArray>& actions, BreakpointActions* result)
 {
     if (!actions)
         return true;
@@ -208,30 +244,30 @@ bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString* errorStr
     for (unsigned i = 0; i < actionsLength; ++i) {
         RefPtr<InspectorValue> value = actions->get(i);
         RefPtr<InspectorObject> object;
-        if (!value->asObject(&object)) {
-            *errorString = ASCIILiteral("BreakpointAction of incorrect type, expected object");
+        if (!value->asObject(object)) {
+            errorString = ASCIILiteral("BreakpointAction of incorrect type, expected object");
             return false;
         }
 
         String typeString;
-        if (!object->getString(ASCIILiteral("type"), &typeString)) {
-            *errorString = ASCIILiteral("BreakpointAction had type missing");
+        if (!object->getString(ASCIILiteral("type"), typeString)) {
+            errorString = ASCIILiteral("BreakpointAction had type missing");
             return false;
         }
 
         ScriptBreakpointActionType type;
         if (!breakpointActionTypeForString(typeString, &type)) {
-            *errorString = ASCIILiteral("BreakpointAction had unknown type");
+            errorString = ASCIILiteral("BreakpointAction had unknown type");
             return false;
         }
 
         // Specifying an identifier is optional. They are used to correlate probe samples
         // in the frontend across multiple backend probe actions and segregate object groups.
         int identifier = 0;
-        object->getNumber(ASCIILiteral("id"), &identifier);
+        object->getInteger(ASCIILiteral("id"), identifier);
 
         String data;
-        object->getString(ASCIILiteral("data"), &data);
+        object->getString(ASCIILiteral("data"), data);
 
         result->append(ScriptBreakpointAction(type, identifier, data));
     }
@@ -239,11 +275,11 @@ bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString* errorStr
     return true;
 }
 
-void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations)
+void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString& errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const InspectorObject* options, Inspector::Protocol::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Debugger::Location>>& locations)
 {
-    locations = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>::create();
+    locations = Inspector::Protocol::Array<Inspector::Protocol::Debugger::Location>::create();
     if (!optionalURL == !optionalURLRegex) {
-        *errorString = ASCIILiteral("Either url or urlRegex must be specified.");
+        errorString = ASCIILiteral("Either url or urlRegex must be specified.");
         return;
     }
 
@@ -253,7 +289,7 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int li
 
     String breakpointIdentifier = (isRegex ? "/" + url + "/" : url) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
     if (m_javaScriptBreakpoints.contains(breakpointIdentifier)) {
-        *errorString = ASCIILiteral("Breakpoint at specified location already exists.");
+        errorString = ASCIILiteral("Breakpoint at specified location already exists.");
         return;
     }
 
@@ -261,9 +297,9 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int li
     bool autoContinue = false;
     RefPtr<InspectorArray> actions;
     if (options) {
-        (*options)->getString(ASCIILiteral("condition"), &condition);
-        (*options)->getBoolean(ASCIILiteral("autoContinue"), &autoContinue);
-        actions = (*options)->getArray(ASCIILiteral("actions"));
+        options->getString(ASCIILiteral("condition"), condition);
+        options->getBoolean(ASCIILiteral("autoContinue"), autoContinue);
+        options->getArray(ASCIILiteral("actions"), actions);
     }
 
     BreakpointActions breakpointActions;
@@ -278,43 +314,43 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int li
         if (!matches(scriptURL, url, isRegex))
             continue;
 
-        RefPtr<Inspector::TypeBuilder::Debugger::Location> location = resolveBreakpoint(breakpointIdentifier, it->key, breakpoint);
+        RefPtr<Inspector::Protocol::Debugger::Location> location = resolveBreakpoint(breakpointIdentifier, it->key, breakpoint);
         if (location)
-            locations->addItem(location);
+            locations->addItem(WTF::move(location));
     }
     *outBreakpointIdentifier = breakpointIdentifier;
 }
 
-static bool parseLocation(ErrorString* errorString, InspectorObject* location, JSC::SourceID* sourceID, unsigned* lineNumber, unsigned* columnNumber)
+static bool parseLocation(ErrorString& errorString, const InspectorObject& location, JSC::SourceID& sourceID, unsigned& lineNumber, unsigned& columnNumber)
 {
     String scriptIDStr;
-    if (!location->getString(ASCIILiteral("scriptId"), &scriptIDStr) || !location->getNumber(ASCIILiteral("lineNumber"), lineNumber)) {
-        *sourceID = JSC::noSourceID;
-        *errorString = ASCIILiteral("scriptId and lineNumber are required.");
+    if (!location.getString(ASCIILiteral("scriptId"), scriptIDStr) || !location.getInteger(ASCIILiteral("lineNumber"), lineNumber)) {
+        sourceID = JSC::noSourceID;
+        errorString = ASCIILiteral("scriptId and lineNumber are required.");
         return false;
     }
 
-    *sourceID = scriptIDStr.toIntPtr();
-    *columnNumber = 0;
-    location->getNumber(ASCIILiteral("columnNumber"), columnNumber);
+    sourceID = scriptIDStr.toIntPtr();
+    columnNumber = 0;
+    location.getInteger(ASCIILiteral("columnNumber"), columnNumber);
     return true;
 }
 
-void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<InspectorObject>& location, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation)
+void InspectorDebuggerAgent::setBreakpoint(ErrorString& errorString, const InspectorObject& location, const InspectorObject* options, Inspector::Protocol::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::Protocol::Debugger::Location>& actualLocation)
 {
     JSC::SourceID sourceID;
     unsigned lineNumber;
     unsigned columnNumber;
-    if (!parseLocation(errorString, location.get(), &sourceID, &lineNumber, &columnNumber))
+    if (!parseLocation(errorString, location, sourceID, lineNumber, columnNumber))
         return;
 
     String condition = emptyString();
     bool autoContinue = false;
     RefPtr<InspectorArray> actions;
     if (options) {
-        (*options)->getString(ASCIILiteral("condition"), &condition);
-        (*options)->getBoolean(ASCIILiteral("autoContinue"), &autoContinue);
-        actions = (*options)->getArray(ASCIILiteral("actions"));
+        options->getString(ASCIILiteral("condition"), condition);
+        options->getBoolean(ASCIILiteral("autoContinue"), autoContinue);
+        options->getArray(ASCIILiteral("actions"), actions);
     }
 
     BreakpointActions breakpointActions;
@@ -323,25 +359,27 @@ void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPt
 
     String breakpointIdentifier = String::number(sourceID) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
     if (m_breakpointIdentifierToDebugServerBreakpointIDs.find(breakpointIdentifier) != m_breakpointIdentifierToDebugServerBreakpointIDs.end()) {
-        *errorString = ASCIILiteral("Breakpoint at specified location already exists.");
+        errorString = ASCIILiteral("Breakpoint at specified location already exists.");
         return;
     }
 
     ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue);
     actualLocation = resolveBreakpoint(breakpointIdentifier, sourceID, breakpoint);
     if (!actualLocation) {
-        *errorString = ASCIILiteral("Could not resolve breakpoint");
+        errorString = ASCIILiteral("Could not resolve breakpoint");
         return;
     }
 
     *outBreakpointIdentifier = breakpointIdentifier;
 }
 
-void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointIdentifier)
+void InspectorDebuggerAgent::removeBreakpoint(ErrorString&, const String& breakpointIdentifier)
 {
     m_javaScriptBreakpoints.remove(breakpointIdentifier);
 
     for (JSC::BreakpointID breakpointID : m_breakpointIdentifierToDebugServerBreakpointIDs.take(breakpointIdentifier)) {
+        m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.remove(breakpointID);
+
         const BreakpointActions& breakpointActions = scriptDebugServer().getActionsForBreakpoint(breakpointID);
         for (auto& action : breakpointActions)
             m_injectedScriptManager->releaseObjectGroup(objectGroupForBreakpointAction(action));
@@ -350,7 +388,7 @@ void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakp
     }
 }
 
-void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const RefPtr<InspectorObject>& location)
+void InspectorDebuggerAgent::continueToLocation(ErrorString& errorString, const InspectorObject& location)
 {
     if (m_continueToLocationBreakpointID != JSC::noBreakpointID) {
         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointID);
@@ -360,7 +398,7 @@ void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const
     JSC::SourceID sourceID;
     unsigned lineNumber;
     unsigned columnNumber;
-    if (!parseLocation(errorString, location.get(), &sourceID, &lineNumber, &columnNumber))
+    if (!parseLocation(errorString, location, sourceID, lineNumber, columnNumber))
         return;
 
     ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", false);
@@ -368,7 +406,7 @@ void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const
     resume(errorString);
 }
 
-PassRefPtr<Inspector::TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointIdentifier, JSC::SourceID sourceID, const ScriptBreakpoint& breakpoint)
+RefPtr<Inspector::Protocol::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointIdentifier, JSC::SourceID sourceID, const ScriptBreakpoint& breakpoint)
 {
     ScriptsMap::iterator scriptIterator = m_scripts.find(sourceID);
     if (scriptIterator == m_scripts.end())
@@ -387,55 +425,59 @@ PassRefPtr<Inspector::TypeBuilder::Debugger::Location> InspectorDebuggerAgent::r
     if (debugServerBreakpointIDsIterator == m_breakpointIdentifierToDebugServerBreakpointIDs.end())
         debugServerBreakpointIDsIterator = m_breakpointIdentifierToDebugServerBreakpointIDs.set(breakpointIdentifier, Vector<JSC::BreakpointID>()).iterator;
     debugServerBreakpointIDsIterator->value.append(debugServerBreakpointID);
+    
+    m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.set(debugServerBreakpointID, breakpointIdentifier);
 
-    RefPtr<Inspector::TypeBuilder::Debugger::Location> location = Inspector::TypeBuilder::Debugger::Location::create()
+    auto location = Inspector::Protocol::Debugger::Location::create()
         .setScriptId(String::number(sourceID))
-        .setLineNumber(actualLineNumber);
+        .setLineNumber(actualLineNumber)
+        .release();
     location->setColumnNumber(actualColumnNumber);
-    return location;
+    return WTF::move(location);
 }
 
-void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& scriptIDStr, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>>& results)
+void InspectorDebuggerAgent::searchInContent(ErrorString& error, const String& scriptIDStr, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>& results)
 {
+    JSC::SourceID sourceID = scriptIDStr.toIntPtr();
+    auto it = m_scripts.find(sourceID);
+    if (it == m_scripts.end()) {
+        error = ASCIILiteral("No script for id: ") + scriptIDStr;
+        return;
+    }
+
     bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
     bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
-
-    JSC::SourceID sourceID = scriptIDStr.toIntPtr();
-    ScriptsMap::iterator it = m_scripts.find(sourceID);
-    if (it != m_scripts.end())
-        results = ContentSearchUtilities::searchInTextByLines(it->value.source, query, caseSensitive, isRegex);
-    else
-        *error = "No script for id: " + scriptIDStr;
+    results = ContentSearchUtilities::searchInTextByLines(it->value.source, query, caseSensitive, isRegex);
 }
 
-void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& scriptIDStr, String* scriptSource)
+void InspectorDebuggerAgent::getScriptSource(ErrorString& error, const String& scriptIDStr, String* scriptSource)
 {
     JSC::SourceID sourceID = scriptIDStr.toIntPtr();
     ScriptsMap::iterator it = m_scripts.find(sourceID);
     if (it != m_scripts.end())
         *scriptSource = it->value.source;
     else
-        *error = "No script for id: " + scriptIDStr;
+        error = ASCIILiteral("No script for id: ") + scriptIDStr;
 }
 
-void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<Inspector::TypeBuilder::Debugger::FunctionDetails>& details)
+void InspectorDebuggerAgent::getFunctionDetails(ErrorString& errorString, const String& functionId, RefPtr<Inspector::Protocol::Debugger::FunctionDetails>& details)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(functionId);
     if (injectedScript.hasNoValue()) {
-        *errorString = ASCIILiteral("Function object id is obsolete");
+        errorString = ASCIILiteral("Function object id is obsolete");
         return;
     }
 
     injectedScript.getFunctionDetails(errorString, functionId, &details);
 }
 
-void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorDebuggerFrontendDispatcher::Reason::Enum breakReason, PassRefPtr<InspectorObject> data)
+void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<InspectorObject>&& data)
 {
     if (m_javaScriptPauseScheduled)
         return;
 
     m_breakReason = breakReason;
-    m_breakAuxData = data;
+    m_breakAuxData = WTF::move(data);
     scriptDebugServer().setPauseOnNextStatement(true);
 }
 
@@ -448,56 +490,49 @@ void InspectorDebuggerAgent::cancelPauseOnNextStatement()
     scriptDebugServer().setPauseOnNextStatement(false);
 }
 
-void InspectorDebuggerAgent::pause(ErrorString*)
+void InspectorDebuggerAgent::pause(ErrorString&)
 {
-    if (m_javaScriptPauseScheduled)
-        return;
+    schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason::PauseOnNextStatement, nullptr);
 
-    clearBreakDetails();
-    scriptDebugServer().setPauseOnNextStatement(true);
     m_javaScriptPauseScheduled = true;
 }
 
-void InspectorDebuggerAgent::resume(ErrorString* errorString)
+void InspectorDebuggerAgent::resume(ErrorString& errorString)
 {
     if (!assertPaused(errorString))
         return;
 
-    m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
     scriptDebugServer().continueProgram();
 }
 
-void InspectorDebuggerAgent::stepOver(ErrorString* errorString)
+void InspectorDebuggerAgent::stepOver(ErrorString& errorString)
 {
     if (!assertPaused(errorString))
         return;
 
-    m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
     scriptDebugServer().stepOverStatement();
 }
 
-void InspectorDebuggerAgent::stepInto(ErrorString* errorString)
+void InspectorDebuggerAgent::stepInto(ErrorString& errorString)
 {
     if (!assertPaused(errorString))
         return;
 
-    m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
     scriptDebugServer().stepIntoStatement();
 
     if (m_listener)
         m_listener->stepInto();
 }
 
-void InspectorDebuggerAgent::stepOut(ErrorString* errorString)
+void InspectorDebuggerAgent::stepOut(ErrorString& errorString)
 {
     if (!assertPaused(errorString))
         return;
 
-    m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
     scriptDebugServer().stepOutOfFunction();
 }
 
-void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, const String& stringPauseState)
+void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString& errorString, const String& stringPauseState)
 {
     JSC::Debugger::PauseOnExceptionsState pauseState;
     if (stringPauseState == "none")
@@ -507,20 +542,20 @@ void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, cons
     else if (stringPauseState == "uncaught")
         pauseState = JSC::Debugger::PauseOnUncaughtExceptions;
     else {
-        *errorString = "Unknown pause on exceptions mode: " + stringPauseState;
+        errorString = ASCIILiteral("Unknown pause on exceptions mode: ") + stringPauseState;
         return;
     }
 
     scriptDebugServer().setPauseOnExceptionsState(static_cast<JSC::Debugger::PauseOnExceptionsState>(pauseState));
     if (scriptDebugServer().pauseOnExceptionsState() != pauseState)
-        *errorString = ASCIILiteral("Internal error. Could not change pause on exceptions state");
+        errorString = ASCIILiteral("Internal error. Could not change pause on exceptions state");
 }
 
-void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString& errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
     if (injectedScript.hasNoValue()) {
-        *errorString = ASCIILiteral("Inspected frame has gone");
+        errorString = ASCIILiteral("Inspected frame has gone");
         return;
     }
 
@@ -531,7 +566,7 @@ void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
         muteConsole();
     }
 
-    injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, &result, wasThrown);
+    injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, saveResult ? *saveResult : false, &result, wasThrown, savedResultIndex);
 
     if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) {
         unmuteConsole();
@@ -540,29 +575,21 @@ void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
     }
 }
 
-void InspectorDebuggerAgent::setOverlayMessage(ErrorString*, const String*)
+void InspectorDebuggerAgent::setOverlayMessage(ErrorString&, const String*)
 {
 }
 
 void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
 {
-    if (scriptDebugServer().pauseOnExceptionsState() != JSC::Debugger::DontPauseOnExceptions) {
-        RefPtr<InspectorObject> directive = InspectorObject::create();
-        directive->setString(ASCIILiteral("directiveText"), directiveText);
-        breakProgram(InspectorDebuggerFrontendDispatcher::Reason::CSPViolation, directive.release());
-    }
+    if (scriptDebugServer().pauseOnExceptionsState() != JSC::Debugger::DontPauseOnExceptions)
+        breakProgram(DebuggerFrontendDispatcher::Reason::CSPViolation, buildCSPViolationPauseReason(directiveText));
 }
 
-PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::CallFrame>> InspectorDebuggerAgent::currentCallFrames()
+Ref<Inspector::Protocol::Array<Inspector::Protocol::Debugger::CallFrame>> InspectorDebuggerAgent::currentCallFrames(InjectedScript injectedScript)
 {
-    if (!m_pausedScriptState)
-        return Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::CallFrame>::create();
-
-    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
-    if (injectedScript.hasNoValue()) {
-        ASSERT_NOT_REACHED();
-        return Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::CallFrame>::create();
-    }
+    ASSERT(!injectedScript.hasNoValue());
+    if (injectedScript.hasNoValue())
+        return Inspector::Protocol::Array<Inspector::Protocol::Debugger::CallFrame>::create();
 
     return injectedScript.wrapCallFrames(m_currentCallStack);
 }
@@ -593,26 +620,31 @@ void InspectorDebuggerAgent::didParseSource(JSC::SourceID sourceID, const Script
         return;
 
     for (auto it = m_javaScriptBreakpoints.begin(), end = m_javaScriptBreakpoints.end(); it != end; ++it) {
-        RefPtr<InspectorObject> breakpointObject = it->value->asObject();
+        RefPtr<InspectorObject> breakpointObject;
+        if (!it->value->asObject(breakpointObject))
+            return;
+
         bool isRegex;
-        breakpointObject->getBoolean(ASCIILiteral("isRegex"), &isRegex);
+        breakpointObject->getBoolean(ASCIILiteral("isRegex"), isRegex);
         String url;
-        breakpointObject->getString(ASCIILiteral("url"), &url);
+        breakpointObject->getString(ASCIILiteral("url"), url);
         if (!matches(scriptURL, url, isRegex))
             continue;
+
         ScriptBreakpoint breakpoint;
-        breakpointObject->getNumber(ASCIILiteral("lineNumber"), &breakpoint.lineNumber);
-        breakpointObject->getNumber(ASCIILiteral("columnNumber"), &breakpoint.columnNumber);
-        breakpointObject->getString(ASCIILiteral("condition"), &breakpoint.condition);
-        breakpointObject->getBoolean(ASCIILiteral("autoContinue"), &breakpoint.autoContinue);
+        breakpointObject->getInteger(ASCIILiteral("lineNumber"), breakpoint.lineNumber);
+        breakpointObject->getInteger(ASCIILiteral("columnNumber"), breakpoint.columnNumber);
+        breakpointObject->getString(ASCIILiteral("condition"), breakpoint.condition);
+        breakpointObject->getBoolean(ASCIILiteral("autoContinue"), breakpoint.autoContinue);
         ErrorString errorString;
-        RefPtr<InspectorArray> actions = breakpointObject->getArray(ASCIILiteral("actions"));
-        if (!breakpointActionsFromProtocol(&errorString, actions, &breakpoint.actions)) {
+        RefPtr<InspectorArray> actions;
+        breakpointObject->getArray(ASCIILiteral("actions"), actions);
+        if (!breakpointActionsFromProtocol(errorString, actions, &breakpoint.actions)) {
             ASSERT_NOT_REACHED();
             continue;
         }
 
-        RefPtr<Inspector::TypeBuilder::Debugger::Location> location = resolveBreakpoint(it->key, sourceID, breakpoint);
+        RefPtr<Inspector::Protocol::Debugger::Location> location = resolveBreakpoint(it->key, sourceID, breakpoint);
         if (location)
             m_frontendDispatcher->breakpointResolved(it->key, location);
     }
@@ -623,22 +655,53 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
     m_frontendDispatcher->scriptFailedToParse(url, data, firstLine, errorLine, errorMessage);
 }
 
-void InspectorDebuggerAgent::didPause(JSC::ExecState* scriptState, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exception)
+void InspectorDebuggerAgent::didPause(JSC::ExecState* scriptState, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exceptionOrCaughtValue)
 {
     ASSERT(scriptState && !m_pausedScriptState);
     m_pausedScriptState = scriptState;
     m_currentCallStack = callFrames;
 
-    if (!exception.hasNoValue()) {
-        InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
-        if (!injectedScript.hasNoValue()) {
-            m_breakReason = InspectorDebuggerFrontendDispatcher::Reason::Exception;
-            m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
-            // m_breakAuxData might be null after this.
+    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
+
+    // If a high level pause pause reason is not already set, try to infer a reason from the debugger.
+    if (m_breakReason == DebuggerFrontendDispatcher::Reason::Other) {
+        switch (scriptDebugServer().reasonForPause()) {
+        case JSC::Debugger::PausedForBreakpoint: {
+            JSC::BreakpointID debuggerBreakpointId = scriptDebugServer().pausingBreakpointID();
+            if (debuggerBreakpointId != m_continueToLocationBreakpointID) {
+                m_breakReason = DebuggerFrontendDispatcher::Reason::Breakpoint;
+                m_breakAuxData = buildBreakpointPauseReason(debuggerBreakpointId);
+            }
+            break;
+        }
+        case JSC::Debugger::PausedForDebuggerStatement:
+            m_breakReason = DebuggerFrontendDispatcher::Reason::DebuggerStatement;
+            m_breakAuxData = nullptr;
+            break;
+        case JSC::Debugger::PausedForException:
+            m_breakReason = DebuggerFrontendDispatcher::Reason::Exception;
+            m_breakAuxData = buildExceptionPauseReason(exceptionOrCaughtValue, injectedScript);
+            break;
+        case JSC::Debugger::PausedAtStatement:
+        case JSC::Debugger::PausedAfterCall:
+        case JSC::Debugger::PausedBeforeReturn:
+        case JSC::Debugger::PausedAtStartOfProgram:
+        case JSC::Debugger::PausedAtEndOfProgram:
+            // Pause was just stepping. Nothing to report.
+            break;
+        case JSC::Debugger::NotPaused:
+            ASSERT_NOT_REACHED();
+            break;
         }
     }
 
-    m_frontendDispatcher->paused(currentCallFrames(), m_breakReason, m_breakAuxData);
+    // Set $exception to the exception or caught value.
+    if (!exceptionOrCaughtValue.hasNoValue() && !injectedScript.hasNoValue()) {
+        injectedScript.setExceptionValue(exceptionOrCaughtValue);
+        m_hasExceptionValue = true;
+    }
+
+    m_frontendDispatcher->paused(currentCallFrames(injectedScript), m_breakReason, m_breakAuxData);
     m_javaScriptPauseScheduled = false;
 
     if (m_continueToLocationBreakpointID != JSC::noBreakpointID) {
@@ -648,6 +711,12 @@ void InspectorDebuggerAgent::didPause(JSC::ExecState* scriptState, const Depreca
 
     if (m_listener)
         m_listener->didPause();
+
+    RefPtr<Stopwatch> stopwatch = m_injectedScriptManager->inspectorEnvironment().executionStopwatch();
+    if (stopwatch && stopwatch->isActive()) {
+        stopwatch->stop();
+        m_didPauseStopwatch = true;
+    }
 }
 
 void InspectorDebuggerAgent::breakpointActionSound(int breakpointActionIdentifier)
@@ -655,35 +724,41 @@ void InspectorDebuggerAgent::breakpointActionSound(int breakpointActionIdentifie
     m_frontendDispatcher->playBreakpointActionSound(breakpointActionIdentifier);
 }
 
-void InspectorDebuggerAgent::breakpointActionProbe(JSC::ExecState* scriptState, const ScriptBreakpointAction& action, int hitCount, const Deprecated::ScriptValue& sample)
+void InspectorDebuggerAgent::breakpointActionProbe(JSC::ExecState* scriptState, const ScriptBreakpointAction& action, unsigned batchId, unsigned sampleId, const Deprecated::ScriptValue& sample)
 {
-    int sampleId = m_nextProbeSampleId++;
-
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
-    RefPtr<TypeBuilder::Runtime::RemoteObject> payload = injectedScript.wrapObject(sample, objectGroupForBreakpointAction(action));
-    RefPtr<TypeBuilder::Debugger::ProbeSample> result = TypeBuilder::Debugger::ProbeSample::create()
+    RefPtr<Protocol::Runtime::RemoteObject> payload = injectedScript.wrapObject(sample, objectGroupForBreakpointAction(action), true);
+    auto result = Protocol::Debugger::ProbeSample::create()
         .setProbeId(action.identifier)
+        .setBatchId(batchId)
         .setSampleId(sampleId)
-        .setBatchId(hitCount)
-        .setTimestamp(monotonicallyIncreasingTime())
-        .setPayload(payload.release());
+        .setTimestamp(m_injectedScriptManager->inspectorEnvironment().executionStopwatch()->elapsedTime())
+        .setPayload(payload.release())
+        .release();
 
-    m_frontendDispatcher->didSampleProbe(result.release());
+    m_frontendDispatcher->didSampleProbe(WTF::move(result));
 }
 
 void InspectorDebuggerAgent::didContinue()
 {
+    if (m_didPauseStopwatch) {
+        m_didPauseStopwatch = false;
+        m_injectedScriptManager->inspectorEnvironment().executionStopwatch()->start();
+    }
+
     m_pausedScriptState = nullptr;
     m_currentCallStack = Deprecated::ScriptValue();
+    m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
     clearBreakDetails();
+    clearExceptionValue();
 
     m_frontendDispatcher->resumed();
 }
 
-void InspectorDebuggerAgent::breakProgram(InspectorDebuggerFrontendDispatcher::Reason::Enum breakReason, PassRefPtr<InspectorObject> data)
+void InspectorDebuggerAgent::breakProgram(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<InspectorObject>&& data)
 {
     m_breakReason = breakReason;
-    m_breakAuxData = data;
+    m_breakAuxData = WTF::move(data);
     scriptDebugServer().breakProgram();
 }
 
@@ -693,7 +768,7 @@ void InspectorDebuggerAgent::clearInspectorBreakpointState()
     Vector<String> breakpointIdentifiers;
     copyKeysToVector(m_breakpointIdentifierToDebugServerBreakpointIDs, breakpointIdentifiers);
     for (const String& identifier : breakpointIdentifiers)
-        removeBreakpoint(&dummyError, identifier);
+        removeBreakpoint(dummyError, identifier);
 
     m_javaScriptBreakpoints.clear();
 
@@ -708,9 +783,11 @@ void InspectorDebuggerAgent::clearDebuggerBreakpointState()
     m_currentCallStack = Deprecated::ScriptValue();
     m_scripts.clear();
     m_breakpointIdentifierToDebugServerBreakpointIDs.clear();
+    m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.clear();
     m_continueToLocationBreakpointID = JSC::noBreakpointID;
     clearBreakDetails();
     m_javaScriptPauseScheduled = false;
+    m_hasExceptionValue = false;
 
     scriptDebugServer().continueProgram();
 }
@@ -725,10 +802,10 @@ void InspectorDebuggerAgent::didClearGlobalObject()
         m_frontendDispatcher->globalObjectCleared();
 }
 
-bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
+bool InspectorDebuggerAgent::assertPaused(ErrorString& errorString)
 {
     if (!m_pausedScriptState) {
-        *errorString = ASCIILiteral("Can only perform operation while paused.");
+        errorString = ASCIILiteral("Can only perform operation while paused.");
         return false;
     }
 
@@ -737,11 +814,16 @@ bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
 
 void InspectorDebuggerAgent::clearBreakDetails()
 {
-    m_breakReason = InspectorDebuggerFrontendDispatcher::Reason::Other;
+    m_breakReason = DebuggerFrontendDispatcher::Reason::Other;
     m_breakAuxData = nullptr;
 }
 
+void InspectorDebuggerAgent::clearExceptionValue()
+{
+    if (m_hasExceptionValue) {
+        m_injectedScriptManager->clearExceptionValue();
+        m_hasExceptionValue = false;
+    }
+}
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index eb2270a9ce242813f9d4ee55900ff83a996f406b..28249e2762d04f2f17346341d7f4ae60255e2060 100644 (file)
 #ifndef InspectorDebuggerAgent_h
 #define InspectorDebuggerAgent_h
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSBackendDispatchers.h"
-#include "InspectorJSFrontendDispatchers.h"
+#include "InspectorBackendDispatchers.h"
+#include "InspectorFrontendDispatchers.h"
 #include "bindings/ScriptValue.h"
 #include "debugger/Debugger.h"
 #include "inspector/InspectorAgentBase.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/PassRefPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/text/StringHash.h>
 
+namespace WTF {
+class Stopwatch;
+}
+
 namespace Inspector {
 
 class InjectedScript;
@@ -57,7 +57,7 @@ class InspectorValue;
 class ScriptDebugServer;
 typedef String ErrorString;
 
-class JS_EXPORT_PRIVATE InspectorDebuggerAgent : public InspectorAgentBase, public ScriptDebugListener, public InspectorDebuggerBackendDispatcherHandler {
+class JS_EXPORT_PRIVATE InspectorDebuggerAgent : public InspectorAgentBase, public ScriptDebugListener, public DebuggerBackendDispatcherHandler {
     WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent);
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -65,35 +65,35 @@ public:
 
     virtual ~InspectorDebuggerAgent();
 
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) override;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason) override;
-
-    virtual void enable(ErrorString*) override;
-    virtual void disable(ErrorString*) override;
-    virtual void setBreakpointsActive(ErrorString*, bool active) override;
-    virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations) override;
-    virtual void setBreakpoint(ErrorString*, const RefPtr<Inspector::InspectorObject>& location, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation) override;
-    virtual void removeBreakpoint(ErrorString*, const String& breakpointIdentifier) override;
-    virtual void continueToLocation(ErrorString*, const RefPtr<InspectorObject>& location) override;
-    virtual void searchInContent(ErrorString*, const String& scriptID, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>>&) override;
-    virtual void getScriptSource(ErrorString*, const String& scriptID, String* scriptSource) override;
-    virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<Inspector::TypeBuilder::Debugger::FunctionDetails>&) override;
-    virtual void pause(ErrorString*) override;
-    virtual void resume(ErrorString*) override;
-    virtual void stepOver(ErrorString*) override;
-    virtual void stepInto(ErrorString*) override;
-    virtual void stepOut(ErrorString*) override;
-    virtual void setPauseOnExceptions(ErrorString*, const String& pauseState) override;
-    virtual void evaluateOnCallFrame(ErrorString*, const String& callFrameId, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown) override;
-    virtual void setOverlayMessage(ErrorString*, const String*) override;
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*) override;
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
+
+    virtual void enable(ErrorString&) override;
+    virtual void disable(ErrorString&) override;
+    virtual void setBreakpointsActive(ErrorString&, bool active) override;
+    virtual void setBreakpointByUrl(ErrorString&, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const Inspector::InspectorObject* options, Inspector::Protocol::Debugger::BreakpointId*, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Debugger::Location>>& locations) override;
+    virtual void setBreakpoint(ErrorString&, const Inspector::InspectorObject& location, const Inspector::InspectorObject* options, Inspector::Protocol::Debugger::BreakpointId*, RefPtr<Inspector::Protocol::Debugger::Location>& actualLocation) override;
+    virtual void removeBreakpoint(ErrorString&, const String& breakpointIdentifier) override;
+    virtual void continueToLocation(ErrorString&, const InspectorObject& location) override;
+    virtual void searchInContent(ErrorString&, const String& scriptID, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>&) override;
+    virtual void getScriptSource(ErrorString&, const String& scriptID, String* scriptSource) override;
+    virtual void getFunctionDetails(ErrorString&, const String& functionId, RefPtr<Inspector::Protocol::Debugger::FunctionDetails>&) override;
+    virtual void pause(ErrorString&) override;
+    virtual void resume(ErrorString&) override;
+    virtual void stepOver(ErrorString&) override;
+    virtual void stepInto(ErrorString&) override;
+    virtual void stepOut(ErrorString&) override;
+    virtual void setPauseOnExceptions(ErrorString&, const String& pauseState) override;
+    virtual void evaluateOnCallFrame(ErrorString&, const String& callFrameId, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) override;
+    virtual void setOverlayMessage(ErrorString&, const String*) override;
 
     bool isPaused();
     
-    void handleConsoleAssert();
+    void handleConsoleAssert(const String& message);
 
-    void schedulePauseOnNextStatement(InspectorDebuggerFrontendDispatcher::Reason::Enum breakReason, PassRefPtr<InspectorObject> data);
+    void schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<InspectorObject>&& data);
     void cancelPauseOnNextStatement();
-    void breakProgram(InspectorDebuggerFrontendDispatcher::Reason::Enum breakReason, PassRefPtr<InspectorObject> data);
+    void breakProgram(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<InspectorObject>&& data);
     void scriptExecutionBlockedByCSP(const String& directiveText);
 
     class Listener {
@@ -112,7 +112,7 @@ protected:
     InspectorDebuggerAgent(InjectedScriptManager*);
 
     InjectedScriptManager* injectedScriptManager() const { return m_injectedScriptManager; }
-    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
+    virtual InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) = 0;
 
     virtual void startListeningScriptDebugServer() = 0;
     virtual void stopListeningScriptDebugServer(bool skipRecompile) = 0;
@@ -121,7 +121,7 @@ protected:
 
     virtual void enable();
     virtual void disable(bool skipRecompile);
-    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exception) override;
+    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exceptionOrCaughtValue) override;
     virtual void didContinue() override;
 
     virtual String sourceMapURLForScript(const Script&);
@@ -129,45 +129,51 @@ protected:
     void didClearGlobalObject();
 
 private:
-    PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::CallFrame>> currentCallFrames();
+    Ref<Inspector::Protocol::Array<Inspector::Protocol::Debugger::CallFrame>> currentCallFrames(InjectedScript);
 
     virtual void didParseSource(JSC::SourceID, const Script&) override final;
     virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) override final;
 
     virtual void breakpointActionSound(int breakpointActionIdentifier) override;
-    virtual void breakpointActionProbe(JSC::ExecState*, const ScriptBreakpointAction&, int hitCount, const Deprecated::ScriptValue& sample) override final;
+    virtual void breakpointActionProbe(JSC::ExecState*, const ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, const Deprecated::ScriptValue& sample) override final;
 
-    PassRefPtr<Inspector::TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointIdentifier, JSC::SourceID, const ScriptBreakpoint&);
-    bool assertPaused(ErrorString*);
+    RefPtr<Inspector::Protocol::Debugger::Location> resolveBreakpoint(const String& breakpointIdentifier, JSC::SourceID, const ScriptBreakpoint&);
+    bool assertPaused(ErrorString&);
     void clearDebuggerBreakpointState();
     void clearInspectorBreakpointState();
     void clearBreakDetails();
+    void clearExceptionValue();
 
-    bool breakpointActionsFromProtocol(ErrorString*, RefPtr<InspectorArray>& actions, BreakpointActions* result);
+    RefPtr<InspectorObject> buildBreakpointPauseReason(JSC::BreakpointID);
+    RefPtr<InspectorObject> buildExceptionPauseReason(const Deprecated::ScriptValue& exception, const InjectedScript&);
+
+    bool breakpointActionsFromProtocol(ErrorString&, RefPtr<InspectorArray>& actions, BreakpointActions* result);
 
     typedef HashMap<JSC::SourceID, Script> ScriptsMap;
     typedef HashMap<String, Vector<JSC::BreakpointID>> BreakpointIdentifierToDebugServerBreakpointIDsMap;
     typedef HashMap<String, RefPtr<InspectorObject>> BreakpointIdentifierToBreakpointMap;
+    typedef HashMap<JSC::BreakpointID, String> DebugServerBreakpointIDToBreakpointIdentifier;
 
     InjectedScriptManager* m_injectedScriptManager;
-    std::unique_ptr<InspectorDebuggerFrontendDispatcher> m_frontendDispatcher;
-    RefPtr<InspectorDebuggerBackendDispatcher> m_backendDispatcher;
-    Listener* m_listener;
-    JSC::ExecState* m_pausedScriptState;
+    std::unique_ptr<DebuggerFrontendDispatcher> m_frontendDispatcher;
+    RefPtr<DebuggerBackendDispatcher> m_backendDispatcher;
+    Listener* m_listener {nullptr};
+    JSC::ExecState* m_pausedScriptState {nullptr};
     Deprecated::ScriptValue m_currentCallStack;
     ScriptsMap m_scripts;
     BreakpointIdentifierToDebugServerBreakpointIDsMap m_breakpointIdentifierToDebugServerBreakpointIDs;
     BreakpointIdentifierToBreakpointMap m_javaScriptBreakpoints;
+    DebugServerBreakpointIDToBreakpointIdentifier m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier;
     JSC::BreakpointID m_continueToLocationBreakpointID;
-    InspectorDebuggerFrontendDispatcher::Reason::Enum m_breakReason;
+    DebuggerFrontendDispatcher::Reason m_breakReason;
     RefPtr<InspectorObject> m_breakAuxData;
-    bool m_enabled;
-    bool m_javaScriptPauseScheduled;
-    int m_nextProbeSampleId;
+    bool m_enabled {false};
+    bool m_javaScriptPauseScheduled {false};
+    bool m_hasExceptionValue {false};
+    bool m_didPauseStopwatch {false};
+    RefPtr<WTF::Stopwatch> m_stopwatch;
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(InspectorDebuggerAgent_h)
diff --git a/inspector/agents/InspectorProfilerAgent.cpp b/inspector/agents/InspectorProfilerAgent.cpp
deleted file mode 100644 (file)
index 82d59a0..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InspectorProfilerAgent.h"
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorValues.h"
-#include "LegacyProfiler.h"
-#include "Profile.h"
-#include "ScriptDebugServer.h"
-#include "ScriptObject.h"
-#include <wtf/CurrentTime.h>
-#include <wtf/text/StringConcatenate.h>
-
-namespace Inspector {
-
-static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
-static const char* const CPUProfileType = "CPU";
-
-InspectorProfilerAgent::InspectorProfilerAgent()
-    : InspectorAgentBase(ASCIILiteral("Profiler"))
-    , m_scriptDebugServer(nullptr)
-    , m_enabled(false)
-    , m_profileHeadersRequested(false)
-    , m_recordingProfileCount(0)
-    , m_nextUserInitiatedProfileNumber(1)
-{
-}
-
-InspectorProfilerAgent::~InspectorProfilerAgent()
-{
-}
-
-void InspectorProfilerAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
-{
-    m_frontendDispatcher = std::make_unique<InspectorProfilerFrontendDispatcher>(frontendChannel);
-    m_backendDispatcher = InspectorProfilerBackendDispatcher::create(backendDispatcher, this);
-}
-
-void InspectorProfilerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
-{
-    m_frontendDispatcher = nullptr;
-    m_backendDispatcher.clear();
-
-    reset();
-
-    disable(reason == InspectorDisconnectReason::InspectedTargetDestroyed ? SkipRecompile : Recompile);
-}
-
-void InspectorProfilerAgent::addProfile(PassRefPtr<JSC::Profile> prpProfile)
-{
-    RefPtr<JSC::Profile> profile = prpProfile;
-    m_profiles.add(profile->uid(), profile);
-
-    if (m_frontendDispatcher && m_profileHeadersRequested)
-        m_frontendDispatcher->addProfileHeader(createProfileHeader(*profile));
-}
-
-PassRefPtr<TypeBuilder::Profiler::ProfileHeader> InspectorProfilerAgent::createProfileHeader(const JSC::Profile& profile)
-{
-    return TypeBuilder::Profiler::ProfileHeader::create()
-        .setTypeId(TypeBuilder::Profiler::ProfileHeader::TypeId::CPU)
-        .setUid(profile.uid())
-        .setTitle(profile.title())
-        .release();
-}
-
-void InspectorProfilerAgent::enable(ErrorString*)
-{
-    enable(Recompile);
-}
-
-void InspectorProfilerAgent::disable(ErrorString*)
-{
-    disable(Recompile);
-}
-
-void InspectorProfilerAgent::enable(ShouldRecompile shouldRecompile)
-{
-    if (m_enabled)
-        return;
-
-    m_enabled = true;
-
-    if (shouldRecompile == Recompile)
-        m_scriptDebugServer->recompileAllJSFunctions();
-}
-
-void InspectorProfilerAgent::disable(ShouldRecompile shouldRecompile)
-{
-    if (!m_enabled)
-        return;
-
-    m_enabled = false;
-    m_profileHeadersRequested = false;
-
-    if (shouldRecompile == Recompile)
-        m_scriptDebugServer->recompileAllJSFunctions();
-}
-
-String InspectorProfilerAgent::getUserInitiatedProfileName()
-{
-    return makeString(UserInitiatedProfileName, '.', String::number(m_nextUserInitiatedProfileNumber++));
-}
-
-void InspectorProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::ProfileHeader>>& headers)
-{
-    m_profileHeadersRequested = true;
-    headers = TypeBuilder::Array<TypeBuilder::Profiler::ProfileHeader>::create();
-
-    for (auto& profile : m_profiles.values())
-        headers->addItem(createProfileHeader(*profile.get()));
-}
-
-static PassRefPtr<TypeBuilder::Profiler::CPUProfileNodeCall> buildInspectorObject(const JSC::ProfileNode::Call& call)
-{
-    RefPtr<TypeBuilder::Profiler::CPUProfileNodeCall> result = TypeBuilder::Profiler::CPUProfileNodeCall::create()
-        .setStartTime(call.startTime())
-        .setTotalTime(call.totalTime());
-    return result.release();
-}
-
-static PassRefPtr<TypeBuilder::Profiler::CPUProfileNode> buildInspectorObject(const JSC::ProfileNode* node)
-{
-    RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNodeCall>> calls = TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNodeCall>::create();
-    for (const JSC::ProfileNode::Call& call : node->calls())
-        calls->addItem(buildInspectorObject(call));
-
-    RefPtr<TypeBuilder::Profiler::CPUProfileNode> result = TypeBuilder::Profiler::CPUProfileNode::create()
-        .setId(node->id())
-        .setCalls(calls.release());
-
-    if (!node->functionName().isEmpty())
-        result->setFunctionName(node->functionName());
-
-    if (!node->url().isEmpty()) {
-        result->setUrl(node->url());
-        result->setLineNumber(node->lineNumber());
-        result->setColumnNumber(node->columnNumber());
-    }
-
-    if (!node->children().isEmpty()) {
-        RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>> children = TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>::create();
-        for (RefPtr<JSC::ProfileNode> profileNode : node->children())
-            children->addItem(buildInspectorObject(profileNode.get()));
-        result->setChildren(children);
-    }
-
-    return result.release();
-}
-
-PassRefPtr<TypeBuilder::Profiler::CPUProfile> InspectorProfilerAgent::buildProfileInspectorObject(const JSC::Profile* profile)
-{
-    RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>> rootNodes = TypeBuilder::Array<TypeBuilder::Profiler::CPUProfileNode>::create();
-    for (RefPtr<JSC::ProfileNode> profileNode : profile->head()->children())
-        rootNodes->addItem(buildInspectorObject(profileNode.get()));
-
-    RefPtr<TypeBuilder::Profiler::CPUProfile> result = TypeBuilder::Profiler::CPUProfile::create()
-        .setRootNodes(rootNodes);
-
-    if (profile->idleTime())
-        result->setIdleTime(profile->idleTime());
-
-    return result.release();
-}
-
-void InspectorProfilerAgent::getCPUProfile(ErrorString* errorString, int rawUid, RefPtr<TypeBuilder::Profiler::CPUProfile>& profileObject)
-{
-    unsigned uid = static_cast<unsigned>(rawUid);
-    auto it = m_profiles.find(uid);
-    if (it == m_profiles.end()) {
-        *errorString = ASCIILiteral("Profile wasn't found");
-        return;
-    }
-
-    profileObject = buildProfileInspectorObject(it->value.get());
-}
-
-void InspectorProfilerAgent::removeProfile(ErrorString*, const String& type, int rawUid)
-{
-    unsigned uid = static_cast<unsigned>(rawUid);
-    if (type == CPUProfileType)
-        m_profiles.remove(uid);
-}
-
-void InspectorProfilerAgent::reset()
-{
-    stop();
-
-    m_profiles.clear();
-    m_nextUserInitiatedProfileNumber = 1;
-    m_profileHeadersRequested = false;
-
-    if (m_frontendDispatcher && m_profileHeadersRequested)
-        m_frontendDispatcher->resetProfiles();
-}
-
-void InspectorProfilerAgent::start(ErrorString*)
-{
-    startProfiling();
-}
-
-void InspectorProfilerAgent::stop(ErrorString*)
-{
-    stopProfiling();
-}
-
-void InspectorProfilerAgent::setRecordingProfile(bool isProfiling)
-{
-    if (m_frontendDispatcher)
-        m_frontendDispatcher->setRecordingProfile(isProfiling);
-}
-
-String InspectorProfilerAgent::startProfiling(const String &title, JSC::ExecState* exec)
-{
-    if (!enabled())
-        enable(Recompile);
-
-    bool wasNotRecording = !m_recordingProfileCount;
-    ++m_recordingProfileCount;
-
-    String resolvedTitle = title;
-    if (title.isEmpty())
-        resolvedTitle = getUserInitiatedProfileName();
-
-    if (!exec)
-        exec = profilingGlobalExecState();
-    ASSERT(exec);
-
-    JSC::LegacyProfiler::profiler()->startProfiling(exec, resolvedTitle);
-
-    if (wasNotRecording)
-        setRecordingProfile(true);
-
-    return resolvedTitle;
-}
-
-PassRefPtr<JSC::Profile> InspectorProfilerAgent::stopProfiling(const String& title, JSC::ExecState* exec)
-{
-    if (!m_recordingProfileCount)
-        return nullptr;
-
-    --m_recordingProfileCount;
-
-    if (!exec)
-        exec = profilingGlobalExecState();
-    ASSERT(exec);
-
-    RefPtr<JSC::Profile> profile = JSC::LegacyProfiler::profiler()->stopProfiling(exec, title);
-    if (profile)
-        addProfile(profile);
-
-    if (!m_recordingProfileCount)
-        setRecordingProfile(false);
-
-    return profile.release();
-}
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
diff --git a/inspector/agents/InspectorProfilerAgent.h b/inspector/agents/InspectorProfilerAgent.h
deleted file mode 100644 (file)
index 5e00fc1..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorProfilerAgent_h
-#define InspectorProfilerAgent_h
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSBackendDispatchers.h"
-#include "InspectorJSFrontendDispatchers.h"
-#include "inspector/InspectorAgentBase.h"
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-class ExecState;
-class Profile;
-}
-
-namespace Inspector {
-
-class ScriptDebugServer;
-
-typedef String ErrorString;
-
-class JS_EXPORT_PRIVATE InspectorProfilerAgent : public InspectorAgentBase, public InspectorProfilerBackendDispatcherHandler {
-    WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    virtual ~InspectorProfilerAgent();
-
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) override final;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason) override final;
-
-    virtual void enable(ErrorString*) override final;
-    virtual void disable(ErrorString*) override final;
-
-    virtual void start(ErrorString* = nullptr) override final;
-    virtual void stop(ErrorString* = nullptr) override final;
-
-    virtual void clearProfiles(ErrorString*) override final { reset(); }
-
-    virtual void getProfileHeaders(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::ProfileHeader>>&) override final;
-    virtual void getCPUProfile(ErrorString*, int uid, RefPtr<TypeBuilder::Profiler::CPUProfile>&) override final;
-    virtual void removeProfile(ErrorString*, const String& type, int uid) override final;
-
-    static PassRefPtr<TypeBuilder::Profiler::CPUProfile> buildProfileInspectorObject(const JSC::Profile*);
-
-    enum ShouldRecompile { SkipRecompile, Recompile };
-
-    virtual void enable(ShouldRecompile);
-    virtual void disable(ShouldRecompile);
-
-    bool enabled() const { return m_enabled; }
-
-    void reset();
-
-    void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
-
-    String startProfiling(const String& title = String(), JSC::ExecState* = nullptr);
-    PassRefPtr<JSC::Profile> stopProfiling(const String& title = String(), JSC::ExecState* = nullptr);
-
-protected:
-    InspectorProfilerAgent();
-
-    virtual JSC::ExecState* profilingGlobalExecState() const = 0;
-
-private:
-    void addProfile(PassRefPtr<JSC::Profile>);
-
-    void setRecordingProfile(bool isProfiling);
-
-    String getUserInitiatedProfileName();
-
-    PassRefPtr<TypeBuilder::Profiler::ProfileHeader> createProfileHeader(const JSC::Profile&);
-
-    std::unique_ptr<InspectorProfilerFrontendDispatcher> m_frontendDispatcher;
-    RefPtr<InspectorProfilerBackendDispatcher> m_backendDispatcher;
-    HashMap<unsigned, RefPtr<JSC::Profile>> m_profiles;
-    ScriptDebugServer* m_scriptDebugServer;
-    bool m_enabled;
-    bool m_profileHeadersRequested;
-    unsigned m_recordingProfileCount;
-    unsigned m_nextUserInitiatedProfileNumber;
-};
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // !defined(InspectorProfilerAgent_h)
index ac65979350c1330fd3b32f323a6a87c3c3344738..e3ec8623c844a81546011e39bbe2c6a0ada71996 100644 (file)
@@ -32,9 +32,8 @@
 #include "config.h"
 #include "InspectorRuntimeAgent.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "Completion.h"
+#include "HeapIterationScope.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
 #include "InspectorValues.h"
 #include "ParserError.h"
 #include "ScriptDebugServer.h"
 #include "SourceCode.h"
-#include <wtf/PassRefPtr.h>
+#include "TypeProfiler.h"
+#include "TypeProfilerLog.h"
+#include "VMEntryScope.h"
+#include <wtf/CurrentTime.h>
 
 using namespace JSC;
 
@@ -58,6 +60,7 @@ InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScri
     , m_injectedScriptManager(injectedScriptManager)
     , m_scriptDebugServer(nullptr)
     , m_enabled(false)
+    , m_isTypeProfilingEnabled(false)
 {
 }
 
@@ -74,15 +77,15 @@ static ScriptDebugServer::PauseOnExceptionsState setPauseOnExceptionsState(Scrip
     return presentState;
 }
 
-static PassRefPtr<Inspector::TypeBuilder::Runtime::ErrorRange> buildErrorRangeObject(const JSTokenLocation& tokenLocation)
+static Ref<Inspector::Protocol::Runtime::ErrorRange> buildErrorRangeObject(const JSTokenLocation& tokenLocation)
 {
-    RefPtr<Inspector::TypeBuilder::Runtime::ErrorRange> result = Inspector::TypeBuilder::Runtime::ErrorRange::create()
+    return Inspector::Protocol::Runtime::ErrorRange::create()
         .setStartOffset(tokenLocation.startOffset)
-        .setEndOffset(tokenLocation.endOffset);
-    return result.release();
+        .setEndOffset(tokenLocation.endOffset)
+        .release();
 }
 
-void InspectorRuntimeAgent::parse(ErrorString*, const String& expression, Inspector::TypeBuilder::Runtime::SyntaxErrorType::Enum* result, Inspector::TypeBuilder::OptOutput<String>* message, RefPtr<Inspector::TypeBuilder::Runtime::ErrorRange>& range)
+void InspectorRuntimeAgent::parse(ErrorString&, const String& expression, Inspector::Protocol::Runtime::SyntaxErrorType* result, Inspector::Protocol::OptOutput<String>* message, RefPtr<Inspector::Protocol::Runtime::ErrorRange>& range)
 {
     VM& vm = globalVM();
     JSLockHolder lock(vm);
@@ -90,28 +93,28 @@ void InspectorRuntimeAgent::parse(ErrorString*, const String& expression, Inspec
     ParserError error;
     checkSyntax(vm, JSC::makeSource(expression), error);
 
-    switch (error.m_syntaxErrorType) {
+    switch (error.syntaxErrorType()) {
     case ParserError::SyntaxErrorNone:
-        *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::None;
+        *result = Inspector::Protocol::Runtime::SyntaxErrorType::None;
         break;
     case ParserError::SyntaxErrorIrrecoverable:
-        *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::Irrecoverable;
+        *result = Inspector::Protocol::Runtime::SyntaxErrorType::Irrecoverable;
         break;
     case ParserError::SyntaxErrorUnterminatedLiteral:
-        *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::UnterminatedLiteral;
+        *result = Inspector::Protocol::Runtime::SyntaxErrorType::UnterminatedLiteral;
         break;
     case ParserError::SyntaxErrorRecoverable:
-        *result = Inspector::TypeBuilder::Runtime::SyntaxErrorType::Recoverable;
+        *result = Inspector::Protocol::Runtime::SyntaxErrorType::Recoverable;
         break;
     }
 
-    if (error.m_syntaxErrorType != ParserError::SyntaxErrorNone) {
-        *message = error.m_message;
-        range = buildErrorRangeObject(error.m_token.m_location);
+    if (error.syntaxErrorType() != ParserError::SyntaxErrorNone) {
+        *message = error.message();
+        range = buildErrorRangeObject(error.token().m_location);
     }
 }
 
-void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* const returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorRuntimeAgent::evaluate(ErrorString& errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* const returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex)
 {
     InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
     if (injectedScript.hasNoValue())
@@ -123,7 +126,7 @@ void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& exp
     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
         muteConsole();
 
-    injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI), asBool(returnByValue), asBool(generatePreview), &result, wasThrown);
+    injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : String(), asBool(includeCommandLineAPI), asBool(returnByValue), asBool(generatePreview), asBool(saveResult), &result, wasThrown, savedResultIndex);
 
     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
         unmuteConsole();
@@ -131,17 +134,17 @@ void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& exp
     }
 }
 
-void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<InspectorArray>* const optionalArguments, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorRuntimeAgent::callFunctionOn(ErrorString& errorString, const String& objectId, const String& expression, const InspectorArray* optionalArguments, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     if (injectedScript.hasNoValue()) {
-        *errorString = ASCIILiteral("Inspected frame has gone");
+        errorString = ASCIILiteral("Inspected frame has gone");
         return;
     }
 
     String arguments;
     if (optionalArguments)
-        arguments = (*optionalArguments)->toJSONString();
+        arguments = optionalArguments->toJSONString();
 
     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;
     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
@@ -157,40 +160,243 @@ void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const Strin
     }
 }
 
-void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, const bool* const ownProperties, const bool* const ownAndGetterProperties, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>>& internalProperties)
+void InspectorRuntimeAgent::getProperties(ErrorString& errorString, const String& objectId, const bool* const ownProperties, const bool* const generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties)
+{
+    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
+    if (injectedScript.hasNoValue()) {
+        errorString = ASCIILiteral("Inspected frame has gone");
+        return;
+    }
+
+    ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
+    muteConsole();
+
+    injectedScript.getProperties(errorString, objectId, asBool(ownProperties), asBool(generatePreview), &result);
+    injectedScript.getInternalProperties(errorString, objectId, asBool(generatePreview), &internalProperties);
+
+    unmuteConsole();
+    setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
+}
+
+void InspectorRuntimeAgent::getDisplayableProperties(ErrorString& errorString, const String& objectId, const bool* const generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     if (injectedScript.hasNoValue()) {
-        *errorString = ASCIILiteral("Inspected frame has gone");
+        errorString = ASCIILiteral("Inspected frame has gone");
         return;
     }
 
     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
     muteConsole();
 
-    injectedScript.getProperties(errorString, objectId, ownProperties ? *ownProperties : false, ownAndGetterProperties ? *ownAndGetterProperties : false, &result);
-    injectedScript.getInternalProperties(errorString, objectId, &internalProperties);
+    injectedScript.getDisplayableProperties(errorString, objectId, asBool(generatePreview), &result);
+    injectedScript.getInternalProperties(errorString, objectId, asBool(generatePreview), &internalProperties);
 
     unmuteConsole();
     setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
 }
 
-void InspectorRuntimeAgent::releaseObject(ErrorString*, const String& objectId)
+void InspectorRuntimeAgent::getCollectionEntries(ErrorString& errorString, const String& objectId, const String* objectGroup, const int* startIndex, const int* numberToFetch, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::CollectionEntry>>& entries)
+{
+    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
+    if (injectedScript.hasNoValue()) {
+        errorString = ASCIILiteral("Inspected frame has gone");
+        return;
+    }
+
+    int start = startIndex && *startIndex >= 0 ? *startIndex : 0;
+    int fetch = numberToFetch && *numberToFetch >= 0 ? *numberToFetch : 0;
+
+    injectedScript.getCollectionEntries(errorString, objectId, objectGroup ? *objectGroup : String(), start, fetch, &entries);
+}
+
+void InspectorRuntimeAgent::saveResult(ErrorString& errorString, const Inspector::InspectorObject& callArgument, const int* executionContextId, Inspector::Protocol::OptOutput<int>* savedResultIndex)
+{
+    InjectedScript injectedScript;
+
+    String objectId;
+    if (callArgument.getString(ASCIILiteral("objectId"), objectId)) {
+        injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
+        if (injectedScript.hasNoValue()) {
+            errorString = ASCIILiteral("Inspected frame has gone");
+            return;
+        }
+    } else {
+        injectedScript = injectedScriptForEval(errorString, executionContextId);
+        if (injectedScript.hasNoValue())
+            return;
+    }
+
+    injectedScript.saveResult(errorString, callArgument.toJSONString(), savedResultIndex);
+}
+
+void InspectorRuntimeAgent::releaseObject(ErrorString&, const String& objectId)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     if (!injectedScript.hasNoValue())
         injectedScript.releaseObject(objectId);
 }
 
-void InspectorRuntimeAgent::releaseObjectGroup(ErrorString*, const String& objectGroup)
+void InspectorRuntimeAgent::releaseObjectGroup(ErrorString&, const String& objectGroup)
 {
     m_injectedScriptManager->releaseObjectGroup(objectGroup);
 }
 
-void InspectorRuntimeAgent::run(ErrorString*)
+void InspectorRuntimeAgent::run(ErrorString&)
 {
+    // FIXME: <https://webkit.org/b/127634> Web Inspector: support debugging web workers
 }
 
-} // namespace Inspector
+void InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets(ErrorString& errorString, const Inspector::InspectorArray& locations, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>>& typeDescriptions)
+{
+    static const bool verbose = false;
+    VM& vm = globalVM();
+    typeDescriptions = Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>::create();
+    if (!vm.typeProfiler()) {
+        errorString = ASCIILiteral("The VM does not currently have Type Information.");
+        return;
+    }
+
+    double start = currentTimeMS();
+    vm.typeProfilerLog()->processLogEntries(ASCIILiteral("User Query"));
+
+    for (size_t i = 0; i < locations.length(); i++) {
+        RefPtr<Inspector::InspectorValue> value = locations.get(i);
+        RefPtr<InspectorObject> location;
+        if (!value->asObject(location)) {
+            errorString = ASCIILiteral("Array of TypeLocation objects has an object that does not have type of TypeLocation.");
+            return;
+        }
+
+        int descriptor;
+        String sourceIDAsString;
+        int divot;
+        location->getInteger(ASCIILiteral("typeInformationDescriptor"), descriptor);
+        location->getString(ASCIILiteral("sourceID"), sourceIDAsString);
+        location->getInteger(ASCIILiteral("divot"), divot);
+
+        bool okay;
+        TypeLocation* typeLocation = vm.typeProfiler()->findLocation(divot, sourceIDAsString.toIntPtrStrict(&okay), static_cast<TypeProfilerSearchDescriptor>(descriptor), vm);
+        ASSERT(okay);
+
+        RefPtr<TypeSet> typeSet;
+        if (typeLocation) {
+            if (typeLocation->m_globalTypeSet && typeLocation->m_globalVariableID != TypeProfilerNoGlobalIDExists)
+                typeSet = typeLocation->m_globalTypeSet;
+            else
+                typeSet = typeLocation->m_instructionTypeSet;
+        }
+
+        bool isValid = typeLocation && typeSet && !typeSet->isEmpty();
+        auto description = Inspector::Protocol::Runtime::TypeDescription::create()
+            .setIsValid(isValid)
+            .release();
+
+        if (isValid) {
+            description->setLeastCommonAncestor(typeSet->leastCommonAncestor());
+            description->setStructures(typeSet->allStructureRepresentations());
+            description->setTypeSet(typeSet->inspectorTypeSet());
+            description->setIsTruncated(typeSet->isOverflown());
+        }
+
+        typeDescriptions->addItem(WTF::move(description));
+    }
 
-#endif // ENABLE(INSPECTOR)
+    double end = currentTimeMS();
+    if (verbose)
+        dataLogF("Inspector::getRuntimeTypesForVariablesAtOffsets took %lfms\n", end - start);
+}
+
+class TypeRecompiler : public MarkedBlock::VoidFunctor {
+public:
+    inline void visit(JSCell* cell)
+    {
+        if (!cell->inherits(FunctionExecutable::info()))
+            return;
+
+        FunctionExecutable* executable = jsCast<FunctionExecutable*>(cell);
+        executable->clearCode();
+        executable->clearUnlinkedCodeForRecompilation();
+    }
+    inline IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
+    }
+};
+
+static void recompileAllJSFunctionsForTypeProfiling(VM& vm, bool shouldEnableTypeProfiling)
+{
+    bool shouldRecompileFromTypeProfiler = (shouldEnableTypeProfiling ? vm.enableTypeProfiler() : vm.disableTypeProfiler());
+    bool shouldRecompileFromControlFlowProfiler = (shouldEnableTypeProfiling ? vm.enableControlFlowProfiler() : vm.disableControlFlowProfiler());
+    bool needsToRecompile = shouldRecompileFromTypeProfiler || shouldRecompileFromControlFlowProfiler;
+
+    if (needsToRecompile) {
+        vm.prepareToDiscardCode();
+        TypeRecompiler recompiler;
+        HeapIterationScope iterationScope(vm.heap);
+        vm.heap.objectSpace().forEachLiveCell(iterationScope, recompiler);
+    }
+}
+
+void InspectorRuntimeAgent::willDestroyFrontendAndBackend(DisconnectReason reason)
+{
+    if (reason != DisconnectReason::InspectedTargetDestroyed && m_isTypeProfilingEnabled)
+        setTypeProfilerEnabledState(false);
+}
+
+void InspectorRuntimeAgent::enableTypeProfiler(ErrorString&)
+{
+    setTypeProfilerEnabledState(true);
+}
+
+void InspectorRuntimeAgent::disableTypeProfiler(ErrorString&)
+{
+    setTypeProfilerEnabledState(false);
+}
+
+void InspectorRuntimeAgent::setTypeProfilerEnabledState(bool shouldEnableTypeProfiling)
+{
+    if (m_isTypeProfilingEnabled == shouldEnableTypeProfiling)
+        return;
+
+    m_isTypeProfilingEnabled = shouldEnableTypeProfiling;
+
+    VM& vm = globalVM();
+
+    // If JavaScript is running, it's not safe to recompile, since we'll end
+    // up throwing away code that is live on the stack.
+    if (vm.entryScope) {
+        vm.entryScope->setEntryScopeDidPopListener(this,
+            [=] (VM& vm, JSGlobalObject*) {
+                recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling);
+            }
+        );
+    } else
+        recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling);
+}
+
+void InspectorRuntimeAgent::getBasicBlocks(ErrorString& errorString, const String& sourceIDAsString, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>>& basicBlocks)
+{
+    VM& vm = globalVM();
+    if (!vm.controlFlowProfiler()) {
+        errorString = ASCIILiteral("The VM does not currently have a Control Flow Profiler.");
+        return;
+    }
+
+    bool okay;
+    intptr_t sourceID = sourceIDAsString.toIntPtrStrict(&okay);
+    ASSERT(okay);
+    const Vector<BasicBlockRange>& basicBlockRanges = vm.controlFlowProfiler()->getBasicBlocksForSourceID(sourceID, vm);
+    basicBlocks = Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>::create();
+    for (const BasicBlockRange& block : basicBlockRanges) {
+        Ref<Inspector::Protocol::Runtime::BasicBlock> location = Inspector::Protocol::Runtime::BasicBlock::create()
+            .setStartOffset(block.m_startOffset)
+            .setEndOffset(block.m_endOffset)
+            .setHasExecuted(block.m_hasExecuted)
+            .release();
+        basicBlocks->addItem(WTF::move(location));
+    }
+}
+
+} // namespace Inspector
index faf43788aa2cc36365b6e0cf3dd74eaa34813ab1..25f3d7c14aacc0557240b7b176bcf3c3c5a9b213 100644 (file)
 #ifndef InspectorRuntimeAgent_h
 #define InspectorRuntimeAgent_h
 
-#if ENABLE(INSPECTOR)
-
-#include "InspectorJSBackendDispatchers.h"
-#include "InspectorJSFrontendDispatchers.h"
+#include "InspectorBackendDispatchers.h"
+#include "InspectorFrontendDispatchers.h"
 #include "inspector/InspectorAgentBase.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
@@ -52,21 +50,30 @@ class InspectorArray;
 class ScriptDebugServer;
 typedef String ErrorString;
 
-class JS_EXPORT_PRIVATE InspectorRuntimeAgent : public InspectorAgentBase, public InspectorRuntimeBackendDispatcherHandler {
+class JS_EXPORT_PRIVATE InspectorRuntimeAgent : public InspectorAgentBase, public RuntimeBackendDispatcherHandler {
     WTF_MAKE_NONCOPYABLE(InspectorRuntimeAgent);
 public:
     virtual ~InspectorRuntimeAgent();
 
-    virtual void enable(ErrorString*) override { m_enabled = true; }
-    virtual void disable(ErrorString*) override { m_enabled = false; }
-    virtual void parse(ErrorString*, const String& expression, Inspector::TypeBuilder::Runtime::SyntaxErrorType::Enum* result, Inspector::TypeBuilder::OptOutput<String>* message, RefPtr<Inspector::TypeBuilder::Runtime::ErrorRange>&) override final;
-    virtual void evaluate(ErrorString*, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown) override final;
-    virtual void callFunctionOn(ErrorString*, const String& objectId, const String& expression, const RefPtr<Inspector::InspectorArray>* optionalArguments, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result, Inspector::TypeBuilder::OptOutput<bool>* wasThrown) override final;
-    virtual void releaseObject(ErrorString*, const ErrorString& objectId) override final;
-    virtual void getProperties(ErrorString*, const String& objectId, const bool* ownProperties, const bool* const ownAndGetterProperties, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
-    virtual void releaseObjectGroup(ErrorString*, const String& objectGroup) override final;
-    virtual void run(ErrorString*) override;
-
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
+
+    virtual void enable(ErrorString&) override { m_enabled = true; }
+    virtual void disable(ErrorString&) override { m_enabled = false; }
+    virtual void parse(ErrorString&, const String& expression, Inspector::Protocol::Runtime::SyntaxErrorType* result, Inspector::Protocol::OptOutput<String>* message, RefPtr<Inspector::Protocol::Runtime::ErrorRange>&) override final;
+    virtual void evaluate(ErrorString&, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) override final;
+    virtual void callFunctionOn(ErrorString&, const String& objectId, const String& expression, const Inspector::InspectorArray* optionalArguments, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown) override final;
+    virtual void releaseObject(ErrorString&, const ErrorString& objectId) override final;
+    virtual void getProperties(ErrorString&, const String& objectId, const bool* ownProperties, const bool* generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
+    virtual void getDisplayableProperties(ErrorString&, const String& objectId, const bool* generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
+    virtual void getCollectionEntries(ErrorString&, const String& objectId, const String* objectGroup, const int* startIndex, const int* numberToFetch, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::CollectionEntry>>& entries) override final;
+    virtual void saveResult(ErrorString&, const Inspector::InspectorObject& callArgument, const int* executionContextId, Inspector::Protocol::OptOutput<int>* savedResultIndex) override final;
+    virtual void releaseObjectGroup(ErrorString&, const String& objectGroup) override final;
+    virtual void run(ErrorString&) override;
+    virtual void getRuntimeTypesForVariablesAtOffsets(ErrorString&, const Inspector::InspectorArray& locations, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::TypeDescription>>&) override;
+    virtual void enableTypeProfiler(ErrorString&) override;
+    virtual void disableTypeProfiler(ErrorString&) override;
+    virtual void getBasicBlocks(ErrorString&, const String& in_sourceID, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::BasicBlock>>& out_basicBlocks) override;
+    
     void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
 
     bool enabled() const { return m_enabled; }
@@ -77,18 +84,20 @@ protected:
     InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
 
     virtual JSC::VM& globalVM() = 0;
-    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
+    virtual InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) = 0;
 
     virtual void muteConsole() = 0;
     virtual void unmuteConsole() = 0;
 
 private:
+    void setTypeProfilerEnabledState(bool);
+
     InjectedScriptManager* m_injectedScriptManager;
     ScriptDebugServer* m_scriptDebugServer;
     bool m_enabled;
+    bool m_isTypeProfilingEnabled;
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
 #endif // InspectorRuntimeAgent_h
index fad5075fc66370deac7b2df134f54f1a82a2a1b0..fe112dd1eae8caece23cab8c031b06e643909fea 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSGlobalObjectConsoleAgent.h"
 
-#if ENABLE(INSPECTOR)
-
 namespace Inspector {
 
 JSGlobalObjectConsoleAgent::JSGlobalObjectConsoleAgent(InjectedScriptManager* injectedScriptManager)
@@ -35,16 +33,14 @@ JSGlobalObjectConsoleAgent::JSGlobalObjectConsoleAgent(InjectedScriptManager* in
 {
 }
 
-void JSGlobalObjectConsoleAgent::setMonitoringXHREnabled(ErrorString* errorString, bool)
+void JSGlobalObjectConsoleAgent::setMonitoringXHREnabled(ErrorString& errorString, bool)
 {
-    *errorString = ASCIILiteral("Not supported for JavaScript context");
+    errorString = ASCIILiteral("Not supported for JavaScript context");
 }
 
-void JSGlobalObjectConsoleAgent::addInspectedNode(ErrorString* errorString, int)
+void JSGlobalObjectConsoleAgent::addInspectedNode(ErrorString& errorString, int)
 {
-    *errorString = ASCIILiteral("Not supported for JavaScript context");
+    errorString = ASCIILiteral("Not supported for JavaScript context");
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 7aa48de411d9c5f6c4fd8da9b04200705ffc8396..0d79c5d1bf1bbee76b9abb853f993c1aac065a49 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSGlobalObjectConsoleAgent_h
 #define JSGlobalObjectConsoleAgent_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorConsoleAgent.h"
 #include "JSGlobalObjectScriptDebugServer.h"
 
@@ -41,14 +39,12 @@ public:
     virtual ~JSGlobalObjectConsoleAgent() { }
 
     // FIXME: XHRs and Nodes only makes sense debugging a Web context. Can this be moved to a different agent?
-    virtual void setMonitoringXHREnabled(ErrorString*, bool enabled) override;
-    virtual void addInspectedNode(ErrorString*, int nodeId) override;
+    virtual void setMonitoringXHREnabled(ErrorString&, bool enabled) override;
+    virtual void addInspectedNode(ErrorString&, int nodeId) override;
 
     virtual bool isWorkerAgent() const override { return false; }
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSGlobalObjectConsoleAgent_h)
index c087e81e97cc41e8eef4f14a2958ade825e42fb0..9ae76c62a6c9c5ab03c70915d2d231d8ff673de9 100644 (file)
@@ -26,8 +26,7 @@
 #include "config.h"
 #include "JSGlobalObjectDebuggerAgent.h"
 
-#if ENABLE(INSPECTOR)
-
+#include "ConsoleMessage.h"
 #include "InjectedScriptManager.h"
 #include "InspectorConsoleAgent.h"
 #include "JSGlobalObject.h"
@@ -56,10 +55,10 @@ void JSGlobalObjectDebuggerAgent::stopListeningScriptDebugServer(bool isBeingDes
     scriptDebugServer().removeListener(this, isBeingDestroyed);
 }
 
-InjectedScript JSGlobalObjectDebuggerAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId)
+InjectedScript JSGlobalObjectDebuggerAgent::injectedScriptForEval(ErrorString& error, const int* executionContextId)
 {
     if (executionContextId) {
-        *error = ASCIILiteral("Execution context id is not supported for JSContext inspection as there is only one execution context.");
+        error = ASCIILiteral("Execution context id is not supported for JSContext inspection as there is only one execution context.");
         return InjectedScript();
     }
 
@@ -69,9 +68,7 @@ InjectedScript JSGlobalObjectDebuggerAgent::injectedScriptForEval(ErrorString* e
 
 void JSGlobalObjectDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String& message)
 {
-    m_consoleAgent->addMessageToConsole(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture), 0);
+    m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(exec, ScriptCallStack::maxCallStackSizeToCapture), 0));
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 27ee6ace125d3cf635defb03aea6f04b4482d08b..ac6b87169f475a282b6010ecbd019b352d75580e 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JSGlobalObjectDebuggerAgent_h
 #define JSGlobalObjectDebuggerAgent_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorDebuggerAgent.h"
 #include "JSGlobalObjectScriptDebugServer.h"
 
@@ -46,7 +44,7 @@ public:
 
     virtual void startListeningScriptDebugServer() override;
     virtual void stopListeningScriptDebugServer(bool isBeingDestroyed) override;
-    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override;
+    virtual InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override;
 
     virtual void breakpointActionLog(JSC::ExecState*, const String&) override;
 
@@ -62,6 +60,4 @@ private:
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSGlobalObjectDebuggerAgent_h)
diff --git a/inspector/agents/JSGlobalObjectProfilerAgent.cpp b/inspector/agents/JSGlobalObjectProfilerAgent.cpp
deleted file mode 100644 (file)
index 8026b9a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSGlobalObjectProfilerAgent.h"
-
-#if ENABLE(INSPECTOR)
-
-#include "JSGlobalObject.h"
-
-using namespace JSC;
-
-namespace Inspector {
-
-JSGlobalObjectProfilerAgent::JSGlobalObjectProfilerAgent(JSGlobalObject& globalObject)
-    : InspectorProfilerAgent()
-    , m_globalObject(globalObject)
-{
-}
-
-ExecState* JSGlobalObjectProfilerAgent::profilingGlobalExecState() const
-{
-    return m_globalObject.globalExec();
-}
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
diff --git a/inspector/agents/JSGlobalObjectProfilerAgent.h b/inspector/agents/JSGlobalObjectProfilerAgent.h
deleted file mode 100644 (file)
index 51906a9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSGlobalObjectProfilerAgent_h
-#define JSGlobalObjectProfilerAgent_h
-
-#if ENABLE(INSPECTOR)
-
-#include "InspectorProfilerAgent.h"
-
-namespace JSC {
-class JSGlobalObject;
-}
-
-namespace Inspector {
-
-class JSGlobalObjectProfilerAgent final : public InspectorProfilerAgent {
-public:
-    JSGlobalObjectProfilerAgent(JSC::JSGlobalObject&);
-
-private:
-    virtual JSC::ExecState* profilingGlobalExecState() const override;
-
-    JSC::JSGlobalObject& m_globalObject;
-};
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // !defined(JSGlobalObjectProfilerAgent_h)
index 126189e312762011ccde003c107e1e9a8c16c8a6..46049f56c75ad7398f3c9d075846ce7a1c128268 100644 (file)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSGlobalObjectRuntimeAgent.h"
 
-#if ENABLE(INSPECTOR)
-
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
 #include "JSGlobalObject.h"
@@ -42,16 +40,18 @@ JSGlobalObjectRuntimeAgent::JSGlobalObjectRuntimeAgent(InjectedScriptManager* in
 {
 }
 
-void JSGlobalObjectRuntimeAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+void JSGlobalObjectRuntimeAgent::didCreateFrontendAndBackend(FrontendChannel* frontendChannel, BackendDispatcher* backendDispatcher)
 {
-    m_frontendDispatcher = std::make_unique<InspectorRuntimeFrontendDispatcher>(frontendChannel);
-    m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this);
+    m_frontendDispatcher = std::make_unique<RuntimeFrontendDispatcher>(frontendChannel);
+    m_backendDispatcher = RuntimeBackendDispatcher::create(backendDispatcher, this);
 }
 
-void JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
+void JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend(DisconnectReason reason)
 {
     m_frontendDispatcher = nullptr;
-    m_backendDispatcher.clear();
+    m_backendDispatcher = nullptr;
+
+    InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason);
 }
 
 VM& JSGlobalObjectRuntimeAgent::globalVM()
@@ -59,18 +59,16 @@ VM& JSGlobalObjectRuntimeAgent::globalVM()
     return m_globalObject.vm();
 }
 
-InjectedScript JSGlobalObjectRuntimeAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
+InjectedScript JSGlobalObjectRuntimeAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId)
 {
     ASSERT_UNUSED(executionContextId, !executionContextId);
 
     JSC::ExecState* scriptState = m_globalObject.globalExec();
     InjectedScript injectedScript = injectedScriptManager()->injectedScriptFor(scriptState);
     if (injectedScript.hasNoValue())
-        *errorString = ASCIILiteral("Internal error: main world execution context not found.");
+        errorString = ASCIILiteral("Internal error: main world execution context not found.");
 
     return injectedScript;
 }
 
 } // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
index 0e72e09b278c67c70a306d2a4f5bbd6fa9f40d6b..631baec0eb33db9e089b5ccc1391b9580a7ff4e8 100644 (file)
 #ifndef JSGlobalObjectRuntimeAgent_h
 #define JSGlobalObjectRuntimeAgent_h
 
-#if ENABLE(INSPECTOR)
-
 #include "InspectorRuntimeAgent.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 class JSGlobalObject;
@@ -41,11 +38,11 @@ class JSGlobalObjectRuntimeAgent final : public InspectorRuntimeAgent {
 public:
     JSGlobalObjectRuntimeAgent(InjectedScriptManager*, JSC::JSGlobalObject&);
 
-    virtual void didCreateFrontendAndBackend(InspectorFrontendChannel*, InspectorBackendDispatcher*) override;
-    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason) override;
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher*) override;
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
 
     virtual JSC::VM& globalVM() override;
-    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override;
+    virtual InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override;
 
     // NOTE: JavaScript inspector does not yet need to mute a console because no messages
     // are sent to the console outside of the API boundary or console object.
@@ -53,13 +50,11 @@ public:
     virtual void unmuteConsole() override { }
 
 private:
-    std::unique_ptr<InspectorRuntimeFrontendDispatcher> m_frontendDispatcher;
-    RefPtr<InspectorRuntimeBackendDispatcher> m_backendDispatcher;
+    std::unique_ptr<RuntimeFrontendDispatcher> m_frontendDispatcher;
+    RefPtr<RuntimeBackendDispatcher> m_backendDispatcher;
     JSC::JSGlobalObject& m_globalObject;
 };
 
 } // namespace Inspector
 
-#endif // ENABLE(INSPECTOR)
-
 #endif // !defined(JSGlobalObjectRuntimeAgent_h)
diff --git a/inspector/augmentable/AlternateDispatchableAgent.h b/inspector/augmentable/AlternateDispatchableAgent.h
new file mode 100644 (file)
index 0000000..5ff0353
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AlternateDispatchableAgent_h
+#define AlternateDispatchableAgent_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorAlternateBackendDispatchers.h"
+#include "InspectorBackendDispatchers.h"
+#include <JavaScriptCore/InspectorAgentBase.h>
+#include <wtf/Forward.h>
+
+namespace Inspector {
+
+template<typename TBackendDispatcher, typename TAlternateDispatcher>
+class AlternateDispatchableAgent final : public InspectorAgentBase {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    AlternateDispatchableAgent(const String& domainName, std::unique_ptr<TAlternateDispatcher> alternateDispatcher)
+        : InspectorAgentBase(domainName)
+        , m_alternateDispatcher(WTF::move(alternateDispatcher))
+    {
+    }
+
+    virtual void didCreateFrontendAndBackend(FrontendChannel*, BackendDispatcher* backendDispatcher) override
+    {
+        m_backendDispatcher = TBackendDispatcher::create(backendDispatcher, nullptr);
+        m_backendDispatcher->setAlternateDispatcher(m_alternateDispatcher.get());
+        m_alternateDispatcher->setBackendDispatcher(backendDispatcher);
+    }
+
+    virtual void willDestroyFrontendAndBackend(DisconnectReason) override
+    {
+        m_backendDispatcher = nullptr;
+        m_alternateDispatcher->setBackendDispatcher(nullptr);
+    }
+
+private:
+    std::unique_ptr<TAlternateDispatcher> m_alternateDispatcher;
+    RefPtr<TBackendDispatcher> m_backendDispatcher;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // AlternateDispatchableAgent_h
diff --git a/inspector/augmentable/AugmentableInspectorController.h b/inspector/augmentable/AugmentableInspectorController.h
new file mode 100644 (file)
index 0000000..2456ac5
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AugmentableInspectorController_h
+#define AugmentableInspectorController_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include <JavaScriptCore/AugmentableInspectorControllerClient.h>
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+
+namespace Inspector {
+
+class InspectorAgentBase;
+
+class AugmentableInspectorController {
+public:
+    virtual ~AugmentableInspectorController() { }
+
+    virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const = 0;
+    virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient*) = 0;
+
+    virtual FrontendChannel* frontendChannel() const = 0;
+    virtual void appendExtraAgent(std::unique_ptr<InspectorAgentBase>) = 0;
+
+    bool connected() const { return !!frontendChannel(); }
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(AugmentableInspectorController_h)
diff --git a/inspector/augmentable/AugmentableInspectorControllerClient.h b/inspector/augmentable/AugmentableInspectorControllerClient.h
new file mode 100644 (file)
index 0000000..fef1cf9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AugmentableInspectorControllerClient_h
+#define AugmentableInspectorControllerClient_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+namespace Inspector {
+
+class AugmentableInspectorControllerClient {
+public:
+    virtual ~AugmentableInspectorControllerClient() { }
+    virtual void inspectorConnected() = 0;
+    virtual void inspectorDisconnected() = 0;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(AugmentableInspectorControllerClient_h)
diff --git a/inspector/protocol/ApplicationCache.json b/inspector/protocol/ApplicationCache.json
new file mode 100644 (file)
index 0000000..86a984a
--- /dev/null
@@ -0,0 +1,87 @@
+{
+    "domain": "ApplicationCache",
+    "availability": "web",
+    "types": [
+        {
+            "id": "ApplicationCacheResource",
+            "type": "object",
+            "description": "Detailed application cache resource information.",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Resource url." },
+                { "name": "size", "type": "integer", "description": "Resource size." },
+                { "name": "type", "type": "string", "description": "Resource type." }
+            ]
+        },
+        {
+            "id": "ApplicationCache",
+            "type": "object",
+            "description": "Detailed application cache information.",
+            "properties": [
+                { "name": "manifestURL", "type": "string", "description": "Manifest URL." },
+                { "name": "size", "type": "number", "description": "Application cache size." },
+                { "name": "creationTime", "type": "number", "description": "Application cache creation time." },
+                { "name": "updateTime", "type": "number", "description": "Application cache update time." },
+                { "name": "resources", "type": "array", "items": { "$ref": "ApplicationCacheResource" }, "description": "Application cache resources." }
+            ]
+        },
+        {
+            "id": "FrameWithManifest",
+            "type": "object",
+            "description": "Frame identifier - manifest URL pair.",
+            "properties": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame identifier." },
+                { "name": "manifestURL", "type": "string", "description": "Manifest URL." },
+                { "name": "status", "type": "integer", "description": "Application cache status." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "getFramesWithManifests",
+            "returns": [
+                { "name": "frameIds", "type": "array", "items": { "$ref": "FrameWithManifest" }, "description": "Array of frame identifiers with manifest urls for each frame containing a document associated with some application cache." }
+            ],
+            "description": "Returns array of frame identifiers with manifest urls for each frame containing a document associated with some application cache."
+        },
+        {
+            "name": "enable",
+            "description": "Enables application cache domain notifications."
+        },
+        {
+            "name": "getManifestForFrame",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose manifest is retrieved." }
+            ],
+            "returns": [
+                { "name": "manifestURL", "type": "string", "description": "Manifest URL for document in the given frame." }
+            ],
+            "description": "Returns manifest URL for document in the given frame."
+        },
+        {
+            "name": "getApplicationCacheForFrame",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose application cache is retrieved." }
+            ],
+            "returns": [
+                { "name": "applicationCache", "$ref": "ApplicationCache", "description": "Relevant application cache data for the document in given frame." }
+            ],
+            "description": "Returns relevant application cache data for the document in given frame."
+        }
+    ],
+    "events": [
+        {
+            "name": "applicationCacheStatusUpdated",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose application cache updated status." },
+                { "name": "manifestURL", "type": "string", "description": "Manifest URL." },
+                { "name": "status", "type": "integer", "description": "Updated application cache status." }
+            ]
+        },
+        {
+            "name": "networkStateUpdated",
+            "parameters": [
+                { "name": "isNowOnline", "type": "boolean" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/protocol/CSS.json b/inspector/protocol/CSS.json
new file mode 100644 (file)
index 0000000..f02216d
--- /dev/null
@@ -0,0 +1,423 @@
+{
+    "domain": "CSS",
+    "description": "This domain exposes CSS read/write operations. All CSS objects, like stylesheets, rules, and styles, have an associated <code>id</code> used in subsequent operations on the related object. Each object type has a specific <code>id</code> structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the <code>get*ForNode()</code> calls (which accept a DOM node id). Alternatively, a client can discover all the existing stylesheets with the <code>getAllStyleSheets()</code> method and subsequently load the required stylesheet contents using the <code>getStyleSheet[Text]()</code> methods.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "StyleSheetId",
+            "type": "string"
+        },
+        {
+            "id": "CSSStyleId",
+            "type": "object",
+            "properties": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "Enclosing stylesheet identifier." },
+                { "name": "ordinal", "type": "integer", "description": "The style ordinal within the stylesheet." }
+            ],
+            "description": "This object identifies a CSS style in a unique way."
+        },
+        {
+            "id": "StyleSheetOrigin",
+            "type": "string",
+            "enum": ["user", "user-agent", "inspector", "regular"],
+            "description": "Stylesheet type: \"user\" for user stylesheets, \"user-agent\" for user-agent stylesheets, \"inspector\" for stylesheets created by the inspector (i.e. those holding the \"via inspector\" rules), \"regular\" for regular stylesheets."
+        },
+        {
+            "id": "CSSRuleId",
+            "type": "object",
+            "properties": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "Enclosing stylesheet identifier." },
+                { "name": "ordinal", "type": "integer", "description": "The rule ordinal within the stylesheet." }
+            ],
+            "description": "This object identifies a CSS rule in a unique way."
+        },
+        {
+            "id": "PseudoIdMatches",
+            "type": "object",
+            "properties": [
+                { "name": "pseudoId", "type": "integer", "description": "Pseudo style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."},
+                { "name": "matches", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules applicable to the pseudo style."}
+            ],
+            "description": "CSS rule collection for a single pseudo style."
+        },
+        {
+            "id": "InheritedStyleEntry",
+            "type": "object",
+            "properties": [
+                { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "The ancestor node's inline style, if any, in the style inheritance chain." },
+                { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules matching the ancestor node in the style inheritance chain." }
+            ],
+            "description": "CSS rule collection for a single pseudo style."
+        },
+        {
+            "id": "RuleMatch",
+            "type": "object",
+            "properties": [
+                { "name": "rule", "$ref": "CSSRule", "description": "CSS rule in the match." },
+                { "name": "matchingSelectors", "type": "array", "items": { "type": "integer" }, "description": "Matching selector indices in the rule's selectorList selectors (0-based)." }
+            ],
+            "description": "Match data for a CSS rule."
+        },
+        {
+            "id": "CSSSelector",
+            "type": "object",
+            "properties": [
+                { "name": "text", "type": "string", "description": "Canonicalized selector text." },
+                { "name": "specificity", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Specificity (a, b, c) tuple. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element." },
+                { "name": "dynamic", "optional": true, "type": "boolean", "description": "Whether or not the specificity can be dynamic. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element." }
+            ],
+            "description": "CSS selector."
+        },
+        {
+            "id": "SelectorList",
+            "type": "object",
+            "properties": [
+                { "name": "selectors", "type": "array", "items": { "$ref": "CSSSelector" }, "description": "Selectors in the list." },
+                { "name": "text", "type": "string", "description": "Rule selector text." },
+                { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Rule selector range in the underlying resource (if available)." }
+            ],
+            "description": "Selector list data."
+        },
+        {
+            "id": "CSSStyleAttribute",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "DOM attribute name (e.g. \"width\")."},
+                { "name": "style", "$ref": "CSSStyle", "description": "CSS style generated by the respective DOM attribute."}
+            ],
+            "description": "CSS style information for a DOM style attribute."
+        },
+        {
+            "id": "CSSStyleSheetHeader",
+            "type": "object",
+            "properties": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "The stylesheet identifier."},
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Owner frame identifier."},
+                { "name": "sourceURL", "type": "string", "description": "Stylesheet resource URL."},
+                { "name": "origin", "$ref": "StyleSheetOrigin", "description": "Stylesheet origin."},
+                { "name": "title", "type": "string", "description": "Stylesheet title."},
+                { "name": "disabled", "type": "boolean", "description": "Denotes whether the stylesheet is disabled."}
+            ],
+            "description": "CSS stylesheet metainformation."
+        },
+        {
+            "id": "CSSStyleSheetBody",
+            "type": "object",
+            "properties": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "The stylesheet identifier."},
+                { "name": "rules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "Stylesheet resource URL."},
+                { "name": "text", "type": "string", "optional": true, "description": "Stylesheet resource contents (if available)."}
+            ],
+            "description": "CSS stylesheet contents."
+        },
+        {
+            "id": "CSSRule",
+            "type": "object",
+            "properties": [
+                { "name": "ruleId", "$ref": "CSSRuleId", "optional": true, "description": "The CSS rule identifier (absent for user agent stylesheet and user-specified stylesheet rules)."},
+                { "name": "selectorList", "$ref": "SelectorList", "description": "Rule selector data." },
+                { "name": "sourceURL", "type": "string", "optional": true, "description": "Parent stylesheet resource URL (for regular rules)."},
+                { "name": "sourceLine", "type": "integer", "description": "Line ordinal of the rule selector start character in the resource."},
+                { "name": "origin", "$ref": "StyleSheetOrigin", "description": "Parent stylesheet's origin."},
+                { "name": "style", "$ref": "CSSStyle", "description": "Associated style declaration." },
+                { "name": "media", "type": "array", "items": { "$ref": "CSSMedia" }, "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards." }
+            ],
+            "description": "CSS rule representation."
+        },
+        {
+            "id": "SourceRange",
+            "type": "object",
+            "properties": [
+                { "name": "startLine", "type": "integer", "description": "Start line of range." },
+                { "name": "startColumn", "type": "integer", "description": "Start column of range (inclusive)." },
+                { "name": "endLine", "type": "integer", "description": "End line of range" },
+                { "name": "endColumn", "type": "integer", "description": "End column of range (exclusive)." }
+            ],
+            "description": "Text range within a resource."
+        },
+        {
+            "id": "ShorthandEntry",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Shorthand name." },
+                { "name": "value", "type": "string", "description": "Shorthand value." }
+            ]
+        },
+        {
+            "id": "CSSPropertyInfo",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Property name." },
+                { "name": "longhands", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Longhand property names." },
+                { "name": "values", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Supported values for this property." }
+            ]
+        },
+        {
+            "id": "CSSComputedStyleProperty",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Computed style property name." },
+                { "name": "value", "type": "string", "description": "Computed style property value." }
+            ]
+        },
+        {
+            "id": "CSSStyle",
+            "type": "object",
+            "properties": [
+                { "name": "styleId", "$ref": "CSSStyleId", "optional": true, "description": "The CSS style identifier (absent for attribute styles)." },
+                { "name": "cssProperties", "type": "array", "items": { "$ref": "CSSProperty" }, "description": "CSS properties in the style." },
+                { "name": "shorthandEntries", "type": "array", "items": { "$ref": "ShorthandEntry" }, "description": "Computed values for all shorthands found in the style." },
+                { "name": "cssText", "type": "string", "optional": true, "description": "Style declaration text (if available)." },
+                { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Style declaration range in the enclosing stylesheet (if available)." },
+                { "name": "width", "type": "string", "optional": true, "description": "The effective \"width\" property value from this style." },
+                { "name": "height", "type": "string", "optional": true, "description": "The effective \"height\" property value from this style." }
+            ],
+            "description": "CSS style representation."
+        },
+        {
+            "id": "CSSPropertyStatus",
+           "type": "string",
+            "enum": ["active", "inactive", "disabled", "style"],
+            "description": "The property status: \"active\" if the property is effective in the style, \"inactive\" if the property is overridden by a same-named property in this style later on, \"disabled\" if the property is disabled by the user, \"style\" (implied if absent) if the property is reported by the browser rather than by the CSS source parser."
+        },
+        {
+            "id": "CSSProperty",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "The property name." },
+                { "name": "value", "type": "string", "description": "The property value." },
+                { "name": "priority", "type": "string", "optional": true, "description": "The property priority (implies \"\" if absent)." },
+                { "name": "implicit", "type": "boolean", "optional": true, "description": "Whether the property is implicit (implies <code>false</code> if absent)." },
+                { "name": "text", "type": "string", "optional": true, "description": "The full property text as specified in the style." },
+                { "name": "parsedOk", "type": "boolean", "optional": true, "description": "Whether the property is understood by the browser (implies <code>true</code> if absent)." },
+                { "name": "status", "$ref": "CSSPropertyStatus", "optional": true, "description": "Whether the property is active or disabled." },
+                { "name": "range", "$ref": "SourceRange", "optional": true, "description": "The entire property range in the enclosing style declaration (if available)." }
+            ],
+            "description": "CSS style effective visual dimensions and source offsets."
+        },
+        {
+            "id": "CSSMedia",
+            "type": "object",
+            "properties": [
+                { "name": "text", "type": "string", "description": "Media query text." },
+                { "name": "source", "type": "string", "enum": ["mediaRule", "importRule", "linkedSheet", "inlineSheet"], "description": "Source of the media query: \"mediaRule\" if specified by a @media rule, \"importRule\" if specified by an @import rule, \"linkedSheet\" if specified by a \"media\" attribute in a linked stylesheet's LINK tag, \"inlineSheet\" if specified by a \"media\" attribute in an inline stylesheet's STYLE tag." },
+                { "name": "sourceURL", "type": "string", "optional": true, "description": "URL of the document containing the media query description." },
+                { "name": "sourceLine", "type": "integer", "optional": true, "description": "Line in the document containing the media query (not defined for the \"stylesheet\" source)." }
+            ],
+            "description": "CSS media query descriptor."
+        },
+        {
+            "id": "Region",
+            "type": "object",
+            "properties": [
+                { "name": "regionOverset", "type": "string", "enum": ["overset", "fit", "empty"], "description": "The \"overset\" attribute of a Named Flow." },
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The corresponding DOM node id." }
+            ],
+            "description": "This object represents a region that flows from a Named Flow."
+        },
+        {
+            "id": "NamedFlow",
+            "type": "object",
+            "properties": [
+                { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." },
+                { "name": "name", "type": "string", "description": "Named Flow identifier." },
+                { "name": "overset", "type": "boolean", "description": "The \"overset\" attribute of a Named Flow." },
+                { "name": "content", "type": "array", "items": { "$ref": "DOM.NodeId" }, "description": "An array of nodes that flow into the Named Flow." },
+                { "name": "regions", "type": "array", "items": { "$ref": "Region" }, "description": "An array of regions associated with the Named Flow." }
+            ],
+            "description": "This object represents a Named Flow."
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been enabled until the result of this command is received."
+        },
+        {
+            "name": "disable",
+            "description": "Disables the CSS agent for the given page."
+        },
+        {
+            "name": "getMatchedStylesForNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId" },
+                { "name": "includePseudo", "type": "boolean", "optional": true, "description": "Whether to include pseudo styles (default: true)." },
+                { "name": "includeInherited", "type": "boolean", "optional": true, "description": "Whether to include inherited styles (default: true)." }
+            ],
+            "returns": [
+                { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "optional": true, "description": "CSS rules matching this node, from all applicable stylesheets." },
+                { "name": "pseudoElements", "type": "array", "items": { "$ref": "PseudoIdMatches" }, "optional": true, "description": "Pseudo style matches for this node." },
+                { "name": "inherited", "type": "array", "items": { "$ref": "InheritedStyleEntry" }, "optional": true, "description": "A chain of inherited styles (from the immediate node parent up to the DOM tree root)." }
+            ],
+            "description": "Returns requested styles for a DOM node identified by <code>nodeId</code>."
+        },
+        {
+            "name": "getInlineStylesForNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId" }
+            ],
+            "returns": [
+                { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "Inline style for the specified DOM node." },
+                { "name": "attributesStyle", "$ref": "CSSStyle", "optional": true, "description": "Attribute-defined element style (e.g. resulting from \"width=20 height=100%\")."}
+            ],
+            "description": "Returns the styles defined inline (explicitly in the \"style\" attribute and implicitly, using DOM attributes) for a DOM node identified by <code>nodeId</code>."
+        },
+        {
+            "name": "getComputedStyleForNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId" }
+            ],
+            "returns": [
+                { "name": "computedStyle", "type": "array", "items": { "$ref": "CSSComputedStyleProperty" }, "description": "Computed style for the specified DOM node." }
+            ],
+            "description": "Returns the computed style for a DOM node identified by <code>nodeId</code>."
+        },
+        {
+            "name": "getAllStyleSheets",
+            "returns": [
+                { "name": "headers", "type": "array", "items": { "$ref": "CSSStyleSheetHeader" }, "description": "Descriptor entries for all available stylesheets." }
+            ],
+            "description": "Returns metainfo entries for all known stylesheets."
+        },
+        {
+            "name": "getStyleSheet",
+            "parameters": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId" }
+            ],
+            "returns": [
+                { "name": "styleSheet", "$ref": "CSSStyleSheetBody", "description": "Stylesheet contents for the specified <code>styleSheetId</code>." }
+            ],
+            "description": "Returns stylesheet data for the specified <code>styleSheetId</code>."
+        },
+        {
+            "name": "getStyleSheetText",
+            "parameters": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId" }
+            ],
+            "returns": [
+                { "name": "text", "type": "string", "description": "The stylesheet text." }
+            ],
+            "description": "Returns the current textual content and the URL for a stylesheet."
+        },
+        {
+            "name": "setStyleSheetText",
+            "parameters": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId" },
+                { "name": "text", "type": "string" }
+            ],
+            "description": "Sets the new stylesheet text, thereby invalidating all existing <code>CSSStyleId</code>'s and <code>CSSRuleId</code>'s contained by this stylesheet."
+        },
+        {
+            "name": "setStyleText",
+            "parameters": [
+                { "name": "styleId", "$ref": "CSSStyleId" },
+                { "name": "text", "type": "string" }
+            ],
+            "returns": [
+                { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the text modification." }
+            ],
+            "description": "Sets the new <code>text</code> for the respective style."
+        },
+        {
+            "name": "setRuleSelector",
+            "parameters": [
+                { "name": "ruleId", "$ref": "CSSRuleId" },
+                { "name": "selector", "type": "string" }
+            ],
+            "returns": [
+                { "name": "rule", "$ref": "CSSRule", "description": "The resulting rule after the selector modification." }
+            ],
+            "description": "Modifies the rule selector."
+        },
+        {
+            "name": "addRule",
+            "parameters": [
+                { "name": "contextNodeId", "$ref": "DOM.NodeId" },
+                { "name": "selector", "type": "string" }
+            ],
+            "returns": [
+                { "name": "rule", "$ref": "CSSRule", "description": "The newly created rule." }
+            ],
+            "description": "Creates a new empty rule with the given <code>selector</code> in a special \"inspector\" stylesheet in the owner document of the context node."
+        },
+        {
+            "name": "getSupportedCSSProperties",
+            "returns": [
+                { "name": "cssProperties", "type": "array", "items": { "$ref": "CSSPropertyInfo" }, "description": "Supported property metainfo." }
+            ],
+            "description": "Returns all supported CSS property names."
+        },
+        {
+            "name": "forcePseudoState",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The element id for which to force the pseudo state." },
+                { "name": "forcedPseudoClasses", "type": "array", "items": { "type": "string", "enum": ["active", "focus", "hover", "visited"] }, "description": "Element pseudo classes to force when computing the element's style." }
+            ],
+            "description": "Ensures that the given node will have specified pseudo-classes whenever its style is computed by the browser."
+        },
+        {
+            "name": "getNamedFlowCollection",
+            "parameters": [
+                { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id for which to get the Named Flow Collection." }
+            ],
+            "returns": [
+                { "name": "namedFlows", "type": "array", "items": { "$ref": "NamedFlow" }, "description": "An array containing the Named Flows in the document." }
+            ],
+            "description": "Returns the Named Flows from the document."
+        }
+    ],
+    "events": [
+        {
+            "name": "mediaQueryResultChanged",
+            "description": "Fires whenever a MediaQuery result changes (for example, after a browser window has been resized.) The current implementation considers only viewport-dependent media features."
+        },
+        {
+            "name": "styleSheetChanged",
+            "parameters": [
+                { "name": "styleSheetId", "$ref": "StyleSheetId" }
+            ],
+            "description": "Fired whenever a stylesheet is changed as a result of the client operation."
+        },
+        {
+            "name": "namedFlowCreated",
+            "parameters": [
+                { "name": "namedFlow", "$ref": "NamedFlow", "description": "The new Named Flow." }
+            ],
+            "description": "Fires when a Named Flow is created."
+        },
+        {
+            "name": "namedFlowRemoved",
+            "parameters": [
+                { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." },
+                { "name": "flowName", "type": "string", "description": "Identifier of the removed Named Flow." }
+            ],
+            "description": "Fires when a Named Flow is removed: has no associated content nodes and regions."
+        },
+        {
+            "name": "regionOversetChanged",
+            "parameters": [
+                { "name": "namedFlow", "$ref": "NamedFlow", "description": "The Named Flow containing the regions whose regionOverset values changed." }
+            ],
+            "description": "Fires if any of the regionOverset values changed in a Named Flow's region chain."
+        },
+        {
+            "name": "registeredNamedFlowContentElement",
+            "parameters": [
+                { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." },
+                { "name": "flowName", "type": "string", "description": "Named Flow identifier for which the new content element was registered." },
+                { "name": "contentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the registered content node." },
+                { "name": "nextContentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the element following the registered content node." }
+            ],
+            "description": "Fires when a Named Flow's has been registered with a new content node."
+        },
+        {
+            "name": "unregisteredNamedFlowContentElement",
+            "parameters": [
+                { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." },
+                { "name": "flowName", "type": "string", "description": "Named Flow identifier for which the new content element was unregistered." },
+                { "name": "contentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the unregistered content node." }
+            ],
+            "description": "Fires when a Named Flow's has been registered with a new content node."
+        }
+    ]
+}
index 23ad9477599da3c9a679e39c5fe309c848945d2b..5b319d9da8e2d42c0a264884f513a3c7fd98efdd 100644 (file)
@@ -2,23 +2,13 @@
     "domain": "Console",
     "description": "Console domain defines methods and events for interaction with the JavaScript console. Console collects messages created by means of the <a href='http://getfirebug.com/wiki/index.php/Console_API'>JavaScript Console API</a>. One needs to enable this domain using <code>enable</code> command in order to start receiving the console messages. Browser collects messages issued while console domain is not enabled as well and reports them using <code>messageAdded</code> notification upon enabling.",
     "types": [
-        {
-            "id": "ConsoleNetworkRequestId",
-            "type": "string",
-            "description": "Unique request identifier. FIXME: Duplicate of Network.RequestId <https://webkit.org/b/125664> Web Inspector: FIX Type Dependency Issues"
-        },
-        {
-            "id": "ConsoleDOMNodeId",
-            "type": "integer",
-            "description": "Unique DOM node identifier. FIXME: Duplicate of DOM.NodeId <https://webkit.org/b/125664> Web Inspector: FIX Type Dependency Issues"
-        },
         {
             "id": "ConsoleMessage",
             "type": "object",
             "description": "Console message.",
             "properties": [
-                { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "css", "security", "other"], "description": "Message source." },
-                { "name": "level", "type": "string", "enum": ["log", "warning", "error", "debug"], "description": "Message severity." },
+                { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "css", "security", "content-blocker", "other"], "description": "Message source." },
+                { "name": "level", "type": "string", "enum": ["log", "info", "warning", "error", "debug"], "description": "Message severity." },
                 { "name": "text", "type": "string", "description": "Message text." },
                 { "name": "type", "type": "string", "optional": true, "enum": ["log", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "timing", "profile", "profileEnd"], "description": "Console message type." },
                 { "name": "url", "type": "string", "optional": true, "description": "URL of the message origin." },
@@ -27,7 +17,7 @@
                 { "name": "repeatCount", "type": "integer", "optional": true, "description": "Repeat count for repeated messages." },
                 { "name": "parameters", "type": "array", "items": { "$ref": "Runtime.RemoteObject" }, "optional": true, "description": "Message parameters in case of the formatted message." },
                 { "name": "stackTrace", "$ref": "StackTrace", "optional": true, "description": "JavaScript stack trace for assertions and error messages." },
-                { "name": "networkRequestId", "$ref": "ConsoleNetworkRequestId", "optional": true, "description": "Identifier of the network request associated with this message." }
+                { "name": "networkRequestId", "$ref": "Network.RequestId", "optional": true, "description": "Identifier of the network request associated with this message." }
             ]
         },
         {
@@ -71,7 +61,7 @@
         {
             "name": "addInspectedNode",
             "parameters": [
-                { "name": "nodeId", "$ref": "ConsoleDOMNodeId", "description": "DOM node id to be accessible by means of $x command line API." }
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "DOM node id to be accessible by means of $x command line API." }
             ],
             "description": "Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions)."
         }
diff --git a/inspector/protocol/DOM.json b/inspector/protocol/DOM.json
new file mode 100644 (file)
index 0000000..5e28dda
--- /dev/null
@@ -0,0 +1,531 @@
+{
+    "domain": "DOM",
+    "description": "This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object that has an <code>id</code>. This <code>id</code> can be used to get additional information on the Node, resolve it into the JavaScript object wrapper, etc. It is important that client receives DOM events only for the nodes that are known to the client. Backend keeps track of the nodes that were sent to the client and never sends the same node twice. It is client's responsibility to collect information about the nodes that were sent to the client.<p>Note that <code>iframe</code> owner elements will return corresponding document elements as their child nodes.</p>",
+    "availability": "web",
+    "types": [
+        {
+            "id": "NodeId",
+            "type": "integer",
+            "description": "Unique DOM node identifier."
+        },
+        {
+            "id": "BackendNodeId",
+            "type": "integer",
+            "description": "Unique DOM node identifier used to reference a node that may not have been pushed to the front-end."
+        },
+        {
+            "id": "LiveRegionRelevant",
+            "type": "string",
+            "enum": ["additions", "removals", "text"],
+            "description": "Token values of @aria-relevant attribute."
+        },
+        {
+            "id": "Node",
+            "type": "object",
+            "properties": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Node identifier that is passed into the rest of the DOM messages as the <code>nodeId</code>. Backend will only push node with given <code>id</code> once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client." },
+                { "name": "nodeType", "type": "integer", "description": "<code>Node</code>'s nodeType." },
+                { "name": "nodeName", "type": "string", "description": "<code>Node</code>'s nodeName." },
+                { "name": "localName", "type": "string", "description": "<code>Node</code>'s localName." },
+                { "name": "nodeValue", "type": "string", "description": "<code>Node</code>'s nodeValue." },
+                { "name": "childNodeCount", "type": "integer", "optional": true, "description": "Child count for <code>Container</code> nodes." },
+                { "name": "children", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Child nodes of this node when requested with children." },
+                { "name": "attributes", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Attributes of the <code>Element</code> node in the form of flat array <code>[name1, value1, name2, value2]</code>." },
+                { "name": "documentURL", "type": "string", "optional": true, "description": "Document URL that <code>Document</code> or <code>FrameOwner</code> node points to." },
+                { "name": "baseURL", "type": "string", "optional": true, "description": "Base URL that <code>Document</code> or <code>FrameOwner</code> node uses for URL completion." },
+                { "name": "publicId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s publicId." },
+                { "name": "systemId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s systemId." },
+                { "name": "internalSubset", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s internalSubset." },
+                { "name": "xmlVersion", "type": "string", "optional": true, "description": "<code>Document</code>'s XML version in case of XML documents." },
+                { "name": "name", "type": "string", "optional": true, "description": "<code>Attr</code>'s name." },
+                { "name": "value", "type": "string", "optional": true, "description": "<code>Attr</code>'s value." },
+                { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." },
+                { "name": "contentDocument", "$ref": "Node", "optional": true, "description": "Content document for frame owner elements." },
+                { "name": "shadowRoots", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Shadow root list for given element host." },
+                { "name": "templateContent", "$ref": "Node", "optional": true, "description": "Content document fragment for template elements" },
+                { "name": "role", "type": "string", "optional": true, "description": "Computed value for first recognized role token, default role per element, or overridden role." }
+            ],
+            "description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type."
+        },
+        {
+            "id": "EventListener",
+            "type": "object",
+            "properties": [
+                { "name": "type", "type": "string", "description": "<code>EventListener</code>'s type." },
+                { "name": "useCapture", "type": "boolean", "description": "<code>EventListener</code>'s useCapture." },
+                { "name": "isAttribute", "type": "boolean", "description": "<code>EventListener</code>'s isAttribute." },
+                { "name": "nodeId", "$ref": "NodeId", "description": "Target <code>DOMNode</code> id." },
+                { "name": "handlerBody", "type": "string", "description": "Event handler function body." },
+                { "name": "location", "$ref": "Debugger.Location", "optional": true, "description": "Handler code location." },
+                { "name": "sourceName", "type": "string", "optional": true, "description": "Source script URL." },
+                { "name": "handler", "$ref": "Runtime.RemoteObject", "optional": true, "description": "Event handler function value." }
+            ],
+            "description": "A structure holding event listener properties."
+        },
+        {
+            "id": "AccessibilityProperties",
+            "description": "A structure holding accessibility properties.",
+            "type": "object",
+            "properties": [
+                { "name": "activeDescendantNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of the accessibility object referenced by aria-activedescendant." },
+                { "name": "busy", "type": "boolean", "optional": true, "description": "Value of @aria-busy on current or ancestor node." },
+                { "name": "checked", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Checked state of certain form controls." },
+                { "name": "childNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of the accessibility tree children if available." },
+                { "name": "controlledNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any nodes referenced via @aria-controls." },
+                { "name": "disabled", "type": "boolean", "optional": true, "description": "Disabled state of form controls." },
+                { "name": "exists", "type": "boolean", "description": "Indicates whether there is an existing AX object for the DOM node. If this is false, all the other properties will be default values." },
+                { "name": "expanded", "type": "boolean", "optional": true, "description": "Expanded state." },
+                { "name": "flowedNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any nodes referenced via @aria-flowto." },
+                { "name": "focused", "type": "boolean", "optional": true, "description": "Focused state. Only defined on focusable elements." },
+                { "name": "ignored", "type": "boolean", "optional": true, "description": "Indicates whether the accessibility of the associated AX object node is ignored, whether heuristically or explicitly." },
+                { "name": "ignoredByDefault", "type": "boolean", "optional": true, "description": "State indicating whether the accessibility of the associated AX object node is ignored by default for node type." },
+                { "name": "invalid", "type": "string", "optional": true, "enum": ["true", "false", "grammar", "spelling"], "description": "Invalid status of form controls." },
+                { "name": "hidden", "type": "boolean", "optional": true, "description": "Hidden state. True if node or an ancestor is hidden via CSS or explicit @aria-hidden, to clarify why the element is ignored." },
+                { "name": "label", "type": "string", "description": "Computed label value for the node, sometimes calculated by referencing other nodes." },
+                { "name": "liveRegionAtomic", "type": "boolean", "optional": true, "description": "Value of @aria-atomic." },
+                { "name": "liveRegionRelevant", "type": "array", "items": { "type": "string" }, "optional": true, "description": "Token value(s) of element's @aria-relevant attribute. Array of string values matching $ref LiveRegionRelevant. FIXME: Enum values blocked by http://webkit.org/b/133711" },
+                { "name": "liveRegionStatus", "type": "string", "optional": true, "enum": ["assertive", "polite", "off"], "description": "Value of element's @aria-live attribute." },
+                { "name": "mouseEventNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of node or closest ancestor node that has a mousedown, mouseup, or click event handler." },
+                { "name": "nodeId", "$ref": "NodeId", "description": "Target <code>DOMNode</code> id." },
+                { "name": "ownedNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any nodes referenced via @aria-owns." },
+                { "name": "parentNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of the accessibility tree parent object if available." },
+                { "name": "pressed", "type": "boolean", "optional": true, "description": "Pressed state for toggle buttons." },
+                { "name": "readonly", "type": "boolean", "optional": true, "description": "Readonly state of text controls." },
+                { "name": "required", "type": "boolean", "optional": true, "description": "Required state of form controls." },
+                { "name": "role", "type": "string", "description": "Computed value for first recognized role token, default role per element, or overridden role." },
+                { "name": "selected", "type": "boolean", "optional": true, "description": "Selected state of certain form controls." },
+                { "name": "selectedChildNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any children marked as selected." }
+            ]
+        },
+        {
+            "id": "RGBAColor",
+            "type": "object",
+            "properties": [
+                { "name": "r", "type": "integer", "description": "The red component, in the [0-255] range." },
+                { "name": "g", "type": "integer", "description": "The green component, in the [0-255] range." },
+                { "name": "b", "type": "integer", "description": "The blue component, in the [0-255] range." },
+                { "name": "a", "type": "number", "optional": true, "description": "The alpha component, in the [0-1] range (default: 1)." }
+            ],
+            "description": "A structure holding an RGBA color."
+        },
+        {
+            "id": "Quad",
+            "type": "array",
+            "items": { "type": "number" },
+            "minItems": 8,
+            "maxItems": 8,
+            "description": "An array of quad vertices, x immediately followed by y for each point, points clock-wise."
+        },
+        {
+            "id": "HighlightConfig",
+            "type": "object",
+            "properties": [
+                { "name": "showInfo", "type": "boolean", "optional": true, "description": "Whether the node info tooltip should be shown (default: false)." },
+                { "name": "contentColor", "$ref": "RGBAColor", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
+                { "name": "paddingColor", "$ref": "RGBAColor", "optional": true, "description": "The padding highlight fill color (default: transparent)." },
+                { "name": "borderColor", "$ref": "RGBAColor", "optional": true, "description": "The border highlight fill color (default: transparent)." },
+                { "name": "marginColor", "$ref": "RGBAColor", "optional": true, "description": "The margin highlight fill color (default: transparent)." }
+            ],
+            "description": "Configuration data for the highlighting of page elements."
+        }
+    ],
+    "commands": [
+        {
+            "name": "getDocument",
+            "returns": [
+                { "name": "root", "$ref": "Node", "description": "Resulting node." }
+            ],
+            "description": "Returns the root DOM node to the caller."
+        },
+        {
+            "name": "requestChildNodes",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get children for." },
+                { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0." }
+            ],
+            "description": "Requests that children of the node with given id are returned to the caller in form of <code>setChildNodes</code> events where not only immediate children are retrieved, but all children down to the specified depth."
+        },
+        {
+            "name": "querySelector",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to query upon." },
+                { "name": "selector", "type": "string", "description": "Selector string." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Query selector result." }
+            ],
+            "description": "Executes <code>querySelector</code> on a given node."
+        },
+        {
+            "name": "querySelectorAll",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to query upon." },
+                { "name": "selector", "type": "string", "description": "Selector string." }
+            ],
+            "returns": [
+                { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Query selector result." }
+            ],
+            "description": "Executes <code>querySelectorAll</code> on a given node."
+        },
+        {
+            "name": "setNodeName",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set name for." },
+                { "name": "name", "type": "string", "description": "New node's name." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "New node's id." }
+            ],
+            "description": "Sets node name for a node with given id."
+        },
+        {
+            "name": "setNodeValue",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set value for." },
+                { "name": "value", "type": "string", "description": "New node's value." }
+            ],
+            "description": "Sets node value for a node with given id."
+        },
+        {
+            "name": "removeNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to remove." }
+            ],
+            "description": "Removes node with given id."
+        },
+        {
+            "name": "setAttributeValue",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to set attribute for." },
+                { "name": "name", "type": "string", "description": "Attribute name." },
+                { "name": "value", "type": "string", "description": "Attribute value." }
+            ],
+            "description": "Sets attribute for an element with given id."
+        },
+        {
+            "name": "setAttributesAsText",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to set attributes for." },
+                { "name": "text", "type": "string", "description": "Text with a number of attributes. Will parse this text using HTML parser." },
+                { "name": "name", "type": "string", "optional": true, "description": "Attribute name to replace with new attributes derived from text in case text parsed successfully." }
+            ],
+            "description": "Sets attributes on element with given id. This method is useful when user edits some existing attribute value and types in several attribute name/value pairs."
+        },
+        {
+            "name": "removeAttribute",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to remove attribute from." },
+                { "name": "name", "type": "string", "description": "Name of the attribute to remove." }
+            ],
+            "description": "Removes attribute with given name from an element with given id."
+        },
+        {
+            "name": "getEventListenersForNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get listeners for." },
+                { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name for handler value. Handler value is not returned without this parameter specified." }
+            ],
+            "returns": [
+                { "name": "listeners", "type": "array", "items": { "$ref": "EventListener"}, "description": "Array of relevant listeners." }
+            ],
+            "description": "Returns event listeners relevant to the node."
+        },
+        {
+            "name": "getAccessibilityPropertiesForNode",
+            "description": "Returns a dictionary of accessibility properties for the node.",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node for which to get accessibility properties." }
+            ],
+            "returns": [
+                { "name": "properties", "$ref": "AccessibilityProperties", "description": "Dictionary of relevant accessibility properties." }
+            ]
+        },
+        {
+            "name": "getOuterHTML",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get markup for." }
+            ],
+            "returns": [
+                { "name": "outerHTML", "type": "string", "description": "Outer HTML markup." }
+            ],
+            "description": "Returns node's HTML markup."
+        },
+        {
+            "name": "setOuterHTML",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set markup for." },
+                { "name": "outerHTML", "type": "string", "description": "Outer HTML markup to set." }
+            ],
+            "description": "Sets node HTML markup, returns new node id."
+        },
+        {
+            "name": "performSearch",
+            "parameters": [
+                { "name": "query", "type": "string", "description": "Plain text or query selector or XPath search query." },
+                { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Ids of nodes to use as starting points for the search." }
+            ],
+            "returns": [
+                { "name": "searchId", "type": "string", "description": "Unique search session identifier." },
+                { "name": "resultCount", "type": "integer", "description": "Number of search results." }
+            ],
+            "description": "Searches for a given string in the DOM tree. Use <code>getSearchResults</code> to access search results or <code>cancelSearch</code> to end this search session."
+        },
+        {
+            "name": "getSearchResults",
+            "parameters": [
+                { "name": "searchId", "type": "string", "description": "Unique search session identifier." },
+                { "name": "fromIndex", "type": "integer", "description": "Start index of the search result to be returned." },
+                { "name": "toIndex", "type": "integer", "description": "End index of the search result to be returned." }
+            ],
+            "returns": [
+                { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Ids of the search result nodes." }
+            ],
+            "description": "Returns search results from given <code>fromIndex</code> to given <code>toIndex</code> from the sarch with the given identifier."
+        },
+        {
+            "name": "discardSearchResults",
+            "parameters": [
+                { "name": "searchId", "type": "string", "description": "Unique search session identifier." }
+            ],
+            "description": "Discards search results from the session with the given id. <code>getSearchResults</code> should no longer be called for that search."
+        },
+        {
+            "name": "requestNode",
+            "parameters": [
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id to convert into node." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Node id for given object." }
+            ],
+            "description": "Requests that the node is sent to the caller given the JavaScript node object reference. All nodes that form the path from the node to the root are also sent to the client as a series of <code>setChildNodes</code> notifications."
+        },
+        {
+            "name": "setInspectModeEnabled",
+            "parameters": [
+                { "name": "enabled", "type": "boolean", "description": "True to enable inspection mode, false to disable it." },
+                { "name": "highlightConfig", "$ref": "HighlightConfig", "optional": true, "description": "A descriptor for the highlight appearance of hovered-over nodes. May be omitted if <code>enabled == false</code>." }
+            ],
+            "description": "Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspect' command upon element selection."
+        },
+        {
+            "name": "highlightRect",
+            "parameters": [
+                { "name": "x", "type": "integer", "description": "X coordinate" },
+                { "name": "y", "type": "integer", "description": "Y coordinate" },
+                { "name": "width", "type": "integer", "description": "Rectangle width" },
+                { "name": "height", "type": "integer", "description": "Rectangle height" },
+                { "name": "color", "$ref": "RGBAColor", "optional": true, "description": "The highlight fill color (default: transparent)." },
+                { "name": "outlineColor", "$ref": "RGBAColor", "optional": true, "description": "The highlight outline color (default: transparent)." },
+                { "name": "usePageCoordinates", "type": "boolean", "optional": true, "description": "Indicates whether the provided parameters are in page coordinates or in viewport coordinates (the default)." }
+            ],
+            "description": "Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport."
+        },
+        {
+            "name": "highlightQuad",
+            "parameters": [
+                { "name": "quad", "$ref": "Quad", "description": "Quad to highlight" },
+                { "name": "color", "$ref": "RGBAColor", "optional": true, "description": "The highlight fill color (default: transparent)." },
+                { "name": "outlineColor", "$ref": "RGBAColor", "optional": true, "description": "The highlight outline color (default: transparent)." },
+                { "name": "usePageCoordinates", "type": "boolean", "optional": true, "description": "Indicates whether the provided parameters are in page coordinates or in viewport coordinates (the default)." }
+            ],
+            "description": "Highlights given quad. Coordinates are absolute with respect to the main frame viewport."
+        },
+        {
+            "name": "highlightSelector",
+            "parameters": [
+                { "name": "highlightConfig", "$ref": "HighlightConfig", "description": "A descriptor for the highlight appearance." },
+                { "name": "selectorString", "type": "string", "description": "A CSS selector for finding matching nodes to highlight." },
+                { "name": "frameId", "type": "string", "optional": true, "description": "Identifier of the frame which will be searched using the selector.  If not provided, the main frame will be used." }
+            ],
+            "description": "Highlights all DOM nodes that match a given selector. A string containing a CSS selector must be specified."
+        },
+        {
+            "name": "highlightNode",
+            "parameters": [
+                { "name": "highlightConfig", "$ref": "HighlightConfig", "description": "A descriptor for the highlight appearance." },
+                { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "Identifier of the node to highlight." },
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "JavaScript object id of the node to be highlighted." }
+            ],
+            "description": "Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified."
+        },
+        {
+            "name": "hideHighlight",
+            "description": "Hides DOM node highlight."
+        },
+        {
+            "name": "highlightFrame",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame to highlight." },
+                { "name": "contentColor", "$ref": "RGBAColor", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
+                { "name": "contentOutlineColor", "$ref": "RGBAColor", "optional": true, "description": "The content box highlight outline color (default: transparent)." }
+            ],
+            "description": "Highlights owner element of the frame with given id."
+        },
+        {
+            "name": "pushNodeByPathToFrontend",
+            "parameters": [
+                { "name": "path", "type": "string", "description": "Path to node in the proprietary format." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node for given path." }
+            ],
+            "description": "Requests that the node is sent to the caller given its path. // FIXME, use XPath"
+        },
+        {
+            "name": "pushNodeByBackendIdToFrontend",
+            "parameters": [
+                { "name": "backendNodeId", "$ref": "BackendNodeId", "description": "The backend node id of the node." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "The pushed node's id." }
+            ],
+            "description": "Requests that the node is sent to the caller given its backend node id."
+        },
+        {
+            "name": "releaseBackendNodeIds",
+            "parameters": [
+                { "name": "nodeGroup", "type": "string", "description": "The backend node ids group name." }
+            ],
+            "description": "Requests that group of <code>BackendNodeIds</code> is released."
+        },
+        {
+            "name": "resolveNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to resolve." },
+                { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
+            ],
+            "returns": [
+                { "name": "object", "$ref": "Runtime.RemoteObject", "description": "JavaScript object wrapper for given node." }
+            ],
+            "description": "Resolves JavaScript node object for given node id."
+        },
+        {
+            "name": "getAttributes",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to retrieve attibutes for." }
+            ],
+            "returns": [
+                { "name": "attributes", "type": "array", "items": { "type": "string" }, "description": "An interleaved array of node attribute names and values." }
+            ],
+            "description": "Returns attributes for the specified node."
+        },
+        {
+            "name": "moveTo",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to drop." },
+                { "name": "targetNodeId", "$ref": "NodeId", "description": "Id of the element to drop into." },
+                { "name": "insertBeforeNodeId", "$ref": "NodeId", "optional": true, "description": "Drop node before given one." }
+            ],
+            "returns": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "New id of the moved node." }
+            ],
+            "description": "Moves node into the new container, places it before the given anchor."
+        },
+        {
+            "name": "undo",
+            "description": "Undoes the last performed action."
+        },
+        {
+            "name": "redo",
+            "description": "Re-does the last undone action."
+        },
+        {
+            "name": "markUndoableState",
+            "description": "Marks last undoable state."
+        },
+        {
+            "name": "focus",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to focus." }
+            ],
+            "description": "Focuses the given element."
+        }
+    ],
+    "events": [
+        {
+            "name": "documentUpdated",
+            "description": "Fired when <code>Document</code> has been totally updated. Node ids are no longer valid."
+        },
+        {
+            "name": "setChildNodes",
+            "parameters": [
+                { "name": "parentId", "$ref": "NodeId", "description": "Parent node id to populate with children." },
+                { "name": "nodes", "type": "array", "items": { "$ref": "Node"}, "description": "Child nodes array." }
+            ],
+            "description": "Fired when backend wants to provide client with the missing DOM structure. This happens upon most of the calls requesting node ids."
+        },
+        {
+            "name": "attributeModified",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." },
+                { "name": "name", "type": "string", "description": "Attribute name." },
+                { "name": "value", "type": "string", "description": "Attribute value." }
+            ],
+            "description": "Fired when <code>Element</code>'s attribute is modified."
+        },
+        {
+            "name": "attributeRemoved",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." },
+                { "name": "name", "type": "string", "description": "A ttribute name." }
+            ],
+            "description": "Fired when <code>Element</code>'s attribute is removed."
+        },
+        {
+            "name": "inlineStyleInvalidated",
+            "parameters": [
+                { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Ids of the nodes for which the inline styles have been invalidated." }
+            ],
+            "description": "Fired when <code>Element</code>'s inline style is modified via a CSS property modification."
+        },
+        {
+            "name": "characterDataModified",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." },
+                { "name": "characterData", "type": "string", "description": "New text value." }
+            ],
+            "description": "Mirrors <code>DOMCharacterDataModified</code> event."
+        },
+        {
+            "name": "childNodeCountUpdated",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." },
+                { "name": "childNodeCount", "type": "integer", "description": "New node count." }
+            ],
+            "description": "Fired when <code>Container</code>'s child node count has changed."
+        },
+        {
+            "name": "childNodeInserted",
+            "parameters": [
+                { "name": "parentNodeId", "$ref": "NodeId", "description": "Id of the node that has changed." },
+                { "name": "previousNodeId", "$ref": "NodeId", "description": "If of the previous siblint." },
+                { "name": "node", "$ref": "Node", "description": "Inserted node data." }
+            ],
+            "description": "Mirrors <code>DOMNodeInserted</code> event."
+        },
+        {
+            "name": "childNodeRemoved",
+            "parameters": [
+                { "name": "parentNodeId", "$ref": "NodeId", "description": "Parent id." },
+                { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has been removed." }
+            ],
+            "description": "Mirrors <code>DOMNodeRemoved</code> event."
+        },
+        {
+            "name": "shadowRootPushed",
+            "parameters": [
+                { "name": "hostId", "$ref": "NodeId", "description": "Host element id." },
+                { "name": "root", "$ref": "Node", "description": "Shadow root." }
+            ],
+            "description": "Called when shadow root is pushed into the element."
+        },
+        {
+            "name": "shadowRootPopped",
+            "parameters": [
+                { "name": "hostId", "$ref": "NodeId", "description": "Host element id." },
+                { "name": "rootId", "$ref": "NodeId", "description": "Shadow root id." }
+            ],
+            "description": "Called when shadow root is popped from the element."
+        }
+    ]
+}
diff --git a/inspector/protocol/DOMDebugger.json b/inspector/protocol/DOMDebugger.json
new file mode 100644 (file)
index 0000000..bfab308
--- /dev/null
@@ -0,0 +1,73 @@
+{
+    "domain": "DOMDebugger",
+    "description": "DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript execution will stop on these operations as if there was a regular breakpoint set.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "DOMBreakpointType",
+            "type": "string",
+            "enum": ["subtree-modified", "attribute-modified", "node-removed"],
+            "description": "DOM breakpoint type."
+        }
+    ],
+    "commands": [
+        {
+            "name": "setDOMBreakpoint",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Identifier of the node to set breakpoint on." },
+                { "name": "type", "$ref": "DOMBreakpointType", "description": "Type of the operation to stop upon." }
+            ],
+            "description": "Sets breakpoint on particular operation with DOM."
+        },
+        {
+            "name": "removeDOMBreakpoint",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Identifier of the node to remove breakpoint from." },
+                { "name": "type", "$ref": "DOMBreakpointType", "description": "Type of the breakpoint to remove." }
+            ],
+            "description": "Removes DOM breakpoint that was set using <code>setDOMBreakpoint</code>."
+        },
+        {
+            "name": "setEventListenerBreakpoint",
+            "parameters": [
+                { "name": "eventName", "type": "string", "description": "DOM Event name to stop on (any DOM event will do)." }
+            ],
+            "description": "Sets breakpoint on particular DOM event."
+        },
+        {
+            "name": "removeEventListenerBreakpoint",
+            "parameters": [
+                { "name": "eventName", "type": "string", "description": "Event name." }
+            ],
+            "description": "Removes breakpoint on particular DOM event."
+        },
+        {
+            "name": "setInstrumentationBreakpoint",
+            "parameters": [
+                { "name": "eventName", "type": "string", "description": "Instrumentation name to stop on." }
+            ],
+            "description": "Sets breakpoint on particular native event."
+        },
+        {
+            "name": "removeInstrumentationBreakpoint",
+            "parameters": [
+                { "name": "eventName", "type": "string", "description": "Instrumentation name to stop on." }
+            ],
+            "description": "Sets breakpoint on particular native event."
+        },
+        {
+            "name": "setXHRBreakpoint",
+            "parameters": [
+                { "name": "url", "type": "string", "description": "Resource URL substring. All XHRs having this substring in the URL will get stopped upon." }
+            ],
+            "description": "Sets breakpoint on XMLHttpRequest."
+        },
+        {
+            "name": "removeXHRBreakpoint",
+            "parameters": [
+                { "name": "url", "type": "string", "description": "Resource URL substring." }
+            ],
+            "description": "Removes breakpoint from XMLHttpRequest."
+        }
+    ]
+}
diff --git a/inspector/protocol/DOMStorage.json b/inspector/protocol/DOMStorage.json
new file mode 100644 (file)
index 0000000..812e70d
--- /dev/null
@@ -0,0 +1,88 @@
+{
+    "domain": "DOMStorage",
+    "description": "Query and modify DOM storage.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "StorageId",
+            "type": "object",
+            "description": "DOM Storage identifier.",
+            "properties": [
+                { "name": "securityOrigin", "type": "string", "description": "Security origin for the storage." },
+                { "name": "isLocalStorage", "type": "boolean", "description": "Whether the storage is local storage (not session storage)." }
+            ]
+        },
+        {
+            "id": "Item",
+            "type": "array",
+            "description": "DOM Storage item.",
+            "items": { "type": "string" }
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables storage tracking, storage events will now be delivered to the client."
+        },
+        {
+            "name": "disable",
+            "description": "Disables storage tracking, prevents storage events from being sent to the client."
+        },
+        {
+            "name": "getDOMStorageItems",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" }
+            ],
+            "returns": [
+                { "name": "entries", "type": "array", "items": { "$ref": "Item" } }
+            ]
+        },
+        {
+            "name": "setDOMStorageItem",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" },
+                { "name": "key", "type": "string" },
+                { "name": "value", "type": "string" }
+            ]
+        },
+        {
+            "name": "removeDOMStorageItem",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" },
+                { "name": "key", "type": "string" }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "domStorageItemsCleared",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" }
+            ]
+        },
+        {
+            "name": "domStorageItemRemoved",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" },
+                { "name": "key", "type": "string" }
+            ]
+        },
+        {
+            "name": "domStorageItemAdded",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" },
+                { "name": "key", "type": "string" },
+                { "name": "newValue", "type": "string" }
+            ]
+        },
+        {
+            "name": "domStorageItemUpdated",
+            "parameters": [
+                { "name": "storageId", "$ref": "StorageId" },
+                { "name": "key", "type": "string" },
+                { "name": "oldValue", "type": "string" },
+                { "name": "newValue", "type": "string" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/protocol/Database.json b/inspector/protocol/Database.json
new file mode 100644 (file)
index 0000000..b959e0f
--- /dev/null
@@ -0,0 +1,71 @@
+{
+    "domain": "Database",
+    "availability": "web",
+    "types": [
+        {
+            "id": "DatabaseId",
+            "type": "string",
+            "description": "Unique identifier of Database object."
+        },
+        {
+            "id": "Database",
+            "type": "object",
+            "description": "Database object.",
+            "properties": [
+                { "name": "id", "$ref": "DatabaseId", "description": "Database ID." },
+                { "name": "domain", "type": "string", "description": "Database domain." },
+                { "name": "name", "type": "string", "description": "Database name." },
+                { "name": "version", "type": "string", "description": "Database version." }
+            ]
+        },
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables database tracking, database events will now be delivered to the client."
+        },
+        {
+            "name": "disable",
+            "description": "Disables database tracking, prevents database events from being sent to the client."
+        },
+        {
+            "name": "getDatabaseTableNames",
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" }
+            ],
+            "returns": [
+                { "name": "tableNames", "type": "array", "items": { "type": "string" } }
+            ]
+        },
+        {
+            "name": "executeSQL",
+            "async": true,
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "query", "type": "string" }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "values", "type": "array", "optional": true, "items": { "type": "any" }},
+                { "name": "sqlError", "$ref": "Error", "optional": true }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "addDatabase",
+            "parameters": [
+                { "name": "database", "$ref": "Database" }
+            ]
+        }
+    ]
+}
index 3b7c4bd49479ddf1f2ef54677832f11157cd8130..a65522ff1458f2f2dfcb0f93246b3de86367ba91 100644 (file)
@@ -80,7 +80,7 @@
             "id": "Scope",
             "type": "object",
             "properties": [
-                { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch"], "description": "Scope type." },
+                { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch", "functionName"], "description": "Scope type." },
                 { "name": "object", "$ref": "Runtime.RemoteObject", "description": "Object representing the scope. For <code>global</code> and <code>with</code> scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties." }
             ],
             "description": "Scope description."
                 { "name": "timestamp", "type": "number", "description": "Timestamp of when the sample was taken." },
                 { "name": "payload", "$ref": "Runtime.RemoteObject", "description": "Contents of the sample." }
             ]
+        },
+        {
+            "id": "AssertPauseReason",
+            "description": "The pause reason auxiliary data when paused because of an assertion.",
+            "type": "object",
+            "properties": [
+                { "name": "message", "type": "string", "optional": true, "description": "The console.assert message string if provided." }
+            ]
+        },
+        {
+            "id": "BreakpointPauseReason",
+            "description": "The pause reason auxiliary data when paused because of hitting a breakpoint.",
+            "type": "object",
+            "properties": [
+                { "name": "breakpointId", "type": "string", "description": "The identifier of the breakpoint causing the pause." }
+            ]
+        },
+        {
+            "id": "CSPViolationPauseReason",
+            "description": "The pause reason auxiliary data when paused because of a Content Security Policy directive.",
+            "type": "object",
+            "properties": [
+                { "name": "directive", "type": "string", "description": "The CSP directive that blocked script execution." }
+            ]
         }
     ],
     "commands": [
         },
         {
             "name": "searchInContent",
+            "description": "Searches for given string in script content.",
             "parameters": [
                 { "name": "scriptId", "$ref": "ScriptId", "description": "Id of the script to search in." },
-                { "name": "query", "type": "string", "description": "String to search for."  },
+                { "name": "query", "type": "string", "description": "String to search for." },
                 { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive." },
                 { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex." }
             ],
             "returns": [
                 { "name": "result", "type": "array", "items": { "$ref": "GenericTypes.SearchMatch" }, "description": "List of search matches." }
-            ],
-            "description": "Searches for given string in script content."
+            ]
         },
         {
             "name": "getScriptSource",
             "returns": [
                 { "name": "details", "$ref": "FunctionDetails", "description": "Information about the function." }
             ],
-            "description": "Returns detailed informtation on given function."
+            "description": "Returns detailed information on given function."
         },
         {
             "name": "setPauseOnExceptions",
                 { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Specifies whether command line API should be available to the evaluated expression, defaults to false." },
                 { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state." },
                 { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." },
-                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." }
+                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." },
+                { "name": "saveResult", "type": "boolean", "optional": true, "description": "Whether the resulting value should be considered for saving in the $n history." }
             ],
             "returns": [
                 { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Object wrapper for the evaluation result." },
-                { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }
+                { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." },
+                { "name": "savedResultIndex", "type": "integer", "optional": true, "description": "If the result was saved, this is the $n index that can be used to access the value." }
             ],
             "description": "Evaluates expression on a given call frame."
         },
             "name": "paused",
             "parameters": [
                 { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." },
-                { "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "CSPViolation", "other" ], "description": "Pause reason." },
+                { "name": "reason", "type": "string", "enum": ["XHR", "DOM", "EventListener", "exception", "assert", "CSPViolation", "DebuggerStatement", "Breakpoint", "PauseOnNextStatement", "other"], "description": "Pause reason." },
                 { "name": "data", "type": "object", "optional": true, "description": "Object containing break-specific auxiliary properties." }
             ],
             "description": "Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria."
diff --git a/inspector/protocol/IndexedDB.json b/inspector/protocol/IndexedDB.json
new file mode 100644 (file)
index 0000000..0e984e4
--- /dev/null
@@ -0,0 +1,145 @@
+{
+    "domain": "IndexedDB",
+    "featureGuard": "ENABLE(INDEXED_DATABASE)",
+    "availability": "web",
+    "types": [
+        {
+            "id": "DatabaseWithObjectStores",
+            "type": "object",
+            "description": "Database with an array of object stores.",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Database name." },
+                { "name": "version", "type": "number", "description": "Database version." },
+                { "name": "objectStores", "type": "array", "items": { "$ref": "ObjectStore" }, "description": "Object stores in this database." }
+            ]
+        },
+        {
+            "id": "ObjectStore",
+            "type": "object",
+            "description": "Object store.",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Object store name." },
+                { "name": "keyPath", "$ref": "KeyPath", "description": "Object store key path." },
+                { "name": "autoIncrement", "type": "boolean", "description": "If true, object store has auto increment flag set." },
+                { "name": "indexes", "type": "array", "items": { "$ref": "ObjectStoreIndex" }, "description": "Indexes in this object store." }
+            ]
+        },
+        {
+            "id": "ObjectStoreIndex",
+            "type": "object",
+            "description": "Object store index.",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Index name." },
+                { "name": "keyPath", "$ref": "KeyPath", "description": "Index key path." },
+                { "name": "unique", "type": "boolean", "description": "If true, index is unique." },
+                { "name": "multiEntry", "type": "boolean", "description": "If true, index allows multiple entries for a key." }
+            ]
+        },
+        {
+            "id": "Key",
+            "type": "object",
+            "description": "Key.",
+            "properties": [
+                { "name": "type", "type": "string", "enum": ["number", "string", "date", "array"], "description": "Key type." },
+                { "name": "number", "type": "number", "optional": true, "description": "Number value." },
+                { "name": "string", "type": "string", "optional": true, "description": "String value." },
+                { "name": "date", "type": "number", "optional": true, "description": "Date value." },
+                { "name": "array", "type": "array", "optional": true, "items": { "$ref": "Key" }, "description": "Array value." }
+            ]
+        },
+        {
+            "id": "KeyRange",
+            "type": "object",
+            "description": "Key range.",
+            "properties": [
+                { "name": "lower", "$ref": "Key", "optional": true, "description": "Lower bound." },
+                { "name": "upper", "$ref": "Key", "optional": true, "description": "Upper bound." },
+                { "name": "lowerOpen", "type": "boolean", "description": "If true lower bound is open." },
+                { "name": "upperOpen", "type": "boolean", "description": "If true upper bound is open." }
+            ]
+        },
+        {
+            "id": "DataEntry",
+            "type": "object",
+            "description": "Data entry.",
+            "properties": [
+                { "name": "key", "$ref": "Runtime.RemoteObject", "description": "Key." },
+                { "name": "primaryKey", "$ref": "Runtime.RemoteObject", "description": "Primary key." },
+                { "name": "value", "$ref": "Runtime.RemoteObject", "description": "Value." }
+            ]
+        },
+        {
+            "id": "KeyPath",
+            "type": "object",
+            "description": "Key path.",
+            "properties": [
+                { "name": "type", "type": "string", "enum": ["null", "string", "array"], "description": "Key path type." },
+                { "name": "string", "type": "string", "optional": true, "description": "String value." },
+                { "name": "array", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Array value." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables events from backend."
+        },
+        {
+            "name": "disable",
+            "description": "Disables events from backend."
+        },
+        {
+            "name": "requestDatabaseNames",
+            "async": true,
+            "parameters": [
+                { "name": "securityOrigin", "type": "string", "description": "Security origin." }
+            ],
+            "returns": [
+                { "name": "databaseNames", "type": "array", "items": { "type": "string" }, "description": "Database names for origin." }
+            ],
+            "description": "Requests database names for given security origin."
+        },
+        {
+            "name": "requestDatabase",
+            "async": true,
+            "parameters": [
+                { "name": "securityOrigin", "type": "string", "description": "Security origin." },
+                { "name": "databaseName", "type": "string", "description": "Database name." }
+            ],
+            "returns": [
+                { "name": "databaseWithObjectStores", "$ref": "DatabaseWithObjectStores", "description": "Database with an array of object stores." }
+            ],
+            "description": "Requests database with given name in given frame."
+        },
+        {
+            "name": "requestData",
+            "async": true,
+            "parameters": [
+                { "name": "securityOrigin", "type": "string", "description": "Security origin." },
+                { "name": "databaseName", "type": "string", "description": "Database name." },
+                { "name": "objectStoreName", "type": "string", "description": "Object store name." },
+                { "name": "indexName", "type": "string", "description": "Index name, empty string for object store data requests." },
+                { "name": "skipCount", "type": "integer", "description": "Number of records to skip." },
+                { "name": "pageSize", "type": "integer", "description": "Number of records to fetch." },
+                { "name": "keyRange", "$ref": "KeyRange", "optional": true, "description": "Key range." }
+            ],
+            "returns": [
+                { "name": "objectStoreDataEntries", "type": "array", "items": { "$ref": "DataEntry" }, "description": "Array of object store data entries." },
+                { "name": "hasMore", "type": "boolean", "description": "If true, there are more entries to fetch in the given range." }
+            ],
+            "description": "Requests data from object store or index."
+        },
+        {
+            "name": "clearObjectStore",
+            "async": true,
+            "parameters": [
+                { "name": "securityOrigin", "type": "string", "description": "Security origin." },
+                { "name": "databaseName", "type": "string", "description": "Database name." },
+                { "name": "objectStoreName", "type": "string", "description": "Object store name." }
+            ],
+            "returns": [
+            ],
+            "description": "Clears all entries from an object store."
+        }
+    ]
+}
diff --git a/inspector/protocol/Inspector.json b/inspector/protocol/Inspector.json
new file mode 100644 (file)
index 0000000..0420ebd
--- /dev/null
@@ -0,0 +1,51 @@
+{
+    "domain": "Inspector",
+    "types": [],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables inspector domain notifications."
+        },
+        {
+            "name": "disable",
+            "description": "Disables inspector domain notifications."
+        },
+        {
+            "name": "initialized",
+            "description": "Sent by the frontend after all initialization messages have been sent."
+        }
+    ],
+    "events": [
+        {
+            "name": "evaluateForTestInFrontend",
+            "parameters": [
+                { "name": "script", "type": "string" }
+            ]
+        },
+        {
+            "name": "inspect",
+            "parameters": [
+                { "name": "object", "$ref": "Runtime.RemoteObject" },
+                { "name": "hints", "type": "object" }
+            ]
+        },
+        {
+            "name": "detached",
+            "description": "Fired when remote debugging connection is about to be terminated. Contains detach reason.",
+            "parameters": [
+                { "name": "reason", "type": "string", "description": "The reason why connection has been terminated." }
+            ]
+        },
+        {
+            "name": "activateExtraDomains",
+            "description": "Fired when the backend has alternate domains that need to be activated.",
+            "parameters": [
+                { "name": "domains", "type": "array", "items": { "type": "string" }, "description": "Domain names that need activation" }
+            ]
+        },
+        {
+            "name": "targetCrashed",
+            "description": "Fired when debugging target has crashed"
+        }
+    ]
+}
diff --git a/inspector/protocol/InspectorDomain.json b/inspector/protocol/InspectorDomain.json
deleted file mode 100644 (file)
index 410631f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-    "domain": "Inspector",
-    "types": [],
-    "commands": [
-        {
-            "name": "enable",
-            "description": "Enables inspector domain notifications."
-        },
-        {
-            "name": "disable",
-            "description": "Disables inspector domain notifications."
-        }
-    ],
-    "events": [
-        {
-            "name": "evaluateForTestInFrontend",
-            "parameters": [
-                { "name": "script", "type": "string" }
-            ]
-        },
-        {
-            "name": "inspect",
-            "parameters": [
-                { "name": "object", "$ref": "Runtime.RemoteObject" },
-                { "name": "hints", "type": "object" }
-            ]
-        },
-        {
-            "name": "detached",
-            "description": "Fired when remote debugging connection is about to be terminated. Contains detach reason.",
-            "parameters": [
-                { "name": "reason", "type": "string", "description": "The reason why connection has been terminated." }
-            ]
-        },
-        {
-            "name": "targetCrashed",
-            "description": "Fired when debugging target has crashed"
-        }
-    ]
-}
diff --git a/inspector/protocol/LayerTree.json b/inspector/protocol/LayerTree.json
new file mode 100644 (file)
index 0000000..61211c2
--- /dev/null
@@ -0,0 +1,113 @@
+{
+    "domain": "LayerTree",
+    "availability": "web",
+    "types": [
+        {
+            "id": "LayerId",
+            "type": "string",
+            "description": "Unique RenderLayer identifier."
+        },
+        {
+            "id": "PseudoElementId",
+            "type": "string",
+            "description": "Unique PseudoElement identifier."
+        },
+        {
+            "id": "IntRect",
+            "type": "object",
+            "description": "A rectangle.",
+            "properties": [
+                { "name": "x", "type": "integer", "description": "The x position." },
+                { "name": "y", "type": "integer", "description": "The y position." },
+                { "name": "width", "type": "integer", "description": "The width metric." },
+                { "name": "height", "type": "integer", "description": "The height metric." }
+            ]
+        },
+        {
+            "id": "Layer",
+            "type": "object",
+            "description": "Information about a compositing layer.",
+            "properties": [
+                { "name": "layerId", "$ref": "LayerId", "description": "The unique id for this layer." },
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The id for the node associated with this layer." },
+                { "name": "bounds", "$ref": "IntRect", "description": "Bounds of the layer in absolute page coordinates." },
+                { "name": "paintCount", "type": "integer", "description": "Indicates how many time this layer has painted." },
+                { "name": "memory", "type": "integer", "description": "Estimated memory used by this layer." },
+                { "name": "compositedBounds", "$ref": "IntRect", "description": "The bounds of the composited layer." },
+                { "name": "isInShadowTree", "type": "boolean", "optional": true, "description": "Indicates whether this layer is associated with an element hosted in a shadow tree." },
+                { "name": "isReflection", "type": "boolean", "optional": true, "description": "Indicates whether this layer was used to provide a reflection for the element." },
+                { "name": "isGeneratedContent", "type": "boolean", "optional": true, "description": "Indicates whether the layer is attached to a pseudo element that is CSS generated content." },
+                { "name": "isAnonymous", "type": "boolean", "optional": true, "description": "Indicates whether the layer was created for a CSS anonymous block or box." },
+                { "name": "pseudoElementId", "$ref": "PseudoElementId", "optional": true, "description": "The id for the pseudo element associated with this layer." },
+                { "name": "pseudoElement", "type": "string", "optional": true, "description": "The name of the CSS pseudo-element that prompted the layer to be generated." }
+            ]
+        },
+        {
+            "id": "CompositingReasons",
+            "type": "object",
+            "description": "An object containing the reasons why the layer was composited as properties.",
+            "properties": [
+                { "name": "transform3D", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a CSS 3D transform." },
+                { "name": "video", "type": "boolean", "optional": true, "description": "Composition due to association with a <video> element." },
+                { "name": "canvas", "type": "boolean", "optional": true, "description": "Composition due to the element being a <canvas> element." },
+                { "name": "plugin", "type": "boolean", "optional": true, "description": "Composition due to association with a plugin." },
+                { "name": "iFrame", "type": "boolean", "optional": true, "description": "Composition due to association with an <iframe> element." },
+                { "name": "backfaceVisibilityHidden", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"backface-visibility: hidden\" style." },
+                { "name": "clipsCompositingDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element clipping compositing descendants." },
+                { "name": "animation", "type": "boolean", "optional": true, "description": "Composition due to association with an animated element." },
+                { "name": "filters", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS filters applied." },
+                { "name": "positionFixed", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"position: fixed\" style." },
+                { "name": "positionSticky", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"position: sticky\" style." },
+                { "name": "overflowScrollingTouch", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"overflow-scrolling: touch\" style." },
+                { "name": "stacking", "type": "boolean", "optional": true, "description": "Composition due to association with an element establishing a stacking context." },
+                { "name": "overlap", "type": "boolean", "optional": true, "description": "Composition due to association with an element overlapping other composited elements." },
+                { "name": "negativeZIndexChildren", "type": "boolean", "optional": true, "description": "Composition due to association with an element with descendants that have a negative z-index." },
+                { "name": "transformWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with composited descendants." },
+                { "name": "opacityWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with opacity applied and composited descendants." },
+                { "name": "maskWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with a masked element and composited descendants." },
+                { "name": "reflectionWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a reflection and composited descendants." },
+                { "name": "filterWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS filters applied and composited descendants." },
+                { "name": "blendingWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS blending applied and composited descendants." },
+                { "name": "isolatesCompositedBlendingDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element isolating compositing descendants having CSS blending applied." },
+                { "name": "perspective", "type": "boolean", "optional": true, "description": "Composition due to association with an element with perspective applied." },
+                { "name": "preserve3D", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"transform-style: preserve-3d\" style." },
+                { "name": "root", "type": "boolean", "optional": true, "description": "Composition due to association with the root element." },
+                { "name": "blending", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"blend-mode\" style." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables compositing tree inspection."
+        },
+        {
+            "name": "disable",
+            "description": "Disables compositing tree inspection."
+        },
+        {
+            "name": "layersForNode",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Root of the subtree for which we want to gather layers." }                ],
+            "description": "Returns the layer tree structure of the current page.",
+            "returns": [
+                { "name": "layers", "type": "array", "items": { "$ref": "Layer" }, "description": "Child layers." }
+            ]
+        },
+        {
+            "name": "reasonsForCompositingLayer",
+            "parameters": [
+                { "name": "layerId", "$ref": "LayerId", "description": "The id of the layer for which we want to get the reasons it was composited." }
+            ],
+            "description": "Provides the reasons why the given layer was composited.",
+            "returns": [
+                { "name": "compositingReasons", "$ref": "CompositingReasons", "description": "An object containing the reasons why the layer was composited as properties." }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "layerTreeDidChange"
+        }
+    ]
+}
diff --git a/inspector/protocol/Network.json b/inspector/protocol/Network.json
new file mode 100644 (file)
index 0000000..de141d2
--- /dev/null
@@ -0,0 +1,336 @@
+{
+    "domain": "Network",
+    "description": "Network domain allows tracking network activities of the page. It exposes information about http, file, data and other requests and responses, their headers, bodies, timing, etc.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "LoaderId",
+            "type": "string",
+            "description": "Unique loader identifier."
+        },
+        {
+            "id": "FrameId",
+            "type": "string",
+            "description": "Unique frame identifier."
+        },
+        {
+            "id": "RequestId",
+            "type": "string",
+            "description": "Unique request identifier."
+        },
+        {
+            "id": "Timestamp",
+            "type": "number",
+            "description": "Number of seconds since epoch."
+        },
+        {
+            "id": "Headers",
+            "type": "object",
+            "description": "Request / response headers as keys / values of JSON object."
+        },
+        {
+            "id": "ResourceTiming",
+            "type": "object",
+            "description": "Timing information for the request.",
+            "properties": [
+                { "name": "navigationStart", "type": "number", "description": "Timing's navigationStart is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this navigationStart." },
+                { "name": "domainLookupStart", "type": "number", "description": "Started DNS address resolve." },
+                { "name": "domainLookupEnd", "type": "number", "description": "Finished DNS address resolve." },
+                { "name": "connectStart", "type": "number", "description": "Started connecting to the remote host." },
+                { "name": "connectEnd", "type": "number", "description": "Connected to the remote host." },
+                { "name": "secureConnectionStart", "type": "number", "description": "Started SSL handshake." },
+                { "name": "requestStart", "type": "number", "description": "Started sending request." },
+                { "name": "responseStart", "type": "number", "description": "Started receiving response headers." }
+            ]
+        },
+        {
+            "id": "Request",
+            "type": "object",
+            "description": "HTTP request data.",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Request URL." },
+                { "name": "method", "type": "string", "description": "HTTP request method." },
+                { "name": "headers", "$ref": "Headers", "description": "HTTP request headers." },
+                { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." }
+            ]
+        },
+        {
+            "id": "Response",
+            "type": "object",
+            "description": "HTTP response data.",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Response URL. This URL can be different from CachedResource.url in case of redirect." },
+                { "name": "status", "type": "number", "description": "HTTP response status code." },
+                { "name": "statusText", "type": "string", "description": "HTTP response status text." },
+                { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." },
+                { "name": "headersText", "type": "string", "optional": true, "description": "HTTP response headers text." },
+                { "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." },
+                { "name": "requestHeaders", "$ref": "Headers", "optional": true, "description": "Refined HTTP request headers that were actually transmitted over the network." },
+                { "name": "requestHeadersText", "type": "string", "optional": true, "description": "HTTP request headers text." },
+                { "name": "fromDiskCache", "type": "boolean", "optional": true, "description": "Specifies that the request was served from the disk cache." },
+                { "name": "timing", "$ref": "ResourceTiming", "optional": true, "description": "Timing information for the given request." }
+            ]
+        },
+        {
+            "id": "WebSocketRequest",
+            "type": "object",
+            "description": "WebSocket request data.",
+            "properties": [
+                { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." }
+            ]
+        },
+        {
+            "id": "WebSocketResponse",
+            "type": "object",
+            "description": "WebSocket response data.",
+            "properties": [
+                { "name": "status", "type": "number", "description": "HTTP response status code." },
+                { "name": "statusText", "type": "string", "description": "HTTP response status text." },
+                { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." }
+            ]
+        },
+        {
+            "id": "WebSocketFrame",
+            "type": "object",
+            "description": "WebSocket frame data.",
+            "properties": [
+                { "name": "opcode", "type": "number", "description": "WebSocket frame opcode." },
+                { "name": "mask", "type": "boolean", "description": "WebSocket frame mask." },
+                { "name": "payloadData", "type": "string", "description": "WebSocket frame payload data." }
+            ]
+        },
+        {
+            "id": "CachedResource",
+            "type": "object",
+            "description": "Information about the cached resource.",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Resource URL. This is the url of the original network request." },
+                { "name": "type", "$ref": "Page.ResourceType", "description": "Type of this resource." },
+                { "name": "response", "$ref": "Response", "optional": true, "description": "Cached response data." },
+                { "name": "bodySize", "type": "number", "description": "Cached response body size." },
+                { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." }
+            ]
+        },
+        {
+            "id": "Initiator",
+            "type": "object",
+            "description": "Information about the request initiator.",
+            "properties": [
+                { "name": "type", "type": "string", "enum": ["parser", "script", "other"], "description": "Type of this initiator." },
+                { "name": "stackTrace", "$ref": "Console.StackTrace", "optional": true, "description": "Initiator JavaScript stack trace, set for Script only." },
+                { "name": "url", "type": "string", "optional": true, "description": "Initiator URL, set for Parser type only." },
+                { "name": "lineNumber", "type": "number", "optional": true, "description": "Initiator line number, set for Parser type only." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables network tracking, network events will now be delivered to the client."
+        },
+        {
+            "name": "disable",
+            "description": "Disables network tracking, prevents network events from being sent to the client."
+        },
+        {
+            "name": "setExtraHTTPHeaders",
+            "description": "Specifies whether to always send extra HTTP headers with the requests from this page.",
+            "parameters": [
+                { "name": "headers", "$ref": "Headers", "description": "Map with extra HTTP headers." }
+            ]
+        },
+        {
+            "name": "getResponseBody",
+            "description": "Returns content served for the given request.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Identifier of the network request to get content for." }
+            ],
+            "returns": [
+                { "name": "body", "type": "string", "description": "Response body." },
+                { "name": "base64Encoded", "type": "boolean", "description": "True, if content was sent as base64." }
+            ]
+        },
+        {
+            "name": "canClearBrowserCache",
+            "description": "Tells whether clearing browser cache is supported.",
+            "returns": [
+                { "name": "result", "type": "boolean", "description": "True if browser cache can be cleared." }
+            ]
+        },
+        {
+            "name": "clearBrowserCache",
+            "description": "Clears browser cache."
+        },
+        {
+            "name": "canClearBrowserCookies",
+            "description": "Tells whether clearing browser cookies is supported.",
+            "returns": [
+                { "name": "result", "type": "boolean", "description": "True if browser cookies can be cleared." }
+            ]
+        },
+        {
+            "name": "clearBrowserCookies",
+            "description": "Clears browser cookies."
+        },
+        {
+            "name": "setCacheDisabled",
+            "parameters": [
+                { "name": "cacheDisabled", "type": "boolean", "description": "Cache disabled state." }
+            ],
+            "description": "Toggles ignoring cache for each request. If <code>true</code>, cache will not be used."
+        },
+        {
+            "name": "loadResource",
+            "async": true,
+            "parameters": [
+                { "name": "frameId", "$ref": "FrameId", "description": "Frame to load the resource from." },
+                { "name": "url", "type": "string", "description": "URL of the resource to load." }
+            ],
+            "returns": [
+                { "name": "content", "type": "string", "description": "Resource content." },
+                { "name": "mimeType", "type": "string", "description": "Resource mimeType." },
+                { "name": "status", "type": "number", "description": "HTTP response status code." }
+            ],
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        }
+    ],
+    "events": [
+        {
+            "name": "requestWillBeSent",
+            "description": "Fired when page is about to send HTTP request.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." },
+                { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." },
+                { "name": "documentURL", "type": "string", "description": "URL of the document this request is loaded for." },
+                { "name": "request", "$ref": "Request", "description": "Request data." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "initiator", "$ref": "Initiator", "description": "Request initiator." },
+                { "name": "redirectResponse", "optional": true, "$ref": "Response", "description": "Redirect response data." },
+                { "name": "type", "$ref": "Page.ResourceType", "optional": true, "description": "Resource type." }
+            ]
+        },
+        {
+            "name": "requestServedFromCache",
+            "description": "Fired if request ended up loading from cache.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }
+            ]
+        },
+        {
+            "name": "responseReceived",
+            "description": "Fired when HTTP response is available.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." },
+                { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "type", "$ref": "Page.ResourceType", "description": "Resource type." },
+                { "name": "response", "$ref": "Response", "description": "Response data." }
+            ]
+        },
+        {
+            "name": "dataReceived",
+            "description": "Fired when data chunk was received over the network.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "dataLength", "type": "integer", "description": "Data chunk length." },
+                { "name": "encodedDataLength", "type": "integer", "description": "Actual bytes received (might be less than dataLength for compressed encodings)." }
+            ]
+        },
+        {
+            "name": "loadingFinished",
+            "description": "Fired when HTTP request has finished loading.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." }
+            ]
+        },
+        {
+            "name": "loadingFailed",
+            "description": "Fired when HTTP request has failed to load.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "errorText", "type": "string", "description": "User friendly error message." },
+                { "name": "canceled", "type": "boolean", "optional": true, "description": "True if loading was canceled." }
+            ]
+        },
+        {
+            "name": "requestServedFromMemoryCache",
+            "description": "Fired when HTTP request has been served from memory cache.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." },
+                { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." },
+                { "name": "documentURL", "type": "string", "description": "URL of the document this request is loaded for." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "initiator", "$ref": "Initiator", "description": "Request initiator." },
+                { "name": "resource", "$ref": "CachedResource", "description": "Cached resource data." }
+            ]
+        },
+        {
+            "name": "webSocketWillSendHandshakeRequest",
+            "description": "Fired when WebSocket is about to initiate handshake.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." }
+            ]
+        },
+        {
+            "name": "webSocketHandshakeResponseReceived",
+            "description": "Fired when WebSocket handshake response becomes available.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." }
+            ]
+        },
+        {
+            "name": "webSocketCreated",
+            "description": "Fired upon WebSocket creation.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "url", "type": "string", "description": "WebSocket request URL." }
+            ]
+        },
+        {
+            "name": "webSocketClosed",
+            "description": "Fired when WebSocket is closed.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }
+            ]
+        },
+        {
+            "name": "webSocketFrameReceived",
+            "description": "Fired when WebSocket frame is received.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "response", "$ref": "WebSocketFrame", "description": "WebSocket response data." }
+            ]
+        },
+        {
+            "name": "webSocketFrameError",
+            "description": "Fired when WebSocket frame error occurs.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "errorMessage", "type": "string", "description": "WebSocket frame error message." }
+            ]
+        },
+        {
+            "name": "webSocketFrameSent",
+            "description": "Fired when WebSocket frame is sent.",
+            "parameters": [
+                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
+                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "response", "$ref": "WebSocketFrame", "description": "WebSocket response data." }
+            ]
+        }
+    ]
+}
diff --git a/inspector/protocol/OverlayTypes.json b/inspector/protocol/OverlayTypes.json
new file mode 100644 (file)
index 0000000..47efa75
--- /dev/null
@@ -0,0 +1,129 @@
+{
+    "domain": "OverlayTypes",
+    "description": "Exposes types to be used by the inspector overlay.",
+    "types": [
+        {
+            "id": "Point",
+            "type": "object",
+            "properties": [
+                { "name": "x", "type": "number" },
+                { "name": "y", "type": "number" }
+            ]
+        },
+        {
+            "id": "Size",
+            "type": "object",
+            "properties": [
+                { "name": "width", "type": "integer" },
+                { "name": "height", "type": "integer" }
+            ]
+        },
+        {
+            "id": "Quad",
+            "description": "A quad is a collection of 4 points. When initialized from a rect, the points are in clockwise order from top left.",
+            "type": "array",
+            "items": { "$ref": "Point" }
+        },
+        {
+            "id": "Rect",
+            "description": "A rectangle specified by a reference coordinate and width/height offsets.",
+            "type": "object",
+            "properties": [
+                { "name": "x", "type": "number" },
+                { "name": "y", "type": "number" },
+                { "name": "width", "type": "number" },
+                { "name": "height", "type": "number" }
+            ]
+        },
+        {
+            "id": "Region",
+            "description": "A single region in a flow thread.",
+            "type": "object",
+            "properties": [
+                { "name": "borderQuad", "$ref": "Quad" },
+                { "name": "incomingQuad", "$ref": "Quad" },
+                { "name": "outgoingQuad", "$ref": "Quad" },
+                { "name": "isHighlighted", "type": "boolean", "optional": true }
+            ]
+        },
+        {
+            "id": "DisplayPath",
+            "description": "A vector path described using SVG path syntax.",
+            "type": "array",
+            "items": { "type": "any" }
+        },
+        {
+            "id": "RegionFlowData",
+            "type": "object",
+            "properties": [
+                { "name": "regions", "type": "array", "items": { "$ref": "Region"} },
+                { "name": "name", "type": "string" }
+            ]
+        },
+        {
+            "id": "ContentFlowData",
+            "type": "object",
+            "properties": [
+                { "name": "name", "type": "string" }
+            ]
+        },
+        {
+            "id": "ShapeOutsideData",
+            "type": "object",
+            "properties": [
+                { "name": "bounds", "$ref": "Quad", "description": "Bounds for the shape-outside paths." },
+                { "name": "shape", "$ref": "DisplayPath", "description": "Path for the element's shape.", "optional": true },
+                { "name": "marginShape", "$ref": "DisplayPath", "description": "Path for the element's margin shape.", "optional": true }
+            ]
+        },
+        {
+            "id": "ElementData",
+            "description": "Data that describes an element to be highlighted.",
+            "type": "object",
+            "properties": [
+                { "name": "tagName", "type": "string" },
+                { "name": "idValue", "type": "string", "description": "The value of the element's 'id' attribute." },
+                { "name": "className", "type": "string", "optional": true },
+                { "name": "size", "$ref": "Size", "optional": true },
+                { "name": "role", "type": "string", "description": "Computed accessibility role for the element.", "optional": true },
+                { "name": "regionFlowData", "$ref": "RegionFlowData", "optional": true },
+                { "name": "contentFlowData", "$ref": "ContentFlowData", "optional": true },
+                { "name": "shapeOutsideData", "$ref": "ShapeOutsideData", "optional": true }
+            ]
+        },
+        {
+            "id": "FragmentHighlightData",
+            "description": "Data required to highlight multiple quads.",
+            "type": "object",
+            "properties": [
+                { "name": "quads", "type": "array", "items": { "$ref": "Quad" }, "description": "Quads for which the highlight should be applied."},
+                { "name": "contentColor", "type": "string" },
+                { "name": "contentOutlineColor", "type": "string" },
+                { "name": "paddingColor", "type": "string" },
+                { "name": "borderColor", "type": "string" },
+                { "name": "marginColor", "type": "string" },
+                { "name": "regionClippingArea", "$ref": "Quad", "optional": true }
+            ]
+        },
+        {
+            "id": "NodeHighlightData",
+            "description": "Data required to highlight a DOM node.",
+            "type": "object",
+            "properties": [
+                { "name": "scrollOffset", "$ref": "Point", "description": "Scroll offset for the MainFrame's FrameView that is shared across all quads." },
+                { "name": "fragments", "type": "array", "items": { "$ref": "FragmentHighlightData" } },
+                { "name": "elementData", "$ref": "ElementData", "optional": true }
+            ]
+        },
+        {
+            "id": "OverlayConfiguration",
+            "description": "Data required to configure the overlay's size and scaling behavior.",
+            "type": "object",
+            "properties": [
+                { "name": "deviceScaleFactor", "type": "number" },
+                { "name": "viewportSize", "$ref": "Size" },
+                { "name": "frameViewFullSize", "$ref": "Size" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/protocol/Page.json b/inspector/protocol/Page.json
new file mode 100644 (file)
index 0000000..c210a89
--- /dev/null
@@ -0,0 +1,357 @@
+{
+    "domain": "Page",
+    "description": "Actions and events related to the inspected page belong to the page domain.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "ResourceType",
+            "type": "string",
+            "enum": ["Document", "Stylesheet", "Image", "Font", "Script", "XHR", "WebSocket", "Other"],
+            "description": "Resource type as it was perceived by the rendering engine."
+        },
+        {
+            "id": "CoordinateSystem",
+            "type": "string",
+            "enum": ["Viewport", "Page"],
+            "description": "Coordinate system used by supplied coordinates."
+        },
+        {
+            "id": "Frame",
+            "type": "object",
+            "description": "Information about the Frame on the page.",
+            "properties": [
+                { "name": "id", "type": "string", "description": "Frame unique identifier." },
+                { "name": "parentId", "type": "string", "optional": true, "description": "Parent frame identifier." },
+                { "name": "loaderId", "$ref": "Network.LoaderId", "description": "Identifier of the loader associated with this frame." },
+                { "name": "name", "type": "string", "optional": true, "description": "Frame's name as specified in the tag." },
+                { "name": "url", "type": "string", "description": "Frame document's URL." },
+                { "name": "securityOrigin", "type": "string", "description": "Frame document's security origin." },
+                { "name": "mimeType", "type": "string", "description": "Frame document's mimeType as determined by the browser." }
+            ]
+        },
+        {
+            "id": "FrameResource",
+            "type": "object",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Resource URL." },
+                { "name": "type", "$ref": "ResourceType", "description": "Type of this resource." },
+                { "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." },
+                { "name": "failed", "type": "boolean", "optional": true, "description": "True if the resource failed to load." },
+                { "name": "canceled", "type": "boolean", "optional": true, "description": "True if the resource was canceled during loading." },
+                { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." }
+            ]
+        },
+        {
+            "id": "FrameResourceTree",
+            "type": "object",
+            "description": "Information about the Frame hierarchy along with their cached resources.",
+            "properties": [
+                { "name": "frame", "$ref": "Frame", "description": "Frame information for this tree item." },
+                { "name": "childFrames", "type": "array", "optional": true, "items": { "$ref": "FrameResourceTree" }, "description": "Child frames." },
+                { "name": "resources", "type": "array", "items": { "$ref": "FrameResource" }, "description": "Information about frame resources." }
+            ]
+        },
+        {
+            "id": "SearchResult",
+            "type": "object",
+            "description": "Search result for resource.",
+            "properties": [
+                { "name": "url", "type": "string", "description": "Resource URL." },
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Resource frame id." },
+                { "name": "matchesCount", "type": "number", "description": "Number of matches in the resource content." }
+            ]
+        },
+        {
+            "id": "Cookie",
+            "type": "object",
+            "description": "Cookie object",
+            "properties": [
+                { "name": "name", "type": "string", "description": "Cookie name." },
+                { "name": "value", "type": "string", "description": "Cookie value." },
+                { "name": "domain", "type": "string", "description": "Cookie domain." },
+                { "name": "path", "type": "string", "description": "Cookie path." },
+                { "name": "expires", "type": "number", "description": "Cookie expires." },
+                { "name": "size", "type": "integer", "description": "Cookie size." },
+                { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." },
+                { "name": "secure", "type": "boolean", "description": "True if cookie is secure." },
+                { "name": "session", "type": "boolean", "description": "True in case of session cookie." }
+            ]
+        },
+        {
+            "id": "ScriptIdentifier",
+            "type": "string",
+            "description": "Unique script identifier."
+        }
+    ],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enables page domain notifications."
+        },
+        {
+            "name": "disable",
+            "description": "Disables page domain notifications."
+        },
+        {
+            "name": "addScriptToEvaluateOnLoad",
+            "parameters": [
+                { "name": "scriptSource", "type": "string" }
+            ],
+            "returns": [
+                { "name": "identifier", "$ref": "ScriptIdentifier", "description": "Identifier of the added script." }
+            ]
+        },
+        {
+            "name": "removeScriptToEvaluateOnLoad",
+            "parameters": [
+                { "name": "identifier", "$ref": "ScriptIdentifier" }
+            ]
+        },
+        {
+            "name": "reload",
+            "parameters": [
+                { "name": "ignoreCache", "type": "boolean", "optional": true, "description": "If true, browser cache is ignored (as if the user pressed Shift+refresh)." },
+                { "name": "scriptToEvaluateOnLoad", "type": "string", "optional": true, "description": "If set, the script will be injected into all frames of the inspected page after reload." }
+            ],
+            "description": "Reloads given page optionally ignoring the cache."
+        },
+        {
+            "name": "navigate",
+            "parameters": [
+                { "name": "url", "type": "string", "description": "URL to navigate the page to." }
+            ],
+            "description": "Navigates current page to the given URL."
+        },
+        {
+            "name": "getCookies",
+            "returns": [
+                { "name": "cookies", "type": "array", "items": { "$ref": "Cookie"}, "description": "Array of cookie objects." }
+            ],
+            "description": "Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the <code>cookies</code> field."
+        },
+        {
+            "name": "deleteCookie",
+            "parameters": [
+                { "name": "cookieName", "type": "string", "description": "Name of the cookie to remove." },
+                { "name": "url", "type": "string", "description": "URL to match cooke domain and path." }
+            ],
+            "description": "Deletes browser cookie with given name, domain and path."
+        },
+        {
+            "name": "getResourceTree",
+            "description": "Returns present frame / resource tree structure.",
+            "returns": [
+                { "name": "frameTree", "$ref": "FrameResourceTree", "description": "Present frame / resource tree structure." }
+            ]
+        },
+        {
+            "name": "getResourceContent",
+            "description": "Returns content of the given resource.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id to get resource for." },
+                { "name": "url", "type": "string", "description": "URL of the resource to get content for." }
+            ],
+            "returns": [
+                { "name": "content", "type": "string", "description": "Resource content." },
+                { "name": "base64Encoded", "type": "boolean", "description": "True, if content was served as base64." }
+            ]
+        },
+        {
+            "name": "searchInResource",
+            "description": "Searches for given string in resource content.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id for resource to search in." },
+                { "name": "url", "type": "string", "description": "URL of the resource to search in." },
+                { "name": "query", "type": "string", "description": "String to search for." },
+                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive." },
+                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex." }
+            ],
+            "returns": [
+                { "name": "result", "type": "array", "items": { "$ref": "GenericTypes.SearchMatch" }, "description": "List of search matches." }
+            ]
+        },
+        {
+            "name": "searchInResources",
+            "description": "Searches for given string in frame / resource tree structure.",
+            "parameters": [
+                { "name": "text", "type": "string", "description": "String to search for." },
+                { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive." },
+                { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex." }
+            ],
+            "returns": [
+                { "name": "result", "type": "array", "items": { "$ref": "SearchResult" }, "description": "List of search results." }
+            ]
+        },
+        {
+            "name": "setDocumentContent",
+            "description": "Sets given markup as the document's HTML.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id to set HTML for." },
+                { "name": "html", "type": "string", "description": "HTML content to set."  }
+            ]
+        },
+        {
+            "name": "setShowPaintRects",
+            "description": "Requests that backend shows paint rectangles",
+            "parameters": [
+                { "name": "result", "type": "boolean", "description": "True for showing paint rectangles" }
+            ]
+        },
+        {
+            "name": "getScriptExecutionStatus",
+            "description": "Determines if scripts can be executed in the page.",
+            "returns": [
+                { "name": "result", "type": "string", "enum": ["allowed", "disabled", "forbidden"], "description": "Script execution status: \"allowed\" if scripts can be executed, \"disabled\" if script execution has been disabled through page settings, \"forbidden\" if script execution for the given page is not possible for other reasons." }
+            ]
+        },
+        {
+            "name": "setScriptExecutionDisabled",
+            "description": "Switches script execution in the page.",
+            "parameters": [
+                { "name": "value", "type": "boolean", "description": "Whether script execution should be disabled in the page." }
+            ]
+        },
+        {
+            "name": "setTouchEmulationEnabled",
+            "parameters": [
+                { "name": "enabled", "type": "boolean", "description": "Whether the touch event emulation should be enabled." }
+            ],
+            "description": "Toggles mouse event-based touch event emulation."
+        },
+        {
+            "name": "setEmulatedMedia",
+            "parameters": [
+                { "name": "media", "type": "string", "description": "Media type to emulate. Empty string disables the override." }
+            ],
+            "description": "Emulates the given media for CSS media queries."
+        },
+        {
+            "name": "getCompositingBordersVisible",
+            "description": "Indicates the visibility of compositing borders.",
+            "returns": [
+                { "name": "result", "type": "boolean", "description": "If true, compositing borders are visible." }
+            ]
+        },
+        {
+            "name": "setCompositingBordersVisible",
+            "description": "Controls the visibility of compositing borders.",
+            "parameters": [
+                { "name": "visible", "type": "boolean", "description": "True for showing compositing borders." }
+            ]
+        },
+        {
+            "name": "snapshotNode",
+            "description": "Capture a snapshot of the specified node that does not include unrelated layers.",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Id of the node to snapshot." }
+            ],
+            "returns": [
+                { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
+            ]
+        },
+        {
+            "name": "snapshotRect",
+            "description": "Capture a snapshot of the page within the specified rectangle and coordinate system.",
+            "parameters": [
+                { "name": "x", "type": "integer", "description": "X coordinate" },
+                { "name": "y", "type": "integer", "description": "Y coordinate" },
+                { "name": "width", "type": "integer", "description": "Rectangle width" },
+                { "name": "height", "type": "integer", "description": "Rectangle height" },
+                { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." }
+            ],
+            "returns": [
+                { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
+            ]
+        },
+        {
+            "name": "handleJavaScriptDialog",
+            "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",
+            "parameters": [
+                { "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog." },
+                { "name": "promptText", "type": "string", "optional": true, "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog." }
+            ]
+        },
+        {
+            "name": "archive",
+            "description": "Grab an archive of the page.",
+            "returns": [
+                { "name": "data", "type": "string", "description": "Base64-encoded web archive." }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "domContentEventFired",
+            "parameters": [
+                { "name": "timestamp", "type": "number" }
+            ]
+        },
+        {
+            "name": "loadEventFired",
+            "parameters": [
+                { "name": "timestamp", "type": "number" }
+            ]
+        },
+        {
+            "name": "frameNavigated",
+            "description": "Fired once navigation of the frame has completed. Frame is now associated with the new loader.",
+            "parameters": [
+                { "name": "frame", "$ref": "Frame", "description": "Frame object." }
+            ]
+        },
+        {
+            "name": "frameDetached",
+            "description": "Fired when frame has been detached from its parent.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." }
+            ]
+        },
+        {
+            "name": "frameStartedLoading",
+            "description": "Fired when frame has started loading.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has started loading." }
+            ]
+        },
+        {
+            "name": "frameStoppedLoading",
+            "description": "Fired when frame has stopped loading.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has stopped loading." }
+            ]
+        },
+        {
+            "name": "frameScheduledNavigation",
+            "description": "Fired when frame schedules a potential navigation.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has scheduled a navigation." },
+                { "name": "delay", "type": "number", "description": "Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start." }
+            ]
+        },
+        {
+            "name": "frameClearedScheduledNavigation",
+            "description": "Fired when frame no longer has a scheduled navigation.",
+            "parameters": [
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." }
+            ]
+        },
+        {
+            "name": "javascriptDialogOpening",
+            "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.",
+            "parameters": [
+                { "name": "message", "type": "string", "description": "Message that will be displayed by the dialog." }
+            ]
+        },
+        {
+            "name": "javascriptDialogClosed",
+            "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed."
+        },
+        {
+            "name": "scriptsEnabled",
+            "description": "Fired when the JavaScript is enabled/disabled on the page",
+            "parameters": [
+                { "name": "isEnabled", "type": "boolean", "description": "Whether script execution is enabled or disabled on the page." }
+            ]
+        }
+    ]
+}
diff --git a/inspector/protocol/Profiler.json b/inspector/protocol/Profiler.json
deleted file mode 100644 (file)
index 7a3bf35..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-{
-    "domain": "Profiler",
-    "types": [
-        {
-            "id": "ProfileHeader",
-            "type": "object",
-            "description": "Profile header.",
-            "properties": [
-                { "name": "typeId", "type": "string", "enum": ["CPU"], "description": "Profile type name." },
-                { "name": "title", "type": "string", "description": "Profile title." },
-                { "name": "uid", "type": "integer", "description": "Unique identifier of the profile." }
-            ]
-        },
-        {
-            "id": "CPUProfileNodeCall",
-            "type": "object",
-            "description": "CPU Profile call info. Holds time information for a specific call that happened on a node.",
-            "properties": [
-                { "name": "startTime", "type": "number", "description": "Start time for the call." },
-                { "name": "totalTime", "type": "number", "description": "Total execution time for the call." }
-            ]
-        },
-        {
-            "id": "CPUProfileNode",
-            "type": "object",
-            "description": "CPU Profile node. Holds callsite information, execution statistics and child nodes.",
-            "properties": [
-                { "name": "id", "type": "integer", "description": "Unique identifier for this call site." },
-                { "name": "calls", "type": "array", "items": { "$ref": "CPUProfileNodeCall" }, "description": "Calls making up this node." },
-                { "name": "functionName", "type": "string", "optional": true, "description": "Function name." },
-                { "name": "url", "type": "string", "optional": true, "description": "URL." },
-                { "name": "lineNumber", "type": "integer", "optional": true, "description": "Line number." },
-                { "name": "columnNumber", "type": "integer", "optional": true, "description": "Column number." },
-                { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "optional": true, "description": "Child nodes." }
-            ]
-        },
-        {
-            "id": "CPUProfile",
-            "type": "object",
-            "description": "Profile.",
-            "properties": [
-                { "name": "rootNodes", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Top level nodes in the stack." },
-                { "name": "idleTime", "type": "number", "optional": true }
-            ]
-        }
-    ],
-    "commands": [
-        {
-            "name": "enable"
-        },
-        {
-            "name": "disable"
-        },
-        {
-            "name": "start"
-        },
-        {
-            "name": "stop"
-        },
-        {
-            "name": "getProfileHeaders",
-            "returns": [
-                { "name": "headers", "type": "array", "items": { "$ref": "ProfileHeader"} }
-            ]
-        },
-        {
-            "name": "getCPUProfile",
-            "parameters": [
-                { "name": "uid", "type": "integer" }
-            ],
-            "returns": [
-                { "name": "profile", "$ref": "CPUProfile" }
-            ]
-        },
-        {
-            "name": "removeProfile",
-            "parameters": [
-                { "name": "type", "type": "string" },
-                { "name": "uid", "type": "integer" }
-            ]
-        },
-        {
-            "name": "clearProfiles"
-        }
-    ],
-    "events": [
-        {
-            "name": "addProfileHeader",
-            "parameters": [
-                { "name": "header", "$ref": "ProfileHeader" }
-            ]
-        },
-        {
-            "name": "setRecordingProfile",
-            "parameters": [
-                { "name": "isProfiling", "type": "boolean" }
-            ]
-        },
-        {
-            "name": "resetProfiles"
-        }
-    ]
-}
diff --git a/inspector/protocol/Replay.json b/inspector/protocol/Replay.json
new file mode 100644 (file)
index 0000000..7bc26bd
--- /dev/null
@@ -0,0 +1,264 @@
+{
+    "domain": "Replay",
+    "description": "Controls web replay, and manages recording sessions and segments.",
+    "featureGuard": "ENABLE(WEB_REPLAY)",
+    "availability": "web",
+    "types": [
+        {
+            "id": "SessionIdentifier", "description": "Unique replay session identifier.",
+            "type": "integer"
+        },
+        {
+            "id": "SegmentIdentifier", "description": "Unique session segment identifier.",
+            "type": "integer"
+        },
+        {
+            "id": "SessionState", "description": "State machine's state for the session.",
+            "type": "string",
+            "enum": ["Capturing", "Inactive", "Replaying"]
+        },
+        {
+            "id": "SegmentState", "description": "State machine's state for the session segment.",
+            "type": "string",
+            "enum": ["Appending", "Unloaded", "Loaded", "Dispatching"]
+        },
+        {
+            "id": "ReplayPosition",
+            "type": "object",
+            "properties": [
+               { "name": "segmentOffset", "type": "integer", "description": "Offset for a segment within the currently-loaded replay session." },
+               { "name": "inputOffset", "type": "integer", "description": "Offset for an event loop input within the specified session segment." }
+            ]
+        },
+        {
+            "id": "ReplayInput",
+            "type": "object",
+            "properties": [
+                { "name": "type", "type": "string", "description": "Input type." },
+                { "name": "offset", "type": "integer", "description": "Offset of this input in its respective queue."},
+                { "name": "data", "type": "object", "description": "Per-input payload." }
+            ]
+        },
+        {
+            "id": "ReplayInputQueue",
+            "type": "object",
+            "properties": [
+                { "name": "type", "type": "string", "description": "Queue type" },
+                { "name": "inputs", "type": "array", "items": { "$ref": "ReplayInput"}, "description": "Inputs belonging to this queue." }
+            ]
+        },
+        {
+            "id": "SessionSegment", "description": "A standalone segment of a replay session that corresponds to a single main frame navigation and execution.",
+            "type": "object",
+            "properties": [
+                { "name": "id", "$ref": "SegmentIdentifier", "description": "Unique session segment identifier." },
+                { "name": "timestamp", "type": "number", "description": "Start time of the segment, in milliseconds since the epoch." },
+                { "name": "queues", "type": "array", "items": { "$ref": "ReplayInputQueue"} }
+            ]
+        },
+        {
+            "id": "ReplaySession", "description": "An ordered collection of replay session segments.",
+            "type": "object",
+            "properties": [
+                { "name": "id", "$ref": "SessionIdentifier", "description": "Unique replay session identifier." },
+                { "name": "timestamp", "type": "number", "description": "Creation time of session, in milliseconds since the epoch." },
+                { "name": "segments", "type": "array", "items": { "$ref": "SegmentIdentifier" }, "description": "An ordered list identifiers for the segments that comprise this replay session." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "startCapturing",
+            "description": "Starts capture of a new replay session."
+        },
+        {
+            "name": "stopCapturing",
+            "description": "Stops capture of the currently recording replay session."
+        },
+        {
+            "name": "replayToPosition",
+            "description": "Seek execution to a specific position within the replay session.",
+            "parameters": [
+                { "name": "position", "$ref": "ReplayPosition" },
+                { "name": "shouldFastForward", "type": "boolean" }
+            ]
+        },
+        {
+            "name": "replayToCompletion",
+            "description": "Replay all session segments completely.",
+            "parameters": [
+                { "name": "shouldFastForward", "type": "boolean" }
+            ]
+        },
+        {
+            "name": "pausePlayback",
+            "description": "Pauses playback in the current segment. Can be resumed by using a replay command."
+        },
+        {
+            "name": "cancelPlayback",
+            "description": "Cancels playback of the current segment. Further replaying will start from the beginning of the current segment."
+        },
+        {
+            "name": "switchSession",
+            "description": "Unloads the current replay session and loads the specified session",
+            "parameters": [
+                { "name": "sessionIdentifier", "$ref": "SessionIdentifier" }
+            ]
+        },
+        {
+            "name": "insertSessionSegment",
+            "description": "Splices the specified session segment into the session at the specified index.",
+            "parameters": [
+                { "name": "sessionIdentifier", "$ref": "SessionIdentifier" },
+                { "name": "segmentIdentifier", "$ref": "SegmentIdentifier" },
+                { "name": "segmentIndex", "type": "integer" }
+            ]
+        },
+        {
+            "name": "removeSessionSegment",
+            "description": "Removes the session segment at the specified position from the session.",
+            "parameters": [
+                { "name": "sessionIdentifier", "$ref": "SessionIdentifier" },
+                { "name": "segmentIndex", "type": "integer" }
+            ]
+        },
+        {
+            "name": "currentReplayState",
+            "description": "Returns the identifier, position, session state and segment state of the currently loaded session. This is necessary because the inspector may be closed and reopened in the middle of replay.",
+            "returns": [
+                { "name": "sessionIdentifier", "$ref": "SessionIdentifier" },
+                { "name": "segmentIdentifier", "$ref": "SegmentIdentifier", "optional": true, "description": "If no segment is currently loaded, then there is no valid segment identifier." },
+                { "name": "sessionState", "$ref": "SessionState" },
+                { "name": "segmentState", "$ref": "SegmentState" },
+                { "name": "replayPosition", "$ref": "ReplayPosition" }
+            ]
+        },
+        {
+            "name": "getAvailableSessions",
+            "description": "Returns identifiers of all available sessions.",
+            "returns": [
+                { "name": "ids", "type": "array", "items": { "$ref": "SessionIdentifier" } }
+            ]
+        },
+        {
+            "name": "getSessionData",
+            "description": "Returns an object for the specified session.",
+            "parameters": [
+                { "name": "sessionIdentifier", "$ref": "SessionIdentifier" }
+            ],
+            "returns": [
+                { "name": "session", "$ref": "ReplaySession", "optional": true, "description": "The requested serialized replay session." }
+            ]
+        },
+        {
+            "name": "getSegmentData",
+            "description": "Returns an object for the specified session segment.",
+            "parameters": [
+                { "name": "id", "$ref": "SegmentIdentifier" }
+            ],
+            "returns": [
+                { "name": "segment", "$ref": "SessionSegment",  "optional": true, "description": "The requested serialized session segment." }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "captureStarted",
+            "description": "Fired when capture has started."
+        },
+        {
+            "name": "captureStopped",
+            "description": "Fired when capture has stopped."
+        },
+        {
+            "name": "playbackHitPosition",
+            "description": "Playback within the session has progressed up to this position, and is about to replay the input at the specified offset.",
+            "parameters": [
+                { "name": "position", "$ref": "ReplayPosition", "description": "The playback position that was hit." },
+                { "name": "timestamp", "type": "number", "description": "A timestamp for the event." }
+            ]
+        },
+        {
+            "name": "playbackStarted",
+            "description": "Fired when session playback has started."
+        },
+        {
+            "name": "playbackPaused",
+            "description": "Fired when session playback has paused, but not finished.",
+            "parameters": [
+                { "name": "position", "$ref": "ReplayPosition", "description": "The playback position immediately prior to where playback is paused." }
+            ]
+        },
+        {
+            "name": "playbackFinished",
+            "description": "Fired when session playback has stopped."
+        },
+        {
+            "name": "inputSuppressionChanged",
+            "description": "Fired when the replay controller starts or stops suppressing user inputs.",
+            "parameters": [
+                { "name": "willSuppress", "type": "boolean", "description": "Whether user inputs will be suppressed during playback." }
+            ]
+        },
+        {
+            "name": "sessionCreated",
+            "description": "Fired when a new replay session is created",
+            "parameters": [
+                { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the created session." }
+            ]
+        },
+        {
+            "name": "sessionModified",
+            "description": "Fired when a session's segments have changed.",
+            "parameters": [
+                { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the session the segment was added to." }
+            ]
+        },
+        {
+            "name": "sessionRemoved",
+            "description": "Fired when a replay session is removed and can no longer be loaded.",
+            "parameters": [
+                { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the removed session." }
+            ]
+        },
+        {
+            "name": "sessionLoaded",
+            "description": "Fired when a replay session is loaded.",
+            "parameters": [
+                { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the loaded session." }
+            ]
+        },
+        {
+            "name": "segmentCreated",
+            "description": "Fired when a new session segment is created.",
+            "parameters": [
+                { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the created session segment." }
+            ]
+        },
+        {
+            "name": "segmentRemoved",
+            "description": "Fired when a session segment is removed and can no longer be replayed as part of a session.",
+            "parameters": [
+                { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the removed session segment." }
+            ]
+        },
+        {
+            "name": "segmentCompleted",
+            "description": "Fired when a session segment is completed and can no longer have inputs added to it.",
+            "parameters": [
+                { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the completed session segment." }
+            ]
+        },
+        {
+            "name": "segmentLoaded",
+            "description": "Fired when a segment is loaded.",
+            "parameters": [
+                { "name": "segmentIdentifier", "$ref": "SegmentIdentifier", "description": "Id for the loaded segment." }
+            ]
+        },
+        {
+            "name": "segmentUnloaded",
+            "description": "Fired when a segment is unloaded."
+        }
+    ]
+}
index b888aa32b75978b8e40bf98af67210b4a149bf26..c321f6afd8a18c2992f888f6b794680a8934e6c4 100644 (file)
             "type": "object",
             "description": "Mirror object referencing original JavaScript object.",
             "properties": [
-                { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean"], "description": "Object type." },
-                { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
+                { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." },
+                { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> <code>function</code> (for class) type values only." },
                 { "name": "className", "type": "string", "optional": true, "description": "Object class (constructor) name. Specified for <code>object</code> type values only." },
                 { "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values or JSON values if it was requested)." },
                 { "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
                 { "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Unique object identifier (for non-primitive values)." },
-                { "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containsing abbreviated property values." }
+                { "name": "size", "type": "integer", "optional": true, "description": "Size of the array/collection. Specified for array/map/set/weakmap/weakset object type values only." },
+                { "name": "classPrototype", "$ref": "RemoteObject", "optional": true, "description": "Remote object for the class prototype. Specified for class object type values only." },
+                { "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containing abbreviated property values. Specified for <code>object</code> type values only." }
             ]
         },
         {
             "type": "object",
             "description": "Object containing abbreviated remote object value.",
             "properties": [
+                { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." },
+                { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
+                { "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
                 { "name": "lossless", "type": "boolean", "description": "Determines whether preview is lossless (contains all information of the original object)." },
-                { "name": "overflow", "type": "boolean", "description": "True iff some of the properties of the original did not fit." },
-                { "name": "properties", "type": "array", "items": { "$ref": "PropertyPreview" }, "description": "List of the properties." }
+                { "name": "overflow", "type": "boolean", "optional": true, "description": "True iff some of the properties of the original did not fit." },
+                { "name": "properties", "type": "array", "items": { "$ref": "PropertyPreview" }, "optional": true, "description": "List of the properties." },
+                { "name": "entries", "type": "array", "items": { "$ref": "EntryPreview" }, "optional": true, "description": "List of the entries. Specified for <code>map</code> and <code>set</code> subtype values only." },
+                { "name": "size", "type": "integer", "optional": true, "description": "Size of the array/collection. Specified for array/map/set/weakmap/weakset object type values only." }
             ]
         },
         {
             "type": "object",
             "properties": [
                 { "name": "name", "type": "string", "description": "Property name." },
-                { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean"], "description": "Object type." },
+                { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "accessor"], "description": "Object type." },
+                { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
                 { "name": "value", "type": "string", "optional": true, "description": "User-friendly property value string." },
                 { "name": "valuePreview", "$ref": "ObjectPreview", "optional": true, "description": "Nested value preview." },
-                { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date"], "description": "Object subtype hint. Specified for <code>object</code> type values only." }
+                { "name": "internal", "type": "boolean", "optional": true, "description": "True if this is an internal property." }
+            ]
+        },
+        {
+            "id": "EntryPreview",
+            "type": "object",
+            "properties": [
+                { "name": "key", "$ref": "ObjectPreview", "optional": true, "description": "Entry key. Specified for map-like collection entries." },
+                { "name": "value", "$ref": "ObjectPreview", "description": "Entry value." }
+            ]
+        },
+        {
+            "id": "CollectionEntry",
+            "type": "object",
+            "properties": [
+                { "name": "key", "$ref": "Runtime.RemoteObject", "optional": true, "description": "Entry key of a map-like collection, otherwise not provided." },
+                { "name": "value", "$ref": "Runtime.RemoteObject", "description": "Entry value." }
             ]
         },
         {
@@ -47,7 +71,7 @@
             "type": "object",
             "description": "Object property descriptor.",
             "properties": [
-                { "name": "name", "type": "string", "description": "Property name." },
+                { "name": "name", "type": "string", "description": "Property name or symbol description." },
                 { "name": "value", "$ref": "RemoteObject", "optional": true, "description": "The value associated with the property." },
                 { "name": "writable", "type": "boolean", "optional": true, "description": "True if the value associated with the property may be changed (data descriptors only)." },
                 { "name": "get", "$ref": "RemoteObject", "optional": true, "description": "A function which serves as a getter for the property, or <code>undefined</code> if there is no getter (accessor descriptors only)." },
@@ -55,7 +79,9 @@
                 { "name": "configurable", "type": "boolean", "description": "True if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object." },
                 { "name": "enumerable", "type": "boolean", "description": "True if this property shows up during enumeration of the properties on the corresponding object." },
                 { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." },
-                { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object." }
+                { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object." },
+                { "name": "symbol", "optional": true, "$ref": "Runtime.RemoteObject", "description": "Property symbol object, if the property is a symbol." },
+                { "name": "nativeGetter", "optional": true, "type": "boolean", "description": "True if the property value came from a native getter." }
             ]
         },
         {
             "type": "integer",
             "description": "Id of an execution context."
         },
-        {
-            "id": "RuntimeFrameId",
-            "type": "string",
-            "description": "Unique frame identifier. FIXME: Duplicate of Network.FrameId <https://webkit.org/b/125664> Web Inspector: FIX Type Dependency Issues"
-        },
         {
             "id": "ExecutionContextDescription",
             "type": "object",
                 { "name": "id", "$ref": "ExecutionContextId", "description": "Unique id of the execution context. It can be used to specify in which execution context script evaluation should be performed." },
                 { "name": "isPageContext", "type": "boolean", "description": "True if this is a context where inpspected web page scripts run. False if it is a content script isolated context." },
                 { "name": "name", "type": "string", "description": "Human readable name describing given context."},
-                { "name": "frameId", "$ref": "RuntimeFrameId", "description": "Id of the owning frame." }
+                { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the owning frame." }
             ]
         },
         {
                 { "name": "startOffset", "type": "integer", "description": "Start offset of range (inclusive)." },
                 { "name": "endOffset", "type": "integer", "description": "End offset of range (exclusive)." }
             ]
+        },
+        {
+            "id": "StructureDescription",
+            "type": "object",
+            "properties": [
+                { "name": "fields", "type": "array",  "items": { "type": "string" }, "optional": true, "description": "Array of strings, where the strings represent object properties." },
+                { "name": "optionalFields", "type": "array",  "items": { "type": "string" }, "optional": true, "description": "Array of strings, where the strings represent optional object properties." },
+                { "name": "constructorName", "type": "string", "optional": true, "description": "Name of the constructor." },
+                { "name": "prototypeStructure", "$ref": "StructureDescription", "optional": true, "description": "Pointer to the StructureRepresentation of the protoype if one exists." },
+                { "name": "isImprecise", "type": "boolean", "optional": true, "description": "If true, it indicates that the fields in this StructureDescription may be inaccurate. I.e, there might have been fields that have been deleted before it was profiled or it has fields we haven't profiled." }
+            ]
+        },
+        {
+            "id": "TypeSet",
+            "type": "object",
+            "properties": [
+                { "name": "isFunction", "type": "boolean", "description": "Indicates if this type description has been type Function." },
+                { "name": "isUndefined", "type": "boolean", "description": "Indicates if this type description has been type Undefined." },
+                { "name": "isNull", "type": "boolean", "description": "Indicates if this type description has been type Null." },
+                { "name": "isBoolean", "type": "boolean", "description": "Indicates if this type description has been type Boolean." },
+                { "name": "isInteger", "type": "boolean", "description": "Indicates if this type description has been type Integer." },
+                { "name": "isNumber", "type": "boolean", "description": "Indicates if this type description has been type Number." },
+                { "name": "isString", "type": "boolean", "description": "Indicates if this type description has been type String." },
+                { "name": "isObject", "type": "boolean", "description": "Indicates if this type description has been type Object." },
+                { "name": "isSymbol", "type": "boolean", "description": "Indicates if this type description has been type Symbol." }
+            ]
+        },
+        {
+            "id": "TypeDescription",
+            "type": "object",
+            "description": "Container for type information that has been gathered.",
+            "properties": [
+                { "name": "isValid", "type": "boolean", "description": "If true, we were able to correlate the offset successfuly with a program location. If false, the offset may be bogus or the offset may be from a CodeBlock that hasn't executed." },
+                { "name": "leastCommonAncestor", "type": "string", "optional": true, "description": "Least common ancestor of all Constructors if the TypeDescription has seen any structures. This string is the display name of the shared constructor function." },
+                { "name": "typeSet", "$ref": "TypeSet", "optional": true, "description": "Set of booleans for determining the aggregate type of this type description." },
+                { "name": "structures", "type": "array", "items": { "$ref": "StructureDescription" }, "optional": true, "description": "Array of descriptions for all structures seen for this variable." },
+                { "name": "isTruncated", "type": "boolean", "optional": true, "description": "If true, this indicates that no more structures are being profiled because some maximum threshold has been reached and profiling has stopped because of memory pressure." }
+            ]
+        },
+        {
+            "id": "TypeLocation",
+            "type": "object",
+            "description": "Describes the location of an expression we want type information for.",
+            "properties": [
+                { "name": "typeInformationDescriptor", "type": "integer", "description": "What kind of type information do we want (normal, function return values, 'this' statement)." },
+                { "name": "sourceID", "type": "string", "description": "sourceID uniquely identifying a script" },
+                { "name": "divot", "type": "integer", "description": "character offset for assignment range" }
+            ]
+        },
+        {
+            "id": "BasicBlock",
+            "type": "object",
+            "description": "From Wikipedia: a basic block is a portion of the code within a program with only one entry point and only one exit point. This type gives the location of a basic block and if that basic block has executed.",
+            "properties": [
+                { "name": "startOffset", "type": "integer", "description": "Start offset of the basic block." },
+                { "name": "endOffset", "type": "integer", "description": "End offset of the basic block." },
+                { "name": "hasExecuted", "type": "boolean", "description": "Indicates if the basic block has executed before." }
+            ]
         }
     ],
     "commands": [
                 { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state." },
                 { "name": "contextId", "$ref": "Runtime.ExecutionContextId", "optional": true, "description": "Specifies in which isolated context to perform evaluation. Each content script lives in an isolated context and this parameter may be used to specify one of those contexts. If the parameter is omitted or 0 the evaluation will be performed in the context of the inspected page." },
                 { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." },
-                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." }
+                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." },
+                { "name": "saveResult", "type": "boolean", "optional": true, "description": "Whether the resulting value should be considered for saving in the $n history." }
             ],
             "returns": [
                 { "name": "result", "$ref": "RemoteObject", "description": "Evaluation result." },
-                { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }
+                { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." },
+                { "name": "savedResultIndex", "type": "integer", "optional": true, "description": "If the result was saved, this is the $n index that can be used to access the value." }
             ],
             "description": "Evaluates expression on global object."
         },
             "parameters": [
                 { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to return properties for." },
                 { "name": "ownProperties", "optional": true, "type": "boolean", "description": "If true, returns properties belonging only to the object itself, not to its prototype chain." },
-                { "name": "ownAndGetterProperties", "optional": true, "type": "boolean", "description": "If true, returns properties belonging to the object itself, and getters in its prototype chain." }
+                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for property values." }
             ],
             "returns": [
                 { "name": "result", "type": "array", "items": { "$ref": "PropertyDescriptor"}, "description": "Object properties." },
             ],
             "description": "Returns properties of a given object. Object group of the result is inherited from the target object."
         },
+        {
+            "name": "getDisplayableProperties",
+            "parameters": [
+                { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to return properties for." },
+                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for property values." }
+            ],
+            "returns": [
+                { "name": "properties", "type": "array", "items": { "$ref": "PropertyDescriptor"}, "description": "Object properties." },
+                { "name": "internalProperties", "optional": true, "type": "array", "items": { "$ref": "InternalPropertyDescriptor"}, "description": "Internal object properties." }
+            ],
+            "description": "Returns displayable properties of a given object. Object group of the result is inherited from the target object. Displayable properties are own properties, internal properties, and native getters in the prototype chain (assumed to be bindings and treated like own properties for the frontend)."
+        },
+        {
+            "name": "getCollectionEntries",
+            "description": "Returns entries of given Map / Set collection.",
+            "parameters": [
+                { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Id of the collection to get entries for." },
+                { "name": "objectGroup", "optional": true, "type": "string", "description": "Symbolic group name that can be used to release multiple. If not provided, it will be the same objectGroup as the RemoteObject determined from <code>objectId</code>. This is useful for WeakMap to release the collection entries." },
+                { "name": "startIndex", "optional": true, "type": "integer", "description": "If provided skip to this index before collecting values. Otherwise, 0." },
+                { "name": "numberToFetch", "optional": true, "type": "integer", "description": "If provided only return <code>numberToFetch</code> values. Otherwise, return values all the way to the end." }
+            ],
+            "returns": [
+                { "name": "entries", "type": "array", "items": { "$ref": "CollectionEntry" }, "description": "Array of collection entries." }
+            ]
+        },
+        {
+            "name": "saveResult",
+            "parameters": [
+                { "name": "value", "$ref": "CallArgument", "description": "Id or value of the object to save." },
+                { "name": "contextId", "optional": true, "$ref": "ExecutionContextId", "description": "Unique id of the execution context. To specify in which execution context script evaluation should be performed. If not provided, determine from the CallArgument's objectId." }
+            ],
+            "returns": [
+                { "name": "savedResultIndex", "type": "integer", "optional": true, "description": "If the value was saved, this is the $n index that can be used to access the value." }
+            ],
+            "description": "Assign a saved result index to this value."
+        },
         {
             "name": "releaseObject",
             "parameters": [
         {
             "name": "disable",
             "description": "Disables reporting of execution contexts creation."
+        },
+        {
+            "name": "getRuntimeTypesForVariablesAtOffsets",
+            "parameters": [
+                { "name": "locations", "type": "array", "items": { "$ref": "TypeLocation" }, "description": "An array of type locations we're requesting information for. Results are expected in the same order they're sent in."}
+            ],
+            "returns": [
+                { "name": "types", "type": "array", "items": { "$ref": "TypeDescription", "description": "Types for requested variable." } }
+            ],
+            "description": "Returns detailed informtation on given function."
+        },
+        {
+            "name": "enableTypeProfiler",
+            "description": "Enables type profiling on the VM."
+        },
+        {
+            "name": "disableTypeProfiler",
+            "description": "Disables type profiling on the VM."
+        },
+        {
+            "name": "getBasicBlocks",
+            "parameters": [
+                { "name": "sourceID", "type": "string", "description": "Indicates which sourceID information is requested for." }
+            ],
+            "returns": [
+                { "name": "basicBlocks", "type": "array", "items": { "$ref": "BasicBlock", "description": "Array of basic blocks." } }
+            ],
+            "description": "Returns a list of basic blocks for the given sourceID with information about their text ranges and whether or not they have executed."
         }
     ],
     "events": [
diff --git a/inspector/protocol/Timeline.json b/inspector/protocol/Timeline.json
new file mode 100644 (file)
index 0000000..6e34297
--- /dev/null
@@ -0,0 +1,120 @@
+{
+    "domain": "Timeline",
+    "description": "Timeline provides its clients with instrumentation records that are generated during the page runtime. Timeline instrumentation can be started and stopped using corresponding commands. While timeline is started, it is generating timeline event records.",
+    "availability": "web",
+    "types": [
+        {
+            "id": "EventType",
+            "type": "string",
+            "enum": [
+                "EventDispatch",
+                "ScheduleStyleRecalculation",
+                "RecalculateStyles",
+                "InvalidateLayout",
+                "Layout",
+                "Paint",
+                "Composite",
+                "RenderingFrame",
+                "ScrollLayer",
+                "ParseHTML",
+                "TimerInstall",
+                "TimerRemove",
+                "TimerFire",
+                "EvaluateScript",
+                "MarkLoad",
+                "MarkDOMContent",
+                "TimeStamp",
+                "Time",
+                "TimeEnd",
+                "XHRReadyStateChange",
+                "XHRLoad",
+                "FunctionCall",
+                "ProbeSample",
+                "ConsoleProfile",
+                "GCEvent",
+                "RequestAnimationFrame",
+                "CancelAnimationFrame",
+                "FireAnimationFrame",
+                "WebSocketCreate",
+                "WebSocketSendHandshakeRequest",
+                "WebSocketReceiveHandshakeResponse",
+                "WebSocketDestroy"
+            ],
+            "description": "Timeline record type."
+        },
+        {
+            "id": "TimelineEvent",
+            "type": "object",
+            "properties": [
+                { "name": "type", "$ref": "EventType", "description": "Event type." },
+                { "name": "data", "type": "object", "description": "Event data." },
+                { "name": "children", "type": "array", "optional": true, "items": { "$ref": "TimelineEvent" }, "description": "Nested records." }
+            ],
+            "description": "Timeline record contains information about the recorded activity."
+        },
+        {
+            "id": "CPUProfileNodeAggregateCallInfo",
+            "type": "object",
+            "description": "Aggregate CPU Profile call info. Holds time information for all the calls that happened on a node.",
+            "properties": [
+                { "name": "callCount", "type": "number", "description": "Total number of calls." },
+                { "name": "startTime", "type": "number", "description": "Start time for the first call." },
+                { "name": "endTime", "type": "number", "description": "End time for the last call." },
+                { "name": "totalTime", "type": "number", "description": "Total execution time for all calls combined." }
+            ]
+        },
+        {
+            "id": "CPUProfileNode",
+            "type": "object",
+            "description": "CPU Profile node. Holds callsite information, execution statistics and child nodes.",
+            "properties": [
+                { "name": "id", "type": "integer", "description": "Unique identifier for this call site." },
+                { "name": "callInfo", "$ref": "CPUProfileNodeAggregateCallInfo", "description": "Aggregate info about all the calls that making up this node." },
+                { "name": "functionName", "type": "string", "optional": true, "description": "Function name." },
+                { "name": "url", "type": "string", "optional": true, "description": "URL." },
+                { "name": "lineNumber", "type": "integer", "optional": true, "description": "Line number." },
+                { "name": "columnNumber", "type": "integer", "optional": true, "description": "Column number." },
+                { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "optional": true, "description": "Child nodes." }
+            ]
+        },
+        {
+            "id": "CPUProfile",
+            "type": "object",
+            "description": "Profile.",
+            "properties": [
+                { "name": "rootNodes", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Top level nodes in the stack." },
+                { "name": "idleTime", "type": "number", "optional": true }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "start",
+            "parameters": [
+                { "name": "maxCallStackDepth", "optional": true, "type": "integer", "description": "Samples JavaScript stack traces up to <code>maxCallStackDepth</code>, defaults to 5." }
+            ],
+            "description": "Starts capturing instrumentation events."
+        },
+        {
+            "name": "stop",
+            "description": "Stops capturing instrumentation events."
+        }
+    ],
+    "events": [
+        {
+            "name": "eventRecorded",
+            "parameters": [
+                { "name": "record", "$ref": "TimelineEvent", "description": "Timeline event record data." }
+            ],
+            "description": "Fired for every instrumentation event while timeline is started."
+        },
+        {
+            "name": "recordingStarted",
+            "description": "Fired when recording has started."
+        },
+        {
+            "name": "recordingStopped",
+            "description": "Fired when recording has stopped."
+        }
+    ]
+}
diff --git a/inspector/protocol/Worker.json b/inspector/protocol/Worker.json
new file mode 100644 (file)
index 0000000..5269e13
--- /dev/null
@@ -0,0 +1,71 @@
+{
+    "domain": "Worker",
+    "types": [],
+    "availability": "web",
+    "commands": [
+        {
+            "name": "enable"
+        },
+        {
+            "name": "disable"
+        },
+        {
+            "name": "sendMessageToWorker",
+            "parameters": [
+                { "name": "workerId", "type": "integer" },
+                { "name": "message", "type": "object" }
+            ]
+        },
+        {
+            "name": "canInspectWorkers",
+            "description": "Tells whether browser supports workers inspection.",
+            "returns": [
+                { "name": "result", "type": "boolean", "description": "True if browser has workers support." }
+            ]
+        },
+        {
+            "name": "connectToWorker",
+            "parameters": [
+                { "name": "workerId", "type": "integer" }
+            ]
+        },
+        {
+            "name": "disconnectFromWorker",
+            "parameters": [
+                { "name": "workerId", "type": "integer" }
+            ]
+        },
+        {
+            "name": "setAutoconnectToWorkers",
+            "parameters": [
+                { "name": "value", "type": "boolean" }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "workerCreated",
+            "parameters": [
+                { "name": "workerId", "type": "integer" },
+                { "name": "url", "type": "string" },
+                { "name": "inspectorConnected", "type": "boolean" }
+            ]
+        },
+        {
+            "name": "workerTerminated",
+            "parameters": [
+                { "name": "workerId", "type": "integer" }
+            ]
+        },
+        {
+            "name": "dispatchMessageFromWorker",
+            "parameters": [
+                { "name": "workerId", "type": "integer" },
+                { "name": "message", "type": "object" }
+            ]
+        },
+        {
+            "name": "disconnectedFromWorker"
+        }
+    ]
+}
index fb6a78ae96ab264ee382c07e676107b20b500fa8..2cd85197b3f42882184b4f8bafa0a88de29746df 100644 (file)
@@ -46,14 +46,17 @@ struct RemoteInspectorDebuggableInfo;
 class JS_EXPORT_PRIVATE RemoteInspector final : public RemoteInspectorXPCConnection::Client {
 public:
     static void startDisabled();
-    static RemoteInspector& shared();
+    static RemoteInspector& singleton();
     friend class NeverDestroyed<RemoteInspector>;
 
     void registerDebuggable(RemoteInspectorDebuggable*);
     void unregisterDebuggable(RemoteInspectorDebuggable*);
     void updateDebuggable(RemoteInspectorDebuggable*);
+    void updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable*);
     void sendMessageToRemoteFrontend(unsigned identifier, const String& message);
     void setupFailed(unsigned identifier);
+    void setupCompleted(unsigned identifier);
+    bool waitingForAutomaticInspection(unsigned identifier);
 
     bool enabled() const { return m_enabled; }
     bool hasActiveDebugSession() const { return m_hasActiveDebugSession; }
@@ -83,6 +86,8 @@ private:
 
     void updateHasActiveDebugSession();
 
+    void sendAutomaticInspectionCandidateMessage();
+
     virtual void xpcConnectionReceivedMessage(RemoteInspectorXPCConnection*, NSString *messageName, NSDictionary *userInfo) override;
     virtual void xpcConnectionFailed(RemoteInspectorXPCConnection*) override;
     virtual void xpcConnectionUnhandledMessage(RemoteInspectorXPCConnection*, xpc_object_t) override;
@@ -94,6 +99,8 @@ private:
     void receivedIndicateMessage(NSDictionary *userInfo);
     void receivedProxyApplicationSetupMessage(NSDictionary *userInfo);
     void receivedConnectionDiedMessage(NSDictionary *userInfo);
+    void receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo);
+    void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo);
 
     static bool startEnabled;
 
@@ -117,6 +124,9 @@ private:
     pid_t m_parentProcessIdentifier;
     RetainPtr<CFDataRef> m_parentProcessAuditData;
     bool m_shouldSendParentProcessInformation;
+    bool m_automaticInspectionEnabled;
+    bool m_automaticInspectionPaused;
+    unsigned m_automaticInspectionCandidateIdentifier;
 };
 
 } // namespace Inspector
index 9e058012dd391acd4b32dd82bfbbc6217432b76b..6814dd311338d6d3f98dee5c189c25929175415c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #import "RemoteInspectorDebuggable.h"
 #import "RemoteInspectorDebuggableConnection.h"
 #import <Foundation/Foundation.h>
+#import <dispatch/dispatch.h>
 #import <notify.h>
 #import <wtf/Assertions.h>
+#import <wtf/MainThread.h>
 #import <wtf/NeverDestroyed.h>
+#import <wtf/spi/darwin/XPCSPI.h>
 #import <wtf/text/WTFString.h>
-#import <xpc/xpc.h>
 
-#if PLATFORM(IOS)
-#import <wtf/ios/WebCoreThread.h>
+#if __has_include(<sandbox/private.h>)
+#import <sandbox/private.h>
+#else
+enum sandbox_filter_type {
+    SANDBOX_FILTER_GLOBAL_NAME = 2,
+};
 #endif
 
+extern "C" int sandbox_check(pid_t, const char *operation, enum sandbox_filter_type, ...);
+extern "C" const enum sandbox_filter_type SANDBOX_CHECK_NO_REPORT;
+
 namespace Inspector {
 
-static void dispatchAsyncOnQueueSafeForAnyDebuggable(void (^block)())
+static bool canAccessWebInspectorMachPort()
 {
-#if PLATFORM(IOS)
-    if (WebCoreWebThreadIsEnabled && WebCoreWebThreadIsEnabled()) {
-        WebCoreWebThreadRun(block);
-        return;
-    }
-#endif
+    return sandbox_check(getpid(), "mach-lookup", static_cast<enum sandbox_filter_type>(SANDBOX_FILTER_GLOBAL_NAME | SANDBOX_CHECK_NO_REPORT), WIRXPCMachPortName) == 0;
+}
+
+static bool globalAutomaticInspectionState()
+{
+    int token = 0;
+    if (notify_register_check(WIRAutomaticInspectionEnabledState, &token) != NOTIFY_STATUS_OK)
+        return false;
 
-    dispatch_async(dispatch_get_main_queue(), block);
+    uint64_t automaticInspectionEnabled = 0;
+    notify_get_state(token, &automaticInspectionEnabled);
+    return automaticInspectionEnabled == 1;
 }
 
 bool RemoteInspector::startEnabled = true;
@@ -64,15 +77,29 @@ void RemoteInspector::startDisabled()
     RemoteInspector::startEnabled = false;
 }
 
-RemoteInspector& RemoteInspector::shared()
+RemoteInspector& RemoteInspector::singleton()
 {
     static NeverDestroyed<RemoteInspector> shared;
 
     static dispatch_once_t once;
     dispatch_once(&once, ^{
-        JSC::initializeThreading();
-        if (RemoteInspector::startEnabled)
-            shared.get().start();
+        if (canAccessWebInspectorMachPort()) {
+            dispatch_block_t initialize = ^{
+                WTF::initializeMainThread();
+                JSC::initializeThreading();
+                if (RemoteInspector::startEnabled)
+                    shared.get().start();
+            };
+
+            if ([NSThread isMainThread])
+                initialize();
+            else {
+                // FIXME: This means that we may miss an auto-attach to a JSContext created on a non-main thread.
+                // The main thread initialization is required for certain WTF values that need to be initialized
+                // on the "real" main thread. We should investigate a better way to handle this.
+                dispatch_async(dispatch_get_main_queue(), initialize);
+            }
+        }
     });
 
     return shared;
@@ -87,6 +114,9 @@ RemoteInspector::RemoteInspector()
     , m_pushScheduled(false)
     , m_parentProcessIdentifier(0)
     , m_shouldSendParentProcessInformation(false)
+    , m_automaticInspectionEnabled(false)
+    , m_automaticInspectionPaused(false)
+    , m_automaticInspectionCandidateIdentifier(0)
 {
 }
 
@@ -145,6 +175,74 @@ void RemoteInspector::updateDebuggable(RemoteInspectorDebuggable* debuggable)
     pushListingSoon();
 }
 
+void RemoteInspector::updateDebuggableAutomaticInspectCandidate(RemoteInspectorDebuggable* debuggable)
+{
+    {
+        std::lock_guard<std::mutex> lock(m_mutex);
+
+        unsigned identifier = debuggable->identifier();
+        if (!identifier)
+            return;
+
+        auto result = m_debuggableMap.set(identifier, std::make_pair(debuggable, debuggable->info()));
+        ASSERT_UNUSED(result, !result.isNewEntry);
+
+        // Don't allow automatic inspection unless it is allowed or we are stopped.
+        if (!m_automaticInspectionEnabled || !m_enabled) {
+            pushListingSoon();
+            return;
+        }
+
+        // FIXME: We should handle multiple debuggables trying to pause at the same time on different threads.
+        // To make this work we will need to change m_automaticInspectionCandidateIdentifier to be a per-thread value.
+        // Multiple attempts on the same thread should not be possible because our nested run loop is in a special RWI mode.
+        if (m_automaticInspectionPaused) {
+            LOG_ERROR("Skipping Automatic Inspection Candidate with pageId(%u) because we are already paused waiting for pageId(%u)", identifier, m_automaticInspectionCandidateIdentifier);
+            pushListingSoon();
+            return;
+        }
+
+        m_automaticInspectionPaused = true;
+        m_automaticInspectionCandidateIdentifier = identifier;
+
+        // If we are pausing before we have connected to webinspectord the candidate message will be sent as soon as the connection is established.
+        if (m_xpcConnection) {
+            pushListingNow();
+            sendAutomaticInspectionCandidateMessage();
+        }
+
+        // In case debuggers fail to respond, or we cannot connect to webinspectord, automatically continue after a short period of time.
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.8 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+            std::lock_guard<std::mutex> lock(m_mutex);
+            if (m_automaticInspectionCandidateIdentifier == identifier) {
+                LOG_ERROR("Skipping Automatic Inspection Candidate with pageId(%u) because we failed to receive a response in time.", m_automaticInspectionCandidateIdentifier);
+                m_automaticInspectionPaused = false;
+            }
+        });
+    }
+
+    debuggable->pauseWaitingForAutomaticInspection();
+
+    {
+        std::lock_guard<std::mutex> lock(m_mutex);
+
+        ASSERT(m_automaticInspectionCandidateIdentifier);
+        m_automaticInspectionCandidateIdentifier = 0;
+    }
+}
+
+void RemoteInspector::sendAutomaticInspectionCandidateMessage()
+{
+    ASSERT(m_enabled);
+    ASSERT(m_automaticInspectionEnabled);
+    ASSERT(m_automaticInspectionPaused);
+    ASSERT(m_automaticInspectionCandidateIdentifier);
+    ASSERT(m_xpcConnection);
+
+    NSDictionary *details = @{WIRPageIdentifierKey: @(m_automaticInspectionCandidateIdentifier)};
+    m_xpcConnection->sendMessage(WIRAutomaticInspectionCandidateMessage, details);
+}
+
 void RemoteInspector::sendMessageToRemoteFrontend(unsigned identifier, const String& message)
 {
     std::lock_guard<std::mutex> lock(m_mutex);
@@ -173,9 +271,26 @@ void RemoteInspector::setupFailed(unsigned identifier)
 
     updateHasActiveDebugSession();
 
+    if (identifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+
     pushListingSoon();
 }
 
+void RemoteInspector::setupCompleted(unsigned identifier)
+{
+    std::lock_guard<std::mutex> lock(m_mutex);
+
+    if (identifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+}
+
+bool RemoteInspector::waitingForAutomaticInspection(unsigned)
+{
+    // We don't take the lock to check this because we assume it will be checked repeatedly.
+    return m_automaticInspectionPaused;
+}
+
 void RemoteInspector::start()
 {
     std::lock_guard<std::mutex> lock(m_mutex);
@@ -185,8 +300,14 @@ void RemoteInspector::start()
 
     m_enabled = true;
 
+    // Load the initial automatic inspection state when first started, so we know it before we have even connected to webinspectord.
+    static dispatch_once_t once;
+    dispatch_once(&once, ^{
+        m_automaticInspectionEnabled = globalAutomaticInspectionState();
+    });
+
     notify_register_dispatch(WIRServiceAvailableNotification, &m_notifyToken, m_xpcQueue, ^(int) {
-        RemoteInspector::shared().setupXPCConnectionIfNeeded();
+        RemoteInspector::singleton().setupXPCConnectionIfNeeded();
     });
 
     notify_post(WIRServiceAvailabilityCheckNotification);
@@ -214,6 +335,8 @@ void RemoteInspector::stopInternal(StopSource source)
 
     updateHasActiveDebugSession();
 
+    m_automaticInspectionPaused = false;
+
     if (m_xpcConnection) {
         switch (source) {
         case StopSource::API:
@@ -245,7 +368,12 @@ void RemoteInspector::setupXPCConnectionIfNeeded()
     m_xpcConnection->sendMessage(@"syn", nil); // Send a simple message to initialize the XPC connection.
     xpc_release(connection);
 
-    pushListingSoon();
+    if (m_automaticInspectionCandidateIdentifier) {
+        // We already have a debuggable waiting to be automatically inspected.
+        pushListingNow();
+        sendAutomaticInspectionCandidateMessage();
+    } else
+        pushListingSoon();
 }
 
 #pragma mark - Proxy Application Information
@@ -289,6 +417,10 @@ void RemoteInspector::xpcConnectionReceivedMessage(RemoteInspectorXPCConnection*
         receivedProxyApplicationSetupMessage(userInfo);
     else if ([messageName isEqualToString:WIRConnectionDiedMessage])
         receivedConnectionDiedMessage(userInfo);
+    else if ([messageName isEqualToString:WIRAutomaticInspectionConfigurationMessage])
+        receivedAutomaticInspectionConfigurationMessage(userInfo);
+    else if ([messageName isEqualToString:WIRAutomaticInspectionRejectMessage])
+        receivedAutomaticInspectionRejectMessage(userInfo);
     else
         NSLog(@"Unrecognized RemoteInspector XPC Message: %@", messageName);
 }
@@ -309,6 +441,8 @@ void RemoteInspector::xpcConnectionFailed(RemoteInspectorXPCConnection* connecti
 
     updateHasActiveDebugSession();
 
+    m_automaticInspectionPaused = false;
+
     // The connection will close itself.
     m_xpcConnection = nullptr;
 }
@@ -408,6 +542,7 @@ void RemoteInspector::updateHasActiveDebugSession()
     // Legacy iOS WebKit 1 had a notification. This will need to be smarter with WebKit2.
 }
 
+
 #pragma mark - Received XPC Messages
 
 void RemoteInspector::receivedSetupMessage(NSDictionary *userInfo)
@@ -436,7 +571,14 @@ void RemoteInspector::receivedSetupMessage(NSDictionary *userInfo)
     RemoteInspectorDebuggable* debuggable = it->value.first;
     RemoteInspectorDebuggableInfo debuggableInfo = it->value.second;
     RefPtr<RemoteInspectorDebuggableConnection> connection = adoptRef(new RemoteInspectorDebuggableConnection(debuggable, connectionIdentifier, sender, debuggableInfo.type));
-    if (!connection->setup()) {
+    bool isAutomaticInspection = m_automaticInspectionCandidateIdentifier == debuggable->identifier();
+
+    bool automaticallyPause = false;
+    NSNumber *automaticallyPauseObject = [userInfo objectForKey:WIRAutomaticallyPause];
+    if ([automaticallyPauseObject isKindOfClass:[NSNumber class]])
+        automaticallyPause = [automaticallyPauseObject boolValue];
+
+    if (!connection->setup(isAutomaticInspection, automaticallyPause)) {
         connection->close();
         return;
     }
@@ -504,7 +646,7 @@ void RemoteInspector::receivedIndicateMessage(NSDictionary *userInfo)
     unsigned identifier = [pageId unsignedIntValue];
     BOOL indicateEnabled = [[userInfo objectForKey:WIRIndicateEnabledKey] boolValue];
 
-    dispatchAsyncOnQueueSafeForAnyDebuggable(^{
+    callOnWebThreadOrDispatchAsyncOnMainThread(^{
         RemoteInspectorDebuggable* debuggable = nullptr;
         {
             std::lock_guard<std::mutex> lock(m_mutex);
@@ -568,6 +710,23 @@ void RemoteInspector::receivedConnectionDiedMessage(NSDictionary *userInfo)
     updateHasActiveDebugSession();
 }
 
+void RemoteInspector::receivedAutomaticInspectionConfigurationMessage(NSDictionary *userInfo)
+{
+    m_automaticInspectionEnabled = [[userInfo objectForKey:WIRAutomaticInspectionEnabledKey] boolValue];
+
+    if (!m_automaticInspectionEnabled && m_automaticInspectionPaused)
+        m_automaticInspectionPaused = false;
+}
+
+void RemoteInspector::receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo)
+{
+    unsigned rejectionIdentifier = [[userInfo objectForKey:WIRPageIdentifierKey] unsignedIntValue];
+
+    ASSERT(rejectionIdentifier == m_automaticInspectionCandidateIdentifier);
+    if (rejectionIdentifier == m_automaticInspectionCandidateIdentifier)
+        m_automaticInspectionPaused = false;
+}
+
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)
index 647b22e1291945c3947107dd6de1f36f9dc13fc6..5d9ddbdd89c507210368e130760d242c42f9320c 100644 (file)
 #define WIRServiceAvailabilityCheckNotification "com.apple.webinspectord.availability_check"
 #define WIRServiceEnabledNotification           "com.apple.webinspectord.enabled"
 #define WIRServiceDisabledNotification          "com.apple.webinspectord.disabled"
+#define WIRAutomaticInspectionEnabledState      "com.apple.webinspectord.automatic_inspection_enabled"
 
 
 #define WIRApplicationIdentifierKey             @"WIRApplicationIdentifierKey"
 #define WIRApplicationBundleIdentifierKey       @"WIRApplicationBundleIdentifierKey"
 #define WIRApplicationNameKey                   @"WIRApplicationNameKey"
 #define WIRIsApplicationProxyKey                @"WIRIsApplicationProxyKey"
+#define WIRIsApplicationActiveKey               @"WIRIsApplicationActiveKey"
 #define WIRHostApplicationIdentifierKey         @"WIRHostApplicationIdentifierKey"
 #define WIRHostApplicationNameKey               @"WIRHostApplicationNameKey"
 #define WIRConnectionIdentifierKey              @"WIRConnectionIdentifierKey"
 #define WIRTypeKey                              @"WIRTypeKey"
 #define WIRTypeJavaScript                       @"WIRTypeJavaScript"
 #define WIRTypeWeb                              @"WIRTypeWeb"
+#define WIRAutomaticallyPause                   @"WIRAutomaticallyPause"
+
+#define WIRAutomaticInspectionEnabledKey           @"WIRAutomaticInspectionEnabledKey"
+#define WIRAutomaticInspectionSessionIdentifierKey @"WIRAutomaticInspectionSessionIdentifierKey"
+#define WIRAutomaticInspectionConfigurationMessage @"WIRAutomaticInspectionConfigurationMessage"
+#define WIRAutomaticInspectionRejectMessage        @"WIRAutomaticInspectionRejectMessage"
+#define WIRAutomaticInspectionCandidateMessage     @"WIRAutomaticInspectionCandidateMessage"
 
 // These definitions are shared with a Simulator webinspectord and
 // OS X process communicating with it.
index fdf1d96e712bafe8d6dd2526ebbee912d37df727..ac83a18e95995b1c3586fa7861071fcc4e5eb839 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(REMOTE_INSPECTOR)
 
+#include "EventLoop.h"
 #include "InspectorFrontendChannel.h"
 #include "RemoteInspector.h"
 
@@ -41,17 +42,17 @@ RemoteInspectorDebuggable::RemoteInspectorDebuggable()
 
 RemoteInspectorDebuggable::~RemoteInspectorDebuggable()
 {
-    RemoteInspector::shared().unregisterDebuggable(this);
+    RemoteInspector::singleton().unregisterDebuggable(this);
 }
 
 void RemoteInspectorDebuggable::init()
 {
-    RemoteInspector::shared().registerDebuggable(this);
+    RemoteInspector::singleton().registerDebuggable(this);
 }
 
 void RemoteInspectorDebuggable::update()
 {
-    RemoteInspector::shared().updateDebuggable(this);
+    RemoteInspector::singleton().updateDebuggable(this);
 }
 
 void RemoteInspectorDebuggable::setRemoteDebuggingAllowed(bool allowed)
@@ -61,7 +62,10 @@ void RemoteInspectorDebuggable::setRemoteDebuggingAllowed(bool allowed)
 
     m_allowed = allowed;
 
-    update();
+    if (m_allowed && automaticInspectionAllowed())
+        RemoteInspector::singleton().updateDebuggableAutomaticInspectCandidate(this);
+    else
+        RemoteInspector::singleton().updateDebuggable(this);
 }
 
 RemoteInspectorDebuggableInfo RemoteInspectorDebuggable::info() const
@@ -76,6 +80,22 @@ RemoteInspectorDebuggableInfo RemoteInspectorDebuggable::info() const
     return info;
 }
 
+void RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection()
+{
+    ASSERT(m_identifier);
+    ASSERT(m_allowed);
+    ASSERT(automaticInspectionAllowed());
+
+    EventLoop loop;
+    while (RemoteInspector::singleton().waitingForAutomaticInspection(identifier()) && !loop.ended())
+        loop.cycle();
+}
+
+void RemoteInspectorDebuggable::unpauseForInitializedInspector()
+{
+    RemoteInspector::singleton().setupCompleted(identifier());
+}
+
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)
index d4809688cf949690d2b38f8e448d1734b893ae36..064b83ae83838e1ab36e5e75f06f6f9750f08809 100644 (file)
@@ -34,7 +34,8 @@
 
 namespace Inspector {
 
-class InspectorFrontendChannel;
+class FrontendChannel;
+
 struct RemoteInspectorDebuggableInfo;
 
 class JS_EXPORT_PRIVATE RemoteInspectorDebuggable {
@@ -62,10 +63,15 @@ public:
     virtual String url() const { return String(); } // Web
     virtual bool hasLocalDebugger() const = 0;
 
-    virtual void connect(InspectorFrontendChannel*) = 0;
+    virtual void connect(FrontendChannel*, bool isAutomaticInspection) = 0;
     virtual void disconnect() = 0;
     virtual void dispatchMessageFromRemoteFrontend(const String& message) = 0;
     virtual void setIndicating(bool) { } // Default is to do nothing.
+    virtual void pause() { };
+
+    virtual bool automaticInspectionAllowed() const { return false; }
+    virtual void pauseWaitingForAutomaticInspection();
+    virtual void unpauseForInitializedInspector();
 
 private:
     unsigned m_identifier;
index 2bec437af201d63e50cd8e4950952ded6f5292f3..cedb7abfafa4f851e1c0f732968a3ea754aada7a 100644 (file)
@@ -30,7 +30,6 @@
 
 #import "InspectorFrontendChannel.h"
 #import "RemoteInspectorDebuggable.h"
-#import <dispatch/dispatch.h>
 #import <mutex>
 #import <wtf/RetainPtr.h>
 #import <wtf/ThreadSafeRefCounted.h>
@@ -75,7 +74,7 @@ private:
 
 typedef Vector<RemoteInspectorBlock> RemoteInspectorQueue;
 
-class RemoteInspectorDebuggableConnection final : public ThreadSafeRefCounted<RemoteInspectorDebuggableConnection>, public InspectorFrontendChannel {
+class RemoteInspectorDebuggableConnection final : public ThreadSafeRefCounted<RemoteInspectorDebuggableConnection>, public FrontendChannel {
 public:
     RemoteInspectorDebuggableConnection(RemoteInspectorDebuggable*, NSString *connectionIdentifier, NSString *destination, RemoteInspectorDebuggable::DebuggableType);
     virtual ~RemoteInspectorDebuggableConnection();
@@ -84,7 +83,7 @@ public:
     NSString *connectionIdentifier() const;
     unsigned identifier() const { return m_identifier; }
 
-    bool setup();
+    bool setup(bool isAutomaticInspection, bool automaticallyPause);
 
     void close();
     void closeFromDebuggable();
index 9b2d0089df1ff6f92b6dd825d776d7fcce8afae6..0821266d88f929a267e16c58c511075ecc1328f4 100644 (file)
@@ -30,6 +30,7 @@
 
 #import "EventLoop.h"
 #import "RemoteInspector.h"
+#import <dispatch/dispatch.h>
 #import <wtf/Vector.h>
 
 #if PLATFORM(IOS)
@@ -83,7 +84,7 @@ static void RemoteInspectorInitializeGlobalQueue()
         rwiQueueMutex = std::make_unique<std::mutex>().release();
 
         CFRunLoopSourceContext runLoopSourceContext = {0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, RemoteInspectorHandleRunSourceGlobal};
-        rwiRunLoopSource = CFRunLoopSourceCreate(nullptr, 1, &runLoopSourceContext);
+        rwiRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 1, &runLoopSourceContext);
 
         // Add to the default run loop mode for default handling, and the JSContext remote inspector run loop mode when paused.
         CFRunLoopAddSource(CFRunLoopGetMain(), rwiRunLoopSource, kCFRunLoopDefaultMode);
@@ -149,7 +150,7 @@ void RemoteInspectorDebuggableConnection::dispatchAsyncOnDebuggable(void (^block
     RemoteInspectorQueueTaskOnGlobalQueue(block);
 }
 
-bool RemoteInspectorDebuggableConnection::setup()
+bool RemoteInspectorDebuggableConnection::setup(bool isAutomaticInspection, bool automaticallyPause)
 {
     std::lock_guard<std::mutex> lock(m_debuggableMutex);
 
@@ -161,11 +162,14 @@ bool RemoteInspectorDebuggableConnection::setup()
         {
             std::lock_guard<std::mutex> lock(m_debuggableMutex);
             if (!m_debuggable || !m_debuggable->remoteDebuggingAllowed() || m_debuggable->hasLocalDebugger()) {
-                RemoteInspector::shared().setupFailed(identifier());
+                RemoteInspector::singleton().setupFailed(identifier());
                 m_debuggable = nullptr;
             } else {
-                m_debuggable->connect(this);
+                m_debuggable->connect(this, isAutomaticInspection);
                 m_connected = true;
+
+                if (automaticallyPause)
+                    m_debuggable->pause();
             }
         }
         deref();
@@ -220,7 +224,7 @@ void RemoteInspectorDebuggableConnection::sendMessageToBackend(NSString *message
 
 bool RemoteInspectorDebuggableConnection::sendMessageToFrontend(const String& message)
 {
-    RemoteInspector::shared().sendMessageToRemoteFrontend(identifier(), message);
+    RemoteInspector::singleton().sendMessageToRemoteFrontend(identifier(), message);
 
     return true;
 }
@@ -236,7 +240,7 @@ void RemoteInspectorDebuggableConnection::setupRunLoop()
     m_runLoop = debuggerRunLoop;
 
     CFRunLoopSourceContext runLoopSourceContext = {0, this, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, RemoteInspectorHandleRunSourceWithInfo};
-    m_runLoopSource = CFRunLoopSourceCreate(nullptr, 1, &runLoopSourceContext);
+    m_runLoopSource = adoptCF(CFRunLoopSourceCreate(kCFAllocatorDefault, 1, &runLoopSourceContext));
 
     CFRunLoopAddSource(m_runLoop.get(), m_runLoopSource.get(), kCFRunLoopDefaultMode);
     CFRunLoopAddSource(m_runLoop.get(), m_runLoopSource.get(), EventLoop::remoteInspectorRunLoopMode());
index f1fe819ce707635bfe504a5f880088d631230fb6..023db2bf621d29fa8415fa3256cff4454721e91c 100644 (file)
@@ -31,7 +31,7 @@
 #import <dispatch/dispatch.h>
 #import <mutex>
 #import <wtf/ThreadSafeRefCounted.h>
-#import <xpc/xpc.h>
+#import <wtf/spi/darwin/XPCSPI.h>
 
 OBJC_CLASS NSDictionary;
 OBJC_CLASS NSString;
index af1ccc51c3f861143859b8df943b287c9ecd0385..6c337d84ddf3dc012bc30ad59dfbf3212dd6eb51 100644 (file)
 #import <Foundation/Foundation.h>
 #import <wtf/Assertions.h>
 #import <wtf/Ref.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/spi/darwin/XPCSPI.h>
 
 #if __has_include(<CoreFoundation/CFXPCBridge.h>)
 #import <CoreFoundation/CFXPCBridge.h>
 #else
-extern "C" xpc_object_t _CFXPCCreateXPCMessageWithCFObject(CFTypeRef);
-extern "C" CFTypeRef _CFXPCCreateCFObjectFromXPCMessage(xpc_object_t);
+extern "C" {
+    xpc_object_t _CFXPCCreateXPCMessageWithCFObject(CFTypeRef);
+    CFTypeRef _CFXPCCreateCFObjectFromXPCMessage(xpc_object_t);
+}
 #endif
 
 namespace Inspector {
@@ -96,12 +100,12 @@ void RemoteInspectorXPCConnection::closeOnQueue()
     if (m_connection) {
         xpc_connection_cancel(m_connection);
         xpc_release(m_connection);
-        m_connection = NULL;
+        m_connection = nullptr;
     }
 
     if (m_queue) {
         dispatch_release(m_queue);
-        m_queue = NULL;
+        m_queue = nullptr;
     }
 }
 
@@ -118,9 +122,9 @@ NSDictionary *RemoteInspectorXPCConnection::deserializeMessage(xpc_object_t obje
         return nil;
     }
 
-    NSDictionary *dictionary = static_cast<NSDictionary *>(_CFXPCCreateCFObjectFromXPCMessage(xpcDictionary));
+    RetainPtr<CFDictionaryRef> dictionary = adoptCF((CFDictionaryRef)_CFXPCCreateCFObjectFromXPCMessage(xpcDictionary));
     ASSERT_WITH_MESSAGE(dictionary, "Unable to deserialize xpc message");
-    return [dictionary autorelease];
+    return (NSDictionary *)dictionary.autorelease();
 }
 
 void RemoteInspectorXPCConnection::handleEvent(xpc_object_t object)
@@ -170,7 +174,7 @@ void RemoteInspectorXPCConnection::sendMessage(NSString *messageName, NSDictiona
     if (!xpcDictionary)
         return;
 
-    xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0);
+    xpc_object_t msg = xpc_dictionary_create(nullptr, nullptr, 0);
     xpc_dictionary_set_value(msg, RemoteInspectorXPCConnectionSerializedMessageKey, xpcDictionary);
     xpc_release(xpcDictionary);
 
diff --git a/inspector/scripts/CodeGeneratorInspector.py b/inspector/scripts/CodeGeneratorInspector.py
deleted file mode 100755 (executable)
index 91fa8c9..0000000
+++ /dev/null
@@ -1,2614 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 Google Inc. All rights reserved.
-# Copyright (c) 2012 Intel Corporation. All rights reserved.
-# Copyright (c) 2013 Apple Inc. All Rights Reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os.path
-import sys
-import string
-import optparse
-import re
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-import CodeGeneratorInspectorStrings
-
-
-DOMAIN_DEFINE_NAME_MAP = {
-    "Database": "SQL_DATABASE",
-    "IndexedDB": "INDEXED_DATABASE",
-    "Replay": "WEB_REPLAY",
-}
-
-
-# Manually-filled map of type name replacements.
-TYPE_NAME_FIX_MAP = {
-    "RGBA": "Rgba",  # RGBA is reported to be conflicting with a define name in Windows CE.
-    "": "Empty",
-}
-
-
-TYPES_WITH_RUNTIME_CAST_SET = frozenset(["Runtime.RemoteObject", "Runtime.PropertyDescriptor", "Runtime.InternalPropertyDescriptor",
-                                         "Debugger.FunctionDetails", "Debugger.CallFrame",
-                                         "Canvas.TraceLog", "Canvas.ResourceInfo", "Canvas.ResourceState",
-                                         # This should be a temporary hack. TimelineEvent should be created via generated C++ API.
-                                         "Timeline.TimelineEvent"])
-
-TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset(["Timeline.TimelineEvent",
-                                            # InspectorStyleSheet not only creates this property but wants to read it and modify it.
-                                            "CSS.CSSProperty",
-                                            # InspectorResourceAgent needs to update mime-type.
-                                            "Network.Response"])
-
-EXACTLY_INT_SUPPORTED = False
-
-INSPECTOR_TYPES_GENERATOR_CONFIG_MAP = {
-    "JavaScript": {
-        "prefix": "JS",
-        "typebuilder_dependency": "",
-        "export_macro": "JS_EXPORT_PRIVATE",
-    },
-    "Web": {
-        "prefix": "Web",
-        "typebuilder_dependency": "#include <inspector/InspectorJSTypeBuilders.h>",
-        "export_macro": "",
-    },
-}
-
-cmdline_parser = optparse.OptionParser(usage="usage: %prog [options] <Inspector.json>")
-cmdline_parser.add_option("--output_h_dir")
-cmdline_parser.add_option("--output_cpp_dir")
-cmdline_parser.add_option("--output_js_dir")
-cmdline_parser.add_option("--output_type")  # JavaScript, Web
-cmdline_parser.add_option("--write_always", action="store_true")
-cmdline_parser.add_option("--no_verification", action="store_true")
-
-try:
-    arg_options, arg_values = cmdline_parser.parse_args()
-    if (len(arg_values) < 1):
-        raise Exception("At least one plain argument expected")
-
-    input_json_filename = arg_values[0]
-    dependency_json_filenames = arg_values[1:]
-
-    output_header_dirname = arg_options.output_h_dir
-    output_cpp_dirname = arg_options.output_cpp_dir
-    output_js_dirname = arg_options.output_js_dir
-    output_type = arg_options.output_type
-
-    write_always = arg_options.write_always
-    verification = not arg_options.no_verification
-    if not output_header_dirname:
-        raise Exception("Output .h directory must be specified")
-    if not output_cpp_dirname:
-        raise Exception("Output .cpp directory must be specified")
-    if not output_js_dirname:
-        raise Exception("Output .js directory must be specified")
-    if output_type not in INSPECTOR_TYPES_GENERATOR_CONFIG_MAP.keys():
-        raise Exception("Unknown output type. Allowed types are: %s" % INSPECTOR_TYPES_GENERATOR_CONFIG_MAP.keys())
-except Exception:
-    # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
-    exc = sys.exc_info()[1]
-    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
-    sys.stderr.write("Usage: <script> Inspector.json --output_h_dir <output_header_dir> --output_cpp_dir <output_cpp_dir> --output_js_dir <output_js_dir> [--write_always] [--no_verification]\n")
-    exit(1)
-
-
-def dash_to_camelcase(word):
-    return ''.join(x.capitalize() or '-' for x in word.split('-'))
-
-
-def fix_camel_case(name):
-    refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
-    refined = to_title_case(refined)
-    return re.sub(r'(?i)HTML|XML|WML|API|GC|XHR|DOM|CSS', lambda pat: pat.group(0).upper(), refined)
-
-
-def to_title_case(name):
-    return name[:1].upper() + name[1:]
-
-
-class Capitalizer:
-    @staticmethod
-    def lower_camel_case_to_upper(str):
-        if len(str) > 0 and str[0].islower():
-            str = str[0].upper() + str[1:]
-        return str
-
-    @staticmethod
-    def upper_camel_case_to_lower(str):
-        pos = 0
-        while pos < len(str) and str[pos].isupper():
-            pos += 1
-        if pos == 0:
-            return str
-        if pos == 1:
-            return str[0].lower() + str[1:]
-        if pos < len(str):
-            pos -= 1
-        possible_abbreviation = str[0:pos]
-        if possible_abbreviation not in Capitalizer.ABBREVIATION:
-            raise Exception("Unknown abbreviation %s" % possible_abbreviation)
-        str = possible_abbreviation.lower() + str[pos:]
-        return str
-
-    @staticmethod
-    def camel_case_to_capitalized_with_underscores(str):
-        if len(str) == 0:
-            return str
-        output = Capitalizer.split_camel_case_(str)
-        return "_".join(output).upper()
-
-    @staticmethod
-    def split_camel_case_(str):
-        output = []
-        pos_being = 0
-        pos = 1
-        has_oneletter = False
-        while pos < len(str):
-            if str[pos].isupper():
-                output.append(str[pos_being:pos].upper())
-                if pos - pos_being == 1:
-                    has_oneletter = True
-                pos_being = pos
-            pos += 1
-        output.append(str[pos_being:])
-        if has_oneletter:
-            array_pos = 0
-            while array_pos < len(output) - 1:
-                if len(output[array_pos]) == 1:
-                    array_pos_end = array_pos + 1
-                    while array_pos_end < len(output) and len(output[array_pos_end]) == 1:
-                        array_pos_end += 1
-                    if array_pos_end - array_pos > 1:
-                        possible_abbreviation = "".join(output[array_pos:array_pos_end])
-                        if possible_abbreviation.upper() in Capitalizer.ABBREVIATION:
-                            output[array_pos:array_pos_end] = [possible_abbreviation]
-                        else:
-                            array_pos = array_pos_end - 1
-                array_pos += 1
-        return output
-
-    ABBREVIATION = frozenset(["XHR", "DOM", "CSS"])
-
-VALIDATOR_IFDEF_NAME = "!ASSERT_DISABLED"
-
-
-class DomainNameFixes:
-    @classmethod
-    def get_fixed_data(cls, domain_name):
-        field_name_res = Capitalizer.upper_camel_case_to_lower(domain_name) + "Agent"
-
-        class Res(object):
-            skip_js_bind = domain_name in cls.skip_js_bind_domains
-
-            @staticmethod
-            def get_guard():
-                if domain_name in DOMAIN_DEFINE_NAME_MAP:
-                    define_name = DOMAIN_DEFINE_NAME_MAP[domain_name]
-
-                    class Guard:
-                        @staticmethod
-                        def generate_open(output):
-                            output.append("#if ENABLE(%s)\n" % define_name)
-
-                        @staticmethod
-                        def generate_close(output):
-                            output.append("#endif // ENABLE(%s)\n" % define_name)
-
-                    return Guard
-
-        return Res
-
-    skip_js_bind_domains = set(["DOMDebugger"])
-
-
-class RawTypes(object):
-    @staticmethod
-    def get(json_type):
-        if json_type == "boolean":
-            return RawTypes.Bool
-        elif json_type == "string":
-            return RawTypes.String
-        elif json_type == "array":
-            return RawTypes.Array
-        elif json_type == "object":
-            return RawTypes.Object
-        elif json_type == "integer":
-            return RawTypes.Int
-        elif json_type == "number":
-            return RawTypes.Number
-        elif json_type == "any":
-            return RawTypes.Any
-        else:
-            raise Exception("Unknown type: %s" % json_type)
-
-    # For output parameter all values are passed by pointer except RefPtr-based types.
-    class OutputPassModel:
-        class ByPointer:
-            @staticmethod
-            def get_argument_prefix():
-                return "&"
-
-            @staticmethod
-            def get_parameter_type_suffix():
-                return "*"
-
-        class ByReference:
-            @staticmethod
-            def get_argument_prefix():
-                return ""
-
-            @staticmethod
-            def get_parameter_type_suffix():
-                return "&"
-
-    class BaseType(object):
-        need_internal_runtime_cast_ = False
-
-        @classmethod
-        def request_raw_internal_runtime_cast(cls):
-            if not cls.need_internal_runtime_cast_:
-                cls.need_internal_runtime_cast_ = True
-
-        @classmethod
-        def get_raw_validator_call_text(cls):
-            return "RuntimeCastHelper::assertType<Inspector::InspectorValue::Type%s>" % cls.get_validate_method_params().template_type
-
-    class String(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "String"
-
-        get_setter_name = get_getter_name
-
-        @staticmethod
-        def get_c_initializer():
-            return "\"\""
-
-        @staticmethod
-        def get_js_bind_type():
-            return "string"
-
-        @staticmethod
-        def get_validate_method_params():
-            class ValidateMethodParams:
-                template_type = "String"
-            return ValidateMethodParams
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByPointer
-
-        @staticmethod
-        def is_heavy_value():
-            return True
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "String"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.String
-
-    class Int(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Int"
-
-        @staticmethod
-        def get_setter_name():
-            return "Number"
-
-        @staticmethod
-        def get_c_initializer():
-            return "0"
-
-        @staticmethod
-        def get_js_bind_type():
-            return "number"
-
-        @classmethod
-        def get_raw_validator_call_text(cls):
-            return "RuntimeCastHelper::assertInt"
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByPointer
-
-        @staticmethod
-        def is_heavy_value():
-            return False
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "int"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Int
-
-    class Number(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Double"
-
-        @staticmethod
-        def get_setter_name():
-            return "Number"
-
-        @staticmethod
-        def get_c_initializer():
-            return "0"
-
-        @staticmethod
-        def get_js_bind_type():
-            return "number"
-
-        @staticmethod
-        def get_validate_method_params():
-            class ValidateMethodParams:
-                template_type = "Number"
-            return ValidateMethodParams
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByPointer
-
-        @staticmethod
-        def is_heavy_value():
-            return False
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "double"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Number
-
-    class Bool(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Boolean"
-
-        get_setter_name = get_getter_name
-
-        @staticmethod
-        def get_c_initializer():
-            return "false"
-
-        @staticmethod
-        def get_js_bind_type():
-            return "boolean"
-
-        @staticmethod
-        def get_validate_method_params():
-            class ValidateMethodParams:
-                template_type = "Boolean"
-            return ValidateMethodParams
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByPointer
-
-        @staticmethod
-        def is_heavy_value():
-            return False
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "bool"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Bool
-
-    class Object(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Object"
-
-        @staticmethod
-        def get_setter_name():
-            return "Value"
-
-        @staticmethod
-        def get_c_initializer():
-            return "InspectorObject::create()"
-
-        @staticmethod
-        def get_js_bind_type():
-            return "object"
-
-        @staticmethod
-        def get_output_argument_prefix():
-            return ""
-
-        @staticmethod
-        def get_validate_method_params():
-            class ValidateMethodParams:
-                template_type = "Object"
-            return ValidateMethodParams
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByReference
-
-        @staticmethod
-        def is_heavy_value():
-            return True
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "Inspector::InspectorObject"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Object
-
-    class Any(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Value"
-
-        get_setter_name = get_getter_name
-
-        @staticmethod
-        def get_c_initializer():
-            raise Exception("Unsupported")
-
-        @staticmethod
-        def get_js_bind_type():
-            raise Exception("Unsupported")
-
-        @staticmethod
-        def get_raw_validator_call_text():
-            return "RuntimeCastHelper::assertAny"
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByReference
-
-        @staticmethod
-        def is_heavy_value():
-            return True
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "Inspector::InspectorValue"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Any
-
-    class Array(BaseType):
-        @staticmethod
-        def get_getter_name():
-            return "Array"
-
-        @staticmethod
-        def get_setter_name():
-            return "Value"
-
-        @staticmethod
-        def get_c_initializer():
-            return "InspectorArray::create()"
-
-        @staticmethod
-        def get_js_bind_type():
-            return "object"
-
-        @staticmethod
-        def get_output_argument_prefix():
-            return ""
-
-        @staticmethod
-        def get_validate_method_params():
-            class ValidateMethodParams:
-                template_type = "Array"
-            return ValidateMethodParams
-
-        @staticmethod
-        def get_output_pass_model():
-            return RawTypes.OutputPassModel.ByReference
-
-        @staticmethod
-        def is_heavy_value():
-            return True
-
-        @staticmethod
-        def get_array_item_raw_c_type_text():
-            return "Inspector::InspectorArray"
-
-        @staticmethod
-        def get_raw_type_model():
-            return TypeModel.Array
-
-
-def replace_right_shift(input_str):
-    return input_str.replace(">>", "> >")
-
-
-class CommandReturnPassModel:
-    class ByReference:
-        def __init__(self, var_type, set_condition):
-            self.var_type = var_type
-            self.set_condition = set_condition
-
-        def get_return_var_type(self):
-            return self.var_type
-
-        @staticmethod
-        def get_output_argument_prefix():
-            return ""
-
-        @staticmethod
-        def get_output_to_raw_expression():
-            return "%s"
-
-        def get_output_parameter_type(self):
-            return self.var_type + "&"
-
-        def get_set_return_condition(self):
-            return self.set_condition
-
-    class ByPointer:
-        def __init__(self, var_type):
-            self.var_type = var_type
-
-        def get_return_var_type(self):
-            return self.var_type
-
-        @staticmethod
-        def get_output_argument_prefix():
-            return "&"
-
-        @staticmethod
-        def get_output_to_raw_expression():
-            return "%s"
-
-        def get_output_parameter_type(self):
-            return self.var_type + "*"
-
-        @staticmethod
-        def get_set_return_condition():
-            return None
-
-    class OptOutput:
-        def __init__(self, var_type):
-            self.var_type = var_type
-
-        def get_return_var_type(self):
-            return "Inspector::TypeBuilder::OptOutput<%s>" % self.var_type
-
-        @staticmethod
-        def get_output_argument_prefix():
-            return "&"
-
-        @staticmethod
-        def get_output_to_raw_expression():
-            return "%s.getValue()"
-
-        def get_output_parameter_type(self):
-            return "Inspector::TypeBuilder::OptOutput<%s>*" % self.var_type
-
-        @staticmethod
-        def get_set_return_condition():
-            return "%s.isAssigned()"
-
-
-class TypeModel:
-    class RefPtrBased(object):
-        def __init__(self, class_name):
-            self.class_name = class_name
-            self.optional = False
-
-        def get_optional(self):
-            result = TypeModel.RefPtrBased(self.class_name)
-            result.optional = True
-            return result
-
-        def get_command_return_pass_model(self):
-            if self.optional:
-                set_condition = "%s"
-            else:
-                set_condition = None
-            return CommandReturnPassModel.ByReference(replace_right_shift("RefPtr<%s>" % self.class_name), set_condition)
-
-        def get_input_param_type_text(self):
-            return replace_right_shift("PassRefPtr<%s>" % self.class_name)
-
-        @staticmethod
-        def get_event_setter_expression_pattern():
-            return "%s"
-
-    class Enum(object):
-        def __init__(self, base_type_name):
-            self.type_name = base_type_name + "::Enum"
-
-        def get_optional(base_self):
-            class EnumOptional:
-                @classmethod
-                def get_optional(cls):
-                    return cls
-
-                @staticmethod
-                def get_command_return_pass_model():
-                    return CommandReturnPassModel.OptOutput(base_self.type_name)
-
-                @staticmethod
-                def get_input_param_type_text():
-                    return base_self.type_name + "*"
-
-                @staticmethod
-                def get_event_setter_expression_pattern():
-                    raise Exception("TODO")
-            return EnumOptional
-
-        def get_command_return_pass_model(self):
-            return CommandReturnPassModel.ByPointer(self.type_name)
-
-        def get_input_param_type_text(self):
-            return self.type_name
-
-        @staticmethod
-        def get_event_setter_expression_pattern():
-            return "%s"
-
-    class ValueType(object):
-        def __init__(self, type_name, is_heavy):
-            self.type_name = type_name
-            self.is_heavy = is_heavy
-
-        def get_optional(self):
-            return self.ValueOptional(self)
-
-        def get_command_return_pass_model(self):
-            return CommandReturnPassModel.ByPointer(self.type_name)
-
-        def get_input_param_type_text(self):
-            if self.is_heavy:
-                return "const %s&" % self.type_name
-            else:
-                return self.type_name
-
-        def get_opt_output_type_(self):
-            return self.type_name
-
-        @staticmethod
-        def get_event_setter_expression_pattern():
-            return "%s"
-
-        class ValueOptional:
-            def __init__(self, base):
-                self.base = base
-
-            def get_optional(self):
-                return self
-
-            def get_command_return_pass_model(self):
-                return CommandReturnPassModel.OptOutput(self.base.get_opt_output_type_())
-
-            def get_input_param_type_text(self):
-                return "const %s* const" % self.base.type_name
-
-            @staticmethod
-            def get_event_setter_expression_pattern():
-                return "*%s"
-
-    class ExactlyInt(ValueType):
-        def __init__(self):
-            TypeModel.ValueType.__init__(self, "int", False)
-
-        def get_input_param_type_text(self):
-            return "Inspector::TypeBuilder::ExactlyInt"
-
-        def get_opt_output_type_(self):
-            return "Inspector::TypeBuilder::ExactlyInt"
-
-    @classmethod
-    def init_class(cls):
-        cls.Bool = cls.ValueType("bool", False)
-        if EXACTLY_INT_SUPPORTED:
-            cls.Int = cls.ExactlyInt()
-        else:
-            cls.Int = cls.ValueType("int", False)
-        cls.Number = cls.ValueType("double", False)
-        cls.String = cls.ValueType("String", True,)
-        cls.Object = cls.RefPtrBased("Inspector::InspectorObject")
-        cls.Array = cls.RefPtrBased("Inspector::InspectorArray")
-        cls.Any = cls.RefPtrBased("Inspector::InspectorValue")
-
-TypeModel.init_class()
-
-
-# Collection of InspectorObject class methods that are likely to be overloaded in generated class.
-# We must explicitly import all overloaded methods or they won't be available to user.
-INSPECTOR_OBJECT_SETTER_NAMES = frozenset(["setValue", "setBoolean", "setNumber", "setString", "setValue", "setObject", "setArray"])
-
-
-def fix_type_name(json_name):
-    if json_name in TYPE_NAME_FIX_MAP:
-        fixed = TYPE_NAME_FIX_MAP[json_name]
-
-        class Result(object):
-            class_name = fixed
-
-            @staticmethod
-            def output_comment(writer):
-                writer.newline("// Type originally was named '%s'.\n" % json_name)
-    else:
-
-        class Result(object):
-            class_name = json_name
-
-            @staticmethod
-            def output_comment(writer):
-                pass
-
-    return Result
-
-
-class Writer:
-    def __init__(self, output, indent):
-        self.output = output
-        self.indent = indent
-
-    def newline(self, str):
-        if (self.indent):
-            self.output.append(self.indent)
-        self.output.append(str)
-
-    def append(self, str):
-        self.output.append(str)
-
-    def newline_multiline(self, str):
-        parts = str.split('\n')
-        self.newline(parts[0])
-        for p in parts[1:]:
-            self.output.append('\n')
-            if p:
-                self.newline(p)
-
-    def append_multiline(self, str):
-        parts = str.split('\n')
-        self.append(parts[0])
-        for p in parts[1:]:
-            self.output.append('\n')
-            if p:
-                self.newline(p)
-
-    def get_indent(self):
-        return self.indent
-
-    def get_indented(self, additional_indent):
-        return Writer(self.output, self.indent + additional_indent)
-
-    def insert_writer(self, additional_indent):
-        new_output = []
-        self.output.append(new_output)
-        return Writer(new_output, self.indent + additional_indent)
-
-
-class EnumConstants:
-    map_ = {}
-    constants_ = []
-
-    @classmethod
-    def add_constant(cls, value):
-        if value in cls.map_:
-            return cls.map_[value]
-        else:
-            pos = len(cls.map_)
-            cls.map_[value] = pos
-            cls.constants_.append(value)
-            return pos
-
-    @classmethod
-    def get_enum_constant_code(cls):
-        output = []
-        for item in cls.constants_:
-            output.append("    \"" + item + "\"")
-        return ",\n".join(output) + "\n"
-
-
-# Typebuilder code is generated in several passes: first typedefs, then other classes.
-# Manual pass management is needed because we cannot have forward declarations for typedefs.
-class TypeBuilderPass:
-    TYPEDEF = "typedef"
-    MAIN = "main"
-
-
-class TypeBindings:
-    @staticmethod
-    def create_named_type_declaration(json_typable, context_domain_name, type_data):
-        json_type = type_data.get_json_type()
-
-        class Helper:
-            is_ad_hoc = False
-            full_name_prefix_for_use = "Inspector::TypeBuilder::" + context_domain_name + "::"
-            full_name_prefix_for_impl = "Inspector::TypeBuilder::" + context_domain_name + "::"
-
-            @staticmethod
-            def write_doc(writer):
-                if "description" in json_type:
-                    writer.newline("/* ")
-                    writer.append(json_type["description"])
-                    writer.append(" */\n")
-
-            @staticmethod
-            def add_to_forward_listener(forward_listener):
-                forward_listener.add_type_data(type_data)
-
-
-        fixed_type_name = fix_type_name(json_type["id"])
-        return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)
-
-    @staticmethod
-    def create_ad_hoc_type_declaration(json_typable, context_domain_name, ad_hoc_type_context):
-        class Helper:
-            is_ad_hoc = True
-            full_name_prefix_for_use = ad_hoc_type_context.container_relative_name_prefix
-            full_name_prefix_for_impl = ad_hoc_type_context.container_full_name_prefix
-
-            @staticmethod
-            def write_doc(writer):
-                pass
-
-            @staticmethod
-            def add_to_forward_listener(forward_listener):
-                pass
-        fixed_type_name = ad_hoc_type_context.get_type_name_fix()
-        return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)
-
-    @staticmethod
-    def create_type_declaration_(json_typable, context_domain_name, fixed_type_name, helper):
-        if json_typable["type"] == "string":
-            if "enum" in json_typable:
-
-                class EnumBinding:
-                    need_user_runtime_cast_ = False
-                    need_internal_runtime_cast_ = False
-
-                    @classmethod
-                    def resolve_inner(cls, resolve_context):
-                        pass
-
-                    @classmethod
-                    def request_user_runtime_cast(cls, request):
-                        if request:
-                            cls.need_user_runtime_cast_ = True
-                            request.acknowledge()
-
-                    @classmethod
-                    def request_internal_runtime_cast(cls):
-                        cls.need_internal_runtime_cast_ = True
-
-                    @classmethod
-                    def get_code_generator(enum_binding_cls):
-                        #FIXME: generate ad-hoc enums too once we figure out how to better implement them in C++.
-                        comment_out = helper.is_ad_hoc
-
-                        class CodeGenerator:
-                            @staticmethod
-                            def generate_type_builder(writer, generate_context):
-                                enum = json_typable["enum"]
-                                helper.write_doc(writer)
-                                enum_name = fixed_type_name.class_name
-                                fixed_type_name.output_comment(writer)
-                                writer.newline("struct ")
-                                writer.append(enum_name)
-                                writer.append(" {\n")
-                                writer.newline("    enum Enum {\n")
-                                for enum_item in enum:
-                                    enum_pos = EnumConstants.add_constant(enum_item)
-
-                                    item_c_name = fix_camel_case(enum_item)
-                                    if item_c_name in TYPE_NAME_FIX_MAP:
-                                        item_c_name = TYPE_NAME_FIX_MAP[item_c_name]
-                                    writer.newline("        ")
-                                    writer.append(item_c_name)
-                                    writer.append(" = ")
-                                    writer.append("%s" % enum_pos)
-                                    writer.append(",\n")
-                                writer.newline("    };\n")
-                                if enum_binding_cls.need_user_runtime_cast_:
-                                    raise Exception("Not yet implemented")
-
-                                if enum_binding_cls.need_internal_runtime_cast_:
-                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
-                                    writer.newline("    static void assertCorrectValue(Inspector::InspectorValue* value);\n")
-                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)
-
-                                    validator_writer = generate_context.validator_writer
-
-                                    domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)
-                                    domain_guard = domain_fixes.get_guard()
-                                    if domain_guard:
-                                        domain_guard.generate_open(validator_writer)
-
-                                    validator_writer.newline("void %s%s::assertCorrectValue(Inspector::InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, enum_name))
-                                    validator_writer.newline("{\n")
-                                    validator_writer.newline("    WTF::String s;\n")
-                                    validator_writer.newline("    bool cast_res = value->asString(&s);\n")
-                                    validator_writer.newline("    ASSERT(cast_res);\n")
-                                    if len(enum) > 0:
-                                        condition_list = []
-                                        for enum_item in enum:
-                                            enum_pos = EnumConstants.add_constant(enum_item)
-                                            condition_list.append("s == \"%s\"" % enum_item)
-                                        validator_writer.newline("    ASSERT(%s);\n" % " || ".join(condition_list))
-                                    validator_writer.newline("}\n")
-
-                                    if domain_guard:
-                                        domain_guard.generate_close(validator_writer)
-
-                                    validator_writer.newline("\n\n")
-
-                                writer.newline("}; // struct ")
-                                writer.append(enum_name)
-                                writer.append("\n")
-
-                            @staticmethod
-                            def register_use(forward_listener):
-                                pass
-
-                            @staticmethod
-                            def get_generate_pass_id():
-                                return TypeBuilderPass.MAIN
-
-                        return CodeGenerator
-
-                    @classmethod
-                    def get_validator_call_text(cls):
-                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"
-
-                    @classmethod
-                    def get_array_item_c_type_text(cls):
-                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::Enum"
-
-                    @staticmethod
-                    def get_setter_value_expression_pattern():
-                        return "Inspector::TypeBuilder::get%sEnumConstantValue(%s)"
-
-                    @staticmethod
-                    def reduce_to_raw_type():
-                        return RawTypes.String
-
-                    @staticmethod
-                    def get_type_model():
-                        return TypeModel.Enum(helper.full_name_prefix_for_use + fixed_type_name.class_name)
-
-                return EnumBinding
-            else:
-                if helper.is_ad_hoc:
-
-                    class PlainString:
-                        @classmethod
-                        def resolve_inner(cls, resolve_context):
-                            pass
-
-                        @staticmethod
-                        def request_user_runtime_cast(request):
-                            raise Exception("Unsupported")
-
-                        @staticmethod
-                        def request_internal_runtime_cast():
-                            pass
-
-                        @staticmethod
-                        def get_code_generator():
-                            return None
-
-                        @classmethod
-                        def get_validator_call_text(cls):
-                            return RawTypes.String.get_raw_validator_call_text()
-
-                        @staticmethod
-                        def reduce_to_raw_type():
-                            return RawTypes.String
-
-                        @staticmethod
-                        def get_type_model():
-                            return TypeModel.String
-
-                        @staticmethod
-                        def get_setter_value_expression_pattern():
-                            return None
-
-                        @classmethod
-                        def get_array_item_c_type_text(cls):
-                            return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()
-
-                    return PlainString
-
-                else:
-
-                    class TypedefString:
-                        @classmethod
-                        def resolve_inner(cls, resolve_context):
-                            pass
-
-                        @staticmethod
-                        def request_user_runtime_cast(request):
-                            raise Exception("Unsupported")
-
-                        @staticmethod
-                        def request_internal_runtime_cast():
-                            RawTypes.String.request_raw_internal_runtime_cast()
-
-                        @staticmethod
-                        def get_code_generator():
-                            class CodeGenerator:
-                                @staticmethod
-                                def generate_type_builder(writer, generate_context):
-                                    helper.write_doc(writer)
-                                    fixed_type_name.output_comment(writer)
-                                    writer.newline("typedef String ")
-                                    writer.append(fixed_type_name.class_name)
-                                    writer.append(";\n\n")
-
-                                @staticmethod
-                                def register_use(forward_listener):
-                                    pass
-
-                                @staticmethod
-                                def get_generate_pass_id():
-                                    return TypeBuilderPass.TYPEDEF
-
-                            return CodeGenerator
-
-                        @classmethod
-                        def get_validator_call_text(cls):
-                            return RawTypes.String.get_raw_validator_call_text()
-
-                        @staticmethod
-                        def reduce_to_raw_type():
-                            return RawTypes.String
-
-                        @staticmethod
-                        def get_type_model():
-                            return TypeModel.ValueType("%s%s" % (helper.full_name_prefix_for_use, fixed_type_name.class_name), True)
-
-                        @staticmethod
-                        def get_setter_value_expression_pattern():
-                            return None
-
-                        @classmethod
-                        def get_array_item_c_type_text(cls):
-                            return "const %s%s&" % (helper.full_name_prefix_for_use, fixed_type_name.class_name)
-
-                    return TypedefString
-
-        elif json_typable["type"] == "integer":
-                if helper.is_ad_hoc:
-
-                    class PlainInteger:
-                        @classmethod
-                        def resolve_inner(cls, resolve_context):
-                            pass
-
-                        @staticmethod
-                        def request_user_runtime_cast(request):
-                            raise Exception("Unsupported")
-
-                        @staticmethod
-                        def request_internal_runtime_cast():
-                            pass
-
-                        @staticmethod
-                        def get_code_generator():
-                            return None
-
-                        @classmethod
-                        def get_validator_call_text(cls):
-                            return RawTypes.Int.get_raw_validator_call_text()
-
-                        @staticmethod
-                        def reduce_to_raw_type():
-                            return RawTypes.Int
-
-                        @staticmethod
-                        def get_type_model():
-                            return TypeModel.Int
-
-                        @staticmethod
-                        def get_setter_value_expression_pattern():
-                            return None
-
-                        @classmethod
-                        def get_array_item_c_type_text(cls):
-                            return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()
-
-                    return PlainInteger
-
-                else:
-
-                    class TypedefInteger:
-                        @classmethod
-                        def resolve_inner(cls, resolve_context):
-                            pass
-
-                        @staticmethod
-                        def request_user_runtime_cast(request):
-                            raise Exception("Unsupported")
-
-                        @staticmethod
-                        def request_internal_runtime_cast():
-                            RawTypes.Int.request_raw_internal_runtime_cast()
-
-                        @staticmethod
-                        def get_code_generator():
-                            class CodeGenerator:
-                                @staticmethod
-                                def generate_type_builder(writer, generate_context):
-                                    helper.write_doc(writer)
-                                    fixed_type_name.output_comment(writer)
-                                    writer.newline("typedef int ")
-                                    writer.append(fixed_type_name.class_name)
-                                    writer.append(";\n\n")
-
-                                @staticmethod
-                                def register_use(forward_listener):
-                                    pass
-
-                                @staticmethod
-                                def get_generate_pass_id():
-                                    return TypeBuilderPass.TYPEDEF
-
-                            return CodeGenerator
-
-                        @classmethod
-                        def get_validator_call_text(cls):
-                            return RawTypes.Int.get_raw_validator_call_text()
-
-                        @staticmethod
-                        def reduce_to_raw_type():
-                            return RawTypes.Int
-
-                        @staticmethod
-                        def get_type_model():
-                            return TypeModel.Int
-
-                        @staticmethod
-                        def get_setter_value_expression_pattern():
-                            return None
-
-                        @classmethod
-                        def get_array_item_c_type_text(cls):
-                            return helper.full_name_prefix_for_use + fixed_type_name.class_name
-
-                    return TypedefInteger
-
-        elif json_typable["type"] == "object":
-            if "properties" in json_typable:
-
-                class ClassBinding:
-                    resolve_data_ = None
-                    need_user_runtime_cast_ = False
-                    need_internal_runtime_cast_ = False
-
-                    @classmethod
-                    def resolve_inner(cls, resolve_context):
-                        if cls.resolve_data_:
-                            return
-
-                        properties = json_typable["properties"]
-                        main = []
-                        optional = []
-
-                        ad_hoc_type_list = []
-
-                        for prop in properties:
-                            prop_name = prop["name"]
-                            ad_hoc_type_context = cls.AdHocTypeContextImpl(prop_name, fixed_type_name.class_name, resolve_context, ad_hoc_type_list, helper.full_name_prefix_for_impl)
-                            binding = resolve_param_type(prop, context_domain_name, ad_hoc_type_context)
-
-                            code_generator = binding.get_code_generator()
-                            if code_generator:
-                                code_generator.register_use(resolve_context.forward_listener)
-
-                            class PropertyData:
-                                param_type_binding = binding
-                                p = prop
-
-                            if prop.get("optional"):
-                                optional.append(PropertyData)
-                            else:
-                                main.append(PropertyData)
-
-                        class ResolveData:
-                            main_properties = main
-                            optional_properties = optional
-                            ad_hoc_types = ad_hoc_type_list
-
-                        cls.resolve_data_ = ResolveData
-
-                        for ad_hoc in ad_hoc_type_list:
-                            ad_hoc.resolve_inner(resolve_context)
-
-                    @classmethod
-                    def request_user_runtime_cast(cls, request):
-                        if not request:
-                            return
-                        cls.need_user_runtime_cast_ = True
-                        request.acknowledge()
-                        cls.request_internal_runtime_cast()
-
-                    @classmethod
-                    def request_internal_runtime_cast(cls):
-                        if cls.need_internal_runtime_cast_:
-                            return
-                        cls.need_internal_runtime_cast_ = True
-                        for p in cls.resolve_data_.main_properties:
-                            p.param_type_binding.request_internal_runtime_cast()
-                        for p in cls.resolve_data_.optional_properties:
-                            p.param_type_binding.request_internal_runtime_cast()
-
-                    @classmethod
-                    def get_code_generator(class_binding_cls):
-                        class CodeGenerator:
-                            @classmethod
-                            def generate_type_builder(cls, writer, generate_context):
-                                resolve_data = class_binding_cls.resolve_data_
-                                helper.write_doc(writer)
-                                class_name = fixed_type_name.class_name
-
-                                is_open_type = (context_domain_name + "." + class_name) in TYPES_WITH_OPEN_FIELD_LIST_SET
-
-                                fixed_type_name.output_comment(writer)
-                                writer.newline("class ")
-                                writer.append(class_name)
-                                writer.append(" : public ")
-                                if is_open_type:
-                                    writer.append("Inspector::InspectorObject")
-                                else:
-                                    writer.append("Inspector::InspectorObjectBase")
-                                writer.append(" {\n")
-                                writer.newline("public:\n")
-                                ad_hoc_type_writer = writer.insert_writer("    ")
-
-                                for ad_hoc_type in resolve_data.ad_hoc_types:
-                                    code_generator = ad_hoc_type.get_code_generator()
-                                    if code_generator:
-                                        code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)
-
-                                writer.newline_multiline(
-"""    enum {
-        NoFieldsSet = 0,
-""")
-
-                                state_enum_items = []
-                                if len(resolve_data.main_properties) > 0:
-                                    pos = 0
-                                    for prop_data in resolve_data.main_properties:
-                                        item_name = Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]) + "Set"
-                                        state_enum_items.append(item_name)
-                                        writer.newline("        %s = 1 << %s,\n" % (item_name, pos))
-                                        pos += 1
-                                    all_fields_set_value = "(" + (" | ".join(state_enum_items)) + ")"
-                                else:
-                                    all_fields_set_value = "0"
-
-                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_1
-                                                         % (all_fields_set_value, class_name, class_name))
-
-                                pos = 0
-                                for prop_data in resolve_data.main_properties:
-                                    prop_name = prop_data.p["name"]
-
-                                    param_type_binding = prop_data.param_type_binding
-                                    param_raw_type = param_type_binding.reduce_to_raw_type()
-
-                                    writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_2
-                                        % (state_enum_items[pos],
-                                           Capitalizer.lower_camel_case_to_upper(prop_name),
-                                           param_type_binding.get_type_model().get_input_param_type_text(),
-                                           state_enum_items[pos], prop_name,
-                                           param_raw_type.get_setter_name(), prop_name,
-                                           format_setter_value_expression(param_type_binding, "value"),
-                                           state_enum_items[pos]))
-
-                                    pos += 1
-
-                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_3
-                                                         % (class_name, class_name, class_name, class_name, class_name))
-
-                                writer.newline("    /*\n")
-                                writer.newline("     * Synthetic constructor:\n")
-                                writer.newline("     * RefPtr<%s> result = %s::create()" % (class_name, class_name))
-                                for prop_data in resolve_data.main_properties:
-                                    writer.append_multiline("\n     *     .set%s(...)" % Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]))
-                                writer.append_multiline(";\n     */\n")
-
-                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_4)
-
-                                writer.newline("    typedef Inspector::TypeBuilder::StructItemTraits ItemTraits;\n")
-
-                                for prop_data in resolve_data.optional_properties:
-                                    prop_name = prop_data.p["name"]
-                                    param_type_binding = prop_data.param_type_binding
-                                    setter_name = "set%s" % Capitalizer.lower_camel_case_to_upper(prop_name)
-
-                                    writer.append_multiline("\n    void %s" % setter_name)
-                                    writer.append("(%s value)\n" % param_type_binding.get_type_model().get_input_param_type_text())
-                                    writer.newline("    {\n")
-                                    writer.newline("        this->set%s(ASCIILiteral(\"%s\"), %s);\n"
-                                        % (param_type_binding.reduce_to_raw_type().get_setter_name(), prop_data.p["name"],
-                                           format_setter_value_expression(param_type_binding, "value")))
-                                    writer.newline("    }\n")
-
-
-                                    if setter_name in INSPECTOR_OBJECT_SETTER_NAMES:
-                                        writer.newline("    using Inspector::InspectorObjectBase::%s;\n\n" % setter_name)
-
-                                if class_binding_cls.need_user_runtime_cast_:
-                                    writer.newline("    static PassRefPtr<%s> runtimeCast(PassRefPtr<Inspector::InspectorValue> value)\n" % class_name)
-                                    writer.newline("    {\n")
-                                    writer.newline("        RefPtr<Inspector::InspectorObject> object;\n")
-                                    writer.newline("        bool castRes = value->asObject(&object);\n")
-                                    writer.newline("        ASSERT_UNUSED(castRes, castRes);\n")
-                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
-                                    writer.newline("        assertCorrectValue(object.get());\n")
-                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)
-                                    writer.newline("        COMPILE_ASSERT(sizeof(%s) == sizeof(Inspector::InspectorObjectBase), type_cast_problem);\n" % class_name)
-                                    writer.newline("        return static_cast<%s*>(static_cast<Inspector::InspectorObjectBase*>(object.get()));\n" % class_name)
-                                    writer.newline("    }\n")
-                                    writer.append("\n")
-
-                                if class_binding_cls.need_internal_runtime_cast_:
-                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
-                                    writer.newline("    static %s void assertCorrectValue(Inspector::InspectorValue* value);\n" % INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["export_macro"])
-                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)
-
-                                    closed_field_set = (context_domain_name + "." + class_name) not in TYPES_WITH_OPEN_FIELD_LIST_SET
-
-                                    validator_writer = generate_context.validator_writer
-
-                                    domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)
-                                    domain_guard = domain_fixes.get_guard()
-                                    if domain_guard:
-                                        domain_guard.generate_open(validator_writer)
-
-                                    validator_writer.newline("void %s%s::assertCorrectValue(Inspector::InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, class_name))
-                                    validator_writer.newline("{\n")
-                                    validator_writer.newline("    RefPtr<InspectorObject> object;\n")
-                                    validator_writer.newline("    bool castRes = value->asObject(&object);\n")
-                                    validator_writer.newline("    ASSERT_UNUSED(castRes, castRes);\n")
-                                    for prop_data in resolve_data.main_properties:
-                                        validator_writer.newline("    {\n")
-                                        it_name = "%sPos" % prop_data.p["name"]
-                                        validator_writer.newline("        InspectorObject::iterator %s;\n" % it_name)
-                                        validator_writer.newline("        %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
-                                        validator_writer.newline("        ASSERT(%s != object->end());\n" % it_name)
-                                        validator_writer.newline("        %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
-                                        validator_writer.newline("    }\n")
-
-                                    if closed_field_set:
-                                        validator_writer.newline("    int foundPropertiesCount = %s;\n" % len(resolve_data.main_properties))
-
-                                    for prop_data in resolve_data.optional_properties:
-                                        validator_writer.newline("    {\n")
-                                        it_name = "%sPos" % prop_data.p["name"]
-                                        validator_writer.newline("        InspectorObject::iterator %s;\n" % it_name)
-                                        validator_writer.newline("        %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
-                                        validator_writer.newline("        if (%s != object->end()) {\n" % it_name)
-                                        validator_writer.newline("            %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
-                                        if closed_field_set:
-                                            validator_writer.newline("            ++foundPropertiesCount;\n")
-                                        validator_writer.newline("        }\n")
-                                        validator_writer.newline("    }\n")
-
-                                    if closed_field_set:
-                                        validator_writer.newline("    if (foundPropertiesCount != object->size())\n")
-                                        validator_writer.newline("        FATAL(\"Unexpected properties in object: %s\\n\", object->toJSONString().ascii().data());\n")
-                                    validator_writer.newline("}\n")
-
-                                    if domain_guard:
-                                        domain_guard.generate_close(validator_writer)
-
-                                    validator_writer.newline("\n\n")
-
-                                if is_open_type:
-                                    cpp_writer = generate_context.cpp_writer
-                                    writer.append("\n")
-                                    writer.newline("    // Property names for type generated as open.\n")
-                                    for prop_data in resolve_data.main_properties + resolve_data.optional_properties:
-                                        prop_name = prop_data.p["name"]
-                                        prop_field_name = Capitalizer.lower_camel_case_to_upper(prop_name)
-                                        writer.newline("    static const char* %s;\n" % (prop_field_name))
-                                        cpp_writer.newline("const char* %s%s::%s = \"%s\";\n" % (helper.full_name_prefix_for_impl, class_name, prop_field_name, prop_name))
-
-
-                                writer.newline("};\n\n")
-
-                            @staticmethod
-                            def generate_forward_declaration(writer):
-                                class_name = fixed_type_name.class_name
-                                writer.newline("class ")
-                                writer.append(class_name)
-                                writer.append(";\n")
-
-                            @staticmethod
-                            def register_use(forward_listener):
-                                helper.add_to_forward_listener(forward_listener)
-
-                            @staticmethod
-                            def get_generate_pass_id():
-                                return TypeBuilderPass.MAIN
-
-                        return CodeGenerator
-
-                    @staticmethod
-                    def get_validator_call_text():
-                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"
-
-                    @classmethod
-                    def get_array_item_c_type_text(cls):
-                        return helper.full_name_prefix_for_use + fixed_type_name.class_name
-
-                    @staticmethod
-                    def get_setter_value_expression_pattern():
-                        return None
-
-                    @staticmethod
-                    def reduce_to_raw_type():
-                        return RawTypes.Object
-
-                    @staticmethod
-                    def get_type_model():
-                        return TypeModel.RefPtrBased(helper.full_name_prefix_for_use + fixed_type_name.class_name)
-
-                    class AdHocTypeContextImpl:
-                        def __init__(self, property_name, class_name, resolve_context, ad_hoc_type_list, parent_full_name_prefix):
-                            self.property_name = property_name
-                            self.class_name = class_name
-                            self.resolve_context = resolve_context
-                            self.ad_hoc_type_list = ad_hoc_type_list
-                            self.container_full_name_prefix = parent_full_name_prefix + class_name + "::"
-                            self.container_relative_name_prefix = ""
-
-                        def get_type_name_fix(self):
-                            class NameFix:
-                                class_name = Capitalizer.lower_camel_case_to_upper(self.property_name)
-
-                                @staticmethod
-                                def output_comment(writer):
-                                    writer.newline("// Named after property name '%s' while generating %s.\n" % (self.property_name, self.class_name))
-
-                            return NameFix
-
-                        def add_type(self, binding):
-                            self.ad_hoc_type_list.append(binding)
-
-                return ClassBinding
-            else:
-
-                class PlainObjectBinding:
-                    @classmethod
-                    def resolve_inner(cls, resolve_context):
-                        pass
-
-                    @staticmethod
-                    def request_user_runtime_cast(request):
-                        pass
-
-                    @staticmethod
-                    def request_internal_runtime_cast():
-                        RawTypes.Object.request_raw_internal_runtime_cast()
-
-                    @staticmethod
-                    def get_code_generator():
-                        pass
-
-                    @staticmethod
-                    def get_validator_call_text():
-                        return "RuntimeCastHelper::assertType<InspectorValue::TypeObject>"
-
-                    @classmethod
-                    def get_array_item_c_type_text(cls):
-                        return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()
-
-                    @staticmethod
-                    def get_setter_value_expression_pattern():
-                        return None
-
-                    @staticmethod
-                    def reduce_to_raw_type():
-                        return RawTypes.Object
-
-                    @staticmethod
-                    def get_type_model():
-                        return TypeModel.Object
-
-                return PlainObjectBinding
-        elif json_typable["type"] == "array":
-            if "items" in json_typable:
-
-                ad_hoc_types = []
-
-                class AdHocTypeContext:
-                    container_full_name_prefix = "<not yet defined>"
-                    container_relative_name_prefix = ""
-
-                    @staticmethod
-                    def get_type_name_fix():
-                        return fixed_type_name
-
-                    @staticmethod
-                    def add_type(binding):
-                        ad_hoc_types.append(binding)
-
-                item_binding = resolve_param_type(json_typable["items"], context_domain_name, AdHocTypeContext)
-
-                class ArrayBinding:
-                    resolve_data_ = None
-                    need_internal_runtime_cast_ = False
-
-                    @classmethod
-                    def resolve_inner(cls, resolve_context):
-                        if cls.resolve_data_:
-                            return
-
-                        class ResolveData:
-                            item_type_binding = item_binding
-                            ad_hoc_type_list = ad_hoc_types
-
-                        cls.resolve_data_ = ResolveData
-
-                        for t in ad_hoc_types:
-                            t.resolve_inner(resolve_context)
-
-                    @classmethod
-                    def request_user_runtime_cast(cls, request):
-                        raise Exception("Not implemented yet")
-
-                    @classmethod
-                    def request_internal_runtime_cast(cls):
-                        if cls.need_internal_runtime_cast_:
-                            return
-                        cls.need_internal_runtime_cast_ = True
-                        cls.resolve_data_.item_type_binding.request_internal_runtime_cast()
-
-                    @classmethod
-                    def get_code_generator(array_binding_cls):
-
-                        class CodeGenerator:
-                            @staticmethod
-                            def generate_type_builder(writer, generate_context):
-                                ad_hoc_type_writer = writer
-
-                                resolve_data = array_binding_cls.resolve_data_
-
-                                for ad_hoc_type in resolve_data.ad_hoc_type_list:
-                                    code_generator = ad_hoc_type.get_code_generator()
-                                    if code_generator:
-                                        code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)
-
-                            @staticmethod
-                            def generate_forward_declaration(writer):
-                                pass
-
-                            @staticmethod
-                            def register_use(forward_listener):
-                                item_code_generator = item_binding.get_code_generator()
-                                if item_code_generator:
-                                    item_code_generator.register_use(forward_listener)
-
-                            @staticmethod
-                            def get_generate_pass_id():
-                                return TypeBuilderPass.MAIN
-
-                        return CodeGenerator
-
-                    @classmethod
-                    def get_validator_call_text(cls):
-                        return cls.get_array_item_c_type_text() + "::assertCorrectValue"
-
-                    @classmethod
-                    def get_array_item_c_type_text(cls):
-                        return replace_right_shift("Inspector::TypeBuilder::Array<%s>" % cls.resolve_data_.item_type_binding.get_array_item_c_type_text())
-
-                    @staticmethod
-                    def get_setter_value_expression_pattern():
-                        return None
-
-                    @staticmethod
-                    def reduce_to_raw_type():
-                        return RawTypes.Array
-
-                    @classmethod
-                    def get_type_model(cls):
-                        return TypeModel.RefPtrBased(cls.get_array_item_c_type_text())
-
-                return ArrayBinding
-            else:
-                # Fall-through to raw type.
-                pass
-
-        raw_type = RawTypes.get(json_typable["type"])
-
-        return RawTypeBinding(raw_type)
-
-
-class RawTypeBinding:
-    def __init__(self, raw_type):
-        self.raw_type_ = raw_type
-
-    def resolve_inner(self, resolve_context):
-        pass
-
-    def request_user_runtime_cast(self, request):
-        raise Exception("Unsupported")
-
-    def request_internal_runtime_cast(self):
-        self.raw_type_.request_raw_internal_runtime_cast()
-
-    def get_code_generator(self):
-        return None
-
-    def get_validator_call_text(self):
-        return self.raw_type_.get_raw_validator_call_text()
-
-    def get_array_item_c_type_text(self):
-        return self.raw_type_.get_array_item_raw_c_type_text()
-
-    def get_setter_value_expression_pattern(self):
-        return None
-
-    def reduce_to_raw_type(self):
-        return self.raw_type_
-
-    def get_type_model(self):
-        return self.raw_type_.get_raw_type_model()
-
-
-class TypeData(object):
-    def __init__(self, json_type, json_domain, domain_data):
-        self.json_type_ = json_type
-        self.json_domain_ = json_domain
-        self.domain_data_ = domain_data
-
-        if "type" not in json_type:
-            raise Exception("Unknown type")
-
-        json_type_name = json_type["type"]
-        self.raw_type_ = RawTypes.get(json_type_name)
-        self.binding_being_resolved_ = False
-        self.binding_ = None
-
-    def get_raw_type(self):
-        return self.raw_type_
-
-    def get_binding(self):
-        if not self.binding_:
-            if self.binding_being_resolved_:
-                raise Exception("Type %s is already being resolved" % self.json_type_["type"])
-            # Resolve only lazily, because resolving one named type may require resolving some other named type.
-            self.binding_being_resolved_ = True
-            try:
-                self.binding_ = TypeBindings.create_named_type_declaration(self.json_type_, self.json_domain_["domain"], self)
-            finally:
-                self.binding_being_resolved_ = False
-
-        return self.binding_
-
-    def get_json_type(self):
-        return self.json_type_
-
-    def get_name(self):
-        return self.json_type_["id"]
-
-    def get_domain_name(self):
-        return self.json_domain_["domain"]
-
-
-class DomainData:
-    def __init__(self, json_domain):
-        self.json_domain = json_domain
-        self.types_ = []
-
-    def add_type(self, type_data):
-        self.types_.append(type_data)
-
-    def name(self):
-        return self.json_domain["domain"]
-
-    def types(self):
-        return self.types_
-
-
-class TypeMap:
-    def __init__(self, api, dependency_api):
-        self.map_ = {}
-        self.domains_ = []
-        self.domains_to_generate_ = []
-        for json_domain in api["domains"]:
-            self.add_domain(json_domain, True)
-        for json_domain in dependency_api["domains"]:
-            self.add_domain(json_domain, False)
-
-    def add_domain(self, json_domain, should_generate):
-        domain_name = json_domain["domain"]
-
-        domain_map = {}
-        self.map_[domain_name] = domain_map
-
-        domain_data = DomainData(json_domain)
-        self.domains_.append(domain_data)
-
-        if should_generate:
-            # FIXME: The order of types should not matter. The generated code should work regardless of the order of types.
-            if domain_name == "Page":
-                self.domains_to_generate_.insert(0, domain_data)
-            else:
-                self.domains_to_generate_.append(domain_data)
-
-        if "types" in json_domain:
-            for json_type in json_domain["types"]:
-                type_name = json_type["id"]
-                type_data = TypeData(json_type, json_domain, domain_data)
-                domain_map[type_name] = type_data
-                domain_data.add_type(type_data)
-
-    def domains(self):
-        return self.domains_
-
-    def domains_to_generate(self):
-        return self.domains_to_generate_
-
-    def get(self, domain_name, type_name):
-        return self.map_[domain_name][type_name]
-
-
-def resolve_param_type(json_parameter, scope_domain_name, ad_hoc_type_context):
-    if "$ref" in json_parameter:
-        json_ref = json_parameter["$ref"]
-        type_data = get_ref_data(json_ref, scope_domain_name)
-        return type_data.get_binding()
-    elif "type" in json_parameter:
-        result = TypeBindings.create_ad_hoc_type_declaration(json_parameter, scope_domain_name, ad_hoc_type_context)
-        ad_hoc_type_context.add_type(result)
-        return result
-    else:
-        raise Exception("Unknown type")
-
-
-def resolve_param_raw_type(json_parameter, scope_domain_name):
-    if "$ref" in json_parameter:
-        json_ref = json_parameter["$ref"]
-        type_data = get_ref_data(json_ref, scope_domain_name)
-        return type_data.get_raw_type()
-    elif "type" in json_parameter:
-        json_type = json_parameter["type"]
-        return RawTypes.get(json_type)
-    else:
-        raise Exception("Unknown type")
-
-
-def get_ref_data(json_ref, scope_domain_name):
-    dot_pos = json_ref.find(".")
-    if dot_pos == -1:
-        domain_name = scope_domain_name
-        type_name = json_ref
-    else:
-        domain_name = json_ref[:dot_pos]
-        type_name = json_ref[dot_pos + 1:]
-
-    return type_map.get(domain_name, type_name)
-
-
-input_file = open(input_json_filename, "r")
-json_string = input_file.read()
-json_api = json.loads(json_string)
-input_file.close()
-if not "domains" in json_api:
-    json_api = {"domains": [json_api]}
-
-dependency_api = {"domains": []}
-for dependency_json_filename in dependency_json_filenames:
-    dependency_input_file = open(dependency_json_filename, "r")
-    dependency_json_string = dependency_input_file.read()
-    dependency_json_api = json.loads(dependency_json_string)
-    dependency_input_file.close()
-    if not "domains" in dependency_json_api:
-        dependency_json_api = {"domains": [dependency_json_api]}
-    dependency_api["domains"] += dependency_json_api["domains"]
-
-
-class Templates:
-    def get_this_script_path_(absolute_path):
-        absolute_path = os.path.abspath(absolute_path)
-        components = []
-
-        def fill_recursive(path_part, depth):
-            if depth <= 0 or path_part == '/':
-                return
-            fill_recursive(os.path.dirname(path_part), depth - 1)
-            components.append(os.path.basename(path_part))
-
-        # Typical path is /Source/WebCore/inspector/CodeGeneratorInspector.py
-        # Let's take 4 components from the real path then.
-        fill_recursive(absolute_path, 4)
-
-        return "/".join(components)
-
-    file_header_ = ("// File is generated by %s\n\n" % get_this_script_path_(sys.argv[0]) +
-"""// Copyright (c) 2013 Apple Inc. All Rights Reserved.
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-""")
-
-    frontend_domain_class = string.Template(CodeGeneratorInspectorStrings.frontend_domain_class)
-    backend_dispatcher_constructor = string.Template(CodeGeneratorInspectorStrings.backend_dispatcher_constructor)
-    backend_dispatcher_dispatch_method = string.Template(CodeGeneratorInspectorStrings.backend_dispatcher_dispatch_method)
-    backend_dispatcher_dispatch_method_simple = string.Template(CodeGeneratorInspectorStrings.backend_dispatcher_dispatch_method_simple)
-    backend_method = string.Template(CodeGeneratorInspectorStrings.backend_method)
-    frontend_method = string.Template(CodeGeneratorInspectorStrings.frontend_method)
-    callback_method = string.Template(CodeGeneratorInspectorStrings.callback_method)
-    frontend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_h)
-    backend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_h)
-    backend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_cpp)
-    frontend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_cpp)
-    typebuilder_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_h)
-    typebuilder_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_cpp)
-    backend_js = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_js)
-    param_container_access_code = CodeGeneratorInspectorStrings.param_container_access_code
-
-
-
-
-
-type_map = TypeMap(json_api, dependency_api)
-
-
-class NeedRuntimeCastRequest:
-    def __init__(self):
-        self.ack_ = None
-
-    def acknowledge(self):
-        self.ack_ = True
-
-    def is_acknowledged(self):
-        return self.ack_
-
-
-def resolve_all_types():
-    runtime_cast_generate_requests = {}
-    for type_name in TYPES_WITH_RUNTIME_CAST_SET:
-        runtime_cast_generate_requests[type_name] = NeedRuntimeCastRequest()
-
-    class ForwardListener:
-        type_data_set = set()
-        already_declared_set = set()
-
-        @classmethod
-        def add_type_data(cls, type_data):
-            if type_data not in cls.already_declared_set:
-                cls.type_data_set.add(type_data)
-
-    class ResolveContext:
-        forward_listener = ForwardListener
-
-    for domain_data in type_map.domains():
-        for type_data in domain_data.types():
-            binding = type_data.get_binding()
-            binding.resolve_inner(ResolveContext)
-            # Do not generate forwards for this type any longer.
-            ForwardListener.already_declared_set.add(type_data)
-
-    for domain_data in type_map.domains():
-        for type_data in domain_data.types():
-            full_type_name = "%s.%s" % (type_data.get_domain_name(), type_data.get_name())
-            request = runtime_cast_generate_requests.pop(full_type_name, None)
-            binding = type_data.get_binding()
-            if request:
-                binding.request_user_runtime_cast(request)
-
-            if request and not request.is_acknowledged():
-                raise Exception("Failed to generate runtimeCast in " + full_type_name)
-
-    # FIXME: This assumes all the domains are processed at once. Change this verification
-    # to only verify runtime casts for the domains being generated.
-    # if verification:
-    #     for full_type_name in runtime_cast_generate_requests:
-    #         raise Exception("Failed to generate runtimeCast. Type " + full_type_name + " not found")
-
-    return ForwardListener
-
-
-global_forward_listener = resolve_all_types()
-
-
-def get_annotated_type_text(raw_type, annotated_type):
-    if annotated_type != raw_type:
-        return "/*%s*/ %s" % (annotated_type, raw_type)
-    else:
-        return raw_type
-
-
-def format_setter_value_expression(param_type_binding, value_ref):
-    pattern = param_type_binding.get_setter_value_expression_pattern()
-    if pattern:
-        return pattern % (INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["prefix"], value_ref)
-    else:
-        return value_ref
-
-
-class Generator:
-    frontend_domain_class_lines = []
-
-    backend_method_implementation_list = []
-    frontend_method_list = []
-    backend_js_domain_initializer_list = []
-
-    backend_handler_interface_list = []
-    backend_handler_implementation_list = []
-    backend_dispatcher_interface_list = []
-    type_builder_fragments = []
-    type_builder_forwards = []
-    validator_impl_list = []
-    type_builder_impl_list = []
-
-
-    @staticmethod
-    def go():
-        Generator.process_types(type_map)
-
-        first_cycle_guardable_list_list = [
-            Generator.backend_method_implementation_list,
-            Generator.backend_handler_interface_list,
-            Generator.backend_handler_implementation_list,
-            Generator.backend_dispatcher_interface_list]
-
-        for json_domain in json_api["domains"]:
-            domain_name = json_domain["domain"]
-            domain_name_lower = domain_name.lower()
-
-            domain_fixes = DomainNameFixes.get_fixed_data(domain_name)
-
-            domain_guard = domain_fixes.get_guard()
-
-            if domain_guard:
-                for l in first_cycle_guardable_list_list:
-                    domain_guard.generate_open(l)
-
-            frontend_method_declaration_lines = []
-
-            if ("commands" in json_domain or "events" in json_domain):
-                Generator.backend_js_domain_initializer_list.append("// %s.\n" % domain_name)
-                if not domain_fixes.skip_js_bind:
-                    Generator.backend_js_domain_initializer_list.append("InspectorBackend.register%sDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"%s\");\n" % (domain_name, domain_name))
-
-            if "types" in json_domain:
-                for json_type in json_domain["types"]:
-                    if "type" in json_type and json_type["type"] == "string" and "enum" in json_type:
-                        enum_name = "%s.%s" % (domain_name, json_type["id"])
-                        Generator.process_enum(json_type, enum_name)
-                    elif json_type["type"] == "object":
-                        if "properties" in json_type:
-                            for json_property in json_type["properties"]:
-                                if "type" in json_property and json_property["type"] == "string" and "enum" in json_property:
-                                    enum_name = "%s.%s%s" % (domain_name, json_type["id"], to_title_case(json_property["name"]))
-                                    Generator.process_enum(json_property, enum_name)
-
-            if "events" in json_domain:
-                if domain_guard:
-                    domain_guard.generate_open(Generator.frontend_method_list)
-                    domain_guard.generate_open(Generator.frontend_domain_class_lines)
-
-                for json_event in json_domain["events"]:
-                    Generator.process_event(json_event, domain_name, frontend_method_declaration_lines)
-
-                Generator.frontend_domain_class_lines.append(Templates.frontend_domain_class.substitute(None,
-                    exportMacro=INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["export_macro"],
-                    domainClassName="Inspector%sFrontendDispatcher" % domain_name,
-                    frontendDomainMethodDeclarations="".join(flatten_list(frontend_method_declaration_lines))))
-
-                if domain_guard:
-                    domain_guard.generate_close(Generator.frontend_method_list)
-                    domain_guard.generate_close(Generator.frontend_domain_class_lines)
-
-            dispatcher_name = "Inspector" + Capitalizer.lower_camel_case_to_upper(domain_name) + "BackendDispatcher"
-            agent_interface_name = dispatcher_name + "Handler"
-
-            if "commands" in json_domain:
-                Generator.backend_dispatcher_interface_list.append("class %s %s final : public Inspector::InspectorSupplementalBackendDispatcher {\n" % (INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["export_macro"], dispatcher_name))
-                Generator.backend_dispatcher_interface_list.append("public:\n")
-                Generator.backend_dispatcher_interface_list.append("    static PassRefPtr<%s> create(Inspector::InspectorBackendDispatcher*, %s*);\n" % (dispatcher_name, agent_interface_name))
-                Generator.backend_dispatcher_interface_list.append("    virtual void dispatch(long callId, const String& method, PassRefPtr<Inspector::InspectorObject> message) override;\n")
-                Generator.backend_dispatcher_interface_list.append("private:\n")
-
-                Generator.backend_handler_interface_list.append("class %s %s {\n" % (INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["export_macro"], agent_interface_name))
-                Generator.backend_handler_interface_list.append("public:\n")
-
-                backend_method_count = len(Generator.backend_method_implementation_list)
-
-                dispatcher_if_chain = []
-                dispatcher_commands_list = []
-                for json_command in json_domain["commands"]:
-                    Generator.process_command(json_command, domain_name, agent_interface_name, dispatcher_name, dispatcher_if_chain, dispatcher_commands_list)
-
-                Generator.backend_handler_interface_list.append("protected:\n")
-                Generator.backend_handler_interface_list.append("    virtual ~%s();\n" % agent_interface_name)
-                Generator.backend_handler_interface_list.append("};\n\n")
-
-                Generator.backend_handler_implementation_list.append("%s::~%s() { }\n" % (agent_interface_name, agent_interface_name))
-
-                Generator.backend_dispatcher_interface_list.append("private:\n")
-                Generator.backend_dispatcher_interface_list.append("    %s(Inspector::InspectorBackendDispatcher*, %s*);\n" % (dispatcher_name, agent_interface_name))
-                Generator.backend_dispatcher_interface_list.append("    %s* m_agent;\n" % agent_interface_name)
-                Generator.backend_dispatcher_interface_list.append("};\n\n")
-
-                Generator.backend_method_implementation_list.insert(backend_method_count, Templates.backend_dispatcher_constructor.substitute(None,
-                    domainName=domain_name,
-                    dispatcherName=dispatcher_name,
-                    agentName=agent_interface_name))
-
-                if len(json_domain["commands"]) <= 5:
-                    Generator.backend_method_implementation_list.insert(backend_method_count + 1, Templates.backend_dispatcher_dispatch_method_simple.substitute(None,
-                        domainName=domain_name,
-                        dispatcherName=dispatcher_name,
-                        ifChain="\n".join(dispatcher_if_chain)))
-                else:
-                    Generator.backend_method_implementation_list.insert(backend_method_count + 1, Templates.backend_dispatcher_dispatch_method.substitute(None,
-                        domainName=domain_name,
-                        dispatcherName=dispatcher_name,
-                        dispatcherCommands="\n".join(dispatcher_commands_list)))
-
-                if domain_guard:
-                    for l in reversed(first_cycle_guardable_list_list):
-                        domain_guard.generate_close(l)
-                Generator.backend_js_domain_initializer_list.append("\n")
-
-    @staticmethod
-    def process_enum(json_enum, enum_name):
-        enum_members = []
-        for member in json_enum["enum"]:
-            enum_members.append("%s: \"%s\"" % (fix_camel_case(member), member))
-
-        Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerEnum(\"%s\", {%s});\n" % (
-            enum_name, ", ".join(enum_members)))
-
-    @staticmethod
-    def process_event(json_event, domain_name, frontend_method_declaration_lines):
-        event_name = json_event["name"]
-
-        ad_hoc_type_output = []
-        frontend_method_declaration_lines.append(ad_hoc_type_output)
-        ad_hoc_type_writer = Writer(ad_hoc_type_output, "        ")
-
-        decl_parameter_list = []
-
-        json_parameters = json_event.get("parameters")
-        Generator.generate_send_method(json_parameters, event_name, domain_name, ad_hoc_type_writer,
-                                       decl_parameter_list,
-                                       Generator.EventMethodStructTemplate,
-                                       Generator.frontend_method_list, Templates.frontend_method, {"eventName": event_name})
-
-        backend_js_event_param_list = []
-        if json_parameters:
-            for parameter in json_parameters:
-                parameter_name = parameter["name"]
-                backend_js_event_param_list.append("\"%s\"" % parameter_name)
-
-        frontend_method_declaration_lines.append(
-            "    void %s(%s);\n" % (event_name, ", ".join(decl_parameter_list)))
-
-        Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerEvent(\"%s.%s\", [%s]);\n" % (
-            domain_name, event_name, ", ".join(backend_js_event_param_list)))
-
-    class EventMethodStructTemplate:
-        @staticmethod
-        def append_prolog(line_list):
-            line_list.append("    RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
-
-        @staticmethod
-        def append_epilog(line_list):
-            line_list.append("    jsonMessage->setObject(ASCIILiteral(\"params\"), paramsObject);\n")
-
-        container_name = "paramsObject"
-
-    @staticmethod
-    def process_command(json_command, domain_name, agent_interface_name, dispatcher_name, dispatcher_if_chain, dispatcher_commands_list):
-        json_command_name = json_command["name"]
-
-        ad_hoc_type_output = []
-        Generator.backend_handler_interface_list.append(ad_hoc_type_output)
-        ad_hoc_type_writer = Writer(ad_hoc_type_output, "    ")
-
-        Generator.backend_dispatcher_interface_list.append("    void %s(long callId, const Inspector::InspectorObject& message);\n" % json_command_name)
-
-        Generator.backend_handler_interface_list.append("    virtual void %s(ErrorString*" % json_command_name)
-
-        if not dispatcher_if_chain:
-            dispatcher_if_chain.append("    if (method == \"%s\")" % json_command_name)
-        else:
-            dispatcher_if_chain.append("    else if (method == \"%s\")" % json_command_name)
-        dispatcher_if_chain.append("        %s(callId, *message.get());" % json_command_name)
-        dispatcher_commands_list.append("            { \"%s\", &%s::%s }," % (json_command_name, dispatcher_name, json_command_name))
-
-        method_in_params_handling = []
-        method_dispatch_handling = []
-        method_out_params_handling = []
-        method_ending_handling = []
-        method_request_message_param_name = ""
-        agent_call_param_list = []
-        js_parameters_text = ""
-        if "parameters" in json_command:
-            json_params = json_command["parameters"]
-            method_request_message_param_name = " message"
-            method_in_params_handling.append("    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();\n")
-            method_in_params_handling.append("    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral(\"params\"));\n")
-            method_in_params_handling.append("    InspectorObject* paramsContainerPtr = paramsContainer.get();\n")
-            method_in_params_handling.append("    InspectorArray* protocolErrorsPtr = protocolErrors.get();\n")
-            js_param_list = []
-
-            for json_parameter in json_params:
-                json_param_name = json_parameter["name"]
-                param_raw_type = resolve_param_raw_type(json_parameter, domain_name)
-
-                getter_name = param_raw_type.get_getter_name()
-
-                optional = json_parameter.get("optional")
-
-                non_optional_type_model = param_raw_type.get_raw_type_model()
-                if optional:
-                    type_model = non_optional_type_model.get_optional()
-                else:
-                    type_model = non_optional_type_model
-
-                if optional:
-                    code = ("    bool %s_valueFound = false;\n"
-                            "    %s in_%s = InspectorBackendDispatcher::get%s(paramsContainerPtr, ASCIILiteral(\"%s\"), &%s_valueFound, protocolErrorsPtr);\n" %
-                           (json_param_name, non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name, json_param_name))
-                    param = ", %s_valueFound ? &in_%s : nullptr" % (json_param_name, json_param_name)
-                    # FIXME: pass optional refptr-values as PassRefPtr
-                    formal_param_type_pattern = "const %s*"
-                else:
-                    code = ("    %s in_%s = InspectorBackendDispatcher::get%s(paramsContainerPtr, ASCIILiteral(\"%s\"), nullptr, protocolErrorsPtr);\n" %
-                            (non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name))
-                    param = ", in_%s" % json_param_name
-                    # FIXME: pass not-optional refptr-values as NonNullPassRefPtr
-                    if param_raw_type.is_heavy_value():
-                        formal_param_type_pattern = "const %s&"
-                    else:
-                        formal_param_type_pattern = "%s"
-
-                method_in_params_handling.append(code)
-                agent_call_param_list.append(param)
-                Generator.backend_handler_interface_list.append(", %s in_%s" % (formal_param_type_pattern % non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name))
-
-                js_bind_type = param_raw_type.get_js_bind_type()
-                js_param_text = "{\"name\": \"%s\", \"type\": \"%s\", \"optional\": %s}" % (
-                    json_param_name,
-                    js_bind_type,
-                    ("true" if ("optional" in json_parameter and json_parameter["optional"]) else "false"))
-
-                js_param_list.append(js_param_text)
-
-            method_in_params_handling.append("    if (protocolErrors->length()) {\n")
-            method_in_params_handling.append("        String errorMessage = String::format(\"Some arguments of method '%%s' can't be processed\", \"%s.%s\");\n" % (domain_name, json_command_name))
-            method_in_params_handling.append("        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());\n")
-            method_in_params_handling.append("        return;\n")
-            method_in_params_handling.append("    }\n")
-            method_in_params_handling.append("\n")
-
-            js_parameters_text = ", ".join(js_param_list)
-
-        method_dispatch_handling.append("    ErrorString error;\n")
-        method_dispatch_handling.append("    RefPtr<InspectorObject> result = InspectorObject::create();\n")
-
-        if json_command.get("async") == True:
-            callback_name = Capitalizer.lower_camel_case_to_upper(json_command_name) + "Callback"
-
-            callback_output = []
-            callback_writer = Writer(callback_output, ad_hoc_type_writer.get_indent())
-
-            decl_parameter_list = []
-            Generator.generate_send_method(json_command.get("returns"), json_command_name, domain_name, ad_hoc_type_writer,
-                                           decl_parameter_list,
-                                           Generator.CallbackMethodStructTemplate,
-                                           Generator.backend_method_implementation_list, Templates.callback_method,
-                                           {"callbackName": callback_name, "handlerName": agent_interface_name})
-
-            callback_writer.newline("class " + callback_name + " : public Inspector::InspectorBackendDispatcher::CallbackBase {\n")
-            callback_writer.newline("public:\n")
-            callback_writer.newline("    " + callback_name + "(PassRefPtr<Inspector::InspectorBackendDispatcher>, int id);\n")
-            callback_writer.newline("    void sendSuccess(" + ", ".join(decl_parameter_list) + ");\n")
-            callback_writer.newline("};\n")
-
-            ad_hoc_type_output.append(callback_output)
-
-            method_dispatch_handling.append("    RefPtr<%s::%s> callback = adoptRef(new %s::%s(m_backendDispatcher,callId));\n" % (agent_interface_name, callback_name, agent_interface_name, callback_name))
-            method_ending_handling.append("    if (error.length()) {\n")
-            method_ending_handling.append("        callback->disable();\n")
-            method_ending_handling.append("        m_backendDispatcher->reportProtocolError(&callId, Inspector::InspectorBackendDispatcher::ServerError, error);\n")
-            method_ending_handling.append("        return;\n")
-            method_ending_handling.append("    }")
-
-            agent_call_param_list.append(", callback")
-            Generator.backend_handler_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
-        elif "returns" in json_command:
-            has_multiple_returns = len(json_command["returns"]) > 1
-            if has_multiple_returns:
-                method_out_params_handling.append("    if (!error.length()) {\n")
-            else:
-                method_out_params_handling.append("    if (!error.length())\n")
-
-            for json_return in json_command["returns"]:
-
-                json_return_name = json_return["name"]
-
-                optional = bool(json_return.get("optional"))
-
-                return_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
-
-                raw_type = return_type_binding.reduce_to_raw_type()
-                setter_type = raw_type.get_setter_name()
-                initializer = raw_type.get_c_initializer()
-
-                type_model = return_type_binding.get_type_model()
-                if optional:
-                    type_model = type_model.get_optional()
-
-                code = "    %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
-                param = ", %sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
-                var_name = "out_%s" % json_return_name
-                setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
-                if return_type_binding.get_setter_value_expression_pattern():
-                    setter_argument = return_type_binding.get_setter_value_expression_pattern() % (INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["prefix"], setter_argument)
-
-                cook = "        result->set%s(ASCIILiteral(\"%s\"), %s);\n" % (setter_type, json_return_name, setter_argument)
-
-                set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
-                if set_condition_pattern:
-                    cook = ("        if (%s)\n    " % (set_condition_pattern % var_name)) + cook
-                annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()
-
-                param_name = "out_%s" % json_return_name
-                if optional:
-                    param_name = "opt_" + param_name
-
-                Generator.backend_handler_interface_list.append(", %s %s" % (annotated_type, param_name))
-                method_out_params_handling.append(cook)
-                method_dispatch_handling.append(code)
-
-                agent_call_param_list.append(param)
-
-            if has_multiple_returns:
-                method_out_params_handling.append("    }\n")
-            method_out_params_handling.append("\n")
-
-        method_dispatch_handling.append("    m_agent->%s(&error%s);\n" % (json_command_name, "".join(agent_call_param_list)))
-        method_dispatch_handling.append("\n")
-
-        if not method_ending_handling:
-            method_ending_handling.append("    m_backendDispatcher->sendResponse(callId, result.release(), error);")
-
-        backend_js_reply_param_list = []
-        if "returns" in json_command:
-            for json_return in json_command["returns"]:
-                json_return_name = json_return["name"]
-                backend_js_reply_param_list.append("\"%s\"" % json_return_name)
-
-        js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
-
-        Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
-            dispatcherName=dispatcher_name,
-            methodName=json_command_name,
-            requestMessageObject=method_request_message_param_name,
-            methodInParametersHandling="".join(method_in_params_handling),
-            methodDispatchHandling="".join(method_dispatch_handling),
-            methodOutParametersHandling="".join(method_out_params_handling),
-            methodEndingHandling="".join(method_ending_handling)))
-
-        Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerCommand(\"%s.%s\", [%s], %s);\n" % (domain_name, json_command_name, js_parameters_text, js_reply_list))
-        Generator.backend_handler_interface_list.append(") = 0;\n")
-
-    class CallbackMethodStructTemplate:
-        @staticmethod
-        def append_prolog(line_list):
-            pass
-
-        @staticmethod
-        def append_epilog(line_list):
-            pass
-
-        container_name = "jsonMessage"
-
-    # Generates common code for event sending and callback response data sending.
-    @staticmethod
-    def generate_send_method(parameters, event_name, domain_name, ad_hoc_type_writer, decl_parameter_list,
-                             method_struct_template,
-                             generator_method_list, method_template, template_params):
-        method_line_list = []
-        if parameters:
-            method_struct_template.append_prolog(method_line_list)
-            for json_parameter in parameters:
-                parameter_name = json_parameter["name"]
-
-                param_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_parameter, event_name, domain_name, ad_hoc_type_writer, "")
-
-                raw_type = param_type_binding.reduce_to_raw_type()
-                raw_type_binding = RawTypeBinding(raw_type)
-
-                optional = bool(json_parameter.get("optional"))
-
-                setter_type = raw_type.get_setter_name()
-
-                type_model = param_type_binding.get_type_model()
-                raw_type_model = raw_type_binding.get_type_model()
-                if optional:
-                    type_model = type_model.get_optional()
-                    raw_type_model = raw_type_model.get_optional()
-
-                annotated_type = type_model.get_input_param_type_text()
-                mode_type_binding = param_type_binding
-
-                decl_parameter_list.append("%s %s" % (annotated_type, parameter_name))
-
-                setter_argument = raw_type_model.get_event_setter_expression_pattern() % parameter_name
-                if mode_type_binding.get_setter_value_expression_pattern():
-                    setter_argument = mode_type_binding.get_setter_value_expression_pattern() % (INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["prefix"], setter_argument)
-
-                setter_code = "    %s->set%s(ASCIILiteral(\"%s\"), %s);\n" % (method_struct_template.container_name, setter_type, parameter_name, setter_argument)
-                if optional:
-                    setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
-                method_line_list.append(setter_code)
-
-            method_struct_template.append_epilog(method_line_list)
-
-        generator_method_list.append(method_template.substitute(None,
-            domainName=domain_name,
-            parameters=", ".join(decl_parameter_list),
-            code="".join(method_line_list), **template_params))
-
-    @staticmethod
-    def resolve_type_and_generate_ad_hoc(json_param, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param):
-        param_name = json_param["name"]
-        ad_hoc_type_list = []
-
-        class AdHocTypeContext:
-            container_full_name_prefix = "<not yet defined>"
-            container_relative_name_prefix = container_relative_name_prefix_param
-
-            @staticmethod
-            def get_type_name_fix():
-                class NameFix:
-                    class_name = Capitalizer.lower_camel_case_to_upper(param_name)
-
-                    @staticmethod
-                    def output_comment(writer):
-                        writer.newline("// Named after parameter '%s' while generating command/event %s.\n" % (param_name, method_name))
-
-                return NameFix
-
-            @staticmethod
-            def add_type(binding):
-                ad_hoc_type_list.append(binding)
-
-        type_binding = resolve_param_type(json_param, domain_name, AdHocTypeContext)
-
-        class InterfaceForwardListener:
-            @staticmethod
-            def add_type_data(type_data):
-                pass
-
-        class InterfaceResolveContext:
-            forward_listener = InterfaceForwardListener
-
-        for type in ad_hoc_type_list:
-            type.resolve_inner(InterfaceResolveContext)
-
-        class InterfaceGenerateContext:
-            validator_writer = "not supported in InterfaceGenerateContext"
-            cpp_writer = validator_writer
-
-        for type in ad_hoc_type_list:
-            generator = type.get_code_generator()
-            if generator:
-                generator.generate_type_builder(ad_hoc_type_writer, InterfaceGenerateContext)
-
-        return type_binding
-
-    @staticmethod
-    def process_types(type_map):
-        output = Generator.type_builder_fragments
-
-        class GenerateContext:
-            validator_writer = Writer(Generator.validator_impl_list, "")
-            cpp_writer = Writer(Generator.type_builder_impl_list, "")
-
-        def generate_all_domains_code(out, type_data_callback):
-            writer = Writer(out, "")
-            for domain_data in type_map.domains_to_generate():
-                domain_fixes = DomainNameFixes.get_fixed_data(domain_data.name())
-                domain_guard = domain_fixes.get_guard()
-
-                namespace_declared = []
-
-                def namespace_lazy_generator():
-                    if not namespace_declared:
-                        if domain_guard:
-                            domain_guard.generate_open(out)
-                        writer.newline("namespace ")
-                        writer.append(domain_data.name())
-                        writer.append(" {\n")
-                        # What is a better way to change value from outer scope?
-                        namespace_declared.append(True)
-                    return writer
-
-                for type_data in domain_data.types():
-                    type_data_callback(type_data, namespace_lazy_generator)
-
-                if namespace_declared:
-                    writer.append("} // ")
-                    writer.append(domain_data.name())
-                    writer.append("\n\n")
-
-                    if domain_guard:
-                        domain_guard.generate_close(out)
-
-        def create_type_builder_caller(generate_pass_id):
-            def call_type_builder(type_data, writer_getter):
-                code_generator = type_data.get_binding().get_code_generator()
-                if code_generator and generate_pass_id == code_generator.get_generate_pass_id():
-                    writer = writer_getter()
-
-                    code_generator.generate_type_builder(writer, GenerateContext)
-            return call_type_builder
-
-        generate_all_domains_code(output, create_type_builder_caller(TypeBuilderPass.MAIN))
-
-        Generator.type_builder_forwards.append("// Forward declarations.\n")
-
-        def generate_forward_callback(type_data, writer_getter):
-            if type_data in global_forward_listener.type_data_set:
-                binding = type_data.get_binding()
-                binding.get_code_generator().generate_forward_declaration(writer_getter())
-        generate_all_domains_code(Generator.type_builder_forwards, generate_forward_callback)
-
-        Generator.type_builder_forwards.append("// End of forward declarations.\n\n")
-
-        Generator.type_builder_forwards.append("// Typedefs.\n")
-
-        generate_all_domains_code(Generator.type_builder_forwards, create_type_builder_caller(TypeBuilderPass.TYPEDEF))
-
-        Generator.type_builder_forwards.append("// End of typedefs.\n\n")
-
-
-def flatten_list(input):
-    res = []
-
-    def fill_recursive(l):
-        for item in l:
-            if isinstance(item, list):
-                fill_recursive(item)
-            else:
-                res.append(item)
-    fill_recursive(input)
-    return res
-
-
-# A writer that only updates file if it actually changed to better support incremental build.
-class SmartOutput:
-    def __init__(self, file_name):
-        self.file_name_ = file_name
-        self.output_ = ""
-
-    def write(self, text):
-        self.output_ += text
-
-    def close(self):
-        text_changed = True
-        self.output_ = self.output_.rstrip() + "\n"
-
-        try:
-            read_file = open(self.file_name_, "r")
-            old_text = read_file.read()
-            read_file.close()
-            text_changed = old_text != self.output_
-        except:
-            # Ignore, just overwrite by default
-            pass
-
-        if text_changed or write_always:
-            out_file = open(self.file_name_, "w")
-            out_file.write(self.output_)
-            out_file.close()
-
-
-Generator.go()
-
-output_file_name_prefix = INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["prefix"]
-
-backend_h_file = SmartOutput(output_header_dirname + ("/Inspector%sBackendDispatchers.h" % output_file_name_prefix))
-backend_cpp_file = SmartOutput(output_cpp_dirname + ("/Inspector%sBackendDispatchers.cpp" % output_file_name_prefix))
-
-frontend_h_file = SmartOutput(output_header_dirname + ("/Inspector%sFrontendDispatchers.h" % output_file_name_prefix))
-frontend_cpp_file = SmartOutput(output_cpp_dirname + ("/Inspector%sFrontendDispatchers.cpp" % output_file_name_prefix))
-
-typebuilder_h_file = SmartOutput(output_header_dirname + ("/Inspector%sTypeBuilders.h" % output_file_name_prefix))
-typebuilder_cpp_file = SmartOutput(output_cpp_dirname + ("/Inspector%sTypeBuilders.cpp" % output_file_name_prefix))
-
-backend_js_file = SmartOutput(output_js_dirname + ("/Inspector%sBackendCommands.js" % output_file_name_prefix))
-
-
-backend_h_file.write(Templates.backend_h.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    handlerInterfaces="".join(flatten_list(Generator.backend_handler_interface_list)),
-    dispatcherInterfaces="".join(flatten_list(Generator.backend_dispatcher_interface_list))))
-
-backend_cpp_file.write(Templates.backend_cpp.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    handlerImplementations="".join(flatten_list(Generator.backend_handler_implementation_list)),
-    methods="\n".join(Generator.backend_method_implementation_list)))
-
-frontend_h_file.write(Templates.frontend_h.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    domainClassList="".join(Generator.frontend_domain_class_lines)))
-
-frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    methods="\n".join(Generator.frontend_method_list)))
-
-typebuilder_h_file.write(Templates.typebuilder_h.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    typeBuilderDependencies=INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["typebuilder_dependency"],
-    exportMacro=INSPECTOR_TYPES_GENERATOR_CONFIG_MAP[output_type]["export_macro"],
-    typeBuilders="".join(flatten_list(Generator.type_builder_fragments)),
-    forwards="".join(Generator.type_builder_forwards),
-    validatorIfdefName=VALIDATOR_IFDEF_NAME))
-
-typebuilder_cpp_file.write(Templates.typebuilder_cpp.substitute(None,
-    outputFileNamePrefix=output_file_name_prefix,
-    enumConstantValues=EnumConstants.get_enum_constant_code(),
-    implCode="".join(flatten_list(Generator.type_builder_impl_list)),
-    validatorCode="".join(flatten_list(Generator.validator_impl_list)),
-    validatorIfdefName=VALIDATOR_IFDEF_NAME))
-
-backend_js_file.write(Templates.backend_js.substitute(None,
-    domainInitializers="".join(Generator.backend_js_domain_initializer_list)))
-
-backend_h_file.close()
-backend_cpp_file.close()
-
-frontend_h_file.close()
-frontend_cpp_file.close()
-
-typebuilder_h_file.close()
-typebuilder_cpp_file.close()
-
-backend_js_file.close()
diff --git a/inspector/scripts/CodeGeneratorInspectorStrings.py b/inspector/scripts/CodeGeneratorInspectorStrings.py
deleted file mode 100644 (file)
index 2763744..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-# Copyright (c) 2013 Google Inc. All rights reserved.
-# Copyright (c) 2013 Apple Inc. All Rights Reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This file contains string resources for CodeGeneratorInspector.
-# Its syntax is a Python syntax subset, suitable for manual parsing.
-
-frontend_domain_class = (
-"""class ${exportMacro} ${domainClassName} {
-public:
-    ${domainClassName}(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
-${frontendDomainMethodDeclarations}private:
-    InspectorFrontendChannel* m_inspectorFrontendChannel;
-};
-
-""")
-
-backend_dispatcher_constructor = (
-"""PassRefPtr<${dispatcherName}> ${dispatcherName}::create(InspectorBackendDispatcher* backendDispatcher, ${agentName}* agent)
-{
-    return adoptRef(new ${dispatcherName}(backendDispatcher, agent));
-}
-
-${dispatcherName}::${dispatcherName}(InspectorBackendDispatcher* backendDispatcher, ${agentName}* agent)
-    : InspectorSupplementalBackendDispatcher(backendDispatcher)
-    , m_agent(agent)
-{
-    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("${domainName}"), this);
-}
-""")
-
-backend_dispatcher_dispatch_method_simple = (
-"""void ${dispatcherName}::dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message)
-{
-    Ref<${dispatcherName}> protect(*this);
-
-${ifChain}
-    else
-        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::MethodNotFound, String("'") + "${domainName}" + '.' + method + "' was not found");
-}
-""")
-
-backend_dispatcher_dispatch_method = (
-"""void ${dispatcherName}::dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message)
-{
-    Ref<${dispatcherName}> protect(*this);
-
-    typedef void (${dispatcherName}::*CallHandler)(long callId, const Inspector::InspectorObject& message);
-    typedef HashMap<String, CallHandler> DispatchMap;
-    DEPRECATED_DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
-    if (dispatchMap.isEmpty()) {
-        static const struct MethodTable {
-            const char* name;
-            CallHandler handler;
-        } commands[] = {
-${dispatcherCommands}
-        };
-        size_t length = WTF_ARRAY_LENGTH(commands);
-        for (size_t i = 0; i < length; ++i)
-            dispatchMap.add(commands[i].name, commands[i].handler);
-    }
-
-    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
-    if (it == dispatchMap.end()) {
-        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::MethodNotFound, String("'") + "${domainName}" + '.' + method + "' was not found");
-        return;
-    }
-
-    ((*this).*it->value)(callId, *message.get());
-}
-""")
-
-backend_method = (
-"""void ${dispatcherName}::${methodName}(long callId, const InspectorObject&${requestMessageObject})
-{
-${methodInParametersHandling}${methodDispatchHandling}${methodOutParametersHandling}${methodEndingHandling}
-}
-""")
-
-frontend_method = ("""void Inspector${domainName}FrontendDispatcher::${eventName}(${parameters})
-{
-    RefPtr<InspectorObject> jsonMessage = InspectorObject::create();
-    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("${domainName}.${eventName}"));
-${code}
-    m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
-}
-""")
-
-callback_method = (
-"""${handlerName}::${callbackName}::${callbackName}(PassRefPtr<InspectorBackendDispatcher> backendDispatcher, int id) : Inspector::InspectorBackendDispatcher::CallbackBase(backendDispatcher, id) { }
-
-void ${handlerName}::${callbackName}::sendSuccess(${parameters})
-{
-    RefPtr<InspectorObject> jsonMessage = InspectorObject::create();
-${code}    sendIfActive(jsonMessage, ErrorString());
-}
-""")
-
-frontend_h = (
-"""#ifndef Inspector${outputFileNamePrefix}FrontendDispatchers_h
-#define Inspector${outputFileNamePrefix}FrontendDispatchers_h
-
-#include "Inspector${outputFileNamePrefix}TypeBuilders.h"
-#include <inspector/InspectorFrontendChannel.h>
-#include <inspector/InspectorValues.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace Inspector {
-
-#if ENABLE(INSPECTOR)
-
-${domainClassList}
-
-#endif // ENABLE(INSPECTOR)
-
-} // namespace Inspector
-
-#endif // !defined(Inspector${outputFileNamePrefix}FrontendDispatchers_h)
-""")
-
-backend_h = (
-"""#ifndef Inspector${outputFileNamePrefix}BackendDispatchers_h
-#define Inspector${outputFileNamePrefix}BackendDispatchers_h
-
-#if ENABLE(INSPECTOR)
-
-#include "Inspector${outputFileNamePrefix}TypeBuilders.h"
-#include <inspector/InspectorBackendDispatcher.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace Inspector {
-
-typedef String ErrorString;
-
-${handlerInterfaces}
-
-${dispatcherInterfaces}
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // !defined(Inspector${outputFileNamePrefix}BackendDispatchers_h)
-""")
-
-backend_cpp = (
-"""
-#include "config.h"
-
-#if ENABLE(INSPECTOR)
-
-#include "Inspector${outputFileNamePrefix}BackendDispatchers.h"
-
-#include <inspector/InspectorFrontendChannel.h>
-#include <inspector/InspectorValues.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace Inspector {
-
-${handlerImplementations}
-
-${methods}
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-""")
-
-frontend_cpp = (
-"""
-
-#include "config.h"
-
-#if ENABLE(INSPECTOR)
-
-#include "Inspector${outputFileNamePrefix}FrontendDispatchers.h"
-
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace Inspector {
-
-${methods}
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-""")
-
-typebuilder_h = (
-"""
-#ifndef Inspector${outputFileNamePrefix}TypeBuilders_h
-#define Inspector${outputFileNamePrefix}TypeBuilders_h
-
-#if ENABLE(INSPECTOR)
-
-#include <inspector/InspectorTypeBuilder.h>
-${typeBuilderDependencies}
-#include <wtf/Assertions.h>
-#include <wtf/PassRefPtr.h>
-
-namespace Inspector {
-
-namespace TypeBuilder {
-
-${forwards}
-
-${exportMacro} String get${outputFileNamePrefix}EnumConstantValue(int code);
-
-${typeBuilders}
-} // namespace TypeBuilder
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // !defined(Inspector${outputFileNamePrefix}TypeBuilders_h)
-
-""")
-
-typebuilder_cpp = (
-"""
-
-#include "config.h"
-#include "Inspector${outputFileNamePrefix}TypeBuilders.h"
-
-#if ENABLE(INSPECTOR)
-
-#include <wtf/text/CString.h>
-
-namespace Inspector {
-
-namespace TypeBuilder {
-
-static const char* const enum_constant_values[] = {
-${enumConstantValues}};
-
-String get${outputFileNamePrefix}EnumConstantValue(int code) {
-    return enum_constant_values[code];
-}
-
-} // namespace TypeBuilder
-
-${implCode}
-
-#if ${validatorIfdefName}
-
-${validatorCode}
-
-#endif // ${validatorIfdefName}
-
-} // namespace Inspector
-
-#endif // ENABLE(INSPECTOR)
-""")
-
-backend_js = (
-"""
-
-${domainInitializers}
-""")
-
-param_container_access_code = """
-    RefPtr<InspectorObject> paramsContainer = message.getObject("params");
-    InspectorObject* paramsContainerPtr = paramsContainer.get();
-    InspectorArray* protocolErrorsPtr = protocolErrors.get();
-"""
-
-class_binding_builder_part_1 = (
-"""        AllFieldsSet = %s
-    };
-
-    template<int STATE>
-    class Builder {
-    private:
-        RefPtr<Inspector::InspectorObject> m_result;
-
-        template<int STEP> Builder<STATE | STEP>& castState()
-        {
-            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
-        }
-
-        Builder(PassRefPtr</*%s*/Inspector::InspectorObject> ptr)
-        {
-            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
-            m_result = ptr;
-        }
-        friend class %s;
-    public:
-""")
-
-class_binding_builder_part_2 = ("""
-        Builder<STATE | %s>& set%s(%s value)
-        {
-            COMPILE_ASSERT(!(STATE & %s), property_%s_already_set);
-            m_result->set%s(ASCIILiteral("%s"), %s);
-            return castState<%s>();
-        }
-""")
-
-class_binding_builder_part_3 = ("""
-        operator RefPtr<%s>& ()
-        {
-            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
-            COMPILE_ASSERT(sizeof(%s) == sizeof(Inspector::InspectorObject), cannot_cast);
-            return *reinterpret_cast<RefPtr<%s>*>(&m_result);
-        }
-
-        PassRefPtr<%s> release()
-        {
-            return RefPtr<%s>(*this).release();
-        }
-    };
-
-""")
-
-class_binding_builder_part_4 = (
-"""    static Builder<NoFieldsSet> create()
-    {
-        return Builder<NoFieldsSet>(Inspector::InspectorObject::create());
-    }
-""")
diff --git a/inspector/scripts/codegen/__init__.py b/inspector/scripts/codegen/__init__.py
new file mode 100644 (file)
index 0000000..6077fa9
--- /dev/null
@@ -0,0 +1,24 @@
+# Required for Python to search this directory for module files
+
+from models import *
+from generator import *
+from cpp_generator import *
+from objc_generator import *
+
+from generate_cpp_alternate_backend_dispatcher_header import *
+from generate_cpp_backend_dispatcher_header import *
+from generate_cpp_backend_dispatcher_implementation import *
+from generate_cpp_frontend_dispatcher_header import *
+from generate_cpp_frontend_dispatcher_implementation import *
+from generate_cpp_protocol_types_header import *
+from generate_cpp_protocol_types_implementation import *
+from generate_js_backend_commands import *
+from generate_objc_backend_dispatcher_header import *
+from generate_objc_backend_dispatcher_implementation import *
+from generate_objc_configuration_header import *
+from generate_objc_configuration_implementation import *
+from generate_objc_conversion_helpers import *
+from generate_objc_frontend_dispatcher_implementation import *
+from generate_objc_header import *
+from generate_objc_internal_header import *
+from generate_objc_protocol_types_implementation import *
diff --git a/inspector/scripts/codegen/cpp_generator.py b/inspector/scripts/codegen/cpp_generator.py
new file mode 100644 (file)
index 0000000..edd330d
--- /dev/null
@@ -0,0 +1,314 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import os.path
+import re
+
+from generator import ucfirst
+from models import PrimitiveType, ObjectType, ArrayType, EnumType, AliasedType, Frameworks
+
+log = logging.getLogger('global')
+
+_PRIMITIVE_TO_CPP_NAME_MAP = {
+    'boolean': 'bool',
+    'integer': 'int',
+    'number': 'double',
+    'string': 'String',
+    'object': 'Inspector::InspectorObject',
+    'array': 'Inspector::InspectorArray',
+    'any': 'Inspector::InspectorValue'
+}
+
+# This class contains extra static methods used for generation, but does
+# not participate in any inheritance hierarchy. File generators should
+# extend the generic "Generator" class instead.
+class CppGenerator:
+
+    # Miscellaneous text manipulation routines.
+    @staticmethod
+    def cpp_getter_method_for_type(_type):
+        if isinstance(_type, ObjectType):
+            return 'getObject'
+        if isinstance(_type, ArrayType):
+            return 'getArray'
+        if isinstance(_type, PrimitiveType):
+            if _type.raw_name() is 'integer':
+                return 'getInteger'
+            elif _type.raw_name() is 'number':
+                return 'getDouble'
+            elif _type.raw_name() is 'any':
+                return 'getValue'
+            else:
+                return 'get' + ucfirst(_type.raw_name())
+        if isinstance(_type, AliasedType):
+            return CppGenerator.cpp_getter_method_for_type(_type.aliased_type)
+        if isinstance(_type, EnumType):
+            return CppGenerator.cpp_getter_method_for_type(_type.primitive_type)
+
+    @staticmethod
+    def cpp_setter_method_for_type(_type):
+        if isinstance(_type, ObjectType):
+            return 'setObject'
+        if isinstance(_type, ArrayType):
+            return 'setArray'
+        if isinstance(_type, PrimitiveType):
+            if _type.raw_name() is 'integer':
+                return 'setInteger'
+            elif _type.raw_name() is 'number':
+                return 'setDouble'
+            elif _type.raw_name() is 'any':
+                return 'setValue'
+            else:
+                return 'set' + ucfirst(_type.raw_name())
+        if isinstance(_type, AliasedType):
+            return CppGenerator.cpp_setter_method_for_type(_type.aliased_type)
+        if isinstance(_type, EnumType):
+            return CppGenerator.cpp_setter_method_for_type(_type.primitive_type)
+
+    # Generate type representations for various situations.
+    @staticmethod
+    def cpp_protocol_type_for_type(_type):
+        if isinstance(_type, ObjectType) and len(_type.members) == 0:
+            return 'Inspector::InspectorObject'
+        if isinstance(_type, ArrayType):
+            if _type.raw_name() is None:  # Otherwise, fall through and use typedef'd name.
+                return 'Inspector::Protocol::Array<%s>' % CppGenerator.cpp_protocol_type_for_type(_type.element_type)
+        if isinstance(_type, (ObjectType, AliasedType, EnumType, ArrayType)):
+            return 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name())
+        if isinstance(_type, PrimitiveType):
+            return CppGenerator.cpp_name_for_primitive_type(_type)
+
+    @staticmethod
+    def cpp_protocol_type_for_type_member(type_member, object_declaration):
+        if isinstance(type_member.type, EnumType) and type_member.type.is_anonymous:
+            return '::'.join([CppGenerator.cpp_protocol_type_for_type(object_declaration.type), ucfirst(type_member.member_name)])
+        else:
+            return CppGenerator.cpp_protocol_type_for_type(type_member.type)
+
+    @staticmethod
+    def cpp_type_for_unchecked_formal_in_parameter(parameter):
+        _type = parameter.type
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type  # Fall through to enum or primitive.
+
+        if isinstance(_type, EnumType):
+            _type = _type.primitive_type  # Fall through to primitive.
+
+        # This handles the 'any' type and objects with defined properties.
+        if isinstance(_type, ObjectType) or _type.qualified_name() is 'object':
+            cpp_name = 'Inspector::InspectorObject'
+            if parameter.is_optional:
+                return 'const %s*' % cpp_name
+            else:
+                return 'const %s&' % cpp_name
+        if isinstance(_type, ArrayType):
+            cpp_name = 'Inspector::InspectorArray'
+            if parameter.is_optional:
+                return 'const %s*' % cpp_name
+            else:
+                return 'const %s&' % cpp_name
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if parameter.is_optional:
+                return 'const %s*' % cpp_name
+            elif _type.raw_name() in ['string']:
+                return 'const %s&' % cpp_name
+            else:
+                return cpp_name
+
+        return "unknown_unchecked_formal_in_parameter_type"
+
+    @staticmethod
+    def cpp_type_for_checked_formal_event_parameter(parameter):
+        return CppGenerator.cpp_type_for_type_with_name(parameter.type, parameter.parameter_name, parameter.is_optional)
+
+    @staticmethod
+    def cpp_type_for_type_member(member):
+        return CppGenerator.cpp_type_for_type_with_name(member.type, member.member_name, False)
+
+    @staticmethod
+    def cpp_type_for_type_with_name(_type, type_name, is_optional):
+        if isinstance(_type, (ArrayType, ObjectType)):
+            return 'RefPtr<%s>' % CppGenerator.cpp_protocol_type_for_type(_type)
+        if isinstance(_type, AliasedType):
+            builder_type = CppGenerator.cpp_protocol_type_for_type(_type)
+            if is_optional:
+                return 'const %s* const' % builder_type
+            elif _type.aliased_type.qualified_name() in ['integer', 'number']:
+                return CppGenerator.cpp_name_for_primitive_type(_type.aliased_type)
+            elif _type.aliased_type.qualified_name() in ['string']:
+                return 'const %s&' % builder_type
+            else:
+                return builder_type
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if _type.qualified_name() in ['object']:
+                return 'RefPtr<Inspector::InspectorObject>'
+            elif _type.qualified_name() in ['any']:
+                return 'RefPtr<Inspector::InspectorValue>'
+            elif is_optional:
+                return 'const %s* const' % cpp_name
+            elif _type.qualified_name() in ['string']:
+                return 'const %s&' % cpp_name
+            else:
+                return cpp_name
+        if isinstance(_type, EnumType):
+            if _type.is_anonymous:
+                enum_type_name = ucfirst(type_name)
+            else:
+                enum_type_name = 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name())
+
+            if is_optional:
+                return '%s*' % enum_type_name
+            else:
+                return '%s' % enum_type_name
+
+    @staticmethod
+    def cpp_type_for_formal_out_parameter(parameter):
+        _type = parameter.type
+
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type  # Fall through.
+
+        if isinstance(_type, (ObjectType, ArrayType)):
+            return 'RefPtr<%s>&' % CppGenerator.cpp_protocol_type_for_type(_type)
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if parameter.is_optional:
+                return "Inspector::Protocol::OptOutput<%s>*" % cpp_name
+            else:
+                return '%s*' % cpp_name
+        if isinstance(_type, EnumType):
+            if _type.is_anonymous:
+                return '%sBackendDispatcherHandler::%s*' % (_type.type_domain().domain_name, ucfirst(parameter.parameter_name))
+            else:
+                return 'Inspector::Protocol::%s::%s*' % (_type.type_domain().domain_name, _type.raw_name())
+
+        raise ValueError("unknown formal out parameter type.")
+
+    # FIXME: this is only slightly different from out parameters; they could be unified.
+    @staticmethod
+    def cpp_type_for_formal_async_parameter(parameter):
+        _type = parameter.type
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type  # Fall through.
+
+        if isinstance(_type, EnumType):
+            _type = _type.primitive_type  # Fall through.
+
+        if isinstance(_type, (ObjectType, ArrayType)):
+            return 'RefPtr<%s>&&' % CppGenerator.cpp_protocol_type_for_type(_type)
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if parameter.is_optional:
+                return "Inspector::Protocol::OptOutput<%s>*" % cpp_name
+            elif _type.qualified_name() in ['integer', 'number']:
+                return CppGenerator.cpp_name_for_primitive_type(_type)
+            elif _type.qualified_name() in ['string']:
+                return 'const %s&' % cpp_name
+            else:
+                return cpp_name
+
+        raise ValueError("Unknown formal async parameter type.")
+
+    # In-parameters don't use builder types, because they could be passed
+    # "open types" that are manually constructed out of InspectorObjects.
+
+    # FIXME: Only parameters that are actually open types should need non-builder parameter types.
+    @staticmethod
+    def cpp_type_for_stack_in_parameter(parameter):
+        _type = parameter.type
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type  # Fall through.
+
+        if isinstance(_type, EnumType):
+            _type = _type.primitive_type  # Fall through.
+
+        if isinstance(_type, ObjectType):
+            return "RefPtr<Inspector::InspectorObject>"
+        if isinstance(_type, ArrayType):
+            return "RefPtr<Inspector::InspectorArray>"
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if _type.qualified_name() in ['any', 'object']:
+                return "RefPtr<%s>" % CppGenerator.cpp_name_for_primitive_type(_type)
+            elif parameter.is_optional and _type.qualified_name() not in ['boolean', 'string', 'integer']:
+                return "Inspector::Protocol::OptOutput<%s>" % cpp_name
+            else:
+                return cpp_name
+
+    @staticmethod
+    def cpp_type_for_stack_out_parameter(parameter):
+        _type = parameter.type
+        if isinstance(_type, (ArrayType, ObjectType)):
+            return 'RefPtr<%s>' % CppGenerator.cpp_protocol_type_for_type(_type)
+        if isinstance(_type, AliasedType):
+            builder_type = CppGenerator.cpp_protocol_type_for_type(_type)
+            if parameter.is_optional:
+                return "Inspector::Protocol::OptOutput<%s>" % builder_type
+            return '%s' % builder_type
+        if isinstance(_type, PrimitiveType):
+            cpp_name = CppGenerator.cpp_name_for_primitive_type(_type)
+            if parameter.is_optional:
+                return "Inspector::Protocol::OptOutput<%s>" % cpp_name
+            else:
+                return cpp_name
+        if isinstance(_type, EnumType):
+            if _type.is_anonymous:
+                return '%sBackendDispatcherHandler::%s' % (_type.type_domain().domain_name, ucfirst(parameter.parameter_name))
+            else:
+                return 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name())
+
+    @staticmethod
+    def cpp_assertion_method_for_type_member(type_member, object_declaration):
+
+        def assertion_method_for_type(_type):
+            return 'BindingTraits<%s>::assertValueHasExpectedType' % CppGenerator.cpp_protocol_type_for_type(_type)
+
+        if isinstance(type_member.type, AliasedType):
+            return assertion_method_for_type(type_member.type.aliased_type)
+        if isinstance(type_member.type, EnumType) and type_member.type.is_anonymous:
+            return 'BindingTraits<%s>::assertValueHasExpectedType' % CppGenerator.cpp_protocol_type_for_type_member(type_member, object_declaration)
+
+        return assertion_method_for_type(type_member.type)
+
+    @staticmethod
+    def cpp_name_for_primitive_type(_type):
+        return _PRIMITIVE_TO_CPP_NAME_MAP.get(_type.raw_name())
+
+    # Decide whether certain helpers are necessary in a situation.
+    @staticmethod
+    def should_use_wrapper_for_return_type(_type):
+        return not isinstance(_type, (ArrayType, ObjectType))
+
+    @staticmethod
+    def should_use_references_for_type(_type):
+        return isinstance(_type, (ArrayType, ObjectType)) or (isinstance(_type, (PrimitiveType)) and _type.qualified_name() in ["any", "object"])
+
+    @staticmethod
+    def should_pass_by_copy_for_return_type(_type):
+        return isinstance(_type, (ArrayType, ObjectType)) or (isinstance(_type, (PrimitiveType)) and _type.qualified_name() == "object")
diff --git a/inspector/scripts/codegen/cpp_generator_templates.py b/inspector/scripts/codegen/cpp_generator_templates.py
new file mode 100755 (executable)
index 0000000..05f3530
--- /dev/null
@@ -0,0 +1,263 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generator templates, which can be filled with string.Template.
+# Following are classes that fill the templates from the typechecked model.
+
+class CppGeneratorTemplates:
+
+    HeaderPrelude = (
+    """#ifndef ${headerGuardString}
+#define ${headerGuardString}
+
+${includes}
+
+namespace Inspector {
+
+${typedefs}""")
+
+    HeaderPostlude = (
+    """} // namespace Inspector
+
+#endif // !defined(${headerGuardString})""")
+
+    ImplementationPrelude = (
+    """#include "config.h"
+#include ${primaryInclude}
+
+${secondaryIncludes}
+
+namespace Inspector {""")
+
+    ImplementationPostlude = (
+    """} // namespace Inspector
+""")
+
+    AlternateDispatchersHeaderPrelude = (
+    """#ifndef ${headerGuardString}
+#define ${headerGuardString}
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+${includes}
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+""")
+
+    AlternateDispatchersHeaderPostlude = (
+    """} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(${headerGuardString})""")
+
+    AlternateBackendDispatcherHeaderDomainHandlerInterfaceDeclaration = (
+    """class Alternate${domainName}BackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~Alternate${domainName}BackendDispatcher() { }
+${commandDeclarations}
+};""")
+
+    BackendDispatcherHeaderDomainHandlerDeclaration = (
+    """${classAndExportMacro} ${domainName}BackendDispatcherHandler {
+public:
+${commandDeclarations}
+protected:
+    virtual ~${domainName}BackendDispatcherHandler();
+};""")
+
+    BackendDispatcherHeaderDomainDispatcherDeclaration = (
+    """${classAndExportMacro} ${domainName}BackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<${domainName}BackendDispatcher> create(BackendDispatcher*, ${domainName}BackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+${commandDeclarations}
+private:
+    ${domainName}BackendDispatcher(BackendDispatcher&, ${domainName}BackendDispatcherHandler*);
+    ${domainName}BackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(Alternate${domainName}BackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    Alternate${domainName}BackendDispatcher* m_alternateDispatcher;
+#endif
+};""")
+
+    BackendDispatcherHeaderAsyncCommandDeclaration = (
+    """    ${classAndExportMacro} ${callbackName} : public BackendDispatcher::CallbackBase {
+    public:
+        ${callbackName}(Ref<BackendDispatcher>&&, int id);
+        void sendSuccess(${outParameters});
+    };
+    virtual void ${commandName}(${inParameters}) = 0;""")
+
+    BackendDispatcherImplementationSmallSwitch = (
+    """void ${domainName}BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<${domainName}BackendDispatcher> protect(*this);
+
+${dispatchCases}
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
+}""")
+
+    BackendDispatcherImplementationLargeSwitch = (
+"""void ${domainName}BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<${domainName}BackendDispatcher> protect(*this);
+
+    typedef void (${domainName}BackendDispatcher::*CallHandler)(long callId, const InspectorObject& message);
+    typedef HashMap<String, CallHandler> DispatchMap;
+    DEPRECATED_DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
+    if (dispatchMap.isEmpty()) {
+        static const struct MethodTable {
+            const char* name;
+            CallHandler handler;
+        } commands[] = {
+${dispatchCases}
+        };
+        size_t length = WTF_ARRAY_LENGTH(commands);
+        for (size_t i = 0; i < length; ++i)
+            dispatchMap.add(commands[i].name, commands[i].handler);
+    }
+
+    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
+    if (it == dispatchMap.end()) {
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\\'', "${domainName}", '.', method, "' was not found"));
+        return;
+    }
+
+    ((*this).*it->value)(callId, message.get());
+}""")
+
+    BackendDispatcherImplementationDomainConstructor = (
+    """Ref<${domainName}BackendDispatcher> ${domainName}BackendDispatcher::create(BackendDispatcher* backendDispatcher, ${domainName}BackendDispatcherHandler* agent)
+{
+    return adoptRef(*new ${domainName}BackendDispatcher(*backendDispatcher, agent));
+}
+
+${domainName}BackendDispatcher::${domainName}BackendDispatcher(BackendDispatcher& backendDispatcher, ${domainName}BackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("${domainName}"), this);
+}""")
+
+    BackendDispatcherImplementationPrepareCommandArguments = (
+"""    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+${inParameterDeclarations}
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method \'%s\' can't be processed", "${domainName}.${commandName}");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+""")
+
+    BackendDispatcherImplementationAsyncCommand = (
+"""${domainName}BackendDispatcherHandler::${callbackName}::${callbackName}(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTF::move(backendDispatcher), id) { }
+
+void ${domainName}BackendDispatcherHandler::${callbackName}::sendSuccess(${formalParameters})
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+${outParameterAssignments}
+    sendIfActive(WTF::move(jsonMessage), ErrorString());
+}""")
+
+    FrontendDispatcherDomainDispatcherDeclaration = (
+"""${classAndExportMacro} ${domainName}FrontendDispatcher {
+public:
+    ${domainName}FrontendDispatcher(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
+${eventDeclarations}
+private:
+    FrontendChannel* m_frontendChannel;
+};""")
+
+    ProtocolObjectBuilderDeclarationPrelude = (
+"""    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*${objectType}*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class ${objectType};
+    public:""")
+
+    ProtocolObjectBuilderDeclarationPostlude = (
+"""
+        Ref<${objectType}> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(${objectType}) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<${objectType}>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+${constructorExample}
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }""")
+
+    ProtocolObjectRuntimeCast = (
+"""RefPtr<${objectType}> BindingTraits<${objectType}>::runtimeCast(RefPtr<InspectorValue>&& value)
+{
+    RefPtr<InspectorObject> result;
+    bool castSucceeded = value->asObject(result);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+#if !ASSERT_DISABLED
+    BindingTraits<${objectType}>::assertValueHasExpectedType(result.get());
+#endif  // !ASSERT_DISABLED
+    COMPILE_ASSERT(sizeof(${objectType}) == sizeof(InspectorObjectBase), type_cast_problem);
+    return static_cast<${objectType}*>(static_cast<InspectorObjectBase*>(result.get()));
+}
+""")
diff --git a/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py b/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py
new file mode 100755 (executable)
index 0000000..d4a8d5a
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+import re
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator
+
+log = logging.getLogger('global')
+
+
+class CppAlternateBackendDispatcherHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return 'InspectorAlternateBackendDispatchers.h'
+
+    def generate_output(self):
+        headers = [
+            '"InspectorProtocolTypes.h"',
+            '<JavaScriptCore/InspectorBackendDispatcher.h>',
+        ]
+
+        header_args = {
+            'headerGuardString': re.sub('\W+', '_', self.output_filename()),
+            'includes': '\n'.join(['#include ' + header for header in headers]),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.AlternateDispatchersHeaderPrelude).substitute(None, **header_args))
+        sections.append('\n'.join(filter(None, map(self._generate_handler_declarations_for_domain, domains))))
+        sections.append(Template(CppTemplates.AlternateDispatchersHeaderPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_handler_declarations_for_domain(self, domain):
+        if not domain.commands:
+            return ''
+
+        command_declarations = []
+        for command in domain.commands:
+            command_declarations.append(self._generate_handler_declaration_for_command(command))
+
+        handler_args = {
+            'domainName': domain.domain_name,
+            'commandDeclarations': '\n'.join(command_declarations),
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(CppTemplates.AlternateBackendDispatcherHeaderDomainHandlerInterfaceDeclaration).substitute(None, **handler_args))
+
+    def _generate_handler_declaration_for_command(self, command):
+        lines = []
+        parameters = ['long callId']
+        for _parameter in command.call_parameters:
+            parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name))
+
+        command_args = {
+            'commandName': command.command_name,
+            'parameters': ', '.join(parameters),
+        }
+        lines.append('    virtual void %(commandName)s(%(parameters)s) = 0;' % command_args)
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py b/inspector/scripts/codegen/generate_cpp_backend_dispatcher_header.py
new file mode 100755 (executable)
index 0000000..54bdb3e
--- /dev/null
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import re
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import EnumType
+
+log = logging.getLogger('global')
+
+
+class CppBackendDispatcherHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorBackendDispatchers.h"
+
+    def domains_to_generate(self):
+        return filter(lambda domain: len(domain.commands) > 0, Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        headers = [
+            '"InspectorProtocolObjects.h"',
+            '<inspector/InspectorBackendDispatcher.h>',
+            '<wtf/text/WTFString.h>']
+
+        typedefs = [('String', 'ErrorString')]
+
+        header_args = {
+            'headerGuardString': re.sub('\W+', '_', self.output_filename()),
+            'includes': '\n'.join(['#include ' + header for header in headers]),
+            'typedefs': '\n'.join(['typedef %s %s;' % typedef for typedef in typedefs]),
+        }
+
+        domains = self.domains_to_generate()
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.HeaderPrelude).substitute(None, **header_args))
+        sections.append(self._generate_alternate_handler_forward_declarations_for_domains(domains))
+        sections.extend(map(self._generate_handler_declarations_for_domain, domains))
+        sections.extend(map(self._generate_dispatcher_declarations_for_domain, domains))
+        sections.append(Template(CppTemplates.HeaderPostlude).substitute(None, **header_args))
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    def _generate_alternate_handler_forward_declarations_for_domains(self, domains):
+        if not domains:
+            return ''
+
+        lines = []
+        lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
+        for domain in domains:
+            lines.append(self.wrap_with_guard_for_domain(domain, 'class Alternate%sBackendDispatcher;' % domain.domain_name))
+        lines.append('#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
+        return '\n'.join(lines)
+
+    def _generate_handler_declarations_for_domain(self, domain):
+        classComponents = ['class']
+        exportMacro = self.model().framework.setting('export_macro', None)
+        if exportMacro is not None:
+            classComponents.append(exportMacro)
+
+        used_enum_names = set()
+
+        command_declarations = []
+        for command in domain.commands:
+            command_declarations.append(self._generate_handler_declaration_for_command(command, used_enum_names))
+
+        handler_args = {
+            'classAndExportMacro': " ".join(classComponents),
+            'domainName': domain.domain_name,
+            'commandDeclarations': "\n".join(command_declarations)
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(CppTemplates.BackendDispatcherHeaderDomainHandlerDeclaration).substitute(None, **handler_args))
+
+    def _generate_anonymous_enum_for_parameter(self, parameter, command):
+        enum_args = {
+            'parameterName': parameter.parameter_name,
+            'commandName': command.command_name
+        }
+
+        lines = []
+        lines.append('    // Named after parameter \'%(parameterName)s\' while generating command/event %(commandName)s.' % enum_args)
+        lines.append('    enum class %s {' % ucfirst(parameter.parameter_name))
+        for enum_value in parameter.type.enum_values():
+            lines.append('        %s = %d,' % (Generator.stylized_name_for_enum_value(enum_value), self.encoding_for_enum_value(enum_value)))
+        lines.append('    }; // enum class %s' % ucfirst(parameter.parameter_name))
+        return '\n'.join(lines)
+
+    def _generate_handler_declaration_for_command(self, command, used_enum_names):
+        if command.is_async:
+            return self._generate_async_handler_declaration_for_command(command)
+
+        lines = []
+        parameters = ['ErrorString&']
+        for _parameter in command.call_parameters:
+            parameter_name = 'in_' + _parameter.parameter_name
+            if _parameter.is_optional:
+                parameter_name = 'opt_' + parameter_name
+
+            parameters.append("%s %s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), parameter_name))
+
+            if isinstance(_parameter.type, EnumType) and _parameter.parameter_name not in used_enum_names:
+                lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command))
+                used_enum_names.add(_parameter.parameter_name)
+
+        for _parameter in command.return_parameters:
+            parameter_name = 'out_' + _parameter.parameter_name
+            if _parameter.is_optional:
+                parameter_name = 'opt_' + parameter_name
+            parameters.append("%s %s" % (CppGenerator.cpp_type_for_formal_out_parameter(_parameter), parameter_name))
+
+            if isinstance(_parameter.type, EnumType) and _parameter.parameter_name not in used_enum_names:
+                lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command))
+                used_enum_names.add(_parameter.parameter_name)
+
+        command_args = {
+            'commandName': command.command_name,
+            'parameters': ", ".join(parameters)
+        }
+        lines.append('    virtual void %(commandName)s(%(parameters)s) = 0;' % command_args)
+        return '\n'.join(lines)
+
+    def _generate_async_handler_declaration_for_command(self, command):
+        callbackName = "%sCallback" % ucfirst(command.command_name)
+
+        in_parameters = ['ErrorString&']
+        for _parameter in command.call_parameters:
+            parameter_name = 'in_' + _parameter.parameter_name
+            if _parameter.is_optional:
+                parameter_name = 'opt_' + parameter_name
+
+            in_parameters.append("%s %s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), parameter_name))
+        in_parameters.append("Ref<%s>&& callback" % callbackName)
+
+        out_parameters = []
+        for _parameter in command.return_parameters:
+            out_parameters.append("%s %s" % (CppGenerator.cpp_type_for_formal_async_parameter(_parameter), _parameter.parameter_name))
+
+        class_components = ['class']
+        export_macro = self.model().framework.setting('export_macro', None)
+        if export_macro:
+            class_components.append(export_macro)
+
+        command_args = {
+            'classAndExportMacro': ' '.join(class_components),
+            'callbackName': callbackName,
+            'commandName': command.command_name,
+            'inParameters': ", ".join(in_parameters),
+            'outParameters': ", ".join(out_parameters),
+        }
+
+        return Template(CppTemplates.BackendDispatcherHeaderAsyncCommandDeclaration).substitute(None, **command_args)
+
+    def _generate_dispatcher_declarations_for_domain(self, domain):
+        classComponents = ['class']
+        exportMacro = self.model().framework.setting('export_macro', None)
+        if exportMacro is not None:
+            classComponents.append(exportMacro)
+
+        declarations = []
+        if len(domain.commands) > 0:
+            declarations.append('private:')
+        declarations.extend(map(self._generate_dispatcher_declaration_for_command, domain.commands))
+
+        handler_args = {
+            'classAndExportMacro': " ".join(classComponents),
+            'domainName': domain.domain_name,
+            'commandDeclarations': "\n".join(declarations)
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(CppTemplates.BackendDispatcherHeaderDomainDispatcherDeclaration).substitute(None, **handler_args))
+
+    def _generate_dispatcher_declaration_for_command(self, command):
+        return "    void %s(long callId, const InspectorObject& message);" % command.command_name
diff --git a/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py b/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py
new file mode 100755 (executable)
index 0000000..350f085
--- /dev/null
@@ -0,0 +1,310 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import ObjectType, ArrayType
+
+log = logging.getLogger('global')
+
+
+class CppBackendDispatcherImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorBackendDispatchers.cpp"
+
+    def domains_to_generate(self):
+        return filter(lambda domain: len(domain.commands) > 0, Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        secondary_headers = [
+            '<inspector/InspectorFrontendChannel.h>',
+            '<inspector/InspectorValues.h>',
+            '<wtf/text/CString.h>']
+
+        secondary_includes = ['#include %s' % header for header in secondary_headers]
+        secondary_includes.append('')
+        secondary_includes.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
+        secondary_includes.append('#include "InspectorAlternateBackendDispatchers.h"')
+        secondary_includes.append('#endif')
+
+        header_args = {
+            'primaryInclude': '"InspectorBackendDispatchers.h"',
+            'secondaryIncludes': '\n'.join(secondary_includes),
+        }
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.append("\n".join(map(self._generate_handler_class_destructor_for_domain, self.domains_to_generate())))
+        sections.extend(map(self._generate_dispatcher_implementations_for_domain, self.domains_to_generate()))
+        sections.append(Template(CppTemplates.ImplementationPostlude).substitute(None, **header_args))
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    def _generate_handler_class_destructor_for_domain(self, domain):
+        destructor_args = {
+            'domainName': domain.domain_name
+        }
+        destructor = '%(domainName)sBackendDispatcherHandler::~%(domainName)sBackendDispatcherHandler() { }' % destructor_args
+        return self.wrap_with_guard_for_domain(domain, destructor)
+
+    def _generate_dispatcher_implementations_for_domain(self, domain):
+        implementations = []
+
+        constructor_args = {
+            'domainName': domain.domain_name,
+        }
+        implementations.append(Template(CppTemplates.BackendDispatcherImplementationDomainConstructor).substitute(None, **constructor_args))
+
+        if len(domain.commands) <= 5:
+            implementations.append(self._generate_small_dispatcher_switch_implementation_for_domain(domain))
+        else:
+            implementations.append(self._generate_large_dispatcher_switch_implementation_for_domain(domain))
+
+        for command in domain.commands:
+            if command.is_async:
+                implementations.append(self._generate_async_dispatcher_class_for_domain(command, domain))
+            implementations.append(self._generate_dispatcher_implementation_for_command(command, domain))
+
+        return self.wrap_with_guard_for_domain(domain, '\n\n'.join(implementations))
+
+    def _generate_small_dispatcher_switch_implementation_for_domain(self, domain):
+        cases = []
+        cases.append('    if (method == "%s")' % domain.commands[0].command_name)
+        cases.append('        %s(callId, message);' % domain.commands[0].command_name)
+        for command in domain.commands[1:]:
+            cases.append('    else if (method == "%s")' % command.command_name)
+            cases.append('        %s(callId, message);' % command.command_name)
+
+        switch_args = {
+            'domainName': domain.domain_name,
+            'dispatchCases': "\n".join(cases)
+        }
+
+        return Template(CppTemplates.BackendDispatcherImplementationSmallSwitch).substitute(None, **switch_args)
+
+    def _generate_large_dispatcher_switch_implementation_for_domain(self, domain):
+        cases = []
+        for command in domain.commands:
+            args = {
+                'domainName': domain.domain_name,
+                'commandName': command.command_name
+            }
+            cases.append('            { "%(commandName)s", &%(domainName)sBackendDispatcher::%(commandName)s },' % args)
+
+        switch_args = {
+            'domainName': domain.domain_name,
+            'dispatchCases': "\n".join(cases)
+        }
+
+        return Template(CppTemplates.BackendDispatcherImplementationLargeSwitch).substitute(None, **switch_args)
+
+    def _generate_async_dispatcher_class_for_domain(self, command, domain):
+        out_parameter_assignments = []
+        formal_parameters = []
+
+        for parameter in command.return_parameters:
+            param_args = {
+                'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type),
+                'parameterKey': parameter.parameter_name,
+                'parameterName': parameter.parameter_name,
+                'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter),
+            }
+
+            formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_formal_async_parameter(parameter), parameter.parameter_name))
+
+            if parameter.is_optional:
+                if CppGenerator.should_use_wrapper_for_return_type(parameter.type):
+                    out_parameter_assignments.append('    if (%(parameterName)s.isAssigned())' % param_args)
+                    out_parameter_assignments.append('        jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s.getValue());' % param_args)
+                else:
+                    out_parameter_assignments.append('    if (%(parameterName)s)' % param_args)
+                    out_parameter_assignments.append('        jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s);' % param_args)
+            elif parameter.type.is_enum():
+                out_parameter_assignments.append('    jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::getEnumConstantValue(%(parameterName)s));' % param_args)
+            else:
+                out_parameter_assignments.append('    jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s);' % param_args)
+
+        async_args = {
+            'domainName': domain.domain_name,
+            'callbackName': ucfirst(command.command_name) + 'Callback',
+            'formalParameters': ", ".join(formal_parameters),
+            'outParameterAssignments': "\n".join(out_parameter_assignments)
+        }
+        return Template(CppTemplates.BackendDispatcherImplementationAsyncCommand).substitute(None, **async_args)
+
+    def _generate_dispatcher_implementation_for_command(self, command, domain):
+        in_parameter_declarations = []
+        out_parameter_declarations = []
+        out_parameter_assignments = []
+        alternate_dispatcher_method_parameters = ['callId']
+        method_parameters = ['error']
+
+        for parameter in command.call_parameters:
+            parameter_name = 'in_' + parameter.parameter_name
+            if parameter.is_optional:
+                parameter_name = 'opt_' + parameter_name
+
+            out_success_argument = 'nullptr'
+            if parameter.is_optional:
+                out_success_argument = '&%s_valueFound' % parameter_name
+                in_parameter_declarations.append('    bool %s_valueFound = false;' % parameter_name)
+
+            # Now add appropriate operators.
+            parameter_expression = parameter_name
+
+            if CppGenerator.should_use_references_for_type(parameter.type):
+                if parameter.is_optional:
+                    parameter_expression = '%s.get()' % parameter_expression
+                else:
+                    # This assumes that we have already proved the object is non-null.
+                    # If a required property is missing, InspectorBackend::getObject will
+                    # append a protocol error, and the method dispatcher will return without
+                    # invoking the backend method (and dereferencing the object).
+                    parameter_expression = '*%s' % parameter_expression
+            elif parameter.is_optional:
+                parameter_expression = '&%s' % parameter_expression
+
+            param_args = {
+                'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter),
+                'parameterKey': parameter.parameter_name,
+                'parameterName': parameter_name,
+                'parameterExpression': parameter_expression,
+                'keyedGetMethod': CppGenerator.cpp_getter_method_for_type(parameter.type),
+                'successOutParam': out_success_argument
+            }
+
+            in_parameter_declarations.append('    %(parameterType)s %(parameterName)s = BackendDispatcher::%(keyedGetMethod)s(paramsContainer.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s, protocolErrors.get());' % param_args)
+
+            if parameter.is_optional:
+                optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args
+                alternate_dispatcher_method_parameters.append(optional_in_parameter_string)
+                method_parameters.append(optional_in_parameter_string)
+            else:
+                alternate_dispatcher_method_parameters.append(parameter_expression)
+                method_parameters.append(parameter_expression)
+
+        if command.is_async:
+            async_args = {
+                'domainName': domain.domain_name,
+                'callbackName': ucfirst(command.command_name) + 'Callback'
+            }
+
+            out_parameter_assignments.append('        callback->disable();')
+            out_parameter_assignments.append('        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);')
+            out_parameter_assignments.append('        return;')
+            method_parameters.append('callback.copyRef()')
+
+        else:
+            for parameter in command.return_parameters:
+                param_args = {
+                    'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter),
+                    'parameterKey': parameter.parameter_name,
+                    'parameterName': parameter.parameter_name,
+                    'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type),
+
+                }
+
+                out_parameter_declarations.append('    %(parameterType)s out_%(parameterName)s;' % param_args)
+                if parameter.is_optional:
+                    if CppGenerator.should_use_wrapper_for_return_type(parameter.type):
+                        out_parameter_assignments.append('        if (out_%(parameterName)s.isAssigned())' % param_args)
+                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s.getValue());' % param_args)
+                    else:
+                        out_parameter_assignments.append('        if (out_%(parameterName)s)' % param_args)
+                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args)
+                elif parameter.type.is_enum():
+                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));' % param_args)
+                else:
+                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args)
+
+                if CppGenerator.should_pass_by_copy_for_return_type(parameter.type):
+                    method_parameters.append('out_' + parameter.parameter_name)
+                else:
+                    method_parameters.append('&out_' + parameter.parameter_name)
+
+        command_args = {
+            'domainName': domain.domain_name,
+            'callbackName': '%sCallback' % ucfirst(command.command_name),
+            'commandName': command.command_name,
+            'inParameterDeclarations': '\n'.join(in_parameter_declarations),
+            'invocationParameters': ', '.join(method_parameters),
+            'alternateInvocationParameters': ', '.join(alternate_dispatcher_method_parameters),
+        }
+
+        lines = []
+        if len(command.call_parameters) == 0:
+            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject&)' % command_args)
+        else:
+            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject& message)' % command_args)
+        lines.append('{')
+
+        if len(command.call_parameters) > 0:
+            lines.append(Template(CppTemplates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args))
+
+        lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
+        lines.append('    if (m_alternateDispatcher) {')
+        lines.append('        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);' % command_args)
+        lines.append('        return;')
+        lines.append('    }')
+        lines.append('#endif')
+        lines.append('')
+
+        lines.append('    ErrorString error;')
+        lines.append('    Ref<InspectorObject> result = InspectorObject::create();')
+        if command.is_async:
+            lines.append('    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), callId));' % command_args)
+        if len(command.return_parameters) > 0:
+            lines.extend(out_parameter_declarations)
+        lines.append('    m_agent->%(commandName)s(%(invocationParameters)s);' % command_args)
+        lines.append('')
+        if command.is_async:
+            lines.append('    if (error.length()) {')
+            lines.extend(out_parameter_assignments)
+            lines.append('    }')
+        elif len(command.return_parameters) > 1:
+            lines.append('    if (!error.length()) {')
+            lines.extend(out_parameter_assignments)
+            lines.append('    }')
+        elif len(command.return_parameters) == 1:
+            lines.append('    if (!error.length())')
+            lines.extend(out_parameter_assignments)
+            lines.append('')
+
+        if not command.is_async:
+            lines.append('    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);')
+        lines.append('}')
+        return "\n".join(lines)
diff --git a/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py b/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_header.py
new file mode 100755 (executable)
index 0000000..ff09ab3
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import re
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import EnumType
+
+log = logging.getLogger('global')
+
+
+class CppFrontendDispatcherHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorFrontendDispatchers.h"
+
+    def domains_to_generate(self):
+        return filter(lambda domain: len(domain.events) > 0, Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        headers = [
+            '"InspectorProtocolObjects.h"',
+            '<inspector/InspectorFrontendChannel.h>',
+            '<inspector/InspectorValues.h>',
+            '<wtf/text/WTFString.h>']
+
+        header_args = {
+            'headerGuardString': re.sub('\W+', '_', self.output_filename()),
+            'includes': '\n'.join(['#include ' + header for header in headers]),
+            'typedefs': '',
+        }
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.HeaderPrelude).substitute(None, **header_args))
+        sections.extend(map(self._generate_dispatcher_declarations_for_domain, self.domains_to_generate()))
+        sections.append(Template(CppTemplates.HeaderPostlude).substitute(None, **header_args))
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    def _generate_anonymous_enum_for_parameter(self, parameter, event):
+        enum_args = {
+            'parameterName': parameter.parameter_name,
+            'eventName': event.event_name
+        }
+
+        lines = []
+        lines.append('        // Named after parameter \'%(parameterName)s\' while generating command/event %(eventName)s.' % enum_args)
+        lines.append('        enum class %s {' % ucfirst(parameter.parameter_name))
+        for enum_value in parameter.type.enum_values():
+            lines.append('            %s = %d,' % (Generator.stylized_name_for_enum_value(enum_value), self.encoding_for_enum_value(enum_value)))
+        lines.append('        }; // enum class %s' % ucfirst(parameter.parameter_name))
+        return "\n".join(lines)
+
+    def _generate_dispatcher_declarations_for_domain(self, domain):
+        classComponents = ['class']
+        exportMacro = self.model().framework.setting('export_macro', None)
+        if exportMacro is not None:
+            classComponents.append(exportMacro)
+
+        used_enum_names = set([])
+
+        event_declarations = []
+        for event in domain.events:
+            event_declarations.append(self._generate_dispatcher_declaration_for_event(event, domain, used_enum_names))
+
+        handler_args = {
+            'classAndExportMacro': " ".join(classComponents),
+            'domainName': domain.domain_name,
+            'eventDeclarations': "\n".join(event_declarations)
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(CppTemplates.FrontendDispatcherDomainDispatcherDeclaration).substitute(None, **handler_args))
+
+    def _generate_dispatcher_declaration_for_event(self, event, domain, used_enum_names):
+        formal_parameters = []
+        lines = []
+        for parameter in event.event_parameters:
+            formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_checked_formal_event_parameter(parameter), parameter.parameter_name))
+            if isinstance(parameter.type, EnumType) and parameter.parameter_name not in used_enum_names:
+                lines.append(self._generate_anonymous_enum_for_parameter(parameter, event))
+                used_enum_names.add(parameter.parameter_name)
+
+        lines.append("    void %s(%s);" % (event.event_name, ", ".join(formal_parameters)))
+        return "\n".join(lines)
diff --git a/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py b/inspector/scripts/codegen/generate_cpp_frontend_dispatcher_implementation.py
new file mode 100755 (executable)
index 0000000..798157a
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import ObjectType, ArrayType
+
+log = logging.getLogger('global')
+
+
+class CppFrontendDispatcherImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorFrontendDispatchers.cpp"
+
+    def domains_to_generate(self):
+        return filter(lambda domain: len(domain.events) > 0, Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        secondary_headers = ['<wtf/text/CString.h>']
+
+        header_args = {
+            'primaryInclude': '"InspectorFrontendDispatchers.h"',
+            'secondaryIncludes': "\n".join(['#include %s' % header for header in secondary_headers]),
+        }
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.extend(map(self._generate_dispatcher_implementations_for_domain, self.domains_to_generate()))
+        sections.append(Template(CppTemplates.ImplementationPostlude).substitute(None, **header_args))
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    def _generate_dispatcher_implementations_for_domain(self, domain):
+        implementations = []
+        for event in domain.events:
+            implementations.append(self._generate_dispatcher_implementation_for_event(event, domain))
+
+        return self.wrap_with_guard_for_domain(domain, '\n\n'.join(implementations))
+
+    def _generate_dispatcher_implementation_for_event(self, event, domain):
+        lines = []
+        parameter_assignments = []
+        formal_parameters = []
+
+        for parameter in event.event_parameters:
+
+            parameter_value = parameter.parameter_name
+            if parameter.is_optional and not CppGenerator.should_pass_by_copy_for_return_type(parameter.type):
+                parameter_value = '*' + parameter_value
+            if parameter.type.is_enum():
+                parameter_value = 'Inspector::Protocol::getEnumConstantValue(%s)' % parameter_value
+
+            parameter_args = {
+                'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter),
+                'parameterName': parameter.parameter_name,
+                'parameterValue': parameter_value,
+                'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type),
+            }
+
+            if parameter.is_optional:
+                parameter_assignments.append('    if (%(parameterName)s)' % parameter_args)
+                parameter_assignments.append('        paramsObject->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), %(parameterValue)s);' % parameter_args)
+            else:
+                parameter_assignments.append('    paramsObject->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), %(parameterValue)s);' % parameter_args)
+
+            formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_checked_formal_event_parameter(parameter), parameter.parameter_name))
+
+        event_args = {
+            'domainName': domain.domain_name,
+            'eventName': event.event_name,
+            'formalParameters': ", ".join(formal_parameters)
+        }
+
+        lines.append('void %(domainName)sFrontendDispatcher::%(eventName)s(%(formalParameters)s)' % event_args)
+        lines.append('{')
+        lines.append('    Ref<InspectorObject> jsonMessage = InspectorObject::create();')
+        lines.append('    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("%(domainName)s.%(eventName)s"));' % event_args)
+
+        if len(parameter_assignments) > 0:
+            lines.append('    Ref<InspectorObject> paramsObject = InspectorObject::create();')
+            lines.extend(parameter_assignments)
+            lines.append('    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));')
+
+        lines.append('')
+        lines.append('    m_frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());')
+        lines.append('}')
+        return "\n".join(lines)
diff --git a/inspector/scripts/codegen/generate_cpp_protocol_types_header.py b/inspector/scripts/codegen/generate_cpp_protocol_types_header.py
new file mode 100755 (executable)
index 0000000..b07b0b9
--- /dev/null
@@ -0,0 +1,352 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import re
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import EnumType, ObjectType, PrimitiveType, AliasedType, ArrayType, Frameworks
+
+log = logging.getLogger('global')
+
+
+class CppProtocolTypesHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorProtocolObjects.h"
+
+    def generate_output(self):
+        domains = self.domains_to_generate()
+        self.calculate_types_requiring_shape_assertions(domains)
+
+        headers = set([
+            '<inspector/InspectorProtocolTypes.h>',
+            '<wtf/Assertions.h>',
+        ])
+
+        export_macro = self.model().framework.setting('export_macro', None)
+
+        header_args = {
+            'headerGuardString': re.sub('\W+', '_', self.output_filename()),
+            'includes': '\n'.join(['#include ' + header for header in sorted(headers)]),
+            'typedefs': '',
+        }
+
+        return_type = 'String'
+        return_type_with_export_macro = [return_type]
+        if export_macro is not None:
+            return_type_with_export_macro[:0] = [export_macro]
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.HeaderPrelude).substitute(None, **header_args))
+        sections.append('namespace Protocol {')
+        sections.append(self._generate_forward_declarations(domains))
+        sections.append(self._generate_typedefs(domains))
+        sections.append('%s getEnumConstantValue(int code);' % ' '.join(return_type_with_export_macro))
+        sections.append('\n'.join([
+            'template<typename T> %s getEnumConstantValue(T enumValue)' % return_type,
+            '{',
+            '    return getEnumConstantValue(static_cast<int>(enumValue));',
+            '}']))
+
+        builder_sections = map(self._generate_builders_for_domain, domains)
+        sections.extend(filter(lambda section: len(section) > 0, builder_sections))
+        sections.append(self._generate_forward_declarations_for_binding_traits())
+        sections.append('} // namespace Protocol')
+        sections.append(Template(CppTemplates.HeaderPostlude).substitute(None, **header_args))
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    # FIXME: move builders out of classes, uncomment forward declaration
+
+    def _generate_forward_declarations(self, domains):
+        sections = []
+
+        for domain in domains:
+            declaration_types = [decl.type for decl in domain.type_declarations]
+            object_types = filter(lambda _type: isinstance(_type, ObjectType), declaration_types)
+            enum_types = filter(lambda _type: isinstance(_type, EnumType), declaration_types)
+            if len(object_types) + len(enum_types) == 0:
+                continue
+
+            domain_lines = []
+            domain_lines.append('namespace %s {' % domain.domain_name)
+
+            object_type_names = [_type.raw_name() for _type in object_types]
+            enum_type_names = [_type.raw_name() for _type in enum_types]
+
+            # Forward-declare all classes so the type builders won't break if rearranged.
+            domain_lines.extend('class %s;' % name for name in sorted(object_type_names))
+            domain_lines.extend('enum class %s;' % name for name in sorted(enum_type_names))
+            domain_lines.append('} // %s' % domain.domain_name)
+            sections.append(self.wrap_with_guard_for_domain(domain, '\n'.join(domain_lines)))
+
+        if len(sections) == 0:
+            return ''
+        else:
+            return """// Forward declarations.
+%s
+// End of forward declarations.
+""" % '\n\n'.join(sections)
+
+    def _generate_typedefs(self, domains):
+        sections = map(self._generate_typedefs_for_domain, domains)
+        sections = filter(lambda text: len(text) > 0, sections)
+
+        if len(sections) == 0:
+            return ''
+        else:
+            return """// Typedefs.
+%s
+// End of typedefs.""" % '\n\n'.join(sections)
+
+    def _generate_typedefs_for_domain(self, domain):
+        primitive_declarations = filter(lambda decl: isinstance(decl.type, AliasedType), domain.type_declarations)
+        array_declarations = filter(lambda decl: isinstance(decl.type, ArrayType), domain.type_declarations)
+        if len(primitive_declarations) == 0 and len(array_declarations) == 0:
+            return ''
+
+        sections = []
+        for declaration in primitive_declarations:
+            primitive_name = CppGenerator.cpp_name_for_primitive_type(declaration.type.aliased_type)
+            typedef_lines = []
+            if len(declaration.description) > 0:
+                typedef_lines.append('/* %s */' % declaration.description)
+            typedef_lines.append('typedef %s %s;' % (primitive_name, declaration.type_name))
+            sections.append('\n'.join(typedef_lines))
+
+        for declaration in array_declarations:
+            element_type = CppGenerator.cpp_protocol_type_for_type(declaration.type.element_type)
+            typedef_lines = []
+            if len(declaration.description) > 0:
+                typedef_lines.append('/* %s */' % declaration.description)
+            typedef_lines.append('typedef Inspector::Protocol::Array<%s> %s;' % (element_type, declaration.type_name))
+            sections.append('\n'.join(typedef_lines))
+
+        lines = []
+        lines.append('namespace %s {' % domain.domain_name)
+        lines.append('\n'.join(sections))
+        lines.append('} // %s' % domain.domain_name)
+        return self.wrap_with_guard_for_domain(domain, '\n'.join(lines))
+
+    def _generate_builders_for_domain(self, domain):
+        sections = []
+
+        for type_declaration in domain.type_declarations:
+            if isinstance(type_declaration.type, EnumType):
+                sections.append(self._generate_struct_for_enum_declaration(type_declaration))
+            elif isinstance(type_declaration.type, ObjectType):
+                sections.append(self._generate_class_for_object_declaration(type_declaration, domain))
+
+        sections = filter(lambda section: len(section) > 0, sections)
+        if len(sections) == 0:
+            return ''
+
+        lines = []
+        lines.append('namespace %s {' % domain.domain_name)
+        lines.append('\n'.join(sections))
+        lines.append('} // %s' % domain.domain_name)
+        return self.wrap_with_guard_for_domain(domain, '\n'.join(lines))
+
+    def _generate_class_for_object_declaration(self, type_declaration, domain):
+        if len(type_declaration.type_members) == 0:
+            return ''
+
+        enum_members = filter(lambda member: isinstance(member.type, EnumType) and member.type.is_anonymous, type_declaration.type_members)
+        required_members = filter(lambda member: not member.is_optional, type_declaration.type_members)
+        optional_members = filter(lambda member: member.is_optional, type_declaration.type_members)
+        object_name = type_declaration.type_name
+
+        lines = []
+        if len(type_declaration.description) > 0:
+            lines.append('/* %s */' % type_declaration.description)
+        base_class = 'Inspector::InspectorObject'
+        if not Generator.type_has_open_fields(type_declaration.type):
+            base_class = base_class + 'Base'
+        lines.append('class %s : public %s {' % (object_name, base_class))
+        lines.append('public:')
+        for enum_member in enum_members:
+            lines.append('    // Named after property name \'%s\' while generating %s.' % (enum_member.member_name, object_name))
+            lines.append(self._generate_struct_for_anonymous_enum_member(enum_member))
+        lines.append(self._generate_builder_state_enum(type_declaration))
+
+        constructor_example = []
+        constructor_example.append('     * Ref<%s> result = %s::create()' % (object_name, object_name))
+        for member in required_members:
+            constructor_example.append('     *     .set%s(...)' % ucfirst(member.member_name))
+        constructor_example.append('     *     .release()')
+
+        builder_args = {
+            'objectType': object_name,
+            'constructorExample': '\n'.join(constructor_example) + ';',
+        }
+
+        lines.append(Template(CppTemplates.ProtocolObjectBuilderDeclarationPrelude).substitute(None, **builder_args))
+        for type_member in required_members:
+            lines.append(self._generate_builder_setter_for_member(type_member, domain))
+        lines.append(Template(CppTemplates.ProtocolObjectBuilderDeclarationPostlude).substitute(None, **builder_args))
+        for member in optional_members:
+            lines.append(self._generate_unchecked_setter_for_member(member, domain))
+
+        if Generator.type_has_open_fields(type_declaration.type):
+            lines.append('')
+            lines.append('    // Property names for type generated as open.')
+            for type_member in type_declaration.type_members:
+                export_macro = self.model().framework.setting('export_macro', None)
+                lines.append('    %s static const char* %s;' % (export_macro, ucfirst(type_member.member_name)))
+
+        lines.append('};')
+        lines.append('')
+        return '\n'.join(lines)
+
+    def _generate_struct_for_enum_declaration(self, enum_declaration):
+        lines = []
+        lines.append('/* %s */' % enum_declaration.description)
+        lines.extend(self._generate_struct_for_enum_type(enum_declaration.type_name, enum_declaration.type))
+        return '\n'.join(lines)
+
+    def _generate_struct_for_anonymous_enum_member(self, enum_member):
+        def apply_indentation(line):
+            if line.startswith(('#', '/*', '*/', '//')) or len(line) is 0:
+                return line
+            else:
+                return '    ' + line
+
+        indented_lines = map(apply_indentation, self._generate_struct_for_enum_type(enum_member.member_name, enum_member.type))
+        return '\n'.join(indented_lines)
+
+    def _generate_struct_for_enum_type(self, enum_name, enum_type):
+        lines = []
+        enum_name = ucfirst(enum_name)
+        lines.append('enum class %s {' % enum_name)
+        for enum_value in enum_type.enum_values():
+            lines.append('    %s = %s,' % (Generator.stylized_name_for_enum_value(enum_value), self.encoding_for_enum_value(enum_value)))
+        lines.append('}; // enum class %s' % enum_name)
+        return lines  # The caller may want to adjust indentation, so don't join these lines.
+
+    def _generate_builder_state_enum(self, type_declaration):
+        lines = []
+        required_members = filter(lambda member: not member.is_optional, type_declaration.type_members)
+        enum_values = []
+
+        lines.append('    enum {')
+        lines.append('        NoFieldsSet = 0,')
+        for i in range(len(required_members)):
+            enum_value = "%sSet" % ucfirst(required_members[i].member_name)
+            enum_values.append(enum_value)
+            lines.append('        %s = 1 << %d,' % (enum_value, i))
+        if len(enum_values) > 0:
+            lines.append('        AllFieldsSet = (%s)' % ' | '.join(enum_values))
+        else:
+            lines.append('        AllFieldsSet = 0')
+        lines.append('    };')
+        lines.append('')
+        return '\n'.join(lines)
+
+    def _generate_builder_setter_for_member(self, type_member, domain):
+        setter_args = {
+            'camelName': ucfirst(type_member.member_name),
+            'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type),
+            'name': type_member.member_name,
+            'parameterType': CppGenerator.cpp_type_for_type_member(type_member)
+        }
+
+        lines = []
+        lines.append('')
+        lines.append('        Builder<STATE | %(camelName)sSet>& set%(camelName)s(%(parameterType)s value)' % setter_args)
+        lines.append('        {')
+        lines.append('            COMPILE_ASSERT(!(STATE & %(camelName)sSet), property_%(name)s_already_set);' % setter_args)
+
+        if isinstance(type_member.type, EnumType):
+            lines.append('            m_result->%(keyedSet)s(ASCIILiteral("%(name)s"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));' % setter_args)
+        else:
+            lines.append('            m_result->%(keyedSet)s(ASCIILiteral("%(name)s"), value);' % setter_args)
+        lines.append('            return castState<%(camelName)sSet>();' % setter_args)
+        lines.append('        }')
+        return '\n'.join(lines)
+
+    def _generate_unchecked_setter_for_member(self, type_member, domain):
+        setter_args = {
+            'camelName': ucfirst(type_member.member_name),
+            'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type),
+            'name': type_member.member_name,
+            'parameterType': CppGenerator.cpp_type_for_type_member(type_member)
+        }
+
+        lines = []
+        lines.append('')
+        lines.append('    void set%(camelName)s(%(parameterType)s value)' % setter_args)
+        lines.append('    {')
+        if isinstance(type_member.type, EnumType):
+            lines.append('        InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));' % setter_args)
+        elif CppGenerator.should_use_references_for_type(type_member.type):
+            lines.append('        InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), WTF::move(value));' % setter_args)
+        else:
+            lines.append('        InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), value);' % setter_args)
+        lines.append('    }')
+        return '\n'.join(lines)
+
+    def _generate_forward_declarations_for_binding_traits(self):
+        # A list of (builder_type, needs_runtime_cast)
+        type_arguments = []
+
+        for domain in self.domains_to_generate():
+            declarations_to_generate = filter(lambda decl: self.type_needs_shape_assertions(decl.type), domain.type_declarations)
+
+            for type_declaration in declarations_to_generate:
+                for type_member in type_declaration.type_members:
+                    if isinstance(type_member.type, EnumType):
+                        type_arguments.append((CppGenerator.cpp_protocol_type_for_type_member(type_member, type_declaration), False))
+
+                if isinstance(type_declaration.type, ObjectType):
+                    type_arguments.append((CppGenerator.cpp_protocol_type_for_type(type_declaration.type), Generator.type_needs_runtime_casts(type_declaration.type)))
+
+        struct_keywords = ['struct']
+        function_keywords = ['static void']
+        export_macro = self.model().framework.setting('export_macro', None)
+        if export_macro is not None:
+            struct_keywords.append(export_macro)
+            #function_keywords[1:1] = [export_macro]
+
+        lines = []
+        for argument in type_arguments:
+            lines.append('template<> %s BindingTraits<%s> {' % (' '.join(struct_keywords), argument[0]))
+            if argument[1]:
+                lines.append('static RefPtr<%s> runtimeCast(RefPtr<Inspector::InspectorValue>&& value);' % argument[0])
+            lines.append('#if !ASSERT_DISABLED')
+            lines.append('%s assertValueHasExpectedType(Inspector::InspectorValue*);' % ' '.join(function_keywords))
+            lines.append('#endif // !ASSERT_DISABLED')
+            lines.append('};')
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_cpp_protocol_types_implementation.py b/inspector/scripts/codegen/generate_cpp_protocol_types_implementation.py
new file mode 100755 (executable)
index 0000000..2c263b5
--- /dev/null
@@ -0,0 +1,183 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from cpp_generator_templates import CppGeneratorTemplates as CppTemplates
+from generator import Generator, ucfirst
+from models import AliasedType, ArrayType, EnumType, ObjectType
+
+log = logging.getLogger('global')
+
+
+class CppProtocolTypesImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorProtocolObjects.cpp"
+
+    def generate_output(self):
+        domains = self.domains_to_generate()
+        self.calculate_types_requiring_shape_assertions(domains)
+
+        secondary_headers = ['<wtf/text/CString.h>']
+
+        header_args = {
+            'primaryInclude': '"InspectorProtocolObjects.h"',
+            'secondaryIncludes': "\n".join(['#include %s' % header for header in secondary_headers]),
+        }
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(CppTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.append('namespace Protocol {')
+        sections.append(self._generate_enum_mapping())
+        sections.append(self._generate_open_field_names())
+        builder_sections = map(self._generate_builders_for_domain, domains)
+        sections.extend(filter(lambda section: len(section) > 0, builder_sections))
+        sections.append('} // namespace Protocol')
+        sections.append(Template(CppTemplates.ImplementationPostlude).substitute(None, **header_args))
+
+        return "\n\n".join(sections)
+
+    # Private methods.
+
+    def _generate_enum_mapping(self):
+        lines = []
+        lines.append('static const char* const enum_constant_values[] = {')
+        lines.extend(['    "%s",' % enum_value for enum_value in self.assigned_enum_values()])
+        lines.append('};')
+        lines.append('')
+        lines.append('String getEnumConstantValue(int code) {')
+        lines.append('    return enum_constant_values[code];')
+        lines.append('}')
+        return '\n'.join(lines)
+
+    def _generate_open_field_names(self):
+        lines = []
+        for domain in self.domains_to_generate():
+            for type_declaration in filter(lambda decl: Generator.type_has_open_fields(decl.type), domain.type_declarations):
+                for type_member in sorted(type_declaration.type_members, key=lambda member: member.member_name):
+                    field_name = '::'.join(['Inspector', 'Protocol', domain.domain_name, ucfirst(type_declaration.type_name), ucfirst(type_member.member_name)])
+                    lines.append('const char* %s = "%s";' % (field_name, type_member.member_name))
+
+        return '\n'.join(lines)
+
+    def _generate_builders_for_domain(self, domain):
+        sections = []
+        declarations_to_generate = filter(lambda decl: self.type_needs_shape_assertions(decl.type), domain.type_declarations)
+
+        for type_declaration in declarations_to_generate:
+            for type_member in type_declaration.type_members:
+                if isinstance(type_member.type, EnumType):
+                    sections.append(self._generate_assertion_for_enum(type_member, type_declaration))
+
+            if isinstance(type_declaration.type, ObjectType):
+                sections.append(self._generate_assertion_for_object_declaration(type_declaration))
+                if Generator.type_needs_runtime_casts(type_declaration.type):
+                    sections.append(self._generate_runtime_cast_for_object_declaration(type_declaration))
+
+        return '\n\n'.join(sections)
+
+    def _generate_runtime_cast_for_object_declaration(self, object_declaration):
+        args = {
+            'objectType': CppGenerator.cpp_protocol_type_for_type(object_declaration.type)
+        }
+        return Template(CppTemplates.ProtocolObjectRuntimeCast).substitute(None, **args)
+
+    def _generate_assertion_for_object_declaration(self, object_declaration):
+        required_members = filter(lambda member: not member.is_optional, object_declaration.type_members)
+        optional_members = filter(lambda member: member.is_optional, object_declaration.type_members)
+        should_count_properties = not Generator.type_has_open_fields(object_declaration.type)
+        lines = []
+
+        lines.append('#if !ASSERT_DISABLED')
+        lines.append('void BindingTraits<%s>::assertValueHasExpectedType(Inspector::InspectorValue* value)' % (CppGenerator.cpp_protocol_type_for_type(object_declaration.type)))
+        lines.append("""{
+    ASSERT_ARG(value, value);
+    RefPtr<InspectorObject> object;
+    bool castSucceeded = value->asObject(object);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);""")
+        for type_member in required_members:
+            args = {
+                'memberName': type_member.member_name,
+                'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration)
+            }
+
+            lines.append("""    {
+        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
+        ASSERT(%(memberName)sPos != object->end());
+        %(assertMethod)s(%(memberName)sPos->value.get());
+    }""" % args)
+
+        if should_count_properties:
+            lines.append('')
+            lines.append('    int foundPropertiesCount = %s;' % len(required_members))
+
+        for type_member in optional_members:
+            args = {
+                'memberName': type_member.member_name,
+                'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration)
+            }
+
+            lines.append("""    {
+        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
+        if (%(memberName)sPos != object->end()) {
+            %(assertMethod)s(%(memberName)sPos->value.get());""" % args)
+
+            if should_count_properties:
+                lines.append('            ++foundPropertiesCount;')
+            lines.append('        }')
+            lines.append('    }')
+
+        if should_count_properties:
+            lines.append('    if (foundPropertiesCount != object->size())')
+            lines.append('        FATAL("Unexpected properties in object: %s\\n", object->toJSONString().ascii().data());')
+        lines.append('}')
+        lines.append('#endif // !ASSERT_DISABLED')
+        return '\n'.join(lines)
+
+    def _generate_assertion_for_enum(self, enum_member, object_declaration):
+        lines = []
+        lines.append('#if !ASSERT_DISABLED')
+        lines.append('void %s(Inspector::InspectorValue* value)' % CppGenerator.cpp_assertion_method_for_type_member(enum_member, object_declaration))
+        lines.append('{')
+        lines.append('    ASSERT_ARG(value, value);')
+        lines.append('    String result;')
+        lines.append('    bool castSucceeded = value->asString(result);')
+        lines.append('    ASSERT(castSucceeded);')
+
+        assert_condition = ' || '.join(['result == "%s"' % enum_value for enum_value in enum_member.type.enum_values()])
+        lines.append('    ASSERT(%s);' % assert_condition)
+        lines.append('}')
+        lines.append('#endif // !ASSERT_DISABLED')
+
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_js_backend_commands.py b/inspector/scripts/codegen/generate_js_backend_commands.py
new file mode 100755 (executable)
index 0000000..3392c78
--- /dev/null
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator, ucfirst
+from generator_templates import GeneratorTemplates as Templates
+from models import EnumType
+
+log = logging.getLogger('global')
+
+
+class JSBackendCommandsGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return "InspectorBackendCommands.js"
+
+    def domains_to_generate(self):
+        def should_generate_domain(domain):
+            domain_enum_types = filter(lambda declaration: isinstance(declaration.type, EnumType), domain.type_declarations)
+            return len(domain.commands) > 0 or len(domain.events) > 0 or len(domain_enum_types) > 0
+
+        return filter(should_generate_domain, Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        sections = []
+        sections.append(self.generate_license())
+        sections.extend(map(self.generate_domain, self.domains_to_generate()))
+        return "\n\n".join(sections)
+
+    def generate_domain(self, domain):
+        lines = []
+        args = {
+            'domain': domain.domain_name
+        }
+
+        lines.append('// %(domain)s.' % args)
+
+        has_async_commands = any(map(lambda command: command.is_async, domain.commands))
+        if len(domain.events) > 0 or has_async_commands:
+            lines.append('InspectorBackend.register%(domain)sDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "%(domain)s");' % args)
+
+        for declaration in domain.type_declarations:
+            if declaration.type.is_enum():
+                enum_args = {
+                    'domain': domain.domain_name,
+                    'enumName': declaration.type_name,
+                    'enumMap': ", ".join(['%s: "%s"' % (Generator.stylized_name_for_enum_value(enum_value), enum_value) for enum_value in declaration.type.enum_values()])
+                }
+                lines.append('InspectorBackend.registerEnum("%(domain)s.%(enumName)s", {%(enumMap)s});' % enum_args)
+
+            def is_anonymous_enum_member(type_member):
+                return isinstance(type_member.type, EnumType) and type_member.type.is_anonymous
+
+            for _member in filter(is_anonymous_enum_member, declaration.type_members):
+                enum_args = {
+                    'domain': domain.domain_name,
+                    'enumName': '%s%s' % (declaration.type_name, ucfirst(_member.member_name)),
+                    'enumMap': ", ".join(['%s: "%s"' % (Generator.stylized_name_for_enum_value(enum_value), enum_value) for enum_value in _member.type.enum_values()])
+                }
+                lines.append('InspectorBackend.registerEnum("%(domain)s.%(enumName)s", {%(enumMap)s});' % enum_args)
+
+        def is_anonymous_enum_param(param):
+            return isinstance(param.type, EnumType) and param.type.is_anonymous
+
+        for event in domain.events:
+            for param in filter(is_anonymous_enum_param, event.event_parameters):
+                enum_args = {
+                    'domain': domain.domain_name,
+                    'enumName': '%s%s' % (ucfirst(event.event_name), ucfirst(param.parameter_name)),
+                    'enumMap': ", ".join(['%s: "%s"' % (Generator.stylized_name_for_enum_value(enum_value), enum_value) for enum_value in param.type.enum_values()])
+                }
+                lines.append('InspectorBackend.registerEnum("%(domain)s.%(enumName)s", {%(enumMap)s});' % enum_args)
+
+            event_args = {
+                'domain': domain.domain_name,
+                'eventName': event.event_name,
+                'params': ", ".join(['"%s"' % parameter.parameter_name for parameter in event.event_parameters])
+            }
+            lines.append('InspectorBackend.registerEvent("%(domain)s.%(eventName)s", [%(params)s]);' % event_args)
+
+        for command in domain.commands:
+            def generate_parameter_object(parameter):
+                optional_string = "true" if parameter.is_optional else "false"
+                pairs = []
+                pairs.append('"name": "%s"' % parameter.parameter_name)
+                pairs.append('"type": "%s"' % Generator.js_name_for_parameter_type(parameter.type))
+                pairs.append('"optional": %s' % optional_string)
+                return "{%s}" % ", ".join(pairs)
+
+            command_args = {
+                'domain': domain.domain_name,
+                'commandName': command.command_name,
+                'callParams': ", ".join([generate_parameter_object(parameter) for parameter in command.call_parameters]),
+                'returnParams': ", ".join(['"%s"' % parameter.parameter_name for parameter in command.return_parameters]),
+            }
+            lines.append('InspectorBackend.registerCommand("%(domain)s.%(commandName)s", [%(callParams)s], [%(returnParams)s]);' % command_args)
+
+        if domain.commands or domain.events:
+            activate_args = {
+                'domain': domain.domain_name,
+                'availability': domain.availability,
+            }
+            if domain.availability:
+                lines.append('InspectorBackend.activateDomain("%(domain)s", "%(availability)s");' % activate_args)
+            else:
+                lines.append('InspectorBackend.activateDomain("%(domain)s");' % activate_args)
+
+        return "\n".join(lines)
diff --git a/inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py b/inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py
new file mode 100755 (executable)
index 0000000..29b38e8
--- /dev/null
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+import re
+from string import Template
+
+from cpp_generator import CppGenerator
+from generator import Generator
+from models import Frameworks
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCBackendDispatcherHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sBackendDispatchers.h' % ObjCGenerator.OBJC_PREFIX
+
+    def domains_to_generate(self):
+        return filter(ObjCGenerator.should_generate_domain_command_handler_filter(self.model()), Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        headers = [
+            '<JavaScriptCore/InspectorAlternateBackendDispatchers.h>',
+            '<wtf/RetainPtr.h>',
+        ]
+
+        header_args = {
+            'headerGuardString': re.sub('\W+', '_', self.output_filename()),
+            'includes': '\n'.join(['#include ' + header for header in headers]),
+            'forwardDeclarations': self._generate_objc_forward_declarations(),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.BackendDispatcherHeaderPrelude).substitute(None, **header_args))
+        sections.extend(map(self._generate_objc_handler_declarations_for_domain, domains))
+        sections.append(Template(ObjCTemplates.BackendDispatcherHeaderPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_objc_forward_declarations(self):
+        lines = []
+        for domain in self.domains_to_generate():
+            if domain.commands:
+                lines.append('@protocol %s%sDomainHandler;' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name))
+        return '\n'.join(lines)
+
+    def _generate_objc_handler_declarations_for_domain(self, domain):
+        if not domain.commands:
+            return ''
+
+        command_declarations = []
+        for command in domain.commands:
+            command_declarations.append(self._generate_objc_handler_declaration_for_command(command))
+
+        handler_args = {
+            'domainName': domain.domain_name,
+            'commandDeclarations': '\n'.join(command_declarations),
+            'objcPrefix': ObjCGenerator.OBJC_PREFIX,
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerObjCDeclaration).substitute(None, **handler_args))
+
+    def _generate_objc_handler_declaration_for_command(self, command):
+        lines = []
+        parameters = ['long callId']
+        for _parameter in command.call_parameters:
+            parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name))
+
+        command_args = {
+            'commandName': command.command_name,
+            'parameters': ', '.join(parameters),
+        }
+        lines.append('    virtual void %(commandName)s(%(parameters)s) override;' % command_args)
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py b/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py
new file mode 100755 (executable)
index 0000000..27bdd4a
--- /dev/null
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+import re
+from string import Template
+
+from cpp_generator import CppGenerator
+from generator import Generator
+from models import PrimitiveType, EnumType, AliasedType, Frameworks
+from objc_generator import ObjCTypeCategory, ObjCGenerator, join_type_and_name
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCConfigurationImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sBackendDispatchers.mm' % ObjCGenerator.OBJC_PREFIX
+
+    def domains_to_generate(self):
+        return filter(ObjCGenerator.should_generate_domain_command_handler_filter(self.model()), Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        secondary_headers = [
+            '"%sInternal.h"' % ObjCGenerator.OBJC_PREFIX,
+            '"%sEnumConversionHelpers.h"' % ObjCGenerator.OBJC_PREFIX,
+            '<JavaScriptCore/InspectorFrontendChannel.h>',
+            '<JavaScriptCore/InspectorValues.h>',
+        ]
+
+        header_args = {
+            'primaryInclude': '"%sBackendDispatchers.h"' % ObjCGenerator.OBJC_PREFIX,
+            'secondaryIncludes': '\n'.join(['#include %s' % header for header in secondary_headers]),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.BackendDispatcherImplementationPrelude).substitute(None, **header_args))
+        sections.extend(map(self._generate_handler_implementation_for_domain, domains))
+        sections.append(Template(ObjCTemplates.BackendDispatcherImplementationPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_handler_implementation_for_domain(self, domain):
+        if not domain.commands:
+            return ''
+
+        command_declarations = []
+        for command in domain.commands:
+            command_declarations.append(self._generate_handler_implementation_for_command(domain, command))
+
+        return '\n'.join(command_declarations)
+
+    def _generate_handler_implementation_for_command(self, domain, command):
+        lines = []
+        parameters = ['long callId']
+        for parameter in command.call_parameters:
+            parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(parameter), parameter.parameter_name))
+
+        command_args = {
+            'domainName': domain.domain_name,
+            'commandName': command.command_name,
+            'parameters': ', '.join(parameters),
+            'successCallback': self._generate_success_block_for_command(domain, command),
+            'conversions': self._generate_conversions_for_command(domain, command),
+            'invocation': self._generate_invocation_for_command(domain, command),
+        }
+
+        return self.wrap_with_guard_for_domain(domain, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerImplementation).substitute(None, **command_args))
+
+    def _generate_success_block_for_command(self, domain, command):
+        lines = []
+
+        if command.return_parameters:
+            success_block_parameters = []
+            for parameter in command.return_parameters:
+                objc_type = ObjCGenerator.objc_type_for_param(domain, command.command_name, parameter)
+                var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+                success_block_parameters.append(join_type_and_name(objc_type, var_name))
+            lines.append('    id successCallback = ^(%s) {' % ', '.join(success_block_parameters))
+        else:
+            lines.append('    id successCallback = ^{')
+
+        if command.return_parameters:
+            lines.append('        Ref<InspectorObject> resultObject = InspectorObject::create();')
+
+            required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), command.return_parameters)
+            for parameter in required_pointer_parameters:
+                var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+                lines.append('        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(%s, @"%s");' % (var_name, var_name))
+                objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
+                if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+                    lines.append('        THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+
+            optional_pointer_parameters = filter(lambda parameter: parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), command.return_parameters)
+            for parameter in optional_pointer_parameters:
+                var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+                lines.append('        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(%s, @"%s");' % (var_name, var_name))
+                objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
+                if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+                    lines.append('        THROW_EXCEPTION_FOR_BAD_TYPE_IN_OPTIONAL_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+
+            for parameter in command.return_parameters:
+                keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type)
+                var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+                var_expression = '*%s' % var_name if parameter.is_optional else var_name
+                export_expression = ObjCGenerator.objc_protocol_export_expression_for_variable(parameter.type, var_expression)
+                if not parameter.is_optional:
+                    lines.append('        resultObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
+                else:
+                    lines.append('        if (%s)' % var_name)
+                    lines.append('            resultObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
+            lines.append('        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());')
+        else:
+            lines.append('        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());')
+
+        lines.append('    };')
+        return '\n'.join(lines)
+
+    def _generate_conversions_for_command(self, domain, command):
+        lines = []
+        if command.call_parameters:
+            lines.append('')
+
+        def in_param_expression(param_name, parameter):
+            _type = parameter.type
+            if isinstance(_type, AliasedType):
+                _type = _type.aliased_type  # Fall through to enum or primitive.
+            if isinstance(_type, EnumType):
+                _type = _type.primitive_type  # Fall through to primitive.
+            if isinstance(_type, PrimitiveType):
+                if _type.raw_name() in ['array', 'any', 'object']:
+                    return '&%s' % param_name if not parameter.is_optional else param_name
+                return '*%s' % param_name if parameter.is_optional else param_name
+            return '&%s' % param_name if not parameter.is_optional else param_name
+
+        for parameter in command.call_parameters:
+            in_param_name = 'in_%s' % parameter.parameter_name
+            objc_in_param_name = 'o_%s' % in_param_name
+            objc_type = ObjCGenerator.objc_type_for_param(domain, command.command_name, parameter, False)
+            param_expression = in_param_expression(in_param_name, parameter)
+            import_expression = ObjCGenerator.objc_protocol_import_expression_for_parameter(param_expression, domain, command.command_name, parameter)
+            if not parameter.is_optional:
+                lines.append('    %s = %s;' % (join_type_and_name(objc_type, objc_in_param_name), import_expression))
+            else:
+                lines.append('    %s;' % join_type_and_name(objc_type, objc_in_param_name))
+                lines.append('    if (%s)' % in_param_name)
+                lines.append('        %s = %s;' % (objc_in_param_name, import_expression))
+
+        if lines:
+            lines.append('')
+        return '\n'.join(lines)
+
+    def _generate_invocation_for_command(self, domain, command):
+        pairs = []
+        pairs.append('WithErrorCallback:errorCallback')
+        pairs.append('successCallback:successCallback')
+        for parameter in command.call_parameters:
+            in_param_name = 'in_%s' % parameter.parameter_name
+            objc_in_param_name = 'o_%s' % in_param_name
+            if not parameter.is_optional:
+                pairs.append('%s:%s' % (parameter.parameter_name, objc_in_param_name))
+            else:
+                optional_expression = '(%s ? &%s : nil)' % (in_param_name, objc_in_param_name)
+                pairs.append('%s:%s' % (parameter.parameter_name, optional_expression))
+        return '    [m_delegate %s%s];' % (command.command_name, ' '.join(pairs))
diff --git a/inspector/scripts/codegen/generate_objc_configuration_header.py b/inspector/scripts/codegen/generate_objc_configuration_header.py
new file mode 100755 (executable)
index 0000000..2002227
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCConfigurationHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sConfiguration.h' % ObjCGenerator.OBJC_PREFIX
+
+    def generate_output(self):
+        headers = [
+            '"%s.h"' % ObjCGenerator.OBJC_PREFIX,
+        ]
+
+        header_args = {
+            'includes': '\n'.join(['#import ' + header for header in headers]),
+        }
+
+        self._command_filter = ObjCGenerator.should_generate_domain_command_handler_filter(self.model())
+        self._event_filter = ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model())
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.GenericHeaderPrelude).substitute(None, **header_args))
+        sections.append(self._generate_configuration_interface_for_domains(domains))
+        sections.append(Template(ObjCTemplates.GenericHeaderPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_configuration_interface_for_domains(self, domains):
+        lines = []
+        lines.append('__attribute__((visibility ("default")))')
+        lines.append('@interface RWIProtocolConfiguration : NSObject')
+        for domain in domains:
+            lines.extend(self._generate_properties_for_domain(domain))
+        lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_properties_for_domain(self, domain):
+        property_args = {
+            'objcPrefix': ObjCGenerator.OBJC_PREFIX,
+            'domainName': domain.domain_name,
+            'variableNamePrefix': ObjCGenerator.variable_name_prefix_for_domain(domain),
+        }
+
+        lines = []
+        if domain.commands and self._command_filter(domain):
+            lines.append(Template(ObjCTemplates.ConfigurationCommandProperty).substitute(None, **property_args))
+        if domain.events and self._event_filter(domain):
+            lines.append(Template(ObjCTemplates.ConfigurationEventProperty).substitute(None, **property_args))
+        return lines
diff --git a/inspector/scripts/codegen/generate_objc_configuration_implementation.py b/inspector/scripts/codegen/generate_objc_configuration_implementation.py
new file mode 100755 (executable)
index 0000000..53205cb
--- /dev/null
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCBackendDispatcherImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sConfiguration.mm' % ObjCGenerator.OBJC_PREFIX
+
+    def generate_output(self):
+        secondary_headers = [
+            '"%sInternal.h"' % ObjCGenerator.OBJC_PREFIX,
+            '"%sBackendDispatchers.h"' % ObjCGenerator.OBJC_PREFIX,
+            '<JavaScriptCore/AlternateDispatchableAgent.h>',
+            '<JavaScriptCore/AugmentableInspectorController.h>',
+            '<JavaScriptCore/InspectorAlternateBackendDispatchers.h>',
+            '<JavaScriptCore/InspectorBackendDispatchers.h>',
+        ]
+
+        header_args = {
+            'primaryInclude': '"%sConfiguration.h"' % ObjCGenerator.OBJC_PREFIX,
+            'secondaryIncludes': '\n'.join(['#import %s' % header for header in secondary_headers]),
+        }
+
+        self._command_filter = ObjCGenerator.should_generate_domain_command_handler_filter(self.model())
+        self._event_filter = ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model())
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.append(self._generate_configuration_implementation_for_domains(domains))
+        sections.append(Template(ObjCTemplates.ImplementationPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_configuration_implementation_for_domains(self, domains):
+        lines = []
+        lines.append('@implementation RWIProtocolConfiguration')
+        lines.append('{')
+        lines.append('    AugmentableInspectorController* _controller;')
+        lines.extend(self._generate_ivars(domains))
+        lines.append('}')
+        lines.append('')
+        lines.append('- (instancetype)initWithController:(AugmentableInspectorController*)controller')
+        lines.append('{')
+        lines.append('    self = [super init];')
+        lines.append('    if (!self)')
+        lines.append('        return nil;')
+        lines.append('    ASSERT(controller);')
+        lines.append('    _controller = controller;')
+        lines.append('    return self;')
+        lines.append('}')
+        lines.append('')
+        lines.extend(self._generate_dealloc(domains))
+        lines.append('')
+        for domain in domains:
+            if domain.commands and self._command_filter(domain):
+                lines.append(self._generate_handler_setter_for_domain(domain))
+                lines.append('')
+            if domain.events and self._event_filter(domain):
+                lines.append(self._generate_event_dispatcher_getter_for_domain(domain))
+                lines.append('')
+        lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_ivars(self, domains):
+        lines = []
+        for domain in domains:
+            if domain.commands and self._command_filter(domain):
+                objc_class_name = '%s%sDomainHandler' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+                ivar_name = '_%sHandler' % ObjCGenerator.variable_name_prefix_for_domain(domain)
+                lines.append('    id<%s> %s;' % (objc_class_name, ivar_name))
+            if domain.events and self._event_filter(domain):
+                objc_class_name = '%s%sDomainEventDispatcher' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+                ivar_name = '_%sEventDispatcher' % ObjCGenerator.variable_name_prefix_for_domain(domain)
+                lines.append('    %s *%s;' % (objc_class_name, ivar_name))
+        return lines
+
+    def _generate_dealloc(self, domains):
+        lines = []
+        lines.append('- (void)dealloc')
+        lines.append('{')
+        for domain in domains:
+            if domain.commands and self._command_filter(domain):
+                lines.append('    [_%sHandler release];' % ObjCGenerator.variable_name_prefix_for_domain(domain))
+            if domain.events and self._event_filter(domain):
+                lines.append('    [_%sEventDispatcher release];' % ObjCGenerator.variable_name_prefix_for_domain(domain))
+        lines.append('    [super dealloc];')
+        lines.append('}')
+        return lines
+
+    def _generate_handler_setter_for_domain(self, domain):
+        setter_args = {
+            'objcPrefix': ObjCGenerator.OBJC_PREFIX,
+            'domainName': domain.domain_name,
+            'variableNamePrefix': ObjCGenerator.variable_name_prefix_for_domain(domain),
+        }
+        return Template(ObjCTemplates.ConfigurationCommandPropertyImplementation).substitute(None, **setter_args)
+
+    def _generate_event_dispatcher_getter_for_domain(self, domain):
+        getter_args = {
+            'objcPrefix': ObjCGenerator.OBJC_PREFIX,
+            'domainName': domain.domain_name,
+            'variableNamePrefix': ObjCGenerator.variable_name_prefix_for_domain(domain),
+        }
+        return Template(ObjCTemplates.ConfigurationGetterImplementation).substitute(None, **getter_args)
+
+    def _variable_name_prefix_for_domain(self, domain):
+        domain_name = domain.domain_name
+        if domain_name.startswith('DOM'):
+            return 'dom' + domain_name[3:]
+        if domain_name.startswith('CSS'):
+            return 'css' + domain_name[3:]
+        return domain_name[:1].lower() + domain_name[1:]
diff --git a/inspector/scripts/codegen/generate_objc_conversion_helpers.py b/inspector/scripts/codegen/generate_objc_conversion_helpers.py
new file mode 100755 (executable)
index 0000000..c31e991
--- /dev/null
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator
+from models import EnumType
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+def add_newline(lines):
+    if lines and lines[-1] == '':
+        return
+    lines.append('')
+
+
+class ObjCConversionHelpersGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sEnumConversionHelpers.h' % ObjCGenerator.OBJC_PREFIX
+
+    def domains_to_generate(self):
+        return filter(ObjCGenerator.should_generate_domain_types_filter(self.model()), Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        headers = [
+            '"%sArrayConversionHelpers.h"' % ObjCGenerator.OBJC_PREFIX,
+        ]
+
+        header_args = {
+            'includes': '\n'.join(['#import ' + header for header in headers]),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.ConversionHelpersPrelude).substitute(None, **header_args))
+        sections.append(Template(ObjCTemplates.ConversionHelpersStandard).substitute(None))
+        sections.extend(map(self._generate_enum_conversion_functions, domains))
+        sections.append(Template(ObjCTemplates.ConversionHelpersPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_enum_conversion_functions(self, domain):
+        lines = []
+
+        # Type enums and member enums.
+        for declaration in domain.type_declarations:
+            if isinstance(declaration.type, EnumType):
+                add_newline(lines)
+                lines.append(self._generate_anonymous_enum_conversion_for_declaration(domain, declaration))
+            else:
+                for member in declaration.type_members:
+                    if (isinstance(member.type, EnumType) and member.type.is_anonymous):
+                        add_newline(lines)
+                        lines.append(self._generate_anonymous_enum_conversion_for_member(domain, declaration, member))
+
+        # Anonymous command enums.
+        for command in domain.commands:
+            for parameter in command.call_parameters:
+                if (isinstance(parameter.type, EnumType) and parameter.type.is_anonymous):
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_conversion_for_parameter(domain, command.command_name, parameter))
+            for parameter in command.return_parameters:
+                if (isinstance(parameter.type, EnumType) and parameter.type.is_anonymous):
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_conversion_for_parameter(domain, command.command_name, parameter))
+
+        # Anonymous event enums.
+        for event in domain.events:
+            for parameter in event.event_parameters:
+                if (isinstance(parameter.type, EnumType) and parameter.type.is_anonymous):
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_conversion_for_parameter(domain, event.event_name, parameter))
+
+        return '\n'.join(lines)
+
+    def _generate_anonymous_enum_conversion_for_declaration(self, domain, declaration):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_declaration(declaration)
+        enum_values = declaration.type.enum_values()
+        lines = []
+        lines.append(self._generate_enum_objc_to_protocol_string(objc_enum_name, enum_values))
+        lines.append(self._generate_enum_from_protocol_string(objc_enum_name, enum_values))
+        return '\n\n'.join(lines)
+
+    def _generate_anonymous_enum_conversion_for_member(self, domain, declaration, member):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_member(declaration, member)
+        enum_values = member.type.enum_values()
+        lines = []
+        lines.append(self._generate_enum_objc_to_protocol_string(objc_enum_name, enum_values))
+        lines.append(self._generate_enum_from_protocol_string(objc_enum_name, enum_values))
+        return '\n\n'.join(lines)
+
+    def _generate_anonymous_enum_conversion_for_parameter(self, domain, event_or_command_name, parameter):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter)
+        enum_values = parameter.type.enum_values()
+        lines = []
+        lines.append(self._generate_enum_objc_to_protocol_string(objc_enum_name, enum_values))
+        lines.append(self._generate_enum_from_protocol_string(objc_enum_name, enum_values))
+        return '\n\n'.join(lines)
+
+    def _generate_enum_objc_to_protocol_string(self, objc_enum_name, enum_values):
+        lines = []
+        lines.append('inline String toProtocolString(%s value)' % objc_enum_name)
+        lines.append('{')
+        lines.append('    switch(value) {')
+        for enum_value in enum_values:
+            lines.append('    case %s%s:' % (objc_enum_name, Generator.stylized_name_for_enum_value(enum_value)))
+            lines.append('        return ASCIILiteral("%s");' % enum_value)
+        lines.append('    }')
+        lines.append('}')
+        return '\n'.join(lines)
+
+    def _generate_enum_from_protocol_string(self, objc_enum_name, enum_values):
+        lines = []
+        lines.append('template<>')
+        lines.append('inline %s fromProtocolString(const String& value)' % objc_enum_name)
+        lines.append('{')
+        for enum_value in enum_values:
+            lines.append('    if (value == "%s")' % enum_value)
+            lines.append('        return %s%s;' % (objc_enum_name, Generator.stylized_name_for_enum_value(enum_value)))
+        lines.append('    ASSERT_NOT_REACHED();')
+        lines.append('    return %s%s;' % (objc_enum_name, Generator.stylized_name_for_enum_value(enum_values[0])))
+        lines.append('}')
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py b/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py
new file mode 100755 (executable)
index 0000000..fb2de4f
--- /dev/null
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from cpp_generator import CppGenerator
+from generator import Generator, ucfirst
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCFrontendDispatcherImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sEventDispatchers.mm' % ObjCGenerator.OBJC_PREFIX
+
+    def domains_to_generate(self):
+        return filter(ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model()), Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        secondary_headers = [
+            '"%sEnumConversionHelpers.h"' % ObjCGenerator.OBJC_PREFIX,
+            '<JavaScriptCore/InspectorFrontendChannel.h>',
+            '<JavaScriptCore/InspectorValues.h>',
+        ]
+
+        header_args = {
+            'primaryInclude': '"%sInternal.h"' % ObjCGenerator.OBJC_PREFIX,
+            'secondaryIncludes': '\n'.join(['#import %s' % header for header in secondary_headers]),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.extend(map(self._generate_event_dispatcher_implementations, domains))
+        sections.append(Template(ObjCTemplates.ImplementationPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_event_dispatcher_implementations(self, domain):
+        if not domain.events:
+            return ''
+
+        lines = []
+        objc_name = '%s%sDomainEventDispatcher' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+        lines.append('@implementation %s' % objc_name)
+        lines.append('{')
+        lines.append('    AugmentableInspectorController* _controller;')
+        lines.append('}')
+        lines.append('')
+        lines.append('- (instancetype)initWithController:(AugmentableInspectorController*)controller;')
+        lines.append('{')
+        lines.append('    self = [super init];')
+        lines.append('    if (!self)')
+        lines.append('        return nil;')
+        lines.append('    ASSERT(controller);')
+        lines.append('    _controller = controller;')
+        lines.append('    return self;')
+        lines.append('}')
+        lines.append('')
+        for event in domain.events:
+            lines.append(self._generate_event(domain, event))
+            lines.append('')
+        lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_event(self, domain, event):
+        lines = []
+        lines.append(self._generate_event_signature(domain, event))
+        lines.append('{')
+        lines.append('    FrontendChannel* frontendChannel = _controller->frontendChannel();')
+        lines.append('    if (!frontendChannel)')
+        lines.append('        return;')
+        lines.append('')
+
+        required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
+        for parameter in required_pointer_parameters:
+            var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+            lines.append('    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(%s, @"%s");' % (var_name, var_name))
+            objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
+            if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+                lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+
+        optional_pointer_parameters = filter(lambda parameter: parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
+        for parameter in optional_pointer_parameters:
+            var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
+            lines.append('    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(%s, @"%s");' % (var_name, var_name))
+            objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
+            if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+                lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_OPTIONAL_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+
+        if required_pointer_parameters or optional_pointer_parameters:
+            lines.append('')
+
+        lines.append('    Ref<InspectorObject> jsonMessage = InspectorObject::create();')
+        lines.append('    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("%s.%s"));' % (domain.domain_name, event.event_name))
+        if event.event_parameters:
+            lines.extend(self._generate_event_out_parameters(domain, event))
+        lines.append('    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());')
+        lines.append('}')
+        return '\n'.join(lines)
+
+    def _generate_event_signature(self, domain, event):
+        if not event.event_parameters:
+            return '- (void)%s' % event.event_name
+        pairs = []
+        for parameter in event.event_parameters:
+            param_name = parameter.parameter_name
+            pairs.append('%s:(%s)%s' % (param_name, ObjCGenerator.objc_type_for_param(domain, event.event_name, parameter), param_name))
+        pairs[0] = ucfirst(pairs[0])
+        return '- (void)%sWith%s' % (event.event_name, ' '.join(pairs))
+
+    def _generate_event_out_parameters(self, domain, event):
+        lines = []
+        lines.append('    Ref<InspectorObject> paramsObject = InspectorObject::create();')
+        for parameter in event.event_parameters:
+            keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type)
+            var_name = parameter.parameter_name
+            safe_var_name = '(*%s)' % var_name if parameter.is_optional else var_name
+            export_expression = ObjCGenerator.objc_protocol_export_expression_for_variable(parameter.type, safe_var_name)
+            if not parameter.is_optional:
+                lines.append('    paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
+            else:
+                lines.append('    if (%s)' % (parameter.parameter_name))
+                lines.append('        paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
+        lines.append('    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));')
+        return lines
diff --git a/inspector/scripts/codegen/generate_objc_header.py b/inspector/scripts/codegen/generate_objc_header.py
new file mode 100755 (executable)
index 0000000..1d3751f
--- /dev/null
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator, ucfirst
+from models import ObjectType, EnumType
+from objc_generator import ObjCGenerator, join_type_and_name
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+def add_newline(lines):
+    if lines and lines[-1] == '':
+        return
+    lines.append('')
+
+
+class ObjCHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%s.h' % ObjCGenerator.OBJC_PREFIX
+
+    def generate_output(self):
+        headers = set([
+            '<WebInspector/RWIProtocolJSONObject.h>',
+        ])
+
+        header_args = {
+            'includes': '\n'.join(['#import ' + header for header in sorted(headers)]),
+        }
+
+        domains = self.domains_to_generate()
+        type_domains = filter(ObjCGenerator.should_generate_domain_types_filter(self.model()), domains)
+        command_domains = filter(ObjCGenerator.should_generate_domain_command_handler_filter(self.model()), domains)
+        event_domains = filter(ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model()), domains)
+
+        # FIXME: <https://webkit.org/b/138222> Web Inspector: Reduce unnecessary enums/types generated in ObjC Protocol Interfaces
+        # Currently we generate enums/types for all types in the type_domains. For the built-in
+        # JSC domains (Debugger, Runtime) this produces extra unused types. We only need to
+        # generate these types if they are referenced by the command_domains or event_domains.
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.HeaderPrelude).substitute(None, **header_args))
+        sections.append('\n'.join(filter(None, map(self._generate_forward_declarations, type_domains))))
+        sections.append('\n'.join(filter(None, map(self._generate_enums, type_domains))))
+        sections.append('\n'.join(filter(None, map(self._generate_types, type_domains))))
+        sections.append('\n\n'.join(filter(None, map(self._generate_command_protocols, command_domains))))
+        sections.append('\n\n'.join(filter(None, map(self._generate_event_interfaces, event_domains))))
+        sections.append(Template(ObjCTemplates.HeaderPostlude).substitute(None))
+        return '\n\n'.join(sections)
+
+    def _generate_forward_declarations(self, domain):
+        lines = []
+        for declaration in domain.type_declarations:
+            if (isinstance(declaration.type, ObjectType)):
+                objc_name = ObjCGenerator.objc_name_for_type(declaration.type)
+                lines.append('@class %s;' % objc_name)
+        return '\n'.join(lines)
+
+    def _generate_enums(self, domain):
+        lines = []
+
+        # Type enums and member enums.
+        for declaration in domain.type_declarations:
+            if isinstance(declaration.type, EnumType):
+                add_newline(lines)
+                lines.append(self._generate_anonymous_enum_for_declaration(domain, declaration))
+            else:
+                for member in declaration.type_members:
+                    if isinstance(member.type, EnumType) and member.type.is_anonymous:
+                        add_newline(lines)
+                        lines.append(self._generate_anonymous_enum_for_member(domain, declaration, member))
+
+        # Anonymous command enums.
+        for command in domain.commands:
+            for parameter in command.call_parameters:
+                if isinstance(parameter.type, EnumType) and parameter.type.is_anonymous:
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_for_parameter(domain, command.command_name, parameter))
+            for parameter in command.return_parameters:
+                if isinstance(parameter.type, EnumType) and parameter.type.is_anonymous:
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_for_parameter(domain, command.command_name, parameter))
+
+        # Anonymous event enums.
+        for event in domain.events:
+            for parameter in event.event_parameters:
+                if isinstance(parameter.type, EnumType) and parameter.type.is_anonymous:
+                    add_newline(lines)
+                    lines.append(self._generate_anonymous_enum_for_parameter(domain, event.event_name, parameter))
+
+        return '\n'.join(lines)
+
+    def _generate_types(self, domain):
+        lines = []
+        # Type interfaces.
+        for declaration in domain.type_declarations:
+            if isinstance(declaration.type, ObjectType):
+                add_newline(lines)
+                lines.append(self._generate_type_interface(domain, declaration))
+        return '\n'.join(lines)
+
+    def _generate_anonymous_enum_for_declaration(self, domain, declaration):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_declaration(declaration)
+        return self._generate_enum(objc_enum_name, declaration.type.enum_values())
+
+    def _generate_anonymous_enum_for_member(self, domain, declaration, member):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_member(declaration, member)
+        return self._generate_enum(objc_enum_name, member.type.enum_values())
+
+    def _generate_anonymous_enum_for_parameter(self, domain, event_or_command_name, parameter):
+        objc_enum_name = ObjCGenerator.objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter)
+        return self._generate_enum(objc_enum_name, parameter.type.enum_values())
+
+    def _generate_enum(self, enum_name, enum_values):
+        lines = []
+        lines.append('typedef NS_ENUM(NSInteger, %s) {' % enum_name)
+        for enum_value in enum_values:
+            lines.append('    %s%s,' % (enum_name, Generator.stylized_name_for_enum_value(enum_value)))
+        lines.append('};')
+        return '\n'.join(lines)
+
+    def _generate_type_interface(self, domain, declaration):
+        lines = []
+        objc_name = ObjCGenerator.objc_name_for_type(declaration.type)
+        lines.append('__attribute__((visibility ("default")))')
+        lines.append('@interface %s : %s' % (objc_name, ObjCGenerator.OBJC_JSON_OBJECT_BASE))
+        required_members = filter(lambda member: not member.is_optional, declaration.type_members)
+        optional_members = filter(lambda member: member.is_optional, declaration.type_members)
+        if required_members:
+            lines.append(self._generate_init_method_for_required_members(domain, declaration, required_members))
+        for member in required_members:
+            lines.append('/* required */ ' + self._generate_member_property(declaration, member))
+        for member in optional_members:
+            lines.append('/* optional */ ' + self._generate_member_property(declaration, member))
+        lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_init_method_for_required_members(self, domain, declaration, required_members):
+        pairs = []
+        for member in required_members:
+            objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+            var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+            pairs.append('%s:(%s)%s' % (var_name, objc_type, var_name))
+        pairs[0] = ucfirst(pairs[0])
+        return '- (instancetype)initWith%s;' % ' '.join(pairs)
+
+    def _generate_member_property(self, declaration, member):
+        accessor_type = ObjCGenerator.objc_accessor_type_for_member(member)
+        objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+        return '@property (nonatomic, %s) %s;' % (accessor_type, join_type_and_name(objc_type, ObjCGenerator.identifier_to_objc_identifier(member.member_name)))
+
+    def _generate_command_protocols(self, domain):
+        lines = []
+        if domain.commands:
+            objc_name = '%s%sDomainHandler' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+            lines.append('@protocol %s <NSObject>' % objc_name)
+            lines.append('@required')
+            for command in domain.commands:
+                lines.append(self._generate_single_command_protocol(domain, command))
+            lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_single_command_protocol(self, domain, command):
+        pairs = []
+        pairs.append('ErrorCallback:(void(^)(NSString *error))errorCallback')
+        pairs.append('successCallback:(%s)successCallback' % self._callback_block_for_command(domain, command))
+        for parameter in command.call_parameters:
+            param_name = parameter.parameter_name
+            pairs.append('%s:(%s)%s' % (param_name, ObjCGenerator.objc_type_for_param(domain, command.command_name, parameter), param_name))
+        return '- (void)%sWith%s;' % (command.command_name, ' '.join(pairs))
+
+    def _callback_block_for_command(self, domain, command):
+        pairs = []
+        for parameter in command.return_parameters:
+            pairs.append(join_type_and_name(ObjCGenerator.objc_type_for_param(domain, command.command_name, parameter), parameter.parameter_name))
+        return 'void(^)(%s)' % ', '.join(pairs)
+
+    def _generate_event_interfaces(self, domain):
+        lines = []
+        if domain.events:
+            objc_name = '%s%sDomainEventDispatcher' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+            lines.append('__attribute__((visibility ("default")))')
+            lines.append('@interface %s : NSObject' % objc_name)
+            for event in domain.events:
+                lines.append(self._generate_single_event_interface(domain, event))
+            lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_single_event_interface(self, domain, event):
+        if not event.event_parameters:
+            return '- (void)%s;' % event.event_name
+        pairs = []
+        for parameter in event.event_parameters:
+            param_name = parameter.parameter_name
+            pairs.append('%s:(%s)%s' % (param_name, ObjCGenerator.objc_type_for_param(domain, event.event_name, parameter), param_name))
+        pairs[0] = ucfirst(pairs[0])
+        return '- (void)%sWith%s;' % (event.event_name, ' '.join(pairs))
diff --git a/inspector/scripts/codegen/generate_objc_internal_header.py b/inspector/scripts/codegen/generate_objc_internal_header.py
new file mode 100755 (executable)
index 0000000..2501ad3
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator, ucfirst
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+class ObjCInternalHeaderGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sInternal.h' % ObjCGenerator.OBJC_PREFIX
+
+    def generate_output(self):
+        headers = set([
+            '"%s.h"' % ObjCGenerator.OBJC_PREFIX,
+            '"RWIProtocolJSONObjectInternal.h"',
+            '<JavaScriptCore/InspectorValues.h>',
+            '<JavaScriptCore/AugmentableInspectorController.h>',
+        ])
+
+        header_args = {
+            'includes': '\n'.join(['#import ' + header for header in sorted(headers)]),
+        }
+
+        domains = self.domains_to_generate()
+        event_domains = filter(ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model()), domains)
+
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.GenericHeaderPrelude).substitute(None, **header_args))
+        sections.append('\n\n'.join(filter(None, map(self._generate_event_dispatcher_private_interfaces, event_domains))))
+        sections.append(Template(ObjCTemplates.GenericHeaderPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def _generate_event_dispatcher_private_interfaces(self, domain):
+        lines = []
+        if domain.events:
+            objc_name = '%s%sDomainEventDispatcher' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
+            lines.append('@interface %s (Private)' % objc_name)
+            lines.append('- (instancetype)initWithController:(Inspector::AugmentableInspectorController*)controller;')
+            lines.append('@end')
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generate_objc_protocol_types_implementation.py b/inspector/scripts/codegen/generate_objc_protocol_types_implementation.py
new file mode 100755 (executable)
index 0000000..95b57f6
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import logging
+import string
+from string import Template
+
+from generator import Generator, ucfirst
+from models import ObjectType
+from objc_generator import ObjCGenerator
+from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
+
+log = logging.getLogger('global')
+
+
+def add_newline(lines):
+    if lines and lines[-1] == '':
+        return
+    lines.append('')
+
+
+class ObjCProtocolTypesImplementationGenerator(Generator):
+    def __init__(self, model, input_filepath):
+        Generator.__init__(self, model, input_filepath)
+
+    def output_filename(self):
+        return '%sTypes.mm' % ObjCGenerator.OBJC_PREFIX
+
+    def domains_to_generate(self):
+        return filter(ObjCGenerator.should_generate_domain_types_filter(self.model()), Generator.domains_to_generate(self))
+
+    def generate_output(self):
+        secondary_headers = [
+            '"%sEnumConversionHelpers.h"' % ObjCGenerator.OBJC_PREFIX,
+            '<JavaScriptCore/InspectorValues.h>',
+            '<wtf/Assertions.h>',
+        ]
+
+        header_args = {
+            'primaryInclude': '"%sInternal.h"' % ObjCGenerator.OBJC_PREFIX,
+            'secondaryIncludes': '\n'.join(['#import %s' % header for header in secondary_headers]),
+        }
+
+        domains = self.domains_to_generate()
+        sections = []
+        sections.append(self.generate_license())
+        sections.append(Template(ObjCTemplates.ImplementationPrelude).substitute(None, **header_args))
+        sections.extend(map(self.generate_type_implementations, domains))
+        sections.append(Template(ObjCTemplates.ImplementationPostlude).substitute(None, **header_args))
+        return '\n\n'.join(sections)
+
+    def generate_type_implementations(self, domain):
+        lines = []
+        for declaration in domain.type_declarations:
+            if (isinstance(declaration.type, ObjectType)):
+                add_newline(lines)
+                lines.append(self.generate_type_implementation(domain, declaration))
+        return '\n'.join(lines)
+
+    def generate_type_implementation(self, domain, declaration):
+        lines = []
+        lines.append('@implementation %s' % ObjCGenerator.objc_name_for_type(declaration.type))
+        required_members = filter(lambda member: not member.is_optional, declaration.type_members)
+        if required_members:
+            lines.append('')
+            lines.append(self._generate_init_method_for_required_members(domain, declaration, required_members))
+        for member in declaration.type_members:
+            lines.append('')
+            lines.append(self._generate_setter_for_member(domain, declaration, member))
+            lines.append('')
+            lines.append(self._generate_getter_for_member(domain, declaration, member))
+        lines.append('')
+        lines.append('@end')
+        return '\n'.join(lines)
+
+    def _generate_init_method_for_required_members(self, domain, declaration, required_members):
+        pairs = []
+        for member in required_members:
+            objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+            var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+            pairs.append('%s:(%s)%s' % (var_name, objc_type, var_name))
+        pairs[0] = ucfirst(pairs[0])
+        lines = []
+        lines.append('- (instancetype)initWith%s;' % ' '.join(pairs))
+        lines.append('{')
+        lines.append('    self = [super init];')
+        lines.append('    if (!self)')
+        lines.append('        return nil;')
+        lines.append('')
+
+        required_pointer_members = filter(lambda member: ObjCGenerator.is_type_objc_pointer_type(member.type), required_members)
+        if required_pointer_members:
+            for member in required_pointer_members:
+                var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+                lines.append('    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(%s, @"%s");' % (var_name, var_name))
+                objc_array_class = ObjCGenerator.objc_class_for_array_type(member.type)
+                if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+                    lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+            lines.append('')
+
+        for member in required_members:
+            var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+            lines.append('    self.%s = %s;' % (var_name, var_name))
+
+        lines.append('')
+        lines.append('    return self;')
+        lines.append('}')
+        return '\n'.join(lines)
+
+    def _generate_setter_for_member(self, domain, declaration, member):
+        objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+        var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+        setter_method = ObjCGenerator.objc_setter_method_for_member(declaration, member)
+        conversion_expression = ObjCGenerator.objc_to_protocol_expression_for_member(declaration, member, var_name)
+        lines = []
+        lines.append('- (void)set%s:(%s)%s' % (ucfirst(var_name), objc_type, var_name))
+        lines.append('{')
+        objc_array_class = ObjCGenerator.objc_class_for_array_type(member.type)
+        if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
+            lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
+        lines.append('    [super %s:%s forKey:@"%s"];' % (setter_method, conversion_expression, member.member_name))
+        lines.append('}')
+        return '\n'.join(lines)
+
+    def _generate_getter_for_member(self, domain, declaration, member):
+        objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+        var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name)
+        getter_method = ObjCGenerator.objc_getter_method_for_member(declaration, member)
+        basic_expression = '[super %s:@"%s"]' % (getter_method, member.member_name)
+        conversion_expression = ObjCGenerator.protocol_to_objc_expression_for_member(declaration, member, basic_expression)
+        lines = []
+        lines.append('- (%s)%s' % (objc_type, var_name))
+        lines.append('{')
+        lines.append('    return %s;' % conversion_expression)
+        lines.append('}')
+        return '\n'.join(lines)
diff --git a/inspector/scripts/codegen/generator.py b/inspector/scripts/codegen/generator.py
new file mode 100755 (executable)
index 0000000..a1923fe
--- /dev/null
@@ -0,0 +1,241 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import os.path
+import re
+from string import Template
+
+from generator_templates import GeneratorTemplates as Templates
+from models import PrimitiveType, ObjectType, ArrayType, EnumType, AliasedType, Frameworks
+
+log = logging.getLogger('global')
+
+
+def ucfirst(str):
+    return str[:1].upper() + str[1:]
+
+_ALWAYS_UPPERCASED_ENUM_VALUE_SUBSTRINGS = set(['API', 'CSS', 'DOM', 'HTML', 'XHR', 'XML'])
+
+# These objects are built manually by creating and setting InspectorValues.
+# Before sending these over the protocol, their shapes are checked against the specification.
+# So, any types referenced by these types require debug-only assertions that check values.
+# Calculating necessary assertions is annoying, and adds a lot of complexity to the generator.
+
+# FIXME: This should be converted into a property in JSON.
+_TYPES_NEEDING_RUNTIME_CASTS = set([
+    "Runtime.RemoteObject",
+    "Runtime.PropertyDescriptor",
+    "Runtime.InternalPropertyDescriptor",
+    "Runtime.CollectionEntry",
+    "Debugger.FunctionDetails",
+    "Debugger.CallFrame",
+    "Canvas.TraceLog",
+    "Canvas.ResourceInfo",
+    "Canvas.ResourceState",
+    # This should be a temporary hack. TimelineEvent should be created via generated C++ API.
+    "Timeline.TimelineEvent",
+    # For testing purposes only.
+    "Test.TypeNeedingCast"
+])
+
+# FIXME: This should be converted into a property in JSON.
+_TYPES_WITH_OPEN_FIELDS = set([
+    "Timeline.TimelineEvent",
+    # InspectorStyleSheet not only creates this property but wants to read it and modify it.
+    "CSS.CSSProperty",
+    # InspectorResourceAgent needs to update mime-type.
+    "Network.Response",
+    # For testing purposes only.
+    "Test.OpenParameterBundle"
+])
+
+
+class Generator:
+    def __init__(self, model, input_filepath):
+        self._model = model
+        self._input_filepath = input_filepath
+
+    def model(self):
+        return self._model
+
+    def generate_license(self):
+        return Template(Templates.CopyrightBlock).substitute(None, inputFilename=os.path.basename(self._input_filepath))
+
+    # These methods are overridden by subclasses.
+    def non_supplemental_domains(self):
+        return filter(lambda domain: not domain.is_supplemental, self.model().domains)
+
+    def domains_to_generate(self):
+        return self.non_supplemental_domains()
+
+    def generate_output(self):
+        pass
+
+    def output_filename(self):
+        pass
+
+    def encoding_for_enum_value(self, enum_value):
+        if not hasattr(self, "_assigned_enum_values"):
+            self._traverse_and_assign_enum_values()
+
+        return self._enum_value_encodings[enum_value]
+
+    def assigned_enum_values(self):
+        if not hasattr(self, "_assigned_enum_values"):
+            self._traverse_and_assign_enum_values()
+
+        return self._assigned_enum_values[:]  # Slice.
+
+    @staticmethod
+    def type_needs_runtime_casts(_type):
+        return _type.qualified_name() in _TYPES_NEEDING_RUNTIME_CASTS
+
+    @staticmethod
+    def type_has_open_fields(_type):
+        return _type.qualified_name() in _TYPES_WITH_OPEN_FIELDS
+
+    def type_needs_shape_assertions(self, _type):
+        if not hasattr(self, "_types_needing_shape_assertions"):
+            self.calculate_types_requiring_shape_assertions(self.model().domains)
+
+        return _type in self._types_needing_shape_assertions
+
+    # To restrict the domains over which we compute types needing assertions, call this method
+    # before generating any output with the desired domains parameter. The computed
+    # set of types will not be automatically regenerated on subsequent calls to
+    # Generator.types_needing_shape_assertions().
+    def calculate_types_requiring_shape_assertions(self, domains):
+        domain_names = map(lambda domain: domain.domain_name, domains)
+        log.debug("> Calculating types that need shape assertions (eligible domains: %s)" % ", ".join(domain_names))
+
+        # Mutates the passed-in set; this simplifies checks to prevent infinite recursion.
+        def gather_transitively_referenced_types(_type, gathered_types):
+            if _type in gathered_types:
+                return
+
+            if isinstance(_type, ObjectType):
+                log.debug("> Adding type %s to list of types needing shape assertions." % _type.qualified_name())
+                gathered_types.add(_type)
+                for type_member in _type.members:
+                    gather_transitively_referenced_types(type_member.type, gathered_types)
+            elif isinstance(_type, EnumType):
+                log.debug("> Adding type %s to list of types needing shape assertions." % _type.qualified_name())
+                gathered_types.add(_type)
+            elif isinstance(_type, AliasedType):
+                gather_transitively_referenced_types(_type.aliased_type, gathered_types)
+            elif isinstance(_type, ArrayType):
+                gather_transitively_referenced_types(_type.element_type, gathered_types)
+
+        found_types = set()
+        for domain in domains:
+            for declaration in domain.type_declarations:
+                if declaration.type.qualified_name() in _TYPES_NEEDING_RUNTIME_CASTS:
+                    log.debug("> Gathering types referenced by %s to generate shape assertions." % declaration.type.qualified_name())
+                    gather_transitively_referenced_types(declaration.type, found_types)
+
+        self._types_needing_shape_assertions = found_types
+
+    # Private helper instance methods.
+    def _traverse_and_assign_enum_values(self):
+        self._enum_value_encodings = {}
+        self._assigned_enum_values = []
+        all_types = []
+
+        domains = self.non_supplemental_domains()
+
+        for domain in domains:
+            for type_declaration in domain.type_declarations:
+                all_types.append(type_declaration.type)
+                for type_member in type_declaration.type_members:
+                    all_types.append(type_member.type)
+
+        for domain in domains:
+            for event in domain.events:
+                all_types.extend([parameter.type for parameter in event.event_parameters])
+
+        for domain in domains:
+            for command in domain.commands:
+                all_types.extend([parameter.type for parameter in command.call_parameters])
+                all_types.extend([parameter.type for parameter in command.return_parameters])
+
+        for _type in all_types:
+            if not isinstance(_type, EnumType):
+                continue
+            map(self._assign_encoding_for_enum_value, _type.enum_values())
+
+    def _assign_encoding_for_enum_value(self, enum_value):
+        if enum_value in self._enum_value_encodings:
+            return
+
+        self._enum_value_encodings[enum_value] = len(self._assigned_enum_values)
+        self._assigned_enum_values.append(enum_value)
+
+    # Miscellaneous text manipulation routines.
+    def wrap_with_guard_for_domain(self, domain, text):
+        if self.model().framework is Frameworks.WebInspector:
+            return text
+        guard = domain.feature_guard
+        if guard:
+            return Generator.wrap_with_guard(guard, text)
+        return text
+
+    @staticmethod
+    def wrap_with_guard(guard, text):
+        return '\n'.join([
+            '#if %s' % guard,
+            text,
+            '#endif // %s' % guard,
+        ])
+
+    @staticmethod
+    def stylized_name_for_enum_value(enum_value):
+        regex = '(%s)' % "|".join(_ALWAYS_UPPERCASED_ENUM_VALUE_SUBSTRINGS)
+
+        def replaceCallback(match):
+            return match.group(1).upper()
+
+        # Split on hyphen, introduce camelcase, and force uppercasing of acronyms.
+        subwords = map(ucfirst, enum_value.split('-'))
+        return re.sub(re.compile(regex, re.IGNORECASE), replaceCallback, "".join(subwords))
+
+    @staticmethod
+    def js_name_for_parameter_type(_type):
+        _type = _type
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type  # Fall through.
+        if isinstance(_type, EnumType):
+            _type = _type.primitive_type  # Fall through.
+
+        if isinstance(_type, (ArrayType, ObjectType)):
+            return 'object'
+        if isinstance(_type, PrimitiveType):
+            if _type.qualified_name() in ['object', 'any']:
+                return 'object'
+            elif _type.qualified_name() in ['integer', 'number']:
+                return 'number'
+            else:
+                return _type.qualified_name()
diff --git a/inspector/scripts/codegen/generator_templates.py b/inspector/scripts/codegen/generator_templates.py
new file mode 100644 (file)
index 0000000..f2e330a
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generator templates, which can be filled with string.Template.
+# Following are classes that fill the templates from the typechecked model.
+
+
+class GeneratorTemplates:
+    CopyrightBlock = (
+    """/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from ${inputFilename}
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py""")
diff --git a/inspector/scripts/codegen/models.py b/inspector/scripts/codegen/models.py
new file mode 100755 (executable)
index 0000000..2dabdc0
--- /dev/null
@@ -0,0 +1,591 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import collections
+
+log = logging.getLogger('global')
+
+
+def ucfirst(str):
+    return str[:1].upper() + str[1:]
+
+
+def find_duplicates(l):
+    return [key for key, count in collections.Counter(l).items() if count > 1]
+
+
+_FRAMEWORK_CONFIG_MAP = {
+    "Global": {
+    },
+    "JavaScriptCore": {
+        "export_macro": "JS_EXPORT_PRIVATE"
+    },
+    "WebInspector": {
+    },
+    # Used for code generator tests.
+    "Test": {
+    }
+}
+
+
+class ParseException(Exception):
+    pass
+
+
+class TypecheckException(Exception):
+    pass
+
+
+class Framework:
+    def __init__(self, name):
+        self._settings = _FRAMEWORK_CONFIG_MAP[name]
+        self.name = name
+
+    def setting(self, key, default=''):
+        return self._settings.get(key, default)
+
+    @staticmethod
+    def fromString(frameworkString):
+        if frameworkString == "Global":
+            return Frameworks.Global
+
+        if frameworkString == "JavaScriptCore":
+            return Frameworks.JavaScriptCore
+
+        if frameworkString == "WebInspector":
+            return Frameworks.WebInspector
+
+        if frameworkString == "Test":
+            return Frameworks.Test
+
+        raise ParseException("Unknown framework: %s" % frameworkString)
+
+
+class Frameworks:
+    Global = Framework("Global")
+    JavaScriptCore = Framework("JavaScriptCore")
+    WebInspector = Framework("WebInspector")
+    Test = Framework("Test")
+
+
+class TypeReference:
+    def __init__(self, type_kind, referenced_type_name, enum_values, array_items):
+        self.type_kind = type_kind
+        self.referenced_type_name = referenced_type_name
+        self.enum_values = enum_values
+        if array_items is None:
+            self.array_type_ref = None
+        else:
+            self.array_type_ref = TypeReference(array_items.get('type'), array_items.get('$ref'), array_items.get('enum'), array_items.get('items'))
+
+        if type_kind is not None and referenced_type_name is not None:
+            raise ParseException("Type reference cannot have both 'type' and '$ref' keys.")
+
+        if type_kind == "array" and array_items is None:
+            raise ParseException("Type reference with type 'array' must have key 'items' to define array element type.")
+
+        if enum_values is not None and len(enum_values) == 0:
+            raise ParseException("Type reference with enum values must have at least one enum value.")
+
+    def referenced_name(self):
+        if self.referenced_type_name is not None:
+            return self.referenced_type_name
+        else:
+            return self.type_kind  # integer, string, number, boolean, enum, object, array
+
+
+class Type:
+    def __init__(self):
+        pass
+
+    def __eq__(self, other):
+        return self.qualified_name() == other.qualified_name()
+
+    def __hash__(self):
+        return self.qualified_name().__hash__()
+
+    def raw_name(self):
+        return self._name
+
+    # These methods should be overridden by subclasses.
+    def is_enum(self):
+        return False
+
+    def type_domain(self):
+        pass
+
+    def qualified_name(self):
+        pass
+
+    # This is used to resolve nested types after instances are created.
+    def resolve_type_references(self, protocol):
+        pass
+
+
+class PrimitiveType(Type):
+    def __init__(self, name):
+        self._name = name
+
+    def __repr__(self):
+        return 'PrimitiveType[%s]' % self.qualified_name()
+
+    def type_domain(self):
+        return None
+
+    def qualified_name(self):
+        return self.raw_name()
+
+
+class AliasedType(Type):
+    def __init__(self, name, domain, aliased_type_ref):
+        self._name = name
+        self._domain = domain
+        self._aliased_type_ref = aliased_type_ref
+        self.aliased_type = None
+
+    def __repr__(self):
+        if self.aliased_type is not None:
+            return 'AliasedType[%s -> %r]' % (self.qualified_name(), self.aliased_type)
+        else:
+            return 'AliasedType[%s -> (unresolved)]' % self.qualified_name()
+
+    def is_enum(self):
+        return self.aliased_type.is_enum()
+
+    def type_domain(self):
+        return self._domain
+
+    def qualified_name(self):
+        return  ".".join([self.type_domain().domain_name, self.raw_name()])
+
+    def resolve_type_references(self, protocol):
+        if self.aliased_type is not None:
+            return
+
+        self.aliased_type = protocol.lookup_type_reference(self._aliased_type_ref, self.type_domain())
+        log.debug("< Resolved type reference for aliased type in %s: %s" % (self.qualified_name(), self.aliased_type.qualified_name()))
+
+
+class EnumType(Type):
+    def __init__(self, name, domain, values, primitive_type_ref, is_anonymous=False):
+        self._name = name
+        self._domain = domain
+        self._values = values
+        self._primitive_type_ref = primitive_type_ref
+        self.primitive_type = None
+        self.is_anonymous = is_anonymous
+
+    def __repr__(self):
+        return 'EnumType[value_type=%s; values=%s]' % (self.qualified_name(), ', '.join(map(str, self.enum_values())))
+
+    def is_enum(self):
+        return True
+
+    def type_domain(self):
+        return self._domain
+
+    def enum_values(self):
+        return self._values
+
+    def qualified_name(self):
+        return  ".".join([self.type_domain().domain_name, self.raw_name()])
+
+    def resolve_type_references(self, protocol):
+        if self.primitive_type is not None:
+            return
+
+        self.primitive_type = protocol.lookup_type_reference(self._primitive_type_ref, Domains.GLOBAL)
+        log.debug("< Resolved type reference for enum type in %s: %s" % (self.qualified_name(), self.primitive_type.qualified_name()))
+        log.debug("<< enum values: %s" % self.enum_values())
+
+
+class ArrayType(Type):
+    def __init__(self, name, element_type_ref, domain):
+        self._name = name
+        self._domain = domain
+        self._element_type_ref = element_type_ref
+        self.element_type = None
+
+    def __repr__(self):
+        if self.element_type is not None:
+            return 'ArrayType[element_type=%r]' % self.element_type
+        else:
+            return 'ArrayType[element_type=(unresolved)]'
+
+    def type_domain(self):
+        return self._domain
+
+    def qualified_name(self):
+        return  ".".join(["array", self.element_type.qualified_name()])
+
+    def resolve_type_references(self, protocol):
+        if self.element_type is not None:
+            return
+
+        self.element_type = protocol.lookup_type_reference(self._element_type_ref, self.type_domain())
+        log.debug("< Resolved type reference for element type in %s: %s" % (self.qualified_name(), self.element_type.qualified_name()))
+
+
+class ObjectType(Type):
+    def __init__(self, name, domain, members):
+        self._name = name
+        self._domain = domain
+        self.members = members
+
+    def __repr__(self):
+        return 'ObjectType[%s]' % self.qualified_name()
+
+    def type_domain(self):
+        return self._domain
+
+    def qualified_name(self):
+        return  ".".join([self.type_domain().domain_name, self.raw_name()])
+
+
+def check_for_required_properties(props, obj, what):
+    for prop in props:
+        if prop not in obj:
+            raise ParseException("When parsing %s, required property missing: %s" % (what, prop))
+
+
+class Protocol:
+    def __init__(self, framework_name):
+        self.domains = []
+        self.types_by_name = {}
+        self.framework = Framework.fromString(framework_name)
+
+    def parse_specification(self, json, isSupplemental):
+        log.debug("parse toplevel")
+
+        if isinstance(json, dict) and 'domains' in json:
+            json = json['domains']
+        if not isinstance(json, list):
+            json = [json]
+
+        for domain in json:
+            self.parse_domain(domain, isSupplemental)
+
+    def parse_domain(self, json, isSupplemental):
+        check_for_required_properties(['domain'], json, "domain")
+        log.debug("parse domain " + json['domain'])
+
+        types = []
+        commands = []
+        events = []
+
+        if 'types' in json:
+            if not isinstance(json['types'], list):
+                raise ParseException("Malformed domain specification: types is not an array")
+            types.extend([self.parse_type_declaration(declaration) for declaration in json['types']])
+
+        if 'commands' in json:
+            if not isinstance(json['commands'], list):
+                raise ParseException("Malformed domain specification: commands is not an array")
+            commands.extend([self.parse_command(command) for command in json['commands']])
+
+        if 'events' in json:
+            if not isinstance(json['events'], list):
+                raise ParseException("Malformed domain specification: events is not an array")
+            events.extend([self.parse_event(event) for event in json['events']])
+
+        if 'availability' in json:
+            if not commands and not events:
+                raise ParseException("Malformed domain specification: availability should only be included if there are commands or events.")
+            allowed_activation_strings = set(['web'])
+            if json['availability'] not in allowed_activation_strings:
+                raise ParseException('Malformed domain specification: availability is an unsupported string. Was: "%s", Allowed values: %s' % (json['availability'], ', '.join(allowed_activation_strings)))
+
+        self.domains.append(Domain(json['domain'], json.get('description', ''), json.get('featureGuard'), json.get('availability'), isSupplemental, types, commands, events))
+
+    def parse_type_declaration(self, json):
+        check_for_required_properties(['id', 'type'], json, "type")
+        log.debug("parse type %s" % json['id'])
+
+        type_members = []
+
+        if 'properties' in json:
+            if not isinstance(json['properties'], list):
+                raise ParseException("Malformed type specification: properties is not an array")
+            type_members.extend([self.parse_type_member(member) for member in json['properties']])
+
+        duplicate_names = find_duplicates([member.member_name for member in type_members])
+        if len(duplicate_names) > 0:
+            raise ParseException("Malformed domain specification: type declaration for %s has duplicate member names" % json['id'])
+
+        type_ref = TypeReference(json['type'], json.get('$ref'), json.get('enum'), json.get('items'))
+        return TypeDeclaration(json['id'], type_ref, json.get("description", ""), type_members)
+
+    def parse_type_member(self, json):
+        check_for_required_properties(['name'], json, "type member")
+        log.debug("parse type member %s" % json['name'])
+
+        type_ref = TypeReference(json.get('type'), json.get('$ref'), json.get('enum'), json.get('items'))
+        return TypeMember(json['name'], type_ref, json.get('optional', False), json.get('description', ""))
+
+    def parse_command(self, json):
+        check_for_required_properties(['name'], json, "command")
+        log.debug("parse command %s" % json['name'])
+
+        call_parameters = []
+        return_parameters = []
+
+        if 'parameters' in json:
+            if not isinstance(json['parameters'], list):
+                raise ParseException("Malformed command specification: parameters is not an array")
+            call_parameters.extend([self.parse_call_or_return_parameter(parameter) for parameter in json['parameters']])
+
+            duplicate_names = find_duplicates([param.parameter_name for param in call_parameters])
+            if len(duplicate_names) > 0:
+                raise ParseException("Malformed domain specification: call parameter list for command %s has duplicate parameter names" % json['name'])
+
+        if 'returns' in json:
+            if not isinstance(json['returns'], list):
+                raise ParseException("Malformed command specification: returns is not an array")
+            return_parameters.extend([self.parse_call_or_return_parameter(parameter) for parameter in json['returns']])
+
+            duplicate_names = find_duplicates([param.parameter_name for param in return_parameters])
+            if len(duplicate_names) > 0:
+                raise ParseException("Malformed domain specification: return parameter list for command %s has duplicate parameter names" % json['name'])
+
+        return Command(json['name'], call_parameters, return_parameters, json.get('description', ""), json.get('async', False))
+
+    def parse_event(self, json):
+        check_for_required_properties(['name'], json, "event")
+        log.debug("parse event %s" % json['name'])
+
+        event_parameters = []
+
+        if 'parameters' in json:
+            if not isinstance(json['parameters'], list):
+                raise ParseException("Malformed event specification: parameters is not an array")
+            event_parameters.extend([self.parse_call_or_return_parameter(parameter) for parameter in json['parameters']])
+
+            duplicate_names = find_duplicates([param.parameter_name for param in event_parameters])
+            if len(duplicate_names) > 0:
+                raise ParseException("Malformed domain specification: parameter list for event %s has duplicate parameter names" % json['name'])
+
+        return Event(json['name'], event_parameters, json.get('description', ""))
+
+    def parse_call_or_return_parameter(self, json):
+        check_for_required_properties(['name'], json, "parameter")
+        log.debug("parse parameter %s" % json['name'])
+
+        type_ref = TypeReference(json.get('type'), json.get('$ref'), json.get('enum'), json.get('items'))
+        return Parameter(json['name'], type_ref, json.get('optional', False), json.get('description', ""))
+
+    def resolve_types(self):
+        qualified_declared_type_names = set(['boolean', 'string', 'integer', 'number', 'enum', 'array', 'object', 'any'])
+
+        self.types_by_name['string'] = PrimitiveType('string')
+        for _primitive_type in ['boolean', 'integer', 'number']:
+            self.types_by_name[_primitive_type] = PrimitiveType(_primitive_type)
+        for _object_type in ['any', 'object']:
+            self.types_by_name[_object_type] = PrimitiveType(_object_type)
+
+        # Gather qualified type names from type declarations in each domain.
+        for domain in self.domains:
+            for declaration in domain.type_declarations:
+                # Basic sanity checking.
+                if declaration.type_ref.referenced_type_name is not None:
+                    raise TypecheckException("Type declarations must name a base type, not a type reference.")
+
+                # Find duplicate qualified type names.
+                qualified_type_name = ".".join([domain.domain_name, declaration.type_name])
+                if qualified_type_name in qualified_declared_type_names:
+                    raise TypecheckException("Duplicate type declaration: %s" % qualified_type_name)
+
+                qualified_declared_type_names.add(qualified_type_name)
+
+                type_instance = None
+
+                kind = declaration.type_ref.type_kind
+                if declaration.type_ref.enum_values is not None:
+                    primitive_type_ref = TypeReference(declaration.type_ref.type_kind, None, None, None)
+                    type_instance = EnumType(declaration.type_name, domain, declaration.type_ref.enum_values, primitive_type_ref)
+                elif kind == "array":
+                    type_instance = ArrayType(declaration.type_name, declaration.type_ref.array_type_ref, domain)
+                elif kind == "object":
+                    type_instance = ObjectType(declaration.type_name, domain, declaration.type_members)
+                else:
+                    type_instance = AliasedType(declaration.type_name, domain, declaration.type_ref)
+
+                log.debug("< Created fresh type %r for declaration %s" % (type_instance, qualified_type_name))
+                self.types_by_name[qualified_type_name] = type_instance
+
+        # Resolve all type references recursively.
+        for domain in self.domains:
+            domain.resolve_type_references(self)
+
+    def lookup_type_for_declaration(self, declaration, domain):
+        # This will only match a type defined in the same domain, where prefixes aren't required.
+        qualified_name = ".".join([domain.domain_name, declaration.type_name])
+        if qualified_name in self.types_by_name:
+            found_type = self.types_by_name[qualified_name]
+            found_type.resolve_type_references(self)
+            return found_type
+
+        raise TypecheckException("Lookup failed for type declaration: %s (referenced from domain: %s)" % (declaration.type_name, domain.domain_name))
+
+    def lookup_type_reference(self, type_ref, domain):
+        # If reference is to an anonymous array type, create a fresh instance.
+        if type_ref.type_kind == "array":
+            type_instance = ArrayType(None, type_ref.array_type_ref, domain)
+            type_instance.resolve_type_references(self)
+            log.debug("< Created fresh type instance for anonymous array type: %s" % type_instance.qualified_name())
+            return type_instance
+
+        # If reference is to an anonymous enum type, create a fresh instance.
+        if type_ref.enum_values is not None:
+            # We need to create a type reference without enum values as the enum's nested type.
+            primitive_type_ref = TypeReference(type_ref.type_kind, None, None, None)
+            type_instance = EnumType("(anonymous)", domain, type_ref.enum_values, primitive_type_ref, True)
+            type_instance.resolve_type_references(self)
+            log.debug("< Created fresh type instance for anonymous enum type: %s" % type_instance.qualified_name())
+            return type_instance
+
+        # This will match when referencing a type defined in the same domain, where prefixes aren't required.
+        qualified_name = ".".join([domain.domain_name, type_ref.referenced_name()])
+        if qualified_name in self.types_by_name:
+            found_type = self.types_by_name[qualified_name]
+            found_type.resolve_type_references(self)
+            log.debug("< Lookup succeeded for unqualified type: %s" % found_type.qualified_name())
+            return found_type
+
+        # This will match primitive types and fully-qualified types from a different domain.
+        if type_ref.referenced_name() in self.types_by_name:
+            found_type = self.types_by_name[type_ref.referenced_name()]
+            found_type.resolve_type_references(self)
+            log.debug("< Lookup succeeded for primitive or qualified type: %s" % found_type.qualified_name())
+            return found_type
+
+        raise TypecheckException("Lookup failed for type reference: %s (referenced from domain: %s)" % (type_ref.referenced_name(), domain.domain_name))
+
+
+class Domain:
+    def __init__(self, domain_name, description, feature_guard, availability, isSupplemental, type_declarations, commands, events):
+        self.domain_name = domain_name
+        self.description = description
+        self.feature_guard = feature_guard
+        self.availability = availability
+        self.is_supplemental = isSupplemental
+        self.type_declarations = type_declarations
+        self.commands = commands
+        self.events = events
+
+    def resolve_type_references(self, protocol):
+        log.debug("> Resolving type declarations for domain: %s" % self.domain_name)
+        for declaration in self.type_declarations:
+            declaration.resolve_type_references(protocol, self)
+
+        log.debug("> Resolving types in commands for domain: %s" % self.domain_name)
+        for command in self.commands:
+            command.resolve_type_references(protocol, self)
+
+        log.debug("> Resolving types in events for domain: %s" % self.domain_name)
+        for event in self.events:
+            event.resolve_type_references(protocol, self)
+
+
+class Domains:
+    GLOBAL = Domain("", "The global domain, in which primitive types are implicitly declared.", None, None, True, [], [], [])
+
+
+class TypeDeclaration:
+    def __init__(self, type_name, type_ref, description, type_members):
+        self.type_name = type_name
+        self.type_ref = type_ref
+        self.description = description
+        self.type_members = type_members
+
+        if self.type_name != ucfirst(self.type_name):
+            raise ParseException("Types must begin with an uppercase character.")
+
+    def resolve_type_references(self, protocol, domain):
+        log.debug(">> Resolving type references for type declaration: %s" % self.type_name)
+        self.type = protocol.lookup_type_for_declaration(self, domain)
+        for member in self.type_members:
+            member.resolve_type_references(protocol, domain)
+
+
+class TypeMember:
+    def __init__(self, member_name, type_ref, is_optional, description):
+        self.member_name = member_name
+        self.type_ref = type_ref
+        self.is_optional = is_optional
+        self.description = description
+
+        if self.is_optional not in [True, False]:
+            raise ParseException("The 'optional' flag for a type member must be a boolean literal.")
+
+    def resolve_type_references(self, protocol, domain):
+        log.debug(">>> Resolving type references for type member: %s" % self.member_name)
+        self.type = protocol.lookup_type_reference(self.type_ref, domain)
+
+
+class Parameter:
+    def __init__(self, parameter_name, type_ref, is_optional, description):
+        self.parameter_name = parameter_name
+        self.type_ref = type_ref
+        self.is_optional = is_optional
+        self.description = description
+
+        if self.is_optional not in [True, False]:
+            raise ParseException("The 'optional' flag for a parameter must be a boolean literal.")
+
+    def resolve_type_references(self, protocol, domain):
+        log.debug(">>> Resolving type references for parameter: %s" % self.parameter_name)
+        self.type = protocol.lookup_type_reference(self.type_ref, domain)
+
+
+class Command:
+    def __init__(self, command_name, call_parameters, return_parameters, description, is_async):
+        self.command_name = command_name
+        self.call_parameters = call_parameters
+        self.return_parameters = return_parameters
+        self.description = description
+        self.is_async = is_async
+
+    def resolve_type_references(self, protocol, domain):
+        log.debug(">> Resolving type references for call parameters in command: %s" % self.command_name)
+        for parameter in self.call_parameters:
+            parameter.resolve_type_references(protocol, domain)
+
+        log.debug(">> Resolving type references for return parameters in command: %s" % self.command_name)
+        for parameter in self.return_parameters:
+            parameter.resolve_type_references(protocol, domain)
+
+
+class Event:
+    def __init__(self, event_name, event_parameters, description):
+        self.event_name = event_name
+        self.event_parameters = event_parameters
+        self.description = description
+
+    def resolve_type_references(self, protocol, domain):
+        log.debug(">> Resolving type references for parameters in event: %s" % self.event_name)
+        for parameter in self.event_parameters:
+            parameter.resolve_type_references(protocol, domain)
diff --git a/inspector/scripts/codegen/objc_generator.py b/inspector/scripts/codegen/objc_generator.py
new file mode 100755 (executable)
index 0000000..f6dd03c
--- /dev/null
@@ -0,0 +1,523 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+from generator import Generator, ucfirst
+from models import PrimitiveType, ObjectType, ArrayType, EnumType, AliasedType, Frameworks
+
+log = logging.getLogger('global')
+
+
+def join_type_and_name(type_str, name_str):
+    if type_str.endswith('*'):
+        return type_str + name_str
+    return type_str + ' ' + name_str
+
+
+def strip_block_comment_markers(str):
+    return str.replace('/*', '').replace('*/', '')
+
+
+def remove_duplicate_from_str(str, possible_duplicate):
+    return str.replace(possible_duplicate + possible_duplicate, possible_duplicate)
+
+
+_OBJC_IDENTIFIER_RENAME_MAP = {
+    'this': 'thisObject',  # Debugger.CallFrame.this
+    'description': 'stringRepresentation',  # Runtime.RemoteObject.description
+    'id': 'identifier',  # Page.Frame.id, Runtime.ExecutionContextDescription.id, Debugger.BreakpointAction.id
+}
+
+_OBJC_IDENTIFIER_REVERSE_RENAME_MAP = dict((v, k) for k, v in _OBJC_IDENTIFIER_RENAME_MAP.iteritems())
+
+
+class ObjCTypeCategory:
+    Simple = 0
+    String = 1
+    Object = 2
+    Array = 3
+
+    @staticmethod
+    def category_for_type(_type):
+        if (isinstance(_type, PrimitiveType)):
+            if _type.raw_name() is 'string':
+                return ObjCTypeCategory.String
+            if  _type.raw_name() in ['object', 'any']:
+                return ObjCTypeCategory.Object
+            if _type.raw_name() is 'array':
+                return ObjCTypeCategory.Array
+            return ObjCTypeCategory.Simple
+        if (isinstance(_type, ObjectType)):
+            return ObjCTypeCategory.Object
+        if (isinstance(_type, ArrayType)):
+            return ObjCTypeCategory.Array
+        if (isinstance(_type, AliasedType)):
+            return ObjCTypeCategory.category_for_type(_type.aliased_type)
+        if (isinstance(_type, EnumType)):
+            return ObjCTypeCategory.category_for_type(_type.primitive_type)
+        return None
+
+
+
+# This class contains extra static methods used for generation, but does
+# not participate in any inheritance hierarchy. File generators should
+# extend the generic "Generator" class instead.
+class ObjCGenerator:
+    OBJC_PREFIX = 'RWIProtocol'
+    OBJC_JSON_OBJECT_BASE = '%sJSONObject' % OBJC_PREFIX
+
+    # Adjust identifier names that collide with ObjC keywords.
+
+    @staticmethod
+    def identifier_to_objc_identifier(name):
+        return _OBJC_IDENTIFIER_RENAME_MAP.get(name, name)
+
+    @staticmethod
+    def objc_identifier_to_identifier(name):
+        return _OBJC_IDENTIFIER_REVERSE_RENAME_MAP.get(name, name)
+
+    # Generate ObjC types, command handlers, and event dispatchers for a subset of domains.
+
+    DOMAINS_TO_GENERATE = ['CSS', 'DOM', 'DOMStorage', 'Network', 'Page', 'GenericTypes']
+
+    @staticmethod
+    def should_generate_domain_types_filter(model):
+        def should_generate_domain_types(domain):
+            if model.framework is Frameworks.Test:
+                return True
+            whitelist = set(ObjCGenerator.DOMAINS_TO_GENERATE)
+            whitelist.update(set(['Console', 'Debugger', 'Runtime']))
+            return domain.domain_name in whitelist
+        return should_generate_domain_types
+
+    @staticmethod
+    def should_generate_domain_command_handler_filter(model):
+        def should_generate_domain_command_handler(domain):
+            if model.framework is Frameworks.Test:
+                return True
+            whitelist = set(ObjCGenerator.DOMAINS_TO_GENERATE)
+            return domain.domain_name in whitelist
+        return should_generate_domain_command_handler
+
+    @staticmethod
+    def should_generate_domain_event_dispatcher_filter(model):
+        def should_generate_domain_event_dispatcher(domain):
+            if model.framework is Frameworks.Test:
+                return True
+            whitelist = set(ObjCGenerator.DOMAINS_TO_GENERATE)
+            whitelist.add('Console')
+            return domain.domain_name in whitelist
+        return should_generate_domain_event_dispatcher
+
+    # ObjC enum and type names.
+
+    @staticmethod
+    def objc_name_for_type(type):
+        name = type.qualified_name().replace('.', '')
+        name = remove_duplicate_from_str(name, type.type_domain().domain_name)
+        return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
+
+    @staticmethod
+    def objc_enum_name_for_anonymous_enum_declaration(declaration):
+        domain_name = declaration.type.type_domain().domain_name
+        name = '%s%s' % (domain_name, declaration.type.raw_name())
+        name = remove_duplicate_from_str(name, domain_name)
+        return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
+
+    @staticmethod
+    def objc_enum_name_for_anonymous_enum_member(declaration, member):
+        domain_name = member.type.type_domain().domain_name
+        name = '%s%s%s' % (domain_name, declaration.type.raw_name(), ucfirst(member.member_name))
+        name = remove_duplicate_from_str(name, domain_name)
+        return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
+
+    @staticmethod
+    def objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter):
+        domain_name = domain.domain_name
+        name = '%s%s%s' % (domain_name, ucfirst(event_or_command_name), ucfirst(parameter.parameter_name))
+        name = remove_duplicate_from_str(name, domain_name)
+        return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
+
+    @staticmethod
+    def objc_enum_name_for_non_anonymous_enum(_type):
+        domain_name = _type.type_domain().domain_name
+        name = _type.qualified_name().replace('.', '')
+        name = remove_duplicate_from_str(name, domain_name)
+        return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
+
+    # Miscellaneous name handling.
+
+    @staticmethod
+    def variable_name_prefix_for_domain(domain):
+        domain_name = domain.domain_name
+        if domain_name.startswith('DOM'):
+            return 'dom' + domain_name[3:]
+        if domain_name.startswith('CSS'):
+            return 'css' + domain_name[3:]
+        return domain_name[:1].lower() + domain_name[1:]
+
+    # Type basics.
+
+    @staticmethod
+    def objc_accessor_type_for_raw_name(raw_name):
+        if raw_name in ['string', 'array']:
+            return 'copy'
+        if raw_name in ['integer', 'number', 'boolean']:
+            return 'assign'
+        if raw_name in ['any', 'object']:
+            return 'retain'
+        return None
+
+    @staticmethod
+    def objc_type_for_raw_name(raw_name):
+        if raw_name is 'string':
+            return 'NSString *'
+        if raw_name is 'array':
+            return 'NSArray *'
+        if raw_name is 'integer':
+            return 'int'
+        if raw_name is 'number':
+            return 'double'
+        if raw_name is 'boolean':
+            return 'BOOL'
+        if raw_name in ['any', 'object']:
+            return '%s *' % ObjCGenerator.OBJC_JSON_OBJECT_BASE
+        return None
+
+    @staticmethod
+    def objc_class_for_raw_name(raw_name):
+        if raw_name is 'string':
+            return 'NSString'
+        if raw_name is 'array':
+            return 'NSArray'
+        if raw_name in ['integer', 'number', 'boolean']:
+            return 'NSNumber'
+        if raw_name in ['any', 'object']:
+            return ObjCGenerator.OBJC_JSON_OBJECT_BASE
+        return None
+
+    # FIXME: Can these protocol_type functions be removed in favor of C++ generators functions?
+
+    @staticmethod
+    def protocol_type_for_raw_name(raw_name):
+        if raw_name is 'string':
+            return 'String'
+        if raw_name is 'integer':
+            return 'int'
+        if raw_name is 'number':
+            return 'double'
+        if raw_name is 'boolean':
+            return 'bool'
+        if raw_name in ['any', 'object']:
+            return 'InspectorObject'
+        return None
+
+    @staticmethod
+    def protocol_type_for_type(_type):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return ObjCGenerator.protocol_type_for_raw_name(_type.raw_name())
+        if (isinstance(_type, EnumType)):
+            return ObjCGenerator.protocol_type_for_type(_type.primitive_type)
+        if (isinstance(_type, ObjectType)):
+            return 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name())
+        if (isinstance(_type, ArrayType)):
+            sub_type = ObjCGenerator.protocol_type_for_type(_type.element_type)
+            return 'Inspector::Protocol::Array<%s>' % sub_type
+        return None
+
+    @staticmethod
+    def is_type_objc_pointer_type(_type):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return _type.raw_name() in ['string', 'array', 'any', 'object']
+        if (isinstance(_type, EnumType)):
+            return False
+        if (isinstance(_type, ObjectType)):
+            return True
+        if (isinstance(_type, ArrayType)):
+            return True
+        return None
+
+    @staticmethod
+    def objc_class_for_type(_type):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return ObjCGenerator.objc_class_for_raw_name(_type.raw_name())
+        if (isinstance(_type, EnumType)):
+            return ObjCGenerator.objc_class_for_raw_name(_type.primitive_type.raw_name())
+        if (isinstance(_type, ObjectType)):
+            return ObjCGenerator.objc_name_for_type(_type)
+        if (isinstance(_type, ArrayType)):
+            sub_type = strip_block_comment_markers(ObjCGenerator.objc_class_for_type(_type.element_type))
+            return 'NSArray/*<%s>*/' % sub_type
+        return None
+
+    @staticmethod
+    def objc_class_for_array_type(_type):
+        if isinstance(_type, AliasedType):
+            _type = _type.aliased_type
+        if isinstance(_type, ArrayType):
+            return ObjCGenerator.objc_class_for_type(_type.element_type)
+        return None
+
+    @staticmethod
+    def objc_accessor_type_for_member(member):
+        return ObjCGenerator.objc_accessor_type_for_member_internal(member.type)
+
+    @staticmethod
+    def objc_accessor_type_for_member_internal(_type):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return ObjCGenerator.objc_accessor_type_for_raw_name(_type.raw_name())
+        if (isinstance(_type, EnumType)):
+            return 'assign'
+        if (isinstance(_type, ObjectType)):
+            return 'retain'
+        if (isinstance(_type, ArrayType)):
+            return 'copy'
+        return None
+
+    @staticmethod
+    def objc_type_for_member(declaration, member):
+        return ObjCGenerator.objc_type_for_member_internal(member.type, declaration, member)
+
+    @staticmethod
+    def objc_type_for_member_internal(_type, declaration, member):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return ObjCGenerator.objc_type_for_raw_name(_type.raw_name())
+        if (isinstance(_type, EnumType)):
+            if (_type.is_anonymous):
+                return ObjCGenerator.objc_enum_name_for_anonymous_enum_member(declaration, member)
+            return ObjCGenerator.objc_enum_name_for_non_anonymous_enum(_type)
+        if (isinstance(_type, ObjectType)):
+            return ObjCGenerator.objc_name_for_type(_type) + ' *'
+        if (isinstance(_type, ArrayType)):
+            sub_type = strip_block_comment_markers(ObjCGenerator.objc_class_for_type(_type.element_type))
+            return 'NSArray/*<%s>*/ *' % sub_type
+        return None
+
+    @staticmethod
+    def objc_type_for_param(domain, event_or_command_name, parameter, respect_optional=True):
+        objc_type = ObjCGenerator.objc_type_for_param_internal(parameter.type, domain, event_or_command_name, parameter)
+        if respect_optional and parameter.is_optional:
+            if objc_type.endswith('*'):
+                return objc_type + '*'
+            return objc_type + ' *'
+        return objc_type
+
+    @staticmethod
+    def objc_type_for_param_internal(_type, domain, event_or_command_name, parameter):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            return ObjCGenerator.objc_type_for_raw_name(_type.raw_name())
+        if (isinstance(_type, EnumType)):
+            if _type.is_anonymous:
+                return ObjCGenerator.objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter)
+            return ObjCGenerator.objc_enum_name_for_non_anonymous_enum(_type)
+        if (isinstance(_type, ObjectType)):
+            return ObjCGenerator.objc_name_for_type(_type) + ' *'
+        if (isinstance(_type, ArrayType)):
+            sub_type = strip_block_comment_markers(ObjCGenerator.objc_class_for_type(_type.element_type))
+            return 'NSArray/*<%s>*/ *' % sub_type
+        return None
+
+    # ObjC <-> Protocol conversion for commands and events.
+    #   - convert a command call parameter received from Protocol to ObjC for handler
+    #   - convert a command return parameter in callback block from ObjC to Protocol to send
+    #   - convert an event parameter from ObjC API to Protocol to send
+
+    @staticmethod
+    def objc_protocol_export_expression_for_variable(var_type, var_name):
+        category = ObjCTypeCategory.category_for_type(var_type)
+        if category in [ObjCTypeCategory.Simple, ObjCTypeCategory.String]:
+            if isinstance(var_type, EnumType):
+                return 'toProtocolString(%s)' % var_name
+            return var_name
+        if category is ObjCTypeCategory.Object:
+            return '[%s toInspectorObject]' % var_name
+        if category is ObjCTypeCategory.Array:
+            protocol_type = ObjCGenerator.protocol_type_for_type(var_type.element_type)
+            objc_class = ObjCGenerator.objc_class_for_type(var_type.element_type)
+            if protocol_type == 'Inspector::Protocol::Array<String>':
+                return 'inspectorStringArrayArray(%s)' % var_name
+            if protocol_type is 'String' and objc_class is 'NSString':
+                return 'inspectorStringArray(%s)' % var_name
+            if protocol_type is 'int' and objc_class is 'NSNumber':
+                return 'inspectorIntegerArray(%s)' % var_name
+            if protocol_type is 'double' and objc_class is 'NSNumber':
+                return 'inspectorDoubleArray(%s)' % var_name
+            return 'inspectorObjectArray(%s)' % var_name
+
+    @staticmethod
+    def objc_protocol_import_expression_for_member(name, declaration, member):
+        if isinstance(member.type, EnumType):
+            if member.type.is_anonymous:
+                return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_anonymous_enum_member(declaration, member), name)
+            return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_non_anonymous_enum(member.type), name)
+        return ObjCGenerator.objc_protocol_import_expression_for_variable(member.type, name)
+
+    @staticmethod
+    def objc_protocol_import_expression_for_parameter(name, domain, event_or_command_name, parameter):
+        if isinstance(parameter.type, EnumType):
+            if parameter.type.is_anonymous:
+                return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter), name)
+            return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_non_anonymous_enum(parameter.type), name)
+        return ObjCGenerator.objc_protocol_import_expression_for_variable(parameter.type, name)
+
+    @staticmethod
+    def objc_protocol_import_expression_for_variable(var_type, var_name):
+        category = ObjCTypeCategory.category_for_type(var_type)
+        if category in [ObjCTypeCategory.Simple, ObjCTypeCategory.String]:
+            return var_name
+        if category is ObjCTypeCategory.Object:
+            objc_class = ObjCGenerator.objc_class_for_type(var_type)
+            return '[[[%s alloc] initWithInspectorObject:%s] autorelease]' % (objc_class, var_name)
+        if category is ObjCTypeCategory.Array:
+            objc_class = ObjCGenerator.objc_class_for_type(var_type.element_type)
+            if objc_class is 'NSString':
+                return 'objcStringArray(%s)' % var_name
+            if objc_class is 'NSNumber':  # FIXME: Integer or Double?
+                return 'objcIntegerArray(%s)' % var_name
+            return 'objcArray<%s>(%s)' % (objc_class, var_name)
+
+    # ObjC <-> JSON object conversion for types getters/setters.
+    #   - convert a member setter from ObjC API to JSON object setter
+    #   - convert a member getter from JSON object to ObjC API
+
+    @staticmethod
+    def objc_to_protocol_expression_for_member(declaration, member, sub_expression):
+        category = ObjCTypeCategory.category_for_type(member.type)
+        if category in [ObjCTypeCategory.Simple, ObjCTypeCategory.String]:
+            if isinstance(member.type, EnumType):
+                return 'toProtocolString(%s)' % sub_expression
+            return sub_expression
+        if category is ObjCTypeCategory.Object:
+            return sub_expression
+        if category is ObjCTypeCategory.Array:
+            objc_class = ObjCGenerator.objc_class_for_type(member.type.element_type)
+            if objc_class is 'NSString':
+                return 'inspectorStringArray(%s)' % sub_expression
+            if objc_class is 'NSNumber':
+                protocol_type = ObjCGenerator.protocol_type_for_type(member.type.element_type)
+                if protocol_type is 'double':
+                    return 'inspectorDoubleArray(%s)' % sub_expression
+                return 'inspectorIntegerArray(%s)' % sub_expression
+            return 'inspectorObjectArray(%s)' % sub_expression
+
+    @staticmethod
+    def protocol_to_objc_expression_for_member(declaration, member, sub_expression):
+        category = ObjCTypeCategory.category_for_type(member.type)
+        if category in [ObjCTypeCategory.Simple, ObjCTypeCategory.String]:
+            if isinstance(member.type, EnumType):
+                if member.type.is_anonymous:
+                    return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_anonymous_enum_member(declaration, member), sub_expression)
+                return 'fromProtocolString<%s>(%s)' % (ObjCGenerator.objc_enum_name_for_non_anonymous_enum(member.type), sub_expression)
+            return sub_expression
+        if category is ObjCTypeCategory.Object:
+            objc_type = ObjCGenerator.objc_type_for_member(declaration, member)
+            return '(%s)%s' % (objc_type, sub_expression)
+        if category is ObjCTypeCategory.Array:
+            protocol_type = ObjCGenerator.protocol_type_for_type(member.type.element_type)
+            objc_class = ObjCGenerator.objc_class_for_type(member.type.element_type)
+            if objc_class is 'NSString':
+                return 'objcStringArray(%s)' % sub_expression
+            if objc_class is 'NSNumber':
+                protocol_type = ObjCGenerator.protocol_type_for_type(member.type.element_type)
+                if protocol_type is 'double':
+                    return 'objcDoubleArray(%s)' % sub_expression
+                return 'objcIntegerArray(%s)' % sub_expression
+            return 'objcArray<%s>(%s)' % (objc_class, sub_expression)
+
+    # JSON object setter/getter selectors for types.
+
+    @staticmethod
+    def objc_setter_method_for_member(declaration, member):
+        return ObjCGenerator.objc_setter_method_for_member_internal(member.type, declaration, member)
+
+    @staticmethod
+    def objc_setter_method_for_member_internal(_type, declaration, member):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            raw_name = _type.raw_name()
+            if raw_name is 'boolean':
+                return 'setBool'
+            if raw_name is 'integer':
+                return 'setInteger'
+            if raw_name is 'number':
+                return 'setDouble'
+            if raw_name is 'string':
+                return 'setString'
+            if raw_name in ['any', 'object']:
+                return 'setObject'
+            if raw_name is 'array':
+                return 'setInspectorArray'
+            return None
+        if (isinstance(_type, EnumType)):
+            return 'setString'
+        if (isinstance(_type, ObjectType)):
+            return 'setObject'
+        if (isinstance(_type, ArrayType)):
+            return 'setInspectorArray'
+        return None
+
+    @staticmethod
+    def objc_getter_method_for_member(declaration, member):
+        return ObjCGenerator.objc_getter_method_for_member_internal(member.type, declaration, member)
+
+    @staticmethod
+    def objc_getter_method_for_member_internal(_type, declaration, member):
+        if (isinstance(_type, AliasedType)):
+            _type = _type.aliased_type
+        if (isinstance(_type, PrimitiveType)):
+            raw_name = _type.raw_name()
+            if raw_name is 'boolean':
+                return 'boolForKey'
+            if raw_name is 'integer':
+                return 'integerForKey'
+            if raw_name is 'number':
+                return 'doubleForKey'
+            if raw_name is 'string':
+                return 'stringForKey'
+            if raw_name in ['any', 'object']:
+                return 'objectForKey'
+            if raw_name is 'array':
+                return 'inspectorArrayForKey'
+            return None
+        if (isinstance(_type, EnumType)):
+            return 'stringForKey'
+        if (isinstance(_type, ObjectType)):
+            return 'objectForKey'
+        if (isinstance(_type, ArrayType)):
+            return 'inspectorArrayForKey'
+        return None
diff --git a/inspector/scripts/codegen/objc_generator_templates.py b/inspector/scripts/codegen/objc_generator_templates.py
new file mode 100755 (executable)
index 0000000..ef712b8
--- /dev/null
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Generator templates, which can be filled with string.Template.
+# Following are classes that fill the templates from the typechecked model.
+
+class ObjCGeneratorTemplates:
+
+    HeaderPrelude = (
+    """#import <Foundation/Foundation.h>
+
+${includes}
+""")
+
+    HeaderPostlude = (
+    """""")
+
+    ConversionHelpersPrelude = (
+    """${includes}
+
+namespace Inspector {""")
+
+    ConversionHelpersPostlude = (
+    """} // namespace Inspector
+""")
+
+    GenericHeaderPrelude = (
+    """${includes}""")
+
+    GenericHeaderPostlude = (
+    """""")
+
+    ConversionHelpersStandard = (
+    """template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);""")
+
+    BackendDispatcherHeaderPrelude = (
+    """${includes}
+
+${forwardDeclarations}
+
+namespace Inspector {
+""")
+
+    BackendDispatcherHeaderPostlude = (
+    """} // namespace Inspector
+""")
+
+    BackendDispatcherImplementationPrelude = (
+    """#import "config.h"
+#import ${primaryInclude}
+
+${secondaryIncludes}
+
+namespace Inspector {""")
+
+    BackendDispatcherImplementationPostlude = (
+    """} // namespace Inspector
+""")
+
+    ImplementationPrelude = (
+    """#import "config.h"
+#import ${primaryInclude}
+
+${secondaryIncludes}
+
+using namespace Inspector;""")
+
+    ImplementationPostlude = (
+    """""")
+
+    BackendDispatcherHeaderDomainHandlerInterfaceDeclaration = (
+    """class Alternate${domainName}BackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~Alternate${domainName}BackendDispatcher() { }
+${commandDeclarations}
+};""")
+
+    BackendDispatcherHeaderDomainHandlerObjCDeclaration = (
+    """class ObjCInspector${domainName}BackendDispatcher final : public Alternate${domainName}BackendDispatcher {
+public:
+    ObjCInspector${domainName}BackendDispatcher(id<${objcPrefix}${domainName}DomainHandler> handler) { m_delegate = handler; }
+${commandDeclarations}
+private:
+    RetainPtr<id<${objcPrefix}${domainName}DomainHandler>> m_delegate;
+};""")
+
+    BackendDispatcherHeaderDomainHandlerImplementation = (
+    """void ObjCInspector${domainName}BackendDispatcher::${commandName}(${parameters})
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+${successCallback}
+${conversions}
+${invocation}
+}
+""")
+
+    ConfigurationCommandProperty = (
+    """@property (nonatomic, retain, setter=set${domainName}Handler:) id<${objcPrefix}${domainName}DomainHandler> ${variableNamePrefix}Handler;""")
+
+    ConfigurationEventProperty = (
+    """@property (nonatomic, readonly) ${objcPrefix}${domainName}DomainEventDispatcher *${variableNamePrefix}EventDispatcher;""")
+
+    ConfigurationCommandPropertyImplementation = (
+    """- (void)set${domainName}Handler:(id<${objcPrefix}${domainName}DomainHandler>)handler
+{
+    if (handler == _${variableNamePrefix}Handler)
+        return;
+
+    [_${variableNamePrefix}Handler release];
+    _${variableNamePrefix}Handler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspector${domainName}BackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<${domainName}BackendDispatcher, Alternate${domainName}BackendDispatcher>>(ASCIILiteral("${domainName}"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<${objcPrefix}${domainName}DomainHandler>)${variableNamePrefix}Handler
+{
+    return _${variableNamePrefix}Handler;
+}""")
+
+    ConfigurationGetterImplementation = (
+    """- (${objcPrefix}${domainName}DomainEventDispatcher *)${variableNamePrefix}EventDispatcher
+{
+    if (!_${variableNamePrefix}EventDispatcher)
+        _${variableNamePrefix}EventDispatcher = [[${objcPrefix}${domainName}DomainEventDispatcher alloc] initWithController:_controller];
+    return _${variableNamePrefix}EventDispatcher;
+}""")
diff --git a/inspector/scripts/generate-inspector-protocol-bindings.py b/inspector/scripts/generate-inspector-protocol-bindings.py
new file mode 100755 (executable)
index 0000000..a1987aa
--- /dev/null
@@ -0,0 +1,211 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Apple Inc. All rights reserved.
+# Copyright (c) 2014 University of Washington. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script generates JS, Objective C, and C++ bindings for the inspector protocol.
+# Generators for individual files are located in the codegen/ directory.
+
+import os.path
+import re
+import sys
+import string
+from string import Template
+import optparse
+import logging
+
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR)
+log = logging.getLogger('global')
+
+try:
+    from codegen import *
+
+# When copying generator files to JavaScriptCore's private headers on Mac,
+# the codegen/ module directory is flattened. So, import directly.
+except ImportError, e:
+    # log.error(e) # Uncomment this to debug early import errors.
+    import models
+    from models import *
+    from generator import *
+    from cpp_generator import *
+    from objc_generator import *
+
+    from generate_cpp_alternate_backend_dispatcher_header import *
+    from generate_cpp_backend_dispatcher_header import *
+    from generate_cpp_backend_dispatcher_implementation import *
+    from generate_cpp_frontend_dispatcher_header import *
+    from generate_cpp_frontend_dispatcher_implementation import *
+    from generate_cpp_protocol_types_header import *
+    from generate_cpp_protocol_types_implementation import *
+    from generate_js_backend_commands import *
+    from generate_objc_backend_dispatcher_header import *
+    from generate_objc_backend_dispatcher_implementation import *
+    from generate_objc_configuration_header import *
+    from generate_objc_configuration_implementation import *
+    from generate_objc_conversion_helpers import *
+    from generate_objc_frontend_dispatcher_implementation import *
+    from generate_objc_header import *
+    from generate_objc_internal_header import *
+    from generate_objc_protocol_types_implementation import *
+
+
+# A writer that only updates file if it actually changed.
+class IncrementalFileWriter:
+    def __init__(self, filepath, force_output):
+        self._filepath = filepath
+        self._output = ""
+        self.force_output = force_output
+
+    def write(self, text):
+        self._output += text
+
+    def close(self):
+        text_changed = True
+        self._output = self._output.rstrip() + "\n"
+
+        try:
+            if self.force_output:
+                raise
+
+            read_file = open(self._filepath, "r")
+            old_text = read_file.read()
+            read_file.close()
+            text_changed = old_text != self._output
+        except:
+            # Ignore, just overwrite by default
+            pass
+
+        if text_changed or self.force_output:
+            out_file = open(self._filepath, "w")
+            out_file.write(self._output)
+            out_file.close()
+
+
+def generate_from_specification(primary_specification_filepath=None,
+                                supplemental_specification_filepaths=[],
+                                concatenate_output=False,
+                                output_dirpath=None,
+                                force_output=False,
+                                framework_name=""):
+
+    def load_specification(protocol, filepath, isSupplemental=False):
+        try:
+            with open(filepath, "r") as input_file:
+                parsed_json = json.load(input_file)
+                protocol.parse_specification(parsed_json, isSupplemental)
+        except ValueError as e:
+            raise Exception("Error parsing valid JSON in file: " + filepath)
+
+    protocol = models.Protocol(framework_name)
+    for specification in supplemental_specification_filepaths:
+        load_specification(protocol, specification, isSupplemental=True)
+    load_specification(protocol, primary_specification_filepath, isSupplemental=False)
+
+    protocol.resolve_types()
+
+    generators = []
+    is_test = protocol.framework is Frameworks.Test
+    if is_test or protocol.framework is not Frameworks.WebInspector:
+        generators.append(CppAlternateBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(JSBackendCommandsGenerator(protocol, primary_specification_filepath))
+        generators.append(CppBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(CppBackendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(CppFrontendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(CppFrontendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(CppProtocolTypesHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(CppProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+    if is_test or protocol.framework is Frameworks.WebInspector:
+        generators.append(ObjCBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCBackendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCConfigurationHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCConfigurationImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCConversionHelpersGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCFrontendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCInternalHeaderGenerator(protocol, primary_specification_filepath))
+
+    single_output_file_contents = []
+
+    for generator in generators:
+        output = generator.generate_output()
+        if concatenate_output:
+            single_output_file_contents.append('### Begin File: %s' % generator.output_filename())
+            single_output_file_contents.append(output)
+            single_output_file_contents.append('### End File: %s' % generator.output_filename())
+            single_output_file_contents.append('')
+        else:
+            output_file = IncrementalFileWriter(os.path.join(output_dirpath, generator.output_filename()), force_output)
+            output_file.write(output)
+            output_file.close()
+
+    if concatenate_output:
+        filename = os.path.join(os.path.basename(primary_specification_filepath) + '-result')
+        output_file = IncrementalFileWriter(os.path.join(output_dirpath, filename), force_output)
+        output_file.write('\n'.join(single_output_file_contents))
+        output_file.close()
+
+
+if __name__ == '__main__':
+    allowed_framework_names = ['JavaScriptCore', 'WebInspector', 'Test']
+    cli_parser = optparse.OptionParser(usage="usage: %prog [options] PrimaryProtocol.json [SupplementalProtocol.json ...]")
+    cli_parser.add_option("-o", "--outputDir", help="Directory where generated files should be written.")
+    cli_parser.add_option("--framework", type="choice", choices=allowed_framework_names, help="The framework that the primary specification belongs to.")
+    cli_parser.add_option("--force", action="store_true", help="Force output of generated scripts, even if nothing changed.")
+    cli_parser.add_option("-v", "--debug", action="store_true", help="Log extra output for debugging the generator itself.")
+    cli_parser.add_option("-t", "--test", action="store_true", help="Enable test mode. Use unique output filenames created by prepending the input filename.")
+
+    options = None
+
+    arg_options, arg_values = cli_parser.parse_args()
+    if (len(arg_values) < 1):
+        raise ParseException("At least one plain argument expected")
+
+    if not arg_options.outputDir:
+        raise ParseException("Missing output directory")
+
+    if arg_options.debug:
+        log.setLevel(logging.DEBUG)
+
+    options = {
+        'primary_specification_filepath': arg_values[0],
+        'supplemental_specification_filepaths': arg_values[1:],
+        'output_dirpath': arg_options.outputDir,
+        'concatenate_output': arg_options.test,
+        'framework_name': arg_options.framework,
+        'force_output': arg_options.force
+    }
+
+    try:
+        generate_from_specification(**options)
+    except (ParseException, TypecheckException) as e:
+        if arg_options.test:
+            log.error(e.message)
+        else:
+            raise  # Force the build to fail.
diff --git a/inspector/scripts/tests/commands-with-async-attribute.json b/inspector/scripts/tests/commands-with-async-attribute.json
new file mode 100644 (file)
index 0000000..11262e8
--- /dev/null
@@ -0,0 +1,109 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "DatabaseId",
+            "type": "integer",
+            "description": "Unique identifier of Database object."
+        },
+        {
+            "id": "PrimaryColors",
+            "type": "string",
+            "enum": ["red", "green", "blue"]
+        },
+        {
+            "id": "ColorList",
+            "type": "array",
+            "items": { "$ref": "PrimaryColors" }
+        },
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "executeSQLSyncOptionalReturnValues",
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "query", "type": "string" }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "databaseId", "$ref": "DatabaseId", "optional": true },
+                { "name": "sqlError", "$ref": "Error", "optional": true },
+                { "name": "screenColor", "$ref": "PrimaryColors", "optional": true },
+                { "name": "alternateColors", "$ref": "ColorList", "optional": true },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"], "optional": true }
+            ]
+        },
+        {
+            "name": "executeSQLAsyncOptionalReturnValues",
+            "async": true,
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "query", "type": "string" }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "databaseId", "$ref": "DatabaseId", "optional": true },
+                { "name": "sqlError", "$ref": "Error", "optional": true },
+                { "name": "screenColor", "$ref": "PrimaryColors", "optional": true },
+                { "name": "alternateColors", "$ref": "ColorList", "optional": true },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"], "optional": true }
+            ]
+        },
+        {
+            "name": "executeSQLSync",
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "query", "type": "string" }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "sqlError", "$ref": "Error" },
+                { "name": "alternateColors", "$ref": "ColorList" },
+                { "name": "screenColor", "$ref": "PrimaryColors" },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"] }
+            ]
+        },
+        {
+            "name": "executeSQLAsync",
+            "async": true,
+            "parameters": [
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "query", "type": "string" }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "sqlError", "$ref": "Error" },
+                { "name": "screenColor", "$ref": "PrimaryColors" },
+                { "name": "alternateColors", "$ref": "ColorList" },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"] }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/commands-with-optional-call-return-parameters.json b/inspector/scripts/tests/commands-with-optional-call-return-parameters.json
new file mode 100644 (file)
index 0000000..361d57d
--- /dev/null
@@ -0,0 +1,85 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "DatabaseId",
+            "type": "integer",
+            "description": "Unique identifier of Database object."
+        },
+        {
+            "id": "PrimaryColors",
+            "type": "string",
+            "enum": ["red", "green", "blue"]
+        },
+        {
+            "id": "ColorList",
+            "type": "array",
+            "items": { "$ref": "PrimaryColors" }
+        },
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "executeAllOptionalParameters",
+            "parameters": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "databaseId", "$ref": "DatabaseId", "optional": true },
+                { "name": "sqlError", "$ref": "Error", "optional": true },
+                { "name": "screenColor", "$ref": "PrimaryColors", "optional": true },
+                { "name": "alternateColors", "$ref": "ColorList", "optional": true },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"], "optional": true }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "databaseId", "$ref": "DatabaseId", "optional": true },
+                { "name": "sqlError", "$ref": "Error", "optional": true },
+                { "name": "screenColor", "$ref": "PrimaryColors", "optional": true },
+                { "name": "alternateColors", "$ref": "ColorList", "optional": true },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"], "optional": true }
+            ]
+        },
+        {
+            "name": "executeNoOptionalParameters",
+            "parameters": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "sqlError", "$ref": "Error" },
+                { "name": "screenColor", "$ref": "PrimaryColors" },
+                { "name": "alternateColors", "$ref": "ColorList" },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"] }
+            ],
+            "returns": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "databaseId", "$ref": "DatabaseId" },
+                { "name": "sqlError", "$ref": "Error" },
+                { "name": "screenColor", "$ref": "PrimaryColors" },
+                { "name": "alternateColors", "$ref": "ColorList" },
+                { "name": "printColor", "type": "string", "enum": ["cyan", "magenta", "yellow", "black"] }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/domains-with-varying-command-sizes.json b/inspector/scripts/tests/domains-with-varying-command-sizes.json
new file mode 100644 (file)
index 0000000..94a8ecb
--- /dev/null
@@ -0,0 +1,54 @@
+[
+{
+    "domain": "Network1",
+    "commands": [
+        {
+            "name": "loadResource1",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        }
+    ]
+},
+{
+    "domain": "Network2",
+    "types": [
+        {
+            "id": "LoaderId",
+            "type": "string",
+            "description": "Unique loader identifier."
+        }
+    ]
+},
+{
+    "domain": "Network3",
+    "commands": [
+        {
+            "name": "loadResource1",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource2",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource3",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource4",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource5",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource6",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        },
+        {
+            "name": "loadResource7",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/enum-values.json b/inspector/scripts/tests/enum-values.json
new file mode 100644 (file)
index 0000000..cdad61d
--- /dev/null
@@ -0,0 +1,35 @@
+{"domains":[
+{
+    "domain": "TypeDomain",
+    "types": [
+        {
+            "id": "TypeDomainEnum",
+            "type": "string",
+            "enum": ["shared", "red", "green", "blue"]
+        }
+    ]
+},
+{
+    "domain": "CommandDomain",
+    "commands": [
+        {
+            "name": "commandWithEnumReturnValue",
+            "parameters": [],
+            "returns": [
+                { "name": "returnValue", "type": "string", "enum": ["shared", "cyan", "magenta", "yellow"] }
+            ]
+        }
+    ]
+},
+{
+    "domain": "EventDomain",
+    "events": [
+        {
+            "name": "eventWithEnumParameter",
+            "parameters": [
+                { "name": "parameter", "type": "string", "enum": ["shared", "black", "white"] }
+            ]
+        }
+    ]
+}
+]}
diff --git a/inspector/scripts/tests/events-with-optional-parameters.json b/inspector/scripts/tests/events-with-optional-parameters.json
new file mode 100644 (file)
index 0000000..cabbf10
--- /dev/null
@@ -0,0 +1,59 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "DatabaseId",
+            "type": "string",
+            "description": "Unique identifier of Database object."
+        },
+        {
+            "id": "PrimaryColors",
+            "type": "string",
+            "values": ["red", "green", "blue"]
+        },
+        {
+            "id": "ColorList",
+            "type": "array",
+            "items": { "$ref": "PrimaryColors" }
+        },
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "didExecuteOptionalParameters",
+            "parameters": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "sqlError", "$ref": "Error", "optional": true },
+                { "name": "screenColor", "$ref": "PrimaryColors", "optional": true },
+                { "name": "alternateColors", "$ref": "ColorList", "optional": true },
+                { "name": "printColor", "type": "string", "values": ["cyan", "magenta", "yellow", "black"], "optional": true }
+            ]
+        },
+        {
+            "name": "didExecuteNoOptionalParameters",
+            "parameters": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "sqlError", "$ref": "Error" },
+                { "name": "screenColor", "$ref": "PrimaryColors" },
+                { "name": "alternateColors", "$ref": "ColorList" },
+                { "name": "printColor", "type": "string", "values": ["cyan", "magenta", "yellow", "black"] }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/expected/commands-with-async-attribute.json-result b/inspector/scripts/tests/expected/commands-with-async-attribute.json-result
new file mode 100644 (file)
index 0000000..15d6a4d
--- /dev/null
@@ -0,0 +1,1637 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+class AlternateDatabaseBackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateDatabaseBackendDispatcher() { }
+    virtual void executeSQLSyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) = 0;
+    virtual void executeSQLAsyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) = 0;
+    virtual void executeSQLSync(long callId, int in_databaseId, const String& in_query) = 0;
+    virtual void executeSQLAsync(long callId, int in_databaseId, const String& in_query) = 0;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Database.
+InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
+InspectorBackend.registerEnum("Database.PrimaryColors", {Red: "red", Green: "green", Blue: "blue"});
+InspectorBackend.registerCommand("Database.executeSQLSyncOptionalReturnValues", [{"name": "databaseId", "type": "number", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.registerCommand("Database.executeSQLAsyncOptionalReturnValues", [{"name": "databaseId", "type": "number", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.registerCommand("Database.executeSQLSync", [{"name": "databaseId", "type": "number", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "alternateColors", "screenColor", "printColor"]);
+InspectorBackend.registerCommand("Database.executeSQLAsync", [{"name": "databaseId", "type": "number", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.activateDomain("Database");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+class AlternateDatabaseBackendDispatcher;
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+class DatabaseBackendDispatcherHandler {
+public:
+    // Named after parameter 'screenColor' while generating command/event executeSQLSyncOptionalReturnValues.
+    enum class ScreenColor {
+        Red = 0,
+        Green = 1,
+        Blue = 2,
+    }; // enum class ScreenColor
+    // Named after parameter 'printColor' while generating command/event executeSQLSyncOptionalReturnValues.
+    enum class PrintColor {
+        Cyan = 3,
+        Magenta = 4,
+        Yellow = 5,
+        Black = 6,
+    }; // enum class PrintColor
+    virtual void executeSQLSyncOptionalReturnValues(ErrorString&, int in_databaseId, const String& in_query, RefPtr<Inspector::Protocol::Array<String>>& opt_out_columnNames, Inspector::Protocol::OptOutput<String>* opt_out_notes, Inspector::Protocol::OptOutput<double>* opt_out_timestamp, Inspector::Protocol::OptOutput<Inspector::InspectorObject>* opt_out_values, Inspector::Protocol::OptOutput<Inspector::InspectorValue>* opt_out_payload, Inspector::Protocol::OptOutput<int>* opt_out_databaseId, RefPtr<Inspector::Protocol::Database::Error>& opt_out_sqlError, Inspector::Protocol::Database::PrimaryColors* opt_out_screenColor, RefPtr<Inspector::Protocol::Database::ColorList>& opt_out_alternateColors, DatabaseBackendDispatcherHandler::PrintColor* opt_out_printColor) = 0;
+    class ExecuteSQLAsyncOptionalReturnValuesCallback : public BackendDispatcher::CallbackBase {
+    public:
+        ExecuteSQLAsyncOptionalReturnValuesCallback(Ref<BackendDispatcher>&&, int id);
+        void sendSuccess(RefPtr<Inspector::Protocol::Array<String>>&& columnNames, Inspector::Protocol::OptOutput<String>* notes, Inspector::Protocol::OptOutput<double>* timestamp, Inspector::Protocol::OptOutput<Inspector::InspectorObject>* values, Inspector::Protocol::OptOutput<Inspector::InspectorValue>* payload, Inspector::Protocol::OptOutput<int>* databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, Inspector::Protocol::OptOutput<String>* screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, Inspector::Protocol::OptOutput<String>* printColor);
+    };
+    virtual void executeSQLAsyncOptionalReturnValues(ErrorString&, int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncOptionalReturnValuesCallback>&& callback) = 0;
+    virtual void executeSQLSync(ErrorString&, int in_databaseId, const String& in_query, RefPtr<Inspector::Protocol::Array<String>>& out_columnNames, String* out_notes, double* out_timestamp, Inspector::InspectorObject* out_values, Inspector::InspectorValue* out_payload, int* out_databaseId, RefPtr<Inspector::Protocol::Database::Error>& out_sqlError, RefPtr<Inspector::Protocol::Database::ColorList>& out_alternateColors, Inspector::Protocol::Database::PrimaryColors* out_screenColor, DatabaseBackendDispatcherHandler::PrintColor* out_printColor) = 0;
+    class ExecuteSQLAsyncCallback : public BackendDispatcher::CallbackBase {
+    public:
+        ExecuteSQLAsyncCallback(Ref<BackendDispatcher>&&, int id);
+        void sendSuccess(RefPtr<Inspector::Protocol::Array<String>>&& columnNames, const String& notes, double timestamp, Inspector::InspectorObject values, Inspector::InspectorValue payload, int databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, const String& screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, const String& printColor);
+    };
+    virtual void executeSQLAsync(ErrorString&, int in_databaseId, const String& in_query, Ref<ExecuteSQLAsyncCallback>&& callback) = 0;
+protected:
+    virtual ~DatabaseBackendDispatcherHandler();
+};
+
+class DatabaseBackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<DatabaseBackendDispatcher> create(BackendDispatcher*, DatabaseBackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void executeSQLSyncOptionalReturnValues(long callId, const InspectorObject& message);
+    void executeSQLAsyncOptionalReturnValues(long callId, const InspectorObject& message);
+    void executeSQLSync(long callId, const InspectorObject& message);
+    void executeSQLAsync(long callId, const InspectorObject& message);
+private:
+    DatabaseBackendDispatcher(BackendDispatcher&, DatabaseBackendDispatcherHandler*);
+    DatabaseBackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateDatabaseBackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateDatabaseBackendDispatcher* m_alternateDispatcher;
+#endif
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+DatabaseBackendDispatcherHandler::~DatabaseBackendDispatcherHandler() { }
+
+Ref<DatabaseBackendDispatcher> DatabaseBackendDispatcher::create(BackendDispatcher* backendDispatcher, DatabaseBackendDispatcherHandler* agent)
+{
+    return adoptRef(*new DatabaseBackendDispatcher(*backendDispatcher, agent));
+}
+
+DatabaseBackendDispatcher::DatabaseBackendDispatcher(BackendDispatcher& backendDispatcher, DatabaseBackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Database"), this);
+}
+
+void DatabaseBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<DatabaseBackendDispatcher> protect(*this);
+
+    if (method == "executeSQLSyncOptionalReturnValues")
+        executeSQLSyncOptionalReturnValues(callId, message);
+    else if (method == "executeSQLAsyncOptionalReturnValues")
+        executeSQLAsyncOptionalReturnValues(callId, message);
+    else if (method == "executeSQLSync")
+        executeSQLSync(callId, message);
+    else if (method == "executeSQLAsync")
+        executeSQLAsync(callId, message);
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
+}
+
+void DatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
+    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSyncOptionalReturnValues");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeSQLSyncOptionalReturnValues(callId, in_databaseId, in_query);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    RefPtr<Inspector::Protocol::Array<String>> out_columnNames;
+    Inspector::Protocol::OptOutput<String> out_notes;
+    Inspector::Protocol::OptOutput<double> out_timestamp;
+    Inspector::Protocol::OptOutput<Inspector::InspectorObject> out_values;
+    Inspector::Protocol::OptOutput<Inspector::InspectorValue> out_payload;
+    Inspector::Protocol::OptOutput<Inspector::Protocol::Database::DatabaseId> out_databaseId;
+    RefPtr<Inspector::Protocol::Database::Error> out_sqlError;
+    Inspector::Protocol::Database::PrimaryColors out_screenColor;
+    RefPtr<Inspector::Protocol::Database::ColorList> out_alternateColors;
+    DatabaseBackendDispatcherHandler::PrintColor out_printColor;
+    m_agent->executeSQLSyncOptionalReturnValues(error, in_databaseId, in_query, out_columnNames, &out_notes, &out_timestamp, out_values, &out_payload, &out_databaseId, out_sqlError, &out_screenColor, out_alternateColors, &out_printColor);
+
+    if (!error.length()) {
+        if (out_columnNames)
+            result->setArray(ASCIILiteral("columnNames"), out_columnNames);
+        if (out_notes.isAssigned())
+            result->setString(ASCIILiteral("notes"), out_notes.getValue());
+        if (out_timestamp.isAssigned())
+            result->setDouble(ASCIILiteral("timestamp"), out_timestamp.getValue());
+        if (out_values.isAssigned())
+            result->setObject(ASCIILiteral("values"), out_values.getValue());
+        if (out_payload.isAssigned())
+            result->setValue(ASCIILiteral("payload"), out_payload.getValue());
+        if (out_databaseId.isAssigned())
+            result->setInteger(ASCIILiteral("databaseId"), out_databaseId.getValue());
+        if (out_sqlError)
+            result->setObject(ASCIILiteral("sqlError"), out_sqlError);
+        if (out_screenColor.isAssigned())
+            result->setString(ASCIILiteral("screenColor"), out_screenColor.getValue());
+        if (out_alternateColors)
+            result->setArray(ASCIILiteral("alternateColors"), out_alternateColors);
+        if (out_printColor.isAssigned())
+            result->setString(ASCIILiteral("printColor"), out_printColor.getValue());
+    }
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback::ExecuteSQLAsyncOptionalReturnValuesCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTF::move(backendDispatcher), id) { }
+
+void DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback::sendSuccess(RefPtr<Inspector::Protocol::Array<String>>&& columnNames, Inspector::Protocol::OptOutput<String>* notes, Inspector::Protocol::OptOutput<double>* timestamp, Inspector::Protocol::OptOutput<Inspector::InspectorObject>* values, Inspector::Protocol::OptOutput<Inspector::InspectorValue>* payload, Inspector::Protocol::OptOutput<int>* databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, Inspector::Protocol::OptOutput<String>* screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, Inspector::Protocol::OptOutput<String>* printColor)
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    if (columnNames)
+        jsonMessage->setArray(ASCIILiteral("columnNames"), columnNames);
+    if (notes.isAssigned())
+        jsonMessage->setString(ASCIILiteral("notes"), notes.getValue());
+    if (timestamp.isAssigned())
+        jsonMessage->setDouble(ASCIILiteral("timestamp"), timestamp.getValue());
+    if (values.isAssigned())
+        jsonMessage->setObject(ASCIILiteral("values"), values.getValue());
+    if (payload.isAssigned())
+        jsonMessage->setValue(ASCIILiteral("payload"), payload.getValue());
+    if (databaseId.isAssigned())
+        jsonMessage->setInteger(ASCIILiteral("databaseId"), databaseId.getValue());
+    if (sqlError)
+        jsonMessage->setObject(ASCIILiteral("sqlError"), sqlError);
+    if (screenColor.isAssigned())
+        jsonMessage->setString(ASCIILiteral("screenColor"), screenColor.getValue());
+    if (alternateColors)
+        jsonMessage->setArray(ASCIILiteral("alternateColors"), alternateColors);
+    if (printColor.isAssigned())
+        jsonMessage->setString(ASCIILiteral("printColor"), printColor.getValue());
+    sendIfActive(WTF::move(jsonMessage), ErrorString());
+}
+
+void DatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
+    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsyncOptionalReturnValues");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeSQLAsyncOptionalReturnValues(callId, in_databaseId, in_query);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncOptionalReturnValuesCallback(m_backendDispatcher.copyRef(), callId));
+    m_agent->executeSQLAsyncOptionalReturnValues(error, in_databaseId, in_query, callback.copyRef());
+
+    if (error.length()) {
+        callback->disable();
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);
+        return;
+    }
+}
+
+void DatabaseBackendDispatcher::executeSQLSync(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
+    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLSync");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeSQLSync(callId, in_databaseId, in_query);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    RefPtr<Inspector::Protocol::Array<String>> out_columnNames;
+    String out_notes;
+    double out_timestamp;
+    Inspector::InspectorObject out_values;
+    Inspector::InspectorValue out_payload;
+    Inspector::Protocol::Database::DatabaseId out_databaseId;
+    RefPtr<Inspector::Protocol::Database::Error> out_sqlError;
+    RefPtr<Inspector::Protocol::Database::ColorList> out_alternateColors;
+    Inspector::Protocol::Database::PrimaryColors out_screenColor;
+    DatabaseBackendDispatcherHandler::PrintColor out_printColor;
+    m_agent->executeSQLSync(error, in_databaseId, in_query, out_columnNames, &out_notes, &out_timestamp, out_values, &out_payload, &out_databaseId, out_sqlError, out_alternateColors, &out_screenColor, &out_printColor);
+
+    if (!error.length()) {
+        result->setArray(ASCIILiteral("columnNames"), out_columnNames);
+        result->setString(ASCIILiteral("notes"), out_notes);
+        result->setDouble(ASCIILiteral("timestamp"), out_timestamp);
+        result->setObject(ASCIILiteral("values"), out_values);
+        result->setValue(ASCIILiteral("payload"), out_payload);
+        result->setInteger(ASCIILiteral("databaseId"), out_databaseId);
+        result->setObject(ASCIILiteral("sqlError"), out_sqlError);
+        result->setArray(ASCIILiteral("alternateColors"), out_alternateColors);
+        result->setString(ASCIILiteral("screenColor"), Inspector::Protocol::getEnumConstantValue(out_screenColor));
+        result->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(out_printColor));
+    }
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback::ExecuteSQLAsyncCallback(Ref<BackendDispatcher>&& backendDispatcher, int id) : BackendDispatcher::CallbackBase(WTF::move(backendDispatcher), id) { }
+
+void DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback::sendSuccess(RefPtr<Inspector::Protocol::Array<String>>&& columnNames, const String& notes, double timestamp, Inspector::InspectorObject values, Inspector::InspectorValue payload, int databaseId, RefPtr<Inspector::Protocol::Database::Error>&& sqlError, const String& screenColor, RefPtr<Inspector::Protocol::Database::ColorList>&& alternateColors, const String& printColor)
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setArray(ASCIILiteral("columnNames"), columnNames);
+    jsonMessage->setString(ASCIILiteral("notes"), notes);
+    jsonMessage->setDouble(ASCIILiteral("timestamp"), timestamp);
+    jsonMessage->setObject(ASCIILiteral("values"), values);
+    jsonMessage->setValue(ASCIILiteral("payload"), payload);
+    jsonMessage->setInteger(ASCIILiteral("databaseId"), databaseId);
+    jsonMessage->setObject(ASCIILiteral("sqlError"), sqlError);
+    jsonMessage->setString(ASCIILiteral("screenColor"), Inspector::Protocol::getEnumConstantValue(screenColor));
+    jsonMessage->setArray(ASCIILiteral("alternateColors"), alternateColors);
+    jsonMessage->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(printColor));
+    sendIfActive(WTF::move(jsonMessage), ErrorString());
+}
+
+void DatabaseBackendDispatcher::executeSQLAsync(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
+    String in_query = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("query"), nullptr, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeSQLAsync");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeSQLAsync(callId, in_databaseId, in_query);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    Ref<DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback> callback = adoptRef(*new DatabaseBackendDispatcherHandler::ExecuteSQLAsyncCallback(m_backendDispatcher.copyRef(), callId));
+    m_agent->executeSQLAsync(error, in_databaseId, in_query, callback.copyRef());
+
+    if (error.length()) {
+        callback->disable();
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::ServerError, error);
+        return;
+    }
+}
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Database {
+class Error;
+enum class PrimaryColors;
+} // Database
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Database {
+/* Unique identifier of Database object. */
+typedef int DatabaseId;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Database::PrimaryColors> ColorList;
+} // Database
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Database {
+/*  */
+enum class PrimaryColors {
+    Red = 0,
+    Green = 1,
+    Blue = 2,
+}; // enum class PrimaryColors
+/* Database error. */
+class Error : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        MessageSet = 1 << 0,
+        CodeSet = 1 << 1,
+        AllFieldsSet = (MessageSet | CodeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*Error*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class Error;
+    public:
+
+        Builder<STATE | MessageSet>& setMessage(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
+            m_result->setString(ASCIILiteral("message"), value);
+            return castState<MessageSet>();
+        }
+
+        Builder<STATE | CodeSet>& setCode(int value)
+        {
+            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
+            m_result->setInteger(ASCIILiteral("code"), value);
+            return castState<CodeSet>();
+        }
+
+        Ref<Error> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(Error) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<Error>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<Error> result = Error::create()
+     *     .setMessage(...)
+     *     .setCode(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Database
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "red",
+    "green",
+    "blue",
+    "cyan",
+    "magenta",
+    "yellow",
+    "black",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+@protocol RWIProtocolDatabaseDomainHandler;
+
+namespace Inspector {
+
+
+class ObjCInspectorDatabaseBackendDispatcher final : public AlternateDatabaseBackendDispatcher {
+public:
+    ObjCInspectorDatabaseBackendDispatcher(id<RWIProtocolDatabaseDomainHandler> handler) { m_delegate = handler; }
+    virtual void executeSQLSyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLAsyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLSync(long callId, int in_databaseId, const String& in_query) override;
+    virtual void executeSQLAsync(long callId, int in_databaseId, const String& in_query) override;
+private:
+    RetainPtr<id<RWIProtocolDatabaseDomainHandler>> m_delegate;
+};
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    id<RWIProtocolDatabaseDomainHandler> _databaseHandler;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_databaseHandler release];
+    [super dealloc];
+}
+
+- (void)setDatabaseHandler:(id<RWIProtocolDatabaseDomainHandler>)handler
+{
+    if (handler == _databaseHandler)
+        return;
+
+    [_databaseHandler release];
+    _databaseHandler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorDatabaseBackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<DatabaseBackendDispatcher, AlternateDatabaseBackendDispatcher>>(ASCIILiteral("Database"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolDatabaseDomainHandler>)databaseHandler
+{
+    return _databaseHandler;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, retain, setter=setDatabaseHandler:) id<RWIProtocolDatabaseDomainHandler> databaseHandler;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor *printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(alternateColors, @"alternateColors");
+        if (columnNames)
+            resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(*columnNames));
+        if (notes)
+            resultObject->setString(ASCIILiteral("notes"), *notes);
+        if (timestamp)
+            resultObject->setDouble(ASCIILiteral("timestamp"), *timestamp);
+        if (values)
+            resultObject->setObject(ASCIILiteral("values"), [*values toInspectorObject]);
+        if (payload)
+            resultObject->setValue(ASCIILiteral("payload"), [*payload toInspectorObject]);
+        if (databaseId)
+            resultObject->setInteger(ASCIILiteral("databaseId"), *databaseId);
+        if (sqlError)
+            resultObject->setObject(ASCIILiteral("sqlError"), [*sqlError toInspectorObject]);
+        if (screenColor)
+            resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(*screenColor));
+        if (alternateColors)
+            resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
+        if (printColor)
+            resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    int o_in_databaseId = in_databaseId;
+    NSString *o_in_query = in_query;
+
+    [m_delegate executeSQLSyncOptionalReturnValuesWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
+}
+
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long callId, int in_databaseId, const String& in_query)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor *printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(alternateColors, @"alternateColors");
+        if (columnNames)
+            resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(*columnNames));
+        if (notes)
+            resultObject->setString(ASCIILiteral("notes"), *notes);
+        if (timestamp)
+            resultObject->setDouble(ASCIILiteral("timestamp"), *timestamp);
+        if (values)
+            resultObject->setObject(ASCIILiteral("values"), [*values toInspectorObject]);
+        if (payload)
+            resultObject->setValue(ASCIILiteral("payload"), [*payload toInspectorObject]);
+        if (databaseId)
+            resultObject->setInteger(ASCIILiteral("databaseId"), *databaseId);
+        if (sqlError)
+            resultObject->setObject(ASCIILiteral("sqlError"), [*sqlError toInspectorObject]);
+        if (screenColor)
+            resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(*screenColor));
+        if (alternateColors)
+            resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
+        if (printColor)
+            resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    int o_in_databaseId = in_databaseId;
+    NSString *o_in_query = in_query;
+
+    [m_delegate executeSQLAsyncOptionalReturnValuesWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
+}
+
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long callId, int in_databaseId, const String& in_query)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabasePrimaryColors screenColor, RWIProtocolDatabaseExecuteSQLSyncPrintColor printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(alternateColors, @"alternateColors");
+        resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(columnNames));
+        resultObject->setString(ASCIILiteral("notes"), notes);
+        resultObject->setDouble(ASCIILiteral("timestamp"), timestamp);
+        resultObject->setObject(ASCIILiteral("values"), [values toInspectorObject]);
+        resultObject->setValue(ASCIILiteral("payload"), [payload toInspectorObject]);
+        resultObject->setInteger(ASCIILiteral("databaseId"), databaseId);
+        resultObject->setObject(ASCIILiteral("sqlError"), [sqlError toInspectorObject]);
+        resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
+        resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
+        resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    int o_in_databaseId = in_databaseId;
+    NSString *o_in_query = in_query;
+
+    [m_delegate executeSQLSyncWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
+}
+
+void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsync(long callId, int in_databaseId, const String& in_query)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteSQLAsyncPrintColor printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(alternateColors, @"alternateColors");
+        resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(columnNames));
+        resultObject->setString(ASCIILiteral("notes"), notes);
+        resultObject->setDouble(ASCIILiteral("timestamp"), timestamp);
+        resultObject->setObject(ASCIILiteral("values"), [values toInspectorObject]);
+        resultObject->setValue(ASCIILiteral("payload"), [payload toInspectorObject]);
+        resultObject->setInteger(ASCIILiteral("databaseId"), databaseId);
+        resultObject->setObject(ASCIILiteral("sqlError"), [sqlError toInspectorObject]);
+        resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
+        resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
+        resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    int o_in_databaseId = in_databaseId;
+    NSString *o_in_query = in_query;
+
+    [m_delegate executeSQLAsyncWithErrorCallback:errorCallback successCallback:successCallback databaseId:o_in_databaseId query:o_in_query];
+}
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolDatabasePrimaryColors value)
+{
+    switch(value) {
+    case RWIProtocolDatabasePrimaryColorsRed:
+        return ASCIILiteral("red");
+    case RWIProtocolDatabasePrimaryColorsGreen:
+        return ASCIILiteral("green");
+    case RWIProtocolDatabasePrimaryColorsBlue:
+        return ASCIILiteral("blue");
+    }
+}
+
+template<>
+inline RWIProtocolDatabasePrimaryColors fromProtocolString(const String& value)
+{
+    if (value == "red")
+        return RWIProtocolDatabasePrimaryColorsRed;
+    if (value == "green")
+        return RWIProtocolDatabasePrimaryColorsGreen;
+    if (value == "blue")
+        return RWIProtocolDatabasePrimaryColorsBlue;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabasePrimaryColorsRed;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteSQLSyncPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteSQLSyncPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteSQLSyncPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteSQLSyncPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteSQLSyncPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteSQLSyncPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteSQLSyncPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteSQLSyncPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteSQLSyncPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteSQLSyncPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteSQLSyncPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteSQLAsyncPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteSQLAsyncPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteSQLAsyncPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteSQLAsyncPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteSQLAsyncPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteSQLAsyncPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteSQLAsyncPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteSQLAsyncPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteSQLAsyncPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteSQLAsyncPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteSQLAsyncPrintColorCyan;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolDatabaseError;
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabasePrimaryColors) {
+    RWIProtocolDatabasePrimaryColorsRed,
+    RWIProtocolDatabasePrimaryColorsGreen,
+    RWIProtocolDatabasePrimaryColorsBlue,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor) {
+    RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorCyan,
+    RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorMagenta,
+    RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorYellow,
+    RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor) {
+    RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorCyan,
+    RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorMagenta,
+    RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorYellow,
+    RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteSQLSyncPrintColor) {
+    RWIProtocolDatabaseExecuteSQLSyncPrintColorCyan,
+    RWIProtocolDatabaseExecuteSQLSyncPrintColorMagenta,
+    RWIProtocolDatabaseExecuteSQLSyncPrintColorYellow,
+    RWIProtocolDatabaseExecuteSQLSyncPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteSQLAsyncPrintColor) {
+    RWIProtocolDatabaseExecuteSQLAsyncPrintColorCyan,
+    RWIProtocolDatabaseExecuteSQLAsyncPrintColorMagenta,
+    RWIProtocolDatabaseExecuteSQLAsyncPrintColorYellow,
+    RWIProtocolDatabaseExecuteSQLAsyncPrintColorBlack,
+};
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseError : RWIProtocolJSONObject
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+/* required */ @property (nonatomic, copy) NSString *message;
+/* required */ @property (nonatomic, assign) int code;
+@end
+
+@protocol RWIProtocolDatabaseDomainHandler <NSObject>
+@required
+- (void)executeSQLSyncOptionalReturnValuesWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor *printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
+- (void)executeSQLAsyncOptionalReturnValuesWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor *printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
+- (void)executeSQLSyncWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabasePrimaryColors screenColor, RWIProtocolDatabaseExecuteSQLSyncPrintColor printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
+- (void)executeSQLAsyncWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteSQLAsyncPrintColor printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
+@end
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolDatabaseError
+
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");
+
+    self.message = message;
+    self.code = code;
+
+    return self;
+}
+
+- (void)setMessage:(NSString *)message
+{
+    [super setString:message forKey:@"message"];
+}
+
+- (NSString *)message
+{
+    return [super stringForKey:@"message"];
+}
+
+- (void)setCode:(int)code
+{
+    [super setInteger:code forKey:@"code"];
+}
+
+- (int)code
+{
+    return [super integerForKey:@"code"];
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-async-attribute.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result b/inspector/scripts/tests/expected/commands-with-optional-call-return-parameters.json-result
new file mode 100644 (file)
index 0000000..e349ecf
--- /dev/null
@@ -0,0 +1,1486 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+class AlternateDatabaseBackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateDatabaseBackendDispatcher() { }
+    virtual void executeAllOptionalParameters(long callId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor) = 0;
+    virtual void executeNoOptionalParameters(long callId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor) = 0;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Database.
+InspectorBackend.registerEnum("Database.PrimaryColors", {Red: "red", Green: "green", Blue: "blue"});
+InspectorBackend.registerCommand("Database.executeAllOptionalParameters", [{"name": "columnNames", "type": "object", "optional": true}, {"name": "notes", "type": "string", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}, {"name": "values", "type": "object", "optional": true}, {"name": "payload", "type": "object", "optional": true}, {"name": "databaseId", "type": "number", "optional": true}, {"name": "sqlError", "type": "object", "optional": true}, {"name": "screenColor", "type": "string", "optional": true}, {"name": "alternateColors", "type": "object", "optional": true}, {"name": "printColor", "type": "string", "optional": true}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.registerCommand("Database.executeNoOptionalParameters", [{"name": "columnNames", "type": "object", "optional": false}, {"name": "notes", "type": "string", "optional": false}, {"name": "timestamp", "type": "number", "optional": false}, {"name": "values", "type": "object", "optional": false}, {"name": "payload", "type": "object", "optional": false}, {"name": "databaseId", "type": "number", "optional": false}, {"name": "sqlError", "type": "object", "optional": false}, {"name": "screenColor", "type": "string", "optional": false}, {"name": "alternateColors", "type": "object", "optional": false}, {"name": "printColor", "type": "string", "optional": false}], ["columnNames", "notes", "timestamp", "values", "payload", "databaseId", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.activateDomain("Database");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+class AlternateDatabaseBackendDispatcher;
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+class DatabaseBackendDispatcherHandler {
+public:
+    // Named after parameter 'screenColor' while generating command/event executeAllOptionalParameters.
+    enum class ScreenColor {
+        Red = 0,
+        Green = 1,
+        Blue = 2,
+    }; // enum class ScreenColor
+    // Named after parameter 'printColor' while generating command/event executeAllOptionalParameters.
+    enum class PrintColor {
+        Cyan = 3,
+        Magenta = 4,
+        Yellow = 5,
+        Black = 6,
+    }; // enum class PrintColor
+    virtual void executeAllOptionalParameters(ErrorString&, const Inspector::InspectorArray* opt_in_columnNames, const String* opt_in_notes, const double* opt_in_timestamp, const Inspector::InspectorObject* opt_in_values, const Inspector::InspectorValue* opt_in_payload, const int* opt_in_databaseId, const Inspector::InspectorObject* opt_in_sqlError, const String* opt_in_screenColor, const Inspector::InspectorArray* opt_in_alternateColors, const String* opt_in_printColor, RefPtr<Inspector::Protocol::Array<String>>& opt_out_columnNames, Inspector::Protocol::OptOutput<String>* opt_out_notes, Inspector::Protocol::OptOutput<double>* opt_out_timestamp, Inspector::Protocol::OptOutput<Inspector::InspectorObject>* opt_out_values, Inspector::Protocol::OptOutput<Inspector::InspectorValue>* opt_out_payload, Inspector::Protocol::OptOutput<int>* opt_out_databaseId, RefPtr<Inspector::Protocol::Database::Error>& opt_out_sqlError, Inspector::Protocol::Database::PrimaryColors* opt_out_screenColor, RefPtr<Inspector::Protocol::Database::ColorList>& opt_out_alternateColors, DatabaseBackendDispatcherHandler::PrintColor* opt_out_printColor) = 0;
+    virtual void executeNoOptionalParameters(ErrorString&, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor, RefPtr<Inspector::Protocol::Array<String>>& out_columnNames, String* out_notes, double* out_timestamp, Inspector::InspectorObject* out_values, Inspector::InspectorValue* out_payload, int* out_databaseId, RefPtr<Inspector::Protocol::Database::Error>& out_sqlError, Inspector::Protocol::Database::PrimaryColors* out_screenColor, RefPtr<Inspector::Protocol::Database::ColorList>& out_alternateColors, DatabaseBackendDispatcherHandler::PrintColor* out_printColor) = 0;
+protected:
+    virtual ~DatabaseBackendDispatcherHandler();
+};
+
+class DatabaseBackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<DatabaseBackendDispatcher> create(BackendDispatcher*, DatabaseBackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void executeAllOptionalParameters(long callId, const InspectorObject& message);
+    void executeNoOptionalParameters(long callId, const InspectorObject& message);
+private:
+    DatabaseBackendDispatcher(BackendDispatcher&, DatabaseBackendDispatcherHandler*);
+    DatabaseBackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateDatabaseBackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateDatabaseBackendDispatcher* m_alternateDispatcher;
+#endif
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+DatabaseBackendDispatcherHandler::~DatabaseBackendDispatcherHandler() { }
+
+Ref<DatabaseBackendDispatcher> DatabaseBackendDispatcher::create(BackendDispatcher* backendDispatcher, DatabaseBackendDispatcherHandler* agent)
+{
+    return adoptRef(*new DatabaseBackendDispatcher(*backendDispatcher, agent));
+}
+
+DatabaseBackendDispatcher::DatabaseBackendDispatcher(BackendDispatcher& backendDispatcher, DatabaseBackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Database"), this);
+}
+
+void DatabaseBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<DatabaseBackendDispatcher> protect(*this);
+
+    if (method == "executeAllOptionalParameters")
+        executeAllOptionalParameters(callId, message);
+    else if (method == "executeNoOptionalParameters")
+        executeNoOptionalParameters(callId, message);
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Database", '.', method, "' was not found"));
+}
+
+void DatabaseBackendDispatcher::executeAllOptionalParameters(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    bool opt_in_columnNames_valueFound = false;
+    RefPtr<Inspector::InspectorArray> opt_in_columnNames = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("columnNames"), &opt_in_columnNames_valueFound, protocolErrors.get());
+    bool opt_in_notes_valueFound = false;
+    String opt_in_notes = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("notes"), &opt_in_notes_valueFound, protocolErrors.get());
+    bool opt_in_timestamp_valueFound = false;
+    Inspector::Protocol::OptOutput<double> opt_in_timestamp = BackendDispatcher::getDouble(paramsContainer.get(), ASCIILiteral("timestamp"), &opt_in_timestamp_valueFound, protocolErrors.get());
+    bool opt_in_values_valueFound = false;
+    RefPtr<Inspector::InspectorObject> opt_in_values = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("values"), &opt_in_values_valueFound, protocolErrors.get());
+    bool opt_in_payload_valueFound = false;
+    RefPtr<Inspector::InspectorValue> opt_in_payload = BackendDispatcher::getValue(paramsContainer.get(), ASCIILiteral("payload"), &opt_in_payload_valueFound, protocolErrors.get());
+    bool opt_in_databaseId_valueFound = false;
+    int opt_in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), &opt_in_databaseId_valueFound, protocolErrors.get());
+    bool opt_in_sqlError_valueFound = false;
+    RefPtr<Inspector::InspectorObject> opt_in_sqlError = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("sqlError"), &opt_in_sqlError_valueFound, protocolErrors.get());
+    bool opt_in_screenColor_valueFound = false;
+    String opt_in_screenColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("screenColor"), &opt_in_screenColor_valueFound, protocolErrors.get());
+    bool opt_in_alternateColors_valueFound = false;
+    RefPtr<Inspector::InspectorArray> opt_in_alternateColors = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("alternateColors"), &opt_in_alternateColors_valueFound, protocolErrors.get());
+    bool opt_in_printColor_valueFound = false;
+    String opt_in_printColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("printColor"), &opt_in_printColor_valueFound, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeAllOptionalParameters");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeAllOptionalParameters(callId, opt_in_columnNames_valueFound ? opt_in_columnNames.get() : nullptr, opt_in_notes_valueFound ? &opt_in_notes : nullptr, opt_in_timestamp_valueFound ? &opt_in_timestamp : nullptr, opt_in_values_valueFound ? opt_in_values.get() : nullptr, opt_in_payload_valueFound ? opt_in_payload.get() : nullptr, opt_in_databaseId_valueFound ? &opt_in_databaseId : nullptr, opt_in_sqlError_valueFound ? opt_in_sqlError.get() : nullptr, opt_in_screenColor_valueFound ? &opt_in_screenColor : nullptr, opt_in_alternateColors_valueFound ? opt_in_alternateColors.get() : nullptr, opt_in_printColor_valueFound ? &opt_in_printColor : nullptr);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    RefPtr<Inspector::Protocol::Array<String>> out_columnNames;
+    Inspector::Protocol::OptOutput<String> out_notes;
+    Inspector::Protocol::OptOutput<double> out_timestamp;
+    Inspector::Protocol::OptOutput<Inspector::InspectorObject> out_values;
+    Inspector::Protocol::OptOutput<Inspector::InspectorValue> out_payload;
+    Inspector::Protocol::OptOutput<Inspector::Protocol::Database::DatabaseId> out_databaseId;
+    RefPtr<Inspector::Protocol::Database::Error> out_sqlError;
+    Inspector::Protocol::Database::PrimaryColors out_screenColor;
+    RefPtr<Inspector::Protocol::Database::ColorList> out_alternateColors;
+    DatabaseBackendDispatcherHandler::PrintColor out_printColor;
+    m_agent->executeAllOptionalParameters(error, opt_in_columnNames_valueFound ? opt_in_columnNames.get() : nullptr, opt_in_notes_valueFound ? &opt_in_notes : nullptr, opt_in_timestamp_valueFound ? &opt_in_timestamp : nullptr, opt_in_values_valueFound ? opt_in_values.get() : nullptr, opt_in_payload_valueFound ? opt_in_payload.get() : nullptr, opt_in_databaseId_valueFound ? &opt_in_databaseId : nullptr, opt_in_sqlError_valueFound ? opt_in_sqlError.get() : nullptr, opt_in_screenColor_valueFound ? &opt_in_screenColor : nullptr, opt_in_alternateColors_valueFound ? opt_in_alternateColors.get() : nullptr, opt_in_printColor_valueFound ? &opt_in_printColor : nullptr, out_columnNames, &out_notes, &out_timestamp, out_values, &out_payload, &out_databaseId, out_sqlError, &out_screenColor, out_alternateColors, &out_printColor);
+
+    if (!error.length()) {
+        if (out_columnNames)
+            result->setArray(ASCIILiteral("columnNames"), out_columnNames);
+        if (out_notes.isAssigned())
+            result->setString(ASCIILiteral("notes"), out_notes.getValue());
+        if (out_timestamp.isAssigned())
+            result->setDouble(ASCIILiteral("timestamp"), out_timestamp.getValue());
+        if (out_values.isAssigned())
+            result->setObject(ASCIILiteral("values"), out_values.getValue());
+        if (out_payload.isAssigned())
+            result->setValue(ASCIILiteral("payload"), out_payload.getValue());
+        if (out_databaseId.isAssigned())
+            result->setInteger(ASCIILiteral("databaseId"), out_databaseId.getValue());
+        if (out_sqlError)
+            result->setObject(ASCIILiteral("sqlError"), out_sqlError);
+        if (out_screenColor.isAssigned())
+            result->setString(ASCIILiteral("screenColor"), out_screenColor.getValue());
+        if (out_alternateColors)
+            result->setArray(ASCIILiteral("alternateColors"), out_alternateColors);
+        if (out_printColor.isAssigned())
+            result->setString(ASCIILiteral("printColor"), out_printColor.getValue());
+    }
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void DatabaseBackendDispatcher::executeNoOptionalParameters(long callId, const InspectorObject& message)
+{
+    auto protocolErrors = Inspector::Protocol::Array<String>::create();
+    RefPtr<InspectorObject> paramsContainer;
+    message.getObject(ASCIILiteral("params"), paramsContainer);
+    RefPtr<Inspector::InspectorArray> in_columnNames = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("columnNames"), nullptr, protocolErrors.get());
+    String in_notes = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("notes"), nullptr, protocolErrors.get());
+    double in_timestamp = BackendDispatcher::getDouble(paramsContainer.get(), ASCIILiteral("timestamp"), nullptr, protocolErrors.get());
+    RefPtr<Inspector::InspectorObject> in_values = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("values"), nullptr, protocolErrors.get());
+    RefPtr<Inspector::InspectorValue> in_payload = BackendDispatcher::getValue(paramsContainer.get(), ASCIILiteral("payload"), nullptr, protocolErrors.get());
+    int in_databaseId = BackendDispatcher::getInteger(paramsContainer.get(), ASCIILiteral("databaseId"), nullptr, protocolErrors.get());
+    RefPtr<Inspector::InspectorObject> in_sqlError = BackendDispatcher::getObject(paramsContainer.get(), ASCIILiteral("sqlError"), nullptr, protocolErrors.get());
+    String in_screenColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("screenColor"), nullptr, protocolErrors.get());
+    RefPtr<Inspector::InspectorArray> in_alternateColors = BackendDispatcher::getArray(paramsContainer.get(), ASCIILiteral("alternateColors"), nullptr, protocolErrors.get());
+    String in_printColor = BackendDispatcher::getString(paramsContainer.get(), ASCIILiteral("printColor"), nullptr, protocolErrors.get());
+    if (protocolErrors->length()) {
+        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Database.executeNoOptionalParameters");
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::InvalidParams, errorMessage, WTF::move(protocolErrors));
+        return;
+    }
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->executeNoOptionalParameters(callId, *in_columnNames, in_notes, in_timestamp, *in_values, *in_payload, in_databaseId, *in_sqlError, in_screenColor, *in_alternateColors, in_printColor);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    RefPtr<Inspector::Protocol::Array<String>> out_columnNames;
+    String out_notes;
+    double out_timestamp;
+    Inspector::InspectorObject out_values;
+    Inspector::InspectorValue out_payload;
+    Inspector::Protocol::Database::DatabaseId out_databaseId;
+    RefPtr<Inspector::Protocol::Database::Error> out_sqlError;
+    Inspector::Protocol::Database::PrimaryColors out_screenColor;
+    RefPtr<Inspector::Protocol::Database::ColorList> out_alternateColors;
+    DatabaseBackendDispatcherHandler::PrintColor out_printColor;
+    m_agent->executeNoOptionalParameters(error, *in_columnNames, in_notes, in_timestamp, *in_values, *in_payload, in_databaseId, *in_sqlError, in_screenColor, *in_alternateColors, in_printColor, out_columnNames, &out_notes, &out_timestamp, out_values, &out_payload, &out_databaseId, out_sqlError, &out_screenColor, out_alternateColors, &out_printColor);
+
+    if (!error.length()) {
+        result->setArray(ASCIILiteral("columnNames"), out_columnNames);
+        result->setString(ASCIILiteral("notes"), out_notes);
+        result->setDouble(ASCIILiteral("timestamp"), out_timestamp);
+        result->setObject(ASCIILiteral("values"), out_values);
+        result->setValue(ASCIILiteral("payload"), out_payload);
+        result->setInteger(ASCIILiteral("databaseId"), out_databaseId);
+        result->setObject(ASCIILiteral("sqlError"), out_sqlError);
+        result->setString(ASCIILiteral("screenColor"), Inspector::Protocol::getEnumConstantValue(out_screenColor));
+        result->setArray(ASCIILiteral("alternateColors"), out_alternateColors);
+        result->setString(ASCIILiteral("printColor"), Inspector::Protocol::getEnumConstantValue(out_printColor));
+    }
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Database {
+class Error;
+enum class PrimaryColors;
+} // Database
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Database {
+/* Unique identifier of Database object. */
+typedef int DatabaseId;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Database::PrimaryColors> ColorList;
+} // Database
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Database {
+/*  */
+enum class PrimaryColors {
+    Red = 0,
+    Green = 1,
+    Blue = 2,
+}; // enum class PrimaryColors
+/* Database error. */
+class Error : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        MessageSet = 1 << 0,
+        CodeSet = 1 << 1,
+        AllFieldsSet = (MessageSet | CodeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*Error*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class Error;
+    public:
+
+        Builder<STATE | MessageSet>& setMessage(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
+            m_result->setString(ASCIILiteral("message"), value);
+            return castState<MessageSet>();
+        }
+
+        Builder<STATE | CodeSet>& setCode(int value)
+        {
+            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
+            m_result->setInteger(ASCIILiteral("code"), value);
+            return castState<CodeSet>();
+        }
+
+        Ref<Error> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(Error) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<Error>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<Error> result = Error::create()
+     *     .setMessage(...)
+     *     .setCode(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Database
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "red",
+    "green",
+    "blue",
+    "cyan",
+    "magenta",
+    "yellow",
+    "black",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+@protocol RWIProtocolDatabaseDomainHandler;
+
+namespace Inspector {
+
+
+class ObjCInspectorDatabaseBackendDispatcher final : public AlternateDatabaseBackendDispatcher {
+public:
+    ObjCInspectorDatabaseBackendDispatcher(id<RWIProtocolDatabaseDomainHandler> handler) { m_delegate = handler; }
+    virtual void executeAllOptionalParameters(long callId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor) override;
+    virtual void executeNoOptionalParameters(long callId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor) override;
+private:
+    RetainPtr<id<RWIProtocolDatabaseDomainHandler>> m_delegate;
+};
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    id<RWIProtocolDatabaseDomainHandler> _databaseHandler;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_databaseHandler release];
+    [super dealloc];
+}
+
+- (void)setDatabaseHandler:(id<RWIProtocolDatabaseDomainHandler>)handler
+{
+    if (handler == _databaseHandler)
+        return;
+
+    [_databaseHandler release];
+    _databaseHandler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorDatabaseBackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<DatabaseBackendDispatcher, AlternateDatabaseBackendDispatcher>>(ASCIILiteral("Database"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolDatabaseDomainHandler>)databaseHandler
+{
+    return _databaseHandler;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, retain, setter=setDatabaseHandler:) id<RWIProtocolDatabaseDomainHandler> databaseHandler;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long callId, const Inspector::InspectorArray* in_columnNames, const String* in_notes, const double* in_timestamp, const Inspector::InspectorObject* in_values, const Inspector::InspectorValue* in_payload, const int* in_databaseId, const Inspector::InspectorObject* in_sqlError, const String* in_screenColor, const Inspector::InspectorArray* in_alternateColors, const String* in_printColor)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor *printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(alternateColors, @"alternateColors");
+        if (columnNames)
+            resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(*columnNames));
+        if (notes)
+            resultObject->setString(ASCIILiteral("notes"), *notes);
+        if (timestamp)
+            resultObject->setDouble(ASCIILiteral("timestamp"), *timestamp);
+        if (values)
+            resultObject->setObject(ASCIILiteral("values"), [*values toInspectorObject]);
+        if (payload)
+            resultObject->setValue(ASCIILiteral("payload"), [*payload toInspectorObject]);
+        if (databaseId)
+            resultObject->setInteger(ASCIILiteral("databaseId"), *databaseId);
+        if (sqlError)
+            resultObject->setObject(ASCIILiteral("sqlError"), [*sqlError toInspectorObject]);
+        if (screenColor)
+            resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(*screenColor));
+        if (alternateColors)
+            resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(*alternateColors));
+        if (printColor)
+            resultObject->setString(ASCIILiteral("printColor"), toProtocolString(*printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    NSArray/*<NSString>*/ *o_in_columnNames;
+    if (in_columnNames)
+        o_in_columnNames = objcStringArray(in_columnNames);
+    NSString *o_in_notes;
+    if (in_notes)
+        o_in_notes = *in_notes;
+    double o_in_timestamp;
+    if (in_timestamp)
+        o_in_timestamp = *in_timestamp;
+    RWIProtocolJSONObject *o_in_values;
+    if (in_values)
+        o_in_values = [[[RWIProtocolJSONObject alloc] initWithInspectorObject:in_values] autorelease];
+    RWIProtocolJSONObject *o_in_payload;
+    if (in_payload)
+        o_in_payload = [[[RWIProtocolJSONObject alloc] initWithInspectorObject:in_payload] autorelease];
+    int o_in_databaseId;
+    if (in_databaseId)
+        o_in_databaseId = *in_databaseId;
+    RWIProtocolDatabaseError *o_in_sqlError;
+    if (in_sqlError)
+        o_in_sqlError = [[[RWIProtocolDatabaseError alloc] initWithInspectorObject:in_sqlError] autorelease];
+    RWIProtocolDatabasePrimaryColors o_in_screenColor;
+    if (in_screenColor)
+        o_in_screenColor = fromProtocolString<RWIProtocolDatabasePrimaryColors>(*in_screenColor);
+    NSArray/*<NSString>*/ *o_in_alternateColors;
+    if (in_alternateColors)
+        o_in_alternateColors = objcStringArray(in_alternateColors);
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor o_in_printColor;
+    if (in_printColor)
+        o_in_printColor = fromProtocolString<RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor>(*in_printColor);
+
+    [m_delegate executeAllOptionalParametersWithErrorCallback:errorCallback successCallback:successCallback columnNames:(in_columnNames ? &o_in_columnNames : nil) notes:(in_notes ? &o_in_notes : nil) timestamp:(in_timestamp ? &o_in_timestamp : nil) values:(in_values ? &o_in_values : nil) payload:(in_payload ? &o_in_payload : nil) databaseId:(in_databaseId ? &o_in_databaseId : nil) sqlError:(in_sqlError ? &o_in_sqlError : nil) screenColor:(in_screenColor ? &o_in_screenColor : nil) alternateColors:(in_alternateColors ? &o_in_alternateColors : nil) printColor:(in_printColor ? &o_in_printColor : nil)];
+}
+
+void ObjCInspectorDatabaseBackendDispatcher::executeNoOptionalParameters(long callId, const Inspector::InspectorArray& in_columnNames, const String& in_notes, double in_timestamp, const Inspector::InspectorObject& in_values, Inspector::InspectorValue in_payload, int in_databaseId, const Inspector::InspectorObject& in_sqlError, const String& in_screenColor, const Inspector::InspectorArray& in_alternateColors, const String& in_printColor)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor printColor) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(columnNames, @"columnNames");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(notes, @"notes");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(values, @"values");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(payload, @"payload");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(sqlError, @"sqlError");
+        THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(alternateColors, @"alternateColors");
+        resultObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(columnNames));
+        resultObject->setString(ASCIILiteral("notes"), notes);
+        resultObject->setDouble(ASCIILiteral("timestamp"), timestamp);
+        resultObject->setObject(ASCIILiteral("values"), [values toInspectorObject]);
+        resultObject->setValue(ASCIILiteral("payload"), [payload toInspectorObject]);
+        resultObject->setInteger(ASCIILiteral("databaseId"), databaseId);
+        resultObject->setObject(ASCIILiteral("sqlError"), [sqlError toInspectorObject]);
+        resultObject->setString(ASCIILiteral("screenColor"), toProtocolString(screenColor));
+        resultObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
+        resultObject->setString(ASCIILiteral("printColor"), toProtocolString(printColor));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    NSArray/*<NSString>*/ *o_in_columnNames = objcStringArray(&in_columnNames);
+    NSString *o_in_notes = in_notes;
+    double o_in_timestamp = in_timestamp;
+    RWIProtocolJSONObject *o_in_values = [[[RWIProtocolJSONObject alloc] initWithInspectorObject:&in_values] autorelease];
+    RWIProtocolJSONObject *o_in_payload = [[[RWIProtocolJSONObject alloc] initWithInspectorObject:&in_payload] autorelease];
+    int o_in_databaseId = in_databaseId;
+    RWIProtocolDatabaseError *o_in_sqlError = [[[RWIProtocolDatabaseError alloc] initWithInspectorObject:&in_sqlError] autorelease];
+    RWIProtocolDatabasePrimaryColors o_in_screenColor = fromProtocolString<RWIProtocolDatabasePrimaryColors>(in_screenColor);
+    NSArray/*<NSString>*/ *o_in_alternateColors = objcStringArray(&in_alternateColors);
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor o_in_printColor = fromProtocolString<RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor>(in_printColor);
+
+    [m_delegate executeNoOptionalParametersWithErrorCallback:errorCallback successCallback:successCallback columnNames:o_in_columnNames notes:o_in_notes timestamp:o_in_timestamp values:o_in_values payload:o_in_payload databaseId:o_in_databaseId sqlError:o_in_sqlError screenColor:o_in_screenColor alternateColors:o_in_alternateColors printColor:o_in_printColor];
+}
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolDatabasePrimaryColors value)
+{
+    switch(value) {
+    case RWIProtocolDatabasePrimaryColorsRed:
+        return ASCIILiteral("red");
+    case RWIProtocolDatabasePrimaryColorsGreen:
+        return ASCIILiteral("green");
+    case RWIProtocolDatabasePrimaryColorsBlue:
+        return ASCIILiteral("blue");
+    }
+}
+
+template<>
+inline RWIProtocolDatabasePrimaryColors fromProtocolString(const String& value)
+{
+    if (value == "red")
+        return RWIProtocolDatabasePrimaryColorsRed;
+    if (value == "green")
+        return RWIProtocolDatabasePrimaryColorsGreen;
+    if (value == "blue")
+        return RWIProtocolDatabasePrimaryColorsBlue;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabasePrimaryColorsRed;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan;
+}
+
+inline String toProtocolString(RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor value)
+{
+    switch(value) {
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow:
+        return ASCIILiteral("yellow");
+    case RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack:
+        return ASCIILiteral("black");
+    }
+}
+
+template<>
+inline RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor fromProtocolString(const String& value)
+{
+    if (value == "cyan")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan;
+    if (value == "magenta")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta;
+    if (value == "yellow")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow;
+    if (value == "black")
+        return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolDatabaseError;
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabasePrimaryColors) {
+    RWIProtocolDatabasePrimaryColorsRed,
+    RWIProtocolDatabasePrimaryColorsGreen,
+    RWIProtocolDatabasePrimaryColorsBlue,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor) {
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor) {
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorCyan,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorMagenta,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorYellow,
+    RWIProtocolDatabaseExecuteAllOptionalParametersPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor) {
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor) {
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorCyan,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorMagenta,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorYellow,
+    RWIProtocolDatabaseExecuteNoOptionalParametersPrintColorBlack,
+};
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseError : RWIProtocolJSONObject
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+/* required */ @property (nonatomic, copy) NSString *message;
+/* required */ @property (nonatomic, assign) int code;
+@end
+
+@protocol RWIProtocolDatabaseDomainHandler <NSObject>
+@required
+- (void)executeAllOptionalParametersWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, RWIProtocolDatabaseError **sqlError, RWIProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor *printColor))successCallback columnNames:(NSArray/*<NSString>*/ **)columnNames notes:(NSString **)notes timestamp:(double *)timestamp values:(RWIProtocolJSONObject **)values payload:(RWIProtocolJSONObject **)payload databaseId:(int *)databaseId sqlError:(RWIProtocolDatabaseError **)sqlError screenColor:(RWIProtocolDatabasePrimaryColors *)screenColor alternateColors:(NSArray/*<NSString>*/ **)alternateColors printColor:(RWIProtocolDatabaseExecuteAllOptionalParametersPrintColor *)printColor;
+- (void)executeNoOptionalParametersWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, RWIProtocolDatabaseError *sqlError, RWIProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor printColor))successCallback columnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload databaseId:(int)databaseId sqlError:(RWIProtocolDatabaseError *)sqlError screenColor:(RWIProtocolDatabasePrimaryColors)screenColor alternateColors:(NSArray/*<NSString>*/ *)alternateColors printColor:(RWIProtocolDatabaseExecuteNoOptionalParametersPrintColor)printColor;
+@end
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolDatabaseError
+
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");
+
+    self.message = message;
+    self.code = code;
+
+    return self;
+}
+
+- (void)setMessage:(NSString *)message
+{
+    [super setString:message forKey:@"message"];
+}
+
+- (NSString *)message
+{
+    return [super stringForKey:@"message"];
+}
+
+- (void)setCode:(int)code
+{
+    [super setInteger:code forKey:@"code"];
+}
+
+- (int)code
+{
+    return [super integerForKey:@"code"];
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from commands-with-optional-call-return-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result b/inspector/scripts/tests/expected/domains-with-varying-command-sizes.json-result
new file mode 100644 (file)
index 0000000..190b260
--- /dev/null
@@ -0,0 +1,1318 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+class AlternateNetwork1BackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateNetwork1BackendDispatcher() { }
+    virtual void loadResource1(long callId) = 0;
+};
+class AlternateNetwork3BackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateNetwork3BackendDispatcher() { }
+    virtual void loadResource1(long callId) = 0;
+    virtual void loadResource2(long callId) = 0;
+    virtual void loadResource3(long callId) = 0;
+    virtual void loadResource4(long callId) = 0;
+    virtual void loadResource5(long callId) = 0;
+    virtual void loadResource6(long callId) = 0;
+    virtual void loadResource7(long callId) = 0;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Network1.
+InspectorBackend.registerCommand("Network1.loadResource1", [], []);
+InspectorBackend.activateDomain("Network1");
+
+// Network3.
+InspectorBackend.registerCommand("Network3.loadResource1", [], []);
+InspectorBackend.registerCommand("Network3.loadResource2", [], []);
+InspectorBackend.registerCommand("Network3.loadResource3", [], []);
+InspectorBackend.registerCommand("Network3.loadResource4", [], []);
+InspectorBackend.registerCommand("Network3.loadResource5", [], []);
+InspectorBackend.registerCommand("Network3.loadResource6", [], []);
+InspectorBackend.registerCommand("Network3.loadResource7", [], []);
+InspectorBackend.activateDomain("Network3");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+class AlternateNetwork1BackendDispatcher;
+class AlternateNetwork3BackendDispatcher;
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+class Network1BackendDispatcherHandler {
+public:
+    virtual void loadResource1(ErrorString&) = 0;
+protected:
+    virtual ~Network1BackendDispatcherHandler();
+};
+
+class Network3BackendDispatcherHandler {
+public:
+    virtual void loadResource1(ErrorString&) = 0;
+    virtual void loadResource2(ErrorString&) = 0;
+    virtual void loadResource3(ErrorString&) = 0;
+    virtual void loadResource4(ErrorString&) = 0;
+    virtual void loadResource5(ErrorString&) = 0;
+    virtual void loadResource6(ErrorString&) = 0;
+    virtual void loadResource7(ErrorString&) = 0;
+protected:
+    virtual ~Network3BackendDispatcherHandler();
+};
+
+class Network1BackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<Network1BackendDispatcher> create(BackendDispatcher*, Network1BackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void loadResource1(long callId, const InspectorObject& message);
+private:
+    Network1BackendDispatcher(BackendDispatcher&, Network1BackendDispatcherHandler*);
+    Network1BackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateNetwork1BackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateNetwork1BackendDispatcher* m_alternateDispatcher;
+#endif
+};
+
+class Network3BackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<Network3BackendDispatcher> create(BackendDispatcher*, Network3BackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void loadResource1(long callId, const InspectorObject& message);
+    void loadResource2(long callId, const InspectorObject& message);
+    void loadResource3(long callId, const InspectorObject& message);
+    void loadResource4(long callId, const InspectorObject& message);
+    void loadResource5(long callId, const InspectorObject& message);
+    void loadResource6(long callId, const InspectorObject& message);
+    void loadResource7(long callId, const InspectorObject& message);
+private:
+    Network3BackendDispatcher(BackendDispatcher&, Network3BackendDispatcherHandler*);
+    Network3BackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateNetwork3BackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateNetwork3BackendDispatcher* m_alternateDispatcher;
+#endif
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+Network1BackendDispatcherHandler::~Network1BackendDispatcherHandler() { }
+Network3BackendDispatcherHandler::~Network3BackendDispatcherHandler() { }
+
+Ref<Network1BackendDispatcher> Network1BackendDispatcher::create(BackendDispatcher* backendDispatcher, Network1BackendDispatcherHandler* agent)
+{
+    return adoptRef(*new Network1BackendDispatcher(*backendDispatcher, agent));
+}
+
+Network1BackendDispatcher::Network1BackendDispatcher(BackendDispatcher& backendDispatcher, Network1BackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network1"), this);
+}
+
+void Network1BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<Network1BackendDispatcher> protect(*this);
+
+    if (method == "loadResource1")
+        loadResource1(callId, message);
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
+}
+
+void Network1BackendDispatcher::loadResource1(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource1(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource1(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+Ref<Network3BackendDispatcher> Network3BackendDispatcher::create(BackendDispatcher* backendDispatcher, Network3BackendDispatcherHandler* agent)
+{
+    return adoptRef(*new Network3BackendDispatcher(*backendDispatcher, agent));
+}
+
+Network3BackendDispatcher::Network3BackendDispatcher(BackendDispatcher& backendDispatcher, Network3BackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network3"), this);
+}
+
+void Network3BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<Network3BackendDispatcher> protect(*this);
+
+    typedef void (Network3BackendDispatcher::*CallHandler)(long callId, const InspectorObject& message);
+    typedef HashMap<String, CallHandler> DispatchMap;
+    DEPRECATED_DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
+    if (dispatchMap.isEmpty()) {
+        static const struct MethodTable {
+            const char* name;
+            CallHandler handler;
+        } commands[] = {
+            { "loadResource1", &Network3BackendDispatcher::loadResource1 },
+            { "loadResource2", &Network3BackendDispatcher::loadResource2 },
+            { "loadResource3", &Network3BackendDispatcher::loadResource3 },
+            { "loadResource4", &Network3BackendDispatcher::loadResource4 },
+            { "loadResource5", &Network3BackendDispatcher::loadResource5 },
+            { "loadResource6", &Network3BackendDispatcher::loadResource6 },
+            { "loadResource7", &Network3BackendDispatcher::loadResource7 },
+        };
+        size_t length = WTF_ARRAY_LENGTH(commands);
+        for (size_t i = 0; i < length; ++i)
+            dispatchMap.add(commands[i].name, commands[i].handler);
+    }
+
+    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
+    if (it == dispatchMap.end()) {
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network3", '.', method, "' was not found"));
+        return;
+    }
+
+    ((*this).*it->value)(callId, message.get());
+}
+
+void Network3BackendDispatcher::loadResource1(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource1(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource1(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource2(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource2(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource2(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource3(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource3(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource3(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource4(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource4(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource4(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource5(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource5(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource5(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource6(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource6(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource6(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+void Network3BackendDispatcher::loadResource7(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource7(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource7(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+
+
+// Typedefs.
+namespace Network2 {
+/* Unique loader identifier. */
+typedef String LoaderId;
+} // Network2
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+@protocol RWIProtocolNetwork1DomainHandler;
+@protocol RWIProtocolNetwork3DomainHandler;
+
+namespace Inspector {
+
+
+class ObjCInspectorNetwork1BackendDispatcher final : public AlternateNetwork1BackendDispatcher {
+public:
+    ObjCInspectorNetwork1BackendDispatcher(id<RWIProtocolNetwork1DomainHandler> handler) { m_delegate = handler; }
+    virtual void loadResource1(long callId) override;
+private:
+    RetainPtr<id<RWIProtocolNetwork1DomainHandler>> m_delegate;
+};
+
+
+
+class ObjCInspectorNetwork3BackendDispatcher final : public AlternateNetwork3BackendDispatcher {
+public:
+    ObjCInspectorNetwork3BackendDispatcher(id<RWIProtocolNetwork3DomainHandler> handler) { m_delegate = handler; }
+    virtual void loadResource1(long callId) override;
+    virtual void loadResource2(long callId) override;
+    virtual void loadResource3(long callId) override;
+    virtual void loadResource4(long callId) override;
+    virtual void loadResource5(long callId) override;
+    virtual void loadResource6(long callId) override;
+    virtual void loadResource7(long callId) override;
+private:
+    RetainPtr<id<RWIProtocolNetwork3DomainHandler>> m_delegate;
+};
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    id<RWIProtocolNetwork1DomainHandler> _network1Handler;
+    id<RWIProtocolNetwork3DomainHandler> _network3Handler;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_network1Handler release];
+    [_network3Handler release];
+    [super dealloc];
+}
+
+- (void)setNetwork1Handler:(id<RWIProtocolNetwork1DomainHandler>)handler
+{
+    if (handler == _network1Handler)
+        return;
+
+    [_network1Handler release];
+    _network1Handler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorNetwork1BackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<Network1BackendDispatcher, AlternateNetwork1BackendDispatcher>>(ASCIILiteral("Network1"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolNetwork1DomainHandler>)network1Handler
+{
+    return _network1Handler;
+}
+
+- (void)setNetwork3Handler:(id<RWIProtocolNetwork3DomainHandler>)handler
+{
+    if (handler == _network3Handler)
+        return;
+
+    [_network3Handler release];
+    _network3Handler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorNetwork3BackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<Network3BackendDispatcher, AlternateNetwork3BackendDispatcher>>(ASCIILiteral("Network3"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolNetwork3DomainHandler>)network3Handler
+{
+    return _network3Handler;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, retain, setter=setNetwork1Handler:) id<RWIProtocolNetwork1DomainHandler> network1Handler;
+@property (nonatomic, retain, setter=setNetwork3Handler:) id<RWIProtocolNetwork3DomainHandler> network3Handler;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+void ObjCInspectorNetwork1BackendDispatcher::loadResource1(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource1WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+
+
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource1(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource1WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource2(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource2WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource3(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource3WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource4(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource4WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource5(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource5WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource6(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource6WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+void ObjCInspectorNetwork3BackendDispatcher::loadResource7(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResource7WithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+
+
+
+@protocol RWIProtocolNetwork1DomainHandler <NSObject>
+@required
+- (void)loadResource1WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+@end
+
+@protocol RWIProtocolNetwork3DomainHandler <NSObject>
+@required
+- (void)loadResource1WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource2WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource3WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource4WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource5WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource6WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+- (void)loadResource7WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+@end
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from domains-with-varying-command-sizes.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/enum-values.json-result b/inspector/scripts/tests/expected/enum-values.json-result
new file mode 100644 (file)
index 0000000..9d74853
--- /dev/null
@@ -0,0 +1,1172 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+class AlternateCommandDomainBackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateCommandDomainBackendDispatcher() { }
+    virtual void commandWithEnumReturnValue(long callId) = 0;
+};
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// TypeDomain.
+InspectorBackend.registerEnum("TypeDomain.TypeDomainEnum", {Shared: "shared", Red: "red", Green: "green", Blue: "blue"});
+
+// CommandDomain.
+InspectorBackend.registerCommand("CommandDomain.commandWithEnumReturnValue", [], ["returnValue"]);
+InspectorBackend.activateDomain("CommandDomain");
+
+// EventDomain.
+InspectorBackend.registerEventDomainDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "EventDomain");
+InspectorBackend.registerEnum("EventDomain.EventWithEnumParameterParameter", {Shared: "shared", Black: "black", White: "white"});
+InspectorBackend.registerEvent("EventDomain.eventWithEnumParameter", ["parameter"]);
+InspectorBackend.activateDomain("EventDomain");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+class AlternateCommandDomainBackendDispatcher;
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+class CommandDomainBackendDispatcherHandler {
+public:
+    // Named after parameter 'returnValue' while generating command/event commandWithEnumReturnValue.
+    enum class ReturnValue {
+        Shared = 0,
+        Cyan = 6,
+        Magenta = 7,
+        Yellow = 8,
+    }; // enum class ReturnValue
+    virtual void commandWithEnumReturnValue(ErrorString&, CommandDomainBackendDispatcherHandler::ReturnValue* out_returnValue) = 0;
+protected:
+    virtual ~CommandDomainBackendDispatcherHandler();
+};
+
+class CommandDomainBackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<CommandDomainBackendDispatcher> create(BackendDispatcher*, CommandDomainBackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void commandWithEnumReturnValue(long callId, const InspectorObject& message);
+private:
+    CommandDomainBackendDispatcher(BackendDispatcher&, CommandDomainBackendDispatcherHandler*);
+    CommandDomainBackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateCommandDomainBackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateCommandDomainBackendDispatcher* m_alternateDispatcher;
+#endif
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+CommandDomainBackendDispatcherHandler::~CommandDomainBackendDispatcherHandler() { }
+
+Ref<CommandDomainBackendDispatcher> CommandDomainBackendDispatcher::create(BackendDispatcher* backendDispatcher, CommandDomainBackendDispatcherHandler* agent)
+{
+    return adoptRef(*new CommandDomainBackendDispatcher(*backendDispatcher, agent));
+}
+
+CommandDomainBackendDispatcher::CommandDomainBackendDispatcher(BackendDispatcher& backendDispatcher, CommandDomainBackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("CommandDomain"), this);
+}
+
+void CommandDomainBackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<CommandDomainBackendDispatcher> protect(*this);
+
+    if (method == "commandWithEnumReturnValue")
+        commandWithEnumReturnValue(callId, message);
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "CommandDomain", '.', method, "' was not found"));
+}
+
+void CommandDomainBackendDispatcher::commandWithEnumReturnValue(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->commandWithEnumReturnValue(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    CommandDomainBackendDispatcherHandler::ReturnValue out_returnValue;
+    m_agent->commandWithEnumReturnValue(error, &out_returnValue);
+
+    if (!error.length())
+        result->setString(ASCIILiteral("returnValue"), Inspector::Protocol::getEnumConstantValue(out_returnValue));
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+class EventDomainFrontendDispatcher {
+public:
+    EventDomainFrontendDispatcher(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
+        // Named after parameter 'parameter' while generating command/event eventWithEnumParameter.
+        enum class Parameter {
+            Shared = 0,
+            Black = 4,
+            White = 5,
+        }; // enum class Parameter
+    void eventWithEnumParameter(Parameter parameter);
+private:
+    FrontendChannel* m_frontendChannel;
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+void EventDomainFrontendDispatcher::eventWithEnumParameter(Parameter parameter)
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("EventDomain.eventWithEnumParameter"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    paramsObject->setString(ASCIILiteral("parameter"), Inspector::Protocol::getEnumConstantValue(parameter));
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+
+    m_frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace TypeDomain {
+enum class TypeDomainEnum;
+} // TypeDomain
+// End of forward declarations.
+
+
+
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace TypeDomain {
+/*  */
+enum class TypeDomainEnum {
+    Shared = 0,
+    Red = 1,
+    Green = 2,
+    Blue = 3,
+}; // enum class TypeDomainEnum
+} // TypeDomain
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "shared",
+    "red",
+    "green",
+    "blue",
+    "black",
+    "white",
+    "cyan",
+    "magenta",
+    "yellow",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+@protocol RWIProtocolCommandDomainDomainHandler;
+
+namespace Inspector {
+
+
+
+
+class ObjCInspectorCommandDomainBackendDispatcher final : public AlternateCommandDomainBackendDispatcher {
+public:
+    ObjCInspectorCommandDomainBackendDispatcher(id<RWIProtocolCommandDomainDomainHandler> handler) { m_delegate = handler; }
+    virtual void commandWithEnumReturnValue(long callId) override;
+private:
+    RetainPtr<id<RWIProtocolCommandDomainDomainHandler>> m_delegate;
+};
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    id<RWIProtocolCommandDomainDomainHandler> _commandDomainHandler;
+    RWIProtocolEventDomainDomainEventDispatcher *_eventDomainEventDispatcher;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_commandDomainHandler release];
+    [_eventDomainEventDispatcher release];
+    [super dealloc];
+}
+
+- (void)setCommandDomainHandler:(id<RWIProtocolCommandDomainDomainHandler>)handler
+{
+    if (handler == _commandDomainHandler)
+        return;
+
+    [_commandDomainHandler release];
+    _commandDomainHandler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorCommandDomainBackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<CommandDomainBackendDispatcher, AlternateCommandDomainBackendDispatcher>>(ASCIILiteral("CommandDomain"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolCommandDomainDomainHandler>)commandDomainHandler
+{
+    return _commandDomainHandler;
+}
+
+- (RWIProtocolEventDomainDomainEventDispatcher *)eventDomainEventDispatcher
+{
+    if (!_eventDomainEventDispatcher)
+        _eventDomainEventDispatcher = [[RWIProtocolEventDomainDomainEventDispatcher alloc] initWithController:_controller];
+    return _eventDomainEventDispatcher;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, retain, setter=setCommandDomainHandler:) id<RWIProtocolCommandDomainDomainHandler> commandDomainHandler;
+@property (nonatomic, readonly) RWIProtocolEventDomainDomainEventDispatcher *eventDomainEventDispatcher;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+void ObjCInspectorCommandDomainBackendDispatcher::commandWithEnumReturnValue(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^(RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue returnValue) {
+        Ref<InspectorObject> resultObject = InspectorObject::create();
+        resultObject->setString(ASCIILiteral("returnValue"), toProtocolString(returnValue));
+        backendDispatcher()->sendResponse(callId, WTF::move(resultObject), String());
+    };
+
+    [m_delegate commandWithEnumReturnValueWithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolTypeDomainEnum value)
+{
+    switch(value) {
+    case RWIProtocolTypeDomainEnumShared:
+        return ASCIILiteral("shared");
+    case RWIProtocolTypeDomainEnumRed:
+        return ASCIILiteral("red");
+    case RWIProtocolTypeDomainEnumGreen:
+        return ASCIILiteral("green");
+    case RWIProtocolTypeDomainEnumBlue:
+        return ASCIILiteral("blue");
+    }
+}
+
+template<>
+inline RWIProtocolTypeDomainEnum fromProtocolString(const String& value)
+{
+    if (value == "shared")
+        return RWIProtocolTypeDomainEnumShared;
+    if (value == "red")
+        return RWIProtocolTypeDomainEnumRed;
+    if (value == "green")
+        return RWIProtocolTypeDomainEnumGreen;
+    if (value == "blue")
+        return RWIProtocolTypeDomainEnumBlue;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolTypeDomainEnumShared;
+}
+
+
+inline String toProtocolString(RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue value)
+{
+    switch(value) {
+    case RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueShared:
+        return ASCIILiteral("shared");
+    case RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueCyan:
+        return ASCIILiteral("cyan");
+    case RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueMagenta:
+        return ASCIILiteral("magenta");
+    case RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueYellow:
+        return ASCIILiteral("yellow");
+    }
+}
+
+template<>
+inline RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue fromProtocolString(const String& value)
+{
+    if (value == "shared")
+        return RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueShared;
+    if (value == "cyan")
+        return RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueCyan;
+    if (value == "magenta")
+        return RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueMagenta;
+    if (value == "yellow")
+        return RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueYellow;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueShared;
+}
+
+
+inline String toProtocolString(RWIProtocolEventDomainEventWithEnumParameterParameter value)
+{
+    switch(value) {
+    case RWIProtocolEventDomainEventWithEnumParameterParameterShared:
+        return ASCIILiteral("shared");
+    case RWIProtocolEventDomainEventWithEnumParameterParameterBlack:
+        return ASCIILiteral("black");
+    case RWIProtocolEventDomainEventWithEnumParameterParameterWhite:
+        return ASCIILiteral("white");
+    }
+}
+
+template<>
+inline RWIProtocolEventDomainEventWithEnumParameterParameter fromProtocolString(const String& value)
+{
+    if (value == "shared")
+        return RWIProtocolEventDomainEventWithEnumParameterParameterShared;
+    if (value == "black")
+        return RWIProtocolEventDomainEventWithEnumParameterParameterBlack;
+    if (value == "white")
+        return RWIProtocolEventDomainEventWithEnumParameterParameterWhite;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolEventDomainEventWithEnumParameterParameterShared;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+@implementation RWIProtocolEventDomainDomainEventDispatcher
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)eventWithEnumParameterWithParameter:(RWIProtocolEventDomainEventWithEnumParameterParameter)parameter
+{
+    FrontendChannel* frontendChannel = _controller->frontendChannel();
+    if (!frontendChannel)
+        return;
+
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("EventDomain.eventWithEnumParameter"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    paramsObject->setString(ASCIILiteral("parameter"), toProtocolString(parameter));
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+@end
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolTypeDomainEnum) {
+    RWIProtocolTypeDomainEnumShared,
+    RWIProtocolTypeDomainEnumRed,
+    RWIProtocolTypeDomainEnumGreen,
+    RWIProtocolTypeDomainEnumBlue,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue) {
+    RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueShared,
+    RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueCyan,
+    RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueMagenta,
+    RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValueYellow,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolEventDomainEventWithEnumParameterParameter) {
+    RWIProtocolEventDomainEventWithEnumParameterParameterShared,
+    RWIProtocolEventDomainEventWithEnumParameterParameterBlack,
+    RWIProtocolEventDomainEventWithEnumParameterParameterWhite,
+};
+
+
+
+@protocol RWIProtocolCommandDomainDomainHandler <NSObject>
+@required
+- (void)commandWithEnumReturnValueWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(RWIProtocolCommandDomainCommandWithEnumReturnValueReturnValue returnValue))successCallback;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolEventDomainDomainEventDispatcher : NSObject
+- (void)eventWithEnumParameterWithParameter:(RWIProtocolEventDomainEventWithEnumParameterParameter)parameter;
+@end
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from enum-values.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+@interface RWIProtocolEventDomainDomainEventDispatcher (Private)
+- (instancetype)initWithController:(Inspector::AugmentableInspectorController*)controller;
+@end
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/events-with-optional-parameters.json-result b/inspector/scripts/tests/expected/events-with-optional-parameters.json-result
new file mode 100644 (file)
index 0000000..4b622d9
--- /dev/null
@@ -0,0 +1,1108 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Database.
+InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
+InspectorBackend.registerEvent("Database.didExecuteOptionalParameters", ["columnNames", "notes", "timestamp", "values", "payload", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.registerEvent("Database.didExecuteNoOptionalParameters", ["columnNames", "notes", "timestamp", "values", "payload", "sqlError", "screenColor", "alternateColors", "printColor"]);
+InspectorBackend.activateDomain("Database");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+class DatabaseFrontendDispatcher {
+public:
+    DatabaseFrontendDispatcher(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
+    void didExecuteOptionalParameters(RefPtr<Inspector::Protocol::Array<String>> columnNames, const String* const notes, const double* const timestamp, RefPtr<Inspector::InspectorObject> values, RefPtr<Inspector::InspectorValue> payload, RefPtr<Inspector::Protocol::Database::Error> sqlError, const Inspector::Protocol::Database::PrimaryColors* const screenColor, RefPtr<Inspector::Protocol::Database::ColorList> alternateColors, const String* const printColor);
+    void didExecuteNoOptionalParameters(RefPtr<Inspector::Protocol::Array<String>> columnNames, const String& notes, double timestamp, RefPtr<Inspector::InspectorObject> values, RefPtr<Inspector::InspectorValue> payload, RefPtr<Inspector::Protocol::Database::Error> sqlError, const Inspector::Protocol::Database::PrimaryColors& screenColor, RefPtr<Inspector::Protocol::Database::ColorList> alternateColors, const String& printColor);
+private:
+    FrontendChannel* m_frontendChannel;
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+void DatabaseFrontendDispatcher::didExecuteOptionalParameters(RefPtr<Inspector::Protocol::Array<String>> columnNames, const String* const notes, const double* const timestamp, RefPtr<Inspector::InspectorObject> values, RefPtr<Inspector::InspectorValue> payload, RefPtr<Inspector::Protocol::Database::Error> sqlError, const Inspector::Protocol::Database::PrimaryColors* const screenColor, RefPtr<Inspector::Protocol::Database::ColorList> alternateColors, const String* const printColor)
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Database.didExecuteOptionalParameters"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    if (columnNames)
+        paramsObject->setArray(ASCIILiteral("columnNames"), columnNames);
+    if (notes)
+        paramsObject->setString(ASCIILiteral("notes"), *notes);
+    if (timestamp)
+        paramsObject->setDouble(ASCIILiteral("timestamp"), *timestamp);
+    if (values)
+        paramsObject->setObject(ASCIILiteral("values"), values);
+    if (payload)
+        paramsObject->setValue(ASCIILiteral("payload"), *payload);
+    if (sqlError)
+        paramsObject->setObject(ASCIILiteral("sqlError"), sqlError);
+    if (screenColor)
+        paramsObject->setString(ASCIILiteral("screenColor"), *screenColor);
+    if (alternateColors)
+        paramsObject->setArray(ASCIILiteral("alternateColors"), alternateColors);
+    if (printColor)
+        paramsObject->setString(ASCIILiteral("printColor"), *printColor);
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+
+    m_frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+void DatabaseFrontendDispatcher::didExecuteNoOptionalParameters(RefPtr<Inspector::Protocol::Array<String>> columnNames, const String& notes, double timestamp, RefPtr<Inspector::InspectorObject> values, RefPtr<Inspector::InspectorValue> payload, RefPtr<Inspector::Protocol::Database::Error> sqlError, const Inspector::Protocol::Database::PrimaryColors& screenColor, RefPtr<Inspector::Protocol::Database::ColorList> alternateColors, const String& printColor)
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Database.didExecuteNoOptionalParameters"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    paramsObject->setArray(ASCIILiteral("columnNames"), columnNames);
+    paramsObject->setString(ASCIILiteral("notes"), notes);
+    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
+    paramsObject->setObject(ASCIILiteral("values"), values);
+    paramsObject->setValue(ASCIILiteral("payload"), payload);
+    paramsObject->setObject(ASCIILiteral("sqlError"), sqlError);
+    paramsObject->setString(ASCIILiteral("screenColor"), screenColor);
+    paramsObject->setArray(ASCIILiteral("alternateColors"), alternateColors);
+    paramsObject->setString(ASCIILiteral("printColor"), printColor);
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+
+    m_frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Database {
+class Error;
+} // Database
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Database {
+/* Unique identifier of Database object. */
+typedef String DatabaseId;
+typedef String PrimaryColors;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Database::PrimaryColors> ColorList;
+} // Database
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Database {
+/* Database error. */
+class Error : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        MessageSet = 1 << 0,
+        CodeSet = 1 << 1,
+        AllFieldsSet = (MessageSet | CodeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*Error*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class Error;
+    public:
+
+        Builder<STATE | MessageSet>& setMessage(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
+            m_result->setString(ASCIILiteral("message"), value);
+            return castState<MessageSet>();
+        }
+
+        Builder<STATE | CodeSet>& setCode(int value)
+        {
+            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
+            m_result->setInteger(ASCIILiteral("code"), value);
+            return castState<CodeSet>();
+        }
+
+        Ref<Error> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(Error) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<Error>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<Error> result = Error::create()
+     *     .setMessage(...)
+     *     .setCode(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Database
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    RWIProtocolDatabaseDomainEventDispatcher *_databaseEventDispatcher;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_databaseEventDispatcher release];
+    [super dealloc];
+}
+
+- (RWIProtocolDatabaseDomainEventDispatcher *)databaseEventDispatcher
+{
+    if (!_databaseEventDispatcher)
+        _databaseEventDispatcher = [[RWIProtocolDatabaseDomainEventDispatcher alloc] initWithController:_controller];
+    return _databaseEventDispatcher;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, readonly) RWIProtocolDatabaseDomainEventDispatcher *databaseEventDispatcher;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolDatabaseDomainEventDispatcher
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)didExecuteOptionalParametersWithColumnNames:(NSArray/*<NSString>*/ **)columnNames notes:(NSString **)notes timestamp:(double *)timestamp values:(RWIProtocolJSONObject **)values payload:(RWIProtocolJSONObject **)payload sqlError:(RWIProtocolDatabaseError **)sqlError screenColor:(NSString **)screenColor alternateColors:(NSArray/*<NSString>*/ **)alternateColors printColor:(NSString **)printColor
+{
+    FrontendChannel* frontendChannel = _controller->frontendChannel();
+    if (!frontendChannel)
+        return;
+
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(columnNames, @"columnNames");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(notes, @"notes");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(values, @"values");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(payload, @"payload");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(sqlError, @"sqlError");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(screenColor, @"screenColor");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(alternateColors, @"alternateColors");
+    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(printColor, @"printColor");
+
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Database.didExecuteOptionalParameters"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    if (columnNames)
+        paramsObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray((*columnNames)));
+    if (notes)
+        paramsObject->setString(ASCIILiteral("notes"), (*notes));
+    if (timestamp)
+        paramsObject->setDouble(ASCIILiteral("timestamp"), (*timestamp));
+    if (values)
+        paramsObject->setObject(ASCIILiteral("values"), [(*values) toInspectorObject]);
+    if (payload)
+        paramsObject->setValue(ASCIILiteral("payload"), [(*payload) toInspectorObject]);
+    if (sqlError)
+        paramsObject->setObject(ASCIILiteral("sqlError"), [(*sqlError) toInspectorObject]);
+    if (screenColor)
+        paramsObject->setString(ASCIILiteral("screenColor"), (*screenColor));
+    if (alternateColors)
+        paramsObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray((*alternateColors)));
+    if (printColor)
+        paramsObject->setString(ASCIILiteral("printColor"), (*printColor));
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+- (void)didExecuteNoOptionalParametersWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload sqlError:(RWIProtocolDatabaseError *)sqlError screenColor:(NSString *)screenColor alternateColors:(NSArray/*<NSString>*/ *)alternateColors printColor:(NSString *)printColor
+{
+    FrontendChannel* frontendChannel = _controller->frontendChannel();
+    if (!frontendChannel)
+        return;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(columnNames, @"columnNames");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(notes, @"notes");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(values, @"values");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(payload, @"payload");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(sqlError, @"sqlError");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(screenColor, @"screenColor");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(alternateColors, @"alternateColors");
+    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(printColor, @"printColor");
+
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Database.didExecuteNoOptionalParameters"));
+    Ref<InspectorObject> paramsObject = InspectorObject::create();
+    paramsObject->setArray(ASCIILiteral("columnNames"), inspectorStringArray(columnNames));
+    paramsObject->setString(ASCIILiteral("notes"), notes);
+    paramsObject->setDouble(ASCIILiteral("timestamp"), timestamp);
+    paramsObject->setObject(ASCIILiteral("values"), [values toInspectorObject]);
+    paramsObject->setValue(ASCIILiteral("payload"), [payload toInspectorObject]);
+    paramsObject->setObject(ASCIILiteral("sqlError"), [sqlError toInspectorObject]);
+    paramsObject->setString(ASCIILiteral("screenColor"), screenColor);
+    paramsObject->setArray(ASCIILiteral("alternateColors"), inspectorStringArray(alternateColors));
+    paramsObject->setString(ASCIILiteral("printColor"), printColor);
+    jsonMessage->setObject(ASCIILiteral("params"), WTF::move(paramsObject));
+    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+@end
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolDatabaseError;
+
+
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseError : RWIProtocolJSONObject
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+/* required */ @property (nonatomic, copy) NSString *message;
+/* required */ @property (nonatomic, assign) int code;
+@end
+
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseDomainEventDispatcher : NSObject
+- (void)didExecuteOptionalParametersWithColumnNames:(NSArray/*<NSString>*/ **)columnNames notes:(NSString **)notes timestamp:(double *)timestamp values:(RWIProtocolJSONObject **)values payload:(RWIProtocolJSONObject **)payload sqlError:(RWIProtocolDatabaseError **)sqlError screenColor:(NSString **)screenColor alternateColors:(NSArray/*<NSString>*/ **)alternateColors printColor:(NSString **)printColor;
+- (void)didExecuteNoOptionalParametersWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload sqlError:(RWIProtocolDatabaseError *)sqlError screenColor:(NSString *)screenColor alternateColors:(NSArray/*<NSString>*/ *)alternateColors printColor:(NSString *)printColor;
+@end
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolDatabaseError
+
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");
+
+    self.message = message;
+    self.code = code;
+
+    return self;
+}
+
+- (void)setMessage:(NSString *)message
+{
+    [super setString:message forKey:@"message"];
+}
+
+- (NSString *)message
+{
+    return [super stringForKey:@"message"];
+}
+
+- (void)setCode:(int)code
+{
+    [super setInteger:code forKey:@"code"];
+}
+
+- (int)code
+{
+    return [super integerForKey:@"code"];
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from events-with-optional-parameters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+@interface RWIProtocolDatabaseDomainEventDispatcher (Private)
+- (instancetype)initWithController:(Inspector::AugmentableInspectorController*)controller;
+@end
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/fail-on-domain-availability.json-error b/inspector/scripts/tests/expected/fail-on-domain-availability.json-error
new file mode 100644 (file)
index 0000000..90d7195
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Malformed domain specification: availability is an unsupported string. Was: "webb", Allowed values: web
diff --git a/inspector/scripts/tests/expected/fail-on-duplicate-command-call-parameter-names.json-error b/inspector/scripts/tests/expected/fail-on-duplicate-command-call-parameter-names.json-error
new file mode 100644 (file)
index 0000000..3f756de
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Malformed domain specification: call parameter list for command processPoints has duplicate parameter names
diff --git a/inspector/scripts/tests/expected/fail-on-duplicate-command-return-parameter-names.json-error b/inspector/scripts/tests/expected/fail-on-duplicate-command-return-parameter-names.json-error
new file mode 100644 (file)
index 0000000..ea148ff
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Malformed domain specification: return parameter list for command processPoints has duplicate parameter names
diff --git a/inspector/scripts/tests/expected/fail-on-duplicate-event-parameter-names.json-error b/inspector/scripts/tests/expected/fail-on-duplicate-event-parameter-names.json-error
new file mode 100644 (file)
index 0000000..c71bbd2
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Malformed domain specification: parameter list for event processedPoints has duplicate parameter names
diff --git a/inspector/scripts/tests/expected/fail-on-duplicate-type-declarations.json-error b/inspector/scripts/tests/expected/fail-on-duplicate-type-declarations.json-error
new file mode 100644 (file)
index 0000000..447cdf8
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Duplicate type declaration: Runtime.RemoteObjectId
diff --git a/inspector/scripts/tests/expected/fail-on-duplicate-type-member-names.json-error b/inspector/scripts/tests/expected/fail-on-duplicate-type-member-names.json-error
new file mode 100644 (file)
index 0000000..d5376a7
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Malformed domain specification: type declaration for Point has duplicate member names
diff --git a/inspector/scripts/tests/expected/fail-on-enum-with-no-values.json-error b/inspector/scripts/tests/expected/fail-on-enum-with-no-values.json-error
new file mode 100644 (file)
index 0000000..2655c2b
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Type reference with enum values must have at least one enum value.
diff --git a/inspector/scripts/tests/expected/fail-on-string-typed-optional-parameter-flag.json-error b/inspector/scripts/tests/expected/fail-on-string-typed-optional-parameter-flag.json-error
new file mode 100644 (file)
index 0000000..97b2af0
--- /dev/null
@@ -0,0 +1 @@
+ERROR: The 'optional' flag for a parameter must be a boolean literal.
diff --git a/inspector/scripts/tests/expected/fail-on-string-typed-optional-type-member.json-error b/inspector/scripts/tests/expected/fail-on-string-typed-optional-type-member.json-error
new file mode 100644 (file)
index 0000000..86df375
--- /dev/null
@@ -0,0 +1 @@
+ERROR: The 'optional' flag for a type member must be a boolean literal.
diff --git a/inspector/scripts/tests/expected/fail-on-type-declaration-using-type-reference.json-error b/inspector/scripts/tests/expected/fail-on-type-declaration-using-type-reference.json-error
new file mode 100644 (file)
index 0000000..42f5753
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Type reference cannot have both 'type' and '$ref' keys.
diff --git a/inspector/scripts/tests/expected/fail-on-type-with-lowercase-name.json-error b/inspector/scripts/tests/expected/fail-on-type-with-lowercase-name.json-error
new file mode 100644 (file)
index 0000000..4e46225
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Types must begin with an uppercase character.
diff --git a/inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-declaration.json-error b/inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-declaration.json-error
new file mode 100644 (file)
index 0000000..d3c782d
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Lookup failed for type reference: dragon (referenced from domain: Runtime)
diff --git a/inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-member.json-error b/inspector/scripts/tests/expected/fail-on-unknown-type-reference-in-type-member.json-error
new file mode 100644 (file)
index 0000000..faf6672
--- /dev/null
@@ -0,0 +1 @@
+ERROR: Lookup failed for type reference: Color (referenced from domain: Fantasy)
diff --git a/inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result b/inspector/scripts/tests/expected/generate-domains-with-feature-guards.json-result
new file mode 100644 (file)
index 0000000..bb8d29d
--- /dev/null
@@ -0,0 +1,1159 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+#if PLATFORM(WEB_COMMANDS)
+class AlternateNetwork1BackendDispatcher : public AlternateBackendDispatcher {
+public:
+    virtual ~AlternateNetwork1BackendDispatcher() { }
+    virtual void loadResource(long callId) = 0;
+};
+#endif // PLATFORM(WEB_COMMANDS)
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Network1.
+InspectorBackend.registerCommand("Network1.loadResource", [], []);
+InspectorBackend.activateDomain("Network1");
+
+// Network3.
+InspectorBackend.registerNetwork3Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network3");
+InspectorBackend.registerEvent("Network3.resourceLoaded", []);
+InspectorBackend.activateDomain("Network3");
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#if PLATFORM(WEB_COMMANDS)
+class AlternateNetwork1BackendDispatcher;
+#endif // PLATFORM(WEB_COMMANDS)
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#if PLATFORM(WEB_COMMANDS)
+class Network1BackendDispatcherHandler {
+public:
+    virtual void loadResource(ErrorString&) = 0;
+protected:
+    virtual ~Network1BackendDispatcherHandler();
+};
+#endif // PLATFORM(WEB_COMMANDS)
+
+#if PLATFORM(WEB_COMMANDS)
+class Network1BackendDispatcher final : public SupplementalBackendDispatcher {
+public:
+    static Ref<Network1BackendDispatcher> create(BackendDispatcher*, Network1BackendDispatcherHandler*);
+    virtual void dispatch(long callId, const String& method, Ref<InspectorObject>&& message) override;
+private:
+    void loadResource(long callId, const InspectorObject& message);
+private:
+    Network1BackendDispatcher(BackendDispatcher&, Network1BackendDispatcherHandler*);
+    Network1BackendDispatcherHandler* m_agent;
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+public:
+    void setAlternateDispatcher(AlternateNetwork1BackendDispatcher* alternateDispatcher) { m_alternateDispatcher = alternateDispatcher; }
+private:
+    AlternateNetwork1BackendDispatcher* m_alternateDispatcher;
+#endif
+};
+#endif // PLATFORM(WEB_COMMANDS)
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+#if PLATFORM(WEB_COMMANDS)
+Network1BackendDispatcherHandler::~Network1BackendDispatcherHandler() { }
+#endif // PLATFORM(WEB_COMMANDS)
+
+#if PLATFORM(WEB_COMMANDS)
+Ref<Network1BackendDispatcher> Network1BackendDispatcher::create(BackendDispatcher* backendDispatcher, Network1BackendDispatcherHandler* agent)
+{
+    return adoptRef(*new Network1BackendDispatcher(*backendDispatcher, agent));
+}
+
+Network1BackendDispatcher::Network1BackendDispatcher(BackendDispatcher& backendDispatcher, Network1BackendDispatcherHandler* agent)
+    : SupplementalBackendDispatcher(backendDispatcher)
+    , m_agent(agent)
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    , m_alternateDispatcher(nullptr)
+#endif
+{
+    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Network1"), this);
+}
+
+void Network1BackendDispatcher::dispatch(long callId, const String& method, Ref<InspectorObject>&& message)
+{
+    Ref<Network1BackendDispatcher> protect(*this);
+
+    if (method == "loadResource")
+        loadResource(callId, message);
+    else
+        m_backendDispatcher->reportProtocolError(&callId, BackendDispatcher::MethodNotFound, makeString('\'', "Network1", '.', method, "' was not found"));
+}
+
+void Network1BackendDispatcher::loadResource(long callId, const InspectorObject&)
+{
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_alternateDispatcher) {
+        m_alternateDispatcher->loadResource(callId);
+        return;
+    }
+#endif
+
+    ErrorString error;
+    Ref<InspectorObject> result = InspectorObject::create();
+    m_agent->loadResource(error);
+
+    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);
+}
+#endif // PLATFORM(WEB_COMMANDS)
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+#if PLATFORM(WEB_EVENTS)
+class Network3FrontendDispatcher {
+public:
+    Network3FrontendDispatcher(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
+    void resourceLoaded();
+private:
+    FrontendChannel* m_frontendChannel;
+};
+#endif // PLATFORM(WEB_EVENTS)
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+#if PLATFORM(WEB_EVENTS)
+void Network3FrontendDispatcher::resourceLoaded()
+{
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network3.resourceLoaded"));
+
+    m_frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+#endif // PLATFORM(WEB_EVENTS)
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+#if PLATFORM(WEB_TYPES)
+namespace Network2 {
+class NetworkError;
+} // Network2
+#endif // PLATFORM(WEB_TYPES)
+// End of forward declarations.
+
+
+
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+#if PLATFORM(WEB_TYPES)
+namespace Network2 {
+class NetworkError : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        MessageSet = 1 << 0,
+        CodeSet = 1 << 1,
+        AllFieldsSet = (MessageSet | CodeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*NetworkError*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class NetworkError;
+    public:
+
+        Builder<STATE | MessageSet>& setMessage(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
+            m_result->setString(ASCIILiteral("message"), value);
+            return castState<MessageSet>();
+        }
+
+        Builder<STATE | CodeSet>& setCode(int value)
+        {
+            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
+            m_result->setInteger(ASCIILiteral("code"), value);
+            return castState<CodeSet>();
+        }
+
+        Ref<NetworkError> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(NetworkError) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<NetworkError>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<NetworkError> result = NetworkError::create()
+     *     .setMessage(...)
+     *     .setCode(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Network2
+#endif // PLATFORM(WEB_TYPES)
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+@protocol RWIProtocolNetwork1DomainHandler;
+
+namespace Inspector {
+
+
+#if PLATFORM(WEB_COMMANDS)
+class ObjCInspectorNetwork1BackendDispatcher final : public AlternateNetwork1BackendDispatcher {
+public:
+    ObjCInspectorNetwork1BackendDispatcher(id<RWIProtocolNetwork1DomainHandler> handler) { m_delegate = handler; }
+    virtual void loadResource(long callId) override;
+private:
+    RetainPtr<id<RWIProtocolNetwork1DomainHandler>> m_delegate;
+};
+#endif // PLATFORM(WEB_COMMANDS)
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+    id<RWIProtocolNetwork1DomainHandler> _network1Handler;
+    RWIProtocolNetwork3DomainEventDispatcher *_network3EventDispatcher;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [_network1Handler release];
+    [_network3EventDispatcher release];
+    [super dealloc];
+}
+
+- (void)setNetwork1Handler:(id<RWIProtocolNetwork1DomainHandler>)handler
+{
+    if (handler == _network1Handler)
+        return;
+
+    [_network1Handler release];
+    _network1Handler = [handler retain];
+
+    auto alternateDispatcher = std::make_unique<ObjCInspectorNetwork1BackendDispatcher>(handler);
+    auto alternateAgent = std::make_unique<AlternateDispatchableAgent<Network1BackendDispatcher, AlternateNetwork1BackendDispatcher>>(ASCIILiteral("Network1"), WTF::move(alternateDispatcher));
+    _controller->appendExtraAgent(WTF::move(alternateAgent));
+}
+
+- (id<RWIProtocolNetwork1DomainHandler>)network1Handler
+{
+    return _network1Handler;
+}
+
+- (RWIProtocolNetwork3DomainEventDispatcher *)network3EventDispatcher
+{
+    if (!_network3EventDispatcher)
+        _network3EventDispatcher = [[RWIProtocolNetwork3DomainEventDispatcher alloc] initWithController:_controller];
+    return _network3EventDispatcher;
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@property (nonatomic, retain, setter=setNetwork1Handler:) id<RWIProtocolNetwork1DomainHandler> network1Handler;
+@property (nonatomic, readonly) RWIProtocolNetwork3DomainEventDispatcher *network3EventDispatcher;
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+#if PLATFORM(WEB_COMMANDS)
+void ObjCInspectorNetwork1BackendDispatcher::loadResource(long callId)
+{
+    id errorCallback = ^(NSString *error) {
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), error);
+    };
+
+    id successCallback = ^{
+        backendDispatcher()->sendResponse(callId, InspectorObject::create(), String());
+    };
+
+    [m_delegate loadResourceWithErrorCallback:errorCallback successCallback:successCallback];
+}
+
+#endif // PLATFORM(WEB_COMMANDS)
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+@implementation RWIProtocolNetwork3DomainEventDispatcher
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)resourceLoaded
+{
+    FrontendChannel* frontendChannel = _controller->frontendChannel();
+    if (!frontendChannel)
+        return;
+
+    Ref<InspectorObject> jsonMessage = InspectorObject::create();
+    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Network3.resourceLoaded"));
+    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+}
+
+@end
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolNetwork2NetworkError;
+
+
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolNetwork2NetworkError : RWIProtocolJSONObject
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+/* required */ @property (nonatomic, copy) NSString *message;
+/* required */ @property (nonatomic, assign) int code;
+@end
+
+@protocol RWIProtocolNetwork1DomainHandler <NSObject>
+@required
+- (void)loadResourceWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)())successCallback;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolNetwork3DomainEventDispatcher : NSObject
+- (void)resourceLoaded;
+@end
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+@implementation RWIProtocolNetwork2NetworkError
+
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");
+
+    self.message = message;
+    self.code = code;
+
+    return self;
+}
+
+- (void)setMessage:(NSString *)message
+{
+    [super setString:message forKey:@"message"];
+}
+
+- (NSString *)message
+{
+    return [super stringForKey:@"message"];
+}
+
+- (void)setCode:(int)code
+{
+    [super setInteger:code forKey:@"code"];
+}
+
+- (int)code
+{
+    return [super integerForKey:@"code"];
+}
+
+@end
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from generate-domains-with-feature-guards.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+@interface RWIProtocolNetwork3DomainEventDispatcher (Private)
+- (instancetype)initWithController:(Inspector::AugmentableInspectorController*)controller;
+@end
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/same-type-id-different-domain.json-result b/inspector/scripts/tests/expected/same-type-id-different-domain.json-result
new file mode 100644 (file)
index 0000000..c272f72
--- /dev/null
@@ -0,0 +1,841 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+
+
+// Typedefs.
+namespace Runtime {
+/* Unique object identifier. */
+typedef String RemoteObjectId;
+} // Runtime
+
+namespace Runtime2 {
+/* Unique object identifier. */
+typedef String RemoteObjectId;
+} // Runtime2
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from same-type-id-different-domain.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result b/inspector/scripts/tests/expected/shadowed-optional-type-setters.json-result
new file mode 100644 (file)
index 0000000..a8186e0
--- /dev/null
@@ -0,0 +1,984 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Runtime {
+class KeyPath;
+} // Runtime
+// End of forward declarations.
+
+
+
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Runtime {
+/* Key path. */
+class KeyPath : public Inspector::InspectorObjectBase {
+public:
+    // Named after property name 'type' while generating KeyPath.
+    enum class Type {
+        Null = 0,
+        String = 1,
+        Array = 2,
+    }; // enum class Type
+    enum {
+        NoFieldsSet = 0,
+        TypeSet = 1 << 0,
+        AllFieldsSet = (TypeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*KeyPath*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class KeyPath;
+    public:
+
+        Builder<STATE | TypeSet>& setType(Type value)
+        {
+            COMPILE_ASSERT(!(STATE & TypeSet), property_type_already_set);
+            m_result->setString(ASCIILiteral("type"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));
+            return castState<TypeSet>();
+        }
+
+        Ref<KeyPath> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(KeyPath) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<KeyPath>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<KeyPath> result = KeyPath::create()
+     *     .setType(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+
+    void setString(const String& value)
+    {
+        InspectorObjectBase::setString(ASCIILiteral("string"), value);
+    }
+
+    void setArray(RefPtr<Inspector::Protocol::Array<String>> value)
+    {
+        InspectorObjectBase::setArray(ASCIILiteral("array"), WTF::move(value));
+    }
+};
+
+} // Runtime
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "null",
+    "string",
+    "array",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolRuntimeKeyPathType value)
+{
+    switch(value) {
+    case RWIProtocolRuntimeKeyPathTypeNull:
+        return ASCIILiteral("null");
+    case RWIProtocolRuntimeKeyPathTypeString:
+        return ASCIILiteral("string");
+    case RWIProtocolRuntimeKeyPathTypeArray:
+        return ASCIILiteral("array");
+    }
+}
+
+template<>
+inline RWIProtocolRuntimeKeyPathType fromProtocolString(const String& value)
+{
+    if (value == "null")
+        return RWIProtocolRuntimeKeyPathTypeNull;
+    if (value == "string")
+        return RWIProtocolRuntimeKeyPathTypeString;
+    if (value == "array")
+        return RWIProtocolRuntimeKeyPathTypeArray;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolRuntimeKeyPathTypeNull;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolRuntimeKeyPath;
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolRuntimeKeyPathType) {
+    RWIProtocolRuntimeKeyPathTypeNull,
+    RWIProtocolRuntimeKeyPathTypeString,
+    RWIProtocolRuntimeKeyPathTypeArray,
+};
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolRuntimeKeyPath : RWIProtocolJSONObject
+- (instancetype)initWithType:(RWIProtocolRuntimeKeyPathType)type;
+/* required */ @property (nonatomic, assign) RWIProtocolRuntimeKeyPathType type;
+/* optional */ @property (nonatomic, copy) NSString *string;
+/* optional */ @property (nonatomic, copy) NSArray/*<NSString>*/ *array;
+@end
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolRuntimeKeyPath
+
+- (instancetype)initWithType:(RWIProtocolRuntimeKeyPathType)type;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    self.type = type;
+
+    return self;
+}
+
+- (void)setType:(RWIProtocolRuntimeKeyPathType)type
+{
+    [super setString:toProtocolString(type) forKey:@"type"];
+}
+
+- (RWIProtocolRuntimeKeyPathType)type
+{
+    return fromProtocolString<RWIProtocolRuntimeKeyPathType>([super stringForKey:@"type"]);
+}
+
+- (void)setString:(NSString *)string
+{
+    [super setString:string forKey:@"string"];
+}
+
+- (NSString *)string
+{
+    return [super stringForKey:@"string"];
+}
+
+- (void)setArray:(NSArray/*<NSString>*/ *)array
+{
+    [super setInspectorArray:inspectorStringArray(array) forKey:@"array"];
+}
+
+- (NSArray/*<NSString>*/ *)array
+{
+    return objcStringArray([super inspectorArrayForKey:@"array"]);
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from shadowed-optional-type-setters.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result b/inspector/scripts/tests/expected/type-declaration-aliased-primitive-type.json-result
new file mode 100644 (file)
index 0000000..53b3f22
--- /dev/null
@@ -0,0 +1,826 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+
+
+// Typedefs.
+namespace Runtime {
+/* Unique object identifier. */
+typedef int RemoteObjectId;
+} // Runtime
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-aliased-primitive-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/type-declaration-array-type.json-result b/inspector/scripts/tests/expected/type-declaration-array-type.json-result
new file mode 100644 (file)
index 0000000..7e9ef1e
--- /dev/null
@@ -0,0 +1,893 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Debugger.
+InspectorBackend.registerEnum("Debugger.Reason", {Died: "Died", Fainted: "Fainted", Hungry: "Hungry"});
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Debugger {
+enum class Reason;
+} // Debugger
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Debugger {
+typedef int BreakpointId;
+} // Debugger
+
+namespace Runtime {
+typedef int ObjectId;
+typedef Inspector::Protocol::Array<int> LuckyNumbers;
+typedef Inspector::Protocol::Array<String> BabyNames;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Runtime::ObjectId> NewObjects;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Debugger::BreakpointId> OldObjects;
+typedef Inspector::Protocol::Array<Inspector::Protocol::Debugger::Reason> StopReasons;
+} // Runtime
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Debugger {
+/*  */
+enum class Reason {
+    Died = 0,
+    Fainted = 1,
+    Hungry = 2,
+}; // enum class Reason
+} // Debugger
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "Died",
+    "Fainted",
+    "Hungry",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolDebuggerReason value)
+{
+    switch(value) {
+    case RWIProtocolDebuggerReasonDied:
+        return ASCIILiteral("Died");
+    case RWIProtocolDebuggerReasonFainted:
+        return ASCIILiteral("Fainted");
+    case RWIProtocolDebuggerReasonHungry:
+        return ASCIILiteral("Hungry");
+    }
+}
+
+template<>
+inline RWIProtocolDebuggerReason fromProtocolString(const String& value)
+{
+    if (value == "Died")
+        return RWIProtocolDebuggerReasonDied;
+    if (value == "Fainted")
+        return RWIProtocolDebuggerReasonFainted;
+    if (value == "Hungry")
+        return RWIProtocolDebuggerReasonHungry;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolDebuggerReasonDied;
+}
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolDebuggerReason) {
+    RWIProtocolDebuggerReasonDied,
+    RWIProtocolDebuggerReasonFainted,
+    RWIProtocolDebuggerReasonHungry,
+};
+
+
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-array-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/type-declaration-enum-type.json-result b/inspector/scripts/tests/expected/type-declaration-enum-type.json-result
new file mode 100644 (file)
index 0000000..6d63dd5
--- /dev/null
@@ -0,0 +1,925 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Runtime.
+InspectorBackend.registerEnum("Runtime.FarmAnimals", {Pigs: "Pigs", Cows: "Cows", Cats: "Cats", Hens: "Hens"});
+InspectorBackend.registerEnum("Runtime.TwoLeggedAnimals", {Ducks: "Ducks", Hens: "Hens", Crows: "Crows", Flamingos: "Flamingos"});
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Runtime {
+enum class FarmAnimals;
+enum class TwoLeggedAnimals;
+} // Runtime
+// End of forward declarations.
+
+
+
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Runtime {
+/*  */
+enum class FarmAnimals {
+    Pigs = 0,
+    Cows = 1,
+    Cats = 2,
+    Hens = 3,
+}; // enum class FarmAnimals
+/*  */
+enum class TwoLeggedAnimals {
+    Ducks = 4,
+    Hens = 3,
+    Crows = 5,
+    Flamingos = 6,
+}; // enum class TwoLeggedAnimals
+} // Runtime
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "Pigs",
+    "Cows",
+    "Cats",
+    "Hens",
+    "Ducks",
+    "Crows",
+    "Flamingos",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolRuntimeFarmAnimals value)
+{
+    switch(value) {
+    case RWIProtocolRuntimeFarmAnimalsPigs:
+        return ASCIILiteral("Pigs");
+    case RWIProtocolRuntimeFarmAnimalsCows:
+        return ASCIILiteral("Cows");
+    case RWIProtocolRuntimeFarmAnimalsCats:
+        return ASCIILiteral("Cats");
+    case RWIProtocolRuntimeFarmAnimalsHens:
+        return ASCIILiteral("Hens");
+    }
+}
+
+template<>
+inline RWIProtocolRuntimeFarmAnimals fromProtocolString(const String& value)
+{
+    if (value == "Pigs")
+        return RWIProtocolRuntimeFarmAnimalsPigs;
+    if (value == "Cows")
+        return RWIProtocolRuntimeFarmAnimalsCows;
+    if (value == "Cats")
+        return RWIProtocolRuntimeFarmAnimalsCats;
+    if (value == "Hens")
+        return RWIProtocolRuntimeFarmAnimalsHens;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolRuntimeFarmAnimalsPigs;
+}
+
+inline String toProtocolString(RWIProtocolRuntimeTwoLeggedAnimals value)
+{
+    switch(value) {
+    case RWIProtocolRuntimeTwoLeggedAnimalsDucks:
+        return ASCIILiteral("Ducks");
+    case RWIProtocolRuntimeTwoLeggedAnimalsHens:
+        return ASCIILiteral("Hens");
+    case RWIProtocolRuntimeTwoLeggedAnimalsCrows:
+        return ASCIILiteral("Crows");
+    case RWIProtocolRuntimeTwoLeggedAnimalsFlamingos:
+        return ASCIILiteral("Flamingos");
+    }
+}
+
+template<>
+inline RWIProtocolRuntimeTwoLeggedAnimals fromProtocolString(const String& value)
+{
+    if (value == "Ducks")
+        return RWIProtocolRuntimeTwoLeggedAnimalsDucks;
+    if (value == "Hens")
+        return RWIProtocolRuntimeTwoLeggedAnimalsHens;
+    if (value == "Crows")
+        return RWIProtocolRuntimeTwoLeggedAnimalsCrows;
+    if (value == "Flamingos")
+        return RWIProtocolRuntimeTwoLeggedAnimalsFlamingos;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolRuntimeTwoLeggedAnimalsDucks;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolRuntimeFarmAnimals) {
+    RWIProtocolRuntimeFarmAnimalsPigs,
+    RWIProtocolRuntimeFarmAnimalsCows,
+    RWIProtocolRuntimeFarmAnimalsCats,
+    RWIProtocolRuntimeFarmAnimalsHens,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolRuntimeTwoLeggedAnimals) {
+    RWIProtocolRuntimeTwoLeggedAnimalsDucks,
+    RWIProtocolRuntimeTwoLeggedAnimalsHens,
+    RWIProtocolRuntimeTwoLeggedAnimalsCrows,
+    RWIProtocolRuntimeTwoLeggedAnimalsFlamingos,
+};
+
+
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-enum-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/type-declaration-object-type.json-result b/inspector/scripts/tests/expected/type-declaration-object-type.json-result
new file mode 100644 (file)
index 0000000..6e94941
--- /dev/null
@@ -0,0 +1,1736 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Database {
+class DummyObject;
+class Error;
+class ObjectWithPropertyNameConflicts;
+class OptionalParameterBundle;
+class ParameterBundle;
+} // Database
+
+namespace Test {
+class ParameterBundle;
+} // Test
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Database {
+typedef Inspector::Protocol::Array<Inspector::Protocol::Database::Error> ErrorList;
+} // Database
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Database {
+/* Database error. */
+class Error : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        MessageSet = 1 << 0,
+        CodeSet = 1 << 1,
+        AllFieldsSet = (MessageSet | CodeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*Error*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class Error;
+    public:
+
+        Builder<STATE | MessageSet>& setMessage(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
+            m_result->setString(ASCIILiteral("message"), value);
+            return castState<MessageSet>();
+        }
+
+        Builder<STATE | CodeSet>& setCode(int value)
+        {
+            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
+            m_result->setInteger(ASCIILiteral("code"), value);
+            return castState<CodeSet>();
+        }
+
+        Ref<Error> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(Error) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<Error>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<Error> result = Error::create()
+     *     .setMessage(...)
+     *     .setCode(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+class OptionalParameterBundle : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        AllFieldsSet = 0
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*OptionalParameterBundle*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class OptionalParameterBundle;
+    public:
+
+        Ref<OptionalParameterBundle> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(OptionalParameterBundle) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<OptionalParameterBundle>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<OptionalParameterBundle> result = OptionalParameterBundle::create()
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+
+    void setColumnNames(RefPtr<Inspector::Protocol::Array<String>> value)
+    {
+        InspectorObjectBase::setArray(ASCIILiteral("columnNames"), WTF::move(value));
+    }
+
+    void setNotes(const String& value)
+    {
+        InspectorObjectBase::setString(ASCIILiteral("notes"), value);
+    }
+
+    void setTimestamp(double value)
+    {
+        InspectorObjectBase::setDouble(ASCIILiteral("timestamp"), value);
+    }
+
+    void setValues(RefPtr<Inspector::InspectorObject> value)
+    {
+        InspectorObjectBase::setObject(ASCIILiteral("values"), WTF::move(value));
+    }
+
+    void setPayload(RefPtr<Inspector::InspectorValue> value)
+    {
+        InspectorObjectBase::setValue(ASCIILiteral("payload"), WTF::move(value));
+    }
+
+    void setError(RefPtr<Inspector::Protocol::Database::Error> value)
+    {
+        InspectorObjectBase::setObject(ASCIILiteral("error"), WTF::move(value));
+    }
+
+    void setErrorList(RefPtr<Inspector::Protocol::Database::ErrorList> value)
+    {
+        InspectorObjectBase::setArray(ASCIILiteral("errorList"), WTF::move(value));
+    }
+};
+
+class ParameterBundle : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        ColumnNamesSet = 1 << 0,
+        NotesSet = 1 << 1,
+        TimestampSet = 1 << 2,
+        ValuesSet = 1 << 3,
+        PayloadSet = 1 << 4,
+        ErrorSet = 1 << 5,
+        ErrorListSet = 1 << 6,
+        AllFieldsSet = (ColumnNamesSet | NotesSet | TimestampSet | ValuesSet | PayloadSet | ErrorSet | ErrorListSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*ParameterBundle*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class ParameterBundle;
+    public:
+
+        Builder<STATE | ColumnNamesSet>& setColumnNames(RefPtr<Inspector::Protocol::Array<String>> value)
+        {
+            COMPILE_ASSERT(!(STATE & ColumnNamesSet), property_columnNames_already_set);
+            m_result->setArray(ASCIILiteral("columnNames"), value);
+            return castState<ColumnNamesSet>();
+        }
+
+        Builder<STATE | NotesSet>& setNotes(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & NotesSet), property_notes_already_set);
+            m_result->setString(ASCIILiteral("notes"), value);
+            return castState<NotesSet>();
+        }
+
+        Builder<STATE | TimestampSet>& setTimestamp(double value)
+        {
+            COMPILE_ASSERT(!(STATE & TimestampSet), property_timestamp_already_set);
+            m_result->setDouble(ASCIILiteral("timestamp"), value);
+            return castState<TimestampSet>();
+        }
+
+        Builder<STATE | ValuesSet>& setValues(RefPtr<Inspector::InspectorObject> value)
+        {
+            COMPILE_ASSERT(!(STATE & ValuesSet), property_values_already_set);
+            m_result->setObject(ASCIILiteral("values"), value);
+            return castState<ValuesSet>();
+        }
+
+        Builder<STATE | PayloadSet>& setPayload(RefPtr<Inspector::InspectorValue> value)
+        {
+            COMPILE_ASSERT(!(STATE & PayloadSet), property_payload_already_set);
+            m_result->setValue(ASCIILiteral("payload"), value);
+            return castState<PayloadSet>();
+        }
+
+        Builder<STATE | ErrorSet>& setError(RefPtr<Inspector::Protocol::Database::Error> value)
+        {
+            COMPILE_ASSERT(!(STATE & ErrorSet), property_error_already_set);
+            m_result->setObject(ASCIILiteral("error"), value);
+            return castState<ErrorSet>();
+        }
+
+        Builder<STATE | ErrorListSet>& setErrorList(RefPtr<Inspector::Protocol::Database::ErrorList> value)
+        {
+            COMPILE_ASSERT(!(STATE & ErrorListSet), property_errorList_already_set);
+            m_result->setArray(ASCIILiteral("errorList"), value);
+            return castState<ErrorListSet>();
+        }
+
+        Ref<ParameterBundle> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(ParameterBundle) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<ParameterBundle>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<ParameterBundle> result = ParameterBundle::create()
+     *     .setColumnNames(...)
+     *     .setNotes(...)
+     *     .setTimestamp(...)
+     *     .setValues(...)
+     *     .setPayload(...)
+     *     .setError(...)
+     *     .setErrorList(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+/* Conflicted names may cause generated getters/setters to clash with built-in InspectorObject methods. */
+class ObjectWithPropertyNameConflicts : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        IntegerSet = 1 << 0,
+        ArraySet = 1 << 1,
+        StringSet = 1 << 2,
+        ValueSet = 1 << 3,
+        ObjectSet = 1 << 4,
+        AllFieldsSet = (IntegerSet | ArraySet | StringSet | ValueSet | ObjectSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*ObjectWithPropertyNameConflicts*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class ObjectWithPropertyNameConflicts;
+    public:
+
+        Builder<STATE | IntegerSet>& setInteger(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & IntegerSet), property_integer_already_set);
+            m_result->setString(ASCIILiteral("integer"), value);
+            return castState<IntegerSet>();
+        }
+
+        Builder<STATE | ArraySet>& setArray(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & ArraySet), property_array_already_set);
+            m_result->setString(ASCIILiteral("array"), value);
+            return castState<ArraySet>();
+        }
+
+        Builder<STATE | StringSet>& setString(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & StringSet), property_string_already_set);
+            m_result->setString(ASCIILiteral("string"), value);
+            return castState<StringSet>();
+        }
+
+        Builder<STATE | ValueSet>& setValue(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & ValueSet), property_value_already_set);
+            m_result->setString(ASCIILiteral("value"), value);
+            return castState<ValueSet>();
+        }
+
+        Builder<STATE | ObjectSet>& setObject(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & ObjectSet), property_object_already_set);
+            m_result->setString(ASCIILiteral("object"), value);
+            return castState<ObjectSet>();
+        }
+
+        Ref<ObjectWithPropertyNameConflicts> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(ObjectWithPropertyNameConflicts) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<ObjectWithPropertyNameConflicts>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<ObjectWithPropertyNameConflicts> result = ObjectWithPropertyNameConflicts::create()
+     *     .setInteger(...)
+     *     .setArray(...)
+     *     .setString(...)
+     *     .setValue(...)
+     *     .setObject(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Database
+
+namespace Test {
+class ParameterBundle : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        ColumnNamesSet = 1 << 0,
+        NotesSet = 1 << 1,
+        TimestampSet = 1 << 2,
+        ValuesSet = 1 << 3,
+        PayloadSet = 1 << 4,
+        ErrorSet = 1 << 5,
+        AllFieldsSet = (ColumnNamesSet | NotesSet | TimestampSet | ValuesSet | PayloadSet | ErrorSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*ParameterBundle*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class ParameterBundle;
+    public:
+
+        Builder<STATE | ColumnNamesSet>& setColumnNames(RefPtr<Inspector::Protocol::Array<String>> value)
+        {
+            COMPILE_ASSERT(!(STATE & ColumnNamesSet), property_columnNames_already_set);
+            m_result->setArray(ASCIILiteral("columnNames"), value);
+            return castState<ColumnNamesSet>();
+        }
+
+        Builder<STATE | NotesSet>& setNotes(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & NotesSet), property_notes_already_set);
+            m_result->setString(ASCIILiteral("notes"), value);
+            return castState<NotesSet>();
+        }
+
+        Builder<STATE | TimestampSet>& setTimestamp(double value)
+        {
+            COMPILE_ASSERT(!(STATE & TimestampSet), property_timestamp_already_set);
+            m_result->setDouble(ASCIILiteral("timestamp"), value);
+            return castState<TimestampSet>();
+        }
+
+        Builder<STATE | ValuesSet>& setValues(RefPtr<Inspector::InspectorObject> value)
+        {
+            COMPILE_ASSERT(!(STATE & ValuesSet), property_values_already_set);
+            m_result->setObject(ASCIILiteral("values"), value);
+            return castState<ValuesSet>();
+        }
+
+        Builder<STATE | PayloadSet>& setPayload(RefPtr<Inspector::InspectorValue> value)
+        {
+            COMPILE_ASSERT(!(STATE & PayloadSet), property_payload_already_set);
+            m_result->setValue(ASCIILiteral("payload"), value);
+            return castState<PayloadSet>();
+        }
+
+        Builder<STATE | ErrorSet>& setError(RefPtr<Inspector::Protocol::Database::Error> value)
+        {
+            COMPILE_ASSERT(!(STATE & ErrorSet), property_error_already_set);
+            m_result->setObject(ASCIILiteral("error"), value);
+            return castState<ErrorSet>();
+        }
+
+        Ref<ParameterBundle> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(ParameterBundle) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<ParameterBundle>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<ParameterBundle> result = ParameterBundle::create()
+     *     .setColumnNames(...)
+     *     .setNotes(...)
+     *     .setTimestamp(...)
+     *     .setValues(...)
+     *     .setPayload(...)
+     *     .setError(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+} // Test
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolDatabaseError;
+@class RWIProtocolDatabaseOptionalParameterBundle;
+@class RWIProtocolDatabaseParameterBundle;
+@class RWIProtocolDatabaseObjectWithPropertyNameConflicts;
+@class RWIProtocolDatabaseDummyObject;
+@class RWIProtocolTestParameterBundle;
+
+
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseError : RWIProtocolJSONObject
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+/* required */ @property (nonatomic, copy) NSString *message;
+/* required */ @property (nonatomic, assign) int code;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseOptionalParameterBundle : RWIProtocolJSONObject
+/* optional */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
+/* optional */ @property (nonatomic, copy) NSString *notes;
+/* optional */ @property (nonatomic, assign) double timestamp;
+/* optional */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
+/* optional */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
+/* optional */ @property (nonatomic, retain) RWIProtocolDatabaseError *error;
+/* optional */ @property (nonatomic, copy) NSArray/*<RWIProtocolDatabaseError>*/ *errorList;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseParameterBundle : RWIProtocolJSONObject
+- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(RWIProtocolDatabaseError *)error errorList:(NSArray/*<RWIProtocolDatabaseError>*/ *)errorList;
+/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
+/* required */ @property (nonatomic, copy) NSString *notes;
+/* required */ @property (nonatomic, assign) double timestamp;
+/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
+/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
+/* required */ @property (nonatomic, retain) RWIProtocolDatabaseError *error;
+/* required */ @property (nonatomic, copy) NSArray/*<RWIProtocolDatabaseError>*/ *errorList;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseObjectWithPropertyNameConflicts : RWIProtocolJSONObject
+- (instancetype)initWithInteger:(NSString *)integer array:(NSString *)array string:(NSString *)string value:(NSString *)value object:(NSString *)object;
+/* required */ @property (nonatomic, copy) NSString *integer;
+/* required */ @property (nonatomic, copy) NSString *array;
+/* required */ @property (nonatomic, copy) NSString *string;
+/* required */ @property (nonatomic, copy) NSString *value;
+/* required */ @property (nonatomic, copy) NSString *object;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolDatabaseDummyObject : RWIProtocolJSONObject
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolTestParameterBundle : RWIProtocolJSONObject
+- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(RWIProtocolDatabaseError *)error;
+/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
+/* required */ @property (nonatomic, copy) NSString *notes;
+/* required */ @property (nonatomic, assign) double timestamp;
+/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
+/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
+/* required */ @property (nonatomic, retain) RWIProtocolDatabaseError *error;
+@end
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolDatabaseError
+
+- (instancetype)initWithMessage:(NSString *)message code:(int)code;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");
+
+    self.message = message;
+    self.code = code;
+
+    return self;
+}
+
+- (void)setMessage:(NSString *)message
+{
+    [super setString:message forKey:@"message"];
+}
+
+- (NSString *)message
+{
+    return [super stringForKey:@"message"];
+}
+
+- (void)setCode:(int)code
+{
+    [super setInteger:code forKey:@"code"];
+}
+
+- (int)code
+{
+    return [super integerForKey:@"code"];
+}
+
+@end
+
+@implementation RWIProtocolDatabaseOptionalParameterBundle
+
+- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
+{
+    [super setInspectorArray:inspectorStringArray(columnNames) forKey:@"columnNames"];
+}
+
+- (NSArray/*<NSString>*/ *)columnNames
+{
+    return objcStringArray([super inspectorArrayForKey:@"columnNames"]);
+}
+
+- (void)setNotes:(NSString *)notes
+{
+    [super setString:notes forKey:@"notes"];
+}
+
+- (NSString *)notes
+{
+    return [super stringForKey:@"notes"];
+}
+
+- (void)setTimestamp:(double)timestamp
+{
+    [super setDouble:timestamp forKey:@"timestamp"];
+}
+
+- (double)timestamp
+{
+    return [super doubleForKey:@"timestamp"];
+}
+
+- (void)setValues:(RWIProtocolJSONObject *)values
+{
+    [super setObject:values forKey:@"values"];
+}
+
+- (RWIProtocolJSONObject *)values
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"values"];
+}
+
+- (void)setPayload:(RWIProtocolJSONObject *)payload
+{
+    [super setObject:payload forKey:@"payload"];
+}
+
+- (RWIProtocolJSONObject *)payload
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"payload"];
+}
+
+- (void)setError:(RWIProtocolDatabaseError *)error
+{
+    [super setObject:error forKey:@"error"];
+}
+
+- (RWIProtocolDatabaseError *)error
+{
+    return (RWIProtocolDatabaseError *)[super objectForKey:@"error"];
+}
+
+- (void)setErrorList:(NSArray/*<RWIProtocolDatabaseError>*/ *)errorList
+{
+    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [RWIProtocolDatabaseError class]);
+    [super setInspectorArray:inspectorObjectArray(errorList) forKey:@"errorList"];
+}
+
+- (NSArray/*<RWIProtocolDatabaseError>*/ *)errorList
+{
+    return objcArray<RWIProtocolDatabaseError>([super inspectorArrayForKey:@"errorList"]);
+}
+
+@end
+
+@implementation RWIProtocolDatabaseParameterBundle
+
+- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(RWIProtocolDatabaseError *)error errorList:(NSArray/*<RWIProtocolDatabaseError>*/ *)errorList;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(columnNames, @"columnNames");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(notes, @"notes");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(values, @"values");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload, @"payload");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(error, @"error");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(errorList, @"errorList");
+    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [RWIProtocolDatabaseError class]);
+
+    self.columnNames = columnNames;
+    self.notes = notes;
+    self.timestamp = timestamp;
+    self.values = values;
+    self.payload = payload;
+    self.error = error;
+    self.errorList = errorList;
+
+    return self;
+}
+
+- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
+{
+    [super setInspectorArray:inspectorStringArray(columnNames) forKey:@"columnNames"];
+}
+
+- (NSArray/*<NSString>*/ *)columnNames
+{
+    return objcStringArray([super inspectorArrayForKey:@"columnNames"]);
+}
+
+- (void)setNotes:(NSString *)notes
+{
+    [super setString:notes forKey:@"notes"];
+}
+
+- (NSString *)notes
+{
+    return [super stringForKey:@"notes"];
+}
+
+- (void)setTimestamp:(double)timestamp
+{
+    [super setDouble:timestamp forKey:@"timestamp"];
+}
+
+- (double)timestamp
+{
+    return [super doubleForKey:@"timestamp"];
+}
+
+- (void)setValues:(RWIProtocolJSONObject *)values
+{
+    [super setObject:values forKey:@"values"];
+}
+
+- (RWIProtocolJSONObject *)values
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"values"];
+}
+
+- (void)setPayload:(RWIProtocolJSONObject *)payload
+{
+    [super setObject:payload forKey:@"payload"];
+}
+
+- (RWIProtocolJSONObject *)payload
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"payload"];
+}
+
+- (void)setError:(RWIProtocolDatabaseError *)error
+{
+    [super setObject:error forKey:@"error"];
+}
+
+- (RWIProtocolDatabaseError *)error
+{
+    return (RWIProtocolDatabaseError *)[super objectForKey:@"error"];
+}
+
+- (void)setErrorList:(NSArray/*<RWIProtocolDatabaseError>*/ *)errorList
+{
+    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [RWIProtocolDatabaseError class]);
+    [super setInspectorArray:inspectorObjectArray(errorList) forKey:@"errorList"];
+}
+
+- (NSArray/*<RWIProtocolDatabaseError>*/ *)errorList
+{
+    return objcArray<RWIProtocolDatabaseError>([super inspectorArrayForKey:@"errorList"]);
+}
+
+@end
+
+@implementation RWIProtocolDatabaseObjectWithPropertyNameConflicts
+
+- (instancetype)initWithInteger:(NSString *)integer array:(NSString *)array string:(NSString *)string value:(NSString *)value object:(NSString *)object;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(integer, @"integer");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(array, @"array");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(string, @"string");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(value, @"value");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(object, @"object");
+
+    self.integer = integer;
+    self.array = array;
+    self.string = string;
+    self.value = value;
+    self.object = object;
+
+    return self;
+}
+
+- (void)setInteger:(NSString *)integer
+{
+    [super setString:integer forKey:@"integer"];
+}
+
+- (NSString *)integer
+{
+    return [super stringForKey:@"integer"];
+}
+
+- (void)setArray:(NSString *)array
+{
+    [super setString:array forKey:@"array"];
+}
+
+- (NSString *)array
+{
+    return [super stringForKey:@"array"];
+}
+
+- (void)setString:(NSString *)string
+{
+    [super setString:string forKey:@"string"];
+}
+
+- (NSString *)string
+{
+    return [super stringForKey:@"string"];
+}
+
+- (void)setValue:(NSString *)value
+{
+    [super setString:value forKey:@"value"];
+}
+
+- (NSString *)value
+{
+    return [super stringForKey:@"value"];
+}
+
+- (void)setObject:(NSString *)object
+{
+    [super setString:object forKey:@"object"];
+}
+
+- (NSString *)object
+{
+    return [super stringForKey:@"object"];
+}
+
+@end
+
+@implementation RWIProtocolDatabaseDummyObject
+
+@end
+
+
+@implementation RWIProtocolTestParameterBundle
+
+- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(RWIProtocolDatabaseError *)error;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(columnNames, @"columnNames");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(notes, @"notes");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(values, @"values");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload, @"payload");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(error, @"error");
+
+    self.columnNames = columnNames;
+    self.notes = notes;
+    self.timestamp = timestamp;
+    self.values = values;
+    self.payload = payload;
+    self.error = error;
+
+    return self;
+}
+
+- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
+{
+    [super setInspectorArray:inspectorStringArray(columnNames) forKey:@"columnNames"];
+}
+
+- (NSArray/*<NSString>*/ *)columnNames
+{
+    return objcStringArray([super inspectorArrayForKey:@"columnNames"]);
+}
+
+- (void)setNotes:(NSString *)notes
+{
+    [super setString:notes forKey:@"notes"];
+}
+
+- (NSString *)notes
+{
+    return [super stringForKey:@"notes"];
+}
+
+- (void)setTimestamp:(double)timestamp
+{
+    [super setDouble:timestamp forKey:@"timestamp"];
+}
+
+- (double)timestamp
+{
+    return [super doubleForKey:@"timestamp"];
+}
+
+- (void)setValues:(RWIProtocolJSONObject *)values
+{
+    [super setObject:values forKey:@"values"];
+}
+
+- (RWIProtocolJSONObject *)values
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"values"];
+}
+
+- (void)setPayload:(RWIProtocolJSONObject *)payload
+{
+    [super setObject:payload forKey:@"payload"];
+}
+
+- (RWIProtocolJSONObject *)payload
+{
+    return (RWIProtocolJSONObject *)[super objectForKey:@"payload"];
+}
+
+- (void)setError:(RWIProtocolDatabaseError *)error
+{
+    [super setObject:error forKey:@"error"];
+}
+
+- (RWIProtocolDatabaseError *)error
+{
+    return (RWIProtocolDatabaseError *)[super objectForKey:@"error"];
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result b/inspector/scripts/tests/expected/type-requiring-runtime-casts.json-result
new file mode 100644 (file)
index 0000000..9eb1d40
--- /dev/null
@@ -0,0 +1,1372 @@
+### Begin File: InspectorAlternateBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorAlternateBackendDispatchers_h
+#define InspectorAlternateBackendDispatchers_h
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#include "InspectorProtocolTypes.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+
+namespace Inspector {
+
+class AlternateBackendDispatcher {
+public:
+    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTF::move(dispatcher); }
+    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
+private:
+    RefPtr<BackendDispatcher> m_backendDispatcher;
+};
+
+
+
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+
+#endif // !defined(InspectorAlternateBackendDispatchers_h)
+### End File: InspectorAlternateBackendDispatchers.h
+
+### Begin File: InspectorBackendCommands.js
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+// Test.
+InspectorBackend.registerEnum("Test.UncastedAnimals", {Pigs: "Pigs", Cows: "Cows", Cats: "Cats", Hens: "Hens"});
+InspectorBackend.registerEnum("Test.CastedAnimals", {Ducks: "Ducks", Hens: "Hens", Crows: "Crows", Flamingos: "Flamingos"});
+### End File: InspectorBackendCommands.js
+
+### Begin File: InspectorBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorBackendDispatchers_h
+#define InspectorBackendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorBackendDispatcher.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+typedef String ErrorString;
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorBackendDispatchers_h)
+### End File: InspectorBackendDispatchers.h
+
+### Begin File: InspectorBackendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorBackendDispatchers.h"
+
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+#include "InspectorAlternateBackendDispatchers.h"
+#endif
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: InspectorBackendDispatchers.cpp
+
+### Begin File: InspectorFrontendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorFrontendDispatchers_h
+#define InspectorFrontendDispatchers_h
+
+#include "InspectorProtocolObjects.h"
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorValues.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendDispatchers_h)
+### End File: InspectorFrontendDispatchers.h
+
+### Begin File: InspectorFrontendDispatchers.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorFrontendDispatchers.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+} // namespace Inspector
+
+### End File: InspectorFrontendDispatchers.cpp
+
+### Begin File: InspectorProtocolObjects.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#ifndef InspectorProtocolObjects_h
+#define InspectorProtocolObjects_h
+
+#include <inspector/InspectorProtocolTypes.h>
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+
+
+namespace Protocol {
+
+// Forward declarations.
+namespace Test {
+class RecursiveObject1;
+class RecursiveObject2;
+class TypeNeedingCast;
+enum class CastedAnimals;
+enum class UncastedAnimals;
+} // Test
+// End of forward declarations.
+
+
+// Typedefs.
+namespace Test {
+typedef int CastedObjectId;
+typedef int UncastedObjectId;
+} // Test
+// End of typedefs.
+
+String getEnumConstantValue(int code);
+
+template<typename T> String getEnumConstantValue(T enumValue)
+{
+    return getEnumConstantValue(static_cast<int>(enumValue));
+}
+
+namespace Test {
+/* A dummy type that requires runtime casts, and forces non-primitive referenced types to also emit runtime cast helpers. */
+class TypeNeedingCast : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        StringSet = 1 << 0,
+        NumberSet = 1 << 1,
+        AnimalsSet = 1 << 2,
+        IdSet = 1 << 3,
+        TreeSet = 1 << 4,
+        AllFieldsSet = (StringSet | NumberSet | AnimalsSet | IdSet | TreeSet)
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*TypeNeedingCast*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class TypeNeedingCast;
+    public:
+
+        Builder<STATE | StringSet>& setString(const String& value)
+        {
+            COMPILE_ASSERT(!(STATE & StringSet), property_string_already_set);
+            m_result->setString(ASCIILiteral("string"), value);
+            return castState<StringSet>();
+        }
+
+        Builder<STATE | NumberSet>& setNumber(int value)
+        {
+            COMPILE_ASSERT(!(STATE & NumberSet), property_number_already_set);
+            m_result->setInteger(ASCIILiteral("number"), value);
+            return castState<NumberSet>();
+        }
+
+        Builder<STATE | AnimalsSet>& setAnimals(Inspector::Protocol::Test::CastedAnimals value)
+        {
+            COMPILE_ASSERT(!(STATE & AnimalsSet), property_animals_already_set);
+            m_result->setString(ASCIILiteral("animals"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));
+            return castState<AnimalsSet>();
+        }
+
+        Builder<STATE | IdSet>& setId(int value)
+        {
+            COMPILE_ASSERT(!(STATE & IdSet), property_id_already_set);
+            m_result->setInteger(ASCIILiteral("id"), value);
+            return castState<IdSet>();
+        }
+
+        Builder<STATE | TreeSet>& setTree(RefPtr<Inspector::Protocol::Test::RecursiveObject1> value)
+        {
+            COMPILE_ASSERT(!(STATE & TreeSet), property_tree_already_set);
+            m_result->setObject(ASCIILiteral("tree"), value);
+            return castState<TreeSet>();
+        }
+
+        Ref<TypeNeedingCast> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(TypeNeedingCast) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<TypeNeedingCast>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<TypeNeedingCast> result = TypeNeedingCast::create()
+     *     .setString(...)
+     *     .setNumber(...)
+     *     .setAnimals(...)
+     *     .setId(...)
+     *     .setTree(...)
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+};
+
+/*  */
+enum class UncastedAnimals {
+    Pigs = 4,
+    Cows = 5,
+    Cats = 6,
+    Hens = 1,
+}; // enum class UncastedAnimals
+/*  */
+enum class CastedAnimals {
+    Ducks = 0,
+    Hens = 1,
+    Crows = 2,
+    Flamingos = 3,
+}; // enum class CastedAnimals
+class RecursiveObject1 : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        AllFieldsSet = 0
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*RecursiveObject1*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class RecursiveObject1;
+    public:
+
+        Ref<RecursiveObject1> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(RecursiveObject1) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<RecursiveObject1>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<RecursiveObject1> result = RecursiveObject1::create()
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+
+    void setObj(RefPtr<Inspector::Protocol::Test::RecursiveObject2> value)
+    {
+        InspectorObjectBase::setObject(ASCIILiteral("obj"), WTF::move(value));
+    }
+};
+
+class RecursiveObject2 : public Inspector::InspectorObjectBase {
+public:
+    enum {
+        NoFieldsSet = 0,
+        AllFieldsSet = 0
+    };
+
+    template<int STATE>
+    class Builder {
+    private:
+        RefPtr<InspectorObject> m_result;
+
+        template<int STEP> Builder<STATE | STEP>& castState()
+        {
+            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
+        }
+
+        Builder(Ref</*RecursiveObject2*/InspectorObject>&& object)
+            : m_result(WTF::move(object))
+        {
+            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
+        }
+        friend class RecursiveObject2;
+    public:
+
+        Ref<RecursiveObject2> release()
+        {
+            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
+            COMPILE_ASSERT(sizeof(RecursiveObject2) == sizeof(InspectorObject), cannot_cast);
+
+            Ref<InspectorObject> result = m_result.releaseNonNull();
+            return WTF::move(*reinterpret_cast<Ref<RecursiveObject2>*>(&result));
+        }
+    };
+
+    /*
+     * Synthetic constructor:
+     * Ref<RecursiveObject2> result = RecursiveObject2::create()
+     *     .release();
+     */
+    static Builder<NoFieldsSet> create()
+    {
+        return Builder<NoFieldsSet>(InspectorObject::create());
+    }
+
+    void setObj(RefPtr<Inspector::Protocol::Test::RecursiveObject1> value)
+    {
+        InspectorObjectBase::setObject(ASCIILiteral("obj"), WTF::move(value));
+    }
+};
+
+} // Test
+
+template<> struct BindingTraits<Inspector::Protocol::Test::CastedAnimals> {
+#if !ASSERT_DISABLED
+static void assertValueHasExpectedType(Inspector::InspectorValue*);
+#endif // !ASSERT_DISABLED
+};
+template<> struct BindingTraits<Inspector::Protocol::Test::TypeNeedingCast> {
+static RefPtr<Inspector::Protocol::Test::TypeNeedingCast> runtimeCast(RefPtr<Inspector::InspectorValue>&& value);
+#if !ASSERT_DISABLED
+static void assertValueHasExpectedType(Inspector::InspectorValue*);
+#endif // !ASSERT_DISABLED
+};
+template<> struct BindingTraits<Inspector::Protocol::Test::RecursiveObject1> {
+#if !ASSERT_DISABLED
+static void assertValueHasExpectedType(Inspector::InspectorValue*);
+#endif // !ASSERT_DISABLED
+};
+template<> struct BindingTraits<Inspector::Protocol::Test::RecursiveObject2> {
+#if !ASSERT_DISABLED
+static void assertValueHasExpectedType(Inspector::InspectorValue*);
+#endif // !ASSERT_DISABLED
+};
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+#endif // !defined(InspectorProtocolObjects_h)
+### End File: InspectorProtocolObjects.h
+
+### Begin File: InspectorProtocolObjects.cpp
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include "config.h"
+#include "InspectorProtocolObjects.h"
+
+#include <wtf/text/CString.h>
+
+namespace Inspector {
+
+namespace Protocol {
+
+static const char* const enum_constant_values[] = {
+    "Ducks",
+    "Hens",
+    "Crows",
+    "Flamingos",
+    "Pigs",
+    "Cows",
+    "Cats",
+};
+
+String getEnumConstantValue(int code) {
+    return enum_constant_values[code];
+}
+
+
+
+#if !ASSERT_DISABLED
+void BindingTraits<Inspector::Protocol::Test::CastedAnimals>::assertValueHasExpectedType(Inspector::InspectorValue* value)
+{
+    ASSERT_ARG(value, value);
+    String result;
+    bool castSucceeded = value->asString(result);
+    ASSERT(castSucceeded);
+    ASSERT(result == "Ducks" || result == "Hens" || result == "Crows" || result == "Flamingos");
+}
+#endif // !ASSERT_DISABLED
+
+#if !ASSERT_DISABLED
+void BindingTraits<Inspector::Protocol::Test::TypeNeedingCast>::assertValueHasExpectedType(Inspector::InspectorValue* value)
+{
+    ASSERT_ARG(value, value);
+    RefPtr<InspectorObject> object;
+    bool castSucceeded = value->asObject(object);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+    {
+        InspectorObject::iterator stringPos = object->find(ASCIILiteral("string"));
+        ASSERT(stringPos != object->end());
+        BindingTraits<String>::assertValueHasExpectedType(stringPos->value.get());
+    }
+    {
+        InspectorObject::iterator numberPos = object->find(ASCIILiteral("number"));
+        ASSERT(numberPos != object->end());
+        BindingTraits<int>::assertValueHasExpectedType(numberPos->value.get());
+    }
+    {
+        InspectorObject::iterator animalsPos = object->find(ASCIILiteral("animals"));
+        ASSERT(animalsPos != object->end());
+        BindingTraits<Inspector::Protocol::Test::CastedAnimals>::assertValueHasExpectedType(animalsPos->value.get());
+    }
+    {
+        InspectorObject::iterator idPos = object->find(ASCIILiteral("id"));
+        ASSERT(idPos != object->end());
+        BindingTraits<int>::assertValueHasExpectedType(idPos->value.get());
+    }
+    {
+        InspectorObject::iterator treePos = object->find(ASCIILiteral("tree"));
+        ASSERT(treePos != object->end());
+        BindingTraits<Inspector::Protocol::Test::RecursiveObject1>::assertValueHasExpectedType(treePos->value.get());
+    }
+
+    int foundPropertiesCount = 5;
+    if (foundPropertiesCount != object->size())
+        FATAL("Unexpected properties in object: %s\n", object->toJSONString().ascii().data());
+}
+#endif // !ASSERT_DISABLED
+
+RefPtr<Inspector::Protocol::Test::TypeNeedingCast> BindingTraits<Inspector::Protocol::Test::TypeNeedingCast>::runtimeCast(RefPtr<InspectorValue>&& value)
+{
+    RefPtr<InspectorObject> result;
+    bool castSucceeded = value->asObject(result);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+#if !ASSERT_DISABLED
+    BindingTraits<Inspector::Protocol::Test::TypeNeedingCast>::assertValueHasExpectedType(result.get());
+#endif  // !ASSERT_DISABLED
+    COMPILE_ASSERT(sizeof(Inspector::Protocol::Test::TypeNeedingCast) == sizeof(InspectorObjectBase), type_cast_problem);
+    return static_cast<Inspector::Protocol::Test::TypeNeedingCast*>(static_cast<InspectorObjectBase*>(result.get()));
+}
+
+
+#if !ASSERT_DISABLED
+void BindingTraits<Inspector::Protocol::Test::RecursiveObject1>::assertValueHasExpectedType(Inspector::InspectorValue* value)
+{
+    ASSERT_ARG(value, value);
+    RefPtr<InspectorObject> object;
+    bool castSucceeded = value->asObject(object);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+    int foundPropertiesCount = 0;
+    {
+        InspectorObject::iterator objPos = object->find(ASCIILiteral("obj"));
+        if (objPos != object->end()) {
+            BindingTraits<Inspector::Protocol::Test::RecursiveObject2>::assertValueHasExpectedType(objPos->value.get());
+            ++foundPropertiesCount;
+        }
+    }
+    if (foundPropertiesCount != object->size())
+        FATAL("Unexpected properties in object: %s\n", object->toJSONString().ascii().data());
+}
+#endif // !ASSERT_DISABLED
+
+#if !ASSERT_DISABLED
+void BindingTraits<Inspector::Protocol::Test::RecursiveObject2>::assertValueHasExpectedType(Inspector::InspectorValue* value)
+{
+    ASSERT_ARG(value, value);
+    RefPtr<InspectorObject> object;
+    bool castSucceeded = value->asObject(object);
+    ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+    int foundPropertiesCount = 0;
+    {
+        InspectorObject::iterator objPos = object->find(ASCIILiteral("obj"));
+        if (objPos != object->end()) {
+            BindingTraits<Inspector::Protocol::Test::RecursiveObject1>::assertValueHasExpectedType(objPos->value.get());
+            ++foundPropertiesCount;
+        }
+    }
+    if (foundPropertiesCount != object->size())
+        FATAL("Unexpected properties in object: %s\n", object->toJSONString().ascii().data());
+}
+#endif // !ASSERT_DISABLED
+
+} // namespace Protocol
+
+} // namespace Inspector
+
+### End File: InspectorProtocolObjects.cpp
+
+### Begin File: RWIProtocolBackendDispatchers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#include <wtf/RetainPtr.h>
+
+
+
+namespace Inspector {
+
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.h
+
+### Begin File: RWIProtocolConfiguration.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolConfiguration.h"
+
+#import "RWIProtocolInternal.h"
+#import "RWIProtocolBackendDispatchers.h"
+#import <JavaScriptCore/AlternateDispatchableAgent.h>
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
+#import <JavaScriptCore/InspectorBackendDispatchers.h>
+
+using namespace Inspector;
+
+@implementation RWIProtocolConfiguration
+{
+    AugmentableInspectorController* _controller;
+}
+
+- (instancetype)initWithController:(AugmentableInspectorController*)controller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    ASSERT(controller);
+    _controller = controller;
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+@end
+
+
+### End File: RWIProtocolConfiguration.mm
+
+### Begin File: RWIProtocolConfiguration.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolConfiguration : NSObject
+@end
+
+
+### End File: RWIProtocolConfiguration.h
+
+### Begin File: RWIProtocolBackendDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolBackendDispatchers.h"
+
+#include "RWIProtocolInternal.h"
+#include "RWIProtocolEnumConversionHelpers.h"
+#include <JavaScriptCore/InspectorFrontendChannel.h>
+#include <JavaScriptCore/InspectorValues.h>
+
+namespace Inspector {
+
+
+
+} // namespace Inspector
+
+### End File: RWIProtocolBackendDispatchers.mm
+
+### Begin File: RWIProtocolEnumConversionHelpers.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocolArrayConversionHelpers.h"
+
+namespace Inspector {
+
+template<typename ObjCEnumType>
+ObjCEnumType fromProtocolString(const String& value);
+
+
+inline String toProtocolString(RWIProtocolTestUncastedAnimals value)
+{
+    switch(value) {
+    case RWIProtocolTestUncastedAnimalsPigs:
+        return ASCIILiteral("Pigs");
+    case RWIProtocolTestUncastedAnimalsCows:
+        return ASCIILiteral("Cows");
+    case RWIProtocolTestUncastedAnimalsCats:
+        return ASCIILiteral("Cats");
+    case RWIProtocolTestUncastedAnimalsHens:
+        return ASCIILiteral("Hens");
+    }
+}
+
+template<>
+inline RWIProtocolTestUncastedAnimals fromProtocolString(const String& value)
+{
+    if (value == "Pigs")
+        return RWIProtocolTestUncastedAnimalsPigs;
+    if (value == "Cows")
+        return RWIProtocolTestUncastedAnimalsCows;
+    if (value == "Cats")
+        return RWIProtocolTestUncastedAnimalsCats;
+    if (value == "Hens")
+        return RWIProtocolTestUncastedAnimalsHens;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolTestUncastedAnimalsPigs;
+}
+
+inline String toProtocolString(RWIProtocolTestCastedAnimals value)
+{
+    switch(value) {
+    case RWIProtocolTestCastedAnimalsDucks:
+        return ASCIILiteral("Ducks");
+    case RWIProtocolTestCastedAnimalsHens:
+        return ASCIILiteral("Hens");
+    case RWIProtocolTestCastedAnimalsCrows:
+        return ASCIILiteral("Crows");
+    case RWIProtocolTestCastedAnimalsFlamingos:
+        return ASCIILiteral("Flamingos");
+    }
+}
+
+template<>
+inline RWIProtocolTestCastedAnimals fromProtocolString(const String& value)
+{
+    if (value == "Ducks")
+        return RWIProtocolTestCastedAnimalsDucks;
+    if (value == "Hens")
+        return RWIProtocolTestCastedAnimalsHens;
+    if (value == "Crows")
+        return RWIProtocolTestCastedAnimalsCrows;
+    if (value == "Flamingos")
+        return RWIProtocolTestCastedAnimalsFlamingos;
+    ASSERT_NOT_REACHED();
+    return RWIProtocolTestCastedAnimalsDucks;
+}
+
+} // namespace Inspector
+
+### End File: RWIProtocolEnumConversionHelpers.h
+
+### Begin File: RWIProtocolEventDispatchers.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorFrontendChannel.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+using namespace Inspector;
+
+
+
+
+### End File: RWIProtocolEventDispatchers.mm
+
+### Begin File: RWIProtocol.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import <Foundation/Foundation.h>
+
+#import <WebInspector/RWIProtocolJSONObject.h>
+
+
+@class RWIProtocolTestTypeNeedingCast;
+@class RWIProtocolTestRecursiveObject1;
+@class RWIProtocolTestRecursiveObject2;
+
+
+typedef NS_ENUM(NSInteger, RWIProtocolTestUncastedAnimals) {
+    RWIProtocolTestUncastedAnimalsPigs,
+    RWIProtocolTestUncastedAnimalsCows,
+    RWIProtocolTestUncastedAnimalsCats,
+    RWIProtocolTestUncastedAnimalsHens,
+};
+
+typedef NS_ENUM(NSInteger, RWIProtocolTestCastedAnimals) {
+    RWIProtocolTestCastedAnimalsDucks,
+    RWIProtocolTestCastedAnimalsHens,
+    RWIProtocolTestCastedAnimalsCrows,
+    RWIProtocolTestCastedAnimalsFlamingos,
+};
+
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolTestTypeNeedingCast : RWIProtocolJSONObject
+- (instancetype)initWithString:(NSString *)string number:(int)number animals:(RWIProtocolTestCastedAnimals)animals identifier:(int)identifier tree:(RWIProtocolTestRecursiveObject1 *)tree;
+/* required */ @property (nonatomic, copy) NSString *string;
+/* required */ @property (nonatomic, assign) int number;
+/* required */ @property (nonatomic, assign) RWIProtocolTestCastedAnimals animals;
+/* required */ @property (nonatomic, assign) int identifier;
+/* required */ @property (nonatomic, retain) RWIProtocolTestRecursiveObject1 *tree;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolTestRecursiveObject1 : RWIProtocolJSONObject
+/* optional */ @property (nonatomic, retain) RWIProtocolTestRecursiveObject2 *obj;
+@end
+
+__attribute__((visibility ("default")))
+@interface RWIProtocolTestRecursiveObject2 : RWIProtocolJSONObject
+/* optional */ @property (nonatomic, retain) RWIProtocolTestRecursiveObject1 *obj;
+@end
+
+
+
+
+
+
+### End File: RWIProtocol.h
+
+### Begin File: RWIProtocolTypes.mm
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "config.h"
+#import "RWIProtocolInternal.h"
+
+#import "RWIProtocolEnumConversionHelpers.h"
+#import <JavaScriptCore/InspectorValues.h>
+#import <wtf/Assertions.h>
+
+using namespace Inspector;
+
+
+@implementation RWIProtocolTestTypeNeedingCast
+
+- (instancetype)initWithString:(NSString *)string number:(int)number animals:(RWIProtocolTestCastedAnimals)animals identifier:(int)identifier tree:(RWIProtocolTestRecursiveObject1 *)tree;
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(string, @"string");
+    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(tree, @"tree");
+
+    self.string = string;
+    self.number = number;
+    self.animals = animals;
+    self.identifier = identifier;
+    self.tree = tree;
+
+    return self;
+}
+
+- (void)setString:(NSString *)string
+{
+    [super setString:string forKey:@"string"];
+}
+
+- (NSString *)string
+{
+    return [super stringForKey:@"string"];
+}
+
+- (void)setNumber:(int)number
+{
+    [super setInteger:number forKey:@"number"];
+}
+
+- (int)number
+{
+    return [super integerForKey:@"number"];
+}
+
+- (void)setAnimals:(RWIProtocolTestCastedAnimals)animals
+{
+    [super setString:toProtocolString(animals) forKey:@"animals"];
+}
+
+- (RWIProtocolTestCastedAnimals)animals
+{
+    return fromProtocolString<RWIProtocolTestCastedAnimals>([super stringForKey:@"animals"]);
+}
+
+- (void)setIdentifier:(int)identifier
+{
+    [super setInteger:identifier forKey:@"id"];
+}
+
+- (int)identifier
+{
+    return [super integerForKey:@"id"];
+}
+
+- (void)setTree:(RWIProtocolTestRecursiveObject1 *)tree
+{
+    [super setObject:tree forKey:@"tree"];
+}
+
+- (RWIProtocolTestRecursiveObject1 *)tree
+{
+    return (RWIProtocolTestRecursiveObject1 *)[super objectForKey:@"tree"];
+}
+
+@end
+
+@implementation RWIProtocolTestRecursiveObject1
+
+- (void)setObj:(RWIProtocolTestRecursiveObject2 *)obj
+{
+    [super setObject:obj forKey:@"obj"];
+}
+
+- (RWIProtocolTestRecursiveObject2 *)obj
+{
+    return (RWIProtocolTestRecursiveObject2 *)[super objectForKey:@"obj"];
+}
+
+@end
+
+@implementation RWIProtocolTestRecursiveObject2
+
+- (void)setObj:(RWIProtocolTestRecursiveObject1 *)obj
+{
+    [super setObject:obj forKey:@"obj"];
+}
+
+- (RWIProtocolTestRecursiveObject1 *)obj
+{
+    return (RWIProtocolTestRecursiveObject1 *)[super objectForKey:@"obj"];
+}
+
+@end
+
+
+### End File: RWIProtocolTypes.mm
+
+### Begin File: RWIProtocolInternal.h
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// DO NOT EDIT THIS FILE. It is automatically generated from type-requiring-runtime-casts.json
+// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
+
+#import "RWIProtocol.h"
+#import "RWIProtocolJSONObjectInternal.h"
+#import <JavaScriptCore/AugmentableInspectorController.h>
+#import <JavaScriptCore/InspectorValues.h>
+
+
+
+
+### End File: RWIProtocolInternal.h
diff --git a/inspector/scripts/tests/fail-on-domain-availability.json b/inspector/scripts/tests/fail-on-domain-availability.json
new file mode 100644 (file)
index 0000000..36ee2c6
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "domain": "WebOnly",
+    "availability": "webb",
+    "commands": [
+        {
+            "name": "enable"
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-duplicate-command-call-parameter-names.json b/inspector/scripts/tests/fail-on-duplicate-command-call-parameter-names.json
new file mode 100644 (file)
index 0000000..bab76ca
--- /dev/null
@@ -0,0 +1,16 @@
+{
+    "domain": "Overlay",
+    "commands": [
+        {
+            "name": "processPoints",
+            "parameters": [
+                { "name": "point", "type": "number" },
+                { "name": "point", "type": "number" }
+            ],
+            "returns": [
+                { "name": "result1", "type": "string" },
+                { "name": "result2", "type": "string" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-duplicate-command-return-parameter-names.json b/inspector/scripts/tests/fail-on-duplicate-command-return-parameter-names.json
new file mode 100644 (file)
index 0000000..c8bb15c
--- /dev/null
@@ -0,0 +1,16 @@
+{
+    "domain": "Overlay",
+    "commands": [
+        {
+            "name": "processPoints",
+            "parameters": [
+                { "name": "point1", "type": "number" },
+                { "name": "point2", "type": "number" }
+            ],
+            "returns": [
+                { "name": "result", "type": "string" },
+                { "name": "result", "type": "string" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-duplicate-event-parameter-names.json b/inspector/scripts/tests/fail-on-duplicate-event-parameter-names.json
new file mode 100644 (file)
index 0000000..d3d3b3c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    "domain": "Overlay",
+    "events": [
+        {
+            "name": "processedPoints",
+            "parameters": [
+                { "name": "point", "type": "number" },
+                { "name": "point", "type": "number" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-duplicate-type-declarations.json b/inspector/scripts/tests/fail-on-duplicate-type-declarations.json
new file mode 100644 (file)
index 0000000..702fc6a
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "string",
+            "description": "Unique object identifier."
+        },
+        {
+            "id": "RemoteObjectId",
+            "type": "string",
+            "description": "Unique object identifier."
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-duplicate-type-member-names.json b/inspector/scripts/tests/fail-on-duplicate-type-member-names.json
new file mode 100644 (file)
index 0000000..aebacee
--- /dev/null
@@ -0,0 +1,15 @@
+[
+{
+    "domain": "OverlayTypes",
+    "types": [
+        {
+            "id": "Point",
+            "type": "object",
+            "properties": [
+                { "name": "x", "type": "integer" },
+                { "name": "x", "type": "integer" }
+            ]
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/fail-on-enum-with-no-values.json b/inspector/scripts/tests/fail-on-enum-with-no-values.json
new file mode 100644 (file)
index 0000000..232a7c3
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "PrimaryColors",
+            "type": "string",
+            "enum": []
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-string-typed-optional-parameter-flag.json b/inspector/scripts/tests/fail-on-string-typed-optional-parameter-flag.json
new file mode 100644 (file)
index 0000000..4012c79
--- /dev/null
@@ -0,0 +1,18 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "DatabaseId",
+            "type": "string",
+            "description": "Unique identifier of Database object."
+        }
+    ],
+    "events": [
+        {
+            "name": "didExecuteOptionalParameters",
+            "parameters": [
+                { "name": "columnNames", "type": "string", "optional": "true" }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-string-typed-optional-type-member.json b/inspector/scripts/tests/fail-on-string-typed-optional-type-member.json
new file mode 100644 (file)
index 0000000..ca3ef28
--- /dev/null
@@ -0,0 +1,16 @@
+[
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code.", "optional": "false" }
+            ]
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/fail-on-type-declaration-using-type-reference.json b/inspector/scripts/tests/fail-on-type-declaration-using-type-reference.json
new file mode 100644 (file)
index 0000000..19b7590
--- /dev/null
@@ -0,0 +1,13 @@
+[
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "object",
+            "$ref": "SomeType",
+            "description": "Unique object identifier."
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/fail-on-type-with-lowercase-name.json b/inspector/scripts/tests/fail-on-type-with-lowercase-name.json
new file mode 100644 (file)
index 0000000..531901e
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "domain": "Database",
+    "types": [
+        {
+            "id": "databaseId",
+            "type": "integer",
+            "description": "Unique identifier of Database object."
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/fail-on-unknown-type-reference-in-type-declaration.json b/inspector/scripts/tests/fail-on-unknown-type-reference-in-type-declaration.json
new file mode 100644 (file)
index 0000000..d6887a2
--- /dev/null
@@ -0,0 +1,12 @@
+[
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "dragon",
+            "description": "Unique object identifier."
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/fail-on-unknown-type-reference-in-type-member.json b/inspector/scripts/tests/fail-on-unknown-type-reference-in-type-member.json
new file mode 100644 (file)
index 0000000..b817db5
--- /dev/null
@@ -0,0 +1,15 @@
+[
+{
+    "domain": "Fantasy",
+    "types": [
+        {
+            "id": "DragonEgg",
+            "type": "object",
+            "description": "A dragon egg.",
+            "properties": [
+                { "name": "color", "$ref": "Color" }
+            ]
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/generate-domains-with-feature-guards.json b/inspector/scripts/tests/generate-domains-with-feature-guards.json
new file mode 100644 (file)
index 0000000..67cf8e5
--- /dev/null
@@ -0,0 +1,36 @@
+[
+{
+    "domain": "Network1",
+    "featureGuard": "PLATFORM(WEB_COMMANDS)",
+    "commands": [
+        {
+            "name": "loadResource",
+            "description": "Loads a resource in the context of a frame on the inspected page without cross origin checks."
+        }
+    ]
+},
+{
+    "domain": "Network2",
+    "featureGuard": "PLATFORM(WEB_TYPES)",
+    "types": [
+        {
+            "id": "NetworkError",
+            "type": "object",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        }
+    ]
+},
+{
+    "domain": "Network3",
+    "featureGuard": "PLATFORM(WEB_EVENTS)",
+    "events": [
+        {
+            "name": "resourceLoaded",
+            "description": "A resource was loaded."
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/same-type-id-different-domain.json b/inspector/scripts/tests/same-type-id-different-domain.json
new file mode 100644 (file)
index 0000000..3bf4dff
--- /dev/null
@@ -0,0 +1,22 @@
+[
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "string",
+            "description": "Unique object identifier."
+        }
+    ]
+},
+{
+    "domain": "Runtime2",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "string",
+            "description": "Unique object identifier."
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/shadowed-optional-type-setters.json b/inspector/scripts/tests/shadowed-optional-type-setters.json
new file mode 100644 (file)
index 0000000..20a0c15
--- /dev/null
@@ -0,0 +1,31 @@
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "KeyPath",
+            "type": "object",
+            "description": "Key path.",
+            "properties": [
+                {
+                    "name": "type",
+                    "type": "string",
+                    "enum": ["null", "string", "array"],
+                    "description": "Key path type."
+                },
+                {
+                    "name": "string",
+                    "type": "string",
+                    "optional": true,
+                    "description": "String value."
+                },
+                {
+                    "name": "array",
+                    "type": "array",
+                    "optional": true,
+                    "items": { "type": "string" },
+                    "description": "Array value."
+                }
+            ]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/type-declaration-aliased-primitive-type.json b/inspector/scripts/tests/type-declaration-aliased-primitive-type.json
new file mode 100644 (file)
index 0000000..cbc9d53
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "RemoteObjectId",
+            "type": "integer",
+            "description": "Unique object identifier."
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/type-declaration-array-type.json b/inspector/scripts/tests/type-declaration-array-type.json
new file mode 100644 (file)
index 0000000..cfb08bd
--- /dev/null
@@ -0,0 +1,50 @@
+[
+{
+    "domain": "Debugger",
+    "types": [
+        {
+            "id": "BreakpointId",
+            "type": "integer"
+        },
+        {
+            "id": "Reason",
+            "type": "string",
+            "enum": ["Died", "Fainted", "Hungry"]
+        }
+    ]
+},
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "ObjectId",
+            "type": "integer"
+        },
+        {
+            "id": "LuckyNumbers",
+            "type": "array",
+            "items": { "type": "integer" }
+        },
+        {
+            "id": "BabyNames",
+            "type": "array",
+            "items": { "type": "string" }
+        },
+        {
+            "id": "NewObjects",
+            "type": "array",
+            "items": { "$ref": "ObjectId" }
+        },
+        {
+            "id": "OldObjects",
+            "type": "array",
+            "items": { "$ref": "Debugger.BreakpointId" }
+        },
+        {
+            "id": "StopReasons",
+            "type": "array",
+            "items": { "$ref": "Debugger.Reason" }
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/type-declaration-enum-type.json b/inspector/scripts/tests/type-declaration-enum-type.json
new file mode 100644 (file)
index 0000000..9f0aee9
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "domain": "Runtime",
+    "types": [
+        {
+            "id": "FarmAnimals",
+            "type": "string",
+            "enum": ["Pigs", "Cows", "Cats", "Hens"]
+        },
+        {
+            "id": "TwoLeggedAnimals",
+            "type": "string",
+            "enum": ["Ducks", "Hens", "Crows", "Flamingos"]
+        }
+    ]
+}
diff --git a/inspector/scripts/tests/type-declaration-object-type.json b/inspector/scripts/tests/type-declaration-object-type.json
new file mode 100644 (file)
index 0000000..1783091
--- /dev/null
@@ -0,0 +1,83 @@
+[
+{
+    "domain": "Database",
+    "description": "Test type builder generation of various object types.",
+    "types": [
+        {
+            "id": "Error",
+            "type": "object",
+            "description": "Database error.",
+            "properties": [
+                { "name": "message", "type": "string", "description": "Error message." },
+                { "name": "code", "type": "integer", "description": "Error code." }
+            ]
+        },
+        {
+            "id": "ErrorList",
+            "type": "array",
+            "items": { "$ref": "Error" }
+        },
+        {
+            "id": "OptionalParameterBundle",
+            "type": "object",
+            "properties": [
+                { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } },
+                { "name": "notes", "type": "string", "optional": true },
+                { "name": "timestamp", "type": "number", "optional": true },
+                { "name": "values", "type": "object", "optional": true },
+                { "name": "payload", "type": "any", "optional": true },
+                { "name": "error", "$ref": "Error", "optional": true },
+                { "name": "errorList", "$ref": "ErrorList", "optional": true }
+            ]
+        },
+        {
+            "id": "ParameterBundle",
+            "type": "object",
+            "properties": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "error", "$ref": "Error" },
+                { "name": "errorList", "$ref": "ErrorList" }
+            ]
+        },
+        {
+            "id": "ObjectWithPropertyNameConflicts",
+            "description": "Conflicted names may cause generated getters/setters to clash with built-in InspectorObject methods.",
+            "type": "object",
+            "properties": [
+                { "name": "integer", "type": "string" },
+                { "name": "array", "type": "string" },
+                { "name": "string", "type": "string" },
+                { "name": "value", "type": "string" },
+                { "name": "object", "type": "string" }
+            ]
+        },
+        {
+            "id": "DummyObject",
+            "description": "An open object that doesn't have any predefined fields.",
+            "type": "object"
+        }
+    ]
+},
+{
+    "domain": "Test",
+    "description": "Test the generation of special behaviors that only apply to specific classes.",
+    "types": [
+        {
+            "id": "ParameterBundle",
+            "type": "object",
+            "properties": [
+                { "name": "columnNames", "type": "array", "items": { "type": "string" } },
+                { "name": "notes", "type": "string" },
+                { "name": "timestamp", "type": "number" },
+                { "name": "values", "type": "object" },
+                { "name": "payload", "type": "any" },
+                { "name": "error", "$ref": "Database.Error" }
+            ]
+        }
+    ]
+}
+]
diff --git a/inspector/scripts/tests/type-requiring-runtime-casts.json b/inspector/scripts/tests/type-requiring-runtime-casts.json
new file mode 100644 (file)
index 0000000..83d94be
--- /dev/null
@@ -0,0 +1,51 @@
+[
+{
+    "domain": "Test",
+    "types": [
+        {
+            "id": "TypeNeedingCast",
+            "type": "object",
+            "description": "A dummy type that requires runtime casts, and forces non-primitive referenced types to also emit runtime cast helpers.",
+            "properties": [
+                { "name": "string", "type": "string", "description": "String member." },
+                { "name": "number", "type": "integer", "description": "Number member." },
+                { "name": "animals", "$ref": "CastedAnimals", "description": "Enum member." },
+                { "name": "id", "$ref": "CastedObjectId", "description": "Aliased member." },
+                { "name": "tree", "$ref": "RecursiveObject1", "description": "Recursive object member." }
+            ]
+        },
+        {
+            "id": "CastedObjectId",
+            "type": "integer"
+        },
+        {
+            "id": "UncastedObjectId",
+            "type": "integer"
+        },
+        {
+            "id": "UncastedAnimals",
+            "type": "string",
+            "enum": ["Pigs", "Cows", "Cats", "Hens"]
+        },
+        {
+            "id": "CastedAnimals",
+            "type": "string",
+            "enum": ["Ducks", "Hens", "Crows", "Flamingos"]
+        },
+        {
+            "id": "RecursiveObject1",
+            "type": "object",
+            "properties": [
+                { "name": "obj", "$ref": "RecursiveObject2", "optional": true }
+            ]
+        },
+        {
+            "id": "RecursiveObject2",
+            "type": "object",
+            "properties": [
+                { "name": "obj", "$ref": "RecursiveObject1", "optional": true }
+            ]
+        }
+    ]
+}
+]
index df19d7fce144e208bf04b862701c8a22e992e6bb..259061df49d1a1ef1921f676fe3c252ddf7e83f7 100644 (file)
@@ -29,7 +29,7 @@
 #include "CallFrameInlines.h"
 #include "CodeBlock.h"
 #include "Interpreter.h"
-#include "JSActivation.h"
+#include "JSLexicalEnvironment.h"
 #include "JSCInlines.h"
 #include "VMEntryScope.h"
 #include <wtf/StringPrintStream.h>
@@ -136,20 +136,36 @@ JSGlobalObject* CallFrame::vmEntryGlobalObject()
     return vm().entryScope->globalObject();
 }
 
-JSActivation* CallFrame::activation() const
+CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame)
+{
+    if (callerFrameOrVMEntryFrame() == currVMEntryFrame) {
+        VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame);
+        currVMEntryFrame = currVMEntryRecord->prevTopVMEntryFrame();
+        return currVMEntryRecord->prevTopCallFrame();
+    }
+    return static_cast<CallFrame*>(callerFrameOrVMEntryFrame());
+}
+
+JSLexicalEnvironment* CallFrame::lexicalEnvironment() const
 {
     CodeBlock* codeBlock = this->codeBlock();
     RELEASE_ASSERT(codeBlock->needsActivation());
     VirtualRegister activationRegister = codeBlock->activationRegister();
-    return registers()[activationRegister.offset()].Register::activation();
+    return registers()[activationRegister.offset()].Register::lexicalEnvironment();
 }
 
-void CallFrame::setActivation(JSActivation* activation)
+JSLexicalEnvironment* CallFrame::lexicalEnvironmentOrNullptr() const
+{
+    CodeBlock* codeBlock = this->codeBlock();
+    return codeBlock->needsActivation() ? lexicalEnvironment() : nullptr;
+}
+    
+void CallFrame::setActivation(JSLexicalEnvironment* lexicalEnvironment)
 {
     CodeBlock* codeBlock = this->codeBlock();
     RELEASE_ASSERT(codeBlock->needsActivation());
     VirtualRegister activationRegister = codeBlock->activationRegister();
-    registers()[activationRegister.offset()] = activation;
+    registers()[activationRegister.offset()] = lexicalEnvironment;
 }
 
 void CallFrame::dump(PrintStream& out)
index 63d6a487b871b24857420d21dc89748666a3ef12..806ccead6fb33f44e8b3338823c4ea3b2bfb6fd4 100644 (file)
 #define CallFrame_h
 
 #include "AbstractPC.h"
-#include "VM.h"
 #include "JSStack.h"
 #include "MacroAssemblerCodeRef.h"
 #include "Register.h"
 #include "StackVisitor.h"
+#include "VM.h"
+#include "VMEntryRecord.h"
 
 namespace JSC  {
 
     class Arguments;
-    class JSActivation;
+    class JSLexicalEnvironment;
     class Interpreter;
     class JSScope;
 
@@ -42,16 +43,17 @@ namespace JSC  {
     class ExecState : private Register {
     public:
         JSValue calleeAsValue() const { return this[JSStack::Callee].jsValue(); }
-        JSObject* callee() const { return this[JSStack::Callee].function(); }
+        JSObject* callee() const { return this[JSStack::Callee].object(); }
         CodeBlock* codeBlock() const { return this[JSStack::CodeBlock].Register::codeBlock(); }
-        JSScope* scope() const
+        JSScope* scope(int scopeRegisterOffset) const
         {
-            ASSERT(this[JSStack::ScopeChain].Register::scope());
-            return this[JSStack::ScopeChain].Register::scope();
+            ASSERT(this[scopeRegisterOffset].Register::scope());
+            return this[scopeRegisterOffset].Register::scope();
         }
 
-        bool hasActivation() const { return !!uncheckedActivation(); }
-        JSActivation* activation() const;
+        bool hasActivation() const;
+        JSLexicalEnvironment* lexicalEnvironment() const;
+        JSLexicalEnvironment* lexicalEnvironmentOrNullptr() const;
         JSValue uncheckedActivation() const;
 
         // Global object in which execution began.
@@ -73,13 +75,12 @@ namespace JSC  {
         // But they're used in many places in legacy code, so they're not going away any time soon.
 
         void clearException() { vm().clearException(); }
-        void clearSupplementaryExceptionInfo()
-        {
-            vm().clearExceptionStack();
-        }
 
-        JSValue exception() const { return vm().exception(); }
-        bool hadException() const { return !vm().exception().isEmpty(); }
+        Exception* exception() const { return vm().exception(); }
+        bool hadException() const { return !!vm().exception(); }
+
+        Exception* lastException() const { return vm().lastException(); }
+        void clearLastException() { vm().clearLastException(); }
 
         AtomicStringTable* atomicStringTable() const { return vm().atomicStringTable(); }
         const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
@@ -87,27 +88,6 @@ namespace JSC  {
         Interpreter* interpreter() { return vm().interpreter; }
         Heap* heap() { return &vm().heap; }
 
-        static const HashTable& arrayConstructorTable(VM& vm) { return *vm.arrayConstructorTable; }
-        static const HashTable& arrayPrototypeTable(VM& vm) { return *vm.arrayPrototypeTable; }
-        static const HashTable& booleanPrototypeTable(VM& vm) { return *vm.booleanPrototypeTable; }
-        static const HashTable& dataViewTable(VM& vm) { return *vm.dataViewTable; }
-        static const HashTable& dateTable(VM& vm) { return *vm.dateTable; }
-        static const HashTable& dateConstructorTable(VM& vm) { return *vm.dateConstructorTable; }
-        static const HashTable& errorPrototypeTable(VM& vm) { return *vm.errorPrototypeTable; }
-        static const HashTable& globalObjectTable(VM& vm) { return *vm.globalObjectTable; }
-        static const HashTable& jsonTable(VM& vm) { return *vm.jsonTable; }
-        static const HashTable& numberConstructorTable(VM& vm) { return *vm.numberConstructorTable; }
-        static const HashTable& numberPrototypeTable(VM& vm) { return *vm.numberPrototypeTable; }
-        static const HashTable& objectConstructorTable(VM& vm) { return *vm.objectConstructorTable; }
-        static const HashTable& privateNamePrototypeTable(VM& vm) { return *vm.privateNamePrototypeTable; }
-        static const HashTable& regExpTable(VM& vm) { return *vm.regExpTable; }
-        static const HashTable& regExpConstructorTable(VM& vm) { return *vm.regExpConstructorTable; }
-        static const HashTable& regExpPrototypeTable(VM& vm) { return *vm.regExpPrototypeTable; }
-        static const HashTable& stringConstructorTable(VM& vm) { return *vm.stringConstructorTable; }
-#if ENABLE(PROMISES)
-        static const HashTable& promisePrototypeTable(VM& vm) { return *vm.promisePrototypeTable; }
-        static const HashTable& promiseConstructorTable(VM& vm) { return *vm.promiseConstructorTable; }
-#endif
 
         static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
         Register* registers() { return this; }
@@ -115,7 +95,10 @@ namespace JSC  {
 
         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
 
-        CallFrame* callerFrame() const { return callerFrameAndPC().callerFrame; }
+        CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); }
+
+        JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
+
         static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); }
 
         ReturnAddressPtr returnPC() const { return ReturnAddressPtr(callerFrameAndPC().pc); }
@@ -182,7 +165,7 @@ namespace JSC  {
 
         Register* topOfFrame()
         {
-            if (isVMEntrySentinel() || !codeBlock())
+            if (!codeBlock())
                 return registers();
             return topOfFrameInternal();
         }
@@ -190,12 +173,10 @@ namespace JSC  {
 #if USE(JSVALUE32_64)
         Instruction* currentVPC() const
         {
-            ASSERT(!isVMEntrySentinel());
             return bitwise_cast<Instruction*>(this[JSStack::ArgumentCount].tag());
         }
         void setCurrentVPC(Instruction* vpc)
         {
-            ASSERT(!isVMEntrySentinel());
             this[JSStack::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc);
         }
 #else
@@ -204,26 +185,27 @@ namespace JSC  {
 #endif
 
         void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
-        void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; }
-        void setActivation(JSActivation*);
-
-        ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, JSScope* scope,
-            CallFrame* callerFrame, int argc, JSObject* callee)
-        {
-            ASSERT(callerFrame == noCaller() || callerFrame->isVMEntrySentinel() || callerFrame->stack()->containsAddress(this));
-
-            setCodeBlock(codeBlock);
-            setScope(scope);
-            setCallerFrame(callerFrame);
-            setReturnPC(vPC); // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
-            setArgumentCountIncludingThis(argc); // original argument count (for the sake of the "arguments" object)
-            setCallee(callee);
+        void setScope(int scopeRegisterOffset, JSScope* scope) { static_cast<Register*>(this)[scopeRegisterOffset] = scope; }
+        void setActivation(JSLexicalEnvironment*);
+
+        ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC,
+            CallFrame* callerFrame, int argc, JSObject* callee) 
+        { 
+            ASSERT(callerFrame == noCaller() || callerFrame->stack()->containsAddress(this)); 
+
+            setCodeBlock(codeBlock); 
+            setCallerFrame(callerFrame); 
+            setReturnPC(vPC); // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. 
+            setArgumentCountIncludingThis(argc); // original argument count (for the sake of the "arguments" object) 
+            setCallee(callee); 
         }
 
         // Read a register from the codeframe (or constant from the CodeBlock).
         Register& r(int);
+        Register& r(VirtualRegister);
         // Read a register for a non-constant
         Register& uncheckedR(int);
+        Register& uncheckedR(VirtualRegister);
 
         // Access to arguments as passed. (After capture, arguments may move to a different location.)
         size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
@@ -256,6 +238,15 @@ namespace JSC  {
             this[argumentOffset(argument)] = value;
         }
 
+        JSValue getArgumentUnsafe(size_t argIndex)
+        {
+            // User beware! This method does not verify that there is a valid
+            // argument at the specified argIndex. This is used for debugging
+            // and verification code only. The caller is expected to know what
+            // he/she is doing when calling this method.
+            return this[argumentOffset(argIndex)].jsValue();
+        }
+
         static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
         JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
         void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
@@ -266,37 +257,8 @@ namespace JSC  {
 
         static CallFrame* noCaller() { return 0; }
 
-        bool isVMEntrySentinel() const
-        {
-            return !!this && codeBlock() == vmEntrySentinelCodeBlock();
-        }
-
-        CallFrame* vmEntrySentinelCallerFrame() const
-        {
-            ASSERT(isVMEntrySentinel());
-            return this[JSStack::ScopeChain].callFrame();
-        }
-
-        void initializeVMEntrySentinelFrame(CallFrame* callFrame)
-        {
-            setCallerFrame(noCaller());
-            setReturnPC(0);
-            setCodeBlock(vmEntrySentinelCodeBlock());
-            static_cast<Register*>(this)[JSStack::ScopeChain] = callFrame;
-            setCallee(0);
-            setArgumentCountIncludingThis(0);
-        }
-
-        CallFrame* callerFrameSkippingVMEntrySentinel()
-        {
-            CallFrame* caller = callerFrame();
-            if (caller->isVMEntrySentinel())
-                return caller->vmEntrySentinelCallerFrame();
-            return caller;
-        }
-
         void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[JSStack::ArgumentCount].payload() = count; }
-        void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = Register::withCallee(callee); }
+        void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = callee; }
         void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[JSStack::CodeBlock] = codeBlock; }
         void setReturnPC(void* value) { callerFrameAndPC().pc = reinterpret_cast<Instruction*>(value); }
 
@@ -312,7 +274,6 @@ namespace JSC  {
         JS_EXPORT_PRIVATE const char* describeFrame();
 
     private:
-        static const intptr_t s_VMEntrySentinel = 1;
 
 #ifndef NDEBUG
         JSStack* stack();
@@ -342,22 +303,12 @@ namespace JSC  {
             return argIndex;
         }
 
-        JSValue getArgumentUnsafe(size_t argIndex)
-        {
-            // User beware! This method does not verify that there is a valid
-            // argument at the specified argIndex. This is used for debugging
-            // and verification code only. The caller is expected to know what
-            // he/she is doing when calling this method.
-            return this[argumentOffset(argIndex)].jsValue();
-        }
+        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
 
         CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
         const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
 
-        static CodeBlock* vmEntrySentinelCodeBlock() { return reinterpret_cast<CodeBlock*>(s_VMEntrySentinel); }
-
         friend class JSStack;
-        friend class VMInspector;
     };
 
 } // namespace JSC
index e3326626d0522d792b4457df939d0a6b77d128ba..2c03b74522902d6a515451bdc2f9350e511c6b41 100644 (file)
@@ -49,11 +49,6 @@ struct CallFrameClosure {
     {
         protoCallFrame->setArgument(argument, value);
     }
-
-    void resetCallFrame()
-    {
-        protoCallFrame->setScope(scope);
-    }
 };
 
 }
index 05fba390afb69cc952df476009efbf65a6984067..3f430ec314098b512fe856ad53d751c34346b1a1 100644 (file)
@@ -139,6 +139,12 @@ inline unsigned CallFrame::locationAsCodeOriginIndex() const
     return Location::decode(locationAsRawBits());
 }
 
+inline bool CallFrame::hasActivation() const
+{
+    JSValue activation = uncheckedActivation();
+    return !!activation && activation.isCell();
+}
+
 inline JSValue CallFrame::uncheckedActivation() const
 {
     CodeBlock* codeBlock = this->codeBlock();
index fb074290200cc92ff747a0ad43f429f94084bfd4..c997d2c90d3eb01eb90e5828feadfe011b08e2ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  *
  * Redistribution and use in source and binary forms, with or without
 #include "config.h"
 #include "Interpreter.h"
 
-#include "Arguments.h"
 #include "BatchedTransitionOptimizer.h"
 #include "CallFrameClosure.h"
 #include "CallFrameInlines.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "Heap.h"
 #include "Debugger.h"
 #include "DebuggerCallFrame.h"
 #include "ErrorInstance.h"
 #include "EvalCodeCache.h"
+#include "Exception.h"
 #include "ExceptionHelpers.h"
 #include "GetterSetter.h"
-#include "JSActivation.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
+#include "JSCInlines.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "JSNotAnObject.h"
-#include "JSPropertyNameIterator.h"
 #include "JSStackInlines.h"
 #include "JSString.h"
 #include "JSWithScope.h"
 #include "LLIntThunks.h"
 #include "LegacyProfiler.h"
 #include "LiteralParser.h"
-#include "NameInstance.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "Parser.h"
 #include "ProtoCallFrame.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
 #include "Register.h"
 #include "SamplingTool.h"
+#include "ScopedArguments.h"
 #include "StackAlignment.h"
 #include "StackVisitor.h"
 #include "StrictEvalActivation.h"
 #include "StrongInlines.h"
+#include "Symbol.h"
 #include "VMEntryScope.h"
 #include "VirtualRegister.h"
 
 #include "JIT.h"
 #endif
 
-#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (!defined(__llvm__))
-
 using namespace std;
 
 namespace JSC {
 
+String StackFrame::friendlySourceURL() const
+{
+    String traceLine;
+    
+    switch (codeType) {
+    case StackFrameEvalCode:
+    case StackFrameFunctionCode:
+    case StackFrameGlobalCode:
+        if (!sourceURL.isEmpty())
+            traceLine = sourceURL.impl();
+        break;
+    case StackFrameNativeCode:
+        traceLine = "[native code]";
+        break;
+    }
+    return traceLine.isNull() ? emptyString() : traceLine;
+}
+
+String StackFrame::friendlyFunctionName(CallFrame* callFrame) const
+{
+    String traceLine;
+    JSObject* stackFrameCallee = callee.get();
+
+    switch (codeType) {
+    case StackFrameEvalCode:
+        traceLine = "eval code";
+        break;
+    case StackFrameNativeCode:
+        if (callee)
+            traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
+        break;
+    case StackFrameFunctionCode:
+        traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
+        break;
+    case StackFrameGlobalCode:
+        traceLine = "global code";
+        break;
+    }
+    return traceLine.isNull() ? emptyString() : traceLine;
+}
+
 JSValue eval(CallFrame* callFrame)
 {
     if (!callFrame->argumentCount())
@@ -106,13 +147,11 @@ JSValue eval(CallFrame* callFrame)
     
     CallFrame* callerFrame = callFrame->callerFrame();
     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
-    JSScope* callerScopeChain = callerFrame->scope();
+    JSScope* callerScopeChain = callerFrame->uncheckedR(callerCodeBlock->scopeRegister().offset()).Register::scope();
     EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
 
     if (!eval) {
         if (!callerCodeBlock->isStrictMode()) {
-            // FIXME: We can use the preparser in strict mode, we just need additional logic
-            // to prevent duplicates.
             if (programSource.is8Bit()) {
                 LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
                 if (JSValue parsedObject = preparser.tryLiteralParse())
@@ -127,7 +166,8 @@ JSValue eval(CallFrame* callFrame)
         // If the literal parser bailed, it should not have thrown exceptions.
         ASSERT(!callFrame->vm().exception());
 
-        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
+        ThisTDZMode thisTDZMode = callerCodeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
+        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
         if (!eval)
             return jsUndefined();
     }
@@ -137,149 +177,103 @@ JSValue eval(CallFrame* callFrame)
     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
 }
 
-CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister, uint32_t firstVarArgOffset)
+unsigned sizeOfVarargs(CallFrame* callFrame, JSValue arguments, uint32_t firstVarArgOffset)
 {
-    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-        if (argumentCountIncludingThis > firstVarArgOffset)
-            argumentCountIncludingThis -= firstVarArgOffset;
-        else
-            argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (arguments.isUndefinedOrNull()) {
-        unsigned argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (!stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
+    if (UNLIKELY(!arguments.isCell())) {
+        if (arguments.isUndefinedOrNull())
             return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (!arguments.isObject()) {
-        callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
+        
+        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame, arguments));
         return 0;
     }
-
-    if (asObject(arguments)->classInfo() == Arguments::info()) {
-        Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = argsObject->length(callFrame);
-        callFrame->vm().varargsLength = argCount;
-        if (argCount >= firstVarArgOffset)
-            argCount -= firstVarArgOffset;
-        else
-            argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (isJSArray(arguments)) {
-        JSArray* array = asArray(arguments);
-        unsigned argCount = array->length();
-        if (argCount >= firstVarArgOffset)
-            argCount -= firstVarArgOffset;
+    
+    JSCell* cell = arguments.asCell();
+    unsigned length;
+    switch (cell->type()) {
+    case DirectArgumentsType:
+        length = jsCast<DirectArguments*>(cell)->length(callFrame);
+        break;
+    case ScopedArgumentsType:
+        length =jsCast<ScopedArguments*>(cell)->length(callFrame);
+        break;
+    case StringType:
+        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame,  arguments));
+        return 0;
+    default:
+        ASSERT(arguments.isObject());
+        if (isJSArray(cell))
+            length = jsCast<JSArray*>(cell)->length();
         else
-            argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
+            length = jsCast<JSObject*>(cell)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+        break;
     }
-
-    JSObject* argObject = asObject(arguments);
-    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
-    callFrame->vm().varargsLength = argCount;
-    if (argCount >= firstVarArgOffset)
-        argCount -= firstVarArgOffset;
+    
+    if (length >= firstVarArgOffset)
+        length -= firstVarArgOffset;
     else
-        argCount = 0;
-    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
-    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-    if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
+        length = 0;
+    
+    return length;
+}
+
+unsigned sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
+{
+    unsigned length = sizeOfVarargs(callFrame, arguments, firstVarArgOffset);
+    
+    CallFrame* calleeFrame = calleeFrameForVarargs(callFrame, numUsedStackSlots, length + 1);
+    if (length > maxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
         throwStackOverflowError(callFrame);
         return 0;
     }
-    return newCallFrame;
+    
+    return length;
 }
 
-void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
+void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, JSValue arguments, uint32_t offset, uint32_t length)
 {
-    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-        if (argumentCountIncludingThis > firstVarArgOffset)
-            argumentCountIncludingThis -= firstVarArgOffset;
-        else
-            argumentCountIncludingThis = 1;
-        newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
-        newCallFrame->setThisValue(thisValue);
-        for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
-            newCallFrame->setArgument(i - firstVarArgOffset, callFrame->argumentAfterCapture(i));
+    if (UNLIKELY(!arguments.isCell()))
         return;
-    }
     
-    if (arguments.isUndefinedOrNull()) {
-        newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+    JSCell* cell = arguments.asCell();
+    switch (cell->type()) {
+    case DirectArgumentsType:
+        jsCast<DirectArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
-    }
-    
-    if (asObject(arguments)->classInfo() == Arguments::info()) {
-        Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = callFrame->vm().varargsLength;
-        callFrame->vm().varargsLength = 0;
-        if (argCount >= firstVarArgOffset) {
-            argCount -= firstVarArgOffset;
-            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
-            argsObject->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
-        } else
-            newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+    case ScopedArgumentsType:
+        jsCast<ScopedArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
-    }
-    
-    if (isJSArray(arguments)) {
-        JSArray* array = asArray(arguments);
-        unsigned argCount = array->length();
-        if (argCount >= firstVarArgOffset) {
-            argCount -= firstVarArgOffset;
-            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
-            array->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
-        } else
-            newCallFrame->setArgumentCountIncludingThis(1);
-        newCallFrame->setThisValue(thisValue);
+    default: {
+        ASSERT(arguments.isObject());
+        JSObject* object = jsCast<JSObject*>(cell);
+        if (isJSArray(object)) {
+            jsCast<JSArray*>(object)->copyToArguments(callFrame, firstElementDest, offset, length);
+            return;
+        }
+        unsigned i;
+        for (i = 0; i < length && object->canGetIndexQuickly(i + offset); ++i)
+            callFrame->r(firstElementDest + i) = object->getIndexQuickly(i + offset);
+        for (; i < length; ++i)
+            callFrame->r(firstElementDest + i) = object->get(callFrame, i + offset);
         return;
-    }
+    } }
+}
+
+void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t offset, uint32_t length)
+{
+    VirtualRegister calleeFrameOffset(newCallFrame - callFrame);
     
-    unsigned argCount = callFrame->vm().varargsLength;
-    if (argCount >= firstVarArgOffset) {
-        argCount -= firstVarArgOffset;
-        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
-    } else
-        newCallFrame->setArgumentCountIncludingThis(1);
+    loadVarargs(
+        callFrame,
+        calleeFrameOffset + CallFrame::argumentOffset(0),
+        arguments, offset, length);
+    
+    newCallFrame->setArgumentCountIncludingThis(length + 1);
+}
 
+void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length)
+{
+    setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset, length);
     newCallFrame->setThisValue(thisValue);
-    for (size_t i = 0; i < argCount; ++i) {
-        newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i + firstVarArgOffset));
-        if (UNLIKELY(callFrame->vm().exception()))
-            return;
-    }
 }
 
 Interpreter::Interpreter(VM& vm)
@@ -386,7 +380,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
     --it;
     dataLogF("[Callee]                   | %10p | %p \n", it, callFrame->callee());
     --it;
-    dataLogF("[ScopeChain]               | %10p | %p \n", it, callFrame->scope());
+    // FIXME: Remove the next decrement when the ScopeChain slot is removed from the call header
     --it;
 #if ENABLE(JIT)
     AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
@@ -441,49 +435,16 @@ bool Interpreter::isOpcode(Opcode opcode)
 static bool unwindCallFrame(StackVisitor& visitor)
 {
     CallFrame* callFrame = visitor->callFrame();
-    CodeBlock* codeBlock = visitor->codeBlock();
-    JSScope* scope = callFrame->scope();
-
     if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
-        ClearExceptionScope scope(&callFrame->vm());
-        if (callFrame->callee())
+        SuspendExceptionScope scope(&callFrame->vm());
+        if (jsDynamicCast<JSFunction*>(callFrame->callee()))
             debugger->returnEvent(callFrame);
         else
             debugger->didExecuteProgram(callFrame);
         ASSERT(!callFrame->hadException());
     }
 
-    JSValue activation;
-    if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
-#if ENABLE(DFG_JIT)
-        RELEASE_ASSERT(!visitor->isInlinedFrame());
-#endif
-        activation = callFrame->uncheckedActivation();
-        // Protect against the activation not being created, or the variable still being
-        // initialized to Undefined inside op_enter.
-        if (activation && activation.isCell()) {
-            JSActivation* activationObject = jsCast<JSActivation*>(activation);
-            // Protect against throwing exceptions after tear-off.
-            if (!activationObject->isTornOff())
-                activationObject->tearOff(*scope->vm());
-        }
-    }
-
-    if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
-        if (Arguments* arguments = visitor->existingArguments()) {
-            if (activation && activation.isCell())
-                arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
-#if ENABLE(DFG_JIT)
-            else if (visitor->isInlinedFrame())
-                arguments->tearOff(callFrame, visitor->inlineCallFrame());
-#endif
-            else
-                arguments->tearOff(callFrame);
-        }
-    }
-
-    CallFrame* callerFrame = callFrame->callerFrame();
-    return !callerFrame->isVMEntrySentinel();
+    return !visitor->callerIsVMEntryFrame();
 }
 
 static StackFrameCodeType getStackFrameCodeType(StackVisitor& visitor)
@@ -520,6 +481,9 @@ void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column)
 
     line = divotLine + lineOffset;
     column = divotColumn + (divotLine ? 1 : firstLineColumnOffset);
+
+    if (executable->hasOverrideLineNumber())
+        line = executable->overrideLineNumber();
 }
 
 void StackFrame::expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
@@ -570,10 +534,10 @@ public:
                 StackFrame s = {
                     Strong<JSObject>(vm, visitor->callee()),
                     getStackFrameCodeType(visitor),
-                    Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
+                    Strong<ScriptExecutable>(vm, codeBlock->ownerExecutable()),
                     Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
                     codeBlock->source(),
-                    codeBlock->ownerExecutable()->lineNo(),
+                    codeBlock->ownerExecutable()->firstLine(),
                     codeBlock->firstLineColumnOffset(),
                     codeBlock->sourceOffset(),
                     visitor->bytecodeOffset(),
@@ -581,7 +545,7 @@ public:
                 };
                 m_results.append(s);
             } else {
-                StackFrame s = { Strong<JSObject>(vm, visitor->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
+                StackFrame s = { Strong<JSObject>(vm, visitor->callee()), StackFrameNativeCode, Strong<ScriptExecutable>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
                 m_results.append(s);
             }
     
@@ -600,7 +564,6 @@ private:
 void Interpreter::getStackTrace(Vector<StackFrame>& results, size_t maxStackSize)
 {
     VM& vm = m_vm;
-    ASSERT(!vm.topCallFrame->isVMEntrySentinel());
     CallFrame* callFrame = vm.topCallFrame;
     if (!callFrame)
         return;
@@ -621,9 +584,9 @@ JSString* Interpreter::stackTraceAsString(ExecState* exec, Vector<StackFrame> st
     return jsString(&exec->vm(), builder.toString());
 }
 
-class GetExceptionHandlerFunctor {
+class GetCatchHandlerFunctor {
 public:
-    GetExceptionHandlerFunctor()
+    GetCatchHandlerFunctor()
         : m_handler(0)
     {
     }
@@ -637,7 +600,7 @@ public:
             return StackVisitor::Continue;
 
         unsigned bytecodeOffset = visitor->bytecodeOffset();
-        m_handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
+        m_handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset, CodeBlock::RequiredHandler::CatchHandler);
         if (m_handler)
             return StackVisitor::Done;
 
@@ -650,8 +613,9 @@ private:
 
 class UnwindFunctor {
 public:
-    UnwindFunctor(CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
-        : m_callFrame(callFrame)
+    UnwindFunctor(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
+        : m_vmEntryFrame(vmEntryFrame)
+        , m_callFrame(callFrame)
         , m_isTermination(isTermination)
         , m_codeBlock(codeBlock)
         , m_handler(handler)
@@ -661,11 +625,12 @@ public:
     StackVisitor::Status operator()(StackVisitor& visitor)
     {
         VM& vm = m_callFrame->vm();
+        m_vmEntryFrame = visitor->vmEntryFrame();
         m_callFrame = visitor->callFrame();
         m_codeBlock = visitor->codeBlock();
         unsigned bytecodeOffset = visitor->bytecodeOffset();
 
-        if (m_isTermination || !(m_handler = m_codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
+        if (m_isTermination || !(m_handler = m_codeBlock ? m_codeBlock->handlerForBytecodeOffset(bytecodeOffset) : nullptr)) {
             if (!unwindCallFrame(visitor)) {
                 if (LegacyProfiler* profiler = vm.enabledProfiler())
                     profiler->exceptionUnwind(m_callFrame);
@@ -678,27 +643,19 @@ public:
     }
 
 private:
+    VMEntryFrame*& m_vmEntryFrame;
     CallFrame*& m_callFrame;
     bool m_isTermination;
     CodeBlock*& m_codeBlock;
     HandlerInfo*& m_handler;
 };
 
-NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue)
+NEVER_INLINE HandlerInfo* Interpreter::unwind(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, Exception* exception)
 {
-    if (callFrame->isVMEntrySentinel()) {
-        // This happens when we throw stack overflow in a function that is called
-        // directly from callToJavaScript. Stack overflow throws the exception in the
-        // context of the caller. In that case the caller is the sentinel frame. The
-        // right thing to do is to pretend that the exception is uncaught so that we
-        // go to the uncaught exception handler, which returns through callToJavaScript.
-        return 0;
-    }
-    
     CodeBlock* codeBlock = callFrame->codeBlock();
-    ASSERT(codeBlock);
     bool isTermination = false;
 
+    JSValue exceptionValue = exception->value();
     ASSERT(!exceptionValue.isEmpty());
     ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
     // This shouldn't be possible (hence the assertions), but we're already in the slowest of
@@ -707,38 +664,41 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& ex
         exceptionValue = jsNull();
 
     if (exceptionValue.isObject())
-        isTermination = isTerminatedExecutionException(asObject(exceptionValue));
+        isTermination = isTerminatedExecutionException(exception);
 
-    ASSERT(callFrame->vm().exceptionStack().size());
+    ASSERT(callFrame->vm().exception() && callFrame->vm().exception()->stack().size());
 
     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
-    if (debugger && debugger->needsExceptionCallbacks()) {
-        // We need to clear the exception and the exception stack here in order to see if a new exception happens.
+    if (debugger && debugger->needsExceptionCallbacks() && !exception->didNotifyInspectorOfThrow()) {
+        // We need to clear the exception here in order to see if a new exception happens.
         // Afterwards, the values are put back to continue processing this error.
-        ClearExceptionScope scope(&callFrame->vm());
+        SuspendExceptionScope scope(&callFrame->vm());
         // This code assumes that if the debugger is enabled then there is no inlining.
         // If that assumption turns out to be false then we'll ignore the inlined call
         // frames.
         // https://bugs.webkit.org/show_bug.cgi?id=121754
 
-        bool hasHandler;
+        bool hasCatchHandler;
         if (isTermination)
-            hasHandler = false;
+            hasCatchHandler = false;
         else {
-            GetExceptionHandlerFunctor functor;
+            GetCatchHandlerFunctor functor;
             callFrame->iterate(functor);
-            hasHandler = !!functor.handler();
+            HandlerInfo* handler = functor.handler();
+            ASSERT(!handler || handler->isCatchHandler());
+            hasCatchHandler = !!handler;
         }
 
-        debugger->exception(callFrame, exceptionValue, hasHandler);
+        debugger->exception(callFrame, exceptionValue, hasCatchHandler);
         ASSERT(!callFrame->hadException());
     }
+    exception->setDidNotifyInspectorOfThrow();
 
     // Calculate an exception handler vPC, unwinding call frames as necessary.
     HandlerInfo* handler = 0;
     VM& vm = callFrame->vm();
     ASSERT(callFrame == vm.topCallFrame);
-    UnwindFunctor functor(callFrame, isTermination, codeBlock, handler);
+    UnwindFunctor functor(vmEntryFrame, callFrame, isTermination, codeBlock, handler);
     callFrame->iterate(functor);
     if (!handler)
         return 0;
@@ -751,13 +711,15 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& ex
     if (codeBlock->needsActivation() && callFrame->hasActivation())
         ++targetScopeDepth;
 
-    JSScope* scope = callFrame->scope();
+    int scopeRegisterOffset = codeBlock->scopeRegister().offset();
+    JSScope* scope = callFrame->scope(scopeRegisterOffset);
     int scopeDelta = scope->depth() - targetScopeDepth;
     RELEASE_ASSERT(scopeDelta >= 0);
 
     while (scopeDelta--)
         scope = scope->next();
-    callFrame->setScope(scope);
+
+    callFrame->setScope(scopeRegisterOffset, scope);
 
     return handler;
 }
@@ -792,8 +754,8 @@ private:
 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
 {
     SamplingScope samplingScope(this);
-    
-    JSScope* scope = callFrame->scope();
+
+    JSScope* scope = thisObj->globalObject();
     VM& vm = *scope->vm();
 
     ASSERT(!vm.exception());
@@ -845,7 +807,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
                         PropertySlot slot(globalObject);
                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
                             if (entry)
-                                return callFrame->vm().throwException(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
+                                return callFrame->vm().throwException(callFrame, createUndefinedVariableError(callFrame, JSONPPath[i].m_pathEntryName));
                             goto failedJSONP;
                         }
                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
@@ -914,7 +876,7 @@ failedJSONP:
     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
-    if (JSObject* error = program->prepareForExecution(callFrame, nullptr, &scope, CodeForCall))
+    if (JSObject* error = program->prepareForExecution(callFrame, nullptr, scope, CodeForCall))
         return checkedReturn(callFrame->vm().throwException(callFrame, error));
 
     ProgramCodeBlock* codeBlock = program->codeBlock();
@@ -925,10 +887,10 @@ failedJSONP:
     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
 
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
+    protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisObj, 1);
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
-        profiler->willExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
+        profiler->willExecute(callFrame, program->sourceURL(), program->firstLine(), program->startColumn());
 
     // Execute the code:
     JSValue result;
@@ -940,7 +902,7 @@ failedJSONP:
     }
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
-        profiler->didExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
+        profiler->didExecute(callFrame, program->sourceURL(), program->firstLine(), program->startColumn());
 
     return checkedReturn(result);
 }
@@ -954,24 +916,27 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
         return jsNull();
 
     bool isJSCall = (callType == CallTypeJS);
-    JSScope* scope;
+    JSScope* scope = nullptr;
     CodeBlock* newCodeBlock;
     size_t argsCount = 1 + args.size(); // implicit "this" parameter
 
-    if (isJSCall)
+    JSGlobalObject* globalObject;
+
+    if (isJSCall) {
         scope = callData.js.scope;
-    else {
+        globalObject = scope->globalObject();
+    } else {
         ASSERT(callType == CallTypeHost);
-        scope = callFrame->scope();
+        globalObject = function->globalObject();
     }
 
-    VMEntryScope entryScope(vm, scope->globalObject());
+    VMEntryScope entryScope(vm, globalObject);
     if (!vm.isSafeToRecurse())
         return checkedReturn(throwStackOverflowError(callFrame));
 
     if (isJSCall) {
         // Compile the callee:
-        JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(function), &scope, CodeForCall);
+        JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(function), scope, CodeForCall);
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
@@ -985,7 +950,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
         return throwTerminatedExecutionException(callFrame);
 
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
+    protoCallFrame.init(newCodeBlock, function, thisValue, argsCount, args.data());
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
         profiler->willExecute(callFrame, function);
@@ -999,7 +964,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
         if (isJSCall)
             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
         else {
-            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
+            result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
             if (callFrame->hadException())
                 result = jsNull();
         }
@@ -1022,24 +987,27 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
         return checkedReturn(throwStackOverflowError(callFrame));
 
     bool isJSConstruct = (constructType == ConstructTypeJS);
-    JSScope* scope;
+    JSScope* scope = nullptr;
     CodeBlock* newCodeBlock;
     size_t argsCount = 1 + args.size(); // implicit "this" parameter
 
-    if (isJSConstruct)
+    JSGlobalObject* globalObject;
+
+    if (isJSConstruct) {
         scope = constructData.js.scope;
-    else {
+        globalObject = scope->globalObject();
+    } else {
         ASSERT(constructType == ConstructTypeHost);
-        scope = callFrame->scope();
+        globalObject = constructor->globalObject();
     }
 
-    VMEntryScope entryScope(vm, scope->globalObject());
+    VMEntryScope entryScope(vm, globalObject);
     if (!vm.isSafeToRecurse())
         return checkedReturn(throwStackOverflowError(callFrame));
 
     if (isJSConstruct) {
         // Compile the callee:
-        JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(constructor), &scope, CodeForConstruct);
+        JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(constructor), scope, CodeForConstruct);
         if (UNLIKELY(!!compileError)) {
             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
         }
@@ -1053,7 +1021,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
         return throwTerminatedExecutionException(callFrame);
 
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
+    protoCallFrame.init(newCodeBlock, constructor, constructor, argsCount, args.data());
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
         profiler->willExecute(callFrame, constructor);
@@ -1067,7 +1035,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
         if (isJSConstruct)
             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
         else {
-            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
+            result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
 
             if (!callFrame->hadException())
                 RELEASE_ASSERT(result.isObject());
@@ -1092,7 +1060,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
         return CallFrameClosure();
 
     // Compile the callee:
-    JSObject* error = functionExecutable->prepareForExecution(callFrame, function, &scope, CodeForCall);
+    JSObject* error = functionExecutable->prepareForExecution(callFrame, function, scope, CodeForCall);
     if (error) {
         callFrame->vm().throwException(callFrame, error);
         return CallFrameClosure();
@@ -1102,7 +1070,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
 
     size_t argsCount = argumentCountIncludingThis;
 
-    protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
+    protoCallFrame->init(newCodeBlock, function, jsUndefined(), argsCount, args);
     // Return the successful closure:
     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
     return result;
@@ -1119,7 +1087,6 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
         return jsNull();
 
     StackStats::CheckPoint stackCheckPoint;
-    closure.resetCallFrame();
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
         profiler->willExecute(closure.oldCallFrame, closure.function);
@@ -1163,19 +1130,20 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
 
     JSScope* variableObject;
     if ((numVariables || numFunctions) && eval->isStrictMode()) {
-        scope = StrictEvalActivation::create(callFrame);
+        scope = StrictEvalActivation::create(callFrame, scope);
         variableObject = scope;
     } else {
         for (JSScope* node = scope; ; node = node->next()) {
             RELEASE_ASSERT(node);
-            if (node->isVariableObject() && !node->isNameScopeObject()) {
+            if (node->isVariableObject()) {
+                ASSERT(!node->isNameScopeObject());
                 variableObject = node;
                 break;
             }
         }
     }
 
-    JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, &scope, CodeForCall);
+    JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, scope, CodeForCall);
     if (UNLIKELY(!!compileError))
         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
     EvalCodeBlock* codeBlock = eval->codeBlock();
@@ -1183,7 +1151,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     if (numVariables || numFunctions) {
         BatchedTransitionOptimizer optimizer(vm, variableObject);
         if (variableObject->next())
-            variableObject->globalObject()->varInjectionWatchpoint()->fireAll();
+            variableObject->globalObject()->varInjectionWatchpoint()->fireAll("Executed eval, fired VarInjection watchpoint");
 
         for (unsigned i = 0; i < numVariables; ++i) {
             const Identifier& ident = codeBlock->variable(i);
@@ -1206,10 +1174,10 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
 
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
+    protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisValue, 1);
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
-        profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
+        profiler->willExecute(callFrame, eval->sourceURL(), eval->firstLine(), eval->startColumn());
 
     // Execute the code:
     JSValue result;
@@ -1221,7 +1189,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     }
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
-        profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
+        profiler->didExecute(callFrame, eval->sourceURL(), eval->firstLine(), eval->startColumn());
 
     return checkedReturn(result);
 }
@@ -1262,7 +1230,7 @@ void Interpreter::enableSampler()
 {
 #if ENABLE(OPCODE_SAMPLING)
     if (!m_sampler) {
-        m_sampler = adoptPtr(new SamplingTool(this));
+        m_sampler = std::make_unique<SamplingTool>(this);
         m_sampler->setup();
     }
 #endif
index c77019e5a1c987379f028c39cfe26fa2b526fcde..ef4ec0d66c04dd28fc9dc054448830c7690f5243 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "ArgList.h"
 #include "JSCJSValue.h"
 #include "JSCell.h"
-#include "JSFunction.h"
 #include "JSObject.h"
 #include "JSStack.h"
 #include "LLIntData.h"
 #include "Opcode.h"
 #include "SourceProvider.h"
+#include "StackAlignment.h"
 
 #include <wtf/HashMap.h>
 #include <wtf/text/StringBuilder.h>
@@ -50,6 +50,7 @@ namespace JSC {
     class ExecutableBase;
     class FunctionExecutable;
     class VM;
+    class JSFunction;
     class JSGlobalObject;
     class LLIntOffsetsExtractor;
     class ProgramExecutable;
@@ -80,7 +81,7 @@ namespace JSC {
     struct StackFrame {
         Strong<JSObject> callee;
         StackFrameCodeType codeType;
-        Strong<ExecutableBase> executable;
+        Strong<ScriptExecutable> executable;
         Strong<UnlinkedCodeBlock> codeBlock;
         RefPtr<SourceProvider> code;
         int lineOffset;
@@ -89,65 +90,28 @@ namespace JSC {
         unsigned bytecodeOffset;
         String sourceURL;
         JS_EXPORT_PRIVATE String toString(CallFrame*);
-        String friendlySourceURL() const
-        {
-            String traceLine;
-
-            switch (codeType) {
-            case StackFrameEvalCode:
-            case StackFrameFunctionCode:
-            case StackFrameGlobalCode:
-                if (!sourceURL.isEmpty())
-                    traceLine = sourceURL.impl();
-                break;
-            case StackFrameNativeCode:
-                traceLine = "[native code]";
-                break;
-            }
-            return traceLine.isNull() ? emptyString() : traceLine;
-        }
-        String friendlyFunctionName(CallFrame* callFrame) const
-        {
-            String traceLine;
-            JSObject* stackFrameCallee = callee.get();
-
-            switch (codeType) {
-            case StackFrameEvalCode:
-                traceLine = "eval code";
-                break;
-            case StackFrameNativeCode:
-                if (callee)
-                    traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
-                break;
-            case StackFrameFunctionCode:
-                traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
-                break;
-            case StackFrameGlobalCode:
-                traceLine = "global code";
-                break;
-            }
-            return traceLine.isNull() ? emptyString() : traceLine;
-        }
+        String friendlySourceURL() const;
+        String friendlyFunctionName(CallFrame*) const;
         JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
 
     private:
         void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
     };
 
-    class ClearExceptionScope {
+    class SuspendExceptionScope {
     public:
-        ClearExceptionScope(VM* vm): m_vm(vm)
+        SuspendExceptionScope(VM* vm)
+            : m_vm(vm)
         {
-            vm->getExceptionInfo(oldException, oldExceptionStack);
+            oldException = vm->exception();
             vm->clearException();
         }
-        ~ClearExceptionScope()
+        ~SuspendExceptionScope()
         {
-            m_vm->setExceptionInfo(oldException, oldExceptionStack);
+            m_vm->setException(oldException);
         }
     private:
-        JSC::JSValue oldException;
-        RefCountedArray<JSC::StackFrame> oldExceptionStack;
+        Exception* oldException;
         VM* m_vm;
     };
     
@@ -157,13 +121,11 @@ namespace JSC {
             : vm(currentVM)
             , oldCallFrame(currentVM.topCallFrame) 
         {
-            ASSERT(!callFrame->isVMEntrySentinel());
             currentVM.topCallFrame = callFrame;
         }
         
         ~TopCallFrameSetter() 
         {
-            ASSERT(!oldCallFrame->isVMEntrySentinel());
             vm.topCallFrame = oldCallFrame;
         }
     private:
@@ -177,18 +139,33 @@ namespace JSC {
         {
             ASSERT(vm);
             ASSERT(callFrame);
-            ASSERT(!callFrame->isVMEntrySentinel());
             vm->topCallFrame = callFrame;
         }
-        
-        enum VMEntrySentinelOKTag { VMEntrySentinelOK };
-        ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame, VMEntrySentinelOKTag)
+    };
+
+    class NativeCallFrameTracerWithRestore {
+    public:
+        ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame)
+            : m_vm(vm)
         {
             ASSERT(vm);
             ASSERT(callFrame);
-            if (!callFrame->isVMEntrySentinel())
-                vm->topCallFrame = callFrame;
+            m_savedTopVMEntryFrame = vm->topVMEntryFrame;
+            m_savedTopCallFrame = vm->topCallFrame;
+            vm->topVMEntryFrame = vmEntryFrame;
+            vm->topCallFrame = callFrame;
         }
+
+        ALWAYS_INLINE ~NativeCallFrameTracerWithRestore()
+        {
+            m_vm->topVMEntryFrame = m_savedTopVMEntryFrame;
+            m_vm->topCallFrame = m_savedTopCallFrame;
+        }
+
+    private:
+        VM* m_vm;
+        VMEntryFrame* m_savedTopVMEntryFrame;
+        CallFrame* m_savedTopCallFrame;
     };
 
     class Interpreter {
@@ -238,7 +215,7 @@ namespace JSC {
         
         SamplingTool* sampler() { return m_sampler.get(); }
 
-        NEVER_INLINE HandlerInfo* unwind(CallFrame*&, JSValue&);
+        NEVER_INLINE HandlerInfo* unwind(VMEntryFrame*&, CallFrame*&, Exception*);
         NEVER_INLINE void debug(CallFrame*, DebugHookID);
         JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
 
@@ -253,6 +230,8 @@ namespace JSC {
 
         JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
 
+        void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+
     private:
         enum ExecutionFlag { Normal, InitializeAndReturn };
 
@@ -260,7 +239,7 @@ namespace JSC {
 
         JSValue execute(CallFrameClosure&);
 
-        void getStackTrace(Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+
 
         void dumpRegisters(CallFrame*);
         
@@ -268,7 +247,7 @@ namespace JSC {
 
         void enableSampler();
         int m_sampleEntryDepth;
-        OwnPtr<SamplingTool> m_sampler;
+        std::unique_ptr<SamplingTool> m_sampler;
 
         VM& m_vm;
         JSStack m_stack;
@@ -285,8 +264,22 @@ namespace JSC {
     };
 
     JSValue eval(CallFrame*);
-    CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, uint32_t firstVarArgOffset);
-    void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, uint32_t firstVarArgOffset);
+
+    inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis)
+    {
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(
+            stackAlignmentRegisters(),
+            numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
+        return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
+    }
+
+    unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset);
+    static const unsigned maxArguments = 0x10000;
+    unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
+    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
+    void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
+    void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
+    
 } // namespace JSC
 
 #endif // Interpreter_h
index c6a703cbc603074432c0b281ec20919ee3bec812..025fef0831455bfc69fb78ef5323620cf8ea3284 100644 (file)
@@ -97,8 +97,7 @@ bool JSStack::growSlowCase(Register* newTopOfStack)
     if (newCommitTop < reservationTop())
         return false;
 
-    // Otherwise, the growth is still within our budget. Go ahead and commit
-    // it and return true.
+    // Otherwise, the growth is still within our budget. Commit it and return true.
     m_reservation.commit(newCommitTop, delta);
     addToCommittedByteCount(delta);
     m_commitTop = newCommitTop;
@@ -118,7 +117,7 @@ void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITS
 
 void JSStack::sanitizeStack()
 {
-#if !defined(ADDRESS_SANITIZER)
+#if !ASAN_ENABLED
     ASSERT(topOfStack() <= baseOfStack());
     
     if (m_lastStackTop < topOfStack()) {
index 174d75fe43704c110aa9a8bf69a1f9da94167274..401fbc0c55abf7ca11d4b014d6c2c1a732bbc818 100644 (file)
@@ -58,7 +58,6 @@ namespace JSC {
         enum CallFrameHeaderEntry {
             CallerFrameAndPCSize = sizeof(CallerFrameAndPC) / sizeof(Register),
             CodeBlock = CallerFrameAndPCSize,
-            ScopeChain,
             Callee,
             ArgumentCount,
             CallFrameHeaderSize,
index 5d6ae0f4f1d1f07bf6ff09f883bd3641ed81a803..eb80b2c2336456eabc8c83c1ad4ed589d238c15b 100644 (file)
 
 namespace JSC {
 
-void ProtoCallFrame::init(CodeBlock* codeBlock, JSScope* scope, JSObject* callee, JSValue thisValue, int argCountIncludingThis, JSValue* otherArgs)
+void ProtoCallFrame::init(CodeBlock* codeBlock, JSObject* callee, JSValue thisValue, int argCountIncludingThis, JSValue* otherArgs)
 {
     this->args = otherArgs;
     this->setCodeBlock(codeBlock);
-    this->setScope(scope);
     this->setCallee(callee);
     this->setArgumentCountIncludingThis(argCountIncludingThis);
-    size_t paddedArgsCount = argCountIncludingThis;
-    if (codeBlock) {
-        size_t numParameters = codeBlock->numParameters();
-        if (paddedArgsCount < numParameters)
-            paddedArgsCount = numParameters;
-    }
-    // Round up paddedArgsCount to keep the stack frame size aligned.
-    paddedArgsCount = roundArgumentCountToAlignFrame(paddedArgsCount);
+    if (codeBlock && argCountIncludingThis < codeBlock->numParameters())
+        this->arityMissMatch = true;
+    else
+        this->arityMissMatch = false;
+
+    // Round up argCountIncludingThis to keep the stack frame size aligned.
+    size_t paddedArgsCount = roundArgumentCountToAlignFrame(argCountIncludingThis);
     this->setPaddedArgCount(paddedArgsCount);
     this->clearCurrentVPC();
     this->setThisValue(thisValue);
index 406dfb3e716322393edbb119fc270924ffb20da4..af33a3072ccc6153daa0c75ae14bc6b8b3b212c9 100644 (file)
@@ -32,23 +32,20 @@ namespace JSC {
 
 struct ProtoCallFrame {
     Register codeBlockValue;
-    Register scopeChainValue;
     Register calleeValue;
     Register argCountAndCodeOriginValue;
     Register thisArg;
     uint32_t paddedArgCount;
+    bool arityMissMatch;
     JSValue *args;
 
-    void init(CodeBlock*, JSScope*, JSObject*, JSValue, int, JSValue* otherArgs = 0);
+    void init(CodeBlock*, JSObject*, JSValue, int, JSValue* otherArgs = 0);
 
     CodeBlock* codeBlock() const { return codeBlockValue.Register::codeBlock(); }
     void setCodeBlock(CodeBlock* codeBlock) { codeBlockValue = codeBlock; }
 
-    JSScope* scope() const { return scopeChainValue.Register::scope(); }
-    void setScope(JSScope* scope) { scopeChainValue = scope; }
-
-    JSObject* callee() const { return calleeValue.Register::function(); }
-    void setCallee(JSObject* callee) { calleeValue = Register::withCallee(callee); }
+    JSObject* callee() const { return calleeValue.Register::object(); }
+    void setCallee(JSObject* callee) { calleeValue = callee; }
 
     int argumentCountIncludingThis() const { return argCountAndCodeOriginValue.payload(); }
     int argumentCount() const { return argumentCountIncludingThis() - 1; }
@@ -60,6 +57,8 @@ struct ProtoCallFrame {
     JSValue thisValue() const { return thisArg.Register::jsValue(); }
     void setThisValue(JSValue value) { thisArg = value; }
 
+    bool needArityCheck() { return arityMissMatch; }
+
     JSValue argument(size_t argumentIndex)
     {
         ASSERT(static_cast<int>(argumentIndex) < argumentCount());
index 054b570e0088c60fef4777235354e1893e0c9863..e41da6271bac184b2f5b7f5d5413d15edb9777cc 100644 (file)
@@ -37,9 +37,8 @@ namespace JSC {
 
     class CodeBlock;
     class ExecState;
-    class JSActivation;
+    class JSLexicalEnvironment;
     class JSObject;
-    class JSPropertyNameIterator;
     class JSScope;
 
     typedef ExecState CallFrame;
@@ -57,13 +56,13 @@ namespace JSC {
         Register& operator=(CallFrame*);
         Register& operator=(CodeBlock*);
         Register& operator=(JSScope*);
+        Register& operator=(JSObject*);
 
         int32_t i() const;
-        JSActivation* activation() const;
+        JSLexicalEnvironment* lexicalEnvironment() const;
         CallFrame* callFrame() const;
         CodeBlock* codeBlock() const;
-        JSObject* function() const;
-        JSPropertyNameIterator* propertyNameIterator() const;
+        JSObject* object() const;
         JSScope* scope() const;
         int32_t unboxedInt32() const;
         int64_t unboxedInt52() const;
@@ -82,8 +81,6 @@ namespace JSC {
             return r;
         }
 
-        static Register withCallee(JSObject* callee);
-
     private:
         union {
             EncodedJSValue value;
index 19f95b92b1ebfa7e7927a94a33fdd902100c3f39..6496fa4d4570e7f13d7f3a3d0528c80d35834172 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "StackVisitor.h"
 
-#include "Arguments.h"
 #include "CallFrameInlines.h"
+#include "ClonedArguments.h"
 #include "Executable.h"
 #include "Interpreter.h"
 #include "JSCInlines.h"
@@ -38,7 +38,20 @@ namespace JSC {
 StackVisitor::StackVisitor(CallFrame* startFrame)
 {
     m_frame.m_index = 0;
-    readFrame(startFrame);
+    CallFrame* topFrame;
+    if (startFrame) {
+        m_frame.m_VMEntryFrame = startFrame->vm().topVMEntryFrame;
+        topFrame = startFrame->vm().topCallFrame;
+    } else {
+        m_frame.m_VMEntryFrame = 0;
+        topFrame = 0;
+    }
+    m_frame.m_callerIsVMEntryFrame = false;
+    readFrame(topFrame);
+
+    // Find the frame the caller wants to start unwinding from.
+    while (m_frame.callFrame() && m_frame.callFrame() != startFrame)
+        gotoNextFrame();
 }
 
 void StackVisitor::gotoNextFrame()
@@ -48,15 +61,15 @@ void StackVisitor::gotoNextFrame()
         InlineCallFrame* inlineCallFrame = m_frame.inlineCallFrame();
         CodeOrigin* callerCodeOrigin = &inlineCallFrame->caller;
         readInlinedFrame(m_frame.callFrame(), callerCodeOrigin);
-
-    } else
+        return;
+    }
 #endif // ENABLE(DFG_JIT)
-        readFrame(m_frame.callerFrame());
+    m_frame.m_VMEntryFrame = m_frame.m_CallerVMEntryFrame;
+    readFrame(m_frame.callerFrame());
 }
 
 void StackVisitor::readFrame(CallFrame* callFrame)
 {
-    ASSERT(!callFrame->isVMEntrySentinel());
     if (!callFrame) {
         m_frame.setToEnd();
         return;
@@ -104,9 +117,10 @@ void StackVisitor::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOri
 {
     m_frame.m_callFrame = callFrame;
     m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-    m_frame.m_callerFrame = callFrame->callerFrameSkippingVMEntrySentinel();
+    m_frame.m_CallerVMEntryFrame = m_frame.m_VMEntryFrame;
+    m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_CallerVMEntryFrame);
+    m_frame.m_callerIsVMEntryFrame = m_frame.m_CallerVMEntryFrame != m_frame.m_VMEntryFrame;
     m_frame.m_callee = callFrame->callee();
-    m_frame.m_scope = callFrame->scope();
     m_frame.m_codeBlock = callFrame->codeBlock();
     m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0
         : codeOrigin ? codeOrigin->bytecodeIndex
@@ -127,7 +141,6 @@ static int inlinedFrameOffset(CodeOrigin* codeOrigin)
 void StackVisitor::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin)
 {
     ASSERT(codeOrigin);
-    ASSERT(!callFrame->isVMEntrySentinel());
 
     int frameOffset = inlinedFrameOffset(codeOrigin);
     bool isInlined = !!frameOffset;
@@ -136,14 +149,15 @@ void StackVisitor::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin
 
         m_frame.m_callFrame = callFrame;
         m_frame.m_inlineCallFrame = inlineCallFrame;
-        m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size();
+        if (inlineCallFrame->argumentCountRegister.isValid())
+            m_frame.m_argumentCountIncludingThis = callFrame->r(inlineCallFrame->argumentCountRegister.offset()).unboxedInt32();
+        else
+            m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size();
         m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock();
         m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex;
 
         JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
-        m_frame.m_scope = callee->scope();
         m_frame.m_callee = callee;
-        ASSERT(m_frame.scope());
         ASSERT(m_frame.callee());
 
         // The callerFrame just needs to be non-null to indicate that we
@@ -182,7 +196,7 @@ String StackVisitor::Frame::functionName()
 
     switch (codeType()) {
     case CodeType::Eval:
-        traceLine = "eval code";
+        traceLine = ASCIILiteral("eval code");
         break;
     case CodeType::Native:
         if (callee)
@@ -192,7 +206,7 @@ String StackVisitor::Frame::functionName()
         traceLine = getCalculatedDisplayName(callFrame(), callee).impl();
         break;
     case CodeType::Global:
-        traceLine = "global code";
+        traceLine = ASCIILiteral("global code");
         break;
     }
     return traceLine.isNull() ? emptyString() : traceLine;
@@ -212,7 +226,7 @@ String StackVisitor::Frame::sourceURL()
         break;
     }
     case CodeType::Native:
-        traceLine = "[native code]";
+        traceLine = ASCIILiteral("[native code]");
         break;
     }
     return traceLine.isNull() ? emptyString() : traceLine;
@@ -241,48 +255,26 @@ String StackVisitor::Frame::toString()
     return traceBuild.toString().impl();
 }
 
-Arguments* StackVisitor::Frame::createArguments()
+ClonedArguments* StackVisitor::Frame::createArguments()
 {
     ASSERT(m_callFrame);
     CallFrame* physicalFrame = m_callFrame;
-    VM& vm = physicalFrame->vm();
-    Arguments* arguments;
+    ClonedArguments* arguments;
+    ArgumentsMode mode;
+    if (Options::enableFunctionDotArguments())
+        mode = ArgumentsMode::Cloned;
+    else
+        mode = ArgumentsMode::FakeValues;
 #if ENABLE(DFG_JIT)
     if (isInlinedFrame()) {
         ASSERT(m_inlineCallFrame);
-        arguments = Arguments::create(vm, physicalFrame, m_inlineCallFrame);
-        arguments->tearOff(physicalFrame, m_inlineCallFrame);
+        arguments = ClonedArguments::createWithInlineFrame(physicalFrame, physicalFrame, m_inlineCallFrame, mode);
     } else 
 #endif
-    {
-        arguments = Arguments::create(vm, physicalFrame);
-        arguments->tearOff(physicalFrame);
-    }
+        arguments = ClonedArguments::createWithMachineFrame(physicalFrame, physicalFrame, mode);
     return arguments;
 }
 
-Arguments* StackVisitor::Frame::existingArguments()
-{
-    if (codeBlock()->codeType() != FunctionCode)
-        return 0;
-    if (!codeBlock()->usesArguments())
-        return 0;
-    
-    VirtualRegister reg;
-        
-#if ENABLE(DFG_JIT)
-    if (isInlinedFrame())
-        reg = inlineCallFrame()->argumentsRegister;
-    else
-#endif // ENABLE(DFG_JIT)
-        reg = codeBlock()->argumentsRegister();
-    
-    JSValue result = callFrame()->r(unmodifiedArgumentsRegister(reg).offset()).jsValue();
-    if (!result || !result.isCell()) // Protect against Undefined in case we throw in op_enter.
-        return 0;
-    return jsCast<Arguments*>(result);
-}
-
 void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column)
 {
     CodeBlock* codeBlock = this->codeBlock();
@@ -299,8 +291,11 @@ void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column)
     unsigned divotColumn = 0;
     retrieveExpressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
 
-    line = divotLine + codeBlock->ownerExecutable()->lineNo();
+    line = divotLine + codeBlock->ownerExecutable()->firstLine();
     column = divotColumn + (divotLine ? 1 : codeBlock->firstLineColumnOffset());
+
+    if (codeBlock->ownerExecutable()->hasOverrideLineNumber())
+        line = codeBlock->ownerExecutable()->overrideLineNumber();
 }
 
 void StackVisitor::Frame::retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
@@ -318,34 +313,23 @@ void StackVisitor::Frame::setToEnd()
 #endif
 }
 
-#ifndef NDEBUG
-
-static const char* jitTypeName(JITCode::JITType jitType)
-{
-    switch (jitType) {
-    case JITCode::None: return "None";
-    case JITCode::HostCallThunk: return "HostCallThunk";
-    case JITCode::InterpreterThunk: return "InterpreterThunk";
-    case JITCode::BaselineJIT: return "BaselineJIT";
-    case JITCode::DFGJIT: return "DFGJIT";
-    case JITCode::FTLJIT: return "FTLJIT";
-    }
-    return "<unknown>";
-}
-
 static void printIndents(int levels)
 {
     while (levels--)
         dataLogFString("   ");
 }
 
-static void printif(int indentLevels, const char* format, ...)
+template<typename... Types>
+void log(unsigned indent, const Types&... values)
 {
-    va_list argList;
-    va_start(argList, format);
+    printIndents(indent);
+    dataLog(values...);
+}
 
-    if (indentLevels)
-        printIndents(indentLevels);
+template<typename... Types>
+void logF(unsigned indent, const char* format, const Types&... values)
+{
+    printIndents(indent);
 
 #if COMPILER(CLANG) || COMPILER(GCC)
 #pragma GCC diagnostic push
@@ -353,122 +337,82 @@ static void printif(int indentLevels, const char* format, ...)
 #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
 #endif
 
-    WTF::dataLogFV(format, argList);
+    dataLogF(format, values...);
 
 #if COMPILER(CLANG) || COMPILER(GCC)
 #pragma GCC diagnostic pop
 #endif
-
-    va_end(argList);
 }
 
-void StackVisitor::Frame::print(int indentLevel)
+void StackVisitor::Frame::print(int indent)
 {
-    int i = indentLevel;
-
     if (!this->callFrame()) {
-        printif(i, "frame 0x0\n");
+        log(indent, "frame 0x0\n");
         return;
     }
 
     CodeBlock* codeBlock = this->codeBlock();
-    printif(i, "frame %p {\n", this->callFrame());
+    logF(indent, "frame %p {\n", this->callFrame());
 
-    CallFrame* callFrame = m_callFrame;
-    CallFrame* callerFrame = this->callerFrame();
-    void* returnPC = callFrame->hasReturnPC() ? callFrame->returnPC().value() : nullptr;
+    {
+        indent++;
+
+        CallFrame* callFrame = m_callFrame;
+        CallFrame* callerFrame = this->callerFrame();
+        void* returnPC = callFrame->hasReturnPC() ? callFrame->returnPC().value() : nullptr;
 
-    printif(i, "   name '%s'\n", functionName().utf8().data());
-    printif(i, "   sourceURL '%s'\n", sourceURL().utf8().data());
-    printif(i, "   isVMEntrySentinel %d\n", callerFrame->isVMEntrySentinel());
+        log(indent, "name: ", functionName(), "\n");
+        log(indent, "sourceURL: ", sourceURL(), "\n");
 
+        bool isInlined = false;
 #if ENABLE(DFG_JIT)
-    printif(i, "   isInlinedFrame %d\n", isInlinedFrame());
-    if (isInlinedFrame())
-        printif(i, "   InlineCallFrame %p\n", m_inlineCallFrame);
+        isInlined = isInlinedFrame();
+        log(indent, "isInlinedFrame: ", isInlinedFrame(), "\n");
+        if (isInlinedFrame())
+            logF(indent, "InlineCallFrame: %p\n", m_inlineCallFrame);
 #endif
 
-    printif(i, "   callee %p\n", callee());
-    printif(i, "   returnPC %p\n", returnPC);
-    printif(i, "   callerFrame %p\n", callerFrame);
-    unsigned locationRawBits = callFrame->locationAsRawBits();
-    printif(i, "   rawLocationBits %u 0x%x\n", locationRawBits, locationRawBits);
-    printif(i, "   codeBlock %p\n", codeBlock);
-    if (codeBlock) {
-        JITCode::JITType jitType = codeBlock->jitType();
-        if (callFrame->hasLocationAsBytecodeOffset()) {
-            unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
-            printif(i, "      bytecodeOffset %u %p / %zu\n", bytecodeOffset, reinterpret_cast<void*>(bytecodeOffset), codeBlock->instructions().size());
+        logF(indent, "callee: %p\n", callee());
+        logF(indent, "returnPC: %p\n", returnPC);
+        logF(indent, "callerFrame: %p\n", callerFrame);
+        unsigned locationRawBits = callFrame->locationAsRawBits();
+        logF(indent, "rawLocationBits: %u 0x%x\n", locationRawBits, locationRawBits);
+        logF(indent, "codeBlock: %p ", codeBlock);
+        if (codeBlock)
+            dataLog(*codeBlock);
+        dataLog("\n");
+        if (codeBlock && !isInlined) {
+            indent++;
+
+            if (callFrame->hasLocationAsBytecodeOffset()) {
+                unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
+                log(indent, "bytecodeOffset: ", bytecodeOffset, " of ", codeBlock->instructions().size(), "\n");
 #if ENABLE(DFG_JIT)
-        } else {
-            unsigned codeOriginIndex = callFrame->locationAsCodeOriginIndex();
-            printif(i, "      codeOriginIdex %u %p / %zu\n", codeOriginIndex, reinterpret_cast<void*>(codeOriginIndex), codeBlock->codeOrigins().size());
+            } else {
+                log(indent, "hasCodeOrigins: ", codeBlock->hasCodeOrigins(), "\n");
+                if (codeBlock->hasCodeOrigins()) {
+                    unsigned codeOriginIndex = callFrame->locationAsCodeOriginIndex();
+                    log(indent, "codeOriginIndex: ", codeOriginIndex, " of ", codeBlock->codeOrigins().size(), "\n");
+
+                    JITCode::JITType jitType = codeBlock->jitType();
+                    if (jitType != JITCode::FTLJIT) {
+                        JITCode* jitCode = codeBlock->jitCode().get();
+                        logF(indent, "jitCode: %p start %p end %p\n", jitCode, jitCode->start(), jitCode->end());
+                    }
+                }
 #endif
+            }
+            unsigned line = 0;
+            unsigned column = 0;
+            computeLineAndColumn(line, column);
+            log(indent, "line: ", line, "\n");
+            log(indent, "column: ", column, "\n");
+
+            indent--;
         }
-        unsigned line = 0;
-        unsigned column = 0;
-        computeLineAndColumn(line, column);
-        printif(i, "      line %d\n", line);
-        printif(i, "      column %d\n", column);
-        printif(i, "      jitType %d <%s> isOptimizingJIT %d\n", jitType, jitTypeName(jitType), JITCode::isOptimizingJIT(jitType));
-#if ENABLE(DFG_JIT)
-        printif(i, "      hasCodeOrigins %d\n", codeBlock->hasCodeOrigins());
-        if (codeBlock->hasCodeOrigins()) {
-            JITCode* jitCode = codeBlock->jitCode().get();
-            printif(i, "         jitCode %p start %p end %p\n", jitCode, jitCode->start(), jitCode->end());
-        }
-#endif
+        indent--;
     }
-    printif(i, "}\n");
+    log(indent, "}\n");
 }
 
-#endif // NDEBUG
-
 } // namespace JSC
-
-#ifndef NDEBUG
-using JSC::StackVisitor;
-
-// For debugging use
-JS_EXPORT_PRIVATE void debugPrintCallFrame(JSC::CallFrame*);
-JS_EXPORT_PRIVATE void debugPrintStack(JSC::CallFrame* topCallFrame);
-
-class DebugPrintFrameFunctor {
-public:
-    enum Action {
-        PrintOne,
-        PrintAll
-    };
-
-    DebugPrintFrameFunctor(Action action)
-        : m_action(action)
-    {
-    }
-
-    StackVisitor::Status operator()(StackVisitor& visitor)
-    {
-        visitor->print(2);
-        return m_action == PrintAll ? StackVisitor::Continue : StackVisitor::Done;
-    }
-
-private:
-    Action m_action;
-};
-
-void debugPrintCallFrame(JSC::CallFrame* callFrame)
-{
-    if (!callFrame)
-        return;
-    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintOne);
-    callFrame->iterate(functor);
-}
-
-void debugPrintStack(JSC::CallFrame* topCallFrame)
-{
-    if (!topCallFrame)
-        return;
-    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintAll);
-    topCallFrame->iterate(functor);
-}
-
-#endif // !NDEBUG
index 990a226b3053df38fd3989f25e6f1feb32ede457..0036a789c58e19ae13b0d4abfb75583e9bb46734 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #ifndef StackVisitor_h
 #define StackVisitor_h
 
+#include "VMEntryRecord.h"
 #include <wtf/text/WTFString.h>
 
 namespace JSC {
@@ -33,12 +34,12 @@ namespace JSC {
 struct CodeOrigin;
 struct InlineCallFrame;
 
-class Arguments;
 class CodeBlock;
 class ExecState;
 class JSFunction;
 class JSObject;
 class JSScope;
+class ClonedArguments;
 class Register;
 
 typedef ExecState CallFrame;
@@ -56,9 +57,9 @@ public:
 
         size_t index() const { return m_index; }
         size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; }
+        bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
         CallFrame* callerFrame() const { return m_callerFrame; }
         JSObject* callee() const { return m_callee; }
-        JSScope* scope() const { return m_scope; }
         CodeBlock* codeBlock() const { return m_codeBlock; }
         unsigned bytecodeOffset() const { return m_bytecodeOffset; }
 #if ENABLE(DFG_JIT)
@@ -77,13 +78,11 @@ public:
         CodeType codeType() const;
         JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
 
-        Arguments* createArguments();
-        Arguments* existingArguments();
+        ClonedArguments* createArguments();
+        VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
         CallFrame* callFrame() const { return m_callFrame; }
         
-#ifndef NDEBUG
         JS_EXPORT_PRIVATE void print(int indentLevel);
-#endif
 
     private:
         Frame() { }
@@ -94,11 +93,13 @@ public:
 
         size_t m_index;
         size_t m_argumentCountIncludingThis;
+        VMEntryFrame* m_VMEntryFrame;
+        VMEntryFrame* m_CallerVMEntryFrame;
         CallFrame* m_callerFrame;
         JSObject* m_callee;
-        JSScope* m_scope;
         CodeBlock* m_codeBlock;
         unsigned m_bytecodeOffset;
+        bool m_callerIsVMEntryFrame;
 #if ENABLE(DFG_JIT)
         InlineCallFrame* m_inlineCallFrame;
 #endif
@@ -144,6 +145,32 @@ private:
     Frame m_frame;
 };
 
+class CallerFunctor {
+public:
+    CallerFunctor()
+        : m_hasSkippedFirstFrame(false)
+        , m_callerFrame(0)
+    {
+    }
+
+    CallFrame* callerFrame() const { return m_callerFrame; }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        if (!m_hasSkippedFirstFrame) {
+            m_hasSkippedFirstFrame = true;
+            return StackVisitor::Continue;
+        }
+
+        m_callerFrame = visitor->callFrame();
+        return StackVisitor::Done;
+    }
+    
+private:
+    bool m_hasSkippedFirstFrame;
+    CallFrame* m_callerFrame;
+};
+
 } // namespace JSC
 
 #endif // StackVisitor_h
diff --git a/interpreter/VMEntryRecord.h b/interpreter/VMEntryRecord.h
new file mode 100644 (file)
index 0000000..50ac65f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VMEntryRecord_h
+#define VMEntryRecord_h
+
+namespace JSC {
+
+typedef void VMEntryFrame;
+
+class ExecState;
+class VM;
+
+struct VMEntryRecord {
+    /*
+     * This record stored in a vmEntryTo{JavaScript,Host} allocated frame. It is allocated on the stack
+     * after callee save registers where local variables would go.
+     */
+    VM* m_vm;
+    ExecState* m_prevTopCallFrame;
+    VMEntryFrame* m_prevTopVMEntryFrame;
+
+    ExecState* prevTopCallFrame() { return m_prevTopCallFrame; }
+
+    VMEntryFrame* prevTopVMEntryFrame() { return m_prevTopVMEntryFrame; }
+};
+
+extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame*);
+
+} // namespace JSC
+
+#endif // VMEntryRecord_h
diff --git a/interpreter/VMInspector.cpp b/interpreter/VMInspector.cpp
deleted file mode 100644 (file)
index e4cd267..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "VMInspector.h"
-
-#if ENABLE(VMINSPECTOR)
-
-#include "JSCInlines.h"
-#include <wtf/ASCIICType.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
-const char* VMInspector::getTypeName(JSValue value)
-{
-    if (value.isInt32())
-        return "<Int32>";
-    if (value.isBoolean())
-        return "<Boolean>";
-    if (value.isNull())
-        return "<Empty>";
-    if (value.isUndefined())
-        return "<Undefined>";
-    if (value.isCell())
-        return "<Cell>";
-    if (value.isEmpty())
-        return "<Empty>";
-    return "";
-}
-
-void VMInspector::dumpFrame0(CallFrame* frame)
-{
-    dumpFrame(frame, 0, 0, 0, 0);
-}
-
-void VMInspector::dumpFrame(CallFrame* frame, const char* prefix,
-                            const char* funcName, const char* file, int line)
-{
-    int frameCount = VMInspector::countFrames(frame);
-    if (frameCount < 0)
-        return;
-
-    Instruction* vPC = 0;
-    if (frame->codeBlock())
-        vPC = frame->currentVPC();
-
-    #define CAST reinterpret_cast
-
-    if (prefix)
-        printf("%s ", prefix);
-
-    printf("frame [%d] %p { cb %p:%s, retPC %p:%s, scope %p:%s, callee %p:%s, callerFrame %p:%s, argc %d, vPC %p }",
-        frameCount, frame,
-        CAST<void*>(frame[JSStack::CodeBlock].payload()),
-        getTypeName(frame[JSStack::CodeBlock].jsValue()),
-        CAST<void*>(frame[JSStack::ReturnPC].payload()),
-        getTypeName(frame[JSStack::ReturnPC].jsValue()),
-        CAST<void*>(frame[JSStack::ScopeChain].payload()),
-        getTypeName(frame[JSStack::ScopeChain].jsValue()),
-        CAST<void*>(frame[JSStack::Callee].payload()),
-        getTypeName(frame[JSStack::Callee].jsValue()),
-        CAST<void*>(frame[JSStack::CallerFrame].callFrame()),
-        getTypeName(frame[JSStack::CallerFrame].jsValue()),
-        frame[JSStack::ArgumentCount].payload(),
-        vPC);
-
-    if (funcName || file || (line >= 0)) {
-        printf(" @");
-        if (funcName)
-            printf(" %s", funcName);
-        if (file)
-            printf(" %s", file);
-        if (line >= 0)
-            printf(":%d", line);
-    }
-    printf("\n");
-}
-
-int VMInspector::countFrames(CallFrame* frame)
-{
-    int count = -1;
-    while (frame && !frame->isVMEntrySentinel()) {
-        count++;
-        frame = frame->callerFrame();
-    }
-    return count;
-}
-
-
-//============================================================================
-//  class FormatPrinter
-//    - implements functionality to support fprintf.
-//
-//    The FormatPrinter classes do the real formatting and printing.
-//    By default, the superclass FormatPrinter will print to stdout (printf).
-//    Each of the subclass will implement the other ...printf() options.
-//    The subclasses are:
-//
-//        FileFormatPrinter     - fprintf
-//        StringFormatPrinter   - sprintf
-//        StringNFormatPrinter  - snprintf
-
-class FormatPrinter {
-public:
-    virtual ~FormatPrinter() { }
-
-    void print(const char* format, va_list args);
-
-protected:
-    // Low level printers:
-    bool printArg(const char* format, ...);
-    virtual bool printArg(const char* format, va_list args);
-
-    // JS type specific printers:
-    void printWTFString(va_list args, bool verbose);
-};
-
-
-// The public print() function is the real workhorse behind the printf
-// family of functions. print() deciphers the % formatting, translate them
-// to primitive formats, and dispatches to underlying printArg() functions
-// to do the printing.
-// 
-// The non-public internal printArg() function is virtual and is responsible
-// for handling the variations between printf, fprintf, sprintf, and snprintf.
-
-void FormatPrinter::print(const char* format, va_list args)
-{
-    const char* p = format;
-    const char* errorStr;
-
-    // buffer is only used for 2 purposes:
-    // 1. To temporarily hold a copy of normal chars (not needing formatting)
-    //    to be passed to printArg() and printed.
-    //
-    //    The incoming format string may contain a string of normal chars much
-    //    longer than 128, but we handle this by breaking them out to 128 chars
-    //    fragments and printing each fragment before re-using the buffer to
-    //    load up the next fragment.
-    //
-    // 2. To hold a single "%..." format to be passed to printArg() to process
-    //    a single va_arg.
-
-    char buffer[129]; // 128 chars + null terminator.
-    char* end = &buffer[sizeof(buffer) - 1];
-    const char* startOfFormatSpecifier = 0;
-
-    while (true) {
-        char c = *p++;
-        char* curr = buffer;
-
-        // Print leading normal chars:
-        while (c != '\0' && c != '%') {
-            *curr++ = c;
-            if (curr == end) {
-                // Out of buffer space. Flush the fragment, and start over.
-                *curr = '\0';
-                bool success = printArg("%s", buffer);
-                if (!success) {
-                    errorStr = buffer;
-                    goto handleError;
-                }
-                curr = buffer;
-            }
-            c = *p++;
-        }
-        // If we have stuff in the buffer, flush the fragment:
-        if (curr != buffer) {
-            ASSERT(curr < end + 1);
-            *curr = '\0';
-            bool success = printArg("%s", buffer);
-            if (!success) {
-                errorStr = buffer;
-                goto handleError;
-            }
-        }
-
-        // End if there are not more chars to print:
-        if (c == '\0')
-            break;
-
-        // If we get here, we've must have seen a '%':
-        startOfFormatSpecifier = p - 1;
-        ASSERT(*startOfFormatSpecifier == '%');
-        c = *p++;
-
-        // Check for "%%" case:
-        if (c == '%') {
-            bool success = printArg("%c", '%');
-            if (!success) {
-                errorStr = p - 2;
-                goto handleError;
-            }
-            continue;
-        }
-
-        // Check for JS (%J<x>) formatting extensions:
-        if (c == 'J') {
-            bool verbose = false;
-
-            c = *p++;
-            if (UNLIKELY(c == '\0')) {
-                errorStr = p - 2; // Rewind to % in "%J\0"
-                goto handleError;
-            }
-
-            if (c == '+') {
-                verbose = true;
-                c= *p++;
-                if (UNLIKELY(c == '\0')) {
-                    errorStr = p - 3; // Rewind to % in "%J+\0"
-                    goto handleError;
-                }
-            }
-
-            switch (c) {
-            // %Js - WTF::String*
-            case 's': {
-                printWTFString(args, verbose);
-                continue;
-            }
-            } // END switch.
-
-        // Check for non-JS extensions:
-        } else if (c == 'b') {
-            int value = va_arg(args, int);
-            printArg("%s", value ? "TRUE" : "FALSE");
-            continue;
-        }
-
-        // If we didn't handle the format in one of the above cases,
-        // rewind p and let the standard formatting check handle it
-        // if possible:
-        p = startOfFormatSpecifier;
-        ASSERT(*p == '%');
-
-        // Check for standard formatting:
-        // A format specifier always starts with a % and ends with some
-        // alphabet. We'll do the simple thing and scan until the next
-        // alphabet, or the end of string.
-
-        // In the following, we're going to use buffer as storage for a copy
-        // of a single format specifier. Hence, conceptually, we can think of
-        // 'buffer' as synonymous with 'argFormat' here:
-
-#define ABORT_IF_FORMAT_TOO_LONG(curr) \
-        do {                           \
-            if (UNLIKELY(curr >= end)) \
-                goto formatTooLong;    \
-        } while (false)
-        
-        curr = buffer;
-        *curr++ = *p++; // Output the first % in the format specifier.
-        c = *p++; // Grab the next char in the format specifier.
-
-        // Checks for leading modifiers e.g. "%-d":
-        //     0, -, ' ', +, '\''
-        if (c == '0' || c == '-' || c == ' ' || c == '+' || c == '\'' || c == '#') {
-            ABORT_IF_FORMAT_TOO_LONG(curr);
-            *curr++ = c;
-            c = *p++;
-        }
-
-        // Checks for decimal digit field width modifiers e.g. "%2f":
-        while (c >= '0' && c <= '9') {
-            ABORT_IF_FORMAT_TOO_LONG(curr);
-            *curr++ = c;
-            c = *p++;
-        }
-
-        // Checks for '.' e.g. "%2.f":
-        if (c == '.') {
-            ABORT_IF_FORMAT_TOO_LONG(curr);
-            *curr++ = c;
-            c = *p++;
-
-            // Checks for decimal digit precision modifiers  e.g. "%.2f":
-            while (c >= '0' && c <= '9') {
-                ABORT_IF_FORMAT_TOO_LONG(curr);
-                *curr++ = c;
-                c = *p++;
-            }
-        }
-
-        // Checks for the modifier <m> where <m> can be:
-        //     l, h, j, t, z
-        // e.g. "%ld"
-        if (c == 'l' || c == 'h' || c == 'j' || c == 't' || c == 'z' || c == 'L') {
-            ABORT_IF_FORMAT_TOO_LONG(curr);
-            *curr++ = c;
-            char prevChar = c;
-            c = *p++;
-
-            // Checks for the modifier ll or hh in %<x><m>:
-            if ((prevChar == 'l' || prevChar == 'h') && c == prevChar) {
-                ABORT_IF_FORMAT_TOO_LONG(curr);
-                *curr++ = c;
-                c = *p++;
-            }
-        }
-
-        // Checks for %<x> where <x> can be:
-        //     d, i, n, o, u, x, X
-        // But hey, we're just going to do the simple thing and allow any
-        // alphabet. The user is expected to pass correct format specifiers.
-        // We won't do any format checking here. We'll just pass it on, and the
-        // underlying ...printf() implementation may do the needed checking
-        // at its discretion.
-        while (c != '\0' && !isASCIIAlpha(c)) {
-            ABORT_IF_FORMAT_TOO_LONG(curr);
-            *curr++ = c;
-            c = *p++;
-        }
-
-        ABORT_IF_FORMAT_TOO_LONG(curr);
-        *curr++ = c;
-        if (c == '\0') {
-            // Uh oh. Bad format. We should have gotten an alphabet instead.
-            // Print the supposed format as a string instead:
-            errorStr = buffer;
-            goto handleError;
-        }
-
-        // Otherwise, we have the alpha that terminates the format.
-        // Terminate the buffer (i.e. argFormat) string:
-        ASSERT(isASCIIAlpha(c));
-        ABORT_IF_FORMAT_TOO_LONG(curr);
-        *curr = '\0';
-
-        bool success = printArg(buffer, args);
-        if (!success) {
-            errorStr = buffer;
-            goto handleError;
-        }
-    }
-#undef ABORT_IF_FORMAT_TOO_LONG
-
-    return;
-
-formatTooLong:
-    // Print the error string:
-    ASSERT(!!startOfFormatSpecifier);
-    p = startOfFormatSpecifier;
-    ASSERT(p >= format);
-    printArg("ERROR @ Format too long at \"%s\"\n", p);
-    return;
-
-handleError:
-    // We've got an error. Can't do any more work. Print an error message if
-    // possible and then just return.
-
-    // The errorStr may be pointing into the middle of buffer, or the original
-    // format string. Move the string to buffer for consistency, and also so
-    // that we can strip it of newlines below.
-    if (errorStr != buffer) {
-        size_t length = strlen(errorStr);
-        if (length > sizeof(buffer) - 1)
-            length = sizeof(buffer) - 1;
-        memmove(buffer, errorStr, length);
-        buffer[length] = '\0'; // Terminate the moved error string.
-    }
-    // Strip the newlines:
-    char* cp = buffer;
-    while (*cp) {
-        if (*cp == '\n' || *cp == '\r')
-            *cp = ' ';
-        cp++;
-    }
-    // Print the error string:
-    printArg("ERROR @ \"%s\"\n", buffer);
-}
-
-
-bool FormatPrinter::printArg(const char* format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    bool success = printArg(format, args);
-    va_end(args);
-    return success;
-}
-
-bool FormatPrinter::printArg(const char* format, va_list args)
-{
-    int count = ::vprintf(format, args);
-    return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-// %Js - WTF::String*
-// verbose mode prints: WTF::String "<your string>"
-void FormatPrinter::printWTFString(va_list args, bool verbose)
-{
-    const String* str = va_arg(args, const String*);
-
-    // Print verbose header if appropriate:
-    if (verbose)
-        printArg("WTF::String \"");
-
-    // Print the string itself:
-    if (!str->isEmpty()) {
-        if (str->is8Bit()) {
-            const LChar* chars = str->characters8();
-            printArg("%s", reinterpret_cast<const char*>(chars));
-        } else {
-            const UChar* chars = str->characters16();
-            printArg("%S", reinterpret_cast<const wchar_t*>(chars));
-        }
-    }
-
-    // Print verbose footer if appropriate:
-    if (verbose)
-        printArg("\"");
-}
-
-
-//============================================================================
-//  class FileFormatPrinter
-//    - implements functionality to support fprintf.
-
-class FileFormatPrinter: public FormatPrinter {
-public:
-    FileFormatPrinter(FILE*);
-private:
-    virtual bool printArg(const char* format, va_list args);
-
-    FILE* m_file;
-};
-
-FileFormatPrinter::FileFormatPrinter(FILE* file)
-    : m_file(file)
-{ 
-}
-
-bool FileFormatPrinter::printArg(const char* format, va_list args)
-{
-    int count = ::vfprintf(m_file, format, args);
-    return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-//============================================================================
-//  class StringFormatPrinter
-//    - implements functionality to support sprintf.
-
-class StringFormatPrinter: public FormatPrinter {
-public:
-    StringFormatPrinter(char* buffer);
-private:
-    virtual bool printArg(const char* format, va_list args);
-
-    char* m_buffer;
-};
-
-StringFormatPrinter::StringFormatPrinter(char* buffer)
-    : m_buffer(buffer)
-{ 
-}
-
-bool StringFormatPrinter::printArg(const char* format, va_list args)
-{
-    int count = ::vsprintf(m_buffer, format, args);
-    m_buffer += count;
-    return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-//============================================================================
-//  class StringNFormatPrinter
-//    - implements functionality to support snprintf.
-
-class StringNFormatPrinter: public FormatPrinter {
-public:
-    StringNFormatPrinter(char* buffer, size_t);
-private:
-    virtual bool printArg(const char* format, va_list args);
-
-    char* m_buffer;
-    size_t m_size;
-};
-
-
-StringNFormatPrinter::StringNFormatPrinter(char* buffer, size_t size)
-    : m_buffer(buffer)
-    , m_size(size)
-{
-}
-
-bool StringNFormatPrinter::printArg(const char* format, va_list args)
-{
-    if (m_size > 0) {
-        int count = ::vsnprintf(m_buffer, m_size, format, args);
-
-        // According to vsnprintf specs, ...
-        bool success = (count >= 0);
-        if (static_cast<size_t>(count) >= m_size) {
-            // If count > size, then we didn't have enough buffer space.
-            count = m_size;
-        }
-
-        // Adjust the buffer to what's left if appropriate:
-        if (success) {
-            m_buffer += count;
-            m_size -= count;
-        }
-        return success;
-    }
-    // No more room to print. Declare it a fail:
-    return false;
-}
-
-
-//============================================================================
-//  VMInspector printf family of methods:
-
-void VMInspector::fprintf(FILE* file, const char* format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    FileFormatPrinter(file).print(format, args);
-    va_end(args);
-}
-
-void VMInspector::printf(const char* format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    FormatPrinter().print(format, args);
-    va_end(args);
-}
-
-void VMInspector::sprintf(char* buffer, const char* format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    StringFormatPrinter(buffer).print(format, args);
-    va_end(args);
-}
-
-void VMInspector::snprintf(char* buffer, size_t size, const char* format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    StringNFormatPrinter(buffer, size).print(format, args);
-    va_end(args);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(VMINSPECTOR)
diff --git a/interpreter/VMInspector.h b/interpreter/VMInspector.h
deleted file mode 100644 (file)
index 6623068..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef VMInspector_h
-#define VMInspector_h
-
-#define ENABLE_VMINSPECTOR 0
-
-#include "CallFrame.h"
-#include "JSCJSValue.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
-#if ENABLE(VMINSPECTOR)
-
-class VMInspector {
-public:    
-    static JS_EXPORT_PRIVATE const char* getTypeName(JSValue);
-    static JS_EXPORT_PRIVATE void dumpFrame0(CallFrame*);
-    static JS_EXPORT_PRIVATE void dumpFrame(CallFrame*, const char* prefix = 0, const char* funcName = 0, const char* file = 0, int line = -1);
-    static JS_EXPORT_PRIVATE int countFrames(CallFrame*);
-
-    // Special family of ...printf() functions that support, in addition to the
-    // standard % formats (e.g. %d, %s, etc), the following extra JSC formatting
-    // options, %J<x>, where <x> consists of:
-    //
-    //   +    - verbose mode modifier.
-    //          Used in combination with other options. Must come after the %J.
-    //   s    - WTF::String*
-    //
-    // Examples of usage:
-    //
-    //    WTF::String str("My WTF String");
-    //
-    //    // Printing the string. Will print:
-    //    // The wtf string says: "My WTF String" and is NOT EMPTY.
-    //
-    //    VMInspector::printf("The wtf string says: \"%Js\" and is %s\n",
-    //        &str, str.isEmpty()?"EMPTY":"NOT EMPTY");
-    //
-    //    // Printing the string with verbose mode. Will print:
-    //    // <WTF::String "My WTF String">
-    //
-    //    VMInspector::printf("<%J+s>\n", &str);
-    //
-    // Also added some convenience non-JS formats:
-    //
-    //   %b    - boolean (va_args will look for an int).
-    //           Prints TRUE if non-zero, else prints FALSE.
-    //
-    // Caution: the user is expected to pass the correctly matched arguments
-    // to pair with the corresponding % fomatting.
-
-    static JS_EXPORT_PRIVATE void fprintf(FILE*, const char* format, ...);
-    static JS_EXPORT_PRIVATE void printf(const char* format, ...);
-    static JS_EXPORT_PRIVATE void sprintf(char*, const char* format, ...);
-    static JS_EXPORT_PRIVATE void snprintf(char*, size_t, const char* format, ...);
-};
-
-#endif // ENABLE(VMINSPECTOR)
-
-} // namespace JSC
-
-#endif // VMInspector.h
index d5d38554c4ecc54717a9e34276f7c68001bf5e35..0d1074773c0269dfa34a58e175ca998c11a3e8de 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace JSC {
 
-struct CallLinkInfo;
+class CallLinkInfo;
 
 // JIT stub routine for use by JavaScript accessors. These will be making a JS
 // call that requires inline caching. 
@@ -46,7 +46,6 @@ public:
     
     virtual bool visitWeak(RepatchBuffer&) override;
     
-private:
     std::unique_ptr<CallLinkInfo> m_callLinkInfo;
 };
 
index 7e9b77d2a1061e1634a983e5ba0cd59d9df7199d..d522b8125a46d77687f0365b10608cc2c35b109e 100644 (file)
@@ -97,7 +97,8 @@ CodeLocationLabel* ArityCheckFailReturnThunks::returnPCsFor(
         jit.jump(GPRInfo::regT2);
     }
     
-    LinkBuffer linkBuffer(vm, jit, GLOBAL_THUNK_ID);
+    // Sadly, we cannot fail here because the LLInt may need us.
+    LinkBuffer linkBuffer(vm, jit, GLOBAL_THUNK_ID, JITCompilationMustSucceed);
     
     unsigned returnPCsSize = numExpectedArgumentsIncludingThis / stackAlignmentRegisters() + 1;
     std::unique_ptr<CodeLocationLabel[]> returnPCs =
index 059e5d9bbd683a2a89226f84defdde30f5fd18b5..09133a8e60a40b779aec5fb19463574bc61619df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -212,15 +212,27 @@ void AssemblyHelpers::callExceptionFuzz()
     addPtr(TrustedImm32(stackAlignmentBytes()), stackPointerRegister);
 }
 
-AssemblyHelpers::Jump AssemblyHelpers::emitExceptionCheck(ExceptionCheckKind kind)
+AssemblyHelpers::Jump AssemblyHelpers::emitExceptionCheck(ExceptionCheckKind kind, ExceptionJumpWidth width)
 {
     callExceptionFuzz();
+
+    if (width == FarJumpWidth)
+        kind = (kind == NormalExceptionCheck ? InvertedExceptionCheck : NormalExceptionCheck);
     
+    Jump result;
 #if USE(JSVALUE64)
-    return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException()));
+    result = branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException()));
 #elif USE(JSVALUE32_64)
-    return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+    result = branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(vm()->addressOfException()), TrustedImm32(0));
 #endif
+    
+    if (width == NormalJumpWidth)
+        return result;
+    
+    PatchableJump realJump = patchableJump();
+    result.link(this);
+    
+    return realJump.m_jump;
 }
 
 void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, TrustedImmPtr structure, RegisterID dest)
index 9aa39f2cada5c431205711d2957a4ae8e15ca28f..d0cdf96ea1ce2fd40199d8a30391e66d9bcb08fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 #include "GPRInfo.h"
 #include "JITCode.h"
 #include "MacroAssembler.h"
+#include "TypeofType.h"
 #include "VM.h"
 
 namespace JSC {
@@ -88,6 +89,61 @@ public:
 #endif
     }
     
+    void storeValue(JSValueRegs regs, BaseIndex address)
+    {
+#if USE(JSVALUE64)
+        store64(regs.gpr(), address);
+#else
+        store32(regs.payloadGPR(), address.withOffset(PayloadOffset));
+        store32(regs.tagGPR(), address.withOffset(TagOffset));
+#endif
+    }
+    
+    void storeValue(JSValueRegs regs, void* address)
+    {
+#if USE(JSVALUE64)
+        store64(regs.gpr(), address);
+#else
+        store32(regs.payloadGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + PayloadOffset));
+        store32(regs.tagGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + TagOffset));
+#endif
+    }
+    
+    void loadValue(Address address, JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        load64(address, regs.gpr());
+#else
+        if (address.base == regs.payloadGPR()) {
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+        } else {
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+        }
+#endif
+    }
+    
+    void loadValue(BaseIndex address, JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        load64(address, regs.gpr());
+#else
+        if (address.base == regs.payloadGPR() || address.index == regs.payloadGPR()) {
+            // We actually could handle the case where the registers are aliased to both
+            // tag and payload, but we don't for now.
+            RELEASE_ASSERT(address.base != regs.tagGPR());
+            RELEASE_ASSERT(address.index != regs.tagGPR());
+            
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+        } else {
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+        }
+#endif
+    }
+    
     void moveTrustedValue(JSValue value, JSValueRegs regs)
     {
 #if USE(JSVALUE64)
@@ -97,6 +153,26 @@ public:
         move(TrustedImm32(value.payload()), regs.payloadGPR());
 #endif
     }
+    
+    void storeTrustedValue(JSValue value, Address address)
+    {
+#if USE(JSVALUE64)
+        store64(TrustedImm64(JSValue::encode(value)), address);
+#else
+        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
+        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
+#endif
+    }
+
+    void storeTrustedValue(JSValue value, BaseIndex address)
+    {
+#if USE(JSVALUE64)
+        store64(TrustedImm64(JSValue::encode(value)), address);
+#else
+        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
+        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
+#endif
+    }
 
 #if CPU(X86_64) || CPU(X86)
     static size_t prologueStackPointerDelta()
@@ -198,6 +274,20 @@ public:
         return 2 * sizeof(void*);
     }
 
+    void emitFunctionPrologue()
+    {
+        push(linkRegister);
+        push(framePointerRegister);
+        move(stackPointerRegister, framePointerRegister);
+    }
+
+    void emitFunctionEpilogue()
+    {
+        move(framePointerRegister, stackPointerRegister);
+        pop(framePointerRegister);
+        pop(linkRegister);
+    }
+
     ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
     {
         m_assembler.stspr(reg);
@@ -214,10 +304,20 @@ public:
     }
 #endif
 
-    void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
+    void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
     {
-        loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
+        loadPtr(Address(from, entry * sizeof(Register)), to);
     }
+    void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
+    {
+        load32(Address(from, entry * sizeof(Register)), to);
+    }
+#if USE(JSVALUE64)
+    void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, GPRReg to, GPRReg from = GPRInfo::callFrameRegister)
+    {
+        load64(Address(from, entry * sizeof(Register)), to);
+    }
+#endif // USE(JSVALUE64)
     void emitPutToCallFrameHeader(GPRReg from, JSStack::CallFrameHeaderEntry entry)
     {
         storePtr(from, Address(GPRInfo::callFrameRegister, entry * sizeof(Register)));
@@ -268,6 +368,36 @@ public:
         storePtr(tag, Address(stackPointerRegister, entry * static_cast<ptrdiff_t>(sizeof(Register)) - prologueStackPointerDelta() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     }
 #endif
+    
+    JumpList branchIfNotEqual(JSValueRegs regs, JSValue value)
+    {
+#if USE(JSVALUE64)
+        return branch64(NotEqual, regs.gpr(), TrustedImm64(JSValue::encode(value)));
+#else
+        JumpList result;
+        result.append(branch32(NotEqual, regs.tagGPR(), TrustedImm32(value.tag())));
+        if (value.isEmpty() || value.isUndefinedOrNull())
+            return result; // These don't have anything interesting in the payload.
+        result.append(branch32(NotEqual, regs.payloadGPR(), TrustedImm32(value.payload())));
+        return result;
+#endif
+    }
+    
+    Jump branchIfEqual(JSValueRegs regs, JSValue value)
+    {
+#if USE(JSVALUE64)
+        return branch64(Equal, regs.gpr(), TrustedImm64(JSValue::encode(value)));
+#else
+        Jump notEqual;
+        // These don't have anything interesting in the payload.
+        if (!value.isEmpty() && !value.isUndefinedOrNull())
+            notEqual = branch32(NotEqual, regs.payloadGPR(), TrustedImm32(value.payload()));
+        Jump result = branch32(Equal, regs.tagGPR(), TrustedImm32(value.tag()));
+        if (notEqual.isSet())
+            notEqual.link(this);
+        return result;
+#endif
+    }
 
     Jump branchIfNotCell(GPRReg reg)
     {
@@ -277,6 +407,161 @@ public:
         return branch32(MacroAssembler::NotEqual, reg, TrustedImm32(JSValue::CellTag));
 #endif
     }
+    Jump branchIfNotCell(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branchIfNotCell(regs.gpr());
+#else
+        return branchIfNotCell(regs.tagGPR());
+#endif
+    }
+    
+    Jump branchIfCell(GPRReg reg)
+    {
+#if USE(JSVALUE64)
+        return branchTest64(MacroAssembler::Zero, reg, GPRInfo::tagMaskRegister);
+#else
+        return branch32(MacroAssembler::Equal, reg, TrustedImm32(JSValue::CellTag));
+#endif
+    }
+    Jump branchIfCell(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branchIfCell(regs.gpr());
+#else
+        return branchIfCell(regs.tagGPR());
+#endif
+    }
+    
+    Jump branchIfOther(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        move(regs.gpr(), tempGPR);
+        and64(TrustedImm32(~TagBitUndefined), tempGPR);
+        return branch64(Equal, tempGPR, TrustedImm64(ValueNull));
+#else
+        or32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(Equal, tempGPR, TrustedImm32(JSValue::NullTag));
+#endif
+    }
+    
+    Jump branchIfNotOther(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        move(regs.gpr(), tempGPR);
+        and64(TrustedImm32(~TagBitUndefined), tempGPR);
+        return branch64(NotEqual, tempGPR, TrustedImm64(ValueNull));
+#else
+        or32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(NotEqual, tempGPR, TrustedImm32(JSValue::NullTag));
+#endif
+    }
+    
+    Jump branchIfInt32(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branch64(AboveOrEqual, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::Int32Tag));
+#endif
+    }
+    
+    Jump branchIfNotInt32(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branch64(Below, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        return branch32(NotEqual, regs.tagGPR(), TrustedImm32(JSValue::Int32Tag));
+#endif
+    }
+
+    // Note that the tempGPR is not used in 64-bit mode.
+    Jump branchIfNumber(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        UNUSED_PARAM(tempGPR);
+        return branchTest64(NonZero, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        add32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(Below, tempGPR, TrustedImm32(JSValue::LowestTag + 1));
+#endif
+    }
+    
+    // Note that the tempGPR is not used in 64-bit mode.
+    Jump branchIfNotNumber(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        UNUSED_PARAM(tempGPR);
+        return branchTest64(Zero, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        add32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(AboveOrEqual, tempGPR, TrustedImm32(JSValue::LowestTag + 1));
+#endif
+    }
+
+    // Note that the tempGPR is not used in 32-bit mode.
+    Jump branchIfBoolean(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        move(regs.gpr(), tempGPR);
+        xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), tempGPR);
+        return branchTest64(Zero, tempGPR, TrustedImm32(static_cast<int32_t>(~1)));
+#else
+        UNUSED_PARAM(tempGPR);
+        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::BooleanTag));
+#endif
+    }
+    
+    // Note that the tempGPR is not used in 32-bit mode.
+    Jump branchIfNotBoolean(JSValueRegs regs, GPRReg tempGPR)
+    {
+#if USE(JSVALUE64)
+        move(regs.gpr(), tempGPR);
+        xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), tempGPR);
+        return branchTest64(NonZero, tempGPR, TrustedImm32(static_cast<int32_t>(~1)));
+#else
+        UNUSED_PARAM(tempGPR);
+        return branch32(NotEqual, regs.tagGPR(), TrustedImm32(JSValue::BooleanTag));
+#endif
+    }
+    
+    Jump branchIfObject(GPRReg cellGPR)
+    {
+        return branch8(
+            AboveOrEqual, Address(cellGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+    }
+    
+    Jump branchIfNotObject(GPRReg cellGPR)
+    {
+        return branch8(
+            Below, Address(cellGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+    }
+    
+    Jump branchIfType(GPRReg cellGPR, JSType type)
+    {
+        return branch8(Equal, Address(cellGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(type));
+    }
+    
+    Jump branchIfNotType(GPRReg cellGPR, JSType type)
+    {
+        return branch8(NotEqual, Address(cellGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(type));
+    }
+    
+    Jump branchIfString(GPRReg cellGPR) { return branchIfType(cellGPR, StringType); }
+    Jump branchIfNotString(GPRReg cellGPR) { return branchIfNotType(cellGPR, StringType); }
+    Jump branchIfSymbol(GPRReg cellGPR) { return branchIfType(cellGPR, SymbolType); }
+    Jump branchIfNotSymbol(GPRReg cellGPR) { return branchIfNotType(cellGPR, SymbolType); }
+    Jump branchIfFunction(GPRReg cellGPR) { return branchIfType(cellGPR, JSFunctionType); }
+    Jump branchIfNotFunction(GPRReg cellGPR) { return branchIfNotType(cellGPR, JSFunctionType); }
+    
+    Jump branchIfEmpty(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branchTest64(Zero, regs.gpr());
+#else
+        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::EmptyValueTag));
+#endif
+    }
     
     static Address addressForByteOffset(ptrdiff_t byteOffset)
     {
@@ -289,6 +574,10 @@ public:
     }
     static Address addressFor(VirtualRegister virtualRegister)
     {
+        // NB. It's tempting on some architectures to sometimes use an offset from the stack
+        // register because for some offsets that will encode to a smaller instruction. But we
+        // cannot do this. We use this in places where the stack pointer has been moved to some
+        // unpredictable location.
         ASSERT(virtualRegister.isValid());
         return Address(GPRInfo::callFrameRegister, virtualRegister.offset() * sizeof(Register));
     }
@@ -317,26 +606,62 @@ public:
         return payloadFor(static_cast<VirtualRegister>(operand));
     }
 
-    Jump branchIfCellNotObject(GPRReg cellReg)
+    // Access to our fixed callee CallFrame.
+    static Address calleeFrameSlot(int slot)
+    {
+        ASSERT(slot >= JSStack::CallerFrameAndPCSize);
+        return Address(stackPointerRegister, sizeof(Register) * (slot - JSStack::CallerFrameAndPCSize));
+    }
+
+    // Access to our fixed callee CallFrame.
+    static Address calleeArgumentSlot(int argument)
+    {
+        return calleeFrameSlot(virtualRegisterForArgument(argument).offset());
+    }
+
+    static Address calleeFrameTagSlot(int slot)
+    {
+        return calleeFrameSlot(slot).withOffset(TagOffset);
+    }
+
+    static Address calleeFramePayloadSlot(int slot)
     {
-        return branch8(Below, Address(cellReg, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+        return calleeFrameSlot(slot).withOffset(PayloadOffset);
     }
 
-    static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
+    static Address calleeArgumentTagSlot(int argument)
     {
-        if (preserve1 != GPRInfo::regT0 && preserve2 != GPRInfo::regT0 && preserve3 != GPRInfo::regT0 && preserve4 != GPRInfo::regT0)
+        return calleeArgumentSlot(argument).withOffset(TagOffset);
+    }
+
+    static Address calleeArgumentPayloadSlot(int argument)
+    {
+        return calleeArgumentSlot(argument).withOffset(PayloadOffset);
+    }
+
+    static Address calleeFrameCallerFrame()
+    {
+        return calleeFrameSlot(0).withOffset(CallFrame::callerFrameOffset());
+    }
+
+    static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg, GPRReg preserve5 = InvalidGPRReg)
+    {
+        if (preserve1 != GPRInfo::regT0 && preserve2 != GPRInfo::regT0 && preserve3 != GPRInfo::regT0 && preserve4 != GPRInfo::regT0 && preserve5 != GPRInfo::regT0)
             return GPRInfo::regT0;
 
-        if (preserve1 != GPRInfo::regT1 && preserve2 != GPRInfo::regT1 && preserve3 != GPRInfo::regT1 && preserve4 != GPRInfo::regT1)
+        if (preserve1 != GPRInfo::regT1 && preserve2 != GPRInfo::regT1 && preserve3 != GPRInfo::regT1 && preserve4 != GPRInfo::regT1 && preserve5 != GPRInfo::regT1)
             return GPRInfo::regT1;
 
-        if (preserve1 != GPRInfo::regT2 && preserve2 != GPRInfo::regT2 && preserve3 != GPRInfo::regT2 && preserve4 != GPRInfo::regT2)
+        if (preserve1 != GPRInfo::regT2 && preserve2 != GPRInfo::regT2 && preserve3 != GPRInfo::regT2 && preserve4 != GPRInfo::regT2 && preserve5 != GPRInfo::regT2)
             return GPRInfo::regT2;
 
-        if (preserve1 != GPRInfo::regT3 && preserve2 != GPRInfo::regT3 && preserve3 != GPRInfo::regT3 && preserve4 != GPRInfo::regT3)
+        if (preserve1 != GPRInfo::regT3 && preserve2 != GPRInfo::regT3 && preserve3 != GPRInfo::regT3 && preserve4 != GPRInfo::regT3 && preserve5 != GPRInfo::regT3)
             return GPRInfo::regT3;
 
-        return GPRInfo::regT4;
+        if (preserve1 != GPRInfo::regT4 && preserve2 != GPRInfo::regT4 && preserve3 != GPRInfo::regT4 && preserve4 != GPRInfo::regT4 && preserve5 != GPRInfo::regT4)
+            return GPRInfo::regT4;
+
+        return GPRInfo::regT5;
     }
 
     // Add a debug call. This call has no effect on JIT code execution state.
@@ -429,13 +754,17 @@ public:
         jitAssertIsJSDouble(gpr);
         return gpr;
     }
-    FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
+    FPRReg unboxDoubleWithoutAssertions(GPRReg gpr, FPRReg fpr)
     {
-        jitAssertIsJSDouble(gpr);
         add64(GPRInfo::tagTypeNumberRegister, gpr);
         move64ToDouble(gpr, fpr);
         return fpr;
     }
+    FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
+    {
+        jitAssertIsJSDouble(gpr);
+        return unboxDoubleWithoutAssertions(gpr, fpr);
+    }
     
     void boxDouble(FPRReg fpr, JSValueRegs regs)
     {
@@ -481,10 +810,29 @@ public:
     }
 #endif
     
+    void boxBooleanPayload(GPRReg boolGPR, GPRReg payloadGPR)
+    {
+#if USE(JSVALUE64)
+        add32(TrustedImm32(ValueFalse), boolGPR, payloadGPR);
+#else
+        move(boolGPR, payloadGPR);
+#endif
+    }
+
+    void boxBoolean(GPRReg boolGPR, JSValueRegs boxedRegs)
+    {
+        boxBooleanPayload(boolGPR, boxedRegs.payloadGPR());
+#if USE(JSVALUE32_64)
+        move(TrustedImm32(JSValue::BooleanTag), boxedRegs.tagGPR());
+#endif
+    }
+    
     void callExceptionFuzz();
     
     enum ExceptionCheckKind { NormalExceptionCheck, InvertedExceptionCheck };
-    Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck);
+    enum ExceptionJumpWidth { NormalJumpWidth, FarJumpWidth };
+    Jump emitExceptionCheck(
+        ExceptionCheckKind = NormalExceptionCheck, ExceptionJumpWidth = NormalJumpWidth);
 
 #if ENABLE(SAMPLING_COUNTERS)
     static void emitCount(MacroAssembler& jit, AbstractSamplingCounter& counter, int32_t increment = 1)
@@ -538,48 +886,27 @@ public:
         return m_baselineCodeBlock;
     }
     
-    VirtualRegister baselineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return baselineCodeBlock()->argumentsRegister();
-        
-        return VirtualRegister(baselineCodeBlockForInlineCallFrame(
-            inlineCallFrame)->argumentsRegister().offset() + inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister baselineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return baselineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
     SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
     {
         return baselineCodeBlockFor(codeOrigin)->symbolTable();
     }
 
-    int offsetOfLocals(const CodeOrigin& codeOrigin)
-    {
-        if (!codeOrigin.inlineCallFrame)
-            return 0;
-        return codeOrigin.inlineCallFrame->stackOffset * sizeof(Register);
-    }
-
-    int offsetOfArgumentsIncludingThis(InlineCallFrame* inlineCallFrame)
+    static VirtualRegister argumentsStart(InlineCallFrame* inlineCallFrame)
     {
         if (!inlineCallFrame)
-            return CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register);
+            return VirtualRegister(CallFrame::argumentOffset(0));
         if (inlineCallFrame->arguments.size() <= 1)
-            return 0;
+            return virtualRegisterForLocal(0);
         ValueRecovery recovery = inlineCallFrame->arguments[1];
         RELEASE_ASSERT(recovery.technique() == DisplacedInJSStack);
-        return (recovery.virtualRegister().offset() - 1) * sizeof(Register);
+        return recovery.virtualRegister();
     }
     
-    int offsetOfArgumentsIncludingThis(const CodeOrigin& codeOrigin)
+    static VirtualRegister argumentsStart(const CodeOrigin& codeOrigin)
     {
-        return offsetOfArgumentsIncludingThis(codeOrigin.inlineCallFrame);
+        return argumentsStart(codeOrigin.inlineCallFrame);
     }
-
+    
     void emitLoadStructure(RegisterID source, RegisterID dest, RegisterID scratch)
     {
 #if USE(JSVALUE64)
@@ -626,16 +953,92 @@ public:
 
     static void emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, TrustedImmPtr structure, RegisterID dest);
 
-    Jump checkMarkByte(GPRReg cell)
+    Jump jumpIfIsRememberedOrInEden(GPRReg cell)
     {
         return branchTest8(MacroAssembler::NonZero, MacroAssembler::Address(cell, JSCell::gcDataOffset()));
     }
 
-    Jump checkMarkByte(JSCell* cell)
+    Jump jumpIfIsRememberedOrInEden(JSCell* cell)
     {
         uint8_t* address = reinterpret_cast<uint8_t*>(cell) + JSCell::gcDataOffset();
         return branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(address));
     }
+    
+    // Emits the branch structure for typeof. The code emitted by this doesn't fall through. The
+    // functor is called at those points where we have pinpointed a type. One way to use this is to
+    // have the functor emit the code to put the type string into an appropriate register and then
+    // jump out. A secondary functor is used for the call trap and masquerades-as-undefined slow
+    // case. It is passed the unlinked jump to the slow case.
+    template<typename Functor, typename SlowPathFunctor>
+    void emitTypeOf(
+        JSValueRegs regs, GPRReg tempGPR, const Functor& functor,
+        const SlowPathFunctor& slowPathFunctor)
+    {
+        // Implements the following branching structure:
+        //
+        // if (is cell) {
+        //     if (is object) {
+        //         if (is function) {
+        //             return function;
+        //         } else if (doesn't have call trap and doesn't masquerade as undefined) {
+        //             return object
+        //         } else {
+        //             return slowPath();
+        //         }
+        //     } else if (is string) {
+        //         return string
+        //     } else {
+        //         return symbol
+        //     }
+        // } else if (is number) {
+        //     return number
+        // } else if (is null) {
+        //     return object
+        // } else if (is boolean) {
+        //     return boolean
+        // } else {
+        //     return undefined
+        // }
+        
+        Jump notCell = branchIfNotCell(regs);
+        
+        GPRReg cellGPR = regs.payloadGPR();
+        Jump notObject = branchIfNotObject(cellGPR);
+        
+        Jump notFunction = branchIfNotFunction(cellGPR);
+        functor(TypeofType::Function, false);
+        
+        notFunction.link(this);
+        slowPathFunctor(
+            branchTest8(
+                NonZero,
+                Address(cellGPR, JSCell::typeInfoFlagsOffset()),
+                TrustedImm32(MasqueradesAsUndefined | TypeOfShouldCallGetCallData)));
+        functor(TypeofType::Object, false);
+        
+        notObject.link(this);
+        
+        Jump notString = branchIfNotString(cellGPR);
+        functor(TypeofType::String, false);
+        notString.link(this);
+        functor(TypeofType::Symbol, false);
+        
+        notCell.link(this);
+
+        Jump notNumber = branchIfNotNumber(regs, tempGPR);
+        functor(TypeofType::Number, false);
+        notNumber.link(this);
+        
+        JumpList notNull = branchIfNotEqual(regs, jsNull());
+        functor(TypeofType::Object, false);
+        notNull.link(this);
+        
+        Jump notBoolean = branchIfNotBoolean(regs, tempGPR);
+        functor(TypeofType::Boolean, false);
+        notBoolean.link(this);
+        
+        functor(TypeofType::Undefined, true);
+    }
 
     Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
     
diff --git a/jit/BinarySwitch.cpp b/jit/BinarySwitch.cpp
new file mode 100644 (file)
index 0000000..866b278
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "BinarySwitch.h"
+
+#if ENABLE(JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+static unsigned globalCounter; // We use a different seed every time we are invoked.
+
+BinarySwitch::BinarySwitch(GPRReg value, const Vector<int64_t>& cases, Type type)
+    : m_value(value)
+    , m_weakRandom(globalCounter++)
+    , m_index(0)
+    , m_caseIndex(UINT_MAX)
+    , m_type(type)
+{
+    if (cases.isEmpty())
+        return;
+    
+    for (unsigned i = 0; i < cases.size(); ++i)
+        m_cases.append(Case(cases[i], i));
+    
+    std::sort(m_cases.begin(), m_cases.end());
+    
+    for (unsigned i = 1; i < m_cases.size(); ++i)
+        RELEASE_ASSERT(m_cases[i - 1] < m_cases[i]);
+    
+    build(0, false, m_cases.size());
+}
+
+BinarySwitch::~BinarySwitch()
+{
+}
+
+bool BinarySwitch::advance(MacroAssembler& jit)
+{
+    if (m_cases.isEmpty()) {
+        m_fallThrough.append(jit.jump());
+        return false;
+    }
+    
+    if (m_index == m_branches.size()) {
+        RELEASE_ASSERT(m_jumpStack.isEmpty());
+        return false;
+    }
+    
+    for (;;) {
+        const BranchCode& code = m_branches[m_index++];
+        switch (code.kind) {
+        case NotEqualToFallThrough:
+            switch (m_type) {
+            case Int32:
+                m_fallThrough.append(jit.branch32(
+                    MacroAssembler::NotEqual, m_value,
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
+                break;
+            case IntPtr:
+                m_fallThrough.append(jit.branchPtr(
+                    MacroAssembler::NotEqual, m_value,
+                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
+                break;
+            }
+            break;
+        case NotEqualToPush:
+            switch (m_type) {
+            case Int32:
+                m_jumpStack.append(jit.branch32(
+                    MacroAssembler::NotEqual, m_value,
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
+                break;
+            case IntPtr:
+                m_jumpStack.append(jit.branchPtr(
+                    MacroAssembler::NotEqual, m_value,
+                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
+                break;
+            }
+            break;
+        case LessThanToPush:
+            switch (m_type) {
+            case Int32:
+                m_jumpStack.append(jit.branch32(
+                    MacroAssembler::LessThan, m_value,
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
+                break;
+            case IntPtr:
+                m_jumpStack.append(jit.branchPtr(
+                    MacroAssembler::LessThan, m_value,
+                    MacroAssembler::ImmPtr(bitwise_cast<const void*>(static_cast<intptr_t>(m_cases[code.index].value)))));
+                break;
+            }
+            break;
+        case Pop:
+            m_jumpStack.takeLast().link(&jit);
+            break;
+        case ExecuteCase:
+            m_caseIndex = code.index;
+            return true;
+        }
+    }
+}
+
+void BinarySwitch::build(unsigned start, bool hardStart, unsigned end)
+{
+    unsigned size = end - start;
+    
+    RELEASE_ASSERT(size);
+    
+    // This code uses some random numbers to keep things balanced. It's important to keep in mind
+    // that this does not improve average-case throughput under the assumption that all cases fire
+    // with equal probability. It just ensures that there will not be some switch structure that
+    // when combined with some input will always produce pathologically good or pathologically bad
+    // performance.
+    
+    const unsigned leafThreshold = 3;
+    
+    if (size <= leafThreshold) {
+        // It turns out that for exactly three cases or less, it's better to just compare each
+        // case individually. This saves 1/6 of a branch on average, and up to 1/3 of a branch in
+        // extreme cases where the divide-and-conquer bottoms out in a lot of 3-case subswitches.
+        //
+        // This assumes that we care about the cost of hitting some case more than we care about
+        // bottoming out in a default case. I believe that in most places where we use switch
+        // statements, we are more likely to hit one of the cases than we are to fall through to
+        // default. Intuitively, if we wanted to improve the performance of default, we would
+        // reduce the value of leafThreshold to 2 or even to 1. See below for a deeper discussion.
+        
+        bool allConsecutive = false;
+        
+        if ((hardStart || (start && m_cases[start - 1].value == m_cases[start].value - 1))
+            && start + size < m_cases.size()
+            && m_cases[start + size - 1].value == m_cases[start + size].value - 1) {
+            allConsecutive = true;
+            for (unsigned i = 0; i < size - 1; ++i) {
+                if (m_cases[i].value + 1 != m_cases[i + 1].value) {
+                    allConsecutive = false;
+                    break;
+                }
+            }
+        }
+        
+        Vector<unsigned, 3> localCaseIndices;
+        for (unsigned i = 0; i < size; ++i)
+            localCaseIndices.append(start + i);
+        
+        std::random_shuffle(
+            localCaseIndices.begin(), localCaseIndices.end(),
+            [this] (unsigned n) {
+                // We use modulo to get a random number in the range we want fully knowing that
+                // this introduces a tiny amount of bias, but we're fine with such tiny bias.
+                return m_weakRandom.getUint32() % n;
+            });
+        
+        for (unsigned i = 0; i < size - 1; ++i) {
+            m_branches.append(BranchCode(NotEqualToPush, localCaseIndices[i]));
+            m_branches.append(BranchCode(ExecuteCase, localCaseIndices[i]));
+            m_branches.append(BranchCode(Pop));
+        }
+        
+        if (!allConsecutive)
+            m_branches.append(BranchCode(NotEqualToFallThrough, localCaseIndices.last()));
+        
+        m_branches.append(BranchCode(ExecuteCase, localCaseIndices.last()));
+        return;
+    }
+        
+    // There are two different strategies we could consider here:
+    //
+    // Isolate median and split: pick a median and check if the comparison value is equal to it;
+    // if so, execute the median case. Otherwise check if the value is less than the median, and
+    // recurse left or right based on this. This has two subvariants: we could either first test
+    // equality for the median and then do the less-than, or we could first do the less-than and
+    // then check equality on the not-less-than path.
+    //
+    // Ignore median and split: do a less-than comparison on a value that splits the cases in two
+    // equal-sized halves. Recurse left or right based on the comparison. Do not test for equality
+    // against the median (or anything else); let the recursion handle those equality comparisons
+    // once we bottom out in a list that case 3 cases or less (see above).
+    //
+    // I'll refer to these strategies as Isolate and Ignore. I initially believed that Isolate
+    // would be faster since it leads to less branching for some lucky cases. It turns out that
+    // Isolate is almost a total fail in the average, assuming all cases are equally likely. How
+    // bad Isolate is depends on whether you believe that doing two consecutive branches based on
+    // the same comparison is cheaper than doing the compare/branches separately. This is
+    // difficult to evaluate. For small immediates that aren't blinded, we just care about
+    // avoiding a second compare instruction. For large immediates or when blinding is in play, we
+    // also care about the instructions used to materialize the immediate a second time. Isolate
+    // can help with both costs since it involves first doing a < compare+branch on some value,
+    // followed by a == compare+branch on the same exact value (or vice-versa). Ignore will do a <
+    // compare+branch on some value, and then the == compare+branch on that same value will happen
+    // much later.
+    //
+    // To evaluate these costs, I wrote the recurrence relation for Isolate and Ignore, assuming
+    // that ComparisonCost is the cost of a compare+branch and ChainedComparisonCost is the cost
+    // of a compare+branch on some value that you've just done another compare+branch for. These
+    // recurrence relations compute the total cost incurred if you executed the switch statement
+    // on each matching value. So the average cost of hitting some case can be computed as
+    // Isolate[n]/n or Ignore[n]/n, respectively for the two relations.
+    //
+    // Isolate[1] = ComparisonCost
+    // Isolate[2] = (2 + 1) * ComparisonCost
+    // Isolate[3] = (3 + 2 + 1) * ComparisonCost
+    // Isolate[n_] := With[
+    //     {medianIndex = Floor[n/2] + If[EvenQ[n], RandomInteger[], 1]},
+    //     ComparisonCost + ChainedComparisonCost +
+    //     (ComparisonCost * (medianIndex - 1) + Isolate[medianIndex - 1]) +
+    //     (2 * ComparisonCost * (n - medianIndex) + Isolate[n - medianIndex])]
+    //
+    // Ignore[1] = ComparisonCost
+    // Ignore[2] = (2 + 1) * ComparisonCost
+    // Ignore[3] = (3 + 2 + 1) * ComparisonCost
+    // Ignore[n_] := With[
+    //     {medianIndex = If[EvenQ[n], n/2, Floor[n/2] + RandomInteger[]]},
+    //     (medianIndex * ComparisonCost + Ignore[medianIndex]) +
+    //     ((n - medianIndex) * ComparisonCost + Ignore[n - medianIndex])]
+    //
+    // This does not account for the average cost of hitting the default case. See further below
+    // for a discussion of that.
+    //
+    // It turns out that for ComparisonCost = 1 and ChainedComparisonCost = 1, Ignore is always
+    // better than Isolate. If we assume that ChainedComparisonCost = 0, then Isolate wins for
+    // switch statements that have 20 cases or fewer, though the margin of victory is never large
+    // - it might sometimes save an average of 0.3 ComparisonCost. For larger switch statements,
+    // we see divergence between the two with Ignore winning. This is of course rather
+    // unrealistic since the chained comparison is never free. For ChainedComparisonCost = 0.5, we
+    // see Isolate winning for 10 cases or fewer, by maybe 0.2 ComparisonCost. Again we see
+    // divergence for large switches with Ignore winning, for example if a switch statement has
+    // 100 cases then Ignore saves one branch on average.
+    //
+    // Our current JIT backends don't provide for optimization for chained comparisons, except for
+    // reducing the code for materializing the immediate if the immediates are large or blinding
+    // comes into play. Probably our JIT backends live somewhere north of
+    // ChainedComparisonCost = 0.5.
+    //
+    // This implies that using the Ignore strategy is likely better. If we wanted to incorporate
+    // the Isolate strategy, we'd want to determine the switch size threshold at which the two
+    // cross over and then use Isolate for switches that are smaller than that size.
+    //
+    // The average cost of hitting the default case is similar, but involves a different cost for
+    // the base cases: you have to assume that you will always fail each branch. For the Ignore
+    // strategy we would get this recurrence relation; the same kind of thing happens to the
+    // Isolate strategy:
+    //
+    // Ignore[1] = ComparisonCost
+    // Ignore[2] = (2 + 2) * ComparisonCost
+    // Ignore[3] = (3 + 3 + 3) * ComparisonCost
+    // Ignore[n_] := With[
+    //     {medianIndex = If[EvenQ[n], n/2, Floor[n/2] + RandomInteger[]]},
+    //     (medianIndex * ComparisonCost + Ignore[medianIndex]) +
+    //     ((n - medianIndex) * ComparisonCost + Ignore[n - medianIndex])]
+    //
+    // This means that if we cared about the default case more, we would likely reduce
+    // leafThreshold. Reducing it to 2 would reduce the average cost of the default case by 1/3
+    // in the most extreme cases (num switch cases = 3, 6, 12, 24, ...). But it would also
+    // increase the average cost of taking one of the non-default cases by 1/3. Typically the
+    // difference is 1/6 in either direction. This makes it a very simple trade-off: if we believe
+    // that the default case is more important then we would want leafThreshold to be 2, and the
+    // default case would become 1/6 faster on average. But we believe that most switch statements
+    // are more likely to take one of the cases than the default, so we use leafThreshold = 3
+    // and get a 1/6 speed-up on average for taking an explicit case.
+        
+    unsigned medianIndex = (start + end) / 2;
+        
+    // We want medianIndex to point to the thing we will do a less-than compare against. We want
+    // this less-than compare to split the current sublist into equal-sized sublists, or
+    // nearly-equal-sized with some randomness if we're in the odd case. With the above
+    // calculation, in the odd case we will have medianIndex pointing at either the element we
+    // want or the element to the left of the one we want. Consider the case of five elements:
+    //
+    //     0 1 2 3 4
+    //
+    // start will be 0, end will be 5. The average is 2.5, which rounds down to 2. If we do
+    // value < 2, then we will split the list into 2 elements on the left and three on the right.
+    // That's pretty good, but in this odd case we'd like to at random choose 3 instead to ensure
+    // that we don't become unbalanced on the right. This does not improve throughput since one
+    // side will always get shafted, and that side might still be odd, in which case it will also
+    // have two sides and one of them will get shafted - and so on. We just want to avoid
+    // deterministic pathologies.
+    //
+    // In the even case, we will always end up pointing at the element we want:
+    //
+    //     0 1 2 3
+    //
+    // start will be 0, end will be 4. So, the average is 2, which is what we'd like.
+    if (size & 1) {
+        RELEASE_ASSERT(medianIndex - start + 1 == end - medianIndex);
+        medianIndex += m_weakRandom.getUint32() & 1;
+    } else
+        RELEASE_ASSERT(medianIndex - start == end - medianIndex);
+        
+    RELEASE_ASSERT(medianIndex > start);
+    RELEASE_ASSERT(medianIndex + 1 < end);
+        
+    m_branches.append(BranchCode(LessThanToPush, medianIndex));
+    build(medianIndex, true, end);
+    m_branches.append(BranchCode(Pop));
+    build(start, hardStart, medianIndex);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
diff --git a/jit/BinarySwitch.h b/jit/BinarySwitch.h
new file mode 100644 (file)
index 0000000..5692793
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef BinarySwitch_h
+#define BinarySwitch_h
+
+#if ENABLE(JIT)
+
+#include "GPRInfo.h"
+#include "MacroAssembler.h"
+#include "WeakRandom.h"
+
+namespace JSC {
+
+// The BinarySwitch class makes it easy to emit a switch statement over either
+// 32-bit integers or pointers, where the switch uses a tree of branches
+// rather than a jump table. This makes it particularly useful if the case
+// values are too far apart to make a jump table practical, or if there are
+// sufficiently few cases that the total cost of log(numCases) branches is
+// less than the cost of an indirected jump.
+//
+// In an effort to simplify the logic of emitting code for each case, this
+// uses an iterator style, rather than a functor callback style. This makes
+// sense because even the iterator implementation found herein is relatively
+// simple, whereas the code it's used from is usually quite complex - one
+// example being the trie-of-trees string switch implementation, where the
+// code emitted for each case involves recursing to emit code for a sub-trie.
+//
+// Use this like so:
+//
+// BinarySwitch switch(valueReg, casesVector, BinarySwitch::Int32);
+// while (switch.advance(jit)) {
+//     int value = switch.caseValue();
+//     unsigned index = switch.caseIndex(); // index into casesVector, above
+//     ... // generate code for this case
+//     ... = jit.jump(); // you have to jump out yourself; falling through causes undefined behavior
+// }
+// switch.fallThrough().link(&jit);
+
+class BinarySwitch {
+public:
+    enum Type {
+        Int32,
+        IntPtr
+    };
+    
+    BinarySwitch(GPRReg value, const Vector<int64_t>& cases, Type);
+    ~BinarySwitch();
+    
+    unsigned caseIndex() const { return m_cases[m_caseIndex].index; }
+    int64_t caseValue() const { return m_cases[m_caseIndex].value; }
+    
+    bool advance(MacroAssembler&);
+    
+    MacroAssembler::JumpList& fallThrough() { return m_fallThrough; }
+    
+private:
+    void build(unsigned start, bool hardStart, unsigned end);
+    
+    GPRReg m_value;
+    
+    struct Case {
+        Case() { }
+
+        Case(int64_t value, unsigned index)
+            : value(value)
+            , index(index)
+        {
+        }
+        
+        bool operator<(const Case& other) const
+        {
+            return value < other.value;
+        }
+        
+        int64_t value;
+        unsigned index;
+    };
+    
+    Vector<Case> m_cases;
+    
+    enum BranchKind {
+        NotEqualToFallThrough,
+        NotEqualToPush,
+        LessThanToPush,
+        Pop,
+        ExecuteCase
+    };
+        
+    struct BranchCode {
+        BranchCode() { }
+        
+        BranchCode(BranchKind kind, unsigned index = UINT_MAX)
+            : kind(kind)
+            , index(index)
+        {
+        }
+        
+        BranchKind kind;
+        unsigned index;
+    };
+    
+    WeakRandom m_weakRandom;
+    
+    Vector<BranchCode> m_branches;
+
+    unsigned m_index;
+    unsigned m_caseIndex;
+    Vector<MacroAssembler::Jump> m_jumpStack;
+    
+    MacroAssembler::JumpList m_fallThrough;
+    
+    Type m_type;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // BinarySwitch_h
+
index b02a3048a56c295e589a0cdd4658253e9286fb81..b69293bf697ec587ee9396a23ae94704e22cfeb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
+#define POKE_ARGUMENT_OFFSET 4
+#else
+#define POKE_ARGUMENT_OFFSET 0
+#endif
+
 class CCallHelpers : public AssemblyHelpers {
 public:
     CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
         : AssemblyHelpers(vm, codeBlock)
     {
     }
+    
+    // The most general helper for setting arguments that fit in a GPR, if you can compute each
+    // argument without using any argument registers. You usually want one of the setupArguments*()
+    // methods below instead of this. This thing is most useful if you have *a lot* of arguments.
+    template<typename Functor>
+    void setupArgument(unsigned argumentIndex, const Functor& functor)
+    {
+        unsigned numberOfRegs = GPRInfo::numberOfArgumentRegisters; // Disguise the constant from clang's tautological compare warning.
+        if (argumentIndex < numberOfRegs) {
+            functor(GPRInfo::toArgumentRegister(argumentIndex));
+            return;
+        }
+        
+        functor(GPRInfo::nonArgGPR0);
+        poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
+    }
 
     // These methods used to sort arguments into the correct registers.
     // On X86 we use cdecl calling conventions, which pass all arguments on the
@@ -280,6 +302,15 @@ public:
         addCallArgument(arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
     {
         resetCallArguments();
@@ -289,6 +320,47 @@ public:
         addCallArgument(arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImm32 arg3)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5, TrustedImm32 arg6)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+        addCallArgument(arg6);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3)
     {
         resetCallArguments();
@@ -395,6 +467,27 @@ public:
         addCallArgument(arg5);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
     {
         resetCallArguments();
@@ -415,6 +508,17 @@ public:
         addCallArgument(arg4);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
     {
         resetCallArguments();
@@ -474,6 +578,17 @@ public:
         addCallArgument(arg4);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
     {
         resetCallArguments();
@@ -619,6 +734,19 @@ public:
         addCallArgument(arg6);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, TrustedImmPtr arg7)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+        addCallArgument(arg6);
+        addCallArgument(arg7);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
     {
         resetCallArguments();
@@ -779,12 +907,6 @@ public:
         setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
     }
 
-#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
-#define POKE_ARGUMENT_OFFSET 4
-#else
-#define POKE_ARGUMENT_OFFSET 0
-#endif
-
 #if CPU(X86_64) || CPU(ARM64)
     ALWAYS_INLINE void setupArguments(FPRReg arg1)
     {
@@ -1247,6 +1369,14 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, GPRReg arg3)
+    {
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg2, GPRInfo::argumentGPR2);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
     {
         move(arg3, GPRInfo::argumentGPR3);
@@ -1255,6 +1385,14 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
+    {
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg2, GPRInfo::argumentGPR2);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3)
     {
         move(arg2, GPRInfo::argumentGPR2);
@@ -1334,6 +1472,20 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3,  GPRReg arg4)
     {
         poke(arg4, POKE_ARGUMENT_OFFSET);
@@ -1358,12 +1510,40 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
     {
         poke(arg4, POKE_ARGUMENT_OFFSET);
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
+    {
+        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1453,6 +1633,12 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1488,6 +1674,26 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1495,6 +1701,13 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1533,6 +1746,15 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, TrustedImmPtr arg7)
+    {
+        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
+        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, GPRReg arg4, GPRReg arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1580,6 +1802,22 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5, TrustedImm32 arg6)
+    {
+        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImmPtr arg6)
+    {
+        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, GPRReg arg7)
     {
         poke(arg7, POKE_ARGUMENT_OFFSET + 3);
@@ -1598,6 +1836,16 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, GPRReg arg7, TrustedImmPtr arg8)
+    {
+        poke(arg8, POKE_ARGUMENT_OFFSET + 4);
+        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
+        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5, GPRReg arg6, GPRReg arg7)
     {
         poke(arg7, POKE_ARGUMENT_OFFSET + 3);
@@ -1614,6 +1862,13 @@ public:
         move(arg3, GPRInfo::argumentGPR2);
         move(arg4, GPRInfo::argumentGPR3);
     }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
+    {
+        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
 #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
 
 #if NUMBER_OF_ARGUMENT_REGISTERS >= 5
@@ -1622,6 +1877,13 @@ public:
         setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3, GPRInfo::argumentGPR4>(arg1, arg3, arg4);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
+    {
+        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
     {
         setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4);
@@ -1645,6 +1907,43 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
     
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
+    {
+        move(arg2, GPRInfo::argumentGPR2); // In case arg2 is argumentGPR1.
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg2, GPRInfo::argumentGPR2);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(arg5, GPRInfo::argumentGPR5);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
+    {
+        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR4>(arg2, arg4);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg3, GPRInfo::argumentGPR3);
+        move(arg5, GPRInfo::argumentGPR5);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+    {
+        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
+        move(arg1, GPRInfo::argumentGPR1);
+        move(arg4, GPRInfo::argumentGPR4);
+        move(arg5, GPRInfo::argumentGPR5);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
     {
         setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
@@ -1652,6 +1951,13 @@ public:
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
+    {
+        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR4>(arg1, arg2, arg4);
+        move(arg3, GPRInfo::argumentGPR3);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
     {
         setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg3, arg4);
@@ -1666,6 +1972,15 @@ public:
         move(arg4, GPRInfo::argumentGPR3);
     }
 #endif
+    
+    void setupArguments(JSValueRegs arg1)
+    {
+#if USE(JSVALUE64)
+        setupArguments(arg1.gpr());
+#else
+        setupArguments(arg1.payloadGPR(), arg1.tagGPR());
+#endif
+    }
 
     void setupResults(GPRReg destA, GPRReg destB)
     {
@@ -1700,6 +2015,7 @@ public:
     void jumpToExceptionHandler()
     {
         // genericUnwind() leaves the handler CallFrame* in vm->callFrameForThrow,
+        // the topVMEntryFrame for the handler in vm->vmEntryFrameForThrow,
         // and the address of the handler in vm->targetMachinePCForThrow.
         loadPtr(&vm()->targetMachinePCForThrow, GPRInfo::regT1);
         jump(GPRInfo::regT1);
diff --git a/jit/ClosureCallStubRoutine.cpp b/jit/ClosureCallStubRoutine.cpp
deleted file mode 100644 (file)
index 3e9b268..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ClosureCallStubRoutine.h"
-
-#if ENABLE(JIT)
-
-#include "Executable.h"
-#include "Heap.h"
-#include "VM.h"
-#include "JSCInlines.h"
-#include "SlotVisitor.h"
-#include "Structure.h"
-
-namespace JSC {
-
-ClosureCallStubRoutine::ClosureCallStubRoutine(
-    const MacroAssemblerCodeRef& code, VM& vm, const JSCell* owner,
-    Structure* structure, ExecutableBase* executable, const CodeOrigin& codeOrigin)
-    : GCAwareJITStubRoutine(code, vm)
-    , m_structure(vm, owner, structure)
-    , m_executable(vm, owner, executable)
-    , m_codeOrigin(codeOrigin)
-{
-}
-
-ClosureCallStubRoutine::~ClosureCallStubRoutine()
-{
-}
-
-void ClosureCallStubRoutine::markRequiredObjectsInternal(SlotVisitor& visitor)
-{
-    visitor.append(&m_structure);
-    visitor.append(&m_executable);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
diff --git a/jit/ClosureCallStubRoutine.h b/jit/ClosureCallStubRoutine.h
deleted file mode 100644 (file)
index 1523301..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ClosureCallStubRoutine_h
-#define ClosureCallStubRoutine_h
-
-#if ENABLE(JIT)
-
-#include "CodeOrigin.h"
-#include "GCAwareJITStubRoutine.h"
-
-namespace JSC {
-
-class ClosureCallStubRoutine : public GCAwareJITStubRoutine {
-public:
-    ClosureCallStubRoutine(
-        const MacroAssemblerCodeRef&, VM&, const JSCell* owner,
-        Structure*, ExecutableBase*, const CodeOrigin&);
-    
-    virtual ~ClosureCallStubRoutine();
-    
-    Structure* structure() const { return m_structure.get(); }
-    ExecutableBase* executable() const { return m_executable.get(); }
-    const CodeOrigin& codeOrigin() const { return m_codeOrigin; }
-
-protected:
-    virtual void markRequiredObjectsInternal(SlotVisitor&) override;
-
-private:
-    WriteBarrier<Structure> m_structure;
-    WriteBarrier<ExecutableBase> m_executable;
-    // This allows us to figure out who a call is linked to by searching through
-    // stub routines.
-    CodeOrigin m_codeOrigin;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // ClosureCallStubRoutine_h
-
index 37cbb24fe2f2cbb348edc4701397fd891430f501..d5eaa4072ba2935e2f55660684aa27af8621c824 100644 (file)
@@ -32,8 +32,6 @@
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/FastMalloc.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -47,7 +45,7 @@ namespace JSC {
 // CompactJITCodeMap::Encoder encoder(map);
 // encoder.append(a, b);
 // encoder.append(c, d); // preconditions: c >= a, d >= b
-// OwnPtr<CompactJITCodeMap> map = encoder.finish();
+// auto map = encoder.finish();
 //
 // At some later time:
 //
@@ -80,6 +78,16 @@ struct BytecodeAndMachineOffset {
 class CompactJITCodeMap {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+    CompactJITCodeMap(uint8_t* buffer, unsigned size, unsigned numberOfEntries)
+        : m_buffer(buffer)
+#if !ASSERT_DISABLED
+        , m_size(size)
+#endif
+        , m_numberOfEntries(numberOfEntries)
+    {
+        UNUSED_PARAM(size);
+    }
+
     ~CompactJITCodeMap()
     {
         if (m_buffer)
@@ -94,16 +102,6 @@ public:
     void decode(Vector<BytecodeAndMachineOffset>& result) const;
     
 private:
-    CompactJITCodeMap(uint8_t* buffer, unsigned size, unsigned numberOfEntries)
-        : m_buffer(buffer)
-#if !ASSERT_DISABLED
-        , m_size(size)
-#endif
-        , m_numberOfEntries(numberOfEntries)
-    {
-        UNUSED_PARAM(size);
-    }
-    
     uint8_t at(unsigned index) const
     {
         ASSERT(index < m_size);
@@ -138,8 +136,8 @@ public:
         
         void ensureCapacityFor(unsigned numberOfEntriesToAdd);
         void append(unsigned bytecodeIndex, unsigned machineCodeOffset);
-        PassOwnPtr<CompactJITCodeMap> finish();
-        
+        std::unique_ptr<CompactJITCodeMap> finish();
+
     private:
         void appendByte(uint8_t value);
         void encodeNumber(uint32_t value);
@@ -212,18 +210,18 @@ inline void CompactJITCodeMap::Encoder::append(unsigned bytecodeIndex, unsigned
     m_numberOfEntries++;
 }
 
-inline PassOwnPtr<CompactJITCodeMap> CompactJITCodeMap::Encoder::finish()
+inline std::unique_ptr<CompactJITCodeMap> CompactJITCodeMap::Encoder::finish()
 {
     m_capacity = m_size;
     m_buffer = static_cast<uint8_t*>(fastRealloc(m_buffer, m_capacity));
-    OwnPtr<CompactJITCodeMap> result = adoptPtr(new CompactJITCodeMap(m_buffer, m_size, m_numberOfEntries));
+    auto result = std::make_unique<CompactJITCodeMap>(m_buffer, m_size, m_numberOfEntries);
     m_buffer = 0;
     m_size = 0;
     m_capacity = 0;
     m_numberOfEntries = 0;
     m_previousBytecodeIndex = 0;
     m_previousMachineCodeOffset = 0;
-    return result.release();
+    return result;
 }
         
 inline void CompactJITCodeMap::Encoder::appendByte(uint8_t value)
diff --git a/jit/ExecutableAllocationFuzz.cpp b/jit/ExecutableAllocationFuzz.cpp
new file mode 100644 (file)
index 0000000..9cee5d9
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ExecutableAllocationFuzz.h"
+
+#include "TestRunnerUtils.h"
+#include <wtf/Atomics.h>
+#include <wtf/DataLog.h>
+
+namespace JSC {
+
+static Atomic<unsigned> s_numberOfExecutableAllocationFuzzChecks;
+unsigned numberOfExecutableAllocationFuzzChecks()
+{
+    return s_numberOfExecutableAllocationFuzzChecks.load();
+}
+
+ExecutableAllocationFuzzResult doExecutableAllocationFuzzing()
+{
+    ASSERT(Options::enableExecutableAllocationFuzz());
+    
+    unsigned oldValue;
+    unsigned newValue;
+    do {
+        oldValue = s_numberOfExecutableAllocationFuzzChecks.load();
+        newValue = oldValue + 1;
+    } while (!s_numberOfExecutableAllocationFuzzChecks.compareExchangeWeak(oldValue, newValue));
+    
+    if (newValue == Options::fireExecutableAllocationFuzzAt()) {
+        if (Options::verboseExecutableAllocationFuzz()) {
+            dataLog("Will pretend to fail executable allocation.\n");
+            WTFReportBacktrace();
+        }
+        return PretendToFailExecutableAllocation;
+    }
+    
+    if (Options::fireExecutableAllocationFuzzAtOrAfter()
+        && newValue >= Options::fireExecutableAllocationFuzzAtOrAfter()) {
+        if (Options::verboseExecutableAllocationFuzz()) {
+            dataLog("Will pretend to fail executable allocation.\n");
+            WTFReportBacktrace();
+        }
+        return PretendToFailExecutableAllocation;
+    }
+    
+    return AllowNormalExecutableAllocation;
+}
+
+} // namespace JSC
+
diff --git a/jit/ExecutableAllocationFuzz.h b/jit/ExecutableAllocationFuzz.h
new file mode 100644 (file)
index 0000000..4997d21
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ExecutableAllocationFuzz_h
+#define ExecutableAllocationFuzz_h
+
+#include "Options.h"
+
+namespace JSC {
+
+enum ExecutableAllocationFuzzResult {
+    AllowNormalExecutableAllocation,
+    PretendToFailExecutableAllocation
+};
+
+ExecutableAllocationFuzzResult doExecutableAllocationFuzzing();
+
+inline ExecutableAllocationFuzzResult doExecutableAllocationFuzzingIfEnabled()
+{
+    if (LIKELY(!Options::enableExecutableAllocationFuzz()))
+        return AllowNormalExecutableAllocation;
+    
+    return doExecutableAllocationFuzzing();
+}
+
+} // namespace JSC
+
+#endif // ExecutableAllocationFuzz_h
+
index accf5fcf60aa7e045c15b5997c47a32b1016ac4b..bb49e736bcd554cbe678219dcae077859f660108 100644 (file)
@@ -34,9 +34,6 @@
 #include <wtf/MetaAllocator.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/PageReservation.h>
-#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
-#include <wtf/PassOwnPtr.h>
-#endif
 #include <wtf/ThreadingPrimitives.h>
 #include <wtf/VMTags.h>
 #endif
@@ -173,7 +170,7 @@ void ExecutableAllocator::initializeAllocator()
 
 ExecutableAllocator::ExecutableAllocator(VM&)
 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
-    : m_allocator(adoptPtr(new  DemandExecutableAllocator()))
+    : m_allocator(std::make_unique<DemandExecutableAllocator>())
 #endif
 {
     ASSERT(allocator());
@@ -216,11 +213,11 @@ double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
 
 }
 
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
+RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
 {
     RefPtr<ExecutableMemoryHandle> result = allocator()->allocate(sizeInBytes, ownerUID);
     RELEASE_ASSERT(result || effort != JITCompilationMustSucceed);
-    return result.release();
+    return result;
 }
 
 size_t ExecutableAllocator::committedByteCount()
index 55f9e77464a00913bf29270cfc1bb6e954740cc2..820ad4afcdb924dbec922a51373bf42fe7b05a90 100644 (file)
@@ -32,7 +32,6 @@
 #include <wtf/MetaAllocatorHandle.h>
 #include <wtf/MetaAllocator.h>
 #include <wtf/PageAllocation.h>
-#include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 #include <unistd.h>
 #endif
 
-#if OS(WINCE)
-// From pkfuncs.h (private header file from the Platform Builder)
-#define CACHE_SYNC_ALL 0x07F
-extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
-#endif
-
 #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (pageSize() * 4)
 
 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
@@ -87,13 +80,16 @@ class DemandExecutableAllocator;
 #endif
 
 #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
-#if CPU(ARM) || CPU(ARM64)
+#if CPU(ARM)
 static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
+#elif CPU(ARM64)
+static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
 #elif CPU(X86_64)
 static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
 #else
 static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
 #endif
+static const double executablePoolReservationFraction = 0.25;
 
 extern uintptr_t startOfFixedExecutableMemoryPool;
 #endif
@@ -119,7 +115,7 @@ public:
     static void dumpProfile() { }
 #endif
 
-    PassRefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
+    RefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
 
 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
     static void makeWritable(void* start, size_t size)
@@ -144,7 +140,7 @@ private:
     static void reprotectRegion(void*, size_t, ProtectionSetting);
 #if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
     // We create a MetaAllocator for each JS global object.
-    OwnPtr<DemandExecutableAllocator> m_allocator;
+    std::unique_ptr<DemandExecutableAllocator> m_allocator;
     DemandExecutableAllocator* allocator() { return m_allocator.get(); }
 #endif
 #endif
index 9afb055d47a0545d833bdadfcdb24acbae6bb1a7..7fe9c8ae8aee4159745b0d56e7f28ecf15b577de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 
 #include "CodeProfiling.h"
+#include "ExecutableAllocationFuzz.h"
 #include <errno.h>
+#if !PLATFORM(WIN)
 #include <unistd.h>
+#endif
 #include <wtf/MetaAllocator.h>
 #include <wtf/PageReservation.h>
 #include <wtf/VMTags.h>
 #include <stdio.h>
 #endif
 
-#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
-// MADV_FREE_REUSABLE does not work for JIT memory on older OSes so use MADV_FREE in that case.
-#define WTF_USE_MADV_FREE_FOR_JIT_MEMORY 1
-#endif
-
 using namespace WTF;
 
 namespace JSC {
@@ -62,9 +60,14 @@ public:
     FixedVMPoolExecutableAllocator()
         : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
     {
-        m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+        size_t reservationSize;
+        if (Options::jitMemoryReservationSize())
+            reservationSize = Options::jitMemoryReservationSize();
+        else
+            reservationSize = fixedExecutableMemoryPoolSize;
+        m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
         if (m_reservation) {
-            ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);
+            ASSERT(m_reservation.size() == reservationSize);
             addFreshFreeSpace(m_reservation.base(), m_reservation.size());
             
             startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(m_reservation.base());
@@ -150,28 +153,49 @@ double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
     MetaAllocator::Statistics statistics = allocator->currentStatistics();
     ASSERT(statistics.bytesAllocated <= statistics.bytesReserved);
     size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage;
-    if (bytesAllocated >= statistics.bytesReserved)
-        bytesAllocated = statistics.bytesReserved;
+    size_t bytesAvailable = static_cast<size_t>(
+        statistics.bytesReserved * (1 - executablePoolReservationFraction));
+    if (bytesAllocated >= bytesAvailable)
+        bytesAllocated = bytesAvailable;
     double result = 1.0;
-    size_t divisor = statistics.bytesReserved - bytesAllocated;
+    size_t divisor = bytesAvailable - bytesAllocated;
     if (divisor)
-        result = static_cast<double>(statistics.bytesReserved) / divisor;
+        result = static_cast<double>(bytesAvailable) / divisor;
     if (result < 1.0)
         result = 1.0;
     return result;
 }
 
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM& vm, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
+RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
 {
+    if (effort != JITCompilationCanFail && Options::reportMustSucceedExecutableAllocations()) {
+        dataLog("Allocating ", sizeInBytes, " bytes of executable memory with JITCompilationMustSucceed.\n");
+        WTFReportBacktrace();
+    }
+    
+    if (effort == JITCompilationCanFail
+        && doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation)
+        return nullptr;
+    
+    if (effort == JITCompilationCanFail) {
+        // Don't allow allocations if we are down to reserve.
+        MetaAllocator::Statistics statistics = allocator->currentStatistics();
+        size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes;
+        size_t bytesAvailable = static_cast<size_t>(
+            statistics.bytesReserved * (1 - executablePoolReservationFraction));
+        if (bytesAllocated > bytesAvailable)
+            return nullptr;
+    }
+    
     RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
     if (!result) {
-        if (effort == JITCompilationCanFail)
-            return result;
-        releaseExecutableMemory(vm);
-        result = allocator->allocate(sizeInBytes, ownerUID);
-        RELEASE_ASSERT(result);
+        if (effort != JITCompilationCanFail) {
+            dataLog("Ran out of executable memory while allocating ", sizeInBytes, " bytes.\n");
+            CRASH();
+        }
+        return nullptr;
     }
-    return result.release();
+    return result;
 }
 
 size_t ExecutableAllocator::committedByteCount()
index b3711cde4b9b26ed5737085f79a16ff16240ef91..a5e301bd4810be3aeeedd209e56cda8186f31e28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,12 +54,19 @@ public:
         return JSValueRegs(gpr);
     }
     
+    static JSValueRegs withTwoAvailableRegs(GPRReg gpr, GPRReg)
+    {
+        return JSValueRegs(gpr);
+    }
+    
     bool operator!() const { return m_gpr == InvalidGPRReg; }
     
     GPRReg gpr() const { return m_gpr; }
     GPRReg tagGPR() const { return InvalidGPRReg; }
     GPRReg payloadGPR() const { return m_gpr; }
     
+    bool uses(GPRReg gpr) const { return m_gpr == gpr; }
+    
 private:
     GPRReg m_gpr;
 };
@@ -144,6 +151,11 @@ public:
     {
     }
     
+    static JSValueRegs withTwoAvailableRegs(GPRReg gpr1, GPRReg gpr2)
+    {
+        return JSValueRegs(gpr1, gpr2);
+    }
+    
     static JSValueRegs payloadOnly(GPRReg gpr)
     {
         return JSValueRegs(InvalidGPRReg, gpr);
@@ -169,6 +181,8 @@ public:
         return tagGPR();
     }
 
+    bool uses(GPRReg gpr) const { return m_tagGPR == gpr || m_payloadGPR == gpr; }
+    
 private:
     int8_t m_tagGPR;
     int8_t m_payloadGPR;
@@ -321,6 +335,12 @@ public:
         return registerForIndex[index];
     }
 
+    static GPRReg toArgumentRegister(unsigned)
+    {
+        UNREACHABLE_FOR_PLATFORM();
+        return InvalidGPRReg;
+    }
+
     static unsigned toIndex(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
@@ -398,6 +418,7 @@ public:
     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
     static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
+    static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10;
     static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
 
     static GPRReg toRegister(unsigned index)
@@ -492,6 +513,13 @@ public:
         return registerForIndex[index];
     }
 
+    static GPRReg toArgumentRegister(unsigned index)
+    {
+        ASSERT(index < numberOfArgumentRegisters);
+        static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3 };
+        return registerForIndex[index];
+    }
+
     static unsigned toIndex(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
@@ -573,6 +601,7 @@ public:
     static const GPRReg returnValueGPR = ARM64Registers::x0; // regT0
     static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1
     static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
+    static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
     static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
 
     // GPRReg mapping is direct, the machine regsiter numbers can
@@ -612,7 +641,7 @@ public:
 
     static const char* debugName(GPRReg reg)
     {
-        ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg);
+        ASSERT(reg != InvalidGPRReg);
         ASSERT(static_cast<unsigned>(reg) < 32);
         static const char* nameForRegister[32] = {
             "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
index 4e43a48bf5f172c4c7fcabd2bff6d6a799227aa6..23d31da56360889fb87635a5b93950b0232d27b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "JIT.h"
 
-// This probably does not belong here; adding here for now as a quick Windows build fix.
-#if ENABLE(ASSEMBLER) && CPU(X86) && !OS(MAC_OS_X)
-#include "MacroAssembler.h"
-JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2;
-#endif
-
 #include "ArityCheckFailReturnThunks.h"
 #include "CodeBlock.h"
+#include "CodeBlockWithJITType.h"
 #include "DFGCapabilities.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
@@ -52,6 +47,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse
 #include "SamplingTool.h"
 #include "SlowPathCall.h"
 #include "StackAlignment.h"
+#include "TypeProfilerLog.h"
 #include <wtf/CryptographicallyRandomNumber.h>
 
 using namespace std;
@@ -80,7 +76,7 @@ JIT::JIT(VM* vm, CodeBlock* codeBlock)
     : JSInterfaceJIT(vm, codeBlock)
     , m_interpreter(vm->interpreter)
     , m_labels(codeBlock ? codeBlock->numberOfInstructions() : 0)
-    , m_bytecodeOffset((unsigned)-1)
+    , m_bytecodeOffset(std::numeric_limits<unsigned>::max())
     , m_getByIdIndex(UINT_MAX)
     , m_putByIdIndex(UINT_MAX)
     , m_byValInstructionIndex(UINT_MAX)
@@ -109,6 +105,25 @@ void JIT::emitEnterOptimizationCheck()
 }
 #endif
 
+void JIT::emitNotifyWrite(WatchpointSet* set)
+{
+    if (!set || set->state() == IsInvalidated)
+        return;
+    
+    addSlowCase(branch8(NotEqual, AbsoluteAddress(set->addressOfState()), TrustedImm32(IsInvalidated)));
+}
+
+void JIT::assertStackPointerOffset()
+{
+    if (ASSERT_DISABLED)
+        return;
+    
+    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, regT0);
+    Jump ok = branchPtr(Equal, regT0, stackPointerRegister);
+    breakpoint();
+    ok.link(this);
+}
+
 #define NEXT_OPCODE(name) \
     m_bytecodeOffset += OPCODE_LENGTH(name); \
     break;
@@ -179,10 +194,9 @@ void JIT::privateCompileMainPass()
         DEFINE_SLOW_OP(greater)
         DEFINE_SLOW_OP(greatereq)
         DEFINE_SLOW_OP(is_function)
-        DEFINE_SLOW_OP(is_object)
+        DEFINE_SLOW_OP(is_object_or_null)
         DEFINE_SLOW_OP(typeof)
 
-        DEFINE_OP(op_touch_entry)
         DEFINE_OP(op_add)
         DEFINE_OP(op_bitand)
         DEFINE_OP(op_bitor)
@@ -193,33 +207,32 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_construct_varargs)
         DEFINE_OP(op_catch)
         DEFINE_OP(op_construct)
-        DEFINE_OP(op_get_callee)
         DEFINE_OP(op_create_this)
         DEFINE_OP(op_to_this)
-        DEFINE_OP(op_init_lazy_reg)
-        DEFINE_OP(op_create_arguments)
+        DEFINE_OP(op_create_direct_arguments)
+        DEFINE_OP(op_create_scoped_arguments)
+        DEFINE_OP(op_create_out_of_band_arguments)
+        DEFINE_OP(op_check_tdz)
         DEFINE_OP(op_debug)
         DEFINE_OP(op_del_by_id)
         DEFINE_OP(op_div)
         DEFINE_OP(op_end)
         DEFINE_OP(op_enter)
-        DEFINE_OP(op_create_activation)
+        DEFINE_OP(op_create_lexical_environment)
+        DEFINE_OP(op_get_scope)
         DEFINE_OP(op_eq)
         DEFINE_OP(op_eq_null)
         case op_get_by_id_out_of_line:
         case op_get_array_length:
         DEFINE_OP(op_get_by_id)
-        DEFINE_OP(op_get_arguments_length)
         DEFINE_OP(op_get_by_val)
-        DEFINE_OP(op_get_argument_by_val)
-        DEFINE_OP(op_get_by_pname)
-        DEFINE_OP(op_get_pnames)
         DEFINE_OP(op_check_has_instance)
         DEFINE_OP(op_instanceof)
         DEFINE_OP(op_is_undefined)
         DEFINE_OP(op_is_boolean)
         DEFINE_OP(op_is_number)
         DEFINE_OP(op_is_string)
+        DEFINE_OP(op_is_object)
         DEFINE_OP(op_jeq_null)
         DEFINE_OP(op_jfalse)
         DEFINE_OP(op_jmp)
@@ -237,7 +250,6 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_loop_hint)
         DEFINE_OP(op_lshift)
         DEFINE_OP(op_mod)
-        DEFINE_OP(op_captured_mov)
         DEFINE_OP(op_mov)
         DEFINE_OP(op_mul)
         DEFINE_OP(op_negate)
@@ -247,11 +259,9 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_new_array_with_size)
         DEFINE_OP(op_new_array_buffer)
         DEFINE_OP(op_new_func)
-        DEFINE_OP(op_new_captured_func)
         DEFINE_OP(op_new_func_exp)
         DEFINE_OP(op_new_object)
         DEFINE_OP(op_new_regexp)
-        DEFINE_OP(op_next_pname)
         DEFINE_OP(op_not)
         DEFINE_OP(op_nstricteq)
         DEFINE_OP(op_pop_scope)
@@ -259,6 +269,8 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_inc)
         DEFINE_OP(op_profile_did_call)
         DEFINE_OP(op_profile_will_call)
+        DEFINE_OP(op_profile_type)
+        DEFINE_OP(op_profile_control_flow)
         DEFINE_OP(op_push_name_scope)
         DEFINE_OP(op_push_with_scope)
         case op_put_by_id_out_of_line:
@@ -270,13 +282,14 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_put_by_index)
         case op_put_by_val_direct:
         DEFINE_OP(op_put_by_val)
+        DEFINE_OP(op_put_getter_by_id)
+        DEFINE_OP(op_put_setter_by_id)
         DEFINE_OP(op_put_getter_setter)
         case op_init_global_const_nop:
             NEXT_OPCODE(op_init_global_const_nop);
         DEFINE_OP(op_init_global_const)
 
         DEFINE_OP(op_ret)
-        DEFINE_OP(op_ret_object_or_this)
         DEFINE_OP(op_rshift)
         DEFINE_OP(op_unsigned)
         DEFINE_OP(op_urshift)
@@ -286,16 +299,27 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_switch_char)
         DEFINE_OP(op_switch_imm)
         DEFINE_OP(op_switch_string)
-        DEFINE_OP(op_tear_off_activation)
-        DEFINE_OP(op_tear_off_arguments)
         DEFINE_OP(op_throw)
         DEFINE_OP(op_throw_static_error)
         DEFINE_OP(op_to_number)
+        DEFINE_OP(op_to_string)
         DEFINE_OP(op_to_primitive)
 
         DEFINE_OP(op_resolve_scope)
         DEFINE_OP(op_get_from_scope)
         DEFINE_OP(op_put_to_scope)
+        DEFINE_OP(op_get_from_arguments)
+        DEFINE_OP(op_put_to_arguments)
+
+        DEFINE_OP(op_get_enumerable_length)
+        DEFINE_OP(op_has_generic_property)
+        DEFINE_OP(op_has_structure_property)
+        DEFINE_OP(op_has_indexed_property)
+        DEFINE_OP(op_get_direct_pname)
+        DEFINE_OP(op_get_property_enumerator)
+        DEFINE_OP(op_enumerator_structure_pname)
+        DEFINE_OP(op_enumerator_generic_pname)
+        DEFINE_OP(op_to_index_string)
         default:
             RELEASE_ASSERT_NOT_REACHED();
         }
@@ -305,7 +329,7 @@ void JIT::privateCompileMainPass()
 
 #ifndef NDEBUG
     // Reset this, in order to guard its use with ASSERTs.
-    m_bytecodeOffset = (unsigned)-1;
+    m_bytecodeOffset = std::numeric_limits<unsigned>::max();
 #endif
 }
 
@@ -363,18 +387,14 @@ void JIT::privateCompileSlowCases()
         DEFINE_SLOWCASE_OP(op_construct_varargs)
         DEFINE_SLOWCASE_OP(op_construct)
         DEFINE_SLOWCASE_OP(op_to_this)
+        DEFINE_SLOWCASE_OP(op_check_tdz)
         DEFINE_SLOWCASE_OP(op_create_this)
-        DEFINE_SLOWCASE_OP(op_captured_mov)
         DEFINE_SLOWCASE_OP(op_div)
         DEFINE_SLOWCASE_OP(op_eq)
-        DEFINE_SLOWCASE_OP(op_get_callee)
         case op_get_by_id_out_of_line:
         case op_get_array_length:
         DEFINE_SLOWCASE_OP(op_get_by_id)
-        DEFINE_SLOWCASE_OP(op_get_arguments_length)
         DEFINE_SLOWCASE_OP(op_get_by_val)
-        DEFINE_SLOWCASE_OP(op_get_argument_by_val)
-        DEFINE_SLOWCASE_OP(op_get_by_pname)
         DEFINE_SLOWCASE_OP(op_check_has_instance)
         DEFINE_SLOWCASE_OP(op_instanceof)
         DEFINE_SLOWCASE_OP(op_jfalse)
@@ -412,7 +432,11 @@ void JIT::privateCompileSlowCases()
         DEFINE_SLOWCASE_OP(op_stricteq)
         DEFINE_SLOWCASE_OP(op_sub)
         DEFINE_SLOWCASE_OP(op_to_number)
+        DEFINE_SLOWCASE_OP(op_to_string)
         DEFINE_SLOWCASE_OP(op_to_primitive)
+        DEFINE_SLOWCASE_OP(op_has_indexed_property)
+        DEFINE_SLOWCASE_OP(op_has_structure_property)
+        DEFINE_SLOWCASE_OP(op_get_direct_pname)
 
         DEFINE_SLOWCASE_OP(op_resolve_scope)
         DEFINE_SLOWCASE_OP(op_get_from_scope)
@@ -438,7 +462,7 @@ void JIT::privateCompileSlowCases()
 
 #ifndef NDEBUG
     // Reset this, in order to guard its use with ASSERTs.
-    m_bytecodeOffset = (unsigned)-1;
+    m_bytecodeOffset = std::numeric_limits<unsigned>::max();
 #endif
 }
 
@@ -451,11 +475,6 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
         m_canBeOptimizedOrInlined = false;
         m_shouldEmitProfiling = false;
         break;
-    case DFG::CanInline:
-        m_canBeOptimized = false;
-        m_canBeOptimizedOrInlined = true;
-        m_shouldEmitProfiling = true;
-        break;
     case DFG::CanCompile:
     case DFG::CanCompileAndInline:
         m_canBeOptimized = true;
@@ -478,9 +497,13 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
         m_codeBlock->m_shouldAlwaysBeInlined &= canInline(level) && DFG::mightInlineFunction(m_codeBlock);
         break;
     }
+
+    // This ensures that we have the most up to date type information when performing typecheck optimizations for op_profile_type.
+    if (m_vm->typeProfiler())
+        m_vm->typeProfilerLog()->processLogEntries(ASCIILiteral("Preparing for JIT compilation."));
     
     if (Options::showDisassembly() || m_vm->m_perBytecodeProfiler)
-        m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
+        m_disassembler = std::make_unique<JITDisassembler>(m_codeBlock);
     if (m_vm->m_perBytecodeProfiler) {
         m_compilation = adoptRef(
             new Profiler::Compilation(
@@ -506,9 +529,8 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
     sampleInstruction(m_codeBlock->instructions().begin());
 #endif
 
-    Jump stackOverflow;
     if (m_codeBlock->codeType() == FunctionCode) {
-        ASSERT(m_bytecodeOffset == (unsigned)-1);
+        ASSERT(m_bytecodeOffset == std::numeric_limits<unsigned>::max());
         if (shouldEmitProfiling()) {
             for (int argument = 0; argument < m_codeBlock->numParameters(); ++argument) {
                 // If this is a constructor, then we want to put in a dummy profiling site (to
@@ -525,12 +547,12 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
                 emitValueProfilingSite(m_codeBlock->valueProfileForArgument(argument));
             }
         }
-
-        addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, regT1);
-        stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1);
     }
 
-    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
+    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, regT1);
+    Jump stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1);
+
+    move(regT1, stackPointerRegister);
     checkStackPointerAlignment();
 
     privateCompileMainPass();
@@ -540,14 +562,14 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
     if (m_disassembler)
         m_disassembler->setEndOfSlowPath(label());
 
+    stackOverflow.link(this);
+    m_bytecodeOffset = 0;
+    if (maxFrameExtentForSlowPathCall)
+        addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
+    callOperationWithCallFrameRollbackOnException(operationThrowStackOverflowError, m_codeBlock);
+
     Label arityCheck;
     if (m_codeBlock->codeType() == FunctionCode) {
-        stackOverflow.link(this);
-        m_bytecodeOffset = 0;
-        if (maxFrameExtentForSlowPathCall)
-            addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
-        callOperationWithCallFrameRollbackOnException(operationThrowStackOverflowError, m_codeBlock);
-
         arityCheck = label();
         store8(TrustedImm32(0), &m_codeBlock->m_shouldAlwaysBeInlined);
         emitFunctionPrologue();
@@ -572,12 +594,14 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
 #else
         thunkReg = GPRInfo::regT5;
 #endif
-        move(TrustedImmPtr(m_vm->arityCheckFailReturnThunks->returnPCsFor(*m_vm, m_codeBlock->numParameters())), thunkReg);
+        CodeLocationLabel* failThunkLabels =
+            m_vm->arityCheckFailReturnThunks->returnPCsFor(*m_vm, m_codeBlock->numParameters());
+        move(TrustedImmPtr(failThunkLabels), thunkReg);
         loadPtr(BaseIndex(thunkReg, regT0, timesPtr()), thunkReg);
-        emitNakedCall(m_vm->getCTIStub(arityFixup).code());
+        emitNakedCall(m_vm->getCTIStub(arityFixupGenerator).code());
 
 #if !ASSERT_DISABLED
-        m_bytecodeOffset = (unsigned)-1; // Reset this, in order to guard its use with ASSERTs.
+        m_bytecodeOffset = std::numeric_limits<unsigned>::max(); // Reset this, in order to guard its use with ASSERTs.
 #endif
 
         jump(beginLabel);
@@ -654,9 +678,9 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
     for (unsigned i = 0; i < m_callCompilationInfo.size(); ++i) {
         CallCompilationInfo& compilationInfo = m_callCompilationInfo[i];
         CallLinkInfo& info = *compilationInfo.callLinkInfo;
-        info.callReturnLocation = patchBuffer.locationOfNearCall(compilationInfo.callReturnLocation);
-        info.hotPathBegin = patchBuffer.locationOf(compilationInfo.hotPathBegin);
-        info.hotPathOther = patchBuffer.locationOfNearCall(compilationInfo.hotPathOther);
+        info.setCallLocations(patchBuffer.locationOfNearCall(compilationInfo.callReturnLocation),
+            patchBuffer.locationOf(compilationInfo.hotPathBegin),
+            patchBuffer.locationOfNearCall(compilationInfo.hotPathOther));
     }
 
     CompactJITCodeMap::Encoder jitCodeMapEncoder;
@@ -670,14 +694,18 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
     if (m_codeBlock->codeType() == FunctionCode)
         withArityCheck = patchBuffer.locationOf(arityCheck);
 
-    if (Options::showDisassembly())
+    if (Options::showDisassembly()) {
         m_disassembler->dump(patchBuffer);
+        patchBuffer.didAlreadyDisassemble();
+    }
     if (m_compilation) {
         m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer);
         m_vm->m_perBytecodeProfiler->addCompilation(m_compilation);
     }
     
-    CodeRef result = patchBuffer.finalizeCodeWithoutDisassembly();
+    CodeRef result = FINALIZE_CODE(
+        patchBuffer,
+        ("Baseline JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT)).data()));
     
     m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
         static_cast<double>(result.size()) /
@@ -696,35 +724,38 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort)
 
 void JIT::privateCompileExceptionHandlers()
 {
-    if (m_exceptionChecks.empty() && m_exceptionChecksWithCallFrameRollback.empty())
-        return;
-
-    Jump doLookup;
-
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
-        emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        doLookup = jump();
+
+        // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
+
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+
+#if CPU(X86)
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
+#endif
+        m_calls.append(CallRecord(call(), std::numeric_limits<unsigned>::max(), FunctionPtr(lookupExceptionHandlerFromCallerFrame).value()));
+        jumpToExceptionHandler();
     }
 
-    if (!m_exceptionChecks.empty())
+    if (!m_exceptionChecks.empty()) {
         m_exceptionChecks.link(this);
-    
-    // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
-    move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
 
-    if (doLookup.isSet())
-        doLookup.link(this);
-
-    move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
 
 #if CPU(X86)
-    // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
-    poke(GPRInfo::argumentGPR0);
-    poke(GPRInfo::argumentGPR1, 1);
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
 #endif
-    m_calls.append(CallRecord(call(), (unsigned)-1, FunctionPtr(lookupExceptionHandler).value()));
-    jumpToExceptionHandler();
+        m_calls.append(CallRecord(call(), std::numeric_limits<unsigned>::max(), FunctionPtr(lookupExceptionHandler).value()));
+        jumpToExceptionHandler();
+    }
 }
 
 unsigned JIT::frameRegisterCountFor(CodeBlock* codeBlock)
index 223450730ab96360a0ba02d779154ff30428b1dd..202c99c63559c33d3d093f66f3308ffa8bbe7e2a 100644 (file)
--- a/jit/JIT.h
+++ b/jit/JIT.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,7 +44,6 @@
 #include "JITDisassembler.h"
 #include "JITInlineCacheGenerator.h"
 #include "JSInterfaceJIT.h"
-#include "LegacyProfiler.h"
 #include "Opcode.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
 namespace JSC {
 
     class ArrayAllocationProfile;
+    class CallLinkInfo;
     class CodeBlock;
     class FunctionExecutable;
     class JIT;
-    class JSPropertyNameIterator;
     class Identifier;
     class Interpreter;
     class JSScope;
@@ -65,7 +64,6 @@ namespace JSC {
     class Register;
     class StructureChain;
 
-    struct CallLinkInfo;
     struct Instruction;
     struct OperandTypes;
     struct PolymorphicAccessStructureList;
@@ -199,13 +197,6 @@ namespace JSC {
             return JIT(vm, codeBlock).privateCompile(effort);
         }
         
-        static void compileClosureCall(VM* vm, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
-        {
-            JIT jit(vm, callerCodeBlock);
-            jit.m_bytecodeOffset = callLinkInfo->codeOrigin.bytecodeIndex;
-            jit.privateCompileClosureCall(callLinkInfo, calleeCodeBlock, expectedStructure, expectedExecutable, codePtr);
-        }
-
         static void compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
         {
             JIT jit(vm, codeBlock);
@@ -227,6 +218,13 @@ namespace JSC {
             jit.privateCompilePutByVal(byValInfo, returnAddress, arrayMode);
         }
 
+        static void compileHasIndexedProperty(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
+        {
+            JIT jit(vm, codeBlock);
+            jit.m_bytecodeOffset = byValInfo->bytecodeIndex;
+            jit.privateCompileHasIndexedProperty(byValInfo, returnAddress, arrayMode);
+        }
+
         static CodeRef compileCTINativeCall(VM* vm, NativeFunction func)
         {
             if (!vm->canUseJIT()) {
@@ -247,11 +245,11 @@ namespace JSC {
         void privateCompileSlowCases();
         CompilationResult privateCompile(JITCompilationEffort);
         
-        void privateCompileClosureCall(CallLinkInfo*, CodeBlock* calleeCodeBlock, Structure*, ExecutableBase*, MacroAssemblerCodePtr);
-        
         void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
         void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
 
+        void privateCompileHasIndexedProperty(ByValInfo*, ReturnAddressPtr, JITArrayMode);
+
         Label privateCompileCTINativeCall(VM*, bool isConstruct = false);
         CodeRef privateCompileCTINativeCall(VM*, NativeFunction);
         void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
@@ -298,7 +296,7 @@ namespace JSC {
 
         void compileOpCall(OpcodeID, Instruction*, unsigned callLinkInfoIndex);
         void compileOpCallSlowCase(OpcodeID, Instruction*, Vector<SlowCaseEntry>::iterator&, unsigned callLinkInfoIndex);
-        void compileLoadVarargs(Instruction*);
+        void compileSetupVarargsFrame(Instruction*, CallLinkInfo*);
         void compileCallEval(Instruction*);
         void compileCallEvalSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitPutCallResult(Instruction*);
@@ -309,6 +307,7 @@ namespace JSC {
         
         void emitLoadDouble(int index, FPRegisterID value);
         void emitLoadInt32ToDouble(int index, FPRegisterID value);
+        Jump emitJumpIfCellObject(RegisterID cellReg);
         Jump emitJumpIfCellNotObject(RegisterID cellReg);
 
         enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterBase, ShouldFilterValue, ShouldFilterBaseAndValue };
@@ -337,10 +336,18 @@ namespace JSC {
         // Property is int-checked and zero extended. Base is cell checked.
         // Structure is already profiled. Returns the slow cases. Fall-through
         // case contains result in regT0, and it is not yet profiled.
+        JumpList emitInt32Load(Instruction* instruction, PatchableJump& badType) { return emitContiguousLoad(instruction, badType, Int32Shape); }
+        JumpList emitDoubleLoad(Instruction*, PatchableJump& badType);
+        JumpList emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape);
+        JumpList emitArrayStorageLoad(Instruction*, PatchableJump& badType);
+        JumpList emitLoadForArrayMode(Instruction*, JITArrayMode, PatchableJump& badType);
+
         JumpList emitInt32GetByVal(Instruction* instruction, PatchableJump& badType) { return emitContiguousGetByVal(instruction, badType, Int32Shape); }
         JumpList emitDoubleGetByVal(Instruction*, PatchableJump& badType);
         JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape);
         JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType);
+        JumpList emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType);
+        JumpList emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType);
         JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
         JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
         
@@ -447,8 +454,9 @@ namespace JSC {
 
         void emit_compareAndJump(OpcodeID, int op1, int op2, unsigned target, RelationalCondition);
         void emit_compareAndJumpSlow(int op1, int op2, unsigned target, DoubleCondition, size_t (JIT_OPERATION *operation)(ExecState*, EncodedJSValue, EncodedJSValue), bool invert, Vector<SlowCaseEntry>::iterator&);
+        
+        void assertStackPointerOffset();
 
-        void emit_op_touch_entry(Instruction*);
         void emit_op_add(Instruction*);
         void emit_op_bitand(Instruction*);
         void emit_op_bitor(Instruction*);
@@ -457,26 +465,27 @@ namespace JSC {
         void emit_op_call_eval(Instruction*);
         void emit_op_call_varargs(Instruction*);
         void emit_op_construct_varargs(Instruction*);
-        void emit_op_captured_mov(Instruction*);
         void emit_op_catch(Instruction*);
         void emit_op_construct(Instruction*);
-        void emit_op_get_callee(Instruction*);
         void emit_op_create_this(Instruction*);
         void emit_op_to_this(Instruction*);
-        void emit_op_create_arguments(Instruction*);
+        void emit_op_create_direct_arguments(Instruction*);
+        void emit_op_create_scoped_arguments(Instruction*);
+        void emit_op_create_out_of_band_arguments(Instruction*);
+        void emit_op_check_tdz(Instruction*);
         void emit_op_debug(Instruction*);
         void emit_op_del_by_id(Instruction*);
         void emit_op_div(Instruction*);
         void emit_op_end(Instruction*);
         void emit_op_enter(Instruction*);
-        void emit_op_create_activation(Instruction*);
+        void emit_op_create_lexical_environment(Instruction*);
+        void emit_op_get_scope(Instruction*);
         void emit_op_eq(Instruction*);
         void emit_op_eq_null(Instruction*);
         void emit_op_get_by_id(Instruction*);
         void emit_op_get_arguments_length(Instruction*);
         void emit_op_get_by_val(Instruction*);
         void emit_op_get_argument_by_val(Instruction*);
-        void emit_op_get_by_pname(Instruction*);
         void emit_op_init_lazy_reg(Instruction*);
         void emit_op_check_has_instance(Instruction*);
         void emit_op_instanceof(Instruction*);
@@ -484,6 +493,7 @@ namespace JSC {
         void emit_op_is_boolean(Instruction*);
         void emit_op_is_number(Instruction*);
         void emit_op_is_string(Instruction*);
+        void emit_op_is_object(Instruction*);
         void emit_op_jeq_null(Instruction*);
         void emit_op_jfalse(Instruction*);
         void emit_op_jmp(Instruction*);
@@ -510,12 +520,9 @@ namespace JSC {
         void emit_op_new_array_with_size(Instruction*);
         void emit_op_new_array_buffer(Instruction*);
         void emit_op_new_func(Instruction*);
-        void emit_op_new_captured_func(Instruction*);
         void emit_op_new_func_exp(Instruction*);
         void emit_op_new_object(Instruction*);
         void emit_op_new_regexp(Instruction*);
-        void emit_op_get_pnames(Instruction*);
-        void emit_op_next_pname(Instruction*);
         void emit_op_not(Instruction*);
         void emit_op_nstricteq(Instruction*);
         void emit_op_pop_scope(Instruction*);
@@ -523,15 +530,18 @@ namespace JSC {
         void emit_op_inc(Instruction*);
         void emit_op_profile_did_call(Instruction*);
         void emit_op_profile_will_call(Instruction*);
+        void emit_op_profile_type(Instruction*);
+        void emit_op_profile_control_flow(Instruction*);
         void emit_op_push_name_scope(Instruction*);
         void emit_op_push_with_scope(Instruction*);
         void emit_op_put_by_id(Instruction*);
         void emit_op_put_by_index(Instruction*);
         void emit_op_put_by_val(Instruction*);
+        void emit_op_put_getter_by_id(Instruction*);
+        void emit_op_put_setter_by_id(Instruction*);
         void emit_op_put_getter_setter(Instruction*);
         void emit_op_init_global_const(Instruction*);
         void emit_op_ret(Instruction*);
-        void emit_op_ret_object_or_this(Instruction*);
         void emit_op_rshift(Instruction*);
         void emit_op_strcat(Instruction*);
         void emit_op_stricteq(Instruction*);
@@ -539,15 +549,24 @@ namespace JSC {
         void emit_op_switch_char(Instruction*);
         void emit_op_switch_imm(Instruction*);
         void emit_op_switch_string(Instruction*);
-        void emit_op_tear_off_activation(Instruction*);
         void emit_op_tear_off_arguments(Instruction*);
         void emit_op_throw(Instruction*);
         void emit_op_throw_static_error(Instruction*);
         void emit_op_to_number(Instruction*);
+        void emit_op_to_string(Instruction*);
         void emit_op_to_primitive(Instruction*);
         void emit_op_unexpected_load(Instruction*);
         void emit_op_unsigned(Instruction*);
         void emit_op_urshift(Instruction*);
+        void emit_op_get_enumerable_length(Instruction*);
+        void emit_op_has_generic_property(Instruction*);
+        void emit_op_has_structure_property(Instruction*);
+        void emit_op_has_indexed_property(Instruction*);
+        void emit_op_get_direct_pname(Instruction*);
+        void emit_op_get_property_enumerator(Instruction*);
+        void emit_op_enumerator_structure_pname(Instruction*);
+        void emit_op_enumerator_generic_pname(Instruction*);
+        void emit_op_to_index_string(Instruction*);
 
         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -557,10 +576,10 @@ namespace JSC {
         void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_construct_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void emitSlow_op_captured_mov(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_to_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_create_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_check_tdz(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_callee(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -568,7 +587,6 @@ namespace JSC {
         void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_check_has_instance(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -598,13 +616,19 @@ namespace JSC {
         void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_to_string(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_unsigned(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_has_indexed_property(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_has_structure_property(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_get_direct_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
 
         void emit_op_resolve_scope(Instruction*);
         void emit_op_get_from_scope(Instruction*);
         void emit_op_put_to_scope(Instruction*);
+        void emit_op_get_from_arguments(Instruction*);
+        void emit_op_put_to_arguments(Instruction*);
         void emitSlow_op_resolve_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_from_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_put_to_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -613,28 +637,19 @@ namespace JSC {
         void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned);
 
         void emitVarInjectionCheck(bool needsVarInjectionChecks);
-        void emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned depth);
+        void emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, unsigned depth);
         void emitLoadWithStructureCheck(int scope, Structure** structureSlot);
         void emitGetGlobalProperty(uintptr_t* operandSlot);
         void emitGetGlobalVar(uintptr_t operand);
         void emitGetClosureVar(int scope, uintptr_t operand);
         void emitPutGlobalProperty(uintptr_t* operandSlot, int value);
-#if USE(JSVALUE64)
-        void emitNotifyWrite(RegisterID value, RegisterID scratch, VariableWatchpointSet*);
-#else
-        void emitNotifyWrite(RegisterID tag, RegisterID payload, RegisterID scratch, VariableWatchpointSet*);
-#endif
-        void emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet*);
-        void emitPutClosureVar(int scope, uintptr_t operand, int value);
+        void emitNotifyWrite(WatchpointSet*);
+        void emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet*);
+        void emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet*);
 
         void emitInitRegister(int dst);
 
         void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
-        void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-        void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-#if USE(JSVALUE64)
-        void emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
-#endif
 
         JSValue getConstantOperand(int src);
         bool isOperandConstantImmediateInt(int src);
@@ -668,9 +683,11 @@ namespace JSC {
         
         MacroAssembler::Call callOperation(C_JITOperation_E);
         MacroAssembler::Call callOperation(C_JITOperation_EO, GPRReg);
+        MacroAssembler::Call callOperation(C_JITOperation_EL, GPRReg);
+        MacroAssembler::Call callOperation(C_JITOperation_EL, TrustedImmPtr);
         MacroAssembler::Call callOperation(C_JITOperation_ESt, Structure*);
         MacroAssembler::Call callOperation(C_JITOperation_EZ, int32_t);
-        MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, int32_t, int32_t);
+        MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, int32_t, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_E, int);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJcpZ, int, ArrayAllocationProfile*, GPRReg, int32_t);
@@ -679,12 +696,17 @@ namespace JSC {
         MacroAssembler::Call callOperation(V_JITOperation_EC, JSCell*);
         MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg);
 #if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, StringImpl*);
+        MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*);
 #else
-        MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, StringImpl*);
+        MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*);
 #endif
         MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*);
         MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
+        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
+        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
+        MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
+        MacroAssembler::Call callOperation(C_JITOperation_EJscZ, GPRReg, int32_t);
+        MacroAssembler::Call callOperation(C_JITOperation_EJscZ, int, GPRReg, int32_t);
 #if USE(JSVALUE64)
         MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EJJ, int, GPRReg, GPRReg);
 #else
@@ -693,6 +715,7 @@ namespace JSC {
         MacroAssembler::Call callOperation(J_JITOperation_EP, int, void*);
         MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EPc, int, Instruction*);
         MacroAssembler::Call callOperation(J_JITOperation_EZ, int, int32_t);
+        MacroAssembler::Call callOperation(J_JITOperation_EZZ, int, int32_t, int32_t);
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, size_t);
         MacroAssembler::Call callOperation(S_JITOperation_ECC, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID);
@@ -702,45 +725,52 @@ namespace JSC {
         MacroAssembler::Call callOperation(V_JITOperation_E);
         MacroAssembler::Call callOperation(V_JITOperation_EC, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_ECC, RegisterID, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_ECIC, RegisterID, const Identifier*, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_ECICC, RegisterID, const Identifier*, RegisterID, RegisterID);
-        MacroAssembler::Call callOperation(V_JITOperation_EIdJZ, const Identifier*, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(J_JITOperation_EE, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID);
 #if USE(JSVALUE64)
         MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID);
 #else
         MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID, RegisterID);
 #endif
+        MacroAssembler::Call callOperation(V_JITOperation_EJIdJ, RegisterID, const Identifier*, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID);
 #if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, int32_t);
-        MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, StringImpl*);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, int32_t, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, UniquedStringImpl*);
 #else
-        MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, RegisterID, RegisterID, StringImpl*);
+        MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, RegisterID, RegisterID, UniquedStringImpl*);
 #endif
         MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, ArrayProfile*);
         MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, int32_t, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_EPc, Instruction*);
         MacroAssembler::Call callOperation(V_JITOperation_EZ, int32_t);
+        MacroAssembler::Call callOperation(V_JITOperation_EZJ, int, GPRReg);
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(J_JITOperation_E);
-        MacroAssembler::Call callOperationNoExceptionCheck(J_JITOperation_EE, RegisterID);
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb, CodeBlock*);
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E);
 #if USE(JSVALUE32_64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJJZ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, int32_t);
-        MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, RegisterID, int32_t, RegisterID);
+        MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, GPRReg, const Identifier*);
         MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg);
+        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*);
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
         MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(S_JITOperation_EJJ, RegisterID, RegisterID, RegisterID, RegisterID);
-        MacroAssembler::Call callOperation(V_JITOperation_EIdJZ, const Identifier*, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ArrayProfile*);
         MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, RegisterID, int32_t, RegisterID, RegisterID);
+        MacroAssembler::Call callOperation(V_JITOperation_EZJ, int32_t, RegisterID, RegisterID);
 #endif
 
         Jump checkStructure(RegisterID reg, Structure* structure);
@@ -815,7 +845,7 @@ namespace JSC {
         unsigned m_byValInstructionIndex;
         unsigned m_callLinkInfoIndex;
 
-        OwnPtr<JITDisassembler> m_disassembler;
+        std::unique_ptr<JITDisassembler> m_disassembler;
         RefPtr<Profiler::Compilation> m_compilation;
         WeakRandom m_randomGenerator;
         static CodeRef stringGetByValStubGenerator(VM*);
index 9f4d61f72c0ff08109143cfc13663865e919e52a..9a97cdb7c5c4377c095f1d614c0fc048c7d16a87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,6 @@
 #if USE(JSVALUE64)
 #include "JIT.h"
 
-#include "Arguments.h"
 #include "CodeBlock.h"
 #include "JITInlines.h"
 #include "JSArray.h"
@@ -40,6 +39,7 @@
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "SetupVarargsFrame.h"
 #include "StackAlignment.h"
 #include "ThunkGenerators.h"
 #include <wtf/StringPrintStream.h>
@@ -54,100 +54,51 @@ void JIT::emitPutCallResult(Instruction* instruction)
     emitPutVirtualRegister(dst);
 }
 
-void JIT::compileLoadVarargs(Instruction* instruction)
+void JIT::compileSetupVarargsFrame(Instruction* instruction, CallLinkInfo* info)
 {
     int thisValue = instruction[3].u.operand;
     int arguments = instruction[4].u.operand;
     int firstFreeRegister = instruction[5].u.operand;
     int firstVarArgOffset = instruction[6].u.operand;
 
-    JumpList slowCase;
-    JumpList end;
-    bool canOptimize = m_codeBlock->usesArguments()
-        && arguments == m_codeBlock->argumentsRegister().offset()
-        && !m_codeBlock->symbolTable()->slowArguments();
-
-    if (canOptimize) {
-        emitGetVirtualRegister(arguments, regT0);
-        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
-
-        emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
-        if (firstVarArgOffset) {
-            Jump sufficientArguments = branch32(GreaterThan, regT0, TrustedImm32(firstVarArgOffset + 1));
-            move(TrustedImm32(1), regT0);
-            Jump endVarArgs = jump();
-            sufficientArguments.link(this);
-            sub32(TrustedImm32(firstVarArgOffset), regT0);
-            endVarArgs.link(this);
-        }
-        slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
-        // regT0: argumentCountIncludingThis
-        move(regT0, regT1);
-        add64(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT1);
-        // regT1 now has the required frame size in Register units
-        // Round regT1 to next multiple of stackAlignmentRegisters()
-        add64(TrustedImm32(stackAlignmentRegisters() - 1), regT1);
-        and64(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT1);
-
-        neg64(regT1);
-        lshift64(TrustedImm32(3), regT1);
-        addPtr(callFrameRegister, regT1);
-        // regT1: newCallFrame
-
-        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT1));
-
-        // Initialize ArgumentCount.
-        store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-
-        // Initialize 'this'.
-        emitGetVirtualRegister(thisValue, regT2);
-        store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
-
-        // Copy arguments.
-        signExtend32ToPtr(regT0, regT0);
-        end.append(branchSub64(Zero, TrustedImm32(1), regT0));
-        // regT0: argumentCount
-
-        Label copyLoop = label();
-        load64(BaseIndex(callFrameRegister, regT0, TimesEight, (CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register))), regT2);
-        store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
-        branchSub64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this);
-
-        end.append(jump());
-    }
-
-    if (canOptimize)
-        slowCase.link(this);
-
     emitGetVirtualRegister(arguments, regT1);
-    callOperation(operationSizeFrameForVarargs, regT1, firstFreeRegister, firstVarArgOffset);
-    move(returnValueGPR, stackPointerRegister);
-    emitGetVirtualRegister(thisValue, regT1);
+    callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
+    move(TrustedImm32(-firstFreeRegister), regT1);
+    emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1);
+    addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), regT1, stackPointerRegister);
     emitGetVirtualRegister(arguments, regT2);
-    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT2, firstVarArgOffset);
+    callOperation(operationSetupVarargsFrame, regT1, regT2, firstVarArgOffset, regT0);
     move(returnValueGPR, regT1);
 
-    if (canOptimize)
-        end.link(this);
+    // Profile the argument count.
+    load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
+    load8(info->addressOfMaxNumArguments(), regT0);
+    Jump notBiggest = branch32(Above, regT0, regT2);
+    Jump notSaturated = branch32(BelowOrEqual, regT2, TrustedImm32(255));
+    move(TrustedImm32(255), regT2);
+    notSaturated.link(this);
+    store8(regT2, info->addressOfMaxNumArguments());
+    notBiggest.link(this);
     
+    // Initialize 'this'.
+    emitGetVirtualRegister(thisValue, regT0);
+    store64(regT0, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
+
     addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
 }
 
 void JIT::compileCallEval(Instruction* instruction)
 {
     addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), stackPointerRegister, regT1);
-    callOperationNoExceptionCheck(operationCallEval, regT1);
-
-    Jump noException = emitExceptionCheck(InvertedExceptionCheck);
-    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);    
-    exceptionCheck(jump());
-
-    noException.link(this);
-    addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue()))));
+    storePtr(callFrameRegister, Address(regT1, CallFrame::callerFrameOffset()));
 
     addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
     checkStackPointerAlignment();
 
+    callOperation(operationCallEval, regT1);
+
+    addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue()))));
+
     sampleCodeBlock(m_codeBlock);
     
     emitPutCallResult(instruction);
@@ -156,6 +107,9 @@ void JIT::compileCallEval(Instruction* instruction)
 void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     linkSlowCase(iter);
+    int registerOffset = -instruction[4].u.operand;
+
+    addPtr(TrustedImm32(registerOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), callFrameRegister, stackPointerRegister);
 
     load64(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT0);
     move(TrustedImmPtr(&CallLinkInfo::dummy()), regT2);
@@ -170,6 +124,8 @@ void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry
 
 void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
 {
+    CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
+
     int callee = instruction[2].u.operand;
 
     /* Caller always:
@@ -177,19 +133,18 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
         - Initializes ArgumentCount; CallerFrame; Callee.
 
        For a JS call:
-        - Caller initializes ScopeChain.
         - Callee initializes ReturnPC; CodeBlock.
         - Callee restores callFrameRegister before return.
 
        For a non-JS call:
-        - Caller initializes ScopeChain; ReturnPC; CodeBlock.
+        - Caller initializes ReturnPC; CodeBlock.
         - Caller restores callFrameRegister after return.
     */
     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct), call_and_construct_opcodes_must_be_same_length);
     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_varargs), call_and_call_varargs_opcodes_must_be_same_length);
     COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct_varargs), call_and_construct_varargs_opcodes_must_be_same_length);
     if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
-        compileLoadVarargs(instruction);
+        compileSetupVarargsFrame(instruction, info);
     else {
         int argCount = instruction[3].u.operand;
         int registerOffset = -instruction[4].u.operand;
@@ -212,7 +167,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
     emitGetVirtualRegister(callee, regT0); // regT0 holds callee.
 
     store64(regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
-
+    
     if (opcodeID == op_call_eval) {
         compileCallEval(instruction);
         return;
@@ -223,17 +178,11 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
     addSlowCase(slowCase);
 
     ASSERT(m_callCompilationInfo.size() == callLinkInfoIndex);
-    CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
-    info->callType = CallLinkInfo::callTypeFor(opcodeID);
-    info->codeOrigin = CodeOrigin(m_bytecodeOffset);
-    info->calleeGPR = regT0;
+    info->setUpCall(CallLinkInfo::callTypeFor(opcodeID), CodeOrigin(m_bytecodeOffset), regT0);
     m_callCompilationInfo.append(CallCompilationInfo());
     m_callCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
     m_callCompilationInfo[callLinkInfoIndex].callLinkInfo = info;
 
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT2);
-    store64(regT2, Address(MacroAssembler::stackPointerRegister, JSStack::ScopeChain * sizeof(Register) - sizeof(CallerFrameAndPC)));
-
     m_callCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
 
     addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
@@ -268,52 +217,6 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction* instruction, Vec
     emitPutCallResult(instruction);
 }
 
-void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
-{
-    JumpList slowCases;
-
-    slowCases.append(branchTestPtr(NonZero, regT0, tagMaskRegister));
-    slowCases.append(branchStructure(NotEqual, Address(regT0, JSCell::structureIDOffset()), expectedStructure));
-    slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
-    
-    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
-    emitPutToCallFrameHeader(regT1, JSStack::ScopeChain);
-    
-    Call call = nearCall();
-    Jump done = jump();
-    
-    slowCases.link(this);
-    move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
-    restoreReturnAddressBeforeReturn(regT2);
-    Jump slow = jump();
-    
-    LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock);
-    
-    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
-    patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
-    patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallThunkGenerator).code()));
-    
-    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
-        FINALIZE_CODE(
-            patchBuffer,
-            ("Baseline closure call stub for %s, return point %p, target %p (%s)",
-                toCString(*m_codeBlock).data(),
-                callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
-                codePtr.executableAddress(),
-                toCString(pointerDump(calleeCodeBlock)).data())),
-        *m_vm, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
-        callLinkInfo->codeOrigin));
-    
-    RepatchBuffer repatchBuffer(m_codeBlock);
-    
-    repatchBuffer.replaceWithJump(
-        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
-        CodeLocationLabel(stubRoutine->code().code()));
-    repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallThunkGenerator).code());
-
-    callLinkInfo->stub = stubRoutine.release();
-}
-
 void JIT::emit_op_call(Instruction* currentInstruction)
 {
     compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
index 3a9feb221c264959840db571a0909522def19eaa..2373c53fb2627e97a92dc83e64b8d624ad8c0d77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,6 @@
 #if USE(JSVALUE32_64)
 #include "JIT.h"
 
-#include "Arguments.h"
 #include "CodeBlock.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
@@ -40,6 +39,7 @@
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "SetupVarargsFrame.h"
 #include "StackAlignment.h"
 #include <wtf/StringPrintStream.h>
 
@@ -64,28 +64,6 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
     ret();
 }
 
-void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
-{
-    unsigned result = currentInstruction[1].u.operand;
-    unsigned thisReg = currentInstruction[2].u.operand;
-
-    emitLoad(result, regT1, regT0);
-    Jump notJSCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    Jump notObject = emitJumpIfCellNotObject(regT0);
-
-    checkStackPointerAlignment();
-    emitFunctionEpilogue();
-    ret();
-
-    notJSCell.link(this);
-    notObject.link(this);
-    emitLoad(thisReg, regT1, regT0);
-
-    checkStackPointerAlignment();
-    emitFunctionEpilogue();
-    ret();
-}
-
 void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     compileOpCallSlowCase(op_call, currentInstruction, iter, m_callLinkInfoIndex++);
@@ -136,102 +114,50 @@ void JIT::emit_op_construct(Instruction* currentInstruction)
     compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
 }
 
-void JIT::compileLoadVarargs(Instruction* instruction)
+void JIT::compileSetupVarargsFrame(Instruction* instruction, CallLinkInfo* info)
 {
     int thisValue = instruction[3].u.operand;
     int arguments = instruction[4].u.operand;
     int firstFreeRegister = instruction[5].u.operand;
     int firstVarArgOffset = instruction[6].u.operand;
 
-    JumpList slowCase;
-    JumpList end;
-    bool canOptimize = m_codeBlock->usesArguments()
-        && VirtualRegister(arguments) == m_codeBlock->argumentsRegister()
-        && !m_codeBlock->symbolTable()->slowArguments();
-
-    if (canOptimize) {
-        emitLoadTag(arguments, regT1);
-        slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
-
-        load32(payloadFor(JSStack::ArgumentCount), regT2);
-        if (firstVarArgOffset) {
-            Jump sufficientArguments = branch32(GreaterThan, regT2, TrustedImm32(firstVarArgOffset + 1));
-            move(TrustedImm32(1), regT2);
-            Jump endVarArgs = jump();
-            sufficientArguments.link(this);
-            sub32(TrustedImm32(firstVarArgOffset), regT2);
-            endVarArgs.link(this);
-        }
-        slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1)));
-        // regT2: argumentCountIncludingThis
-
-        move(regT2, regT3);
-        addPtr(TrustedImm32(-firstFreeRegister + JSStack::CallFrameHeaderSize), regT3);
-        // regT1 now has the required frame size in Register units
-        // Round regT1 to next multiple of stackAlignmentRegisters()
-        addPtr(TrustedImm32(stackAlignmentRegisters() - 1), regT3);
-        andPtr(TrustedImm32(~(stackAlignmentRegisters() - 1)), regT3);
-        neg32(regT3);
-        lshift32(TrustedImm32(3), regT3);
-        addPtr(callFrameRegister, regT3);
-        // regT3: newCallFrame
-
-        slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), regT3));
-
-        // Initialize ArgumentCount.
-        store32(regT2, payloadFor(JSStack::ArgumentCount, regT3));
-
-        // Initialize 'this'.
-        emitLoad(thisValue, regT1, regT0);
-        store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-
-        // Copy arguments.
-        end.append(branchSub32(Zero, TrustedImm32(1), regT2));
-        // regT2: argumentCount;
-
-        Label copyLoop = label();
-        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT0);
-        load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +((CallFrame::thisArgumentOffset() + firstVarArgOffset) * static_cast<int>(sizeof(Register)))), regT1);
-        store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
-        branchSub32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this);
-
-        end.append(jump());
-    }
-
-    if (canOptimize)
-        slowCase.link(this);
-
     emitLoad(arguments, regT1, regT0);
-    callOperation(operationSizeFrameForVarargs, regT1, regT0, firstFreeRegister, firstVarArgOffset);
-    addPtr(TrustedImm32(-sizeof(CallerFrameAndPC)), returnValueGPR, stackPointerRegister);
-    emitLoad(thisValue, regT1, regT4);
-    emitLoad(arguments, regT3, regT2);
-    callOperation(operationLoadVarargs, returnValueGPR, regT1, regT4, regT3, regT2, firstVarArgOffset);
-    move(returnValueGPR, regT3);
-
-    if (canOptimize)
-        end.link(this);
-
-    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT3, stackPointerRegister);
+    callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
+    move(TrustedImm32(-firstFreeRegister), regT1);
+    emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1);
+    addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), regT1, stackPointerRegister);
+    emitLoad(arguments, regT2, regT4);
+    callOperation(operationSetupVarargsFrame, regT1, regT2, regT4, firstVarArgOffset, regT0);
+    move(returnValueGPR, regT1);
+
+    // Profile the argument count.
+    load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
+    load8(info->addressOfMaxNumArguments(), regT0);
+    Jump notBiggest = branch32(Above, regT0, regT2);
+    Jump notSaturated = branch32(BelowOrEqual, regT2, TrustedImm32(255));
+    move(TrustedImm32(255), regT2);
+    notSaturated.link(this);
+    store8(regT2, info->addressOfMaxNumArguments());
+    notBiggest.link(this);
+    
+    // Initialize 'this'.
+    emitLoad(thisValue, regT2, regT0);
+    store32(regT0, Address(regT1, PayloadOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
+    store32(regT2, Address(regT1, TagOffset + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))));
+    
+    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
 }
 
 void JIT::compileCallEval(Instruction* instruction)
 {
     addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), stackPointerRegister, regT1);
+    storePtr(callFrameRegister, Address(regT1, CallFrame::callerFrameOffset()));
 
-    callOperationNoExceptionCheck(operationCallEval, regT1);
-
-    Jump noException = emitExceptionCheck(InvertedExceptionCheck);
     addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
-    exceptionCheck(jump());
 
-    noException.link(this);
-    addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
+    callOperation(operationCallEval, regT1);
 
-    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
-    checkStackPointerAlignment();
+    addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
 
     sampleCodeBlock(m_codeBlock);
     
@@ -242,6 +168,10 @@ void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry
 {
     linkSlowCase(iter);
 
+    int registerOffset = -instruction[4].u.operand;
+
+    addPtr(TrustedImm32(registerOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), callFrameRegister, stackPointerRegister);
+
     loadPtr(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT0);
     loadPtr(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT1);
     move(TrustedImmPtr(&CallLinkInfo::dummy()), regT2);
@@ -258,6 +188,7 @@ void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry
 
 void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
 {
+    CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
     int callee = instruction[2].u.operand;
 
     /* Caller always:
@@ -265,17 +196,16 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
         - Initializes ArgumentCount; CallerFrame; Callee.
 
        For a JS call:
-        - Caller initializes ScopeChain.
         - Callee initializes ReturnPC; CodeBlock.
         - Callee restores callFrameRegister before return.
 
        For a non-JS call:
-        - Caller initializes ScopeChain; ReturnPC; CodeBlock.
+        - Caller initializes ReturnPC; CodeBlock.
         - Caller restores callFrameRegister after return.
     */
     
     if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
-        compileLoadVarargs(instruction);
+        compileSetupVarargsFrame(instruction, info);
     else {
         int argCount = instruction[3].u.operand;
         int registerOffset = -instruction[4].u.operand;
@@ -313,18 +243,11 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
     addSlowCase(slowCase);
 
     ASSERT(m_callCompilationInfo.size() == callLinkInfoIndex);
-    CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
-    info->callType = CallLinkInfo::callTypeFor(opcodeID);
-    info->codeOrigin = CodeOrigin(m_bytecodeOffset);
-    info->calleeGPR = regT0;
+    info->setUpCall(CallLinkInfo::callTypeFor(opcodeID), CodeOrigin(m_bytecodeOffset), regT0);
     m_callCompilationInfo.append(CallCompilationInfo());
     m_callCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
     m_callCompilationInfo[callLinkInfoIndex].callLinkInfo = info;
 
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT2);
-    store32(regT2, Address(MacroAssembler::stackPointerRegister, JSStack::ScopeChain * sizeof(Register) + PayloadOffset - sizeof(CallerFrameAndPC)));
-    store32(TrustedImm32(JSValue::CellTag), Address(stackPointerRegister, JSStack::ScopeChain * sizeof(Register) + TagOffset - sizeof(CallerFrameAndPC)));
-
     checkStackPointerAlignment();
     m_callCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
 
@@ -359,52 +282,6 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction* instruction, Vec
     emitPutCallResult(instruction);
 }
 
-void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
-{
-    JumpList slowCases;
-
-    slowCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
-    slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(expectedStructure)));
-    slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
-    
-    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
-    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-    
-    Call call = nearCall();
-    Jump done = jump();
-    
-    slowCases.link(this);
-    move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
-    restoreReturnAddressBeforeReturn(regT2);
-    Jump slow = jump();
-    
-    LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock);
-    
-    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
-    patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
-    patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallThunkGenerator).code()));
-    
-    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
-        FINALIZE_CODE(
-            patchBuffer,
-            ("Baseline closure call stub for %s, return point %p, target %p (%s)",
-                toCString(*m_codeBlock).data(),
-                callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
-                codePtr.executableAddress(),
-                toCString(pointerDump(calleeCodeBlock)).data())),
-        *m_vm, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
-        callLinkInfo->codeOrigin));
-    
-    RepatchBuffer repatchBuffer(m_codeBlock);
-    
-    repatchBuffer.replaceWithJump(
-        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
-        CodeLocationLabel(stubRoutine->code().code()));
-    repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallThunkGenerator).code());
-    
-    callLinkInfo->stub = stubRoutine.release();
-}
-
 } // namespace JSC
 
 #endif // USE(JSVALUE32_64)
index df0759cbf9fc58a9cdf68be08f6f6933f11e04c4..e86b5c346170b33fc4ae56ecea5135a5314827e7 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "LLIntThunks.h"
 #include "JSCInlines.h"
+#include "ProtoCallFrame.h"
 #include "RegisterPreservationWrapperGenerator.h"
 #include <wtf/PrintStream.h>
 
@@ -42,9 +43,42 @@ JITCode::~JITCode()
 {
 }
 
+const char* JITCode::typeName(JITType jitType)
+{
+    switch (jitType) {
+    case None:
+        return "None";
+    case HostCallThunk:
+        return "Host";
+    case InterpreterThunk:
+        return "LLInt";
+    case BaselineJIT:
+        return "Baseline";
+    case DFGJIT:
+        return "DFG";
+    case FTLJIT:
+        return "FTL";
+    default:
+        CRASH();
+        return "";
+    }
+}
+
+void JITCode::validateReferences(const TrackedReferences&)
+{
+}
+
 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
 {
-    JSValue result = JSValue::decode(callToJavaScript(executableAddress(), vm, protoCallFrame));
+    void* entryAddress;
+    JSFunction* function = jsDynamicCast<JSFunction*>(protoCallFrame->callee());
+
+    if (!function || !protoCallFrame->needArityCheck()) {
+        ASSERT(!protoCallFrame->needArityCheck());
+        entryAddress = executableAddress();
+    } else
+        entryAddress = addressForCall(*vm, function->executable(), MustCheckArity, RegisterPreservationNotRequired).executableAddress();
+    JSValue result = JSValue::decode(vmEntryToJavaScript(entryAddress, vm, protoCallFrame));
     return vm->exception() ? jsNull() : result;
 }
 
@@ -224,29 +258,7 @@ namespace WTF {
 
 void printInternal(PrintStream& out, JSC::JITCode::JITType type)
 {
-    switch (type) {
-    case JSC::JITCode::None:
-        out.print("None");
-        return;
-    case JSC::JITCode::HostCallThunk:
-        out.print("Host");
-        return;
-    case JSC::JITCode::InterpreterThunk:
-        out.print("LLInt");
-        return;
-    case JSC::JITCode::BaselineJIT:
-        out.print("Baseline");
-        return;
-    case JSC::JITCode::DFGJIT:
-        out.print("DFG");
-        return;
-    case JSC::JITCode::FTLJIT:
-        out.print("FTL");
-        return;
-    default:
-        CRASH();
-        return;
-    }
+    out.print(JSC::JITCode::typeName(type));
 }
 
 } // namespace WTF
index 010392368ce452064193b6a6c4d8841454606286..1d83cb59d7a738ae66c895f231e1686d592c1da9 100644 (file)
@@ -31,7 +31,6 @@
 #include "Disassembler.h"
 #include "JITStubs.h"
 #include "JSCJSValue.h"
-#include "LegacyProfiler.h"
 #include "MacroAssemblerCodeRef.h"
 #include "RegisterPreservationMode.h"
 
@@ -47,6 +46,7 @@ class JITCode;
 }
 
 struct ProtoCallFrame;
+class TrackedReferences;
 class VM;
 
 class JITCode : public ThreadSafeRefCounted<JITCode> {
@@ -63,6 +63,8 @@ public:
         FTLJIT
     };
     
+    static const char* typeName(JITType);
+
     static JITType bottomTierJIT()
     {
         return BaselineJIT;
@@ -182,6 +184,8 @@ public:
     virtual FTL::JITCode* ftl();
     virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
     
+    virtual void validateReferences(const TrackedReferences&);
+    
     JSValue execute(VM*, ProtoCallFrame*);
     
     void* start() { return dataAddressAtOffset(0); }
index 5eb68017899119c7c504d70b38ca1f0d1bff2414..29e95426a07a46ae6221723450a55d33851c71b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index 1375ae6477d49ae689ac5f6546c9cc316cba7217..4f6d9e8f02908ca8bb4bf14495ba52a5f89f3d7b 100644 (file)
 
 namespace JSC {
 
-void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
+void genericUnwind(VM* vm, ExecState* callFrame)
 {
     if (Options::breakOnThrow()) {
         dataLog("In call frame ", RawPointer(callFrame), " for code block ", *callFrame->codeBlock(), "\n");
         CRASH();
     }
     
-    RELEASE_ASSERT(exceptionValue);
-    HandlerInfo* handler = vm->interpreter->unwind(callFrame, exceptionValue); // This may update callFrame.
+    Exception* exception = vm->exception();
+    RELEASE_ASSERT(exception);
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    HandlerInfo* handler = vm->interpreter->unwind(vmEntryFrame, callFrame, exception); // This may update vmEntryFrame and callFrame.
 
     void* catchRoutine;
     Instruction* catchPCForInterpreter = 0;
@@ -62,6 +64,7 @@ void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
     } else
         catchRoutine = LLInt::getCodePtr(handleUncaughtException);
     
+    vm->vmEntryFrameForThrow = vmEntryFrame;
     vm->callFrameForThrow = callFrame;
     vm->targetMachinePCForThrow = catchRoutine;
     vm->targetInterpreterPCForThrow = catchPCForInterpreter;
index e02b515ebe1f6c1954b4ce79b8c8ca85fca4b0ee..43b92e7fb9653e47b64e53a8d433cb060a8e3de8 100644 (file)
@@ -33,7 +33,7 @@ namespace JSC {
 class ExecState;
 class VM;
 
-void genericUnwind(VM*, ExecState*, JSValue exceptionValue);
+void genericUnwind(VM*, ExecState*);
 
 } // namespace JSC
 
index 7072b5e16404ff38b50da437823d2ab5a325d969..a21c8088d78a0e8c6b50818c6ba1f5aa60d59126 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+#if USE(JSVALUE64)
+inline MacroAssembler::JumpList JIT::emitDoubleGetByVal(Instruction* instruction, PatchableJump& badType)
+{
+    JumpList slowCases = emitDoubleLoad(instruction, badType);
+    moveDoubleTo64(fpRegT0, regT0);
+    sub64(tagTypeNumberRegister, regT0);
+    return slowCases;
+}
+#else
+inline MacroAssembler::JumpList JIT::emitDoubleGetByVal(Instruction* instruction, PatchableJump& badType)
+{
+    JumpList slowCases = emitDoubleLoad(instruction, badType);
+    moveDoubleToInts(fpRegT0, regT0, regT1);
+    return slowCases;
+}
+#endif // USE(JSVALUE64)
+
+ALWAYS_INLINE MacroAssembler::JumpList JIT::emitLoadForArrayMode(Instruction* currentInstruction, JITArrayMode arrayMode, PatchableJump& badType)
+{
+    switch (arrayMode) {
+    case JITInt32:
+        return emitInt32Load(currentInstruction, badType);
+    case JITDouble:
+        return emitDoubleLoad(currentInstruction, badType);
+    case JITContiguous:
+        return emitContiguousLoad(currentInstruction, badType);
+    case JITArrayStorage:
+        return emitArrayStorageLoad(currentInstruction, badType);
+    default:
+        break;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return MacroAssembler::JumpList();
+}
+
+inline MacroAssembler::JumpList JIT::emitContiguousGetByVal(Instruction* instruction, PatchableJump& badType, IndexingType expectedShape)
+{
+    return emitContiguousLoad(instruction, badType, expectedShape);
+}
+
+inline MacroAssembler::JumpList JIT::emitArrayStorageGetByVal(Instruction* instruction, PatchableJump& badType)
+{
+    return emitArrayStorageLoad(instruction, badType);
+}
+
 ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(int src)
 {
     return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();
@@ -53,23 +98,6 @@ ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, JSStack::Ca
 #endif
 }
 
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    loadPtr(Address(from, entry * sizeof(Register)), to);
-}
-
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    load32(Address(from, entry * sizeof(Register)), to);
-}
-
-#if USE(JSVALUE64)
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
-{
-    load64(Address(from, entry * sizeof(Register)), to);
-}
-#endif
-
 ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
 {
     failures.append(branchStructure(NotEqual, Address(src, JSCell::structureIDOffset()), m_vm->stringStructure.get()));
@@ -91,7 +119,7 @@ ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst,
 
 ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
     Call nakedCall = nearCall();
     m_calls.append(CallRecord(nakedCall, m_bytecodeOffset, function.executableAddress()));
     return nakedCall;
@@ -165,6 +193,30 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_E operation
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJsc operation, GPRReg arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJscZ operation, GPRReg arg1, int32_t arg2)
+{
+    setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
+    return appendCallWithExceptionCheck(operation);
+}
+
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EL operation, GPRReg arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+    
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EL operation, TrustedImmPtr arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+    
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EO operation, GPRReg arg)
 {
     setupArgumentsWithExecState(arg);
@@ -213,6 +265,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EC operatio
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJscC operation, int dst, GPRReg arg1, JSCell* cell)
+{
+    setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
+    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EP operation, int dst, void* pointer)
 {
     setupArgumentsWithExecState(TrustedImmPtr(pointer));
@@ -231,6 +289,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EZ operatio
     return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EZZ operation, int dst, int32_t arg1, int32_t arg2)
+{
+    setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImm32(arg2));
+    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_ECC operation, RegisterID regOp1, RegisterID regOp2)
 {
     setupArgumentsWithExecState(regOp1, regOp2);
@@ -272,6 +336,13 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ECC operati
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EE operation, RegisterID regOp)
+{
+    setupArgumentsWithExecState(regOp);
+    updateTopCallFrame();
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EPc operation, Instruction* bytecodePC)
 {
     setupArgumentsWithExecState(TrustedImmPtr(bytecodePC));
@@ -290,13 +361,6 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnExce
     return appendCallWithCallFrameRollbackOnException(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(J_JITOperation_EE operation, RegisterID regOp)
-{
-    setupArgumentsWithExecState(regOp);
-    updateTopCallFrame();
-    return appendCall(operation);
-}
-
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, CodeBlock* pointer)
 {
     setupArgumentsWithExecState(TrustedImmPtr(pointer));
@@ -311,19 +375,19 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnExce
 
 
 #if USE(JSVALUE64)
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3)
 {
     setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, int32_t arg4)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3, GPRReg arg4)
 {
-    setupArgumentsWithExecState(arg1, arg2, arg3, TrustedImm32(arg4));
+    setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1, RegisterID regOp2, StringImpl* uid)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1, RegisterID regOp2, UniquedStringImpl* uid)
 {
     setupArgumentsWithExecState(TrustedImmPtr(stubInfo), regOp1, regOp2, TrustedImmPtr(uid));
     return appendCallWithExceptionCheck(operation);
@@ -335,7 +399,19 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJ operat
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, StringImpl* uid)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJAp operation, RegisterID regOp1, RegisterID regOp2, RegisterID regOp3, ArrayProfile* arrayProfile)
+{
+    setupArgumentsWithExecState(regOp1, regOp2, regOp3, TrustedImmPtr(arrayProfile));
+    return appendCallWithExceptionCheck(operation);
+}
+
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZJ operation, int dst, GPRReg arg)
+{
+    setupArgumentsWithExecState(TrustedImm32(dst), arg);
+    return appendCallWithExceptionCheck(operation);
+}
+
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
 {
     setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
     return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
@@ -371,6 +447,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJ operati
     return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJAp operation, int dst, GPRReg arg1, GPRReg arg2, ArrayProfile* arrayProfile)
+{
+    setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arrayProfile));
+    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1)
 {
     setupArgumentsWithExecState(arg1);
@@ -396,9 +478,9 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operati
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2, int32_t op3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZSymtabJ operation, int op1, SymbolTable* symbolTable, RegisterID regOp3)
 {
-    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2, TrustedImm32(op3));
+    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(symbolTable), regOp3);
     return appendCallWithExceptionCheck(operation);
 }
 
@@ -408,6 +490,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operatio
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJIdJ operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3)
+{
+    setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3);
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJIdJJ operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3, RegisterID regOp4)
 {
     setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3, regOp4);
@@ -452,15 +540,15 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOpera
     return appendCall(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3)
 {
     setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload, int32_t arg4)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3, GPRReg arg4)
 {
-    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag, TrustedImm32(arg4));
+    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
     return appendCallWithExceptionCheck(operation);
 }
     
@@ -476,7 +564,7 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJ operatio
     return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, StringImpl* uid)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
 {
     setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
     return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
@@ -494,6 +582,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJ operati
     return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJAp operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, ArrayProfile* arrayProfile)
+{
+    setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag, TrustedImmPtr(arrayProfile));
+    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_EJJ operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
 {
     setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
@@ -518,6 +612,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operati
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ECIC operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3)
+{
+    setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3);
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ECICC operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3, RegisterID regOp4)
 {
     setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3, regOp4);
@@ -530,13 +630,13 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operatio
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2Tag, RegisterID regOp2Payload, int32_t op3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZSymtabJ operation, int32_t op1, SymbolTable* symbolTable, RegisterID regOp3Tag, RegisterID regOp3Payload)
 {
-    setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2Payload, regOp2Tag, TrustedImm32(op3));
+    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(symbolTable), EABI_32BIT_DUMMY_ARG regOp3Payload, regOp3Tag);
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, StringImpl* uid)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, UniquedStringImpl* uid)
 {
     setupArgumentsWithExecState(TrustedImmPtr(stubInfo), regOp1Payload, regOp1Tag, regOp2Payload, regOp2Tag, TrustedImmPtr(uid));
     return appendCallWithExceptionCheck(operation);
@@ -548,6 +648,18 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJ operat
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJAp operation, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, RegisterID regOp3Tag, RegisterID regOp3Payload, ArrayProfile* arrayProfile)
+{
+    setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, SH4_32BIT_DUMMY_ARG regOp2Payload, regOp2Tag, regOp3Payload, regOp3Tag, TrustedImmPtr(arrayProfile));
+    return appendCallWithExceptionCheck(operation);
+}
+
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZJ operation, int dst, RegisterID regOp1Tag, RegisterID regOp1Payload)
+{
+    setupArgumentsWithExecState(TrustedImm32(dst), regOp1Payload, regOp1Tag);
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJZ operation, RegisterID regOp1Tag, RegisterID regOp1Payload, int32_t op2)
 {
     setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, TrustedImm32(op2));
@@ -578,14 +690,14 @@ ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&
 
 ALWAYS_INLINE void JIT::addSlowCase(Jump jump)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
 
     m_slowCases.append(SlowCaseEntry(jump, m_bytecodeOffset));
 }
 
 ALWAYS_INLINE void JIT::addSlowCase(JumpList jumpList)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
 
     const JumpList::JumpVector& jumpVector = jumpList.jumps();
     size_t size = jumpVector.size();
@@ -595,7 +707,7 @@ ALWAYS_INLINE void JIT::addSlowCase(JumpList jumpList)
 
 ALWAYS_INLINE void JIT::addSlowCase()
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
     
     Jump emptyJump; // Doing it this way to make Windows happy.
     m_slowCases.append(SlowCaseEntry(emptyJump, m_bytecodeOffset));
@@ -603,18 +715,23 @@ ALWAYS_INLINE void JIT::addSlowCase()
 
 ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
 
     m_jmpTable.append(JumpTable(jump, m_bytecodeOffset + relativeOffset));
 }
 
 ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
 
     jump.linkTo(m_labels[m_bytecodeOffset + relativeOffset], this);
 }
 
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfCellObject(RegisterID cellReg)
+{
+    return branch8(AboveOrEqual, Address(cellReg, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
+}
+
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfCellNotObject(RegisterID cellReg)
 {
     return branch8(Below, Address(cellReg, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
@@ -943,7 +1060,7 @@ ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(int op1, int op2, int& op
 // get arg puts an arg from the SF register array into a h/w register
 ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
 {
-    ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
+    ASSERT(m_bytecodeOffset != std::numeric_limits<unsigned>::max()); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
 
     // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
     if (m_codeBlock->isConstantRegisterIndex(src)) {
index 25a843fcbade8e0dcf41b3b5285ad84da89c500e..0813b1555c83dabab5a0843aff9ea46998b2f439 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
  *
  * Redistribution and use in source and binary forms, with or without
 #if ENABLE(JIT)
 #include "JIT.h"
 
-#include "Arguments.h"
+#include "BasicBlockLocation.h"
 #include "CopiedSpaceInlines.h"
 #include "Debugger.h"
+#include "Exception.h"
 #include "Heap.h"
 #include "JITInlines.h"
 #include "JSArray.h"
 #include "JSCell.h"
 #include "JSFunction.h"
-#include "JSPropertyNameIterator.h"
+#include "JSNameScope.h"
+#include "JSPropertyNameEnumerator.h"
+#include "LinkBuffer.h"
 #include "MaxFrameExtentForSlowPathCall.h"
+#include "RepatchBuffer.h"
 #include "SlowPathCall.h"
+#include "TypeLocation.h"
+#include "TypeProfilerLog.h"
 #include "VirtualRegister.h"
 
 namespace JSC {
@@ -59,15 +65,6 @@ void JIT::emit_op_mov(Instruction* currentInstruction)
     emitPutVirtualRegister(dst);
 }
 
-void JIT::emit_op_captured_mov(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int src = currentInstruction[2].u.operand;
-
-    emitGetVirtualRegister(src, regT0);
-    emitNotifyWrite(regT0, regT1, currentInstruction[3].u.watchpointSet);
-    emitPutVirtualRegister(dst);
-}
 
 void JIT::emit_op_end(Instruction* currentInstruction)
 {
@@ -229,42 +226,26 @@ void JIT::emit_op_is_string(Instruction* currentInstruction)
     emitPutVirtualRegister(dst);
 }
 
-void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
-{
-    int activation = currentInstruction[1].u.operand;
-    Jump activationNotCreated = branchTest64(Zero, addressFor(activation));
-    emitGetVirtualRegister(activation, regT0);
-    callOperation(operationTearOffActivation, regT0);
-    activationNotCreated.link(this);
-}
-
-void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
+void JIT::emit_op_is_object(Instruction* currentInstruction)
 {
-    int arguments = currentInstruction[1].u.operand;
-    int activation = currentInstruction[2].u.operand;
+    int dst = currentInstruction[1].u.operand;
+    int value = currentInstruction[2].u.operand;
 
-    Jump argsNotCreated = branchTest64(Zero, Address(callFrameRegister, sizeof(Register) * (unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset())));
-    emitGetVirtualRegister(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), regT0);
-    emitGetVirtualRegister(activation, regT1);
-    callOperation(operationTearOffArguments, regT0, regT1);
-    argsNotCreated.link(this);
-}
+    emitGetVirtualRegister(value, regT0);
+    Jump isNotCell = emitJumpIfNotJSCell(regT0);
 
-void JIT::emit_op_ret(Instruction* currentInstruction)
-{
-    ASSERT(callFrameRegister != regT1);
-    ASSERT(regT1 != returnValueGPR);
-    ASSERT(returnValueGPR != callFrameRegister);
+    compare8(AboveOrEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType), regT0);
+    emitTagAsBoolImmediate(regT0);
+    Jump done = jump();
 
-    // Return the result in %eax.
-    emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueGPR);
+    isNotCell.link(this);
+    move(TrustedImm32(ValueFalse), regT0);
 
-    checkStackPointerAlignment();
-    emitFunctionEpilogue();
-    ret();
+    done.link(this);
+    emitPutVirtualRegister(dst);
 }
 
-void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
+void JIT::emit_op_ret(Instruction* currentInstruction)
 {
     ASSERT(callFrameRegister != regT1);
     ASSERT(regT1 != returnValueGPR);
@@ -272,19 +253,8 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
 
     // Return the result in %eax.
     emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueGPR);
-    Jump notJSCell = emitJumpIfNotJSCell(returnValueGPR);
-    Jump notObject = emitJumpIfCellNotObject(returnValueGPR);
-
-    // Return.
-    emitFunctionEpilogue();
-    ret();
 
-    // Return 'this' in %eax.
-    notJSCell.link(this);
-    notObject.link(this);
-    emitGetVirtualRegister(currentInstruction[2].u.operand, returnValueGPR);
-
-    // Return.
+    checkStackPointerAlignment();
     emitFunctionEpilogue();
     ret();
 }
@@ -297,9 +267,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
     emitGetVirtualRegister(src, regT0);
     
     Jump isImm = emitJumpIfNotJSCell(regT0);
-    addSlowCase(branchStructure(NotEqual, 
-        Address(regT0, JSCell::structureIDOffset()), 
-        m_vm->stringStructure.get()));
+    addSlowCase(emitJumpIfCellObject(regT0));
     isImm.link(this);
 
     if (dst != src)
@@ -456,115 +424,18 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
     jumpToExceptionHandler();
 }
 
-void JIT::emit_op_get_pnames(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int breakTarget = currentInstruction[5].u.operand;
-
-    JumpList isNotObject;
-
-    emitGetVirtualRegister(base, regT0);
-    if (!m_codeBlock->isKnownNotImmediate(base))
-        isNotObject.append(emitJumpIfNotJSCell(regT0));
-    if (base != m_codeBlock->thisRegister().offset() || m_codeBlock->isStrictMode())
-        isNotObject.append(emitJumpIfCellNotObject(regT0));
-
-    // We could inline the case where you have a valid cache, but
-    // this call doesn't seem to be hot.
-    Label isObject(this);
-    callOperation(operationGetPNames, regT0);
-    emitStoreCell(dst, returnValueGPR);
-    load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
-    store64(tagTypeNumberRegister, addressFor(i));
-    store32(TrustedImm32(Int32Tag), intTagFor(size));
-    store32(regT3, intPayloadFor(size));
-    Jump end = jump();
-
-    isNotObject.link(this);
-    move(regT0, regT1);
-    and32(TrustedImm32(~TagBitUndefined), regT1);
-    addJump(branch32(Equal, regT1, TrustedImm32(ValueNull)), breakTarget);
-    callOperation(operationToObject, base, regT0);
-    jump().linkTo(isObject, this);
-    
-    end.link(this);
-}
-
-void JIT::emit_op_next_pname(Instruction* currentInstruction)
+void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int it = currentInstruction[5].u.operand;
-    int target = currentInstruction[6].u.operand;
-    
-    JumpList callHasProperty;
-
-    Label begin(this);
-    load32(intPayloadFor(i), regT0);
-    Jump end = branch32(Equal, regT0, intPayloadFor(size));
-
-    // Grab key @ i
-    loadPtr(addressFor(it), regT1);
-    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
-
-    load64(BaseIndex(regT2, regT0, TimesEight), regT2);
-
-    emitPutVirtualRegister(dst, regT2);
-
-    // Increment i
-    add32(TrustedImm32(1), regT0);
-    store32(regT0, intPayloadFor(i));
-
-    // Verify that i is valid:
-    emitGetVirtualRegister(base, regT0);
-
-    // Test base's structure
-    emitLoadStructure(regT0, regT2, regT3);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
-
-    // Test base's prototype chain
-    loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
-    loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
-    addJump(branchTestPtr(Zero, Address(regT3)), target);
-
-    Label checkPrototype(this);
-    load64(Address(regT2, Structure::prototypeOffset()), regT2);
-    callHasProperty.append(emitJumpIfNotJSCell(regT2));
-    emitLoadStructure(regT2, regT2, regT1);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
-    addPtr(TrustedImm32(sizeof(Structure*)), regT3);
-    branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
-
-    // Continue loop.
-    addJump(jump(), target);
-
-    // Slow case: Ask the object if i is valid.
-    callHasProperty.link(this);
-    emitGetVirtualRegister(dst, regT1);
-    callOperation(operationHasProperty, regT0, regT1);
-
-    // Test for valid key.
-    addJump(branchTest32(NonZero, regT0), target);
-    jump().linkTo(begin, this);
-
-    // End of loop.
-    end.link(this);
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    callOperation(operationPushWithScope, dst, regT0);
 }
 
-void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
+void JIT::emit_op_pop_scope(Instruction* currentInstruction)
 {
-    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
-    callOperation(operationPushWithScope, regT0);
-}
+    int scope = currentInstruction[1].u.operand;
 
-void JIT::emit_op_pop_scope(Instruction*)
-{
-    callOperation(operationPopScope);
+    callOperation(operationPopScope, scope);
 }
 
 void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type)
@@ -618,10 +489,28 @@ void JIT::emit_op_to_number(Instruction* currentInstruction)
     emitPutVirtualRegister(currentInstruction[1].u.operand);
 }
 
+void JIT::emit_op_to_string(Instruction* currentInstruction)
+{
+    int srcVReg = currentInstruction[2].u.operand;
+    emitGetVirtualRegister(srcVReg, regT0);
+
+    addSlowCase(emitJumpIfNotJSCell(regT0));
+    addSlowCase(branch8(NotEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
+
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
+    int dst = currentInstruction[1].u.operand;
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
-    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT0, currentInstruction[3].u.operand);
+    if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
+        callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
+        return;
+    }
+
+    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
+    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
@@ -633,12 +522,17 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
     
     move(TrustedImmPtr(m_vm), regT3);
     load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
+    load64(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store64(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
 
     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
 
     load64(Address(regT3, VM::exceptionOffset()), regT0);
     store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, VM::exceptionOffset()));
     emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+    load64(Address(regT0, Exception::valueOffset()), regT0);
+    emitPutVirtualRegister(currentInstruction[2].u.operand);
 }
 
 void JIT::emit_op_switch_imm(Instruction* currentInstruction)
@@ -779,34 +673,23 @@ void JIT::emit_op_enter(Instruction*)
     emitEnterOptimizationCheck();
 }
 
-void JIT::emit_op_create_activation(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    
-    Jump activationCreated = branchTest64(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
-    callOperation(operationCreateActivation, 0);
-    emitStoreCell(dst, returnValueGPR);
-    activationCreated.link(this);
-}
-
-void JIT::emit_op_create_arguments(Instruction* currentInstruction)
+void JIT::emit_op_create_lexical_environment(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
+    int scope = currentInstruction[2].u.operand;
 
-    Jump argsCreated = branchTest64(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
-
-    callOperation(operationCreateArguments);
+    emitGetVirtualRegister(scope, regT0);
+    callOperation(operationCreateActivation, regT0);
     emitStoreCell(dst, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)), returnValueGPR);
-
-    argsCreated.link(this);
+    emitStoreCell(scope, returnValueGPR);
 }
 
-void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
+void JIT::emit_op_get_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-
-    store64(TrustedImm64((int64_t)0), Address(callFrameRegister, sizeof(Register) * dst));
+    emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);
+    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT0);
+    emitStoreCell(dst, regT0);
 }
 
 void JIT::emit_op_to_this(Instruction* currentInstruction)
@@ -823,53 +706,58 @@ void JIT::emit_op_to_this(Instruction* currentInstruction)
     addSlowCase(branch32(NotEqual, Address(regT1, JSCell::structureIDOffset()), regT2));
 }
 
-void JIT::emit_op_get_callee(Instruction* currentInstruction)
-{
-    int result = currentInstruction[1].u.operand;
-    WriteBarrierBase<JSCell>* cachedFunction = &currentInstruction[2].u.jsCell;
-    emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);
-
-    loadPtr(cachedFunction, regT2);
-    addSlowCase(branchPtr(NotEqual, regT0, regT2));
-
-    emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_get_callee(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_callee);
-    slowPathCall.call();
-}
-
 void JIT::emit_op_create_this(Instruction* currentInstruction)
 {
     int callee = currentInstruction[2].u.operand;
+    WriteBarrierBase<JSCell>* cachedFunction = &currentInstruction[4].u.jsCell;
     RegisterID calleeReg = regT0;
+    RegisterID rareDataReg = regT4;
     RegisterID resultReg = regT0;
     RegisterID allocatorReg = regT1;
     RegisterID structureReg = regT2;
+    RegisterID cachedFunctionReg = regT4;
     RegisterID scratchReg = regT3;
 
     emitGetVirtualRegister(callee, calleeReg);
-    loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
-    loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
+    loadPtr(Address(calleeReg, JSFunction::offsetOfRareData()), rareDataReg);
+    addSlowCase(branchTestPtr(Zero, rareDataReg));
+    loadPtr(Address(rareDataReg, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
+    loadPtr(Address(rareDataReg, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
     addSlowCase(branchTestPtr(Zero, allocatorReg));
 
+    loadPtr(cachedFunction, cachedFunctionReg);
+    Jump hasSeenMultipleCallees = branchPtr(Equal, cachedFunctionReg, TrustedImmPtr(JSCell::seenMultipleCalleeObjects()));
+    addSlowCase(branchPtr(NotEqual, calleeReg, cachedFunctionReg));
+    hasSeenMultipleCallees.link(this);
+
     emitAllocateJSObject(allocatorReg, structureReg, resultReg, scratchReg);
     emitPutVirtualRegister(currentInstruction[1].u.operand);
 }
 
 void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    linkSlowCase(iter); // doesn't have rare data
     linkSlowCase(iter); // doesn't have an allocation profile
     linkSlowCase(iter); // allocation failed
+    linkSlowCase(iter); // cached function didn't match
 
     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_this);
     slowPathCall.call();
 }
 
+void JIT::emit_op_check_tdz(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+    addSlowCase(branchTest64(Zero, regT0));
+}
+
+void JIT::emitSlow_op_check_tdz(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_tdz_error);
+    slowPathCall.call();
+}
+
 void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
 {
     Jump profilerDone = branchTestPtr(Zero, AbsoluteAddress(m_vm->enabledProfilerAddress()));
@@ -1016,76 +904,17 @@ void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCase
     slowPathCall.call();
 }
 
-void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
-    emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
-    sub32(TrustedImm32(1), regT0);
-    emitFastArithReTagImmediate(regT0, regT0);
-    emitPutVirtualRegister(dst, regT0);
-}
-
-void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    callOperation(operationGetArgumentsLength, dst, base);
-}
-
-void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+void JIT::emitSlow_op_to_string(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
-    emitGetVirtualRegister(property, regT1);
-    addSlowCase(emitJumpIfNotImmediateInteger(regT1));
-    add32(TrustedImm32(1), regT1);
-    // regT1 now contains the integer index of the argument we want, including this
-    emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT2);
-    addSlowCase(branch32(AboveOrEqual, regT1, regT2));
-
-    signExtend32ToPtr(regT1, regT1);
-    load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
-    emitValueProfilingSite();
-    emitPutVirtualRegister(dst, regT0);
-}
+    linkSlowCase(iter); // Not JSCell.
+    linkSlowCase(iter); // Not JSString.
 
-void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int dst = currentInstruction[1].u.operand;
-    int arguments = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    
-    linkSlowCase(iter);
-    Jump skipArgumentsCreation = jump();
-    
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-    callOperation(operationCreateArguments);
-    emitStoreCell(arguments, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)), returnValueGPR);
-    
-    skipArgumentsCreation.link(this);
-    emitGetVirtualRegister(arguments, regT0);
-    emitGetVirtualRegister(property, regT1);
-    callOperation(WithProfile, operationGetByValGeneric, dst, regT0, regT1);
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_string);
+    slowPathCall.call();
 }
 
 #endif // USE(JSVALUE64)
 
-void JIT::emit_op_touch_entry(Instruction* currentInstruction)
-{
-    if (m_codeBlock->symbolTable()->m_functionEnteredOnce.hasBeenInvalidated())
-        return;
-    
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_touch_entry);
-    slowPathCall.call();
-}
-
 void JIT::emit_op_loop_hint(Instruction*)
 {
     // Emit the JIT optimization check: 
@@ -1139,32 +968,36 @@ void JIT::emit_op_new_func(Instruction* currentInstruction)
 {
     Jump lazyJump;
     int dst = currentInstruction[1].u.operand;
-    if (currentInstruction[3].u.operand) {
-#if USE(JSVALUE32_64)
-        lazyJump = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
+
+#if USE(JSVALUE64)
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
 #else
-        lazyJump = branchTest64(NonZero, addressFor(dst));
+    emitLoadPayload(currentInstruction[2].u.operand, regT0);
 #endif
-    }
-
-    FunctionExecutable* funcExec = m_codeBlock->functionDecl(currentInstruction[2].u.operand);
-    callOperation(operationNewFunction, dst, funcExec);
-
-    if (currentInstruction[3].u.operand)
-        lazyJump.link(this);
-}
-
-void JIT::emit_op_new_captured_func(Instruction* currentInstruction)
-{
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_new_captured_func);
-    slowPathCall.call();
+    FunctionExecutable* funcExec = m_codeBlock->functionDecl(currentInstruction[3].u.operand);
+    callOperation(operationNewFunction, dst, regT0, funcExec);
 }
 
 void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
 {
+    Jump notUndefinedScope;
     int dst = currentInstruction[1].u.operand;
-    FunctionExecutable* funcExpr = m_codeBlock->functionExpr(currentInstruction[2].u.operand);
-    callOperation(operationNewFunction, dst, funcExpr);
+#if USE(JSVALUE64)
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    notUndefinedScope = branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsUndefined())));
+    store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, sizeof(Register) * dst));
+#else
+    emitLoadPayload(currentInstruction[2].u.operand, regT0);
+    notUndefinedScope = branch32(NotEqual, tagFor(currentInstruction[2].u.operand), TrustedImm32(JSValue::UndefinedTag));
+    emitStore(dst, jsUndefined());
+#endif
+
+    Jump done = jump();
+    notUndefinedScope.link(this);
+
+    FunctionExecutable* funcExpr = m_codeBlock->functionExpr(currentInstruction[3].u.operand);
+    callOperation(operationNewFunction, dst, regT0, funcExpr);
+    done.link(this);
 }
 
 void JIT::emit_op_new_array(Instruction* currentInstruction)
@@ -1201,16 +1034,330 @@ void JIT::emit_op_new_array_buffer(Instruction* currentInstruction)
     callOperation(operationNewArrayBufferWithProfile, dst, currentInstruction[4].u.arrayAllocationProfile, values, size);
 }
 
-void JIT::emitSlow_op_captured_mov(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+#if USE(JSVALUE64)
+void JIT::emit_op_has_structure_property(Instruction* currentInstruction)
 {
-    VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet;
-    if (!set || set->state() == IsInvalidated)
-        return;
-#if USE(JSVALUE32_64)
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int enumerator = currentInstruction[4].u.operand;
+
+    emitGetVirtualRegister(base, regT0);
+    emitGetVirtualRegister(enumerator, regT1);
+    emitJumpSlowCaseIfNotJSCell(regT0, base);
+
+    load32(Address(regT0, JSCell::structureIDOffset()), regT0);
+    addSlowCase(branch32(NotEqual, regT0, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset())));
+    
+    move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0);
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::privateCompileHasIndexedProperty(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
+{
+    Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex;
+    
+    PatchableJump badType;
+    
+    // FIXME: Add support for other types like TypedArrays and Arguments.
+    // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034.
+    JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType);
+    move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0);
+    Jump done = jump();
+
+    LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock);
+    
+    patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
+    patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
+    
+    patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone));
+    
+    byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB(
+        m_codeBlock, patchBuffer,
+        ("Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.value()));
+    
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code()));
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(operationHasIndexedPropertyGeneric));
+}
+
+void JIT::emit_op_has_indexed_property(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int property = currentInstruction[3].u.operand;
+    ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
+    
+    emitGetVirtualRegisters(base, regT0, property, regT1);
+
+    // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
+    // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if
+    // number was signed since m_vectorLength is always less than intmax (since the total allocation
+    // size is always less than 4Gb). As such zero extending will have been correct (and extending the value
+    // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
+    // extending since it makes it easier to re-tag the value in the slow case.
+    zeroExtend32ToPtr(regT1, regT1);
+
+    emitJumpSlowCaseIfNotJSCell(regT0, base);
+    emitArrayProfilingSiteWithCell(regT0, regT2, profile);
+    and32(TrustedImm32(IndexingShapeMask), regT2);
+
+    JITArrayMode mode = chooseArrayMode(profile);
+    PatchableJump badType;
+
+    // FIXME: Add support for other types like TypedArrays and Arguments.
+    // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034.
+    JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType);
+    
+    move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0);
+
+    addSlowCase(badType);
+    addSlowCase(slowCases);
+    
+    Label done = label();
+    
+    emitPutVirtualRegister(dst);
+    
+    m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
+}
+
+void JIT::emitSlow_op_has_indexed_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int property = currentInstruction[3].u.operand;
+    ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
+    
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+    linkSlowCase(iter); // base array check
+    linkSlowCase(iter); // vector length check
+    linkSlowCase(iter); // empty value
+    
+    Label slowPath = label();
+    
+    emitGetVirtualRegister(base, regT0);
+    emitGetVirtualRegister(property, regT1);
+    Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT0, regT1, profile);
+
+    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
+    m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
+    m_byValInstructionIndex++;
+}
+
+void JIT::emit_op_get_direct_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int index = currentInstruction[4].u.operand;
+    int enumerator = currentInstruction[5].u.operand;
+
+    // Check that base is a cell
+    emitGetVirtualRegister(base, regT0);
+    emitJumpSlowCaseIfNotJSCell(regT0, base);
+
+    // Check the structure
+    emitGetVirtualRegister(enumerator, regT2);
+    load32(Address(regT0, JSCell::structureIDOffset()), regT1);
+    addSlowCase(branch32(NotEqual, regT1, Address(regT2, JSPropertyNameEnumerator::cachedStructureIDOffset())));
+
+    // Compute the offset
+    emitGetVirtualRegister(index, regT1);
+    // If index is less than the enumerator's cached inline storage, then it's an inline access
+    Jump outOfLineAccess = branch32(AboveOrEqual, regT1, Address(regT2, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
+    addPtr(TrustedImm32(JSObject::offsetOfInlineStorage()), regT0);
+    signExtend32ToPtr(regT1, regT1);
+    load64(BaseIndex(regT0, regT1, TimesEight), regT0);
+    
+    Jump done = jump();
+
+    // Otherwise it's out of line
+    outOfLineAccess.link(this);
+    loadPtr(Address(regT0, JSObject::butterflyOffset()), regT0);
+    sub32(Address(regT2, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), regT1);
+    neg32(regT1);
+    signExtend32ToPtr(regT1, regT1);
+    int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
+    load64(BaseIndex(regT0, regT1, TimesEight, offsetOfFirstProperty), regT0);
+    
+    done.link(this);
+    emitValueProfilingSite();
+    emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_direct_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int base = currentInstruction[2].u.operand;
+    linkSlowCaseIfNotJSCell(iter, base);
     linkSlowCase(iter);
-#endif
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_direct_pname);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_enumerator_structure_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int enumerator = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+
+    emitGetVirtualRegister(index, regT0);
+    emitGetVirtualRegister(enumerator, regT1);
+    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()));
+
+    move(TrustedImm64(JSValue::encode(jsNull())), regT0);
+
+    Jump done = jump();
+    inBounds.link(this);
+
+    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
+    signExtend32ToPtr(regT0, regT0);
+    load64(BaseIndex(regT1, regT0, TimesEight), regT0);
+
+    done.link(this);
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emit_op_enumerator_generic_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int enumerator = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+
+    emitGetVirtualRegister(index, regT0);
+    emitGetVirtualRegister(enumerator, regT1);
+    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
+
+    move(TrustedImm64(JSValue::encode(jsNull())), regT0);
+
+    Jump done = jump();
+    inBounds.link(this);
+
+    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
+    signExtend32ToPtr(regT0, regT0);
+    load64(BaseIndex(regT1, regT0, TimesEight), regT0);
+    
+    done.link(this);
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emit_op_profile_type(Instruction* currentInstruction)
+{
+    TypeLocation* cachedTypeLocation = currentInstruction[2].u.location;
+    int valueToProfile = currentInstruction[1].u.operand;
+
+    emitGetVirtualRegister(valueToProfile, regT0);
+
+    JumpList jumpToEnd;
+
+    // Compile in a predictive type check, if possible, to see if we can skip writing to the log.
+    // These typechecks are inlined to match those of the 64-bit JSValue type checks.
+    if (cachedTypeLocation->m_lastSeenType == TypeUndefined)
+        jumpToEnd.append(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsUndefined()))));
+    else if (cachedTypeLocation->m_lastSeenType == TypeNull)
+        jumpToEnd.append(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsNull()))));
+    else if (cachedTypeLocation->m_lastSeenType == TypeBoolean) {
+        move(regT0, regT1);
+        and64(TrustedImm32(~1), regT1);
+        jumpToEnd.append(branch64(Equal, regT1, TrustedImm64(ValueFalse)));
+    } else if (cachedTypeLocation->m_lastSeenType == TypeMachineInt)
+        jumpToEnd.append(emitJumpIfImmediateInteger(regT0));
+    else if (cachedTypeLocation->m_lastSeenType == TypeNumber)
+        jumpToEnd.append(emitJumpIfImmediateNumber(regT0));
+    else if (cachedTypeLocation->m_lastSeenType == TypeString) {
+        Jump isNotCell = emitJumpIfNotJSCell(regT0);
+        jumpToEnd.append(branch8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
+        isNotCell.link(this);
+    }
+
+    // Load the type profiling log into T2.
+    TypeProfilerLog* cachedTypeProfilerLog = m_vm->typeProfilerLog();
+    move(TrustedImmPtr(cachedTypeProfilerLog), regT2);
+    // Load the next log entry into T1.
+    loadPtr(Address(regT2, TypeProfilerLog::currentLogEntryOffset()), regT1);
+
+    // Store the JSValue onto the log entry.
+    store64(regT0, Address(regT1, TypeProfilerLog::LogEntry::valueOffset()));
+
+    // Store the structureID of the cell if T0 is a cell, otherwise, store 0 on the log entry.
+    Jump notCell = emitJumpIfNotJSCell(regT0);
+    load32(Address(regT0, JSCell::structureIDOffset()), regT0);
+    store32(regT0, Address(regT1, TypeProfilerLog::LogEntry::structureIDOffset()));
+    Jump skipIsCell = jump();
+    notCell.link(this);
+    store32(TrustedImm32(0), Address(regT1, TypeProfilerLog::LogEntry::structureIDOffset()));
+    skipIsCell.link(this);
+
+    // Store the typeLocation on the log entry.
+    move(TrustedImmPtr(cachedTypeLocation), regT0);
+    store64(regT0, Address(regT1, TypeProfilerLog::LogEntry::locationOffset()));
+
+    // Increment the current log entry.
+    addPtr(TrustedImm32(sizeof(TypeProfilerLog::LogEntry)), regT1);
+    store64(regT1, Address(regT2, TypeProfilerLog::currentLogEntryOffset()));
+    Jump skipClearLog = branchPtr(NotEqual, regT1, TrustedImmPtr(cachedTypeProfilerLog->logEndPtr()));
+    // Clear the log if we're at the end of the log.
+    callOperation(operationProcessTypeProfilerLog);
+    skipClearLog.link(this);
+
+    jumpToEnd.link(this);
+}
+
+#endif // USE(JSVALUE64)
+
+void JIT::emit_op_get_enumerable_length(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_enumerable_length);
+    slowPathCall.call();
+}
+
+void JIT::emitSlow_op_has_structure_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
     linkSlowCase(iter);
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_captured_mov);
+    linkSlowCase(iter);
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_structure_property);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_has_generic_property(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_generic_property);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_get_property_enumerator(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_property_enumerator);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_to_index_string(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_index_string);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_profile_control_flow(Instruction* currentInstruction)
+{
+    BasicBlockLocation* basicBlockLocation = currentInstruction[1].u.basicBlockLocation;
+    if (!basicBlockLocation->hasExecuted())
+        basicBlockLocation->emitExecuteCode(*this, regT1);
+}
+
+void JIT::emit_op_create_direct_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_direct_arguments);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_create_scoped_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_scoped_arguments);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_create_out_of_band_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_out_of_band_arguments);
     slowPathCall.call();
 }
 
index a540d6e8a89c668ec3421d5faff0759af292c648..8764cc2ccaa1fc00e5b5500a4ff025b4f44b534c 100644 (file)
 
 #include "CCallHelpers.h"
 #include "Debugger.h"
+#include "Exception.h"
 #include "JITInlines.h"
 #include "JSArray.h"
 #include "JSCell.h"
+#include "JSEnvironmentRecord.h"
 #include "JSFunction.h"
-#include "JSPropertyNameIterator.h"
-#include "JSVariableObject.h"
+#include "JSNameScope.h"
+#include "JSPropertyNameEnumerator.h"
 #include "LinkBuffer.h"
 #include "MaxFrameExtentForSlowPathCall.h"
+#include "RepatchBuffer.h"
 #include "SlowPathCall.h"
+#include "TypeProfilerLog.h"
 #include "VirtualRegister.h"
 
 namespace JSC {
@@ -54,12 +58,6 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
     storePtr(callFrameRegister, &m_vm->topCallFrame);
 
 #if CPU(X86)
-    // Load caller frame's scope chain into this callframe so that whatever we call can
-    // get to its global data.
-    emitGetCallerFrameFromCallFrameHeaderPtr(regT0);
-    emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
-    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
     // Calling convention:      f(ecx, edx, ...);
     // Host function signature: f(ExecState*);
     move(callFrameRegister, X86Registers::ecx);
@@ -73,11 +71,6 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
     addPtr(TrustedImm32(8), stackPointerRegister);
 
 #elif CPU(ARM) || CPU(SH4) || CPU(MIPS)
-    // Load caller frame's scope chain into this callframe so that whatever we call can get to its global data.
-    emitGetCallerFrameFromCallFrameHeaderPtr(regT2);
-    emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2);
-    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
 #if CPU(MIPS)
     // Allocate stack space for (unused) 16 bytes (8-byte aligned) for 4 arguments.
     subPtr(TrustedImm32(16), stackPointerRegister);
@@ -105,7 +98,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
 #endif // CPU(X86)
 
     // Check for an exception
-    Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(vm->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); 
+    Jump sawException = branch32(NotEqual, AbsoluteAddress(vm->addressOfException()), TrustedImm32(0));
 
     emitFunctionEpilogue();
     // Return.
@@ -152,16 +145,6 @@ void JIT::emit_op_mov(Instruction* currentInstruction)
     }
 }
 
-void JIT::emit_op_captured_mov(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int src = currentInstruction[2].u.operand;
-
-    emitLoad(src, regT1, regT0);
-    emitNotifyWrite(regT1, regT0, regT2, currentInstruction[3].u.watchpointSet);
-    emitStore(dst, regT1, regT0);
-}
-
 void JIT::emit_op_end(Instruction* currentInstruction)
 {
     ASSERT(returnValueGPR != callFrameRegister);
@@ -349,25 +332,22 @@ void JIT::emit_op_is_string(Instruction* currentInstruction)
     emitStoreBool(dst, regT0);
 }
 
-void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
+void JIT::emit_op_is_object(Instruction* currentInstruction)
 {
-    int activation = currentInstruction[1].u.operand;
-    Jump activationNotCreated = branch32(Equal, tagFor(activation), TrustedImm32(JSValue::EmptyValueTag));
-    emitLoadPayload(activation, regT0);
-    callOperation(operationTearOffActivation, regT0);
-    activationNotCreated.link(this);
-}
+    int dst = currentInstruction[1].u.operand;
+    int value = currentInstruction[2].u.operand;
 
-void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
-{
-    VirtualRegister arguments = VirtualRegister(currentInstruction[1].u.operand);
-    int activation = currentInstruction[2].u.operand;
+    emitLoad(value, regT1, regT0);
+    Jump isNotCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+
+    compare8(AboveOrEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType), regT0);
+    Jump done = jump();
+
+    isNotCell.link(this);
+    move(TrustedImm32(0), regT0);
 
-    Jump argsNotCreated = branch32(Equal, tagFor(unmodifiedArgumentsRegister(arguments).offset()), TrustedImm32(JSValue::EmptyValueTag));
-    emitLoadPayload(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), regT0);
-    emitLoadPayload(activation, regT1);
-    callOperation(operationTearOffArguments, regT0, regT1);
-    argsNotCreated.link(this);
+    done.link(this);
+    emitStoreBool(dst, regT0);
 }
 
 void JIT::emit_op_to_primitive(Instruction* currentInstruction)
@@ -378,7 +358,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
     emitLoad(src, regT1, regT0);
 
     Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+    addSlowCase(emitJumpIfCellObject(regT0));
     isImm.link(this);
 
     if (dst != src)
@@ -651,12 +631,12 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
     addSlowCase(branch32(NotEqual, regT1, regT3));
     addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
 
-    // Jump to a slow case if both are strings.
+    // Jump to a slow case if both are strings or symbols (non object).
     Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
-    Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get()));
-    addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+    Jump firstIsObject = emitJumpIfCellObject(regT0);
+    addSlowCase(emitJumpIfCellNotObject(regT2));
     notCell.link(this);
-    firstNotString.link(this);
+    firstIsObject.link(this);
 
     // Simply compare the payloads.
     if (type == OpStrictEq)
@@ -767,143 +747,76 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
     jumpToExceptionHandler();
 }
 
-void JIT::emit_op_get_pnames(Instruction* currentInstruction)
+void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int breakTarget = currentInstruction[5].u.operand;
-
-    JumpList isNotObject;
-
-    emitLoad(base, regT1, regT0);
-    if (!m_codeBlock->isKnownNotImmediate(base))
-        isNotObject.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
-    if (VirtualRegister(base) != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode())
-        isNotObject.append(emitJumpIfCellNotObject(regT0));
-
-    // We could inline the case where you have a valid cache, but
-    // this call doesn't seem to be hot.
-    Label isObject(this);
-    callOperation(operationGetPNames, regT0);
-    emitStoreCell(dst, returnValueGPR);
-    load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
-    store32(TrustedImm32(Int32Tag), intTagFor(i));
-    store32(TrustedImm32(0), intPayloadFor(i));
-    store32(TrustedImm32(Int32Tag), intTagFor(size));
-    store32(regT3, payloadFor(size));
-    Jump end = jump();
-
-    isNotObject.link(this);
-    addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), breakTarget);
-    addJump(branch32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag)), breakTarget);
-    callOperation(operationToObject, base, regT1, regT0);
-    jump().linkTo(isObject, this);
+    emitLoad(currentInstruction[2].u.operand, regT1, regT0);
+    callOperation(operationPushWithScope, dst, regT1, regT0);
+}
 
-    end.link(this);
+void JIT::emit_op_pop_scope(Instruction* currentInstruction)
+{
+    int scope = currentInstruction[1].u.operand;
+    callOperation(operationPopScope, scope);
 }
 
-void JIT::emit_op_next_pname(Instruction* currentInstruction)
+void JIT::emit_op_to_number(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int it = currentInstruction[5].u.operand;
-    int target = currentInstruction[6].u.operand;
-
-    JumpList callHasProperty;
-
-    Label begin(this);
-    load32(intPayloadFor(i), regT0);
-    Jump end = branch32(Equal, regT0, intPayloadFor(size));
-
-    // Grab key @ i
-    loadPtr(payloadFor(it), regT1);
-    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
-    load32(BaseIndex(regT2, regT0, TimesEight), regT2);
-    store32(TrustedImm32(JSValue::CellTag), tagFor(dst));
-    store32(regT2, payloadFor(dst));
-
-    // Increment i
-    add32(TrustedImm32(1), regT0);
-    store32(regT0, intPayloadFor(i));
-
-    // Verify that i is valid:
-    loadPtr(payloadFor(base), regT0);
-
-    // Test base's structure
-    loadPtr(Address(regT0, JSCell::structureIDOffset()), regT2);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
-
-    // Test base's prototype chain
-    loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
-    loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
-    addJump(branchTestPtr(Zero, Address(regT3)), target);
-
-    Label checkPrototype(this);
-    callHasProperty.append(branch32(Equal, Address(regT2, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::NullTag)));
-    loadPtr(Address(regT2, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
-    loadPtr(Address(regT2, JSCell::structureIDOffset()), regT2);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
-    addPtr(TrustedImm32(sizeof(Structure*)), regT3);
-    branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
-
-    // Continue loop.
-    addJump(jump(), target);
+    int src = currentInstruction[2].u.operand;
 
-    // Slow case: Ask the object if i is valid.
-    callHasProperty.link(this);
-    loadPtr(addressFor(dst), regT1);
-    callOperation(operationHasProperty, regT0, regT1);
+    emitLoad(src, regT1, regT0);
 
-    // Test for valid key.
-    addJump(branchTest32(NonZero, regT0), target);
-    jump().linkTo(begin, this);
+    Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
+    addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
+    isInt32.link(this);
 
-    // End of loop.
-    end.link(this);
+    if (src != dst)
+        emitStore(dst, regT1, regT0);
 }
 
-void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
+void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
-    emitLoad(currentInstruction[1].u.operand, regT1, regT0);
-    callOperation(operationPushWithScope, regT1, regT0);
-}
+    linkSlowCase(iter);
 
-void JIT::emit_op_pop_scope(Instruction*)
-{
-    callOperation(operationPopScope);
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_number);
+    slowPathCall.call();
 }
 
-void JIT::emit_op_to_number(Instruction* currentInstruction)
+void JIT::emit_op_to_string(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
     int src = currentInstruction[2].u.operand;
 
     emitLoad(src, regT1, regT0);
 
-    Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
-    addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
-    isInt32.link(this);
+    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
+    addSlowCase(branch8(NotEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
 
     if (src != dst)
         emitStore(dst, regT1, regT0);
 }
 
-void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_to_string(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
-    linkSlowCase(iter);
+    linkSlowCase(iter); // Not JSCell.
+    linkSlowCase(iter); // Not JSString.
 
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_number);
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_string);
     slowPathCall.call();
 }
 
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
+    int dst = currentInstruction[1].u.operand;
     emitLoad(currentInstruction[2].u.operand, regT1, regT0);
-    callOperation(operationPushNameScope, &m_codeBlock->identifier(currentInstruction[1].u.operand), regT1, regT0, currentInstruction[3].u.operand);
+    if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
+        callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
+        return;
+    }
+
+    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
+    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
@@ -911,17 +824,25 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
     move(TrustedImmPtr(m_vm), regT3);
     // operationThrow returns the callFrame for the handler.
     load32(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
+    load32(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store32(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
 
     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
 
     // Now store the exception returned by operationThrow.
-    load32(Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
-    load32(Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
-    store32(TrustedImm32(JSValue().payload()), Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
-    store32(TrustedImm32(JSValue().tag()), Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+    load32(Address(regT3, VM::exceptionOffset()), regT2);
+    move(TrustedImm32(JSValue::CellTag), regT1);
+
+    store32(TrustedImm32(0), Address(regT3, VM::exceptionOffset()));
 
     unsigned exception = currentInstruction[1].u.operand;
-    emitStore(exception, regT1, regT0);
+    emitStore(exception, regT1, regT2);
+
+    load32(Address(regT2, Exception::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+    load32(Address(regT2, Exception::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+
+    unsigned thrownValue = currentInstruction[2].u.operand;
+    emitStore(thrownValue, regT1, regT0);
 }
 
 void JIT::emit_op_switch_imm(Instruction* currentInstruction)
@@ -1000,77 +921,59 @@ void JIT::emit_op_enter(Instruction* currentInstruction)
     slowPathCall.call();
 }
 
-void JIT::emit_op_create_activation(Instruction* currentInstruction)
-{
-    int activation = currentInstruction[1].u.operand;
-    
-    Jump activationCreated = branch32(NotEqual, tagFor(activation), TrustedImm32(JSValue::EmptyValueTag));
-    callOperation(operationCreateActivation, 0);
-    emitStoreCell(activation, returnValueGPR);
-    activationCreated.link(this);
-}
-
-void JIT::emit_op_create_arguments(Instruction* currentInstruction)
+void JIT::emit_op_create_lexical_environment(Instruction* currentInstruction)
 {
-    int dst = currentInstruction[1].u.operand;
+    int lexicalEnvironment = currentInstruction[1].u.operand;
+    int scope = currentInstruction[2].u.operand;
 
-    Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
-    callOperation(operationCreateArguments);
-    emitStoreCell(dst, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)).offset(), returnValueGPR);
-    argsCreated.link(this);
+    emitLoadPayload(currentInstruction[2].u.operand, regT0);
+    callOperation(operationCreateActivation, regT0);
+    emitStoreCell(lexicalEnvironment, returnValueGPR);
+    emitStoreCell(scope, returnValueGPR);
 }
 
-void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
+void JIT::emit_op_get_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-
-    emitStore(dst, JSValue());
-}
-
-void JIT::emit_op_get_callee(Instruction* currentInstruction)
-{
-    int result = currentInstruction[1].u.operand;
-    WriteBarrierBase<JSCell>* cachedFunction = &currentInstruction[2].u.jsCell;
     emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);
-
-    loadPtr(cachedFunction, regT2);
-    addSlowCase(branchPtr(NotEqual, regT0, regT2));
-
-    move(TrustedImm32(JSValue::CellTag), regT1);
-    emitStore(result, regT1, regT0);
-}
-
-void JIT::emitSlow_op_get_callee(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_callee);
-    slowPathCall.call();
+    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT0);
+    emitStoreCell(dst, regT0);
 }
 
 void JIT::emit_op_create_this(Instruction* currentInstruction)
 {
     int callee = currentInstruction[2].u.operand;
+    WriteBarrierBase<JSCell>* cachedFunction = &currentInstruction[4].u.jsCell;
     RegisterID calleeReg = regT0;
+    RegisterID rareDataReg = regT4;
     RegisterID resultReg = regT0;
     RegisterID allocatorReg = regT1;
     RegisterID structureReg = regT2;
+    RegisterID cachedFunctionReg = regT4;
     RegisterID scratchReg = regT3;
 
     emitLoadPayload(callee, calleeReg);
-    loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
-    loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
+    loadPtr(Address(calleeReg, JSFunction::offsetOfRareData()), rareDataReg);
+    addSlowCase(branchTestPtr(Zero, rareDataReg));
+    loadPtr(Address(rareDataReg, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
+    loadPtr(Address(rareDataReg, FunctionRareData::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
     addSlowCase(branchTestPtr(Zero, allocatorReg));
 
+    loadPtr(cachedFunction, cachedFunctionReg);
+    Jump hasSeenMultipleCallees = branchPtr(Equal, cachedFunctionReg, TrustedImmPtr(JSCell::seenMultipleCalleeObjects()));
+    addSlowCase(branchPtr(NotEqual, calleeReg, cachedFunctionReg));
+    hasSeenMultipleCallees.link(this);
+
     emitAllocateJSObject(allocatorReg, structureReg, resultReg, scratchReg);
     emitStoreCell(currentInstruction[1].u.operand, resultReg);
 }
 
 void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    linkSlowCase(iter); // doesn't have rare data
     linkSlowCase(iter); // doesn't have an allocation profile
     linkSlowCase(iter); // allocation failed
+    linkSlowCase(iter); // cached function didn't match
 
     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_this);
     slowPathCall.call();
@@ -1099,6 +1002,19 @@ void JIT::emitSlow_op_to_this(Instruction* currentInstruction, Vector<SlowCaseEn
     slowPathCall.call();
 }
 
+void JIT::emit_op_check_tdz(Instruction* currentInstruction)
+{
+    emitLoadTag(currentInstruction[1].u.operand, regT0);
+    addSlowCase(branch32(Equal, regT0, TrustedImm32(JSValue::EmptyValueTag)));
+}
+
+void JIT::emitSlow_op_check_tdz(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_tdz_error);
+    slowPathCall.call();
+}
+
 void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
 {
     load32(m_vm->enabledProfilerAddress(), regT0);
@@ -1117,63 +1033,276 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
     profilerDone.link(this);
 }
 
-void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
+void JIT::emit_op_has_structure_property(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
-    load32(payloadFor(JSStack::ArgumentCount), regT0);
-    sub32(TrustedImm32(1), regT0);
-    emitStoreInt32(dst, regT0);
+    int base = currentInstruction[2].u.operand;
+    int enumerator = currentInstruction[4].u.operand;
+
+    emitLoadPayload(base, regT0);
+    emitJumpSlowCaseIfNotJSCell(base);
+
+    emitLoadPayload(enumerator, regT1);
+
+    load32(Address(regT0, JSCell::structureIDOffset()), regT0);
+    addSlowCase(branch32(NotEqual, regT0, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset())));
+    
+    move(TrustedImm32(1), regT0);
+    emitStoreBool(dst, regT0);
 }
 
-void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::privateCompileHasIndexedProperty(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
+{
+    Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex;
+    
+    PatchableJump badType;
+    
+    // FIXME: Add support for other types like TypedArrays and Arguments.
+    // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034.
+    JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType);
+    move(TrustedImm32(1), regT0);
+    Jump done = jump();
+
+    LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock);
+    
+    patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
+    patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
+    
+    patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone));
+    
+    byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB(
+        m_codeBlock, patchBuffer,
+        ("Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.value()));
+    
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code()));
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(operationHasIndexedPropertyGeneric));
+}
+
+void JIT::emit_op_has_indexed_property(Instruction* currentInstruction)
 {
-    linkSlowCase(iter);
     int dst = currentInstruction[1].u.operand;
     int base = currentInstruction[2].u.operand;
-    callOperation(operationGetArgumentsLength, dst, base);
+    int property = currentInstruction[3].u.operand;
+    ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
+    
+    emitLoadPayload(base, regT0);
+    emitJumpSlowCaseIfNotJSCell(base);
+
+    emitLoadPayload(property, regT1);
+
+    // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
+    // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if
+    // number was signed since m_vectorLength is always less than intmax (since the total allocation
+    // size is always less than 4Gb). As such zero extending will have been correct (and extending the value
+    // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
+    // extending since it makes it easier to re-tag the value in the slow case.
+    zeroExtend32ToPtr(regT1, regT1);
+
+    emitArrayProfilingSiteWithCell(regT0, regT2, profile);
+    and32(TrustedImm32(IndexingShapeMask), regT2);
+
+    JITArrayMode mode = chooseArrayMode(profile);
+    PatchableJump badType;
+
+    // FIXME: Add support for other types like TypedArrays and Arguments.
+    // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034.
+    JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType);
+    move(TrustedImm32(1), regT0);
+
+    addSlowCase(badType);
+    addSlowCase(slowCases);
+    
+    Label done = label();
+    
+    emitStoreBool(dst, regT0);
+    
+    m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
 }
 
-void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+void JIT::emitSlow_op_has_indexed_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
+    int base = currentInstruction[2].u.operand;
     int property = currentInstruction[3].u.operand;
-    addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
-    emitLoad(property, regT1, regT2);
-    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-    add32(TrustedImm32(1), regT2);
-    // regT2 now contains the integer index of the argument we want, including this
-    load32(payloadFor(JSStack::ArgumentCount), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT2, regT3));
+    ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
+    
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+    linkSlowCase(iter); // base array check
+    linkSlowCase(iter); // vector length check
+    linkSlowCase(iter); // empty value
+
+    Label slowPath = label();
+    
+    emitLoad(base, regT1, regT0);
+    emitLoad(property, regT3, regT2);
+    Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT1, regT0, regT3, regT2, profile);
+
+    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
+    m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
+    m_byValInstructionIndex++;
+}
+
+void JIT::emit_op_get_direct_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int index = currentInstruction[4].u.operand;
+    int enumerator = currentInstruction[5].u.operand;
+
+    // Check that base is a cell
+    emitLoadPayload(base, regT0);
+    emitJumpSlowCaseIfNotJSCell(base);
+
+    // Check the structure
+    emitLoadPayload(enumerator, regT1);
+    load32(Address(regT0, JSCell::structureIDOffset()), regT2);
+    addSlowCase(branch32(NotEqual, regT2, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset())));
+
+    // Compute the offset
+    emitLoadPayload(index, regT2);
+    // If index is less than the enumerator's cached inline storage, then it's an inline access
+    Jump outOfLineAccess = branch32(AboveOrEqual, regT2, Address(regT1, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
+    addPtr(TrustedImm32(JSObject::offsetOfInlineStorage()), regT0);
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+    
+    Jump done = jump();
+
+    // Otherwise it's out of line
+    outOfLineAccess.link(this);
+    loadPtr(Address(regT0, JSObject::butterflyOffset()), regT0);
+    sub32(Address(regT1, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), regT2);
+    neg32(regT2);
+    int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
+    load32(BaseIndex(regT0, regT2, TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+    load32(BaseIndex(regT0, regT2, TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
     
-    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
-    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT1);
+    done.link(this);
     emitValueProfilingSite();
     emitStore(dst, regT1, regT0);
 }
 
-void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_get_direct_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int base = currentInstruction[2].u.operand;
+    linkSlowCaseIfNotJSCell(iter, base);
+    linkSlowCase(iter);
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_direct_pname);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_enumerator_structure_pname(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    int arguments = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
+    int enumerator = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
 
-    linkSlowCase(iter);
-    Jump skipArgumentsCreation = jump();
+    emitLoadPayload(index, regT0);
+    emitLoadPayload(enumerator, regT1);
+    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()));
 
-    linkSlowCase(iter);
-    linkSlowCase(iter);
+    move(TrustedImm32(JSValue::NullTag), regT2);
+    move(TrustedImm32(0), regT0);
+
+    Jump done = jump();
+    inBounds.link(this);
+
+    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
+    loadPtr(BaseIndex(regT1, regT0, timesPtr()), regT0);
+    move(TrustedImm32(JSValue::CellTag), regT2);
+
+    done.link(this);
+    emitStore(dst, regT2, regT0);
+}
+
+void JIT::emit_op_enumerator_generic_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int enumerator = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+
+    emitLoadPayload(index, regT0);
+    emitLoadPayload(enumerator, regT1);
+    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
+
+    move(TrustedImm32(JSValue::NullTag), regT2);
+    move(TrustedImm32(0), regT0);
+
+    Jump done = jump();
+    inBounds.link(this);
 
-    callOperation(operationCreateArguments);
-    emitStoreCell(arguments, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), returnValueGPR);
+    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
+    loadPtr(BaseIndex(regT1, regT0, timesPtr()), regT0);
+    move(TrustedImm32(JSValue::CellTag), regT2);
     
-    skipArgumentsCreation.link(this);
-    emitLoad(arguments, regT1, regT0);
-    emitLoad(property, regT3, regT2);
-    callOperation(WithProfile, operationGetByValGeneric, dst, regT1, regT0, regT3, regT2);
+    done.link(this);
+    emitStore(dst, regT2, regT0);
+}
+
+void JIT::emit_op_profile_type(Instruction* currentInstruction)
+{
+    TypeLocation* cachedTypeLocation = currentInstruction[2].u.location;
+    int valueToProfile = currentInstruction[1].u.operand;
+
+    // Load payload in T0. Load tag in T3.
+    emitLoadPayload(valueToProfile, regT0);
+    emitLoadTag(valueToProfile, regT3);
+
+    JumpList jumpToEnd;
+
+    // Compile in a predictive type check, if possible, to see if we can skip writing to the log.
+    // These typechecks are inlined to match those of the 32-bit JSValue type checks.
+    if (cachedTypeLocation->m_lastSeenType == TypeUndefined)
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::UndefinedTag)));
+    else if (cachedTypeLocation->m_lastSeenType == TypeNull)
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::NullTag)));
+    else if (cachedTypeLocation->m_lastSeenType == TypeBoolean)
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::BooleanTag)));
+    else if (cachedTypeLocation->m_lastSeenType == TypeMachineInt)
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::Int32Tag)));
+    else if (cachedTypeLocation->m_lastSeenType == TypeNumber) {
+        jumpToEnd.append(branch32(Below, regT3, TrustedImm32(JSValue::LowestTag)));
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::Int32Tag)));
+    } else if (cachedTypeLocation->m_lastSeenType == TypeString) {
+        Jump isNotCell = branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag));
+        jumpToEnd.append(branch8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
+        isNotCell.link(this);
+    }
+
+    // Load the type profiling log into T2.
+    TypeProfilerLog* cachedTypeProfilerLog = m_vm->typeProfilerLog();
+    move(TrustedImmPtr(cachedTypeProfilerLog), regT2);
+
+    // Load the next log entry into T1.
+    loadPtr(Address(regT2, TypeProfilerLog::currentLogEntryOffset()), regT1);
+
+    // Store the JSValue onto the log entry.
+    store32(regT0, Address(regT1, TypeProfilerLog::LogEntry::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+    store32(regT3, Address(regT1, TypeProfilerLog::LogEntry::valueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+
+    // Store the structureID of the cell if argument is a cell, otherwise, store 0 on the log entry.
+    Jump notCell = branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag));
+    load32(Address(regT0, JSCell::structureIDOffset()), regT0);
+    store32(regT0, Address(regT1, TypeProfilerLog::LogEntry::structureIDOffset()));
+    Jump skipNotCell = jump();
+    notCell.link(this);
+    store32(TrustedImm32(0), Address(regT1, TypeProfilerLog::LogEntry::structureIDOffset()));
+    skipNotCell.link(this);
+
+    // Store the typeLocation on the log entry.
+    move(TrustedImmPtr(cachedTypeLocation), regT0);
+    store32(regT0, Address(regT1, TypeProfilerLog::LogEntry::locationOffset()));
+
+    // Increment the current log entry.
+    addPtr(TrustedImm32(sizeof(TypeProfilerLog::LogEntry)), regT1);
+    store32(regT1, Address(regT2, TypeProfilerLog::currentLogEntryOffset()));
+    jumpToEnd.append(branchPtr(NotEqual, regT1, TrustedImmPtr(cachedTypeProfilerLog->logEndPtr())));
+    // Clear the log if we're at the end of the log.
+    callOperation(operationProcessTypeProfilerLog);
+
+    jumpToEnd.link(this);
 }
 
 } // namespace JSC
index 3aaef526a9b56ab4592ef778aa03fbfa91f8ed11..38015d2d804f935920f9756a71ca2fdfea179590 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
 
 #if ENABLE(JIT)
 
-#include "Arguments.h"
 #include "ArrayConstructor.h"
 #include "DFGCompilationMode.h"
 #include "DFGDriver.h"
 #include "DFGThunks.h"
 #include "DFGWorklist.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
 #include "Error.h"
 #include "ErrorHandlingScope.h"
+#include "ExceptionFuzz.h"
 #include "GetterSetter.h"
 #include "HostCallReturnValue.h"
 #include "JIT.h"
 #include "JITToDFGDeferredCompilationCallback.h"
+#include "JSCInlines.h"
+#include "JSCatchScope.h"
+#include "JSFunctionNameScope.h"
 #include "JSGlobalObjectFunctions.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
-#include "JSPropertyNameIterator.h"
+#include "JSPropertyNameEnumerator.h"
 #include "JSStackInlines.h"
 #include "JSWithScope.h"
+#include "LegacyProfiler.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
+#include "PropertyName.h"
 #include "Repatch.h"
 #include "RepatchBuffer.h"
+#include "ScopedArguments.h"
 #include "TestRunnerUtils.h"
+#include "TypeProfilerLog.h"
 #include <wtf/InlineASM.h>
 
 namespace JSC {
 
-static unsigned s_numberOfExceptionFuzzChecks;
-unsigned numberOfExceptionFuzzChecks() { return s_numberOfExceptionFuzzChecks; }
+template<typename ScopeType>
+void pushNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    
+    ASSERT(!JITCode::isOptimizingJIT(exec->codeBlock()->jitType()));
+
+    // FIXME: This won't work if this operation is called from the DFG or FTL.
+    // This should be changed to pass in the new scope.
+    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
+    JSNameScope* scope = ScopeType::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, JSValue::decode(encodedValue));
+
+    // FIXME: This won't work if this operation is called from the DFG or FTL.
+    // This should be changed to return the new scope.
+    exec->uncheckedR(dst) = scope;
+}
 
 extern "C" {
 
@@ -81,11 +104,13 @@ void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock*
 {
     // We pass in our own code block, because the callframe hasn't been populated.
     VM* vm = codeBlock->vm();
-    CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
+
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
     if (!callerFrame)
         callerFrame = exec;
 
-    NativeCallFrameTracer tracer(vm, callerFrame);
+    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
     ErrorHandlingScope errorScope(*vm);
     vm->throwException(callerFrame, createStackOverflowError(callerFrame));
 }
@@ -93,14 +118,16 @@ void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock*
 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 {
     VM* vm = &exec->vm();
-    CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
-    NativeCallFrameTracer tracer(vm, callerFrame);
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
 
     JSStack& stack = vm->interpreter->stack();
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall);
-    if (missingArgCount < 0)
+    if (missingArgCount < 0) {
+        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
         throwStackOverflowError(callerFrame);
+    }
 
     return missingArgCount;
 }
@@ -108,81 +135,94 @@ int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
 {
     VM* vm = &exec->vm();
-    CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
-    NativeCallFrameTracer tracer(vm, callerFrame);
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
 
     JSStack& stack = vm->interpreter->stack();
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct);
-    if (missingArgCount < 0)
+    if (missingArgCount < 0) {
+        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
         throwStackOverflowError(callerFrame);
+    }
 
     return missingArgCount;
 }
 
-EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo*, EncodedJSValue base, StringImpl* uid)
+EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
+{
+    VM* vm = &exec->vm();
+    NativeCallFrameTracer tracer(vm, exec);
+    
+    stubInfo->tookSlowPath = true;
+    
+    JSValue baseValue = JSValue::decode(base);
+    PropertySlot slot(baseValue);
+    Identifier ident = Identifier::fromUid(vm, uid);
+    return JSValue::encode(baseValue.get(exec, ident, slot));
+}
+
+EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState* exec, EncodedJSValue base, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
     JSValue baseValue = JSValue::decode(base);
     PropertySlot slot(baseValue);
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     return JSValue::encode(baseValue.get(exec, ident, slot));
 }
 
-EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, StringImpl* uid)
+EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue baseValue = JSValue::decode(base);
     PropertySlot slot(baseValue);
-    JSValue result = baseValue.get(exec, ident, slot);
-
+    bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
+    
     if (accessType == static_cast<AccessType>(stubInfo->accessType))
         buildGetByIDList(exec, baseValue, ident, slot, *stubInfo);
 
-    return JSValue::encode(result);
+    return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
 }
 
-EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, StringImpl* uid)
+EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
-    Identifier ident = uid->isEmptyUnique() ? Identifier::from(PrivateName(uid)) : Identifier(vm, uid);
-    AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+    Identifier ident = Identifier::fromUid(vm, uid);
 
     JSValue baseValue = JSValue::decode(base);
     PropertySlot slot(baseValue);
-    JSValue result = baseValue.get(exec, ident, slot);
     
-    if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
-        if (stubInfo->seen)
-            repatchGetByID(exec, baseValue, ident, slot, *stubInfo);
-        else
-            stubInfo->seen = true;
-    }
+    bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
+    if (stubInfo->seen)
+        repatchGetByID(exec, baseValue, ident, slot, *stubInfo);
+    else
+        stubInfo->seen = true;
+    
+    return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
 
-    return JSValue::encode(result);
 }
 
-EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, StringImpl* key)
+EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
     if (!base->isObject()) {
-        vm->throwException(exec, createInvalidParameterError(exec, "in", base));
+        vm->throwException(exec, createInvalidInParameterError(exec, base));
         return JSValue::encode(jsUndefined());
     }
     
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
-    Identifier ident(vm, key);
+    Identifier ident = Identifier::fromUid(vm, key);
     PropertySlot slot(base);
     bool result = asObject(base)->getPropertySlot(exec, ident, slot);
     
@@ -196,17 +236,19 @@ EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubI
     return JSValue::encode(jsBoolean(result));
 }
 
-EncodedJSValue JIT_OPERATION operationIn(ExecState* exec, StructureStubInfo*, JSCell* base, StringImpl* key)
+EncodedJSValue JIT_OPERATION operationIn(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
+    
+    stubInfo->tookSlowPath = true;
 
     if (!base->isObject()) {
-        vm->throwException(exec, createInvalidParameterError(exec, "in", base));
+        vm->throwException(exec, createInvalidInParameterError(exec, base));
         return JSValue::encode(jsUndefined());
     }
 
-    Identifier ident(vm, key);
+    Identifier ident = Identifier::fromUid(vm, key);
     return JSValue::encode(jsBoolean(asObject(base)->hasProperty(exec, ident)));
 }
 
@@ -218,216 +260,232 @@ EncodedJSValue JIT_OPERATION operationGenericIn(ExecState* exec, JSCell* base, E
     return JSValue::encode(jsBoolean(CommonSlowPaths::opIn(exec, JSValue::decode(key), base)));
 }
 
-void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    stubInfo->tookSlowPath = true;
+    
+    Identifier ident = Identifier::fromUid(vm, uid);
     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
 }
 
-void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    stubInfo->tookSlowPath = true;
+    
+    Identifier ident = Identifier::fromUid(vm, uid);
     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
     JSValue::decode(encodedBase).put(exec, ident, JSValue::decode(encodedValue), slot);
 }
 
-void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    stubInfo->tookSlowPath = true;
+    
+    Identifier ident = Identifier::fromUid(vm, uid);
     PutPropertySlot slot(JSValue::decode(encodedBase), true, exec->codeBlock()->putByIdContext());
     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
 }
 
-void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    stubInfo->tookSlowPath = true;
+    
+    Identifier ident = Identifier::fromUid(vm, uid);
     PutPropertySlot slot(JSValue::decode(encodedBase), false, exec->codeBlock()->putByIdContext());
     asObject(JSValue::decode(encodedBase))->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
 }
 
-void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSValue baseValue = JSValue::decode(encodedBase);
     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
-    
+
+    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
     baseValue.put(exec, ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
     if (stubInfo->seen)
-        repatchPutByID(exec, baseValue, ident, slot, *stubInfo, NotDirect);
+        repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
     else
         stubInfo->seen = true;
 }
 
-void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSValue baseValue = JSValue::decode(encodedBase);
     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
-    
+
+    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;    
     baseValue.put(exec, ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
     if (stubInfo->seen)
-        repatchPutByID(exec, baseValue, ident, slot, *stubInfo, NotDirect);
+        repatchPutByID(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
     else
         stubInfo->seen = true;
 }
 
-void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
     
+    Structure* structure = baseObject->structure(*vm);
     baseObject->putDirect(exec->vm(), ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
     if (stubInfo->seen)
-        repatchPutByID(exec, baseObject, ident, slot, *stubInfo, Direct);
+        repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
     else
         stubInfo->seen = true;
 }
 
-void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
     
+    Structure* structure = baseObject->structure(*vm);
     baseObject->putDirect(exec->vm(), ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
     if (stubInfo->seen)
-        repatchPutByID(exec, baseObject, ident, slot, *stubInfo, Direct);
+        repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
     else
         stubInfo->seen = true;
 }
 
-void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSValue baseValue = JSValue::decode(encodedBase);
     PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
     
+    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr; 
     baseValue.put(exec, ident, value, slot);
-    
+
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
-    
-    buildPutByIdList(exec, baseValue, ident, slot, *stubInfo, NotDirect);
+
+    buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
 }
 
-void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSValue baseValue = JSValue::decode(encodedBase);
     PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
-    
+
+    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
     baseValue.put(exec, ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
-    buildPutByIdList(exec, baseValue, ident, slot, *stubInfo, NotDirect);
+    buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
 }
 
-void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
     
     JSValue value = JSValue::decode(encodedValue);
     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
     PutPropertySlot slot(baseObject, true, exec->codeBlock()->putByIdContext());
-    
-    baseObject->putDirect(exec->vm(), ident, value, slot);
+
+    Structure* structure = baseObject->structure(*vm);    
+    baseObject->putDirect(*vm, ident, value, slot);
     
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
-    buildPutByIdList(exec, baseObject, ident, slot, *stubInfo, Direct);
+    buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
 }
 
-void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl* uid)
+void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    Identifier ident(vm, uid);
+    Identifier ident = Identifier::fromUid(vm, uid);
     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
 
     JSValue value = JSValue::decode(encodedValue);
     JSObject* baseObject = asObject(JSValue::decode(encodedBase));
     PutPropertySlot slot(baseObject, false, exec->codeBlock()->putByIdContext());
-    
-    baseObject ->putDirect(exec->vm(), ident, value, slot);
-    
+
+    Structure* structure = baseObject->structure(*vm);    
+    baseObject->putDirect(*vm, ident, value, slot);
+
     if (accessType != static_cast<AccessType>(stubInfo->accessType))
         return;
     
-    buildPutByIdList(exec, baseObject, ident, slot, *stubInfo, Direct);
+    buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
 }
 
 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
@@ -441,7 +499,7 @@ void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObj
     base->putDirect(vm, offset, JSValue::decode(value));
 }
 
-static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value)
+static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
 {
     VM& vm = callFrame->vm();
     if (LIKELY(subscript.isUInt32())) {
@@ -450,15 +508,14 @@ static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript,
             JSObject* object = asObject(baseValue);
             if (object->canSetIndexQuickly(i))
                 object->setIndexQuickly(callFrame->vm(), i, value);
-            else
+            else {
+                arrayProfile->setOutOfBounds();
                 object->methodTable(vm)->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
+            }
         } else
             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
-    } else if (isName(subscript)) {
-        PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
-        baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
     } else {
-        Identifier property = subscript.toString(callFrame)->toIdentifier(callFrame);
+        auto property = subscript.toPropertyKey(callFrame);
         if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
             PutPropertySlot slot(baseValue, callFrame->codeBlock()->isStrictMode());
             baseValue.put(callFrame, property, value, slot);
@@ -466,23 +523,45 @@ static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript,
     }
 }
 
-static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value)
+static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
 {
+    bool isStrictMode = callFrame->codeBlock()->isStrictMode();
     if (LIKELY(subscript.isUInt32())) {
-        uint32_t i = subscript.asUInt32();
-        baseObject->putDirectIndex(callFrame, i, value);
-    } else if (isName(subscript)) {
-        PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
-        baseObject->putDirect(callFrame->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
-        if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
-            PutPropertySlot slot(baseObject, callFrame->codeBlock()->isStrictMode());
-            baseObject->putDirect(callFrame->vm(), property, value, slot);
+        // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
+        uint32_t index = subscript.asUInt32();
+        ASSERT(isIndex(index));
+        if (baseObject->canSetIndexQuicklyForPutDirect(index)) {
+            baseObject->setIndexQuickly(callFrame->vm(), index, value);
+            return;
+        }
+
+        arrayProfile->setOutOfBounds();
+        baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+        return;
+    }
+
+    if (subscript.isDouble()) {
+        double subscriptAsDouble = subscript.asDouble();
+        uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
+        if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
+            baseObject->putDirectIndex(callFrame, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+            return;
         }
     }
+
+    // Don't put to an object if toString threw an exception.
+    auto property = subscript.toPropertyKey(callFrame);
+    if (callFrame->vm().exception())
+        return;
+
+    if (Optional<uint32_t> index = parseIndex(property))
+        baseObject->putDirectIndex(callFrame, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+    else {
+        PutPropertySlot slot(baseObject, isStrictMode);
+        baseObject->putDirect(callFrame->vm(), property, value, slot);
+    }
 }
-void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
+void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -501,10 +580,15 @@ void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBase
         ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
         ASSERT(!byValInfo.stubRoutine);
 
-        if (hasOptimizableIndexing(object->structure(vm))) {
+        Structure* structure = object->structure(vm);
+        if (hasOptimizableIndexing(structure)) {
             // Attempt to optimize.
-            JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
-            if (arrayMode != byValInfo.arrayMode) {
+            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
+            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
+                CodeBlock* codeBlock = exec->codeBlock();
+                ConcurrentJITLocker locker(codeBlock->m_lock);
+                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
+
                 JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
                 didOptimize = true;
             }
@@ -519,16 +603,15 @@ void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBase
             if (++byValInfo.slowPathCount >= 10
                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
                 // Don't ever try to optimize.
-                RepatchBuffer repatchBuffer(exec->codeBlock());
-                repatchBuffer.relinkCallerToFunction(ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationPutByValGeneric));
+                ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationPutByValGeneric));
             }
         }
     }
 
-    putByVal(exec, baseValue, subscript, value);
+    putByVal(exec, baseValue, subscript, value, arrayProfile);
 }
 
-void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
+void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
 {
     VM& vm = callFrame->vm();
     NativeCallFrameTracer tracer(&vm, callFrame);
@@ -546,11 +629,16 @@ void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue
         ASSERT(bytecodeOffset);
         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
         ASSERT(!byValInfo.stubRoutine);
-        
-        if (hasOptimizableIndexing(object->structure(vm))) {
+
+        Structure* structure = object->structure(vm);
+        if (hasOptimizableIndexing(structure)) {
             // Attempt to optimize.
-            JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
-            if (arrayMode != byValInfo.arrayMode) {
+            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
+            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
+                CodeBlock* codeBlock = callFrame->codeBlock();
+                ConcurrentJITLocker locker(codeBlock->m_lock);
+                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
+
                 JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
                 didOptimize = true;
             }
@@ -565,15 +653,14 @@ void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue
             if (++byValInfo.slowPathCount >= 10
                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
                 // Don't ever try to optimize.
-                RepatchBuffer repatchBuffer(callFrame->codeBlock());
-                repatchBuffer.relinkCallerToFunction(ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationDirectPutByValGeneric));
+                ctiPatchCallByReturnAddress(callFrame->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationDirectPutByValGeneric));
             }
         }
     }
-    directPutByVal(callFrame, object, subscript, value);
+    directPutByVal(callFrame, object, subscript, value, arrayProfile);
 }
 
-void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
+void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -582,11 +669,11 @@ void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue enco
     JSValue subscript = JSValue::decode(encodedSubscript);
     JSValue value = JSValue::decode(encodedValue);
 
-    putByVal(exec, baseValue, subscript, value);
+    putByVal(exec, baseValue, subscript, value, arrayProfile);
 }
 
 
-void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
+void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -595,16 +682,16 @@ void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValu
     JSValue subscript = JSValue::decode(encodedSubscript);
     JSValue value = JSValue::decode(encodedValue);
     RELEASE_ASSERT(baseValue.isObject());
-    directPutByVal(exec, asObject(baseValue), subscript, value);
+    directPutByVal(exec, asObject(baseValue), subscript, value, arrayProfile);
 }
 
 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee)
 {
-    ASSERT(exec->codeBlock()->codeType() != FunctionCode
+
+    ASSERT_UNUSED(exec, exec->codeBlock()->codeType() != FunctionCode
         || !exec->codeBlock()->needsActivation()
         || exec->hasActivation());
 
-    execCallee->setScope(exec->scope());
     execCallee->setCodeBlock(0);
 
     if (!isHostFunction(execCallee->calleeAsValue(), globalFuncEval))
@@ -623,7 +710,6 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
     ExecState* exec = execCallee->callerFrame();
     VM* vm = &exec->vm();
 
-    execCallee->setScope(exec->scope());
     execCallee->setCodeBlock(0);
 
     if (kind == CodeForCall) {
@@ -679,12 +765,15 @@ inline char* linkFor(
     
     JSValue calleeAsValue = execCallee->calleeAsValue();
     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
-    if (!calleeAsFunctionCell)
+    if (!calleeAsFunctionCell) {
+        // FIXME: We should cache these kinds of calls. They can be common and currently they are
+        // expensive.
+        // https://bugs.webkit.org/show_bug.cgi?id=144458
         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
+    }
 
     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
     JSScope* scope = callee->scopeUnchecked();
-    execCallee->setScope(scope);
     ExecutableBase* executable = callee->executable();
 
     MacroAssemblerCodePtr codePtr;
@@ -693,15 +782,20 @@ inline char* linkFor(
         codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, registers);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, &scope, kind);
-        execCallee->setScope(scope);
+
+        if (!isCall(kind) && functionExecutable->isBuiltinFunction()) {
+            exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
+            return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+        }
+
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
         if (error) {
-            throwStackOverflowError(exec);
+            exec->vm().throwException(exec, error);
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
         }
         codeBlock = functionExecutable->codeBlockFor(kind);
         ArityCheckMode arity;
-        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType == CallLinkInfo::CallVarargs || callLinkInfo->callType == CallLinkInfo::ConstructVarargs)
+        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType() == CallLinkInfo::CallVarargs || callLinkInfo->callType() == CallLinkInfo::ConstructVarargs)
             arity = MustCheckArity;
         else
             arity = ArityCheckNotRequired;
@@ -711,6 +805,7 @@ inline char* linkFor(
         callLinkInfo->setSeen();
     else
         linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr, kind, registers);
+    
     return reinterpret_cast<char*>(codePtr.executableAddress());
 }
 
@@ -749,12 +844,16 @@ inline char* virtualForWithFunction(
     
     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
     JSScope* scope = function->scopeUnchecked();
-    execCallee->setScope(scope);
     ExecutableBase* executable = function->executable();
     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->prepareForExecution(execCallee, function, &scope, kind);
-        execCallee->setScope(scope);
+
+        if (!isCall(kind) && functionExecutable->isBuiltinFunction()) {
+            exec->vm().throwException(exec, createNotAConstructorError(exec, function));
+            return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+        }
+
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, function, scope, kind);
         if (error) {
             exec->vm().throwException(exec, error);
             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
@@ -771,51 +870,12 @@ inline char* virtualFor(
     return virtualForWithFunction(execCallee, kind, registers, calleeAsFunctionCellIgnored);
 }
 
-static bool attemptToOptimizeClosureCall(
-    ExecState* execCallee, RegisterPreservationMode registers, JSCell* calleeAsFunctionCell,
-    CallLinkInfo& callLinkInfo)
-{
-    if (!calleeAsFunctionCell)
-        return false;
-    
-    VM& vm = execCallee->vm();
-    JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
-    JSFunction* oldCallee = callLinkInfo.callee.get();
-    
-    if (!oldCallee
-        || oldCallee->structure(vm) != callee->structure(vm)
-        || oldCallee->executable() != callee->executable())
-        return false;
-    
-    ASSERT(callee->executable()->hasJITCodeForCall());
-    MacroAssemblerCodePtr codePtr =
-        callee->executable()->generatedJITCodeForCall()->addressForCall(
-            *execCallee->callerFrame()->codeBlock()->vm(), callee->executable(),
-            ArityCheckNotRequired, registers);
-    
-    CodeBlock* codeBlock;
-    if (callee->executable()->isHostFunction())
-        codeBlock = 0;
-    else {
-        codeBlock = jsCast<FunctionExecutable*>(callee->executable())->codeBlockForCall();
-        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs || callLinkInfo.callType == CallLinkInfo::ConstructVarargs)
-            return false;
-    }
-    
-    linkClosureCall(
-        execCallee, callLinkInfo, codeBlock,
-        callee->structure(), callee->executable(), codePtr, registers);
-    
-    return true;
-}
-
-char* JIT_OPERATION operationLinkClosureCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
+char* JIT_OPERATION operationLinkPolymorphicCall(ExecState* execCallee, CallLinkInfo* callLinkInfo)
 {
     JSCell* calleeAsFunctionCell;
     char* result = virtualForWithFunction(execCallee, CodeForCall, RegisterPreservationNotRequired, calleeAsFunctionCell);
 
-    if (!attemptToOptimizeClosureCall(execCallee, RegisterPreservationNotRequired, calleeAsFunctionCell, *callLinkInfo))
-        linkSlowFor(execCallee, *callLinkInfo, CodeForCall, RegisterPreservationNotRequired);
+    linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell), RegisterPreservationNotRequired);
     
     return result;
 }
@@ -830,13 +890,12 @@ char* JIT_OPERATION operationVirtualConstruct(ExecState* execCallee, CallLinkInf
     return virtualFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired);
 }
 
-char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState* execCallee, CallLinkInfo* callLinkInfo)
+char* JIT_OPERATION operationLinkPolymorphicCallThatPreservesRegs(ExecState* execCallee, CallLinkInfo* callLinkInfo)
 {
     JSCell* calleeAsFunctionCell;
     char* result = virtualForWithFunction(execCallee, CodeForCall, MustPreserveRegisters, calleeAsFunctionCell);
 
-    if (!attemptToOptimizeClosureCall(execCallee, MustPreserveRegisters, calleeAsFunctionCell, *callLinkInfo))
-        linkSlowFor(execCallee, *callLinkInfo, CodeForCall, MustPreserveRegisters);
+    linkPolymorphicCall(execCallee, *callLinkInfo, CallVariant(calleeAsFunctionCell), MustPreserveRegisters);
     
     return result;
 }
@@ -918,7 +977,7 @@ size_t JIT_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSC
 
 size_t JIT_OPERATION operationHasProperty(ExecState* exec, JSObject* base, JSString* property)
 {
-    int result = base->hasProperty(exec, Identifier(exec, property->value(exec)));
+    int result = base->hasProperty(exec, property->toIdentifier(exec));
     return result;
 }
     
@@ -945,12 +1004,20 @@ EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState* exec
     return JSValue::encode(constructArrayWithSizeQuirk(exec, profile, exec->lexicalGlobalObject(), sizeValue));
 }
 
-EncodedJSValue JIT_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
+EncodedJSValue JIT_OPERATION operationNewFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
 {
     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    return JSValue::encode(JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()));
+    return JSValue::encode(JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
+}
+
+EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
+{
+    ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    return JSValue::encode(JSFunction::createWithInvalidatedReallocationWatchpoint(vm, static_cast<FunctionExecutable*>(functionExecutable), scope));
 }
 
 JSCell* JIT_OPERATION operationNewObject(ExecState* exec, Structure* structure)
@@ -967,7 +1034,7 @@ EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr
     NativeCallFrameTracer tracer(&vm, exec);
     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
     if (!regexp->isValid()) {
-        vm.throwException(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+        vm.throwException(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
         return JSValue::encode(jsUndefined());
     }
 
@@ -987,12 +1054,13 @@ void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue enc
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-
-    String message = errorDescriptionForValue(exec, JSValue::decode(encodedValue))->value(exec);
+    JSValue errorMessageValue = JSValue::decode(encodedValue);
+    RELEASE_ASSERT(errorMessageValue.isString());
+    String errorMessage = asString(errorMessageValue)->value(exec);
     if (referenceErrorFlag)
-        vm.throwException(exec, createReferenceError(exec, message));
+        vm.throwException(exec, createReferenceError(exec, errorMessage));
     else
-        vm.throwException(exec, createTypeError(exec, message));
+        vm.throwException(exec, createTypeError(exec, errorMessage));
 }
 
 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookID)
@@ -1032,6 +1100,10 @@ SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t byte
     DeferGCForAWhile deferGC(vm.heap);
     
     CodeBlock* codeBlock = exec->codeBlock();
+    if (codeBlock->jitType() != JITCode::BaselineJIT) {
+        dataLog("Unexpected code block in Baseline->DFG tier-up: ", *codeBlock, "\n");
+        RELEASE_ASSERT_NOT_REACHED();
+    }
     
     if (bytecodeIndex) {
         // If we're attempting to OSR from a loop, assume that this should be
@@ -1176,17 +1248,7 @@ SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t byte
         Operands<JSValue> mustHandleValues(codeBlock->numParameters(), numVarsWithValues);
         for (size_t i = 0; i < mustHandleValues.size(); ++i) {
             int operand = mustHandleValues.operandForIndex(i);
-            if (operandIsArgument(operand)
-                && !VirtualRegister(operand).toArgument()
-                && codeBlock->codeType() == FunctionCode
-                && codeBlock->specializationKind() == CodeForConstruct) {
-                // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
-                // also never be used. It doesn't matter what we put into the value for this,
-                // but it has to be an actual value that can be grokked by subsequent DFG passes,
-                // so we sanitize it here by turning it into Undefined.
-                mustHandleValues[i] = jsUndefined();
-            } else
-                mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
+            mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
         }
 
         RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
@@ -1261,6 +1323,32 @@ void JIT_OPERATION operationPutByIndex(ExecState* exec, EncodedJSValue encodedAr
 }
 
 #if USE(JSVALUE64)
+void JIT_OPERATION operationPutGetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    ASSERT(JSValue::decode(encodedObjectValue).isObject());
+    JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
+
+    JSValue getter = JSValue::decode(encodedGetterValue);
+    ASSERT(getter.isObject());
+    baseObj->putGetter(exec, *identifier, asObject(getter));
+}
+
+void JIT_OPERATION operationPutSetterById(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedSetterValue)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    ASSERT(JSValue::decode(encodedObjectValue).isObject());
+    JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
+
+    JSValue setter = JSValue::decode(encodedSetterValue);
+    ASSERT(setter.isObject());
+    baseObj->putSetter(exec, *identifier, asObject(setter));
+}
+
 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, EncodedJSValue encodedObjectValue, Identifier* identifier, EncodedJSValue encodedGetterValue, EncodedJSValue encodedSetterValue)
 {
     VM& vm = exec->vm();
@@ -1269,7 +1357,7 @@ void JIT_OPERATION operationPutGetterSetter(ExecState* exec, EncodedJSValue enco
     ASSERT(JSValue::decode(encodedObjectValue).isObject());
     JSObject* baseObj = asObject(JSValue::decode(encodedObjectValue));
 
-    GetterSetter* accessor = GetterSetter::create(vm);
+    GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
 
     JSValue getter = JSValue::decode(encodedGetterValue);
     JSValue setter = JSValue::decode(encodedSetterValue);
@@ -1278,12 +1366,36 @@ void JIT_OPERATION operationPutGetterSetter(ExecState* exec, EncodedJSValue enco
     ASSERT(getter.isObject() || setter.isObject());
 
     if (!getter.isUndefined())
-        accessor->setGetter(vm, asObject(getter));
+        accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
     if (!setter.isUndefined())
-        accessor->setSetter(vm, asObject(setter));
+        accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
 }
 #else
+void JIT_OPERATION operationPutGetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    ASSERT(object && object->isObject());
+    JSObject* baseObj = object->getObject();
+
+    ASSERT(getter->isObject());
+    baseObj->putGetter(exec, *identifier, getter);
+}
+
+void JIT_OPERATION operationPutSetterById(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* setter)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    ASSERT(object && object->isObject());
+    JSObject* baseObj = object->getObject();
+
+    ASSERT(setter->isObject());
+    baseObj->putSetter(exec, *identifier, setter);
+}
+
 void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Identifier* identifier, JSCell* getter, JSCell* setter)
 {
     VM& vm = exec->vm();
@@ -1292,31 +1404,31 @@ void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Ide
     ASSERT(object && object->isObject());
     JSObject* baseObj = object->getObject();
 
-    GetterSetter* accessor = GetterSetter::create(vm);
+    GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
 
     ASSERT(!getter || getter->isObject());
     ASSERT(!setter || setter->isObject());
     ASSERT(getter || setter);
 
     if (getter)
-        accessor->setGetter(vm, getter->getObject());
+        accessor->setGetter(vm, exec->lexicalGlobalObject(), getter->getObject());
     if (setter)
-        accessor->setSetter(vm, setter->getObject());
+        accessor->setSetter(vm, exec->lexicalGlobalObject(), setter->getObject());
     baseObj->putDirectAccessor(exec, *identifier, accessor, Accessor);
 }
 #endif
 
-void JIT_OPERATION operationPushNameScope(ExecState* exec, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes)
+void JIT_OPERATION operationPushCatchScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
 {
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    JSNameScope* scope = JSNameScope::create(exec, *identifier, JSValue::decode(encodedValue), attibutes);
+    pushNameScope<JSCatchScope>(exec, dst, symbolTable, encodedValue);
+}
 
-    exec->setScope(scope);
+void JIT_OPERATION operationPushFunctionNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
+{
+    pushNameScope<JSFunctionNameScope>(exec, dst, symbolTable, encodedValue);
 }
 
-void JIT_OPERATION operationPushWithScope(ExecState* exec, EncodedJSValue encodedValue)
+void JIT_OPERATION operationPushWithScope(ExecState* exec, int32_t dst, EncodedJSValue encodedValue)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -1325,15 +1437,19 @@ void JIT_OPERATION operationPushWithScope(ExecState* exec, EncodedJSValue encode
     if (vm.exception())
         return;
 
-    exec->setScope(JSWithScope::create(exec, o));
+    // FIXME: This won't work if this operation is called from the DFG or FTL.
+    // This should be changed to pass in the old scope and return the new scope.
+    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
+    exec->uncheckedR(dst) = JSWithScope::create(exec, o, currentScope);
 }
 
-void JIT_OPERATION operationPopScope(ExecState* exec)
+void JIT_OPERATION operationPopScope(ExecState* exec, int32_t scopeReg)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
-    exec->setScope(exec->scope()->next());
+    JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
+    exec->uncheckedR(scopeReg) = scope->next();
 }
 
 void JIT_OPERATION operationProfileDidCall(ExecState* exec, EncodedJSValue encodedValue)
@@ -1371,91 +1487,97 @@ EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState* exec, EncodedJ
         }
     }
 
-    vm.throwException(exec, createInvalidParameterError(exec, "instanceof", baseVal));
+    vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal));
     return JSValue::encode(JSValue());
 }
 
-JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, int32_t offset)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    JSActivation* activation = JSActivation::create(vm, exec, exec->registers() + offset, exec->codeBlock());
-    exec->setScope(activation);
-    return activation;
-}
-
-JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec)
+JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* currentScope)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    // NB: This needs to be exceedingly careful with top call frame tracking, since it
-    // may be called from OSR exit, while the state of the call stack is bizarre.
-    Arguments* result = Arguments::create(vm, exec);
-    ASSERT(!vm.exception());
-    return result;
+    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, currentScope, exec->codeBlock());
+    return lexicalEnvironment;
 }
 
-JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState* exec)
-{
-    DeferGCForAWhile(exec->vm().heap);
-    return operationCreateArguments(exec);
 }
 
-EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
+static bool canAccessArgumentIndexQuickly(JSObject& object, uint32_t index)
 {
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    // Here we can assume that the argumernts were created. Because otherwise the JIT code would
-    // have not made this call.
-    Identifier ident(&vm, "length");
-    JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
-    PropertySlot slot(baseValue);
-    return JSValue::encode(baseValue.get(exec, ident, slot));
-}
-
+    switch (object.structure()->typeInfo().type()) {
+    case DirectArgumentsType: {
+        DirectArguments* directArguments = jsCast<DirectArguments*>(&object);
+        if (directArguments->canAccessArgumentIndexQuicklyInDFG(index))
+            return true;
+        break;
+    }
+    case ScopedArgumentsType: {
+        ScopedArguments* scopedArguments = jsCast<ScopedArguments*>(&object);
+        if (scopedArguments->canAccessArgumentIndexQuicklyInDFG(index))
+            return true;
+        break;
+    }
+    default:
+        break;
+    }
+    return false;
 }
 
-static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
+static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ArrayProfile* arrayProfile, ReturnAddressPtr returnAddress)
 {
     if (LIKELY(baseValue.isCell() && subscript.isString())) {
         VM& vm = exec->vm();
         Structure& structure = *baseValue.asCell()->structure(vm);
         if (JSCell::canUseFastGetOwnProperty(structure)) {
-            if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, asString(subscript)->value(exec)))
-                return result;
+            if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
+                if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
+                    return result;
+            }
         }
     }
 
     if (subscript.isUInt32()) {
         uint32_t i = subscript.asUInt32();
-        if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
-            ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
-            return asString(baseValue)->getIndex(exec, i);
+        if (isJSString(baseValue)) {
+            if (asString(baseValue)->canGetIndex(i)) {
+                ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
+                return asString(baseValue)->getIndex(exec, i);
+            }
+            arrayProfile->setOutOfBounds();
+        } else if (baseValue.isObject()) {
+            JSObject* object = asObject(baseValue);
+            if (object->canGetIndexQuickly(i))
+                return object->getIndexQuickly(i);
+
+            if (!canAccessArgumentIndexQuickly(*object, i))
+                arrayProfile->setOutOfBounds();
         }
+
         return baseValue.get(exec, i);
     }
 
-    if (isName(subscript))
-        return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
-
-    Identifier property = subscript.toString(exec)->toIdentifier(exec);
+    baseValue.requireObjectCoercible(exec);
+    if (exec->hadException())
+        return jsUndefined();
+    auto property = subscript.toPropertyKey(exec);
+    if (exec->hadException())
+        return jsUndefined();
     return baseValue.get(exec, property);
 }
 
 extern "C" {
     
-EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
+EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     JSValue baseValue = JSValue::decode(encodedBase);
     JSValue subscript = JSValue::decode(encodedSubscript);
 
-    JSValue result = getByVal(exec, baseValue, subscript, ReturnAddressPtr(OUR_RETURN_ADDRESS));
+    JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
     return JSValue::encode(result);
 }
 
-EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
+EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -1474,8 +1596,15 @@ EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJS
         
         if (hasOptimizableIndexing(object->structure(vm))) {
             // Attempt to optimize.
-            JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
+            Structure* structure = object->structure(vm);
+            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
             if (arrayMode != byValInfo.arrayMode) {
+                // If we reached this case, we got an interesting array mode we did not expect when we compiled.
+                // Let's update the profile to do better next time.
+                CodeBlock* codeBlock = exec->codeBlock();
+                ConcurrentJITLocker locker(codeBlock->m_lock);
+                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
+
                 JIT::compileGetByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
                 didOptimize = true;
             }
@@ -1490,16 +1619,84 @@ EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJS
             if (++byValInfo.slowPathCount >= 10
                 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
                 // Don't ever try to optimize.
-                RepatchBuffer repatchBuffer(exec->codeBlock());
-                repatchBuffer.relinkCallerToFunction(ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValGeneric));
+                ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValGeneric));
             }
         }
     }
     
-    JSValue result = getByVal(exec, baseValue, subscript, ReturnAddressPtr(OUR_RETURN_ADDRESS));
+    JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
     return JSValue::encode(result);
 }
     
+EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue baseValue = JSValue::decode(encodedBase);
+    JSValue subscript = JSValue::decode(encodedSubscript);
+    
+    ASSERT(baseValue.isObject());
+    ASSERT(subscript.isUInt32());
+
+    JSObject* object = asObject(baseValue);
+    bool didOptimize = false;
+
+    unsigned bytecodeOffset = exec->locationAsBytecodeOffset();
+    ASSERT(bytecodeOffset);
+    ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1);
+    ASSERT(!byValInfo.stubRoutine);
+    
+    if (hasOptimizableIndexing(object->structure(vm))) {
+        // Attempt to optimize.
+        JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
+        if (arrayMode != byValInfo.arrayMode) {
+            JIT::compileHasIndexedProperty(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
+            didOptimize = true;
+        }
+    }
+    
+    if (!didOptimize) {
+        // If we take slow path more than 10 times without patching then make sure we
+        // never make that mistake again. Or, if we failed to patch and we have some object
+        // that intercepts indexed get, then don't even wait until 10 times. For cases
+        // where we see non-index-intercepting objects, this gives 10 iterations worth of
+        // opportunity for us to observe that the get_by_val may be polymorphic.
+        if (++byValInfo.slowPathCount >= 10
+            || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
+            // Don't ever try to optimize.
+            ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationHasIndexedPropertyGeneric)); 
+        }
+    }
+
+    uint32_t index = subscript.asUInt32();
+    if (object->canGetIndexQuickly(index))
+        return JSValue::encode(JSValue(JSValue::JSTrue));
+
+    if (!canAccessArgumentIndexQuickly(*object, index))
+        arrayProfile->setOutOfBounds();
+    return JSValue::encode(jsBoolean(object->hasProperty(exec, index)));
+}
+    
+EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue baseValue = JSValue::decode(encodedBase);
+    JSValue subscript = JSValue::decode(encodedSubscript);
+    
+    ASSERT(baseValue.isObject());
+    ASSERT(subscript.isUInt32());
+
+    JSObject* object = asObject(baseValue);
+    uint32_t index = subscript.asUInt32();
+    if (object->canGetIndexQuickly(index))
+        return JSValue::encode(JSValue(JSValue::JSTrue));
+
+    if (!canAccessArgumentIndexQuickly(*object, index))
+        arrayProfile->setOutOfBounds();
+    return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32())));
+}
+    
 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
 {
     VM& vm = exec->vm();
@@ -1517,34 +1714,18 @@ EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSV
             if (!isJSString(baseValue))
                 ctiPatchCallByReturnAddress(exec->codeBlock(), ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationGetByValDefault));
         }
-    } else if (isName(subscript))
-        result = baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
-    else {
-        Identifier property = subscript.toString(exec)->toIdentifier(exec);
+    } else {
+        baseValue.requireObjectCoercible(exec);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+        auto property = subscript.toPropertyKey(exec);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
         result = baseValue.get(exec, property);
     }
 
     return JSValue::encode(result);
 }
-    
-void JIT_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    ASSERT(exec->codeBlock()->needsActivation());
-    jsCast<JSActivation*>(activationCell)->tearOff(vm);
-}
-
-void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
-{
-    ASSERT(exec->codeBlock()->usesArguments());
-    if (activationCell) {
-        jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
-        return;
-    }
-    jsCast<Arguments*>(argumentsCell)->tearOff(exec);
-}
 
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, const Identifier* identifier)
 {
@@ -1555,22 +1736,10 @@ EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue
     bool couldDelete = baseObj->methodTable(vm)->deleteProperty(baseObj, exec, *identifier);
     JSValue result = jsBoolean(couldDelete);
     if (!couldDelete && exec->codeBlock()->isStrictMode())
-        vm.throwException(exec, createTypeError(exec, "Unable to delete property."));
+        vm.throwException(exec, createTypeError(exec, ASCIILiteral("Unable to delete property.")));
     return JSValue::encode(result);
 }
 
-JSCell* JIT_OPERATION operationGetPNames(ExecState* exec, JSObject* obj)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    Structure* structure = obj->structure(vm);
-    JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
-    if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
-        jsPropertyNameIterator = JSPropertyNameIterator::create(exec, obj);
-    return jsPropertyNameIterator;
-}
-
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
 {
     VM& vm = exec->vm();
@@ -1584,23 +1753,21 @@ EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue
     return JSValue::encode(jsBoolean(result));
 }
 
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister, int32_t firstVarArgOffset)
+int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     JSStack* stack = &exec->interpreter()->stack();
     JSValue arguments = JSValue::decode(encodedArguments);
-    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, firstFreeRegister, firstVarArgOffset);
-    return newCallFrame;
+    return sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
 }
 
-CallFrame* JIT_OPERATION operationLoadVarargs(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedThis, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    JSValue thisValue = JSValue::decode(encodedThis);
     JSValue arguments = JSValue::decode(encodedArguments);
-    loadVarargs(exec, newCallFrame, thisValue, arguments, firstVarArgOffset);
+    setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length);
     return newCallFrame;
 }
 
@@ -1667,12 +1834,13 @@ char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState* exec, Enc
     return reinterpret_cast<char*>(result);
 }
 
-EncodedJSValue JIT_OPERATION operationResolveScope(ExecState* exec, int32_t identifierIndex)
+EncodedJSValue JIT_OPERATION operationResolveScope(ExecState* exec, int32_t scopeReg, int32_t identifierIndex)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     const Identifier& ident = exec->codeBlock()->identifier(identifierIndex);
-    return JSValue::encode(JSScope::resolve(exec, exec->scope(), ident));
+    JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
+    return JSValue::encode(JSScope::resolve(exec, scope, ident));
 }
 
 EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction* bytecodePC)
@@ -1696,9 +1864,13 @@ EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState* exec, Instruction*
     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure(vm)->propertyAccessesAreCacheable()) {
         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
-            ConcurrentJITLocker locker(codeBlock->m_lock);
-            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure(vm));
-            pc[6].u.operand = slot.cachedOffset();
+            Structure* structure = scope->structure(vm);
+            {
+                ConcurrentJITLocker locker(codeBlock->m_lock);
+                pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
+                pc[6].u.operand = slot.cachedOffset();
+            }
+            structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
         }
     }
 
@@ -1716,7 +1888,13 @@ void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[1].u.operand).jsValue());
     JSValue value = exec->r(pc[3].u.operand).jsValue();
     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
-
+    if (modeAndType.type() == LocalClosureVar) {
+        JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
+        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
+        if (WatchpointSet* set = pc[5].u.watchpointSet)
+            set->touch("Executed op_put_scope<LocalClosureVar>");
+        return;
+    }
     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
         exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
         return;
@@ -1728,14 +1906,7 @@ void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
     if (exec->vm().exception())
         return;
 
-    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
-    if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
-        if (slot.isCacheablePut() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
-            ConcurrentJITLocker locker(codeBlock->m_lock);
-            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
-            pc[6].u.operand = slot.cachedOffset();
-        }
-    }
+    CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
 }
 
 void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
@@ -1746,8 +1917,8 @@ void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExcepti
     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
     vm->throwException(exec, exceptionValue);
 
-    // Results stored out-of-band in vm.targetMachinePCForThrow & vm.callFrameForThrow
-    genericUnwind(vm, exec, exceptionValue);
+    // Results stored out-of-band in vm.targetMachinePCForThrow, vm.callFrameForThrow & vm.vmEntryFrameForThrow
+    genericUnwind(vm, exec);
 }
 
 void JIT_OPERATION operationFlushWriteBarrierBuffer(ExecState* exec, JSCell* cell)
@@ -1780,17 +1951,24 @@ void JIT_OPERATION operationInitGlobalConst(ExecState* exec, Instruction* pc)
     NativeCallFrameTracer tracer(vm, exec);
 
     JSValue value = exec->r(pc[2].u.operand).jsValue();
-    pc[1].u.registerPointer->set(*vm, exec->codeBlock()->globalObject(), value);
+    pc[1].u.variablePointer->set(*vm, exec->codeBlock()->globalObject(), value);
 }
 
 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
 {
-    NativeCallFrameTracer tracer(vm, exec, NativeCallFrameTracer::VMEntrySentinelOK);
+    NativeCallFrameTracer tracer(vm, exec);
+    genericUnwind(vm, exec);
+    ASSERT(vm->targetMachinePCForThrow);
+}
 
-    JSValue exceptionValue = vm->exception();
-    ASSERT(exceptionValue);
-    
-    genericUnwind(vm, exec, exceptionValue);
+void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
+{
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    ASSERT(callerFrame);
+
+    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+    genericUnwind(vm, callerFrame);
     ASSERT(vm->targetMachinePCForThrow);
 }
 
@@ -1798,9 +1976,7 @@ void JIT_OPERATION operationVMHandleException(ExecState* exec)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
-
-    ASSERT(!exec->isVMEntrySentinel());
-    genericUnwind(vm, exec, vm->exception());
+    genericUnwind(vm, exec);
 }
 
 // This function "should" just take the ExecState*, but doing so would make it more difficult
@@ -1810,24 +1986,65 @@ void JIT_OPERATION operationVMHandleException(ExecState* exec)
 // testing.
 void JIT_OPERATION operationExceptionFuzz()
 {
-    ASSERT(Options::enableExceptionFuzz());
-
     // This probably "just works" for GCC also, but I haven't tried.
 #if COMPILER(CLANG)
     ExecState* exec = static_cast<ExecState*>(__builtin_frame_address(1));
-    DeferGCForAWhile deferGC(exec->vm().heap);
-    
-    s_numberOfExceptionFuzzChecks++;
-    
-    unsigned fireTarget = Options::fireExceptionFuzzAt();
-    if (fireTarget == s_numberOfExceptionFuzzChecks) {
-        printf("JSC EXCEPTION FUZZ: Throwing fuzz exception with call frame %p and return address %p.\n", exec, __builtin_return_address(0));
-        exec->vm().throwException(
-            exec, createError(exec->lexicalGlobalObject(), ASCIILiteral("Exception Fuzz")));
-    }
+    void* returnPC = __builtin_return_address(0);
+    doExceptionFuzzing(exec, "JITOperations", returnPC);
 #endif // COMPILER(CLANG)
 }
 
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue baseValue = JSValue::decode(encodedBaseValue);
+    if (baseValue.isUndefinedOrNull())
+        return JSValue::encode(jsBoolean(false));
+
+    JSObject* base = baseValue.toObject(exec);
+    return JSValue::encode(jsBoolean(base->hasProperty(exec, asString(propertyName)->toIdentifier(exec))));
+}
+
+EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState* exec, JSCell* baseCell, int32_t subscript)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSObject* object = baseCell->toObject(exec, exec->lexicalGlobalObject());
+    return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript)));
+}
+    
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, JSCell* cell)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
+
+    return propertyNameEnumerator(exec, base);
+}
+
+EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell);
+    JSString* propertyName = enumerator->propertyNameAtIndex(index);
+    return JSValue::encode(propertyName ? propertyName : jsNull());
+}
+
+JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    return jsString(exec, Identifier::from(exec, index).string());
+}
+
+void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
+{
+    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside baseline JIT"));
+}
+
 } // extern "C"
 
 // Note: getHostCallReturnValueWithExecState() needs to be placed before the
index c36acec361a0a6266514e0d52af7a3061830342d..7de77fc740856261d5856f427d45e1e37bdb3485 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
 #include "PutKind.h"
 #include "SpillRegistersMode.h"
 #include "StructureStubInfo.h"
-#include "VariableWatchpointSet.h"
 
 
 namespace JSC {
@@ -58,19 +57,23 @@ extern "C" {
     Key:
     A: JSArray*
     Aap: ArrayAllocationProfile*
+    Ap: ArrayProfile*
     C: JSCell*
     Cb: CodeBlock*
     Cli: CallLinkInfo*
     D: double
     E: ExecState*
     F: CallFrame*
-    I: StringImpl*
-    Icf: InlineCalLFrame*
+    G: JSGlobalObject*
+    I: UniquedStringImpl*
+    Icf: InlineCallFrame*
     Idc: const Identifier*
     J: EncodedJSValue
     Jcp: const JSValue*
-    Jsa: JSActivation*
+    Jsc: JSScope*
+    Jsf: JSFunction*
     Jss: JSString*
+    L: JSLexicalEnvironment*
     O: JSObject*
     P: pointer (char*)
     Pc: Instruction* i.e. bytecode PC
@@ -80,14 +83,15 @@ extern "C" {
     Sprt: SlowPathReturnType
     Ssi: StructureStubInfo*
     St: Structure*
+    Symtab: SymbolTable*
+    T: StringImpl*
     V: void
     Vm: VM*
-    Vws: VariableWatchpointSet*
+    Ws: WatchpointSet*
     Z: int32_t
 */
 
-typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJJZ)(ExecState*, CallFrame*, EncodedJSValue, EncodedJSValue, int32_t);
-typedef CallFrame* JIT_OPERATION (*F_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
+typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_E)(ExecState*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EA)(ExecState*, JSArray*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EAZ)(ExecState*, JSArray*, int32_t);
@@ -95,39 +99,60 @@ typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EAapJ)(ExecState*, ArrayAl
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EAapJcpZ)(ExecState*, ArrayAllocationProfile*, const JSValue*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EC)(ExecState*, JSCell*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
-typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECI)(ExecState*, JSCell*, StringImpl*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECI)(ExecState*, JSCell*, UniquedStringImpl*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EDA)(ExecState*, double, JSArray*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EE)(ExecState*, ExecState*);
-typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EI)(ExecState*, StringImpl*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EI)(ExecState*, UniquedStringImpl*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJ)(ExecState*, EncodedJSValue);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJC)(ExecState*, EncodedJSValue, JSCell*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJA)(ExecState*, EncodedJSValue, JSArray*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJI)(ExecState*, EncodedJSValue, UniquedStringImpl*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJIdc)(ExecState*, EncodedJSValue, const Identifier*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, ArrayProfile*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJP)(ExecState*, EncodedJSValue, void*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EP)(ExecState*, void*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EPP)(ExecState*, void*, void*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EPS)(ExecState*, void*, size_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EPc)(ExecState*, Instruction*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESS)(ExecState*, size_t, size_t);
-typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiCI)(ExecState*, StructureStubInfo*, JSCell*, StringImpl*);
-typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiJI)(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiCI)(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiJI)(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZ)(ExecState*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZIcfZ)(ExecState*, int32_t, InlineCallFrame*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_E)(ExecState*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EC)(ExecState*, JSCell*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_ECZC)(ExecState*, JSCell*, int32_t, JSCell*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJ)(ExecState*, EncodedJSValue);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJsc)(ExecState*, JSScope*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZC)(ExecState*, EncodedJSValue, int32_t, JSCell*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJJC)(ExecState*, EncodedJSValue, EncodedJSValue, JSCell*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJscZ)(ExecState*, JSScope*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssSt)(ExecState*, JSString*, Structure*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssJss)(ExecState*, JSString*, JSString*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssJssJss)(ExecState*, JSString*, JSString*, JSString*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EL)(ExecState*, JSLexicalEnvironment*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EO)(ExecState*, JSObject*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EOZ)(ExecState*, JSObject*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_ESt)(ExecState*, Structure*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStJscSymtab)(ExecState*, Structure*, JSScope*, SymbolTable*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsfL)(ExecState*, Structure*, Register*, int32_t, JSFunction*, JSLexicalEnvironment*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsf)(ExecState*, Structure*, Register*, int32_t, JSFunction*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZ)(ExecState*, Structure*, int32_t);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZZ)(ExecState*, Structure*, int32_t, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
 typedef double JIT_OPERATION (*D_JITOperation_D)(double);
 typedef double JIT_OPERATION (*D_JITOperation_DD)(double, double);
@@ -137,7 +162,13 @@ typedef int64_t JIT_OPERATION(*Q_JITOperation_J)(EncodedJSValue);
 typedef int64_t JIT_OPERATION(*Q_JITOperation_D)(double);
 typedef int32_t JIT_OPERATION (*Z_JITOperation_D)(double);
 typedef int32_t JIT_OPERATION (*Z_JITOperation_E)(ExecState*);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_EC)(ExecState*, JSCell*);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_ESJss)(ExecState*, size_t, JSString*);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
 typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
+typedef size_t JIT_OPERATION (*S_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
 typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef size_t JIT_OPERATION (*S_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
 typedef size_t JIT_OPERATION (*S_JITOperation_EOJss)(ExecState*, JSObject*, JSString*);
@@ -149,17 +180,20 @@ typedef void JIT_OPERATION (*V_JITOperation_EC)(ExecState*, JSCell*);
 typedef void JIT_OPERATION (*V_JITOperation_ECb)(ExecState*, CodeBlock*);
 typedef void JIT_OPERATION (*V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
 typedef void JIT_OPERATION (*V_JITOperation_ECIcf)(ExecState*, JSCell*, InlineCallFrame*);
+typedef void JIT_OPERATION (*V_JITOperation_ECIC)(ExecState*, JSCell*, Identifier*, JSCell*);
 typedef void JIT_OPERATION (*V_JITOperation_ECICC)(ExecState*, JSCell*, Identifier*, JSCell*, JSCell*);
 typedef void JIT_OPERATION (*V_JITOperation_ECCIcf)(ExecState*, JSCell*, JSCell*, InlineCallFrame*);
 typedef void JIT_OPERATION (*V_JITOperation_ECJJ)(ExecState*, JSCell*, EncodedJSValue, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_ECPSPS)(ExecState*, JSCell*, void*, size_t, void*, size_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
-typedef void JIT_OPERATION (*V_JITOperation_EIdJZ)(ExecState*, Identifier*, EncodedJSValue, int32_t);
+typedef void JIT_OPERATION (*V_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJ)(ExecState*, EncodedJSValue);
-typedef void JIT_OPERATION (*V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, StringImpl*);
+typedef void JIT_OPERATION (*V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, UniquedStringImpl*);
+typedef void JIT_OPERATION (*V_JITOperation_EJIdJ)(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJIdJJ)(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
+typedef void JIT_OPERATION (*V_JITOperation_EJJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*);
 typedef void JIT_OPERATION (*V_JITOperation_EJPP)(ExecState*, EncodedJSValue, void*, void*);
 typedef void JIT_OPERATION (*V_JITOperation_EJZJ)(ExecState*, EncodedJSValue, int32_t, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
@@ -167,10 +201,14 @@ typedef void JIT_OPERATION (*V_JITOperation_EOZD)(ExecState*, JSObject*, int32_t
 typedef void JIT_OPERATION (*V_JITOperation_EOZJ)(ExecState*, JSObject*, int32_t, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EPc)(ExecState*, Instruction*);
 typedef void JIT_OPERATION (*V_JITOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue);
-typedef void JIT_OPERATION (*V_JITOperation_ESsiJJI)(ExecState*, StructureStubInfo*, EncodedJSValue, EncodedJSValue, StringImpl*);
-typedef void JIT_OPERATION (*V_JITOperation_EVwsJ)(ExecState*, VariableWatchpointSet*, EncodedJSValue);
+typedef void JIT_OPERATION (*V_JITOperation_ESsiJJI)(ExecState*, StructureStubInfo*, EncodedJSValue, EncodedJSValue, UniquedStringImpl*);
+typedef void JIT_OPERATION (*V_JITOperation_EWs)(ExecState*, WatchpointSet*);
 typedef void JIT_OPERATION (*V_JITOperation_EZ)(ExecState*, int32_t);
+typedef void JIT_OPERATION (*V_JITOperation_EZJ)(ExecState*, int32_t, EncodedJSValue);
+typedef void JIT_OPERATION (*V_JITOperation_EZJZZZ)(ExecState*, int32_t, EncodedJSValue, int32_t, int32_t, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation_EVm)(ExecState*, VM*);
+typedef void JIT_OPERATION (*V_JITOperation_J)(EncodedJSValue);
+typedef void JIT_OPERATION (*V_JITOperation_Z)(int32_t);
 typedef char* JIT_OPERATION (*P_JITOperation_E)(ExecState*);
 typedef char* JIT_OPERATION (*P_JITOperation_EC)(ExecState*, JSCell*);
 typedef char* JIT_OPERATION (*P_JITOperation_ECli)(ExecState*, CallLinkInfo*);
@@ -187,49 +225,51 @@ typedef char* JIT_OPERATION (*P_JITOperation_EStPS)(ExecState*, Structure*, void
 typedef char* JIT_OPERATION (*P_JITOperation_EStSS)(ExecState*, Structure*, size_t, size_t);
 typedef char* JIT_OPERATION (*P_JITOperation_EStZ)(ExecState*, Structure*, int32_t);
 typedef char* JIT_OPERATION (*P_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
-typedef StringImpl* JIT_OPERATION (*I_JITOperation_EJss)(ExecState*, JSString*);
+typedef StringImpl* JIT_OPERATION (*T_JITOperation_EJss)(ExecState*, JSString*);
 typedef JSString* JIT_OPERATION (*Jss_JITOperation_EZ)(ExecState*, int32_t);
 
 // This method is used to lookup an exception hander, keyed by faultLocation, which is
 // the return location from one of the calls out to one of the helper operations above.
 
 void JIT_OPERATION lookupExceptionHandler(VM*, ExecState*) WTF_INTERNAL;
+void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM*, ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationVMHandleException(ExecState*) WTF_INTERNAL;
 
 void JIT_OPERATION operationThrowStackOverflowError(ExecState*, CodeBlock*) WTF_INTERNAL;
 int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL;
 int32_t JIT_OPERATION operationConstructArityCheck(ExecState*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetById(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, StringImpl*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, StringImpl*);
-EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, StringImpl*);
-EncodedJSValue JIT_OPERATION operationGenericIn(ExecState*, JSCell*, EncodedJSValue);
-void JIT_OPERATION operationPutByIdStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
-void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, StringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationIn(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGenericIn(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectNonStrict(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdNonStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
-void JIT_OPERATION operationPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
-void JIT_OPERATION operationDirectPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
-void JIT_OPERATION operationPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
-void JIT_OPERATION operationDirectPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
+void JIT_OPERATION operationDirectPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
+void JIT_OPERATION operationDirectPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationCallEval(ExecState*, ExecState*) WTF_INTERNAL;
 char* JIT_OPERATION operationLinkCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
-char* JIT_OPERATION operationLinkClosureCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
+char* JIT_OPERATION operationLinkPolymorphicCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationVirtualCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationVirtualConstruct(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationLinkConstruct(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationLinkCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
-char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
+char* JIT_OPERATION operationLinkPolymorphicCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationVirtualCallThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationVirtualConstructThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
 char* JIT_OPERATION operationLinkConstructThatPreservesRegs(ExecState*, CallLinkInfo*) WTF_INTERNAL;
@@ -249,7 +289,8 @@ size_t JIT_OPERATION operationHasProperty(ExecState*, JSObject*, JSString*) WTF_
 EncodedJSValue JIT_OPERATION operationNewArrayWithProfile(ExecState*, ArrayAllocationProfile*, const JSValue* values, int32_t size) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewArrayBufferWithProfile(ExecState*, ArrayAllocationProfile*, const JSValue* values, int32_t size) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState*, ArrayAllocationProfile*, EncodedJSValue size) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSCell*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
 void JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
@@ -261,36 +302,38 @@ SlowPathReturnType JIT_OPERATION operationOptimize(ExecState*, int32_t) WTF_INTE
 #endif
 void JIT_OPERATION operationPutByIndex(ExecState*, EncodedJSValue, int32_t, EncodedJSValue);
 #if USE(JSVALUE64)
+void JIT_OPERATION operationPutGetterById(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutSetterById(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPutGetterSetter(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 #else
+void JIT_OPERATION operationPutGetterById(ExecState*, JSCell*, Identifier*, JSCell*) WTF_INTERNAL;
+void JIT_OPERATION operationPutSetterById(ExecState*, JSCell*, Identifier*, JSCell*) WTF_INTERNAL;
 void JIT_OPERATION operationPutGetterSetter(ExecState*, JSCell*, Identifier*, JSCell*, JSCell*) WTF_INTERNAL;
 #endif
-void JIT_OPERATION operationPushNameScope(ExecState*, Identifier*, EncodedJSValue, int32_t) WTF_INTERNAL;
-void JIT_OPERATION operationPushWithScope(ExecState*, EncodedJSValue) WTF_INTERNAL;
-void JIT_OPERATION operationPopScope(ExecState*) WTF_INTERNAL;
+void JIT_OPERATION operationPushCatchScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPushFunctionNameScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPushWithScope(ExecState*, int32_t, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPopScope(ExecState*, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationProfileWillCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateActivation(ExecState*, int32_t offset) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateArguments(ExecState*) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
-void JIT_OPERATION operationTearOffActivation(ExecState*, JSCell*) WTF_INTERNAL;
-void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t firstFreeRegister, int32_t firstVarArgOffset) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationLoadVarargs(ExecState*, CallFrame*, EncodedJSValue thisValue, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
+int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset, int32_t length) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
 
 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
 char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
 char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationResolveScope(ExecState*, int32_t identifierIndex) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationResolveScope(ExecState*, int32_t scope, int32_t identifierIndex) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
 void JIT_OPERATION operationPutToScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
 
@@ -303,6 +346,14 @@ void JIT_OPERATION operationInitGlobalConst(ExecState*, Instruction*);
 
 void JIT_OPERATION operationExceptionFuzz();
 
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
+EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState*, JSCell*, int32_t);
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, JSCell*);
+EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t);
+JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
+
+void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
+
 } // extern "C"
 
 inline P_JITOperation_ECli operationLinkFor(
@@ -355,13 +406,13 @@ inline P_JITOperation_ECli operationVirtualFor(
     return 0;
 }
 
-inline P_JITOperation_ECli operationLinkClosureCallFor(RegisterPreservationMode registers)
+inline P_JITOperation_ECli operationLinkPolymorphicCallFor(RegisterPreservationMode registers)
 {
     switch (registers) {
     case RegisterPreservationNotRequired:
-        return operationLinkClosureCall;
+        return operationLinkPolymorphicCall;
     case MustPreserveRegisters:
-        return operationLinkClosureCallThatPreservesRegs;
+        return operationLinkPolymorphicCallThatPreservesRegs;
     }
     RELEASE_ASSERT_NOT_REACHED();
     return 0;
index 34d51517db490ca489c96c6696398f086109935d..12390afc1bc340a3d4d28d5b838f7d0c74667990 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JIT.h"
 
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "GCAwareJITStubRoutine.h"
 #include "GetterSetter.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
 #include "JSArray.h"
+#include "JSEnvironmentRecord.h"
 #include "JSFunction.h"
-#include "JSPropertyNameIterator.h"
-#include "JSVariableObject.h"
 #include "LinkBuffer.h"
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 #include <wtf/StringPrintStream.h>
 
 
@@ -103,8 +105,8 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.
     // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if
     // number was signed since m_vectorLength is always less than intmax (since the total allocation
-    // size is always less than 4Gb).  As such zero extending wil have been correct (and extending the value
-    // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign
+    // size is always less than 4Gb).  As such zero extending will have been correct (and extending the value
+    // to 64-bits is necessary since it's used in the address calculation).  We zero extend rather than sign
     // extending since it makes it easier to re-tag the value in the slow case.
     zeroExtend32ToPtr(regT1, regT1);
 
@@ -151,7 +153,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
 }
 
-JIT::JumpList JIT::emitDoubleGetByVal(Instruction*, PatchableJump& badType)
+JIT::JumpList JIT::emitDoubleLoad(Instruction*, PatchableJump& badType)
 {
     JumpList slowCases;
     
@@ -160,13 +162,11 @@ JIT::JumpList JIT::emitDoubleGetByVal(Instruction*, PatchableJump& badType)
     slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength())));
     loadDouble(BaseIndex(regT2, regT1, TimesEight), fpRegT0);
     slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0));
-    moveDoubleTo64(fpRegT0, regT0);
-    sub64(tagTypeNumberRegister, regT0);
     
     return slowCases;
 }
 
-JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape)
+JIT::JumpList JIT::emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape)
 {
     JumpList slowCases;
     
@@ -179,7 +179,7 @@ JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType,
     return slowCases;
 }
 
-JIT::JumpList JIT::emitArrayStorageGetByVal(Instruction*, PatchableJump& badType)
+JIT::JumpList JIT::emitArrayStorageLoad(Instruction*, PatchableJump& badType)
 {
     JumpList slowCases;
 
@@ -217,20 +217,14 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
     notString.link(this);
     nonCell.link(this);
     
-    Jump skipProfiling = jump();
-    
     linkSlowCase(iter); // vector length check
     linkSlowCase(iter); // empty value
     
-    emitArrayProfileOutOfBoundsSpecialCase(profile);
-    
-    skipProfiling.link(this);
-    
     Label slowPath = label();
     
     emitGetVirtualRegister(base, regT0);
     emitGetVirtualRegister(property, regT1);
-    Call call = callOperation(operationGetByValDefault, dst, regT0, regT1);
+    Call call = callOperation(operationGetByValDefault, dst, regT0, regT1, profile);
 
     m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
     m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
@@ -264,51 +258,6 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID
     load64(BaseIndex(scratch, offset, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), result);
 }
 
-void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    unsigned expected = currentInstruction[4].u.operand;
-    int iter = currentInstruction[5].u.operand;
-    int i = currentInstruction[6].u.operand;
-
-    emitGetVirtualRegister(property, regT0);
-    addSlowCase(branch64(NotEqual, regT0, addressFor(expected)));
-    emitGetVirtualRegisters(base, regT0, iter, regT1);
-    emitJumpSlowCaseIfNotJSCell(regT0, base);
-
-    // Test base's structure
-    emitLoadStructure(regT0, regT2, regT3);
-    addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
-    load32(addressFor(i), regT3);
-    sub32(TrustedImm32(1), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
-    Jump inlineProperty = branch32(Below, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)));
-    add32(TrustedImm32(firstOutOfLineOffset), regT3);
-    sub32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)), regT3);
-    inlineProperty.link(this);
-    compileGetDirectOffset(regT0, regT0, regT3, regT1);
-
-    emitPutVirtualRegister(dst, regT0);
-}
-
-void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-
-    linkSlowCase(iter);
-    linkSlowCaseIfNotJSCell(iter, base);
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-
-    emitGetVirtualRegister(base, regT0);
-    emitGetVirtualRegister(property, regT1);
-    callOperation(operationGetByValGeneric, dst, regT0, regT1);
-}
-
 void JIT::emit_op_put_by_val(Instruction* currentInstruction)
 {
     int base = currentInstruction[1].u.operand;
@@ -475,7 +424,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
     emitGetVirtualRegister(property, regT1);
     emitGetVirtualRegister(value, regT2);
     bool isDirect = m_interpreter->getOpcodeID(currentInstruction->u.opcode) == op_put_by_val_direct;
-    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT0, regT1, regT2);
+    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT0, regT1, regT2, profile);
 
     m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
     m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
@@ -489,6 +438,20 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction)
     callOperation(operationPutByIndex, regT0, currentInstruction[2].u.operand, regT1);
 }
 
+void JIT::emit_op_put_getter_by_id(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT1);
+    callOperation(operationPutGetterById, regT0, &m_codeBlock->identifier(currentInstruction[2].u.operand), regT1);
+}
+
+void JIT::emit_op_put_setter_by_id(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT1);
+    callOperation(operationPutSetterById, regT0, &m_codeBlock->identifier(currentInstruction[2].u.operand), regT1);
+}
+
 void JIT::emit_op_put_getter_setter(Instruction* currentInstruction)
 {
     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
@@ -528,6 +491,7 @@ void JIT::emit_op_get_by_id(Instruction* currentInstruction)
 
     emitValueProfilingSite();
     emitPutVirtualRegister(resultVReg);
+    assertStackPointerOffset();
 }
 
 void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -637,16 +601,10 @@ void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
     addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfState()), TrustedImm32(IsInvalidated)));
 }
 
-void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned depth)
+void JIT::emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, unsigned depth)
 {
     emitVarInjectionCheck(needsVarInjectionChecks);
-    emitGetVirtualRegister(JSStack::ScopeChain, regT0);
-    if (m_codeBlock->needsActivation()) {
-        emitGetVirtualRegister(m_codeBlock->activationRegister(), regT1);
-        Jump noActivation = branchTestPtr(Zero, regT1);
-        loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
-        noActivation.link(this);
-    }
+    emitGetVirtualRegister(scope, regT0);
     for (unsigned i = 0; i < depth; ++i)
         loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
     emitPutVirtualRegister(dst);
@@ -655,8 +613,9 @@ void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned dep
 void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[3].u.operand);
-    unsigned depth = currentInstruction[4].u.operand;
+    int scope = currentInstruction[2].u.operand;
+    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
+    unsigned depth = currentInstruction[5].u.operand;
 
     switch (resolveType) {
     case GlobalProperty:
@@ -669,25 +628,28 @@ void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
         break;
     case ClosureVar:
     case ClosureVarWithVarInjectionChecks:
-        emitResolveClosure(dst, needsVarInjectionChecks(resolveType), depth);
+        emitResolveClosure(dst, scope, needsVarInjectionChecks(resolveType), depth);
         break;
     case Dynamic:
         addSlowCase(jump());
         break;
+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
     }
 }
 
 void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     int dst = currentInstruction[1].u.operand;
-    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[3].u.operand);
+    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
 
     if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar)
         return;
 
     linkSlowCase(iter);
-    int32_t indentifierIndex = currentInstruction[2].u.operand;
-    callOperation(operationResolveScope, dst, indentifierIndex);
+    int32_t scope = currentInstruction[2].u.operand;
+    int32_t identifierIndex = currentInstruction[3].u.operand;
+    callOperation(operationResolveScope, dst, scope, identifierIndex);
 }
 
 void JIT::emitLoadWithStructureCheck(int scope, Structure** structureSlot)
@@ -713,8 +675,7 @@ void JIT::emitGetGlobalVar(uintptr_t operand)
 void JIT::emitGetClosureVar(int scope, uintptr_t operand)
 {
     emitGetVirtualRegister(scope, regT0);
-    loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
-    loadPtr(Address(regT0, operand * sizeof(Register)), regT0);
+    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)), regT0);
 }
 
 void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
@@ -744,6 +705,8 @@ void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
     case Dynamic:
         addSlowCase(jump());
         break;
+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
     }
     emitPutVirtualRegister(dst);
     emitValueProfilingSite();
@@ -773,30 +736,19 @@ void JIT::emitPutGlobalProperty(uintptr_t* operandSlot, int value)
     storePtr(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)));
 }
 
-void JIT::emitNotifyWrite(RegisterID value, RegisterID scratch, VariableWatchpointSet* set)
-{
-    if (!set || set->state() == IsInvalidated)
-        return;
-    
-    load8(set->addressOfState(), scratch);
-    Jump isDone = branch32(Equal, scratch, TrustedImm32(IsInvalidated));
-    addSlowCase(branch64(NotEqual, AbsoluteAddress(set->addressOfInferredValue()), value));
-    isDone.link(this);
-}
-
-void JIT::emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet* set)
+void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
 {
     emitGetVirtualRegister(value, regT0);
-    emitNotifyWrite(regT0, regT1, set);
+    emitNotifyWrite(set);
     storePtr(regT0, reinterpret_cast<void*>(operand));
 }
 
-void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value)
+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet* set)
 {
     emitGetVirtualRegister(value, regT1);
     emitGetVirtualRegister(scope, regT0);
-    loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
-    storePtr(regT1, Address(regT0, operand * sizeof(Register)));
+    emitNotifyWrite(set);
+    storePtr(regT1, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)));
 }
 
 void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
@@ -820,11 +772,12 @@ void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
         emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
         break;
+    case LocalClosureVar:
     case ClosureVar:
     case ClosureVarWithVarInjectionChecks:
         emitWriteBarrier(scope, value, ShouldFilterValue);
         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
-        emitPutClosureVar(scope, *operandSlot, value);
+        emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
         break;
     case Dynamic:
         addSlowCase(jump());
@@ -836,9 +789,9 @@ void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowC
 {
     ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
     unsigned linkCount = 0;
-    if (resolveType != GlobalVar && resolveType != ClosureVar)
+    if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar)
         linkCount++;
-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
+    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
         && currentInstruction[5].u.watchpointSet->state() != IsInvalidated)
         linkCount++;
     if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks)
@@ -850,12 +803,37 @@ void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowC
     callOperation(operationPutToScope, currentInstruction);
 }
 
+void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int arguments = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+    
+    emitGetVirtualRegister(arguments, regT0);
+    load64(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)), regT0);
+    emitValueProfilingSite();
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
+{
+    int arguments = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+    
+    emitWriteBarrier(arguments, value, ShouldFilterValue);
+    
+    emitGetVirtualRegister(arguments, regT0);
+    emitGetVirtualRegister(value, regT1);
+    store64(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)));
+}
+
 void JIT::emit_op_init_global_const(Instruction* currentInstruction)
 {
     JSGlobalObject* globalObject = m_codeBlock->globalObject();
     emitWriteBarrier(globalObject, currentInstruction[2].u.operand, ShouldFilterValue);
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
-    store64(regT0, currentInstruction[1].u.registerPointer);
+    store64(regT0, currentInstruction[1].u.variablePointer);
 }
 
 #endif // USE(JSVALUE64)
@@ -875,9 +853,9 @@ void JIT::emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode mode
     if (mode == ShouldFilterBaseAndValue || mode == ShouldFilterBase)
         ownerNotCell = branchTest64(NonZero, regT0, tagMaskRegister);
 
-    Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(regT0);
+    Jump ownerIsRememberedOrInEden = jumpIfIsRememberedOrInEden(regT0);
     callOperation(operationUnconditionalWriteBarrier, regT0);
-    ownerNotMarkedOrAlreadyRemembered.link(this);
+    ownerIsRememberedOrInEden.link(this);
 
     if (mode == ShouldFilterBaseAndValue || mode == ShouldFilterBase)
         ownerNotCell.link(this);
@@ -925,9 +903,9 @@ void JIT::emitWriteBarrier(unsigned owner, unsigned value, WriteBarrierMode mode
     if (mode == ShouldFilterBase || mode == ShouldFilterBaseAndValue)
         ownerNotCell = branch32(NotEqual, regT0, TrustedImm32(JSValue::CellTag));
 
-    Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(regT1);
+    Jump ownerIsRememberedOrInEden = jumpIfIsRememberedOrInEden(regT1);
     callOperation(operationUnconditionalWriteBarrier, regT1);
-    ownerNotMarkedOrAlreadyRemembered.link(this);
+    ownerIsRememberedOrInEden.link(this);
 
     if (mode == ShouldFilterBase || mode == ShouldFilterBaseAndValue)
         ownerNotCell.link(this);
@@ -966,9 +944,9 @@ void JIT::emitWriteBarrier(JSCell* owner)
 {
 #if ENABLE(GGC)
     if (!MarkedBlock::blockFor(owner)->isMarked(owner)) {
-        Jump ownerNotMarkedOrAlreadyRemembered = checkMarkByte(owner);
+        Jump ownerIsRememberedOrInEden = jumpIfIsRememberedOrInEden(owner);
         callOperation(operationUnconditionalWriteBarrier, owner);
-        ownerNotMarkedOrAlreadyRemembered.link(this);
+        ownerIsRememberedOrInEden.link(this);
     } else
         callOperation(operationUnconditionalWriteBarrier, owner);
 #else
@@ -996,6 +974,12 @@ void JIT::privateCompileGetByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
     case JITArrayStorage:
         slowCases = emitArrayStorageGetByVal(currentInstruction, badType);
         break;
+    case JITDirectArguments:
+        slowCases = emitDirectArgumentsGetByVal(currentInstruction, badType);
+        break;
+    case JITScopedArguments:
+        slowCases = emitScopedArgumentsGetByVal(currentInstruction, badType);
+        break;
     default:
         TypedArrayType type = typedArrayTypeForJITArrayMode(arrayMode);
         if (isInt(type))
@@ -1091,6 +1075,75 @@ void JIT::privateCompilePutByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric));
 }
 
+JIT::JumpList JIT::emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType)
+{
+    JumpList slowCases;
+    
+#if USE(JSVALUE64)
+    RegisterID base = regT0;
+    RegisterID property = regT1;
+    JSValueRegs result = JSValueRegs(regT0);
+    RegisterID scratch = regT3;
+#else
+    RegisterID base = regT0;
+    RegisterID property = regT2;
+    JSValueRegs result = JSValueRegs(regT1, regT0);
+    RegisterID scratch = regT3;
+#endif
+
+    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
+    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(DirectArgumentsType));
+    
+    slowCases.append(branch32(AboveOrEqual, property, Address(base, DirectArguments::offsetOfLength())));
+    slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfOverrides())));
+    
+    zeroExtend32ToPtr(property, scratch);
+    loadValue(BaseIndex(base, scratch, TimesEight, DirectArguments::storageOffset()), result);
+    
+    return slowCases;
+}
+
+JIT::JumpList JIT::emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType)
+{
+    JumpList slowCases;
+    
+#if USE(JSVALUE64)
+    RegisterID base = regT0;
+    RegisterID property = regT1;
+    JSValueRegs result = JSValueRegs(regT0);
+    RegisterID scratch = regT3;
+    RegisterID scratch2 = regT4;
+#else
+    RegisterID base = regT0;
+    RegisterID property = regT2;
+    JSValueRegs result = JSValueRegs(regT1, regT0);
+    RegisterID scratch = regT3;
+    RegisterID scratch2 = regT4;
+#endif
+
+    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
+    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(ScopedArgumentsType));
+    slowCases.append(branch32(AboveOrEqual, property, Address(base, ScopedArguments::offsetOfTotalLength())));
+    
+    loadPtr(Address(base, ScopedArguments::offsetOfTable()), scratch);
+    load32(Address(scratch, ScopedArgumentsTable::offsetOfLength()), scratch2);
+    Jump overflowCase = branch32(AboveOrEqual, property, scratch2);
+    loadPtr(Address(base, ScopedArguments::offsetOfScope()), scratch2);
+    loadPtr(Address(scratch, ScopedArgumentsTable::offsetOfArguments()), scratch);
+    load32(BaseIndex(scratch, property, TimesFour), scratch);
+    slowCases.append(branch32(Equal, scratch, TrustedImm32(ScopeOffset::invalidOffset)));
+    loadValue(BaseIndex(scratch2, scratch, TimesEight, JSEnvironmentRecord::offsetOfVariables()), result);
+    Jump done = jump();
+    overflowCase.link(this);
+    sub32(property, scratch2);
+    neg32(scratch2);
+    loadValue(BaseIndex(base, scratch2, TimesEight, ScopedArguments::overflowStorageOffset()), result);
+    slowCases.append(branchIfEmpty(result));
+    done.link(this);
+    
+    return slowCases;
+}
+
 JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType type)
 {
     ASSERT(isInt(type));
@@ -1121,13 +1174,13 @@ JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badTyp
     switch (elementSize(type)) {
     case 1:
         if (isSigned(type))
-            load8Signed(BaseIndex(base, property, TimesOne), resultPayload);
+            load8SignedExtendTo32(BaseIndex(base, property, TimesOne), resultPayload);
         else
             load8(BaseIndex(base, property, TimesOne), resultPayload);
         break;
     case 2:
         if (isSigned(type))
-            load16Signed(BaseIndex(base, property, TimesTwo), resultPayload);
+            load16SignedExtendTo32(BaseIndex(base, property, TimesTwo), resultPayload);
         else
             load16(BaseIndex(base, property, TimesTwo), resultPayload);
         break;
index 88974f142aa2ae10b6294d631d71ece0721236f0..1bebb92a942118bb6899492778707fb0341deae9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JIT.h"
 
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "GCAwareJITStubRoutine.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
 #include "JSArray.h"
+#include "JSEnvironmentRecord.h"
 #include "JSFunction.h"
-#include "JSPropertyNameIterator.h"
-#include "JSVariableObject.h"
 #include "LinkBuffer.h"
 #include "RepatchBuffer.h"
 #include "ResultType.h"
@@ -57,6 +57,28 @@ void JIT::emit_op_put_by_index(Instruction* currentInstruction)
     callOperation(operationPutByIndex, regT1, regT0, property, regT3, regT2);
 }
 
+void JIT::emit_op_put_getter_by_id(Instruction* currentInstruction)
+{
+    int base = currentInstruction[1].u.operand;
+    int property = currentInstruction[2].u.operand;
+    int getter = currentInstruction[3].u.operand;
+
+    emitLoadPayload(base, regT1);
+    emitLoadPayload(getter, regT3);
+    callOperation(operationPutGetterById, regT1, &m_codeBlock->identifier(property), regT3);
+}
+
+void JIT::emit_op_put_setter_by_id(Instruction* currentInstruction)
+{
+    int base = currentInstruction[1].u.operand;
+    int property = currentInstruction[2].u.operand;
+    int setter = currentInstruction[3].u.operand;
+
+    emitLoadPayload(base, regT1);
+    emitLoadPayload(setter, regT3);
+    callOperation(operationPutSetterById, regT1, &m_codeBlock->identifier(property), regT3);
+}
+
 void JIT::emit_op_put_getter_setter(Instruction* currentInstruction)
 {
     int base = currentInstruction[1].u.operand;
@@ -173,15 +195,13 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
 }
 
-JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape)
+JIT::JumpList JIT::emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape)
 {
     JumpList slowCases;
     
     badType = patchableBranch32(NotEqual, regT1, TrustedImm32(expectedShape));
-    
     loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
     slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength())));
-    
     load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
     load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
     slowCases.append(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
@@ -189,32 +209,27 @@ JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType,
     return slowCases;
 }
 
-JIT::JumpList JIT::emitDoubleGetByVal(Instruction*, PatchableJump& badType)
+JIT::JumpList JIT::emitDoubleLoad(Instruction*, PatchableJump& badType)
 {
     JumpList slowCases;
     
     badType = patchableBranch32(NotEqual, regT1, TrustedImm32(DoubleShape));
-    
     loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
     slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength())));
-    
     loadDouble(BaseIndex(regT3, regT2, TimesEight), fpRegT0);
     slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0));
-    moveDoubleToInts(fpRegT0, regT0, regT1);
     
     return slowCases;
 }
 
-JIT::JumpList JIT::emitArrayStorageGetByVal(Instruction*, PatchableJump& badType)
+JIT::JumpList JIT::emitArrayStorageLoad(Instruction*, PatchableJump& badType)
 {
     JumpList slowCases;
     
     add32(TrustedImm32(-ArrayStorageShape), regT1, regT3);
     badType = patchableBranch32(Above, regT3, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape));
-    
     loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
     slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset())));
-    
     load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
     load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
     slowCases.append(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
@@ -242,21 +257,15 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
     failed.link(this);
     notString.link(this);
     nonCell.link(this);
-    
-    Jump skipProfiling = jump();
 
     linkSlowCase(iter); // vector length check
     linkSlowCase(iter); // empty value
     
-    emitArrayProfileOutOfBoundsSpecialCase(profile);
-    
-    skipProfiling.link(this);
-    
     Label slowPath = label();
     
     emitLoad(base, regT1, regT0);
     emitLoad(property, regT3, regT2);
-    Call call = callOperation(operationGetByValDefault, dst, regT1, regT0, regT3, regT2);
+    Call call = callOperation(operationGetByValDefault, dst, regT1, regT0, regT3, regT2, profile);
 
     m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
     m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
@@ -449,6 +458,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
     emitLoad(value, regT0, regT1);
     addCallArgument(regT1);
     addCallArgument(regT0);
+    addCallArgument(TrustedImmPtr(profile));
     Call call = appendCallWithExceptionCheck(isDirect ? operationDirectPutByVal : operationPutByVal);
 #else
     // The register selection below is chosen to reduce register swapping on ARM.
@@ -456,7 +466,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
     emitLoad(base, regT2, regT1);
     emitLoad(property, regT3, regT0);
     emitLoad(value, regT5, regT4);
-    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT2, regT1, regT3, regT0, regT5, regT4);
+    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT2, regT1, regT3, regT0, regT5, regT4, profile);
 #endif
 
     m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
@@ -520,9 +530,6 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
     emitLoad2(base, regT1, regT0, value, regT3, regT2);
     
     emitJumpSlowCaseIfNotJSCell(base, regT1);
-    
-    emitLoad(base, regT1, regT0);
-    emitLoad(value, regT3, regT2);
 
     JITPutByIdGenerator gen(
         m_codeBlock, CodeOrigin(m_bytecodeOffset), RegisterSet::specialRegisters(),
@@ -544,7 +551,10 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase
     linkSlowCase(iter);
     
     Label coldPathBegin(this);
-    
+
+    // JITPutByIdGenerator only preserve the value and the base's payload, we have to reload the tag.
+    emitLoadTag(base, regT1);
+
     JITPutByIdGenerator& gen = m_putByIds[m_putByIdIndex++];
     
     Call call = callOperation(
@@ -613,54 +623,6 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, Register
     load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), resultTag);
 }
 
-void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    unsigned expected = currentInstruction[4].u.operand;
-    int iter = currentInstruction[5].u.operand;
-    int i = currentInstruction[6].u.operand;
-    
-    emitLoad2(property, regT1, regT0, base, regT3, regT2);
-    emitJumpSlowCaseIfNotJSCell(property, regT1);
-    addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected)));
-    // Property registers are now available as the property is known
-    emitJumpSlowCaseIfNotJSCell(base, regT3);
-    emitLoadPayload(iter, regT1);
-    
-    // Test base's structure
-    loadPtr(Address(regT2, JSCell::structureIDOffset()), regT0);
-    addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
-    load32(addressFor(i), regT3);
-    sub32(TrustedImm32(1), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
-    Jump inlineProperty = branch32(Below, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)));
-    add32(TrustedImm32(firstOutOfLineOffset), regT3);
-    sub32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)), regT3);
-    inlineProperty.link(this);
-    compileGetDirectOffset(regT2, regT1, regT0, regT3);    
-    
-    emitStore(dst, regT1, regT0);
-}
-
-void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    
-    linkSlowCaseIfNotJSCell(iter, property);
-    linkSlowCase(iter);
-    linkSlowCaseIfNotJSCell(iter, base);
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-    
-    emitLoad(base, regT1, regT0);
-    emitLoad(property, regT3, regT2);
-    callOperation(operationGetByValGeneric, dst, regT1, regT0, regT3, regT2);
-}
-
 void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
 {
     if (!needsVarInjectionChecks)
@@ -668,17 +630,11 @@ void JIT::emitVarInjectionCheck(bool needsVarInjectionChecks)
     addSlowCase(branch8(Equal, AbsoluteAddress(m_codeBlock->globalObject()->varInjectionWatchpoint()->addressOfState()), TrustedImm32(IsInvalidated)));
 }
 
-void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned depth)
+void JIT::emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, unsigned depth)
 {
     emitVarInjectionCheck(needsVarInjectionChecks);
     move(TrustedImm32(JSValue::CellTag), regT1);
-    emitLoadPayload(JSStack::ScopeChain, regT0);
-    if (m_codeBlock->needsActivation()) {
-        emitLoadPayload(m_codeBlock->activationRegister().offset(), regT2);
-        Jump noActivation = branchTestPtr(Zero, regT2);
-        loadPtr(Address(regT2, JSScope::offsetOfNext()), regT0);
-        noActivation.link(this);
-    }
+    emitLoadPayload(scope, regT0);
     for (unsigned i = 0; i < depth; ++i)
         loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
     emitStore(dst, regT1, regT0);
@@ -687,8 +643,9 @@ void JIT::emitResolveClosure(int dst, bool needsVarInjectionChecks, unsigned dep
 void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[3].u.operand);
-    unsigned depth = currentInstruction[4].u.operand;
+    int scope = currentInstruction[2].u.operand;
+    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
+    unsigned depth = currentInstruction[5].u.operand;
 
     switch (resolveType) {
     case GlobalProperty:
@@ -702,25 +659,28 @@ void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
         break;
     case ClosureVar:
     case ClosureVarWithVarInjectionChecks:
-        emitResolveClosure(dst, needsVarInjectionChecks(resolveType), depth);
+        emitResolveClosure(dst, scope, needsVarInjectionChecks(resolveType), depth);
         break;
     case Dynamic:
         addSlowCase(jump());
         break;
+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
     }
 }
 
 void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     int dst = currentInstruction[1].u.operand;
-    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[3].u.operand);
+    ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand);
 
     if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar)
         return;
 
     linkSlowCase(iter);
-    int32_t indentifierIndex = currentInstruction[2].u.operand;
-    callOperation(operationResolveScope, dst, indentifierIndex);
+    int32_t scope = currentInstruction[2].u.operand;
+    int32_t identifierIndex = currentInstruction[3].u.operand;
+    callOperation(operationResolveScope, dst, scope, identifierIndex);
 }
 
 void JIT::emitLoadWithStructureCheck(int scope, Structure** structureSlot)
@@ -746,9 +706,8 @@ void JIT::emitGetGlobalVar(uintptr_t operand)
 void JIT::emitGetClosureVar(int scope, uintptr_t operand)
 {
     emitLoad(scope, regT1, regT0);
-    loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
-    load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), regT1);
-    load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), regT0);
+    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset), regT1);
+    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset), regT0);
 }
 
 void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
@@ -778,6 +737,8 @@ void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
     case Dynamic:
         addSlowCase(jump());
         break;
+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
     }
     emitValueProfilingSite();
     emitStore(dst, regT1, regT0);
@@ -806,38 +767,21 @@ void JIT::emitPutGlobalProperty(uintptr_t* operandSlot, int value)
     store32(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
 }
 
-void JIT::emitNotifyWrite(RegisterID tag, RegisterID payload, RegisterID scratch, VariableWatchpointSet* set)
-{
-    if (!set || set->state() == IsInvalidated)
-        return;
-    
-    load8(set->addressOfState(), scratch);
-    Jump isDone = branch32(Equal, scratch, TrustedImm32(IsInvalidated));
-
-    JumpList notifySlow = branch32(
-        NotEqual, AbsoluteAddress(set->addressOfInferredValue()->payloadPointer()), payload);
-    notifySlow.append(branch32(
-        NotEqual, AbsoluteAddress(set->addressOfInferredValue()->tagPointer()), tag));
-    addSlowCase(notifySlow);
-
-    isDone.link(this);
-}
-
-void JIT::emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet* set)
+void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
 {
     emitLoad(value, regT1, regT0);
-    emitNotifyWrite(regT1, regT0, regT2, set);
+    emitNotifyWrite(set);
     store32(regT1, reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
     store32(regT0, reinterpret_cast<char*>(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
 }
 
-void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value)
+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet* set)
 {
     emitLoad(value, regT3, regT2);
     emitLoad(scope, regT1, regT0);
-    loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
-    store32(regT3, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    store32(regT2, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+    emitNotifyWrite(set);
+    store32(regT3, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset));
+    store32(regT2, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset));
 }
 
 void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
@@ -861,11 +805,12 @@ void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
         emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
         break;
+    case LocalClosureVar:
     case ClosureVar:
     case ClosureVarWithVarInjectionChecks:
         emitWriteBarrier(scope, value, ShouldFilterValue);
         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
-        emitPutClosureVar(scope, *operandSlot, value);
+        emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
         break;
     case Dynamic:
         addSlowCase(jump());
@@ -877,11 +822,11 @@ void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowC
 {
     ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
     unsigned linkCount = 0;
-    if (resolveType != GlobalVar && resolveType != ClosureVar)
+    if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar)
         linkCount++;
-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
+    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
         && currentInstruction[5].u.watchpointSet->state() != IsInvalidated)
-        linkCount += 2;
+        linkCount++;
     if (!linkCount)
         return;
     while (linkCount--)
@@ -889,9 +834,36 @@ void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowC
     callOperation(operationPutToScope, currentInstruction);
 }
 
+void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int arguments = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+    
+    emitLoadPayload(arguments, regT0);
+    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset), regT1);
+    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset), regT0);
+    emitValueProfilingSite();
+    emitStore(dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
+{
+    int arguments = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+    
+    emitWriteBarrier(arguments, value, ShouldFilterValue);
+    
+    emitLoadPayload(arguments, regT0);
+    emitLoad(value, regT1, regT2);
+    store32(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset));
+    store32(regT2, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset));
+}
+
 void JIT::emit_op_init_global_const(Instruction* currentInstruction)
 {
-    WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer;
+    WriteBarrier<Unknown>* variablePointer = currentInstruction[1].u.variablePointer;
     int value = currentInstruction[2].u.operand;
 
     JSGlobalObject* globalObject = m_codeBlock->globalObject();
@@ -900,8 +872,8 @@ void JIT::emit_op_init_global_const(Instruction* currentInstruction)
 
     emitLoad(value, regT1, regT0);
     
-    store32(regT1, registerPointer->tagPointer());
-    store32(regT0, registerPointer->payloadPointer());
+    store32(regT1, variablePointer->tagPointer());
+    store32(regT0, variablePointer->payloadPointer());
 }
 
 } // namespace JSC
index 163705d2dc70423e598506a90ac37ecc1b4bcc7b..b2113a65f1f83a6d78e96a91a75d4d134658de78 100644 (file)
@@ -60,10 +60,10 @@ public:
     
     // Use this if you want to pass a CodePtr to someone who insists on taking
     // a RefPtr<JITStubRoutine>.
-    static PassRefPtr<JITStubRoutine> createSelfManagedRoutine(
+    static Ref<JITStubRoutine> createSelfManagedRoutine(
         MacroAssemblerCodePtr rawCodePointer)
     {
-        return adoptRef(new JITStubRoutine(MacroAssemblerCodeRef::createSelfManagedCodeRef(rawCodePointer)));
+        return adoptRef(*new JITStubRoutine(MacroAssemblerCodeRef::createSelfManagedCodeRef(rawCodePointer)));
     }
     
     virtual ~JITStubRoutine();
@@ -141,6 +141,9 @@ public:
         return true;
     }
     
+    // Return true if you are still valid after. Return false if you are now invalid. If you return
+    // false, you will usually not do any clearing because the idea is that you will simply be
+    // destroyed.
     virtual bool visitWeak(RepatchBuffer&);
 
 protected:
index bd71ea61d77b5a447e20065cf1515744aad5ee94..7206a14988c6c5e4ecf3069afd3a17db097cbdc7 100644 (file)
@@ -41,12 +41,12 @@ struct ProtoCallFrame;
 class VM;
 
 extern "C" {
-    EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);
-    EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue vmEntryToJavaScript(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*);
 }
 #endif
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 extern "C" void ctiMasmProbeTrampoline();
 #endif
 
index d1b7a1884ef2d9399a16a6ada190f8b7c68aad3c..19c37b7542dac4cdfc18039f6f5a23014b984baa 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC {
 
 #if COMPILER(GCC)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 // The following are offsets for MacroAssembler::ProbeContext fields accessed
 // by the ctiMasmProbeTrampoline stub.
 
@@ -143,10 +143,10 @@ COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu
 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
 #undef PROBE_OFFSETOF
 
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 asm (
 ".text" "\n"
 ".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
@@ -291,7 +291,7 @@ SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n"
 
     "pop       { pc }" "\n"
 );
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 
 
index e8a612e875a1495ea787d19018678bfdb49e7d15..cbe9791cb5ec2c9656d6dd6f87a3ef13cd6db20b 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC {
 
 #if COMPILER(GCC)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 // The following are offsets for MacroAssembler::ProbeContext fields accessed
 // by the ctiMasmProbeTrampoline stub.
 
@@ -94,8 +94,6 @@ namespace JSC {
 #define PROBE_CPU_D13_OFFSET (PROBE_FIRST_FPREG_OFFSET + (13 * FPREG_SIZE))
 #define PROBE_CPU_D14_OFFSET (PROBE_FIRST_FPREG_OFFSET + (14 * FPREG_SIZE))
 #define PROBE_CPU_D15_OFFSET (PROBE_FIRST_FPREG_OFFSET + (15 * FPREG_SIZE))
-
-#if CPU(APPLE_ARMV7S)
 #define PROBE_CPU_D16_OFFSET (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE))
 #define PROBE_CPU_D17_OFFSET (PROBE_FIRST_FPREG_OFFSET + (17 * FPREG_SIZE))
 #define PROBE_CPU_D18_OFFSET (PROBE_FIRST_FPREG_OFFSET + (18 * FPREG_SIZE))
@@ -113,10 +111,6 @@ namespace JSC {
 #define PROBE_CPU_D30_OFFSET (PROBE_FIRST_FPREG_OFFSET + (30 * FPREG_SIZE))
 #define PROBE_CPU_D31_OFFSET (PROBE_FIRST_FPREG_OFFSET + (31 * FPREG_SIZE))
 #define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (32 * FPREG_SIZE))
-#else
-#define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE))
-#endif // CPU(APPLE_ARMV7S)
-
 
 // These ASSERTs remind you that if you change the layout of ProbeContext,
 // you need to change ctiMasmProbeTrampoline offsets above to match.
@@ -162,7 +156,6 @@ COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d13) == PROBE_CPU_D13_OFFSET, ProbeContext_cpu
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d14) == PROBE_CPU_D14_OFFSET, ProbeContext_cpu_d14_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline);
 
-#if CPU(APPLE_ARMV7S)
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d16) == PROBE_CPU_D16_OFFSET, ProbeContext_cpu_d16_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d17) == PROBE_CPU_D17_OFFSET, ProbeContext_cpu_d17_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d18) == PROBE_CPU_D18_OFFSET, ProbeContext_cpu_d18_offset_matches_ctiMasmProbeTrampoline);
@@ -179,7 +172,6 @@ COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d28) == PROBE_CPU_D28_OFFSET, ProbeContext_cpu
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d29) == PROBE_CPU_D29_OFFSET, ProbeContext_cpu_d29_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d30) == PROBE_CPU_D30_OFFSET, ProbeContext_cpu_d30_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d31) == PROBE_CPU_D31_OFFSET, ProbeContext_cpu_d31_offset_matches_ctiMasmProbeTrampoline);
-#endif // CPU(APPLE_ARMV7S)
 
 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
 
@@ -238,11 +230,7 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     "ldr       lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n"
 
     "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D0_OFFSET) "\n"
-#if CPU(APPLE_ARMV7S)
     "vstmia.64 ip, { d0-d31 }" "\n"
-#else
-    "vstmia.64 ip, { d0-d15 }" "\n"
-#endif
 
     "mov       fp, sp" "\n" // Save the ProbeContext*.
 
@@ -255,13 +243,8 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     // To enable probes to modify register state, we copy all registers
     // out of the ProbeContext before returning.
 
-#if CPU(APPLE_ARMV7S)
     "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D31_OFFSET + FPREG_SIZE) "\n"
     "vldmdb.64 ip!, { d0-d31 }" "\n"
-#else
-    "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D15_OFFSET + FPREG_SIZE) "\n"
-    "vldmdb.64 ip!, { d0-d15 }" "\n"
-#endif
     "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET + GPREG_SIZE) "\n"
     "ldmdb     ip, { r0-r11 }" "\n"
     "ldr       ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSCR_OFFSET) "]" "\n"
@@ -342,7 +325,7 @@ SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n"
 
     "pop       { pc }" "\n"
 );
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 #endif // COMPILER(GCC)
 
index afbcac48e496207bbf513efe9f0457247544490e..ffd119763b8c47bf2850637828972d8e28d8604d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
  *
@@ -45,7 +45,7 @@ namespace JSC {
 
 #if COMPILER(GCC)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 asm (
 ".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
 HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
@@ -95,14 +95,14 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     "movl 6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n"
     "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp)" "\n"
 
-    "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp)" "\n"
-    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp)" "\n"
+    "movq %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp)" "\n"
+    "movq %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp)" "\n"
+    "movq %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp)" "\n"
+    "movq %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp)" "\n"
+    "movq %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp)" "\n"
+    "movq %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp)" "\n"
+    "movq %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp)" "\n"
+    "movq %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp)" "\n"
 
     // Reserve stack space for the arg while maintaining the required stack
     // pointer 32 byte alignment:
@@ -119,14 +119,14 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp), %esi" "\n"
     "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp), %edi" "\n"
 
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp), %xmm0" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp), %xmm1" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp), %xmm2" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp), %xmm3" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp), %xmm4" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp), %xmm5" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp), %xmm6" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp), %xmm7" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp), %xmm0" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp), %xmm1" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp), %xmm2" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp), %xmm3" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp), %xmm4" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp), %xmm5" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp), %xmm6" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp), %xmm7" "\n"
 
     // There are 6 more registers left to restore:
     //     eax, ecx, ebp, esp, eip, and eflags.
@@ -196,7 +196,7 @@ SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n"
     "popl %ebp" "\n"
     "ret" "\n"
 );
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 #endif // COMPILER(GCC)
 
index f102f3b25627de199686a481d978cf8d5ebeb1b8..00b361c89ce46eb2103db4ebce702d4a8074f75e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,7 +36,7 @@ namespace JSC {
 
 #if COMPILER(GCC)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 // The following are offsets for MacroAssembler::ProbeContext fields accessed
 // by the ctiMasmProbeTrampoline stub.
 
@@ -50,39 +50,35 @@ namespace JSC {
 #define PROBE_ARG1_OFFSET (1 * PTR_SIZE)
 #define PROBE_ARG2_OFFSET (2 * PTR_SIZE)
 
-#define PROBE_CPU_EAX_OFFSET (4 * PTR_SIZE)
-#define PROBE_CPU_EBX_OFFSET (5 * PTR_SIZE)
-#define PROBE_CPU_ECX_OFFSET (6 * PTR_SIZE)
-#define PROBE_CPU_EDX_OFFSET (7 * PTR_SIZE)
-#define PROBE_CPU_ESI_OFFSET (8 * PTR_SIZE)
-#define PROBE_CPU_EDI_OFFSET (9 * PTR_SIZE)
-#define PROBE_CPU_EBP_OFFSET (10 * PTR_SIZE)
-#define PROBE_CPU_ESP_OFFSET (11 * PTR_SIZE)
+#define PROBE_FIRST_GPR_OFFSET (3 * PTR_SIZE)
+#define PROBE_CPU_EAX_OFFSET (PROBE_FIRST_GPR_OFFSET + (0 * PTR_SIZE))
+#define PROBE_CPU_ECX_OFFSET (PROBE_FIRST_GPR_OFFSET + (1 * PTR_SIZE))
+#define PROBE_CPU_EDX_OFFSET (PROBE_FIRST_GPR_OFFSET + (2 * PTR_SIZE))
+#define PROBE_CPU_EBX_OFFSET (PROBE_FIRST_GPR_OFFSET + (3 * PTR_SIZE))
+#define PROBE_CPU_ESP_OFFSET (PROBE_FIRST_GPR_OFFSET + (4 * PTR_SIZE))
+#define PROBE_CPU_EBP_OFFSET (PROBE_FIRST_GPR_OFFSET + (5 * PTR_SIZE))
+#define PROBE_CPU_ESI_OFFSET (PROBE_FIRST_GPR_OFFSET + (6 * PTR_SIZE))
+#define PROBE_CPU_EDI_OFFSET (PROBE_FIRST_GPR_OFFSET + (7 * PTR_SIZE))
 
 #if CPU(X86)
-#define PROBE_FIRST_SPECIAL_OFFSET (12 * PTR_SIZE)
+#define PROBE_FIRST_SPECIAL_OFFSET (PROBE_FIRST_GPR_OFFSET + (8 * PTR_SIZE))
 #else // CPU(X86_64)
-#define PROBE_CPU_R8_OFFSET (12 * PTR_SIZE)
-#define PROBE_CPU_R9_OFFSET (13 * PTR_SIZE)
-#define PROBE_CPU_R10_OFFSET (14 * PTR_SIZE)
-#define PROBE_CPU_R11_OFFSET (15 * PTR_SIZE)
-#define PROBE_CPU_R12_OFFSET (16 * PTR_SIZE)
-#define PROBE_CPU_R13_OFFSET (17 * PTR_SIZE)
-#define PROBE_CPU_R14_OFFSET (18 * PTR_SIZE)
-#define PROBE_CPU_R15_OFFSET (19 * PTR_SIZE)
-#define PROBE_FIRST_SPECIAL_OFFSET (20 * PTR_SIZE)
+#define PROBE_CPU_R8_OFFSET (PROBE_FIRST_GPR_OFFSET + (8 * PTR_SIZE))
+#define PROBE_CPU_R9_OFFSET (PROBE_FIRST_GPR_OFFSET + (9 * PTR_SIZE))
+#define PROBE_CPU_R10_OFFSET (PROBE_FIRST_GPR_OFFSET + (10 * PTR_SIZE))
+#define PROBE_CPU_R11_OFFSET (PROBE_FIRST_GPR_OFFSET + (11 * PTR_SIZE))
+#define PROBE_CPU_R12_OFFSET (PROBE_FIRST_GPR_OFFSET + (12 * PTR_SIZE))
+#define PROBE_CPU_R13_OFFSET (PROBE_FIRST_GPR_OFFSET + (13 * PTR_SIZE))
+#define PROBE_CPU_R14_OFFSET (PROBE_FIRST_GPR_OFFSET + (14 * PTR_SIZE))
+#define PROBE_CPU_R15_OFFSET (PROBE_FIRST_GPR_OFFSET + (15 * PTR_SIZE))
+#define PROBE_FIRST_SPECIAL_OFFSET (PROBE_FIRST_GPR_OFFSET + (16 * PTR_SIZE))
 #endif // CPU(X86_64)
 
 #define PROBE_CPU_EIP_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (0 * PTR_SIZE))
 #define PROBE_CPU_EFLAGS_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (1 * PTR_SIZE))
+#define PROBE_FIRST_XMM_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (2 * PTR_SIZE))
 
-#if CPU(X86)
-#define PROBE_FIRST_XMM_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (4 * PTR_SIZE)) // After padding.
-#else // CPU(X86_64)
-#define PROBE_FIRST_XMM_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (2 * PTR_SIZE)) // After padding.
-#endif // CPU(X86_64)
-
-#define XMM_SIZE 16
+#define XMM_SIZE 8
 #define PROBE_CPU_XMM0_OFFSET (PROBE_FIRST_XMM_OFFSET + (0 * XMM_SIZE))
 #define PROBE_CPU_XMM1_OFFSET (PROBE_FIRST_XMM_OFFSET + (1 * XMM_SIZE))
 #define PROBE_CPU_XMM2_OFFSET (PROBE_FIRST_XMM_OFFSET + (2 * XMM_SIZE))
@@ -92,7 +88,19 @@ namespace JSC {
 #define PROBE_CPU_XMM6_OFFSET (PROBE_FIRST_XMM_OFFSET + (6 * XMM_SIZE))
 #define PROBE_CPU_XMM7_OFFSET (PROBE_FIRST_XMM_OFFSET + (7 * XMM_SIZE))
 
+#if CPU(X86)
 #define PROBE_SIZE (PROBE_CPU_XMM7_OFFSET + XMM_SIZE)
+#else // CPU(X86_64)
+#define PROBE_CPU_XMM8_OFFSET (PROBE_FIRST_XMM_OFFSET + (8 * XMM_SIZE))
+#define PROBE_CPU_XMM9_OFFSET (PROBE_FIRST_XMM_OFFSET + (9 * XMM_SIZE))
+#define PROBE_CPU_XMM10_OFFSET (PROBE_FIRST_XMM_OFFSET + (10 * XMM_SIZE))
+#define PROBE_CPU_XMM11_OFFSET (PROBE_FIRST_XMM_OFFSET + (11 * XMM_SIZE))
+#define PROBE_CPU_XMM12_OFFSET (PROBE_FIRST_XMM_OFFSET + (12 * XMM_SIZE))
+#define PROBE_CPU_XMM13_OFFSET (PROBE_FIRST_XMM_OFFSET + (13 * XMM_SIZE))
+#define PROBE_CPU_XMM14_OFFSET (PROBE_FIRST_XMM_OFFSET + (14 * XMM_SIZE))
+#define PROBE_CPU_XMM15_OFFSET (PROBE_FIRST_XMM_OFFSET + (15 * XMM_SIZE))
+#define PROBE_SIZE (PROBE_CPU_XMM15_OFFSET + XMM_SIZE)
+#endif // CPU(X86_64)
 
 // These ASSERTs remind you that if you change the layout of ProbeContext,
 // you need to change ctiMasmProbeTrampoline offsets above to match.
@@ -132,14 +140,22 @@ COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm5) == PROBE_CPU_XMM5_OFFSET, ProbeContext_c
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm6) == PROBE_CPU_XMM6_OFFSET, ProbeContext_cpu_xmm6_offset_matches_ctiMasmProbeTrampoline);
 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm7) == PROBE_CPU_XMM7_OFFSET, ProbeContext_cpu_xmm7_offset_matches_ctiMasmProbeTrampoline);
 
+#if CPU(X86_64)
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm8) == PROBE_CPU_XMM8_OFFSET, ProbeContext_cpu_xmm8_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm9) == PROBE_CPU_XMM9_OFFSET, ProbeContext_cpu_xmm9_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm10) == PROBE_CPU_XMM10_OFFSET, ProbeContext_cpu_xmm10_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm11) == PROBE_CPU_XMM11_OFFSET, ProbeContext_cpu_xmm11_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm12) == PROBE_CPU_XMM12_OFFSET, ProbeContext_cpu_xmm12_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm13) == PROBE_CPU_XMM13_OFFSET, ProbeContext_cpu_xmm13_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm14) == PROBE_CPU_XMM14_OFFSET, ProbeContext_cpu_xmm14_offset_matches_ctiMasmProbeTrampoline);
+COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm15) == PROBE_CPU_XMM15_OFFSET, ProbeContext_cpu_xmm15_offset_matches_ctiMasmProbeTrampoline);
+#endif // CPU(X86_64)
+
 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
 
-// Also double check that the xmm registers are 16 byte (128-bit) aligned as
-// required by the movdqa instruction used in the trampoline.
-COMPILE_ASSERT(!(PROBE_OFFSETOF(cpu.xmm0) % 16), ProbeContext_xmm0_offset_not_aligned_properly);
 #undef PROBE_OFFSETOF
 
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 #endif // COMPILER(GCC)
 
index 6fb434d256a5c6f028c4a8bddadb4d2aadee9223..21fbddbff7abde4dc2b74c18458ad3469d737e2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
  *
@@ -45,7 +45,7 @@ namespace JSC {
 
 #if COMPILER(GCC)
 
-#if USE(MASM_PROBE)
+#if ENABLE(MASM_PROBE)
 asm (
 ".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
 HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
@@ -104,14 +104,22 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     "movq %r14, " STRINGIZE_VALUE_OF(PROBE_CPU_R14_OFFSET) "(%rbp)" "\n"
     "movq %r15, " STRINGIZE_VALUE_OF(PROBE_CPU_R15_OFFSET) "(%rbp)" "\n"
 
-    "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp)" "\n"
-    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp)" "\n"
+    "movq %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp)" "\n"
+    "movq %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp)" "\n"
+    "movq %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp)" "\n"
+    "movq %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp)" "\n"
+    "movq %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp)" "\n"
+    "movq %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp)" "\n"
+    "movq %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp)" "\n"
+    "movq %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp)" "\n"
+    "movq %xmm8, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM8_OFFSET) "(%rbp)" "\n"
+    "movq %xmm9, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM9_OFFSET) "(%rbp)" "\n"
+    "movq %xmm10, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM10_OFFSET) "(%rbp)" "\n"
+    "movq %xmm11, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM11_OFFSET) "(%rbp)" "\n"
+    "movq %xmm12, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM12_OFFSET) "(%rbp)" "\n"
+    "movq %xmm13, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM13_OFFSET) "(%rbp)" "\n"
+    "movq %xmm14, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM14_OFFSET) "(%rbp)" "\n"
+    "movq %xmm15, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM15_OFFSET) "(%rbp)" "\n"
 
     "movq %rbp, %rdi" "\n" // the ProbeContext* arg.
     "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%rbp)" "\n"
@@ -133,14 +141,22 @@ SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R14_OFFSET) "(%rbp), %r14" "\n"
     "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R15_OFFSET) "(%rbp), %r15" "\n"
 
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp), %xmm0" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp), %xmm1" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp), %xmm2" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp), %xmm3" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp), %xmm4" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp), %xmm5" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp), %xmm6" "\n"
-    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp), %xmm7" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp), %xmm0" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp), %xmm1" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp), %xmm2" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp), %xmm3" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp), %xmm4" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp), %xmm5" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp), %xmm6" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp), %xmm7" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM8_OFFSET) "(%rbp), %xmm8" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM9_OFFSET) "(%rbp), %xmm9" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM10_OFFSET) "(%rbp), %xmm10" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM11_OFFSET) "(%rbp), %xmm11" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM12_OFFSET) "(%rbp), %xmm12" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM13_OFFSET) "(%rbp), %xmm13" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM14_OFFSET) "(%rbp), %xmm14" "\n"
+    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_XMM15_OFFSET) "(%rbp), %xmm15" "\n"
 
     // There are 6 more registers left to restore:
     //     rax, rcx, rbp, rsp, rip, and rflags.
@@ -209,7 +225,7 @@ SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n"
     "popq %rbp" "\n"
     "ret" "\n"
 );
-#endif // USE(MASM_PROBE)
+#endif // ENABLE(MASM_PROBE)
 
 #endif // COMPILER(GCC)
 
index a0694f533d3eb614c3b66fc21534007f331ca511..0a50a9054c7cad61d350fd2e2a423cefd2a9bd3c 100644 (file)
@@ -36,7 +36,7 @@
 namespace JSC {
 
 JITThunks::JITThunks()
-    : m_hostFunctionStubMap(adoptPtr(new HostFunctionStubMap))
+    : m_hostFunctionStubMap(std::make_unique<HostFunctionStubMap>())
 {
 }
 
@@ -76,6 +76,12 @@ MacroAssemblerCodeRef JITThunks::ctiStub(VM* vm, ThunkGenerator generator)
     return entry.iterator->value;
 }
 
+void JITThunks::finalize(Handle<Unknown> handle, void*)
+{
+    auto* nativeExecutable = jsCast<NativeExecutable*>(handle.get().asCell());
+    weakRemove(*m_hostFunctionStubMap, std::make_pair(nativeExecutable->function(), nativeExecutable->constructor()), nativeExecutable);
+}
+
 NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor)
 {
     ASSERT(!isCompilationThread());
@@ -89,36 +95,35 @@ NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, N
         function,
         adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), JITCode::HostCallThunk)),
         constructor, NoIntrinsic);
-    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, constructor), Weak<NativeExecutable>(nativeExecutable));
+    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, constructor), Weak<NativeExecutable>(nativeExecutable, this));
     return nativeExecutable;
 }
 
 NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
 {
     ASSERT(!isCompilationThread());    
+    ASSERT(vm->canUseJIT());
 
     if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, &callHostFunctionAsConstructor)))
         return nativeExecutable;
 
     RefPtr<JITCode> forCall;
     if (generator) {
-        if (vm->canUseJIT()) {
-            MacroAssemblerCodeRef entry = generator(vm);
-            forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk));
-        }
+        MacroAssemblerCodeRef entry = generator(vm);
+        forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk));
     } else
         forCall = adoptRef(new NativeJITCode(JIT::compileCTINativeCall(vm, function), JITCode::HostCallThunk));
     
     RefPtr<JITCode> forConstruct = adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), JITCode::HostCallThunk));
     
     NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall, function, forConstruct, callHostFunctionAsConstructor, intrinsic);
-    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, &callHostFunctionAsConstructor), Weak<NativeExecutable>(nativeExecutable));
+    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, &callHostFunctionAsConstructor), Weak<NativeExecutable>(nativeExecutable, this));
     return nativeExecutable;
 }
 
 void JITThunks::clearHostFunctionStubs()
 {
-    m_hostFunctionStubMap.clear();
+    m_hostFunctionStubMap = nullptr;
 }
 
 } // namespace JSC
index 9e28ecb85d96dfc4aa8fc7dc555ebf61665d9817..64a06b52a0a6f19e1c776547101307c0ec34a6db 100644 (file)
@@ -34,9 +34,9 @@
 #include "MacroAssemblerCodeRef.h"
 #include "ThunkGenerator.h"
 #include "Weak.h"
+#include "WeakHandleOwner.h"
 #include "WeakInlines.h"
 #include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/ThreadingPrimitives.h>
 
@@ -45,10 +45,11 @@ namespace JSC {
 class VM;
 class NativeExecutable;
 
-class JITThunks {
+class JITThunks final : private WeakHandleOwner {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
     JITThunks();
-    ~JITThunks();
+    virtual ~JITThunks();
 
     MacroAssemblerCodePtr ctiNativeCall(VM*);
     MacroAssemblerCodePtr ctiNativeConstruct(VM*);
@@ -65,11 +66,13 @@ private:
     // Main thread can hold this lock for a while, so use an adaptive mutex.
     typedef Mutex Lock;
     typedef MutexLocker Locker;
+
+    void finalize(Handle<Unknown>, void* context) override;
     
     typedef HashMap<ThunkGenerator, MacroAssemblerCodeRef> CTIStubMap;
     CTIStubMap m_ctiStubMap;
     typedef HashMap<std::pair<NativeFunction, NativeFunction>, Weak<NativeExecutable>> HostFunctionStubMap;
-    OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
+    std::unique_ptr<HostFunctionStubMap> m_hostFunctionStubMap;
     Lock m_lock;
 };
 
index 4786312def09b04f03a456bb6aee96c78b6d2a2a..f7f0ab9bc619a189005428481a18d3e103f274e2 100644 (file)
@@ -37,9 +37,9 @@ namespace JSC {
 JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback() { }
 JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback() { }
 
-PassRefPtr<JITToDFGDeferredCompilationCallback> JITToDFGDeferredCompilationCallback::create()
+Ref<JITToDFGDeferredCompilationCallback> JITToDFGDeferredCompilationCallback::create()
 {
-    return adoptRef(new JITToDFGDeferredCompilationCallback());
+    return adoptRef(*new JITToDFGDeferredCompilationCallback());
 }
 
 void JITToDFGDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
index 5a1c7ff1c52448d4dc92d25d22d4b709a1124e21..f64b979cecccd43932f32fd88d5b46b264b5811d 100644 (file)
@@ -42,7 +42,7 @@ protected:
 public:
     virtual ~JITToDFGDeferredCompilationCallback();
 
-    static PassRefPtr<JITToDFGDeferredCompilationCallback> create();
+    static Ref<JITToDFGDeferredCompilationCallback> create();
     
     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) override;
     virtual void compilationDidComplete(CodeBlock*, CompilationResult) override;
index 34c20db66d495f655283500ffda88b91a69cd915..b410ecadbc9f7f57b9084e74bd5a0998e61604cb 100644 (file)
@@ -31,6 +31,7 @@
 #include "MacroAssembler.h"
 #include "SlotVisitor.h"
 #include "UnusedPointer.h"
+#include "VM.h"
 #include "WriteBarrier.h"
 
 namespace JSC {
@@ -42,8 +43,7 @@ class VM;
 #define JITWriteBarrierFlag ((void*)2)
 class JITWriteBarrierBase {
 public:
-    typedef void* (JITWriteBarrierBase::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return get(); }
     bool operator!() const { return !get(); }
 
     void setFlagOnBarrier()
index 1e45f03004af79bb873c0fab6c77a0dadab02931..9c77118a8859c765c58cbf614aefa963e9306dd8 100644 (file)
@@ -50,9 +50,7 @@ namespace JSC {
         }
 
 #if USE(JSVALUE32_64)
-        // Can't just propogate JSValue::Int32Tag as visual studio doesn't like it
-        static const unsigned Int32Tag = 0xffffffff;
-        COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
+        static const unsigned Int32Tag = static_cast<unsigned>(JSValue::Int32Tag);
 #else
         static const unsigned Int32Tag = static_cast<unsigned>(TagTypeNumber >> 32);
 #endif
diff --git a/jit/PolymorphicCallStubRoutine.cpp b/jit/PolymorphicCallStubRoutine.cpp
new file mode 100644 (file)
index 0000000..6e55e63
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "PolymorphicCallStubRoutine.h"
+
+#if ENABLE(JIT)
+
+#include "CallLinkInfo.h"
+#include "CodeBlock.h"
+#include "JSCInlines.h"
+#include "LinkBuffer.h"
+
+namespace JSC {
+
+PolymorphicCallNode::~PolymorphicCallNode()
+{
+    if (isOnList())
+        remove();
+}
+
+void PolymorphicCallNode::unlink(RepatchBuffer& repatchBuffer)
+{
+    if (m_callLinkInfo) {
+        if (Options::showDisassembly())
+            dataLog("Unlinking polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n");
+
+        m_callLinkInfo->unlink(repatchBuffer);
+    }
+
+    if (isOnList())
+        remove();
+}
+
+void PolymorphicCallNode::clearCallLinkInfo()
+{
+    if (Options::showDisassembly())
+        dataLog("Clearing call link info for polymorphic call at ", m_callLinkInfo->callReturnLocation(), ", ", m_callLinkInfo->codeOrigin(), "\n");
+
+    m_callLinkInfo = nullptr;
+}
+
+void PolymorphicCallCase::dump(PrintStream& out) const
+{
+    out.print("<variant = ", m_variant, ", codeBlock = ", pointerDump(m_codeBlock), ">");
+}
+
+PolymorphicCallStubRoutine::PolymorphicCallStubRoutine(
+    const MacroAssemblerCodeRef& codeRef, VM& vm, const JSCell* owner, ExecState* callerFrame,
+    CallLinkInfo& info, const Vector<PolymorphicCallCase>& cases,
+    std::unique_ptr<uint32_t[]> fastCounts)
+    : GCAwareJITStubRoutine(codeRef, vm)
+    , m_fastCounts(WTF::move(fastCounts))
+{
+    for (PolymorphicCallCase callCase : cases) {
+        m_variants.append(WriteBarrier<JSCell>(vm, owner, callCase.variant().rawCalleeCell()));
+        if (shouldShowDisassemblyFor(callerFrame->codeBlock()))
+            dataLog("Linking polymorphic call in ", *callerFrame->codeBlock(), " at ", callerFrame->codeOrigin(), " to ", callCase.variant(), ", codeBlock = ", pointerDump(callCase.codeBlock()), "\n");
+        if (CodeBlock* codeBlock = callCase.codeBlock())
+            codeBlock->linkIncomingPolymorphicCall(callerFrame, m_callNodes.add(&info));
+    }
+    m_variants.shrinkToFit();
+    WTF::storeStoreFence();
+}
+
+PolymorphicCallStubRoutine::~PolymorphicCallStubRoutine() { }
+
+CallVariantList PolymorphicCallStubRoutine::variants() const
+{
+    CallVariantList result;
+    for (size_t i = 0; i < m_variants.size(); ++i)
+        result.append(CallVariant(m_variants[i].get()));
+    return result;
+}
+
+CallEdgeList PolymorphicCallStubRoutine::edges() const
+{
+    // We wouldn't have these if this was an FTL stub routine. We shouldn't be asking for profiling
+    // from the FTL.
+    RELEASE_ASSERT(m_fastCounts);
+    
+    CallEdgeList result;
+    for (size_t i = 0; i < m_variants.size(); ++i)
+        result.append(CallEdge(CallVariant(m_variants[i].get()), m_fastCounts[i]));
+    return result;
+}
+
+void PolymorphicCallStubRoutine::clearCallNodesFor(CallLinkInfo* info)
+{
+    for (Bag<PolymorphicCallNode>::iterator iter = m_callNodes.begin(); !!iter; ++iter) {
+        PolymorphicCallNode& node = **iter;
+        // All nodes should point to info, but okay to be a little paranoid.
+        if (node.hasCallLinkInfo(info))
+            node.clearCallLinkInfo();
+    }
+}
+
+bool PolymorphicCallStubRoutine::visitWeak(RepatchBuffer&)
+{
+    for (auto& variant : m_variants) {
+        if (!Heap::isMarked(variant.get()))
+            return false;
+    }
+    return true;
+}
+
+void PolymorphicCallStubRoutine::markRequiredObjectsInternal(SlotVisitor& visitor)
+{
+    for (auto& variant : m_variants)
+        visitor.append(&variant);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/jit/PolymorphicCallStubRoutine.h b/jit/PolymorphicCallStubRoutine.h
new file mode 100644 (file)
index 0000000..31492b6
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef PolymorphicCallStubRoutine_h
+#define PolymorphicCallStubRoutine_h
+
+#if ENABLE(JIT)
+
+#include "CallEdge.h"
+#include "CallVariant.h"
+#include "CodeOrigin.h"
+#include "GCAwareJITStubRoutine.h"
+#include <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CallLinkInfo;
+
+class PolymorphicCallNode : public BasicRawSentinelNode<PolymorphicCallNode> {
+    WTF_MAKE_NONCOPYABLE(PolymorphicCallNode);
+public:
+    PolymorphicCallNode(CallLinkInfo* info)
+        : m_callLinkInfo(info)
+    {
+    }
+    
+    ~PolymorphicCallNode();
+    
+    void unlink(RepatchBuffer&);
+
+    bool hasCallLinkInfo(CallLinkInfo* info) { return m_callLinkInfo == info; }
+    void clearCallLinkInfo();
+    
+private:
+    CallLinkInfo* m_callLinkInfo;
+};
+
+class PolymorphicCallCase {
+public:
+    PolymorphicCallCase()
+        : m_codeBlock(nullptr)
+    {
+    }
+    
+    PolymorphicCallCase(CallVariant variant, CodeBlock* codeBlock)
+        : m_variant(variant)
+        , m_codeBlock(codeBlock)
+    {
+    }
+    
+    CallVariant variant() const { return m_variant; }
+    CodeBlock* codeBlock() const { return m_codeBlock; }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    CallVariant m_variant;
+    CodeBlock* m_codeBlock;
+};
+
+class PolymorphicCallStubRoutine : public GCAwareJITStubRoutine {
+public:
+    PolymorphicCallStubRoutine(
+        const MacroAssemblerCodeRef&, VM&, const JSCell* owner,
+        ExecState* callerFrame, CallLinkInfo&, const Vector<PolymorphicCallCase>&,
+        std::unique_ptr<uint32_t[]> fastCounts);
+    
+    virtual ~PolymorphicCallStubRoutine();
+    
+    CallVariantList variants() const;
+    CallEdgeList edges() const;
+
+    void clearCallNodesFor(CallLinkInfo*);
+    
+    bool visitWeak(RepatchBuffer&) override;
+
+protected:
+    virtual void markRequiredObjectsInternal(SlotVisitor&) override;
+
+private:
+    Vector<WriteBarrier<JSCell>, 2> m_variants;
+    std::unique_ptr<uint32_t[]> m_fastCounts;
+    Bag<PolymorphicCallNode> m_callNodes;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // PolymorphicCallStubRoutine_h
+
index f93d99d70a119b92bce2528e7b6f427eb120eb40..6302e261d15c73e1f48339886fac79905bd2cb1c 100644 (file)
@@ -86,6 +86,18 @@ RegisterSet RegisterSet::calleeSaveRegisters()
     result.set(ARMRegisters::r5);
     result.set(ARMRegisters::r6);
     result.set(ARMRegisters::r8);
+#if !PLATFORM(IOS)
+    result.set(ARMRegisters::r9);
+#endif
+    result.set(ARMRegisters::r10);
+    result.set(ARMRegisters::r11);
+#elif CPU(ARM_TRADITIONAL)
+    result.set(ARMRegisters::r4);
+    result.set(ARMRegisters::r5);
+    result.set(ARMRegisters::r6);
+    result.set(ARMRegisters::r7);
+    result.set(ARMRegisters::r8);
+    result.set(ARMRegisters::r9);
     result.set(ARMRegisters::r10);
     result.set(ARMRegisters::r11);
 #elif CPU(ARM64)
index dbc7d6617dda1f97092a9704f46a364d2ea4eb91..5d4b44b16c26d59365ac4ff2e3132c17f6723de1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(JIT)
 
 #include "AccessorCallJITStubRoutine.h"
+#include "BinarySwitch.h"
 #include "CCallHelpers.h"
 #include "DFGOperations.h"
 #include "DFGSpeculativeJIT.h"
@@ -48,6 +49,8 @@
 #include "StructureRareDataInlines.h"
 #include "StructureStubClearingWatchpoint.h"
 #include "ThunkGenerators.h"
+#include <wtf/CommaPrinter.h>
+#include <wtf/ListDump.h>
 #include <wtf/StringPrintStream.h>
 
 namespace JSC {
@@ -97,12 +100,14 @@ static void repatchCall(CodeBlock* codeblock, CodeLocationCall call, FunctionPtr
     repatchCall(repatchBuffer, call, newCalleeFunction);
 }
 
-static void repatchByIdSelfAccess(VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, const Identifier& propertyName, PropertyOffset offset,
-    const FunctionPtr &slowPathFunction, bool compact)
+static void repatchByIdSelfAccess(
+    VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure,
+    const Identifier& propertyName, PropertyOffset offset, const FunctionPtr &slowPathFunction,
+    bool compact)
 {
     if (structure->typeInfo().newImpurePropertyFiresWatchpoints())
         vm.registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
-
+    
     RepatchBuffer repatchBuffer(codeBlock);
 
     // Only optimize once!
@@ -226,6 +231,7 @@ static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratc
 
 enum ByIdStubKind {
     GetValue,
+    GetUndefined,
     CallGetter,
     CallCustomGetter,
     CallSetter,
@@ -237,6 +243,8 @@ static const char* toString(ByIdStubKind kind)
     switch (kind) {
     case GetValue:
         return "GetValue";
+    case GetUndefined:
+        return "GetUndefined";
     case CallGetter:
         return "CallGetter";
     case CallCustomGetter:
@@ -255,6 +263,8 @@ static ByIdStubKind kindFor(const PropertySlot& slot)
 {
     if (slot.isCacheableValue())
         return GetValue;
+    if (slot.isUnset())
+        return GetUndefined;
     if (slot.isCacheableCustom())
         return CallCustomGetter;
     RELEASE_ASSERT(slot.isCacheableGetter());
@@ -284,12 +294,13 @@ static FunctionPtr customFor(const PutPropertySlot& slot)
     return FunctionPtr(slot.customSetter());
 }
 
-static void generateByIdStub(
+static bool generateByIdStub(
     ExecState* exec, ByIdStubKind kind, const Identifier& propertyName,
     FunctionPtr custom, StructureStubInfo& stubInfo, StructureChain* chain, size_t count,
     PropertyOffset offset, Structure* structure, bool loadTargetFromProxy, WatchpointSet* watchpointSet,
     CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, RefPtr<JITStubRoutine>& stubRoutine)
 {
+
     VM* vm = &exec->vm();
     GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR);
     JSValueRegs valueRegs = JSValueRegs(
@@ -299,7 +310,7 @@ static void generateByIdStub(
         static_cast<GPRReg>(stubInfo.patch.valueGPR));
     GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
     bool needToRestoreScratch = scratchGPR == InvalidGPRReg;
-    RELEASE_ASSERT(!needToRestoreScratch || kind == GetValue);
+    RELEASE_ASSERT(!needToRestoreScratch || (kind == GetValue || kind == GetUndefined));
     
     CCallHelpers stubJit(&exec->vm(), exec->codeBlock());
     if (needToRestoreScratch) {
@@ -341,7 +352,7 @@ static void generateByIdStub(
     if (watchpointSet)
         watchpointSet->add(stubInfo.addWatchpoint(codeBlock));
 
-    Structure* currStructure = structure;
+    Structure* currStructure = structure; 
     JSObject* protoObject = 0;
     if (chain) {
         WriteBarrier<Structure>* it = chain->head();
@@ -355,26 +366,32 @@ static void generateByIdStub(
                 failureCases, scratchGPR);
             currStructure = it->get();
         }
+        ASSERT(!protoObject || protoObject->structure() == currStructure);
     }
     
-    GPRReg baseForAccessGPR;
-    if (chain) {
-        // We could have clobbered scratchGPR earlier, so we have to reload from baseGPR to get the target.
-        if (loadTargetFromProxy)
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSProxy::targetOffset()), baseForGetGPR);
-        stubJit.move(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR);
-        baseForAccessGPR = scratchGPR;
-    } else {
-        // For proxy objects, we need to do all the Structure checks before moving the baseGPR into 
-        // baseForGetGPR because if we fail any of the checks then we would have the wrong value in baseGPR
-        // on the slow path.
-        if (loadTargetFromProxy)
-            stubJit.move(scratchGPR, baseForGetGPR);
-        baseForAccessGPR = baseForGetGPR;
+    currStructure->startWatchingPropertyForReplacements(*vm, offset);
+    GPRReg baseForAccessGPR = InvalidGPRReg;
+    if (kind != GetUndefined) {
+        if (chain) {
+            // We could have clobbered scratchGPR earlier, so we have to reload from baseGPR to get the target.
+            if (loadTargetFromProxy)
+                stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSProxy::targetOffset()), baseForGetGPR);
+            stubJit.move(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR);
+            baseForAccessGPR = scratchGPR;
+        } else {
+            // For proxy objects, we need to do all the Structure checks before moving the baseGPR into
+            // baseForGetGPR because if we fail any of the checks then we would have the wrong value in baseGPR
+            // on the slow path.
+            if (loadTargetFromProxy)
+                stubJit.move(scratchGPR, baseForGetGPR);
+            baseForAccessGPR = baseForGetGPR;
+        }
     }
 
     GPRReg loadedValueGPR = InvalidGPRReg;
-    if (kind != CallCustomGetter && kind != CallCustomSetter) {
+    if (kind == GetUndefined)
+        stubJit.moveTrustedValue(jsUndefined(), valueRegs);
+    else if (kind != CallCustomGetter && kind != CallCustomSetter) {
         if (kind == GetValue)
             loadedValueGPR = valueRegs.payloadGPR();
         else
@@ -408,7 +425,7 @@ static void generateByIdStub(
     std::unique_ptr<CallLinkInfo> callLinkInfo;
 
     MacroAssembler::Jump success, fail;
-    if (kind != GetValue) {
+    if (kind != GetValue && kind != GetUndefined) {
         // Need to make sure that whenever this call is made in the future, we remember the
         // place that we made it from. It just so happens to be the place that we are at
         // right now!
@@ -431,9 +448,7 @@ static void generateByIdStub(
             // shrink it after.
             
             callLinkInfo = std::make_unique<CallLinkInfo>();
-            callLinkInfo->callType = CallLinkInfo::Call;
-            callLinkInfo->codeOrigin = stubInfo.codeOrigin;
-            callLinkInfo->calleeGPR = loadedValueGPR;
+            callLinkInfo->setUpCall(CallLinkInfo::Call, stubInfo.codeOrigin, loadedValueGPR);
             
             MacroAssembler::JumpList done;
             
@@ -497,13 +512,6 @@ static void generateByIdStub(
                 MacroAssembler::NotEqual, loadedValueGPR, addressOfLinkFunctionCheck,
                 MacroAssembler::TrustedImmPtr(0));
             
-            // loadedValueGPR is already burned. We can reuse it. From here on we assume that
-            // any volatile register will be clobbered anyway.
-            stubJit.loadPtr(
-                MacroAssembler::Address(loadedValueGPR, JSFunction::offsetOfScopeChain()),
-                loadedValueGPR);
-            stubJit.storeCell(
-                loadedValueGPR, calleeFrame.withOffset(JSStack::ScopeChain * sizeof(Register)));
             fastPathCall = stubJit.nearCall();
             
             stubJit.addPtr(
@@ -565,16 +573,18 @@ static void generateByIdStub(
     }
     emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
     
-    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock());
+    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock(), JITCompilationCanFail);
+    if (patchBuffer.didFailToAllocate())
+        return false;
     
     linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
     if (kind == CallCustomGetter || kind == CallCustomSetter) {
         patchBuffer.link(operationCall, custom);
         patchBuffer.link(handlerCall, lookupExceptionHandler);
     } else if (kind == CallGetter || kind == CallSetter) {
-        callLinkInfo->hotPathOther = patchBuffer.locationOfNearCall(fastPathCall);
-        callLinkInfo->hotPathBegin = patchBuffer.locationOf(addressOfLinkFunctionCheck);
-        callLinkInfo->callReturnLocation = patchBuffer.locationOfNearCall(slowPathCall);
+        callLinkInfo->setCallLocations(patchBuffer.locationOfNearCall(slowPathCall),
+            patchBuffer.locationOf(addressOfLinkFunctionCheck),
+            patchBuffer.locationOfNearCall(fastPathCall));
 
         ThunkGenerator generator = linkThunkGeneratorFor(
             CodeForCall, RegisterPreservationNotRequired);
@@ -592,6 +602,8 @@ static void generateByIdStub(
         stubRoutine = adoptRef(new AccessorCallJITStubRoutine(code, *vm, WTF::move(callLinkInfo)));
     else
         stubRoutine = createJITStubRoutine(code, *vm, codeBlock->ownerExecutable(), true);
+    
+    return true;
 }
 
 enum InlineCacheAction {
@@ -634,7 +646,7 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
     CodeBlock* codeBlock = exec->codeBlock();
     VM* vm = &exec->vm();
 
-    if ((isJSArray(baseValue) || isRegExpMatchesArray(baseValue) || isJSString(baseValue)) && propertyName == exec->propertyNames().length) {
+    if ((isJSArray(baseValue) || isJSString(baseValue)) && propertyName == exec->propertyNames().length) {
         GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR);
 #if USE(JSVALUE32_64)
         GPRReg resultTagGPR = static_cast<GPRReg>(stubInfo.patch.valueTagGPR);
@@ -643,7 +655,7 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
 
         MacroAssembler stubJit;
 
-        if (isJSArray(baseValue) || isRegExpMatchesArray(baseValue)) {
+        if (isJSArray(baseValue)) {
             GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
             bool needToRestoreScratch = false;
 
@@ -671,14 +683,16 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
 #if USE(JSVALUE64)
             stubJit.or64(AssemblyHelpers::TrustedImm64(TagTypeNumber), resultGPR);
 #elif USE(JSVALUE32_64)
-            stubJit.move(AssemblyHelpers::TrustedImm32(0xffffffff), resultTagGPR); // JSValue::Int32Tag
+            stubJit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), resultTagGPR);
 #endif
 
             MacroAssembler::Jump success, fail;
 
             emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
             
-            LinkBuffer patchBuffer(*vm, stubJit, codeBlock);
+            LinkBuffer patchBuffer(*vm, stubJit, codeBlock, JITCompilationCanFail);
+            if (patchBuffer.didFailToAllocate())
+                return GiveUpOnCache;
 
             linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
 
@@ -703,13 +717,15 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
 #if USE(JSVALUE64)
         stubJit.or64(AssemblyHelpers::TrustedImm64(TagTypeNumber), resultGPR);
 #elif USE(JSVALUE32_64)
-        stubJit.move(AssemblyHelpers::TrustedImm32(0xffffffff), resultTagGPR); // JSValue::Int32Tag
+        stubJit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), resultTagGPR);
 #endif
 
         MacroAssembler::Jump success = stubJit.jump();
 
-        LinkBuffer patchBuffer(*vm, stubJit, codeBlock);
-
+        LinkBuffer patchBuffer(*vm, stubJit, codeBlock, JITCompilationCanFail);
+        if (patchBuffer.didFailToAllocate())
+            return GiveUpOnCache;
+        
         patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
         patchBuffer.link(failure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
 
@@ -729,23 +745,26 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
     // FIXME: Cache property access for immediates.
     if (!baseValue.isCell())
         return GiveUpOnCache;
-    JSCell* baseCell = baseValue.asCell();
-    Structure* structure = baseCell->structure();
-    if (!slot.isCacheable())
+
+    if (!slot.isCacheable() && !slot.isUnset())
         return GiveUpOnCache;
 
+    JSCell* baseCell = baseValue.asCell();
+    Structure* structure = baseCell->structure(*vm);
+
     InlineCacheAction action = actionForCell(*vm, baseCell);
     if (action != AttemptToCache)
         return action;
 
     // Optimize self access.
-    if (slot.slotBase() == baseValue
-        && slot.isCacheableValue()
+    if (slot.isCacheableValue()
+        && slot.slotBase() == baseValue
         && !slot.watchpointSet()
         && MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))) {
-            repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, propertyName, slot.cachedOffset(), operationGetByIdBuildList, true);
-            stubInfo.initGetByIdSelf(*vm, codeBlock->ownerExecutable(), structure);
-            return RetryCacheLater;
+        structure->startWatchingPropertyForReplacements(*vm, slot.cachedOffset());
+        repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, propertyName, slot.cachedOffset(), operationGetByIdBuildList, true);
+        stubInfo.initGetByIdSelf(*vm, codeBlock->ownerExecutable(), structure);
+        return RetryCacheLater;
     }
 
     repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdBuildList);
@@ -778,7 +797,7 @@ static void patchJumpToGetByIdStub(CodeBlock* codeBlock, StructureStubInfo& stub
 static InlineCacheAction tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier& ident, const PropertySlot& slot, StructureStubInfo& stubInfo)
 {
     if (!baseValue.isCell()
-        || !slot.isCacheable())
+        || (!slot.isCacheable() && !slot.isUnset()))
         return GiveUpOnCache;
 
     JSCell* baseCell = baseValue.asCell();
@@ -803,20 +822,23 @@ static InlineCacheAction tryBuildGetByIDList(ExecState* exec, JSValue baseValue,
         // We cannot do as much inline caching if the registers were not flushed prior to this GetById. In particular,
         // non-Value cached properties require planting calls, which requires registers to have been flushed. Thus,
         // if registers were not flushed, don't do non-Value caching.
-        if (!slot.isCacheableValue())
+        if (!slot.isCacheableValue() && !slot.isUnset())
             return GiveUpOnCache;
     }
-    
-    PropertyOffset offset = slot.cachedOffset();
+
+    PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset();
     StructureChain* prototypeChain = 0;
     size_t count = 0;
     
-    if (slot.slotBase() != baseValue) {
+    if (slot.isUnset() || slot.slotBase() != baseValue) {
         if (typeInfo.prohibitsPropertyCaching() || structure->isDictionary())
             return GiveUpOnCache;
-        
-        count = normalizePrototypeChainForChainAccess(
-            exec, baseValue, slot.slotBase(), ident, offset);
+
+        if (slot.isUnset())
+            count = normalizePrototypeChain(exec, structure);
+        else
+            count = normalizePrototypeChainForChainAccess(
+                exec, structure, slot.slotBase(), ident, offset);
         if (count == InvalidPrototypeChain)
             return GiveUpOnCache;
         prototypeChain = structure->prototypeChain(exec);
@@ -829,15 +851,19 @@ static InlineCacheAction tryBuildGetByIDList(ExecState* exec, JSValue baseValue,
     }
     
     RefPtr<JITStubRoutine> stubRoutine;
-    generateByIdStub(
+    bool result = generateByIdStub(
         exec, kindFor(slot), ident, customFor(slot), stubInfo, prototypeChain, count, offset, 
         structure, loadTargetFromProxy, slot.watchpointSet(), 
         stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
         CodeLocationLabel(list->currentSlowPathTarget(stubInfo)), stubRoutine);
+    if (!result)
+        return GiveUpOnCache;
     
     GetByIdAccess::AccessType accessType;
     if (slot.isCacheableValue())
         accessType = slot.watchpointSet() ? GetByIdAccess::WatchedStub : GetByIdAccess::SimpleStub;
+    else if (slot.isUnset())
+        accessType = GetByIdAccess::SimpleMiss;
     else if (slot.isCacheableGetter())
         accessType = GetByIdAccess::Getter;
     else
@@ -884,13 +910,11 @@ static V_JITOperation_ESsiJJI appropriateListBuildingPutByIdFunction(const PutPr
     return operationPutByIdNonStrictBuildList;
 }
 
-static void emitPutReplaceStub(
+static bool emitPutReplaceStub(
     ExecState* exec,
-    JSValue,
     const Identifier&,
     const PutPropertySlot& slot,
     StructureStubInfo& stubInfo,
-    PutKind,
     Structure* structure,
     CodeLocationLabel failureLabel,
     RefPtr<JITStubRoutine>& stubRoutine)
@@ -953,7 +977,10 @@ static void emitPutReplaceStub(
         failure = badStructure;
     }
     
-    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock());
+    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock(), JITCompilationCanFail);
+    if (patchBuffer.didFailToAllocate())
+        return false;
+    
     patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
     patchBuffer.link(failure, failureLabel);
             
@@ -962,22 +989,48 @@ static void emitPutReplaceStub(
         ("PutById replace stub for %s, return point %p",
             toCString(*exec->codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
                 stubInfo.patch.deltaCallToDone).executableAddress()));
+    
+    return true;
 }
 
-static void emitPutTransitionStub(
-    ExecState* exec,
-    JSValue,
-    const Identifier&,
-    const PutPropertySlot& slot,
-    StructureStubInfo& stubInfo,
-    PutKind putKind,
-    Structure* structure,
-    Structure* oldStructure,
-    StructureChain* prototypeChain,
-    CodeLocationLabel failureLabel,
-    RefPtr<JITStubRoutine>& stubRoutine)
+static Structure* emitPutTransitionStubAndGetOldStructure(ExecState* exec, VM* vm, Structure*& structure, const Identifier& ident, 
+    const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
 {
-    VM* vm = &exec->vm();
+    PropertyName pname(ident);
+    Structure* oldStructure = structure;
+    if (!oldStructure->isObject() || oldStructure->isDictionary() || parseIndex(pname))
+        return nullptr;
+
+    PropertyOffset propertyOffset;
+    structure = Structure::addPropertyTransitionToExistingStructureConcurrently(oldStructure, ident.impl(), 0, propertyOffset);
+
+    if (!structure || !structure->isObject() || structure->isDictionary() || !structure->propertyAccessesAreCacheable())
+        return nullptr;
+
+    // Skip optimizing the case where we need a realloc, if we don't have
+    // enough registers to make it happen.
+    if (GPRInfo::numberOfRegisters < 6
+        && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()
+        && oldStructure->outOfLineCapacity()) {
+        return nullptr;
+    }
+
+    // Skip optimizing the case where we need realloc, and the structure has
+    // indexing storage.
+    // FIXME: We shouldn't skip this! Implement it!
+    // https://bugs.webkit.org/show_bug.cgi?id=130914
+    if (oldStructure->couldHaveIndexingHeader())
+        return nullptr;
+
+    if (normalizePrototypeChain(exec, structure) == InvalidPrototypeChain)
+        return nullptr;
+
+    StructureChain* prototypeChain = structure->prototypeChain(exec);
+
+    // emitPutTransitionStub
+
+    CodeLocationLabel failureLabel = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
+    RefPtr<JITStubRoutine>& stubRoutine = stubInfo.stubRoutine;
 
     GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR);
 #if USE(JSVALUE32_64)
@@ -1108,6 +1161,38 @@ static void emitPutTransitionStub(
     }
 #endif
     
+    ScratchBuffer* scratchBuffer = nullptr;
+
+#if ENABLE(GGC)
+    MacroAssembler::Call callFlushWriteBarrierBuffer;
+    MacroAssembler::Jump ownerIsRememberedOrInEden = stubJit.jumpIfIsRememberedOrInEden(baseGPR);
+    {
+        WriteBarrierBuffer& writeBarrierBuffer = stubJit.vm()->heap.writeBarrierBuffer();
+        stubJit.load32(writeBarrierBuffer.currentIndexAddress(), scratchGPR2);
+        MacroAssembler::Jump needToFlush =
+            stubJit.branch32(MacroAssembler::AboveOrEqual, scratchGPR2, MacroAssembler::TrustedImm32(writeBarrierBuffer.capacity()));
+
+        stubJit.add32(MacroAssembler::TrustedImm32(1), scratchGPR2);
+        stubJit.store32(scratchGPR2, writeBarrierBuffer.currentIndexAddress());
+
+        stubJit.move(MacroAssembler::TrustedImmPtr(writeBarrierBuffer.buffer()), scratchGPR1);
+        // We use an offset of -sizeof(void*) because we already added 1 to scratchGPR2.
+        stubJit.storePtr(baseGPR, MacroAssembler::BaseIndex(scratchGPR1, scratchGPR2, MacroAssembler::ScalePtr, static_cast<int32_t>(-sizeof(void*))));
+
+        MacroAssembler::Jump doneWithBarrier = stubJit.jump();
+        needToFlush.link(&stubJit);
+
+        scratchBuffer = vm->scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
+        allocator.preserveUsedRegistersToScratchBufferForCall(stubJit, scratchBuffer, scratchGPR2);
+        stubJit.setupArgumentsWithExecState(baseGPR);
+        callFlushWriteBarrierBuffer = stubJit.call();
+        allocator.restoreUsedRegistersFromScratchBufferForCall(stubJit, scratchBuffer, scratchGPR2);
+
+        doneWithBarrier.link(&stubJit);
+    }
+    ownerIsRememberedOrInEden.link(&stubJit);
+#endif
+
     MacroAssembler::Jump success;
     MacroAssembler::Jump failure;
             
@@ -1128,7 +1213,8 @@ static void emitPutTransitionStub(
         slowPath.link(&stubJit);
         
         allocator.restoreReusedRegistersByPopping(stubJit);
-        ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
+        if (!scratchBuffer)
+            scratchBuffer = vm->scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
         allocator.preserveUsedRegistersToScratchBufferForCall(stubJit, scratchBuffer, scratchGPR1);
 #if USE(JSVALUE64)
         stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR);
@@ -1140,12 +1226,18 @@ static void emitPutTransitionStub(
         successInSlowPath = stubJit.jump();
     }
     
-    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock());
+    LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock(), JITCompilationCanFail);
+    if (patchBuffer.didFailToAllocate())
+        return nullptr;
+    
     patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
     if (allocator.didReuseRegisters())
         patchBuffer.link(failure, failureLabel);
     else
         patchBuffer.link(failureCases, failureLabel);
+#if ENABLE(GGC)
+    patchBuffer.link(callFlushWriteBarrierBuffer, operationFlushWriteBarrierBuffer);
+#endif
     if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) {
         patchBuffer.link(operationCall, operationReallocateStorageAndFinishPut);
         patchBuffer.link(successInSlowPath, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
@@ -1164,9 +1256,11 @@ static void emitPutTransitionStub(
             exec->codeBlock()->ownerExecutable(),
             structure->outOfLineCapacity() != oldStructure->outOfLineCapacity(),
             structure);
+
+    return oldStructure;
 }
 
-static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
 {
     if (Options::forceICFailure())
         return GiveUpOnCache;
@@ -1176,46 +1270,23 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, con
 
     if (!baseValue.isCell())
         return GiveUpOnCache;
-    JSCell* baseCell = baseValue.asCell();
-    Structure* structure = baseCell->structure();
-    Structure* oldStructure = structure->previousID();
     
     if (!slot.isCacheablePut() && !slot.isCacheableCustom() && !slot.isCacheableSetter())
         return GiveUpOnCache;
+
     if (!structure->propertyAccessesAreCacheable())
         return GiveUpOnCache;
 
     // Optimize self access.
     if (slot.base() == baseValue && slot.isCacheablePut()) {
         if (slot.type() == PutPropertySlot::NewProperty) {
-            if (structure->isDictionary())
-                return GiveUpOnCache;
-            
-            // Skip optimizing the case where we need a realloc, if we don't have
-            // enough registers to make it happen.
-            if (GPRInfo::numberOfRegisters < 6
-                && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()
-                && oldStructure->outOfLineCapacity())
-                return GiveUpOnCache;
-            
-            // Skip optimizing the case where we need realloc, and the structure has
-            // indexing storage.
-            // FIXME: We shouldn't skip this!  Implement it!
-            // https://bugs.webkit.org/show_bug.cgi?id=130914
-            if (oldStructure->couldHaveIndexingHeader())
-                return GiveUpOnCache;
-            
-            if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)
+
+            Structure* oldStructure = emitPutTransitionStubAndGetOldStructure(exec, vm, structure, ident, slot, stubInfo, putKind);
+            if (!oldStructure)
                 return GiveUpOnCache;
             
             StructureChain* prototypeChain = structure->prototypeChain(exec);
             
-            emitPutTransitionStub(
-                exec, baseValue, ident, slot, stubInfo, putKind,
-                structure, oldStructure, prototypeChain,
-                stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase),
-                stubInfo.stubRoutine);
-            
             RepatchBuffer repatchBuffer(codeBlock);
             repatchBuffer.relink(
                 stubInfo.callReturnLocation.jumpAtOffset(
@@ -1231,10 +1302,12 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, con
         if (!MacroAssembler::isPtrAlignedAddressOffset(offsetRelativeToPatchedStorage(slot.cachedOffset())))
             return GiveUpOnCache;
 
+        structure->didCachePropertyReplacement(*vm, slot.cachedOffset());
         repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, ident, slot.cachedOffset(), appropriateListBuildingPutByIdFunction(slot, putKind), false);
         stubInfo.initPutByIdReplace(*vm, codeBlock->ownerExecutable(), structure);
         return RetryCacheLater;
     }
+
     if ((slot.isCacheableCustom() || slot.isCacheableSetter())
         && stubInfo.patch.spillMode == DontSpill) {
         RefPtr<JITStubRoutine> stubRoutine;
@@ -1243,26 +1316,27 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, con
         PropertyOffset offset = slot.cachedOffset();
         size_t count = 0;
         if (baseValue != slot.base()) {
-            count = normalizePrototypeChainForChainAccess(exec, baseCell, slot.base(), ident, offset);
+            count = normalizePrototypeChainForChainAccess(exec, structure, slot.base(), ident, offset);
             if (count == InvalidPrototypeChain)
                 return GiveUpOnCache;
-
             prototypeChain = structure->prototypeChain(exec);
         }
         PolymorphicPutByIdList* list;
         list = PolymorphicPutByIdList::from(putKind, stubInfo);
 
-        generateByIdStub(
+        bool result = generateByIdStub(
             exec, kindFor(slot), ident, customFor(slot), stubInfo, prototypeChain, count,
             offset, structure, false, nullptr,
             stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
             stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase),
             stubRoutine);
-
+        if (!result)
+            return GiveUpOnCache;
+        
         list->addAccess(PutByIdAccess::setter(
             *vm, codeBlock->ownerExecutable(),
             slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
-            structure, prototypeChain, slot.customSetter(), stubRoutine));
+            structure, prototypeChain, count, slot.customSetter(), stubRoutine));
 
         RepatchBuffer repatchBuffer(codeBlock);
         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine->code().code()));
@@ -1274,26 +1348,22 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, con
     return GiveUpOnCache;
 }
 
-void repatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+void repatchPutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
 {
     GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap);
     
-    if (tryCachePutByID(exec, baseValue, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
+    if (tryCachePutByID(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
         repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
 }
 
-static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
 {
     CodeBlock* codeBlock = exec->codeBlock();
     VM* vm = &exec->vm();
 
     if (!baseValue.isCell())
         return GiveUpOnCache;
-    JSCell* baseCell = baseValue.asCell();
-    Structure* structure = baseCell->structure();
-    Structure* oldStructure = structure->previousID();
-    
-    
+
     if (!slot.isCacheablePut() && !slot.isCacheableCustom() && !slot.isCacheableSetter())
         return GiveUpOnCache;
 
@@ -1306,64 +1376,47 @@ static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue,
         RefPtr<JITStubRoutine> stubRoutine;
         
         if (slot.type() == PutPropertySlot::NewProperty) {
-            if (structure->isDictionary())
-                return GiveUpOnCache;
-            
-            // Skip optimizing the case where we need a realloc, if we don't have
-            // enough registers to make it happen.
-            if (GPRInfo::numberOfRegisters < 6
-                && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()
-                && oldStructure->outOfLineCapacity())
-                return GiveUpOnCache;
-            
-            // Skip optimizing the case where we need realloc, and the structure has
-            // indexing storage.
-            if (oldStructure->couldHaveIndexingHeader())
-                return GiveUpOnCache;
-            
-            if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)
-                return GiveUpOnCache;
-            
-            StructureChain* prototypeChain = structure->prototypeChain(exec);
-            
             list = PolymorphicPutByIdList::from(putKind, stubInfo);
             if (list->isFull())
                 return GiveUpOnCache; // Will get here due to recursion.
-            
-            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
-            emitPutTransitionStub(
-                exec, baseValue, propertyName, slot, stubInfo, putKind,
-                structure, oldStructure, prototypeChain,
-                CodeLocationLabel(list->currentSlowPathTarget()),
-                stubRoutine);
-            
+
+            Structure* oldStructure = emitPutTransitionStubAndGetOldStructure(exec, vm, structure, propertyName, slot, stubInfo, putKind);
+
+            if (!oldStructure) 
+                return GiveUpOnCache;
+
+            StructureChain* prototypeChain = structure->prototypeChain(exec);
+            stubRoutine = stubInfo.stubRoutine;
             list->addAccess(
                 PutByIdAccess::transition(
                     *vm, codeBlock->ownerExecutable(),
                     oldStructure, structure, prototypeChain,
                     stubRoutine));
+
         } else {
             list = PolymorphicPutByIdList::from(putKind, stubInfo);
             if (list->isFull())
                 return GiveUpOnCache; // Will get here due to recursion.
             
+            structure->didCachePropertyReplacement(*vm, slot.cachedOffset());
+            
             // We're now committed to creating the stub. Mogrify the meta-data accordingly.
-            emitPutReplaceStub(
-                exec, baseValue, propertyName, slot, stubInfo, putKind,
+            bool result = emitPutReplaceStub(
+                exec, propertyName, slot, stubInfo, 
                 structure, CodeLocationLabel(list->currentSlowPathTarget()), stubRoutine);
+            if (!result)
+                return GiveUpOnCache;
             
             list->addAccess(
                 PutByIdAccess::replace(
                     *vm, codeBlock->ownerExecutable(),
                     structure, stubRoutine));
         }
-        
         RepatchBuffer repatchBuffer(codeBlock);
         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine->code().code()));
-        
         if (list->isFull())
             repatchCall(repatchBuffer, stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
-        
+
         return RetryCacheLater;
     }
 
@@ -1374,26 +1427,28 @@ static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue,
         PropertyOffset offset = slot.cachedOffset();
         size_t count = 0;
         if (baseValue != slot.base()) {
-            count = normalizePrototypeChainForChainAccess(exec, baseCell, slot.base(), propertyName, offset);
+            count = normalizePrototypeChainForChainAccess(exec, structure, slot.base(), propertyName, offset);
             if (count == InvalidPrototypeChain)
                 return GiveUpOnCache;
-
             prototypeChain = structure->prototypeChain(exec);
         }
+        
         PolymorphicPutByIdList* list;
         list = PolymorphicPutByIdList::from(putKind, stubInfo);
 
-        generateByIdStub(
+        bool result = generateByIdStub(
             exec, kindFor(slot), propertyName, customFor(slot), stubInfo, prototypeChain, count,
             offset, structure, false, nullptr,
             stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
             CodeLocationLabel(list->currentSlowPathTarget()),
             stubRoutine);
-
+        if (!result)
+            return GiveUpOnCache;
+        
         list->addAccess(PutByIdAccess::setter(
             *vm, codeBlock->ownerExecutable(),
             slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
-            structure, prototypeChain, slot.customSetter(), stubRoutine));
+            structure, prototypeChain, count, slot.customSetter(), stubRoutine));
 
         RepatchBuffer repatchBuffer(codeBlock);
         repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine->code().code()));
@@ -1405,11 +1460,11 @@ static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue,
     return GiveUpOnCache;
 }
 
-void buildPutByIdList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
+void buildPutByIdList(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
 {
     GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap);
     
-    if (tryBuildPutByIdList(exec, baseValue, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
+    if (tryBuildPutByIdList(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
         repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
 }
 
@@ -1430,10 +1485,12 @@ static InlineCacheAction tryRepatchIn(
     
     CodeBlock* codeBlock = exec->codeBlock();
     VM* vm = &exec->vm();
-    Structure* structure = base->structure();
+    Structure* structure = base->structure(*vm);
     
     PropertyOffset offsetIgnored;
-    size_t count = normalizePrototypeChainForChainAccess(exec, base, wasFound ? slot.slotBase() : JSValue(), ident, offsetIgnored);
+    JSValue foundSlotBase = wasFound ? slot.slotBase() : JSValue();
+    size_t count = !foundSlotBase || foundSlotBase != base ? 
+        normalizePrototypeChainForChainAccess(exec, structure, foundSlotBase, ident, offsetIgnored) : 0;
     if (count == InvalidPrototypeChain)
         return GiveUpOnCache;
     
@@ -1513,8 +1570,10 @@ static InlineCacheAction tryRepatchIn(
         
         emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
         
-        LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock());
-
+        LinkBuffer patchBuffer(*vm, stubJit, exec->codeBlock(), JITCompilationCanFail);
+        if (patchBuffer.didFailToAllocate())
+            return GiveUpOnCache;
+        
         linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
         
         stubRoutine = FINALIZE_CODE_FOR_STUB(
@@ -1541,13 +1600,18 @@ void repatchIn(
         repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationIn);
 }
 
+static void linkSlowFor(
+    RepatchBuffer& repatchBuffer, VM* vm, CallLinkInfo& callLinkInfo, ThunkGenerator generator)
+{
+    repatchBuffer.relink(
+        callLinkInfo.callReturnLocation(), vm->getCTIStub(generator).code());
+}
+
 static void linkSlowFor(
     RepatchBuffer& repatchBuffer, VM* vm, CallLinkInfo& callLinkInfo,
     CodeSpecializationKind kind, RegisterPreservationMode registers)
 {
-    repatchBuffer.relink(
-        callLinkInfo.callReturnLocation,
-        vm->getCTIStub(virtualThunkGeneratorFor(kind, registers)).code());
+    linkSlowFor(repatchBuffer, vm, callLinkInfo, virtualThunkGeneratorFor(kind, registers));
 }
 
 void linkFor(
@@ -1555,30 +1619,27 @@ void linkFor(
     JSFunction* callee, MacroAssemblerCodePtr codePtr, CodeSpecializationKind kind,
     RegisterPreservationMode registers)
 {
-    ASSERT(!callLinkInfo.stub);
+    ASSERT(!callLinkInfo.stub());
     
     CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
 
-    // If you're being call-linked from a DFG caller then you obviously didn't get inlined.
-    if (calleeCodeBlock && JITCode::isOptimizingJIT(callerCodeBlock->jitType()))
-        calleeCodeBlock->m_shouldAlwaysBeInlined = false;
-    
     VM* vm = callerCodeBlock->vm();
     
     RepatchBuffer repatchBuffer(callerCodeBlock);
     
     ASSERT(!callLinkInfo.isLinked());
-    callLinkInfo.callee.set(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
-    callLinkInfo.lastSeenCallee.set(exec->callerFrame()->vm(), callerCodeBlock->ownerExecutable(), callee);
+    callLinkInfo.setCallee(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin(), callerCodeBlock->ownerExecutable(), callee);
+    callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock->ownerExecutable(), callee);
     if (shouldShowDisassemblyFor(callerCodeBlock))
-        dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin, " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n");
-    repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr);
+        dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n");
+    repatchBuffer.relink(callLinkInfo.hotPathOther(), codePtr);
     
     if (calleeCodeBlock)
         calleeCodeBlock->linkIncomingCall(exec->callerFrame(), &callLinkInfo);
     
     if (kind == CodeForCall) {
-        repatchBuffer.relink(callLinkInfo.callReturnLocation, vm->getCTIStub(linkClosureCallThunkGeneratorFor(registers)).code());
+        linkSlowFor(
+            repatchBuffer, vm, callLinkInfo, linkPolymorphicCallThunkGeneratorFor(registers));
         return;
     }
     
@@ -1598,17 +1659,126 @@ void linkSlowFor(
     linkSlowFor(repatchBuffer, vm, callLinkInfo, kind, registers);
 }
 
-void linkClosureCall(
-    ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock,
-    Structure* structure, ExecutableBase* executable, MacroAssemblerCodePtr codePtr,
+static void revertCall(
+    RepatchBuffer& repatchBuffer, VM* vm, CallLinkInfo& callLinkInfo, ThunkGenerator generator)
+{
+    repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(
+        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
+        static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
+    linkSlowFor(repatchBuffer, vm, callLinkInfo, generator);
+    callLinkInfo.clearSeen();
+    callLinkInfo.clearCallee();
+    callLinkInfo.clearStub();
+    if (callLinkInfo.isOnList())
+        callLinkInfo.remove();
+}
+
+void unlinkFor(
+    RepatchBuffer& repatchBuffer, CallLinkInfo& callLinkInfo,
+    CodeSpecializationKind kind, RegisterPreservationMode registers)
+{
+    if (Options::showDisassembly())
+        dataLog("Unlinking call from ", callLinkInfo.callReturnLocation(), " in request from ", pointerDump(repatchBuffer.codeBlock()), "\n");
+    
+    revertCall(
+        repatchBuffer, repatchBuffer.codeBlock()->vm(), callLinkInfo,
+        linkThunkGeneratorFor(kind, registers));
+}
+
+void linkVirtualFor(
+    ExecState* exec, CallLinkInfo& callLinkInfo,
+    CodeSpecializationKind kind, RegisterPreservationMode registers)
+{
+    // FIXME: We could generate a virtual call stub here. This would lead to faster virtual calls
+    // by eliminating the branch prediction bottleneck inside the shared virtual call thunk.
+    
+    CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
+    VM* vm = callerCodeBlock->vm();
+    
+    if (shouldShowDisassemblyFor(callerCodeBlock))
+        dataLog("Linking virtual call at ", *callerCodeBlock, " ", exec->callerFrame()->codeOrigin(), "\n");
+    
+    RepatchBuffer repatchBuffer(callerCodeBlock);
+    revertCall(repatchBuffer, vm, callLinkInfo, virtualThunkGeneratorFor(kind, registers));
+}
+
+namespace {
+struct CallToCodePtr {
+    CCallHelpers::Call call;
+    MacroAssemblerCodePtr codePtr;
+};
+} // annonymous namespace
+
+void linkPolymorphicCall(
+    ExecState* exec, CallLinkInfo& callLinkInfo, CallVariant newVariant,
     RegisterPreservationMode registers)
 {
-    ASSERT(!callLinkInfo.stub);
+    // Currently we can't do anything for non-function callees.
+    // https://bugs.webkit.org/show_bug.cgi?id=140685
+    if (!newVariant || !newVariant.executable()) {
+        linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+        return;
+    }
     
     CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
     VM* vm = callerCodeBlock->vm();
     
-    GPRReg calleeGPR = static_cast<GPRReg>(callLinkInfo.calleeGPR);
+    CallVariantList list;
+    if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub())
+        list = stub->variants();
+    else if (JSFunction* oldCallee = callLinkInfo.callee())
+        list = CallVariantList{ CallVariant(oldCallee) };
+    
+    list = variantListWithVariant(list, newVariant);
+
+    // If there are any closure calls then it makes sense to treat all of them as closure calls.
+    // This makes switching on callee cheaper. It also produces profiling that's easier on the DFG;
+    // the DFG doesn't really want to deal with a combination of closure and non-closure callees.
+    bool isClosureCall = false;
+    for (CallVariant variant : list)  {
+        if (variant.isClosureCall()) {
+            list = despecifiedVariantList(list);
+            isClosureCall = true;
+            break;
+        }
+    }
+    
+    if (isClosureCall)
+        callLinkInfo.setHasSeenClosure();
+    
+    Vector<PolymorphicCallCase> callCases;
+    
+    // Figure out what our cases are.
+    for (CallVariant variant : list) {
+        CodeBlock* codeBlock;
+        if (variant.executable()->isHostFunction())
+            codeBlock = nullptr;
+        else {
+            codeBlock = jsCast<FunctionExecutable*>(variant.executable())->codeBlockForCall();
+            
+            // If we cannot handle a callee, assume that it's better for this whole thing to be a
+            // virtual call.
+            if (exec->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType() == CallLinkInfo::CallVarargs || callLinkInfo.callType() == CallLinkInfo::ConstructVarargs) {
+                linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+                return;
+            }
+        }
+        
+        callCases.append(PolymorphicCallCase(variant, codeBlock));
+    }
+    
+    // If we are over the limit, just use a normal virtual call.
+    unsigned maxPolymorphicCallVariantListSize;
+    if (callerCodeBlock->jitType() == JITCode::topTierJIT())
+        maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSizeForTopTier();
+    else
+        maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSize();
+    if (list.size() > maxPolymorphicCallVariantListSize) {
+        linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+        return;
+    }
+    
+    GPRReg calleeGPR = static_cast<GPRReg>(callLinkInfo.calleeGPR());
     
     CCallHelpers stubJit(vm, callerCodeBlock);
     
@@ -1622,87 +1792,154 @@ void linkClosureCall(
         stubJit.abortWithReason(RepatchInsaneArgumentCount);
         okArgumentCount.link(&stubJit);
     }
+    
+    GPRReg scratch = AssemblyHelpers::selectScratchGPR(calleeGPR);
+    GPRReg comparisonValueGPR;
+    
+    if (isClosureCall) {
+        // Verify that we have a function and stash the executable in scratch.
 
 #if USE(JSVALUE64)
-    // We can safely clobber everything except the calleeGPR. We can't rely on tagMaskRegister
-    // being set. So we do this the hard way.
-    GPRReg scratch = AssemblyHelpers::selectScratchGPR(calleeGPR);
-    stubJit.move(MacroAssembler::TrustedImm64(TagMask), scratch);
-    slowPath.append(stubJit.branchTest64(CCallHelpers::NonZero, calleeGPR, scratch));
+        // We can safely clobber everything except the calleeGPR. We can't rely on tagMaskRegister
+        // being set. So we do this the hard way.
+        stubJit.move(MacroAssembler::TrustedImm64(TagMask), scratch);
+        slowPath.append(stubJit.branchTest64(CCallHelpers::NonZero, calleeGPR, scratch));
 #else
-    // We would have already checked that the callee is a cell.
+        // We would have already checked that the callee is a cell.
 #endif
     
-    slowPath.append(
-        branchStructure(stubJit,
-            CCallHelpers::NotEqual,
-            CCallHelpers::Address(calleeGPR, JSCell::structureIDOffset()),
-            structure));
+        slowPath.append(
+            stubJit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(calleeGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(JSFunctionType)));
     
-    slowPath.append(
-        stubJit.branchPtr(
-            CCallHelpers::NotEqual,
+        stubJit.loadPtr(
             CCallHelpers::Address(calleeGPR, JSFunction::offsetOfExecutable()),
-            CCallHelpers::TrustedImmPtr(executable)));
+            scratch);
+        
+        comparisonValueGPR = scratch;
+    } else
+        comparisonValueGPR = calleeGPR;
     
-    stubJit.loadPtr(
-        CCallHelpers::Address(calleeGPR, JSFunction::offsetOfScopeChain()),
-        GPRInfo::returnValueGPR);
+    Vector<int64_t> caseValues(callCases.size());
+    Vector<CallToCodePtr> calls(callCases.size());
+    std::unique_ptr<uint32_t[]> fastCounts;
     
-#if USE(JSVALUE64)
-    stubJit.store64(
-        GPRInfo::returnValueGPR,
-        CCallHelpers::Address(MacroAssembler::stackPointerRegister, static_cast<ptrdiff_t>(sizeof(Register) * JSStack::ScopeChain) + offsetToFrame));
-#else
-    stubJit.storePtr(
-        GPRInfo::returnValueGPR,
-        CCallHelpers::Address(MacroAssembler::stackPointerRegister, static_cast<ptrdiff_t>(sizeof(Register) * JSStack::ScopeChain) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) + offsetToFrame));
-    stubJit.store32(
-        CCallHelpers::TrustedImm32(JSValue::CellTag),
-        CCallHelpers::Address(MacroAssembler::stackPointerRegister, static_cast<ptrdiff_t>(sizeof(Register) * JSStack::ScopeChain) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) + offsetToFrame));
-#endif
+    if (callerCodeBlock->jitType() != JITCode::topTierJIT())
+        fastCounts = std::make_unique<uint32_t[]>(callCases.size());
+    
+    for (size_t i = 0; i < callCases.size(); ++i) {
+        if (fastCounts)
+            fastCounts[i] = 0;
+        
+        CallVariant variant = callCases[i].variant();
+        int64_t newCaseValue;
+        if (isClosureCall)
+            newCaseValue = bitwise_cast<intptr_t>(variant.executable());
+        else
+            newCaseValue = bitwise_cast<intptr_t>(variant.function());
+        
+        if (!ASSERT_DISABLED) {
+            for (size_t j = 0; j < i; ++j) {
+                if (caseValues[j] != newCaseValue)
+                    continue;
+
+                dataLog("ERROR: Attempt to add duplicate case value.\n");
+                dataLog("Existing case values: ");
+                CommaPrinter comma;
+                for (size_t k = 0; k < i; ++k)
+                    dataLog(comma, caseValues[k]);
+                dataLog("\n");
+                dataLog("Attempting to add: ", newCaseValue, "\n");
+                dataLog("Variant list: ", listDump(callCases), "\n");
+                RELEASE_ASSERT_NOT_REACHED();
+            }
+        }
+        
+        caseValues[i] = newCaseValue;
+    }
     
-    AssemblyHelpers::Call call = stubJit.nearCall();
-    AssemblyHelpers::Jump done = stubJit.jump();
+    GPRReg fastCountsBaseGPR =
+        AssemblyHelpers::selectScratchGPR(calleeGPR, comparisonValueGPR, GPRInfo::regT3);
+    stubJit.move(CCallHelpers::TrustedImmPtr(fastCounts.get()), fastCountsBaseGPR);
+    
+    BinarySwitch binarySwitch(comparisonValueGPR, caseValues, BinarySwitch::IntPtr);
+    CCallHelpers::JumpList done;
+    while (binarySwitch.advance(stubJit)) {
+        size_t caseIndex = binarySwitch.caseIndex();
+        
+        CallVariant variant = callCases[caseIndex].variant();
+        
+        ASSERT(variant.executable()->hasJITCodeForCall());
+        MacroAssemblerCodePtr codePtr =
+            variant.executable()->generatedJITCodeForCall()->addressForCall(
+                *vm, variant.executable(), ArityCheckNotRequired, registers);
+        
+        if (fastCounts) {
+            stubJit.add32(
+                CCallHelpers::TrustedImm32(1),
+                CCallHelpers::Address(fastCountsBaseGPR, caseIndex * sizeof(uint32_t)));
+        }
+        calls[caseIndex].call = stubJit.nearCall();
+        calls[caseIndex].codePtr = codePtr;
+        done.append(stubJit.jump());
+    }
     
     slowPath.link(&stubJit);
+    binarySwitch.fallThrough().link(&stubJit);
     stubJit.move(calleeGPR, GPRInfo::regT0);
 #if USE(JSVALUE32_64)
     stubJit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
 #endif
     stubJit.move(CCallHelpers::TrustedImmPtr(&callLinkInfo), GPRInfo::regT2);
-    stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.callReturnLocation.executableAddress()), GPRInfo::regT4);
+    stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.callReturnLocation().executableAddress()), GPRInfo::regT4);
     
     stubJit.restoreReturnAddressBeforeReturn(GPRInfo::regT4);
     AssemblyHelpers::Jump slow = stubJit.jump();
+        
+    LinkBuffer patchBuffer(*vm, stubJit, callerCodeBlock, JITCompilationCanFail);
+    if (patchBuffer.didFailToAllocate()) {
+        linkVirtualFor(exec, callLinkInfo, CodeForCall, registers);
+        return;
+    }
     
-    LinkBuffer patchBuffer(*vm, stubJit, callerCodeBlock);
-    
-    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
+    RELEASE_ASSERT(callCases.size() == calls.size());
+    for (CallToCodePtr callToCodePtr : calls) {
+        patchBuffer.link(
+            callToCodePtr.call, FunctionPtr(callToCodePtr.codePtr.executableAddress()));
+    }
     if (JITCode::isOptimizingJIT(callerCodeBlock->jitType()))
-        patchBuffer.link(done, callLinkInfo.callReturnLocation.labelAtOffset(0));
+        patchBuffer.link(done, callLinkInfo.callReturnLocation().labelAtOffset(0));
     else
-        patchBuffer.link(done, callLinkInfo.hotPathOther.labelAtOffset(0));
-    patchBuffer.link(slow, CodeLocationLabel(vm->getCTIStub(virtualThunkGeneratorFor(CodeForCall, registers)).code()));
+        patchBuffer.link(done, callLinkInfo.hotPathOther().labelAtOffset(0));
+    patchBuffer.link(slow, CodeLocationLabel(vm->getCTIStub(linkPolymorphicCallThunkGeneratorFor(registers)).code()));
     
-    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
+    RefPtr<PolymorphicCallStubRoutine> stubRoutine = adoptRef(new PolymorphicCallStubRoutine(
         FINALIZE_CODE_FOR(
             callerCodeBlock, patchBuffer,
-            ("Closure call stub for %s, return point %p, target %p (%s)",
-                toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation.labelAtOffset(0).executableAddress(),
-                codePtr.executableAddress(), toCString(pointerDump(calleeCodeBlock)).data())),
-        *vm, callerCodeBlock->ownerExecutable(), structure, executable, callLinkInfo.codeOrigin));
+            ("Polymorphic call stub for %s, return point %p, targets %s",
+                toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation().labelAtOffset(0).executableAddress(),
+                toCString(listDump(callCases)).data())),
+        *vm, callerCodeBlock->ownerExecutable(), exec->callerFrame(), callLinkInfo, callCases,
+        WTF::move(fastCounts)));
     
     RepatchBuffer repatchBuffer(callerCodeBlock);
     
     repatchBuffer.replaceWithJump(
-        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin),
+        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
         CodeLocationLabel(stubRoutine->code().code()));
+    // This is weird. The original slow path should no longer be reachable.
     linkSlowFor(repatchBuffer, vm, callLinkInfo, CodeForCall, registers);
     
-    callLinkInfo.stub = stubRoutine.release();
+    // If there had been a previous stub routine, that one will die as soon as the GC runs and sees
+    // that it's no longer on stack.
+    callLinkInfo.setStub(stubRoutine.release());
     
-    ASSERT(!calleeCodeBlock || calleeCodeBlock->isIncomingCallAlreadyLinked(&callLinkInfo));
+    // The call link info no longer has a call cache apart from the jump to the polymorphic call
+    // stub.
+    if (callLinkInfo.isOnList())
+        callLinkInfo.remove();
 }
 
 void resetGetByID(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
index ee9950ef9d58973f0cc77763fb927c4547373ebc..ddd008b3ed9a21ecaaa71f2b249fa3706ae21677 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(JIT)
 
 #include "CCallHelpers.h"
+#include "CallVariant.h"
 #include "JITOperations.h"
 
 namespace JSC {
@@ -36,12 +37,14 @@ namespace JSC {
 void repatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
 void buildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
 void buildGetByIDProtoList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
-void repatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
-void buildPutByIdList(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
+void repatchPutByID(ExecState*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
+void buildPutByIdList(ExecState*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
 void repatchIn(ExecState*, JSCell*, const Identifier&, bool wasFound, const PropertySlot&, StructureStubInfo&);
 void linkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind, RegisterPreservationMode);
 void linkSlowFor(ExecState*, CallLinkInfo&, CodeSpecializationKind, RegisterPreservationMode);
-void linkClosureCall(ExecState*, CallLinkInfo&, CodeBlock*, Structure*, ExecutableBase*, MacroAssemblerCodePtr, RegisterPreservationMode);
+void unlinkFor(RepatchBuffer&, CallLinkInfo&, CodeSpecializationKind, RegisterPreservationMode);
+void linkVirtualFor(ExecState*, CallLinkInfo&, CodeSpecializationKind, RegisterPreservationMode);
+void linkPolymorphicCall(ExecState*, CallLinkInfo&, CallVariant, RegisterPreservationMode);
 void resetGetByID(RepatchBuffer&, StructureStubInfo&);
 void resetPutByID(RepatchBuffer&, StructureStubInfo&);
 void resetIn(RepatchBuffer&, StructureStubInfo&);
diff --git a/jit/SetupVarargsFrame.cpp b/jit/SetupVarargsFrame.cpp
new file mode 100644 (file)
index 0000000..9e133cc
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "SetupVarargsFrame.h"
+
+#if ENABLE(JIT)
+
+#include "Interpreter.h"
+#include "JSCInlines.h"
+#include "StackAlignment.h"
+
+namespace JSC {
+
+void emitSetVarargsFrame(CCallHelpers& jit, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR)
+{
+    jit.move(numUsedSlotsGPR, resultGPR);
+    jit.addPtr(lengthGPR, resultGPR);
+    jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize + (lengthIncludesThis? 0 : 1)), resultGPR);
+    
+    // resultGPR now has the required frame size in Register units
+    // Round resultGPR to next multiple of stackAlignmentRegisters()
+    jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), resultGPR);
+    jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), resultGPR);
+    
+    // Now resultGPR has the right stack frame offset in Register units.
+    jit.negPtr(resultGPR);
+    jit.lshiftPtr(CCallHelpers::Imm32(3), resultGPR);
+    jit.addPtr(GPRInfo::callFrameRegister, resultGPR);
+}
+
+void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, ValueRecovery argCountRecovery, VirtualRegister firstArgumentReg, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase)
+{
+    CCallHelpers::JumpList end;
+    
+    if (argCountRecovery.isConstant()) {
+        // FIXME: We could constant-fold a lot of the computation below in this case.
+        // https://bugs.webkit.org/show_bug.cgi?id=141486
+        jit.move(CCallHelpers::TrustedImm32(argCountRecovery.constant().asInt32()), scratchGPR1);
+    } else
+        jit.load32(CCallHelpers::payloadFor(argCountRecovery.virtualRegister()), scratchGPR1);
+    if (firstVarArgOffset) {
+        CCallHelpers::Jump sufficientArguments = jit.branch32(CCallHelpers::GreaterThan, scratchGPR1, CCallHelpers::TrustedImm32(firstVarArgOffset + 1));
+        jit.move(CCallHelpers::TrustedImm32(1), scratchGPR1);
+        CCallHelpers::Jump endVarArgs = jit.jump();
+        sufficientArguments.link(&jit);
+        jit.sub32(CCallHelpers::TrustedImm32(firstVarArgOffset), scratchGPR1);
+        endVarArgs.link(&jit);
+    }
+    slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(maxArguments + 1)));
+    
+    emitSetVarargsFrame(jit, scratchGPR1, true, numUsedSlotsGPR, scratchGPR2);
+
+    slowCase.append(jit.branchPtr(CCallHelpers::Above, CCallHelpers::AbsoluteAddress(jit.vm()->addressOfStackLimit()), scratchGPR2));
+
+    // Initialize ArgumentCount.
+    jit.store32(scratchGPR1, CCallHelpers::Address(scratchGPR2, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset));
+
+    // Copy arguments.
+    jit.signExtend32ToPtr(scratchGPR1, scratchGPR1);
+    CCallHelpers::Jump done = jit.branchSubPtr(CCallHelpers::Zero, CCallHelpers::TrustedImm32(1), scratchGPR1);
+    // scratchGPR1: argumentCount
+
+    CCallHelpers::Label copyLoop = jit.label();
+    int argOffset = (firstArgumentReg.offset() - 1 + firstVarArgOffset) * static_cast<int>(sizeof(Register));
+#if USE(JSVALUE64)
+    jit.load64(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, argOffset), scratchGPR3);
+    jit.store64(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))));
+#else // USE(JSVALUE64), so this begins the 32-bit case
+    jit.load32(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, argOffset + TagOffset), scratchGPR3);
+    jit.store32(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)) + TagOffset));
+    jit.load32(CCallHelpers::BaseIndex(GPRInfo::callFrameRegister, scratchGPR1, CCallHelpers::TimesEight, argOffset + PayloadOffset), scratchGPR3);
+    jit.store32(scratchGPR3, CCallHelpers::BaseIndex(scratchGPR2, scratchGPR1, CCallHelpers::TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)) + PayloadOffset));
+#endif // USE(JSVALUE64), end of 32-bit case
+    jit.branchSubPtr(CCallHelpers::NonZero, CCallHelpers::TrustedImm32(1), scratchGPR1).linkTo(copyLoop, &jit);
+    
+    done.link(&jit);
+}
+
+void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase)
+{
+    emitSetupVarargsFrameFastCase(jit, numUsedSlotsGPR, scratchGPR1, scratchGPR2, scratchGPR3, nullptr, firstVarArgOffset, slowCase);
+}
+
+void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, InlineCallFrame* inlineCallFrame, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase)
+{
+    ValueRecovery argumentCountRecovery;
+    VirtualRegister firstArgumentReg;
+    if (inlineCallFrame) {
+        if (inlineCallFrame->isVarargs()) {
+            argumentCountRecovery = ValueRecovery::displacedInJSStack(
+                inlineCallFrame->argumentCountRegister, DataFormatInt32);
+        } else {
+            argumentCountRecovery = ValueRecovery::constant(
+                jsNumber(inlineCallFrame->arguments.size()));
+        }
+        if (inlineCallFrame->arguments.size() > 1)
+            firstArgumentReg = inlineCallFrame->arguments[1].virtualRegister();
+        else
+            firstArgumentReg = VirtualRegister(0);
+    } else {
+        argumentCountRecovery = ValueRecovery::displacedInJSStack(
+            VirtualRegister(JSStack::ArgumentCount), DataFormatInt32);
+        firstArgumentReg = VirtualRegister(CallFrame::argumentOffset(0));
+    }
+    emitSetupVarargsFrameFastCase(jit, numUsedSlotsGPR, scratchGPR1, scratchGPR2, scratchGPR3, argumentCountRecovery, firstArgumentReg, firstVarArgOffset, slowCase);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
diff --git a/jit/SetupVarargsFrame.h b/jit/SetupVarargsFrame.h
new file mode 100644 (file)
index 0000000..0e8933a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef SetupVarargsFrame_h
+#define SetupVarargsFrame_h
+
+#if ENABLE(JIT)
+
+#include "CCallHelpers.h"
+#include "VirtualRegister.h"
+
+namespace JSC {
+
+void emitSetVarargsFrame(CCallHelpers&, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR);
+
+// Assumes that SP refers to the last in-use stack location, and after this returns SP will point to
+// the newly created frame plus the native header. scratchGPR2 may be the same as numUsedSlotsGPR.
+void emitSetupVarargsFrameFastCase(CCallHelpers&, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, ValueRecovery argCountRecovery, VirtualRegister firstArgumentReg, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
+
+// Variant that assumes normal stack frame.
+void emitSetupVarargsFrameFastCase(CCallHelpers&, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
+
+// Variant for potentially inlined stack frames.
+void emitSetupVarargsFrameFastCase(CCallHelpers&, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, InlineCallFrame*, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // SetupVarargsFrame_h
+
index f0aa28e83b4c7c5abd2bebdbde0e6b5efcd5e555..55da60cd0c3cf952d6c0f4aa4735fdd87d92869f 100644 (file)
@@ -45,7 +45,7 @@ public:
     JIT::Call call()
     {
 #if ENABLE(OPCODE_SAMPLING)
-        if (m_jit->m_bytecodeOffset != (unsigned)-1)
+        if (m_jit->m_bytecodeOffset != std::numeric_limits<unsigned>::max())
             m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, true);
 #endif
         m_jit->updateTopCallFrame();
@@ -73,7 +73,7 @@ public:
 #endif
 
 #if ENABLE(OPCODE_SAMPLING)
-        if (m_jit->m_bytecodeOffset != (unsigned)-1)
+        if (m_jit->m_bytecodeOffset != std::numeric_limits<unsigned>::max())
             m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, false);
 #endif
         
index 97323eee29ee554758bdeca1ae9249129621552b..df27face95718b7d443f9a768b77a6aabc117cef 100644 (file)
@@ -129,14 +129,7 @@ namespace JSC {
             move(tagTypeNumberRegister, regT0);
             done.link(this);
 #else
-#if !CPU(X86)
-            // The src register is not clobbered by moveDoubleToInts with ARM, MIPS and SH4 macro assemblers, so let's use it.
             moveDoubleToInts(src, regT0, regT1);
-#else
-            storeDouble(src, Address(stackPointerRegister, -(int)sizeof(double)));
-            loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
-            loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
-#endif
             Jump lowNonZero = branchTestPtr(NonZero, regT1);
             Jump highNonZero = branchTestPtr(NonZero, regT0);
             move(TrustedImm32(0), regT0);
index 3b6302bcb652c219eb3fc2924a9fc48a6e23485b..17546766f9fa246e9ccc41fab9a54ca1b643db54 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSArray.h"
 #include "JSArrayIterator.h"
 #include "JSStack.h"
+#include "MathCommon.h"
 #include "MaxFrameExtentForSlowPathCall.h"
 #include "JSCInlines.h"
 #include "SpecializedThunkJIT.h"
@@ -137,27 +138,27 @@ MacroAssemblerCodeRef linkConstructThatPreservesRegsThunkGenerator(VM* vm)
     return linkForThunkGenerator(vm, CodeForConstruct, MustPreserveRegisters);
 }
 
-static MacroAssemblerCodeRef linkClosureCallForThunkGenerator(
+static MacroAssemblerCodeRef linkPolymorphicCallForThunkGenerator(
     VM* vm, RegisterPreservationMode registers)
 {
     CCallHelpers jit(vm);
     
-    slowPathFor(jit, vm, operationLinkClosureCallFor(registers));
+    slowPathFor(jit, vm, operationLinkPolymorphicCallFor(registers));
     
     LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID);
-    return FINALIZE_CODE(patchBuffer, ("Link closure call %s slow path thunk", registers == MustPreserveRegisters ? " that preserves registers" : ""));
+    return FINALIZE_CODE(patchBuffer, ("Link polymorphic call %s slow path thunk", registers == MustPreserveRegisters ? " that preserves registers" : ""));
 }
 
 // For closure optimizations, we only include calls, since if you're using closures for
 // object construction then you're going to lose big time anyway.
-MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM* vm)
+MacroAssemblerCodeRef linkPolymorphicCallThunkGenerator(VM* vm)
 {
-    return linkClosureCallForThunkGenerator(vm, RegisterPreservationNotRequired);
+    return linkPolymorphicCallForThunkGenerator(vm, RegisterPreservationNotRequired);
 }
 
-MacroAssemblerCodeRef linkClosureCallThatPreservesRegsThunkGenerator(VM* vm)
+MacroAssemblerCodeRef linkPolymorphicCallThatPreservesRegsThunkGenerator(VM* vm)
 {
-    return linkClosureCallForThunkGenerator(vm, MustPreserveRegisters);
+    return linkPolymorphicCallForThunkGenerator(vm, MustPreserveRegisters);
 }
 
 static MacroAssemblerCodeRef virtualForThunkGenerator(
@@ -176,7 +177,7 @@ static MacroAssemblerCodeRef virtualForThunkGenerator(
     // slow path execution for the profiler.
     jit.add32(
         CCallHelpers::TrustedImm32(1),
-        CCallHelpers::Address(GPRInfo::regT2, OBJECT_OFFSETOF(CallLinkInfo, slowPathCount)));
+        CCallHelpers::Address(GPRInfo::regT2, CallLinkInfo::offsetOfSlowPathCount()));
 
     // FIXME: we should have a story for eliminating these checks. In many cases,
     // the DFG knows that the value is definitely a cell, or definitely a function.
@@ -214,17 +215,6 @@ static MacroAssemblerCodeRef virtualForThunkGenerator(
     // Now we know that we have a CodeBlock, and we're committed to making a fast
     // call.
     
-    jit.loadPtr(
-        CCallHelpers::Address(GPRInfo::regT0, JSFunction::offsetOfScopeChain()),
-        GPRInfo::regT1);
-#if USE(JSVALUE64)
-    jit.emitPutToCallFrameHeaderBeforePrologue(GPRInfo::regT1, JSStack::ScopeChain);
-#else
-    jit.emitPutPayloadToCallFrameHeaderBeforePrologue(GPRInfo::regT1, JSStack::ScopeChain);
-    jit.emitPutTagToCallFrameHeaderBeforePrologue(CCallHelpers::TrustedImm32(JSValue::CellTag),
-        JSStack::ScopeChain);
-#endif
-    
     // Make a tail call. This will return back to JIT code.
     emitPointerValidation(jit, GPRInfo::regT4);
     jit.jump(GPRInfo::regT4);
@@ -276,12 +266,6 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
 
 #if CPU(X86)
-    // Load caller frame's scope chain into this callframe so that whatever we call can
-    // get to its global data.
-    jit.emitGetCallerFrameFromCallFrameHeaderPtr(JSInterfaceJIT::regT0);
-    jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT0);
-    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
-
     // Calling convention:      f(ecx, edx, ...);
     // Host function signature: f(ExecState*);
     jit.move(JSInterfaceJIT::callFrameRegister, X86Registers::ecx);
@@ -296,11 +280,6 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::stackPointerRegister);
 
 #elif CPU(X86_64)
-    // Load caller frame's scope chain into this callframe so that whatever we call can
-    // get to its global data.
-    jit.emitGetCallerFrameFromCallFrameHeaderPtr(JSInterfaceJIT::regT0);
-    jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT0);
-    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
 #if !OS(WINDOWS)
     // Calling convention:      f(edi, esi, edx, ecx, ...);
     // Host function signature: f(ExecState*);
@@ -333,12 +312,6 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     COMPILE_ASSERT(ARM64Registers::x1 != JSInterfaceJIT::regT3, T3_not_trampled_by_arg_1);
     COMPILE_ASSERT(ARM64Registers::x2 != JSInterfaceJIT::regT3, T3_not_trampled_by_arg_2);
 
-    // Load caller frame's scope chain into this callframe so that whatever we call can
-    // get to its global data.
-    jit.emitGetCallerFrameFromCallFrameHeaderPtr(ARM64Registers::x3);
-    jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, ARM64Registers::x3);
-    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
-
     // Host function signature: f(ExecState*);
     jit.move(JSInterfaceJIT::callFrameRegister, ARM64Registers::x0);
 
@@ -346,11 +319,6 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     jit.loadPtr(JSInterfaceJIT::Address(ARM64Registers::x1, JSFunction::offsetOfExecutable()), ARM64Registers::x2);
     jit.call(JSInterfaceJIT::Address(ARM64Registers::x2, executableOffsetToFunction));
 #elif CPU(ARM) || CPU(SH4) || CPU(MIPS)
-    // Load caller frame's scope chain into this callframe so that whatever we call can get to its global data.
-    jit.emitGetCallerFrameFromCallFrameHeaderPtr(JSInterfaceJIT::regT2);
-    jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT2);
-    jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
-
 #if CPU(MIPS)
     // Allocate stack space for (unused) 16 bytes (8-byte aligned) for 4 arguments.
     jit.subPtr(JSInterfaceJIT::TrustedImm32(16), JSInterfaceJIT::stackPointerRegister);
@@ -381,8 +349,8 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
 #else
     JSInterfaceJIT::Jump exceptionHandler = jit.branch32(
         JSInterfaceJIT::NotEqual,
-        JSInterfaceJIT::AbsoluteAddress(reinterpret_cast<char*>(vm->addressOfException()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-        JSInterfaceJIT::TrustedImm32(JSValue::EmptyValueTag));
+        JSInterfaceJIT::AbsoluteAddress(vm->addressOfException()),
+        JSInterfaceJIT::TrustedImm32(0));
 #endif
 
     jit.emitFunctionEpilogue();
@@ -434,7 +402,7 @@ MacroAssemblerCodeRef nativeConstructGenerator(VM* vm)
     return nativeForGenerator(vm, CodeForConstruct);
 }
 
-MacroAssemblerCodeRef arityFixup(VM* vm)
+MacroAssemblerCodeRef arityFixupGenerator(VM* vm)
 {
     JSInterfaceJIT jit(vm);
 
@@ -537,6 +505,83 @@ MacroAssemblerCodeRef arityFixup(VM* vm)
     return FINALIZE_CODE(patchBuffer, ("fixup arity"));
 }
 
+MacroAssemblerCodeRef baselineGetterReturnThunkGenerator(VM* vm)
+{
+    JSInterfaceJIT jit(vm);
+    
+#if USE(JSVALUE64)
+    jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0);
+#else
+    jit.setupResults(GPRInfo::regT0, GPRInfo::regT1);
+#endif
+    
+    unsigned numberOfParameters = 0;
+    numberOfParameters++; // The 'this' argument.
+    numberOfParameters++; // The true return PC.
+    
+    unsigned numberOfRegsForCall =
+        JSStack::CallFrameHeaderSize + numberOfParameters;
+    
+    unsigned numberOfBytesForCall =
+        numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
+    
+    unsigned alignedNumberOfBytesForCall =
+        WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
+            
+    // The real return address is stored above the arguments. We passed one argument, which is
+    // 'this'. So argument at index 1 is the return address.
+    jit.loadPtr(
+        AssemblyHelpers::Address(
+            AssemblyHelpers::stackPointerRegister,
+            (virtualRegisterForArgument(1).offset() - JSStack::CallerFrameAndPCSize) * sizeof(Register)),
+        GPRInfo::regT2);
+    
+    jit.addPtr(
+        AssemblyHelpers::TrustedImm32(alignedNumberOfBytesForCall),
+        AssemblyHelpers::stackPointerRegister);
+    
+    jit.jump(GPRInfo::regT2);
+
+    LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID);
+    return FINALIZE_CODE(patchBuffer, ("baseline getter return thunk"));
+}
+
+MacroAssemblerCodeRef baselineSetterReturnThunkGenerator(VM* vm)
+{
+    JSInterfaceJIT jit(vm);
+    
+    unsigned numberOfParameters = 0;
+    numberOfParameters++; // The 'this' argument.
+    numberOfParameters++; // The value to set.
+    numberOfParameters++; // The true return PC.
+    
+    unsigned numberOfRegsForCall =
+        JSStack::CallFrameHeaderSize + numberOfParameters;
+    
+    unsigned numberOfBytesForCall =
+        numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
+    
+    unsigned alignedNumberOfBytesForCall =
+        WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
+            
+    // The real return address is stored above the arguments. We passed two arguments, so
+    // the argument at index 2 is the return address.
+    jit.loadPtr(
+        AssemblyHelpers::Address(
+            AssemblyHelpers::stackPointerRegister,
+            (virtualRegisterForArgument(2).offset() - JSStack::CallerFrameAndPCSize) * sizeof(Register)),
+        GPRInfo::regT2);
+    
+    jit.addPtr(
+        AssemblyHelpers::TrustedImm32(alignedNumberOfBytesForCall),
+        AssemblyHelpers::stackPointerRegister);
+    
+    jit.jump(GPRInfo::regT2);
+
+    LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID);
+    return FINALIZE_CODE(patchBuffer, ("baseline setter return thunk"));
+}
+
 static void stringCharLoad(SpecializedThunkJIT& jit, VM* vm)
 {
     // load string
@@ -602,6 +647,27 @@ MacroAssemblerCodeRef fromCharCodeThunkGenerator(VM* vm)
     return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "fromCharCode");
 }
 
+MacroAssemblerCodeRef clz32ThunkGenerator(VM* vm)
+{
+    SpecializedThunkJIT jit(vm, 1);
+    MacroAssembler::Jump nonIntArgJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntArgJump);
+
+    SpecializedThunkJIT::Label convertedArgumentReentry(&jit);
+    jit.countLeadingZeros32(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+    jit.returnInt32(SpecializedThunkJIT::regT1);
+
+    if (jit.supportsFloatingPointTruncate()) {
+        nonIntArgJump.link(&jit);
+        jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+        jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(convertedArgumentReentry, &jit);
+        jit.appendFailure(jit.jump());
+    } else
+        jit.appendFailure(nonIntArgJump);
+
+    return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "clz32");
+}
+
 MacroAssemblerCodeRef sqrtThunkGenerator(VM* vm)
 {
     SpecializedThunkJIT jit(vm, 1);
@@ -618,16 +684,6 @@ MacroAssemblerCodeRef sqrtThunkGenerator(VM* vm)
 #define UnaryDoubleOpWrapper(function) function##Wrapper
 enum MathThunkCallingConvention { };
 typedef MathThunkCallingConvention(*MathThunk)(MathThunkCallingConvention);
-extern "C" {
-
-double jsRound(double) REFERENCED_FROM_ASM;
-double jsRound(double d)
-{
-    double integer = ceil(d);
-    return integer - (integer - d > 0.5);
-}
-
-}
 
 #if CPU(X86_64) && COMPILER(GCC) && (OS(DARWIN) || OS(LINUX))
 
@@ -647,6 +703,30 @@ double jsRound(double d)
     } \
     static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
 
+#elif CPU(X86) && COMPILER(GCC) && OS(LINUX) && defined(__PIC__)
+#define defineUnaryDoubleOpWrapper(function) \
+    asm( \
+        ".text\n" \
+        ".globl " SYMBOL_STRING(function##Thunk) "\n" \
+        HIDE_SYMBOL(function##Thunk) "\n" \
+        SYMBOL_STRING(function##Thunk) ":" "\n" \
+        "pushl %ebx\n" \
+        "subl $20, %esp\n" \
+        "movsd %xmm0, (%esp) \n" \
+        "call __x86.get_pc_thunk.bx\n" \
+        "addl $_GLOBAL_OFFSET_TABLE_, %ebx\n" \
+        "call " GLOBAL_REFERENCE(function) "\n" \
+        "fstpl (%esp) \n" \
+        "movsd (%esp), %xmm0 \n" \
+        "addl $20, %esp\n" \
+        "popl %ebx\n" \
+        "ret\n" \
+    );\
+    extern "C" { \
+        MathThunkCallingConvention function##Thunk(MathThunkCallingConvention); \
+    } \
+    static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
+
 #elif CPU(X86) && COMPILER(GCC) && (OS(DARWIN) || OS(LINUX))
 #define defineUnaryDoubleOpWrapper(function) \
     asm( \
@@ -700,12 +780,38 @@ double jsRound(double d)
         HIDE_SYMBOL(function##Thunk) "\n" \
         SYMBOL_STRING(function##Thunk) ":" "\n" \
         "b " GLOBAL_REFERENCE(function) "\n" \
+        ".previous" \
     ); \
     extern "C" { \
         MathThunkCallingConvention function##Thunk(MathThunkCallingConvention); \
     } \
     static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
 
+#elif CPU(X86) && COMPILER(MSVC) && OS(WINDOWS)
+
+// MSVC does not accept floor, etc, to be called directly from inline assembly, so we need to wrap these functions.
+static double (_cdecl *floorFunction)(double) = floor;
+static double (_cdecl *ceilFunction)(double) = ceil;
+static double (_cdecl *expFunction)(double) = exp;
+static double (_cdecl *logFunction)(double) = log;
+static double (_cdecl *jsRoundFunction)(double) = jsRound;
+
+#define defineUnaryDoubleOpWrapper(function) \
+    extern "C" __declspec(naked) MathThunkCallingConvention function##Thunk(MathThunkCallingConvention) \
+    { \
+        __asm \
+        { \
+        __asm sub esp, 20 \
+        __asm movsd mmword ptr [esp], xmm0  \
+        __asm call function##Function \
+        __asm fstp qword ptr [esp] \
+        __asm movsd xmm0, mmword ptr [esp] \
+        __asm add esp, 20 \
+        __asm ret \
+        } \
+    } \
+    static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
+
 #else
 
 #define defineUnaryDoubleOpWrapper(function) \
@@ -950,105 +1056,6 @@ MacroAssemblerCodeRef imulThunkGenerator(VM* vm)
     return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "imul");
 }
 
-static MacroAssemblerCodeRef arrayIteratorNextThunkGenerator(VM* vm, ArrayIterationKind kind)
-{
-    typedef SpecializedThunkJIT::TrustedImm32 TrustedImm32;
-    typedef SpecializedThunkJIT::TrustedImmPtr TrustedImmPtr;
-    typedef SpecializedThunkJIT::Address Address;
-    typedef SpecializedThunkJIT::BaseIndex BaseIndex;
-    typedef SpecializedThunkJIT::Jump Jump;
-    
-    SpecializedThunkJIT jit(vm);
-    // Make sure we're being called on an array iterator, and load m_iteratedObject, and m_nextIndex into regT0 and regT1 respectively
-    jit.loadArgumentWithSpecificClass(JSArrayIterator::info(), SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT4, SpecializedThunkJIT::regT1);
-
-    // Early exit if we don't have a thunk for this form of iteration
-    jit.appendFailure(jit.branch32(SpecializedThunkJIT::AboveOrEqual, Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfIterationKind()), TrustedImm32(ArrayIterateKeyValue)));
-    
-    jit.loadPtr(Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfIteratedObject()), SpecializedThunkJIT::regT0);
-    
-    jit.load32(Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()), SpecializedThunkJIT::regT1);
-    
-    // Pull out the butterfly from iteratedObject
-    jit.load8(Address(SpecializedThunkJIT::regT0, JSCell::indexingTypeOffset()), SpecializedThunkJIT::regT3);
-    jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
-    
-    jit.and32(TrustedImm32(IndexingShapeMask), SpecializedThunkJIT::regT3);
-
-    Jump notDone = jit.branch32(SpecializedThunkJIT::Below, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfPublicLength()));
-    // Return the termination signal to indicate that we've finished
-    jit.move(TrustedImmPtr(vm->iterationTerminator.get()), SpecializedThunkJIT::regT0);
-    jit.returnJSCell(SpecializedThunkJIT::regT0);
-    
-    notDone.link(&jit);
-    
-    if (kind == ArrayIterateKey) {
-        jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-        jit.returnInt32(SpecializedThunkJIT::regT1);
-        return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "array-iterator-next-key");
-        
-    }
-    ASSERT(kind == ArrayIterateValue);
-    
-    // Okay, now we're returning a value so make sure we're inside the vector size
-    jit.appendFailure(jit.branch32(SpecializedThunkJIT::AboveOrEqual, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfVectorLength())));
-    
-    // So now we perform inline loads for int32, value/undecided, and double storage
-    Jump undecidedStorage = jit.branch32(SpecializedThunkJIT::Equal, SpecializedThunkJIT::regT3, TrustedImm32(UndecidedShape));
-    Jump notContiguousStorage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ContiguousShape));
-    
-    undecidedStorage.link(&jit);
-    
-    jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
-    
-#if USE(JSVALUE64)
-    jit.load64(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight), SpecializedThunkJIT::regT0);
-    Jump notHole = jit.branchTest64(SpecializedThunkJIT::NonZero, SpecializedThunkJIT::regT0);
-    jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), JSInterfaceJIT::regT0);
-    notHole.link(&jit);
-    jit.addPtr(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-    jit.returnJSValue(SpecializedThunkJIT::regT0);
-#else
-    jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfTag()), SpecializedThunkJIT::regT3);
-    Jump notHole = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(JSValue::EmptyValueTag));
-    jit.move(JSInterfaceJIT::TrustedImm32(JSValue::UndefinedTag), JSInterfaceJIT::regT1);
-    jit.move(JSInterfaceJIT::TrustedImm32(0), JSInterfaceJIT::regT0);
-    jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-    jit.returnJSValue(SpecializedThunkJIT::regT0, JSInterfaceJIT::regT1);
-    notHole.link(&jit);
-    jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfPayload()), SpecializedThunkJIT::regT0);
-    jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-    jit.move(SpecializedThunkJIT::regT3, SpecializedThunkJIT::regT1);
-    jit.returnJSValue(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
-#endif
-    notContiguousStorage.link(&jit);
-    
-    Jump notInt32Storage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(Int32Shape));
-    jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
-    jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfPayload()), SpecializedThunkJIT::regT0);
-    jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-    jit.returnInt32(SpecializedThunkJIT::regT0);
-    notInt32Storage.link(&jit);
-    
-    jit.appendFailure(jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(DoubleShape)));
-    jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
-    jit.loadDouble(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight), SpecializedThunkJIT::fpRegT0);
-    jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
-    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
-    
-    return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "array-iterator-next-value");
-}
-
-MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM* vm)
-{
-    return arrayIteratorNextThunkGenerator(vm, ArrayIterateKey);
-}
-
-MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM* vm)
-{
-    return arrayIteratorNextThunkGenerator(vm, ArrayIterateValue);
-}
-    
 }
 
 #endif // ENABLE(JIT)
index c35a2f54799cc8a6a448dfeaf11b5ef3afdec088..fa189f3fad45203d8bff72b0525235d32c501f99 100644 (file)
@@ -65,16 +65,16 @@ inline ThunkGenerator linkThunkGeneratorFor(
     return 0;
 }
 
-MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM*);
-MacroAssemblerCodeRef linkClosureCallThatPreservesRegsThunkGenerator(VM*);
+MacroAssemblerCodeRef linkPolymorphicCallThunkGenerator(VM*);
+MacroAssemblerCodeRef linkPolymorphicCallThatPreservesRegsThunkGenerator(VM*);
 
-inline ThunkGenerator linkClosureCallThunkGeneratorFor(RegisterPreservationMode registers)
+inline ThunkGenerator linkPolymorphicCallThunkGeneratorFor(RegisterPreservationMode registers)
 {
     switch (registers) {
     case RegisterPreservationNotRequired:
-        return linkClosureCallThunkGenerator;
+        return linkPolymorphicCallThunkGenerator;
     case MustPreserveRegisters:
-        return linkClosureCallThatPreservesRegsThunkGenerator;
+        return linkPolymorphicCallThatPreservesRegsThunkGenerator;
     }
     RELEASE_ASSERT_NOT_REACHED();
     return 0;
@@ -113,10 +113,14 @@ inline ThunkGenerator virtualThunkGeneratorFor(
 MacroAssemblerCodeRef nativeCallGenerator(VM*);
 MacroAssemblerCodeRef nativeConstructGenerator(VM*);
 MacroAssemblerCodeRef nativeTailCallGenerator(VM*);
-MacroAssemblerCodeRef arityFixup(VM*);
+MacroAssemblerCodeRef arityFixupGenerator(VM*);
+
+MacroAssemblerCodeRef baselineGetterReturnThunkGenerator(VM* vm);
+MacroAssemblerCodeRef baselineSetterReturnThunkGenerator(VM* vm);
 
 MacroAssemblerCodeRef charCodeAtThunkGenerator(VM*);
 MacroAssemblerCodeRef charAtThunkGenerator(VM*);
+MacroAssemblerCodeRef clz32ThunkGenerator(VM*);
 MacroAssemblerCodeRef fromCharCodeThunkGenerator(VM*);
 MacroAssemblerCodeRef absThunkGenerator(VM*);
 MacroAssemblerCodeRef ceilThunkGenerator(VM*);
@@ -127,8 +131,6 @@ MacroAssemblerCodeRef roundThunkGenerator(VM*);
 MacroAssemblerCodeRef sqrtThunkGenerator(VM*);
 MacroAssemblerCodeRef powThunkGenerator(VM*);
 MacroAssemblerCodeRef imulThunkGenerator(VM*);
-MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM*);
-MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM*);
 
 }
 #endif // ENABLE(JIT)
diff --git a/jsc.cpp b/jsc.cpp
index 6ecd4f23ef1772d1fd5bf99ad7c804232d164807..1e5e9812b5ef03c784cf5ae29d32e52ee321dcdb 100644 (file)
--- a/jsc.cpp
+++ b/jsc.cpp
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2012, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
  *
  *  This library is free software; you can redistribute it and/or
 #include "ArrayPrototype.h"
 #include "ButterflyInlines.h"
 #include "BytecodeGenerator.h"
+#include "CodeBlock.h"
 #include "Completion.h"
 #include "CopiedSpaceInlines.h"
+#include "Disassembler.h"
+#include "Exception.h"
 #include "ExceptionHelpers.h"
 #include "HeapStatistics.h"
 #include "InitializeThreading.h"
@@ -36,6 +39,7 @@
 #include "JSCInlines.h"
 #include "JSFunction.h"
 #include "JSLock.h"
+#include "JSONObject.h"
 #include "JSProxy.h"
 #include "JSString.h"
 #include "ProfilerDatabase.h"
@@ -44,6 +48,7 @@
 #include "StructureInlines.h"
 #include "StructureRareDataInlines.h"
 #include "TestRunnerUtils.h"
+#include "TypeProfilerLog.h"
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -75,7 +80,7 @@
 #include <signal.h>
 #endif
 
-#if COMPILER(MSVC) && !OS(WINCE)
+#if COMPILER(MSVC)
 #include <crtdbg.h>
 #include <mmsystem.h>
 #include <windows.h>
 using namespace JSC;
 using namespace WTF;
 
+namespace JSC {
+WTF_IMPORT extern const struct HashTable globalObjectTable;
+}
+
 namespace {
 
+NO_RETURN_WITH_VALUE static void jscExit(int status)
+{
+    waitForAsynchronousDisassembly();
+    
+#if ENABLE(DFG_JIT)
+    if (DFG::isCrashing()) {
+        for (;;) {
+#if OS(WINDOWS)
+            Sleep(1000);
+#else
+            pause();
+#endif
+        }
+    }
+#endif // ENABLE(DFG_JIT)
+    exit(status);
+}
+
 class Element;
 class ElementHandleOwner;
 class Masuqerader;
@@ -103,27 +130,34 @@ class RuntimeArray;
 
 class Element : public JSNonFinalObject {
 public:
-    Element(VM& vm, Structure* structure, Root* root)
+    Element(VM& vm, Structure* structure)
         : Base(vm, structure)
-        , m_root(root)
     {
     }
 
     typedef JSNonFinalObject Base;
     static const bool needsDestruction = false;
 
-    Root* root() const { return m_root; }
-    void setRoot(Root* root) { m_root = root; }
+    Root* root() const { return m_root.get(); }
+    void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
 
     static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
     {
         Structure* structure = createStructure(vm, globalObject, jsNull());
-        Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure, root);
-        element->finishCreation(vm);
+        Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure);
+        element->finishCreation(vm, root);
         return element;
     }
 
-    void finishCreation(VM&);
+    void finishCreation(VM&, Root*);
+
+    static void visitChildren(JSCell* cell, SlotVisitor& visitor)
+    {
+        Element* thisObject = jsCast<Element*>(cell);
+        ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+        Base::visitChildren(thisObject, visitor);
+        visitor.append(&thisObject->m_root);
+    }
 
     static ElementHandleOwner* handleOwner();
 
@@ -135,7 +169,7 @@ public:
     DECLARE_INFO;
 
 private:
-    Root* m_root;
+    WriteBarrier<Root> m_root;
 };
 
 class ElementHandleOwner : public WeakHandleOwner {
@@ -155,10 +189,11 @@ public:
     }
 
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::MasqueradesAsUndefined;
 
     static Masquerader* create(VM& vm, JSGlobalObject* globalObject)
     {
-        globalObject->masqueradesAsUndefinedWatchpoint()->fireAll();
+        globalObject->masqueradesAsUndefinedWatchpoint()->fireAll("Masquerading object allocated");
         Structure* structure = createStructure(vm, globalObject, jsNull());
         Masquerader* result = new (NotNull, allocateCell<Masquerader>(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure);
         result->finishCreation(vm);
@@ -171,9 +206,6 @@ public:
     }
 
     DECLARE_INFO;
-
-protected:
-    static const unsigned StructureFlags = JSC::MasqueradesAsUndefined | Base::StructureFlags;
 };
 
 class Root : public JSDestructibleObject {
@@ -231,6 +263,7 @@ public:
 
     DECLARE_INFO;
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
@@ -251,8 +284,6 @@ public:
             m_delegate.set(vm, this, delegate);
     }
 
-    static const unsigned StructureFlags = JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot | JSC::OverridesVisitChildren | Base::StructureFlags;
-
     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
     {
         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
@@ -282,6 +313,7 @@ private:
 class RuntimeArray : public JSArray {
 public:
     typedef JSArray Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
     static RuntimeArray* create(ExecState* exec)
     {
@@ -311,10 +343,9 @@ public:
             return true;
         }
 
-        unsigned index = propertyName.asIndex();
-        if (index < thisObject->getLength()) {
-            ASSERT(index != PropertyName::NotAnIndex);
-            slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
+        Optional<uint32_t> index = parseIndex(propertyName);
+        if (index && index.value() < thisObject->getLength()) {
+            slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index.value()]));
             return true;
         }
 
@@ -340,9 +371,6 @@ public:
     static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
     {
         RELEASE_ASSERT_NOT_REACHED();
-#if !COMPILER(CLANG)
-        return true;
-#endif
     }
 
     unsigned getLength() const { return m_vector.size(); }
@@ -369,8 +397,6 @@ protected:
             m_vector.append(exec->argument(i).toInt32(exec));
     }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSArray::StructureFlags;
-
 private:
     RuntimeArray(ExecState* exec, Structure* structure)
         : JSArray(exec->vm(), structure, 0)
@@ -388,11 +414,11 @@ private:
     Vector<int> m_vector;
 };
 
-const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Element) };
-const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Masquerader) };
-const ClassInfo Root::s_info = { "Root", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Root) };
-const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ImpureGetter) };
-const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) };
+const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, CREATE_METHOD_TABLE(Element) };
+const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, CREATE_METHOD_TABLE(Masquerader) };
+const ClassInfo Root::s_info = { "Root", &Base::s_info, 0, CREATE_METHOD_TABLE(Root) };
+const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, 0, CREATE_METHOD_TABLE(ImpureGetter) };
+const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, CREATE_METHOD_TABLE(RuntimeArray) };
 
 ElementHandleOwner* Element::handleOwner()
 {
@@ -402,9 +428,10 @@ ElementHandleOwner* Element::handleOwner()
     return owner;
 }
 
-void Element::finishCreation(VM& vm)
+void Element::finishCreation(VM& vm, Root* root)
 {
     Base::finishCreation(vm);
+    setRoot(vm, root);
     m_root->setElement(this);
 }
 
@@ -429,7 +456,9 @@ static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionDeleteAllCompiledCode(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*);
 #ifndef NDEBUG
 static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
@@ -451,9 +480,17 @@ static EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
 
 #if ENABLE(SAMPLING_FLAGS)
 static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
@@ -546,7 +583,7 @@ public:
         return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
     }
 
-    static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return true; }
+    static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags::createAllEnabled(); }
 
 protected:
     void finishCreation(VM& vm, const Vector<String>& arguments)
@@ -561,7 +598,9 @@ protected:
         addFunction(vm, "gc", functionGCAndSweep, 0);
         addFunction(vm, "fullGC", functionFullGC, 0);
         addFunction(vm, "edenGC", functionEdenGC, 0);
+        addFunction(vm, "gcHeapSize", functionHeapSize, 0);
         addFunction(vm, "deleteAllCompiledCode", functionDeleteAllCompiledCode, 0);
+        addFunction(vm, "addressOf", functionAddressOf, 1);
 #ifndef NDEBUG
         addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
         addFunction(vm, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
@@ -589,44 +628,55 @@ protected:
         addFunction(vm, "getElement", functionGetElement, 1);
         addFunction(vm, "setElementRoot", functionSetElementRoot, 2);
         
-        putDirectNativeFunction(vm, this, Identifier(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, DontEnum | JSC::Function);
-        putDirectNativeFunction(vm, this, Identifier(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum | JSC::Function);
-        putDirectNativeFunction(vm, this, Identifier(&vm, "isFinalTier"), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum | JSC::Function);
-        putDirectNativeFunction(vm, this, Identifier(&vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum | JSC::Function);
-        putDirectNativeFunction(vm, this, Identifier(&vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isFinalTier"), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "isInt32"), 0, functionIsInt32, CheckInt32Intrinsic, DontEnum | JSC::Function);
+        putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum | JSC::Function);
         
         addFunction(vm, "effectful42", functionEffectful42, 0);
         addFunction(vm, "makeMasquerader", functionMakeMasquerader, 0);
+        addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0);
 
         addFunction(vm, "createProxy", functionCreateProxy, 1);
         addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
 
         addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
         addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
+
+        addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
+        addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
+        addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
+
+        addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
+        addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
+
+        addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
         
         JSArray* array = constructEmptyArray(globalExec(), 0);
         for (size_t i = 0; i < arguments.size(); ++i)
             array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]));
-        putDirect(vm, Identifier(globalExec(), "arguments"), array);
+        putDirect(vm, Identifier::fromString(globalExec(), "arguments"), array);
         
-        putDirect(vm, Identifier(globalExec(), "console"), jsUndefined());
+        putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined());
     }
 
     void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
     {
-        Identifier identifier(&vm, name);
+        Identifier identifier = Identifier::fromString(&vm, name);
         putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function));
     }
     
     void addConstructableFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
     {
-        Identifier identifier(&vm, name);
+        Identifier identifier = Identifier::fromString(&vm, name);
         putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function, NoIntrinsic, function));
     }
 };
 
-const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
-const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled, 0, &shouldInterruptScriptBeforeTimeout };
+const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, &globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
+const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptRuntimeFlags, 0, &shouldInterruptScriptBeforeTimeout };
 
 
 GlobalObject::GlobalObject(VM& vm, Structure* structure)
@@ -636,20 +686,7 @@ GlobalObject::GlobalObject(VM& vm, Structure* structure)
 
 static inline String stringFromUTF(const char* utf8)
 {
-    // Find the the first non-ascii character, or nul.
-    const char* pos = utf8;
-    while (*pos > 0)
-        pos++;
-    size_t asciiLength = pos - utf8;
-    
-    // Fast case - string is all ascii.
-    if (!*pos)
-        return String(utf8, asciiLength);
-    
-    // Slow case - contains non-ascii characters, use fromUTF8WithLatin1Fallback.
-    ASSERT(*pos < 0);
-    ASSERT(strlen(utf8) == asciiLength + strlen(pos));
-    return String::fromUTF8WithLatin1Fallback(utf8, asciiLength + strlen(pos));
+    return String::fromUTF8WithLatin1Fallback(utf8, strlen(utf8));
 }
 
 static inline SourceCode jscSource(const char* utf8, const String& filename)
@@ -664,7 +701,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
         if (i)
             putchar(' ');
 
-        printf("%s", exec->uncheckedArgument(i).toString(exec)->value(exec).utf8().data());
+        printf("%s", exec->uncheckedArgument(i).toString(exec)->view(exec).get().utf8().data());
     }
 
     putchar('\n');
@@ -675,15 +712,17 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
 #ifndef NDEBUG
 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
 {
-    if (!exec->callerFrame()->isVMEntrySentinel())
-        exec->vm().interpreter->dumpCallFrame(exec->callerFrame());
+    VMEntryFrame* topVMEntryFrame = exec->vm().topVMEntryFrame;
+    ExecState* callerFrame = exec->callerFrame(topVMEntryFrame);
+    if (callerFrame)
+        exec->vm().interpreter->dumpCallFrame(callerFrame);
     return JSValue::encode(jsUndefined());
 }
 #endif
 
 EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
 {
-    fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->value(exec).utf8().data());
+    fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->view(exec).get().utf8().data());
     return JSValue::encode(jsUndefined());
 }
 
@@ -700,8 +739,8 @@ EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState* exec)
         return JSValue::encode(jsUndefined());
     JSObject* object = jsDynamicCast<JSObject*>(exec->argument(0));
     if (!object)
-        return JSValue::encode(jsString(exec, "<not object>"));
-    return JSValue::encode(jsString(exec, toString("<Public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">")));
+        return JSValue::encode(jsNontrivialString(exec, ASCIILiteral("<not object>")));
+    return JSValue::encode(jsNontrivialString(exec, toString("<Public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">")));
 }
 
 class FunctionJSCStackFunctor {
@@ -757,7 +796,7 @@ EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState* exec)
     JSLockHolder lock(exec);
     Element* element = jsCast<Element*>(exec->argument(0));
     Root* root = jsCast<Root*>(exec->argument(1));
-    element->setRoot(root);
+    element->setRoot(exec->vm(), root);
     return JSValue::encode(jsUndefined());
 }
 
@@ -810,21 +849,27 @@ EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState* exec)
 {
     JSLockHolder lock(exec);
     exec->heap()->collectAllGarbage();
-    return JSValue::encode(jsUndefined());
+    return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection()));
 }
 
 EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState* exec)
 {
     JSLockHolder lock(exec);
     exec->heap()->collect(FullCollection);
-    return JSValue::encode(jsUndefined());
+    return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection()));
 }
 
 EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
 {
     JSLockHolder lock(exec);
     exec->heap()->collect(EdenCollection);
-    return JSValue::encode(jsUndefined());
+    return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastEdenCollection()));
+}
+
+EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState* exec)
+{
+    JSLockHolder lock(exec);
+    return JSValue::encode(jsNumber(exec->heap()->size()));
 }
 
 EncodedJSValue JSC_HOST_CALL functionDeleteAllCompiledCode(ExecState* exec)
@@ -834,6 +879,21 @@ EncodedJSValue JSC_HOST_CALL functionDeleteAllCompiledCode(ExecState* exec)
     return JSValue::encode(jsUndefined());
 }
 
+// This function is not generally very helpful in 64-bit code as the tag and payload
+// share a register. But in 32-bit JITed code the tag may not be checked if an
+// optimization removes type checking requirements, such as in ===.
+EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState* exec)
+{
+    JSValue value = exec->argument(0);
+    if (!value.isCell())
+        return JSValue::encode(jsUndefined());
+    // Need to cast to uint64_t so bitwise_cast will play along.
+    uint64_t asNumber = reinterpret_cast<uint64_t>(value.asCell());
+    EncodedJSValue returnValue = JSValue::encode(jsNumber(bitwise_cast<double>(asNumber)));
+    return returnValue;
+}
+
+
 #ifndef NDEBUG
 EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState* exec)
 {
@@ -855,7 +915,7 @@ EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
     String fileName = exec->argument(0).toString(exec)->value(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
 
     GlobalObject* globalObject = GlobalObject::create(exec->vm(), GlobalObject::createStructure(exec->vm(), jsNull()), Vector<String>());
 
@@ -863,15 +923,15 @@ EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
     for (unsigned i = 1; i < exec->argumentCount(); ++i)
         array->putDirectIndex(globalObject->globalExec(), i - 1, exec->uncheckedArgument(i));
     globalObject->putDirect(
-        exec->vm(), Identifier(globalObject->globalExec(), "arguments"), array);
+        exec->vm(), Identifier::fromString(globalObject->globalExec(), "arguments"), array);
 
-    JSValue exception;
+    NakedPtr<Exception> exception;
     StopWatch stopWatch;
     stopWatch.start();
-    evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), &exception);
+    evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), exception);
     stopWatch.stop();
 
-    if (!!exception) {
+    if (exception) {
         exec->vm().throwException(globalObject->globalExec(), exception);
         return JSValue::encode(jsUndefined());
     }
@@ -884,12 +944,12 @@ EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
     String fileName = exec->argument(0).toString(exec)->value(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
 
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     
-    JSValue evaluationException;
-    JSValue result = evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), &evaluationException);
+    NakedPtr<Exception> evaluationException;
+    JSValue result = evaluate(globalObject->globalExec(), jscSource(script.data(), fileName), JSValue(), evaluationException);
     if (evaluationException)
         exec->vm().throwException(exec, evaluationException);
     return JSValue::encode(result);
@@ -900,7 +960,7 @@ EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState* exec)
     String fileName = exec->argument(0).toString(exec)->value(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
 
     return JSValue::encode(jsString(exec, stringFromUTF(script.data())));
 }
@@ -910,7 +970,7 @@ EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
     String fileName = exec->argument(0).toString(exec)->value(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Could not open file.")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
 
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
 
@@ -997,11 +1057,11 @@ EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState* exec)
 EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState* exec)
 {
     if (exec->argumentCount() < 1)
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Not enough arguments")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Not enough arguments"))));
     
     JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(0));
     if (!buffer)
-        return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Expected an array buffer")));
+        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Expected an array buffer"))));
     
     ArrayBufferContents dummyContents;
     buffer->impl()->transfer(dummyContents);
@@ -1011,9 +1071,9 @@ EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*)
 {
-    exit(EXIT_SUCCESS);
+    jscExit(EXIT_SUCCESS);
 
-#if COMPILER(MSVC) && OS(WINCE)
+#if COMPILER(MSVC)
     // Without this, Visual Studio will complain that this method does not return a value.
     return JSValue::encode(jsUndefined());
 #endif
@@ -1024,6 +1084,14 @@ EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*) { return JSValue::encode
 
 EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*) { return JSValue::encode(jsUndefined()); }
 EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*) { return JSValue::encode(jsUndefined()); }
+EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState* exec)
+{
+    for (size_t i = 0; i < exec->argumentCount(); ++i) {
+        if (!exec->argument(i).isInt32())
+            return JSValue::encode(jsBoolean(false));
+    }
+    return JSValue::encode(jsBoolean(true));
+}
 
 EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState* exec) { return JSValue::encode(exec->argument(0)); }
 
@@ -1037,12 +1105,89 @@ EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState* exec)
     return JSValue::encode(Masquerader::create(exec->vm(), exec->lexicalGlobalObject()));
 }
 
+EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState* exec)
+{
+    JSValue value = exec->argument(0);
+    if (value.isObject())
+        return JSValue::encode(jsBoolean(asObject(value)->hasCustomProperties()));
+    return JSValue::encode(jsBoolean(false));
+}
+
+EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState* exec)
+{
+    exec->vm().dumpTypeProfilerData();
+    return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
+{
+    RELEASE_ASSERT(exec->vm().typeProfiler());
+    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));
+
+    JSValue functionValue = exec->argument(0);
+    RELEASE_ASSERT(functionValue.isFunction());
+    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
+
+    RELEASE_ASSERT(exec->argument(1).isString());
+    String substring = exec->argument(1).getString(exec);
+    String sourceCodeText = executable->source().toString();
+    unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
+    
+    String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), exec->vm());
+    return JSValue::encode(JSONParse(exec, jsonString));
+}
+
+EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
+{
+    RELEASE_ASSERT(exec->vm().typeProfiler());
+    exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));
+
+    JSValue functionValue = exec->argument(0);
+    RELEASE_ASSERT(functionValue.isFunction());
+    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
+
+    unsigned offset = executable->source().startOffset();
+    String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), exec->vm());
+    return JSValue::encode(JSONParse(exec, jsonString));
+}
+
+EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
+{
+    RELEASE_ASSERT(exec->vm().controlFlowProfiler());
+    exec->vm().controlFlowProfiler()->dumpData();
+    return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)
+{
+    RELEASE_ASSERT(exec->vm().controlFlowProfiler());
+
+    JSValue functionValue = exec->argument(0);
+    RELEASE_ASSERT(functionValue.isFunction());
+    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
+
+    RELEASE_ASSERT(exec->argument(1).isString());
+    String substring = exec->argument(1).getString(exec);
+    String sourceCodeText = executable->source().toString();
+    RELEASE_ASSERT(sourceCodeText.contains(substring));
+    int offset = sourceCodeText.find(substring) + executable->source().startOffset();
+    
+    bool hasExecuted = exec->vm().controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), exec->vm());
+    return JSValue::encode(jsBoolean(hasExecuted));
+}
+
+EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)
+{
+    Options::enableExceptionFuzz() = true;
+    return JSValue::encode(jsUndefined());
+}
+
 // Use SEH for Release builds only to get rid of the crash report dialog
 // (luckily the same tests fail in Release and Debug builds so far). Need to
 // be in a separate main function because the jscmain function requires object
 // unwinding.
 
-#if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE)
+#if COMPILER(MSVC) && !defined(_DEBUG)
 #define TRY       __try {
 #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
 #else
@@ -1073,8 +1218,14 @@ int main(int argc, char** argv)
     fesetenv( &env );
 #endif
 
-#if OS(WINDOWS)
-#if !OS(WINCE)
+#if OS(WINDOWS) && (defined(_M_X64) || defined(__x86_64__))
+    // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+    // if the feature has been disabled in firmware. This causes us to crash
+    // in some of the math functions. For now, we disable those optimizations
+    // because Microsoft is not going to fix the problem in VS2013.
+    // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+    _set_FMA3_enable(0);
+
     // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
     // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
     // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
@@ -1087,7 +1238,6 @@ int main(int argc, char** argv)
     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
-#endif
 #endif
 
     timeBeginPeriod(1);
@@ -1097,13 +1247,11 @@ int main(int argc, char** argv)
     ecore_init();
 #endif
 
-    // Initialize JSC before getting VM.
-#if ENABLE(SAMPLING_REGIONS)
-    WTF::initializeMainThread();
-#endif
-    JSC::initializeThreading();
+    // Need to initialize WTF threading before we start any threads. Cannot initialize JSC
+    // threading yet, since that would do somethings that we'd like to defer until after we
+    // have a chance to parse options.
+    WTF::initializeThreading();
 
-#if !OS(WINCE)
     if (char* timeoutString = getenv("JSC_timeout")) {
         if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) {
             dataLog(
@@ -1112,7 +1260,6 @@ int main(int argc, char** argv)
         } else
             createThread(timeoutThreadMain, 0, "jsc Timeout Thread");
     }
-#endif
 
 #if PLATFORM(IOS)
     Options::crashIfCantAllocateJITMemory() = true;
@@ -1131,7 +1278,7 @@ int main(int argc, char** argv)
     ecore_shutdown();
 #endif
 
-    return res;
+    jscExit(res);
 }
 
 static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
@@ -1158,20 +1305,20 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
             script = scriptBuffer.data();
         } else {
             script = scripts[i].argument;
-            fileName = "[Command Line]";
+            fileName = ASCIILiteral("[Command Line]");
         }
 
         vm.startSampling();
 
-        JSValue evaluationException;
-        JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), &evaluationException);
+        NakedPtr<Exception> evaluationException;
+        JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), evaluationException);
         success = success && !evaluationException;
         if (dump && !evaluationException)
             printf("End: %s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
         if (evaluationException) {
-            printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
-            Identifier stackID(globalObject->globalExec(), "stack");
-            JSValue stackValue = evaluationException.get(globalObject->globalExec(), stackID);
+            printf("Exception: %s\n", evaluationException->value().toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
+            Identifier stackID = Identifier::fromString(globalObject->globalExec(), "stack");
+            JSValue stackValue = evaluationException->value().get(globalObject->globalExec(), stackID);
             if (!stackValue.isUndefinedOrNull())
                 printf("%s\n", stackValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
         }
@@ -1200,7 +1347,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
 
 static void runInteractive(GlobalObject* globalObject)
 {
-    String interpreterName("Interpreter");
+    String interpreterName(ASCIILiteral("Interpreter"));
     
     bool shouldQuit = false;
     while (!shouldQuit) {
@@ -1219,16 +1366,16 @@ static void runInteractive(GlobalObject* globalObject)
             if (!line[0])
                 break;
             add_history(line);
-        } while (error.m_syntaxErrorType == ParserError::SyntaxErrorRecoverable);
+        } while (error.syntaxErrorType() == ParserError::SyntaxErrorRecoverable);
         
-        if (error.m_type != ParserError::ErrorNone) {
-            printf("%s:%d\n", error.m_message.utf8().data(), error.m_line);
+        if (error.isValid()) {
+            printf("%s:%d\n", error.message().utf8().data(), error.line());
             continue;
         }
         
         
-        JSValue evaluationException;
-        JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, interpreterName), JSValue(), &evaluationException);
+        NakedPtr<Exception> evaluationException;
+        JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, interpreterName), JSValue(), evaluationException);
 #else
         printf("%s", interactivePrompt);
         Vector<char, 256> line;
@@ -1243,11 +1390,11 @@ static void runInteractive(GlobalObject* globalObject)
             break;
         line.append('\0');
 
-        JSValue evaluationException;
-        JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line.data(), interpreterName), JSValue(), &evaluationException);
+        NakedPtr<Exception> evaluationException;
+        JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line.data(), interpreterName), JSValue(), evaluationException);
 #endif
         if (evaluationException)
-            printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
+            printf("Exception: %s\n", evaluationException->value().toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
         else
             printf("%s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
 
@@ -1275,11 +1422,13 @@ static NO_RETURN void printUsageStatement(bool help = false)
     fprintf(stderr, "  --<jsc VM option>=<value>  Sets the specified JSC VM option\n");
     fprintf(stderr, "\n");
 
-    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
+    jscExit(help ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 void CommandLine::parseArguments(int argc, char** argv)
 {
+    Options::initialize();
+    
     int i = 1;
     bool needToDumpOptions = false;
     bool needToExit = false;
@@ -1344,8 +1493,7 @@ void CommandLine::parseArguments(int argc, char** argv)
         }
 
         // See if the -- option is a JSC VM option.
-        // NOTE: At this point, we know that the arg starts with "--". Skip it.
-        if (JSC::Options::setOption(&arg[2])) {
+        if (strstr(arg, "--") == arg && JSC::Options::setOption(&arg[2])) {
             // The arg was recognized as a VM option and has been parsed.
             continue; // Just continue with the next arg. 
         }
@@ -1362,9 +1510,10 @@ void CommandLine::parseArguments(int argc, char** argv)
         m_arguments.append(argv[i]);
 
     if (needToDumpOptions)
-        JSC::Options::dumpAllOptions(stderr);
+        JSC::Options::dumpAllOptions(JSC::Options::DumpLevel::Verbose, "All JSC runtime options:", stderr);
+    JSC::Options::ensureOptionsAreCoherent();
     if (needToExit)
-        exit(EXIT_SUCCESS);
+        jscExit(EXIT_SUCCESS);
 }
 
 int jscmain(int argc, char** argv)
@@ -1372,13 +1521,20 @@ int jscmain(int argc, char** argv)
     // Note that the options parsing can affect VM creation, and thus
     // comes first.
     CommandLine options(argc, argv);
-    VM* vm = VM::create(LargeHeap).leakRef();
+
+    // Initialize JSC before getting VM.
+#if ENABLE(SAMPLING_REGIONS)
+    WTF::initializeMainThread();
+#endif
+    JSC::initializeThreading();
+
+    VM* vm = &VM::create(LargeHeap).leakRef();
     int result;
     {
         JSLockHolder locker(vm);
 
         if (options.m_profile && !vm->m_perBytecodeProfiler)
-            vm->m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*vm));
+            vm->m_perBytecodeProfiler = std::make_unique<Profiler::Database>(*vm);
     
         GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);
         bool success = runWithScripts(globalObject, options.m_scripts, options.m_dump);
@@ -1398,6 +1554,14 @@ int jscmain(int argc, char** argv)
 #if ENABLE(JIT)
         if (Options::enableExceptionFuzz())
             printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
+        bool fireAtEnabled =
+            Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
+        if (Options::enableExecutableAllocationFuzz() && (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
+            printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks());
+        if (Options::enableOSRExitFuzz()) {
+            printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks());
+            printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks());
+        }
 #endif
     }
     
@@ -1432,3 +1596,10 @@ static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& b
 
     return true;
 }
+
+#if OS(WINDOWS)
+extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
+{
+    return main(argc, const_cast<char**>(argv));
+}
+#endif
index 5327813f755c2d53ef88e15ade562a467b1f4c8f..e926f52dc76d9ede2f0e3a5b3dc26b336a92f85d 100644 (file)
@@ -73,10 +73,10 @@ void Data::performAssertions(VM& vm)
 #ifndef NDEBUG
 #if USE(JSVALUE64)
     const ptrdiff_t PtrSize = 8;
-    const ptrdiff_t CallFrameHeaderSlots = 6;
+    const ptrdiff_t CallFrameHeaderSlots = 5;
 #else // USE(JSVALUE64) // i.e. 32-bit version
     const ptrdiff_t PtrSize = 4;
-    const ptrdiff_t CallFrameHeaderSlots = 5;
+    const ptrdiff_t CallFrameHeaderSlots = 4;
 #endif
     const ptrdiff_t SlotSize = 8;
 #endif
@@ -89,8 +89,7 @@ void Data::performAssertions(VM& vm)
     ASSERT(JSStack::CallerFrameAndPCSize == (PtrSize * 2) / SlotSize);
     ASSERT(CallFrame::returnPCOffset() == CallFrame::callerFrameOffset() + PtrSize);
     ASSERT(JSStack::CodeBlock * sizeof(Register) == CallFrame::returnPCOffset() + PtrSize);
-    ASSERT(JSStack::ScopeChain * sizeof(Register) == JSStack::CodeBlock * sizeof(Register) + SlotSize);
-    ASSERT(JSStack::Callee * sizeof(Register) == JSStack::ScopeChain * sizeof(Register) + SlotSize);
+    ASSERT(JSStack::Callee * sizeof(Register) == JSStack::CodeBlock * sizeof(Register) + SlotSize);
     ASSERT(JSStack::ArgumentCount * sizeof(Register) == JSStack::Callee * sizeof(Register) + SlotSize);
     ASSERT(JSStack::ThisArgument * sizeof(Register) == JSStack::ArgumentCount * sizeof(Register) + SlotSize);
     ASSERT(JSStack::CallFrameHeaderSize == JSStack::ThisArgument);
@@ -132,7 +131,7 @@ void Data::performAssertions(VM& vm)
 #elif CPU(X86_64) && OS(WINDOWS)
     ASSERT(maxFrameExtentForSlowPathCall == 64);
 #endif
-    ASSERT(StringType == 5);
+    ASSERT(StringType == 6);
     ASSERT(ObjectType == 18);
     ASSERT(FinalObjectType == 19);
     ASSERT(MasqueradesAsUndefined == 1);
@@ -143,17 +142,18 @@ void Data::performAssertions(VM& vm)
     ASSERT(EvalCode == 1);
     ASSERT(FunctionCode == 2);
 
-    ASSERT(GlobalProperty == 0);
-    ASSERT(GlobalVar == 1);
-    ASSERT(ClosureVar == 2);
-    ASSERT(GlobalPropertyWithVarInjectionChecks == 3);
-    ASSERT(GlobalVarWithVarInjectionChecks == 4);
-    ASSERT(ClosureVarWithVarInjectionChecks == 5);
-    ASSERT(Dynamic == 6);
+    static_assert(GlobalProperty == 0, "LLInt assumes GlobalProperty ResultType is == 0");
+    static_assert(GlobalVar == 1, "LLInt assumes GlobalVar ResultType is == 1");
+    static_assert(ClosureVar == 2, "LLInt assumes ClosureVar ResultType is == 2");
+    static_assert(LocalClosureVar == 3, "LLInt assumes LocalClosureVar ResultType is == 3");
+    static_assert(GlobalPropertyWithVarInjectionChecks == 4, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 4");
+    static_assert(GlobalVarWithVarInjectionChecks == 5, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 5");
+    static_assert(ClosureVarWithVarInjectionChecks == 6, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 6");
+    static_assert(Dynamic == 7, "LLInt assumes Dynamic ResultType is == 7");
     
     ASSERT(ResolveModeAndType::mask == 0xffff);
 
-    ASSERT(MarkedBlock::blockMask == ~static_cast<decltype(MarkedBlock::blockMask)>(0xffff));
+    ASSERT(MarkedBlock::blockMask == ~static_cast<decltype(MarkedBlock::blockMask)>(0x3fff));
 
     // FIXME: make these assertions less horrible.
 #if !ASSERT_DISABLED
@@ -163,7 +163,7 @@ void Data::performAssertions(VM& vm)
     ASSERT(bitwise_cast<int**>(&testVector)[0] == testVector.begin());
 #endif
 
-    ASSERT(StringImpl::s_hashFlag8BitBuffer == 32);
+    ASSERT(StringImpl::s_hashFlag8BitBuffer == 8);
 }
 #if COMPILER(CLANG)
 #pragma clang diagnostic pop
index da85879fad6e4dc9bca5865befa88cef5a0b0a8c..5ab9ced09ce444ad0118265e368bbf2ccc616e4b 100644 (file)
@@ -40,6 +40,7 @@
 #define OFFLINE_ASM_ARM64 0
 #define OFFLINE_ASM_X86_64 0
 #define OFFLINE_ASM_X86_64_WIN 0
+#define OFFLINE_ASM_ARMv7k 0
 #define OFFLINE_ASM_ARMv7s 0
 #define OFFLINE_ASM_MIPS 0
 #define OFFLINE_ASM_SH4 0
 #define OFFLINE_ASM_X86_WIN 0
 #endif
 
+#ifdef __ARM_ARCH_7K__
+#define OFFLINE_ASM_ARMv7k 1
+#else
+#define OFFLINE_ASM_ARMv7k 0
+#endif
+
 #ifdef __ARM_ARCH_7S__
 #define OFFLINE_ASM_ARMv7s 1
 #else
 #define OFFLINE_ASM_EXECUTION_TRACING 0
 #endif
 
-#if LLINT_ALWAYS_ALLOCATE_SLOW
-#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 1
-#else
-#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 0
-#endif
-
 #if ENABLE(GGC)
 #define OFFLINE_ASM_GGC 1
 #else
index 84256aec6ce33016fd2822ff2b183ea576b5ec4c..5e16174405a8316d7b0181b8a115b035633ceb92 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,8 @@
 #include "CodeBlock.h"
 #include "CommonSlowPaths.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
+#include "Exception.h"
 #include "Executable.h"
 #include "Heap.h"
 #include "Interpreter.h"
 #include "JSCell.h"
 #include "JSFunction.h"
 #include "VM.h"
+#include "JSEnvironmentRecord.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
-#include "JSPropertyNameIterator.h"
 #include "JSStack.h"
 #include "JSString.h"
 #include "JSTypeInfo.h"
-#include "JSVariableObject.h"
 #include "JumpTable.h"
 #include "LLIntOfflineAsmConfig.h"
 #include "MarkedSpace.h"
 #include "ProtoCallFrame.h"
 #include "Structure.h"
 #include "StructureChain.h"
+#include "TypeProfiler.h"
+#include "TypeProfilerLog.h"
+#include "VMEntryRecord.h"
 #include "ValueProfile.h"
 #include <wtf/text/StringImpl.h>
 
index 6c7c131c065eb9b6efa73bd62a324b82062cf916..9cfe87340ee9234081bfbd94528e9e907244aaa9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "config.h"
 #include "LLIntSlowPaths.h"
-#include "Arguments.h"
+
 #include "ArrayConstructor.h"
 #include "CallFrame.h"
 #include "CommonSlowPaths.h"
 #include "CommonSlowPathsExceptions.h"
+#include "Error.h"
 #include "ErrorHandlingScope.h"
+#include "ExceptionFuzz.h"
 #include "GetterSetter.h"
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITExceptions.h"
-#include "JSActivation.h"
+#include "JSLexicalEnvironment.h"
+#include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
-#include "JSPropertyNameIterator.h"
 #include "JSStackInlines.h"
 #include "JSString.h"
 #include "JSWithScope.h"
 #include "LLIntCommon.h"
 #include "LLIntExceptions.h"
+#include "LegacyProfiler.h"
 #include "LowLevelInterpreter.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "ProtoCallFrame.h"
 #include "StructureRareDataInlines.h"
 #include <wtf/StringPrintStream.h>
@@ -90,6 +92,7 @@ namespace JSC { namespace LLInt {
     } while (false)
 
 #define LLINT_CHECK_EXCEPTION() do {                    \
+        doExceptionFuzzingIfEnabled(exec, "LLIntSlowPaths", pc);    \
         if (UNLIKELY(vm.exception())) {                 \
             pc = returnToThrow(exec);                   \
             LLINT_END_IMPL();                           \
@@ -147,24 +150,26 @@ namespace JSC { namespace LLInt {
         LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec));                 \
     } while (false)
 
-#define LLINT_CALL_CHECK_EXCEPTION(exec) do {                           \
+#define LLINT_CALL_CHECK_EXCEPTION(exec, execCallee) do {               \
         ExecState* __cce_exec = (exec);                                 \
+        ExecState* __cce_execCallee = (execCallee);                     \
+        doExceptionFuzzingIfEnabled(__cce_exec, "LLIntSlowPaths/call", nullptr); \
         if (UNLIKELY(vm.exception()))                                   \
-            LLINT_CALL_END_IMPL(0, callToThrow(__cce_exec));            \
+            LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee));      \
     } while (false)
 
-#define LLINT_CALL_RETURN(exec, callTarget) do {                        \
+#define LLINT_CALL_RETURN(exec, execCallee, callTarget) do {            \
         ExecState* __cr_exec = (exec);                                  \
+        ExecState* __cr_execCallee = (execCallee);                      \
         void* __cr_callTarget = (callTarget);                           \
-        LLINT_CALL_CHECK_EXCEPTION(__cr_exec);                          \
-        LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget);                \
+        LLINT_CALL_CHECK_EXCEPTION(__cr_exec, __cr_execCallee);         \
+        LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget);          \
     } while (false)
 
 #define LLINT_RETURN_CALLEE_FRAME(execCallee) do {                      \
         ExecState* __rcf_exec = (execCallee);                           \
         LLINT_RETURN_TWO(pc, __rcf_exec);                               \
     } while (false)
-    
 
 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 {
@@ -249,12 +254,11 @@ LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
 
 LLINT_SLOW_PATH_DECL(trace)
 {
-    dataLogF("%p / %p: executing bc#%zu, %s, scope %p, pc = %p\n",
+    dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
             exec->codeBlock(),
             exec,
             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
-            opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
-            exec->scope(), pc);
+            opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)], pc);
     if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_enter) {
         dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
         *bitwise_cast<volatile char*>(exec->returnPC().value());
@@ -327,6 +331,7 @@ inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
         }
     }
     default:
+        dataLog("Unexpected code block in LLInt: ", *codeBlock, "\n");
         RELEASE_ASSERT_NOT_REACHED();
         return false;
     }
@@ -456,21 +461,13 @@ LLINT_SLOW_PATH_DECL(stack_check)
     dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
     dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
 
-#if ENABLE(LLINT_C_LOOP)
-    dataLogF("Current end is at %p.\n", exec->vm().jsStackLimit());
-#else
+#if ENABLE(JIT)
     dataLogF("Current end is at %p.\n", exec->vm().stackLimit());
+#else
+    dataLogF("Current end is at %p.\n", exec->vm().jsStackLimit());
 #endif
 
 #endif
-    // This stack check is done in the prologue for a function call, and the
-    // CallFrame is not completely set up yet. For example, if the frame needs
-    // an activation object, the activation object will only be set up after
-    // we start executing the function. If we need to throw a StackOverflowError
-    // here, then we need to tell the prologue to start the stack unwinding from
-    // the caller frame (which is fully set up) instead. To do that, we return
-    // the caller's CallFrame in the second return value.
-    //
     // If the stack check succeeds and we don't need to throw the error, then
     // we'll return 0 instead. The prologue will check for a non-zero value
     // when determining whether to set the callFrame or not.
@@ -484,7 +481,6 @@ LLINT_SLOW_PATH_DECL(stack_check)
         LLINT_RETURN_TWO(pc, 0);
 #endif
 
-    exec = exec->callerFrame();
     vm.topCallFrame = exec;
     ErrorHandlingScope errorScope(vm);
     CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
@@ -492,15 +488,16 @@ LLINT_SLOW_PATH_DECL(stack_check)
     LLINT_RETURN_TWO(pc, exec);
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_create_activation)
+LLINT_SLOW_PATH_DECL(slow_path_create_lexical_environment)
 {
     LLINT_BEGIN();
 #if LLINT_SLOW_PATH_TRACING
-    dataLogF("Creating an activation, exec = %p!\n", exec);
+    dataLogF("Creating an lexicalEnvironment, exec = %p!\n", exec);
 #endif
-    JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
-    exec->setScope(activation);
-    LLINT_RETURN(JSValue(activation));
+    int scopeReg = pc[2].u.operand;
+    JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
+    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, scope, exec->codeBlock());
+    LLINT_RETURN(JSValue(lexicalEnvironment));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_new_object)
@@ -550,7 +547,7 @@ LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
             LLINT_RETURN_WITH_PC_ADJUSTMENT(result, pc[4].u.operand);
         }
     }
-    LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
+    LLINT_THROW(createInvalidInstanceofParameterError(exec, baseVal));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
@@ -658,7 +655,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
                     // below may GC.
                     pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
 
-                    if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
+                    if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
                         ASSERT(structure->previousID()->isObject());
                         pc[4].u.structure.set(
                             vm, codeBlock->ownerExecutable(), structure->previousID());
@@ -687,6 +684,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
                     }
                 }
             } else {
+                structure->didCachePropertyReplacement(vm, slot.cachedOffset());
                 pc[4].u.structure.set(
                     vm, codeBlock->ownerExecutable(), structure);
                 if (isInlineOffset(slot.cachedOffset())) {
@@ -721,8 +719,10 @@ inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
         VM& vm = exec->vm();
         Structure& structure = *baseValue.asCell()->structure(vm);
         if (JSCell::canUseFastGetOwnProperty(structure)) {
-            if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, asString(subscript)->value(exec)))
-                return result;
+            if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
+                if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
+                    return result;
+            }
         }
     }
     
@@ -734,10 +734,12 @@ inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
         return baseValue.get(exec, i);
     }
 
-    if (isName(subscript))
-        return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
-    
-    Identifier property = subscript.toString(exec)->toIdentifier(exec);
+    baseValue.requireObjectCoercible(exec);
+    if (exec->hadException())
+        return jsUndefined();
+    auto property = subscript.toPropertyKey(exec);
+    if (exec->hadException())
+        return jsUndefined();
     return baseValue.get(exec, property);
 }
 
@@ -747,26 +749,6 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
     LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
-{
-    LLINT_BEGIN();
-    JSValue arguments = LLINT_OP(2).jsValue();
-    if (!arguments) {
-        arguments = Arguments::create(vm, exec);
-        LLINT_CHECK_EXCEPTION();
-        LLINT_OP(2) = arguments;
-        exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[2].u.operand)).offset()) = arguments;
-    }
-    
-    LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
-{
-    LLINT_BEGIN();
-    LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
 {
     LLINT_BEGIN();
@@ -789,13 +771,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
         LLINT_END();
     }
 
-    if (isName(subscript)) {
-        PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
-        baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
-        LLINT_END();
-    }
-
-    Identifier property(exec, subscript.toString(exec)->value(exec));
+    auto property = subscript.toPropertyKey(exec);
     LLINT_CHECK_EXCEPTION();
     PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
     baseValue.put(exec, property, value, slot);
@@ -811,19 +787,34 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
     JSValue value = LLINT_OP_C(3).jsValue();
     RELEASE_ASSERT(baseValue.isObject());
     JSObject* baseObject = asObject(baseValue);
+    bool isStrictMode = exec->codeBlock()->isStrictMode();
     if (LIKELY(subscript.isUInt32())) {
-        uint32_t i = subscript.asUInt32();
-        baseObject->putDirectIndex(exec, i, value);
-    } else if (isName(subscript)) {
-        PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
-        baseObject->putDirect(exec->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
-    } else {
-        Identifier property(exec, subscript.toString(exec)->value(exec));
-        if (!exec->vm().exception()) { // Don't put to an object if toString threw an exception.
-            PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
-            baseObject->putDirect(exec->vm(), property, value, slot);
+        // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
+        ASSERT(isIndex(subscript.asUInt32()));
+        baseObject->putDirectIndex(exec, subscript.asUInt32(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+        LLINT_END();
+    }
+
+    if (subscript.isDouble()) {
+        double subscriptAsDouble = subscript.asDouble();
+        uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
+        if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
+            baseObject->putDirectIndex(exec, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+            LLINT_END();
         }
     }
+
+    // Don't put to an object if toString threw an exception.
+    auto property = subscript.toPropertyKey(exec);
+    if (exec->vm().exception())
+        LLINT_END();
+
+    if (Optional<uint32_t> index = parseIndex(property))
+        baseObject->putDirectIndex(exec, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+    else {
+        PutPropertySlot slot(baseObject, isStrictMode);
+        baseObject->putDirect(exec->vm(), property, value, slot);
+    }
     LLINT_END();
 }
 
@@ -840,11 +831,9 @@ LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
     uint32_t i;
     if (subscript.getUInt32(i))
         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
-    else if (isName(subscript))
-        couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     else {
         LLINT_CHECK_EXCEPTION();
-        Identifier property(exec, subscript.toString(exec)->value(exec));
+        auto property = subscript.toPropertyKey(exec);
         LLINT_CHECK_EXCEPTION();
         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
     }
@@ -864,13 +853,39 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
     LLINT_END();
 }
 
+LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
+{
+    LLINT_BEGIN();
+    ASSERT(LLINT_OP(1).jsValue().isObject());
+    JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
+    
+    JSValue getter = LLINT_OP(3).jsValue();
+    ASSERT(getter.isObject());
+    
+    baseObj->putGetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(getter));
+    LLINT_END();
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_put_setter_by_id)
+{
+    LLINT_BEGIN();
+    ASSERT(LLINT_OP(1).jsValue().isObject());
+    JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
+    
+    JSValue setter = LLINT_OP(3).jsValue();
+    ASSERT(setter.isObject());
+    
+    baseObj->putSetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(setter));
+    LLINT_END();
+}
+
 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
 {
     LLINT_BEGIN();
     ASSERT(LLINT_OP(1).jsValue().isObject());
     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
     
-    GetterSetter* accessor = GetterSetter::create(vm);
+    GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
     LLINT_CHECK_EXCEPTION();
     
     JSValue getter = LLINT_OP(3).jsValue();
@@ -880,9 +895,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
     ASSERT(getter.isObject() || setter.isObject());
     
     if (!getter.isUndefined())
-        accessor->setGetter(vm, asObject(getter));
+        accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
     if (!setter.isUndefined())
-        accessor->setSetter(vm, asObject(setter));
+        accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
     baseObj->putDirectAccessor(
         exec,
         exec->codeBlock()->identifier(pc[2].u.operand),
@@ -999,18 +1014,20 @@ LLINT_SLOW_PATH_DECL(slow_path_new_func)
     LLINT_BEGIN();
     CodeBlock* codeBlock = exec->codeBlock();
     ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
+    JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
 #if LLINT_SLOW_PATH_TRACING
     dataLogF("Creating function!\n");
 #endif
-    LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
+    LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
 {
     LLINT_BEGIN();
     CodeBlock* codeBlock = exec->codeBlock();
-    FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
-    JSFunction* func = JSFunction::create(vm, function, exec->scope());
+    JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
+    FunctionExecutable* function = codeBlock->functionExpr(pc[3].u.operand);
+    JSFunction* func = JSFunction::create(vm, function, scope);
     
     LLINT_RETURN(func);
 }
@@ -1026,7 +1043,6 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
     ExecState* exec = execCallee->callerFrame();
     VM& vm = exec->vm();
 
-    execCallee->setScope(exec->scope());
     execCallee->setCodeBlock(0);
     execCallee->clearReturnPC();
 
@@ -1041,7 +1057,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
             execCallee->setCallee(asObject(callee));
             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
             
-            LLINT_CALL_RETURN(execCallee, LLInt::getCodePtr(getHostCallReturnValue));
+            LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
         }
         
 #if LLINT_SLOW_PATH_TRACING
@@ -1064,7 +1080,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
         execCallee->setCallee(asObject(callee));
         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
 
-        LLINT_CALL_RETURN(execCallee, LLInt::getCodePtr(getHostCallReturnValue));
+        LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
     }
     
 #if LLINT_SLOW_PATH_TRACING
@@ -1077,10 +1093,12 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
 
 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
 {
+    ExecState* exec = execCallee->callerFrame();
+
 #if LLINT_SLOW_PATH_TRACING
-    dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
+    dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
 #endif
-
+    
     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
     if (!calleeAsFunctionCell)
         return handleHostCall(execCallee, pc, calleeAsValue, kind);
@@ -1088,7 +1106,6 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
     JSScope* scope = callee->scopeUnchecked();
     VM& vm = *scope->vm();
-    execCallee->setScope(scope);
     ExecutableBase* executable = callee->executable();
     
     MacroAssemblerCodePtr codePtr;
@@ -1097,10 +1114,13 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, &scope, kind);
-        execCallee->setScope(scope);
+
+        if (!isCall(kind) && functionExecutable->isBuiltinFunction())
+            LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
+
+        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
         if (error)
-            LLINT_CALL_THROW(execCallee->callerFrame(), error);
+            LLINT_CALL_THROW(exec, error);
         codeBlock = functionExecutable->codeBlockFor(kind);
         ASSERT(codeBlock);
         ArityCheckMode arity;
@@ -1114,9 +1134,7 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
     ASSERT(!!codePtr);
     
     if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
-        ExecState* execCaller = execCallee->callerFrame();
-        
-        CodeBlock* callerCodeBlock = execCaller->codeBlock();
+        CodeBlock* callerCodeBlock = exec->codeBlock();
 
         ConcurrentJITLocker locker(callerCodeBlock->m_lock);
         
@@ -1126,10 +1144,10 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
         callLinkInfo->machineCodeTarget = codePtr;
         if (codeBlock)
-            codeBlock->linkIncomingCall(execCaller, callLinkInfo);
+            codeBlock->linkIncomingCall(exec, callLinkInfo);
     }
 
-    LLINT_CALL_RETURN(execCallee, codePtr.executableAddress());
+    LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
 }
 
 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
@@ -1170,10 +1188,13 @@ LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
     // This needs to:
     // - Set up a call frame while respecting the variable arguments.
     
-    ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
-        LLINT_OP_C(4).jsValue(), pc[5].u.operand, pc[6].u.operand);
-    LLINT_CALL_CHECK_EXCEPTION(exec);
+    unsigned numUsedStackSlots = -pc[5].u.operand;
+    unsigned length = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
+        LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand);
+    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
+    ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1);
+    vm.varargsLength = length;
     vm.newCallFrameReturnValue = execCallee;
 
     LLINT_RETURN_CALLEE_FRAME(execCallee);
@@ -1190,8 +1211,8 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
 
-    loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
-    LLINT_CALL_CHECK_EXCEPTION(exec);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
+    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
     execCallee->setCallerFrame(exec);
@@ -1211,8 +1232,8 @@ LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
     
-    loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
-    LLINT_CALL_CHECK_EXCEPTION(exec);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
+    LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
     execCallee->setCallerFrame(exec);
@@ -1231,7 +1252,6 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
     execCallee->setCallerFrame(exec);
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
-    execCallee->setScope(exec->scope());
     execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
     execCallee->setCodeBlock(0);
     exec->setCurrentVPC(pc);
@@ -1240,27 +1260,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
         return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
     
     vm.hostCallReturnValue = eval(execCallee);
-    LLINT_CALL_RETURN(execCallee, LLInt::getCodePtr(getHostCallReturnValue));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
-{
-    LLINT_BEGIN();
-    ASSERT(exec->codeBlock()->needsActivation());
-    jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
-    LLINT_END();
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
-{
-    LLINT_BEGIN();
-    ASSERT(exec->codeBlock()->usesArguments());
-    Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()).jsValue());
-    if (JSValue activationValue = LLINT_OP_C(2).jsValue())
-        arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
-    else
-        arguments->tearOff(exec);
-    LLINT_END();
+    LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_strcat)
@@ -1275,50 +1275,16 @@ LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
     LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
-{
-    LLINT_BEGIN();
-    JSValue v = LLINT_OP(2).jsValue();
-    if (v.isUndefinedOrNull()) {
-        pc += pc[5].u.operand;
-        LLINT_END();
-    }
-    
-    JSObject* o = v.toObject(exec);
-    Structure* structure = o->structure();
-    JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
-    if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
-        jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
-    
-    LLINT_OP(1) = JSValue(jsPropertyNameIterator);
-    LLINT_OP(2) = JSValue(o);
-    LLINT_OP(3) = Register::withInt(0);
-    LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
-    
-    pc += OPCODE_LENGTH(op_get_pnames);
-    LLINT_END();
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_next_pname)
-{
-    LLINT_BEGIN();
-    JSObject* base = asObject(LLINT_OP(2).jsValue());
-    JSString* property = asString(LLINT_OP(1).jsValue());
-    if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
-        // Go to target.
-        pc += pc[6].u.operand;
-    } // Else, don't change the PC, so the interpreter will reloop.
-    LLINT_END();
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
 {
     LLINT_BEGIN();
-    JSValue v = LLINT_OP_C(1).jsValue();
+    JSValue v = LLINT_OP_C(2).jsValue();
     JSObject* o = v.toObject(exec);
     LLINT_CHECK_EXCEPTION();
-    
-    exec->setScope(JSWithScope::create(exec, o));
+
+    int scopeReg = pc[1].u.operand;
+    JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
+    exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
     
     LLINT_END();
 }
@@ -1326,16 +1292,22 @@ LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
 {
     LLINT_BEGIN();
-    exec->setScope(exec->scope()->next());
+    int scopeReg = pc[1].u.operand;
+    JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
+    exec->uncheckedR(scopeReg) = scope->next();
     LLINT_END();
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
 {
     LLINT_BEGIN();
-    CodeBlock* codeBlock = exec->codeBlock();
-    JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
-    exec->setScope(scope);
+    int scopeReg = pc[1].u.operand;
+    JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
+    JSValue value = LLINT_OP_C(2).jsValue();
+    SymbolTable* symbolTable = jsCast<SymbolTable*>(LLINT_OP_C(3).jsValue());
+    JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[4].u.operand);
+    JSNameScope* scope = JSNameScope::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, value, type);
+    exec->uncheckedR(scopeReg) = scope;
     LLINT_END();
 }
 
@@ -1348,10 +1320,13 @@ LLINT_SLOW_PATH_DECL(slow_path_throw)
 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
 {
     LLINT_BEGIN();
+    JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
+    RELEASE_ASSERT(errorMessageValue.isString());
+    String errorMessage = asString(errorMessageValue)->value(exec);
     if (pc[2].u.operand)
-        LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
+        LLINT_THROW(createReferenceError(exec, errorMessage));
     else
-        LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
+        LLINT_THROW(createTypeError(exec, errorMessage));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
@@ -1391,21 +1366,22 @@ LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
 LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
 {
     LLINT_BEGIN_NO_SET_PC();
-    ASSERT(vm.exception());
-    genericUnwind(&vm, exec, vm.exception());
+    genericUnwind(&vm, exec);
     LLINT_END_IMPL();
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
 {
     LLINT_BEGIN();
-    const Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
-    LLINT_RETURN(JSScope::resolve(exec, exec->scope(), ident));
+    const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
+    JSScope* scope = LLINT_OP(2).Register::scope();
+    LLINT_RETURN(JSScope::resolve(exec, scope, ident));
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
 {
     LLINT_BEGIN();
+
     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
     JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
     ResolveModeAndType modeAndType(pc[4].u.operand);
@@ -1421,9 +1397,13 @@ LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
             CodeBlock* codeBlock = exec->codeBlock();
-            ConcurrentJITLocker locker(codeBlock->m_lock);
-            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
-            pc[6].u.operand = slot.cachedOffset();
+            Structure* structure = scope->structure(vm);
+            {
+                ConcurrentJITLocker locker(codeBlock->m_lock);
+                pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
+                pc[6].u.operand = slot.cachedOffset();
+            }
+            structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
         }
     }
 
@@ -1433,26 +1413,31 @@ LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
 {
     LLINT_BEGIN();
+
     CodeBlock* codeBlock = exec->codeBlock();
     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
     JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
     JSValue value = LLINT_OP_C(3).jsValue();
     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
+    if (modeAndType.type() == LocalClosureVar) {
+        JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
+        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
+        
+        // Have to do this *after* the write, because if this puts the set into IsWatched, then we need
+        // to have already changed the value of the variable. Otherwise we might watch and constant-fold
+        // to the Undefined value from before the assignment.
+        if (WatchpointSet* set = pc[5].u.watchpointSet)
+            set->touch("Executed op_put_scope<LocalClosureVar>");
+        LLINT_END();
+    }
 
     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
         LLINT_THROW(createUndefinedVariableError(exec, ident));
 
     PutPropertySlot slot(scope, codeBlock->isStrictMode());
     scope->methodTable()->put(scope, exec, ident, value, slot);
-
-    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
-    if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
-        if (slot.isCacheablePut() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
-            ConcurrentJITLocker locker(codeBlock->m_lock);
-            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
-            pc[6].u.operand = slot.cachedOffset();
-        }
-    }
+    
+    CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
 
     LLINT_END();
 }
@@ -1461,7 +1446,7 @@ extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCall
 {
     ExecState* exec = vm->topCallFrame;
     if (!exec)
-        exec = protoFrame->scope()->globalObject()->globalExec();
+        exec = protoFrame->callee()->globalObject()->globalExec();
     throwStackOverflowError(exec);
     return encodeResult(0, 0);
 }
index 2f8cffd0ef14904f4f99cf539dc8937d3e40c028..f8f38641007af80fd091c48214f07ef1c86f08d9 100644 (file)
@@ -62,7 +62,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct_arityCheck);
 LLINT_SLOW_PATH_HIDDEN_DECL(loop_osr);
 LLINT_SLOW_PATH_HIDDEN_DECL(replace);
 LLINT_SLOW_PATH_HIDDEN_DECL(stack_check);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_activation);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_lexical_environment);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_object);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array_with_size);
@@ -76,11 +76,12 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_argument_by_val);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_pname);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val_direct);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_index);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_getter_by_id);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_setter_by_id);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_getter_setter);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jtrue);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jfalse);
@@ -103,12 +104,9 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_size_frame_for_varargs);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_varargs);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_varargs);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_eval);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_activation);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_pnames);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_next_pname);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pop_scope);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_name_scope);
index e8f8a1714efa5b3fbc7da866c0c85caff60db612..8ab96b30475fd554def8b32662496632eaf96d9a 100644 (file)
@@ -37,6 +37,7 @@
 #include "LinkBuffer.h"
 #include "LowLevelInterpreter.h"
 #include "ProtoCallFrame.h"
+#include "StackAlignment.h"
 #include "VM.h"
 
 namespace JSC {
@@ -93,18 +94,27 @@ MacroAssemblerCodeRef programEntryThunkGenerator(VM* vm)
 
 // Non-JIT (i.e. C Loop LLINT) case:
 
-EncodedJSValue callToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
+EncodedJSValue vmEntryToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
 {
-    JSValue result = CLoop::execute(llint_call_to_javascript, executableAddress, vm, protoCallFrame);
+    JSValue result = CLoop::execute(llint_vm_entry_to_javascript, executableAddress, vm, protoCallFrame);
     return JSValue::encode(result);
 }
 
-EncodedJSValue callToNativeFunction(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
+EncodedJSValue vmEntryToNative(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
 {
-    JSValue result = CLoop::execute(llint_call_to_native_function, executableAddress, vm, protoCallFrame);
+    JSValue result = CLoop::execute(llint_vm_entry_to_native, executableAddress, vm, protoCallFrame);
     return JSValue::encode(result);
 }
 
+extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame* entryFrame)
+{
+    // The C Loop doesn't have any callee save registers, so the VMEntryRecord is allocated at the base of the frame.
+    intptr_t stackAlignment = stackAlignmentBytes();
+    intptr_t VMEntryTotalFrameSize = (sizeof(VMEntryRecord) + (stackAlignment - 1)) & ~(stackAlignment - 1);
+    return reinterpret_cast<VMEntryRecord*>(static_cast<char*>(entryFrame) - VMEntryTotalFrameSize);
+}
+
+
 #endif // ENABLE(JIT)
 
 } // namespace JSC
index 98cff784f6ef47b90aba6523756d4673bf75da7b..0d1be6bdaeadf79487ce90668264685188a8bd12 100644 (file)
@@ -34,8 +34,8 @@ class VM;
 struct ProtoCallFrame;
 
 extern "C" {
-    EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);
-    EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue vmEntryToJavaScript(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*);
 }
 
 namespace LLInt {
index f0aa44ef07b818c28266527a08f24bcf18433d28..d9cd01b50c87fadc30cd38caec516781da6b4bf2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # First come the common protocols that both interpreters use. Note that each
 # of these must have an ASSERT() in LLIntData.cpp
 
-# Work-around for the fact that the toolchain's awareness of armv7s results in
-# a separate slab in the fat binary, yet the offlineasm doesn't know to expect
-# it.
+# Work-around for the fact that the toolchain's awareness of armv7k / armv7s
+# results in a separate slab in the fat binary, yet the offlineasm doesn't know
+# to expect it.
+if ARMv7k
+end
 if ARMv7s
 end
 
 # These declarations must match interpreter/JSStack.h.
 
 if JSVALUE64
-const PtrSize = 8
-const CallFrameHeaderSlots = 6
+    const PtrSize = 8
+    const CallFrameHeaderSlots = 5
 else
-const PtrSize = 4
-const CallFrameHeaderSlots = 5
-const CallFrameAlignSlots = 1
+    const PtrSize = 4
+    const CallFrameHeaderSlots = 4
+    const CallFrameAlignSlots = 1
 end
 const SlotSize = 8
 
+const JSEnvironmentRecord_variables = (sizeof JSEnvironmentRecord + SlotSize - 1) & ~(SlotSize - 1)
+const DirectArguments_storage = (sizeof DirectArguments + SlotSize - 1) & ~(SlotSize - 1)
+
+const StackAlignment = 16
+const StackAlignmentMask = StackAlignment - 1
+
 const CallerFrameAndPCSize = 2 * PtrSize
 
 const CallerFrame = 0
 const ReturnPC = CallerFrame + PtrSize
 const CodeBlock = ReturnPC + PtrSize
-const ScopeChain = CodeBlock + SlotSize
-const Callee = ScopeChain + SlotSize
+const Callee = CodeBlock + SlotSize
 const ArgumentCount = Callee + SlotSize
 const ThisArgumentOffset = ArgumentCount + SlotSize
+const FirstArgumentOffset = ThisArgumentOffset + SlotSize
 const CallFrameHeaderSize = ThisArgumentOffset
 
 # Some value representation constants.
 if JSVALUE64
-const TagBitTypeOther = 0x2
-const TagBitBool      = 0x4
-const TagBitUndefined = 0x8
-const ValueEmpty      = 0x0
-const ValueFalse      = TagBitTypeOther | TagBitBool
-const ValueTrue       = TagBitTypeOther | TagBitBool | 1
-const ValueUndefined  = TagBitTypeOther | TagBitUndefined
-const ValueNull       = TagBitTypeOther
+    const TagBitTypeOther = 0x2
+    const TagBitBool      = 0x4
+    const TagBitUndefined = 0x8
+    const ValueEmpty      = 0x0
+    const ValueFalse      = TagBitTypeOther | TagBitBool
+    const ValueTrue       = TagBitTypeOther | TagBitBool | 1
+    const ValueUndefined  = TagBitTypeOther | TagBitUndefined
+    const ValueNull       = TagBitTypeOther
     const TagTypeNumber   = 0xffff000000000000
     const TagMask         = TagTypeNumber | TagBitTypeOther
 else
-const Int32Tag = -1
-const BooleanTag = -2
-const NullTag = -3
-const UndefinedTag = -4
-const CellTag = -5
-const EmptyValueTag = -6
-const DeletedValueTag = -7
-const LowestTag = DeletedValueTag
+    const Int32Tag = -1
+    const BooleanTag = -2
+    const NullTag = -3
+    const UndefinedTag = -4
+    const CellTag = -5
+    const EmptyValueTag = -6
+    const DeletedValueTag = -7
+    const LowestTag = DeletedValueTag
 end
 
 const CallOpCodeSize = 9
 
 if X86_64 or ARM64 or C_LOOP
-const maxFrameExtentForSlowPathCall = 0
+    const maxFrameExtentForSlowPathCall = 0
 elsif ARM or ARMv7_TRADITIONAL or ARMv7 or SH4
-const maxFrameExtentForSlowPathCall = 24
+    const maxFrameExtentForSlowPathCall = 24
 elsif X86 or X86_WIN
-const maxFrameExtentForSlowPathCall = 40
+    const maxFrameExtentForSlowPathCall = 40
 elsif MIPS
-const maxFrameExtentForSlowPathCall = 40
+    const maxFrameExtentForSlowPathCall = 40
 elsif X86_64_WIN
-const maxFrameExtentForSlowPathCall = 64
+    const maxFrameExtentForSlowPathCall = 64
 end
 
 # Watchpoint states
@@ -152,7 +160,7 @@ const ArrayStorageShape        = 28
 const SlowPutArrayStorageShape = 30
 
 # Type constants.
-const StringType = 5
+const StringType = 6
 const ObjectType = 18
 const FinalObjectType = 19
 
@@ -173,7 +181,7 @@ const FunctionCode = 2
 const LLIntReturnPC = ArgumentCount + TagOffset
 
 # String flags.
-const HashFlags8BitBuffer = 32
+const HashFlags8BitBuffer = 8
 
 # Copied from PropertyOffset.h
 const firstOutOfLineOffset = 100
@@ -182,14 +190,15 @@ const firstOutOfLineOffset = 100
 const GlobalProperty = 0
 const GlobalVar = 1
 const ClosureVar = 2
-const GlobalPropertyWithVarInjectionChecks = 3
-const GlobalVarWithVarInjectionChecks = 4
-const ClosureVarWithVarInjectionChecks = 5
-const Dynamic = 6
+const LocalClosureVar = 3
+const GlobalPropertyWithVarInjectionChecks = 4
+const GlobalVarWithVarInjectionChecks = 5
+const ClosureVarWithVarInjectionChecks = 6
+const Dynamic = 7
 
 const ResolveModeMask = 0xffff
 
-const MarkedBlockSize = 64 * 1024
+const MarkedBlockSize = 16 * 1024
 const MarkedBlockMask = ~(MarkedBlockSize - 1)
 # Constants for checking mark bits.
 const AtomNumberShift = 3
@@ -237,9 +246,9 @@ macro checkStackPointerAlignment(tempReg, location)
         if ARM or ARMv7 or ARMv7_TRADITIONAL
             # ARM can't do logical ops with the sp as a source
             move sp, tempReg
-            andp 0xf, tempReg
+            andp StackAlignmentMask, tempReg
         else
-            andp sp, 0xf, tempReg
+            andp sp, StackAlignmentMask, tempReg
         end
         btpz tempReg, .stackPointerOkay
         move location, tempReg
@@ -248,6 +257,126 @@ macro checkStackPointerAlignment(tempReg, location)
     end
 end
 
+if C_LOOP
+    const CalleeSaveRegisterCount = 0
+elsif ARM or ARMv7_TRADITIONAL or ARMv7
+    const CalleeSaveRegisterCount = 7
+elsif ARM64
+    const CalleeSaveRegisterCount = 10
+elsif SH4 or X86_64 or MIPS
+    const CalleeSaveRegisterCount = 5
+elsif X86 or X86_WIN
+    const CalleeSaveRegisterCount = 3
+elsif X86_64_WIN
+    const CalleeSaveRegisterCount = 7
+end
+
+const CalleeRegisterSaveSize = CalleeSaveRegisterCount * PtrSize
+
+# VMEntryTotalFrameSize includes the space for struct VMEntryRecord and the
+# callee save registers rounded up to keep the stack aligned
+const VMEntryTotalFrameSize = (CalleeRegisterSaveSize + sizeof VMEntryRecord + StackAlignment - 1) & ~StackAlignmentMask
+
+macro pushCalleeSaves()
+    if C_LOOP
+    elsif ARM or ARMv7_TRADITIONAL
+        emit "push {r4-r10}"
+    elsif ARMv7
+        emit "push {r4-r6, r8-r11}"
+    elsif ARM64
+        emit "stp x20, x19, [sp, #-16]!"
+        emit "stp x22, x21, [sp, #-16]!"
+        emit "stp x24, x23, [sp, #-16]!"
+        emit "stp x26, x25, [sp, #-16]!"
+        emit "stp x28, x27, [sp, #-16]!"
+    elsif MIPS
+        emit "addiu $sp, $sp, -20"
+        emit "sw $20, 16($sp)"
+        emit "sw $19, 12($sp)"
+        emit "sw $18, 8($sp)"
+        emit "sw $17, 4($sp)"
+        emit "sw $16, 0($sp)"
+    elsif SH4
+        emit "mov.l r13, @-r15"
+        emit "mov.l r11, @-r15"
+        emit "mov.l r10, @-r15"
+        emit "mov.l r9, @-r15"
+        emit "mov.l r8, @-r15"
+    elsif X86
+        emit "push %esi"
+        emit "push %edi"
+        emit "push %ebx"
+    elsif X86_WIN
+        emit "push esi"
+        emit "push edi"
+        emit "push ebx"
+    elsif X86_64
+        emit "push %r12"
+        emit "push %r13"
+        emit "push %r14"
+        emit "push %r15"
+        emit "push %rbx"
+    elsif X86_64_WIN
+        emit "push r12"
+        emit "push r13"
+        emit "push r14"
+        emit "push r15"
+        emit "push rbx"
+        emit "push rdi"
+        emit "push rsi"
+    end
+end
+
+macro popCalleeSaves()
+    if C_LOOP
+    elsif ARM or ARMv7_TRADITIONAL
+        emit "pop {r4-r10}"
+    elsif ARMv7
+        emit "pop {r4-r6, r8-r11}"
+    elsif ARM64
+        emit "ldp x28, x27, [sp], #16"
+        emit "ldp x26, x25, [sp], #16"
+        emit "ldp x24, x23, [sp], #16"
+        emit "ldp x22, x21, [sp], #16"
+        emit "ldp x20, x19, [sp], #16"
+    elsif MIPS
+        emit "lw $16, 0($sp)"
+        emit "lw $17, 4($sp)"
+        emit "lw $18, 8($sp)"
+        emit "lw $19, 12($sp)"
+        emit "lw $20, 16($sp)"
+        emit "addiu $sp, $sp, 20"
+    elsif SH4
+        emit "mov.l @r15+, r8"
+        emit "mov.l @r15+, r9"
+        emit "mov.l @r15+, r10"
+        emit "mov.l @r15+, r11"
+        emit "mov.l @r15+, r13"
+    elsif X86
+        emit "pop %ebx"
+        emit "pop %edi"
+        emit "pop %esi"
+    elsif X86_WIN
+        emit "pop ebx"
+        emit "pop edi"
+        emit "pop esi"
+    elsif X86_64
+        emit "pop %rbx"
+        emit "pop %r15"
+        emit "pop %r14"
+        emit "pop %r13"
+        emit "pop %r12"
+    elsif X86_64_WIN
+        emit "pop rsi"
+        emit "pop rdi"
+        emit "pop rbx"
+        emit "pop r15"
+        emit "pop r14"
+        emit "pop r13"
+        emit "pop r12"
+    end
+end
+
 macro preserveCallerPCAndCFR()
     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
         push lr
@@ -255,7 +384,7 @@ macro preserveCallerPCAndCFR()
     elsif X86 or X86_WIN or X86_64 or X86_64_WIN
         push cfr
     elsif ARM64
-        pushLRAndFP
+        push cfr, lr
     else
         error
     end
@@ -270,7 +399,7 @@ macro restoreCallerPCAndCFR()
     elsif X86 or X86_WIN or X86_64 or X86_64_WIN
         pop cfr
     elsif ARM64
-        popLRAndFP
+        pop lr, cfr
     end
 end
 
@@ -300,7 +429,7 @@ macro functionPrologue()
     if X86 or X86_WIN or X86_64 or X86_64_WIN
         push cfr
     elsif ARM64
-        pushLRAndFP
+        push cfr, lr
     elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
         push lr
         push cfr
@@ -312,99 +441,34 @@ macro functionEpilogue()
     if X86 or X86_WIN or X86_64 or X86_64_WIN
         pop cfr
     elsif ARM64
-        popLRAndFP
+        pop lr, cfr
     elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
         pop cfr
         pop lr
     end
 end
 
-macro callToJavaScriptPrologue()
-    if X86_64 or X86_64_WIN
-        push cfr
-        push t0
-    elsif X86 or X86_WIN
-        push cfr
-    elsif ARM64
-        pushLRAndFP
-    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
-        push lr
-        push cfr
-    end
-    pushCalleeSaves
-    if X86
-        subp 12, sp
-    elsif X86_WIN
-        subp 16, sp
-        move sp, t4
-        move t4, t0
-        move t4, t2
-        andp 0xf, t2
-        andp 0xfffffff0, t0
-        move t0, sp
-        storep t4, [sp]
-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL
-        subp 4, sp
-        move sp, t4
-        clrbp t4, 0xf, t5
-        move t5, sp
-        storep t4, [sp]
-    end
+macro vmEntryRecord(entryFramePointer, resultReg)
+    subp entryFramePointer, VMEntryTotalFrameSize, resultReg
 end
 
-macro callToJavaScriptEpilogue()
-    if ARMv7
-        addp CallFrameHeaderSlots * 8, cfr, t4
-        move t4, sp
-    else
-        addp CallFrameHeaderSlots * 8, cfr, sp
-    end
-
-    loadp CallerFrame[cfr], cfr
-
-    if X86
-        addp 12, sp
-    elsif X86_WIN
-        pop t4
-        move t4, sp
-        addp 16, sp
-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL
-        pop t4
-        move t4, sp
-        addp 4, sp
-    end
-
-    popCalleeSaves
-    if X86_64 or X86_64_WIN
-        pop t2
-        pop cfr
-    elsif X86 or X86_WIN
-        pop cfr
-    elsif ARM64
-        popLRAndFP
-    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
-        pop cfr
-        pop lr
-    end
+macro getFrameRegisterSizeForCodeBlock(codeBlock, size)
+    loadi CodeBlock::m_numCalleeRegisters[codeBlock], size
+    lshiftp 3, size
+    addp maxFrameExtentForSlowPathCall, size
 end
 
-macro moveStackPointerForCodeBlock(codeBlock, scratch)
-    loadi CodeBlock::m_numCalleeRegisters[codeBlock], scratch
-    lshiftp 3, scratch
-    addp maxFrameExtentForSlowPathCall, scratch
+macro restoreStackPointerAfterCall()
+    loadp CodeBlock[cfr], t2
+    getFrameRegisterSizeForCodeBlock(t2, t4)
     if ARMv7
-        subp cfr, scratch, scratch
-        move scratch, sp
+        subp cfr, t4, t4
+        move t4, sp
     else
-        subp cfr, scratch, sp
+        subp cfr, t4, sp
     end
 end
 
-macro restoreStackPointerAfterCall()
-    loadp CodeBlock[cfr], t2
-    moveStackPointerForCodeBlock(t2, t4)
-end
-
 macro traceExecution()
     if EXECUTION_TRACING
         callSlowPath(_llint_trace)
@@ -452,11 +516,15 @@ macro arrayProfile(cellAndIndexingType, profile, scratch)
     loadb JSCell::m_indexingType[cell], indexingType
 end
 
-macro checkMarkByte(cell, scratch1, scratch2, continuation)
+macro skipIfIsRememberedOrInEden(cell, scratch1, scratch2, continuation)
     loadb JSCell::m_gcData[cell], scratch1
     continuation(scratch1)
 end
 
+macro notifyWrite(set, slow)
+    bbneq WatchpointSet::m_state[set], IsInvalidated, slow
+end
+
 macro checkSwitchToJIT(increment, action)
     loadp CodeBlock[cfr], t0
     baddis increment, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t0], .continue
@@ -477,13 +545,21 @@ macro assertNotConstant(index)
 end
 
 macro functionForCallCodeBlockGetter(targetRegister)
-    loadp Callee[cfr], targetRegister
+    if JSVALUE64
+        loadp Callee[cfr], targetRegister
+    else
+        loadp Callee + PayloadOffset[cfr], targetRegister
+    end
     loadp JSFunction::m_executable[targetRegister], targetRegister
     loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
 end
 
 macro functionForConstructCodeBlockGetter(targetRegister)
-    loadp Callee[cfr], targetRegister
+    if JSVALUE64
+        loadp Callee[cfr], targetRegister
+    else
+        loadp Callee + PayloadOffset[cfr], targetRegister
+    end
     loadp JSFunction::m_executable[targetRegister], targetRegister
     loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
 end
@@ -512,38 +588,35 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
         addp maxFrameExtentForSlowPathCall, sp
     end
     codeBlockGetter(t1)
-if C_LOOP
-else
-    baddis 5, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t1], .continue
-    if JSVALUE64
-        cCall2(osrSlowPath, cfr, PC)
-    else
-        # We are after the function prologue, but before we have set up sp from the CodeBlock.
-        # Temporarily align stack pointer for this call.
-        subp 8, sp
-        cCall2(osrSlowPath, cfr, PC)
-        addp 8, sp
-    end
-    btpz t0, .recover
-    move cfr, sp # restore the previous sp
-    # pop the callerFrame since we will jump to a function that wants to save it
-    if ARM64
-        popLRAndFP
-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
-        pop cfr
-        pop lr
-    else
-        pop cfr
+    if not C_LOOP
+        baddis 5, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t1], .continue
+        if JSVALUE64
+            cCall2(osrSlowPath, cfr, PC)
+        else
+            # We are after the function prologue, but before we have set up sp from the CodeBlock.
+            # Temporarily align stack pointer for this call.
+            subp 8, sp
+            cCall2(osrSlowPath, cfr, PC)
+            addp 8, sp
+        end
+        btpz t0, .recover
+        move cfr, sp # restore the previous sp
+        # pop the callerFrame since we will jump to a function that wants to save it
+        if ARM64
+            pop lr, cfr
+        elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
+            pop cfr
+            pop lr
+        else
+            pop cfr
+        end
+        jmp t0
+    .recover:
+        codeBlockGetter(t1)
+    .continue:
     end
-    jmp t0
-.recover:
-    codeBlockGetter(t1)
-.continue:
-end
 
     codeBlockSetter(t1)
-    
-    moveStackPointerForCodeBlock(t1, t2)
 
     # Set up the PC.
     if JSVALUE64
@@ -552,6 +625,29 @@ end
     else
         loadp CodeBlock::m_instructions[t1], PC
     end
+
+    # Get new sp in t0 and check stack height.
+    getFrameRegisterSizeForCodeBlock(t1, t0)
+    subp cfr, t0, t0
+    loadp CodeBlock::m_vm[t1], t2
+    bpbeq VM::m_jsStackLimit[t2], t0, .stackHeightOK
+
+    # Stack height check failed - need to call a slow_path.
+    subp maxFrameExtentForSlowPathCall, sp # Set up temporary stack pointer for call
+    callSlowPath(_llint_stack_check)
+    bpeq t1, 0, .stackHeightOKGetCodeBlock
+    move t1, cfr
+    dispatch(0) # Go to exception handler in PC
+
+.stackHeightOKGetCodeBlock:
+    # Stack check slow path returned that the stack was ok.
+    # Since they were clobbered, need to get CodeBlock and new sp
+    codeBlockGetter(t1)
+    getFrameRegisterSizeForCodeBlock(t1, t0)
+    subp cfr, t0, t0
+
+.stackHeightOK:
+    move t0, sp
 end
 
 # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
@@ -586,42 +682,24 @@ macro functionInitialization(profileArgSkip)
     end
     baddpnz -8, t0, .argumentProfileLoop
 .argumentProfileDone:
-        
-    # Check stack height.
-    loadi CodeBlock::m_numCalleeRegisters[t1], t0
-    loadp CodeBlock::m_vm[t1], t2
-    lshiftp 3, t0
-    addi maxFrameExtentForSlowPathCall, t0
-    subp cfr, t0, t0
-    bpbeq VM::m_jsStackLimit[t2], t0, .stackHeightOK
-
-    # Stack height check failed - need to call a slow_path.
-    callSlowPath(_llint_stack_check)
-    bpeq t1, 0, .stackHeightOK
-    move t1, cfr
-.stackHeightOK:
 end
 
 macro allocateJSObject(allocator, structure, result, scratch1, slowCase)
-    if ALWAYS_ALLOCATE_SLOW
-        jmp slowCase
-    else
-        const offsetOfFirstFreeCell = 
-            MarkedAllocator::m_freeList + 
-            MarkedBlock::FreeList::head
-
-        # Get the object from the free list.   
-        loadp offsetOfFirstFreeCell[allocator], result
-        btpz result, slowCase
-        
-        # Remove the object from the free list.
-        loadp [result], scratch1
-        storep scratch1, offsetOfFirstFreeCell[allocator]
+    const offsetOfFirstFreeCell = 
+        MarkedAllocator::m_freeList + 
+        MarkedBlock::FreeList::head
+
+    # Get the object from the free list.   
+    loadp offsetOfFirstFreeCell[allocator], result
+    btpz result, slowCase
     
-        # Initialize the object.
-        storep 0, JSObject::m_butterfly[result]
-        storeStructureWithTypeInfo(result, structure, scratch1)
-    end
+    # Remove the object from the free list.
+    loadp [result], scratch1
+    storep scratch1, offsetOfFirstFreeCell[allocator]
+
+    # Initialize the object.
+    storep 0, JSObject::m_butterfly[result]
+    storeStructureWithTypeInfo(result, structure, scratch1)
 end
 
 macro doReturn()
@@ -630,102 +708,122 @@ macro doReturn()
 end
 
 # stub to call into JavaScript or Native functions
-# EncodedJSValue callToJavaScript(void* code, ExecState** vmTopCallFrame, ProtoCallFrame* protoFrame)
-# EncodedJSValue callToNativeFunction(void* code, ExecState** vmTopCallFrame, ProtoCallFrame* protoFrame)
+# EncodedJSValue vmEntryToJavaScript(void* code, VM* vm, ProtoCallFrame* protoFrame)
+# EncodedJSValue vmEntryToNativeFunction(void* code, VM* vm, ProtoCallFrame* protoFrame)
 
 if C_LOOP
-_llint_call_to_javascript:
+    _llint_vm_entry_to_javascript:
 else
-global _callToJavaScript
-_callToJavaScript:
+    global _vmEntryToJavaScript
+    _vmEntryToJavaScript:
 end
-    doCallToJavaScript(makeJavaScriptCall)
+    doVMEntry(makeJavaScriptCall)
 
 
 if C_LOOP
-_llint_call_to_native_function:
+    _llint_vm_entry_to_native:
 else
-global _callToNativeFunction
-_callToNativeFunction:
+    global _vmEntryToNative
+    _vmEntryToNative:
 end
-    doCallToJavaScript(makeHostFunctionCall)
-
-
-if C_LOOP
-else
-# void sanitizeStackForVMImpl(VM* vm)
-global _sanitizeStackForVMImpl
-_sanitizeStackForVMImpl:
-    if X86_64
-        const vm = t4
-        const address = t1
-        const zeroValue = t0
-    elsif X86_64_WIN
-        const vm = t2
-        const address = t1
-        const zeroValue = t0
-    elsif X86 or X86_WIN
-        const vm = t2
-        const address = t1
-        const zeroValue = t0
-    else
-        const vm = a0
-        const address = t1
-        const zeroValue = t2
-    end
-
-    if X86 or X86_WIN
-        loadp 4[sp], vm
-    end
-
-    loadp VM::m_lastStackTop[vm], address
-    bpbeq sp, address, .zeroFillDone
-
-    move 0, zeroValue
-.zeroFillLoop:
-    storep zeroValue, [address]
-    addp PtrSize, address
-    bpa sp, address, .zeroFillLoop
-
-.zeroFillDone:
-    move sp, address
-    storep address, VM::m_lastStackTop[vm]
-    ret
+    doVMEntry(makeHostFunctionCall)
+
+
+if not C_LOOP
+    # void sanitizeStackForVMImpl(VM* vm)
+    global _sanitizeStackForVMImpl
+    _sanitizeStackForVMImpl:
+        if X86_64
+            const vm = t4
+            const address = t1
+            const zeroValue = t0
+        elsif X86_64_WIN
+            const vm = t2
+            const address = t1
+            const zeroValue = t0
+        elsif X86 or X86_WIN
+            const vm = t2
+            const address = t1
+            const zeroValue = t0
+        else
+            const vm = a0
+            const address = t1
+            const zeroValue = t2
+        end
+    
+        if X86 or X86_WIN
+            loadp 4[sp], vm
+        end
+    
+        loadp VM::m_lastStackTop[vm], address
+        bpbeq sp, address, .zeroFillDone
+    
+        move 0, zeroValue
+    .zeroFillLoop:
+        storep zeroValue, [address]
+        addp PtrSize, address
+        bpa sp, address, .zeroFillLoop
+    
+    .zeroFillDone:
+        move sp, address
+        storep address, VM::m_lastStackTop[vm]
+        ret
+    
+    # VMEntryRecord* vmEntryRecord(const VMEntryFrame* entryFrame)
+    global _vmEntryRecord
+    _vmEntryRecord:
+        if X86_64
+            const entryFrame = t4
+            const result = t0
+        elsif X86 or X86_WIN or X86_64_WIN
+            const entryFrame = t2
+            const result = t0
+        else
+            const entryFrame = a0
+            const result = t0
+        end
+    
+        if X86 or X86_WIN
+            loadp 4[sp], entryFrame
+        end
+    
+        vmEntryRecord(entryFrame, result)
+        ret
 end
 
-
 if C_LOOP
-# Dummy entry point the C Loop uses to initialize.
-_llint_entry:
-    crash()
-else
-macro initPCRelative(pcBase)
-    if X86_64 or X86_64_WIN
-        call _relativePCBase
-    _relativePCBase:
-        pop pcBase
-    elsif X86 or X86_WIN
-        call _relativePCBase
-    _relativePCBase:
-        pop pcBase
-        loadp 20[sp], t4
-    elsif ARM64
-    elsif ARMv7
-    _relativePCBase:
-        move pc, pcBase
-        subp 3, pcBase   # Need to back up the PC and set the Thumb2 bit
-    elsif ARM or ARMv7_TRADITIONAL
-    _relativePCBase:
-        move pc, pcBase
-        subp 8, pcBase
-    elsif MIPS
-        crash()  # Need to replace with any initialization steps needed to step up PC relative address calculation
-    elsif SH4
-        mova _relativePCBase, t0
-        move t0, pcBase
-        alignformova
-    _relativePCBase:
-    end
+    # Dummy entry point the C Loop uses to initialize.
+    _llint_entry:
+        crash()
+    else
+    macro initPCRelative(pcBase)
+        if X86_64 or X86_64_WIN
+            call _relativePCBase
+        _relativePCBase:
+            pop pcBase
+        elsif X86 or X86_WIN
+            call _relativePCBase
+        _relativePCBase:
+            pop pcBase
+            loadp 20[sp], t4
+        elsif ARM64
+        elsif ARMv7
+        _relativePCBase:
+            move pc, pcBase
+            subp 3, pcBase   # Need to back up the PC and set the Thumb2 bit
+        elsif ARM or ARMv7_TRADITIONAL
+        _relativePCBase:
+            move pc, pcBase
+            subp 8, pcBase
+        elsif MIPS
+            la _relativePCBase, pcBase
+        _relativePCBase:
+        elsif SH4
+            mova _relativePCBase, t0
+            move t0, pcBase
+            alignformova
+        _relativePCBase:
+        end
 end
 
 macro setEntryAddress(index, label)
@@ -757,7 +855,12 @@ macro setEntryAddress(index, label)
         storep t2, [a0, t3, 4]
         flushcp # Force constant pool flush to avoid "pcrel too far" link error.
     elsif MIPS
-        crash()  # Need to replace with code to turn label into and absolute address and save at index
+        la label, t2
+        la _relativePCBase, t3
+        subp t3, t2
+        addp t2, t1, t2
+        move index, t3
+        storep t2, [a0, t3, 4]
     end
 end
 
@@ -765,13 +868,13 @@ global _llint_entry
 # Entry point for the llint to initialize.
 _llint_entry:
     functionPrologue()
-    pushCalleeSaves
+    pushCalleeSaves()
     initPCRelative(t1)
 
     # Include generated bytecode initialization file.
     include InitBytecodes
 
-    popCalleeSaves
+    popCalleeSaves()
     functionEpilogue()
     ret
 end
@@ -823,10 +926,28 @@ end
 
 
 # Value-representation-agnostic code.
-_llint_op_touch_entry:
+_llint_op_create_direct_arguments:
     traceExecution()
-    callSlowPath(_slow_path_touch_entry)
-    dispatch(1)
+    callSlowPath(_slow_path_create_direct_arguments)
+    dispatch(2)
+
+
+_llint_op_create_scoped_arguments:
+    traceExecution()
+    callSlowPath(_slow_path_create_scoped_arguments)
+    dispatch(3)
+
+
+_llint_op_create_out_of_band_arguments:
+    traceExecution()
+    callSlowPath(_slow_path_create_out_of_band_arguments)
+    dispatch(2)
+
+
+_llint_op_new_func:
+    traceExecution()
+    callSlowPath(_llint_slow_path_new_func)
+    dispatch(4)
 
 
 _llint_op_new_array:
@@ -889,12 +1010,11 @@ _llint_op_typeof:
     dispatch(3)
 
 
-_llint_op_is_object:
+_llint_op_is_object_or_null:
     traceExecution()
-    callSlowPath(_slow_path_is_object)
+    callSlowPath(_slow_path_is_object_or_null)
     dispatch(3)
 
-
 _llint_op_is_function:
     traceExecution()
     callSlowPath(_slow_path_is_function)
@@ -939,6 +1059,18 @@ _llint_op_put_by_index:
     dispatch(4)
 
 
+_llint_op_put_getter_by_id:
+    traceExecution()
+    callSlowPath(_llint_slow_path_put_getter_by_id)
+    dispatch(4)
+
+
+_llint_op_put_setter_by_id:
+    traceExecution()
+    callSlowPath(_llint_slow_path_put_setter_by_id)
+    dispatch(4)
+
+
 _llint_op_put_getter_setter:
     traceExecution()
     callSlowPath(_llint_slow_path_put_getter_setter)
@@ -1027,12 +1159,14 @@ _llint_op_loop_hint:
     traceExecution()
     loadp CodeBlock[cfr], t1
     loadp CodeBlock::m_vm[t1], t1
-    loadb VM::watchdog+Watchdog::m_timerDidFire[t1], t0
-    btbnz t0, .handleWatchdogTimer
+    loadp VM::watchdog[t1], t0
+    btpnz t0, .handleWatchdogTimer
 .afterWatchdogTimerCheck:
     checkSwitchToJITForLoop()
     dispatch(1)
 .handleWatchdogTimer:
+    loadb Watchdog::m_timerDidFire[t0], t0
+    btbz t0, .afterWatchdogTimerCheck
     callWatchdogTimerHandler(.throwHandler)
     jmp .afterWatchdogTimerCheck
 .throwHandler:
@@ -1047,7 +1181,7 @@ _llint_op_switch_string:
 _llint_op_new_func_exp:
     traceExecution()
     callSlowPath(_llint_slow_path_new_func_exp)
-    dispatch(3)
+    dispatch(4)
 
 
 _llint_op_call:
@@ -1147,28 +1281,22 @@ _llint_op_strcat:
     dispatch(4)
 
 
-_llint_op_get_pnames:
-    traceExecution()
-    callSlowPath(_llint_slow_path_get_pnames)
-    dispatch(0) # The slow_path either advances the PC or jumps us to somewhere else.
-
-
 _llint_op_push_with_scope:
     traceExecution()
     callSlowPath(_llint_slow_path_push_with_scope)
-    dispatch(2)
+    dispatch(3)
 
 
 _llint_op_pop_scope:
     traceExecution()
     callSlowPath(_llint_slow_path_pop_scope)
-    dispatch(1)
+    dispatch(2)
 
 
 _llint_op_push_name_scope:
     traceExecution()
     callSlowPath(_llint_slow_path_push_name_scope)
-    dispatch(4)
+    dispatch(5)
 
 
 _llint_op_throw:
@@ -1222,6 +1350,56 @@ _llint_native_call_trampoline:
 _llint_native_construct_trampoline:
     nativeCallTrampoline(NativeExecutable::m_constructor)
 
+_llint_op_get_enumerable_length:
+    traceExecution()
+    callSlowPath(_slow_path_get_enumerable_length)
+    dispatch(3)
+
+_llint_op_has_indexed_property:
+    traceExecution()
+    callSlowPath(_slow_path_has_indexed_property)
+    dispatch(5)
+
+_llint_op_has_structure_property:
+    traceExecution()
+    callSlowPath(_slow_path_has_structure_property)
+    dispatch(5)
+
+_llint_op_has_generic_property:
+    traceExecution()
+    callSlowPath(_slow_path_has_generic_property)
+    dispatch(4)
+
+_llint_op_get_direct_pname:
+    traceExecution()
+    callSlowPath(_slow_path_get_direct_pname)
+    dispatch(7)
+
+_llint_op_get_property_enumerator:
+    traceExecution()
+    callSlowPath(_slow_path_get_property_enumerator)
+    dispatch(3)
+
+_llint_op_enumerator_structure_pname:
+    traceExecution()
+    callSlowPath(_slow_path_next_structure_enumerator_pname)
+    dispatch(4)
+
+_llint_op_enumerator_generic_pname:
+    traceExecution()
+    callSlowPath(_slow_path_next_generic_enumerator_pname)
+    dispatch(4)
+
+_llint_op_to_index_string:
+    traceExecution()
+    callSlowPath(_slow_path_to_index_string)
+    dispatch(3)
+
+_llint_op_profile_control_flow:
+    traceExecution()
+    loadpFromInstruction(1, t0)
+    storeb 1, BasicBlockLocation::m_hasExecuted[t0]
+    dispatch(2)
 
 # Lastly, make sure that we can link even though we don't support all opcodes.
 # These opcodes should never arise when using LLInt or either JIT. We assert
@@ -1243,4 +1421,3 @@ end
 
 _llint_op_init_global_const_nop:
     dispatch(5)
-
index 20f8a6547f754e20982fec301a1add5a15e22cda..72bcddf57e06f0c839526669e855bc186792bb45 100644 (file)
@@ -34,7 +34,6 @@
 #include "LLIntCLoop.h"
 #include "LLIntSlowPaths.h"
 #include "JSCInlines.h"
-#include "VMInspector.h"
 #include <wtf/Assertions.h>
 #include <wtf/MathExtras.h>
 
@@ -338,7 +337,7 @@ JSValue CLoop::execute(OpcodeID entryOpcodeID, void* executableAddress, VM* vm,
     CallFrame* startCFR = cfr.callFrame;
 #endif
 
-    // Initialize the incoming args for doCallToJavaScript:
+    // Initialize the incoming args for doVMEntryToJavaScript:
     t0.vp = executableAddress;
     t1.vm = vm;
     t2.protoCallFrame = protoCallFrame;
index 8aa8126ad169f4a23b061e0cb4314b8bac5e0ac5..119b89a20a6500e217bed35323788ea4f4911ccd 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -155,16 +155,14 @@ macro callSlowPath(slowPath)
     move t0, PC
 end
 
-macro doCallToJavaScript(makeCall)
+macro doVMEntry(makeCall)
     if X86 or X86_WIN
         const entry = t4
         const vm = t3
         const protoCallFrame = t5
 
-        const previousCFR = t0
-        const previousPC = t1
-        const temp1 = t0 # Same as previousCFR
-        const temp2 = t1 # Same as previousPC
+        const temp1 = t0
+        const temp2 = t1
         const temp3 = t2
         const temp4 = t3 # same as vm
     elsif ARM or ARMv7 or ARMv7_TRADITIONAL or C_LOOP
@@ -172,20 +170,15 @@ macro doCallToJavaScript(makeCall)
         const vm = a1
         const protoCallFrame = a2
 
-        const previousCFR = t3
-        const previousPC = lr
-        const temp1 = t3 # Same as previousCFR
+        const temp1 = t3
         const temp2 = t4
         const temp3 = t5
         const temp4 = t4 # Same as temp2
     elsif MIPS
         const entry = a0
-        const vmTopCallFrame = a1
+        const vm = a1
         const protoCallFrame = a2
-        const topOfStack = a3
 
-        const previousCFR = t2
-        const previousPC = lr
         const temp1 = t3
         const temp2 = t5
         const temp3 = t4
@@ -195,71 +188,63 @@ macro doCallToJavaScript(makeCall)
         const vm = a1
         const protoCallFrame = a2
 
-        const previousCFR = t3
-        const previousPC = lr
-        const temp1 = t3 # Same as previousCFR
+        const temp1 = t3
         const temp2 = a3
         const temp3 = t8
         const temp4 = t9
     end
 
-    callToJavaScriptPrologue()
+    functionPrologue()
+    pushCalleeSaves()
 
-    if X86
-        loadp 36[sp], vm
-        loadp 32[sp], entry
-    elsif X86_WIN
-        loadp 40[sp, temp3], vm
-        loadp 36[sp, temp3], entry
-    else
-        move cfr, previousCFR
+    if X86 or X86_WIN
+        loadp 12[cfr], vm
+        loadp 8[cfr], entry
     end
 
-    checkStackPointerAlignment(temp2, 0xbad0dc01)
+    if ARMv7
+        vmEntryRecord(cfr, temp1)
+        move temp1, sp
+    else
+        vmEntryRecord(cfr, sp)
+    end
 
-    # The stack reserved zone ensures that we have adequate space for the
-    # VMEntrySentinelFrame. Proceed with allocating and initializing the
-    # sentinel frame.
-    move sp, cfr
-    subp CallFrameHeaderSlots * 8, cfr
-    storep 0, ArgumentCount[cfr]
-    storep vm, Callee[cfr]
+    storep vm, VMEntryRecord::m_vm[sp]
     loadp VM::topCallFrame[vm], temp2
-    storep temp2, ScopeChain[cfr]
-    storep 1, CodeBlock[cfr]
-    if X86
-        loadp 28[sp], previousPC
-        loadp 24[sp], previousCFR
-    elsif X86_WIN
-        loadp 32[sp, temp3], previousPC
-        loadp 28[sp, temp3], previousCFR
+    storep temp2, VMEntryRecord::m_prevTopCallFrame[sp]
+    loadp VM::topVMEntryFrame[vm], temp2
+    storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp]
+
+    # Align stack pointer
+    if X86_WIN
+        addp CallFrameAlignSlots * SlotSize, sp, temp1
+        andp ~StackAlignmentMask, temp1
+        subp temp1, CallFrameAlignSlots * SlotSize, sp
+    elsif ARM or ARMv7 or ARMv7_TRADITIONAL
+        addp CallFrameAlignSlots * SlotSize, sp, temp1
+        clrbp temp1, StackAlignmentMask, temp1
+        if ARMv7
+            subp temp1, CallFrameAlignSlots * SlotSize, temp1
+            move temp1, sp
+        else
+            subp temp1, CallFrameAlignSlots * SlotSize, sp
+        end
     end
-    storep previousPC, ReturnPC[cfr]
-    storep previousCFR, CallerFrame[cfr]
 
-    if X86
-        loadp 40[sp], protoCallFrame
-    elsif X86_WIN
-        loadp 44[sp, temp3], protoCallFrame
+    if X86 or X86_WIN
+        loadp 16[cfr], protoCallFrame
     end
 
     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
     addp CallFrameHeaderSlots, temp2, temp2
     lshiftp 3, temp2
-    subp cfr, temp2, temp1
+    subp sp, temp2, temp1
 
     # Ensure that we have enough additional stack capacity for the incoming args,
     # and the frame for the JS code we're executing. We need to do this check
     # before we start copying the args from the protoCallFrame below.
     bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
 
-    if ARMv7
-        subp cfr, 8, temp2
-        move temp2, sp
-    else
-        subp cfr, 8, sp
-    end
-
     if C_LOOP
         move entry, temp2
         move vm, temp3
@@ -274,13 +259,36 @@ macro doCallToJavaScript(makeCall)
         move temp3, vm
     end
 
+    subp 8, sp # Align stack for cCall2() to make a call.
     cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
-    callToJavaScriptEpilogue()
+
+    if ARMv7
+        vmEntryRecord(cfr, temp1)
+        move temp1, sp
+    else
+        vmEntryRecord(cfr, sp)
+    end
+
+    loadp VMEntryRecord::m_vm[sp], temp3
+    loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4
+    storep temp4, VM::topCallFrame[temp3]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4
+    storep temp4, VM::topVMEntryFrame[temp3]
+
+    if ARMv7
+        subp cfr, CalleeRegisterSaveSize, temp3
+        move temp3, sp
+    else
+        subp cfr, CalleeRegisterSaveSize, sp
+    end
+
+    popCalleeSaves()
+    functionEpilogue()
     ret
 
 .stackHeightOK:
     move temp1, sp
-    move 5, temp1
+    move 4, temp1
 
 .copyHeaderLoop:
     subi 1, temp1
@@ -316,18 +324,32 @@ macro doCallToJavaScript(makeCall)
 
 .copyArgsDone:
     storep sp, VM::topCallFrame[vm]
+    storep cfr, VM::topVMEntryFrame[vm]
 
     makeCall(entry, temp1, temp2)
 
-    bpeq CodeBlock[cfr], 1, .calleeFramePopped
-    loadp CallerFrame[cfr], cfr
+    if ARMv7
+        vmEntryRecord(cfr, temp1)
+        move temp1, sp
+    else
+        vmEntryRecord(cfr, sp)
+    end
 
-.calleeFramePopped:
-    loadp Callee[cfr], temp3 # VM
-    loadp ScopeChain[cfr], temp4 # previous topCallFrame
+    loadp VMEntryRecord::m_vm[sp], temp3
+    loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4
     storep temp4, VM::topCallFrame[temp3]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4
+    storep temp4, VM::topVMEntryFrame[temp3]
+
+    if ARMv7
+        subp cfr, CalleeRegisterSaveSize, temp3
+        move temp3, sp
+    else
+        subp cfr, CalleeRegisterSaveSize, sp
+    end
 
-    callToJavaScriptEpilogue()
+    popCalleeSaves()
+    functionEpilogue()
     ret
 end
 
@@ -345,52 +367,56 @@ end
 
 macro makeHostFunctionCall(entry, temp1, temp2)
     move entry, temp1
+    storep cfr, [sp]
     if C_LOOP
         move sp, a0
-        storep cfr, [sp]
         storep lr, PtrSize[sp]
         cloopCallNative temp1
+    elsif X86 or X86_WIN
+        # Put callee frame pointer on stack as arg0, also put it in ecx for "fastcall" targets
+        move 0, temp2
+        move temp2, 4[sp] # put 0 in ReturnPC
+        move sp, t2 # t2 is ecx
+        push temp2 # Push dummy arg1
+        push t2
+        call temp1
+        addp 8, sp
     else
-        if X86 or X86_WIN
-            # Put callee frame pointer on stack as arg0, also put it in ecx for "fastcall" targets
-            move 0, temp2
-            move temp2, 4[sp] # put 0 in ReturnPC
-            move cfr, [sp] # put caller frame pointer into callee frame since callee prologue can't
-            move sp, t2 # t2 is ecx
-            push temp2 # Push dummy arg1
-            push t2
-        else
-            move sp, a0
-            addp CallerFrameAndPCSize, sp
-        end
+        move sp, a0
         call temp1
-        if X86 or X86_WIN
-            addp 8, sp
-        else
-            subp CallerFrameAndPCSize, sp
-        end
     end
 end
 
 _handleUncaughtException:
-    loadp ScopeChain + PayloadOffset[cfr], t3
+    loadp Callee + PayloadOffset[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
 
-    # So far, we've unwound the stack to the frame just below the sentinel frame, except
-    # in the case of stack overflow in the first function called from callToJavaScript.
-    # Check if we need to pop to the sentinel frame and do the necessary clean up for
-    # returning to the caller C frame.
-    bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel
-    loadp CallerFrame + PayloadOffset[cfr], cfr
-.handleUncaughtExceptionAlreadyIsSentinel:
+    loadp CallerFrame[cfr], cfr
+
+    if ARMv7
+        vmEntryRecord(cfr, t3)
+        move t3, sp
+    else
+        vmEntryRecord(cfr, sp)
+    end
 
-    loadp Callee + PayloadOffset[cfr], t3 # VM
-    loadp ScopeChain + PayloadOffset[cfr], t5 # previous topCallFrame
+    loadp VMEntryRecord::m_vm[sp], t3
+    loadp VMEntryRecord::m_prevTopCallFrame[sp], t5
     storep t5, VM::topCallFrame[t3]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t5
+    storep t5, VM::topVMEntryFrame[t3]
+
+    if ARMv7
+        subp cfr, CalleeRegisterSaveSize, t3
+        move t3, sp
+    else
+        subp cfr, CalleeRegisterSaveSize, sp
+    end
 
-    callToJavaScriptEpilogue()
+    popCalleeSaves()
+    functionEpilogue()
     ret
 
 macro doReturnFromHostFunction(extraStackSpace)
@@ -544,7 +570,7 @@ macro writeBarrierOnOperand(cellOperand)
     if GGC
         loadisFromInstruction(cellOperand, t1)
         loadConstantOrVariablePayload(t1, CellTag, t2, .writeBarrierDone)
-        checkMarkByte(t2, t1, t3, 
+        skipIfIsRememberedOrInEden(t2, t1, t3, 
             macro(gcData)
                 btbnz gcData, .writeBarrierDone
                 push cfr, PC
@@ -578,7 +604,7 @@ macro writeBarrierOnGlobalObject(valueOperand)
     
         loadp CodeBlock[cfr], t3
         loadp CodeBlock::m_globalObject[t3], t3
-        checkMarkByte(t3, t1, t2,
+        skipIfIsRememberedOrInEden(t3, t1, t2,
             macro(gcData)
                 btbnz gcData, .writeBarrierDone
                 push cfr, PC
@@ -664,10 +690,10 @@ macro functionArityCheck(doneLabel, slowPath)
 end
 
 macro branchIfException(label)
-    loadp ScopeChain[cfr], t3
+    loadp Callee + PayloadOffset[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    bieq VM::m_exception + TagOffset[t3], EmptyValueTag, .noException
+    btiz VM::m_exception[t3], .noException
     jmp label
 .noException:
 end
@@ -694,29 +720,19 @@ _llint_op_enter:
     dispatch(1)
 
 
-_llint_op_create_activation:
+_llint_op_create_lexical_environment:
     traceExecution()
-    loadi 4[PC], t0
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateActivationDone
-    callSlowPath(_llint_slow_path_create_activation)
-.opCreateActivationDone:
-    dispatch(2)
-
-
-_llint_op_init_lazy_reg:
-    traceExecution()
-    loadi 4[PC], t0
-    storei EmptyValueTag, TagOffset[cfr, t0, 8]
-    storei 0, PayloadOffset[cfr, t0, 8]
-    dispatch(2)
+    callSlowPath(_llint_slow_path_create_lexical_environment)
+    dispatch(3)
 
 
-_llint_op_create_arguments:
+_llint_op_get_scope:
     traceExecution()
-    loadi 4[PC], t0
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
-    callSlowPath(_slow_path_create_arguments)
-.opCreateArgumentsDone:
+    loadi Callee + PayloadOffset[cfr], t0
+    loadi JSCallee::m_scope[t0], t0
+    loadisFromInstruction(1, t1)
+    storei CellTag, TagOffset[cfr, t1, 8]
+    storei t0, PayloadOffset[cfr, t1, 8]
     dispatch(2)
 
 
@@ -724,33 +740,25 @@ _llint_op_create_this:
     traceExecution()
     loadi 8[PC], t0
     loadp PayloadOffset[cfr, t0, 8], t0
-    loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_allocator[t0], t1
-    loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_structure[t0], t2
+    loadp JSFunction::m_rareData[t0], t4
+    btpz t4, .opCreateThisSlow
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
     btpz t1, .opCreateThisSlow
+    loadpFromInstruction(4, t4)
+    bpeq t4, 1, .hasSeenMultipleCallee
+    bpneq t4, t0, .opCreateThisSlow
+.hasSeenMultipleCallee:
     allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
     loadi 4[PC], t1
     storei CellTag, TagOffset[cfr, t1, 8]
     storei t0, PayloadOffset[cfr, t1, 8]
-    dispatch(4)
+    dispatch(5)
 
 .opCreateThisSlow:
     callSlowPath(_slow_path_create_this)
-    dispatch(4)
-
-
-_llint_op_get_callee:
-    traceExecution()
-    loadi 4[PC], t0
-    loadp PayloadOffset + Callee[cfr], t1
-    loadpFromInstruction(2, t2)
-    bpneq t1, t2, .opGetCalleeSlow
-    storei CellTag, TagOffset[cfr, t0, 8]
-    storei t1, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(5)
 
-.opGetCalleeSlow:
-    callSlowPath(_slow_path_get_callee)
-    dispatch(3)
 
 _llint_op_to_this:
     traceExecution()
@@ -760,11 +768,11 @@ _llint_op_to_this:
     bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow
     loadpFromInstruction(2, t2)
     bpneq JSCell::m_structureID[t0], t2, .opToThisSlow
-    dispatch(3)
+    dispatch(4)
 
 .opToThisSlow:
     callSlowPath(_slow_path_to_this)
-    dispatch(3)
+    dispatch(4)
 
 
 _llint_op_new_object:
@@ -783,40 +791,24 @@ _llint_op_new_object:
     dispatch(4)
 
 
-_llint_op_mov:
+_llint_op_check_tdz:
     traceExecution()
-    loadi 8[PC], t1
-    loadi 4[PC], t0
-    loadConstantOrVariable(t1, t2, t3)
-    storei t2, TagOffset[cfr, t0, 8]
-    storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    loadpFromInstruction(1, t0)
+    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opNotTDZ
+    callSlowPath(_slow_path_throw_tdz_error)
 
+.opNotTDZ:
+    dispatch(2)
 
-macro notifyWrite(set, valueTag, valuePayload, scratch, slow)
-    loadb VariableWatchpointSet::m_state[set], scratch
-    bieq scratch, IsInvalidated, .done
-    bineq valuePayload, VariableWatchpointSet::m_inferredValue + PayloadOffset[set], slow
-    bineq valueTag, VariableWatchpointSet::m_inferredValue + TagOffset[set], slow
-.done:
-end
 
-_llint_op_captured_mov:
+_llint_op_mov:
     traceExecution()
     loadi 8[PC], t1
-    loadConstantOrVariable(t1, t2, t3)
-    loadpFromInstruction(3, t0)
-    btpz t0, .opCapturedMovReady
-    notifyWrite(t0, t2, t3, t1, .opCapturedMovSlow)
-.opCapturedMovReady:
     loadi 4[PC], t0
+    loadConstantOrVariable(t1, t2, t3)
     storei t2, TagOffset[cfr, t0, 8]
     storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(4)
-
-.opCapturedMovSlow:
-    callSlowPath(_slow_path_captured_mov)
-    dispatch(4)
+    dispatch(3)
 
 
 _llint_op_not:
@@ -936,10 +928,10 @@ macro strictEq(equalityOperation, slowPath)
     loadConstantOrVariable2Reg(t0, t2, t0)
     bineq t2, t3, .slow
     bib t2, LowestTag, .slow
-    bineq t2, CellTag, .notString
-    bbneq JSCell::m_type[t0], StringType, .notString
-    bbeq JSCell::m_type[t1], StringType, .slow
-.notString:
+    bineq t2, CellTag, .notStringOrSymbol
+    bbaeq JSCell::m_type[t0], ObjectType, .notStringOrSymbol
+    bbb JSCell::m_type[t1], ObjectType, .slow
+.notStringOrSymbol:
     loadi 4[PC], t2
     equalityOperation(t0, t1, t0)
     storei BooleanTag, TagOffset[cfr, t2, 8]
@@ -1006,6 +998,23 @@ _llint_op_to_number:
     dispatch(3)
 
 
+_llint_op_to_string:
+    traceExecution()
+    loadi 8[PC], t0
+    loadi 4[PC], t1
+    loadConstantOrVariable(t0, t2, t3)
+    bineq t2, CellTag, .opToStringSlow
+    bbneq JSCell::m_type[t3], StringType, .opToStringSlow
+.opToStringIsString:
+    storei t2, TagOffset[cfr, t1, 8]
+    storei t3, PayloadOffset[cfr, t1, 8]
+    dispatch(3)
+
+.opToStringSlow:
+    callSlowPath(_slow_path_to_string)
+    dispatch(3)
+
+
 _llint_op_negate:
     traceExecution()
     loadi 8[PC], t0
@@ -1317,6 +1326,21 @@ _llint_op_is_string:
     dispatch(3)
 
 
+_llint_op_is_object:
+    traceExecution()
+    loadi 8[PC], t1
+    loadi 4[PC], t2
+    loadConstantOrVariable(t1, t0, t3)
+    storei BooleanTag, TagOffset[cfr, t2, 8]
+    bineq t0, CellTag, .opIsObjectNotCell
+    cbaeq JSCell::m_type[t3], ObjectType, t1
+    storei t1, PayloadOffset[cfr, t2, 8]
+    dispatch(3)
+.opIsObjectNotCell:
+    storep 0, PayloadOffset[cfr, t2, 8]
+    dispatch(3)
+
+
 macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffset, objectAndStorage, tag, payload)
     assert(macro (ok) bigteq propertyOffset, firstOutOfLineOffset, ok end)
     negi propertyOffset
@@ -1423,22 +1447,6 @@ _llint_op_get_array_length:
     dispatch(9)
 
 
-_llint_op_get_arguments_length:
-    traceExecution()
-    loadi 8[PC], t0
-    loadi 4[PC], t1
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
-    loadi ArgumentCount + PayloadOffset[cfr], t2
-    subi 1, t2
-    storei Int32Tag, TagOffset[cfr, t1, 8]
-    storei t2, PayloadOffset[cfr, t1, 8]
-    dispatch(4)
-
-.opGetArgumentsLengthSlow:
-    callSlowPath(_llint_slow_path_get_arguments_length)
-    dispatch(4)
-
-
 macro putById(getPropertyStorage)
     traceExecution()
     writeBarrierOnOperands(1, 3)
@@ -1589,61 +1597,6 @@ _llint_op_get_by_val:
     dispatch(6)
 
 
-_llint_op_get_argument_by_val:
-    # FIXME: At some point we should array profile this. Right now it isn't necessary
-    # since the DFG will never turn a get_argument_by_val into a GetByVal.
-    traceExecution()
-    loadi 8[PC], t0
-    loadi 12[PC], t1
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
-    loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
-    addi 1, t2
-    loadi ArgumentCount + PayloadOffset[cfr], t1
-    biaeq t2, t1, .opGetArgumentByValSlow
-    loadi 4[PC], t3
-    loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
-    loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
-    storei t0, TagOffset[cfr, t3, 8]
-    storei t1, PayloadOffset[cfr, t3, 8]
-    valueProfile(t0, t1, 20, t2)
-    dispatch(6)
-
-.opGetArgumentByValSlow:
-    callSlowPath(_llint_slow_path_get_argument_by_val)
-    dispatch(6)
-
-
-_llint_op_get_by_pname:
-    traceExecution()
-    loadi 12[PC], t0
-    loadConstantOrVariablePayload(t0, CellTag, t1, .opGetByPnameSlow)
-    loadi 16[PC], t0
-    bpneq t1, PayloadOffset[cfr, t0, 8], .opGetByPnameSlow
-    loadi 8[PC], t0
-    loadConstantOrVariablePayload(t0, CellTag, t2, .opGetByPnameSlow)
-    loadi 20[PC], t0
-    loadi PayloadOffset[cfr, t0, 8], t3
-    loadp JSCell::m_structureID[t2], t0
-    bpneq t0, JSPropertyNameIterator::m_cachedStructure[t3], .opGetByPnameSlow
-    loadi 24[PC], t0
-    loadi [cfr, t0, 8], t0
-    subi 1, t0
-    biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
-    bilt t0, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], .opGetByPnameInlineProperty
-    addi firstOutOfLineOffset, t0
-    subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], t0
-.opGetByPnameInlineProperty:
-    loadPropertyAtVariableOffset(t0, t2, t1, t3)
-    loadi 4[PC], t0
-    storei t1, TagOffset[cfr, t0, 8]
-    storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(7)
-
-.opGetByPnameSlow:
-    callSlowPath(_llint_slow_path_get_by_pname)
-    dispatch(7)
-
-
 macro contiguousPutByVal(storeCallback)
     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
 .storeResult:
@@ -1925,23 +1878,6 @@ _llint_op_switch_char:
     dispatch(0)
 
 
-_llint_op_new_func:
-    traceExecution()
-    btiz 12[PC], .opNewFuncUnchecked
-    loadi 4[PC], t1
-    bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
-.opNewFuncUnchecked:
-    callSlowPath(_llint_slow_path_new_func)
-.opNewFuncDone:
-    dispatch(4)
-
-
-_llint_op_new_captured_func:
-    traceExecution()
-    callSlowPath(_slow_path_new_captured_func)
-    dispatch(4)
-
-
 macro arrayProfileForCall()
     loadi 16[PC], t3
     negi t3
@@ -1963,14 +1899,11 @@ macro doCall(slowPath)
     lshifti 3, t3
     negi t3
     addp cfr, t3  # t3 contains the new value of cfr
-    loadp JSFunction::m_scope[t2], t0
     storei t2, Callee + PayloadOffset[t3]
-    storei t0, ScopeChain + PayloadOffset[t3]
     loadi 12[PC], t2
     storei PC, ArgumentCount + TagOffset[cfr]
     storei t2, ArgumentCount + PayloadOffset[t3]
     storei CellTag, Callee + TagOffset[t3]
-    storei CellTag, ScopeChain + TagOffset[t3]
     addp CallerFrameAndPCSize, t3
     callTargetFunction(t1, t3)
 
@@ -1979,25 +1912,6 @@ macro doCall(slowPath)
 end
 
 
-_llint_op_tear_off_activation:
-    traceExecution()
-    loadi 4[PC], t0
-    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationNotCreated
-    callSlowPath(_llint_slow_path_tear_off_activation)
-.opTearOffActivationNotCreated:
-    dispatch(2)
-
-
-_llint_op_tear_off_arguments:
-    traceExecution()
-    loadi 4[PC], t0
-    addi 1, t0   # Get the unmodifiedArgumentsRegister
-    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
-    callSlowPath(_llint_slow_path_tear_off_arguments)
-.opTearOffArgumentsNotCreated:
-    dispatch(3)
-
-
 _llint_op_ret:
     traceExecution()
     checkSwitchToJITForEpilogue()
@@ -2006,28 +1920,13 @@ _llint_op_ret:
     doReturn()
 
 
-_llint_op_ret_object_or_this:
-    traceExecution()
-    checkSwitchToJITForEpilogue()
-    loadi 4[PC], t2
-    loadConstantOrVariable(t2, t1, t0)
-    bineq t1, CellTag, .opRetObjectOrThisNotObject
-    bbb JSCell::m_type[t0], ObjectType, .opRetObjectOrThisNotObject
-    doReturn()
-
-.opRetObjectOrThisNotObject:
-    loadi 8[PC], t2
-    loadConstantOrVariable(t2, t1, t0)
-    doReturn()
-
-
 _llint_op_to_primitive:
     traceExecution()
     loadi 8[PC], t2
     loadi 4[PC], t3
     loadConstantOrVariable(t2, t1, t0)
     bineq t1, CellTag, .opToPrimitiveIsImm
-    bbneq JSCell::m_type[t0], StringType, .opToPrimitiveSlowCase
+    bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
 .opToPrimitiveIsImm:
     storei t1, TagOffset[cfr, t3, 8]
     storei t0, PayloadOffset[cfr, t3, 8]
@@ -2038,103 +1937,35 @@ _llint_op_to_primitive:
     dispatch(3)
 
 
-_llint_op_next_pname:
-    traceExecution()
-    loadi 12[PC], t1
-    loadi 16[PC], t2
-    loadi PayloadOffset[cfr, t1, 8], t0
-    bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
-    loadi 20[PC], t2
-    loadi PayloadOffset[cfr, t2, 8], t2
-    loadp JSPropertyNameIterator::m_jsStrings[t2], t3
-    loadi [t3, t0, 8], t3
-    addi 1, t0
-    storei t0, PayloadOffset[cfr, t1, 8]
-    loadi 4[PC], t1
-    storei CellTag, TagOffset[cfr, t1, 8]
-    storei t3, PayloadOffset[cfr, t1, 8]
-    loadi 8[PC], t3
-    loadi PayloadOffset[cfr, t3, 8], t3
-    loadp JSCell::m_structureID[t3], t1
-    bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
-    loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
-    loadp StructureChain::m_vector[t0], t0
-    btpz [t0], .opNextPnameTarget
-.opNextPnameCheckPrototypeLoop:
-    bieq Structure::m_prototype + TagOffset[t1], NullTag, .opNextPnameSlow
-    loadp Structure::m_prototype + PayloadOffset[t1], t2
-    loadp JSCell::m_structureID[t2], t1
-    bpneq t1, [t0], .opNextPnameSlow
-    addp 4, t0
-    btpnz [t0], .opNextPnameCheckPrototypeLoop
-.opNextPnameTarget:
-    dispatchBranch(24[PC])
-
-.opNextPnameEnd:
-    dispatch(7)
-
-.opNextPnameSlow:
-    callSlowPath(_llint_slow_path_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
-    dispatch(0)
-
-
 _llint_op_catch:
     # This is where we end up from the JIT's throw trampoline (because the
     # machine code return address will be set to _llint_op_catch), and from
     # the interpreter's throw trampoline (see _llint_throw_trampoline).
     # The throwing code must have known that we were throwing to the interpreter,
     # and have set VM::targetInterpreterPCForThrow.
-    loadp ScopeChain + PayloadOffset[cfr], t3
+    loadp Callee + PayloadOffset[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
     restoreStackPointerAfterCall()
 
     loadi VM::targetInterpreterPCForThrow[t3], PC
-    loadi VM::m_exception + PayloadOffset[t3], t0
-    loadi VM::m_exception + TagOffset[t3], t1
-    storei 0, VM::m_exception + PayloadOffset[t3]
-    storei EmptyValueTag, VM::m_exception + TagOffset[t3]
+    loadi VM::m_exception[t3], t0
+    storei 0, VM::m_exception[t3]
     loadi 4[PC], t2
     storei t0, PayloadOffset[cfr, t2, 8]
-    storei t1, TagOffset[cfr, t2, 8]
-    traceExecution()  # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
-    dispatch(2)
-
-
-# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
-# scopes as they are traversed. scopeCheck() is called with two arguments: the register
-# holding the scope, and a register that can be used for scratch. Note that this does not
-# use t3, so you can hold stuff in t3 if need be.
-macro getDeBruijnScope(deBruijinIndexOperand, scopeCheck)
-    loadp ScopeChain + PayloadOffset[cfr], t0
-    loadi deBruijinIndexOperand, t2
-
-    btiz t2, .done
-
-    loadp CodeBlock[cfr], t1
-    bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
-    btbz CodeBlock::m_needsActivation[t1], .loop
-
-    loadi CodeBlock::m_activationRegister[t1], t1
-
-    # Need to conditionally skip over one scope.
-    bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
-    scopeCheck(t0, t1)
-    loadp JSScope::m_next[t0], t0
-.noActivation:
-    subi 1, t2
+    storei CellTag, TagOffset[cfr, t2, 8]
 
-    btiz t2, .done
-.loop:
-    scopeCheck(t0, t1)
-    loadp JSScope::m_next[t0], t0
-    subi 1, t2
-    btinz t2, .loop
-
-.done:
+    loadi Exception::m_value + TagOffset[t0], t1
+    loadi Exception::m_value + PayloadOffset[t0], t0
+    loadi 8[PC], t2
+    storei t0, PayloadOffset[cfr, t2, 8]
+    storei t1, TagOffset[cfr, t2, 8]
 
-end
+    traceExecution()  # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
+    dispatch(3)
 
 _llint_op_end:
     traceExecution()
@@ -2152,8 +1983,9 @@ _llint_throw_from_slow_path_trampoline:
     # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
     # the throw target is not necessarily interpreted code, we come to here.
     # This essentially emulates the JIT's throwing protocol.
-    loadp CodeBlock[cfr], t1
-    loadp CodeBlock::m_vm[t1], t1
+    loadp Callee[cfr], t1
+    andp MarkedBlockMask, t1
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
     jmp VM::targetMachinePCForThrow[t1]
 
 
@@ -2166,10 +1998,8 @@ macro nativeCallTrampoline(executableOffsetToFunction)
 
     functionPrologue()
     storep 0, CodeBlock[cfr]
-    loadp CallerFrame[cfr], t0
-    loadi ScopeChain + PayloadOffset[t0], t1
-    storei CellTag, ScopeChain + TagOffset[cfr]
-    storei t1, ScopeChain + PayloadOffset[cfr]
+    loadi Callee + PayloadOffset[cfr], t1
+    // Callee is still in t1 for code below
     if X86 or X86_WIN
         subp 8, sp # align stack pointer
         andp MarkedBlockMask, t1
@@ -2181,13 +2011,13 @@ macro nativeCallTrampoline(executableOffsetToFunction)
         loadp JSFunction::m_executable[t1], t1
         checkStackPointerAlignment(t3, 0xdead0001)
         call executableOffsetToFunction[t1]
-        loadp ScopeChain[cfr], t3
+        loadp Callee + PayloadOffset[cfr], t3
         andp MarkedBlockMask, t3
         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
         addp 8, sp
     elsif ARM or ARMv7 or ARMv7_TRADITIONAL or C_LOOP or MIPS or SH4
         subp 8, sp # align stack pointer
-        # t1 already contains the ScopeChain.
+        # t1 already contains the Callee.
         andp MarkedBlockMask, t1
         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
         storep cfr, VM::topCallFrame[t1]
@@ -2204,7 +2034,7 @@ macro nativeCallTrampoline(executableOffsetToFunction)
         else
             call executableOffsetToFunction[t1]
         end
-        loadp ScopeChain[cfr], t3
+        loadp Callee + PayloadOffset[cfr], t3
         andp MarkedBlockMask, t3
         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
         addp 8, sp
@@ -2213,7 +2043,7 @@ macro nativeCallTrampoline(executableOffsetToFunction)
     end
     
     functionEpilogue()
-    bineq VM::m_exception + TagOffset[t3], EmptyValueTag, .handleException
+    btinz VM::m_exception[t3], .handleException
     ret
 
 .handleException:
@@ -2240,14 +2070,10 @@ end
 
 macro resolveScope()
     loadp CodeBlock[cfr], t0
-    loadisFromInstruction(4, t2)
-    btbz CodeBlock::m_needsActivation[t0], .resolveScopeAfterActivationCheck
-    loadis CodeBlock::m_activationRegister[t0], t1
-    btpz PayloadOffset[cfr, t1, 8], .resolveScopeAfterActivationCheck
-    addi 1, t2
+    loadisFromInstruction(5, t2)
 
-.resolveScopeAfterActivationCheck:
-    loadp ScopeChain[cfr], t0
+    loadisFromInstruction(2, t0)
+    loadp PayloadOffset[cfr, t0, 8], t0
     btiz t2, .resolveScopeLoopEnd
 
 .resolveScopeLoop:
@@ -2264,49 +2090,49 @@ end
 
 _llint_op_resolve_scope:
     traceExecution()
-    loadisFromInstruction(3, t0)
+    loadisFromInstruction(4, t0)
 
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rClosureVar
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rClosureVar:
     bineq t0, ClosureVar, .rGlobalPropertyWithVarInjectionChecks
     resolveScope()
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
     varInjectionCheck(.rDynamic)
     resolveScope()
-    dispatch(6)
+    dispatch(7)
 
 .rDynamic:
     callSlowPath(_llint_slow_path_resolve_scope)
-    dispatch(6)
+    dispatch(7)
 
 
 macro loadWithStructureCheck(operand, slowPath)
     loadisFromInstruction(operand, t0)
-    loadp [cfr, t0, 8], t0
+    loadp PayloadOffset[cfr, t0, 8], t0
     loadpFromInstruction(5, t1)
     bpneq JSCell::m_structureID[t0], t1, slowPath
 end
@@ -2331,10 +2157,9 @@ macro getGlobalVar()
 end
 
 macro getClosureVar()
-    loadp JSVariableObject::m_registers[t0], t0
     loadisFromInstruction(6, t3)
-    loadp TagOffset[t0, t3, 8], t1
-    loadp PayloadOffset[t0, t3, 8], t2
+    loadp JSEnvironmentRecord_variables + TagOffset[t0, t3, 8], t1
+    loadp JSEnvironmentRecord_variables + PayloadOffset[t0, t3, 8], t2
     valueProfile(t1, t2, 28, t0)
     loadisFromInstruction(1, t0)
     storei t1, TagOffset[cfr, t0, 8]
@@ -2372,7 +2197,6 @@ _llint_op_get_from_scope:
 .gGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
     varInjectionCheck(.gDynamic)
-    loadVariable(2, t2, t1, t0)
     getGlobalVar()
     dispatch(8)
 
@@ -2399,7 +2223,7 @@ macro putGlobalVar()
     loadisFromInstruction(3, t0)
     loadConstantOrVariable(t0, t1, t2)
     loadpFromInstruction(5, t3)
-    notifyWrite(t3, t1, t2, t0, .pDynamic)
+    notifyWrite(t3, .pDynamic)
     loadpFromInstruction(6, t0)
     storei t1, TagOffset[t0]
     storei t2, PayloadOffset[t0]
@@ -2408,10 +2232,21 @@ end
 macro putClosureVar()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2, t3)
-    loadp JSVariableObject::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storei t2, TagOffset[t0, t1, 8]
-    storei t3, PayloadOffset[t0, t1, 8]
+    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
+    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
+end
+
+macro putLocalClosureVar()
+    loadisFromInstruction(3, t1)
+    loadConstantOrVariable(t1, t2, t3)
+    loadpFromInstruction(5, t4)
+    btpz t4, .noVariableWatchpointSet
+    notifyWrite(t4, .pDynamic)
+.noVariableWatchpointSet:
+    loadisFromInstruction(6, t1)
+    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
+    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
 end
 
 
@@ -2420,7 +2255,14 @@ _llint_op_put_to_scope:
     loadisFromInstruction(4, t0)
     andi ResolveModeMask, t0
 
-#pGlobalProperty:
+#pLocalClosureVar:
+    bineq t0, LocalClosureVar, .pGlobalProperty
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t2, t1, t0)
+    putLocalClosureVar()
+    dispatch(7)
+
+.pGlobalProperty:
     bineq t0, GlobalProperty, .pGlobalVar
     writeBarrierOnOperands(1, 3)
     loadWithStructureCheck(1, .pDynamic)
@@ -2465,3 +2307,72 @@ _llint_op_put_to_scope:
 .pDynamic:
     callSlowPath(_llint_slow_path_put_to_scope)
     dispatch(7)
+
+
+_llint_op_get_from_arguments:
+    traceExecution()
+    loadisFromInstruction(2, t0)
+    loadi PayloadOffset[cfr, t0, 8], t0
+    loadi 12[PC], t1
+    loadi DirectArguments_storage + TagOffset[t0, t1, 8], t2
+    loadi DirectArguments_storage + PayloadOffset[t0, t1, 8], t3
+    loadisFromInstruction(1, t1)
+    valueProfile(t2, t3, 16, t0)
+    storei t2, TagOffset[cfr, t1, 8]
+    storei t3, PayloadOffset[cfr, t1, 8]
+    dispatch(5)
+
+
+_llint_op_put_to_arguments:
+    traceExecution()
+    writeBarrierOnOperands(1, 3)
+    loadisFromInstruction(1, t0)
+    loadi PayloadOffset[cfr, t0, 8], t0
+    loadisFromInstruction(3, t1)
+    loadConstantOrVariable(t1, t2, t3)
+    loadi 8[PC], t1
+    storei t2, DirectArguments_storage + TagOffset[t0, t1, 8]
+    storei t3, DirectArguments_storage + PayloadOffset[t0, t1, 8]
+    dispatch(4)
+
+
+_llint_op_profile_type:
+    traceExecution()
+    loadp CodeBlock[cfr], t1
+    loadp CodeBlock::m_vm[t1], t1
+    # t1 is holding the pointer to the typeProfilerLog.
+    loadp VM::m_typeProfilerLog[t1], t1
+
+    # t0 is holding the payload, t4 is holding the tag.
+    loadisFromInstruction(1, t2)
+    loadConstantOrVariable(t2, t4, t0)
+
+    # t2 is holding the pointer to the current log entry.
+    loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
+
+    # Store the JSValue onto the log entry.
+    storei t4, TypeProfilerLog::LogEntry::value + TagOffset[t2]
+    storei t0, TypeProfilerLog::LogEntry::value + PayloadOffset[t2]
+
+    # Store the TypeLocation onto the log entry.
+    loadpFromInstruction(2, t3)
+    storep t3, TypeProfilerLog::LogEntry::location[t2]
+
+    bieq t4, CellTag, .opProfileTypeIsCell
+    storei 0, TypeProfilerLog::LogEntry::structureID[t2]
+    jmp .opProfileTypeSkipIsCell
+.opProfileTypeIsCell:
+    loadi JSCell::m_structureID[t0], t3
+    storei t3, TypeProfilerLog::LogEntry::structureID[t2]
+.opProfileTypeSkipIsCell:
+    
+    # Increment the current log entry.
+    addp sizeof TypeProfilerLog::LogEntry, t2
+    storep t2, TypeProfilerLog::m_currentLogEntryPtr[t1]
+
+    loadp TypeProfilerLog::m_logEndPtr[t1], t1
+    bpneq t2, t1, .opProfileTypeDone
+    callSlowPath(_slow_path_profile_type_clear_log)
+
+.opProfileTypeDone:
+    dispatch(6)
index 67a8f1b8c9cf3d53616704c5e98a465852c063f4..43e997b91b50198821b1f99f96f56f66b90c325f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2015 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -138,7 +138,7 @@ macro cCall4(function, arg1, arg2, arg3, arg4)
     end
 end
 
-macro doCallToJavaScript(makeCall)
+macro doVMEntry(makeCall)
     if X86_64
         const entry = t4
         const vm = t5
@@ -171,47 +171,29 @@ macro doCallToJavaScript(makeCall)
         const temp3 = t6
     end
 
-    callToJavaScriptPrologue()
+    functionPrologue()
+    pushCalleeSaves()
 
-    if X86_64
-        loadp 7*8[sp], previousPC
-        move 6*8[sp], previousCFR
-    elsif X86_64_WIN
-        # Win64 pushes two more registers
-        loadp 9*8[sp], previousPC
-        move 8*8[sp], previousCFR
-    elsif ARM64
-        move cfr, previousCFR
-    end
+    vmEntryRecord(cfr, sp)
 
     checkStackPointerAlignment(temp2, 0xbad0dc01)
 
-    # The stack reserved zone ensures that we have adequate space for the
-    # VMEntrySentinelFrame. Proceed with allocating and initializing the
-    # sentinel frame.
-    move sp, cfr
-    subp CallFrameHeaderSlots * 8, cfr
-    storep 0, ArgumentCount[cfr]
-    storep vm, Callee[cfr]
+    storep vm, VMEntryRecord::m_vm[sp]
     loadp VM::topCallFrame[vm], temp2
-    storep temp2, ScopeChain[cfr]
-    storep 1, CodeBlock[cfr]
-
-    storep previousPC, ReturnPC[cfr]
-    storep previousCFR, CallerFrame[cfr]
+    storep temp2, VMEntryRecord::m_prevTopCallFrame[sp]
+    loadp VM::topVMEntryFrame[vm], temp2
+    storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp]
 
     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
     addp CallFrameHeaderSlots, temp2, temp2
     lshiftp 3, temp2
-    subp cfr, temp2, temp1
+    subp sp, temp2, temp1
 
     # Ensure that we have enough additional stack capacity for the incoming args,
     # and the frame for the JS code we're executing. We need to do this check
     # before we start copying the args from the protoCallFrame below.
     bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
 
-    move cfr, sp
-
     if C_LOOP
         move entry, temp2
         move vm, temp3
@@ -227,12 +209,24 @@ macro doCallToJavaScript(makeCall)
     end
 
     cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
-    callToJavaScriptEpilogue()
+
+    vmEntryRecord(cfr, temp2)
+
+    loadp VMEntryRecord::m_vm[temp2], vm
+    loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3
+    storep temp3, VM::topCallFrame[vm]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3
+    storep temp3, VM::topVMEntryFrame[vm]
+
+    subp cfr, CalleeRegisterSaveSize, sp
+
+    popCalleeSaves()
+    functionEpilogue()
     ret
 
 .stackHeightOK:
     move temp1, sp
-    move 5, temp1
+    move 4, temp1
 
 .copyHeaderLoop:
     subi 1, temp1
@@ -269,6 +263,7 @@ macro doCallToJavaScript(makeCall)
     else
         storep sp, VM::topCallFrame[vm]
     end
+    storep cfr, VM::topVMEntryFrame[vm]
 
     move 0xffff000000000000, csr1
     addp 2, csr1, csr2
@@ -279,20 +274,18 @@ macro doCallToJavaScript(makeCall)
 
     checkStackPointerAlignment(temp3, 0xbad0dc03)
 
-    bpeq CodeBlock[cfr], 1, .calleeFramePopped
-    loadp CallerFrame[cfr], cfr
+    vmEntryRecord(cfr, temp2)
 
-.calleeFramePopped:
-    loadp Callee[cfr], temp2 # VM
-    loadp ScopeChain[cfr], temp3 # previous topCallFrame
-    storep temp3, VM::topCallFrame[temp2]
+    loadp VMEntryRecord::m_vm[temp2], vm
+    loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3
+    storep temp3, VM::topCallFrame[vm]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3
+    storep temp3, VM::topVMEntryFrame[vm]
 
-    checkStackPointerAlignment(temp3, 0xbad0dc04)
+    subp cfr, CalleeRegisterSaveSize, sp
 
-    if X86_64 or X86_64_WIN
-        pop t5
-    end
-    callToJavaScriptEpilogue()
+    popCalleeSaves()
+    functionEpilogue()
 
     ret
 end
@@ -311,6 +304,7 @@ end
 
 macro makeHostFunctionCall(entry, temp)
     move entry, temp
+    storep cfr, [sp]
     if X86_64
         move sp, t4
     elsif X86_64_WIN
@@ -319,46 +313,38 @@ macro makeHostFunctionCall(entry, temp)
         move sp, a0
     end
     if C_LOOP
-        storep cfr, [sp]
         storep lr, 8[sp]
         cloopCallNative temp
     elsif X86_64_WIN
-        # For a host function call, JIT relies on that the CallerFrame (frame pointer) is put on the stack,
-        # On Win64 we need to manually copy the frame pointer to the stack, since MSVC may not maintain a frame pointer on 64-bit.
-        # See http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx where it's stated that rbp MAY be used as a frame pointer.
-        storep cfr, [sp]
-
         # We need to allocate 32 bytes on the stack for the shadow space.
         subp 32, sp
         call temp
         addp 32, sp
     else
-        addp 16, sp
         call temp
-        subp 16, sp
     end
 end
 
 
 _handleUncaughtException:
-    loadp ScopeChain[cfr], t3
+    loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
 
-    # So far, we've unwound the stack to the frame just below the sentinel frame, except
-    # in the case of stack overflow in the first function called from callToJavaScript.
-    # Check if we need to pop to the sentinel frame and do the necessary clean up for
-    # returning to the caller C frame.
-    bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel
     loadp CallerFrame[cfr], cfr
-.handleUncaughtExceptionAlreadyIsSentinel:
+    vmEntryRecord(cfr, t2)
 
-    loadp Callee[cfr], t3 # VM
-    loadp ScopeChain[cfr], t5 # previous topCallFrame
+    loadp VMEntryRecord::m_vm[t2], t3
+    loadp VMEntryRecord::m_prevTopCallFrame[t2], t5
     storep t5, VM::topCallFrame[t3]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], t5
+    storep t5, VM::topVMEntryFrame[t3]
 
-    callToJavaScriptEpilogue()
+    subp cfr, CalleeRegisterSaveSize, sp
+
+    popCalleeSaves()
+    functionEpilogue()
     ret
 
 
@@ -457,7 +443,7 @@ macro writeBarrierOnOperand(cellOperand)
     if GGC
         loadisFromInstruction(cellOperand, t1)
         loadConstantOrVariableCell(t1, t2, .writeBarrierDone)
-        checkMarkByte(t2, t1, t3, 
+        skipIfIsRememberedOrInEden(t2, t1, t3, 
             macro(gcData)
                 btbnz gcData, .writeBarrierDone
                 push PB, PC
@@ -488,7 +474,7 @@ macro writeBarrierOnGlobalObject(valueOperand)
     
         loadp CodeBlock[cfr], t3
         loadp CodeBlock::m_globalObject[t3], t3
-        checkMarkByte(t3, t1, t2,
+        skipIfIsRememberedOrInEden(t3, t1, t2,
             macro(gcData)
                 btbnz gcData, .writeBarrierDone
                 push PB, PC
@@ -592,7 +578,7 @@ macro functionArityCheck(doneLabel, slowPath)
 end
 
 macro branchIfException(label)
-    loadp ScopeChain[cfr], t3
+    loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     btqz VM::m_exception[t3], .noException
@@ -621,28 +607,18 @@ _llint_op_enter:
     dispatch(1)
 
 
-_llint_op_create_activation:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    bqneq [cfr, t0, 8], ValueEmpty, .opCreateActivationDone
-    callSlowPath(_llint_slow_path_create_activation)
-.opCreateActivationDone:
-    dispatch(2)
-
-
-_llint_op_init_lazy_reg:
+_llint_op_create_lexical_environment:
     traceExecution()
-    loadisFromInstruction(1, t0)
-    storeq ValueEmpty, [cfr, t0, 8]
-    dispatch(2)
+    callSlowPath(_llint_slow_path_create_lexical_environment)
+    dispatch(3)
 
 
-_llint_op_create_arguments:
+_llint_op_get_scope:
     traceExecution()
-    loadisFromInstruction(1, t0)
-    bqneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone
-    callSlowPath(_slow_path_create_arguments)
-.opCreateArgumentsDone:
+    loadp Callee[cfr], t0
+    loadp JSCallee::m_scope[t0], t0
+    loadisFromInstruction(1, t1)
+    storeq t0, [cfr, t1, 8]
     dispatch(2)
 
 
@@ -650,31 +626,24 @@ _llint_op_create_this:
     traceExecution()
     loadisFromInstruction(2, t0)
     loadp [cfr, t0, 8], t0
-    loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_allocator[t0], t1
-    loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_structure[t0], t2
+    loadp JSFunction::m_rareData[t0], t4
+    btpz t4, .opCreateThisSlow
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
     btpz t1, .opCreateThisSlow
+    loadpFromInstruction(4, t4)
+    bpeq t4, 1, .hasSeenMultipleCallee
+    bpneq t4, t0, .opCreateThisSlow
+.hasSeenMultipleCallee:
     allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(4)
+    dispatch(5)
 
 .opCreateThisSlow:
     callSlowPath(_slow_path_create_this)
-    dispatch(4)
-
-
-_llint_op_get_callee:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    loadp Callee[cfr], t1
-    loadpFromInstruction(2, t2)
-    bpneq t1, t2, .opGetCalleeSlow
-    storep t1, [cfr, t0, 8]
-    dispatch(3)
+    dispatch(5)
 
-.opGetCalleeSlow:
-    callSlowPath(_slow_path_get_callee)
-    dispatch(3)
 
 _llint_op_to_this:
     traceExecution()
@@ -685,11 +654,11 @@ _llint_op_to_this:
     loadStructureWithScratch(t0, t1, t2)
     loadpFromInstruction(2, t2)
     bpneq t1, t2, .opToThisSlow
-    dispatch(3)
+    dispatch(4)
 
 .opToThisSlow:
     callSlowPath(_slow_path_to_this)
-    dispatch(3)
+    dispatch(4)
 
 
 _llint_op_new_object:
@@ -707,37 +676,24 @@ _llint_op_new_object:
     dispatch(4)
 
 
-_llint_op_mov:
+_llint_op_check_tdz:
     traceExecution()
-    loadisFromInstruction(2, t1)
-    loadisFromInstruction(1, t0)
-    loadConstantOrVariable(t1, t2)
-    storeq t2, [cfr, t0, 8]
-    dispatch(3)
+    loadpFromInstruction(1, t0)
+    loadq [cfr, t0, 8], t0
+    bqneq t0, ValueEmpty, .opNotTDZ
+    callSlowPath(_slow_path_throw_tdz_error)
 
+.opNotTDZ:
+    dispatch(2)
 
-macro notifyWrite(set, value, scratch, slow)
-    loadb VariableWatchpointSet::m_state[set], scratch
-    bieq scratch, IsInvalidated, .done
-    bqneq value, VariableWatchpointSet::m_inferredValue[set], slow
-.done:
-end
 
-_llint_op_captured_mov:
+_llint_op_mov:
     traceExecution()
     loadisFromInstruction(2, t1)
-    loadConstantOrVariable(t1, t2)
-    loadpFromInstruction(3, t0)
-    btpz t0, .opCapturedMovReady
-    notifyWrite(t0, t2, t1, .opCapturedMovSlow)
-.opCapturedMovReady:
     loadisFromInstruction(1, t0)
+    loadConstantOrVariable(t1, t2)
     storeq t2, [cfr, t0, 8]
-    dispatch(4)
-
-.opCapturedMovSlow:
-    callSlowPath(_slow_path_captured_mov)
-    dispatch(4)
+    dispatch(3)
 
 
 _llint_op_not:
@@ -903,6 +859,22 @@ _llint_op_to_number:
     dispatch(3)
 
 
+_llint_op_to_string:
+    traceExecution()
+    loadisFromInstruction(2, t1)
+    loadisFromInstruction(1, t2)
+    loadConstantOrVariable(t1, t0)
+    btqnz t0, tagMask, .opToStringSlow
+    bbneq JSCell::m_type[t0], StringType, .opToStringSlow
+.opToStringIsString:
+    storeq t0, [cfr, t2, 8]
+    dispatch(3)
+
+.opToStringSlow:
+    callSlowPath(_slow_path_to_string)
+    dispatch(3)
+
+
 _llint_op_negate:
     traceExecution()
     loadisFromInstruction(2, t0)
@@ -1230,6 +1202,21 @@ _llint_op_is_string:
     dispatch(3)
 
 
+_llint_op_is_object:
+    traceExecution()
+    loadisFromInstruction(2, t1)
+    loadisFromInstruction(1, t2)
+    loadConstantOrVariable(t1, t0)
+    btqnz t0, tagMask, .opIsObjectNotCell
+    cbaeq JSCell::m_type[t0], ObjectType, t1
+    orq ValueFalse, t1
+    storeq t1, [cfr, t2, 8]
+    dispatch(3)
+.opIsObjectNotCell:
+    storeq ValueFalse, [cfr, t2, 8]
+    dispatch(3)
+
+
 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
     loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
@@ -1325,22 +1312,6 @@ _llint_op_get_array_length:
     dispatch(9)
 
 
-_llint_op_get_arguments_length:
-    traceExecution()
-    loadisFromInstruction(2, t0)
-    loadisFromInstruction(1, t1)
-    btqnz [cfr, t0, 8], .opGetArgumentsLengthSlow
-    loadi ArgumentCount + PayloadOffset[cfr], t2
-    subi 1, t2
-    orq tagTypeNumber, t2
-    storeq t2, [cfr, t1, 8]
-    dispatch(4)
-
-.opGetArgumentsLengthSlow:
-    callSlowPath(_llint_slow_path_get_arguments_length)
-    dispatch(4)
-
-
 macro putById(getPropertyStorage)
     traceExecution()
     writeBarrierOnOperands(1, 3)
@@ -1487,61 +1458,6 @@ _llint_op_get_by_val:
     dispatch(6)
 
 
-_llint_op_get_argument_by_val:
-    # FIXME: At some point we should array profile this. Right now it isn't necessary
-    # since the DFG will never turn a get_argument_by_val into a GetByVal.
-    traceExecution()
-    loadisFromInstruction(2, t0)
-    loadisFromInstruction(3, t1)
-    btqnz [cfr, t0, 8], .opGetArgumentByValSlow
-    loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
-    addi 1, t2
-    loadi ArgumentCount + PayloadOffset[cfr], t1
-    biaeq t2, t1, .opGetArgumentByValSlow
-    loadisFromInstruction(1, t3)
-    loadpFromInstruction(5, t1)
-    loadq ThisArgumentOffset[cfr, t2, 8], t0
-    storeq t0, [cfr, t3, 8]
-    valueProfile(t0, 5, t1)
-    dispatch(6)
-
-.opGetArgumentByValSlow:
-    callSlowPath(_llint_slow_path_get_argument_by_val)
-    dispatch(6)
-
-
-_llint_op_get_by_pname:
-    traceExecution()
-    loadisFromInstruction(3, t1)
-    loadConstantOrVariable(t1, t0)
-    loadisFromInstruction(4, t1)
-    assertNotConstant(t1)
-    bqneq t0, [cfr, t1, 8], .opGetByPnameSlow
-    loadisFromInstruction(2, t2)
-    loadisFromInstruction(5, t3)
-    loadConstantOrVariableCell(t2, t0, .opGetByPnameSlow)
-    assertNotConstant(t3)
-    loadq [cfr, t3, 8], t1
-    loadStructureWithScratch(t0, t2, t3)
-    bpneq t2, JSPropertyNameIterator::m_cachedStructure[t1], .opGetByPnameSlow
-    loadisFromInstruction(6, t3)
-    loadi PayloadOffset[cfr, t3, 8], t3
-    subi 1, t3
-    biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow
-    bilt t3, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], .opGetByPnameInlineProperty
-    addi firstOutOfLineOffset, t3
-    subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], t3
-.opGetByPnameInlineProperty:
-    loadPropertyAtVariableOffset(t3, t0, t0)
-    loadisFromInstruction(1, t1)
-    storeq t0, [cfr, t1, 8]
-    dispatch(7)
-
-.opGetByPnameSlow:
-    callSlowPath(_llint_slow_path_get_by_pname)
-    dispatch(7)
-
-
 macro contiguousPutByVal(storeCallback)
     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
 .storeResult:
@@ -1823,24 +1739,6 @@ _llint_op_switch_char:
     dispatch(0)
 
 
-_llint_op_new_func:
-    traceExecution()
-    loadisFromInstruction(3, t2)
-    btiz t2, .opNewFuncUnchecked
-    loadisFromInstruction(1, t1)
-    btqnz [cfr, t1, 8], .opNewFuncDone
-.opNewFuncUnchecked:
-    callSlowPath(_llint_slow_path_new_func)
-.opNewFuncDone:
-    dispatch(4)
-
-
-_llint_op_new_captured_func:
-    traceExecution()
-    callSlowPath(_slow_path_new_captured_func)
-    dispatch(4)
-
-
 macro arrayProfileForCall()
     loadisFromInstruction(4, t3)
     negp t3
@@ -1862,9 +1760,7 @@ macro doCall(slowPath)
     lshifti 3, t3
     negp t3
     addp cfr, t3
-    loadp JSFunction::m_scope[t2], t0
     storeq t2, Callee[t3]
-    storeq t0, ScopeChain[t3]
     loadisFromInstruction(3, t2)
     storei PC, ArgumentCount + TagOffset[cfr]
     storei t2, ArgumentCount + PayloadOffset[t3]
@@ -1876,25 +1772,6 @@ macro doCall(slowPath)
 end
 
 
-_llint_op_tear_off_activation:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    btqz [cfr, t0, 8], .opTearOffActivationNotCreated
-    callSlowPath(_llint_slow_path_tear_off_activation)
-.opTearOffActivationNotCreated:
-    dispatch(2)
-
-
-_llint_op_tear_off_arguments:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    addq 1, t0   # Get the unmodifiedArgumentsRegister
-    btqz [cfr, t0, 8], .opTearOffArgumentsNotCreated
-    callSlowPath(_llint_slow_path_tear_off_arguments)
-.opTearOffArgumentsNotCreated:
-    dispatch(3)
-
-
 _llint_op_ret:
     traceExecution()
     checkSwitchToJITForEpilogue()
@@ -1903,28 +1780,13 @@ _llint_op_ret:
     doReturn()
 
 
-_llint_op_ret_object_or_this:
-    traceExecution()
-    checkSwitchToJITForEpilogue()
-    loadisFromInstruction(1, t2)
-    loadConstantOrVariable(t2, t0)
-    btqnz t0, tagMask, .opRetObjectOrThisNotObject
-    bbb JSCell::m_type[t0], ObjectType, .opRetObjectOrThisNotObject
-    doReturn()
-
-.opRetObjectOrThisNotObject:
-    loadisFromInstruction(2, t2)
-    loadConstantOrVariable(t2, t0)
-    doReturn()
-
-
 _llint_op_to_primitive:
     traceExecution()
     loadisFromInstruction(2, t2)
     loadisFromInstruction(1, t3)
     loadConstantOrVariable(t2, t0)
     btqnz t0, tagMask, .opToPrimitiveIsImm
-    bbneq JSCell::m_type[t0], StringType, .opToPrimitiveSlowCase
+    bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
 .opToPrimitiveIsImm:
     storeq t0, [cfr, t3, 8]
     dispatch(3)
@@ -1934,49 +1796,6 @@ _llint_op_to_primitive:
     dispatch(3)
 
 
-_llint_op_next_pname:
-    traceExecution()
-    loadisFromInstruction(3, t1)
-    loadisFromInstruction(4, t2)
-    assertNotConstant(t1)
-    assertNotConstant(t2)
-    loadi PayloadOffset[cfr, t1, 8], t0
-    bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
-    loadisFromInstruction(5, t2)
-    assertNotConstant(t2)
-    loadp [cfr, t2, 8], t2
-    loadp JSPropertyNameIterator::m_jsStrings[t2], t3
-    loadq [t3, t0, 8], t3
-    addi 1, t0
-    storei t0, PayloadOffset[cfr, t1, 8]
-    loadisFromInstruction(1, t1)
-    storeq t3, [cfr, t1, 8]
-    loadisFromInstruction(2, t3)
-    assertNotConstant(t3)
-    loadq [cfr, t3, 8], t3
-    loadStructureWithScratch(t3, t1, t0)
-    bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
-    loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
-    loadp StructureChain::m_vector[t0], t0
-    btpz [t0], .opNextPnameTarget
-.opNextPnameCheckPrototypeLoop:
-    bqeq Structure::m_prototype[t1], ValueNull, .opNextPnameSlow
-    loadq Structure::m_prototype[t1], t2
-    loadStructureWithScratch(t2, t1, t3)
-    bpneq t1, [t0], .opNextPnameSlow
-    addp 8, t0
-    btpnz [t0], .opNextPnameCheckPrototypeLoop
-.opNextPnameTarget:
-    dispatchIntIndirect(6)
-
-.opNextPnameEnd:
-    dispatch(7)
-
-.opNextPnameSlow:
-    callSlowPath(_llint_slow_path_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
-    dispatch(0)
-
-
 _llint_op_catch:
     # Gotta restore the tag registers. We could be throwing from FTL, which may
     # clobber them.
@@ -1988,10 +1807,12 @@ _llint_op_catch:
     # the interpreter's throw trampoline (see _llint_throw_trampoline).
     # The throwing code must have known that we were throwing to the interpreter,
     # and have set VM::targetInterpreterPCForThrow.
-    loadp ScopeChain[cfr], t3
+    loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
     restoreStackPointerAfterCall()
 
     loadp CodeBlock[cfr], PB
@@ -1999,12 +1820,18 @@ _llint_op_catch:
     loadp VM::targetInterpreterPCForThrow[t3], PC
     subp PB, PC
     rshiftp 3, PC
+
     loadq VM::m_exception[t3], t0
     storeq 0, VM::m_exception[t3]
     loadisFromInstruction(1, t2)
     storeq t0, [cfr, t2, 8]
+
+    loadq Exception::m_value[t0], t3
+    loadisFromInstruction(2, t2)
+    storeq t3, [cfr, t2, 8]
+
     traceExecution()
-    dispatch(2)
+    dispatch(3)
 
 
 _llint_op_end:
@@ -2022,8 +1849,9 @@ _llint_throw_from_slow_path_trampoline:
     # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
     # the throw target is not necessarily interpreted code, we come to here.
     # This essentially emulates the JIT's throwing protocol.
-    loadp CodeBlock[cfr], t1
-    loadp CodeBlock::m_vm[t1], t1
+    loadp Callee[cfr], t1
+    andp MarkedBlockMask, t1
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
     jmp VM::targetMachinePCForThrow[t1]
 
 
@@ -2046,13 +1874,10 @@ macro nativeCallTrampoline(executableOffsetToFunction)
             const arg2 = t1  # t1 = rdx
             const temp = t0
         end
-        loadp ScopeChain[cfr], t0
-        andp MarkedBlockMask, t0
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t0], t0
-        storep cfr, VM::topCallFrame[t0]
-        loadp CallerFrame[cfr], t0
-        loadq ScopeChain[t0], t1
-        storeq t1, ScopeChain[cfr]
+        loadp Callee[cfr], t0
+        andp MarkedBlockMask, t0, t1
+        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+        storep cfr, VM::topCallFrame[t1]
         move cfr, arg1
         loadp Callee[cfr], arg2
         loadp JSFunction::m_executable[arg2], temp
@@ -2064,30 +1889,26 @@ macro nativeCallTrampoline(executableOffsetToFunction)
         if X86_64_WIN
             addp 32, sp
         end
-        loadp ScopeChain[cfr], t3
+        loadp Callee[cfr], t3
         andp MarkedBlockMask, t3
         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     elsif ARM64 or C_LOOP
-        loadp ScopeChain[cfr], t0
-        andp MarkedBlockMask, t0
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t0], t0
-        storep cfr, VM::topCallFrame[t0]
-        loadp CallerFrame[cfr], t2
-        loadp ScopeChain[t2], t1
-        storep t1, ScopeChain[cfr]
+        loadp Callee[cfr], t0
+        andp MarkedBlockMask, t0, t1
+        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+        storep cfr, VM::topCallFrame[t1]
         preserveReturnAddressAfterCall(t3)
         storep t3, ReturnPC[cfr]
         move cfr, t0
         loadp Callee[cfr], t1
         loadp JSFunction::m_executable[t1], t1
-        move t2, cfr # Restore cfr to avoid loading from stack
         if C_LOOP
             cloopCallNative executableOffsetToFunction[t1]
         else
             call executableOffsetToFunction[t1]
         end
         restoreReturnAddressBeforeReturn(t3)
-        loadp ScopeChain[cfr], t3
+        loadp Callee[cfr], t3
         andp MarkedBlockMask, t3
         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     else
@@ -2121,15 +1942,9 @@ macro varInjectionCheck(slowPath)
 end
 
 macro resolveScope()
-    loadp CodeBlock[cfr], t0
-    loadisFromInstruction(4, t2)
-    btbz CodeBlock::m_needsActivation[t0], .resolveScopeAfterActivationCheck
-    loadis CodeBlock::m_activationRegister[t0], t1
-    btpz [cfr, t1, 8], .resolveScopeAfterActivationCheck
-    addi 1, t2
-
-.resolveScopeAfterActivationCheck:
-    loadp ScopeChain[cfr], t0
+    loadisFromInstruction(5, t2)
+    loadisFromInstruction(2, t0)
+    loadp [cfr, t0, 8], t0
     btiz t2, .resolveScopeLoopEnd
 
 .resolveScopeLoop:
@@ -2145,44 +1960,44 @@ end
 
 _llint_op_resolve_scope:
     traceExecution()
-    loadisFromInstruction(3, t0)
+    loadisFromInstruction(4, t0)
 
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rClosureVar
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rClosureVar:
     bineq t0, ClosureVar, .rGlobalPropertyWithVarInjectionChecks
     resolveScope()
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getGlobalObject(1)
-    dispatch(6)
+    dispatch(7)
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
     varInjectionCheck(.rDynamic)
     resolveScope()
-    dispatch(6)
+    dispatch(7)
 
 .rDynamic:
     callSlowPath(_llint_slow_path_resolve_scope)
-    dispatch(6)
+    dispatch(7)
 
 
 macro loadWithStructureCheck(operand, slowPath)
@@ -2210,9 +2025,8 @@ macro getGlobalVar()
 end
 
 macro getClosureVar()
-    loadp JSVariableObject::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    loadq [t0, t1, 8], t0
+    loadq JSEnvironmentRecord_variables[t0, t1, 8], t0
     valueProfile(t0, 7, t1)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
@@ -2249,7 +2063,6 @@ _llint_op_get_from_scope:
 .gGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
     varInjectionCheck(.gDynamic)
-    loadVariable(2, t0)
     getGlobalVar()
     dispatch(8)
 
@@ -2276,17 +2089,27 @@ macro putGlobalVar()
     loadisFromInstruction(3, t0)
     loadConstantOrVariable(t0, t1)
     loadpFromInstruction(5, t2)
-    notifyWrite(t2, t1, t0, .pDynamic)
     loadpFromInstruction(6, t0)
+    notifyWrite(t2, .pDynamic)
     storeq t1, [t0]
 end
 
 macro putClosureVar()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2)
-    loadp JSVariableObject::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storeq t2, [t0, t1, 8]
+    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
+end
+
+macro putLocalClosureVar()
+    loadisFromInstruction(3, t1)
+    loadConstantOrVariable(t1, t2)
+    loadpFromInstruction(5, t3)
+    btpz t3, .noVariableWatchpointSet
+    notifyWrite(t3, .pDynamic)
+.noVariableWatchpointSet:
+    loadisFromInstruction(6, t1)
+    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
 end
 
 
@@ -2295,7 +2118,14 @@ _llint_op_put_to_scope:
     loadisFromInstruction(4, t0)
     andi ResolveModeMask, t0
 
-#pGlobalProperty:
+#pLocalClosureVar:
+    bineq t0, LocalClosureVar, .pGlobalProperty
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t0)
+    putLocalClosureVar()
+    dispatch(7)
+
+.pGlobalProperty:
     bineq t0, GlobalProperty, .pGlobalVar
     writeBarrierOnOperands(1, 3)
     loadWithStructureCheck(1, .pDynamic)
@@ -2340,3 +2170,65 @@ _llint_op_put_to_scope:
 .pDynamic:
     callSlowPath(_llint_slow_path_put_to_scope)
     dispatch(7)
+
+
+_llint_op_get_from_arguments:
+    traceExecution()
+    loadVariable(2, t0)
+    loadi 24[PB, PC, 8], t1
+    loadq DirectArguments_storage[t0, t1, 8], t0
+    valueProfile(t0, 4, t1)
+    loadisFromInstruction(1, t1)
+    storeq t0, [cfr, t1, 8]
+    dispatch(5)
+
+
+_llint_op_put_to_arguments:
+    traceExecution()
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t0)
+    loadi 16[PB, PC, 8], t1
+    loadisFromInstruction(3, t3)
+    loadConstantOrVariable(t3, t2)
+    storeq t2, DirectArguments_storage[t0, t1, 8]
+    dispatch(4)
+
+
+_llint_op_profile_type:
+    traceExecution()
+    loadp CodeBlock[cfr], t1
+    loadp CodeBlock::m_vm[t1], t1
+    # t1 is holding the pointer to the typeProfilerLog.
+    loadp VM::m_typeProfilerLog[t1], t1
+    # t2 is holding the pointer to the current log entry.
+    loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
+
+    # t0 is holding the JSValue argument.
+    loadisFromInstruction(1, t3)
+    loadConstantOrVariable(t3, t0)
+
+    # Store the JSValue onto the log entry.
+    storeq t0, TypeProfilerLog::LogEntry::value[t2]
+    
+    # Store the TypeLocation onto the log entry.
+    loadpFromInstruction(2, t3)
+    storep t3, TypeProfilerLog::LogEntry::location[t2]
+
+    btqz t0, tagMask, .opProfileTypeIsCell
+    storei 0, TypeProfilerLog::LogEntry::structureID[t2]
+    jmp .opProfileTypeSkipIsCell
+.opProfileTypeIsCell:
+    loadi JSCell::m_structureID[t0], t3
+    storei t3, TypeProfilerLog::LogEntry::structureID[t2]
+.opProfileTypeSkipIsCell:
+    
+    # Increment the current log entry.
+    addp sizeof TypeProfilerLog::LogEntry, t2
+    storep t2, TypeProfilerLog::m_currentLogEntryPtr[t1]
+
+    loadp TypeProfilerLog::m_logEndPtr[t1], t1
+    bpneq t2, t1, .opProfileTypeDone
+    callSlowPath(_slow_path_profile_type_clear_log)
+
+.opProfileTypeDone:
+    dispatch(6)
index 870688e7984fb88b0c722d29d62ccb58e13ffd5a..47348bc394a50449a30f4392b75034ce75aa573c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #if HAVE(LLVM)
 
 #include "LLVMAPI.h"
+#include "Options.h"
 #include <pthread.h>
+#include <wtf/DataLog.h>
 
 namespace JSC {
 
 static pthread_once_t initializeLLVMOnceKey = PTHREAD_ONCE_INIT;
 
+static void initializeLLVMImpl()
+{
+    const bool verbose =
+        Options::verboseFTLCompilation()
+        || Options::showFTLDisassembly()
+        || Options::verboseFTLFailure()
+        || Options::verboseCompilation()
+        || Options::showDFGDisassembly()
+        || Options::showDisassembly();
+    
+    LLVMInitializerFunction initializer = getLLVMInitializerFunction(verbose);
+    if (!initializer)
+        return;
+    
+    bool enableFastISel = Options::enableLLVMFastISel();
+    llvm = initializer(WTFLogAlwaysAndCrash, &enableFastISel);
+    if (!llvm) {
+        if (verbose)
+            dataLog("LLVM initilization failed.\n");
+    }
+    if (Options::enableLLVMFastISel() && !enableFastISel) {
+        if (verbose)
+            dataLog("Fast ISel requested but LLVM not new enough.\n");
+    }
+    
+    enableLLVMFastISel = enableFastISel;
+}
+
 bool initializeLLVM()
 {
     pthread_once(&initializeLLVMOnceKey, initializeLLVMImpl);
index ba6d92e06221269aba75c4ea269c98580f7d13d0..dd7b7bcabcb6922054b294de2551de93f4323fba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if HAVE(LLVM)
 
+#include "LLVMAPI.h"
+#include <string>
+#include <wtf/text/CString.h>
+
 namespace JSC {
 
-void initializeLLVMImpl();
+typedef void (*LoggerFunction)(const char*, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
+typedef LLVMAPI* (*LLVMInitializerFunction)(LoggerFunction, bool* enableFastISel);
+
+LLVMInitializerFunction getLLVMInitializerFunction(bool verbose);
+
+extern const CString* llvmBitcodeLibraryForInliningPath;
 
-// You msut call this before using JSC::llvm. It's safe to call this multiple times.
+// You must call this before using JSC::llvm. It's safe to call this multiple times.
 // Returns true if we successfully loaded LLVM. Returns false if we didn't.
 bool initializeLLVM();
 
index cbbd28f978fd6cc20927ad94948ac8b525a4708a..9e06ddac054ed5cc25fa91915211e95ff59a8f2b 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2013 University of Szeged. All rights reserved.
  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,9 +34,9 @@
 
 namespace JSC {
 
-void initializeLLVMImpl()
+LLVMInitializerFunction getLLVMInitializerFunction(bool verbose)
 {
-    initializeLLVMPOSIX("libllvmForJSC.so");
+    return getLLVMInitializerFunctionPOSIX("libllvmForJSC.so", verbose);
 }
 
 } // namespace JSC
diff --git a/llvm/InitializeLLVMMac.cpp b/llvm/InitializeLLVMMac.cpp
new file mode 100644 (file)
index 0000000..ade7ff4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "InitializeLLVM.h"
+
+#if HAVE(LLVM)
+
+#include "BundlePath.h"
+#include "InitializeLLVMPOSIX.h"
+#include <wtf/StringPrintStream.h>
+
+// Use the "JS" prefix to make check-for-inappropriate-objc-class-names happy. I
+// think this is better than hacking that script.
+
+namespace JSC {
+
+LLVMInitializerFunction getLLVMInitializerFunction(bool verbose)
+{
+    return getLLVMInitializerFunctionPOSIX(toCString(bundlePath().data(), "/Libraries/libllvmForJSC.dylib").data(), verbose);
+}
+
+} // namespace JSC
+
+#endif // HAVE(LLVM)
diff --git a/llvm/InitializeLLVMMac.mm b/llvm/InitializeLLVMMac.mm
deleted file mode 100644 (file)
index 55d5b64..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#import "config.h"
-#import "InitializeLLVM.h"
-
-#if HAVE(LLVM)
-
-#import "InitializeLLVMPOSIX.h"
-#import <Foundation/Foundation.h>
-
-// Use the "JS" prefix to make check-for-inappropriate-objc-class-names happy. I
-// think this is better than hacking that script.
-
-@interface JSJavaScriptCoreBundleFinder : NSObject
-@end
-
-@implementation JSJavaScriptCoreBundleFinder
-@end
-
-namespace JSC {
-
-void initializeLLVMImpl()
-{
-    @autoreleasepool {
-        NSBundle *myBundle = [NSBundle bundleForClass:[JSJavaScriptCoreBundleFinder class]];
-        NSString *path = [[myBundle bundlePath] stringByAppendingPathComponent:@"Libraries/libllvmForJSC.dylib"];
-        
-        initializeLLVMPOSIX([path UTF8String]);
-    }
-}
-
-} // namespace JSC
-
-#endif // HAVE(LLVM)
index 447e1303f768fb7c6e031dcb99f5626d3e6ef4fd..8c9c24844fa652c748fa7e05bb2920533397b126 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-typedef void (*LoggerFunction)(const char*, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
-typedef LLVMAPI* (*InitializerFunction)(LoggerFunction);
-
-void initializeLLVMPOSIX(const char* libraryName)
+LLVMInitializerFunction getLLVMInitializerFunctionPOSIX(const char* libraryName, bool verbose)
 {
-    const bool verbose =
-        Options::verboseFTLCompilation()
-        || Options::showFTLDisassembly()
-        || Options::verboseFTLFailure()
-        || Options::verboseCompilation()
-        || Options::showDFGDisassembly()
-        || Options::showDisassembly();
+    int flags = RTLD_NOW;
+    
+#if OS(LINUX)
+    // We need this to cause our overrides (like __cxa_atexit) to take precedent over the __cxa_atexit that is already
+    // globally exported. Those overrides are necessary to prevent crashes (our __cxa_atexit turns off LLVM's exit-time
+    // destruction, which causes exit-time crashes if the concurrent JIT is still running) and to make LLVM assertion
+    // failures funnel through WebKit's mechanisms. This flag induces behavior that is the default on Darwin. Other OSes
+    // may need their own flags in place of this.
+    flags |= RTLD_DEEPBIND;
+#endif
     
-    void* library = dlopen(libraryName, RTLD_NOW);
+    void* library = dlopen(libraryName, flags);
     if (!library) {
         if (verbose)
             dataLog("Failed to load LLVM library at ", libraryName, ": ", dlerror(), "\n");
-        return;
+        return nullptr;
     }
     
     const char* symbolName = "initializeAndGetJSCLLVMAPI";
-    InitializerFunction initializer = bitwise_cast<InitializerFunction>(
+    LLVMInitializerFunction initializer = bitwise_cast<LLVMInitializerFunction>(
         dlsym(library, symbolName));
     if (!initializer) {
         if (verbose)
             dataLog("Failed to find ", symbolName, " in ", libraryName, ": ", dlerror());
-        return;
+        return nullptr;
     }
     
-    llvm = initializer(WTFLogAlwaysAndCrash);
-    if (!llvm) {
-        if (verbose)
-            dataLog("LLVM initilization failed.\n");
-    }
+    return initializer;
 }
 
 } // namespace JSC
index ffc37c5de1142f8736673fd30c023e9ba2253b02..c3ee8217f97d10a68b6bf9a008cd054635ca10f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if HAVE(LLVM)
 
+#include "InitializeLLVM.h"
+
 namespace JSC {
 
-void initializeLLVMPOSIX(const char* libraryName);
+LLVMInitializerFunction getLLVMInitializerFunctionPOSIX(const char* libraryName, bool verbose);
 
 } // namespace JSC
 
index f60d4caa2af051c01b41f142fe724178c0aa112b..c56b8974b9d10b13279111019b32157ab0198913 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-typedef LLVMAPI* (*InitializerFunction)(void(*)(const char*, ...));
-
-void initializeLLVMImpl()
+LLVMInitializerFunction getLLVMInitializerFunction(bool /* verbose */)
 {
     const wchar_t* libraryName = L"libllvmForJSC.dll";
 
     HMODULE library = ::LoadLibrary(libraryName);
 
     if (!library)
-        return;
+        return nullptr;
 
     const char* symbolName = "initializeAndGetJSCLLVMAPI";
-    InitializerFunction initializer = bitwise_cast<InitializerFunction>(GetProcAddress(library, symbolName));
-    if (initializer)
-        llvm = initializer(WTFLogAlwaysAndCrash);
+    return bitwise_cast<LLVMInitializerFunction>(GetProcAddress(library, symbolName));
 }
 
 } // namespace JSC
index 283723e16bb1347c90a406e87410c135e0ae8f33..34995124f21a2183549d4ca2932765a314d0faae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
 namespace JSC {
 
 LLVMAPI* llvm;
+bool enableLLVMFastISel;
 
 }
 
index 581be3b430e6b9f9845f84c9797e2893bf3b9a97..a10318befaa691228f94e54880177e68e425fd28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,9 +38,13 @@ struct LLVMAPI {
     returnType (*name) signature;
     FOR_EACH_LLVM_API_FUNCTION(LLVM_API_FUNCTION_DECLARATION)
 #undef LLVM_API_FUNCTION_DECLARATION
+    
+    // Functions that we add conditionally.
+    void (*AddLowerSwitchPass)(LLVMPassManagerRef PM);
 };
 
 extern LLVMAPI* llvm;
+extern bool enableLLVMFastISel;
 
 } // namespace JSC
 
index f9c11ce2e6240e78f12de977add2551a5a485c2a..14c4f000e6bbf3a3ad7b583f7200513fa6d7ca26 100644 (file)
 #include "LLVMHeaders.h"
 
 #define FOR_EACH_LLVM_API_FUNCTION(macro) \
+    macro(LLVMBool, ParseBitcode, (LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, char **OutMessage)) \
+    macro(LLVMBool, ParseBitcodeInContext, (LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, char **OutMessage)) \
+    macro(LLVMBool, GetBitcodeModuleInContext, (LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, char **OutMessage)) \
+    macro(LLVMBool, GetBitcodeModule, (LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, char **OutMessage)) \
+    macro(LLVMBool, GetBitcodeModuleProviderInContext, (LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef *OutMP, char **OutMessage)) \
+    macro(LLVMBool, GetBitcodeModuleProvider, (LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef *OutMP, char **OutMessage)) \
+    macro(LLVMBool, LinkModules, (LLVMModuleRef Dest, LLVMModuleRef Str, LLVMLinkerMode Mode, char **OutMessage)) \
     macro(void, InitializeCore, (LLVMPassRegistryRef R)) \
     macro(void, Shutdown, ()) \
     macro(char *, CreateMessage, (const char *Message)) \
@@ -51,6 +58,7 @@
     macro(void, SetModuleInlineAsm, (LLVMModuleRef M, const char *Asm)) \
     macro(LLVMContextRef, GetModuleContext, (LLVMModuleRef M)) \
     macro(LLVMTypeRef, GetTypeByName, (LLVMModuleRef M, const char *Name)) \
+    macro(void, DumpType, (LLVMTypeRef Val)) \
     macro(unsigned, GetNamedMetadataNumOperands, (LLVMModuleRef M, const char* name)) \
     macro(void, GetNamedMetadataOperands, (LLVMModuleRef M, const char* name, LLVMValueRef *Dest)) \
     macro(void, AddNamedMetadataOperand, (LLVMModuleRef M, const char* name, LLVMValueRef Val)) \
     macro(double, GenericValueToFloat, (LLVMTypeRef TyRef, LLVMGenericValueRef GenVal)) \
     macro(void, DisposeGenericValue, (LLVMGenericValueRef GenVal)) \
     macro(LLVMBool, CreateExecutionEngineForModule, (LLVMExecutionEngineRef *OutEE, LLVMModuleRef M, char **OutError)) \
-    macro(LLVMBool, CreateInterpreterForModule, (LLVMExecutionEngineRef *OutInterp, LLVMModuleRef M, char **OutError)) \
-    macro(LLVMBool, CreateJITCompilerForModule, (LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, unsigned OptLevel, char **OutError)) \
     macro(void, InitializeMCJITCompilerOptions, (struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions)) \
     macro(LLVMBool, CreateMCJITCompilerForModule, (LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions, char **OutError)) \
     macro(LLVMBool, CreateExecutionEngine, (LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, char **OutError)) \
-    macro(LLVMBool, CreateInterpreter, (LLVMExecutionEngineRef *OutInterp, LLVMModuleProviderRef MP, char **OutError)) \
-    macro(LLVMBool, CreateJITCompiler, (LLVMExecutionEngineRef *OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, char **OutError)) \
     macro(void, DisposeExecutionEngine, (LLVMExecutionEngineRef EE)) \
     macro(void, RunStaticConstructors, (LLVMExecutionEngineRef EE)) \
     macro(void, RunStaticDestructors, (LLVMExecutionEngineRef EE)) \
     macro(LLVMBool, FindFunction, (LLVMExecutionEngineRef EE, const char *Name, LLVMValueRef *OutFn)) \
     macro(void *, RecompileAndRelinkFunction, (LLVMExecutionEngineRef EE, LLVMValueRef Fn)) \
     macro(LLVMTargetDataRef, GetExecutionEngineTargetData, (LLVMExecutionEngineRef EE)) \
+    macro(LLVMTargetMachineRef, GetExecutionEngineTargetMachine, (LLVMExecutionEngineRef EE)) \
     macro(void, AddGlobalMapping, (LLVMExecutionEngineRef EE, LLVMValueRef Global, void* Addr)) \
     macro(void *, GetPointerToGlobal, (LLVMExecutionEngineRef EE, LLVMValueRef Global)) \
     macro(LLVMMCJITMemoryManagerRef, CreateSimpleMCJITMemoryManager, (void *Opaque, LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, LLVMMemoryManagerDestroyCallback Destory)) \
     macro(void, PassManagerBuilderPopulateFunctionPassManager, (LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM)) \
     macro(void, PassManagerBuilderPopulateModulePassManager, (LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM)) \
     macro(void, PassManagerBuilderPopulateLTOPassManager, (LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, LLVMBool Internalize, LLVMBool RunInliner)) \
+    macro(void, AddAnalysisPasses, (LLVMTargetMachineRef T, LLVMPassManagerRef PM)) \
+    macro(void, AddInternalizePass, (LLVMPassManagerRef PM, unsigned AllButMain)) \
     macro(void, AddAggressiveDCEPass, (LLVMPassManagerRef PM)) \
     macro(void, AddCFGSimplificationPass, (LLVMPassManagerRef PM)) \
     macro(void, AddDeadStoreEliminationPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddFunctionInliningPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddGlobalDCEPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddPruneEHPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddIPSCCPPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddDeadArgEliminationPass, (LLVMPassManagerRef PM)) \
+    macro(void, AddConstantMergePass, (LLVMPassManagerRef PM)) \
+    macro(void, AddGlobalOptimizerPass, (LLVMPassManagerRef PM)) \
     macro(void, AddGVNPass, (LLVMPassManagerRef PM)) \
     macro(void, AddIndVarSimplifyPass, (LLVMPassManagerRef PM)) \
     macro(void, AddInstructionCombiningPass, (LLVMPassManagerRef PM)) \
index b6bffe2613a2eb256c11c5ec2a6af6cd089f7364..4b41fe6b53b645321805c2e726bd0c50c3736224 100644 (file)
 #endif // COMPILER(CLANG)
 
 #include <llvm-c/Analysis.h>
+#include <llvm-c/BitReader.h>
 #include <llvm-c/Core.h>
 #include <llvm-c/Disassembler.h>
 #include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Initialization.h>
+#include <llvm-c/Linker.h>
 #include <llvm-c/Target.h>
+#include <llvm-c/TargetMachine.h>
+#include <llvm-c/Transforms/IPO.h>
 #include <llvm-c/Transforms/PassManagerBuilder.h>
 #include <llvm-c/Transforms/Scalar.h>
 
index b1979f2a302608e5779665c330c51914ea5f8666..a6624a9cfd14af124768c32ff40d3dafa015a51b 100644 (file)
 #undef __STDC_LIMIT_MACROS
 #undef __STDC_CONSTANT_MACROS
 
-extern "C" WTF_EXPORT_PRIVATE JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*)(const char*, ...));
+static void llvmCrash(const char*) NO_RETURN;
+extern "C" WTF_EXPORT_PRIVATE JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(
+    void (*)(const char*, ...) NO_RETURN, bool* enableFastISel);
 
 static void llvmCrash(const char* reason)
 {
     g_llvmTrapCallback("LLVM fatal error: %s", reason);
 }
 
-extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*, ...))
+template<typename... Args>
+void initCommandLine(Args... args)
+{
+    const char* theArgs[] = { args... };
+    llvm::cl::ParseCommandLineOptions(sizeof(theArgs) / sizeof(const char*), theArgs);
+}
+
+extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(
+    void (*callback)(const char*, ...) NO_RETURN,
+    bool* enableFastISel)
 {
     g_llvmTrapCallback = callback;
     
@@ -81,28 +92,50 @@ extern "C" JSC::LLVMAPI* initializeAndGetJSCLLVMAPI(void (*callback)(const char*
     LLVMInitializeX86AsmPrinter();
     LLVMInitializeX86Disassembler();
 #elif CPU(ARM64)
+#if (__IPHONE_OS_VERSION_MIN_REQUIRED > 80200) || OS(LINUX)
+    LLVMInitializeAArch64TargetInfo();
+    LLVMInitializeAArch64Target();
+    LLVMInitializeAArch64TargetMC();
+    LLVMInitializeAArch64AsmPrinter();
+    LLVMInitializeAArch64Disassembler();
+#else
     LLVMInitializeARM64TargetInfo();
     LLVMInitializeARM64Target();
     LLVMInitializeARM64TargetMC();
     LLVMInitializeARM64AsmPrinter();
     LLVMInitializeARM64Disassembler();
+#endif
 #else
     UNREACHABLE_FOR_PLATFORM();
 #endif
     
-    const char* args[] = {
-        "llvmForJSC.dylib",
-        "-enable-patchpoint-liveness=true"
-    };
-    llvm::cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args);
+#if LLVM_VERSION_MAJOR >= 4 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6)
+    // It's OK to have fast ISel, if it was requested.
+#else
+    // We don't have enough support for fast ISel. Disable it.
+    *enableFastISel = false;
+#endif
+
+    if (*enableFastISel)
+        initCommandLine("llvmForJSC.dylib", "-enable-misched=false", "-regalloc=basic");
+    else
+        initCommandLine("llvmForJSC.dylib", "-enable-patchpoint-liveness=true");
     
     JSC::LLVMAPI* result = new JSC::LLVMAPI;
     
+    // Initialize the whole thing to null.
+    memset(result, 0, sizeof(*result));
+    
 #define LLVM_API_FUNCTION_ASSIGNMENT(returnType, name, signature) \
     result->name = LLVM##name;
     FOR_EACH_LLVM_API_FUNCTION(LLVM_API_FUNCTION_ASSIGNMENT);
 #undef LLVM_API_FUNCTION_ASSIGNMENT
     
+    // Handle conditionally available functions.
+#if LLVM_VERSION_MAJOR >= 4 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6)
+    result->AddLowerSwitchPass = LLVMAddLowerSwitchPass;
+#endif
+    
     return result;
 }
 
index ced4066f90c138e2c552a98b508df3a41c068c4e..ef288367c33726acc18736f05351d94d8c44d2a3 100644 (file)
 extern "C" int __cxa_atexit();
 extern "C" int __cxa_atexit() { return 0; }
 
-void (*g_llvmTrapCallback)(const char* message, ...);
+void (*g_llvmTrapCallback)(const char* message, ...) NO_RETURN;
 
 // If LLVM tries to raise signals, abort, or fail an assertion, then let
 // WebKit handle it instead of trapping.
 extern "C" int raise(int signal);
-extern "C" void __assert_rtn(const char* function, const char* filename, int lineNumber, const char* expression);
-extern "C" void abort(void);
+extern "C" void __assert_rtn(const char* function, const char* filename, int lineNumber, const char* expression) NO_RETURN;
+extern "C" void abort(void) NO_RETURN;
 
 extern "C" int raise(int signal)
 {
index 92620b0929b9090b0a3a9615a063d39b18146e5b..6bcaf6d8a1091ade16ff544d8de6d0591d1180e1 100644 (file)
@@ -26,7 +26,9 @@
 #ifndef LLVMTrapCallback_h
 #define LLVMTrapCallback_h
 
-extern void (*g_llvmTrapCallback)(const char* message, ...);
+#include <wtf/Assertions.h>
+
+extern void (*g_llvmTrapCallback)(const char* message, ...) NO_RETURN;
 
 #endif // LLVMTrapCallback_h
 
diff --git a/llvm/library/libllvmForJSC.version b/llvm/library/libllvmForJSC.version
new file mode 100644 (file)
index 0000000..198bde8
--- /dev/null
@@ -0,0 +1,4 @@
+LLVMFORJSC {
+    global: initializeAndGetJSCLLVMAPI;
+    local: *;
+};
index c92243610e3142dad55d7b8dc2cf8ba6b97ab811..44cfbe5c906ec82b5d00246d7d1830b7e8000468 100644 (file)
@@ -466,18 +466,6 @@ class Instruction
                 | op |
                 $asm.puts "push { #{op.armOperand} }"
             }
-        when "popCalleeSaves"
-            if isARMv7
-                $asm.puts "pop {r4-r6, r8-r11}"                
-            else
-                $asm.puts "pop {r4-r10}"
-            end
-        when "pushCalleeSaves"
-            if isARMv7
-                $asm.puts "push {r4-r6, r8-r11}"
-            else
-                $asm.puts "push {r4-r10}"
-            end
         when "move"
             if operands[0].immediate?
                 armMoveImmediate(operands[0].value, operands[1])
index 76d3dcc3bef656209f48febba8ab7244161b83e9..3a0d786c8f8498a0178df339223b794e1e918b10 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2014 University of Szeged. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -197,6 +198,64 @@ end
 # Actual lowering code follows.
 #
 
+def arm64LowerMalformedLoadStoreAddresses(list)
+    newList = []
+
+    def isAddressMalformed(operand)
+        operand.is_a? Address and not (-255..4095).include? operand.offset.value
+    end
+
+    list.each {
+        | node |
+        if node.is_a? Instruction
+            if node.opcode =~ /^store/ and isAddressMalformed(node.operands[1])
+                address = node.operands[1]
+                tmp = Tmp.new(codeOrigin, :gpr)
+                newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp])
+                newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0))], node.annotation)
+            elsif node.opcode =~ /^load/ and isAddressMalformed(node.operands[0])
+                address = node.operands[0]
+                tmp = Tmp.new(codeOrigin, :gpr)
+                newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp])
+                newList << Instruction.new(node.codeOrigin, node.opcode, [BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0)), node.operands[1]], node.annotation)
+            else
+                newList << node
+            end
+        else
+            newList << node
+        end
+    }
+    newList
+end
+
+# Workaround for Cortex-A53 erratum (835769)
+def arm64CortexA53Fix835769(list)
+    newList = []
+    lastOpcodeUnsafe = false
+
+    list.each {
+        | node |
+        if node.is_a? Instruction
+            case node.opcode
+            when /^store/, /^load/
+                # List all macro instructions that can be lowered to a load, store or prefetch ARM64 assembly instruction
+                lastOpcodeUnsafe = true
+            when  "muli", "mulp", "mulq", "smulli"
+                # List all macro instructions that can be lowered to a 64-bit multiply-accumulate ARM64 assembly instruction
+                # (defined as one of MADD, MSUB, SMADDL, SMSUBL, UMADDL or UMSUBL).
+                if lastOpcodeUnsafe
+                    newList << Instruction.new(node.codeOrigin, "nopCortexA53Fix835769", [])
+                end
+                lastOpcodeUnsafe = false
+            else
+                lastOpcodeUnsafe = false
+            end
+        end
+        newList << node
+    }
+    newList
+end
+
 class Sequence
     def getModifiedListARM64
         result = @list
@@ -204,6 +263,7 @@ class Sequence
         result = riscLowerSimpleBranchOps(result)
         result = riscLowerHardBranchOps64(result)
         result = riscLowerShiftOps(result)
+        result = arm64LowerMalformedLoadStoreAddresses(result)
         result = riscLowerMalformedAddresses(result) {
             | node, address |
             case node.opcode
@@ -252,6 +312,7 @@ class Sequence
         result = riscLowerTest(result)
         result = assignRegistersToTemporaries(result, :gpr, ARM64_EXTRA_GPRS)
         result = assignRegistersToTemporaries(result, :fpr, ARM64_EXTRA_FPRS)
+        result = arm64CortexA53Fix835769(result)
         return result
     end
 end
@@ -369,7 +430,7 @@ def emitARM64MoveImmediate(value, target)
     [48, 32, 16, 0].each {
         | shift |
         currentValue = (value >> shift) & 0xffff
-        next if currentValue == (isNegative ? 0xffff : 0) and shift != 0
+        next if currentValue == (isNegative ? 0xffff : 0) and (shift != 0 or !first)
         if first
             if isNegative
                 $asm.puts "movn #{target.arm64Operand(:ptr)}, \##{(~currentValue) & 0xffff}, lsl \##{shift}"
@@ -586,22 +647,6 @@ class Instruction
                 | ops |
                 $asm.puts "stp #{ops[0].arm64Operand(:ptr)}, #{ops[1].arm64Operand(:ptr)}, [sp, #-16]!"
             }
-        when "popLRAndFP"
-            $asm.puts "ldp x29, x30, [sp], #16"
-        when "pushLRAndFP"
-            $asm.puts "stp x29, x30, [sp, #-16]!"
-        when "popCalleeSaves"
-            $asm.puts "ldp x28, x27, [sp], #16"
-            $asm.puts "ldp x26, x25, [sp], #16"
-            $asm.puts "ldp x24, x23, [sp], #16"
-            $asm.puts "ldp x22, x21, [sp], #16"
-            $asm.puts "ldp x20, x19, [sp], #16"
-        when "pushCalleeSaves"
-            $asm.puts "stp x20, x19, [sp, #-16]!"
-            $asm.puts "stp x22, x21, [sp, #-16]!"
-            $asm.puts "stp x24, x23, [sp, #-16]!"
-            $asm.puts "stp x26, x25, [sp, #-16]!"
-            $asm.puts "stp x28, x27, [sp, #-16]!"
         when "move"
             if operands[0].immediate?
                 emitARM64MoveImmediate(operands[0].value, operands[1])
@@ -821,7 +866,11 @@ class Instruction
         when "memfence"
             $asm.puts "dmb sy"
         when "pcrtoaddr"
-          $asm.puts "adr #{operands[1].arm64Operand(:ptr)}, #{operands[0].value}"
+            $asm.puts "adr #{operands[1].arm64Operand(:ptr)}, #{operands[0].value}"
+        when "nopCortexA53Fix835769"
+            $asm.putStr("#if CPU(ARM64_CORTEXA53)")
+            $asm.puts "nop"
+            $asm.putStr("#endif")
         else
             lowerDefault
         end
index dc2de5e1130b7179e9f6d1f8d2c4e13da5acbfe2..1241b7fe5a2b1c721b342929d7de600255ddd676 100644 (file)
@@ -580,6 +580,44 @@ class BitnotImmediate < Node
     end
 end
 
+class StringLiteral < NoChildren
+    attr_reader :value
+    
+    def initialize(codeOrigin, value)
+        super(codeOrigin)
+        @value = value[1..-2]
+        raise "Bad string literal #{value.inspect} at #{codeOriginString}" unless value.is_a? String
+    end
+    
+    def dump
+        "#{value}"
+    end
+    
+    def ==(other)
+        other.is_a? StringLiteral and other.value == @value
+    end
+    
+    def address?
+        false
+    end
+    
+    def label?
+        false
+    end
+    
+    def immediate?
+        false
+    end
+    
+    def immediateOperand?
+        false
+    end
+        
+    def register?
+        false
+    end
+end
+
 class RegisterID < NoChildren
     attr_reader :name
     
@@ -889,6 +927,8 @@ class Instruction < Node
             $asm.putLocalAnnotation
         when "globalAnnotation"
             $asm.putGlobalAnnotation
+        when "emit"
+          $asm.puts "#{operands[0].dump}"
         else
             raise "Unhandled opcode #{opcode} at #{codeOriginString}"
         end
index 4fa3e19ecd00ea0c9be784f32bfe3ab833a0e049..e7805dfe48732cf2ac6a0a2333703633dc0fd752 100644 (file)
@@ -67,6 +67,37 @@ WORKING_BACKENDS =
 
 BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
 
+$allBackends = {}
+$validBackends = {}
+BACKENDS.each {
+    | backend |
+    $validBackends[backend] = true
+    $allBackends[backend] = true
+}
+
+def includeOnlyBackends(list)
+    newValidBackends = {}
+    list.each {
+        | backend |
+        if $validBackends[backend]
+            newValidBackends[backend] = true
+        end
+    }
+    $validBackends = newValidBackends
+end
+
+def isBackend?(backend)
+    $allBackends[backend]
+end
+
+def isValidBackend?(backend)
+    $validBackends[backend]
+end
+
+def validBackends
+    $validBackends.keys
+end
+
 class Node
     def lower(name)
         begin
index d0cbc06622a0bbbf5d714798e793221b3708296a..04a6998144786dec55c436f6b99154fd16b07b2f 100644 (file)
@@ -1104,9 +1104,6 @@ class Instruction
                 $asm.putc "POP(#{op.clDump});"
             }
 
-        when "pushCalleeSaves"
-        when "popCalleeSaves"
-
 
         # A convenience and compact call to crash because we don't want to use
         # the generic llint crash mechanism which relies on the availability
index 07ce7177bda56e500e781a952be15b78688558a4..fc4579c17335273b6b50525d6b5a2114dc2d9c4f 100644 (file)
@@ -39,6 +39,12 @@ IncludeFile.processIncludeOptions()
 inputFlnm = ARGV.shift
 outputFlnm = ARGV.shift
 
+validBackends = ARGV.shift
+if validBackends
+    $stderr.puts "Only dealing with backends: #{validBackends}"
+    includeOnlyBackends(validBackends.split(","))
+end
+
 $stderr.puts "offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
 
 def emitMagicNumber
index 44280e776b1ce2a563bbd366d37281f1ed3b3032..1d0d8676a62a6264dc01ff26b0e7bc2daeb5eb7c 100644 (file)
@@ -30,6 +30,7 @@ require "set"
 
 MACRO_INSTRUCTIONS =
     [
+     "emit",
      "addi",
      "andi",
      "lshifti",
@@ -248,8 +249,6 @@ MACRO_INSTRUCTIONS =
      "bnz",
      "leai",
      "leap",
-     "pushCalleeSaves",
-     "popCalleeSaves",
      "memfence"
     ]
 
@@ -267,9 +266,8 @@ ARM_INSTRUCTIONS =
 
 ARM64_INSTRUCTIONS =
     [
-     "pcrtoaddr",    # Address from PC relative offset - adr instruction
-     "popLRAndFP",   # ARM64 requires registers to be pushed and popped in pairs,
-     "pushLRAndFP"   # therefore we do LR (link register) and FP (frame pointer) together.
+     "pcrtoaddr",   # Address from PC relative offset - adr instruction
+     "nopFixCortexA53Err835769" # nop on Cortex-A53 (nothing otherwise)
     ]
 
 RISC_INSTRUCTIONS =
@@ -283,12 +281,12 @@ RISC_INSTRUCTIONS =
 
 MIPS_INSTRUCTIONS =
     [
+    "la",
     "movz",
     "movn",
     "slt",
     "sltu",
-    "pichdr",
-    "pichdrra"
+    "pichdr"
     ]
 
 SH4_INSTRUCTIONS =
index 686f58f164f0fc6bc166f6614bc971cde12d1b99..cc107ec3750b624547ecfe745fc2a8f63c932fc7 100644 (file)
@@ -62,7 +62,6 @@ MIPS_TEMP_GPRS = [SpecialRegister.new("$t5"), SpecialRegister.new("$t6"), Specia
 MIPS_ZERO_REG = SpecialRegister.new("$zero")
 MIPS_GP_REG = SpecialRegister.new("$gp")
 MIPS_GPSAVE_REG = SpecialRegister.new("$s4")
-MIPS_JUMP_REG = SpecialRegister.new("$ra")
 MIPS_CALL_REG = SpecialRegister.new("$t9")
 MIPS_TEMP_FPRS = [SpecialRegister.new("$f16")]
 MIPS_SCRATCH_FPR = SpecialRegister.new("$f18")
@@ -161,6 +160,70 @@ class AbsoluteAddress
     end
 end
 
+#
+# Negate condition of branches to labels.
+#
+
+class Instruction
+    def mipsNegateCondition(list)
+        /^(b(add|sub|or|mul|t)?)([ipb])/.match(opcode)
+        case $~.post_match
+        when "eq"
+            op = "neq"
+        when "neq"
+            op = "eq"
+        when "z"
+            op = "nz"
+        when "nz"
+            op = "z"
+        when "gt"
+            op = "lteq"
+        when "gteq"
+            op = "lt"
+        when "lt"
+            op = "gteq"
+        when "lteq"
+            op = "gt"
+        when "a"
+            op = "beq"
+        when "b"
+            op = "aeq"
+        when "aeq"
+            op = "b"
+        when "beq"
+            op = "a"
+        else
+            raise "Can't negate #{opcode} branch."
+        end
+        noBranch = LocalLabel.unique("nobranch")
+        noBranchRef = LocalLabelReference.new(codeOrigin, noBranch)
+        toRef = operands[-1]
+        list << Instruction.new(codeOrigin, "#{$1}#{$3}#{op}", operands[0..-2].push(noBranchRef), annotation)
+        list << Instruction.new(codeOrigin, "la", [toRef, MIPS_CALL_REG])
+        list << Instruction.new(codeOrigin, "jmp", [MIPS_CALL_REG])
+        list << noBranch
+    end
+end
+
+def mipsLowerFarBranchOps(list)
+    newList = []
+    list.each {
+        | node |
+        if node.is_a? Instruction
+            annotation = node.annotation
+            case node.opcode
+            when /^b(add|sub|or|mul|t)?([ipb])/
+                if node.operands[-1].is_a? LabelReference
+                    node.mipsNegateCondition(newList)
+                    next
+                end
+            end
+        end
+        newList << node
+    }
+    newList
+end
+
 #
 # Lower 'and' masked branches
 #
@@ -445,6 +508,30 @@ end
 # Specialization of lowering of misplaced addresses.
 #
 
+class LocalLabelReference
+    def register?
+        false
+    end
+end
+
+def mipsAsRegister(preList, postList, operand, needRestore)
+    tmp = MIPS_CALL_REG
+    if operand.address?
+        preList << Instruction.new(operand.codeOrigin, "loadp", [operand, MIPS_CALL_REG])
+    elsif operand.is_a? LabelReference
+        preList << Instruction.new(operand.codeOrigin, "la", [operand, MIPS_CALL_REG])
+    elsif operand.register? and operand != MIPS_CALL_REG
+        preList << Instruction.new(operand.codeOrigin, "move", [operand, MIPS_CALL_REG])
+    else
+        needRestore = false
+        tmp = operand
+    end
+    if needRestore
+        postList << Instruction.new(operand.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
+    end
+    tmp
+end
+
 def mipsLowerMisplacedAddresses(list)
     newList = []
     list.each {
@@ -454,33 +541,13 @@ def mipsLowerMisplacedAddresses(list)
             annotation = node.annotation
             case node.opcode
             when "jmp"
-                if node.operands[0].address?
-                    newList << Instruction.new(node.operands[0].codeOrigin, "loadi", [node.operands[0], MIPS_JUMP_REG])
-                    newList << Instruction.new(node.codeOrigin, node.opcode, [MIPS_JUMP_REG])
-                else
-                    newList << Instruction.new(node.codeOrigin,
-                                               node.opcode,
-                                               [riscAsRegister(newList, postInstructions, node.operands[0], "p", false)])
-                end
+                newList << Instruction.new(node.codeOrigin,
+                                           node.opcode,
+                                           [mipsAsRegister(newList, [], node.operands[0], false)])
             when "call"
-                restoreGP = false;
-                tmp = MIPS_CALL_REG
-                if node.operands[0].address?
-                    newList << Instruction.new(node.operands[0].codeOrigin, "loadp", [node.operands[0], MIPS_CALL_REG])
-                    restoreGP = true;
-                elsif node.operands[0].is_a? LabelReference
-                    tmp = node.operands[0]
-                    restoreGP = true;
-                elsif node.operands[0].register?
-                    newList << Instruction.new(node.operands[0].codeOrigin, "move", [node.operands[0], MIPS_CALL_REG])
-                    restoreGP = true;
-                else
-                    tmp = node.operands[0]
-                end
-                newList << Instruction.new(node.codeOrigin, node.opcode, [tmp])
-                if restoreGP
-                    newList << Instruction.new(node.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
-                end
+                newList << Instruction.new(node.codeOrigin,
+                                           node.opcode,
+                                           [mipsAsRegister(newList, postInstructions, node.operands[0], true)])
             when "slt", "sltu"
                 newList << Instruction.new(node.codeOrigin,
                                            node.opcode,
@@ -565,7 +632,7 @@ class Address
 end
 
 #
-# Add PIC compatible header code to prologue/entry rutins.
+# Add PIC compatible header code to all the LLInt rutins.
 #
 
 def mipsAddPICCode(list)
@@ -574,13 +641,7 @@ def mipsAddPICCode(list)
         | node |
         myList << node
         if node.is_a? Label
-            if /_prologue$/.match(node.name) || /^_llint_function_/.match(node.name)
-                # Functions called from trampoline/JIT codes.
-                myList << Instruction.new(node.codeOrigin, "pichdr", [])
-            elsif /_llint_op_catch/.match(node.name)
-                # Exception cactcher entry point function.
-                myList << Instruction.new(node.codeOrigin, "pichdrra", [])
-            end
+            myList << Instruction.new(node.codeOrigin, "pichdr", [])
         end
     }
     myList
@@ -606,6 +667,7 @@ class Sequence
         }
 
         result = mipsAddPICCode(result)
+        result = mipsLowerFarBranchOps(result)
         result = mipsLowerSimpleBranchOps(result)
         result = riscLowerSimpleBranchOps(result)
         result = riscLowerHardBranchOps(result)
@@ -714,6 +776,16 @@ def emitMIPSDoubleBranch(branchOpcode, neg, operands)
     end
 end
 
+def emitMIPSJumpOrCall(opcode, operand)
+    if operand.label?
+        raise "Direct call/jump to a not local label." unless operand.is_a? LocalLabelReference
+        $asm.puts "#{opcode} #{operand.asmLabel}"
+    else
+        raise "Invalid call/jump register." unless operand == MIPS_CALL_REG
+        $asm.puts "#{opcode}r #{MIPS_CALL_REG.mipsOperand}"
+    end
+end
+
 class Instruction
     def lowerMIPS
         $asm.comment codeOriginString
@@ -784,6 +856,8 @@ class Instruction
             $asm.puts "ldc1 #{mipsFlippedOperands(operands)}"
         when "stored"
             $asm.puts "sdc1 #{mipsOperands(operands)}"
+        when "la"
+            $asm.puts "la #{operands[1].mipsOperand}, #{operands[0].asmLabel}"
         when "addd"
             emitMIPS("add.d", operands)
         when "divd"
@@ -850,20 +924,6 @@ class Instruction
                 $asm.puts "addiu $sp, $sp, -4"
                 $asm.puts "sw #{op.mipsOperand}, 0($sp)"
             }
-        when "popCalleeSaves"
-            $asm.puts "lw $16, 0($sp)"
-            $asm.puts "lw $17, 4($sp)"
-            $asm.puts "lw $18, 8($sp)"
-            $asm.puts "lw $19, 12($sp)"
-            $asm.puts "lw $20, 16($sp)"
-            $asm.puts "addiu $sp, $sp, 20"
-        when "pushCalleeSaves"
-            $asm.puts "addiu $sp, $sp, -20"
-            $asm.puts "sw $20, 16($sp)"
-            $asm.puts "sw $19, 12($sp)"
-            $asm.puts "sw $18, 8($sp)"
-            $asm.puts "sw $17, 4($sp)"
-            $asm.puts "sw $16, 0($sp)"
         when "move", "sxi2p", "zxi2p"
             if operands[0].is_a? Immediate
                 mipsMoveImmediate(operands[0].value, operands[1])
@@ -885,17 +945,9 @@ class Instruction
         when "bilteq", "bplteq", "bblteq"
             $asm.puts "ble #{mipsOperands(operands[0..1])}, #{operands[2].asmLabel}"
         when "jmp"
-            if operands[0].label?
-                $asm.puts "j #{operands[0].asmLabel}"
-            else
-                $asm.puts "jr #{operands[0].mipsOperand}"
-            end
+            emitMIPSJumpOrCall("j", operands[0])
         when "call"
-            if operands[0].label?
-                $asm.puts "jal #{operands[0].asmLabel}"
-            else
-                $asm.puts "jalr #{operands[0].mipsOperand}"
-            end
+            emitMIPSJumpOrCall("jal", operands[0])
         when "break"
             $asm.puts "break"
         when "ret"
@@ -954,11 +1006,8 @@ class Instruction
         when "sltu", "sltub"
             $asm.puts "sltu #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
         when "pichdr"
-            $asm.putStr("OFFLINE_ASM_CPLOAD($25)")
-            $asm.puts "move $s4, $gp"
-        when "pichdrra"
-            $asm.putStr("OFFLINE_ASM_CPLOAD($31)")
-            $asm.puts "move $s4, $gp"
+            $asm.putStr("OFFLINE_ASM_CPLOAD(#{MIPS_CALL_REG.mipsOperand})")
+            $asm.puts "move #{MIPS_GPSAVE_REG.mipsOperand}, #{MIPS_GP_REG.mipsOperand}"
         when "memfence"
             $asm.puts "sync"
         else
index 04f70a4bd0ac0a66cce1591d1c499f56191af61e..a122a68c4c3ad8e6ae20e8819d53ceb2120f45a8 100644 (file)
@@ -165,6 +165,8 @@ def lex(str, fileName)
             result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
         when /\A[:,\(\)\[\]=\+\-~\|&^*]/
             result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
+        when /\A".*"/
+            result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
         else
             raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
         end
@@ -212,6 +214,10 @@ def isInteger(token)
     token =~ /\A[0-9]/
 end
 
+def isString(token)
+    token =~ /\A".*"/
+end
+
 #
 # The parser. Takes an array of tokens and returns an AST. Methods
 # other than parse(tokens) are not for public consumption.
@@ -397,6 +403,10 @@ class Parser
             result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
             @idx += 1
             result
+        elsif isString @tokens[@idx]
+            result = StringLiteral.new(@tokens[@idx].codeOrigin, @tokens[@idx].string)
+            @idx += 1
+            result
         elsif isIdentifier @tokens[@idx]
             codeOrigin, names = parseColonColon
             if names.size > 1
@@ -438,7 +448,7 @@ class Parser
     end
     
     def couldBeExpression
-        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
     end
     
     def parseExpressionAdd
index b35d3d06082a617a7b1064bee909c0fa7c388c44..eec092584fecf441619bd0f87de9ffa08e797d05 100644 (file)
@@ -54,7 +54,28 @@ def computeSettingsCombinations(ast)
         settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
     end
     
-    settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + BACKENDS).uniq)
+    nonBackendSettings = ast.filter(Setting).uniq.collect{ |v| v.name }
+    nonBackendSettings.delete_if {
+        | setting |
+        isBackend? setting
+    }
+    
+    allBackendsFalse = {}
+    BACKENDS.each {
+        | backend |
+        allBackendsFalse[backend] = false
+    }
+    
+    # This will create entries for invalid backends. That's fine. It's necessary
+    # because it ensures that generate_offsets_extractor (which knows about valid
+    # backends) has settings indices that are compatible with what asm will see
+    # (asm doesn't know about valid backends).
+    BACKENDS.each {
+        | backend |
+        map = allBackendsFalse.clone
+        map[backend] = true
+        settingsCombinator(settingsCombinations, map, nonBackendSettings)
+    }
     
     settingsCombinations
 end
@@ -73,15 +94,13 @@ def forSettings(concreteSettings, ast)
     selectedBackend = nil
     BACKENDS.each {
         | backend |
-        isSupported = concreteSettings[backend]
-        raise unless isSupported != nil
-        numClaimedBackends += if isSupported then 1 else 0 end
-        if isSupported
+        if concreteSettings[backend]
+            raise if selectedBackend
             selectedBackend = backend
         end
     }
     
-    return if numClaimedBackends > 1
+    return unless isValidBackend? selectedBackend
     
     # Resolve the AST down to a low-level form (no macros or conditionals).
     lowLevelAST = ast.resolveSettings(concreteSettings)
index 54c05562f1475a3e67ab79bd8546da8410b9754e..0241f38d89ebdb28e3f40ebd797933f146c77064 100644 (file)
@@ -1091,18 +1091,6 @@ class Instruction
             else
                 $asm.puts "mov.l #{sh4Operands(operands)}, @-r15"
             end
-        when "popCalleeSaves"
-            $asm.puts "mov.l @r15+, r8"
-            $asm.puts "mov.l @r15+, r9"
-            $asm.puts "mov.l @r15+, r10"
-            $asm.puts "mov.l @r15+, r11"
-            $asm.puts "mov.l @r15+, r13"
-        when "pushCalleeSaves"
-            $asm.puts "mov.l r13, @-r15"
-            $asm.puts "mov.l r11, @-r15"
-            $asm.puts "mov.l r10, @-r15"
-            $asm.puts "mov.l r9, @-r15"
-            $asm.puts "mov.l r8, @-r15"
         when "break"
             # This special opcode always generates an illegal instruction exception.
             $asm.puts ".word 0xfffd"
index c77bf63a231b299db063c1887b4d5eda50073a9d..84dd0413bc51dd6f95f1f45f9658157699fa772b 100644 (file)
@@ -423,6 +423,11 @@ class Immediate
     end
 end
 
+class StringLiteral
+    def validate
+    end
+end
+
 class RegisterID
     def validate
     end
index 3be1d267c6c1b594d629e82885bcb35f63bd5a33..8830e3d41d2ab09432a2a47d6935c08c4f8cf3a1 100644 (file)
@@ -55,7 +55,7 @@ def useX87
 end
 
 def isWindows
-    RUBY_PLATFORM =~ /cygwin/i
+    ENV['OS'] == 'Windows_NT'
 end
 
 def isGCC
@@ -1146,38 +1146,6 @@ class Instruction
                 | op |
                 $asm.puts "push #{op.x86Operand(:ptr)}"
             }
-        when "popCalleeSaves"
-            if isX64
-                if isMSVC
-                    $asm.puts "pop " + register("rsi")
-                    $asm.puts "pop " + register("rdi")
-                end
-                $asm.puts "pop " + register("rbx")
-                $asm.puts "pop " + register("r15")
-                $asm.puts "pop " + register("r14")
-                $asm.puts "pop " + register("r13")
-                $asm.puts "pop " + register("r12")
-            else
-                $asm.puts "pop " + register("ebx")
-                $asm.puts "pop " + register("edi")
-                $asm.puts "pop " + register("esi")
-            end
-        when "pushCalleeSaves"
-            if isX64
-                $asm.puts "push " + register("r12")
-                $asm.puts "push " + register("r13")
-                $asm.puts "push " + register("r14")
-                $asm.puts "push " + register("r15")
-                $asm.puts "push " + register("rbx")
-                if isMSVC
-                    $asm.puts "push " + register("rdi")
-                    $asm.puts "push " + register("rsi")
-                end
-            else
-                $asm.puts "push " + register("esi")
-                $asm.puts "push " + register("edi")
-                $asm.puts "push " + register("ebx")
-            end
         when "move"
             handleMove
         when "sxi2q"
index 6e099ba00fd22558ec47772777882d6d2ace17b0..0fb0f29a9b0179f356e09d1ad56c2702627410fd 100644 (file)
@@ -27,6 +27,7 @@
 #define ASTBuilder_h
 
 #include "BuiltinNames.h"
+#include "BytecodeIntrinsicRegistry.h"
 #include "NodeConstructors.h"
 #include "SyntaxChecker.h"
 #include <utility>
@@ -76,10 +77,10 @@ class ASTBuilder {
         Operator m_op;
     };
 public:
-    ASTBuilder(VM* vm, SourceCode* sourceCode)
+    ASTBuilder(VM* vm, ParserArena& parserArena, SourceCode* sourceCode)
         : m_vm(vm)
+        , m_parserArena(parserArena)
         , m_sourceCode(sourceCode)
-        , m_scope(vm)
         , m_evalCount(0)
     {
     }
@@ -102,14 +103,23 @@ public:
     typedef PropertyListNode* PropertyList;
     typedef ElementNode* ElementList;
     typedef ArgumentListNode* ArgumentsList;
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    typedef TemplateExpressionListNode* TemplateExpressionList;
+    typedef TemplateStringNode* TemplateString;
+    typedef TemplateStringListNode* TemplateStringList;
+    typedef TemplateLiteralNode* TemplateLiteral;
+#endif
     typedef ParameterNode* FormalParameterList;
     typedef FunctionBodyNode* FunctionBody;
+#if ENABLE(ES6_CLASS_SYNTAX)
+    typedef ClassExprNode* ClassExpression;
+#endif
     typedef StatementNode* Statement;
     typedef ClauseListNode* ClauseList;
     typedef CaseClauseNode* Clause;
     typedef ConstDeclNode* ConstDeclList;
     typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
-    typedef RefPtr<DeconstructionPatternNode> DeconstructionPattern;
+    typedef RefPtr<DestructuringPatternNode> DestructuringPattern;
     typedef RefPtr<ArrayPatternNode> ArrayPattern;
     typedef RefPtr<ObjectPatternNode> ObjectPattern;
     typedef RefPtr<BindingNode> BindingPattern;
@@ -122,17 +132,13 @@ public:
     ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
     ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd);
 
-    JSC::SourceElements* createSourceElements() { return new (m_vm) JSC::SourceElements(); }
+    JSC::SourceElements* createSourceElements() { return new (m_parserArena) JSC::SourceElements(); }
 
-    ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
-    ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
+    DeclarationStacks::VarStack& varDeclarations() { return m_scope.m_varDeclarations; }
+    DeclarationStacks::FunctionStack& funcDeclarations() { return m_scope.m_funcDeclarations; }
     int features() const { return m_scope.m_features; }
     int numConstants() const { return m_scope.m_numConstants; }
 
-    void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
-
-    CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_vm) CommaNode(location, lhs, rhs); }
-
     ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
     ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
     ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
@@ -157,92 +163,145 @@ public:
         if (expr->isNumber())
             return createBoolean(location, isZeroOrUnordered(static_cast<NumberNode*>(expr)->value()));
 
-        return new (m_vm) LogicalNotNode(location, expr);
+        return new (m_parserArena) LogicalNotNode(location, expr);
     }
-    ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_vm) UnaryPlusNode(location, expr); }
+    ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) UnaryPlusNode(location, expr); }
     ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
     {
         incConstants();
-        return new (m_vm) VoidNode(location, expr);
+        return new (m_parserArena) VoidNode(location, expr);
     }
-    ExpressionNode* thisExpr(const JSTokenLocation& location)
+    ExpressionNode* thisExpr(const JSTokenLocation& location, ThisTDZMode thisTDZMode)
     {
         usesThis();
-        return new (m_vm) ThisNode(location);
+        return new (m_parserArena) ThisNode(location, thisTDZMode);
+    }
+    ExpressionNode* superExpr(const JSTokenLocation& location)
+    {
+        return new (m_parserArena) SuperNode(location);
     }
     ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start)
     {
         if (m_vm->propertyNames->arguments == *ident)
             usesArguments();
-        return new (m_vm) ResolveNode(location, *ident, start);
+        return new (m_parserArena) ResolveNode(location, *ident, start);
     }
-    ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_vm) ObjectLiteralNode(location); }
-    ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_vm) ObjectLiteralNode(location, properties); }
+    ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_parserArena) ObjectLiteralNode(location); }
+    ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_parserArena) ObjectLiteralNode(location, properties); }
 
     ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
     {
         if (elisions)
             incConstants();
-        return new (m_vm) ArrayNode(location, elisions);
+        return new (m_parserArena) ArrayNode(location, elisions);
     }
 
-    ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_vm) ArrayNode(location, elems); }
+    ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_parserArena) ArrayNode(location, elems); }
     ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
     {
         if (elisions)
             incConstants();
-        return new (m_vm) ArrayNode(location, elisions, elems);
+        return new (m_parserArena) ArrayNode(location, elisions, elems);
     }
-    ExpressionNode* createNumberExpr(const JSTokenLocation& location, double d)
+    ExpressionNode* createDoubleExpr(const JSTokenLocation& location, double d)
     {
         incConstants();
-        return new (m_vm) NumberNode(location, d);
+        return new (m_parserArena) DoubleNode(location, d);
+    }
+    ExpressionNode* createIntegerExpr(const JSTokenLocation& location, double d)
+    {
+        incConstants();
+        return new (m_parserArena) IntegerNode(location, d);
     }
 
     ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
     {
         incConstants();
-        return new (m_vm) StringNode(location, *string);
+        return new (m_parserArena) StringNode(location, *string);
     }
 
     ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
     {
         incConstants();
-        return new (m_vm) BooleanNode(location, b);
+        return new (m_parserArena) BooleanNode(location, b);
     }
 
     ExpressionNode* createNull(const JSTokenLocation& location)
     {
         incConstants();
-        return new (m_vm) NullNode(location);
+        return new (m_parserArena) NullNode(location);
     }
 
     ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
-        BracketAccessorNode* node = new (m_vm) BracketAccessorNode(location, base, property, propertyHasAssignments);
+        BracketAccessorNode* node = new (m_parserArena) BracketAccessorNode(location, base, property, propertyHasAssignments);
         setExceptionLocation(node, start, divot, end);
         return node;
     }
 
     ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
-        DotAccessorNode* node = new (m_vm) DotAccessorNode(location, base, *property);
+        DotAccessorNode* node = new (m_parserArena) DotAccessorNode(location, base, *property);
         setExceptionLocation(node, start, divot, end);
         return node;
     }
 
     ExpressionNode* createSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
-        auto node = new (m_vm) SpreadExpressionNode(location, expression);
+        auto node = new (m_parserArena) SpreadExpressionNode(location, expression);
+        setExceptionLocation(node, start, divot, end);
+        return node;
+    }
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    TemplateStringNode* createTemplateString(const JSTokenLocation& location, const Identifier& cooked, const Identifier& raw)
+    {
+        return new (m_parserArena) TemplateStringNode(location, cooked, raw);
+    }
+
+    TemplateStringListNode* createTemplateStringList(TemplateStringNode* templateString)
+    {
+        return new (m_parserArena) TemplateStringListNode(templateString);
+    }
+
+    TemplateStringListNode* createTemplateStringList(TemplateStringListNode* templateStringList, TemplateStringNode* templateString)
+    {
+        return new (m_parserArena) TemplateStringListNode(templateStringList, templateString);
+    }
+
+    TemplateExpressionListNode* createTemplateExpressionList(ExpressionNode* expression)
+    {
+        return new (m_parserArena) TemplateExpressionListNode(expression);
+    }
+
+    TemplateExpressionListNode* createTemplateExpressionList(TemplateExpressionListNode* templateExpressionListNode, ExpressionNode* expression)
+    {
+        return new (m_parserArena) TemplateExpressionListNode(templateExpressionListNode, expression);
+    }
+
+    TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList)
+    {
+        return new (m_parserArena) TemplateLiteralNode(location, templateStringList);
+    }
+
+    TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList, TemplateExpressionListNode* templateExpressionList)
+    {
+        return new (m_parserArena) TemplateLiteralNode(location, templateStringList, templateExpressionList);
+    }
+
+    ExpressionNode* createTaggedTemplate(const JSTokenLocation& location, ExpressionNode* base, TemplateLiteralNode* templateLiteral, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
+    {
+        auto node = new (m_parserArena) TaggedTemplateNode(location, base, templateLiteral);
         setExceptionLocation(node, start, divot, end);
         return node;
     }
+#endif
 
     ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start)
     {
         if (Yarr::checkSyntax(pattern.string()))
             return 0;
-        RegExpNode* node = new (m_vm) RegExpNode(location, pattern, flags);
+        RegExpNode* node = new (m_parserArena) RegExpNode(location, pattern, flags);
         int size = pattern.length() + 2; // + 2 for the two /'s
         JSTextPosition end = start + size;
         setExceptionLocation(node, start, end, end);
@@ -251,190 +310,225 @@ public:
 
     ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
-        NewExprNode* node = new (m_vm) NewExprNode(location, expr, arguments);
+        NewExprNode* node = new (m_parserArena) NewExprNode(location, expr, arguments);
         setExceptionLocation(node, start, divot, end);
         return node;
     }
 
     ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
     {
-        NewExprNode* node = new (m_vm) NewExprNode(location, expr);
+        NewExprNode* node = new (m_parserArena) NewExprNode(location, expr);
         setExceptionLocation(node, start, end, end);
         return node;
     }
 
     ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
     {
-        return new (m_vm) ConditionalNode(location, condition, lhs, rhs);
+        return new (m_parserArena) ConditionalNode(location, condition, lhs, rhs);
     }
 
     ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
         if (rhs->isFuncExprNode())
             static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
-        AssignResolveNode* node = new (m_vm) AssignResolveNode(location, ident, rhs);
+        AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, ident, rhs);
         setExceptionLocation(node, start, divot, end);
         return node;
     }
 
-    ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned startColumn)
+#if ENABLE(ES6_CLASS_SYNTAX)
+    ClassExprNode* createClassExpr(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructor,
+        ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
     {
-        FuncExprNode* result = new (m_vm) FuncExprNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, startColumn), parameters);
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
+        return new (m_parserArena) ClassExprNode(location, name, constructor, parentClass, instanceMethods, staticMethods);
+    }
+#endif
+
+    ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
+    {
+        FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body,
+            m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
         return result;
     }
 
-    FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
+    FunctionBodyNode* createFunctionBody(
+        const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, 
+        unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
+        int functionNameStart, int parametersStart, bool inStrictContext, 
+        ConstructorKind constructorKind)
     {
-        return FunctionBodyNode::create(m_vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
+        return new (m_parserArena) FunctionBodyNode(
+            m_parserArena, startLocation, endLocation, startColumn, endColumn, 
+            functionKeywordStart, functionNameStart, parametersStart, 
+            inStrictContext, constructorKind);
     }
 
-    void setFunctionNameStart(FunctionBodyNode* body, int functionNameStart)
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
     {
-        body->setFunctionNameStart(functionNameStart);
+        SourceCode source = info.functionBodyType == ArrowFunctionBodyExpression
+            ? m_sourceCode->subArrowExpression(info.arrowFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn)
+            : m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn);
+
+        FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body, source, info.parameters);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        return result;
     }
-    
-    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
+#endif
+
+    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
+        const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding)
     {
         ASSERT(name);
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        body->setInferredName(*name);
-        return new (m_vm) PropertyNode(m_vm, *name, new (m_vm) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        info.body->setInferredName(*name);
+        SourceCode source = m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn);
+        FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, info.body, source, info.parameters);
+        return new (m_parserArena) PropertyNode(*name, funcExpr, type, PropertyNode::Unknown, superBinding);
     }
     
-    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM*, const JSTokenLocation& location, PropertyNode::Type type, bool, double name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
+    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool,
+        double name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding)
     {
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        return new (m_vm) PropertyNode(m_vm, name, new (m_vm) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name);
+        SourceCode source = m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn);
+        FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, info.body, source, info.parameters);
+        return new (m_parserArena) PropertyNode(ident, funcExpr, type, PropertyNode::Unknown, superBinding);
     }
 
-    ArgumentsNode* createArguments() { return new (m_vm) ArgumentsNode(); }
-    ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_vm) ArgumentsNode(args); }
-    ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_vm) ArgumentListNode(location, arg); }
-    ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_vm) ArgumentListNode(location, args, arg); }
+    ArgumentsNode* createArguments() { return new (m_parserArena) ArgumentsNode(); }
+    ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_parserArena) ArgumentsNode(args); }
+    ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, arg); }
+    ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, args, arg); }
 
-    PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, bool)
+    PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding = SuperBinding::NotNeeded)
     {
         if (node->isFuncExprNode())
             static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
-        return new (m_vm) PropertyNode(m_vm, *propertyName, node, type);
+        return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding);
     }
-    PropertyNode* createProperty(VM*, double propertyName, ExpressionNode* node, PropertyNode::Type type, bool) { return new (m_vm) PropertyNode(m_vm, propertyName, node, type); }
-    PropertyNode* createProperty(VM*, ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, bool) { return new (m_vm) PropertyNode(m_vm, propertyName, node, type); }
-    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_vm) PropertyListNode(location, property); }
-    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_vm) PropertyListNode(location, property, tail); }
-
-    ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_vm) ElementNode(elisions, expr); }
-    ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_vm) ElementNode(elems, elisions, expr); }
+    PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool)
+    {
+        return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType);
+    }
+    PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool) { return new (m_parserArena) PropertyNode(propertyName, node, type, putType); }
+    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_parserArena) PropertyListNode(location, property); }
+    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_parserArena) PropertyListNode(location, property, tail); }
 
-    ParameterNode* createFormalParameterList(DeconstructionPattern pattern) { return new (m_vm) ParameterNode(pattern); }
-    ParameterNode* createFormalParameterList(ParameterNode* list, DeconstructionPattern pattern) { return new (m_vm) ParameterNode(list, pattern); }
+    ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elisions, expr); }
+    ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elems, elisions, expr); }
 
-    CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_vm) CaseClauseNode(expr, statements); }
-    ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_vm) ClauseListNode(clause); }
-    ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_vm) ClauseListNode(tail, clause); }
+    ParameterNode* createFormalParameterList(DestructuringPattern pattern) { return new (m_parserArena) ParameterNode(pattern); }
+    ParameterNode* createFormalParameterList(ParameterNode* list, DestructuringPattern pattern) { return new (m_parserArena) ParameterNode(list, pattern); }
 
-    void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
+    CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_parserArena) CaseClauseNode(expr, statements); }
+    ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(clause); }
+    ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(tail, clause); }
 
-    StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
+    StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
     {
-        FuncDeclNode* decl = new (m_vm) FuncDeclNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), parameters);
-        if (*name == m_vm->propertyNames->arguments)
+        FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *info.name, info.body,
+            m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
+        if (*info.name == m_vm->propertyNames->arguments)
             usesArguments();
-        m_scope.m_funcDeclarations->data.append(decl->body());
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
+        m_scope.m_funcDeclarations.append(decl->body());
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        return decl;
+    }
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+    StatementNode* createClassDeclStatement(const JSTokenLocation& location, ClassExprNode* classExpression,
+        const JSTextPosition& classStart, const JSTextPosition& classEnd, unsigned startLine, unsigned endLine)
+    {
+        // FIXME: Use "let" declaration.
+        ExpressionNode* assign = createAssignResolve(location, classExpression->name(), classExpression, classStart, classStart + 1, classEnd);
+        ClassDeclNode* decl = new (m_parserArena) ClassDeclNode(location, assign);
+        decl->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return decl;
     }
+#endif
 
     StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
     {
-        BlockNode* block = new (m_vm) BlockNode(location, elements);
+        BlockNode* block = new (m_parserArena) BlockNode(location, elements);
         block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return block;
     }
 
     StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end)
     {
-        ExprStatementNode* result = new (m_vm) ExprStatementNode(location, expr);
+        ExprStatementNode* result = new (m_parserArena) ExprStatementNode(location, expr);
         result->setLoc(start.line, end, start.offset, start.lineStartOffset);
         return result;
     }
 
     StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
     {
-        IfElseNode* result = new (m_vm) IfElseNode(location, condition, trueBlock, falseBlock);
+        IfElseNode* result = new (m_parserArena) IfElseNode(location, condition, trueBlock, falseBlock);
         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
     {
-        ForNode* result = new (m_vm) ForNode(location, initializer, condition, iter, statements);
+        ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements);
         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
     {
-        ForInNode* result = new (m_vm) ForInNode(location, lhs, iter, statements);
+        ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements);
         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
         setExceptionLocation(result, eStart, eDivot, eEnd);
         return result;
     }
     
-    StatementNode* createForInLoop(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
+    StatementNode* createForInLoop(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
     {
-        ForInNode* result = new (m_vm) ForInNode(m_vm, location, pattern.get(), iter, statements);
-        result->setLoc(start, end, location.startOffset, location.lineStartOffset);
-        setExceptionLocation(result, eStart, eDivot, eEnd);
-        return result;
+        auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
+        return createForInLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
     }
     
     StatementNode* createForOfLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
     {
-        ForOfNode* result = new (m_vm) ForOfNode(location, lhs, iter, statements);
+        ForOfNode* result = new (m_parserArena) ForOfNode(location, lhs, iter, statements);
         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
         setExceptionLocation(result, eStart, eDivot, eEnd);
         return result;
     }
     
-    StatementNode* createForOfLoop(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
+    StatementNode* createForOfLoop(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
     {
-        ForOfNode* result = new (m_vm) ForOfNode(m_vm, location, pattern.get(), iter, statements);
-        result->setLoc(start, end, location.startOffset, location.lineStartOffset);
-        setExceptionLocation(result, eStart, eDivot, eEnd);
-        return result;
+        auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
+        return createForOfLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
     }
 
-    bool isBindingNode(const DeconstructionPattern& pattern)
+    bool isBindingNode(const DestructuringPattern& pattern)
     {
         return pattern->isBindingNode();
     }
 
-    StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_vm) EmptyStatementNode(location); }
+    StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_parserArena) EmptyStatementNode(location); }
 
     StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
     {
         StatementNode* result;
-        if (!expr)
-            result = new (m_vm) EmptyStatementNode(location);
-        else
-            result = new (m_vm) VarStatementNode(location, expr);
+        result = new (m_parserArena) VarStatementNode(location, expr);
         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
         return result;
     }
 
-    StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
+    ExpressionNode* createEmptyVarExpression(const JSTokenLocation& location, const Identifier& identifier)
     {
-        ReturnNode* result = new (m_vm) ReturnNode(location, expression);
-        setExceptionLocation(result, start, end, end);
-        result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
-        return result;
+        return new (m_parserArena) EmptyVarExpression(location, identifier);
     }
 
-    StatementNode* createBreakStatement(const JSTokenLocation& location, const JSTextPosition& start, const JSTextPosition& end)
+    StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
     {
-        BreakNode* result = new (m_vm) BreakNode(m_vm, location);
+        ReturnNode* result = new (m_parserArena) ReturnNode(location, expression);
         setExceptionLocation(result, start, end, end);
         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
         return result;
@@ -442,15 +536,7 @@ public:
 
     StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
     {
-        BreakNode* result = new (m_vm) BreakNode(location, *ident);
-        setExceptionLocation(result, start, end, end);
-        result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
-        return result;
-    }
-
-    StatementNode* createContinueStatement(const JSTokenLocation& location, const JSTextPosition& start, const JSTextPosition& end)
-    {
-        ContinueNode* result = new (m_vm) ContinueNode(m_vm, location);
+        BreakNode* result = new (m_parserArena) BreakNode(location, *ident);
         setExceptionLocation(result, start, end, end);
         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
         return result;
@@ -458,7 +544,7 @@ public:
 
     StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
     {
-        ContinueNode* result = new (m_vm) ContinueNode(location, *ident);
+        ContinueNode* result = new (m_parserArena) ContinueNode(location, *ident);
         setExceptionLocation(result, start, end, end);
         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
         return result;
@@ -466,7 +552,7 @@ public:
 
     StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
     {
-        TryNode* result = new (m_vm) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
+        TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
         if (catchBlock)
             usesCatch();
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
@@ -475,29 +561,29 @@ public:
 
     StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
     {
-        CaseBlockNode* cases = new (m_vm) CaseBlockNode(firstClauses, defaultClause, secondClauses);
-        SwitchNode* result = new (m_vm) SwitchNode(location, expr, cases);
+        CaseBlockNode* cases = new (m_parserArena) CaseBlockNode(firstClauses, defaultClause, secondClauses);
+        SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
     {
-        WhileNode* result = new (m_vm) WhileNode(location, expr, statement);
+        WhileNode* result = new (m_parserArena) WhileNode(location, expr, statement);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
     {
-        DoWhileNode* result = new (m_vm) DoWhileNode(location, statement, expr);
+        DoWhileNode* result = new (m_parserArena) DoWhileNode(location, statement, expr);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end)
     {
-        LabelNode* result = new (m_vm) LabelNode(location, *ident, statement);
+        LabelNode* result = new (m_parserArena) LabelNode(location, *ident, statement);
         setExceptionLocation(result, start, end, end);
         return result;
     }
@@ -505,14 +591,14 @@ public:
     StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine)
     {
         usesWith();
-        WithNode* result = new (m_vm) WithNode(location, expr, statement, end, end - start);
+        WithNode* result = new (m_parserArena) WithNode(location, expr, statement, end, end - start);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }    
     
     StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
     {
-        ThrowNode* result = new (m_vm) ThrowNode(location, expr);
+        ThrowNode* result = new (m_parserArena) ThrowNode(location, expr);
         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
         setExceptionLocation(result, start, end, end);
         return result;
@@ -520,21 +606,21 @@ public:
     
     StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
     {
-        DebuggerStatementNode* result = new (m_vm) DebuggerStatementNode(location);
+        DebuggerStatementNode* result = new (m_parserArena) DebuggerStatementNode(location);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }
     
     StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
     {
-        ConstStatementNode* result = new (m_vm) ConstStatementNode(location, decls);
+        ConstStatementNode* result = new (m_parserArena) ConstStatementNode(location, decls);
         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
         return result;
     }
 
     ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
     {
-        ConstDeclNode* result = new (m_vm) ConstDeclNode(location, *name, initializer);
+        ConstDeclNode* result = new (m_parserArena) ConstDeclNode(location, *name, initializer);
         if (tail)
             tail->m_next = result;
         return result;
@@ -549,19 +635,21 @@ public:
     {
         if (m_vm->propertyNames->arguments == *ident)
             usesArguments();
-        ASSERT(ident->impl()->isAtomic());
-        m_scope.m_varDeclarations->data.append(std::make_pair(*ident, attrs));
+        ASSERT(ident->impl()->isAtomic() || ident->impl()->isSymbol());
+        m_scope.m_varDeclarations.append(std::make_pair(*ident, attrs));
     }
 
-    ExpressionNode* combineCommaNodes(const JSTokenLocation& location, ExpressionNode* list, ExpressionNode* init)
+    CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* node)
     {
-        if (!list)
-            return init;
-        if (list->isCommaNode()) {
-            static_cast<CommaNode*>(list)->append(init);
-            return list;
-        }
-        return new (m_vm) CommaNode(location, list, init);
+        return new (m_parserArena) CommaNode(location, node);
+    }
+
+    CommaNode* appendToCommaExpr(const JSTokenLocation& location, ExpressionNode*, ExpressionNode* tail, ExpressionNode* next)
+    {
+        ASSERT(tail->isCommaNode());
+        CommaNode* newTail = new (m_parserArena) CommaNode(location, next);
+        static_cast<CommaNode*>(tail)->setNext(newTail);
+        return newTail;
     }
 
     int evalCount() const { return m_evalCount; }
@@ -644,58 +732,86 @@ public:
         assignmentStackDepth--;
         return result;
     }
-    
-    const Identifier* getName(Property property) const { return property->name(); }
-    PropertyNode::Type getType(Property property) const { return property->type(); }
+
+    const Identifier* getName(const Property& property) const { return property->name(); }
+    PropertyNode::Type getType(const Property& property) const { return property->type(); }
 
     bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
 
-    ExpressionNode* createDeconstructingAssignment(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* initializer)
+    ExpressionNode* createDestructuringAssignment(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> pattern, ExpressionNode* initializer)
     {
-        return new (m_vm) DeconstructingAssignmentNode(location, pattern.get(), initializer);
+        return new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), initializer);
     }
     
     ArrayPattern createArrayPattern(const JSTokenLocation&)
     {
-        return ArrayPatternNode::create(m_vm);
+        return ArrayPatternNode::create();
     }
     
     void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
     {
-        node->appendIndex(location, 0);
+        node->appendIndex(ArrayPatternNode::BindingType::Elision, location, 0, nullptr);
+    }
+
+    void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern, ExpressionNode* defaultValue)
+    {
+        node->appendIndex(ArrayPatternNode::BindingType::Element, location, pattern.get(), defaultValue);
+    }
+
+    void appendArrayPatternRestEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern)
+    {
+        node->appendIndex(ArrayPatternNode::BindingType::RestElement, location, pattern.get(), nullptr);
     }
 
-    void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern)
+    void finishArrayPattern(ArrayPattern node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
     {
-        node->appendIndex(location, pattern.get());
+        setExceptionLocation(node.get(), divotStart, divot, divotEnd);
     }
     
     ObjectPattern createObjectPattern(const JSTokenLocation&)
     {
-        return ObjectPatternNode::create(m_vm);
+        return ObjectPatternNode::create();
     }
     
-    void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern)
+    void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue)
     {
-        node->appendEntry(location, identifier, wasString, pattern.get());
+        node->appendEntry(location, identifier, wasString, pattern.get(), defaultValue);
     }
     
     BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
     {
-        return BindingNode::create(m_vm, boundProperty, start, end);
+        return BindingNode::create(boundProperty, start, end);
+    }
+
+    void setEndOffset(Node* node, int offset)
+    {
+        node->setEndOffset(offset);
+    }
+
+    int endOffset(Node* node)
+    {
+        return node->endOffset();
+    }
+
+    void setStartOffset(CaseClauseNode* node, int offset)
+    {
+        node->setStartOffset(offset);
+    }
+
+    void setStartOffset(Node* node, int offset)
+    {
+        node->setStartOffset(offset);
     }
     
 private:
     struct Scope {
-        Scope(VM* vm)
-            : m_varDeclarations(new (vm) ParserArenaData<DeclarationStacks::VarStack>)
-            , m_funcDeclarations(new (vm) ParserArenaData<DeclarationStacks::FunctionStack>)
-            , m_features(0)
+        Scope()
+            : m_features(0)
             , m_numConstants(0)
         {
         }
-        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
-        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
+        DeclarationStacks::VarStack m_varDeclarations;
+        DeclarationStacks::FunctionStack m_funcDeclarations;
         int m_features;
         int m_numConstants;
     };
@@ -716,12 +832,29 @@ private:
         m_evalCount++;
         m_scope.m_features |= EvalFeature;
     }
-    ExpressionNode* createNumber(const JSTokenLocation& location, double d)
+    ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
     {
-        return new (m_vm) NumberNode(location, d);
+        return new (m_parserArena) IntegerNode(location, d);
     }
-    
+    ExpressionNode* createDoubleLikeNumber(const JSTokenLocation& location, double d)
+    {
+        return new (m_parserArena) DoubleNode(location, d);
+    }
+    ExpressionNode* createNumberFromBinaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNodeA, const NumberNode& originalNodeB)
+    {
+        if (originalNodeA.isIntegerNode() && originalNodeB.isIntegerNode())
+            return createIntegerLikeNumber(location, value);
+        return createDoubleLikeNumber(location, value);
+    }
+    ExpressionNode* createNumberFromUnaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNode)
+    {
+        if (originalNode.isIntegerNode())
+            return createIntegerLikeNumber(location, value);
+        return createDoubleLikeNumber(location, value);
+    }
+
     VM* m_vm;
+    ParserArena& m_parserArena;
     SourceCode* m_sourceCode;
     Scope m_scope;
     Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
@@ -735,44 +868,43 @@ ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, Expr
 {
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new (m_vm) TypeOfResolveNode(location, resolve->identifier());
+        return new (m_parserArena) TypeOfResolveNode(location, resolve->identifier());
     }
-    return new (m_vm) TypeOfValueNode(location, expr);
+    return new (m_parserArena) TypeOfValueNode(location, expr);
 }
 
 ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
 {
     if (!expr->isLocation())
-        return new (m_vm) DeleteValueNode(location, expr);
+        return new (m_parserArena) DeleteValueNode(location, expr);
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new (m_vm) DeleteResolveNode(location, resolve->identifier(), divot, start, end);
+        return new (m_parserArena) DeleteResolveNode(location, resolve->identifier(), divot, start, end);
     }
     if (expr->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
-        return new (m_vm) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end);
+        return new (m_parserArena) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end);
     }
     ASSERT(expr->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
-    return new (m_vm) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end);
+    return new (m_parserArena) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end);
 }
 
 ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
 {
     if (n->isNumber()) {
-        NumberNode* numberNode = static_cast<NumberNode*>(n);
-        numberNode->setValue(-numberNode->value());
-        return numberNode;
+        const NumberNode& numberNode = static_cast<const NumberNode&>(*n);
+        return createNumberFromUnaryOperation(location, -numberNode.value(), numberNode);
     }
 
-    return new (m_vm) NegateNode(location, n);
+    return new (m_parserArena) NegateNode(location, n);
 }
 
 ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
 {
     if (expr->isNumber())
-        return createNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
-    return new (m_vm) BitwiseNotNode(location, expr);
+        return createIntegerLikeNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
+    return new (m_parserArena) BitwiseNotNode(location, expr);
 }
 
 ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -780,16 +912,19 @@ ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, Expres
     expr1 = expr1->stripUnaryPlus();
     expr2 = expr2->stripUnaryPlus();
 
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createNumberFromBinaryOperation(location, numberExpr1.value() * numberExpr2.value(), numberExpr1, numberExpr2);
+    }
 
     if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
-        return new (m_vm) UnaryPlusNode(location, expr2);
+        return new (m_parserArena) UnaryPlusNode(location, expr2);
 
     if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
-        return new (m_vm) UnaryPlusNode(location, expr1);
+        return new (m_parserArena) UnaryPlusNode(location, expr1);
 
-    return new (m_vm) MultNode(location, expr1, expr2, rightHasAssignments);
+    return new (m_parserArena) MultNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -797,26 +932,39 @@ ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, Express
     expr1 = expr1->stripUnaryPlus();
     expr2 = expr2->stripUnaryPlus();
 
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
-    return new (m_vm) DivNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        double result = numberExpr1.value() / numberExpr2.value();
+        if (static_cast<int64_t>(result) == result)
+            return createNumberFromBinaryOperation(location, result, numberExpr1, numberExpr2);
+        return createDoubleLikeNumber(location, result);
+    }
+    return new (m_parserArena) DivNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
     expr1 = expr1->stripUnaryPlus();
     expr2 = expr2->stripUnaryPlus();
-    
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
-    return new (m_vm) ModNode(location, expr1, expr2, rightHasAssignments);
+
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, fmod(numberExpr1.value(), numberExpr2.value()));
+    }
+    return new (m_parserArena) ModNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
-    return new (m_vm) AddNode(location, expr1, expr2, rightHasAssignments);
+
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createNumberFromBinaryOperation(location, numberExpr1.value() + numberExpr2.value(), numberExpr1, numberExpr2);
+    }
+    return new (m_parserArena) AddNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -824,70 +972,93 @@ ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, Express
     expr1 = expr1->stripUnaryPlus();
     expr2 = expr2->stripUnaryPlus();
 
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
-    return new (m_vm) SubNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createNumberFromBinaryOperation(location, numberExpr1.value() - numberExpr2.value(), numberExpr1, numberExpr2);
+    }
+    return new (m_parserArena) SubNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
-    return new (m_vm) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) << (toUInt32(numberExpr2.value()) & 0x1f));
+    }
+    return new (m_parserArena) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
-    return new (m_vm) RightShiftNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
+    }
+    return new (m_parserArena) RightShiftNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
-    return new (m_vm) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toUInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
+    }
+    return new (m_parserArena) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
-    return new (m_vm) BitOrNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) | toInt32(numberExpr2.value()));
+    }
+    return new (m_parserArena) BitOrNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
-    return new (m_vm) BitAndNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) & toInt32(numberExpr2.value()));
+    }
+    return new (m_parserArena) BitAndNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
-    if (expr1->isNumber() && expr2->isNumber())
-        return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
-    return new (m_vm) BitXOrNode(location, expr1, expr2, rightHasAssignments);
+    if (expr1->isNumber() && expr2->isNumber()) {
+        const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
+        const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
+        return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) ^ toInt32(numberExpr2.value()));
+    }
+    return new (m_parserArena) BitXOrNode(location, expr1, expr2, rightHasAssignments);
 }
 
 ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
 {
     ASSERT(divot.offset >= divot.lineStartOffset);
     if (!func->isLocation())
-        return new (m_vm) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd);
+        return new (m_parserArena) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd);
     if (func->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(func);
         const Identifier& identifier = resolve->identifier();
         if (identifier == m_vm->propertyNames->eval) {
             usesEval();
-            return new (m_vm) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
+            return new (m_parserArena) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
         }
-        return new (m_vm) FunctionCallResolveNode(location, identifier, args, divot, divotStart, divotEnd);
+        if (BytecodeIntrinsicNode::EmitterType emitter = m_vm->propertyNames->bytecodeIntrinsicRegistry().lookup(identifier))
+            return new (m_parserArena) BytecodeIntrinsicNode(location, emitter, identifier, args, divot, divotStart, divotEnd);
+        return new (m_parserArena) FunctionCallResolveNode(location, identifier, args, divot, divotStart, divotEnd);
     }
     if (func->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
-        FunctionCallBracketNode* node = new (m_vm) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divotStart, divotEnd);
+        FunctionCallBracketNode* node = new (m_parserArena) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), bracket->subscriptHasAssignments(), args, divot, divotStart, divotEnd);
         node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
         return node;
     }
@@ -895,11 +1066,11 @@ ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
     FunctionCallDotNode* node;
     if (dot->identifier() == m_vm->propertyNames->builtinNames().callPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().callPrivateName())
-        node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
+        node = new (m_parserArena) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
     else if (dot->identifier() == m_vm->propertyNames->builtinNames().applyPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().applyPrivateName())
-        node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
+        node = new (m_parserArena) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
     else
-        node = new (m_vm) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
+        node = new (m_parserArena) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
     node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
     return node;
 }
@@ -908,10 +1079,10 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
 {
     switch (token) {
     case OR:
-        return new (m_vm) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
+        return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
 
     case AND:
-        return new (m_vm) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
+        return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
 
     case BITOR:
         return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
@@ -923,37 +1094,37 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
         return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case EQEQ:
-        return new (m_vm) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case NE:
-        return new (m_vm) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case STREQ:
-        return new (m_vm) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case STRNEQ:
-        return new (m_vm) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case LT:
-        return new (m_vm) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case GT:
-        return new (m_vm) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case LE:
-        return new (m_vm) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case GE:
-        return new (m_vm) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        return new (m_parserArena) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
 
     case INSTANCEOF: {
-        InstanceOfNode* node = new (m_vm) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        InstanceOfNode* node = new (m_parserArena) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
         return node;
     }
 
     case INTOKEN: {
-        InNode* node = new (m_vm) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+        InNode* node = new (m_parserArena) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
         return node;
     }
@@ -989,24 +1160,24 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
 ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
 {
     if (!loc->isLocation())
-        return new (m_vm) AssignErrorNode(location, divot, start, end);
+        return new (m_parserArena) AssignErrorNode(location, divot, start, end);
 
     if (loc->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
         if (op == OpEqual) {
             if (expr->isFuncExprNode())
                 static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
-            AssignResolveNode* node = new (m_vm) AssignResolveNode(location, resolve->identifier(), expr);
+            AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, resolve->identifier(), expr);
             setExceptionLocation(node, start, divot, end);
             return node;
         }
-        return new (m_vm) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
+        return new (m_parserArena) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
     }
     if (loc->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
         if (op == OpEqual)
-            return new (m_vm) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), start, end);
-        ReadModifyBracketNode* node = new (m_vm) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end);
+            return new (m_parserArena) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), start, end);
+        ReadModifyBracketNode* node = new (m_parserArena) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end);
         node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
         return node;
     }
@@ -1015,22 +1186,22 @@ ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, Expr
     if (op == OpEqual) {
         if (expr->isFuncExprNode())
             static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
-        return new (m_vm) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end);
+        return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end);
     }
 
-    ReadModifyDotNode* node = new (m_vm) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end);
+    ReadModifyDotNode* node = new (m_parserArena) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end);
     node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
     return node;
 }
 
 ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
 {
-    return new (m_vm) PrefixNode(location, expr, op, divot, start, end);
+    return new (m_parserArena) PrefixNode(location, expr, op, divot, start, end);
 }
 
 ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
 {
-    return new (m_vm) PostfixNode(location, expr, op, divot, start, end);
+    return new (m_parserArena) PostfixNode(location, expr, op, divot, start, end);
 }
 
 }
index 527eada607b5aaf3d3d0a70eb08bf9e55054c903..3c3f95f8706d1c708d71279f0c53dd9af235484d 100644 (file)
@@ -10,8 +10,10 @@ false                FALSETOKEN
 break          BREAK
 case           CASE
 catch          CATCH
+class          CLASSTOKEN
 const          CONSTTOKEN
 default                DEFAULT
+extends        EXTENDS
 finally                FINALLY
 for            FOR
 instanceof     INSTANCEOF
@@ -28,6 +30,7 @@ do            DO
 while          WHILE
 else           ELSE
 in             INTOKEN
+super          SUPER
 switch         SWITCH
 throw          THROW
 try            TRY
@@ -36,12 +39,9 @@ with         WITH
 debugger       DEBUGGER
 
 # Reserved for future use.
-class           RESERVED
 enum            RESERVED
 export          RESERVED
-extends         RESERVED
 import          RESERVED
-super           RESERVED
 
 # Reserved for future use in strict code.
 implements      RESERVED_IF_STRICT
index 9ca761012e9c5b072fa6fba334cd598edbd239a0..53aa9b05f09c00da3f1a69b02dc06666abdbef1a 100644 (file)
@@ -30,7 +30,6 @@
 #include "BuiltinNames.h"
 #include "JSGlobalObjectFunctions.h"
 #include "Identifier.h"
-#include "NodeInfo.h"
 #include "Nodes.h"
 #include "JSCInlines.h"
 #include <wtf/dtoa.h>
@@ -72,6 +71,7 @@ enum CharacterType {
     CharacterQuestion,
     CharacterTilde,
     CharacterQuote,
+    CharacterBackQuote,
     CharacterDot,
     CharacterSlash,
     CharacterBackSlash,
@@ -193,7 +193,11 @@ static const unsigned short typesOfLatin1Characters[256] = {
 /*  93 - ]                  */ CharacterCloseBracket,
 /*  94 - ^                  */ CharacterXor,
 /*  95 - _                  */ CharacterIdentifierStart,
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+/*  96 - `                  */ CharacterBackQuote,
+#else
 /*  96 - `                  */ CharacterInvalid,
+#endif
 /*  97 - a                  */ CharacterIdentifierStart,
 /*  98 - b                  */ CharacterIdentifierStart,
 /*  99 - c                  */ CharacterIdentifierStart,
@@ -489,13 +493,20 @@ static const LChar singleCharacterEscapeValuesForASCII[128] = {
 };
 
 template <typename T>
-Lexer<T>::Lexer(VM* vm, JSParserStrictness strictness)
+Lexer<T>::Lexer(VM* vm, JSParserBuiltinMode builtinMode)
     : m_isReparsing(false)
     , m_vm(vm)
-    , m_parsingBuiltinFunction(strictness == JSParseBuiltin)
+    , m_parsingBuiltinFunction(builtinMode == JSParserBuiltinMode::Builtin)
 {
 }
 
+static inline JSTokenType tokenTypeForIntegerLikeToken(double doubleValue)
+{
+    if ((doubleValue || !std::signbit(doubleValue)) && static_cast<int64_t>(doubleValue) == doubleValue)
+        return INTEGER;
+    return DOUBLE;
+}
+
 template <typename T>
 Lexer<T>::~Lexer()
 {
@@ -506,21 +517,21 @@ String Lexer<T>::invalidCharacterMessage() const
 {
     switch (m_current) {
     case 0:
-        return "Invalid character: '\\0'";
+        return ASCIILiteral("Invalid character: '\\0'");
     case 10:
-        return "Invalid character: '\\n'";
+        return ASCIILiteral("Invalid character: '\\n'");
     case 11:
-        return "Invalid character: '\\v'";
+        return ASCIILiteral("Invalid character: '\\v'");
     case 13:
-        return "Invalid character: '\\r'";
+        return ASCIILiteral("Invalid character: '\\r'");
     case 35:
-        return "Invalid character: '#'";
+        return ASCIILiteral("Invalid character: '#'");
     case 64:
-        return "Invalid character: '@'";
+        return ASCIILiteral("Invalid character: '@'");
     case 96:
-        return "Invalid character: '`'";
+        return ASCIILiteral("Invalid character: '`'");
     default:
-        return String::format("Invalid character '\\u%04u'", static_cast<unsigned>(m_current)).impl();
+        return String::format("Invalid character '\\u%04u'", static_cast<unsigned>(m_current));
     }
 }
 
@@ -558,6 +569,7 @@ void Lexer<T>::setCode(const SourceCode& source, ParserArena* arena)
     
     m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
     m_buffer16.reserveInitialCapacity((m_codeEnd - m_code) / 2);
+    m_bufferForRawTemplateString16.reserveInitialCapacity(initialReadBufferCapacity);
     
     if (LIKELY(m_code < m_codeEnd))
         m_current = *m_code;
@@ -599,22 +611,60 @@ ALWAYS_INLINE T Lexer<T>::peek(int offset) const
     return (code < m_codeEnd) ? *code : 0;
 }
 
-template <typename T>
-typename Lexer<T>::UnicodeHexValue Lexer<T>::parseFourDigitUnicodeHex()
-{
-    T char1 = peek(1);
-    T char2 = peek(2);
-    T char3 = peek(3);
+struct ParsedUnicodeEscapeValue {
+    ParsedUnicodeEscapeValue(UChar32 value)
+        : m_value(value)
+    {
+        ASSERT(isValid());
+    }
+
+    enum SpecialValueType { Incomplete = -2, Invalid = -1 };
+    ParsedUnicodeEscapeValue(SpecialValueType type)
+        : m_value(type)
+    {
+    }
+
+    bool isValid() const { return m_value >= 0; }
+    bool isIncomplete() const { return m_value == Incomplete; }
 
-    if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(char1) || !isASCIIHexDigit(char2) || !isASCIIHexDigit(char3)))
-        return UnicodeHexValue((m_code + 4) >= m_codeEnd ? UnicodeHexValue::IncompleteHex : UnicodeHexValue::InvalidHex);
+    UChar32 value() const
+    {
+        ASSERT(isValid());
+        return m_value;
+    }
+
+private:
+    UChar32 m_value;
+};
+
+template<typename CharacterType> ParsedUnicodeEscapeValue Lexer<CharacterType>::parseUnicodeEscape()
+{
+    if (m_current == '{') {
+        shift();
+        UChar32 codePoint = 0;
+        do {
+            if (!isASCIIHexDigit(m_current))
+                return m_current ? ParsedUnicodeEscapeValue::Invalid : ParsedUnicodeEscapeValue::Incomplete;
+            codePoint = (codePoint << 4) | toASCIIHexValue(m_current);
+            if (codePoint > UCHAR_MAX_VALUE)
+                return ParsedUnicodeEscapeValue::Invalid;
+            shift();
+        } while (m_current != '}');
+        shift();
+        return codePoint;
+    }
 
-    int result = convertUnicode(m_current, char1, char2, char3);
+    auto character2 = peek(1);
+    auto character3 = peek(2);
+    auto character4 = peek(3);
+    if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(character2) || !isASCIIHexDigit(character3) || !isASCIIHexDigit(character4)))
+        return (m_code + 4) >= m_codeEnd ? ParsedUnicodeEscapeValue::Incomplete : ParsedUnicodeEscapeValue::Invalid;
+    auto result = convertUnicode(m_current, character2, character3, character4);
     shift();
     shift();
     shift();
     shift();
-    return UnicodeHexValue(result);
+    return result;
 }
 
 template <typename T>
@@ -654,18 +704,24 @@ static ALWAYS_INLINE bool isLatin1(UChar c)
     return c < 256;
 }
 
+static ALWAYS_INLINE bool isLatin1(UChar32 c)
+{
+    return !(c & ~0xFF);
+}
+
 static inline bool isIdentStart(LChar c)
 {
     return typesOfLatin1Characters[c] == CharacterIdentifierStart;
 }
 
-static inline bool isIdentStart(UChar c)
+static inline bool isIdentStart(UChar32 c)
 {
     return isLatin1(c) ? isIdentStart(static_cast<LChar>(c)) : isNonLatin1IdentStart(c);
 }
 
-static NEVER_INLINE bool isNonLatin1IdentPart(int c)
+static NEVER_INLINE bool isNonLatin1IdentPart(UChar32 c)
 {
+    // FIXME: ES6 says this should be based on the Unicode property ID_Continue now instead.
     return (U_GET_GC_MASK(c) & (U_GC_L_MASK | U_GC_MN_MASK | U_GC_MC_MASK | U_GC_ND_MASK | U_GC_PC_MASK)) || c == 0x200C || c == 0x200D;
 }
 
@@ -677,11 +733,61 @@ static ALWAYS_INLINE bool isIdentPart(LChar c)
     return typesOfLatin1Characters[c] <= CharacterNumber;
 }
 
-static ALWAYS_INLINE bool isIdentPart(UChar c)
+static ALWAYS_INLINE bool isIdentPart(UChar32 c)
 {
     return isLatin1(c) ? isIdentPart(static_cast<LChar>(c)) : isNonLatin1IdentPart(c);
 }
 
+static ALWAYS_INLINE bool isIdentPart(UChar c)
+{
+    return isIdentPart(static_cast<UChar32>(c));
+}
+
+template<typename CharacterType> ALWAYS_INLINE bool isIdentPartIncludingEscapeTemplate(const CharacterType* code, const CharacterType* codeEnd)
+{
+    if (isIdentPart(code[0]))
+        return true;
+
+    // Shortest sequence handled below is \u{0}, which is 5 characters.
+    if (!(code[0] == '\\' && codeEnd - code >= 5 && code[1] == 'u'))
+        return false;
+
+    if (code[2] == '{') {
+        UChar32 codePoint = 0;
+        const CharacterType* pointer;
+        for (pointer = &code[3]; pointer < codeEnd; ++pointer) {
+            auto digit = *pointer;
+            if (!isASCIIHexDigit(digit))
+                break;
+            codePoint = (codePoint << 4) | toASCIIHexValue(digit);
+            if (codePoint > UCHAR_MAX_VALUE)
+                return false;
+        }
+        return isIdentPart(codePoint) && pointer < codeEnd && *pointer == '}';
+    }
+
+    // Shortest sequence handled below is \uXXXX, which is 6 characters.
+    if (codeEnd - code < 6)
+        return false;
+
+    auto character1 = code[2];
+    auto character2 = code[3];
+    auto character3 = code[4];
+    auto character4 = code[5];
+    return isASCIIHexDigit(character1) && isASCIIHexDigit(character2) && isASCIIHexDigit(character3) && isASCIIHexDigit(character4)
+        && isIdentPart(Lexer<LChar>::convertUnicode(character1, character2, character3, character4));
+}
+
+static ALWAYS_INLINE bool isIdentPartIncludingEscape(const LChar* code, const LChar* codeEnd)
+{
+    return isIdentPartIncludingEscapeTemplate(code, codeEnd);
+}
+
+static ALWAYS_INLINE bool isIdentPartIncludingEscape(const UChar* code, const UChar* codeEnd)
+{
+    return isIdentPartIncludingEscapeTemplate(code, codeEnd);
+}
+
 static inline LChar singleEscape(int c)
 {
     if (c < 128) {
@@ -758,6 +864,18 @@ inline void Lexer<T>::record16(int c)
     m_buffer16.append(static_cast<UChar>(c));
 }
     
+template<typename CharacterType> inline void Lexer<CharacterType>::recordUnicodeCodePoint(UChar32 codePoint)
+{
+    ASSERT(codePoint >= 0);
+    ASSERT(codePoint <= UCHAR_MAX_VALUE);
+    if (U_IS_BMP(codePoint))
+        record16(codePoint);
+    else {
+        UChar codeUnits[2] = { U16_LEAD(codePoint), U16_TRAIL(codePoint) };
+        append16(codeUnits, 2);
+    }
+}
+
 #if !ASSERT_DISABLED
 bool isSafeBuiltinIdentifier(VM& vm, const Identifier* ident)
 {
@@ -766,6 +884,7 @@ bool isSafeBuiltinIdentifier(VM& vm, const Identifier* ident)
     /* Just block any use of suspicious identifiers.  This is intended to
      * be used as a safety net while implementing builtins.
      */
+    // FIXME: How can a debug-only assertion be a safety net?
     if (*ident == vm.propertyNames->builtinNames().callPublicName())
         return false;
     if (*ident == vm.propertyNames->builtinNames().applyPublicName())
@@ -919,11 +1038,9 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
     return IDENT;
 }
 
-template <typename T>
-template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlowCase(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
+template<typename CharacterType> template<bool shouldCreateIdentifier> JSTokenType Lexer<CharacterType>::parseIdentifierSlowCase(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
 {
-    const ptrdiff_t remaining = m_codeEnd - m_code;
-    const T* identifierStart = currentSourcePtr();
+    auto identifierStart = currentSourcePtr();
     bool bufferRequired = false;
 
     while (true) {
@@ -942,19 +1059,18 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
         if (UNLIKELY(m_current != 'u'))
             return atEnd() ? UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK : INVALID_IDENTIFIER_ESCAPE_ERRORTOK;
         shift();
-        UnicodeHexValue character = parseFourDigitUnicodeHex();
+        auto character = parseUnicodeEscape();
         if (UNLIKELY(!character.isValid()))
-            return character.valueType() == UnicodeHexValue::IncompleteHex ? UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK : INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK;
-        UChar ucharacter = static_cast<UChar>(character.value());
-        if (UNLIKELY(m_buffer16.size() ? !isIdentPart(ucharacter) : !isIdentStart(ucharacter)))
+            return character.isIncomplete() ? UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK : INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK;
+        if (UNLIKELY(m_buffer16.size() ? !isIdentPart(character.value()) : !isIdentStart(character.value())))
             return INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK;
         if (shouldCreateIdentifier)
-            record16(ucharacter);
+            recordUnicodeCodePoint(character.value());
         identifierStart = currentSourcePtr();
     }
 
     int identifierLength;
-    const Identifier* ident = 0;
+    const Identifier* ident = nullptr;
     if (shouldCreateIdentifier) {
         if (!bufferRequired) {
             identifierLength = currentSourcePtr() - identifierStart;
@@ -967,23 +1083,19 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
 
         tokenData->ident = ident;
     } else
-        tokenData->ident = 0;
+        tokenData->ident = nullptr;
 
-    if (LIKELY(!bufferRequired && !(lexerFlags & LexerFlagsIgnoreReservedWords))) {
+    m_buffer16.shrink(0);
+
+    if (LIKELY(!(lexerFlags & LexerFlagsIgnoreReservedWords))) {
         ASSERT(shouldCreateIdentifier);
-        // Keywords must not be recognized if there was an \uXXXX in the identifier.
-        if (remaining < maxTokenLength) {
-            const HashTableValue* entry = m_vm->keywords->getKeyword(*ident);
-            ASSERT((remaining < maxTokenLength) || !entry);
-            if (!entry)
-                return IDENT;
-            JSTokenType token = static_cast<JSTokenType>(entry->lexerValue());
-            return (token != RESERVED_IF_STRICT) || strictMode ? token : IDENT;
-        }
-        return IDENT;
+        const HashTableValue* entry = m_vm->keywords->getKeyword(*ident);
+        if (!entry)
+            return IDENT;
+        JSTokenType token = static_cast<JSTokenType>(entry->lexerValue());
+        return (token != RESERVED_IF_STRICT) || strictMode ? token : IDENT;
     }
 
-    m_buffer16.resize(0);
     return IDENT;
 }
 
@@ -1016,7 +1128,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
 
             LChar escape = singleEscape(m_current);
 
-            // Most common escape sequences first
+            // Most common escape sequences first.
             if (escape) {
                 if (shouldBuildStrings)
                     record8(escape);
@@ -1026,7 +1138,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
             else if (m_current == 'x') {
                 shift();
                 if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
-                    m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
+                    m_lexErrorMessage = ASCIILiteral("\\x can only be followed by a hex character sequence");
                     return (atEnd() || (isASCIIHexDigit(m_current) && (m_code + 1 == m_codeEnd))) ? StringUnterminated : StringCannotBeParsed;
                 }
                 T prev = m_current;
@@ -1037,7 +1149,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
             } else {
                 setOffset(startingOffset, startingLineStartOffset);
                 setLineNumber(startingLineNumber);
-                m_buffer8.resize(0);
+                m_buffer8.shrink(0);
                 return parseStringSlowCase<shouldBuildStrings>(tokenData, strictMode);
             }
             stringStart = currentSourcePtr();
@@ -1047,7 +1159,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
         if (UNLIKELY(characterRequiresParseStringSlowCase(m_current))) {
             setOffset(startingOffset, startingLineStartOffset);
             setLineNumber(startingLineNumber);
-            m_buffer8.resize(0);
+            m_buffer8.shrink(0);
             return parseStringSlowCase<shouldBuildStrings>(tokenData, strictMode);
         }
 
@@ -1058,7 +1170,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
         append8(stringStart, currentSourcePtr() - stringStart);
     if (shouldBuildStrings) {
         tokenData->ident = makeIdentifier(m_buffer8.data(), m_buffer8.size());
-        m_buffer8.resize(0);
+        m_buffer8.shrink(0);
     } else
         tokenData->ident = 0;
 
@@ -1066,7 +1178,93 @@ template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseR
 }
 
 template <typename T>
-template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>::parseStringSlowCase(JSTokenData* tokenData, bool strictMode)
+template <bool shouldBuildStrings> ALWAYS_INLINE auto Lexer<T>::parseComplexEscape(EscapeParseMode escapeParseMode, bool strictMode, T stringQuoteCharacter) -> StringParseResult
+{
+    if (m_current == 'x') {
+        shift();
+        if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
+            m_lexErrorMessage = ASCIILiteral("\\x can only be followed by a hex character sequence");
+            return StringCannotBeParsed;
+        }
+        T prev = m_current;
+        shift();
+        if (shouldBuildStrings)
+            record16(convertHex(prev, m_current));
+        shift();
+        return StringParsedSuccessfully;
+    }
+
+    if (m_current == 'u') {
+        shift();
+
+        if (escapeParseMode == EscapeParseMode::String && m_current == stringQuoteCharacter) {
+            if (shouldBuildStrings)
+                record16('u');
+            return StringParsedSuccessfully;
+        }
+
+        auto character = parseUnicodeEscape();
+        if (character.isValid()) {
+            if (shouldBuildStrings)
+                recordUnicodeCodePoint(character.value());
+            return StringParsedSuccessfully;
+        }
+
+        m_lexErrorMessage = ASCIILiteral("\\u can only be followed by a Unicode character sequence");
+        return character.isIncomplete() ? StringUnterminated : StringCannotBeParsed;
+    }
+
+    if (strictMode) {
+        if (isASCIIDigit(m_current)) {
+            // The only valid numeric escape in strict mode is '\0', and this must not be followed by a decimal digit.
+            int character1 = m_current;
+            shift();
+            if (character1 != '0' || isASCIIDigit(m_current)) {
+                m_lexErrorMessage = ASCIILiteral("The only valid numeric escape in strict mode is '\\0'");
+                return StringCannotBeParsed;
+            }
+            if (shouldBuildStrings)
+                record16(0);
+            return StringParsedSuccessfully;
+        }
+    } else {
+        if (isASCIIOctalDigit(m_current)) {
+            // Octal character sequences
+            T character1 = m_current;
+            shift();
+            if (isASCIIOctalDigit(m_current)) {
+                // Two octal characters
+                T character2 = m_current;
+                shift();
+                if (character1 >= '0' && character1 <= '3' && isASCIIOctalDigit(m_current)) {
+                    if (shouldBuildStrings)
+                        record16((character1 - '0') * 64 + (character2 - '0') * 8 + m_current - '0');
+                    shift();
+                } else {
+                    if (shouldBuildStrings)
+                        record16((character1 - '0') * 8 + character2 - '0');
+                }
+            } else {
+                if (shouldBuildStrings)
+                    record16(character1 - '0');
+            }
+            return StringParsedSuccessfully;
+        }
+    }
+
+    if (!atEnd()) {
+        if (shouldBuildStrings)
+            record16(m_current);
+        shift();
+        return StringParsedSuccessfully;
+    }
+
+    m_lexErrorMessage = ASCIILiteral("Unterminated string constant");
+    return StringUnterminated;
+}
+
+template <typename T>
+template <bool shouldBuildStrings> auto Lexer<T>::parseStringSlowCase(JSTokenData* tokenData, bool strictMode) -> StringParseResult
 {
     T stringQuoteCharacter = m_current;
     shift();
@@ -1088,67 +1286,10 @@ template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>
                 shift();
             } else if (UNLIKELY(isLineTerminator(m_current)))
                 shiftLineTerminator();
-            else if (m_current == 'x') {
-                shift();
-                if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
-                    m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
-                    return StringCannotBeParsed;
-                }
-                T prev = m_current;
-                shift();
-                if (shouldBuildStrings)
-                    record16(convertHex(prev, m_current));
-                shift();
-            } else if (m_current == 'u') {
-                shift();
-                UnicodeHexValue character = parseFourDigitUnicodeHex();
-                if (character.isValid()) {
-                    if (shouldBuildStrings)
-                        record16(character.value());
-                } else if (m_current == stringQuoteCharacter) {
-                    if (shouldBuildStrings)
-                        record16('u');
-                } else {
-                    m_lexErrorMessage = "\\u can only be followed by a Unicode character sequence";
-                    return character.valueType() == UnicodeHexValue::IncompleteHex ? StringUnterminated : StringCannotBeParsed;
-                }
-            } else if (strictMode && isASCIIDigit(m_current)) {
-                // The only valid numeric escape in strict mode is '\0', and this must not be followed by a decimal digit.
-                int character1 = m_current;
-                shift();
-                if (character1 != '0' || isASCIIDigit(m_current)) {
-                    m_lexErrorMessage = "The only valid numeric escape in strict mode is '\\0'";
-                    return StringCannotBeParsed;
-                }
-                if (shouldBuildStrings)
-                    record16(0);
-            } else if (!strictMode && isASCIIOctalDigit(m_current)) {
-                // Octal character sequences
-                T character1 = m_current;
-                shift();
-                if (isASCIIOctalDigit(m_current)) {
-                    // Two octal characters
-                    T character2 = m_current;
-                    shift();
-                    if (character1 >= '0' && character1 <= '3' && isASCIIOctalDigit(m_current)) {
-                        if (shouldBuildStrings)
-                            record16((character1 - '0') * 64 + (character2 - '0') * 8 + m_current - '0');
-                        shift();
-                    } else {
-                        if (shouldBuildStrings)
-                            record16((character1 - '0') * 8 + character2 - '0');
-                    }
-                } else {
-                    if (shouldBuildStrings)
-                        record16(character1 - '0');
-                }
-            } else if (!atEnd()) {
-                if (shouldBuildStrings)
-                    record16(m_current);
-                shift();
-            } else {
-                m_lexErrorMessage = "Unterminated string constant";
-                return StringUnterminated;
+            else {
+                StringParseResult result = parseComplexEscape<shouldBuildStrings>(EscapeParseMode::String, strictMode, stringQuoteCharacter);
+                if (result != StringParsedSuccessfully)
+                    return result;
             }
 
             stringStart = currentSourcePtr();
@@ -1160,7 +1301,7 @@ template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>
         if (UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) {
             // New-line or end of input is not allowed
             if (atEnd() || isLineTerminator(m_current)) {
-                m_lexErrorMessage = "Unexpected EOF";
+                m_lexErrorMessage = ASCIILiteral("Unexpected EOF");
                 return atEnd() ? StringUnterminated : StringCannotBeParsed;
             }
             // Anything else is just a normal character
@@ -1175,10 +1316,190 @@ template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>
     else
         tokenData->ident = 0;
 
-    m_buffer16.resize(0);
+    m_buffer16.shrink(0);
     return StringParsedSuccessfully;
 }
 
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+// While the lexer accepts <LF><CR> (not <CR><LF>) sequence
+// as one line terminator and increments one line number,
+// TemplateLiteral considers it as two line terminators <LF> and <CR>.
+//
+// TemplateLiteral normalizes line terminators as follows.
+//
+// <LF> => <LF>
+// <CR> => <LF>
+// <CR><LF> => <LF>
+// <\u2028> => <\u2028>
+// <\u2029> => <\u2029>
+//
+// So, <LF><CR> should be normalized to <LF><LF>.
+// However, the lexer should increment the line number only once for <LF><CR>.
+//
+// To achieve this, LineNumberAdder holds the current status of line terminator sequence.
+// When TemplateLiteral lexer encounters a line terminator, it notifies to LineNumberAdder.
+// LineNumberAdder maintains the status and increments the line number when it's necessary.
+// For example, LineNumberAdder increments the line number only once for <LF><CR> and <CR><LF>.
+template<typename CharacterType>
+class LineNumberAdder {
+public:
+    LineNumberAdder(int& lineNumber)
+        : m_lineNumber(lineNumber)
+    {
+    }
+
+    void clear()
+    {
+        m_previous = 0;
+    }
+
+    void add(CharacterType character)
+    {
+        ASSERT(Lexer<CharacterType>::isLineTerminator(character));
+        if ((character + m_previous) == ('\n' + '\r'))
+            m_previous = 0;
+        else {
+            ++m_lineNumber;
+            m_previous = character;
+        }
+    }
+
+private:
+    int& m_lineNumber;
+    CharacterType m_previous { 0 };
+};
+
+template <typename T>
+template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>::parseTemplateLiteral(JSTokenData* tokenData, RawStringsBuildMode rawStringsBuildMode)
+{
+    const T* stringStart = currentSourcePtr();
+    const T* rawStringStart = currentSourcePtr();
+
+    LineNumberAdder<T> lineNumberAdder(m_lineNumber);
+
+    while (m_current != '`') {
+        if (UNLIKELY(m_current == '\\')) {
+            lineNumberAdder.clear();
+            if (stringStart != currentSourcePtr() && shouldBuildStrings)
+                append16(stringStart, currentSourcePtr() - stringStart);
+            shift();
+
+            LChar escape = singleEscape(m_current);
+
+            // Most common escape sequences first.
+            if (escape) {
+                if (shouldBuildStrings)
+                    record16(escape);
+                shift();
+            } else if (UNLIKELY(isLineTerminator(m_current))) {
+                if (m_current == '\r') {
+                    lineNumberAdder.add(m_current);
+                    shift();
+                    if (m_current == '\n') {
+                        lineNumberAdder.add(m_current);
+                        shift();
+                    }
+                } else {
+                    lineNumberAdder.add(m_current);
+                    shift();
+                }
+            } else {
+                bool strictMode = true;
+                StringParseResult result = parseComplexEscape<shouldBuildStrings>(EscapeParseMode::Template, strictMode, '`');
+                if (result != StringParsedSuccessfully)
+                    return result;
+            }
+
+            stringStart = currentSourcePtr();
+            continue;
+        }
+
+        if (m_current == '$' && peek(1) == '{')
+            break;
+
+        // Fast check for characters that require special handling.
+        // Catches 0, \n, \r, 0x2028, and 0x2029 as efficiently
+        // as possible, and lets through all common ASCII characters.
+        if (UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) {
+            // End of input is not allowed.
+            // Unlike String, line terminator is allowed.
+            if (atEnd()) {
+                m_lexErrorMessage = ASCIILiteral("Unexpected EOF");
+                return atEnd() ? StringUnterminated : StringCannotBeParsed;
+            }
+
+            if (isLineTerminator(m_current)) {
+                if (m_current == '\r') {
+                    // Normalize <CR>, <CR><LF> to <LF>.
+                    if (shouldBuildStrings) {
+                        if (stringStart != currentSourcePtr())
+                            append16(stringStart, currentSourcePtr() - stringStart);
+                        if (rawStringStart != currentSourcePtr() && rawStringsBuildMode == RawStringsBuildMode::BuildRawStrings)
+                            m_bufferForRawTemplateString16.append(rawStringStart, currentSourcePtr() - rawStringStart);
+
+                        record16('\n');
+                        if (rawStringsBuildMode == RawStringsBuildMode::BuildRawStrings)
+                            m_bufferForRawTemplateString16.append('\n');
+                    }
+                    lineNumberAdder.add(m_current);
+                    shift();
+                    if (m_current == '\n') {
+                        lineNumberAdder.add(m_current);
+                        shift();
+                    }
+                    stringStart = currentSourcePtr();
+                    rawStringStart = currentSourcePtr();
+                } else {
+                    lineNumberAdder.add(m_current);
+                    shift();
+                }
+                continue;
+            }
+            // Anything else is just a normal character
+        }
+
+        lineNumberAdder.clear();
+        shift();
+    }
+
+    bool isTail = m_current == '`';
+
+    if (shouldBuildStrings) {
+        if (currentSourcePtr() != stringStart)
+            append16(stringStart, currentSourcePtr() - stringStart);
+        if (rawStringStart != currentSourcePtr() && rawStringsBuildMode == RawStringsBuildMode::BuildRawStrings)
+            m_bufferForRawTemplateString16.append(rawStringStart, currentSourcePtr() - rawStringStart);
+    }
+
+    if (shouldBuildStrings) {
+        tokenData->cooked = makeIdentifier(m_buffer16.data(), m_buffer16.size());
+        // Line terminator normalization (e.g. <CR> => <LF>) should be applied to both the raw and cooked representations.
+        if (rawStringsBuildMode == RawStringsBuildMode::BuildRawStrings)
+            tokenData->raw = makeIdentifier(m_bufferForRawTemplateString16.data(), m_bufferForRawTemplateString16.size());
+        else
+            tokenData->raw = makeEmptyIdentifier();
+    } else {
+        tokenData->cooked = makeEmptyIdentifier();
+        tokenData->raw = makeEmptyIdentifier();
+    }
+    tokenData->isTail = isTail;
+
+    m_buffer16.shrink(0);
+    m_bufferForRawTemplateString16.shrink(0);
+
+    if (isTail) {
+        // Skip `
+        shift();
+    } else {
+        // Skip $ and {
+        shift();
+        shift();
+    }
+
+    return StringParsedSuccessfully;
+}
+#endif
+
 template <typename T>
 ALWAYS_INLINE void Lexer<T>::parseHex(double& returnValue)
 {
@@ -1186,9 +1507,6 @@ ALWAYS_INLINE void Lexer<T>::parseHex(double& returnValue)
     uint32_t hexValue = 0;
     int maximumDigits = 7;
 
-    // Shift out the 'x' prefix.
-    shift();
-
     do {
         hexValue = (hexValue << 4) + toASCIIHexValue(m_current);
         shift();
@@ -1219,29 +1537,68 @@ ALWAYS_INLINE void Lexer<T>::parseHex(double& returnValue)
     returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16);
 }
 
+template <typename T>
+ALWAYS_INLINE bool Lexer<T>::parseBinary(double& returnValue)
+{
+    // Optimization: most binary values fit into 4 bytes.
+    uint32_t binaryValue = 0;
+    const unsigned maximumDigits = 32;
+    int digit = maximumDigits - 1;
+    // Temporary buffer for the digits. Makes easier
+    // to reconstruct the input characters when needed.
+    LChar digits[maximumDigits];
+
+    do {
+        binaryValue = (binaryValue << 1) + (m_current - '0');
+        digits[digit] = m_current;
+        shift();
+        --digit;
+    } while (isASCIIBinaryDigit(m_current) && digit >= 0);
+
+    if (!isASCIIDigit(m_current) && digit >= 0) {
+        returnValue = binaryValue;
+        return true;
+    }
+
+    for (int i = maximumDigits - 1; i > digit; --i)
+        record8(digits[i]);
+
+    while (isASCIIBinaryDigit(m_current)) {
+        record8(m_current);
+        shift();
+    }
+
+    if (isASCIIDigit(m_current))
+        return false;
+
+    returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 2);
+    return true;
+}
+
 template <typename T>
 ALWAYS_INLINE bool Lexer<T>::parseOctal(double& returnValue)
 {
     // Optimization: most octal values fit into 4 bytes.
     uint32_t octalValue = 0;
-    int maximumDigits = 9;
+    const unsigned maximumDigits = 10;
+    int digit = maximumDigits - 1;
     // Temporary buffer for the digits. Makes easier
     // to reconstruct the input characters when needed.
-    LChar digits[10];
+    LChar digits[maximumDigits];
 
     do {
         octalValue = octalValue * 8 + (m_current - '0');
-        digits[maximumDigits] = m_current;
+        digits[digit] = m_current;
         shift();
-        --maximumDigits;
-    } while (isASCIIOctalDigit(m_current) && maximumDigits >= 0);
+        --digit;
+    } while (isASCIIOctalDigit(m_current) && digit >= 0);
 
-    if (!isASCIIDigit(m_current) && maximumDigits >= 0) {
+    if (!isASCIIDigit(m_current) && digit >= 0) {
         returnValue = octalValue;
         return true;
     }
 
-    for (int i = 9; i > maximumDigits; --i)
+    for (int i = maximumDigits - 1; i > digit; --i)
          record8(digits[i]);
 
     while (isASCIIOctalDigit(m_current)) {
@@ -1265,24 +1622,25 @@ ALWAYS_INLINE bool Lexer<T>::parseDecimal(double& returnValue)
     // Since parseOctal may be executed before parseDecimal,
     // the m_buffer8 may hold ascii digits.
     if (!m_buffer8.size()) {
-        int maximumDigits = 9;
+        const unsigned maximumDigits = 10;
+        int digit = maximumDigits - 1;
         // Temporary buffer for the digits. Makes easier
         // to reconstruct the input characters when needed.
-        LChar digits[10];
+        LChar digits[maximumDigits];
 
         do {
             decimalValue = decimalValue * 10 + (m_current - '0');
-            digits[maximumDigits] = m_current;
+            digits[digit] = m_current;
             shift();
-            --maximumDigits;
-        } while (isASCIIDigit(m_current) && maximumDigits >= 0);
+            --digit;
+        } while (isASCIIDigit(m_current) && digit >= 0);
 
-        if (maximumDigits >= 0 && m_current != '.' && (m_current | 0x20) != 'e') {
+        if (digit >= 0 && m_current != '.' && (m_current | 0x20) != 'e') {
             returnValue = decimalValue;
             return true;
         }
 
-        for (int i = 9; i > maximumDigits; --i)
+        for (int i = maximumDigits - 1; i > digit; --i)
             record8(digits[i]);
     }
 
@@ -1357,11 +1715,25 @@ bool Lexer<T>::nextTokenIsColon()
     return code < m_codeEnd && *code == ':';
 }
 
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+template <typename T>
+void Lexer<T>::setTokenPosition(JSToken* tokenRecord)
+{
+    JSTokenData* tokenData = &tokenRecord->m_data;
+    tokenData->line = lineNumber();
+    tokenData->offset = currentOffset();
+    tokenData->lineStartOffset = currentLineStartOffset();
+    ASSERT(tokenData->offset >= tokenData->lineStartOffset);
+}
+#endif
+
 template <typename T>
 JSTokenType Lexer<T>::lex(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
 {
     JSTokenData* tokenData = &tokenRecord->m_data;
     JSTokenLocation* tokenLocation = &tokenRecord->m_location;
+    m_lastTockenLocation = JSTokenLocation(tokenRecord->m_location);
+    
     ASSERT(!m_error);
     ASSERT(m_buffer8.isEmpty());
     ASSERT(m_buffer16.isEmpty());
@@ -1420,7 +1792,19 @@ start:
         }
         token = GT;
         break;
-    case CharacterEqual:
+    case CharacterEqual: {
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+        if (peek(1) == '>') {
+            token = ARROWFUNCTION;
+            tokenData->line = lineNumber();
+            tokenData->offset = currentOffset();
+            tokenData->lineStartOffset = currentLineStartOffset();
+            ASSERT(tokenData->offset >= tokenData->lineStartOffset);
+            shift();
+            shift();
+            break;
+        }
+#endif
         shift();
         if (m_current == '=') {
             shift();
@@ -1434,6 +1818,7 @@ start:
         }
         token = EQUAL;
         break;
+    }
     case CharacterLess:
         shift();
         if (m_current == '!' && peek(1) == '-' && peek(2) == '-') {
@@ -1522,7 +1907,7 @@ start:
             shift();
             if (parseMultilineComment())
                 goto start;
-            m_lexErrorMessage = "Multiline comment was not closed properly";
+            m_lexErrorMessage = ASCIILiteral("Multiline comment was not closed properly");
             token = UNTERMINATED_MULTILINE_COMMENT_ERRORTOK;
             goto returnError;
         }
@@ -1648,79 +2033,144 @@ start:
         shift();
         if ((m_current | 0x20) == 'x') {
             if (!isASCIIHexDigit(peek(1))) {
-                m_lexErrorMessage = "No hexadecimal digits after '0x'";
+                m_lexErrorMessage = ASCIILiteral("No hexadecimal digits after '0x'");
                 token = INVALID_HEX_NUMBER_ERRORTOK;
                 goto returnError;
             }
+
+            // Shift out the 'x' prefix.
+            shift();
+
             parseHex(tokenData->doubleValue);
             if (isIdentStart(m_current)) {
-                m_lexErrorMessage = "No space between hexadecimal literal and identifier";
+                m_lexErrorMessage = ASCIILiteral("No space between hexadecimal literal and identifier");
                 token = INVALID_HEX_NUMBER_ERRORTOK;
                 goto returnError;
             }
-            token = NUMBER;
-            m_buffer8.resize(0);
+            token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
+            m_buffer8.shrink(0);
+            break;
+        }
+        if ((m_current | 0x20) == 'b') {
+            if (!isASCIIBinaryDigit(peek(1))) {
+                m_lexErrorMessage = ASCIILiteral("No binary digits after '0b'");
+                token = INVALID_BINARY_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+
+            // Shift out the 'b' prefix.
+            shift();
+
+            parseBinary(tokenData->doubleValue);
+            if (isIdentStart(m_current)) {
+                m_lexErrorMessage = ASCIILiteral("No space between binary literal and identifier");
+                token = INVALID_BINARY_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+            token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
+            m_buffer8.shrink(0);
+            break;
+        }
+
+        if ((m_current | 0x20) == 'o') {
+            if (!isASCIIOctalDigit(peek(1))) {
+                m_lexErrorMessage = ASCIILiteral("No octal digits after '0o'");
+                token = INVALID_OCTAL_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+
+            // Shift out the 'o' prefix.
+            shift();
+
+            parseOctal(tokenData->doubleValue);
+            if (isIdentStart(m_current)) {
+                m_lexErrorMessage = ASCIILiteral("No space between octal literal and identifier");
+                token = INVALID_OCTAL_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+            token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
+            m_buffer8.shrink(0);
             break;
         }
 
         record8('0');
+        if (strictMode && isASCIIDigit(m_current)) {
+            m_lexErrorMessage = ASCIILiteral("Decimal integer literals with a leading zero are forbidden in strict mode");
+            token = INVALID_OCTAL_NUMBER_ERRORTOK;
+            goto returnError;
+        }
         if (isASCIIOctalDigit(m_current)) {
             if (parseOctal(tokenData->doubleValue)) {
-                if (strictMode) {
-                    m_lexErrorMessage = "Octal escapes are forbidden in strict mode";
-                    token = INVALID_OCTAL_NUMBER_ERRORTOK;
-                    goto returnError;
-                }
-                token = NUMBER;
+                token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
             }
         }
         FALLTHROUGH;
     case CharacterNumber:
-        if (LIKELY(token != NUMBER)) {
+        if (LIKELY(token != INTEGER && token != DOUBLE)) {
             if (!parseDecimal(tokenData->doubleValue)) {
+                token = INTEGER;
                 if (m_current == '.') {
                     shift();
 inNumberAfterDecimalPoint:
                     parseNumberAfterDecimalPoint();
+                    token = DOUBLE;
                 }
                 if ((m_current | 0x20) == 'e') {
                     if (!parseNumberAfterExponentIndicator()) {
-                        m_lexErrorMessage = "Non-number found after exponent indicator";
+                        m_lexErrorMessage = ASCIILiteral("Non-number found after exponent indicator");
                         token = atEnd() ? UNTERMINATED_NUMERIC_LITERAL_ERRORTOK : INVALID_NUMERIC_LITERAL_ERRORTOK;
                         goto returnError;
                     }
                 }
                 size_t parsedLength;
                 tokenData->doubleValue = parseDouble(m_buffer8.data(), m_buffer8.size(), parsedLength);
-            }
-            token = NUMBER;
+                if (token == INTEGER)
+                    token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
+            } else
+                token = tokenTypeForIntegerLikeToken(tokenData->doubleValue);
         }
 
         // No identifiers allowed directly after numeric literal, e.g. "3in" is bad.
         if (UNLIKELY(isIdentStart(m_current))) {
-            m_lexErrorMessage = "At least one digit must occur after a decimal point";
+            m_lexErrorMessage = ASCIILiteral("At least one digit must occur after a decimal point");
             token = atEnd() ? UNTERMINATED_NUMERIC_LITERAL_ERRORTOK : INVALID_NUMERIC_LITERAL_ERRORTOK;
             goto returnError;
         }
-        m_buffer8.resize(0);
+        m_buffer8.shrink(0);
         break;
-    case CharacterQuote:
-        if (lexerFlags & LexerFlagsDontBuildStrings) {
-            StringParseResult result = parseString<false>(tokenData, strictMode);
-            if (UNLIKELY(result != StringParsedSuccessfully)) {
-                token = result == StringUnterminated ? UNTERMINATED_STRING_LITERAL_ERRORTOK : INVALID_STRING_LITERAL_ERRORTOK;
-                goto returnError;
-            }
-        } else {
-            StringParseResult result = parseString<true>(tokenData, strictMode);
-            if (UNLIKELY(result != StringParsedSuccessfully)) {
-                token = result == StringUnterminated ? UNTERMINATED_STRING_LITERAL_ERRORTOK : INVALID_STRING_LITERAL_ERRORTOK;
-                goto returnError;
-            }
+    case CharacterQuote: {
+        StringParseResult result = StringCannotBeParsed;
+        if (lexerFlags & LexerFlagsDontBuildStrings)
+            result = parseString<false>(tokenData, strictMode);
+        else
+            result = parseString<true>(tokenData, strictMode);
+
+        if (UNLIKELY(result != StringParsedSuccessfully)) {
+            token = result == StringUnterminated ? UNTERMINATED_STRING_LITERAL_ERRORTOK : INVALID_STRING_LITERAL_ERRORTOK;
+            goto returnError;
         }
         shift();
         token = STRING;
         break;
+        }
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    case CharacterBackQuote: {
+        // Skip backquote.
+        shift();
+        StringParseResult result = StringCannotBeParsed;
+        if (lexerFlags & LexerFlagsDontBuildStrings)
+            result = parseTemplateLiteral<false>(tokenData, RawStringsBuildMode::BuildRawStrings);
+        else
+            result = parseTemplateLiteral<true>(tokenData, RawStringsBuildMode::BuildRawStrings);
+
+        if (UNLIKELY(result != StringParsedSuccessfully)) {
+            token = result == StringUnterminated ? UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK : INVALID_TEMPLATE_LITERAL_ERRORTOK;
+            goto returnError;
+        }
+        token = TEMPLATE;
+        break;
+        }
+#endif
     case CharacterIdentifierStart:
         ASSERT(isIdentStart(m_current));
         FALLTHROUGH;
@@ -1749,7 +2199,7 @@ inNumberAfterDecimalPoint:
         goto returnError;
     default:
         RELEASE_ASSERT_NOT_REACHED();
-        m_lexErrorMessage = "Internal Error";
+        m_lexErrorMessage = ASCIILiteral("Internal Error");
         token = ERRORTOK;
         goto returnError;
     }
@@ -1823,7 +2273,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
 
     while (true) {
         if (isLineTerminator(m_current) || atEnd()) {
-            m_buffer16.resize(0);
+            m_buffer16.shrink(0);
             return false;
         }
 
@@ -1857,7 +2307,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
 
     pattern = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
 
-    m_buffer16.resize(0);
+    m_buffer16.shrink(0);
     charactersOredTogether = 0;
 
     while (isIdentPart(m_current)) {
@@ -1867,7 +2317,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
     }
 
     flags = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
-    m_buffer16.resize(0);
+    m_buffer16.shrink(0);
 
     return true;
 }
@@ -1913,6 +2363,40 @@ bool Lexer<T>::skipRegExp()
     return true;
 }
 
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+template <typename T>
+JSTokenType Lexer<T>::scanTrailingTemplateString(JSToken* tokenRecord, RawStringsBuildMode rawStringsBuildMode)
+{
+    JSTokenData* tokenData = &tokenRecord->m_data;
+    JSTokenLocation* tokenLocation = &tokenRecord->m_location;
+    ASSERT(!m_error);
+    ASSERT(m_buffer16.isEmpty());
+
+    // Leading closing brace } is already shifted in the previous token scan.
+    // So in this re-scan phase, shift() is not needed here.
+    StringParseResult result = parseTemplateLiteral<true>(tokenData, rawStringsBuildMode);
+    JSTokenType token = ERRORTOK;
+    if (UNLIKELY(result != StringParsedSuccessfully)) {
+        token = result == StringUnterminated ? UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK : INVALID_TEMPLATE_LITERAL_ERRORTOK;
+        m_error = true;
+    } else {
+        token = TEMPLATE;
+        m_lastToken = token;
+    }
+
+    // Since TemplateString always ends with ` or }, m_atLineStart always becomes false.
+    m_atLineStart = false;
+
+    // Adjust current tokenLocation data for TemplateString.
+    tokenLocation->line = m_lineNumber;
+    tokenLocation->endOffset = currentOffset();
+    tokenLocation->lineStartOffset = currentLineStartOffset();
+    ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
+    tokenRecord->m_endPosition = currentPosition();
+    return token;
+}
+#endif
+
 template <typename T>
 void Lexer<T>::clear()
 {
@@ -1924,6 +2408,9 @@ void Lexer<T>::clear()
     Vector<UChar> newBuffer16;
     m_buffer16.swap(newBuffer16);
 
+    Vector<UChar> newBufferForRawTemplateString16;
+    m_bufferForRawTemplateString16.swap(newBufferForRawTemplateString16);
+
     m_isReparsing = false;
 }
 
index 07241ae28ab42837a74f25e495ab9832e9eb92f8..b142c484a4057d472736a2e9932b8b86d79d1c21 100644 (file)
@@ -37,14 +37,16 @@ class Keywords {
 public:
     bool isKeyword(const Identifier& ident) const
     {
-        return m_keywordTable.entry(m_vm, ident);
+        return m_keywordTable.entry(ident);
     }
     
     const HashTableValue* getKeyword(const Identifier& ident) const
     {
-        return m_keywordTable.entry(m_vm, ident);
+        return m_keywordTable.entry(ident);
     }
-    
+
+    explicit Keywords(VM&);
+
     ~Keywords()
     {
         m_keywordTable.deleteTable();
@@ -53,8 +55,6 @@ public:
 private:
     friend class VM;
     
-    explicit Keywords(VM&);
-    
     VM& m_vm;
     const HashTable m_keywordTable;
 };
@@ -65,13 +65,15 @@ enum LexerFlags {
     LexexFlagsDontBuildKeywords = 4
 };
 
+struct ParsedUnicodeEscapeValue;
+
 template <typename T>
 class Lexer {
     WTF_MAKE_NONCOPYABLE(Lexer);
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Lexer(VM*, JSParserStrictness);
+    Lexer(VM*, JSParserBuiltinMode);
     ~Lexer();
 
     // Character manipulation functions.
@@ -85,6 +87,9 @@ public:
     void setIsReparsing() { m_isReparsing = true; }
     bool isReparsing() const { return m_isReparsing; }
 
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    void setTokenPosition(JSToken* tokenRecord);
+#endif
     JSTokenType lex(JSToken*, unsigned, bool strictMode);
     bool nextTokenIsColon();
     int lineNumber() const { return m_lineNumber; }
@@ -95,10 +100,15 @@ public:
         return JSTextPosition(m_lineNumber, currentOffset(), currentLineStartOffset());
     }
     JSTextPosition positionBeforeLastNewline() const { return m_positionBeforeLastNewline; }
+    JSTokenLocation lastTokenLocation() const { return m_lastTockenLocation; }
     void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
     int lastLineNumber() const { return m_lastLineNumber; }
     bool prevTerminator() const { return m_terminator; }
     bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0);
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    enum class RawStringsBuildMode { BuildRawStrings, DontBuildRawStrings };
+    JSTokenType scanTrailingTemplateString(JSToken*, RawStringsBuildMode);
+#endif
     bool skipRegExp();
 
     // Functions for use after parsing.
@@ -125,6 +135,10 @@ public:
     {
         m_lineNumber = line;
     }
+    void setTerminator(bool terminator)
+    {
+        m_terminator = terminator;
+    }
 
     SourceProvider* sourceProvider() const { return m_source->provider(); }
 
@@ -135,42 +149,15 @@ private:
     void append8(const T*, size_t);
     void record16(int);
     void record16(T);
+    void recordUnicodeCodePoint(UChar32);
     void append16(const LChar*, size_t);
     void append16(const UChar* characters, size_t length) { m_buffer16.append(characters, length); }
 
     ALWAYS_INLINE void shift();
     ALWAYS_INLINE bool atEnd() const;
     ALWAYS_INLINE T peek(int offset) const;
-    struct UnicodeHexValue {
-        
-        enum ValueType { ValidHex, IncompleteHex, InvalidHex };
-        
-        explicit UnicodeHexValue(int value)
-            : m_value(value)
-        {
-        }
-        explicit UnicodeHexValue(ValueType type)
-            : m_value(type == IncompleteHex ? -2 : -1)
-        {
-        }
-
-        ValueType valueType() const
-        {
-            if (m_value >= 0)
-                return ValidHex;
-            return m_value == -2 ? IncompleteHex : InvalidHex;
-        }
-        bool isValid() const { return m_value >= 0; }
-        int value() const
-        {
-            ASSERT(m_value >= 0);
-            return m_value;
-        }
-        
-    private:
-        int m_value;
-    };
-    UnicodeHexValue parseFourDigitUnicodeHex();
+
+    ParsedUnicodeEscapeValue parseUnicodeEscape();
     void shiftLineTerminator();
 
     ALWAYS_INLINE int offsetFromSourcePtr(const T* ptr) const { return ptr - m_codeStart; }
@@ -188,6 +175,7 @@ private:
     ALWAYS_INLINE const Identifier* makeLCharIdentifier(const UChar* characters, size_t length);
     ALWAYS_INLINE const Identifier* makeRightSizedIdentifier(const UChar* characters, size_t length, UChar orAllChars);
     ALWAYS_INLINE const Identifier* makeIdentifierLCharFromUChar(const UChar* characters, size_t length);
+    ALWAYS_INLINE const Identifier* makeEmptyIdentifier();
 
     ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
 
@@ -202,7 +190,14 @@ private:
     };
     template <bool shouldBuildStrings> ALWAYS_INLINE StringParseResult parseString(JSTokenData*, bool strictMode);
     template <bool shouldBuildStrings> NEVER_INLINE StringParseResult parseStringSlowCase(JSTokenData*, bool strictMode);
+
+    enum class EscapeParseMode { Template, String };
+    template <bool shouldBuildStrings> ALWAYS_INLINE StringParseResult parseComplexEscape(EscapeParseMode, bool strictMode, T stringQuoteCharacter);
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    template <bool shouldBuildStrings> ALWAYS_INLINE StringParseResult parseTemplateLiteral(JSTokenData*, RawStringsBuildMode);
+#endif
     ALWAYS_INLINE void parseHex(double& returnValue);
+    ALWAYS_INLINE bool parseBinary(double& returnValue);
     ALWAYS_INLINE bool parseOctal(double& returnValue);
     ALWAYS_INLINE bool parseDecimal(double& returnValue);
     ALWAYS_INLINE void parseNumberAfterDecimalPoint();
@@ -216,6 +211,7 @@ private:
 
     Vector<LChar> m_buffer8;
     Vector<UChar> m_buffer16;
+    Vector<UChar> m_bufferForRawTemplateString16;
     bool m_terminator;
     int m_lastToken;
 
@@ -227,6 +223,7 @@ private:
     const T* m_codeStartPlusOffset;
     const T* m_lineStart;
     JSTextPosition m_positionBeforeLastNewline;
+    JSTokenLocation m_lastTockenLocation;
     bool m_isReparsing;
     bool m_atLineStart;
     bool m_error;
@@ -304,6 +301,12 @@ ALWAYS_INLINE const Identifier* Lexer<UChar>::makeRightSizedIdentifier(const UCh
     return &m_arena->makeIdentifier(m_vm, characters, length);
 }
 
+template <typename T>
+ALWAYS_INLINE const Identifier* Lexer<T>::makeEmptyIdentifier()
+{
+    return &m_arena->makeEmptyIdentifier(m_vm);
+}
+
 template <>
 ALWAYS_INLINE void Lexer<LChar>::setCodeStart(const StringImpl* sourceString)
 {
index 2083aa4e64c6711473ccaaa11191102f6801ebb0..60c7c2ff663f0c2a19eef162188e13b900b9cc76 100644 (file)
 
 namespace JSC {
 
-    inline void* ParserArenaFreeable::operator new(size_t size, VM* vm)
+    inline void* ParserArenaFreeable::operator new(size_t size, ParserArena& parserArena)
     {
-        return vm->parserArena->allocateFreeable(size);
+        return parserArena.allocateFreeable(size);
     }
 
-    inline void* ParserArenaDeletable::operator new(size_t size, VM* vm)
+    inline void* ParserArenaDeletable::operator new(size_t size, ParserArena& parserArena)
     {
-        return vm->parserArena->allocateDeletable(size);
+        return parserArena.allocateDeletable(size);
     }
 
-    inline ParserArenaRefCounted::ParserArenaRefCounted(VM* vm)
+    inline ParserArenaRoot::ParserArenaRoot(ParserArena& parserArena)
     {
-        vm->parserArena->derefWithArena(adoptRef(this));
+        m_arena.swap(parserArena);
     }
 
     inline Node::Node(const JSTokenLocation& location)
         : m_position(location.line, location.startOffset, location.lineStartOffset)
+        , m_endOffset(-1)
     {
         ASSERT(location.startOffset >= location.lineStartOffset);
     }
@@ -56,6 +57,7 @@ namespace JSC {
 
     inline StatementNode::StatementNode(const JSTokenLocation& location)
         : Node(location)
+        , m_next(nullptr)
         , m_lastLine(-1)
     {
     }
@@ -82,12 +84,74 @@ namespace JSC {
     {
     }
 
+    inline DoubleNode::DoubleNode(const JSTokenLocation& location, double value)
+        : NumberNode(location, value)
+    {
+    }
+
+    inline IntegerNode::IntegerNode(const JSTokenLocation& location, double value)
+        : DoubleNode(location, value)
+    {
+    }
+
     inline StringNode::StringNode(const JSTokenLocation& location, const Identifier& value)
         : ConstantNode(location, ResultType::stringType())
         , m_value(value)
     {
     }
 
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    inline TemplateExpressionListNode::TemplateExpressionListNode(ExpressionNode* node)
+        : m_node(node)
+    {
+    }
+
+    inline TemplateExpressionListNode::TemplateExpressionListNode(TemplateExpressionListNode* previous, ExpressionNode* node)
+        : m_node(node)
+    {
+        previous->m_next = this;
+    }
+
+    inline TemplateStringNode::TemplateStringNode(const JSTokenLocation& location, const Identifier& cooked, const Identifier& raw)
+        : ExpressionNode(location)
+        , m_cooked(cooked)
+        , m_raw(raw)
+    {
+    }
+
+    inline TemplateStringListNode::TemplateStringListNode(TemplateStringNode* node)
+        : m_node(node)
+    {
+    }
+
+    inline TemplateStringListNode::TemplateStringListNode(TemplateStringListNode* previous, TemplateStringNode* node)
+        : m_node(node)
+    {
+        previous->m_next = this;
+    }
+
+    inline TemplateLiteralNode::TemplateLiteralNode(const JSTokenLocation& location, TemplateStringListNode* templateStrings)
+        : ExpressionNode(location)
+        , m_templateStrings(templateStrings)
+        , m_templateExpressions(nullptr)
+    {
+    }
+
+    inline TemplateLiteralNode::TemplateLiteralNode(const JSTokenLocation& location, TemplateStringListNode* templateStrings, TemplateExpressionListNode* templateExpressions)
+        : ExpressionNode(location)
+        , m_templateStrings(templateStrings)
+        , m_templateExpressions(templateExpressions)
+    {
+    }
+
+    inline TaggedTemplateNode::TaggedTemplateNode(const JSTokenLocation& location, ExpressionNode* tag, TemplateLiteralNode* templateLiteral)
+        : ExpressionNode(location)
+        , m_tag(tag)
+        , m_templateLiteral(templateLiteral)
+    {
+    }
+#endif
+
     inline RegExpNode::RegExpNode(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags)
         : ExpressionNode(location)
         , m_pattern(pattern)
@@ -95,12 +159,18 @@ namespace JSC {
     {
     }
 
-    inline ThisNode::ThisNode(const JSTokenLocation& location)
+    inline ThisNode::ThisNode(const JSTokenLocation& location, ThisTDZMode thisTDZMode)
+        : ExpressionNode(location)
+        , m_shouldAlwaysEmitTDZCheck(thisTDZMode == ThisTDZMode::AlwaysCheck)
+    {
+    }
+
+    inline SuperNode::SuperNode(const JSTokenLocation& location)
         : ExpressionNode(location)
     {
     }
 
-inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start)
+    inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start)
         : ExpressionNode(location)
         , m_ident(ident)
         , m_start(start)
@@ -147,25 +217,22 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     {
     }
 
-    inline PropertyNode::PropertyNode(VM*, const Identifier& name, ExpressionNode* assign, Type type)
+    inline PropertyNode::PropertyNode(const Identifier& name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding = SuperBinding::NotNeeded)
         : m_name(&name)
         , m_assign(assign)
         , m_type(type)
+        , m_needsSuperBinding(superBinding == SuperBinding::Needed)
+        , m_putType(putType)
     {
     }
 
-    inline PropertyNode::PropertyNode(VM* vm, double name, ExpressionNode* assign, Type type)
-        : m_name(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name))
-        , m_assign(assign)
-        , m_type(type)
-    {
-    }
-    
-    inline PropertyNode::PropertyNode(VM*, ExpressionNode* name, ExpressionNode* assign, Type type)
+    inline PropertyNode::PropertyNode(ExpressionNode* name, ExpressionNode* assign, Type type, PutType putType)
         : m_name(0)
         , m_expression(name)
         , m_assign(assign)
         , m_type(type)
+        , m_needsSuperBinding(false)
+        , m_putType(putType)
     {
     }
 
@@ -281,12 +348,13 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     {
     }
 
-    inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+    inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
         : ExpressionNode(location)
         , ThrowableSubExpressionData(divot, divotStart, divotEnd)
         , m_base(base)
         , m_subscript(subscript)
         , m_args(args)
+        , m_subscriptHasAssignments(subscriptHasAssignments)
     {
     }
 
@@ -299,6 +367,15 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     {
     }
 
+    inline BytecodeIntrinsicNode::BytecodeIntrinsicNode(const JSTokenLocation& location, EmitterType emitter, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+        : ExpressionNode(location)
+        , ThrowableExpressionData(divot, divotStart, divotEnd)
+        , m_emitter(emitter)
+        , m_ident(ident)
+        , m_args(args)
+    {
+    }
+
     inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
         : FunctionCallDotNode(location, base, ident, args, divot, divotStart, divotEnd)
     {
@@ -615,13 +692,11 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     {
     }
 
-    inline CommaNode::CommaNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2)
+    inline CommaNode::CommaNode(const JSTokenLocation& location, ExpressionNode* expr)
         : ExpressionNode(location)
+        , m_expr(expr)
+        , m_next(nullptr)
     {
-        ASSERT(expr1);
-        ASSERT(expr2);
-        m_expressions.append(expr1);
-        m_expressions.append(expr2);
     }
 
     inline ConstStatementNode::ConstStatementNode(const JSTokenLocation& location, ConstDeclNode* next)
@@ -631,6 +706,8 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     }
 
     inline SourceElements::SourceElements()
+        : m_head(nullptr)
+        , m_tail(nullptr)
     {
     }
 
@@ -655,6 +732,12 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
         , m_expr(expr)
     {
     }
+
+    inline EmptyVarExpression::EmptyVarExpression(const JSTokenLocation& location, const Identifier& ident)
+        : ExpressionNode(location)
+        , m_ident(ident)
+    {
+    }
     
     inline IfElseNode::IfElseNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
         : StatementNode(location)
@@ -688,24 +771,12 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
         ASSERT(statement);
     }
 
-    inline ContinueNode::ContinueNode(VM* vm, const JSTokenLocation& location)
-        : StatementNode(location)
-        , m_ident(vm->propertyNames->nullIdentifier)
-    {
-    }
-
     inline ContinueNode::ContinueNode(const JSTokenLocation& location, const Identifier& ident)
         : StatementNode(location)
         , m_ident(ident)
     {
     }
     
-    inline BreakNode::BreakNode(VM* vm, const JSTokenLocation& location)
-        : StatementNode(location)
-        , m_ident(vm->propertyNames->nullIdentifier)
-    {
-    }
-
     inline BreakNode::BreakNode(const JSTokenLocation& location, const Identifier& ident)
         : StatementNode(location)
         , m_ident(ident)
@@ -740,29 +811,29 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
     {
     }
 
-    inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
+    inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier& thrownValueIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
         : StatementNode(location)
         , m_tryBlock(tryBlock)
-        , m_exceptionIdent(exceptionIdent)
+        , m_thrownValueIdent(thrownValueIdent)
         , m_catchBlock(catchBlock)
         , m_finallyBlock(finallyBlock)
     {
     }
 
-    inline ParameterNode::ParameterNode(PassRefPtr<DeconstructionPatternNode> pattern)
+    inline ParameterNode::ParameterNode(PassRefPtr<DestructuringPatternNode> pattern)
         : m_pattern(pattern)
         , m_next(0)
     {
         ASSERT(m_pattern);
     }
 
-    inline ParameterNode::ParameterNode(ParameterNode* l, PassRefPtr<DeconstructionPatternNode> pattern)
+    inline ParameterNode::ParameterNode(ParameterNode* previous, PassRefPtr<DestructuringPatternNode> pattern)
         : m_pattern(pattern)
         , m_next(0)
     {
-        l->m_next = this;
+        previous->m_next = this;
         ASSERT(m_pattern);
-        ASSERT(l->m_pattern);
+        ASSERT(previous->m_pattern);
     }
 
     inline FuncExprNode::FuncExprNode(const JSTokenLocation& location, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
@@ -779,6 +850,24 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
         m_body->finishParsing(source, parameter, ident, FunctionDeclaration);
     }
 
+#if ENABLE(ES6_CLASS_SYNTAX)
+    inline ClassDeclNode::ClassDeclNode(const JSTokenLocation& location, ExpressionNode* classDeclaration)
+        : StatementNode(location)
+        , m_classDeclaration(classDeclaration)
+    {
+    }
+
+    inline ClassExprNode::ClassExprNode(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
+        : ExpressionNode(location)
+        , m_name(name)
+        , m_constructorExpression(constructorExpression)
+        , m_classHeritage(classHeritage)
+        , m_instanceMethods(instanceMethods)
+        , m_staticMethods(staticMethods)
+    {
+    }
+#endif
+
     inline CaseClauseNode::CaseClauseNode(ExpressionNode* expr, SourceElements* statements)
         : m_expr(expr)
         , m_statements(statements)
@@ -835,73 +924,54 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie
         ASSERT(l);
     }
     
-    inline EnumerationNode::EnumerationNode(VM* vm, const JSTokenLocation& location, DeconstructionPatternNode* pattern, ExpressionNode* expr, StatementNode* statement)
-        : StatementNode(location)
-        , m_lexpr(new (vm) DeconstructingAssignmentNode(location, pattern, 0))
-        , m_expr(expr)
-        , m_statement(statement)
-    {
-        ASSERT(pattern);
-    }
-    
     inline ForInNode::ForInNode(const JSTokenLocation& location, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
         : EnumerationNode(location, l, expr, statement)
     {
     }
     
-    inline ForInNode::ForInNode(VM* vm, const JSTokenLocation& location, DeconstructionPatternNode* pattern, ExpressionNode* expr, StatementNode* statement)
-        : EnumerationNode(vm, location, pattern, expr, statement)
-    {
-    }
-    
     inline ForOfNode::ForOfNode(const JSTokenLocation& location, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
         : EnumerationNode(location, l, expr, statement)
     {
     }
     
-    inline ForOfNode::ForOfNode(VM* vm, const JSTokenLocation& location, DeconstructionPatternNode* pattern, ExpressionNode* expr, StatementNode* statement)
-        : EnumerationNode(vm, location, pattern, expr, statement)
-    {
-    }
-    
-    inline DeconstructionPatternNode::DeconstructionPatternNode(VM*)
+    inline DestructuringPatternNode::DestructuringPatternNode()
     {
     }
 
-    inline ArrayPatternNode::ArrayPatternNode(VM* vm)
-        : DeconstructionPatternNode(vm)
+    inline ArrayPatternNode::ArrayPatternNode()
+        : DestructuringPatternNode()
     {
     }
     
-    inline PassRefPtr<ArrayPatternNode> ArrayPatternNode::create(VM* vm)
+    inline Ref<ArrayPatternNode> ArrayPatternNode::create()
     {
-        return adoptRef(new ArrayPatternNode(vm));
+        return adoptRef(*new ArrayPatternNode);
     }
     
-    inline ObjectPatternNode::ObjectPatternNode(VM* vm)
-        : DeconstructionPatternNode(vm)
+    inline ObjectPatternNode::ObjectPatternNode()
+        : DestructuringPatternNode()
     {
     }
     
-    inline PassRefPtr<ObjectPatternNode> ObjectPatternNode::create(VM* vm)
+    inline Ref<ObjectPatternNode> ObjectPatternNode::create()
     {
-        return adoptRef(new ObjectPatternNode(vm));
+        return adoptRef(*new ObjectPatternNode);
     }
 
-    inline PassRefPtr<BindingNode> BindingNode::create(VM* vm, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
+    inline Ref<BindingNode> BindingNode::create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
     {
-        return adoptRef(new BindingNode(vm, boundProperty, start, end));
+        return adoptRef(*new BindingNode(boundProperty, start, end));
     }
     
-    inline BindingNode::BindingNode(VM* vm, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
-        : DeconstructionPatternNode(vm)
+    inline BindingNode::BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
+        : DestructuringPatternNode()
         , m_divotStart(start)
         , m_divotEnd(end)
         , m_boundProperty(boundProperty)
     {
     }
     
-    inline DeconstructingAssignmentNode::DeconstructingAssignmentNode(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> bindings, ExpressionNode* initializer)
+    inline DestructuringAssignmentNode::DestructuringAssignmentNode(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> bindings, ExpressionNode* initializer)
         : ExpressionNode(location)
         , m_bindings(bindings)
         , m_initializer(initializer)
diff --git a/parser/NodeInfo.h b/parser/NodeInfo.h
deleted file mode 100644 (file)
index 4853aec..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef NodeInfo_h
-#define NodeInfo_h
-
-#include "Nodes.h"
-
-namespace JSC {
-
-    template <typename T> struct NodeInfo {
-        T m_node;
-        CodeFeatures m_features;
-        int m_numConstants;
-    };
-
-    typedef NodeInfo<FuncDeclNode*> FuncDeclNodeInfo;    
-    typedef NodeInfo<FuncExprNode*> FuncExprNodeInfo;
-    typedef NodeInfo<ExpressionNode*> ExpressionNodeInfo;
-    typedef NodeInfo<ArgumentsNode*> ArgumentsNodeInfo;
-    typedef NodeInfo<ConstDeclNode*> ConstDeclNodeInfo;
-    typedef NodeInfo<PropertyNode*> PropertyNodeInfo;
-    typedef NodeInfo<PropertyList> PropertyListInfo;
-    typedef NodeInfo<ElementList> ElementListInfo;
-    typedef NodeInfo<ArgumentList> ArgumentListInfo;
-    
-    template <typename T> struct NodeDeclarationInfo {
-        T m_node;
-        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
-        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
-        CodeFeatures m_features;
-        int m_numConstants;
-    };
-    
-    typedef NodeDeclarationInfo<StatementNode*> StatementNodeInfo;
-    typedef NodeDeclarationInfo<CaseBlockNode*> CaseBlockNodeInfo;
-    typedef NodeDeclarationInfo<CaseClauseNode*> CaseClauseNodeInfo;
-    typedef NodeDeclarationInfo<SourceElements*> SourceElementsInfo;
-    typedef NodeDeclarationInfo<ClauseList> ClauseListInfo;
-    typedef NodeDeclarationInfo<ExpressionNode*> VarDeclListInfo;
-    typedef NodeDeclarationInfo<ConstDeclList> ConstDeclListInfo;
-    typedef NodeDeclarationInfo<ParameterList> ParameterListInfo;
-
-} // namespace JSC
-
-#endif // NodeInfo_h
index bdc3bf8d8b4eea00e98d72823d7112615864b3d0..93a63a422fda3a40f30ce7ac9e115138618adc7a 100644 (file)
@@ -27,7 +27,6 @@
 #include "Nodes.h"
 #include "NodeConstructors.h"
 
-#include "BytecodeGenerator.h"
 #include "CallFrame.h"
 #include "Debugger.h"
 #include "JIT.h"
@@ -65,20 +64,27 @@ void SourceElements::append(StatementNode* statement)
 {
     if (statement->isEmptyStatement())
         return;
-    m_statements.append(statement);
+
+    if (!m_head) {
+        m_head = statement;
+        m_tail = statement;
+        return;
+    }
+
+    m_tail->setNext(statement);
+    m_tail = statement;
 }
 
 StatementNode* SourceElements::singleStatement() const
 {
-    size_t size = m_statements.size();
-    return size == 1 ? m_statements[0] : 0;
+    return m_head == m_tail ? m_head : nullptr;
 }
 
 // ------------------------------ ScopeNode -----------------------------
 
-ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
+ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
     : StatementNode(endLocation)
-    , ParserArenaRefCounted(vm)
+    , ParserArenaRoot(parserArena)
     , m_startLineNumber(startLocation.line)
     , m_startStartOffset(startLocation.startOffset)
     , m_startLineStartOffset(startLocation.lineStartOffset)
@@ -88,9 +94,9 @@ ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSToken
 {
 }
 
-ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
+ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
     : StatementNode(endLocation)
-    , ParserArenaRefCounted(vm)
+    , ParserArenaRoot(parserArena)
     , m_startLineNumber(startLocation.line)
     , m_startStartOffset(startLocation.startOffset)
     , m_startLineStartOffset(startLocation.lineStartOffset)
@@ -99,11 +105,8 @@ ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSToken
     , m_numConstants(numConstants)
     , m_statements(children)
 {
-    m_arena.swap(*vm->parserArena);
-    if (varStack)
-        m_varStack.swap(*varStack);
-    if (funcStack)
-        m_functionStack.swap(*funcStack);
+    m_varStack.swap(varStack);
+    m_functionStack.swap(funcStack);
     m_capturedVariables.swap(capturedVariables);
 }
 
@@ -114,60 +117,37 @@ StatementNode* ScopeNode::singleStatement() const
 
 // ------------------------------ ProgramNode -----------------------------
 
-inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
-    : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+    : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
     , m_startColumn(startColumn)
     , m_endColumn(endColumn)
 {
 }
 
-PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
-{
-    RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, endColumn, children, varStack, funcStack,  capturedVariables, source, features, numConstants);
-
-    ASSERT(node->m_arena.last() == node);
-    node->m_arena.removeLast();
-    ASSERT(!node->m_arena.contains(node.get()));
-
-    return node.release();
-}
-
-
-void ProgramNode::setClosedVariables(Vector<RefPtr<StringImpl>>&& closedVariables)
+void ProgramNode::setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&& closedVariables)
 {
     m_closedVariables = WTF::move(closedVariables);
 }
 
 // ------------------------------ EvalNode -----------------------------
 
-inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
-    : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+    : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
     , m_endColumn(endColumn)
 {
 }
 
-PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
-{
-    RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
-
-    ASSERT(node->m_arena.last() == node);
-    node->m_arena.removeLast();
-    ASSERT(!node->m_arena.contains(node.get()));
-
-    return node.release();
-}
-
 // ------------------------------ FunctionBodyNode -----------------------------
 
-PassRefPtr<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
+Ref<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
 {
     unsigned parameterCount = 0;
     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
         ++parameterCount;
 
-    size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DeconstructionPatternNode*) * parameterCount;
+    size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DestructuringPatternNode*) * parameterCount;
     void* slot = fastMalloc(objectSize);
-    return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount));
+    return adoptRef(*new (slot) FunctionParameters(firstParameter, parameterCount));
 }
 
 FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
@@ -187,54 +167,53 @@ FunctionParameters::~FunctionParameters()
         patterns()[i]->deref();
 }
 
-inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
-    : ScopeNode(vm, startLocation, endLocation, inStrictContext)
-    , m_startColumn(startColumn)
-    , m_endColumn(endColumn)
-{
-}
-
-inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
-    : ScopeNode(vm, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
-    , m_startColumn(startColumn)
-    , m_endColumn(endColumn)
+FunctionBodyNode::FunctionBodyNode(
+    ParserArena&, const JSTokenLocation& startLocation, 
+    const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, 
+    int functionKeywordStart, int functionNameStart, int parametersStart,
+    bool isInStrictContext, ConstructorKind constructorKind)
+        : StatementNode(endLocation)
+        , m_startColumn(startColumn)
+        , m_endColumn(endColumn)
+        , m_functionKeywordStart(functionKeywordStart)
+        , m_functionNameStart(functionNameStart)
+        , m_parametersStart(parametersStart)
+        , m_startStartOffset(startLocation.startOffset)
+        , m_isInStrictContext(isInStrictContext)
+        , m_constructorKind(static_cast<unsigned>(constructorKind))
 {
+    ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
 }
 
 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, enum FunctionMode functionMode)
 {
-    setSource(source);
-    finishParsing(FunctionParameters::create(firstParameter), ident, functionMode);
-}
-
-void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, enum FunctionMode functionMode)
-{
-    ASSERT(!source().isNull());
-    m_parameters = parameters;
+    m_source = source;
+    m_parameters = FunctionParameters::create(firstParameter);
     m_ident = ident;
     m_functionMode = functionMode;
 }
 
-FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
+void FunctionBodyNode::setEndPosition(JSTextPosition position)
 {
-    return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
+    m_lastLine = position.line;
+    m_endColumn = position.offset - position.lineStartOffset;
 }
 
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
-{
-    RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn , children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
-
-    ASSERT(node->m_arena.last() == node);
-    node->m_arena.removeLast();
-    ASSERT(!node->m_arena.contains(node.get()));
+// ------------------------------ FunctionNode -----------------------------
 
-    return node.release();
+FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+    : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
+    , m_startColumn(startColumn)
+    , m_endColumn(endColumn)
+{
 }
 
-void FunctionBodyNode::setEndPosition(JSTextPosition position)
+void FunctionNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, enum FunctionMode functionMode)
 {
-    m_lastLine = position.line;
-    m_endColumn = position.offset - position.lineStartOffset;
+    ASSERT(!source().isNull());
+    m_parameters = parameters;
+    m_ident = ident;
+    m_functionMode = functionMode;
 }
 
 } // namespace JSC
index a3b41532ff9f93888eaddd1a2b2fdd509bc63dad..f29a5104f8af23625a5ca1091d7fa5836ee9f35a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *  Copyright (C) 2007 Maks Orlovich
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -76,7 +76,7 @@ namespace JSC {
     };
     inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
 
-    typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
+    typedef HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> IdentifierSet;
 
     namespace DeclarationStacks {
         enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
@@ -94,7 +94,7 @@ namespace JSC {
     public:
         // ParserArenaFreeable objects are are freed when the arena is deleted.
         // Destructors are not called. Clients must not call delete on such objects.
-        void* operator new(size_t, VM*);
+        void* operator new(size_t, ParserArena&);
     };
 
     class ParserArenaDeletable {
@@ -103,24 +103,20 @@ namespace JSC {
 
         // ParserArenaDeletable objects are deleted when the arena is deleted.
         // Clients must not call delete directly on such objects.
-        void* operator new(size_t, VM*);
+        void* operator new(size_t, ParserArena&);
     };
 
-    template <typename T>
-    struct ParserArenaData : ParserArenaDeletable {
-        T data;
-    };
-
-    class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
+    class ParserArenaRoot {
         WTF_MAKE_FAST_ALLOCATED;
     protected:
-        ParserArenaRefCounted(VM*);
+        ParserArenaRoot(ParserArena&);
 
     public:
-        virtual ~ParserArenaRefCounted()
-        {
-            ASSERT(deletionHasBegun());
-        }
+        ParserArena& parserArena() { return m_arena; }
+        virtual ~ParserArenaRoot() { }
+
+    protected:
+        ParserArena m_arena;
     };
 
     class Node : public ParserArenaFreeable {
@@ -130,13 +126,17 @@ namespace JSC {
     public:
         virtual ~Node() { }
 
-        int lineNo() const { return m_position.line; }
+        int firstLine() const { return m_position.line; }
         int startOffset() const { return m_position.offset; }
+        int endOffset() const { return m_endOffset; }
         int lineStartOffset() const { return m_position.lineStartOffset; }
         const JSTextPosition& position() const { return m_position; }
+        void setEndOffset(int offset) { m_endOffset = offset; }
+        void setStartOffset(int offset) { m_position.offset = offset; }
 
     protected:
         JSTextPosition m_position;
+        int m_endOffset;
     };
 
     class ExpressionNode : public Node {
@@ -156,7 +156,7 @@ namespace JSC {
         virtual bool isResolveNode() const { return false; }
         virtual bool isBracketAccessorNode() const { return false; }
         virtual bool isDotAccessorNode() const { return false; }
-        virtual bool isDeconstructionNode() const { return false; }
+        virtual bool isDestructuringNode() const { return false; }
         virtual bool isFuncExprNode() const { return false; }
         virtual bool isCommaNode() const { return false; }
         virtual bool isSimpleArray() const { return false; }
@@ -164,6 +164,7 @@ namespace JSC {
         virtual bool isSubtract() const { return false; }
         virtual bool isBoolean() const { return false; }
         virtual bool isSpreadExpression() const { return false; }
+        virtual bool isSuperNode() const { return false; }
 
         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
 
@@ -183,17 +184,21 @@ namespace JSC {
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
 
         void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
-        unsigned firstLine() const { return lineNo(); }
         unsigned lastLine() const { return m_lastLine; }
 
+        StatementNode* next() { return m_next; }
+        void setNext(StatementNode* next) { m_next = next; }
+
         virtual bool isEmptyStatement() const { return false; }
         virtual bool isReturnNode() const { return false; }
         virtual bool isExprStatement() const { return false; }
         virtual bool isBreak() const { return false; }
         virtual bool isContinue() const { return false; }
         virtual bool isBlock() const { return false; }
+        virtual bool isFuncDeclNode() const { return false; }
 
     protected:
+        StatementNode* m_next;
         int m_lastLine;
     };
 
@@ -232,16 +237,32 @@ namespace JSC {
     class NumberNode : public ConstantNode {
     public:
         NumberNode(const JSTokenLocation&, double value);
-        double value() { return m_value; }
-        void setValue(double value) { m_value = value; }
+        double value() const { return m_value; }
+        virtual bool isIntegerNode() const = 0;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override final;
 
     private:
-        virtual bool isNumber() const override { return true; }
+        virtual bool isNumber() const override final { return true; }
         virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
 
         double m_value;
     };
 
+    class DoubleNode : public NumberNode {
+    public:
+        DoubleNode(const JSTokenLocation&, double value);
+
+    private:
+        virtual bool isIntegerNode() const override { return false; }
+    };
+
+    // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
+    class IntegerNode : public DoubleNode {
+    public:
+        IntegerNode(const JSTokenLocation&, double value);
+        virtual bool isIntegerNode() const override final { return true; }
+    };
+
     class StringNode : public ConstantNode {
     public:
         StringNode(const JSTokenLocation&, const Identifier&);
@@ -253,7 +274,7 @@ namespace JSC {
 
         const Identifier& m_value;
     };
-    
+
     class ThrowableExpressionData {
     public:
         ThrowableExpressionData()
@@ -406,6 +427,76 @@ namespace JSC {
         uint16_t m_subexpressionLineStartOffset;
     };
 
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    class TemplateExpressionListNode : public ParserArenaFreeable {
+    public:
+        TemplateExpressionListNode(ExpressionNode*);
+        TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*);
+
+        ExpressionNode* value() { return m_node; }
+        TemplateExpressionListNode* next() { return m_next; }
+
+    private:
+        TemplateExpressionListNode* m_next { nullptr };
+        ExpressionNode* m_node { nullptr };
+    };
+
+    class TemplateStringNode : public ExpressionNode {
+    public:
+        TemplateStringNode(const JSTokenLocation&, const Identifier& cooked, const Identifier& raw);
+
+        const Identifier& cooked() { return m_cooked; }
+        const Identifier& raw() { return m_raw; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_cooked;
+        const Identifier& m_raw;
+    };
+
+    class TemplateStringListNode : public ParserArenaFreeable {
+    public:
+        TemplateStringListNode(TemplateStringNode*);
+        TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*);
+
+        TemplateStringNode* value() { return m_node; }
+        TemplateStringListNode* next() { return m_next; }
+
+    private:
+        TemplateStringListNode* m_next { nullptr };
+        TemplateStringNode* m_node { nullptr };
+    };
+
+    class TemplateLiteralNode : public ExpressionNode {
+    public:
+        TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*);
+        TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*);
+
+        TemplateStringListNode* templateStrings() const { return m_templateStrings; }
+        TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        TemplateStringListNode* m_templateStrings;
+        TemplateExpressionListNode* m_templateExpressions;
+    };
+
+    class TaggedTemplateNode : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*);
+
+        TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        ExpressionNode* m_tag;
+        TemplateLiteralNode* m_templateLiteral;
+    };
+#endif
+
     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
@@ -419,10 +510,21 @@ namespace JSC {
 
     class ThisNode : public ExpressionNode {
     public:
-        ThisNode(const JSTokenLocation&);
+        ThisNode(const JSTokenLocation&, ThisTDZMode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        bool m_shouldAlwaysEmitTDZCheck;
+    };
+
+    class SuperNode final : public ExpressionNode {
+    public:
+        SuperNode(const JSTokenLocation&);
+
+    private:
+        virtual bool isSuperNode() const override { return true; }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class ResolveNode : public ExpressionNode {
@@ -463,7 +565,7 @@ namespace JSC {
         ArrayNode(const JSTokenLocation&, ElementNode*);
         ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
 
-        ArgumentListNode* toArgumentList(VM*, int, int) const;
+        ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
 
         ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
     private:
@@ -478,23 +580,27 @@ namespace JSC {
 
     class PropertyNode : public ParserArenaFreeable {
     public:
-        enum Type { Constant = 1, Getter = 2, Setter = 4 };
+        enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16 };
+        enum PutType { Unknown, KnownDirect };
+
+        PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding);
+        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType);
 
-        PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
-        PropertyNode(VM*, double, ExpressionNode*, Type);
-        PropertyNode(VM*, ExpressionNode* propertyName, ExpressionNode*, Type);
-        
         ExpressionNode* expressionName() const { return m_expression; }
         const Identifier* name() const { return m_name; }
 
-        Type type() const { return m_type; }
+        Type type() const { return static_cast<Type>(m_type); }
+        bool needsSuperBinding() const { return m_needsSuperBinding; }
+        PutType putType() const { return static_cast<PutType>(m_putType); }
 
     private:
         friend class PropertyListNode;
         const Identifier* m_name;
         ExpressionNode* m_expression;
         ExpressionNode* m_assign;
-        Type m_type;
+        unsigned m_type : 5;
+        unsigned m_needsSuperBinding : 1;
+        unsigned m_putType : 1;
     };
 
     class PropertyListNode : public ExpressionNode {
@@ -502,9 +608,10 @@ namespace JSC {
         PropertyListNode(const JSTokenLocation&, PropertyNode*);
         PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
 
+    private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
 
-    private:
         PropertyNode* m_node;
         PropertyListNode* m_next;
     };
@@ -636,7 +743,7 @@ namespace JSC {
     
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
@@ -644,6 +751,7 @@ namespace JSC {
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
         ArgumentsNode* m_args;
+        bool m_subscriptHasAssignments;
     };
 
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
@@ -659,6 +767,26 @@ namespace JSC {
         ArgumentsNode* m_args;
     };
 
+    class BytecodeIntrinsicNode : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
+
+        BytecodeIntrinsicNode(const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+
+        const Identifier& identifier() const { return m_ident; }
+
+#define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
+        JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
+#undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        EmitterType m_emitter;
+        const Identifier& m_ident;
+        ArgumentsNode* m_args;
+    };
+
     class CallFunctionCallDotNode : public FunctionCallDotNode {
     public:
         CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
@@ -1094,21 +1222,19 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
     
-    typedef Vector<ExpressionNode*, 8> ExpressionVector;
-
-    class CommaNode : public ExpressionNode, public ParserArenaDeletable {
+    class CommaNode final : public ExpressionNode {
     public:
-        CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
+        CommaNode(const JSTokenLocation&, ExpressionNode*);
 
-        using ParserArenaDeletable::operator new;
-
-        void append(ExpressionNode* expr) { ASSERT(expr); m_expressions.append(expr); }
+        void setNext(CommaNode* next) { m_next = next; }
+        CommaNode* next() { return m_next; }
 
     private:
         virtual bool isCommaNode() const override { return true; }
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        ExpressionVector m_expressions;
+        ExpressionNode* m_expr;
+        CommaNode* m_next;
     };
     
     class ConstDeclNode : public ExpressionNode {
@@ -1141,7 +1267,7 @@ namespace JSC {
         ConstDeclNode* m_next;
     };
 
-    class SourceElements : public ParserArenaDeletable {
+    class SourceElements final : public ParserArenaFreeable {
     public:
         SourceElements();
 
@@ -1153,7 +1279,8 @@ namespace JSC {
         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
 
     private:
-        Vector<StatementNode*> m_statements;
+        StatementNode* m_head;
+        StatementNode* m_tail;
     };
 
     class BlockNode : public StatementNode {
@@ -1212,6 +1339,17 @@ namespace JSC {
         ExpressionNode* m_expr;
     };
 
+    class EmptyVarExpression : public ExpressionNode {
+    public:
+        EmptyVarExpression(const JSTokenLocation&, const Identifier&);
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_ident;
+    };
+
+
     class IfElseNode : public StatementNode {
     public:
         IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
@@ -1261,12 +1399,11 @@ namespace JSC {
         StatementNode* m_statement;
     };
     
-    class DeconstructionPatternNode;
+    class DestructuringPatternNode;
     
     class EnumerationNode : public StatementNode, public ThrowableExpressionData {
     public:
         EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
-        EnumerationNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
         
     protected:
         ExpressionNode* m_lexpr;
@@ -1277,16 +1414,18 @@ namespace JSC {
     class ForInNode : public EnumerationNode {
     public:
         ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
-        ForInNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
 
     private:
+        RegisterID* tryGetBoundLocal(BytecodeGenerator&);
+        void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
+        void emitMultiLoopBytecode(BytecodeGenerator&, RegisterID* dst);
+
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
     
     class ForOfNode : public EnumerationNode {
     public:
         ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
-        ForOfNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
         
     private:
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
@@ -1294,7 +1433,6 @@ namespace JSC {
 
     class ContinueNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ContinueNode(VM*, const JSTokenLocation&);
         ContinueNode(const JSTokenLocation&, const Identifier&);
         Label* trivialTarget(BytecodeGenerator&);
         
@@ -1307,7 +1445,6 @@ namespace JSC {
 
     class BreakNode : public StatementNode, public ThrowableExpressionData {
     public:
-        BreakNode(VM*, const JSTokenLocation&);
         BreakNode(const JSTokenLocation&, const Identifier&);
         Label* trivialTarget(BytecodeGenerator&);
         
@@ -1374,42 +1511,33 @@ namespace JSC {
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         StatementNode* m_tryBlock;
-        const Identifier& m_exceptionIdent;
+        const Identifier& m_thrownValueIdent;
         StatementNode* m_catchBlock;
         StatementNode* m_finallyBlock;
     };
 
     class ParameterNode : public ParserArenaDeletable {
     public:
-        ParameterNode(PassRefPtr<DeconstructionPatternNode>);
-        ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
+        ParameterNode(PassRefPtr<DestructuringPatternNode>);
+        ParameterNode(ParameterNode*, PassRefPtr<DestructuringPatternNode>);
 
-        DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
+        DestructuringPatternNode* pattern() const { return m_pattern.get(); }
         ParameterNode* nextParam() const { return m_next; }
 
     private:
-        RefPtr<DeconstructionPatternNode> m_pattern;
+        RefPtr<DestructuringPatternNode> m_pattern;
         ParameterNode* m_next;
     };
 
-    class ScopeNode : public StatementNode, public ParserArenaRefCounted {
+    class ScopeNode : public StatementNode, public ParserArenaRoot {
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
-        ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
-        ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+        ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+        ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, CodeFeatures, int numConstants);
 
-        using ParserArenaRefCounted::operator new;
-
-        void destroyData()
-        {
-            m_arena.reset();
-            m_varStack.clear();
-            m_functionStack.clear();
-            m_statements = 0;
-            m_capturedVariables.clear();
-        }
+        using ParserArenaRoot::operator new;
 
         const SourceCode& source() const { return m_source; }
         const String& sourceURL() const { return m_source.provider()->url(); }
@@ -1425,6 +1553,7 @@ namespace JSC {
         bool usesEval() const { return m_features & EvalFeature; }
         bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
         bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
+        bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); }
         bool isStrictMode() const { return m_features & StrictModeFeature; }
         void setUsesArguments() { m_features |= ArgumentsFeature; }
         bool usesThis() const { return m_features & ThisFeature; }
@@ -1433,7 +1562,8 @@ namespace JSC {
         bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
         size_t capturedVariableCount() const { return m_capturedVariables.size(); }
         const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
-        bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+        bool captures(UniquedStringImpl* uid) { return m_capturedVariables.contains(uid); }
+        bool captures(const Identifier& ident) { return captures(ident.impl()); }
 
         VarStack& varStack() { return m_varStack; }
         FunctionStack& functionStack() { return m_functionStack; }
@@ -1449,12 +1579,9 @@ namespace JSC {
 
         void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
         
-        void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { }
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
 
     protected:
-        void setSource(const SourceCode& source) { m_source = source; }
-        ParserArena m_arena;
-
         int m_startLineNumber;
         unsigned m_startStartOffset;
         unsigned m_startLineStartOffset;
@@ -1471,29 +1598,26 @@ namespace JSC {
 
     class ProgramNode : public ScopeNode {
     public:
-        static const bool isFunctionNode = false;
-        static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
 
         static const bool scopeIsFunction = false;
 
-        void setClosedVariables(Vector<RefPtr<StringImpl>>&&);
-        const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
-    private:
-        ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&);
+        const Vector<RefPtr<UniquedStringImpl>>& closedVariables() const { return m_closedVariables; }
 
+    private:
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-        Vector<RefPtr<StringImpl>> m_closedVariables;
+        Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
         unsigned m_startColumn;
         unsigned m_endColumn;
     };
 
     class EvalNode : public ScopeNode {
     public:
-        static const bool isFunctionNode = false;
-        static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
         ALWAYS_INLINE unsigned startColumn() const { return 0; }
         unsigned endColumn() const { return m_endColumn; }
@@ -1501,8 +1625,6 @@ namespace JSC {
         static const bool scopeIsFunction = false;
 
     private:
-        EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
-
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         unsigned m_endColumn;
@@ -1512,34 +1634,36 @@ namespace JSC {
         WTF_MAKE_FAST_ALLOCATED;
         WTF_MAKE_NONCOPYABLE(FunctionParameters);
     public:
-        static PassRefPtr<FunctionParameters> create(ParameterNode*);
+        static Ref<FunctionParameters> create(ParameterNode*);
         ~FunctionParameters();
 
         unsigned size() const { return m_size; }
-        DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
+        DestructuringPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
 
     private:
         FunctionParameters(ParameterNode*, unsigned size);
 
-        DeconstructionPatternNode** patterns() { return &m_storage; }
+        DestructuringPatternNode** patterns() { return &m_storage; }
 
         unsigned m_size;
-        DeconstructionPatternNode* m_storage;
+        DestructuringPatternNode* m_storage;
     };
 
-    class FunctionBodyNode : public ScopeNode {
+    class FunctionBodyNode final : public StatementNode, public ParserArenaDeletable {
     public:
-        static const bool isFunctionNode = true;
-        static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isStrictMode);
-        static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        using ParserArenaDeletable::operator new;
+
+        FunctionBodyNode(
+            ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, 
+            unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
+            int functionNameStart, int parametersStart, bool isInStrictContext, 
+            ConstructorKind);
 
         FunctionParameters* parameters() const { return m_parameters.get(); }
-        size_t parameterCount() const { return m_parameters->size(); }
 
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
-        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
         
         void overrideName(const Identifier& ident) { m_ident = ident; }
         const Identifier& ident() { return m_ident; }
@@ -1548,24 +1672,59 @@ namespace JSC {
 
         FunctionMode functionMode() { return m_functionMode; }
 
-        void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; }
         int functionNameStart() const { return m_functionNameStart; }
+        int functionKeywordStart() const { return m_functionKeywordStart; }
+        int parametersStart() const { return m_parametersStart; }
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
 
         void setEndPosition(JSTextPosition);
 
-        static const bool scopeIsFunction = true;
+        const SourceCode& source() const { return m_source; }
 
-    private:
-        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool inStrictContext);
-        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        int startStartOffset() const { return m_startStartOffset; }
+        bool isInStrictContext() const { return m_isInStrictContext; }
+        ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
 
+    protected:
         Identifier m_ident;
         Identifier m_inferredName;
         FunctionMode m_functionMode;
         RefPtr<FunctionParameters> m_parameters;
+        unsigned m_startColumn;
+        unsigned m_endColumn;
+        int m_functionKeywordStart;
         int m_functionNameStart;
+        int m_parametersStart;
+        SourceCode m_source;
+        int m_startStartOffset;
+        unsigned m_isInStrictContext : 1;
+        unsigned m_constructorKind : 2;
+    };
+
+    class FunctionNode final : public ScopeNode {
+    public:
+        FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        FunctionParameters* parameters() const { return m_parameters.get(); }
+
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
+        
+        const Identifier& ident() { return m_ident; }
+
+        FunctionMode functionMode() { return m_functionMode; }
+
+        unsigned startColumn() const { return m_startColumn; }
+        unsigned endColumn() const { return m_endColumn; }
+
+        static const bool scopeIsFunction = true;
+
+    private:
+        Identifier m_ident;
+        FunctionMode m_functionMode;
+        RefPtr<FunctionParameters> m_parameters;
         unsigned m_startColumn;
         unsigned m_endColumn;
     };
@@ -1584,8 +1743,27 @@ namespace JSC {
         FunctionBodyNode* m_body;
     };
 
-    class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
-        WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
+#if ENABLE(ES6_CLASS_SYNTAX)
+    class ClassExprNode final : public ExpressionNode {
+    public:
+        ClassExprNode(const JSTokenLocation&, const Identifier&, ExpressionNode* constructorExpresssion,
+            ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
+
+        const Identifier& name() { return m_name; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_name;
+        ExpressionNode* m_constructorExpression;
+        ExpressionNode* m_classHeritage;
+        PropertyListNode* m_instanceMethods;
+        PropertyListNode* m_staticMethods;
+    };
+#endif
+
+    class DestructuringPatternNode : public RefCounted<DestructuringPatternNode> {
+        WTF_MAKE_NONCOPYABLE(DestructuringPatternNode);
         WTF_MAKE_FAST_ALLOCATED;
 
     public:
@@ -1596,67 +1774,73 @@ namespace JSC {
         virtual bool isBindingNode() const { return false; }
         virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
         
-        virtual ~DeconstructionPatternNode() = 0;
+        virtual ~DestructuringPatternNode() = 0;
         
     protected:
-        DeconstructionPatternNode(VM*);
+        DestructuringPatternNode();
     };
 
-    class ArrayPatternNode : public DeconstructionPatternNode {
+    class ArrayPatternNode : public DestructuringPatternNode, public ThrowableExpressionData {
     public:
-        static PassRefPtr<ArrayPatternNode> create(VM*);
-        void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
+        enum class BindingType {
+            Elision,
+            Element,
+            RestElement
+        };
+
+        static Ref<ArrayPatternNode> create();
+        void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue)
         {
-            m_targetPatterns.append(node);
+            m_targetPatterns.append({ bindingType, node, defaultValue });
         }
 
     private:
-        ArrayPatternNode(VM*);
+        struct Entry {
+            BindingType bindingType;
+            RefPtr<DestructuringPatternNode> pattern;
+            ExpressionNode* defaultValue;
+        };
+        ArrayPatternNode();
         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
         virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
         virtual void toString(StringBuilder&) const override;
 
-        Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
+        Vector<Entry> m_targetPatterns;
     };
     
-    class ObjectPatternNode : public DeconstructionPatternNode {
+    class ObjectPatternNode : public DestructuringPatternNode {
     public:
-        static PassRefPtr<ObjectPatternNode> create(VM*);
-        void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
+        static Ref<ObjectPatternNode> create();
+        void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
         {
-            m_targetPatterns.append(Entry(identifier, wasString, pattern));
+            m_targetPatterns.append(Entry{ identifier, wasString, pattern, defaultValue });
         }
         
     private:
-        ObjectPatternNode(VM*);
+        ObjectPatternNode();
         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
         virtual void toString(StringBuilder&) const override;
         struct Entry {
-            Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
-                : propertyName(propertyName)
-                , wasString(wasString)
-                , pattern(pattern)
-            {
-            }
             Identifier propertyName;
             bool wasString;
-            RefPtr<DeconstructionPatternNode> pattern;
+            RefPtr<DestructuringPatternNode> pattern;
+            ExpressionNode* defaultValue;
         };
         Vector<Entry> m_targetPatterns;
     };
 
-    class BindingNode : public DeconstructionPatternNode {
+    class BindingNode : public DestructuringPatternNode {
     public:
-        static PassRefPtr<BindingNode> create(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+        static Ref<BindingNode> create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
         const Identifier& boundProperty() const { return m_boundProperty; }
 
         const JSTextPosition& divotStart() const { return m_divotStart; }
         const JSTextPosition& divotEnd() const { return m_divotEnd; }
         
     private:
-        BindingNode(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+        BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
 
         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
@@ -1669,19 +1853,19 @@ namespace JSC {
         Identifier m_boundProperty;
     };
 
-    class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+    class DestructuringAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
     public:
-        DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
-        DeconstructionPatternNode* bindings() { return m_bindings.get(); }
+        DestructuringAssignmentNode(const JSTokenLocation&, PassRefPtr<DestructuringPatternNode>, ExpressionNode*);
+        DestructuringPatternNode* bindings() { return m_bindings.get(); }
         
         using ParserArenaDeletable::operator new;
 
     private:
         virtual bool isAssignmentLocation() const override { return true; }
-        virtual bool isDeconstructionNode() const override { return true; }
+        virtual bool isDestructuringNode() const override { return true; }
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        RefPtr<DeconstructionPatternNode> m_bindings;
+        RefPtr<DestructuringPatternNode> m_bindings;
         ExpressionNode* m_initializer;
     };
 
@@ -1689,6 +1873,7 @@ namespace JSC {
     public:
         FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
+        virtual bool isFuncDeclNode() const override { return true; }
         FunctionBodyNode* body() { return m_body; }
 
     private:
@@ -1697,6 +1882,18 @@ namespace JSC {
         FunctionBodyNode* m_body;
     };
 
+#if ENABLE(ES6_CLASS_SYNTAX)
+    class ClassDeclNode final : public StatementNode {
+    public:
+        ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
+
+    private:
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        ExpressionNode* m_classDeclaration;
+    };
+#endif
+
     class CaseClauseNode : public ParserArenaFreeable {
     public:
         CaseClauseNode(ExpressionNode*, SourceElements* = 0);
@@ -1704,10 +1901,12 @@ namespace JSC {
         ExpressionNode* expr() const { return m_expr; }
 
         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
+        void setStartOffset(int offset) { m_startOffset = offset; }
 
     private:
         ExpressionNode* m_expr;
         SourceElements* m_statements;
+        int m_startOffset;
     };
 
     class ClauseListNode : public ParserArenaFreeable {
index d1d50b6a612901904ebb189e45906d40d9245304..be88dd2556764ce7ea136febb38165d91a3e5d7a 100644 (file)
 #include "Debugger.h"
 #include "JSCJSValueInlines.h"
 #include "Lexer.h"
-#include "NodeInfo.h"
 #include "JSCInlines.h"
 #include "SourceProvider.h"
 #include "VM.h"
 #include <utility>
 #include <wtf/HashFunctions.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/StringPrintStream.h>
 #include <wtf/WTFThreadData.h>
 
@@ -192,7 +190,11 @@ void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B
 }
 
 template <typename LexerType>
-Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
+Parser<LexerType>::Parser(
+    VM* vm, const SourceCode& source, FunctionParameters* parameters, 
+    const Identifier& name, JSParserBuiltinMode builtinMode, 
+    JSParserStrictMode strictMode, JSParserCodeType codeType, 
+    ConstructorKind defaultConstructorKind, ThisTDZMode thisTDZMode)
     : m_vm(vm)
     , m_source(&source)
     , m_hasStackOverflow(false)
@@ -205,20 +207,21 @@ Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters*
     , m_lastIdentifier(0)
     , m_lastFunctionName(nullptr)
     , m_sourceElements(0)
-    , m_parsingBuiltin(strictness == JSParseBuiltin)
+    , m_parsingBuiltin(builtinMode == JSParserBuiltinMode::Builtin)
+    , m_defaultConstructorKind(defaultConstructorKind)
+    , m_thisTDZMode(thisTDZMode)
 {
-    m_lexer = adoptPtr(new LexerType(vm, strictness));
-    m_arena = m_vm->parserArena.get();
-    m_lexer->setCode(source, m_arena);
+    m_lexer = std::make_unique<LexerType>(vm, builtinMode);
+    m_lexer->setCode(source, &m_parserArena);
     m_token.m_location.line = source.firstLine();
     m_token.m_location.startOffset = source.startOffset();
     m_token.m_location.endOffset = source.startOffset();
     m_token.m_location.lineStartOffset = source.startOffset();
     m_functionCache = vm->addSourceProviderCache(source.provider());
     ScopeRef scope = pushScope();
-    if (parserMode == JSParseFunctionCode)
+    if (codeType == JSParserCodeType::Function)
         scope->setIsFunction();
-    if (strictness == JSParseStrict)
+    if (strictMode == JSParserStrictMode::Strict)
         scope->setStrictMode();
     if (parameters) {
         bool hadBindingParameters = false;
@@ -257,11 +260,11 @@ String Parser<LexerType>::parseInner()
 {
     String parseError = String();
     
-    ASTBuilder context(const_cast<VM*>(m_vm), const_cast<SourceCode*>(m_source));
+    ASTBuilder context(const_cast<VM*>(m_vm), m_parserArena, const_cast<SourceCode*>(m_source));
     if (m_lexer->isReparsing())
         m_statementDepth--;
     ScopeRef scope = currentScope();
-    SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode);
+    SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode, StandardFunctionParseType);
     if (!sourceElements || !consume(EOFTOK)) {
         if (hasError())
             parseError = m_errorMessage;
@@ -271,7 +274,8 @@ String Parser<LexerType>::parseInner()
 
     IdentifierSet capturedVariables;
     bool modifiedParameter = false;
-    scope->getCapturedVariables(capturedVariables, modifiedParameter);
+    bool modifiedArguments = false;
+    scope->getCapturedVariables(capturedVariables, modifiedParameter, modifiedArguments);
     
     CodeFeatures features = context.features();
     if (scope->strictMode())
@@ -280,20 +284,38 @@ String Parser<LexerType>::parseInner()
         features |= ShadowsArgumentsFeature;
     if (modifiedParameter)
         features |= ModifiedParameterFeature;
-    
-    Vector<RefPtr<StringImpl>> closedVariables;
+    if (modifiedArguments)
+        features |= ModifiedArgumentsFeature;
+    Vector<RefPtr<UniquedStringImpl>> closedVariables;
     if (m_parsingBuiltin) {
-        RELEASE_ASSERT(!capturedVariables.size());
         IdentifierSet usedVariables;
         scope->getUsedVariables(usedVariables);
         for (const auto& variable : usedVariables) {
-            if (scope->hasDeclaredVariable(Identifier(m_vm, variable.get())))
+            Identifier identifier = Identifier::fromUid(m_vm, variable.get());
+            if (scope->hasDeclaredVariable(identifier))
                 continue;
             
-            if (scope->hasDeclaredParameter(Identifier(m_vm, variable.get())))
+            if (scope->hasDeclaredParameter(identifier))
+                continue;
+
+            if (variable == m_vm->propertyNames->arguments.impl())
                 continue;
+
             closedVariables.append(variable);
         }
+
+        if (!capturedVariables.isEmpty()) {
+            for (const auto& capturedVariable : capturedVariables) {
+                Identifier identifier = Identifier::fromUid(m_vm, capturedVariable.get());
+                if (scope->hasDeclaredVariable(identifier))
+                    continue;
+
+                if (scope->hasDeclaredParameter(identifier))
+                    continue;
+
+                RELEASE_ASSERT_NOT_REACHED();
+            }
+        }
     }
     didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
         context.numConstants(), capturedVariables, WTF::move(closedVariables));
@@ -302,12 +324,12 @@ String Parser<LexerType>::parseInner()
 }
 
 template <typename LexerType>
-void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 
-    ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars, const Vector<RefPtr<StringImpl>>&& closedVariables)
+void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, DeclarationStacks::VarStack& varStack, 
+    DeclarationStacks::FunctionStack& funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars, const Vector<RefPtr<UniquedStringImpl>>&& closedVariables)
 {
     m_sourceElements = sourceElements;
-    m_varDeclarations = varStack;
-    m_funcDeclarations = funcStack;
+    m_varDeclarations.swap(varStack);
+    m_funcDeclarations.swap(funcStack);
     m_capturedVariables.swap(capturedVars);
     m_closedVariables = closedVariables;
     m_features = features;
@@ -321,7 +343,7 @@ bool Parser<LexerType>::allowAutomaticSemicolon()
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode)
+template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode, FunctionParseType functionParseType)
 {
     const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length
     TreeSourceElements sourceElements = context.createSourceElements();
@@ -330,7 +352,24 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceEl
     unsigned directiveLiteralLength = 0;
     auto savePoint = createSavePoint();
     bool hasSetStrict = false;
-    while (TreeStatement statement = parseStatement(context, directive, &directiveLiteralLength)) {
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    if (match(ARROWFUNCTION)) {
+        TreeStatement arrowfunctionStatement = parseArrowFunctionSingleExpressionBody(context, functionParseType);
+            
+        if (arrowfunctionStatement) {
+            context.setEndOffset(arrowfunctionStatement, m_lastTokenEndPosition.offset);
+            context.appendStatement(sourceElements, arrowfunctionStatement);
+        }
+        
+        propagateError();
+        return sourceElements;
+    }
+#else
+    UNUSED_PARAM(functionParseType);
+#endif
+    
+    while (TreeStatement statement = parseStatementListItem(context, directive, &directiveLiteralLength)) {
         if (mode == CheckForStrictMode && !seenNonDirective) {
             if (directive) {
                 // "use strict" must be the exact literal without escape sequences or line continuation.
@@ -363,6 +402,30 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceEl
     propagateError();
     return sourceElements;
 }
+template <typename LexerType>
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
+{
+    // The grammar is documented here:
+    // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
+    TreeStatement result = 0;
+    switch (m_token.m_type) {
+    case CONSTTOKEN:
+        result = parseConstDeclaration(context);
+        break;
+#if ENABLE(ES6_CLASS_SYNTAX)
+    case CLASSTOKEN:
+        result = parseClassDeclaration(context);
+        break;
+#endif
+    default:
+        // FIXME: This needs to consider 'let' in bug:
+        // https://bugs.webkit.org/show_bug.cgi?id=142944
+        result = parseStatement(context, directive, directiveLiteralLength);
+        break;
+    }
+
+    return result;
+}
 
 template <typename LexerType>
 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaration(TreeBuilder& context)
@@ -372,10 +435,10 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaratio
     int start = tokenLine();
     int end = 0;
     int scratch;
-    TreeDeconstructionPattern scratch1 = 0;
+    TreeDestructuringPattern scratch1 = 0;
     TreeExpression scratch2 = 0;
     JSTextPosition scratch3;
-    TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3);
+    TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext);
     propagateError();
     failIfFalse(autoSemiColon(), "Expected ';' after var declaration");
     
@@ -444,13 +507,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatemen
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd)
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext)
 {
-    TreeExpression varDecls = 0;
+    TreeExpression head = 0;
+    TreeExpression tail = 0;
     const Identifier* lastIdent;
+    JSToken lastIdentToken; 
     do {
         lastIdent = 0;
-        lastPattern = 0;
+        lastPattern = TreeDestructuringPattern(0);
         JSTokenLocation location(tokenLocation());
         next();
         TreeExpression node = 0;
@@ -458,9 +523,11 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
         bool hasInitializer = false;
         if (match(IDENT)) {
             JSTextPosition varStart = tokenStartPosition();
+            JSTokenLocation varStartLocation(tokenLocation());
             identStart = varStart;
             const Identifier* name = m_token.m_data.ident;
             lastIdent = name;
+            lastIdentToken = m_token;
             next();
             hasInitializer = match(EQUAL);
             failIfFalseIfStrict(declareVariable(name), "Cannot declare a variable named ", name->impl(), " in strict mode");
@@ -475,74 +542,76 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
                 failIfFalse(initializer, "Expected expression as the intializer for the variable '", name->impl(), "'");
                 
                 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition());
-            }
+            } else
+                node = context.createEmptyVarExpression(varStartLocation, *name);
         } else {
             lastIdent = 0;
-            auto pattern = parseDeconstructionPattern(context, DeconstructToVariables);
-            failIfFalse(pattern, "Cannot parse this deconstruction pattern");
+            auto pattern = parseDestructuringPattern(context, DestructureToVariables);
+            failIfFalse(pattern, "Cannot parse this destructuring pattern");
             hasInitializer = match(EQUAL);
+            failIfTrue(declarationListContext == VarDeclarationContext && !hasInitializer, "Expected an initializer in destructuring variable declaration");
             lastPattern = pattern;
             if (hasInitializer) {
                 next(TreeBuilder::DontBuildStrings); // consume '='
-                TreeExpression rhs = parseExpression(context);
-                node = context.createDeconstructingAssignment(location, pattern, rhs);
+                TreeExpression rhs = parseAssignmentExpression(context);
+                node = context.createDestructuringAssignment(location, pattern, rhs);
                 lastInitializer = rhs;
             }
         }
         
-        if (hasInitializer) {
-            if (!varDecls)
-                varDecls = node;
-            else
-                varDecls = context.combineCommaNodes(location, varDecls, node);
-        }
+        if (!head)
+            head = node;
+        else if (!tail) {
+            head = context.createCommaExpr(location, head);
+            tail = context.appendToCommaExpr(location, head, head, node);
+        } else
+            tail = context.appendToCommaExpr(location, head, tail, node);
     } while (match(COMMA));
     if (lastIdent)
-        lastPattern = createBindingPattern(context, DeconstructToVariables, *lastIdent, 0);
-    return varDecls;
+        lastPattern = createBindingPattern(context, DestructureToVariables, *lastIdent, 0, lastIdentToken);
+    return head;
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DeconstructionKind kind, const Identifier& name, int depth)
+template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token)
 {
-    ASSERT(!name.isEmpty());
     ASSERT(!name.isNull());
     
-    ASSERT(name.impl()->isAtomic());
+    ASSERT(name.impl()->isAtomic() || name.impl()->isSymbol());
     if (depth) {
-        if (kind == DeconstructToVariables)
-            failIfFalseIfStrict(declareVariable(&name), "Cannot deconstruct to a variable named '", name.impl(), "' in strict mode");
-        if (kind == DeconstructToParameters) {
+        if (kind == DestructureToVariables)
+            failIfFalseIfStrict(declareVariable(&name), "Cannot destructure to a variable named '", name.impl(), "' in strict mode");
+        if (kind == DestructureToParameters) {
             auto bindingResult = declareBoundParameter(&name);
             if (bindingResult == Scope::StrictBindingFailed && strictMode()) {
-                semanticFailIfTrue(m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot deconstruct to a parameter name '", name.impl(), "' in strict mode");
+                semanticFailIfTrue(m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot destructure to a parameter name '", name.impl(), "' in strict mode");
                 if (m_lastFunctionName && name == *m_lastFunctionName)
-                    semanticFail("Cannot deconstruct to '", name.impl(), "' as it shadows the name of a strict mode function");
+                    semanticFail("Cannot destructure to '", name.impl(), "' as it shadows the name of a strict mode function");
                 semanticFailureDueToKeyword("bound parameter name");
                 if (hasDeclaredParameter(name))
-                    semanticFail("Cannot deconstruct to '", name.impl(), "' as it has already been declared");
+                    semanticFail("Cannot destructure to '", name.impl(), "' as it has already been declared");
                 semanticFail("Cannot bind to a parameter named '", name.impl(), "' in strict mode");
             }
             if (bindingResult == Scope::BindingFailed) {
                 semanticFailureDueToKeyword("bound parameter name");
                 if (hasDeclaredParameter(name))
-                    semanticFail("Cannot deconstruct to '", name.impl(), "' as it has already been declared");
-                semanticFail("Cannot deconstruct to a parameter named '", name.impl(), "'");
+                    semanticFail("Cannot destructure to '", name.impl(), "' as it has already been declared");
+                semanticFail("Cannot destructure to a parameter named '", name.impl(), "'");
             }
         }
-        if (kind != DeconstructToExpressions)
+        if (kind != DestructureToExpressions)
             context.addVar(&name, DeclarationStacks::HasInitializer);
 
     } else {
-        if (kind == DeconstructToVariables) {
+        if (kind == DestructureToVariables) {
             failIfFalseIfStrict(declareVariable(&name), "Cannot declare a variable named '", name.impl(), "' in strict mode");
             context.addVar(&name, DeclarationStacks::HasInitializer);
         }
         
-        if (kind == DeconstructToParameters) {
+        if (kind == DestructureToParameters) {
             bool declarationResult = declareParameter(&name);
             if (!declarationResult && strictMode()) {
-                semanticFailIfTrue(m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot deconstruct to a parameter name '", name.impl(), "' in strict mode");
+                semanticFailIfTrue(m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot destructure to a parameter name '", name.impl(), "' in strict mode");
                 if (m_lastFunctionName && name == *m_lastFunctionName)
                     semanticFail("Cannot declare a parameter named '", name.impl(), "' as it shadows the name of a strict mode function");
                 semanticFailureDueToKeyword("parameter name");
@@ -552,73 +621,133 @@ template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::create
             }
         }
     }
-    return context.createBindingLocation(m_token.m_location, name, m_token.m_startPosition, m_token.m_endPosition);
+    return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition);
 }
 
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
 template <typename LexerType>
-template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::tryParseDeconstructionPatternExpression(TreeBuilder& context)
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseArrowFunctionSingleExpressionBody(TreeBuilder& context, FunctionParseType parseType)
 {
-    return parseDeconstructionPattern(context, DeconstructToExpressions);
+    ASSERT(match(ARROWFUNCTION));
+
+    // When reparsing phase, parseType becomes StandardFunctionParseType even if the function is arrow function.
+    // This condition considers the following situations.
+    // (1): If we are in the reparsing phase, this arrow function is already parsed once, so there is no syntax error.
+    // (2): But if we are not in the reparsing phase, we should check this function is called in the context of the arrow function.
+    if (!m_lexer->isReparsing() && parseType != ArrowFunctionParseType)
+        failDueToUnexpectedToken();
+    
+    JSTokenLocation location(tokenLocation());
+    JSTextPosition start = tokenStartPosition();
+    JSTextPosition end = tokenEndPosition();
+
+    next();
+
+    failIfStackOverflow();
+    TreeExpression expr = parseAssignmentExpression(context);
+    failIfFalse(expr, "Cannot parse the arrow function expression");
+    
+    context.setEndOffset(expr, m_lastTokenEndPosition.offset);
+
+    failIfFalse(isEndOfArrowFunction(), "Expected a ';', ']', '}', ')', ',', line terminator or EOF following a arrow function statement");
+
+    end = tokenEndPosition();
+    
+    if (!m_lexer->prevTerminator())
+        setEndOfStatement();
+
+    return context.createReturnStatement(location, expr, start, end);
+}
+#endif
+
+template <typename LexerType>
+template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context)
+{
+    return parseDestructuringPattern(context, DestructureToExpressions);
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::parseDeconstructionPattern(TreeBuilder& context, DeconstructionKind kind, int depth)
+template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, int depth)
 {
     failIfStackOverflow();
     int nonLHSCount = m_nonLHSCount;
-    TreeDeconstructionPattern pattern;
+    TreeDestructuringPattern pattern;
     switch (m_token.m_type) {
     case OPENBRACKET: {
+        JSTextPosition divotStart = tokenStartPosition();
         auto arrayPattern = context.createArrayPattern(m_token.m_location);
         next();
-        if (kind == DeconstructToExpressions && match(CLOSEBRACKET))
-            return 0;
-        failIfTrue(match(CLOSEBRACKET), "There must be at least one bound property in an array deconstruction pattern");
+
+        bool restElementWasFound = false;
+
         do {
             while (match(COMMA)) {
                 context.appendArrayPatternSkipEntry(arrayPattern, m_token.m_location);
                 next();
             }
             propagateError();
+
+            if (match(CLOSEBRACKET))
+                break;
+
+            if (UNLIKELY(match(DOTDOTDOT))) {
+                JSTokenLocation location = m_token.m_location;
+                next();
+                auto innerPattern = parseDestructuringPattern(context, kind, depth + 1);
+                if (kind == DestructureToExpressions && !innerPattern)
+                    return 0;
+                failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
+
+                failIfTrue(kind != DestructureToExpressions && !context.isBindingNode(innerPattern),  "Expected identifier for a rest element destructuring pattern");
+
+                context.appendArrayPatternRestEntry(arrayPattern, location, innerPattern);
+                restElementWasFound = true;
+                break;
+            }
+
             JSTokenLocation location = m_token.m_location;
-            auto innerPattern = parseDeconstructionPattern(context, kind, depth + 1);
-            if (kind == DeconstructToExpressions && !innerPattern)
+            auto innerPattern = parseDestructuringPattern(context, kind, depth + 1);
+            if (kind == DestructureToExpressions && !innerPattern)
                 return 0;
-            failIfFalse(innerPattern, "Cannot parse this deconstruction pattern");
-            context.appendArrayPatternEntry(arrayPattern, location, innerPattern);
+            failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
+            TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context);
+            failIfTrue(kind == DestructureToParameters && defaultValue,  "Default values in destructuring parameters are currently not supported");
+            context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue);
         } while (consume(COMMA));
-        
-        if (kind == DeconstructToExpressions && !match(CLOSEBRACKET))
-            return 0;
 
-        consumeOrFail(CLOSEBRACKET, "Expected either a closing ']' or a ',' following an element deconstruction pattern");
+        if (kind == DestructureToExpressions && !match(CLOSEBRACKET))
+            return 0;
+        consumeOrFail(CLOSEBRACKET, restElementWasFound ? "Expected a closing ']' following a rest element destructuring pattern" : "Expected either a closing ']' or a ',' following an element destructuring pattern");
+        context.finishArrayPattern(arrayPattern, divotStart, divotStart, lastTokenEndPosition());
         pattern = arrayPattern;
         break;
     }
     case OPENBRACE: {
+        auto objectPattern = context.createObjectPattern(m_token.m_location);
         next();
-        
-        if (kind == DeconstructToExpressions && match(CLOSEBRACE))
-            return 0;
 
-        failIfTrue(match(CLOSEBRACE), "There must be at least one bound property in an object deconstruction pattern");
-        auto objectPattern = context.createObjectPattern(m_token.m_location);
-        bool wasString = false;
         do {
+            bool wasString = false;
+
+            if (match(CLOSEBRACE))
+                break;
+
             Identifier propertyName;
-            TreeDeconstructionPattern innerPattern = 0;
+            TreeDestructuringPattern innerPattern = 0;
             JSTokenLocation location = m_token.m_location;
             if (match(IDENT)) {
                 propertyName = *m_token.m_data.ident;
+                JSToken identifierToken = m_token;
                 next();
                 if (consume(COLON))
-                    innerPattern = parseDeconstructionPattern(context, kind, depth + 1);
+                    innerPattern = parseDestructuringPattern(context, kind, depth + 1);
                 else
-                    innerPattern = createBindingPattern(context, kind, propertyName, depth);
+                    innerPattern = createBindingPattern(context, kind, propertyName, depth, identifierToken);
             } else {
                 JSTokenType tokenType = m_token.m_type;
                 switch (m_token.m_type) {
-                case NUMBER:
+                case DOUBLE:
+                case INTEGER:
                     propertyName = Identifier::from(m_vm, m_token.m_data.doubleValue);
                     break;
                 case STRING:
@@ -627,7 +756,7 @@ template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::parseD
                     break;
                 default:
                     if (m_token.m_type != RESERVED && m_token.m_type != RESERVED_IF_STRICT && !(m_token.m_type & KeywordTokenFlag)) {
-                        if (kind == DeconstructToExpressions)
+                        if (kind == DestructureToExpressions)
                             return 0;
                         failWithMessage("Expected a property name");
                     }
@@ -636,36 +765,39 @@ template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::parseD
                 }
                 next();
                 if (!consume(COLON)) {
-                    if (kind == DeconstructToExpressions)
+                    if (kind == DestructureToExpressions)
                         return 0;
-                    semanticFailIfTrue(tokenType == RESERVED, "Cannot use abbreviated deconstruction syntax for reserved name '", propertyName.impl(), "'");
-                    semanticFailIfTrue(tokenType == RESERVED_IF_STRICT, "Cannot use abbreviated deconstruction syntax for reserved name '", propertyName.impl(), "' in strict mode");
-                    semanticFailIfTrue(tokenType & KeywordTokenFlag, "Cannot use abbreviated deconstruction syntax for keyword '", propertyName.impl(), "'");
+                    semanticFailIfTrue(tokenType == RESERVED, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName.impl(), "'");
+                    semanticFailIfTrue(tokenType == RESERVED_IF_STRICT, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName.impl(), "' in strict mode");
+                    semanticFailIfTrue(tokenType & KeywordTokenFlag, "Cannot use abbreviated destructuring syntax for keyword '", propertyName.impl(), "'");
                     
-                    failWithMessage("Expected a ':' prior to named property deconstruction");
+                    failWithMessage("Expected a ':' prior to a named destructuring property");
                 }
-                innerPattern = parseDeconstructionPattern(context, kind, depth + 1);
+                innerPattern = parseDestructuringPattern(context, kind, depth + 1);
             }
-            if (kind == DeconstructToExpressions && !innerPattern)
+            if (kind == DestructureToExpressions && !innerPattern)
                 return 0;
-            failIfFalse(innerPattern, "Cannot parse this deconstruction pattern");
-            context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern);
+            failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
+            TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context);
+            failIfTrue(kind == DestructureToParameters && defaultValue, "Default values in destructuring parameters are currently not supported");
+            context.appendObjectPatternEntry(objectPattern, location, wasString, propertyName, innerPattern, defaultValue);
         } while (consume(COMMA));
-        if (kind == DeconstructToExpressions && !match(CLOSEBRACE))
+
+        if (kind == DestructureToExpressions && !match(CLOSEBRACE))
             return 0;
-        consumeOrFail(CLOSEBRACE, "Expected either a closing '}' or an ',' after a property deconstruction pattern");
+        consumeOrFail(CLOSEBRACE, "Expected either a closing '}' or an ',' after a property destructuring pattern");
         pattern = objectPattern;
         break;
     }
 
     default: {
         if (!match(IDENT)) {
-            if (kind == DeconstructToExpressions)
+            if (kind == DestructureToExpressions)
                 return 0;
             semanticFailureDueToKeyword("variable name");
             failWithMessage("Expected a parameter pattern or a ')' in parameter list");
         }
-        pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth);
+        pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token);
         next();
         break;
     }
@@ -674,6 +806,16 @@ template <class TreeBuilder> TreeDeconstructionPattern Parser<LexerType>::parseD
     return pattern;
 }
 
+template <typename LexerType>
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseDefaultValueForDestructuringPattern(TreeBuilder& context)
+{
+    if (!match(EQUAL))
+        return 0;
+
+    next(TreeBuilder::DontBuildStrings); // consume '='
+    return parseAssignmentExpression(context);
+}
+
 template <typename LexerType>
 template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDeclarationList(TreeBuilder& context)
 {
@@ -716,18 +858,18 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
     JSTextPosition declsStart;
     JSTextPosition declsEnd;
     TreeExpression decls = 0;
-    TreeDeconstructionPattern pattern = 0;
+    TreeDestructuringPattern pattern = 0;
     if (match(VAR)) {
         /*
          for (var IDENT in expression) statement
          for (var varDeclarationList; expressionOpt; expressionOpt)
          */
-        TreeDeconstructionPattern forInTarget = 0;
+        TreeDestructuringPattern forInTarget = 0;
         TreeExpression forInInitializer = 0;
         m_allowsIn = false;
         JSTextPosition initStart;
         JSTextPosition initEnd;
-        decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd);
+        decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext);
         m_allowsIn = true;
         propagateError();
 
@@ -772,11 +914,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
         if (match(OPENBRACE) || match(OPENBRACKET)) {
             SavePoint savePoint = createSavePoint();
             declsStart = tokenStartPosition();
-            pattern = tryParseDeconstructionPatternExpression(context);
+            pattern = tryParseDestructuringPatternExpression(context);
             declsEnd = lastTokenEndPosition();
             if (pattern && (match(INTOKEN) || (match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of)))
                 goto enumerationLoop;
-            pattern = 0;
+            pattern = TreeDestructuringPattern(0);
             restoreSavePoint(savePoint);
         }
         m_allowsIn = false;
@@ -856,7 +998,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatemen
     
     if (autoSemiColon()) {
         semanticFailIfFalse(breakIsValid(), "'break' is only valid inside a switch or loop statement");
-        return context.createBreakStatement(location, start, end);
+        return context.createBreakStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
     }
     matchOrFail(IDENT, "Expected an identifier as the target for a break statement");
     const Identifier* ident = m_token.m_data.ident;
@@ -878,13 +1020,13 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState
     
     if (autoSemiColon()) {
         semanticFailIfFalse(continueIsValid(), "'continue' is only valid inside a loop statement");
-        return context.createContinueStatement(location, start, end);
+        return context.createContinueStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
     }
     matchOrFail(IDENT, "Expected an identifier as the target for a continue statement");
     const Identifier* ident = m_token.m_data.ident;
     ScopeLabelInfo* label = getLabel(ident);
     semanticFailIfFalse(label, "Cannot use the undeclared label '", ident->impl(), "'");
-    semanticFailIfFalse(label->m_isLoop, "Cannot continue to the label '", ident->impl(), "' as it is not targeting a loop");
+    semanticFailIfFalse(label->isLoop, "Cannot continue to the label '", ident->impl(), "' as it is not targeting a loop");
     end = tokenEndPosition();
     next();
     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted continue statement");
@@ -995,24 +1137,28 @@ template <class TreeBuilder> TreeClauseList Parser<LexerType>::parseSwitchClause
 {
     if (!match(CASE))
         return 0;
+    unsigned startOffset = tokenStart();
     next();
     TreeExpression condition = parseExpression(context);
     failIfFalse(condition, "Cannot parse switch clause");
     consumeOrFail(COLON, "Expected a ':' after switch clause expression");
-    TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
+    TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType);
     failIfFalse(statements, "Cannot parse the body of a switch clause");
     TreeClause clause = context.createClause(condition, statements);
+    context.setStartOffset(clause, startOffset);
     TreeClauseList clauseList = context.createClauseList(clause);
     TreeClauseList tail = clauseList;
     
     while (match(CASE)) {
+        startOffset = tokenStart();
         next();
         TreeExpression condition = parseExpression(context);
         failIfFalse(condition, "Cannot parse switch case expression");
         consumeOrFail(COLON, "Expected a ':' after switch clause expression");
-        TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
+        TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType);
         failIfFalse(statements, "Cannot parse the body of a switch clause");
         clause = context.createClause(condition, statements);
+        context.setStartOffset(clause, startOffset);
         tail = context.createClauseList(tail, clause);
     }
     return clauseList;
@@ -1023,11 +1169,14 @@ template <class TreeBuilder> TreeClause Parser<LexerType>::parseSwitchDefaultCla
 {
     if (!match(DEFAULT))
         return 0;
+    unsigned startOffset = tokenStart();
     next();
     consumeOrFail(COLON, "Expected a ':' after switch default clause");
-    TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
+    TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType);
     failIfFalse(statements, "Cannot parse the body of a switch default clause");
-    return context.createClause(0, statements);
+    TreeClause result = context.createClause(0, statements);
+    context.setStartOffset(result, startOffset);
+    return result;
 }
 
 template <typename LexerType>
@@ -1097,17 +1246,26 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatemen
 {
     ASSERT(match(OPENBRACE));
     JSTokenLocation location(tokenLocation());
+    int startOffset = m_token.m_data.offset;
     int start = tokenLine();
     next();
     if (match(CLOSEBRACE)) {
+        int endOffset = m_token.m_data.offset;
         next();
-        return context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line);
+        TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line);
+        context.setStartOffset(result, startOffset);
+        context.setEndOffset(result, endOffset);
+        return result;
     }
-    TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode);
+    TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType);
     failIfFalse(subtree, "Cannot parse the body of the block statement");
     matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement");
+    int endOffset = m_token.m_data.offset;
     next();
-    return context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line);
+    TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line);
+    context.setStartOffset(result, startOffset);
+    context.setEndOffset(result, endOffset);
+    return result;
 }
 
 template <typename LexerType>
@@ -1118,45 +1276,63 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
     directive = 0;
     int nonTrivialExpressionCount = 0;
     failIfStackOverflow();
+    TreeStatement result = 0;
+    bool shouldSetEndOffset = true;
+
     switch (m_token.m_type) {
     case OPENBRACE:
-        return parseBlockStatement(context);
+        result = parseBlockStatement(context);
+        shouldSetEndOffset = false;
+        break;
     case VAR:
-        return parseVarDeclaration(context);
-    case CONSTTOKEN:
-        return parseConstDeclaration(context);
+        result = parseVarDeclaration(context);
+        break;
     case FUNCTION:
         failIfFalseIfStrict(m_statementDepth == 1, "Strict mode does not allow function declarations in a lexically nested statement");
-        return parseFunctionDeclaration(context);
+        result = parseFunctionDeclaration(context);
+        break;
     case SEMICOLON: {
         JSTokenLocation location(tokenLocation());
         next();
-        return context.createEmptyStatement(location);
+        result = context.createEmptyStatement(location);
+        break;
     }
     case IF:
-        return parseIfStatement(context);
+        result = parseIfStatement(context);
+        break;
     case DO:
-        return parseDoWhileStatement(context);
+        result = parseDoWhileStatement(context);
+        break;
     case WHILE:
-        return parseWhileStatement(context);
+        result = parseWhileStatement(context);
+        break;
     case FOR:
-        return parseForStatement(context);
+        result = parseForStatement(context);
+        break;
     case CONTINUE:
-        return parseContinueStatement(context);
+        result = parseContinueStatement(context);
+        break;
     case BREAK:
-        return parseBreakStatement(context);
+        result = parseBreakStatement(context);
+        break;
     case RETURN:
-        return parseReturnStatement(context);
+        result = parseReturnStatement(context);
+        break;
     case WITH:
-        return parseWithStatement(context);
+        result = parseWithStatement(context);
+        break;
     case SWITCH:
-        return parseSwitchStatement(context);
+        result = parseSwitchStatement(context);
+        break;
     case THROW:
-        return parseThrowStatement(context);
+        result = parseThrowStatement(context);
+        break;
     case TRY:
-        return parseTryStatement(context);
+        result = parseTryStatement(context);
+        break;
     case DEBUGGER:
-        return parseDebuggerStatement(context);
+        result = parseDebuggerStatement(context);
+        break;
     case EOFTOK:
     case CASE:
     case CLOSEBRACE:
@@ -1164,7 +1340,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
         // These tokens imply the end of a set of source elements
         return 0;
     case IDENT:
-        return parseExpressionOrLabelStatement(context);
+        result = parseExpressionOrLabelStatement(context);
+        break;
     case STRING:
         directive = m_token.m_data.ident;
         if (directiveLiteralLength)
@@ -1175,19 +1352,24 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
         TreeStatement exprStatement = parseExpressionStatement(context);
         if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
             directive = 0;
-        return exprStatement;
+        result = exprStatement;
+        break;
     }
+
+    if (result && shouldSetEndOffset)
+        context.setEndOffset(result, m_lastTokenEndPosition.offset);
+    return result;
 }
 
 template <typename LexerType>
 template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFormalParameters(TreeBuilder& context)
 {
-    auto parameter = parseDeconstructionPattern(context, DeconstructToParameters);
+    auto parameter = parseDestructuringPattern(context, DestructureToParameters);
     failIfFalse(parameter, "Cannot parse parameter pattern");
     TreeFormalParameterList list = context.createFormalParameterList(parameter);
     TreeFormalParameterList tail = list;
     while (consume(COMMA)) {
-        parameter = parseDeconstructionPattern(context, DeconstructToParameters);
+        parameter = parseDestructuringPattern(context, DestructureToParameters);
         failIfFalse(parameter, "Cannot parse parameter pattern");
         tail = context.createFormalParameterList(tail, parameter);
     }
@@ -1195,22 +1377,31 @@ template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFor
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
+template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(
+    TreeBuilder& context, int functionKeywordStart, int functionNameStart, 
+    int parametersStart, ConstructorKind constructorKind, FunctionParseType parseType)
 {
     JSTokenLocation startLocation(tokenLocation());
     unsigned startColumn = tokenColumn();
-    next();
 
-    if (match(CLOSEBRACE)) {
-        unsigned endColumn = tokenColumn();
-        return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode());
+    if (parseType == StandardFunctionParseType) {
+        next();
+        if (match(CLOSEBRACE)) {
+            unsigned endColumn = tokenColumn();
+            return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind);
+        }
     }
+
     DepthManager statementDepth(&m_statementDepth);
     m_statementDepth = 0;
     typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<VM*>(m_vm), m_lexer.get());
-    failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode), "Cannot parse body of this function");
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, parseType), parseType == StandardFunctionParseType ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
+#else
+    failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, StandardFunctionParseType), "Cannot parse body of this function");
+#endif
     unsigned endColumn = tokenColumn();
-    return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode());
+    return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind);
 }
 
 static const char* stringForFunctionMode(FunctionParseMode mode)
@@ -1222,118 +1413,299 @@ static const char* stringForFunctionMode(FunctionParseMode mode)
         return "setter";
     case FunctionMode:
         return "function";
+    case MethodMode:
+        return "method";
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    case ArrowFunctionMode:
+        return "arrow function";
+#endif
     }
     RELEASE_ASSERT_NOT_REACHED();
     return nullptr;
 }
 
+template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, FunctionParseMode mode, ParserFunctionInfo<TreeBuilder>& info)
+{
+    int parametersStart = m_token.m_location.startOffset;
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    if (mode == ArrowFunctionMode) {
+        if (!match(IDENT) && !match(OPENPAREN)) {
+            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
+            failWithMessage("Expected an arrow function input parameter");
+        } else {
+            if (match(OPENPAREN)) {
+                next();
+                
+                if (!match(CLOSEPAREN)) {
+                    info.parameters = parseFormalParameters(context);
+                    failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
+                }
+                
+                consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
+            } else {
+                auto parameter = parseDestructuringPattern(context, DestructureToParameters);
+                failIfFalse(parameter, "Cannot parse parameter pattern");
+                info.parameters = context.createFormalParameterList(parameter);
+                failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
+            }
+        }
+        
+        return parametersStart;
+    }
+#endif
+    
+    if (!consume(OPENPAREN)) {
+        semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
+        failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
+    }
+
+    if (mode == GetterMode)
+        consumeOrFail(CLOSEPAREN, "getter functions must have no parameters");
+    else if (mode == SetterMode) {
+        failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter");
+        auto parameter = parseDestructuringPattern(context, DestructureToParameters);
+        failIfFalse(parameter, "setter functions must have one parameter");
+        info.parameters = context.createFormalParameterList(parameter);
+        failIfTrue(match(COMMA), "setter functions must have one parameter");
+        consumeOrFail(CLOSEPAREN, "Expected a ')' after a parameter declaration");
+    } else {
+        if (!match(CLOSEPAREN)) {
+            info.parameters = parseFormalParameters(context);
+            failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
+        }
+        consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
+    }
+    
+    return parametersStart;
+}
+
 template <typename LexerType>
-template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn)
+template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& info, FunctionParseType parseType)
 {
     AutoPopScopeRef functionScope(this, pushScope());
     functionScope->setIsFunction();
     int functionNameStart = m_token.m_location.startOffset;
     const Identifier* lastFunctionName = m_lastFunctionName;
     m_lastFunctionName = nullptr;
-    if (match(IDENT)) {
-        name = m_token.m_data.ident;
-        m_lastFunctionName = name;
-        next();
-        if (!nameIsInContainingScope)
-            failIfFalseIfStrict(functionScope->declareVariable(name), "'", name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
-    } else if (requirements == FunctionNeedsName) {
-        if (match(OPENPAREN) && mode == FunctionMode)
-            semanticFail("Function statements must have a name");
-        semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
-        failDueToUnexpectedToken();
-        return false;
+    int parametersStart;
+    
+    switch (parseType) {
+    case StandardFunctionParseType: {
+        if (match(IDENT)) {
+            info.name = m_token.m_data.ident;
+            m_lastFunctionName = info.name;
+            next();
+            if (!nameIsInContainingScope)
+                failIfFalseIfStrict(functionScope->declareVariable(info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
+        } else if (requirements == FunctionNeedsName) {
+            if (match(OPENPAREN) && mode == FunctionMode)
+                semanticFail("Function statements must have a name");
+            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
+            failDueToUnexpectedToken();
+            return false;
+        }
+        
+        parametersStart = parseFunctionParameters(context, mode, info);
+        propagateError();
+        
+        matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
+        
+        // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed.
+        // Set ConstructorKind to None for non-constructor methods of classes.
+    
+        if (m_defaultConstructorKind != ConstructorKind::None) {
+            constructorKind = m_defaultConstructorKind;
+            expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded;
+        }
+        
+        info.startFunctionOffset = m_token.m_data.offset;
+        
+        break;
     }
-    if (!consume(OPENPAREN)) {
-        semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
-        failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    case ArrowFunctionParseType: {
+        parametersStart = parseFunctionParameters(context, ArrowFunctionMode, info);
+        propagateError();
+        
+        matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration");
+        
+        if (m_lexer->prevTerminator())
+            failDueToUnexpectedToken();
+
+        ASSERT(constructorKind == ConstructorKind::None);
+        
+        info.arrowFunctionOffset = m_token.m_data.offset;
+        // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function
+        // and we need use common approach to parse function body
+        SavePoint savePoint = createSavePoint();
+        
+        next();
+        info.functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression;
+        info.startFunctionOffset = (info.functionBodyType == ArrowFunctionBodyBlock) ? m_token.m_data.offset : info.arrowFunctionOffset;
+        
+        restoreSavePoint(savePoint);
+
+        break;
     }
-    if (!match(CLOSEPAREN)) {
-        parameters = parseFormalParameters(context);
-        failIfFalse(parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
+#endif
     }
-    consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
-    matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
     
-    openBraceOffset = m_token.m_data.offset;
-    bodyStartLine = tokenLine();
-    bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
+    bool isClassConstructor = constructorKind != ConstructorKind::None;
+
+    info.bodyStartLine = tokenLine();
+    info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
     JSTokenLocation startLocation(tokenLocation());
     
     // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
-    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBraceOffset) : 0) {
+    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(info.startFunctionOffset) : 0) {
         // If we're in a strict context, the cached function info must say it was strict too.
         ASSERT(!strictMode() || cachedInfo->strictMode);
         JSTokenLocation endLocation;
 
-        endLocation.line = cachedInfo->closeBraceLine;
-        endLocation.startOffset = cachedInfo->closeBraceOffset;
-        endLocation.lineStartOffset = cachedInfo->closeBraceLineStartOffset;
+        endLocation.line = cachedInfo->lastTockenLine;
+        endLocation.startOffset = cachedInfo->lastTockenStartOffset;
+        endLocation.lineStartOffset = cachedInfo->lastTockenLineStartOffset;
 
-        bool endColumnIsOnStartLine = (endLocation.line == bodyStartLine);
+        bool endColumnIsOnStartLine = (endLocation.line == info.bodyStartLine);
         ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
         unsigned bodyEndColumn = endColumnIsOnStartLine ?
             endLocation.startOffset - m_token.m_data.lineStartOffset :
             endLocation.startOffset - endLocation.lineStartOffset;
+        unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;
 
-        body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);
+        info.body = context.createFunctionBody(
+            startLocation, endLocation, info.bodyStartColumn, bodyEndColumn, 
+            functionKeywordStart, functionNameStart, parametersStart, 
+            cachedInfo->strictMode, constructorKind);
         
         functionScope->restoreFromSourceProviderCache(cachedInfo);
         failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
         
-        closeBraceOffset = cachedInfo->closeBraceOffset;
-
-        context.setFunctionNameStart(body, functionNameStart);
-        m_token = cachedInfo->closeBraceToken();
+        m_token = cachedInfo->endFunctionToken();
+        
+        if (endColumnIsOnStartLine)
+            m_token.m_location.lineStartOffset = currentLineStartOffset;
 
         m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
         m_lexer->setLineNumber(m_token.m_location.line);
+        info.endFunctionOffset = cachedInfo->endFunctionOffset;
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+        if (parseType == ArrowFunctionParseType)
+            info.functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
+        else
+            info.functionBodyType = StandardFunctionBodyBlock;
         
+        switch (info.functionBodyType) {
+        case ArrowFunctionBodyExpression:
+            next();
+            context.setEndOffset(info.body, m_lexer->currentOffset());
+            break;
+        case ArrowFunctionBodyBlock:
+        case StandardFunctionBodyBlock:
+            context.setEndOffset(info.body, m_lexer->currentOffset());
+            next();
+            break;
+        }
+#else
+        context.setEndOffset(info.body, m_lexer->currentOffset());
         next();
+#endif
+        info.bodyEndLine = m_lastTokenEndPosition.line;
         return true;
     }
+    
     m_lastFunctionName = lastFunctionName;
     ParserState oldState = saveState();
-    body = parseFunctionBody(context);
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    switch (info.functionBodyType) {
+    case ArrowFunctionBodyBlock: {
+        // Consume => in case of arrow function block e.g. x => { return x; }
+        next();
+    
+        info.bodyStartLine = tokenLine();
+        info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
+            
+        info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType);
+        break;
+    }
+    case StandardFunctionBodyBlock:
+    case ArrowFunctionBodyExpression : {
+        info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, parseType);
+        break;
+    }
+    }
+#else
+    info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType);
+#endif
+    
     restoreState(oldState);
-    failIfFalse(body, "Cannot parse the body of this ", stringForFunctionMode(mode));
-    if (functionScope->strictMode() && name) {
-        RELEASE_ASSERT(mode == FunctionMode);
-        semanticFailIfTrue(m_vm->propertyNames->arguments == *name, "'", name->impl(), "' is not a valid function name in strict mode");
-        semanticFailIfTrue(m_vm->propertyNames->eval == *name, "'", name->impl(), "' is not a valid function name in strict mode");
+    failIfFalse(info.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
+    context.setEndOffset(info.body, m_lexer->currentOffset());
+    if (functionScope->strictMode() && info.name) {
+        RELEASE_ASSERT(mode == FunctionMode || mode == MethodMode);
+        semanticFailIfTrue(m_vm->propertyNames->arguments == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");
+        semanticFailIfTrue(m_vm->propertyNames->eval == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");
+    }
+    if (functionScope->hasDirectSuper()) {
+        semanticFailIfTrue(!isClassConstructor, "Cannot call super() outside of a class constructor");
+        semanticFailIfTrue(constructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor");
+    }
+    if (functionScope->needsSuperBinding())
+        semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
+
+    JSTokenLocation location = JSTokenLocation(m_token.m_location);
+    info.endFunctionOffset = m_token.m_data.offset;
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    if (info.functionBodyType == ArrowFunctionBodyExpression) {
+        location = locationBeforeLastToken();
+        info.endFunctionOffset = location.endOffset;
     }
-    closeBraceOffset = m_token.m_data.offset;
-    unsigned closeBraceLine = m_token.m_data.line;
-    unsigned closeBraceLineStartOffset = m_token.m_data.lineStartOffset;
+#endif
     
     // Cache the tokenizer state and the function scope the first time the function is parsed.
     // Any future reparsing can then skip the function.
     static const int minimumFunctionLengthToCache = 16;
     std::unique_ptr<SourceProviderCacheItem> newInfo;
-    int functionLength = closeBraceOffset - openBraceOffset;
+    int functionLength = info.endFunctionOffset - info.startFunctionOffset;
     if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
         SourceProviderCacheItemCreationParameters parameters;
+        parameters.endFunctionOffset = info.endFunctionOffset;
         parameters.functionNameStart = functionNameStart;
-        parameters.closeBraceLine = closeBraceLine;
-        parameters.closeBraceOffset = closeBraceOffset;
-        parameters.closeBraceLineStartOffset = closeBraceLineStartOffset;
+        parameters.lastTockenLine = location.line;
+        parameters.lastTockenStartOffset = location.startOffset;
+        parameters.lastTockenEndOffset = location.endOffset;
+        parameters.lastTockenLineStartOffset = location.lineStartOffset;
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+        if (info.functionBodyType == ArrowFunctionBodyExpression) {
+            parameters.isBodyArrowExpression = true;
+            parameters.tokenType = m_token.m_type;
+        }
+#endif
         functionScope->fillParametersForSourceProviderCache(parameters);
         newInfo = SourceProviderCacheItem::create(parameters);
-
     }
-    context.setFunctionNameStart(body, functionNameStart);
     
     failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    if (info.functionBodyType == ArrowFunctionBodyExpression)
+        failIfFalse(isEndOfArrowFunction(), "Expected the closing ';' ',' ']' ')' '}', line terminator or EOF after arrow function");
+    else {
+        matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");
+        next();
+    }
+#else
     matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");
+    next();
+#endif
     
     if (newInfo)
-        m_functionCache->add(openBraceOffset, WTF::move(newInfo));
+        m_functionCache->add(info.startFunctionOffset, WTF::move(newInfo));
     
-    next();
+    info.bodyEndLine = m_lastTokenEndPosition.line;
     return true;
 }
 
@@ -1342,20 +1714,165 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
 {
     ASSERT(match(FUNCTION));
     JSTokenLocation location(tokenLocation());
+    unsigned functionKeywordStart = tokenStart();
     next();
-    const Identifier* name = 0;
-    TreeFormalParameterList parameters = 0;
-    TreeFunctionBody body = 0;
-    unsigned openBraceOffset = 0;
-    unsigned closeBraceOffset = 0;
-    int bodyStartLine = 0;
-    unsigned bodyStartColumn = 0;
-    failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse this function");
-    failIfFalse(name, "Function statements must have a name");
-    failIfFalseIfStrict(declareVariable(name), "Cannot declare a function named '", name->impl(), "' in strict mode");
-    return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn);
+    ParserFunctionInfo<TreeBuilder> info;
+    failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded,
+        functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse this function");
+    failIfFalse(info.name, "Function statements must have a name");
+    failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode");
+    return context.createFuncDeclStatement(location, info);
+}
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+template <typename LexerType>
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context)
+{
+    ASSERT(match(CLASSTOKEN));
+    JSTokenLocation location(tokenLocation());
+    JSTextPosition classStart = tokenStartPosition();
+    unsigned classStartLine = tokenLine();
+
+    ParserClassInfo<TreeBuilder> info;
+    TreeClassExpression classExpr = parseClass(context, FunctionNeedsName, info);
+    failIfFalse(classExpr, "Failed to parse class");
+    declareVariable(info.className);
+
+    // FIXME: This should be like `let`, not `var`.
+    context.addVar(info.className, DeclarationStacks::HasInitializer);
+
+    JSTextPosition classEnd = lastTokenEndPosition();
+    unsigned classEndLine = tokenLine();
+
+    return context.createClassDeclStatement(location, classExpr, classStart, classEnd, classStartLine, classEndLine);
 }
 
+template <typename LexerType>
+template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionRequirements requirements, ParserClassInfo<TreeBuilder>& info)
+{
+    ASSERT(match(CLASSTOKEN));
+    JSTokenLocation location(tokenLocation());
+    next();
+
+    AutoPopScopeRef classScope(this, pushScope());
+    classScope->setStrictMode();
+
+    const Identifier* className = nullptr;
+    if (match(IDENT)) {
+        className = m_token.m_data.ident;
+        info.className = className;
+        next();
+        failIfFalse(classScope->declareVariable(className), "'", className->impl(), "' is not a valid class name");
+    } else if (requirements == FunctionNeedsName) {
+        if (match(OPENBRACE))
+            semanticFail("Class statements must have a name");
+        semanticFailureDueToKeyword("class name");
+        failDueToUnexpectedToken();
+    } else
+        className = &m_vm->propertyNames->nullIdentifier;
+    ASSERT(className);
+
+    TreeExpression parentClass = 0;
+    if (consume(EXTENDS)) {
+        parentClass = parseMemberExpression(context);
+        failIfFalse(parentClass, "Cannot parse the parent class name");
+    }
+    const ConstructorKind constructorKind = parentClass ? ConstructorKind::Derived : ConstructorKind::Base;
+
+    consumeOrFail(OPENBRACE, "Expected opening '{' at the start of a class body");
+
+    TreeExpression constructor = 0;
+    TreePropertyList staticMethods = 0;
+    TreePropertyList instanceMethods = 0;
+    TreePropertyList instanceMethodsTail = 0;
+    TreePropertyList staticMethodsTail = 0;
+    while (!match(CLOSEBRACE)) {
+        if (match(SEMICOLON)) {
+            next();
+            continue;
+        }
+
+        JSTokenLocation methodLocation(tokenLocation());
+        unsigned methodStart = tokenStart();
+
+        // For backwards compatibility, "static" is a non-reserved keyword in non-strict mode.
+        bool isStaticMethod = match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword;
+        if (isStaticMethod)
+            next();
+
+        // FIXME: Figure out a way to share more code with parseProperty.
+        const CommonIdentifiers& propertyNames = *m_vm->propertyNames;
+        const Identifier* ident = nullptr;
+        bool isGetter = false;
+        bool isSetter = false;
+        switch (m_token.m_type) {
+        case STRING:
+            ident = m_token.m_data.ident;
+            ASSERT(ident);
+            next();
+            break;
+        case IDENT:
+            ident = m_token.m_data.ident;
+            isGetter = *ident == propertyNames.get;
+            isSetter = *ident == propertyNames.set;
+            ASSERT(ident);
+            break;
+        case DOUBLE:
+        case INTEGER:
+            ident = &m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), m_token.m_data.doubleValue);
+            ASSERT(ident);
+            next();
+            break;
+        default:
+            failDueToUnexpectedToken();
+        }
+
+        TreeProperty property;
+        const bool alwaysStrictInsideClass = true;
+        if (isGetter || isSetter) {
+            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
+            property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart,
+                ConstructorKind::None, SuperBinding::Needed);
+            failIfFalse(property, "Cannot parse this method");
+        } else {
+            ParserFunctionInfo<TreeBuilder> methodInfo;
+            bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
+            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? FunctionMode : MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method");
+            failIfFalse(ident && declareVariable(ident), "Cannot declare a method named '", methodInfo.name->impl(), "'");
+            methodInfo.name = isConstructor ? className : ident;
+
+            TreeExpression method = context.createFunctionExpr(methodLocation, methodInfo);
+            if (isConstructor) {
+                semanticFailIfTrue(constructor, "Cannot declare multiple constructors in a single class");
+                constructor = method;
+                continue;
+            }
+
+            // FIXME: Syntax error when super() is called
+            semanticFailIfTrue(isStaticMethod && methodInfo.name && *methodInfo.name == propertyNames.prototype,
+                "Cannot declare a static method named 'prototype'");
+            property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
+        }
+
+        TreePropertyList& tail = isStaticMethod ? staticMethodsTail : instanceMethodsTail;
+        if (tail)
+            tail = context.createPropertyList(methodLocation, property, tail);
+        else {
+            tail = context.createPropertyList(methodLocation, property);
+            if (isStaticMethod)
+                staticMethods = tail;
+            else
+                instanceMethods = tail;
+        }
+    }
+
+    failIfFalse(popScope(classScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
+    consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
+
+    return context.createClassExpr(location, *className, constructor, parentClass, instanceMethods, staticMethods);
+}
+#endif
+
 struct LabelInfo {
     LabelInfo(const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
     : m_ident(ident)
@@ -1436,6 +1953,19 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
 template <typename LexerType>
 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
 {
+    switch (m_token.m_type) {
+    // Consult: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-expression-statement
+    // The ES6 spec mandates that we should fail from FUNCTION token here. We handle this case 
+    // in parseStatement() which is the only caller of parseExpressionStatement().
+    // We actually allow FUNCTION in situations where it should not be allowed unless we're in strict mode.
+    case CLASSTOKEN:
+        failWithMessage("'class' declaration is not directly within a block statement");
+        break;
+    default:
+        // FIXME: when implementing 'let' we should fail when we see the token sequence "let [".
+        // https://bugs.webkit.org/show_bug.cgi?id=142944
+        break;
+    }
     JSTextPosition start = tokenStartPosition();
     JSTokenLocation location(tokenLocation());
     TreeExpression expression = parseExpression(context);
@@ -1508,7 +2038,9 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
         posStack.removeLast();
         JSTokenLocation elseLocation = tokenLocationStack.last();
         tokenLocationStack.removeLast();
-        statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second));
+        TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second);
+        context.setEndOffset(ifStatement, context.endOffset(trueBlock));
+        statementStack.append(ifStatement);
     }
 
     while (!exprStack.isEmpty()) {
@@ -1522,7 +2054,9 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
         posStack.removeLast();
         JSTokenLocation elseLocation = tokenLocationStack.last();
         tokenLocationStack.removeLast();
-        statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second));
+        TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second);
+        context.setEndOffset(ifStatement, context.endOffset(falseBlock));
+        statementStack.append(ifStatement);
     }
 
     return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end);
@@ -1535,6 +2069,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(T
     JSTokenLocation location(tokenLocation());
     TreeExpression node = parseAssignmentExpression(context);
     failIfFalse(node, "Cannot parse expression");
+    context.setEndOffset(node, m_lastTokenEndPosition.offset);
     if (!match(COMMA))
         return node;
     next();
@@ -1542,16 +2077,21 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(T
     m_nonLHSCount++;
     TreeExpression right = parseAssignmentExpression(context);
     failIfFalse(right, "Cannot parse expression in a comma expression");
-    typename TreeBuilder::Comma commaNode = context.createCommaExpr(location, node, right);
+    context.setEndOffset(right, m_lastTokenEndPosition.offset);
+    typename TreeBuilder::Comma head = context.createCommaExpr(location, node);
+    typename TreeBuilder::Comma tail = context.appendToCommaExpr(location, head, head, right);
     while (match(COMMA)) {
         next(TreeBuilder::DontBuildStrings);
         right = parseAssignmentExpression(context);
         failIfFalse(right, "Cannot parse expression in a comma expression");
-        context.appendToComma(commaNode, right);
+        context.setEndOffset(right, m_lastTokenEndPosition.offset);
+        tail = context.appendToCommaExpr(location, head, tail, right);
     }
-    return commaNode;
+    context.setEndOffset(head, m_lastTokenEndPosition.offset);
+    return head;
 }
 
+    
 template <typename LexerType>
 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context)
 {
@@ -1562,14 +2102,20 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
     int initialNonLHSCount = m_nonLHSCount;
     if (match(OPENBRACE) || match(OPENBRACKET)) {
         SavePoint savePoint = createSavePoint();
-        auto pattern = tryParseDeconstructionPatternExpression(context);
+        auto pattern = tryParseDestructuringPatternExpression(context);
         if (pattern && consume(EQUAL)) {
             auto rhs = parseAssignmentExpression(context);
             if (rhs)
-                return context.createDeconstructingAssignment(location, pattern, rhs);
+                return context.createDestructuringAssignment(location, pattern, rhs);
         }
         restoreSavePoint(savePoint);
     }
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    if (isArrowFunctionParamters())
+        return parseArrowFunctionExpression(context);
+#endif
+    
     TreeExpression lhs = parseConditionalExpression(context);
     failIfFalse(lhs, "Cannot parse expression");
     if (initialNonLHSCount != m_nonLHSCount) {
@@ -1645,10 +2191,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalE
     next(TreeBuilder::DontBuildStrings);
     TreeExpression lhs = parseAssignmentExpression(context);
     failIfFalse(lhs, "Cannot parse left hand side of ternary operator");
+    context.setEndOffset(lhs, m_lastTokenEndPosition.offset);
     consumeOrFailWithFlags(COLON, TreeBuilder::DontBuildStrings, "Expected ':' in ternary operator");
     
     TreeExpression rhs = parseAssignmentExpression(context);
     failIfFalse(rhs, "Cannot parse right hand side of ternary operator");
+    context.setEndOffset(rhs, m_lastTokenEndPosition.offset);
     return context.createConditionalExpr(location, cond, lhs, rhs);
 }
 
@@ -1668,7 +2216,6 @@ int Parser<LexerType>::isBinaryOperator(JSTokenType token)
 template <typename LexerType>
 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpression(TreeBuilder& context)
 {
-    
     int operandStackDepth = 0;
     int operatorStackDepth = 0;
     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
@@ -1722,25 +2269,36 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
         FALLTHROUGH;
     case STRING: {
         const Identifier* ident = m_token.m_data.ident;
+        unsigned getterOrSetterStartOffset = tokenStart();
         if (complete || (wasIdent && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
             nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
         else
             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
-        
+
         if (match(COLON)) {
             next();
             TreeExpression node = parseAssignmentExpression(context);
             failIfFalse(node, "Cannot parse expression for property declaration");
-            return context.createProperty(ident, node, PropertyNode::Constant, complete);
+            context.setEndOffset(node, m_lexer->currentOffset());
+            return context.createProperty(ident, node, PropertyNode::Constant, PropertyNode::Unknown, complete);
         }
+
+        if (match(OPENPAREN)) {
+            auto method = parsePropertyMethod(context, ident);
+            propagateError();
+            return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete);
+        }
+
         failIfFalse(wasIdent, "Expected an identifier as property name");
-        const Identifier* accessorName = 0;
-        TreeFormalParameterList parameters = 0;
-        TreeFunctionBody body = 0;
-        unsigned openBraceOffset = 0;
-        unsigned closeBraceOffset = 0;
-        int bodyStartLine = 0;
-        unsigned bodyStartColumn = 0;
+
+        if (match(COMMA) || match(CLOSEBRACE)) {
+            JSTextPosition start = tokenStartPosition();
+            JSTokenLocation location(tokenLocation());
+            currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
+            TreeExpression node = context.createResolve(location, ident, start);
+            return context.createProperty(ident, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Shorthand), PropertyNode::KnownDirect, complete);
+        }
+
         PropertyNode::Type type;
         if (*ident == m_vm->propertyNames->get)
             type = PropertyNode::Getter;
@@ -1748,45 +2306,43 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
             type = PropertyNode::Setter;
         else
             failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
-        const Identifier* stringPropertyName = 0;
-        double numericPropertyName = 0;
-        if (m_token.m_type == IDENT || m_token.m_type == STRING)
-            stringPropertyName = m_token.m_data.ident;
-        else if (m_token.m_type == NUMBER)
-            numericPropertyName = m_token.m_data.doubleValue;
-        else
-            failDueToUnexpectedToken();
-        JSTokenLocation location(tokenLocation());
-        next();
-        if (type == PropertyNode::Getter) {
-            failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition");
-            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse getter definition");
-        } else {
-            failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition");
-            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse setter definition");
-        }
-        if (stringPropertyName)
-            return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn);
-        return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), location, type, complete, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn);
+        return parseGetterSetter(context, complete, type, getterOrSetterStartOffset);
     }
-    case NUMBER: {
+    case DOUBLE:
+    case INTEGER: {
         double propertyName = m_token.m_data.doubleValue;
         next();
+
+        if (match(OPENPAREN)) {
+            const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
+            auto method = parsePropertyMethod(context, &ident);
+            propagateError();
+            return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete);
+        }
+
         consumeOrFail(COLON, "Expected ':' after property name");
         TreeExpression node = parseAssignmentExpression(context);
         failIfFalse(node, "Cannot parse expression for property declaration");
-        return context.createProperty(const_cast<VM*>(m_vm), propertyName, node, PropertyNode::Constant, complete);
+        context.setEndOffset(node, m_lexer->currentOffset());
+        return context.createProperty(const_cast<VM*>(m_vm), m_parserArena, propertyName, node, PropertyNode::Constant, PropertyNode::Unknown, complete);
     }
     case OPENBRACKET: {
         next();
-        auto propertyName = parseExpression(context);
+        auto propertyName = parseAssignmentExpression(context);
         failIfFalse(propertyName, "Cannot parse computed property name");
-        
         handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
+
+        if (match(OPENPAREN)) {
+            auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier);
+            propagateError();
+            return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete);
+        }
+
         consumeOrFail(COLON, "Expected ':' after property name");
         TreeExpression node = parseAssignmentExpression(context);
         failIfFalse(node, "Cannot parse expression for property declaration");
-        return context.createProperty(const_cast<VM*>(m_vm), propertyName, node, PropertyNode::Constant, complete);
+        context.setEndOffset(node, m_lexer->currentOffset());
+        return context.createProperty(propertyName, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::Unknown, complete);
     }
     default:
         failIfFalse(m_token.m_type & KeywordTokenFlag, "Expected a property name");
@@ -1794,15 +2350,72 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
     }
 }
 
+template <typename LexerType>
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName)
+{
+    JSTokenLocation methodLocation(tokenLocation());
+    unsigned methodStart = tokenStart();
+    ParserFunctionInfo<TreeBuilder> methodInfo;
+    failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method");
+    methodInfo.name = methodName;
+    return context.createFunctionExpr(methodLocation, methodInfo);
+}
+
+template <typename LexerType>
+template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(TreeBuilder& context, bool strict, PropertyNode::Type type, unsigned getterOrSetterStartOffset,
+    ConstructorKind constructorKind, SuperBinding superBinding)
+{
+    const Identifier* stringPropertyName = 0;
+    double numericPropertyName = 0;
+    if (m_token.m_type == IDENT || m_token.m_type == STRING) {
+        stringPropertyName = m_token.m_data.ident;
+        semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->prototype,
+            "Cannot declare a static method named 'prototype'");
+        semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->constructor,
+            "Cannot declare a getter or setter named 'constructor'");
+    } else if (m_token.m_type == DOUBLE || m_token.m_type == INTEGER)
+        numericPropertyName = m_token.m_data.doubleValue;
+    else
+        failDueToUnexpectedToken();
+    JSTokenLocation location(tokenLocation());
+    next();
+    ParserFunctionInfo<TreeBuilder> info;
+    if (type & PropertyNode::Getter) {
+        failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition");
+        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, constructorKind, superBinding,
+            getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse getter definition");
+    } else {
+        failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition");
+        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, constructorKind, superBinding,
+            getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse setter definition");
+    }
+    if (stringPropertyName)
+        return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, superBinding);
+    return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, superBinding);
+}
+
+template <typename LexerType>
+template <class TreeBuilder> bool Parser<LexerType>::shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder& context, const TreeProperty& property)
+{
+    if (m_syntaxAlreadyValidated)
+        return false;
+
+    if (!context.getName(property))
+        return false;
+
+    // A Constant property that is not a Computed or Shorthand Constant property.
+    return context.getType(property) == PropertyNode::Constant;
+}
+
 template <typename LexerType>
 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
 {
     auto savePoint = createSavePoint();
     consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of an object literal");
-    JSTokenLocation location(tokenLocation());
 
     int oldNonLHSCount = m_nonLHSCount;
-    
+
+    JSTokenLocation location(tokenLocation());    
     if (match(CLOSEBRACE)) {
         next();
         return context.createObjectLiteral(location);
@@ -1810,24 +2423,35 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
     
     TreeProperty property = parseProperty(context, false);
     failIfFalse(property, "Cannot parse object literal property");
-    if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
+
+    if (!m_syntaxAlreadyValidated && context.getType(property) & (PropertyNode::Getter | PropertyNode::Setter)) {
         restoreSavePoint(savePoint);
         return parseStrictObjectLiteral(context);
     }
+
+    bool seenUnderscoreProto = false;
+    if (shouldCheckPropertyForUnderscoreProtoDuplicate(context, property))
+        seenUnderscoreProto = *context.getName(property) == m_vm->propertyNames->underscoreProto;
+
     TreePropertyList propertyList = context.createPropertyList(location, property);
     TreePropertyList tail = propertyList;
     while (match(COMMA)) {
         next(TreeBuilder::DontBuildStrings);
-        // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
         if (match(CLOSEBRACE))
             break;
         JSTokenLocation propertyLocation(tokenLocation());
         property = parseProperty(context, false);
         failIfFalse(property, "Cannot parse object literal property");
-        if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
+        if (!m_syntaxAlreadyValidated && context.getType(property) & (PropertyNode::Getter | PropertyNode::Setter)) {
             restoreSavePoint(savePoint);
             return parseStrictObjectLiteral(context);
         }
+        if (shouldCheckPropertyForUnderscoreProtoDuplicate(context, property)) {
+            if (*context.getName(property) == m_vm->propertyNames->underscoreProto) {
+                semanticFailIfTrue(seenUnderscoreProto, "Attempted to redefine __proto__ property");
+                seenUnderscoreProto = true;
+            }
+        }
         tail = context.createPropertyList(propertyLocation, property, tail);
     }
 
@@ -1854,30 +2478,24 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObject
     
     TreeProperty property = parseProperty(context, true);
     failIfFalse(property, "Cannot parse object literal property");
-    
-    typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap;
-    ObjectValidationMap objectValidator;
-    // Add the first property
-    if (!m_syntaxAlreadyValidated && context.getName(property))
-        objectValidator.add(context.getName(property)->impl(), context.getType(property));
-    
+
+    bool seenUnderscoreProto = false;
+    if (shouldCheckPropertyForUnderscoreProtoDuplicate(context, property))
+        seenUnderscoreProto = *context.getName(property) == m_vm->propertyNames->underscoreProto;
+
     TreePropertyList propertyList = context.createPropertyList(location, property);
     TreePropertyList tail = propertyList;
     while (match(COMMA)) {
         next();
-        // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
         if (match(CLOSEBRACE))
             break;
         JSTokenLocation propertyLocation(tokenLocation());
         property = parseProperty(context, true);
         failIfFalse(property, "Cannot parse object literal property");
-        if (!m_syntaxAlreadyValidated && context.getName(property)) {
-            ObjectValidationMap::AddResult propertyEntry = objectValidator.add(context.getName(property)->impl(), context.getType(property));
-            if (!propertyEntry.isNewEntry) {
-                semanticFailIfTrue(propertyEntry.iterator->value == PropertyNode::Constant, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
-                semanticFailIfTrue(context.getType(property) == PropertyNode::Constant, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
-                semanticFailIfTrue(context.getType(property) & propertyEntry.iterator->value, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
-                propertyEntry.iterator->value |= context.getType(property);
+        if (shouldCheckPropertyForUnderscoreProtoDuplicate(context, property)) {
+            if (*context.getName(property) == m_vm->propertyNames->underscoreProto) {
+                semanticFailIfTrue(seenUnderscoreProto, "Attempted to redefine __proto__ property");
+                seenUnderscoreProto = true;
             }
         }
         tail = context.createPropertyList(propertyLocation, property, tail);
@@ -1965,11 +2583,86 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral
     return context.createArray(location, elementList);
 }
 
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+template <typename LexerType>
+template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail)
+{
+    if (!isTemplateHead) {
+        matchOrFail(CLOSEBRACE, "Expected a closing '}' following an expression in template literal");
+        // Re-scan the token to recognize it as Template Element.
+        m_token.m_type = m_lexer->scanTrailingTemplateString(&m_token, rawStringsBuildMode);
+    }
+    matchOrFail(TEMPLATE, "Expected an template element");
+    const Identifier* cooked = m_token.m_data.cooked;
+    const Identifier* raw = m_token.m_data.raw;
+    elementIsTail = m_token.m_data.isTail;
+    JSTokenLocation location(tokenLocation());
+    next();
+    return context.createTemplateString(location, *cooked, *raw);
+}
+
+template <typename LexerType>
+template <class TreeBuilder> typename TreeBuilder::TemplateLiteral Parser<LexerType>::parseTemplateLiteral(TreeBuilder& context, typename LexerType::RawStringsBuildMode rawStringsBuildMode)
+{
+    JSTokenLocation location(tokenLocation());
+    bool elementIsTail = false;
+
+    auto headTemplateString = parseTemplateString(context, true, rawStringsBuildMode, elementIsTail);
+    failIfFalse(headTemplateString, "Cannot parse head template element");
+
+    typename TreeBuilder::TemplateStringList templateStringList = context.createTemplateStringList(headTemplateString);
+    typename TreeBuilder::TemplateStringList templateStringTail = templateStringList;
+
+    if (elementIsTail)
+        return context.createTemplateLiteral(location, templateStringList);
+
+    failIfTrue(match(CLOSEBRACE), "Template literal expression cannot be empty");
+    TreeExpression expression = parseExpression(context);
+    failIfFalse(expression, "Cannot parse expression in template literal");
+
+    typename TreeBuilder::TemplateExpressionList templateExpressionList = context.createTemplateExpressionList(expression);
+    typename TreeBuilder::TemplateExpressionList templateExpressionTail = templateExpressionList;
+
+    auto templateString = parseTemplateString(context, false, rawStringsBuildMode, elementIsTail);
+    failIfFalse(templateString, "Cannot parse template element");
+    templateStringTail = context.createTemplateStringList(templateStringTail, templateString);
+
+    while (!elementIsTail) {
+        failIfTrue(match(CLOSEBRACE), "Template literal expression cannot be empty");
+        TreeExpression expression = parseExpression(context);
+        failIfFalse(expression, "Cannot parse expression in template literal");
+
+        templateExpressionTail = context.createTemplateExpressionList(templateExpressionTail, expression);
+
+        auto templateString = parseTemplateString(context, false, rawStringsBuildMode, elementIsTail);
+        failIfFalse(templateString, "Cannot parse template element");
+        templateStringTail = context.createTemplateStringList(templateStringTail, templateString);
+    }
+
+    return context.createTemplateLiteral(location, templateStringList, templateExpressionList);
+}
+#endif
+
 template <typename LexerType>
 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpression(TreeBuilder& context)
 {
     failIfStackOverflow();
     switch (m_token.m_type) {
+    case FUNCTION: {
+        JSTokenLocation location(tokenLocation());
+        unsigned functionKeywordStart = tokenStart();
+        next();
+        ParserFunctionInfo<TreeBuilder> info;
+        info.name = &m_vm->propertyNames->nullIdentifier;
+        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse function expression");
+        return context.createFunctionExpr(location, info);
+    }
+#if ENABLE(ES6_CLASS_SYNTAX)
+    case CLASSTOKEN: {
+        ParserClassInfo<TreeBuilder> info;
+        return parseClass(context, FunctionNoRequirements, info);
+    }
+#endif
     case OPENBRACE:
         if (strictMode())
             return parseStrictObjectLiteral(context);
@@ -1987,7 +2680,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
     case THISTOKEN: {
         JSTokenLocation location(tokenLocation());
         next();
-        return context.thisExpr(location);
+        return context.thisExpr(location, m_thisTDZMode);
     }
     case IDENT: {
         JSTextPosition start = tokenStartPosition();
@@ -2004,11 +2697,17 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
         next();
         return context.createString(location, ident);
     }
-    case NUMBER: {
+    case DOUBLE: {
         double d = m_token.m_data.doubleValue;
         JSTokenLocation location(tokenLocation());
         next();
-        return context.createNumberExpr(location, d);
+        return context.createDoubleExpr(location, d);
+    }
+    case INTEGER: {
+        double d = m_token.m_data.doubleValue;
+        JSTokenLocation location(tokenLocation());
+        next();
+        return context.createIntegerExpr(location, d);
     }
     case NULLTOKEN: {
         JSTokenLocation location(tokenLocation());
@@ -2045,6 +2744,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
         }
         return re;
     }
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    case TEMPLATE:
+        return parseTemplateLiteral(context, LexerType::RawStringsBuildMode::DontBuildRawStrings);
+#endif
     default:
         failDueToUnexpectedToken();
     }
@@ -2100,27 +2803,27 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
     TreeExpression base = 0;
     JSTextPosition expressionStart = tokenStartPosition();
     int newCount = 0;
+    JSTokenLocation startLocation = tokenLocation();
     JSTokenLocation location;
     while (match(NEW)) {
         next();
         newCount++;
     }
-    
-    if (match(FUNCTION)) {
-        const Identifier* name = &m_vm->propertyNames->nullIdentifier;
-        TreeFormalParameterList parameters = 0;
-        TreeFunctionBody body = 0;
-        unsigned openBraceOffset = 0;
-        unsigned closeBraceOffset = 0;
-        int bodyStartLine = 0;
-        unsigned bodyStartColumn = 0;
-        location = tokenLocation();
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+    bool baseIsSuper = match(SUPER);
+    semanticFailIfTrue(baseIsSuper && newCount, "Cannot use new with super");
+#else
+    bool baseIsSuper = false;
+#endif
+
+    if (baseIsSuper) {
+        base = context.superExpr(location);
         next();
-        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse function expression");
-        base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn);
+        currentScope()->setNeedsSuperBinding();
     } else
         base = parsePrimaryExpression(context);
-    
+
     failIfFalse(base, "Cannot parse base expression");
     while (true) {
         location = tokenLocation();
@@ -2151,7 +2854,9 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
                 JSTextPosition expressionEnd = lastTokenEndPosition();
                 TreeArguments arguments = parseArguments(context, AllowSpread);
                 failIfFalse(arguments, "Cannot parse call arguments");
-                base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
+                if (baseIsSuper)
+                    currentScope()->setHasDirectSuper();
+                base = context.makeFunctionCallNode(startLocation, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
             }
             m_nonLHSCount = nonLHSCount;
             break;
@@ -2165,16 +2870,46 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
             next();
             break;
         }
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+        case TEMPLATE: {
+            semanticFailIfTrue(baseIsSuper, "Cannot use super as tag for tagged templates");
+            JSTextPosition expressionEnd = lastTokenEndPosition();
+            int nonLHSCount = m_nonLHSCount;
+            typename TreeBuilder::TemplateLiteral templateLiteral = parseTemplateLiteral(context, LexerType::RawStringsBuildMode::BuildRawStrings);
+            failIfFalse(templateLiteral, "Cannot parse template literal");
+            base = context.createTaggedTemplate(location, base, templateLiteral, expressionStart, expressionEnd, lastTokenEndPosition());
+            m_nonLHSCount = nonLHSCount;
+            break;
+        }
+#endif
         default:
             goto endMemberExpression;
         }
+        baseIsSuper = false;
     }
 endMemberExpression:
+    semanticFailIfTrue(baseIsSuper, "Cannot reference super");
     while (newCount--)
         base = context.createNewExpr(location, base, expressionStart, lastTokenEndPosition());
     return base;
 }
 
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+template <typename LexerType>
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context)
+{
+    JSTokenLocation location;
+
+    unsigned functionKeywordStart = tokenStart();
+    location = tokenLocation();
+    ParserFunctionInfo<TreeBuilder> info;
+    info.name = &m_vm->propertyNames->nullIdentifier;
+    failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, ArrowFunctionParseType)), "Cannot parse arrow function expression");
+
+    return context.createArrowFunctionExpr(location, info);
+}
+#endif
+
 static const char* operatorString(bool prefix, unsigned tok)
 {
     switch (tok) {
@@ -2372,7 +3107,8 @@ template <typename LexerType> void Parser<LexerType>::printUnexpectedTokenText(W
     case STRING:
         out.print("Unexpected string literal ", getToken());
         return;
-    case NUMBER:
+    case INTEGER:
+    case DOUBLE:
         out.print("Unexpected number '", getToken(), "'");
         return;
     
index b88f209ce5f0bb618acd7d0052fec5d8c68441a3..a0e5ce7080ff635aa274172e70d2e921c1a19166 100644 (file)
 #include "Nodes.h"
 #include "ParserArena.h"
 #include "ParserError.h"
+#include "ParserFunctionInfo.h"
 #include "ParserTokens.h"
 #include "SourceProvider.h"
 #include "SourceProviderCache.h"
 #include "SourceProviderCacheItem.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
 namespace JSC {
 struct Scope;
@@ -70,33 +70,43 @@ class SourceCode;
 #define TreeArguments typename TreeBuilder::Arguments
 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
 #define TreeFunctionBody typename TreeBuilder::FunctionBody
+#if ENABLE(ES6_CLASS_SYNTAX)
+#define TreeClassExpression typename TreeBuilder::ClassExpression
+#endif
 #define TreeProperty typename TreeBuilder::Property
 #define TreePropertyList typename TreeBuilder::PropertyList
-#define TreeDeconstructionPattern typename TreeBuilder::DeconstructionPattern
+#define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
 
 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
 
 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+enum FunctionParseType { StandardFunctionParseType, ArrowFunctionParseType };
+#else
+enum FunctionParseType { StandardFunctionParseType};
+#endif
 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
-enum FunctionParseMode { FunctionMode, GetterMode, SetterMode };
-enum DeconstructionKind {
-    DeconstructToVariables,
-    DeconstructToParameters,
-    DeconstructToExpressions
+enum FunctionParseMode {
+    FunctionMode,
+    GetterMode,
+    SetterMode,
+    MethodMode,
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    ArrowFunctionMode
+#endif
+};
+enum DestructuringKind {
+    DestructureToVariables,
+    DestructureToParameters,
+    DestructureToExpressions
 };
 
 template <typename T> inline bool isEvalNode() { return false; }
 template <> inline bool isEvalNode<EvalNode>() { return true; }
 
 struct ScopeLabelInfo {
-    ScopeLabelInfo(StringImpl* ident, bool isLoop)
-        : m_ident(ident)
-        , m_isLoop(isLoop)
-    {
-    }
-
-    StringImpl* m_ident;
-    bool m_isLoop;
+    UniquedStringImpl* uid;
+    bool isLoop;
 };
 
 struct Scope {
@@ -105,6 +115,8 @@ struct Scope {
         , m_shadowsArguments(false)
         , m_usesEval(false)
         , m_needsFullActivation(false)
+        , m_hasDirectSuper(false)
+        , m_needsSuperBinding(false)
         , m_allowsNewDecls(true)
         , m_strictMode(strictMode)
         , m_isFunction(isFunction)
@@ -120,6 +132,8 @@ struct Scope {
         , m_shadowsArguments(rhs.m_shadowsArguments)
         , m_usesEval(rhs.m_usesEval)
         , m_needsFullActivation(rhs.m_needsFullActivation)
+        , m_hasDirectSuper(rhs.m_hasDirectSuper)
+        , m_needsSuperBinding(rhs.m_needsSuperBinding)
         , m_allowsNewDecls(rhs.m_allowsNewDecls)
         , m_strictMode(rhs.m_strictMode)
         , m_isFunction(rhs.m_isFunction)
@@ -129,12 +143,12 @@ struct Scope {
         , m_switchDepth(rhs.m_switchDepth)
     {
         if (rhs.m_labels) {
-            m_labels = adoptPtr(new LabelStack);
+            m_labels = std::make_unique<LabelStack>();
 
             typedef LabelStack::const_iterator iterator;
             iterator end = rhs.m_labels->end();
             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
-                m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
+                m_labels->append(ScopeLabelInfo { it->uid, it->isLoop });
         }
     }
 
@@ -149,8 +163,8 @@ struct Scope {
     void pushLabel(const Identifier* label, bool isLoop)
     {
         if (!m_labels)
-            m_labels = adoptPtr(new LabelStack);
-        m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
+            m_labels = std::make_unique<LabelStack>();
+        m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
     }
 
     void popLabel()
@@ -165,7 +179,7 @@ struct Scope {
         if (!m_labels)
             return 0;
         for (int i = m_labels->size(); i > 0; i--) {
-            if (m_labels->at(i - 1).m_ident == label->impl())
+            if (m_labels->at(i - 1).uid == label->impl())
                 return &m_labels->at(i - 1);
         }
         return 0;
@@ -181,14 +195,14 @@ struct Scope {
 
     void declareCallee(const Identifier* ident)
     {
-        m_declaredVariables.add(ident->string().impl());
+        m_declaredVariables.add(ident->impl());
     }
 
     bool declareVariable(const Identifier* ident)
     {
         bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
-        m_declaredVariables.add(ident->string().impl());
+        m_declaredVariables.add(ident->impl());
         return isValidStrictMode;
     }
 
@@ -214,9 +228,9 @@ struct Scope {
     bool declareParameter(const Identifier* ident)
     {
         bool isArguments = m_vm->propertyNames->arguments == *ident;
-        bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
+        bool isValidStrictMode = m_declaredVariables.add(ident->impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
-        m_declaredParameters.add(ident->string().impl());
+        m_declaredParameters.add(ident->impl());
 
         if (isArguments)
             m_shadowsArguments = true;
@@ -231,7 +245,7 @@ struct Scope {
     BindingResult declareBoundParameter(const Identifier* ident)
     {
         bool isArguments = m_vm->propertyNames->arguments == *ident;
-        bool newEntry = m_declaredVariables.add(ident->string().impl()).isNewEntry;
+        bool newEntry = m_declaredVariables.add(ident->impl()).isNewEntry;
         bool isValidStrictMode = newEntry && m_vm->propertyNames->eval != *ident && !isArguments;
         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
     
@@ -250,11 +264,25 @@ struct Scope {
     void useVariable(const Identifier* ident, bool isEval)
     {
         m_usesEval |= isEval;
-        m_usedVariables.add(ident->string().impl());
+        m_usedVariables.add(ident->impl());
     }
 
     void setNeedsFullActivation() { m_needsFullActivation = true; }
 
+#if ENABLE(ES6_CLASS_SYNTAX)
+    bool hasDirectSuper() { return m_hasDirectSuper; }
+#else
+    bool hasDirectSuper() { return false; }
+#endif
+    void setHasDirectSuper() { m_hasDirectSuper = true; }
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+    bool needsSuperBinding() { return m_needsSuperBinding; }
+#else
+    bool needsSuperBinding() { return false; }
+#endif
+    void setNeedsSuperBinding() { m_needsSuperBinding = true; }
+
     bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
     {
         if (nestedScope->m_usesEval)
@@ -279,11 +307,11 @@ struct Scope {
         return true;
     }
 
-    void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter)
+    void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter, bool& modifiedArguments)
     {
         if (m_needsFullActivation || m_usesEval) {
             modifiedParameter = true;
-            capturedVariables.swap(m_declaredVariables);
+            capturedVariables = m_declaredVariables;
             return;
         }
         for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
@@ -292,9 +320,13 @@ struct Scope {
             capturedVariables.add(*ptr);
         }
         modifiedParameter = false;
+        if (shadowsArguments())
+            modifiedArguments = true;
         if (m_declaredParameters.size()) {
             IdentifierSet::iterator end = m_writtenVariables.end();
             for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
+                if (*ptr == m_vm->propertyNames->arguments.impl())
+                    modifiedArguments = true;
                 if (!m_declaredParameters.contains(*ptr))
                     continue;
                 modifiedParameter = true;
@@ -307,7 +339,7 @@ struct Scope {
     bool isValidStrictMode() const { return m_isValidStrictMode; }
     bool shadowsArguments() const { return m_shadowsArguments; }
 
-    void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl>>& vector)
+    void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<UniquedStringImpl>>& vector)
     {
         IdentifierSet::iterator end = capturedVariables.end();
         for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
@@ -344,6 +376,8 @@ private:
     bool m_shadowsArguments : 1;
     bool m_usesEval : 1;
     bool m_needsFullActivation : 1;
+    bool m_hasDirectSuper : 1;
+    bool m_needsSuperBinding : 1;
     bool m_allowsNewDecls : 1;
     bool m_strictMode : 1;
     bool m_isFunction : 1;
@@ -353,7 +387,7 @@ private:
     int m_switchDepth;
 
     typedef Vector<ScopeLabelInfo, 2> LabelStack;
-    OwnPtr<LabelStack> m_labels;
+    std::unique_ptr<LabelStack> m_labels;
     IdentifierSet m_declaredParameters;
     IdentifierSet m_declaredVariables;
     IdentifierSet m_usedVariables;
@@ -394,14 +428,18 @@ class Parser {
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
+    Parser(
+        VM*, const SourceCode&, FunctionParameters*, const Identifier&, 
+        JSParserBuiltinMode, JSParserStrictMode, JSParserCodeType,
+        ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode = ThisTDZMode::CheckIfNeeded);
     ~Parser();
 
     template <class ParsedNode>
-    PassRefPtr<ParsedNode> parse(ParserError&, bool needReparsingAdjustment);
+    std::unique_ptr<ParsedNode> parse(ParserError&);
 
     JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
-    Vector<RefPtr<StringImpl>>&& closedVariables() { return WTF::move(m_closedVariables); }
+    JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
+    Vector<RefPtr<UniquedStringImpl>>&& closedVariables() { return WTF::move(m_closedVariables); }
 
 private:
     struct AllowInOverride {
@@ -527,8 +565,8 @@ private:
     Parser();
     String parseInner();
 
-    void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*
-        ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<StringImpl>>&&);
+    void didFinishParsing(SourceElements*, DeclarationStacks::VarStack&
+        DeclarationStacks::FunctionStack&, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<UniquedStringImpl>>&&);
 
     // Used to determine type of error to report.
     bool isFunctionBodyNode(ScopeNode*) { return false; }
@@ -583,6 +621,47 @@ private:
         return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
     }
     
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    ALWAYS_INLINE bool isEndOfArrowFunction()
+    {
+        return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator();
+    }
+    
+    ALWAYS_INLINE bool isArrowFunctionParamters()
+    {
+        bool isArrowFunction = false;
+        
+        if (match(EOFTOK))
+            return isArrowFunction;
+        
+        SavePoint saveArrowFunctionPoint = createSavePoint();
+        
+        if (consume(OPENPAREN)) {
+            bool isArrowFunctionParamters = true;
+            
+            while (consume(IDENT)) {
+                if (consume(COMMA)) {
+                    if (!match(IDENT)) {
+                        isArrowFunctionParamters = false;
+                        break;
+                    }
+                } else
+                    break;
+            }
+            
+            if (isArrowFunctionParamters) {
+                if (consume(CLOSEPAREN) && match(ARROWFUNCTION))
+                    isArrowFunction = true;
+            }
+        } else if (consume(IDENT) && match(ARROWFUNCTION))
+            isArrowFunction = true;
+
+        restoreSavePoint(saveArrowFunctionPoint);
+        
+        return isArrowFunction;
+    }
+#endif
+    
     ALWAYS_INLINE unsigned tokenStart()
     {
         return m_token.m_location.startOffset;
@@ -618,9 +697,9 @@ private:
         return m_token.m_location;
     }
 
-    void setErrorMessage(String msg)
+    void setErrorMessage(const String& message)
     {
-        m_errorMessage = msg;
+        m_errorMessage = message;
     }
     
     NEVER_INLINE void logError(bool);
@@ -632,9 +711,9 @@ private:
     template <typename A, typename B, typename C, typename D, typename E, typename F> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&);
     template <typename A, typename B, typename C, typename D, typename E, typename F, typename G> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&, const G&);
     
-    NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
+    NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
     {
-        m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
+        m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
     }
     
     NEVER_INLINE void updateErrorMessage(const char* msg)
@@ -686,9 +765,13 @@ private:
         }
         return result;
     }
-    
-    template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
+
+    template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode, FunctionParseType);
+    template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
+#if ENABLE(ES6_CLASS_SYNTAX)
+    template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&);
+#endif
     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
@@ -722,15 +805,39 @@ private:
     enum SpreadMode { AllowSpread, DontAllowSpread };
     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&, SpreadMode);
     template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
-    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
+    template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName);
+    template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded);
+    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, FunctionParseType);
     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
-    template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd);
+    enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
+    template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext);
     template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
 
-    template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, DeconstructionKind, const Identifier&, int depth);
-    template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0);
-    template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&);
-    template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    template <class TreeBuilder> TreeStatement parseArrowFunctionSingleExpressionBody(TreeBuilder&, FunctionParseType);
+    template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
+#endif
+
+    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, const Identifier&, int depth, JSToken);
+    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, int depth = 0);
+    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&);
+    template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
+
+    template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType);
+    
+    template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, FunctionParseMode, ParserFunctionInfo<TreeBuilder>&);
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+    template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&);
+#endif
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
+    template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
+#endif
+
+    template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
+
     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
     bool allowAutomaticSemicolon();
     
@@ -743,6 +850,14 @@ private:
         return allowAutomaticSemicolon();
     }
     
+
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    void setEndOfStatement()
+    {
+        m_lexer->setTokenPosition(&m_token);
+    }
+#endif
+
     bool canRecurse()
     {
         return m_vm->isSafeToRecurse();
@@ -811,8 +926,8 @@ private:
 
     VM* m_vm;
     const SourceCode* m_source;
-    ParserArena* m_arena;
-    OwnPtr<LexerType> m_lexer;
+    ParserArena m_parserArena;
+    std::unique_ptr<LexerType> m_lexer;
     
     bool m_hasStackOverflow;
     String m_errorMessage;
@@ -829,10 +944,12 @@ private:
     RefPtr<SourceProviderCache> m_functionCache;
     SourceElements* m_sourceElements;
     bool m_parsingBuiltin;
-    ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
-    ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
+    ConstructorKind m_defaultConstructorKind;
+    ThisTDZMode m_thisTDZMode;
+    DeclarationStacks::VarStack m_varDeclarations;
+    DeclarationStacks::FunctionStack m_funcDeclarations;
     IdentifierSet m_capturedVariables;
-    Vector<RefPtr<StringImpl>> m_closedVariables;
+    Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
     CodeFeatures m_features;
     int m_numConstants;
     
@@ -857,12 +974,12 @@ private:
 
 template <typename LexerType>
 template <class ParsedNode>
-PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error, bool needReparsingAdjustment)
+std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
 {
     int errLine;
     String errMsg;
 
-    if (ParsedNode::scopeIsFunction && needReparsingAdjustment)
+    if (ParsedNode::scopeIsFunction)
         m_lexer->setIsReparsing();
 
     m_sourceElements = 0;
@@ -888,26 +1005,27 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error, bool needRep
         m_sourceElements = 0;
     }
 
-    RefPtr<ParsedNode> result;
+    std::unique_ptr<ParsedNode> result;
     if (m_sourceElements) {
         JSTokenLocation endLocation;
         endLocation.line = m_lexer->lineNumber();
         endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
         endLocation.startOffset = m_lexer->currentOffset();
         unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
-        result = ParsedNode::create(m_vm,
+        result = std::make_unique<ParsedNode>(m_parserArena,
                                     startLocation,
                                     endLocation,
                                     startColumn,
                                     endColumn,
                                     m_sourceElements,
-                                    m_varDeclarations ? &m_varDeclarations->data : 0,
-                                    m_funcDeclarations ? &m_funcDeclarations->data : 0,
+                                    m_varDeclarations,
+                                    m_funcDeclarations,
                                     m_capturedVariables,
                                     *m_source,
                                     m_features,
                                     m_numConstants);
         result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
+        result->setEndOffset(m_lexer->currentOffset());
     } else {
         // We can never see a syntax error when reparsing a function, since we should have
         // reported the error when parsing the containing program or eval code. So if we're
@@ -931,35 +1049,39 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error, bool needRep
         }
     }
 
-    m_arena->reset();
-
-    return result.release();
+    return result;
 }
 
 template <class ParsedNode>
-PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0, bool needReparsingAdjustment = false)
+std::unique_ptr<ParsedNode> parse(
+    VM* vm, const SourceCode& source, FunctionParameters* parameters,
+    const Identifier& name, JSParserBuiltinMode builtinMode,
+    JSParserStrictMode strictMode, JSParserCodeType codeType,
+    ParserError& error, JSTextPosition* positionBeforeLastNewline = 0,
+    ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
 {
     SamplingRegion samplingRegion("Parsing");
 
     ASSERT(!source.provider()->source().isNull());
     if (source.provider()->source().is8Bit()) {
-        Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
-        RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment);
+        Parser<Lexer<LChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
+        std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
         if (positionBeforeLastNewline)
             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
-        if (strictness == JSParseBuiltin) {
+        if (builtinMode == JSParserBuiltinMode::Builtin) {
             if (!result)
-                WTF::dataLog("Error compiling builtin: ", error.m_message, "\n");
+                WTF::dataLog("Error compiling builtin: ", error.message(), "\n");
             RELEASE_ASSERT(result);
             result->setClosedVariables(parser.closedVariables());
         }
-        return result.release();
+        return result;
     }
-    Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
-    RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment);
+    ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
+    Parser<Lexer<UChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
+    std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
     if (positionBeforeLastNewline)
         *positionBeforeLastNewline = parser.positionBeforeLastNewline();
-    return result.release();
+    return result;
 }
 
 } // namespace
index 43f931a872be8a6ede2574a4fe797f415944d220..a276887708c409644db81bcced8ae71b5c04e9a8 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "Nodes.h"
 #include "JSCInlines.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 
@@ -63,38 +62,6 @@ ParserArena::~ParserArena()
     deallocateObjects();
 }
 
-bool ParserArena::contains(ParserArenaRefCounted* object) const
-{
-    return m_refCountedObjects.find(object) != notFound;
-}
-
-ParserArenaRefCounted* ParserArena::last() const
-{
-    return m_refCountedObjects.last().get();
-}
-
-void ParserArena::removeLast()
-{
-    m_refCountedObjects.removeLast();
-}
-
-void ParserArena::reset()
-{
-    // Since this code path is used only when parsing fails, it's not bothering to reuse
-    // any of the memory the arena allocated. We could improve that later if we want to
-    // efficiently reuse the same arena.
-
-    deallocateObjects();
-
-    m_freeableMemory = 0;
-    m_freeablePoolEnd = 0;
-    if (m_identifierArena)
-        m_identifierArena->clear();
-    m_freeablePools.clear();
-    m_deletableObjects.clear();
-    m_refCountedObjects.clear();
-}
-
 void ParserArena::allocateFreeablePool()
 {
     if (m_freeablePoolEnd)
@@ -106,18 +73,4 @@ void ParserArena::allocateFreeablePool()
     ASSERT(freeablePool() == pool);
 }
 
-bool ParserArena::isEmpty() const
-{
-    return !m_freeablePoolEnd
-        && (!m_identifierArena || m_identifierArena->isEmpty())
-        && m_freeablePools.isEmpty()
-        && m_deletableObjects.isEmpty()
-        && m_refCountedObjects.isEmpty();
-}
-
-void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object)
-{
-    m_refCountedObjects.append(object);
-}
-
 }
index d8bc2cffa427314564fd1b0415c82475ce52b235..2a7d44de7718584063001c112594a61b59fcfa9c 100644 (file)
@@ -34,7 +34,6 @@
 namespace JSC {
 
     class ParserArenaDeletable;
-    class ParserArenaRefCounted;
 
     class IdentifierArena {
         WTF_MAKE_FAST_ALLOCATED;
@@ -46,12 +45,11 @@ namespace JSC {
 
         template <typename T>
         ALWAYS_INLINE const Identifier& makeIdentifier(VM*, const T* characters, size_t length);
+        ALWAYS_INLINE const Identifier& makeEmptyIdentifier(VM*);
         ALWAYS_INLINE const Identifier& makeIdentifierLCharFromUChar(VM*, const UChar* characters, size_t length);
 
         const Identifier& makeNumericIdentifier(VM*, double number);
 
-        bool isEmpty() const { return m_identifiers.isEmpty(); }
-
     public:
         static const int MaximumCachableCharacter = 128;
         typedef SegmentedVector<Identifier, 64> IdentifierVector;
@@ -76,24 +74,29 @@ namespace JSC {
         if (!length)
             return vm->propertyNames->emptyIdentifier;
         if (characters[0] >= MaximumCachableCharacter) {
-            m_identifiers.append(Identifier(vm, characters, length));
+            m_identifiers.append(Identifier::fromString(vm, characters, length));
             return m_identifiers.last();
         }
         if (length == 1) {
             if (Identifier* ident = m_shortIdentifiers[characters[0]])
                 return *ident;
-            m_identifiers.append(Identifier(vm, characters, length));
+            m_identifiers.append(Identifier::fromString(vm, characters, length));
             m_shortIdentifiers[characters[0]] = &m_identifiers.last();
             return m_identifiers.last();
         }
         Identifier* ident = m_recentIdentifiers[characters[0]];
         if (ident && Identifier::equal(ident->impl(), characters, length))
             return *ident;
-        m_identifiers.append(Identifier(vm, characters, length));
+        m_identifiers.append(Identifier::fromString(vm, characters, length));
         m_recentIdentifiers[characters[0]] = &m_identifiers.last();
         return m_identifiers.last();
     }
 
+    ALWAYS_INLINE const Identifier& IdentifierArena::makeEmptyIdentifier(VM* vm)
+    {
+        return vm->propertyNames->emptyIdentifier;
+    }
+
     ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifierLCharFromUChar(VM* vm, const UChar* characters, size_t length)
     {
         if (!length)
@@ -105,7 +108,7 @@ namespace JSC {
         if (length == 1) {
             if (Identifier* ident = m_shortIdentifiers[characters[0]])
                 return *ident;
-            m_identifiers.append(Identifier(vm, characters, length));
+            m_identifiers.append(Identifier::fromString(vm, characters, length));
             m_shortIdentifiers[characters[0]] = &m_identifiers.last();
             return m_identifiers.last();
         }
@@ -119,7 +122,7 @@ namespace JSC {
     
     inline const Identifier& IdentifierArena::makeNumericIdentifier(VM* vm, double number)
     {
-        m_identifiers.append(Identifier(vm, String::numberToStringECMAScript(number)));
+        m_identifiers.append(Identifier::fromString(vm, String::numberToStringECMAScript(number)));
         return m_identifiers.last();
     }
 
@@ -136,7 +139,6 @@ namespace JSC {
             m_identifierArena.swap(otherArena.m_identifierArena);
             m_freeablePools.swap(otherArena.m_freeablePools);
             m_deletableObjects.swap(otherArena.m_deletableObjects);
-            m_refCountedObjects.swap(otherArena.m_refCountedObjects);
         }
 
         void* allocateFreeable(size_t size)
@@ -159,18 +161,10 @@ namespace JSC {
             return deletable;
         }
 
-        void derefWithArena(PassRefPtr<ParserArenaRefCounted>);
-        bool contains(ParserArenaRefCounted*) const;
-        ParserArenaRefCounted* last() const;
-        void removeLast();
-
-        bool isEmpty() const;
-        JS_EXPORT_PRIVATE void reset();
-
         IdentifierArena& identifierArena()
         {
             if (UNLIKELY (!m_identifierArena))
-                m_identifierArena = adoptPtr(new IdentifierArena);
+                m_identifierArena = std::make_unique<IdentifierArena>();
             return *m_identifierArena;
         }
 
@@ -189,10 +183,9 @@ namespace JSC {
         char* m_freeableMemory;
         char* m_freeablePoolEnd;
 
-        OwnPtr<IdentifierArena> m_identifierArena;
+        std::unique_ptr<IdentifierArena> m_identifierArena;
         Vector<void*> m_freeablePools;
         Vector<ParserArenaDeletable*> m_deletableObjects;
-        Vector<RefPtr<ParserArenaRefCounted>> m_refCountedObjects;
     };
 
 }
index df38a067429aeb2bb769a5fb8396404fe88a4567..89a05ab4290f4e8ad3364efa0df970defce8f732 100644 (file)
@@ -34,7 +34,8 @@
 
 namespace JSC {
 
-struct ParserError {
+class ParserError {
+public:
     enum SyntaxErrorType {
         SyntaxErrorNone,
         SyntaxErrorIrrecoverable,
@@ -50,62 +51,72 @@ struct ParserError {
         SyntaxError
     };
 
-    ErrorType m_type;
-    SyntaxErrorType m_syntaxErrorType;
-    JSToken m_token;
-    String m_message;
-    int m_line;
     ParserError()
         : m_type(ErrorNone)
         , m_syntaxErrorType(SyntaxErrorNone)
-        , m_line(-1)
     {
     }
     
     explicit ParserError(ErrorType type)
         : m_type(type)
         , m_syntaxErrorType(SyntaxErrorNone)
-        , m_line(-1)
     {
     }
 
     ParserError(ErrorType type, SyntaxErrorType syntaxError, JSToken token)
-        : m_type(type)
+        : m_token(token)
+        , m_type(type)
         , m_syntaxErrorType(syntaxError)
-        , m_token(token)
-        , m_line(-1)
     {
     }
 
-    ParserError(ErrorType type, SyntaxErrorType syntaxError, JSToken token, String msg, int line)
-        : m_type(type)
-        , m_syntaxErrorType(syntaxError)
-        , m_token(token)
+    ParserError(ErrorType type, SyntaxErrorType syntaxError, JSToken token, const String& msg, int line)
+        : m_token(token)
         , m_message(msg)
         , m_line(line)
+        , m_type(type)
+        , m_syntaxErrorType(syntaxError)
     {
     }
 
-    JSObject* toErrorObject(JSGlobalObject* globalObject, const SourceCode& source)
+    bool isValid() const { return m_type != ErrorNone; }
+    SyntaxErrorType syntaxErrorType() const { return m_syntaxErrorType; }
+    const JSToken& token() const { return m_token; }
+    const String& message() const { return m_message; }
+    int line() const { return m_line; }
+
+    JSObject* toErrorObject(
+        JSGlobalObject* globalObject, const SourceCode& source, 
+        int overrideLineNumber = -1)
     {
+        ExecState* exec = globalObject->globalExec();
         switch (m_type) {
         case ErrorNone:
-            return 0;
+            return nullptr;
         case SyntaxError:
-            return addErrorInfo(globalObject->globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
+            return addErrorInfo(
+                exec, 
+                createSyntaxError(exec, m_message), 
+                overrideLineNumber == -1 ? m_line : overrideLineNumber, source);
         case EvalError:
-            return createSyntaxError(globalObject, m_message);
+            return createSyntaxError(exec, m_message);
         case StackOverflow: {
             ErrorHandlingScope errorScope(globalObject->vm());
-            return createStackOverflowError(globalObject);
+            return createStackOverflowError(exec);
         }
         case OutOfMemory:
-            return createOutOfMemoryError(globalObject);
+            return createOutOfMemoryError(exec);
         }
         CRASH();
-        return createOutOfMemoryError(globalObject); // Appease Qt bot
+        return nullptr;
     }
-#undef GET_ERROR_CODE
+
+private:
+    JSToken m_token;
+    String m_message;
+    int m_line { -1 };
+    ErrorType m_type;
+    SyntaxErrorType m_syntaxErrorType;
 };
 
 } // namespace JSC
diff --git a/parser/ParserFunctionInfo.h b/parser/ParserFunctionInfo.h
new file mode 100644 (file)
index 0000000..366084d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ParserFunctionInfo_h
+#define ParserFunctionInfo_h
+
+namespace JSC {
+
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock };
+#endif
+
+template <class TreeBuilder>
+struct ParserFunctionInfo {
+    const Identifier* name = 0;
+    typename TreeBuilder::FormalParameterList parameters = 0;
+    typename TreeBuilder::FunctionBody body = 0;
+    unsigned startFunctionOffset = 0;
+    unsigned endFunctionOffset = 0;
+    int bodyStartLine = 0;
+    int bodyEndLine = 0;
+    unsigned bodyStartColumn = 0;
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    unsigned arrowFunctionOffset = 0;
+    unsigned arrowFunctionNextTockenEndOffset = 0;
+    bool isArrowFunction { false };
+    bool isEndByTerminator { false };
+    FunctionBodyType functionBodyType { StandardFunctionBodyBlock };
+#endif
+};
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+template <class TreeBuilder>
+struct ParserClassInfo {
+    const Identifier* className = 0;
+};
+#endif
+
+}
+
+#endif
index 9314b19790a0d558ae4d24f1fc621175fffd427f..edf0296ecaa563c88e1e30670fa2a272d2c19d0e 100644 (file)
 
 namespace JSC {
 
-enum JSParserStrictness { JSParseNormal, JSParseBuiltin, JSParseStrict };
-enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
+enum class JSParserStrictMode { NotStrict, Strict };
+enum class JSParserBuiltinMode { NotBuiltin, Builtin };
+enum class JSParserCodeType { Program, Function };
+
+enum class ConstructorKind { None, Base, Derived };
+enum class SuperBinding { Needed, NotNeeded };
+enum class ThisTDZMode { AlwaysCheck, CheckIfNeeded };
 
 enum ProfilerMode { ProfilerOff, ProfilerOn };
 enum DebuggerMode { DebuggerOff, DebuggerOn };
@@ -75,6 +80,7 @@ const CodeFeatures ThisFeature = 1 << 4;
 const CodeFeatures StrictModeFeature = 1 << 5;
 const CodeFeatures ShadowsArgumentsFeature = 1 << 6;
 const CodeFeatures ModifiedParameterFeature = 1 << 7;
+const CodeFeatures ModifiedArgumentsFeature = 1 << 8;
 
 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature;
 
index a6758d0a10308e954c06ce974267b612c8bd9e31..e9154caf053c5381b5f09816dba0558a5434bf37 100644 (file)
@@ -75,6 +75,18 @@ enum JSTokenType {
     FINALLY,
     DEBUGGER,
     ELSE,
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    ARROWFUNCTION,
+#endif
+#if ENABLE(ES6_CLASS_SYNTAX)
+    CLASSTOKEN,
+    EXTENDS,
+    SUPER,
+#else
+    CLASSTOKEN = RESERVED,
+    EXTENDS = RESERVED,
+    SUPER = RESERVED,
+#endif
     OPENBRACE = 0,
     CLOSEBRACE,
     OPENPAREN,
@@ -83,9 +95,11 @@ enum JSTokenType {
     CLOSEBRACKET,
     COMMA,
     QUESTION,
-    NUMBER,
+    INTEGER,
+    DOUBLE,
     IDENT,
     STRING,
+    TEMPLATE,
     SEMICOLON,
     COLON,
     DOT,
@@ -150,7 +164,10 @@ enum JSTokenType {
     UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
     INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
     INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag,
-    INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag
+    INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag,
+    INVALID_BINARY_NUMBER_ERRORTOK = 12 | ErrorTokenFlag,
+    UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK = 13 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+    INVALID_TEMPLATE_LITERAL_ERRORTOK = 14 | ErrorTokenFlag,
 };
 
 struct JSTextPosition {
@@ -178,6 +195,11 @@ union JSTokenData {
     };
     double doubleValue;
     const Identifier* ident;
+    struct {
+        const Identifier* cooked;
+        const Identifier* raw;
+        bool isTail;
+    };
 };
 
 struct JSTokenLocation {
index 73d23db82af25ea46c0f89785ce424bb60eb61a7..f4a19029b5808d2bb0453b103e210ea140c99319 100644 (file)
@@ -105,6 +105,9 @@ namespace JSC {
         
         SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn);
 
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+        SourceCode subArrowExpression(unsigned startArrowFunction, unsigned endArrowFunction, int firstLine, int startColumn);
+#endif
     private:
         RefPtr<SourceProvider> m_provider;
         int m_startChar;
@@ -117,6 +120,16 @@ namespace JSC {
     {
         return SourceCode(StringSourceProvider::create(source, url, startPosition), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt());
     }
+    
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    inline SourceCode SourceCode::subArrowExpression(unsigned startArrowFunction, unsigned endArrowFunction, int firstLine, int startColumn)
+    {
+        ASSERT(provider()->source()[startArrowFunction] == '=' && provider()->source()[startArrowFunction + 1] == '>');
+
+        startColumn += 1; // Convert to base 1.
+        return SourceCode(provider(), startArrowFunction, endArrowFunction, firstLine, startColumn);
+    }
+#endif
 
     inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn)
     {
index 939addfbd58b173cbf6bddcc8f1f74d6e9db4ec4..c9652459a117f9bda578c72f17c4d3426f69127d 100644 (file)
@@ -27,8 +27,8 @@
 #include "SourceProvider.h"
 
 #include "JSCInlines.h"
+#include <wtf/SpinLock.h>
 #include <wtf/StdLibExtras.h>
-#include <wtf/TCSpinLock.h>
 
 namespace JSC {
 
@@ -44,7 +44,7 @@ SourceProvider::~SourceProvider()
 {
 }
 
-static TCMalloc_SpinLock providerIdLock = SPINLOCK_INITIALIZER;
+static StaticSpinLock providerIdLock;
 
 void SourceProvider::getID()
 {
index 91c1c68652c9e32dcd80718e20e86e695374e178..cccabf36964f411a64cbae2592d24f424f026b47 100644 (file)
@@ -29,7 +29,6 @@
 #ifndef SourceProvider_h
 #define SourceProvider_h
 
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/TextPosition.h>
 #include <wtf/text/WTFString.h>
@@ -54,9 +53,6 @@ namespace JSC {
         TextPosition startPosition() const { return m_startPosition; }
         intptr_t asID()
         {
-            ASSERT(this);
-            if (!this) // Be defensive in release mode.
-                return nullID;
             if (!m_id)
                 getID();
             return m_id;
@@ -78,9 +74,9 @@ namespace JSC {
 
     class StringSourceProvider : public SourceProvider {
     public:
-        static PassRefPtr<StringSourceProvider> create(const String& source, const String& url, const TextPosition& startPosition = TextPosition::minimumPosition())
+        static Ref<StringSourceProvider> create(const String& source, const String& url, const TextPosition& startPosition = TextPosition::minimumPosition())
         {
-            return adoptRef(new StringSourceProvider(source, url, startPosition));
+            return adoptRef(*new StringSourceProvider(source, url, startPosition));
         }
 
         virtual const String& source() const override
index 7558a09f4f839d6d6991a1fd88af19d3073f51ca..cded96878623f8bc3908b73d7967a58e619255a9 100644 (file)
@@ -28,8 +28,6 @@
 
 #include "SourceProviderCacheItem.h"
 #include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
 
 namespace JSC {
index 3962118610f6aa6a8f4905a90eb2daa4a0085eeb..c0c507f591a300f1943586066f4465322aa1c9e1 100644 (file)
 #define SourceProviderCacheItem_h
 
 #include "ParserTokens.h"
-#include <wtf/PassOwnPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/text/UniquedStringImpl.h>
 #include <wtf/text/WTFString.h>
 
 namespace JSC {
 
 struct SourceProviderCacheItemCreationParameters {
     unsigned functionNameStart;
-    unsigned closeBraceLine;
-    unsigned closeBraceOffset;
-    unsigned closeBraceLineStartOffset;
+    unsigned lastTockenLine;
+    unsigned lastTockenStartOffset;
+    unsigned lastTockenEndOffset;
+    unsigned lastTockenLineStartOffset;
+    unsigned endFunctionOffset;
     bool needsFullActivation;
     bool usesEval;
     bool strictMode;
-    Vector<RefPtr<StringImpl>> usedVariables;
-    Vector<RefPtr<StringImpl>> writtenVariables;
+    Vector<RefPtr<UniquedStringImpl>> usedVariables;
+    Vector<RefPtr<UniquedStringImpl>> writtenVariables;
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    bool isBodyArrowExpression { false };
+    JSTokenType tokenType { CLOSEBRACE };
+#endif
 };
 
 #if COMPILER(MSVC)
@@ -56,15 +62,19 @@ public:
     static std::unique_ptr<SourceProviderCacheItem> create(const SourceProviderCacheItemCreationParameters&);
     ~SourceProviderCacheItem();
 
-    JSToken closeBraceToken() const 
+    JSToken endFunctionToken() const 
     {
         JSToken token;
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+        token.m_type = isBodyArrowExpression ? tokenType : CLOSEBRACE;
+#else
         token.m_type = CLOSEBRACE;
-        token.m_data.offset = closeBraceOffset;
-        token.m_location.startOffset = closeBraceOffset;
-        token.m_location.endOffset = closeBraceOffset + 1;
-        token.m_location.line = closeBraceLine;
-        token.m_location.lineStartOffset = closeBraceLineStartOffset;
+#endif
+        token.m_data.offset = lastTockenStartOffset;
+        token.m_location.startOffset = lastTockenStartOffset;
+        token.m_location.endOffset = lastTockenEndOffset;
+        token.m_location.line = lastTockenLine;
+        token.m_location.lineStartOffset = lastTockenLineStartOffset;
         // token.m_location.sourceOffset is initialized once by the client. So,
         // we do not need to set it here.
         return token;
@@ -72,24 +82,31 @@ public:
 
     unsigned functionNameStart : 31;
     bool needsFullActivation : 1;
+
+    unsigned endFunctionOffset : 31;
+    unsigned lastTockenLine : 31;
+    unsigned lastTockenStartOffset : 31;
+    unsigned lastTockenEndOffset: 31;
     
-    unsigned closeBraceLine : 31;
     bool usesEval : 1;
 
-    unsigned closeBraceOffset : 31;
     bool strictMode : 1;
 
-    unsigned closeBraceLineStartOffset;
+    unsigned lastTockenLineStartOffset;
     unsigned usedVariablesCount;
     unsigned writtenVariablesCount;
 
-    StringImpl** usedVariables() const { return const_cast<StringImpl**>(m_variables); }
-    StringImpl** writtenVariables() const { return const_cast<StringImpl**>(&m_variables[usedVariablesCount]); }
+    UniquedStringImpl** usedVariables() const { return const_cast<UniquedStringImpl**>(m_variables); }
+    UniquedStringImpl** writtenVariables() const { return const_cast<UniquedStringImpl**>(&m_variables[usedVariablesCount]); }
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    bool isBodyArrowExpression;
+    JSTokenType tokenType;
+#endif
 
 private:
     SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters&);
 
-    StringImpl* m_variables[0];
+    UniquedStringImpl* m_variables[0];
 };
 
 inline SourceProviderCacheItem::~SourceProviderCacheItem()
@@ -101,7 +118,7 @@ inline SourceProviderCacheItem::~SourceProviderCacheItem()
 inline std::unique_ptr<SourceProviderCacheItem> SourceProviderCacheItem::create(const SourceProviderCacheItemCreationParameters& parameters)
 {
     size_t variableCount = parameters.writtenVariables.size() + parameters.usedVariables.size();
-    size_t objectSize = sizeof(SourceProviderCacheItem) + sizeof(StringImpl*) * variableCount;
+    size_t objectSize = sizeof(SourceProviderCacheItem) + sizeof(UniquedStringImpl*) * variableCount;
     void* slot = fastMalloc(objectSize);
     return std::unique_ptr<SourceProviderCacheItem>(new (slot) SourceProviderCacheItem(parameters));
 }
@@ -109,13 +126,19 @@ inline std::unique_ptr<SourceProviderCacheItem> SourceProviderCacheItem::create(
 inline SourceProviderCacheItem::SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters& parameters)
     : functionNameStart(parameters.functionNameStart)
     , needsFullActivation(parameters.needsFullActivation)
-    , closeBraceLine(parameters.closeBraceLine)
+    , endFunctionOffset(parameters.endFunctionOffset)
+    , lastTockenLine(parameters.lastTockenLine)
+    , lastTockenStartOffset(parameters.lastTockenStartOffset)
+    , lastTockenEndOffset(parameters.lastTockenEndOffset)
     , usesEval(parameters.usesEval)
-    , closeBraceOffset(parameters.closeBraceOffset)
     , strictMode(parameters.strictMode)
-    , closeBraceLineStartOffset(parameters.closeBraceLineStartOffset)
+    , lastTockenLineStartOffset(parameters.lastTockenLineStartOffset)
     , usedVariablesCount(parameters.usedVariables.size())
     , writtenVariablesCount(parameters.writtenVariables.size())
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    , isBodyArrowExpression(parameters.isBodyArrowExpression)
+    , tokenType(parameters.tokenType)
+#endif
 {
     unsigned j = 0;
     for (unsigned i = 0; i < usedVariablesCount; ++i, ++j) {
index 8912d8b88b839d0f9577be10649fbdda8f7abffd..a3306d20726496ced102cf0d300c18e23c9de1a8 100644 (file)
@@ -27,6 +27,7 @@
 #define SyntaxChecker_h
 
 #include "Lexer.h"
+#include "ParserFunctionInfo.h"
 #include "YarrSyntaxChecker.h"
 
 namespace JSC {
@@ -70,17 +71,20 @@ public:
 
     typedef SyntaxChecker FunctionBodyBuilder;
     enum { NoneExpr = 0,
-        ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr,
+        ResolveEvalExpr, ResolveExpr, IntegerExpr, DoubleExpr, StringExpr,
         ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
-        FunctionExpr, BracketExpr, DotExpr, CallExpr,
+        FunctionExpr, ClassExpr, SuperExpr, BracketExpr, DotExpr, CallExpr,
         NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
         ConditionalExpr, AssignmentExpr, TypeofExpr,
-        DeleteExpr, ArrayLiteralExpr, BindingDeconstruction,
-        ArrayDeconstruction, ObjectDeconstruction, SourceElementsResult,
+        DeleteExpr, ArrayLiteralExpr, BindingDestructuring,
+        ArrayDestructuring, ObjectDestructuring, SourceElementsResult,
         FunctionBodyResult, SpreadExpr, ArgumentsResult,
         PropertyListResult, ArgumentsListResult, ElementsListResult,
         StatementResult, FormalParameterListResult, ClauseResult,
-        ClauseListResult, CommaExpr, DeconstructingAssignment
+        ClauseListResult, CommaExpr, DestructuringAssignment,
+        TemplateStringResult, TemplateStringListResult,
+        TemplateExpressionListResult, TemplateExpr,
+        TaggedTemplateExpr
     };
     typedef int ExpressionType;
 
@@ -110,16 +114,25 @@ public:
     typedef int PropertyList;
     typedef int ElementList;
     typedef int ArgumentsList;
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    typedef int TemplateExpressionList;
+    typedef int TemplateString;
+    typedef int TemplateStringList;
+    typedef int TemplateLiteral;
+#endif
     typedef int FormalParameterList;
     typedef int FunctionBody;
+#if ENABLE(ES6_CLASS_SYNTAX)
+    typedef int ClassExpression;
+#endif
     typedef int Statement;
     typedef int ClauseList;
     typedef int Clause;
     typedef int ConstDeclList;
     typedef int BinaryOperand;
-    typedef int DeconstructionPattern;
-    typedef DeconstructionPattern ArrayPattern;
-    typedef DeconstructionPattern ObjectPattern;
+    typedef int DestructuringPattern;
+    typedef DestructuringPattern ArrayPattern;
+    typedef DestructuringPattern ObjectPattern;
 
     static const bool CreatesAST = false;
     static const bool NeedsFreeVariableInfo = false;
@@ -129,8 +142,8 @@ public:
 
     int createSourceElements() { return SourceElementsResult; }
     ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int) { return CallExpr; }
-    void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
-    ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType, ExpressionType right) { return right; }
+    ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType expr) { return expr; }
+    ExpressionType appendToCommaExpr(const JSTokenLocation&, ExpressionType& head, ExpressionType, ExpressionType next) { head = next; return next; }
     ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
     ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PreExpr; }
     ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PostExpr; }
@@ -141,13 +154,15 @@ public:
     ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
     ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
     ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
-    ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; }
+    ExpressionType thisExpr(const JSTokenLocation&, ThisTDZMode) { return ThisExpr; }
+    ExpressionType superExpr(const JSTokenLocation&) { return SuperExpr; }
     ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; }
     ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
     ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; }
     ExpressionType createArray(const JSTokenLocation&, int) { return ArrayLiteralExpr; }
     ExpressionType createArray(const JSTokenLocation&, int, int) { return ArrayLiteralExpr; }
-    ExpressionType createNumberExpr(const JSTokenLocation&, double) { return NumberExpr; }
+    ExpressionType createDoubleExpr(const JSTokenLocation&, double) { return DoubleExpr; }
+    ExpressionType createIntegerExpr(const JSTokenLocation&, double) { return IntegerExpr; }
     ExpressionType createString(const JSTokenLocation&, const Identifier*) { return StringExpr; }
     ExpressionType createBoolean(const JSTokenLocation&, bool) { return BoolExpr; }
     ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
@@ -158,28 +173,46 @@ public:
     ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; }
     ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
     ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
-    ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; }
-    int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool) { return FunctionBodyResult; }
+    ExpressionType createEmptyVarExpression(const JSTokenLocation&, const Identifier&) { return AssignmentExpr; }
+#if ENABLE(ES6_CLASS_SYNTAX)
+    ClassExpression createClassExpr(const JSTokenLocation&, const Identifier&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
+#endif
+    ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
+    int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind) { return FunctionBodyResult; }
+#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
+    ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
+#endif 
     void setFunctionNameStart(int, int) { }
     int createArguments() { return ArgumentsResult; }
     int createArguments(int) { return ArgumentsResult; }
     ExpressionType createSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return SpreadExpr; }
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    TemplateString createTemplateString(const JSTokenLocation&, const Identifier&, const Identifier&) { return TemplateStringResult; }
+    TemplateStringList createTemplateStringList(TemplateString) { return TemplateStringListResult; }
+    TemplateStringList createTemplateStringList(TemplateStringList, TemplateString) { return TemplateStringListResult; }
+    TemplateExpressionList createTemplateExpressionList(Expression) { return TemplateExpressionListResult; }
+    TemplateExpressionList createTemplateExpressionList(TemplateExpressionList, Expression) { return TemplateExpressionListResult; }
+    TemplateLiteral createTemplateLiteral(const JSTokenLocation&, TemplateStringList) { return TemplateExpr; }
+    TemplateLiteral createTemplateLiteral(const JSTokenLocation&, TemplateStringList, TemplateExpressionList) { return TemplateExpr; }
+    ExpressionType createTaggedTemplate(const JSTokenLocation&, ExpressionType, TemplateLiteral, int, int, int) { return TaggedTemplateExpr; }
+#endif
+
     int createArgumentsList(const JSTokenLocation&, int) { return ArgumentsListResult; }
     int createArgumentsList(const JSTokenLocation&, int, int) { return ArgumentsListResult; }
-    Property createProperty(const Identifier* name, int, PropertyNode::Type type, bool complete)
+    Property createProperty(const Identifier* name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete, SuperBinding = SuperBinding::NotNeeded)
     {
         if (!complete)
             return Property(type);
         ASSERT(name);
         return Property(name, type);
     }
-    Property createProperty(VM* vm, double name, int, PropertyNode::Type type, bool complete)
+    Property createProperty(VM* vm, ParserArena& parserArena, double name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete)
     {
         if (!complete)
             return Property(type);
-        return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
+        return Property(&parserArena.identifierArena().makeNumericIdentifier(vm, name), type);
     }
-    Property createProperty(VM*, ExpressionNode*, int, PropertyNode::Type type, bool)
+    Property createProperty(int, int, PropertyNode::Type type, PropertyNode::PutType, bool)
     {
         return Property(type);
     }
@@ -187,13 +220,16 @@ public:
     int createPropertyList(const JSTokenLocation&, Property, int) { return PropertyListResult; }
     int createElementList(int, int) { return ElementsListResult; }
     int createElementList(int, int, int) { return ElementsListResult; }
-    int createFormalParameterList(DeconstructionPattern) { return FormalParameterListResult; }
-    int createFormalParameterList(int, DeconstructionPattern) { return FormalParameterListResult; }
+    int createFormalParameterList(DestructuringPattern) { return FormalParameterListResult; }
+    int createFormalParameterList(int, DestructuringPattern) { return FormalParameterListResult; }
     int createClause(int, int) { return ClauseResult; }
     int createClauseList(int) { return ClauseListResult; }
     int createClauseList(int, int) { return ClauseListResult; }
-    void setUsesArguments(int) { }
-    int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return StatementResult; }
+    int createFuncDeclStatement(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return StatementResult; }
+#if ENABLE(ES6_CLASS_SYNTAX)
+    int createClassDeclStatement(const JSTokenLocation&, ClassExpression,
+        const JSTextPosition&, const JSTextPosition&, int, int) { return StatementResult; }
+#endif
     int createBlockStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int createExprStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int createIfStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
@@ -218,18 +254,18 @@ public:
     int createDebugger(const JSTokenLocation&, int, int) { return StatementResult; }
     int createConstStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return StatementResult; }
-    Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, int, int, int, int, int, int, int)
+    Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, const ParserFunctionInfo<SyntaxChecker>&, SuperBinding)
     {
         ASSERT(name);
         if (!strict)
             return Property(type);
         return Property(name, type);
     }
-    Property createGetterOrSetterProperty(VM* vm, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, int, int, int, int, int, int, int)
+    Property createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, const ParserFunctionInfo<SyntaxChecker>&, SuperBinding)
     {
         if (!strict)
             return Property(type);
-        return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
+        return Property(&parserArena.identifierArena().makeNumericIdentifier(vm, name), type);
     }
 
     void appendStatement(int, int) { }
@@ -261,41 +297,51 @@ public:
     
     void assignmentStackAppend(int, int, int, int, int, Operator) { }
     int createAssignment(const JSTokenLocation&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return AssignmentExpr; }
-    const Identifier* getName(const Property& property) const { ASSERT(property.name); return property.name; }
+    const Identifier* getName(const Property& property) const { return property.name; }
     PropertyNode::Type getType(const Property& property) const { return property.type; }
     bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
-    ExpressionType createDeconstructingAssignment(const JSTokenLocation&, int, ExpressionType)
+    ExpressionType createDestructuringAssignment(const JSTokenLocation&, int, ExpressionType)
     {
-        return DeconstructingAssignment;
+        return DestructuringAssignment;
     }
     
     ArrayPattern createArrayPattern(const JSTokenLocation&)
     {
-        return ArrayDeconstruction;
+        return ArrayDestructuring;
     }
     void appendArrayPatternSkipEntry(ArrayPattern, const JSTokenLocation&)
     {
     }
-    void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern)
+    void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DestructuringPattern, int)
+    {
+    }
+    void appendArrayPatternRestEntry(ArrayPattern, const JSTokenLocation&, DestructuringPattern)
+    {
+    }
+    void finishArrayPattern(ArrayPattern, const JSTextPosition&, const JSTextPosition&, const JSTextPosition&)
     {
     }
     ObjectPattern createObjectPattern(const JSTokenLocation&)
     {
-        return ObjectDeconstruction;
+        return ObjectDestructuring;
     }
-    void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern)
+    void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DestructuringPattern, int)
     {
     }
-    DeconstructionPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&)
+    DestructuringPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&)
     {
-        return BindingDeconstruction;
+        return BindingDestructuring;
     }
 
-    bool isBindingNode(DeconstructionPattern pattern)
+    bool isBindingNode(DestructuringPattern pattern)
     {
-        return pattern == BindingDeconstruction;
+        return pattern == BindingDestructuring;
     }
 
+    void setEndOffset(int, int) { }
+    int endOffset(int) { return 0; }
+    void setStartOffset(int, int) { }
+
 private:
     int m_topBinaryExpr;
     int m_topUnaryToken;
index 92dad5c7cf73626d40f53947f3dc1e86a7cf430f..3ae3b0ca9e51d14429e976ef5072bf969b880aab 100755 (executable)
@@ -1,12 +1,6 @@
 cd "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}"
 
-if [[ ${TARGET_MAC_OS_X_VERSION_MAJOR} == "1080" ]]; then
-    UNIFDEF_OPTIONS="-DJSC_OBJC_API_AVAILABLE_MAC_OS_X_1080";
-else
-    UNIFDEF_OPTIONS="-UJSC_OBJC_API_AVAILABLE_MAC_OS_X_1080";
-fi
-
-UNIFDEF_OPTIONS+=" -D__MAC_OS_X_VERSION_MIN_REQUIRED=${TARGET_MAC_OS_X_VERSION_MAJOR}"
+UNIFDEF_OPTIONS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=${TARGET_MAC_OS_X_VERSION_MAJOR}"
 
 for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do
     eval HEADER=\${SCRIPT_INPUT_FILE_${i}};
@@ -22,4 +16,3 @@ for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do
         exit 1
     esac
 done
-
index 33ff454b75171505871aa525576b6c3e6fc115c8..787d362dce4c7a6cccd7fab50179b736a5788cfd 100644 (file)
@@ -49,16 +49,16 @@ static unsigned ProfilesUID = 0;
 
 static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber);
 
-LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0;
+LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = nullptr;
 
 LegacyProfiler* LegacyProfiler::profiler()
 {
     if (!s_sharedLegacyProfiler)
         s_sharedLegacyProfiler = new LegacyProfiler();
     return s_sharedLegacyProfiler;
-}   
+}
 
-void LegacyProfiler::startProfiling(ExecState* exec, const String& title)
+void LegacyProfiler::startProfiling(ExecState* exec, const String& title, PassRefPtr<Stopwatch> stopwatch)
 {
     if (!exec)
         return;
@@ -74,14 +74,14 @@ void LegacyProfiler::startProfiling(ExecState* exec, const String& title)
     }
 
     exec->vm().setEnabledProfiler(this);
-    RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
+    RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID, stopwatch);
     m_currentProfiles.append(profileGenerator);
 }
 
-PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title)
+RefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title)
 {
     if (!exec)
-        return 0;
+        return nullptr;
 
     JSGlobalObject* origin = exec->lexicalGlobalObject();
     for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
@@ -93,12 +93,12 @@ PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String&
             m_currentProfiles.remove(i);
             if (!m_currentProfiles.size())
                 exec->vm().setEnabledProfiler(nullptr);
-            
+
             return returnProfile;
         }
     }
 
-    return 0;
+    return nullptr;
 }
 
 void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
@@ -114,19 +114,37 @@ void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
     }
 }
 
-static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector<RefPtr<ProfileGenerator>>& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup)
+static inline void callFunctionForProfilesWithGroup(std::function<void(ProfileGenerator*)> callback, const Vector<RefPtr<ProfileGenerator>>& profiles, unsigned targetProfileGroup)
 {
-    for (size_t i = 0; i < profiles.size(); ++i) {
-        if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->origin())
-            (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier);
+    for (const RefPtr<ProfileGenerator>& profile : profiles) {
+        if (profile->profileGroup() == targetProfileGroup || !profile->origin())
+            callback(profile.get());
     }
 }
 
+void LegacyProfiler::suspendProfiling(JSC::ExecState* exec)
+{
+    if (!exec)
+        return;
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::setIsSuspended, std::placeholders::_1, true), m_currentProfiles, exec->lexicalGlobalObject()->profileGroup());
+}
+
+void LegacyProfiler::unsuspendProfiling(JSC::ExecState* exec)
+{
+    if (!exec)
+        return;
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::setIsSuspended, std::placeholders::_1, false), m_currentProfiles, exec->lexicalGlobalObject()->profileGroup());
+}
+
 void LegacyProfiler::willExecute(ExecState* callerCallFrame, JSValue function)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
+    CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0);
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::willExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup());
 }
 
 void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, unsigned startingLineNumber, unsigned startingColumnNumber)
@@ -135,28 +153,34 @@ void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourc
 
     CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber, startingColumnNumber);
 
-    dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup());
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::willExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup());
 }
 
 void LegacyProfiler::didExecute(ExecState* callerCallFrame, JSValue function)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
+    CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, function, StringImpl::empty(), 0, 0);
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::didExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup());
 }
 
 void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, unsigned startingLineNumber, unsigned startingColumnNumber)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber, startingColumnNumber), callerCallFrame->lexicalGlobalObject()->profileGroup());
+    CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber, startingColumnNumber);
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::didExecute, std::placeholders::_1, callerCallFrame, callIdentifier), m_currentProfiles, callerCallFrame->lexicalGlobalObject()->profileGroup());
 }
 
 void LegacyProfiler::exceptionUnwind(ExecState* handlerCallFrame)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    dispatchFunctionToProfiles(handlerCallFrame, m_currentProfiles, &ProfileGenerator::exceptionUnwind, createCallIdentifier(handlerCallFrame, JSValue(), StringImpl::empty(), 0, 0), handlerCallFrame->lexicalGlobalObject()->profileGroup());
+    CallIdentifier callIdentifier = createCallIdentifier(handlerCallFrame, JSValue(), StringImpl::empty(), 0, 0);
+
+    callFunctionForProfilesWithGroup(std::bind(&ProfileGenerator::exceptionUnwind, std::placeholders::_1, handlerCallFrame, callIdentifier), m_currentProfiles, handlerCallFrame->lexicalGlobalObject()->profileGroup());
 }
 
 CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber)
@@ -167,6 +191,8 @@ CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue fun
         return CallIdentifier(ASCIILiteral("(unknown)"), defaultSourceURL, defaultLineNumber, defaultColumnNumber);
     if (asObject(functionValue)->inherits(JSFunction::info()) || asObject(functionValue)->inherits(InternalFunction::info()))
         return createCallIdentifierFromFunctionImp(exec, asObject(functionValue), defaultSourceURL, defaultLineNumber, defaultColumnNumber);
+    if (asObject(functionValue)->inherits(JSCallee::info()))
+        return CallIdentifier(ASCIILiteral(GlobalCodeExecution), defaultSourceURL, defaultLineNumber, defaultColumnNumber);
     return CallIdentifier(asObject(functionValue)->methodTable()->className(asObject(functionValue)), defaultSourceURL, defaultLineNumber, defaultColumnNumber);
 }
 
@@ -175,7 +201,7 @@ CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSObject* fu
     const String& name = getCalculatedDisplayName(exec, function);
     JSFunction* jsFunction = jsDynamicCast<JSFunction*>(function);
     if (jsFunction && !jsFunction->isHostOrBuiltinFunction())
-        return CallIdentifier(name.isEmpty() ? ASCIILiteral(AnonymousFunction) : name, jsFunction->jsExecutable()->sourceURL(), jsFunction->jsExecutable()->lineNo(), jsFunction->jsExecutable()->startColumn());
+        return CallIdentifier(name.isEmpty() ? ASCIILiteral(AnonymousFunction) : name, jsFunction->jsExecutable()->sourceURL(), jsFunction->jsExecutable()->firstLine(), jsFunction->jsExecutable()->startColumn());
     return CallIdentifier(name.isEmpty() ? ASCIILiteral(AnonymousFunction) : name, defaultSourceURL, defaultLineNumber, defaultColumnNumber);
 }
 
index cc5f63b0bb93fadedfc62cdfa168d3d74be65d0e..af0ab41e26720c54ae53cdcf5953e3312fba48fb 100644 (file)
 #include "Profile.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
+#include <wtf/Stopwatch.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
 
 class ExecState;
-class VM;
 class JSGlobalObject;
 class JSObject;
 class JSValue;
@@ -47,13 +47,17 @@ struct CallIdentifier;
 class LegacyProfiler {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    JS_EXPORT_PRIVATE static LegacyProfiler* profiler(); 
+    JS_EXPORT_PRIVATE static LegacyProfiler* profiler();
     static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber);
 
-    JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title);
-    JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
+    JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title, PassRefPtr<Stopwatch>);
+    JS_EXPORT_PRIVATE RefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
     void stopProfiling(JSGlobalObject*);
 
+    // Used to ignore profile node subtrees rooted at InjectedScript calls.
+    JS_EXPORT_PRIVATE void suspendProfiling(ExecState*);
+    JS_EXPORT_PRIVATE void unsuspendProfiling(ExecState*);
+
     void willExecute(ExecState* callerCallFrame, JSValue function);
     void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, unsigned startingLineNumber, unsigned startingColumnNumber);
     void didExecute(ExecState* callerCallFrame, JSValue function);
index b5e022420aa574e53ce6bccf61974126fb21fe72..f3d450ab2303830dc23102156cb01c69302d3a5f 100644 (file)
 
 namespace JSC {
 
-PassRefPtr<Profile> Profile::create(const String& title, unsigned uid)
+Ref<Profile> Profile::create(const String& title, unsigned uid, double startTime)
 {
-    return adoptRef(new Profile(title, uid));
+    return adoptRef(*new Profile(title, uid, startTime));
 }
 
-Profile::Profile(const String& title, unsigned uid)
+Profile::Profile(const String& title, unsigned uid, double startTime)
     : m_title(title)
     , m_uid(uid)
-    , m_idleTime(0)
 {
     // FIXME: When multi-threading is supported this will be a vector and calls
     // into the profiler will need to know which thread it is executing on.
-    m_head = ProfileNode::create(0, CallIdentifier("Thread_1", String(), 0, 0), 0, 0);
+    m_rootNode = ProfileNode::create(nullptr, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), nullptr);
+    m_rootNode->appendCall(ProfileNode::Call(startTime));
 }
 
 Profile::~Profile()
 {
 }
 
-void Profile::forEach(void (ProfileNode::*function)())
-{
-    ProfileNode* currentNode = m_head->firstChild();
-    for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
-        currentNode = nextNode;
-
-    if (!currentNode)
-        currentNode = m_head.get();
-
-    ProfileNode* endNode = m_head->traverseNextNodePostOrder();
-    while (currentNode && currentNode != endNode) {
-        (currentNode->*function)();
-        currentNode = currentNode->traverseNextNodePostOrder();
-    } 
-}
-
 #ifndef NDEBUG
-void Profile::debugPrintData() const
+void Profile::debugPrint()
 {
+    CalculateProfileSubtreeDataFunctor functor;
+    m_rootNode->forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = functor.returnValue();
+
     dataLogF("Call graph:\n");
-    m_head->debugPrintData(0);
+    m_rootNode->debugPrintRecursively(0, data);
 }
 
 typedef WTF::KeyValuePair<FunctionCallHashCount::ValueType, unsigned> NameCountPair;
@@ -80,13 +68,17 @@ static inline bool functionNameCountPairComparator(const NameCountPair& a, const
     return a.value > b.value;
 }
 
-void Profile::debugPrintDataSampleStyle() const
+void Profile::debugPrintSampleStyle()
 {
     typedef Vector<NameCountPair> NameCountPairVector;
 
+    CalculateProfileSubtreeDataFunctor functor;
+    m_rootNode->forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = functor.returnValue();
+
     FunctionCallHashCount countedFunctions;
     dataLogF("Call graph:\n");
-    m_head->debugPrintDataSampleStyle(0, countedFunctions);
+    m_rootNode->debugPrintSampleStyleRecursively(0, countedFunctions, data);
 
     dataLogF("\nTotal number in stack:\n");
     NameCountPairVector sortedFunctions(countedFunctions.size());
index 8984eaf2c54c16c9187fcd5c6b9c6e8e7cb351ea..41cb670cae7ca9eb17ae464dac3ee31c1a1f1f92 100644 (file)
@@ -35,38 +35,30 @@ namespace JSC {
 
 class JS_EXPORT_PRIVATE Profile : public RefCounted<Profile> {
 public:
-    static PassRefPtr<Profile> create(const String& title, unsigned uid);
+    static Ref<Profile> create(const String& title, unsigned uid, double);
     virtual ~Profile();
 
     const String& title() const { return m_title; }
     unsigned uid() const { return m_uid; }
 
-    ProfileNode* head() const { return m_head.get(); }
-    void setHead(PassRefPtr<ProfileNode> head) { m_head = head; }
-
-    double totalTime() const { return m_head->totalTime(); }
-
-    double idleTime() const { return m_idleTime; }
-    void setIdleTime(double idleTime) { m_idleTime = idleTime; }
-
-    void forEach(void (ProfileNode::*)());
+    ProfileNode* rootNode() const { return m_rootNode.get(); }
+    void setRootNode(PassRefPtr<ProfileNode> rootNode) { m_rootNode = rootNode; }
 
 #ifndef NDEBUG
-    void debugPrintData() const;
-    void debugPrintDataSampleStyle() const;
+    void debugPrint();
+    void debugPrintSampleStyle();
 #endif
 
 protected:
-    Profile(const String& title, unsigned uid);
+    Profile(const String& title, unsigned uid, double startTime);
 
 private:
     void removeProfileStart();
     void removeProfileEnd();
 
     String m_title;
-    RefPtr<ProfileNode> m_head;
+    RefPtr<ProfileNode> m_rootNode;
     unsigned m_uid;
-    double m_idleTime;
 };
 
 } // namespace JSC
index d37b3566ccacc8fe2c8e5ad1b3739861e4169eaa..f70e4a3f6499d4d0b486c12e00d839015d9d52a7 100644 (file)
 
 namespace JSC {
 
-PassRefPtr<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const String& title, unsigned uid)
+Ref<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const String& title, unsigned uid, PassRefPtr<Stopwatch> stopwatch)
 {
-    return adoptRef(new ProfileGenerator(exec, title, uid));
+    return adoptRef(*new ProfileGenerator(exec, title, uid, stopwatch));
 }
 
-ProfileGenerator::ProfileGenerator(ExecState* exec, const String& title, unsigned uid)
-    : m_origin(exec ? exec->lexicalGlobalObject() : 0)
+ProfileGenerator::ProfileGenerator(ExecState* exec, const String& title, unsigned uid, PassRefPtr<Stopwatch> stopwatch)
+    : m_origin(exec ? exec->lexicalGlobalObject() : nullptr)
     , m_profileGroup(exec ? exec->lexicalGlobalObject()->profileGroup() : 0)
+    , m_stopwatch(stopwatch)
     , m_foundConsoleStartParent(false)
+    , m_suspended(false)
 {
-    m_profile = Profile::create(title, uid);
-    m_currentNode = m_head = m_profile->head();
+    double startTime = m_stopwatch->elapsedTime();
+    m_profile = Profile::create(title, uid, startTime);
+    m_currentNode = m_rootNode = m_profile->rootNode();
     if (exec)
-        addParentForConsoleStart(exec);
+        addParentForConsoleStart(exec, startTime);
 }
 
 class AddParentForConsoleStartFunctor {
 public:
-    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)
+    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode, double startTime)
         : m_exec(exec)
         , m_hasSkippedFirstFrame(false)
         , m_foundParent(false)
-        , m_head(head)
+        , m_rootNode(rootNode)
         , m_currentNode(currentNode)
+        , m_startTime(startTime)
     {
     }
 
@@ -78,8 +82,9 @@ public:
         unsigned line = 0;
         unsigned column = 0;
         visitor->computeLineAndColumn(line, column);
-        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_head.get(), m_head.get());
-        m_head->insertNode(m_currentNode.get());
+        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_rootNode.get());
+        m_currentNode->appendCall(ProfileNode::Call(m_startTime));
+        m_rootNode->spliceNode(m_currentNode.get());
 
         m_foundParent = true;
         return StackVisitor::Done;
@@ -88,14 +93,15 @@ public:
 private:
     ExecState* m_exec;
     bool m_hasSkippedFirstFrame;
-    bool m_foundParent; 
-    RefPtr<ProfileNode>& m_head;
+    bool m_foundParent;
+    RefPtr<ProfileNode>& m_rootNode;
     RefPtr<ProfileNode>& m_currentNode;
+    double m_startTime;
 };
 
-void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
+void ProfileGenerator::addParentForConsoleStart(ExecState* exec, double startTime)
 {
-    AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
+    AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode, startTime);
     exec->iterate(functor);
 
     m_foundConsoleStartParent = functor.foundParent();
@@ -106,19 +112,56 @@ const String& ProfileGenerator::title() const
     return m_profile->title();
 }
 
+void ProfileGenerator::beginCallEntry(ProfileNode* node, double startTime)
+{
+    ASSERT_ARG(node, node);
+
+    if (std::isnan(startTime))
+        startTime = m_stopwatch->elapsedTime();
+
+    node->appendCall(ProfileNode::Call(startTime));
+}
+
+void ProfileGenerator::endCallEntry(ProfileNode* node)
+{
+    ASSERT_ARG(node, node);
+
+    ProfileNode::Call& last = node->lastCall();
+
+    double previousElapsedTime = std::isnan(last.elapsedTime()) ? 0.0 : last.elapsedTime();
+    double newlyElapsedTime = m_stopwatch->elapsedTime() - last.startTime();
+    last.setElapsedTime(previousElapsedTime + newlyElapsedTime);
+}
+
 void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
 {
     if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
         CString name = callIdentifier.functionName().utf8();
         CString url = callIdentifier.url().utf8();
-        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber());
+        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
     }
 
     if (!m_origin)
         return;
 
-    ASSERT(m_currentNode);
-    m_currentNode = m_currentNode->willExecute(callerCallFrame, callIdentifier);
+    if (m_suspended)
+        return;
+
+    RefPtr<ProfileNode> calleeNode = nullptr;
+
+    // Find or create a node for the callee call frame.
+    for (const RefPtr<ProfileNode>& child : m_currentNode->children()) {
+        if (child->callIdentifier() == callIdentifier)
+            calleeNode = child;
+    }
+
+    if (!calleeNode) {
+        calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
+        m_currentNode->addChild(calleeNode);
+    }
+
+    m_currentNode = calleeNode;
+    beginCallEntry(calleeNode.get(), m_stopwatch->elapsedTime());
 }
 
 void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
@@ -126,26 +169,35 @@ void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifi
     if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
         CString name = callIdentifier.functionName().utf8();
         CString url = callIdentifier.url().utf8();
-        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber());
+        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
     }
 
     if (!m_origin)
         return;
 
+    if (m_suspended)
+        return;
+
+    // Make a new node if the caller node has never seen this callee call frame before.
+    // This can happen if |console.profile()| is called several frames deep in the call stack.
     ASSERT(m_currentNode);
     if (m_currentNode->callIdentifier() != callIdentifier) {
-        RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
-        returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime());
-        returningNode->didExecute();
-        m_currentNode->insertNode(returningNode.release());
+        RefPtr<ProfileNode> calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
+        beginCallEntry(calleeNode.get(), m_currentNode->lastCall().startTime());
+        endCallEntry(calleeNode.get());
+        m_currentNode->spliceNode(calleeNode.release());
         return;
     }
 
-    m_currentNode = m_currentNode->didExecute();
+    endCallEntry(m_currentNode.get());
+    m_currentNode = m_currentNode->parent();
 }
 
 void ProfileGenerator::exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&)
 {
+    if (m_suspended)
+        return;
+
     // If the current node was called by the handler (==) or any
     // more nested function (>) the we have exited early from it.
     ASSERT(m_currentNode);
@@ -157,7 +209,8 @@ void ProfileGenerator::exceptionUnwind(ExecState* handlerCallFrame, const CallId
 
 void ProfileGenerator::stopProfiling()
 {
-    m_profile->forEach(&ProfileNode::stopProfiling);
+    for (ProfileNode* node = m_currentNode.get(); node != m_profile->rootNode(); node = node->parent())
+        endCallEntry(node);
 
     if (m_foundConsoleStartParent) {
         removeProfileStart();
@@ -169,41 +222,31 @@ void ProfileGenerator::stopProfiling()
     // Set the current node to the parent, because we are in a call that
     // will not get didExecute call.
     m_currentNode = m_currentNode->parent();
-
-    if (double headSelfTime = m_head->selfTime()) {
-        m_head->setSelfTime(0.0);
-        m_profile->setIdleTime(headSelfTime);
-    }
 }
 
 // The console.profile that started this ProfileGenerator will be the first child.
 void ProfileGenerator::removeProfileStart()
 {
-    ProfileNode* currentNode = 0;
-    for (ProfileNode* next = m_head.get(); next; next = next->firstChild())
+    ProfileNode* currentNode = nullptr;
+    for (ProfileNode* next = m_rootNode.get(); next; next = next->firstChild())
         currentNode = next;
 
     if (currentNode->callIdentifier().functionName() != "profile")
         return;
 
-    // Attribute the time of the node aobut to be removed to the self time of its parent
-    currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
     currentNode->parent()->removeChild(currentNode);
 }
 
 // The console.profileEnd that stopped this ProfileGenerator will be the last child.
 void ProfileGenerator::removeProfileEnd()
 {
-    ProfileNode* currentNode = 0;
-    for (ProfileNode* next = m_head.get(); next; next = next->lastChild())
+    ProfileNode* currentNode = nullptr;
+    for (ProfileNode* next = m_rootNode.get(); next; next = next->lastChild())
         currentNode = next;
 
     if (currentNode->callIdentifier().functionName() != "profileEnd")
         return;
 
-    // Attribute the time of the node aobut to be removed to the self time of its parent
-    currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
-
     ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
     currentNode->parent()->removeChild(currentNode);
 }
index 03de0699cc6a190ee6d875c9b7045901bd2bfa5e..387ed5f4a704433d063dc7c6911bde183115d8fb 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #ifndef ProfileGenerator_h
 #define ProfileGenerator_h
 
-#include "Profile.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
+#include <wtf/Stopwatch.h>
+#include <wtf/text/WTFString.h>
 
 namespace JSC {
 
+    class DebuggerCallFrame;
     class ExecState;
     class JSGlobalObject;
     class Profile;
     class ProfileNode;
-    struct CallIdentifier;    
+    struct CallIdentifier;
 
     class ProfileGenerator : public RefCounted<ProfileGenerator>  {
     public:
-        static PassRefPtr<ProfileGenerator> create(ExecState*, const WTF::String& title, unsigned uid);
+        static Ref<ProfileGenerator> create(ExecState*, const WTF::String& title, unsigned uid, PassRefPtr<Stopwatch>);
 
         // Members
         const WTF::String& title() const;
@@ -49,30 +51,32 @@ namespace JSC {
         JSGlobalObject* origin() const { return m_origin; }
         unsigned profileGroup() const { return m_profileGroup; }
 
-        // Collecting
         void willExecute(ExecState* callerCallFrame, const CallIdentifier&);
         void didExecute(ExecState* callerCallFrame, const CallIdentifier&);
-
         void exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&);
 
-        // Stopping Profiling
-        void stopProfiling();
+        void setIsSuspended(bool suspended) { ASSERT(m_suspended != suspended); m_suspended = suspended; }
 
-        typedef void (ProfileGenerator::*ProfileFunction)(ExecState* callerOrHandlerCallFrame, const CallIdentifier& callIdentifier);
+        void stopProfiling();
 
     private:
-        ProfileGenerator(ExecState*, const WTF::String& title, unsigned uid);
-        void addParentForConsoleStart(ExecState*);
+        ProfileGenerator(ExecState*, const WTF::String& title, unsigned uid, PassRefPtr<Stopwatch>);
+        void addParentForConsoleStart(ExecState*, double);
 
         void removeProfileStart();
         void removeProfileEnd();
 
+        void beginCallEntry(ProfileNode*, double startTime);
+        void endCallEntry(ProfileNode*);
+
         RefPtr<Profile> m_profile;
         JSGlobalObject* m_origin;
         unsigned m_profileGroup;
-        RefPtr<ProfileNode> m_head;
+        RefPtr<Stopwatch> m_stopwatch;
+        RefPtr<ProfileNode> m_rootNode;
         RefPtr<ProfileNode> m_currentNode;
         bool m_foundConsoleStartParent;
+        bool m_suspended;
     };
 
 } // namespace JSC
index cb8678724acdde8674cb6261ee2639331219728d..9bcf37586c6003edaf39aaf834619ace4edf247d 100644 (file)
@@ -38,58 +38,35 @@ using namespace WTF;
 
 namespace JSC {
 
-ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
     : m_callerCallFrame(callerCallFrame)
     , m_callIdentifier(callIdentifier)
-    , m_head(headNode)
     , m_parent(parentNode)
+#ifndef NDEBUG
     , m_nextSibling(nullptr)
-    , m_totalTime(0)
-    , m_selfTime(0)
+#endif
 {
-    startTimer();
 }
 
-ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy)
     : m_callerCallFrame(callerCallFrame)
     , m_callIdentifier(nodeToCopy->callIdentifier())
-    , m_head(headNode)
     , m_parent(nodeToCopy->parent())
-    , m_nextSibling(0)
-    , m_totalTime(nodeToCopy->totalTime())
-    , m_selfTime(nodeToCopy->selfTime())
     , m_calls(nodeToCopy->calls())
+#ifndef NDEBUG
+    , m_nextSibling(nullptr)
+#endif
 {
 }
 
-ProfileNode* ProfileNode::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
-{
-    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) {
-        if ((*currentChild)->callIdentifier() == callIdentifier) {
-            (*currentChild)->startTimer();
-            return (*currentChild).get();
-        }
-    }
-
-    RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
-    if (m_children.size())
-        m_children.last()->setNextSibling(newChild.get());
-    m_children.append(newChild.release());
-    return m_children.last().get();
-}
-
-ProfileNode* ProfileNode::didExecute()
-{
-    endAndRecordCall();
-    return m_parent;
-}
-
 void ProfileNode::addChild(PassRefPtr<ProfileNode> prpChild)
 {
     RefPtr<ProfileNode> child = prpChild;
     child->setParent(this);
+#ifndef NDEBUG
     if (m_children.size())
         m_children.last()->setNextSibling(child.get());
+#endif
     m_children.append(child.release());
 }
 
@@ -98,17 +75,18 @@ void ProfileNode::removeChild(ProfileNode* node)
     if (!node)
         return;
 
-    for (size_t i = 0; i < m_children.size(); ++i) {
-        if (*node == m_children[i].get()) {
-            m_children.remove(i);
-            break;
-        }
-    }
-    
-    resetChildrensSiblings();
+    m_children.removeFirstMatching([node] (const RefPtr<ProfileNode>& current) {
+        return *node == current.get();
+    });
+
+#ifndef NDEBUG
+    size_t size = m_children.size();
+    for (size_t i = 0; i < size; ++i)
+        m_children[i]->setNextSibling(i + 1 == size ? nullptr : m_children[i + 1].get());
+#endif
 }
 
-void ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode)
+void ProfileNode::spliceNode(PassRefPtr<ProfileNode> prpNode)
 {
     RefPtr<ProfileNode> node = prpNode;
 
@@ -119,21 +97,7 @@ void ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode)
     m_children.append(node.release());
 }
 
-void ProfileNode::stopProfiling()
-{
-    ASSERT(!m_calls.isEmpty());
-
-    if (isnan(m_calls.last().totalTime()))
-        endAndRecordCall();
-
-    // Because we iterate in post order all of our children have been stopped before us.
-    for (unsigned i = 0; i < m_children.size(); ++i)
-        m_selfTime += m_children[i]->totalTime();
-
-    ASSERT(m_selfTime <= m_totalTime);
-    m_selfTime = m_totalTime - m_selfTime;
-}
-
+#ifndef NDEBUG
 ProfileNode* ProfileNode::traverseNextNodePostOrder() const
 {
     ProfileNode* next = m_nextSibling;
@@ -144,55 +108,63 @@ ProfileNode* ProfileNode::traverseNextNodePostOrder() const
     return next;
 }
 
-void ProfileNode::endAndRecordCall()
+void ProfileNode::debugPrint()
 {
-    Call& last = lastCall();
-    ASSERT(isnan(last.totalTime()));
-
-    last.setTotalTime(currentTime() - last.startTime());
+    CalculateProfileSubtreeDataFunctor functor;
+    forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = functor.returnValue();
 
-    m_totalTime += last.totalTime();
+    debugPrintRecursively(0, data);
 }
 
-void ProfileNode::startTimer()
+void ProfileNode::debugPrintSampleStyle()
 {
-    m_calls.append(Call(currentTime()));
-}
+    FunctionCallHashCount countedFunctions;
 
-void ProfileNode::resetChildrensSiblings()
-{
-    unsigned size = m_children.size();
-    for (unsigned i = 0; i < size; ++i)
-        m_children[i]->setNextSibling(i + 1 == size ? 0 : m_children[i + 1].get());
+    CalculateProfileSubtreeDataFunctor functor;
+    forEachNodePostorder(functor);
+    ProfileNode::ProfileSubtreeData data = functor.returnValue();
+
+    debugPrintSampleStyleRecursively(0, countedFunctions, data);
 }
 
-#ifndef NDEBUG
-void ProfileNode::debugPrintData(int indentLevel) const
+void ProfileNode::debugPrintRecursively(int indentLevel, const ProfileSubtreeData& data)
 {
     // Print function names
     for (int i = 0; i < indentLevel; ++i)
         dataLogF("  ");
 
+    auto it = data.selfAndTotalTimes.find(this);
+    ASSERT(it != data.selfAndTotalTimes.end());
+
+    double nodeSelfTime = it->value.first;
+    double nodeTotalTime = it->value.second;
+    double rootTotalTime = data.rootTotalTime;
+
     dataLogF("Function Name %s %zu SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n",
         functionName().utf8().data(),
-        numberOfCalls(), m_selfTime, selfPercent(), m_totalTime, totalPercent(),
+        m_calls.size(), nodeSelfTime, nodeSelfTime / rootTotalTime * 100.0, nodeTotalTime, nodeTotalTime / rootTotalTime * 100.0,
         m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
 
     ++indentLevel;
 
     // Print children's names and information
     for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
-        (*currentChild)->debugPrintData(indentLevel);
+        (*currentChild)->debugPrintRecursively(indentLevel, data);
 }
 
 // print the profiled data in a format that matches the tool sample's output.
-double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
+double ProfileNode::debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount& countedFunctions, const ProfileSubtreeData& data)
 {
     dataLogF("    ");
 
+    auto it = data.selfAndTotalTimes.find(this);
+    ASSERT(it != data.selfAndTotalTimes.end());
+    double nodeTotalTime = it->value.second;
+
     // Print function names
     const char* name = functionName().utf8().data();
-    double sampleCount = m_totalTime * 1000;
+    double sampleCount = nodeTotalTime * 1000;
     if (indentLevel) {
         for (int i = 0; i < indentLevel; ++i)
             dataLogF("  ");
@@ -208,7 +180,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
     // Print children's names and information
     double sumOfChildrensCount = 0.0;
     for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
-        sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
+        sumOfChildrensCount += (*currentChild)->debugPrintSampleStyleRecursively(indentLevel, countedFunctions, data);
 
     sumOfChildrensCount *= 1000;    //
     // Print remainder of samples to match sample's output
@@ -220,7 +192,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
         dataLogF("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data());
     }
 
-    return m_totalTime;
+    return nodeTotalTime;
 }
 #endif
 
index 2bb3406c0492c8b8be5dfa4a3162da72a25feb51..fcaee0e242299c656b5a5a767a0411d55aede713 100644 (file)
@@ -44,43 +44,45 @@ namespace JSC {
 
     class ProfileNode : public RefCounted<ProfileNode> {
     public:
-        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+        static Ref<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
         {
-            return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode));
+            return adoptRef(*new ProfileNode(callerCallFrame, callIdentifier, parentNode));
         }
 
-        static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node)
+        static Ref<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* node)
         {
-            return adoptRef(new ProfileNode(callerCallFrame, headNode, node));
+            return adoptRef(*new ProfileNode(callerCallFrame, node));
         }
 
         struct Call {
         public:
-            Call(double startTime, double totalTime = NAN)
+            Call(double startTime, double elapsedTime = NAN)
                 : m_startTime(startTime)
-                , m_totalTime(totalTime)
+                , m_elapsedTime(elapsedTime)
             {
             }
 
             double startTime() const { return m_startTime; }
-            void setStartTime(double time) { m_startTime = time; }
+            void setStartTime(double time)
+            {
+                ASSERT_ARG(time, time >= 0.0 || std::isnan(time));
+                m_startTime = time;
+            }
 
-            double totalTime() const { return m_totalTime; }
-            void setTotalTime(double time) { m_totalTime = time; }
+            double elapsedTime() const { return m_elapsedTime; }
+            void setElapsedTime(double time)
+            {
+                ASSERT_ARG(time, time >= 0.0 || std::isnan(time));
+                m_elapsedTime = time;
+            }
 
         private:
             double m_startTime;
-            double m_totalTime;
+            double m_elapsedTime;
         };
 
         bool operator==(ProfileNode* node) { return m_callIdentifier == node->callIdentifier(); }
 
-        ProfileNode* willExecute(ExecState* callerCallFrame, const CallIdentifier&);
-        ProfileNode* didExecute();
-
-        void stopProfiling();
-
-        // CallIdentifier members
         ExecState* callerCallFrame() const { return m_callerCallFrame; }
         const CallIdentifier& callIdentifier() const { return m_callIdentifier; }
         unsigned id() const { return m_callIdentifier.hash(); }
@@ -89,68 +91,103 @@ namespace JSC {
         unsigned lineNumber() const { return m_callIdentifier.lineNumber(); }
         unsigned columnNumber() const { return m_callIdentifier.columnNumber(); }
 
-        // Relationships
-        ProfileNode* head() const { return m_head; }
-        void setHead(ProfileNode* head) { m_head = head; }
-
         ProfileNode* parent() const { return m_parent; }
         void setParent(ProfileNode* parent) { m_parent = parent; }
 
-        ProfileNode* nextSibling() const { return m_nextSibling; }
-        void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
-
-        // Time members
-        double totalTime() const { return m_totalTime; }
-        void setTotalTime(double time) { m_totalTime = time; }
-
-        double selfTime() const { return m_selfTime; }
-        void setSelfTime(double time) { m_selfTime = time; }
-
-        double totalPercent() const { return (m_totalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-        double selfPercent() const { return (m_selfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-
-        Vector<Call> calls() const { return m_calls; }
+        const Vector<Call>& calls() const { return m_calls; }
         Call& lastCall() { ASSERT(!m_calls.isEmpty()); return m_calls.last(); }
-        size_t numberOfCalls() const { return m_calls.size(); }
+        void appendCall(Call call) { m_calls.append(call); }
 
-        // Children members
         const Vector<RefPtr<ProfileNode>>& children() const { return m_children; }
-        ProfileNode* firstChild() const { return m_children.size() ? m_children.first().get() : 0; }
-        ProfileNode* lastChild() const { return m_children.size() ? m_children.last().get() : 0; }
-        void removeChild(ProfileNode*);
-        void addChild(PassRefPtr<ProfileNode> prpChild);
-        void insertNode(PassRefPtr<ProfileNode> prpNode);
+        ProfileNode* firstChild() const { return m_children.size() ? m_children.first().get() : nullptr; }
+        ProfileNode* lastChild() const { return m_children.size() ? m_children.last().get() : nullptr; }
 
-        ProfileNode* traverseNextNodePostOrder() const;
+        void removeChild(ProfileNode*);
+        void addChild(PassRefPtr<ProfileNode>);
+        // Reparent our child nodes to the passed node, and make it a child node of |this|.
+        void spliceNode(PassRefPtr<ProfileNode>);
 
 #ifndef NDEBUG
-        const char* c_str() const { return m_callIdentifier; }
-        void debugPrintData(int indentLevel) const;
-        double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
+        struct ProfileSubtreeData {
+            HashMap<ProfileNode*, std::pair<double, double>> selfAndTotalTimes;
+            double rootTotalTime;
+        };
+
+        // Use these functions to dump the subtree rooted at this node.
+        void debugPrint();
+        void debugPrintSampleStyle();
+
+        // These are used to recursively print entire subtrees using precomputed self and total times.
+        template <typename Functor> void forEachNodePostorder(Functor&);
+
+        void debugPrintRecursively(int indentLevel, const ProfileSubtreeData&);
+        double debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount&, const ProfileSubtreeData&);
 #endif
 
     private:
         typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator;
 
-        ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
-        ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy);
+        ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* parentNode);
+        ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy);
+
+#ifndef NDEBUG
+        ProfileNode* nextSibling() const { return m_nextSibling; }
+        void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
 
-        void startTimer();
-        void resetChildrensSiblings();
-        void endAndRecordCall();
+        ProfileNode* traverseNextNodePostOrder() const;
+#endif
 
         ExecState* m_callerCallFrame;
         CallIdentifier m_callIdentifier;
-        ProfileNode* m_head;
         ProfileNode* m_parent;
+        Vector<Call> m_calls;
+        Vector<RefPtr<ProfileNode>> m_children;
+
+#ifndef NDEBUG
         ProfileNode* m_nextSibling;
+#endif
+    };
 
-        double m_totalTime;
-        double m_selfTime;
+#ifndef NDEBUG
+    template <typename Functor> inline void ProfileNode::forEachNodePostorder(Functor& functor)
+    {
+        ProfileNode* currentNode = this;
+        // Go down to the first node of the traversal, and slowly walk back up.
+        for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
+            currentNode = nextNode;
+
+        ProfileNode* endNode = this;
+        while (currentNode && currentNode != endNode) {
+            functor(currentNode);
+            currentNode = currentNode->traverseNextNodePostOrder();
+        }
 
-        Vector<Call, 1> m_calls;
-        Vector<RefPtr<ProfileNode>> m_children;
+        functor(endNode);
+    }
+
+    struct CalculateProfileSubtreeDataFunctor {
+        void operator()(ProfileNode* node)
+        {
+            double selfTime = 0.0;
+            for (const ProfileNode::Call& call : node->calls())
+                selfTime += call.elapsedTime();
+
+            double totalTime = selfTime;
+            for (RefPtr<ProfileNode> child : node->children()) {
+                auto it = m_data.selfAndTotalTimes.find(child.get());
+                if (it != m_data.selfAndTotalTimes.end())
+                    totalTime += it->value.second;
+            }
+
+            ASSERT(node);
+            m_data.selfAndTotalTimes.set(node, std::make_pair(selfTime, totalTime));
+        }
+
+        ProfileNode::ProfileSubtreeData returnValue() { return WTF::move(m_data); }
+
+        ProfileNode::ProfileSubtreeData m_data;
     };
+#endif
 
 } // namespace JSC
 
index 5bfedb4846d6e07e202952c91a5818a281d02de9..145ee44d1dcd60c6a88053b90d526d01e9721e2d 100644 (file)
@@ -44,7 +44,7 @@ BytecodeSequence::BytecodeSequence(CodeBlock* codeBlock)
         if (!description.length())
             continue;
         out.reset();
-        out.print("arg", i, " (r", virtualRegisterForArgument(i).offset(), "): ", description);
+        out.print("arg", i, ": ", description);
         m_header.append(out.toCString());
     }
     
index d43e196869798e3ef13f526f3f720d03a2c21e59..488f563de4525504459452147b3143da360b7644 100644 (file)
@@ -30,6 +30,7 @@
 #include "ObjectConstructor.h"
 #include "JSCInlines.h"
 #include "ProfilerDatabase.h"
+#include "Watchpoint.h"
 #include <wtf/StringPrintStream.h>
 
 namespace JSC { namespace Profiler {
@@ -93,6 +94,18 @@ OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, Ex
     return &m_osrExits.last();
 }
 
+void Compilation::setJettisonReason(JettisonReason jettisonReason, const FireDetail* detail)
+{
+    if (m_jettisonReason != NotJettisoned)
+        return; // We only care about the original jettison reason.
+    
+    m_jettisonReason = jettisonReason;
+    if (detail)
+        m_additionalJettisonReason = toCString(*detail);
+    else
+        m_additionalJettisonReason = CString();
+}
+
 JSValue Compilation::toJS(ExecState* exec) const
 {
     JSObject* result = constructEmptyObject(exec);
@@ -133,6 +146,8 @@ JSValue Compilation::toJS(ExecState* exec) const
     result->putDirect(exec->vm(), exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
     result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
     result->putDirect(exec->vm(), exec->propertyNames().jettisonReason, jsString(exec, String::fromUTF8(toCString(m_jettisonReason))));
+    if (!m_additionalJettisonReason.isNull())
+        result->putDirect(exec->vm(), exec->propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason)));
     
     return result;
 }
index f643fff70bc3e2e3b9302d3284272bc24c0fa638..b358b659c080b476d741bd6d3891c4cd708a380a 100644 (file)
 #include <wtf/RefCounted.h>
 #include <wtf/SegmentedVector.h>
 
-namespace JSC { namespace Profiler {
+namespace JSC {
+
+class FireDetail;
+
+namespace Profiler {
 
 class Bytecodes;
 class Database;
@@ -69,10 +73,7 @@ public:
     void addOSRExitSite(const Vector<const void*>& codeAddresses);
     OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
     
-    void setJettisonReason(JettisonReason jettisonReason)
-    {
-        m_jettisonReason = jettisonReason;
-    }
+    void setJettisonReason(JettisonReason, const FireDetail*);
     
     JSValue toJS(ExecState*) const;
     
@@ -80,6 +81,7 @@ private:
     Bytecodes* m_bytecodes;
     CompilationKind m_kind;
     JettisonReason m_jettisonReason;
+    CString m_additionalJettisonReason;
     Vector<ProfiledBytecodes> m_profiledBytecodes;
     Vector<CompiledBytecode> m_descriptions;
     HashMap<OriginStack, std::unique_ptr<ExecutionCounter>> m_counters;
index 3d5a2ee895acc401946c0d143a7943cba52043d6..236a5c8c8189d9ceb9292b5e87dc5737f51324f7 100644 (file)
@@ -35,7 +35,7 @@ namespace JSC { namespace Profiler {
 
 static std::atomic<int> databaseCounter;
 
-static SpinLock registrationLock = SPINLOCK_INITIALIZER;
+static StaticSpinLock registrationLock;
 static std::atomic<int> didRegisterAtExit;
 static Database* firstDatabase;
 
@@ -138,14 +138,14 @@ void Database::addDatabaseToAtExit()
     if (++didRegisterAtExit == 1)
         atexit(atExitCallback);
     
-    TCMalloc_SpinLockHolder holder(&registrationLock);
+    SpinLockHolder holder(registrationLock);
     m_nextRegisteredDatabase = firstDatabase;
     firstDatabase = this;
 }
 
 void Database::removeDatabaseFromAtExit()
 {
-    TCMalloc_SpinLockHolder holder(&registrationLock);
+    SpinLockHolder holder(registrationLock);
     for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) {
         if (*current != this)
             continue;
@@ -163,7 +163,7 @@ void Database::performAtExitSave() const
 
 Database* Database::removeFirstAtExitDatabase()
 {
-    TCMalloc_SpinLockHolder holder(&registrationLock);
+    SpinLockHolder holder(registrationLock);
     Database* result = firstDatabase;
     if (result) {
         firstDatabase = result->m_nextRegisteredDatabase;
index f2a9a40e8a9163c71fcdaea3493e6bd90a71a5d9..a38aee237d9730da20c31f6be39ec00f4d76e462 100644 (file)
@@ -40,9 +40,9 @@ class EmptyInputCursor final : public InputCursor {
 public:
     virtual ~EmptyInputCursor() { }
 
-    static PassRefPtr<EmptyInputCursor> create()
+    static Ref<EmptyInputCursor> create()
     {
-        return adoptRef(new EmptyInputCursor());
+        return adoptRef(*new EmptyInputCursor());
     }
 
     virtual bool isCapturing() const override { return false; }
@@ -60,7 +60,7 @@ public:
     }
 
 protected:
-    virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString&) override
+    virtual NondeterministicInputBase* loadInput(InputQueue, const String&) override
     {
         ASSERT_NOT_REACHED();
         return nullptr;
index 0191d4148efbf4dff9663ccd99e6ac61525c3cc2..727eba10df6d02b65140be001ba9ceaa428c0371 100644 (file)
@@ -37,22 +37,32 @@ using namespace Inspector;
 
 namespace JSC {
 
-PassRefPtr<InspectorObject> EncodedValue::asObject()
+RefPtr<InspectorObject> EncodedValue::asObject()
 {
     RefPtr<InspectorObject> result;
-    bool castSucceeded = m_value->asObject(&result);
+    bool castSucceeded = m_value->asObject(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
-    return result.release();
+    return result;
 }
 
-PassRefPtr<InspectorArray> EncodedValue::asArray()
+RefPtr<InspectorArray> EncodedValue::asArray()
 {
     RefPtr<InspectorArray> result;
-    bool castSucceeded = m_value->asArray(&result);
+    bool castSucceeded = m_value->asArray(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
-    return result.release();
+    return result;
+}
+
+EncodedValue EncodingTraits<Vector<char>>::encodeValue(const Vector<char>& buffer)
+{
+    return EncodedValue::createString(base64Encode(buffer));
+}
+
+bool EncodingTraits<Vector<char>>::decodeValue(EncodedValue& encodedBuffer, Vector<char>& decodedValue)
+{
+    return base64Decode(encodedBuffer.convertTo<String>(), decodedValue);
 }
 
 template<> EncodedValue ScalarEncodingTraits<bool>::encodeValue(const bool& value)
@@ -90,15 +100,10 @@ template<> EncodedValue ScalarEncodingTraits<uint64_t>::encodeValue(const uint64
     return EncodedValue(InspectorBasicValue::create((double)value));
 }
 
-template<> EncodedValue ScalarEncodingTraits<unsigned long>::encodeValue(const unsigned long& value)
-{
-    return EncodedValue(InspectorBasicValue::create((double)value));
-}
-
 template<> bool EncodedValue::convertTo<bool>()
 {
     bool result;
-    bool castSucceeded = m_value->asBoolean(&result);
+    bool castSucceeded = m_value->asBoolean(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -107,7 +112,7 @@ template<> bool EncodedValue::convertTo<bool>()
 template<> double EncodedValue::convertTo<double>()
 {
     double result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asDouble(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -116,7 +121,7 @@ template<> double EncodedValue::convertTo<double>()
 template<> float EncodedValue::convertTo<float>()
 {
     float result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asDouble(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -125,7 +130,7 @@ template<> float EncodedValue::convertTo<float>()
 template<> int32_t EncodedValue::convertTo<int32_t>()
 {
     int32_t result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asInteger(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -134,7 +139,7 @@ template<> int32_t EncodedValue::convertTo<int32_t>()
 template<> int64_t EncodedValue::convertTo<int64_t>()
 {
     int64_t result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asInteger(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -143,7 +148,7 @@ template<> int64_t EncodedValue::convertTo<int64_t>()
 template<> uint32_t EncodedValue::convertTo<uint32_t>()
 {
     uint32_t result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asInteger(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -152,16 +157,7 @@ template<> uint32_t EncodedValue::convertTo<uint32_t>()
 template<> uint64_t EncodedValue::convertTo<uint64_t>()
 {
     uint64_t result;
-    bool castSucceeded = m_value->asNumber(&result);
-    ASSERT_UNUSED(castSucceeded, castSucceeded);
-
-    return result;
-}
-
-template<> unsigned long EncodedValue::convertTo<unsigned long>()
-{
-    unsigned long result;
-    bool castSucceeded = m_value->asNumber(&result);
+    bool castSucceeded = m_value->asInteger(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -170,7 +166,7 @@ template<> unsigned long EncodedValue::convertTo<unsigned long>()
 template<> String EncodedValue::convertTo<String>()
 {
     String result;
-    bool castSucceeded = m_value->asString(&result);
+    bool castSucceeded = m_value->asString(result);
     ASSERT_UNUSED(castSucceeded, castSucceeded);
 
     return result;
@@ -179,23 +175,23 @@ template<> String EncodedValue::convertTo<String>()
 template<>
 void EncodedValue::put<EncodedValue>(const String& key, const typename EncodingTraits<EncodedValue>::DecodedType& value)
 {
-    asObject()->setValue(key, value.m_value);
+    asObject()->setValue(key, value.m_value.copyRef());
 }
 
 template<>
 void EncodedValue::append<EncodedValue>(const typename EncodingTraits<EncodedValue>::DecodedType& value)
 {
-    asArray()->pushValue(value.m_value);
+    asArray()->pushValue(value.m_value.copyRef());
 }
 
 template<>
 bool EncodedValue::get<EncodedValue>(const String& key, typename EncodingTraits<EncodedValue>::DecodedType& decodedValue)
 {
-    RefPtr<Inspector::InspectorValue> inspectorValue(asObject()->get(key));
-    if (!inspectorValue)
+    RefPtr<Inspector::InspectorValue> value;
+    if (!asObject()->getValue(key, value))
         return false;
 
-    decodedValue = EncodedValue(inspectorValue);
+    decodedValue = EncodedValue(WTF::move(value));
     return true;
 }
 
index de6bff7db54adf2312be91170e0127cd1aa0d0d3..8659b4f50b15bf35544144bfaf25d084b0440ca6 100644 (file)
@@ -41,7 +41,7 @@ template<typename T> struct EncodingTraits;
 
 class EncodedValue final {
 public:
-    explicit EncodedValue(PassRefPtr<Inspector::InspectorValue> value)
+    explicit EncodedValue(RefPtr<Inspector::InspectorValue>&& value)
         : m_value(value) { }
 
     EncodedValue()
@@ -78,8 +78,8 @@ public:
 
     template<typename T> T convertTo();
 
-    JS_EXPORT_PRIVATE PassRefPtr<Inspector::InspectorObject> asObject();
-    JS_EXPORT_PRIVATE PassRefPtr<Inspector::InspectorArray> asArray();
+    JS_EXPORT_PRIVATE RefPtr<Inspector::InspectorObject> asObject();
+    JS_EXPORT_PRIVATE RefPtr<Inspector::InspectorArray> asArray();
 
 private:
     RefPtr<Inspector::InspectorValue> m_value;
@@ -92,7 +92,6 @@ template<> JS_EXPORT_PRIVATE int32_t EncodedValue::convertTo<int32_t>();
 template<> JS_EXPORT_PRIVATE int64_t EncodedValue::convertTo<int64_t>();
 template<> JS_EXPORT_PRIVATE uint32_t EncodedValue::convertTo<uint32_t>();
 template<> JS_EXPORT_PRIVATE uint64_t EncodedValue::convertTo<uint64_t>();
-template<> JS_EXPORT_PRIVATE unsigned long EncodedValue::convertTo<unsigned long>();
 template<> JS_EXPORT_PRIVATE String EncodedValue::convertTo<String>();
 
 template<typename T>
@@ -113,7 +112,7 @@ struct EncodingTraits<Vector<T, inlineCapacity, OverflowHandler>> {
     {
         EncodedValue encodedVector = EncodedValue::createArray();
         for (const typename EncodingTraits<T>::DecodedType& value : vectorOfValues)
-            encodedVector.append<typename EncodingTraits<T>::DecodedType>(value);
+            encodedVector.append<T>(value);
 
         return WTF::move(encodedVector);
     }
@@ -137,6 +136,13 @@ template<> struct EncodingTraits<EncodedValue> {
     // so encodeValue and decodeValue are intentionally omitted here.
 };
 
+// Specialize byte vectors to use base64 encoding.
+template<> struct EncodingTraits<Vector<char>> {
+    typedef Vector<char> DecodedType;
+    static EncodedValue encodeValue(const DecodedType&);
+    static bool decodeValue(EncodedValue&, DecodedType&);
+};
+
 template<typename T>
 struct ScalarEncodingTraits {
     typedef T DecodedType;
@@ -156,7 +162,6 @@ template<> struct EncodingTraits<int32_t> : public ScalarEncodingTraits<int32_t>
 template<> struct EncodingTraits<int64_t> : public ScalarEncodingTraits<int64_t> { };
 template<> struct EncodingTraits<uint32_t> : public ScalarEncodingTraits<uint32_t> { };
 template<> struct EncodingTraits<uint64_t> : public ScalarEncodingTraits<uint64_t> { };
-template<> struct EncodingTraits<unsigned long> : public ScalarEncodingTraits<unsigned long> { };
 
 template<> struct EncodingTraits<String> : public ScalarEncodingTraits<String> {
     static EncodedValue encodeValue(const String& value)
index 6102a7fe8a3ac88f73df5854264f6d27055e0d47..6cdb292a520f7caaaa5ec970c44fe951f4eaf348 100644 (file)
@@ -33,7 +33,6 @@
 #include "NondeterministicInput.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/RefCounted.h>
-#include <wtf/text/AtomicString.h>
 
 namespace JSC {
 
@@ -41,12 +40,23 @@ class InputCursor : public RefCounted<InputCursor> {
     WTF_MAKE_NONCOPYABLE(InputCursor);
 public:
     InputCursor() { }
-
     virtual ~InputCursor() { }
 
     virtual bool isCapturing() const = 0;
     virtual bool isReplaying() const = 0;
 
+    void setWithinEventLoopInputExtent(bool withinEventLoopInputExtent)
+    {
+        // We can be within two input extents when a nested run loop
+        // processes additional user inputs while the debugger is paused.
+        // However, the debugger should not pause when capturing, and we
+        // should not replay event loop inputs while in a nested run loop.
+        ASSERT(m_withinEventLoopInputExtent != withinEventLoopInputExtent || !(isCapturing() || isReplaying()));
+        m_withinEventLoopInputExtent = withinEventLoopInputExtent;
+    }
+
+    bool withinEventLoopInputExtent() const { return m_withinEventLoopInputExtent; }
+
     template <class InputType, class... Args> inline
     void appendInput(Args&&... args)
     {
@@ -63,7 +73,10 @@ public:
     virtual void storeInput(std::unique_ptr<NondeterministicInputBase>) = 0;
     virtual NondeterministicInputBase* uncheckedLoadInput(InputQueue) = 0;
 protected:
-    virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString&) = 0;
+    virtual NondeterministicInputBase* loadInput(InputQueue, const String&) = 0;
+
+private:
+    bool m_withinEventLoopInputExtent {false};
 };
 
 } // namespace JSC
index 7394d9470a84b29fdd3d4b41cf3b918df35f4380..fa5c0041307575ff6e1ddacae537dbd709c024fe 100644 (file)
@@ -1,27 +1,49 @@
 {
     "types": {
         "Global": [
+            { "name": "bool", "mode": "SCALAR" },
             { "name": "double", "mode": "SCALAR" },
-            { "name": "uint64_t", "mode": "SCALAR" }
+            { "name": "uint32_t", "mode": "SCALAR", "description": "Unsigned 32-bit integer." },
+            { "name": "uint64_t", "mode": "SCALAR", "description": "Unsigned 64-bit integer." },
+            { "name": "int32_t", "mode": "SCALAR", "description": "Signed 32-bit integer." },
+            { "name": "int64_t", "mode": "SCALAR", "description": "Signed 64-bit integer." }
+        ],
+
+        "WTF": [
+            {
+                "name": "String", "mode": "HEAVY_SCALAR",
+                "header": "wtf/text/WTFString.h"
+            }
+        ],
+
+        "JavaScriptCore": [
+            {
+                "name": "InputQueue", "mode": "SCALAR", "storage": "uint8_t",
+                "flags": ["ENUM_CLASS"],
+                "values": ["EventLoopInput", "LoaderMemoizedData", "ScriptMemoizedData", "Count"],
+                "header": "replay/NondeterministicInput.h"
+            }
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "currentTime", "type": "double" }
-            ]
-        },
-        {
-            "name": "SetRandomSeed",
-            "description": "Sets the PRNG seed used by Math.random().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "randomSeed", "type": "uint64_t" }
-            ]
-        }
-    ]
+    "inputs": {
+        "JavaScriptCore": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "currentTime", "type": "double" }
+                ]
+            },
+            {
+                "name": "SetRandomSeed",
+                "description": "Sets the PRNG seed used by Math.random().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "randomSeed", "type": "uint64_t" }
+                ]
+            }
+        ]
+    }
 }
index a256c2b627d95b4804402ffa28625bb377ccc3ce..30ba33bcf7d91a6cdbd4217abf38706703e16fea 100644 (file)
@@ -47,7 +47,7 @@ enum class InputQueue {
 template<typename InputType>
 struct JS_EXPORT_PRIVATE InputTraits {
     static InputQueue queue();
-    static AtomicString& type();
+    static String& type();
 
     static void encode(EncodedValue& encodedInput, InputType& decodedInput);
     static bool decode(EncodedValue& encodedInput, std::unique_ptr<InputType>& decodedInput);
@@ -59,13 +59,14 @@ public:
     NondeterministicInputBase() { }
     virtual ~NondeterministicInputBase() { }
 
-    virtual const AtomicString& type() const = 0;
+    virtual const String& type() const = 0;
     virtual InputQueue queue() const = 0;
 };
 
 template<typename InputType>
 class NondeterministicInput : public NondeterministicInputBase {
-    virtual const AtomicString& type() const override
+public:
+    virtual const String& type() const override
     {
         return InputTraits<InputType>::type();
     }
index d12e9eba9c9f26d32f864cbf9f69d45493b4240a..d838ae5e6afa35ebf489ee448f4f7ae46bb7841c 100644 (file)
@@ -57,6 +57,9 @@ GLOBAL_CONFIG = {
         (["JavaScriptCore"],
             ("JavaScriptCore", "replay/NondeterministicInput.h")
         ),
+        (["JavaScriptCore", "WebCore"],
+            ("WTF", "wtf/TypeCasts.h")
+        ),
         (["WebCore"],
             ("WTF", "wtf/text/WTFString.h")
         ),
@@ -71,21 +74,15 @@ GLOBAL_CONFIG = {
     ],
 
     "implIncludes": [
-        (["WebCore"],
-            ("WebCore", "replay/ReplayInputTypes.h")
-        ),
         (["WebCore"],
             ("WebCore", "replay/SerializationMethods.h")
         ),
         (["WebCore", "JavaScriptCore"],
             ("JavaScriptCore", "inspector/InspectorValues.h")
         ),
-        (["JavaScriptCore"],
+        (["WebCore", "JavaScriptCore"],
             ("WTF", "wtf/NeverDestroyed.h")
         ),
-        (["JavaScriptCore"],
-            ("WTF", "wtf/text/AtomicString.h")
-        ),
 
         # Testing fixtures.
         (["Test"],
@@ -111,18 +108,17 @@ FRAMEWORK_CONFIG_MAP = {
         "prefix": "JS",
         "namespace": "JSC",
         "exportMacro": "JS_EXPORT_PRIVATE",
-        "inputTypeTemplate": Templates.InputTypeFromStaticLocal,
     },
     "WebCore": {
         "prefix": "Web",
         "namespace": "WebCore",
-        "inputTypeTemplate": Templates.InputTypeFromThreadLocal,
+        "exportMacro": "WEBCORE_EXPORT"
     },
     # Used for bindings tests.
     "Test": {
         "prefix": "Test",
         "namespace": "Test",
-        "inputTypeTemplate": Templates.InputTypeFromStaticLocal,
+        "exportMacro": "TEST_EXPORT_MACRO"
     }
 }
 
@@ -221,9 +217,10 @@ class InputQueues:
 
 
 class Input:
-    def __init__(self, name, description, queueString, flags, guard=None):
+    def __init__(self, name, description, framework, queueString, flags, guard=None):
         self.name = name
         self.description = description
+        self.framework = framework
         self.queue = InputQueue.fromString(queueString)
         self._flags = flags
         self.guard = guard
@@ -350,16 +347,19 @@ class Type:
         if self.mode == TypeModes.SCALAR:
             return self.type_name(qualified)
         elif self.mode == TypeModes.SHARED:
-            return "PassRefPtr<%s>" % self.type_name(qualified)
+            return "RefPtr<%s>" % self.type_name(qualified)
         else:
             return "const %s&" % self.type_name(qualified)
 
     def argument_type(self, qualified=False):
         if self.mode == TypeModes.SHARED:
-            return "PassRefPtr<%s>" % self.type_name(qualified)
+            return "RefPtr<%s>&&" % self.type_name(qualified)
         else:
             return self.storage_type()
 
+    def encoding_type_argument(self, qualified=False):
+        return self.type_name(qualified=qualified)
+
 
 def check_for_required_properties(props, obj, what):
     for prop in props:
@@ -390,6 +390,9 @@ class VectorType(Type):
         return ""
 
     def type_name(self, qualified=False):
+        return "Vector<%s>" % self._element_type.storage_type(qualified=qualified)
+
+    def encoding_type_argument(self, qualified=False):
         return "Vector<%s>" % self._element_type.type_name(qualified=qualified)
 
     def argument_type(self, qualified=False):
@@ -397,7 +400,7 @@ class VectorType(Type):
 
 
 class InputsModel:
-    def __init__(self, parsed_json):
+    def __init__(self):
         self.inputs = []
         self.types = []
 
@@ -406,8 +409,6 @@ class InputsModel:
         self.types_by_name = {}
         self.inputs_by_name = {}
 
-        self.parse_toplevel(parsed_json)
-
     def enum_types(self):
         _enums = filter(lambda x: x.is_enum() or x.is_enum_class(), self.types)
         return sorted(_enums, key=lambda _enum: _enum.type_name())
@@ -418,27 +419,33 @@ class InputsModel:
         else:
             return self.types_by_name.get(member.typeName)
 
-    def parse_toplevel(self, json):
-        check_for_required_properties(['types', 'inputs'], json, 'toplevel')
-        if not isinstance(json['types'], dict):
-            raise ParseException("Malformed specification: types is not a dict of framework->type list")
+    def parse_specification(self, json):
+        if 'types' in json:
+            if not isinstance(json['types'], dict):
+                raise ParseException("Malformed specification: types is not a dict of framework->type list")
 
-        if not isinstance(json['inputs'], list):
-            raise ParseException("Malformed specification: inputs is not an array")
+            for framework_name, type_list in json['types'].iteritems():
+                if not isinstance(type_list, list):
+                    raise ParseException("Malformed specification: type list for framework %s is not a list" % framework_name)
 
-        for type_framework_name, type_list in json['types'].iteritems():
-            if not isinstance(type_list, list):
-                raise ParseException("Malformed specification: type list for framework %s is not a list" % type_framework_name)
+                framework = Framework.fromString(framework_name)
+                for _type in type_list:
+                    self.parse_type_with_framework(_type, framework)
 
-            for _type in type_list:
-                self.parse_type_with_framework_name(_type, type_framework_name)
+        if 'inputs' in json:
+            if not isinstance(json['inputs'], dict):
+                raise ParseException("Malformed specification: inputs is not a dict of framework->input list")
 
-        for val in json['inputs']:
-            self.parse_input(val)
+            for framework_name, input_list in json['inputs'].iteritems():
+                if not isinstance(input_list, list):
+                    raise ParseException("Malformed specification: input list for framework %s is not a list" % framework_name)
 
-    def parse_type_with_framework_name(self, json, framework_name):
+                framework = Framework.fromString(framework_name)
+                for _input in input_list:
+                    self.parse_input_with_framework(_input, framework)
+
+    def parse_type_with_framework(self, json, framework):
         check_for_required_properties(['name', 'mode'], json, 'type')
-        framework = Framework.fromString(framework_name)
         if framework is not Frameworks.Global:
             check_for_required_properties(['header'], json, 'non-global type')
 
@@ -457,14 +464,14 @@ class InputsModel:
             if not isinstance(json['values'], list) or len(_type.values) == 0:
                 raise ParseException("Malformed specification: enum %s does not supply a list of values" % type_name)
 
-            if _type.is_enum() and "storage" not in json:
-                raise ParseException("Could not parse enum %s: C-style enums must also specify their storage type so they can be forward declared." % type_name)
+            if _type.is_enum() and enclosing_class is None and type_storage is None:
+                raise ParseException("Could not parse enum %s: C-style enums not enclosed by a class must specify their storage type so they can be forward declared." % type_name)
 
         self.types.append(_type)
 
-    def parse_input(self, json):
+    def parse_input_with_framework(self, json, framework):
         check_for_required_properties(['name', 'description', 'queue', 'members'], json, 'input')
-        _input = Input(json['name'], json['description'], json['queue'], json.get('flags', []), json.get('guard'))
+        _input = Input(json['name'], json['description'], framework, json['queue'], json.get('flags', []), json.get('guard'))
         if isinstance(json['members'], list):
             for member in json['members']:
                 check_for_required_properties(['name', 'type'], member, 'member')
@@ -563,6 +570,9 @@ class Generator:
     def setting(self, key, default=''):
         return self.target_framework.setting(key, GLOBAL_CONFIG.get(key, default))
 
+    def should_generate_item(self, item):
+        return item.framework is self.target_framework
+
     # This does not account for any filename mangling performed on behalf of the test harness.
     def output_filename(self, extension=None):
         components = []
@@ -587,6 +597,9 @@ class Generator:
         implementation_file.close()
 
     def generate_header(self):
+        enums_to_generate = filter(self.should_generate_item, self._model.enum_types())
+        inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
+
         template_arguments = {
             'licenseBlock': self.generate_license(),
             'headerGuard': re.sub('[-./]', '_', self.output_filename() + ".h"),
@@ -596,16 +609,20 @@ class Generator:
             'inputsNamespace': self.target_framework.setting('namespace'),
             'includes': self.generate_includes(defaults=self.setting('headerIncludes')),
             'typeForwardDeclarations': self.generate_type_forward_declarations(),
-            'inputForwardDeclarations': "\n".join([wrap_with_guard("class %s;", _input.guard) % _input.name for _input in self._model.inputs]),
-            'inputClassDeclarations': "\n\n".join([self.generate_class_declaration(_input) for _input in self._model.inputs]),
-            'inputTraitDeclarations': "\n\n".join([self.generate_input_trait_declaration(_input) for _input in self._model.inputs]),
-            'enumTraitDeclarations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_declaration(_type), _type.guard) for _type in self._model.enum_types()]),
+            'inputForwardDeclarations': "\n".join([wrap_with_guard("class %s;", _input.guard) % _input.name for _input in inputs_to_generate]),
+            'inputClassDeclarations': "\n\n".join([self.generate_class_declaration(_input) for _input in inputs_to_generate]),
+            'inputTraitDeclarations': "\n\n".join([self.generate_input_trait_declaration(_input) for _input in inputs_to_generate]),
+            'inputTypeTraitDeclarations': "\n\n".join([self.generate_input_type_trait_declaration(_input) for _input in inputs_to_generate]),
+            'enumTraitDeclarations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_declaration(_type), _type.guard) for _type in enums_to_generate]),
             'forEachMacro': self.generate_for_each_macro(),
         }
 
         return Template(Templates.HeaderSkeleton).substitute(template_arguments)
 
     def generate_implementation(self):
+        enums_to_generate = filter(self.should_generate_item, self._model.enum_types())
+        inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
+
         template_arguments = {
             'licenseBlock': self.generate_license(),
             'filename': self.output_filename(),
@@ -613,9 +630,9 @@ class Generator:
             'traitsNamespace': self.traits_framework.setting('namespace'),
             'inputsNamespace': self.target_framework.setting('namespace'),
             'includes': self.generate_includes(defaults=self.setting('implIncludes'), includes_for_types=True),
-            'inputClassImplementations': "\n\n".join([self.generate_class_implementation(_input) for _input in self._model.inputs]),
-            'inputTraitImplementations': "\n\n".join([self.generate_input_trait_implementation(_input) for _input in self._model.inputs]),
-            'enumTraitImplementations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_implementation(_type), _type.guard) for _type in self._model.enum_types()]),
+            'inputClassImplementations': "\n\n".join([self.generate_class_implementation(_input) for _input in inputs_to_generate]),
+            'inputTraitImplementations': "\n\n".join([self.generate_input_trait_implementation(_input) for _input in inputs_to_generate]),
+            'enumTraitImplementations': "\n\n".join([wrap_with_guard(self.generate_enum_trait_implementation(_type), _type.guard) for _type in enums_to_generate]),
         }
 
         return Template(Templates.ImplementationSkeleton).substitute(template_arguments)
@@ -635,7 +652,7 @@ class Generator:
             include_for_destructor = _type.mode is TypeModes.SHARED
             # Enums within classes cannot be forward declared, so we include
             # headers with the relevant class declaration.
-            include_for_enclosing_class = _type.is_enum() and _type.enclosing_class is not None
+            include_for_enclosing_class = _type.enclosing_class is not None
             # Include headers for types like URL and String which are copied, not owned or shared.
             include_for_copyable_member = _type.mode is TypeModes.HEAVY_SCALAR
             if (not includes_for_types) ^ (include_for_destructor or include_for_enclosing_class or include_for_copyable_member):
@@ -750,11 +767,11 @@ class Generator:
     def generate_input_member_tuples(self, _input):
         return [(_member, self._model.get_type_for_member(_member)) for _member in _input.members]
 
-    def qualified_input_name(self, _input):
-        if self.target_framework == self.traits_framework:
-            return _input.name
-        else:
+    def qualified_input_name(self, _input, forceQualified=False):
+        if forceQualified or self.target_framework != self.traits_framework:
             return "%s::%s" % (self.target_framework.setting('namespace'), _input.name)
+        else:
+            return _input.name
 
     def generate_input_trait_declaration(self, _input):
         decl_type = ['struct']
@@ -769,19 +786,34 @@ class Generator:
 
         return wrap_with_guard(Template(Templates.InputTraitsDeclaration).substitute(template_arguments), _input.guard)
 
+    def generate_input_type_trait_declaration(self, _input):
+        template_arguments = {
+            'qualifiedInputName': self.qualified_input_name(_input, forceQualified=True),
+        }
+
+        return wrap_with_guard(Template(Templates.InputTypeTraitsDeclaration).substitute(template_arguments), _input.guard)
+
     def generate_enum_trait_declaration(self, _type):
+        decl_type = ['struct']
+        if len(self.setting('exportMacro')) > 0:
+            decl_type.append(self.setting('exportMacro'))
+
         should_qualify_type = _type.framework != self.traits_framework
         template = Templates.EnumTraitDeclaration if _type.is_enum() else Templates.EnumClassTraitDeclaration
         template_arguments = {
-            'enumName': _type.type_name(qualified=should_qualify_type),
+            'encodingTypeArgument': _type.encoding_type_argument(qualified=should_qualify_type),
+            'enumType': _type.type_name(qualified=should_qualify_type),
+            'structOrClass': " ".join(decl_type)
         }
         return Template(template).substitute(template_arguments)
 
     def generate_for_each_macro(self):
+        inputs_to_generate = filter(self.should_generate_item, self._model.inputs)
+
         macro_name = "%s_REPLAY_INPUT_NAMES_FOR_EACH" % self.setting('prefix').upper()
         lines = []
         lines.append("#define %s(macro) \\" % macro_name)
-        lines.extend(["    macro(%s) \\" % _input.name for _input in self._model.inputs])
+        lines.extend(["    macro(%s) \\" % _input.name for _input in inputs_to_generate])
         lines.append("    \\")
         lines.append("// end of %s" % macro_name)
         return "\n".join(lines)
@@ -801,10 +833,10 @@ class Generator:
         prefix_components = []
         if should_qualify_type:
             prefix_components.append(_type.framework.setting('namespace'))
-        if _type.is_enum_class():
-            prefix_components.append(_type.type_name())
-        if _type.enclosing_class is not None:
+        if _type.is_enum() and _type.enclosing_class is not None:
             prefix_components.append(_type.enclosing_class)
+        elif _type.is_enum_class():
+            prefix_components.append(_type.type_name(qualified=False))
         prefix_components.append("")
         enum_prefix = "::".join(prefix_components)
         encodeLines = []
@@ -838,8 +870,10 @@ class Generator:
 
         # Generate body for decode.
         decodeLines = []
-        for _value in _type.values:
+        for i, _value in enumerate(_type.values):
+
             template_arguments = {
+                'branchKeyword': "else if" if i > 0 else "if",
                 'enumStringValue': _value,
                 'qualifiedEnumValue': "%s%s" % (enum_prefix, _value),
                 'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
@@ -848,8 +882,9 @@ class Generator:
 
         for guard, guard_values in _type.guard_values_map.iteritems():
             guardedLines = []
-            for guard_value in guard_values:
+            for i, guard_value in enumerate(guard_values):
                 template_arguments = {
+                    'branchKeyword': "else if" if i > 0 else "if",
                     'enumStringValue': guard_value,
                     'qualifiedEnumValue': "%s%s" % (enum_prefix, guard_value),
                     'qualifiedEnumName': _type.type_name(qualified=should_qualify_type)
@@ -858,7 +893,8 @@ class Generator:
             decodeLines.append(wrap_with_guard("\n".join(guardedLines), guard))
 
         template_arguments = {
-            'enumName': _type.type_name(qualified=should_qualify_type),
+            'encodingTypeArgument': _type.encoding_type_argument(qualified=should_qualify_type),
+            'enumType': _type.type_name(qualified=should_qualify_type),
             'encodeCases': "\n".join(encodeLines),
             'decodeCases': "\n".join(decodeLines)
         }
@@ -868,7 +904,7 @@ class Generator:
     def generate_input_trait_implementation(self, _input):
         template_arguments = {
             'inputsNamespace': self.target_framework.setting('namespace'),
-            'inputTypeImplementation': Template(self.setting('inputTypeTemplate')).substitute(None, inputName=_input.name),
+            'inputNameStringLiteral': '"%s"' % _input.name,
             'qualifiedInputName': self.qualified_input_name(_input),
             'constructorArguments': self.generate_constructor_arguments_list(_input),
             'constructorFormalsList': self.generate_constructor_formals_list(_input),
@@ -881,7 +917,7 @@ class Generator:
         steps = []
         for (_member, _type) in self.generate_input_member_tuples(_input):
             should_qualify_type = _type.framework != self.traits_framework
-            put_method = "put<%s>" % _type.type_name(qualified=should_qualify_type)
+            put_method = "put<%s>" % _type.encoding_type_argument(qualified=should_qualify_type)
 
             steps.extend([
                 "    encodedValue.%s(ASCIILiteral(\"%s\"), input.%s());" % (put_method, _member.memberName, _member.memberName)
@@ -899,7 +935,7 @@ class Generator:
         steps = []
         for (_member, _type) in self.generate_input_member_tuples(_input):
             should_qualify_type = _type.framework != self.traits_framework
-            get_method = "get<%s>" % _type.type_name(qualified=should_qualify_type)
+            get_method = "get<%s>" % _type.encoding_type_argument(qualified=should_qualify_type)
 
             lines = [
                 "    %s %s;" % (_type.storage_type(qualified=should_qualify_type), _member.memberName),
@@ -939,7 +975,7 @@ class Generator:
 
     def generate_member_move_expression(self, _member):
         _type = self._model.get_type_for_member(_member)
-        if _type.mode == TypeModes.OWNED:
+        if _type.mode in [TypeModes.OWNED, TypeModes.SHARED]:
             return "WTF::move(%s)" % _member.memberName
         else:
             return _member.memberName
@@ -948,19 +984,29 @@ class Generator:
         return ", ".join([self.generate_member_move_expression(_member) for _member in _input.members])
 
 
-def generate_from_specification(input_filepath=None, output_prefix="", output_dirpath=None, framework_name=None, force_output=False):
-    try:
-        with open(input_filepath, "r") as input_file:
-            parsed_json = json.load(input_file)
-    except ValueError as e:
-        raise Exception("Error parsing valid JSON in file: " + input_filepath)
+def generate_from_specifications(input_filepaths=[], output_prefix="", output_dirpath=None, framework_name=None, force_output=False):
 
     if not framework_name in FRAMEWORK_CONFIG_MAP:
         raise ParseException("Unknown or unsupported framework name supplied: " + framework_name)
 
-    model = InputsModel(parsed_json)
+    if len(input_filepaths) == 0:
+        raise ParseException("Must provide at least one specification file, none were provided.")
+
+    def parse_json_from_file(input_filepath):
+        try:
+            with open(input_filepath, "r") as input_file:
+                return json.load(input_file)
+        except ValueError as e:
+            raise Exception("Error parsing valid JSON in file: " + input_filepath)
+
+    specifications = map(parse_json_from_file, input_filepaths)
+
+    model = InputsModel()
+    for spec in specifications:
+        model.parse_specification(spec)
+
     model.resolve_types()
-    generator = Generator(model, framework_name, input_filepath, output_prefix)
+    generator = Generator(model, framework_name, input_filepaths[0], output_prefix)
 
     generator.write_output_files(output_dirpath, force_output)
 
@@ -968,7 +1014,7 @@ def generate_from_specification(input_filepath=None, output_prefix="", output_di
 if __name__ == '__main__':
     allowed_framework_names = FRAMEWORK_CONFIG_MAP.keys()
 
-    cli_parser = optparse.OptionParser(usage="usage: %prog [options] <Inputs.json>")
+    cli_parser = optparse.OptionParser(usage="usage: %prog [options] <Inputs.json> [, <MoreInputs.json> ]")
     cli_parser.add_option("-o", "--outputDir", help="Directory where generated files should be written.")
     cli_parser.add_option("--framework", type="choice", choices=allowed_framework_names, help="The framework these inputs belong to.")  # JavaScriptCore, WebCore
     cli_parser.add_option("--force", action="store_true", help="Force output of generated scripts, even if nothing changed.")
@@ -978,8 +1024,6 @@ if __name__ == '__main__':
     options = None
 
     arg_options, arg_values = cli_parser.parse_args()
-    if (len(arg_values) < 1):
-        raise ParseException("At least one plain argument expected")
 
     if not arg_options.outputDir:
         raise ParseException("Missing output directory")
@@ -988,7 +1032,7 @@ if __name__ == '__main__':
         log.setLevel(logging.DEBUG)
 
     options = {
-        'input_filepath': arg_values[0],
+        'input_filepaths': arg_values,
         'output_dirpath': arg_options.outputDir,
         'output_prefix': os.path.basename(arg_values[0]) if arg_options.test else "",
         'framework_name': arg_options.framework,
@@ -996,7 +1040,7 @@ if __name__ == '__main__':
     }
 
     try:
-        generate_from_specification(**options)
+        generate_from_specifications(**options)
     except (ParseException, TypecheckException) as e:
         if arg_options.test:
             log.error(e.message)
index 1095dfd81fa102f93c27fbfd3f0b81c0b5b8915a..6d8112b44cc26af943270c5639892348f4d995b0 100644 (file)
@@ -88,6 +88,8 @@ namespace ${inputsNamespace} {
 ${inputClassDeclarations}
 } // namespace ${inputsNamespace}
 
+${inputTypeTraitDeclarations}
+
 ${forEachMacro}
 
 #endif // ${guardCondition}
@@ -98,26 +100,31 @@ ${forEachMacro}
     InputTraitsDeclaration = (
     """template<> ${structOrClass} InputTraits<${qualifiedInputName}> {
     static InputQueue queue() { return InputQueue::${queueType}; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const ${qualifiedInputName}&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<${qualifiedInputName}>&);
 };""")
 
+    InputTypeTraitsDeclaration = (
+    """SPECIALIZE_TYPE_TRAITS_BEGIN(${qualifiedInputName})
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<${qualifiedInputName}>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()""")
+
     EnumTraitDeclaration = (
-    """template<> struct EncodingTraits<${enumName}> {
-    typedef ${enumName} DecodedType;
+    """template<> ${structOrClass} EncodingTraits<${encodingTypeArgument}> {
+    typedef ${enumType} DecodedType;
 
-    static EncodedValue encodeValue(const ${enumName}& value);
-    static bool decodeValue(EncodedValue&, ${enumName}& value);
+    static EncodedValue encodeValue(const ${enumType}& value);
+    static bool decodeValue(EncodedValue&, ${enumType}& value);
 };""")
 
     EnumClassTraitDeclaration = (
-    """template<> struct EncodingTraits<${enumName}> {
-    typedef ${enumName} DecodedType;
+    """template<> ${structOrClass} EncodingTraits<${encodingTypeArgument}> {
+    typedef ${enumType} DecodedType;
 
-    static EncodedValue encodeValue(const ${enumName}& value);
-    static bool decodeValue(EncodedValue&, ${enumName}& value);
+    static EncodedValue encodeValue(const ${enumType}& value);
+    static bool decodeValue(EncodedValue&, ${enumType}& value);
 };""")
 
     InputClassDeclaration = (
@@ -152,9 +159,10 @@ ${enumTraitImplementations}
 """)
 
     InputTraitsImplementation = (
-    """const AtomicString& InputTraits<${qualifiedInputName}>::type()
+    """const String& InputTraits<${qualifiedInputName}>::type()
 {
-$inputTypeImplementation
+    static NeverDestroyed<const String> type(ASCIILiteral(${inputNameStringLiteral}));
+    return type;
 }
 
 void InputTraits<${qualifiedInputName}>::encode(EncodedValue& encodedValue, const ${qualifiedInputName}& input)
@@ -170,7 +178,7 @@ ${decodeSteps}
 }""")
 
     EnumClassTraitImplementation = (
-    """EncodedValue EncodingTraits<${enumName}>::encodeValue(const ${enumName}& enumValue)
+    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumType}& enumValue)
 {
     switch (enumValue) {
 ${encodeCases}
@@ -178,7 +186,7 @@ ${encodeCases}
     }
 }
 
-bool EncodingTraits<${enumName}>::decodeValue(EncodedValue& encodedValue, ${enumName}& enumValue)
+bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumType}& enumValue)
 {
     String enumString = encodedValue.convertTo<String>();
 ${decodeCases}
@@ -195,20 +203,20 @@ ${decodeCases}
     }""")
 
     EnumTraitImplementation = (
-    """EncodedValue EncodingTraits<${enumName}>::encodeValue(const ${enumName}& enumValue)
+    """EncodedValue EncodingTraits<${encodingTypeArgument}>::encodeValue(const ${enumType}& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();
 ${encodeCases}
     return encodedValue;
 }
 
-bool EncodingTraits<${enumName}>::decodeValue(EncodedValue& encodedValue, ${enumName}& enumValue)
+bool EncodingTraits<${encodingTypeArgument}>::decodeValue(EncodedValue& encodedValue, ${enumType}& enumValue)
 {
     Vector<String> enumStrings;
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
 ${decodeCases}
     }
 
@@ -223,15 +231,9 @@ ${decodeCases}
     }""")
 
     EnumDecodeCase = (
-    """        if (enumString == "${enumStringValue}")
+    """        ${branchKeyword} (enumString == "${enumStringValue}")
             enumValue = static_cast<${qualifiedEnumName}>(enumValue | ${qualifiedEnumValue});""")
 
-    InputTypeFromStaticLocal = (
-    """    static NeverDestroyed<const AtomicString> type("${inputName}", AtomicString::ConstructFromLiteral);
-    return type;""")
-
-    InputTypeFromThreadLocal = "    return WebCore::inputTypes().${inputName};"
-
     InputClassImplementation = (
     """${inputName}::${inputName}(${constructorFormalsList})
 ${initializerList}
index 2e8bee67cfe18f8c9c5bcabf4146576edfa82057..382fb0407e92cfbcbde02139414a39f0160045c6 100644 (file)
@@ -1 +1 @@
-ERROR: Could not parse enum MouseButton: C-style enums must also specify their storage type so they can be forward declared.
+ERROR: Could not parse enum MouseButton: C-style enums not enclosed by a class must specify their storage type so they can be forward declared.
diff --git a/replay/scripts/tests/expected/fail-on-no-inputs.json-error b/replay/scripts/tests/expected/fail-on-no-inputs.json-error
deleted file mode 100644 (file)
index f95ace7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ERROR: When parsing toplevel, required property missing: inputs
diff --git a/replay/scripts/tests/expected/fail-on-no-types.json-error b/replay/scripts/tests/expected/fail-on-no-types.json-error
deleted file mode 100644 (file)
index 6231c8d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ERROR: When parsing toplevel, required property missing: types
index 48f13fe51437cd50b26443be121933aee3cc86aa..d5b15855b6e278807e44830f9cc1a2bf73c652c1 100644 (file)
@@ -48,9 +48,9 @@ SavedMouseButton::~SavedMouseButton()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::SavedMouseButton>::type()
+const String& InputTraits<Test::SavedMouseButton>::type()
 {
-    static NeverDestroyed<const AtomicString> type("SavedMouseButton", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("SavedMouseButton"));
     return type;
 }
 
@@ -68,80 +68,7 @@ bool InputTraits<Test::SavedMouseButton>::decode(EncodedValue& encodedValue, std
     input = std::make_unique<Test::SavedMouseButton>(button);
     return true;
 }
-EncodedValue EncodingTraits<WebCore::MouseButton>::encodeValue(const WebCore::MouseButton& enumValue)
-{
-    EncodedValue encodedValue = EncodedValue::createArray();
-    if (enumValue & WebCore::NoButton) {
-        encodedValue.append<String>(ASCIILiteral("NoButton"));
-        if (enumValue == WebCore::NoButton)
-            return encodedValue;
-    }
-    if (enumValue & WebCore::LeftButton) {
-        encodedValue.append<String>(ASCIILiteral("LeftButton"));
-        if (enumValue == WebCore::LeftButton)
-            return encodedValue;
-    }
-    if (enumValue & WebCore::MiddleButton) {
-        encodedValue.append<String>(ASCIILiteral("MiddleButton"));
-        if (enumValue == WebCore::MiddleButton)
-            return encodedValue;
-    }
-    if (enumValue & WebCore::RightButton) {
-        encodedValue.append<String>(ASCIILiteral("RightButton"));
-        if (enumValue == WebCore::RightButton)
-            return encodedValue;
-    }
-#if ENABLE(SIDE_BUTTONS)
-    if (enumValue & WebCore::LeftSideButton) {
-        encodedValue.append<String>(ASCIILiteral("LeftSideButton"));
-        if (enumValue == WebCore::LeftSideButton)
-            return encodedValue;
-    }
-    if (enumValue & WebCore::RightSideButton) {
-        encodedValue.append<String>(ASCIILiteral("RightSideButton"));
-        if (enumValue == WebCore::RightSideButton)
-            return encodedValue;
-    }
-#endif // ENABLE(SIDE_BUTTONS)
-#if PLATFORM(WINDOWS)
-    if (enumValue & WebCore::WindowsButton) {
-        encodedValue.append<String>(ASCIILiteral("WindowsButton"));
-        if (enumValue == WebCore::WindowsButton)
-            return encodedValue;
-    }
-#endif // PLATFORM(WINDOWS)
-    return encodedValue;
-}
-
-bool EncodingTraits<WebCore::MouseButton>::decodeValue(EncodedValue& encodedValue, WebCore::MouseButton& enumValue)
-{
-    Vector<String> enumStrings;
-    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
-        return false;
-
-    for (String enumString : enumStrings) {
-        if (enumString == "NoButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::NoButton);
-        if (enumString == "LeftButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftButton);
-        if (enumString == "MiddleButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::MiddleButton);
-        if (enumString == "RightButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightButton);
-#if ENABLE(SIDE_BUTTONS)
-        if (enumString == "LeftSideButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftSideButton);
-        if (enumString == "RightSideButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightSideButton);
-#endif // ENABLE(SIDE_BUTTONS)
-#if PLATFORM(WINDOWS)
-        if (enumString == "WindowsButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::WindowsButton);
-#endif // PLATFORM(WINDOWS)
-    }
 
-    return true;
-}
 } // namespace JSC
 
 #endif // ENABLE(WEB_REPLAY)
index 14937cd6247822bc34d971bec0c0881ffd20e369..a9f0673fd07aea3ea96f57f163e5afae18a30c0b 100644 (file)
@@ -44,25 +44,20 @@ class SavedMouseButton;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::SavedMouseButton> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::SavedMouseButton> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::SavedMouseButton&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::SavedMouseButton>&);
 };
-template<> struct EncodingTraits<WebCore::MouseButton> {
-    typedef WebCore::MouseButton DecodedType;
 
-    static EncodedValue encodeValue(const WebCore::MouseButton& value);
-    static bool decodeValue(EncodedValue&, WebCore::MouseButton& value);
-};
 } // namespace JSC
 
 namespace Test {
 class SavedMouseButton : public NondeterministicInput<SavedMouseButton> {
 public:
-    SavedMouseButton(MouseButton button);
+    TEST_EXPORT_MACRO SavedMouseButton(MouseButton button);
     virtual ~SavedMouseButton();
 
     MouseButton button() const { return m_button; }
@@ -71,6 +66,10 @@ private:
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::SavedMouseButton)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::SavedMouseButton>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(SavedMouseButton) \
     \
index 6406994a138fe3316d26209d9063b2e67409477b..02df572449957c5f30c1780b2d0d3f240a32a8e2 100644 (file)
@@ -32,9 +32,9 @@
 
 #if ENABLE(WEB_REPLAY)
 #include "InternalNamespaceImplIncludeDummy.h"
+#include "NondeterministicInput.h"
+#include "PlatformMouseEvent.h"
 #include <platform/ExternalNamespaceImplIncludeDummy.h>
-#include <platform/PlatformMouseEvent.h>
-#include <replay/NondeterministicInput.h>
 
 namespace Test {
 SavedMouseButton::SavedMouseButton(MouseButton button)
@@ -49,95 +49,141 @@ SavedMouseButton::~SavedMouseButton()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::SavedMouseButton>::type()
+const String& InputTraits<Test::SavedMouseButton>::type()
 {
-    static NeverDestroyed<const AtomicString> type("SavedMouseButton", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("SavedMouseButton"));
     return type;
 }
 
 void InputTraits<Test::SavedMouseButton>::encode(EncodedValue& encodedValue, const Test::SavedMouseButton& input)
 {
-    encodedValue.put<WebCore::MouseButton>(ASCIILiteral("button"), input.button());
+    encodedValue.put<Test::MouseButton>(ASCIILiteral("button"), input.button());
 }
 
 bool InputTraits<Test::SavedMouseButton>::decode(EncodedValue& encodedValue, std::unique_ptr<Test::SavedMouseButton>& input)
 {
-    WebCore::MouseButton button;
-    if (!encodedValue.get<WebCore::MouseButton>(ASCIILiteral("button"), button))
+    Test::MouseButton button;
+    if (!encodedValue.get<Test::MouseButton>(ASCIILiteral("button"), button))
         return false;
 
     input = std::make_unique<Test::SavedMouseButton>(button);
     return true;
 }
-EncodedValue EncodingTraits<InputQueue>::encodeValue(const InputQueue& enumValue)
+EncodedValue EncodingTraits<Test::InputQueue>::encodeValue(const Test::InputQueue& enumValue)
 {
     switch (enumValue) {
-    case InputQueue::EventLoopInput: return EncodedValue::createString("EventLoopInput");
-    case InputQueue::LoaderMemoizedData: return EncodedValue::createString("LoaderMemoizedData");
-    case InputQueue::ScriptMemoizedData: return EncodedValue::createString("ScriptMemoizedData");
+    case Test::InputQueue::EventLoopInput: return EncodedValue::createString("EventLoopInput");
+    case Test::InputQueue::LoaderMemoizedData: return EncodedValue::createString("LoaderMemoizedData");
+    case Test::InputQueue::ScriptMemoizedData: return EncodedValue::createString("ScriptMemoizedData");
     default: ASSERT_NOT_REACHED(); return EncodedValue::createString("Error!");
     }
 }
 
-bool EncodingTraits<InputQueue>::decodeValue(EncodedValue& encodedValue, InputQueue& enumValue)
+bool EncodingTraits<Test::InputQueue>::decodeValue(EncodedValue& encodedValue, Test::InputQueue& enumValue)
 {
     String enumString = encodedValue.convertTo<String>();
     if (enumString == "EventLoopInput") {
-        enumValue = InputQueue::EventLoopInput;
+        enumValue = Test::InputQueue::EventLoopInput;
         return true;
     }
     if (enumString == "LoaderMemoizedData") {
-        enumValue = InputQueue::LoaderMemoizedData;
+        enumValue = Test::InputQueue::LoaderMemoizedData;
         return true;
     }
     if (enumString == "ScriptMemoizedData") {
-        enumValue = InputQueue::ScriptMemoizedData;
+        enumValue = Test::InputQueue::ScriptMemoizedData;
         return true;
     }
     return false;
 }
 
-EncodedValue EncodingTraits<WebCore::MouseButton>::encodeValue(const WebCore::MouseButton& enumValue)
+EncodedValue EncodingTraits<Test::MouseButton>::encodeValue(const Test::MouseButton& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();
-    if (enumValue & WebCore::NoButton) {
+    if (enumValue & Test::NoButton) {
         encodedValue.append<String>(ASCIILiteral("NoButton"));
-        if (enumValue == WebCore::NoButton)
+        if (enumValue == Test::NoButton)
             return encodedValue;
     }
-    if (enumValue & WebCore::LeftButton) {
+    if (enumValue & Test::LeftButton) {
         encodedValue.append<String>(ASCIILiteral("LeftButton"));
-        if (enumValue == WebCore::LeftButton)
+        if (enumValue == Test::LeftButton)
             return encodedValue;
     }
-    if (enumValue & WebCore::MiddleButton) {
+    if (enumValue & Test::MiddleButton) {
         encodedValue.append<String>(ASCIILiteral("MiddleButton"));
-        if (enumValue == WebCore::MiddleButton)
+        if (enumValue == Test::MiddleButton)
             return encodedValue;
     }
-    if (enumValue & WebCore::RightButton) {
+    if (enumValue & Test::RightButton) {
         encodedValue.append<String>(ASCIILiteral("RightButton"));
-        if (enumValue == WebCore::RightButton)
+        if (enumValue == Test::RightButton)
             return encodedValue;
     }
     return encodedValue;
 }
 
-bool EncodingTraits<WebCore::MouseButton>::decodeValue(EncodedValue& encodedValue, WebCore::MouseButton& enumValue)
+bool EncodingTraits<Test::MouseButton>::decodeValue(EncodedValue& encodedValue, Test::MouseButton& enumValue)
 {
     Vector<String> enumStrings;
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "NoButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::NoButton);
-        if (enumString == "LeftButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::LeftButton);
-        if (enumString == "MiddleButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::MiddleButton);
-        if (enumString == "RightButton")
-            enumValue = static_cast<WebCore::MouseButton>(enumValue | WebCore::RightButton);
+            enumValue = static_cast<Test::MouseButton>(enumValue | Test::NoButton);
+        else if (enumString == "LeftButton")
+            enumValue = static_cast<Test::MouseButton>(enumValue | Test::LeftButton);
+        else if (enumString == "MiddleButton")
+            enumValue = static_cast<Test::MouseButton>(enumValue | Test::MiddleButton);
+        else if (enumString == "RightButton")
+            enumValue = static_cast<Test::MouseButton>(enumValue | Test::RightButton);
+    }
+
+    return true;
+}
+
+EncodedValue EncodingTraits<Test::PlatformEvent::Type>::encodeValue(const Test::PlatformEvent::Type& enumValue)
+{
+    EncodedValue encodedValue = EncodedValue::createArray();
+    if (enumValue & Test::PlatformEvent::Mouse) {
+        encodedValue.append<String>(ASCIILiteral("Mouse"));
+        if (enumValue == Test::PlatformEvent::Mouse)
+            return encodedValue;
+    }
+    if (enumValue & Test::PlatformEvent::Key) {
+        encodedValue.append<String>(ASCIILiteral("Key"));
+        if (enumValue == Test::PlatformEvent::Key)
+            return encodedValue;
+    }
+    if (enumValue & Test::PlatformEvent::Touch) {
+        encodedValue.append<String>(ASCIILiteral("Touch"));
+        if (enumValue == Test::PlatformEvent::Touch)
+            return encodedValue;
+    }
+    if (enumValue & Test::PlatformEvent::Wheel) {
+        encodedValue.append<String>(ASCIILiteral("Wheel"));
+        if (enumValue == Test::PlatformEvent::Wheel)
+            return encodedValue;
+    }
+    return encodedValue;
+}
+
+bool EncodingTraits<Test::PlatformEvent::Type>::decodeValue(EncodedValue& encodedValue, Test::PlatformEvent::Type& enumValue)
+{
+    Vector<String> enumStrings;
+    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
+        return false;
+
+    for (const String& enumString : enumStrings) {
+        if (enumString == "Mouse")
+            enumValue = static_cast<Test::PlatformEvent::Type>(enumValue | Test::PlatformEvent::Mouse);
+        else if (enumString == "Key")
+            enumValue = static_cast<Test::PlatformEvent::Type>(enumValue | Test::PlatformEvent::Key);
+        else if (enumString == "Touch")
+            enumValue = static_cast<Test::PlatformEvent::Type>(enumValue | Test::PlatformEvent::Touch);
+        else if (enumString == "Wheel")
+            enumValue = static_cast<Test::PlatformEvent::Type>(enumValue | Test::PlatformEvent::Wheel);
     }
 
     return true;
index 824bb93534b442a740dc0eef099ab33259dfdf69..d38cee72e0a647e6ef6e39241c057ce25ccdfd46 100644 (file)
 
 #if ENABLE(WEB_REPLAY)
 #include "InternalNamespaceHeaderIncludeDummy.h"
+#include "PlatformEvent.h"
 #include <platform/ExternalNamespaceHeaderIncludeDummy.h>
 
-namespace WebCore {
+namespace Test {
 enum MouseButton : unsigned;
-}
-
-namespace JSC {
 enum class InputQueue;
 }
 
@@ -48,32 +46,39 @@ class SavedMouseButton;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::SavedMouseButton> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::SavedMouseButton> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::SavedMouseButton&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::SavedMouseButton>&);
 };
-template<> struct EncodingTraits<InputQueue> {
-    typedef InputQueue DecodedType;
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::InputQueue> {
+    typedef Test::InputQueue DecodedType;
 
-    static EncodedValue encodeValue(const InputQueue& value);
-    static bool decodeValue(EncodedValue&, InputQueue& value);
+    static EncodedValue encodeValue(const Test::InputQueue& value);
+    static bool decodeValue(EncodedValue&, Test::InputQueue& value);
 };
 
-template<> struct EncodingTraits<WebCore::MouseButton> {
-    typedef WebCore::MouseButton DecodedType;
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::MouseButton> {
+    typedef Test::MouseButton DecodedType;
 
-    static EncodedValue encodeValue(const WebCore::MouseButton& value);
-    static bool decodeValue(EncodedValue&, WebCore::MouseButton& value);
+    static EncodedValue encodeValue(const Test::MouseButton& value);
+    static bool decodeValue(EncodedValue&, Test::MouseButton& value);
+};
+
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::PlatformEvent::Type> {
+    typedef Test::PlatformEvent::Type DecodedType;
+
+    static EncodedValue encodeValue(const Test::PlatformEvent::Type& value);
+    static bool decodeValue(EncodedValue&, Test::PlatformEvent::Type& value);
 };
 } // namespace JSC
 
 namespace Test {
 class SavedMouseButton : public NondeterministicInput<SavedMouseButton> {
 public:
-    SavedMouseButton(MouseButton button);
+    TEST_EXPORT_MACRO SavedMouseButton(MouseButton button);
     virtual ~SavedMouseButton();
 
     MouseButton button() const { return m_button; }
@@ -82,6 +87,10 @@ private:
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::SavedMouseButton)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::SavedMouseButton>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(SavedMouseButton) \
     \
index 5a7c9079cadded49b3c9f75fa4a42a92b01a61b3..0aa7820596c8092004bcae3fc4842da0159be726 100644 (file)
 
 #if ENABLE(WEB_REPLAY)
 #include "InternalNamespaceImplIncludeDummy.h"
+#include "PlatformWheelEvent.h"
 #include <platform/ExternalNamespaceImplIncludeDummy.h>
 #include <platform/PlatformWheelEvent.h>
 
 namespace Test {
-HandleWheelEvent::HandleWheelEvent(std::unique_ptr<PlatformWheelEvent> platformEvent)
+HandleWheelEvent::HandleWheelEvent(std::unique_ptr<PlatformWheelEvent> platformEvent, PlatformWheelPhase phase)
     : EventLoopInput<HandleWheelEvent>()
     , m_platformEvent(WTF::move(platformEvent))
+    , m_phase(phase)
 {
 }
 
@@ -48,15 +50,16 @@ HandleWheelEvent::~HandleWheelEvent()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::HandleWheelEvent>::type()
+const String& InputTraits<Test::HandleWheelEvent>::type()
 {
-    static NeverDestroyed<const AtomicString> type("HandleWheelEvent", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("HandleWheelEvent"));
     return type;
 }
 
 void InputTraits<Test::HandleWheelEvent>::encode(EncodedValue& encodedValue, const Test::HandleWheelEvent& input)
 {
     encodedValue.put<WebCore::PlatformWheelEvent>(ASCIILiteral("platformEvent"), input.platformEvent());
+    encodedValue.put<Test::PlatformWheelPhase>(ASCIILiteral("phase"), input.phase());
 }
 
 bool InputTraits<Test::HandleWheelEvent>::decode(EncodedValue& encodedValue, std::unique_ptr<Test::HandleWheelEvent>& input)
@@ -65,30 +68,34 @@ bool InputTraits<Test::HandleWheelEvent>::decode(EncodedValue& encodedValue, std
     if (!encodedValue.get<WebCore::PlatformWheelEvent>(ASCIILiteral("platformEvent"), platformEvent))
         return false;
 
-    input = std::make_unique<Test::HandleWheelEvent>(WTF::move(platformEvent));
+    Test::PlatformWheelPhase phase;
+    if (!encodedValue.get<Test::PlatformWheelPhase>(ASCIILiteral("phase"), phase))
+        return false;
+
+    input = std::make_unique<Test::HandleWheelEvent>(WTF::move(platformEvent), phase);
     return true;
 }
 #if ENABLE(DUMMY_FEATURE)
-EncodedValue EncodingTraits<WebCore::PlatformWheelEventPhase>::encodeValue(const WebCore::PlatformWheelEventPhase& enumValue)
+EncodedValue EncodingTraits<Test::PlatformWheelPhase>::encodeValue(const Test::PlatformWheelPhase& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();
-    if (enumValue & WebCore::PlatformWheelEventPhaseNone) {
+    if (enumValue & Test::PlatformWheelEventPhaseNone) {
         encodedValue.append<String>(ASCIILiteral("PlatformWheelEventPhaseNone"));
-        if (enumValue == WebCore::PlatformWheelEventPhaseNone)
+        if (enumValue == Test::PlatformWheelEventPhaseNone)
             return encodedValue;
     }
     return encodedValue;
 }
 
-bool EncodingTraits<WebCore::PlatformWheelEventPhase>::decodeValue(EncodedValue& encodedValue, WebCore::PlatformWheelEventPhase& enumValue)
+bool EncodingTraits<Test::PlatformWheelPhase>::decodeValue(EncodedValue& encodedValue, Test::PlatformWheelPhase& enumValue)
 {
     Vector<String> enumStrings;
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "PlatformWheelEventPhaseNone")
-            enumValue = static_cast<WebCore::PlatformWheelEventPhase>(enumValue | WebCore::PlatformWheelEventPhaseNone);
+            enumValue = static_cast<Test::PlatformWheelPhase>(enumValue | Test::PlatformWheelEventPhaseNone);
     }
 
     return true;
index 81826a60bbe9aadd76c7b57f0bdb220701a90846..3302f580b8e9cb7948078f2fefaa68023f929247 100644 (file)
 #include "InternalNamespaceHeaderIncludeDummy.h"
 #include <platform/ExternalNamespaceHeaderIncludeDummy.h>
 
+namespace Test {
+enum PlatformWheelPhase : uint64_t;
+}
+
 namespace WebCore {
 class PlatformWheelEvent;
-enum PlatformWheelEventPhase : uint64_t;
 }
 
 
@@ -45,19 +48,19 @@ class HandleWheelEvent;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::HandleWheelEvent> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::HandleWheelEvent> {
     static InputQueue queue() { return InputQueue::EventLoopInput; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::HandleWheelEvent&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::HandleWheelEvent>&);
 };
 #if ENABLE(DUMMY_FEATURE)
-template<> struct EncodingTraits<WebCore::PlatformWheelEventPhase> {
-    typedef WebCore::PlatformWheelEventPhase DecodedType;
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::PlatformWheelPhase> {
+    typedef Test::PlatformWheelPhase DecodedType;
 
-    static EncodedValue encodeValue(const WebCore::PlatformWheelEventPhase& value);
-    static bool decodeValue(EncodedValue&, WebCore::PlatformWheelEventPhase& value);
+    static EncodedValue encodeValue(const Test::PlatformWheelPhase& value);
+    static bool decodeValue(EncodedValue&, Test::PlatformWheelPhase& value);
 };
 #endif // ENABLE(DUMMY_FEATURE)
 } // namespace JSC
@@ -65,17 +68,23 @@ template<> struct EncodingTraits<WebCore::PlatformWheelEventPhase> {
 namespace Test {
 class HandleWheelEvent : public EventLoopInput<HandleWheelEvent> {
 public:
-    HandleWheelEvent(std::unique_ptr<PlatformWheelEvent> platformEvent);
+    TEST_EXPORT_MACRO HandleWheelEvent(std::unique_ptr<PlatformWheelEvent> platformEvent, PlatformWheelPhase phase);
     virtual ~HandleWheelEvent();
 
     // EventLoopInput API
     virtual void dispatch(ReplayController&) override final;
     const PlatformWheelEvent& platformEvent() const { return *m_platformEvent; }
+    PlatformWheelPhase phase() const { return m_phase; }
 private:
     std::unique_ptr<PlatformWheelEvent> m_platformEvent;
+    PlatformWheelPhase m_phase;
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::HandleWheelEvent)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::HandleWheelEvent>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(HandleWheelEvent) \
     \
index 6b79631a1c5fdf80cc710f43067697e88aadc838..a19644ffa05fb5da9d6883ad049fe465c1021dfe 100644 (file)
 #include <platform/ExternalNamespaceImplIncludeDummy.h>
 
 namespace Test {
-FormCombo::FormCombo(PlatformEvent::Type eventType, FormData::Type formType)
+FormCombo::FormCombo(PlatformEvent1::Type eventType1, PlatformEvent2::Type eventType2, FormData1::Type formType1, FormData2::Type formType2)
     : NondeterministicInput<FormCombo>()
-    , m_eventType(eventType)
-    , m_formType(formType)
+    , m_eventType1(eventType1)
+    , m_eventType2(eventType2)
+    , m_formType1(formType1)
+    , m_formType2(formType2)
 {
 }
 
@@ -48,93 +50,94 @@ FormCombo::~FormCombo()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::FormCombo>::type()
+const String& InputTraits<Test::FormCombo>::type()
 {
-    static NeverDestroyed<const AtomicString> type("FormCombo", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("FormCombo"));
     return type;
 }
 
 void InputTraits<Test::FormCombo>::encode(EncodedValue& encodedValue, const Test::FormCombo& input)
 {
-    encodedValue.put<PlatformEvent::Type>(ASCIILiteral("eventType"), input.eventType());
-    encodedValue.put<WebCore::FormData::Type>(ASCIILiteral("formType"), input.formType());
+    encodedValue.put<PlatformEvent1::Type>(ASCIILiteral("eventType1"), input.eventType1());
+    encodedValue.put<PlatformEvent2::Type>(ASCIILiteral("eventType2"), input.eventType2());
+    encodedValue.put<Test::FormData1::Type>(ASCIILiteral("formType1"), input.formType1());
+    encodedValue.put<Test::FormData2::Type>(ASCIILiteral("formType2"), input.formType2());
 }
 
 bool InputTraits<Test::FormCombo>::decode(EncodedValue& encodedValue, std::unique_ptr<Test::FormCombo>& input)
 {
-    PlatformEvent::Type eventType;
-    if (!encodedValue.get<PlatformEvent::Type>(ASCIILiteral("eventType"), eventType))
+    PlatformEvent1::Type eventType1;
+    if (!encodedValue.get<PlatformEvent1::Type>(ASCIILiteral("eventType1"), eventType1))
         return false;
 
-    WebCore::FormData::Type formType;
-    if (!encodedValue.get<WebCore::FormData::Type>(ASCIILiteral("formType"), formType))
+    PlatformEvent2::Type eventType2;
+    if (!encodedValue.get<PlatformEvent2::Type>(ASCIILiteral("eventType2"), eventType2))
         return false;
 
-    input = std::make_unique<Test::FormCombo>(eventType, formType);
+    Test::FormData1::Type formType1;
+    if (!encodedValue.get<Test::FormData1::Type>(ASCIILiteral("formType1"), formType1))
+        return false;
+
+    Test::FormData2::Type formType2;
+    if (!encodedValue.get<Test::FormData2::Type>(ASCIILiteral("formType2"), formType2))
+        return false;
+
+    input = std::make_unique<Test::FormCombo>(eventType1, eventType2, formType1, formType2);
     return true;
 }
-EncodedValue EncodingTraits<WebCore::FormData::Type>::encodeValue(const WebCore::FormData::Type& enumValue)
+EncodedValue EncodingTraits<Test::FormData1::Type>::encodeValue(const Test::FormData1::Type& enumValue)
 {
     EncodedValue encodedValue = EncodedValue::createArray();
-    if (enumValue & WebCore::FormData::Text) {
+    if (enumValue & Test::FormData1::Text) {
         encodedValue.append<String>(ASCIILiteral("Text"));
-        if (enumValue == WebCore::FormData::Text)
+        if (enumValue == Test::FormData1::Text)
             return encodedValue;
     }
-    if (enumValue & WebCore::FormData::Blob) {
+    if (enumValue & Test::FormData1::Blob) {
         encodedValue.append<String>(ASCIILiteral("Blob"));
-        if (enumValue == WebCore::FormData::Blob)
+        if (enumValue == Test::FormData1::Blob)
             return encodedValue;
     }
     return encodedValue;
 }
 
-bool EncodingTraits<WebCore::FormData::Type>::decodeValue(EncodedValue& encodedValue, WebCore::FormData::Type& enumValue)
+bool EncodingTraits<Test::FormData1::Type>::decodeValue(EncodedValue& encodedValue, Test::FormData1::Type& enumValue)
 {
     Vector<String> enumStrings;
     if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
         return false;
 
-    for (String enumString : enumStrings) {
+    for (const String& enumString : enumStrings) {
         if (enumString == "Text")
-            enumValue = static_cast<WebCore::FormData::Type>(enumValue | WebCore::FormData::Text);
-        if (enumString == "Blob")
-            enumValue = static_cast<WebCore::FormData::Type>(enumValue | WebCore::FormData::Blob);
+            enumValue = static_cast<Test::FormData1::Type>(enumValue | Test::FormData1::Text);
+        else if (enumString == "Blob")
+            enumValue = static_cast<Test::FormData1::Type>(enumValue | Test::FormData1::Blob);
     }
 
     return true;
 }
 
-EncodedValue EncodingTraits<PlatformEvent::Type>::encodeValue(const PlatformEvent::Type& enumValue)
+EncodedValue EncodingTraits<Test::FormData2::Type>::encodeValue(const Test::FormData2::Type& enumValue)
 {
-    EncodedValue encodedValue = EncodedValue::createArray();
-    if (enumValue & PlatformEvent::Mouse) {
-        encodedValue.append<String>(ASCIILiteral("Mouse"));
-        if (enumValue == PlatformEvent::Mouse)
-            return encodedValue;
-    }
-    if (enumValue & PlatformEvent::Keyboard) {
-        encodedValue.append<String>(ASCIILiteral("Keyboard"));
-        if (enumValue == PlatformEvent::Keyboard)
-            return encodedValue;
+    switch (enumValue) {
+    case Test::FormData2::Type::Text: return EncodedValue::createString("Text");
+    case Test::FormData2::Type::Blob: return EncodedValue::createString("Blob");
+    default: ASSERT_NOT_REACHED(); return EncodedValue::createString("Error!");
     }
-    return encodedValue;
 }
 
-bool EncodingTraits<PlatformEvent::Type>::decodeValue(EncodedValue& encodedValue, PlatformEvent::Type& enumValue)
+bool EncodingTraits<Test::FormData2::Type>::decodeValue(EncodedValue& encodedValue, Test::FormData2::Type& enumValue)
 {
-    Vector<String> enumStrings;
-    if (!EncodingTraits<Vector<String>>::decodeValue(encodedValue, enumStrings))
-        return false;
-
-    for (String enumString : enumStrings) {
-        if (enumString == "Mouse")
-            enumValue = static_cast<PlatformEvent::Type>(enumValue | PlatformEvent::Mouse);
-        if (enumString == "Keyboard")
-            enumValue = static_cast<PlatformEvent::Type>(enumValue | PlatformEvent::Keyboard);
+    String enumString = encodedValue.convertTo<String>();
+    if (enumString == "Text") {
+        enumValue = Test::FormData2::Type::Text;
+        return true;
     }
-
-    return true;
+    if (enumString == "Blob") {
+        enumValue = Test::FormData2::Type::Blob;
+        return true;
+    }
+    return false;
 }
 } // namespace JSC
 
index d73407696b67f780448804e4c60d664b75145445..fd3b39897be3d2bc16f75d195f75e6cb28e562b0 100644 (file)
 #define generate_enums_with_same_base_name_json_TestReplayInputs_h
 
 #if ENABLE(WEB_REPLAY)
+#include "FormData1.h"
+#include "FormData2.h"
 #include "InternalNamespaceHeaderIncludeDummy.h"
 #include <platform/ExternalNamespaceHeaderIncludeDummy.h>
-#include <replay/FormData.h>
 #include <replay/PlatformEvent.h>
 
 
@@ -43,42 +44,50 @@ class FormCombo;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::FormCombo> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::FormCombo> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::FormCombo&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::FormCombo>&);
 };
-template<> struct EncodingTraits<WebCore::FormData::Type> {
-    typedef WebCore::FormData::Type DecodedType;
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::FormData1::Type> {
+    typedef Test::FormData1::Type DecodedType;
 
-    static EncodedValue encodeValue(const WebCore::FormData::Type& value);
-    static bool decodeValue(EncodedValue&, WebCore::FormData::Type& value);
+    static EncodedValue encodeValue(const Test::FormData1::Type& value);
+    static bool decodeValue(EncodedValue&, Test::FormData1::Type& value);
 };
 
-template<> struct EncodingTraits<PlatformEvent::Type> {
-    typedef PlatformEvent::Type DecodedType;
+template<> struct TEST_EXPORT_MACRO EncodingTraits<Test::FormData2::Type> {
+    typedef Test::FormData2::Type DecodedType;
 
-    static EncodedValue encodeValue(const PlatformEvent::Type& value);
-    static bool decodeValue(EncodedValue&, PlatformEvent::Type& value);
+    static EncodedValue encodeValue(const Test::FormData2::Type& value);
+    static bool decodeValue(EncodedValue&, Test::FormData2::Type& value);
 };
 } // namespace JSC
 
 namespace Test {
 class FormCombo : public NondeterministicInput<FormCombo> {
 public:
-    FormCombo(PlatformEvent::Type eventType, FormData::Type formType);
+    TEST_EXPORT_MACRO FormCombo(PlatformEvent1::Type eventType1, PlatformEvent2::Type eventType2, FormData1::Type formType1, FormData2::Type formType2);
     virtual ~FormCombo();
 
-    PlatformEvent::Type eventType() const { return m_eventType; }
-    FormData::Type formType() const { return m_formType; }
+    PlatformEvent1::Type eventType1() const { return m_eventType1; }
+    PlatformEvent2::Type eventType2() const { return m_eventType2; }
+    FormData1::Type formType1() const { return m_formType1; }
+    FormData2::Type formType2() const { return m_formType2; }
 private:
-    PlatformEvent::Type m_eventType;
-    FormData::Type m_formType;
+    PlatformEvent1::Type m_eventType1;
+    PlatformEvent2::Type m_eventType2;
+    FormData1::Type m_formType1;
+    FormData2::Type m_formType2;
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::FormCombo)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::FormCombo>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(FormCombo) \
     \
index 2306f212e0aaa6c0e6747f0c18bebcc9375ecd0a..9cbb7af33dd14fede235ba358eee3d52569bfa8a 100644 (file)
@@ -60,9 +60,9 @@ SetRandomSeed::~SetRandomSeed()
 
 namespace JSC {
 #if ENABLE(DUMMY_FEATURE)
-const AtomicString& InputTraits<Test::GetCurrentTime>::type()
+const String& InputTraits<Test::GetCurrentTime>::type()
 {
-    static NeverDestroyed<const AtomicString> type("GetCurrentTime", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("GetCurrentTime"));
     return type;
 }
 
@@ -82,9 +82,9 @@ bool InputTraits<Test::GetCurrentTime>::decode(EncodedValue& encodedValue, std::
 }
 #endif // ENABLE(DUMMY_FEATURE)
 
-const AtomicString& InputTraits<Test::SetRandomSeed>::type()
+const String& InputTraits<Test::SetRandomSeed>::type()
 {
-    static NeverDestroyed<const AtomicString> type("SetRandomSeed", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("SetRandomSeed"));
     return type;
 }
 
index a0d7d393670c2b6f61ac8c10d7f67192b59ab79a..e0967ccc22bd28b653856642e08fe3f80b9a07ab 100644 (file)
@@ -45,18 +45,18 @@ class SetRandomSeed;
 
 namespace JSC {
 #if ENABLE(DUMMY_FEATURE)
-template<> struct InputTraits<Test::GetCurrentTime> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::GetCurrentTime> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::GetCurrentTime&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::GetCurrentTime>&);
 };
 #endif // ENABLE(DUMMY_FEATURE)
 
-template<> struct InputTraits<Test::SetRandomSeed> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::SetRandomSeed> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::SetRandomSeed&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::SetRandomSeed>&);
@@ -68,7 +68,7 @@ namespace Test {
 #if ENABLE(DUMMY_FEATURE)
 class GetCurrentTime : public NondeterministicInput<GetCurrentTime> {
 public:
-    GetCurrentTime(double currentTime);
+    TEST_EXPORT_MACRO GetCurrentTime(double currentTime);
     virtual ~GetCurrentTime();
 
     double currentTime() const { return m_currentTime; }
@@ -79,7 +79,7 @@ private:
 
 class SetRandomSeed : public NondeterministicInput<SetRandomSeed> {
 public:
-    SetRandomSeed(uint64_t randomSeed);
+    TEST_EXPORT_MACRO SetRandomSeed(uint64_t randomSeed);
     virtual ~SetRandomSeed();
 
     uint64_t randomSeed() const { return m_randomSeed; }
@@ -88,6 +88,16 @@ private:
 };
 } // namespace Test
 
+#if ENABLE(DUMMY_FEATURE)
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::GetCurrentTime)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::GetCurrentTime>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+#endif // ENABLE(DUMMY_FEATURE)
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::SetRandomSeed)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::SetRandomSeed>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(GetCurrentTime) \
     macro(SetRandomSeed) \
index 02bb56b525c446b0db1138bde7d5f2dc5cf962ba..f2f962a193b8c9ac00ed1b068501fb8beb486716 100644 (file)
@@ -48,12 +48,22 @@ ArrayOfThings::ArrayOfThings(Vector<double>& doubles, Vector<JSThing>& jsthings,
 ArrayOfThings::~ArrayOfThings()
 {
 }
+
+SavedHistory::SavedHistory(Vector<RefPtr<HistoryItem>>& entries)
+    : NondeterministicInput<SavedHistory>()
+    , m_entries(entries)
+{
+}
+
+SavedHistory::~SavedHistory()
+{
+}
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::ArrayOfThings>::type()
+const String& InputTraits<Test::ArrayOfThings>::type()
 {
-    static NeverDestroyed<const AtomicString> type("ArrayOfThings", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("ArrayOfThings"));
     return type;
 }
 
@@ -82,6 +92,27 @@ bool InputTraits<Test::ArrayOfThings>::decode(EncodedValue& encodedValue, std::u
     return true;
 }
 
+const String& InputTraits<Test::SavedHistory>::type()
+{
+    static NeverDestroyed<const String> type(ASCIILiteral("SavedHistory"));
+    return type;
+}
+
+void InputTraits<Test::SavedHistory>::encode(EncodedValue& encodedValue, const Test::SavedHistory& input)
+{
+    encodedValue.put<Vector<WebCore::HistoryItem>>(ASCIILiteral("entries"), input.entries());
+}
+
+bool InputTraits<Test::SavedHistory>::decode(EncodedValue& encodedValue, std::unique_ptr<Test::SavedHistory>& input)
+{
+    Vector<RefPtr<WebCore::HistoryItem>> entries;
+    if (!encodedValue.get<Vector<WebCore::HistoryItem>>(ASCIILiteral("entries"), entries))
+        return false;
+
+    input = std::make_unique<Test::SavedHistory>(entries);
+    return true;
+}
+
 } // namespace JSC
 
 #endif // ENABLE(WEB_REPLAY)
index 278c37d409170f6f40ce6fbff302ae447d48d026..467c0102c6f16b2a43122e02fc4c82c6e27f699c 100644 (file)
 
 #if ENABLE(WEB_REPLAY)
 #include "InternalNamespaceHeaderIncludeDummy.h"
+#include <history/HistoryItem.h>
 #include <platform/ExternalNamespaceHeaderIncludeDummy.h>
 
+namespace WebCore {
+class HistoryItem;
+}
 
 
 namespace Test {
 class ArrayOfThings;
+class SavedHistory;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::ArrayOfThings> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::ArrayOfThings> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::ArrayOfThings&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::ArrayOfThings>&);
 };
 
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::SavedHistory> {
+    static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
+    static const String& type();
+
+    static void encode(JSC::EncodedValue&, const Test::SavedHistory&);
+    static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::SavedHistory>&);
+};
+
 } // namespace JSC
 
 namespace Test {
 class ArrayOfThings : public NondeterministicInput<ArrayOfThings> {
 public:
-    ArrayOfThings(Vector<double>& doubles, Vector<JSThing>& jsthings, Vector<WebThing>& webthings);
+    TEST_EXPORT_MACRO ArrayOfThings(Vector<double>& doubles, Vector<JSThing>& jsthings, Vector<WebThing>& webthings);
     virtual ~ArrayOfThings();
 
     const Vector<double>& doubles() const { return m_doubles; }
@@ -65,10 +78,29 @@ private:
     Vector<JSThing> m_jsthings;
     Vector<WebThing> m_webthings;
 };
+
+class SavedHistory : public NondeterministicInput<SavedHistory> {
+public:
+    TEST_EXPORT_MACRO SavedHistory(Vector<RefPtr<HistoryItem>>& entries);
+    virtual ~SavedHistory();
+
+    const Vector<RefPtr<HistoryItem>>& entries() const { return m_entries; }
+private:
+    Vector<RefPtr<HistoryItem>> m_entries;
+};
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::ArrayOfThings)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::ArrayOfThings>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::SavedHistory)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::SavedHistory>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(ArrayOfThings) \
+    macro(SavedHistory) \
     \
 // end of TEST_REPLAY_INPUT_NAMES_FOR_EACH
 
index a444f15ffb8be679a06e2dd3e83a6cebac327e55..821f4d0fc50f1935bd2d39ac24c4bf8e21632624 100644 (file)
@@ -57,9 +57,9 @@ ScalarInput2::~ScalarInput2()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::ScalarInput1>::type()
+const String& InputTraits<Test::ScalarInput1>::type()
 {
-    static NeverDestroyed<const AtomicString> type("ScalarInput1", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("ScalarInput1"));
     return type;
 }
 
@@ -78,9 +78,9 @@ bool InputTraits<Test::ScalarInput1>::decode(EncodedValue& encodedValue, std::un
     return true;
 }
 
-const AtomicString& InputTraits<Test::ScalarInput2>::type()
+const String& InputTraits<Test::ScalarInput2>::type()
 {
-    static NeverDestroyed<const AtomicString> type("ScalarInput2", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("ScalarInput2"));
     return type;
 }
 
index 6566127ea32e07e52c00ab3e240717679a6e8a8f..7b98bfc5ff5fc3f4a03c157fdc473057b72ba270 100644 (file)
@@ -42,17 +42,17 @@ class ScalarInput2;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::ScalarInput1> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::ScalarInput1> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::ScalarInput1&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::ScalarInput1>&);
 };
 
-template<> struct InputTraits<Test::ScalarInput2> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::ScalarInput2> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::ScalarInput2&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::ScalarInput2>&);
@@ -63,7 +63,7 @@ template<> struct InputTraits<Test::ScalarInput2> {
 namespace Test {
 class ScalarInput1 : public NondeterministicInput<ScalarInput1> {
 public:
-    ScalarInput1(ScalarType data);
+    TEST_EXPORT_MACRO ScalarInput1(ScalarType data);
     virtual ~ScalarInput1();
 
     ScalarType data() const { return m_data; }
@@ -73,7 +73,7 @@ private:
 
 class ScalarInput2 : public NondeterministicInput<ScalarInput2> {
 public:
-    ScalarInput2(ScalarType data);
+    TEST_EXPORT_MACRO ScalarInput2(ScalarType data);
     virtual ~ScalarInput2();
 
     ScalarType data() const { return m_data; }
@@ -82,6 +82,14 @@ private:
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::ScalarInput1)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::ScalarInput1>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::ScalarInput2)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::ScalarInput2>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(ScalarInput1) \
     macro(ScalarInput2) \
index 025cf064affa2ab158292527f394bd65cb3da713..0be9206d8a0c7561dcb3b5c46e7f7a175f564e07 100644 (file)
@@ -57,9 +57,9 @@ MapInput::~MapInput()
 } // namespace Test
 
 namespace JSC {
-const AtomicString& InputTraits<Test::ScalarInput>::type()
+const String& InputTraits<Test::ScalarInput>::type()
 {
-    static NeverDestroyed<const AtomicString> type("ScalarInput", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("ScalarInput"));
     return type;
 }
 
@@ -78,9 +78,9 @@ bool InputTraits<Test::ScalarInput>::decode(EncodedValue& encodedValue, std::uni
     return true;
 }
 
-const AtomicString& InputTraits<Test::MapInput>::type()
+const String& InputTraits<Test::MapInput>::type()
 {
-    static NeverDestroyed<const AtomicString> type("MapInput", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const String> type(ASCIILiteral("MapInput"));
     return type;
 }
 
index e48b0c4d8be605a4ef2a803b1f6512492b3ddb4f..d77bcff32bf994d648ee5f38a83e450543aebb42 100644 (file)
@@ -42,17 +42,17 @@ class MapInput;
 } // namespace Test
 
 namespace JSC {
-template<> struct InputTraits<Test::ScalarInput> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::ScalarInput> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::ScalarInput&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::ScalarInput>&);
 };
 
-template<> struct InputTraits<Test::MapInput> {
+template<> struct TEST_EXPORT_MACRO InputTraits<Test::MapInput> {
     static InputQueue queue() { return InputQueue::ScriptMemoizedData; }
-    static const AtomicString& type();
+    static const String& type();
 
     static void encode(JSC::EncodedValue&, const Test::MapInput&);
     static bool decode(JSC::EncodedValue&, std::unique_ptr<Test::MapInput>&);
@@ -63,7 +63,7 @@ template<> struct InputTraits<Test::MapInput> {
 namespace Test {
 class ScalarInput : public NondeterministicInput<ScalarInput> {
 public:
-    ScalarInput(ScalarType data);
+    TEST_EXPORT_MACRO ScalarInput(ScalarType data);
     virtual ~ScalarInput();
 
     ScalarType data() const { return m_data; }
@@ -73,7 +73,7 @@ private:
 
 class MapInput : public NondeterministicInput<MapInput> {
 public:
-    MapInput(std::unique_ptr<MapType> data);
+    TEST_EXPORT_MACRO MapInput(std::unique_ptr<MapType> data);
     virtual ~MapInput();
 
     const MapType& data() const { return *m_data; }
@@ -82,6 +82,14 @@ private:
 };
 } // namespace Test
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::ScalarInput)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::ScalarInput>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(Test::MapInput)
+    static bool isType(const NondeterministicInputBase& input) { return input.type() == InputTraits<Test::MapInput>::type(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #define TEST_REPLAY_INPUT_NAMES_FOR_EACH(macro) \
     macro(ScalarInput) \
     macro(MapInput) \
index 03b68e4d731dd932f6749b72e29913a411d889f5..31d2c437a583355ac81a0ca7ddbbc42a0de137b2 100644 (file)
@@ -1,6 +1,6 @@
 {
     "types": {
-        "WebCore": [
+        "Test": [
             {
                 "name": "MouseButton", "mode": "SCALAR",
                 "flags": ["ENUM"],
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SavedMouseButton",
-            "description": "Supplies a mouse button enum value.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "button", "type": "MouseButton" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SavedMouseButton",
+                "description": "Supplies a mouse button enum value.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "button", "type": "MouseButton" }
+                ]
+            }
+        ]
+    }
 }
index 6ebb61cb40033c1e7a0de908e1d318f223e07c0e..089e69925c81fdeea5760703073cd857f623028b 100644 (file)
         ]
     },
 
-    "inputs": [
-        {
-            "name": "FormCombo",
-            "description": "Combines an event type and form data type.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "eventType", "type": "PlatformEvent::Type" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "FormCombo",
+                "description": "Combines an event type and form data type.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "eventType", "type": "PlatformEvent::Type" }
+                ]
+            }
+        ]
+    }
 }
index 0ce634acfe9a9e2737fe7d790408d0741671a2f2..91c84a2ef2862a84725ff514be24ac532454d3ed 100644 (file)
@@ -6,22 +6,24 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "currentTime", "type": "double" }
-            ]
-        },
-        {
-            "name": "GetCurrentTime",
-            "description": "Sets the PRNG seed used by Math.random().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "randomSeed", "type": "uint64_t" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "currentTime", "type": "double" }
+                ]
+            },
+            {
+                "name": "GetCurrentTime",
+                "description": "Sets the PRNG seed used by Math.random().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "randomSeed", "type": "uint64_t" }
+                ]
+            }
+        ]
+    }
 }
index cca473e5ed98c9844e54cc0684eac24c020b340d..fc4b5d9b9809c306edb73072cd0ca657b35b54a0 100644 (file)
@@ -6,17 +6,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SetRandomSeed",
-            "description": "Sets the PRNG seed used by Math.random().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "randomSeed",
-                    "type": "uint64_t"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SetRandomSeed",
+                "description": "Sets the PRNG seed used by Math.random().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "randomSeed",
+                        "type": "uint64_t"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 21b5d1deb800d7dd5abb0816078b3000aa3be125..5bd20bd517fce7b09b6a85b6d3e09da6731494fa 100644 (file)
@@ -8,14 +8,16 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SavedMouseButton",
-            "description": "Supplies a mouse button enum value.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "currentTime", "type": "MouseButton" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SavedMouseButton",
+                "description": "Supplies a mouse button enum value.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "currentTime", "type": "MouseButton" }
+                ]
+            }
+        ]
+    }
 }
index ec16e0676f7e771656a4017a0e4adfa44585fcc5..b924aafe739795a125d9c55456650601950ba460 100644 (file)
@@ -5,16 +5,18 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index feed8b82f9c24f333ad8f5c7b635e7d490363cf6..aa80980d80d8d0a8b072dac7686cab5cfd1f21ce 100644 (file)
@@ -5,16 +5,18 @@
         ]
     },
 
-    "inputs": [
-        {
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 56422c330bdf7004829fb9827f4048b55819a405..8136dfbb39068a3713bdb43f79dcbcb28e737a7b 100644 (file)
@@ -5,16 +5,18 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index a5d37b713aa7f90b2732fb2564ec9353686a8337..3ed6d1e4548b4ecf3f922dfd93790f1ca8f2d88c 100644 (file)
@@ -5,17 +5,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 017495eef395db2ea695125f1caede620b73b7f1..01b1c08728e429c3c7278fb0cedba34aad608821 100644 (file)
@@ -5,17 +5,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
diff --git a/replay/scripts/tests/fail-on-no-inputs.json b/replay/scripts/tests/fail-on-no-inputs.json
deleted file mode 100644 (file)
index 91f31fd..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "types": {
-        "Global": [
-            { "name": "double", "mode": "SCALAR" }
-        ]
-    }
-}
diff --git a/replay/scripts/tests/fail-on-no-types.json b/replay/scripts/tests/fail-on-no-types.json
deleted file mode 100644 (file)
index e260c55..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
- }
index 6f40f8171ed61fd358158bbec8eb3de2029ca751..cd15f0640134567be6153f404e64ecd31119485c 100644 (file)
@@ -5,17 +5,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEOIZED",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 5a00d12bed3848e71082f4c4d3acf2b55537690f..8a2305757157c587cb82481df2b7c482228fc5be 100644 (file)
@@ -5,17 +5,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SetRandomSeed",
-            "description": "Sets the PRNG seed used by Math.random().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "randomSeed",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SetRandomSeed",
+                "description": "Sets the PRNG seed used by Math.random().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "randomSeed",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 03655cbf170ebf64a0317d92fc5a8e51336c4f4f..b553befc91738324d2c028779a4c27ce4f0bc13d 100644 (file)
@@ -5,17 +5,19 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {
-                    "name": "currentTime",
-                    "type": "double"
-                }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {
+                        "name": "currentTime",
+                        "type": "double"
+                    }
+                ]
+            }
+        ]
+    }
 }
index 40e4943a78763285c002f683ce8941961510a984..9b2017d5855def36c01d6273e70790c728fbdc11 100644 (file)
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SavedMouseButton",
-            "description": "Supplies a mouse button enum value.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "button", "type": "MouseButton" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SavedMouseButton",
+                "description": "Supplies a mouse button enum value.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "button", "type": "MouseButton" }
+                ]
+            }
+        ]
+    }
 }
index 65d71a317f8fd3d4115fa46df2236bed8616efc8..ef2e1634654a51012c781f37740cd4f2904db4bf 100644 (file)
@@ -1,31 +1,38 @@
 {
     "types": {
-        "JavaScriptCore": [
+        "Test": [
             {
                 "name": "InputQueue", "mode": "SCALAR",
                 "flags": ["ENUM_CLASS"],
                 "values": ["EventLoopInput", "LoaderMemoizedData", "ScriptMemoizedData"],
                 "header": "replay/NondeterministicInput.h"
-            }
-        ],
-        "WebCore": [
+            },
             {
                 "name": "MouseButton", "mode": "SCALAR", "storage": "unsigned",
                 "flags": ["ENUM"],
                 "values": ["NoButton", "LeftButton", "MiddleButton", "RightButton"],
                 "header": "platform/PlatformMouseEvent.h"
+            },
+            {
+                "name": "Type", "mode": "SCALAR",
+                "flags": ["ENUM"],
+                "enclosing_class": "PlatformEvent",
+                "values": ["Mouse", "Key", "Touch", "Wheel"],
+                "header": "platform/PlatformEvent.h"
             }
         ]
     },
 
-    "inputs": [
-        {
-            "name": "SavedMouseButton",
-            "description": "Supplies a mouse button enum value.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "button", "type": "MouseButton" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "SavedMouseButton",
+                "description": "Supplies a mouse button enum value.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "button", "type": "MouseButton" }
+                ]
+            }
+        ]
+    }
 }
index 680e320dd6617237f0118ea6189420b07bf33746..20ea35922e506b53a5a6b836a2f750b9d2e84f4e 100644 (file)
@@ -7,9 +7,11 @@
             {
                 "name": "PlatformWheelEvent", "mode": "OWNED",
                 "header": "platform/PlatformWheelEvent.h"
-            },
+            }
+        ],
+        "Test": [
             {
-                "name": "PlatformWheelEventPhase", "mode": "SCALAR", "storage": "uint64_t",
+                "name": "PlatformWheelPhase", "mode": "SCALAR", "storage": "uint64_t",
                 "flags": ["ENUM"],
                 "guard": "ENABLE(DUMMY_FEATURE)",
                 "values": ["PlatformWheelEventPhaseNone"],
         ]
     },
 
-    "inputs": [
-        {
-            "name": "HandleWheelEvent",
-            "description": "",
-            "queue": "EVENT_LOOP",
-            "members": [
-                { "name": "platformEvent", "type": "PlatformWheelEvent" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "HandleWheelEvent",
+                "description": "",
+                "queue": "EVENT_LOOP",
+                "members": [
+                    { "name": "platformEvent", "type": "PlatformWheelEvent" },
+                    { "name": "phase", "type": "PlatformWheelPhase" }
+                ]
+            }
+        ]
+    }
 }
index 2ed29127c1b4b9c8c20c44c563001a7d19a14286..699439d8aa86d2739a1d5db03b1b5768c6192236 100644 (file)
@@ -3,32 +3,50 @@
         "JavaScriptCore": [
             {
                 "name": "Type", "mode": "SCALAR", "storage": "uint64_t",
-                "enclosing_class": "PlatformEvent",
+                "enclosing_class": "PlatformEvent1",
                 "flags": ["ENUM"],
                 "values": ["Mouse", "Keyboard"],
                 "header": "replay/PlatformEvent.h"
+            },
+            {
+                "name": "Type", "mode": "SCALAR",
+                "enclosing_class": "PlatformEvent2",
+                "flags": ["ENUM_CLASS"],
+                "values": ["Mouse", "Keyboard"],
+                "header": "replay/PlatformEvent.h"
             }
         ],
-        "WebCore": [
+        "Test": [
             {
                 "name": "Type", "mode": "SCALAR", "storage": "uint64_t",
-                "enclosing_class": "FormData",
+                "enclosing_class": "FormData1",
                 "flags": ["ENUM"],
                 "values": ["Text", "Blob"],
-                "header": "replay/FormData.h"
+                "header": "replay/FormData1.h"
+            },
+            {
+                "name": "Type", "mode": "SCALAR",
+                "enclosing_class": "FormData2",
+                "flags": ["ENUM_CLASS"],
+                "values": ["Text", "Blob"],
+                "header": "replay/FormData2.h"
             }
         ]
     },
 
-    "inputs": [
-        {
-            "name": "FormCombo",
-            "description": "Combines an event type and form data type.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "eventType", "type": "PlatformEvent::Type" },
-                { "name": "formType", "type": "FormData::Type" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "FormCombo",
+                "description": "Combines an event type and form data type.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "eventType1", "type": "PlatformEvent1::Type" },
+                    { "name": "eventType2", "type": "PlatformEvent2::Type" },
+                    { "name": "formType1", "type": "FormData1::Type" },
+                    { "name": "formType2", "type": "FormData2::Type" }
+                ]
+            }
+        ]
+    }
 }
index 5f6a24e8b3c23c816767395a646700338d374ef7..93b16bfa5abc42ebc98ebaad71cecf0b01eb574e 100644 (file)
@@ -7,30 +7,32 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "ScalarInput",
-            "description": "",
-            "queue": "EVENT_LOOP",
-            "members": [
-                { "name": "data", "type": "ScalarType" }
-            ]
-        },
-        {
-            "name": "MapInput",
-            "description": "",
-            "queue": "EVENT_LOOP",
-            "members": [
-                { "name": "data", "type": "MapType" }
-            ]
-        },
-        {
-            "name": "SharedMapInput",
-            "description": "",
-            "queue": "EVENT_LOOP",
-            "members": [
-                { "name": "data", "type": "SharedMapType" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "ScalarInput",
+                "description": "",
+                "queue": "EVENT_LOOP",
+                "members": [
+                    { "name": "data", "type": "ScalarType" }
+                ]
+            },
+            {
+                "name": "MapInput",
+                "description": "",
+                "queue": "EVENT_LOOP",
+                "members": [
+                    { "name": "data", "type": "MapType" }
+                ]
+            },
+            {
+                "name": "SharedMapInput",
+                "description": "",
+                "queue": "EVENT_LOOP",
+                "members": [
+                    { "name": "data", "type": "SharedMapType" }
+                ]
+            }
+        ]
+    }
 }
index 67846d77eb75858ab3808ba2cca83d1896c315a9..75cd5047323d4eb81298045cea5b0ab44aa927d5 100644 (file)
@@ -6,23 +6,25 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "GetCurrentTime",
-            "description": "Supplies the system time to Date.now() and new Date().",
-            "queue": "SCRIPT_MEMOIZED",
-            "guard": "ENABLE(DUMMY_FEATURE)",
-            "members": [
-                { "name": "currentTime", "type": "double" }
-            ]
-        },
-        {
-            "name": "SetRandomSeed",
-            "description": "Sets the PRNG seed used by Math.random().",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                {"name": "randomSeed", "type": "uint64_t" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "GetCurrentTime",
+                "description": "Supplies the system time to Date.now() and new Date().",
+                "queue": "SCRIPT_MEMOIZED",
+                "guard": "ENABLE(DUMMY_FEATURE)",
+                "members": [
+                    { "name": "currentTime", "type": "double" }
+                ]
+            },
+            {
+                "name": "SetRandomSeed",
+                "description": "Sets the PRNG seed used by Math.random().",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    {"name": "randomSeed", "type": "uint64_t" }
+                ]
+            }
+        ]
+    }
 }
index eb3487c9e3b00c51c56f069093180857c5ab654a..eabd072e1446d7b9c23774c686f827e459775816 100644 (file)
@@ -9,20 +9,34 @@
         ],
 
         "WebCore": [
-            { "name": "WebThing", "mode": "SCALAR", "header": "things/WebThing.h"  }
+            { "name": "WebThing", "mode": "SCALAR", "header": "things/WebThing.h" },
+            {
+                "name": "HistoryItem", "mode": "SHARED",
+                "header": "history/HistoryItem.h"
+            }
         ]
     },
 
-    "inputs": [
-        {
-            "name": "ArrayOfThings",
-            "description": "Supplies arrays of things.",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "doubles", "type": "double", "flags": ["VECTOR"] },
-                { "name": "jsthings", "type": "JSThing", "flags": ["VECTOR"] },
-                { "name": "webthings", "type": "WebThing", "flags": ["VECTOR"] }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "ArrayOfThings",
+                "description": "Supplies arrays of things.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "doubles", "type": "double", "flags": ["VECTOR"] },
+                    { "name": "jsthings", "type": "JSThing", "flags": ["VECTOR"] },
+                    { "name": "webthings", "type": "WebThing", "flags": ["VECTOR"] }
+                ]
+            },
+            {
+                "name": "SavedHistory",
+                "description": "Save history items.",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "entries", "type": "HistoryItem", "flags": ["VECTOR"] }
+                ]
+            }
+        ]
+    }
 }
index f5069e6d45a4e5eec52e36fe55186caae3ac1099..3f49cc19e5b30ddc995e5ba4d0ce7a1fb26a872c 100644 (file)
@@ -5,23 +5,25 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "ScalarInput1",
-            "description": "",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "data", "type": "ScalarType" }
-            ]
-        },
-        {
-            "name": "ScalarInput2",
-            "description": "",
-            "queue": "SCRIPT_MEMOIZED",
-            "flags": ["CREATE_FROM_PAGE"],
-            "members": [
-                { "name": "data", "type": "ScalarType" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "ScalarInput1",
+                "description": "",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "data", "type": "ScalarType" }
+                ]
+            },
+            {
+                "name": "ScalarInput2",
+                "description": "",
+                "queue": "SCRIPT_MEMOIZED",
+                "flags": ["CREATE_FROM_PAGE"],
+                "members": [
+                    { "name": "data", "type": "ScalarType" }
+                ]
+            }
+        ]
+    }
 }
index 80e50d63cdc1f7ce670edf9c70b36d33d0e09fb1..0d66bd853fb450ff17611745d055d327c6dc4770 100644 (file)
@@ -6,22 +6,24 @@
         ]
     },
 
-    "inputs": [
-        {
-            "name": "ScalarInput",
-            "description": "",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "data", "type": "ScalarType" }
-            ]
-        },
-        {
-            "name": "MapInput",
-            "description": "",
-            "queue": "SCRIPT_MEMOIZED",
-            "members": [
-                { "name": "data", "type": "MapType" }
-            ]
-        }
-    ]
+    "inputs": {
+        "Test": [
+            {
+                "name": "ScalarInput",
+                "description": "",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "data", "type": "ScalarType" }
+                ]
+            },
+            {
+                "name": "MapInput",
+                "description": "",
+                "queue": "SCRIPT_MEMOIZED",
+                "members": [
+                    { "name": "data", "type": "MapType" }
+                ]
+            }
+        ]
+    }
 }
diff --git a/runtime/Arguments.cpp b/runtime/Arguments.cpp
deleted file mode 100644 (file)
index b232d99..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
- *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (C) 2007 Maks Orlovich
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "Arguments.h"
-
-#include "CopyVisitorInlines.h"
-#include "JSActivation.h"
-#include "JSArgumentsIterator.h"
-#include "JSFunction.h"
-#include "JSGlobalObject.h"
-#include "JSCInlines.h"
-
-using namespace std;
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(Arguments);
-
-const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
-
-void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    JSObject::visitChildren(thisObject, visitor);
-
-    if (thisObject->m_registerArray) {
-        visitor.copyLater(thisObject, ArgumentsRegisterArrayCopyToken, 
-            thisObject->m_registerArray.get(), thisObject->registerArraySizeInBytes());
-        visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments);
-    }
-    if (thisObject->m_slowArgumentData) {
-        visitor.copyLater(thisObject, ArgumentsSlowArgumentDataCopyToken,
-            thisObject->m_slowArgumentData.get(), SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments));
-    }
-    visitor.append(&thisObject->m_callee);
-    visitor.append(&thisObject->m_activation);
-}
-
-void Arguments::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    
-
-    switch (token) {
-    case ArgumentsRegisterArrayCopyToken: {
-        WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get();
-        if (!registerArray)
-            return;
-
-        if (visitor.checkIfShouldCopy(registerArray)) {
-            size_t bytes = thisObject->registerArraySizeInBytes();
-            WriteBarrier<Unknown>* newRegisterArray = static_cast<WriteBarrier<Unknown>*>(visitor.allocateNewSpace(bytes));
-            memcpy(newRegisterArray, registerArray, bytes);
-            thisObject->m_registerArray.setWithoutWriteBarrier(newRegisterArray);
-            thisObject->m_registers = newRegisterArray - CallFrame::offsetFor(1) - 1;
-            visitor.didCopy(registerArray, bytes);
-        }
-        return;
-    }
-
-    case ArgumentsSlowArgumentDataCopyToken: {
-        SlowArgumentData* slowArgumentData = thisObject->m_slowArgumentData.get();
-        if (!slowArgumentData)
-            return;
-
-        if (visitor.checkIfShouldCopy(slowArgumentData)) {
-            size_t bytes = SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments);
-            SlowArgumentData* newSlowArgumentData = static_cast<SlowArgumentData*>(visitor.allocateNewSpace(bytes));
-            memcpy(newSlowArgumentData, slowArgumentData, bytes);
-            thisObject->m_slowArgumentData.setWithoutWriteBarrier(newSlowArgumentData);
-            visitor.didCopy(slowArgumentData, bytes);
-        }
-        return;
-    }
-
-    default:
-        return;
-    }
-}
-    
-static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
-
-void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
-{
-    uint32_t length = copyLength + firstVarArgOffset;
-
-    if (UNLIKELY(m_overrodeLength)) {
-        length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
-        for (unsigned i = firstVarArgOffset; i < length; i++)
-            callFrame->setArgument(i, get(exec, i));
-        return;
-    }
-    ASSERT(length == this->length(exec));
-    for (size_t i = firstVarArgOffset; i < length; ++i) {
-        if (JSValue value = tryGetArgument(i))
-            callFrame->setArgument(i - firstVarArgOffset, value);
-        else
-            callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
-    }
-}
-
-void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
-{
-    if (UNLIKELY(m_overrodeLength)) {
-        unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); 
-        for (unsigned i = 0; i < length; i++) 
-            args.append(get(exec, i)); 
-        return;
-    }
-    uint32_t length = this->length(exec);
-    for (size_t i = 0; i < length; ++i) {
-        if (JSValue value = tryGetArgument(i))
-            args.append(value);
-        else
-            args.append(get(exec, i));
-    }
-}
-
-bool Arguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned i, PropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    if (JSValue value = thisObject->tryGetArgument(i)) {
-        slot.setValue(thisObject, None, value);
-        return true;
-    }
-
-    return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot);
-}
-    
-void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
-{
-    if (m_overrodeCaller)
-        return;
-
-    VM& vm = exec->vm();
-    m_overrodeCaller = true;
-    PropertyDescriptor descriptor;
-    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
-    methodTable(exec->vm())->defineOwnProperty(this, exec, vm.propertyNames->caller, descriptor, false);
-}
-
-void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
-{
-    if (m_overrodeCallee)
-        return;
-
-    VM& vm = exec->vm();
-    m_overrodeCallee = true;
-    PropertyDescriptor descriptor;
-    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
-    methodTable(exec->vm())->defineOwnProperty(this, exec, vm.propertyNames->callee, descriptor, false);
-}
-
-bool Arguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    unsigned i = propertyName.asIndex();
-    if (JSValue value = thisObject->tryGetArgument(i)) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        slot.setValue(thisObject, None, value);
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
-        slot.setValue(thisObject, DontEnum, jsNumber(thisObject->m_numArguments));
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
-        if (!thisObject->m_isStrictMode) {
-            slot.setValue(thisObject, DontEnum, thisObject->m_callee.get());
-            return true;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-        return true;
-    if (propertyName == exec->propertyNames().iteratorPrivateName) {
-        VM& vm = exec->vm();
-        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-        thisObject->JSC_NATIVE_FUNCTION(exec->propertyNames().iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
-        if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            return true;
-    }
-    return false;
-}
-
-void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    for (unsigned i = 0; i < thisObject->m_numArguments; ++i) {
-        if (!thisObject->isArgument(i))
-            continue;
-        propertyNames.add(Identifier::from(exec, i));
-    }
-    if (mode == IncludeDontEnumProperties) {
-        propertyNames.add(exec->propertyNames().callee);
-        propertyNames.add(exec->propertyNames().length);
-    }
-    JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
-}
-
-void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    if (thisObject->trySetArgument(exec->vm(), i, value))
-        return;
-
-    PutPropertySlot slot(thisObject, shouldThrow);
-    JSObject::put(thisObject, exec, Identifier::from(exec, i), value, slot);
-}
-
-void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    unsigned i = propertyName.asIndex();
-    if (thisObject->trySetArgument(exec->vm(), i, value))
-        return;
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->m_overrodeLength = true;
-        thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
-        return;
-    }
-
-    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        if (!thisObject->m_isStrictMode) {
-            thisObject->m_overrodeCallee = true;
-            thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
-            return;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    JSObject::put(thisObject, exec, propertyName, value, slot);
-}
-
-bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) 
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    if (i < thisObject->m_numArguments) {
-        if (!Base::deletePropertyByIndex(cell, exec, i))
-            return false;
-        if (thisObject->tryDeleteArgument(exec->vm(), i))
-            return true;
-    }
-    return JSObject::deletePropertyByIndex(thisObject, exec, i);
-}
-
-bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) 
-{
-    if (exec->vm().isInDefineOwnProperty())
-        return Base::deleteProperty(cell, exec, propertyName);
-
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    unsigned i = propertyName.asIndex();
-    if (i < thisObject->m_numArguments) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        if (!Base::deleteProperty(cell, exec, propertyName))
-            return false;
-        if (thisObject->tryDeleteArgument(exec->vm(), i))
-            return true;
-    }
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->m_overrodeLength = true;
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        if (!thisObject->m_isStrictMode) {
-            thisObject->m_overrodeCallee = true;
-            return true;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-    
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    return JSObject::deleteProperty(thisObject, exec, propertyName);
-}
-
-bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    unsigned i = propertyName.asIndex();
-    if (i < thisObject->m_numArguments) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        // If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
-        PropertySlot slot(thisObject);
-        if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
-            JSValue value = thisObject->tryGetArgument(i);
-            ASSERT(value);
-            object->putDirectMayBeIndex(exec, propertyName, value);
-        }
-        if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
-            return false;
-
-        // From ES 5.1, 10.6 Arguments Object
-        // 5. If the value of isMapped is not undefined, then
-        if (thisObject->isArgument(i)) {
-            // a. If IsAccessorDescriptor(Desc) is true, then
-            if (descriptor.isAccessorDescriptor()) {
-                // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
-                thisObject->tryDeleteArgument(exec->vm(), i);
-            } else { // b. Else
-                // i. If Desc.[[Value]] is present, then
-                // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
-                if (descriptor.value())
-                    thisObject->trySetArgument(exec->vm(), i, descriptor.value());
-                // ii. If Desc.[[Writable]] is present and its value is false, then
-                // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
-                if (descriptor.writablePresent() && !descriptor.writable())
-                    thisObject->tryDeleteArgument(exec->vm(), i);
-            }
-        }
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->putDirect(exec->vm(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum);
-        thisObject->m_overrodeLength = true;
-    } else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        thisObject->putDirect(exec->vm(), propertyName, thisObject->m_callee.get(), DontEnum);
-        thisObject->m_overrodeCallee = true;
-    } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
-}
-
-void Arguments::allocateRegisterArray(VM& vm)
-{
-    ASSERT(!m_registerArray);
-    void* backingStore;
-    if (!vm.heap.tryAllocateStorage(this, registerArraySizeInBytes(), &backingStore))
-        RELEASE_ASSERT_NOT_REACHED();
-    m_registerArray.set(vm, this, static_cast<WriteBarrier<Unknown>*>(backingStore));
-}
-
-void Arguments::tearOff(CallFrame* callFrame)
-{
-    if (isTornOff())
-        return;
-
-    if (!m_numArguments)
-        return;
-
-    // Must be called for the same call frame from which it was created.
-    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
-    
-    allocateRegisterArray(callFrame->vm());
-    m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;
-
-    // If we have a captured argument that logically aliases activation storage,
-    // but we optimize away the activation, the argument needs to tear off into
-    // our storage. The simplest way to do this is to revert it to Normal status.
-    if (m_slowArgumentData && !m_activation) {
-        for (size_t i = 0; i < m_numArguments; ++i) {
-            if (m_slowArgumentData->slowArguments()[i].status != SlowArgument::Captured)
-                continue;
-            m_slowArgumentData->slowArguments()[i].status = SlowArgument::Normal;
-            m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i);
-        }
-    }
-
-    for (size_t i = 0; i < m_numArguments; ++i)
-        trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
-}
-
-void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
-{
-    RELEASE_ASSERT(activation);
-    if (isTornOff())
-        return;
-
-    if (!m_numArguments)
-        return;
-    
-    m_activation.set(exec->vm(), this, activation);
-    tearOff(exec);
-}
-
-void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-{
-    if (isTornOff())
-        return;
-    
-    if (!m_numArguments)
-        return;
-    
-    allocateRegisterArray(callFrame->vm());
-    m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;
-
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
-        trySetArgument(callFrame->vm(), i, recovery.recover(callFrame));
-    }
-}
-    
-EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec)
-{
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    Arguments* arguments = jsDynamicCast<Arguments*>(thisObj);
-    if (!arguments)
-        return JSValue::encode(throwTypeError(exec, "Attempted to use Arguments iterator on non-Arguments object"));
-    return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), arguments));
-}
-
-
-} // namespace JSC
diff --git a/runtime/Arguments.h b/runtime/Arguments.h
deleted file mode 100644 (file)
index 6970cb8..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (C) 2007 Maks Orlovich
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Arguments_h
-#define Arguments_h
-
-#include "CodeOrigin.h"
-#include "JSActivation.h"
-#include "JSFunction.h"
-#include "JSGlobalObject.h"
-#include "Interpreter.h"
-#include "ObjectConstructor.h"
-#include "WriteBarrierInlines.h"
-#include <wtf/StdLibExtras.h>
-
-namespace JSC {
-
-class Arguments : public JSNonFinalObject {
-    friend class JIT;
-    friend class JSArgumentsIterator;
-public:
-    typedef JSNonFinalObject Base;
-
-    static Arguments* create(VM& vm, CallFrame* callFrame)
-    {
-        Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap)) Arguments(callFrame);
-        arguments->finishCreation(callFrame);
-        return arguments;
-    }
-        
-    static Arguments* create(VM& vm, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-    {
-        Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap)) Arguments(callFrame);
-        arguments->finishCreation(callFrame, inlineCallFrame);
-        return arguments;
-    }
-
-    enum { MaxArguments = 0x10000 };
-
-private:
-    enum NoParametersType { NoParameters };
-        
-    Arguments(CallFrame*);
-    Arguments(CallFrame*, NoParametersType);
-        
-public:
-    DECLARE_INFO;
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
-
-    void fillArgList(ExecState*, MarkedArgumentBuffer&);
-
-    uint32_t length(ExecState* exec) const 
-    {
-        if (UNLIKELY(m_overrodeLength))
-            return get(exec, exec->propertyNames().length).toUInt32(exec);
-        return m_numArguments; 
-    }
-        
-    void copyToArguments(ExecState*, CallFrame*, uint32_t copyLength, int32_t firstArgumentOffset);
-    void tearOff(CallFrame*);
-    void tearOff(CallFrame*, InlineCallFrame*);
-    bool isTornOff() const { return m_registerArray.get(); }
-    void didTearOffActivation(ExecState*, JSActivation*);
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-    { 
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ArgumentsType, StructureFlags), info()); 
-    }
-    
-    static ptrdiff_t offsetOfActivation() { return OBJECT_OFFSETOF(Arguments, m_activation); }
-    static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); }
-    static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
-    static ptrdiff_t offsetOfIsStrictMode() { return OBJECT_OFFSETOF(Arguments, m_isStrictMode); }
-    static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); }
-    static ptrdiff_t offsetOfRegisterArray() { return OBJECT_OFFSETOF(Arguments, m_registerArray); }
-    static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); }
-    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(Arguments, m_callee); }
-
-    static size_t allocationSize(size_t inlineCapacity)
-    {
-        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
-        return sizeof(Arguments);
-    }
-    
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
-
-    void finishCreation(CallFrame*);
-    void finishCreation(CallFrame*, InlineCallFrame*);
-
-private:
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
-    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
-    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
-    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-    void createStrictModeCallerIfNecessary(ExecState*);
-    void createStrictModeCalleeIfNecessary(ExecState*);
-
-    size_t registerArraySizeInBytes() const { return sizeof(WriteBarrier<Unknown>) * m_numArguments; }
-    void allocateRegisterArray(VM&);
-    bool isArgument(size_t);
-    bool trySetArgument(VM&, size_t argument, JSValue);
-    JSValue tryGetArgument(size_t argument);
-    bool isDeletedArgument(size_t);
-    bool tryDeleteArgument(VM&, size_t);
-    WriteBarrierBase<Unknown>& argument(size_t);
-    void allocateSlowArguments(VM&);
-
-    void init(CallFrame*);
-
-    WriteBarrier<JSActivation> m_activation;
-
-    unsigned m_numArguments;
-
-    // We make these full byte booleans to make them easy to test from the JIT,
-    // and because even if they were single-bit booleans we still wouldn't save
-    // any space.
-    bool m_overrodeLength; 
-    bool m_overrodeCallee;
-    bool m_overrodeCaller;
-    bool m_isStrictMode;
-
-    WriteBarrierBase<Unknown>* m_registers;
-    CopyWriteBarrier<WriteBarrier<Unknown>> m_registerArray;
-
-public:
-    struct SlowArgumentData {
-    public:
-        SlowArgumentData()
-            : m_bytecodeToMachineCaptureOffset(0)
-        {
-        }
-
-        SlowArgument* slowArguments()
-        {
-            return reinterpret_cast<SlowArgument*>(WTF::roundUpToMultipleOf<8>(reinterpret_cast<size_t>(this + 1)));
-        }
-
-        int bytecodeToMachineCaptureOffset() const { return m_bytecodeToMachineCaptureOffset; }
-        void setBytecodeToMachineCaptureOffset(int newOffset) { m_bytecodeToMachineCaptureOffset = newOffset; }
-
-        static size_t sizeForNumArguments(unsigned numArguments)
-        {
-            return WTF::roundUpToMultipleOf<8>(sizeof(SlowArgumentData)) + sizeof(SlowArgument) * numArguments;
-        }
-
-    private:
-        int m_bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite. 
-    };
-    
-private:
-    CopyWriteBarrier<SlowArgumentData> m_slowArgumentData;
-
-    WriteBarrier<JSFunction> m_callee;
-};
-
-Arguments* asArguments(JSValue);
-
-inline Arguments* asArguments(JSValue value)
-{
-    ASSERT(asObject(value)->inherits(Arguments::info()));
-    return static_cast<Arguments*>(asObject(value));
-}
-
-inline Arguments::Arguments(CallFrame* callFrame)
-    : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
-    : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline void Arguments::allocateSlowArguments(VM& vm)
-{
-    if (!!m_slowArgumentData)
-        return;
-
-    void* backingStore;
-    if (!vm.heap.tryAllocateStorage(this, SlowArgumentData::sizeForNumArguments(m_numArguments), &backingStore))
-        RELEASE_ASSERT_NOT_REACHED();
-    m_slowArgumentData.set(vm, this, static_cast<SlowArgumentData*>(backingStore));
-
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        ASSERT(m_slowArgumentData->slowArguments()[i].status == SlowArgument::Normal);
-        m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i);
-    }
-}
-
-inline bool Arguments::tryDeleteArgument(VM& vm, size_t argument)
-{
-    if (!isArgument(argument))
-        return false;
-    allocateSlowArguments(vm);
-    m_slowArgumentData->slowArguments()[argument].status = SlowArgument::Deleted;
-    return true;
-}
-
-inline bool Arguments::trySetArgument(VM& vm, size_t argument, JSValue value)
-{
-    if (!isArgument(argument))
-        return false;
-    this->argument(argument).set(vm, this, value);
-    return true;
-}
-
-inline JSValue Arguments::tryGetArgument(size_t argument)
-{
-    if (!isArgument(argument))
-        return JSValue();
-    return this->argument(argument).get();
-}
-
-inline bool Arguments::isDeletedArgument(size_t argument)
-{
-    if (argument >= m_numArguments)
-        return false;
-    if (!m_slowArgumentData)
-        return false;
-    if (m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Deleted)
-        return false;
-    return true;
-}
-
-inline bool Arguments::isArgument(size_t argument)
-{
-    if (argument >= m_numArguments)
-        return false;
-    if (m_slowArgumentData && m_slowArgumentData->slowArguments()[argument].status == SlowArgument::Deleted)
-        return false;
-    return true;
-}
-
-inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
-{
-    ASSERT(isArgument(argument));
-    if (!m_slowArgumentData)
-        return m_registers[CallFrame::argumentOffset(argument)];
-
-    int index = m_slowArgumentData->slowArguments()[argument].index;
-    if (!m_activation || m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Captured)
-        return m_registers[index];
-
-    return m_activation->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame)
-{
-    Base::finishCreation(callFrame->vm());
-    ASSERT(inherits(info()));
-
-    JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
-    m_numArguments = callFrame->argumentCount();
-    m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
-    m_callee.set(callFrame->vm(), this, callee);
-    m_overrodeLength = false;
-    m_overrodeCallee = false;
-    m_overrodeCaller = false;
-    m_isStrictMode = callFrame->codeBlock()->isStrictMode();
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    if (codeBlock->hasSlowArguments()) {
-        SymbolTable* symbolTable = codeBlock->symbolTable();
-        const SlowArgument* slowArguments = codeBlock->machineSlowArguments();
-        allocateSlowArguments(callFrame->vm());
-        size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
-        for (size_t i = 0; i < count; ++i)
-            m_slowArgumentData->slowArguments()[i] = slowArguments[i];
-        m_slowArgumentData->setBytecodeToMachineCaptureOffset(
-            codeBlock->framePointerOffsetToGetActivationRegisters());
-    }
-
-    // The bytecode generator omits op_tear_off_activation in cases of no
-    // declared parameters, so we need to tear off immediately.
-    if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
-        tearOff(callFrame);
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-{
-    Base::finishCreation(callFrame->vm());
-    ASSERT(inherits(info()));
-
-    JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
-    m_numArguments = inlineCallFrame->arguments.size() - 1;
-    
-    if (m_numArguments) {
-        int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset();
-        m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset();
-    } else
-        m_registers = 0;
-    m_callee.set(callFrame->vm(), this, callee);
-    m_overrodeLength = false;
-    m_overrodeCallee = false;
-    m_overrodeCaller = false;
-    m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
-    ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments());
-
-    // The bytecode generator omits op_tear_off_activation in cases of no
-    // declared parameters, so we need to tear off immediately.
-    if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
-        tearOff(callFrame, inlineCallFrame);
-}
-
-} // namespace JSC
-
-#endif // Arguments_h
diff --git a/runtime/ArgumentsIteratorConstructor.cpp b/runtime/ArgumentsIteratorConstructor.cpp
deleted file mode 100644 (file)
index ae621c7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ArgumentsIteratorConstructor.h"
-
-#include "ArgumentsIteratorPrototype.h"
-#include "JSArgumentsIterator.h"
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSGlobalObject.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-const ClassInfo ArgumentsIteratorConstructor::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorConstructor) };
-
-void ArgumentsIteratorConstructor::finishCreation(VM& vm, ArgumentsIteratorPrototype* prototype)
-{
-    Base::finishCreation(vm);
-    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
-}
-
-}
diff --git a/runtime/ArgumentsIteratorConstructor.h b/runtime/ArgumentsIteratorConstructor.h
deleted file mode 100644 (file)
index 8360c59..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ArgumentsIteratorConstructor_h
-#define ArgumentsIteratorConstructor_h
-
-#include "InternalFunction.h"
-
-namespace JSC {
-
-class ArgumentsIteratorPrototype;
-
-class ArgumentsIteratorConstructor : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static ArgumentsIteratorConstructor* create(VM& vm, Structure* structure, ArgumentsIteratorPrototype* prototype)
-    {
-        ArgumentsIteratorConstructor* constructor = new (NotNull, allocateCell<ArgumentsIteratorConstructor>(vm.heap)) ArgumentsIteratorConstructor(vm, structure);
-        constructor->finishCreation(vm, prototype);
-        return constructor;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-private:
-    ArgumentsIteratorConstructor(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-    void finishCreation(VM&, ArgumentsIteratorPrototype*);
-};
-
-}
-
-#endif // !defined(ArgumentsIteratorConstructor_h)
diff --git a/runtime/ArgumentsIteratorPrototype.cpp b/runtime/ArgumentsIteratorPrototype.cpp
deleted file mode 100644 (file)
index 1514630..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ArgumentsIteratorPrototype.h"
-
-#include "JSArgumentsIterator.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo ArgumentsIteratorPrototype::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArgumentsIteratorPrototype) };
-
-static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(ExecState*);
-static EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(ExecState*);
-
-void ArgumentsIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
-{
-    Base::finishCreation(vm);
-    ASSERT(inherits(info()));
-    vm.prototypeMap.addPrototype(this);
-
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsIteratorPrototypeFuncIterator, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorNextPrivateName, argumentsIteratorPrototypeFuncNext, DontEnum, 0);
-}
-
-EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncIterator(CallFrame* callFrame)
-{
-    return JSValue::encode(callFrame->thisValue());
-}
-
-EncodedJSValue JSC_HOST_CALL argumentsIteratorPrototypeFuncNext(CallFrame* callFrame)
-{
-    JSValue result;
-    if (jsCast<JSArgumentsIterator*>(callFrame->thisValue())->next(callFrame, result))
-        return JSValue::encode(result);
-    return JSValue::encode(callFrame->vm().iterationTerminator.get());
-}
-
-}
diff --git a/runtime/ArgumentsIteratorPrototype.h b/runtime/ArgumentsIteratorPrototype.h
deleted file mode 100644 (file)
index 21839bf..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ArgumentsIteratorPrototype_h
-#define ArgumentsIteratorPrototype_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-class ArgumentsIteratorPrototype : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static ArgumentsIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-    {
-        ArgumentsIteratorPrototype* prototype = new (NotNull, allocateCell<ArgumentsIteratorPrototype>(vm.heap)) ArgumentsIteratorPrototype(vm, structure);
-        prototype->finishCreation(vm, globalObject);
-        return prototype;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-private:
-    ArgumentsIteratorPrototype(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-    void finishCreation(VM&, JSGlobalObject*);
-};
-
-}
-
-#endif // !defined(ArgumentsIteratorPrototype_h)
diff --git a/runtime/ArgumentsMode.h b/runtime/ArgumentsMode.h
new file mode 100644 (file)
index 0000000..67cd334
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ArgumentsMode_h
+#define ArgumentsMode_h
+
+namespace JSC {
+
+enum class ArgumentsMode {
+    Cloned,
+    FakeValues
+};
+
+} // namespace JSC
+
+#endif // ArgumentsMode_h
+
index 02fe94909dee53bd827921ab09429e64468b2926..f78a0c0f00520c388d15fe71264c9d7d2a02e218 100644 (file)
@@ -57,7 +57,7 @@ bool ArrayBuffer::transfer(ArrayBufferContents& result)
         if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(cell))
             view->neuter();
         else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast<ArrayBufferNeuteringWatchpoint*>(cell))
-            watchpoint->set()->fireAll();
+            watchpoint->fireAll();
     }
     return true;
 }
index 6fb7c7994a336a413a8123327b4ae2bbc68bff81..a15b50440fb9c7ddfbdc628017e7aa168b1d1372 100644 (file)
@@ -31,7 +31,7 @@
 namespace JSC {
 
 const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = {
-    "ArrayBufferNeuteringWatchpoint", 0, 0, 0,
+    "ArrayBufferNeuteringWatchpoint", 0, 0,
     CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint)
 };
 
@@ -57,7 +57,12 @@ ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM& vm)
 
 Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM& vm)
 {
-    return Structure::create(vm, 0, jsNull(), TypeInfo(CompoundType, StructureFlags), info());
+    return Structure::create(vm, 0, jsNull(), TypeInfo(CellType, StructureFlags), info());
+}
+
+void ArrayBufferNeuteringWatchpoint::fireAll()
+{
+    set()->fireAll("Array buffer was neutered");
 }
 
 } // namespace JSC
index 96dbd69c77063b8d7952badda6496a68732a779c..ab26f0332b5404b53dd774f32f7505bf413b4fcf 100644 (file)
 
 namespace JSC {
 
-class ArrayBufferNeuteringWatchpoint : public JSCell {
+class ArrayBufferNeuteringWatchpoint final : public JSCell {
 public:
     typedef JSCell Base;
-    
-private:
-    ArrayBufferNeuteringWatchpoint(VM&);
-    
-public:
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     DECLARE_INFO;
     
     static ArrayBufferNeuteringWatchpoint* create(VM&);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
     
     static Structure* createStructure(VM&);
     
     WatchpointSet* set() { return m_set.get(); }
+    
+    void fireAll();
 
 private:
+    explicit ArrayBufferNeuteringWatchpoint(VM&);
+    
     RefPtr<WatchpointSet> m_set;
 };
 
index ea7cd5a8f86c574ac3a716ee5741c87d7a09485e..3fc10b0dd7bb3415d3f701a50e7d6330a316d784 100644 (file)
@@ -77,22 +77,20 @@ public:
 
     JS_EXPORT_PRIVATE virtual ~ArrayBufferView();
 
+    // Helper to verify byte offset is size aligned.
+    static bool verifyByteOffsetAlignment(unsigned byteOffset, size_t size)
+    {
+        return !(byteOffset & (size - 1));
+    }
+
     // Helper to verify that a given sub-range of an ArrayBuffer is
     // within range.
-    // FIXME: This should distinguish between alignment errors and bounds errors.
-    // https://bugs.webkit.org/show_bug.cgi?id=125391
-    template <typename T>
-    static bool verifySubRange(
-        PassRefPtr<ArrayBuffer> buffer,
-        unsigned byteOffset,
-        unsigned numElements)
+    static bool verifySubRangeLength(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned numElements, size_t size)
     {
         unsigned byteLength = buffer->byteLength();
-        if (sizeof(T) > 1 && byteOffset % sizeof(T))
-            return false;
         if (byteOffset > byteLength)
             return false;
-        unsigned remainingElements = (byteLength - byteOffset) / sizeof(T);
+        unsigned remainingElements = (byteLength - byteOffset) / size;
         if (numElements > remainingElements)
             return false;
         return true;
index 4442930213a80f2582b39807a482e99039b29c46..194f9217c1c21860369ec0e4ee44d87c98800836 100644 (file)
@@ -46,11 +46,13 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ArrayConstructor);
 
-const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) };
+const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_info, &arrayConstructorTable, CREATE_METHOD_TABLE(ArrayConstructor) };
 
 /* Source for ArrayConstructor.lut.h
 @begin arrayConstructorTable
   isArray   arrayConstructorIsArray     DontEnum|Function 1
+  of        arrayConstructorOf          DontEnum|Function 0
+  from      arrayConstructorFrom        DontEnum|Function 0
 @end
 */
 
@@ -68,7 +70,7 @@ void ArrayConstructor::finishCreation(VM& vm, ArrayPrototype* arrayPrototype)
 
 bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<InternalFunction>(exec, ExecState::arrayConstructorTable(exec->vm()), jsCast<ArrayConstructor*>(object), propertyName, slot);
+    return getStaticFunctionSlot<InternalFunction>(exec, arrayConstructorTable, jsCast<ArrayConstructor*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions ---------------------------
index a6ac76ea4e49704ea29565865dd01e00b7c7e967..040f26c4c9905a457694c05c854470607bb484a7 100644 (file)
@@ -32,6 +32,7 @@ class JSArray;
 class ArrayConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
     static ArrayConstructor* create(VM& vm, Structure* structure, ArrayPrototype* arrayPrototype)
     {
@@ -49,7 +50,6 @@ public:
 
 protected:
     void finishCreation(VM&, ArrayPrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     ArrayConstructor(VM&, Structure*);
index e5ef963360bca1bde1232226a6edea3810ae5a81..9c62ea9b8e559b26fbf65c52eeb7eb1f56c0301f 100644 (file)
@@ -38,7 +38,7 @@ namespace JSC {
 // (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit
 // integer) are not considered array indices and will be stored in the JSObject property map.
 //
-// All properties with a numeric identifer, representable as an unsigned integer i,
+// All properties with a numeric identifier, representable as an unsigned integer i,
 // where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the
 // storage vector or the sparse map. An array index i will be handled in the following
 // fashion:
@@ -58,7 +58,14 @@ namespace JSC {
 
 // These values have to be macros to be used in max() and min() without introducing
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
+
+// If you grow an ArrayStorage array by more than this, then the array will go sparse. Note that we
+// could probably make this smaller (it's large because it used to be conflated with
+// MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH).
 #define MIN_SPARSE_ARRAY_INDEX 100000U
+// If you try to allocate a contiguous array larger than this, then we will allocate an ArrayStorage
+// array instead. We allow for an array that occupies 1GB of VM.
+#define MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH 1024 * 1024 * 1024 / 8
 #define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1)
 // 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
 #define MAX_ARRAY_INDEX 0xFFFFFFFEU
diff --git a/runtime/ArrayIteratorConstructor.cpp b/runtime/ArrayIteratorConstructor.cpp
deleted file mode 100644 (file)
index 3451db6..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ArrayIteratorConstructor.h"
-
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSGlobalObject.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-const ClassInfo ArrayIteratorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorConstructor) };
-
-void ArrayIteratorConstructor::finishCreation(VM& vm)
-{
-    Base::finishCreation(vm);
-}
-
-}
diff --git a/runtime/ArrayIteratorConstructor.h b/runtime/ArrayIteratorConstructor.h
deleted file mode 100644 (file)
index 489d5d9..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef ArrayIteratorConstructor_h
-#define ArrayIteratorConstructor_h
-
-#include "InternalFunction.h"
-
-namespace JSC {
-
-class ArrayIteratorPrototype;
-
-class ArrayIteratorConstructor : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static ArrayIteratorConstructor* create(VM& vm, Structure* structure, ArrayIteratorPrototype*)
-    {
-        ArrayIteratorConstructor* constructor = new (NotNull, allocateCell<ArrayIteratorConstructor>(vm.heap)) ArrayIteratorConstructor(vm, structure);
-        constructor->finishCreation(vm);
-        return constructor;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-private:
-    ArrayIteratorConstructor(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-    void finishCreation(VM&);
-};
-
-}
-
-#endif // !defined(ArrayIteratorConstructor_h)
index ecc57cbdf0f986232a8af18c1deabf74d65ac565..c330912597dc07746fc5d7c4eda57e96f7ac0520 100644 (file)
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "ArrayIteratorPrototype.h"
 
+namespace JSC {
+
+}
+
+#include "ArrayIteratorPrototype.lut.h"
+
+#include "IteratorOperations.h"
 #include "JSArrayIterator.h"
+#include "JSCInlines.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
 
 namespace JSC {
 
-const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) };
 
-static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*);
+const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, &arrayIteratorPrototypeTable, CREATE_METHOD_TABLE(ArrayIteratorPrototype) };
 
-void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+/* Source for ArrayIteratorPrototype.lut.h
+@begin arrayIteratorPrototypeTable
+  next      arrayIteratorProtoFuncNext  DontEnum|Function 0
+@end
+*/
+
+void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject*)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
-
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0);
 }
 
-EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(CallFrame* callFrame)
+bool ArrayIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return JSValue::encode(callFrame->thisValue());
+    return getStaticFunctionSlot<Base>(exec, arrayIteratorPrototypeTable, jsCast<ArrayIteratorPrototype*>(object), propertyName, slot);
 }
 
-}
+// ------------------------------ Array Functions ----------------------------
+
+} // namespace JSC
index 10ee9a6a2676d99d1937d38c8781295844fa0b5d..2b234f8ee1eead8a9fcccb0e131b489098cd953e 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class ArrayIteratorPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
     static ArrayIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -53,7 +54,9 @@ private:
         : Base(vm, structure)
     {
     }
+
     void finishCreation(VM&, JSGlobalObject*);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 };
 
 }
index d8e48bac1d7ba55bd0242b410773941c36abe344..87ceae1cbef55cf76be8581e17c2b39c75803ade 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
  *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
  *
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JSArrayIterator.h"
+#include "JSCBuiltins.h"
+#include "JSCInlines.h"
 #include "JSStringBuilder.h"
 #include "JSStringJoiner.h"
 #include "Lookup.h"
+#include "ObjectConstructor.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "StringRecursionChecker.h"
 #include <algorithm>
 #include <wtf/Assertions.h>
 
 namespace JSC {
 
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState*);
-
-}
-
-#include "ArrayPrototype.lut.h"
-
-namespace JSC {
-
-static inline bool isNumericCompareFunction(ExecState* exec, JSValue function, CallType callType, const CallData& callData)
-{
-    if (callType != CallTypeJS)
-        return false;
-
-    FunctionExecutable* executable = callData.js.functionExecutable;
-    JSScope* scope = callData.js.scope;
-
-    JSObject* error = executable->prepareForExecution(exec, jsCast<JSFunction*>(function), &scope, CodeForCall);
-    if (error)
-        return false;
-
-    return executable->codeBlockForCall()->isNumericCompareFunction();
-}
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncEntries(ExecState*);
 
 // ------------------------------ ArrayPrototype ----------------------------
 
-const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, 0, ExecState::arrayPrototypeTable, CREATE_METHOD_TABLE(ArrayPrototype)};
-
-/* Source for ArrayPrototype.lut.h
-@begin arrayPrototypeTable 16
-  toString       arrayProtoFuncToString       DontEnum|Function 0
-  toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0
-  concat         arrayProtoFuncConcat         DontEnum|Function 1
-  fill           arrayProtoFuncFill           DontEnum|Function 1
-  join           arrayProtoFuncJoin           DontEnum|Function 1
-  pop            arrayProtoFuncPop            DontEnum|Function 0
-  push           arrayProtoFuncPush           DontEnum|Function 1
-  reverse        arrayProtoFuncReverse        DontEnum|Function 0
-  shift          arrayProtoFuncShift          DontEnum|Function 0
-  slice          arrayProtoFuncSlice          DontEnum|Function 2
-  sort           arrayProtoFuncSort           DontEnum|Function 1
-  splice         arrayProtoFuncSplice         DontEnum|Function 2
-  unshift        arrayProtoFuncUnShift        DontEnum|Function 1
-  every          arrayProtoFuncEvery          DontEnum|Function 1
-  forEach        arrayProtoFuncForEach        DontEnum|Function 1
-  some           arrayProtoFuncSome           DontEnum|Function 1
-  indexOf        arrayProtoFuncIndexOf        DontEnum|Function 1
-  lastIndexOf    arrayProtoFuncLastIndexOf    DontEnum|Function 1
-  filter         arrayProtoFuncFilter         DontEnum|Function 1
-  reduce         arrayProtoFuncReduce         DontEnum|Function 1
-  reduceRight    arrayProtoFuncReduceRight    DontEnum|Function 1
-  map            arrayProtoFuncMap            DontEnum|Function 1
-  entries        arrayProtoFuncEntries        DontEnum|Function 0
-  keys           arrayProtoFuncKeys           DontEnum|Function 0
-  find           arrayProtoFuncFind           DontEnum|Function 1
-  findIndex      arrayProtoFuncFindIndex      DontEnum|Function 1
-@end
-*/
+const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, nullptr, CREATE_METHOD_TABLE(ArrayPrototype)};
 
 ArrayPrototype* ArrayPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
 {
@@ -138,21 +86,64 @@ void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayProtoFuncValues, DontEnum, 0);
-}
 
-bool ArrayPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayPrototypeTable(exec->vm()), jsCast<ArrayPrototype*>(object), propertyName, slot);
+    putDirectWithoutTransition(vm, vm.propertyNames->values, globalObject->arrayProtoValuesFunction(), DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, globalObject->arrayProtoValuesFunction(), DontEnum);
+    
+    JSC_NATIVE_FUNCTION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
+    JSC_NATIVE_FUNCTION("concat", arrayProtoFuncConcat, DontEnum, 1);
+    JSC_BUILTIN_FUNCTION("fill", arrayPrototypeFillCodeGenerator, DontEnum);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1);
+    JSC_NATIVE_INTRINSIC_FUNCTION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
+    JSC_NATIVE_INTRINSIC_FUNCTION("push", arrayProtoFuncPush, DontEnum, 1, ArrayPushIntrinsic);
+    JSC_NATIVE_FUNCTION("reverse", arrayProtoFuncReverse, DontEnum, 0);
+    JSC_NATIVE_FUNCTION("shift", arrayProtoFuncShift, DontEnum, 0);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->slice, arrayProtoFuncSlice, DontEnum, 2);
+    JSC_BUILTIN_FUNCTION("sort", arrayPrototypeSortCodeGenerator, DontEnum);
+    JSC_NATIVE_FUNCTION("splice", arrayProtoFuncSplice, DontEnum, 2);
+    JSC_NATIVE_FUNCTION("unshift", arrayProtoFuncUnShift, DontEnum, 1);
+    JSC_BUILTIN_FUNCTION("every", arrayPrototypeEveryCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("forEach", arrayPrototypeForEachCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("some", arrayPrototypeSomeCodeGenerator, DontEnum);
+    JSC_NATIVE_FUNCTION("indexOf", arrayProtoFuncIndexOf, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("lastIndexOf", arrayProtoFuncLastIndexOf, DontEnum, 1);
+    JSC_BUILTIN_FUNCTION("filter", arrayPrototypeFilterCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("reduce", arrayPrototypeReduceCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("reduceRight", arrayPrototypeReduceRightCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("map", arrayPrototypeMapCodeGenerator, DontEnum);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->entries, arrayProtoFuncEntries, DontEnum, 0);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->keys, arrayProtoFuncKeys, DontEnum, 0);
+    JSC_BUILTIN_FUNCTION("find", arrayPrototypeFindCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("findIndex", arrayPrototypeFindIndexCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("includes", arrayPrototypeIncludesCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("copyWithin", arrayPrototypeCopyWithinCodeGenerator, DontEnum);
+    
+    if (!globalObject->runtimeFlags().isSymbolDisabled()) {
+        JSObject* unscopables = constructEmptyObject(globalObject->globalExec(), globalObject->nullPrototypeObjectStructure());
+        const char* unscopableNames[] = {
+            "copyWithin",
+            "entries",
+            "fill",
+            "find",
+            "findIndex",
+            "keys",
+            "values"
+        };
+        for (const char* unscopableName : unscopableNames)
+            unscopables->putDirect(vm, Identifier::fromString(&vm, unscopableName), jsBoolean(true));
+        putDirectWithoutTransition(vm, vm.propertyNames->unscopablesSymbol, unscopables, DontEnum | ReadOnly);
+    }
 }
 
 // ------------------------------ Array Functions ----------------------------
 
-// Helper function
-static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
+static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsigned index)
 {
-    PropertySlot slot(obj);
-    if (!obj->getPropertySlot(exec, index, slot))
+    if (JSValue result = object->tryGetIndexQuickly(index))
+        return result;
+    PropertySlot slot(object);
+    if (!object->getPropertySlot(exec, index, slot))
         return JSValue();
     return slot.getValue(exec, index);
 }
@@ -170,7 +161,7 @@ static void putLength(ExecState* exec, JSObject* obj, JSValue value)
     obj->methodTable()->put(obj, exec, exec->propertyNames().length, value, slot);
 }
 
-static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
+static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
 {
     JSValue value = exec->argument(argument);
     if (value.isUndefined())
@@ -184,7 +175,6 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
     return indexDouble > length ? length : static_cast<unsigned>(indexDouble);
 }
 
-
 // The shift/unshift function implement the shift/unshift behaviour required
 // by the corresponding array prototype methods, and by splice. In both cases,
 // the methods are operating an an array or array like object.
@@ -199,6 +189,7 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
 // currentCount) will be shifted to the left or right as appropriate; in the
 // case of shift this must be removing values, in the case of unshift this
 // must be introducing new values.
+
 template<JSArray::ShiftCountMode shiftCountMode>
 void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
 {
@@ -210,19 +201,17 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current
 
     if (isJSArray(thisObj)) {
         JSArray* array = asArray(thisObj);
-        if (array->length() == length && asArray(thisObj)->shiftCount<shiftCountMode>(exec, header, count))
+        if (array->length() == length && array->shiftCount<shiftCountMode>(exec, header, count))
             return;
     }
 
     for (unsigned k = header; k < length - currentCount; ++k) {
         unsigned from = k + currentCount;
         unsigned to = k + resultCount;
-        PropertySlot slot(thisObj);
-        if (thisObj->getPropertySlot(exec, from, slot)) {
-            JSValue value = slot.getValue(exec, from);
+        if (JSValue value = getProperty(exec, thisObj, from)) {
             if (exec->hadException())
                 return;
-            thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, to, value, true);
+            thisObj->putByIndexInline(exec, to, value, true);
             if (exec->hadException())
                 return;
         } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) {
@@ -237,6 +226,7 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current
         }
     }
 }
+
 template<JSArray::ShiftCountMode shiftCountMode>
 void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
 {
@@ -257,16 +247,14 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre
         if (array->length() == length && array->unshiftCount<shiftCountMode>(exec, header, count))
             return;
     }
-    
+
     for (unsigned k = length - currentCount; k > header; --k) {
         unsigned from = k + currentCount - 1;
         unsigned to = k + resultCount - 1;
-        PropertySlot slot(thisObj);
-        if (thisObj->getPropertySlot(exec, from, slot)) {
-            JSValue value = slot.getValue(exec, from);
+        if (JSValue value = getProperty(exec, thisObj, from)) {
             if (exec->hadException())
                 return;
-            thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, to, value, true);
+            thisObj->putByIndexInline(exec, to, value, true);
         } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, to)) {
             throwTypeError(exec, ASCIILiteral("Unable to delete property."));
             return;
@@ -301,161 +289,258 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
         return JSValue::encode(call(exec, function, callType, callData, thisObject, exec->emptyList()));
 
     ASSERT(isJSArray(thisValue));
-    JSArray* thisObj = asArray(thisValue);
-    
-    unsigned length = getLength(exec, thisObj);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
+    JSArray* thisArray = asArray(thisValue);
+
+    unsigned length = thisArray->length();
 
-    StringRecursionChecker checker(exec, thisObj);
+    StringRecursionChecker checker(exec, thisArray);
     if (JSValue earlyReturnValue = checker.earlyReturnValue())
         return JSValue::encode(earlyReturnValue);
 
-    String separator(",", String::ConstructFromLiteral);
-    JSStringJoiner stringJoiner(separator, length);
-    for (unsigned k = 0; k < length; k++) {
-        JSValue element;
-        if (thisObj->canGetIndexQuickly(k))
-            element = thisObj->getIndexQuickly(k);
-        else {
-            element = thisObj->get(exec, k);
+    JSStringJoiner joiner(*exec, ',', length);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    for (unsigned i = 0; i < length; ++i) {
+        JSValue element = thisArray->tryGetIndexQuickly(i);
+        if (!element) {
+            element = thisArray->get(exec, i);
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
         }
-
-        if (element.isUndefinedOrNull())
-            stringJoiner.append(String());
-        else
-            stringJoiner.append(element.toWTFString(exec));
-
+        joiner.append(*exec, element);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
     }
-    return JSValue::encode(stringJoiner.join(exec));
+
+    return JSValue::encode(joiner.join(*exec));
 }
 
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
 
-    JSObject* thisObj = thisValue.toObject(exec);
+    JSObject* thisObject = thisValue.toObject(exec);
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
-    unsigned length = getLength(exec, thisObj);
+    unsigned length = getLength(exec, thisObject);
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
-    StringRecursionChecker checker(exec, thisObj);
+    StringRecursionChecker checker(exec, thisObject);
     if (JSValue earlyReturnValue = checker.earlyReturnValue())
         return JSValue::encode(earlyReturnValue);
 
-    String separator(",", String::ConstructFromLiteral);
-    JSStringJoiner stringJoiner(separator, length);
-    for (unsigned k = 0; k < length; k++) {
-        JSValue element = thisObj->get(exec, k);
+    JSStringJoiner stringJoiner(*exec, ',', length);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    for (unsigned i = 0; i < length; ++i) {
+        JSValue element = thisObject->getIndex(exec, i);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
-        if (!element.isUndefinedOrNull()) {
-            JSObject* o = element.toObject(exec);
-            JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
-            if (exec->hadException())
-                return JSValue::encode(jsUndefined());
-            String str;
-            CallData callData;
-            CallType callType = getCallData(conversionFunction, callData);
-            if (callType != CallTypeNone)
-                str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toWTFString(exec);
-            else
-                str = element.toWTFString(exec);
+        if (element.isUndefinedOrNull())
+            continue;
+        JSValue conversionFunction = element.get(exec, exec->propertyNames().toLocaleString);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+        CallData callData;
+        CallType callType = getCallData(conversionFunction, callData);
+        if (callType != CallTypeNone) {
+            element = call(exec, conversionFunction, callType, callData, element, exec->emptyList());
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
-            stringJoiner.append(str);
         }
+        stringJoiner.append(*exec, element);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
     }
 
-    return JSValue::encode(stringJoiner.join(exec));
+    return JSValue::encode(stringJoiner.join(*exec));
 }
 
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
+static inline bool isHole(double value)
 {
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = getLength(exec, thisObj);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    StringRecursionChecker checker(exec, thisObj);
-    if (JSValue earlyReturnValue = checker.earlyReturnValue())
-        return JSValue::encode(earlyReturnValue);
+    return std::isnan(value);
+}
 
-    String separator;
-    if (!exec->argument(0).isUndefined())
-        separator = exec->argument(0).toWTFString(exec);
-    if (separator.isNull())
-        separator = String(",", String::ConstructFromLiteral);
+static inline bool isHole(const WriteBarrier<Unknown>& value)
+{
+    return !value;
+}
 
-    JSStringJoiner stringJoiner(separator, length);
+template<typename T> static inline bool containsHole(T* data, unsigned length)
+{
+    for (unsigned i = 0; i < length; ++i) {
+        if (isHole(data[i]))
+            return true;
+    }
+    return false;
+}
 
-    unsigned k = 0;
-    if (isJSArray(thisObj)) {
-        JSArray* array = asArray(thisObj);
+static inline bool holesMustForwardToPrototype(ExecState& state, JSObject* object)
+{
+    auto& vm = state.vm();
+    return object->structure(vm)->holesMustForwardToPrototype(vm);
+}
 
-        for (; k < length; k++) {
-            if (!array->canGetIndexQuickly(k))
-                break;
+static inline JSValue join(ExecState& state, JSObject* thisObject, StringView separator)
+{
+    unsigned length = getLength(&state, thisObject);
+    if (state.hadException())
+        return jsUndefined();
 
-            JSValue element = array->getIndexQuickly(k);
-            if (!element.isUndefinedOrNull())
-                stringJoiner.append(element.toWTFStringInline(exec));
-            else
-                stringJoiner.append(String());
+    switch (thisObject->indexingType()) {
+    case ALL_CONTIGUOUS_INDEXING_TYPES:
+    case ALL_INT32_INDEXING_TYPES: {
+        auto& butterfly = *thisObject->butterfly();
+        if (length > butterfly.publicLength())
+            break;
+        JSStringJoiner joiner(state, separator, length);
+        if (state.hadException())
+            return jsUndefined();
+        auto data = butterfly.contiguous().data();
+        bool holesKnownToBeOK = false;
+        for (unsigned i = 0; i < length; ++i) {
+            if (JSValue value = data[i].get()) {
+                joiner.append(state, value);
+                if (state.hadException())
+                    return jsUndefined();
+            } else {
+                if (!holesKnownToBeOK) {
+                    if (holesMustForwardToPrototype(state, thisObject))
+                        goto generalCase;
+                    holesKnownToBeOK = true;
+                }
+                joiner.appendEmptyString();
+            }
+        }
+        return joiner.join(state);
+    }
+    case ALL_DOUBLE_INDEXING_TYPES: {
+        auto& butterfly = *thisObject->butterfly();
+        if (length > butterfly.publicLength())
+            break;
+        JSStringJoiner joiner(state, separator, length);
+        if (state.hadException())
+            return jsUndefined();
+        auto data = butterfly.contiguousDouble().data();
+        bool holesKnownToBeOK = false;
+        for (unsigned i = 0; i < length; ++i) {
+            double value = data[i];
+            if (!isHole(value))
+                joiner.append(state, jsDoubleNumber(value));
+            else {
+                if (!holesKnownToBeOK) {
+                    if (thisObject->structure(state.vm())->holesMustForwardToPrototype(state.vm()))
+                        goto generalCase;
+                    holesKnownToBeOK = true;
+                }
+                joiner.appendEmptyString();
+            }
         }
+        return joiner.join(state);
+    }
+    case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
+        auto& storage = *thisObject->butterfly()->arrayStorage();
+        if (length > storage.vectorLength())
+            break;
+        if (storage.hasHoles() && thisObject->structure(state.vm())->holesMustForwardToPrototype(state.vm()))
+            break;
+        JSStringJoiner joiner(state, separator, length);
+        if (state.hadException())
+            return jsUndefined();
+        auto data = storage.vector().data();
+        for (unsigned i = 0; i < length; ++i) {
+            if (JSValue value = data[i].get()) {
+                joiner.append(state, value);
+                if (state.hadException())
+                    return jsUndefined();
+            } else
+                joiner.appendEmptyString();
+        }
+        return joiner.join(state);
+    }
     }
 
-    for (; k < length; k++) {
-        JSValue element = thisObj->get(exec, k);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-        if (!element.isUndefinedOrNull())
-            stringJoiner.append(element.toWTFStringInline(exec));
-        else
-            stringJoiner.append(String());
+generalCase:
+    JSStringJoiner joiner(state, separator, length);
+    if (state.hadException())
+        return jsUndefined();
+    for (unsigned i = 0; i < length; ++i) {
+        JSValue element = thisObject->getIndex(&state, i);
+        if (state.hadException())
+            return jsUndefined();
+        joiner.append(state, element);
+        if (state.hadException())
+            return jsUndefined();
     }
+    return joiner.join(state);
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
+{
+    JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
+
+    StringRecursionChecker checker(exec, thisObject);
+    if (JSValue earlyReturnValue = checker.earlyReturnValue())
+        return JSValue::encode(earlyReturnValue);
 
-    return JSValue::encode(stringJoiner.join(exec));
+    JSValue separatorValue = exec->argument(0);
+    if (separatorValue.isUndefined()) {
+        const LChar comma = ',';
+        return JSValue::encode(join(*exec, thisObject, { &comma, 1 }));
+    }
+
+    JSString* separator = separatorValue.toString(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(join(*exec, thisObject, separator->view(exec)));
 }
 
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
-    size_t argCount = exec->argumentCount();
+    unsigned argCount = exec->argumentCount();
     JSValue curArg = thisValue.toObject(exec);
     Checked<unsigned, RecordOverflow> finalArraySize = 0;
 
-    for (size_t i = 0;;) {
-        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
+    JSArray* currentArray = nullptr;
+    JSArray* previousArray = nullptr;
+    for (unsigned i = 0; ; ++i) {
+        previousArray = currentArray;
+        currentArray = jsDynamicCast<JSArray*>(curArg);
+        if (currentArray) {
+            // Can't use JSArray::length here because this might be a RuntimeArray!
             finalArraySize += getLength(exec, currentArray);
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
         } else
-            finalArraySize++;
+            ++finalArraySize;
         if (i == argCount)
             break;
         curArg = exec->uncheckedArgument(i);
-        ++i;
     }
 
     if (finalArraySize.hasOverflowed())
         return JSValue::encode(throwOutOfMemoryError(exec));
 
+    if (argCount == 1 && previousArray && currentArray && finalArraySize.unsafeGet() < MIN_SPARSE_ARRAY_INDEX) {
+        IndexingType type = JSArray::fastConcatType(exec->vm(), *previousArray, *currentArray);
+        if (type != NonArray)
+            return previousArray->fastConcatWith(*exec, *currentArray);
+    }
+
     JSArray* arr = constructEmptyArray(exec, nullptr, finalArraySize.unsafeGet());
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
     curArg = thisValue.toObject(exec);
     unsigned n = 0;
-    for (size_t i = 0;;) {
+    for (unsigned i = 0; ; ++i) {
         if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
+            // Can't use JSArray::length here because this might be a RuntimeArray!
             unsigned length = getLength(exec, currentArray);
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
@@ -474,7 +559,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
         if (i == argCount)
             break;
         curArg = exec->uncheckedArgument(i);
-        ++i;
     }
     arr->setLength(exec, n);
     return JSValue::encode(arr);
@@ -530,7 +614,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
             thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->uncheckedArgument(n), true);
         else {
             PutPropertySlot slot(thisObj);
-            Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toWTFString(exec));
+            Identifier propertyName = Identifier::fromString(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toWTFString(exec));
             thisObj->methodTable()->put(thisObj, exec, propertyName, exec->uncheckedArgument(n), slot);
         }
         if (exec->hadException())
@@ -544,40 +628,75 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
 {
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = getLength(exec, thisObj);
+    JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
+
+    unsigned length = getLength(exec, thisObject);
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
+    switch (thisObject->indexingType()) {
+    case ALL_CONTIGUOUS_INDEXING_TYPES:
+    case ALL_INT32_INDEXING_TYPES: {
+        auto& butterfly = *thisObject->butterfly();
+        if (length > butterfly.publicLength())
+            break;
+        auto data = butterfly.contiguous().data();
+        if (containsHole(data, length) && holesMustForwardToPrototype(*exec, thisObject))
+            break;
+        std::reverse(data, data + length);
+        return JSValue::encode(thisObject);
+    }
+    case ALL_DOUBLE_INDEXING_TYPES: {
+        auto& butterfly = *thisObject->butterfly();
+        if (length > butterfly.publicLength())
+            break;
+        auto data = butterfly.contiguousDouble().data();
+        if (containsHole(data, length) && holesMustForwardToPrototype(*exec, thisObject))
+            break;
+        std::reverse(data, data + length);
+        return JSValue::encode(thisObject);
+    }
+    case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
+        auto& storage = *thisObject->butterfly()->arrayStorage();
+        if (length > storage.vectorLength())
+            break;
+        if (storage.hasHoles() && holesMustForwardToPrototype(*exec, thisObject))
+            break;
+        auto data = storage.vector().data();
+        std::reverse(data, data + length);
+        return JSValue::encode(thisObject);
+    }
+    }
+
     unsigned middle = length / 2;
     for (unsigned k = 0; k < middle; k++) {
         unsigned lk1 = length - k - 1;
-        JSValue obj2 = getProperty(exec, thisObj, lk1);
+        JSValue obj2 = getProperty(exec, thisObject, lk1);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
-        JSValue obj = getProperty(exec, thisObj, k);
+        JSValue obj = getProperty(exec, thisObject, k);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
 
         if (obj2) {
-            thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, k, obj2, true);
+            thisObject->putByIndexInline(exec, k, obj2, true);
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
-        } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, k)) {
+        } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, k)) {
             throwTypeError(exec, ASCIILiteral("Unable to delete property."));
             return JSValue::encode(jsUndefined());
         }
 
         if (obj) {
-            thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, lk1, obj, true);
+            thisObject->putByIndexInline(exec, lk1, obj, true);
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
-        } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, lk1)) {
+        } else if (!thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, lk1)) {
             throwTypeError(exec, ASCIILiteral("Unable to delete property."));
             return JSValue::encode(jsUndefined());
         }
     }
-    return JSValue::encode(thisObj);
+    return JSValue::encode(thisObject);
 }
 
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
@@ -592,7 +711,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
         putLength(exec, thisObj, jsNumber(length));
         result = jsUndefined();
     } else {
-        result = thisObj->get(exec, 0);
+        result = thisObj->getIndex(exec, 0);
         shift<JSArray::ShiftCountForShift>(exec, thisObj, 0, 1, 0, length);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
@@ -612,6 +731,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
     unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
     unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
 
+    if (isJSArray(thisObj)) {
+        if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin))
+            return JSValue::encode(result);
+    }
+
     JSArray* result = constructEmptyArray(exec, nullptr, end - begin);
 
     unsigned n = 0;
@@ -626,167 +750,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
     return JSValue::encode(result);
 }
 
-inline JSValue getOrHole(JSObject* obj, ExecState* exec, unsigned propertyName)
-{
-    PropertySlot slot(obj);
-    if (obj->getPropertySlot(exec, propertyName, slot))
-        return slot.getValue(exec, propertyName);
-
-    return JSValue();
-}
-
-static bool attemptFastSort(ExecState* exec, JSObject* thisObj, JSValue function, CallData& callData, CallType& callType)
-{
-    if (thisObj->classInfo() != JSArray::info()
-        || asArray(thisObj)->hasSparseMap()
-        || shouldUseSlowPut(thisObj->indexingType()))
-        return false;
-    
-    if (isNumericCompareFunction(exec, function, callType, callData))
-        asArray(thisObj)->sortNumeric(exec, function, callType, callData);
-    else if (callType != CallTypeNone)
-        asArray(thisObj)->sort(exec, function, callType, callData);
-    else
-        asArray(thisObj)->sort(exec);
-    return true;
-}
-
-static bool performSlowSort(ExecState* exec, JSObject* thisObj, unsigned length, JSValue function, CallData& callData, CallType& callType)
-{
-    // "Min" sort. Not the fastest, but definitely less code than heapsort
-    // or quicksort, and much less swapping than bubblesort/insertionsort.
-    for (unsigned i = 0; i < length - 1; ++i) {
-        JSValue iObj = getOrHole(thisObj, exec, i);
-        if (exec->hadException())
-            return false;
-        unsigned themin = i;
-        JSValue minObj = iObj;
-        for (unsigned j = i + 1; j < length; ++j) {
-            JSValue jObj = getOrHole(thisObj, exec, j);
-            if (exec->hadException())
-                return false;
-            double compareResult;
-            if (!jObj)
-                compareResult = 1;
-            else if (!minObj)
-                compareResult = -1;
-            else if (jObj.isUndefined())
-                compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
-            else if (minObj.isUndefined())
-                compareResult = -1;
-            else if (callType != CallTypeNone) {
-                MarkedArgumentBuffer l;
-                l.append(jObj);
-                l.append(minObj);
-                compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec);
-            } else
-                compareResult = codePointCompareLessThan(jObj.toWTFStringInline(exec), minObj.toWTFStringInline(exec)) ? -1 : 1;
-
-            if (compareResult < 0) {
-                themin = j;
-                minObj = jObj;
-            }
-        }
-        // Swap themin and i
-        if (themin > i) {
-            if (minObj) {
-                thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, i, minObj, true);
-                if (exec->hadException())
-                    return false;
-            } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, i)) {
-                throwTypeError(exec, "Unable to delete property.");
-                return false;
-            }
-            if (iObj) {
-                thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, themin, iObj, true);
-                if (exec->hadException())
-                    return false;
-            } else if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, themin)) {
-                throwTypeError(exec, "Unable to delete property.");
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
-{
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = getLength(exec, thisObj);
-    if (!length || exec->hadException())
-        return JSValue::encode(thisObj);
-
-    JSValue function = exec->argument(0);
-    CallData callData;
-    CallType callType = getCallData(function, callData);
-
-    if (attemptFastSort(exec, thisObj, function, callData, callType))
-        return JSValue::encode(thisObj);
-    
-    // Assume that for small-ish arrays, doing the slow sort directly is better.
-    if (length < 1000)
-        return performSlowSort(exec, thisObj, length, function, callData, callType) ? JSValue::encode(thisObj) : JSValue::encode(jsUndefined());
-    
-    JSGlobalObject* globalObject = JSGlobalObject::create(
-        exec->vm(), JSGlobalObject::createStructure(exec->vm(), jsNull()));
-    JSArray* flatArray = constructEmptyArray(globalObject->globalExec(), nullptr);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-    
-    PropertyNameArray nameArray(exec);
-    thisObj->methodTable(exec->vm())->getPropertyNames(thisObj, exec, nameArray, IncludeDontEnumProperties);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    Vector<uint32_t, 0, UnsafeVectorOverflow> keys;
-    for (size_t i = 0; i < nameArray.size(); ++i) {
-        PropertyName name = nameArray[i];
-        uint32_t index = name.asIndex();
-        if (index == PropertyName::NotAnIndex)
-            continue;
-        
-        JSValue value = getOrHole(thisObj, exec, index);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-        if (!value)
-            continue;
-        keys.append(index);
-        flatArray->push(exec, value);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-    }
-    
-    if (!attemptFastSort(exec, flatArray, function, callData, callType)
-        && !performSlowSort(exec, flatArray, flatArray->length(), function, callData, callType))
-        return JSValue::encode(jsUndefined());
-    
-    for (size_t i = 0; i < keys.size(); ++i) {
-        size_t index = keys[i];
-        if (index < flatArray->length())
-            continue;
-        
-        if (!thisObj->methodTable(exec->vm())->deletePropertyByIndex(thisObj, exec, index)) {
-            throwTypeError(exec, "Unable to delete property.");
-            return JSValue::encode(jsUndefined());
-        }
-    }
-    
-    for (size_t i = flatArray->length(); i--;) {
-        JSValue value = getOrHole(flatArray, exec, i);
-        RELEASE_ASSERT(value);
-        thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, i, value, true);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-    }
-    
-    return JSValue::encode(thisObj);
-}
-
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
 {
     // 15.4.4.12
 
+    VM& vm = exec->vm();
+
     JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
     unsigned length = getLength(exec, thisObj);
     if (exec->hadException())
@@ -808,17 +777,22 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
             deleteCount = static_cast<unsigned>(deleteDouble);
     }
 
-    JSArray* resObj = JSArray::tryCreateUninitialized(exec->vm(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount);
-    if (!resObj)
-        return JSValue::encode(throwOutOfMemoryError(exec));
+    JSArray* result = nullptr;
 
-    JSValue result = resObj;
-    VM& vm = exec->vm();
-    for (unsigned k = 0; k < deleteCount; k++) {
-        JSValue v = getProperty(exec, thisObj, k + begin);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-        resObj->initializeIndex(vm, k, v);
+    if (isJSArray(thisObj))
+        result = asArray(thisObj)->fastSlice(*exec, begin, deleteCount);
+
+    if (!result) {
+        result = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount);
+        if (!result)
+            return JSValue::encode(throwOutOfMemoryError(exec));
+
+        for (unsigned k = 0; k < deleteCount; ++k) {
+            JSValue v = getProperty(exec, thisObj, k + begin);
+            if (exec->hadException())
+                return JSValue::encode(jsUndefined());
+            result->initializeIndex(vm, k, v);
+        }
     }
 
     unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
@@ -832,7 +806,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
             return JSValue::encode(jsUndefined());
     }
     for (unsigned k = 0; k < additionalArgs; ++k) {
-        thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, k + begin, exec->uncheckedArgument(k + 2), true);
+        thisObj->putByIndexInline(exec, k + begin, exec->uncheckedArgument(k + 2), true);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
     }
@@ -857,7 +831,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
             return JSValue::encode(jsUndefined());
     }
     for (unsigned k = 0; k < nrArgs; ++k) {
-        thisObj->methodTable(exec->vm())->putByIndex(thisObj, exec, k, exec->uncheckedArgument(k), true);
+        thisObj->putByIndexInline(exec, k, exec->uncheckedArgument(k), true);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
     }
@@ -866,159 +840,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
     return JSValue::encode(result);
 }
 
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
-{
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = getLength(exec, thisObj);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSValue function = exec->argument(0);
-    CallData callData;
-    CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
-        return throwVMTypeError(exec);
-
-    unsigned i = 0;
-    JSValue rv;
-    if (!length && exec->argumentCount() == 1)
-        return throwVMTypeError(exec);
-
-    JSArray* array = 0;
-    if (isJSArray(thisObj))
-        array = asArray(thisObj);
-
-    if (exec->argumentCount() >= 2)
-        rv = exec->uncheckedArgument(1);
-    else if (array && array->canGetIndexQuickly(0)) {
-        rv = array->getIndexQuickly(0);
-        i = 1;
-    } else {
-        for (i = 0; i < length; i++) {
-            rv = getProperty(exec, thisObj, i);
-            if (exec->hadException())
-                return JSValue::encode(jsUndefined());
-            if (rv)
-                break;
-        }
-        if (!rv)
-            return throwVMTypeError(exec);
-        i++;
-    }
-
-    if (callType == CallTypeJS && array) {
-        CachedCall cachedCall(exec, jsCast<JSFunction*>(function), 4);
-        for (; i < length && !exec->hadException(); ++i) {
-            cachedCall.setThis(jsUndefined());
-            cachedCall.setArgument(0, rv);
-            JSValue v;
-            if (LIKELY(array->canGetIndexQuickly(i)))
-                v = array->getIndexQuickly(i);
-            else
-                break; // length has been made unsafe while we enumerate fallback to slow path
-            cachedCall.setArgument(1, v);
-            cachedCall.setArgument(2, jsNumber(i));
-            cachedCall.setArgument(3, array);
-            rv = cachedCall.call();
-        }
-        if (i == length) // only return if we reached the end of the array
-            return JSValue::encode(rv);
-    }
-
-    for (; i < length && !exec->hadException(); ++i) {
-        JSValue prop = getProperty(exec, thisObj, i);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-        if (!prop)
-            continue;
-        
-        MarkedArgumentBuffer eachArguments;
-        eachArguments.append(rv);
-        eachArguments.append(prop);
-        eachArguments.append(jsNumber(i));
-        eachArguments.append(thisObj);
-        
-        rv = call(exec, function, callType, callData, jsUndefined(), eachArguments);
-    }
-    return JSValue::encode(rv);
-}
-
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
-{
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = getLength(exec, thisObj);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSValue function = exec->argument(0);
-    CallData callData;
-    CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
-        return throwVMTypeError(exec);
-    
-    unsigned i = 0;
-    JSValue rv;
-    if (!length && exec->argumentCount() == 1)
-        return throwVMTypeError(exec);
-
-    JSArray* array = 0;
-    if (isJSArray(thisObj))
-        array = asArray(thisObj);
-    
-    if (exec->argumentCount() >= 2)
-        rv = exec->uncheckedArgument(1);
-    else if (array && array->canGetIndexQuickly(length - 1)) {
-        rv = array->getIndexQuickly(length - 1);
-        i = 1;
-    } else {
-        for (i = 0; i < length; i++) {
-            rv = getProperty(exec, thisObj, length - i - 1);
-            if (exec->hadException())
-                return JSValue::encode(jsUndefined());
-            if (rv)
-                break;
-        }
-        if (!rv)
-            return throwVMTypeError(exec);
-        i++;
-    }
-    
-    if (callType == CallTypeJS && array) {
-        CachedCall cachedCall(exec, jsCast<JSFunction*>(function), 4);
-        for (; i < length && !exec->hadException(); ++i) {
-            unsigned idx = length - i - 1;
-            cachedCall.setThis(jsUndefined());
-            cachedCall.setArgument(0, rv);
-            if (UNLIKELY(!array->canGetIndexQuickly(idx)))
-                break; // length has been made unsafe while we enumerate fallback to slow path
-            cachedCall.setArgument(1, array->getIndexQuickly(idx));
-            cachedCall.setArgument(2, jsNumber(idx));
-            cachedCall.setArgument(3, array);
-            rv = cachedCall.call();
-        }
-        if (i == length) // only return if we reached the end of the array
-            return JSValue::encode(rv);
-    }
-    
-    for (; i < length && !exec->hadException(); ++i) {
-        unsigned idx = length - i - 1;
-        JSValue prop = getProperty(exec, thisObj, idx);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-        if (!prop)
-            continue;
-        
-        MarkedArgumentBuffer eachArguments;
-        eachArguments.append(rv);
-        eachArguments.append(prop);
-        eachArguments.append(jsNumber(idx));
-        eachArguments.append(thisObj);
-        
-        rv = call(exec, function, callType, callData, jsUndefined(), eachArguments);
-    }
-    return JSValue::encode(rv);        
-}
-
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
 {
     // 15.4.4.14
index 472a1dd9c98fd1459eabe24f8585485540c2c944..39412c2205bdc7ae23d3d22e4a5d9e8429250c2a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2007, 2011 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2011, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -35,8 +35,6 @@ public:
 
     static ArrayPrototype* create(VM&, JSGlobalObject*, Structure*);
         
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-
     DECLARE_INFO;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -48,6 +46,8 @@ protected:
     void finishCreation(VM&, JSGlobalObject*);
 };
 
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
+
 } // namespace JSC
 
 #endif // ArrayPrototype_h
diff --git a/runtime/BasicBlockLocation.cpp b/runtime/BasicBlockLocation.cpp
new file mode 100644 (file)
index 0000000..33cc396
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Saam Barati. <saambarati1@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "BasicBlockLocation.h"
+
+#include "CCallHelpers.h"
+#include <climits>
+#include <wtf/DataLog.h>
+
+namespace JSC {
+
+BasicBlockLocation::BasicBlockLocation(int startOffset, int endOffset)
+    : m_startOffset(startOffset)
+    , m_endOffset(endOffset)
+    , m_hasExecuted(false)
+{
+}
+
+void BasicBlockLocation::insertGap(int startOffset, int endOffset)
+{
+    std::pair<int, int> gap(startOffset, endOffset);
+    if (!m_gaps.contains(gap))
+        m_gaps.append(gap);
+}
+
+Vector<std::pair<int, int>> BasicBlockLocation::getExecutedRanges() const
+{
+    Vector<Gap> result;
+    Vector<Gap> gaps = m_gaps;
+    int nextRangeStart = m_startOffset;
+    while (gaps.size()) {
+        Gap minGap(INT_MAX, 0);
+        unsigned minIdx = std::numeric_limits<unsigned>::max();
+        for (unsigned idx = 0; idx < gaps.size(); idx++) {
+            // Because we know that the Gaps inside m_gaps aren't enclosed within one another, it suffices to just check the first element to test ordering.
+            if (gaps[idx].first < minGap.first) {
+                minGap = gaps[idx];
+                minIdx = idx;
+            }
+        }
+        result.append(Gap(nextRangeStart, minGap.first - 1));
+        nextRangeStart = minGap.second + 1;
+        gaps.remove(minIdx);
+    }
+
+    result.append(Gap(nextRangeStart, m_endOffset));
+    return result;
+}
+
+void BasicBlockLocation::dumpData() const
+{
+    Vector<Gap> executedRanges = getExecutedRanges();
+    for (Gap gap : executedRanges)
+        dataLogF("\tBasicBlock: [%d, %d] hasExecuted: %s\n", gap.first, gap.second, hasExecuted() ? "true" : "false");
+}
+
+#if ENABLE(JIT)
+void BasicBlockLocation::emitExecuteCode(CCallHelpers& jit, MacroAssembler::RegisterID ptrReg) const
+{
+    jit.move(CCallHelpers::TrustedImmPtr(&m_hasExecuted), ptrReg);
+    jit.store8(CCallHelpers::TrustedImm32(true), CCallHelpers::Address(ptrReg, 0));
+}
+#endif // ENABLE(JIT)
+
+} // namespace JSC
diff --git a/runtime/BasicBlockLocation.h b/runtime/BasicBlockLocation.h
new file mode 100644 (file)
index 0000000..49bf514
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Saam Barati. <saambarati1@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef BasicBlockLocation_h
+#define BasicBlockLocation_h
+
+#include "MacroAssembler.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CCallHelpers;
+class LLIntOffsetsExtractor;
+
+class BasicBlockLocation {
+public:
+    typedef std::pair<int, int> Gap;
+
+    BasicBlockLocation(int startOffset = -1, int endOffset = -1);
+
+    int startOffset() const { return m_startOffset; }
+    int endOffset() const { return m_endOffset; }
+    void setStartOffset(int startOffset) { m_startOffset = startOffset; }
+    void setEndOffset(int endOffset) { m_endOffset = endOffset; }
+    bool hasExecuted() const { return m_hasExecuted; }
+    void insertGap(int, int);
+    Vector<Gap> getExecutedRanges() const;
+    JS_EXPORT_PRIVATE void dumpData() const;
+#if ENABLE(JIT)
+    void emitExecuteCode(CCallHelpers&, MacroAssembler::RegisterID) const;
+#endif
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    int m_startOffset;
+    int m_endOffset;
+    bool m_hasExecuted;
+    Vector<Gap> m_gaps;
+};
+
+} // namespace JSC
+
+#endif // BasicBlockLocation_h
index b316be1d5af9217e88f028ef74d104f421acc940..0a250760d06b4bd7791133db391c1cf84703cfeb 100644 (file)
@@ -29,7 +29,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanConstructor);
 
-const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) };
+const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(BooleanConstructor) };
 
 BooleanConstructor::BooleanConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
index 89fb83a9564ff3784c0828c3208b9f82e367c30d..28cad6ae7575c492ec4847a9e329ff291dee0700 100644 (file)
@@ -28,7 +28,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BooleanObject);
 
-const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) };
+const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(BooleanObject) };
 
 BooleanObject::BooleanObject(VM& vm, Structure* structure)
     : JSWrapperObject(vm, structure)
index 56182bac8acb60113177967242559cc9cbd7e166..be737ae5a0906bd39f4d2e1eb7d76b2582180e3e 100644 (file)
@@ -39,7 +39,7 @@ static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*);
 
 namespace JSC {
 
-const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, 0, ExecState::booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) };
+const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, &booleanPrototypeTable, CREATE_METHOD_TABLE(BooleanPrototype) };
 
 /* Source for BooleanPrototype.lut.h
 @begin booleanPrototypeTable
@@ -65,7 +65,7 @@ void BooleanPrototype::finishCreation(VM& vm, JSGlobalObject*)
 
 bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<BooleanObject>(exec, ExecState::booleanPrototypeTable(exec->vm()), jsCast<BooleanPrototype*>(object), propertyName, slot);
+    return getStaticFunctionSlot<BooleanObject>(exec, booleanPrototypeTable, jsCast<BooleanPrototype*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions ---------------------------
index 35ece4bd36e5b9697052ea59371c53beb64e1dc1..6d8fc5e8148194e05ca3867233ee3cf2fcb52fa7 100644 (file)
@@ -28,6 +28,7 @@ namespace JSC {
 class BooleanPrototype : public BooleanObject {
 public:
     typedef BooleanObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static BooleanPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     {
@@ -45,7 +46,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | BooleanObject::StructureFlags;
 
 private:
     BooleanPrototype(VM&, Structure*);
diff --git a/runtime/BundlePath.cpp b/runtime/BundlePath.cpp
new file mode 100644 (file)
index 0000000..e4e4c68
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics
+ * Copyright (C) 2014 University of Szeged
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BundlePath.h"
+
+#if ENABLE(FTL_NATIVE_CALL_INLINING)
+
+#include <execinfo.h>
+#include <string>
+
+
+namespace JSC {
+
+const CString* constantBundlePath = nullptr;
+
+const CString& bundlePath()
+{
+    if (!constantBundlePath) {
+        std::string programPath(realpath(program_invocation_name, 0));
+        constantBundlePath = new CString(programPath.substr(0, programPath.find_last_of("\\/")).c_str());
+    }
+
+    return *constantBundlePath;
+}
+
+} // namespace JSC
+
+#endif // FTL_NATIVE_CALL_INLINING
diff --git a/runtime/BundlePath.h b/runtime/BundlePath.h
new file mode 100644 (file)
index 0000000..c8c6948
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef BundlePath_h
+#define BundlePath_h
+
+#include <string>
+#include <wtf/text/CString.h>
+
+namespace JSC {
+
+const CString& bundlePath();
+
+} // namespace JSC
+
+#endif // BundlePath_h
+
diff --git a/runtime/BundlePath.mm b/runtime/BundlePath.mm
new file mode 100644 (file)
index 0000000..bd2212e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#import "config.h"
+#import "BundlePath.h"
+
+#import <Foundation/Foundation.h>
+#import <string>
+
+@interface JSJavaScriptCoreFinder : NSObject
+@end
+
+@implementation JSJavaScriptCoreFinder
+@end
+
+
+namespace JSC {
+
+const CString* constantBundlePath = nullptr;
+
+const CString& bundlePath()
+{
+    if (!constantBundlePath) {
+        @autoreleasepool {
+            NSBundle* myBundle = [NSBundle bundleForClass:[JSJavaScriptCoreFinder class]];
+
+            constantBundlePath = new CString([[myBundle bundlePath] UTF8String]);
+        }
+    }
+
+    return *constantBundlePath;
+}
+
+} // namespace JSC
index 6d00109c3ddba5f13facd496f1027a0c2e37da8c..31c28c3364b2de1294eea2555fbb4f3bed0583b6 100644 (file)
@@ -39,12 +39,11 @@ JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const C
     return exec->interpreter()->executeCall(exec, asObject(functionObject), callType, callData, thisValue, args);
 }
 
-JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, JSValue* exception)
+JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args, NakedPtr<Exception>& returnedException)
 {
     JSValue result = call(exec, functionObject, callType, callData, thisValue, args);
     if (exec->hadException()) {
-        if (exception)
-            *exception = exec->exception();
+        returnedException = exec->exception();
         exec->clearException();
         return jsUndefined();
     }
index b6edd3731083ce49b8a2af6a0bb47df6abfc25e6..e4a918deca4fc36bcc31ac1348bc0b8b60c3c6ad 100644 (file)
 #define CallData_h
 
 #include "JSCJSValue.h"
+#include <wtf/NakedPtr.h>
 
 namespace JSC {
 
 class ArgList;
+class Exception;
 class ExecState;
 class FunctionExecutable;
 class JSObject;
@@ -58,7 +60,7 @@ union CallData {
 };
 
 JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
-JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&, JSValue* exception);
+JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&, NakedPtr<Exception>& returnedException);
 
 } // namespace JSC
 
index f7cabe5e319bbb133ddfb79ef6ab8a507274f651..cb5058c2dc062b4db5d682a01617b3778c1404ba 100644 (file)
@@ -82,6 +82,12 @@ struct MethodTable {
     typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     GetPropertyNamesFunctionPtr getPropertyNames;
 
+    typedef uint32_t (*GetEnumerableLengthFunctionPtr)(ExecState*, JSObject*);
+    GetEnumerableLengthFunctionPtr getEnumerableLength;
+
+    GetPropertyNamesFunctionPtr getStructurePropertyNames;
+    GetPropertyNamesFunctionPtr getGenericPropertyNames;
+
     typedef String (*ClassNameFunctionPtr)(const JSObject*);
     ClassNameFunctionPtr className;
 
@@ -137,6 +143,9 @@ struct MethodTable {
         &ClassName::getOwnPropertyNames, \
         &ClassName::getOwnNonIndexPropertyNames, \
         &ClassName::getPropertyNames, \
+        &ClassName::getEnumerableLength, \
+        &ClassName::getStructurePropertyNames, \
+        &ClassName::getGenericPropertyNames, \
         &ClassName::className, \
         &ClassName::customHasInstance, \
         &ClassName::defineOwnProperty, \
@@ -154,25 +163,6 @@ struct ClassInfo {
     // nullptrif there is none.
     const ClassInfo* parentClass;
 
-    // Static hash-table of properties.
-    // For classes that can be used from multiple threads, it is accessed via a getter function
-    // that would typically return a pointer to a thread-specific value.
-    const HashTable* propHashTable(ExecState* exec) const
-    {
-        if (classPropHashTableGetterFunction)
-            return &classPropHashTableGetterFunction(exec->vm());
-
-        return staticPropHashTable;
-    }
-
-    const HashTable* propHashTable(VM& vm) const
-    {
-        if (classPropHashTableGetterFunction)
-            return &classPropHashTableGetterFunction(vm);
-
-        return staticPropHashTable;
-    }
-
     bool isSubClassOf(const ClassInfo* other) const
     {
         for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
@@ -185,17 +175,15 @@ struct ClassInfo {
     bool hasStaticProperties() const
     {
         for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
-            if (ci->staticPropHashTable || ci->classPropHashTableGetterFunction)
+            if (ci->staticPropHashTable)
                 return true;
         }
         return false;
     }
 
-    bool hasStaticSetterOrReadonlyProperties(VM&) const;
+    bool hasStaticSetterOrReadonlyProperties() const;
 
     const HashTable* staticPropHashTable;
-    typedef const HashTable& (*ClassPropHashTableGetterFunction)(VM&);
-    const ClassPropHashTableGetterFunction classPropHashTableGetterFunction;
 
     MethodTable methodTable;
 
diff --git a/runtime/ClonedArguments.cpp b/runtime/ClonedArguments.cpp
new file mode 100644 (file)
index 0000000..fffd87e
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ClonedArguments.h"
+
+#include "GetterSetter.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ClonedArguments);
+
+const ClassInfo ClonedArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(ClonedArguments) };
+
+ClonedArguments::ClonedArguments(VM& vm, Structure* structure)
+    : Base(vm, structure, nullptr)
+{
+}
+
+ClonedArguments* ClonedArguments::createEmpty(
+    VM& vm, Structure* structure, JSFunction* callee)
+{
+    ClonedArguments* result =
+        new (NotNull, allocateCell<ClonedArguments>(vm.heap))
+        ClonedArguments(vm, structure);
+    result->finishCreation(vm);
+    result->m_callee.set(vm, result, callee);
+    return result;
+}
+
+ClonedArguments* ClonedArguments::createEmpty(ExecState* exec, JSFunction* callee)
+{
+    // NB. Some clients might expect that the global object of of this object is the global object
+    // of the callee. We don't do this for now, but maybe we should.
+    return createEmpty(
+        exec->vm(), exec->lexicalGlobalObject()->outOfBandArgumentsStructure(), callee);
+}
+
+ClonedArguments* ClonedArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
+{
+    VM& vm = myFrame->vm();
+    
+    JSFunction* callee;
+    
+    if (inlineCallFrame)
+        callee = jsCast<JSFunction*>(inlineCallFrame->calleeRecovery.recover(targetFrame));
+    else
+        callee = jsCast<JSFunction*>(targetFrame->callee());
+
+    ClonedArguments* result = createEmpty(myFrame, callee);
+    
+    unsigned length = 0; // Initialize because VC needs it.
+    switch (mode) {
+    case ArgumentsMode::Cloned: {
+        if (inlineCallFrame) {
+            if (inlineCallFrame->argumentCountRegister.isValid())
+                length = targetFrame->r(inlineCallFrame->argumentCountRegister).unboxedInt32();
+            else
+                length = inlineCallFrame->arguments.size();
+            length--;
+            
+            for (unsigned i = length; i--;)
+                result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
+        } else {
+            length = targetFrame->argumentCount();
+            
+            for (unsigned i = length; i--;)
+                result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i));
+        }
+        break;
+    }
+        
+    case ArgumentsMode::FakeValues: {
+        length = 0;
+        break;
+    } }
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    
+    return result;
+}
+
+ClonedArguments* ClonedArguments::createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode mode)
+{
+    return createWithInlineFrame(myFrame, targetFrame, nullptr, mode);
+}
+
+ClonedArguments* ClonedArguments::createByCopyingFrom(
+    ExecState* exec, Structure* structure, Register* argumentStart, unsigned length,
+    JSFunction* callee)
+{
+    VM& vm = exec->vm();
+    ClonedArguments* result = createEmpty(vm, structure, callee);
+    
+    for (unsigned i = length; i--;)
+        result->putDirectIndex(exec, i, argumentStart[i].jsValue());
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    return result;
+}
+
+Structure* ClonedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+bool ClonedArguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller
+        || ident == vm.propertyNames->iteratorSymbol)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    if (Base::getOwnPropertySlot(thisObject, exec, ident, slot))
+        return true;
+    
+    return false;
+}
+
+void ClonedArguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    thisObject->materializeSpecialsIfNecessary(exec);
+    Base::getOwnPropertyNames(thisObject, exec, array, mode);
+}
+
+void ClonedArguments::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(cell);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller
+        || ident == vm.propertyNames->iteratorSymbol) {
+        thisObject->materializeSpecialsIfNecessary(exec);
+        PutPropertySlot dummy = slot; // Shadow the given PutPropertySlot to prevent caching.
+        Base::put(thisObject, exec, ident, value, dummy);
+        return;
+    }
+    
+    Base::put(thisObject, exec, ident, value, slot);
+}
+
+bool ClonedArguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(cell);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller
+        || ident == vm.propertyNames->iteratorSymbol)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    return Base::deleteProperty(thisObject, exec, ident);
+}
+
+bool ClonedArguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller
+        || ident == vm.propertyNames->iteratorSymbol)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
+}
+
+void ClonedArguments::materializeSpecials(ExecState* exec)
+{
+    RELEASE_ASSERT(!specialsMaterialized());
+    VM& vm = exec->vm();
+    
+    FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_callee->executable());
+    bool isStrictMode = executable->isStrictMode();
+    
+    if (isStrictMode) {
+        putDirectAccessor(exec, vm.propertyNames->callee, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor);
+        putDirectAccessor(exec, vm.propertyNames->caller, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor);
+    } else
+        putDirect(vm, vm.propertyNames->callee, JSValue(m_callee.get()));
+
+    putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum);
+    
+    m_callee.clear();
+}
+
+void ClonedArguments::materializeSpecialsIfNecessary(ExecState* exec)
+{
+    if (!specialsMaterialized())
+        materializeSpecials(exec);
+}
+
+void ClonedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    visitor.append(&thisObject->m_callee);
+}
+
+} // namespace JSC
+
diff --git a/runtime/ClonedArguments.h b/runtime/ClonedArguments.h
new file mode 100644 (file)
index 0000000..8e713d5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ClonedArguments_h
+#define ClonedArguments_h
+
+#include "ArgumentsMode.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you do function.arguments, or you say
+// "arguments" inside a function in strict mode. It behaves almpst entirely like an ordinary
+// JavaScript object. All of the arguments values are simply copied from the stack (possibly via
+// some sophisticated ValueRecovery's if an optimizing compiler is in play) and the appropriate
+// properties of the object are populated. The only reason why we need a special class is to make
+// the object claim to be "Arguments" from a toString standpoint, and to avoid materializing the
+// caller/callee/@@iterator properties unless someone asks for them.
+class ClonedArguments : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+    
+private:
+    ClonedArguments(VM&, Structure*);
+
+public:
+    static ClonedArguments* createEmpty(VM&, Structure*, JSFunction* callee);
+    static ClonedArguments* createEmpty(ExecState*, JSFunction* callee);
+    static ClonedArguments* createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame*, ArgumentsMode);
+    static ClonedArguments* createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode);
+    static ClonedArguments* createByCopyingFrom(ExecState*, Structure*, Register* argumentsStart, unsigned length, JSFunction* callee);
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    DECLARE_INFO;
+
+private:
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+    
+    bool specialsMaterialized() const { return !m_callee; }
+    void materializeSpecials(ExecState*);
+    void materializeSpecialsIfNecessary(ExecState*);
+    
+    WriteBarrier<JSFunction> m_callee; // Set to nullptr when we materialize all of our special properties.
+};
+
+} // namespace JSC
+
+#endif // ClonedArguments_h
+
index 442835b854bb81147484bd925721a5ec694d333a..298efc6235d30962a1d42881ac46295300c3a9bf 100644 (file)
@@ -75,13 +75,14 @@ template <> struct CacheTypes<UnlinkedEvalCodeBlock> {
 };
 
 template <class UnlinkedCodeBlockType, class ExecutableType>
-UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode,
+    JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
-    SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
-    CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
-    bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff;
-    if (!addResult.isNewEntry && canCache) {
-        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
+    SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, thisTDZMode);
+    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
+    bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler();
+    if (cache && canCache) {
+        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(cache->cell.get());
         unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine();
         unsigned lineCount = unlinkedCodeBlock->lineCount();
         unsigned startColumn = unlinkedCodeBlock->startColumn() + source.startColumn();
@@ -92,81 +93,88 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe
     }
 
     typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
-    RefPtr<RootNode> rootNode = parse<RootNode>(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error);
-    if (!rootNode) {
-        m_sourceCode.remove(addResult.iterator);
-        return 0;
-    }
-    unsigned lineCount = rootNode->lastLine() - rootNode->lineNo();
+    std::unique_ptr<RootNode> rootNode = parse<RootNode>(
+        &vm, source, 0, Identifier(), builtinMode, strictMode, 
+        JSParserCodeType::Program, error, 0, ConstructorKind::None, thisTDZMode);
+    if (!rootNode)
+        return nullptr;
+
+    unsigned lineCount = rootNode->lastLine() - rootNode->firstLine();
     unsigned startColumn = rootNode->startColumn() + 1;
     bool endColumnIsOnStartLine = !lineCount;
     unsigned unlinkedEndColumn = rootNode->endColumn();
     unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
-    executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), startColumn, endColumn);
+    executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn);
 
     UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
-    unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), lineCount, unlinkedEndColumn);
+    unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn);
 
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode)));
+    auto generator = std::make_unique<BytecodeGenerator>(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode);
     error = generator->generate();
-    rootNode->destroyData();
-    if (error.m_type != ParserError::ErrorNone) {
-        m_sourceCode.remove(addResult.iterator);
-        return 0;
-    }
+    if (error.isValid())
+        return nullptr;
 
-    if (!canCache) {
-        m_sourceCode.remove(addResult.iterator);
+    if (!canCache)
         return unlinkedCodeBlock;
-    }
 
-    addResult.iterator->value = SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age());
+    m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age()));
     return unlinkedCodeBlock;
 }
 
-UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
-    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
+    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error);
 }
 
-UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
-    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictness, debuggerMode, profilerMode, error);
+    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error);
 }
 
+// FIXME: There's no need to add the function's name to the key here. It's already in the source code.
 UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error)
 {
-    SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal);
-    CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
-    if (!addResult.isNewEntry)
-        return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get());
+    SourceCodeKey key = SourceCodeKey(
+        source, name.string(), SourceCodeKey::FunctionType, 
+        JSParserBuiltinMode::NotBuiltin, 
+        JSParserStrictMode::NotStrict);
+    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
+    if (cache)
+        return jsCast<UnlinkedFunctionExecutable*>(cache->cell.get());
 
     JSTextPosition positionBeforeLastNewline;
-    RefPtr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline);
+    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
+        &vm, source, 0, Identifier(), JSParserBuiltinMode::NotBuiltin, 
+        JSParserStrictMode::NotStrict, JSParserCodeType::Program, 
+        error, &positionBeforeLastNewline);
     if (!program) {
-        RELEASE_ASSERT(error.m_type != ParserError::ErrorNone);
-        m_sourceCode.remove(addResult.iterator);
-        return 0;
+        RELEASE_ASSERT(error.isValid());
+        return nullptr;
     }
 
-    // This function assumes an input string that would result in a single anonymous function expression.
-    StatementNode* exprStatement = program->singleStatement();
-    RELEASE_ASSERT(exprStatement);
-    RELEASE_ASSERT(exprStatement->isExprStatement());
-    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
-    RELEASE_ASSERT(funcExpr);
-    RELEASE_ASSERT(funcExpr->isFuncExprNode());
-    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
-    RELEASE_ASSERT(!program->hasCapturedVariables());
+    // This function assumes an input string that would result in a single function declaration.
+    StatementNode* statement = program->singleStatement();
+    ASSERT(statement);
+    ASSERT(statement->isBlock());
+    if (!statement || !statement->isBlock())
+        return nullptr;
+
+    StatementNode* funcDecl = static_cast<BlockNode*>(statement)->singleStatement();
+    ASSERT(funcDecl);
+    ASSERT(funcDecl->isFuncDeclNode());
+    if (!funcDecl || !funcDecl->isFuncDeclNode())
+        return nullptr;
+
+    FunctionBodyNode* body = static_cast<FuncDeclNode*>(funcDecl)->body();
+    ASSERT(body);
+    if (!body)
+        return nullptr;
     
     body->setEndPosition(positionBeforeLastNewline);
-    RELEASE_ASSERT(body);
-    RELEASE_ASSERT(body->ident().isNull());
-
     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, UnlinkedNormalFunction);
     functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
 
-    addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age());
+    m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
     return functionExecutable;
 }
 
index 1b015467b88bf753aa1bf9d509b2ef03d7e598f4..8877fc06c84e83b61a3451b5b8f253da19d47990 100644 (file)
@@ -33,7 +33,6 @@
 #include "WeakRandom.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/Forward.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RandomNumber.h>
 #include <wtf/text/WTFString.h>
 
@@ -43,6 +42,7 @@ class EvalExecutable;
 class FunctionBodyNode;
 class Identifier;
 class JSScope;
+class ParserError;
 class ProgramExecutable;
 class UnlinkedCodeBlock;
 class UnlinkedEvalCodeBlock;
@@ -50,7 +50,6 @@ class UnlinkedFunctionCodeBlock;
 class UnlinkedFunctionExecutable;
 class UnlinkedProgramCodeBlock;
 class VM;
-struct ParserError;
 class SourceCode;
 class SourceProvider;
 
@@ -62,10 +61,15 @@ public:
     {
     }
 
-    SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness)
+    SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserBuiltinMode builtinMode,
+        JSParserStrictMode strictMode, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
         : m_sourceCode(sourceCode)
         , m_name(name)
-        , m_flags((codeType << 2) | jsParserStrictness)
+        , m_flags(
+            (static_cast<unsigned>(codeType) << 3)
+            | (static_cast<unsigned>(builtinMode) << 2)
+            | (static_cast<unsigned>(strictMode) << 1)
+            | static_cast<unsigned>(thisTDZMode))
         , m_hash(string().impl()->hash())
     {
     }
@@ -145,18 +149,15 @@ public:
     {
     }
 
-    AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
+    SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key)
     {
         prune();
 
-        AddResult addResult = m_map.add(key, value);
-        if (addResult.isNewEntry) {
-            m_size += key.length();
-            m_age += key.length();
-            return addResult;
-        }
+        iterator findResult = m_map.find(key);
+        if (findResult == m_map.end())
+            return nullptr;
 
-        int64_t age = m_age - addResult.iterator->value.age;
+        int64_t age = m_age - findResult->value.age;
         if (age > m_capacity) {
             // A requested object is older than the cache's capacity. We can
             // infer that requested objects are subject to high eviction probability,
@@ -171,7 +172,20 @@ public:
                 m_capacity = m_minCapacity;
         }
 
-        addResult.iterator->value.age = m_age;
+        findResult->value.age = m_age;
+        m_age += key.length();
+
+        return &findResult->value;
+    }
+
+    AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value)
+    {
+        prune();
+
+        AddResult addResult = m_map.add(key, value);
+        ASSERT(addResult.isNewEntry);
+
+        m_size += key.length();
         m_age += key.length();
         return addResult;
     }
@@ -237,12 +251,12 @@ private:
 class CodeCache {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
+    CodeCache();
+    ~CodeCache();
 
-    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
-    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&);
     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
-    ~CodeCache();
 
     void clear()
     {
@@ -250,10 +264,8 @@ public:
     }
 
 private:
-    CodeCache();
-
     template <class UnlinkedCodeBlockType, class ExecutableType> 
-    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&);
 
     CodeCacheMap m_sourceCode;
 };
index 56df3450287ff999a38fcf4cb7150e861a5643e8..21bc4c7cefde867d8ab51c572be15979be8120f0 100644 (file)
 #include "CommonIdentifiers.h"
 
 #include "BuiltinNames.h"
+#include "IdentifierInlines.h"
 #include "JSCBuiltins.h"
 #include "PrivateName.h"
 
 namespace JSC {
 
-#define INITIALIZE_PROPERTY_NAME(name) , name(vm, #name)
-#define INITIALIZE_KEYWORD(name) , name##Keyword(vm, #name)
+#define INITIALIZE_PROPERTY_NAME(name) , name(Identifier::fromString(vm, #name))
+#define INITIALIZE_KEYWORD(name) , name##Keyword(Identifier::fromString(vm, #name))
 #define INITIALIZE_PRIVATE_NAME(name) , name##PrivateName(m_builtinNames->name##PrivateName())
+#define INITIALIZE_SYMBOL(name) , name##Symbol(m_builtinNames->name##Symbol())
 
 CommonIdentifiers::CommonIdentifiers(VM* vm)
     : nullIdentifier()
     , emptyIdentifier(Identifier::EmptyIdentifier)
-    , underscoreProto(vm, "__proto__")
-    , thisIdentifier(vm, "this")
-    , useStrictIdentifier(vm, "use strict")
+    , underscoreProto(Identifier::fromString(vm, "__proto__"))
+    , thisIdentifier(Identifier::fromString(vm, "this"))
+    , useStrictIdentifier(Identifier::fromString(vm, "use strict"))
     , m_builtinNames(new BuiltinNames(vm, this))
     JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(INITIALIZE_KEYWORD)
     JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PRIVATE_NAME)
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_SYMBOL)
+    , m_bytecodeIntrinsicRegistry(*this)
 {
 }
 
@@ -48,6 +52,21 @@ CommonIdentifiers::~CommonIdentifiers()
 {
 }
 
+bool CommonIdentifiers::isPrivateName(SymbolImpl& uid) const
+{
+    return m_builtinNames->isPrivateName(uid);
+}
+
+bool CommonIdentifiers::isPrivateName(UniquedStringImpl& uid) const
+{
+    return m_builtinNames->isPrivateName(uid);
+}
+
+bool CommonIdentifiers::isPrivateName(const Identifier& ident) const
+{
+    return m_builtinNames->isPrivateName(ident);
+}
+
 const Identifier* CommonIdentifiers::getPrivateName(const Identifier& ident) const
 {
     return m_builtinNames->getPrivateName(ident);
index 96f88f80f3199d74be4ac4a6a919fef6116cc0ce..41b94f1bf47bfc66d876450c01301e5521ff956d 100644 (file)
 #ifndef CommonIdentifiers_h
 #define CommonIdentifiers_h
 
+#include "BytecodeIntrinsicRegistry.h"
 #include "Identifier.h"
 #include <wtf/Noncopyable.h>
 
 // MarkedArgumentBuffer of property names, passed to a macro so we can do set them up various
 // ways without repeating the list.
 #define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
-    macro(ArgumentsIterator) \
     macro(Array) \
     macro(ArrayBuffer) \
     macro(ArrayIterator) \
@@ -38,6 +38,7 @@
     macro(EvalError) \
     macro(Function) \
     macro(Infinity) \
+    macro(Intl) \
     macro(JSON) \
     macro(Map)\
     macro(MapIterator)\
     macro(Set)\
     macro(SetIterator)\
     macro(String) \
+    macro(Symbol) \
     macro(SyntaxError) \
     macro(TypeError) \
     macro(URIError) \
     macro(UTC) \
     macro(WeakMap)\
+    macro(WeakSet)\
     macro(__defineGetter__) \
     macro(__defineSetter__) \
     macro(__lookupGetter__) \
     macro(__lookupSetter__) \
     macro(add) \
+    macro(additionalJettisonReason) \
     macro(anonymous) \
     macro(arguments) \
     macro(assign) \
     macro(bytecodesID) \
     macro(callee) \
     macro(caller) \
-    macro(cast) \
     macro(clear) \
     macro(close) \
     macro(closed) \
+    macro(column) \
     macro(compilationKind) \
     macro(compilations) \
     macro(compile) \
@@ -88,6 +92,7 @@
     macro(constructor) \
     macro(count) \
     macro(counters) \
+    macro(defineProperty) \
     macro(description) \
     macro(descriptions) \
     macro(displayName) \
     macro(exec) \
     macro(executionCount) \
     macro(exitKind) \
+    macro(flags) \
     macro(focus) \
     macro(forEach) \
     macro(forward) \
     macro(id) \
     macro(ignoreCase) \
     macro(index) \
+    macro(indexedDB) \
     macro(inferredName) \
     macro(input) \
     macro(instructionCount) \
     macro(keys) \
     macro(lastIndex) \
     macro(length) \
+    macro(line) \
     macro(message) \
     macro(multiline) \
     macro(name) \
     macro(osrExitSites) \
     macro(osrExits) \
     macro(parse) \
+    macro(parseInt) \
     macro(postMessage) \
     macro(profiledBytecodes) \
     macro(propertyIsEnumerable) \
     macro(prototype) \
+    macro(raw) \
     macro(reload) \
     macro(replace) \
+    macro(resolve) \
     macro(set) \
     macro(showModalDialog) \
     macro(size) \
     macro(slice) \
     macro(source) \
+    macro(sourceURL) \
     macro(sourceCode) \
     macro(stack) \
     macro(subarray) \
     macro(valueOf) \
     macro(values) \
     macro(webkit) \
+    macro(webkitIndexedDB) \
     macro(window) \
     macro(writable)
 
     macro(with) \
     macro(yield)
 
-#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
+#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
+    macro(hasInstance) \
+    macro(isConcatSpreadable) \
+    macro(match) \
+    macro(replace) \
+    macro(search) \
+    macro(species) \
+    macro(split) \
+    macro(toPrimitive) \
+    macro(toStringTag)
+
+#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
     macro(iterator) \
-    macro(iteratorNext) \
-    macro(resolve) \
-    macro(reject) \
+    macro(unscopables)
+
+#define JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(macro) \
+    macro(putByValDirect) \
+    macro(toString)
+
+#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
+    JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(macro) \
+    macro(symbolIterator) \
+    macro(iteratedObject) \
+    macro(arrayIteratorNextIndex) \
+    macro(arrayIterationKind) \
+    macro(arrayIterationKindKey) \
+    macro(arrayIterationKindValue) \
+    macro(arrayIterationKindKeyValue) \
+    macro(charCodeAt) \
+    macro(iteratedString) \
+    macro(stringIteratorNextIndex) \
     macro(promise) \
     macro(fulfillmentHandler) \
     macro(rejectionHandler) \
     macro(deferred) \
     macro(countdownHolder) \
     macro(Object) \
+    macro(objectKeys) \
+    macro(objectGetOwnPropertyDescriptor) \
+    macro(objectGetOwnPropertySymbols) \
+    macro(Number) \
+    macro(Array) \
+    macro(String) \
+    macro(Promise) \
+    macro(abs) \
+    macro(floor) \
+    macro(isFinite) \
+    macro(getPrototypeOf) \
+    macro(getOwnPropertyNames) \
     macro(TypeError) \
     macro(undefined) \
-    macro(BuiltinLog)
+    macro(BuiltinLog) \
+    macro(homeObject) \
+    macro(getTemplateObject) \
+    macro(enqueueJob) \
+    macro(handler) \
+    macro(promiseState) \
+    macro(promisePending) \
+    macro(promiseFulfilled) \
+    macro(promiseRejected) \
+    macro(promiseFulfillReactions) \
+    macro(promiseRejectReactions) \
+    macro(promiseResult) \
+    macro(capabilities) \
+
 
 namespace JSC {
     
@@ -269,9 +333,22 @@ namespace JSC {
 #define JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL(name) const Identifier name##PrivateName;
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL)
 #undef JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL
-        
+
+#define JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL(name) const Identifier name##Symbol;
+        JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL)
+#undef JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL
+
+        bool isPrivateName(SymbolImpl& uid) const;
+        bool isPrivateName(UniquedStringImpl& uid) const;
+        bool isPrivateName(const Identifier&) const;
+
         const Identifier* getPrivateName(const Identifier&) const;
         Identifier getPublicName(const Identifier&) const;
+
+        const BytecodeIntrinsicRegistry& bytecodeIntrinsicRegistry() const { return m_bytecodeIntrinsicRegistry; }
+
+    private:
+        BytecodeIntrinsicRegistry m_bytecodeIntrinsicRegistry;
     };
 
 } // namespace JSC
index 610b94b9143946129fee63401c58892dfc1776f8..56d46ed82b6758f91d3c2b2d04e27a00f1355e5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "config.h"
 #include "CommonSlowPaths.h"
-#include "Arguments.h"
 #include "ArityCheckFailReturnThunks.h"
 #include "ArrayConstructor.h"
 #include "CallFrame.h"
+#include "ClonedArguments.h"
 #include "CodeProfiling.h"
 #include "CommonSlowPathsExceptions.h"
+#include "DirectArguments.h"
+#include "Error.h"
 #include "ErrorHandlingScope.h"
+#include "ExceptionFuzz.h"
 #include "GetterSetter.h"
 #include "HostCallReturnValue.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITStubs.h"
-#include "JSActivation.h"
+#include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
-#include "JSPropertyNameIterator.h"
+#include "JSPropertyNameEnumerator.h"
 #include "JSString.h"
 #include "JSWithScope.h"
 #include "LLIntCommon.h"
 #include "LLIntExceptions.h"
 #include "LowLevelInterpreter.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
+#include "ScopedArguments.h"
 #include "StructureRareDataInlines.h"
-#include "VariableWatchpointSetInlines.h"
+#include "TypeProfilerLog.h"
 #include <wtf/StringPrintStream.h>
 
 namespace JSC {
@@ -92,6 +96,7 @@ namespace JSC {
     } while (false)
 
 #define CHECK_EXCEPTION() do {                    \
+        doExceptionFuzzingIfEnabled(exec, "CommonSlowPaths", pc);   \
         if (UNLIKELY(vm.exception())) {           \
             RETURN_TO_THROW(exec, pc);               \
             END_IMPL();                           \
@@ -163,7 +168,7 @@ static CommonSlowPaths::ArityCheckData* setupArityCheckData(VM& vm, int slotsToA
     result->paddedStackSpace = slotsToAdd;
 #if ENABLE(JIT)
     if (vm.canUseJIT()) {
-        result->thunkToCall = vm.getCTIStub(arityFixup).code().executableAddress();
+        result->thunkToCall = vm.getCTIStub(arityFixupGenerator).code().executableAddress();
         result->returnPC = vm.arityCheckFailReturnThunks->returnPCFor(vm, slotsToAdd * stackAlignmentRegisters()).executableAddress();
     } else
 #endif
@@ -200,29 +205,24 @@ SLOW_PATH_DECL(slow_path_construct_arityCheck)
     RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd));
 }
 
-SLOW_PATH_DECL(slow_path_touch_entry)
+SLOW_PATH_DECL(slow_path_create_direct_arguments)
 {
     BEGIN();
-    exec->codeBlock()->symbolTable()->m_functionEnteredOnce.touch();
-    END();
+    RETURN(DirectArguments::createByCopying(exec));
 }
 
-SLOW_PATH_DECL(slow_path_get_callee)
+SLOW_PATH_DECL(slow_path_create_scoped_arguments)
 {
     BEGIN();
-    JSFunction* callee = jsCast<JSFunction*>(exec->callee());
-    pc[2].u.jsCell.set(exec->vm(), exec->codeBlock()->ownerExecutable(), callee);
-    RETURN(callee);
+    JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue());
+    ScopedArgumentsTable* table = exec->codeBlock()->symbolTable()->arguments();
+    RETURN(ScopedArguments::createByCopying(exec, table, scope));
 }
 
-SLOW_PATH_DECL(slow_path_create_arguments)
+SLOW_PATH_DECL(slow_path_create_out_of_band_arguments)
 {
     BEGIN();
-    JSValue arguments = JSValue(Arguments::create(vm, exec));
-    CHECK_EXCEPTION();
-    exec->uncheckedR(pc[1].u.operand) = arguments;
-    exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()) = arguments;
-    END();
+    RETURN(ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned));
 }
 
 SLOW_PATH_DECL(slow_path_create_this)
@@ -235,8 +235,14 @@ SLOW_PATH_DECL(slow_path_create_this)
     ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
 #endif
 
+    auto& cacheWriteBarrier = pc[4].u.jsCell;
+    if (!cacheWriteBarrier)
+        cacheWriteBarrier.set(exec->vm(), exec->codeBlock()->ownerExecutable(), constructor);
+    else if (cacheWriteBarrier.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cacheWriteBarrier.get() != constructor)
+        cacheWriteBarrier.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
+
     size_t inlineCapacity = pc[3].u.operand;
-    Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure();
+    Structure* structure = constructor->rareData(exec, inlineCapacity)->allocationProfile()->structure();
     RETURN(constructEmptyObject(exec, structure));
 }
 
@@ -244,31 +250,25 @@ SLOW_PATH_DECL(slow_path_to_this)
 {
     BEGIN();
     JSValue v1 = OP(1).jsValue();
-    if (v1.isCell())
-        pc[2].u.structure.set(vm, exec->codeBlock()->ownerExecutable(), v1.asCell()->structure(vm));
-    else
+    if (v1.isCell()) {
+        Structure* myStructure = v1.asCell()->structure(vm);
+        Structure* otherStructure = pc[2].u.structure.get();
+        if (myStructure != otherStructure) {
+            if (otherStructure)
+                pc[3].u.toThisStatus = ToThisConflicted;
+            pc[2].u.structure.set(vm, exec->codeBlock()->ownerExecutable(), myStructure);
+        }
+    } else {
+        pc[3].u.toThisStatus = ToThisConflicted;
         pc[2].u.structure.clear();
+    }
     RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode));
 }
 
-SLOW_PATH_DECL(slow_path_captured_mov)
-{
-    BEGIN();
-    JSValue value = OP_C(2).jsValue();
-    if (VariableWatchpointSet* set = pc[3].u.watchpointSet)
-        set->notifyWrite(vm, value);
-    RETURN(value);
-}
-
-SLOW_PATH_DECL(slow_path_new_captured_func)
+SLOW_PATH_DECL(slow_path_throw_tdz_error)
 {
     BEGIN();
-    CodeBlock* codeBlock = exec->codeBlock();
-    ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
-    JSValue value = JSFunction::create(vm, codeBlock->functionDecl(pc[2].u.operand), exec->scope());
-    if (VariableWatchpointSet* set = pc[3].u.watchpointSet)
-        set->notifyWrite(vm, value);
-    RETURN(value);
+    THROW(createReferenceError(exec, "Cannot access uninitialized variable."));
 }
 
 SLOW_PATH_DECL(slow_path_not)
@@ -343,6 +343,12 @@ SLOW_PATH_DECL(slow_path_to_number)
     RETURN(jsNumber(OP_C(2).jsValue().toNumber(exec)));
 }
 
+SLOW_PATH_DECL(slow_path_to_string)
+{
+    BEGIN();
+    RETURN(OP_C(2).jsValue().toString(exec));
+}
+
 SLOW_PATH_DECL(slow_path_negate)
 {
     BEGIN();
@@ -461,10 +467,10 @@ SLOW_PATH_DECL(slow_path_typeof)
     RETURN(jsTypeStringForValue(exec, OP_C(2).jsValue()));
 }
 
-SLOW_PATH_DECL(slow_path_is_object)
+SLOW_PATH_DECL(slow_path_is_object_or_null)
 {
     BEGIN();
-    RETURN(jsBoolean(jsIsObjectType(exec, OP_C(2).jsValue())));
+    RETURN(jsBoolean(jsIsObjectTypeOrNull(exec, OP_C(2).jsValue())));
 }
 
 SLOW_PATH_DECL(slow_path_is_function)
@@ -492,11 +498,9 @@ SLOW_PATH_DECL(slow_path_del_by_val)
     uint32_t i;
     if (subscript.getUInt32(i))
         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
-    else if (isName(subscript))
-        couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     else {
         CHECK_EXCEPTION();
-        Identifier property(exec, subscript.toString(exec)->value(exec));
+        auto property = subscript.toPropertyKey(exec);
         CHECK_EXCEPTION();
         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
     }
@@ -527,4 +531,111 @@ SLOW_PATH_DECL(slow_path_enter)
     END();
 }
 
+SLOW_PATH_DECL(slow_path_get_enumerable_length)
+{
+    BEGIN();
+    JSValue enumeratorValue = OP(2).jsValue();
+    if (enumeratorValue.isUndefinedOrNull())
+        RETURN(jsNumber(0));
+
+    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorValue.asCell());
+
+    RETURN(jsNumber(enumerator->indexedLength()));
+}
+
+SLOW_PATH_DECL(slow_path_has_indexed_property)
+{
+    BEGIN();
+    JSObject* base = OP(2).jsValue().toObject(exec);
+    JSValue property = OP(3).jsValue();
+    pc[4].u.arrayProfile->observeStructure(base->structure(vm));
+    ASSERT(property.isUInt32());
+    RETURN(jsBoolean(base->hasProperty(exec, property.asUInt32())));
+}
+
+SLOW_PATH_DECL(slow_path_has_structure_property)
+{
+    BEGIN();
+    JSObject* base = OP(2).jsValue().toObject(exec);
+    JSValue property = OP(3).jsValue();
+    ASSERT(property.isString());
+    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell());
+    if (base->structure(vm)->id() == enumerator->cachedStructureID())
+        RETURN(jsBoolean(true));
+    RETURN(jsBoolean(base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec))));
+}
+
+SLOW_PATH_DECL(slow_path_has_generic_property)
+{
+    BEGIN();
+    JSObject* base = OP(2).jsValue().toObject(exec);
+    JSValue property = OP(3).jsValue();
+    bool result;
+    if (property.isString())
+        result = base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec));
+    else {
+        ASSERT(property.isUInt32());
+        result = base->hasProperty(exec, property.asUInt32());
+    }
+    RETURN(jsBoolean(result));
+}
+
+SLOW_PATH_DECL(slow_path_get_direct_pname)
+{
+    BEGIN();
+    JSValue baseValue = OP_C(2).jsValue();
+    JSValue property = OP(3).jsValue();
+    ASSERT(property.isString());
+    RETURN(baseValue.get(exec, asString(property)->toIdentifier(exec)));
+}
+
+SLOW_PATH_DECL(slow_path_get_property_enumerator)
+{
+    BEGIN();
+    JSValue baseValue = OP(2).jsValue();
+    if (baseValue.isUndefinedOrNull())
+        RETURN(JSPropertyNameEnumerator::create(vm));
+
+    JSObject* base = baseValue.toObject(exec);
+
+    RETURN(propertyNameEnumerator(exec, base));
+}
+
+SLOW_PATH_DECL(slow_path_next_structure_enumerator_pname)
+{
+    BEGIN();
+    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
+    uint32_t index = OP(3).jsValue().asUInt32();
+
+    JSString* propertyName = nullptr;
+    if (index < enumerator->endStructurePropertyIndex())
+        propertyName = enumerator->propertyNameAtIndex(index);
+    RETURN(propertyName ? propertyName : jsNull());
+}
+
+SLOW_PATH_DECL(slow_path_next_generic_enumerator_pname)
+{
+    BEGIN();
+    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
+    uint32_t index = OP(3).jsValue().asUInt32();
+
+    JSString* propertyName = nullptr;
+    if (enumerator->endStructurePropertyIndex() <= index && index < enumerator->endGenericPropertyIndex())
+        propertyName = enumerator->propertyNameAtIndex(index);
+    RETURN(propertyName ? propertyName : jsNull());
+}
+
+SLOW_PATH_DECL(slow_path_to_index_string)
+{
+    BEGIN();
+    RETURN(jsString(exec, Identifier::from(exec, OP(2).jsValue().asUInt32()).string()));
+}
+
+SLOW_PATH_DECL(slow_path_profile_type_clear_log)
+{
+    BEGIN();
+    vm.typeProfilerLog()->processLogEntries(ASCIILiteral("LLInt log full."));
+    END();
+}
+
 } // namespace JSC
index d8ce5fa13766960d65154e065a243e5072e7e826..4d8e3fc8e370f1ea90112e4beca4e843ee9d4770 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,8 +30,8 @@
 #include "CodeSpecializationKind.h"
 #include "ExceptionHelpers.h"
 #include "JSStackInlines.h"
-#include "NameInstance.h"
 #include "StackAlignment.h"
+#include "Symbol.h"
 #include "VM.h"
 #include <wtf/StdLibExtras.h>
 
@@ -72,7 +72,7 @@ ALWAYS_INLINE int arityCheckFor(ExecState* exec, JSStack* stack, CodeSpecializat
 inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
 {
     if (!baseVal.isObject()) {
-        exec->vm().throwException(exec, createInvalidParameterError(exec, "in", baseVal));
+        exec->vm().throwException(exec, createInvalidInParameterError(exec, baseVal));
         return false;
     }
 
@@ -82,15 +82,39 @@ inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
     if (propName.getUInt32(i))
         return baseObj->hasProperty(exec, i);
 
-    if (isName(propName))
-        return baseObj->hasProperty(exec, jsCast<NameInstance*>(propName.asCell())->privateName());
-
-    Identifier property(exec, propName.toString(exec)->value(exec));
+    auto property = propName.toPropertyKey(exec);
     if (exec->vm().exception())
         return false;
     return baseObj->hasProperty(exec, property);
 }
 
+inline void tryCachePutToScopeGlobal(
+    ExecState* exec, CodeBlock* codeBlock, Instruction* pc, JSObject* scope,
+    ResolveModeAndType modeAndType, PutPropertySlot& slot)
+{
+    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
+    
+    if (modeAndType.type() != GlobalProperty && modeAndType.type() != GlobalPropertyWithVarInjectionChecks)
+        return;
+    
+    if (!slot.isCacheablePut()
+        || slot.base() != scope
+        || !scope->structure()->propertyAccessesAreCacheable())
+        return;
+    
+    if (slot.type() == PutPropertySlot::NewProperty) {
+        // Don't cache if we've done a transition. We want to detect the first replace so that we
+        // can invalidate the watchpoint.
+        return;
+    }
+    
+    scope->structure()->didCachePropertyReplacement(exec->vm(), slot.cachedOffset());
+
+    ConcurrentJITLocker locker(codeBlock->m_lock);
+    pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
+    pc[6].u.operand = slot.cachedOffset();
+}
+
 } // namespace CommonSlowPaths
 
 class ExecState;
@@ -157,14 +181,14 @@ SLOW_PATH_DECL(name) WTF_INTERNAL
     
 SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck);
 SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
-SLOW_PATH_HIDDEN_DECL(slow_path_touch_entry);
-SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_direct_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_scoped_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_out_of_band_arguments);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_enter);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_callee);
 SLOW_PATH_HIDDEN_DECL(slow_path_to_this);
-SLOW_PATH_HIDDEN_DECL(slow_path_captured_mov);
-SLOW_PATH_HIDDEN_DECL(slow_path_new_captured_func);
+SLOW_PATH_HIDDEN_DECL(slow_path_throw_tdz_error);
 SLOW_PATH_HIDDEN_DECL(slow_path_not);
 SLOW_PATH_HIDDEN_DECL(slow_path_eq);
 SLOW_PATH_HIDDEN_DECL(slow_path_neq);
@@ -177,6 +201,7 @@ SLOW_PATH_HIDDEN_DECL(slow_path_greatereq);
 SLOW_PATH_HIDDEN_DECL(slow_path_inc);
 SLOW_PATH_HIDDEN_DECL(slow_path_dec);
 SLOW_PATH_HIDDEN_DECL(slow_path_to_number);
+SLOW_PATH_HIDDEN_DECL(slow_path_to_string);
 SLOW_PATH_HIDDEN_DECL(slow_path_negate);
 SLOW_PATH_HIDDEN_DECL(slow_path_add);
 SLOW_PATH_HIDDEN_DECL(slow_path_mul);
@@ -192,11 +217,22 @@ SLOW_PATH_HIDDEN_DECL(slow_path_bitor);
 SLOW_PATH_HIDDEN_DECL(slow_path_bitxor);
 SLOW_PATH_HIDDEN_DECL(slow_path_typeof);
 SLOW_PATH_HIDDEN_DECL(slow_path_is_object);
+SLOW_PATH_HIDDEN_DECL(slow_path_is_object_or_null);
 SLOW_PATH_HIDDEN_DECL(slow_path_is_function);
 SLOW_PATH_HIDDEN_DECL(slow_path_in);
 SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
 SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
 SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
+SLOW_PATH_HIDDEN_DECL(slow_path_get_enumerable_length);
+SLOW_PATH_HIDDEN_DECL(slow_path_has_generic_property);
+SLOW_PATH_HIDDEN_DECL(slow_path_has_structure_property);
+SLOW_PATH_HIDDEN_DECL(slow_path_has_indexed_property);
+SLOW_PATH_HIDDEN_DECL(slow_path_get_direct_pname);
+SLOW_PATH_HIDDEN_DECL(slow_path_get_property_enumerator);
+SLOW_PATH_HIDDEN_DECL(slow_path_next_structure_enumerator_pname);
+SLOW_PATH_HIDDEN_DECL(slow_path_next_generic_enumerator_pname);
+SLOW_PATH_HIDDEN_DECL(slow_path_to_index_string);
+SLOW_PATH_HIDDEN_DECL(slow_path_profile_type_clear_log);
 
 } // namespace JSC
 
index c414570dae6591b7334f09cbc4ad19ec674d2fc8..f67bc575af40a99b1c0e961682b73825db239d91 100644 (file)
@@ -26,6 +26,7 @@
 #include "CallFrame.h"
 #include "CodeProfiling.h"
 #include "Debugger.h"
+#include "Exception.h"
 #include "Interpreter.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
@@ -55,11 +56,12 @@ bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)
 {
     JSLockHolder lock(vm);
     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
-    RefPtr<ProgramNode> programNode = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
-    return programNode;
+    return !!parse<ProgramNode>(
+        &vm, source, 0, Identifier(), JSParserBuiltinMode::NotBuiltin, 
+        JSParserStrictMode::NotStrict, JSParserCodeType::Program, error);
 }
 
-JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, JSValue* returnedException)
+JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException)
 {
     JSLockHolder lock(exec);
     RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
@@ -69,9 +71,7 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, J
 
     ProgramExecutable* program = ProgramExecutable::create(exec, source);
     if (!program) {
-        if (returnedException)
-            *returnedException = exec->vm().exception();
-
+        returnedException = exec->vm().exception();
         exec->vm().clearException();
         return jsUndefined();
     }
@@ -82,9 +82,7 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, J
     JSValue result = exec->interpreter()->execute(program, exec, thisObj);
 
     if (exec->hadException()) {
-        if (returnedException)
-            *returnedException = exec->exception();
-
+        returnedException = exec->exception();
         exec->clearException();
         return jsUndefined();
     }
index 78f8ac795d8c782cd5cf582899f773ec4ec1cb1c..089911e0fd78eb5d1f98a0e23a3eef19a533ad7d 100644 (file)
 #define Completion_h
 
 #include "JSCJSValue.h"
+#include <wtf/NakedPtr.h>
 
 namespace JSC {
-    
-    struct ParserError;
-    class ExecState;
-    class JSScope;
-    class SourceCode;
-    class VM;
 
-    JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
-    JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
-    JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
+class Exception;
+class ExecState;
+class JSScope;
+class ParserError;
+class SourceCode;
+class VM;
+
+JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
+JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
+JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException);
+inline JSValue evaluate(ExecState* exec, const SourceCode& sourceCode, JSValue thisValue = JSValue())
+{
+    NakedPtr<Exception> unused;
+    return evaluate(exec, sourceCode, thisValue, unused);
+}
 
 } // namespace JSC
 
index c1b9f113f629beb8cc22126993265bf5af0aea3d..31b48b222f8a4ac28b1ac2ff0f1c3f943afac34c 100644 (file)
@@ -105,6 +105,9 @@ static void appendMessagePrefix(StringBuilder& builder, MessageSource source, Me
     case MessageLevel::Log:
         levelString = "LOG";
         break;
+    case MessageLevel::Info:
+        levelString = "INFO";
+        break;
     case MessageLevel::Warning:
         levelString = "WARN";
         break;
@@ -119,6 +122,8 @@ static void appendMessagePrefix(StringBuilder& builder, MessageSource source, Me
 
     if (type == MessageType::Trace)
         levelString = "TRACE";
+    else if (type == MessageType::Table)
+        levelString = "TABLE";
 
     builder.append(sourceString);
     builder.append(' ');
@@ -141,7 +146,7 @@ void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type,
     WTFLogAlways("%s", builder.toString().utf8().data());
 }
 
-void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments)
+void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments)
 {
     RefPtr<ScriptArguments> arguments = prpArguments;
 
@@ -186,7 +191,7 @@ void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, Messa
     }
 }
 
-void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments, ArgumentRequirement argumentRequirement)
+void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments, ArgumentRequirement argumentRequirement)
 {
     RefPtr<ScriptArguments> arguments = prpArguments;
     if (argumentRequirement == ArgumentRequired && !arguments->argumentCount())
@@ -195,57 +200,57 @@ void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLev
     messageWithTypeAndLevel(type, level, exec, arguments.release());
 }
 
-void ConsoleClient::logWithLevel(ExecState* exec, PassRefPtr<ScriptArguments> arguments, MessageLevel level)
+void ConsoleClient::logWithLevel(ExecState* exec, RefPtr<ScriptArguments>&& arguments, MessageLevel level)
 {
-    internalMessageWithTypeAndLevel(MessageType::Log, level, exec, arguments, ArgumentRequired);
+    internalMessageWithTypeAndLevel(MessageType::Log, level, exec, WTF::move(arguments), ArgumentRequired);
 }
 
-void ConsoleClient::clear(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::clear(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
-void ConsoleClient::dir(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::dir(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, arguments, ArgumentRequired);
+    internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
 }
 
-void ConsoleClient::dirXML(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::dirXML(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, arguments, ArgumentRequired);
+    internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
 }
 
-void ConsoleClient::table(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::table(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, arguments, ArgumentRequired);
+    internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired);
 }
 
-void ConsoleClient::trace(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::trace(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
-void ConsoleClient::assertCondition(ExecState* exec, PassRefPtr<ScriptArguments> arguments, bool condition)
+void ConsoleClient::assertCondition(ExecState* exec, RefPtr<ScriptArguments>&& arguments, bool condition)
 {
     if (condition)
         return;
 
-    internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
-void ConsoleClient::group(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::group(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
-void ConsoleClient::groupCollapsed(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::groupCollapsed(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
-void ConsoleClient::groupEnd(ExecState* exec, PassRefPtr<ScriptArguments> arguments)
+void ConsoleClient::groupEnd(ExecState* exec, RefPtr<ScriptArguments>&& arguments)
 {
-    internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired);
+    internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired);
 }
 
 } // namespace JSC
index a5f9e2005ad25a92e3688333de15823056f2eb61..a16b85bb4a4c713e5949e768eac1dc8bf515e43a 100644 (file)
@@ -27,7 +27,6 @@
 #define ConsoleClient_h
 
 #include "ConsoleTypes.h"
-#include "Profile.h"
 #include <wtf/Forward.h>
 
 namespace Inspector {
@@ -43,30 +42,30 @@ public:
     virtual ~ConsoleClient() { }
 
     JS_EXPORT_PRIVATE static void printConsoleMessage(MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber);
-    JS_EXPORT_PRIVATE static void printConsoleMessageWithArguments(MessageSource, MessageType, MessageLevel, JSC::ExecState*, PassRefPtr<Inspector::ScriptArguments>);
+    JS_EXPORT_PRIVATE static void printConsoleMessageWithArguments(MessageSource, MessageType, MessageLevel, JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&);
 
-    void logWithLevel(ExecState*, PassRefPtr<Inspector::ScriptArguments>, MessageLevel);
-    void clear(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void dir(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void dirXML(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void table(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void trace(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void assertCondition(ExecState*, PassRefPtr<Inspector::ScriptArguments>, bool condition);
-    void group(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void groupCollapsed(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
-    void groupEnd(ExecState*, PassRefPtr<Inspector::ScriptArguments>);
+    void logWithLevel(ExecState*, RefPtr<Inspector::ScriptArguments>&&, MessageLevel);
+    void clear(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void dir(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void dirXML(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void table(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void trace(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void assertCondition(ExecState*, RefPtr<Inspector::ScriptArguments>&&, bool condition);
+    void group(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void groupCollapsed(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
+    void groupEnd(ExecState*, RefPtr<Inspector::ScriptArguments>&&);
 
-    virtual void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, PassRefPtr<Inspector::ScriptArguments>) = 0;
-    virtual void count(ExecState*, PassRefPtr<Inspector::ScriptArguments>) = 0;
+    virtual void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&) = 0;
+    virtual void count(ExecState*, RefPtr<Inspector::ScriptArguments>&&) = 0;
     virtual void profile(ExecState*, const String& title) = 0;
     virtual void profileEnd(ExecState*, const String& title) = 0;
     virtual void time(ExecState*, const String& title) = 0;
     virtual void timeEnd(ExecState*, const String& title) = 0;
-    virtual void timeStamp(ExecState*, PassRefPtr<Inspector::ScriptArguments>) = 0;
+    virtual void timeStamp(ExecState*, RefPtr<Inspector::ScriptArguments>&&) = 0;
 
 private:
     enum ArgumentRequirement { ArgumentRequired, ArgumentNotRequired };
-    void internalMessageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, PassRefPtr<Inspector::ScriptArguments>, ArgumentRequirement);
+    void internalMessageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&, ArgumentRequirement);
 };
 
 } // namespace JSC
index a2a1ec620f5abaaa7ff03722b98f0032d5355091..7cad2c9deab987166bc5273549847c939c2d857d 100644 (file)
 
 namespace JSC {
 
-const ClassInfo ConsolePrototype::s_info = { "ConsolePrototype", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ConsolePrototype) };
+const ClassInfo ConsolePrototype::s_info = { "ConsolePrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(ConsolePrototype) };
 
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState*);
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState*);
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState*);
+static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState*);
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState*);
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState*);
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState*);
@@ -70,7 +71,7 @@ void ConsolePrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     JSC_NATIVE_FUNCTION("debug", consoleProtoFuncDebug, None, 0);
     JSC_NATIVE_FUNCTION("error", consoleProtoFuncError, None, 0);
     JSC_NATIVE_FUNCTION("log", consoleProtoFuncLog, None, 0);
-    JSC_NATIVE_FUNCTION("info", consoleProtoFuncLog, None, 0); // "info" is an alias of "log".
+    JSC_NATIVE_FUNCTION("info", consoleProtoFuncInfo, None, 0);
     JSC_NATIVE_FUNCTION("warn", consoleProtoFuncWarn, None, 0);
 
     JSC_NATIVE_FUNCTION("clear", consoleProtoFuncClear, None, 0);
@@ -127,6 +128,11 @@ static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState* exec)
     return consoleLogWithLevel(exec, MessageLevel::Log);
 }
 
+static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState* exec)
+{
+    return consoleLogWithLevel(exec, MessageLevel::Info);
+}
+
 static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState* exec)
 {
     return consoleLogWithLevel(exec, MessageLevel::Warning);
index 45c65f57823566134c7fa6237e628ecbcd03c2c6..c6ecabda931aeb6bdb3c6d0f914988c837376738 100644 (file)
@@ -38,6 +38,7 @@ enum class MessageSource {
     Rendering,
     CSS,
     Security,
+    ContentBlocker,
     Other,
 };
 
@@ -62,6 +63,7 @@ enum class MessageLevel {
     Warning = 2,
     Error = 3,
     Debug = 4,
+    Info = 5,
 };
 
 } // namespace JSC
diff --git a/runtime/ConstantMode.cpp b/runtime/ConstantMode.cpp
new file mode 100644 (file)
index 0000000..58ba794
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ConstantMode.h"
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, ConstantMode mode)
+{
+    switch (mode) {
+    case IsConstant:
+        out.print("Constant");
+        return;
+    case IsVariable:
+        out.print("Variable");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
index 389a074f9f4c124f696367ebbf1e5fff30202b12..a0496278a0fc1aa8a0553dde79c387b5b7279def 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef ConstantMode_h
 #define ConstantMode_h
 
+#include <wtf/PrintStream.h>
+
 namespace JSC {
 
 enum ConstantMode { IsConstant, IsVariable };
 
+inline ConstantMode modeForIsConstant(bool isConstant)
+{
+    return isConstant ? IsConstant : IsVariable;
+}
+
 } // namespace JSC
 
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::ConstantMode);
+
+} // namespace WTF
+
 #endif // ConstantMode_h
 
index 91b1e207d0eb5305fa817dbddf3d0fc8747d7d31..8d4ed8f28c7e1ecd879cbc0f2f4fefd14c4c1558 100644 (file)
 
 namespace JSC {
 
-    class ArgList;
-    class ExecState;
-    class FunctionExecutable;
-    class JSObject;
-    class JSScope;
-
-    enum ConstructType {
-        ConstructTypeNone,
-        ConstructTypeHost,
-        ConstructTypeJS
-    };
-
-    union ConstructData {
-        struct {
-            NativeFunction function;
-        } native;
-        struct {
-            FunctionExecutable* functionExecutable;
-            JSScope* scope;
-        } js;
-    };
-
-    JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
+class ArgList;
+class ExecState;
+class FunctionExecutable;
+class JSObject;
+class JSScope;
+
+enum ConstructType {
+    ConstructTypeNone,
+    ConstructTypeHost,
+    ConstructTypeJS
+};
+
+union ConstructData {
+    struct {
+        NativeFunction function;
+    } native;
+    struct {
+        FunctionExecutable* functionExecutable;
+        JSScope* scope;
+    } js;
+};
+
+JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
 
 } // namespace JSC
 
diff --git a/runtime/ControlFlowProfiler.cpp b/runtime/ControlFlowProfiler.cpp
new file mode 100644 (file)
index 0000000..d80e7f3
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Saam Barati. <saambarati1@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ControlFlowProfiler.h"
+
+#include "VM.h"
+
+namespace JSC {
+
+ControlFlowProfiler::ControlFlowProfiler()
+    : m_dummyBasicBlock(BasicBlockLocation(-1, -1))
+{
+}
+
+ControlFlowProfiler::~ControlFlowProfiler()
+{
+    for (const BlockLocationCache& cache : m_sourceIDBuckets.values()) {
+        for (BasicBlockLocation* block : cache.values())
+            delete block;
+    }
+}
+
+BasicBlockLocation* ControlFlowProfiler::getBasicBlockLocation(intptr_t sourceID, int startOffset, int endOffset)
+{
+    auto addResult = m_sourceIDBuckets.add(sourceID, BlockLocationCache());
+    BlockLocationCache& blockLocationCache = addResult.iterator->value;
+    BasicBlockKey key(startOffset, endOffset);
+    auto addResultForBasicBlock = blockLocationCache.add(key, nullptr);
+    if (addResultForBasicBlock.isNewEntry)
+        addResultForBasicBlock.iterator->value = new BasicBlockLocation(startOffset, endOffset);
+    return addResultForBasicBlock.iterator->value;
+}
+
+void ControlFlowProfiler::dumpData() const
+{
+    auto iter = m_sourceIDBuckets.begin();
+    auto end = m_sourceIDBuckets.end();
+    for (; iter != end; ++iter) {
+        dataLog("SourceID: ", iter->key, "\n");
+        for (const BasicBlockLocation* block : iter->value.values())
+            block->dumpData();
+    }
+}
+
+Vector<BasicBlockRange> ControlFlowProfiler::getBasicBlocksForSourceID(intptr_t sourceID, VM& vm) const 
+{
+    Vector<BasicBlockRange> result(0);
+    auto bucketFindResult = m_sourceIDBuckets.find(sourceID);
+    if (bucketFindResult == m_sourceIDBuckets.end())
+        return result;
+
+    const BlockLocationCache& cache = bucketFindResult->value;
+    for (const BasicBlockLocation* block : cache.values()) {
+        bool hasExecuted = block->hasExecuted();
+        const Vector<BasicBlockLocation::Gap>& blockRanges = block->getExecutedRanges();
+        for (BasicBlockLocation::Gap gap : blockRanges) {
+            BasicBlockRange range;
+            range.m_hasExecuted = hasExecuted;
+            range.m_startOffset = gap.first;
+            range.m_endOffset = gap.second;
+            result.append(range);
+        }
+    }
+
+    const Vector<std::tuple<bool, unsigned, unsigned>>& unexecutedFunctionRanges = vm.functionHasExecutedCache()->getFunctionRanges(sourceID);
+    for (const auto& functionRange : unexecutedFunctionRanges) {
+        BasicBlockRange range;
+        range.m_hasExecuted = std::get<0>(functionRange);
+        range.m_startOffset = static_cast<int>(std::get<1>(functionRange));
+        range.m_endOffset = static_cast<int>(std::get<2>(functionRange));
+        result.append(range);
+    }
+
+    return result;
+}
+
+bool ControlFlowProfiler::hasBasicBlockAtTextOffsetBeenExecuted(int offset, intptr_t sourceID, VM& vm)
+{
+    const Vector<BasicBlockRange>& blocks = getBasicBlocksForSourceID(sourceID, vm);
+    int bestDistance = INT_MAX;
+    BasicBlockRange bestRange;
+    bestRange.m_startOffset = bestRange.m_endOffset = -1;
+    bestRange.m_hasExecuted = false; // Suppress MSVC warning.
+    // Because some ranges may overlap because of function boundaries, make sure to find the smallest range enclosing the offset.
+    for (BasicBlockRange range : blocks) {
+        if (range.m_startOffset <= offset && offset <= range.m_endOffset && (range.m_endOffset - range.m_startOffset) < bestDistance) {
+            RELEASE_ASSERT(range.m_endOffset - range.m_startOffset >= 0);
+            bestDistance = range.m_endOffset - range.m_startOffset;
+            bestRange = range;
+        }
+    }
+
+    RELEASE_ASSERT(bestRange.m_startOffset != -1 && bestRange.m_endOffset != -1);
+    return bestRange.m_hasExecuted;
+}
+
+} // namespace JSC
diff --git a/runtime/ControlFlowProfiler.h b/runtime/ControlFlowProfiler.h
new file mode 100644 (file)
index 0000000..e745b2d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Saam Barati. <saambarati1@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ControlFlowProfiler_h
+#define ControlFlowProfiler_h
+
+#include "BasicBlockLocation.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashMethod.h>
+
+namespace JSC {
+
+class VM;
+
+struct BasicBlockKey {
+    BasicBlockKey()
+        : m_startOffset(-3)
+        , m_endOffset(-3)
+    { }
+
+    BasicBlockKey(int startOffset, int endOffset)
+        : m_startOffset(startOffset)
+        , m_endOffset(endOffset)
+    { }
+
+    BasicBlockKey(WTF::HashTableDeletedValueType)
+        : m_startOffset(-2)
+        , m_endOffset(-2)
+    { }
+
+    bool isHashTableDeletedValue() const { return m_startOffset == -2 && m_endOffset == -2; }
+    bool operator==(const BasicBlockKey& other) const { return m_startOffset == other.m_startOffset && m_endOffset == other.m_endOffset; }
+    unsigned hash() const { return m_startOffset + m_endOffset + 1; }
+
+    int m_startOffset;
+    int m_endOffset;
+};
+
+struct BasicBlockKeyHash {
+    static unsigned hash(const BasicBlockKey& key) { return key.hash(); }
+    static bool equal(const BasicBlockKey& a, const BasicBlockKey& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::BasicBlockKey> {
+    typedef JSC::BasicBlockKeyHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::BasicBlockKey> : SimpleClassHashTraits<JSC::BasicBlockKey> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+namespace JSC {
+
+struct BasicBlockRange {
+    int m_startOffset;
+    int m_endOffset;
+    bool m_hasExecuted;
+};
+
+class ControlFlowProfiler {
+public:
+    ControlFlowProfiler();
+    ~ControlFlowProfiler();
+    BasicBlockLocation* getBasicBlockLocation(intptr_t sourceID, int startOffset, int endOffset);
+    JS_EXPORT_PRIVATE void dumpData() const;
+    Vector<BasicBlockRange> getBasicBlocksForSourceID(intptr_t sourceID, VM&) const;
+    BasicBlockLocation* dummyBasicBlock() { return &m_dummyBasicBlock; }
+    JS_EXPORT_PRIVATE bool hasBasicBlockAtTextOffsetBeenExecuted(int, intptr_t, VM&); // This function exists for testing.
+
+private:
+    typedef HashMap<BasicBlockKey, BasicBlockLocation*> BlockLocationCache;
+    typedef HashMap<intptr_t, BlockLocationCache> SourceIDBuckets;
+
+    SourceIDBuckets m_sourceIDBuckets;
+    BasicBlockLocation m_dummyBasicBlock;
+};
+
+} // namespace JSC
+
+#endif // ControlFlowProfiler_h
index 92b0219c70877691fd7aeb843647cafa085075d0..0f9e1afa99982a9a9c9bf2628cf0d3f3f28c9550 100644 (file)
@@ -34,7 +34,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(CustomGetterSetter);
 
-const ClassInfo CustomGetterSetter::s_info = { "CustomGetterSetter", 0, 0, 0, CREATE_METHOD_TABLE(CustomGetterSetter) };
+const ClassInfo CustomGetterSetter::s_info = { "CustomGetterSetter", 0, 0, CREATE_METHOD_TABLE(CustomGetterSetter) };
 
 void callCustomSetter(ExecState* exec, JSValue customGetterSetter, JSObject* base, JSValue thisValue, JSValue value)
 {
index 4de7ded9815680a90f56d4433807cf0867ecb7c2..54519eba38c05733397208208de07fad9bf52ff8 100644 (file)
 
 namespace JSC {
 
-class CustomGetterSetter : public JSCell {
+class CustomGetterSetter final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     typedef PropertySlot::GetValueFunc CustomGetter;
     typedef PutPropertySlot::PutValueFunc CustomSetter;
index 0c83d6e95b0e24c49ea4f990948f12e4a4ca02b7..78e743fc15f80bbff526f8e77369e3b016477adf 100644 (file)
@@ -37,13 +37,13 @@ DataView::DataView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned
 {
 }
 
-PassRefPtr<DataView> DataView::create(
+Ref<DataView> DataView::create(
     PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
 {
-    return adoptRef(new DataView(buffer, byteOffset, byteLength));
+    return adoptRef(*new DataView(buffer, byteOffset, byteLength));
 }
 
-PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> passedBuffer)
+Ref<DataView> DataView::create(PassRefPtr<ArrayBuffer> passedBuffer)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
     return create(buffer, 0, buffer->byteLength());
index 4a8aa9258ad119b574923b878756ea88a40b068c..a01d1350669f3c75ecaa57dcb24643a70cef0c14 100644 (file)
@@ -37,8 +37,8 @@ protected:
     DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
     
 public:
-    JS_EXPORT_PRIVATE static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
-    static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>);
+    JS_EXPORT_PRIVATE static Ref<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
+    static Ref<DataView> create(PassRefPtr<ArrayBuffer>);
     
     virtual unsigned byteLength() const override
     {
index 476a31b23a536affc581584fdcce2e6056c00b87..d6329fdf1b0250d7824c8c8bd70dd6870472b4fc 100644 (file)
 #include "JSReplayInputs.h"
 #endif
 
-#if OS(WINCE)
-extern "C" time_t time(time_t* timer); // Provided by libce.
-#endif
-
 #if HAVE(SYS_TIME_H)
 #include <sys/time.h>
 #endif
@@ -56,9 +52,9 @@ using namespace WTF;
 
 namespace JSC {
 
-static EncodedJSValue JSC_HOST_CALL dateParse(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateParse(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateNow(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*);
 
 }
 
@@ -66,7 +62,7 @@ static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*);
 
 namespace JSC {
 
-const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::dateConstructorTable, CREATE_METHOD_TABLE(DateConstructor) };
+const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_info, &dateConstructorTable, CREATE_METHOD_TABLE(DateConstructor) };
 
 /* Source for DateConstructor.lut.h
 @begin dateConstructorTable
@@ -114,7 +110,7 @@ void DateConstructor::finishCreation(VM& vm, DatePrototype* datePrototype)
 
 bool DateConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<InternalFunction>(exec, ExecState::dateConstructorTable(exec->vm()), jsCast<DateConstructor*>(object), propertyName, slot);
+    return getStaticFunctionSlot<InternalFunction>(exec, dateConstructorTable, jsCast<DateConstructor*>(object), propertyName, slot);
 }
 
 // ECMA 15.9.3
@@ -166,7 +162,7 @@ JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const Arg
             t.setSecond(JSC::toInt32(doubleArguments[5]));
             t.setIsDST(-1);
             double ms = (numArgs >= 7) ? doubleArguments[6] : 0;
-            value = gregorianDateTimeToMS(vm, t, ms, false);
+            value = gregorianDateTimeToMS(vm, t, ms, WTF::LocalTime);
         }
     }
 
@@ -190,7 +186,7 @@ static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec)
 {
     VM& vm = exec->vm();
     GregorianDateTime ts;
-    msToGregorianDateTime(vm, currentTimeMS(), false, ts);
+    msToGregorianDateTime(vm, currentTimeMS(), WTF::LocalTime, ts);
     return JSValue::encode(jsNontrivialString(&vm, formatDateTime(ts, DateTimeFormatDateAndTime, false)));
 }
 
@@ -200,12 +196,12 @@ CallType DateConstructor::getCallData(JSCell*, CallData& callData)
     return CallTypeHost;
 }
 
-static EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec)
 {
     return JSValue::encode(jsNumber(parseDate(exec->vm(), exec->argument(0).toString(exec)->value(exec))));
 }
 
-static EncodedJSValue JSC_HOST_CALL dateNow(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dateNow(ExecState* exec)
 {
 #if !ENABLE(WEB_REPLAY)
     UNUSED_PARAM(exec);
@@ -214,7 +210,7 @@ static EncodedJSValue JSC_HOST_CALL dateNow(ExecState* exec)
     return JSValue::encode(jsNumber(NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(exec->lexicalGlobalObject()))));
 }
 
-static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec) 
+EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec) 
 {
     double doubleArguments[7] = {
         exec->argument(0).toNumber(exec), 
@@ -244,7 +240,7 @@ static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec)
     t.setMinute(JSC::toInt32(doubleArguments[4]));
     t.setSecond(JSC::toInt32(doubleArguments[5]));
     double ms = (n >= 7) ? doubleArguments[6] : 0;
-    return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec->vm(), t, ms, true))));
+    return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec->vm(), t, ms, WTF::UTCTime))));
 }
 
 } // namespace JSC
index 383e6f1b3fd59958caa92d0133241d684b888f8c..054f571d579e8ce4f34b540917b8d028b50dfb9b 100644 (file)
 
 namespace JSC {
 
-    class DatePrototype;
+class DatePrototype;
 
-    class DateConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class DateConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
-        static DateConstructor* create(VM& vm, Structure* structure, DatePrototype* datePrototype)
-        {
-            DateConstructor* constructor = new (NotNull, allocateCell<DateConstructor>(vm.heap)) DateConstructor(vm, structure);
-            constructor->finishCreation(vm, datePrototype);
-            return constructor;
-        }
+    static DateConstructor* create(VM& vm, Structure* structure, DatePrototype* datePrototype)
+    {
+        DateConstructor* constructor = new (NotNull, allocateCell<DateConstructor>(vm.heap)) DateConstructor(vm, structure);
+        constructor->finishCreation(vm, datePrototype);
+        return constructor;
+    }
 
-        DECLARE_INFO;
+    DECLARE_INFO;
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-    protected:
-        void finishCreation(VM&, DatePrototype*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
+protected:
+    void finishCreation(VM&, DatePrototype*);
 
-    private:
-        DateConstructor(VM&, Structure*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
+private:
+    DateConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
 
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    };
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
 
-    JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
+JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
 
 } // namespace JSC
 
index 8ea4c17adbd2aba3438645c200b17cf2c95cbffa..80a29c8239e77898a654c996b354bd9b53787616 100644 (file)
@@ -39,7 +39,7 @@ enum DateTimeFormat {
     DateTimeFormatDateAndTime = DateTimeFormatDate | DateTimeFormatTime
 };
 
-WTF::String formatDateTime(const GregorianDateTime&, DateTimeFormat, bool asUTCVariant);
+JS_EXPORT_PRIVATE WTF::String formatDateTime(const GregorianDateTime&, DateTimeFormat, bool asUTCVariant);
 
 } // namespace JSC
 
index d0317c2edb891520ceef376ddb52c25ec25fe663..e095f882c8ae337ef86c65f1ea792c92e0ac9f72 100644 (file)
@@ -32,7 +32,7 @@ using namespace WTF;
 
 namespace JSC {
 
-const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(DateInstance)};
+const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(DateInstance)};
 
 DateInstance::DateInstance(VM& vm, Structure* structure)
     : JSWrapperObject(vm, structure)
@@ -69,7 +69,7 @@ const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exe
         m_data = vm.dateInstanceCache.add(milli);
 
     if (m_data->m_gregorianDateTimeCachedForMS != milli) {
-        msToGregorianDateTime(vm, milli, false, m_data->m_cachedGregorianDateTime);
+        msToGregorianDateTime(vm, milli, WTF::LocalTime, m_data->m_cachedGregorianDateTime);
         m_data->m_gregorianDateTimeCachedForMS = milli;
     }
     return &m_data->m_cachedGregorianDateTime;
@@ -86,7 +86,7 @@ const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(ExecState*
         m_data = vm.dateInstanceCache.add(milli);
 
     if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
-        msToGregorianDateTime(vm, milli, true, m_data->m_cachedGregorianDateTimeUTC);
+        msToGregorianDateTime(vm, milli, WTF::UTCTime, m_data->m_cachedGregorianDateTimeUTC);
         m_data->m_gregorianDateTimeUTCCachedForMS = milli;
     }
     return &m_data->m_cachedGregorianDateTimeUTC;
index 193e054216af975351dbbb4984b9e3173669850f..000e1a15777a73de34703e69581df0fb81eceda6 100644 (file)
 
 namespace JSC {
 
-    class DateInstance : public JSWrapperObject {
-    protected:
-        JS_EXPORT_PRIVATE DateInstance(VM&, Structure*);
-        void finishCreation(VM&);
-        JS_EXPORT_PRIVATE void finishCreation(VM&, double);
-
-        static void destroy(JSCell*);
-    public:
-        typedef JSWrapperObject Base;
-
-        static DateInstance* create(VM& vm, Structure* structure, double date)
-        {
-            DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
-            instance->finishCreation(vm, date);
-            return instance;
-        }
-
-        static DateInstance* create(VM& vm, Structure* structure)
-        {
-            DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
-            instance->finishCreation(vm);
-            return instance;
-        }
-
-        double internalNumber() const { return internalValue().asNumber(); }
-
-        DECLARE_EXPORT_INFO;
-
-        const GregorianDateTime* gregorianDateTime(ExecState* exec) const
-        {
-            if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
-                return &m_data->m_cachedGregorianDateTime;
-            return calculateGregorianDateTime(exec);
-        }
-        
-        const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
-        {
-            if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
-                return &m_data->m_cachedGregorianDateTimeUTC;
-            return calculateGregorianDateTimeUTC(exec);
-        }
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    private:
-        const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
-        const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
-
-        mutable RefPtr<DateInstanceData> m_data;
-    };
-
-    DateInstance* asDateInstance(JSValue);
-
-    inline DateInstance* asDateInstance(JSValue value)
+class DateInstance : public JSWrapperObject {
+protected:
+    JS_EXPORT_PRIVATE DateInstance(VM&, Structure*);
+    void finishCreation(VM&);
+    JS_EXPORT_PRIVATE void finishCreation(VM&, double);
+
+    JS_EXPORT_PRIVATE static void destroy(JSCell*);
+
+public:
+    typedef JSWrapperObject Base;
+
+    static DateInstance* create(VM& vm, Structure* structure, double date)
+    {
+        DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
+        instance->finishCreation(vm, date);
+        return instance;
+    }
+
+    static DateInstance* create(VM& vm, Structure* structure)
+    {
+        DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
+        instance->finishCreation(vm);
+        return instance;
+    }
+
+    double internalNumber() const { return internalValue().asNumber(); }
+
+    DECLARE_EXPORT_INFO;
+
+    const GregorianDateTime* gregorianDateTime(ExecState* exec) const
     {
-        ASSERT(asObject(value)->inherits(DateInstance::info()));
-        return static_cast<DateInstance*>(asObject(value));
+        if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
+            return &m_data->m_cachedGregorianDateTime;
+        return calculateGregorianDateTime(exec);
     }
 
+    const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
+    {
+        if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
+            return &m_data->m_cachedGregorianDateTimeUTC;
+        return calculateGregorianDateTimeUTC(exec);
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
+    JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
+
+    mutable RefPtr<DateInstanceData> m_data;
+};
+
+DateInstance* asDateInstance(JSValue);
+
+inline DateInstance* asDateInstance(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(DateInstance::info()));
+    return static_cast<DateInstance*>(asObject(value));
+}
+
 } // namespace JSC
 
 #endif // DateInstance_h
index 07053062eeabcdf5878ca0b585f94f6b4c04d39f..865ee8ff20b9e85ef3b7ff0446791e9488ee19b4 100644 (file)
 #include "JSDateMath.h"
 #include <array>
 #include <wtf/HashFunctions.h>
-#include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 
 namespace JSC {
 
-    class DateInstanceData : public RefCounted<DateInstanceData> {
-    public:
-        static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
-
-        double m_gregorianDateTimeCachedForMS;
-        GregorianDateTime m_cachedGregorianDateTime;
-        double m_gregorianDateTimeUTCCachedForMS;
-        GregorianDateTime m_cachedGregorianDateTimeUTC;
-
-    private:
-        DateInstanceData()
-            : m_gregorianDateTimeCachedForMS(PNaN)
-            , m_gregorianDateTimeUTCCachedForMS(PNaN)
-        {
-        }
-    };
+class DateInstanceData : public RefCounted<DateInstanceData> {
+public:
+    static Ref<DateInstanceData> create() { return adoptRef(*new DateInstanceData); }
 
-    class DateInstanceCache {
-    public:
-        DateInstanceCache()
-        {
-            reset();
-        }
-        
-        void reset()
-        {
-            for (size_t i = 0; i < cacheSize; ++i)
-                m_cache[i].key = PNaN;
-        }
-        
-        DateInstanceData* add(double d)
-        {
-            CacheEntry& entry = lookup(d);
-            if (d == entry.key)
-                return entry.value.get();
-
-            entry.key = d;
-            entry.value = DateInstanceData::create();
-            return entry.value.get();
-        }
+    double m_gregorianDateTimeCachedForMS;
+    GregorianDateTime m_cachedGregorianDateTime;
+    double m_gregorianDateTimeUTCCachedForMS;
+    GregorianDateTime m_cachedGregorianDateTimeUTC;
+
+private:
+    DateInstanceData()
+        : m_gregorianDateTimeCachedForMS(PNaN)
+        , m_gregorianDateTimeUTCCachedForMS(PNaN)
+    {
+    }
+};
+
+class DateInstanceCache {
+public:
+    DateInstanceCache()
+    {
+        reset();
+    }
 
-    private:
-        static const size_t cacheSize = 16;
+    void reset()
+    {
+        for (size_t i = 0; i < cacheSize; ++i)
+            m_cache[i].key = PNaN;
+    }
 
-        struct CacheEntry {
-            double key;
-            RefPtr<DateInstanceData> value;
-        };
+    DateInstanceData* add(double d)
+    {
+        CacheEntry& entry = lookup(d);
+        if (d == entry.key)
+            return entry.value.get();
+
+        entry.key = d;
+        entry.value = DateInstanceData::create();
+        return entry.value.get();
+    }
 
-        CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
+private:
+    static const size_t cacheSize = 16;
 
-        std::array<CacheEntry, cacheSize> m_cache;
+    struct CacheEntry {
+        double key;
+        RefPtr<DateInstanceData> value;
     };
 
+    CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
+
+    std::array<CacheEntry, cacheSize> m_cache;
+};
+
 } // namespace JSC
 
 #endif // DateInstanceCache_h
index 9cd736acc845ec090676bc65d8d806bd236c6fb3..77db102f0f226a4d67dbc08bfe0d95441ef3605e 100644 (file)
@@ -70,51 +70,51 @@ using namespace WTF;
 
 namespace JSC {
 
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState*);
+EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState*);
 
 }
 
@@ -425,7 +425,7 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, int maxArgs, double *ms
     return ok;
 }
 
-const ClassInfo DatePrototype::s_info = {"Date", &DateInstance::s_info, 0, ExecState::dateTable, CREATE_METHOD_TABLE(DatePrototype)};
+const ClassInfo DatePrototype::s_info = {"Date", &DateInstance::s_info, &dateTable, CREATE_METHOD_TABLE(DatePrototype)};
 
 /* Source for DatePrototype.lut.h
 @begin dateTable
@@ -495,7 +495,7 @@ void DatePrototype::finishCreation(VM& vm, JSGlobalObject*)
 
 bool DatePrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec->vm()), jsCast<DatePrototype*>(object), propertyName, slot);
+    return getStaticFunctionSlot<JSObject>(exec, dateTable, jsCast<DatePrototype*>(object), propertyName, slot);
 }
 
 // Functions
@@ -859,7 +859,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec)
     return JSValue::encode(result);
 }
 
-static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
+static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, WTF::TimeType inputTimeType)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.inherits(DateInstance::info()))
@@ -878,7 +878,7 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
     double secs = floor(milli / msPerSecond);
     double ms = milli - secs * msPerSecond;
 
-    const GregorianDateTime* other = inputIsUTC 
+    const GregorianDateTime* other = inputTimeType == WTF::UTCTime
         ? thisDateObj->gregorianDateTimeUTC(exec)
         : thisDateObj->gregorianDateTime(exec);
     if (!other)
@@ -892,12 +892,12 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
         return JSValue::encode(result);
     } 
     
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputTimeType));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }
 
-static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC)
+static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, WTF::TimeType inputTimeType)
 {
     JSValue thisValue = exec->thisValue();
     if (!thisValue.inherits(DateInstance::info()))
@@ -916,10 +916,10 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
 
     GregorianDateTime gregorianDateTime; 
     if (numArgsToUse == 3 && std::isnan(milli)) 
-        msToGregorianDateTime(vm, 0, true, gregorianDateTime);
+        msToGregorianDateTime(vm, 0, WTF::UTCTime, gregorianDateTime);
     else { 
         ms = milli - floor(milli / msPerSecond) * msPerSecond; 
-        const GregorianDateTime* other = inputIsUTC 
+        const GregorianDateTime* other = inputTimeType == WTF::UTCTime
             ? thisDateObj->gregorianDateTimeUTC(exec)
             : thisDateObj->gregorianDateTime(exec);
         if (!other)
@@ -933,93 +933,79 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
         return JSValue::encode(result);
     } 
            
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputTimeType));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 1, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 1, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 1, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 1, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 2, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 2, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 2, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 2, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 3, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 3, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 3, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 3, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromTimeArgs(exec, 4, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 4, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromTimeArgs(exec, 4, inputIsUTC);
+    return setNewValueFromTimeArgs(exec, 4, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 1, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 1, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 1, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 1, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 2, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 2, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 2, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 2, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec)
 {
-    const bool inputIsUTC = false;
-    return setNewValueFromDateArgs(exec, 3, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 3, WTF::LocalTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec)
 {
-    const bool inputIsUTC = true;
-    return setNewValueFromDateArgs(exec, 3, inputIsUTC);
+    return setNewValueFromDateArgs(exec, 3, WTF::UTCTime);
 }
 
 EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
@@ -1043,7 +1029,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
     if (std::isnan(milli))
         // Based on ECMA 262 B.2.5 (setYear)
         // the time must be reset to +0 if it is NaN.
-        msToGregorianDateTime(vm, 0, true, gregorianDateTime);
+        msToGregorianDateTime(vm, 0, WTF::UTCTime, gregorianDateTime);
     else {
         double secs = floor(milli / msPerSecond);
         ms = milli - secs * msPerSecond;
@@ -1059,7 +1045,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
     }
 
     gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year));
-    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, false));
+    JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, WTF::LocalTime));
     thisDateObj->setInternalValue(vm, result);
     return JSValue::encode(result);
 }
index a9bfbd47733503d3ebeac4901a664dcaefc6e837..6714d7e3664b4adb07147e60670bbf26590f859d 100644 (file)
 
 namespace JSC {
 
-    class ObjectPrototype;
-
-    class DatePrototype : public DateInstance {
-    private:
-        DatePrototype(VM&, Structure*);
-
-    public:
-        typedef DateInstance Base;
-
-        static DatePrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-        {
-            DatePrototype* prototype = new (NotNull, allocateCell<DatePrototype>(vm.heap)) DatePrototype(vm, structure);
-            prototype->finishCreation(vm, globalObject);
-            return prototype;
-        }
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        void finishCreation(VM&, JSGlobalObject*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
-    };
+class ObjectPrototype;
+
+class DatePrototype : public DateInstance {
+private:
+    DatePrototype(VM&, Structure*);
+
+public:
+    typedef DateInstance Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static DatePrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        DatePrototype* prototype = new (NotNull, allocateCell<DatePrototype>(vm.heap)) DatePrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
+};
 
 } // namespace JSC
 
diff --git a/runtime/DirectArguments.cpp b/runtime/DirectArguments.cpp
new file mode 100644 (file)
index 0000000..bb61e4f
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DirectArguments.h"
+
+#include "CopyVisitorInlines.h"
+#include "GenericArgumentsInlines.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DirectArguments);
+
+const ClassInfo DirectArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(DirectArguments) };
+
+DirectArguments::DirectArguments(VM& vm, Structure* structure, unsigned length, unsigned capacity)
+    : GenericArguments(vm, structure)
+    , m_length(length)
+    , m_minCapacity(capacity)
+{
+    // When we construct the object from C++ code, we expect the capacity to be at least as large as
+    // length. JIT-allocated DirectArguments objects play evil tricks, though.
+    ASSERT(capacity >= length);
+}
+
+DirectArguments* DirectArguments::createUninitialized(
+    VM& vm, Structure* structure, unsigned length, unsigned capacity)
+{
+    DirectArguments* result =
+        new (NotNull, allocateCell<DirectArguments>(vm.heap, allocationSize(capacity)))
+        DirectArguments(vm, structure, length, capacity);
+    result->finishCreation(vm);
+    return result;
+}
+
+DirectArguments* DirectArguments::create(VM& vm, Structure* structure, unsigned length, unsigned capacity)
+{
+    DirectArguments* result = createUninitialized(vm, structure, length, capacity);
+    
+    for (unsigned i = capacity; i--;)
+        result->storage()[i].clear();
+    
+    return result;
+}
+
+DirectArguments* DirectArguments::createByCopying(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    
+    unsigned length = exec->argumentCount();
+    unsigned capacity = std::max(length, static_cast<unsigned>(exec->codeBlock()->numParameters() - 1));
+    DirectArguments* result = createUninitialized(
+        vm, exec->lexicalGlobalObject()->directArgumentsStructure(), length, capacity);
+    
+    for (unsigned i = capacity; i--;)
+        result->storage()[i].set(vm, result, exec->getArgumentUnsafe(i));
+    
+    result->callee().set(vm, result, jsCast<JSFunction*>(exec->callee()));
+    
+    return result;
+}
+
+void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
+{
+    DirectArguments* thisObject = static_cast<DirectArguments*>(thisCell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    
+    visitor.appendValues(thisObject->storage(), std::max(thisObject->m_length, thisObject->m_minCapacity));
+    visitor.append(&thisObject->m_callee);
+    
+    if (thisObject->m_overrides) {
+        visitor.copyLater(
+            thisObject, DirectArgumentsOverridesCopyToken,
+            thisObject->m_overrides.get(), thisObject->overridesSize());
+    }
+}
+
+void DirectArguments::copyBackingStore(JSCell* thisCell, CopyVisitor& visitor, CopyToken token)
+{
+    DirectArguments* thisObject = static_cast<DirectArguments*>(thisCell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    
+    RELEASE_ASSERT(token == DirectArgumentsOverridesCopyToken);
+    
+    bool* oldOverrides = thisObject->m_overrides.get();
+    if (!oldOverrides)
+        return;
+    
+    if (visitor.checkIfShouldCopy(oldOverrides)) {
+        bool* newOverrides = static_cast<bool*>(visitor.allocateNewSpace(thisObject->overridesSize()));
+        memcpy(newOverrides, oldOverrides, thisObject->m_length);
+        thisObject->m_overrides.setWithoutWriteBarrier(newOverrides);
+        visitor.didCopy(oldOverrides, thisObject->overridesSize());
+    }
+}
+
+Structure* DirectArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(DirectArgumentsType, StructureFlags), info());
+}
+
+void DirectArguments::overrideThings(VM& vm)
+{
+    RELEASE_ASSERT(!m_overrides);
+    
+    putDirect(vm, vm.propertyNames->length, jsNumber(m_length), DontEnum);
+    putDirect(vm, vm.propertyNames->callee, m_callee.get(), DontEnum);
+    putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum);
+    
+    void* backingStore;
+    RELEASE_ASSERT(vm.heap.tryAllocateStorage(this, overridesSize(), &backingStore));
+    m_overrides.set(vm, this, static_cast<bool*>(backingStore));
+    for (unsigned i = m_length; i--;)
+        m_overrides.get()[i] = false;
+}
+
+void DirectArguments::overrideThingsIfNecessary(VM& vm)
+{
+    if (!m_overrides)
+        overrideThings(vm);
+}
+
+void DirectArguments::overrideArgument(VM& vm, unsigned index)
+{
+    overrideThingsIfNecessary(vm);
+    m_overrides.get()[index] = true;
+}
+
+void DirectArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    if (!m_overrides) {
+        unsigned limit = std::min(length + offset, m_length);
+        unsigned i;
+        VirtualRegister start = firstElementDest - offset;
+        for (i = offset; i < limit; ++i)
+            exec->r(start + i) = storage()[i].get();
+        for (; i < length; ++i)
+            exec->r(start + i) = get(exec, i);
+        return;
+    }
+
+    GenericArguments::copyToArguments(exec, firstElementDest, offset, length);
+}
+
+unsigned DirectArguments::overridesSize()
+{
+    // We always allocate something; in the relatively uncommon case of overriding an empty argument we
+    // still allocate so that m_overrides is non-null. We use that to indicate that the other properties
+    // (length, etc) are overridden.
+    return WTF::roundUpToMultipleOf<8>(m_length ? m_length : 1);
+}
+
+} // namespace JSC
+
diff --git a/runtime/DirectArguments.h b/runtime/DirectArguments.h
new file mode 100644 (file)
index 0000000..14bb8bb
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DirectArguments_h
+#define DirectArguments_h
+
+#include "DirectArgumentsOffset.h"
+#include "GenericArguments.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you say "arguments" inside a function,
+// and none of the arguments are captured in the function's activation. The function will copy all
+// of its arguments into this object, and all subsequent accesses to the arguments will go through
+// this object thereafter. Special support is in place for mischevious events like the arguments
+// being deleted (something like "delete arguments[0]") or reconfigured (broadly, we say deletions
+// and reconfigurations mean that the respective argument was "overridden").
+//
+// To speed allocation, this object will hold all of the arguments in-place. The arguments as well
+// as a table of flags saying which arguments were overridden.
+class DirectArguments : public GenericArguments<DirectArguments> {
+private:
+    DirectArguments(VM&, Structure*, unsigned length, unsigned capacity);
+    
+public:
+    // Creates an arguments object but leaves it uninitialized. This is dangerous if we GC right
+    // after allocation.
+    static DirectArguments* createUninitialized(VM&, Structure*, unsigned length, unsigned capacity);
+    
+    // Creates an arguments object and initializes everything to the empty value. Use this if you
+    // cannot guarantee that you'll immediately initialize all of the elements.
+    static DirectArguments* create(VM&, Structure*, unsigned length, unsigned capacity);
+    
+    // Creates an arguments object by copying the argumnets from the stack.
+    static DirectArguments* createByCopying(ExecState*);
+    
+    static void visitChildren(JSCell*, SlotVisitor&);
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
+    
+    uint32_t internalLength() const
+    {
+        return m_length;
+    }
+    
+    uint32_t length(ExecState* exec) const
+    {
+        if (UNLIKELY(m_overrides))
+            return get(exec, exec->propertyNames().length).toUInt32(exec);
+        return m_length;
+    }
+    
+    bool canAccessIndexQuickly(uint32_t i) const
+    {
+        return i < m_length && (!m_overrides || !m_overrides.get()[i]);
+    }
+
+    bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
+    {
+        return i < m_length && !overrodeThings();
+    }
+
+    JSValue getIndexQuickly(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        return const_cast<DirectArguments*>(this)->storage()[i].get();
+    }
+    
+    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        storage()[i].set(vm, this, value);
+    }
+    
+    WriteBarrier<JSFunction>& callee()
+    {
+        return m_callee;
+    }
+    
+    WriteBarrier<Unknown>& argument(DirectArgumentsOffset offset)
+    {
+        ASSERT(offset);
+        ASSERT_WITH_SECURITY_IMPLICATION(offset.offset() < std::max(m_length, m_minCapacity));
+        return storage()[offset.offset()];
+    }
+    
+    // Methods intended for use by the GenericArguments mixin.
+    bool overrodeThings() const { return !!m_overrides; }
+    void overrideThings(VM&);
+    void overrideThingsIfNecessary(VM&);
+    void overrideArgument(VM&, unsigned index);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+    
+    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(DirectArguments, m_callee); }
+    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
+    static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
+    static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
+    
+    static size_t storageOffset()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(DirectArguments));
+    }
+    
+    static size_t offsetOfSlot(uint32_t index)
+    {
+        return storageOffset() + sizeof(WriteBarrier<Unknown>) * index;
+    }
+    
+    static size_t allocationSize(uint32_t capacity)
+    {
+        return offsetOfSlot(capacity);
+    }
+    
+private:
+    WriteBarrier<Unknown>* storage()
+    {
+        return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + storageOffset());
+    }
+    
+    unsigned overridesSize();
+    
+    WriteBarrier<JSFunction> m_callee;
+    uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property.
+    uint32_t m_minCapacity; // The max of this and length determines the capacity of this object. It may be the actual capacity, or maybe something smaller. We arrange it this way to be kind to the JITs.
+    CopyWriteBarrier<bool> m_overrides; // If non-null, it means that length, callee, and caller are fully materialized properties.
+};
+
+} // namespace JSC
+
+#endif // DirectArguments_h
+
diff --git a/runtime/DirectArgumentsOffset.cpp b/runtime/DirectArgumentsOffset.cpp
new file mode 100644 (file)
index 0000000..9fc4c42
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DirectArgumentsOffset.h"
+
+namespace JSC {
+
+void DirectArgumentsOffset::dump(PrintStream& out) const
+{
+    if (!*this) {
+        out.print("capturedArgumentInvalid");
+        return;
+    }
+
+    out.print("capturedArgument", offset());
+}
+
+} // namespace JSC
+
diff --git a/runtime/DirectArgumentsOffset.h b/runtime/DirectArgumentsOffset.h
new file mode 100644 (file)
index 0000000..88a5187
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DirectArgumentsOffset_h
+#define DirectArgumentsOffset_h
+
+#include "GenericOffset.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+// This is an offset into the special arguments object, which captures the arguments to a
+// function. It only comes into play if the arguments aren't also lifted into the activation.
+// If they were then accesses to the arguments would resolve to a ScopeOffset and not a
+// DirectArgumentsOffset.
+class DirectArgumentsOffset : public GenericOffset<DirectArgumentsOffset> {
+public:
+    DirectArgumentsOffset() { }
+    
+    explicit DirectArgumentsOffset(unsigned offset)
+        : GenericOffset(offset)
+    {
+    }
+    
+    void dump(PrintStream&) const;
+};
+
+} // namespace JSC
+
+#endif // DirectArgumentsOffset_h
+
diff --git a/runtime/EnumerationMode.h b/runtime/EnumerationMode.h
new file mode 100644 (file)
index 0000000..3e95ed3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EnumerationMode_h
+#define EnumerationMode_h
+
+namespace JSC {
+
+enum class DontEnumPropertiesMode {
+    Include,
+    Exclude
+};
+
+enum class SymbolPropertiesMode {
+    Include,
+    Exclude
+};
+
+enum class JSObjectPropertiesMode {
+    Include,
+    Exclude
+};
+
+class EnumerationMode {
+public:
+    EnumerationMode(DontEnumPropertiesMode dontEnumPropertiesMode = DontEnumPropertiesMode::Exclude, SymbolPropertiesMode symbolPropertiesMode = SymbolPropertiesMode::Exclude, JSObjectPropertiesMode jsObjectPropertiesMode = JSObjectPropertiesMode::Include)
+        : m_dontEnumPropertiesMode(dontEnumPropertiesMode)
+        , m_symbolPropertiesMode(symbolPropertiesMode)
+        , m_jsObjectPropertiesMode(jsObjectPropertiesMode)
+    {
+    }
+
+    EnumerationMode(const EnumerationMode& mode, JSObjectPropertiesMode jsObjectPropertiesMode)
+        : m_dontEnumPropertiesMode(mode.m_dontEnumPropertiesMode)
+        , m_symbolPropertiesMode(mode.m_symbolPropertiesMode)
+        , m_jsObjectPropertiesMode(jsObjectPropertiesMode)
+    {
+    }
+
+    // Add other constructors as needed for convenience
+
+    bool includeDontEnumProperties()
+    {
+        return m_dontEnumPropertiesMode == DontEnumPropertiesMode::Include;
+    }
+
+    bool includeSymbolProperties()
+    {
+        return m_symbolPropertiesMode == SymbolPropertiesMode::Include;
+    }
+
+    bool includeJSObjectProperties()
+    {
+        return m_jsObjectPropertiesMode == JSObjectPropertiesMode::Include;
+    }
+
+private:
+    DontEnumPropertiesMode m_dontEnumPropertiesMode;
+    SymbolPropertiesMode m_symbolPropertiesMode;
+    JSObjectPropertiesMode m_jsObjectPropertiesMode;
+};
+
+} // namespace JSC
+
+#endif // EnumerationMode_h
index c7ac3a585649d37e658726a634a8c466a4882e2d..00285a67577347479bd9a9b7b93955c26434657c 100644 (file)
@@ -44,91 +44,150 @@ namespace JSC {
 static const char* linePropertyName = "line";
 static const char* sourceURLPropertyName = "sourceURL";
 
-JSObject* createError(JSGlobalObject* globalObject, const String& message)
+JSObject* createError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createEvalError(JSGlobalObject* globalObject, const String& message)
+JSObject* createEvalError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createRangeError(JSGlobalObject* globalObject, const String& message)
+JSObject* createRangeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message)
+JSObject* createReferenceError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message)
+JSObject* createSyntaxError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createTypeError(JSGlobalObject* globalObject, const String& message)
+JSObject* createTypeError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message, appender, type, true);
 }
 
-JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject)
+JSObject* createNotEnoughArgumentsError(ExecState* exec, ErrorInstance::SourceAppender appender)
 {
-    return createTypeError(globalObject, ASCIILiteral("Not enough arguments"));
+    return createTypeError(exec, ASCIILiteral("Not enough arguments"), appender, TypeNothing);
 }
 
-JSObject* createURIError(JSGlobalObject* globalObject, const String& message)
+JSObject* createURIError(ExecState* exec, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    return ErrorInstance::create(exec, globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
-JSObject* createError(ExecState* exec, const String& message)
+JSObject* createOutOfMemoryError(ExecState* exec, ErrorInstance::SourceAppender appender) 
 {
-    return createError(exec->lexicalGlobalObject(), message);
+    return createError(exec, ASCIILiteral("Out of memory"), appender);
 }
 
-JSObject* createEvalError(ExecState* exec, const String& message)
-{
-    return createEvalError(exec->lexicalGlobalObject(), message);
-}
 
-JSObject* createRangeError(ExecState* exec, const String& message)
-{
-    return createRangeError(exec->lexicalGlobalObject(), message);
-}
+class FindFirstCallerFrameWithCodeblockFunctor {
+public:
+    FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
+        : m_startCallFrame(startCallFrame)
+        , m_foundCallFrame(nullptr)
+        , m_foundStartCallFrame(false)
+        , m_index(0)
+    { }
 
-JSObject* createReferenceError(ExecState* exec, const String& message)
-{
-    return createReferenceError(exec->lexicalGlobalObject(), message);
-}
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
+            m_foundStartCallFrame = true;
 
-JSObject* createSyntaxError(ExecState* exec, const String& message)
-{
-    return createSyntaxError(exec->lexicalGlobalObject(), message);
-}
+        if (m_foundStartCallFrame) {
+            if (visitor->callFrame()->codeBlock()) {
+                m_foundCallFrame = visitor->callFrame();
+                return StackVisitor::Done;
+            }
+            m_index++;
+        }
 
-JSObject* createTypeError(ExecState* exec, const String& message)
-{
-    return createTypeError(exec->lexicalGlobalObject(), message);
-}
+        return StackVisitor::Continue;
+    }
 
-JSObject* createNotEnoughArgumentsError(ExecState* exec)
+    CallFrame* foundCallFrame() const { return m_foundCallFrame; }
+    unsigned index() const { return m_index; }
+
+private:
+    CallFrame* m_startCallFrame;
+    CallFrame* m_foundCallFrame;
+    bool m_foundStartCallFrame;
+    unsigned m_index;
+};
+
+bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned &bytecodeOffset) 
 {
-    return createNotEnoughArgumentsError(exec->lexicalGlobalObject());
+    Vector<StackFrame> stackTrace = Vector<StackFrame>();
+
+    if (exec && stackTrace.isEmpty())
+        vm.interpreter->getStackTrace(stackTrace);
+
+    if (!stackTrace.isEmpty()) {
+
+        ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+
+        StackFrame* stackFrame;
+        for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
+            stackFrame = &stackTrace.at(i);
+            if (stackFrame->bytecodeOffset)
+                break;
+        }
+
+        if (bytecodeOffset) {
+            FindFirstCallerFrameWithCodeblockFunctor functor(exec);
+            vm.topCallFrame->iterate(functor);
+            callFrame = functor.foundCallFrame();
+            unsigned stackIndex = functor.index();
+            bytecodeOffset = stackTrace.at(stackIndex).bytecodeOffset;
+        }
+        
+        unsigned line;
+        unsigned column;
+        stackFrame->computeLineAndColumn(line, column);
+        obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete);
+        obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete);
+
+        if (!stackFrame->sourceURL.isEmpty())
+            obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, stackFrame->sourceURL), ReadOnly | DontDelete);
+    
+        if (!useCurrentFrame)
+            stackTrace.remove(0);
+        obj->putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+        return true;
+    }
+    return false;
 }
 
-JSObject* createURIError(ExecState* exec, const String& message)
+void addErrorInfo(ExecState* exec, JSObject* obj, bool useCurrentFrame)
 {
-    return createURIError(exec->lexicalGlobalObject(), message);
+    CallFrame* callFrame = nullptr;
+    unsigned bytecodeOffset = 0;
+    addErrorInfoAndGetBytecodeOffset(exec, exec->vm(), obj, useCurrentFrame, callFrame, bytecodeOffset);
 }
 
 JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const SourceCode& source)
@@ -137,22 +196,22 @@ JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const So
     const String& sourceURL = source.provider()->url();
 
     if (line != -1)
-        error->putDirect(*vm, Identifier(vm, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
+        error->putDirect(*vm, Identifier::fromString(vm, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
     if (!sourceURL.isNull())
-        error->putDirect(*vm, Identifier(vm, sourceURLPropertyName), jsString(vm, sourceURL), ReadOnly | DontDelete);
+        error->putDirect(*vm, Identifier::fromString(vm, sourceURLPropertyName), jsString(vm, sourceURL), ReadOnly | DontDelete);
     return error;
 }
 
 
 bool hasErrorInfo(ExecState* exec, JSObject* error)
 {
-    return error->hasProperty(exec, Identifier(exec, linePropertyName))
-        || error->hasProperty(exec, Identifier(exec, sourceURLPropertyName));
+    return error->hasProperty(exec, Identifier::fromString(exec, linePropertyName))
+        || error->hasProperty(exec, Identifier::fromString(exec, sourceURLPropertyName));
 }
 
 JSObject* throwTypeError(ExecState* exec)
 {
-    return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Type error")));
+    return exec->vm().throwException(exec, createTypeError(exec));
 }
 
 JSObject* throwSyntaxError(ExecState* exec)
@@ -160,7 +219,59 @@ JSObject* throwSyntaxError(ExecState* exec)
     return exec->vm().throwException(exec, createSyntaxError(exec, ASCIILiteral("Syntax error")));
 }
 
-const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
+
+JSObject* createError(ExecState* exec, const String& message)
+{
+    return createError(exec, message, nullptr);
+}
+
+JSObject* createEvalError(ExecState* exec, const String& message)
+{
+    return createEvalError(exec, message, nullptr);
+}
+
+JSObject* createRangeError(ExecState* exec, const String& message)
+{
+    return createRangeError(exec, message, nullptr);
+}
+
+JSObject* createReferenceError(ExecState* exec, const String& message)
+{
+    return createReferenceError(exec, message, nullptr);
+}
+
+JSObject* createSyntaxError(ExecState* exec, const String& message)
+{
+    return createSyntaxError(exec, message, nullptr);
+}
+
+JSObject* createTypeError(ExecState* exec)
+{
+    return createTypeError(exec, ASCIILiteral("Type error"));
+}
+
+JSObject* createTypeError(ExecState* exec, const String& message)
+{
+    return createTypeError(exec, message, nullptr, TypeNothing);
+}
+
+JSObject* createNotEnoughArgumentsError(ExecState* exec)
+{
+    return createNotEnoughArgumentsError(exec, nullptr);
+}
+
+JSObject* createURIError(ExecState* exec, const String& message)
+{
+    return createURIError(exec, message, nullptr);
+}
+
+JSObject* createOutOfMemoryError(ExecState* exec)
+{
+    return createOutOfMemoryError(exec, nullptr);
+}
+
+
+const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
 
 void StrictModeTypeErrorFunction::destroy(JSCell* cell)
 {
index 50674eec862f8dadb343e3b46bf4c57f9fd3ad13..ec30a3dc466e1eb449b3e585aa80492ef1984647 100644 (file)
 #ifndef Error_h
 #define Error_h
 
+#include "ErrorInstance.h"
 #include "InternalFunction.h"
 #include "Interpreter.h"
 #include "JSObject.h"
 #include <stdint.h>
 
+
 namespace JSC {
 
-    class ExecState;
-    class VM;
-    class JSGlobalObject;
-    class JSObject;
-    class SourceCode;
-    class Structure;
-
-    // Methods to create a range of internal errors.
-    JSObject* createError(JSGlobalObject*, const String&);
-    JSObject* createEvalError(JSGlobalObject*, const String&);
-    JSObject* createRangeError(JSGlobalObject*, const String&);
-    JSObject* createReferenceError(JSGlobalObject*, const String&);
-    JSObject* createSyntaxError(JSGlobalObject*, const String&);
-    JSObject* createTypeError(JSGlobalObject*, const String&);
-    JSObject* createNotEnoughArgumentsError(JSGlobalObject*);
-    JSObject* createURIError(JSGlobalObject*, const String&);
-    // ExecState wrappers.
-    JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&);
-    JSObject* createEvalError(ExecState*, const String&);
-    JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&);
-    JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&);
-    JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&);
-    JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&);
-    JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
-    JSObject* createURIError(ExecState*, const String&);
-
-    // Methods to add 
-    bool hasErrorInfo(ExecState*, JSObject* error);
-    // ExecState wrappers.
-    JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
-
-    // Methods to throw Errors.
-
-    // Convenience wrappers, create an throw an exception with a default message.
-    JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
-    JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
-
-    // Convenience wrappers, wrap result as an EncodedJSValue.
-    inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
-    inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
-    inline EncodedJSValue throwVMTypeError(ExecState* exec, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
-    
-    class StrictModeTypeErrorFunction : public InternalFunction {
-    private:
-        StrictModeTypeErrorFunction(VM& vm, Structure* structure, const String& message)
-            : InternalFunction(vm, structure)
-            , m_message(message)
-        {
-        }
-
-        static void destroy(JSCell*);
-
-    public:
-        typedef InternalFunction Base;
-
-        static StrictModeTypeErrorFunction* create(VM& vm, Structure* structure, const String& message)
-        {
-            StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(vm.heap)) StrictModeTypeErrorFunction(vm, structure, message);
-            function->finishCreation(vm, String());
-            return function;
-        }
-    
-        static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
-        {
-            throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
-            return JSValue::encode(jsNull());
-        }
-    
-        static ConstructType getConstructData(JSCell*, ConstructData& constructData)
-        {
-            constructData.native.function = constructThrowTypeError;
-            return ConstructTypeHost;
-        }
-    
-        static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
-        {
-            throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
-            return JSValue::encode(jsNull());
-        }
-
-        static CallType getCallData(JSCell*, CallData& callData)
-        {
-            callData.native.function = callThrowTypeError;
-            return CallTypeHost;
-        }
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-        { 
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
-        }
-
-    private:
-        String m_message;
-    };
+class ExecState;
+class VM;
+class JSGlobalObject;
+class JSObject;
+class SourceCode;
+class Structure;
+
+// ExecState wrappers.
+JSObject* createError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createEvalError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createRangeError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createReferenceError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createSyntaxError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createTypeError(ExecState*, const String&, ErrorInstance::SourceAppender, RuntimeType);
+JSObject* createNotEnoughArgumentsError(ExecState*, ErrorInstance::SourceAppender);
+JSObject* createURIError(ExecState*, const String&, ErrorInstance::SourceAppender);
+JSObject* createOutOfMemoryError(ExecState*, ErrorInstance::SourceAppender);
+
+
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createEvalError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* createURIError(ExecState*, const String&);
+JS_EXPORT_PRIVATE JSObject* createOutOfMemoryError(ExecState*);
+
+
+bool addErrorInfoAndGetBytecodeOffset(ExecState*, VM&, JSObject*, bool, CallFrame*&, unsigned&);
+
+bool hasErrorInfo(ExecState*, JSObject* error);
+JS_EXPORT_PRIVATE void addErrorInfo(ExecState*, JSObject*, bool); 
+JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
+
+// Methods to throw Errors.
+
+// Convenience wrappers, create an throw an exception with a default message.
+JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
+inline JSObject* throwRangeError(ExecState* state, const String& errorMessage) { return state->vm().throwException(state, createRangeError(state, errorMessage)); }
+
+// Convenience wrappers, wrap result as an EncodedJSValue.
+inline void throwVMError(ExecState* exec, Exception* exception) { exec->vm().throwException(exec, exception); }
+inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
+inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
+inline EncodedJSValue throwVMTypeError(ExecState* exec, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
+inline EncodedJSValue throwVMRangeError(ExecState* state, const String& errorMessage) { return JSValue::encode(throwRangeError(state, errorMessage)); }
+
+class StrictModeTypeErrorFunction : public InternalFunction {
+private:
+    StrictModeTypeErrorFunction(VM& vm, Structure* structure, const String& message)
+        : InternalFunction(vm, structure)
+        , m_message(message)
+    {
+    }
+
+    static void destroy(JSCell*);
+
+public:
+    typedef InternalFunction Base;
+
+    static StrictModeTypeErrorFunction* create(VM& vm, Structure* structure, const String& message)
+    {
+        StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(vm.heap)) StrictModeTypeErrorFunction(vm, structure, message);
+        function->finishCreation(vm, String());
+        return function;
+    }
+
+    static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
+    {
+        throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+        return JSValue::encode(jsNull());
+    }
+
+    static ConstructType getConstructData(JSCell*, ConstructData& constructData)
+    {
+        constructData.native.function = constructThrowTypeError;
+        return ConstructTypeHost;
+    }
+
+    static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
+    {
+        throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+        return JSValue::encode(jsNull());
+    }
+
+    static CallType getCallData(JSCell*, CallData& callData)
+    {
+        callData.native.function = callThrowTypeError;
+        return CallTypeHost;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    { 
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
+    }
+
+private:
+    String m_message;
+};
 
 } // namespace JSC
 
index 9acbc4cd02fc12ad203d20b4c11499d8885e2058..30c4faae5f2613e78868d0e66065dcfa5e807601 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ErrorConstructor);
 
-const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorConstructor) };
+const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(ErrorConstructor) };
 
 ErrorConstructor::ErrorConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
@@ -52,10 +52,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::constructWithErrorConstructor(ExecStat
 {
     JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
     Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
-    Vector<StackFrame> stackTrace;
-    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
-    stackTrace.remove(0);
-    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
 }
 
 ConstructType ErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -68,10 +65,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::callErrorConstructor(ExecState* exec)
 {
     JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
     Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
-    Vector<StackFrame> stackTrace;
-    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
-    stackTrace.remove(0);
-    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
 }
 
 CallType ErrorConstructor::getCallData(JSCell*, CallData& callData)
index 29283d01b1b043804b05be5d569bf9228f5f6161..b11894dbe4b5614fd230b60f6ae3bc8bb35d292e 100644 (file)
 
 namespace JSC {
 
-    class ErrorPrototype;
+class ErrorPrototype;
 
-    class ErrorConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class ErrorConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
 
-        static ErrorConstructor* create(VM& vm, Structure* structure, ErrorPrototype* errorPrototype)
-        {
-            ErrorConstructor* constructor = new (NotNull, allocateCell<ErrorConstructor>(vm.heap)) ErrorConstructor(vm, structure);
-            constructor->finishCreation(vm, errorPrototype);
-            return constructor;
-        }
+    static ErrorConstructor* create(VM& vm, Structure* structure, ErrorPrototype* errorPrototype)
+    {
+        ErrorConstructor* constructor = new (NotNull, allocateCell<ErrorConstructor>(vm.heap)) ErrorConstructor(vm, structure);
+        constructor->finishCreation(vm, errorPrototype);
+        return constructor;
+    }
 
-        DECLARE_INFO;
+    DECLARE_INFO;
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-        
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    { 
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
+    }
 
-    protected:
-        void finishCreation(VM&, ErrorPrototype*);
+protected:
+    void finishCreation(VM&, ErrorPrototype*);
         
-    private:
-        ErrorConstructor(VM&, Structure*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-    };
+private:
+    ErrorConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
 
 } // namespace JSC
 
index 42e7c533c9b24da34e94c3900c2605c900340044..2bf1493bdf817e491b01ad67574376c24be1d2e6 100644 (file)
 
 #include "JSScope.h"
 #include "JSCInlines.h"
+#include "JSGlobalObjectFunctions.h"
+#include <wtf/Vector.h>
 
 namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ErrorInstance);
 
-const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorInstance) };
+const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, CREATE_METHOD_TABLE(ErrorInstance) };
 
 ErrorInstance::ErrorInstance(VM& vm, Structure* structure)
     : JSNonFinalObject(vm, structure)
-    , m_appendSourceToMessage(false)
 {
 }
 
-void ErrorInstance::finishCreation(VM& vm, const String& message, Vector<StackFrame> stackTrace)
+static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
+{
+    ErrorInstance::SourceAppender appender = exception->sourceAppender();
+    exception->clearSourceAppender();
+    RuntimeType type = exception->runtimeTypeForCause();
+    exception->clearRuntimeTypeForCause();
+
+    if (!callFrame->codeBlock()->hasExpressionInfo())
+        return;
+    
+    int startOffset = 0;
+    int endOffset = 0;
+    int divotPoint = 0;
+    unsigned line = 0;
+    unsigned column = 0;
+    
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
+    
+    int expressionStart = divotPoint - startOffset;
+    int expressionStop = divotPoint + endOffset;
+
+    const String& sourceString = codeBlock->source()->source();
+    if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
+        return;
+    
+    VM* vm = &callFrame->vm();
+    JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
+    if (!jsMessage || !jsMessage.isString())
+        return;
+    
+    String message = asString(jsMessage)->value(callFrame);
+    if (expressionStart < expressionStop)
+        message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop) , type, ErrorInstance::FoundExactSource);
+    else {
+        // No range information, so give a few characters of context.
+        const StringImpl* data = sourceString.impl();
+        int dataLength = sourceString.length();
+        int start = expressionStart;
+        int stop = expressionStart;
+        // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
+        // Then strip whitespace.
+        while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
+            start--;
+        while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
+            start++;
+        while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
+            stop++;
+        while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
+            stop--;
+        message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
+    }
+    exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
+
+}
+
+class FindFirstCallerFrameWithCodeblockFunctor {
+public:
+    FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
+        : m_startCallFrame(startCallFrame)
+        , m_foundCallFrame(nullptr)
+        , m_foundStartCallFrame(false)
+        , m_index(0)
+    { }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
+            m_foundStartCallFrame = true;
+
+        if (m_foundStartCallFrame) {
+            if (visitor->callFrame()->codeBlock()) {
+                m_foundCallFrame = visitor->callFrame();
+                return StackVisitor::Done;
+            }
+            m_index++;
+        }
+
+        return StackVisitor::Continue;
+    }
+
+    CallFrame* foundCallFrame() const { return m_foundCallFrame; }
+    unsigned index() const { return m_index; }
+
+private:
+    CallFrame* m_startCallFrame;
+    CallFrame* m_foundCallFrame;
+    bool m_foundStartCallFrame;
+    unsigned m_index;
+};
+
+static bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned &bytecodeOffset)
+{
+    Vector<StackFrame> stackTrace = Vector<StackFrame>();
+
+    if (exec && stackTrace.isEmpty())
+        vm.interpreter->getStackTrace(stackTrace);
+
+    if (!stackTrace.isEmpty()) {
+
+        ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
+
+        StackFrame* stackFrame;
+        for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
+            stackFrame = &stackTrace.at(i);
+            if (stackFrame->bytecodeOffset)
+                break;
+        }
+
+        if (bytecodeOffset) {
+            FindFirstCallerFrameWithCodeblockFunctor functor(exec);
+            vm.topCallFrame->iterate(functor);
+            callFrame = functor.foundCallFrame();
+            unsigned stackIndex = functor.index();
+            bytecodeOffset = stackTrace.at(stackIndex).bytecodeOffset;
+        }
+        
+        unsigned line;
+        unsigned column;
+        stackFrame->computeLineAndColumn(line, column);
+        obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete);
+        obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete);
+
+        if (!stackFrame->sourceURL.isEmpty())
+            obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, stackFrame->sourceURL), ReadOnly | DontDelete);
+    
+        if (!useCurrentFrame)
+            stackTrace.remove(0);
+        obj->putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+        return true;
+    }
+    return false;
+}
+
+void ErrorInstance::finishCreation(ExecState* exec, VM& vm, const String& message, bool useCurrentFrame)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     if (!message.isNull())
         putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum);
-    
-    if (!stackTrace.isEmpty())
-        putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum);
+
+    unsigned bytecodeOffset = hasSourceAppender();
+    CallFrame* callFrame = nullptr;
+    bool hasTrace = addErrorInfoAndGetBytecodeOffset(exec, vm, this, useCurrentFrame, callFrame, bytecodeOffset);
+
+    if (hasTrace && callFrame && hasSourceAppender()) {
+        if (callFrame && callFrame->codeBlock()) 
+            appendSourceToError(callFrame, this, bytecodeOffset);
+    }
 }
     
 } // namespace JSC
index 91dd7ef0ae63c57f514de9135e082a27c21ea22c..3f584a99f072e84d87c1a1a51ba030b15cf62e32 100644 (file)
 #define ErrorInstance_h
 
 #include "Interpreter.h"
-#include "JSObject.h"
+#include "RuntimeType.h"
 #include "SourceProvider.h"
+#include <wtf/Vector.h>
 
 namespace JSC {
 
-    class ErrorInstance : public JSNonFinalObject {
-    public:
-        typedef JSNonFinalObject Base;
+class ErrorInstance : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
 
-        DECLARE_INFO;
+    enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
+    typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
-        }
+    DECLARE_INFO;
 
-        static ErrorInstance* create(VM& vm, Structure* structure, const String& message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
-        {
-            ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
-            instance->finishCreation(vm, message, stackTrace);
-            return instance;
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
+    }
 
-        static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
-        {
-            return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
-        }
+    static ErrorInstance* create(ExecState* exec, VM& vm, Structure* structure, const String& message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
+    {
+        ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
+        instance->m_sourceAppender = appender;
+        instance->m_runtimeTypeForCause = type;
+        instance->finishCreation(exec, vm, message, useCurrentFrame);
+        return instance;
+    }
 
-        bool appendSourceToMessage() { return m_appendSourceToMessage; }
-        void setAppendSourceToMessage() { m_appendSourceToMessage = true; }
-        void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
+    static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
+    {
+        return create(exec, exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), appender, type, useCurrentFrame);
+    }
 
-    protected:
-        explicit ErrorInstance(VM&, Structure*);
+    static void addErrorInfo(ExecState*, VM&, JSObject*, bool = true);
 
-        void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
+    bool hasSourceAppender() const { return !!m_sourceAppender; }
+    SourceAppender sourceAppender() const { return m_sourceAppender; }
+    void setSourceAppender(SourceAppender appender) { m_sourceAppender = appender; }
+    void clearSourceAppender() { m_sourceAppender = nullptr; }
+    void setRuntimeTypeForCause(RuntimeType type) { m_runtimeTypeForCause = type; }
+    RuntimeType runtimeTypeForCause() const { return m_runtimeTypeForCause; }
+    void clearRuntimeTypeForCause() { m_runtimeTypeForCause = TypeNothing; }
 
-        bool m_appendSourceToMessage;
-    };
+protected:
+    explicit ErrorInstance(VM&, Structure*);
+
+    void finishCreation(ExecState*, VM&, const String&, bool useCurrentFrame = true);
+
+    SourceAppender m_sourceAppender { nullptr };
+    RuntimeType m_runtimeTypeForCause { TypeNothing };
+};
 
 } // namespace JSC
 
index 080b975c94159ca3ffdcd297e86b02bcfc883ec4..5bc2ec3c8ec2f3ddac967a2fb15d99ac3d866501 100644 (file)
@@ -41,7 +41,7 @@ static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*);
 
 namespace JSC {
 
-const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, 0, ExecState::errorPrototypeTable, CREATE_METHOD_TABLE(ErrorPrototype) };
+const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, &errorPrototypeTable, CREATE_METHOD_TABLE(ErrorPrototype) };
 
 /* Source for ErrorPrototype.lut.h
 @begin errorPrototypeTable
@@ -54,16 +54,16 @@ ErrorPrototype::ErrorPrototype(VM& vm, Structure* structure)
 {
 }
 
-void ErrorPrototype::finishCreation(VM& vm, JSGlobalObject*)
+void ErrorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
-    Base::finishCreation(vm, "");
+    Base::finishCreation(globalObject->globalExec(), vm, "");
     ASSERT(inherits(info()));
     putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("Error"))), DontEnum);
 }
 
 bool ErrorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<ErrorInstance>(exec, ExecState::errorPrototypeTable(exec->vm()), jsCast<ErrorPrototype*>(object), propertyName, slot);
+    return getStaticFunctionSlot<ErrorInstance>(exec, errorPrototypeTable, jsCast<ErrorPrototype*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions ---------------------------
index 10707abdb493014394c9f47ec6e0a27329efecec..29cd6a9487b87330d5763de7fd9310fb127dc817 100644 (file)
 
 namespace JSC {
 
-    class ObjectPrototype;
-
-    class ErrorPrototype : public ErrorInstance {
-    public:
-        typedef ErrorInstance Base;
-
-        static ErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-        {
-            ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
-            prototype->finishCreation(vm, globalObject);
-            return prototype;
-        }
-        
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
-        }
-
-    protected:
-        ErrorPrototype(VM&, Structure*);
-        void finishCreation(VM&, JSGlobalObject*);
-
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
-
-    private:
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    };
+class ObjectPrototype;
+
+class ErrorPrototype : public ErrorInstance {
+public:
+    typedef ErrorInstance Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static ErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
+    }
+
+protected:
+    ErrorPrototype(VM&, Structure*);
+    void finishCreation(VM&, JSGlobalObject*);
+
+private:
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
 
 } // namespace JSC
 
diff --git a/runtime/Exception.cpp b/runtime/Exception.cpp
new file mode 100644 (file)
index 0000000..4f5fcb9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Exception.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo Exception::s_info = { "Exception", &Base::s_info, 0, CREATE_METHOD_TABLE(Exception) };
+
+Exception* Exception::create(VM& vm, JSValue thrownValue, StackCaptureAction action)
+{
+    Exception* result = new (NotNull, allocateCell<Exception>(vm.heap)) Exception(vm);
+    result->finishCreation(vm, thrownValue, action);
+    return result;
+}
+
+void Exception::destroy(JSCell* cell)
+{
+    Exception* exception = static_cast<Exception*>(cell);
+    exception->~Exception();
+}
+
+Structure* Exception::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+void Exception::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    Exception* thisObject = jsCast<Exception*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.append(&thisObject->m_value);
+}
+
+Exception::Exception(VM& vm)
+    : Base(vm, vm.exceptionStructure.get())
+{
+}
+
+Exception::~Exception()
+{
+}
+
+void Exception::finishCreation(VM& vm, JSValue thrownValue, StackCaptureAction action)
+{
+    Base::finishCreation(vm);
+
+    m_value.set(vm, this, thrownValue);
+
+    Vector<StackFrame> stackTrace;
+    if (action == StackCaptureAction::CaptureStack)
+        vm.interpreter->getStackTrace(stackTrace);
+    m_stack = RefCountedArray<StackFrame>(stackTrace);
+}
+
+} // namespace JSC
diff --git a/runtime/Exception.h b/runtime/Exception.h
new file mode 100644 (file)
index 0000000..491cb49
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Exception_h
+#define Exception_h
+
+#include "Interpreter.h"
+#include <wtf/RefCountedArray.h>
+
+namespace JSC {
+    
+class Exception : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+
+    enum StackCaptureAction {
+        CaptureStack,
+        DoNotCaptureStack
+    };
+    JS_EXPORT_PRIVATE static Exception* create(VM&, JSValue thrownValue, StackCaptureAction = CaptureStack);
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    DECLARE_EXPORT_INFO;
+
+    static ptrdiff_t valueOffset()
+    {
+        return OBJECT_OFFSETOF(Exception, m_value);
+    }
+
+    JSValue value() const { return m_value.get(); }
+    const RefCountedArray<StackFrame>& stack() const { return m_stack; }
+
+    bool didNotifyInspectorOfThrow() const { return m_didNotifyInspectorOfThrow; }
+    void setDidNotifyInspectorOfThrow() { m_didNotifyInspectorOfThrow = true; }
+
+    ~Exception();
+
+private:
+    Exception(VM&);
+    void finishCreation(VM&, JSValue thrownValue, StackCaptureAction);
+
+    WriteBarrier<Unknown> m_value;
+    RefCountedArray<StackFrame> m_stack;
+    bool m_didNotifyInspectorOfThrow { false };
+
+    friend class LLIntOffsetsExtractor;
+};
+
+} // namespace JSC
+
+#endif // Exception_h
diff --git a/runtime/ExceptionFuzz.cpp b/runtime/ExceptionFuzz.cpp
new file mode 100644 (file)
index 0000000..744b1a6
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ExceptionFuzz.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "TestRunnerUtils.h"
+
+namespace JSC {
+
+static unsigned s_numberOfExceptionFuzzChecks;
+unsigned numberOfExceptionFuzzChecks() { return s_numberOfExceptionFuzzChecks; }
+
+// Call this only if you know that exception fuzzing is enabled.
+void doExceptionFuzzing(ExecState* exec, const char* where, void* returnPC)
+{
+    ASSERT(Options::enableExceptionFuzz());
+
+    DeferGCForAWhile deferGC(exec->vm().heap);
+    
+    s_numberOfExceptionFuzzChecks++;
+    
+    unsigned fireTarget = Options::fireExceptionFuzzAt();
+    if (fireTarget == s_numberOfExceptionFuzzChecks) {
+        printf("JSC EXCEPTION FUZZ: Throwing fuzz exception with call frame %p, seen in %s and return address %p.\n", exec, where, returnPC);
+        exec->vm().throwException(
+            exec, createError(exec, ASCIILiteral("Exception Fuzz")));
+    }
+}
+
+} // namespace JSC
+
+
diff --git a/runtime/ExceptionFuzz.h b/runtime/ExceptionFuzz.h
new file mode 100644 (file)
index 0000000..d9a6b4b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ExceptionFuzz_h
+#define ExceptionFuzz_h
+
+#include "Options.h"
+
+namespace JSC {
+
+class ExecState;
+
+// Call this only if you know that exception fuzzing is enabled.
+void doExceptionFuzzing(ExecState* exec, const char* where, void* returnPC);
+
+// This is what you should call if you don't know if fuzzing is enabled.
+ALWAYS_INLINE void doExceptionFuzzingIfEnabled(ExecState* exec, const char* where, void* returnPC)
+{
+    if (LIKELY(!Options::enableExceptionFuzz()))
+        return;
+    doExceptionFuzzing(exec, where, returnPC);
+}
+
+} // namespace JSC
+
+#endif // ExceptionFuzz_h
+
index 6a668d465064bb609916529a15ed51ce6b767db6..b8a6285c50b6b9cd4a3600c671ca72471ec17460 100644 (file)
 #include "CodeBlock.h"
 #include "CallFrame.h"
 #include "ErrorHandlingScope.h"
-#include "ErrorInstance.h"
+#include "Exception.h"
 #include "JSGlobalObjectFunctions.h"
-#include "JSObject.h"
 #include "JSNotAnObject.h"
 #include "Interpreter.h"
 #include "Nodes.h"
 #include "JSCInlines.h"
+#include "RuntimeType.h"
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringView.h>
 
 namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(TerminatedExecutionError);
 
-const ClassInfo TerminatedExecutionError::s_info = { "TerminatedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(TerminatedExecutionError) };
+const ClassInfo TerminatedExecutionError::s_info = { "TerminatedExecutionError", &Base::s_info, 0, CREATE_METHOD_TABLE(TerminatedExecutionError) };
 
 JSValue TerminatedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint)
 {
@@ -58,31 +60,19 @@ JSObject* createTerminatedExecutionException(VM* vm)
     return TerminatedExecutionError::create(*vm);
 }
 
-bool isTerminatedExecutionException(JSObject* object)
+bool isTerminatedExecutionException(Exception* exception)
 {
-    return object->inherits(TerminatedExecutionError::info());
+    return exception->value().inherits(TerminatedExecutionError::info());
 }
 
-bool isTerminatedExecutionException(JSValue value)
-{
-    return value.inherits(TerminatedExecutionError::info());
-}
-
-
 JSObject* createStackOverflowError(ExecState* exec)
 {
     return createRangeError(exec, ASCIILiteral("Maximum call stack size exceeded."));
 }
 
-JSObject* createStackOverflowError(JSGlobalObject* globalObject)
-{
-    return createRangeError(globalObject, ASCIILiteral("Maximum call stack size exceeded."));
-}
-
 JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
 {
-    
-    if (ident.impl()->isEmptyUnique()) {
+    if (exec->propertyNames().isPrivateName(ident)) {
         String message(makeString("Can't find private variable: @", exec->propertyNames().getPublicName(ident).string()));
         return createReferenceError(exec, message);
     }
@@ -92,76 +82,194 @@ JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
     
 JSString* errorDescriptionForValue(ExecState* exec, JSValue v)
 {
-    VM& vm = exec->vm();
-    if (v.isNull())
-        return vm.smallStrings.nullString();
-    if (v.isUndefined())
-        return vm.smallStrings.undefinedString();
-    if (v.isInt32())
-        return jsString(&vm, vm.numericStrings.add(v.asInt32()));
-    if (v.isDouble())
-        return jsString(&vm, vm.numericStrings.add(v.asDouble()));
-    if (v.isTrue())
-        return vm.smallStrings.trueString();
-    if (v.isFalse())
-        return vm.smallStrings.falseString();
     if (v.isString())
-        return jsCast<JSString*>(v.asCell());
+        return jsNontrivialString(exec, makeString('"',  asString(v)->value(exec), '"'));
     if (v.isObject()) {
         CallData callData;
         JSObject* object = asObject(v);
         if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
-            return vm.smallStrings.functionString();
-        return jsString(exec, object->methodTable()->className(object));
+            return exec->vm().smallStrings.functionString();
+        return jsString(exec, JSObject::calculatedClassName(object));
     }
-    
-    // The JSValue should never be empty, so this point in the code should never be reached.
-    ASSERT_NOT_REACHED();
-    return vm.smallStrings.emptyString();
+    return v.toString(exec);
 }
     
-JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message)
+static String defaultApproximateSourceError(const String& originalMessage, const String& sourceText)
+{
+    return makeString(originalMessage, " (near '...", sourceText, "...')");
+}
+
+static String defaultSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    return makeString(originalMessage, " (evaluating '", sourceText, "')");
+}
+
+static String functionCallBase(const String& sourceText)
+{ 
+    // This function retrieves the 'foo.bar' substring from 'foo.bar(baz)'.
+    // FIXME: This function has simple processing of /* */ style comments.
+    // It doesn't properly handle embedded comments of string literals that contain
+    // parenthesis or comment constructs, e.g. foo.bar("/abc\)*/").
+    // https://bugs.webkit.org/show_bug.cgi?id=146304
+
+    unsigned sourceLength = sourceText.length();
+    unsigned idx = sourceLength - 1;
+    if (sourceLength < 2 || sourceText[idx] != ')') {
+        // For function calls that have many new lines in between their open parenthesis
+        // and their closing parenthesis, the text range passed into the message appender 
+        // will not inlcude the text in between these parentheses, it will just be the desired
+        // text that precedes the parentheses.
+        return sourceText;
+    }
+
+    unsigned parenStack = 1;
+    bool isInMultiLineComment = false;
+    idx -= 1;
+    // Note that we're scanning text right to left instead of the more common left to right, 
+    // so syntax detection is backwards.
+    while (parenStack > 0) {
+        UChar curChar = sourceText[idx];
+        if (isInMultiLineComment)  {
+            if (idx > 0 && curChar == '*' && sourceText[idx - 1] == '/') {
+                isInMultiLineComment = false;
+                idx -= 1;
+            }
+        } else if (curChar == '(')
+            parenStack -= 1;
+        else if (curChar == ')')
+            parenStack += 1;
+        else if (idx > 0 && curChar == '/' && sourceText[idx - 1] == '*') {
+            isInMultiLineComment = true;
+            idx -= 1;
+        }
+
+        if (!idx)
+            break;
+
+        idx -= 1;
+    }
+
+    return sourceText.left(idx + 1);
+}
+
+static String notAFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType type, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
 {
-    String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), " ", message);
-    JSObject* exception = errorFactory(exec, errorMessage);
+    ASSERT(type != TypeFunction);
+
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto notAFunctionIndex = originalMessage.reverseFind("is not a function");
+    RELEASE_ASSERT(notAFunctionIndex != notFound);
+    StringView displayValue;
+    if (originalMessage.is8Bit()) 
+        displayValue = StringView(originalMessage.characters8(), notAFunctionIndex - 1);
+    else
+        displayValue = StringView(originalMessage.characters16(), notAFunctionIndex - 1);
+
+    String base = functionCallBase(sourceText);
+    StringBuilder builder;
+    builder.append(base);
+    builder.appendLiteral(" is not a function. (In '");
+    builder.append(sourceText);
+    builder.appendLiteral("', '");
+    builder.append(base);
+    builder.appendLiteral("' is ");
+    if (type == TypeObject)
+        builder.appendLiteral("an instance of ");
+    builder.append(displayValue);
+    builder.appendLiteral(")");
+
+    return builder.toString();
+}
+
+static String invalidParameterInSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType type, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    ASSERT_UNUSED(type, type != TypeObject);
+
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto inIndex = sourceText.reverseFind("in");
+    RELEASE_ASSERT(inIndex != notFound);
+    if (sourceText.find("in") != inIndex)
+        return makeString(originalMessage, " (evaluating '", sourceText, "')");
+
+    static const unsigned inLength = 2;
+    String rightHandSide = sourceText.substring(inIndex + inLength).simplifyWhiteSpace();
+    return makeString(rightHandSide, " is not an Object. (evaluating '", sourceText, "')");
+}
+
+static String invalidParameterInstanceofSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
+{
+    if (occurrence == ErrorInstance::FoundApproximateSource)
+        return defaultApproximateSourceError(originalMessage, sourceText);
+
+    ASSERT(occurrence == ErrorInstance::FoundExactSource);
+    auto instanceofIndex = sourceText.reverseFind("instanceof");
+    RELEASE_ASSERT(instanceofIndex != notFound);
+    if (sourceText.find("instanceof") != instanceofIndex)
+        return makeString(originalMessage, " (evaluating '", sourceText, "')");
+
+    static const unsigned instanceofLength = 10;
+    String rightHandSide = sourceText.substring(instanceofIndex + instanceofLength).simplifyWhiteSpace();
+    return makeString(rightHandSide, " is not a function. (evaluating '", sourceText, "')");
+}
+
+JSObject* createError(ExecState* exec, JSValue value, const String& message, ErrorInstance::SourceAppender appender)
+{
+    String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), ' ', message);
+    JSObject* exception = createTypeError(exec, errorMessage, appender, runtimeTypeForValue(value));
+    ASSERT(exception->isErrorInstance());
+    return exception;
+}
+
+JSObject* createInvalidFunctionApplyParameterError(ExecState* exec, JSValue value)
+{
+    JSObject* exception = createTypeError(exec, makeString("second argument to Function.prototype.apply must be an Array-like object"), defaultSourceAppender, runtimeTypeForValue(value));
     ASSERT(exception->isErrorInstance());
-    static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
     return exception;
 }
 
-JSObject* createInvalidParameterError(ExecState* exec, const char* op, JSValue value)
+JSObject* createInvalidInParameterError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, makeString("is not a valid argument for '", op, "'"));
+    return createError(exec, value, makeString("is not an Object."), invalidParameterInSourceAppender);
+}
+
+JSObject* createInvalidInstanceofParameterError(ExecState* exec, JSValue value)
+{
+    return createError(exec, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender);
 }
 
 JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, "is not a constructor");
+    return createError(exec, value, ASCIILiteral("is not a constructor"), defaultSourceAppender);
 }
 
 JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, "is not a function");
+    return createError(exec, value, ASCIILiteral("is not a function"), notAFunctionSourceAppender);
 }
 
 JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
 {
-    return createError(exec, createTypeError, value, "is not an object");
+    return createError(exec, value, ASCIILiteral("is not an object"), defaultSourceAppender);
 }
 
 JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const String& propertyName)
 {
-    return createReferenceError(exec, makeString("Strict mode forbids implicit creation of global property '", propertyName, "'"));
-}
-
-JSObject* createOutOfMemoryError(JSGlobalObject* globalObject)
-{
-    return createError(globalObject, ASCIILiteral("Out of memory"));
+    return createReferenceError(exec, makeString("Strict mode forbids implicit creation of global property '", propertyName, '\''));
 }
 
 JSObject* throwOutOfMemoryError(ExecState* exec)
 {
-    return exec->vm().throwException(exec, createOutOfMemoryError(exec->lexicalGlobalObject()));
+    return exec->vm().throwException(exec, createOutOfMemoryError(exec));
 }
 
 JSObject* throwStackOverflowError(ExecState* exec)
index 66d8136efe2f6ffb20bce62d0d711309d3fe2b48..305ebef9113af01cd3aa274416502c95ae094f72 100644 (file)
 #ifndef ExceptionHelpers_h
 #define ExceptionHelpers_h
 
+#include "ErrorInstance.h"
 #include "JSObject.h"
 
 namespace JSC {
 
-typedef JSObject* (*ErrorFactory)(ExecState*, const String&);
+typedef JSObject* (*ErrorFactory)(ExecState*, const String&, ErrorInstance::SourceAppender);
 
 JSObject* createTerminatedExecutionException(VM*);
-bool isTerminatedExecutionException(JSObject*);
-JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
-JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&);
+JS_EXPORT_PRIVATE bool isTerminatedExecutionException(Exception*);
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, JSValue, const String&, ErrorInstance::SourceAppender);
 JS_EXPORT_PRIVATE JSObject* createStackOverflowError(ExecState*);
-JSObject* createStackOverflowError(JSGlobalObject*);
-JSObject* createOutOfMemoryError(JSGlobalObject*);
 JSObject* createUndefinedVariableError(ExecState*, const Identifier&);
 JSObject* createNotAnObjectError(ExecState*, JSValue);
-JSObject* createInvalidParameterError(ExecState*, const char* op, JSValue);
+JSObject* createInvalidFunctionApplyParameterError(ExecState*, JSValue);
+JSObject* createInvalidInParameterError(ExecState*, JSValue);
+JSObject* createInvalidInstanceofParameterError(ExecState*, JSValue);
 JSObject* createNotAConstructorError(ExecState*, JSValue);
 JSObject* createNotAFunctionError(ExecState*, JSValue);
 JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const String&);
 JSString* errorDescriptionForValue(ExecState*, JSValue);
 
-JSObject* throwOutOfMemoryError(ExecState*);
-JSObject* throwStackOverflowError(ExecState*);
-JSObject* throwTerminatedExecutionException(ExecState*);
+JS_EXPORT_PRIVATE JSObject* throwOutOfMemoryError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* throwStackOverflowError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* throwTerminatedExecutionException(ExecState*);
 
 
-class TerminatedExecutionError : public JSNonFinalObject {
-private:
-    TerminatedExecutionError(VM& vm)
-        : JSNonFinalObject(vm, vm.terminatedExecutionErrorStructure.get())
-    {
-    }
-
-    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
-
+class TerminatedExecutionError final : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static TerminatedExecutionError* create(VM& vm)
     {
@@ -80,6 +73,15 @@ public:
     }
 
     DECLARE_EXPORT_INFO;
+
+private:
+    explicit TerminatedExecutionError(VM& vm)
+        : JSNonFinalObject(vm, vm.terminatedExecutionErrorStructure.get())
+    {
+    }
+
+    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
+
 };
 
 } // namespace JSC
index ff9f614a0f9ca4c8188d5b7536e97b8548371a7c..55240fd91f7bc7842f13e59281d10d21d86c4f50 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "Executable.h"
 
 #include "BatchedTransitionOptimizer.h"
-#include "BytecodeGenerator.h"
 #include "CodeBlock.h"
 #include "DFGDriver.h"
 #include "JIT.h"
-#include "LLIntEntrypoint.h"
 #include "JSCInlines.h"
+#include "JSFunctionNameScope.h"
+#include "LLIntEntrypoint.h"
 #include "Parser.h"
 #include "ProfilerDatabase.h"
+#include "TypeProfiler.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/Vector.h>
 #include <wtf/text/StringBuilder.h>
 
 namespace JSC {
 
-const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0, CREATE_METHOD_TABLE(ExecutableBase) };
+const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, CREATE_METHOD_TABLE(ExecutableBase) };
 
-#if ENABLE(JIT)
 void ExecutableBase::destroy(JSCell* cell)
 {
     static_cast<ExecutableBase*>(cell)->ExecutableBase::~ExecutableBase();
 }
-#endif
 
 void ExecutableBase::clearCode()
 {
 #if ENABLE(JIT)
-    m_jitCodeForCall.clear();
-    m_jitCodeForConstruct.clear();
+    m_jitCodeForCall = nullptr;
+    m_jitCodeForConstruct = nullptr;
     m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
     m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
     m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
@@ -78,14 +77,12 @@ Intrinsic ExecutableBase::intrinsic() const
 }
 #endif
 
-const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(NativeExecutable) };
+const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(NativeExecutable) };
 
-#if ENABLE(JIT)
 void NativeExecutable::destroy(JSCell* cell)
 {
     static_cast<NativeExecutable*>(cell)->NativeExecutable::~NativeExecutable();
 }
-#endif
 
 #if ENABLE(DFG_JIT)
 Intrinsic NativeExecutable::intrinsic() const
@@ -94,20 +91,38 @@ Intrinsic NativeExecutable::intrinsic() const
 }
 #endif
 
-const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(ScriptExecutable) };
+const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(ScriptExecutable) };
+
+ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
+    : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
+    , m_source(source)
+    , m_features(isInStrictContext ? StrictModeFeature : 0)
+    , m_hasCapturedVariables(false)
+    , m_neverInline(false)
+    , m_didTryToEnterInLoop(false)
+    , m_overrideLineNumber(-1)
+    , m_firstLine(-1)
+    , m_lastLine(-1)
+    , m_startColumn(UINT_MAX)
+    , m_endColumn(UINT_MAX)
+    , m_typeProfilingStartOffset(UINT_MAX)
+    , m_typeProfilingEndOffset(UINT_MAX)
+{
+}
 
-#if ENABLE(JIT)
 void ScriptExecutable::destroy(JSCell* cell)
 {
     static_cast<ScriptExecutable*>(cell)->ScriptExecutable::~ScriptExecutable();
 }
-#endif
 
 void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
 {
     RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
     RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType()));
     
+    if (Options::verboseOSR())
+        dataLog("Installing ", *genericCodeBlock, "\n");
+    
     VM& vm = *genericCodeBlock->vm();
     
     if (vm.m_perBytecodeProfiler)
@@ -184,10 +199,10 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
     Heap::heap(this)->writeBarrier(this);
 }
 
-PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
-    CodeSpecializationKind kind, JSFunction* function, JSScope** scope, JSObject*& exception)
+RefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
+    CodeSpecializationKind kind, JSFunction* function, JSScope* scope, JSObject*& exception)
 {
-    VM* vm = (*scope)->vm();
+    VM* vm = scope->vm();
 
     ASSERT(vm->heap.isDeferred());
     ASSERT(startColumn() != UINT_MAX);
@@ -199,7 +214,7 @@ PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
         RELEASE_ASSERT(!executable->m_evalCodeBlock);
         RELEASE_ASSERT(!function);
         return adoptRef(new EvalCodeBlock(
-            executable, executable->m_unlinkedEvalCodeBlock.get(), *scope,
+            executable, executable->m_unlinkedEvalCodeBlock.get(), scope,
             executable->source().provider()));
     }
     
@@ -209,7 +224,7 @@ PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
         RELEASE_ASSERT(!executable->m_programCodeBlock);
         RELEASE_ASSERT(!function);
         return adoptRef(new ProgramCodeBlock(
-            executable, executable->m_unlinkedProgramCodeBlock.get(), *scope,
+            executable, executable->m_unlinkedProgramCodeBlock.get(), scope,
             executable->source().provider(), executable->source().startColumn()));
     }
     
@@ -217,27 +232,32 @@ PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
     RELEASE_ASSERT(function);
     FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
     RELEASE_ASSERT(!executable->codeBlockFor(kind));
-    JSGlobalObject* globalObject = (*scope)->globalObject();
+    JSGlobalObject* globalObject = scope->globalObject();
     ParserError error;
     DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
     ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
     UnlinkedFunctionCodeBlock* unlinkedCodeBlock =
         executable->m_unlinkedExecutable->codeBlockFor(
-            *vm, executable->m_source, kind, debuggerMode, profilerMode, executable->bodyIncludesBraces(), error);
-    recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn(), endColumn()); 
+            *vm, executable->m_source, kind, debuggerMode, profilerMode, error);
+    recordParse(executable->m_unlinkedExecutable->features(), executable->m_unlinkedExecutable->hasCapturedVariables(), firstLine(), lastLine(), startColumn(), endColumn()); 
     if (!unlinkedCodeBlock) {
         exception = vm->throwException(
             globalObject->globalExec(),
             error.toErrorObject(globalObject, executable->m_source));
-        return 0;
+        return nullptr;
     }
 
     // Parsing reveals whether our function uses features that require a separate function name object in the scope chain.
     // Be sure to add this scope before linking the bytecode because this scope will change the resolution depth of non-local variables.
-    if (!executable->m_didParseForTheFirstTime) {
-        executable->m_didParseForTheFirstTime = true;
-        function->addNameScopeIfNeeded(*vm);
-        *scope = function->scope();
+    if (functionNameIsInScope(executable->name(), executable->functionMode())
+        && functionNameScopeIsDynamic(executable->usesEval(), executable->isStrictMode())) {
+        // We shouldn't have to do this. But we do, because bytecode linking requires a real scope
+        // chain.
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141885
+        SymbolTable* symbolTable =
+            SymbolTable::createNameScopeTable(*vm, executable->name(), ReadOnly | DontDelete);
+        scope = JSFunctionNameScope::create(
+            *vm, scope->globalObject(), scope, symbolTable, function);
     }
     
     SourceProvider* provider = executable->source().provider();
@@ -245,7 +265,7 @@ PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
     unsigned startColumn = executable->source().startColumn();
 
     return adoptRef(new FunctionCodeBlock(
-        executable, unlinkedCodeBlock, *scope, provider, sourceOffset, startColumn));
+        executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
 }
 
 PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor(
@@ -301,7 +321,7 @@ static void setupJIT(VM& vm, CodeBlock* codeBlock)
 }
 
 JSObject* ScriptExecutable::prepareForExecutionImpl(
-    ExecState* exec, JSFunction* function, JSScope** scope, CodeSpecializationKind kind)
+    ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
 {
     VM& vm = exec->vm();
     DeferGC deferGC(vm.heap);
@@ -325,9 +345,9 @@ JSObject* ScriptExecutable::prepareForExecutionImpl(
     return 0;
 }
 
-const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
+const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(EvalExecutable) };
 
-EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext
+EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode)
 {
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     if (!globalObject->evalEnabled()) {
@@ -338,7 +358,7 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source
     EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
     executable->finishCreation(exec->vm());
 
-    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable);
+    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode);
     if (!unlinkedEvalCode)
         return 0;
 
@@ -348,7 +368,7 @@ EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source
 }
 
 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
-    : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec, source, inStrictContext)
+    : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext)
 {
 }
 
@@ -357,11 +377,15 @@ void EvalExecutable::destroy(JSCell* cell)
     static_cast<EvalExecutable*>(cell)->EvalExecutable::~EvalExecutable();
 }
 
-const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
+const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
 
 ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
-    : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec, source, false)
+    : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false)
 {
+    m_typeProfilingStartOffset = 0;
+    m_typeProfilingEndOffset = source.length() - 1;
+    if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler())
+        exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset);
 }
 
 void ProgramExecutable::destroy(JSCell* cell)
@@ -369,13 +393,13 @@ void ProgramExecutable::destroy(JSCell* cell)
     static_cast<ProgramExecutable*>(cell)->ProgramExecutable::~ProgramExecutable();
 }
 
-const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
+const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
 
-FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces)
+FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, 
+    UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, 
+    unsigned lastLine, unsigned startColumn, unsigned endColumn)
     : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext())
     , m_unlinkedExecutable(vm, this, unlinkedExecutable)
-    , m_bodyIncludesBraces(bodyIncludesBraces)
-    , m_didParseForTheFirstTime(false)
 {
     RELEASE_ASSERT(!source.isNull());
     ASSERT(source.length());
@@ -385,6 +409,15 @@ FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, Unlinke
     ASSERT(endColumn != UINT_MAX);
     m_startColumn = startColumn;
     m_endColumn = endColumn;
+    m_parametersStartOffset = unlinkedExecutable->parametersStartOffset();
+    m_typeProfilingStartOffset = unlinkedExecutable->typeProfilingStartOffset();
+    m_typeProfilingEndOffset = unlinkedExecutable->typeProfilingEndOffset();
+}
+
+void FunctionExecutable::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    m_singletonFunction.set(vm, this, InferredValue::create(vm));
 }
 
 void FunctionExecutable::destroy(JSCell* cell)
@@ -413,8 +446,6 @@ void EvalExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     EvalExecutable* thisObject = jsCast<EvalExecutable*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     ScriptExecutable::visitChildren(thisObject, visitor);
     if (thisObject->m_evalCodeBlock)
         thisObject->m_evalCodeBlock->visitAggregate(visitor);
@@ -433,7 +464,7 @@ void EvalExecutable::unlinkCalls()
 
 void EvalExecutable::clearCode()
 {
-    m_evalCodeBlock.clear();
+    m_evalCodeBlock = nullptr;
     m_unlinkedEvalCodeBlock.clear();
     Base::clearCode();
 }
@@ -443,10 +474,12 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
     ParserError error;
     VM* vm = &exec->vm();
     JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
-    RefPtr<ProgramNode> programNode = parse<ProgramNode>(vm, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error);
+    std::unique_ptr<ProgramNode> programNode = parse<ProgramNode>(
+        vm, m_source, 0, Identifier(), JSParserBuiltinMode::NotBuiltin, 
+        JSParserStrictMode::NotStrict, JSParserCodeType::Program, error);
     if (programNode)
         return 0;
-    ASSERT(error.m_type != ParserError::ErrorNone);
+    ASSERT(error.isValid());
     return error.toErrorObject(lexicalGlobalObject, m_source);
 }
 
@@ -477,12 +510,16 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
     BatchedTransitionOptimizer optimizer(vm, globalObject);
 
     const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
-    const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations();
 
-    for (size_t i = 0; i < functionDeclarations.size(); ++i) {
-        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get();
-        JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, m_source, lineNo()), scope);
-        globalObject->addFunction(callFrame, functionDeclarations[i].first, value);
+    for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) {
+        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i);
+        ASSERT(!unlinkedFunctionExecutable->name().isEmpty());
+        globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name());
+        if (vm.typeProfiler() || vm.controlFlowProfiler()) {
+            vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), 
+                unlinkedFunctionExecutable->typeProfilingStartOffset(), 
+                unlinkedFunctionExecutable->typeProfilingEndOffset());
+        }
     }
 
     for (size_t i = 0; i < variableDeclarations.size(); ++i) {
@@ -498,8 +535,6 @@ void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     ProgramExecutable* thisObject = jsCast<ProgramExecutable*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     ScriptExecutable::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_unlinkedProgramCodeBlock);
     if (thisObject->m_programCodeBlock)
@@ -508,7 +543,7 @@ void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
 void ProgramExecutable::clearCode()
 {
-    m_programCodeBlock.clear();
+    m_programCodeBlock = nullptr;
     m_unlinkedProgramCodeBlock.clear();
     Base::clearCode();
 }
@@ -531,14 +566,13 @@ void FunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     FunctionExecutable* thisObject = jsCast<FunctionExecutable*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     ScriptExecutable::visitChildren(thisObject, visitor);
     if (thisObject->m_codeBlockForCall)
         thisObject->m_codeBlockForCall->visitAggregate(visitor);
     if (thisObject->m_codeBlockForConstruct)
         thisObject->m_codeBlockForConstruct->visitAggregate(visitor);
     visitor.append(&thisObject->m_unlinkedExecutable);
+    visitor.append(&thisObject->m_singletonFunction);
 }
 
 SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind)
@@ -546,24 +580,15 @@ SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind)
     return codeBlockFor(kind)->symbolTable();
 }
 
-void FunctionExecutable::clearCodeIfNotCompiling()
-{
-    if (isCompiling())
-        return;
-    clearCode();
-}
-
-void FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling()
+void FunctionExecutable::clearUnlinkedCodeForRecompilation()
 {
-    if (isCompiling())
-        return;
     m_unlinkedExecutable->clearCodeForRecompilation();
 }
 
 void FunctionExecutable::clearCode()
 {
-    m_codeBlockForCall.clear();
-    m_codeBlockForConstruct.clear();
+    m_codeBlockForCall = nullptr;
+    m_codeBlockForConstruct = nullptr;
     Base::clearCode();
 }
 
@@ -581,34 +606,17 @@ void FunctionExecutable::unlinkCalls()
 #endif
 }
 
-FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
+FunctionExecutable* FunctionExecutable::fromGlobalCode(
+    const Identifier& name, ExecState& exec, const SourceCode& source, 
+    JSObject*& exception, int overrideLineNumber)
 {
-    UnlinkedFunctionExecutable* unlinkedExecutable = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception);
+    UnlinkedFunctionExecutable* unlinkedExecutable = 
+        UnlinkedFunctionExecutable::fromGlobalCode(
+            name, exec, source, exception, overrideLineNumber);
     if (!unlinkedExecutable)
-        return 0;
-    unsigned lineCount = unlinkedExecutable->lineCount();
-    unsigned firstLine = source.firstLine() + unlinkedExecutable->firstLineOffset();
-    unsigned startOffset = source.startOffset() + unlinkedExecutable->startOffset();
-
-    // We don't have any owner executable. The source string is effectively like a global
-    // string (like in the handling of eval). Hence, the startColumn is always 1.
-    unsigned startColumn = 1;
-    unsigned sourceLength = unlinkedExecutable->sourceLength();
-    bool endColumnIsOnStartLine = !lineCount;
-    // The unlinkedBodyEndColumn is based-0. Hence, we need to add 1 to it. But if the
-    // endColumn is on the startLine, then we need to subtract back the adjustment for
-    // the open brace resulting in an adjustment of 0.
-    unsigned endColumnExcludingBraces = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? 0 : 1);
-    unsigned startOffsetExcludingOpenBrace = startOffset + 1;
-    unsigned endOffsetExcludingCloseBrace = startOffset + sourceLength - 1;
-    SourceCode bodySource(source.provider(), startOffsetExcludingOpenBrace, endOffsetExcludingCloseBrace, firstLine, startColumn);
+        return nullptr;
 
-    return FunctionExecutable::create(exec->vm(), bodySource, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumnExcludingBraces, false);
-}
-
-String FunctionExecutable::paramString() const
-{
-    return m_unlinkedExecutable->paramString();
+    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
 }
 
 void ExecutableBase::dump(PrintStream& out) const
index b58a57b38214d1a1761e490d36f1c0c0d192f20c..1c7c80003d2a32bd6a311dac0de53901a8ad781f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "CompilationResult.h"
 #include "DFGPlan.h"
 #include "HandlerInfo.h"
-#include "JSFunction.h"
-#include "Interpreter.h"
+#include "InferredValue.h"
 #include "JITCode.h"
 #include "JSGlobalObject.h"
 #include "RegisterPreservationMode.h"
 #include "SamplingTool.h"
 #include "SourceCode.h"
+#include "TypeSet.h"
 #include "UnlinkedCodeBlock.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 
@@ -63,8 +62,7 @@ inline bool isCall(CodeSpecializationKind kind)
     return false;
 }
 
-class ExecutableBase : public JSCell, public DoublyLinkedListNode<ExecutableBase> {
-    friend class WTF::DoublyLinkedListNode<ExecutableBase>;
+class ExecutableBase : public JSCell {
     friend class JIT;
 
 protected:
@@ -85,12 +83,10 @@ protected:
 
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
-#if ENABLE(JIT)
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
-#endif
         
     CodeBlockHash hashFor(CodeSpecializationKind) const;
 
@@ -113,14 +109,13 @@ public:
         return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
     }
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CompoundType, StructureFlags), info()); }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
         
     void clearCode();
 
     DECLARE_EXPORT_INFO;
 
 protected:
-    static const unsigned StructureFlags = StructureIsImmortal;
     int m_numParametersForCall;
     int m_numParametersForConstruct;
 
@@ -273,9 +268,6 @@ public:
     void dump(PrintStream&) const;
         
 protected:
-    ExecutableBase* m_prev;
-    ExecutableBase* m_next;
-
     RefPtr<JITCode> m_jitCodeForCall;
     RefPtr<JITCode> m_jitCodeForConstruct;
     MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
@@ -284,11 +276,12 @@ protected:
     MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheckAndPreserveRegs;
 };
 
-class NativeExecutable : public ExecutableBase {
+class NativeExecutable final : public ExecutableBase {
     friend class JIT;
     friend class LLIntOffsetsExtractor;
 public:
     typedef ExecutableBase Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic)
     {
@@ -298,9 +291,7 @@ public:
         return executable;
     }
 
-#if ENABLE(JIT)
     static void destroy(JSCell*);
-#endif
 
     CodeBlockHash hashFor(CodeSpecializationKind) const;
 
@@ -323,7 +314,7 @@ public:
         return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
     }
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(LeafType, StructureFlags), info()); }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
         
     DECLARE_INFO;
 
@@ -355,40 +346,24 @@ private:
 class ScriptExecutable : public ExecutableBase {
 public:
     typedef ExecutableBase Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
-    ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
-        : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
-        , m_source(source)
-        , m_features(isInStrictContext ? StrictModeFeature : 0)
-        , m_neverInline(false)
-        , m_startColumn(UINT_MAX)
-        , m_endColumn(UINT_MAX)
-    {
-    }
-
-    ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
-        : ExecutableBase(exec->vm(), structure, NUM_PARAMETERS_NOT_COMPILED)
-        , m_source(source)
-        , m_features(isInStrictContext ? StrictModeFeature : 0)
-        , m_neverInline(false)
-        , m_startColumn(UINT_MAX)
-        , m_endColumn(UINT_MAX)
-    {
-    }
-
-#if ENABLE(JIT)
     static void destroy(JSCell*);
-#endif
         
     CodeBlockHash hashFor(CodeSpecializationKind) const;
 
     const SourceCode& source() const { return m_source; }
     intptr_t sourceID() const { return m_source.providerID(); }
     const String& sourceURL() const { return m_source.provider()->url(); }
-    int lineNo() const { return m_firstLine; }
+    int firstLine() const { return m_firstLine; }
+    void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; }
+    bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; }
+    int overrideLineNumber() const { return m_overrideLineNumber; }
     int lastLine() const { return m_lastLine; }
     unsigned startColumn() const { return m_startColumn; }
     unsigned endColumn() const { return m_endColumn; }
+    unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
+    unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
 
     bool usesEval() const { return m_features & EvalFeature; }
     bool usesArguments() const { return m_features & ArgumentsFeature; }
@@ -397,8 +372,12 @@ public:
     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
         
     void setNeverInline(bool value) { m_neverInline = value; }
+    void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }
     bool neverInline() const { return m_neverInline; }
+    bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }
     bool isInliningCandidate() const { return !neverInline(); }
+    
+    bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; }
 
     void unlinkCalls();
         
@@ -419,10 +398,10 @@ public:
     }
 
     void installCode(CodeBlock*);
-    PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope**, JSObject*& exception);
+    RefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
     PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
     
-    JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope** scope, CodeSpecializationKind kind)
+    JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
     {
         if (hasJITCodeFor(kind))
             return 0;
@@ -432,9 +411,11 @@ public:
     template <typename Functor> void forEachCodeBlock(Functor&&);
 
 private:
-    JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope**, CodeSpecializationKind);
+    JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
 
 protected:
+    ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);
+
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
@@ -450,16 +431,21 @@ protected:
     CodeFeatures m_features;
     bool m_hasCapturedVariables;
     bool m_neverInline;
+    bool m_didTryToEnterInLoop;
+    int m_overrideLineNumber;
     int m_firstLine;
     int m_lastLine;
     unsigned m_startColumn;
     unsigned m_endColumn;
+    unsigned m_typeProfilingStartOffset;
+    unsigned m_typeProfilingEndOffset;
 };
 
-class EvalExecutable : public ScriptExecutable {
+class EvalExecutable final : public ScriptExecutable {
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static void destroy(JSCell*);
 
@@ -468,7 +454,7 @@ public:
         return m_evalCodeBlock.get();
     }
 
-    static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext);
+    static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode);
 
     PassRefPtr<JITCode> generatedJITCode()
     {
@@ -486,14 +472,13 @@ public:
 
     void clearCode();
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None); }
 
     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
 
 private:
     friend class ScriptExecutable;
-    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
     EvalExecutable(ExecState*, const SourceCode&, bool);
 
     static void visitChildren(JSCell*, SlotVisitor&);
@@ -502,10 +487,11 @@ private:
     WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
 };
 
-class ProgramExecutable : public ScriptExecutable {
+class ProgramExecutable final : public ScriptExecutable {
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
     {
@@ -542,12 +528,10 @@ public:
 
     void clearCode();
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None); }
 
 private:
     friend class ScriptExecutable;
-    
-    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
 
     ProgramExecutable(ExecState*, const SourceCode&);
 
@@ -557,19 +541,24 @@ private:
     RefPtr<ProgramCodeBlock> m_programCodeBlock;
 };
 
-class FunctionExecutable : public ScriptExecutable {
+class FunctionExecutable final : public ScriptExecutable {
     friend class JIT;
     friend class LLIntOffsetsExtractor;
 public:
     typedef ScriptExecutable Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-    static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces = true)
+    static FunctionExecutable* create(
+        VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, 
+        unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn)
     {
-        FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn, bodyIncludesBraces);
+        FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn);
         executable->finishCreation(vm);
         return executable;
     }
-    static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+    static FunctionExecutable* fromGlobalCode(
+        const Identifier& name, ExecState&, const SourceCode&, 
+        JSObject*& exception, int overrideLineNumber);
 
     static void destroy(JSCell*);
         
@@ -630,54 +619,63 @@ public:
     {
         return baselineCodeBlockFor(kind);
     }
+
+    RefPtr<TypeSet> returnStatementTypeSet() 
+    {
+        if (!m_returnStatementTypeSet)
+            m_returnStatementTypeSet = TypeSet::create();
+
+        return m_returnStatementTypeSet;
+    }
         
     FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
     bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
+    bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
     const Identifier& name() { return m_unlinkedExecutable->name(); }
     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
     size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
-    String paramString() const;
     SymbolTable* symbolTable(CodeSpecializationKind);
 
-    void clearCodeIfNotCompiling();
-    void clearUnlinkedCodeForRecompilationIfNotCompiling();
+    void clearUnlinkedCodeForRecompilation();
     static void visitChildren(JSCell*, SlotVisitor&);
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     {
         return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info());
     }
-        
+
+    unsigned parametersStartOffset() const { return m_parametersStartOffset; }
+
+    void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset)
+    {
+        m_parametersStartOffset = parametersStartOffset;
+        m_typeProfilingStartOffset = typeProfilingStartOffset;
+        m_typeProfilingEndOffset = typeProfilingEndOffset;
+    }
+
     DECLARE_INFO;
         
     void unlinkCalls();
 
     void clearCode();
-
-    bool bodyIncludesBraces() const { return m_bodyIncludesBraces; }
+    
+    InferredValue* singletonFunction() { return m_singletonFunction.get(); }
 
 private:
-    FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces);
-
-    bool isCompiling()
-    {
-#if ENABLE(JIT)
-        if (!m_jitCodeForCall && m_codeBlockForCall)
-            return true;
-        if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
-            return true;
-#endif
-        return false;
-    }
+    FunctionExecutable(
+        VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, 
+        unsigned lastLine, unsigned startColumn, unsigned endColumn);
+    
+    void finishCreation(VM&);
 
     friend class ScriptExecutable;
-
-    static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
+    
     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
     RefPtr<FunctionCodeBlock> m_codeBlockForCall;
     RefPtr<FunctionCodeBlock> m_codeBlockForConstruct;
-    bool m_bodyIncludesBraces;
-    bool m_didParseForTheFirstTime;
+    RefPtr<TypeSet> m_returnStatementTypeSet;
+    unsigned m_parametersStartOffset;
+    WriteBarrier<InferredValue> m_singletonFunction;
 };
 
 inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
index 3fc724220833118c88d4db5f99d0fa113bef140f..dbe42fa5fe26304e86ee2013b100cabb221c429c 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(FunctionConstructor);
 
-const ClassInfo FunctionConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionConstructor) };
+const ClassInfo FunctionConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(FunctionConstructor) };
 
 FunctionConstructor::FunctionConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
@@ -86,33 +86,37 @@ JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const
     return constructFunctionSkippingEvalEnabledCheck(exec, globalObject, args, functionName, sourceURL, position);
 }
 
-JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const String& sourceURL, const TextPosition& position)
+JSObject* constructFunctionSkippingEvalEnabledCheck(
+    ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, 
+    const Identifier& functionName, const String& sourceURL, 
+    const TextPosition& position, int overrideLineNumber)
 {
-    // Functions need to have a space following the opening { due to for web compatibility
-    // see https://bugs.webkit.org/show_bug.cgi?id=24350
-    // We also need \n before the closing } to handle // comments at the end of the last line
+    // How we stringify functions is sometimes important for web compatibility.
+    // See https://bugs.webkit.org/show_bug.cgi?id=24350.
     String program;
     if (args.isEmpty())
-        program = ASCIILiteral("(function() {\n})");
+        program = makeString("{function ", functionName.string(), "() {\n\n}}");
     else if (args.size() == 1)
-        program = makeString("(function() {", args.at(0).toString(exec)->value(exec), "\n})");
+        program = makeString("{function ", functionName.string(), "() {\n", args.at(0).toString(exec)->value(exec), "\n}}");
     else {
         StringBuilder builder;
-        builder.appendLiteral("(function(");
-        builder.append(args.at(0).toString(exec)->value(exec));
+        builder.appendLiteral("{function ");
+        builder.append(functionName.string());
+        builder.append('(');
+        builder.append(args.at(0).toString(exec)->view(exec));
         for (size_t i = 1; i < args.size() - 1; i++) {
-            builder.append(',');
-            builder.append(args.at(i).toString(exec)->value(exec));
+            builder.appendLiteral(", ");
+            builder.append(args.at(i).toString(exec)->view(exec));
         }
-        builder.appendLiteral(") {");
-        builder.append(args.at(args.size() - 1).toString(exec)->value(exec));
-        builder.appendLiteral("\n})");
+        builder.appendLiteral(") {\n");
+        builder.append(args.at(args.size() - 1).toString(exec)->view(exec));
+        builder.appendLiteral("\n}}");
         program = builder.toString();
     }
 
     SourceCode source = makeSource(program, sourceURL, position);
-    JSObject* exception = 0;
-    FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->vmEntryGlobalObject()->debugger(), source, &exception);
+    JSObject* exception = nullptr;
+    FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, *exec, source, exception, overrideLineNumber);
     if (!function) {
         ASSERT(exception);
         return exec->vm().throwException(exec, exception);
index 61443e944d8c7e4347b67a6071c66785b211e71c..22ecb57b93f69bfc9f8b1b306fb4c42a0a67d2e3 100644 (file)
@@ -29,37 +29,39 @@ class TextPosition;
 
 namespace JSC {
 
-    class FunctionPrototype;
+class FunctionPrototype;
 
-    class FunctionConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class FunctionConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
 
-        static FunctionConstructor* create(VM& vm, Structure* structure, FunctionPrototype* functionPrototype)
-        {
-            FunctionConstructor* constructor = new (NotNull, allocateCell<FunctionConstructor>(vm.heap)) FunctionConstructor(vm, structure);
-            constructor->finishCreation(vm, functionPrototype);
-            return constructor;
-        }
+    static FunctionConstructor* create(VM& vm, Structure* structure, FunctionPrototype* functionPrototype)
+    {
+        FunctionConstructor* constructor = new (NotNull, allocateCell<FunctionConstructor>(vm.heap)) FunctionConstructor(vm, structure);
+        constructor->finishCreation(vm, functionPrototype);
+        return constructor;
+    }
 
-        DECLARE_INFO;
+    DECLARE_INFO;
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-        
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    { 
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
+    }
 
-    private:
-        FunctionConstructor(VM&, Structure*);
-        void finishCreation(VM&, FunctionPrototype*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-    };
+private:
+    FunctionConstructor(VM&, Structure*);
+    void finishCreation(VM&, FunctionPrototype*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
 
-    JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&);
-    JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
+JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&);
+JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
 
-    JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&);
+JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(
+    ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, 
+    const String&, const WTF::TextPosition&, int overrideLineNumber = -1);
 
 } // namespace JSC
 
diff --git a/runtime/FunctionHasExecutedCache.cpp b/runtime/FunctionHasExecutedCache.cpp
new file mode 100644 (file)
index 0000000..3d7e31b
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FunctionHasExecutedCache.h"
+
+#include <limits.h>
+
+namespace JSC {
+
+bool FunctionHasExecutedCache::hasExecutedAtOffset(intptr_t id, unsigned offset)
+{
+    if (m_rangeMap.find(id) == m_rangeMap.end())
+        return false;
+
+    RangeMap& map = m_rangeMap.find(id)->second;
+    unsigned distance = UINT_MAX;
+    bool hasExecuted = false;
+    for (auto iter = map.begin(), end = map.end(); iter != end; ++iter) {
+        const FunctionRange& range = iter->first;
+        if (range.m_start <= offset && offset <= range.m_end && range.m_end - range.m_start < distance) {
+            hasExecuted = iter->second;
+            distance = range.m_end - range.m_start;
+        }
+    }
+
+    return hasExecuted;
+}
+
+void FunctionHasExecutedCache::insertUnexecutedRange(intptr_t id, unsigned start, unsigned end) 
+{
+    if (m_rangeMap.find(id) == m_rangeMap.end()) {
+        RangeMap map;
+        m_rangeMap[id] = map;
+    }
+
+    RangeMap& map = m_rangeMap.find(id)->second;
+    FunctionRange range;
+    range.m_start = start;
+    range.m_end = end;
+    // Only insert unexecuted ranges once for a given sourceID because we may run into a situation where an executable executes, then is GCed, and then is allocated again,
+    // and tries to reinsert itself, claiming it has never run, but this is false because it indeed already executed.
+    if (map.find(range) == map.end())
+        map[range] = false;
+}
+
+void FunctionHasExecutedCache::removeUnexecutedRange(intptr_t id, unsigned start, unsigned end)
+{
+    // FIXME: We should never have an instance where we return here, but currently do in some situations. Find out why.
+    if (m_rangeMap.find(id) == m_rangeMap.end())
+        return;
+
+    RangeMap& map = m_rangeMap.find(id)->second;
+
+    FunctionRange range;
+    range.m_start = start;
+    range.m_end = end;
+    map[range] = true;
+}
+
+Vector<std::tuple<bool, unsigned, unsigned>> FunctionHasExecutedCache::getFunctionRanges(intptr_t id)
+{
+    Vector<std::tuple<bool, unsigned, unsigned>> ranges(0);
+    auto findResult = m_rangeMap.find(id);
+    if (findResult == m_rangeMap.end())
+        return ranges;
+
+    RangeMap& map = m_rangeMap.find(id)->second;
+    for (auto iter = map.begin(), end = map.end(); iter != end; ++iter) {
+        const FunctionRange& range = iter->first;
+        bool hasExecuted = iter->second;
+        ranges.append(std::tuple<bool, unsigned, unsigned>(hasExecuted, range.m_start, range.m_end));
+    }
+
+    return ranges;
+}
+
+} // namespace JSC
diff --git a/runtime/FunctionHasExecutedCache.h b/runtime/FunctionHasExecutedCache.h
new file mode 100644 (file)
index 0000000..7f3eb97
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FunctionHasExecutedCache_h
+#define FunctionHasExecutedCache_h
+
+#include <unordered_map>
+#include <wtf/HashMethod.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class FunctionHasExecutedCache {
+public:
+    struct FunctionRange {
+        FunctionRange() {}
+        bool operator==(const FunctionRange& other) const 
+        {
+            return m_start == other.m_start && m_end == other.m_end;
+        }
+        unsigned hash() const
+        {
+            return m_start * m_end;
+        }
+
+        unsigned m_start;
+        unsigned m_end;
+    };
+
+    bool hasExecutedAtOffset(intptr_t id, unsigned offset);
+    void insertUnexecutedRange(intptr_t id, unsigned start, unsigned end);
+    void removeUnexecutedRange(intptr_t id, unsigned start, unsigned end);
+    Vector<std::tuple<bool, unsigned, unsigned>> getFunctionRanges(intptr_t id);
+
+private:     
+    typedef std::unordered_map<FunctionRange, bool, HashMethod<FunctionRange>> RangeMap;
+    typedef std::unordered_map<intptr_t, RangeMap> SourceIDToRangeMap;
+    SourceIDToRangeMap m_rangeMap;
+};
+
+} // namespace JSC
+
+#endif // FunctionHasExecutedCache_h
index eb57840bd667bf3ad269a3047bda0a9483152c6b..d082b12cf5bb3083834847bb0649f0d385205088 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -21,9 +21,9 @@
 #include "config.h"
 #include "FunctionPrototype.h"
 
-#include "Arguments.h"
 #include "BuiltinExecutables.h"
 #include "BuiltinNames.h"
+#include "Error.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
@@ -37,7 +37,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(FunctionPrototype);
 
-const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionPrototype) };
+const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(FunctionPrototype) };
 
 static EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState*);
@@ -79,27 +79,6 @@ CallType FunctionPrototype::getCallData(JSCell*, CallData& callData)
     return CallTypeHost;
 }
 
-// Functions
-
-// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
-static inline void insertSemicolonIfNeeded(String& functionBody, bool bodyIncludesBraces)
-{
-    if (!bodyIncludesBraces)
-        functionBody = makeString("{ ", functionBody, "}");
-
-    ASSERT(functionBody[0] == '{');
-    ASSERT(functionBody[functionBody.length() - 1] == '}');
-
-    for (size_t i = functionBody.length() - 2; i > 0; --i) {
-        UChar ch = functionBody[i];
-        if (!Lexer<UChar>::isWhiteSpace(ch) && !Lexer<UChar>::isLineTerminator(ch)) {
-            if (ch != ';' && ch != '}')
-                functionBody = makeString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1)));
-            return;
-        }
-    }
-}
-
 EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
@@ -107,10 +86,12 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
         JSFunction* function = jsCast<JSFunction*>(thisValue);
         if (function->isHostOrBuiltinFunction())
             return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n    [native code]\n}"));
+
         FunctionExecutable* executable = function->jsExecutable();
-        String sourceString = executable->source().toString();
-        insertSemicolonIfNeeded(sourceString, executable->bodyIncludesBraces());
-        return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
+        String source = executable->source().provider()->getRange(
+            executable->parametersStartOffset(),
+            executable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'.
+        return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), source));
     }
 
     if (thisValue.inherits(InternalFunction::info())) {
index 68d2f6a811c60d6f1e8d2206e8b4843f13c7d37a..52ce8f11c5dd7d1031556903e5acab0d2ad4c0f8 100644 (file)
 
 namespace JSC {
 
-    class FunctionPrototype : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
-
-        static FunctionPrototype* create(VM& vm, Structure* structure)
-        {
-            FunctionPrototype* prototype = new (NotNull, allocateCell<FunctionPrototype>(vm.heap)) FunctionPrototype(vm, structure);
-            prototype->finishCreation(vm, String());
-            return prototype;
-        }
-        
-        void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
-        
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
-        {
-            return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-        DECLARE_INFO;
-
-    protected:
-        void finishCreation(VM&, const String& name);
-
-    private:
-        FunctionPrototype(VM&, Structure*);
-        static CallType getCallData(JSCell*, CallData&);
-    };
+class FunctionPrototype : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+
+    static FunctionPrototype* create(VM& vm, Structure* structure)
+    {
+        FunctionPrototype* prototype = new (NotNull, allocateCell<FunctionPrototype>(vm.heap)) FunctionPrototype(vm, structure);
+        prototype->finishCreation(vm, String());
+        return prototype;
+    }
+
+    void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+    {
+        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    DECLARE_INFO;
+
+protected:
+    void finishCreation(VM&, const String& name);
+
+private:
+    FunctionPrototype(VM&, Structure*);
+    static CallType getCallData(JSCell*, CallData&);
+};
 
 } // namespace JSC
 
diff --git a/runtime/FunctionRareData.cpp b/runtime/FunctionRareData.cpp
new file mode 100644 (file)
index 0000000..d44c323
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "FunctionRareData.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo FunctionRareData::s_info = { "FunctionRareData", 0, 0, CREATE_METHOD_TABLE(FunctionRareData) };
+
+FunctionRareData* FunctionRareData::create(VM& vm, JSObject* prototype, size_t inlineCapacity)
+{
+    FunctionRareData* rareData = new (NotNull, allocateCell<FunctionRareData>(vm.heap)) FunctionRareData(vm);
+    rareData->finishCreation(vm, prototype, inlineCapacity);
+    return rareData;
+}
+
+void FunctionRareData::destroy(JSCell* cell)
+{
+    FunctionRareData* rareData = static_cast<FunctionRareData*>(cell);
+    rareData->FunctionRareData::~FunctionRareData();
+}
+
+Structure* FunctionRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+void FunctionRareData::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    FunctionRareData* rareData = jsCast<FunctionRareData*>(cell);
+
+    rareData->m_allocationProfile.visitAggregate(visitor);
+}
+
+FunctionRareData::FunctionRareData(VM& vm)
+    : Base(vm, vm.functionRareDataStructure.get())
+    , m_allocationProfile()
+    // We initialize blind so that changes to the prototype after function creation but before
+    // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
+    // watchpoint will start watching and any changes will both force deoptimization and disable
+    // future attempts to optimize. This is necessary because we are guaranteed that the
+    // allocation profile is changed exactly once prior to optimizations kicking in. We could be
+    // smarter and count the number of times the prototype is clobbered and only optimize if it
+    // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
+    // clobbered once, and if it's clobbered more than once, that will probably only occur
+    // before we started optimizing, anyway.
+    , m_allocationProfileWatchpoint(ClearWatchpoint)
+{
+}
+
+FunctionRareData::~FunctionRareData()
+{
+}
+
+void FunctionRareData::finishCreation(VM& vm, JSObject* prototype, size_t inlineCapacity)
+{
+    Base::finishCreation(vm);
+    initialize(vm, prototype, inlineCapacity);
+}
+
+void FunctionRareData::initialize(VM& vm, JSObject* prototype, size_t inlineCapacity)
+{
+    m_allocationProfile.initialize(vm, this, prototype, inlineCapacity);
+}
+
+void FunctionRareData::clear(const char* reason)
+{
+    m_allocationProfile.clear();
+    m_allocationProfileWatchpoint.fireAll(reason);
+}
+
+}
diff --git a/runtime/FunctionRareData.h b/runtime/FunctionRareData.h
new file mode 100644 (file)
index 0000000..f0a2db2
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FunctionRareData_h
+#define FunctionRareData_h
+
+#include "JSCell.h"
+#include "ObjectAllocationProfile.h"
+#include "Watchpoint.h"
+
+namespace JSC {
+
+class JSGlobalObject;
+class LLIntOffsetsExtractor;
+namespace DFG {
+class SpeculativeJIT;
+class JITCompiler;
+}
+
+class FunctionRareData : public JSCell {
+    friend class JIT;
+    friend class DFG::SpeculativeJIT;
+    friend class DFG::JITCompiler;
+    friend class VM;
+    
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+
+    static FunctionRareData* create(VM&, JSObject* prototype, size_t inlineCapacity);
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    DECLARE_INFO;
+
+    static inline ptrdiff_t offsetOfAllocationProfile()
+    {
+        return OBJECT_OFFSETOF(FunctionRareData, m_allocationProfile);
+    }
+
+    ObjectAllocationProfile* allocationProfile()
+    {
+        return &m_allocationProfile;
+    }
+
+    Structure* allocationStructure() { return m_allocationProfile.structure(); }
+
+    InlineWatchpointSet& allocationProfileWatchpointSet()
+    {
+        return m_allocationProfileWatchpoint;
+    }
+
+    void clear(const char* reason);
+
+    void initialize(VM&, JSObject* prototype, size_t inlineCapacity);
+
+    bool isInitialized() { return !m_allocationProfile.isNull(); }
+
+protected:
+    FunctionRareData(VM&);
+    ~FunctionRareData();
+
+    void finishCreation(VM&, JSObject* prototype, size_t inlineCapacity);
+    using Base::finishCreation;
+
+private:
+
+    friend class LLIntOffsetsExtractor;
+
+    ObjectAllocationProfile m_allocationProfile;
+    InlineWatchpointSet m_allocationProfileWatchpoint;
+};
+
+} // namespace JSC
+
+#endif // FunctionRareData_h
diff --git a/runtime/GenericArguments.h b/runtime/GenericArguments.h
new file mode 100644 (file)
index 0000000..67f1b03
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericArguments_h
+#define GenericArguments_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+// This is a mixin for the two kinds of Arguments-class objects that arise when you say
+// "arguments" inside a function. This class doesn't show up in the JSCell inheritance hierarchy.
+template<typename Type>
+class GenericArguments : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
+
+protected:
+    GenericArguments(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+};
+
+} // namespace JSC
+
+#endif // GenericArguments_h
+
diff --git a/runtime/GenericArgumentsInlines.h b/runtime/GenericArgumentsInlines.h
new file mode 100644 (file)
index 0000000..5f952c6
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericArgumentsInlines_h
+#define GenericArgumentsInlines_h
+
+#include "GenericArguments.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+template<typename Type>
+bool GenericArguments<Type>::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()) {
+        if (ident == vm.propertyNames->length) {
+            slot.setValue(thisObject, DontEnum, jsNumber(thisObject->internalLength()));
+            return true;
+        }
+        if (ident == vm.propertyNames->callee) {
+            slot.setValue(thisObject, DontEnum, thisObject->callee().get());
+            return true;
+        }
+        if (ident == vm.propertyNames->iteratorSymbol) {
+            slot.setValue(thisObject, DontEnum, thisObject->globalObject()->arrayProtoValuesFunction());
+            return true;
+        }
+    }
+    
+    Optional<uint32_t> index = parseIndex(ident);
+    if (index && thisObject->canAccessIndexQuickly(index.value())) {
+        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index.value()));
+        return true;
+    }
+    
+    return Base::getOwnPropertySlot(thisObject, exec, ident, slot);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    
+    if (thisObject->canAccessIndexQuickly(index)) {
+        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
+        return true;
+    }
+    
+    return Base::getOwnPropertySlotByIndex(object, exec, index, slot);
+}
+
+template<typename Type>
+void GenericArguments<Type>::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    
+    for (unsigned i = 0; i < thisObject->internalLength(); ++i) {
+        if (!thisObject->canAccessIndexQuickly(i))
+            continue;
+        array.add(Identifier::from(exec, i));
+    }
+    if (mode.includeDontEnumProperties() && !thisObject->overrodeThings()) {
+        array.add(exec->propertyNames().length);
+        array.add(exec->propertyNames().callee);
+        if (mode.includeSymbolProperties())
+            array.add(exec->propertyNames().iteratorSymbol);
+    }
+    Base::getOwnPropertyNames(thisObject, exec, array, mode);
+}
+
+template<typename Type>
+void GenericArguments<Type>::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()
+        && (ident == vm.propertyNames->length
+            || ident == vm.propertyNames->callee
+            || ident == vm.propertyNames->iteratorSymbol)) {
+        thisObject->overrideThings(vm);
+        PutPropertySlot dummy = slot; // This put is not cacheable, so we shadow the slot that was given to us.
+        Base::put(thisObject, exec, ident, value, dummy);
+        return;
+    }
+    
+    Optional<uint32_t> index = parseIndex(ident);
+    if (index && thisObject->canAccessIndexQuickly(index.value())) {
+        thisObject->setIndexQuickly(vm, index.value(), value);
+        return;
+    }
+    
+    Base::put(thisObject, exec, ident, value, slot);
+}
+
+template<typename Type>
+void GenericArguments<Type>::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool shouldThrow)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->setIndexQuickly(vm, index, value);
+        return;
+    }
+    
+    return Base::putByIndex(cell, exec, index, value, shouldThrow);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()
+        && (ident == vm.propertyNames->length
+            || ident == vm.propertyNames->callee
+            || ident == vm.propertyNames->iteratorSymbol))
+        thisObject->overrideThings(vm);
+    
+    Optional<uint32_t> index = parseIndex(ident);
+    if (index && thisObject->canAccessIndexQuickly(index.value())) {
+        thisObject->overrideArgument(vm, index.value());
+        return true;
+    }
+    
+    return Base::deleteProperty(thisObject, exec, ident);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned index)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->overrideArgument(vm, index);
+        return true;
+    }
+    
+    return Base::deletePropertyByIndex(cell, exec, index);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->length
+        || ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->iteratorSymbol)
+        thisObject->overrideThingsIfNecessary(vm);
+    else {
+        Optional<uint32_t> optionalIndex = parseIndex(ident);
+        if (optionalIndex && thisObject->canAccessIndexQuickly(optionalIndex.value())) {
+            uint32_t index = optionalIndex.value();
+            if (!descriptor.isAccessorDescriptor()) {
+                // If the property is not deleted and we are using a non-accessor descriptor, then
+                // make sure that the aliased argument sees the value.
+                if (descriptor.value())
+                    thisObject->setIndexQuickly(vm, index, descriptor.value());
+            
+                // If the property is not deleted and we are using a non-accessor, writable
+                // descriptor, then we are done. The argument continues to be aliased. Note that we
+                // ignore the request to change enumerability. We appear to have always done so, in
+                // cases where the argument was still aliased.
+                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
+                if (descriptor.writable())
+                    return true;
+            }
+        
+            // If the property is a non-deleted argument, then move it into the base object and
+            // then delete it.
+            JSValue value = thisObject->getIndexQuickly(index);
+            ASSERT(value);
+            object->putDirectMayBeIndex(exec, ident, value);
+            thisObject->overrideArgument(vm, index);
+        }
+    }
+    
+    // Now just let the normal object machinery do its thing.
+    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
+}
+
+template<typename Type>
+void GenericArguments<Type>::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    Type* thisObject = static_cast<Type*>(this);
+    for (unsigned i = 0; i < length; ++i) {
+        if (thisObject->canAccessIndexQuickly(i + offset))
+            exec->r(firstElementDest + i) = thisObject->getIndexQuickly(i + offset);
+        else {
+            exec->r(firstElementDest + i) = get(exec, i + offset);
+            if (UNLIKELY(exec->vm().exception()))
+                return;
+        }
+    }
+}
+
+} // namespace JSC
+
+#endif // GenericArgumentsInlines_h
+
diff --git a/runtime/GenericOffset.h b/runtime/GenericOffset.h
new file mode 100644 (file)
index 0000000..a6bfe56
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericOffset_h
+#define GenericOffset_h
+
+#include <limits.h>
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// A mixin for creating the various kinds of variable offsets that our engine supports.
+template<typename T>
+class GenericOffset {
+public:
+    static const unsigned invalidOffset = UINT_MAX;
+    
+    GenericOffset()
+        : m_offset(invalidOffset)
+    {
+    }
+    
+    explicit GenericOffset(unsigned offset)
+        : m_offset(offset)
+    {
+    }
+    
+    bool operator!() const { return m_offset == invalidOffset; }
+    
+    unsigned offsetUnchecked() const
+    {
+        return m_offset;
+    }
+    
+    unsigned offset() const
+    {
+        ASSERT(m_offset != invalidOffset);
+        return m_offset;
+    }
+    
+    bool operator==(const T& other) const
+    {
+        return m_offset == other.offsetUnchecked();
+    }
+    bool operator!=(const T& other) const
+    {
+        return m_offset != other.offsetUnchecked();
+    }
+    bool operator<(const T& other) const
+    {
+        return m_offset < other.offsetUnchecked();
+    }
+    bool operator>(const T& other) const
+    {
+        return m_offset > other.offsetUnchecked();
+    }
+    bool operator<=(const T& other) const
+    {
+        return m_offset <= other.offsetUnchecked();
+    }
+    bool operator>=(const T& other) const
+    {
+        return m_offset >= other.offsetUnchecked();
+    }
+    
+    T operator+(int value) const
+    {
+        return T(offset() + value);
+    }
+    T operator-(int value) const
+    {
+        return T(offset() - value);
+    }
+    T& operator+=(int value)
+    {
+        return *this = *this + value;
+    }
+    T& operator-=(int value)
+    {
+        return *this = *this - value;
+    }
+    
+private:
+    unsigned m_offset;
+};
+
+} // namespace JSC
+
+#endif // GenericOffset_h
+
index 0069b386d750cd22fc016294202c60f643b8d31a..36e37ca32b1e42c759a04cf748241efad285aa0e 100644 (file)
@@ -37,11 +37,11 @@ protected:
     GenericTypedArrayView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
 
 public:
-    static PassRefPtr<GenericTypedArrayView> create(unsigned length);
-    static PassRefPtr<GenericTypedArrayView> create(const typename Adaptor::Type* array, unsigned length);
-    static PassRefPtr<GenericTypedArrayView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
+    static RefPtr<GenericTypedArrayView> create(unsigned length);
+    static RefPtr<GenericTypedArrayView> create(const typename Adaptor::Type* array, unsigned length);
+    static RefPtr<GenericTypedArrayView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
     
-    static PassRefPtr<GenericTypedArrayView> createUninitialized(unsigned length);
+    static RefPtr<GenericTypedArrayView> createUninitialized(unsigned length);
     
     typename Adaptor::Type* data() const { return static_cast<typename Adaptor::Type*>(baseAddress()); }
     
@@ -98,8 +98,8 @@ public:
             && offset + pos >= offset);
     }
     
-    PassRefPtr<GenericTypedArrayView> subarray(int start) const;
-    PassRefPtr<GenericTypedArrayView> subarray(int start, int end) const;
+    RefPtr<GenericTypedArrayView> subarray(int start) const;
+    RefPtr<GenericTypedArrayView> subarray(int start, int end) const;
     
     virtual TypedArrayType getType() const override
     {
index 1289c50357588c79149cee64e63b847a951dfcaf..253726965a662741fccf0fa62f0e1b2400edd8e7 100644 (file)
@@ -40,16 +40,16 @@ GenericTypedArrayView<Adaptor>::GenericTypedArrayView(
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(unsigned length)
+RefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(unsigned length)
 {
     RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(typename Adaptor::Type));
     if (!buffer)
-        return 0;
-    return create(buffer, 0, length);
+        return nullptr;
+    return create(buffer.release(), 0, length);
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(
+RefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(
     const typename Adaptor::Type* array, unsigned length)
 {
     RefPtr<GenericTypedArrayView> result = create(length);
@@ -58,36 +58,38 @@ PassRefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::creat
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(
+RefPtr<GenericTypedArrayView<Adaptor>> GenericTypedArrayView<Adaptor>::create(
     PassRefPtr<ArrayBuffer> passedBuffer, unsigned byteOffset, unsigned length)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!verifySubRange<typename Adaptor::Type>(buffer, byteOffset, length))
-        return 0;
+    if (!verifySubRangeLength(buffer, byteOffset, length, sizeof(typename Adaptor::Type))
+        || !verifyByteOffsetAlignment(byteOffset, sizeof(typename Adaptor::Type))) {
+        return nullptr;
+    }
     
-    return adoptRef(new GenericTypedArrayView(buffer, byteOffset, length));
+    return adoptRef(new GenericTypedArrayView(buffer.release(), byteOffset, length));
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>>
+RefPtr<GenericTypedArrayView<Adaptor>>
 GenericTypedArrayView<Adaptor>::createUninitialized(unsigned length)
 {
     RefPtr<ArrayBuffer> buffer =
         ArrayBuffer::createUninitialized(length, sizeof(typename Adaptor::Type));
     if (!buffer)
-        return 0;
-    return create(buffer, 0, length);
+        return nullptr;
+    return create(buffer.release(), 0, length);
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>>
+RefPtr<GenericTypedArrayView<Adaptor>>
 GenericTypedArrayView<Adaptor>::subarray(int start) const
 {
     return subarray(start, length());
 }
 
 template<typename Adaptor>
-PassRefPtr<GenericTypedArrayView<Adaptor>>
+RefPtr<GenericTypedArrayView<Adaptor>>
 GenericTypedArrayView<Adaptor>::subarray(int start, int end) const
 {
     unsigned offset, length;
index 3de956ac6624633d05732c034e97b6ee88a78522..2cd66e5cd42fd01db52de0d76bcf4d2191ef7cb9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2004, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2004, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -24,6 +24,7 @@
 #include "GetterSetter.h"
 
 #include "Error.h"
+#include "Exception.h"
 #include "JSObject.h"
 #include "JSCInlines.h"
 #include <wtf/Assertions.h>
@@ -32,29 +33,52 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(GetterSetter);
 
-const ClassInfo GetterSetter::s_info = { "GetterSetter", 0, 0, 0, CREATE_METHOD_TABLE(GetterSetter) };
+const ClassInfo GetterSetter::s_info = { "GetterSetter", 0, 0, CREATE_METHOD_TABLE(GetterSetter) };
 
 void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     GetterSetter* thisObject = jsCast<GetterSetter*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     JSCell::visitChildren(thisObject, visitor);
 
     visitor.append(&thisObject->m_getter);
     visitor.append(&thisObject->m_setter);
 }
 
+GetterSetter* GetterSetter::withGetter(VM& vm, JSGlobalObject* globalObject, JSObject* newGetter)
+{
+    if (isGetterNull()) {
+        setGetter(vm, globalObject, newGetter);
+        return this;
+    }
+    
+    GetterSetter* result = GetterSetter::create(vm, globalObject);
+    result->setGetter(vm, globalObject, newGetter);
+    result->setSetter(vm, globalObject, setter());
+    return result;
+}
+
+GetterSetter* GetterSetter::withSetter(VM& vm, JSGlobalObject* globalObject, JSObject* newSetter)
+{
+    if (isSetterNull()) {
+        setSetter(vm, globalObject, newSetter);
+        return this;
+    }
+    
+    GetterSetter* result = GetterSetter::create(vm, globalObject);
+    result->setGetter(vm, globalObject, getter());
+    result->setSetter(vm, globalObject, newSetter);
+    return result;
+}
+
 JSValue callGetter(ExecState* exec, JSValue base, JSValue getterSetter)
 {
     // FIXME: Some callers may invoke get() without checking for an exception first.
     // We work around that by checking here.
     if (exec->hadException())
-        return exec->exception();
+        return exec->exception()->value();
 
     JSObject* getter = jsCast<GetterSetter*>(getterSetter)->getter();
-    if (!getter)
-        return jsUndefined();
 
     CallData callData;
     CallType callType = getter->methodTable(exec->vm())->getCallData(getter, callData);
@@ -63,13 +87,16 @@ JSValue callGetter(ExecState* exec, JSValue base, JSValue getterSetter)
 
 void callSetter(ExecState* exec, JSValue base, JSValue getterSetter, JSValue value, ECMAMode ecmaMode)
 {
-    JSObject* setter = jsCast<GetterSetter*>(getterSetter)->setter();
-    if (!setter) {
+    GetterSetter* getterSetterObj = jsCast<GetterSetter*>(getterSetter);
+
+    if (getterSetterObj->isSetterNull()) {
         if (ecmaMode == StrictMode)
             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
         return;
     }
 
+    JSObject* setter = getterSetterObj->setter();
+
     MarkedArgumentBuffer args;
     args.append(value);
 
index bc5cbe0afb1325f1d14f7af26fa9fc956e942ae4..b983f043dc03eb608bb7e0732e3c89361f2b779f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #include "JSCell.h"
 
 #include "CallFrame.h"
+#include "JSGlobalObject.h"
+#include "NullGetterFunction.h"
+#include "NullSetterFunction.h"
 #include "Structure.h"
 
 namespace JSC {
 
-    class JSObject;
-
-    // This is an internal value object which stores getter and setter functions
-    // for a property.
-    class GetterSetter : public JSCell {
-        friend class JIT;
-
-    private:        
-        GetterSetter(VM& vm)
-            : JSCell(vm, vm.getterSetterStructure.get())
-        {
-        }
-
-    public:
-        typedef JSCell Base;
-
-        static GetterSetter* create(VM& vm)
-        {
-            GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm);
-            getterSetter->finishCreation(vm);
-            return getterSetter;
-        }
-
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-        JSObject* getter() const { return m_getter.get(); }
-        void setGetter(VM& vm, JSObject* getter) { m_getter.setMayBeNull(vm, this, getter); }
-        JSObject* setter() const { return m_setter.get(); }
-        void setSetter(VM& vm, JSObject* setter) { m_setter.setMayBeNull(vm, this, setter); }
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType, OverridesVisitChildren), info());
-        }
-        
-        static ptrdiff_t offsetOfGetter()
-        {
-            return OBJECT_OFFSETOF(GetterSetter, m_getter);
-        }
-        
-        static ptrdiff_t offsetOfSetter()
-        {
-            return OBJECT_OFFSETOF(GetterSetter, m_setter);
-        }
-        
-        DECLARE_INFO;
-
-    private:
-        WriteBarrier<JSObject> m_getter;
-        WriteBarrier<JSObject> m_setter;  
-    };
-
-    GetterSetter* asGetterSetter(JSValue);
-
-    inline GetterSetter* asGetterSetter(JSValue value)
+class JSObject;
+
+// This is an internal value object which stores getter and setter functions
+// for a property. Instances of this class have the property that once a getter
+// or setter is set to a non-null value, then they cannot be changed. This means
+// that if a property holding a GetterSetter reference is constant-inferred and
+// that constant is observed to have a non-null setter (or getter) then we can
+// constant fold that setter (or getter).
+class GetterSetter final : public JSCell {
+    friend class JIT;
+
+private:
+    GetterSetter(VM& vm, JSGlobalObject* globalObject)
+        : JSCell(vm, vm.getterSetterStructure.get())
+    {
+        m_getter.set(vm, this, globalObject->nullGetterFunction());
+        m_setter.set(vm, this, globalObject->nullSetterFunction());
+    }
+
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static GetterSetter* create(VM& vm, JSGlobalObject* globalObject)
+    {
+        GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm, globalObject);
+        getterSetter->finishCreation(vm);
+        return getterSetter;
+    }
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    JSObject* getter() const { return m_getter.get(); }
+
+    JSObject* getterConcurrently() const
+    {
+        JSObject* result = getter();
+        WTF::loadLoadFence();
+        return result;
+    }
+
+    bool isGetterNull() const { return !!jsDynamicCast<NullGetterFunction*>(m_getter.get()); }
+    bool isSetterNull() const { return !!jsDynamicCast<NullSetterFunction*>(m_setter.get()); }
+
+    // Set the getter. It's only valid to call this if you've never set the getter on this
+    // object.
+    void setGetter(VM& vm, JSGlobalObject* globalObject, JSObject* getter)
+    {
+        if (!getter)
+            getter = jsCast<JSObject*>(globalObject->nullGetterFunction());
+
+        RELEASE_ASSERT(isGetterNull());
+        WTF::storeStoreFence();
+        m_getter.set(vm, this, getter);
+    }
+
+    JSObject* setter() const { return m_setter.get(); }
+
+    JSObject* setterConcurrently() const
+    {
+        JSObject* result = setter();
+        WTF::loadLoadFence();
+        return result;
+    }
+
+    // Set the setter. It's only valid to call this if you've never set the setter on this
+    // object.
+    void setSetter(VM& vm, JSGlobalObject* globalObject, JSObject* setter)
+    {
+        if (!setter)
+            setter = jsCast<JSObject*>(globalObject->nullSetterFunction());
+
+        RELEASE_ASSERT(isSetterNull());
+        WTF::storeStoreFence();
+        m_setter.set(vm, this, setter);
+    }
+
+    GetterSetter* withGetter(VM&, JSGlobalObject*, JSObject* getter);
+    GetterSetter* withSetter(VM&, JSGlobalObject*, JSObject* setter);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());
-        return static_cast<GetterSetter*>(value.asCell());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType), info());
     }
 
-    JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter);
-    void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue value, ECMAMode);
+    static ptrdiff_t offsetOfGetter()
+    {
+        return OBJECT_OFFSETOF(GetterSetter, m_getter);
+    }
+
+    static ptrdiff_t offsetOfSetter()
+    {
+        return OBJECT_OFFSETOF(GetterSetter, m_setter);
+    }
+
+    DECLARE_INFO;
+
+private:
+    WriteBarrier<JSObject> m_getter;
+    WriteBarrier<JSObject> m_setter;  
+};
+
+GetterSetter* asGetterSetter(JSValue);
+
+inline GetterSetter* asGetterSetter(JSValue value)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());
+    return static_cast<GetterSetter*>(value.asCell());
+}
+
+JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter);
+void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue, ECMAMode);
 
 } // namespace JSC
 
index 32d408e7d7b47c9cbcf59390ae01bf99caa90b55..d26d9567c6830fe7f31ef12a7a45c011247f86df 100644 (file)
@@ -38,22 +38,22 @@ using WTF::ThreadSpecific;
 
 namespace JSC {
 
-PassRef<StringImpl> Identifier::add(VM* vm, const char* c)
+Ref<StringImpl> Identifier::add(VM* vm, const char* c)
 {
     ASSERT(c);
     ASSERT(c[0]);
     if (!c[1])
         return *vm->smallStrings.singleCharacterStringRep(c[0]);
 
-    return *AtomicString::add(c);
+    return *AtomicStringImpl::add(c);
 }
 
-PassRef<StringImpl> Identifier::add(ExecState* exec, const char* c)
+Ref<StringImpl> Identifier::add(ExecState* exec, const char* c)
 {
     return add(&exec->vm(), c);
 }
 
-PassRef<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length)
+Ref<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length)
 {
     if (length == 1) {
         UChar c = s[0];
@@ -64,7 +64,7 @@ PassRef<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length)
     if (!length)
         return *StringImpl::empty();
 
-    return *AtomicString::add(s, length);
+    return *AtomicStringImpl::add(s, length);
 }
 
 Identifier Identifier::from(ExecState* exec, unsigned value)
@@ -97,6 +97,14 @@ Identifier Identifier::from(VM* vm, double value)
     return Identifier(vm, vm->numericStrings.add(value));
 }
 
+void Identifier::dump(PrintStream& out) const
+{
+    if (impl())
+        out.print(impl());
+    else
+        out.print("<null identifier>");
+}
+
 #ifndef NDEBUG
 
 void Identifier::checkCurrentAtomicStringTable(VM* vm)
index 50a253fd36e6423fa0f9b2499f52638b06fb9942..61de6536a6fa4c29aca4df14b7d6fec4d2a503e6 100644 (file)
 #define Identifier_h
 
 #include "VM.h"
+#include <wtf/Optional.h>
 #include <wtf/ThreadSpecific.h>
 #include <wtf/WTFThreadData.h>
 #include <wtf/text/CString.h>
+#include <wtf/text/UniquedStringImpl.h>
 #include <wtf/text/WTFString.h>
 
 namespace JSC {
 
-    class ExecState;
-
-    class Identifier {
-        friend class Structure;
-    public:
-        Identifier() { }
-        enum EmptyIdentifierFlag { EmptyIdentifier };
-        Identifier(EmptyIdentifierFlag) : m_string(StringImpl::empty()) { ASSERT(m_string.impl()->isAtomic()); }
-
-        // Only to be used with string literals.
-        template<unsigned charactersCount>
-        Identifier(ExecState* exec, const char (&characters)[charactersCount]) : m_string(add(exec, characters)) { ASSERT(m_string.impl()->isAtomic()); }
-        template<unsigned charactersCount>
-        Identifier(VM* vm, const char (&characters)[charactersCount]) : m_string(add(vm, characters)) { ASSERT(m_string.impl()->isAtomic()); }
-
-        Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { ASSERT(m_string.impl()->isAtomic()); }
-        Identifier(ExecState* exec, const String& s) : m_string(add(exec, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
-
-        Identifier(VM* vm, const LChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
-        Identifier(VM* vm, const UChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
-        Identifier(VM* vm, StringImpl* rep) : m_string(add(vm, rep)) { ASSERT(m_string.impl()->isAtomic()); }
-        Identifier(VM* vm, const String& s) : m_string(add(vm, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
-
-        const String& string() const { return m_string; }
-        StringImpl* impl() const { return m_string.impl(); }
-        
-        int length() const { return m_string.length(); }
-        
-        CString ascii() const { return m_string.ascii(); }
-        CString utf8() const { return m_string.utf8(); }
-        
-        static Identifier from(const PrivateName& name)
-        {
-            Identifier result;
-            result.m_string = name.uid();
-            return result;
-        }
-
-        static Identifier createLCharFromUChar(VM* vm, const UChar* s, int length) { return Identifier(vm, add8(vm, s, length)); }
-
-        JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, unsigned y);
-        JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, int y);
-        static Identifier from(ExecState* exec, double y);
-        static Identifier from(VM*, unsigned y);
-        static Identifier from(VM*, int y);
-        static Identifier from(VM*, double y);
-
-        bool isNull() const { return m_string.isNull(); }
-        bool isEmpty() const { return m_string.isEmpty(); }
-        
-        friend bool operator==(const Identifier&, const Identifier&);
-        friend bool operator!=(const Identifier&, const Identifier&);
-
-        friend bool operator==(const Identifier&, const LChar*);
-        friend bool operator==(const Identifier&, const char*);
-        friend bool operator!=(const Identifier&, const LChar*);
-        friend bool operator!=(const Identifier&, const char*);
-    
-        static bool equal(const StringImpl*, const LChar*);
-        static inline bool equal(const StringImpl*a, const char*b) { return Identifier::equal(a, reinterpret_cast<const LChar*>(b)); };
-        static bool equal(const StringImpl*, const LChar*, unsigned length);
-        static bool equal(const StringImpl*, const UChar*, unsigned length);
-        static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
-
-        // Only to be used with string literals.
-        JS_EXPORT_PRIVATE static PassRef<StringImpl> add(VM*, const char*);
-        JS_EXPORT_PRIVATE static PassRef<StringImpl> add(ExecState*, const char*);
-
-    private:
-        String m_string;
-
-        template <typename CharType>
-        ALWAYS_INLINE static uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length, bool& ok);
-
-        static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); }
-        static bool equal(const Identifier& a, const LChar* b) { return equal(a.m_string.impl(), b); }
-
-        template <typename T> static PassRef<StringImpl> add(VM*, const T*, int length);
-        static PassRef<StringImpl> add8(VM*, const UChar*, int length);
-        template <typename T> ALWAYS_INLINE static bool canUseSingleCharacterString(T);
-
-        static PassRef<StringImpl> add(ExecState*, StringImpl*);
-        static PassRef<StringImpl> add(VM*, StringImpl*);
-
-        JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(ExecState*);
-        JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(VM*);
-    };
-
-    template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
-    {
-        ASSERT(maxSingleCharacterString == 0xff);
-        return true;
-    }
-
-    template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(UChar c)
-    {
-        return (c <= maxSingleCharacterString);
-    }
-
-    template <typename T>
-    PassRef<StringImpl> Identifier::add(VM* vm, const T* s, int length)
-    {
-        if (length == 1) {
-            T c = s[0];
-            if (canUseSingleCharacterString(c))
-                return *vm->smallStrings.singleCharacterStringRep(c);
-        }
-        if (!length)
-            return *StringImpl::empty();
-        
-        return *AtomicString::add(s, length);
+class ExecState;
+
+ALWAYS_INLINE bool isIndex(uint32_t index)
+{
+    return index != 0xFFFFFFFFU;
+}
+
+template <typename CharType>
+ALWAYS_INLINE Optional<uint32_t> parseIndex(const CharType* characters, unsigned length)
+{
+    // An empty string is not a number.
+    if (!length)
+        return Nullopt;
+
+    // Get the first character, turning it into a digit.
+    uint32_t value = characters[0] - '0';
+    if (value > 9)
+        return Nullopt;
+
+    // Check for leading zeros. If the first characher is 0, then the
+    // length of the string must be one - e.g. "042" is not equal to "42".
+    if (!value && length > 1)
+        return Nullopt;
+
+    while (--length) {
+        // Multiply value by 10, checking for overflow out of 32 bits.
+        if (value > 0xFFFFFFFFU / 10)
+            return Nullopt;
+        value *= 10;
+
+        // Get the next character, turning it into a digit.
+        uint32_t newValue = *(++characters) - '0';
+        if (newValue > 9)
+            return Nullopt;
+
+        // Add in the old value, checking for overflow out of 32 bits.
+        newValue += value;
+        if (newValue < value)
+            return Nullopt;
+        value = newValue;
     }
 
-    inline bool operator==(const Identifier& a, const Identifier& b)
+    if (!isIndex(value))
+        return Nullopt;
+    return value;
+}
+
+ALWAYS_INLINE Optional<uint32_t> parseIndex(StringImpl& impl)
+{
+    if (impl.is8Bit())
+        return parseIndex(impl.characters8(), impl.length());
+    return parseIndex(impl.characters16(), impl.length());
+}
+
+class Identifier {
+    friend class Structure;
+public:
+    Identifier() { }
+    enum EmptyIdentifierFlag { EmptyIdentifier };
+    Identifier(EmptyIdentifierFlag) : m_string(StringImpl::empty()) { ASSERT(m_string.impl()->isAtomic()); }
+
+    const String& string() const { return m_string; }
+    UniquedStringImpl* impl() const { return static_cast<UniquedStringImpl*>(m_string.impl()); }
+
+    int length() const { return m_string.length(); }
+
+    CString ascii() const { return m_string.ascii(); }
+    CString utf8() const { return m_string.utf8(); }
+
+    // There's 2 functions to construct Identifier from string, (1) fromString and (2) fromUid.
+    // They have different meanings in keeping or discarding symbol-ness of strings.
+    // (1): fromString
+    // Just construct Identifier from string. String held by Identifier is always atomized.
+    // Symbol-ness of StringImpl*, which represents that the string is inteded to be used for ES6 Symbols, is discarded.
+    // So a constructed Identifier never represents a symbol.
+    // (2): fromUid
+    // `StringImpl* uid` represents ether String or Symbol property.
+    // fromUid keeps symbol-ness of provided StringImpl* while fromString discards it.
+    // Use fromUid when constructing Identifier from StringImpl* which may represent symbols.
+
+    // Only to be used with string literals.
+    template<unsigned charactersCount>
+    static Identifier fromString(VM*, const char (&characters)[charactersCount]);
+    template<unsigned charactersCount>
+    static Identifier fromString(ExecState*, const char (&characters)[charactersCount]);
+    static Identifier fromString(VM*, const LChar*, int length);
+    static Identifier fromString(VM*, const UChar*, int length);
+    static Identifier fromString(VM*, const String&);
+    static Identifier fromString(ExecState*, AtomicStringImpl*);
+    static Identifier fromString(ExecState*, const AtomicString&);
+    static Identifier fromString(ExecState*, const String&);
+    static Identifier fromString(ExecState*, const char*);
+
+    static Identifier fromUid(VM*, UniquedStringImpl* uid);
+    static Identifier fromUid(ExecState*, UniquedStringImpl* uid);
+    static Identifier fromUid(const PrivateName&);
+
+    static Identifier createLCharFromUChar(VM* vm, const UChar* s, int length) { return Identifier(vm, add8(vm, s, length)); }
+
+    JS_EXPORT_PRIVATE static Identifier from(ExecState*, unsigned y);
+    JS_EXPORT_PRIVATE static Identifier from(ExecState*, int y);
+    static Identifier from(ExecState*, double y);
+    static Identifier from(VM*, unsigned y);
+    static Identifier from(VM*, int y);
+    static Identifier from(VM*, double y);
+
+    bool isNull() const { return m_string.isNull(); }
+    bool isEmpty() const { return m_string.isEmpty(); }
+    bool isSymbol() const { return !isNull() && impl()->isSymbol(); }
+
+    friend bool operator==(const Identifier&, const Identifier&);
+    friend bool operator!=(const Identifier&, const Identifier&);
+
+    friend bool operator==(const Identifier&, const LChar*);
+    friend bool operator==(const Identifier&, const char*);
+    friend bool operator!=(const Identifier&, const LChar*);
+    friend bool operator!=(const Identifier&, const char*);
+
+    static bool equal(const StringImpl*, const LChar*);
+    static inline bool equal(const StringImpl*a, const char*b) { return Identifier::equal(a, reinterpret_cast<const LChar*>(b)); };
+    static bool equal(const StringImpl*, const LChar*, unsigned length);
+    static bool equal(const StringImpl*, const UChar*, unsigned length);
+    static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
+
+    // Only to be used with string literals.
+    JS_EXPORT_PRIVATE static Ref<StringImpl> add(VM*, const char*);
+    JS_EXPORT_PRIVATE static Ref<StringImpl> add(ExecState*, const char*);
+
+    void dump(PrintStream&) const;
+
+private:
+    String m_string;
+
+    // Only to be used with string literals.
+    template<unsigned charactersCount>
+    Identifier(VM* vm, const char (&characters)[charactersCount]) : m_string(add(vm, characters)) { ASSERT(m_string.impl()->isAtomic()); }
+
+    Identifier(VM* vm, const LChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
+    Identifier(VM* vm, const UChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
+    Identifier(ExecState*, AtomicStringImpl*);
+    Identifier(ExecState*, const AtomicString&);
+    Identifier(VM* vm, const String& string) : m_string(add(vm, string.impl())) { ASSERT(m_string.impl()->isAtomic()); }
+    Identifier(VM* vm, StringImpl* rep) : m_string(add(vm, rep)) { ASSERT(m_string.impl()->isAtomic()); }
+
+    Identifier(SymbolImpl& uid)
+        : m_string(&uid)
     {
-        return Identifier::equal(a, b);
     }
 
-    inline bool operator!=(const Identifier& a, const Identifier& b)
-    {
-        return !Identifier::equal(a, b);
-    }
-
-    inline bool operator==(const Identifier& a, const LChar* b)
-    {
-        return Identifier::equal(a, b);
-    }
-
-    inline bool operator==(const Identifier& a, const char* b)
-    {
-        return Identifier::equal(a, reinterpret_cast<const LChar*>(b));
-    }
-    
-    inline bool operator!=(const Identifier& a, const LChar* b)
-    {
-        return !Identifier::equal(a, b);
-    }
-
-    inline bool operator!=(const Identifier& a, const char* b)
-    {
-        return !Identifier::equal(a, reinterpret_cast<const LChar*>(b));
-    }
-    
-    inline bool Identifier::equal(const StringImpl* r, const LChar* s)
-    {
-        return WTF::equal(r, s);
-    }
-
-    inline bool Identifier::equal(const StringImpl* r, const LChar* s, unsigned length)
-    {
-        return WTF::equal(r, s, length);
-    }
-
-    inline bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
-    {
-        return WTF::equal(r, s, length);
+    template <typename CharType>
+    ALWAYS_INLINE static uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length, bool& ok);
+
+    static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); }
+    static bool equal(const Identifier& a, const LChar* b) { return equal(a.m_string.impl(), b); }
+
+    template <typename T> static Ref<StringImpl> add(VM*, const T*, int length);
+    static Ref<StringImpl> add8(VM*, const UChar*, int length);
+    template <typename T> ALWAYS_INLINE static bool canUseSingleCharacterString(T);
+
+    static Ref<StringImpl> add(ExecState*, StringImpl*);
+    static Ref<StringImpl> add(VM*, StringImpl*);
+
+#ifndef NDEBUG
+    JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(ExecState*);
+    JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(VM*);
+#else
+    JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(ExecState*);
+    JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(VM*);
+#endif
+};
+
+template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
+{
+    ASSERT(maxSingleCharacterString == 0xff);
+    return true;
+}
+
+template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(UChar c)
+{
+    return (c <= maxSingleCharacterString);
+}
+
+template <typename T>
+Ref<StringImpl> Identifier::add(VM* vm, const T* s, int length)
+{
+    if (length == 1) {
+        T c = s[0];
+        if (canUseSingleCharacterString(c))
+            return *vm->smallStrings.singleCharacterStringRep(c);
     }
-    
-    struct IdentifierRepHash : PtrHash<RefPtr<StringImpl>> {
-        static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); }
-        static unsigned hash(StringImpl* key) { return key->existingHash(); }
-    };
-
-    struct IdentifierMapIndexHashTraits : HashTraits<int> {
-        static int emptyValue() { return std::numeric_limits<int>::max(); }
-        static const bool emptyValueIsZero = false;
-    };
-
-    typedef HashMap<RefPtr<StringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, IdentifierMapIndexHashTraits> IdentifierMap;
-    typedef HashMap<StringImpl*, int, IdentifierRepHash, HashTraits<StringImpl*>, IdentifierMapIndexHashTraits> BorrowedIdentifierMap;
+    if (!length)
+        return *StringImpl::empty();
+
+    return *AtomicStringImpl::add(s, length);
+}
+
+inline bool operator==(const Identifier& a, const Identifier& b)
+{
+    return Identifier::equal(a, b);
+}
+
+inline bool operator!=(const Identifier& a, const Identifier& b)
+{
+    return !Identifier::equal(a, b);
+}
+
+inline bool operator==(const Identifier& a, const LChar* b)
+{
+    return Identifier::equal(a, b);
+}
+
+inline bool operator==(const Identifier& a, const char* b)
+{
+    return Identifier::equal(a, reinterpret_cast<const LChar*>(b));
+}
+
+inline bool operator!=(const Identifier& a, const LChar* b)
+{
+    return !Identifier::equal(a, b);
+}
+
+inline bool operator!=(const Identifier& a, const char* b)
+{
+    return !Identifier::equal(a, reinterpret_cast<const LChar*>(b));
+}
+
+inline bool Identifier::equal(const StringImpl* r, const LChar* s)
+{
+    return WTF::equal(r, s);
+}
+
+inline bool Identifier::equal(const StringImpl* r, const LChar* s, unsigned length)
+{
+    return WTF::equal(r, s, length);
+}
+
+inline bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
+{
+    return WTF::equal(r, s, length);
+}
+
+ALWAYS_INLINE Optional<uint32_t> parseIndex(const Identifier& identifier)
+{
+    auto uid = identifier.impl();
+    if (!uid)
+        return Nullopt;
+    if (uid->isSymbol())
+        return Nullopt;
+    return parseIndex(*uid);
+}
+
+struct IdentifierRepHash : PtrHash<RefPtr<UniquedStringImpl>> {
+    static unsigned hash(const RefPtr<UniquedStringImpl>& key) { return key->existingSymbolAwareHash(); }
+    static unsigned hash(UniquedStringImpl* key) { return key->existingSymbolAwareHash(); }
+};
+
+struct IdentifierMapIndexHashTraits : HashTraits<int> {
+    static int emptyValue() { return std::numeric_limits<int>::max(); }
+    static const bool emptyValueIsZero = false;
+};
+
+typedef HashMap<RefPtr<UniquedStringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, IdentifierMapIndexHashTraits> IdentifierMap;
+typedef HashMap<UniquedStringImpl*, int, IdentifierRepHash, HashTraits<UniquedStringImpl*>, IdentifierMapIndexHashTraits> BorrowedIdentifierMap;
 
 } // namespace JSC
 
index 3a7e20beef494114f387d433bf4bcac03934a5e5..6b50748e70353f663b11fbbae7c788187c836f6f 100644 (file)
 
 namespace JSC  {
 
-inline PassRef<StringImpl> Identifier::add(ExecState* exec, StringImpl* r)
+inline Identifier::Identifier(ExecState* exec, AtomicStringImpl* string)
+    : m_string(string)
 {
 #ifndef NDEBUG
     checkCurrentAtomicStringTable(exec);
+    if (string)
+        ASSERT_WITH_MESSAGE(!string->length() || string->isSymbol() || AtomicStringImpl::isInAtomicStringTable(string), "The atomic string comes from an other thread!");
+#else
+    UNUSED_PARAM(exec);
 #endif
-    return *AtomicString::addWithStringTableProvider(*exec, r);
 }
-inline PassRef<StringImpl> Identifier::add(VM* vm, StringImpl* r)
+
+inline Identifier::Identifier(ExecState* exec, const AtomicString& string)
+    : m_string(string.string())
+{
+#ifndef NDEBUG
+    checkCurrentAtomicStringTable(exec);
+    if (!string.isNull())
+        ASSERT_WITH_MESSAGE(!string.length() || string.impl()->isSymbol() || AtomicStringImpl::isInAtomicStringTable(string.impl()), "The atomic string comes from an other thread!");
+#else
+    UNUSED_PARAM(exec);
+#endif
+}
+
+inline Ref<StringImpl> Identifier::add(ExecState* exec, StringImpl* r)
+{
+#ifndef NDEBUG
+    checkCurrentAtomicStringTable(exec);
+#endif
+    return *AtomicStringImpl::addWithStringTableProvider(*exec, r);
+}
+inline Ref<StringImpl> Identifier::add(VM* vm, StringImpl* r)
 {
 #ifndef NDEBUG
     checkCurrentAtomicStringTable(vm);
 #endif
-    return *AtomicString::addWithStringTableProvider(*vm, r);
+    return *AtomicStringImpl::addWithStringTableProvider(*vm, r);
+}
+
+inline Identifier Identifier::fromUid(VM* vm, UniquedStringImpl* uid)
+{
+    if (!uid || !uid->isSymbol())
+        return Identifier(vm, uid);
+    return static_cast<SymbolImpl&>(*uid);
+}
+
+inline Identifier Identifier::fromUid(ExecState* exec, UniquedStringImpl* uid)
+{
+    return fromUid(&exec->vm(), uid);
+}
+
+inline Identifier Identifier::fromUid(const PrivateName& name)
+{
+    return *name.uid();
+}
+
+template<unsigned charactersCount>
+inline Identifier Identifier::fromString(VM* vm, const char (&characters)[charactersCount])
+{
+    return Identifier(vm, characters);
+}
+
+template<unsigned charactersCount>
+inline Identifier Identifier::fromString(ExecState* exec, const char (&characters)[charactersCount])
+{
+    return Identifier(&exec->vm(), characters);
+}
+
+inline Identifier Identifier::fromString(VM* vm, const LChar* s, int length)
+{
+    return Identifier(vm, s, length);
+}
+
+inline Identifier Identifier::fromString(VM* vm, const UChar* s, int length)
+{
+    return Identifier(vm, s, length);
+}
+
+inline Identifier Identifier::fromString(VM* vm, const String& string)
+{
+    return Identifier(vm, string.impl());
+}
+
+inline Identifier Identifier::fromString(ExecState* exec, const String& string)
+{
+    return Identifier(&exec->vm(), string.impl());
+}
+
+inline Identifier Identifier::fromString(ExecState* exec, AtomicStringImpl* atomicString)
+{
+    return Identifier(exec, atomicString);
+}
+
+inline Identifier Identifier::fromString(ExecState* exec, const AtomicString& atomicString)
+{
+    return Identifier(exec, atomicString);
+}
+
+inline Identifier Identifier::fromString(ExecState* exec, const char* s)
+{
+    return Identifier(exec, AtomicString(s));
 }
 
 } // namespace JSC
index aadd8299fa18d486773d7e4e2982841c367a116b..a88643239e08ce1ab4e93f53b69d2eaa67bd589c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index 25d5a10b8841f596584ebb569890b314951f1a98..3f9fdd1ed662f5d0c37925c51deaaa52ec22c2b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+/*
+    Structure of the IndexingType
+    =============================
+    Conceptually, the IndexingType looks like this:
+
+    struct IndexingType {
+        uint8_t isArray:1;                    // bit 0
+        uint8_t shape:4;                      // bit 1 - 3
+        uint8_t mayHaveIndexedAccessors:1;    // bit 4
+    };
+
+    The shape values (e.g. Int32Shape, ContiguousShape, etc) are an enumeration of
+    various shapes (though not necessarily sequential in terms of their values).
+    Hence, shape values are not bitwise exclusive with respect to each other.
+*/
+
 typedef uint8_t IndexingType;
 
 // Flags for testing the presence of capabilities.
 static const IndexingType IsArray                  = 0x01;
 
 // The shape of the indexed property storage.
-static const IndexingType IndexingShapeMask        = 0x1E;
+static const IndexingType IndexingShapeMask        = 0x0E;
 static const IndexingType NoIndexingShape          = 0x00;
 static const IndexingType UndecidedShape           = 0x02; // Only useful for arrays.
-static const IndexingType Int32Shape               = 0x14;
-static const IndexingType DoubleShape              = 0x16;
-static const IndexingType ContiguousShape          = 0x1A;
-static const IndexingType ArrayStorageShape        = 0x1C;
-static const IndexingType SlowPutArrayStorageShape = 0x1E;
+static const IndexingType Int32Shape               = 0x04;
+static const IndexingType DoubleShape              = 0x06;
+static const IndexingType ContiguousShape          = 0x08;
+static const IndexingType ArrayStorageShape        = 0x0A;
+static const IndexingType SlowPutArrayStorageShape = 0x0C;
 
 static const IndexingType IndexingShapeShift       = 1;
-static const IndexingType NumberOfIndexingShapes   = 16;
+static const IndexingType NumberOfIndexingShapes   = 7;
 
 // Additional flags for tracking the history of the type. These are usually
 // masked off unless you ask for them directly.
-static const IndexingType MayHaveIndexedAccessors  = 0x20;
+static const IndexingType MayHaveIndexedAccessors  = 0x10;
 
 // List of acceptable array types.
 static const IndexingType NonArray                        = 0x0;
@@ -128,7 +144,7 @@ static inline bool hasArrayStorage(IndexingType indexingType)
 
 static inline bool hasAnyArrayStorage(IndexingType indexingType)
 {
-    return static_cast<uint8_t>((indexingType & IndexingShapeMask) - ArrayStorageShape) <= static_cast<uint8_t>(SlowPutArrayStorageShape - ArrayStorageShape);
+    return static_cast<uint8_t>(indexingType & IndexingShapeMask) >= ArrayStorageShape;
 }
 
 static inline bool shouldUseSlowPut(IndexingType indexingType)
@@ -146,10 +162,10 @@ void dumpIndexingType(PrintStream&, IndexingType);
 MAKE_PRINT_ADAPTOR(IndexingTypeDump, IndexingType, dumpIndexingType);
 
 // Mask of all possible types.
-static const IndexingType AllArrayTypes            = 31;
+static const IndexingType AllArrayTypes            = IndexingShapeMask | IsArray;
 
 // Mask of all possible types including the history.
-static const IndexingType AllArrayTypesAndHistory  = 127;
+static const IndexingType AllArrayTypesAndHistory  = AllArrayTypes | MayHaveIndexedAccessors;
 
 } // namespace JSC
 
diff --git a/runtime/InferredValue.cpp b/runtime/InferredValue.cpp
new file mode 100644 (file)
index 0000000..73c6bc7
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "InferredValue.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo InferredValue::s_info = { "InferredValue", 0, 0, CREATE_METHOD_TABLE(InferredValue) };
+
+InferredValue* InferredValue::create(VM& vm)
+{
+    InferredValue* result = new (NotNull, allocateCell<InferredValue>(vm.heap)) InferredValue(vm);
+    result->finishCreation(vm);
+    return result;
+}
+
+void InferredValue::destroy(JSCell* cell)
+{
+    InferredValue* inferredValue = static_cast<InferredValue*>(cell);
+    inferredValue->InferredValue::~InferredValue();
+}
+
+Structure* InferredValue::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+void InferredValue::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    InferredValue* inferredValue = jsCast<InferredValue*>(cell);
+    
+    if (inferredValue->m_set.hasBeenInvalidated()) {
+        inferredValue->m_cleanup = nullptr;
+        return;
+    }
+    
+    if (!inferredValue->m_value)
+        return;
+    if (!inferredValue->m_value.get().isCell())
+        return;
+    
+    if (!inferredValue->m_cleanup)
+        inferredValue->m_cleanup = std::make_unique<ValueCleanup>(inferredValue);
+    visitor.addUnconditionalFinalizer(inferredValue->m_cleanup.get());
+}
+
+InferredValue::InferredValue(VM& vm)
+    : Base(vm, vm.inferredValueStructure.get())
+    , m_set(ClearWatchpoint)
+{
+}
+
+InferredValue::~InferredValue()
+{
+}
+
+void InferredValue::notifyWriteSlow(VM& vm, JSValue value, const FireDetail& detail)
+{
+    ASSERT(!!value);
+    switch (m_set.state()) {
+    case ClearWatchpoint:
+        m_value.set(vm, this, value);
+        m_set.startWatching();
+        return;
+        
+    case IsWatched:
+        ASSERT(!!m_value);
+        if (m_value.get() == value)
+            return;
+        invalidate(detail);
+        return;
+        
+    case IsInvalidated:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    
+    ASSERT_NOT_REACHED();
+}
+
+void InferredValue::notifyWriteSlow(VM& vm, JSValue value, const char* reason)
+{
+    notifyWriteSlow(vm, value, StringFireDetail(reason));
+}
+
+InferredValue::ValueCleanup::ValueCleanup(InferredValue* owner)
+    : m_owner(owner)
+{
+}
+
+InferredValue::ValueCleanup::~ValueCleanup()
+{
+}
+
+void InferredValue::ValueCleanup::finalizeUnconditionally()
+{
+    ASSERT(m_owner->m_value);
+    ASSERT(m_owner->m_value.get().isCell());
+    
+    if (Heap::isMarked(m_owner->m_value.get().asCell()))
+        return;
+    
+    m_owner->invalidate(StringFireDetail("InferredValue clean-up during GC"));
+}
+
+} // namespace JSC
+
diff --git a/runtime/InferredValue.h b/runtime/InferredValue.h
new file mode 100644 (file)
index 0000000..28318e9
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef InferredValue_h
+#define InferredValue_h
+
+#include "JSCell.h"
+#include "Watchpoint.h"
+#include "WriteBarrier.h"
+
+namespace JSC {
+
+// Allocate one of these if you'd like to infer a constant value. Writes to the value should use
+// notifyWrite(). So long as exactly one value had ever been written and invalidate() has never been
+// called, and you register a watchpoint, you can rely on the inferredValue() being the one true
+// value.
+//
+// Commonly used for inferring singletons - in that case each allocation does notifyWrite(). But you
+// can use it for other things as well.
+
+class InferredValue : public JSCell {
+public:
+    typedef JSCell Base;
+    
+    static InferredValue* create(VM&);
+    
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+    
+    static void visitChildren(JSCell*, SlotVisitor&);
+    
+    DECLARE_INFO;
+    
+    // For the purpose of deciding whether or not to watch this variable, you only need
+    // to inspect inferredValue(). If this returns something other than the empty
+    // value, then it means that at all future safepoints, this watchpoint set will be
+    // in one of these states:
+    //
+    //    IsWatched: in this case, the variable's value must still be the
+    //        inferredValue.
+    //
+    //    IsInvalidated: in this case the variable's value may be anything but you'll
+    //        either notice that it's invalidated and not install the watchpoint, or
+    //        you will have been notified that the watchpoint was fired.
+    JSValue inferredValue() { return m_value.get(); }
+
+    // Forwards some WatchpointSet methods.
+    WatchpointState state() const { return m_set.state(); }
+    bool isStillValid() const { return m_set.isStillValid(); }
+    bool hasBeenInvalidated() const { return m_set.hasBeenInvalidated(); }
+    void add(Watchpoint* watchpoint) { m_set.add(watchpoint); }
+    
+    void notifyWrite(VM& vm, JSValue value, const FireDetail& detail)
+    {
+        if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
+            return;
+        notifyWriteSlow(vm, value, detail);
+    }
+    
+    void notifyWrite(VM& vm, JSValue value, const char* reason)
+    {
+        if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
+            return;
+        notifyWriteSlow(vm, value, reason);
+    }
+    
+    void invalidate(const FireDetail& detail)
+    {
+        m_value.clear();
+        m_set.invalidate(detail);
+    }
+    
+    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+    
+    // We could have used Weak<>. But we want arbitrary JSValues, not just cells. It's also somewhat
+    // convenient to have eager notification of death.
+    //
+    // Also note that this should be a private class, but it isn't because Windows.
+    class ValueCleanup : public UnconditionalFinalizer {
+        WTF_MAKE_FAST_ALLOCATED;
+        
+    public:
+        ValueCleanup(InferredValue*);
+        virtual ~ValueCleanup();
+        
+    protected:
+        void finalizeUnconditionally() override;
+        
+    private:
+        InferredValue* m_owner;
+    };
+    
+private:
+    InferredValue(VM&);
+    ~InferredValue();
+    
+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const FireDetail&);
+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const char* reason);
+    
+    friend class ValueCleanup;
+    
+    InlineWatchpointSet m_set;
+    WriteBarrier<Unknown> m_value;
+    std::unique_ptr<ValueCleanup> m_cleanup;
+};
+
+// FIXME: We could have an InlineInferredValue, which only allocates the InferredValue object when
+// a notifyWrite() transitions us towards watching, and then clears the reference (allowing the object
+// to die) when we get invalidated.
+
+} // namespace JSC
+
+#endif // InferredValue_h
+
index b05ce418e77e13b726e6e8add079f367b3bc377b..39845c2439a14420c2b5df1b981f9434686d2239 100644 (file)
@@ -31,9 +31,9 @@
 
 namespace JSC {
 
-    // This function must be called from the main thread. It is safe to call it repeatedly.
-    // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
-    JS_EXPORT_PRIVATE void initializeThreading();
+// This function must be called from the main thread. It is safe to call it repeatedly.
+// Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
+JS_EXPORT_PRIVATE void initializeThreading();
 
 }
 
index 290e42583623526586d53ea7d939cd314afb4d93..d73f748e3af574e12bffa13d27a3a066a9769fa9 100644 (file)
 
 namespace JSC {
 
-IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head)
+IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, JSValue prototype)
     : m_globalObject(globalObject)
-    , m_head(head)
+    , m_prototype(prototype)
 {
-    JSValue prototype = head->prototypeForLookup(globalObject);
+    ASSERT(m_prototype.isNull() || m_prototype.isObject());
     if (prototype.isNull())
         return;
     for (Structure* current = asObject(prototype)->structure(); current; current = current->storedPrototypeStructure())
         m_vector.append(current);
 }
 
+IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head)
+    : m_globalObject(globalObject)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
+{
+    if (m_prototype.isNull())
+        return;
+    for (Structure* current = asObject(m_prototype)->structure(); current; current = current->storedPrototypeStructure())
+        m_vector.append(current);
+}
+
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, Structure* prototypeStructure)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     m_vector.append(prototypeStructure);
 }
 
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     for (unsigned i = 0; chain->head()[i]; ++i)
         m_vector.append(chain->head()[i].get());
@@ -61,7 +71,7 @@ IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure*
 
 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain, unsigned count)
     : m_globalObject(codeBlock->globalObject())
-    , m_head(head)
+    , m_prototype(head->prototypeForLookup(m_globalObject))
 {
     for (unsigned i = 0; i < count; ++i)
         m_vector.append(chain->head()[i].get());
@@ -73,7 +83,7 @@ IntendedStructureChain::~IntendedStructureChain()
 
 bool IntendedStructureChain::isStillValid() const
 {
-    JSValue currentPrototype = m_head->prototypeForLookup(m_globalObject);
+    JSValue currentPrototype = m_prototype;
     for (unsigned i = 0; i < m_vector.size(); ++i) {
         if (asObject(currentPrototype)->structure() != m_vector[i])
             return false;
@@ -93,20 +103,11 @@ bool IntendedStructureChain::matches(StructureChain* chain) const
     return true;
 }
 
-StructureChain* IntendedStructureChain::chain(VM& vm) const
-{
-    ASSERT(isStillValid());
-    StructureChain* result = StructureChain::create(vm, m_head);
-    ASSERT(matches(result));
-    return result;
-}
-
-bool IntendedStructureChain::mayInterceptStoreTo(VM& vm, StringImpl* uid)
+bool IntendedStructureChain::mayInterceptStoreTo(UniquedStringImpl* uid)
 {
     for (unsigned i = 0; i < m_vector.size(); ++i) {
         unsigned attributes;
-        JSCell* specificValue;
-        PropertyOffset offset = m_vector[i]->getConcurrently(vm, uid, attributes, specificValue);
+        PropertyOffset offset = m_vector[i]->getConcurrently(uid, attributes);
         if (!isValidOffset(offset))
             continue;
         if (attributes & (ReadOnly | Accessor))
@@ -118,8 +119,6 @@ bool IntendedStructureChain::mayInterceptStoreTo(VM& vm, StringImpl* uid)
 
 bool IntendedStructureChain::isNormalized()
 {
-    if (m_head->isProxy())
-        return false;
     for (unsigned i = 0; i < m_vector.size(); ++i) {
         Structure* structure = m_vector[i];
         if (structure->isProxy())
@@ -130,18 +129,45 @@ bool IntendedStructureChain::isNormalized()
     return true;
 }
 
+bool IntendedStructureChain::takesSlowPathInDFGForImpureProperty()
+{
+    for (size_t i = 0; i < size(); ++i) {
+        if (at(i)->takesSlowPathInDFGForImpureProperty())
+            return true;
+    }
+    return false;
+}
+
 JSObject* IntendedStructureChain::terminalPrototype() const
 {
     ASSERT(!m_vector.isEmpty());
     if (m_vector.size() == 1)
-        return asObject(m_head->prototypeForLookup(m_globalObject));
+        return asObject(m_prototype);
     return asObject(m_vector[m_vector.size() - 2]->storedPrototype());
 }
 
+bool IntendedStructureChain::operator==(const IntendedStructureChain& other) const
+{
+    return m_globalObject == other.m_globalObject
+        && m_prototype == other.m_prototype
+        && m_vector == other.m_vector;
+}
+
+void IntendedStructureChain::gatherChecks(ConstantStructureCheckVector& vector) const
+{
+    JSValue currentPrototype = m_prototype;
+    for (unsigned i = 0; i < size(); ++i) {
+        JSObject* currentObject = asObject(currentPrototype);
+        Structure* currentStructure = at(i);
+        vector.append(ConstantStructureCheck(currentObject, currentStructure));
+        currentPrototype = currentStructure->prototypeForLookup(m_globalObject);
+    }
+}
+
 void IntendedStructureChain::visitChildren(SlotVisitor& visitor)
 {
     visitor.appendUnbarrieredPointer(&m_globalObject);
-    visitor.appendUnbarrieredPointer(&m_head);
+    visitor.appendUnbarrieredValue(&m_prototype);
     for (unsigned i = m_vector.size(); i--;)
         visitor.appendUnbarrieredPointer(&m_vector[i]);
 }
@@ -155,7 +181,7 @@ void IntendedStructureChain::dumpInContext(PrintStream& out, DumpContext* contex
 {
     out.print(
         "(global = ", RawPointer(m_globalObject), ", head = ",
-        pointerDumpInContext(m_head, context), ", vector = [");
+        inContext(m_prototype, context), ", vector = [");
     CommaPrinter comma;
     for (unsigned i = 0; i < m_vector.size(); ++i)
         out.print(comma, pointerDumpInContext(m_vector[i], context));
index a78188b98ac38c031849af025ba7f56aba8fc8c3..a0f5565bd11fee8c83711f0f56052f2143229e53 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef IntendedStructureChain_h
 #define IntendedStructureChain_h
 
+#include "ConstantStructureCheck.h"
 #include "Structure.h"
 #include <wtf/RefCounted.h>
 
@@ -39,7 +40,8 @@ struct DumpContext;
 
 class IntendedStructureChain : public RefCounted<IntendedStructureChain> {
 public:
-    IntendedStructureChain(JSGlobalObject* globalObject, Structure* head);
+    IntendedStructureChain(JSGlobalObject* globalObject, JSValue prototype);
+    IntendedStructureChain(JSGlobalObject* globalObject, Structure*);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, Structure* prototypeStructure);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain);
     IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain, unsigned count);
@@ -47,27 +49,36 @@ public:
     
     bool isStillValid() const;
     bool matches(StructureChain*) const;
-    StructureChain* chain(VM&) const;
-    bool mayInterceptStoreTo(VM&, StringImpl* uid);
+    bool mayInterceptStoreTo(UniquedStringImpl* uid);
     bool isNormalized();
     
-    Structure* head() const { return m_head; }
+    bool takesSlowPathInDFGForImpureProperty();
+    
+    JSValue prototype() const { return m_prototype; }
     
     size_t size() const { return m_vector.size(); }
-    Structure* at(size_t index) { return m_vector[index]; }
-    Structure* operator[](size_t index) { return at(index); }
+    Structure* at(size_t index) const { return m_vector[index]; }
+    Structure* operator[](size_t index) const { return at(index); }
     
     JSObject* terminalPrototype() const;
     
     Structure* last() const { return m_vector.last(); }
     
+    bool operator==(const IntendedStructureChain&) const;
+    bool operator!=(const IntendedStructureChain& other) const
+    {
+        return !(*this == other);
+    }
+    
+    void gatherChecks(ConstantStructureCheckVector&) const;
+    
     void visitChildren(SlotVisitor&);
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
 private:
     JSGlobalObject* m_globalObject;
-    Structure* m_head;
+    JSValue m_prototype;
     Vector<Structure*> m_vector;
 };
 
index 24519c663774f18bb29ba17f66e6d9fc8685c2f2..6f53bc01fd72120ca9f120376e9a88669a50baeb 100644 (file)
@@ -32,7 +32,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(InternalFunction);
 
-const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
+const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(InternalFunction) };
 
 InternalFunction::InternalFunction(VM& vm, Structure* structure)
     : JSDestructibleObject(vm, structure)
index e216c2f82eb373326314f354c21f6b254bdc85b2..8b0d09f13f6879130f127c4a03f597e9baa332fe 100644 (file)
 
 namespace JSC {
 
-    class FunctionPrototype;
+class FunctionPrototype;
 
-    class InternalFunction : public JSDestructibleObject {
-    public:
-        typedef JSDestructibleObject Base;
+class InternalFunction : public JSDestructibleObject {
+public:
+    typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance | TypeOfShouldCallGetCallData;
 
-        DECLARE_EXPORT_INFO;
+    DECLARE_EXPORT_INFO;
 
-        JS_EXPORT_PRIVATE const String& name(ExecState*);
-        const String displayName(ExecState*);
-        const String calculatedDisplayName(ExecState*);
+    JS_EXPORT_PRIVATE const String& name(ExecState*);
+    const String displayName(ExecState*);
+    const String calculatedDisplayName(ExecState*);
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 
-        { 
-            return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info()); 
-        }
-
-    protected:
-        static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 
+    { 
+        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info()); 
+    }
 
-        JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);
+protected:
+    JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);
 
-        JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
+    JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
 
-        static CallType getCallData(JSCell*, CallData&);
-    };
+    static CallType getCallData(JSCell*, CallData&);
+};
 
-    InternalFunction* asInternalFunction(JSValue);
+InternalFunction* asInternalFunction(JSValue);
 
-    inline InternalFunction* asInternalFunction(JSValue value)
-    {
-        ASSERT(asObject(value)->inherits(InternalFunction::info()));
-        return static_cast<InternalFunction*>(asObject(value));
-    }
+inline InternalFunction* asInternalFunction(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(InternalFunction::info()));
+    return static_cast<InternalFunction*>(asObject(value));
+}
 
 } // namespace JSC
 
diff --git a/runtime/IntlObject.cpp b/runtime/IntlObject.cpp
new file mode 100644 (file)
index 0000000..12da938
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner (thetalecrafter@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IntlObject.h"
+
+#if ENABLE(INTL)
+
+#include "JSCInlines.h"
+#include "Lookup.h"
+#include "ObjectPrototype.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(IntlObject);
+
+}
+
+namespace JSC {
+
+const ClassInfo IntlObject::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(IntlObject) };
+
+IntlObject::IntlObject(VM& vm, Structure* structure)
+    : JSNonFinalObject(vm, structure)
+{
+}
+
+IntlObject* IntlObject::create(VM& vm, Structure* structure)
+{
+    IntlObject* object = new (NotNull, allocateCell<IntlObject>(vm.heap)) IntlObject(vm, structure);
+    object->finishCreation(vm);
+    return object;
+}
+
+void IntlObject::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+}
+
+Structure* IntlObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+} // namespace JSC
+
+#endif // ENABLE(INTL)
diff --git a/runtime/IntlObject.h b/runtime/IntlObject.h
new file mode 100644 (file)
index 0000000..f45b9ab
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner (thetalecrafter@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IntlObject_h
+#define IntlObject_h
+
+#if ENABLE(INTL)
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class IntlObject : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static IntlObject* create(VM&, Structure*);
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+    DECLARE_INFO;
+
+protected:
+    void finishCreation(VM&);
+
+private:
+    IntlObject(VM&, Structure*);
+};
+
+} // namespace JSC
+
+#endif // ENABLE(INTL)
+
+#endif // IntlObject_h
index 538b3284c24c133640fa47e3e427bdd6579ac4a9..fe552a7810d91a84e3a0cd6671a9ed2eed09e342 100644 (file)
@@ -35,6 +35,7 @@ enum Intrinsic {
     MaxIntrinsic,
     SqrtIntrinsic,
     SinIntrinsic,
+    Clz32Intrinsic,
     CosIntrinsic,
     ArrayPushIntrinsic,
     ArrayPopIntrinsic,
@@ -52,16 +53,14 @@ enum Intrinsic {
     StringPrototypeValueOfIntrinsic,
     IMulIntrinsic,
     FRoundIntrinsic,
-    ArrayIteratorNextValueIntrinsic,
-    ArrayIteratorNextKeyIntrinsic,
-    ArrayIteratorNextGenericIntrinsic,
-    
+
     // Debugging intrinsics. These are meant to be used as testing hacks within
     // jsc.cpp and should never be exposed to users.
     DFGTrueIntrinsic,
     OSRExitIntrinsic,
     IsFinalTierIntrinsic,
     SetInt32HeapPredictionIntrinsic,
+    CheckInt32Intrinsic,
     FiatInt52Intrinsic,
 };
 
diff --git a/runtime/IterationStatus.h b/runtime/IterationStatus.h
new file mode 100644 (file)
index 0000000..fb8b5fb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IterationStatus_h
+#define IterationStatus_h
+
+namespace JSC {
+
+enum class IterationStatus {
+    Continue,
+    Done
+};
+
+} // namespace JSC
+
+#endif // IterationStatus_h
diff --git a/runtime/IteratorOperations.cpp b/runtime/IteratorOperations.cpp
new file mode 100644 (file)
index 0000000..2e886bf
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IteratorOperations.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "ObjectConstructor.h"
+
+using namespace WTF;
+
+namespace JSC {
+
+JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value)
+{
+    JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->next);
+    if (exec->hadException())
+        return jsUndefined();
+
+    CallData nextFunctionCallData;
+    CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
+    if (nextFunctionCallType == CallTypeNone)
+        return throwTypeError(exec);
+
+    MarkedArgumentBuffer nextFunctionArguments;
+    if (!value.isEmpty())
+        nextFunctionArguments.append(value);
+    JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments);
+    if (exec->hadException())
+        return jsUndefined();
+
+    if (!result.isObject())
+        return throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object."));
+
+    return result;
+}
+
+JSValue iteratorNext(ExecState* exec, JSValue iterator)
+{
+    return iteratorNext(exec, iterator, JSValue());
+}
+
+JSValue iteratorValue(ExecState* exec, JSValue iterResult)
+{
+    return iterResult.get(exec, exec->vm().propertyNames->value);
+}
+
+bool iteratorComplete(ExecState* exec, JSValue iterResult)
+{
+    JSValue done = iterResult.get(exec, exec->vm().propertyNames->done);
+    return done.toBoolean(exec);
+}
+
+JSValue iteratorStep(ExecState* exec, JSValue iterator)
+{
+    JSValue result = iteratorNext(exec, iterator);
+    if (exec->hadException())
+        return jsUndefined();
+    bool done = iteratorComplete(exec, result);
+    if (exec->hadException())
+        return jsUndefined();
+    if (done)
+        return jsBoolean(false);
+    return result;
+}
+
+void iteratorClose(ExecState* exec, JSValue iterator)
+{
+    Exception* exception = nullptr;
+    if (exec->hadException()) {
+        exception = exec->exception();
+        exec->clearException();
+    }
+    JSValue returnFunction = iterator.get(exec, exec->vm().propertyNames->returnKeyword);
+    if (exec->hadException())
+        return;
+
+    if (returnFunction.isUndefined()) {
+        if (exception)
+            exec->vm().throwException(exec, exception);
+        return;
+    }
+
+    CallData returnFunctionCallData;
+    CallType returnFunctionCallType = getCallData(returnFunction, returnFunctionCallData);
+    if (returnFunctionCallType == CallTypeNone) {
+        if (exception)
+            exec->vm().throwException(exec, exception);
+        else
+            throwTypeError(exec);
+        return;
+    }
+
+    MarkedArgumentBuffer returnFunctionArguments;
+    JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterator, returnFunctionArguments);
+
+    if (exception) {
+        exec->vm().throwException(exec, exception);
+        return;
+    }
+
+    if (exec->hadException())
+        return;
+
+    if (!innerResult.isObject()) {
+        throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object."));
+        return;
+    }
+}
+
+JSObject* createIteratorResultObject(ExecState* exec, JSValue value, bool done)
+{
+    JSObject* resultObject = constructEmptyObject(exec);
+    resultObject->putDirect(exec->vm(), exec->propertyNames().done, jsBoolean(done));
+    resultObject->putDirect(exec->vm(), exec->propertyNames().value, value);
+    return resultObject;
+}
+
+} // namespace JSC
diff --git a/runtime/IteratorOperations.h b/runtime/IteratorOperations.h
new file mode 100644 (file)
index 0000000..a9a300c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IteratorOperations_h
+#define IteratorOperations_h
+
+#include "JSCJSValue.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+JSValue iteratorNext(ExecState*, JSValue iterator, JSValue);
+JSValue iteratorNext(ExecState*, JSValue iterator);
+JSValue iteratorValue(ExecState*, JSValue iterator);
+bool iteratorComplete(ExecState*, JSValue iterator);
+JSValue iteratorStep(ExecState*, JSValue iterator);
+void iteratorClose(ExecState*, JSValue iterator);
+JS_EXPORT_PRIVATE JSObject* createIteratorResultObject(ExecState*, JSValue, bool done);
+
+}
+
+#endif // !defined(IteratorOperations_h)
diff --git a/runtime/IteratorPrototype.cpp b/runtime/IteratorPrototype.cpp
new file mode 100644 (file)
index 0000000..3e4ec93
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IteratorPrototype.h"
+
+#include "JSCBuiltins.h"
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+const ClassInfo IteratorPrototype::s_info = { "Iterator", &Base::s_info, nullptr, CREATE_METHOD_TABLE(IteratorPrototype) };
+
+void IteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+    vm.prototypeMap.addPrototype(this);
+
+    JSFunction* iteratorPrototypeFunction = JSFunction::createBuiltinFunction(vm, iteratorPrototypeSymbolIteratorCodeGenerator(vm), globalObject, "[Symbol.iterator]");
+    putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, iteratorPrototypeFunction, DontEnum);
+}
+
+} // namespace JSC
diff --git a/runtime/IteratorPrototype.h b/runtime/IteratorPrototype.h
new file mode 100644 (file)
index 0000000..c15971d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IteratorPrototype_h
+#define IteratorPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class IteratorPrototype : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
+    static IteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        IteratorPrototype* prototype = new (NotNull, allocateCell<IteratorPrototype>(vm.heap)) IteratorPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    IteratorPrototype(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    void finishCreation(VM&, JSGlobalObject*);
+};
+
+}
+
+#endif // !defined(IteratorPrototype_h)
index 80c762620a357c6c01f8364cda3cfd91e7b2075f..6e5b53618d11926898cf7e41b6e2b5736c877753 100644 (file)
@@ -29,6 +29,6 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSAPIValueWrapper);
 
-const ClassInfo JSAPIValueWrapper::s_info = { "API Wrapper", 0, 0, 0, CREATE_METHOD_TABLE(JSAPIValueWrapper) };
+const ClassInfo JSAPIValueWrapper::s_info = { "API Wrapper", 0, 0, CREATE_METHOD_TABLE(JSAPIValueWrapper) };
 
 } // namespace JSC
index e1f2cd80478209c843b81179b85ff89d43829529..66e61c70d3e2ab3b2ebce1f0fd998dfda252b02b 100644 (file)
 
 namespace JSC {
 
-    class JSAPIValueWrapper : public JSCell {
-        friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
-    public:
-        typedef JSCell Base;
+class JSAPIValueWrapper : public JSCell {
+    friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-        JSValue value() const { return m_value.get(); }
+    JSValue value() const { return m_value.get(); }
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesVisitChildren | OverridesGetPropertyNames), info());
-        }
-        
-        DECLARE_EXPORT_INFO;
-        
-        static JSAPIValueWrapper* create(ExecState* exec, JSValue value) 
-        {
-            VM& vm = exec->vm();
-            JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(exec);
-            wrapper->finishCreation(vm, value);
-            return wrapper;
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesGetPropertyNames), info());
+    }
 
-    protected:
-        void finishCreation(VM& vm, JSValue value)
-        {
-            Base::finishCreation(vm);
-            m_value.set(vm, this, value);
-            ASSERT(!value.isCell());
-        }
+    DECLARE_EXPORT_INFO;
 
-    private:
-        JSAPIValueWrapper(ExecState* exec)
-            : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get())
-        {
-        }
+    static JSAPIValueWrapper* create(ExecState* exec, JSValue value) 
+    {
+        VM& vm = exec->vm();
+        JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(exec);
+        wrapper->finishCreation(vm, value);
+        return wrapper;
+    }
 
-        WriteBarrier<Unknown> m_value;
-    };
+protected:
+    void finishCreation(VM& vm, JSValue value)
+    {
+        Base::finishCreation(vm);
+        m_value.set(vm, this, value);
+        ASSERT(!value.isCell());
+    }
 
-    inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
+private:
+    JSAPIValueWrapper(ExecState* exec)
+        : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get())
     {
-        return JSAPIValueWrapper::create(exec, value);
     }
 
+    WriteBarrier<Unknown> m_value;
+};
+
+inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
+{
+    return JSAPIValueWrapper::create(exec, value);
+}
+
 } // namespace JSC
 
 #endif // JSAPIValueWrapper_h
diff --git a/runtime/JSActivation.cpp b/runtime/JSActivation.cpp
deleted file mode 100644 (file)
index 8296506..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "config.h"
-#include "JSActivation.h"
-
-#include "Arguments.h"
-#include "Interpreter.h"
-#include "JSFunction.h"
-#include "JSCInlines.h"
-
-using namespace std;
-
-namespace JSC {
-
-const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) };
-
-void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSActivation* thisObject = jsCast<JSActivation*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    // No need to mark our registers if they're still in the JSStack.
-    if (!thisObject->isTornOff())
-        return;
-
-    for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i)
-        visitor.append(&thisObject->storage()[i]);
-}
-
-inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
-{
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
-    if (entry.isNull())
-        return false;
-
-    // Defend against the inspector asking for a var after it has been optimized out.
-    if (isTornOff() && !isValid(entry))
-        return false;
-
-    slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
-    return true;
-}
-
-inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor)
-{
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
-    if (entry.isNull())
-        return false;
-
-    // Defend against the inspector asking for a var after it has been optimized out.
-    if (isTornOff() && !isValid(entry))
-        return false;
-
-    descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
-    return true;
-}
-
-inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrow)
-{
-    VM& vm = exec->vm();
-    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
-    
-    WriteBarrierBase<Unknown>* reg;
-    {
-        GCSafeConcurrentJITLocker locker(symbolTable()->m_lock, exec->vm().heap);
-        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.uid());
-        if (iter == symbolTable()->end(locker))
-            return false;
-        ASSERT(!iter->value.isNull());
-        if (iter->value.isReadOnly()) {
-            if (shouldThrow)
-                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-            return true;
-        }
-        // Defend against the inspector asking for a var after it has been optimized out.
-        if (isTornOff() && !isValid(iter->value))
-            return false;
-        if (VariableWatchpointSet* set = iter->value.watchpointSet())
-            set->invalidate(); // Don't mess around - if we had found this statically, we would have invcalidated it.
-        reg = &registerAt(iter->value.getIndex());
-    }
-    reg->set(vm, this, value);
-    return true;
-}
-
-void JSActivation::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
-    JSActivation* thisObject = jsCast<JSActivation*>(object);
-
-    CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
-    if (mode == IncludeDontEnumProperties && !thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))
-        propertyNames.add(exec->propertyNames().arguments);
-
-    {
-        ConcurrentJITLocker locker(thisObject->symbolTable()->m_lock);
-        SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker);
-        for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
-            if (it->value.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
-                continue;
-            if (!thisObject->isValid(it->value))
-                continue;
-            propertyNames.add(Identifier(exec, it->key.get()));
-        }
-    }
-    // Skip the JSVariableObject implementation of getOwnNonIndexPropertyNames
-    JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
-}
-
-inline bool JSActivation::symbolTablePutWithAttributes(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
-{
-    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
-    
-    WriteBarrierBase<Unknown>* reg;
-    {
-        ConcurrentJITLocker locker(symbolTable()->m_lock);
-        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.uid());
-        if (iter == symbolTable()->end(locker))
-            return false;
-        SymbolTableEntry& entry = iter->value;
-        ASSERT(!entry.isNull());
-        if (!isValid(entry))
-            return false;
-        
-        entry.setAttributes(attributes);
-        reg = &registerAt(entry.getIndex());
-    }
-    reg->set(vm, this, value);
-    return true;
-}
-
-bool JSActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    JSActivation* thisObject = jsCast<JSActivation*>(object);
-
-    if (propertyName == exec->propertyNames().arguments) {
-        // Defend against the inspector asking for the arguments object after it has been optimized out.
-        CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
-        if (!thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) {
-            slot.setCustom(thisObject, DontEnum, argumentsGetter);
-            return true;
-        }
-    }
-
-    if (thisObject->symbolTableGet(propertyName, slot))
-        return true;
-
-    unsigned attributes;
-    if (JSValue value = thisObject->getDirect(exec->vm(), propertyName, attributes)) {
-        slot.setValue(thisObject, attributes, value);
-        return true;
-    }
-
-    // We don't call through to JSObject because there's no way to give an 
-    // activation object getter properties or a prototype.
-    ASSERT(!thisObject->hasGetterSetterProperties());
-    ASSERT(thisObject->prototype().isNull());
-    return false;
-}
-
-void JSActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
-    JSActivation* thisObject = jsCast<JSActivation*>(cell);
-    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
-
-    if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode()))
-        return;
-
-    // We don't call through to JSObject because __proto__ and getter/setter 
-    // properties are non-standard extensions that other implementations do not
-    // expose in the activation object.
-    ASSERT(!thisObject->hasGetterSetterProperties());
-    thisObject->putOwnDataProperty(exec->vm(), propertyName, value, slot);
-}
-
-bool JSActivation::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
-{
-    if (propertyName == exec->propertyNames().arguments)
-        return false;
-
-    return Base::deleteProperty(cell, exec, propertyName);
-}
-
-JSValue JSActivation::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
-{
-    if (ecmaMode == StrictMode)
-        return jsUndefined();
-    return exec->globalThisValue();
-}
-
-EncodedJSValue JSActivation::argumentsGetter(ExecState*, JSObject* slotBase, EncodedJSValue, PropertyName)
-{
-    JSActivation* activation = jsCast<JSActivation*>(slotBase);
-    CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
-    ASSERT(!activation->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()));
-    if (activation->isTornOff() || !(callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))
-        return JSValue::encode(jsUndefined());
-
-    VirtualRegister argumentsRegister = callFrame->codeBlock()->argumentsRegister();
-    if (JSValue arguments = callFrame->uncheckedR(argumentsRegister.offset()).jsValue())
-        return JSValue::encode(arguments);
-    int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister).offset();
-
-    JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame));
-    callFrame->uncheckedR(argumentsRegister.offset()) = arguments;
-    callFrame->uncheckedR(realArgumentsRegister) = arguments;
-    
-    ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info()));
-    return JSValue::encode(callFrame->uncheckedR(realArgumentsRegister).jsValue());
-}
-
-} // namespace JSC
diff --git a/runtime/JSActivation.h b/runtime/JSActivation.h
deleted file mode 100644 (file)
index 55c5ade..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef JSActivation_h
-#define JSActivation_h
-
-#include "CodeBlock.h"
-#include "CopiedSpaceInlines.h"
-#include "JSVariableObject.h"
-#include "Nodes.h"
-#include "SymbolTable.h"
-
-namespace JSC {
-
-class Register;
-    
-class JSActivation : public JSVariableObject {
-private:
-    JSActivation(VM&, CallFrame*, Register*, SymbolTable*);
-    
-public:
-    typedef JSVariableObject Base;
-
-    static JSActivation* create(VM& vm, CallFrame* callFrame, Register* registers, CodeBlock* codeBlock)
-    {
-        SymbolTable* symbolTable = codeBlock->symbolTable();
-        ASSERT(codeBlock->codeType() == FunctionCode);
-        JSActivation* activation = new (
-            NotNull,
-            allocateCell<JSActivation>(
-                vm.heap,
-                allocationSize(symbolTable)
-            )
-        ) JSActivation(vm, callFrame, registers, symbolTable);
-        activation->finishCreation(vm);
-        return activation;
-    }
-        
-    static JSActivation* create(VM& vm, CallFrame* callFrame, CodeBlock* codeBlock)
-    {
-        return create(vm, callFrame, callFrame->registers() + codeBlock->framePointerOffsetToGetActivationRegisters(), codeBlock);
-    }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-
-    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-
-    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-
-    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
-
-    void tearOff(VM&);
-        
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), info()); }
-
-    WriteBarrierBase<Unknown>& registerAt(int) const;
-    bool isValidIndex(int) const;
-    bool isValid(const SymbolTableEntry&) const;
-    bool isTornOff();
-    int registersOffset();
-    static int registersOffset(SymbolTable*);
-
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
-
-private:
-    bool symbolTableGet(PropertyName, PropertySlot&);
-    bool symbolTableGet(PropertyName, PropertyDescriptor&);
-    bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
-    bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
-    bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
-
-    static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-
-    static size_t allocationSize(SymbolTable*);
-    static size_t storageOffset();
-
-    WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
-};
-
-extern int activationCount;
-extern int allTheThingsCount;
-
-inline JSActivation::JSActivation(VM& vm, CallFrame* callFrame, Register* registers, SymbolTable* symbolTable)
-    : Base(
-        vm,
-        callFrame->lexicalGlobalObject()->activationStructure(),
-        registers,
-        callFrame->scope(),
-        symbolTable)
-{
-    WriteBarrier<Unknown>* storage = this->storage();
-    size_t captureCount = symbolTable->captureCount();
-    for (size_t i = 0; i < captureCount; ++i)
-        new (NotNull, &storage[i]) WriteBarrier<Unknown>;
-}
-
-JSActivation* asActivation(JSValue);
-
-inline JSActivation* asActivation(JSValue value)
-{
-    ASSERT(asObject(value)->inherits(JSActivation::info()));
-    return jsCast<JSActivation*>(asObject(value));
-}
-    
-ALWAYS_INLINE JSActivation* Register::activation() const
-{
-    return asActivation(jsValue());
-}
-
-inline int JSActivation::registersOffset(SymbolTable* symbolTable)
-{
-    return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart()  - 1) * sizeof(WriteBarrier<Unknown>));
-}
-
-inline void JSActivation::tearOff(VM& vm)
-{
-    ASSERT(!isTornOff());
-
-    WriteBarrierBase<Unknown>* dst = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
-        reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
-    WriteBarrierBase<Unknown>* src = m_registers;
-
-    int captureEnd = symbolTable()->captureEnd();
-    for (int i = symbolTable()->captureStart(); i > captureEnd; --i)
-        dst[i].set(vm, this, src[i].get());
-
-    m_registers = dst;
-    ASSERT(isTornOff());
-}
-
-inline bool JSActivation::isTornOff()
-{
-    return m_registers == reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
-        reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
-}
-
-inline size_t JSActivation::storageOffset()
-{
-    return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
-}
-
-inline WriteBarrier<Unknown>* JSActivation::storage()
-{
-    return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
-        reinterpret_cast<char*>(this) + storageOffset());
-}
-
-inline size_t JSActivation::allocationSize(SymbolTable* symbolTable)
-{
-    size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
-    size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
-    return objectSizeInBytes + storageSizeInBytes;
-}
-
-inline bool JSActivation::isValidIndex(int index) const
-{
-    if (index > symbolTable()->captureStart())
-        return false;
-    if (index <= symbolTable()->captureEnd())
-        return false;
-    return true;
-}
-
-inline bool JSActivation::isValid(const SymbolTableEntry& entry) const
-{
-    return isValidIndex(entry.getIndex());
-}
-
-inline WriteBarrierBase<Unknown>& JSActivation::registerAt(int index) const
-{
-    ASSERT(isValidIndex(index));
-    return Base::registerAt(index);
-}
-
-} // namespace JSC
-
-#endif // JSActivation_h
diff --git a/runtime/JSArgumentsIterator.cpp b/runtime/JSArgumentsIterator.cpp
deleted file mode 100644 (file)
index b902a3d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "JSArgumentsIterator.h"
-
-#include "Arguments.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo JSArgumentsIterator::s_info = { "ArgumentsIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArgumentsIterator) };
-
-void JSArgumentsIterator::finishCreation(VM& vm, Arguments* arguments)
-{
-    Base::finishCreation(vm);
-    m_arguments.set(vm, this, arguments);
-}
-
-}
diff --git a/runtime/JSArgumentsIterator.h b/runtime/JSArgumentsIterator.h
deleted file mode 100644 (file)
index 0eed745..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef JSArgumentsIterator_h
-#define JSArgumentsIterator_h
-
-#include "Arguments.h"
-
-namespace JSC {
-
-class JSArgumentsIterator : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    DECLARE_EXPORT_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-    static JSArgumentsIterator* create(VM& vm, Structure* structure, Arguments* arguments)
-    {
-        JSArgumentsIterator* instance = new (NotNull, allocateCell<JSArgumentsIterator>(vm.heap)) JSArgumentsIterator(vm, structure);
-        instance->finishCreation(vm, arguments);
-        return instance;
-    }
-
-    bool next(CallFrame* callFrame, JSValue& value)
-    {
-        if (m_nextIndex >= m_arguments->length(callFrame))
-            return false;
-        value = m_arguments->tryGetArgument(m_nextIndex++);
-        if (!value)
-            value = jsUndefined();
-        return true;
-    }
-
-private:
-
-    static const unsigned StructureFlags = Base::StructureFlags;
-
-    JSArgumentsIterator(VM& vm, Structure* structure)
-        : Base(vm, structure)
-        , m_nextIndex(0)
-    {
-    }
-
-    void finishCreation(VM&, Arguments*);
-    
-    WriteBarrier<Arguments> m_arguments;
-    size_t m_nextIndex;
-};
-
-}
-
-#endif // !defined(JSArgumentsIterator_h)
index f4bc093deedf1a176a369cde6aa97347602fea08..2c5a19ae6ee65808b7d71ca35037588d50061b35 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
  *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
  *
@@ -34,9 +34,7 @@
 #include "JSCInlines.h"
 #include "PropertyNameArray.h"
 #include "Reject.h"
-#include <wtf/AVLTree.h>
 #include <wtf/Assertions.h>
-#include <wtf/OwnPtr.h>
 
 using namespace std;
 using namespace WTF;
@@ -45,7 +43,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSArray);
 
-const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSArray)};
+const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, CREATE_METHOD_TABLE(JSArray)};
 
 Butterfly* createArrayButterflyInDictionaryIndexingMode(
     VM& vm, JSCell* intendedOwner, unsigned initialLength)
@@ -108,11 +106,12 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName
         unsigned newLen = descriptor.value().toUInt32(exec);
         // d. If newLen is not equal to ToNumber( Desc.[[Value]]), throw a RangeError exception.
         if (newLen != descriptor.value().toNumber(exec)) {
-            exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
+            exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
             return false;
         }
 
         // Based on SameValue check in 8.12.9, this is always okay.
+        // FIXME: Nothing prevents this from being called on a RuntimeArray, and the length function will always return 0 in that case.
         if (newLen == array->length()) {
             if (descriptor.writablePresent())
                 array->setLengthWritable(exec, descriptor.writable());
@@ -159,9 +158,10 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName
 
     // 4. Else if P is an array index (15.4), then
     // a. Let index be ToUint32(P).
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex) {
+    if (Optional<uint32_t> optionalIndex = parseIndex(propertyName)) {
         // b. Reject if index >= oldLen and oldLenDesc.[[Writable]] is false.
+        uint32_t index = optionalIndex.value();
+        // FIXME: Nothing prevents this from being called on a RuntimeArray, and the length function will always return 0 in that case.
         if (index >= array->length() && !array->isLengthWritable())
             return reject(exec, throwException, "Attempting to define numeric property on array with non-writable length property.");
         // c. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing P, Desc, and false as arguments.
@@ -227,7 +227,7 @@ void JSArray::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pro
 {
     JSArray* thisObject = jsCast<JSArray*>(object);
 
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         propertyNames.add(exec->propertyNames().length);
 
     JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
@@ -378,7 +378,7 @@ bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo
         unsigned usedVectorLength = min(length, storage->vectorLength());
         for (unsigned i = newLength; i < usedVectorLength; ++i) {
             WriteBarrier<Unknown>& valueSlot = storage->m_vector[i];
-            bool hadValue = valueSlot;
+            bool hadValue = !!valueSlot;
             valueSlot.clear();
             storage->m_numValuesInVector -= hadValue;
         }
@@ -406,7 +406,7 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
     case ArrayWithUndecided:
     case ArrayWithInt32:
     case ArrayWithDouble:
-    case ArrayWithContiguous:
+    case ArrayWithContiguous: {
         if (newLength == m_butterfly->publicLength())
             return true;
         if (newLength >= MAX_ARRAY_INDEX // This case ensures that we can do fast push.
@@ -420,6 +420,14 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
             ensureLength(exec->vm(), newLength);
             return true;
         }
+
+        unsigned lengthToClear = m_butterfly->publicLength() - newLength;
+        unsigned costToAllocateNewButterfly = 64; // a heuristic.
+        if (lengthToClear > newLength && lengthToClear > costToAllocateNewButterfly) {
+            reallocateAndShrinkButterfly(exec->vm(), newLength);
+            return true;
+        }
+
         if (indexingType() == ArrayWithDouble) {
             for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
                 m_butterfly->contiguousDouble()[i] = PNaN;
@@ -429,6 +437,7 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
         }
         m_butterfly->setPublicLength(newLength);
         return true;
+    }
         
     case ArrayWithArrayStorage:
     case ArrayWithSlowPutArrayStorage:
@@ -523,7 +532,7 @@ JSValue JSArray::pop(ExecState* exec)
         return jsUndefined();
     // Call the [[Delete]] internal method of O with arguments indx and true.
     if (!deletePropertyByIndex(this, exec, index)) {
-        throwTypeError(exec, "Unable to delete property.");
+        throwTypeError(exec, ASCIILiteral("Unable to delete property."));
         return jsUndefined();
     }
     // Call the [[Put]] internal method of O with arguments "length", indx, and true.
@@ -567,7 +576,7 @@ void JSArray::push(ExecState* exec, JSValue value)
         if (length > MAX_ARRAY_INDEX) {
             methodTable(exec->vm())->putByIndex(this, exec, length, value, true);
             if (!exec->hadException())
-                exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
+                exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
             return;
         }
         
@@ -587,7 +596,7 @@ void JSArray::push(ExecState* exec, JSValue value)
         if (length > MAX_ARRAY_INDEX) {
             methodTable(exec->vm())->putByIndex(this, exec, length, value, true);
             if (!exec->hadException())
-                exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
+                exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
             return;
         }
         
@@ -619,7 +628,7 @@ void JSArray::push(ExecState* exec, JSValue value)
         if (length > MAX_ARRAY_INDEX) {
             methodTable(exec->vm())->putByIndex(this, exec, length, value, true);
             if (!exec->hadException())
-                exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
+                exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
             return;
         }
         
@@ -654,7 +663,7 @@ void JSArray::push(ExecState* exec, JSValue value)
             methodTable(exec->vm())->putByIndex(this, exec, storage->length(), value, true);
             // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
             if (!exec->hadException())
-                exec->vm().throwException(exec, createRangeError(exec, "Invalid array length"));
+                exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
             return;
         }
 
@@ -668,6 +677,68 @@ void JSArray::push(ExecState* exec, JSValue value)
     }
 }
 
+JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)
+{
+    auto arrayType = indexingType();
+    switch (arrayType) {
+    case ArrayWithDouble:
+    case ArrayWithInt32:
+    case ArrayWithContiguous: {
+        VM& vm = exec.vm();
+        if (count >= MIN_SPARSE_ARRAY_INDEX || structure(vm)->holesMustForwardToPrototype(vm))
+            return nullptr;
+
+        Structure* resultStructure = exec.lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(arrayType);
+        JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, count);
+        if (!resultArray)
+            return nullptr;
+
+        auto& resultButterfly = *resultArray->butterfly();
+        if (arrayType == ArrayWithDouble)
+            memcpy(resultButterfly.contiguousDouble().data(), m_butterfly->contiguousDouble().data() + startIndex, sizeof(JSValue) * count);
+        else
+            memcpy(resultButterfly.contiguous().data(), m_butterfly->contiguous().data() + startIndex, sizeof(JSValue) * count);
+        resultButterfly.setPublicLength(count);
+
+        return resultArray;
+    }
+    default:
+        return nullptr;
+    }
+}
+
+EncodedJSValue JSArray::fastConcatWith(ExecState& exec, JSArray& otherArray)
+{
+    auto newArrayType = indexingType();
+
+    VM& vm = exec.vm();
+    ASSERT(newArrayType == fastConcatType(vm, *this, otherArray));
+
+    unsigned thisArraySize = m_butterfly->publicLength();
+    unsigned otherArraySize = otherArray.m_butterfly->publicLength();
+    ASSERT(thisArraySize + otherArraySize < MIN_SPARSE_ARRAY_INDEX);
+
+    Structure* resultStructure = exec.lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(newArrayType);
+    JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, thisArraySize + otherArraySize);
+    if (!resultArray)
+        return JSValue::encode(throwOutOfMemoryError(&exec));
+
+    auto& resultButterfly = *resultArray->butterfly();
+    auto& otherButterfly = *otherArray.butterfly();
+    if (newArrayType == ArrayWithDouble) {
+        auto buffer = resultButterfly.contiguousDouble().data();
+        memcpy(buffer, m_butterfly->contiguousDouble().data(), sizeof(JSValue) * thisArraySize);
+        memcpy(buffer + thisArraySize, otherButterfly.contiguousDouble().data(), sizeof(JSValue) * otherArraySize);
+    } else {
+        auto buffer = resultButterfly.contiguous().data();
+        memcpy(buffer, m_butterfly->contiguous().data(), sizeof(JSValue) * thisArraySize);
+        memcpy(buffer + thisArraySize, otherButterfly.contiguous().data(), sizeof(JSValue) * otherArraySize);
+    }
+
+    resultButterfly.setPublicLength(thisArraySize + otherArraySize);
+    return JSValue::encode(resultArray);
+}
+
 bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
 {
     unsigned oldLength = storage->length();
@@ -676,7 +747,7 @@ bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned c
     // If the array contains holes or is otherwise in an abnormal state,
     // use the generic algorithm in ArrayPrototype.
     if ((storage->hasHoles() && this->structure(vm)->holesMustForwardToPrototype(vm)) 
-        || inSparseIndexingMode() 
+        || hasSparseMap() 
         || shouldUseSlowPut(indexingType())) {
         return false;
     }
@@ -995,519 +1066,6 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
     }
 }
 
-static int compareNumbersForQSortWithInt32(const void* a, const void* b)
-{
-    int32_t ia = static_cast<const JSValue*>(a)->asInt32();
-    int32_t ib = static_cast<const JSValue*>(b)->asInt32();
-    return ia - ib;
-}
-
-static int compareNumbersForQSortWithDouble(const void* a, const void* b)
-{
-    double da = *static_cast<const double*>(a);
-    double db = *static_cast<const double*>(b);
-    return (da > db) - (da < db);
-}
-
-static int compareNumbersForQSort(const void* a, const void* b)
-{
-    double da = static_cast<const JSValue*>(a)->asNumber();
-    double db = static_cast<const JSValue*>(b)->asNumber();
-    return (da > db) - (da < db);
-}
-
-static int compareByStringPairForQSort(const void* a, const void* b)
-{
-    const ValueStringPair* va = static_cast<const ValueStringPair*>(a);
-    const ValueStringPair* vb = static_cast<const ValueStringPair*>(b);
-    return codePointCompare(va->second, vb->second);
-}
-
-template<IndexingType arrayIndexingType>
-void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
-    ASSERT(arrayIndexingType == ArrayWithInt32 || arrayIndexingType == ArrayWithDouble || arrayIndexingType == ArrayWithContiguous || arrayIndexingType == ArrayWithArrayStorage);
-    
-    unsigned lengthNotIncludingUndefined;
-    unsigned newRelevantLength;
-    compactForSorting<arrayIndexingType>(
-        lengthNotIncludingUndefined,
-        newRelevantLength);
-    
-    ContiguousJSValues data = indexingData<arrayIndexingType>();
-    
-    if (arrayIndexingType == ArrayWithArrayStorage && arrayStorage()->m_sparseMap.get()) {
-        throwOutOfMemoryError(exec);
-        return;
-    }
-    
-    if (!lengthNotIncludingUndefined)
-        return;
-    
-    bool allValuesAreNumbers = true;
-    switch (arrayIndexingType) {
-    case ArrayWithInt32:
-    case ArrayWithDouble:
-        break;
-        
-    default:
-        for (size_t i = 0; i < newRelevantLength; ++i) {
-            if (!data[i].isNumber()) {
-                allValuesAreNumbers = false;
-                break;
-            }
-        }
-        break;
-    }
-    
-    if (!allValuesAreNumbers)
-        return sort(exec, compareFunction, callType, callData);
-    
-    // For numeric comparison, which is fast, qsort is faster than mergesort. We
-    // also don't require mergesort's stability, since there's no user visible
-    // side-effect from swapping the order of equal primitive values.
-    int (*compare)(const void*, const void*);
-    switch (arrayIndexingType) {
-    case ArrayWithInt32:
-        compare = compareNumbersForQSortWithInt32;
-        break;
-        
-    case ArrayWithDouble:
-        compare = compareNumbersForQSortWithDouble;
-        ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(double));
-        break;
-        
-    default:
-        compare = compareNumbersForQSort;
-        break;
-    }
-    ASSERT(data.length() >= newRelevantLength);
-    qsort(data.data(), newRelevantLength, sizeof(WriteBarrier<Unknown>), compare);
-    return;
-}
-
-void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
-    ASSERT(!inSparseIndexingMode());
-
-    switch (indexingType()) {
-    case ArrayClass:
-        return;
-        
-    case ArrayWithInt32:
-        sortNumericVector<ArrayWithInt32>(exec, compareFunction, callType, callData);
-        break;
-        
-    case ArrayWithDouble:
-        sortNumericVector<ArrayWithDouble>(exec, compareFunction, callType, callData);
-        break;
-        
-    case ArrayWithContiguous:
-        sortNumericVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
-        return;
-
-    case ArrayWithArrayStorage:
-        sortNumericVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData);
-        return;
-        
-    default:
-        CRASH();
-        return;
-    }
-}
-
-template <IndexingType> struct ContiguousTypeAccessor {
-    typedef WriteBarrier<Unknown> Type;
-    static JSValue getAsValue(ContiguousData<Type> data, size_t i) { return data[i].get(); }
-    static void setWithValue(VM& vm, JSArray* thisValue, ContiguousData<Type> data, size_t i, JSValue value)
-    {
-        data[i].set(vm, thisValue, value);
-    }
-    static void replaceDataReference(ContiguousData<Type>* outData, ContiguousJSValues inData)
-    {
-        *outData = inData;
-    }
-};
-
-template <> struct ContiguousTypeAccessor<ArrayWithDouble> {
-    typedef double Type;
-    static JSValue getAsValue(ContiguousData<Type> data, size_t i) { ASSERT(data[i] == data[i]); return JSValue(JSValue::EncodeAsDouble, data[i]); }
-    static void setWithValue(VM&, JSArray*, ContiguousData<Type> data, size_t i, JSValue value)
-    {
-        data[i] = value.asNumber();
-    }
-    static NO_RETURN_DUE_TO_CRASH void replaceDataReference(ContiguousData<Type>*, ContiguousJSValues)
-    {
-        RELEASE_ASSERT_WITH_MESSAGE(0, "Inconsistent indexing types during compact array sort.");
-    }
-};
-
-
-template<IndexingType arrayIndexingType, typename StorageType>
-void JSArray::sortCompactedVector(ExecState* exec, ContiguousData<StorageType> data, unsigned relevantLength)
-{
-    if (!relevantLength)
-        return;
-    
-    VM& vm = exec->vm();
-
-    // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
-    // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
-    // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
-    // random or otherwise changing results, effectively making compare function inconsistent.
-        
-    Vector<ValueStringPair, 0, UnsafeVectorOverflow> values(relevantLength);
-    if (!values.begin()) {
-        throwOutOfMemoryError(exec);
-        return;
-    }
-        
-    Heap::heap(this)->pushTempSortVector(&values);
-        
-    bool isSortingPrimitiveValues = true;
-
-    for (size_t i = 0; i < relevantLength; i++) {
-        JSValue value = ContiguousTypeAccessor<arrayIndexingType>::getAsValue(data, i);
-        ASSERT(arrayIndexingType != ArrayWithInt32 || value.isInt32());
-        ASSERT(!value.isUndefined());
-        values[i].first = value;
-        if (arrayIndexingType != ArrayWithDouble && arrayIndexingType != ArrayWithInt32)
-            isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
-    }
-        
-    // FIXME: The following loop continues to call toString on subsequent values even after
-    // a toString call raises an exception.
-        
-    for (size_t i = 0; i < relevantLength; i++)
-        values[i].second = values[i].first.toWTFStringInline(exec);
-        
-    if (exec->hadException()) {
-        Heap::heap(this)->popTempSortVector(&values);
-        return;
-    }
-        
-    // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather
-    // than O(N log N).
-        
-#if HAVE(MERGESORT)
-    if (isSortingPrimitiveValues)
-        qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
-    else
-        mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
-#else
-    // FIXME: The qsort library function is likely to not be a stable sort.
-    // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
-    qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
-#endif
-    
-    // If the toString function changed the length of the array or vector storage,
-    // increase the length to handle the orignal number of actual values.
-    switch (arrayIndexingType) {
-    case ArrayWithInt32:
-    case ArrayWithDouble:
-    case ArrayWithContiguous:
-        ensureLength(vm, relevantLength);
-        break;
-        
-    case ArrayWithArrayStorage:
-        if (arrayStorage()->vectorLength() < relevantLength) {
-            increaseVectorLength(exec->vm(), relevantLength);
-            ContiguousTypeAccessor<arrayIndexingType>::replaceDataReference(&data, arrayStorage()->vector());
-        }
-        if (arrayStorage()->length() < relevantLength)
-            arrayStorage()->setLength(relevantLength);
-        break;
-        
-    default:
-        CRASH();
-    }
-
-    for (size_t i = 0; i < relevantLength; i++)
-        ContiguousTypeAccessor<arrayIndexingType>::setWithValue(vm, this, data, i, values[i].first);
-    
-    Heap::heap(this)->popTempSortVector(&values);
-}
-
-void JSArray::sort(ExecState* exec)
-{
-    ASSERT(!inSparseIndexingMode());
-    
-    switch (indexingType()) {
-    case ArrayClass:
-    case ArrayWithUndecided:
-        return;
-        
-    case ArrayWithInt32: {
-        unsigned lengthNotIncludingUndefined;
-        unsigned newRelevantLength;
-        compactForSorting<ArrayWithInt32>(
-            lengthNotIncludingUndefined, newRelevantLength);
-        
-        sortCompactedVector<ArrayWithInt32>(
-            exec, m_butterfly->contiguousInt32(), lengthNotIncludingUndefined);
-        return;
-    }
-        
-    case ArrayWithDouble: {
-        unsigned lengthNotIncludingUndefined;
-        unsigned newRelevantLength;
-        compactForSorting<ArrayWithDouble>(
-            lengthNotIncludingUndefined, newRelevantLength);
-        
-        sortCompactedVector<ArrayWithDouble>(
-            exec, m_butterfly->contiguousDouble(), lengthNotIncludingUndefined);
-        return;
-    }
-        
-    case ArrayWithContiguous: {
-        unsigned lengthNotIncludingUndefined;
-        unsigned newRelevantLength;
-        compactForSorting<ArrayWithContiguous>(
-            lengthNotIncludingUndefined, newRelevantLength);
-        
-        sortCompactedVector<ArrayWithContiguous>(
-            exec, m_butterfly->contiguous(), lengthNotIncludingUndefined);
-        return;
-    }
-        
-    case ArrayWithArrayStorage: {
-        unsigned lengthNotIncludingUndefined;
-        unsigned newRelevantLength;
-        compactForSorting<ArrayWithArrayStorage>(
-            lengthNotIncludingUndefined, newRelevantLength);
-        ArrayStorage* storage = m_butterfly->arrayStorage();
-        ASSERT(!storage->m_sparseMap);
-        
-        sortCompactedVector<ArrayWithArrayStorage>(exec, storage->vector(), lengthNotIncludingUndefined);
-        return;
-    }
-        
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-
-struct AVLTreeNodeForArrayCompare {
-    JSValue value;
-
-    // Child pointers.  The high bit of gt is robbed and used as the
-    // balance factor sign.  The high bit of lt is robbed and used as
-    // the magnitude of the balance factor.
-    int32_t gt;
-    int32_t lt;
-};
-
-struct AVLTreeAbstractorForArrayCompare {
-    typedef int32_t handle; // Handle is an index into m_nodes vector.
-    typedef JSValue key;
-    typedef int32_t size;
-
-    Vector<AVLTreeNodeForArrayCompare, 0, UnsafeVectorOverflow> m_nodes;
-    ExecState* m_exec;
-    JSValue m_compareFunction;
-    CallType m_compareCallType;
-    const CallData* m_compareCallData;
-    OwnPtr<CachedCall> m_cachedCall;
-
-    handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
-    void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
-    handle get_greater(handle h) { return m_nodes[h].gt & 0x7FFFFFFF; }
-    void set_greater(handle h, handle gh) { m_nodes[h].gt &= 0x80000000; m_nodes[h].gt |= gh; }
-
-    int get_balance_factor(handle h)
-    {
-        if (m_nodes[h].gt & 0x80000000)
-            return -1;
-        return static_cast<unsigned>(m_nodes[h].lt) >> 31;
-    }
-
-    void set_balance_factor(handle h, int bf)
-    {
-        if (bf == 0) {
-            m_nodes[h].lt &= 0x7FFFFFFF;
-            m_nodes[h].gt &= 0x7FFFFFFF;
-        } else {
-            m_nodes[h].lt |= 0x80000000;
-            if (bf < 0)
-                m_nodes[h].gt |= 0x80000000;
-            else
-                m_nodes[h].gt &= 0x7FFFFFFF;
-        }
-    }
-
-    int compare_key_key(key va, key vb)
-    {
-        ASSERT(!va.isUndefined());
-        ASSERT(!vb.isUndefined());
-
-        if (m_exec->hadException())
-            return 1;
-
-        double compareResult;
-        if (m_cachedCall) {
-            m_cachedCall->setThis(jsUndefined());
-            m_cachedCall->setArgument(0, va);
-            m_cachedCall->setArgument(1, vb);
-            compareResult = m_cachedCall->call().toNumber(m_exec);
-        } else {
-            MarkedArgumentBuffer arguments;
-            arguments.append(va);
-            arguments.append(vb);
-            compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, jsUndefined(), arguments).toNumber(m_exec);
-        }
-        return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
-    }
-
-    int compare_key_node(key k, handle h) { return compare_key_key(k, m_nodes[h].value); }
-    int compare_node_node(handle h1, handle h2) { return compare_key_key(m_nodes[h1].value, m_nodes[h2].value); }
-
-    static handle null() { return 0x7FFFFFFF; }
-};
-
-template<IndexingType arrayIndexingType>
-void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
-    ASSERT(!inSparseIndexingMode());
-    ASSERT(arrayIndexingType == indexingType());
-    
-    // FIXME: This ignores exceptions raised in the compare function or in toNumber.
-        
-    // The maximum tree depth is compiled in - but the caller is clearly up to no good
-    // if a larger array is passed.
-    ASSERT(m_butterfly->publicLength() <= static_cast<unsigned>(std::numeric_limits<int>::max()));
-    if (m_butterfly->publicLength() > static_cast<unsigned>(std::numeric_limits<int>::max()))
-        return;
-        
-    unsigned usedVectorLength = relevantLength<arrayIndexingType>();
-    unsigned nodeCount = usedVectorLength;
-        
-    if (!nodeCount)
-        return;
-        
-    AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
-    tree.abstractor().m_exec = exec;
-    tree.abstractor().m_compareFunction = compareFunction;
-    tree.abstractor().m_compareCallType = callType;
-    tree.abstractor().m_compareCallData = &callData;
-    tree.abstractor().m_nodes.grow(nodeCount);
-        
-    if (callType == CallTypeJS)
-        tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, jsCast<JSFunction*>(compareFunction), 2));
-        
-    if (!tree.abstractor().m_nodes.begin()) {
-        throwOutOfMemoryError(exec);
-        return;
-    }
-        
-    // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified
-    // right out from under us while we're building the tree here.
-        
-    unsigned numDefined = 0;
-    unsigned numUndefined = 0;
-    
-    // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
-    for (; numDefined < usedVectorLength; ++numDefined) {
-        if (numDefined >= m_butterfly->vectorLength())
-            break;
-        JSValue v = getHolyIndexQuickly(numDefined);
-        if (!v || v.isUndefined())
-            break;
-        tree.abstractor().m_nodes[numDefined].value = v;
-        tree.insert(numDefined);
-    }
-    for (unsigned i = numDefined; i < usedVectorLength; ++i) {
-        if (i >= m_butterfly->vectorLength())
-            break;
-        JSValue v = getHolyIndexQuickly(i);
-        if (v) {
-            if (v.isUndefined())
-                ++numUndefined;
-            else {
-                tree.abstractor().m_nodes[numDefined].value = v;
-                tree.insert(numDefined);
-                ++numDefined;
-            }
-        }
-    }
-    
-    unsigned newUsedVectorLength = numDefined + numUndefined;
-        
-    // The array size may have changed. Figure out the new bounds.
-    unsigned newestUsedVectorLength = currentRelevantLength();
-        
-    unsigned elementsToExtractThreshold = min(min(newestUsedVectorLength, numDefined), static_cast<unsigned>(tree.abstractor().m_nodes.size()));
-    unsigned undefinedElementsThreshold = min(newestUsedVectorLength, newUsedVectorLength);
-    unsigned clearElementsThreshold = min(newestUsedVectorLength, usedVectorLength);
-        
-    // Copy the values back into m_storage.
-    AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
-    iter.start_iter_least(tree);
-    VM& vm = exec->vm();
-    for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
-        ASSERT(i < butterfly()->vectorLength());
-        if (indexingType() == ArrayWithDouble)
-            butterfly()->contiguousDouble()[i] = tree.abstractor().m_nodes[*iter].value.asNumber();
-        else
-            currentIndexingData()[i].set(vm, this, tree.abstractor().m_nodes[*iter].value);
-        ++iter;
-    }
-    // Put undefined values back in.
-    switch (indexingType()) {
-    case ArrayWithInt32:
-    case ArrayWithDouble:
-        ASSERT(elementsToExtractThreshold == undefinedElementsThreshold);
-        break;
-        
-    default:
-        for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i) {
-            ASSERT(i < butterfly()->vectorLength());
-            currentIndexingData()[i].setUndefined();
-        }
-    }
-
-    // Ensure that unused values in the vector are zeroed out.
-    for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) {
-        ASSERT(i < butterfly()->vectorLength());
-        if (indexingType() == ArrayWithDouble)
-            butterfly()->contiguousDouble()[i] = PNaN;
-        else
-            currentIndexingData()[i].clear();
-    }
-    
-    if (hasAnyArrayStorage(indexingType()))
-        arrayStorage()->m_numValuesInVector = newUsedVectorLength;
-}
-
-void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
-    ASSERT(!inSparseIndexingMode());
-    
-    switch (indexingType()) {
-    case ArrayClass:
-    case ArrayWithUndecided:
-        return;
-        
-    case ArrayWithInt32:
-        sortVector<ArrayWithInt32>(exec, compareFunction, callType, callData);
-        return;
-
-    case ArrayWithDouble:
-        sortVector<ArrayWithDouble>(exec, compareFunction, callType, callData);
-        return;
-
-    case ArrayWithContiguous:
-        sortVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
-        return;
-
-    case ArrayWithArrayStorage:
-        sortVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData);
-        return;
-        
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-
 void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
 {
     unsigned i = 0;
@@ -1553,9 +1111,11 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
         
     default:
         CRASH();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         vector = 0;
         vectorEnd = 0;
         break;
+#endif
     }
     
     for (; i < vectorEnd; ++i) {
@@ -1564,18 +1124,22 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
             break;
         args.append(v.get());
     }
-    
+
+    // FIXME: What prevents this from being called with a RuntimeArray? The length function will always return 0 in that case.
     for (; i < length(); ++i)
         args.append(get(exec, i));
 }
 
-void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
+void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
 {
-    unsigned i = firstVarArgOffset;
+    unsigned i = offset;
     WriteBarrier<Unknown>* vector;
     unsigned vectorEnd;
-    unsigned length = copyLength + firstVarArgOffset;
+    length += offset; // We like to think of the length as being our length, rather than the output length.
+
+    // FIXME: What prevents this from being called with a RuntimeArray? The length function will always return 0 in that case.
     ASSERT(length == this->length());
+
     switch (indexingType()) {
     case ArrayClass:
         return;
@@ -1601,7 +1165,7 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t co
             double v = m_butterfly->contiguousDouble()[i];
             if (v != v)
                 break;
-            callFrame->setArgument(i - firstVarArgOffset, JSValue(JSValue::EncodeAsDouble, v));
+            exec->r(firstElementDest + i - offset) = JSValue(JSValue::EncodeAsDouble, v);
         }
         break;
     }
@@ -1615,111 +1179,25 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t co
         
     default:
         CRASH();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         vector = 0;
         vectorEnd = 0;
         break;
+#endif
     }
     
     for (; i < vectorEnd; ++i) {
         WriteBarrier<Unknown>& v = vector[i];
         if (!v)
             break;
-        callFrame->setArgument(i - firstVarArgOffset, v.get());
+        exec->r(firstElementDest + i - offset) = v.get();
     }
     
-    for (; i < length; ++i)
-        callFrame->setArgument(i - firstVarArgOffset, get(exec, i));
-}
-
-template<IndexingType arrayIndexingType>
-void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLength)
-{
-    ASSERT(!inSparseIndexingMode());
-    ASSERT(arrayIndexingType == indexingType());
-
-    unsigned myRelevantLength = relevantLength<arrayIndexingType>();
-    
-    numDefined = 0;
-    unsigned numUndefined = 0;
-        
-    for (; numDefined < myRelevantLength; ++numDefined) {
-        ASSERT(numDefined < m_butterfly->vectorLength());
-        if (arrayIndexingType == ArrayWithInt32) {
-            JSValue v = m_butterfly->contiguousInt32()[numDefined].get();
-            if (!v)
-                break;
-            ASSERT(v.isInt32());
-            continue;
-        }
-        if (arrayIndexingType == ArrayWithDouble) {
-            double v = m_butterfly->contiguousDouble()[numDefined];
-            if (v != v)
-                break;
-            continue;
-        }
-        JSValue v = indexingData<arrayIndexingType>()[numDefined].get();
-        if (!v || v.isUndefined())
-            break;
-    }
-        
-    for (unsigned i = numDefined; i < myRelevantLength; ++i) {
-        ASSERT(i < m_butterfly->vectorLength());
-        if (arrayIndexingType == ArrayWithInt32) {
-            JSValue v = m_butterfly->contiguousInt32()[i].get();
-            if (!v)
-                continue;
-            ASSERT(v.isInt32());
-            ASSERT(numDefined < m_butterfly->vectorLength());
-            m_butterfly->contiguousInt32()[numDefined++].setWithoutWriteBarrier(v);
-            continue;
-        }
-        if (arrayIndexingType == ArrayWithDouble) {
-            double v = m_butterfly->contiguousDouble()[i];
-            if (v != v)
-                continue;
-            ASSERT(numDefined < m_butterfly->vectorLength());
-            m_butterfly->contiguousDouble()[numDefined++] = v;
-            continue;
-        }
-        JSValue v = indexingData<arrayIndexingType>()[i].get();
-        if (v) {
-            if (v.isUndefined())
-                ++numUndefined;
-            else {
-                ASSERT(numDefined < m_butterfly->vectorLength());
-                indexingData<arrayIndexingType>()[numDefined++].setWithoutWriteBarrier(v);
-            }
-        }
-    }
-        
-    newRelevantLength = numDefined + numUndefined;
-    
-    if (hasAnyArrayStorage(arrayIndexingType))
-        RELEASE_ASSERT(!arrayStorage()->m_sparseMap);
-    
-    switch (arrayIndexingType) {
-    case ArrayWithInt32:
-    case ArrayWithDouble:
-        RELEASE_ASSERT(numDefined == newRelevantLength);
-        break;
-        
-    default:
-        for (unsigned i = numDefined; i < newRelevantLength; ++i) {
-            ASSERT(i < m_butterfly->vectorLength());
-            indexingData<arrayIndexingType>()[i].setUndefined();
-        }
-        break;
-    }
-    for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) {
-        ASSERT(i < m_butterfly->vectorLength());
-        if (arrayIndexingType == ArrayWithDouble)
-            m_butterfly->contiguousDouble()[i] = PNaN;
-        else
-            indexingData<arrayIndexingType>()[i].clear();
+    for (; i < length; ++i) {
+        exec->r(firstElementDest + i - offset) = get(exec, i);
+        if (UNLIKELY(exec->vm().exception()))
+            return;
     }
-
-    if (hasAnyArrayStorage(arrayIndexingType))
-        arrayStorage()->m_numValuesInVector = newRelevantLength;
 }
 
 } // namespace JSC
index d1366cff2556cc503961bf4113f8f019db207159..45b558b20098118f9e3e16208947fce676b99eb5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009, 2012, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -37,6 +37,7 @@ class JSArray : public JSNonFinalObject {
 
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static size_t allocationSize(size_t inlineCapacity)
     {
@@ -52,6 +53,7 @@ protected:
 
 public:
     static JSArray* create(VM&, Structure*, unsigned initialLength = 0);
+    static JSArray* createWithButterfly(VM&, Structure*, Butterfly*);
 
     // tryCreateUninitialized is used for fast construction of arrays whose size and
     // contents are known at time of creation. Clients of this interface must:
@@ -61,20 +63,34 @@ public:
 
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool throwException);
 
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 
     DECLARE_EXPORT_INFO;
-        
+
+    // OK if we know this is a JSArray, but not if it could be an object of a derived class; for RuntimeArray this always returns 0.
     unsigned length() const { return getArrayLength(); }
-    // OK to use on new arrays, but not if it might be a RegExpMatchArray.
-    bool setLength(ExecState*, unsigned, bool throwException = false);
 
-    void sort(ExecState*);
-    void sort(ExecState*, JSValue compareFunction, CallType, const CallData&);
-    void sortNumeric(ExecState*, JSValue compareFunction, CallType, const CallData&);
+    // OK to use on new arrays, but not if it might be a RegExpMatchArray or RuntimeArray.
+    JS_EXPORT_PRIVATE bool setLength(ExecState*, unsigned, bool throwException = false);
+
+    JS_EXPORT_PRIVATE void push(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE JSValue pop(ExecState*);
 
-    void push(ExecState*, JSValue);
-    JSValue pop(ExecState*);
+    JSArray* fastSlice(ExecState&, unsigned startIndex, unsigned count);
+
+    static IndexingType fastConcatType(VM& vm, JSArray& firstArray, JSArray& secondArray)
+    {
+        IndexingType type = firstArray.indexingType();
+        if (type != secondArray.indexingType())
+            return NonArray;
+        if (type != ArrayWithDouble && type != ArrayWithInt32 && type != ArrayWithContiguous)
+            return NonArray;
+        if (firstArray.structure(vm)->holesMustForwardToPrototype(vm)
+            || secondArray.structure(vm)->holesMustForwardToPrototype(vm))
+            return NonArray;
+        return type;
+    }
+    EncodedJSValue fastConcatWith(ExecState&, JSArray&);
 
     enum ShiftCountMode {
         // This form of shift hints that we're doing queueing. With this assumption in hand,
@@ -131,8 +147,8 @@ public:
         }
     }
 
-    void fillArgList(ExecState*, MarkedArgumentBuffer&);
-    void copyToArguments(ExecState*, CallFrame*, uint32_t length, int32_t firstVarArgOffset);
+    JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&);
+    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
     {
@@ -140,7 +156,6 @@ public:
     }
         
 protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
 
     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
@@ -157,26 +172,14 @@ private:
     }
         
     bool shiftCountWithAnyIndexingType(ExecState*, unsigned& startIndex, unsigned count);
-    bool shiftCountWithArrayStorage(VM&, unsigned startIndex, unsigned count, ArrayStorage*);
+    JS_EXPORT_PRIVATE bool shiftCountWithArrayStorage(VM&, unsigned startIndex, unsigned count, ArrayStorage*);
 
     bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
     bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*);
     bool unshiftCountSlowCase(VM&, bool, unsigned);
 
-    template<IndexingType indexingType>
-    void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
-        
-    template<IndexingType indexingType, typename StorageType>
-    void sortCompactedVector(ExecState*, ContiguousData<StorageType>, unsigned relevantLength);
-        
-    template<IndexingType indexingType>
-    void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
-
     bool setLengthWithArrayStorage(ExecState*, unsigned newLength, bool throwException, ArrayStorage*);
     void setLengthWritable(ExecState*, bool writable);
-        
-    template<IndexingType indexingType>
-    void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
 };
 
 inline Butterfly* createContiguousArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned length, unsigned& vectorLength)
@@ -216,7 +219,7 @@ inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLe
             || hasContiguous(structure->indexingType()));
         unsigned vectorLength;
         butterfly = createContiguousArrayButterfly(vm, 0, initialLength, vectorLength);
-        ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
+        ASSERT(initialLength < MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH);
         if (hasDouble(structure->indexingType())) {
             for (unsigned i = 0; i < vectorLength; ++i)
                 butterfly->contiguousDouble()[i] = PNaN;
@@ -227,9 +230,8 @@ inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLe
             || structure->indexingType() == ArrayWithArrayStorage);
         butterfly = createArrayButterfly(vm, 0, initialLength);
     }
-    JSArray* array = new (NotNull, allocateCell<JSArray>(vm.heap)) JSArray(vm, structure, butterfly);
-    array->finishCreation(vm);
-    return array;
+
+    return createWithButterfly(vm, structure, butterfly);
 }
 
 inline JSArray* JSArray::tryCreateUninitialized(VM& vm, Structure* structure, unsigned initialLength)
@@ -267,7 +269,12 @@ inline JSArray* JSArray::tryCreateUninitialized(VM& vm, Structure* structure, un
         storage->m_sparseMap.clear();
         storage->m_numValuesInVector = initialLength;
     }
-        
+
+    return createWithButterfly(vm, structure, butterfly);
+}
+
+inline JSArray* JSArray::createWithButterfly(VM& vm, Structure* structure, Butterfly* butterfly)
+{
     JSArray* array = new (NotNull, allocateCell<JSArray>(vm.heap)) JSArray(vm, structure, butterfly);
     array->finishCreation(vm);
     return array;
index 6105bd6ad446b4bd6e17f2f4e14a2101bfe1d8cd..62ab89a3de24b4a37e54c94bec22c3b6d424ebf0 100644 (file)
@@ -32,7 +32,7 @@
 namespace JSC {
 
 const ClassInfo JSArrayBuffer::s_info = {
-    "ArrayBuffer", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayBuffer)};
+    "ArrayBuffer", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayBuffer)};
 
 JSArrayBuffer::JSArrayBuffer(VM& vm, Structure* structure, PassRefPtr<ArrayBuffer> arrayBuffer)
     : Base(vm, structure)
@@ -119,7 +119,7 @@ void JSArrayBuffer::getOwnNonIndexPropertyNames(
 {
     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object);
     
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         array.add(exec->propertyNames().byteLength);
     
     Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
index 319b82e5a0b116e8deb39a61010fa9ad36c00f19..7529e3634d4d3a571dbad32e90b2876a48abf871 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
 class JSArrayBuffer : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot;
     
 protected:
     JSArrayBuffer(VM&, Structure*, PassRefPtr<ArrayBuffer>);
@@ -56,8 +57,6 @@ protected:
     
     static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | Base::StructureFlags;
-
 private:
     ArrayBuffer* m_impl;
 };
index 22f79c898a74b4c08247b6dd6b41982e5c509653..3d14a9ef55f4c330c0ee78f0f863773d05dcf8c9 100644 (file)
@@ -38,7 +38,7 @@ namespace JSC {
 static EncodedJSValue JSC_HOST_CALL arrayBufferFuncIsView(ExecState*);
 
 const ClassInfo JSArrayBufferConstructor::s_info = {
-    "Function", &Base::s_info, 0, 0,
+    "Function", &Base::s_info, 0,
     CREATE_METHOD_TABLE(JSArrayBufferConstructor)
 };
 
@@ -49,7 +49,7 @@ JSArrayBufferConstructor::JSArrayBufferConstructor(VM& vm, Structure* structure)
 
 void JSArrayBufferConstructor::finishCreation(VM& vm, JSArrayBufferPrototype* prototype)
 {
-    Base::finishCreation(vm, "ArrayBuffer");
+    Base::finishCreation(vm, ASCIILiteral("ArrayBuffer"));
     putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), DontEnum | DontDelete | ReadOnly);
 
@@ -92,10 +92,10 @@ static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState* exec)
     
     RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, 1);
     if (!buffer)
-        return throwVMError(exec, createOutOfMemoryError(constructor->globalObject()));
+        return throwVMError(exec, createOutOfMemoryError(exec));
     
     JSArrayBuffer* result = JSArrayBuffer::create(
-        exec->vm(), constructor->globalObject()->arrayBufferStructure(), buffer);
+        exec->vm(), constructor->globalObject()->arrayBufferStructure(), buffer.release());
     
     return JSValue::encode(result);
 }
index 8ef3aa3caa565381a4d05357d7c99e40f8fb1bd5..ef650f6eb4b4f8c73c9595da7ab49093e87fca2c 100644 (file)
@@ -41,10 +41,10 @@ static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec)
     
     JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(exec->thisValue());
     if (!thisObject)
-        return throwVMError(exec, createTypeError(exec, "Receiver of slice must be an array buffer."));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of slice must be an array buffer.")));
     
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Slice requires at least one argument."));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Slice requires at least one argument.")));
     
     int32_t begin = exec->argument(0).toInt32(exec);
     if (exec->hadException())
@@ -60,7 +60,7 @@ static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec)
     
     RefPtr<ArrayBuffer> newBuffer = thisObject->impl()->slice(begin, end);
     if (!newBuffer)
-        return throwVMError(exec, createOutOfMemoryError(callee->globalObject()));
+        return throwVMError(exec, createOutOfMemoryError(exec));
     
     Structure* structure = callee->globalObject()->arrayBufferStructure();
     
@@ -70,7 +70,7 @@ static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec)
 }
 
 const ClassInfo JSArrayBufferPrototype::s_info = {
-    "ArrayBufferPrototype", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayBufferPrototype)
+    "ArrayBufferPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayBufferPrototype)
 };
 
 JSArrayBufferPrototype::JSArrayBufferPrototype(VM& vm, Structure* structure)
index da0cde256ca0c999c35aa5caeb123709bd790c94..a3398dbaae9cec062e8792fa093bac80a352d0a3 100644 (file)
@@ -33,7 +33,7 @@
 namespace JSC {
 
 const ClassInfo JSArrayBufferView::s_info = {
-    "ArrayBufferView", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayBufferView)
+    "ArrayBufferView", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayBufferView)
 };
 
 JSArrayBufferView::ConstructionContext::ConstructionContext(
@@ -78,7 +78,7 @@ JSArrayBufferView::ConstructionContext::ConstructionContext(
             return;
     }
     
-    vm.heap.reportExtraMemoryCost(static_cast<size_t>(length) * elementSize);
+    vm.heap.reportExtraMemoryAllocated(static_cast<size_t>(length) * elementSize);
     
     m_structure = structure;
     m_mode = OversizeTypedArray;
@@ -201,7 +201,7 @@ void JSArrayBufferView::getOwnNonIndexPropertyNames(
     JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(object);
     
     // length/byteOffset/byteLength are DontEnum, at least in Firefox.
-    if (mode == IncludeDontEnumProperties) {
+    if (mode.includeDontEnumProperties()) {
         array.add(exec->propertyNames().byteOffset);
         array.add(exec->propertyNames().byteLength);
         array.add(exec->propertyNames().buffer);
index 3feb03b7219314d2b42f831e4ec38bca19729f44..0514452990dd25d197020827aea4e36a3ce4c606 100644 (file)
@@ -93,6 +93,7 @@ inline bool hasArrayBuffer(TypedArrayMode mode)
 class JSArrayBufferView : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot;
     
     static const unsigned fastSizeLimit = 1000;
     
@@ -174,8 +175,6 @@ private:
     static void finalize(JSCell*);
 
 protected:
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | Base::StructureFlags;
-    
     ArrayBuffer* existingBufferInButterfly();
 
     void* m_vector;
index c6220f5f9916cd1767c5f72496b1c1d7abe59e44..0abc9d120fb01bac220232761aeabb09e70a3320 100644 (file)
 
 namespace JSC {
 
-const ClassInfo JSArrayIterator::s_info = { "ArrayIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayIterator) };
+const ClassInfo JSArrayIterator::s_info = { "Array Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayIterator) };
 
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(ExecState*);
-
-void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject* globalObject, ArrayIterationKind kind, JSObject* iteratedObject)
+void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject*, ArrayIterationKind kind, JSObject* iteratedObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
-    m_iterationKind = kind;
-    m_iteratedObject.set(vm, this, iteratedObject);
-    switch (kind) {
-    case ArrayIterateKey:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextKey, DontEnum, 0, ArrayIteratorNextKeyIntrinsic);
-        break;
-    case ArrayIterateValue:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextValue, DontEnum, 0, ArrayIteratorNextValueIntrinsic);
-        break;
-    default:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextGeneric, DontEnum, 0, ArrayIteratorNextGenericIntrinsic);
-        break;
-    }
 
+    putDirect(vm, vm.propertyNames->iteratedObjectPrivateName, iteratedObject);
+    putDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName, jsNumber(0));
+    putDirect(vm, vm.propertyNames->arrayIterationKindPrivateName, jsNumber(kind));
 }
-    
-    
-void JSArrayIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSArrayIterator* thisObject = jsCast<JSArrayIterator*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-        
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_iteratedObject);
 
-}
-
-static EncodedJSValue createIteratorResult(CallFrame* callFrame, ArrayIterationKind kind, size_t index, JSValue result, bool done)
+ArrayIterationKind JSArrayIterator::kind(ExecState* exec) const
 {
-    if (done)
-        return JSValue::encode(callFrame->vm().iterationTerminator.get());
-    
-    switch (kind & ~ArrayIterateSparseTag) {
-    case ArrayIterateKey:
-        return JSValue::encode(jsNumber(index));
-        
-    case ArrayIterateValue:
-        return JSValue::encode(result);
-        
-    case ArrayIterateKeyValue: {
-        MarkedArgumentBuffer args;
-        args.append(jsNumber(index));
-        args.append(result);
-        JSGlobalObject* globalObject = callFrame->callee()->globalObject();
-        return JSValue::encode(constructArray(callFrame, 0, globalObject, args));
-        
-    }
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    return JSValue::encode(JSValue());
+    JSValue kindValue = getDirect(exec->vm(), exec->vm().propertyNames->arrayIterationKindPrivateName);
+    return static_cast<ArrayIterationKind>(kindValue.asInt32());
 }
 
-static inline EncodedJSValue JSC_HOST_CALL arrayIteratorNext(CallFrame* callFrame)
-{
-    JSArrayIterator* iterator = jsDynamicCast<JSArrayIterator*>(callFrame->thisValue());
-    if (!iterator) {
-        ASSERT_NOT_REACHED();
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call ArrayIterator.next() on a non-ArrayIterator object")));
-    }
-    JSObject* iteratedObject = iterator->iteratedObject();
-    size_t index = iterator->nextIndex();
-    ArrayIterationKind kind = iterator->iterationKind();
-    JSValue jsLength = JSValue(iteratedObject).get(callFrame, callFrame->propertyNames().length);
-    if (callFrame->hadException())
-        return JSValue::encode(jsNull());
-    
-    size_t length = jsLength.toUInt32(callFrame);
-    if (callFrame->hadException())
-        return JSValue::encode(jsNull());
-    
-    if (index >= length) {
-        iterator->finish();
-        return createIteratorResult(callFrame, kind, index, jsUndefined(), true);
-    }
-    if (JSValue result = iteratedObject->tryGetIndexQuickly(index)) {
-        iterator->setNextIndex(index + 1);
-        return createIteratorResult(callFrame, kind, index, result, false);
-    }
-    
-    JSValue result = jsUndefined();
-    PropertySlot slot(iteratedObject);
-    if (kind > ArrayIterateSparseTag) {
-        // We assume that the indexed property will be an own property so cache the getOwnProperty
-        // method locally
-        auto getOwnPropertySlotByIndex = iteratedObject->methodTable()->getOwnPropertySlotByIndex;
-        while (index < length) {
-            if (getOwnPropertySlotByIndex(iteratedObject, callFrame, index, slot)) {
-                result = slot.getValue(callFrame, index);
-                break;
-            }
-            if (iteratedObject->getPropertySlot(callFrame, index, slot)) {
-                result = slot.getValue(callFrame, index);
-                break;
-            }
-            index++;
-        }
-    } else if (iteratedObject->getPropertySlot(callFrame, index, slot))
-        result = slot.getValue(callFrame, index);
-    
-    if (index == length)
-        iterator->finish();
-    else
-        iterator->setNextIndex(index + 1);
-    return createIteratorResult(callFrame, kind, index, jsUndefined(), index == length);
-}
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(CallFrame* callFrame)
-{
-    return arrayIteratorNext(callFrame);
-}
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(CallFrame* callFrame)
+JSValue JSArrayIterator::iteratedValue(ExecState* exec) const
 {
-    return arrayIteratorNext(callFrame);
+    return getDirect(exec->vm(), exec->vm().propertyNames->iteratedObjectPrivateName);
 }
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(CallFrame* callFrame)
+
+JSArrayIterator* JSArrayIterator::clone(ExecState* exec)
 {
-    return arrayIteratorNext(callFrame);
+    VM& vm = exec->vm();
+    JSValue iteratedObject = getDirect(vm, vm.propertyNames->iteratedObjectPrivateName);
+    JSValue nextIndex = getDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName);
+
+    auto clone = JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), kind(exec), asObject(iteratedObject));
+    clone->putDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName, nextIndex);
+    return clone;
 }
 
 }
index 2994a67d1a94eb14b5a60993cc2cea0a19f94495..0166bd2e5352ba2159364271ecabbaf80e15363d 100644 (file)
@@ -33,11 +33,7 @@ namespace JSC {
 enum ArrayIterationKind : uint32_t {
     ArrayIterateKey,
     ArrayIterateValue,
-    ArrayIterateKeyValue,
-    ArrayIterateSparseTag = 4,
-    ArrayIterateSparseKey,
-    ArrayIterateSparseValue,
-    ArrayIterateSparseKeyValue
+    ArrayIterateKeyValue
 };
 
 class JSArrayIterator : public JSNonFinalObject {
@@ -59,33 +55,18 @@ public:
         return instance;
     }
 
-    ArrayIterationKind iterationKind() const { return m_iterationKind; }
-    JSObject* iteratedObject() const { return m_iteratedObject.get(); }
-    size_t nextIndex() const { return m_nextIndex; }
-    void setNextIndex(size_t nextIndex) { m_nextIndex = nextIndex; }
-    void finish() { m_nextIndex = std::numeric_limits<uint32_t>::max(); }
-    
-    using JSNonFinalObject::arrayStorageOrNull;
-    static ptrdiff_t offsetOfIterationKind() { return OBJECT_OFFSETOF(JSArrayIterator, m_iterationKind); }
-    static ptrdiff_t offsetOfIteratedObject() { return OBJECT_OFFSETOF(JSArrayIterator, m_iteratedObject); }
-    static ptrdiff_t offsetOfNextIndex() { return OBJECT_OFFSETOF(JSArrayIterator, m_nextIndex); }
+    ArrayIterationKind kind(ExecState*) const;
+    JSValue iteratedValue(ExecState*) const;
+    JSArrayIterator* clone(ExecState*);
 
+    using JSNonFinalObject::arrayStorageOrNull;
 private:
-
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
-
     JSArrayIterator(VM& vm, Structure* structure)
         : Base(vm, structure)
-        , m_nextIndex(0)
     {
     }
 
     void finishCreation(VM&, JSGlobalObject*, ArrayIterationKind, JSObject* iteratedObject);
-    static void visitChildren(JSCell*, SlotVisitor&);
-    
-    ArrayIterationKind m_iterationKind;
-    WriteBarrier<JSObject> m_iteratedObject;
-    uint32_t m_nextIndex;
 };
 
 }
index ef79c422d5bfe1a5e84cbf56f07c25b734a092ee..8c5cc2ed390482eac2e775a4f0c2d2d5c4c99e61 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace JSC {
 
-const ClassInfo JSBoundFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSBoundFunction) };
+const ClassInfo JSBoundFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(JSBoundFunction) };
 
 EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState* exec)
 {
@@ -86,11 +86,6 @@ JSBoundFunction* JSBoundFunction::create(VM& vm, JSGlobalObject* globalObject, J
     return function;
 }
 
-void JSBoundFunction::destroy(JSCell* cell)
-{
-    static_cast<JSBoundFunction*>(cell)->JSBoundFunction::~JSBoundFunction();
-}
-
 bool JSBoundFunction::customHasInstance(JSObject* object, ExecState* exec, JSValue value)
 {
     return jsCast<JSBoundFunction*>(object)->m_targetFunction->hasInstance(exec, value);
@@ -117,8 +112,6 @@ void JSBoundFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSBoundFunction* thisObject = jsCast<JSBoundFunction*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
 
     visitor.append(&thisObject->m_targetFunction);
index 7852f78ce39059b5643e49e0f9df1cd7edc8e0b8..af2a6323d5371e20560c0f2556cc5b87f62568e9 100644 (file)
@@ -36,11 +36,10 @@ EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState*);
 class JSBoundFunction : public JSFunction {
 public:
     typedef JSFunction Base;
+    const static unsigned StructureFlags = OverridesHasInstance | Base::StructureFlags;
 
     static JSBoundFunction* create(VM&, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&);
     
-    static void destroy(JSCell*);
-
     static bool customHasInstance(JSObject*, ExecState*, JSValue);
 
     JSObject* targetFunction() { return m_targetFunction.get(); }
@@ -56,8 +55,6 @@ public:
     DECLARE_INFO;
 
 protected:
-    const static unsigned StructureFlags = OverridesHasInstance | OverridesVisitChildren | Base::StructureFlags;
-
     static void visitChildren(JSCell*, SlotVisitor&);
 
 private:
index 9cf7028ccfde8538f239f0f62de953a10583f17a..e9fabb53e1c2055d7540a9e59f7217c302196df3 100644 (file)
@@ -51,5 +51,6 @@
 #include "Operations.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
+#include "WeakGCMapInlines.h"
 
 #endif // JSCInlines_h
index 0ca8103228c8ac40d5aafb5b5fa70f0bbff276d6..9e0aab1774de17a03ca6de12c9e98f9d7236360b 100644 (file)
@@ -99,8 +99,10 @@ JSValue JSValue::toThisSlowCase(ExecState* exec, ECMAMode ecmaMode) const
 JSObject* JSValue::synthesizePrototype(ExecState* exec) const
 {
     if (isCell()) {
-        ASSERT(isString());
-        return exec->lexicalGlobalObject()->stringPrototype();
+        if (isString())
+            return exec->lexicalGlobalObject()->stringPrototype();
+        ASSERT(isSymbol());
+        return exec->lexicalGlobalObject()->symbolPrototype();
     }
 
     if (isNumber())
@@ -119,9 +121,8 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
 {
     VM& vm = exec->vm();
 
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex) {
-        putToPrimitiveByIndex(exec, index, value, slot.isStrictMode());
+    if (Optional<uint32_t> index = parseIndex(propertyName)) {
+        putToPrimitiveByIndex(exec, index.value(), value, slot.isStrictMode());
         return;
     }
 
@@ -141,8 +142,7 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
 
     for (; ; obj = asObject(prototype)) {
         unsigned attributes;
-        JSCell* specificValue;
-        PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes, specificValue);
+        PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes);
         if (offset != invalidOffset) {
             if (attributes & ReadOnly) {
                 if (slot.isStrictMode())
@@ -197,6 +197,13 @@ void JSValue::dump(PrintStream& out) const
 }
 
 void JSValue::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    dumpInContextAssumingStructure(
+        out, context, (!!*this && isCell()) ? asCell()->structure() : nullptr);
+}
+
+void JSValue::dumpInContextAssumingStructure(
+    PrintStream& out, DumpContext* context, Structure* structure) const
 {
     if (!*this)
         out.print("<JSValue()>");
@@ -214,7 +221,7 @@ void JSValue::dumpInContext(PrintStream& out, DumpContext* context) const
         out.printf("Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
 #endif
     } else if (isCell()) {
-        if (asCell()->inherits(JSString::info())) {
+        if (structure->classInfo()->isSubClassOf(JSString::info())) {
             JSString* string = jsCast<JSString*>(asCell());
             out.print("String");
             if (string->isRope())
@@ -225,16 +232,16 @@ void JSValue::dumpInContext(PrintStream& out, DumpContext* context) const
                     out.print(" (atomic)");
                 if (impl->isAtomic())
                     out.print(" (identifier)");
-                if (impl->isEmptyUnique())
-                    out.print(" (unique)");
+                if (impl->isSymbol())
+                    out.print(" (symbol)");
             } else
                 out.print(" (unresolved)");
             out.print(": ", impl);
-        } else if (asCell()->inherits(Structure::info()))
+        } else if (structure->classInfo()->isSubClassOf(Structure::info()))
             out.print("Structure: ", inContext(*jsCast<Structure*>(asCell()), context));
         else {
             out.print("Cell: ", RawPointer(asCell()));
-            out.print(" (", inContext(*asCell()->structure(), context), ")");
+            out.print(" (", inContext(*structure, context), ")");
         }
 #if USE(JSVALUE64)
         out.print(", ID: ", asCell()->structureID());
@@ -346,8 +353,12 @@ JSString* JSValue::toStringSlowCase(ExecState* exec) const
 {
     VM& vm = exec->vm();
     ASSERT(!isString());
-    if (isInt32())
-        return jsString(&vm, vm.numericStrings.add(asInt32()));
+    if (isInt32()) {
+        auto integer = asInt32();
+        if (static_cast<unsigned>(integer) <= 9)
+            return vm.smallStrings.singleCharacterString(integer + '0');
+        return jsNontrivialString(&vm, vm.numericStrings.add(integer));
+    }
     if (isDouble())
         return jsString(&vm, vm.numericStrings.add(asDouble()));
     if (isTrue())
@@ -358,6 +369,10 @@ JSString* JSValue::toStringSlowCase(ExecState* exec) const
         return vm.smallStrings.nullString();
     if (isUndefined())
         return vm.smallStrings.undefinedString();
+    if (isSymbol()) {
+        throwTypeError(exec);
+        return jsEmptyString(exec);
+    }
 
     ASSERT(isCell());
     JSValue value = asCell()->toPrimitive(exec, PreferString);
@@ -369,7 +384,20 @@ JSString* JSValue::toStringSlowCase(ExecState* exec) const
 
 String JSValue::toWTFStringSlowCase(ExecState* exec) const
 {
-    return inlineJSValueNotStringtoString(*this, exec);
+    VM& vm = exec->vm();
+    if (isInt32())
+        return vm.numericStrings.add(asInt32());
+    if (isDouble())
+        return vm.numericStrings.add(asDouble());
+    if (isTrue())
+        return vm.propertyNames->trueKeyword.string();
+    if (isFalse())
+        return vm.propertyNames->falseKeyword.string();
+    if (isNull())
+        return vm.propertyNames->nullKeyword.string();
+    if (isUndefined())
+        return vm.propertyNames->undefinedKeyword.string();
+    return toString(exec)->value(exec);
 }
 
 } // namespace JSC
index 514c4d931c6140881f397a9ff6cde76af7d5e07e..039c14eb7a12aae6565dba7fa4fbdcbfaff31993 100644 (file)
@@ -32,6 +32,7 @@
 #include <wtf/HashMap.h>
 #include <wtf/HashTraits.h>
 #include <wtf/MathExtras.h>
+#include <wtf/MediaTime.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/TriState.h>
 
@@ -45,9 +46,11 @@ class VM;
 class JSGlobalObject;
 class JSObject;
 class JSString;
+class Identifier;
 class PropertyName;
 class PropertySlot;
 class PutPropertySlot;
+class Structure;
 #if ENABLE(DFG_JIT)
 namespace DFG {
 class JITCompiler;
@@ -122,8 +125,15 @@ inline uint32_t toUInt32(double number)
 int64_t tryConvertToInt52(double);
 bool isInt52(double);
 
+enum class SourceCodeRepresentation {
+    Other,
+    Integer,
+    Double
+};
+
 class JSValue {
     friend struct EncodedJSValueHashTraits;
+    friend struct EncodedJSValueWithRepresentationHashTraits;
     friend class AssemblyHelpers;
     friend class JIT;
     friend class JITSlowPathCall;
@@ -185,8 +195,7 @@ public:
     explicit JSValue(long long);
     explicit JSValue(unsigned long long);
 
-    typedef void* (JSValue::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const;
+    explicit operator bool() const;
     bool operator==(const JSValue& other) const;
     bool operator!=(const JSValue& other) const;
 
@@ -215,6 +224,7 @@ public:
     bool isMachineInt() const;
     bool isNumber() const;
     bool isString() const;
+    bool isSymbol() const;
     bool isPrimitive() const;
     bool isGetterSetter() const;
     bool isCustomGetterSetter() const;
@@ -240,19 +250,19 @@ public:
     // been set in the ExecState already.
     double toNumber(ExecState*) const;
     JSString* toString(ExecState*) const;
+    Identifier toPropertyKey(ExecState*) const;
     WTF::String toWTFString(ExecState*) const;
-    WTF::String toWTFStringInline(ExecState*) const;
     JSObject* toObject(ExecState*) const;
     JSObject* toObject(ExecState*, JSGlobalObject*) const;
 
     // Integer conversions.
     JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
-    double toIntegerPreserveNaN(ExecState*) const;
+    JS_EXPORT_PRIVATE double toIntegerPreserveNaN(ExecState*) const;
     int32_t toInt32(ExecState*) const;
     uint32_t toUInt32(ExecState*) const;
 
-    // Floating point conversions (this is a convenience method for webcore;
-    // signle precision float is not a representation used in JS or JSC).
+    // Floating point conversions (this is a convenience function for WebCore;
+    // single precision float is not a representation used in JS or JSC).
     float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
 
     // Object operations, with the toObject operation included.
@@ -260,9 +270,12 @@ public:
     JSValue get(ExecState*, PropertyName, PropertySlot&) const;
     JSValue get(ExecState*, unsigned propertyName) const;
     JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
+
+    bool getPropertySlot(ExecState*, PropertyName, PropertySlot&) const;
+
     void put(ExecState*, PropertyName, JSValue, PutPropertySlot&);
-    void putToPrimitive(ExecState*, PropertyName, JSValue, PutPropertySlot&);
-    void putToPrimitiveByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+    JS_EXPORT_PRIVATE void putToPrimitive(ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    JS_EXPORT_PRIVATE void putToPrimitiveByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
 
     JSValue toThis(ExecState*, ECMAMode) const;
@@ -283,9 +296,11 @@ public:
 
     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
+    void dumpInContextAssumingStructure(PrintStream&, DumpContext*, Structure*) const;
     void dumpForBacktrace(PrintStream&) const;
 
     JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
+    bool requireObjectCoercible(ExecState*) const;
 
     // Constants used for Int52. Int52 isn't part of JSValue right now, but JSValues may be
     // converted to Int52s and back again.
@@ -440,7 +455,26 @@ struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
 };
 #endif
 
-typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
+typedef std::pair<EncodedJSValue, SourceCodeRepresentation> EncodedJSValueWithRepresentation;
+
+struct EncodedJSValueWithRepresentationHashTraits : HashTraits<EncodedJSValueWithRepresentation> {
+    static const bool emptyValueIsZero = false;
+    static EncodedJSValueWithRepresentation emptyValue() { return std::make_pair(JSValue::encode(JSValue()), SourceCodeRepresentation::Other); }
+    static void constructDeletedValue(EncodedJSValueWithRepresentation& slot) { slot = std::make_pair(JSValue::encode(JSValue(JSValue::HashTableDeletedValue)), SourceCodeRepresentation::Other); }
+    static bool isDeletedValue(EncodedJSValueWithRepresentation value) { return value == std::make_pair(JSValue::encode(JSValue(JSValue::HashTableDeletedValue)), SourceCodeRepresentation::Other); }
+};
+
+struct EncodedJSValueWithRepresentationHash {
+    static unsigned hash(const EncodedJSValueWithRepresentation& value)
+    {
+        return WTF::pairIntHash(EncodedJSValueHash::hash(value.first), IntHash<SourceCodeRepresentation>::hash(value.second));
+    }
+    static bool equal(const EncodedJSValueWithRepresentation& a, const EncodedJSValueWithRepresentation& b)
+    {
+        return a == b;
+    }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
 
 // Stand-alone helper functions.
 inline JSValue jsNull()
@@ -470,6 +504,11 @@ ALWAYS_INLINE JSValue jsNumber(double d)
     return JSValue(d);
 }
 
+ALWAYS_INLINE JSValue jsNumber(MediaTime t)
+{
+    return jsNumber(t.toDouble());
+}
+
 ALWAYS_INLINE JSValue jsNumber(char i)
 {
     return JSValue(i);
index d0245c13ea709461afbfe86a0d69e6eebc1a2fa7..71842c21cbd9e3f112027e3db75a2982b75d5333 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef JSValueInlines_h
 #define JSValueInlines_h
 
+#include "ExceptionHelpers.h"
+#include "Identifier.h"
 #include "InternalFunction.h"
 #include "JSCJSValue.h"
 #include "JSCellInlines.h"
@@ -211,10 +213,10 @@ inline JSValue::JSValue(const JSCell* ptr)
     u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
 }
 
-inline JSValue::operator UnspecifiedBoolType*() const
+inline JSValue::operator bool() const
 {
     ASSERT(tag() != DeletedValueTag);
-    return tag() != EmptyValueTag ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
+    return tag() != EmptyValueTag;
 }
 
 inline bool JSValue::operator==(const JSValue& other) const
@@ -327,7 +329,7 @@ inline bool JSValue::isNumber() const
 
 inline bool JSValue::isBoolean() const
 {
-    return isTrue() || isFalse();
+    return tag() == BooleanTag;
 }
 
 inline bool JSValue::asBoolean() const
@@ -360,9 +362,9 @@ inline JSValue::JSValue(const JSCell* ptr)
     u.asInt64 = reinterpret_cast<uintptr_t>(const_cast<JSCell*>(ptr));
 }
 
-inline JSValue::operator UnspecifiedBoolType*() const
+inline JSValue::operator bool() const
 {
-    return u.asInt64 ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
+    return u.asInt64;
 }
 
 inline bool JSValue::operator==(const JSValue& other) const
@@ -549,9 +551,14 @@ inline bool JSValue::isString() const
     return isCell() && asCell()->isString();
 }
 
+inline bool JSValue::isSymbol() const
+{
+    return isCell() && asCell()->isSymbol();
+}
+
 inline bool JSValue::isPrimitive() const
 {
-    return !isCell() || asCell()->isString();
+    return !isCell() || asCell()->isString() || asCell()->isSymbol();
 }
 
 inline bool JSValue::isGetterSetter() const
@@ -604,6 +611,17 @@ ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
     return false;
 }
 
+ALWAYS_INLINE Identifier JSValue::toPropertyKey(ExecState* exec) const
+{
+    if (isString())
+        return asString(*this)->toIdentifier(exec);
+
+    JSValue primitive = toPrimitive(exec, PreferString);
+    if (primitive.isSymbol())
+        return Identifier::fromUid(asSymbol(primitive)->privateName());
+    return primitive.toString(exec)->toIdentifier(exec);
+}
+
 inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
 {
     return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
@@ -681,20 +699,24 @@ ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, PropertyName propertyName) c
 }
 
 ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
+{
+    return getPropertySlot(exec, propertyName, slot) ? 
+        slot.getValue(exec, propertyName) : jsUndefined();
+}
+
+ALWAYS_INLINE bool JSValue::getPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
 {
     // If this is a primitive, we'll need to synthesize the prototype -
     // and if it's a string there are special properties to check first.
     JSObject* object;
     if (UNLIKELY(!isObject())) {
-        if (isCell() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
-            return slot.getValue(exec, propertyName);
+        if (isString() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
+            return true;
         object = synthesizePrototype(exec);
     } else
         object = asObject(asCell());
     
-    if (object->getPropertySlot(exec, propertyName, slot))
-        return slot.getValue(exec, propertyName);
-    return jsUndefined();
+    return object->getPropertySlot(exec, propertyName, slot);
 }
 
 ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
@@ -709,7 +731,7 @@ ALWAYS_INLINE JSValue JSValue::get(ExecState* exec, unsigned propertyName, Prope
     // and if it's a string there are special properties to check first.
     JSObject* object;
     if (UNLIKELY(!isObject())) {
-        if (isCell() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
+        if (isString() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
             return slot.getValue(exec, propertyName);
         object = synthesizePrototype(exec);
     } else
@@ -802,6 +824,14 @@ ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSV
             continue;
         }
 
+        bool sym1 = v1.isSymbol();
+        bool sym2 = v2.isSymbol();
+        if (sym1 || sym2) {
+            if (sym1 && sym2)
+                return asSymbol(v1)->privateName() == asSymbol(v2)->privateName();
+            return false;
+        }
+
         if (s1 || s2) {
             double d1 = v1.toNumber(exec);
             double d2 = v2.toNumber(exec);
@@ -827,6 +857,8 @@ ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v
 
     if (v1.asCell()->isString() && v2.asCell()->isString())
         return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl());
+    if (v1.asCell()->isSymbol() && v2.asCell()->isSymbol())
+        return asSymbol(v1)->privateName() == asSymbol(v2)->privateName();
 
     return v1 == v2;
 }
@@ -885,6 +917,14 @@ inline TriState JSValue::pureToBoolean() const
     return isTrue() ? TrueTriState : FalseTriState;
 }
 
+ALWAYS_INLINE bool JSValue::requireObjectCoercible(ExecState* exec) const
+{
+    if (!isUndefinedOrNull())
+        return true;
+    exec->vm().throwException(exec, createNotAnObjectError(exec, *this));
+    return false;
+}
+
 } // namespace JSC
 
 #endif // JSValueInlines_h
diff --git a/runtime/JSCallee.cpp b/runtime/JSCallee.cpp
new file mode 100644 (file)
index 0000000..d303296
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCallee.h"
+
+#include "GetterSetter.h"
+#include "JSCJSValueInlines.h"
+#include "JSCell.h"
+#include "JSCellInlines.h"
+#include "JSGlobalObject.h"
+#include "SlotVisitorInlines.h"
+#include "StackVisitor.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSCallee::s_info = { "Callee", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallee) };
+
+JSCallee::JSCallee(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    : Base(vm, structure)
+    , m_scope(vm, this, globalObject)
+{
+}
+
+JSCallee::JSCallee(VM& vm, JSScope* scope, Structure* structure)
+    : Base(vm, structure)
+{
+    setScope(vm, scope);
+}
+
+void JSCallee::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+}
+
+void JSCallee::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    JSCallee* thisObject = jsCast<JSCallee*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.append(&thisObject->m_scope);
+}
+
+} // namespace JSC
diff --git a/runtime/JSCallee.h b/runtime/JSCallee.h
new file mode 100644 (file)
index 0000000..1545edd
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSCallee_h
+#define JSCallee_h
+
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "JSScope.h"
+
+namespace JSC {
+
+class JSGlobalObject;
+class LLIntOffsetsExtractor;
+
+
+class JSCallee : public JSNonFinalObject {
+    friend class JIT;
+#if ENABLE(DFG_JIT)
+    friend class DFG::SpeculativeJIT;
+    friend class DFG::JITCompiler;
+#endif
+    friend class VM;
+
+public:
+    typedef JSNonFinalObject Base;
+    const static unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
+
+    static JSCallee* create(VM& vm, JSGlobalObject* globalObject, JSScope* scope)
+    {
+        JSCallee* callee = new (NotNull, allocateCell<JSCallee>(vm.heap)) JSCallee(vm, scope, globalObject->calleeStructure());
+        callee->finishCreation(vm);
+        return callee;
+    }
+    
+    JSScope* scope()
+    {
+        return m_scope.get();
+    }
+
+    // This method may be called for host functions, in which case it
+    // will return an arbitrary value. This should only be used for
+    // optimized paths in which the return value does not matter for
+    // host functions, and checking whether the function is a host
+    // function is deemed too expensive.
+    JSScope* scopeUnchecked()
+    {
+        return m_scope.get();
+    }
+
+    void setScope(VM& vm, JSScope* scope)
+    {
+        m_scope.set(vm, this, scope);
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    {
+        ASSERT(globalObject);
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSCalleeType, StructureFlags), info());
+    }
+
+    static inline ptrdiff_t offsetOfScopeChain()
+    {
+        return OBJECT_OFFSETOF(JSCallee, m_scope);
+    }
+
+protected:
+    JS_EXPORT_PRIVATE JSCallee(VM&, JSGlobalObject*, Structure*);
+    JSCallee(VM&, JSScope*, Structure*);
+
+    void finishCreation(VM&);
+    using Base::finishCreation;
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    WriteBarrier<JSScope> m_scope;
+};
+
+} // namespace JSC
+
+#endif // JSCallee_h
diff --git a/runtime/JSCatchScope.cpp b/runtime/JSCatchScope.cpp
new file mode 100644 (file)
index 0000000..15e49dd
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSCatchScope.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSCatchScope::s_info = { "CatchScope", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCatchScope) };
+
+} // namespace JSC
+
diff --git a/runtime/JSCatchScope.h b/runtime/JSCatchScope.h
new file mode 100644 (file)
index 0000000..0eeab90
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSCatchScope_h
+#define JSCatchScope_h
+
+#include "JSNameScope.h"
+
+namespace JSC {
+
+class JSCatchScope : public JSNameScope {
+public:
+    typedef JSNameScope Base;
+
+private:
+    friend class JSNameScope;
+    
+    JSCatchScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, globalObject->catchScopeStructure(), next, symbolTable)
+    {
+    }
+    
+public:
+    static JSCatchScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
+    {
+        return Base::create<JSCatchScope>(vm, globalObject, currentScope, symbolTable, value);
+    }
+    
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+    {
+        return Structure::create(vm, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), info());
+    }
+    
+    DECLARE_INFO;
+};
+
+} // namespace JSC
+
+#endif // JSCatchScope_h
+
index 84349fe259fc694a458be2308aec7072d8bd8e74..2c403c813fb38568b0e60ce78989ddea4c953c12 100644 (file)
@@ -96,7 +96,7 @@ ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
 
 void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot)
 {
-    if (cell->isString()) {
+    if (cell->isString() || cell->isSymbol()) {
         JSValue(cell).putToPrimitive(exec, identifier, value, slot);
         return;
     }
@@ -106,7 +106,7 @@ void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue
 
 void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
 {
-    if (cell->isString()) {
+    if (cell->isString() || cell->isSymbol()) {
         PutPropertySlot slot(cell, shouldThrow);
         JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
         return;
@@ -138,6 +138,8 @@ JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredTyp
 {
     if (isString())
         return static_cast<const JSString*>(this)->toPrimitive(exec, preferredType);
+    if (isSymbol())
+        return static_cast<const Symbol*>(this)->toPrimitive(exec, preferredType);
     return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
 }
 
@@ -145,6 +147,8 @@ bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
 {
     if (isString())
         return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
+    if (isSymbol())
+        return static_cast<const Symbol*>(this)->getPrimitiveNumber(exec, number, value);
     return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
 }
 
@@ -152,6 +156,8 @@ double JSCell::toNumber(ExecState* exec) const
 { 
     if (isString())
         return static_cast<const JSString*>(this)->toNumber(exec);
+    if (isSymbol())
+        return static_cast<const Symbol*>(this)->toNumber(exec);
     return static_cast<const JSObject*>(this)->toNumber(exec);
 }
 
@@ -159,6 +165,8 @@ JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
 {
     if (isString())
         return static_cast<const JSString*>(this)->toObject(exec, globalObject);
+    if (isSymbol())
+        return static_cast<const Symbol*>(this)->toObject(exec, globalObject);
     ASSERT(isObject());
     return jsCast<JSObject*>(const_cast<JSCell*>(this));
 }
@@ -236,4 +244,20 @@ PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
     return 0;
 }
 
+uint32_t JSCell::getEnumerableLength(ExecState*, JSObject*)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+    return 0;
+}
+
+void JSCell::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void JSCell::getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 } // namespace JSC
index abf45579ddfdbfce3c9d7f379836349824fedfb7..6d648ad262944ed7b4670e23df79c8e63b2985b8 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "CallData.h"
 #include "ConstructData.h"
+#include "EnumerationMode.h"
 #include "Heap.h"
 #include "IndexingType.h"
 #include "JSLock.h"
@@ -38,6 +39,7 @@ namespace JSC {
 
 class CopyVisitor;
 class ExecState;
+class Identifier;
 class JSArrayBufferView;
 class JSDestructibleObject;
 class JSGlobalObject;
@@ -46,11 +48,6 @@ class PropertyDescriptor;
 class PropertyNameArray;
 class Structure;
 
-enum EnumerationMode {
-    ExcludeDontEnumProperties,
-    IncludeDontEnumProperties
-};
-
 template<typename T> void* allocateCell(Heap&);
 template<typename T> void* allocateCell(Heap&, size_t);
 
@@ -76,7 +73,8 @@ public:
     static const unsigned StructureFlags = 0;
 
     static const bool needsDestruction = false;
-    static const bool hasImmortalStructure = false;
+
+    static JSCell* seenMultipleCalleeObjects() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(1)); }
 
     enum CreatingEarlyCellTag { CreatingEarlyCell };
     JSCell(CreatingEarlyCellTag);
@@ -88,6 +86,7 @@ protected:
 public:
     // Querying the type.
     bool isString() const;
+    bool isSymbol() const;
     bool isObject() const;
     bool isGetterSetter() const;
     bool isCustomGetterSetter() const;
@@ -107,12 +106,20 @@ public:
 
     const char* className() const;
 
+    VM* vm() const;
+
     // Extracting the value.
     JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const;
     JS_EXPORT_PRIVATE String getString(ExecState*) const; // null string if not a string
     JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object
     const JSObject* getObject() const; // NULL if not an object
         
+    // Returns information about how to call/construct this cell as a function/constructor. May tell
+    // you that the cell is not callable or constructor (default is that it's not either). If it
+    // says that the function is callable, and the TypeOfShouldCallGetCallData type flag is set, and
+    // this is an object, then typeof will return "function" instead of "object". These methods
+    // cannot change their minds and must be thread-safe. They are sometimes called from compiler
+    // threads.
     JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
     JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
 
@@ -145,12 +152,17 @@ public:
     bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
 
     static bool canUseFastGetOwnProperty(const Structure&);
-    JSValue fastGetOwnProperty(VM&, Structure&, const String&);
+    JSValue fastGetOwnProperty(VM&, Structure&, PropertyName);
 
     enum GCData : uint8_t {
-        Marked = 0,
-        NotMarked = 1,
-        MarkedAndRemembered = 2,
+        Marked = 0, // The object has survived a GC and is in the old gen.
+        NotMarked = 1, // The object is new and in the eden gen.
+        MarkedAndRemembered = 2, // The object is in the GC's remembered set.
+
+        // The object being in the GC's remembered set implies that it is also
+        // Marked. This is because objects are only added to the remembered sets
+        // by write barriers, and write barriers are only interested in old gen
+        // objects that point to potential eden gen objects.
     };
 
     void setMarked() { m_gcData = Marked; }
@@ -209,6 +221,11 @@ protected:
     static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+
+    static uint32_t getEnumerableLength(ExecState*, JSObject*);
+    static NO_RETURN_DUE_TO_CRASH void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static NO_RETURN_DUE_TO_CRASH void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+
     static String className(const JSObject*);
     JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue);
     static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
@@ -230,14 +247,14 @@ private:
 template<typename To, typename From>
 inline To jsCast(From* from)
 {
-    ASSERT(!from || from->JSCell::inherits(std::remove_pointer<To>::type::info()));
+    ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(std::remove_pointer<To>::type::info()));
     return static_cast<To>(from);
 }
     
 template<typename To>
 inline To jsCast(JSValue from)
 {
-    ASSERT(from.isCell() && from.asCell()->JSCell::inherits(std::remove_pointer<To>::type::info()));
+    ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(std::remove_pointer<To>::type::info()));
     return static_cast<To>(from.asCell());
 }
 
index ed111c655e59fe079515545c95e0b0066504fd5e..c4019ff4e4d23233efbe62d53e42c2b7c0de9721 100644 (file)
 #include "DeferGC.h"
 #include "Handle.h"
 #include "JSCell.h"
+#include "JSDestructibleObject.h"
 #include "JSObject.h"
 #include "JSString.h"
+#include "MarkedBlock.h"
 #include "Structure.h"
+#include "Symbol.h"
 #include <wtf/CompilationThread.h>
 
 namespace JSC {
@@ -110,18 +113,24 @@ inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.appendUnbarrieredPointer(&structure);
 }
 
+inline VM* JSCell::vm() const
+{
+    return MarkedBlock::blockFor(this)->vm();
+}
+
+inline VM& ExecState::vm() const
+{
+    ASSERT(callee());
+    ASSERT(callee()->vm());
+    return *calleeAsValue().asCell()->vm();
+}
+
 template<typename T>
 void* allocateCell(Heap& heap, size_t size)
 {
     ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
     ASSERT(size >= sizeof(T));
-    JSCell* result = 0;
-    if (T::needsDestruction && T::hasImmortalStructure)
-        result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
-    else if (T::needsDestruction)
-        result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
-    else 
-        result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
+    JSCell* result = static_cast<JSCell*>(heap.allocateObjectOfType<T>(size));
 #if ENABLE(GC_VALIDATION)
     ASSERT(!heap.vm()->isInitializingObject());
     heap.vm()->setInitializingObjectClass(T::info());
@@ -151,6 +160,11 @@ inline bool JSCell::isString() const
     return m_type == StringType;
 }
 
+inline bool JSCell::isSymbol() const
+{
+    return m_type == SymbolType;
+}
+
 inline bool JSCell::isGetterSetter() const
 {
     return m_type == GetterSetterType;
@@ -173,7 +187,6 @@ inline bool JSCell::isAPIValueWrapper() const
 
 inline void JSCell::setStructure(VM& vm, Structure* structure)
 {
-    ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
     ASSERT(structure->classInfo() == this->structure()->classInfo());
     ASSERT(!this->structure()
         || this->structure()->transitionWatchpointSetHasBeenInvalidated()
@@ -209,16 +222,10 @@ inline bool JSCell::inherits(const ClassInfo* info) const
     return classInfo()->isSubClassOf(info);
 }
 
-// Fast call to get a property where we may not yet have converted the string to an
-// identifier. The first time we perform a property access with a given string, try
-// performing the property map lookup without forming an identifier. We detect this
-// case by checking whether the hash has yet been set for this string.
-ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(VM& vm, Structure& structure, const String& name)
+ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(VM& vm, Structure& structure, PropertyName name)
 {
     ASSERT(canUseFastGetOwnProperty(structure));
-    PropertyOffset offset = name.impl()->hasHash()
-        ? structure.get(vm, Identifier(&vm, name))
-        : structure.get(vm, name);
+    PropertyOffset offset = structure.get(vm, name);
     if (offset != invalidOffset)
         return asObject(this)->locationForOffset(offset)->get();
     return JSValue();
@@ -231,17 +238,27 @@ inline bool JSCell::canUseFastGetOwnProperty(const Structure& structure)
         && !structure.typeInfo().overridesGetOwnPropertySlot();
 }
 
+inline const ClassInfo* JSCell::classInfo() const
+{
+    MarkedBlock* block = MarkedBlock::blockFor(this);
+    if (block->needsDestruction() && !(inlineTypeFlags() & StructureIsImmortal))
+        return static_cast<const JSDestructibleObject*>(this)->classInfo();
+    return structure(*block->vm())->classInfo();
+}
+
 inline bool JSCell::toBoolean(ExecState* exec) const
 {
-    if (isString()) 
+    if (isString())
         return static_cast<const JSString*>(this)->toBoolean();
     return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
 }
 
 inline TriState JSCell::pureToBoolean() const
 {
-    if (isString()) 
+    if (isString())
         return static_cast<const JSString*>(this)->toBoolean() ? TrueTriState : FalseTriState;
+    if (isSymbol())
+        return TrueTriState;
     return MixedTriState;
 }
 
index 56712f2241c3c7162c2b475863b933f8c3b1ee2d..7d04abf5844fd33d33ff37da135ff07aa4c6467d 100644 (file)
@@ -31,6 +31,6 @@
 
 namespace JSC {
 
-const ClassInfo JSConsole::s_info = { "Console", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSConsole) };
+const ClassInfo JSConsole::s_info = { "Console", &Base::s_info, 0, CREATE_METHOD_TABLE(JSConsole) };
 
 }
index d2e231a453a5ba75135149ee3bd88d3ac711f04c..513d4c6b3bd5cbf0084605e52c0ef5b3a41474d3 100644 (file)
@@ -34,7 +34,7 @@
 namespace JSC {
 
 const ClassInfo JSDataView::s_info = {
-    "DataView", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSDataView)};
+    "DataView", &Base::s_info, 0, CREATE_METHOD_TABLE(JSDataView)};
 
 JSDataView::JSDataView(VM& vm, ConstructionContext& context, ArrayBuffer* buffer)
     : Base(vm, context)
@@ -47,10 +47,13 @@ JSDataView* JSDataView::create(
     unsigned byteOffset, unsigned byteLength)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!ArrayBufferView::verifySubRange<uint8_t>(buffer, byteOffset, byteLength)) {
-        throwVMError(
-            exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
-        return 0;
+    if (!ArrayBufferView::verifySubRangeLength(buffer, byteOffset, byteLength, sizeof(uint8_t))) {
+        throwVMError(exec, createRangeError(exec, ASCIILiteral("Length out of range of buffer")));
+        return nullptr;
+    }
+    if (!ArrayBufferView::verifyByteOffsetAlignment(byteOffset, sizeof(uint8_t))) {
+        exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Byte offset is not aligned")));
+        return nullptr;
     }
     VM& vm = exec->vm();
     ConstructionContext context(
index 92900e6106d1ac87bc80519cba849ddc47b34f04..4318153ceb7157fd0929f4551524ad6810b44300 100644 (file)
 
 namespace JSC {
 
-const ClassInfo JSDataViewPrototype::s_info = {
-    "DataViewPrototype", &Base::s_info, 0, ExecState::dataViewTable,
-    CREATE_METHOD_TABLE(JSDataViewPrototype)
-};
-
 /* Source for JSDataViewPrototype.lut.h
 @begin dataViewTable
   getInt8               dataViewProtoFuncGetInt8             DontEnum|Function       0
@@ -62,6 +57,34 @@ const ClassInfo JSDataViewPrototype::s_info = {
 @end
 */
 
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt8(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt16(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint8(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint16(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat64(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt8(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt16(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint8(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint16(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat32(ExecState*);
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat64(ExecState*);
+
+}
+
+#include "JSDataViewPrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo JSDataViewPrototype::s_info = {
+    "DataViewPrototype", &Base::s_info, &dataViewTable,
+    CREATE_METHOD_TABLE(JSDataViewPrototype)
+};
+
 JSDataViewPrototype::JSDataViewPrototype(VM& vm, Structure* structure)
     : Base(vm, structure)
 {
@@ -87,19 +110,19 @@ bool JSDataViewPrototype::getOwnPropertySlot(
     JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     return getStaticFunctionSlot<JSObject>(
-        exec, ExecState::dataViewTable(exec->vm()), jsCast<JSDataViewPrototype*>(object),
+        exec, dataViewTable, jsCast<JSDataViewPrototype*>(object),
         propertyName, slot);
 }
 
 template<typename Adaptor>
-EncodedJSValue getData(ExecState* exec)
+EncodedJSValue ATTR_USED getData(ExecState* exec)
 {
     JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue());
     if (!dataView)
-        return throwVMError(exec, createTypeError(exec, "Receiver of DataView method must be a DataView"));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView")));
     
     if (!exec->argumentCount())
-        return throwVMError(exec, createTypeError(exec, "Need at least one argument (the byteOffset)"));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Need at least one argument (the byteOffset)")));
     
     unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
     if (exec->hadException())
@@ -115,13 +138,13 @@ EncodedJSValue getData(ExecState* exec)
     
     unsigned byteLength = dataView->length();
     if (elementSize > byteLength || byteOffset > byteLength - elementSize)
-        return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
+        return throwVMError(exec, createRangeError(exec, ASCIILiteral("Out of bounds access")));
 
     const unsigned dataSize = sizeof(typename Adaptor::Type);
     union {
         typename Adaptor::Type value;
         uint8_t rawBytes[dataSize];
-    } u;
+    } u = { };
 
     uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset;
 
@@ -137,14 +160,14 @@ EncodedJSValue getData(ExecState* exec)
 }
 
 template<typename Adaptor>
-EncodedJSValue setData(ExecState* exec)
+EncodedJSValue ATTR_USED setData(ExecState* exec)
 {
     JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue());
     if (!dataView)
-        return throwVMError(exec, createTypeError(exec, "Receiver of DataView method must be a DataView"));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of DataView method must be a DataView")));
     
     if (exec->argumentCount() < 2)
-        return throwVMError(exec, createTypeError(exec, "Need at least two argument (the byteOffset and value)"));
+        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Need at least two argument (the byteOffset and value)")));
     
     unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
     if (exec->hadException())
@@ -170,7 +193,7 @@ EncodedJSValue setData(ExecState* exec)
     
     unsigned byteLength = dataView->length();
     if (elementSize > byteLength || byteOffset > byteLength - elementSize)
-        return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
+        return throwVMError(exec, createRangeError(exec, ASCIILiteral("Out of bounds access")));
 
     uint8_t* dataPtr = static_cast<uint8_t*>(dataView->vector()) + byteOffset;
 
@@ -185,87 +208,92 @@ EncodedJSValue setData(ExecState* exec)
     return JSValue::encode(jsUndefined());
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt8(ExecState* exec)
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#endif
+
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt8(ExecState* exec)
 {
     return getData<Int8Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt16(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt16(ExecState* exec)
 {
     return getData<Int16Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetInt32(ExecState* exec)
 {
     return getData<Int32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint8(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint8(ExecState* exec)
 {
     return getData<Uint8Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint16(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint16(ExecState* exec)
 {
     return getData<Uint16Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetUint32(ExecState* exec)
 {
     return getData<Uint32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat32(ExecState* exec)
 {
     return getData<Float32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat64(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncGetFloat64(ExecState* exec)
 {
     return getData<Float64Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt8(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt8(ExecState* exec)
 {
     return setData<Int8Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt16(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt16(ExecState* exec)
 {
     return setData<Int16Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetInt32(ExecState* exec)
 {
     return setData<Int32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint8(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint8(ExecState* exec)
 {
     return setData<Uint8Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint16(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint16(ExecState* exec)
 {
     return setData<Uint16Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetUint32(ExecState* exec)
 {
     return setData<Uint32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat32(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat32(ExecState* exec)
 {
     return setData<Float32Adaptor>(exec);
 }
 
-static EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat64(ExecState* exec)
+EncodedJSValue JSC_HOST_CALL dataViewProtoFuncSetFloat64(ExecState* exec)
 {
     return setData<Float64Adaptor>(exec);
 }
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
 
 } // namespace JSC
-
-#include "JSDataViewPrototype.lut.h"
-
index 9d2ba2c6de535b649feb98cb8bf52bff795a502c..bc72455ccc62c8ec55a346c0d8d40e71675d5945 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class JSDataViewPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
 protected:
     JSDataViewPrototype(VM&, Structure*);
@@ -46,8 +47,6 @@ public:
 
 protected:
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 };
 
 } // namespace JSC
index c8a2acc7e89331afd8e5025cb383b3ddc4acb7b7..1482e312f377082e37c71554f8fcd7a2debfe1e6 100644 (file)
@@ -132,13 +132,14 @@ static inline int msToWeekDay(double ms)
 // NOTE: The implementation relies on the fact that no time zones have
 // more than one daylight savings offset change per month.
 // If this function is called with NaN it returns NaN.
-static LocalTimeOffset localTimeOffset(VM& vm, double ms)
+static LocalTimeOffset localTimeOffset(VM& vm, double ms, WTF::TimeType inputTimeType = WTF::UTCTime)
 {
     LocalTimeOffsetCache& cache = vm.localTimeOffsetCache;
     double start = cache.start;
     double end = cache.end;
+    WTF::TimeType cachedTimeType = cache.timeType;
 
-    if (start <= ms) {
+    if (cachedTimeType == inputTimeType && start <= ms) {
         // If the time fits in the cached interval, return the cached offset.
         if (ms <= end) return cache.offset;
 
@@ -146,7 +147,7 @@ static LocalTimeOffset localTimeOffset(VM& vm, double ms)
         double newEnd = end + cache.increment;
 
         if (ms <= newEnd) {
-            LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd);
+            LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd, inputTimeType);
             if (cache.offset == endOffset) {
                 // If the offset at the end of the new interval still matches
                 // the offset in the cache, we grow the cached time interval
@@ -155,7 +156,7 @@ static LocalTimeOffset localTimeOffset(VM& vm, double ms)
                 cache.increment = msPerMonth;
                 return endOffset;
             }
-            LocalTimeOffset offset = calculateLocalTimeOffset(ms);
+            LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
             if (offset == endOffset) {
                 // The offset at the given time is equal to the offset at the
                 // new end of the interval, so that means that we've just skipped
@@ -180,31 +181,31 @@ static LocalTimeOffset localTimeOffset(VM& vm, double ms)
     // Compute the DST offset for the time and shrink the cache interval
     // to only contain the time. This allows fast repeated DST offset
     // computations for the same time.
-    LocalTimeOffset offset = calculateLocalTimeOffset(ms);
+    LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
     cache.offset = offset;
     cache.start = ms;
     cache.end = ms;
     cache.increment = msPerMonth;
+    cache.timeType = inputTimeType;
     return offset;
 }
 
-double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType)
 {
     double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay());
     double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds);
-    double result = (day * WTF::msPerDay) + ms;
+    double localTimeResult = (day * WTF::msPerDay) + ms;
+    double localToUTCTimeOffset = inputTimeType == LocalTime
+        ? localTimeOffset(vm, localTimeResult, inputTimeType).offset : 0;
 
-    if (!inputIsUTC)
-        result -= localTimeOffset(vm, result).offset;
-
-    return result;
+    return localTimeResult - localToUTCTimeOffset;
 }
 
 // input is UTC
-void msToGregorianDateTime(VM& vm, double ms, bool outputIsUTC, GregorianDateTime& tm)
+void msToGregorianDateTime(VM& vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm)
 {
     LocalTimeOffset localTime;
-    if (!outputIsUTC) {
+    if (outputTimeType == WTF::LocalTime) {
         localTime = localTimeOffset(vm, ms);
         ms += localTime.offset;
     }
@@ -226,15 +227,15 @@ double parseDateFromNullTerminatedCharacters(VM& vm, const char* dateString)
 {
     bool haveTZ;
     int offset;
-    double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
-    if (std::isnan(ms))
+    double localTimeMS = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+    if (std::isnan(localTimeMS))
         return std::numeric_limits<double>::quiet_NaN();
 
-    // fall back to local timezone
+    // fall back to local timezone.
     if (!haveTZ)
-        offset = localTimeOffset(vm, ms).offset / WTF::msPerMinute;
+        offset = localTimeOffset(vm, localTimeMS, WTF::LocalTime).offset / WTF::msPerMinute;
 
-    return ms - (offset * WTF::msPerMinute);
+    return localTimeMS - (offset * WTF::msPerMinute);
 }
 
 double parseDate(VM& vm, const String& date)
index 17ba4a26e6667e667e83b69baddb8c47373a4927..4e4d16ff566095571a33c1bd21524ebbc68b859f 100644 (file)
@@ -50,11 +50,11 @@ namespace JSC {
 
 class VM;
 
-void msToGregorianDateTime(VM&, double, bool outputIsUTC, GregorianDateTime&);
-double gregorianDateTimeToMS(VM&, const GregorianDateTime&, double, bool inputIsUTC);
-double getUTCOffset(VM&);
-double parseDateFromNullTerminatedCharacters(VM&, const char* dateString);
-double parseDate(VM&, const WTF::String&);
+JS_EXPORT_PRIVATE void msToGregorianDateTime(VM&, double, WTF::TimeType outputTimeType, GregorianDateTime&);
+JS_EXPORT_PRIVATE double gregorianDateTimeToMS(VM&, const GregorianDateTime&, double, WTF::TimeType inputTimeType);
+JS_EXPORT_PRIVATE double getUTCOffset(VM&);
+JS_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(VM&, const char* dateString);
+JS_EXPORT_PRIVATE double parseDate(VM&, const WTF::String&);
 
 } // namespace JSC
 
index f10fbabc7c4695faa0b9a019d573fe2d7c84d87c..d687b84201783cab23e10c31d2186b16d2339707 100644 (file)
@@ -29,14 +29,6 @@ private:
     const ClassInfo* m_classInfo;
 };
 
-inline const ClassInfo* JSCell::classInfo() const
-{
-    MarkedBlock* block = MarkedBlock::blockFor(this);
-    if (block->destructorType() == MarkedBlock::Normal)
-        return static_cast<const JSDestructibleObject*>(this)->classInfo();
-    return structure(*block->vm())->classInfo();
-}
-
 } // namespace JSC
 
 #endif
diff --git a/runtime/JSEnvironmentRecord.cpp b/runtime/JSEnvironmentRecord.cpp
new file mode 100644 (file)
index 0000000..f1d7695
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSEnvironmentRecord.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSEnvironmentRecord::s_info = { "EnvironmentRecord", &Base::s_info, 0, CREATE_METHOD_TABLE(JSEnvironmentRecord) };
+
+void JSEnvironmentRecord::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    JSEnvironmentRecord* thisObject = jsCast<JSEnvironmentRecord*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    visitor.appendValues(thisObject->variables(), thisObject->symbolTable()->scopeSize());
+}
+
+} // namespace JSC
diff --git a/runtime/JSEnvironmentRecord.h b/runtime/JSEnvironmentRecord.h
new file mode 100644 (file)
index 0000000..35807ba
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSEnvironmentRecord_h
+#define JSEnvironmentRecord_h
+
+#include "JSObject.h"
+#include "JSSymbolTableObject.h"
+#include "Register.h"
+#include "SymbolTable.h"
+
+namespace JSC {
+
+class LLIntOffsetsExtractor;
+class Register;
+
+class JSEnvironmentRecord : public JSSymbolTableObject {
+    friend class JIT;
+    friend class LLIntOffsetsExtractor;
+
+public:
+    typedef JSSymbolTableObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
+    WriteBarrierBase<Unknown>* variables()
+    {
+        return bitwise_cast<WriteBarrierBase<Unknown>*>(bitwise_cast<char*>(this) + offsetOfVariables());
+    }
+    
+    bool isValid(ScopeOffset offset)
+    {
+        return !!offset && offset.offset() < symbolTable()->scopeSize();
+    }
+    
+    WriteBarrierBase<Unknown>& variableAt(ScopeOffset offset)
+    {
+        ASSERT(isValid(offset));
+        return variables()[offset.offset()];
+    }
+
+    static size_t offsetOfVariables()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSEnvironmentRecord));
+    }
+    
+    static ptrdiff_t offsetOfVariable(ScopeOffset offset)
+    {
+        return offsetOfVariables() + offset.offset() * sizeof(WriteBarrier<Unknown>);
+    }
+
+    DECLARE_INFO;
+
+    static size_t allocationSizeForScopeSize(unsigned scopeSize)
+    {
+        return offsetOfVariables() + scopeSize * sizeof(WriteBarrier<Unknown>);
+    }
+    
+    static size_t allocationSize(SymbolTable* symbolTable)
+    {
+        return allocationSizeForScopeSize(symbolTable->scopeSize());
+    }
+    
+protected:
+    JSEnvironmentRecord(
+        VM& vm,
+        Structure* structure,
+        JSScope* scope,
+        SymbolTable* symbolTable)
+        : Base(vm, structure, scope, symbolTable)
+    {
+    }
+    
+    void finishCreationUninitialized(VM& vm)
+    {
+        Base::finishCreation(vm);
+    }
+    
+    void finishCreation(VM& vm)
+    {
+        finishCreationUninitialized(vm);
+        for (unsigned i = symbolTable()->scopeSize(); i--;) {
+            // Filling this with undefined is useful because that's what variables start out as.
+            variableAt(ScopeOffset(i)).setUndefined();
+        }
+    }
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+};
+
+} // namespace JSC
+
+#endif // JSEnvironmentRecord_h
index 0f47ac9861d2e2b33d613343a1f3c5ef7a784484..1b8c407ec3d4949b606ec95b9ac9b4e2dfc6812f 100644 (file)
@@ -1,9 +1,10 @@
 /*
  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *  Copyright (C) 2007 Maks Orlovich
+ *  Copyright (C) 2015 Canon Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -25,7 +26,7 @@
 #include "config.h"
 #include "JSFunction.h"
 
-#include "Arguments.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CommonIdentifiers.h"
 #include "CallFrame.h"
 #include "GetterSetter.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
+#include "JSCInlines.h"
 #include "JSFunctionInlines.h"
 #include "JSGlobalObject.h"
-#include "JSNameScope.h" 
 #include "JSNotAnObject.h"
 #include "Interpreter.h"
 #include "ObjectConstructor.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "StackVisitor.h"
@@ -53,51 +53,70 @@ EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec)
     return throwVMError(exec, createNotAConstructorError(exec, exec->callee()));
 }
 
-const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) };
+const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFunction) };
 
 bool JSFunction::isHostFunctionNonInline() const
 {
     return isHostFunction();
 }
 
-JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
+JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
+{
+    JSFunction* result = createImpl(vm, executable, scope);
+    executable->singletonFunction()->notifyWrite(vm, result, "Allocating a function");
+    return result;
+}
+
+static inline NativeExecutable* getNativeExecutable(VM& vm, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
 {
-    NativeExecutable* executable;
 #if !ENABLE(JIT)
     UNUSED_PARAM(intrinsic);
 #else
     if (intrinsic != NoIntrinsic && vm.canUseJIT()) {
         ASSERT(nativeConstructor == callHostFunctionAsConstructor);
-        executable = vm.getHostFunction(nativeFunction, intrinsic);
-    } else
+        return vm.getHostFunction(nativeFunction, intrinsic);
+    }
 #endif
-        executable = vm.getHostFunction(nativeFunction, nativeConstructor);
+    return vm.getHostFunction(nativeFunction, nativeConstructor);
+}
 
+JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
+{
+    NativeExecutable* executable = getNativeExecutable(vm, nativeFunction, intrinsic, nativeConstructor);
     JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, globalObject, globalObject->functionStructure());
     // Can't do this during initialization because getHostFunction might do a GC allocation.
     function->finishCreation(vm, executable, length, name);
     return function;
 }
 
-void JSFunction::destroy(JSCell* cell)
+class JSStdFunction : public JSFunction {
+public:
+    JSStdFunction(VM& vm, JSGlobalObject* object, Structure* structure, NativeStdFunction&& function)
+        : JSFunction(vm, object, structure)
+        , stdFunction(WTF::move(function)) { }
+
+    NativeStdFunction stdFunction;
+};
+
+static EncodedJSValue JSC_HOST_CALL runStdFunction(ExecState* state)
+{
+    JSStdFunction* jsFunction = jsCast<JSStdFunction*>(state->callee());
+    ASSERT(jsFunction);
+    return jsFunction->stdFunction(state);
+}
+
+JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeStdFunction&& nativeStdFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
 {
-    static_cast<JSFunction*>(cell)->JSFunction::~JSFunction();
+    NativeExecutable* executable = getNativeExecutable(vm, runStdFunction, intrinsic, nativeConstructor);
+    JSStdFunction* function = new (NotNull, allocateCell<JSStdFunction>(vm.heap)) JSStdFunction(vm, globalObject, globalObject->functionStructure(), WTF::move(nativeStdFunction));
+    // Can't do this during initialization because getHostFunction might do a GC allocation.
+    function->finishCreation(vm, executable, length, name);
+    return function;
 }
 
 JSFunction::JSFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-    : Base(vm, structure)
+    : Base(vm, globalObject, structure)
     , m_executable()
-    , m_scope(vm, this, globalObject)
-    // We initialize blind so that changes to the prototype after function creation but before
-    // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
-    // watchpoint will start watching and any changes will both force deoptimization and disable
-    // future attempts to optimize. This is necessary because we are guaranteed that the
-    // allocation profile is changed exactly once prior to optimizations kicking in. We could be
-    // smarter and count the number of times the prototype is clobbered and only optimize if it
-    // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
-    // clobbered once, and if it's clobbered more than once, that will probably only occur
-    // before we started optimizing, anyway.
-    , m_allocationProfileWatchpoint(ClearWatchpoint)
 {
 }
 
@@ -110,32 +129,48 @@ void JSFunction::finishCreation(VM& vm, NativeExecutable* executable, int length
     putDirect(vm, vm.propertyNames->length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
 }
 
-void JSFunction::addNameScopeIfNeeded(VM& vm)
+JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
 {
-    FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_executable.get());
-    if (!functionNameIsInScope(executable->name(), executable->functionMode()))
-        return;
-    if (!functionNameScopeIsDynamic(executable->usesEval(), executable->isStrictMode()))
-        return;
-    m_scope.set(vm, this, JSNameScope::create(vm, m_scope->globalObject(), executable->name(), this, ReadOnly | DontDelete, m_scope.get()));
+    JSFunction* function = create(vm, executable, globalObject);
+    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), DontDelete | ReadOnly | DontEnum);
+    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
+    return function;
 }
 
-JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
+JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject, const String& name)
 {
     JSFunction* function = create(vm, executable, globalObject);
-    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), DontDelete | ReadOnly | DontEnum);
+    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
     function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
     return function;
 }
 
-ObjectAllocationProfile* JSFunction::createAllocationProfile(ExecState* exec, size_t inlineCapacity)
+FunctionRareData* JSFunction::allocateAndInitializeRareData(ExecState* exec, size_t inlineCapacity)
+{
+    ASSERT(!m_rareData);
+    VM& vm = exec->vm();
+    JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
+    if (!prototype)
+        prototype = globalObject()->objectPrototype();
+    FunctionRareData* rareData = FunctionRareData::create(vm, prototype, inlineCapacity);
+
+    // A DFG compilation thread may be trying to read the rare data
+    // We want to ensure that it sees it properly allocated
+    WTF::storeStoreFence();
+
+    m_rareData.set(vm, this, rareData);
+    return m_rareData.get();
+}
+
+FunctionRareData* JSFunction::initializeRareData(ExecState* exec, size_t inlineCapacity)
 {
+    ASSERT(!!m_rareData);
     VM& vm = exec->vm();
     JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
     if (!prototype)
         prototype = globalObject()->objectPrototype();
-    m_allocationProfile.initialize(globalObject()->vm(), this, prototype, inlineCapacity);
-    return &m_allocationProfile;
+    m_rareData->initialize(globalObject()->vm(), prototype, inlineCapacity);
+    return m_rareData.get();
 }
 
 String JSFunction::name(ExecState* exec)
@@ -178,13 +213,11 @@ void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
 
-    visitor.append(&thisObject->m_scope);
     visitor.append(&thisObject->m_executable);
-    thisObject->m_allocationProfile.visitAggregate(visitor);
+    if (thisObject->m_rareData)
+        visitor.append(&thisObject->m_rareData);
 }
 
 CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
@@ -293,8 +326,12 @@ EncodedJSValue JSFunction::callerGetter(ExecState* exec, JSObject* slotBase, Enc
     JSValue caller = retrieveCallerFunction(exec, thisObj);
 
     // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller.
-    if (!caller.isObject() || !asObject(caller)->inherits(JSFunction::info()))
+    if (!caller.isObject() || !asObject(caller)->inherits(JSFunction::info())) {
+        // It isn't a JSFunction, but if it is a JSCallee from a program or call eval, return null.
+        if (jsDynamicCast<JSCallee*>(caller))
+            return JSValue::encode(jsNull());
         return JSValue::encode(caller);
+    }
     JSFunction* function = jsCast<JSFunction*>(caller);
     if (function->isHostOrBuiltinFunction() || !function->jsExecutable()->isStrictMode())
         return JSValue::encode(caller);
@@ -380,7 +417,7 @@ bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN
 void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(object);
-    if (!thisObject->isHostOrBuiltinFunction() && (mode == IncludeDontEnumProperties)) {
+    if (!thisObject->isHostOrBuiltinFunction() && mode.includeDontEnumProperties()) {
         VM& vm = exec->vm();
         // Make sure prototype has been reified.
         PropertySlot slot(thisObject);
@@ -406,9 +443,9 @@ void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
         // following the rules set out in ECMA-262 8.12.9.
         PropertySlot slot(thisObject);
         thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot);
-        thisObject->m_allocationProfile.clear();
-        thisObject->m_allocationProfileWatchpoint.fireAll();
-        // Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile.
+        if (thisObject->m_rareData)
+            thisObject->m_rareData->clear("Store to prototype property of a function");
+        // Don't allow this to be cached, since a [[Put]] must clear m_rareData.
         PutPropertySlot dontCache(thisObject);
         Base::put(thisObject, exec, propertyName, value, dontCache);
         return;
@@ -453,8 +490,8 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
         // following the rules set out in ECMA-262 8.12.9.
         PropertySlot slot(thisObject);
         thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot);
-        thisObject->m_allocationProfile.clear();
-        thisObject->m_allocationProfileWatchpoint.fireAll();
+        if (thisObject->m_rareData)
+            thisObject->m_rareData->clear("Store to prototype property of a function");
         return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
     }
 
@@ -484,7 +521,7 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
      
     if (descriptor.configurablePresent() && descriptor.configurable()) {
         if (throwException)
-            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+            exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
         return false;
     }
     if (descriptor.enumerablePresent() && descriptor.enumerable()) {
@@ -514,6 +551,10 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
 ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(cell);
+
+    if (thisObject->isBuiltinFunction())
+        return ConstructTypeNone;
+
     if (thisObject->isHostFunction()) {
         constructData.native.function = thisObject->nativeConstructor();
         return ConstructTypeHost;
index f7b7f1633cd871c67bcf25a0049d793cbcb67eb7..0b87d75c91450c5af1aaed27a61a748ef80f093e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *  Copyright (C) 2007 Maks Orlovich
  *
 #ifndef JSFunction_h
 #define JSFunction_h
 
+#include "FunctionRareData.h"
 #include "InternalFunction.h"
-#include "JSDestructibleObject.h"
+#include "JSCallee.h"
 #include "JSScope.h"
-#include "ObjectAllocationProfile.h"
 #include "Watchpoint.h"
 
 namespace JSC {
 
-    class ExecutableBase;
-    class FunctionExecutable;
-    class FunctionPrototype;
-    class JSActivation;
-    class JSGlobalObject;
-    class LLIntOffsetsExtractor;
-    class NativeExecutable;
-    class SourceCode;
-    namespace DFG {
-    class SpeculativeJIT;
-    class JITCompiler;
+class ExecutableBase;
+class FunctionExecutable;
+class FunctionPrototype;
+class JSLexicalEnvironment;
+class JSGlobalObject;
+class LLIntOffsetsExtractor;
+class NativeExecutable;
+class SourceCode;
+namespace DFG {
+class SpeculativeJIT;
+class JITCompiler;
+}
+
+typedef std::function<EncodedJSValue (ExecState*)> NativeStdFunction;
+
+JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
+
+JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
+
+class JSFunction : public JSCallee {
+    friend class JIT;
+    friend class DFG::SpeculativeJIT;
+    friend class DFG::JITCompiler;
+    friend class VM;
+
+public:
+    typedef JSCallee Base;
+    const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+
+    static size_t allocationSize(size_t inlineCapacity)
+    {
+        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
+        return sizeof(JSFunction);
     }
 
-    JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
+    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
+    
+    static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*);
+    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeStdFunction&&, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
+
+    static JSFunction* create(VM&, FunctionExecutable*, JSScope*);
+
+    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
+    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name);
+
+    JS_EXPORT_PRIVATE String name(ExecState*);
+    JS_EXPORT_PRIVATE String displayName(ExecState*);
+    const String calculatedDisplayName(ExecState*);
+
+    ExecutableBase* executable() const { return m_executable.get(); }
 
-    JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
+    // To call either of these methods include Executable.h
+    bool isHostFunction() const;
+    FunctionExecutable* jsExecutable() const;
+
+    JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    {
+        ASSERT(globalObject);
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info()); 
+    }
+
+    NativeFunction nativeFunction();
+    NativeFunction nativeConstructor();
+
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+
+    static inline ptrdiff_t offsetOfExecutable()
+    {
+        return OBJECT_OFFSETOF(JSFunction, m_executable);
+    }
+
+    static inline ptrdiff_t offsetOfRareData()
+    {
+        return OBJECT_OFFSETOF(JSFunction, m_rareData);
+    }
+
+    FunctionRareData* rareData(ExecState* exec, unsigned inlineCapacity)
+    {
+        if (UNLIKELY(!m_rareData))
+            return allocateAndInitializeRareData(exec, inlineCapacity);
+        if (UNLIKELY(!m_rareData->isInitialized()))
+            return initializeRareData(exec, inlineCapacity);
+        return m_rareData.get();
+    }
+
+    FunctionRareData* rareData()
+    {
+        FunctionRareData* rareData = m_rareData.get();
+
+        // The JS thread may be concurrently creating the rare data
+        // If we see it, we want to ensure it has been properly created
+        WTF::loadLoadFence();
+
+        return rareData;
+    }
+
+    bool isHostOrBuiltinFunction() const;
+    bool isBuiltinFunction() const;
+    JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
+    bool isClassConstructorFunction() const;
+
+protected:
+    JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
+    JSFunction(VM&, FunctionExecutable*, JSScope*);
+
+    void finishCreation(VM&, NativeExecutable*, int length, const String& name);
+    using Base::finishCreation;
+
+    FunctionRareData* allocateAndInitializeRareData(ExecState*, size_t inlineCapacity);
+    FunctionRareData* initializeRareData(ExecState*, size_t inlineCapacity);
+
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = EnumerationMode());
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+    static JSFunction* createImpl(VM& vm, FunctionExecutable* executable, JSScope* scope)
+    {
+        JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
+        ASSERT(function->structure()->globalObject());
+        function->finishCreation(vm);
+        return function;
+    }
     
-    class JSFunction : public JSDestructibleObject {
-        friend class JIT;
-        friend class DFG::SpeculativeJIT;
-        friend class DFG::JITCompiler;
-        friend class VM;
-
-    public:
-        typedef JSDestructibleObject Base;
-
-        JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
-
-        static JSFunction* create(VM& vm, FunctionExecutable* executable, JSScope* scope)
-        {
-            JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
-            ASSERT(function->structure()->globalObject());
-            function->finishCreation(vm);
-            return function;
-        }
-        
-        static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
-        
-        static void destroy(JSCell*);
-        
-        JS_EXPORT_PRIVATE String name(ExecState*);
-        JS_EXPORT_PRIVATE String displayName(ExecState*);
-        const String calculatedDisplayName(ExecState*);
-
-        JSScope* scope()
-        {
-            ASSERT(!isHostFunctionNonInline());
-            return m_scope.get();
-        }
-        // This method may be called for host functins, in which case it
-        // will return an arbitrary value. This should only be used for
-        // optimized paths in which the return value does not matter for
-        // host functions, and checking whether the function is a host
-        // function is deemed too expensive.
-        JSScope* scopeUnchecked()
-        {
-            return m_scope.get();
-        }
-        void setScope(VM& vm, JSScope* scope)
-        {
-            ASSERT(!isHostFunctionNonInline());
-            m_scope.set(vm, this, scope);
-        }
-        void addNameScopeIfNeeded(VM&);
-
-        ExecutableBase* executable() const { return m_executable.get(); }
-
-        // To call either of these methods include Executable.h
-        bool isHostFunction() const;
-        FunctionExecutable* jsExecutable() const;
-
-        JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
-
-        DECLARE_EXPORT_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-        {
-            ASSERT(globalObject);
-            return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info()); 
-        }
-
-        NativeFunction nativeFunction();
-        NativeFunction nativeConstructor();
-
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-
-        static inline ptrdiff_t offsetOfScopeChain()
-        {
-            return OBJECT_OFFSETOF(JSFunction, m_scope);
-        }
-
-        static inline ptrdiff_t offsetOfExecutable()
-        {
-            return OBJECT_OFFSETOF(JSFunction, m_executable);
-        }
-
-        static inline ptrdiff_t offsetOfAllocationProfile()
-        {
-            return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
-        }
-
-        ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
-        {
-            if (UNLIKELY(m_allocationProfile.isNull()))
-                return createAllocationProfile(exec, inlineCapacity);
-            return &m_allocationProfile;
-        }
-        
-        Structure* allocationStructure() { return m_allocationProfile.structure(); }
-
-        InlineWatchpointSet& allocationProfileWatchpointSet()
-        {
-            return m_allocationProfileWatchpoint;
-        }
-
-        bool isHostOrBuiltinFunction() const;
-        bool isBuiltinFunction() const;
-        JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
-
-    protected:
-        const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
-
-        JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
-        JSFunction(VM&, FunctionExecutable*, JSScope*);
-        
-        void finishCreation(VM&, NativeExecutable*, int length, const String& name);
-        using Base::finishCreation;
-
-        ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
-
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-        static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
-        static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-
-        static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-
-        static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-    private:
-        friend class LLIntOffsetsExtractor;
-        
-        static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-        static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-        static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-        static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-
-        WriteBarrier<ExecutableBase> m_executable;
-        WriteBarrier<JSScope> m_scope;
-        ObjectAllocationProfile m_allocationProfile;
-        InlineWatchpointSet m_allocationProfileWatchpoint;
-    };
+    friend class LLIntOffsetsExtractor;
+
+    static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+    static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+    static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+    static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+
+    WriteBarrier<ExecutableBase> m_executable;
+    WriteBarrier<FunctionRareData> m_rareData;
+};
 
 } // namespace JSC
 
index ad5b56b880c382d0d6d148787d5248c1cb954b52..f6c6d58ec6e5c1164cb27fa5e41618b4b8142f02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+inline JSFunction* JSFunction::createWithInvalidatedReallocationWatchpoint(
+    VM& vm, FunctionExecutable* executable, JSScope* scope)
+{
+    ASSERT(executable->singletonFunction()->hasBeenInvalidated());
+    return createImpl(vm, executable, scope);
+}
+
 inline JSFunction::JSFunction(VM& vm, FunctionExecutable* executable, JSScope* scope)
-    : Base(vm, scope->globalObject()->functionStructure())
+    : Base(vm, scope, scope->globalObject()->functionStructure())
     , m_executable(vm, this, executable)
-    , m_scope(vm, this, scope)
-    , m_allocationProfileWatchpoint(ClearWatchpoint) // See comment in JSFunction.cpp concerning the reason for using ClearWatchpoint as opposed to IsWatched.
+    , m_rareData()
 {
 }
 
@@ -61,6 +67,11 @@ inline bool JSFunction::isHostOrBuiltinFunction() const
     return isHostFunction() || isBuiltinFunction();
 }
 
+inline bool JSFunction::isClassConstructorFunction() const
+{
+    return !isHostFunction() && jsExecutable()->isClassConstructorFunction();
+}
+
 inline NativeFunction JSFunction::nativeFunction()
 {
     ASSERT(isHostFunctionNonInline());
diff --git a/runtime/JSFunctionNameScope.cpp b/runtime/JSFunctionNameScope.cpp
new file mode 100644 (file)
index 0000000..21364eb
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSFunctionNameScope.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSFunctionNameScope::s_info = { "FunctionNameScope", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFunctionNameScope) };
+
+} // namespace JSC
+
diff --git a/runtime/JSFunctionNameScope.h b/runtime/JSFunctionNameScope.h
new file mode 100644 (file)
index 0000000..922e89a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSFunctionNameScope_h
+#define JSFunctionNameScope_h
+
+#include "JSNameScope.h"
+
+namespace JSC {
+
+class JSFunctionNameScope : public JSNameScope {
+public:
+    typedef JSNameScope Base;
+
+private:
+    friend class JSNameScope;
+    
+    JSFunctionNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, globalObject->catchScopeStructure(), next, symbolTable)
+    {
+    }
+    
+public:
+    static JSFunctionNameScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
+    {
+        return Base::create<JSFunctionNameScope>(vm, globalObject, currentScope, symbolTable, value);
+    }
+    
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+    {
+        return Structure::create(vm, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), info());
+    }
+    
+    DECLARE_INFO;
+};
+
+} // namespace JSC
+
+#endif // JSFunctionNameScope_h
+
index 1343eee3d720a2066adc92b439fdf19918fa45f8..3996e1cceaf050ddc12e429805968a0a04ea5d6a 100644 (file)
@@ -87,6 +87,8 @@ template<typename Adaptor>
 class JSGenericTypedArrayView : public JSArrayBufferView {
 public:
     typedef JSArrayBufferView Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetPropertyNames | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero;
+
     static const unsigned elementSize = sizeof(typename Adaptor::Type);
     
 protected:
@@ -228,8 +230,6 @@ public:
     
 protected:
     friend struct TypedArrayClassInfos;
-    
-    static const unsigned StructureFlags = OverridesGetPropertyNames | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
 
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
index 8d877d602e60af7d717f2e7157ddaad52e8913e8..ec653dcdc4889d4e95c14bd49ba8d82112c957f0 100644 (file)
@@ -49,7 +49,7 @@ JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::create(
 {
     ConstructionContext context(exec->vm(), structure, length, sizeof(typename Adaptor::Type));
     if (!context) {
-        exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
+        exec->vm().throwException(exec, createOutOfMemoryError(exec));
         return 0;
     }
     JSGenericTypedArrayView* result =
@@ -67,7 +67,7 @@ JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninit
         exec->vm(), structure, length, sizeof(typename Adaptor::Type),
         ConstructionContext::DontInitialize);
     if (!context) {
-        exec->vm().throwException(exec, createOutOfMemoryError(structure->globalObject()));
+        exec->vm().throwException(exec, createOutOfMemoryError(exec));
         return 0;
     }
     JSGenericTypedArrayView* result =
@@ -83,10 +83,14 @@ JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::create(
     unsigned byteOffset, unsigned length)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!ArrayBufferView::verifySubRange<typename Adaptor::Type>(buffer, byteOffset, length)) {
-        exec->vm().throwException(
-            exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
-        return 0;
+    size_t size = sizeof(typename Adaptor::Type);
+    if (!ArrayBufferView::verifySubRangeLength(buffer, byteOffset, length, size)) {
+        exec->vm().throwException(exec, createRangeError(exec, "Length out of range of buffer"));
+        return nullptr;
+    }
+    if (!ArrayBufferView::verifyByteOffsetAlignment(byteOffset, size)) {
+        exec->vm().throwException(exec, createRangeError(exec, "Byte offset is not aligned"));
+        return nullptr;
     }
     ConstructionContext context(exec->vm(), structure, buffer, byteOffset, length);
     ASSERT(context);
@@ -298,9 +302,9 @@ bool JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot(
         return true;
     }
     
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex && thisObject->canGetIndexQuickly(index)) {
-        slot.setValue(thisObject, DontDelete | ReadOnly, thisObject->getIndexQuickly(index));
+    Optional<uint32_t> index = parseIndex(propertyName);
+    if (index && thisObject->canGetIndexQuickly(index.value())) {
+        slot.setValue(thisObject, DontDelete | ReadOnly, thisObject->getIndexQuickly(index.value()));
         return true;
     }
     
@@ -320,9 +324,8 @@ void JSGenericTypedArrayView<Adaptor>::put(
         return;
     }
     
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex) {
-        putByIndex(thisObject, exec, index, value, slot.isStrictMode());
+    if (Optional<uint32_t> index = parseIndex(propertyName)) {
+        putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
         return;
     }
     
@@ -339,8 +342,7 @@ bool JSGenericTypedArrayView<Adaptor>::defineOwnProperty(
     // This is matching Firefox behavior. In particular, it rejects all attempts to
     // defineOwnProperty for indexed properties on typed arrays, even if they're out
     // of bounds.
-    if (propertyName == exec->propertyNames().length
-        || propertyName.asIndex() != PropertyName::NotAnIndex)
+    if (propertyName == exec->propertyNames().length || parseIndex(propertyName))
         return reject(exec, shouldThrow, "Attempting to write to a read-only typed array property.");
     
     return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
@@ -352,8 +354,7 @@ bool JSGenericTypedArrayView<Adaptor>::deleteProperty(
 {
     JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
     
-    if (propertyName == exec->propertyNames().length
-        || propertyName.asIndex() != PropertyName::NotAnIndex)
+    if (propertyName == exec->propertyNames().length || parseIndex(propertyName))
         return false;
     
     return Base::deleteProperty(thisObject, exec, propertyName);
@@ -411,7 +412,7 @@ void JSGenericTypedArrayView<Adaptor>::getOwnNonIndexPropertyNames(
 {
     JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
     
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         array.add(exec->propertyNames().length);
     
     Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
@@ -442,7 +443,7 @@ void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor&
     }
         
     case OversizeTypedArray: {
-        visitor.reportExtraMemoryUsage(thisObject, thisObject->byteSize());
+        visitor.reportExtraMemoryVisited(thisObject, thisObject->byteSize());
         break;
     }
         
index fbf2ff575a1a44bb2d3530563da2ccbaab6d3a9d..10bf17782022c4794d30e70efb2bef5df242ce18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *
  * Redistribution and use in source and binary forms, with or without
 #include "config.h"
 #include "JSGlobalObject.h"
 
-#include "Arguments.h"
-#include "ArgumentsIteratorConstructor.h"
-#include "ArgumentsIteratorPrototype.h"
 #include "ArrayConstructor.h"
-#include "ArrayIteratorConstructor.h"
 #include "ArrayIteratorPrototype.h"
 #include "ArrayPrototype.h"
 #include "BooleanConstructor.h"
 #include "BooleanPrototype.h"
+#include "BuiltinNames.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CodeCache.h"
 #include "ConsolePrototype.h"
 #include "DateConstructor.h"
 #include "DatePrototype.h"
 #include "Debugger.h"
+#include "DebuggerScope.h"
+#include "DirectArguments.h"
 #include "Error.h"
 #include "ErrorConstructor.h"
 #include "ErrorPrototype.h"
@@ -53,9 +53,8 @@
 #include "GetterSetter.h"
 #include "HeapIterationScope.h"
 #include "Interpreter.h"
+#include "IteratorPrototype.h"
 #include "JSAPIWrapperObject.h"
-#include "JSActivation.h"
-#include "JSArgumentsIterator.h"
 #include "JSArrayBuffer.h"
 #include "JSArrayBufferConstructor.h"
 #include "JSArrayBufferPrototype.h"
 #include "JSCallbackConstructor.h"
 #include "JSCallbackFunction.h"
 #include "JSCallbackObject.h"
+#include "JSCatchScope.h"
 #include "JSConsole.h"
 #include "JSDataView.h"
 #include "JSDataViewPrototype.h"
+#include "JSDollarVM.h"
+#include "JSDollarVMPrototype.h"
 #include "JSFunction.h"
+#include "JSFunctionNameScope.h"
 #include "JSGenericTypedArrayViewConstructorInlines.h"
 #include "JSGenericTypedArrayViewInlines.h"
 #include "JSGenericTypedArrayViewPrototypeInlines.h"
 #include "JSGlobalObjectFunctions.h"
+#include "JSJob.h"
+#include "JSLexicalEnvironment.h"
 #include "JSLock.h"
 #include "JSMap.h"
 #include "JSMapIterator.h"
-#include "JSNameScope.h"
 #include "JSONObject.h"
 #include "JSSet.h"
 #include "JSSetIterator.h"
+#include "JSStringIterator.h"
+#include "JSTemplateRegistryKey.h"
 #include "JSTypedArrayConstructors.h"
 #include "JSTypedArrayPrototypes.h"
 #include "JSTypedArrays.h"
 #include "JSWeakMap.h"
+#include "JSWeakSet.h"
 #include "JSWithScope.h"
 #include "LegacyProfiler.h"
 #include "Lookup.h"
 #include "MapConstructor.h"
-#include "MapIteratorConstructor.h"
 #include "MapIteratorPrototype.h"
 #include "MapPrototype.h"
 #include "MathObject.h"
 #include "Microtask.h"
-#include "NameConstructor.h"
-#include "NameInstance.h"
-#include "NamePrototype.h"
 #include "NativeErrorConstructor.h"
 #include "NativeErrorPrototype.h"
+#include "NullGetterFunction.h"
+#include "NullSetterFunction.h"
 #include "NumberConstructor.h"
 #include "NumberPrototype.h"
 #include "ObjCCallbackFunction.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
+#include "ScopedArguments.h"
 #include "SetConstructor.h"
-#include "SetIteratorConstructor.h"
 #include "SetIteratorPrototype.h"
 #include "SetPrototype.h"
 #include "StrictEvalActivation.h"
 #include "StringConstructor.h"
+#include "StringIteratorPrototype.h"
 #include "StringPrototype.h"
-#include "VariableWatchpointSetInlines.h"
+#include "Symbol.h"
+#include "SymbolConstructor.h"
+#include "SymbolPrototype.h"
+#include "VariableWriteFireDetail.h"
+#include "WeakGCMapInlines.h"
 #include "WeakMapConstructor.h"
 #include "WeakMapPrototype.h"
+#include "WeakSetConstructor.h"
+#include "WeakSetPrototype.h"
+
+#if ENABLE(INTL)
+#include "IntlObject.h"
+#endif // ENABLE(INTL)
 
 #if ENABLE(PROMISES)
 #include "JSPromise.h"
 
 namespace JSC {
 
-const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &Base::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(JSGlobalObject) };
+const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &Base::s_info, &globalObjectTable, CREATE_METHOD_TABLE(JSGlobalObject) };
 
-const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled, 0, &shouldInterruptScriptBeforeTimeout };
+const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptRuntimeFlags, 0, &shouldInterruptScriptBeforeTimeout };
 
 /* Source for JSGlobalObject.lut.h
 @begin globalObjectTable
-  parseInt              globalFuncParseInt              DontEnum|Function 2
   parseFloat            globalFuncParseFloat            DontEnum|Function 1
   isNaN                 globalFuncIsNaN                 DontEnum|Function 1
   isFinite              globalFuncIsFinite              DontEnum|Function 1
@@ -158,6 +173,28 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &all
 @end
 */
 
+static EncodedJSValue JSC_HOST_CALL getTemplateObject(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    ASSERT(thisValue.inherits(JSTemplateRegistryKey::info()));
+    return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)->templateRegistryKey()));
+}
+
+
+static EncodedJSValue JSC_HOST_CALL enqueueJob(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+
+    JSValue job = exec->argument(0);
+    JSValue arguments = exec->argument(1);
+    ASSERT(arguments.inherits(JSArray::info()));
+
+    globalObject->queueMicrotask(createJSJob(vm, job, jsCast<JSArray*>(arguments)));
+
+    return JSValue::encode(jsUndefined());
+}
+
 JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
     : Base(vm, structure, 0)
     , m_vm(vm)
@@ -168,8 +205,9 @@ JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectM
     , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
     , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
     , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
+    , m_templateRegistry(vm)
     , m_evalEnabled(true)
-    , m_experimentsEnabled(false)
+    , m_runtimeFlags()
     , m_consoleClient(nullptr)
     , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
 {
@@ -198,11 +236,11 @@ void JSGlobalObject::setGlobalThis(VM& vm, JSObject* globalThis)
     m_globalThis.set(vm, this, globalThis);
 }
 
-void JSGlobalObject::init()
+void JSGlobalObject::init(VM& vm)
 {
-    ASSERT(vm().currentThreadIsHoldingAPILock());
+    ASSERT(vm.currentThreadIsHoldingAPILock());
 
-    JSGlobalObject::globalExec()->init(0, 0, this, CallFrame::noCaller(), 0, 0);
+    JSGlobalObject::globalExec()->init(0, 0, CallFrame::noCaller(), 0, 0);
 
     m_debugger = 0;
 
@@ -210,88 +248,38 @@ void JSGlobalObject::init()
     m_inspectorController = std::make_unique<Inspector::JSGlobalObjectInspectorController>(*this);
     m_inspectorDebuggable = std::make_unique<JSGlobalObjectDebuggable>(*this);
     m_inspectorDebuggable->init();
-    m_inspectorDebuggable->setRemoteDebuggingAllowed(true);
     m_consoleClient = m_inspectorController->consoleClient();
 #endif
 
-    reset(prototype());
-}
-
-void JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
-    JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
-    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
-
-    if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode()))
-        return;
-    Base::put(thisObject, exec, propertyName, value, slot);
-}
-
-bool JSGlobalObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-{
-    JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
-    PropertySlot slot(thisObject);
-    // silently ignore attempts to add accessors aliasing vars.
-    if (descriptor.isAccessorDescriptor() && symbolTableGet(thisObject, propertyName, slot))
-        return false;
-    return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
-}
-
-JSGlobalObject::NewGlobalVar JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)
-{
-    ConcurrentJITLocker locker(symbolTable()->m_lock);
-    int index = symbolTable()->size(locker);
-    SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0);
-    if (constantMode == IsVariable)
-        newEntry.prepareToWatch(symbolTable());
-    SymbolTable::Map::AddResult result = symbolTable()->add(locker, ident.impl(), newEntry);
-    if (result.isNewEntry)
-        addRegisters(1);
-    else
-        index = result.iterator->value.getIndex();
-    NewGlobalVar var;
-    var.registerNumber = index;
-    var.set = result.iterator->value.watchpointSet();
-    return var;
-}
-
-void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName, JSValue value)
-{
-    VM& vm = exec->vm();
-    removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties.
-    NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
-    registerAt(var.registerNumber).set(exec->vm(), this, value);
-    if (var.set)
-        var.set->notifyWrite(vm, value);
-}
-
-static inline JSObject* lastInPrototypeChain(JSObject* object)
-{
-    JSObject* o = object;
-    while (o->prototype().isObject())
-        o = asObject(o->prototype());
-    return o;
-}
-
-void JSGlobalObject::reset(JSValue prototype)
-{
     ExecState* exec = JSGlobalObject::globalExec();
-    VM& vm = exec->vm();
 
     m_functionPrototype.set(vm, this, FunctionPrototype::create(vm, FunctionPrototype::createStructure(vm, this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
+    m_calleeStructure.set(vm, this, JSCallee::createStructure(vm, this, jsNull()));
+
+    // Need to create the callee structure (above) before creating the callee.
+    m_globalCallee.set(vm, this, JSCallee::create(vm, this, this));
+    exec->setCallee(m_globalCallee.get());
+
     m_functionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
     m_boundFunctionStructure.set(vm, this, JSBoundFunction::createStructure(vm, this, m_functionPrototype.get()));
-    m_namedFunctionStructure.set(vm, this, Structure::addPropertyTransition(vm, m_functionStructure.get(), vm.propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
+    m_namedFunctionStructure.set(vm, this, Structure::addPropertyTransition(vm, m_functionStructure.get(), vm.propertyNames->name, DontDelete | ReadOnly | DontEnum, m_functionNameOffset));
     m_internalFunctionStructure.set(vm, this, InternalFunction::createStructure(vm, this, m_functionPrototype.get()));
     JSFunction* callFunction = 0;
     JSFunction* applyFunction = 0;
     m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction);
     m_callFunction.set(vm, this, callFunction);
     m_applyFunction.set(vm, this, applyFunction);
+    m_arrayProtoValuesFunction.set(vm, this, JSFunction::create(vm, this, 0, vm.propertyNames->values.string(), arrayProtoFuncValues));
+#if ENABLE(PROMISES)
+    m_initializePromiseFunction.set(vm, this, JSFunction::createBuiltinFunction(vm, operationsPromiseInitializePromiseCodeGenerator(vm), this));
+    m_newPromiseDeferredFunction.set(vm, this, JSFunction::createBuiltinFunction(vm, operationsPromiseNewPromiseDeferredCodeGenerator(vm), this));
+#endif // ENABLE(PROMISES)
+    m_nullGetterFunction.set(vm, this, NullGetterFunction::create(vm, NullGetterFunction::createStructure(vm, this, m_functionPrototype.get())));
+    m_nullSetterFunction.set(vm, this, NullSetterFunction::create(vm, NullSetterFunction::createStructure(vm, this, m_functionPrototype.get())));
     m_objectPrototype.set(vm, this, ObjectPrototype::create(vm, this, ObjectPrototype::createStructure(vm, this, jsNull())));
-    GetterSetter* protoAccessor = GetterSetter::create(vm);
-    protoAccessor->setGetter(vm, JSFunction::create(vm, this, 0, String(), globalFuncProtoGetter));
-    protoAccessor->setSetter(vm, JSFunction::create(vm, this, 0, String(), globalFuncProtoSetter));
+    GetterSetter* protoAccessor = GetterSetter::create(vm, this);
+    protoAccessor->setGetter(vm, this, JSFunction::create(vm, this, 0, String(), globalFuncProtoGetter));
+    protoAccessor->setSetter(vm, this, JSFunction::create(vm, this, 0, String(), globalFuncProtoSetter));
     m_objectPrototype->putDirectNonIndexAccessor(vm, vm.propertyNames->underscoreProto, protoAccessor, Accessor | DontEnum);
     m_functionPrototype->structure()->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
     
@@ -316,23 +304,27 @@ void JSGlobalObject::reset(JSValue prototype)
     m_typedArrays[toIndex(TypeFloat32)].structure.set(vm, this, JSFloat32Array::createStructure(vm, this, m_typedArrays[toIndex(TypeFloat32)].prototype.get()));
     m_typedArrays[toIndex(TypeFloat64)].structure.set(vm, this, JSFloat64Array::createStructure(vm, this, m_typedArrays[toIndex(TypeFloat64)].prototype.get()));
     m_typedArrays[toIndex(TypeDataView)].structure.set(vm, this, JSDataView::createStructure(vm, this, m_typedArrays[toIndex(TypeDataView)].prototype.get()));
-
-    m_nameScopeStructure.set(vm, this, JSNameScope::createStructure(vm, this, jsNull()));
-    m_activationStructure.set(vm, this, JSActivation::createStructure(vm, this, jsNull()));
+    
+    m_catchScopeStructure.set(vm, this, JSCatchScope::createStructure(vm, this, jsNull()));
+    m_functionNameScopeStructure.set(vm, this, JSFunctionNameScope::createStructure(vm, this, jsNull()));
+    m_lexicalEnvironmentStructure.set(vm, this, JSLexicalEnvironment::createStructure(vm, this));
     m_strictEvalActivationStructure.set(vm, this, StrictEvalActivation::createStructure(vm, this, jsNull()));
+    m_debuggerScopeStructure.set(m_vm, this, DebuggerScope::createStructure(m_vm, this));
     m_withScopeStructure.set(vm, this, JSWithScope::createStructure(vm, this, jsNull()));
-
+    
     m_nullPrototypeObjectStructure.set(vm, this, JSFinalObject::createStructure(vm, this, jsNull(), JSFinalObject::defaultInlineCapacity()));
-
+    
     m_callbackFunctionStructure.set(vm, this, JSCallbackFunction::createStructure(vm, this, m_functionPrototype.get()));
-    m_argumentsStructure.set(vm, this, Arguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_directArgumentsStructure.set(vm, this, DirectArguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_scopedArgumentsStructure.set(vm, this, ScopedArguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_outOfBandArgumentsStructure.set(vm, this, ClonedArguments::createStructure(vm, this, m_objectPrototype.get()));
     m_callbackConstructorStructure.set(vm, this, JSCallbackConstructor::createStructure(vm, this, m_objectPrototype.get()));
     m_callbackObjectStructure.set(vm, this, JSCallbackObject<JSDestructibleObject>::createStructure(vm, this, m_objectPrototype.get()));
 #if JSC_OBJC_API_ENABLED
     m_objcCallbackFunctionStructure.set(vm, this, ObjCCallbackFunction::createStructure(vm, this, m_functionPrototype.get()));
     m_objcWrapperObjectStructure.set(vm, this, JSCallbackObject<JSAPIWrapperObject>::createStructure(vm, this, m_objectPrototype.get()));
 #endif
-
+    
     m_arrayPrototype.set(vm, this, ArrayPrototype::create(vm, this, ArrayPrototype::createStructure(vm, this, m_objectPrototype.get())));
     
     m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithUndecided));
@@ -343,46 +335,62 @@ void JSGlobalObject::reset(JSValue prototype)
     m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
         m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
-    
-    m_regExpMatchesArrayStructure.set(vm, this, RegExpMatchesArray::createStructure(vm, this, m_arrayPrototype.get()));
 
     RegExp* emptyRegex = RegExp::create(vm, "", NoFlags);
     
     m_regExpPrototype.set(vm, this, RegExpPrototype::create(vm, RegExpPrototype::createStructure(vm, this, m_objectPrototype.get()), emptyRegex));
     m_regExpStructure.set(vm, this, RegExpObject::createStructure(vm, this, m_regExpPrototype.get()));
-
+    m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, *this));
+    
 #if ENABLE(PROMISES)
     m_promisePrototype.set(vm, this, JSPromisePrototype::create(exec, this, JSPromisePrototype::createStructure(vm, this, m_objectPrototype.get())));
     m_promiseStructure.set(vm, this, JSPromise::createStructure(vm, this, m_promisePrototype.get()));
 #endif // ENABLE(PROMISES)
 
-#define CREATE_PROTOTYPE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
-    m_ ## lowerName ## Prototype.set(vm, this, capitalName##Prototype::create(vm, this, capitalName##Prototype::createStructure(vm, this, m_objectPrototype.get()))); \
-    m_ ## properName ## Structure.set(vm, this, instanceType::createStructure(vm, this, m_ ## lowerName ## Prototype.get()));
+    m_parseIntFunction.set(vm, this, JSFunction::create(vm, this, 2, vm.propertyNames->parseInt.string(), globalFuncParseInt, NoIntrinsic));
+    putDirectWithoutTransition(vm, vm.propertyNames->parseInt, m_parseIntFunction.get(), DontEnum | Function);
 
+#define CREATE_PROTOTYPE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
+m_ ## lowerName ## Prototype.set(vm, this, capitalName##Prototype::create(vm, this, capitalName##Prototype::createStructure(vm, this, m_objectPrototype.get()))); \
+m_ ## properName ## Structure.set(vm, this, instanceType::createStructure(vm, this, m_ ## lowerName ## Prototype.get()));
+    
     FOR_EACH_SIMPLE_BUILTIN_TYPE(CREATE_PROTOTYPE_FOR_SIMPLE_TYPE)
-
+    
 #undef CREATE_PROTOTYPE_FOR_SIMPLE_TYPE
 
-    // Constructors
+    m_iteratorPrototype.set(vm, this, IteratorPrototype::create(vm, this, IteratorPrototype::createStructure(vm, this, m_objectPrototype.get())));
+
+#define CREATE_PROTOTYPE_FOR_DERIVED_ITERATOR_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
+m_ ## lowerName ## Prototype.set(vm, this, capitalName##Prototype::create(vm, this, capitalName##Prototype::createStructure(vm, this, m_iteratorPrototype.get()))); \
+m_ ## properName ## Structure.set(vm, this, instanceType::createStructure(vm, this, m_ ## lowerName ## Prototype.get()));
+    
+    FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(CREATE_PROTOTYPE_FOR_DERIVED_ITERATOR_TYPE)
+    
+#undef CREATE_PROTOTYPE_FOR_DERIVED_ITERATOR_TYPE
 
-    ObjectConstructor* objectConstructor = ObjectConstructor::create(vm, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
+    // Constructors
+    
+    ObjectConstructor* objectConstructor = ObjectConstructor::create(vm, this, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
     m_objectConstructor.set(vm, this, objectConstructor);
+
+    JSFunction* definePropertyFunction = m_objectConstructor->addDefineProperty(exec, this);
+    m_definePropertyFunction.set(vm, this, definePropertyFunction);
+
     JSCell* functionConstructor = FunctionConstructor::create(vm, FunctionConstructor::createStructure(vm, this, m_functionPrototype.get()), m_functionPrototype.get());
     JSCell* arrayConstructor = ArrayConstructor::create(vm, ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayPrototype.get());
-
+    
     m_regExpConstructor.set(vm, this, RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get()));
-
+    
 #define CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
-    capitalName ## Constructor* lowerName ## Constructor = capitalName ## Constructor::create(vm, capitalName ## Constructor::createStructure(vm, this, m_functionPrototype.get()), m_ ## lowerName ## Prototype.get()); \
-    m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, lowerName ## Constructor, DontEnum); \
+capitalName ## Constructor* lowerName ## Constructor = capitalName ## Constructor::create(vm, capitalName ## Constructor::createStructure(vm, this, m_functionPrototype.get()), m_ ## lowerName ## Prototype.get()); \
+m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, lowerName ## Constructor, DontEnum); \
 
     FOR_EACH_SIMPLE_BUILTIN_TYPE(CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE)
-
+    
 #undef CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE
-
+    
     m_errorConstructor.set(vm, this, errorConstructor);
-
+    
     Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(vm, this, m_errorPrototype.get());
     Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(vm, this, m_functionPrototype.get());
     m_evalErrorConstructor.set(vm, this, NativeErrorConstructor::create(vm, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError")));
@@ -394,7 +402,7 @@ void JSGlobalObject::reset(JSValue prototype)
 #if ENABLE(PROMISES)
     m_promiseConstructor.set(vm, this, JSPromiseConstructor::create(vm, JSPromiseConstructor::createStructure(vm, this, m_functionPrototype.get()), m_promisePrototype.get()));
 #endif
-
+    
     m_objectPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, objectConstructor, DontEnum);
     m_functionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, functionConstructor, DontEnum);
     m_arrayPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayConstructor, DontEnum);
@@ -402,7 +410,7 @@ void JSGlobalObject::reset(JSValue prototype)
 #if ENABLE(PROMISES)
     m_promisePrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_promiseConstructor.get(), DontEnum);
 #endif
-
+    
     putDirectWithoutTransition(vm, vm.propertyNames->Object, objectConstructor, DontEnum);
     putDirectWithoutTransition(vm, vm.propertyNames->Function, functionConstructor, DontEnum);
     putDirectWithoutTransition(vm, vm.propertyNames->Array, arrayConstructor, DontEnum);
@@ -414,55 +422,109 @@ void JSGlobalObject::reset(JSValue prototype)
     putDirectWithoutTransition(vm, vm.propertyNames->TypeError, m_typeErrorConstructor.get(), DontEnum);
     putDirectWithoutTransition(vm, vm.propertyNames->URIError, m_URIErrorConstructor.get(), DontEnum);
 #if ENABLE(PROMISES)
-    putDirectWithoutTransition(vm, vm.propertyNames->Promise, m_promiseConstructor.get(), DontEnum);
+    if (!m_runtimeFlags.isPromiseDisabled())
+        putDirectWithoutTransition(vm, vm.propertyNames->Promise, m_promiseConstructor.get(), DontEnum);
 #endif
-
-
+    
+    
 #define PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
-    putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Constructor, DontEnum); \
+putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Constructor, DontEnum); \
 
     FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE)
 
+    if (!m_runtimeFlags.isSymbolDisabled())
+        putDirectWithoutTransition(vm, vm.propertyNames->Symbol, symbolConstructor, DontEnum);
+
 #undef PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE
     PrototypeMap& prototypeMap = vm.prototypeMap;
     Structure* iteratorResultStructure = prototypeMap.emptyObjectStructureForPrototype(m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity());
     PropertyOffset offset;
-    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->done, 0, 0, offset);
-    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->value, 0, 0, offset);
+    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->done, 0, offset);
+    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->value, 0, offset);
     m_iteratorResultStructure.set(vm, this, iteratorResultStructure);
-
+    
     m_evalFunction.set(vm, this, JSFunction::create(vm, this, 1, vm.propertyNames->eval.string(), globalFuncEval));
     putDirectWithoutTransition(vm, vm.propertyNames->eval, m_evalFunction.get(), DontEnum);
-
+    
+#if ENABLE(INTL)
+    putDirectWithoutTransition(vm, vm.propertyNames->Intl, IntlObject::create(vm, IntlObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
+#endif // ENABLE(INTL)
     putDirectWithoutTransition(vm, vm.propertyNames->JSON, JSONObject::create(vm, JSONObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
     putDirectWithoutTransition(vm, vm.propertyNames->Math, MathObject::create(vm, this, MathObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
     
     std::array<InternalFunction*, NUMBER_OF_TYPED_ARRAY_TYPES> typedArrayConstructors;
-    typedArrayConstructors[toIndex(TypeInt8)] = JSInt8ArrayConstructor::create(vm, JSInt8ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt8)].prototype.get(), "Int8Array");
-    typedArrayConstructors[toIndex(TypeInt16)] = JSInt16ArrayConstructor::create(vm, JSInt16ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt16)].prototype.get(), "Int16Array");
-    typedArrayConstructors[toIndex(TypeInt32)] = JSInt32ArrayConstructor::create(vm, JSInt32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt32)].prototype.get(), "Int32Array");
-    typedArrayConstructors[toIndex(TypeUint8)] = JSUint8ArrayConstructor::create(vm, JSUint8ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint8)].prototype.get(), "Uint8Array");
-    typedArrayConstructors[toIndex(TypeUint8Clamped)] = JSUint8ClampedArrayConstructor::create(vm, JSUint8ClampedArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint8Clamped)].prototype.get(), "Uint8ClampedArray");
-    typedArrayConstructors[toIndex(TypeUint16)] = JSUint16ArrayConstructor::create(vm, JSUint16ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint16)].prototype.get(), "Uint16Array");
-    typedArrayConstructors[toIndex(TypeUint32)] = JSUint32ArrayConstructor::create(vm, JSUint32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint32)].prototype.get(), "Uint32Array");
-    typedArrayConstructors[toIndex(TypeFloat32)] = JSFloat32ArrayConstructor::create(vm, JSFloat32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeFloat32)].prototype.get(), "Float32Array");
-    typedArrayConstructors[toIndex(TypeFloat64)] = JSFloat64ArrayConstructor::create(vm, JSFloat64ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeFloat64)].prototype.get(), "Float64Array");
-    typedArrayConstructors[toIndex(TypeDataView)] = JSDataViewConstructor::create(vm, JSDataViewConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeDataView)].prototype.get(), "DataView");
-
+    typedArrayConstructors[toIndex(TypeInt8)] = JSInt8ArrayConstructor::create(vm, JSInt8ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt8)].prototype.get(), ASCIILiteral("Int8Array"));
+    typedArrayConstructors[toIndex(TypeInt16)] = JSInt16ArrayConstructor::create(vm, JSInt16ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt16)].prototype.get(), ASCIILiteral("Int16Array"));
+    typedArrayConstructors[toIndex(TypeInt32)] = JSInt32ArrayConstructor::create(vm, JSInt32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeInt32)].prototype.get(), ASCIILiteral("Int32Array"));
+    typedArrayConstructors[toIndex(TypeUint8)] = JSUint8ArrayConstructor::create(vm, JSUint8ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint8)].prototype.get(), ASCIILiteral("Uint8Array"));
+    typedArrayConstructors[toIndex(TypeUint8Clamped)] = JSUint8ClampedArrayConstructor::create(vm, JSUint8ClampedArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint8Clamped)].prototype.get(), ASCIILiteral("Uint8ClampedArray"));
+    typedArrayConstructors[toIndex(TypeUint16)] = JSUint16ArrayConstructor::create(vm, JSUint16ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint16)].prototype.get(), ASCIILiteral("Uint16Array"));
+    typedArrayConstructors[toIndex(TypeUint32)] = JSUint32ArrayConstructor::create(vm, JSUint32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeUint32)].prototype.get(), ASCIILiteral("Uint32Array"));
+    typedArrayConstructors[toIndex(TypeFloat32)] = JSFloat32ArrayConstructor::create(vm, JSFloat32ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeFloat32)].prototype.get(), ASCIILiteral("Float32Array"));
+    typedArrayConstructors[toIndex(TypeFloat64)] = JSFloat64ArrayConstructor::create(vm, JSFloat64ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeFloat64)].prototype.get(), ASCIILiteral("Float64Array"));
+    typedArrayConstructors[toIndex(TypeDataView)] = JSDataViewConstructor::create(vm, JSDataViewConstructor::createStructure(vm, this, m_functionPrototype.get()), m_typedArrays[toIndex(TypeDataView)].prototype.get(), ASCIILiteral("DataView"));
+    
     for (unsigned typedArrayIndex = NUMBER_OF_TYPED_ARRAY_TYPES; typedArrayIndex--;) {
         m_typedArrays[typedArrayIndex].prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, typedArrayConstructors[typedArrayIndex], DontEnum);
-        putDirectWithoutTransition(vm, Identifier(exec, typedArrayConstructors[typedArrayIndex]->name(exec)), typedArrayConstructors[typedArrayIndex], DontEnum);
+        putDirectWithoutTransition(vm, Identifier::fromString(exec, typedArrayConstructors[typedArrayIndex]->name(exec)), typedArrayConstructors[typedArrayIndex], DontEnum);
     }
     
     JSFunction* builtinLog = JSFunction::create(vm, this, 1, vm.propertyNames->emptyIdentifier.string(), globalFuncBuiltinLog);
+
+    JSFunction* privateFuncAbs = JSFunction::create(vm, this, 0, String(), mathProtoFuncAbs, AbsIntrinsic);
+    JSFunction* privateFuncFloor = JSFunction::create(vm, this, 0, String(), mathProtoFuncFloor, FloorIntrinsic);
+    JSFunction* privateFuncIsFinite = JSFunction::create(vm, this, 0, String(), globalFuncIsFinite);
+
+    JSFunction* privateFuncObjectKeys = JSFunction::create(vm, this, 0, String(), objectConstructorKeys);
+    JSFunction* privateFuncObjectGetOwnPropertyDescriptor = JSFunction::create(vm, this, 0, String(), objectConstructorGetOwnPropertyDescriptor);
+    JSFunction* privateFuncObjectGetOwnPropertySymbols = JSFunction::create(vm, this, 0, String(), objectConstructorGetOwnPropertySymbols);
+    JSFunction* privateFuncGetTemplateObject = JSFunction::create(vm, this, 0, String(), getTemplateObject);
+    JSFunction* privateFuncToLength = JSFunction::createBuiltinFunction(vm, globalObjectToLengthCodeGenerator(vm), this);
+    JSFunction* privateFuncToInteger = JSFunction::createBuiltinFunction(vm, globalObjectToIntegerCodeGenerator(vm), this);
+
     GlobalPropertyInfo staticGlobals[] = {
         GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->undefinedPrivateName, jsUndefined(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->objectKeysPrivateName, privateFuncObjectKeys, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->objectGetOwnPropertyDescriptorPrivateName, privateFuncObjectGetOwnPropertyDescriptor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->objectGetOwnPropertySymbolsPrivateName, privateFuncObjectGetOwnPropertySymbols, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->TypeErrorPrivateName, m_typeErrorConstructor.get(), DontEnum | DontDelete | ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly)
+        GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->absPrivateName, privateFuncAbs, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->floorPrivateName, privateFuncFloor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->getPrototypeOfPrivateName, privateFuncFloor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->getOwnPropertyNamesPrivateName, privateFuncFloor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->isFinitePrivateName, privateFuncIsFinite, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->arrayIterationKindKeyPrivateName, jsNumber(ArrayIterateKey), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->arrayIterationKindValuePrivateName, jsNumber(ArrayIterateValue), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->arrayIterationKindKeyValuePrivateName, jsNumber(ArrayIterateKeyValue), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->symbolIteratorPrivateName, Symbol::create(vm, static_cast<SymbolImpl&>(*vm.propertyNames->iteratorSymbol.impl())), DontEnum | DontDelete | ReadOnly),
+#if ENABLE(PROMISES)
+        GlobalPropertyInfo(vm.propertyNames->PromisePrivateName, m_promiseConstructor.get(), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->promisePendingPrivateName, jsNumber(static_cast<unsigned>(JSPromise::Status::Pending)), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->promiseFulfilledPrivateName, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->promiseRejectedPrivateName, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)), DontEnum | DontDelete | ReadOnly),
+#endif
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().toLengthPrivateName(), privateFuncToLength, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().toIntegerPrivateName(), privateFuncToInteger, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().isObjectPrivateName(), JSFunction::createBuiltinFunction(vm, globalObjectIsObjectCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().isPromisePrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseIsPromiseCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().newPromiseReactionPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseNewPromiseReactionCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().newPromiseCapabilityPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseNewPromiseCapabilityCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().triggerPromiseReactionsPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseTriggerPromiseReactionsCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().rejectPromisePrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseRejectPromiseCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().fulfillPromisePrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseFulfillPromiseCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().createResolvingFunctionsPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromiseCreateResolvingFunctionsCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().promiseReactionJobPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromisePromiseReactionJobCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().promiseResolveThenableJobPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromisePromiseResolveThenableJobCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
     };
     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
     
@@ -471,21 +533,75 @@ void JSGlobalObject::reset(JSValue prototype)
     m_specialPointers[Special::ObjectConstructor] = objectConstructor;
     m_specialPointers[Special::ArrayConstructor] = arrayConstructor;
 
+    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::DefinePropertyFunction)] = m_definePropertyFunction.get();
+
     ConsolePrototype* consolePrototype = ConsolePrototype::create(vm, this, ConsolePrototype::createStructure(vm, this, m_objectPrototype.get()));
     m_consoleStructure.set(vm, this, JSConsole::createStructure(vm, this, consolePrototype));
     JSConsole* consoleObject = JSConsole::create(vm, m_consoleStructure.get());
-    putDirectWithoutTransition(vm, Identifier(exec, "console"), consoleObject, DontEnum);
+    putDirectWithoutTransition(vm, Identifier::fromString(exec, "console"), consoleObject, DontEnum);
 
-    if (m_experimentsEnabled) {
-        NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(vm, this, m_objectPrototype.get()));
-        m_privateNameStructure.set(vm, this, NameInstance::createStructure(vm, this, privateNamePrototype));
-
-        JSCell* privateNameConstructor = NameConstructor::create(vm, NameConstructor::createStructure(vm, this, m_functionPrototype.get()), privateNamePrototype);
-        privateNamePrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, privateNameConstructor, DontEnum);
-        putDirectWithoutTransition(vm, Identifier(exec, "Name"), privateNameConstructor, DontEnum);
+    if (UNLIKELY(Options::enableDollarVM())) {
+        JSDollarVMPrototype* dollarVMPrototype = JSDollarVMPrototype::create(vm, this, JSDollarVMPrototype::createStructure(vm, this, m_objectPrototype.get()));
+        m_dollarVMStructure.set(vm, this, JSDollarVM::createStructure(vm, this, dollarVMPrototype));
+        JSDollarVM* dollarVM = JSDollarVM::create(vm, m_dollarVMStructure.get());
+        putDirectWithoutTransition(vm, Identifier::fromString(exec, "$vm"), dollarVM, DontEnum);
     }
 
-    resetPrototype(vm, prototype);
+    resetPrototype(vm, prototype());
+}
+
+void JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+    JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
+
+    if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode()))
+        return;
+    Base::put(thisObject, exec, propertyName, value, slot);
+}
+
+bool JSGlobalObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
+    PropertySlot slot(thisObject);
+    // silently ignore attempts to add accessors aliasing vars.
+    if (descriptor.isAccessorDescriptor() && symbolTableGet(thisObject, propertyName, slot))
+        return false;
+    return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
+}
+
+void JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)
+{
+    ConcurrentJITLocker locker(symbolTable()->m_lock);
+    SymbolTableEntry entry = symbolTable()->get(locker, ident.impl());
+    if (!entry.isNull())
+        return;
+    
+    ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
+    SymbolTableEntry newEntry(VarOffset(offset), (constantMode == IsConstant) ? ReadOnly : 0);
+    if (constantMode == IsVariable)
+        newEntry.prepareToWatch();
+    else
+        newEntry.disableWatching();
+    symbolTable()->add(locker, ident.impl(), newEntry);
+    
+    ScopeOffset offsetForAssert = addVariables(1);
+    RELEASE_ASSERT(offsetForAssert == offset);
+}
+
+void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName)
+{
+    VM& vm = exec->vm();
+    removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties.
+    addGlobalVar(propertyName, IsVariable);
+}
+
+static inline JSObject* lastInPrototypeChain(JSObject* object)
+{
+    JSObject* o = object;
+    while (o->prototype().isObject())
+        o = asObject(o->prototype());
+    return o;
 }
 
 // Private namespace for helpers for JSGlobalObject::haveABadTime()
@@ -494,9 +610,11 @@ namespace {
 class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor {
 public:
     ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer&, JSGlobalObject*);
-    void operator()(JSCell*);
+    IterationStatus operator()(JSCell*);
 
 private:
+    void visit(JSCell*);
+
     MarkedArgumentBuffer& m_foundObjects;
     JSGlobalObject* m_globalObject;
 };
@@ -517,7 +635,7 @@ inline bool hasBrokenIndexing(JSObject* object)
     return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasArrayStorage(type);
 }
 
-void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+inline void ObjectsWithBrokenIndexingFinder::visit(JSCell* cell)
 {
     if (!cell->isObject())
         return;
@@ -549,6 +667,12 @@ void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
     m_foundObjects.append(object);
 }
 
+IterationStatus ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+{
+    visit(cell);
+    return IterationStatus::Continue;
+}
+
 } // end private namespace for helpers for JSGlobalObject::haveABadTime()
 
 void JSGlobalObject::haveABadTime(VM& vm)
@@ -561,7 +685,7 @@ void JSGlobalObject::haveABadTime(VM& vm)
     // Make sure that all allocations or indexed storage transitions that are inlining
     // the assumption that it's safe to transition to a non-SlowPut array storage don't
     // do so anymore.
-    m_havingABadTimeWatchpoint->fireAll();
+    m_havingABadTimeWatchpoint->fireAll("Having a bad time");
     ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
     
     // Make sure that all JSArray allocations that load the appropriate structure from
@@ -608,9 +732,9 @@ bool JSGlobalObject::stringPrototypeChainIsSane()
 void JSGlobalObject::createThrowTypeError(VM& vm)
 {
     JSFunction* thrower = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeError);
-    GetterSetter* getterSetter = GetterSetter::create(vm);
-    getterSetter->setGetter(vm, thrower);
-    getterSetter->setSetter(vm, thrower);
+    GetterSetter* getterSetter = GetterSetter::create(vm, this);
+    getterSetter->setGetter(vm, this, thrower);
+    getterSetter->setSetter(vm, this, thrower);
     m_throwTypeErrorGetterSetter.set(vm, this, getterSetter);
 }
 
@@ -632,12 +756,11 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 { 
     JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
 
     visitor.append(&thisObject->m_globalThis);
 
+    visitor.append(&thisObject->m_globalCallee);
     visitor.append(&thisObject->m_regExpConstructor);
     visitor.append(&thisObject->m_errorConstructor);
     visitor.append(&thisObject->m_evalErrorConstructor);
@@ -651,24 +774,39 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_promiseConstructor);
 #endif
 
+    visitor.append(&thisObject->m_nullGetterFunction);
+    visitor.append(&thisObject->m_nullSetterFunction);
+
+    visitor.append(&thisObject->m_parseIntFunction);
     visitor.append(&thisObject->m_evalFunction);
     visitor.append(&thisObject->m_callFunction);
     visitor.append(&thisObject->m_applyFunction);
+    visitor.append(&thisObject->m_definePropertyFunction);
+    visitor.append(&thisObject->m_arrayProtoValuesFunction);
+#if ENABLE(PROMISES)
+    visitor.append(&thisObject->m_initializePromiseFunction);
+    visitor.append(&thisObject->m_newPromiseDeferredFunction);
+#endif
     visitor.append(&thisObject->m_throwTypeErrorGetterSetter);
 
     visitor.append(&thisObject->m_objectPrototype);
     visitor.append(&thisObject->m_functionPrototype);
     visitor.append(&thisObject->m_arrayPrototype);
     visitor.append(&thisObject->m_errorPrototype);
+    visitor.append(&thisObject->m_iteratorPrototype);
 #if ENABLE(PROMISES)
     visitor.append(&thisObject->m_promisePrototype);
 #endif
 
+    visitor.append(&thisObject->m_debuggerScopeStructure);
     visitor.append(&thisObject->m_withScopeStructure);
     visitor.append(&thisObject->m_strictEvalActivationStructure);
-    visitor.append(&thisObject->m_activationStructure);
-    visitor.append(&thisObject->m_nameScopeStructure);
-    visitor.append(&thisObject->m_argumentsStructure);
+    visitor.append(&thisObject->m_lexicalEnvironmentStructure);
+    visitor.append(&thisObject->m_catchScopeStructure);
+    visitor.append(&thisObject->m_functionNameScopeStructure);
+    visitor.append(&thisObject->m_directArgumentsStructure);
+    visitor.append(&thisObject->m_scopedArgumentsStructure);
+    visitor.append(&thisObject->m_outOfBandArgumentsStructure);
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
         visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]);
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
@@ -683,13 +821,15 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 #endif
     visitor.append(&thisObject->m_nullPrototypeObjectStructure);
     visitor.append(&thisObject->m_errorStructure);
+    visitor.append(&thisObject->m_calleeStructure);
     visitor.append(&thisObject->m_functionStructure);
     visitor.append(&thisObject->m_boundFunctionStructure);
     visitor.append(&thisObject->m_namedFunctionStructure);
-    visitor.append(&thisObject->m_privateNameStructure);
-    visitor.append(&thisObject->m_regExpMatchesArrayStructure);
+    visitor.append(&thisObject->m_symbolObjectStructure);
     visitor.append(&thisObject->m_regExpStructure);
+    visitor.append(&thisObject->m_regExpMatchesArrayStructure);
     visitor.append(&thisObject->m_consoleStructure);
+    visitor.append(&thisObject->m_dollarVMStructure);
     visitor.append(&thisObject->m_internalFunctionStructure);
 
 #if ENABLE(PROMISES)
@@ -701,6 +841,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_ ## properName ## Structure); \
 
     FOR_EACH_SIMPLE_BUILTIN_TYPE(VISIT_SIMPLE_TYPE)
+    FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(VISIT_SIMPLE_TYPE)
 
 #undef VISIT_SIMPLE_TYPE
 
@@ -724,30 +865,35 @@ ExecState* JSGlobalObject::globalExec()
 
 void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
 {
-    addRegisters(count);
+    ScopeOffset startOffset = addVariables(count);
 
     for (int i = 0; i < count; ++i) {
         GlobalPropertyInfo& global = globals[i];
         ASSERT(global.attributes & DontDelete);
         
-        int index = symbolTable()->size();
-        SymbolTableEntry newEntry(index, global.attributes);
-        symbolTable()->add(global.identifier.impl(), newEntry);
-        registerAt(index).set(vm(), this, global.value);
+        ScopeOffset offset;
+        {
+            ConcurrentJITLocker locker(symbolTable()->m_lock);
+            offset = symbolTable()->takeNextScopeOffset(locker);
+            RELEASE_ASSERT(offset = startOffset + i);
+            SymbolTableEntry newEntry(VarOffset(offset), global.attributes);
+            symbolTable()->add(locker, global.identifier.impl(), newEntry);
+        }
+        variableAt(offset).set(vm(), this, global.value);
     }
 }
 
 bool JSGlobalObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
-    if (getStaticFunctionSlot<Base>(exec, ExecState::globalObjectTable(exec->vm()), thisObject, propertyName, slot))
+    if (getStaticFunctionSlot<Base>(exec, globalObjectTable, thisObject, propertyName, slot))
         return true;
     return symbolTableGet(thisObject, propertyName, slot);
 }
 
 void JSGlobalObject::clearRareData(JSCell* cell)
 {
-    jsCast<JSGlobalObject*>(cell)->m_rareData.clear();
+    jsCast<JSGlobalObject*>(cell)->m_rareData = nullptr;
 }
 
 void slowValidateCell(JSGlobalObject* globalObject)
@@ -759,36 +905,39 @@ void slowValidateCell(JSGlobalObject* globalObject)
 UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* callFrame, ProgramExecutable* executable, JSObject** exception)
 {
     ParserError error;
-    JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
+    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
     DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
     ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
-    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getProgramCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
+    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getProgramCodeBlock(
+        vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, 
+        debuggerMode, profilerMode, error);
 
     if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
+        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
 
-    if (error.m_type != ParserError::ErrorNone) {
+    if (error.isValid()) {
         *exception = error.toErrorObject(this, executable->source());
-        return 0;
+        return nullptr;
     }
     
     return unlinkedCodeBlock;
 }
 
-UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable)
+UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode)
 {
     ParserError error;
-    JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
+    JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
     DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
     ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
-    UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
+    UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock(
+        vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, debuggerMode, profilerMode, error);
 
     if (hasDebugger())
-        debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
+        debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message());
 
-    if (error.m_type != ParserError::ErrorNone) {
+    if (error.isValid()) {
         throwVMError(callFrame, error.toErrorObject(this, executable->source()));
-        return 0;
+        return nullptr;
     }
 
     return unlinkedCodeBlock;
index 7bdcb72ac56f764bae4ba717f9d610b18a5ea581..594d966223378d1d1aab8f47595ade0822c18223 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *  Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #include "JSSegmentedVariableObject.h"
 #include "JSWeakObjectMapRefInternal.h"
 #include "NumberPrototype.h"
+#include "RuntimeFlags.h"
 #include "SpecialPointer.h"
 #include "StringPrototype.h"
 #include "StructureChain.h"
 #include "StructureRareDataInlines.h"
+#include "SymbolPrototype.h"
+#include "TemplateRegistry.h"
 #include "VM.h"
 #include "Watchpoint.h"
 #include <JavaScriptCore/JSBase.h>
 #include <array>
 #include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RandomNumber.h>
 
@@ -80,11 +82,17 @@ class ProgramExecutable;
 class RegExpConstructor;
 class RegExpPrototype;
 class SourceCode;
+class NullGetterFunction;
+class NullSetterFunction;
+enum class ThisTDZMode;
 struct ActivationStackNode;
 struct HashTable;
 
 #define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName)
-    
+
+#define FOR_EACH_EXPERIMENTAL_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
+    macro(Symbol, symbol, symbolObject, SymbolObject, Symbol) \
+
 #define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
     macro(Set, set, set, JSSet, Set) \
     macro(Map, map, map, JSMap, Map) \
@@ -95,21 +103,30 @@ struct HashTable;
     macro(Error, error, error, ErrorInstance, Error) \
     macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer) \
     DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
+    DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
 
-#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \
-    FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
+#define FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \
     DEFINE_STANDARD_BUILTIN(macro, ArrayIterator, arrayIterator) \
-    DEFINE_STANDARD_BUILTIN(macro, ArgumentsIterator, argumentsIterator) \
     DEFINE_STANDARD_BUILTIN(macro, MapIterator, mapIterator) \
     DEFINE_STANDARD_BUILTIN(macro, SetIterator, setIterator) \
+    DEFINE_STANDARD_BUILTIN(macro, StringIterator, stringIterator) \
 
+#define FOR_EACH_BUILTIN_ITERATOR_TYPE(macro) \
+    DEFINE_STANDARD_BUILTIN(macro, Iterator, iterator) \
+    FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \
+
+#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \
+    FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
+    FOR_EACH_EXPERIMENTAL_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
 
 #define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
     class JS ## capitalName; \
     class capitalName ## Prototype; \
     class capitalName ## Constructor;
 
+class IteratorPrototype;
 FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
+FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
 
 #undef DECLARE_SIMPLE_BUILTIN_TYPE
 
@@ -128,8 +145,8 @@ struct GlobalObjectMethodTable {
     typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
     ShouldInterruptScriptFunctionPtr shouldInterruptScript;
 
-    typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*);
-    JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled;
+    typedef RuntimeFlags (*JavaScriptRuntimeFlagsFunctionPtr)(const JSGlobalObject*);
+    JavaScriptRuntimeFlagsFunctionPtr javaScriptRuntimeFlags;
 
     typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, PassRefPtr<Microtask>);
     QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop;
@@ -160,6 +177,7 @@ protected:
 
     WriteBarrier<JSObject> m_globalThis;
 
+    WriteBarrier<JSObject> m_globalCallee;
     WriteBarrier<RegExpConstructor> m_regExpConstructor;
     WriteBarrier<ErrorConstructor> m_errorConstructor;
     WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
@@ -173,24 +191,40 @@ protected:
 #endif
     WriteBarrier<ObjectConstructor> m_objectConstructor;
 
+    WriteBarrier<NullGetterFunction> m_nullGetterFunction;
+    WriteBarrier<NullSetterFunction> m_nullSetterFunction;
+
+    WriteBarrier<JSFunction> m_parseIntFunction;
+
     WriteBarrier<JSFunction> m_evalFunction;
     WriteBarrier<JSFunction> m_callFunction;
     WriteBarrier<JSFunction> m_applyFunction;
+    WriteBarrier<JSFunction> m_definePropertyFunction;
+    WriteBarrier<JSFunction> m_arrayProtoValuesFunction;
+#if ENABLE(PROMISES)
+    WriteBarrier<JSFunction> m_initializePromiseFunction;
+    WriteBarrier<JSFunction> m_newPromiseDeferredFunction;
+#endif
     WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter;
 
     WriteBarrier<ObjectPrototype> m_objectPrototype;
     WriteBarrier<FunctionPrototype> m_functionPrototype;
     WriteBarrier<ArrayPrototype> m_arrayPrototype;
     WriteBarrier<RegExpPrototype> m_regExpPrototype;
+    WriteBarrier<IteratorPrototype> m_iteratorPrototype;
 #if ENABLE(PROMISES)
     WriteBarrier<JSPromisePrototype> m_promisePrototype;
 #endif
 
+    WriteBarrier<Structure> m_debuggerScopeStructure;
     WriteBarrier<Structure> m_withScopeStructure;
     WriteBarrier<Structure> m_strictEvalActivationStructure;
-    WriteBarrier<Structure> m_activationStructure;
-    WriteBarrier<Structure> m_nameScopeStructure;
-    WriteBarrier<Structure> m_argumentsStructure;
+    WriteBarrier<Structure> m_lexicalEnvironmentStructure;
+    WriteBarrier<Structure> m_catchScopeStructure;
+    WriteBarrier<Structure> m_functionNameScopeStructure;
+    WriteBarrier<Structure> m_directArgumentsStructure;
+    WriteBarrier<Structure> m_scopedArgumentsStructure;
+    WriteBarrier<Structure> m_outOfBandArgumentsStructure;
         
     // Lists the actual structures used for having these particular indexing shapes.
     WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
@@ -205,18 +239,21 @@ protected:
     WriteBarrier<Structure> m_objcWrapperObjectStructure;
 #endif
     WriteBarrier<Structure> m_nullPrototypeObjectStructure;
+    WriteBarrier<Structure> m_calleeStructure;
     WriteBarrier<Structure> m_functionStructure;
     WriteBarrier<Structure> m_boundFunctionStructure;
     WriteBarrier<Structure> m_namedFunctionStructure;
     PropertyOffset m_functionNameOffset;
     WriteBarrier<Structure> m_privateNameStructure;
-    WriteBarrier<Structure> m_regExpMatchesArrayStructure;
     WriteBarrier<Structure> m_regExpStructure;
     WriteBarrier<Structure> m_consoleStructure;
+    WriteBarrier<Structure> m_dollarVMStructure;
     WriteBarrier<Structure> m_internalFunctionStructure;
     
     WriteBarrier<Structure> m_iteratorResultStructure;
 
+    WriteBarrier<Structure> m_regExpMatchesArrayStructure;
+
 #if ENABLE(PROMISES)
     WriteBarrier<Structure> m_promiseStructure;
 #endif // ENABLE(PROMISES)
@@ -226,6 +263,7 @@ protected:
     WriteBarrier<Structure> m_ ## properName ## Structure;
 
     FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
+    FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
 
 #undef DEFINE_STORAGE_FOR_SIMPLE_TYPE
 
@@ -235,8 +273,9 @@ protected:
     };
     
     std::array<TypedArrayData, NUMBER_OF_TYPED_ARRAY_TYPES> m_typedArrays;
-        
-    void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
+
+    JSCell* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
+    JSCell* m_linkTimeConstants[LinkTimeConstantCount];
 
     String m_name;
 
@@ -257,13 +296,15 @@ protected:
     RefPtr<WatchpointSet> m_havingABadTimeWatchpoint;
     RefPtr<WatchpointSet> m_varInjectionWatchpoint;
 
-    OwnPtr<JSGlobalObjectRareData> m_rareData;
+    std::unique_ptr<JSGlobalObjectRareData> m_rareData;
 
     WeakRandom m_weakRandom;
 
+    TemplateRegistry m_templateRegistry;
+
     bool m_evalEnabled;
     String m_evalDisabledErrorMessage;
-    bool m_experimentsEnabled;
+    RuntimeFlags m_runtimeFlags;
     ConsoleClient* m_consoleClient;
 
     static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
@@ -273,15 +314,16 @@ protected:
     {
         if (m_rareData)
             return;
-        m_rareData = adoptPtr(new JSGlobalObjectRareData);
+        m_rareData = std::make_unique<JSGlobalObjectRareData>();
     }
         
 public:
     typedef JSSegmentedVariableObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
-    static JSGlobalObject* create(VM& vm, Structure* structure)
+    static JSGlobalObject* create(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = nullptr)
     {
-        JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
+        JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure, globalObjectMethodTable);
         globalObject->finishCreation(vm);
         vm.heap.addFinalizer(globalObject, destroy);
         return globalObject;
@@ -291,6 +333,7 @@ public:
 
     bool hasDebugger() const { return m_debugger; }
     bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); }
+    const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; }
 
 protected:
     JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0);
@@ -299,8 +342,8 @@ protected:
     {
         Base::finishCreation(vm);
         structure()->setGlobalObject(vm, this);
-        m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
-        init();
+        m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
+        init(vm);
         setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, prototype(), PureForwardingProxyType), this));
     }
 
@@ -308,16 +351,12 @@ protected:
     {
         Base::finishCreation(vm);
         structure()->setGlobalObject(vm, this);
-        m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
-        init();
+        m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
+        init(vm);
         setGlobalThis(vm, thisValue);
     }
 
-    struct NewGlobalVar {
-        int registerNumber;
-        VariableWatchpointSet* set;
-    };
-    NewGlobalVar addGlobalVar(const Identifier&, ConstantMode);
+    void addGlobalVar(const Identifier&, ConstantMode);
 
 public:
     JS_EXPORT_PRIVATE ~JSGlobalObject();
@@ -349,7 +388,7 @@ public:
         if (!hasProperty(exec, propertyName))
             addGlobalVar(propertyName, IsConstant);
     }
-    void addFunction(ExecState*, const Identifier&, JSValue);
+    void addFunction(ExecState*, const Identifier&);
 
     // The following accessors return pristine values, even if a script 
     // replaces the global object's associated property.
@@ -368,9 +407,20 @@ public:
     JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); }
 #endif
 
+    NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); }
+    NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); }
+
+    JSFunction* parseIntFunction() const { return m_parseIntFunction.get(); }
+
     JSFunction* evalFunction() const { return m_evalFunction.get(); }
     JSFunction* callFunction() const { return m_callFunction.get(); }
     JSFunction* applyFunction() const { return m_applyFunction.get(); }
+    JSFunction* definePropertyFunction() const { return m_definePropertyFunction.get(); }
+    JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(); }
+#if ENABLE(PROMISES)
+    JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(); }
+    JSFunction* newPromiseDeferredFunction() const { return m_newPromiseDeferredFunction.get(); }
+#endif
     GetterSetter* throwTypeErrorGetterSetter(VM& vm)
     {
         if (!m_throwTypeErrorGetterSetter)
@@ -383,19 +433,25 @@ public:
     ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
     BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
     StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
+    SymbolPrototype* symbolPrototype() const { return m_symbolPrototype.get(); }
     NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
     DatePrototype* datePrototype() const { return m_datePrototype.get(); }
     RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
     ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); }
+    IteratorPrototype* iteratorPrototype() const { return m_iteratorPrototype.get(); }
 #if ENABLE(PROMISES)
     JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); }
 #endif
 
+    Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(); }
     Structure* withScopeStructure() const { return m_withScopeStructure.get(); }
     Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
-    Structure* activationStructure() const { return m_activationStructure.get(); }
-    Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
-    Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+    Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
+    Structure* catchScopeStructure() const { return m_catchScopeStructure.get(); }
+    Structure* functionNameScopeStructure() const { return m_functionNameScopeStructure.get(); }
+    Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
+    Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); }
+    Structure* outOfBandArgumentsStructure() const { return m_outOfBandArgumentsStructure.get(); }
     Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
     {
         ASSERT(indexingType & IsArray);
@@ -427,6 +483,7 @@ public:
     Structure* dateStructure() const { return m_dateStructure.get(); }
     Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
     Structure* errorStructure() const { return m_errorStructure.get(); }
+    Structure* calleeStructure() const { return m_calleeStructure.get(); }
     Structure* functionStructure() const { return m_functionStructure.get(); }
     Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
     Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
@@ -435,12 +492,13 @@ public:
     Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
     Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
     Structure* mapStructure() const { return m_mapStructure.get(); }
-    Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
     Structure* regExpStructure() const { return m_regExpStructure.get(); }
     Structure* setStructure() const { return m_setStructure.get(); }
     Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+    Structure* symbolObjectStructure() const { return m_symbolObjectStructure.get(); }
     Structure* iteratorResultStructure() const { return m_iteratorResultStructure.get(); }
     static ptrdiff_t iteratorResultStructureOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_iteratorResultStructure); }
+    Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
 
 #if ENABLE(PROMISES)
     Structure* promiseStructure() const { return m_promiseStructure.get(); }
@@ -459,7 +517,7 @@ public:
     JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); }
 #endif
 
-    JS_EXPORT_PRIVATE void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; }
+    void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; }
     ConsoleClient* consoleClient() const { return m_consoleClient; }
 
     void setName(const String&);
@@ -471,6 +529,7 @@ public:
     Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); }
 
     FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
+    FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
 
 #undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE
 
@@ -486,11 +545,17 @@ public:
         return typedArrayStructure(type) == structure;
     }
 
-    void* actualPointerFor(Special::Pointer pointer)
+    JSCell* actualPointerFor(Special::Pointer pointer)
     {
         ASSERT(pointer < Special::TableSize);
         return m_specialPointers[pointer];
     }
+    JSCell* jsCellForLinkTimeConstant(LinkTimeConstant type)
+    {
+        unsigned index = static_cast<unsigned>(type);
+        ASSERT(index < LinkTimeConstantCount);
+        return m_linkTimeConstants[index];
+    }
 
     WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
     WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
@@ -528,7 +593,7 @@ public:
 
     static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
     static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; }
-    static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; }
+    static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); }
 
     void queueMicrotask(PassRefPtr<Microtask>);
 
@@ -568,16 +633,15 @@ public:
         return m_rareData->opaqueJSClassData;
     }
 
+    TemplateRegistry& templateRegistry() { return m_templateRegistry; }
+
     double weakRandomNumber() { return m_weakRandom.get(); }
     unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
 
     UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
-    UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*);
+    UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode);
 
 protected:
-
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
-
     struct GlobalPropertyInfo {
         GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
             : identifier(i)
@@ -599,9 +663,7 @@ private:
 
     JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis);
 
-    // FIXME: Fold reset into init.
-    JS_EXPORT_PRIVATE void init();
-    void reset(JSValue prototype);
+    JS_EXPORT_PRIVATE void init(VM&);
 
     void createThrowTypeError(VM&);
 
@@ -633,7 +695,7 @@ inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
 
 inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0)
 {
-    return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
+    return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
 }
 
 inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0)
@@ -671,6 +733,11 @@ inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationPr
     return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length);
 }
 
+inline JSObject* ExecState::globalThisValue() const
+{
+    return lexicalGlobalObject()->globalThis();
+}
+
 inline JSObject* JSScope::globalThis()
 { 
     return globalObject()->globalThis();
index 05e0d87b1658570dc25fa246491a45242db27fab..eecc5ba030ab540ca5e43ddd5aa8ad22c373691e 100644 (file)
@@ -31,6 +31,7 @@
 #include "InspectorAgentBase.h"
 #include "InspectorFrontendChannel.h"
 #include "JSGlobalObject.h"
+#include "JSLock.h"
 #include "RemoteInspector.h"
 
 using namespace Inspector;
@@ -48,18 +49,25 @@ String JSGlobalObjectDebuggable::name() const
     return name.isEmpty() ? ASCIILiteral("JSContext") : name;
 }
 
-void JSGlobalObjectDebuggable::connect(InspectorFrontendChannel* frontendChannel)
+void JSGlobalObjectDebuggable::connect(FrontendChannel* frontendChannel, bool automaticInspection)
 {
     JSLockHolder locker(&m_globalObject.vm());
 
-    m_globalObject.inspectorController().connectFrontend(frontendChannel);
+    m_globalObject.inspectorController().connectFrontend(frontendChannel, automaticInspection);
 }
 
 void JSGlobalObjectDebuggable::disconnect()
 {
     JSLockHolder locker(&m_globalObject.vm());
 
-    m_globalObject.inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
+    m_globalObject.inspectorController().disconnectFrontend(DisconnectReason::InspectorDestroyed);
+}
+
+void JSGlobalObjectDebuggable::pause()
+{
+    JSLockHolder locker(&m_globalObject.vm());
+
+    m_globalObject.inspectorController().pause();
 }
 
 void JSGlobalObjectDebuggable::dispatchMessageFromRemoteFrontend(const String& message)
@@ -69,6 +77,12 @@ void JSGlobalObjectDebuggable::dispatchMessageFromRemoteFrontend(const String& m
     m_globalObject.inspectorController().dispatchMessageFromFrontend(message);
 }
 
+void JSGlobalObjectDebuggable::pauseWaitingForAutomaticInspection()
+{
+    JSC::JSLock::DropAllLocks dropAllLocks(&m_globalObject.vm());
+    RemoteInspectorDebuggable::pauseWaitingForAutomaticInspection();
+}
+
 } // namespace JSC
 
 #endif // ENABLE(REMOTE_INSPECTOR)
index 9f4b6e87ffe2c1162bc0b9157cc41d16f00907f6..60ce58a44c79359a7739a9079b9930dd12aba394 100644 (file)
@@ -33,7 +33,8 @@
 #include <wtf/Noncopyable.h>
 
 namespace Inspector {
-enum class InspectorDisconnectReason;
+class FrontendChannel;
+enum class DisconnectReason;
 }
 
 namespace JSC {
@@ -41,6 +42,7 @@ namespace JSC {
 class JSGlobalObject;
 
 class JSGlobalObjectDebuggable final : public Inspector::RemoteInspectorDebuggable {
+    WTF_MAKE_FAST_ALLOCATED;
     WTF_MAKE_NONCOPYABLE(JSGlobalObjectDebuggable);
 public:
     JSGlobalObjectDebuggable(JSGlobalObject&);
@@ -51,9 +53,13 @@ public:
     virtual String name() const override;
     virtual bool hasLocalDebugger() const override { return false; }
 
-    virtual void connect(Inspector::InspectorFrontendChannel*) override;
+    virtual void connect(Inspector::FrontendChannel*, bool automaticInspection) override;
     virtual void disconnect() override;
     virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
+    virtual void pause() override;
+
+    virtual bool automaticInspectionAllowed() const override { return true; }
+    virtual void pauseWaitingForAutomaticInspection() override;
 
 private:
     JSGlobalObject& m_globalObject;
index 604de2b1800f80990dc2cc8bebca80e5e9fdaa57..45a24ecd20d3c17efe43a49408069219622838e7 100644 (file)
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/Assertions.h>
+#include <wtf/HexNumber.h>
 #include <wtf/MathExtras.h>
 #include <wtf/StringExtras.h>
 #include <wtf/text/StringBuilder.h>
@@ -52,9 +53,18 @@ using namespace Unicode;
 
 namespace JSC {
 
-static JSValue encode(ExecState* exec, const char* doNotEscape)
+template<unsigned charactersCount>
+static Bitmap<256> makeCharacterBitmap(const char (&characters)[charactersCount])
 {
-    CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(StrictConversion);
+    Bitmap<256> bitmap;
+    for (unsigned i = 0; i < charactersCount; ++i)
+        bitmap.set(characters[i]);
+    return bitmap;
+}
+
+static JSValue encode(ExecState* exec, const Bitmap<256>& doNotEscape)
+{
+    CString cstr = exec->argument(0).toString(exec)->view(exec).get().utf8(StrictConversion);
     if (!cstr.data())
         return exec->vm().throwException(exec, createURIError(exec, ASCIILiteral("String contained an illegal UTF-16 sequence.")));
 
@@ -62,12 +72,11 @@ static JSValue encode(ExecState* exec, const char* doNotEscape)
     const char* p = cstr.data();
     for (size_t k = 0; k < cstr.length(); k++, p++) {
         char c = *p;
-        if (c && strchr(doNotEscape, c))
+        if (c && doNotEscape.get(static_cast<LChar>(c)))
             builder.append(static_cast<LChar>(c));
         else {
-            char tmp[4];
-            snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c));
-            builder.append(tmp);
+            builder.append(static_cast<LChar>('%'));
+            appendByteAsHex(c, builder);
         }
     }
     return builder.build(exec);
@@ -75,7 +84,7 @@ static JSValue encode(ExecState* exec, const char* doNotEscape)
 
 template <typename CharType>
 ALWAYS_INLINE
-static JSValue decode(ExecState* exec, const CharType* characters, int length, const char* doNotUnescape, bool strict)
+static JSValue decode(ExecState* exec, const CharType* characters, int length, const Bitmap<256>& doNotUnescape, bool strict)
 {
     JSStringBuilder builder;
     int k = 0;
@@ -127,7 +136,7 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c
                     u = Lexer<UChar>::convertUnicode(p[2], p[3], p[4], p[5]);
                 }
             }
-            if (charLen && (u == 0 || u >= 128 || !strchr(doNotUnescape, u))) {
+            if (charLen && (u == 0 || u >= 128 || !doNotUnescape.get(static_cast<LChar>(u)))) {
                 builder.append(u);
                 k += charLen;
                 continue;
@@ -139,9 +148,9 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c
     return builder.build(exec);
 }
 
-static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict)
+static JSValue decode(ExecState* exec, const Bitmap<256>& doNotUnescape, bool strict)
 {
-    String str = exec->argument(0).toString(exec)->value(exec);
+    StringView str = exec->argument(0).toString(exec)->view(exec);
     
     if (str.is8Bit())
         return decode(exec, str.characters8(), str.length(), doNotUnescape, strict);
@@ -239,7 +248,7 @@ static double parseIntOverflow(StringView string, int radix)
 // ES5.1 15.1.2.2
 template <typename CharType>
 ALWAYS_INLINE
-static double parseInt(const String& s, const CharType* data, int radix)
+static double parseInt(StringView s, const CharType* data, int radix)
 {
     // 1. Let inputString be ToString(string).
     // 2. Let S be a newly created substring of inputString consisting of the first character that is not a
@@ -311,16 +320,16 @@ static double parseInt(const String& s, const CharType* data, int radix)
     if (number >= mantissaOverflowLowerBound) {
         if (radix == 10) {
             size_t parsedLength;
-            number = parseDouble(StringView(s).substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
+            number = parseDouble(s.substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
         } else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
-            number = parseIntOverflow(StringView(s).substring(firstDigitPosition, p - firstDigitPosition), radix);
+            number = parseIntOverflow(s.substring(firstDigitPosition, p - firstDigitPosition), radix);
     }
 
     // 15. Return sign x number.
     return sign * number;
 }
 
-static double parseInt(const String& s, int radix)
+static double parseInt(StringView s, int radix)
 {
     if (s.is8Bit())
         return parseInt(s, s.characters8(), radix);
@@ -343,7 +352,51 @@ static bool isInfinity(const CharType* data, const CharType* end)
         && data[7] == 'y';
 }
 
-// See ecma-262 9.3.1
+// See ecma-262 6th 11.8.3
+template <typename CharType>
+static double jsBinaryIntegerLiteral(const CharType*& data, const CharType* end)
+{
+    // Binary number.
+    data += 2;
+    const CharType* firstDigitPosition = data;
+    double number = 0;
+    while (true) {
+        number = number * 2 + (*data - '0');
+        ++data;
+        if (data == end)
+            break;
+        if (!isASCIIBinaryDigit(*data))
+            break;
+    }
+    if (number >= mantissaOverflowLowerBound)
+        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 2);
+
+    return number;
+}
+
+// See ecma-262 6th 11.8.3
+template <typename CharType>
+static double jsOctalIntegerLiteral(const CharType*& data, const CharType* end)
+{
+    // Octal number.
+    data += 2;
+    const CharType* firstDigitPosition = data;
+    double number = 0;
+    while (true) {
+        number = number * 8 + (*data - '0');
+        ++data;
+        if (data == end)
+            break;
+        if (!isASCIIOctalDigit(*data))
+            break;
+    }
+    if (number >= mantissaOverflowLowerBound)
+        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 8);
+    
+    return number;
+}
+
+// See ecma-262 6th 11.8.3
 template <typename CharType>
 static double jsHexIntegerLiteral(const CharType*& data, const CharType* end)
 {
@@ -365,7 +418,7 @@ static double jsHexIntegerLiteral(const CharType*& data, const CharType* end)
     return number;
 }
 
-// See ecma-262 9.3.1
+// See ecma-262 6th 11.8.3
 template <typename CharType>
 static double jsStrDecimalLiteral(const CharType*& data, const CharType* end)
 {
@@ -422,9 +475,16 @@ static double toDouble(const CharType* characters, unsigned size)
         return 0.0;
     
     double number;
-    if (characters[0] == '0' && characters + 2 < endCharacters && (characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2]))
-        number = jsHexIntegerLiteral(characters, endCharacters);
-    else
+    if (characters[0] == '0' && characters + 2 < endCharacters) {
+        if ((characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2]))
+            number = jsHexIntegerLiteral(characters, endCharacters);
+        else if ((characters[1] | 0x20) == 'o' && isASCIIOctalDigit(characters[2]))
+            number = jsOctalIntegerLiteral(characters, endCharacters);
+        else if ((characters[1] | 0x20) == 'b' && isASCIIBinaryDigit(characters[2]))
+            number = jsBinaryIntegerLiteral(characters, endCharacters);
+        else
+            number = jsStrDecimalLiteral(characters, endCharacters);
+    } else
         number = jsStrDecimalLiteral(characters, endCharacters);
     
     // Allow trailing white space.
@@ -438,8 +498,8 @@ static double toDouble(const CharType* characters, unsigned size)
     return number;
 }
 
-// See ecma-262 9.3.1
-double jsToNumber(const String& s)
+// See ecma-262 6th 11.8.3
+double jsToNumber(StringView s)
 {
     unsigned size = s.length();
 
@@ -457,7 +517,7 @@ double jsToNumber(const String& s)
     return toDouble(s.characters16(), size);
 }
 
-static double parseFloat(const String& s)
+static double parseFloat(StringView s)
 {
     unsigned size = s.length();
 
@@ -520,7 +580,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
     }
 
     JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject();
-    EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false);
+    EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded);
     if (!eval)
         return JSValue::encode(jsUndefined());
 
@@ -550,7 +610,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
     }
 
     // If ToString throws, we shouldn't call ToInt32.
-    String s = value.toString(exec)->value(exec);
+    StringView s = value.toString(exec)->view(exec);
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
@@ -559,7 +619,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
 {
-    return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->value(exec))));
+    return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->view(exec))));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec)
@@ -575,59 +635,63 @@ EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec)
 {
-    static const char do_not_unescape_when_decoding_URI[] =
-        "#$&+,/:;=?@";
+    static Bitmap<256> doNotUnescapeWhenDecodingURI = makeCharacterBitmap(
+        "#$&+,/:;=?@"
+    );
 
-    return JSValue::encode(decode(exec, do_not_unescape_when_decoding_URI, true));
+    return JSValue::encode(decode(exec, doNotUnescapeWhenDecodingURI, true));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec)
 {
-    return JSValue::encode(decode(exec, "", true));
+    static Bitmap<256> emptyBitmap;
+    return JSValue::encode(decode(exec, emptyBitmap, true));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec)
 {
-    static const char do_not_escape_when_encoding_URI[] =
+    static Bitmap<256> doNotEscapeWhenEncodingURI = makeCharacterBitmap(
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
         "abcdefghijklmnopqrstuvwxyz"
         "0123456789"
-        "!#$&'()*+,-./:;=?@_~";
+        "!#$&'()*+,-./:;=?@_~"
+    );
 
-    return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI));
+    return JSValue::encode(encode(exec, doNotEscapeWhenEncodingURI));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec)
 {
-    static const char do_not_escape_when_encoding_URI_component[] =
+    static Bitmap<256> doNotEscapeWhenEncodingURIComponent = makeCharacterBitmap(
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
         "abcdefghijklmnopqrstuvwxyz"
         "0123456789"
-        "!'()*-._~";
+        "!'()*-._~"
+    );
 
-    return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI_component));
+    return JSValue::encode(encode(exec, doNotEscapeWhenEncodingURIComponent));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
 {
-    static const char do_not_escape[] =
+    static Bitmap<256> doNotEscape = makeCharacterBitmap(
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
         "abcdefghijklmnopqrstuvwxyz"
         "0123456789"
-        "*+-./@_";
+        "*+-./@_"
+    );
 
     JSStringBuilder builder;
-    String str = exec->argument(0).toString(exec)->value(exec);
+    StringView str = exec->argument(0).toString(exec)->view(exec);
     if (str.is8Bit()) {
         const LChar* c = str.characters8();
         for (unsigned k = 0; k < str.length(); k++, c++) {
             int u = c[0];
-            if (u && strchr(do_not_escape, static_cast<char>(u)))
+            if (u && doNotEscape.get(static_cast<LChar>(u)))
                 builder.append(*c);
             else {
-                char tmp[4];
-                snprintf(tmp, sizeof(tmp), "%%%02X", u);
-                builder.append(tmp);
+                builder.append(static_cast<LChar>('%'));
+                appendByteAsHex(static_cast<LChar>(u), builder);
             }
         }
 
@@ -638,15 +702,15 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
     for (unsigned k = 0; k < str.length(); k++, c++) {
         int u = c[0];
         if (u > 255) {
-            char tmp[7];
-            snprintf(tmp, sizeof(tmp), "%%u%04X", u);
-            builder.append(tmp);
-        } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u)))
+            builder.append(static_cast<LChar>('%'));
+            builder.append(static_cast<LChar>('u'));
+            appendByteAsHex(u >> 8, builder);
+            appendByteAsHex(u & 0xFF, builder);
+        } else if (u != 0 && doNotEscape.get(static_cast<LChar>(u)))
             builder.append(*c);
         else {
-            char tmp[4];
-            snprintf(tmp, sizeof(tmp), "%%%02X", u);
-            builder.append(tmp);
+            builder.append(static_cast<LChar>('%'));
+            appendByteAsHex(u, builder);
         }
     }
 
@@ -656,7 +720,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
 EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
 {
     StringBuilder builder;
-    String str = exec->argument(0).toString(exec)->value(exec);
+    StringView str = exec->argument(0).toString(exec)->view(exec);
     int k = 0;
     int len = str.length();
     
@@ -741,6 +805,9 @@ private:
 
 EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState* exec)
 {
+    if (exec->thisValue().isUndefinedOrNull()) 
+        return throwVMError(exec, createTypeError(exec, "Can't convert undefined or null to object"));
+
     JSObject* thisObject = jsDynamicCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode));
 
     if (!thisObject)
@@ -779,8 +846,18 @@ private:
     JSObject* m_thisObject;
 };
 
+bool checkProtoSetterAccessAllowed(ExecState* exec, JSObject* object)
+{
+    GlobalFuncProtoSetterFunctor functor(object);
+    exec->iterate(functor);
+    return functor.allowsAccess();
+}
+
 EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
 {
+    if (exec->thisValue().isUndefinedOrNull()) 
+        return throwVMError(exec, createTypeError(exec, "Can't convert undefined or null to object"));
+
     JSValue value = exec->argument(0);
 
     JSObject* thisObject = jsDynamicCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode));
@@ -789,9 +866,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
     if (!thisObject)
         return JSValue::encode(jsUndefined());
 
-    GlobalFuncProtoSetterFunctor functor(thisObject);
-    exec->iterate(functor);
-    if (!functor.allowsAccess())
+    if (!checkProtoSetterAccessAllowed(exec, thisObject))
         return JSValue::encode(jsUndefined());
 
     // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
@@ -802,7 +877,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
         return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
 
     if (!thisObject->setPrototypeWithCycleCheck(exec, value))
-        exec->vm().throwException(exec, createError(exec, "cyclic __proto__ value"));
+        exec->vm().throwException(exec, createError(exec, ASCIILiteral("cyclic __proto__ value")));
     return JSValue::encode(jsUndefined());
 }
     
index 2922d613e3ae438951ba71b01b52e1195b7c1ecd..b929f51432a3f398f397b3c896712b1cdf8c8289 100644 (file)
@@ -52,11 +52,13 @@ EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState*);
 EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
 EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
 EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*);
-    
+
+bool checkProtoSetterAccessAllowed(ExecState*, JSObject*);
+
 static const double mantissaOverflowLowerBound = 9007199254740992.0;
 double parseIntOverflow(const LChar*, unsigned length, int radix);
 bool isStrWhiteSpace(UChar);
-double jsToNumber(const WTF::String&);
+double jsToNumber(StringView);
 
 } // namespace JSC
 
diff --git a/runtime/JSJob.cpp b/runtime/JSJob.cpp
new file mode 100644 (file)
index 0000000..92d2122
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSJob.h"
+
+#include "Error.h"
+#include "Exception.h"
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "JSGlobalObject.h"
+#include "Microtask.h"
+#include "SlotVisitorInlines.h"
+#include "StrongInlines.h"
+
+namespace JSC {
+
+class JSJobMicrotask final : public Microtask {
+public:
+    JSJobMicrotask(VM& vm, JSValue job, JSArray* arguments)
+    {
+        m_job.set(vm, job);
+        m_arguments.set(vm, arguments);
+    }
+
+    virtual ~JSJobMicrotask()
+    {
+    }
+
+private:
+    virtual void run(ExecState*) override;
+
+    Strong<Unknown> m_job;
+    Strong<JSArray> m_arguments;
+};
+
+Ref<Microtask> createJSJob(VM& vm, JSValue job, JSArray* arguments)
+{
+    return adoptRef(*new JSJobMicrotask(vm, job, arguments));
+}
+
+void JSJobMicrotask::run(ExecState* exec)
+{
+    CallData handlerCallData;
+    CallType handlerCallType = getCallData(m_job.get(), handlerCallData);
+    ASSERT(handlerCallType != CallTypeNone);
+
+    MarkedArgumentBuffer handlerArguments;
+    for (unsigned index = 0, length = m_arguments->length(); index < length; ++index)
+        handlerArguments.append(m_arguments->JSArray::get(exec, index));
+    call(exec, m_job.get(), handlerCallType, handlerCallData, jsUndefined(), handlerArguments);
+}
+
+} // namespace JSC
diff --git a/runtime/JSJob.h b/runtime/JSJob.h
new file mode 100644 (file)
index 0000000..0147c83
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSJob_h
+#define JSJob_h
+
+#include "JSCell.h"
+#include "Structure.h"
+
+namespace JSC {
+
+class Microtask;
+class JSArray;
+
+Ref<Microtask> createJSJob(VM&, JSValue job, JSArray* arguments);
+
+} // namespace JSC
+
+#endif // JSJob_h
diff --git a/runtime/JSLexicalEnvironment.cpp b/runtime/JSLexicalEnvironment.cpp
new file mode 100644 (file)
index 0000000..183f484
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSLexicalEnvironment.h"
+
+#include "Interpreter.h"
+#include "JSFunction.h"
+#include "JSCInlines.h"
+
+using namespace std;
+
+namespace JSC {
+
+const ClassInfo JSLexicalEnvironment::s_info = { "JSLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSLexicalEnvironment) };
+
+inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
+{
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
+    if (entry.isNull())
+        return false;
+
+    ScopeOffset offset = entry.scopeOffset();
+
+    // Defend against the inspector asking for a var after it has been optimized out.
+    if (!isValid(offset))
+        return false;
+
+    slot.setValue(this, DontEnum, variableAt(offset).get());
+    return true;
+}
+
+inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor)
+{
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
+    if (entry.isNull())
+        return false;
+
+    ScopeOffset offset = entry.scopeOffset();
+
+    // Defend against the inspector asking for a var after it has been optimized out.
+    if (!isValid(offset))
+        return false;
+
+    descriptor.setDescriptor(variableAt(offset).get(), entry.getAttributes());
+    return true;
+}
+
+inline bool JSLexicalEnvironment::symbolTablePut(ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrow)
+{
+    VM& vm = exec->vm();
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+    
+    WriteBarrierBase<Unknown>* reg;
+    WatchpointSet* set;
+    {
+        GCSafeConcurrentJITLocker locker(symbolTable()->m_lock, exec->vm().heap);
+        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.uid());
+        if (iter == symbolTable()->end(locker))
+            return false;
+        ASSERT(!iter->value.isNull());
+        if (iter->value.isReadOnly()) {
+            if (shouldThrow)
+                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+            return true;
+        }
+        ScopeOffset offset = iter->value.scopeOffset();
+        // Defend against the inspector asking for a var after it has been optimized out.
+        if (!isValid(offset))
+            return false;
+        set = iter->value.watchpointSet();
+        reg = &variableAt(offset);
+    }
+    reg->set(vm, this, value);
+    if (set)
+        set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
+    return true;
+}
+
+void JSLexicalEnvironment::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(object);
+
+    {
+        ConcurrentJITLocker locker(thisObject->symbolTable()->m_lock);
+        SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker);
+        for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
+            if (it->value.getAttributes() & DontEnum && !mode.includeDontEnumProperties())
+                continue;
+            if (!thisObject->isValid(it->value.scopeOffset()))
+                continue;
+            if (it->key->isSymbol() && !mode.includeSymbolProperties())
+                continue;
+            propertyNames.add(Identifier::fromUid(exec, it->key.get()));
+        }
+    }
+    // Skip the JSEnvironmentRecord implementation of getOwnNonIndexPropertyNames
+    JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
+}
+
+inline bool JSLexicalEnvironment::symbolTablePutWithAttributes(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+    
+    WriteBarrierBase<Unknown>* reg;
+    {
+        ConcurrentJITLocker locker(symbolTable()->m_lock);
+        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.uid());
+        if (iter == symbolTable()->end(locker))
+            return false;
+        SymbolTableEntry& entry = iter->value;
+        ASSERT(!entry.isNull());
+        
+        ScopeOffset offset = entry.scopeOffset();
+        if (!isValid(offset))
+            return false;
+        
+        entry.setAttributes(attributes);
+        reg = &variableAt(offset);
+    }
+    reg->set(vm, this, value);
+    return true;
+}
+
+bool JSLexicalEnvironment::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+    JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(object);
+
+    if (thisObject->symbolTableGet(propertyName, slot))
+        return true;
+
+    unsigned attributes;
+    if (JSValue value = thisObject->getDirect(exec->vm(), propertyName, attributes)) {
+        slot.setValue(thisObject, attributes, value);
+        return true;
+    }
+
+    // We don't call through to JSObject because there's no way to give a 
+    // lexical environment object getter properties or a prototype.
+    ASSERT(!thisObject->hasGetterSetterProperties());
+    ASSERT(thisObject->prototype().isNull());
+    return false;
+}
+
+void JSLexicalEnvironment::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+    JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(cell);
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
+
+    if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode()))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the lexicalEnvironment object.
+    ASSERT(!thisObject->hasGetterSetterProperties());
+    thisObject->putOwnDataProperty(exec->vm(), propertyName, value, slot);
+}
+
+bool JSLexicalEnvironment::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+    if (propertyName == exec->propertyNames().arguments)
+        return false;
+
+    return Base::deleteProperty(cell, exec, propertyName);
+}
+
+JSValue JSLexicalEnvironment::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
+{
+    if (ecmaMode == StrictMode)
+        return jsUndefined();
+    return exec->globalThisValue();
+}
+
+} // namespace JSC
diff --git a/runtime/JSLexicalEnvironment.h b/runtime/JSLexicalEnvironment.h
new file mode 100644 (file)
index 0000000..4d9e341
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef JSLexicalEnvironment_h
+#define JSLexicalEnvironment_h
+
+#include "CodeBlock.h"
+#include "CopiedSpaceInlines.h"
+#include "JSEnvironmentRecord.h"
+#include "SymbolTable.h"
+
+namespace JSC {
+
+class Register;
+    
+class JSLexicalEnvironment : public JSEnvironmentRecord {
+private:
+    JSLexicalEnvironment(VM&, Structure*, JSScope*, SymbolTable*);
+    
+public:
+    typedef JSEnvironmentRecord Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+
+    static JSLexicalEnvironment* create(
+        VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
+    {
+        JSLexicalEnvironment* result = 
+            new (
+                NotNull,
+                allocateCell<JSLexicalEnvironment>(vm.heap, allocationSize(symbolTable)))
+            JSLexicalEnvironment(vm, structure, currentScope, symbolTable);
+        result->finishCreation(vm);
+        return result;
+    }
+    
+    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
+    {
+        JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
+        Structure* structure = globalObject->activationStructure();
+        SymbolTable* symbolTable = codeBlock->symbolTable();
+        return create(vm, structure, currentScope, symbolTable);
+    }
+        
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+
+    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
+
+private:
+    bool symbolTableGet(PropertyName, PropertySlot&);
+    bool symbolTableGet(PropertyName, PropertyDescriptor&);
+    bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
+    bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
+    bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
+};
+
+inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
+    : Base(vm, structure, currentScope, symbolTable)
+{
+}
+
+inline JSLexicalEnvironment* asActivation(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(JSLexicalEnvironment::info()));
+    return jsCast<JSLexicalEnvironment*>(asObject(value));
+}
+    
+ALWAYS_INLINE JSLexicalEnvironment* Register::lexicalEnvironment() const
+{
+    return asActivation(jsValue());
+}
+
+} // namespace JSC
+
+#endif // JSLexicalEnvironment_h
index af8e2722b5f8841e0b6c2ba7ae07af9511dca1af..c2ee0a5532c0b5193687109d9a32ec4a1445d8bd 100644 (file)
@@ -73,7 +73,7 @@ void JSLockHolder::init()
 JSLockHolder::~JSLockHolder()
 {
     RefPtr<JSLock> apiLock(&m_vm->apiLock());
-    m_vm.clear();
+    m_vm = nullptr;
     apiLock->unlock();
 }
 
@@ -157,10 +157,14 @@ void JSLock::unlock(intptr_t unlockCount)
     RELEASE_ASSERT(currentThreadIsHoldingLock());
     ASSERT(m_lockCount >= unlockCount);
 
+    // Maintain m_lockCount while calling willReleaseLock() so that its callees know that
+    // they still have the lock.
+    if (unlockCount == m_lockCount)
+        willReleaseLock();
+
     m_lockCount -= unlockCount;
 
     if (!m_lockCount) {
-        willReleaseLock();
 
         if (!m_hasExclusiveThread) {
             m_ownerThreadID = std::thread::id();
@@ -171,8 +175,10 @@ void JSLock::unlock(intptr_t unlockCount)
 
 void JSLock::willReleaseLock()
 {
-    if (m_vm)
+    if (m_vm) {
+        m_vm->heap.releaseDelayedReleasedObjects();
         m_vm->setStackPointerAtVMEntry(nullptr);
+    }
 
     if (m_entryAtomicStringTable) {
         wtfThreadData().setCurrentAtomicStringTable(m_entryAtomicStringTable);
@@ -206,8 +212,6 @@ unsigned JSLock::dropAllLocks(DropAllLocks* dropper)
         return 0;
     }
 
-    // Check if this thread is currently holding the lock.
-    // FIXME: Maybe we want to require this, guard with an ASSERT?
     if (!currentThreadIsHoldingLock())
         return 0;
 
@@ -259,7 +263,7 @@ JSLock::DropAllLocks::DropAllLocks(VM* vm)
     if (!m_vm)
         return;
     wtfThreadData().resetCurrentAtomicStringTable();
-    RELEASE_ASSERT(!m_vm->isCollectorBusy());
+    RELEASE_ASSERT(!m_vm->apiLock().currentThreadIsHoldingLock() || !m_vm->isCollectorBusy());
     m_droppedLockCount = m_vm->apiLock().dropAllLocks(this);
 }
 
index f4a34eb6eb136fa47af1564064f25d8628df907c..c4339c0fde3e74891cc07161ff3acaa04061cd27 100644 (file)
 
 namespace JSC {
 
-    // To make it safe to use JavaScript on multiple threads, it is
-    // important to lock before doing anything that allocates a
-    // JavaScript data structure or that interacts with shared state
-    // such as the protect count hash table. The simplest way to lock
-    // is to create a local JSLockHolder object in the scope where the lock 
-    // must be held and pass it the context that requires protection. 
-    // The lock is recursive so nesting is ok. The JSLock 
-    // object also acts as a convenience short-hand for running important
-    // initialization routines.
-
-    // To avoid deadlock, sometimes it is necessary to temporarily
-    // release the lock. Since it is recursive you actually have to
-    // release all locks held by your thread. This is safe to do if
-    // you are executing code that doesn't require the lock, and you
-    // reacquire the right number of locks at the end. You can do this
-    // by constructing a locally scoped JSLock::DropAllLocks object. The 
-    // DropAllLocks object takes care to release the JSLock only if your
-    // thread acquired it to begin with.
-
-    class ExecState;
-    class VM;
-
-    // This class is used to protect the initialization of the legacy single 
-    // shared VM.
-    class GlobalJSLock {
-        WTF_MAKE_NONCOPYABLE(GlobalJSLock);
+// To make it safe to use JavaScript on multiple threads, it is
+// important to lock before doing anything that allocates a
+// JavaScript data structure or that interacts with shared state
+// such as the protect count hash table. The simplest way to lock
+// is to create a local JSLockHolder object in the scope where the lock 
+// must be held and pass it the context that requires protection. 
+// The lock is recursive so nesting is ok. The JSLock 
+// object also acts as a convenience short-hand for running important
+// initialization routines.
+
+// To avoid deadlock, sometimes it is necessary to temporarily
+// release the lock. Since it is recursive you actually have to
+// release all locks held by your thread. This is safe to do if
+// you are executing code that doesn't require the lock, and you
+// reacquire the right number of locks at the end. You can do this
+// by constructing a locally scoped JSLock::DropAllLocks object. The 
+// DropAllLocks object takes care to release the JSLock only if your
+// thread acquired it to begin with.
+
+class ExecState;
+class VM;
+
+// This class is used to protect the initialization of the legacy single 
+// shared VM.
+class GlobalJSLock {
+    WTF_MAKE_NONCOPYABLE(GlobalJSLock);
+public:
+    JS_EXPORT_PRIVATE GlobalJSLock();
+    JS_EXPORT_PRIVATE ~GlobalJSLock();
+
+    static void initialize();
+private:
+    static std::mutex* s_sharedInstanceMutex;
+};
+
+class JSLockHolder {
+public:
+    JS_EXPORT_PRIVATE JSLockHolder(VM*);
+    JS_EXPORT_PRIVATE JSLockHolder(VM&);
+    JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
+
+    JS_EXPORT_PRIVATE ~JSLockHolder();
+private:
+    void init();
+
+    RefPtr<VM> m_vm;
+};
+
+class JSLock : public ThreadSafeRefCounted<JSLock> {
+    WTF_MAKE_NONCOPYABLE(JSLock);
+public:
+    JSLock(VM*);
+    JS_EXPORT_PRIVATE ~JSLock();
+
+    JS_EXPORT_PRIVATE void lock();
+    JS_EXPORT_PRIVATE void unlock();
+
+    static void lock(ExecState*);
+    static void unlock(ExecState*);
+    static void lock(VM&);
+    static void unlock(VM&);
+
+    VM* vm() { return m_vm; }
+
+    bool hasExclusiveThread() const { return m_hasExclusiveThread; }
+    std::thread::id exclusiveThread() const
+    {
+        ASSERT(m_hasExclusiveThread);
+        return m_ownerThreadID;
+    }
+    JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
+    JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
+
+    void willDestroyVM(VM*);
+
+    class DropAllLocks {
+        WTF_MAKE_NONCOPYABLE(DropAllLocks);
     public:
-        JS_EXPORT_PRIVATE GlobalJSLock();
-        JS_EXPORT_PRIVATE ~GlobalJSLock();
+        JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
+        JS_EXPORT_PRIVATE DropAllLocks(VM*);
+        JS_EXPORT_PRIVATE DropAllLocks(VM&);
+        JS_EXPORT_PRIVATE ~DropAllLocks();
 
-        static void initialize();
-    private:
-        static std::mutex* s_sharedInstanceMutex;
-    };
+        void setDropDepth(unsigned depth) { m_dropDepth = depth; }
+        unsigned dropDepth() const { return m_dropDepth; }
 
-    class JSLockHolder {
-    public:
-        JS_EXPORT_PRIVATE JSLockHolder(VM*);
-        JS_EXPORT_PRIVATE JSLockHolder(VM&);
-        JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
-
-        JS_EXPORT_PRIVATE ~JSLockHolder();
     private:
-        void init();
-
+        intptr_t m_droppedLockCount;
         RefPtr<VM> m_vm;
+        unsigned m_dropDepth;
     };
 
-    class JSLock : public ThreadSafeRefCounted<JSLock> {
-        WTF_MAKE_NONCOPYABLE(JSLock);
-    public:
-        JSLock(VM*);
-        JS_EXPORT_PRIVATE ~JSLock();
-
-        JS_EXPORT_PRIVATE void lock();
-        JS_EXPORT_PRIVATE void unlock();
-
-        static void lock(ExecState*);
-        static void unlock(ExecState*);
-        static void lock(VM&);
-        static void unlock(VM&);
-
-        VM* vm() { return m_vm; }
-
-        bool hasExclusiveThread() const { return m_hasExclusiveThread; }
-        std::thread::id exclusiveThread() const
-        {
-            ASSERT(m_hasExclusiveThread);
-            return m_ownerThreadID;
-        }
-        JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
-        JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
-
-        void willDestroyVM(VM*);
-
-        class DropAllLocks {
-            WTF_MAKE_NONCOPYABLE(DropAllLocks);
-        public:
-            JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
-            JS_EXPORT_PRIVATE DropAllLocks(VM*);
-            JS_EXPORT_PRIVATE DropAllLocks(VM&);
-            JS_EXPORT_PRIVATE ~DropAllLocks();
-            
-            void setDropDepth(unsigned depth) { m_dropDepth = depth; }
-            unsigned dropDepth() const { return m_dropDepth; }
-
-        private:
-            intptr_t m_droppedLockCount;
-            RefPtr<VM> m_vm;
-            unsigned m_dropDepth;
-        };
+private:
+    void lock(intptr_t lockCount);
+    void unlock(intptr_t unlockCount);
 
-    private:
-        void lock(intptr_t lockCount);
-        void unlock(intptr_t unlockCount);
-
-        void didAcquireLock();
-        void willReleaseLock();
-
-        unsigned dropAllLocks(DropAllLocks*);
-        void grabAllLocks(DropAllLocks*, unsigned lockCount);
-
-        std::mutex m_lock;
-        std::thread::id m_ownerThreadID;
-        intptr_t m_lockCount;
-        unsigned m_lockDropDepth;
-        bool m_hasExclusiveThread;
-        VM* m_vm;
-        AtomicStringTable* m_entryAtomicStringTable; 
-    };
+    void didAcquireLock();
+    void willReleaseLock();
+
+    unsigned dropAllLocks(DropAllLocks*);
+    void grabAllLocks(DropAllLocks*, unsigned lockCount);
+
+    std::mutex m_lock;
+    std::thread::id m_ownerThreadID;
+    intptr_t m_lockCount;
+    unsigned m_lockDropDepth;
+    bool m_hasExclusiveThread;
+    VM* m_vm;
+    AtomicStringTable* m_entryAtomicStringTable; 
+};
 
 } // namespace
 
index 5500c5655712e10cca847a8e7f0476e47cd79e99..352648b5e078be8c79a9cf003060f61bff66c656 100644 (file)
 #include "JSMap.h"
 
 #include "JSCJSValueInlines.h"
-#include "MapData.h"
+#include "JSMapIterator.h"
+#include "MapDataInlines.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
-    
-const ClassInfo JSMap::s_info = { "Map", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSMap) };
+
+const ClassInfo JSMap::s_info = { "Map", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMap) };
+
+void JSMap::destroy(JSCell* cell)
+{
+    JSMap* thisObject = jsCast<JSMap*>(cell);
+    thisObject->JSMap::~JSMap();
+}
 
 void JSMap::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     Base::visitChildren(cell, visitor);
-    JSMap* thisObject = jsCast<JSMap*>(cell);
-    visitor.append(&thisObject->m_mapData);
+    jsCast<JSMap*>(cell)->m_mapData.visitChildren(cell, visitor);
+}
+
+void JSMap::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
+{
+    Base::copyBackingStore(cell, visitor, token);
+    jsCast<JSMap*>(cell)->m_mapData.copyBackingStore(visitor, token);
+}
+
+bool JSMap::has(ExecState* exec, JSValue key)
+{
+    return m_mapData.contains(exec, key);
 }
 
-void JSMap::finishCreation(VM& vm)
+size_t JSMap::size(ExecState* exec)
 {
-    Base::finishCreation(vm);
-    m_mapData.set(vm, this, MapData::create(vm));
+    return m_mapData.size(exec);
 }
 
+JSValue JSMap::get(ExecState* exec, JSValue key)
+{
+    JSValue result = m_mapData.get(exec, key);
+    if (!result)
+        return jsUndefined();
+    return result;
+}
+
+void JSMap::set(ExecState* exec, JSValue key, JSValue value)
+{
+    m_mapData.set(exec, this, key, value);
+}
+
+void JSMap::clear(ExecState*)
+{
+    m_mapData.clear();
+}
+
+bool JSMap::remove(ExecState* exec, JSValue key)
+{
+    return m_mapData.remove(exec, key);
+}
 
 }
index 29aa18243a9559bf60fd994b598e6f0716c0c94b..837f7e36956c7209a661641466756765f6bc25bb 100644 (file)
 #ifndef JSMap_h
 #define JSMap_h
 
+#include "JSDestructibleObject.h"
 #include "JSObject.h"
+#include "MapData.h"
 
 namespace JSC {
 
-class MapData;
+class JSMapIterator;
 
-class JSMap : public JSNonFinalObject {
+class JSMap : public JSDestructibleObject {
 public:
-    typedef JSNonFinalObject Base;
+    typedef JSDestructibleObject Base;
+
+    friend class JSMapIterator;
+
+    // Our marking functions expect Entry to maintain this layout, and have all
+    // fields be WriteBarrier<Unknown>
+    class Entry {
+    private:
+        WriteBarrier<Unknown> m_key;
+        WriteBarrier<Unknown> m_value;
+
+    public:
+        const WriteBarrier<Unknown>& key() const
+        {
+            return m_key;
+        }
+
+        const WriteBarrier<Unknown>& value() const
+        {
+            return m_value;
+        }
+
+        void visitChildren(SlotVisitor& visitor)
+        {
+            visitor.append(&m_key);
+            visitor.append(&m_value);
+        }
+
+        void setKey(VM& vm, const JSCell* owner, JSValue key)
+        {
+            m_key.set(vm, owner, key);
+        }
+
+        void setKeyWithoutWriteBarrier(JSValue key)
+        {
+            m_key.setWithoutWriteBarrier(key);
+        }
+
+        void setValue(VM& vm, const JSCell* owner, JSValue value)
+        {
+            m_value.set(vm, owner, value);
+        }
+
+        void clear()
+        {
+            m_key.clear();
+            m_value.clear();
+        }
+    };
+
+    typedef MapDataImpl<Entry, JSMapIterator> MapData;
 
     DECLARE_EXPORT_INFO;
 
@@ -55,21 +107,25 @@ public:
         return create(exec->vm(), structure);
     }
 
-    MapData* mapData() { return m_mapData.get(); }
+    bool has(ExecState*, JSValue);
+    size_t size(ExecState*);
+    JSValue get(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE void set(ExecState*, JSValue key, JSValue value);
+    void clear(ExecState*);
+    bool remove(ExecState*, JSValue);
 
 private:
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     JSMap(VM& vm, Structure* structure)
         : Base(vm, structure)
+        , m_mapData(vm)
     {
     }
 
-    JS_EXPORT_PRIVATE void finishCreation(VM&);
-
+    static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
 
-    WriteBarrier<MapData> m_mapData;
+    MapData m_mapData;
 };
 
 }
index d732edbbbdb6b53297b17ce87780c38e85a00e69..885362bd4984f1151a5f71deab15a0529d78fb61 100644 (file)
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSMap.h"
+#include "MapDataInlines.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo JSMapIterator::s_info = { "Map Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSMapIterator) };
+const ClassInfo JSMapIterator::s_info = { "Map Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMapIterator) };
 
 void JSMapIterator::finishCreation(VM& vm, JSMap* iteratedObject)
 {
     Base::finishCreation(vm);
-    m_iteratedObjectData.set(vm, this, iteratedObject->mapData());
+    m_map.set(vm, this, iteratedObject);
+}
+
+void JSMapIterator::destroy(JSCell* cell)
+{
+    JSMapIterator* thisObject = jsCast<JSMapIterator*>(cell);
+    thisObject->JSMapIterator::~JSMapIterator();
 }
 
 void JSMapIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSMapIterator* thisObject = jsCast<JSMapIterator*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-        
     Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_iteratedObjectData);
+    visitor.append(&thisObject->m_map);
 }
 
 JSValue JSMapIterator::createPair(CallFrame* callFrame, JSValue key, JSValue value)
@@ -62,4 +66,11 @@ JSValue JSMapIterator::createPair(CallFrame* callFrame, JSValue key, JSValue val
     return constructArray(callFrame, 0, globalObject, args);
 }
 
+JSMapIterator* JSMapIterator::clone(ExecState* exec)
+{
+    auto clone = JSMapIterator::create(exec->vm(), exec->callee()->globalObject()->mapIteratorStructure(), m_map.get(), m_kind);
+    clone->m_iterator = m_iterator;
+    return clone;
+}
+
 }
index 0096d9e043779548b1f38c96194ba52a1b7abc9b..cc2ae867aa79a8f09d7cd15c8abfd61929fc548b 100644 (file)
@@ -57,36 +57,59 @@ public:
 
     bool next(CallFrame* callFrame, JSValue& value)
     {
-        if (!m_iterator.ensureSlot())
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
             return false;
 
         if (m_kind == MapIterateValue)
-            value = m_iterator.value();
+            value = pair.value;
         else if (m_kind == MapIterateKey)
-            value = m_iterator.key();
+            value = pair.key;
         else
-            value = createPair(callFrame, m_iterator.key(), m_iterator.value());
-        ++m_iterator;
+            value = createPair(callFrame, pair.key, pair.value);
         return true;
     }
 
-private:
+    bool nextKeyValue(JSValue& key, JSValue& value)
+    {
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
+            return false;
 
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
+        key = pair.key;
+        value = pair.value;
+        return true;
+    }
 
+    void finish()
+    {
+        m_iterator.finish();
+    }
+
+    MapIterationKind kind() const { return m_kind; }
+    JSValue iteratedValue() const { return m_map.get(); }
+    JSMapIterator* clone(ExecState*);
+
+    JSMap::MapData::IteratorData* iteratorData()
+    {
+        return &m_iterator;
+    }
+
+private:
     JSMapIterator(VM& vm, Structure* structure, JSMap* iteratedObject, MapIterationKind kind)
         : Base(vm, structure)
-        , m_iterator(iteratedObject->mapData()->begin())
+        , m_iterator(iteratedObject->m_mapData.createIteratorData(this))
         , m_kind(kind)
     {
     }
 
-    void finishCreation(VM&, JSMap*);
+    static void destroy(JSCell*);
+    JS_EXPORT_PRIVATE void finishCreation(VM&, JSMap*);
     JSValue createPair(CallFrame*, JSValue, JSValue);
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    WriteBarrier<MapData> m_iteratedObjectData;
-    MapData::const_iterator m_iterator;
+    WriteBarrier<JSMap> m_map;
+    JSMap::MapData::IteratorData m_iterator;
     MapIterationKind m_kind;
 };
 
index db721379136d76ad16b249834d8ae4accf0370ea..d159f69be2a6fc80a13588b470fbed72cf8c4d0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2012, 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "Error.h"
 #include "JSCInlines.h"
+#include "JSCatchScope.h"
+#include "JSFunctionNameScope.h"
 
 namespace JSC {
 
-const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNameScope) };
+const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, CREATE_METHOD_TABLE(JSNameScope) };
 
-void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
+JSNameScope* JSNameScope::create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value, Type type)
 {
-    JSNameScope* thisObject = jsCast<JSNameScope*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_registerStore);
+    switch (type) {
+    case CatchScope:
+        return JSCatchScope::create(vm, globalObject, currentScope, symbolTable, value);
+    case FunctionNameScope:
+        return JSFunctionNameScope::create(vm, globalObject, currentScope, symbolTable, value);
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
 }
 
 JSValue JSNameScope::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
index a6b6a22f5548700894a4b7f4f61f3e61cc02c07b..db8d0085d86bdc12ec087c6ee25079074c9a730b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSNameScope_h
 #define JSNameScope_h
 
+#include "JSEnvironmentRecord.h"
 #include "JSGlobalObject.h"
-#include "JSVariableObject.h"
 
 namespace JSC {
 
 // Used for scopes with a single named variable: catch and named function expression.
-class JSNameScope : public JSVariableObject {
+class JSNameScope : public JSEnvironmentRecord {
 public:
-    typedef JSVariableObject Base;
+    typedef JSEnvironmentRecord Base;
+    static const unsigned StructureFlags = Base::StructureFlags| OverridesGetOwnPropertySlot;
 
-    static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes)
-    {
-        VM& vm = exec->vm();
-        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), exec->scope());
-        scopeObject->finishCreation(vm, identifier, value, attributes);
-        return scopeObject;
-    }
+    enum Type {
+        CatchScope,
+        FunctionNameScope
+    };
 
-    static JSNameScope* create(VM& vm, JSGlobalObject* globalObject, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next)
+    template<typename T>
+    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
     {
-        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, globalObject, next);
-        scopeObject->finishCreation(vm, identifier, value, attributes);
+        T* scopeObject = new (
+            NotNull, allocateCell<T>(vm.heap, allocationSizeForScopeSize(1)))
+            T(vm, globalObject, currentScope, symbolTable);
+        scopeObject->finishCreation(vm, value);
         return scopeObject;
     }
+    
+    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
 
-    static void visitChildren(JSCell*, SlotVisitor&);
     static JSValue toThis(JSCell*, ExecState*, ECMAMode);
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), info()); }
-
     DECLARE_INFO;
 
+    JSValue value() { return variableAt(ScopeOffset(0)).get(); }
+
 protected:
-    void finishCreation(VM& vm, const Identifier& identifier, JSValue value, unsigned attributes)
+    void finishCreation(VM& vm, JSValue value)
     {
-        Base::finishCreation(vm);
-        m_registerStore.set(vm, this, value);
-        symbolTable()->add(identifier.impl(), SymbolTableEntry(-1, attributes));
+        Base::finishCreationUninitialized(vm);
+        variableAt(ScopeOffset(0)).set(vm, this, value);
     }
 
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags;
-
-private:
-    JSNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next)
-        : Base(
-            vm,
-            globalObject->nameScopeStructure(),
-            reinterpret_cast<Register*>(&m_registerStore + 1),
-            next
-        )
+    JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, structure, next, symbolTable)
     {
+        ASSERT(symbolTable->scopeSize() == 1);
     }
-
-    WriteBarrier<Unknown> m_registerStore;
 };
 
 }
index 2367a3563c4a89b3cf52150ee1c8dcd825c6d67b..af4737e9b02f57103065ee7d8e7ba040dec0d2ac 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSNotAnObject);
 
-const ClassInfo JSNotAnObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNotAnObject) };
+const ClassInfo JSNotAnObject::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(JSNotAnObject) };
 
 // JSValue methods
 JSValue JSNotAnObject::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType)
index a84100288a5961ffe5955d05a8a49416464d135e..0c26ec98b6fb17a81cec959f71d5acc448a457e2 100644 (file)
 
 namespace JSC {
 
-    // This unholy class is used to allow us to avoid multiple exception checks
-    // in certain SquirrelFish bytecodes -- effectively it just silently consumes
-    // any operations performed on the result of a failed toObject call.
-    class JSNotAnObject : public JSNonFinalObject {
-    private:
-        explicit JSNotAnObject(VM& vm)
-            : JSNonFinalObject(vm, vm.notAnObjectStructure.get())
-        {
-        }
-        
-    public:
-        typedef JSNonFinalObject Base;
+// This unholy class is used to allow us to avoid multiple exception checks
+// in certain SquirrelFish bytecodes -- effectively it just silently consumes
+// any operations performed on the result of a failed toObject call.
+class JSNotAnObject final : public JSNonFinalObject {
+private:
+    explicit JSNotAnObject(VM& vm)
+        : JSNonFinalObject(vm, vm.notAnObjectStructure.get())
+    {
+    }
 
-        static JSNotAnObject* create(VM& vm)
-        {
-            JSNotAnObject* object = new (NotNull, allocateCell<JSNotAnObject>(vm.heap)) JSNotAnObject(vm);
-            object->finishCreation(vm);
-            return object;
-        }
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    static JSNotAnObject* create(VM& vm)
+    {
+        JSNotAnObject* object = new (NotNull, allocateCell<JSNotAnObject>(vm.heap)) JSNotAnObject(vm);
+        object->finishCreation(vm);
+        return object;
+    }
 
-        DECLARE_INFO;
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-     private:
-        
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
+    DECLARE_INFO;
 
-        // JSValue methods
-        static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
+private:
+    // JSValue methods
+    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
 
-        // JSObject methods
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-        static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
+    // JSObject methods
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
 
-        static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
 
-        static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-        static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
 
-        static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-    };
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+};
 
 } // namespace JSC
 
index 87b9237d414141967b3d7bd8c9ed761a015442ff..61dc046b0d2b91decae7b8798f205702ddd52f5b 100644 (file)
@@ -45,8 +45,8 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSONObject);
 
-static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*);
-static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*);
+EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*);
+EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*);
 
 }
 
@@ -107,8 +107,6 @@ private:
 
     friend class Holder;
 
-    static void appendQuotedString(StringBuilder&, const String&);
-
     JSValue toJSON(JSValue, const PropertyNameForFunctionCall&);
 
     enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue };
@@ -226,9 +224,10 @@ Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const
             if (name.isObject()) {
                 if (!asObject(name)->inherits(NumberObject::info()) && !asObject(name)->inherits(StringObject::info()))
                     continue;
-            }
+            } else if (!name.isNumber() && !name.isString())
+                continue;
 
-            m_arrayReplacerPropertyNames.add(Identifier(exec, name.toString(exec)->value(exec)));
+            m_arrayReplacerPropertyNames.add(name.toString(exec)->toIdentifier(exec));
         }
         return;
     }
@@ -254,77 +253,6 @@ Local<Unknown> Stringifier::stringify(Handle<Unknown> value)
     return Local<Unknown>(m_exec->vm(), jsString(m_exec, result.toString()));
 }
 
-template <typename CharType>
-static void appendStringToStringBuilder(StringBuilder& builder, const CharType* data, int length)
-{
-    for (int i = 0; i < length; ++i) {
-        int start = i;
-        while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\'))
-            ++i;
-        builder.append(data + start, i - start);
-        if (i >= length)
-            break;
-        switch (data[i]) {
-        case '\t':
-            builder.append('\\');
-            builder.append('t');
-            break;
-        case '\r':
-            builder.append('\\');
-            builder.append('r');
-            break;
-        case '\n':
-            builder.append('\\');
-            builder.append('n');
-            break;
-        case '\f':
-            builder.append('\\');
-            builder.append('f');
-            break;
-        case '\b':
-            builder.append('\\');
-            builder.append('b');
-            break;
-        case '"':
-            builder.append('\\');
-            builder.append('"');
-            break;
-        case '\\':
-            builder.append('\\');
-            builder.append('\\');
-            break;
-        default:
-            static const char hexDigits[] = "0123456789abcdef";
-            UChar ch = data[i];
-            LChar hex[] = { '\\', 'u', static_cast<LChar>(hexDigits[(ch >> 12) & 0xF]), static_cast<LChar>(hexDigits[(ch >> 8) & 0xF]), static_cast<LChar>(hexDigits[(ch >> 4) & 0xF]), static_cast<LChar>(hexDigits[ch & 0xF]) };
-            builder.append(hex, WTF_ARRAY_LENGTH(hex));
-            break;
-        }
-    }
-}
-
-void escapeStringToBuilder(StringBuilder& builder, const String& message)
-{
-    if (message.is8Bit())
-        appendStringToStringBuilder(builder, message.characters8(), message.length());
-    else
-        appendStringToStringBuilder(builder, message.characters16(), message.length());
-}
-
-void Stringifier::appendQuotedString(StringBuilder& builder, const String& value)
-{
-    int length = value.length();
-
-    builder.append('"');
-
-    if (value.is8Bit())
-        appendStringToStringBuilder<LChar>(builder, value.characters8(), length);
-    else
-        appendStringToStringBuilder<UChar>(builder, value.characters16(), length);
-
-    builder.append('"');
-}
-
 inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName)
 {
     ASSERT(!m_exec->hadException());
@@ -387,18 +315,21 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
         return StringifySucceeded;
     }
 
-    String stringValue;
-    if (value.getString(m_exec, stringValue)) {
-        appendQuotedString(builder, stringValue);
+    if (value.isString()) {
+        builder.appendQuotedJSONString(asString(value)->value(m_exec));
         return StringifySucceeded;
     }
 
     if (value.isNumber()) {
-        double number = value.asNumber();
-        if (!std::isfinite(number))
-            builder.appendLiteral("null");
-        else
-            builder.append(String::numberToStringECMAScript(number));
+        if (value.isInt32())
+            builder.appendNumber(value.asInt32());
+        else {
+            double number = value.asNumber();
+            if (!std::isfinite(number))
+                builder.appendLiteral("null");
+            else
+                builder.appendECMAScriptNumber(number);
+        }
         return StringifySucceeded;
     }
 
@@ -487,14 +418,17 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
     if (!m_index) {
         if (m_isArray) {
             m_isJSArray = isJSArray(m_object.get());
-            m_size = m_object->get(exec, exec->vm().propertyNames->length).toUInt32(exec);
+            if (m_isJSArray)
+                m_size = asArray(m_object.get())->length();
+            else
+                m_size = m_object->get(exec, exec->vm().propertyNames->length).toUInt32(exec);
             builder.append('[');
         } else {
             if (stringifier.m_usingArrayReplacer)
                 m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data();
             else {
                 PropertyNameArray objectPropertyNames(exec);
-                m_object->methodTable()->getOwnPropertyNames(m_object.get(), exec, objectPropertyNames, ExcludeDontEnumProperties);
+                m_object->methodTable()->getOwnPropertyNames(m_object.get(), exec, objectPropertyNames, EnumerationMode());
                 m_propertyNames = objectPropertyNames.releaseData();
             }
             m_size = m_propertyNames->propertyNameVector().size();
@@ -556,7 +490,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
         stringifier.startNewLine(builder);
 
         // Append the property name.
-        appendQuotedString(builder, propertyName.string());
+        builder.appendQuotedJSONString(propertyName.string());
         builder.append(':');
         if (stringifier.willIndent())
             builder.append(' ');
@@ -588,7 +522,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
 
 // ------------------------------ JSONObject --------------------------------
 
-const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, 0, ExecState::jsonTable, CREATE_METHOD_TABLE(JSONObject) };
+const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, &jsonTable, CREATE_METHOD_TABLE(JSONObject) };
 
 /* Source for JSONObject.lut.h
 @begin jsonTable
@@ -601,7 +535,7 @@ const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, 0, Exe
 
 bool JSONObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return getStaticFunctionSlot<JSObject>(exec, ExecState::jsonTable(exec->vm()), jsCast<JSONObject*>(object), propertyName, slot);
+    return getStaticFunctionSlot<JSObject>(exec, jsonTable, jsCast<JSONObject*>(object), propertyName, slot);
 }
 
 class Walker {
@@ -711,7 +645,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
                 objectStack.push(object);
                 indexStack.append(0);
                 propertyStack.append(PropertyNameArray(m_exec));
-                object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), ExcludeDontEnumProperties);
+                object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), EnumerationMode());
             }
             objectStartVisitMember:
             FALLTHROUGH;
@@ -785,7 +719,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
 {
     if (!exec->argumentCount())
         return throwVMError(exec, createError(exec, ASCIILiteral("JSON.parse requires at least one parameter")));
-    String source = exec->uncheckedArgument(0).toString(exec)->value(exec);
+    StringView source = exec->uncheckedArgument(0).toString(exec)->view(exec);
     if (exec->hadException())
         return JSValue::encode(jsNull());
 
index cacfc5d6c6c920522ea4daa967e0db016a60a0c7..d550525c9e71d85abcf41a8d18a90017a1bb30ad 100644 (file)
 
 namespace JSC {
 
-    class Stringifier;
+class Stringifier;
 
-    class JSONObject : public JSNonFinalObject {
-    public:
-        typedef JSNonFinalObject Base;
+class JSONObject : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
-        static JSONObject* create(VM& vm, Structure* structure)
-        {
-            JSONObject* object = new (NotNull, allocateCell<JSONObject>(vm.heap)) JSONObject(vm, structure);
-            object->finishCreation(vm);
-            return object;
-        }
-        
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-        
-        DECLARE_INFO;
+    static JSONObject* create(VM& vm, Structure* structure)
+    {
+        JSONObject* object = new (NotNull, allocateCell<JSONObject>(vm.heap)) JSONObject(vm, structure);
+        object->finishCreation(vm);
+        return object;
+    }
 
-    protected:
-        void finishCreation(VM&);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-    private:
-        JSONObject(VM&, Structure*);
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    DECLARE_INFO;
 
-    };
+protected:
+    void finishCreation(VM&);
 
-    JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
-    JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent);
+private:
+    JSONObject(VM&, Structure*);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
+
+JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
+JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent);
 
-    void escapeStringToBuilder(StringBuilder&, const String&);
     
 } // namespace JSC
 
index ebb718ce8bfac671c4f790cc1efe4240b8107d59..d20daa20451d2fbef33bcd91349104f1fbcb5873 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2006, 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
  *
  *  This library is free software; you can redistribute it and/or
 #include "CustomGetterSetter.h"
 #include "DatePrototype.h"
 #include "ErrorConstructor.h"
+#include "Exception.h"
 #include "Executable.h"
 #include "GetterSetter.h"
 #include "IndexingHeaderInlines.h"
+#include "JSCatchScope.h"
 #include "JSFunction.h"
+#include "JSFunctionNameScope.h"
 #include "JSGlobalObject.h"
 #include "Lookup.h"
 #include "NativeErrorConstructor.h"
@@ -56,23 +59,14 @@ namespace JSC {
 // ArrayConventions.h.
 static unsigned lastArraySize = 0;
 
-JSCell* getCallableObjectSlow(JSCell* cell)
-{
-    if (cell->type() == JSFunctionType)
-        return cell;
-    if (cell->structure()->classInfo()->isSubClassOf(InternalFunction::info()))
-        return cell;
-    return 0;
-}
-
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSObject);
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSFinalObject);
 
 const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
 
-const ClassInfo JSObject::s_info = { "Object", 0, 0, 0, CREATE_METHOD_TABLE(JSObject) };
+const ClassInfo JSObject::s_info = { "Object", 0, 0, CREATE_METHOD_TABLE(JSObject) };
 
-const ClassInfo JSFinalObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFinalObject) };
+const ClassInfo JSFinalObject::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFinalObject) };
 
 static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode, bool didReify)
 {
@@ -80,13 +74,13 @@ static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* class
 
     // Add properties from the static hashtables of properties
     for (; classInfo; classInfo = classInfo->parentClass) {
-        const HashTable* table = classInfo->propHashTable(vm);
+        const HashTable* table = classInfo->staticPropHashTable;
         if (!table)
             continue;
 
-        for (auto iter = table->begin(vm); iter != table->end(vm); ++iter) {
-            if ((!(iter->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)) && !((iter->attributes() & BuiltinOrFunction) && didReify))
-                propertyNames.add(Identifier(&vm, iter.key()));
+        for (auto iter = table->begin(); iter != table->end(); ++iter) {
+            if ((!(iter->attributes() & DontEnum) || mode.includeDontEnumProperties()) && !((iter->attributes() & BuiltinOrFunctionOrAccessor) && didReify))
+                propertyNames.add(Identifier::fromString(&vm, iter.key()));
         }
     }
 }
@@ -266,6 +260,44 @@ String JSObject::className(const JSObject* object)
     return info->className;
 }
 
+String JSObject::calculatedClassName(JSObject* object)
+{
+    String prototypeFunctionName;
+    ExecState* exec = object->globalObject()->globalExec();
+    PropertySlot slot(object->structure()->storedPrototype());
+    PropertyName constructor(exec->propertyNames().constructor);
+    if (object->getPropertySlot(exec, constructor, slot)) {
+        if (slot.isValue()) {
+            JSValue constructorValue = slot.getValue(exec, constructor);
+            if (constructorValue.isCell()) {
+                if (JSCell* constructorCell = constructorValue.asCell()) {
+                    if (JSObject* ctorObject = constructorCell->getObject()) {
+                        if (JSFunction* constructorFunction = jsDynamicCast<JSFunction*>(ctorObject))
+                            prototypeFunctionName = constructorFunction->calculatedDisplayName(exec);
+                        else if (InternalFunction* constructorFunction = jsDynamicCast<InternalFunction*>(ctorObject))
+                            prototypeFunctionName = constructorFunction->calculatedDisplayName(exec);
+                    }
+                }
+            }
+        }
+    }
+
+    if (prototypeFunctionName.isNull() || prototypeFunctionName == "Object") {
+        String tableClassName = object->methodTable()->className(object);
+        if (!tableClassName.isNull() && tableClassName != "Object")
+            return tableClassName;
+
+        String classInfoName = object->classInfo()->className;
+        if (!classInfoName.isNull())
+            return classInfoName;
+
+        if (prototypeFunctionName.isNull())
+            return ASCIILiteral("Object");
+    }
+
+    return prototypeFunctionName;
+}
+
 bool JSObject::getOwnPropertySlotByIndex(JSObject* thisObject, ExecState* exec, unsigned i, PropertySlot& slot)
 {
     // NB. The fact that we're directly consulting our indexed storage implies that it is not
@@ -348,9 +380,8 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
     
     // Try indexed put first. This is required for correctness, since loads on property names that appear like
     // valid indices will never look in the named property storage.
-    unsigned i = propertyName.asIndex();
-    if (i != PropertyName::NotAnIndex) {
-        putByIndex(thisObject, exec, i, value, slot.isStrictMode());
+    if (Optional<uint32_t> index = parseIndex(propertyName)) {
+        putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
         return;
     }
     
@@ -361,7 +392,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
             prototype = obj->prototype();
             if (prototype.isNull()) {
                 ASSERT(!thisObject->structure(vm)->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName));
-                if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value))
+                if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot)
                     && slot.isStrictMode())
                     throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
                 return;
@@ -372,8 +403,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
     JSObject* obj;
     for (obj = thisObject; ; obj = asObject(prototype)) {
         unsigned attributes;
-        JSCell* specificValue;
-        PropertyOffset offset = obj->structure(vm)->get(vm, propertyName, attributes, specificValue);
+        PropertyOffset offset = obj->structure(vm)->get(vm, propertyName, attributes);
         if (isValidOffset(offset)) {
             if (attributes & ReadOnly) {
                 ASSERT(thisObject->structure(vm)->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
@@ -401,10 +431,12 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
             break;
         }
         const ClassInfo* info = obj->classInfo();
-        if (info->hasStaticSetterOrReadonlyProperties(vm)) {
-            if (const HashTableValue* entry = obj->findPropertyHashEntry(vm, propertyName)) {
-                putEntry(exec, entry, obj, propertyName, value, slot);
-                return;
+        if (info->hasStaticSetterOrReadonlyProperties()) {
+            if (const HashTableValue* entry = obj->findPropertyHashEntry(propertyName)) {
+                if (!obj->staticFunctionsReified() || !(entry->attributes() & BuiltinOrFunctionOrAccessor)) {
+                    putEntry(exec, entry, obj, propertyName, value, slot);
+                    return;
+                }
             }
         }
         prototype = obj->prototype();
@@ -413,7 +445,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
     }
     
     ASSERT(!thisObject->structure(vm)->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
-    if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
+    if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot) && slot.isStrictMode())
         throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
     return;
 }
@@ -734,12 +766,13 @@ ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(VM&
     return newStorage;
 }
 
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransition transition)
 {
     DeferGC deferGC(vm.heap);
     ASSERT(hasUndecided(indexingType()));
-    
-    ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
+
+    unsigned vectorLength = m_butterfly->vectorLength();
+    ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength);
     // No need to copy elements.
     
     Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), transition);
@@ -747,11 +780,6 @@ ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransi
     return storage;
 }
 
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransition transition)
-{
-    return convertUndecidedToArrayStorage(vm, transition, m_butterfly->vectorLength());
-}
-
 ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm)
 {
     return convertUndecidedToArrayStorage(vm, structure(vm)->suggestedArrayStorageTransition());
@@ -785,18 +813,20 @@ ContiguousJSValues JSObject::convertInt32ToContiguous(VM& vm)
     return m_butterfly->contiguous();
 }
 
-ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition transition)
 {
-    ASSERT(hasInt32(indexingType()));
-    
     DeferGC deferGC(vm.heap);
-    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
-    for (unsigned i = m_butterfly->publicLength(); i--;) {
+    ASSERT(hasInt32(indexingType()));
+
+    unsigned vectorLength = m_butterfly->vectorLength();
+    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength);
+    for (unsigned i = 0; i < m_butterfly->publicLength(); i++) {
         JSValue v = m_butterfly->contiguous()[i].get();
-        if (!v)
-            continue;
-        newStorage->m_vector[i].setWithoutWriteBarrier(v);
-        newStorage->m_numValuesInVector++;
+        if (v) {
+            newStorage->m_vector[i].setWithoutWriteBarrier(v);
+            newStorage->m_numValuesInVector++;
+        } else
+            ASSERT(newStorage->m_vector[i].get().isEmpty());
     }
     
     Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), transition);
@@ -804,18 +834,12 @@ ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition
     return newStorage;
 }
 
-ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition transition)
-{
-    return convertInt32ToArrayStorage(vm, transition, m_butterfly->vectorLength());
-}
-
 ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm)
 {
     return convertInt32ToArrayStorage(vm, structure(vm)->suggestedArrayStorageTransition());
 }
 
-template<JSObject::DoubleToContiguousMode mode>
-ContiguousJSValues JSObject::genericConvertDoubleToContiguous(VM& vm)
+ContiguousJSValues JSObject::convertDoubleToContiguous(VM& vm)
 {
     ASSERT(hasDouble(indexingType()));
     
@@ -827,20 +851,7 @@ ContiguousJSValues JSObject::genericConvertDoubleToContiguous(VM& vm)
             currentAsValue->clear();
             continue;
         }
-        JSValue v;
-        switch (mode) {
-        case EncodeValueAsDouble:
-            v = JSValue(JSValue::EncodeAsDouble, value);
-            break;
-        case RageConvertDoubleToValue:
-            v = jsNumber(value);
-            break;
-        default:
-            v = JSValue();
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-        }
-        ASSERT(v.isNumber());
+        JSValue v = JSValue(JSValue::EncodeAsDouble, value);
         currentAsValue->setWithoutWriteBarrier(v);
     }
     
@@ -848,28 +859,20 @@ ContiguousJSValues JSObject::genericConvertDoubleToContiguous(VM& vm)
     return m_butterfly->contiguous();
 }
 
-ContiguousJSValues JSObject::convertDoubleToContiguous(VM& vm)
-{
-    return genericConvertDoubleToContiguous<EncodeValueAsDouble>(vm);
-}
-
-ContiguousJSValues JSObject::rageConvertDoubleToContiguous(VM& vm)
-{
-    return genericConvertDoubleToContiguous<RageConvertDoubleToValue>(vm);
-}
-
-ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransition transition)
 {
     DeferGC deferGC(vm.heap);
     ASSERT(hasDouble(indexingType()));
-    
-    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
-    for (unsigned i = m_butterfly->publicLength(); i--;) {
+
+    unsigned vectorLength = m_butterfly->vectorLength();
+    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength);
+    for (unsigned i = 0; i < m_butterfly->publicLength(); i++) {
         double value = m_butterfly->contiguousDouble()[i];
-        if (value != value)
-            continue;
-        newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
-        newStorage->m_numValuesInVector++;
+        if (value == value) {
+            newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
+            newStorage->m_numValuesInVector++;
+        } else
+            ASSERT(newStorage->m_vector[i].get().isEmpty());
     }
     
     Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), transition);
@@ -877,28 +880,25 @@ ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransitio
     return newStorage;
 }
 
-ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransition transition)
-{
-    return convertDoubleToArrayStorage(vm, transition, m_butterfly->vectorLength());
-}
-
 ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm)
 {
     return convertDoubleToArrayStorage(vm, structure(vm)->suggestedArrayStorageTransition());
 }
 
-ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTransition transition)
 {
     DeferGC deferGC(vm.heap);
     ASSERT(hasContiguous(indexingType()));
-    
-    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
-    for (unsigned i = m_butterfly->publicLength(); i--;) {
+
+    unsigned vectorLength = m_butterfly->vectorLength();
+    ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength);
+    for (unsigned i = 0; i < m_butterfly->publicLength(); i++) {
         JSValue v = m_butterfly->contiguous()[i].get();
-        if (!v)
-            continue;
-        newStorage->m_vector[i].setWithoutWriteBarrier(v);
-        newStorage->m_numValuesInVector++;
+        if (v) {
+            newStorage->m_vector[i].setWithoutWriteBarrier(v);
+            newStorage->m_numValuesInVector++;
+        } else
+            ASSERT(newStorage->m_vector[i].get().isEmpty());
     }
     
     Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), transition);
@@ -906,11 +906,6 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTrans
     return newStorage;
 }
 
-ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTransition transition)
-{
-    return convertContiguousToArrayStorage(vm, transition, m_butterfly->vectorLength());
-}
-
 ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm)
 {
     return convertContiguousToArrayStorage(vm, structure(vm)->suggestedArrayStorageTransition());
@@ -953,7 +948,7 @@ void JSObject::convertInt32ForValue(VM& vm, JSValue value)
 {
     ASSERT(!value.isInt32());
     
-    if (value.isDouble()) {
+    if (value.isDouble() && !std::isnan(value.asDouble())) {
         convertInt32ToDouble(vm);
         return;
     }
@@ -1033,7 +1028,7 @@ ContiguousDoubles JSObject::ensureDoubleSlow(VM& vm)
     }
 }
 
-ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm, DoubleToContiguousMode mode)
+ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm)
 {
     ASSERT(inherits(info()));
     
@@ -1050,8 +1045,6 @@ ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm, DoubleToContiguousMode
         return convertInt32ToContiguous(vm);
         
     case ALL_DOUBLE_INDEXING_TYPES:
-        if (mode == RageConvertDoubleToValue)
-            return rageConvertDoubleToContiguous(vm);
         return convertDoubleToContiguous(vm);
         
     case ALL_ARRAY_STORAGE_INDEXING_TYPES:
@@ -1063,16 +1056,6 @@ ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm, DoubleToContiguousMode
     }
 }
 
-ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm)
-{
-    return ensureContiguousSlow(vm, EncodeValueAsDouble);
-}
-
-ContiguousJSValues JSObject::rageEnsureContiguousSlow(VM& vm)
-{
-    return ensureContiguousSlow(vm, RageConvertDoubleToValue);
-}
-
 ArrayStorage* JSObject::ensureArrayStorageSlow(VM& vm)
 {
     ASSERT(inherits(info()));
@@ -1217,13 +1200,30 @@ bool JSObject::allowsAccessFrom(ExecState* exec)
     return globalObject->globalObjectMethodTable()->allowsAccessFrom(globalObject, exec);
 }
 
+void JSObject::putGetter(ExecState* exec, PropertyName propertyName, JSValue getter)
+{
+    PropertyDescriptor descriptor;
+    descriptor.setGetter(getter);
+    descriptor.setEnumerable(true);
+    descriptor.setConfigurable(true);
+    defineOwnProperty(this, exec, propertyName, descriptor, false);
+}
+
+void JSObject::putSetter(ExecState* exec, PropertyName propertyName, JSValue setter)
+{
+    PropertyDescriptor descriptor;
+    descriptor.setSetter(setter);
+    descriptor.setEnumerable(true);
+    descriptor.setConfigurable(true);
+    defineOwnProperty(this, exec, propertyName, descriptor, false);
+}
+
 void JSObject::putDirectAccessor(ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes)
 {
     ASSERT(value.isGetterSetter() && (attributes & Accessor));
 
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex) {
-        putDirectIndex(exec, index, value, attributes, PutDirectIndexLikePutDirect);
+    if (Optional<uint32_t> index = parseIndex(propertyName)) {
+        putDirectIndex(exec, index.value(), value, attributes, PutDirectIndexLikePutDirect);
         return;
     }
 
@@ -1232,35 +1232,29 @@ void JSObject::putDirectAccessor(ExecState* exec, PropertyName propertyName, JSV
 
 void JSObject::putDirectCustomAccessor(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
 {
-    ASSERT(propertyName.asIndex() == PropertyName::NotAnIndex);
+    ASSERT(!parseIndex(propertyName));
 
     PutPropertySlot slot(this);
-    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
+    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
 
     ASSERT(slot.type() == PutPropertySlot::NewProperty);
 
     Structure* structure = this->structure(vm);
     if (attributes & ReadOnly)
         structure->setContainsReadOnlyProperties();
-    structure->setHasCustomGetterSetterProperties(propertyName == vm.propertyNames->underscoreProto);
+    structure->setHasCustomGetterSetterPropertiesWithProtoCheck(propertyName == vm.propertyNames->underscoreProto);
 }
 
 void JSObject::putDirectNonIndexAccessor(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
 {
     PutPropertySlot slot(this);
-    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
-
-    // putDirect will change our Structure if we add a new property. For
-    // getters and setters, though, we also need to change our Structure
-    // if we override an existing non-getter or non-setter.
-    if (slot.type() != PutPropertySlot::NewProperty)
-        setStructure(vm, Structure::attributeChangeTransition(vm, structure(vm), propertyName, attributes));
+    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
 
     Structure* structure = this->structure(vm);
     if (attributes & ReadOnly)
         structure->setContainsReadOnlyProperties();
 
-    structure->setHasGetterSetterProperties(propertyName == vm.propertyNames->underscoreProto);
+    structure->setHasGetterSetterPropertiesWithProtoCheck(propertyName == vm.propertyNames->underscoreProto);
 }
 
 bool JSObject::hasProperty(ExecState* exec, PropertyName propertyName) const
@@ -1280,17 +1274,15 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper
 {
     JSObject* thisObject = jsCast<JSObject*>(cell);
     
-    unsigned i = propertyName.asIndex();
-    if (i != PropertyName::NotAnIndex)
-        return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, i);
+    if (Optional<uint32_t> index = parseIndex(propertyName))
+        return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, index.value());
 
     if (!thisObject->staticFunctionsReified())
         thisObject->reifyStaticFunctionsForDelete(exec);
 
     unsigned attributes;
-    JSCell* specificValue;
     VM& vm = exec->vm();
-    if (isValidOffset(thisObject->structure(vm)->get(vm, propertyName, attributes, specificValue))) {
+    if (isValidOffset(thisObject->structure(vm)->get(vm, propertyName, attributes))) {
         if (attributes & DontDelete && !vm.isInDefineOwnProperty())
             return false;
         thisObject->removeDirect(vm, propertyName);
@@ -1298,13 +1290,16 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper
     }
 
     // Look in the static hashtable of properties
-    const HashTableValue* entry = thisObject->findPropertyHashEntry(vm, propertyName);
+    const HashTableValue* entry = thisObject->findPropertyHashEntry(propertyName);
     if (entry) {
         if (entry->attributes() & DontDelete && !vm.isInDefineOwnProperty())
             return false; // this builtin property can't be deleted
 
         PutPropertySlot slot(thisObject);
-        putEntry(exec, entry, thisObject, propertyName, jsUndefined(), slot);
+        if (!(entry->attributes() & BuiltinOrFunctionOrAccessor)) {
+            ASSERT(thisObject->staticFunctionsReified());
+            putEntry(exec, entry, thisObject, propertyName, jsUndefined(), slot);
+        }
     }
 
     return true;
@@ -1316,6 +1311,12 @@ bool JSObject::hasOwnProperty(ExecState* exec, PropertyName propertyName) const
     return const_cast<JSObject*>(this)->methodTable(exec->vm())->getOwnPropertySlot(const_cast<JSObject*>(this), exec, propertyName, slot);
 }
 
+bool JSObject::hasOwnProperty(ExecState* exec, unsigned propertyName) const
+{
+    PropertySlot slot(this);
+    return const_cast<JSObject*>(this)->methodTable(exec->vm())->getOwnPropertySlotByIndex(const_cast<JSObject*>(this), exec, propertyName, slot);
+}
+
 bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
 {
     JSObject* thisObject = jsCast<JSObject*>(cell);
@@ -1404,6 +1405,10 @@ bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& resu
 // ECMA 8.6.2.6
 JSValue JSObject::defaultValue(const JSObject* object, ExecState* exec, PreferredPrimitiveType hint)
 {
+    // Make sure that whatever default value methods there are on object's prototype chain are
+    // being watched.
+    object->structure()->startWatchingInternalPropertiesIfNecessaryForEntireChain(exec->vm());
+    
     // Must call toString first for Date objects.
     if ((hint == PreferString) || (hint != PreferNumber && object->prototype() == exec->lexicalGlobalObject()->datePrototype())) {
         JSValue value = callDefaultValueFunction(exec, object, exec->propertyNames().toString);
@@ -1426,11 +1431,11 @@ JSValue JSObject::defaultValue(const JSObject* object, ExecState* exec, Preferre
     return exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("No default value")));
 }
 
-const HashTableValue* JSObject::findPropertyHashEntry(VM& vm, PropertyName propertyName) const
+const HashTableValue* JSObject::findPropertyHashEntry(PropertyName propertyName) const
 {
     for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
-        if (const HashTable* propHashTable = info->propHashTable(vm)) {
-            if (const HashTableValue* entry = propHashTable->entry(vm, propertyName))
+        if (const HashTable* propHashTable = info->staticPropHashTable) {
+            if (const HashTableValue* entry = propHashTable->entry(propertyName))
                 return entry;
         }
     }
@@ -1445,7 +1450,7 @@ bool JSObject::hasInstance(ExecState* exec, JSValue value)
         return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype));
     if (info.implementsHasInstance())
         return methodTable(vm)->customHasInstance(this, exec, value);
-    vm.throwException(exec, createInvalidParameterError(exec, "instanceof" , this));
+    vm.throwException(exec, createInvalidInstanceofParameterError(exec, this));
     return false;
 }
 
@@ -1467,23 +1472,8 @@ bool JSObject::defaultHasInstance(ExecState* exec, JSValue value, JSValue proto)
     return false;
 }
 
-bool JSObject::getPropertySpecificValue(ExecState* exec, PropertyName propertyName, JSCell*& specificValue) const
-{
-    VM& vm = exec->vm();
-    unsigned attributes;
-    if (isValidOffset(structure(vm)->get(vm, propertyName, attributes, specificValue)))
-        return true;
-
-    // This could be a function within the static table? - should probably
-    // also look in the hash?  This currently should not be a problem, since
-    // we've currently always call 'get' first, which should have populated
-    // the normal storage.
-    return false;
-}
-
 void JSObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    propertyNames.setBaseObject(object);
     object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, propertyNames, mode);
 
     if (object->prototype().isNull())
@@ -1506,6 +1496,12 @@ void JSObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameA
 
 void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
+    if (!mode.includeJSObjectProperties()) {
+        // We still have to get non-indexed properties from any subclasses of JSObject that have them.
+        object->methodTable(exec->vm())->getOwnNonIndexPropertyNames(object, exec, propertyNames, mode);
+        return;
+    }
+
     // Add numeric properties first. That appears to be the accepted convention.
     // FIXME: Filling PropertyNameArray with an identifier for every integer
     // is incredibly inefficient for large arrays. We need a different approach,
@@ -1522,7 +1518,7 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
         for (unsigned i = 0; i < usedLength; ++i) {
             if (!butterfly->contiguous()[i])
                 continue;
-            propertyNames.add(Identifier::from(exec, i));
+            propertyNames.add(i);
         }
         break;
     }
@@ -1534,7 +1530,7 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
             double value = butterfly->contiguousDouble()[i];
             if (value != value)
                 continue;
-            propertyNames.add(Identifier::from(exec, i));
+            propertyNames.add(i);
         }
         break;
     }
@@ -1545,7 +1541,7 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
         unsigned usedVectorLength = std::min(storage->length(), storage->vectorLength());
         for (unsigned i = 0; i < usedVectorLength; ++i) {
             if (storage->m_vector[i])
-                propertyNames.add(Identifier::from(exec, i));
+                propertyNames.add(i);
         }
         
         if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
@@ -1554,13 +1550,13 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
             
             SparseArrayValueMap::const_iterator end = map->end();
             for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
-                if (mode == IncludeDontEnumProperties || !(it->value.attributes & DontEnum))
+                if (mode.includeDontEnumProperties() || !(it->value.attributes & DontEnum))
                     keys.uncheckedAppend(static_cast<unsigned>(it->key));
             }
             
             std::sort(keys.begin(), keys.end());
             for (unsigned i = 0; i < keys.size(); ++i)
-                propertyNames.add(Identifier::from(exec, keys[i]));
+                propertyNames.add(keys[i]);
         }
         break;
     }
@@ -1568,7 +1564,7 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
     default:
         RELEASE_ASSERT_NOT_REACHED();
     }
-    
+
     object->methodTable(exec->vm())->getOwnNonIndexPropertyNames(object, exec, propertyNames, mode);
 }
 
@@ -1576,12 +1572,11 @@ void JSObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pr
 {
     getClassPropertyNames(exec, object->classInfo(), propertyNames, mode, object->staticFunctionsReified());
 
+    if (!mode.includeJSObjectProperties())
+        return;
+    
     VM& vm = exec->vm();
-    bool canCachePropertiesFromStructure = !propertyNames.size();
     object->structure(vm)->getPropertyNamesFromStructure(vm, propertyNames, mode);
-
-    if (canCachePropertiesFromStructure)
-        propertyNames.setNumCacheableSlotsForObject(object, propertyNames.size());
 }
 
 double JSObject::toNumber(ExecState* exec) const
@@ -1605,6 +1600,16 @@ JSValue JSObject::toThis(JSCell* cell, ExecState*, ECMAMode)
     return jsCast<JSObject*>(cell);
 }
 
+bool JSObject::isCatchScopeObject() const
+{
+    return inherits(JSCatchScope::info());
+}
+
+bool JSObject::isFunctionNameScopeObject() const
+{
+    return inherits(JSFunctionNameScope::info());
+}
+
 void JSObject::seal(VM& vm)
 {
     if (isSealed(vm))
@@ -1638,7 +1643,7 @@ void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
     // If this object's ClassInfo has no static properties, then nothing to reify!
     // We can safely set the flag to avoid the expensive check again in the future.
     if (!classInfo()->hasStaticProperties()) {
-        structure(vm)->setStaticFunctionsReified();
+        structure(vm)->setStaticFunctionsReified(true);
         return;
     }
 
@@ -1646,17 +1651,17 @@ void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
         setStructure(vm, Structure::toUncacheableDictionaryTransition(vm, structure(vm)));
 
     for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
-        const HashTable* hashTable = info->propHashTable(vm);
+        const HashTable* hashTable = info->staticPropHashTable;
         if (!hashTable)
             continue;
         PropertySlot slot(this);
-        for (auto iter = hashTable->begin(vm); iter != hashTable->end(vm); ++iter) {
-            if (iter->attributes() & BuiltinOrFunction)
-                setUpStaticFunctionSlot(globalObject()->globalExec(), iter.value(), this, Identifier(&vm, iter.key()), slot);
+        for (auto iter = hashTable->begin(); iter != hashTable->end(); ++iter) {
+            if (iter->attributes() & BuiltinOrFunctionOrAccessor)
+                setUpStaticFunctionSlot(globalObject()->globalExec(), iter.value(), this, Identifier::fromString(&vm, iter.key()), slot);
         }
     }
 
-    structure(vm)->setStaticFunctionsReified();
+    structure(vm)->setStaticFunctionsReified(true);
 }
 
 bool JSObject::removeDirect(VM& vm, PropertyName propertyName)
@@ -1716,11 +1721,11 @@ void JSObject::putIndexedDescriptor(ExecState* exec, SparseArrayEntry* entryInMa
         else if (oldDescriptor.isAccessorDescriptor())
             setter = oldDescriptor.setterObject();
 
-        GetterSetter* accessor = GetterSetter::create(vm);
+        GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
         if (getter)
-            accessor->setGetter(vm, getter);
+            accessor->setGetter(vm, exec->lexicalGlobalObject(), getter);
         if (setter)
-            accessor->setSetter(vm, setter);
+            accessor->setSetter(vm, exec->lexicalGlobalObject(), setter);
 
         entryInMap->set(vm, map, accessor);
         entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor) & ~ReadOnly;
@@ -2458,6 +2463,21 @@ void JSObject::ensureLengthSlow(VM& vm, unsigned length)
     }
 }
 
+void JSObject::reallocateAndShrinkButterfly(VM& vm, unsigned length)
+{
+    ASSERT(length < MAX_ARRAY_INDEX);
+    ASSERT(length < MAX_STORAGE_VECTOR_LENGTH);
+    ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType()));
+    ASSERT(m_butterfly->vectorLength() > length);
+    ASSERT(!m_butterfly->indexingHeader()->preCapacity(structure()));
+
+    DeferGC deferGC(vm.heap);
+    Butterfly* newButterfly = m_butterfly->resizeArray(vm, this, structure(), 0, ArrayStorage::sizeFor(length));
+    m_butterfly.set(vm, this, newButterfly);
+    m_butterfly->setVectorLength(length);
+    m_butterfly->setPublicLength(length);
+}
+
 Butterfly* JSObject::growOutOfLineStorage(VM& vm, size_t oldSize, size_t newSize)
 {
     ASSERT(newSize > oldSize);
@@ -2490,11 +2510,11 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
     VM& vm = exec->vm();
     if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) {
         if (descriptor.isGenericDescriptor() && oldDescriptor.isAccessorDescriptor()) {
-            GetterSetter* accessor = GetterSetter::create(vm);
+            GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
             if (oldDescriptor.getterPresent())
-                accessor->setGetter(vm, oldDescriptor.getterObject());
+                accessor->setGetter(vm, exec->lexicalGlobalObject(), oldDescriptor.getterObject());
             if (oldDescriptor.setterPresent())
-                accessor->setSetter(vm, oldDescriptor.setterObject());
+                accessor->setSetter(vm, exec->lexicalGlobalObject(), oldDescriptor.setterObject());
             target->putDirectAccessor(exec, propertyName, accessor, attributes | Accessor);
             return true;
         }
@@ -2509,16 +2529,16 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
         return true;
     }
     attributes &= ~ReadOnly;
-    GetterSetter* accessor = GetterSetter::create(vm);
+    GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
 
     if (descriptor.getterPresent())
-        accessor->setGetter(vm, descriptor.getterObject());
+        accessor->setGetter(vm, exec->lexicalGlobalObject(), descriptor.getterObject());
     else if (oldDescriptor.getterPresent())
-        accessor->setGetter(vm, oldDescriptor.getterObject());
+        accessor->setGetter(vm, exec->lexicalGlobalObject(), oldDescriptor.getterObject());
     if (descriptor.setterPresent())
-        accessor->setSetter(vm, descriptor.setterObject());
+        accessor->setSetter(vm, exec->lexicalGlobalObject(), descriptor.setterObject());
     else if (oldDescriptor.setterPresent())
-        accessor->setSetter(vm, oldDescriptor.setterObject());
+        accessor->setSetter(vm, exec->lexicalGlobalObject(), oldDescriptor.setterObject());
 
     target->putDirectAccessor(exec, propertyName, accessor, attributes | Accessor);
     return true;
@@ -2526,11 +2546,10 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
 
 void JSObject::putDirectMayBeIndex(ExecState* exec, PropertyName propertyName, JSValue value)
 {
-    unsigned asIndex = propertyName.asIndex();
-    if (asIndex == PropertyName::NotAnIndex)
-        putDirect(exec->vm(), propertyName, value);
+    if (Optional<uint32_t> index = parseIndex(propertyName))
+        putDirectIndex(exec, index.value(), value);
     else
-        putDirectIndex(exec, asIndex, value);
+        putDirect(exec->vm(), propertyName, value);
 }
 
 class DefineOwnPropertyScope {
@@ -2582,7 +2601,7 @@ bool JSObject::defineOwnNonIndexProperty(ExecState* exec, PropertyName propertyN
     if (!current.configurable()) {
         if (descriptor.configurable()) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
             return false;
         }
         if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) {
@@ -2657,17 +2676,22 @@ bool JSObject::defineOwnNonIndexProperty(ExecState* exec, PropertyName propertyN
     if (!accessor)
         return false;
     GetterSetter* getterSetter;
+    bool getterSetterChanged = false;
     if (accessor.isCustomGetterSetter())
-        getterSetter = GetterSetter::create(exec->vm());
+        getterSetter = GetterSetter::create(exec->vm(), exec->lexicalGlobalObject());
     else {
         ASSERT(accessor.isGetterSetter());
         getterSetter = asGetterSetter(accessor);
     }
-    if (descriptor.setterPresent())
-        getterSetter->setSetter(exec->vm(), descriptor.setterObject());
-    if (descriptor.getterPresent())
-        getterSetter->setGetter(exec->vm(), descriptor.getterObject());
-    if (current.attributesEqual(descriptor))
+    if (descriptor.setterPresent()) {
+        getterSetter = getterSetter->withSetter(exec->vm(), exec->lexicalGlobalObject(), descriptor.setterObject());
+        getterSetterChanged = true;
+    }
+    if (descriptor.getterPresent()) {
+        getterSetter = getterSetter->withGetter(exec->vm(), exec->lexicalGlobalObject(), descriptor.getterObject());
+        getterSetterChanged = true;
+    }
+    if (current.attributesEqual(descriptor) && !getterSetterChanged)
         return true;
     methodTable(exec->vm())->deleteProperty(this, exec, propertyName);
     unsigned attrs = descriptor.attributesOverridingCurrent(current);
@@ -2678,15 +2702,14 @@ bool JSObject::defineOwnNonIndexProperty(ExecState* exec, PropertyName propertyN
 bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool throwException)
 {
     // If it's an array index, then use the indexed property storage.
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex) {
+    if (Optional<uint32_t> index = parseIndex(propertyName)) {
         // c. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing P, Desc, and false as arguments.
         // d. Reject if succeeded is false.
         // e. If index >= oldLen
         // e.i. Set oldLenDesc.[[Value]] to index + 1.
         // e.ii. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", oldLenDesc, and false as arguments. This call will always return true.
         // f. Return true.
-        return object->defineOwnIndexedProperty(exec, index, descriptor, throwException);
+        return object->defineOwnIndexedProperty(exec, index.value(), descriptor, throwException);
     }
     
     return object->defineOwnNonIndexProperty(exec, propertyName, descriptor, throwException);
@@ -2708,4 +2731,84 @@ void JSObject::shiftButterflyAfterFlattening(VM& vm, size_t outOfLineCapacityBef
     setButterflyWithoutChangingStructure(vm, Butterfly::fromBase(newBase, preCapacity, outOfLineCapacityAfter));
 }
 
+uint32_t JSObject::getEnumerableLength(ExecState* exec, JSObject* object)
+{
+    VM& vm = exec->vm();
+    Structure* structure = object->structure(vm);
+    if (structure->holesMustForwardToPrototype(vm))
+        return 0;
+    switch (object->indexingType()) {
+    case ALL_BLANK_INDEXING_TYPES:
+    case ALL_UNDECIDED_INDEXING_TYPES:
+        return 0;
+        
+    case ALL_INT32_INDEXING_TYPES:
+    case ALL_CONTIGUOUS_INDEXING_TYPES: {
+        Butterfly* butterfly = object->butterfly();
+        unsigned usedLength = butterfly->publicLength();
+        for (unsigned i = 0; i < usedLength; ++i) {
+            if (!butterfly->contiguous()[i])
+                return 0;
+        }
+        return usedLength;
+    }
+        
+    case ALL_DOUBLE_INDEXING_TYPES: {
+        Butterfly* butterfly = object->butterfly();
+        unsigned usedLength = butterfly->publicLength();
+        for (unsigned i = 0; i < usedLength; ++i) {
+            double value = butterfly->contiguousDouble()[i];
+            if (value != value)
+                return 0;
+        }
+        return usedLength;
+    }
+        
+    case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
+        ArrayStorage* storage = object->m_butterfly->arrayStorage();
+        if (storage->m_sparseMap.get())
+            return 0;
+        
+        unsigned usedVectorLength = std::min(storage->length(), storage->vectorLength());
+        for (unsigned i = 0; i < usedVectorLength; ++i) {
+            if (!storage->m_vector[i])
+                return 0;
+        }
+        return usedVectorLength;
+    }
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return 0;
+    }
+}
+
+void JSObject::getStructurePropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    VM& vm = exec->vm();
+    object->structure(vm)->getPropertyNamesFromStructure(vm, propertyNames, mode);
+}
+
+void JSObject::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    VM& vm = exec->vm();
+    object->methodTable(vm)->getOwnPropertyNames(object, exec, propertyNames, EnumerationMode(mode, JSObjectPropertiesMode::Exclude));
+
+    if (object->prototype().isNull())
+        return;
+
+    JSObject* prototype = asObject(object->prototype());
+    while (true) {
+        if (prototype->structure(vm)->typeInfo().overridesGetPropertyNames()) {
+            prototype->methodTable(vm)->getPropertyNames(prototype, exec, propertyNames, mode);
+            break;
+        }
+        prototype->methodTable(vm)->getOwnPropertyNames(prototype, exec, propertyNames, mode);
+        JSValue nextProto = prototype->prototype();
+        if (nextProto.isNull())
+            break;
+        prototype = asObject(nextProto);
+    }
+}
+
 } // namespace JSC
index 3d084908268c3214660fdf8d334f4919d5461cdb..5c9622cc4de4adabe51136c239c5ea1732382f2f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2009, 2012-2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -57,15 +57,6 @@ inline JSCell* getJSFunction(JSValue value)
     return 0;
 }
 
-JS_EXPORT_PRIVATE JSCell* getCallableObjectSlow(JSCell*);
-
-inline JSCell* getCallableObject(JSValue value)
-{
-    if (!value.isCell())
-        return 0;
-    return getCallableObjectSlow(value.asCell());
-}
-
 class GetterSetter;
 class InternalFunction;
 class JSFunction;
@@ -109,10 +100,11 @@ public:
     JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
 
     JS_EXPORT_PRIVATE static String className(const JSObject*);
+    JS_EXPORT_PRIVATE static String calculatedClassName(JSObject*);
 
     JSValue prototype() const;
-    void setPrototype(VM&, JSValue prototype);
-    bool setPrototypeWithCycleCheck(ExecState*, JSValue prototype);
+    JS_EXPORT_PRIVATE void setPrototype(VM&, JSValue prototype);
+    JS_EXPORT_PRIVATE bool setPrototypeWithCycleCheck(ExecState*, JSValue prototype);
         
     bool mayInterceptIndexedAccesses()
     {
@@ -132,9 +124,9 @@ public:
     // The key difference between this and getOwnPropertySlot is that getOwnPropertySlot
     // currently returns incorrect results for the DOM window (with non-own properties)
     // being returned. Once this is fixed we should migrate code & remove this method.
-    bool getOwnPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
+    JS_EXPORT_PRIVATE bool getOwnPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
 
-    bool allowsAccessFrom(ExecState*);
+    JS_EXPORT_PRIVATE bool allowsAccessFrom(ExecState*);
 
     unsigned getArrayLength() const
     {
@@ -153,7 +145,7 @@ public:
     JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
         
-    void putByIndexInline(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
+    ALWAYS_INLINE void putByIndexInline(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
     {
         if (canSetIndexQuickly(propertyName)) {
             setIndexQuickly(exec->vm(), propertyName, value);
@@ -372,10 +364,15 @@ public:
             RELEASE_ASSERT_NOT_REACHED();
         }
     }
-        
+
     void initializeIndex(VM& vm, unsigned i, JSValue v)
     {
-        switch (indexingType()) {
+        initializeIndex(vm, i, v, indexingType());
+    }
+
+    void initializeIndex(VM& vm, unsigned i, JSValue v, IndexingType indexingType)
+    {
+        switch (indexingType) {
         case ALL_UNDECIDED_INDEXING_TYPES: {
             setIndexQuicklyToUndecided(vm, i, v);
             break;
@@ -432,7 +429,7 @@ public:
         case ALL_CONTIGUOUS_INDEXING_TYPES:
             return false;
         case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return m_butterfly->arrayStorage()->m_sparseMap;
+            return !!m_butterfly->arrayStorage()->m_sparseMap;
         default:
             RELEASE_ASSERT_NOT_REACHED();
             return false;
@@ -470,9 +467,13 @@ public:
     void putDirectAccessor(ExecState*, PropertyName, JSValue, unsigned attributes);
     JS_EXPORT_PRIVATE void putDirectCustomAccessor(VM&, PropertyName, JSValue, unsigned attributes);
 
+    void putGetter(ExecState*, PropertyName, JSValue);
+    void putSetter(ExecState*, PropertyName, JSValue);
+
     JS_EXPORT_PRIVATE bool hasProperty(ExecState*, PropertyName) const;
     JS_EXPORT_PRIVATE bool hasProperty(ExecState*, unsigned propertyName) const;
     bool hasOwnProperty(ExecState*, PropertyName) const;
+    bool hasOwnProperty(ExecState*, unsigned) const;
 
     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
@@ -486,6 +487,10 @@ public:
     JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
+    JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(ExecState*, JSObject*);
+    JS_EXPORT_PRIVATE static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+
     JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
     bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
     JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
@@ -493,8 +498,6 @@ public:
 
     JS_EXPORT_PRIVATE static JSValue toThis(JSCell*, ExecState*, ECMAMode);
 
-    bool getPropertySpecificValue(ExecState*, PropertyName, JSCell*& specificFunction) const;
-
     // This get function only looks at the property map.
     JSValue getDirect(VM& vm, PropertyName propertyName) const
     {
@@ -503,12 +506,11 @@ public:
         checkOffset(offset, structure->inlineCapacity());
         return offset != invalidOffset ? getDirect(offset) : JSValue();
     }
-
+    
     JSValue getDirect(VM& vm, PropertyName propertyName, unsigned& attributes) const
     {
-        JSCell* specific;
         Structure* structure = this->structure(vm);
-        PropertyOffset offset = structure->get(vm, propertyName, attributes, specific);
+        PropertyOffset offset = structure->get(vm, propertyName, attributes);
         checkOffset(offset, structure->inlineCapacity());
         return offset != invalidOffset ? getDirect(offset) : JSValue();
     }
@@ -523,9 +525,8 @@ public:
 
     PropertyOffset getDirectOffset(VM& vm, PropertyName propertyName, unsigned& attributes)
     {
-        JSCell* specific;
         Structure* structure = this->structure(vm);
-        PropertyOffset offset = structure->get(vm, propertyName, attributes, specific);
+        PropertyOffset offset = structure->get(vm, propertyName, attributes);
         checkOffset(offset, structure->inlineCapacity());
         return offset;
     }
@@ -581,7 +582,7 @@ public:
     //  - assumes the object contains no own getter/setter properties.
     //  - provides no special handling for __proto__
     //  - does not walk the prototype chain (to check for accessors or non-writable properties).
-    // This is used by JSActivation.
+    // This is used by JSLexicalEnvironment.
     bool putOwnDataProperty(VM&, PropertyName, JSValue, PutPropertySlot&);
 
     // Fast access to known property offsets.
@@ -592,7 +593,7 @@ public:
     JS_EXPORT_PRIVATE void putDirectNativeFunction(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
     JS_EXPORT_PRIVATE JSFunction* putDirectBuiltinFunction(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
     JSFunction* putDirectBuiltinFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
-    void putDirectNativeFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
+    JS_EXPORT_PRIVATE void putDirectNativeFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
 
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
 
@@ -600,11 +601,14 @@ public:
     bool isVariableObject() const;
     bool isStaticScopeObject() const;
     bool isNameScopeObject() const;
+    bool isCatchScopeObject() const;
+    bool isFunctionNameScopeObject() const;
     bool isActivationObject() const;
     bool isErrorInstance() const;
+    bool isWithScope() const;
 
-    void seal(VM&);
-    void freeze(VM&);
+    JS_EXPORT_PRIVATE void seal(VM&);
+    JS_EXPORT_PRIVATE void freeze(VM&);
     JS_EXPORT_PRIVATE void preventExtensions(VM&);
     bool isSealed(VM& vm) { return structure(vm)->isSealed(vm); }
     bool isFrozen(VM& vm) { return structure(vm)->isFrozen(vm); }
@@ -688,18 +692,7 @@ public:
             
         return ensureContiguousSlow(vm);
     }
-        
-    // Same as ensureContiguous(), except that if the indexed storage is in
-    // double mode, then it does a rage conversion to contiguous: it
-    // attempts to convert each double to an int32.
-    ContiguousJSValues rageEnsureContiguous(VM& vm)
-    {
-        if (LIKELY(hasContiguous(indexingType())))
-            return m_butterfly->contiguous();
-            
-        return rageEnsureContiguousSlow(vm);
-    }
-        
+
     // Ensure that the object is in a mode where it has array storage. Use
     // this if you're about to perform actions that would have required the
     // object to be converted to have array storage, if it didn't have it
@@ -731,8 +724,6 @@ protected:
     {
         Base::finishCreation(vm);
         ASSERT(inherits(info()));
-        ASSERT(!structure()->outOfLineCapacity());
-        ASSERT(structure()->isEmpty());
         ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
         ASSERT(structure()->isObject());
         ASSERT(classInfo());
@@ -789,23 +780,18 @@ protected:
     ContiguousJSValues convertUndecidedToInt32(VM&);
     ContiguousDoubles convertUndecidedToDouble(VM&);
     ContiguousJSValues convertUndecidedToContiguous(VM&);
-    ArrayStorage* convertUndecidedToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
     ArrayStorage* convertUndecidedToArrayStorage(VM&, NonPropertyTransition);
     ArrayStorage* convertUndecidedToArrayStorage(VM&);
         
     ContiguousDoubles convertInt32ToDouble(VM&);
     ContiguousJSValues convertInt32ToContiguous(VM&);
-    ArrayStorage* convertInt32ToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
     ArrayStorage* convertInt32ToArrayStorage(VM&, NonPropertyTransition);
     ArrayStorage* convertInt32ToArrayStorage(VM&);
     
     ContiguousJSValues convertDoubleToContiguous(VM&);
-    ContiguousJSValues rageConvertDoubleToContiguous(VM&);
-    ArrayStorage* convertDoubleToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
     ArrayStorage* convertDoubleToArrayStorage(VM&, NonPropertyTransition);
     ArrayStorage* convertDoubleToArrayStorage(VM&);
         
-    ArrayStorage* convertContiguousToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
     ArrayStorage* convertContiguousToArrayStorage(VM&, NonPropertyTransition);
     ArrayStorage* convertContiguousToArrayStorage(VM&);
 
@@ -841,109 +827,16 @@ protected:
             m_butterfly->setPublicLength(length);
     }
         
+    // Call this if you want to shrink the butterfly backing store, and you're
+    // sure that the array is contiguous.
+    void reallocateAndShrinkButterfly(VM&, unsigned length);
+    
     template<IndexingType indexingShape>
     unsigned countElements(Butterfly*);
         
     // This is relevant to undecided, int32, double, and contiguous.
     unsigned countElements();
         
-    // This strange method returns a pointer to the start of the indexed data
-    // as if it contained JSValues. But it won't always contain JSValues.
-    // Make sure you cast this to the appropriate type before using.
-    template<IndexingType indexingType>
-    ContiguousJSValues indexingData()
-    {
-        switch (indexingType) {
-        case ALL_INT32_INDEXING_TYPES:
-        case ALL_DOUBLE_INDEXING_TYPES:
-        case ALL_CONTIGUOUS_INDEXING_TYPES:
-            return m_butterfly->contiguous();
-                
-        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return m_butterfly->arrayStorage()->vector();
-
-        default:
-            CRASH();
-            return ContiguousJSValues();
-        }
-    }
-
-    ContiguousJSValues currentIndexingData()
-    {
-        switch (indexingType()) {
-        case ALL_INT32_INDEXING_TYPES:
-        case ALL_CONTIGUOUS_INDEXING_TYPES:
-            return m_butterfly->contiguous();
-
-        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return m_butterfly->arrayStorage()->vector();
-
-        default:
-            CRASH();
-            return ContiguousJSValues();
-        }
-    }
-        
-    JSValue getHolyIndexQuickly(unsigned i)
-    {
-        ASSERT(i < m_butterfly->vectorLength());
-        switch (indexingType()) {
-        case ALL_INT32_INDEXING_TYPES:
-        case ALL_CONTIGUOUS_INDEXING_TYPES:
-            return m_butterfly->contiguous()[i].get();
-        case ALL_DOUBLE_INDEXING_TYPES: {
-            double value = m_butterfly->contiguousDouble()[i];
-            if (value == value)
-                return JSValue(JSValue::EncodeAsDouble, value);
-            return JSValue();
-        }
-        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return m_butterfly->arrayStorage()->m_vector[i].get();
-        default:
-            CRASH();
-            return JSValue();
-        }
-    }
-        
-    template<IndexingType indexingType>
-    unsigned relevantLength()
-    {
-        switch (indexingType) {
-        case ALL_INT32_INDEXING_TYPES:
-        case ALL_DOUBLE_INDEXING_TYPES:
-        case ALL_CONTIGUOUS_INDEXING_TYPES:
-            return m_butterfly->publicLength();
-                
-        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return std::min(
-                m_butterfly->arrayStorage()->length(),
-                m_butterfly->arrayStorage()->vectorLength());
-                
-        default:
-            CRASH();
-            return 0;
-        }
-    }
-
-    unsigned currentRelevantLength()
-    {
-        switch (indexingType()) {
-        case ALL_INT32_INDEXING_TYPES:
-        case ALL_DOUBLE_INDEXING_TYPES:
-        case ALL_CONTIGUOUS_INDEXING_TYPES:
-            return m_butterfly->publicLength();
-
-        case ALL_ARRAY_STORAGE_INDEXING_TYPES:
-            return std::min(
-                m_butterfly->arrayStorage()->length(),
-                m_butterfly->arrayStorage()->vectorLength());
-
-        default:
-            CRASH();
-            return 0;
-        }
-    }
-
 private:
     friend class LLIntOffsetsExtractor;
         
@@ -960,13 +853,13 @@ private:
     ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(VM&, ArrayStorage*);
         
     template<PutMode>
-    bool putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
+    bool putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&);
 
     bool inlineGetOwnPropertySlot(VM&, Structure&, PropertyName, PropertySlot&);
     JS_EXPORT_PRIVATE void fillGetterPropertySlot(PropertySlot&, JSValue, unsigned, PropertyOffset);
     void fillCustomGetterPropertySlot(PropertySlot&, JSValue, unsigned, Structure&);
 
-    const HashTableValue* findPropertyHashEntry(VM&, PropertyName) const;
+    const HashTableValue* findPropertyHashEntry(PropertyName) const;
         
     void putIndexedDescriptor(ExecState*, SparseArrayEntry*, const PropertyDescriptor&, PropertyDescriptor& old);
         
@@ -988,14 +881,8 @@ private:
     ContiguousJSValues ensureInt32Slow(VM&);
     ContiguousDoubles ensureDoubleSlow(VM&);
     ContiguousJSValues ensureContiguousSlow(VM&);
-    ContiguousJSValues rageEnsureContiguousSlow(VM&);
-    ArrayStorage* ensureArrayStorageSlow(VM&);
-    
-    enum DoubleToContiguousMode { EncodeValueAsDouble, RageConvertDoubleToValue };
-    template<DoubleToContiguousMode mode>
-    ContiguousJSValues genericConvertDoubleToContiguous(VM&);
-    ContiguousJSValues ensureContiguousSlow(VM&, DoubleToContiguousMode);
-    
+    JS_EXPORT_PRIVATE ArrayStorage* ensureArrayStorageSlow(VM&);
+
 protected:
     CopyWriteBarrier<Butterfly> m_butterfly;
 #if USE(JSVALUE32_64)
@@ -1027,7 +914,7 @@ protected:
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
-        ASSERT(!this->structure()->totalStorageCapacity());
+        ASSERT(!this->structure()->hasInlineStorage());
         ASSERT(classInfo());
     }
 };
@@ -1041,6 +928,7 @@ class JSFinalObject : public JSObject {
 
 public:
     typedef JSObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     static size_t allocationSize(size_t inlineCapacity)
     {
@@ -1059,7 +947,7 @@ public:
         return (maxSize - allocationSize(0)) / sizeof(WriteBarrier<Unknown>);
     }
 
-    static JSFinalObject* create(ExecState*, Structure*);
+    static JSFinalObject* create(ExecState*, Structure*, Butterfly* = nullptr);
     static JSFinalObject* create(VM&, Structure*);
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, unsigned inlineCapacity)
     {
@@ -1083,15 +971,14 @@ protected:
 private:
     friend class LLIntOffsetsExtractor;
 
-    explicit JSFinalObject(VM& vm, Structure* structure)
-        : JSObject(vm, structure)
+    explicit JSFinalObject(VM& vm, Structure* structure, Butterfly* butterfly = nullptr)
+        : JSObject(vm, structure, butterfly)
     {
     }
-
-    static const unsigned StructureFlags = JSObject::StructureFlags;
 };
 
-inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
+inline JSFinalObject* JSFinalObject::create(
+    ExecState* exec, Structure* structure, Butterfly* butterfly)
 {
     JSFinalObject* finalObject = new (
         NotNull, 
@@ -1099,7 +986,7 @@ inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structur
             *exec->heap(),
             allocationSize(structure->inlineCapacity())
         )
-    ) JSFinalObject(exec->vm(), structure);
+    ) JSFinalObject(exec->vm(), structure, butterfly);
     finalObject->finishCreation(exec->vm());
     return finalObject;
 }
@@ -1142,7 +1029,6 @@ inline bool JSObject::isStaticScopeObject() const
     return type == NameScopeObjectType || type == ActivationObjectType;
 }
 
-
 inline bool JSObject::isNameScopeObject() const
 {
     return type() == NameScopeObjectType;
@@ -1158,6 +1044,11 @@ inline bool JSObject::isErrorInstance() const
     return type() == ErrorInstanceType;
 }
 
+inline bool JSObject::isWithScope() const
+{
+    return type() == WithScopeType;
+}
+
 inline void JSObject::setStructureAndButterfly(VM& vm, Structure* structure, Butterfly* butterfly)
 {
     ASSERT(structure);
@@ -1218,8 +1109,7 @@ inline JSValue JSObject::prototype() const
 ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(VM& vm, Structure& structure, PropertyName propertyName, PropertySlot& slot)
 {
     unsigned attributes;
-    JSCell* specific;
-    PropertyOffset offset = structure.get(vm, propertyName, attributes, specific);
+    PropertyOffset offset = structure.get(vm, propertyName, attributes);
     if (!isValidOffset(offset))
         return false;
 
@@ -1252,9 +1142,8 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(JSObject* object, ExecState* exe
     Structure& structure = *object->structure(vm);
     if (object->inlineGetOwnPropertySlot(vm, structure, propertyName, slot))
         return true;
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex)
-        return getOwnPropertySlotByIndex(object, exec, index, slot);
+    if (Optional<uint32_t> index = parseIndex(propertyName))
+        return getOwnPropertySlotByIndex(object, exec, index.value(), slot);
     return false;
 }
 
@@ -1282,9 +1171,8 @@ ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, PropertyName prope
         object = asObject(prototype);
     }
 
-    unsigned index = propertyName.asIndex();
-    if (index != PropertyName::NotAnIndex)
-        return getPropertySlot(exec, index, slot);
+    if (Optional<uint32_t> index = parseIndex(propertyName))
+        return getPropertySlot(exec, index.value(), slot);
     return false;
 }
 
@@ -1323,35 +1211,29 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
 }
 
 template<JSObject::PutMode mode>
-inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot, JSCell* specificFunction)
+inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot)
 {
     ASSERT(value);
     ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
-    ASSERT(propertyName.asIndex() == PropertyName::NotAnIndex);
+    ASSERT(!parseIndex(propertyName));
 
     Structure* structure = this->structure(vm);
     if (structure->isDictionary()) {
         unsigned currentAttributes;
-        JSCell* currentSpecificFunction;
-        PropertyOffset offset = structure->get(vm, propertyName, currentAttributes, currentSpecificFunction);
+        PropertyOffset offset = structure->get(vm, propertyName, currentAttributes);
         if (offset != invalidOffset) {
-            // If there is currently a specific function, and there now either isn't,
-            // or the new value is different, then despecify.
-            if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
-                structure->despecifyDictionaryFunction(vm, propertyName);
             if ((mode == PutModePut) && currentAttributes & ReadOnly)
                 return false;
 
             putDirect(vm, offset, value);
-            // At this point, the objects structure only has a specific value set if previously there
-            // had been one set, and if the new value being specified is the same (otherwise we would
-            // have despecified, above).  So, if currentSpecificFunction is not set, or if the new
-            // value is different (or there is no new value), then the slot now has no value - and
-            // as such it is cachable.
-            // If there was previously a value, and the new value is the same, then we cannot cache.
-            if (!currentSpecificFunction || (specificFunction != currentSpecificFunction))
-                slot.setExistingProperty(this, offset);
+            structure->didReplaceProperty(offset);
+            slot.setExistingProperty(this, offset);
+
+            if ((attributes & Accessor) != (currentAttributes & Accessor)) {
+                ASSERT(!(attributes & ReadOnly));
+                setStructure(vm, Structure::attributeChangeTransition(vm, structure, propertyName, attributes));
+            }
             return true;
         }
 
@@ -1362,15 +1244,13 @@ inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSVal
         Butterfly* newButterfly = butterfly();
         if (this->structure()->putWillGrowOutOfLineStorage())
             newButterfly = growOutOfLineStorage(vm, this->structure()->outOfLineCapacity(), this->structure()->suggestedNewOutOfLineStorageCapacity());
-        offset = this->structure()->addPropertyWithoutTransition(vm, propertyName, attributes, specificFunction);
+        offset = this->structure()->addPropertyWithoutTransition(vm, propertyName, attributes);
         setStructureAndButterfly(vm, this->structure(), newButterfly);
 
         validateOffset(offset);
         ASSERT(this->structure()->isValidOffset(offset));
         putDirect(vm, offset, value);
-        // See comment on setNewProperty call below.
-        if (!specificFunction)
-            slot.setNewProperty(this, offset);
+        slot.setNewProperty(this, offset);
         if (attributes & ReadOnly)
             this->structure()->setContainsReadOnlyProperties();
         return true;
@@ -1378,7 +1258,7 @@ inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSVal
 
     PropertyOffset offset;
     size_t currentCapacity = this->structure()->outOfLineCapacity();
-    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
+    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, offset)) {
         DeferGC deferGC(vm.heap);
         Butterfly* newButterfly = butterfly();
         if (currentCapacity != structure->outOfLineCapacity()) {
@@ -1390,59 +1270,38 @@ inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSVal
         ASSERT(structure->isValidOffset(offset));
         setStructureAndButterfly(vm, structure, newButterfly);
         putDirect(vm, offset, value);
-        // This is a new property; transitions with specific values are not currently cachable,
-        // so leave the slot in an uncachable state.
-        if (!specificFunction)
-            slot.setNewProperty(this, offset);
+        slot.setNewProperty(this, offset);
         return true;
     }
 
     unsigned currentAttributes;
-    JSCell* currentSpecificFunction;
-    offset = structure->get(vm, propertyName, currentAttributes, currentSpecificFunction);
+    offset = structure->get(vm, propertyName, currentAttributes);
     if (offset != invalidOffset) {
         if ((mode == PutModePut) && currentAttributes & ReadOnly)
             return false;
 
-        // There are three possibilities here:
-        //  (1) There is an existing specific value set, and we're overwriting with *the same value*.
-        //       * Do nothing - no need to despecify, but that means we can't cache (a cached
-        //         put could write a different value). Leave the slot in an uncachable state.
-        //  (2) There is a specific value currently set, but we're writing a different value.
-        //       * First, we have to despecify.  Having done so, this is now a regular slot
-        //         with no specific value, so go ahead & cache like normal.
-        //  (3) Normal case, there is no specific value set.
-        //       * Go ahead & cache like normal.
-        if (currentSpecificFunction) {
-            // case (1) Do the put, then return leaving the slot uncachable.
-            if (specificFunction == currentSpecificFunction) {
-                putDirect(vm, offset, value);
-                return true;
-            }
-            // case (2) Despecify, fall through to (3).
-            setStructure(vm, Structure::despecifyFunctionTransition(vm, structure, propertyName));
-        }
-
-        // case (3) set the slot, do the put, return.
+        structure->didReplaceProperty(offset);
         slot.setExistingProperty(this, offset);
         putDirect(vm, offset, value);
+
+        if ((attributes & Accessor) != (currentAttributes & Accessor)) {
+            ASSERT(!(attributes & ReadOnly));
+            setStructure(vm, Structure::attributeChangeTransition(vm, structure, propertyName, attributes));
+        }
         return true;
     }
 
     if ((mode == PutModePut) && !isExtensible())
         return false;
 
-    structure = Structure::addPropertyTransition(vm, structure, propertyName, attributes, specificFunction, offset, slot.context());
+    structure = Structure::addPropertyTransition(vm, structure, propertyName, attributes, offset, slot.context());
     
     validateOffset(offset);
     ASSERT(structure->isValidOffset(offset));
     setStructureAndReallocateStorageIfNecessary(vm, structure);
 
     putDirect(vm, offset, value);
-    // This is a new property; transitions with specific values are not currently cachable,
-    // so leave the slot in an uncachable state.
-    if (!specificFunction)
-        slot.setNewProperty(this, offset);
+    slot.setNewProperty(this, offset);
     if (attributes & ReadOnly)
         structure->setContainsReadOnlyProperties();
     return true;
@@ -1476,7 +1335,7 @@ inline bool JSObject::putOwnDataProperty(VM& vm, PropertyName propertyName, JSVa
     ASSERT(!structure()->hasGetterSetterProperties());
     ASSERT(!structure()->hasCustomGetterSetterProperties());
 
-    return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value));
+    return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot);
 }
 
 inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
@@ -1484,14 +1343,14 @@ inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value
     ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
     ASSERT(!value.isCustomGetterSetter());
     PutPropertySlot slot(this);
-    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
+    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot);
 }
 
 inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
 {
     ASSERT(!value.isGetterSetter());
     ASSERT(!value.isCustomGetterSetter());
-    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, 0, slot, getCallableObject(value));
+    putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, 0, slot);
 }
 
 inline void JSObject::putDirectWithoutTransition(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
@@ -1502,7 +1361,7 @@ inline void JSObject::putDirectWithoutTransition(VM& vm, PropertyName propertyNa
     Butterfly* newButterfly = m_butterfly.get();
     if (structure()->putWillGrowOutOfLineStorage())
         newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
-    PropertyOffset offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes, getCallableObject(value));
+    PropertyOffset offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes);
     setStructureAndButterfly(vm, structure(), newButterfly);
     putDirect(vm, offset, value);
 }
@@ -1512,18 +1371,15 @@ inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType pre
     return methodTable()->defaultValue(this, exec, preferredType);
 }
 
-ALWAYS_INLINE JSObject* Register::function() const
+ALWAYS_INLINE JSObject* Register::object() const
 {
-    if (!jsValue())
-        return 0;
     return asObject(jsValue());
 }
 
-ALWAYS_INLINE Register Register::withCallee(JSObject* callee)
+ALWAYS_INLINE Register& Register::operator=(JSObject* object)
 {
-    Register r;
-    r = JSValue(callee);
-    return r;
+    u.value = JSValue::encode(JSValue(object));
+    return *this;
 }
 
 inline size_t offsetInButterfly(PropertyOffset offset)
@@ -1598,7 +1454,7 @@ COMPILE_ASSERT(!(sizeof(JSObject) % sizeof(WriteBarrierBase<Unknown>)), JSObject
 
 ALWAYS_INLINE Identifier makeIdentifier(VM& vm, const char* name)
 {
-    return Identifier(&vm, name);
+    return Identifier::fromString(&vm, name);
 }
 
 ALWAYS_INLINE Identifier makeIdentifier(VM&, const Identifier& name)
@@ -1620,23 +1476,11 @@ ALWAYS_INLINE Identifier makeIdentifier(VM&, const Identifier& name)
 #define JSC_NATIVE_FUNCTION(jsName, cppName, attributes, length) \
     JSC_NATIVE_INTRINSIC_FUNCTION(jsName, cppName, (attributes), (length), NoIntrinsic)
 
-ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, PropertyName propertyName) const
-{
-    if (m_propertyType == TypeValue)
-        return JSValue::decode(m_data.value);
-    if (m_propertyType == TypeGetter)
-        return functionGetter(exec);
-    return JSValue::decode(m_data.custom.getValue(exec, slotBase(), JSValue::encode(m_thisValue), propertyName));
-}
-
-ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, unsigned propertyName) const
-{
-    if (m_propertyType == TypeValue)
-        return JSValue::decode(m_data.value);
-    if (m_propertyType == TypeGetter)
-        return functionGetter(exec);
-    return JSValue::decode(m_data.custom.getValue(exec, slotBase(), JSValue::encode(m_thisValue), Identifier::from(exec, propertyName)));
-}
+// Identical helpers but for builtins. Note that currently, we don't support builtins that are
+// also intrinsics, but we probably will do that eventually.
+#define JSC_BUILTIN_FUNCTION(jsName, generatorName, attributes) \
+    putDirectBuiltinFunction(\
+        vm, globalObject, makeIdentifier(vm, (jsName)), (generatorName)(vm), (attributes))
 
 } // namespace JSC
 
index 9f182c954b331c48754aaa80d81b4a384561c3dc..b3fd4e72961712255681cafe10cac88a19a3b2e6 100644 (file)
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSPromiseConstructor.h"
-#include "JSPromiseReaction.h"
 #include "Microtask.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-static void triggerPromiseReactions(VM&, JSGlobalObject*, Vector<WriteBarrier<JSPromiseReaction>>&, JSValue);
+const ClassInfo JSPromise::s_info = { "Promise", &Base::s_info, 0, CREATE_METHOD_TABLE(JSPromise) };
 
-const ClassInfo JSPromise::s_info = { "Promise", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSPromise) };
-
-JSPromise* JSPromise::create(VM& vm, JSGlobalObject* globalObject, JSPromiseConstructor* constructor)
+JSPromise* JSPromise::create(VM& vm, JSGlobalObject* globalObject)
 {
     JSPromise* promise = new (NotNull, allocateCell<JSPromise>(vm.heap)) JSPromise(vm, globalObject->promiseStructure());
-    promise->finishCreation(vm, constructor);
+    promise->finishCreation(vm);
     return promise;
 }
 
@@ -56,114 +53,29 @@ Structure* JSPromise::createStructure(VM& vm, JSGlobalObject* globalObject, JSVa
 }
 
 JSPromise::JSPromise(VM& vm, Structure* structure)
-    : JSDestructibleObject(vm, structure)
-    , m_status(Status::Unresolved)
+    : JSNonFinalObject(vm, structure)
 {
 }
 
-void JSPromise::finishCreation(VM& vm, JSPromiseConstructor* constructor)
+void JSPromise::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    ASSERT(inherits(info()));
-    
-    m_constructor.set(vm, this, constructor);
-}
-
-void JSPromise::destroy(JSCell* cell)
-{
-    static_cast<JSPromise*>(cell)->JSPromise::~JSPromise();
-}
-
-void JSPromise::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSPromise* thisObject = jsCast<JSPromise*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.append(&thisObject->m_result);
-    visitor.append(&thisObject->m_constructor);
-    visitor.append(thisObject->m_resolveReactions.begin(), thisObject->m_resolveReactions.end());
-    visitor.append(thisObject->m_rejectReactions.begin(), thisObject->m_rejectReactions.end());
-}
-
-void JSPromise::reject(VM& vm, JSValue reason)
-{
-    // 1. If the value of promise's internal slot [[PromiseStatus]] is not "unresolved", return.
-    if (m_status != Status::Unresolved)
-        return;
-
-    DeferGC deferGC(vm.heap);
-
-    // 2. Let 'reactions' be the value of promise's [[RejectReactions]] internal slot.
-    Vector<WriteBarrier<JSPromiseReaction>> reactions;
-    reactions.swap(m_rejectReactions);
-
-    // 3. Set the value of promise's [[Result]] internal slot to reason.
-    m_result.set(vm, this, reason);
-
-    // 4. Set the value of promise's [[ResolveReactions]] internal slot to undefined.
-    m_resolveReactions.clear();
-
-    // 5. Set the value of promise's [[RejectReactions]] internal slot to undefined.
-    // NOTE: Handled by the swap above.
-
-    // 6. Set the value of promise's [[PromiseStatus]] internal slot to "has-rejection".
-    m_status = Status::HasRejection;
-
-    // 7. Return the result of calling TriggerPromiseReactions(reactions, reason).
-    triggerPromiseReactions(vm, globalObject(), reactions, reason);
-}
-
-void JSPromise::resolve(VM& vm, JSValue resolution)
-{
-    // 1. If the value of promise's internal slot [[PromiseStatus]] is not "unresolved", return.
-    if (m_status != Status::Unresolved)
-        return;
-
-    DeferGC deferGC(vm.heap);
-
-    // 2. Let 'reactions' be the value of promise's [[ResolveReactions]] internal slot.
-    Vector<WriteBarrier<JSPromiseReaction>> reactions;
-    reactions.swap(m_resolveReactions);
-    
-    // 3. Set the value of promise's [[Result]] internal slot to resolution.
-    m_result.set(vm, this, resolution);
-
-    // 4. Set the value of promise's [[ResolveReactions]] internal slot to undefined.
-    // NOTE: Handled by the swap above.
-
-    // 5. Set the value of promise's [[RejectReactions]] internal slot to undefined.
-    m_rejectReactions.clear();
-
-    // 6. Set the value of promise's [[PromiseStatus]] internal slot to "has-resolution".
-    m_status = Status::HasResolution;
-
-    // 7. Return the result of calling TriggerPromiseReactions(reactions, resolution).
-    triggerPromiseReactions(vm, globalObject(), reactions, resolution);
-}
-
-void JSPromise::appendResolveReaction(VM& vm, JSPromiseReaction* reaction)
-{
-    m_resolveReactions.append(WriteBarrier<JSPromiseReaction>(vm, this, reaction));
+    putDirect(vm, vm.propertyNames->promiseStatePrivateName, jsNumber(static_cast<unsigned>(Status::Pending)));
+    putDirect(vm, vm.propertyNames->promiseFulfillReactionsPrivateName, jsUndefined());
+    putDirect(vm, vm.propertyNames->promiseRejectReactionsPrivateName, jsUndefined());
+    putDirect(vm, vm.propertyNames->promiseResultPrivateName, jsUndefined());
 }
 
-void JSPromise::appendRejectReaction(VM& vm, JSPromiseReaction* reaction)
+auto JSPromise::status(VM& vm) const -> Status
 {
-    m_rejectReactions.append(WriteBarrier<JSPromiseReaction>(vm, this, reaction));
+    JSValue value = getDirect(vm, vm.propertyNames->promiseStatePrivateName);
+    ASSERT(value.isUInt32());
+    return static_cast<Status>(value.asUInt32());
 }
 
-void triggerPromiseReactions(VM& vm, JSGlobalObject* globalObject, Vector<WriteBarrier<JSPromiseReaction>>& reactions, JSValue argument)
+JSValue JSPromise::result(VM& vm) const
 {
-    // 1. Repeat for each reaction in reactions, in original insertion order
-    for (auto& reaction : reactions) {
-        // i. Call QueueMicrotask(ExecutePromiseReaction, (reaction, argument)).
-        globalObject->queueMicrotask(createExecutePromiseReactionMicrotask(vm, reaction.get(), argument));
-    }
-    
-    // 2. Return.
+    return getDirect(vm, vm.propertyNames->promiseResultPrivateName);
 }
 
 } // namespace JSC
index d1d1854d936c17c39944be92ee3f52455af57f81..89fd8a69ca51482ef9666088150d09031c535440 100644 (file)
 
 #if ENABLE(PROMISES)
 
-#include "JSDestructibleObject.h"
+#include "JSObject.h"
 
 namespace JSC {
 
-class JSPromiseReaction;
-class JSPromiseConstructor;
-
-class JSPromise : public JSDestructibleObject {
+class JSPromise : public JSNonFinalObject {
 public:
-    typedef JSDestructibleObject Base;
+    typedef JSNonFinalObject Base;
 
-    static JSPromise* create(VM&, JSGlobalObject*, JSPromiseConstructor*);
+    static JSPromise* create(VM&, JSGlobalObject*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
-    DECLARE_INFO;
+    DECLARE_EXPORT_INFO;
 
-    enum class Status {
-        Unresolved,
-        HasResolution,
-        HasRejection
+    enum class Status : unsigned {
+        Pending = 1,
+        Fulfilled,
+        Rejected
     };
 
-    Status status() const
-    {
-        return m_status;
-    }
-
-    JSValue result() const
-    {
-        ASSERT(m_status != Status::Unresolved);
-        return m_result.get();
-    }
-
-    JSPromiseConstructor* constructor() const
-    {
-        return m_constructor.get();
-    }
-
-    void reject(VM&, JSValue);
-    void resolve(VM&, JSValue);
-
-    void appendResolveReaction(VM&, JSPromiseReaction*);
-    void appendRejectReaction(VM&, JSPromiseReaction*);
+    Status status(VM&) const;
+    JSValue result(VM&) const;
 
 private:
     JSPromise(VM&, Structure*);
-    void finishCreation(VM&, JSPromiseConstructor*);
-    static const unsigned StructureFlags = OverridesVisitChildren | JSObject::StructureFlags;
-    static void destroy(JSCell*);
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    Status m_status;
-    WriteBarrier<Unknown> m_result;
-    WriteBarrier<JSPromiseConstructor> m_constructor;
-    Vector<WriteBarrier<JSPromiseReaction>> m_resolveReactions;
-    Vector<WriteBarrier<JSPromiseReaction>> m_rejectReactions;
+    void finishCreation(VM&);
 };
 
 } // namespace JSC
index 402619633fa06fd254b3f2a7a8cc71e807aaf911..6895ed82fad8077cd7cfc30441e469104cb2ef2c 100644 (file)
 #if ENABLE(PROMISES)
 
 #include "Error.h"
+#include "Exception.h"
+#include "IteratorOperations.h"
+#include "JSCBuiltins.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSPromise.h"
-#include "JSPromiseDeferred.h"
-#include "JSPromiseFunctions.h"
 #include "JSPromisePrototype.h"
 #include "Lookup.h"
 #include "NumberObject.h"
@@ -43,22 +44,16 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSPromiseConstructor);
 
-static EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncCast(ExecState*);
-static EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncResolve(ExecState*);
-static EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncReject(ExecState*);
-static EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncRace(ExecState*);
-static EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncAll(ExecState*);
 }
 
 #include "JSPromiseConstructor.lut.h"
 
 namespace JSC {
 
-const ClassInfo JSPromiseConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::promiseConstructorTable, CREATE_METHOD_TABLE(JSPromiseConstructor) };
+const ClassInfo JSPromiseConstructor::s_info = { "Function", &InternalFunction::s_info, &promiseConstructorTable, CREATE_METHOD_TABLE(JSPromiseConstructor) };
 
 /* Source for JSPromiseConstructor.lut.h
 @begin promiseConstructorTable
-  cast            JSPromiseConstructorFuncCast                DontEnum|Function 1
   resolve         JSPromiseConstructorFuncResolve             DontEnum|Function 1
   reject          JSPromiseConstructorFuncReject              DontEnum|Function 1
   race            JSPromiseConstructorFuncRace                DontEnum|Function 1
@@ -85,65 +80,27 @@ JSPromiseConstructor::JSPromiseConstructor(VM& vm, Structure* structure)
 
 void JSPromiseConstructor::finishCreation(VM& vm, JSPromisePrototype* promisePrototype)
 {
-    Base::finishCreation(vm, "Promise");
+    Base::finishCreation(vm, ASCIILiteral("Promise"));
     putDirectWithoutTransition(vm, vm.propertyNames->prototype, promisePrototype, DontEnum | DontDelete | ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
 }
 
 static EncodedJSValue JSC_HOST_CALL constructPromise(ExecState* exec)
 {
-    // NOTE: We ignore steps 1-4 as they only matter if you support subclassing, which we do not yet.
-    // 1. Let promise be the this value.
-    // 2. If Type(promise) is not Object, then throw a TypeError exception.
-    // 3. If promise does not have a [[PromiseStatus]] internal slot, then throw a TypeError exception.
-    // 4. If promise's [[PromiseStatus]] internal slot is not undefined, then throw a TypeError exception.
-
-    JSValue resolver = exec->argument(0);
-
-    // 5. IsCallable(resolver) is false, then throw a TypeError exception
-    CallData callData;
-    CallType callType = getCallData(resolver, callData);
-    if (callType == CallTypeNone)
-        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Promise constructor takes a function argument")));
-
     VM& vm = exec->vm();
     JSGlobalObject* globalObject = exec->callee()->globalObject();
 
-    JSPromise* promise = JSPromise::create(vm, globalObject, jsCast<JSPromiseConstructor*>(exec->callee()));
-
-    // NOTE: Steps 6-8 are handled by JSPromise::create().
-    // 6. Set promise's [[PromiseStatus]] internal slot to "unresolved".
-    // 7. Set promise's [[ResolveReactions]] internal slot to a new empty List.
-    // 8. Set promise's [[RejectReactions]] internal slot to a new empty List.
-    
-    // 9. Let 'resolve' be a new built-in function object as defined in Resolve Promise Functions.
-    JSFunction* resolve = createResolvePromiseFunction(vm, globalObject);
-
-    // 10. Set the [[Promise]] internal slot of 'resolve' to 'promise'.
-    resolve->putDirect(vm, vm.propertyNames->promisePrivateName, promise);
-    
-    // 11. Let 'reject' be a new built-in function object as defined in Reject Promise Functions
-    JSFunction* reject = createRejectPromiseFunction(vm, globalObject);
+    JSPromise* promise = JSPromise::create(vm, globalObject);
 
-    // 12. Set the [[Promise]] internal slot of 'reject' to 'promise'.
-    reject->putDirect(vm, vm.propertyNames->promisePrivateName, promise);
+    JSFunction* initializePromise = globalObject->initializePromiseFunction();
+    CallData callData;
+    CallType callType = getCallData(initializePromise, callData);
+    ASSERT(callType != CallTypeNone);
 
-    // 13. Let 'result' be the result of calling the [[Call]] internal method of resolver with
-    //     undefined as thisArgument and a List containing resolve and reject as argumentsList.
     MarkedArgumentBuffer arguments;
-    arguments.append(resolve);
-    arguments.append(reject);
-    call(exec, resolver, callType, callData, jsUndefined(), arguments);
-
-    // 14. If result is an abrupt completion, call PromiseReject(promise, result.[[value]]).
-    if (exec->hadException()) {
-        JSValue exception = exec->exception();
-        exec->clearException();
-
-        promise->reject(vm, exception);
-    }
+    arguments.append(exec->argument(0));
+    call(exec, initializePromise, callType, callData, promise, arguments);
 
-    // 15. Return promise.
     return JSValue::encode(promise);
 }
 
@@ -161,380 +118,7 @@ CallType JSPromiseConstructor::getCallData(JSCell*, CallData& callData)
 
 bool JSPromiseConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return getStaticFunctionSlot<InternalFunction>(exec, ExecState::promiseConstructorTable(exec->vm()), jsCast<JSPromiseConstructor*>(object), propertyName, slot);
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncCast(ExecState* exec)
-{
-    // -- Promise.cast(x) --
-    JSValue x = exec->argument(0);
-
-    // 1. Let 'C' be the this value.
-    JSValue C = exec->thisValue();
-
-    // 2. If IsPromise(x) is true,
-    JSPromise* promise = jsDynamicCast<JSPromise*>(x);
-    if (promise) {
-        // i. Let 'constructor' be the value of x's [[PromiseConstructor]] internal slot.
-        JSValue constructor = promise->constructor();
-        // ii. If SameValue(constructor, C) is true, return x.
-        if (sameValue(exec, constructor, C))
-            return JSValue::encode(x);
-    }
-
-    // 3. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-    
-    // 4. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 5. Let 'resolveResult' be the result of calling the [[Call]] internal method
-    //    of deferred.[[Resolve]] with undefined as thisArgument and a List containing x
-    //    as argumentsList.
-    performDeferredResolve(exec, deferred, x);
-
-    // 6. ReturnIfAbrupt(resolveResult).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // 7. Return deferred.[[Promise]].
-    return JSValue::encode(deferred->promise());
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncResolve(ExecState* exec)
-{
-    // -- Promise.resolve(x) --
-    JSValue x = exec->argument(0);
-
-    // 1. Let 'C' be the this value.
-    JSValue C = exec->thisValue();
-
-    // 2. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 3. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 4. Let 'resolveResult' be the result of calling the [[Call]] internal method
-    //    of deferred.[[Resolve]] with undefined as thisArgument and a List containing x
-    //    as argumentsList.
-    performDeferredResolve(exec, deferred, x);
-    
-    // 5. ReturnIfAbrupt(resolveResult).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // 6. Return deferred.[[Promise]].
-    return JSValue::encode(deferred->promise());
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncReject(ExecState* exec)
-{
-    // -- Promise.reject(x) --
-    JSValue r = exec->argument(0);
-
-    // 1. Let 'C' be the this value.
-    JSValue C = exec->thisValue();
-
-    // 2. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 3. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 4. Let 'rejectResult' be the result of calling the [[Call]] internal method
-    //    of deferred.[[Reject]] with undefined as thisArgument and a List containing r
-    //    as argumentsList.
-    performDeferredReject(exec, deferred, r);
-
-    // 5. ReturnIfAbrupt(resolveResult).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // 6. Return deferred.[[Promise]].
-    return JSValue::encode(deferred->promise());
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncRace(ExecState* exec)
-{
-    // -- Promise.race(iterable) --
-    JSValue iterable = exec->argument(0);
-    VM& vm = exec->vm();
-
-    // 1. Let 'C' be the this value.
-    JSValue C = exec->thisValue();
-
-    // 2. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 3. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 4. Let 'iterator' be the result of calling GetIterator(iterable).
-    JSValue iteratorFunction = iterable.get(exec, vm.propertyNames->iteratorPrivateName);
-    if (exec->hadException())
-        return JSValue::encode(abruptRejection(exec, deferred));
-
-    CallData iteratorFunctionCallData;
-    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone) {
-        throwTypeError(exec);
-        return JSValue::encode(abruptRejection(exec, deferred));
-    }
-
-    ArgList iteratorFunctionArguments;
-    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
-
-    // 5. RejectIfAbrupt(iterator, deferred).
-    if (exec->hadException())
-        return JSValue::encode(abruptRejection(exec, deferred));
-
-    // 6. Repeat
-    do {
-        // i. Let 'next' be the result of calling IteratorStep(iterator).
-        JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->iteratorNextPrivateName);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData nextFunctionCallData;
-        CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
-        if (nextFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer nextFunctionArguments;
-        nextFunctionArguments.append(jsUndefined());
-        JSValue next = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments);
-        
-        // ii. RejectIfAbrupt(next, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-    
-        // iii. If 'next' is false, return deferred.[[Promise]].
-        // Note: We implement this as an iterationTerminator
-        if (next == vm.iterationTerminator.get())
-            return JSValue::encode(deferred->promise());
-        
-        // iv. Let 'nextValue' be the result of calling IteratorValue(next).
-        // v. RejectIfAbrupt(nextValue, deferred).
-        // Note: 'next' is already the value, so there is nothing to do here.
-
-        // vi. Let 'nextPromise' be the result of calling Invoke(C, "cast", (nextValue)).
-        JSValue castFunction = C.get(exec, vm.propertyNames->cast);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData castFunctionCallData;
-        CallType castFunctionCallType = getCallData(castFunction, castFunctionCallData);
-        if (castFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer castFunctionArguments;
-        castFunctionArguments.append(next);
-        JSValue nextPromise = call(exec, castFunction, castFunctionCallType, castFunctionCallData, C, castFunctionArguments);
-
-        // vii. RejectIfAbrupt(nextPromise, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        // viii. Let 'result' be the result of calling Invoke(nextPromise, "then", (deferred.[[Resolve]], deferred.[[Reject]])).
-        JSValue thenFunction = nextPromise.get(exec, vm.propertyNames->then);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData thenFunctionCallData;
-        CallType thenFunctionCallType = getCallData(thenFunction, thenFunctionCallData);
-        if (thenFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer thenFunctionArguments;
-        thenFunctionArguments.append(deferred->resolve());
-        thenFunctionArguments.append(deferred->reject());
-
-        call(exec, thenFunction, thenFunctionCallType, thenFunctionCallData, nextPromise, thenFunctionArguments);
-
-        // ix. RejectIfAbrupt(result, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-    } while (true);
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncAll(ExecState* exec)
-{
-    // -- Promise.all(iterable) --
-
-    JSValue iterable = exec->argument(0);
-    VM& vm = exec->vm();
-
-    // 1. Let 'C' be the this value.
-    JSValue C = exec->thisValue();
-
-    // 2. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 3. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // NOTE: A non-abrupt completion of createJSPromiseDeferredFromConstructor implies that
-    // C and deferredValue are objects.
-    JSObject* thisObject = asObject(C);
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 4. Let 'iterator' be the result of calling GetIterator(iterable).
-    JSValue iteratorFunction = iterable.get(exec, vm.propertyNames->iteratorPrivateName);
-    if (exec->hadException())
-        return JSValue::encode(abruptRejection(exec, deferred));
-
-    CallData iteratorFunctionCallData;
-    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone) {
-        throwTypeError(exec);
-        return JSValue::encode(abruptRejection(exec, deferred));
-    }
-
-    ArgList iteratorFunctionArguments;
-    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
-
-    // 5. RejectIfAbrupt(iterator, deferred).
-    if (exec->hadException())
-        return JSValue::encode(abruptRejection(exec, deferred));
-
-    // 6. Let 'values' be the result of calling ArrayCreate(0).
-    JSArray* values = constructEmptyArray(exec, nullptr, thisObject->globalObject());
-    
-    // 7. Let 'countdownHolder' be Record { [[Countdown]]: 0 }.
-    NumberObject* countdownHolder = constructNumber(exec, thisObject->globalObject(), JSValue(0));
-    
-    // 8. Let 'index' be 0.
-    unsigned index = 0;
-    
-    // 9. Repeat.
-    do {
-        // i. Let 'next' be the result of calling IteratorStep(iterator).
-        JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->iteratorNextPrivateName);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData nextFunctionCallData;
-        CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
-        if (nextFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer nextFunctionArguments;
-        nextFunctionArguments.append(jsUndefined());
-        JSValue next = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments);
-        
-        // ii. RejectIfAbrupt(next, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        // iii. If 'next' is false,
-        // Note: We implement this as an iterationTerminator
-        if (next == vm.iterationTerminator.get()) {
-            // a. If 'index' is 0,
-            if (!index) {
-                // a. Let 'resolveResult' be the result of calling the [[Call]] internal method
-                //    of deferred.[[Resolve]] with undefined as thisArgument and a List containing
-                //    values as argumentsList.
-                performDeferredResolve(exec, deferred, values);
-
-                // b. ReturnIfAbrupt(resolveResult).
-                if (exec->hadException())
-                    return JSValue::encode(jsUndefined());
-            }
-            
-            // b. Return deferred.[[Promise]].
-            return JSValue::encode(deferred->promise());
-        }
-        
-        // iv. Let 'nextValue' be the result of calling IteratorValue(next).
-        // v. RejectIfAbrupt(nextValue, deferred).
-        // Note: 'next' is already the value, so there is nothing to do here.
-
-        // vi. Let 'nextPromise' be the result of calling Invoke(C, "cast", (nextValue)).
-        JSValue castFunction = C.get(exec, vm.propertyNames->cast);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData castFunctionCallData;
-        CallType castFunctionCallType = getCallData(castFunction, castFunctionCallData);
-        if (castFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer castFunctionArguments;
-        castFunctionArguments.append(next);
-        JSValue nextPromise = call(exec, castFunction, castFunctionCallType, castFunctionCallData, C, castFunctionArguments);
-
-        // vii. RejectIfAbrupt(nextPromise, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        // viii. Let 'countdownFunction' be a new built-in function object as defined in Promise.all Countdown Functions.
-        JSFunction* countdownFunction = createPromiseAllCountdownFunction(vm, thisObject->globalObject());
-        
-        // ix. Set the [[Index]] internal slot of 'countdownFunction' to 'index'.
-        countdownFunction->putDirect(vm, vm.propertyNames->indexPrivateName, JSValue(index));
-
-        // x. Set the [[Values]] internal slot of 'countdownFunction' to 'values'.
-        countdownFunction->putDirect(vm, vm.propertyNames->valuesPrivateName, values);
-
-        // xi. Set the [[Deferred]] internal slot of 'countdownFunction' to 'deferred'.
-        countdownFunction->putDirect(vm, vm.propertyNames->deferredPrivateName, deferred);
-
-        // xii. Set the [[CountdownHolder]] internal slot of 'countdownFunction' to 'countdownHolder'.
-        countdownFunction->putDirect(vm, vm.propertyNames->countdownHolderPrivateName, countdownHolder);
-
-        // xiii. Let 'result' be the result of calling Invoke(nextPromise, "then", (countdownFunction, deferred.[[Reject]])).
-        JSValue thenFunction = nextPromise.get(exec, vm.propertyNames->then);
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        CallData thenFunctionCallData;
-        CallType thenFunctionCallType = getCallData(thenFunction, thenFunctionCallData);
-        if (thenFunctionCallType == CallTypeNone) {
-            throwTypeError(exec);
-            return JSValue::encode(abruptRejection(exec, deferred));
-        }
-
-        MarkedArgumentBuffer thenFunctionArguments;
-        thenFunctionArguments.append(countdownFunction);
-        thenFunctionArguments.append(deferred->reject());
-
-        call(exec, thenFunction, thenFunctionCallType, thenFunctionCallData, nextPromise, thenFunctionArguments);
-
-        // xiv. RejectIfAbrupt(result, deferred).
-        if (exec->hadException())
-            return JSValue::encode(abruptRejection(exec, deferred));
-
-        // xv. Set index to index + 1.
-        index++;
-
-        // xvi. Set countdownHolder.[[Countdown]] to countdownHolder.[[Countdown]] + 1.
-        uint32_t newCountdownValue = countdownHolder->internalValue().asUInt32() + 1;
-        countdownHolder->setInternalValue(vm, JSValue(newCountdownValue));
-    } while (true);
+    return getStaticFunctionSlot<InternalFunction>(exec, promiseConstructorTable, jsCast<JSPromiseConstructor*>(object), propertyName, slot);
 }
 
 JSPromise* constructPromise(ExecState* exec, JSGlobalObject* globalObject, JSFunction* resolver)
index 498bb8b56d019e5b4cebd0160c259b0233ffc18c..fc0f04d2b2b43698a904c51e2fddba7a381266f2 100644 (file)
@@ -38,6 +38,7 @@ class JSPromisePrototype;
 class JSPromiseConstructor : public InternalFunction {
 public:
     typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static JSPromiseConstructor* create(VM&, Structure*, JSPromisePrototype*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
@@ -46,7 +47,6 @@ public:
 
 protected:
     void finishCreation(VM&, JSPromisePrototype*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
 
 private:
     JSPromiseConstructor(VM&, Structure*);
index 67fd550a90a9498795ff0a150431a5e2b3eccf22..1add652ea23bf4edeee8cc3cde240cc93fa6abdd 100644 (file)
 
 #if ENABLE(PROMISES)
 
+#include "BuiltinNames.h"
 #include "Error.h"
+#include "Exception.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSPromise.h"
 #include "JSPromiseConstructor.h"
-#include "JSPromiseFunctions.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo JSPromiseDeferred::s_info = { "JSPromiseDeferred", 0, 0, 0, CREATE_METHOD_TABLE(JSPromiseDeferred) };
+const ClassInfo JSPromiseDeferred::s_info = { "JSPromiseDeferred", 0, 0, CREATE_METHOD_TABLE(JSPromiseDeferred) };
 
 JSPromiseDeferred* JSPromiseDeferred::create(ExecState* exec, JSGlobalObject* globalObject)
 {
     VM& vm = exec->vm();
-    
-    JSFunction* resolver = createDeferredConstructionFunction(vm, globalObject);
 
-    JSPromise* promise = constructPromise(exec, globalObject, resolver);
-    JSValue resolve = resolver->get(exec, vm.propertyNames->resolvePrivateName);
-    JSValue reject = resolver->get(exec, vm.propertyNames->rejectPrivateName);
+    JSFunction* newPromiseDeferredFunction = globalObject->newPromiseDeferredFunction();
+    CallData callData;
+    CallType callType = JSC::getCallData(newPromiseDeferredFunction, callData);
+    ASSERT(callType != CallTypeNone);
 
-    return JSPromiseDeferred::create(vm, promise, resolve, reject);
+    MarkedArgumentBuffer arguments;
+    JSValue deferred = call(exec, newPromiseDeferredFunction, callType, callData, jsUndefined(), arguments);
+
+    JSValue promise = deferred.get(exec, vm.propertyNames->promisePrivateName);
+    ASSERT(promise.inherits(JSPromise::info()));
+    JSValue resolve = deferred.get(exec, vm.propertyNames->builtinNames().resolvePrivateName());
+    JSValue reject = deferred.get(exec, vm.propertyNames->builtinNames().rejectPrivateName());
+
+    return JSPromiseDeferred::create(vm, jsCast<JSPromise*>(promise), resolve, reject);
 }
 
 JSPromiseDeferred* JSPromiseDeferred::create(VM& vm, JSObject* promise, JSValue resolve, JSValue reject)
@@ -78,8 +86,6 @@ void JSPromiseDeferred::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSPromiseDeferred* thisObject = jsCast<JSPromiseDeferred*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
 
     Base::visitChildren(thisObject, visitor);
 
@@ -88,164 +94,6 @@ void JSPromiseDeferred::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_reject);
 }
 
-JSValue createJSPromiseDeferredFromConstructor(ExecState* exec, JSValue C)
-{
-    // -- This implements the GetDeferred(C) abstract operation --
-
-    // 1. If IsConstructor(C) is false, throw a TypeError.
-    if (!C.isObject())
-        return throwTypeError(exec);
-
-    ConstructData constructData;
-    ConstructType constructType = getConstructData(C, constructData);
-    if (constructType == ConstructTypeNone)
-        return throwTypeError(exec);
-
-    VM& vm = exec->vm();
-
-    // 2. Let 'resolver' be a new built-in function object as defined in Deferred Construction Functions.
-    JSFunction* resolver = createDeferredConstructionFunction(vm, asObject(C)->globalObject());
-
-    // 3. Let 'promise' be the result of calling the [[Construct]] internal method of 'C' with
-    //    an argument list containing the single item resolver.
-    MarkedArgumentBuffer constructArguments;
-    constructArguments.append(resolver);
-    JSObject* promise = construct(exec, C, constructType, constructData, constructArguments);
-
-    // 4. ReturnIfAbrupt(promise).
-    if (exec->hadException())
-        return jsUndefined();
-
-    // 5. Let 'resolve' be the value of resolver's [[Resolve]] internal slot.
-    JSValue resolve = resolver->get(exec, vm.propertyNames->resolvePrivateName);
-
-    // 6. If IsCallable(resolve) is false, throw a TypeError.
-    CallData resolveCallData;
-    CallType resolveCallType = getCallData(resolve, resolveCallData);
-    if (resolveCallType == CallTypeNone)
-        return throwTypeError(exec);
-
-    // 7. Let 'reject' be the value of resolver's [[Reject]] internal slot.
-    JSValue reject = resolver->get(exec, vm.propertyNames->rejectPrivateName);
-
-    // 8. If IsCallable(reject) is false, throw a TypeError.
-    CallData rejectCallData;
-    CallType rejectCallType = getCallData(reject, rejectCallData);
-    if (rejectCallType == CallTypeNone)
-        return throwTypeError(exec);
-
-    // 9. Return the Deferred { [[Promise]]: promise, [[Resolve]]: resolve, [[Reject]]: reject }.
-    return JSPromiseDeferred::create(exec->vm(), promise, resolve, reject);
-}
-
-ThenableStatus updateDeferredFromPotentialThenable(ExecState* exec, JSValue x, JSPromiseDeferred* deferred)
-{
-    // 1. If Type(x) is not Object, return "not a thenable".
-    if (!x.isObject())
-        return NotAThenable;
-    
-    // 2. Let 'then' be the result of calling Get(x, "then").
-    JSValue thenValue = x.get(exec, exec->vm().propertyNames->then);
-    
-    // 3. If then is an abrupt completion,
-    if (exec->hadException()) {
-        // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of
-        //    deferred.[[Reject]] with undefined as thisArgument and a List containing
-        //    then.[[value]] as argumentsList.
-        JSValue exception = exec->exception();
-        exec->clearException();
-
-        performDeferredReject(exec, deferred, exception);
-
-        // ii. ReturnIfAbrupt(rejectResult).
-        // NOTE: Nothing to do.
-
-        // iii. Return.
-        return WasAThenable;
-    }
-
-    // 4. Let 'then' be then.[[value]].
-    // Note: Nothing to do.
-
-    // 5. If IsCallable(then) is false, return "not a thenable".
-    CallData thenCallData;
-    CallType thenCallType = getCallData(thenValue, thenCallData);
-    if (thenCallType == CallTypeNone)
-        return NotAThenable;
-
-    // 6. Let 'thenCallResult' be the result of calling the [[Call]] internal method of
-    //    'then' passing x as thisArgument and a List containing deferred.[[Resolve]] and
-    //    deferred.[[Reject]] as argumentsList.
-    MarkedArgumentBuffer thenArguments;
-    thenArguments.append(deferred->resolve());
-    thenArguments.append(deferred->reject());
-    
-    call(exec, thenValue, thenCallType, thenCallData, x, thenArguments);
-
-    // 7. If 'thenCallResult' is an abrupt completion,
-    if (exec->hadException()) {
-        // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of
-        //    deferred.[[Reject]] with undefined as thisArgument and a List containing
-        //    thenCallResult.[[value]] as argumentsList.
-        JSValue exception = exec->exception();
-        exec->clearException();
-
-        performDeferredReject(exec, deferred, exception);
-
-        // ii. ReturnIfAbrupt(rejectResult).
-        // NOTE: Nothing to do.
-    }
-
-    return WasAThenable;
-}
-
-void performDeferredResolve(ExecState* exec, JSPromiseDeferred* deferred, JSValue argument)
-{
-    JSValue deferredResolve = deferred->resolve();
-
-    CallData resolveCallData;
-    CallType resolveCallType = getCallData(deferredResolve, resolveCallData);
-    ASSERT(resolveCallType != CallTypeNone);
-
-    MarkedArgumentBuffer arguments;
-    arguments.append(argument);
-
-    call(exec, deferredResolve, resolveCallType, resolveCallData, jsUndefined(), arguments);
-}
-
-void performDeferredReject(ExecState* exec, JSPromiseDeferred* deferred, JSValue argument)
-{
-    JSValue deferredReject = deferred->reject();
-
-    CallData rejectCallData;
-    CallType rejectCallType = getCallData(deferredReject, rejectCallData);
-    ASSERT(rejectCallType != CallTypeNone);
-
-    MarkedArgumentBuffer arguments;
-    arguments.append(argument);
-
-    call(exec, deferredReject, rejectCallType, rejectCallData, jsUndefined(), arguments);
-}
-
-JSValue abruptRejection(ExecState* exec, JSPromiseDeferred* deferred)
-{
-    ASSERT(exec->hadException());
-    JSValue argument = exec->exception();
-    exec->clearException();
-
-    // i. Let 'rejectResult' be the result of calling the [[Call]] internal method
-    // of deferred.[[Reject]] with undefined as thisArgument and a List containing
-    // argument.[[value]] as argumentsList.
-    performDeferredReject(exec, deferred, argument);
-
-    // ii. ReturnIfAbrupt(rejectResult).
-    if (exec->hadException())
-        return jsUndefined();
-
-    // iii. Return deferred.[[Promise]].
-    return deferred->promise();
-}
-
 } // namespace JSC
 
 #endif // ENABLE(PROMISES)
index d1c9761c2dcc55b3d66ca50d26da33819d3de975..c655eeb0abfde6b819389268b1c783e53a3d32fc 100644 (file)
 
 namespace JSC {
 
-class JSPromiseDeferred : public JSCell {
+class JSPromiseDeferred final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     JS_EXPORT_PRIVATE static JSPromiseDeferred* create(ExecState*, JSGlobalObject*);
     JS_EXPORT_PRIVATE static JSPromiseDeferred* create(VM&, JSObject* promise, JSValue resolve, JSValue reject);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
-    static const bool hasImmortalStructure = true;
-
     DECLARE_EXPORT_INFO;
 
     JSObject* promise() const { return m_promise.get(); }
@@ -56,7 +55,6 @@ public:
 private:
     JSPromiseDeferred(VM&);
     void finishCreation(VM&, JSObject*, JSValue, JSValue);
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
     static void visitChildren(JSCell*, SlotVisitor&);
 
     WriteBarrier<JSObject> m_promise;
@@ -64,19 +62,6 @@ private:
     WriteBarrier<Unknown> m_reject;
 };
 
-enum ThenableStatus {
-    WasAThenable,
-    NotAThenable
-};
-
-JSValue createJSPromiseDeferredFromConstructor(ExecState*, JSValue constructor);
-ThenableStatus updateDeferredFromPotentialThenable(ExecState*, JSValue, JSPromiseDeferred*);
-
-void performDeferredResolve(ExecState*, JSPromiseDeferred*, JSValue argument);
-void performDeferredReject(ExecState*, JSPromiseDeferred*, JSValue argument);
-
-JSValue abruptRejection(ExecState*, JSPromiseDeferred*);
-
 } // namespace JSC
 
 #endif // ENABLE(PROMISES)
diff --git a/runtime/JSPromiseFunctions.cpp b/runtime/JSPromiseFunctions.cpp
deleted file mode 100644 (file)
index b8d82f2..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSPromiseFunctions.h"
-
-#if ENABLE(PROMISES)
-
-#include "Error.h"
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSPromise.h"
-#include "JSPromiseConstructor.h"
-#include "JSPromiseDeferred.h"
-#include "NumberObject.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-// Deferred Construction Functions
-static EncodedJSValue JSC_HOST_CALL deferredConstructionFunction(ExecState* exec)
-{
-    JSObject* F = exec->callee();
-
-    VM& vm = exec->vm();
-
-    // 1. Set F's [[Resolve]] internal slot to resolve.
-    F->putDirect(vm, vm.propertyNames->resolvePrivateName, exec->argument(0));
-
-    // 2. Set F's [[Reject]] internal slot to reject.
-    F->putDirect(vm, vm.propertyNames->rejectPrivateName, exec->argument(1));
-
-    // 3. Return.
-    return JSValue::encode(jsUndefined());
-}
-
-JSFunction* createDeferredConstructionFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 2, ASCIILiteral("DeferredConstructionFunction"), deferredConstructionFunction);
-}
-
-// Identity Functions
-
-static EncodedJSValue JSC_HOST_CALL identifyFunction(ExecState* exec)
-{
-    return JSValue::encode(exec->argument(0));
-}
-
-JSFunction* createIdentifyFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("IdentityFunction"), identifyFunction);
-}
-
-// Promise.All Countdown Functions
-
-static EncodedJSValue JSC_HOST_CALL promiseAllCountdownFunction(ExecState* exec)
-{
-    JSValue x = exec->argument(0);
-    VM& vm = exec->vm();
-    JSObject* F = exec->callee();
-
-    // 1. Let 'index' be the value of F's [[Index]] internal slot.
-    uint32_t index = F->get(exec, vm.propertyNames->indexPrivateName).asUInt32();
-
-    // 2. Let 'values' be the value of F's [[Values]] internal slot..
-    JSArray* values = jsCast<JSArray*>(F->get(exec, vm.propertyNames->valuesPrivateName));
-
-    // 3. Let 'deferred' be the value of F's [[Deferred]] internal slot.
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(F->get(exec, vm.propertyNames->deferredPrivateName));
-
-    // 4. Let 'countdownHolder' be the value of F's [[CountdownHolder]] internal slot.
-    NumberObject* countdownHolder = jsCast<NumberObject*>(F->get(exec, vm.propertyNames->countdownHolderPrivateName));
-
-    // 5. Let 'result' be the result of calling the [[DefineOwnProperty]] internal method
-    //    of 'values' with arguments 'index' and Property Descriptor { [[Value]]: x,
-    //    [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
-    values->putDirectIndex(exec, index, x);
-
-    // 6. RejectIfAbrupt(result, deferred).
-    if (exec->hadException())
-        abruptRejection(exec, deferred);
-
-    // 7. Set countdownHolder.[[Countdown]] to countdownHolder.[[Countdown]] - 1.
-    uint32_t newCountdownValue = countdownHolder->internalValue().asUInt32() - 1;
-    countdownHolder->setInternalValue(vm, JSValue(newCountdownValue));
-
-    // 8. If countdownHolder.[[Countdown]] is 0,
-    if (!newCountdownValue) {
-        // i. Return the result of calling the [[Call]] internal method of deferred.[[Resolve]]
-        //    with undefined as thisArgument and a List containing 'values' as argumentsList.
-        performDeferredResolve(exec, deferred, values);
-    }
-
-    // 9. Return.
-    return JSValue::encode(jsUndefined());
-}
-
-JSFunction* createPromiseAllCountdownFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("PromiseAllCountdownFunction"), promiseAllCountdownFunction);
-}
-
-// Promise Resolution Handler Functions
-
-static EncodedJSValue JSC_HOST_CALL promiseResolutionHandlerFunction(ExecState* exec)
-{
-    JSValue x = exec->argument(0);
-    VM& vm = exec->vm();
-    JSObject* F = exec->callee();
-
-    // 1. Let 'promise' be the value of F's [[Promise]] internal slot
-    JSPromise* promise = jsCast<JSPromise*>(F->get(exec, vm.propertyNames->promisePrivateName));
-
-    // 2. Let 'fulfillmentHandler' be the value of F's [[FulfillmentHandler]] internal slot.
-    JSValue fulfillmentHandler = F->get(exec, vm.propertyNames->fulfillmentHandlerPrivateName);
-    
-    // 3. Let 'rejectionHandler' be the value of F's [[RejectionHandler]] internal slot.
-    JSValue rejectionHandler = F->get(exec, vm.propertyNames->rejectionHandlerPrivateName);
-    
-    // 4. If SameValue(x, promise) is true,
-    if (sameValue(exec, x, promise)) {
-        // i. Let 'selfResolutionError' be a newly-created TypeError object.
-        JSObject* selfResolutionError = createTypeError(exec, ASCIILiteral("Resolve a promise with itself"));
-        // ii. Return the result of calling the [[Call]] internal method of rejectionHandler with
-        //     undefined as thisArgument and a List containing selfResolutionError as argumentsList.
-        CallData rejectCallData;
-        CallType rejectCallType = getCallData(rejectionHandler, rejectCallData);
-        ASSERT(rejectCallType != CallTypeNone);
-
-        MarkedArgumentBuffer rejectArguments;
-        rejectArguments.append(selfResolutionError);
-
-        return JSValue::encode(call(exec, rejectionHandler, rejectCallType, rejectCallData, jsUndefined(), rejectArguments));
-    }
-
-    // 5. Let 'C' be the value of promise's [[PromiseConstructor]] internal slot.
-    JSValue C = promise->constructor();
-
-    // 6. Let 'deferred' be the result of calling GetDeferred(C)
-    JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 7. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);
-
-    // 8. Let 'updateResult' be the result of calling UpdateDeferredFromPotentialThenable(x, deferred).
-    ThenableStatus updateResult = updateDeferredFromPotentialThenable(exec, x, deferred);
-
-    // 9. ReturnIfAbrupt(updateResult).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // 10. If 'updateResult' is not "not a thenable", return the result of calling
-    //     Invoke(deferred.[[Promise]], "then", (fulfillmentHandler, rejectionHandler)).
-    // NOTE: Invoke does not seem to be defined anywhere, so I am guessing here.
-    if (updateResult != NotAThenable) {
-        JSObject* deferredPromise = deferred->promise();
-    
-        JSValue thenValue = deferredPromise->get(exec, exec->vm().propertyNames->then);
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-
-        CallData thenCallData;
-        CallType thenCallType = getCallData(thenValue, thenCallData);
-        if (thenCallType == CallTypeNone)
-            return JSValue::encode(throwTypeError(exec));
-
-        MarkedArgumentBuffer arguments;
-        arguments.append(fulfillmentHandler);
-        arguments.append(rejectionHandler);
-
-        return JSValue::encode(call(exec, thenValue, thenCallType, thenCallData, deferredPromise, arguments));
-    }
-    
-    // 11. Return the result of calling the [[Call]] internal method of fulfillmentHandler
-    //     with undefined as thisArgument and a List containing x as argumentsList.
-    CallData fulfillmentHandlerCallData;
-    CallType fulfillmentHandlerCallType = getCallData(fulfillmentHandler, fulfillmentHandlerCallData);
-    ASSERT(fulfillmentHandlerCallType != CallTypeNone);
-    
-    MarkedArgumentBuffer fulfillmentHandlerArguments;
-    fulfillmentHandlerArguments.append(x);
-
-    return JSValue::encode(call(exec, fulfillmentHandler, fulfillmentHandlerCallType, fulfillmentHandlerCallData, jsUndefined(), fulfillmentHandlerArguments));
-}
-
-JSFunction* createPromiseResolutionHandlerFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("PromiseResolutionHandlerFunction"), promiseResolutionHandlerFunction);
-}
-
-// Reject Promise Functions
-
-static EncodedJSValue JSC_HOST_CALL rejectPromiseFunction(ExecState* exec)
-{
-    JSValue reason = exec->argument(0);
-    JSObject* F = exec->callee();
-    VM& vm = exec->vm();
-
-    // 1. Let 'promise' be the value of F's [[Promise]] internal slot.
-    JSPromise* promise = jsCast<JSPromise*>(F->get(exec, exec->vm().propertyNames->promisePrivateName));
-
-    // 2. Return the result of calling PromiseReject(promise, reason);
-    promise->reject(vm, reason);
-
-    return JSValue::encode(jsUndefined());
-}
-
-JSFunction* createRejectPromiseFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("RejectPromiseFunction"), rejectPromiseFunction);
-}
-
-// Resolve Promise Functions
-
-static EncodedJSValue JSC_HOST_CALL resolvePromiseFunction(ExecState* exec)
-{
-    JSValue resolution = exec->argument(0);
-    JSObject* F = exec->callee();
-    VM& vm = exec->vm();
-
-    // 1. Let 'promise' be the value of F's [[Promise]] internal slot.
-    JSPromise* promise = jsCast<JSPromise*>(F->get(exec, vm.propertyNames->promisePrivateName));
-
-    // 2. Return the result of calling PromiseResolve(promise, resolution);
-    promise->resolve(vm, resolution);
-
-    return JSValue::encode(jsUndefined());
-}
-
-JSFunction* createResolvePromiseFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("ResolvePromiseFunction"), resolvePromiseFunction);
-}
-
-// Thrower Functions
-
-static EncodedJSValue JSC_HOST_CALL throwerFunction(ExecState* exec)
-{
-    return JSValue::encode(exec->vm().throwException(exec, exec->argument(0)));
-}
-
-JSFunction* createThrowerFunction(VM& vm, JSGlobalObject* globalObject)
-{
-    return JSFunction::create(vm, globalObject, 1, ASCIILiteral("ThrowerFunction"), throwerFunction);
-}
-
-
-} // namespace JSC
-
-#endif // ENABLE(PROMISES)
diff --git a/runtime/JSPromiseFunctions.h b/runtime/JSPromiseFunctions.h
deleted file mode 100644 (file)
index 8021219..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSPromiseFunctions_h
-#define JSPromiseFunctions_h
-
-#if ENABLE(PROMISES)
-
-#include "JSFunction.h"
-
-namespace JSC {
-
-JSFunction* createDeferredConstructionFunction(VM&, JSGlobalObject*);
-JSFunction* createIdentifyFunction(VM&, JSGlobalObject*);
-JSFunction* createPromiseAllCountdownFunction(VM&, JSGlobalObject*);
-JSFunction* createPromiseResolutionHandlerFunction(VM&, JSGlobalObject*);
-JSFunction* createRejectPromiseFunction(VM&, JSGlobalObject*);
-JSFunction* createResolvePromiseFunction(VM&, JSGlobalObject*);
-JSFunction* createThrowerFunction(VM&, JSGlobalObject*);
-
-} // namespace JSC
-
-#endif // ENABLE(PROMISES)
-
-#endif // JSPromiseFunctions_h
index 0ded57fa962c09d0e77218ea74ee552f950e5be1..e5c24be2aefb211c27125ac798d2cf0d124ce427 100644 (file)
 #if ENABLE(PROMISES)
 
 #include "Error.h"
+#include "JSCBuiltins.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
 #include "JSPromise.h"
-#include "JSPromiseDeferred.h"
-#include "JSPromiseFunctions.h"
-#include "JSPromiseReaction.h"
 #include "Microtask.h"
 #include "StructureInlines.h"
 
@@ -43,15 +41,13 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSPromisePrototype);
 
-static EncodedJSValue JSC_HOST_CALL JSPromisePrototypeFuncThen(ExecState*);
-
 }
 
 #include "JSPromisePrototype.lut.h"
 
 namespace JSC {
 
-const ClassInfo JSPromisePrototype::s_info = { "PromisePrototype", &JSNonFinalObject::s_info, 0, ExecState::promisePrototypeTable, CREATE_METHOD_TABLE(JSPromisePrototype) };
+const ClassInfo JSPromisePrototype::s_info = { "PromisePrototype", &JSNonFinalObject::s_info, &promisePrototypeTable, CREATE_METHOD_TABLE(JSPromisePrototype) };
 
 /* Source for JSPromisePrototype.lut.h
 @begin promisePrototypeTable
@@ -85,105 +81,7 @@ void JSPromisePrototype::finishCreation(VM& vm, Structure*)
 
 bool JSPromisePrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return getStaticFunctionSlot<JSObject>(exec, ExecState::promisePrototypeTable(exec->vm()), jsCast<JSPromisePrototype*>(object), propertyName, slot);
-}
-
-EncodedJSValue JSC_HOST_CALL JSPromisePrototypeFuncThen(ExecState* exec)
-{
-    // -- Promise.prototype.then(onFulfilled, onRejected) --
-
-    // 1. Let promise be the this value.
-    // 2. If IsPromise(promise) is false, throw a TypeError exception.
-    JSPromise* promise = jsDynamicCast<JSPromise*>(exec->thisValue());
-    if (!promise)
-        return JSValue::encode(throwTypeError(exec));
-
-    // 3. Let 'C' be the result of calling Get(promise, "constructor").
-    JSValue C = promise->get(exec, exec->propertyNames().constructor);
-    
-    // 4. ReturnIfAbrupt(C).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-    
-    // 5. Let 'deferred' be the result of calling GetDeferred(C).
-    JSValue deferred = createJSPromiseDeferredFromConstructor(exec, C);
-
-    // 6. ReturnIfAbrupt(deferred).
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    VM& vm = exec->vm();
-    JSGlobalObject* globalObject = promise->globalObject();
-
-    // 7. Let 'rejectionHandler' be a new built-in function object as defined in Thrower Functions
-    // 8. If IsCallable(onRejected), set rejectionHandler to onRejected.
-    JSValue onRejected = exec->argument(1);
-    CallData onRejectedCallData;
-    CallType onRejectedCallType = getCallData(onRejected, onRejectedCallData);
-    JSObject* rejectionHandler = (onRejectedCallType == CallTypeNone) ? createThrowerFunction(vm, globalObject) : asObject(onRejected);
-    
-    // 9. Let 'fulfillmentHandler' be a new built-in function object as defined in Identity Functions
-    // 10. If IsCallable(onFulfilled), set fulfillmentHandler to onFulfilled
-    JSValue onFulfilled = exec->argument(0);
-    CallData onFulfilledCallData;
-    CallType onFulfilledCallType = getCallData(onFulfilled, onFulfilledCallData);
-    JSObject* fulfillmentHandler = (onFulfilledCallType == CallTypeNone) ? createIdentifyFunction(vm, globalObject) : asObject(onFulfilled);
-
-    // 11. Let 'resolutionHandler' be a new built-in function object as defined in Promise Resolution Handler Functions
-    JSObject* resolutionHandler = createPromiseResolutionHandlerFunction(vm, globalObject);
-
-    // 12. Set the [[Promise]] internal slot of resolutionHandler to promise.
-    resolutionHandler->putDirect(vm, vm.propertyNames->promisePrivateName, promise);
-
-    // 13. Set the [[FulfillmentHandler]] internal slot of resolutionHandler to fulfillmentHandler.
-    resolutionHandler->putDirect(vm, vm.propertyNames->fulfillmentHandlerPrivateName, fulfillmentHandler);
-
-    // 14. Set the [[RejectionHandler]] internal slot of resolutionHandler to rejectionHandler.
-    resolutionHandler->putDirect(vm, vm.propertyNames->rejectionHandlerPrivateName, rejectionHandler);
-
-    // 15. Let 'resolveReaction' be the PromiseReaction { [[Deferred]]: deferred, [[Handler]]: resolutionHandler }.
-    JSPromiseReaction* resolveReaction = JSPromiseReaction::create(vm, jsCast<JSPromiseDeferred*>(deferred), resolutionHandler);
-
-    // 16. Let 'rejectReaction' be the PromiseReaction { [[Deferred]]: deferred, [[Handler]]: rejectionHandler }.
-    JSPromiseReaction* rejectReaction = JSPromiseReaction::create(vm, jsCast<JSPromiseDeferred*>(deferred), rejectionHandler);
-
-    switch (promise->status()) {
-    case JSPromise::Status::Unresolved: {
-        // 17. If the value of promise's [[PromiseStatus]] internal slot is "unresolved",
-
-        // i. Append resolveReaction as the last element of promise's [[ResolveReactions]] internal slot.
-        promise->appendResolveReaction(vm, resolveReaction);
-
-        // ii. Append rejectReaction as the last element of promise's [[RejectReactions]] internal slot.
-        promise->appendRejectReaction(vm, rejectReaction);
-        break;
-    }
-
-    case JSPromise::Status::HasResolution: {
-        // 18. If the value of promise's [[PromiseStatus]] internal slot is "has-resolution",
-
-        // i. Let 'resolution' be the value of promise's [[Result]] internal slot.
-        JSValue resolution = promise->result();
-
-        // ii. Call QueueMicrotask(ExecutePromiseReaction, (resolveReaction, resolution)).
-        globalObject->queueMicrotask(createExecutePromiseReactionMicrotask(vm, resolveReaction, resolution));
-        break;
-    }
-
-    case JSPromise::Status::HasRejection: {
-        // 19. If the value of promise's [[PromiseStatus]] internal slot is "has-rejection",
-
-        // i. Let reason be the value of promise's [[Result]] internal slot.
-        JSValue reason = promise->result();
-
-        // ii. Call QueueMicrotask(ExecutePromiseReaction, (rejectReaction, reason)).
-        globalObject->queueMicrotask(createExecutePromiseReactionMicrotask(vm, rejectReaction, reason));
-        break;
-    }
-    }
-
-    // 20. Return deferred.[[Promise]].
-    return JSValue::encode(jsCast<JSPromiseDeferred*>(deferred)->promise());
+    return getStaticFunctionSlot<JSObject>(exec, promisePrototypeTable, jsCast<JSPromisePrototype*>(object), propertyName, slot);
 }
 
 } // namespace JSC
index 893fc4afc8de080eea77ae2a5b3e8e233e8c8316..cd7cef45c5e5f10b45b9066d1d274927550fdf29 100644 (file)
@@ -35,6 +35,7 @@ namespace JSC {
 class JSPromisePrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
     static JSPromisePrototype* create(ExecState*, JSGlobalObject*, Structure*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
@@ -43,7 +44,6 @@ public:
 
 protected:
     void finishCreation(VM&, Structure*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
 
 private:
     JSPromisePrototype(ExecState*, Structure*);
diff --git a/runtime/JSPromiseReaction.cpp b/runtime/JSPromiseReaction.cpp
deleted file mode 100644 (file)
index 1d3ab6f..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSPromiseReaction.h"
-
-#if ENABLE(PROMISES)
-
-#include "Error.h"
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSGlobalObject.h"
-#include "JSPromiseDeferred.h"
-#include "Microtask.h"
-#include "SlotVisitorInlines.h"
-#include "StrongInlines.h"
-
-namespace JSC {
-
-class ExecutePromiseReactionMicrotask final : public Microtask {
-public:
-    ExecutePromiseReactionMicrotask(VM& vm, JSPromiseReaction* reaction, JSValue argument)
-    {
-        m_reaction.set(vm, reaction);
-        m_argument.set(vm, argument);
-    }
-
-    virtual ~ExecutePromiseReactionMicrotask()
-    {
-    }
-
-private:
-    virtual void run(ExecState*) override;
-
-    Strong<JSPromiseReaction> m_reaction;
-    Strong<Unknown> m_argument;
-};
-
-PassRefPtr<Microtask> createExecutePromiseReactionMicrotask(VM& vm, JSPromiseReaction* reaction, JSValue argument)
-{
-    return adoptRef(new ExecutePromiseReactionMicrotask(vm, reaction, argument));
-}
-
-void ExecutePromiseReactionMicrotask::run(ExecState* exec)
-{
-    // 1. Let 'deferred' be reaction.[[Deferred]].
-    JSPromiseDeferred* deferred = m_reaction->deferred();
-    
-    // 2. Let 'handler' be reaction.[[Handler]].
-    JSValue handler = m_reaction->handler();
-
-    // 3. Let 'handlerResult' be the result of calling the [[Call]] internal method of
-    //    handler passing undefined as thisArgument and a List containing argument as
-    //    argumentsList.
-
-    CallData handlerCallData;
-    CallType handlerCallType = getCallData(handler, handlerCallData);
-    ASSERT(handlerCallType != CallTypeNone);
-
-    MarkedArgumentBuffer handlerArguments;
-    handlerArguments.append(m_argument.get());
-
-    JSValue handlerResult = call(exec, handler, handlerCallType, handlerCallData, jsUndefined(), handlerArguments);
-
-    // 4. If handlerResult is an abrupt completion, return the result of calling the
-    //    [[Call]] internal method of deferred.[[Reject]] passing undefined as thisArgument
-    //    and a List containing handlerResult.[[value]] as argumentsList.
-    if (exec->hadException()) {
-        JSValue exception = exec->exception();
-        exec->clearException();
-
-        performDeferredReject(exec, deferred, exception);
-    }
-    
-    // 5. Let 'handlerResult' be handlerResult.[[value]].
-    // Note: Nothing to do.
-
-    // 6. If SameValue(handlerResult, deferred.[[Promise]]) is true,
-    if (sameValue(exec, handlerResult, deferred->promise())) {
-        // i. Let 'selfResolutionError' be a newly-created TypeError object.
-        JSObject* selfResolutionError = createTypeError(exec, ASCIILiteral("Resolve a promise with itself"));
-
-        // ii. Return the result of calling the [[Call]] internal method of deferred.[[Reject]] passing
-        //     undefined as thisArgument and a List containing selfResolutionError as argumentsList.
-        performDeferredReject(exec, deferred, selfResolutionError);
-    }
-
-    // 7. Let 'updateResult' be the result of calling UpdateDeferredFromPotentialThenable(handlerResult, deferred).
-    ThenableStatus updateResult = updateDeferredFromPotentialThenable(exec, handlerResult, deferred);
-    
-    // 8. ReturnIfAbrupt(updateResult).
-    if (exec->hadException())
-        return;
-
-    // 9. If 'updateResult' is "not a thenable",
-    if (updateResult == NotAThenable) {
-        // i. Return the result of calling the [[Call]] internal method of deferred.[[Resolve]]
-        //    passing undefined as thisArgument and a List containing handlerResult as argumentsList.
-        performDeferredResolve(exec, deferred, handlerResult);
-    }
-}
-
-
-const ClassInfo JSPromiseReaction::s_info = { "JSPromiseReaction", 0, 0, 0, CREATE_METHOD_TABLE(JSPromiseReaction) };
-
-JSPromiseReaction* JSPromiseReaction::create(VM& vm, JSPromiseDeferred* deferred, JSValue handler)
-{
-    JSPromiseReaction* promiseReaction = new (NotNull, allocateCell<JSPromiseReaction>(vm.heap)) JSPromiseReaction(vm);
-    promiseReaction->finishCreation(vm, deferred, handler);
-    return promiseReaction;
-}
-
-JSPromiseReaction::JSPromiseReaction(VM& vm)
-    : Base(vm, vm.promiseReactionStructure.get())
-{
-}
-
-void JSPromiseReaction::finishCreation(VM& vm, JSPromiseDeferred* deferred, JSValue handler)
-{
-    Base::finishCreation(vm);
-    m_deferred.set(vm, this, deferred);
-    m_handler.set(vm, this, handler);
-}
-
-void JSPromiseReaction::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSPromiseReaction* thisObject = jsCast<JSPromiseReaction*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.append(&thisObject->m_deferred);
-    visitor.append(&thisObject->m_handler);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(PROMISES)
diff --git a/runtime/JSPromiseReaction.h b/runtime/JSPromiseReaction.h
deleted file mode 100644 (file)
index 1235427..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSPromiseReaction_h
-#define JSPromiseReaction_h
-
-#if ENABLE(PROMISES)
-
-#include "JSCell.h"
-#include "Structure.h"
-
-namespace JSC {
-
-class JSPromiseDeferred;
-class Microtask;
-
-class JSPromiseReaction : public JSCell {
-public:
-    typedef JSCell Base;
-
-    static JSPromiseReaction* create(VM&, JSPromiseDeferred*, JSValue);
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
-    }
-
-    static const bool hasImmortalStructure = true;
-
-    DECLARE_INFO;
-
-    JSPromiseDeferred* deferred() const { return m_deferred.get(); }
-    JSValue handler() const { return m_handler.get(); }
-
-private:
-    JSPromiseReaction(VM&);
-    void finishCreation(VM&, JSPromiseDeferred*, JSValue);
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    WriteBarrier<JSPromiseDeferred> m_deferred;
-    WriteBarrier<Unknown> m_handler;
-};
-
-PassRefPtr<Microtask> createExecutePromiseReactionMicrotask(VM&, JSPromiseReaction*, JSValue);
-
-} // namespace JSC
-
-#endif // ENABLE(PROMISES)
-
-#endif // JSPromiseReaction_h
diff --git a/runtime/JSPropertyNameEnumerator.cpp b/runtime/JSPropertyNameEnumerator.cpp
new file mode 100644 (file)
index 0000000..7e7d1ac
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSPropertyNameEnumerator.h"
+
+#include "JSCInlines.h"
+#include "StrongInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSPropertyNameEnumerator::s_info = { "JSPropertyNameEnumerator", 0, 0, CREATE_METHOD_TABLE(JSPropertyNameEnumerator) };
+
+JSPropertyNameEnumerator* JSPropertyNameEnumerator::create(VM& vm)
+{
+    if (!vm.emptyPropertyNameEnumerator.get()) {
+        PropertyNameArray propertyNames(&vm);
+        vm.emptyPropertyNameEnumerator = Strong<JSCell>(vm, create(vm, 0, 0, 0, propertyNames));
+    }
+    return jsCast<JSPropertyNameEnumerator*>(vm.emptyPropertyNameEnumerator.get());
+}
+
+JSPropertyNameEnumerator* JSPropertyNameEnumerator::create(VM& vm, Structure* structure, uint32_t indexedLength, uint32_t numberStructureProperties, PropertyNameArray& propertyNames)
+{
+    StructureID structureID = structure ? structure->id() : 0;
+    uint32_t inlineCapacity = structure ? structure->inlineCapacity() : 0;
+    JSPropertyNameEnumerator* enumerator = new (NotNull, 
+        allocateCell<JSPropertyNameEnumerator>(vm.heap)) JSPropertyNameEnumerator(vm, structureID, inlineCapacity);
+    enumerator->finishCreation(vm, indexedLength, numberStructureProperties, propertyNames.data());
+    return enumerator;
+}
+
+JSPropertyNameEnumerator::JSPropertyNameEnumerator(VM& vm, StructureID structureID, uint32_t inlineCapacity)
+    : JSCell(vm, vm.propertyNameEnumeratorStructure.get())
+    , m_cachedStructureID(structureID)
+    , m_cachedInlineCapacity(inlineCapacity)
+{
+}
+
+void JSPropertyNameEnumerator::finishCreation(VM& vm, uint32_t indexedLength, uint32_t endStructurePropertyIndex, PassRefPtr<PropertyNameArrayData> idents)
+{
+    Base::finishCreation(vm);
+
+    RefPtr<PropertyNameArrayData> identifiers = idents;
+    PropertyNameArrayData::PropertyNameVector& vector = identifiers->propertyNameVector();
+
+    m_indexedLength = indexedLength;
+    m_endStructurePropertyIndex = endStructurePropertyIndex;
+    m_endGenericPropertyIndex = vector.size();
+
+    m_propertyNames.resizeToFit(vector.size());
+    for (unsigned i = 0; i < vector.size(); ++i) {
+        const Identifier& identifier = vector[i];
+        m_propertyNames[i].set(vm, this, jsString(&vm, identifier.string()));
+    }
+}
+
+void JSPropertyNameEnumerator::destroy(JSCell* cell)
+{
+    jsCast<JSPropertyNameEnumerator*>(cell)->JSPropertyNameEnumerator::~JSPropertyNameEnumerator();
+}
+
+void JSPropertyNameEnumerator::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    Base::visitChildren(cell, visitor);
+    JSPropertyNameEnumerator* thisObject = jsCast<JSPropertyNameEnumerator*>(cell);
+    for (unsigned i = 0; i < thisObject->m_propertyNames.size(); ++i)
+        visitor.append(&thisObject->m_propertyNames[i]);
+    visitor.append(&thisObject->m_prototypeChain);
+}
+
+} // namespace JSC
diff --git a/runtime/JSPropertyNameEnumerator.h b/runtime/JSPropertyNameEnumerator.h
new file mode 100644 (file)
index 0000000..94b0343
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSPropertyNameEnumerator_h
+#define JSPropertyNameEnumerator_h
+
+#include "JSCell.h"
+#include "Operations.h"
+#include "PropertyNameArray.h"
+#include "Structure.h"
+
+namespace JSC {
+
+class Identifier;
+
+class JSPropertyNameEnumerator final : public JSCell {
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static JSPropertyNameEnumerator* create(VM&);
+    static JSPropertyNameEnumerator* create(VM&, Structure*, uint32_t, uint32_t, PropertyNameArray&);
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    JSString* propertyNameAtIndex(uint32_t index) const
+    {
+        if (index >= m_propertyNames.size())
+            return nullptr;
+        return m_propertyNames[index].get();
+    }
+
+    StructureChain* cachedPrototypeChain() const { return m_prototypeChain.get(); }
+    void setCachedPrototypeChain(VM& vm, StructureChain* prototypeChain) { return m_prototypeChain.set(vm, this, prototypeChain); }
+
+    Structure* cachedStructure(VM& vm) const
+    {
+        if (!m_cachedStructureID)
+            return nullptr;
+        return vm.heap.structureIDTable().get(m_cachedStructureID);
+    }
+    StructureID cachedStructureID() const { return m_cachedStructureID; }
+    uint32_t indexedLength() const { return m_indexedLength; }
+    uint32_t endStructurePropertyIndex() const { return m_endStructurePropertyIndex; }
+    uint32_t endGenericPropertyIndex() const { return m_endGenericPropertyIndex; }
+    uint32_t cachedInlineCapacity() const { return m_cachedInlineCapacity; }
+    static ptrdiff_t cachedStructureIDOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_cachedStructureID); }
+    static ptrdiff_t indexedLengthOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_indexedLength); }
+    static ptrdiff_t endStructurePropertyIndexOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_endStructurePropertyIndex); }
+    static ptrdiff_t endGenericPropertyIndexOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_endGenericPropertyIndex); }
+    static ptrdiff_t cachedInlineCapacityOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_cachedInlineCapacity); }
+    static ptrdiff_t cachedPropertyNamesVectorOffset()
+    {
+        return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_propertyNames) + Vector<WriteBarrier<JSString>>::dataMemoryOffset();
+    }
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+    JSPropertyNameEnumerator(VM&, StructureID, uint32_t);
+    void finishCreation(VM&, uint32_t, uint32_t, PassRefPtr<PropertyNameArrayData>);
+
+    Vector<WriteBarrier<JSString>> m_propertyNames;
+    StructureID m_cachedStructureID;
+    WriteBarrier<StructureChain> m_prototypeChain;
+    uint32_t m_indexedLength;
+    uint32_t m_endStructurePropertyIndex;
+    uint32_t m_endGenericPropertyIndex;
+    uint32_t m_cachedInlineCapacity;
+};
+
+inline JSPropertyNameEnumerator* propertyNameEnumerator(ExecState* exec, JSObject* base)
+{
+    VM& vm = exec->vm();
+
+    uint32_t indexedLength = base->methodTable(vm)->getEnumerableLength(exec, base);
+
+    JSPropertyNameEnumerator* enumerator = nullptr;
+
+    Structure* structure = base->structure(vm);
+    if (!indexedLength
+        && (enumerator = structure->cachedPropertyNameEnumerator())
+        && enumerator->cachedPrototypeChain() == structure->prototypeChain(exec))
+        return enumerator;
+
+    uint32_t numberStructureProperties = 0;
+
+    PropertyNameArray propertyNames(exec);
+
+    if (structure->canAccessPropertiesQuickly() && indexedLength == base->getArrayLength()) {
+        base->methodTable(vm)->getStructurePropertyNames(base, exec, propertyNames, EnumerationMode());
+
+        numberStructureProperties = propertyNames.size();
+
+        base->methodTable(vm)->getGenericPropertyNames(base, exec, propertyNames, EnumerationMode());
+    } else
+        base->methodTable(vm)->getPropertyNames(base, exec, propertyNames, EnumerationMode());
+
+    ASSERT(propertyNames.size() < UINT32_MAX);
+
+    normalizePrototypeChain(exec, structure);
+
+    enumerator = JSPropertyNameEnumerator::create(vm, structure, indexedLength, numberStructureProperties, propertyNames);
+    enumerator->setCachedPrototypeChain(vm, structure->prototypeChain(exec));
+    if (!indexedLength && structure->canCachePropertyNameEnumerator())
+        structure->setCachedPropertyNameEnumerator(vm, enumerator);
+    return enumerator;
+}
+
+} // namespace JSC
+
+#endif // JSPropertyNameEnumerator_h
diff --git a/runtime/JSPropertyNameIterator.cpp b/runtime/JSPropertyNameIterator.cpp
deleted file mode 100644 (file)
index b595980..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSPropertyNameIterator.h"
-
-#include "JSCInlines.h"
-#include "JSGlobalObject.h"
-#include <wtf/StdLibExtras.h>
-
-namespace JSC {
-
-const ClassInfo JSPropertyNameIterator::s_info = { "JSPropertyNameIterator", 0, 0, 0, CREATE_METHOD_TABLE(JSPropertyNameIterator) };
-
-inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
-    : JSCell(exec->vm(), exec->vm().propertyNameIteratorStructure.get())
-    , m_numCacheableSlots(numCacheableSlots)
-    , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
-    , m_jsStrings(m_jsStringsSize ? std::make_unique<WriteBarrier<Unknown>[]>(m_jsStringsSize) : nullptr)
-{
-}
-
-JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
-{
-    ASSERT(!o->structure()->enumerationCache() ||
-            o->structure()->enumerationCache()->cachedStructure() != o->structure() ||
-            o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec));
-
-    VM& vm = exec->vm();
-
-    PropertyNameArray propertyNames(exec);
-    o->methodTable()->getPropertyNames(o, exec, propertyNames, ExcludeDontEnumProperties);
-    size_t numCacheableSlots = 0;
-    if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasGetterSetterProperties()
-        && !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames())
-        numCacheableSlots = propertyNames.numCacheableSlots();
-    
-    JSPropertyNameIterator* jsPropertyNameIterator = new (NotNull, allocateCell<JSPropertyNameIterator>(vm.heap)) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots);
-    jsPropertyNameIterator->finishCreation(vm, propertyNames.data(), o);
-
-    if (o->structure()->isDictionary())
-        return jsPropertyNameIterator;
-
-    if (o->structure()->typeInfo().overridesGetPropertyNames())
-        return jsPropertyNameIterator;
-    
-    if (hasIndexedProperties(o->indexingType()))
-        return jsPropertyNameIterator;
-    
-    size_t count = normalizePrototypeChain(exec, o);
-    StructureChain* structureChain = o->structure()->prototypeChain(exec);
-    WriteBarrier<Structure>* structure = structureChain->head();
-    for (size_t i = 0; i < count; ++i) {
-        if (structure[i]->typeInfo().overridesGetPropertyNames())
-            return jsPropertyNameIterator;
-    }
-
-    jsPropertyNameIterator->setCachedPrototypeChain(vm, structureChain);
-    jsPropertyNameIterator->setCachedStructure(vm, o->structure());
-    o->structure()->setEnumerationCache(vm, jsPropertyNameIterator);
-    return jsPropertyNameIterator;
-}
-
-void JSPropertyNameIterator::destroy(JSCell* cell)
-{
-    static_cast<JSPropertyNameIterator*>(cell)->JSPropertyNameIterator::~JSPropertyNameIterator();
-}
-
-JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
-{
-    JSValue identifier = m_jsStrings[i].get();
-    if (m_cachedStructure.get() == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
-        return identifier;
-
-    if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
-        return JSValue();
-    return identifier;
-}
-
-void JSPropertyNameIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSPropertyNameIterator* thisObject = jsCast<JSPropertyNameIterator*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    visitor.appendValues(thisObject->m_jsStrings.get(), thisObject->m_jsStringsSize);
-    visitor.append(&thisObject->m_cachedPrototypeChain);
-}
-
-} // namespace JSC
diff --git a/runtime/JSPropertyNameIterator.h b/runtime/JSPropertyNameIterator.h
deleted file mode 100644 (file)
index d48185e..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSPropertyNameIterator_h
-#define JSPropertyNameIterator_h
-
-#include "JSObject.h"
-#include "JSString.h"
-#include "PropertyNameArray.h"
-#include <memory>
-
-namespace JSC {
-
-    class Identifier;
-    class JSObject;
-    class LLIntOffsetsExtractor;
-
-    class JSPropertyNameIterator : public JSCell {
-        friend class JIT;
-
-    public:
-        typedef JSCell Base;
-
-        static JSPropertyNameIterator* create(ExecState*, JSObject*);
-
-        static const bool needsDestruction = true;
-        static const bool hasImmortalStructure = true;
-        static void destroy(JSCell*);
-       
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
-        }
-
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-        JSValue get(ExecState*, JSObject*, size_t i);
-        size_t size() { return m_jsStringsSize; }
-
-        void setCachedStructure(VM& vm, Structure* structure)
-        {
-            ASSERT(!m_cachedStructure);
-            ASSERT(structure);
-            m_cachedStructure.set(vm, this, structure);
-        }
-        Structure* cachedStructure() { return m_cachedStructure.get(); }
-
-        void setCachedPrototypeChain(VM& vm, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(vm, this, cachedPrototypeChain); }
-        StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
-        
-        DECLARE_EXPORT_INFO;
-
-    protected:
-        static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal;
-
-        void finishCreation(VM& vm, PropertyNameArrayData* propertyNameArrayData, JSObject* object)
-        {
-            Base::finishCreation(vm);
-            PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
-            for (size_t i = 0; i < m_jsStringsSize; ++i)
-                m_jsStrings[i].set(vm, this, jsOwnedString(&vm, propertyNameVector[i].string()));
-            m_cachedStructureInlineCapacity = object->structure()->inlineCapacity();
-        }
-
-    private:
-        friend class LLIntOffsetsExtractor;
-        
-        JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
-
-        WriteBarrier<Structure> m_cachedStructure;
-        WriteBarrier<StructureChain> m_cachedPrototypeChain;
-        uint32_t m_numCacheableSlots;
-        uint32_t m_jsStringsSize;
-        unsigned m_cachedStructureInlineCapacity;
-        std::unique_ptr<WriteBarrier<Unknown>[]> m_jsStrings;
-    };
-
-    ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
-    {
-        return jsCast<JSPropertyNameIterator*>(jsValue().asCell());
-    }
-
-    inline JSPropertyNameIterator* StructureRareData::enumerationCache()
-    {
-        return m_enumerationCache.get();
-    }
-    
-    inline void StructureRareData::setEnumerationCache(VM& vm, JSPropertyNameIterator* value)
-    {
-        m_enumerationCache.set(vm, this, value);
-    }
-
-} // namespace JSC
-
-#endif // JSPropertyNameIterator_h
index 494a79e324a0c0a8d3c66d36ccb21388bd396350..f4c6829e04bc21a1de39f7e4f903a9bf454b8371 100644 (file)
@@ -33,16 +33,12 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSProxy);
 
-const ClassInfo JSProxy::s_info = { "JSProxy", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSProxy) };
+const ClassInfo JSProxy::s_info = { "JSProxy", &Base::s_info, 0, CREATE_METHOD_TABLE(JSProxy) };
 
 void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSProxy* thisObject = jsCast<JSProxy*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_target);
 }
@@ -118,6 +114,25 @@ void JSProxy::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameAr
     thisObject->target()->methodTable(exec->vm())->getPropertyNames(thisObject->target(), exec, propertyNames, mode);
 }
 
+uint32_t JSProxy::getEnumerableLength(ExecState* exec, JSObject* object)
+{
+    JSProxy* thisObject = jsCast<JSProxy*>(object);
+    return thisObject->target()->methodTable(exec->vm())->getEnumerableLength(exec, thisObject->target());
+}
+
+void JSProxy::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
+{
+    // Skip the structure loop, since it is invalid for proxies.
+}
+
+void JSProxy::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    JSProxy* thisObject = jsCast<JSProxy*>(object);
+    // Get *all* of the property names, not just the generic ones, since we skipped the structure
+    // ones above.
+    thisObject->target()->methodTable(exec->vm())->getPropertyNames(thisObject->target(), exec, propertyNames, mode);
+}
+
 void JSProxy::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     JSProxy* thisObject = jsCast<JSProxy*>(object);
index 100998a4937e2a8f4d5608189f561e51677388f2..2bdcd1b72abceba87ffb06e74fe16b63273d8124 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
 class JSProxy : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero;
 
     static JSProxy* create(VM& vm, Structure* structure, JSObject* target)
     {
@@ -68,8 +69,6 @@ protected:
         m_target.set(vm, this, target);
     }
 
-    static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
-
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
     JS_EXPORT_PRIVATE void setTarget(VM&, JSGlobalObject*);
@@ -83,6 +82,9 @@ protected:
     JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
     JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(ExecState*, JSObject*);
+    JS_EXPORT_PRIVATE static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
 
 private:
index 57c81c633f8d7042ba974a839c1db3d710aa9c52..32ced617f18570403561beff88a751f90c4183f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "JSScope.h"
 
-#include "JSActivation.h"
 #include "JSGlobalObject.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "JSWithScope.h"
 #include "JSCInlines.h"
@@ -40,9 +40,6 @@ void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSScope* thisObject = jsCast<JSScope*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_next);
 }
@@ -50,26 +47,26 @@ void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
 // Returns true if we found enough information to terminate optimization.
 static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, size_t depth, bool& needsVarInjectionChecks, ResolveOp& op)
 {
-    if (JSActivation* activation = jsDynamicCast<JSActivation*>(scope)) {
+    if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(scope)) {
         if (ident == exec->propertyNames().arguments) {
-            // We know the property will be at this activation scope, but we don't know how to cache it.
+            // We know the property will be at this lexical environment scope, but we don't know how to cache it.
             op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
             return true;
         }
 
-        SymbolTableEntry entry = activation->symbolTable()->get(ident.impl());
+        SymbolTableEntry entry = lexicalEnvironment->symbolTable()->get(ident.impl());
         if (entry.isReadOnly() && getOrPut == Put) {
-            // We know the property will be at this activation scope, but we don't know how to cache it.
+            // We know the property will be at this lexical environment scope, but we don't know how to cache it.
             op = ResolveOp(Dynamic, 0, 0, 0, 0, 0);
             return true;
         }
 
         if (!entry.isNull()) {
-            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, activation, entry.watchpointSet(), entry.getIndex());
+            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, lexicalEnvironment, entry.watchpointSet(), entry.scopeOffset().offset());
             return true;
         }
 
-        if (activation->symbolTable()->usesNonStrictEval())
+        if (lexicalEnvironment->symbolTable()->usesNonStrictEval())
             needsVarInjectionChecks = true;
         return false;
     }
@@ -85,7 +82,7 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
 
             op = ResolveOp(
                 makeType(GlobalVar, needsVarInjectionChecks), depth, 0, 0, entry.watchpointSet(),
-                reinterpret_cast<uintptr_t>(globalObject->registerAt(entry.getIndex()).slot()));
+                reinterpret_cast<uintptr_t>(globalObject->variableAt(entry.scopeOffset()).slot()));
             return true;
         }
 
@@ -99,8 +96,19 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif
             op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
             return true;
         }
-
-        op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), 0, 0, slot.cachedOffset());
+        
+        WatchpointState state = globalObject->structure()->ensurePropertyReplacementWatchpointSet(exec->vm(), slot.cachedOffset())->state();
+        if (state == IsWatched && getOrPut == Put) {
+            // The field exists, but because the replacement watchpoint is still intact. This is
+            // kind of dangerous. We have two options:
+            // 1) Invalidate the watchpoint set. That would work, but it's possible that this code
+            //    path never executes - in which case this would be unwise.
+            // 2) Have the invalidation happen at run-time. All we have to do is leave the code
+            //    uncached. The only downside is slightly more work when this does execute.
+            // We go with option (2) here because it seems less evil.
+            op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, 0, 0, 0, 0);
+        } else
+            op = ResolveOp(makeType(GlobalProperty, needsVarInjectionChecks), depth, globalObject->structure(), 0, 0, slot.cachedOffset());
         return true;
     }
 
@@ -125,28 +133,50 @@ int JSScope::depth()
     return depth;
 }
 
+// When an exception occurs, the result of isUnscopable becomes false.
+static inline bool isUnscopable(ExecState* exec, JSScope* scope, JSObject* object, const Identifier& ident)
+{
+    if (scope->type() != WithScopeType)
+        return false;
+
+    JSValue unscopables = object->get(exec, exec->propertyNames().unscopablesSymbol);
+    if (exec->hadException())
+        return false;
+    if (!unscopables.isObject())
+        return false;
+    JSValue blocked = jsCast<JSObject*>(unscopables)->get(exec, ident);
+    if (exec->hadException())
+        return false;
+
+    return blocked.toBoolean(exec);
+}
+
 JSValue JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
 {
     ScopeChainIterator end = scope->end();
     ScopeChainIterator it = scope->begin();
     while (1) {
+        JSScope* scope = it.scope();
         JSObject* object = it.get();
 
         if (++it == end) // Global scope.
             return object;
 
-        if (object->hasProperty(exec, ident))
-            return object;
+        if (object->hasProperty(exec, ident)) {
+            if (!isUnscopable(exec, scope, object, ident))
+                return object;
+            ASSERT_WITH_MESSAGE(!exec->hadException(), "When an exception occurs, the result of isUnscopable becomes false");
+        }
     }
 }
 
-ResolveOp JSScope::abstractResolve(ExecState* exec, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
+ResolveOp JSScope::abstractResolve(ExecState* exec, bool hasTopActivation, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType)
 {
     ResolveOp op(Dynamic, 0, 0, 0, 0, 0);
     if (unlinkedType == Dynamic)
         return op;
 
-    size_t depth = 0;
+    size_t depth = hasTopActivation ? 1 : 0;
     bool needsVarInjectionChecks = JSC::needsVarInjectionChecks(unlinkedType);
     for (; scope; scope = scope->next()) {
         if (abstractAccess(exec, scope, ident, getOrPut, depth, needsVarInjectionChecks, op))
@@ -172,12 +202,12 @@ const char* resolveTypeName(ResolveType type)
         "GlobalProperty",
         "GlobalVar",
         "ClosureVar",
+        "LocalClosureVar",
         "GlobalPropertyWithVarInjectionChecks",
         "GlobalVarWithVarInjectionChecks",
         "ClosureVarWithVarInjectionChecks",
         "Dynamic"
     };
-    ASSERT(type < sizeof(names) / sizeof(names[0]));
     return names[type];
 }
 
index 6e6d85eefeef78ef10aa21c07e19b871f76ec08a..5d0eb4bc72eef83106578e3f7cbebb48eb6c8766 100644 (file)
@@ -31,7 +31,7 @@
 namespace JSC {
 
 class ScopeChainIterator;
-class VariableWatchpointSet;
+class WatchpointSet;
 
 enum ResolveMode {
     ThrowIfNotFound,
@@ -43,6 +43,7 @@ enum ResolveType {
     GlobalProperty,
     GlobalVar,
     ClosureVar,
+    LocalClosureVar,
 
     // Ditto, but at least one intervening scope used non-strict eval, which
     // can inject an intercepting var delcaration at runtime.
@@ -68,6 +69,7 @@ inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks)
     case GlobalVar:
         return GlobalVarWithVarInjectionChecks;
     case ClosureVar:
+    case LocalClosureVar:
         return ClosureVarWithVarInjectionChecks;
     case GlobalPropertyWithVarInjectionChecks:
     case GlobalVarWithVarInjectionChecks:
@@ -86,6 +88,7 @@ inline bool needsVarInjectionChecks(ResolveType type)
     case GlobalProperty:
     case GlobalVar:
     case ClosureVar:
+    case LocalClosureVar:
         return false;
     case GlobalPropertyWithVarInjectionChecks:
     case GlobalVarWithVarInjectionChecks:
@@ -99,11 +102,11 @@ inline bool needsVarInjectionChecks(ResolveType type)
 }
 
 struct ResolveOp {
-    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSActivation* activation, VariableWatchpointSet* watchpointSet, uintptr_t operand)
+    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand)
         : type(type)
         , depth(depth)
         , structure(structure)
-        , activation(activation)
+        , lexicalEnvironment(lexicalEnvironment)
         , watchpointSet(watchpointSet)
         , operand(operand)
     {
@@ -112,8 +115,8 @@ struct ResolveOp {
     ResolveType type;
     size_t depth;
     Structure* structure;
-    JSActivation* activation;
-    VariableWatchpointSet* watchpointSet;
+    JSLexicalEnvironment* lexicalEnvironment;
+    WatchpointSet* watchpointSet;
     uintptr_t operand;
 };
 
@@ -146,14 +149,15 @@ enum GetOrPut { Get, Put };
 class JSScope : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
     friend class LLIntOffsetsExtractor;
     static size_t offsetOfNext();
 
-    JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*);
+    static JSObject* objectAtScope(JSScope*);
 
     static JSValue resolve(ExecState*, JSScope*, const Identifier&);
-    static ResolveOp abstractResolve(ExecState*, JSScope*, const Identifier&, GetOrPut, ResolveType);
+    static ResolveOp abstractResolve(ExecState*, bool hasTopActivation, JSScope*, const Identifier&, GetOrPut, ResolveType);
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -168,7 +172,6 @@ public:
 
 protected:
     JSScope(VM&, Structure*, JSScope* next);
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
 
 private:
     WriteBarrier<JSScope> m_next;
@@ -189,6 +192,7 @@ public:
 
     JSObject* get() const { return JSScope::objectAtScope(m_node); }
     JSObject* operator->() const { return JSScope::objectAtScope(m_node); }
+    JSScope* scope() const { return m_node; }
 
     ScopeChainIterator& operator++() { m_node = m_node->next(); return *this; }
 
@@ -237,20 +241,9 @@ inline JSScope* Register::scope() const
     return jsCast<JSScope*>(jsValue());
 }
 
-inline VM& ExecState::vm() const
-{
-    ASSERT(scope()->vm());
-    return *scope()->vm();
-}
-
 inline JSGlobalObject* ExecState::lexicalGlobalObject() const
 {
-    return scope()->globalObject();
-}
-
-inline JSObject* ExecState::globalThisValue() const
-{
-    return scope()->globalThis();
+    return callee()->globalObject();
 }
 
 inline size_t JSScope::offsetOfNext()
index fba6f7902e0f4c32ab75ae965dca3f83dd524be8..2502fa8393d7161ce6b05cadc6ff137cfbc0f0f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-int JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
+ScopeOffset JSSegmentedVariableObject::findVariableIndex(void* variableAddress)
 {
     ConcurrentJITLocker locker(m_lock);
     
-    for (int i = m_registers.size(); i--;) {
-        if (&m_registers[i] != registerAddress)
+    for (unsigned i = m_variables.size(); i--;) {
+        if (&m_variables[i] != variableAddress)
             continue;
-        return i;
+        return ScopeOffset(i);
     }
     CRASH();
-    return -1;
+    return ScopeOffset();
 }
 
-int JSSegmentedVariableObject::addRegisters(int numberOfRegistersToAdd)
+ScopeOffset JSSegmentedVariableObject::addVariables(unsigned numberOfVariablesToAdd)
 {
     ConcurrentJITLocker locker(m_lock);
     
-    ASSERT(numberOfRegistersToAdd >= 0);
+    size_t oldSize = m_variables.size();
+    m_variables.grow(oldSize + numberOfVariablesToAdd);
     
-    size_t oldSize = m_registers.size();
-    m_registers.grow(oldSize + numberOfRegistersToAdd);
+    for (size_t i = numberOfVariablesToAdd; i--;)
+        m_variables[oldSize + i].setWithoutWriteBarrier(jsUndefined());
     
-    for (size_t i = numberOfRegistersToAdd; i--;)
-        m_registers[oldSize + i].setWithoutWriteBarrier(jsUndefined());
-    
-    return static_cast<int>(oldSize);
+    return ScopeOffset(oldSize);
 }
 
 void JSSegmentedVariableObject::visitChildren(JSCell* cell, SlotVisitor& slotVisitor)
 {
     JSSegmentedVariableObject* thisObject = jsCast<JSSegmentedVariableObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     JSSymbolTableObject::visitChildren(thisObject, slotVisitor);
     
-    for (unsigned i = thisObject->m_registers.size(); i--;)
-        slotVisitor.append(&thisObject->m_registers[i]);
+    for (unsigned i = thisObject->m_variables.size(); i--;)
+        slotVisitor.append(&thisObject->m_variables[i]);
 }
 
 } // namespace JSC
index 7bfdd31a1b23be49b754386460bca987e333aae5..feaf0bb0eb55ed9d62cd374fd5d62be78b67c2de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,11 +41,11 @@ namespace JSC {
 class LLIntOffsetsExtractor;
 class Register;
 
-// This is a mostly drop-in replacement for JSVariableObject, except that it preserves
+// This is a mostly drop-in replacement for JSEnvironmentRecord, except that it preserves
 // the invariant that after a variable is created, its address in memory will not change
 // so long as the JSSegmentedVariableObject is alive. This allows optimizations based
 // on getting the address of the variable and remembering it. As well, unlike a
-// JSVariableObject, this will manage the memory for the registers itself and neither
+// JSEnvironmentRecord, this will manage the memory for the registers itself and neither
 // requires nor allows for the subclasses to manage that memory. Finally,
 // JSSegmentedVariableObject has its own GC tracing functionality, since it knows the
 // exact dimensions of the variables array at all times.
@@ -57,30 +57,31 @@ class JSSegmentedVariableObject : public JSSymbolTableObject {
 public:
     typedef JSSymbolTableObject Base;
 
-    WriteBarrier<Unknown>& registerAt(int index) { return m_registers[index]; }
+    // This is not thread-safe, since m_variables is a segmented vector, and its spine can resize with
+    // malloc/free if new variables - unrelated to the one you are accessing - are added. You can get
+    // around this by grabbing m_lock, or finding some other way to get to the variable pointer (global
+    // variable access bytecode instructions will have a direct pointer already).
+    WriteBarrier<Unknown>& variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; }
     
     // This is a slow method call, which searches the register bank to find the index
     // given a pointer. It will CRASH() if it does not find the register. Only use this
     // in debug code (like bytecode dumping).
-    JS_EXPORT_PRIVATE int findRegisterIndex(void*);
+    JS_EXPORT_PRIVATE ScopeOffset findVariableIndex(void*);
     
-    WriteBarrier<Unknown>* assertRegisterIsInThisObject(WriteBarrier<Unknown>* registerPointer)
+    WriteBarrier<Unknown>* assertVariableIsInThisObject(WriteBarrier<Unknown>* variablePointer)
     {
-#if !ASSERT_DISABLED
-        findRegisterIndex(registerPointer);
-#endif
-        return registerPointer;
+        if (!ASSERT_DISABLED)
+            findVariableIndex(variablePointer);
+        return variablePointer;
     }
     
     // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
     // the index of the first one added.
-    JS_EXPORT_PRIVATE int addRegisters(int numberOfRegistersToAdd);
+    JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd);
     
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
 protected:
-    static const unsigned StructureFlags = OverridesVisitChildren | JSSymbolTableObject::StructureFlags;
-
     JSSegmentedVariableObject(VM& vm, Structure* structure, JSScope* scope)
         : JSSymbolTableObject(vm, structure, scope)
     {
@@ -89,9 +90,10 @@ protected:
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
+        setSymbolTable(vm, SymbolTable::create(vm));
     }
     
-    SegmentedVector<WriteBarrier<Unknown>, 16> m_registers;
+    SegmentedVector<WriteBarrier<Unknown>, 16> m_variables;
     ConcurrentJITLock m_lock;
 };
 
index 9c9aa524a069bea2151c82bc3b036f8ac921a3d8..d875345da8099b26ed4cf311ac58f4569ea451ca 100644 (file)
 #include "JSSet.h"
 
 #include "JSCJSValueInlines.h"
-#include "MapData.h"
+#include "JSSetIterator.h"
+#include "MapDataInlines.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo JSSet::s_info = { "Set", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSSet) };
+const ClassInfo JSSet::s_info = { "Set", &Base::s_info, 0, CREATE_METHOD_TABLE(JSSet) };
+
+void JSSet::destroy(JSCell* cell)
+{
+    JSSet* thisObject = jsCast<JSSet*>(cell);
+    thisObject->JSSet::~JSSet();
+}
 
 void JSSet::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     Base::visitChildren(cell, visitor);
-    JSSet* thisObject = jsCast<JSSet*>(cell);
-    visitor.append(&thisObject->m_mapData);
+    jsCast<JSSet*>(cell)->m_setData.visitChildren(cell, visitor);
+}
+
+void JSSet::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
+{
+    Base::copyBackingStore(cell, visitor, token);
+    jsCast<JSSet*>(cell)->m_setData.copyBackingStore(visitor, token);
+}
+
+bool JSSet::has(ExecState* exec, JSValue value)
+{
+    return m_setData.contains(exec, value);
+}
+
+size_t JSSet::size(ExecState* exec)
+{
+    return m_setData.size(exec);
+}
+
+void JSSet::add(ExecState* exec, JSValue value)
+{
+    m_setData.set(exec, this, value, value);
+}
+
+void JSSet::clear(ExecState*)
+{
+    m_setData.clear();
 }
 
-void JSSet::finishCreation(VM& vm)
+bool JSSet::remove(ExecState* exec, JSValue value)
 {
-    Base::finishCreation(vm);
-    m_mapData.set(vm, this, MapData::create(vm));
+    return m_setData.remove(exec, value);
 }
 
 }
index 22c5d860b482c100a717c552437e87646191e778..e55362ebb6dbce805c2c17528b3dd3ad75ced304 100644 (file)
 #ifndef JSSet_h
 #define JSSet_h
 
+#include "JSDestructibleObject.h"
 #include "JSObject.h"
+#include "MapData.h"
 
 namespace JSC {
 
-class MapData;
+class JSSetIterator;
 
-class JSSet : public JSNonFinalObject {
+class JSSet : public JSDestructibleObject {
 public:
-    typedef JSNonFinalObject Base;
+    typedef JSDestructibleObject Base;
+
+    friend class JSSetIterator;
+
+    // Our marking functions expect Entry to maintain this layout, and have all
+    // fields be WriteBarrier<Unknown>
+    class Entry {
+    private:
+        WriteBarrier<Unknown> m_key;
+
+    public:
+        const WriteBarrier<Unknown>& key() const
+        {
+            return m_key;
+        }
+
+        const WriteBarrier<Unknown>& value() const
+        {
+            return m_key;
+        }
+
+        void visitChildren(SlotVisitor& visitor)
+        {
+            visitor.append(&m_key);
+        }
+
+        void setKey(VM& vm, const JSCell* owner, JSValue key)
+        {
+            m_key.set(vm, owner, key);
+        }
+
+        void setKeyWithoutWriteBarrier(JSValue key)
+        {
+            m_key.setWithoutWriteBarrier(key);
+        }
+
+        void setValue(VM&, const JSCell*, JSValue)
+        {
+        }
+
+        void clear()
+        {
+            m_key.clear();
+        }
+    };
+
+    typedef MapDataImpl<Entry, JSSetIterator> SetData;
 
     DECLARE_EXPORT_INFO;
 
@@ -55,22 +103,24 @@ public:
         return create(exec->vm(), structure);
     }
 
-    MapData* mapData() { return m_mapData.get(); }
+    bool has(ExecState*, JSValue);
+    size_t size(ExecState*);
+    JS_EXPORT_PRIVATE void add(ExecState*, JSValue);
+    void clear(ExecState*);
+    bool remove(ExecState*, JSValue);
 
 private:
-
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     JSSet(VM& vm, Structure* structure)
         : Base(vm, structure)
+        , m_setData(vm)
     {
     }
 
-    JS_EXPORT_PRIVATE void finishCreation(VM&);
-    
+    static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
-    
-    WriteBarrier<MapData> m_mapData;
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
+
+    SetData m_setData;
 };
 
 }
index 1fdfe29a0e617bac73b6eba038bc59b5bc56d5f4..3a0ddbeab9ead6ad09218bd5ca129fef642816ff 100644 (file)
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSSet.h"
+#include "MapDataInlines.h"
 #include "SlotVisitorInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo JSSetIterator::s_info = { "Set Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSSetIterator) };
+const ClassInfo JSSetIterator::s_info = { "Set Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSSetIterator) };
 
 void JSSetIterator::finishCreation(VM& vm, JSSet* iteratedObject)
 {
     Base::finishCreation(vm);
-    m_iteratedObjectData.set(vm, this, iteratedObject->mapData());
+    m_set.set(vm, this, iteratedObject);
 }
 
 void JSSetIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSSetIterator* thisObject = jsCast<JSSetIterator*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-        
     Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_iteratedObjectData);
+    visitor.append(&thisObject->m_set);
+}
+
+void JSSetIterator::destroy(JSCell* cell)
+{
+    JSSetIterator* thisObject = jsCast<JSSetIterator*>(cell);
+    thisObject->JSSetIterator::~JSSetIterator();
 }
 
 JSValue JSSetIterator::createPair(CallFrame* callFrame, JSValue key, JSValue value)
@@ -62,4 +66,11 @@ JSValue JSSetIterator::createPair(CallFrame* callFrame, JSValue key, JSValue val
     return constructArray(callFrame, 0, globalObject, args);
 }
 
+JSSetIterator* JSSetIterator::clone(ExecState* exec)
+{
+    auto clone = JSSetIterator::create(exec->vm(), exec->callee()->globalObject()->setIteratorStructure(), m_set.get(), m_kind);
+    clone->m_iterator = m_iterator;
+    return clone;
+}
+
 }
index 0ecd19e320fe902400b352efc1e9667dcf1d4fe4..6dad6b1b9c848d439d1ebed152d395da707c9f5b 100644 (file)
@@ -58,33 +58,45 @@ public:
 
     bool next(CallFrame* callFrame, JSValue& value)
     {
-        if (!m_iterator.ensureSlot())
+        WTF::KeyValuePair<JSValue, JSValue> pair;
+        if (!m_iterator.next(pair))
             return false;
         if (m_kind == SetIterateValue || m_kind == SetIterateKey)
-            value = m_iterator.key();
+            value = pair.key;
         else
-            value = createPair(callFrame, m_iterator.key(), m_iterator.key());
-        ++m_iterator;
+            value = createPair(callFrame, pair.key, pair.key);
         return true;
     }
 
-private:
+    void finish()
+    {
+        m_iterator.finish();
+    }
 
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesVisitChildren;
+    SetIterationKind kind() const { return m_kind; }
+    JSValue iteratedValue() const { return m_set.get(); }
+    JSSetIterator* clone(ExecState*);
 
+    JSSet::SetData::IteratorData* iteratorData()
+    {
+        return &m_iterator;
+    }
+
+private:
     JSSetIterator(VM& vm, Structure* structure, JSSet* iteratedObject, SetIterationKind kind)
         : Base(vm, structure)
-        , m_iterator(iteratedObject->mapData()->begin())
+        , m_iterator(iteratedObject->m_setData.createIteratorData(this))
         , m_kind(kind)
     {
     }
 
-    void finishCreation(VM&, JSSet*);
-    JSValue createPair(CallFrame*, JSValue, JSValue);
+    static void destroy(JSCell*);
+    JS_EXPORT_PRIVATE void finishCreation(VM&, JSSet*);
+    JS_EXPORT_PRIVATE JSValue createPair(CallFrame*, JSValue, JSValue);
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    WriteBarrier<MapData> m_iteratedObjectData;
-    MapData::const_iterator m_iterator;
+    WriteBarrier<JSSet> m_set;
+    JSSet::SetData::IteratorData m_iterator;
     SetIterationKind m_kind;
 };
 
index 10a16d9733d73d5d42e17bd6f26b2fa27d18de21..eb046ed2df98c52e6d29c57b42ca0e9b73cb009c 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace JSC {
     
-const ClassInfo JSString::s_info = { "string", 0, 0, 0, CREATE_METHOD_TABLE(JSString) };
+const ClassInfo JSString::s_info = { "string", 0, 0, CREATE_METHOD_TABLE(JSString) };
 
 void JSRopeString::RopeBuilder::expand()
 {
@@ -77,30 +77,45 @@ void JSString::visitChildren(JSCell* cell, SlotVisitor& visitor)
     else {
         StringImpl* impl = thisObject->m_value.impl();
         ASSERT(impl);
-        visitor.reportExtraMemoryUsage(thisObject, impl->costDuringGC());
+        visitor.reportExtraMemoryVisited(thisObject, impl->costDuringGC());
     }
 }
 
 void JSRopeString::visitFibers(SlotVisitor& visitor)
 {
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
-        visitor.append(&m_fibers[i]);
+    if (isSubstring()) {
+        visitor.append(&substringBase());
+        return;
+    }
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
+        visitor.append(&fiber(i));
 }
 
 static const unsigned maxLengthForOnStackResolve = 2048;
 
 void JSRopeString::resolveRopeInternal8(LChar* buffer) const
 {
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) {
-        if (m_fibers[i]->isRope()) {
+    if (isSubstring()) {
+        StringImpl::copyChars(
+            buffer, substringBase()->m_value.characters8() + substringOffset(), m_length);
+        return;
+    }
+    
+    resolveRopeInternal8NoSubstring(buffer);
+}
+
+void JSRopeString::resolveRopeInternal8NoSubstring(LChar* buffer) const
+{
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
+        if (fiber(i)->isRope()) {
             resolveRopeSlowCase8(buffer);
             return;
         }
     }
 
     LChar* position = buffer;
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) {
-        const StringImpl& fiberString = *m_fibers[i]->m_value.impl();
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
+        const StringImpl& fiberString = *fiber(i)->m_value.impl();
         unsigned length = fiberString.length();
         StringImpl::copyChars(position, fiberString.characters8(), length);
         position += length;
@@ -110,16 +125,27 @@ void JSRopeString::resolveRopeInternal8(LChar* buffer) const
 
 void JSRopeString::resolveRopeInternal16(UChar* buffer) const
 {
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) {
-        if (m_fibers[i]->isRope()) {
+    if (isSubstring()) {
+        StringImpl::copyChars(
+            buffer, substringBase()->m_value.characters16() + substringOffset(), m_length);
+        return;
+    }
+    
+    resolveRopeInternal16NoSubstring(buffer);
+}
+
+void JSRopeString::resolveRopeInternal16NoSubstring(UChar* buffer) const
+{
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
+        if (fiber(i)->isRope()) {
             resolveRopeSlowCase(buffer);
             return;
         }
     }
 
     UChar* position = buffer;
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) {
-        const StringImpl& fiberString = *m_fibers[i]->m_value.impl();
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
+        const StringImpl& fiberString = *fiber(i)->m_value.impl();
         unsigned length = fiberString.length();
         if (fiberString.is8Bit())
             StringImpl::copyChars(position, fiberString.characters8(), length);
@@ -135,6 +161,7 @@ void JSRopeString::resolveRopeToAtomicString(ExecState* exec) const
     if (m_length > maxLengthForOnStackResolve) {
         resolveRope(exec);
         m_value = AtomicString(m_value);
+        setIs8Bit(m_value.impl()->is8Bit());
         return;
     }
 
@@ -142,50 +169,55 @@ void JSRopeString::resolveRopeToAtomicString(ExecState* exec) const
         LChar buffer[maxLengthForOnStackResolve];
         resolveRopeInternal8(buffer);
         m_value = AtomicString(buffer, m_length);
+        setIs8Bit(m_value.impl()->is8Bit());
     } else {
         UChar buffer[maxLengthForOnStackResolve];
         resolveRopeInternal16(buffer);
         m_value = AtomicString(buffer, m_length);
+        setIs8Bit(m_value.impl()->is8Bit());
     }
 
     clearFibers();
 
     // If we resolved a string that didn't previously exist, notify the heap that we've grown.
     if (m_value.impl()->hasOneRef())
-        Heap::heap(this)->reportExtraMemoryCost(m_value.impl()->cost());
+        Heap::heap(this)->reportExtraMemoryAllocated(m_value.impl()->cost());
 }
 
 void JSRopeString::clearFibers() const
 {
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
-        m_fibers[i].clear();
+    for (size_t i = 0; i < s_maxInternalRopeLength; ++i)
+        u[i].number = 0;
 }
 
-AtomicStringImpl* JSRopeString::resolveRopeToExistingAtomicString(ExecState* exec) const
+RefPtr<AtomicStringImpl> JSRopeString::resolveRopeToExistingAtomicString(ExecState* exec) const
 {
     if (m_length > maxLengthForOnStackResolve) {
         resolveRope(exec);
-        if (AtomicStringImpl* existingAtomicString = AtomicString::find(m_value.impl())) {
+        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(m_value.impl())) {
             m_value = *existingAtomicString;
+            setIs8Bit(m_value.impl()->is8Bit());
             clearFibers();
             return existingAtomicString;
         }
         return nullptr;
     }
-
+    
     if (is8Bit()) {
         LChar buffer[maxLengthForOnStackResolve];
         resolveRopeInternal8(buffer);
-        if (AtomicStringImpl* existingAtomicString = AtomicString::find(buffer, m_length)) {
+        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, m_length)) {
             m_value = *existingAtomicString;
+            setIs8Bit(m_value.impl()->is8Bit());
             clearFibers();
             return existingAtomicString;
         }
     } else {
         UChar buffer[maxLengthForOnStackResolve];
         resolveRopeInternal16(buffer);
-        if (AtomicStringImpl* existingAtomicString = AtomicString::find(buffer, m_length)) {
+        if (RefPtr<AtomicStringImpl> existingAtomicString = AtomicStringImpl::lookUp(buffer, m_length)) {
             m_value = *existingAtomicString;
+            setIs8Bit(m_value.impl()->is8Bit());
             clearFibers();
             return existingAtomicString;
         }
@@ -197,17 +229,24 @@ AtomicStringImpl* JSRopeString::resolveRopeToExistingAtomicString(ExecState* exe
 void JSRopeString::resolveRope(ExecState* exec) const
 {
     ASSERT(isRope());
-
+    
+    if (isSubstring()) {
+        ASSERT(!substringBase()->isRope());
+        m_value = substringBase()->m_value.substring(substringOffset(), m_length);
+        substringBase().clear();
+        return;
+    }
+    
     if (is8Bit()) {
         LChar* buffer;
         if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
-            Heap::heap(this)->reportExtraMemoryCost(newImpl->cost());
+            Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost());
             m_value = newImpl.release();
         } else {
             outOfMemory(exec);
             return;
         }
-        resolveRopeInternal8(buffer);
+        resolveRopeInternal8NoSubstring(buffer);
         clearFibers();
         ASSERT(!isRope());
         return;
@@ -215,14 +254,14 @@ void JSRopeString::resolveRope(ExecState* exec) const
 
     UChar* buffer;
     if (RefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) {
-        Heap::heap(this)->reportExtraMemoryCost(newImpl->cost());
+        Heap::heap(this)->reportExtraMemoryAllocated(newImpl->cost());
         m_value = newImpl.release();
     } else {
         outOfMemory(exec);
         return;
     }
 
-    resolveRopeInternal16(buffer);
+    resolveRopeInternal16NoSubstring(buffer);
     clearFibers();
     ASSERT(!isRope());
 }
@@ -242,24 +281,32 @@ void JSRopeString::resolveRopeSlowCase8(LChar* buffer) const
     LChar* position = buffer + m_length; // We will be working backwards over the rope.
     Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // Putting strings into a Vector is only OK because there are no GC points in this method.
     
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
-        workQueue.append(m_fibers[i].get());
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
+        workQueue.append(fiber(i).get());
 
     while (!workQueue.isEmpty()) {
         JSString* currentFiber = workQueue.last();
         workQueue.removeLast();
 
+        const LChar* characters;
+        
         if (currentFiber->isRope()) {
             JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
-            for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->m_fibers[i]; ++i)
-                workQueue.append(currentFiberAsRope->m_fibers[i].get());
-            continue;
-        }
-
-        StringImpl* string = static_cast<StringImpl*>(currentFiber->m_value.impl());
-        unsigned length = string->length();
+            if (!currentFiberAsRope->isSubstring()) {
+                for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
+                    workQueue.append(currentFiberAsRope->fiber(i).get());
+                continue;
+            }
+            ASSERT(!currentFiberAsRope->substringBase()->isRope());
+            characters =
+                currentFiberAsRope->substringBase()->m_value.characters8() +
+                currentFiberAsRope->substringOffset();
+        } else
+            characters = currentFiber->m_value.characters8();
+        
+        unsigned length = currentFiber->length();
         position -= length;
-        StringImpl::copyChars(position, string->characters8(), length);
+        StringImpl::copyChars(position, characters, length);
     }
 
     ASSERT(buffer == position);
@@ -270,8 +317,8 @@ void JSRopeString::resolveRopeSlowCase(UChar* buffer) const
     UChar* position = buffer + m_length; // We will be working backwards over the rope.
     Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // These strings are kept alive by the parent rope, so using a Vector is OK.
 
-    for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
-        workQueue.append(m_fibers[i].get());
+    for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
+        workQueue.append(fiber(i).get());
 
     while (!workQueue.isEmpty()) {
         JSString* currentFiber = workQueue.last();
@@ -279,8 +326,21 @@ void JSRopeString::resolveRopeSlowCase(UChar* buffer) const
 
         if (currentFiber->isRope()) {
             JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
-            for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->m_fibers[i]; ++i)
-                workQueue.append(currentFiberAsRope->m_fibers[i].get());
+            if (currentFiberAsRope->isSubstring()) {
+                ASSERT(!currentFiberAsRope->substringBase()->isRope());
+                StringImpl* string = static_cast<StringImpl*>(
+                    currentFiberAsRope->substringBase()->m_value.impl());
+                unsigned offset = currentFiberAsRope->substringOffset();
+                unsigned length = currentFiberAsRope->length();
+                position -= length;
+                if (string->is8Bit())
+                    StringImpl::copyChars(position, string->characters8() + offset, length);
+                else
+                    StringImpl::copyChars(position, string->characters16() + offset, length);
+                continue;
+            }
+            for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
+                workQueue.append(currentFiberAsRope->fiber(i).get());
             continue;
         }
 
@@ -305,18 +365,6 @@ void JSRopeString::outOfMemory(ExecState* exec) const
         throwOutOfMemoryError(exec);
 }
 
-JSString* JSRopeString::getIndexSlowCase(ExecState* exec, unsigned i)
-{
-    ASSERT(isRope());
-    resolveRope(exec);
-    // Return a safe no-value result, this should never be used, since the excetion will be thrown.
-    if (exec->exception())
-        return jsEmptyString(exec);
-    ASSERT(!isRope());
-    RELEASE_ASSERT(i < m_value.length());
-    return jsSingleCharacterSubstring(exec, m_value, i);
-}
-
 JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSString*>(this);
@@ -325,18 +373,13 @@ JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) const
 {
     result = this;
-    number = jsToNumber(value(exec));
+    number = jsToNumber(view(exec));
     return false;
 }
 
-bool JSString::toBoolean() const
-{
-    return m_length;
-}
-
 double JSString::toNumber(ExecState* exec) const
 {
-    return jsToNumber(value(exec));
+    return jsToNumber(view(exec));
 }
 
 inline StringObject* StringObject::create(VM& vm, JSGlobalObject* globalObject, JSString* string)
@@ -365,10 +408,9 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, PropertyName propert
         return true;
     }
     
-    unsigned i = propertyName.asIndex();
-    if (i < m_length) {
-        ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
-        descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
+    Optional<uint32_t> index = parseIndex(propertyName);
+    if (index && index.value() < m_length) {
+        descriptor.setDescriptor(getIndex(exec, index.value()), DontDelete | ReadOnly);
         return true;
     }
     
@@ -377,11 +419,12 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, PropertyName propert
 
 JSString* jsStringWithCacheSlowCase(VM& vm, StringImpl& stringImpl)
 {
-    auto addResult = vm.stringCache.add(&stringImpl, nullptr);
-    if (addResult.isNewEntry)
-        addResult.iterator->value = jsString(&vm, String(stringImpl));
-    vm.lastCachedString.set(vm, addResult.iterator->value.get());
-    return addResult.iterator->value.get();
+    if (JSString* string = vm.stringCache.get(&stringImpl))
+        return string;
+
+    JSString* string = jsString(&vm, String(stringImpl));
+    vm.lastCachedString.set(vm, string);
+    return string;
 }
 
 } // namespace JSC
index 1287b66bee4a9ef4f89b122b6d7c7b37f294af7a..068f52fbb6a0cc452e46c27638e639a7ec45fa4e 100644 (file)
 #include "PropertySlot.h"
 #include "Structure.h"
 #include <array>
+#include <wtf/text/StringView.h>
 
 namespace JSC {
 
-    class JSString;
-    class JSRopeString;
-    class LLIntOffsetsExtractor;
+class JSString;
+class JSRopeString;
+class LLIntOffsetsExtractor;
+
+JSString* jsEmptyString(VM*);
+JSString* jsEmptyString(ExecState*);
+JSString* jsString(VM*, const String&); // returns empty string if passed null string
+JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
+
+JSString* jsSingleCharacterString(VM*, UChar);
+JSString* jsSingleCharacterString(ExecState*, UChar);
+JSString* jsSubstring(VM*, const String&, unsigned offset, unsigned length);
+JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
+JSString* jsSubstring8(VM*, const String&, unsigned offset, unsigned length);
+JSString* jsSubstring8(ExecState*, const String&, unsigned offset, unsigned length);
+
+// Non-trivial strings are two or more characters long.
+// These functions are faster than just calling jsString.
+JSString* jsNontrivialString(VM*, const String&);
+JSString* jsNontrivialString(ExecState*, const String&);
+JSString* jsNontrivialString(ExecState*, String&&);
+
+// Should be used for strings that are owned by an object that will
+// likely outlive the JSValue this makes, such as the parse tree or a
+// DOM object that contains a String
+JSString* jsOwnedString(VM*, const String&);
+JSString* jsOwnedString(ExecState*, const String&);
+
+JSRopeString* jsStringBuilder(VM*);
+
+bool isJSString(JSValue);
+JSString* asString(JSValue);
+
+struct StringViewWithUnderlyingString {
+    StringView view;
+    String underlyingString;
+};
+
+class JSString : public JSCell {
+public:
+    friend class JIT;
+    friend class VM;
+    friend class SpecializedThunkJIT;
+    friend class JSRopeString;
+    friend class MarkStack;
+    friend class SlotVisitor;
+    friend struct ThunkHelpers;
+
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+private:
+    JSString(VM& vm, PassRefPtr<StringImpl> value)
+        : JSCell(vm, vm.stringStructure.get())
+        , m_flags(0)
+        , m_value(value)
+    {
+    }
 
-    JSString* jsEmptyString(VM*);
-    JSString* jsEmptyString(ExecState*);
-    JSString* jsString(VM*, const String&); // returns empty string if passed null string
-    JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
+    JSString(VM& vm)
+        : JSCell(vm, vm.stringStructure.get())
+        , m_flags(0)
+    {
+    }
 
-    JSString* jsSingleCharacterString(VM*, UChar);
-    JSString* jsSingleCharacterString(ExecState*, UChar);
-    JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset);
-    JSString* jsSubstring(VM*, const String&, unsigned offset, unsigned length);
-    JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
+    void finishCreation(VM& vm, size_t length)
+    {
+        ASSERT(!m_value.isNull());
+        Base::finishCreation(vm);
+        m_length = length;
+        setIs8Bit(m_value.impl()->is8Bit());
+        vm.m_newStringsSinceLastHashCons++;
+    }
 
-    // Non-trivial strings are two or more characters long.
-    // These functions are faster than just calling jsString.
-    JSString* jsNontrivialString(VM*, const String&);
-    JSString* jsNontrivialString(ExecState*, const String&);
+    void finishCreation(VM& vm, size_t length, size_t cost)
+    {
+        ASSERT(!m_value.isNull());
+        Base::finishCreation(vm);
+        m_length = length;
+        setIs8Bit(m_value.impl()->is8Bit());
+        Heap::heap(this)->reportExtraMemoryAllocated(cost);
+        vm.m_newStringsSinceLastHashCons++;
+    }
 
-    // Should be used for strings that are owned by an object that will
-    // likely outlive the JSValue this makes, such as the parse tree or a
-    // DOM object that contains a String
-    JSString* jsOwnedString(VM*, const String&);
-    JSString* jsOwnedString(ExecState*, const String&);
+protected:
+    void finishCreation(VM& vm)
+    {
+        Base::finishCreation(vm);
+        m_length = 0;
+        setIs8Bit(true);
+        vm.m_newStringsSinceLastHashCons++;
+    }
 
-    JSRopeString* jsStringBuilder(VM*);
+public:
+    static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
+    {
+        ASSERT(value);
+        int32_t length = value->length();
+        RELEASE_ASSERT(length >= 0);
+        size_t cost = value->cost();
+        JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
+        newString->finishCreation(vm, length, cost);
+        return newString;
+    }
+    static JSString* createHasOtherOwner(VM& vm, PassRefPtr<StringImpl> value)
+    {
+        ASSERT(value);
+        size_t length = value->length();
+        JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
+        newString->finishCreation(vm, length);
+        return newString;
+    }
 
-    class JSString : public JSCell {
-    public:
-        friend class JIT;
-        friend class VM;
-        friend class SpecializedThunkJIT;
-        friend class JSRopeString;
-        friend class MarkStack;
-        friend class SlotVisitor;
-        friend struct ThunkHelpers;
+    Identifier toIdentifier(ExecState*) const;
+    AtomicString toAtomicString(ExecState*) const;
+    RefPtr<AtomicStringImpl> toExistingAtomicString(ExecState*) const;
 
-        typedef JSCell Base;
+    class SafeView;
+    SafeView view(ExecState*) const;
+    StringViewWithUnderlyingString viewWithUnderlyingString(ExecState&) const;
 
-        static const bool needsDestruction = true;
-        static const bool hasImmortalStructure = true;
-        static void destroy(JSCell*);
+    const String& value(ExecState*) const;
+    const String& tryGetValue() const;
+    const StringImpl* tryGetValueImpl() const;
+    unsigned length() const { return m_length; }
 
-    private:
-        JSString(VM& vm, PassRefPtr<StringImpl> value)
-            : JSCell(vm, vm.stringStructure.get())
-            , m_flags(0)
-            , m_value(value)
-        {
-        }
-
-        JSString(VM& vm)
-            : JSCell(vm, vm.stringStructure.get())
-            , m_flags(0)
-        {
-        }
+    JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+    bool toBoolean() const { return !!m_length; }
+    bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
+    JSObject* toObject(ExecState*, JSGlobalObject*) const;
+    double toNumber(ExecState*) const;
 
-        void finishCreation(VM& vm, size_t length)
-        {
-            ASSERT(!m_value.isNull());
-            Base::finishCreation(vm);
-            m_length = length;
-            setIs8Bit(m_value.impl()->is8Bit());
-            vm.m_newStringsSinceLastHashCons++;
-        }
-
-        void finishCreation(VM& vm, size_t length, size_t cost)
-        {
-            ASSERT(!m_value.isNull());
-            Base::finishCreation(vm);
-            m_length = length;
-            setIs8Bit(m_value.impl()->is8Bit());
-            Heap::heap(this)->reportExtraMemoryCost(cost);
-            vm.m_newStringsSinceLastHashCons++;
-        }
+    bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
+    bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+    bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
 
-    protected:
-        void finishCreation(VM& vm)
-        {
-            Base::finishCreation(vm);
-            m_length = 0;
-            setIs8Bit(true);
-            vm.m_newStringsSinceLastHashCons++;
-        }
-            
-    public:
-        static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
-        {
-            ASSERT(value);
-            int32_t length = value->length();
-            RELEASE_ASSERT(length >= 0);
-            size_t cost = value->cost();
-            JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
-            newString->finishCreation(vm, length, cost);
-            return newString;
-        }
-        static JSString* createHasOtherOwner(VM& vm, PassRefPtr<StringImpl> value)
-        {
-            ASSERT(value);
-            size_t length = value->length();
-            JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
-            newString->finishCreation(vm, length);
-            return newString;
-        }
+    bool canGetIndex(unsigned i) { return i < m_length; }
+    JSString* getIndex(ExecState*, unsigned);
 
-        Identifier toIdentifier(ExecState*) const;
-        AtomicString toAtomicString(ExecState*) const;
-        AtomicStringImpl* toExistingAtomicString(ExecState*) const;
-        const String& value(ExecState*) const;
-        const String& tryGetValue() const;
-        const StringImpl* tryGetValueImpl() const;
-        unsigned length() const { return m_length; }
-
-        JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        JS_EXPORT_PRIVATE bool toBoolean() const;
-        bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
-        JSObject* toObject(ExecState*, JSGlobalObject*) const;
-        double toNumber(ExecState*) const;
-            
-        bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
-        bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
-        bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
-
-        bool canGetIndex(unsigned i) { return i < m_length; }
-        JSString* getIndex(ExecState*, unsigned);
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
-        {
-            return Structure::create(vm, globalObject, proto, TypeInfo(StringType, StructureFlags), info());
-        }
-
-        static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
-        static size_t offsetOfFlags() { return OBJECT_OFFSETOF(JSString, m_flags); }
-        static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
-
-        DECLARE_EXPORT_INFO;
-
-        static void dumpToStream(const JSCell*, PrintStream&);
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-        enum {
-            HashConsLock = 1u << 2,
-            IsHashConsSingleton = 1u << 1,
-            Is8Bit = 1u
-        };
-
-    protected:
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+    {
+        return Structure::create(vm, globalObject, proto, TypeInfo(StringType, StructureFlags), info());
+    }
 
-        friend class JSValue;
-            
-        bool isRope() const { return m_value.isNull(); }
-        bool is8Bit() const { return m_flags & Is8Bit; }
-        void setIs8Bit(bool flag)
-        {
-            if (flag)
-                m_flags |= Is8Bit;
-            else
-                m_flags &= ~Is8Bit;
-        }
-        bool shouldTryHashCons();
-        bool isHashConsSingleton() const { return m_flags & IsHashConsSingleton; }
-        void clearHashConsSingleton() { m_flags &= ~IsHashConsSingleton; }
-        void setHashConsSingleton() { m_flags |= IsHashConsSingleton; }
-        bool tryHashConsLock();
-        void releaseHashConsLock();
-
-        unsigned m_flags;
-            
-        // A string is represented either by a String or a rope of fibers.
-        unsigned m_length;
-        mutable String m_value;
+    static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
+    static size_t offsetOfFlags() { return OBJECT_OFFSETOF(JSString, m_flags); }
+    static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
 
-    private:
-        friend class LLIntOffsetsExtractor;
-            
-        static JSValue toThis(JSCell*, ExecState*, ECMAMode);
+    DECLARE_EXPORT_INFO;
 
-        String& string() { ASSERT(!isRope()); return m_value; }
+    static void dumpToStream(const JSCell*, PrintStream&);
+    static void visitChildren(JSCell*, SlotVisitor&);
 
-        friend JSValue jsString(ExecState*, JSString*, JSString*);
-        friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
+    enum {
+        HashConsLock = 1u << 2,
+        IsHashConsSingleton = 1u << 1,
+        Is8Bit = 1u
     };
 
-    class JSRopeString : public JSString {
-        friend class JSString;
+protected:
+    friend class JSValue;
 
-        friend JSRopeString* jsStringBuilder(VM*);
+    bool isRope() const { return m_value.isNull(); }
+    bool isSubstring() const;
+    bool is8Bit() const { return m_flags & Is8Bit; }
+    void setIs8Bit(bool flag) const
+    {
+        if (flag)
+            m_flags |= Is8Bit;
+        else
+            m_flags &= ~Is8Bit;
+    }
+    bool shouldTryHashCons();
+    bool isHashConsSingleton() const { return m_flags & IsHashConsSingleton; }
+    void clearHashConsSingleton() { m_flags &= ~IsHashConsSingleton; }
+    void setHashConsSingleton() { m_flags |= IsHashConsSingleton; }
+    bool tryHashConsLock();
+    void releaseHashConsLock();
 
-        class RopeBuilder {
-        public:
-            RopeBuilder(VM& vm)
-                : m_vm(vm)
-                , m_jsString(jsStringBuilder(&vm))
-                , m_index(0)
-            {
-            }
+    mutable unsigned m_flags;
 
-            bool append(JSString* jsString)
-            {
-                if (m_index == JSRopeString::s_maxInternalRopeLength)
-                    expand();
-                if (static_cast<int32_t>(m_jsString->length() + jsString->length()) < 0) {
-                    m_jsString = nullptr;
-                    return false;
-                }
-                m_jsString->append(m_vm, m_index++, jsString);
-                return true;
-            }
+    // A string is represented either by a String or a rope of fibers.
+    unsigned m_length;
+    mutable String m_value;
 
-            JSRopeString* release()
-            {
-                RELEASE_ASSERT(m_jsString);
-                JSRopeString* tmp = m_jsString;
-                m_jsString = 0;
-                return tmp;
-            }
+private:
+    friend class LLIntOffsetsExtractor;
 
-            unsigned length() const { return m_jsString->m_length; }
+    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
 
-        private:
-            void expand();
-                
-            VM& m_vm;
-            JSRopeString* m_jsString;
-            size_t m_index;
-        };
-            
-    private:
-        JSRopeString(VM& vm)
-            : JSString(vm)
-        {
-        }
+    String& string() { ASSERT(!isRope()); return m_value; }
+    StringView unsafeView(ExecState&) const;
 
-        void finishCreation(VM& vm, JSString* s1, JSString* s2)
-        {
-            Base::finishCreation(vm);
-            m_length = s1->length() + s2->length();
-            setIs8Bit(s1->is8Bit() && s2->is8Bit());
-            m_fibers[0].set(vm, this, s1);
-            m_fibers[1].set(vm, this, s2);
-        }
-            
-        void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3)
-        {
-            Base::finishCreation(vm);
-            m_length = s1->length() + s2->length() + s3->length();
-            setIs8Bit(s1->is8Bit() && s2->is8Bit() &&  s3->is8Bit());
-            m_fibers[0].set(vm, this, s1);
-            m_fibers[1].set(vm, this, s2);
-            m_fibers[2].set(vm, this, s3);
-        }
+    friend JSValue jsString(ExecState*, JSString*, JSString*);
+    friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
+};
 
-        void finishCreation(VM& vm)
-        {
-            JSString::finishCreation(vm);
-        }
+class JSRopeString final : public JSString {
+    friend class JSString;
 
-        void append(VM& vm, size_t index, JSString* jsString)
-        {
-            m_fibers[index].set(vm, this, jsString);
-            m_length += jsString->m_length;
-            RELEASE_ASSERT(static_cast<int32_t>(m_length) >= 0);
-            setIs8Bit(is8Bit() && jsString->is8Bit());
-        }
+    friend JSRopeString* jsStringBuilder(VM*);
 
-        static JSRopeString* createNull(VM& vm)
+public:
+    class RopeBuilder {
+    public:
+        RopeBuilder(VM& vm)
+            : m_vm(vm)
+            , m_jsString(jsStringBuilder(&vm))
+            , m_index(0)
         {
-            JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
-            newString->finishCreation(vm);
-            return newString;
         }
 
-    public:
-        static JSString* create(VM& vm, JSString* s1, JSString* s2)
+        bool append(JSString* jsString)
         {
-            JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
-            newString->finishCreation(vm, s1, s2);
-            return newString;
+            if (m_index == JSRopeString::s_maxInternalRopeLength)
+                expand();
+            if (static_cast<int32_t>(m_jsString->length() + jsString->length()) < 0) {
+                m_jsString = nullptr;
+                return false;
+            }
+            m_jsString->append(m_vm, m_index++, jsString);
+            return true;
         }
-        static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3)
+
+        JSRopeString* release()
         {
-            JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
-            newString->finishCreation(vm, s1, s2, s3);
-            return newString;
+            RELEASE_ASSERT(m_jsString);
+            JSRopeString* tmp = m_jsString;
+            m_jsString = 0;
+            return tmp;
         }
 
-        void visitFibers(SlotVisitor&);
-            
-        static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, m_fibers); }
+        unsigned length() const { return m_jsString->m_length; }
 
-        static const unsigned s_maxInternalRopeLength = 3;
-            
     private:
-        friend JSValue jsStringFromRegisterArray(ExecState*, Register*, unsigned);
-        friend JSValue jsStringFromArguments(ExecState*, JSValue);
-
-        JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
-        JS_EXPORT_PRIVATE void resolveRopeToAtomicString(ExecState*) const;
-        JS_EXPORT_PRIVATE AtomicStringImpl* resolveRopeToExistingAtomicString(ExecState*) const;
-        void resolveRopeSlowCase8(LChar*) const;
-        void resolveRopeSlowCase(UChar*) const;
-        void outOfMemory(ExecState*) const;
-        void resolveRopeInternal8(LChar*) const;
-        void resolveRopeInternal16(UChar*) const;
-        void clearFibers() const;
-            
-        JS_EXPORT_PRIVATE JSString* getIndexSlowCase(ExecState*, unsigned);
-
-        mutable std::array<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers;
-    };
+        void expand();
 
+        VM& m_vm;
+        JSRopeString* m_jsString;
+        size_t m_index;
+    };
 
-    inline const StringImpl* JSString::tryGetValueImpl() const
+private:
+    JSRopeString(VM& vm)
+        : JSString(vm)
     {
-        return m_value.impl();
     }
 
-    JSString* asString(JSValue);
-
-    inline JSString* asString(JSValue value)
+    void finishCreation(VM& vm, JSString* s1, JSString* s2)
     {
-        ASSERT(value.asCell()->isString());
-        return jsCast<JSString*>(value.asCell());
+        Base::finishCreation(vm);
+        m_length = s1->length() + s2->length();
+        setIs8Bit(s1->is8Bit() && s2->is8Bit());
+        setIsSubstring(false);
+        fiber(0).set(vm, this, s1);
+        fiber(1).set(vm, this, s2);
+        fiber(2).clear();
     }
 
-    inline JSString* jsEmptyString(VM* vm)
+    void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3)
     {
-        return vm->smallStrings.emptyString();
+        Base::finishCreation(vm);
+        m_length = s1->length() + s2->length() + s3->length();
+        setIs8Bit(s1->is8Bit() && s2->is8Bit() &&  s3->is8Bit());
+        setIsSubstring(false);
+        fiber(0).set(vm, this, s1);
+        fiber(1).set(vm, this, s2);
+        fiber(2).set(vm, this, s3);
     }
 
-    ALWAYS_INLINE JSString* jsSingleCharacterString(VM* vm, UChar c)
+    void finishCreation(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     {
-        if (c <= maxSingleCharacterString)
-            return vm->smallStrings.singleCharacterString(c);
-        return JSString::create(*vm, String(&c, 1).impl());
+        VM& vm = exec.vm();
+        Base::finishCreation(vm);
+        ASSERT(!sumOverflows<int32_t>(offset, length));
+        ASSERT(offset + length <= base.length());
+        m_length = length;
+        setIs8Bit(base.is8Bit());
+        setIsSubstring(true);
+        if (base.isSubstring()) {
+            JSRopeString& baseRope = static_cast<JSRopeString&>(base);
+            substringBase().set(vm, this, baseRope.substringBase().get());
+            substringOffset() = baseRope.substringOffset() + offset;
+        } else {
+            substringBase().set(vm, this, &base);
+            substringOffset() = offset;
+
+            // For now, let's not allow substrings with a rope base.
+            // Resolve non-substring rope bases so we don't have to deal with it.
+            // FIXME: Evaluate if this would be worth adding more branches.
+            if (base.isRope())
+                static_cast<JSRopeString&>(base).resolveRope(&exec);
+        }
     }
 
-    ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset)
+    void finishCreation(VM& vm)
     {
-        VM* vm = &exec->vm();
-        ASSERT(offset < static_cast<unsigned>(s.length()));
-        UChar c = s.characterAt(offset);
-        if (c <= maxSingleCharacterString)
-            return vm->smallStrings.singleCharacterString(c);
-        return JSString::create(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, 1));
+        JSString::finishCreation(vm);
+        setIsSubstring(false);
+        fiber(0).clear();
+        fiber(1).clear();
+        fiber(2).clear();
     }
 
-    inline JSString* jsNontrivialString(VM* vm, const String& s)
+    void append(VM& vm, size_t index, JSString* jsString)
     {
-        ASSERT(s.length() > 1);
-        return JSString::create(*vm, s.impl());
+        fiber(index).set(vm, this, jsString);
+        m_length += jsString->m_length;
+        RELEASE_ASSERT(static_cast<int32_t>(m_length) >= 0);
+        setIs8Bit(is8Bit() && jsString->is8Bit());
     }
 
-    ALWAYS_INLINE Identifier JSString::toIdentifier(ExecState* exec) const
+    static JSRopeString* createNull(VM& vm)
     {
-        return Identifier(exec, toAtomicString(exec));
+        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+        newString->finishCreation(vm);
+        return newString;
     }
 
-    ALWAYS_INLINE AtomicString JSString::toAtomicString(ExecState* exec) const
+public:
+    static JSString* create(VM& vm, JSString* s1, JSString* s2)
     {
-        if (isRope())
-            static_cast<const JSRopeString*>(this)->resolveRopeToAtomicString(exec);
-        return AtomicString(m_value);
+        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+        newString->finishCreation(vm, s1, s2);
+        return newString;
     }
-
-    ALWAYS_INLINE AtomicStringImpl* JSString::toExistingAtomicString(ExecState* exec) const
+    static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3)
     {
-        if (isRope())
-            return static_cast<const JSRopeString*>(this)->resolveRopeToExistingAtomicString(exec);
-        if (m_value.impl()->isAtomic())
-            return static_cast<AtomicStringImpl*>(m_value.impl());
-        if (AtomicStringImpl* existingAtomicString = AtomicString::find(m_value.impl())) {
-            m_value = *existingAtomicString;
-            return existingAtomicString;
-        }
-        return nullptr;
+        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+        newString->finishCreation(vm, s1, s2, s3);
+        return newString;
     }
 
-    inline const String& JSString::value(ExecState* exec) const
+    static JSString* create(ExecState& exec, JSString& base, unsigned offset, unsigned length)
     {
-        if (isRope())
-            static_cast<const JSRopeString*>(this)->resolveRope(exec);
-        return m_value;
+        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(exec.vm().heap)) JSRopeString(exec.vm());
+        newString->finishCreation(exec, base, offset, length);
+        return newString;
     }
 
-    inline const String& JSString::tryGetValue() const
-    {
-        if (isRope())
-            static_cast<const JSRopeString*>(this)->resolveRope(0);
-        return m_value;
-    }
+    void visitFibers(SlotVisitor&);
 
-    inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
-    {
-        ASSERT(canGetIndex(i));
-        if (isRope())
-            return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
-        ASSERT(i < m_value.length());
-        return jsSingleCharacterSubstring(exec, m_value, i);
-    }
+    static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, u); }
 
-    inline JSString* jsString(VM* vm, const String& s)
+    static const unsigned s_maxInternalRopeLength = 3;
+
+private:
+    friend JSValue jsStringFromRegisterArray(ExecState*, Register*, unsigned);
+    friend JSValue jsStringFromArguments(ExecState*, JSValue);
+
+    JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
+    JS_EXPORT_PRIVATE void resolveRopeToAtomicString(ExecState*) const;
+    JS_EXPORT_PRIVATE RefPtr<AtomicStringImpl> resolveRopeToExistingAtomicString(ExecState*) const;
+    void resolveRopeSlowCase8(LChar*) const;
+    void resolveRopeSlowCase(UChar*) const;
+    void outOfMemory(ExecState*) const;
+    void resolveRopeInternal8(LChar*) const;
+    void resolveRopeInternal8NoSubstring(LChar*) const;
+    void resolveRopeInternal16(UChar*) const;
+    void resolveRopeInternal16NoSubstring(UChar*) const;
+    void clearFibers() const;
+    StringView unsafeView(ExecState&) const;
+    StringViewWithUnderlyingString viewWithUnderlyingString(ExecState&) const;
+
+    WriteBarrierBase<JSString>& fiber(unsigned i) const
     {
-        int size = s.length();
-        if (!size)
-            return vm->smallStrings.emptyString();
-        if (size == 1) {
-            UChar c = s.characterAt(0);
-            if (c <= maxSingleCharacterString)
-                return vm->smallStrings.singleCharacterString(c);
-        }
-        return JSString::create(*vm, s.impl());
+        ASSERT(!isSubstring());
+        ASSERT(i < s_maxInternalRopeLength);
+        return u[i].string;
     }
 
-    inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
+    WriteBarrierBase<JSString>& substringBase() const
     {
-        ASSERT(offset <= static_cast<unsigned>(s->length()));
-        ASSERT(length <= static_cast<unsigned>(s->length()));
-        ASSERT(offset + length <= static_cast<unsigned>(s->length()));
-        VM* vm = &exec->vm();
-        if (!length)
-            return vm->smallStrings.emptyString();
-        return jsSubstring(vm, s->value(exec), offset, length);
+        return u[1].string;
     }
 
-    inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
+    uintptr_t& substringOffset() const
     {
-        ASSERT(offset <= static_cast<unsigned>(s.length()));
-        ASSERT(length <= static_cast<unsigned>(s.length()));
-        ASSERT(offset + length <= static_cast<unsigned>(s.length()));
-        if (!length)
-            return vm->smallStrings.emptyString();
-        if (length == 1) {
-            UChar c = s.characterAt(offset);
-            if (c <= maxSingleCharacterString)
-                return vm->smallStrings.singleCharacterString(c);
-        }
-        return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl8(s.impl(), offset, length));
+        return u[2].number;
     }
 
-    inline JSString* jsSubstring(VM* vm, const String& s, unsigned offset, unsigned length)
+    static uintptr_t notSubstringSentinel()
     {
-        ASSERT(offset <= static_cast<unsigned>(s.length()));
-        ASSERT(length <= static_cast<unsigned>(s.length()));
-        ASSERT(offset + length <= static_cast<unsigned>(s.length()));
-        if (!length)
-            return vm->smallStrings.emptyString();
-        if (length == 1) {
-            UChar c = s.characterAt(offset);
-            if (c <= maxSingleCharacterString)
-                return vm->smallStrings.singleCharacterString(c);
-        }
-        return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, length));
+        return 0;
     }
 
-    inline JSString* jsOwnedString(VM* vm, const String& s)
+    static uintptr_t substringSentinel()
     {
-        int size = s.length();
-        if (!size)
-            return vm->smallStrings.emptyString();
-        if (size == 1) {
-            UChar c = s.characterAt(0);
-            if (c <= maxSingleCharacterString)
-                return vm->smallStrings.singleCharacterString(c);
-        }
-        return JSString::createHasOtherOwner(*vm, s.impl());
+        return 1;
     }
 
-    inline JSRopeString* jsStringBuilder(VM* vm)
+    bool isSubstring() const
     {
-        return JSRopeString::createNull(*vm);
+        return u[0].number == substringSentinel();
     }
 
-    inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->vm()); }
-    inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->vm(), s); }
-    inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->vm(), c); }
-    inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->vm(), s, offset, length); }
-    inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->vm(), s, offset, length); }
-    inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
-    inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
-
-    JS_EXPORT_PRIVATE JSString* jsStringWithCacheSlowCase(VM&, StringImpl&);
-
-    ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const String& s)
+    void setIsSubstring(bool isSubstring)
     {
-        VM& vm = exec->vm();
-        StringImpl* stringImpl = s.impl();
-        if (!stringImpl || !stringImpl->length())
-            return jsEmptyString(&vm);
-
-        if (stringImpl->length() == 1) {
-            UChar singleCharacter = (*stringImpl)[0u];
-            if (singleCharacter <= maxSingleCharacterString)
-                return vm.smallStrings.singleCharacterString(static_cast<unsigned char>(singleCharacter));
-        }
+        u[0].number = isSubstring ? substringSentinel() : notSubstringSentinel();
+    }
 
-        if (JSString* lastCachedString = vm.lastCachedString.get()) {
-            if (lastCachedString->tryGetValueImpl() == stringImpl)
-                return lastCachedString;
-        }
+    mutable union {
+        uintptr_t number;
+        WriteBarrierBase<JSString> string;
+    } u[s_maxInternalRopeLength];
+};
+
+class JSString::SafeView {
+public:
+    SafeView();
+    explicit SafeView(ExecState&, const JSString&);
+    operator StringView() const;
+    StringView get() const;
+
+private:
+    ExecState* m_state { nullptr };
+
+    // The following pointer is marked "volatile" to make the compiler leave it on the stack
+    // or in a register as long as this object is alive, even after the last use of the pointer.
+    // That's needed to prevent garbage collecting the string and possibly deleting the block
+    // with the characters in it, and then using the StringView after that.
+    const JSString* volatile m_string { nullptr };
+};
+
+JS_EXPORT_PRIVATE JSString* jsStringWithCacheSlowCase(VM&, StringImpl&);
+
+inline const StringImpl* JSString::tryGetValueImpl() const
+{
+    return m_value.impl();
+}
+
+inline JSString* asString(JSValue value)
+{
+    ASSERT(value.asCell()->isString());
+    return jsCast<JSString*>(value.asCell());
+}
+
+inline JSString* jsEmptyString(VM* vm)
+{
+    return vm->smallStrings.emptyString();
+}
+
+ALWAYS_INLINE JSString* jsSingleCharacterString(VM* vm, UChar c)
+{
+    if (c <= maxSingleCharacterString)
+        return vm->smallStrings.singleCharacterString(c);
+    return JSString::create(*vm, String(&c, 1).impl());
+}
+
+inline JSString* jsNontrivialString(VM* vm, const String& s)
+{
+    ASSERT(s.length() > 1);
+    return JSString::create(*vm, s.impl());
+}
+
+inline JSString* jsNontrivialString(VM* vm, String&& s)
+{
+    ASSERT(s.length() > 1);
+    return JSString::create(*vm, s.releaseImpl());
+}
+
+ALWAYS_INLINE Identifier JSString::toIdentifier(ExecState* exec) const
+{
+    return Identifier::fromString(exec, toAtomicString(exec));
+}
+
+ALWAYS_INLINE AtomicString JSString::toAtomicString(ExecState* exec) const
+{
+    if (isRope())
+        static_cast<const JSRopeString*>(this)->resolveRopeToAtomicString(exec);
+    return AtomicString(m_value);
+}
+
+ALWAYS_INLINE RefPtr<AtomicStringImpl> JSString::toExistingAtomicString(ExecState* exec) const
+{
+    if (isRope())
+        return static_cast<const JSRopeString*>(this)->resolveRopeToExistingAtomicString(exec);
+    if (m_value.impl()->isAtomic())
+        return static_cast<AtomicStringImpl*>(m_value.impl());
+    return AtomicStringImpl::lookUp(m_value.impl());
+}
+
+inline const String& JSString::value(ExecState* exec) const
+{
+    if (isRope())
+        static_cast<const JSRopeString*>(this)->resolveRope(exec);
+    return m_value;
+}
+
+inline const String& JSString::tryGetValue() const
+{
+    if (isRope())
+        static_cast<const JSRopeString*>(this)->resolveRope(0);
+    return m_value;
+}
+
+inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
+{
+    ASSERT(canGetIndex(i));
+    return jsSingleCharacterString(exec, unsafeView(*exec)[i]);
+}
+
+inline JSString* jsString(VM* vm, const String& s)
+{
+    int size = s.length();
+    if (!size)
+        return vm->smallStrings.emptyString();
+    if (size == 1) {
+        UChar c = s.characterAt(0);
+        if (c <= maxSingleCharacterString)
+            return vm->smallStrings.singleCharacterString(c);
+    }
+    return JSString::create(*vm, s.impl());
+}
+
+inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
+{
+    ASSERT(offset <= static_cast<unsigned>(s->length()));
+    ASSERT(length <= static_cast<unsigned>(s->length()));
+    ASSERT(offset + length <= static_cast<unsigned>(s->length()));
+    VM& vm = exec->vm();
+    if (!length)
+        return vm.smallStrings.emptyString();
+    if (!offset && length == s->length())
+        return s;
+    return JSRopeString::create(*exec, *s, offset, length);
+}
+
+inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
+{
+    ASSERT(offset <= static_cast<unsigned>(s.length()));
+    ASSERT(length <= static_cast<unsigned>(s.length()));
+    ASSERT(offset + length <= static_cast<unsigned>(s.length()));
+    if (!length)
+        return vm->smallStrings.emptyString();
+    if (length == 1) {
+        UChar c = s.characterAt(offset);
+        if (c <= maxSingleCharacterString)
+            return vm->smallStrings.singleCharacterString(c);
+    }
+    return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl8(s.impl(), offset, length));
+}
+
+inline JSString* jsSubstring(VM* vm, const String& s, unsigned offset, unsigned length)
+{
+    ASSERT(offset <= static_cast<unsigned>(s.length()));
+    ASSERT(length <= static_cast<unsigned>(s.length()));
+    ASSERT(offset + length <= static_cast<unsigned>(s.length()));
+    if (!length)
+        return vm->smallStrings.emptyString();
+    if (length == 1) {
+        UChar c = s.characterAt(offset);
+        if (c <= maxSingleCharacterString)
+            return vm->smallStrings.singleCharacterString(c);
+    }
+    return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, length));
+}
 
-        return jsStringWithCacheSlowCase(vm, *stringImpl);
+inline JSString* jsOwnedString(VM* vm, const String& s)
+{
+    int size = s.length();
+    if (!size)
+        return vm->smallStrings.emptyString();
+    if (size == 1) {
+        UChar c = s.characterAt(0);
+        if (c <= maxSingleCharacterString)
+            return vm->smallStrings.singleCharacterString(c);
+    }
+    return JSString::createHasOtherOwner(*vm, s.impl());
+}
+
+inline JSRopeString* jsStringBuilder(VM* vm)
+{
+    return JSRopeString::createNull(*vm);
+}
+
+inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->vm()); }
+inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->vm(), s); }
+inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->vm(), c); }
+inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->vm(), s, offset, length); }
+inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->vm(), s, offset, length); }
+inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
+inline JSString* jsNontrivialString(ExecState* exec, String&& s) { return jsNontrivialString(&exec->vm(), WTF::move(s)); }
+inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
+
+ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const String& s)
+{
+    VM& vm = exec->vm();
+    StringImpl* stringImpl = s.impl();
+    if (!stringImpl || !stringImpl->length())
+        return jsEmptyString(&vm);
+
+    if (stringImpl->length() == 1) {
+        UChar singleCharacter = (*stringImpl)[0u];
+        if (singleCharacter <= maxSingleCharacterString)
+            return vm.smallStrings.singleCharacterString(static_cast<unsigned char>(singleCharacter));
     }
 
-    ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const AtomicString& s)
-    {
-        return jsStringWithCache(exec, s.string());
+    if (JSString* lastCachedString = vm.lastCachedString.get()) {
+        if (lastCachedString->tryGetValueImpl() == stringImpl)
+            return lastCachedString;
     }
 
-    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-    {
-        if (propertyName == exec->propertyNames().length) {
-            slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
-            return true;
-        }
+    return jsStringWithCacheSlowCase(vm, *stringImpl);
+}
 
-        unsigned i = propertyName.asIndex();
-        if (i < m_length) {
-            ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
-            slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
-            return true;
-        }
+ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const AtomicString& s)
+{
+    return jsStringWithCache(exec, s.string());
+}
 
-        return false;
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().length) {
+        slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
+        return true;
     }
-            
-    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
-    {
-        if (propertyName < m_length) {
-            slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
-            return true;
-        }
 
-        return false;
+    Optional<uint32_t> index = parseIndex(propertyName);
+    if (index && index.value() < m_length) {
+        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, index.value()));
+        return true;
     }
 
-    inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->type() == StringType; }
-
-    // --- JSValue inlines ----------------------------
-        
-    inline bool JSValue::toBoolean(ExecState* exec) const
-    {
-        if (isInt32())
-            return asInt32();
-        if (isDouble())
-            return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
-        if (isCell())
-            return asCell()->toBoolean(exec);
-        return isTrue(); // false, null, and undefined all convert to false.
-    }
+    return false;
+}
 
-    inline JSString* JSValue::toString(ExecState* exec) const
-    {
-        if (isString())
-            return jsCast<JSString*>(asCell());
-        return toStringSlowCase(exec);
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    if (propertyName < m_length) {
+        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
+        return true;
     }
 
-    inline String JSValue::toWTFString(ExecState* exec) const
-    {
-        if (isString())
-            return static_cast<JSString*>(asCell())->value(exec);
-        return toWTFStringSlowCase(exec);
-    }
+    return false;
+}
 
-    ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
-    {
-        VM& vm = exec->vm();
-        if (value.isInt32())
-            return vm.numericStrings.add(value.asInt32());
-        if (value.isDouble())
-            return vm.numericStrings.add(value.asDouble());
-        if (value.isTrue())
-            return vm.propertyNames->trueKeyword.string();
-        if (value.isFalse())
-            return vm.propertyNames->falseKeyword.string();
-        if (value.isNull())
-            return vm.propertyNames->nullKeyword.string();
-        if (value.isUndefined())
-            return vm.propertyNames->undefinedKeyword.string();
-        return value.toString(exec)->value(exec);
-    }
-
-    ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
-    {
-        if (isString())
-            return static_cast<JSString*>(asCell())->value(exec);
+inline bool isJSString(JSValue v)
+{
+    return v.isCell() && v.asCell()->type() == StringType;
+}
 
-        return inlineJSValueNotStringtoString(*this, exec);
+ALWAYS_INLINE StringView JSRopeString::unsafeView(ExecState& state) const
+{
+    if (isSubstring()) {
+        if (is8Bit())
+            return StringView(substringBase()->m_value.characters8() + substringOffset(), m_length);
+        return StringView(substringBase()->m_value.characters16() + substringOffset(), m_length);
+    }
+    resolveRope(&state);
+    return m_value;
+}
+
+ALWAYS_INLINE StringViewWithUnderlyingString JSRopeString::viewWithUnderlyingString(ExecState& state) const
+{
+    if (isSubstring()) {
+        auto& base = substringBase()->m_value;
+        if (is8Bit())
+            return { { base.characters8() + substringOffset(), m_length }, base };
+        return { { base.characters16() + substringOffset(), m_length }, base };
     }
+    resolveRope(&state);
+    return { m_value, m_value };
+}
+
+ALWAYS_INLINE StringView JSString::unsafeView(ExecState& state) const
+{
+    if (isRope())
+        return static_cast<const JSRopeString*>(this)->unsafeView(state);
+    return m_value;
+}
+
+ALWAYS_INLINE StringViewWithUnderlyingString JSString::viewWithUnderlyingString(ExecState& state) const
+{
+    if (isRope())
+        return static_cast<const JSRopeString&>(*this).viewWithUnderlyingString(state);
+    return { m_value, m_value };
+}
+
+inline bool JSString::isSubstring() const
+{
+    return isRope() && static_cast<const JSRopeString*>(this)->isSubstring();
+}
+
+inline JSString::SafeView::SafeView()
+{
+}
+
+inline JSString::SafeView::SafeView(ExecState& state, const JSString& string)
+    : m_state(&state)
+    , m_string(&string)
+{
+}
+
+inline JSString::SafeView::operator StringView() const
+{
+    return m_string->unsafeView(*m_state);
+}
+
+inline StringView JSString::SafeView::get() const
+{
+    return *this;
+}
+
+ALWAYS_INLINE JSString::SafeView JSString::view(ExecState* exec) const
+{
+    return SafeView(*exec, *this);
+}
+
+// --- JSValue inlines ----------------------------
+
+inline bool JSValue::toBoolean(ExecState* exec) const
+{
+    if (isInt32())
+        return asInt32();
+    if (isDouble())
+        return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
+    if (isCell())
+        return asCell()->toBoolean(exec);
+    return isTrue(); // false, null, and undefined all convert to false.
+}
+
+inline JSString* JSValue::toString(ExecState* exec) const
+{
+    if (isString())
+        return jsCast<JSString*>(asCell());
+    return toStringSlowCase(exec);
+}
+
+inline String JSValue::toWTFString(ExecState* exec) const
+{
+    if (isString())
+        return static_cast<JSString*>(asCell())->value(exec);
+    return toWTFStringSlowCase(exec);
+}
 
 } // namespace JSC
 
index 63e51a3ce29febc80860f9da357217c161a68d1f..34f43c4db21aa23ffe4a403731ea2973428ac055 100644 (file)
@@ -118,49 +118,19 @@ private:
     bool m_is8Bit;
 };
 
-template<typename StringType1, typename StringType2>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
+template<typename StringType>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType&& string)
 {
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
+    return jsNontrivialString(exec, std::forward<StringType>(string));
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+template<typename StringType, typename... StringTypes>
+inline JSValue jsMakeNontrivialString(ExecState* exec, const StringType& string, const StringTypes&... strings)
 {
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
+    RefPtr<StringImpl> result = WTF::tryMakeString(string, strings...);
     if (!result)
         return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
+    return jsNontrivialString(exec, result.release());
 }
 
 }
diff --git a/runtime/JSStringIterator.cpp b/runtime/JSStringIterator.cpp
new file mode 100644 (file)
index 0000000..c6fede7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSStringIterator.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSStringIterator::s_info = { "String Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSStringIterator) };
+
+void JSStringIterator::finishCreation(VM& vm, JSGlobalObject*, JSString* iteratedString)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+    putDirect(vm, vm.propertyNames->iteratedStringPrivateName, iteratedString);
+    putDirect(vm, vm.propertyNames->stringIteratorNextIndexPrivateName, jsNumber(0));
+}
+
+JSValue JSStringIterator::iteratedValue(ExecState* exec) const
+{
+    return getDirect(exec->vm(), exec->vm().propertyNames->iteratedStringPrivateName);
+}
+
+JSStringIterator* JSStringIterator::clone(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSValue iteratedString = getDirect(vm, vm.propertyNames->iteratedStringPrivateName);
+    JSValue nextIndex = getDirect(vm, vm.propertyNames->stringIteratorNextIndexPrivateName);
+
+    auto clone = JSStringIterator::create(exec, exec->callee()->globalObject()->stringIteratorStructure(), asString(iteratedString));
+    clone->putDirect(vm, vm.propertyNames->stringIteratorNextIndexPrivateName, nextIndex);
+    return clone;
+}
+
+} // namespace JSC
diff --git a/runtime/JSStringIterator.h b/runtime/JSStringIterator.h
new file mode 100644 (file)
index 0000000..6a789a3
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSStringIterator_h
+#define JSStringIterator_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class JSStringIterator : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static JSStringIterator* create(ExecState* exec, Structure* structure, JSString* iteratedString)
+    {
+        VM& vm = exec->vm();
+        JSStringIterator* instance = new (NotNull, allocateCell<JSStringIterator>(vm.heap)) JSStringIterator(vm, structure);
+        instance->finishCreation(vm, structure->globalObject(), iteratedString);
+        return instance;
+    }
+
+    JSValue iteratedValue(ExecState*) const;
+    JSStringIterator* clone(ExecState*);
+
+private:
+    JSStringIterator(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    void finishCreation(VM&, JSGlobalObject*, JSString* iteratedString);
+};
+
+}
+
+#endif // !defined(JSStringIterator_h)
index f9870c3423b4ad1119825bf51df137a821a03cc2..6f19593881966e93e4a39f266eb7bce6d7f9c5a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "JSStringJoiner.h"
 
-#include "ExceptionHelpers.h"
-#include "JSScope.h"
-#include "JSString.h"
 #include "JSCInlines.h"
-#include <wtf/text/StringImpl.h>
 
 namespace JSC {
 
-// The destination is 16bits, at least one string is 16 bits.
-static inline void appendStringToData(UChar*& data, const String& string)
+template<typename CharacterType>
+static inline void appendStringToData(CharacterType*& data, StringView string)
 {
-    if (string.isNull())
-        return;
+    string.getCharactersWithUpconvert(data);
+    data += string.length();
+}
 
-    unsigned length = string.length();
-    const StringImpl* stringImpl = string.impl();
+template<typename CharacterType>
+static inline String joinStrings(const Vector<StringViewWithUnderlyingString>& strings, StringView separator, unsigned joinedLength)
+{
+    ASSERT(joinedLength);
 
-    if (stringImpl->is8Bit()) {
-        for (unsigned i = 0; i < length; ++i) {
-            *data = stringImpl->characters8()[i];
-            ++data;
+    CharacterType* data;
+    String result = StringImpl::tryCreateUninitialized(joinedLength, data);
+    if (result.isNull())
+        return result;
+
+    appendStringToData(data, strings[0].view);
+
+    unsigned size = strings.size();
+
+    switch (separator.length()) {
+    case 0:
+        for (unsigned i = 1; i < size; ++i)
+            appendStringToData(data, strings[i].view);
+        break;
+    case 1: {
+        CharacterType separatorCharacter = separator[0];
+        for (unsigned i = 1; i < size; ++i) {
+            *data++ = separatorCharacter;
+            appendStringToData(data, strings[i].view);
         }
-    } else {
-        for (unsigned i = 0; i < length; ++i) {
-            *data = stringImpl->characters16()[i];
-            ++data;
+        break;
+    }
+    default:
+        for (unsigned i = 1; i < size; ++i) {
+            appendStringToData(data, separator);
+            appendStringToData(data, strings[i].view);
         }
     }
-}
-
-// If the destination is 8bits, we know every string has to be 8bit.
-static inline void appendStringToData(LChar*& data, const String& string)
-{
-    if (string.isNull())
-        return;
-    ASSERT(string.is8Bit());
+    ASSERT(data == result.characters<CharacterType>() + joinedLength);
 
-    unsigned length = string.length();
-    const StringImpl* stringImpl = string.impl();
-
-    for (unsigned i = 0; i < length; ++i) {
-        *data = stringImpl->characters8()[i];
-        ++data;
-    }
+    return result;
 }
 
-template<typename CharacterType>
-static inline PassRefPtr<StringImpl> joinStrings(const Vector<String>& strings, const String& separator, unsigned outputLength)
+inline unsigned JSStringJoiner::joinedLength(ExecState& state) const
 {
-    ASSERT(outputLength);
-
-    CharacterType* data;
-    RefPtr<StringImpl> outputStringImpl = StringImpl::tryCreateUninitialized(outputLength, data);
-    if (!outputStringImpl)
-        return nullptr;
+    unsigned numberOfStrings = m_strings.size();
+    if (!numberOfStrings)
+        return 0;
 
-    const String firstString = strings.first();
-    appendStringToData(data, firstString);
+    Checked<unsigned, RecordOverflow> separatorLength = m_separator.length();
+    Checked<unsigned, RecordOverflow> totalSeparatorsLength = separatorLength * (numberOfStrings - 1);
+    Checked<unsigned, RecordOverflow> totalLength = totalSeparatorsLength + m_accumulatedStringsLength;
 
-    for (size_t i = 1; i < strings.size(); ++i) {
-        appendStringToData(data, separator);
-        appendStringToData(data, strings[i]);
+    unsigned result;
+    if (totalLength.safeGet(result) == CheckedState::DidOverflow) {
+        throwOutOfMemoryError(&state);
+        return 0;
     }
-
-    ASSERT(data == (outputStringImpl->characters<CharacterType>() + outputStringImpl->length()));
-    return outputStringImpl.release();
+    return result;
 }
 
-JSValue JSStringJoiner::join(ExecState* exec)
+JSValue JSStringJoiner::join(ExecState& state)
 {
-    if (!m_isValid)
-        return throwOutOfMemoryError(exec);
+    ASSERT(m_strings.size() <= m_strings.capacity());
 
-    if (!m_strings.size())
-        return jsEmptyString(exec);
+    unsigned length = joinedLength(state);
+    if (state.hadException())
+        return jsUndefined();
 
-    Checked<unsigned, RecordOverflow> separatorLength = m_separator.length();
-    // FIXME: add special cases of joinStrings() for (separatorLength == 0) and (separatorLength == 1).
-    ASSERT(m_strings.size() > 0);
-    Checked<unsigned, RecordOverflow> totalSeparactorsLength = separatorLength * (m_strings.size() - 1);
-    Checked<unsigned, RecordOverflow> outputStringSize = totalSeparactorsLength + m_accumulatedStringsLength;
-
-    unsigned finalSize;
-    if (outputStringSize.safeGet(finalSize) == CheckedState::DidOverflow)
-        return throwOutOfMemoryError(exec);
-        
-    if (!outputStringSize)
-        return jsEmptyString(exec);
-
-    RefPtr<StringImpl> outputStringImpl;
-    if (m_is8Bits)
-        outputStringImpl = joinStrings<LChar>(m_strings, m_separator, finalSize);
+    if (!length)
+        return jsEmptyString(&state);
+
+    String result;
+    if (m_isAll8Bit)
+        result = joinStrings<LChar>(m_strings, m_separator, length);
     else
-        outputStringImpl = joinStrings<UChar>(m_strings, m_separator, finalSize);
+        result = joinStrings<UChar>(m_strings, m_separator, length);
 
-    if (!outputStringImpl)
-        return throwOutOfMemoryError(exec);
+    if (result.isNull())
+        return throwOutOfMemoryError(&state);
 
-    return JSString::create(exec->vm(), outputStringImpl.release());
+    return jsString(&state, WTF::move(result));
 }
 
 }
index 73950c6d745a0ac8caf3eca3225277f7673ef254..2247844933a26c7b497e62efea5268694785e134 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSStringJoiner_h
 #define JSStringJoiner_h
 
+#include "ExceptionHelpers.h"
 #include "JSCJSValue.h"
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
 
 namespace JSC {
 
-class ExecState;
-
-
 class JSStringJoiner {
 public:
-    JSStringJoiner(const String& separator, size_t stringCount);
+    JSStringJoiner(ExecState&, LChar separator, unsigned stringCount);
+    JSStringJoiner(ExecState&, StringView separator, unsigned stringCount);
 
-    void append(const String&);
-    JSValue join(ExecState*);
+    void append(ExecState&, JSValue);
+    void appendEmptyString();
+
+    JSValue join(ExecState&);
 
 private:
-    String m_separator;
-    Vector<String> m_strings;
+    void append(StringViewWithUnderlyingString&&);
+    void append8Bit(const String&);
+    void appendLiteral(const Identifier&);
+    unsigned joinedLength(ExecState&) const;
 
+    LChar m_singleCharacterSeparator;
+    StringView m_separator;
+    Vector<StringViewWithUnderlyingString> m_strings;
     Checked<unsigned, RecordOverflow> m_accumulatedStringsLength;
-    bool m_isValid;
-    bool m_is8Bits;
+    bool m_isAll8Bit { true };
 };
 
-inline JSStringJoiner::JSStringJoiner(const String& separator, size_t stringCount)
+inline JSStringJoiner::JSStringJoiner(ExecState& state, StringView separator, unsigned stringCount)
     : m_separator(separator)
-    , m_isValid(true)
-    , m_is8Bits(m_separator.is8Bit())
+    , m_isAll8Bit(m_separator.is8Bit())
+{
+    if (!m_strings.tryReserveCapacity(stringCount))
+        throwOutOfMemoryError(&state);
+}
+
+inline JSStringJoiner::JSStringJoiner(ExecState& state, LChar separator, unsigned stringCount)
+    : m_singleCharacterSeparator(separator)
+    , m_separator { &m_singleCharacterSeparator, 1 }
+{
+    if (!m_strings.tryReserveCapacity(stringCount))
+        throwOutOfMemoryError(&state);
+}
+
+ALWAYS_INLINE void JSStringJoiner::append(StringViewWithUnderlyingString&& string)
 {
-    ASSERT(!m_separator.isNull());
-    m_isValid = m_strings.tryReserveCapacity(stringCount);
+    m_accumulatedStringsLength += string.view.length();
+    m_isAll8Bit = m_isAll8Bit && string.view.is8Bit();
+    m_strings.uncheckedAppend(WTF::move(string));
 }
 
-inline void JSStringJoiner::append(const String& str)
+ALWAYS_INLINE void JSStringJoiner::append8Bit(const String& string)
 {
-    if (!m_isValid)
+    ASSERT(string.is8Bit());
+    m_accumulatedStringsLength += string.length();
+    m_strings.uncheckedAppend({ string, string });
+}
+
+ALWAYS_INLINE void JSStringJoiner::appendLiteral(const Identifier& literal)
+{
+    m_accumulatedStringsLength += literal.length();
+    ASSERT(literal.string().is8Bit());
+    m_strings.uncheckedAppend({ literal.string(), { } });
+}
+
+ALWAYS_INLINE void JSStringJoiner::appendEmptyString()
+{
+    m_strings.uncheckedAppend({ { }, { } });
+}
+
+ALWAYS_INLINE void JSStringJoiner::append(ExecState& state, JSValue value)
+{
+    // The following code differs from using the result of JSValue::toString in the following ways:
+    // 1) It's inlined more than JSValue::toString is.
+    // 2) It includes conversion to WTF::String in a way that avoids allocating copies of substrings.
+    // 3) It doesn't create a JSString for numbers, true, or false.
+    // 4) It turns undefined and null into the empty string instead of "undefined" and "null".
+    // 5) It uses optimized code paths for all the cases known to be 8-bit and for the empty string.
+
+    if (value.isCell()) {
+        if (value.asCell()->isString()) {
+            append(asString(value)->viewWithUnderlyingString(state));
+            return;
+        }
+        append(value.toString(&state)->viewWithUnderlyingString(state));
         return;
+    }
 
-    m_strings.append(str);
-    if (!str.isNull()) {
-        m_accumulatedStringsLength += str.length();
-        m_is8Bits = m_is8Bits && str.is8Bit();
+    if (value.isInt32()) {
+        append8Bit(state.vm().numericStrings.add(value.asInt32()));
+        return;
+    }
+    if (value.isDouble()) {
+        append8Bit(state.vm().numericStrings.add(value.asDouble()));
+        return;
+    }
+    if (value.isTrue()) {
+        append8Bit(state.vm().propertyNames->trueKeyword.string());
+        return;
+    }
+    if (value.isFalse()) {
+        append8Bit(state.vm().propertyNames->falseKeyword.string());
+        return;
     }
+    ASSERT(value.isUndefinedOrNull());
+    appendEmptyString();
 }
 
 }
index 7e43ada9b568ff36032029fe850557a1c3d4f7b2..c08ff59487bf8de727caae6a5839a24c88fe45ff 100644 (file)
@@ -29,8 +29,8 @@
 #include "config.h"
 #include "JSSymbolTableObject.h"
 
-#include "JSActivation.h"
 #include "JSGlobalObject.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "JSCInlines.h"
 #include "PropertyNameArray.h"
@@ -41,9 +41,6 @@ void JSSymbolTableObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_symbolTable);
 }
@@ -64,10 +61,11 @@ void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecStat
         ConcurrentJITLocker locker(thisObject->symbolTable()->m_lock);
         SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker);
         for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
-            if (it->key->isEmptyUnique())
-                continue;
-            if (!(it->value.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
-                propertyNames.add(Identifier(exec, it->key.get()));
+            if (!(it->value.getAttributes() & DontEnum) || mode.includeDontEnumProperties()) {
+                if (it->key->isSymbol() && !mode.includeSymbolProperties())
+                    continue;
+                propertyNames.add(Identifier::fromUid(exec, it->key.get()));
+            }
         }
     }
     
index ecdd8a0a705ad87ff8653182a861ed0964f8cd5b..9fe8384c6d54ab20fd734340e0470faaacb8c658 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JSScope.h"
 #include "PropertyDescriptor.h"
 #include "SymbolTable.h"
-#include "VariableWatchpointSetInlines.h"
+#include "VariableWriteFireDetail.h"
 
 namespace JSC {
 
+class JSSymbolTableObject;
+
 class JSSymbolTableObject : public JSScope {
 public:
     typedef JSScope Base;
+    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord | OverridesGetPropertyNames;
     
     SymbolTable* symbolTable() const { return m_symbolTable.get(); }
     
     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     
+    static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
+    
 protected:
-    static const unsigned StructureFlags = IsEnvironmentRecord | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
+    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
+        : Base(vm, structure, scope)
+    {
+    }
     
-    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable = 0)
+    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable)
         : Base(vm, structure, scope)
     {
-        if (symbolTable)
-            m_symbolTable.set(vm, this, symbolTable);
+        ASSERT(symbolTable);
+        setSymbolTable(vm, symbolTable);
     }
-
-    void finishCreation(VM& vm)
+    
+    void setSymbolTable(VM& vm, SymbolTable* symbolTable)
     {
-        Base::finishCreation(vm);
-        if (!m_symbolTable)
-            m_symbolTable.set(vm, this, SymbolTable::create(vm));
+        ASSERT(!m_symbolTable);
+        symbolTable->singletonScope()->notifyWrite(vm, this, "Allocated a scope");
+        m_symbolTable.set(vm, this, symbolTable);
     }
-
+    
     static void visitChildren(JSCell*, SlotVisitor&);
-
+    
+private:
     WriteBarrier<SymbolTable> m_symbolTable;
 };
 
@@ -78,7 +87,7 @@ inline bool symbolTableGet(
         return false;
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
-    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
     return true;
 }
 
@@ -94,7 +103,7 @@ inline bool symbolTableGet(
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
     descriptor.setDescriptor(
-        object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
+        object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
     return true;
 }
 
@@ -110,7 +119,7 @@ inline bool symbolTableGet(
         return false;
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
-    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
     slotIsWriteable = !entry.isReadOnly();
     return true;
 }
@@ -124,6 +133,7 @@ inline bool symbolTablePut(
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
     
     WriteBarrierBase<Unknown>* reg;
+    WatchpointSet* set;
     {
         SymbolTable& symbolTable = *object->symbolTable();
         // FIXME: This is very suspicious. We shouldn't need a GC-safe lock here.
@@ -140,17 +150,15 @@ inline bool symbolTablePut(
                 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
             return true;
         }
-        if (VariableWatchpointSet* set = iter->value.watchpointSet()) {
-            // FIXME: It's strange that we're doing this while holding the symbol table's lock.
-            // https://bugs.webkit.org/show_bug.cgi?id=134601
-            set->notifyWrite(vm, value);
-        }
-        reg = &object->registerAt(fastEntry.getIndex());
+        set = iter->value.watchpointSet();
+        reg = &object->variableAt(fastEntry.scopeOffset());
     }
     // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
     // the right for barriers to be able to trigger GC. And I don't want to hold VM
     // locks while GC'ing.
     reg->set(vm, object, value);
+    if (set)
+        VariableWriteFireDetail::touch(set, object, propertyName);
     return true;
 }
 
@@ -162,6 +170,7 @@ inline bool symbolTablePutWithAttributes(
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
 
     WriteBarrierBase<Unknown>* reg;
+    WatchpointSet* set;
     {
         SymbolTable& symbolTable = *object->symbolTable();
         ConcurrentJITLocker locker(symbolTable.m_lock);
@@ -170,12 +179,13 @@ inline bool symbolTablePutWithAttributes(
             return false;
         SymbolTableEntry& entry = iter->value;
         ASSERT(!entry.isNull());
-        if (VariableWatchpointSet* set = entry.watchpointSet())
-            set->notifyWrite(vm, value);
+        set = entry.watchpointSet();
         entry.setAttributes(attributes);
-        reg = &object->registerAt(entry.getIndex());
+        reg = &object->variableAt(entry.scopeOffset());
     }
     reg->set(vm, object, value);
+    if (set)
+        VariableWriteFireDetail::touch(set, object, propertyName);
     return true;
 }
 
diff --git a/runtime/JSTemplateRegistryKey.cpp b/runtime/JSTemplateRegistryKey.cpp
new file mode 100644 (file)
index 0000000..e3f3ae9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSTemplateRegistryKey.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "StructureInlines.h"
+#include "VM.h"
+
+namespace JSC {
+
+const ClassInfo JSTemplateRegistryKey::s_info = { "TemplateRegistryKey", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSTemplateRegistryKey) };
+
+
+JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, const TemplateRegistryKey& templateRegistryKey)
+    : Base(vm, vm.templateRegistryKeyStructure.get())
+    , m_templateRegistryKey(templateRegistryKey)
+{
+}
+
+JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM& vm, const TemplateRegistryKey& templateRegistryKey)
+{
+    JSTemplateRegistryKey* result = new (NotNull, allocateCell<JSTemplateRegistryKey>(vm.heap)) JSTemplateRegistryKey(vm, templateRegistryKey);
+    result->finishCreation(vm);
+    return result;
+}
+
+void JSTemplateRegistryKey::destroy(JSCell* cell)
+{
+    static_cast<JSTemplateRegistryKey*>(cell)->JSTemplateRegistryKey::~JSTemplateRegistryKey();
+}
+
+} // namespace JSC
diff --git a/runtime/JSTemplateRegistryKey.h b/runtime/JSTemplateRegistryKey.h
new file mode 100644 (file)
index 0000000..fc6e392
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSTemplateRegistryKey_h
+#define JSTemplateRegistryKey_h
+
+#include "JSDestructibleObject.h"
+#include "Structure.h"
+#include "TemplateRegistryKey.h"
+
+namespace JSC {
+
+class JSTemplateRegistryKey final : public JSDestructibleObject {
+public:
+    typedef JSDestructibleObject Base;
+
+    static JSTemplateRegistryKey* create(VM&, const TemplateRegistryKey&);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    DECLARE_INFO;
+
+    const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey; }
+
+protected:
+    static void destroy(JSCell*);
+
+private:
+    JSTemplateRegistryKey(VM&, const TemplateRegistryKey&);
+
+    TemplateRegistryKey m_templateRegistryKey;
+};
+
+} // namespace JSC
+
+#endif // JSTemplateRegistryKey_h
index fb855e9ab118eaf28192f6b6b0eeaf6d7f91e4bc..40326ce0f329fa7c7bbc99f446428fe96c9124b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -29,11 +29,12 @@ enum JSType : uint8_t {
     BooleanType,
     NumberType,
     NullType,
+
+    // The CellType value must come before any JSType that is a JSCell.
+    CellType,
     StringType,
-    LeafType,
+    SymbolType,
 
-    // The CompoundType value must come before any JSType that may have children.
-    CompoundType,
     GetterSetterType,
     CustomGetterSetterType,
     APIValueWrapperType,
@@ -50,14 +51,15 @@ enum JSType : uint8_t {
     // The ObjectType value must come before any JSType that is a subclass of JSObject.
     ObjectType,
     FinalObjectType,
+    JSCalleeType,
     JSFunctionType,
-    NameInstanceType,
     NumberObjectType,
     ErrorInstanceType,
     PureForwardingProxyType,
     ImpureProxyType,
     WithScopeType,
-    ArgumentsType,
+    DirectArgumentsType,
+    ScopedArgumentsType,
 
     Int8ArrayType,
     Int16ArrayType,
index 4cf03f7d7f6b9b5550179f4cdcc7e0c44ac5d36a..27863abf2e98f8252039c56697463904e4c4b6bc 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: c++; c-basic-offset: 4 -*-
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-    class LLIntOffsetsExtractor;
-
-    static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
-    static const unsigned ImplementsHasInstance = 1 << 1;
-    static const unsigned OverridesHasInstance = 1 << 2;
-    static const unsigned ImplementsDefaultHasInstance = 1 << 3;
-    static const unsigned IsEnvironmentRecord = 1 << 4;
-    static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
-    static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
-    static const unsigned OverridesVisitChildren = 1 << 7;
-
-    static const unsigned OverridesGetPropertyNames = 1 << 8;
-    static const unsigned ProhibitsPropertyCaching = 1 << 9;
-    static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
-    static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
-    static const unsigned StructureIsImmortal = 1 << 12;
-
-    class TypeInfo {
-    public:
-        typedef uint8_t InlineTypeFlags;
-        typedef uint8_t OutOfLineTypeFlags;
-
-        TypeInfo(JSType type, unsigned flags = 0)
-            : TypeInfo(type, flags & 0xff, flags >> 8)
-        {
-        }
-        
-        TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
-            : m_type(type)
-            , m_flags(inlineTypeFlags)
-            , m_flags2(outOfLineTypeFlags)
-        {
-            ASSERT(m_type >= CompoundType || !(isSetOnFlags1(OverridesVisitChildren)));
-            // No object that doesn't ImplementsHasInstance should override it!
-            ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance)) != OverridesHasInstance);
-            // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
-            if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
-                m_flags |= ImplementsDefaultHasInstance;
-        }
-
-        JSType type() const { return static_cast<JSType>(m_type); }
-        bool isObject() const { return isObject(type()); }
-        static bool isObject(JSType type) { return type >= ObjectType; }
-        bool isFinalObject() const { return type() == FinalObjectType; }
-        bool isNumberObject() const { return type() == NumberObjectType; }
-        bool isName() const { return type() == NameInstanceType; }
-
-        unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
-        bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
-        bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
-        bool isEnvironmentRecord() const { return isSetOnFlags1(IsEnvironmentRecord); }
-        bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
-        bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
-        bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
-        static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
-        bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
-        bool overridesVisitChildren() const { return isSetOnFlags1(OverridesVisitChildren); }
-        bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
-        bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
-        bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
-        bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
-        bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
-
-        static ptrdiff_t flagsOffset()
-        {
-            return OBJECT_OFFSETOF(TypeInfo, m_flags);
-        }
-
-        static ptrdiff_t typeOffset()
-        {
-            return OBJECT_OFFSETOF(TypeInfo, m_type);
-        }
-
-        InlineTypeFlags inlineTypeFlags() const { return m_flags; }
-        OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
-
-    private:
-        friend class LLIntOffsetsExtractor;
-        
-        bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
-        bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
-
-        unsigned char m_type;
-        unsigned char m_flags;
-        unsigned char m_flags2;
-    };
+class LLIntOffsetsExtractor;
+
+static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
+static const unsigned ImplementsHasInstance = 1 << 1;
+static const unsigned OverridesHasInstance = 1 << 2;
+static const unsigned ImplementsDefaultHasInstance = 1 << 3;
+static const unsigned TypeOfShouldCallGetCallData = 1 << 4; // Need this flag if you override getCallData() and you want typeof to use this to determine if it should say "function". Currently we always set this flag when we override getCallData().
+static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
+static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
+static const unsigned StructureIsImmortal = 1 << 7;
+
+static const unsigned OverridesGetPropertyNames = 1 << 8;
+static const unsigned ProhibitsPropertyCaching = 1 << 9;
+static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
+static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
+static const unsigned IsEnvironmentRecord = 1 << 12;
+
+class TypeInfo {
+public:
+    typedef uint8_t InlineTypeFlags;
+    typedef uint8_t OutOfLineTypeFlags;
+
+    TypeInfo(JSType type, unsigned flags = 0)
+        : TypeInfo(type, flags & 0xff, flags >> 8)
+    {
+    }
+
+    TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
+        : m_type(type)
+        , m_flags(inlineTypeFlags)
+        , m_flags2(outOfLineTypeFlags)
+    {
+        // No object that doesn't ImplementsHasInstance should override it!
+        ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance)) != OverridesHasInstance);
+        // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
+        if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
+            m_flags |= ImplementsDefaultHasInstance;
+    }
+
+    JSType type() const { return static_cast<JSType>(m_type); }
+    bool isObject() const { return isObject(type()); }
+    static bool isObject(JSType type) { return type >= ObjectType; }
+    bool isFinalObject() const { return type() == FinalObjectType; }
+    bool isNumberObject() const { return type() == NumberObjectType; }
+
+    unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
+    bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
+    bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
+    bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
+    bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
+    bool typeOfShouldCallGetCallData() const { return isSetOnFlags1(TypeOfShouldCallGetCallData); }
+    bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
+    static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
+    bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
+    bool structureIsImmortal() const { return isSetOnFlags1(StructureIsImmortal); }
+    bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
+    bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
+    bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
+    bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
+    bool isEnvironmentRecord() const { return isSetOnFlags2(IsEnvironmentRecord); }
+
+    static ptrdiff_t flagsOffset()
+    {
+        return OBJECT_OFFSETOF(TypeInfo, m_flags);
+    }
+
+    static ptrdiff_t typeOffset()
+    {
+        return OBJECT_OFFSETOF(TypeInfo, m_type);
+    }
+
+    InlineTypeFlags inlineTypeFlags() const { return m_flags; }
+    OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
+    bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
+
+    unsigned char m_type;
+    unsigned char m_flags;
+    unsigned char m_flags2;
+};
 
 }
 
index 7c4955df515eec29a1b8ff3d62dec5111c9334a3..f42f3179508a78acfdff979b98b6cafa31f3d223 100644 (file)
@@ -33,7 +33,7 @@
 namespace JSC {
 
 #define MAKE_S_INFO(type) \
-    template<> const ClassInfo JS##type##Constructor::s_info = {"Function", &JS##type##Constructor::Base::s_info, 0, 0, CREATE_METHOD_TABLE(JS##type##Constructor)}
+    template<> const ClassInfo JS##type##Constructor::s_info = {"Function", &JS##type##Constructor::Base::s_info, 0, CREATE_METHOD_TABLE(JS##type##Constructor)}
 
 MAKE_S_INFO(Int8Array);
 MAKE_S_INFO(Int16Array);
index 78c6baf69b7496d8a912490572391d4d4cd8f98a..c01d8f88918b98b7eb473d7cf00d032fbb75e352 100644 (file)
@@ -32,7 +32,7 @@
 namespace JSC {
 
 #define MAKE_S_INFO(type) \
-    template<> const ClassInfo JS##type##Prototype::s_info = {#type "Prototype", &JS##type##Prototype::Base::s_info, 0, 0, CREATE_METHOD_TABLE(JS##type##Prototype)}
+    template<> const ClassInfo JS##type##Prototype::s_info = {#type "Prototype", &JS##type##Prototype::Base::s_info, 0, CREATE_METHOD_TABLE(JS##type##Prototype)}
 
 MAKE_S_INFO(Int8Array);
 MAKE_S_INFO(Int16Array);
index 4964907171469c7c0a25a16b27d3572e8c86d87a..2c5c4747bb1be4aeb4fee220a6df9a23aafe4c00 100644 (file)
@@ -35,7 +35,7 @@ namespace JSC {
 
 #define MAKE_S_INFO(type) \
     template<> const ClassInfo JS##type##Array::s_info = { \
-        #type "Array", &JS##type##Array::Base::s_info, 0, 0, \
+        #type "Array", &JS##type##Array::Base::s_info, 0, \
         CREATE_METHOD_TABLE(JS##type##Array) \
     }; \
     const ClassInfo* get##type##ArrayClassInfo() { return &JS##type##Array::s_info; }
diff --git a/runtime/JSVariableObject.cpp b/runtime/JSVariableObject.cpp
deleted file mode 100644 (file)
index d19c658..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSVariableObject.h"
-
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo JSVariableObject::s_info = { "VariableObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSVariableObject) };
-
-} // namespace JSC
diff --git a/runtime/JSVariableObject.h b/runtime/JSVariableObject.h
deleted file mode 100644 (file)
index 5f98dca..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSVariableObject_h
-#define JSVariableObject_h
-
-#include "JSObject.h"
-#include "JSSymbolTableObject.h"
-#include "Register.h"
-#include "SymbolTable.h"
-
-namespace JSC {
-
-class LLIntOffsetsExtractor;
-class Register;
-
-class JSVariableObject : public JSSymbolTableObject {
-    friend class JIT;
-    friend class LLIntOffsetsExtractor;
-
-public:
-    typedef JSSymbolTableObject Base;
-
-    WriteBarrierBase<Unknown>* registers() { return m_registers; }
-    WriteBarrierBase<Unknown>& registerAt(int index) const { return m_registers[index]; }
-
-    WriteBarrierBase<Unknown>* const * addressOfRegisters() const { return &m_registers; }
-    static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSVariableObject, m_registers); }
-
-    DECLARE_INFO;
-
-protected:
-    static const unsigned StructureFlags = Base::StructureFlags;
-
-    JSVariableObject(
-        VM& vm,
-        Structure* structure,
-        Register* registers,
-        JSScope* scope,
-        SymbolTable* symbolTable = 0)
-        : Base(vm, structure, scope, symbolTable)
-        , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
-    {
-    }
-
-    WriteBarrierBase<Unknown>* m_registers; // "r" in the stack.
-};
-
-} // namespace JSC
-
-#endif // JSVariableObject_h
index f54652bf837fa234dcc4f072b7253d9e385cd4af..80b46ce8434818cbaac0c9d1045fc8dd29caef35 100644 (file)
@@ -34,7 +34,7 @@
 
 namespace JSC {
 
-const ClassInfo JSWeakMap::s_info = { "WeakMap", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWeakMap) };
+const ClassInfo JSWeakMap::s_info = { "WeakMap", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWeakMap) };
 
 void JSWeakMap::finishCreation(VM& vm)
 {
index 81b3962ded8c78be288c7f1f8e3d6146d5cea2b3..a3229c26589a0db9b530f660e59562406bf3ab40 100644 (file)
@@ -65,8 +65,6 @@ public:
     void clear(CallFrame*);
 
 private:
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
     JSWeakMap(VM& vm, Structure* structure)
         : Base(vm, structure)
     {
diff --git a/runtime/JSWeakSet.cpp b/runtime/JSWeakSet.cpp
new file mode 100644 (file)
index 0000000..3b80753
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSWeakSet.h"
+
+#include "JSCJSValueInlines.h"
+#include "SlotVisitorInlines.h"
+#include "StructureInlines.h"
+#include "WeakMapData.h"
+#include "WriteBarrierInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSWeakSet::s_info = { "WeakSet", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWeakSet) };
+
+void JSWeakSet::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    m_weakMapData.set(vm, this, WeakMapData::create(vm));
+}
+
+void JSWeakSet::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    Base::visitChildren(cell, visitor);
+    JSWeakSet* thisObj = jsCast<JSWeakSet*>(cell);
+    visitor.append(&thisObj->m_weakMapData);
+}
+
+}
diff --git a/runtime/JSWeakSet.h b/runtime/JSWeakSet.h
new file mode 100644 (file)
index 0000000..da2ecaa
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSWeakSet_h
+#define JSWeakSet_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class WeakMapData;
+
+class JSWeakSet : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static JSWeakSet* create(VM& vm, Structure* structure)
+    {
+        JSWeakSet* instance = new (NotNull, allocateCell<JSWeakSet>(vm.heap)) JSWeakSet(vm, structure);
+        instance->finishCreation(vm);
+        return instance;
+    }
+
+    static JSWeakSet* create(ExecState* exec, Structure* structure)
+    {
+        return create(exec->vm(), structure);
+    }
+
+    WeakMapData* weakMapData() { return m_weakMapData.get(); }
+
+    JSValue get(CallFrame*, JSObject*);
+    bool has(CallFrame*, JSObject*);
+    bool remove(CallFrame*, JSObject*);
+
+    void set(CallFrame*, JSObject*, JSValue);
+    void clear(CallFrame*);
+
+private:
+    JSWeakSet(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    void finishCreation(VM&);
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    WriteBarrier<WeakMapData> m_weakMapData;
+};
+
+}
+
+#endif // !defined(JSWeakSet_h)
index 689f152a8d97c14a8ff5cb0b7128372de0746e8b..1ffe8d1f272c99e66137965a7011d111f16de371 100644 (file)
 
 namespace JSC {
 
-const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWithScope) };
+const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWithScope) };
 
 void JSWithScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSWithScope* thisObject = jsCast<JSWithScope*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_object);
 }
index 9b7e1826d467af221094cef8cd9caa30ce87ae2e..8e5d09fa1dc7963ec8cc1c02fa6d37b462429f71 100644 (file)
@@ -34,13 +34,6 @@ class JSWithScope : public JSScope {
 public:
     typedef JSScope Base;
 
-    static JSWithScope* create(ExecState* exec, JSObject* object)
-    {
-        JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object);
-        withScope->finishCreation(exec->vm());
-        return withScope;
-    }
-
     static JSWithScope* create(ExecState* exec, JSObject* object, JSScope* next)
     {
         JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object, next);
@@ -59,20 +52,7 @@ public:
 
     DECLARE_EXPORT_INFO;
 
-protected:
-    static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
-
 private:
-    JSWithScope(ExecState* exec, JSObject* object)
-        : Base(
-            exec->vm(),
-            exec->lexicalGlobalObject()->withScopeStructure(),
-            exec->scope()
-        )
-        , m_object(exec->vm(), this, object)
-    {
-    }
-
     JSWithScope(ExecState* exec, JSObject* object, JSScope* next)
         : Base(
             exec->vm(),
index 039dd6983117fd65283b34cec18b8e5254c18b72..b6fadadb05d220277d5aa412a5c605cbfad97571 100644 (file)
@@ -32,9 +32,6 @@ void JSWrapperObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSWrapperObject* thisObject = jsCast<JSWrapperObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     JSObject::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_internalValue);
 }
index 349c75e6ad2108c93531a3188cb0f70a68476161..1036add599543b028d3e07feb72b65632bfd7c14 100644 (file)
 
 namespace JSC {
 
-    // This class is used as a base for classes such as String,
-    // Number, Boolean and Date which are wrappers for primitive types.
-    class JSWrapperObject : public JSDestructibleObject {
-    public:
-        typedef JSDestructibleObject Base;
-
-        static size_t allocationSize(size_t inlineCapacity)
-        {
-            ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
-            return sizeof(JSWrapperObject);
-        }
-
-        JSValue internalValue() const;
-        void setInternalValue(VM&, JSValue);
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-        
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-        
-        static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
-        static ptrdiff_t internalValueCellOffset()
-        {
+// This class is used as a base for classes such as String,
+// Number, Boolean and Date which are wrappers for primitive types.
+class JSWrapperObject : public JSDestructibleObject {
+public:
+    typedef JSDestructibleObject Base;
+
+    static size_t allocationSize(size_t inlineCapacity)
+    {
+        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
+        return sizeof(JSWrapperObject);
+    }
+
+    JSValue internalValue() const;
+    void setInternalValue(VM&, JSValue);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    { 
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
+    static ptrdiff_t internalValueCellOffset()
+    {
 #if USE(JSVALUE64)
-            return internalValueOffset();
+        return internalValueOffset();
 #else
-            return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
+        return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
 #endif
-        }
+    }
 
-    protected:
-        explicit JSWrapperObject(VM&, Structure*);
-        static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+protected:
+    explicit JSWrapperObject(VM&, Structure*);
 
-        static void visitChildren(JSCell*, SlotVisitor&);
+    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
-    private:
-        WriteBarrier<Unknown> m_internalValue;
-    };
+private:
+    WriteBarrier<Unknown> m_internalValue;
+};
 
-    inline JSWrapperObject::JSWrapperObject(VM& vm, Structure* structure)
-        : JSDestructibleObject(vm, structure)
-    {
-    }
+inline JSWrapperObject::JSWrapperObject(VM& vm, Structure* structure)
+    : JSDestructibleObject(vm, structure)
+{
+}
 
-    inline JSValue JSWrapperObject::internalValue() const
-    {
-        return m_internalValue.get();
-    }
+inline JSValue JSWrapperObject::internalValue() const
+{
+    return m_internalValue.get();
+}
 
-    inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value)
-    {
-        ASSERT(value);
-        ASSERT(!value.isObject());
-        m_internalValue.set(vm, this, value);
-    }
+inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value)
+{
+    ASSERT(value);
+    ASSERT(!value.isObject());
+    m_internalValue.set(vm, this, value);
+}
 
 } // namespace JSC
 
index 9b01951894eedf90f7fedf3683b0f5009b6a80da..9d9fe2f312f5ecc3fc24771a8801ff2b489527d4 100644 (file)
@@ -57,17 +57,17 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
     do {
         Vector<JSONPPathEntry> path;
         // Unguarded next to start off the lexer
-        Identifier name = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+        Identifier name = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
         JSONPPathEntry entry;
         if (name == m_exec->vm().propertyNames->varKeyword) {
             if (m_lexer.next() != TokIdentifier)
                 return false;
             entry.m_type = JSONPPathEntryTypeDeclare;
-            entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+            entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
             path.append(entry);
         } else {
             entry.m_type = JSONPPathEntryTypeDot;
-            entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+            entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
             path.append(entry);
         }
         if (m_exec->vm().keywords->isKeyword(entry.m_pathEntryName))
@@ -94,7 +94,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
                 entry.m_type = JSONPPathEntryTypeDot;
                 if (m_lexer.next() != TokIdentifier)
                     return false;
-                entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+                entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
                 break;
             }
             case TokLParen: {
@@ -135,17 +135,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const LCh
     if (!length)
         return m_exec->vm().propertyNames->emptyIdentifier;
     if (characters[0] >= MaximumCachableCharacter)
-        return Identifier(&m_exec->vm(), characters, length);
+        return Identifier::fromString(&m_exec->vm(), characters, length);
 
     if (length == 1) {
         if (!m_shortIdentifiers[characters[0]].isNull())
             return m_shortIdentifiers[characters[0]];
-        m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
+        m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length);
         return m_shortIdentifiers[characters[0]];
     }
     if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length))
         return m_recentIdentifiers[characters[0]];
-    m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
+    m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length);
     return m_recentIdentifiers[characters[0]];
 }
 
@@ -155,17 +155,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const UCh
     if (!length)
         return m_exec->vm().propertyNames->emptyIdentifier;
     if (characters[0] >= MaximumCachableCharacter)
-        return Identifier(&m_exec->vm(), characters, length);
+        return Identifier::fromString(&m_exec->vm(), characters, length);
 
     if (length == 1) {
         if (!m_shortIdentifiers[characters[0]].isNull())
             return m_shortIdentifiers[characters[0]];
-        m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
+        m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length);
         return m_shortIdentifiers[characters[0]];
     }
     if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length))
         return m_recentIdentifiers[characters[0]];
-    m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
+    m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length);
     return m_recentIdentifiers[characters[0]];
 }
 
@@ -281,7 +281,7 @@ template <ParserMode mode> TokenType LiteralParser<CharType>::Lexer::lex(Literal
             return lexString<mode, '\''>(token);
         }
     }
-    m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr).impl();
+    m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr);
     return TokError;
 }
 
@@ -406,7 +406,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse
                     } // uNNNN == 5 characters
                     for (int i = 1; i < 5; i++) {
                         if (!isASCIIHexDigit(m_ptr[i])) {
-                            m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()).impl();
+                            m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data());
                             return TokError;
                         }
                     }
@@ -420,7 +420,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse
                         m_ptr++;
                         break;
                     }
-                    m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr).impl();
+                    m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr);
                     return TokError;
             }
         }
@@ -548,6 +548,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
     JSValue lastValue;
     Vector<ParserState, 16, UnsafeVectorOverflow> stateStack;
     Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack;
+    HashSet<JSObject*> visitedUnderscoreProto;
     while (1) {
         switch(state) {
             startParseArray:
@@ -649,11 +650,20 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
             {
                 JSObject* object = asObject(objectStack.last());
                 PropertyName ident = identifierStack.last();
-                unsigned i = ident.asIndex();
-                if (i != PropertyName::NotAnIndex)
-                    object->putDirectIndex(m_exec, i, lastValue);
-                else
-                    object->putDirect(m_exec->vm(), ident, lastValue);
+                if (m_mode != StrictJSON && ident == m_exec->vm().propertyNames->underscoreProto) {
+                    if (!visitedUnderscoreProto.add(object).isNewEntry) {
+                        m_parseErrorMessage = ASCIILiteral("Attempted to redefine __proto__ property");
+                        return JSValue();
+                    }
+                    CodeBlock* codeBlock = m_exec->codeBlock();
+                    PutPropertySlot slot(object, codeBlock ? codeBlock->isStrictMode() : false);
+                    objectStack.last().put(m_exec, ident, lastValue, slot);
+                } else {
+                    if (Optional<uint32_t> index = parseIndex(ident))
+                        object->putDirectIndex(m_exec, index.value(), lastValue);
+                    else
+                        object->putDirect(m_exec->vm(), ident, lastValue);                    
+                }
                 identifierStack.removeLast();
                 if (m_lexer.currentToken().type == TokComma)
                     goto doParseObjectStartExpression;
@@ -711,9 +721,9 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
                     case TokIdentifier: {
                         const LiteralParserToken<CharType>& token = m_lexer.currentToken();
                         if (token.stringIs8Bit)
-                            m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()).impl();
+                            m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data());
                         else
-                            m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()).impl();
+                            m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data());
                         return JSValue();
                     }
                     case TokColon:
index f05f032043d34562aa644bf894ff9d0d368d2954..fcb79fa401b063d431951827529a2157c8819bc6 100644 (file)
@@ -98,9 +98,9 @@ public:
     String getErrorMessage()
     { 
         if (!m_lexer.getErrorMessage().isEmpty())
-            return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl();
+            return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data());
         if (!m_parseErrorMessage.isEmpty())
-            return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl();
+            return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data());
         return ASCIILiteral("JSON Parse error: Unable to parse JSON string");
     }
     
index 4828bcd6b9b35a770259a4e7c155fcd52d001c44..950f135a2a6fb11d817070d2a3940ea51092796b 100644 (file)
 #include "Lookup.h"
 
 #include "Executable.h"
+#include "GetterSetter.h"
 #include "JSFunction.h"
 #include "JSCInlines.h"
 
 namespace JSC {
 
-void HashTable::createTable(VM&) const
+void HashTable::createTable() const
 {
     ASSERT(!keys);
     keys = static_cast<const char**>(fastMalloc(sizeof(char*) * numberOfValues));
@@ -47,12 +48,26 @@ void HashTable::deleteTable() const
     }
 }
 
+void reifyStaticAccessor(VM& vm, const HashTableValue& value, JSObject& thisObj, PropertyName propertyName)
+{
+    JSGlobalObject* globalObject = thisObj.globalObject();
+    GetterSetter* accessor = GetterSetter::create(vm, globalObject);
+    if (value.accessorGetter()) {
+        RefPtr<StringImpl> getterName = WTF::tryMakeString(ASCIILiteral("get "), String(*propertyName.publicName()));
+        if (!getterName)
+            return;
+        accessor->setGetter(vm, globalObject, JSFunction::create(vm, globalObject, 0, *getterName, value.accessorGetter()));
+    }
+    thisObj.putDirectNonIndexAccessor(vm, propertyName, accessor, value.attributes());
+}
+
 bool setUpStaticFunctionSlot(ExecState* exec, const HashTableValue* entry, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
 {
     ASSERT(thisObj->globalObject());
-    ASSERT(entry->attributes() & BuiltinOrFunction);
+    ASSERT(entry->attributes() & BuiltinOrFunctionOrAccessor);
     VM& vm = exec->vm();
     unsigned attributes;
+    bool isAccessor = entry->attributes() & Accessor;
     PropertyOffset offset = thisObj->getDirectOffset(vm, propertyName, attributes);
 
     if (!isValidOffset(offset)) {
@@ -60,19 +75,26 @@ bool setUpStaticFunctionSlot(ExecState* exec, const HashTableValue* entry, JSObj
         // all static functions at that time - after this we shouldn't be re-adding anything.
         if (thisObj->staticFunctionsReified())
             return false;
-    
+
         if (entry->attributes() & Builtin)
             thisObj->putDirectBuiltinFunction(vm, thisObj->globalObject(), propertyName, entry->builtinGenerator()(vm), entry->attributes());
-        else {
+        else if (entry->attributes() & Function) {
             thisObj->putDirectNativeFunction(
                 vm, thisObj->globalObject(), propertyName, entry->functionLength(),
                 entry->function(), entry->intrinsic(), entry->attributes());
+        } else {
+            ASSERT(isAccessor);
+            reifyStaticAccessor(vm, *entry, *thisObj, propertyName);
         }
+
         offset = thisObj->getDirectOffset(vm, propertyName, attributes);
         ASSERT(isValidOffset(offset));
     }
 
-    slot.setValue(thisObj, attributes, thisObj->getDirect(offset), offset);
+    if (isAccessor)
+        slot.setCacheableGetterSlot(thisObj, attributes, jsCast<GetterSetter*>(thisObj->getDirect(offset)), offset);
+    else
+        slot.setValue(thisObj, attributes, thisObj->getDirect(offset), offset);
     return true;
 }
 
index 909734b4448f7e749392888ddf741303d53308c6..4c86ccdcc1dbba40a60934871d2127dca1a0ad94 100644 (file)
 #include <wtf/Assertions.h>
 
 namespace JSC {
-    struct CompactHashIndex {
-        const int16_t value;
-        const int16_t next;
-    };
 
-    // FIXME: There is no reason this get function can't be simpler.
-    // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
-    typedef PropertySlot::GetValueFunc GetFunction;
-    typedef PutPropertySlot::PutValueFunc PutFunction;
-    typedef FunctionExecutable* (*BuiltinGenerator)(VM&);
+struct CompactHashIndex {
+    const int16_t value;
+    const int16_t next;
+};
 
-    // Hash table generated by the create_hash_table script.
-    struct HashTableValue {
-        const char* m_key; // property name
-        unsigned m_attributes; // JSObject attributes
-        Intrinsic m_intrinsic;
-        intptr_t m_value1;
-        intptr_t m_value2;
+// FIXME: There is no reason this get function can't be simpler.
+// ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
+typedef PropertySlot::GetValueFunc GetFunction;
+typedef PutPropertySlot::PutValueFunc PutFunction;
+typedef FunctionExecutable* (*BuiltinGenerator)(VM&);
 
-        unsigned attributes() const { return m_attributes; }
+// Hash table generated by the create_hash_table script.
+struct HashTableValue {
+    const char* m_key; // property name
+    unsigned m_attributes; // JSObject attributes
+    Intrinsic m_intrinsic;
+    intptr_t m_value1;
+    intptr_t m_value2;
 
-        Intrinsic intrinsic() const { ASSERT(m_attributes & Function); return m_intrinsic; }
-        BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return reinterpret_cast<BuiltinGenerator>(m_value1); }
-        NativeFunction function() const { ASSERT(m_attributes & Function); return reinterpret_cast<NativeFunction>(m_value1); }
-        unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_value2); }
+    unsigned attributes() const { return m_attributes; }
 
-        GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<GetFunction>(m_value1); }
-        PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<PutFunction>(m_value2); }
+    Intrinsic intrinsic() const { ASSERT(m_attributes & Function); return m_intrinsic; }
+    BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return reinterpret_cast<BuiltinGenerator>(m_value1); }
+    NativeFunction function() const { ASSERT(m_attributes & Function); return reinterpret_cast<NativeFunction>(m_value1); }
+    unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_value2); }
 
-        intptr_t constantInteger() const { ASSERT(m_attributes & ConstantInteger); return m_value1; }
+    GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrAccessorOrConstant)); return reinterpret_cast<GetFunction>(m_value1); }
+    PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrAccessorOrConstant)); return reinterpret_cast<PutFunction>(m_value2); }
 
-        intptr_t lexerValue() const { ASSERT(!m_attributes); return m_value1; }
-    };
+    NativeFunction accessorGetter() const { ASSERT(m_attributes & Accessor); return reinterpret_cast<NativeFunction>(m_value1); }
+    NativeFunction accessorSetter() const { ASSERT(m_attributes & Accessor); return reinterpret_cast<NativeFunction>(m_value2); }
 
-    struct HashTable {
-        mutable int numberOfValues;
-        int indexMask;
-        bool hasSetterOrReadonlyProperties;
+    intptr_t constantInteger() const { ASSERT(m_attributes & ConstantInteger); return m_value1; }
 
-        const HashTableValue* values; // Fixed values generated by script.
-        mutable const char** keys; // Table allocated at runtime.
-        const CompactHashIndex* index;
+    intptr_t lexerValue() const { ASSERT(!m_attributes); return m_value1; }
+};
 
-        ALWAYS_INLINE HashTable copy() const
-        {
-            // Don't copy dynamic table since it's thread specific.
-            HashTable result = { numberOfValues, indexMask, hasSetterOrReadonlyProperties, values, 0, index };
-            return result;
-        }
+struct HashTable {
+    mutable int numberOfValues;
+    int indexMask;
+    bool hasSetterOrReadonlyProperties;
+
+    const HashTableValue* values; // Fixed values generated by script.
+    mutable const char** keys; // Table allocated at runtime.
+    const CompactHashIndex* index;
+
+    ALWAYS_INLINE HashTable copy() const
+    {
+        // Don't copy dynamic table since it's thread specific.
+        HashTable result = { numberOfValues, indexMask, hasSetterOrReadonlyProperties, values, 0, index };
+        return result;
+    }
+
+    ALWAYS_INLINE void initializeIfNeeded() const
+    {
+        if (!keys)
+            createTable();
+    }
+
+    JS_EXPORT_PRIVATE void deleteTable() const;
+
+    // Find an entry in the table, and return the entry.
+    ALWAYS_INLINE const HashTableValue* entry(PropertyName propertyName) const
+    {
+        initializeIfNeeded();
+
+        if (propertyName.isSymbol())
+            return nullptr;
 
-        ALWAYS_INLINE void initializeIfNeeded(VM& vm) const
+        auto uid = propertyName.uid();
+        if (!uid)
+            return nullptr;
+
+        ASSERT(keys);
+
+        int indexEntry = IdentifierRepHash::hash(uid) & indexMask;
+        int valueIndex = index[indexEntry].value;
+        if (valueIndex == -1)
+            return nullptr;
+
+        while (true) {
+            if (WTF::equal(uid, keys[valueIndex]))
+                return &values[valueIndex];
+
+            indexEntry = index[indexEntry].next;
+            if (indexEntry == -1)
+                return nullptr;
+            valueIndex = index[indexEntry].value;
+            ASSERT(valueIndex != -1);
+        };
+    }
+
+    class ConstIterator {
+    public:
+        ConstIterator(const HashTable* table, int position)
+            : m_table(table)
+            , m_position(position)
         {
-            if (!keys)
-                createTable(vm);
+            skipInvalidKeys();
         }
 
-        ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const
+        const HashTableValue* value()
         {
-            if (!keys)
-                createTable(exec->vm());
+            return &m_table->values[m_position];
         }
 
-        JS_EXPORT_PRIVATE void deleteTable() const;
-
-        // Find an entry in the table, and return the entry.
-        ALWAYS_INLINE const HashTableValue* entry(VM& vm, PropertyName identifier) const
+        const char* key()
         {
-            initializeIfNeeded(vm);
-            return entry(identifier);
+            return m_table->keys[m_position];
         }
 
-        ALWAYS_INLINE const HashTableValue* entry(ExecState* exec, PropertyName identifier) const
+        const HashTableValue* operator->()
         {
-            initializeIfNeeded(exec);
-            return entry(identifier);
+            return value();
         }
 
-        class ConstIterator {
-        public:
-            ConstIterator(const HashTable* table, int position)
-                : m_table(table)
-                , m_position(position)
-            {
-                skipInvalidKeys();
-            }
-
-            const HashTableValue* value()
-            {
-                return &m_table->values[m_position];
-            }
-
-            const char* key()
-            {
-                return m_table->keys[m_position];
-            }
-
-            const HashTableValue* operator->()
-            {
-                return value();
-            }
-
-            bool operator!=(const ConstIterator& other)
-            {
-                ASSERT(m_table == other.m_table);
-                return m_position != other.m_position;
-            }
-            
-            ConstIterator& operator++()
-            {
-                ASSERT(m_position < m_table->numberOfValues);
-                ++m_position;
-                skipInvalidKeys();
-                return *this;
-            }
-
-        private:
-            void skipInvalidKeys()
-            {
-                ASSERT(m_position <= m_table->numberOfValues);
-                while (m_position < m_table->numberOfValues && !m_table->keys[m_position])
-                    ++m_position;
-                ASSERT(m_position <= m_table->numberOfValues);
-            }
-            
-            const HashTable* m_table;
-            int m_position;
-        };
-
-        ConstIterator begin(VM& vm) const
+        bool operator!=(const ConstIterator& other)
         {
-            initializeIfNeeded(vm);
-            return ConstIterator(this, 0);
+            ASSERT(m_table == other.m_table);
+            return m_position != other.m_position;
         }
-        ConstIterator end(VM& vm) const
+
+        ConstIterator& operator++()
         {
-            initializeIfNeeded(vm);
-            return ConstIterator(this, numberOfValues);
+            ASSERT(m_position < m_table->numberOfValues);
+            ++m_position;
+            skipInvalidKeys();
+            return *this;
         }
 
     private:
-        ALWAYS_INLINE const HashTableValue* entry(PropertyName propertyName) const
+        void skipInvalidKeys()
         {
-            StringImpl* impl = propertyName.uid();
-            if (!impl)
-                return 0;
-        
-            ASSERT(keys);
-
-            int indexEntry = impl->existingHash() & indexMask;
-            int valueIndex = index[indexEntry].value;
-            if (valueIndex == -1)
-                return 0;
-
-            while (true) {
-                if (WTF::equal(impl, keys[valueIndex]))
-                    return &values[valueIndex];
-
-                indexEntry = index[indexEntry].next;
-                if (indexEntry == -1)
-                    return nullptr;
-                valueIndex = index[indexEntry].value;
-                ASSERT(valueIndex != -1);
-            };
+            ASSERT(m_position <= m_table->numberOfValues);
+            while (m_position < m_table->numberOfValues && !m_table->keys[m_position])
+                ++m_position;
+            ASSERT(m_position <= m_table->numberOfValues);
         }
 
-        // Convert the hash table keys to identifiers.
-        JS_EXPORT_PRIVATE void createTable(VM&) const;
+        const HashTable* m_table;
+        int m_position;
     };
 
-    JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashTableValue*, JSObject* thisObject, PropertyName, PropertySlot&);
-
-    /**
-     * This method does it all (looking in the hashtable, checking for function
-     * overrides, creating the function or retrieving from cache, calling
-     * getValueProperty in case of a non-function property, forwarding to parent if
-     * unknown property).
-     */
-    template <class ThisImp, class ParentImp>
-    inline bool getStaticPropertySlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
+    ConstIterator begin() const
     {
-        const HashTableValue* entry = table.entry(exec, propertyName);
+        initializeIfNeeded();
+        return ConstIterator(this, 0);
+    }
+    ConstIterator end() const
+    {
+        initializeIfNeeded();
+        return ConstIterator(this, numberOfValues);
+    }
 
-        if (!entry) // not found, forward to parent
-            return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
+private:
+    // Convert the hash table keys to identifiers.
+    JS_EXPORT_PRIVATE void createTable() const;
+};
 
-        if (entry->attributes() & BuiltinOrFunction)
-            return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
+JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashTableValue*, JSObject* thisObject, PropertyName, PropertySlot&);
+JS_EXPORT_PRIVATE void reifyStaticAccessor(VM&, const HashTableValue&, JSObject& thisObject, PropertyName);
 
-        if (entry->attributes() & ConstantInteger) {
-            slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
-            return true;
-        }
-    
-        slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
+/**
+ * This method does it all (looking in the hashtable, checking for function
+ * overrides, creating the function or retrieving from cache, calling
+ * getValueProperty in case of a non-function property, forwarding to parent if
+ * unknown property).
+ */
+template <class ThisImp, class ParentImp>
+inline bool getStaticPropertySlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
+{
+    const HashTableValue* entry = table.entry(propertyName);
+
+    if (!entry) // not found, forward to parent
+        return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
+
+    if (entry->attributes() & BuiltinOrFunctionOrAccessor)
+        return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
+
+    if (entry->attributes() & ConstantInteger) {
+        slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
         return true;
     }
 
-    /**
-     * Simplified version of getStaticPropertySlot in case there are only functions.
-     * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
-     * a dummy getValueProperty.
-     */
-    template <class ParentImp>
-    inline bool getStaticFunctionSlot(ExecState* exec, const HashTable& table, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
-    {
-        if (ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot))
-            return true;
+    slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
+    return true;
+}
 
-        const HashTableValue* entry = table.entry(exec, propertyName);
-        if (!entry)
-            return false;
+/**
+ * Simplified version of getStaticPropertySlot in case there are only functions.
+ * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
+ * a dummy getValueProperty.
+ */
+template <class ParentImp>
+inline bool getStaticFunctionSlot(ExecState* exec, const HashTable& table, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
+{
+    if (ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot))
+        return true;
 
-        return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
-    }
+    const HashTableValue* entry = table.entry(propertyName);
+    if (!entry)
+        return false;
 
-    /**
-     * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
-     * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
-     */
-    template <class ThisImp, class ParentImp>
-    inline bool getStaticValueSlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
-    {
-        const HashTableValue* entry = table.entry(exec, propertyName);
+    return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
+}
 
-        if (!entry) // not found, forward to parent
-            return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
+/**
+ * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
+ * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
+ */
+template <class ThisImp, class ParentImp>
+inline bool getStaticValueSlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
+{
+    const HashTableValue* entry = table.entry(propertyName);
 
-        ASSERT(!(entry->attributes() & BuiltinOrFunction));
+    if (!entry) // not found, forward to parent
+        return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
 
-        if (entry->attributes() & ConstantInteger) {
-            slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
-            return true;
-        }
+    ASSERT(!(entry->attributes() & BuiltinOrFunctionOrAccessor));
 
-        slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
+    if (entry->attributes() & ConstantInteger) {
+        slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
         return true;
     }
 
-    inline void putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-    {
-        // If this is a function put it as an override property.
-        if (entry->attributes() & BuiltinOrFunction) {
-            if (JSObject* thisObject = jsDynamicCast<JSObject*>(slot.thisValue()))
-                thisObject->putDirect(exec->vm(), propertyName, value);
-        } else if (!(entry->attributes() & ReadOnly)) {
-            entry->propertyPutter()(exec, base, JSValue::encode(slot.thisValue()), JSValue::encode(value));
-            slot.setCustomProperty(base, entry->propertyPutter());
-        } else if (slot.isStrictMode())
+    slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
+    return true;
+}
+
+inline void putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+    // If this is a function put it as an override property.
+    if (entry->attributes() & BuiltinOrFunction) {
+        if (JSObject* thisObject = jsDynamicCast<JSObject*>(slot.thisValue()))
+            thisObject->putDirect(exec->vm(), propertyName, value);
+    } else if (entry->attributes() & Accessor) {
+        if (slot.isStrictMode())
             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-    }
-
-    /**
-     * This one is for "put".
-     * It looks up a hash entry for the property to be set.  If an entry
-     * is found it sets the value and returns true, else it returns false.
-     */
-    inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSObject* base, JSValue value, const HashTable& table, PutPropertySlot& slot)
-    {
-        const HashTableValue* entry = table.entry(exec, propertyName);
+    } else if (!(entry->attributes() & ReadOnly)) {
+        entry->propertyPutter()(exec, base, JSValue::encode(slot.thisValue()), JSValue::encode(value));
+        slot.setCustomProperty(base, entry->propertyPutter());
+    } else if (slot.isStrictMode())
+        throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+}
+
+/**
+ * This one is for "put".
+ * It looks up a hash entry for the property to be set.  If an entry
+ * is found it sets the value and returns true, else it returns false.
+ */
+inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSObject* base, JSValue value, const HashTable& table, PutPropertySlot& slot)
+{
+    const HashTableValue* entry = table.entry(propertyName);
+
+    if (!entry)
+        return false;
+
+    putEntry(exec, entry, base, propertyName, value, slot);
+    return true;
+}
+
+template<unsigned numberOfValues>
+inline void reifyStaticProperties(VM& vm, const HashTableValue (&values)[numberOfValues], JSObject& thisObj)
+{
+    BatchedTransitionOptimizer transitionOptimizer(vm, &thisObj);
+    for (auto& value : values) {
+        if (!value.m_key)
+            continue;
+
+        Identifier propertyName = Identifier::fromString(&vm, reinterpret_cast<const LChar*>(value.m_key), strlen(value.m_key));
+        if (value.attributes() & Builtin) {
+            thisObj.putDirectBuiltinFunction(vm, thisObj.globalObject(), propertyName, value.builtinGenerator()(vm), value.attributes());
+            continue;
+        }
 
-        if (!entry)
-            return false;
+        if (value.attributes() & Function) {
+            thisObj.putDirectNativeFunction(vm, thisObj.globalObject(), propertyName, value.functionLength(),
+                value.function(), value.intrinsic(), value.attributes());
+            continue;
+        }
 
-        putEntry(exec, entry, base, propertyName, value, slot);
-        return true;
-    }
+        if (value.attributes() & ConstantInteger) {
+            thisObj.putDirect(vm, propertyName, jsNumber(value.constantInteger()), value.attributes());
+            continue;
+        }
 
-    template<unsigned numberOfValues>
-    inline void reifyStaticProperties(VM& vm, const HashTableValue (&values)[numberOfValues], JSObject& thisObj)
-    {
-        BatchedTransitionOptimizer transitionOptimizer(vm, &thisObj);
-        for (auto& value : values) {
-            if (!value.m_key)
-                continue;                
-        
-            Identifier propertyName(&vm, reinterpret_cast<const LChar*>(value.m_key), strlen(value.m_key));
-            if (value.attributes() & Builtin) {
-                thisObj.putDirectBuiltinFunction(vm, thisObj.globalObject(), propertyName, value.builtinGenerator()(vm), value.attributes());
-                continue;
-            }
-
-            if (value.attributes() & Function) {
-                thisObj.putDirectNativeFunction(vm, thisObj.globalObject(), propertyName, value.functionLength(),
-                    value.function(), value.intrinsic(), value.attributes());
-                continue;
-            }
-
-            if (value.attributes() & ConstantInteger) {
-                thisObj.putDirect(vm, propertyName, jsNumber(value.constantInteger()), value.attributes());
-                continue;
-            }
-
-            if (value.attributes() & Accessor) {
-                RELEASE_ASSERT_NOT_REACHED();
-                continue;
-            }
-
-            CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, value.propertyGetter(), value.propertyPutter());
-            thisObj.putDirectCustomAccessor(vm, propertyName, customGetterSetter, value.attributes());
+        if (value.attributes() & Accessor) {
+            reifyStaticAccessor(vm, value, thisObj, propertyName);
+            continue;
         }
+
+        CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, value.propertyGetter(), value.propertyPutter());
+        thisObj.putDirectCustomAccessor(vm, propertyName, customGetterSetter, value.attributes());
     }
+}
 
 } // namespace JSC
 
index 04f17d985f616a887b9c77b4df0ca86bb2cd26a1..fad52c056048e18b7eec498ff14953fd90fcfedd 100644 (file)
@@ -27,6 +27,7 @@
 #include "MapConstructor.h"
 
 #include "Error.h"
+#include "IteratorOperations.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
@@ -36,7 +37,7 @@
 
 namespace JSC {
 
-const ClassInfo MapConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MapConstructor) };
+const ClassInfo MapConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(MapConstructor) };
 
 void MapConstructor::finishCreation(VM& vm, MapPrototype* mapPrototype)
 {
@@ -45,18 +46,87 @@ void MapConstructor::finishCreation(VM& vm, MapPrototype* mapPrototype)
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum | DontDelete);
 }
 
-static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
+static EncodedJSValue JSC_HOST_CALL callMap(ExecState* exec)
 {
-    // Until we have iterators we throw if we've been given
-    // any arguments that could require us to throw.
-    if (!exec->argument(0).isUndefinedOrNull())
-        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Map constructor does not accept arguments")));
-    if (!exec->argument(1).isUndefined())
-        return throwVMError(exec, createRangeError(exec, WTF::ASCIILiteral("Invalid comparator function")));
+    return JSValue::encode(throwTypeError(exec, ASCIILiteral("Map cannot be called as a function")));
+}
 
+static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
+{
     JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
     Structure* mapStructure = globalObject->mapStructure();
-    return JSValue::encode(JSMap::create(exec, mapStructure));
+    JSMap* map = JSMap::create(exec, mapStructure);
+    JSValue iterable = exec->argument(0);
+    if (iterable.isUndefinedOrNull())
+        return JSValue::encode(map);
+
+    JSValue adderFunction = map->JSObject::get(exec, exec->propertyNames().set);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData adderFunctionCallData;
+    CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
+    if (adderFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData iteratorFunctionCallData;
+    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
+    if (iteratorFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    ArgList iteratorFunctionArguments;
+    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    if (!iterator.isObject())
+        return JSValue::encode(throwTypeError(exec));
+
+    while (true) {
+        JSValue next = iteratorStep(exec, iterator);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (next.isFalse())
+            return JSValue::encode(map);
+
+        JSValue nextItem = iteratorValue(exec, next);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (!nextItem.isObject()) {
+            throwTypeError(exec);
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        JSValue key = nextItem.get(exec, 0);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        JSValue value = nextItem.get(exec, 1);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(key);
+        arguments.append(value);
+        call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, map, arguments);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return JSValue::encode(map);
 }
 
 ConstructType MapConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -67,7 +137,7 @@ ConstructType MapConstructor::getConstructData(JSCell*, ConstructData& construct
 
 CallType MapConstructor::getCallData(JSCell*, CallData& callData)
 {
-    callData.native.function = constructMap;
+    callData.native.function = callMap;
     return CallTypeHost;
 }
 
diff --git a/runtime/MapData.cpp b/runtime/MapData.cpp
deleted file mode 100644 (file)
index f09e03a..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "MapData.h"
-
-#include "CopiedAllocator.h"
-#include "CopyVisitorInlines.h"
-#include "ExceptionHelpers.h"
-#include "JSCJSValueInlines.h"
-#include "SlotVisitorInlines.h"
-
-#include <wtf/CryptographicallyRandomNumber.h>
-#include <wtf/MathExtras.h>
-
-
-namespace JSC {
-
-const ClassInfo MapData::s_info = { "MapData", 0, 0, 0, CREATE_METHOD_TABLE(MapData) };
-
-static const int32_t minimumMapSize = 8;
-
-MapData::MapData(VM& vm)
-    : Base(vm, vm.mapDataStructure.get())
-    , m_capacity(0)
-    , m_size(0)
-    , m_deletedCount(0)
-    , m_iteratorCount(0)
-    , m_entries(0)
-{
-}
-
-MapData::Entry* MapData::find(CallFrame* callFrame, KeyType key)
-{
-    if (key.value.isString()) {
-        auto iter = m_stringKeyedTable.find(asString(key.value)->value(callFrame).impl());
-        if (iter == m_stringKeyedTable.end())
-            return 0;
-        return &m_entries[iter->value];
-    }
-    if (key.value.isCell()) {
-        auto iter = m_cellKeyedTable.find(key.value.asCell());
-        if (iter == m_cellKeyedTable.end())
-            return 0;
-        return &m_entries[iter->value];
-    }
-
-    auto iter = m_valueKeyedTable.find(JSValue::encode(key.value));
-    if (iter == m_valueKeyedTable.end())
-        return 0;
-    return &m_entries[iter->value];
-}
-
-bool MapData::contains(CallFrame* callFrame, KeyType key)
-{
-    return find(callFrame, key);
-}
-
-template <typename Map, typename Key> MapData::Entry* MapData::add(CallFrame* callFrame, Map& map, Key key, KeyType keyValue)
-{
-    typename Map::iterator location = map.find(key);
-    if (location != map.end())
-        return &m_entries[location->value];
-    
-    if (!ensureSpaceForAppend(callFrame))
-        return 0;
-
-    auto result = map.add(key, m_size);
-    RELEASE_ASSERT(result.isNewEntry);
-    Entry* entry = &m_entries[m_size++];
-    new (entry) Entry();
-    entry->key.set(callFrame->vm(), this, keyValue.value);
-    return entry;
-}
-
-void MapData::set(CallFrame* callFrame, KeyType key, JSValue value)
-{
-    Entry* location = add(callFrame, key);
-    if (!location)
-        return;
-    location->value.set(callFrame->vm(), this, value);
-}
-    
-MapData::Entry* MapData::add(CallFrame* callFrame, KeyType key)
-{
-    if (key.value.isString())
-        return add(callFrame, m_stringKeyedTable, asString(key.value)->value(callFrame).impl(), key);
-    if (key.value.isCell())
-        return add(callFrame, m_cellKeyedTable, key.value.asCell(), key);
-    return add(callFrame, m_valueKeyedTable, JSValue::encode(key.value), key);
-}
-
-JSValue MapData::get(CallFrame* callFrame, KeyType key)
-{
-    if (Entry* entry = find(callFrame, key))
-        return entry->value.get();
-    return JSValue();
-}
-
-bool MapData::remove(CallFrame* callFrame, KeyType key)
-{
-    int32_t location;
-    if (key.value.isString()) {
-        auto iter = m_stringKeyedTable.find(asString(key.value)->value(callFrame).impl());
-        if (iter == m_stringKeyedTable.end())
-            return false;
-        location = iter->value;
-        m_stringKeyedTable.remove(iter);
-    } else if (key.value.isCell()) {
-        auto iter = m_cellKeyedTable.find(key.value.asCell());
-        if (iter == m_cellKeyedTable.end())
-            return false;
-        location = iter->value;
-        m_cellKeyedTable.remove(iter);
-    } else {
-        auto iter = m_valueKeyedTable.find(JSValue::encode(key.value));
-        if (iter == m_valueKeyedTable.end())
-            return false;
-        location = iter->value;
-        m_valueKeyedTable.remove(iter);
-    }
-    m_entries[location].key.clear();
-    m_entries[location].value.clear();
-    m_deletedCount++;
-    return true;
-}
-
-void MapData::replaceAndPackBackingStore(Entry* destination, int32_t newCapacity)
-{
-    ASSERT(shouldPack());
-    int32_t newEnd = 0;
-    RELEASE_ASSERT(newCapacity > 0);
-    for (int32_t i = 0; i < m_size; i++) {
-        Entry& entry = m_entries[i];
-        if (!entry.key)
-            continue;
-        ASSERT(newEnd < newCapacity);
-        destination[newEnd] = entry;
-
-        // We overwrite the old entry with a forwarding index for the new entry,
-        // so that we can fix up our hash tables below without doing additional
-        // hash lookups
-        entry.value.setWithoutWriteBarrier(jsNumber(newEnd));
-        newEnd++;
-    }
-
-    // Fixup for the hashmaps
-    for (auto ptr = m_valueKeyedTable.begin(); ptr != m_valueKeyedTable.end(); ++ptr)
-        ptr->value = m_entries[ptr->value].value.get().asInt32();
-    for (auto ptr = m_cellKeyedTable.begin(); ptr != m_cellKeyedTable.end(); ++ptr)
-        ptr->value = m_entries[ptr->value].value.get().asInt32();
-    for (auto ptr = m_stringKeyedTable.begin(); ptr != m_stringKeyedTable.end(); ++ptr)
-        ptr->value = m_entries[ptr->value].value.get().asInt32();
-
-    ASSERT((m_size - newEnd) == m_deletedCount);
-    m_deletedCount = 0;
-
-    m_capacity = newCapacity;
-    m_size = newEnd;
-    m_entries = destination;
-
-}
-
-void MapData::replaceBackingStore(Entry* destination, int32_t newCapacity)
-{
-    ASSERT(!shouldPack());
-    RELEASE_ASSERT(newCapacity > 0);
-    ASSERT(newCapacity >= m_capacity);
-    memcpy(destination, m_entries, sizeof(Entry) * m_size);
-    m_capacity = newCapacity;
-    m_entries = destination;
-}
-
-CheckedBoolean MapData::ensureSpaceForAppend(CallFrame* callFrame)
-{
-    if (m_capacity > m_size)
-        return true;
-
-    size_t requiredSize = std::max(m_capacity + (m_capacity / 2) + 1, minimumMapSize);
-    void* newStorage = 0;
-    DeferGC defer(*callFrame->heap());
-    if (!callFrame->heap()->tryAllocateStorage(this, requiredSize * sizeof(Entry), &newStorage)) {
-        throwOutOfMemoryError(callFrame);
-        return false;
-    }
-    Entry* newEntries = static_cast<Entry*>(newStorage);
-    if (shouldPack())
-        replaceAndPackBackingStore(newEntries, requiredSize);
-    else
-        replaceBackingStore(newEntries, requiredSize);
-    callFrame->heap()->writeBarrier(this);
-    return true;
-}
-
-void MapData::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    Base::visitChildren(cell, visitor);
-    MapData* thisObject = jsCast<MapData*>(cell);
-    Entry* entries = thisObject->m_entries;
-    if (!entries)
-        return;
-    size_t size = thisObject->m_size;
-    if (thisObject->m_deletedCount) {
-        for (size_t i = 0; i < size; i++) {
-            if (!entries[i].key)
-                continue;
-            visitor.append(&entries[i].key);
-            visitor.append(&entries[i].value);
-        }
-    } else
-        visitor.appendValues(&entries[0].key, size * (sizeof(Entry) / sizeof(WriteBarrier<Unknown>)));
-
-    visitor.copyLater(thisObject, MapBackingStoreCopyToken, entries, thisObject->capacityInBytes());
-}
-
-void MapData::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
-{
-    MapData* thisObject = jsCast<MapData*>(cell);
-    if (token == MapBackingStoreCopyToken && visitor.checkIfShouldCopy(thisObject->m_entries)) {
-        Entry* oldEntries = thisObject->m_entries;
-        Entry* newEntries = static_cast<Entry*>(visitor.allocateNewSpace(thisObject->capacityInBytes()));
-        if (thisObject->shouldPack())
-            thisObject->replaceAndPackBackingStore(newEntries, thisObject->m_capacity);
-        else
-            thisObject->replaceBackingStore(newEntries, thisObject->m_capacity);
-        visitor.didCopy(oldEntries, thisObject->capacityInBytes());
-    }
-    Base::copyBackingStore(cell, visitor, token);
-}
-
-void MapData::destroy(JSCell* cell)
-{
-    static_cast<MapData*>(cell)->~MapData();
-}
-
-}
index 9d117db698daa9b1abf4843edfbc6d995909f56e..3b5863efcdf2776eb1b845902b38708943668b7c 100644 (file)
 #define MapData_h
 
 #include "JSCell.h"
-#include "Structure.h"
+#include "WeakGCMapInlines.h"
 #include <wtf/HashFunctions.h>
 #include <wtf/HashMap.h>
 #include <wtf/MathExtras.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
 
 namespace JSC {
 
-class MapData : public JSCell {
+class ExecState;
+class VM;
+
+template<typename Entry, typename JSIterator>
+class MapDataImpl {
 public:
-    typedef JSCell Base;
+    enum : int32_t {
+        minimumMapSize = 8
+    };
+
+    class IteratorData {
+    public:
+        friend class MapDataImpl;
+
+        IteratorData(const MapDataImpl*);
+        bool next(WTF::KeyValuePair<JSValue, JSValue>&);
+
+        // This function is called while packing a map's backing store. The
+        // passed-in index is the new index the entry would have after packing.
+        void didRemoveEntry(int32_t packedIndex)
+        {
+            if (isFinished())
+                return;
 
-    struct const_iterator {
-        const_iterator(const MapData*);
-        ~const_iterator();
-        const WTF::KeyValuePair<JSValue, JSValue> operator*() const;
-        JSValue key() const { RELEASE_ASSERT(!atEnd()); return m_mapData->m_entries[m_index].key.get(); }
-        JSValue value() const { RELEASE_ASSERT(!atEnd()); return m_mapData->m_entries[m_index].value.get(); }
-        void operator++() { ASSERT(!atEnd()); internalIncrement(); }
-        static const_iterator end(const MapData*);
-        bool operator!=(const const_iterator& other);
-        bool operator==(const const_iterator& other);
+            if (m_index <= packedIndex)
+                return;
 
-        bool ensureSlot();
+            --m_index;
+        }
+
+        void didRemoveAllEntries()
+        {
+            if (isFinished())
+                return;
+            m_index = 0;
+        }
+
+        void finish()
+        {
+            m_index = -1;
+        }
 
     private:
-        // This is a bit gnarly. We use an index of -1 to indicate the
-        // "end()" iterator. By casting to unsigned we can immediately
-        // test if both iterators are at the end of their iteration.
-        // We need this in order to keep the common case (eg. iter != end())
-        // fast.
-        bool atEnd() const { return static_cast<size_t>(m_index) >= static_cast<size_t>(m_mapData->m_size); }
-        void internalIncrement();
-        const MapData* m_mapData;
-        int32_t m_index;
+        bool ensureSlot() const;
+        bool isFinished() const { return m_index == -1; }
+        int32_t refreshCursor() const;
+
+        const MapDataImpl* m_mapData;
+        mutable int32_t m_index;
     };
 
     struct KeyType {
@@ -69,63 +94,37 @@ public:
         JSValue value;
     };
 
-    static MapData* create(VM& vm)
-    {
-        MapData* mapData = new (NotNull, allocateCell<MapData>(vm.heap)) MapData(vm);
-        mapData->finishCreation(vm);
-        return mapData;
-    }
+    MapDataImpl(VM&);
 
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
-    }
-
-    static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
+    void set(ExecState*, JSCell* owner, KeyType, JSValue);
+    JSValue get(ExecState*, KeyType);
+    bool remove(ExecState*, KeyType);
+    bool contains(ExecState*, KeyType);
+    size_t size(ExecState*) const { return m_size - m_deletedCount; }
 
-    JS_EXPORT_PRIVATE void set(CallFrame*, KeyType, JSValue);
-    JSValue get(CallFrame*, KeyType);
-    bool remove(CallFrame*, KeyType);
-    bool contains(CallFrame*, KeyType);
-    size_t size(CallFrame*) const { return m_size - m_deletedCount; }
-
-    const_iterator begin() const { return const_iterator(this); }
-    const_iterator end() const { return const_iterator::end(this); }
+    IteratorData createIteratorData(JSIterator*);
 
     void clear();
 
-    DECLARE_INFO;
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | Base::StructureFlags;
+    void visitChildren(JSCell* owner, SlotVisitor&);
+    void copyBackingStore(CopyVisitor&, CopyToken);
 
 private:
     typedef WTF::UnsignedWithZeroKeyHashTraits<int32_t> IndexTraits;
 
-    // Our marking functions expect Entry to maintain this layout, and have all
-    // fields be WriteBarrier<Unknown>
-    struct Entry {
-        WriteBarrier<Unknown> key;
-        WriteBarrier<Unknown> value;
-    };
-
     typedef HashMap<JSCell*, int32_t, typename WTF::DefaultHash<JSCell*>::Hash, WTF::HashTraits<JSCell*>, IndexTraits> CellKeyedMap;
     typedef HashMap<EncodedJSValue, int32_t, EncodedJSValueHash, EncodedJSValueHashTraits, IndexTraits> ValueKeyedMap;
     typedef HashMap<StringImpl*, int32_t, typename WTF::DefaultHash<StringImpl*>::Hash, WTF::HashTraits<StringImpl*>, IndexTraits> StringKeyedMap;
+    typedef HashMap<SymbolImpl*, int32_t, typename WTF::PtrHash<SymbolImpl*>, WTF::HashTraits<SymbolImpl*>, IndexTraits> SymbolKeyedMap;
 
     size_t capacityInBytes() { return m_capacity * sizeof(Entry); }
 
-    MapData(VM&);
-    static void destroy(JSCell*);
-    static void visitChildren(JSCell*, SlotVisitor&);
-    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
-
+    ALWAYS_INLINE Entry* find(ExecState*, KeyType);
+    ALWAYS_INLINE Entry* add(ExecState*, JSCell* owner, KeyType);
+    template <typename Map, typename Key> ALWAYS_INLINE Entry* add(ExecState*, JSCell* owner, Map&, Key, KeyType);
 
-    ALWAYS_INLINE Entry* find(CallFrame*, KeyType);
-    ALWAYS_INLINE Entry* add(CallFrame*, KeyType);
-    template <typename Map, typename Key> ALWAYS_INLINE Entry* add(CallFrame*, Map&, Key, KeyType);
-
-    ALWAYS_INLINE bool shouldPack() const { return m_deletedCount && !m_iteratorCount; }
-    CheckedBoolean ensureSpaceForAppend(CallFrame*);
+    ALWAYS_INLINE bool shouldPack() const { return m_deletedCount; }
+    CheckedBoolean ensureSpaceForAppend(ExecState*, JSCell* owner);
 
     ALWAYS_INLINE void replaceAndPackBackingStore(Entry* destination, int32_t newSize);
     ALWAYS_INLINE void replaceBackingStore(Entry* destination, int32_t newSize);
@@ -133,32 +132,33 @@ private:
     CellKeyedMap m_cellKeyedTable;
     ValueKeyedMap m_valueKeyedTable;
     StringKeyedMap m_stringKeyedTable;
+    SymbolKeyedMap m_symbolKeyedTable;
     int32_t m_capacity;
     int32_t m_size;
     int32_t m_deletedCount;
-    mutable int32_t m_iteratorCount;
     Entry* m_entries;
+    WeakGCMap<JSIterator*, JSIterator> m_iterators;
 };
 
-ALWAYS_INLINE void MapData::clear()
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE MapDataImpl<Entry, JSIterator>::MapDataImpl(VM& vm)
+    : m_capacity(0)
+    , m_size(0)
+    , m_deletedCount(0)
+    , m_entries(nullptr)
+    , m_iterators(vm)
 {
-    m_cellKeyedTable.clear();
-    m_valueKeyedTable.clear();
-    m_stringKeyedTable.clear();
-    m_capacity = 0;
-    m_size = 0;
-    m_deletedCount = 0;
-    m_entries = nullptr;
 }
 
-ALWAYS_INLINE MapData::KeyType::KeyType(JSValue v)
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE MapDataImpl<Entry, JSIterator>::KeyType::KeyType(JSValue v)
 {
     if (!v.isDouble()) {
         value = v;
         return;
     }
     double d = v.asDouble();
-    if (std::isnan(d) || (std::signbit(d) && d == 0.0)) {
+    if (std::isnan(d)) {
         value = v;
         return;
     }
@@ -170,65 +170,45 @@ ALWAYS_INLINE MapData::KeyType::KeyType(JSValue v)
         value = jsNumber(i);
 }
 
-ALWAYS_INLINE void MapData::const_iterator::internalIncrement()
-{
-    Entry* entries = m_mapData->m_entries;
-    size_t index = m_index + 1;
-    size_t end = m_mapData->m_size;
-    while (index < end && !entries[index].key)
-        index++;
-    m_index = index;
-}
-    
-ALWAYS_INLINE bool MapData::const_iterator::ensureSlot()
-{
-    // When an iterator exists outside of host cost it is possible for
-    // the containing map to be modified
-    Entry* entries = m_mapData->m_entries;
-    size_t index = m_index;
-    size_t end = m_mapData->m_size;
-    if (index < end && entries[index].key)
-        return true;
-    internalIncrement();
-    return static_cast<size_t>(m_index) < end;
-}
-
-ALWAYS_INLINE MapData::const_iterator::const_iterator(const MapData* mapData)
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE MapDataImpl<Entry, JSIterator>::IteratorData::IteratorData(const MapDataImpl<Entry, JSIterator>* mapData)
     : m_mapData(mapData)
-    , m_index(-1)
+    , m_index(0)
 {
-    internalIncrement();
 }
 
-ALWAYS_INLINE MapData::const_iterator::~const_iterator()
-{
-    m_mapData->m_iteratorCount--;
-}
-
-ALWAYS_INLINE const WTF::KeyValuePair<JSValue, JSValue> MapData::const_iterator::operator*() const
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE bool MapDataImpl<Entry, JSIterator>::IteratorData::next(WTF::KeyValuePair<JSValue, JSValue>& pair)
 {
+    if (!ensureSlot())
+        return false;
     Entry* entry = &m_mapData->m_entries[m_index];
-    return WTF::KeyValuePair<JSValue, JSValue>(entry->key.get(), entry->value.get());
+    pair = WTF::KeyValuePair<JSValue, JSValue>(entry->key().get(), entry->value().get());
+    m_index += 1;
+    return true;
 }
 
-ALWAYS_INLINE MapData::const_iterator MapData::const_iterator::end(const MapData* mapData)
+// This is a bit gnarly. We use an index of -1 to indicate the
+// finished state. By casting to unsigned we can immediately
+// test if both iterators are at the end of their iteration.
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE bool MapDataImpl<Entry, JSIterator>::IteratorData::ensureSlot() const
 {
-    const_iterator result(mapData);
-    result.m_index = -1;
-    return result;
+    int32_t index = refreshCursor();
+    return static_cast<size_t>(index) < static_cast<size_t>(m_mapData->m_size);
 }
 
-ALWAYS_INLINE bool MapData::const_iterator::operator!=(const const_iterator& other)
+template<typename Entry, typename JSIterator>
+ALWAYS_INLINE int32_t MapDataImpl<Entry, JSIterator>::IteratorData::refreshCursor() const
 {
-    ASSERT(other.m_mapData == m_mapData);
-    if (atEnd() && other.atEnd())
-        return false;
-    return m_index != other.m_index;
-}
+    if (isFinished())
+        return m_index;
 
-ALWAYS_INLINE bool MapData::const_iterator::operator==(const const_iterator& other)
-{
-    return !(*this != other);
+    Entry* entries = m_mapData->m_entries;
+    size_t end = m_mapData->m_size;
+    while (static_cast<size_t>(m_index) < end && !entries[m_index].key())
+        m_index++;
+    return m_index;
 }
 
 }
diff --git a/runtime/MapDataInlines.h b/runtime/MapDataInlines.h
new file mode 100644 (file)
index 0000000..176acc1
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CopiedAllocator.h"
+#include "CopyVisitorInlines.h"
+#include "ExceptionHelpers.h"
+#include "JSCJSValueInlines.h"
+#include "MapData.h"
+#include "SlotVisitorInlines.h"
+
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/MathExtras.h>
+
+
+namespace JSC {
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::clear()
+{
+    m_cellKeyedTable.clear();
+    m_valueKeyedTable.clear();
+    m_stringKeyedTable.clear();
+    m_symbolKeyedTable.clear();
+    m_capacity = 0;
+    m_size = 0;
+    m_deletedCount = 0;
+    m_entries = nullptr;
+    m_iterators.forEach([](JSIterator* iterator, JSIterator*) {
+        iterator->iteratorData()->didRemoveAllEntries();
+    });
+}
+
+template<typename Entry, typename JSIterator>
+inline Entry* MapDataImpl<Entry, JSIterator>::find(ExecState* exec, KeyType key)
+{
+    if (key.value.isString()) {
+        auto iter = m_stringKeyedTable.find(asString(key.value)->value(exec).impl());
+        if (iter == m_stringKeyedTable.end())
+            return 0;
+        return &m_entries[iter->value];
+    }
+    if (key.value.isSymbol()) {
+        auto iter = m_symbolKeyedTable.find(asSymbol(key.value)->privateName().uid());
+        if (iter == m_symbolKeyedTable.end())
+            return 0;
+        return &m_entries[iter->value];
+    }
+    if (key.value.isCell()) {
+        auto iter = m_cellKeyedTable.find(key.value.asCell());
+        if (iter == m_cellKeyedTable.end())
+            return 0;
+        return &m_entries[iter->value];
+    }
+
+    auto iter = m_valueKeyedTable.find(JSValue::encode(key.value));
+    if (iter == m_valueKeyedTable.end())
+        return 0;
+    return &m_entries[iter->value];
+}
+
+template<typename Entry, typename JSIterator>
+inline bool MapDataImpl<Entry, JSIterator>::contains(ExecState* exec, KeyType key)
+{
+    return find(exec, key);
+}
+
+template<typename Entry, typename JSIterator>
+template <typename Map, typename Key>
+inline Entry* MapDataImpl<Entry, JSIterator>::add(ExecState* exec, JSCell* owner, Map& map, Key key, KeyType keyValue)
+{
+    typename Map::iterator location = map.find(key);
+    if (location != map.end())
+        return &m_entries[location->value];
+
+    if (!ensureSpaceForAppend(exec, owner))
+        return 0;
+
+    auto result = map.add(key, m_size);
+    RELEASE_ASSERT(result.isNewEntry);
+    Entry* entry = &m_entries[m_size++];
+    new (entry) Entry();
+    entry->setKey(exec->vm(), owner, keyValue.value);
+    return entry;
+}
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::set(ExecState* exec, JSCell* owner, KeyType key, JSValue value)
+{
+    Entry* location = add(exec, owner, key);
+    if (!location)
+        return;
+    location->setValue(exec->vm(), owner, value);
+}
+
+template<typename Entry, typename JSIterator>
+inline Entry* MapDataImpl<Entry, JSIterator>::add(ExecState* exec, JSCell* owner, KeyType key)
+{
+    if (key.value.isString())
+        return add(exec, owner, m_stringKeyedTable, asString(key.value)->value(exec).impl(), key);
+    if (key.value.isSymbol())
+        return add(exec, owner, m_symbolKeyedTable, asSymbol(key.value)->privateName().uid(), key);
+    if (key.value.isCell())
+        return add(exec, owner, m_cellKeyedTable, key.value.asCell(), key);
+    return add(exec, owner, m_valueKeyedTable, JSValue::encode(key.value), key);
+}
+
+template<typename Entry, typename JSIterator>
+inline JSValue MapDataImpl<Entry, JSIterator>::get(ExecState* exec, KeyType key)
+{
+    if (Entry* entry = find(exec, key))
+        return entry->value().get();
+    return JSValue();
+}
+
+template<typename Entry, typename JSIterator>
+inline bool MapDataImpl<Entry, JSIterator>::remove(ExecState* exec, KeyType key)
+{
+    int32_t location;
+    if (key.value.isString()) {
+        auto iter = m_stringKeyedTable.find(asString(key.value)->value(exec).impl());
+        if (iter == m_stringKeyedTable.end())
+            return false;
+        location = iter->value;
+        m_stringKeyedTable.remove(iter);
+    }  else if (key.value.isSymbol()) {
+        auto iter = m_symbolKeyedTable.find(asSymbol(key.value)->privateName().uid());
+        if (iter == m_symbolKeyedTable.end())
+            return false;
+        location = iter->value;
+        m_symbolKeyedTable.remove(iter);
+    } else if (key.value.isCell()) {
+        auto iter = m_cellKeyedTable.find(key.value.asCell());
+        if (iter == m_cellKeyedTable.end())
+            return false;
+        location = iter->value;
+        m_cellKeyedTable.remove(iter);
+    } else {
+        auto iter = m_valueKeyedTable.find(JSValue::encode(key.value));
+        if (iter == m_valueKeyedTable.end())
+            return false;
+        location = iter->value;
+        m_valueKeyedTable.remove(iter);
+    }
+    m_entries[location].clear();
+    m_deletedCount++;
+    return true;
+}
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::replaceAndPackBackingStore(Entry* destination, int32_t newCapacity)
+{
+    ASSERT(shouldPack());
+    int32_t newEnd = 0;
+    RELEASE_ASSERT(newCapacity > 0);
+    for (int32_t i = 0; i < m_size; i++) {
+        Entry& entry = m_entries[i];
+        if (!entry.key()) {
+            m_iterators.forEach([newEnd](JSIterator* iterator, JSIterator*) {
+                iterator->iteratorData()->didRemoveEntry(newEnd);
+            });
+            continue;
+        }
+        ASSERT(newEnd < newCapacity);
+        destination[newEnd] = entry;
+
+        // We overwrite the old entry with a forwarding index for the new entry,
+        // so that we can fix up our hash tables below without doing additional
+        // hash lookups
+        entry.setKeyWithoutWriteBarrier(jsNumber(newEnd));
+        newEnd++;
+    }
+
+    // Fixup for the hashmaps
+    for (auto ptr = m_valueKeyedTable.begin(); ptr != m_valueKeyedTable.end(); ++ptr)
+        ptr->value = m_entries[ptr->value].key().get().asInt32();
+    for (auto ptr = m_cellKeyedTable.begin(); ptr != m_cellKeyedTable.end(); ++ptr)
+        ptr->value = m_entries[ptr->value].key().get().asInt32();
+    for (auto ptr = m_stringKeyedTable.begin(); ptr != m_stringKeyedTable.end(); ++ptr)
+        ptr->value = m_entries[ptr->value].key().get().asInt32();
+    for (auto ptr = m_symbolKeyedTable.begin(); ptr != m_symbolKeyedTable.end(); ++ptr)
+        ptr->value = m_entries[ptr->value].key().get().asInt32();
+
+    ASSERT((m_size - newEnd) == m_deletedCount);
+    m_deletedCount = 0;
+
+    m_capacity = newCapacity;
+    m_size = newEnd;
+    m_entries = destination;
+}
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::replaceBackingStore(Entry* destination, int32_t newCapacity)
+{
+    ASSERT(!shouldPack());
+    RELEASE_ASSERT(newCapacity > 0);
+    ASSERT(newCapacity >= m_capacity);
+    memcpy(destination, m_entries, sizeof(Entry) * m_size);
+    m_capacity = newCapacity;
+    m_entries = destination;
+}
+
+template<typename Entry, typename JSIterator>
+inline CheckedBoolean MapDataImpl<Entry, JSIterator>::ensureSpaceForAppend(ExecState* exec, JSCell* owner)
+{
+    if (m_capacity > m_size)
+        return true;
+
+    size_t requiredSize = std::max(m_capacity + (m_capacity / 2) + 1, static_cast<int32_t>(minimumMapSize));
+    void* newStorage = nullptr;
+    DeferGC defer(*exec->heap());
+    if (!exec->heap()->tryAllocateStorage(owner, requiredSize * sizeof(Entry), &newStorage)) {
+        throwOutOfMemoryError(exec);
+        return false;
+    }
+    Entry* newEntries = static_cast<Entry*>(newStorage);
+    if (shouldPack())
+        replaceAndPackBackingStore(newEntries, requiredSize);
+    else
+        replaceBackingStore(newEntries, requiredSize);
+    exec->heap()->writeBarrier(owner);
+    return true;
+}
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::visitChildren(JSCell* owner, SlotVisitor& visitor)
+{
+    Entry* entries = m_entries;
+    if (!entries)
+        return;
+    if (m_deletedCount) {
+        for (int32_t i = 0; i < m_size; i++) {
+            if (!entries[i].key())
+                continue;
+            entries[i].visitChildren(visitor);
+        }
+    } else {
+        // Guaranteed that all fields of Entry type is WriteBarrier<Unknown>.
+        visitor.appendValues(reinterpret_cast<WriteBarrier<Unknown>*>(&entries[0]), m_size * (sizeof(Entry) / sizeof(WriteBarrier<Unknown>)));
+    }
+
+    visitor.copyLater(owner, MapBackingStoreCopyToken, entries, capacityInBytes());
+}
+
+template<typename Entry, typename JSIterator>
+inline void MapDataImpl<Entry, JSIterator>::copyBackingStore(CopyVisitor& visitor, CopyToken token)
+{
+    if (token == MapBackingStoreCopyToken && visitor.checkIfShouldCopy(m_entries)) {
+        Entry* oldEntries = m_entries;
+        Entry* newEntries = static_cast<Entry*>(visitor.allocateNewSpace(capacityInBytes()));
+        if (shouldPack())
+            replaceAndPackBackingStore(newEntries, m_capacity);
+        else
+            replaceBackingStore(newEntries, m_capacity);
+        visitor.didCopy(oldEntries, capacityInBytes());
+    }
+}
+
+template<typename Entry, typename JSIterator>
+inline auto MapDataImpl<Entry, JSIterator>::createIteratorData(JSIterator* iterator) -> IteratorData
+{
+    m_iterators.set(iterator, iterator);
+    return IteratorData(this);
+}
+
+}
diff --git a/runtime/MapIteratorConstructor.cpp b/runtime/MapIteratorConstructor.cpp
deleted file mode 100644 (file)
index 40cc239..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "MapIteratorConstructor.h"
-
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSGlobalObject.h"
-#include "JSMapIterator.h"
-#include "MapIteratorPrototype.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-const ClassInfo MapIteratorConstructor::s_info = { "MapIterator Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MapIteratorConstructor) };
-
-void MapIteratorConstructor::finishCreation(VM& vm, MapIteratorPrototype* prototype)
-{
-    Base::finishCreation(vm);
-    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
-}
-
-}
diff --git a/runtime/MapIteratorConstructor.h b/runtime/MapIteratorConstructor.h
deleted file mode 100644 (file)
index 45ba5b7..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef MapIteratorConstructor_h
-#define MapIteratorConstructor_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-class MapIteratorPrototype;
-
-class MapIteratorConstructor : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static MapIteratorConstructor* create(VM& vm, Structure* structure, MapIteratorPrototype* prototype)
-    {
-        MapIteratorConstructor* constructor = new (NotNull, allocateCell<MapIteratorConstructor>(vm.heap)) MapIteratorConstructor(vm, structure);
-        constructor->finishCreation(vm, prototype);
-        return constructor;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-private:
-    MapIteratorConstructor(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-    void finishCreation(VM&, MapIteratorPrototype*);
-};
-
-}
-
-#endif // !defined(MapConstructor_h)
index 78fb6697d63f88e3c124c6c6f9f7816a33f564ea..5e7ec33f9d52bc7147ed062c494b6b008802865f 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "MapIteratorPrototype.h"
 
+#include "IteratorOperations.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSMapIterator.h"
 
 namespace JSC {
 
-const ClassInfo MapIteratorPrototype::s_info = { "Map Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MapIteratorPrototype) };
+const ClassInfo MapIteratorPrototype::s_info = { "Map Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(MapIteratorPrototype) };
 
-static EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncIterator(ExecState*);
 static EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncNext(ExecState*);
 
-
 void MapIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
 
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, MapIteratorPrototypeFuncIterator, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorNextPrivateName, MapIteratorPrototypeFuncNext, DontEnum, 0);
-}
-
-EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncIterator(CallFrame* callFrame)
-{
-    return JSValue::encode(callFrame->thisValue());
+    JSC_NATIVE_FUNCTION(vm.propertyNames->next, MapIteratorPrototypeFuncNext, DontEnum, 0);
 }
 
 EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncNext(CallFrame* callFrame)
@@ -59,11 +52,12 @@ EncodedJSValue JSC_HOST_CALL MapIteratorPrototypeFuncNext(CallFrame* callFrame)
     JSMapIterator* iterator = jsDynamicCast<JSMapIterator*>(callFrame->thisValue());
     if (!iterator)
         return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call MapIterator.next() on a non-MapIterator object")));
-    
+
     JSValue result;
     if (iterator->next(callFrame, result))
-        return JSValue::encode(result);
-    return JSValue::encode(callFrame->vm().iterationTerminator.get());
+        return JSValue::encode(createIteratorResultObject(callFrame, result, false));
+    iterator->finish();
+    return JSValue::encode(createIteratorResultObject(callFrame, jsUndefined(), true));
 }
 
 
index 5221177b34074590d4a0bca23ee224ecd6cf86ef..96deae714ca51a67fd16408e5c39d3c65673894d 100644 (file)
 #include "JSFunctionInlines.h"
 #include "JSMap.h"
 #include "JSMapIterator.h"
-#include "MapData.h"
+#include "MapDataInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo MapPrototype::s_info = { "Map", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MapPrototype) };
+const ClassInfo MapPrototype::s_info = { "Map", &Base::s_info, 0, CREATE_METHOD_TABLE(MapPrototype) };
 
 static EncodedJSValue JSC_HOST_CALL mapProtoFuncClear(ExecState*);
 static EncodedJSValue JSC_HOST_CALL mapProtoFuncDelete(ExecState*);
@@ -67,50 +67,52 @@ void MapPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     JSC_NATIVE_FUNCTION(vm.propertyNames->set, mapProtoFuncSet, DontEnum, 2);
     JSC_NATIVE_FUNCTION(vm.propertyNames->keys, mapProtoFuncKeys, DontEnum, 0);
     JSC_NATIVE_FUNCTION(vm.propertyNames->values, mapProtoFuncValues, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->entries, mapProtoFuncEntries, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, mapProtoFuncEntries, DontEnum, 0);
 
-    GetterSetter* accessor = GetterSetter::create(vm);
+    JSFunction* entries = JSFunction::create(vm, globalObject, 0, vm.propertyNames->entries.string(), mapProtoFuncEntries);
+    putDirectWithoutTransition(vm, vm.propertyNames->entries, entries, DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, entries, DontEnum);
+
+    GetterSetter* accessor = GetterSetter::create(vm, globalObject);
     JSFunction* function = JSFunction::create(vm, globalObject, 0, vm.propertyNames->size.string(), mapProtoFuncSize);
-    accessor->setGetter(vm, function);
+    accessor->setGetter(vm, globalObject, function);
     putDirectNonIndexAccessor(vm, vm.propertyNames->size, accessor, DontEnum | Accessor);
 }
 
-ALWAYS_INLINE static MapData* getMapData(CallFrame* callFrame, JSValue thisValue)
+ALWAYS_INLINE static JSMap* getMap(CallFrame* callFrame, JSValue thisValue)
 {
     if (!thisValue.isObject()) {
         throwVMError(callFrame, createNotAnObjectError(callFrame, thisValue));
-        return 0;
+        return nullptr;
     }
     JSMap* map = jsDynamicCast<JSMap*>(thisValue);
     if (!map) {
         throwTypeError(callFrame, ASCIILiteral("Map operation called on non-Map object"));
-        return 0;
+        return nullptr;
     }
-    return map->mapData();
+    return map;
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncClear(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
-    data->clear();
+    map->clear(callFrame);
     return JSValue::encode(jsUndefined());
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncDelete(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsBoolean(data->remove(callFrame, callFrame->argument(0))));
+    return JSValue::encode(jsBoolean(map->remove(callFrame, callFrame->argument(0))));
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncForEach(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
     JSValue callBack = callFrame->argument(0);
     CallData callData;
@@ -119,60 +121,64 @@ EncodedJSValue JSC_HOST_CALL mapProtoFuncForEach(CallFrame* callFrame)
         return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("Map.prototype.forEach called without callback")));
     JSValue thisValue = callFrame->argument(1);
     VM* vm = &callFrame->vm();
+    JSMapIterator* iterator = JSMapIterator::create(*vm, callFrame->callee()->globalObject()->mapIteratorStructure(), map, MapIterateKeyValue);
+    JSValue key, value;
     if (callType == CallTypeJS) {
         JSFunction* function = jsCast<JSFunction*>(callBack);
-        CachedCall cachedCall(callFrame, function, 2);
-        for (auto ptr = data->begin(), end = data->end(); ptr != end && !vm->exception(); ++ptr) {
+        CachedCall cachedCall(callFrame, function, 3);
+        while (iterator->nextKeyValue(key, value) && !vm->exception()) {
             cachedCall.setThis(thisValue);
-            cachedCall.setArgument(0, ptr.value());
-            cachedCall.setArgument(1, ptr.key());
+            cachedCall.setArgument(0, value);
+            cachedCall.setArgument(1, key);
+            cachedCall.setArgument(2, map);
             cachedCall.call();
         }
+        iterator->finish();
     } else {
-        for (auto ptr = data->begin(), end = data->end(); ptr != end && !vm->exception(); ++ptr) {
+        while (iterator->nextKeyValue(key, value) && !vm->exception()) {
             MarkedArgumentBuffer args;
-            args.append(ptr.value());
-            args.append(ptr.key());
+            args.append(value);
+            args.append(key);
+            args.append(map);
             JSC::call(callFrame, callBack, callType, callData, thisValue, args);
         }
+        iterator->finish();
     }
     return JSValue::encode(jsUndefined());
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncGet(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
-    JSValue result = data->get(callFrame, callFrame->argument(0));
-    if (!result)
-        result = jsUndefined();
-    return JSValue::encode(result);
+    return JSValue::encode(map->get(callFrame, callFrame->argument(0)));
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncHas(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsBoolean(data->contains(callFrame, callFrame->argument(0))));
+    return JSValue::encode(jsBoolean(map->has(callFrame, callFrame->argument(0))));
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncSet(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSValue thisValue = callFrame->thisValue();
+    JSMap* map = getMap(callFrame, thisValue);
+    if (!map)
         return JSValue::encode(jsUndefined());
-    data->set(callFrame, callFrame->argument(0), callFrame->argument(1));
-    return JSValue::encode(callFrame->thisValue());
+    map->set(callFrame, callFrame->argument(0), callFrame->argument(1));
+    return JSValue::encode(thisValue);
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncSize(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSMap* map = getMap(callFrame, callFrame->thisValue());
+    if (!map)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsNumber(data->size(callFrame)));
+    return JSValue::encode(jsNumber(map->size(callFrame)));
 }
 
 EncodedJSValue JSC_HOST_CALL mapProtoFuncValues(CallFrame* callFrame)
@@ -187,7 +193,7 @@ EncodedJSValue JSC_HOST_CALL mapProtoFuncEntries(CallFrame* callFrame)
 {
     JSMap* thisObj = jsDynamicCast<JSMap*>(callFrame->thisValue());
     if (!thisObj)
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map key iterator for a non-Map object.")));
+        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map entry iterator for a non-Map object.")));
     return JSValue::encode(JSMapIterator::create(callFrame->vm(), callFrame->callee()->globalObject()->mapIteratorStructure(), thisObj, MapIterateKeyValue));
 }
 
@@ -195,7 +201,7 @@ EncodedJSValue JSC_HOST_CALL mapProtoFuncKeys(CallFrame* callFrame)
 {
     JSMap* thisObj = jsDynamicCast<JSMap*>(callFrame->thisValue());
     if (!thisObj)
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map entry iterator for a non-Map object.")));
+        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map key iterator for a non-Map object.")));
     return JSValue::encode(JSMapIterator::create(callFrame->vm(), callFrame->callee()->globalObject()->mapIteratorStructure(), thisObj, MapIterateKey));
 }
 
diff --git a/runtime/MathCommon.cpp b/runtime/MathCommon.cpp
new file mode 100644 (file)
index 0000000..5420466
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MathCommon.h"
+
+#include <cmath>
+#include "PureNaN.h"
+
+namespace JSC {
+
+#if PLATFORM(IOS) && CPU(ARM_THUMB2)
+
+// The following code is taken from netlib.org:
+//   http://www.netlib.org/fdlibm/fdlibm.h
+//   http://www.netlib.org/fdlibm/e_pow.c
+//   http://www.netlib.org/fdlibm/s_scalbn.c
+//
+// And was originally distributed under the following license:
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ *              n
+ * Method:  Let x =  2   * (1+f)
+ *    1. Compute and return log2(x) in two pieces:
+ *        log2(x) = w1 + w2,
+ *       where w1 has 53-24 = 29 bit trailing zeros.
+ *    2. Perform y*log2(x) = n+y' by simulating muti-precision
+ *       arithmetic, where |y'|<=0.5.
+ *    3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ *    1.  (anything) ** 0  is 1
+ *    2.  (anything) ** 1  is itself
+ *    3.  (anything) ** NAN is NAN
+ *    4.  NAN ** (anything except 0) is NAN
+ *    5.  +-(|x| > 1) **  +INF is +INF
+ *    6.  +-(|x| > 1) **  -INF is +0
+ *    7.  +-(|x| < 1) **  +INF is +0
+ *    8.  +-(|x| < 1) **  -INF is +INF
+ *    9.  +-1         ** +-INF is NAN
+ *    10. +0 ** (+anything except 0, NAN)               is +0
+ *    11. -0 ** (+anything except 0, NAN, odd integer)  is +0
+ *    12. +0 ** (-anything except 0, NAN)               is +INF
+ *    13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
+ *    14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ *    15. +INF ** (+anything except 0,NAN) is +INF
+ *    16. +INF ** (-anything except 0,NAN) is +0
+ *    17. -INF ** (anything)  = -0 ** (-anything)
+ *    18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ *    19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ *    pow(x,y) returns x**y nearly rounded. In particular
+ *            pow(integer,integer)
+ *    always returns the correct integer provided it is
+ *    representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#define __HI(x) *(1+(int*)&x)
+#define __LO(x) *(int*)&x
+
+static const double
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero    =  0.0,
+one    =  1.0,
+two    =  2.0,
+two53    =  9007199254740992.0,    /* 0x43400000, 0x00000000 */
+huge    =  1.0e300,
+tiny    =  1.0e-300,
+/* for scalbn */
+two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1  =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2  =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3  =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4  =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5  =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6  =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2  =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h  =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l  = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt =  8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp    =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h  =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l  = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2    =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+inline double fdlibmScalbn (double x, int n)
+{
+    int  k,hx,lx;
+    hx = __HI(x);
+    lx = __LO(x);
+    k = (hx&0x7ff00000)>>20;        /* extract exponent */
+    if (k==0) {                /* 0 or subnormal x */
+        if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+        x *= two54;
+        hx = __HI(x);
+        k = ((hx&0x7ff00000)>>20) - 54;
+        if (n< -50000) return tiny*x;     /*underflow*/
+    }
+    if (k==0x7ff) return x+x;        /* NaN or Inf */
+    k = k+n;
+    if (k >  0x7fe) return huge*copysign(huge,x); /* overflow  */
+    if (k > 0)                 /* normal result */
+    {__HI(x) = (hx&0x800fffff)|(k<<20); return x;}
+    if (k <= -54) {
+        if (n > 50000)     /* in case integer overflow in n+k */
+            return huge*copysign(huge,x);    /*overflow*/
+        else return tiny*copysign(tiny,x);     /*underflow*/
+    }
+    k += 54;                /* subnormal result */
+    __HI(x) = (hx&0x800fffff)|(k<<20);
+    return x*twom54;
+}
+
+static double fdlibmPow(double x, double y)
+{
+    double z,ax,z_h,z_l,p_h,p_l;
+    double y1,t1,t2,r,s,t,u,v,w;
+    int i0,i1,i,j,k,yisint,n;
+    int hx,hy,ix,iy;
+    unsigned lx,ly;
+
+    i0 = ((*(int*)&one)>>29)^1; i1=1-i0;
+    hx = __HI(x); lx = __LO(x);
+    hy = __HI(y); ly = __LO(y);
+    ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
+
+    /* y==zero: x**0 = 1 */
+    if((iy|ly)==0) return one;
+
+    /* +-NaN return x+y */
+    if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+       iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+        return x+y;
+
+    /* determine if y is an odd int when x < 0
+     * yisint = 0    ... y is not an integer
+     * yisint = 1    ... y is an odd int
+     * yisint = 2    ... y is an even int
+     */
+    yisint  = 0;
+    if(hx<0) {
+        if(iy>=0x43400000) yisint = 2; /* even integer y */
+        else if(iy>=0x3ff00000) {
+            k = (iy>>20)-0x3ff;       /* exponent */
+            if(k>20) {
+                j = ly>>(52-k);
+                if(static_cast<unsigned>(j<<(52-k))==ly) yisint = 2-(j&1);
+            } else if(ly==0) {
+                j = iy>>(20-k);
+                if((j<<(20-k))==iy) yisint = 2-(j&1);
+            }
+        }
+    }
+
+    /* special value of y */
+    if(ly==0) {
+        if (iy==0x7ff00000) {    /* y is +-inf */
+            if(((ix-0x3ff00000)|lx)==0)
+                return  y - y;    /* inf**+-1 is NaN */
+            else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+                return (hy>=0)? y: zero;
+            else            /* (|x|<1)**-,+inf = inf,0 */
+                return (hy<0)?-y: zero;
+        }
+        if(iy==0x3ff00000) {    /* y is  +-1 */
+            if(hy<0) return one/x; else return x;
+        }
+        if(hy==0x40000000) return x*x; /* y is  2 */
+        if(hy==0x3fe00000) {    /* y is  0.5 */
+            if(hx>=0)    /* x >= +0 */
+                return sqrt(x);
+        }
+    }
+
+    ax   = fabs(x);
+    /* special value of x */
+    if(lx==0) {
+        if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+            z = ax;            /*x is +-0,+-inf,+-1*/
+            if(hy<0) z = one/z;    /* z = (1/|x|) */
+            if(hx<0) {
+                if(((ix-0x3ff00000)|yisint)==0) {
+                    z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+                } else if(yisint==1)
+                    z = -z;        /* (x<0)**odd = -(|x|**odd) */
+            }
+            return z;
+        }
+    }
+
+    n = (hx>>31)+1;
+
+    /* (x<0)**(non-int) is NaN */
+    if((n|yisint)==0) return (x-x)/(x-x);
+
+    s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+    if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
+
+    /* |y| is huge */
+    if(iy>0x41e00000) { /* if |y| > 2**31 */
+        if(iy>0x43f00000){    /* if |y| > 2**64, must o/uflow */
+            if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+            if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+        }
+        /* over/underflow if x is not close to one */
+        if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
+        if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
+        /* now |1-x| is tiny <= 2**-20, suffice to compute
+         log(x) by x-x^2/2+x^3/3-x^4/4 */
+        t = ax-one;        /* t has 20 trailing zeros */
+        w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+        u = ivln2_h*t;    /* ivln2_h has 21 sig. bits */
+        v = t*ivln2_l-w*ivln2;
+        t1 = u+v;
+        __LO(t1) = 0;
+        t2 = v-(t1-u);
+    } else {
+        double ss,s2,s_h,s_l,t_h,t_l;
+        n = 0;
+        /* take care subnormal number */
+        if(ix<0x00100000)
+        {ax *= two53; n -= 53; ix = __HI(ax); }
+        n  += ((ix)>>20)-0x3ff;
+        j  = ix&0x000fffff;
+        /* determine interval */
+        ix = j|0x3ff00000;        /* normalize ix */
+        if(j<=0x3988E) k=0;        /* |x|<sqrt(3/2) */
+        else if(j<0xBB67A) k=1;    /* |x|<sqrt(3)   */
+        else {k=0;n+=1;ix -= 0x00100000;}
+        __HI(ax) = ix;
+
+        /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+        u = ax-bp[k];        /* bp[0]=1.0, bp[1]=1.5 */
+        v = one/(ax+bp[k]);
+        ss = u*v;
+        s_h = ss;
+        __LO(s_h) = 0;
+        /* t_h=ax+bp[k] High */
+        t_h = zero;
+        __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18);
+        t_l = ax - (t_h-bp[k]);
+        s_l = v*((u-s_h*t_h)-s_h*t_l);
+        /* compute log(ax) */
+        s2 = ss*ss;
+        r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+        r += s_l*(s_h+ss);
+        s2  = s_h*s_h;
+        t_h = 3.0+s2+r;
+        __LO(t_h) = 0;
+        t_l = r-((t_h-3.0)-s2);
+        /* u+v = ss*(1+...) */
+        u = s_h*t_h;
+        v = s_l*t_h+t_l*ss;
+        /* 2/(3log2)*(ss+...) */
+        p_h = u+v;
+        __LO(p_h) = 0;
+        p_l = v-(p_h-u);
+        z_h = cp_h*p_h;        /* cp_h+cp_l = 2/(3*log2) */
+        z_l = cp_l*p_h+p_l*cp+dp_l[k];
+        /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+        t = (double)n;
+        t1 = (((z_h+z_l)+dp_h[k])+t);
+        __LO(t1) = 0;
+        t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+    }
+
+    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+    y1  = y;
+    __LO(y1) = 0;
+    p_l = (y-y1)*t1+y*t2;
+    p_h = y1*t1;
+    z = p_l+p_h;
+    j = __HI(z);
+    i = __LO(z);
+    if (j>=0x40900000) {                /* z >= 1024 */
+        if(((j-0x40900000)|i)!=0)            /* if z > 1024 */
+            return s*huge*huge;            /* overflow */
+        else {
+            if(p_l+ovt>z-p_h) return s*huge*huge;    /* overflow */
+        }
+    } else if((j&0x7fffffff)>=0x4090cc00 ) {    /* z <= -1075 */
+        if(((j-0xc090cc00)|i)!=0)         /* z < -1075 */
+            return s*tiny*tiny;        /* underflow */
+        else {
+            if(p_l<=z-p_h) return s*tiny*tiny;    /* underflow */
+        }
+    }
+    /*
+     * compute 2**(p_h+p_l)
+     */
+    i = j&0x7fffffff;
+    k = (i>>20)-0x3ff;
+    n = 0;
+    if(i>0x3fe00000) {        /* if |z| > 0.5, set n = [z+0.5] */
+        n = j+(0x00100000>>(k+1));
+        k = ((n&0x7fffffff)>>20)-0x3ff;    /* new k for n */
+        t = zero;
+        __HI(t) = (n&~(0x000fffff>>k));
+        n = ((n&0x000fffff)|0x00100000)>>(20-k);
+        if(j<0) n = -n;
+        p_h -= t;
+    }
+    t = p_l+p_h;
+    __LO(t) = 0;
+    u = t*lg2_h;
+    v = (p_l-(t-p_h))*lg2+t*lg2_l;
+    z = u+v;
+    w = v-(z-u);
+    t  = z*z;
+    t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+    r  = (z*t1)/(t1-two)-(w+z*w);
+    z  = one-(r-z);
+    j  = __HI(z);
+    j += (n<<20);
+    if((j>>20)<=0) z = fdlibmScalbn(z,n);    /* subnormal output */
+    else __HI(z) += (n<<20);
+    return s*z;
+}
+
+static ALWAYS_INLINE bool isDenormal(double x)
+{
+    static const uint64_t signbit = 0x8000000000000000ULL;
+    static const uint64_t minNormal = 0x0001000000000000ULL;
+    return (bitwise_cast<uint64_t>(x) & ~signbit) - 1 < minNormal - 1;
+}
+
+static ALWAYS_INLINE bool isEdgeCase(double x)
+{
+    static const uint64_t signbit = 0x8000000000000000ULL;
+    static const uint64_t infinity = 0x7fffffffffffffffULL;
+    return (bitwise_cast<uint64_t>(x) & ~signbit) - 1 >= infinity - 1;
+}
+
+static ALWAYS_INLINE double mathPowInternal(double x, double y)
+{
+    if (!isDenormal(x) && !isDenormal(y)) {
+        double libmResult = std::pow(x, y);
+        if (libmResult || isEdgeCase(x) || isEdgeCase(y))
+            return libmResult;
+    }
+    return fdlibmPow(x, y);
+}
+
+#else
+
+ALWAYS_INLINE double mathPowInternal(double x, double y)
+{
+    return pow(x, y);
+}
+
+#endif
+
+double JIT_OPERATION operationMathPow(double x, double y)
+{
+    if (std::isnan(y))
+        return PNaN;
+    if (std::isinf(y) && fabs(x) == 1)
+        return PNaN;
+    return mathPowInternal(x, y);
+}
+
+extern "C" {
+double jsRound(double value)
+{
+    double integer = ceil(value);
+    return integer - (integer - value > 0.5);
+}
+}
+
+} // namespace JSC
diff --git a/runtime/MathCommon.h b/runtime/MathCommon.h
new file mode 100644 (file)
index 0000000..840d863
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MathCommon_h
+#define MathCommon_h
+
+#include "JITOperations.h"
+
+#ifndef JIT_OPERATION
+#define JIT_OPERATION
+#endif
+
+namespace JSC {
+double JIT_OPERATION operationMathPow(double x, double y) WTF_INTERNAL;
+
+inline int clz32(uint32_t number)
+{
+#if COMPILER(GCC) || COMPILER(CLANG)
+    int zeroCount = 32;
+    if (number)
+        zeroCount = __builtin_clz(number);
+    return zeroCount;
+#else
+    int zeroCount = 0;
+    for (int i = 31; i >= 0; i--) {
+        if (!(number >> i))
+            zeroCount++;
+        else
+            break;
+    }
+    return zeroCount;
+#endif
+}
+
+extern "C" {
+double JIT_OPERATION jsRound(double value) REFERENCED_FROM_ASM WTF_INTERNAL;
+}
+
+}
+
+#endif // MathCommon_h
index fdf5abdf64b6d3892ef6e9c4a3a310bf3c8b0cc1..d23e46b6bf3a2230e807d53d482fcf3cbea1b33b 100644 (file)
@@ -22,6 +22,7 @@
 #include "MathObject.h"
 
 #include "Lookup.h"
+#include "MathCommon.h"
 #include "ObjectPrototype.h"
 #include "JSCInlines.h"
 #include <time.h>
@@ -35,45 +36,45 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(MathObject);
 
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncACosh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncASinh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncATanh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncCbrt(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncCosh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncExpm1(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncHypot(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog1p(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog10(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog2(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncSinh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncTanh(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*);
-static EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncACosh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncASinh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncATanh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncCbrt(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncClz32(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncCosh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncExpm1(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncHypot(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncLog1p(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncLog10(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncLog2(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncSign(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncSinh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncTanh(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState*);
 
 }
 
 namespace JSC {
 
-const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(MathObject) };
+const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, CREATE_METHOD_TABLE(MathObject) };
 
 MathObject::MathObject(VM& vm, Structure* structure)
     : JSNonFinalObject(vm, structure)
@@ -85,48 +86,50 @@ void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
 
-    putDirectWithoutTransition(vm, Identifier(&vm, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
-    putDirectWithoutTransition(vm, Identifier(&vm, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
-
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "abs"), 1, mathProtoFuncAbs, AbsIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "acos"), 1, mathProtoFuncACos, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "asin"), 1, mathProtoFuncASin, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "atan"), 1, mathProtoFuncATan, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "acosh"), 1, mathProtoFuncACosh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "asinh"), 1, mathProtoFuncASinh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "atanh"), 1, mathProtoFuncATanh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "cbrt"), 1, mathProtoFuncCbrt, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "cosh"), 1, mathProtoFuncCosh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "expm1"), 1, mathProtoFuncExpm1, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "fround"), 1, mathProtoFuncFround, FRoundIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log10"), 1, mathProtoFuncLog10, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log1p"), 1, mathProtoFuncLog1p, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log2"), 1, mathProtoFuncLog2, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "max"), 2, mathProtoFuncMax, MaxIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "random"), 0, mathProtoFuncRandom, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sinh"), 1, mathProtoFuncSinh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "tan"), 1, mathProtoFuncTan, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "tanh"), 1, mathProtoFuncTanh, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "trunc"), 1, mathProtoFuncTrunc, NoIntrinsic, DontEnum | Function);
-    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "imul"), 1, mathProtoFuncIMul, IMulIntrinsic, DontEnum | Function);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
+
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "abs"), 1, mathProtoFuncAbs, AbsIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acos"), 1, mathProtoFuncACos, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asin"), 1, mathProtoFuncASin, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan"), 1, mathProtoFuncATan, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acosh"), 1, mathProtoFuncACosh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asinh"), 1, mathProtoFuncASinh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atanh"), 1, mathProtoFuncATanh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cbrt"), 1, mathProtoFuncCbrt, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "clz32"), 1, mathProtoFuncClz32, Clz32Intrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cosh"), 1, mathProtoFuncCosh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "expm1"), 1, mathProtoFuncExpm1, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "fround"), 1, mathProtoFuncFround, FRoundIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log10"), 1, mathProtoFuncLog10, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log1p"), 1, mathProtoFuncLog1p, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log2"), 1, mathProtoFuncLog2, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "max"), 2, mathProtoFuncMax, MaxIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "random"), 0, mathProtoFuncRandom, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sign"), 1, mathProtoFuncSign, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sinh"), 1, mathProtoFuncSinh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tan"), 1, mathProtoFuncTan, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tanh"), 1, mathProtoFuncTanh, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "trunc"), 1, mathProtoFuncTrunc, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "imul"), 2, mathProtoFuncIMul, IMulIntrinsic, DontEnum | Function);
 }
 
 // ------------------------------ Functions --------------------------------
@@ -163,6 +166,14 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec)
     return JSValue::encode(jsNumber(ceil(exec->argument(0).toNumber(exec))));
 }
 
+EncodedJSValue JSC_HOST_CALL mathProtoFuncClz32(ExecState* exec)
+{
+    uint32_t value = exec->argument(0).toUInt32(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
+    return JSValue::encode(JSValue(clz32(value)));
+}
+
 EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec)
 {
     return JSValue::encode(jsDoubleNumber(cos(exec->argument(0).toNumber(exec))));
@@ -240,43 +251,6 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec)
     return JSValue::encode(jsNumber(result));
 }
 
-#if PLATFORM(IOS) && CPU(ARM_THUMB2)
-
-static double fdlibmPow(double x, double y);
-
-static ALWAYS_INLINE bool isDenormal(double x)
-{
-        static const uint64_t signbit = 0x8000000000000000ULL;
-        static const uint64_t minNormal = 0x0001000000000000ULL;
-        return (bitwise_cast<uint64_t>(x) & ~signbit) - 1 < minNormal - 1;
-}
-
-static ALWAYS_INLINE bool isEdgeCase(double x)
-{
-        static const uint64_t signbit = 0x8000000000000000ULL;
-        static const uint64_t infinity = 0x7fffffffffffffffULL;
-        return (bitwise_cast<uint64_t>(x) & ~signbit) - 1 >= infinity - 1;
-}
-
-static ALWAYS_INLINE double mathPow(double x, double y)
-{
-    if (!isDenormal(x) && !isDenormal(y)) {
-        double libmResult = pow(x,y);
-        if (libmResult || isEdgeCase(x) || isEdgeCase(y))
-            return libmResult;
-    }
-    return fdlibmPow(x,y);
-}
-
-#else
-
-ALWAYS_INLINE double mathPow(double x, double y)
-{
-    return pow(x, y);
-}
-
-#endif
-
 EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec)
 {
     // ECMA 15.8.2.1.13
@@ -284,11 +258,7 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec)
     double arg = exec->argument(0).toNumber(exec);
     double arg2 = exec->argument(1).toNumber(exec);
 
-    if (std::isnan(arg2))
-        return JSValue::encode(jsNaN());
-    if (std::isinf(arg2) && fabs(arg) == 1)
-        return JSValue::encode(jsNaN());
-    return JSValue::encode(jsNumber(mathPow(arg, arg2)));
+    return JSValue::encode(JSValue(operationMathPow(arg, arg2)));
 }
 
 EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec)
@@ -297,10 +267,18 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec)
 }
 
 EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec)
+{
+    return JSValue::encode(jsNumber(jsRound(exec->argument(0).toNumber(exec))));
+}
+
+EncodedJSValue JSC_HOST_CALL mathProtoFuncSign(ExecState* exec)
 {
     double arg = exec->argument(0).toNumber(exec);
-    double integer = ceil(arg);
-    return JSValue::encode(jsNumber(integer - (integer - arg > 0.5)));
+    if (std::isnan(arg))
+        return JSValue::encode(jsNaN());
+    if (!arg)
+        return JSValue::encode(std::signbit(arg) ? jsNumber(-0.0) : jsNumber(0));
+    return JSValue::encode(jsNumber(std::signbit(arg) ? -1 : 1));
 }
 
 EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec)
@@ -395,354 +373,4 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*exec)
     return JSValue::encode(jsNumber(exec->argument(0).toIntegerPreserveNaN(exec)));
 }
 
-
-#if PLATFORM(IOS) && CPU(ARM_THUMB2)
-
-// The following code is taken from netlib.org:
-//   http://www.netlib.org/fdlibm/fdlibm.h
-//   http://www.netlib.org/fdlibm/e_pow.c
-//   http://www.netlib.org/fdlibm/s_scalbn.c
-//
-// And was originally distributed under the following license:
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice 
- * is preserved.
- * ====================================================
- */
-/*
- * ====================================================
- * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice 
- * is preserved.
- * ====================================================
- */
-
-/* __ieee754_pow(x,y) return x**y
- *
- *              n
- * Method:  Let x =  2   * (1+f)
- *    1. Compute and return log2(x) in two pieces:
- *        log2(x) = w1 + w2,
- *       where w1 has 53-24 = 29 bit trailing zeros.
- *    2. Perform y*log2(x) = n+y' by simulating muti-precision 
- *       arithmetic, where |y'|<=0.5.
- *    3. Return x**y = 2**n*exp(y'*log2)
- *
- * Special cases:
- *    1.  (anything) ** 0  is 1
- *    2.  (anything) ** 1  is itself
- *    3.  (anything) ** NAN is NAN
- *    4.  NAN ** (anything except 0) is NAN
- *    5.  +-(|x| > 1) **  +INF is +INF
- *    6.  +-(|x| > 1) **  -INF is +0
- *    7.  +-(|x| < 1) **  +INF is +0
- *    8.  +-(|x| < 1) **  -INF is +INF
- *    9.  +-1         ** +-INF is NAN
- *    10. +0 ** (+anything except 0, NAN)               is +0
- *    11. -0 ** (+anything except 0, NAN, odd integer)  is +0
- *    12. +0 ** (-anything except 0, NAN)               is +INF
- *    13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
- *    14. -0 ** (odd integer) = -( +0 ** (odd integer) )
- *    15. +INF ** (+anything except 0,NAN) is +INF
- *    16. +INF ** (-anything except 0,NAN) is +0
- *    17. -INF ** (anything)  = -0 ** (-anything)
- *    18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
- *    19. (-anything except 0 and inf) ** (non-integer) is NAN
- *
- * Accuracy:
- *    pow(x,y) returns x**y nearly rounded. In particular
- *            pow(integer,integer)
- *    always returns the correct integer provided it is 
- *    representable.
- *
- * Constants :
- * The hexadecimal values are the intended ones for the following 
- * constants. The decimal values may be used, provided that the 
- * compiler will convert from decimal to binary accurately enough 
- * to produce the hexadecimal values shown.
- */
-
-#define __HI(x) *(1+(int*)&x)
-#define __LO(x) *(int*)&x
-
-static const double
-bp[] = {1.0, 1.5,},
-dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
-dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
-zero    =  0.0,
-one    =  1.0,
-two    =  2.0,
-two53    =  9007199254740992.0,    /* 0x43400000, 0x00000000 */
-huge    =  1.0e300,
-tiny    =  1.0e-300,
-        /* for scalbn */
-two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-    /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
-L1  =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
-L2  =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
-L3  =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
-L4  =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
-L5  =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
-L6  =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
-P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
-P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
-P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
-P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
-P5   =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
-lg2  =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
-lg2_h  =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
-lg2_l  = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
-ovt =  8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
-cp    =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
-cp_h  =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
-cp_l  = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
-ivln2    =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
-ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
-ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
-
-inline double fdlibmScalbn (double x, int n)
-{
-    int  k,hx,lx;
-    hx = __HI(x);
-    lx = __LO(x);
-        k = (hx&0x7ff00000)>>20;        /* extract exponent */
-        if (k==0) {                /* 0 or subnormal x */
-            if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
-        x *= two54; 
-        hx = __HI(x);
-        k = ((hx&0x7ff00000)>>20) - 54; 
-            if (n< -50000) return tiny*x;     /*underflow*/
-        }
-        if (k==0x7ff) return x+x;        /* NaN or Inf */
-        k = k+n; 
-        if (k >  0x7fe) return huge*copysign(huge,x); /* overflow  */
-        if (k > 0)                 /* normal result */
-        {__HI(x) = (hx&0x800fffff)|(k<<20); return x;}
-        if (k <= -54) {
-            if (n > 50000)     /* in case integer overflow in n+k */
-        return huge*copysign(huge,x);    /*overflow*/
-        else return tiny*copysign(tiny,x);     /*underflow*/
-        }
-        k += 54;                /* subnormal result */
-        __HI(x) = (hx&0x800fffff)|(k<<20);
-        return x*twom54;
-}
-
-double fdlibmPow(double x, double y)
-{
-    double z,ax,z_h,z_l,p_h,p_l;
-    double y1,t1,t2,r,s,t,u,v,w;
-    int i0,i1,i,j,k,yisint,n;
-    int hx,hy,ix,iy;
-    unsigned lx,ly;
-
-    i0 = ((*(int*)&one)>>29)^1; i1=1-i0;
-    hx = __HI(x); lx = __LO(x);
-    hy = __HI(y); ly = __LO(y);
-    ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
-
-    /* y==zero: x**0 = 1 */
-    if((iy|ly)==0) return one;     
-
-    /* +-NaN return x+y */
-    if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
-       iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) 
-        return x+y;    
-
-    /* determine if y is an odd int when x < 0
-     * yisint = 0    ... y is not an integer
-     * yisint = 1    ... y is an odd int
-     * yisint = 2    ... y is an even int
-     */
-    yisint  = 0;
-    if(hx<0) {    
-        if(iy>=0x43400000) yisint = 2; /* even integer y */
-        else if(iy>=0x3ff00000) {
-        k = (iy>>20)-0x3ff;       /* exponent */
-        if(k>20) {
-            j = ly>>(52-k);
-            if(static_cast<unsigned>(j<<(52-k))==ly) yisint = 2-(j&1);
-        } else if(ly==0) {
-            j = iy>>(20-k);
-            if((j<<(20-k))==iy) yisint = 2-(j&1);
-        }
-        }        
-    } 
-
-    /* special value of y */
-    if(ly==0) {     
-        if (iy==0x7ff00000) {    /* y is +-inf */
-            if(((ix-0x3ff00000)|lx)==0)
-            return  y - y;    /* inf**+-1 is NaN */
-            else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
-            return (hy>=0)? y: zero;
-            else            /* (|x|<1)**-,+inf = inf,0 */
-            return (hy<0)?-y: zero;
-        } 
-        if(iy==0x3ff00000) {    /* y is  +-1 */
-        if(hy<0) return one/x; else return x;
-        }
-        if(hy==0x40000000) return x*x; /* y is  2 */
-        if(hy==0x3fe00000) {    /* y is  0.5 */
-        if(hx>=0)    /* x >= +0 */
-        return sqrt(x);    
-        }
-    }
-
-    ax   = fabs(x);
-    /* special value of x */
-    if(lx==0) {
-        if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
-        z = ax;            /*x is +-0,+-inf,+-1*/
-        if(hy<0) z = one/z;    /* z = (1/|x|) */
-        if(hx<0) {
-            if(((ix-0x3ff00000)|yisint)==0) {
-            z = (z-z)/(z-z); /* (-1)**non-int is NaN */
-            } else if(yisint==1) 
-            z = -z;        /* (x<0)**odd = -(|x|**odd) */
-        }
-        return z;
-        }
-    }
-    
-    n = (hx>>31)+1;
-
-    /* (x<0)**(non-int) is NaN */
-    if((n|yisint)==0) return (x-x)/(x-x);
-
-    s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
-    if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
-
-    /* |y| is huge */
-    if(iy>0x41e00000) { /* if |y| > 2**31 */
-        if(iy>0x43f00000){    /* if |y| > 2**64, must o/uflow */
-        if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
-        if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
-        }
-    /* over/underflow if x is not close to one */
-        if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
-        if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
-    /* now |1-x| is tiny <= 2**-20, suffice to compute 
-       log(x) by x-x^2/2+x^3/3-x^4/4 */
-        t = ax-one;        /* t has 20 trailing zeros */
-        w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
-        u = ivln2_h*t;    /* ivln2_h has 21 sig. bits */
-        v = t*ivln2_l-w*ivln2;
-        t1 = u+v;
-        __LO(t1) = 0;
-        t2 = v-(t1-u);
-    } else {
-        double ss,s2,s_h,s_l,t_h,t_l;
-        n = 0;
-    /* take care subnormal number */
-        if(ix<0x00100000)
-        {ax *= two53; n -= 53; ix = __HI(ax); }
-        n  += ((ix)>>20)-0x3ff;
-        j  = ix&0x000fffff;
-    /* determine interval */
-        ix = j|0x3ff00000;        /* normalize ix */
-        if(j<=0x3988E) k=0;        /* |x|<sqrt(3/2) */
-        else if(j<0xBB67A) k=1;    /* |x|<sqrt(3)   */
-        else {k=0;n+=1;ix -= 0x00100000;}
-        __HI(ax) = ix;
-
-    /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
-        u = ax-bp[k];        /* bp[0]=1.0, bp[1]=1.5 */
-        v = one/(ax+bp[k]);
-        ss = u*v;
-        s_h = ss;
-        __LO(s_h) = 0;
-    /* t_h=ax+bp[k] High */
-        t_h = zero;
-        __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18); 
-        t_l = ax - (t_h-bp[k]);
-        s_l = v*((u-s_h*t_h)-s_h*t_l);
-    /* compute log(ax) */
-        s2 = ss*ss;
-        r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
-        r += s_l*(s_h+ss);
-        s2  = s_h*s_h;
-        t_h = 3.0+s2+r;
-        __LO(t_h) = 0;
-        t_l = r-((t_h-3.0)-s2);
-    /* u+v = ss*(1+...) */
-        u = s_h*t_h;
-        v = s_l*t_h+t_l*ss;
-    /* 2/(3log2)*(ss+...) */
-        p_h = u+v;
-        __LO(p_h) = 0;
-        p_l = v-(p_h-u);
-        z_h = cp_h*p_h;        /* cp_h+cp_l = 2/(3*log2) */
-        z_l = cp_l*p_h+p_l*cp+dp_l[k];
-    /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
-        t = (double)n;
-        t1 = (((z_h+z_l)+dp_h[k])+t);
-        __LO(t1) = 0;
-        t2 = z_l-(((t1-t)-dp_h[k])-z_h);
-    }
-
-    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
-    y1  = y;
-    __LO(y1) = 0;
-    p_l = (y-y1)*t1+y*t2;
-    p_h = y1*t1;
-    z = p_l+p_h;
-    j = __HI(z);
-    i = __LO(z);
-    if (j>=0x40900000) {                /* z >= 1024 */
-        if(((j-0x40900000)|i)!=0)            /* if z > 1024 */
-        return s*huge*huge;            /* overflow */
-        else {
-        if(p_l+ovt>z-p_h) return s*huge*huge;    /* overflow */
-        }
-    } else if((j&0x7fffffff)>=0x4090cc00 ) {    /* z <= -1075 */
-        if(((j-0xc090cc00)|i)!=0)         /* z < -1075 */
-        return s*tiny*tiny;        /* underflow */
-        else {
-        if(p_l<=z-p_h) return s*tiny*tiny;    /* underflow */
-        }
-    }
-    /*
-     * compute 2**(p_h+p_l)
-     */
-    i = j&0x7fffffff;
-    k = (i>>20)-0x3ff;
-    n = 0;
-    if(i>0x3fe00000) {        /* if |z| > 0.5, set n = [z+0.5] */
-        n = j+(0x00100000>>(k+1));
-        k = ((n&0x7fffffff)>>20)-0x3ff;    /* new k for n */
-        t = zero;
-        __HI(t) = (n&~(0x000fffff>>k));
-        n = ((n&0x000fffff)|0x00100000)>>(20-k);
-        if(j<0) n = -n;
-        p_h -= t;
-    } 
-    t = p_l+p_h;
-    __LO(t) = 0;
-    u = t*lg2_h;
-    v = (p_l-(t-p_h))*lg2+t*lg2_l;
-    z = u+v;
-    w = v-(z-u);
-    t  = z*z;
-    t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
-    r  = (z*t1)/(t1-two)-(w+z*w);
-    z  = one-(r-z);
-    j  = __HI(z);
-    j += (n<<20);
-    if((j>>20)<=0) z = fdlibmScalbn(z,n);    /* subnormal output */
-    else __HI(z) += (n<<20);
-    return s*z;
-}
-
-#endif
-
 } // namespace JSC
index 4b2a5bbece04dd2d30ce25d5e3775a3fe289e25a..9d1c181c0f1efaa20b35f7e85d8dfadbff46379b 100644 (file)
 
 namespace JSC {
 
-    class MathObject : public JSNonFinalObject {
-    private:
-        MathObject(VM&, Structure*);
-
-    public:
-        typedef JSNonFinalObject Base;
-
-        static MathObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-        {
-            MathObject* object = new (NotNull, allocateCell<MathObject>(vm.heap)) MathObject(vm, structure);
-            object->finishCreation(vm, globalObject);
-            return object;
-        }
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        void finishCreation(VM&, JSGlobalObject*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
-    };
+class MathObject : public JSNonFinalObject {
+private:
+    MathObject(VM&, Structure*);
+
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static MathObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        MathObject* object = new (NotNull, allocateCell<MathObject>(vm.heap)) MathObject(vm, structure);
+        object->finishCreation(vm, globalObject);
+        return object;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
+};
+
+EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*);
+EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*);
 
 } // namespace JSC
 
diff --git a/runtime/NameConstructor.cpp b/runtime/NameConstructor.cpp
deleted file mode 100644 (file)
index 3926883..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "NameConstructor.h"
-
-#include "JSGlobalObject.h"
-#include "NamePrototype.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NameConstructor);
-
-const ClassInfo NameConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameConstructor) };
-
-NameConstructor::NameConstructor(VM& vm, Structure* structure)
-    : InternalFunction(vm, structure)
-{
-}
-
-void NameConstructor::finishCreation(VM& vm, NamePrototype* prototype)
-{
-    Base::finishCreation(vm, prototype->classInfo()->className);
-    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
-    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
-}
-
-static EncodedJSValue JSC_HOST_CALL constructPrivateName(ExecState* exec)
-{
-    JSValue publicName = exec->argument(0);
-    return JSValue::encode(NameInstance::create(exec->vm(), exec->lexicalGlobalObject()->privateNameStructure(), publicName.toString(exec)));
-}
-
-ConstructType NameConstructor::getConstructData(JSCell*, ConstructData& constructData)
-{
-    constructData.native.function = constructPrivateName;
-    return ConstructTypeHost;
-}
-
-CallType NameConstructor::getCallData(JSCell*, CallData& callData)
-{
-    callData.native.function = constructPrivateName;
-    return CallTypeHost;
-}
-
-} // namespace JSC
diff --git a/runtime/NameConstructor.h b/runtime/NameConstructor.h
deleted file mode 100644 (file)
index 8e20f28..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NameConstructor_h
-#define NameConstructor_h
-
-#include "InternalFunction.h"
-#include "NameInstance.h"
-
-namespace JSC {
-
-class NamePrototype;
-
-class NameConstructor : public InternalFunction {
-public:
-    typedef InternalFunction Base;
-
-    static NameConstructor* create(VM& vm, Structure* structure, NamePrototype* prototype)
-    {
-        NameConstructor* constructor = new (NotNull, allocateCell<NameConstructor>(vm.heap)) NameConstructor(vm, structure);
-        constructor->finishCreation(vm, prototype);
-        return constructor;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-    { 
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
-    }
-
-protected:
-    void finishCreation(VM&, NamePrototype*);
-    
-private:
-    NameConstructor(VM&, Structure*);
-    static ConstructType getConstructData(JSCell*, ConstructData&);
-    static CallType getCallData(JSCell*, CallData&);
-};
-
-} // namespace JSC
-
-#endif // NameConstructor_h
diff --git a/runtime/NameInstance.cpp b/runtime/NameInstance.cpp
deleted file mode 100644 (file)
index cc6ce9b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "NameInstance.h"
-
-#include "JSScope.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo NameInstance::s_info = { "Name", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameInstance) };
-
-NameInstance::NameInstance(VM& vm, Structure* structure, JSString* nameString)
-    : Base(vm, structure)
-{
-    m_nameString.set(vm, this, nameString);
-}
-
-void NameInstance::destroy(JSCell* cell)
-{
-    static_cast<NameInstance*>(cell)->NameInstance::~NameInstance();
-}
-
-} // namespace JSC
diff --git a/runtime/NameInstance.h b/runtime/NameInstance.h
deleted file mode 100644 (file)
index 55842d5..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NameInstance_h
-#define NameInstance_h
-
-#include "JSDestructibleObject.h"
-#include "PrivateName.h"
-
-namespace JSC {
-
-class NameInstance : public JSDestructibleObject {
-public:
-    typedef JSDestructibleObject Base;
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), info());
-    }
-
-    static NameInstance* create(VM& vm, Structure* structure, JSString* nameString)
-    {
-        NameInstance* name = new (NotNull, allocateCell<NameInstance>(vm.heap)) NameInstance(vm, structure, nameString);
-        name->finishCreation(vm);
-        return name;
-    }
-
-    const PrivateName& privateName() { return m_privateName; }
-    JSString* nameString() { return m_nameString.get(); }
-
-protected:
-    static void destroy(JSCell*);
-
-    NameInstance(VM&, Structure*, JSString*);
-
-    void finishCreation(VM& vm)
-    {
-        Base::finishCreation(vm);
-        ASSERT(inherits(info()));
-    }
-
-    PrivateName m_privateName;
-    WriteBarrier<JSString> m_nameString;
-};
-
-inline bool isName(JSValue v)
-{
-    return v.isCell() && v.asCell()->type() == NameInstanceType;
-}
-
-} // namespace JSC
-
-#endif // NameInstance_h
diff --git a/runtime/NamePrototype.cpp b/runtime/NamePrototype.cpp
deleted file mode 100644 (file)
index d030fd0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "NamePrototype.h"
-
-#include "Error.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-static EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState*);
-
-}
-
-#include "NamePrototype.lut.h"
-
-namespace JSC {
-
-const ClassInfo NamePrototype::s_info = { "Name", &Base::s_info, 0, ExecState::privateNamePrototypeTable, CREATE_METHOD_TABLE(NamePrototype) };
-
-/* Source for NamePrototype.lut.h
-@begin privateNamePrototypeTable
-  toString          privateNameProtoFuncToString         DontEnum|Function 0
-@end
-*/
-
-NamePrototype::NamePrototype(ExecState* exec, Structure* structure)
-    : Base(exec->vm(), structure, jsEmptyString(exec))
-{
-}
-
-void NamePrototype::finishCreation(VM& vm)
-{
-    Base::finishCreation(vm);
-    ASSERT(inherits(info()));
-}
-
-bool NamePrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
-{
-    return getStaticFunctionSlot<Base>(exec, ExecState::privateNamePrototypeTable(exec->vm()), jsCast<NamePrototype*>(object), propertyName, slot);
-}
-
-// ------------------------------ Functions ---------------------------
-
-EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState* exec)
-{
-    JSValue thisValue = exec->thisValue();
-    if (!thisValue.isObject())
-        return throwVMTypeError(exec);
-
-    JSObject* thisObject = asObject(thisValue);
-    if (!thisObject->inherits(NameInstance::info()))
-        return throwVMTypeError(exec);
-
-    return JSValue::encode(jsCast<NameInstance*>(thisObject)->nameString());
-}
-
-} // namespace JSC
diff --git a/runtime/NamePrototype.h b/runtime/NamePrototype.h
deleted file mode 100644 (file)
index d4b947f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NamePrototype_h
-#define NamePrototype_h
-
-#include "NameInstance.h"
-
-namespace JSC {
-
-class NamePrototype : public NameInstance {
-public:
-    typedef NameInstance Base;
-
-    static NamePrototype* create(ExecState* exec, Structure* structure)
-    {
-        VM& vm = exec->vm();
-        NamePrototype* prototype = new (NotNull, allocateCell<NamePrototype>(vm.heap)) NamePrototype(exec, structure);
-        prototype->finishCreation(vm);
-        return prototype;
-    }
-    
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), info());
-    }
-
-protected:
-    NamePrototype(ExecState*, Structure*);
-    void finishCreation(VM&);
-
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NameInstance::StructureFlags;
-
-private:
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-};
-
-} // namespace JSC
-
-#endif // NamePrototype_h
index 62600555b4c62cd0c5f3f43f8b152f39475cdefa..3fb58a3289b39c95ed81dd61c67a729680564578 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NativeErrorConstructor);
 
-const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(NativeErrorConstructor) };
+const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(NativeErrorConstructor) };
 
 NativeErrorConstructor::NativeErrorConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
@@ -56,10 +56,7 @@ void NativeErrorConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     NativeErrorConstructor* thisObject = jsCast<NativeErrorConstructor*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    InternalFunction::visitChildren(thisObject, visitor);
+    Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_errorStructure);
 }
 
@@ -68,10 +65,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::constructWithNativeErrorConstructor(Ex
     JSValue message = exec->argument(0);
     Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
     ASSERT(errorStructure);
-    Vector<StackFrame> stackTrace;
-    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
-    stackTrace.remove(0);
-    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
 }
 
 ConstructType NativeErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -84,10 +78,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::callNativeErrorConstructor(ExecState*
 {
     JSValue message = exec->argument(0);
     Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
-    Vector<StackFrame> stackTrace;
-    exec->vm().interpreter->getStackTrace(stackTrace, std::numeric_limits<size_t>::max());
-    stackTrace.remove(0);
-    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, stackTrace));
+    return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
 }
 
 CallType NativeErrorConstructor::getCallData(JSCell*, CallData& callData)
index 438a3afb9bb0f6412c97932230c88710961f5467..b582ef392109294e543ccc8eab3e6385710757db 100644 (file)
 
 namespace JSC {
 
-    class ErrorInstance;
-    class FunctionPrototype;
-    class NativeErrorPrototype;
+class ErrorInstance;
+class FunctionPrototype;
+class NativeErrorPrototype;
 
-    class NativeErrorConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class NativeErrorConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
 
-        static NativeErrorConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name)
-        {
-            NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
-            constructor->finishCreation(vm, globalObject, prototypeStructure, name);
-            return constructor;
-        }
-        
-        DECLARE_INFO;
+    static NativeErrorConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name)
+    {
+        NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
+        constructor->finishCreation(vm, globalObject, prototypeStructure, name);
+        return constructor;
+    }
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    DECLARE_INFO;
 
-        Structure* errorStructure() { return m_errorStructure.get(); }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-    protected:
-        void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
+    Structure* errorStructure() { return m_errorStructure.get(); }
 
-    private:
-        NativeErrorConstructor(VM&, Structure*);
-        static const unsigned StructureFlags = OverridesVisitChildren | InternalFunction::StructureFlags;
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-        static void visitChildren(JSCell*, SlotVisitor&);
+protected:
+    void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
 
-        WriteBarrier<Structure> m_errorStructure;
-    };
+private:
+    NativeErrorConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    WriteBarrier<Structure> m_errorStructure;
+};
 
 } // namespace JSC
 
index 9326c5ccbec50327b5824aa6b656f063b3249644..5812e63639401810b04891574c3c267a3aa86d83 100644 (file)
 #include "ErrorPrototype.h"
 
 namespace JSC {
-    class NativeErrorConstructor;
-
-    class NativeErrorPrototype : public ErrorPrototype {
-    private:
-        NativeErrorPrototype(VM&, Structure*);
-    
-    public:
-        typedef ErrorPrototype Base;
-
-        static NativeErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, const String& name, NativeErrorConstructor* constructor)
-        {
-            NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(vm.heap)) NativeErrorPrototype(vm, structure);
-            prototype->finishCreation(vm, globalObject, name, constructor);
-            return prototype;
-        }
-
-    protected:
-        void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*);
-    };
+
+class NativeErrorConstructor;
+
+class NativeErrorPrototype : public ErrorPrototype {
+private:
+    NativeErrorPrototype(VM&, Structure*);
+
+public:
+    typedef ErrorPrototype Base;
+
+    static NativeErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, const String& name, NativeErrorConstructor* constructor)
+    {
+        NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(vm.heap)) NativeErrorPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject, name, constructor);
+        return prototype;
+    }
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*);
+};
 
 } // namespace JSC
 
diff --git a/runtime/NullGetterFunction.cpp b/runtime/NullGetterFunction.cpp
new file mode 100644 (file)
index 0000000..4243e5c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NullGetterFunction.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo NullGetterFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(NullGetterFunction) };
+
+static EncodedJSValue JSC_HOST_CALL callReturnUndefined(ExecState*)
+{
+    return JSValue::encode(jsUndefined());
+}
+
+CallType NullGetterFunction::getCallData(JSCell*, CallData& callData)
+{
+    callData.native.function = callReturnUndefined;
+    return CallTypeHost;
+}
+
+ConstructType NullGetterFunction::getConstructData(JSCell*, ConstructData&)
+{
+    return ConstructTypeNone;
+}
+
+}
diff --git a/runtime/NullGetterFunction.h b/runtime/NullGetterFunction.h
new file mode 100644 (file)
index 0000000..d95feb7
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NullGetterFunction_h
+#define  NullGetterFunction_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+class NullGetterFunction : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+
+    static NullGetterFunction* create(VM& vm, Structure* structure)
+    {
+        NullGetterFunction* function = new (NotNull, allocateCell< NullGetterFunction>(vm.heap))  NullGetterFunction(vm, structure);
+        function->finishCreation(vm, String());
+        return function;
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    NullGetterFunction(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
+
+}
+
+#endif // NullGetterFunction_h
diff --git a/runtime/NullSetterFunction.cpp b/runtime/NullSetterFunction.cpp
new file mode 100644 (file)
index 0000000..118fb15
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NullSetterFunction.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "JSCJSValueInlines.h"
+#include "StackVisitor.h"
+
+namespace JSC {
+
+const ClassInfo NullSetterFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(NullSetterFunction) };
+
+
+class GetCallerStrictnessFunctor {
+public:
+    GetCallerStrictnessFunctor()
+        : m_iterations(0)
+        , m_callerIsStrict(false)
+    {
+    }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        ++m_iterations;
+        if (m_iterations < 2)
+            return StackVisitor::Continue;
+
+        CodeBlock* codeBlock = visitor->codeBlock();
+        m_callerIsStrict = codeBlock && codeBlock->isStrictMode();
+        return StackVisitor::Done;
+    }
+
+    bool callerIsStrict() const { return m_callerIsStrict; }
+
+private:
+    int m_iterations;
+    bool m_callerIsStrict;
+};
+
+static bool callerIsStrict(ExecState* exec)
+{
+    GetCallerStrictnessFunctor iter;
+    exec->iterate(iter);
+    return iter.callerIsStrict();
+}
+
+static EncodedJSValue JSC_HOST_CALL callReturnUndefined(ExecState* exec)
+{
+    if (callerIsStrict(exec))
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Setting a property that has only a getter")));
+    return JSValue::encode(jsUndefined());
+}
+
+CallType NullSetterFunction::getCallData(JSCell*, CallData& callData)
+{
+    callData.native.function = callReturnUndefined;
+    return CallTypeHost;
+}
+
+ConstructType NullSetterFunction::getConstructData(JSCell*, ConstructData&)
+{
+    return ConstructTypeNone;
+}
+
+}
diff --git a/runtime/NullSetterFunction.h b/runtime/NullSetterFunction.h
new file mode 100644 (file)
index 0000000..ccdc6f1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NullSetterFunction_h
+#define NullSetterFunction_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+class NullSetterFunction : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+
+    static NullSetterFunction* create(VM& vm, Structure* structure)
+    {
+        NullSetterFunction* function = new (NotNull, allocateCell< NullSetterFunction>(vm.heap))  NullSetterFunction(vm, structure);
+        function->finishCreation(vm, String());
+        return function;
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    NullSetterFunction(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
+
+}
+
+#endif // NullSetterFunction_h
index 04c509838e40c13a716cc233e8175753767891ee..0a21512d3b1444ad3e9e4069c6832f29cf3a01dd 100644 (file)
 #include "NumberObject.h"
 #include "NumberPrototype.h"
 #include "JSCInlines.h"
+#include "JSGlobalObjectFunctions.h"
 
 namespace JSC {
 
-static EncodedJSValue numberConstructorNaNValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorNegInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorPosInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorMaxValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorMinValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsFinite(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsInteger(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsNaN(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsSafeInteger(ExecState*);
 
 } // namespace JSC
 
-#include "NumberConstructor.lut.h"
-
 namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NumberConstructor);
 
-const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::numberConstructorTable, CREATE_METHOD_TABLE(NumberConstructor) };
-
-/* Source for NumberConstructor.lut.h
-@begin numberConstructorTable
-   NaN                   numberConstructorNaNValue       DontEnum|DontDelete|ReadOnly
-   NEGATIVE_INFINITY     numberConstructorNegInfinity    DontEnum|DontDelete|ReadOnly
-   POSITIVE_INFINITY     numberConstructorPosInfinity    DontEnum|DontDelete|ReadOnly
-   MAX_VALUE             numberConstructorMaxValue       DontEnum|DontDelete|ReadOnly
-   MIN_VALUE             numberConstructorMinValue       DontEnum|DontDelete|ReadOnly
-@end
-*/
+const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(NumberConstructor) };
 
 NumberConstructor::NumberConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
@@ -70,36 +58,22 @@ void NumberConstructor::finishCreation(VM& vm, NumberPrototype* numberPrototype)
 
     // no. of arguments for constructor
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
-}
-
-bool NumberConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberConstructorTable(exec->vm()), jsCast<NumberConstructor*>(object), propertyName, slot);
-}
-
-static EncodedJSValue numberConstructorNaNValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNaN());
-}
-
-static EncodedJSValue numberConstructorNegInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(-std::numeric_limits<double>::infinity()));
-}
 
-static EncodedJSValue numberConstructorPosInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(std::numeric_limits<double>::infinity()));
-}
-
-static EncodedJSValue numberConstructorMaxValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(1.7976931348623157E+308));
-}
-
-static EncodedJSValue numberConstructorMinValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(5E-324));
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "EPSILON"), jsDoubleNumber(std::numeric_limits<double>::epsilon()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "MAX_VALUE"), jsDoubleNumber(1.7976931348623157E+308), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "MIN_VALUE"), jsDoubleNumber(5E-324), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "MAX_SAFE_INTEGER"), jsDoubleNumber(9007199254740991.0), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "MIN_SAFE_INTEGER"), jsDoubleNumber(-9007199254740991.0), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "NEGATIVE_INFINITY"), jsDoubleNumber(-std::numeric_limits<double>::infinity()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "POSITIVE_INFINITY"), jsDoubleNumber(std::numeric_limits<double>::infinity()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "NaN"), jsNaN(), DontDelete | DontEnum | ReadOnly);
+
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier::fromString(&vm, "isFinite"), 1, numberConstructorFuncIsFinite, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier::fromString(&vm, "isInteger"), 1, numberConstructorFuncIsInteger, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier::fromString(&vm, "isNaN"), 1, numberConstructorFuncIsNaN, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier::fromString(&vm, "isSafeInteger"), 1, numberConstructorFuncIsSafeInteger, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier::fromString(&vm, "parseFloat"), 1, globalFuncParseFloat, NoIntrinsic, DontEnum | Function);
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "parseInt"), numberPrototype->globalObject()->parseIntFunction(), DontEnum | Function);
 }
 
 // ECMA 15.7.1
@@ -129,4 +103,50 @@ CallType NumberConstructor::getCallData(JSCell*, CallData& callData)
     return CallTypeHost;
 }
 
+// ECMA-262 20.1.2.2
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsFinite(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    return JSValue::encode(jsBoolean(argument.isNumber() && (argument.isInt32() || std::isfinite(argument.asDouble()))));
+}
+
+// ECMA-262 20.1.2.3
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsInteger(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    bool isInteger;
+    if (argument.isInt32())
+        isInteger = true;
+    else if (!argument.isDouble())
+        isInteger = false;
+    else {
+        double number = argument.asDouble();
+        isInteger = std::isfinite(number) && trunc(number) == number;
+    }
+    return JSValue::encode(jsBoolean(isInteger));
+}
+
+// ECMA-262 20.1.2.4
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsNaN(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    return JSValue::encode(jsBoolean(argument.isDouble() && std::isnan(argument.asDouble())));
+}
+
+// ECMA-262 20.1.2.5
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsSafeInteger(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    bool isInteger;
+    if (argument.isInt32())
+        isInteger = true;
+    else if (!argument.isDouble())
+        isInteger = false;
+    else {
+        double number = argument.asDouble();
+        isInteger = trunc(number) == number && std::abs(number) <= 9007199254740991.0;
+    }
+    return JSValue::encode(jsBoolean(isInteger));
+}
+
 } // namespace JSC
index 6c8ed89fecdc04f00ee324879a58a3e97646003b..f8b1f7f443703ab4198dd4321e209dfe66882a3c 100644 (file)
 
 namespace JSC {
 
-    class NumberPrototype;
-
-    class NumberConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
-
-        static NumberConstructor* create(VM& vm, Structure* structure, NumberPrototype* numberPrototype)
-        {
-            NumberConstructor* constructor = new (NotNull, allocateCell<NumberConstructor>(vm.heap)) NumberConstructor(vm, structure);
-            constructor->finishCreation(vm, numberPrototype);
-            return constructor;
-        }
-
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-        JSValue getValueProperty(ExecState*, int token) const;
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 
-        { 
-            return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info()); 
-        }
-
-        enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
-
-    protected:
-        void finishCreation(VM&, NumberPrototype*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
-
-    private:
-        NumberConstructor(VM&, Structure*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-    };
+class NumberPrototype;
+
+class NumberConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | ImplementsHasInstance;
+
+    static NumberConstructor* create(VM& vm, Structure* structure, NumberPrototype* numberPrototype)
+    {
+        NumberConstructor* constructor = new (NotNull, allocateCell<NumberConstructor>(vm.heap)) NumberConstructor(vm, structure);
+        constructor->finishCreation(vm, numberPrototype);
+        return constructor;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 
+    { 
+        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info()); 
+    }
+
+protected:
+    void finishCreation(VM&, NumberPrototype*);
+
+private:
+    NumberConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
 
 } // namespace JSC
 
index 4df58e81b463e216e422457323b32b57d6a40b8e..31350ccbd17009831cf08b40a01cdaec680b2870 100644 (file)
@@ -30,7 +30,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NumberObject);
 
-const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(NumberObject) };
+const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(NumberObject) };
 
 NumberObject::NumberObject(VM& vm, Structure* structure)
     : JSWrapperObject(vm, structure)
index 4bdf2819f2667669af53715ce201880251240064..d979dd48aa2ce2c08469797e0ab380b5316fa8e0 100644 (file)
 
 namespace JSC {
 
-    class NumberObject : public JSWrapperObject {
-    protected:
-        NumberObject(VM&, Structure*);
-        void finishCreation(VM&);
-
-    public:
-        typedef JSWrapperObject Base;
-
-        static NumberObject* create(VM& vm, Structure* structure)
-        {
-            NumberObject* number = new (NotNull, allocateCell<NumberObject>(vm.heap)) NumberObject(vm, structure);
-            number->finishCreation(vm);
-            return number;
-        }
-
-        DECLARE_EXPORT_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
-        }
-    };
-
-    JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
+class NumberObject : public JSWrapperObject {
+protected:
+    NumberObject(VM&, Structure*);
+    void finishCreation(VM&);
+
+public:
+    typedef JSWrapperObject Base;
+
+    static NumberObject* create(VM& vm, Structure* structure)
+    {
+        NumberObject* number = new (NotNull, allocateCell<NumberObject>(vm.heap)) NumberObject(vm, structure);
+        number->finishCreation(vm);
+        return number;
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
+    }
+};
+
+JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
 
 } // namespace JSC
 
index 42ee30a5fbf73d16ecdc8392386957a8e8d3b841..ea711c0f71e1d71dce21220a76c9cce58f39ac09 100644 (file)
@@ -48,7 +48,6 @@ static EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*);
 static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*);
 static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*);
 static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);
-static EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState*);
 
 }
 
@@ -56,7 +55,7 @@ static EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState*);
 
 namespace JSC {
 
-const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0, ExecState::numberPrototypeTable, CREATE_METHOD_TABLE(NumberPrototype) };
+const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, &numberPrototypeTable, CREATE_METHOD_TABLE(NumberPrototype) };
 
 /* Source for NumberPrototype.lut.h
 @begin numberPrototypeTable
@@ -66,7 +65,6 @@ const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0,
   toFixed           numberProtoFuncToFixed          DontEnum|Function 1
   toExponential     numberProtoFuncToExponential    DontEnum|Function 1
   toPrecision       numberProtoFuncToPrecision      DontEnum|Function 1
-  clz               numberProtoFuncClz              DontEnum|Function 1
 @end
 */
 
@@ -87,7 +85,7 @@ void NumberPrototype::finishCreation(VM& vm, JSGlobalObject*)
 
 bool NumberPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<NumberObject>(exec, ExecState::numberPrototypeTable(exec->vm()), jsCast<NumberPrototype*>(object), propertyName, slot);
+    return getStaticFunctionSlot<NumberObject>(exec, numberPrototypeTable, jsCast<NumberPrototype*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions ---------------------------
@@ -378,7 +376,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
 
     // Handle NaN and Infinity.
     if (!std::isfinite(x))
-        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));
 
     // Round if the argument is not undefined, always format as exponential.
     char buffer[WTF::NumberToStringBufferLength];
@@ -446,47 +444,12 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
 
     // Handle NaN and Infinity.
     if (!std::isfinite(x))
-        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
+        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));
 
     NumberToStringBuffer buffer;
     return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
 }
 
-#if !COMPILER(GCC) && !COMPILER(CLANG)
-static inline int clz(uint32_t number)
-{
-    int zeroCount = 0;
-    for (int i = 31; i >= 0; i--) {
-        if (!(number >> i))
-            zeroCount++;
-        else
-            break;
-    }
-    return zeroCount;
-}
-#endif
-
-EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState* exec)
-{
-    double x;
-    if (!toThisNumber(exec->thisValue(), x))
-        return throwVMTypeError(exec);
-
-    if (!std::isfinite(x))
-        return JSValue::encode(JSValue(x));
-
-    uint32_t number = toUInt32(x);
-#if COMPILER(GCC) || COMPILER(CLANG)
-    int zeroCount = 32;
-    if (number)
-        zeroCount = __builtin_clz(number);
-
-    return JSValue::encode(JSValue(zeroCount));
-#else
-    return JSValue::encode(JSValue(clz(number)));
-#endif
-}
-
 static inline int32_t extractRadixFromArgs(ExecState* exec)
 {
     JSValue radixValue = exec->argument(0);
@@ -540,7 +503,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
     }
 
     if (!std::isfinite(doubleValue))
-        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(doubleValue)));
+        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(doubleValue)));
 
     RadixBuffer s;
     return JSValue::encode(jsString(exec, toStringWithRadix(s, doubleValue, radix)));
index 723544faaa3e6857cee85c735cdce76207e553fd..45acd8fb19cd89276d2eec44c933089057dcd8fd 100644 (file)
 
 namespace JSC {
 
-    class NumberPrototype : public NumberObject {
-    public:
-        typedef NumberObject Base;
-
-        static NumberPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
-        {
-            NumberPrototype* prototype = new (NotNull, allocateCell<NumberPrototype>(vm.heap)) NumberPrototype(vm, structure);
-            prototype->finishCreation(vm, globalObject);
-            return prototype;
-        }
-        
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
-        }
-
-    protected:
-        void finishCreation(VM&, JSGlobalObject*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NumberObject::StructureFlags;
-
-    private:
-        NumberPrototype(VM&, Structure*);
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    };
+class NumberPrototype : public NumberObject {
+public:
+    typedef NumberObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static NumberPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        NumberPrototype* prototype = new (NotNull, allocateCell<NumberPrototype>(vm.heap)) NumberPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
+    }
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
+
+private:
+    NumberPrototype(VM&, Structure*);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
 
 } // namespace JSC
 
index 3bb5b91c815ece3b834fca295451e8f0d6fa2b03..ac8d416039a2789509dc7b2a79924ed4dbec5c86 100644 (file)
 
 namespace JSC {
 
-    class NumericStrings {
-    public:
-        ALWAYS_INLINE String add(double d)
-        {
-            CacheEntry<double>& entry = lookup(d);
-            if (d == entry.key && !entry.value.isNull())
-                return entry.value;
-            entry.key = d;
-            entry.value = String::numberToStringECMAScript(d);
+class NumericStrings {
+public:
+    ALWAYS_INLINE String add(double d)
+    {
+        CacheEntry<double>& entry = lookup(d);
+        if (d == entry.key && !entry.value.isNull())
             return entry.value;
-        }
+        entry.key = d;
+        entry.value = String::numberToStringECMAScript(d);
+        return entry.value;
+    }
 
-        ALWAYS_INLINE String add(int i)
-        {
-            if (static_cast<unsigned>(i) < cacheSize)
-                return lookupSmallString(static_cast<unsigned>(i));
-            CacheEntry<int>& entry = lookup(i);
-            if (i == entry.key && !entry.value.isNull())
-                return entry.value;
-            entry.key = i;
-            entry.value = String::number(i);
+    ALWAYS_INLINE String add(int i)
+    {
+        if (static_cast<unsigned>(i) < cacheSize)
+            return lookupSmallString(static_cast<unsigned>(i));
+        CacheEntry<int>& entry = lookup(i);
+        if (i == entry.key && !entry.value.isNull())
             return entry.value;
-        }
+        entry.key = i;
+        entry.value = String::number(i);
+        return entry.value;
+    }
 
-        ALWAYS_INLINE String add(unsigned i)
-        {
-            if (i < cacheSize)
-                return lookupSmallString(static_cast<unsigned>(i));
-            CacheEntry<unsigned>& entry = lookup(i);
-            if (i == entry.key && !entry.value.isNull())
-                return entry.value;
-            entry.key = i;
-            entry.value = String::number(i);
+    ALWAYS_INLINE String add(unsigned i)
+    {
+        if (i < cacheSize)
+            return lookupSmallString(static_cast<unsigned>(i));
+        CacheEntry<unsigned>& entry = lookup(i);
+        if (i == entry.key && !entry.value.isNull())
             return entry.value;
-        }
-    private:
-        static const size_t cacheSize = 64;
+        entry.key = i;
+        entry.value = String::number(i);
+        return entry.value;
+    }
+private:
+    static const size_t cacheSize = 64;
 
-        template<typename T>
-        struct CacheEntry {
-            T key;
-            String value;
-        };
+    template<typename T>
+    struct CacheEntry {
+        T key;
+        String value;
+    };
 
-        CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
-        CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
-        CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; }
-        ALWAYS_INLINE const String& lookupSmallString(unsigned i)
-        {
-            ASSERT(i < cacheSize);
-            if (smallIntCache[i].isNull())
-                smallIntCache[i] = String::number(i);
-            return smallIntCache[i];
-        }
+    CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
+    CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
+    CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; }
+    ALWAYS_INLINE const String& lookupSmallString(unsigned i)
+    {
+        ASSERT(i < cacheSize);
+        if (smallIntCache[i].isNull())
+            smallIntCache[i] = String::number(i);
+        return smallIntCache[i];
+    }
 
-        std::array<CacheEntry<double>, cacheSize> doubleCache;
-        std::array<CacheEntry<int>, cacheSize> intCache;
-        std::array<CacheEntry<unsigned>, cacheSize> unsignedCache;
-        std::array<String, cacheSize> smallIntCache;
-    };
+    std::array<CacheEntry<double>, cacheSize> doubleCache;
+    std::array<CacheEntry<int>, cacheSize> intCache;
+    std::array<CacheEntry<unsigned>, cacheSize> unsignedCache;
+    std::array<String, cacheSize> smallIntCache;
+};
 
 } // namespace JSC
 
index a3c192790770d925e5e92ea0ce81bceba5b98a41..1a11e28d7255b4cda710c1a9cbb499dffae12353 100644 (file)
 #include "CopiedSpaceInlines.h"
 #include "Error.h"
 #include "ExceptionHelpers.h"
-#include "JSFunction.h"
 #include "JSArray.h"
+#include "JSCInlines.h"
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
+#include "JSGlobalObjectFunctions.h"
 #include "Lookup.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "PropertyDescriptor.h"
 #include "PropertyNameArray.h"
 #include "StackVisitor.h"
+#include "Symbol.h"
 
 namespace JSC {
 
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorSetPrototypeOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIs(ExecState*);
 
 }
 
@@ -59,11 +61,12 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectConstructor);
 
-const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
+const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, &objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
 
 /* Source for ObjectConstructor.lut.h
 @begin objectConstructorTable
   getPrototypeOf            objectConstructorGetPrototypeOf             DontEnum|Function 1
+  setPrototypeOf            objectConstructorSetPrototypeOf             DontEnum|Function 2
   getOwnPropertyDescriptor  objectConstructorGetOwnPropertyDescriptor   DontEnum|Function 2
   getOwnPropertyNames       objectConstructorGetOwnPropertyNames        DontEnum|Function 1
   keys                      objectConstructorKeys                       DontEnum|Function 1
@@ -76,6 +79,8 @@ const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_i
   isSealed                  objectConstructorIsSealed                   DontEnum|Function 1
   isFrozen                  objectConstructorIsFrozen                   DontEnum|Function 1
   isExtensible              objectConstructorIsExtensible               DontEnum|Function 1
+  is                        objectConstructorIs                         DontEnum|Function 2
+  assign                    objectConstructorAssign                     DontEnum|Function 2
 @end
 */
 
@@ -84,18 +89,32 @@ ObjectConstructor::ObjectConstructor(VM& vm, Structure* structure)
 {
 }
 
-void ObjectConstructor::finishCreation(VM& vm, ObjectPrototype* objectPrototype)
+void ObjectConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, ObjectPrototype* objectPrototype)
 {
-    Base::finishCreation(vm, Identifier(&vm, "Object").string());
+    Base::finishCreation(vm, objectPrototype->classInfo()->className);
     // ECMA 15.2.3.1
     putDirectWithoutTransition(vm, vm.propertyNames->prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
     // no. of arguments for constructor
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+
+    if (!globalObject->runtimeFlags().isSymbolDisabled())
+        JSC_NATIVE_FUNCTION("getOwnPropertySymbols", objectConstructorGetOwnPropertySymbols, DontEnum, 1);
+
+    JSC_NATIVE_FUNCTION(vm.propertyNames->getPrototypeOfPrivateName, objectConstructorGetPrototypeOf, DontEnum, 1);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->getOwnPropertyNamesPrivateName, objectConstructorGetOwnPropertyNames, DontEnum, 1);
+}
+
+JSFunction* ObjectConstructor::addDefineProperty(ExecState* exec, JSGlobalObject* globalObject)
+{
+    VM& vm = exec->vm();
+    JSFunction* definePropertyFunction = JSFunction::create(vm, globalObject, 3, vm.propertyNames->defineProperty.string(), objectConstructorDefineProperty);
+    putDirectWithoutTransition(vm, vm.propertyNames->defineProperty, definePropertyFunction, DontEnum);
+    return definePropertyFunction;
 }
 
 bool ObjectConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<JSObject>(exec, ExecState::objectConstructorTable(exec->vm()), jsCast<ObjectConstructor*>(object), propertyName, slot);
+    return getStaticFunctionSlot<JSObject>(exec, objectConstructorTable, jsCast<ObjectConstructor*>(object), propertyName, slot);
 }
 
 static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
@@ -148,10 +167,10 @@ public:
             return StackVisitor::Continue;
         }
 
-    if (m_object->allowsAccessFrom(visitor->callFrame()))
-        m_result = JSValue::encode(m_object->prototype());
-    return StackVisitor::Done;
-}
+        if (m_object->allowsAccessFrom(visitor->callFrame()))
+            m_result = JSValue::encode(m_object->prototype());
+        return StackVisitor::Done;
+    }
 
 private:
     bool m_hasSkippedFirstFrame;
@@ -161,24 +180,52 @@ private:
 
 EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec)
 {
-    if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object.")));
-    JSObject* object = asObject(exec->argument(0));
+    JSObject* object = exec->argument(0).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
     ObjectConstructorGetPrototypeOfFunctor functor(object);
     exec->iterate(functor);
     return functor.result();
 }
 
+EncodedJSValue JSC_HOST_CALL objectConstructorSetPrototypeOf(ExecState* exec)
+{
+    JSValue objectValue = exec->argument(0);
+    if (objectValue.isUndefinedOrNull())
+        return throwVMTypeError(exec);
+
+    JSValue protoValue = exec->argument(1);
+    if (!protoValue.isObject() && !protoValue.isNull())
+        return throwVMTypeError(exec);
+
+    JSObject* object = objectValue.toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(objectValue);
+
+    if (!checkProtoSetterAccessAllowed(exec, object))
+        return JSValue::encode(objectValue);
+
+    if (!object->isExtensible())
+        return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+
+    if (!object->setPrototypeWithCycleCheck(exec, protoValue)) {
+        exec->vm().throwException(exec, createError(exec, ASCIILiteral("cyclic __proto__ value")));
+        return JSValue::encode(jsUndefined());
+    }
+
+    return JSValue::encode(objectValue);
+}
+
 EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
 {
-    if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property descriptor of a value that is not an object.")));
-    String propertyName = exec->argument(1).toString(exec)->value(exec);
+    JSObject* object = exec->argument(0).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
+    auto propertyName = exec->argument(1).toPropertyKey(exec);
     if (exec->hadException())
         return JSValue::encode(jsNull());
-    JSObject* object = asObject(exec->argument(0));
     PropertyDescriptor descriptor;
-    if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor))
+    if (!object->getOwnPropertyDescriptor(exec, propertyName, descriptor))
         return JSValue::encode(jsUndefined());
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
@@ -203,10 +250,11 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState
 // FIXME: Use the enumeration cache.
 EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec)
 {
-    if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object.")));
+    JSObject* object = exec->argument(0).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
     PropertyNameArray properties(exec);
-    asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include));
     JSArray* names = constructEmptyArray(exec, 0);
     size_t numProperties = properties.size();
     for (size_t i = 0; i < numProperties; i++)
@@ -214,13 +262,32 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exe
     return JSValue::encode(names);
 }
 
+// FIXME: Use the enumeration cache.
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertySymbols(ExecState* exec)
+{
+    JSObject* object = exec->argument(0).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
+    PropertyNameArray properties(exec);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
+    JSArray* names = constructEmptyArray(exec, 0);
+    size_t numProperties = properties.size();
+    for (size_t i = 0; i < numProperties; i++) {
+        auto impl = properties[i].impl();
+        if (impl->isSymbol() && !exec->propertyNames().isPrivateName(*impl))
+            names->push(exec, Symbol::create(exec->vm(), static_cast<SymbolImpl&>(*impl)));
+    }
+    return JSValue::encode(names);
+}
+
 // FIXME: Use the enumeration cache.
 EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec)
 {
-    if (!exec->argument(0).isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object.")));
+    JSObject* object = exec->argument(0).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsNull());
     PropertyNameArray properties(exec);
-    asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode());
     JSArray* keys = constructEmptyArray(exec, 0);
     size_t numProperties = properties.size();
     for (size_t i = 0; i < numProperties; i++)
@@ -316,7 +383,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
     if (!exec->argument(0).isObject())
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
     JSObject* O = asObject(exec->argument(0));
-    String propertyName = exec->argument(1).toString(exec)->value(exec);
+    auto propertyName = exec->argument(1).toPropertyKey(exec);
     if (exec->hadException())
         return JSValue::encode(jsNull());
     PropertyDescriptor descriptor;
@@ -324,14 +391,14 @@ EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
         return JSValue::encode(jsNull());
     ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
     ASSERT(!exec->hadException());
-    O->methodTable(exec->vm())->defineOwnProperty(O, exec, Identifier(exec, propertyName), descriptor, true);
+    O->methodTable(exec->vm())->defineOwnProperty(O, exec, propertyName, descriptor, true);
     return JSValue::encode(O);
 }
 
 static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties)
 {
     PropertyNameArray propertyNames(exec);
-    asObject(properties)->methodTable(exec->vm())->getOwnPropertyNames(asObject(properties), exec, propertyNames, ExcludeDontEnumProperties);
+    asObject(properties)->methodTable(exec->vm())->getOwnPropertyNames(asObject(properties), exec, propertyNames, EnumerationMode(DontEnumPropertiesMode::Exclude, SymbolPropertiesMode::Include));
     size_t numProperties = propertyNames.size();
     Vector<PropertyDescriptor> descriptors;
     MarkedArgumentBuffer markBuffer;
@@ -354,7 +421,10 @@ static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* pro
         }
     }
     for (size_t i = 0; i < numProperties; i++) {
-        object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyNames[i], descriptors[i], true);
+        Identifier propertyName = propertyNames[i];
+        if (exec->propertyNames().isPrivateName(propertyName))
+            continue;
+        object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, descriptors[i], true);
         if (exec->hadException())
             return jsNull();
     }
@@ -385,10 +455,10 @@ EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
 {
-    // 1. If Type(O) is not Object throw a TypeError exception.
+    // 1. If Type(O) is not Object, return O.
     JSValue obj = exec->argument(0);
     if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.seal can only be called on Objects.")));
+        return JSValue::encode(obj);
     JSObject* object = asObject(obj);
 
     if (isJSFinalObject(object)) {
@@ -398,17 +468,20 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
 
     // 2. For each named own property name P of O,
     PropertyNameArray properties(exec);
-    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
     PropertyNameArray::const_iterator end = properties.end();
     for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+        Identifier propertyName = *iter;
+        if (exec->propertyNames().isPrivateName(propertyName))
+            continue;
         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
         PropertyDescriptor desc;
-        if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+        if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
             continue;
         // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
         desc.setConfigurable(false);
         // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
-        object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
+        object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, desc, true);
         if (exec->hadException())
             return JSValue::encode(obj);
     }
@@ -420,27 +493,24 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
     return JSValue::encode(obj);
 }
 
-EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
+JSObject* objectConstructorFreeze(ExecState* exec, JSObject* object)
 {
-    // 1. If Type(O) is not Object throw a TypeError exception.
-    JSValue obj = exec->argument(0);
-    if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
-    JSObject* object = asObject(obj);
-
     if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
         object->freeze(exec->vm());
-        return JSValue::encode(obj);
+        return object;
     }
 
     // 2. For each named own property name P of O,
     PropertyNameArray properties(exec);
-    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
     PropertyNameArray::const_iterator end = properties.end();
     for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+        Identifier propertyName = *iter;
+        if (exec->propertyNames().isPrivateName(propertyName))
+            continue;
         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
         PropertyDescriptor desc;
-        if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+        if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
             continue;
         // b. If IsDataDescriptor(desc) is true, then
         // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
@@ -449,33 +519,42 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
         // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
         desc.setConfigurable(false);
         // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
-        object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
+        object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, desc, true);
         if (exec->hadException())
-            return JSValue::encode(obj);
+            return object;
     }
 
     // 3. Set the [[Extensible]] internal property of O to false.
     object->preventExtensions(exec->vm());
 
     // 4. Return O.
-    return JSValue::encode(obj);
+    return object;
+}
+
+EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
+{
+    // 1. If Type(O) is not Object, return O.
+    JSValue obj = exec->argument(0);
+    if (!obj.isObject())
+        return JSValue::encode(obj);
+    return JSValue::encode(objectConstructorFreeze(exec, asObject(obj)));
 }
 
 EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
 {
     JSValue obj = exec->argument(0);
     if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects.")));
+        return JSValue::encode(obj);
     asObject(obj)->preventExtensions(exec->vm());
     return JSValue::encode(obj);
 }
 
 EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
 {
-    // 1. If Type(O) is not Object throw a TypeError exception.
+    // 1. If Type(O) is not Object, return true.
     JSValue obj = exec->argument(0);
     if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isSealed can only be called on Objects.")));
+        return JSValue::encode(jsBoolean(true));
     JSObject* object = asObject(obj);
 
     if (isJSFinalObject(object))
@@ -483,12 +562,15 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
 
     // 2. For each named own property name P of O,
     PropertyNameArray properties(exec);
-    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
     PropertyNameArray::const_iterator end = properties.end();
     for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+        Identifier propertyName = *iter;
+        if (exec->propertyNames().isPrivateName(propertyName))
+            continue;
         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
         PropertyDescriptor desc;
-        if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+        if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
             continue;
         // b. If desc.[[Configurable]] is true, then return false.
         if (desc.configurable())
@@ -502,10 +584,10 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
 {
-    // 1. If Type(O) is not Object throw a TypeError exception.
+    // 1. If Type(O) is not Object, return true.
     JSValue obj = exec->argument(0);
     if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects.")));
+        return JSValue::encode(jsBoolean(true));
     JSObject* object = asObject(obj);
 
     if (isJSFinalObject(object))
@@ -513,12 +595,15 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
 
     // 2. For each named own property name P of O,
     PropertyNameArray properties(exec);
-    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+    object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
     PropertyNameArray::const_iterator end = properties.end();
     for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+        Identifier propertyName = *iter;
+        if (exec->propertyNames().isPrivateName(propertyName))
+            continue;
         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
         PropertyDescriptor desc;
-        if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+        if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
             continue;
         // b. If IsDataDescriptor(desc) is true then
         // i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false.
@@ -535,8 +620,13 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState* exec)
 {
     JSValue obj = exec->argument(0);
     if (!obj.isObject())
-        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isExtensible can only be called on Objects.")));
+        return JSValue::encode(jsBoolean(false));
     return JSValue::encode(jsBoolean(asObject(obj)->isExtensible()));
 }
 
+EncodedJSValue JSC_HOST_CALL objectConstructorIs(ExecState* exec)
+{
+    return JSValue::encode(jsBoolean(sameValue(exec, exec->argument(0), exec->argument(1))));
+}
+
 } // namespace JSC
index 4a6b4711b3ea65926c3a48a7942b51eeff73a544..8fc5c7322582663c8be243655dd7b9e82646fabe 100644 (file)
 
 namespace JSC {
 
-    class ObjectPrototype;
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertySymbols(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*);
 
-    class ObjectConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class ObjectPrototype;
 
-        static ObjectConstructor* create(VM& vm, Structure* structure, ObjectPrototype* objectPrototype)
-        {
-            ObjectConstructor* constructor = new (NotNull, allocateCell<ObjectConstructor>(vm.heap)) ObjectConstructor(vm, structure);
-            constructor->finishCreation(vm, objectPrototype);
-            return constructor;
-        }
+class ObjectConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        void finishCreation(VM& vm, ObjectPrototype*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
-
-    private:
-        ObjectConstructor(VM&, Structure*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-    };
-
-    inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
+    static ObjectConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, ObjectPrototype* objectPrototype)
     {
-        return JSFinalObject::create(exec, structure);
+        ObjectConstructor* constructor = new (NotNull, allocateCell<ObjectConstructor>(vm.heap)) ObjectConstructor(vm, structure);
+        constructor->finishCreation(vm, globalObject, objectPrototype);
+        return constructor;
     }
 
-    inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
-    {
-        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-        PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
-        Structure* structure = prototypeMap.emptyObjectStructureForPrototype(
-            prototype, inlineCapacity);
-        return constructEmptyObject(exec, structure);
-    }
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 
-    inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype)
-    {
-        return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity());
-    }
+    DECLARE_INFO;
 
-    inline JSObject* constructEmptyObject(ExecState* exec)
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
+    JSFunction* addDefineProperty(ExecState*, JSGlobalObject*);
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*, ObjectPrototype*);
+
+private:
+    ObjectConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
+
+inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
+{
+    return JSFinalObject::create(exec, structure);
+}
+
+inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
+{
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
+    Structure* structure = prototypeMap.emptyObjectStructureForPrototype(
+        prototype, inlineCapacity);
+    return constructEmptyObject(exec, structure);
+}
+
+inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype)
+{
+    return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity());
+}
+
+inline JSObject* constructEmptyObject(ExecState* exec)
+{
+    return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype());
+}
+
+JSObject* objectConstructorFreeze(ExecState*, JSObject*);
+
 } // namespace JSC
 
 #endif // ObjectConstructor_h
index 9fa7861c900eb4e3fa6f7f6be2547728c5148829..905d0d25647851927a9cd1bf31dc78eb54fd9722 100644 (file)
@@ -42,7 +42,7 @@ static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectPrototype);
 
-const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ObjectPrototype) };
+const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, CREATE_METHOD_TABLE(ObjectPrototype) };
 
 ObjectPrototype::ObjectPrototype(VM& vm, Structure* stucture)
     : JSNonFinalObject(vm, stucture)
@@ -85,7 +85,10 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec)
 EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
-    return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, exec->argument(0).toString(exec)->toIdentifier(exec))));
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, propertyName)));
 }
 
 EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
@@ -118,11 +121,17 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
     if (getCallData(get, callData) == CallTypeNone)
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid getter usage")));
 
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
     PropertyDescriptor descriptor;
     descriptor.setGetter(get);
     descriptor.setEnumerable(true);
     descriptor.setConfigurable(true);
-    thisObject->methodTable(exec->vm())->defineOwnProperty(thisObject, exec, exec->argument(0).toString(exec)->toIdentifier(exec), descriptor, false);
+
+    bool shouldThrow = false;
+    thisObject->methodTable(exec->vm())->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
 
     return JSValue::encode(jsUndefined());
 }
@@ -138,11 +147,17 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
     if (getCallData(set, callData) == CallTypeNone)
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid setter usage")));
 
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
     PropertyDescriptor descriptor;
     descriptor.setSetter(set);
     descriptor.setEnumerable(true);
     descriptor.setConfigurable(true);
-    thisObject->methodTable(exec->vm())->defineOwnProperty(thisObject, exec, exec->argument(0).toString(exec)->toIdentifier(exec), descriptor, false);
+
+    bool shouldThrow = false;
+    thisObject->methodTable(exec->vm())->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
 
     return JSValue::encode(jsUndefined());
 }
@@ -153,11 +168,14 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec)
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
     PropertySlot slot(thisObject);
-    if (thisObject->getPropertySlot(exec, exec->argument(0).toString(exec)->toIdentifier(exec), slot)
-        && slot.isAccessor()) {
-        JSObject* getter = slot.getterSetter()->getter();
-        return getter ? JSValue::encode(getter) : JSValue::encode(jsUndefined());
+    if (thisObject->getPropertySlot(exec, propertyName, slot) && slot.isAccessor()) {
+        GetterSetter* getterSetter = slot.getterSetter();
+        return getterSetter->isGetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->getter());
     }
 
     return JSValue::encode(jsUndefined());
@@ -169,11 +187,14 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
 
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
     PropertySlot slot(thisObject);
-    if (thisObject->getPropertySlot(exec, exec->argument(0).toString(exec)->toIdentifier(exec), slot)
-        && slot.isAccessor()) {
-        JSObject* setter = slot.getterSetter()->setter();
-        return setter ? JSValue::encode(setter) : JSValue::encode(jsUndefined());
+    if (thisObject->getPropertySlot(exec, propertyName, slot) && slot.isAccessor()) {
+        GetterSetter* getterSetter = slot.getterSetter();
+        return getterSetter->isSetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->setter());
     }
 
     return JSValue::encode(jsUndefined());
@@ -181,9 +202,13 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec)
 {
-    JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    Identifier propertyName(exec, exec->argument(0).toString(exec)->value(exec));
+    auto propertyName = exec->argument(0).toPropertyKey(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
 
+    JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
     PropertyDescriptor descriptor;
     bool enumerable = thisObject->getOwnPropertyDescriptor(exec, propertyName, descriptor) && descriptor.enumerable();
     return JSValue::encode(jsBoolean(enumerable));
index 75a2a95a192dc7653494520cfe281b74517a714b..34238a9f45f66ff042b57b84774a0a31ee89edec 100644 (file)
 
 namespace JSC {
 
-    class ObjectPrototype : public JSNonFinalObject {
-    public:
-        typedef JSNonFinalObject Base;
+class ObjectPrototype : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
 
-        static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);
+    static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);
 
-        DECLARE_INFO;
+    DECLARE_INFO;
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-    protected:
-        void finishCreation(VM&, JSGlobalObject*);
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
 
-    private:
-        ObjectPrototype(VM&, Structure*);
-    };
+private:
+    ObjectPrototype(VM&, Structure*);
+};
 
-    JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
+JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
 
 } // namespace JSC
 
index 36d832f4420b73e316ad81820c4fc34bb177146a..5732cfd0c224f329579dc3d75ecb51ed56b90bc8 100644 (file)
@@ -65,15 +65,22 @@ JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v)
         return vm.smallStrings.numberString();
     if (v.isString())
         return vm.smallStrings.stringString();
+    if (v.isSymbol())
+        return vm.smallStrings.symbolString();
     if (v.isObject()) {
+        JSObject* object = asObject(v);
         // Return "undefined" for objects that should be treated
         // as null when doing comparisons.
-        if (asObject(v)->structure(vm)->masqueradesAsUndefined(globalObject))
+        if (object->structure(vm)->masqueradesAsUndefined(globalObject))
             return vm.smallStrings.undefinedString();
-        CallData callData;
-        JSObject* object = asObject(v);
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->type() == JSFunctionType)
             return vm.smallStrings.functionString();
+        if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+            CallData callData;
+            JSObject* object = asObject(v);
+            if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+                return vm.smallStrings.functionString();
+        }
     }
     return vm.smallStrings.objectString();
 }
@@ -83,13 +90,13 @@ JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
     return jsTypeStringForValue(callFrame->vm(), callFrame->lexicalGlobalObject(), v);
 }
 
-bool jsIsObjectType(CallFrame* callFrame, JSValue v)
+bool jsIsObjectTypeOrNull(CallFrame* callFrame, JSValue v)
 {
     if (!v.isCell())
         return v.isNull();
 
     JSType type = v.asCell()->type();
-    if (type == StringType)
+    if (type == StringType || type == SymbolType)
         return false;
     if (type >= ObjectType) {
         if (asObject(v)->structure(callFrame->vm())->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
index bd45c225a00b5c974dc472f774548d416fe1b784..ac47c8f9cd7b4b27099344f8dedc528354f66913 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
 NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
 JSValue jsTypeStringForValue(CallFrame*, JSValue);
 JSValue jsTypeStringForValue(VM&, JSGlobalObject*, JSValue);
-bool jsIsObjectType(CallFrame*, JSValue);
+bool jsIsObjectTypeOrNull(CallFrame*, JSValue);
 bool jsIsFunctionType(JSValue);
 
 ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
@@ -194,65 +194,65 @@ ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
 
 #define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
 
-inline size_t normalizePrototypeChainForChainAccess(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
+inline size_t normalizePrototypeChainForChainAccess(CallFrame* callFrame, Structure* structure, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
 {
     VM& vm = callFrame->vm();
-    JSCell* cell = base.asCell();
     size_t count = 0;
         
-    while (!slotBase || slotBase != cell) {
-        if (cell->isProxy())
+    while (1) {
+        if (structure->isProxy())
             return InvalidPrototypeChain;
 
-        const TypeInfo& typeInfo = cell->structure()->typeInfo();
+        const TypeInfo& typeInfo = structure->typeInfo();
         if (typeInfo.hasImpureGetOwnPropertySlot() && !typeInfo.newImpurePropertyFiresWatchpoints())
             return InvalidPrototypeChain;
             
-        JSValue v = cell->structure()->prototypeForLookup(callFrame);
+        JSValue v = structure->prototypeForLookup(callFrame);
 
-        // If we didn't find slotBase in base's prototype chain, then base
+        // If we didn't find slotBase in the base's prototype chain, then the base
         // must be a proxy for another object.
 
         if (v.isNull()) {
             if (!slotBase)
-                return count;
+                break;
             return InvalidPrototypeChain;
         }
 
-        cell = v.asCell();
-
+        JSCell* cell = v.asCell();
+        structure = cell->structure(vm);
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (cell->structure(vm)->isDictionary()) {
-            asObject(cell)->flattenDictionaryObject(callFrame->vm());
+        if (structure->isDictionary()) {
+            structure->flattenDictionaryStructure(vm, asObject(cell));
             if (slotBase == cell)
-                slotOffset = cell->structure(vm)->get(callFrame->vm(), propertyName); 
+                slotOffset = structure->get(vm, propertyName); 
         }
-            
         ++count;
+
+        if (slotBase == cell)
+            break;
     }
         
     return count;
 }
 
-inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
+inline size_t normalizePrototypeChain(CallFrame* callFrame, Structure* structure)
 {
     VM& vm = callFrame->vm();
     size_t count = 0;
     while (1) {
-        if (base->isProxy())
+        if (structure->isProxy())
             return InvalidPrototypeChain;
-            
-        JSValue v = base->structure(vm)->prototypeForLookup(callFrame);
+        JSValue v = structure->prototypeForLookup(callFrame);
         if (v.isNull())
             return count;
 
-        base = v.asCell();
-
+        JSCell* base = v.asCell();
+        structure = base->structure(vm);
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (base->structure(vm)->isDictionary())
-            asObject(base)->flattenDictionaryObject(callFrame->vm());
+        if (structure->isDictionary())
+            structure->flattenDictionaryStructure(vm, asObject(base));
 
         ++count;
     }
index f0ddf98e745e606b15db48f47f03678c96534522..c9c698f7368cfd67ff8d447ee7c03bc92baae9da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2012, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,8 @@
 #include "HeapStatistics.h"
 #include <algorithm>
 #include <limits>
+#include <math.h>
+#include <mutex>
 #include <stdlib.h>
 #include <string.h>
 #include <wtf/DataLog.h>
 #include <sys/sysctl.h>
 #endif
 
+#if OS(WINDOWS)
+#include "MacroAssemblerX86.h"
+#endif
+
 namespace JSC {
 
 static bool parse(const char* string, bool& value)
@@ -105,7 +111,6 @@ static bool parse(const char* string, GCLogging::Level& value)
 template<typename T>
 bool overrideOptionWithHeuristic(T& variable, const char* name)
 {
-#if !OS(WINCE)
     const char* stringValue = getenv(name);
     if (!stringValue)
         return false;
@@ -114,7 +119,6 @@ bool overrideOptionWithHeuristic(T& variable, const char* name)
         return true;
     
     fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
-#endif
     return false;
 }
 
@@ -198,16 +202,54 @@ bool OptionRange::isInRange(unsigned count)
     return m_state == Normal ? false : true;
 }
 
+void OptionRange::dump(PrintStream& out) const
+{
+    out.print(m_rangeString);
+}
+
 Options::Entry Options::s_options[Options::numberOfOptions];
+Options::Entry Options::s_defaultOptions[Options::numberOfOptions];
 
 // Realize the names for each of the options:
 const Options::EntryInfo Options::s_optionsInfo[Options::numberOfOptions] = {
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    { #name_, Options::type_##Type },
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    { #name_, description_, Options::Type::type_##Type },
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 };
 
+static void scaleJITPolicy()
+{
+    auto& scaleFactor = Options::jitPolicyScale();
+    if (scaleFactor > 1.0)
+        scaleFactor = 1.0;
+    else if (scaleFactor < 0.0)
+        scaleFactor = 0.0;
+
+    struct OptionToScale {
+        Options::OptionID id;
+        int32_t minVal;
+    };
+
+    static const OptionToScale optionsToScale[] = {
+        { Options::thresholdForJITAfterWarmUpID, 0 },
+        { Options::thresholdForJITSoonID, 0 },
+        { Options::thresholdForOptimizeAfterWarmUpID, 1 },
+        { Options::thresholdForOptimizeAfterLongWarmUpID, 1 },
+        { Options::thresholdForOptimizeSoonID, 1 },
+        { Options::thresholdForFTLOptimizeSoonID, 2 },
+        { Options::thresholdForFTLOptimizeAfterWarmUpID, 2 }
+    };
+
+    const int numberOfOptionsToScale = sizeof(optionsToScale) / sizeof(OptionToScale);
+    for (int i = 0; i < numberOfOptionsToScale; i++) {
+        Option option(optionsToScale[i].id);
+        ASSERT(option.type() == Options::Type::int32Type);
+        option.int32Val() *= scaleFactor;
+        option.int32Val() = std::max(option.int32Val(), optionsToScale[i].minVal);
+    }
+}
+
 static void recomputeDependentOptions()
 {
 #if !ENABLE(JIT)
@@ -229,7 +271,11 @@ static void recomputeDependentOptions()
 #if !ENABLE(FTL_JIT)
     Options::useFTLJIT() = false;
 #endif
-
+#if OS(WINDOWS) && CPU(X86) 
+    // Disable JIT on Windows if SSE2 is not present 
+    if (!MacroAssemblerX86::supportsFloatingPoint())
+        Options::useJIT() = false;
+#endif
     if (Options::showDisassembly()
         || Options::showDFGDisassembly()
         || Options::showFTLDisassembly()
@@ -247,7 +293,22 @@ static void recomputeDependentOptions()
         || Options::verboseCFA()
         || Options::verboseFTLFailure())
         Options::alwaysComputeHash() = true;
+
+    if (Option(Options::jitPolicyScaleID).isOverridden())
+        scaleJITPolicy();
     
+    if (Options::forceEagerCompilation()) {
+        Options::thresholdForJITAfterWarmUp() = 10;
+        Options::thresholdForJITSoon() = 10;
+        Options::thresholdForOptimizeAfterWarmUp() = 20;
+        Options::thresholdForOptimizeAfterLongWarmUp() = 20;
+        Options::thresholdForOptimizeSoon() = 20;
+        Options::thresholdForFTLOptimizeAfterWarmUp() = 20;
+        Options::thresholdForFTLOptimizeSoon() = 20;
+        Options::maximumEvalCacheableSourceLength() = 150000;
+        Options::enableConcurrentJIT() = false;
+    }
+
     // Compute the maximum value of the reoptimization retry counter. This is simply
     // the largest value at which we don't overflow the execute counter, when using it
     // to left-shift the execution counter by this amount. Currently the value ends
@@ -263,31 +324,66 @@ static void recomputeDependentOptions()
 
 void Options::initialize()
 {
-    // Initialize each of the options with their default values:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    name_() = defaultValue_;
-    JSC_OPTIONS(FOR_EACH_OPTION)
+    static std::once_flag initializeOptionsOnceFlag;
+    
+    std::call_once(
+        initializeOptionsOnceFlag,
+        [] {
+            // Initialize each of the options with their default values:
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            name_() = defaultValue_;                                    \
+            name_##Default() = defaultValue_;
+            JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
+    
+                // It *probably* makes sense for other platforms to enable this.
+#if PLATFORM(IOS) && CPU(ARM64)
+                enableLLVMFastISel() = true;
+#endif
         
-    // Allow environment vars to override options if applicable.
-    // The evn var should be the name of the option prefixed with
-    // "JSC_".
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    if (overrideOptionWithHeuristic(name_(), "JSC_" #name_)) \
-        s_options[OPT_##name_].didOverride = true;
-    JSC_OPTIONS(FOR_EACH_OPTION)
+            // Allow environment vars to override options if applicable.
+            // The evn var should be the name of the option prefixed with
+            // "JSC_".
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            overrideOptionWithHeuristic(name_(), "JSC_" #name_);
+            JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
 #if 0
-    ; // Deconfuse editors that do auto indentation
+                ; // Deconfuse editors that do auto indentation
 #endif
     
-    recomputeDependentOptions();
-
-    // Do range checks where needed and make corrections to the options:
-    ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
+            recomputeDependentOptions();
+
+            // Do range checks where needed and make corrections to the options:
+            ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
+
+            if (Options::showOptions()) {
+                DumpLevel level = static_cast<DumpLevel>(Options::showOptions());
+                if (level > DumpLevel::Verbose)
+                    level = DumpLevel::Verbose;
+
+                const char* title = nullptr;
+                switch (level) {
+                case DumpLevel::None:
+                    break;
+                case DumpLevel::Overridden:
+                    title = "Overridden JSC options:";
+                    break;
+                case DumpLevel::All:
+                    title = "All JSC options:";
+                    break;
+                case DumpLevel::Verbose:
+                    title = "All JSC options with descriptions:";
+                    break;
+                }
+                dumpAllOptions(level, title);
+            }
+
+            ensureOptionsAreCoherent();
+        });
 }
 
 // Parses a single command line option in the format "<optionName>=<value>"
@@ -304,14 +400,13 @@ bool Options::setOption(const char* arg)
 
     // For each option, check if the specify arg is a match. If so, set the arg
     // if the value makes sense. Otherwise, move on to checking the next option.
-#define FOR_EACH_OPTION(type_, name_, defaultValue_)    \
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
     if (!strncmp(arg, #name_, equalStr - arg)) {        \
         type_ value;                                    \
         value = (defaultValue_);                        \
         bool success = parse(valueStr, value);          \
         if (success) {                                  \
             name_() = value;                            \
-            s_options[OPT_##name_].didOverride = true;  \
             recomputeDependentOptions();                \
             return true;                                \
         }                                               \
@@ -324,48 +419,104 @@ bool Options::setOption(const char* arg)
     return false; // No option matched.
 }
 
-void Options::dumpAllOptions(FILE* stream)
+void Options::dumpAllOptions(DumpLevel level, const char* title, FILE* stream)
 {
-    fprintf(stream, "JSC runtime options:\n");
+    if (title)
+        fprintf(stream, "%s\n", title);
     for (int id = 0; id < numberOfOptions; id++)
-        dumpOption(static_cast<OptionID>(id), stream, "   ", "\n");
+        dumpOption(level, static_cast<OptionID>(id), stream, "   ", "\n");
 }
 
-void Options::dumpOption(OptionID id, FILE* stream, const char* header, const char* footer)
+void Options::dumpOption(DumpLevel level, OptionID id, FILE* stream, const char* header, const char* footer)
 {
     if (id >= numberOfOptions)
         return; // Illegal option.
 
-    fprintf(stream, "%s%s: ", header, s_optionsInfo[id].name);
-    switch (s_optionsInfo[id].type) {
-    case boolType:
-        fprintf(stream, "%s", s_options[id].u.boolVal?"true":"false");
+    Option option(id);
+    bool wasOverridden = option.isOverridden();
+    bool needsDescription = (level == DumpLevel::Verbose && option.description());
+
+    if (level == DumpLevel::Overridden && !wasOverridden)
+        return;
+
+    fprintf(stream, "%s%s: ", header, option.name());
+    option.dump(stream);
+
+    if (wasOverridden) {
+        fprintf(stream, " (default: ");
+        option.defaultOption().dump(stream);
+        fprintf(stream, ")");
+    }
+
+    if (needsDescription)
+        fprintf(stream, "   ... %s", option.description());
+
+    fprintf(stream, "%s", footer);
+}
+
+void Options::ensureOptionsAreCoherent()
+{
+    bool coherent = true;
+    if (!(useLLInt() || useJIT())) {
+        coherent = false;
+        dataLog("INCOHERENT OPTIONS: at least one of useLLInt or useJIT must be true\n");
+    }
+    if (!coherent)
+        CRASH();
+}
+
+void Option::dump(FILE* stream) const
+{
+    switch (type()) {
+    case Options::Type::boolType:
+        fprintf(stream, "%s", m_entry.boolVal ? "true" : "false");
         break;
-    case unsignedType:
-        fprintf(stream, "%u", s_options[id].u.unsignedVal);
+    case Options::Type::unsignedType:
+        fprintf(stream, "%u", m_entry.unsignedVal);
         break;
-    case doubleType:
-        fprintf(stream, "%lf", s_options[id].u.doubleVal);
+    case Options::Type::doubleType:
+        fprintf(stream, "%lf", m_entry.doubleVal);
         break;
-    case int32Type:
-        fprintf(stream, "%d", s_options[id].u.int32Val);
+    case Options::Type::int32Type:
+        fprintf(stream, "%d", m_entry.int32Val);
         break;
-    case optionRangeType:
-        fprintf(stream, "%s", s_options[id].u.optionRangeVal.rangeString());
+    case Options::Type::optionRangeType:
+        fprintf(stream, "%s", m_entry.optionRangeVal.rangeString());
         break;
-    case optionStringType: {
-        const char* option = s_options[id].u.optionStringVal;
+    case Options::Type::optionStringType: {
+        const char* option = m_entry.optionStringVal;
         if (!option)
             option = "";
         fprintf(stream, "%s", option);
         break;
     }
-    case gcLogLevelType: {
-        fprintf(stream, "%s", GCLogging::levelAsString(s_options[id].u.gcLogLevelVal));
+    case Options::Type::gcLogLevelType: {
+        fprintf(stream, "%s", GCLogging::levelAsString(m_entry.gcLogLevelVal));
         break;
     }
     }
-    fprintf(stream, "%s", footer);
+}
+
+bool Option::operator==(const Option& other) const
+{
+    switch (type()) {
+    case Options::Type::boolType:
+        return m_entry.boolVal == other.m_entry.boolVal;
+    case Options::Type::unsignedType:
+        return m_entry.unsignedVal == other.m_entry.unsignedVal;
+    case Options::Type::doubleType:
+        return (m_entry.doubleVal == other.m_entry.doubleVal) || (isnan(m_entry.doubleVal) && isnan(other.m_entry.doubleVal));
+    case Options::Type::int32Type:
+        return m_entry.int32Val == other.m_entry.int32Val;
+    case Options::Type::optionRangeType:
+        return m_entry.optionRangeVal.rangeString() == other.m_entry.optionRangeVal.rangeString();
+    case Options::Type::optionStringType:
+        return (m_entry.optionStringVal == other.m_entry.optionStringVal)
+            || (m_entry.optionStringVal && other.m_entry.optionStringVal && !strcmp(m_entry.optionStringVal, other.m_entry.optionStringVal));
+    case Options::Type::gcLogLevelType:
+        return m_entry.gcLogLevelVal == other.m_entry.gcLogLevelVal;
+    }
+    return false;
 }
 
 } // namespace JSC
index eeb4022f387e6410288899f1d2a956a812087d02..924f4fd0f2a0b3a06911606cbeef10be826fd055 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
 #include "JSExportMacros.h"
 #include <stdint.h>
 #include <stdio.h>
+#include <wtf/PrintStream.h>
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
@@ -79,7 +80,9 @@ public:
 
     bool init(const char*);
     bool isInRange(unsigned);
-    const char* rangeString() { return (m_state > InitError) ? m_rangeString : "<null>"; }
+    const char* rangeString() const { return (m_state > InitError) ? m_rangeString : "<null>"; }
+    
+    void dump(PrintStream& out) const;
 
 private:
     RangeState m_state;
@@ -92,265 +95,408 @@ typedef OptionRange optionRange;
 typedef const char* optionString;
 
 #define JSC_OPTIONS(v) \
-    v(bool, useLLInt,  true) \
-    v(bool, useJIT,    true) \
-    v(bool, useDFGJIT, true) \
-    v(bool, useRegExpJIT, true) \
+    v(unsigned, showOptions, 0, "shows JSC options (0 = None, 1 = Overridden only, 2 = All, 3 = Verbose)") \
     \
-    v(unsigned, maxPerThreadStackUsage, 4 * MB) \
-    v(unsigned, reservedZoneSize, 128 * KB) \
-    v(unsigned, errorModeReservedZoneSize, 64 * KB) \
+    v(bool, useLLInt,  true, "allows the LLINT to be used if true") \
+    v(bool, useJIT,    true, "allows the baseline JIT to be used if true") \
+    v(bool, useDFGJIT, true, "allows the DFG JIT to be used if true") \
+    v(bool, useRegExpJIT, true, "allows the RegExp JIT to be used if true") \
     \
-    v(bool, crashIfCantAllocateJITMemory, false) \
+    v(bool, reportMustSucceedExecutableAllocations, false, nullptr) \
     \
-    v(bool, forceDFGCodeBlockLiveness, false) \
-    v(bool, forceICFailure, false) \
+    v(unsigned, maxPerThreadStackUsage, 4 * MB, nullptr) \
+    v(unsigned, reservedZoneSize, 128 * KB, nullptr) \
+    v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
     \
-    v(bool, dumpGeneratedBytecodes, false) \
-    v(bool, dumpBytecodeLivenessResults, false) \
-    v(bool, validateBytecode, false) \
-    v(bool, forceDebuggerBytecodeGeneration, false) \
-    v(bool, forceProfilerBytecodeGeneration, false) \
+    v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
+    v(unsigned, jitMemoryReservationSize, 0, nullptr) \
     \
-    /* showDisassembly implies showDFGDisassembly. */ \
-    v(bool, showDisassembly, false) \
-    v(bool, showDFGDisassembly, false) \
-    v(bool, showFTLDisassembly, false) \
-    v(bool, showAllDFGNodes, false) \
-    v(optionRange, bytecodeRangeToDFGCompile, 0) \
-    v(optionString, dfgFunctionWhitelistFile, nullptr) \
-    v(bool, dumpBytecodeAtDFGTime, false) \
-    v(bool, dumpGraphAtEachPhase, false) \
-    v(bool, verboseDFGByteCodeParsing, false) \
-    v(bool, verboseCompilation, false) \
-    v(bool, verboseFTLCompilation, false) \
-    v(bool, logCompilationChanges, false) \
-    v(bool, printEachOSRExit, false) \
-    v(bool, validateGraph, false) \
-    v(bool, validateGraphAtEachPhase, false) \
-    v(bool, verboseOSR, false) \
-    v(bool, verboseFTLOSRExit, false) \
-    v(bool, verboseCallLink, false) \
-    v(bool, verboseCompilationQueue, false) \
-    v(bool, reportCompileTimes, false) \
-    v(bool, reportFTLCompileTimes, false) \
-    v(bool, verboseCFA, false) \
-    v(bool, verboseFTLToJSThunk, false) \
-    v(bool, verboseFTLFailure, false) \
-    v(bool, alwaysComputeHash, false) \
-    v(bool, testTheFTL, false) \
-    v(bool, verboseSanitizeStack, false) \
-    v(bool, alwaysDoFullCollection, false) \
-    v(bool, eagerlyUpdateTopCallFrame, false) \
-    \
-    v(bool, enableOSREntryToDFG, true) \
-    v(bool, enableOSREntryToFTL, true) \
-    \
-    v(bool, useFTLJIT, true) \
-    v(bool, enableExperimentalFTLCoverage, false) \
-    v(bool, useFTLTBAA, true) \
-    v(bool, enableLLVMFastISel, false) \
-    v(bool, useLLVMSmallCodeModel, false) \
-    v(bool, dumpLLVMIR, false) \
-    v(bool, validateFTLOSRExitLiveness, false) \
-    v(bool, llvmAlwaysFailsBeforeCompile, false) \
-    v(bool, llvmAlwaysFailsBeforeLink, false) \
-    v(bool, llvmSimpleOpt, true) \
-    v(unsigned, llvmBackendOptimizationLevel, 2) \
-    v(unsigned, llvmOptimizationLevel, 2) \
-    v(unsigned, llvmSizeLevel, 0) \
-    v(unsigned, llvmMaxStackSize, 128 * KB) \
-    v(bool, llvmDisallowAVX, true) \
-    v(bool, ftlCrashes, false) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
-    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED) \
-    v(bool, assumeAllRegsInFTLICAreLive, false) \
-    v(bool, enableAccessInlining, true) \
-    v(bool, enablePolyvariantDevirtualization, true) \
-    v(bool, enablePolymorphicAccessInlining, true) \
-    \
-    v(bool, enableConcurrentJIT, true) \
-    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1) \
-    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1) \
-    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0)) \
-    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0)) \
-    \
-    v(bool, enableProfiler, false) \
-    \
-    v(bool, forceUDis86Disassembler, false) \
-    v(bool, forceLLVMDisassembler, false) \
-    \
-    v(bool, enableArchitectureSpecificOptimizations, true) \
-    \
-    v(bool, breakOnThrow, false) \
-    \
-    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000) \
-    \
-    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180) \
-    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100) \
-    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100) \
-    \
-    v(unsigned, maximumFTLCandidateInstructionCount, 20000) \
-    \
-    /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
-    v(unsigned, maximumInliningDepth, 5) \
-    v(unsigned, maximumInliningRecursion, 2) \
-    v(unsigned, maximumInliningDepthForMustInline, 7) \
-    v(unsigned, maximumInliningRecursionForMustInline, 3) \
-    \
-    /* Maximum size of a caller for enabling inlining. This is purely to protect us */\
-    /* from super long compiles that take a lot of memory. */\
-    v(unsigned, maximumInliningCallerSize, 10000) \
-    \
-    v(bool, enablePolyvariantCallInlining, true) \
-    v(bool, enablePolyvariantByIdInlining, true) \
-    \
-    v(unsigned, maximumBinaryStringSwitchCaseLength, 50) \
-    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000) \
-    \
-    v(int32, thresholdForJITAfterWarmUp, 500) \
-    v(int32, thresholdForJITSoon, 100) \
-    \
-    v(int32, thresholdForOptimizeAfterWarmUp, 1000) \
-    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000) \
-    v(int32, thresholdForOptimizeSoon, 1000) \
-    v(int32, executionCounterIncrementForLoop, 1) \
-    v(int32, executionCounterIncrementForEntry, 15) \
-    \
-    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000) \
-    v(int32, thresholdForFTLOptimizeSoon, 1000) \
-    v(int32, ftlTierUpCounterIncrementForLoop, 1) \
-    v(int32, ftlTierUpCounterIncrementForReturn, 15) \
-    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15) \
-    v(unsigned, ftlOSREntryRetryThreshold, 100) \
-    \
-    v(int32, evalThresholdMultiplier, 10) \
-    \
-    v(bool, randomizeExecutionCountsBetweenCheckpoints, false) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000) \
-    \
-    v(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \
-    v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
-    \
-    v(unsigned, osrExitCountForReoptimization, 100) \
-    v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
-    \
-    v(unsigned, reoptimizationRetryCounterMax, 0)  \
-    v(unsigned, reoptimizationRetryCounterStep, 1) \
+    v(bool, forceDFGCodeBlockLiveness, false, nullptr) \
+    v(bool, forceICFailure, false, nullptr) \
     \
-    v(unsigned, minimumOptimizationDelay, 1) \
-    v(unsigned, maximumOptimizationDelay, 5) \
-    v(double, desiredProfileLivenessRate, 0.75) \
-    v(double, desiredProfileFullnessRate, 0.35) \
+    v(bool, dumpGeneratedBytecodes, false, nullptr) \
+    v(bool, dumpBytecodeLivenessResults, false, nullptr) \
+    v(bool, validateBytecode, false, nullptr) \
+    v(bool, forceDebuggerBytecodeGeneration, false, nullptr) \
+    v(bool, forceProfilerBytecodeGeneration, false, nullptr) \
     \
-    v(double, doubleVoteRatioForDoubleFormat, 2) \
-    v(double, structureCheckVoteRatioForHoisting, 1) \
-    v(double, checkArrayVoteRatioForHoisting, 1) \
+    v(bool, enableFunctionDotArguments, true, nullptr) \
     \
-    v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
-    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
-    v(unsigned, opaqueRootMergeThreshold, 1000) \
-    v(double, minHeapUtilization, 0.8) \
-    v(double, minCopiedBlockUtilization, 0.9) \
-    v(double, minMarkedBlockUtilization, 0.9) \
-    v(unsigned, slowPathAllocsBetweenGCs, 0) \
-    \
-    v(double, percentCPUPerMBForFullTimer, 0.0003125) \
-    v(double, percentCPUPerMBForEdenTimer, 0.0025) \
-    v(double, collectionTimerMaxPercentCPU, 0.05) \
-    \
-    v(bool, forceWeakRandomSeed, false) \
-    v(unsigned, forcedWeakRandomSeed, 0) \
+    /* showDisassembly implies showDFGDisassembly. */ \
+    v(bool, showDisassembly, false, "dumps disassembly of all JIT compiled code upon compilation") \
+    v(bool, asyncDisassembly, false, nullptr) \
+    v(bool, showDFGDisassembly, false, "dumps disassembly of DFG function upon compilation") \
+    v(bool, showFTLDisassembly, false, "dumps disassembly of FTL function upon compilation") \
+    v(bool, showAllDFGNodes, false, nullptr) \
+    v(optionRange, bytecodeRangeToDFGCompile, 0, "bytecode size range to allow DFG compilation on, e.g. 1:100") \
+    v(optionString, dfgWhitelist, nullptr, "file with list of function signatures to allow DFG compilation on") \
+    v(bool, dumpSourceAtDFGTime, false, "dumps source code of JS function being DFG compiled") \
+    v(bool, dumpBytecodeAtDFGTime, false, "dumps bytecode of JS function being DFG compiled") \
+    v(bool, dumpGraphAfterParsing, false, nullptr) \
+    v(bool, dumpGraphAtEachPhase, false, nullptr) \
+    v(bool, verboseDFGByteCodeParsing, false, nullptr) \
+    v(bool, verboseCompilation, false, nullptr) \
+    v(bool, verboseFTLCompilation, false, nullptr) \
+    v(bool, logCompilationChanges, false, nullptr) \
+    v(bool, printEachOSRExit, false, nullptr) \
+    v(bool, validateGraph, false, nullptr) \
+    v(bool, validateGraphAtEachPhase, false, nullptr) \
+    v(bool, verboseValidationFailure, false, nullptr) \
+    v(bool, verboseOSR, false, nullptr) \
+    v(bool, verboseFTLOSRExit, false, nullptr) \
+    v(bool, verboseCallLink, false, nullptr) \
+    v(bool, verboseCompilationQueue, false, nullptr) \
+    v(bool, reportCompileTimes, false, "dumps JS function signature and the time it took to compile") \
+    v(bool, reportFTLCompileTimes, false, "dumps JS function signature and the time it took to FTL compile") \
+    v(bool, verboseCFA, false, nullptr) \
+    v(bool, verboseFTLToJSThunk, false, nullptr) \
+    v(bool, verboseFTLFailure, false, nullptr) \
+    v(bool, alwaysComputeHash, false, nullptr) \
+    v(bool, testTheFTL, false, nullptr) \
+    v(bool, verboseSanitizeStack, false, nullptr) \
+    v(bool, alwaysDoFullCollection, false, nullptr) \
+    v(bool, eagerlyUpdateTopCallFrame, false, nullptr) \
+    \
+    v(bool, enableOSREntryToDFG, true, nullptr) \
+    v(bool, enableOSREntryToFTL, true, nullptr) \
+    \
+    v(bool, useFTLJIT, true, "allows the FTL JIT to be used if true") \
+    v(bool, useFTLTBAA, true, nullptr) \
+    v(bool, enableLLVMFastISel, false, nullptr) \
+    v(bool, useLLVMSmallCodeModel, false, nullptr) \
+    v(bool, dumpLLVMIR, false, nullptr) \
+    v(bool, validateFTLOSRExitLiveness, false, nullptr) \
+    v(bool, llvmAlwaysFailsBeforeCompile, false, nullptr) \
+    v(bool, llvmAlwaysFailsBeforeLink, false, nullptr) \
+    v(bool, llvmSimpleOpt, true, nullptr) \
+    v(unsigned, llvmBackendOptimizationLevel, 2, nullptr) \
+    v(unsigned, llvmOptimizationLevel, 2, nullptr) \
+    v(unsigned, llvmSizeLevel, 0, nullptr) \
+    v(unsigned, llvmMaxStackSize, 128 * KB, nullptr) \
+    v(bool, llvmDisallowAVX, true, nullptr) \
+    v(bool, ftlCrashes, false, nullptr) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
+    v(bool, ftlCrashesIfCantInitializeLLVM, false, nullptr) \
+    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, nullptr) \
+    v(bool, assumeAllRegsInFTLICAreLive, false, nullptr) \
+    v(bool, enableAccessInlining, true, nullptr) \
+    v(bool, enablePolyvariantDevirtualization, true, nullptr) \
+    v(bool, enablePolymorphicAccessInlining, true, nullptr) \
+    v(bool, enablePolymorphicCallInlining, true, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSize, 15, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantsForInlining, 5, nullptr) \
+    v(unsigned, frequentCallThreshold, 2, nullptr) \
+    v(double, minimumCallToKnownRate, 0.51, nullptr) \
+    v(bool, optimizeNativeCalls, false, nullptr) \
+    v(bool, enableMovHintRemoval, true, nullptr) \
+    v(bool, enableObjectAllocationSinking, true, nullptr) \
+    \
+    v(bool, enableConcurrentJIT, true, "allows the DFG / FTL compilation in threads other than the executing JS thread") \
+    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1, nullptr) \
+    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1, nullptr) \
+    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0), nullptr) \
+    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0), nullptr) \
+    \
+    v(bool, enableProfiler, false, nullptr) \
+    \
+    v(bool, forceUDis86Disassembler, false, nullptr) \
+    v(bool, forceLLVMDisassembler, false, nullptr) \
+    \
+    v(bool, enableArchitectureSpecificOptimizations, true, nullptr) \
+    \
+    v(bool, breakOnThrow, false, nullptr) \
+    \
+    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, nullptr) \
+    \
+    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, nullptr) \
+    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, nullptr) \
+    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, nullptr) \
+    \
+    v(unsigned, maximumFTLCandidateInstructionCount, 20000, nullptr) \
     \
-    v(bool, useZombieMode, false) \
-    v(bool, objectsAreImmortal, false) \
-    v(bool, showObjectStatistics, false) \
+    /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
+    v(unsigned, maximumInliningDepth, 5, "maximum allowed inlining depth.  Depth of 1 means no inlining") \
+    v(unsigned, maximumInliningRecursion, 2, nullptr) \
     \
-    v(gcLogLevel, logGC, GCLogging::None) \
-    v(bool, disableGC, false) \
-    v(unsigned, gcMaxHeapSize, 0) \
-    v(bool, recordGCPauseTimes, false) \
-    v(bool, logHeapStatisticsAtExit, false) \
+    v(unsigned, maximumLLVMInstructionCountForNativeInlining, 80, nullptr) \
     \
-    v(bool, enableExceptionFuzz, false) \
-    v(unsigned, fireExceptionFuzzAt, 0)
+    /* Maximum size of a caller for enabling inlining. This is purely to protect us */\
+    /* from super long compiles that take a lot of memory. */\
+    v(unsigned, maximumInliningCallerSize, 10000, nullptr) \
+    \
+    v(unsigned, maximumVarargsForInlining, 100, nullptr) \
+    \
+    v(bool, enablePolyvariantCallInlining, true, nullptr) \
+    v(bool, enablePolyvariantByIdInlining, true, nullptr) \
+    \
+    v(unsigned, maximumBinaryStringSwitchCaseLength, 50, nullptr) \
+    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000, nullptr) \
+    \
+    v(double, jitPolicyScale, 1.0, "scale JIT thresholds to this specified ratio between 0.0 (compile ASAP) and 1.0 (compile like normal).") \
+    v(bool, forceEagerCompilation, false, nullptr) \
+    v(int32, thresholdForJITAfterWarmUp, 500, nullptr) \
+    v(int32, thresholdForJITSoon, 100, nullptr) \
+    \
+    v(int32, thresholdForOptimizeAfterWarmUp, 1000, nullptr) \
+    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000, nullptr) \
+    v(int32, thresholdForOptimizeSoon, 1000, nullptr) \
+    v(int32, executionCounterIncrementForLoop, 1, nullptr) \
+    v(int32, executionCounterIncrementForEntry, 15, nullptr) \
+    \
+    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000, nullptr) \
+    v(int32, thresholdForFTLOptimizeSoon, 1000, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForLoop, 1, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForReturn, 15, nullptr) \
+    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15, nullptr) \
+    v(unsigned, ftlOSREntryRetryThreshold, 100, nullptr) \
+    \
+    v(int32, evalThresholdMultiplier, 10, nullptr) \
+    v(unsigned, maximumEvalCacheableSourceLength, 256, nullptr) \
+    \
+    v(bool, randomizeExecutionCountsBetweenCheckpoints, false, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000, nullptr) \
+    \
+    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20, nullptr) \
+    v(unsigned, couldTakeSlowCaseMinimumCount, 10, nullptr) \
+    \
+    v(unsigned, osrExitCountForReoptimization, 100, nullptr) \
+    v(unsigned, osrExitCountForReoptimizationFromLoop, 5, nullptr) \
+    \
+    v(unsigned, reoptimizationRetryCounterMax, 0, nullptr)  \
+    \
+    v(unsigned, minimumOptimizationDelay, 1, nullptr) \
+    v(unsigned, maximumOptimizationDelay, 5, nullptr) \
+    v(double, desiredProfileLivenessRate, 0.75, nullptr) \
+    v(double, desiredProfileFullnessRate, 0.35, nullptr) \
+    \
+    v(double, doubleVoteRatioForDoubleFormat, 2, nullptr) \
+    v(double, structureCheckVoteRatioForHoisting, 1, nullptr) \
+    v(double, checkArrayVoteRatioForHoisting, 1, nullptr) \
+    \
+    v(unsigned, minimumNumberOfScansBetweenRebalance, 100, nullptr) \
+    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7), nullptr) \
+    v(unsigned, opaqueRootMergeThreshold, 1000, nullptr) \
+    v(double, minHeapUtilization, 0.8, nullptr) \
+    v(double, minCopiedBlockUtilization, 0.9, nullptr) \
+    v(double, minMarkedBlockUtilization, 0.9, nullptr) \
+    v(unsigned, slowPathAllocsBetweenGCs, 0, "force a GC on every Nth slow path alloc, where N is specified by this option") \
+    \
+    v(double, percentCPUPerMBForFullTimer, 0.0003125, nullptr) \
+    v(double, percentCPUPerMBForEdenTimer, 0.0025, nullptr) \
+    v(double, collectionTimerMaxPercentCPU, 0.05, nullptr) \
+    \
+    v(bool, forceWeakRandomSeed, false, nullptr) \
+    v(unsigned, forcedWeakRandomSeed, 0, nullptr) \
+    \
+    v(bool, useZombieMode, false, "debugging option to scribble over dead objects with 0xdeadbeef") \
+    v(bool, objectsAreImmortal, false, "debugging option to keep all objects alive forever") \
+    v(bool, showObjectStatistics, false, nullptr) \
+    \
+    v(gcLogLevel, logGC, GCLogging::None, "debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)") \
+    v(bool, disableGC, false, nullptr) \
+    v(unsigned, gcMaxHeapSize, 0, nullptr) \
+    v(unsigned, forceRAMSize, 0, nullptr) \
+    v(bool, recordGCPauseTimes, false, nullptr) \
+    v(bool, logHeapStatisticsAtExit, false, nullptr) \
+    v(bool, enableTypeProfiler, false, nullptr) \
+    v(bool, enableControlFlowProfiler, false, nullptr) \
+    \
+    v(bool, verifyHeap, false, nullptr) \
+    v(unsigned, numberOfGCCyclesToRecordForVerification, 3, nullptr) \
+    \
+    v(bool, enableExceptionFuzz, false, nullptr) \
+    v(unsigned, fireExceptionFuzzAt, 0, nullptr) \
+    \
+    v(bool, enableExecutableAllocationFuzz, false, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAt, 0, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0, nullptr) \
+    v(bool, verboseExecutableAllocationFuzz, false, nullptr) \
+    \
+    v(bool, enableOSRExitFuzz, false, nullptr) \
+    v(unsigned, fireOSRExitFuzzAtStatic, 0, nullptr) \
+    v(unsigned, fireOSRExitFuzzAt, 0, nullptr) \
+    v(unsigned, fireOSRExitFuzzAtOrAfter, 0, nullptr) \
+    \
+    v(bool, enableDollarVM, false, "installs the $vm debugging tool in global objects") \
+    v(optionString, functionOverrides, nullptr, "file with debugging overrides for function bodies") \
 
 class Options {
 public:
+    enum class DumpLevel {
+        None = 0,
+        Overridden,
+        All,
+        Verbose
+    };
+    
     // This typedef is to allow us to eliminate the '_' in the field name in
     // union inside Entry. This is needed to keep the style checker happy.
     typedef int32_t int32;
 
     // Declare the option IDs:
     enum OptionID {
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-        OPT_##name_,
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+        name_##ID,
         JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
         numberOfOptions
     };
 
+    enum class Type {
+        boolType,
+        unsignedType,
+        doubleType,
+        int32Type,
+        optionRangeType,
+        optionStringType,
+        gcLogLevelType,
+    };
 
-    static void initialize();
+    JS_EXPORT_PRIVATE static void initialize();
 
     // Parses a single command line option in the format "<optionName>=<value>"
     // (no spaces allowed) and set the specified option if appropriate.
     JS_EXPORT_PRIVATE static bool setOption(const char* arg);
-    JS_EXPORT_PRIVATE static void dumpAllOptions(FILE* stream = stdout);
-    static void dumpOption(OptionID id, FILE* stream = stdout, const char* header = "", const char* footer = "");
+    JS_EXPORT_PRIVATE static void dumpAllOptions(DumpLevel, const char* title = nullptr, FILE* stream = stdout);
+    static void dumpOption(DumpLevel, OptionID, FILE* stream = stdout, const char* header = "", const char* footer = "");
+    JS_EXPORT_PRIVATE static void ensureOptionsAreCoherent();
 
     // Declare accessors for each option:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    ALWAYS_INLINE static type_& name_() { return s_options[OPT_##name_].u.type_##Val; } \
-    static bool name_##WasOverridden() { return s_options[OPT_##name_].didOverride; }
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    ALWAYS_INLINE static type_& name_() { return s_options[name_##ID].type_##Val; } \
+    ALWAYS_INLINE static type_& name_##Default() { return s_defaultOptions[name_##ID].type_##Val; }
 
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
 private:
-    enum EntryType {
-        boolType,
-        unsignedType,
-        doubleType,
-        int32Type,
-        optionRangeType,
-        optionStringType,
-        gcLogLevelType,
-    };
-
     // For storing for an option value:
-    struct Entry {
-        union {
-            bool boolVal;
-            unsigned unsignedVal;
-            double doubleVal;
-            int32 int32Val;
-            OptionRange optionRangeVal;
-            const char* optionStringVal;
-            GCLogging::Level gcLogLevelVal;
-        } u;
-        bool didOverride;
+    union Entry {
+        bool boolVal;
+        unsigned unsignedVal;
+        double doubleVal;
+        int32 int32Val;
+        OptionRange optionRangeVal;
+        const char* optionStringVal;
+        GCLogging::Level gcLogLevelVal;
     };
 
     // For storing constant meta data about each option:
     struct EntryInfo {
         const char* name;
-        EntryType type;
+        const char* description;
+        Type type;
     };
 
     Options();
 
-    // Declare the options:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    type_ m_##name_;
-    JSC_OPTIONS(FOR_EACH_OPTION)
-#undef FOR_EACH_OPTION
-
     // Declare the singleton instance of the options store:
     JS_EXPORTDATA static Entry s_options[numberOfOptions];
+    static Entry s_defaultOptions[numberOfOptions];
     static const EntryInfo s_optionsInfo[numberOfOptions];
+
+    friend class Option;
 };
 
+class Option {
+public:
+    Option(Options::OptionID id)
+        : m_id(id)
+        , m_entry(Options::s_options[m_id])
+    {
+    }
+    
+    void dump(FILE*) const;
+    bool operator==(const Option& other) const;
+    bool operator!=(const Option& other) const { return !(*this == other); }
+    
+    const char* name() const;
+    const char* description() const;
+    Options::Type type() const;
+    bool isOverridden() const;
+    const Option defaultOption() const;
+    
+    bool& boolVal();
+    unsigned& unsignedVal();
+    double& doubleVal();
+    int32_t& int32Val();
+    OptionRange optionRangeVal();
+    const char* optionStringVal();
+    GCLogging::Level& gcLogLevelVal();
+    
+private:
+    // Only used for constructing default Options.
+    Option(Options::OptionID id, Options::Entry& entry)
+        : m_id(id)
+        , m_entry(entry)
+    {
+    }
+    
+    Options::OptionID m_id;
+    Options::Entry& m_entry;
+};
+
+inline const char* Option::name() const
+{
+    return Options::s_optionsInfo[m_id].name;
+}
+
+inline const char* Option::description() const
+{
+    return Options::s_optionsInfo[m_id].description;
+}
+
+inline Options::Type Option::type() const
+{
+    return Options::s_optionsInfo[m_id].type;
+}
+
+inline bool Option::isOverridden() const
+{
+    return *this != defaultOption();
+}
+
+inline const Option Option::defaultOption() const
+{
+    return Option(m_id, Options::s_defaultOptions[m_id]);
+}
+
+inline bool& Option::boolVal()
+{
+    return m_entry.boolVal;
+}
+
+inline unsigned& Option::unsignedVal()
+{
+    return m_entry.unsignedVal;
+}
+
+inline double& Option::doubleVal()
+{
+    return m_entry.doubleVal;
+}
+
+inline int32_t& Option::int32Val()
+{
+    return m_entry.int32Val;
+}
+
+inline OptionRange Option::optionRangeVal()
+{
+    return m_entry.optionRangeVal;
+}
+
+inline const char* Option::optionStringVal()
+{
+    return m_entry.optionStringVal;
+}
+
+inline GCLogging::Level& Option::gcLogLevelVal()
+{
+    return m_entry.gcLogLevelVal;
+}
+
 } // namespace JSC
 
 #endif // Options_h
index 5d2774a2031363e09ed6ed746b1c8cf0ef20167c..2b6ba017db6700d5e1960889bc7b47e5be94d914 100644 (file)
 #ifndef PrivateName_h
 #define PrivateName_h
 
-#include <wtf/text/StringImpl.h>
+#include <wtf/text/SymbolImpl.h>
 
 namespace JSC {
 
 class PrivateName {
 public:
     PrivateName()
-        : m_impl(StringImpl::createEmptyUnique())
+        : m_uid(StringImpl::createSymbolEmpty())
     {
     }
-    explicit PrivateName(StringImpl* uid)
-        : m_impl(uid)
+
+    explicit PrivateName(SymbolImpl& uid)
+        : m_uid(&uid)
     {
-        ASSERT(m_impl->isEmptyUnique());
     }
 
-    StringImpl* uid() const { return m_impl.get(); }
+    enum DescriptionTag { Description };
+    explicit PrivateName(DescriptionTag, const String& description)
+        : m_uid(StringImpl::createSymbol(description.impl()))
+    {
+    }
+
+    SymbolImpl* uid() const { return m_uid.get(); }
+
+    bool operator==(const PrivateName& other) const { return uid() == other.uid(); }
+    bool operator!=(const PrivateName& other) const { return uid() != other.uid(); }
 
 private:
-    RefPtr<StringImpl> m_impl;
+    RefPtr<SymbolImpl> m_uid;
 };
 
 }
index 450920c555e4d1ee4a3e10c20f7b07ca7bc64b44..5722e88da0fab36bcaf185db1c5415618ad7fe54 100644 (file)
@@ -106,8 +106,8 @@ void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes)
         m_attributes &= ~ReadOnly; // FIXME: we should be able to ASSERT this!
 
         GetterSetter* accessor = asGetterSetter(value);
-        m_getter = accessor->getter() ? accessor->getter() : jsUndefined();
-        m_setter = accessor->setter() ? accessor->setter() : jsUndefined();
+        m_getter = !accessor->isGetterNull() ? accessor->getter() : jsUndefined();
+        m_setter = !accessor->isSetterNull() ? accessor->setter() : jsUndefined();
         m_seenAttributes = EnumerablePresent | ConfigurablePresent;
     } else {
         m_value = value;
@@ -131,8 +131,8 @@ void PropertyDescriptor::setAccessorDescriptor(GetterSetter* accessor, unsigned
     attributes &= ~ReadOnly; // FIXME: we should be able to ASSERT this!
 
     m_attributes = attributes;
-    m_getter = accessor->getter() ? accessor->getter() : jsUndefined();
-    m_setter = accessor->setter() ? accessor->setter() : jsUndefined();
+    m_getter = !accessor->isGetterNull() ? accessor->getter() : jsUndefined();
+    m_setter = !accessor->isSetterNull() ? accessor->setter() : jsUndefined();
     m_seenAttributes = EnumerablePresent | ConfigurablePresent;
 }
 
@@ -186,8 +186,10 @@ bool sameValue(ExecState* exec, JSValue a, JSValue b)
         return false;
     double x = a.asNumber();
     double y = b.asNumber();
-    if (std::isnan(x))
-        return std::isnan(y);
+    bool xIsNaN = std::isnan(x);
+    bool yIsNaN = std::isnan(y);
+    if (xIsNaN || yIsNaN)
+        return xIsNaN && yIsNaN;
     return bitwise_cast<uint64_t>(x) == bitwise_cast<uint64_t>(y);
 }
 
index df74d9e15af968fcf9fb2f43822c2806c88b616a..0345b4e4aef82cf5df3415df5e1d5e0e51b35152 100644 (file)
 #include "JSCJSValue.h"
 
 namespace JSC {
-    class GetterSetter;
 
-    // See ES5.1 9.12
-    bool sameValue(ExecState*, JSValue, JSValue);
+class GetterSetter;
 
-    class PropertyDescriptor {
-    public:
-        PropertyDescriptor()
-            : m_attributes(defaultAttributes)
-            , m_seenAttributes(0)
-        {
-        }
-        PropertyDescriptor(JSValue value, unsigned attributes)
-            : m_value(value)
-            , m_attributes(attributes)
-            , m_seenAttributes(EnumerablePresent | ConfigurablePresent | WritablePresent)
-        {
-            ASSERT(m_value);
-            ASSERT(!m_value.isGetterSetter());
-            ASSERT(!m_value.isCustomGetterSetter());
-        }
-        JS_EXPORT_PRIVATE bool writable() const;
-        JS_EXPORT_PRIVATE bool enumerable() const;
-        JS_EXPORT_PRIVATE bool configurable() const;
-        JS_EXPORT_PRIVATE bool isDataDescriptor() const;
-        bool isGenericDescriptor() const;
-        JS_EXPORT_PRIVATE bool isAccessorDescriptor() const;
-        unsigned attributes() const { return m_attributes; }
-        JSValue value() const { return m_value; }
-        JS_EXPORT_PRIVATE JSValue getter() const;
-        JS_EXPORT_PRIVATE JSValue setter() const;
-        JSObject* getterObject() const;
-        JSObject* setterObject() const;
-        JS_EXPORT_PRIVATE void setUndefined();
-        JS_EXPORT_PRIVATE void setDescriptor(JSValue value, unsigned attributes);
-        JS_EXPORT_PRIVATE void setCustomDescriptor(unsigned attributes);
-        JS_EXPORT_PRIVATE void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
-        JS_EXPORT_PRIVATE void setWritable(bool);
-        JS_EXPORT_PRIVATE void setEnumerable(bool);
-        JS_EXPORT_PRIVATE void setConfigurable(bool);
-        void setValue(JSValue value) { m_value = value; }
-        JS_EXPORT_PRIVATE void setSetter(JSValue);
-        JS_EXPORT_PRIVATE void setGetter(JSValue);
-        bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); }
-        bool writablePresent() const { return m_seenAttributes & WritablePresent; }
-        bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; }
-        bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; }
-        bool setterPresent() const { return m_setter; }
-        bool getterPresent() const { return m_getter; }
-        bool equalTo(ExecState* exec, const PropertyDescriptor& other) const;
-        bool attributesEqual(const PropertyDescriptor& other) const;
-        unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
+// See ES5.1 9.12
+bool sameValue(ExecState*, JSValue, JSValue);
+
+class PropertyDescriptor {
+public:
+    PropertyDescriptor()
+        : m_attributes(defaultAttributes)
+        , m_seenAttributes(0)
+    {
+    }
+    PropertyDescriptor(JSValue value, unsigned attributes)
+        : m_value(value)
+        , m_attributes(attributes)
+        , m_seenAttributes(EnumerablePresent | ConfigurablePresent | WritablePresent)
+    {
+        ASSERT(m_value);
+        ASSERT(!m_value.isGetterSetter());
+        ASSERT(!m_value.isCustomGetterSetter());
+    }
+    JS_EXPORT_PRIVATE bool writable() const;
+    JS_EXPORT_PRIVATE bool enumerable() const;
+    JS_EXPORT_PRIVATE bool configurable() const;
+    JS_EXPORT_PRIVATE bool isDataDescriptor() const;
+    bool isGenericDescriptor() const;
+    JS_EXPORT_PRIVATE bool isAccessorDescriptor() const;
+    unsigned attributes() const { return m_attributes; }
+    JSValue value() const { return m_value; }
+    JS_EXPORT_PRIVATE JSValue getter() const;
+    JS_EXPORT_PRIVATE JSValue setter() const;
+    JSObject* getterObject() const;
+    JSObject* setterObject() const;
+    JS_EXPORT_PRIVATE void setUndefined();
+    JS_EXPORT_PRIVATE void setDescriptor(JSValue, unsigned attributes);
+    JS_EXPORT_PRIVATE void setCustomDescriptor(unsigned attributes);
+    JS_EXPORT_PRIVATE void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
+    JS_EXPORT_PRIVATE void setWritable(bool);
+    JS_EXPORT_PRIVATE void setEnumerable(bool);
+    JS_EXPORT_PRIVATE void setConfigurable(bool);
+    void setValue(JSValue value) { m_value = value; }
+    JS_EXPORT_PRIVATE void setSetter(JSValue);
+    JS_EXPORT_PRIVATE void setGetter(JSValue);
+    bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); }
+    bool writablePresent() const { return m_seenAttributes & WritablePresent; }
+    bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; }
+    bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; }
+    bool setterPresent() const { return !!m_setter; }
+    bool getterPresent() const { return !!m_getter; }
+    bool equalTo(ExecState*, const PropertyDescriptor& other) const;
+    bool attributesEqual(const PropertyDescriptor& other) const;
+    unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
+
+private:
+    JS_EXPORTDATA static unsigned defaultAttributes;
+    bool operator==(const PropertyDescriptor&) { return false; }
+    enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4};
+    // May be a getter/setter
+    JSValue m_value;
+    JSValue m_getter;
+    JSValue m_setter;
+    unsigned m_attributes;
+    unsigned m_seenAttributes;
+};
 
-    private:
-        JS_EXPORTDATA static unsigned defaultAttributes;
-        bool operator==(const PropertyDescriptor&){ return false; }
-        enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4};
-        // May be a getter/setter
-        JSValue m_value;
-        JSValue m_getter;
-        JSValue m_setter;
-        unsigned m_attributes;
-        unsigned m_seenAttributes;
-    };
 }
 
 #endif
index 5da5cf347884609808231a760085fe558eb3812e..b068b991dead55814c49d207428bcb6d1637edca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #include <wtf/CryptographicallyRandomNumber.h>
 #include <wtf/HashTable.h>
 #include <wtf/MathExtras.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/Vector.h>
-#include <wtf/text/StringImpl.h>
+#include <wtf/text/AtomicStringImpl.h>
 
 
 #define DUMP_PROPERTYMAP_STATS 0
 #define DUMP_PROPERTYMAP_COLLISIONS 0
 
-#define PROPERTY_MAP_DELETED_ENTRY_KEY ((StringImpl*)1)
+#define PROPERTY_MAP_DELETED_ENTRY_KEY ((UniquedStringImpl*)1)
 
 namespace JSC {
 
@@ -78,22 +77,7 @@ inline unsigned nextPowerOf2(unsigned v)
     return v;
 }
 
-struct PropertyMapEntry {
-    StringImpl* key;
-    PropertyOffset offset;
-    unsigned attributes;
-    WriteBarrier<JSCell> specificValue;
-
-    PropertyMapEntry(VM& vm, JSCell* owner, StringImpl* key, PropertyOffset offset, unsigned attributes, JSCell* specificValue)
-        : key(key)
-        , offset(offset)
-        , attributes(attributes)
-        , specificValue(vm, owner, specificValue, WriteBarrier<JSCell>::MayBeNull)
-    {
-    }
-};
-
-class PropertyTable : public JSCell {
+class PropertyTable final : public JSCell {
 
     // This is the implementation for 'iterator' and 'const_iterator',
     // used for iterating over the table in insertion order.
@@ -136,20 +120,20 @@ class PropertyTable : public JSCell {
     };
 
 public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     DECLARE_EXPORT_INFO;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    typedef StringImpl* KeyType;
+    typedef UniquedStringImpl* KeyType;
     typedef PropertyMapEntry ValueType;
 
     // The in order iterator provides overloaded * and -> to access the Value at the current position.
@@ -175,7 +159,6 @@ public:
 
     // Find a value in the table.
     find_iterator find(const KeyType&);
-    find_iterator findWithString(const KeyType&);
     ValueType* get(const KeyType&);
     // Add a value to the table
     enum EffectOnPropertyOffset { PropertyOffsetMayChange, PropertyOffsetMustNotChange };
@@ -209,9 +192,6 @@ public:
     void checkConsistency();
 #endif
 
-protected:
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal;
-
 private:
     PropertyTable(VM&, unsigned initialCapacity);
     PropertyTable(VM&, const PropertyTable&);
@@ -261,7 +241,7 @@ private:
     unsigned* m_index;
     unsigned m_keyCount;
     unsigned m_deletedCount;
-    OwnPtr< Vector<PropertyOffset>> m_deletedOffsets;
+    std::unique_ptr<Vector<PropertyOffset>> m_deletedOffsets;
 
     static const unsigned MinimumTableSize = 16;
     static const unsigned EmptyEntryIndex = 0;
@@ -290,8 +270,8 @@ inline PropertyTable::const_iterator PropertyTable::end() const
 inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
 {
     ASSERT(key);
-    ASSERT(key->isAtomic() || key->isEmptyUnique());
-    unsigned hash = key->existingHash();
+    ASSERT(key->isAtomic() || key->isSymbol());
+    unsigned hash = IdentifierRepHash::hash(key);
     unsigned step = 0;
 
 #if DUMP_PROPERTYMAP_STATS
@@ -306,7 +286,7 @@ inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
             return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask);
 
         if (!step)
-            step = WTF::doubleHash(key->existingHash()) | 1;
+            step = WTF::doubleHash(IdentifierRepHash::hash(key)) | 1;
 
 #if DUMP_PROPERTYMAP_STATS
         ++propertyMapHashTableStats->numCollisions;
@@ -314,7 +294,7 @@ inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
 
 #if DUMP_PROPERTYMAP_COLLISIONS
         dataLog("PropertyTable collision for ", key, " (", hash, ") with step ", step, "\n");
-        dataLog("Collided with ", table()[entryIndex - 1].key, "(", table()[entryIndex - 1].key->existingHash(), ")\n");
+        dataLog("Collided with ", table()[entryIndex - 1].key, "(", IdentifierRepHash::hash(table()[entryIndex - 1].key), ")\n");
 #endif
 
         hash += step;
@@ -324,12 +304,12 @@ inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
 inline PropertyTable::ValueType* PropertyTable::get(const KeyType& key)
 {
     ASSERT(key);
-    ASSERT(key->isAtomic() || key->isEmptyUnique());
+    ASSERT(key->isAtomic() || key->isSymbol());
 
     if (!m_keyCount)
         return nullptr;
 
-    unsigned hash = key->existingHash();
+    unsigned hash = IdentifierRepHash::hash(key);
     unsigned step = 0;
 
 #if DUMP_PROPERTYMAP_STATS
@@ -348,36 +328,7 @@ inline PropertyTable::ValueType* PropertyTable::get(const KeyType& key)
 #endif
 
         if (!step)
-            step = WTF::doubleHash(key->existingHash()) | 1;
-        hash += step;
-    }
-}
-
-inline PropertyTable::find_iterator PropertyTable::findWithString(const KeyType& key)
-{
-    ASSERT(key);
-    ASSERT(!key->isAtomic() && !key->hasHash());
-    unsigned hash = key->hash();
-    unsigned step = 0;
-
-#if DUMP_PROPERTYMAP_STATS
-    ++propertyMapHashTableStats->numLookups;
-#endif
-
-    while (true) {
-        unsigned entryIndex = m_index[hash & m_indexMask];
-        if (entryIndex == EmptyEntryIndex)
-            return std::make_pair((ValueType*)0, hash & m_indexMask);
-        const KeyType& keyInMap = table()[entryIndex - 1].key;
-        if (equal(key, keyInMap) && keyInMap->isAtomic())
-            return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask);
-
-#if DUMP_PROPERTYMAP_STATS
-        ++propertyMapHashTableStats->numLookupProbing;
-#endif
-
-        if (!step)
-            step = WTF::doubleHash(key->existingHash()) | 1;
+            step = WTF::doubleHash(IdentifierRepHash::hash(key)) | 1;
         hash += step;
     }
 }
@@ -468,7 +419,7 @@ inline unsigned PropertyTable::propertyStorageSize() const
 
 inline void PropertyTable::clearDeletedOffsets()
 {
-    m_deletedOffsets.clear();
+    m_deletedOffsets = nullptr;
 }
 
 inline bool PropertyTable::hasDeletedOffset()
@@ -486,7 +437,7 @@ inline PropertyOffset PropertyTable::getDeletedOffset()
 inline void PropertyTable::addDeletedOffset(PropertyOffset offset)
 {
     if (!m_deletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>);
+        m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>();
     m_deletedOffsets->append(offset);
 }
 
index 7d2464b4449264b4313f05ed6021d5a462694900..eaba6280476bba95306ceb46c601303118941226 100644 (file)
 
 #include "Identifier.h"
 #include "PrivateName.h"
+#include <wtf/Optional.h>
 
 namespace JSC {
 
-template <typename CharType>
-ALWAYS_INLINE uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length)
-{
-    // An empty string is not a number.
-    if (!length)
-        return UINT_MAX;
-
-    // Get the first character, turning it into a digit.
-    uint32_t value = characters[0] - '0';
-    if (value > 9)
-        return UINT_MAX;
-    
-    // Check for leading zeros. If the first characher is 0, then the
-    // length of the string must be one - e.g. "042" is not equal to "42".
-    if (!value && length > 1)
-        return UINT_MAX;
-    
-    while (--length) {
-        // Multiply value by 10, checking for overflow out of 32 bits.
-        if (value > 0xFFFFFFFFU / 10)
-            return UINT_MAX;
-        value *= 10;
-        
-        // Get the next character, turning it into a digit.
-        uint32_t newValue = *(++characters) - '0';
-        if (newValue > 9)
-            return UINT_MAX;
-        
-        // Add in the old value, checking for overflow out of 32 bits.
-        newValue += value;
-        if (newValue < value)
-            return UINT_MAX;
-        value = newValue;
-    }
-    
-    return value;
-}
-
-ALWAYS_INLINE uint32_t toUInt32FromStringImpl(StringImpl* impl)
-{
-    if (impl->is8Bit())
-        return toUInt32FromCharacters(impl->characters8(), impl->length());
-    return toUInt32FromCharacters(impl->characters16(), impl->length());
-}
-
 class PropertyName {
 public:
+    PropertyName(UniquedStringImpl* propertyName)
+        : m_impl(propertyName)
+    {
+    }
+
     PropertyName(const Identifier& propertyName)
-        : m_impl(propertyName.impl())
+        : PropertyName(propertyName.impl())
     {
-        ASSERT(!m_impl || m_impl->isAtomic());
     }
 
     PropertyName(const PrivateName& propertyName)
         : m_impl(propertyName.uid())
     {
-        ASSERT(m_impl && m_impl->isEmptyUnique());
+        ASSERT(m_impl);
+        ASSERT(m_impl->isSymbol());
     }
 
-    StringImpl* uid() const
+    bool isSymbol()
     {
-        return m_impl;
+        return m_impl && m_impl->isSymbol();
     }
 
-    StringImpl* publicName() const
+    UniquedStringImpl* uid() const
     {
-        return m_impl->isEmptyUnique() ? 0 : m_impl;
+        return m_impl;
     }
 
-    static const uint32_t NotAnIndex = UINT_MAX;
+    AtomicStringImpl* publicName() const
+    {
+        return (!m_impl || m_impl->isSymbol()) ? nullptr : static_cast<AtomicStringImpl*>(m_impl);
+    }
 
-    uint32_t asIndex()
+    void dump(PrintStream& out) const
     {
-        return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex;
+        if (m_impl)
+            out.print(m_impl);
+        else
+            out.print("<null property name>");
     }
 
 private:
-    StringImpl* m_impl;
+    UniquedStringImpl* m_impl;
 };
 
 inline bool operator==(PropertyName a, const Identifier& b)
@@ -126,6 +93,11 @@ inline bool operator==(PropertyName a, PropertyName b)
     return a.uid() == b.uid();
 }
 
+inline bool operator==(PropertyName a, const char* b)
+{
+    return equal(a.uid(), b);
+}
+
 inline bool operator!=(PropertyName a, const Identifier& b)
 {
     return a.uid() != b.impl();
@@ -141,6 +113,16 @@ inline bool operator!=(PropertyName a, PropertyName b)
     return a.uid() != b.uid();
 }
 
+ALWAYS_INLINE Optional<uint32_t> parseIndex(PropertyName propertyName)
+{
+    auto uid = propertyName.uid();
+    if (!uid)
+        return Nullopt;
+    if (uid->isSymbol())
+        return Nullopt;
+    return parseIndex(*uid);
+}
+
 }
 
 #endif
diff --git a/runtime/PropertyNameArray.cpp b/runtime/PropertyNameArray.cpp
deleted file mode 100644 (file)
index a8f64ea..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "PropertyNameArray.h"
-
-#include "JSCInlines.h"
-#include "JSObject.h"
-#include "Structure.h"
-#include "StructureChain.h"
-
-namespace JSC {
-
-static const size_t setThreshold = 20;
-
-void PropertyNameArray::add(StringImpl* identifier)
-{
-    ASSERT(!identifier || identifier == StringImpl::empty() || identifier->isAtomic());
-
-    size_t size = m_data->propertyNameVector().size();
-    if (size < setThreshold) {
-        for (size_t i = 0; i < size; ++i) {
-            if (identifier == m_data->propertyNameVector()[i].impl())
-                return;
-        }
-    } else {
-        if (m_set.isEmpty()) {
-            for (size_t i = 0; i < size; ++i)
-                m_set.add(m_data->propertyNameVector()[i].impl());
-        }
-        if (!m_set.add(identifier).isNewEntry)
-            return;
-    }
-
-    addKnownUnique(identifier);
-}
-
-} // namespace JSC
index bfbddaa60c1c96127a13c2e8a7f13aec58fe564f..c2f13d8c3729ae5ab7bd39db74e345883e4c8672 100644 (file)
 #include <wtf/Vector.h>
 
 namespace JSC {
-    
-    class Structure;
-    class StructureChain;
 
-    // FIXME: Rename to PropertyNameArray.
-    class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
-    public:
-        typedef Vector<Identifier, 20> PropertyNameVector;
-
-        static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); }
-
-        PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
-
-    private:
-        PropertyNameArrayData()
-        {
-        }
-
-        PropertyNameVector m_propertyNameVector;
-    };
-
-    // FIXME: Rename to PropertyNameArrayBuilder.
-    class PropertyNameArray {
-    public:
-        PropertyNameArray(VM* vm)
-            : m_data(PropertyNameArrayData::create())
-            , m_vm(vm)
-            , m_numCacheableSlots(0)
-            , m_baseObject(0)
-        {
-        }
-
-        PropertyNameArray(ExecState* exec)
-            : m_data(PropertyNameArrayData::create())
-            , m_vm(&exec->vm())
-            , m_numCacheableSlots(0)
-            , m_baseObject(0)
-        {
-        }
-
-        VM* vm() { return m_vm; }
-
-        void add(const Identifier& identifier) { add(identifier.impl()); }
-        JS_EXPORT_PRIVATE void add(StringImpl*);
-        void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_vm, identifier)); }
-
-        Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
-        const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
-
-        void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; }
-        PropertyNameArrayData* data() { return m_data.get(); }
-        PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
-
-        // FIXME: Remove these functions.
-        typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
-        size_t size() const { return m_data->propertyNameVector().size(); }
-        const_iterator begin() const { return m_data->propertyNameVector().begin(); }
-        const_iterator end() const { return m_data->propertyNameVector().end(); }
-
-        size_t numCacheableSlots() const { return m_numCacheableSlots; }
-        void setNumCacheableSlotsForObject(JSObject* object, size_t numCacheableSlots)
-        {
-            if (object != m_baseObject)
-                return;
-            m_numCacheableSlots = numCacheableSlots;
+// FIXME: Rename to PropertyNameArray.
+class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
+public:
+    typedef Vector<Identifier, 20> PropertyNameVector;
+
+    static Ref<PropertyNameArrayData> create() { return adoptRef(*new PropertyNameArrayData); }
+
+    PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
+
+private:
+    PropertyNameArrayData()
+    {
+    }
+
+    PropertyNameVector m_propertyNameVector;
+};
+
+// FIXME: Rename to PropertyNameArrayBuilder.
+class PropertyNameArray {
+public:
+    PropertyNameArray(VM* vm)
+        : m_data(PropertyNameArrayData::create())
+        , m_vm(vm)
+    {
+    }
+
+    PropertyNameArray(ExecState* exec)
+        : m_data(PropertyNameArrayData::create())
+        , m_vm(&exec->vm())
+    {
+    }
+
+    VM* vm() { return m_vm; }
+
+    void add(uint32_t index)
+    {
+        add(Identifier::from(m_vm, index));
+    }
+
+    void add(const Identifier&);
+    void add(UniquedStringImpl*);
+    void addKnownUnique(UniquedStringImpl*);
+
+    Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
+    const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
+
+    void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; }
+    PropertyNameArrayData* data() { return m_data.get(); }
+    PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
+
+    // FIXME: Remove these functions.
+    bool canAddKnownUniqueForStructure() const { return m_data->propertyNameVector().isEmpty(); }
+    typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
+    size_t size() const { return m_data->propertyNameVector().size(); }
+    const_iterator begin() const { return m_data->propertyNameVector().begin(); }
+    const_iterator end() const { return m_data->propertyNameVector().end(); }
+
+private:
+    RefPtr<PropertyNameArrayData> m_data;
+    HashSet<UniquedStringImpl*> m_set;
+    VM* m_vm;
+};
+
+ALWAYS_INLINE void PropertyNameArray::add(const Identifier& identifier)
+{
+    add(identifier.impl());
+}
+
+ALWAYS_INLINE void PropertyNameArray::addKnownUnique(UniquedStringImpl* identifier)
+{
+    m_data->propertyNameVector().append(Identifier::fromUid(m_vm, identifier));
+}
+
+ALWAYS_INLINE void PropertyNameArray::add(UniquedStringImpl* identifier)
+{
+    static const unsigned setThreshold = 20;
+
+    ASSERT(identifier);
+
+    if (size() < setThreshold) {
+        if (m_data->propertyNameVector().contains(identifier))
+            return;
+    } else {
+        if (m_set.isEmpty()) {
+            for (Identifier& name : m_data->propertyNameVector())
+                m_set.add(name.impl());
         }
-        void setBaseObject(JSObject* object)
-        {
-            if (m_baseObject)
-                return;
-            m_baseObject = object;
-        }
-
-    private:
-        typedef HashSet<StringImpl*, PtrHash<StringImpl*>> IdentifierSet;
+        if (!m_set.add(identifier).isNewEntry)
+            return;
+    }
 
-        RefPtr<PropertyNameArrayData> m_data;
-        IdentifierSet m_set;
-        VM* m_vm;
-        size_t m_numCacheableSlots;
-        JSObject* m_baseObject;
-    };
+    addKnownUnique(identifier);
+}
 
 } // namespace JSC
 
index f46048803b913095a9cd5643239b1f0944198ae9..9a68372397f7ae44807f97d3640b0d76ca786b17 100644 (file)
@@ -46,7 +46,8 @@ enum Attribute {
     Builtin           = 1 << 7, // property is a builtin function - only used by static hashtables
     ConstantInteger   = 1 << 8, // property is a constant integer - only used by static hashtables
     BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables
-    BuiltinOrFunctionOrConstant = Builtin | Function | ConstantInteger, // helper only used by static hashtables
+    BuiltinOrFunctionOrAccessor = Builtin | Function | Accessor, // helper only used by static hashtables
+    BuiltinOrFunctionOrAccessorOrConstant = Builtin | Function | Accessor | ConstantInteger, // helper only used by static hashtables
 };
 
 class PropertySlot {
@@ -78,6 +79,7 @@ public:
     JSValue getValue(ExecState*, unsigned propertyName) const;
 
     bool isCacheable() const { return m_cacheability == CachingAllowed && m_offset != invalidOffset; }
+    bool isUnset() const { return m_propertyType == TypeUnset; }
     bool isValue() const { return m_propertyType == TypeValue; }
     bool isAccessor() const { return m_propertyType == TypeGetter; }
     bool isCustom() const { return m_propertyType == TypeCustom; }
@@ -204,6 +206,11 @@ public:
         m_offset = offset;
     }
 
+    void setThisValue(JSValue thisValue)
+    {
+        m_thisValue = thisValue;
+    }
+
     void setUndefined()
     {
         m_data.value = JSValue::encode(jsUndefined());
@@ -235,12 +242,30 @@ private:
 
     PropertyType m_propertyType;
     PropertyOffset m_offset;
-    const JSValue m_thisValue;
+    JSValue m_thisValue;
     JSObject* m_slotBase;
     WatchpointSet* m_watchpointSet;
     CacheabilityType m_cacheability;
 };
 
+ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, PropertyName propertyName) const
+{
+    if (m_propertyType == TypeValue)
+        return JSValue::decode(m_data.value);
+    if (m_propertyType == TypeGetter)
+        return functionGetter(exec);
+    return JSValue::decode(m_data.custom.getValue(exec, slotBase(), JSValue::encode(m_thisValue), propertyName));
+}
+
+ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, unsigned propertyName) const
+{
+    if (m_propertyType == TypeValue)
+        return JSValue::decode(m_data.value);
+    if (m_propertyType == TypeGetter)
+        return functionGetter(exec);
+    return JSValue::decode(m_data.custom.getValue(exec, slotBase(), JSValue::encode(m_thisValue), Identifier::from(exec, propertyName)));
+}
+
 } // namespace JSC
 
 #endif // PropertySlot_h
index c53b7218b0bf35af570dd9a9ced2cf375aa21428..74474c6d915f3dad5ab9dcd237e98b0c2e9df0b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,7 @@
 
 namespace JSC {
 
-const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
+const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
 
 PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
 {
@@ -82,15 +82,13 @@ PropertyTable::PropertyTable(VM& vm, const PropertyTable& other)
     memcpy(m_index, other.m_index, dataSize());
 
     iterator end = this->end();
-    for (iterator iter = begin(); iter != end; ++iter) {
+    for (iterator iter = begin(); iter != end; ++iter)
         iter->key->ref();
-        vm.heap.writeBarrier(this, iter->specificValue.get());
-    }
 
     // Copy the m_deletedOffsets vector.
     Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
     if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+        m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>(*otherDeletedOffsets);
 }
 
 PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTable& other)
@@ -109,13 +107,12 @@ PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTab
         ASSERT(canInsert());
         reinsert(*iter);
         iter->key->ref();
-        vm.heap.writeBarrier(this, iter->specificValue.get());
     }
 
     // Copy the m_deletedOffsets vector.
     Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
     if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+        m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>(*otherDeletedOffsets);
 }
 
 void PropertyTable::destroy(JSCell* cell)
@@ -132,17 +129,5 @@ PropertyTable::~PropertyTable()
     fastFree(m_index);
 }
 
-void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    PropertyTable* thisObject = jsCast<PropertyTable*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    JSCell::visitChildren(thisObject, visitor);
+} // namespace JSC
 
-    PropertyTable::iterator end = thisObject->end();
-    for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr)
-        visitor.append(&ptr->specificValue);
-}
-
-}
index 78dd319a3c395a2ab162f25d6bda4645cb7352e3..e72cafb828890636817745d38bc0154a00eb0122 100644 (file)
 
 namespace JSC {
 
-    inline void gcProtect(JSCell* val) 
-    {
-        Heap::heap(val)->protect(val);
-    }
+inline void gcProtect(JSCell* val) 
+{
+    Heap::heap(val)->protect(val);
+}
 
-    inline void gcUnprotect(JSCell* val)
-    {
-        Heap::heap(val)->unprotect(val);
-    }
+inline void gcUnprotect(JSCell* val)
+{
+    Heap::heap(val)->unprotect(val);
+}
 
-    inline void gcProtectNullTolerant(JSCell* val) 
-    {
-        if (val) 
-            gcProtect(val);
-    }
+inline void gcProtectNullTolerant(JSCell* val) 
+{
+    if (val) 
+        gcProtect(val);
+}
 
-    inline void gcUnprotectNullTolerant(JSCell* val) 
-    {
-        if (val) 
-            gcUnprotect(val);
-    }
-    
-    inline void gcProtect(JSValue value)
-    {
-        if (value && value.isCell())
-            gcProtect(value.asCell());
-    }
+inline void gcUnprotectNullTolerant(JSCell* val) 
+{
+    if (val) 
+        gcUnprotect(val);
+}
 
-    inline void gcUnprotect(JSValue value)
-    {
-        if (value && value.isCell())
-            gcUnprotect(value.asCell());
-    }
+inline void gcProtect(JSValue value)
+{
+    if (value && value.isCell())
+        gcProtect(value.asCell());
+}
+
+inline void gcUnprotect(JSValue value)
+{
+    if (value && value.isCell())
+        gcUnprotect(value.asCell());
+}
 
 } // namespace JSC
 
index a7a417f3cee8615121a86972454818ad1adffabc..43f03441b56ad51deea9f59e068527dbb4a9db81 100644 (file)
@@ -33,7 +33,7 @@ namespace JSC {
 
 void PrototypeMap::addPrototype(JSObject* object)
 {
-    m_prototypes.add(object, object);
+    m_prototypes.set(object, object);
 
     // Note that this method makes the somewhat odd decision to not check if this
     // object currently has indexed accessors. We could do that check here, and if
@@ -54,16 +54,16 @@ void PrototypeMap::addPrototype(JSObject* object)
 
 Structure* PrototypeMap::emptyObjectStructureForPrototype(JSObject* prototype, unsigned inlineCapacity)
 {
-    StructureMap::AddResult addResult = m_structures.add(std::make_pair(prototype, inlineCapacity), nullptr);
-    if (!addResult.isNewEntry) {
+    auto key = std::make_pair(prototype, inlineCapacity);
+    if (Structure* structure = m_structures.get(key)) {
         ASSERT(isPrototype(prototype));
-        return addResult.iterator->value.get();
+        return structure;
     }
 
     addPrototype(prototype);
     Structure* structure = JSFinalObject::createStructure(
         prototype->globalObject()->vm(), prototype->globalObject(), prototype, inlineCapacity);
-    addResult.iterator->value = Weak<Structure>(structure);
+    m_structures.set(key, Weak<Structure>(structure));
     return structure;
 }
 
index 9752ca7ead8d40718506d1b0532dc3a6e4648171..505e0b85cd9c4edaf66bdb77b7c29681f9d487d8 100644 (file)
@@ -33,10 +33,17 @@ namespace JSC {
 
 class JSObject;
 class Structure;
+class VM;
 
 // Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
 class PrototypeMap {
 public:
+    explicit PrototypeMap(VM& vm)
+        : m_prototypes(vm)
+        , m_structures(vm)
+    {
+    }
+
     JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
     void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
     void addPrototype(JSObject*);
index 503411b592886708ef428df3bb733b2668f20bd3..fd32d95714eb497e5e016f8f5db76aaa795fa77b 100644 (file)
 #define PutPropertySlot_h
 
 #include "JSCJSValue.h"
+#include "PropertyOffset.h"
 
 #include <wtf/Assertions.h>
 
 namespace JSC {
     
-    class JSObject;
-    class JSFunction;
+class JSObject;
+class JSFunction;
     
-    class PutPropertySlot {
-    public:
-        enum Type { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomProperty };
-        enum Context { UnknownContext, PutById, PutByIdEval };
-        typedef void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
-
-        PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
-            : m_type(Uncachable)
-            , m_base(0)
-            , m_thisValue(thisValue)
-            , m_isStrictMode(isStrictMode)
-            , m_context(context)
-            , m_putFunction(nullptr)
-        {
-        }
-
-        void setExistingProperty(JSObject* base, PropertyOffset offset)
-        {
-            m_type = ExistingProperty;
-            m_base = base;
-            m_offset = offset;
-        }
-
-        void setNewProperty(JSObject* base, PropertyOffset offset)
-        {
-            m_type = NewProperty;
-            m_base = base;
-            m_offset = offset;
-        }
-
-        void setCustomProperty(JSObject* base, PutValueFunc function)
-        {
-            m_type = CustomProperty;
-            m_base = base;
-            m_putFunction = function;
-        }
-        
-        void setCacheableSetter(JSObject* base, PropertyOffset offset)
-        {
-            m_type = SetterProperty;
-            m_base = base;
-            m_offset = offset;
-        }
-
-        PutValueFunc customSetter() const { return m_putFunction; }
-
-        Context context() const { return static_cast<Context>(m_context); }
-
-        Type type() const { return m_type; }
-        JSObject* base() const { return m_base; }
-        JSValue thisValue() const { return m_thisValue; }
-
-        bool isStrictMode() const { return m_isStrictMode; }
-        bool isCacheablePut() const { return m_type == NewProperty || m_type == ExistingProperty; }
-        bool isCacheableSetter() const { return m_type == SetterProperty; }
-        bool isCacheableCustom() const { return m_type == CustomProperty; }
-
-        PropertyOffset cachedOffset() const
-        {
-            return m_offset;
-        }
-
-    private:
-        Type m_type;
-        JSObject* m_base;
-        JSValue m_thisValue;
-        PropertyOffset m_offset;
-        bool m_isStrictMode;
-        uint8_t m_context;
-        PutValueFunc m_putFunction;
-
-    };
+class PutPropertySlot {
+public:
+    enum Type { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomProperty };
+    enum Context { UnknownContext, PutById, PutByIdEval };
+    typedef void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
+
+    PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
+        : m_type(Uncachable)
+        , m_base(0)
+        , m_thisValue(thisValue)
+        , m_isStrictMode(isStrictMode)
+        , m_context(context)
+        , m_putFunction(nullptr)
+    {
+    }
+
+    void setExistingProperty(JSObject* base, PropertyOffset offset)
+    {
+        m_type = ExistingProperty;
+        m_base = base;
+        m_offset = offset;
+    }
+
+    void setNewProperty(JSObject* base, PropertyOffset offset)
+    {
+        m_type = NewProperty;
+        m_base = base;
+        m_offset = offset;
+    }
+
+    void setCustomProperty(JSObject* base, PutValueFunc function)
+    {
+        m_type = CustomProperty;
+        m_base = base;
+        m_putFunction = function;
+    }
+
+    void setCacheableSetter(JSObject* base, PropertyOffset offset)
+    {
+        m_type = SetterProperty;
+        m_base = base;
+        m_offset = offset;
+    }
+
+    void setThisValue(JSValue thisValue)
+    {
+        m_thisValue = thisValue;
+    }
+
+    PutValueFunc customSetter() const { return m_putFunction; }
+
+    Context context() const { return static_cast<Context>(m_context); }
+
+    Type type() const { return m_type; }
+    JSObject* base() const { return m_base; }
+    JSValue thisValue() const { return m_thisValue; }
+
+    bool isStrictMode() const { return m_isStrictMode; }
+    bool isCacheablePut() const { return m_type == NewProperty || m_type == ExistingProperty; }
+    bool isCacheableSetter() const { return m_type == SetterProperty; }
+    bool isCacheableCustom() const { return m_type == CustomProperty; }
+
+    PropertyOffset cachedOffset() const
+    {
+        return m_offset;
+    }
+
+private:
+    Type m_type;
+    JSObject* m_base;
+    JSValue m_thisValue;
+    PropertyOffset m_offset;
+    bool m_isStrictMode;
+    uint8_t m_context;
+    PutValueFunc m_putFunction;
+};
 
 } // namespace JSC
 
index 47c979d4cb2a9c30b29ac6cfb6b882ea1b7e8f44..af1f2fa1da6398bad6af3263d311e39e11c54d16 100644 (file)
@@ -40,7 +40,7 @@
 
 namespace JSC {
 
-const ClassInfo RegExp::s_info = { "RegExp", 0, 0, 0, CREATE_METHOD_TABLE(RegExp) };
+const ClassInfo RegExp::s_info = { "RegExp", 0, 0, CREATE_METHOD_TABLE(RegExp) };
 
 RegExpFlags regExpFlags(const String& string)
 {
@@ -113,7 +113,7 @@ RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::get()
     return s_instance;
 }
 
-void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, String s, int startOffset, int* ovector, int result)
+void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, const String& s, int startOffset, int* ovector, int result)
 {
     if ((!m_lastRegExp) || (m_lastRegExp != regExp)) {
         m_lastRegExp = regExp;
@@ -273,8 +273,10 @@ void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize)
     Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
     if (m_constructionError) {
         RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;
         return;
+#endif
     }
     ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
 
@@ -287,22 +289,16 @@ void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize)
 #if ENABLE(YARR_JIT)
     if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
         Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
-#if ENABLE(YARR_JIT_DEBUG)
-        if (!m_regExpJITCode.isFallBack())
-            m_state = JITCode;
-        else
-            m_state = ByteCode;
-#else
         if (!m_regExpJITCode.isFallBack()) {
             m_state = JITCode;
             return;
         }
-#endif
     }
 #else
     UNUSED_PARAM(charSize);
 #endif
 
+    m_state = ByteCode;
     m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
 }
 
@@ -396,8 +392,10 @@ void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize)
     Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
     if (m_constructionError) {
         RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;
         return;
+#endif
     }
     ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
 
@@ -410,22 +408,16 @@ void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize)
 #if ENABLE(YARR_JIT)
     if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
         Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
-#if ENABLE(YARR_JIT_DEBUG)
-        if (!m_regExpJITCode.isFallBack())
-            m_state = JITCode;
-        else
-            m_state = ByteCode;
-#else
         if (!m_regExpJITCode.isFallBack()) {
             m_state = JITCode;
             return;
         }
-#endif
     }
 #else
     UNUSED_PARAM(charSize);
 #endif
 
+    m_state = ByteCode;
     m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
 }
 
@@ -498,7 +490,7 @@ void RegExp::invalidateCode()
 #if ENABLE(YARR_JIT)
     m_regExpJITCode.clear();
 #endif
-    m_regExpBytecode.clear();
+    m_regExpBytecode = nullptr;
 }
 
 #if ENABLE(YARR_JIT_DEBUG)
index fec8f6a6fa2ac754c4ab88769228e8b019c698af..670505f773585e5220461185d8970ea62449037c 100644 (file)
 
 namespace JSC {
 
-    struct RegExpRepresentation;
-    class VM;
+struct RegExpRepresentation;
+class VM;
 
-    JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
+JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
 
-    class RegExp : public JSCell {
-    public:
-        typedef JSCell Base;
+class RegExp final : public JSCell {
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-        JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
-        static const bool needsDestruction = true;
-        static const bool hasImmortalStructure = true;
-        static void destroy(JSCell*);
+    JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
 
-        bool global() const { return m_flags & FlagGlobal; }
-        bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
-        bool multiline() const { return m_flags & FlagMultiline; }
+    bool global() const { return m_flags & FlagGlobal; }
+    bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
+    bool multiline() const { return m_flags & FlagMultiline; }
 
-        const String& pattern() const { return m_patternString; }
+    const String& pattern() const { return m_patternString; }
 
-        bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
-        const char* errorMessage() const { return m_constructionError; }
+    bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
+    const char* errorMessage() const { return m_constructionError; }
 
-        JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
-        MatchResult match(VM&, const String&, unsigned startOffset);
-        unsigned numSubpatterns() const { return m_numSubpatterns; }
+    JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
+    JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset);
+    unsigned numSubpatterns() const { return m_numSubpatterns; }
 
-        bool hasCode()
-        {
-            return m_state != NotCompiled;
-        }
+    bool hasCode()
+    {
+        return m_state != NotCompiled;
+    }
+
+    void invalidateCode();
 
-        void invalidateCode();
-        
 #if ENABLE(REGEXP_TRACING)
-        void printTraceData();
+    void printTraceData();
 #endif
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(LeafType, StructureFlags), info());
-        }
-        
-        DECLARE_INFO;
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+    DECLARE_INFO;
 
-        RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
+    RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
 
-    protected:
-        static const unsigned StructureFlags = StructureIsImmortal;
+protected:
+    void finishCreation(VM&);
 
-        void finishCreation(VM&);
+private:
+    friend class RegExpCache;
+    RegExp(VM&, const String&, RegExpFlags);
 
-    private:
-        friend class RegExpCache;
-        RegExp(VM&, const String&, RegExpFlags);
+    static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
 
-        static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
+    enum RegExpState {
+        ParseError,
+        JITCode,
+        ByteCode,
+        NotCompiled
+    };
 
-        enum RegExpState {
-            ParseError,
-            JITCode,
-            ByteCode,
-            NotCompiled
-        } m_state;
+    RegExpState m_state;
 
-        void compile(VM*, Yarr::YarrCharSize);
-        void compileIfNecessary(VM&, Yarr::YarrCharSize);
+    void compile(VM*, Yarr::YarrCharSize);
+    void compileIfNecessary(VM&, Yarr::YarrCharSize);
 
-        void compileMatchOnly(VM*, Yarr::YarrCharSize);
-        void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
+    void compileMatchOnly(VM*, Yarr::YarrCharSize);
+    void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
 
 #if ENABLE(YARR_JIT_DEBUG)
-        void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
+    void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
 #endif
 
-        String m_patternString;
-        RegExpFlags m_flags;
-        const char* m_constructionError;
-        unsigned m_numSubpatterns;
+    String m_patternString;
+    RegExpFlags m_flags;
+    const char* m_constructionError;
+    unsigned m_numSubpatterns;
 #if ENABLE(REGEXP_TRACING)
-        double m_rtMatchOnlyTotalSubjectStringLen;
-        double m_rtMatchTotalSubjectStringLen;
-        unsigned m_rtMatchOnlyCallCount;
-        unsigned m_rtMatchOnlyFoundCount;
-        unsigned m_rtMatchCallCount;
-        unsigned m_rtMatchFoundCount;
+    double m_rtMatchOnlyTotalSubjectStringLen;
+    double m_rtMatchTotalSubjectStringLen;
+    unsigned m_rtMatchOnlyCallCount;
+    unsigned m_rtMatchOnlyFoundCount;
+    unsigned m_rtMatchCallCount;
+    unsigned m_rtMatchFoundCount;
 #endif
 
 #if ENABLE(YARR_JIT)
-        Yarr::YarrCodeBlock m_regExpJITCode;
+    Yarr::YarrCodeBlock m_regExpJITCode;
 #endif
-        OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
-    };
+    std::unique_ptr<Yarr::BytecodePattern> m_regExpBytecode;
+};
 
 } // namespace JSC
 
index d2bfdfef30e2fa41e4269115fc533305933be889..dd46ac664901741a580a81c3c544b51c9b7f20ba 100644 (file)
 namespace JSC {
 
 class RegExpCache : private WeakHandleOwner {
-friend class RegExp;
-typedef HashMap<RegExpKey, Weak<RegExp>> RegExpCacheMap;
+    WTF_MAKE_FAST_ALLOCATED;
+
+    friend class RegExp;
+    typedef HashMap<RegExpKey, Weak<RegExp>> RegExpCacheMap;
 
 public:
     RegExpCache(VM* vm);
index 276ba331e4213707116cd91ce94c96535e903185..e93061886aeb1f31ce1035fef0faf83893bb3cf1 100644 (file)
@@ -37,23 +37,45 @@ void RegExpCachedResult::visitChildren(SlotVisitor& visitor)
     visitor.append(&m_lastRegExp);
     visitor.append(&m_reifiedInput);
     visitor.append(&m_reifiedResult);
+    visitor.append(&m_reifiedLeftContext);
+    visitor.append(&m_reifiedRightContext);
 }
 
-RegExpMatchesArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner)
+JSArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner)
 {
-    if (m_result) {
+    if (!m_reified) {
         m_reifiedInput.set(exec->vm(), owner, m_lastInput.get());
-        m_reifiedResult.set(exec->vm(), owner, RegExpMatchesArray::create(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
-        m_result = MatchResult::failed();
+        m_reifiedResult.set(exec->vm(), owner, createRegExpMatchesArray(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
+        m_reified = true;
     }
     return m_reifiedResult.get();
 }
 
+JSString* RegExpCachedResult::leftContext(ExecState* exec, JSObject* owner)
+{
+    // Make sure we're reified.
+    lastResult(exec, owner);
+    if (!m_reifiedLeftContext)
+        m_reifiedLeftContext.set(exec->vm(), owner, m_result.start ? jsSubstring(exec, m_reifiedInput.get(), 0, m_result.start) : jsEmptyString(exec));
+    return m_reifiedLeftContext.get();
+}
+
+JSString* RegExpCachedResult::rightContext(ExecState* exec, JSObject* owner)
+{
+    // Make sure we're reified.
+    lastResult(exec, owner);
+    if (!m_reifiedRightContext) {
+        unsigned length = m_reifiedInput->length();
+        m_reifiedRightContext.set(exec->vm(), owner, m_result.end != length ? jsSubstring(exec, m_reifiedInput.get(), m_result.end, length - m_result.end) : jsEmptyString(exec));
+    }
+    return m_reifiedRightContext.get();
+}
+
 void RegExpCachedResult::setInput(ExecState* exec, JSObject* owner, JSString* input)
 {
     // Make sure we're reified, otherwise m_reifiedInput will be ignored.
     lastResult(exec, owner);
-    ASSERT(!m_result);
+    ASSERT(m_reified);
     m_reifiedInput.set(exec->vm(), owner, input);
 }
 
index d2763bc77c1823959b767c32f2f12d82c1637771..bf6c0b86460e958c09d02ef08d4380b876d40857 100644 (file)
 
 namespace JSC {
 
-    class JSString;
-    class RegExpMatchesArray;
+class JSArray;
+class JSString;
 
-    // RegExpCachedResult is used to track the cached results of the last
-    // match, stores on the RegExp constructor (e.g. $&, $_, $1, $2 ...).
-    // These values will be lazily generated on demand, so the cached result
-    // may be in a lazy or reified state. A lazy state is indicated by a
-    // value of m_result indicating a successful match, and a reified state
-    // is indicated by setting m_result to MatchResult::failed().
-    // Following a successful match, m_result, m_lastInput and m_lastRegExp
-    // can be used to reify the results from the match, following reification
-    // m_reifiedResult and m_reifiedInput hold the cached results.
-    class RegExpCachedResult {
-    public:
-        RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
-            : m_result(0, 0)
-        {
-            m_lastInput.set(vm, owner, jsEmptyString(&vm));
-            m_lastRegExp.set(vm, owner, emptyRegExp);
-        }
+// RegExpCachedResult is used to track the cached results of the last
+// match, stores on the RegExp constructor (e.g. $&, $_, $1, $2 ...).
+// These values will be lazily generated on demand, so the cached result
+// may be in a lazy or reified state. A lazy state is indicated by a
+// value of m_result indicating a successful match, and a reified state
+// is indicated by setting m_result to MatchResult::failed().
+// Following a successful match, m_result, m_lastInput and m_lastRegExp
+// can be used to reify the results from the match, following reification
+// m_reifiedResult and m_reifiedInput hold the cached results.
+class RegExpCachedResult {
+public:
+    RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
+        : m_result(0, 0)
+        , m_reified(false)
+    {
+        m_lastInput.set(vm, owner, jsEmptyString(&vm));
+        m_lastRegExp.set(vm, owner, emptyRegExp);
+    }
 
-        ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
-        {
-            m_lastRegExp.set(vm, owner, regExp);
-            m_lastInput.set(vm, owner, input);
-            m_result = result;
-        }
+    ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
+    {
+        m_lastRegExp.set(vm, owner, regExp);
+        m_lastInput.set(vm, owner, input);
+        m_reifiedLeftContext.clear();
+        m_reifiedRightContext.clear();
+        m_result = result;
+        m_reified = false;
+    }
 
-        RegExpMatchesArray* lastResult(ExecState*, JSObject* owner);
-        void setInput(ExecState*, JSObject* owner, JSString*);
+    JSArray* lastResult(ExecState*, JSObject* owner);
+    void setInput(ExecState*, JSObject* owner, JSString*);
 
-        JSString* input()
-        {
-            // If m_result showas a match then we're in a lazy state, so m_lastInput
-            // is the most recent value of the input property. If not then we have
-            // reified, in which case m_reifiedInput will contain the correct value.
-            return m_result ? m_lastInput.get() : m_reifiedInput.get();
-        }
+    JSString* leftContext(ExecState*, JSObject* owner);
+    JSString* rightContext(ExecState*, JSObject* owner);
 
-        void visitChildren(SlotVisitor&);
+    JSString* input()
+    {
+        return m_reified ? m_reifiedInput.get() : m_lastInput.get();
+    }
 
-    private:
-        MatchResult m_result;
-        WriteBarrier<JSString> m_lastInput;
-        WriteBarrier<RegExp> m_lastRegExp;
-        WriteBarrier<RegExpMatchesArray> m_reifiedResult;
-        WriteBarrier<JSString> m_reifiedInput;
-    };
+    void visitChildren(SlotVisitor&);
+
+private:
+    MatchResult m_result;
+    bool m_reified;
+    WriteBarrier<JSString> m_lastInput;
+    WriteBarrier<RegExp> m_lastRegExp;
+    WriteBarrier<JSArray> m_reifiedResult;
+    WriteBarrier<JSString> m_reifiedInput;
+    WriteBarrier<JSString> m_reifiedLeftContext;
+    WriteBarrier<JSString> m_reifiedRightContext;
+};
 
 } // namespace JSC
 
index 0c6bf4886ebf50dd5019bca91d1f8a4fc4c036a7..ee1d8b3fc69f943b94a5259cf7c186cac6373f74 100644 (file)
@@ -54,7 +54,7 @@ static void setRegExpConstructorMultiline(ExecState*, JSObject*, EncodedJSValue,
 
 namespace JSC {
 
-const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::regExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) };
+const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_info, &regExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) };
 
 /* Source for RegExpConstructor.lut.h
 @begin regExpConstructorTable
@@ -91,7 +91,7 @@ RegExpConstructor::RegExpConstructor(VM& vm, Structure* structure, RegExpPrototy
 
 void RegExpConstructor::finishCreation(VM& vm, RegExpPrototype* regExpPrototype)
 {
-    Base::finishCreation(vm, Identifier(&vm, "RegExp").string());
+    Base::finishCreation(vm, regExpPrototype->classInfo()->className);
     ASSERT(inherits(info()));
 
     // ECMA 15.10.5.1 RegExp.prototype
@@ -110,16 +110,13 @@ void RegExpConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     RegExpConstructor* thisObject = jsCast<RegExpConstructor*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     thisObject->m_cachedResult.visitChildren(visitor);
 }
 
 JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i)
 {
-    RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);
+    JSArray* array = m_cachedResult.lastResult(exec, this);
 
     if (i < array->length()) {
         JSValue result = JSValue(array).get(exec, i);
@@ -132,7 +129,7 @@ JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i)
 
 JSValue RegExpConstructor::getLastParen(ExecState* exec)
 {
-    RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);
+    JSArray* array = m_cachedResult.lastResult(exec, this);
     unsigned length = array->length();
     if (length > 1) {
         JSValue result = JSValue(array).get(exec, length - 1);
@@ -145,17 +142,17 @@ JSValue RegExpConstructor::getLastParen(ExecState* exec)
 
 JSValue RegExpConstructor::getLeftContext(ExecState* exec)
 {
-    return m_cachedResult.lastResult(exec, this)->leftContext(exec);
+    return m_cachedResult.leftContext(exec, this);
 }
 
 JSValue RegExpConstructor::getRightContext(ExecState* exec)
 {
-    return m_cachedResult.lastResult(exec, this)->rightContext(exec);
+    return m_cachedResult.rightContext(exec, this);
 }
     
 bool RegExpConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
-    return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec->vm()), jsCast<RegExpConstructor*>(object), propertyName, slot);
+    return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, regExpConstructorTable, jsCast<RegExpConstructor*>(object), propertyName, slot);
 }
     
 EncodedJSValue regExpConstructorDollar1(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName)
index 9fa8ed8bfabc11f117b92f28bb94ca7fde89bd3e..cabee19c93d9b246c808851f2aff4e2ad1046a1a 100644 (file)
 #include "RegExp.h"
 #include "RegExpCachedResult.h"
 #include "RegExpObject.h"
-#include <wtf/OwnPtr.h>
-
 
 namespace JSC {
 
-    class RegExpPrototype;
+class RegExpPrototype;
 
-    class RegExpConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
+class RegExpConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
-        static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
-        {
-            RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
-            constructor->finishCreation(vm, regExpPrototype);
-            return constructor;
-        }
+    static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
+    {
+        RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
+        constructor->finishCreation(vm, regExpPrototype);
+        return constructor;
+    }
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
 
-        DECLARE_INFO;
+    DECLARE_INFO;
 
-        MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
-        MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
+    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
+    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
 
-        void setMultiline(bool multiline) { m_multiline = multiline; }
-        bool multiline() const { return m_multiline; }
+    void setMultiline(bool multiline) { m_multiline = multiline; }
+    bool multiline() const { return m_multiline; }
 
-        JSValue getBackref(ExecState*, unsigned);
-        JSValue getLastParen(ExecState*);
-        JSValue getLeftContext(ExecState*);
-        JSValue getRightContext(ExecState*);
+    JSValue getBackref(ExecState*, unsigned);
+    JSValue getLastParen(ExecState*);
+    JSValue getLeftContext(ExecState*);
+    JSValue getRightContext(ExecState*);
 
-        void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
-        JSString* input() { return m_cachedResult.input(); }
+    void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
+    JSString* input() { return m_cachedResult.input(); }
 
-        static void visitChildren(JSCell*, SlotVisitor&);
+    static void visitChildren(JSCell*, SlotVisitor&);
 
-    protected:
-        void finishCreation(VM&, RegExpPrototype*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags;
+protected:
+    void finishCreation(VM&, RegExpPrototype*);
 
-    private:
-        RegExpConstructor(VM&, Structure*, RegExpPrototype*);
-        static void destroy(JSCell*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
+private:
+    RegExpConstructor(VM&, Structure*, RegExpPrototype*);
+    static void destroy(JSCell*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
 
-        RegExpCachedResult m_cachedResult;
-        bool m_multiline;
-        Vector<int, 32> m_ovector;
-    };
+    RegExpCachedResult m_cachedResult;
+    bool m_multiline;
+    Vector<int, 32> m_ovector;
+};
 
-    RegExpConstructor* asRegExpConstructor(JSValue);
+RegExpConstructor* asRegExpConstructor(JSValue);
 
-    JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
+JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
 
-    inline RegExpConstructor* asRegExpConstructor(JSValue value)
-    {
-        ASSERT(asObject(value)->inherits(RegExpConstructor::info()));
-        return static_cast<RegExpConstructor*>(asObject(value));
-    }
+inline RegExpConstructor* asRegExpConstructor(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(RegExpConstructor::info()));
+    return static_cast<RegExpConstructor*>(asObject(value));
+}
 
-    /* 
-      To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
-      expression matching through the performMatch function. We use cached results to calculate, 
-      e.g., RegExp.lastMatch and RegExp.leftParen.
-    */
-    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
-    {
-        int position = regExp->match(vm, input, startOffset, m_ovector);
+/* 
+   To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
+   expression matching through the performMatch function. We use cached results to calculate, 
+   e.g., RegExp.lastMatch and RegExp.leftParen.
+*/
+ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
+{
+    int position = regExp->match(vm, input, startOffset, m_ovector);
 
-        if (ovector)
-            *ovector = m_ovector.data();
+    if (ovector)
+        *ovector = m_ovector.data();
 
-        if (position == -1)
-            return MatchResult::failed();
+    if (position == -1)
+        return MatchResult::failed();
 
-        ASSERT(!m_ovector.isEmpty());
-        ASSERT(m_ovector[0] == position);
-        ASSERT(m_ovector[1] >= position);
-        size_t end = m_ovector[1];
+    ASSERT(!m_ovector.isEmpty());
+    ASSERT(m_ovector[0] == position);
+    ASSERT(m_ovector[1] >= position);
+    size_t end = m_ovector[1];
 
-        m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
+    m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
 
-        return MatchResult(position, end);
-    }
-    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
-    {
-        MatchResult result = regExp->match(vm, input, startOffset);
-        if (result)
-            m_cachedResult.record(vm, this, regExp, string, result);
-        return result;
-    }
+    return MatchResult(position, end);
+}
+ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
+{
+    MatchResult result = regExp->match(vm, input, startOffset);
+    if (result)
+        m_cachedResult.record(vm, this, regExp, string, result);
+    return result;
+}
 
 } // namespace JSC
 
index f0cc10b5afef0c830c834e505950062a791a0282..440cc95120efa14648f5cb3bbad9ddbf545e2851 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
-const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RegExpMatchesArray)};
+static const PropertyOffset indexPropertyOffset = 100;
+static const PropertyOffset inputPropertyOffset = 101;
 
-RegExpMatchesArray::RegExpMatchesArray(VM& vm, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result)
-    : JSArray(vm, globalObject->regExpMatchesArrayStructure(), butterfly)
-    , m_result(result)
-    , m_state(ReifiedNone)
+static JSArray* tryCreateUninitializedRegExpMatchesArray(VM& vm, Structure* structure, unsigned initialLength)
 {
-    m_input.set(vm, this, input);
-    m_regExp.set(vm, this, regExp);
+    unsigned vectorLength = std::max(BASE_VECTOR_LEN, initialLength);
+    if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
+        return 0;
+
+    void* temp;
+    if (!vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)), &temp))
+        return 0;
+    Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity());
+    butterfly->setVectorLength(vectorLength);
+    butterfly->setPublicLength(initialLength);
+
+    return JSArray::createWithButterfly(vm, structure, butterfly);
 }
 
-RegExpMatchesArray* RegExpMatchesArray::create(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
+JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
 {
     ASSERT(result);
     VM& vm = exec->vm();
-    Butterfly* butterfly = createArrayButterfly(vm, 0, regExp->numSubpatterns() + 1);
-    RegExpMatchesArray* array = new (NotNull, allocateCell<RegExpMatchesArray>(vm.heap)) RegExpMatchesArray(vm, butterfly, exec->lexicalGlobalObject(), input, regExp, result);
-    array->finishCreation(vm);
-    return array;
-}
-
-void RegExpMatchesArray::finishCreation(VM& vm)
-{
-    Base::finishCreation(vm);
-}
+    JSArray* array = tryCreateUninitializedRegExpMatchesArray(vm, exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
+    RELEASE_ASSERT(array);
 
-void RegExpMatchesArray::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_input);
-    visitor.append(&thisObject->m_regExp);
-}
+    SamplingRegion samplingRegion("Reifying substring properties");
 
-void RegExpMatchesArray::reifyAllProperties(ExecState* exec)
-{
-    ASSERT(m_state != ReifiedAll);
-    ASSERT(m_result);
-    reifyMatchPropertyIfNecessary(exec);
+    array->initializeIndex(vm, 0, jsSubstring(exec, input, result.start, result.end - result.start), ArrayWithContiguous);
 
-    if (unsigned numSubpatterns = m_regExp->numSubpatterns()) {
+    if (unsigned numSubpatterns = regExp->numSubpatterns()) {
         Vector<int, 32> subpatternResults;
-        int position = m_regExp->match(exec->vm(), m_input->value(exec), m_result.start, subpatternResults);
-        ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == m_result.start);
-        ASSERT(m_result.start == static_cast<size_t>(subpatternResults[0]));
-        ASSERT(m_result.end == static_cast<size_t>(subpatternResults[1]));
+        int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
+        ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
+        ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
+        ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
 
         for (unsigned i = 1; i <= numSubpatterns; ++i) {
             int start = subpatternResults[2 * i];
             if (start >= 0)
-                putDirectIndex(exec, i, jsSubstring(exec, m_input.get(), start, subpatternResults[2 * i + 1] - start));
+                array->initializeIndex(vm, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous);
             else
-                putDirectIndex(exec, i, jsUndefined());
+                array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous);
         }
     }
 
-    putDirect(exec->vm(), exec->propertyNames().index, jsNumber(m_result.start));
-    putDirect(exec->vm(), exec->propertyNames().input, m_input.get());
+    array->putDirect(vm, indexPropertyOffset, jsNumber(result.start));
+    array->putDirect(vm, inputPropertyOffset, input);
 
-    m_state = ReifiedAll;
-}
-
-void RegExpMatchesArray::reifyMatchProperty(ExecState* exec)
-{
-    ASSERT(m_state == ReifiedNone);
-    ASSERT(m_result);
-    putDirectIndex(exec, 0, jsSubstring(exec, m_input.get(), m_result.start, m_result.end - m_result.start));
-    m_state = ReifiedMatch;
-}
-
-JSString* RegExpMatchesArray::leftContext(ExecState* exec)
-{
-    if (!m_result.start)
-        return jsEmptyString(exec);
-    return jsSubstring(exec, m_input.get(), 0, m_result.start);
+    return array;
 }
 
-JSString* RegExpMatchesArray::rightContext(ExecState* exec)
+Structure* createRegExpMatchesArrayStructure(VM& vm, JSGlobalObject& globalObject)
 {
-    unsigned length = m_input->length();
-    if (m_result.end == length)
-        return jsEmptyString(exec);
-    return jsSubstring(exec, m_input.get(), m_result.end, length - m_result.end);
+    Structure* structure = globalObject.arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
+    PropertyOffset offset;
+    structure = structure->addPropertyTransition(vm, structure, vm.propertyNames->index, 0, offset);
+    ASSERT(offset == indexPropertyOffset);
+    structure = structure->addPropertyTransition(vm, structure, vm.propertyNames->input, 0, offset);
+    ASSERT(offset == inputPropertyOffset);
+    return structure;
 }
 
 } // namespace JSC
index 8997d8e47fcc8c4fad02b45c4c5d6b12ef02ba45..669dd39ed52ab3de8e824b4cff4a48701bf94b10 100644 (file)
 
 namespace JSC {
 
-    class RegExpMatchesArray : public JSArray {
-    private:
-        RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
-
-        enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
-
-    public:
-        typedef JSArray Base;
-
-        static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);
-
-        JSString* leftContext(ExecState*);
-        JSString* rightContext(ExecState*);
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayWithSlowPutArrayStorage);
-        }
-
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-    protected:
-        void finishCreation(VM&);
-
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
-
-    private:
-        ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)
-        {
-            if (m_state != ReifiedAll)
-                reifyAllProperties(exec);
-        }
-
-        ALWAYS_INLINE void reifyMatchPropertyIfNecessary(ExecState* exec)
-        {
-            if (m_state == ReifiedNone)
-                reifyMatchProperty(exec);
-        }
-
-        static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
-        }
-
-        static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
-            if (propertyName)
-                thisObject->reifyAllPropertiesIfNecessary(exec);
-            else
-                thisObject->reifyMatchPropertyIfNecessary(exec);
-            return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
-        }
-
-        static void put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue v, PutPropertySlot& slot)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            JSArray::put(thisObject, exec, propertyName, v, slot);
-        }
-        
-        static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
-        }
-
-        static bool deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            return JSArray::deleteProperty(thisObject, exec, propertyName);
-        }
-
-        static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
-        }
-
-        static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
-        }
-
-        static bool defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-        {
-            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
-            thisObject->reifyAllPropertiesIfNecessary(exec);
-            return JSArray::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
-        }
-
-        void reifyAllProperties(ExecState*);
-        void reifyMatchProperty(ExecState*);
-
-        WriteBarrier<JSString> m_input;
-        WriteBarrier<RegExp> m_regExp;
-        MatchResult m_result;
-        ReifiedState m_state;
-};
-
-inline bool isRegExpMatchesArray(JSValue value)
-{
-    return value.isCell() && value.asCell()->classInfo() == RegExpMatchesArray::info();
-}
+JSArray* createRegExpMatchesArray(ExecState*, JSString*, RegExp*, MatchResult);
+Structure* createRegExpMatchesArrayStructure(VM&, JSGlobalObject&);
 
 }
 
index 4e4c02cdc99bd7cedfa6b30866754a7daaaf428d..60a26ef673e5d1e1687178be9bbc8dc81b9db1cd 100644 (file)
 #include "JSArray.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
-#include "Lexer.h"
 #include "Lookup.h"
 #include "JSCInlines.h"
 #include "RegExpConstructor.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpPrototype.h"
-#include <wtf/PassOwnPtr.h>
 #include <wtf/text/StringBuilder.h>
 
 namespace JSC {
 
-static EncodedJSValue regExpObjectGlobal(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue regExpObjectIgnoreCase(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue regExpObjectMultiline(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue regExpObjectSource(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-
-} // namespace JSC
-
-#include "RegExpObject.lut.h"
-
-namespace JSC {
-
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(RegExpObject);
 
-const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) };
-
-/* Source for RegExpObject.lut.h
-@begin regExpTable
-    global        regExpObjectGlobal       DontDelete|ReadOnly|DontEnum
-    ignoreCase    regExpObjectIgnoreCase   DontDelete|ReadOnly|DontEnum
-    multiline     regExpObjectMultiline    DontDelete|ReadOnly|DontEnum
-    source        regExpObjectSource       DontDelete|ReadOnly|DontEnum
-@end
-*/
+const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, nullptr, CREATE_METHOD_TABLE(RegExpObject) };
 
 RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp)
     : JSNonFinalObject(vm, structure)
@@ -81,9 +59,6 @@ void RegExpObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     RegExpObject* thisObject = jsCast<RegExpObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_regExp);
     visitor.append(&thisObject->m_lastIndex);
@@ -97,7 +72,7 @@ bool RegExpObject::getOwnPropertySlot(JSObject* object, ExecState* exec, Propert
         slot.setValue(regExp, attributes, regExp->getLastIndex());
         return true;
     }
-    return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec->vm()), jsCast<RegExpObject*>(object), propertyName, slot);
+    return Base::getOwnPropertySlot(object, exec, propertyName, slot);
 }
 
 bool RegExpObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
@@ -109,18 +84,25 @@ bool RegExpObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName pr
 
 void RegExpObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         propertyNames.add(exec->propertyNames().lastIndex);
     Base::getOwnNonIndexPropertyNames(object, exec, propertyNames, mode);
 }
 
 void RegExpObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         propertyNames.add(exec->propertyNames().lastIndex);
     Base::getPropertyNames(object, exec, propertyNames, mode);
 }
 
+void RegExpObject::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    if (mode.includeDontEnumProperties())
+        propertyNames.add(exec->propertyNames().lastIndex);
+    Base::getGenericPropertyNames(object, exec, propertyNames, mode);
+}
+
 static bool reject(ExecState* exec, bool throwException, const char* message)
 {
     if (throwException)
@@ -155,141 +137,23 @@ bool RegExpObject::defineOwnProperty(JSObject* object, ExecState* exec, Property
     return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
 }
 
-EncodedJSValue regExpObjectGlobal(ExecState*, JSObject* slotBase, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsBoolean(asRegExpObject(slotBase)->regExp()->global()));
-}
-
-EncodedJSValue regExpObjectIgnoreCase(ExecState*, JSObject* slotBase, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()));
-}
-EncodedJSValue regExpObjectMultiline(ExecState*, JSObject* slotBase, EncodedJSValue, PropertyName)
-{            
-    return JSValue::encode(jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()));
-}
-
-template <typename CharacterType>
-static inline void appendLineTerminatorEscape(StringBuilder&, CharacterType);
-
-template <>
-inline void appendLineTerminatorEscape<LChar>(StringBuilder& builder, LChar lineTerminator)
+static void regExpObjectSetLastIndexStrict(ExecState* exec, JSObject* slotBase, EncodedJSValue, EncodedJSValue value)
 {
-    if (lineTerminator == '\n')
-        builder.append('n');
-    else
-        builder.append('r');
-}
-
-template <>
-inline void appendLineTerminatorEscape<UChar>(StringBuilder& builder, UChar lineTerminator)
-{
-    if (lineTerminator == '\n')
-        builder.append('n');
-    else if (lineTerminator == '\r')
-        builder.append('r');
-    else if (lineTerminator == 0x2028)
-        builder.appendLiteral("u2028");
-    else
-        builder.appendLiteral("u2029");
-}
-
-template <typename CharacterType>
-static inline JSValue regExpObjectSourceInternal(ExecState* exec, String pattern, const CharacterType* characters, unsigned length)
-{
-    bool previousCharacterWasBackslash = false;
-    bool inBrackets = false;
-    bool shouldEscape = false;
-
-    // 15.10.6.4 specifies that RegExp.prototype.toString must return '/' + source + '/',
-    // and also states that the result must be a valid RegularExpressionLiteral. '//' is
-    // not a valid RegularExpressionLiteral (since it is a single line comment), and hence
-    // source cannot ever validly be "". If the source is empty, return a different Pattern
-    // that would match the same thing.
-    if (!length)
-        return jsNontrivialString(exec, ASCIILiteral("(?:)"));
-
-    // early return for strings that don't contain a forwards slash and LineTerminator
-    for (unsigned i = 0; i < length; ++i) {
-        CharacterType ch = characters[i];
-        if (!previousCharacterWasBackslash) {
-            if (inBrackets) {
-                if (ch == ']')
-                    inBrackets = false;
-            } else {
-                if (ch == '/') {
-                    shouldEscape = true;
-                    break;
-                }
-                if (ch == '[')
-                    inBrackets = true;
-            }
-        }
-
-        if (Lexer<CharacterType>::isLineTerminator(ch)) {
-            shouldEscape = true;
-            break;
-        }
-
-        if (previousCharacterWasBackslash)
-            previousCharacterWasBackslash = false;
-        else
-            previousCharacterWasBackslash = ch == '\\';
-    }
-
-    if (!shouldEscape)
-        return jsString(exec, pattern);
-
-    previousCharacterWasBackslash = false;
-    inBrackets = false;
-    StringBuilder result;
-    for (unsigned i = 0; i < length; ++i) {
-        CharacterType ch = characters[i];
-        if (!previousCharacterWasBackslash) {
-            if (inBrackets) {
-                if (ch == ']')
-                    inBrackets = false;
-            } else {
-                if (ch == '/')
-                    result.append('\\');
-                else if (ch == '[')
-                    inBrackets = true;
-            }
-        }
-
-        // escape LineTerminator
-        if (Lexer<CharacterType>::isLineTerminator(ch)) {
-            if (!previousCharacterWasBackslash)
-                result.append('\\');
-
-            appendLineTerminatorEscape<CharacterType>(result, ch);
-        } else
-            result.append(ch);
-
-        if (previousCharacterWasBackslash)
-            previousCharacterWasBackslash = false;
-        else
-            previousCharacterWasBackslash = ch == '\\';
-    }
-
-    return jsString(exec, result.toString());
+    asRegExpObject(slotBase)->setLastIndex(exec, JSValue::decode(value), true);
 }
 
-    
-    
-EncodedJSValue regExpObjectSource(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName)
+static void regExpObjectSetLastIndexNonStrict(ExecState* exec, JSObject* slotBase, EncodedJSValue, EncodedJSValue value)
 {
-    String pattern = asRegExpObject(slotBase)->regExp()->pattern();
-    if (pattern.is8Bit())
-        return JSValue::encode(regExpObjectSourceInternal(exec, pattern, pattern.characters8(), pattern.length()));
-    return JSValue::encode(regExpObjectSourceInternal(exec, pattern, pattern.characters16(), pattern.length()));
+    asRegExpObject(slotBase)->setLastIndex(exec, JSValue::decode(value), false);
 }
 
 void RegExpObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
 {
     if (propertyName == exec->propertyNames().lastIndex) {
         asRegExpObject(cell)->setLastIndex(exec, value, slot.isStrictMode());
+        slot.setCustomProperty(asRegExpObject(cell), slot.isStrictMode()
+            ? regExpObjectSetLastIndexStrict
+            : regExpObjectSetLastIndexNonStrict);
         return;
     }
     Base::put(cell, exec, propertyName, value, slot);
@@ -298,7 +162,7 @@ void RegExpObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName,
 JSValue RegExpObject::exec(ExecState* exec, JSString* string)
 {
     if (MatchResult result = match(exec, string))
-        return RegExpMatchesArray::create(exec, string, regExp(), result);
+        return createRegExpMatchesArray(exec, string, regExp(), result);
     return jsNull();
 }
 
index 2b49ba2a44fbc7f59955e2abaf31f2801e7ca73f..a1f571d9f695baa57043851f297374b7535b53ed 100644 (file)
 
 namespace JSC {
     
-    class RegExpObject : public JSNonFinalObject {
-    public:
-        typedef JSNonFinalObject Base;
-
-        static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
-        {
-            RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
-            object->finishCreation(vm);
-            return object;
-        }
-
-        void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
-        RegExp* regExp() const { return m_regExp.get(); }
-
-        void setLastIndex(ExecState* exec, size_t lastIndex)
-        {
+class RegExpObject : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+
+    static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
+    {
+        RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
+        object->finishCreation(vm);
+        return object;
+    }
+
+    void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
+    RegExp* regExp() const { return m_regExp.get(); }
+
+    void setLastIndex(ExecState* exec, size_t lastIndex)
+    {
+        m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+        if (LIKELY(m_lastIndexIsWritable))
             m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
-            if (LIKELY(m_lastIndexIsWritable))
-                m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
-            else
-                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-        }
-        void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
-        {
-            if (LIKELY(m_lastIndexIsWritable))
-                m_lastIndex.set(exec->vm(), this, lastIndex);
-            else if (shouldThrow)
-                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-        }
-        JSValue getLastIndex() const
-        {
-            return m_lastIndex.get();
-        }
-
-        bool test(ExecState* exec, JSString* string) { return match(exec, string); }
-        JSValue exec(ExecState*, JSString*);
-
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-        static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-
-        DECLARE_EXPORT_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
-        JS_EXPORT_PRIVATE void finishCreation(VM&);
-
-        static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | Base::StructureFlags;
-
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-        JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-        JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-        JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-        JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-
-    private:
-        MatchResult match(ExecState*, JSString*);
-
-        WriteBarrier<RegExp> m_regExp;
-        WriteBarrier<Unknown> m_lastIndex;
-        bool m_lastIndexIsWritable;
-    };
-
-    RegExpObject* asRegExpObject(JSValue);
-
-    inline RegExpObject* asRegExpObject(JSValue value)
+        else
+            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+    }
+    void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
+    {
+        if (LIKELY(m_lastIndexIsWritable))
+            m_lastIndex.set(exec->vm(), this, lastIndex);
+        else if (shouldThrow)
+            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+    }
+    JSValue getLastIndex() const
+    {
+        return m_lastIndex.get();
+    }
+
+    bool test(ExecState* exec, JSString* string) { return match(exec, string); }
+    JSValue exec(ExecState*, JSString*);
+
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        ASSERT(asObject(value)->inherits(RegExpObject::info()));
-        return static_cast<RegExpObject*>(asObject(value));
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
+protected:
+    JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
+    JS_EXPORT_PRIVATE void finishCreation(VM&);
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+
+private:
+    MatchResult match(ExecState*, JSString*);
+
+    WriteBarrier<RegExp> m_regExp;
+    WriteBarrier<Unknown> m_lastIndex;
+    bool m_lastIndexIsWritable;
+};
+
+RegExpObject* asRegExpObject(JSValue);
+
+inline RegExpObject* asRegExpObject(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(RegExpObject::info()));
+    return static_cast<RegExpObject*>(asObject(value));
+}
+
 } // namespace JSC
 
 #endif // RegExpObject_h
index 7aeaff56afdd76fa9689484e1c73299a12bca523..fb6fc5f4aaf19907569f441adb9573f53b9ad101 100644 (file)
@@ -29,6 +29,7 @@
 #include "JSObject.h"
 #include "JSString.h"
 #include "JSStringBuilder.h"
+#include "Lexer.h"
 #include "ObjectPrototype.h"
 #include "JSCInlines.h"
 #include "RegExpObject.h"
@@ -42,6 +43,11 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*);
 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*);
 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*);
 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoGetterGlobal(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoGetterIgnoreCase(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoGetterMultiline(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoGetterSource(ExecState*);
+static EncodedJSValue JSC_HOST_CALL regExpProtoGetterFlags(ExecState*);
 
 }
 
@@ -49,14 +55,19 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
 
 namespace JSC {
 
-const ClassInfo RegExpPrototype::s_info = { "RegExp", &RegExpObject::s_info, 0, ExecState::regExpPrototypeTable, CREATE_METHOD_TABLE(RegExpPrototype) };
+const ClassInfo RegExpPrototype::s_info = { "RegExp", &RegExpObject::s_info, &regExpPrototypeTable, CREATE_METHOD_TABLE(RegExpPrototype) };
 
 /* Source for RegExpPrototype.lut.h
 @begin regExpPrototypeTable
-  compile   regExpProtoFuncCompile      DontEnum|Function 2
-  exec      regExpProtoFuncExec         DontEnum|Function 1
-  test      regExpProtoFuncTest         DontEnum|Function 1
-  toString  regExpProtoFuncToString     DontEnum|Function 0
+  compile       regExpProtoFuncCompile      DontEnum|Function 2
+  exec          regExpProtoFuncExec         DontEnum|Function 1
+  test          regExpProtoFuncTest         DontEnum|Function 1
+  toString      regExpProtoFuncToString     DontEnum|Function 0
+  global        regExpProtoGetterGlobal     DontEnum|Accessor
+  ignoreCase    regExpProtoGetterIgnoreCase DontEnum|Accessor
+  multiline     regExpProtoGetterMultiline  DontEnum|Accessor
+  source        regExpProtoGetterSource     DontEnum|Accessor
+  flags         regExpProtoGetterFlags      DontEnum|Accessor
 @end
 */
 
@@ -67,7 +78,7 @@ RegExpPrototype::RegExpPrototype(VM& vm, Structure* structure, RegExp* regExp)
 
 bool RegExpPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<RegExpObject>(exec, ExecState::regExpPrototypeTable(exec->vm()), jsCast<RegExpPrototype*>(object), propertyName, slot);
+    return getStaticFunctionSlot<Base>(exec, regExpPrototypeTable, jsCast<RegExpPrototype*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions ---------------------------
@@ -126,29 +137,214 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
     return JSValue::encode(jsUndefined());
 }
 
+typedef std::array<char, 3 + 1> FlagsString; // 3 different flags and a null character terminator.
+
+static inline FlagsString flagsString(ExecState* exec, JSObject* regexp)
+{
+    FlagsString string;
+
+    JSValue globalValue = regexp->get(exec, exec->propertyNames().global);
+    if (exec->hadException())
+        return string;
+    JSValue ignoreCaseValue = regexp->get(exec, exec->propertyNames().ignoreCase);
+    if (exec->hadException())
+        return string;
+    JSValue multilineValue = regexp->get(exec, exec->propertyNames().multiline);
+
+    unsigned index = 0;
+    if (globalValue.toBoolean(exec))
+        string[index++] = 'g';
+    if (ignoreCaseValue.toBoolean(exec))
+        string[index++] = 'i';
+    if (multilineValue.toBoolean(exec))
+        string[index++] = 'm';
+    ASSERT(index < string.size());
+    string[index] = 0;
+    return string;
+}
+
 EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
-    if (!thisValue.inherits(RegExpObject::info()))
+    if (!thisValue.isObject())
         return throwVMTypeError(exec);
 
-    RegExpObject* thisObject = asRegExpObject(thisValue);
+    JSObject* thisObject = asObject(thisValue);
 
     StringRecursionChecker checker(exec, thisObject);
     if (JSValue earlyReturnValue = checker.earlyReturnValue())
         return JSValue::encode(earlyReturnValue);
 
-    char postfix[5] = { '/', 0, 0, 0, 0 };
-    int index = 1;
-    if (thisObject->get(exec, exec->propertyNames().global).toBoolean(exec))
-        postfix[index++] = 'g';
-    if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
-        postfix[index++] = 'i';
-    if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
-        postfix[index] = 'm';
-    String source = thisObject->get(exec, exec->propertyNames().source).toString(exec)->value(exec);
-    // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
-    return JSValue::encode(jsMakeNontrivialString(exec, "/", source, postfix));
+    JSValue sourceValue = thisObject->get(exec, exec->propertyNames().source);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    String source = sourceValue.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    auto flags = flagsString(exec, thisObject);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    return JSValue::encode(jsMakeNontrivialString(exec, '/', source, '/', flags.data()));
+}
+
+EncodedJSValue JSC_HOST_CALL regExpProtoGetterGlobal(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!thisValue.inherits(RegExpObject::info()))
+        return throwVMTypeError(exec);
+
+    return JSValue::encode(jsBoolean(asRegExpObject(thisValue)->regExp()->global()));
+}
+
+EncodedJSValue JSC_HOST_CALL regExpProtoGetterIgnoreCase(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!thisValue.inherits(RegExpObject::info()))
+        return throwVMTypeError(exec);
+
+    return JSValue::encode(jsBoolean(asRegExpObject(thisValue)->regExp()->ignoreCase()));
+}
+
+EncodedJSValue JSC_HOST_CALL regExpProtoGetterMultiline(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!thisValue.inherits(RegExpObject::info()))
+        return throwVMTypeError(exec);
+
+    return JSValue::encode(jsBoolean(asRegExpObject(thisValue)->regExp()->multiline()));
+}
+
+EncodedJSValue JSC_HOST_CALL regExpProtoGetterFlags(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!thisValue.isObject())
+        return throwVMTypeError(exec);
+
+    auto flags = flagsString(exec, asObject(thisValue));
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    return JSValue::encode(jsString(exec, flags.data()));
+}
+
+template <typename CharacterType>
+static inline void appendLineTerminatorEscape(StringBuilder&, CharacterType);
+
+template <>
+inline void appendLineTerminatorEscape<LChar>(StringBuilder& builder, LChar lineTerminator)
+{
+    if (lineTerminator == '\n')
+        builder.append('n');
+    else
+        builder.append('r');
+}
+
+template <>
+inline void appendLineTerminatorEscape<UChar>(StringBuilder& builder, UChar lineTerminator)
+{
+    if (lineTerminator == '\n')
+        builder.append('n');
+    else if (lineTerminator == '\r')
+        builder.append('r');
+    else if (lineTerminator == 0x2028)
+        builder.appendLiteral("u2028");
+    else
+        builder.appendLiteral("u2029");
+}
+
+template <typename CharacterType>
+static inline JSValue regExpProtoGetterSourceInternal(ExecState* exec, const String& pattern, const CharacterType* characters, unsigned length)
+{
+    bool previousCharacterWasBackslash = false;
+    bool inBrackets = false;
+    bool shouldEscape = false;
+
+    // 15.10.6.4 specifies that RegExp.prototype.toString must return '/' + source + '/',
+    // and also states that the result must be a valid RegularExpressionLiteral. '//' is
+    // not a valid RegularExpressionLiteral (since it is a single line comment), and hence
+    // source cannot ever validly be "". If the source is empty, return a different Pattern
+    // that would match the same thing.
+    if (!length)
+        return jsNontrivialString(exec, ASCIILiteral("(?:)"));
+
+    // early return for strings that don't contain a forwards slash and LineTerminator
+    for (unsigned i = 0; i < length; ++i) {
+        CharacterType ch = characters[i];
+        if (!previousCharacterWasBackslash) {
+            if (inBrackets) {
+                if (ch == ']')
+                    inBrackets = false;
+            } else {
+                if (ch == '/') {
+                    shouldEscape = true;
+                    break;
+                }
+                if (ch == '[')
+                    inBrackets = true;
+            }
+        }
+
+        if (Lexer<CharacterType>::isLineTerminator(ch)) {
+            shouldEscape = true;
+            break;
+        }
+
+        if (previousCharacterWasBackslash)
+            previousCharacterWasBackslash = false;
+        else
+            previousCharacterWasBackslash = ch == '\\';
+    }
+
+    if (!shouldEscape)
+        return jsString(exec, pattern);
+
+    previousCharacterWasBackslash = false;
+    inBrackets = false;
+    StringBuilder result;
+    for (unsigned i = 0; i < length; ++i) {
+        CharacterType ch = characters[i];
+        if (!previousCharacterWasBackslash) {
+            if (inBrackets) {
+                if (ch == ']')
+                    inBrackets = false;
+            } else {
+                if (ch == '/')
+                    result.append('\\');
+                else if (ch == '[')
+                    inBrackets = true;
+            }
+        }
+
+        // escape LineTerminator
+        if (Lexer<CharacterType>::isLineTerminator(ch)) {
+            if (!previousCharacterWasBackslash)
+                result.append('\\');
+
+            appendLineTerminatorEscape<CharacterType>(result, ch);
+        } else
+            result.append(ch);
+
+        if (previousCharacterWasBackslash)
+            previousCharacterWasBackslash = false;
+        else
+            previousCharacterWasBackslash = ch == '\\';
+    }
+
+    return jsString(exec, result.toString());
+}
+
+EncodedJSValue JSC_HOST_CALL regExpProtoGetterSource(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!thisValue.inherits(RegExpObject::info()))
+        return throwVMTypeError(exec);
+
+    String pattern = asRegExpObject(thisValue)->regExp()->pattern();
+    if (pattern.is8Bit())
+        return JSValue::encode(regExpProtoGetterSourceInternal(exec, pattern, pattern.characters8(), pattern.length()));
+    return JSValue::encode(regExpProtoGetterSourceInternal(exec, pattern, pattern.characters16(), pattern.length()));
 }
 
 } // namespace JSC
index e9fef179bc2b8f898d9b93a4676e34798502b42a..cb6ee6974a47cecbe101976a3dd4b8e73fe391b3 100644 (file)
 
 namespace JSC {
 
-    class RegExpPrototype : public RegExpObject {
-    public:
-        typedef RegExpObject Base;
-
-        static RegExpPrototype* create(VM& vm, Structure* structure, RegExp* regExp)
-        {
-            RegExpPrototype* prototype = new (NotNull, allocateCell<RegExpPrototype>(vm.heap)) RegExpPrototype(vm, structure, regExp);
-            prototype->finishCreation(vm);
-            return prototype;
-        }
-        
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        RegExpPrototype(VM&, Structure*, RegExp*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | RegExpObject::StructureFlags;
-
-    private:
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    };
+class RegExpPrototype : public RegExpObject {
+public:
+    typedef RegExpObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static RegExpPrototype* create(VM& vm, Structure* structure, RegExp* regExp)
+    {
+        RegExpPrototype* prototype = new (NotNull, allocateCell<RegExpPrototype>(vm.heap)) RegExpPrototype(vm, structure, regExp);
+        prototype->finishCreation(vm);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+protected:
+    RegExpPrototype(VM&, Structure*, RegExp*);
+
+private:
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
 
 } // namespace JSC
 
diff --git a/runtime/RuntimeFlags.h b/runtime/RuntimeFlags.h
new file mode 100644 (file)
index 0000000..edc3e75
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RuntimeFlags_h
+#define RuntimeFlags_h
+
+#include <initializer_list>
+
+namespace JSC {
+
+// macro(name, isEnabledFlag)
+#define JSC_RUNTIME_FLAG(macro) \
+    macro(SymbolDisabled, false)\
+    macro(PromiseDisabled, false)
+
+
+class RuntimeFlags {
+private:
+    enum RuntimeFlagShiftValue : unsigned {
+#define JSC_DECLARE_RUNTIME_FLAG_SHIFT_VALUE(name, isEnabledFlag) shiftValueFor##name,
+        JSC_RUNTIME_FLAG(JSC_DECLARE_RUNTIME_FLAG_SHIFT_VALUE)
+#undef JSC_DECLARE_RUNTIME_FLAG_SHIFT_VALUE
+    };
+
+public:
+    enum RuntimeFlag : unsigned {
+#define JSC_DECLARE_RUNTIME_FLAG(name, isEnabledFlag) name = 1u << (shiftValueFor##name),
+        JSC_RUNTIME_FLAG(JSC_DECLARE_RUNTIME_FLAG)
+#undef JSC_DECLARE_RUNTIME_FLAG
+    };
+
+#define JSC_DECLARE_RUNTIME_FLAG_ACCESSOR(name, isEnabledFlag) \
+    void set##name(bool value)\
+    {\
+        if (value)\
+            m_flags |= name;\
+        else\
+            m_flags &= (~name);\
+    }\
+    bool is##name() const\
+    {\
+        return m_flags & name;\
+    }
+    JSC_RUNTIME_FLAG(JSC_DECLARE_RUNTIME_FLAG_ACCESSOR)
+#undef JSC_DECLARE_RUNTIME_FLAG_ACCESSOR
+
+    RuntimeFlags()
+        : RuntimeFlags(0u)
+    {
+    }
+
+    RuntimeFlags(std::initializer_list<RuntimeFlag> initializerList)
+        : RuntimeFlags()
+    {
+        for (RuntimeFlag flag : initializerList)
+            m_flags |= flag;
+    }
+
+    explicit RuntimeFlags(unsigned flags)
+        : m_flags(flags)
+    {
+    }
+
+    static RuntimeFlags createAllEnabled()
+    {
+        return RuntimeFlags(
+#define JSC_USE_RUNTIME_FLAG(name, isEnabledFlag) ((isEnabledFlag) ? name : 0u) |
+            JSC_RUNTIME_FLAG(JSC_USE_RUNTIME_FLAG)
+#undef JSC_USE_RUNTIME_FLAG
+            0u
+        );
+    }
+
+private:
+    unsigned m_flags;
+};
+
+} // namespace JSC
+
+#endif // RuntimeFlags_h
diff --git a/runtime/RuntimeType.cpp b/runtime/RuntimeType.cpp
new file mode 100644 (file)
index 0000000..4e7b3a7
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) Saam Barati <saambarati1@gmail.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+
+#include "config.h"
+#include "RuntimeType.h"
+
+#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
+
+namespace JSC {
+
+RuntimeType runtimeTypeForValue(JSValue value)
+{
+    if (value.isUndefined())
+        return TypeUndefined;
+    if (value.isNull())
+        return TypeNull;
+    if (value.isMachineInt())
+        return TypeMachineInt;
+    if (value.isNumber())
+        return TypeNumber;
+    if (value.isString())
+        return TypeString;
+    if (value.isBoolean())
+        return TypeBoolean;
+    if (value.isObject())
+        return TypeObject;
+    if (value.isFunction())
+        return TypeFunction;
+    if (value.isSymbol())
+        return TypeSymbol;
+
+    return TypeNothing;
+}
+
+String runtimeTypeAsString(RuntimeType type)
+{
+    if (type == TypeUndefined)
+        return ASCIILiteral("Undefined");
+    if (type == TypeNull)
+        return ASCIILiteral("Null");
+    if (type == TypeMachineInt)
+        return ASCIILiteral("Integer");
+    if (type == TypeNumber)
+        return ASCIILiteral("Number");
+    if (type == TypeString)
+        return ASCIILiteral("String");
+    if (type == TypeObject)
+        return ASCIILiteral("Object");
+    if (type == TypeBoolean)
+        return ASCIILiteral("Boolean");
+    if (type == TypeFunction)
+        return ASCIILiteral("Function");
+    if (type == TypeNothing)
+        return ASCIILiteral("(Nothing)");
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return emptyString();
+}
+
+} // namespace JSC
diff --git a/runtime/RuntimeType.h b/runtime/RuntimeType.h
new file mode 100644 (file)
index 0000000..d57b8fb
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) Saam Barati <saambarati1@gmail.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RuntimeType_h
+#define RuntimeType_h
+
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+enum RuntimeType : uint16_t {
+    TypeNothing            = 0x0,
+    TypeFunction           = 0x1,
+    TypeUndefined          = 0x2,
+    TypeNull               = 0x4,
+    TypeBoolean            = 0x8,
+    TypeMachineInt         = 0x10,
+    TypeNumber             = 0x20,
+    TypeString             = 0x40,
+    TypeObject             = 0x80,
+    TypeSymbol             = 0x100
+};
+
+typedef uint16_t RuntimeTypeMask;
+
+class JSValue;
+RuntimeType runtimeTypeForValue(JSValue);
+String runtimeTypeAsString(RuntimeType);
+
+ALWAYS_INLINE bool runtimeTypeIsPrimitive(RuntimeTypeMask type)
+{
+    return type & ~(TypeFunction | TypeObject);
+}
+
+} // namespace JSC
+
+#endif // RuntimeType_h
diff --git a/runtime/ScopeOffset.cpp b/runtime/ScopeOffset.cpp
new file mode 100644 (file)
index 0000000..1753165
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ScopeOffset.h"
+
+namespace JSC {
+
+void ScopeOffset::dump(PrintStream& out) const
+{
+    if (!*this) {
+        out.print("scopeInvalid");
+        return;
+    }
+    
+    out.print("scope", offset());
+}
+
+} // namespace JSC
+
diff --git a/runtime/ScopeOffset.h b/runtime/ScopeOffset.h
new file mode 100644 (file)
index 0000000..4dbd186
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ScopeOffset_h
+#define ScopeOffset_h
+
+#include "GenericOffset.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+// This is an offset into a scope of some kind. It could be an activation scope or it could be a
+// global object.
+class ScopeOffset : public GenericOffset<ScopeOffset> {
+public:
+    ScopeOffset() { }
+    
+    explicit ScopeOffset(unsigned offset)
+        : GenericOffset(offset)
+    {
+    }
+    
+    void dump(PrintStream&) const;
+};
+
+} // namespace JSC
+
+#endif // ScopeOffset_h
+
diff --git a/runtime/ScopedArguments.cpp b/runtime/ScopedArguments.cpp
new file mode 100644 (file)
index 0000000..a5a2fc7
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ScopedArguments.h"
+
+#include "GenericArgumentsInlines.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ScopedArguments);
+
+const ClassInfo ScopedArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(ScopedArguments) };
+
+ScopedArguments::ScopedArguments(VM& vm, Structure* structure, unsigned totalLength)
+    : GenericArguments(vm, structure)
+    , m_overrodeThings(false)
+    , m_totalLength(totalLength)
+{
+}
+
+void ScopedArguments::finishCreation(VM& vm, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    Base::finishCreation(vm);
+    m_callee.set(vm, this, callee);
+    m_table.set(vm, this, table);
+    m_scope.set(vm, this, scope);
+}
+
+ScopedArguments* ScopedArguments::createUninitialized(VM& vm, Structure* structure, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope, unsigned totalLength)
+{
+    unsigned overflowLength;
+    if (totalLength > table->length())
+        overflowLength = totalLength - table->length();
+    else
+        overflowLength = 0;
+    ScopedArguments* result = new (
+        NotNull,
+        allocateCell<ScopedArguments>(vm.heap, allocationSize(overflowLength)))
+        ScopedArguments(vm, structure, totalLength);
+    result->finishCreation(vm, callee, table, scope);
+    return result;
+}
+
+ScopedArguments* ScopedArguments::create(VM& vm, Structure* structure, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope, unsigned totalLength)
+{
+    ScopedArguments* result =
+        createUninitialized(vm, structure, callee, table, scope, totalLength);
+
+    unsigned namedLength = table->length();
+    for (unsigned i = namedLength; i < totalLength; ++i)
+        result->overflowStorage()[i - namedLength].clear();
+    
+    return result;
+}
+
+ScopedArguments* ScopedArguments::createByCopying(ExecState* exec, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    return createByCopyingFrom(
+        exec->vm(), exec->lexicalGlobalObject()->scopedArgumentsStructure(),
+        exec->registers() + CallFrame::argumentOffset(0), exec->argumentCount(),
+        jsCast<JSFunction*>(exec->callee()), table, scope);
+}
+
+ScopedArguments* ScopedArguments::createByCopyingFrom(VM& vm, Structure* structure, Register* argumentsStart, unsigned totalLength, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    ScopedArguments* result =
+        createUninitialized(vm, structure, callee, table, scope, totalLength);
+    
+    unsigned namedLength = table->length();
+    for (unsigned i = namedLength; i < totalLength; ++i)
+        result->overflowStorage()[i - namedLength].set(vm, result, argumentsStart[i].jsValue());
+    
+    return result;
+}
+
+void ScopedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    ScopedArguments* thisObject = static_cast<ScopedArguments*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.append(&thisObject->m_callee);
+    visitor.append(&thisObject->m_table);
+    visitor.append(&thisObject->m_scope);
+    
+    if (thisObject->m_totalLength > thisObject->m_table->length()) {
+        visitor.appendValues(
+            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
+    }
+}
+
+Structure* ScopedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ScopedArgumentsType, StructureFlags), info());
+}
+
+void ScopedArguments::overrideThings(VM& vm)
+{
+    RELEASE_ASSERT(!m_overrodeThings);
+    
+    putDirect(vm, vm.propertyNames->length, jsNumber(m_table->length()), DontEnum);
+    putDirect(vm, vm.propertyNames->callee, m_callee.get(), DontEnum);
+    putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum);
+    
+    m_overrodeThings = true;
+}
+
+void ScopedArguments::overrideThingsIfNecessary(VM& vm)
+{
+    if (!m_overrodeThings)
+        overrideThings(vm);
+}
+
+void ScopedArguments::overrideArgument(VM& vm, uint32_t i)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(i < m_totalLength);
+    unsigned namedLength = m_table->length();
+    if (i < namedLength)
+        m_table.set(vm, this, m_table->set(vm, i, ScopeOffset()));
+    else
+        overflowStorage()[i - namedLength].clear();
+}
+
+void ScopedArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    GenericArguments::copyToArguments(exec, firstElementDest, offset, length);
+}
+
+} // namespace JSC
+
diff --git a/runtime/ScopedArguments.h b/runtime/ScopedArguments.h
new file mode 100644 (file)
index 0000000..8d36a1b
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ScopedArguments_h
+#define ScopedArguments_h
+
+#include "GenericArguments.h"
+#include "JSLexicalEnvironment.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you say "arguments" inside a function,
+// and one or more of the arguments may be captured in the function's activation. The function
+// will copy its formally declared arguments into the activation and then create this object. This
+// object will store the overflow arguments, if there are any. This object will use the symbol
+// table's ScopedArgumentsTable and the activation, or its overflow storage, to handle all indexed
+// lookups.
+class ScopedArguments : public GenericArguments<ScopedArguments> {
+private:
+    ScopedArguments(VM&, Structure*, unsigned totalLength);
+    void finishCreation(VM&, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
+
+public:
+    // Creates an arguments object but leaves it uninitialized. This is dangerous if we GC right
+    // after allocation.
+    static ScopedArguments* createUninitialized(VM&, Structure*, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*, unsigned totalLength);
+    
+    // Creates an arguments object and initializes everything to the empty value. Use this if you
+    // cannot guarantee that you'll immediately initialize all of the elements.
+    static ScopedArguments* create(VM&, Structure*, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*, unsigned totalLength);
+    
+    // Creates an arguments object by copying the arguments from the stack.
+    static ScopedArguments* createByCopying(ExecState*, ScopedArgumentsTable*, JSLexicalEnvironment*);
+    
+    // Creates an arguments object by copying the arguments from a well-defined stack location.
+    static ScopedArguments* createByCopyingFrom(VM&, Structure*, Register* argumentsStart, unsigned totalLength, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
+    
+    static void visitChildren(JSCell*, SlotVisitor&);
+    
+    uint32_t internalLength() const
+    {
+        return m_totalLength;
+    }
+    
+    uint32_t length(ExecState* exec) const
+    {
+        if (UNLIKELY(m_overrodeThings))
+            return get(exec, exec->propertyNames().length).toUInt32(exec);
+        return internalLength();
+    }
+    
+    bool canAccessIndexQuickly(uint32_t i) const
+    {
+        if (i >= m_totalLength)
+            return false;
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            return !!m_table->get(i);
+        return !!overflowStorage()[i - namedLength].get();
+    }
+
+    bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
+    {
+        return canAccessIndexQuickly(i);
+    }
+    
+    JSValue getIndexQuickly(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            return m_scope->variableAt(m_table->get(i)).get();
+        return overflowStorage()[i - namedLength].get();
+    }
+
+    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            m_scope->variableAt(m_table->get(i)).set(vm, this, value);
+        else
+            overflowStorage()[i - namedLength].set(vm, this, value);
+    }
+
+    WriteBarrier<JSFunction>& callee()
+    {
+        return m_callee;
+    }
+    
+    bool overrodeThings() const { return m_overrodeThings; }
+    void overrideThings(VM&);
+    void overrideThingsIfNecessary(VM&);
+    void overrideArgument(VM&, uint32_t index);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+    
+    static ptrdiff_t offsetOfOverrodeThings() { return OBJECT_OFFSETOF(ScopedArguments, m_overrodeThings); }
+    static ptrdiff_t offsetOfTotalLength() { return OBJECT_OFFSETOF(ScopedArguments, m_totalLength); }
+    static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(ScopedArguments, m_table); }
+    static ptrdiff_t offsetOfScope() { return OBJECT_OFFSETOF(ScopedArguments, m_scope); }
+    
+    static size_t overflowStorageOffset()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(ScopedArguments));
+    }
+    
+    static size_t allocationSize(unsigned overflowArgumentsLength)
+    {
+        return overflowStorageOffset() + sizeof(WriteBarrier<Unknown>) * overflowArgumentsLength;
+    }
+
+private:
+    WriteBarrier<Unknown>* overflowStorage() const
+    {
+        return bitwise_cast<WriteBarrier<Unknown>*>(
+            bitwise_cast<char*>(this) + overflowStorageOffset());
+    }
+    
+    
+    bool m_overrodeThings; // True if length, callee, and caller are fully materialized in the object.
+    unsigned m_totalLength; // The length of declared plus overflow arguments.
+    WriteBarrier<JSFunction> m_callee;
+    WriteBarrier<ScopedArgumentsTable> m_table;
+    WriteBarrier<JSLexicalEnvironment> m_scope;
+};
+
+} // namespace JSC
+
+#endif // ScopedArguments_h
+
diff --git a/runtime/ScopedArgumentsTable.cpp b/runtime/ScopedArgumentsTable.cpp
new file mode 100644 (file)
index 0000000..9be4797
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ScopedArgumentsTable.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo ScopedArgumentsTable::s_info = { "ScopedArgumentsTable", 0, 0, CREATE_METHOD_TABLE(ScopedArgumentsTable) };
+
+ScopedArgumentsTable::ScopedArgumentsTable(VM& vm)
+    : Base(vm, vm.scopedArgumentsTableStructure.get())
+    , m_length(0)
+    , m_locked(false)
+{
+}
+
+ScopedArgumentsTable::~ScopedArgumentsTable()
+{
+}
+
+void ScopedArgumentsTable::destroy(JSCell* cell)
+{
+    static_cast<ScopedArgumentsTable*>(cell)->ScopedArgumentsTable::~ScopedArgumentsTable();
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::create(VM& vm)
+{
+    ScopedArgumentsTable* result =
+        new (NotNull, allocateCell<ScopedArgumentsTable>(vm.heap)) ScopedArgumentsTable(vm);
+    result->finishCreation(vm);
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::create(VM& vm, uint32_t length)
+{
+    ScopedArgumentsTable* result = create(vm);
+    result->m_length = length;
+    result->m_arguments = std::make_unique<ScopeOffset[]>(length);
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::clone(VM& vm)
+{
+    ScopedArgumentsTable* result = create(vm, m_length);
+    for (unsigned i = m_length; i--;)
+        result->m_arguments[i] = m_arguments[i];
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength)
+{
+    if (LIKELY(!m_locked)) {
+        std::unique_ptr<ScopeOffset[]> newArguments = std::make_unique<ScopeOffset[]>(newLength);
+        for (unsigned i = std::min(m_length, newLength); i--;)
+            newArguments[i] = m_arguments[i];
+        m_length = newLength;
+        m_arguments = WTF::move(newArguments);
+        return this;
+    }
+    
+    ScopedArgumentsTable* result = create(vm, newLength);
+    for (unsigned i = std::min(m_length, newLength); i--;)
+        result->m_arguments[i] = m_arguments[i];
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::set(VM& vm, uint32_t i, ScopeOffset value)
+{
+    ScopedArgumentsTable* result;
+    if (UNLIKELY(m_locked))
+        result = clone(vm);
+    else
+        result = this;
+    result->at(i) = value;
+    return result;
+}
+
+Structure* ScopedArgumentsTable::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+} // namespace JSC
+
diff --git a/runtime/ScopedArgumentsTable.h b/runtime/ScopedArgumentsTable.h
new file mode 100644 (file)
index 0000000..b6d7ddc
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ScopedArgumentsTable_h
+#define ScopedArgumentsTable_h
+
+#include "JSCell.h"
+#include "ScopeOffset.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// This class's only job is to hold onto the list of ScopeOffsets for each argument that a
+// function has. Most of the time, the BytecodeGenerator will create one of these and it will
+// never be modified subsequently. There is a rare case where a ScopedArguments object is created
+// and aliases one of these and then decides to modify it; in that case we do copy-on-write. This
+// makes sense because such modifications are so uncommon. You'd have to do something crazy like
+// "delete arguments[i]" or some variant of defineOwnProperty.
+class ScopedArgumentsTable final : public JSCell {
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+    
+private:
+    ScopedArgumentsTable(VM&);
+    ~ScopedArgumentsTable();
+
+public:
+    static ScopedArgumentsTable* create(VM&);
+    static ScopedArgumentsTable* create(VM&, uint32_t length);
+    
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+    ScopedArgumentsTable* clone(VM&);
+    
+    uint32_t length() const { return m_length; }
+    ScopedArgumentsTable* setLength(VM&, uint32_t newLength);
+    
+    ScopeOffset get(uint32_t i) const
+    {
+        return const_cast<ScopedArgumentsTable*>(this)->at(i);
+    }
+    
+    void lock()
+    {
+        m_locked = true;
+    }
+    
+    ScopedArgumentsTable* set(VM&, uint32_t index, ScopeOffset);
+    
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_length); }
+    static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); }
+
+private:
+    ScopeOffset& at(uint32_t i)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
+        return m_arguments[i];
+    }
+    
+    uint32_t m_length;
+    bool m_locked; // Being locked means that there are multiple references to this object and none of them expect to see the others' modifications. This means that modifications need to make a copy first.
+    std::unique_ptr<ScopeOffset[]> m_arguments;
+};
+
+} // namespace JSC
+
+#endif // ScopedArgumentsTable_h
+
index 8ad7e54a4622a5062a0a6afa943fad46aa4e272c..fb97b6d9fa0d0ee63a1d52a9887ec77698f753df 100644 (file)
@@ -27,6 +27,7 @@
 #include "SetConstructor.h"
 
 #include "Error.h"
+#include "IteratorOperations.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
@@ -37,7 +38,7 @@
 
 namespace JSC {
 
-const ClassInfo SetConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(SetConstructor) };
+const ClassInfo SetConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(SetConstructor) };
 
 void SetConstructor::finishCreation(VM& vm, SetPrototype* setPrototype)
 {
@@ -46,31 +47,67 @@ void SetConstructor::finishCreation(VM& vm, SetPrototype* setPrototype)
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum | DontDelete);
 }
 
-static EncodedJSValue JSC_HOST_CALL callSet(CallFrame* callFrame)
+static EncodedJSValue JSC_HOST_CALL callSet(ExecState* exec)
 {
-    // Until we have iterators we throw if we've been given
-    // any arguments that could require us to throw.
-    if (!callFrame->argument(0).isUndefinedOrNull())
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Set does not accept arguments when called as a function")));
-    if (!callFrame->argument(1).isUndefined())
-        return throwVMError(callFrame, createRangeError(callFrame, WTF::ASCIILiteral("Invalid comparator function")));
-
-    JSGlobalObject* globalObject = asInternalFunction(callFrame->callee())->globalObject();
-    Structure* setStructure = globalObject->setStructure();
-    return JSValue::encode(JSSet::create(callFrame, setStructure));
+    return JSValue::encode(throwTypeError(exec, ASCIILiteral("Set cannot be called as a function")));
 }
 
-static EncodedJSValue JSC_HOST_CALL constructSet(CallFrame* callFrame)
+static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 {
-    JSGlobalObject* globalObject = asInternalFunction(callFrame->callee())->globalObject();
+    JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
     Structure* setStructure = globalObject->setStructure();
-    JSSet* set = JSSet::create(callFrame, setStructure);
-    MapData* mapData = set->mapData();
-    size_t count = callFrame->argumentCount();
-    for (size_t i = 0; i < count; i++) {
-        JSValue item = callFrame->uncheckedArgument(i);
-        mapData->set(callFrame, item, item);
+    JSSet* set = JSSet::create(exec, setStructure);
+    JSValue iterable = exec->argument(0);
+    if (iterable.isUndefinedOrNull())
+        return JSValue::encode(set);
+
+    JSValue adderFunction = set->get(exec, exec->propertyNames().add);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData adderFunctionCallData;
+    CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
+    if (adderFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData iteratorFunctionCallData;
+    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
+    if (iteratorFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    ArgList iteratorFunctionArguments;
+    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    if (!iterator.isObject())
+        return JSValue::encode(throwTypeError(exec));
+
+    while (true) {
+        JSValue next = iteratorStep(exec, iterator);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (next.isFalse())
+            return JSValue::encode(set);
+
+        JSValue nextValue = iteratorValue(exec, next);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(nextValue);
+        call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, set, arguments);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
     }
+    RELEASE_ASSERT_NOT_REACHED();
     return JSValue::encode(set);
 }
 
diff --git a/runtime/SetIteratorConstructor.cpp b/runtime/SetIteratorConstructor.cpp
deleted file mode 100644 (file)
index 19d716e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "SetIteratorConstructor.h"
-
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSGlobalObject.h"
-#include "JSSetIterator.h"
-#include "SetIteratorPrototype.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-const ClassInfo SetIteratorConstructor::s_info = { "Set Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(SetIteratorConstructor) };
-
-void SetIteratorConstructor::finishCreation(VM& vm, SetIteratorPrototype* prototype)
-{
-    Base::finishCreation(vm);
-    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
-}
-
-}
diff --git a/runtime/SetIteratorConstructor.h b/runtime/SetIteratorConstructor.h
deleted file mode 100644 (file)
index cfd954e..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef SetIteratorConstructor_h
-#define SetIteratorConstructor_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-class SetIteratorPrototype;
-
-class SetIteratorConstructor : public JSNonFinalObject {
-public:
-    typedef JSNonFinalObject Base;
-
-    static SetIteratorConstructor* create(VM& vm, Structure* structure, SetIteratorPrototype* prototype)
-    {
-        SetIteratorConstructor* constructor = new (NotNull, allocateCell<SetIteratorConstructor>(vm.heap)) SetIteratorConstructor(vm, structure);
-        constructor->finishCreation(vm, prototype);
-        return constructor;
-    }
-
-    DECLARE_INFO;
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-    }
-
-private:
-    SetIteratorConstructor(VM& vm, Structure* structure)
-        : Base(vm, structure)
-    {
-    }
-    void finishCreation(VM&, SetIteratorPrototype*);
-};
-
-}
-
-#endif // !defined(SetConstructor_h)
index 319381d0233b86b60d5cdd30df0daba71ea78028..ab8df44475d1023dace03faaee503d0814a87383 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "SetIteratorPrototype.h"
 
+#include "IteratorOperations.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSSetIterator.h"
 
 namespace JSC {
 
-const ClassInfo SetIteratorPrototype::s_info = { "Set Iterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(SetIteratorPrototype) };
+const ClassInfo SetIteratorPrototype::s_info = { "Set Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(SetIteratorPrototype) };
 
-static EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncIterator(ExecState*);
 static EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncNext(ExecState*);
 
-
 void SetIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
 
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, SetIteratorPrototypeFuncIterator, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorNextPrivateName, SetIteratorPrototypeFuncNext, DontEnum, 0);
-}
-
-EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncIterator(CallFrame* callFrame)
-{
-    return JSValue::encode(callFrame->thisValue());
+    JSC_NATIVE_FUNCTION(vm.propertyNames->next, SetIteratorPrototypeFuncNext, DontEnum, 0);
 }
 
 EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncNext(CallFrame* callFrame)
@@ -62,10 +55,9 @@ EncodedJSValue JSC_HOST_CALL SetIteratorPrototypeFuncNext(CallFrame* callFrame)
         return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call SetIterator.next() on a non-SetIterator object")));
 
     if (iterator->next(callFrame, result))
-        return JSValue::encode(result);
-
-    return JSValue::encode(callFrame->vm().iterationTerminator.get());
+        return JSValue::encode(createIteratorResultObject(callFrame, result, false));
+    iterator->finish();
+    return JSValue::encode(createIteratorResultObject(callFrame, jsUndefined(), true));
 }
 
-
 }
index 01970e040b4160a2f612f0dd4f08dfe3760741ef..e83e383258f99bb05bbe11e0c65de04b8e049e0a 100644 (file)
 #include "JSFunctionInlines.h"
 #include "JSSet.h"
 #include "JSSetIterator.h"
-#include "MapData.h"
+#include "MapDataInlines.h"
 #include "StructureInlines.h"
 
 namespace JSC {
 
-const ClassInfo SetPrototype::s_info = { "Set", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(SetPrototype) };
+const ClassInfo SetPrototype::s_info = { "Set", &Base::s_info, 0, CREATE_METHOD_TABLE(SetPrototype) };
 
 static EncodedJSValue JSC_HOST_CALL setProtoFuncAdd(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncClear(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncDelete(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncForEach(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncHas(ExecState*);
-static EncodedJSValue JSC_HOST_CALL setProtoFuncKeys(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncValues(ExecState*);
 static EncodedJSValue JSC_HOST_CALL setProtoFuncEntries(ExecState*);
 
@@ -64,61 +63,64 @@ void SetPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     JSC_NATIVE_FUNCTION(vm.propertyNames->deleteKeyword, setProtoFuncDelete, DontEnum, 1);
     JSC_NATIVE_FUNCTION(vm.propertyNames->forEach, setProtoFuncForEach, DontEnum, 1);
     JSC_NATIVE_FUNCTION(vm.propertyNames->has, setProtoFuncHas, DontEnum, 1);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->keys, setProtoFuncKeys, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->values, setProtoFuncValues, DontEnum, 0);
     JSC_NATIVE_FUNCTION(vm.propertyNames->entries, setProtoFuncEntries, DontEnum, 0);
-    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, setProtoFuncKeys, DontEnum, 0);
 
-    GetterSetter* accessor = GetterSetter::create(vm);
+    JSFunction* values = JSFunction::create(vm, globalObject, 0, vm.propertyNames->values.string(), setProtoFuncValues);
+    putDirectWithoutTransition(vm, vm.propertyNames->values, values, DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->keys, values, DontEnum);
+    putDirectWithoutTransition(vm, vm.propertyNames->iteratorSymbol, values, DontEnum);
+
+    GetterSetter* accessor = GetterSetter::create(vm, globalObject);
     JSFunction* function = JSFunction::create(vm, globalObject, 0, vm.propertyNames->size.string(), setProtoFuncSize);
-    accessor->setGetter(vm, function);
+    accessor->setGetter(vm, globalObject, function);
     putDirectNonIndexAccessor(vm, vm.propertyNames->size, accessor, DontEnum | Accessor);
 }
 
-ALWAYS_INLINE static MapData* getMapData(CallFrame* callFrame, JSValue thisValue)
+ALWAYS_INLINE static JSSet* getSet(CallFrame* callFrame, JSValue thisValue)
 {
     if (!thisValue.isObject()) {
         throwVMError(callFrame, createNotAnObjectError(callFrame, thisValue));
-        return 0;
+        return nullptr;
     }
     JSSet* set = jsDynamicCast<JSSet*>(thisValue);
     if (!set) {
         throwTypeError(callFrame, ASCIILiteral("Set operation called on non-Set object"));
-        return 0;
+        return nullptr;
     }
-    return set->mapData();
+    return set;
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncAdd(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSValue thisValue = callFrame->thisValue();
+    JSSet* set = getSet(callFrame, thisValue);
+    if (!set)
         return JSValue::encode(jsUndefined());
-    data->set(callFrame, callFrame->argument(0), callFrame->argument(0));
-    return JSValue::encode(callFrame->thisValue());
+    set->add(callFrame, callFrame->argument(0));
+    return JSValue::encode(thisValue);
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncClear(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSSet* set = getSet(callFrame, callFrame->thisValue());
+    if (!set)
         return JSValue::encode(jsUndefined());
-    data->clear();
+    set->clear(callFrame);
     return JSValue::encode(jsUndefined());
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncDelete(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSSet* set = getSet(callFrame, callFrame->thisValue());
+    if (!set)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsBoolean(data->remove(callFrame, callFrame->argument(0))));
+    return JSValue::encode(jsBoolean(set->remove(callFrame, callFrame->argument(0))));
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncForEach(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSSet* set = getSet(callFrame, callFrame->thisValue());
+    if (!set)
         return JSValue::encode(jsUndefined());
     JSValue callBack = callFrame->argument(0);
     CallData callData;
@@ -127,45 +129,53 @@ EncodedJSValue JSC_HOST_CALL setProtoFuncForEach(CallFrame* callFrame)
         return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("Set.prototype.forEach called without callback")));
     JSValue thisValue = callFrame->argument(1);
     VM* vm = &callFrame->vm();
+    JSSetIterator* iterator = JSSetIterator::create(*vm, callFrame->callee()->globalObject()->setIteratorStructure(), set, SetIterateKey);
+    JSValue key;
     if (callType == CallTypeJS) {
         JSFunction* function = jsCast<JSFunction*>(callBack);
-        CachedCall cachedCall(callFrame, function, 1);
-        for (auto ptr = data->begin(), end = data->end(); ptr != end && !vm->exception(); ++ptr) {
+        CachedCall cachedCall(callFrame, function, 3);
+        while (iterator->next(callFrame, key) && !vm->exception()) {
             cachedCall.setThis(thisValue);
-            cachedCall.setArgument(0, ptr.key());
+            cachedCall.setArgument(0, key);
+            cachedCall.setArgument(1, key);
+            cachedCall.setArgument(2, set);
             cachedCall.call();
         }
+        iterator->finish();
     } else {
-        for (auto ptr = data->begin(), end = data->end(); ptr != end && !vm->exception(); ++ptr) {
+        while (iterator->next(callFrame, key) && !vm->exception()) {
             MarkedArgumentBuffer args;
-            args.append(ptr.key());
+            args.append(key);
+            args.append(key);
+            args.append(set);
             JSC::call(callFrame, callBack, callType, callData, thisValue, args);
         }
+        iterator->finish();
     }
     return JSValue::encode(jsUndefined());
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncHas(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSSet* set = getSet(callFrame, callFrame->thisValue());
+    if (!set)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsBoolean(data->contains(callFrame, callFrame->argument(0))));
+    return JSValue::encode(jsBoolean(set->has(callFrame, callFrame->argument(0))));
 }
 
 EncodedJSValue JSC_HOST_CALL setProtoFuncSize(CallFrame* callFrame)
 {
-    MapData* data = getMapData(callFrame, callFrame->thisValue());
-    if (!data)
+    JSSet* set = getSet(callFrame, callFrame->thisValue());
+    if (!set)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(jsNumber(data->size(callFrame)));
+    return JSValue::encode(jsNumber(set->size(callFrame)));
 }
     
 EncodedJSValue JSC_HOST_CALL setProtoFuncValues(CallFrame* callFrame)
 {
     JSSet* thisObj = jsDynamicCast<JSSet*>(callFrame->thisValue());
     if (!thisObj)
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map value iterator for a non-Map object.")));
+        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Set value iterator for a non-Set object.")));
     return JSValue::encode(JSSetIterator::create(callFrame->vm(), callFrame->callee()->globalObject()->setIteratorStructure(), thisObj, SetIterateValue));
 }
 
@@ -173,16 +183,8 @@ EncodedJSValue JSC_HOST_CALL setProtoFuncEntries(CallFrame* callFrame)
 {
     JSSet* thisObj = jsDynamicCast<JSSet*>(callFrame->thisValue());
     if (!thisObj)
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map key iterator for a non-Map object.")));
+        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Set entry iterator for a non-Set object.")));
     return JSValue::encode(JSSetIterator::create(callFrame->vm(), callFrame->callee()->globalObject()->setIteratorStructure(), thisObj, SetIterateKeyValue));
 }
 
-EncodedJSValue JSC_HOST_CALL setProtoFuncKeys(CallFrame* callFrame)
-{
-    JSSet* thisObj = jsDynamicCast<JSSet*>(callFrame->thisValue());
-    if (!thisObj)
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot create a Map entry iterator for a non-Map object.")));
-    return JSValue::encode(JSSetIterator::create(callFrame->vm(), callFrame->callee()->globalObject()->setIteratorStructure(), thisObj, SetIterateKey));
-}
-
 }
index a4bdb0c9e3cbfbacf58ed281957f0adf6a8794b1..9c6a43ae2138f4eefeba6e1d02bc2ead19e4de51 100644 (file)
@@ -31,7 +31,6 @@
 #include "JSString.h"
 #include "JSCInlines.h"
 #include <wtf/Noncopyable.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/text/StringImpl.h>
 
 namespace JSC {
@@ -58,7 +57,7 @@ SmallStringsStorage::SmallStringsStorage()
     RefPtr<StringImpl> baseString = StringImpl::createUninitialized(singleCharacterStringCount, characterBuffer);
     for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
         characterBuffer[i] = i;
-        m_reps[i] = AtomicString::add(PassRefPtr<StringImpl>(StringImpl::createSubstringSharingImpl(baseString, i, 1)).get());
+        m_reps[i] = AtomicStringImpl::add(PassRefPtr<StringImpl>(StringImpl::createSubstringSharingImpl(baseString, i, 1)).get());
     }
 }
 
@@ -69,6 +68,7 @@ SmallStrings::SmallStrings()
 #undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE
     , m_nullObjectString(nullptr)
     , m_undefinedObjectString(nullptr)
+    , m_needsToBeVisited(true)
 {
     COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
 
@@ -90,6 +90,7 @@ void SmallStrings::initializeCommonStrings(VM& vm)
 
 void SmallStrings::visitStrongReferences(SlotVisitor& visitor)
 {
+    m_needsToBeVisited = false;
     visitor.appendUnbarrieredPointer(&m_emptyString);
     for (unsigned i = 0; i <= maxSingleCharacterString; ++i)
         visitor.appendUnbarrieredPointer(m_singleCharacterStrings + i);
@@ -108,26 +109,29 @@ void SmallStrings::createEmptyString(VM* vm)
 {
     ASSERT(!m_emptyString);
     m_emptyString = JSString::createHasOtherOwner(*vm, StringImpl::empty());
+    m_needsToBeVisited = true;
 }
 
 void SmallStrings::createSingleCharacterString(VM* vm, unsigned char character)
 {
     if (!m_storage)
-        m_storage = adoptPtr(new SmallStringsStorage);
+        m_storage = std::make_unique<SmallStringsStorage>();
     ASSERT(!m_singleCharacterStrings[character]);
     m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*vm, PassRefPtr<StringImpl>(m_storage->rep(character)));
+    m_needsToBeVisited = true;
 }
 
 StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character)
 {
     if (!m_storage)
-        m_storage = adoptPtr(new SmallStringsStorage);
+        m_storage = std::make_unique<SmallStringsStorage>();
     return m_storage->rep(character);
 }
 
-void SmallStrings::initialize(VM* vm, JSString*& string, const char* value) const
+void SmallStrings::initialize(VM* vm, JSString*& string, const char* value)
 {
-    string = JSString::create(*vm, StringImpl::create(value));
+    string = JSString::create(*vm, Identifier::fromString(vm, value).impl());
+    m_needsToBeVisited = true;
 }
 
 } // namespace JSC
index e3d398113ba8776863cede485cc0f7fa44aa8cbc..909bae1dea90e820563620ef309891ba21722dfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,9 +26,9 @@
 #ifndef SmallStrings_h
 #define SmallStrings_h
 
+#include "TypeofType.h"
 #include "WriteBarrier.h"
 #include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
 
 #define JSC_COMMON_STRINGS_EACH_NAME(macro) \
     macro(boolean) \
@@ -39,6 +39,7 @@
     macro(object) \
     macro(undefined) \
     macro(string) \
+    macro(symbol) \
     macro(true)
 
 namespace WTF {
@@ -47,65 +48,96 @@ class StringImpl;
 
 namespace JSC {
 
-    class HeapRootVisitor;
-    class VM;
-    class JSString;
-    class SmallStringsStorage;
-    class SlotVisitor;
+class HeapRootVisitor;
+class VM;
+class JSString;
+class SmallStringsStorage;
+class SlotVisitor;
 
-    static const unsigned maxSingleCharacterString = 0xFF;
+static const unsigned maxSingleCharacterString = 0xFF;
 
-    class SmallStrings {
-        WTF_MAKE_NONCOPYABLE(SmallStrings);
-    public:
-        SmallStrings();
-        ~SmallStrings();
+class SmallStrings {
+    WTF_MAKE_NONCOPYABLE(SmallStrings);
+public:
+    SmallStrings();
+    ~SmallStrings();
 
-        JSString* emptyString()
-        {
-            return m_emptyString;
-        }
+    JSString* emptyString()
+    {
+        return m_emptyString;
+    }
 
-        JSString* singleCharacterString(unsigned char character)
-        {
-            return m_singleCharacterStrings[character];
-        }
+    JSString* singleCharacterString(unsigned char character)
+    {
+        return m_singleCharacterStrings[character];
+    }
 
-        JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character);
+    JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character);
 
-        JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
+    JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
 
-        void initializeCommonStrings(VM&);
-        void visitStrongReferences(SlotVisitor&);
+    void initializeCommonStrings(VM&);
+    void visitStrongReferences(SlotVisitor&);
 
 #define JSC_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
-        JSString* name##String() const \
-        { \
-            return m_##name; \
-        }
-        JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
+    JSString* name##String() const                   \
+    {                                                \
+        return m_##name;                             \
+    }
+    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
 #undef JSC_COMMON_STRINGS_ACCESSOR_DEFINITION
+    
+    JSString* typeString(TypeofType type) const
+    {
+        switch (type) {
+        case TypeofType::Undefined:
+            return undefinedString();
+        case TypeofType::Boolean:
+            return booleanString();
+        case TypeofType::Number:
+            return numberString();
+        case TypeofType::String:
+            return stringString();
+        case TypeofType::Symbol:
+            return symbolString();
+        case TypeofType::Object:
+            return objectString();
+        case TypeofType::Function:
+            return functionString();
+        }
+        
+        RELEASE_ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
+    JSString* nullObjectString() const { return m_nullObjectString; }
+    JSString* undefinedObjectString() const { return m_undefinedObjectString; }
 
-        JSString* nullObjectString() const { return m_nullObjectString; }
-        JSString* undefinedObjectString() const { return m_undefinedObjectString; }
+    bool needsToBeVisited(HeapOperation collectionType) const
+    {
+        if (collectionType == FullCollection)
+            return true;
+        return m_needsToBeVisited;
+    }
 
-    private:
-        static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
+private:
+    static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
 
-        JS_EXPORT_PRIVATE void createEmptyString(VM*);
-        JS_EXPORT_PRIVATE void createSingleCharacterString(VM*, unsigned char);
+    JS_EXPORT_PRIVATE void createEmptyString(VM*);
+    JS_EXPORT_PRIVATE void createSingleCharacterString(VM*, unsigned char);
 
-        void initialize(VM* vm, JSString*& string, const char* value) const;
+    void initialize(VM*, JSString*&, const char* value);
 
-        JSString* m_emptyString;
+    JSString* m_emptyString;
 #define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) JSString* m_##name;
-        JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
+    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
 #undef JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION
-        JSString* m_nullObjectString;
-        JSString* m_undefinedObjectString;
-        JSString* m_singleCharacterStrings[singleCharacterStringCount];
-        OwnPtr<SmallStringsStorage> m_storage;
-    };
+    JSString* m_nullObjectString;
+    JSString* m_undefinedObjectString;
+    JSString* m_singleCharacterStrings[singleCharacterStringCount];
+    std::unique_ptr<SmallStringsStorage> m_storage;
+    bool m_needsToBeVisited;
+};
 
 } // namespace JSC
 
index 31909248c9eb7388fa8e6b4099b4074f0ca2b902..62d34baafddb40eea0f615f06207a29ab9ff9983 100644 (file)
@@ -37,7 +37,7 @@
 
 namespace JSC {
 
-const ClassInfo SparseArrayValueMap::s_info = { "SparseArrayValueMap", 0, 0, 0, CREATE_METHOD_TABLE(SparseArrayValueMap) };
+const ClassInfo SparseArrayValueMap::s_info = { "SparseArrayValueMap", 0, 0, CREATE_METHOD_TABLE(SparseArrayValueMap) };
 
 SparseArrayValueMap::SparseArrayValueMap(VM& vm)
     : Base(vm, vm.sparseArrayValueMapStructure.get())
@@ -69,7 +69,7 @@ void SparseArrayValueMap::destroy(JSCell* cell)
 
 Structure* SparseArrayValueMap::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 {
-    return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
 }
 
 SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigned i)
@@ -80,7 +80,9 @@ SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigne
     AddResult result = m_map.add(i, entry);
     size_t capacity = m_map.capacity();
     if (capacity != m_reportedCapacity) {
-        Heap::heap(array)->reportExtraMemoryCost((capacity - m_reportedCapacity) * (sizeof(unsigned) + sizeof(WriteBarrier<Unknown>)));
+        // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated.
+        // https://bugs.webkit.org/show_bug.cgi?id=142595
+        Heap::heap(array)->deprecatedReportExtraMemory((capacity - m_reportedCapacity) * (sizeof(unsigned) + sizeof(WriteBarrier<Unknown>)));
         m_reportedCapacity = capacity;
     }
     return result;
index 4e5326f767e030f19f4f1501f0464af218777cc7..ff36caa711f1bc3ed6768b1d5ab855eeae7de5ab 100644 (file)
@@ -51,9 +51,10 @@ struct SparseArrayEntry : public WriteBarrier<Unknown> {
     unsigned attributes;
 };
 
-class SparseArrayValueMap : public JSCell {
+class SparseArrayValueMap final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     
 private:
     typedef HashMap<uint64_t, SparseArrayEntry, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> Map;
@@ -69,8 +70,6 @@ private:
     
     void finishCreation(VM&);
 
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | JSCell::StructureFlags;
-
 public:
     DECLARE_EXPORT_INFO;
     
@@ -81,7 +80,6 @@ public:
     static SparseArrayValueMap* create(VM&);
     
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
     
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
index e05e7d3dd9057a1187419f9f2130abf50b65cfdb..4260e10b9f021b49b1c4cda2849a6d1b906f63b1 100644 (file)
@@ -33,13 +33,13 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StrictEvalActivation);
 
-const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictEvalActivation) };
+const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, 0, CREATE_METHOD_TABLE(StrictEvalActivation) };
 
-StrictEvalActivation::StrictEvalActivation(ExecState* exec)
+StrictEvalActivation::StrictEvalActivation(ExecState* exec, JSScope* currentScope)
     : Base(
         exec->vm(),
         exec->lexicalGlobalObject()->strictEvalActivationStructure(),
-        exec->scope()
+        currentScope
     )
 {
 }
index e02bb615d04fb15ec7f5cf147ab16991e0ac51d8..13157f68af62656cc440168677c389a884f8228c 100644 (file)
@@ -33,12 +33,13 @@ namespace JSC {
 class StrictEvalActivation : public JSScope {
 public:
     typedef JSScope Base;
+    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord;
 
-    static StrictEvalActivation* create(ExecState* exec)
+    static StrictEvalActivation* create(ExecState* exec, JSScope* currentScope)
     {
-        StrictEvalActivation* activation = new (NotNull, allocateCell<StrictEvalActivation>(*exec->heap())) StrictEvalActivation(exec);
-        activation->finishCreation(exec->vm());
-        return activation;
+        StrictEvalActivation* lexicalEnvironment = new (NotNull, allocateCell<StrictEvalActivation>(*exec->heap())) StrictEvalActivation(exec, currentScope);
+        lexicalEnvironment->finishCreation(exec->vm());
+        return lexicalEnvironment;
     }
 
     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
@@ -51,11 +52,8 @@ public:
     
     DECLARE_INFO;
 
-protected:
-    static const unsigned StructureFlags = IsEnvironmentRecord | Base::StructureFlags;
-
 private:
-    StrictEvalActivation(ExecState*);
+    StrictEvalActivation(ExecState*, JSScope*);
 };
 
 } // namespace JSC
index f8221d7cbcc4933407aa34c95a97b1580c3b3688..e8d39697073e355d3775206731631e6e8773310f 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "StringConstructor.h"
 
+#include "Error.h"
 #include "Executable.h"
 #include "JITCode.h"
 #include "JSFunction.h"
@@ -31,6 +32,7 @@
 namespace JSC {
 
 static EncodedJSValue JSC_HOST_CALL stringFromCharCode(ExecState*);
+static EncodedJSValue JSC_HOST_CALL stringFromCodePoint(ExecState*);
 
 }
 
@@ -38,11 +40,13 @@ static EncodedJSValue JSC_HOST_CALL stringFromCharCode(ExecState*);
 
 namespace JSC {
 
-const ClassInfo StringConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::stringConstructorTable, CREATE_METHOD_TABLE(StringConstructor) };
+const ClassInfo StringConstructor::s_info = { "Function", &InternalFunction::s_info, &stringConstructorTable, CREATE_METHOD_TABLE(StringConstructor) };
 
 /* Source for StringConstructor.lut.h
 @begin stringConstructorTable
   fromCharCode          stringFromCharCode         DontEnum|Function 1
+  fromCodePoint         stringFromCodePoint        DontEnum|Function 1
+  raw                   stringRaw                  DontEnum|Function 1
 @end
 */
 
@@ -62,7 +66,7 @@ void StringConstructor::finishCreation(VM& vm, StringPrototype* stringPrototype)
 
 bool StringConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
 {
-    return getStaticFunctionSlot<InternalFunction>(exec, ExecState::stringConstructorTable(exec->vm()), jsCast<StringConstructor*>(object), propertyName, slot);
+    return getStaticFunctionSlot<InternalFunction>(exec, stringConstructorTable, jsCast<StringConstructor*>(object), propertyName, slot);
 }
 
 // ------------------------------ Functions --------------------------------
@@ -89,6 +93,33 @@ JSCell* JSC_HOST_CALL stringFromCharCode(ExecState* exec, int32_t arg)
     return jsSingleCharacterString(exec, arg);
 }
 
+static EncodedJSValue JSC_HOST_CALL stringFromCodePoint(ExecState* exec)
+{
+    unsigned length = exec->argumentCount();
+    StringBuilder builder;
+    builder.reserveCapacity(length);
+
+    for (unsigned i = 0; i < length; ++i) {
+        double codePointAsDouble = exec->uncheckedArgument(i).toNumber(exec);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        uint32_t codePoint = static_cast<uint32_t>(codePointAsDouble);
+
+        if (codePoint != codePointAsDouble || codePoint > UCHAR_MAX_VALUE)
+            return throwVMError(exec, createRangeError(exec, ASCIILiteral("Arguments contain a value that is out of range of code points")));
+
+        if (U_IS_BMP(codePoint))
+            builder.append(static_cast<UChar>(codePoint));
+        else {
+            builder.append(U16_LEAD(codePoint));
+            builder.append(U16_TRAIL(codePoint));
+        }
+    }
+
+    return JSValue::encode(jsString(exec, builder.toString()));
+}
+
 static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec)
 {
     JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
@@ -96,7 +127,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* ex
 
     if (!exec->argumentCount())
         return JSValue::encode(StringObject::create(vm, globalObject->stringObjectStructure()));
-    
+
     return JSValue::encode(StringObject::create(vm, globalObject->stringObjectStructure(), exec->uncheckedArgument(0).toString(exec)));
 }
 
@@ -106,11 +137,18 @@ ConstructType StringConstructor::getConstructData(JSCell*, ConstructData& constr
     return ConstructTypeHost;
 }
 
+JSCell* stringConstructor(ExecState* exec, JSValue argument)
+{
+    if (argument.isSymbol())
+        return jsNontrivialString(exec, asSymbol(argument)->descriptiveString());
+    return argument.toString(exec);
+}
+
 static EncodedJSValue JSC_HOST_CALL callStringConstructor(ExecState* exec)
 {
     if (!exec->argumentCount())
         return JSValue::encode(jsEmptyString(exec));
-    return JSValue::encode(exec->uncheckedArgument(0).toString(exec));
+    return JSValue::encode(stringConstructor(exec, exec->uncheckedArgument(0)));
 }
 
 CallType StringConstructor::getCallData(JSCell*, CallData& callData)
index a2c08231ef12de5bcbd09a62ace732183b7de6b1..357511a57654e16825fd22b0ae677389d203c203 100644 (file)
 
 namespace JSC {
 
-    class StringPrototype;
-
-    class StringConstructor : public InternalFunction {
-    public:
-        typedef InternalFunction Base;
-
-        static StringConstructor* create(VM& vm, Structure* structure, StringPrototype* stringPrototype)
-        {
-            StringConstructor* constructor = new (NotNull, allocateCell<StringConstructor>(vm.heap)) StringConstructor(vm, structure);
-            constructor->finishCreation(vm, stringPrototype);
-            return constructor;
-        }
-
-        DECLARE_INFO;
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
-
-    private:
-        StringConstructor(VM&, Structure*);
-        void finishCreation(VM&, StringPrototype*);
-        static ConstructType getConstructData(JSCell*, ConstructData&);
-        static CallType getCallData(JSCell*, CallData&);
-
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    };
-    
-    JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
+class StringPrototype;
+
+class StringConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static StringConstructor* create(VM& vm, Structure* structure, StringPrototype* stringPrototype)
+    {
+        StringConstructor* constructor = new (NotNull, allocateCell<StringConstructor>(vm.heap)) StringConstructor(vm, structure);
+        constructor->finishCreation(vm, stringPrototype);
+        return constructor;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    StringConstructor(VM&, Structure*);
+    void finishCreation(VM&, StringPrototype*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
+
+JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
+JSCell* stringConstructor(ExecState*, JSValue);
 
 } // namespace JSC
 
diff --git a/runtime/StringIteratorPrototype.cpp b/runtime/StringIteratorPrototype.cpp
new file mode 100644 (file)
index 0000000..b58d0dd
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple, Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StringIteratorPrototype.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "JSGlobalObject.h"
+#include "JSStringIterator.h"
+#include "ObjectConstructor.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+}
+
+#include "StringIteratorPrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo StringIteratorPrototype::s_info = { "String Iterator", &Base::s_info, &stringIteratorPrototypeTable, CREATE_METHOD_TABLE(StringIteratorPrototype) };
+
+/* Source for StringIteratorPrototype.lut.h
+@begin stringIteratorPrototypeTable
+  next      stringIteratorPrototypeFuncNext  DontEnum|Function 0
+@end
+*/
+
+void StringIteratorPrototype::finishCreation(VM& vm, JSGlobalObject*)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+    vm.prototypeMap.addPrototype(this);
+}
+
+bool StringIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+    return getStaticFunctionSlot<Base>(exec, stringIteratorPrototypeTable, jsCast<StringIteratorPrototype*>(object), propertyName, slot);
+}
+
+} // namespace JSC
diff --git a/runtime/StringIteratorPrototype.h b/runtime/StringIteratorPrototype.h
new file mode 100644 (file)
index 0000000..393af56
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 Apple, Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StringIteratorPrototype_h
+#define StringIteratorPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class StringIteratorPrototype : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static StringIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        StringIteratorPrototype* prototype = new (NotNull, allocateCell<StringIteratorPrototype>(vm.heap)) StringIteratorPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    StringIteratorPrototype(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    void finishCreation(VM&, JSGlobalObject*);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
+
+}
+
+#endif // !defined(StringIteratorPrototype_h)
index a5e23f74123b0d1d28b86e609d97522c4004d576..eb7430eb553ad760747854b2f64eebeb7e508782 100644 (file)
@@ -30,7 +30,7 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StringObject);
 
-const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
+const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, CREATE_METHOD_TABLE(StringObject) };
 
 StringObject::StringObject(VM& vm, Structure* structure)
     : JSWrapperObject(vm, structure)
@@ -93,7 +93,7 @@ bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, Property
         }
         if (descriptor.configurablePresent() && descriptor.configurable()) {
             if (throwException)
-                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+                exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
             return false;
         }
         if (descriptor.enumerablePresent() && descriptor.enumerable()) {
@@ -128,9 +128,8 @@ bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName pr
     StringObject* thisObject = jsCast<StringObject*>(cell);
     if (propertyName == exec->propertyNames().length)
         return false;
-    unsigned i = propertyName.asIndex();
-    if (thisObject->internalValue()->canGetIndex(i)) {
-        ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
+    Optional<uint32_t> index = parseIndex(propertyName);
+    if (index && thisObject->internalValue()->canGetIndex(index.value())) {
         return false;
     }
     return JSObject::deleteProperty(thisObject, exec, propertyName);
@@ -150,7 +149,7 @@ void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Proper
     int size = thisObject->internalValue()->length();
     for (int i = 0; i < size; ++i)
         propertyNames.add(Identifier::from(exec, i));
-    if (mode == IncludeDontEnumProperties)
+    if (mode.includeDontEnumProperties())
         propertyNames.add(exec->propertyNames().length);
     return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
 }
index df63614747362bfd3bf33eac58e641067677305a..90e6e5cca44aa0647435a0aaf7bd0b3cfdf1da09 100644 (file)
 
 namespace JSC {
 
-    class StringObject : public JSWrapperObject {
-    public:
-        typedef JSWrapperObject Base;
-
-        static StringObject* create(VM& vm, Structure* structure)
-        {
-            JSString* string = jsEmptyString(&vm);
-            StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
-            object->finishCreation(vm, string);
-            return object;
-        }
-        static StringObject* create(VM& vm, Structure* structure, JSString* string)
-        {
-            StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
-            object->finishCreation(vm, string);
-            return object;
-        }
-        static StringObject* create(VM&, JSGlobalObject*, JSString*);
-
-        static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-        static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
-
-        static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
-
-        static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-        static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
-        static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-        static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-
-        DECLARE_EXPORT_INFO;
-
-        JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
-
-    protected:
-        JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
-        JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
-    };
-
-    StringObject* asStringObject(JSValue);
-
-    inline StringObject* asStringObject(JSValue value)
+class StringObject : public JSWrapperObject {
+public:
+    typedef JSWrapperObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
+
+    static StringObject* create(VM& vm, Structure* structure)
+    {
+        JSString* string = jsEmptyString(&vm);
+        StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
+        object->finishCreation(vm, string);
+        return object;
+    }
+    static StringObject* create(VM& vm, Structure* structure, JSString* string)
+    {
+        StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
+        object->finishCreation(vm, string);
+        return object;
+    }
+    static StringObject* create(VM&, JSGlobalObject*, JSString*);
+
+    JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
+
+    JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+
+    JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+    JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+
+    DECLARE_EXPORT_INFO;
+
+    JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        ASSERT(asObject(value)->inherits(StringObject::info()));
-        return static_cast<StringObject*>(asObject(value));
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue);
+protected:
+    JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
+    JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
+};
+
+StringObject* asStringObject(JSValue);
+
+inline StringObject* asStringObject(JSValue value)
+{
+    ASSERT(asObject(value)->inherits(StringObject::info()));
+    return static_cast<StringObject*>(asObject(value));
+}
+
+JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue);
 
 } // namespace JSC
 
index c5d7d2b9150bd6970c9c78e4473ecb29e902a48e..2edbf42c746e9335c7fa216375eaff9703fcac50 100644 (file)
@@ -2,6 +2,7 @@
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
  *  Copyright (C) 2009 Torch Mobile, Inc.
+ *  Copyright (C) 2015 Jordan Harband (ljharb@gmail.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
 #include "Lookup.h"
 #include "ObjectPrototype.h"
 #include "JSCInlines.h"
+#include "JSStringIterator.h"
 #include "PropertyNameArray.h"
 #include "RegExpCache.h"
 #include "RegExpConstructor.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
+#include <algorithm>
 #include <wtf/ASCIICType.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/StringView.h>
@@ -50,40 +53,46 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StringPrototype);
 
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*);
-static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*);
-
-const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringPrototype) };
+EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncCodePointAt(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeat(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncStartsWith(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncEndsWith(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncIncludes(ExecState*);
+EncodedJSValue JSC_HOST_CALL stringProtoFuncIterator(ExecState*);
+
+const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, CREATE_METHOD_TABLE(StringPrototype) };
 
 // ECMA 15.5.4
 StringPrototype::StringPrototype(VM& vm, Structure* structure)
@@ -100,10 +109,12 @@ void StringPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject, JSStr
     JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->valueOf, stringProtoFuncToString, DontEnum, 0, StringPrototypeValueOfIntrinsic);
     JSC_NATIVE_INTRINSIC_FUNCTION("charAt", stringProtoFuncCharAt, DontEnum, 1, CharAtIntrinsic);
     JSC_NATIVE_INTRINSIC_FUNCTION("charCodeAt", stringProtoFuncCharCodeAt, DontEnum, 1, CharCodeAtIntrinsic);
+    JSC_NATIVE_FUNCTION("codePointAt", stringProtoFuncCodePointAt, DontEnum, 1);
     JSC_NATIVE_FUNCTION("concat", stringProtoFuncConcat, DontEnum, 1);
     JSC_NATIVE_FUNCTION("indexOf", stringProtoFuncIndexOf, DontEnum, 1);
     JSC_NATIVE_FUNCTION("lastIndexOf", stringProtoFuncLastIndexOf, DontEnum, 1);
     JSC_NATIVE_FUNCTION("match", stringProtoFuncMatch, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("repeat", stringProtoFuncRepeat, DontEnum, 1);
     JSC_NATIVE_FUNCTION("replace", stringProtoFuncReplace, DontEnum, 2);
     JSC_NATIVE_FUNCTION("search", stringProtoFuncSearch, DontEnum, 1);
     JSC_NATIVE_FUNCTION("slice", stringProtoFuncSlice, DontEnum, 2);
@@ -131,6 +142,12 @@ void StringPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject, JSStr
     JSC_NATIVE_FUNCTION("trim", stringProtoFuncTrim, DontEnum, 0);
     JSC_NATIVE_FUNCTION("trimLeft", stringProtoFuncTrimLeft, DontEnum, 0);
     JSC_NATIVE_FUNCTION("trimRight", stringProtoFuncTrimRight, DontEnum, 0);
+    JSC_NATIVE_FUNCTION("startsWith", stringProtoFuncStartsWith, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("endsWith", stringProtoFuncEndsWith, DontEnum, 1);
+    JSC_NATIVE_FUNCTION("includes", stringProtoFuncIncludes, DontEnum, 1);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorSymbol, stringProtoFuncIterator, DontEnum, 0);
+
+    JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->charCodeAtPrivateName, stringProtoFuncCharCodeAt, DontEnum, 1, CharCodeAtIntrinsic);
 
     // The constructor will be added later, after StringConstructor has been built
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
@@ -158,6 +175,16 @@ static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue
     return jsString(exec, string);
 }
 
+// Helper that tries to use the JSString substring sharing mechanism if 'originalValue' is a JSString.
+static inline JSString* jsSubstring(ExecState* exec, JSValue originalValue, const String& string, unsigned offset, unsigned length)
+{
+    if (originalValue.isString()) {
+        ASSERT(asString(originalValue)->value(exec) == string);
+        return jsSubstring(exec, asString(originalValue), offset, length);
+    }
+    return jsSubstring(exec, string, offset, length);
+}
+
 static NEVER_INLINE String substituteBackreferencesSlow(StringView replacement, StringView source, const int* ovector, RegExp* reg, size_t i)
 {
     StringBuilder substitutedReplacement;
@@ -666,6 +693,66 @@ static inline bool checkObjectCoercible(JSValue thisValue)
     return true;
 }
 
+template <typename CharacterType>
+static inline JSValue repeatCharacter(ExecState* exec, CharacterType character, unsigned repeatCount)
+{
+    CharacterType* buffer = nullptr;
+    RefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(repeatCount, buffer);
+    if (!impl)
+        return throwOutOfMemoryError(exec);
+
+    std::fill_n(buffer, repeatCount, character);
+
+    return jsString(exec, impl.release());
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeat(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+
+    JSString* string = thisValue.toString(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    double repeatCountDouble = exec->argument(0).toInteger(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    if (repeatCountDouble < 0 || std::isinf(repeatCountDouble))
+        return throwVMError(exec, createRangeError(exec, ASCIILiteral("repeat() argument must be greater than or equal to 0 and not be infinity")));
+
+    VM& vm = exec->vm();
+
+    if (!string->length() || !repeatCountDouble)
+        return JSValue::encode(jsEmptyString(&vm));
+
+    if (repeatCountDouble == 1)
+        return JSValue::encode(string);
+
+    // JSString requires the limitation that its length is in the range of int32_t.
+    if (repeatCountDouble > std::numeric_limits<int32_t>::max() / string->length())
+        return JSValue::encode(throwOutOfMemoryError(exec));
+    unsigned repeatCount = static_cast<unsigned>(repeatCountDouble);
+
+    // For a string which length is small, instead of creating ropes,
+    // allocating a sequential buffer and fill with the repeated string for efficiency.
+    if (string->length() == 1) {
+        String repeatedString = string->value(exec);
+        UChar character = repeatedString.at(0);
+        if (!(character & ~0xff))
+            return JSValue::encode(repeatCharacter(exec, static_cast<LChar>(character), repeatCount));
+        return JSValue::encode(repeatCharacter(exec, character, repeatCount));
+    }
+
+    JSRopeString::RopeBuilder ropeBuilder(vm);
+    for (unsigned i = 0; i < repeatCount; ++i) {
+        if (!ropeBuilder.append(string))
+            return JSValue::encode(throwOutOfMemoryError(exec));
+    }
+    return JSValue::encode(ropeBuilder.release());
+}
+
 EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
@@ -698,18 +785,17 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec)
     JSValue thisValue = exec->thisValue();
     if (!checkObjectCoercible(thisValue))
         return throwVMTypeError(exec);
-    String s = thisValue.toString(exec)->value(exec);
-    unsigned len = s.length();
+    StringView string = thisValue.toString(exec)->view(exec);
     JSValue a0 = exec->argument(0);
     if (a0.isUInt32()) {
         uint32_t i = a0.asUInt32();
-        if (i < len)
-            return JSValue::encode(jsSingleCharacterSubstring(exec, s, i));
+        if (i < string.length())
+            return JSValue::encode(jsSingleCharacterString(exec, string[i]));
         return JSValue::encode(jsEmptyString(exec));
     }
     double dpos = a0.toInteger(exec);
-    if (dpos >= 0 && dpos < len)
-        return JSValue::encode(jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos)));
+    if (dpos >= 0 && dpos < string.length())
+        return JSValue::encode(jsSingleCharacterString(exec, string[static_cast<unsigned>(dpos)]));
     return JSValue::encode(jsEmptyString(exec));
 }
 
@@ -718,24 +804,56 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec)
     JSValue thisValue = exec->thisValue();
     if (!checkObjectCoercible(thisValue))
         return throwVMTypeError(exec);
-    String s = thisValue.toString(exec)->value(exec);
-    unsigned len = s.length();
+    StringView string = thisValue.toString(exec)->view(exec);
     JSValue a0 = exec->argument(0);
     if (a0.isUInt32()) {
         uint32_t i = a0.asUInt32();
-        if (i < len) {
-            if (s.is8Bit())
-                return JSValue::encode(jsNumber(s.characters8()[i]));
-            return JSValue::encode(jsNumber(s.characters16()[i]));
-        }
+        if (i < string.length())
+            return JSValue::encode(jsNumber(string[i]));
         return JSValue::encode(jsNaN());
     }
     double dpos = a0.toInteger(exec);
-    if (dpos >= 0 && dpos < len)
-        return JSValue::encode(jsNumber(s[static_cast<int>(dpos)]));
+    if (dpos >= 0 && dpos < string.length())
+        return JSValue::encode(jsNumber(string[static_cast<int>(dpos)]));
     return JSValue::encode(jsNaN());
 }
 
+static inline UChar32 codePointAt(const String& string, unsigned position, unsigned length)
+{
+    RELEASE_ASSERT(position < length);
+    if (string.is8Bit())
+        return string.characters8()[position];
+    UChar32 character;
+    U16_NEXT(string.characters16(), position, length, character);
+    return character;
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncCodePointAt(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+
+    String string = thisValue.toWTFString(exec);
+    unsigned length = string.length();
+
+    JSValue argument0 = exec->argument(0);
+    if (argument0.isUInt32()) {
+        unsigned position = argument0.asUInt32();
+        if (position < length)
+            return JSValue::encode(jsNumber(codePointAt(string, position, length)));
+        return JSValue::encode(jsUndefined());
+    }
+
+    if (UNLIKELY(exec->hadException()))
+        return JSValue::encode(jsUndefined());
+
+    double doublePosition = argument0.toInteger(exec);
+    if (doublePosition >= 0 && doublePosition < length)
+        return JSValue::encode(jsNumber(codePointAt(string, static_cast<unsigned>(doublePosition), length)));
+    return JSValue::encode(jsUndefined());
+}
+
 EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue();
@@ -778,7 +896,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
     if (thisJSString->length() < otherJSString->length() + pos)
         return JSValue::encode(jsNumber(-1));
 
-    size_t result = thisJSString->value(exec).find(otherJSString->value(exec), pos);
+    size_t result = thisJSString->view(exec).get().find(otherJSString->view(exec), pos);
     if (result == notFound)
         return JSValue::encode(jsNumber(-1));
     return JSValue::encode(jsNumber(result));
@@ -858,7 +976,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
     MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0);
     // case without 'g' flag is handled like RegExp.prototype.exec
     if (!global)
-        return JSValue::encode(result ? RegExpMatchesArray::create(exec, string, regExp, result) : jsNull());
+        return JSValue::encode(result ? createRegExpMatchesArray(exec, string, regExp, result) : jsNull());
 
     // return array of matches
     MarkedArgumentBuffer list;
@@ -940,7 +1058,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec)
 
 // Return true in case of early return (resultLength got to limitLength).
 template<typename CharacterType>
-static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength)
+static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, JSValue originalValue, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength)
 {
     // 12. Let q = p.
     size_t matchPosition;
@@ -954,7 +1072,7 @@ static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray
         //    through q (exclusive).
         // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
         //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
-        result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
+        result->putDirectIndex(exec, resultLength, jsSubstring(exec, originalValue, input, position, matchPosition - position));
         // 3. Increment lengthA by 1.
         // 4. If lengthA == lim, return A.
         if (++resultLength == limitLength)
@@ -1032,11 +1150,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
             // a. Call SplitMatch(S, q, R) and let z be its MatchResult result.
             Vector<int, 32> ovector;
             int mpos = reg->match(*vm, input, matchPosition, ovector);
-            // b. If z is failure, then let q = q + 1.
+
+            // b. If z is a failure then we can break because there are no matches
             if (mpos < 0)
                 break;
             matchPosition = mpos;
 
+            // if the match is the empty match at the end, break.
+            if (matchPosition >= input.length())
+                break;
+
             // c. Else, z is not failure
             // i. z must be a State. Let e be z's endIndex and let cap be z's captures array.
             size_t matchEnd = ovector[1];
@@ -1046,13 +1169,17 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
                 ++matchPosition;
                 continue;
             }
+            // iii. if matchEnd == 0 then position should also be zero and thus matchEnd should equal position.
+            ASSERT(matchEnd);
+
             // iii. Else, e != p
 
             // 1. Let T be a String value equal to the substring of S consisting of the characters at positions p (inclusive)
             //    through q (exclusive).
             // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
             //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
-            result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
+            result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
+
             // 3. Increment lengthA by 1.
             // 4. If lengthA == lim, return A.
             if (++resultLength == limit)
@@ -1071,7 +1198,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
                 //   ToString(lengthA), Property Descriptor {[[Value]]: cap[i], [[Writable]]:
                 //   true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
                 int sub = ovector[i * 2];
-                result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub));
+                result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, thisValue, input, sub, ovector[i * 2 + 1] - sub));
                 // c Increment lengthA by 1.
                 // d If lengthA == lim, return A.
                 if (++resultLength == limit)
@@ -1114,7 +1241,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
             ASSERT(limit);
 
             do {
-                result->putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position));
+                result->putDirectIndex(exec, position, jsSingleCharacterString(exec, input[position]));
             } while (++position < limit);
 
             return JSValue::encode(result);
@@ -1136,10 +1263,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
                 separatorCharacter = separatorImpl->characters16()[0];
 
             if (stringImpl->is8Bit()) {
-                if (splitStringByOneCharacterImpl<LChar>(exec, result, input, stringImpl, separatorCharacter, position, resultLength, limit))
+                if (splitStringByOneCharacterImpl<LChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit))
                     return JSValue::encode(result);
             } else {
-                if (splitStringByOneCharacterImpl<UChar>(exec, result, input, stringImpl, separatorCharacter, position, resultLength, limit))
+                if (splitStringByOneCharacterImpl<UChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit))
                     return JSValue::encode(result);
             }
         } else {
@@ -1154,7 +1281,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
                 //    through q (exclusive).
                 // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
                 //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
-                result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
+                result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
                 // 3. Increment lengthA by 1.
                 // 4. If lengthA == lim, return A.
                 if (++resultLength == limit)
@@ -1171,7 +1298,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
     //     through s (exclusive).
     // 15. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), Property Descriptor
     //     {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
-    result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position));
+    result->putDirectIndex(exec, resultLength++, jsSubstring(exec, thisValue, input, position, input.length() - position));
 
     // 16. Return A.
     return JSValue::encode(result);
@@ -1218,6 +1345,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec)
 {
+    SamplingRegion samplingRegion("Doing substringing");
     JSValue thisValue = exec->thisValue();
     if (!checkObjectCoercible(thisValue))
         return throwVMTypeError(exec);
@@ -1545,6 +1673,120 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec)
     JSValue thisValue = exec->thisValue();
     return JSValue::encode(trimString(exec, thisValue, TrimRight));
 }
-    
-    
+
+static inline unsigned clampAndTruncateToUnsigned(double value, unsigned min, unsigned max)
+{
+    if (value < min)
+        return min;
+    if (value > max)
+        return max;
+    return static_cast<unsigned>(value);
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncStartsWith(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+
+    String stringToSearchIn = thisValue.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    JSValue a0 = exec->argument(0);
+    if (jsDynamicCast<RegExpObject*>(a0))
+        return throwVMTypeError(exec);
+
+    String searchString = a0.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    JSValue positionArg = exec->argument(1);
+    unsigned start = 0;
+    if (positionArg.isInt32())
+        start = std::max(0, positionArg.asInt32());
+    else {
+        unsigned length = stringToSearchIn.length();
+        start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+    }
+
+    return JSValue::encode(jsBoolean(stringToSearchIn.hasInfixStartingAt(searchString, start)));
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncEndsWith(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+
+    String stringToSearchIn = thisValue.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    JSValue a0 = exec->argument(0);
+    if (jsDynamicCast<RegExpObject*>(a0))
+        return throwVMTypeError(exec);
+
+    String searchString = a0.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    unsigned length = stringToSearchIn.length();
+
+    JSValue endPositionArg = exec->argument(1);
+    unsigned end = length;
+    if (endPositionArg.isInt32())
+        end = std::max(0, endPositionArg.asInt32());
+    else if (!endPositionArg.isUndefined()) {
+        end = clampAndTruncateToUnsigned(endPositionArg.toInteger(exec), 0, length);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+    }
+
+    return JSValue::encode(jsBoolean(stringToSearchIn.hasInfixEndingAt(searchString, std::min(end, length))));
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncIncludes(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+
+    String stringToSearchIn = thisValue.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    JSValue a0 = exec->argument(0);
+    if (jsDynamicCast<RegExpObject*>(a0))
+        return throwVMTypeError(exec);
+
+    String searchString = a0.toString(exec)->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    JSValue positionArg = exec->argument(1);
+    unsigned start = 0;
+    if (positionArg.isInt32())
+        start = std::max(0, positionArg.asInt32());
+    else {
+        unsigned length = stringToSearchIn.length();
+        start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+    }
+
+    return JSValue::encode(jsBoolean(stringToSearchIn.contains(searchString, true, start)));
+}
+
+EncodedJSValue JSC_HOST_CALL stringProtoFuncIterator(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (!checkObjectCoercible(thisValue))
+        return throwVMTypeError(exec);
+    JSString* string = thisValue.toString(exec);
+    return JSValue::encode(JSStringIterator::create(exec, exec->callee()->globalObject()->stringIteratorStructure(), string));
+}
+
 } // namespace JSC
index fe22453ada6a3a2f9c4ddcae96a8977fa136e3aa..bd4f02a61e48dba57be32b08401ac7d291cd196b 100644 (file)
 
 namespace JSC {
 
-    class ObjectPrototype;
+class ObjectPrototype;
 
-    class StringPrototype : public StringObject {
-    private:
-        StringPrototype(VM&, Structure*);
+class StringPrototype : public StringObject {
+private:
+    StringPrototype(VM&, Structure*);
 
-    public:
-        typedef StringObject Base;
+public:
+    typedef StringObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
 
-        static StringPrototype* create(VM&, JSGlobalObject*, Structure*);
+    static StringPrototype* create(VM&, JSGlobalObject*, Structure*);
 
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
-        }
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
 
-        DECLARE_INFO;
-        
-    protected:
-        void finishCreation(VM&, JSGlobalObject*, JSString*);
-        static const unsigned StructureFlags = StringObject::StructureFlags;
+    DECLARE_INFO;
 
-    };
+protected:
+    void finishCreation(VM&, JSGlobalObject*, JSString*);
+};
 
 } // namespace JSC
 
index c99dd4ff13beb8bbe0c87ee719bc7a544de90d7e..0f1990e76f0f2482c9d9b034cb5131bf1bfb5b9e 100644 (file)
@@ -52,7 +52,15 @@ inline JSValue StringRecursionChecker::performCheck()
     VM& vm = m_exec->vm();
     if (!vm.isSafeToRecurse())
         return throwStackOverflowError();
-    bool alreadyVisited = !vm.stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+
+    bool alreadyVisited = false;
+    if (!vm.stringRecursionCheckFirstObject)
+        vm.stringRecursionCheckFirstObject = m_thisObject;
+    else if (vm.stringRecursionCheckFirstObject == m_thisObject)
+        alreadyVisited = true;
+    else
+        alreadyVisited = !vm.stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+
     if (alreadyVisited)
         return emptyString(); // Return empty string to avoid infinite recursion.
     return JSValue(); // Indicate success.
@@ -74,8 +82,14 @@ inline StringRecursionChecker::~StringRecursionChecker()
 {
     if (m_earlyReturnValue)
         return;
-    ASSERT(m_exec->vm().stringRecursionCheckVisitedObjects.contains(m_thisObject));
-    m_exec->vm().stringRecursionCheckVisitedObjects.remove(m_thisObject);
+
+    VM& vm = m_exec->vm();
+    if (vm.stringRecursionCheckFirstObject == m_thisObject)
+        vm.stringRecursionCheckFirstObject = nullptr;
+    else {
+        ASSERT(vm.stringRecursionCheckVisitedObjects.contains(m_thisObject));
+        vm.stringRecursionCheckVisitedObjects.remove(m_thisObject);
+    }
 }
 
 }
index 1305ecb004a49935ed652b2e10a00d8bdfbe25c1..3985805cf55c83c1da654a135c4510c750170b19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "DumpContext.h"
 #include "JSCInlines.h"
 #include "JSObject.h"
-#include "JSPropertyNameIterator.h"
+#include "JSPropertyNameEnumerator.h"
 #include "Lookup.h"
 #include "PropertyMapHashTable.h"
 #include "PropertyNameArray.h"
 #include "StructureChain.h"
 #include "StructureRareDataInlines.h"
+#include "WeakGCMapInlines.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/ProcessID.h>
 #include <wtf/RefCountedLeakCounter.h>
@@ -59,25 +60,25 @@ namespace JSC {
 static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
 #endif
 
-bool StructureTransitionTable::contains(StringImpl* rep, unsigned attributes) const
+bool StructureTransitionTable::contains(UniquedStringImpl* rep, unsigned attributes) const
 {
     if (isUsingSingleSlot()) {
         Structure* transition = singleTransition();
-        return transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes;
+        return transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes;
     }
     return map()->get(std::make_pair(rep, attributes));
 }
 
-inline Structure* StructureTransitionTable::get(StringImpl* rep, unsigned attributes) const
+Structure* StructureTransitionTable::get(UniquedStringImpl* rep, unsigned attributes) const
 {
     if (isUsingSingleSlot()) {
         Structure* transition = singleTransition();
-        return (transition && transition->m_nameInPrevious == rep && transition->m_attributesInPrevious == attributes) ? transition : 0;
+        return (transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes) ? transition : 0;
     }
     return map()->get(std::make_pair(rep, attributes));
 }
 
-inline void StructureTransitionTable::add(VM& vm, Structure* structure)
+void StructureTransitionTable::add(VM& vm, Structure* structure)
 {
     if (isUsingSingleSlot()) {
         Structure* existingTransition = singleTransition();
@@ -90,7 +91,7 @@ inline void StructureTransitionTable::add(VM& vm, Structure* structure)
 
         // This handles the second transition being added
         // (or the first transition being despecified!)
-        setMap(new TransitionMap());
+        setMap(new TransitionMap(vm));
         add(vm, existingTransition);
     }
 
@@ -99,7 +100,7 @@ inline void StructureTransitionTable::add(VM& vm, Structure* structure)
     // Newer versions of the STL have an std::make_pair function that takes rvalue references.
     // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
     // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
-    map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->m_attributesInPrevious), structure);
+    map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->attributesInPrevious()), structure);
 }
 
 void Structure::dumpStatistics()
@@ -157,28 +158,28 @@ Structure::Structure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, co
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(inlineCapacity)
-    , m_dictionaryKind(NoneDictionaryKind)
-    , m_hasBeenFlattenedBefore(false)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasCustomGetterSetterProperties(false)
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasNonEnumerableProperties(false)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(0)
-    , m_preventExtensions(false)
-    , m_didTransition(false)
-    , m_staticFunctionReified(false)
-    , m_hasRareData(false)
+    , m_bitField(0)
 {
+    setDictionaryKind(NoneDictionaryKind);
+    setIsPinnedPropertyTable(false);
+    setHasGetterSetterProperties(classInfo->hasStaticSetterOrReadonlyProperties());
+    setHasCustomGetterSetterProperties(false);
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo->hasStaticSetterOrReadonlyProperties());
+    setHasNonEnumerableProperties(false);
+    setAttributesInPrevious(0);
+    setPreventExtensions(false);
+    setDidTransition(false);
+    setStaticFunctionsReified(false);
+    setHasRareData(false);
     ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
     ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset);
-    ASSERT(!m_hasRareData);
-    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
-    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    ASSERT(!hasRareData());
+    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
+    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
 }
 
-const ClassInfo Structure::s_info = { "Structure", 0, 0, 0, CREATE_METHOD_TABLE(Structure) };
+const ClassInfo Structure::s_info = { "Structure", 0, 0, CREATE_METHOD_TABLE(Structure) };
 
 Structure::Structure(VM& vm)
     : JSCell(CreatingEarlyCell)
@@ -187,26 +188,26 @@ Structure::Structure(VM& vm)
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(0)
-    , m_dictionaryKind(NoneDictionaryKind)
-    , m_hasBeenFlattenedBefore(false)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasCustomGetterSetterProperties(false)
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties(vm))
-    , m_hasNonEnumerableProperties(false)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(0)
-    , m_preventExtensions(false)
-    , m_didTransition(false)
-    , m_staticFunctionReified(false)
-    , m_hasRareData(false)
-{
-    TypeInfo typeInfo = TypeInfo(CompoundType, OverridesVisitChildren | StructureIsImmortal);
+    , m_bitField(0)
+{
+    setDictionaryKind(NoneDictionaryKind);
+    setIsPinnedPropertyTable(false);
+    setHasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties());
+    setHasCustomGetterSetterProperties(false);
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties());
+    setHasNonEnumerableProperties(false);
+    setAttributesInPrevious(0);
+    setPreventExtensions(false);
+    setDidTransition(false);
+    setStaticFunctionsReified(false);
+    setHasRareData(false);
+    TypeInfo typeInfo = TypeInfo(CellType, StructureFlags);
     m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo);
     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
 
-    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
-    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
+    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
 }
 
 Structure::Structure(VM& vm, Structure* previous)
@@ -216,34 +217,32 @@ Structure::Structure(VM& vm, Structure* previous)
     , m_transitionWatchpointSet(IsWatched)
     , m_offset(invalidOffset)
     , m_inlineCapacity(previous->m_inlineCapacity)
-    , m_dictionaryKind(previous->m_dictionaryKind)
-    , m_hasBeenFlattenedBefore(previous->m_hasBeenFlattenedBefore)
-    , m_isPinnedPropertyTable(false)
-    , m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
-    , m_hasCustomGetterSetterProperties(previous->m_hasCustomGetterSetterProperties)
-    , m_hasReadOnlyOrGetterSetterPropertiesExcludingProto(previous->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto)
-    , m_hasNonEnumerableProperties(previous->m_hasNonEnumerableProperties)
-    , m_attributesInPrevious(0)
-    , m_specificFunctionThrashCount(previous->m_specificFunctionThrashCount)
-    , m_preventExtensions(previous->m_preventExtensions)
-    , m_didTransition(true)
-    , m_staticFunctionReified(previous->m_staticFunctionReified)
-    , m_hasRareData(false)
+    , m_bitField(0)
 {
+    setDictionaryKind(previous->dictionaryKind());
+    setIsPinnedPropertyTable(previous->hasBeenFlattenedBefore());
+    setHasGetterSetterProperties(previous->hasGetterSetterProperties());
+    setHasCustomGetterSetterProperties(previous->hasCustomGetterSetterProperties());
+    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(previous->hasReadOnlyOrGetterSetterPropertiesExcludingProto());
+    setHasNonEnumerableProperties(previous->hasNonEnumerableProperties());
+    setAttributesInPrevious(0);
+    setPreventExtensions(previous->preventExtensions());
+    setDidTransition(true);
+    setStaticFunctionsReified(previous->staticFunctionsReified());
+    setHasRareData(false);
     TypeInfo typeInfo = previous->typeInfo();
     m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingTypeIncludingHistory(), typeInfo);
     m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
 
     ASSERT(!previous->typeInfo().structureIsImmortal());
-    if (previous->m_hasRareData && previous->rareData()->needsCloning())
-        cloneRareDataFrom(vm, previous);
     setPreviousID(vm, previous);
 
-    previous->notifyTransitionFromThisStructure();
+    previous->didTransitionFromThisStructure();
     if (previous->m_globalObject)
         m_globalObject.set(vm, this, previous->m_globalObject.get());
-    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
-    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties(vm));
+    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
+    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
 }
 
 Structure::~Structure()
@@ -310,37 +309,19 @@ void Structure::materializePropertyMap(VM& vm)
         structure = structures[i];
         if (!structure->m_nameInPrevious)
             continue;
-        PropertyMapEntry entry(vm, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
+        PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious());
         propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
     }
     
     checkOffsetConsistency();
 }
 
-void Structure::despecifyDictionaryFunction(VM& vm, PropertyName propertyName)
-{
-    StringImpl* rep = propertyName.uid();
-
-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-
-    ASSERT(isDictionary());
-    ASSERT(propertyTable());
-
-    PropertyMapEntry* entry = propertyTable()->get(rep);
-    ASSERT(entry);
-    entry->specificValue.clear();
-}
-
-Structure* Structure::addPropertyTransitionToExistingStructureImpl(Structure* structure, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
+Structure* Structure::addPropertyTransitionToExistingStructureImpl(Structure* structure, UniquedStringImpl* uid, unsigned attributes, PropertyOffset& offset)
 {
     ASSERT(!structure->isDictionary());
     ASSERT(structure->isObject());
 
     if (Structure* existingTransition = structure->m_transitionTable.get(uid, attributes)) {
-        JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious.get();
-        if (specificValueInPrevious && specificValueInPrevious != specificValue)
-            return 0;
         validateOffset(existingTransition->m_offset, existingTransition->inlineCapacity());
         offset = existingTransition->m_offset;
         return existingTransition;
@@ -349,16 +330,16 @@ Structure* Structure::addPropertyTransitionToExistingStructureImpl(Structure* st
     return 0;
 }
 
-Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
+Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset& offset)
 {
     ASSERT(!isCompilationThread());
-    return addPropertyTransitionToExistingStructureImpl(structure, propertyName.uid(), attributes, specificValue, offset);
+    return addPropertyTransitionToExistingStructureImpl(structure, propertyName.uid(), attributes, offset);
 }
 
-Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
+Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, UniquedStringImpl* uid, unsigned attributes, PropertyOffset& offset)
 {
     ConcurrentJITLocker locker(structure->m_lock);
-    return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, specificValue, offset);
+    return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, offset);
 }
 
 bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const
@@ -413,25 +394,12 @@ NonPropertyTransition Structure::suggestedArrayStorageTransition() const
     return AllocateArrayStorage;
 }
 
-Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset, PutPropertySlot::Context context)
+Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset& offset, PutPropertySlot::Context context)
 {
-    // If we have a specific function, we may have got to this point if there is
-    // already a transition with the correct property name and attributes, but
-    // specialized to a different function.  In this case we just want to give up
-    // and despecialize the transition.
-    // In this case we clear the value of specificFunction which will result
-    // in us adding a non-specific transition, and any subsequent lookup in
-    // Structure::addPropertyTransitionToExistingStructure will just use that.
-    if (specificValue && structure->m_transitionTable.contains(propertyName.uid(), attributes))
-        specificValue = 0;
-
     ASSERT(!structure->isDictionary());
     ASSERT(structure->isObject());
-    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
+    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
     
-    if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
-        specificValue = 0;
-
     int maxTransitionLength;
     if (context == PutPropertySlot::PutById)
         maxTransitionLength = s_maxTransitionLengthForNonEvalPutById;
@@ -440,7 +408,7 @@ Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, Proper
     if (structure->transitionCount() > maxTransitionLength) {
         Structure* transition = toCacheableDictionaryTransition(vm, structure);
         ASSERT(structure != transition);
-        offset = transition->putSpecificValue(vm, propertyName, attributes, specificValue);
+        offset = transition->add(vm, propertyName, attributes);
         return transition;
     }
     
@@ -448,12 +416,11 @@ Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, Proper
 
     transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
     transition->m_nameInPrevious = propertyName.uid();
-    transition->m_attributesInPrevious = attributes;
-    transition->m_specificValueInPrevious.setMayBeNull(vm, transition, specificValue);
+    transition->setAttributesInPrevious(attributes);
     transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm));
     transition->m_offset = structure->m_offset;
 
-    offset = transition->putSpecificValue(vm, propertyName, attributes, specificValue);
+    offset = transition->add(vm, propertyName, attributes);
 
     checkOffset(transition->m_offset, transition->inlineCapacity());
     {
@@ -493,30 +460,6 @@ Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JS
     return transition;
 }
 
-Structure* Structure::despecifyFunctionTransition(VM& vm, Structure* structure, PropertyName replaceFunction)
-{
-    ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
-    Structure* transition = create(vm, structure);
-
-    ++transition->m_specificFunctionThrashCount;
-
-    DeferGC deferGC(vm.heap);
-    structure->materializePropertyMapIfNecessary(vm, deferGC);
-    transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm));
-    transition->m_offset = structure->m_offset;
-    transition->pin();
-
-    if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
-        transition->despecifyAllFunctions(vm);
-    else {
-        bool removed = transition->despecifyFunction(vm, replaceFunction);
-        ASSERT_UNUSED(removed, removed);
-    }
-
-    transition->checkOffsetConsistency();
-    return transition;
-}
-
 Structure* Structure::attributeChangeTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes)
 {
     DeferGC deferGC(vm.heap);
@@ -550,7 +493,7 @@ Structure* Structure::toDictionaryTransition(VM& vm, Structure* structure, Dicti
     structure->materializePropertyMapIfNecessary(vm, deferGC);
     transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm));
     transition->m_offset = structure->m_offset;
-    transition->m_dictionaryKind = kind;
+    transition->setDictionaryKind(kind);
     transition->pin();
 
     transition->checkOffsetConsistency();
@@ -591,13 +534,13 @@ Structure* Structure::freezeTransition(VM& vm, Structure* structure)
         PropertyTable::iterator iter = transition->propertyTable()->begin();
         PropertyTable::iterator end = transition->propertyTable()->end();
         if (iter != end)
-            transition->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+            transition->setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
         for (; iter != end; ++iter)
             iter->attributes |= iter->attributes & Accessor ? DontDelete : (DontDelete | ReadOnly);
     }
 
-    ASSERT(transition->hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !transition->classInfo()->hasStaticSetterOrReadonlyProperties(vm));
-    ASSERT(transition->hasGetterSetterProperties() || !transition->classInfo()->hasStaticSetterOrReadonlyProperties(vm));
+    ASSERT(transition->hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !transition->classInfo()->hasStaticSetterOrReadonlyProperties());
+    ASSERT(transition->hasGetterSetterProperties() || !transition->classInfo()->hasStaticSetterOrReadonlyProperties());
     transition->checkOffsetConsistency();
     return transition;
 }
@@ -613,7 +556,7 @@ Structure* Structure::preventExtensionsTransition(VM& vm, Structure* structure)
     structure->materializePropertyMapIfNecessary(vm, deferGC);
     transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm));
     transition->m_offset = structure->m_offset;
-    transition->m_preventExtensions = true;
+    transition->setPreventExtensions(true);
     transition->pin();
 
     transition->checkOffsetConsistency();
@@ -625,7 +568,7 @@ PropertyTable* Structure::takePropertyTableOrCloneIfPinned(VM& vm)
     DeferGC deferGC(vm.heap);
     materializePropertyMapIfNecessaryForPinning(vm, deferGC);
     
-    if (m_isPinnedPropertyTable)
+    if (isPinnedPropertyTable())
         return propertyTable()->copy(vm, propertyTable()->size() + 1);
     
     // Hold the lock while stealing the table - so that getConcurrently() on another thread
@@ -646,7 +589,7 @@ Structure* Structure::nonPropertyTransition(VM& vm, Structure* structure, NonPro
         if (globalObject->isOriginalArrayStructure(structure)) {
             Structure* result = globalObject->originalArrayStructureForIndexingType(indexingType);
             if (result->indexingTypeIncludingHistory() == indexingType) {
-                structure->notifyTransitionFromThisStructure();
+                structure->didTransitionFromThisStructure();
                 return result;
             }
         }
@@ -654,13 +597,13 @@ Structure* Structure::nonPropertyTransition(VM& vm, Structure* structure, NonPro
     
     Structure* existingTransition;
     if (!structure->isDictionary() && (existingTransition = structure->m_transitionTable.get(0, attributes))) {
-        ASSERT(existingTransition->m_attributesInPrevious == attributes);
+        ASSERT(existingTransition->attributesInPrevious() == attributes);
         ASSERT(existingTransition->indexingTypeIncludingHistory() == indexingType);
         return existingTransition;
     }
     
     Structure* transition = create(vm, structure);
-    transition->m_attributesInPrevious = attributes;
+    transition->setAttributesInPrevious(attributes);
     transition->m_blob.setIndexingType(indexingType);
     transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm));
     transition->m_offset = structure->m_offset;
@@ -747,8 +690,8 @@ Structure* Structure::flattenDictionaryStructure(VM& vm, JSObject* object)
         checkOffsetConsistency();
     }
 
-    m_dictionaryKind = NoneDictionaryKind;
-    m_hasBeenFlattenedBefore = true;
+    setDictionaryKind(NoneDictionaryKind);
+    setHasBeenFlattenedBefore(true);
 
     size_t afterOutOfLineCapacity = this->outOfLineCapacity();
 
@@ -768,25 +711,19 @@ Structure* Structure::flattenDictionaryStructure(VM& vm, JSObject* object)
     return this;
 }
 
-PropertyOffset Structure::addPropertyWithoutTransition(VM& vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::addPropertyWithoutTransition(VM& vm, PropertyName propertyName, unsigned attributes)
 {
-    ASSERT(!enumerationCache());
-
-    if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
-        specificValue = 0;
-
     DeferGC deferGC(vm.heap);
     materializePropertyMapIfNecessaryForPinning(vm, deferGC);
     
     pin();
 
-    return putSpecificValue(vm, propertyName, attributes, specificValue);
+    return add(vm, propertyName, attributes);
 }
 
 PropertyOffset Structure::removePropertyWithoutTransition(VM& vm, PropertyName propertyName)
 {
     ASSERT(isUncacheableDictionary());
-    ASSERT(!enumerationCache());
 
     DeferGC deferGC(vm.heap);
     materializePropertyMapIfNecessaryForPinning(vm, deferGC);
@@ -798,28 +735,64 @@ PropertyOffset Structure::removePropertyWithoutTransition(VM& vm, PropertyName p
 void Structure::pin()
 {
     ASSERT(propertyTable());
-    m_isPinnedPropertyTable = true;
+    setIsPinnedPropertyTable(true);
     clearPreviousID();
-    m_nameInPrevious.clear();
+    m_nameInPrevious = nullptr;
 }
 
 void Structure::allocateRareData(VM& vm)
 {
-    ASSERT(!m_hasRareData);
+    ASSERT(!hasRareData());
     StructureRareData* rareData = StructureRareData::create(vm, previous());
+    WTF::storeStoreFence();
     m_previousOrRareData.set(vm, this, rareData);
-    m_hasRareData = true;
-    ASSERT(m_hasRareData);
+    WTF::storeStoreFence();
+    setHasRareData(true);
+    ASSERT(hasRareData());
+}
+
+WatchpointSet* Structure::ensurePropertyReplacementWatchpointSet(VM& vm, PropertyOffset offset)
+{
+    ASSERT(!isUncacheableDictionary());
+    
+    if (!hasRareData())
+        allocateRareData(vm);
+    ConcurrentJITLocker locker(m_lock);
+    StructureRareData* rareData = this->rareData();
+    if (!rareData->m_replacementWatchpointSets) {
+        rareData->m_replacementWatchpointSets =
+            std::make_unique<StructureRareData::PropertyWatchpointMap>();
+        WTF::storeStoreFence();
+    }
+    auto result = rareData->m_replacementWatchpointSets->add(offset, nullptr);
+    if (result.isNewEntry)
+        result.iterator->value = adoptRef(new WatchpointSet(IsWatched));
+    return result.iterator->value.get();
+}
+
+void Structure::startWatchingPropertyForReplacements(VM& vm, PropertyName propertyName)
+{
+    ASSERT(!isUncacheableDictionary());
+    
+    PropertyOffset offset = get(vm, propertyName);
+    if (!JSC::isValidOffset(offset))
+        return;
+    
+    startWatchingPropertyForReplacements(vm, offset);
 }
 
-void Structure::cloneRareDataFrom(VM& vm, const Structure* other)
+void Structure::didCachePropertyReplacement(VM& vm, PropertyOffset offset)
 {
-    ASSERT(!m_hasRareData);
-    ASSERT(other->m_hasRareData);
-    StructureRareData* newRareData = StructureRareData::clone(vm, other->rareData());
-    m_previousOrRareData.set(vm, this, newRareData);
-    m_hasRareData = true;
-    ASSERT(m_hasRareData);
+    ensurePropertyReplacementWatchpointSet(vm, offset)->fireAll("Did cache property replacement");
+}
+
+void Structure::startWatchingInternalProperties(VM& vm)
+{
+    if (!isUncacheableDictionary()) {
+        startWatchingPropertyForReplacements(vm, vm.propertyNames->toString);
+        startWatchingPropertyForReplacements(vm, vm.propertyNames->valueOf);
+    }
+    setDidWatchInternalProperties(true);
 }
 
 #if DUMP_PROPERTYMAP_STATS
@@ -855,15 +828,6 @@ PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
 
 #endif
 
-#if !DO_PROPERTYMAP_CONSTENCY_CHECK
-
-inline void Structure::checkConsistency()
-{
-    checkOffsetConsistency();
-}
-
-#endif
-
 PropertyTable* Structure::copyPropertyTable(VM& vm)
 {
     if (!propertyTable())
@@ -878,68 +842,37 @@ PropertyTable* Structure::copyPropertyTableForPinning(VM& vm)
     return PropertyTable::create(vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
 }
 
-PropertyOffset Structure::getConcurrently(VM&, StringImpl* uid, unsigned& attributes, JSCell*& specificValue)
+PropertyOffset Structure::getConcurrently(UniquedStringImpl* uid, unsigned& attributes)
 {
-    Vector<Structure*, 8> structures;
-    Structure* structure;
-    PropertyTable* table;
-    
-    findStructuresAndMapForMaterialization(structures, structure, table);
-    
-    if (table) {
-        PropertyMapEntry* entry = table->get(uid);
-        if (entry) {
-            attributes = entry->attributes;
-            specificValue = entry->specificValue.get();
-            PropertyOffset result = entry->offset;
-            structure->m_lock.unlock();
-            return result;
-        }
-        structure->m_lock.unlock();
-    }
+    PropertyOffset result = invalidOffset;
     
-    for (unsigned i = structures.size(); i--;) {
-        structure = structures[i];
-        if (structure->m_nameInPrevious.get() != uid)
-            continue;
-        
-        attributes = structure->m_attributesInPrevious;
-        specificValue = structure->m_specificValueInPrevious.get();
-        return structure->m_offset;
-    }
+    forEachPropertyConcurrently(
+        [&] (const PropertyMapEntry& candidate) -> bool {
+            if (candidate.key != uid)
+                return true;
+            
+            result = candidate.offset;
+            attributes = candidate.attributes;
+            return false;
+        });
     
-    return invalidOffset;
-}
-
-bool Structure::despecifyFunction(VM& vm, PropertyName propertyName)
-{
-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-    if (!propertyTable())
-        return false;
-
-    PropertyMapEntry* entry = propertyTable()->get(propertyName.uid());
-    if (!entry)
-        return false;
-
-    ASSERT(entry->specificValue);
-    entry->specificValue.clear();
-    return true;
+    return result;
 }
 
-void Structure::despecifyAllFunctions(VM& vm)
+Vector<PropertyMapEntry> Structure::getPropertiesConcurrently()
 {
-    DeferGC deferGC(vm.heap);
-    materializePropertyMapIfNecessary(vm, deferGC);
-    if (!propertyTable())
-        return;
+    Vector<PropertyMapEntry> result;
 
-    PropertyTable::iterator end = propertyTable()->end();
-    for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter)
-        iter->specificValue.clear();
+    forEachPropertyConcurrently(
+        [&] (const PropertyMapEntry& entry) -> bool {
+            result.append(entry);
+            return true;
+        });
+    
+    return result;
 }
 
-PropertyOffset Structure::putSpecificValue(VM& vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::add(VM& vm, PropertyName propertyName, unsigned attributes)
 {
     GCSafeConcurrentJITLocker locker(m_lock, vm.heap);
     
@@ -947,16 +880,16 @@ PropertyOffset Structure::putSpecificValue(VM& vm, PropertyName propertyName, un
 
     checkConsistency();
     if (attributes & DontEnum)
-        m_hasNonEnumerableProperties = true;
+        setHasNonEnumerableProperties(true);
 
-    StringImpl* rep = propertyName.uid();
+    auto rep = propertyName.uid();
 
     if (!propertyTable())
         createPropertyMap(locker, vm);
 
     PropertyOffset newOffset = propertyTable()->nextOffset(m_inlineCapacity);
 
-    propertyTable()->add(PropertyMapEntry(vm, propertyTable().get(), rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange);
+    propertyTable()->add(PropertyMapEntry(rep, newOffset, attributes), m_offset, PropertyTable::PropertyOffsetMayChange);
     
     checkConsistency();
     return newOffset;
@@ -968,7 +901,7 @@ PropertyOffset Structure::remove(PropertyName propertyName)
     
     checkConsistency();
 
-    StringImpl* rep = propertyName.uid();
+    auto rep = propertyName.uid();
 
     if (!propertyTable())
         return invalidOffset;
@@ -1001,12 +934,14 @@ void Structure::getPropertyNamesFromStructure(VM& vm, PropertyNameArray& propert
     if (!propertyTable())
         return;
 
-    bool knownUnique = !propertyNames.size();
+    bool knownUnique = propertyNames.canAddKnownUniqueForStructure();
 
     PropertyTable::iterator end = propertyTable()->end();
     for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
-        ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum));
-        if (!iter->key->isEmptyUnique() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {
+        ASSERT(hasNonEnumerableProperties() || !(iter->attributes & DontEnum));
+        if (!(iter->attributes & DontEnum) || mode.includeDontEnumProperties()) {
+            if (iter->key->isSymbol() && !mode.includeSymbolProperties())
+                continue;
             if (knownUnique)
                 propertyNames.addKnownUnique(iter->key);
             else
@@ -1015,6 +950,31 @@ void Structure::getPropertyNamesFromStructure(VM& vm, PropertyNameArray& propert
     }
 }
 
+namespace {
+
+class StructureFireDetail : public FireDetail {
+public:
+    StructureFireDetail(const Structure* structure)
+        : m_structure(structure)
+    {
+    }
+    
+    virtual void dump(PrintStream& out) const override
+    {
+        out.print("Structure transition from ", *m_structure);
+    }
+
+private:
+    const Structure* m_structure;
+};
+
+} // anonymous namespace
+
+void Structure::didTransitionFromThisStructure() const
+{
+    m_transitionWatchpointSet.fireAll(StructureFireDetail(this));
+}
+
 JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const
 {
     return prototypeForLookup(codeBlock->globalObject());
@@ -1024,7 +984,6 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     Structure* thisObject = jsCast<Structure*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
 
     JSCell::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_globalObject);
@@ -1035,9 +994,8 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
         visitor.append(&thisObject->m_cachedPrototypeChain);
     }
     visitor.append(&thisObject->m_previousOrRareData);
-    visitor.append(&thisObject->m_specificValueInPrevious);
 
-    if (thisObject->m_isPinnedPropertyTable) {
+    if (thisObject->isPinnedPropertyTable()) {
         ASSERT(thisObject->m_propertyTableUnsafe);
         visitor.append(&thisObject->m_propertyTableUnsafe);
     } else if (thisObject->m_propertyTableUnsafe)
@@ -1046,8 +1004,7 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
 bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyName)
 {
-    unsigned i = propertyName.asIndex();
-    if (i != PropertyName::NotAnIndex)
+    if (parseIndex(propertyName))
         return anyObjectInChainMayInterceptIndexedAccesses();
     
     for (Structure* current = this; ;) {
@@ -1058,8 +1015,7 @@ bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyN
         current = prototype.asCell()->structure(vm);
         
         unsigned attributes;
-        JSCell* specificValue;
-        PropertyOffset offset = current->get(vm, propertyName, attributes, specificValue);
+        PropertyOffset offset = current->get(vm, propertyName, attributes);
         if (!JSC::isValidOffset(offset))
             continue;
         
@@ -1070,43 +1026,73 @@ bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyN
     }
 }
 
+PassRefPtr<StructureShape> Structure::toStructureShape(JSValue value)
+{
+    RefPtr<StructureShape> baseShape = StructureShape::create();
+    RefPtr<StructureShape> curShape = baseShape;
+    Structure* curStructure = this;
+    JSValue curValue = value;
+    while (curStructure) {
+        Vector<Structure*, 8> structures;
+        Structure* structure;
+        PropertyTable* table;
+
+        curStructure->findStructuresAndMapForMaterialization(structures, structure, table);
+        if (table) {
+            PropertyTable::iterator iter = table->begin();
+            PropertyTable::iterator end = table->end();
+            for (; iter != end; ++iter)
+                curShape->addProperty(*iter->key);
+            
+            structure->m_lock.unlock();
+        }
+        for (unsigned i = structures.size(); i--;) {
+            Structure* structure = structures[i];
+            if (structure->m_nameInPrevious)
+                curShape->addProperty(*structure->m_nameInPrevious);
+        }
+
+        if (JSObject* curObject = curValue.getObject())
+            curShape->setConstructorName(JSObject::calculatedClassName(curObject));
+        else
+            curShape->setConstructorName(curStructure->classInfo()->className);
+
+        if (curStructure->isDictionary())
+            curShape->enterDictionaryMode();
+
+        curShape->markAsFinal();
+
+        if (curStructure->storedPrototypeStructure()) {
+            RefPtr<StructureShape> newShape = StructureShape::create();
+            curShape->setProto(newShape);
+            curShape = newShape.release();
+            curValue = curStructure->storedPrototype();
+        }
+
+        curStructure = curStructure->storedPrototypeStructure();
+    }
+    
+    return baseShape.release();
+}
+
+bool Structure::canUseForAllocationsOf(Structure* other)
+{
+    return inlineCapacity() == other->inlineCapacity()
+        && storedPrototype() == other->storedPrototype()
+        && objectInitializationBlob() == other->objectInitializationBlob();
+}
+
 void Structure::dump(PrintStream& out) const
 {
     out.print(RawPointer(this), ":[", classInfo()->className, ", {");
     
-    Vector<Structure*, 8> structures;
-    Structure* structure;
-    PropertyTable* table;
-    
-    const_cast<Structure*>(this)->findStructuresAndMapForMaterialization(
-        structures, structure, table);
-    
     CommaPrinter comma;
     
-    if (table) {
-        PropertyTable::iterator iter = table->begin();
-        PropertyTable::iterator end = table->end();
-        for (; iter != end; ++iter) {
-            out.print(comma, iter->key, ":", static_cast<int>(iter->offset));
-            if (iter->specificValue) {
-                DumpContext dummyContext;
-                out.print("=>", RawPointer(iter->specificValue.get()));
-            }
-        }
-        
-        structure->m_lock.unlock();
-    }
-    
-    for (unsigned i = structures.size(); i--;) {
-        Structure* structure = structures[i];
-        if (!structure->m_nameInPrevious)
-            continue;
-        out.print(comma, structure->m_nameInPrevious.get(), ":", static_cast<int>(structure->m_offset));
-        if (structure->m_specificValueInPrevious) {
-            DumpContext dummyContext;
-            out.print("=>", RawPointer(structure->m_specificValueInPrevious.get()));
-        }
-    }
+    const_cast<Structure*>(this)->forEachPropertyConcurrently(
+        [&] (const PropertyMapEntry& entry) -> bool {
+            out.print(comma, entry.key, ":", static_cast<int>(entry.offset));
+            return true;
+        });
     
     out.print("}, ", IndexingTypeDump(indexingType()));
     
@@ -1138,7 +1124,6 @@ void Structure::dumpContextHeader(PrintStream& out)
 
 void PropertyTable::checkConsistency()
 {
-    checkOffsetConsistency();
     ASSERT(m_indexSize >= PropertyTable::MinimumTableSize);
     ASSERT(m_indexMask);
     ASSERT(m_indexSize == m_indexMask + 1);
@@ -1176,7 +1161,7 @@ void PropertyTable::checkConsistency()
         if (rep == PROPERTY_MAP_DELETED_ENTRY_KEY)
             continue;
         ++nonEmptyEntryCount;
-        unsigned i = rep->existingHash();
+        unsigned i = IdentifierRepHash::hash(rep);
         unsigned k = 0;
         unsigned entryIndex;
         while (1) {
@@ -1185,7 +1170,7 @@ void PropertyTable::checkConsistency()
             if (rep == table()[entryIndex - 1].key)
                 break;
             if (k == 0)
-                k = 1 | doubleHash(rep->existingHash());
+                k = 1 | doubleHash(IdentifierRepHash::hash(rep));
             i += k;
         }
         ASSERT(entryIndex == c + 1);
@@ -1196,10 +1181,12 @@ void PropertyTable::checkConsistency()
 
 void Structure::checkConsistency()
 {
+    checkOffsetConsistency();
+
     if (!propertyTable())
         return;
 
-    if (!m_hasNonEnumerableProperties) {
+    if (!hasNonEnumerableProperties()) {
         PropertyTable::iterator end = propertyTable()->end();
         for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
             ASSERT(!(iter->attributes & DontEnum));
@@ -1209,12 +1196,19 @@ void Structure::checkConsistency()
     propertyTable()->checkConsistency();
 }
 
+#else
+
+inline void Structure::checkConsistency()
+{
+    checkOffsetConsistency();
+}
+
 #endif // DO_PROPERTYMAP_CONSTENCY_CHECK
 
-bool ClassInfo::hasStaticSetterOrReadonlyProperties(VM& vm) const
+bool ClassInfo::hasStaticSetterOrReadonlyProperties() const
 {
     for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
-        if (const HashTable* table = ci->propHashTable(vm)) {
+        if (const HashTable* table = ci->staticPropHashTable) {
             if (table->hasSetterOrReadonlyProperties)
                 return true;
         }
@@ -1222,4 +1216,55 @@ bool ClassInfo::hasStaticSetterOrReadonlyProperties(VM& vm) const
     return false;
 }
 
+void Structure::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
+{
+    ASSERT(!isDictionary());
+    if (!hasRareData())
+        allocateRareData(vm);
+    rareData()->setCachedPropertyNameEnumerator(vm, enumerator);
+}
+
+JSPropertyNameEnumerator* Structure::cachedPropertyNameEnumerator() const
+{
+    if (!hasRareData())
+        return nullptr;
+    return rareData()->cachedPropertyNameEnumerator();
+}
+
+bool Structure::canCachePropertyNameEnumerator() const
+{
+    if (isDictionary())
+        return false;
+
+    if (hasIndexedProperties(indexingType()))
+        return false;
+
+    if (typeInfo().overridesGetPropertyNames())
+        return false;
+
+    StructureChain* structureChain = m_cachedPrototypeChain.get();
+    ASSERT(structureChain);
+    WriteBarrier<Structure>* structure = structureChain->head();
+    while (true) {
+        if (!structure->get())
+            break;
+        if (structure->get()->typeInfo().overridesGetPropertyNames())
+            return false;
+        structure++;
+    }
+    
+    return true;
+}
+    
+bool Structure::canAccessPropertiesQuickly() const
+{
+    if (hasNonEnumerableProperties())
+        return false;
+    if (hasGetterSetterProperties())
+        return false;
+    if (isUncacheableDictionary())
+        return false;
+    return true;
+}
+
 } // namespace JSC
index e9d04e49d564300709c644cd28e25a3612cc97b5..25a97fedd341a96abcb66d930b88887d93954f0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <wtf/PassRefPtr.h>
 #include <wtf/PrintStream.h>
 #include <wtf/RefCounted.h>
-#include <wtf/text/StringImpl.h>
 
+namespace WTF {
+
+class UniquedStringImpl;
+
+} // namespace WTF
 
 namespace JSC {
 
@@ -59,6 +63,7 @@ class PropertyNameArray;
 class PropertyNameArrayData;
 class PropertyTable;
 class StructureChain;
+class StructureShape;
 class SlotVisitor;
 class JSString;
 struct DumpContext;
@@ -72,11 +77,32 @@ static const unsigned initialOutOfLineCapacity = 4;
 // initial allocation.
 static const unsigned outOfLineGrowthFactor = 2;
 
-class Structure : public JSCell {
+struct PropertyMapEntry {
+    UniquedStringImpl* key;
+    PropertyOffset offset;
+    unsigned attributes;
+
+    PropertyMapEntry()
+        : key(nullptr)
+        , offset(invalidOffset)
+        , attributes(0)
+    {
+    }
+    
+    PropertyMapEntry(UniquedStringImpl* key, PropertyOffset offset, unsigned attributes)
+        : key(key)
+        , offset(offset)
+        , attributes(attributes)
+    {
+    }
+};
+
+class Structure final : public JSCell {
 public:
     friend class StructureTransitionTable;
 
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     
     static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
 
@@ -111,44 +137,39 @@ public:
 
     static void dumpStatistics();
 
-    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
-    static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&);
-    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, PropertyOffset&, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
+    static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
+    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, PropertyOffset&);
     static Structure* removePropertyTransition(VM&, Structure*, PropertyName, PropertyOffset&);
     JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype);
-    JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(VM&, Structure*, PropertyName);
-    static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
+    JS_EXPORT_PRIVATE static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
     JS_EXPORT_PRIVATE static Structure* toCacheableDictionaryTransition(VM&, Structure*);
     static Structure* toUncacheableDictionaryTransition(VM&, Structure*);
-    static Structure* sealTransition(VM&, Structure*);
-    static Structure* freezeTransition(VM&, Structure*);
+    JS_EXPORT_PRIVATE static Structure* sealTransition(VM&, Structure*);
+    JS_EXPORT_PRIVATE static Structure* freezeTransition(VM&, Structure*);
     static Structure* preventExtensionsTransition(VM&, Structure*);
-    static Structure* nonPropertyTransition(VM&, Structure*, NonPropertyTransition);
+    JS_EXPORT_PRIVATE static Structure* nonPropertyTransition(VM&, Structure*, NonPropertyTransition);
 
-    bool isSealed(VM&);
-    bool isFrozen(VM&);
-    bool isExtensible() const { return !m_preventExtensions; }
-    bool didTransition() const { return m_didTransition; }
+    JS_EXPORT_PRIVATE bool isSealed(VM&);
+    JS_EXPORT_PRIVATE bool isFrozen(VM&);
+    bool isExtensible() const { return !preventExtensions(); }
     bool putWillGrowOutOfLineStorage();
     size_t suggestedNewOutOfLineStorageCapacity(); 
 
     JS_EXPORT_PRIVATE Structure* flattenDictionaryStructure(VM&, JSObject*);
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     // These should be used with caution.  
-    JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
+    JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&, PropertyName, unsigned attributes);
     PropertyOffset removePropertyWithoutTransition(VM&, PropertyName);
     void setPrototypeWithoutTransition(VM& vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
         
-    bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
-    bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
-
-    bool hasBeenFlattenedBefore() const { return m_hasBeenFlattenedBefore; }
-
-    bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
+    bool isDictionary() const { return dictionaryKind() != NoneDictionaryKind; }
+    bool isUncacheableDictionary() const { return dictionaryKind() == UncachedDictionaryKind; }
+  
+    bool propertyAccessesAreCacheable() { return dictionaryKind() != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
 
     // We use SlowPath in GetByIdStatus for structures that may get new impure properties later to prevent
     // DFG from inlining property accesses since structures don't transition when a new impure property appears.
@@ -191,12 +212,10 @@ public:
     // Will just the prototype chain intercept this property access?
     bool prototypeChainMayInterceptStoreTo(VM&, PropertyName);
         
-    bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
-        
     Structure* previousID() const
     {
         ASSERT(structure()->classInfo() == info());
-        if (m_hasRareData)
+        if (hasRareData())
             return rareData()->previousID();
         return previous();
     }
@@ -265,73 +284,63 @@ public:
     bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
 
     PropertyOffset get(VM&, PropertyName);
-    PropertyOffset get(VM&, const WTF::String& name);
-    PropertyOffset get(VM&, PropertyName, unsigned& attributes, JSCell*& specificValue);
-
-    PropertyOffset getConcurrently(VM&, StringImpl* uid);
-    PropertyOffset getConcurrently(VM&, StringImpl* uid, unsigned& attributes, JSCell*& specificValue);
-
-    bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
-    bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
-    void setHasGetterSetterProperties(bool is__proto__)
+    PropertyOffset get(VM&, PropertyName, unsigned& attributes);
+
+    // This is a somewhat internalish method. It will call your functor while possibly holding the
+    // Structure's lock. There is no guarantee whether the lock is held or not in any particular
+    // call. So, you have to assume the worst. Also, the functor returns true if it wishes for you
+    // to continue or false if it's done.
+    template<typename Functor>
+    void forEachPropertyConcurrently(const Functor&);
+    
+    PropertyOffset getConcurrently(UniquedStringImpl* uid);
+    PropertyOffset getConcurrently(UniquedStringImpl* uid, unsigned& attributes);
+    
+    Vector<PropertyMapEntry> getPropertiesConcurrently();
+    
+    void setHasGetterSetterPropertiesWithProtoCheck(bool is__proto__)
     {
-        m_hasGetterSetterProperties = true;
+        setHasGetterSetterProperties(true);
         if (!is__proto__)
-            m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+            setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
     }
-
-    bool hasCustomGetterSetterProperties() const { return m_hasCustomGetterSetterProperties; }
-    void setHasCustomGetterSetterProperties(bool is__proto__)
+    
+    void setContainsReadOnlyProperties() { setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true); }
+    
+    void setHasCustomGetterSetterPropertiesWithProtoCheck(bool is__proto__)
     {
-        m_hasCustomGetterSetterProperties = true;
+        setHasCustomGetterSetterProperties(true);
         if (!is__proto__)
-            m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+            setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
     }
-
-    void setContainsReadOnlyProperties()
-    {
-        m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
-    }
-
-    bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
-        
+    
     bool isEmpty() const
     {
         ASSERT(checkOffsetConsistency());
         return !JSC::isValidOffset(m_offset);
     }
 
-    JS_EXPORT_PRIVATE void despecifyDictionaryFunction(VM&, PropertyName);
-    void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
+    void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
+    JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
+    bool canCachePropertyNameEnumerator() const;
+    bool canAccessPropertiesQuickly() const;
 
-    void setEnumerationCache(VM&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
-    JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
     void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode);
 
     JSString* objectToStringValue()
     {
-        if (!m_hasRareData)
+        if (!hasRareData())
             return 0;
         return rareData()->objectToStringValue();
     }
 
     void setObjectToStringValue(VM& vm, JSString* value)
     {
-        if (!m_hasRareData)
+        if (!hasRareData())
             allocateRareData(vm);
         rareData()->setObjectToStringValue(vm, value);
     }
 
-    bool staticFunctionsReified()
-    {
-        return m_staticFunctionReified;
-    }
-
-    void setStaticFunctionsReified()
-    {
-        m_staticFunctionReified = true;
-    }
-
     const ClassInfo* classInfo() const { return m_classInfo; }
 
     static ptrdiff_t structureIDOffset()
@@ -370,23 +379,65 @@ public:
     {
         return m_transitionWatchpointSet.isStillValid();
     }
+    
+    bool dfgShouldWatchIfPossible() const
+    {
+        // FIXME: We would like to not watch things that are unprofitable to watch, like
+        // dictionaries. Unfortunately, we can't do such things: a dictionary could get flattened,
+        // in which case it will start to appear watchable and so the DFG will think that it is
+        // watching it. We should come up with a comprehensive story for not watching things that
+        // aren't profitable to watch.
+        // https://bugs.webkit.org/show_bug.cgi?id=133625
+        return true;
+    }
+    
+    bool dfgShouldWatch() const
+    {
+        return dfgShouldWatchIfPossible() && transitionWatchpointSetIsStillValid();
+    }
         
     void addTransitionWatchpoint(Watchpoint* watchpoint) const
     {
         ASSERT(transitionWatchpointSetIsStillValid());
         m_transitionWatchpointSet.add(watchpoint);
     }
-        
-    void notifyTransitionFromThisStructure() const
-    {
-        m_transitionWatchpointSet.fireAll();
-    }
+    
+    void didTransitionFromThisStructure() const;
     
     InlineWatchpointSet& transitionWatchpointSet() const
     {
         return m_transitionWatchpointSet;
     }
     
+    WatchpointSet* ensurePropertyReplacementWatchpointSet(VM&, PropertyOffset);
+    void startWatchingPropertyForReplacements(VM& vm, PropertyOffset offset)
+    {
+        ensurePropertyReplacementWatchpointSet(vm, offset);
+    }
+    void startWatchingPropertyForReplacements(VM&, PropertyName);
+    WatchpointSet* propertyReplacementWatchpointSet(PropertyOffset);
+    void didReplaceProperty(PropertyOffset);
+    void didCachePropertyReplacement(VM&, PropertyOffset);
+    
+    void startWatchingInternalPropertiesIfNecessary(VM& vm)
+    {
+        if (LIKELY(didWatchInternalProperties()))
+            return;
+        startWatchingInternalProperties(vm);
+    }
+    
+    void startWatchingInternalPropertiesIfNecessaryForEntireChain(VM& vm)
+    {
+        for (Structure* structure = this; structure; structure = structure->storedPrototypeStructure())
+            structure->startWatchingInternalPropertiesIfNecessary(vm);
+    }
+
+    PassRefPtr<StructureShape> toStructureShape(JSValue);
+    
+    // Determines if the two structures match enough that this one could be used for allocations
+    // of the other one.
+    bool canUseForAllocationsOf(Structure*);
+    
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dumpBrief(PrintStream&, const CString&) const;
@@ -395,6 +446,38 @@ public:
     
     DECLARE_EXPORT_INFO;
 
+private:
+    typedef enum { 
+        NoneDictionaryKind = 0,
+        CachedDictionaryKind = 1,
+        UncachedDictionaryKind = 2
+    } DictionaryKind;
+
+public:
+#define DEFINE_BITFIELD(type, lowerName, upperName, width, offset) \
+    static const uint32_t s_##lowerName##Shift = offset;\
+    static const uint32_t s_##lowerName##Mask = ((1 << (width - 1)) | ((1 << (width - 1)) - 1));\
+    type lowerName() const { return static_cast<type>((m_bitField >> offset) & s_##lowerName##Mask); }\
+    void set##upperName(type newValue) \
+    {\
+        m_bitField &= ~(s_##lowerName##Mask << offset);\
+        m_bitField |= (newValue & s_##lowerName##Mask) << offset;\
+    }
+
+    DEFINE_BITFIELD(DictionaryKind, dictionaryKind, DictionaryKind, 2, 0);
+    DEFINE_BITFIELD(bool, isPinnedPropertyTable, IsPinnedPropertyTable, 1, 2);
+    DEFINE_BITFIELD(bool, hasGetterSetterProperties, HasGetterSetterProperties, 1, 3);
+    DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
+    DEFINE_BITFIELD(bool, hasNonEnumerableProperties, HasNonEnumerableProperties, 1, 5);
+    DEFINE_BITFIELD(unsigned, attributesInPrevious, AttributesInPrevious, 14, 6);
+    DEFINE_BITFIELD(bool, preventExtensions, PreventExtensions, 1, 20);
+    DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21);
+    DEFINE_BITFIELD(bool, staticFunctionsReified, StaticFunctionsReified, 1, 22);
+    DEFINE_BITFIELD(bool, hasRareData, HasRareData, 1, 23);
+    DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 24);
+    DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 25);
+    DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 26);
+
 private:
     friend class LLIntOffsetsExtractor;
 
@@ -404,7 +487,7 @@ private:
 
     static Structure* create(VM&, Structure*);
     
-    static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+    static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
 
     // This will return the structure that has a usable property table, that property table,
     // and the list of structures that we visited before we got to it. If it returns a
@@ -412,22 +495,14 @@ private:
     // to unlock it.
     void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
     
-    typedef enum { 
-        NoneDictionaryKind = 0,
-        CachedDictionaryKind = 1,
-        UncachedDictionaryKind = 2
-    } DictionaryKind;
     static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind);
 
-    PropertyOffset putSpecificValue(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
+    PropertyOffset add(VM&, PropertyName, unsigned attributes);
     PropertyOffset remove(PropertyName);
 
     void createPropertyMap(const GCSafeConcurrentJITLocker&, VM&, unsigned keyCount = 0);
     void checkConsistency();
 
-    bool despecifyFunction(VM&, PropertyName);
-    void despecifyAllFunctions(VM&);
-
     WriteBarrier<PropertyTable>& propertyTable();
     PropertyTable* takePropertyTableOrCloneIfPinned(VM&);
     PropertyTable* copyPropertyTable(VM&);
@@ -463,7 +538,7 @@ private:
 
     void setPreviousID(VM& vm, Structure* structure)
     {
-        if (m_hasRareData)
+        if (hasRareData())
             rareData()->setPreviousID(vm, structure);
         else
             m_previousOrRareData.set(vm, this, structure);
@@ -471,7 +546,7 @@ private:
 
     void clearPreviousID()
     {
-        if (m_hasRareData)
+        if (hasRareData())
             rareData()->clearPreviousID();
         else
             m_previousOrRareData.clear();
@@ -490,26 +565,25 @@ private:
 
     Structure* previous() const
     {
-        ASSERT(!m_hasRareData);
+        ASSERT(!hasRareData());
         return static_cast<Structure*>(m_previousOrRareData.get());
     }
 
     StructureRareData* rareData() const
     {
-        ASSERT(m_hasRareData);
+        ASSERT(hasRareData());
         return static_cast<StructureRareData*>(m_previousOrRareData.get());
     }
         
     bool checkOffsetConsistency() const;
 
-    void allocateRareData(VM&);
-    void cloneRareDataFrom(VM&, const Structure*);
+    JS_EXPORT_PRIVATE void allocateRareData(VM&);
+    
+    void startWatchingInternalProperties(VM&);
 
     static const int s_maxTransitionLength = 64;
     static const int s_maxTransitionLengthForNonEvalPutById = 512;
 
-    static const unsigned maxSpecificFunctionThrashCount = 3;
-    
     // These need to be properly aligned at the beginning of the 'Structure'
     // part of the object.
     StructureIDBlob m_blob;
@@ -521,8 +595,7 @@ private:
 
     WriteBarrier<JSCell> m_previousOrRareData;
 
-    RefPtr<StringImpl> m_nameInPrevious;
-    WriteBarrier<JSCell> m_specificValueInPrevious;
+    RefPtr<UniquedStringImpl> m_nameInPrevious;
 
     const ClassInfo* m_classInfo;
 
@@ -542,19 +615,7 @@ private:
     
     ConcurrentJITLock m_lock;
     
-    unsigned m_dictionaryKind : 2;
-    bool m_hasBeenFlattenedBefore : 1;
-    bool m_isPinnedPropertyTable : 1;
-    bool m_hasGetterSetterProperties : 1;
-    bool m_hasCustomGetterSetterProperties : 1;
-    bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
-    bool m_hasNonEnumerableProperties : 1;
-    unsigned m_attributesInPrevious : 14;
-    unsigned m_specificFunctionThrashCount : 2;
-    unsigned m_preventExtensions : 1;
-    unsigned m_didTransition : 1;
-    unsigned m_staticFunctionReified : 1;
-    bool m_hasRareData : 1;
+    uint32_t m_bitField;
 };
 
 } // namespace JSC
index dc4283950e9f452b250fbd8afdc1ddb1eeeee567..9a8568b6914b84ab3c50e3f283dfac483e6d6840 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace JSC {
     
-const ClassInfo StructureChain::s_info = { "StructureChain", 0, 0, 0, CREATE_METHOD_TABLE(StructureChain) };
+const ClassInfo StructureChain::s_info = { "StructureChain", 0, 0, CREATE_METHOD_TABLE(StructureChain) };
 
 StructureChain::StructureChain(VM& vm, Structure* structure)
     : JSCell(vm, structure)
@@ -49,7 +49,6 @@ void StructureChain::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     StructureChain* thisObject = jsCast<StructureChain*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     size_t i = 0;
     while (thisObject->m_vector[i])
         visitor.append(&thisObject->m_vector[i++]);
index 26bda4dfd59708acc85609dd23066ed1bc8923c7..0fbd1e20773e6c46b2482e802bc41d656867988d 100644 (file)
 
 namespace JSC {
 
-    class LLIntOffsetsExtractor;
-    class Structure;
-
-    class StructureChain : public JSCell {
-        friend class JIT;
-
-    public:
-        typedef JSCell Base;
-
-        static StructureChain* create(VM& vm, Structure* head)
-        { 
-            StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get());
-            chain->finishCreation(vm, head);
-            return chain;
-        }
-        WriteBarrier<Structure>* head() { return m_vector.get(); }
-        static void visitChildren(JSCell*, SlotVisitor&);
-
-        static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-        {
-            return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
-        }
-        
-        DECLARE_INFO;
-
-        static const bool needsDestruction = true;
-        static const bool hasImmortalStructure = true;
-        static void destroy(JSCell*);
-
-    protected:
-        static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal;
-
-        void finishCreation(VM& vm, Structure* head)
-        {
-            Base::finishCreation(vm);
-            size_t size = 0;
-            for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
-                ++size;
-    
-            m_vector = std::make_unique<WriteBarrier<Structure>[]>(size + 1);
-
-            size_t i = 0;
-            for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
-                m_vector[i++].set(vm, this, current);
-        }
-
-    private:
-        friend class LLIntOffsetsExtractor;
-        
-        StructureChain(VM&, Structure*);
-        std::unique_ptr<WriteBarrier<Structure>[]> m_vector;
-    };
+class LLIntOffsetsExtractor;
+class Structure;
+
+class StructureChain final : public JSCell {
+    friend class JIT;
+
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static StructureChain* create(VM& vm, Structure* head)
+    { 
+        StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get());
+        chain->finishCreation(vm, head);
+        return chain;
+    }
+    WriteBarrier<Structure>* head() { return m_vector.get(); }
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+    DECLARE_INFO;
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+protected:
+    void finishCreation(VM& vm, Structure* head)
+    {
+        Base::finishCreation(vm);
+        size_t size = 0;
+        for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
+            ++size;
+
+        m_vector = std::make_unique<WriteBarrier<Structure>[]>(size + 1);
+
+        size_t i = 0;
+        for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
+            m_vector[i++].set(vm, this, current);
+    }
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    StructureChain(VM&, Structure*);
+    std::unique_ptr<WriteBarrier<Structure>[]> m_vector;
+};
 
 } // namespace JSC
 
index 57acd29fe4cf7d44e0668140192390723ba9ff55..8aa89b066e66338daae053a4898f33f1ab1015da 100644 (file)
 #include <limits.h>
 #include <wtf/Atomics.h>
 #include <wtf/DataLog.h>
-#include <wtf/PassOwnPtr.h>
 
 namespace JSC {
 
 StructureIDTable::StructureIDTable()
     : m_firstFreeOffset(0)
-    , m_table(adoptPtr(new StructureOrOffset[s_initialSize]))
+    , m_table(std::make_unique<StructureOrOffset[]>(s_initialSize))
     , m_size(0)
     , m_capacity(s_initialSize)
 {
@@ -47,7 +46,7 @@ StructureIDTable::StructureIDTable()
 void StructureIDTable::resize(size_t newCapacity)
 {
     // Create the new table.
-    OwnPtr<StructureOrOffset> newTable = adoptPtr(new StructureOrOffset[newCapacity]);
+    auto newTable = std::make_unique<StructureOrOffset[]>(newCapacity);
 
     // Copy the contents of the old table to the new table.
     memcpy(newTable.get(), table(), m_capacity * sizeof(StructureOrOffset));
@@ -59,7 +58,7 @@ void StructureIDTable::resize(size_t newCapacity)
     swap(m_table, newTable);
 
     // Put the old table (now labeled as new) into the list of old tables.
-    m_oldTables.append(newTable.release());
+    m_oldTables.append(WTF::move(newTable));
 
     // Update the capacity.
     m_capacity = newCapacity;
index 1902071de57497b412f553e696d67ea18a129f34..630333f0c571ada155b984f0df504a7f22f37527 100644 (file)
@@ -27,7 +27,6 @@
 #define StructureIDTable_h
 
 #include "UnusedPointer.h"
-#include <wtf/OwnPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -67,10 +66,10 @@ private:
     
     static const size_t s_initialSize = 256;
 
-    Vector<OwnPtr<StructureOrOffset>> m_oldTables;
+    Vector<std::unique_ptr<StructureOrOffset[]>> m_oldTables;
 
     uint32_t m_firstFreeOffset;
-    OwnPtr<StructureOrOffset> m_table;
+    std::unique_ptr<StructureOrOffset[]> m_table;
 
     size_t m_size;
     size_t m_capacity;
@@ -83,6 +82,7 @@ private:
 inline Structure* StructureIDTable::get(StructureID structureID)
 {
 #if USE(JSVALUE64)
+    ASSERT_WITH_SECURITY_IMPLICATION(structureID && structureID < m_capacity);
     return table()[structureID].structure;
 #else
     return structureID;
index 955de705349246d01266829a424ec977dd3c1e7e..5c3aed77151a9b237b676aaadec5bc01162cf74e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,7 +61,7 @@ inline JSObject* Structure::storedPrototypeObject() const
 {
     JSValue value = m_prototype.get();
     if (value.isNull())
-        return 0;
+        return nullptr;
     return asObject(value);
 }
 
@@ -69,7 +69,7 @@ inline Structure* Structure::storedPrototypeStructure() const
 {
     JSObject* object = storedPrototypeObject();
     if (!object)
-        return 0;
+        return nullptr;
     return object->structure();
 }
 
@@ -85,21 +85,8 @@ ALWAYS_INLINE PropertyOffset Structure::get(VM& vm, PropertyName propertyName)
     PropertyMapEntry* entry = propertyTable->get(propertyName.uid());
     return entry ? entry->offset : invalidOffset;
 }
-
-ALWAYS_INLINE PropertyOffset Structure::get(VM& vm, const WTF::String& name)
-{
-    ASSERT(!isCompilationThread());
-    ASSERT(structure()->classInfo() == info());
-    PropertyTable* propertyTable;
-    materializePropertyMapIfNecessary(vm, propertyTable);
-    if (!propertyTable)
-        return invalidOffset;
-
-    PropertyMapEntry* entry = propertyTable->findWithString(name.impl()).first;
-    return entry ? entry->offset : invalidOffset;
-}
     
-ALWAYS_INLINE PropertyOffset Structure::get(VM& vm, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
+ALWAYS_INLINE PropertyOffset Structure::get(VM& vm, PropertyName propertyName, unsigned& attributes)
 {
     ASSERT(!isCompilationThread());
     ASSERT(structure()->classInfo() == info());
@@ -114,16 +101,42 @@ ALWAYS_INLINE PropertyOffset Structure::get(VM& vm, PropertyName propertyName, u
         return invalidOffset;
 
     attributes = entry->attributes;
-    specificValue = entry->specificValue.get();
     return entry->offset;
 }
 
-inline PropertyOffset Structure::getConcurrently(VM& vm, StringImpl* uid)
+template<typename Functor>
+void Structure::forEachPropertyConcurrently(const Functor& functor)
+{
+    Vector<Structure*, 8> structures;
+    Structure* structure;
+    PropertyTable* table;
+    
+    findStructuresAndMapForMaterialization(structures, structure, table);
+    
+    if (table) {
+        for (auto& entry : *table) {
+            if (!functor(entry)) {
+                structure->m_lock.unlock();
+                return;
+            }
+        }
+        structure->m_lock.unlock();
+    }
+    
+    for (unsigned i = structures.size(); i--;) {
+        structure = structures[i];
+        if (!structure->m_nameInPrevious)
+            continue;
+        
+        if (!functor(PropertyMapEntry(structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious())))
+            return;
+    }
+}
+
+inline PropertyOffset Structure::getConcurrently(UniquedStringImpl* uid)
 {
     unsigned attributesIgnored;
-    JSCell* specificValueIgnored;
-    return getConcurrently(
-        vm, uid, attributesIgnored, specificValueIgnored);
+    return getConcurrently(uid, attributesIgnored);
 }
 
 inline bool Structure::hasIndexingHeader(const JSCell* cell) const
@@ -151,25 +164,12 @@ inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
     return false;
 }
 
-inline void Structure::setEnumerationCache(VM& vm, JSPropertyNameIterator* enumerationCache)
-{
-    ASSERT(!isDictionary());
-    if (!m_hasRareData)
-        allocateRareData(vm);
-    rareData()->setEnumerationCache(vm, enumerationCache);
-}
-
-inline JSPropertyNameIterator* Structure::enumerationCache()
-{
-    if (!m_hasRareData)
-        return 0;
-    return rareData()->enumerationCache();
-}
-
 inline JSValue Structure::prototypeForLookup(JSGlobalObject* globalObject) const
 {
     if (isObject())
         return m_prototype.get();
+    if (typeInfo().type() == SymbolType)
+        return globalObject->symbolPrototype();
 
     ASSERT(typeInfo().type() == StringType);
     return globalObject->stringPrototype();
@@ -242,12 +242,37 @@ ALWAYS_INLINE WriteBarrier<PropertyTable>& Structure::propertyTable()
     return m_propertyTableUnsafe;
 }
 
+inline void Structure::didReplaceProperty(PropertyOffset offset)
+{
+    if (LIKELY(!hasRareData()))
+        return;
+    StructureRareData::PropertyWatchpointMap* map = rareData()->m_replacementWatchpointSets.get();
+    if (LIKELY(!map))
+        return;
+    WatchpointSet* set = map->get(offset);
+    if (LIKELY(!set))
+        return;
+    set->fireAll("Property did get replaced");
+}
+
+inline WatchpointSet* Structure::propertyReplacementWatchpointSet(PropertyOffset offset)
+{
+    ConcurrentJITLocker locker(m_lock);
+    if (!hasRareData())
+        return nullptr;
+    WTF::loadLoadFence();
+    StructureRareData::PropertyWatchpointMap* map = rareData()->m_replacementWatchpointSets.get();
+    if (!map)
+        return nullptr;
+    return map->get(offset);
+}
+
 ALWAYS_INLINE bool Structure::checkOffsetConsistency() const
 {
     PropertyTable* propertyTable = m_propertyTableUnsafe.get();
 
     if (!propertyTable) {
-        ASSERT(!m_isPinnedPropertyTable);
+        ASSERT(!isPinnedPropertyTable());
         return true;
     }
 
index a2c6fc2e3444993b892787c54f8bb1882caa1bf3..20a5371e7a3df334c7cdd95e01fdc554219691bc 100644 (file)
 #include "config.h"
 #include "StructureRareData.h"
 
-#include "JSPropertyNameIterator.h"
+#include "JSPropertyNameEnumerator.h"
 #include "JSString.h"
 #include "JSCInlines.h"
 
 namespace JSC {
 
-const ClassInfo StructureRareData::s_info = { "StructureRareData", 0, 0, 0, CREATE_METHOD_TABLE(StructureRareData) };
+const ClassInfo StructureRareData::s_info = { "StructureRareData", 0, 0, CREATE_METHOD_TABLE(StructureRareData) };
 
 Structure* StructureRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 {
-    return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
 }
 
 StructureRareData* StructureRareData::create(VM& vm, Structure* previous)
@@ -46,11 +46,9 @@ StructureRareData* StructureRareData::create(VM& vm, Structure* previous)
     return rareData;
 }
 
-StructureRareData* StructureRareData::clone(VM& vm, const StructureRareData* other)
+void StructureRareData::destroy(JSCell* cell)
 {
-    StructureRareData* newRareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, other);
-    newRareData->finishCreation(vm);
-    return newRareData;
+    static_cast<StructureRareData*>(cell)->StructureRareData::~StructureRareData();
 }
 
 StructureRareData::StructureRareData(VM& vm, Structure* previous)
@@ -60,25 +58,26 @@ StructureRareData::StructureRareData(VM& vm, Structure* previous)
         m_previous.set(vm, this, previous);
 }
 
-StructureRareData::StructureRareData(VM& vm, const StructureRareData* other)
-    : JSCell(vm, other->structure())
-{
-    if (other->previousID())
-        m_previous.set(vm, this, other->previousID());
-    if (other->objectToStringValue())
-        m_objectToStringValue.set(vm, this, other->objectToStringValue());
-}
-
 void StructureRareData::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     StructureRareData* thisObject = jsCast<StructureRareData*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
 
     JSCell::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_previous);
     visitor.append(&thisObject->m_objectToStringValue);
-    visitor.append(&thisObject->m_enumerationCache);
+    visitor.append(&thisObject->m_cachedPropertyNameEnumerator);
+    visitor.append(&thisObject->m_cachedGenericPropertyNameEnumerator);
+}
+
+JSPropertyNameEnumerator* StructureRareData::cachedPropertyNameEnumerator() const
+{
+    return m_cachedPropertyNameEnumerator.get();
+}
+
+void StructureRareData::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
+{
+    m_cachedPropertyNameEnumerator.set(vm, this, enumerator);
 }
 
 } // namespace JSC
index 1808b6a1c2f94a77c7dd572e6bf41f00a07e4f06..2b11ab8338ee5232f2c144a36836c1a594d915ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "ClassInfo.h"
 #include "JSCell.h"
 #include "JSTypeInfo.h"
+#include "PropertyOffset.h"
 
 namespace JSC {
 
-class JSPropertyNameIterator;
+class JSPropertyNameEnumerator;
 class Structure;
 
-class StructureRareData : public JSCell {
-    friend class Structure;
+class StructureRareData final : public JSCell {
 public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
     static StructureRareData* create(VM&, Structure*);
-    static StructureRareData* clone(VM&, const StructureRareData* other);
+
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
 
-    // Returns true if this StructureRareData should also be cloned when cloning the owner Structure.
-    bool needsCloning() const { return false; }
-
     Structure* previousID() const;
     void setPreviousID(VM&, Structure*);
     void clearPreviousID();
@@ -55,20 +57,23 @@ public:
     JSString* objectToStringValue() const;
     void setObjectToStringValue(VM&, JSString* value);
 
-    JSPropertyNameIterator* enumerationCache();
-    void setEnumerationCache(VM&, JSPropertyNameIterator* value);
+    JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
+    void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
 
     DECLARE_EXPORT_INFO;
 
 private:
+    friend class Structure;
+    
     StructureRareData(VM&, Structure*);
-    StructureRareData(VM&, const StructureRareData*);
-
-    static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
 
     WriteBarrier<Structure> m_previous;
     WriteBarrier<JSString> m_objectToStringValue;
-    WriteBarrier<JSPropertyNameIterator> m_enumerationCache;
+    WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator;
+    WriteBarrier<JSPropertyNameEnumerator> m_cachedGenericPropertyNameEnumerator;
+    
+    typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap;
+    std::unique_ptr<PropertyWatchpointMap> m_replacementWatchpointSets;
 };
 
 } // namespace JSC
index 27c0a79adca5c46c81b4d0556d1403db6c9ecdbf..7fd3c77581ef39096c84eaa1153495282e532325 100644 (file)
@@ -29,8 +29,7 @@
 #include "IndexingType.h"
 #include "WeakGCMap.h"
 #include <wtf/HashFunctions.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/text/StringImpl.h>
+#include <wtf/text/UniquedStringImpl.h>
 
 namespace JSC {
 
@@ -94,11 +93,11 @@ class StructureTransitionTable {
 
     
     struct Hash {
-        typedef std::pair<StringImpl*, unsigned> Key;
+        typedef std::pair<UniquedStringImpl*, unsigned> Key;
         
         static unsigned hash(const Key& p)
         {
-            return PtrHash<StringImpl*>::hash(p.first) + p.second;
+            return PtrHash<UniquedStringImpl*>::hash(p.first) + p.second;
         }
 
         static bool equal(const Key& a, const Key& b)
@@ -130,9 +129,9 @@ public:
         WeakSet::deallocate(impl);
     }
 
-    inline void add(VM&, Structure*);
-    inline bool contains(StringImpl* rep, unsigned attributes) const;
-    inline Structure* get(StringImpl* rep, unsigned attributes) const;
+    void add(VM&, Structure*);
+    bool contains(UniquedStringImpl*, unsigned attributes) const;
+    Structure* get(UniquedStringImpl*, unsigned attributes) const;
 
 private:
     bool isUsingSingleSlot() const
diff --git a/runtime/Symbol.cpp b/runtime/Symbol.cpp
new file mode 100644 (file)
index 0000000..a765609
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Symbol.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "SymbolObject.h"
+
+namespace JSC {
+
+const ClassInfo Symbol::s_info = { "symbol", nullptr, nullptr, CREATE_METHOD_TABLE(Symbol) };
+
+Symbol::Symbol(VM& vm)
+    : Base(vm, vm.symbolStructure.get())
+    , m_privateName()
+{
+}
+
+Symbol::Symbol(VM& vm, const String& string)
+    : Base(vm, vm.symbolStructure.get())
+    , m_privateName(PrivateName::Description, string)
+{
+}
+
+Symbol::Symbol(VM& vm, SymbolImpl& uid)
+    : Base(vm, vm.symbolStructure.get())
+    , m_privateName(uid)
+{
+}
+
+inline SymbolObject* SymbolObject::create(VM& vm, JSGlobalObject* globalObject, Symbol* symbol)
+{
+    SymbolObject* object = new (NotNull, allocateCell<SymbolObject>(vm.heap)) SymbolObject(vm, globalObject->symbolObjectStructure());
+    object->finishCreation(vm, symbol);
+    return object;
+}
+
+JSValue Symbol::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    return const_cast<Symbol*>(this);
+}
+
+bool Symbol::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) const
+{
+    result = this;
+    number = toNumber(exec);
+    return true;
+}
+
+JSObject* Symbol::toObject(ExecState* exec, JSGlobalObject* globalObject) const
+{
+    return SymbolObject::create(exec->vm(), globalObject, const_cast<Symbol*>(this));
+}
+
+double Symbol::toNumber(ExecState* exec) const
+{
+    throwTypeError(exec);
+    return 0.0;
+}
+
+void Symbol::destroy(JSCell* cell)
+{
+    static_cast<Symbol*>(cell)->Symbol::~Symbol();
+}
+
+String Symbol::descriptiveString() const
+{
+    return makeString("Symbol(", String(privateName().uid()), ')');
+}
+
+} // namespace JSC
diff --git a/runtime/Symbol.h b/runtime/Symbol.h
new file mode 100644 (file)
index 0000000..e5790d7
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Symbol_h
+#define Symbol_h
+
+#include "JSCell.h"
+#include "JSString.h"
+#include "PrivateName.h"
+
+namespace JSC {
+
+class Symbol final : public JSCell {
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
+
+    DECLARE_EXPORT_INFO;
+
+    static const bool needsDestruction = true;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(SymbolType, StructureFlags), info());
+    }
+
+    static Symbol* create(VM& vm)
+    {
+        Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm);
+        symbol->finishCreation(vm);
+        return symbol;
+    }
+
+    static Symbol* create(ExecState* exec, JSString* description)
+    {
+        VM& vm = exec->vm();
+        String desc = description->value(exec);
+        Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, desc);
+        symbol->finishCreation(vm);
+        return symbol;
+    }
+
+    static Symbol* create(VM& vm, SymbolImpl& uid)
+    {
+        Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, uid);
+        symbol->finishCreation(vm);
+        return symbol;
+    }
+
+    const PrivateName& privateName() const { return m_privateName; }
+    String descriptiveString() const;
+
+    JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+    bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
+    JSObject* toObject(ExecState*, JSGlobalObject*) const;
+    double toNumber(ExecState*) const;
+
+protected:
+    static void destroy(JSCell*);
+
+    Symbol(VM&);
+    Symbol(VM&, const String&);
+    Symbol(VM&, SymbolImpl& uid);
+
+    void finishCreation(VM& vm)
+    {
+        Base::finishCreation(vm);
+        ASSERT(inherits(info()));
+    }
+
+    PrivateName m_privateName;
+};
+
+Symbol* asSymbol(JSValue);
+
+inline Symbol* asSymbol(JSValue value)
+{
+    ASSERT(value.asCell()->isSymbol());
+    return jsCast<Symbol*>(value.asCell());
+}
+
+} // namespace JSC
+
+#endif // Symbol_h
diff --git a/runtime/SymbolConstructor.cpp b/runtime/SymbolConstructor.cpp
new file mode 100644 (file)
index 0000000..753ce60
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SymbolConstructor.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "JSGlobalObject.h"
+#include "Symbol.h"
+#include "SymbolPrototype.h"
+#include <wtf/text/SymbolRegistry.h>
+
+namespace JSC {
+
+static EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState*);
+static EncodedJSValue JSC_HOST_CALL symbolConstructorKeyFor(ExecState*);
+
+}
+
+#include "SymbolConstructor.lut.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(SymbolConstructor);
+
+const ClassInfo SymbolConstructor::s_info = { "Function", &Base::s_info, &symbolConstructorTable, CREATE_METHOD_TABLE(SymbolConstructor) };
+
+/* Source for SymbolConstructor.lut.h
+@begin symbolConstructorTable
+  for       symbolConstructorFor       DontEnum|Function 1
+  keyFor    symbolConstructorKeyFor    DontEnum|Function 1
+@end
+*/
+
+SymbolConstructor::SymbolConstructor(VM& vm, Structure* structure)
+    : InternalFunction(vm, structure)
+{
+}
+
+#define INITIALIZE_WELL_KNOWN_SYMBOLS(name) \
+    putDirectWithoutTransition(vm, Identifier::fromString(&vm, #name), Symbol::create(vm, static_cast<SymbolImpl&>(*vm.propertyNames->name##Symbol.impl())), DontEnum | DontDelete | ReadOnly);
+
+void SymbolConstructor::finishCreation(VM& vm, SymbolPrototype* prototype)
+{
+    Base::finishCreation(vm, prototype->classInfo()->className);
+    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_WELL_KNOWN_SYMBOLS)
+}
+
+bool SymbolConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
+{
+    return getStaticFunctionSlot<Base>(exec, symbolConstructorTable, jsCast<SymbolConstructor*>(object), propertyName, slot);
+}
+
+// ------------------------------ Functions ---------------------------
+
+static EncodedJSValue JSC_HOST_CALL callSymbol(ExecState* exec)
+{
+    JSValue description = exec->argument(0);
+    if (description.isUndefined())
+        return JSValue::encode(Symbol::create(exec->vm()));
+    return JSValue::encode(Symbol::create(exec, description.toString(exec)));
+}
+
+ConstructType SymbolConstructor::getConstructData(JSCell*, ConstructData&)
+{
+    return ConstructTypeNone;
+}
+
+CallType SymbolConstructor::getCallData(JSCell*, CallData& callData)
+{
+    callData.native.function = callSymbol;
+    return CallTypeHost;
+}
+
+EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState* exec)
+{
+    JSString* stringKey = exec->argument(0).toString(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+    String string = stringKey->value(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    return JSValue::encode(Symbol::create(exec->vm(), exec->vm().symbolRegistry().symbolForKey(string)));
+}
+
+EncodedJSValue JSC_HOST_CALL symbolConstructorKeyFor(ExecState* exec)
+{
+    JSValue symbolValue = exec->argument(0);
+    if (!symbolValue.isSymbol())
+        return JSValue::encode(throwTypeError(exec));
+
+    SymbolImpl* uid = asSymbol(symbolValue)->privateName().uid();
+    if (!uid->symbolRegistry())
+        return JSValue::encode(jsUndefined());
+
+    ASSERT(uid->symbolRegistry() == &exec->vm().symbolRegistry());
+    return JSValue::encode(jsString(exec, exec->vm().symbolRegistry().keyForSymbol(*uid)));
+}
+
+} // namespace JSC
diff --git a/runtime/SymbolConstructor.h b/runtime/SymbolConstructor.h
new file mode 100644 (file)
index 0000000..344a978
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SymbolConstructor_h
+#define SymbolConstructor_h
+
+#include "InternalFunction.h"
+#include "Symbol.h"
+
+namespace JSC {
+
+class SymbolPrototype;
+
+class SymbolConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
+
+    static SymbolConstructor* create(VM& vm, Structure* structure, SymbolPrototype* prototype)
+    {
+        SymbolConstructor* constructor = new (NotNull, allocateCell<SymbolConstructor>(vm.heap)) SymbolConstructor(vm, structure);
+        constructor->finishCreation(vm, prototype);
+        return constructor;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+protected:
+    void finishCreation(VM&, SymbolPrototype*);
+
+private:
+    SymbolConstructor(VM&, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
+
+} // namespace JSC
+
+#endif // SymbolConstructor_h
diff --git a/runtime/SymbolObject.cpp b/runtime/SymbolObject.cpp
new file mode 100644 (file)
index 0000000..9ab7a7e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SymbolObject.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(SymbolObject);
+
+const ClassInfo SymbolObject::s_info = { "Symbol", &JSWrapperObject::s_info, nullptr, CREATE_METHOD_TABLE(SymbolObject) };
+
+SymbolObject::SymbolObject(VM& vm, Structure* structure)
+    : JSWrapperObject(vm, structure)
+{
+}
+
+void SymbolObject::finishCreation(VM& vm, Symbol* symbol)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+    setInternalValue(vm, symbol);
+}
+
+JSValue SymbolObject::defaultValue(const JSObject* object, ExecState*, PreferredPrimitiveType)
+{
+    const SymbolObject* symbolObject = jsCast<const SymbolObject*>(object);
+    return symbolObject->internalValue();
+}
+
+} // namespace JSC
diff --git a/runtime/SymbolObject.h b/runtime/SymbolObject.h
new file mode 100644 (file)
index 0000000..46a0491
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef SymbolObject_h
+#define SymbolObject_h
+
+#include "JSWrapperObject.h"
+#include "Symbol.h"
+
+namespace JSC {
+
+class SymbolObject : public JSWrapperObject {
+public:
+    typedef JSWrapperObject Base;
+
+    static SymbolObject* create(VM& vm, Structure* structure)
+    {
+        Symbol* symbol = Symbol::create(vm);
+        SymbolObject* object = new (NotNull, allocateCell<SymbolObject>(vm.heap)) SymbolObject(vm, structure);
+        object->finishCreation(vm, symbol);
+        return object;
+    }
+    static SymbolObject* create(VM& vm, Structure* structure, Symbol* symbol)
+    {
+        SymbolObject* object = new (NotNull, allocateCell<SymbolObject>(vm.heap)) SymbolObject(vm, structure);
+        object->finishCreation(vm, symbol);
+        return object;
+    }
+    static SymbolObject* create(VM&, JSGlobalObject*, Symbol*);
+
+    DECLARE_EXPORT_INFO;
+
+    Symbol* internalValue() const { return asSymbol(JSWrapperObject::internalValue());}
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
+
+protected:
+    JS_EXPORT_PRIVATE void finishCreation(VM&, Symbol*);
+    JS_EXPORT_PRIVATE SymbolObject(VM&, Structure*);
+};
+
+} // namespace JSC
+
+#endif // SymbolObject_h
diff --git a/runtime/SymbolPrototype.cpp b/runtime/SymbolPrototype.cpp
new file mode 100644 (file)
index 0000000..2f4ac4d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SymbolPrototype.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+static EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState*);
+static EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState*);
+
+}
+
+#include "SymbolPrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo SymbolPrototype::s_info = { "Symbol", &Base::s_info, &symbolPrototypeTable, CREATE_METHOD_TABLE(SymbolPrototype) };
+
+/* Source for SymbolPrototype.lut.h
+@begin symbolPrototypeTable
+  toString          symbolProtoFuncToString         DontEnum|Function 0
+  valueOf           symbolProtoFuncValueOf          DontEnum|Function 0
+@end
+*/
+
+SymbolPrototype::SymbolPrototype(VM& vm, Structure* structure)
+    : Base(vm, structure)
+{
+}
+
+void SymbolPrototype::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+}
+
+bool SymbolPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
+{
+    return getStaticFunctionSlot<Base>(exec, symbolPrototypeTable, jsCast<SymbolPrototype*>(object), propertyName, slot);
+}
+
+// ------------------------------ Functions ---------------------------
+
+EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    Symbol* symbol = nullptr;
+    if (thisValue.isSymbol())
+        symbol = asSymbol(thisValue);
+    else if (!thisValue.isObject())
+        return throwVMTypeError(exec);
+    else {
+        JSObject* thisObject = asObject(thisValue);
+        if (!thisObject->inherits(SymbolObject::info()))
+            return throwVMTypeError(exec);
+        symbol = asSymbol(jsCast<SymbolObject*>(thisObject)->internalValue());
+    }
+
+    return JSValue::encode(jsNontrivialString(exec, symbol->descriptiveString()));
+}
+
+EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState* exec)
+{
+    JSValue thisValue = exec->thisValue();
+    if (thisValue.isSymbol())
+        return JSValue::encode(thisValue);
+
+    if (!thisValue.isObject())
+        return throwVMTypeError(exec);
+
+    JSObject* thisObject = asObject(thisValue);
+    if (!thisObject->inherits(SymbolObject::info()))
+        return throwVMTypeError(exec);
+
+    return JSValue::encode(jsCast<SymbolObject*>(thisObject)->internalValue());
+}
+
+} // namespace JSC
diff --git a/runtime/SymbolPrototype.h b/runtime/SymbolPrototype.h
new file mode 100644 (file)
index 0000000..8b221e5
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SymbolPrototype_h
+#define SymbolPrototype_h
+
+#include "Symbol.h"
+#include "SymbolObject.h"
+
+namespace JSC {
+
+// In the ES6 spec, Symbol.prototype object is an ordinary JS object, not one of the symbol wrapper object instance.
+class SymbolPrototype : public JSDestructibleObject {
+public:
+    typedef JSDestructibleObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+
+    static SymbolPrototype* create(VM& vm, JSGlobalObject*, Structure* structure)
+    {
+        SymbolPrototype* prototype = new (NotNull, allocateCell<SymbolPrototype>(vm.heap)) SymbolPrototype(vm, structure);
+        prototype->finishCreation(vm);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+protected:
+    SymbolPrototype(VM&, Structure*);
+    void finishCreation(VM&);
+
+private:
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+};
+
+} // namespace JSC
+
+#endif // SymbolPrototype_h
index f60c86ac914e83cfaab5fe340479bec8210f641a..ecbf9ab6f1e899a3d8f84ed8bae54163df7fe506 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JSDestructibleObject.h"
 #include "JSCInlines.h"
 #include "SlotVisitorInlines.h"
-#include "VariableWatchpointSetInlines.h"
+#include "TypeProfiler.h"
 
 namespace JSC {
 
-const ClassInfo SymbolTable::s_info = { "SymbolTable", 0, 0, 0, CREATE_METHOD_TABLE(SymbolTable) };
+const ClassInfo SymbolTable::s_info = { "SymbolTable", 0, 0, CREATE_METHOD_TABLE(SymbolTable) };
 
 SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other)
 {
@@ -59,19 +59,14 @@ void SymbolTableEntry::freeFatEntrySlow()
     delete fatEntry();
 }
 
-JSValue SymbolTableEntry::inferredValue()
-{
-    if (!isFat())
-        return JSValue();
-    return fatEntry()->m_watchpoints->inferredValue();
-}
-
-void SymbolTableEntry::prepareToWatch(SymbolTable* symbolTable)
+void SymbolTableEntry::prepareToWatch()
 {
+    if (!isWatchable())
+        return;
     FatEntry* entry = inflate();
     if (entry->m_watchpoints)
         return;
-    entry->m_watchpoints = adoptRef(new VariableWatchpointSet(*symbolTable));
+    entry->m_watchpoints = adoptRef(new WatchpointSet(ClearWatchpoint));
 }
 
 void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint)
@@ -79,15 +74,6 @@ void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint)
     fatEntry()->m_watchpoints->add(watchpoint);
 }
 
-void SymbolTableEntry::notifyWriteSlow(VM& vm, JSValue value)
-{
-    VariableWatchpointSet* watchpoints = fatEntry()->m_watchpoints.get();
-    if (!watchpoints)
-        return;
-    
-    watchpoints->notifyWrite(vm, value);
-}
-
 SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow()
 {
     FatEntry* entry = new FatEntry(m_bits);
@@ -97,69 +83,177 @@ SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow()
 
 SymbolTable::SymbolTable(VM& vm)
     : JSCell(vm, vm.symbolTableStructure.get())
-    , m_parameterCountIncludingThis(0)
     , m_usesNonStrictEval(false)
-    , m_captureStart(0)
-    , m_captureEnd(0)
-    , m_functionEnteredOnce(ClearWatchpoint)
 {
 }
 
 SymbolTable::~SymbolTable() { }
 
+void SymbolTable::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    m_singletonScope.set(vm, this, InferredValue::create(vm));
+}
+
 void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
 {
     SymbolTable* thisSymbolTable = jsCast<SymbolTable*>(thisCell);
-    if (!thisSymbolTable->m_watchpointCleanup) {
-        thisSymbolTable->m_watchpointCleanup =
-            std::make_unique<WatchpointCleanup>(thisSymbolTable);
-    }
     
-    visitor.addUnconditionalFinalizer(thisSymbolTable->m_watchpointCleanup.get());
+    visitor.append(&thisSymbolTable->m_arguments);
+    visitor.append(&thisSymbolTable->m_singletonScope);
+    
+    // Save some memory. This is O(n) to rebuild and we do so on the fly.
+    ConcurrentJITLocker locker(thisSymbolTable->m_lock);
+    thisSymbolTable->m_localToEntry = nullptr;
 }
 
-SymbolTable::WatchpointCleanup::WatchpointCleanup(SymbolTable* symbolTable)
-    : m_symbolTable(symbolTable)
+const SymbolTable::LocalToEntryVec& SymbolTable::localToEntry(const ConcurrentJITLocker&)
 {
+    if (UNLIKELY(!m_localToEntry)) {
+        unsigned size = 0;
+        for (auto& entry : m_map) {
+            VarOffset offset = entry.value.varOffset();
+            if (offset.isScope())
+                size = std::max(size, offset.scopeOffset().offset() + 1);
+        }
+    
+        m_localToEntry = std::make_unique<LocalToEntryVec>(size, nullptr);
+        for (auto& entry : m_map) {
+            VarOffset offset = entry.value.varOffset();
+            if (offset.isScope())
+                m_localToEntry->at(offset.scopeOffset().offset()) = &entry.value;
+        }
+    }
+    
+    return *m_localToEntry;
 }
 
-SymbolTable::WatchpointCleanup::~WatchpointCleanup() { }
-
-void SymbolTable::WatchpointCleanup::finalizeUnconditionally()
+SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJITLocker& locker, ScopeOffset offset)
 {
-    Map::iterator iter = m_symbolTable->m_map.begin();
-    Map::iterator end = m_symbolTable->m_map.end();
-    for (; iter != end; ++iter) {
-        if (VariableWatchpointSet* set = iter->value.watchpointSet())
-            set->finalizeUnconditionally();
-    }
+    auto& toEntryVector = localToEntry(locker);
+    if (offset.offset() >= toEntryVector.size())
+        return nullptr;
+    return toEntryVector[offset.offset()];
 }
 
-SymbolTable* SymbolTable::cloneCapturedNames(VM& vm)
+SymbolTable* SymbolTable::cloneScopePart(VM& vm)
 {
     SymbolTable* result = SymbolTable::create(vm);
     
-    result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
     result->m_usesNonStrictEval = m_usesNonStrictEval;
-    result->m_captureStart = m_captureStart;
-    result->m_captureEnd = m_captureEnd;
 
     for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
-        if (!isCaptured(iter->value.getIndex()))
+        if (!iter->value.varOffset().isScope())
             continue;
         result->m_map.add(
             iter->key,
-            SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
+            SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes()));
     }
     
-    if (m_slowArguments) {
-        result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
-        for (unsigned i = parameterCount(); i--;)
-            result->m_slowArguments[i] = m_slowArguments[i];
+    result->m_maxScopeOffset = m_maxScopeOffset;
+    
+    if (ScopedArgumentsTable* arguments = this->arguments())
+        result->m_arguments.set(vm, result, arguments);
+    
+    if (m_typeProfilingRareData) {
+        result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
+
+        {
+            auto iter = m_typeProfilingRareData->m_uniqueIDMap.begin();
+            auto end = m_typeProfilingRareData->m_uniqueIDMap.end();
+            for (; iter != end; ++iter)
+                result->m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, iter->value);
+        }
+
+        {
+            auto iter = m_typeProfilingRareData->m_offsetToVariableMap.begin();
+            auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+            for (; iter != end; ++iter)
+                result->m_typeProfilingRareData->m_offsetToVariableMap.set(iter->key, iter->value);
+        }
+
+        {
+            auto iter = m_typeProfilingRareData->m_uniqueTypeSetMap.begin();
+            auto end = m_typeProfilingRareData->m_uniqueTypeSetMap.end();
+            for (; iter != end; ++iter)
+                result->m_typeProfilingRareData->m_uniqueTypeSetMap.set(iter->key, iter->value);
+        }
     }
     
     return result;
 }
 
+void SymbolTable::prepareForTypeProfiling(const ConcurrentJITLocker&)
+{
+    if (m_typeProfilingRareData)
+        return;
+
+    m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
+
+    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
+        m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration);
+        m_typeProfilingRareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key);
+    }
+}
+
+GlobalVariableID SymbolTable::uniqueIDForVariable(const ConcurrentJITLocker&, UniquedStringImpl* key, VM& vm)
+{
+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    auto iter = m_typeProfilingRareData->m_uniqueIDMap.find(key);
+    auto end = m_typeProfilingRareData->m_uniqueIDMap.end();
+    if (iter == end)
+        return TypeProfilerNoGlobalIDExists;
+
+    GlobalVariableID id = iter->value;
+    if (id == TypeProfilerNeedsUniqueIDGeneration) {
+        id = vm.typeProfiler()->getNextUniqueVariableID();
+        m_typeProfilingRareData->m_uniqueIDMap.set(key, id);
+        m_typeProfilingRareData->m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
+    }
+
+    return id;
+}
+
+GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
+{
+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
+    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+    if (iter == end)
+        return TypeProfilerNoGlobalIDExists;
+
+    return uniqueIDForVariable(locker, iter->value.get(), vm);
+}
+
+RefPtr<TypeSet> SymbolTable::globalTypeSetForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
+{
+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary.
+
+    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
+    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
+    if (iter == end)
+        return nullptr;
+
+    return globalTypeSetForVariable(locker, iter->value.get(), vm);
+}
+
+RefPtr<TypeSet> SymbolTable::globalTypeSetForVariable(const ConcurrentJITLocker& locker, UniquedStringImpl* key, VM& vm)
+{
+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    uniqueIDForVariable(locker, key, vm); // Lazily create the TypeSet if necessary.
+
+    auto iter = m_typeProfilingRareData->m_uniqueTypeSetMap.find(key);
+    auto end = m_typeProfilingRareData->m_uniqueTypeSetMap.end();
+    if (iter == end)
+        return nullptr;
+
+    return iter->value;
+}
+
 } // namespace JSC
 
index 6b3bc7cb83b147c9b70cb8c5e955214cfe0942e4..9f0bc4e43eb9d7d64a27d91d89b80a996e804166 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define SymbolTable_h
 
 #include "ConcurrentJITLock.h"
+#include "ConstantMode.h"
+#include "InferredValue.h"
 #include "JSObject.h"
-#include "VariableWatchpointSet.h"
+#include "ScopedArgumentsTable.h"
+#include "TypeLocation.h"
+#include "VarOffset.h"
+#include "Watchpoint.h"
 #include <memory>
 #include <wtf/HashTraits.h>
-#include <wtf/text/StringImpl.h>
+#include <wtf/text/UniquedStringImpl.h>
 
 namespace JSC {
 
-struct SlowArgument {
-public:
-    enum Status {
-        Normal = 0,
-        Captured = 1,
-        Deleted = 2
-    };
-
-    SlowArgument()
-        : status(Normal)
-        , index(0)
-    {
-    }
-
-    Status status;
-    int index; // If status is 'Deleted', index is bogus.
-};
+class SymbolTable;
 
 static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
 
@@ -77,14 +66,36 @@ static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>
 // counted pointer to a shared WatchpointSet. Thus, in-place edits of the
 // WatchpointSet will manifest in all copies. Here's a picture:
 //
-// SymbolTableEntry --> FatEntry --> VariableWatchpointSet
+// SymbolTableEntry --> FatEntry --> WatchpointSet
 //
 // If you make a copy of a SymbolTableEntry, you will have:
 //
-// original: SymbolTableEntry --> FatEntry --> VariableWatchpointSet
+// original: SymbolTableEntry --> FatEntry --> WatchpointSet
 // copy:     SymbolTableEntry --> FatEntry -----^
 
 struct SymbolTableEntry {
+private:
+    static VarOffset varOffsetFromBits(intptr_t bits)
+    {
+        VarKind kind;
+        intptr_t kindBits = bits & KindBitsMask;
+        if (kindBits <= UnwatchableScopeKindBits)
+            kind = VarKind::Scope;
+        else if (kindBits == StackKindBits)
+            kind = VarKind::Stack;
+        else
+            kind = VarKind::DirectArgument;
+        return VarOffset::assemble(kind, static_cast<int>(bits >> FlagBits));
+    }
+    
+    static ScopeOffset scopeOffsetFromBits(intptr_t bits)
+    {
+        ASSERT((bits & KindBitsMask) <= UnwatchableScopeKindBits);
+        return ScopeOffset(static_cast<int>(bits >> FlagBits));
+    }
+
+public:
+    
     // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
     // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
     // and (2) you are in a hot path where you need to minimize the number of times
@@ -106,22 +117,35 @@ struct SymbolTableEntry {
             return !(m_bits & ~SlimFlag);
         }
 
-        int getIndex() const
+        VarOffset varOffset() const
         {
-            return static_cast<int>(m_bits >> FlagBits);
+            return varOffsetFromBits(m_bits);
         }
-    
+        
+        // Asserts if the offset is anything but a scope offset. This structures the assertions
+        // in a way that may result in better code, even in release, than doing
+        // varOffset().scopeOffset().
+        ScopeOffset scopeOffset() const
+        {
+            return scopeOffsetFromBits(m_bits);
+        }
+        
         bool isReadOnly() const
         {
             return m_bits & ReadOnlyFlag;
         }
         
+        bool isDontEnum() const
+        {
+            return m_bits & DontEnumFlag;
+        }
+        
         unsigned getAttributes() const
         {
             unsigned attributes = 0;
-            if (m_bits & ReadOnlyFlag)
+            if (isReadOnly())
                 attributes |= ReadOnly;
-            if (m_bits & DontEnumFlag)
+            if (isDontEnum())
                 attributes |= DontEnum;
             return attributes;
         }
@@ -141,18 +165,18 @@ struct SymbolTableEntry {
     {
     }
 
-    SymbolTableEntry(int index)
+    SymbolTableEntry(VarOffset offset)
         : m_bits(SlimFlag)
     {
-        ASSERT(isValidIndex(index));
-        pack(index, false, false);
+        ASSERT(isValidVarOffset(offset));
+        pack(offset, true, false, false);
     }
 
-    SymbolTableEntry(int index, unsigned attributes)
+    SymbolTableEntry(VarOffset offset, unsigned attributes)
         : m_bits(SlimFlag)
     {
-        ASSERT(isValidIndex(index));
-        pack(index, attributes & ReadOnly, attributes & DontEnum);
+        ASSERT(isValidVarOffset(offset));
+        pack(offset, true, attributes & ReadOnly, attributes & DontEnum);
     }
     
     ~SymbolTableEntry()
@@ -180,9 +204,22 @@ struct SymbolTableEntry {
         return !(bits() & ~SlimFlag);
     }
 
-    int getIndex() const
+    VarOffset varOffset() const
     {
-        return static_cast<int>(bits() >> FlagBits);
+        return varOffsetFromBits(bits());
+    }
+    
+    bool isWatchable() const
+    {
+        return (m_bits & KindBitsMask) == ScopeKindBits;
+    }
+    
+    // Asserts if the offset is anything but a scope offset. This structures the assertions
+    // in a way that may result in better code, even in release, than doing
+    // varOffset().scopeOffset().
+    ScopeOffset scopeOffset() const
+    {
+        return scopeOffsetFromBits(bits());
     }
     
     ALWAYS_INLINE Fast getFast() const
@@ -205,10 +242,10 @@ struct SymbolTableEntry {
     {
         return getFast().getAttributes();
     }
-
+    
     void setAttributes(unsigned attributes)
     {
-        pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
+        pack(varOffset(), isWatchable(), attributes & ReadOnly, attributes & DontEnum);
     }
 
     bool isReadOnly() const
@@ -216,32 +253,65 @@ struct SymbolTableEntry {
         return bits() & ReadOnlyFlag;
     }
     
-    JSValue inferredValue();
+    ConstantMode constantMode() const
+    {
+        return modeForIsConstant(isReadOnly());
+    }
+    
+    bool isDontEnum() const
+    {
+        return bits() & DontEnumFlag;
+    }
+    
+    void disableWatching()
+    {
+        if (WatchpointSet* set = watchpointSet())
+            set->invalidate("Disabling watching in symbol table");
+        if (varOffset().isScope())
+            pack(varOffset(), false, isReadOnly(), isDontEnum());
+    }
     
-    void prepareToWatch(SymbolTable*);
+    void prepareToWatch();
     
     void addWatchpoint(Watchpoint*);
     
-    VariableWatchpointSet* watchpointSet()
+    // This watchpoint set is initialized clear, and goes through the following state transitions:
+    // 
+    // First write to this var, in any scope that has this symbol table: Clear->IsWatched.
+    //
+    // Second write to this var, in any scope that has this symbol table: IsWatched->IsInvalidated.
+    //
+    // We ensure that we touch the set (i.e. trigger its state transition) after we do the write. This
+    // means that if you're in the compiler thread, and you:
+    //
+    // 1) Observe that the set IsWatched and commit to adding your watchpoint.
+    // 2) Load a value from any scope that has this watchpoint set.
+    //
+    // Then you can be sure that that value is either going to be the correct value for that var forever,
+    // or the watchpoint set will invalidate and you'll get fired.
+    //
+    // It's possible to write a program that first creates multiple scopes with the same var, and then
+    // initializes that var in just one of them. This means that a compilation could constant-fold to one
+    // of the scopes that still has an undefined value for this variable. That's fine, because at that
+    // point any write to any of the instances of that variable would fire the watchpoint.
+    WatchpointSet* watchpointSet()
     {
         if (!isFat())
             return 0;
         return fatEntry()->m_watchpoints.get();
     }
     
-    ALWAYS_INLINE void notifyWrite(VM& vm, JSValue value)
-    {
-        if (LIKELY(!isFat()))
-            return;
-        notifyWriteSlow(vm, value);
-    }
-    
 private:
     static const intptr_t SlimFlag = 0x1;
     static const intptr_t ReadOnlyFlag = 0x2;
     static const intptr_t DontEnumFlag = 0x4;
     static const intptr_t NotNullFlag = 0x8;
-    static const intptr_t FlagBits = 4;
+    static const intptr_t KindBitsMask = 0x30;
+    static const intptr_t ScopeKindBits = 0x00;
+    static const intptr_t UnwatchableScopeKindBits = 0x10;
+    static const intptr_t StackKindBits = 0x20;
+    static const intptr_t DirectArgumentKindBits = 0x30;
+    static const intptr_t FlagBits = 6;
     
     class FatEntry {
         WTF_MAKE_FAST_ALLOCATED;
@@ -253,11 +323,11 @@ private:
         
         intptr_t m_bits; // always has FatFlag set and exactly matches what the bits would have been if this wasn't fat.
         
-        RefPtr<VariableWatchpointSet> m_watchpoints;
+        RefPtr<WatchpointSet> m_watchpoints;
     };
     
     SymbolTableEntry& copySlow(const SymbolTableEntry&);
-    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue);
+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const FireDetail&);
     
     bool isFat() const
     {
@@ -308,20 +378,38 @@ private:
 
     JS_EXPORT_PRIVATE void freeFatEntrySlow();
 
-    void pack(int index, bool readOnly, bool dontEnum)
+    void pack(VarOffset offset, bool isWatchable, bool readOnly, bool dontEnum)
     {
         ASSERT(!isFat());
         intptr_t& bitsRef = bits();
-        bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
+        bitsRef =
+            (static_cast<intptr_t>(offset.rawOffset()) << FlagBits) | NotNullFlag | SlimFlag;
         if (readOnly)
             bitsRef |= ReadOnlyFlag;
         if (dontEnum)
             bitsRef |= DontEnumFlag;
+        switch (offset.kind()) {
+        case VarKind::Scope:
+            if (isWatchable)
+                bitsRef |= ScopeKindBits;
+            else
+                bitsRef |= UnwatchableScopeKindBits;
+            break;
+        case VarKind::Stack:
+            bitsRef |= StackKindBits;
+            break;
+        case VarKind::DirectArgument:
+            bitsRef |= DirectArgumentKindBits;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
     }
     
-    bool isValidIndex(int index)
+    static bool isValidVarOffset(VarOffset offset)
     {
-        return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
+        return ((static_cast<intptr_t>(offset.rawOffset()) << FlagBits) >> FlagBits) == static_cast<intptr_t>(offset.rawOffset());
     }
 
     intptr_t m_bits;
@@ -331,11 +419,16 @@ struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
     static const bool needsDestruction = true;
 };
 
-class SymbolTable : public JSCell {
+class SymbolTable final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-    typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, SymbolTableIndexHashTraits> Map;
+    typedef HashMap<RefPtr<UniquedStringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>, SymbolTableIndexHashTraits> Map;
+    typedef HashMap<RefPtr<UniquedStringImpl>, GlobalVariableID, IdentifierRepHash> UniqueIDMap;
+    typedef HashMap<RefPtr<UniquedStringImpl>, RefPtr<TypeSet>, IdentifierRepHash> UniqueTypeSetMap;
+    typedef HashMap<VarOffset, RefPtr<UniquedStringImpl>> OffsetToVariableMap;
+    typedef Vector<SymbolTableEntry*> LocalToEntryVec;
 
     static SymbolTable* create(VM& vm)
     {
@@ -343,43 +436,50 @@ public:
         symbolTable->finishCreation(vm);
         return symbolTable;
     }
+    
+    static SymbolTable* createNameScopeTable(VM& vm, const Identifier& ident, unsigned attributes)
+    {
+        SymbolTable* result = create(vm);
+        result->add(ident.impl(), SymbolTableEntry(VarOffset(ScopeOffset(0)), attributes));
+        return result;
+    }
+    
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(LeafType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
     // You must hold the lock until after you're done with the iterator.
-    Map::iterator find(const ConcurrentJITLocker&, StringImpl* key)
+    Map::iterator find(const ConcurrentJITLocker&, UniquedStringImpl* key)
     {
         return m_map.find(key);
     }
     
-    Map::iterator find(const GCSafeConcurrentJITLocker&, StringImpl* key)
+    Map::iterator find(const GCSafeConcurrentJITLocker&, UniquedStringImpl* key)
     {
         return m_map.find(key);
     }
     
-    SymbolTableEntry get(const ConcurrentJITLocker&, StringImpl* key)
+    SymbolTableEntry get(const ConcurrentJITLocker&, UniquedStringImpl* key)
     {
         return m_map.get(key);
     }
     
-    SymbolTableEntry get(StringImpl* key)
+    SymbolTableEntry get(UniquedStringImpl* key)
     {
         ConcurrentJITLocker locker(m_lock);
         return get(locker, key);
     }
     
-    SymbolTableEntry inlineGet(const ConcurrentJITLocker&, StringImpl* key)
+    SymbolTableEntry inlineGet(const ConcurrentJITLocker&, UniquedStringImpl* key)
     {
         return m_map.inlineGet(key);
     }
     
-    SymbolTableEntry inlineGet(StringImpl* key)
+    SymbolTableEntry inlineGet(UniquedStringImpl* key)
     {
         ConcurrentJITLocker locker(m_lock);
         return inlineGet(locker, key);
@@ -411,103 +511,178 @@ public:
         return size(locker);
     }
     
-    Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
+    ScopeOffset maxScopeOffset() const
+    {
+        return m_maxScopeOffset;
+    }
+    
+    void didUseScopeOffset(ScopeOffset offset)
+    {
+        if (!m_maxScopeOffset || m_maxScopeOffset < offset)
+            m_maxScopeOffset = offset;
+    }
+    
+    void didUseVarOffset(VarOffset offset)
     {
-        return m_map.add(key, entry);
+        if (offset.isScope())
+            didUseScopeOffset(offset.scopeOffset());
     }
     
-    void add(StringImpl* key, const SymbolTableEntry& entry)
+    unsigned scopeSize() const
+    {
+        ScopeOffset maxScopeOffset = this->maxScopeOffset();
+        
+        // Do some calculation that relies on invalid scope offset plus one being zero.
+        unsigned fastResult = maxScopeOffset.offsetUnchecked() + 1;
+        
+        // Assert that this works.
+        ASSERT(fastResult == (!maxScopeOffset ? 0 : maxScopeOffset.offset() + 1));
+        
+        return fastResult;
+    }
+    
+    ScopeOffset nextScopeOffset() const
+    {
+        return ScopeOffset(scopeSize());
+    }
+    
+    ScopeOffset takeNextScopeOffset(const ConcurrentJITLocker&)
+    {
+        ScopeOffset result = nextScopeOffset();
+        m_maxScopeOffset = result;
+        return result;
+    }
+    
+    ScopeOffset takeNextScopeOffset()
+    {
+        ConcurrentJITLocker locker(m_lock);
+        return takeNextScopeOffset(locker);
+    }
+    
+    void add(const ConcurrentJITLocker&, UniquedStringImpl* key, const SymbolTableEntry& entry)
+    {
+        RELEASE_ASSERT(!m_localToEntry);
+        didUseVarOffset(entry.varOffset());
+        Map::AddResult result = m_map.add(key, entry);
+        ASSERT_UNUSED(result, result.isNewEntry);
+    }
+    
+    void add(UniquedStringImpl* key, const SymbolTableEntry& entry)
     {
         ConcurrentJITLocker locker(m_lock);
         add(locker, key, entry);
     }
     
-    Map::AddResult set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
+    void set(const ConcurrentJITLocker&, UniquedStringImpl* key, const SymbolTableEntry& entry)
     {
-        return m_map.set(key, entry);
+        RELEASE_ASSERT(!m_localToEntry);
+        didUseVarOffset(entry.varOffset());
+        m_map.set(key, entry);
     }
     
-    void set(StringImpl* key, const SymbolTableEntry& entry)
+    void set(UniquedStringImpl* key, const SymbolTableEntry& entry)
     {
         ConcurrentJITLocker locker(m_lock);
         set(locker, key, entry);
     }
     
-    bool contains(const ConcurrentJITLocker&, StringImpl* key)
+    bool contains(const ConcurrentJITLocker&, UniquedStringImpl* key)
     {
         return m_map.contains(key);
     }
     
-    bool contains(StringImpl* key)
+    bool contains(UniquedStringImpl* key)
     {
         ConcurrentJITLocker locker(m_lock);
         return contains(locker, key);
     }
     
-    bool usesNonStrictEval() { return m_usesNonStrictEval; }
-    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
-
-    int captureStart() const { return m_captureStart; }
-    void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
-
-    int captureEnd() const { return m_captureEnd; }
-    void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
-
-    int captureCount() const { return -(m_captureEnd - m_captureStart); }
+    // The principle behind ScopedArgumentsTable modifications is that we will create one and
+    // leave it unlocked - thereby allowing in-place changes - until someone asks for a pointer to
+    // the table. Then, we will lock it. Then both our future changes and their future changes
+    // will first have to make a copy. This discipline means that usually when we create a
+    // ScopedArguments object, we don't have to make a copy of the ScopedArgumentsTable - instead
+    // we just take a reference to one that we already have.
+    
+    uint32_t argumentsLength() const
+    {
+        if (!m_arguments)
+            return 0;
+        return m_arguments->length();
+    }
     
-    bool isCaptured(int operand)
+    void setArgumentsLength(VM& vm, uint32_t length)
     {
-        return operand <= captureStart() && operand > captureEnd();
+        if (UNLIKELY(!m_arguments))
+            m_arguments.set(vm, this, ScopedArgumentsTable::create(vm));
+        m_arguments.set(vm, this, m_arguments->setLength(vm, length));
     }
+    
+    ScopeOffset argumentOffset(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
+        return m_arguments->get(i);
+    }
+    
+    void setArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
+        m_arguments.set(vm, this, m_arguments->set(vm, i, offset));
+    }
+    
+    ScopedArgumentsTable* arguments() const
+    {
+        if (!m_arguments)
+            return nullptr;
+        m_arguments->lock();
+        return m_arguments.get();
+    }
+    
+    const LocalToEntryVec& localToEntry(const ConcurrentJITLocker&);
+    SymbolTableEntry* entryFor(const ConcurrentJITLocker&, ScopeOffset);
+    
+    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, UniquedStringImpl* key, VM&);
+    GlobalVariableID uniqueIDForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
+    RefPtr<TypeSet> globalTypeSetForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
+    RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker&, UniquedStringImpl* key, VM&);
+
+    bool usesNonStrictEval() { return m_usesNonStrictEval; }
+    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
 
-    int parameterCount() { return m_parameterCountIncludingThis - 1; }
-    int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
-    void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
+    SymbolTable* cloneScopePart(VM&);
 
-    // 0 if we don't capture any arguments; parameterCount() in length if we do.
-    const SlowArgument* slowArguments() { return m_slowArguments.get(); }
-    void setSlowArguments(std::unique_ptr<SlowArgument[]> slowArguments) { m_slowArguments = WTF::move(slowArguments); }
+    void prepareForTypeProfiling(const ConcurrentJITLocker&);
     
-    SymbolTable* cloneCapturedNames(VM&);
+    InferredValue* singletonScope() { return m_singletonScope.get(); }
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
     DECLARE_EXPORT_INFO;
 
-protected:
-    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
-
 private:
-    class WatchpointCleanup : public UnconditionalFinalizer {
-    public:
-        WatchpointCleanup(SymbolTable*);
-        virtual ~WatchpointCleanup();
-        
-    protected:
-        virtual void finalizeUnconditionally() override;
-
-    private:
-        SymbolTable* m_symbolTable;
-    };
-    
     JS_EXPORT_PRIVATE SymbolTable(VM&);
     ~SymbolTable();
+    
+    JS_EXPORT_PRIVATE void finishCreation(VM&);
 
     Map m_map;
+    ScopeOffset m_maxScopeOffset;
     
-    int m_parameterCountIncludingThis;
-    bool m_usesNonStrictEval;
-
-    int m_captureStart;
-    int m_captureEnd;
+    struct TypeProfilingRareData {
+        UniqueIDMap m_uniqueIDMap;
+        OffsetToVariableMap m_offsetToVariableMap;
+        UniqueTypeSetMap m_uniqueTypeSetMap;
+    };
+    std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
 
-    std::unique_ptr<SlowArgument[]> m_slowArguments;
+    bool m_usesNonStrictEval;
+    
+    WriteBarrier<ScopedArgumentsTable> m_arguments;
+    WriteBarrier<InferredValue> m_singletonScope;
     
-    std::unique_ptr<WatchpointCleanup> m_watchpointCleanup;
+    std::unique_ptr<LocalToEntryVec> m_localToEntry;
 
 public:
-    InlineWatchpointSet m_functionEnteredOnce;
-    
     mutable ConcurrentJITLock m_lock;
 };
 
diff --git a/runtime/TemplateRegistry.cpp b/runtime/TemplateRegistry.cpp
new file mode 100644 (file)
index 0000000..7bdac38
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TemplateRegistry.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "StructureInlines.h"
+#include "WeakGCMapInlines.h"
+
+namespace JSC {
+
+TemplateRegistry::TemplateRegistry(VM& vm)
+    : m_templateMap(vm)
+{
+}
+
+JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, const TemplateRegistryKey& templateKey)
+{
+    JSArray* cached = m_templateMap.get(templateKey);
+    if (cached)
+        return cached;
+
+    unsigned count = templateKey.cookedStrings().size();
+    JSArray* templateObject = constructEmptyArray(exec, nullptr, count);
+    JSArray* rawObject = constructEmptyArray(exec, nullptr, count);
+
+    for (unsigned index = 0; index < count; ++index) {
+        templateObject->putDirectIndex(exec, index, jsString(exec, templateKey.cookedStrings()[index]), ReadOnly | DontDelete, PutDirectIndexLikePutDirect);
+        rawObject->putDirectIndex(exec, index, jsString(exec, templateKey.rawStrings()[index]), ReadOnly | DontDelete, PutDirectIndexLikePutDirect);
+    }
+
+    objectConstructorFreeze(exec, rawObject);
+    ASSERT(!exec->hadException());
+
+    templateObject->putDirect(exec->vm(), exec->propertyNames().raw, rawObject, ReadOnly | DontEnum | DontDelete);
+
+    objectConstructorFreeze(exec, templateObject);
+    ASSERT(!exec->hadException());
+
+    m_templateMap.set(templateKey, templateObject);
+
+    return templateObject;
+}
+
+
+} // namespace JSC
diff --git a/runtime/TemplateRegistry.h b/runtime/TemplateRegistry.h
new file mode 100644 (file)
index 0000000..9cb62dd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TemplateRegistry_h
+#define TemplateRegistry_h
+
+#include "JSArray.h"
+#include "TemplateRegistryKey.h"
+#include "WeakGCMap.h"
+#include <limits>
+
+namespace JSC {
+
+class TemplateRegistry {
+public:
+    TemplateRegistry(VM&);
+
+    JSArray* getTemplateObject(ExecState*, const TemplateRegistryKey&);
+
+private:
+    WeakGCMap<TemplateRegistryKey, JSArray> m_templateMap;
+};
+
+} // namespace JSC
+
+#endif // TemplateRegistry_h
diff --git a/runtime/TemplateRegistryKey.h b/runtime/TemplateRegistryKey.h
new file mode 100644 (file)
index 0000000..17d8828
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TemplateRegistryKey_h
+#define TemplateRegistryKey_h
+
+#include <limits>
+#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class TemplateRegistryKey {
+public:
+    typedef Vector<String, 4> StringVector;
+
+    TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings);
+    enum DeletedValueTag { DeletedValue };
+    TemplateRegistryKey(DeletedValueTag);
+    enum EmptyValueTag { EmptyValue };
+    TemplateRegistryKey(EmptyValueTag);
+
+    bool isDeletedValue() const { return m_rawStrings.isEmpty() && m_hash == std::numeric_limits<unsigned>::max(); }
+
+    bool isEmptyValue() const { return m_rawStrings.isEmpty() && !m_hash; }
+
+    unsigned hash() const { return m_hash; }
+
+    const StringVector& rawStrings() const { return m_rawStrings; }
+    const StringVector& cookedStrings() const { return m_cookedStrings; }
+
+    bool operator==(const TemplateRegistryKey& other) const { return m_hash == other.m_hash && m_rawStrings == other.m_rawStrings; }
+    bool operator!=(const TemplateRegistryKey& other) const { return m_hash != other.m_hash || m_rawStrings != other.m_rawStrings; }
+
+    struct Hasher {
+        static unsigned hash(const TemplateRegistryKey& key) { return key.hash(); }
+        static bool equal(const TemplateRegistryKey& a, const TemplateRegistryKey& b) { return a == b; }
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+private:
+    StringVector m_rawStrings;
+    StringVector m_cookedStrings;
+    unsigned m_hash { 0 };
+};
+
+inline TemplateRegistryKey::TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings)
+    : m_rawStrings(rawStrings)
+    , m_cookedStrings(cookedStrings)
+{
+    m_hash = 0;
+    for (const String& string : rawStrings)
+        m_hash += WTF::StringHash::hash(string);
+}
+
+inline TemplateRegistryKey::TemplateRegistryKey(DeletedValueTag)
+    : m_hash(std::numeric_limits<unsigned>::max())
+{
+}
+
+inline TemplateRegistryKey::TemplateRegistryKey(EmptyValueTag)
+    : m_hash(0)
+{
+}
+
+} // namespace JSC
+
+namespace WTF {
+template<typename T> struct DefaultHash;
+
+template<> struct DefaultHash<JSC::TemplateRegistryKey> {
+    typedef JSC::TemplateRegistryKey::Hasher Hash;
+};
+
+template<> struct HashTraits<JSC::TemplateRegistryKey> : CustomHashTraits<JSC::TemplateRegistryKey> {
+};
+
+} // namespace WTF
+
+#endif // TemplateRegistryKey_h
index 45e33855ce8c32631b7b4bc3f07fae1b4d2a1808..ffb8438970ea79a998e3bf7fa30e6980503aeb63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +45,9 @@ JS_EXPORT_PRIVATE JSValue setNeverInline(ExecState*);
 JS_EXPORT_PRIVATE JSValue optimizeNextInvocation(ExecState*);
 
 JS_EXPORT_PRIVATE unsigned numberOfExceptionFuzzChecks();
+JS_EXPORT_PRIVATE unsigned numberOfExecutableAllocationFuzzChecks();
+JS_EXPORT_PRIVATE unsigned numberOfStaticOSRExitFuzzChecks();
+JS_EXPORT_PRIVATE unsigned numberOfOSRExitFuzzChecks();
 
 } // namespace JSC
 
index da854b99090ccd6594e2d8b789f1e146baa07454..ec13625d8905c9f917efac47d818b24acb44279b 100644 (file)
@@ -28,9 +28,9 @@ provider JavaScriptCore
     probe gc__begin();
     probe gc__marked();
     probe gc__end();
-    
-    probe profile__will_execute(int, char*, char*, int);
-    probe profile__did_execute(int, char*, char*, int);
+
+    probe profile__will_execute(int, char*, char*, int, int);
+    probe profile__did_execute(int, char*, char*, int, int);
 };
 
 #pragma D attributes Unstable/Unstable/Common provider JavaScriptCore provider
index c28c85f614270e44ea6a9da96c541390d8602a6c..69ead921c33a90a278e893943cc09c78fe5a5a25 100644 (file)
 #define JAVASCRIPTCORE_GC_MARKED()
 #define JAVASCRIPTCORE_GC_MARKED_ENABLED() 0
 
-#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(arg0, arg1, arg2, arg3)
+#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(arg0, arg1, arg2, arg3, arg4)
 #define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED() 0
 
-#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE(arg0, arg1, arg2, arg3)
+#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE(arg0, arg1, arg2, arg3, arg4)
 #define JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED() 0
 
 #endif
diff --git a/runtime/TypeLocationCache.cpp b/runtime/TypeLocationCache.cpp
new file mode 100644 (file)
index 0000000..4c8069a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "TypeLocationCache.h"
+
+#include "TypeProfiler.h"
+#include "VM.h"
+
+namespace JSC {
+
+std::pair<TypeLocation*, bool> TypeLocationCache::getTypeLocation(GlobalVariableID globalVariableID, intptr_t sourceID, unsigned start, unsigned end, PassRefPtr<TypeSet> globalTypeSet, VM* vm)
+{
+    LocationKey key;
+    key.m_globalVariableID = globalVariableID;
+    key.m_sourceID = sourceID;
+    key.m_start = start;
+    key.m_end = end;
+
+    bool isNewLocation = false;
+    if (m_locationMap.find(key) == m_locationMap.end()) {
+        ASSERT(vm->typeProfiler());
+        TypeLocation* location = vm->typeProfiler()->nextTypeLocation();
+        location->m_globalVariableID = globalVariableID;
+        location->m_sourceID = sourceID;
+        location->m_divotStart = start;
+        location->m_divotEnd = end;
+        location->m_globalTypeSet = globalTypeSet;
+
+        m_locationMap[key] = location;
+        isNewLocation = true;
+    }
+
+    TypeLocation* location = m_locationMap.find(key)->second;
+    return std::pair<TypeLocation*, bool>(location, isNewLocation);
+}
+
+} // namespace JSC
diff --git a/runtime/TypeLocationCache.h b/runtime/TypeLocationCache.h
new file mode 100644 (file)
index 0000000..9f85666
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeLocationCache_h
+#define TypeLocationCache_h
+
+#include "TypeLocation.h"
+#include <unordered_map>
+#include <wtf/HashMethod.h>
+
+namespace JSC {
+
+class VM;
+
+class TypeLocationCache {
+public:
+    struct LocationKey {
+        LocationKey() {}
+        bool operator==(const LocationKey& other) const 
+        {
+            return m_globalVariableID == other.m_globalVariableID
+                && m_sourceID == other.m_sourceID
+                && m_start == other.m_start
+                && m_end == other.m_end;
+        }
+
+        unsigned hash() const
+        {
+            return m_globalVariableID + m_sourceID + m_start + m_end;
+        }
+
+        GlobalVariableID m_globalVariableID;
+        intptr_t m_sourceID;
+        unsigned m_start;
+        unsigned m_end;
+    };
+
+    std::pair<TypeLocation*, bool> getTypeLocation(GlobalVariableID, intptr_t, unsigned start, unsigned end, PassRefPtr<TypeSet>, VM*);
+private:     
+    typedef std::unordered_map<LocationKey, TypeLocation*, HashMethod<LocationKey>> LocationMap;
+    LocationMap m_locationMap;
+};
+
+} // namespace JSC
+
+#endif // TypeLocationCache_h
diff --git a/runtime/TypeProfiler.cpp b/runtime/TypeProfiler.cpp
new file mode 100644 (file)
index 0000000..338a1c2
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TypeProfiler.h"
+
+#include "InspectorProtocolObjects.h"
+#include "TypeLocation.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace JSC {
+
+static const bool verbose = false;
+
+TypeProfiler::TypeProfiler()
+    : m_nextUniqueVariableID(1)
+{ 
+}
+
+void TypeProfiler::logTypesForTypeLocation(TypeLocation* location, VM& vm)
+{
+    TypeProfilerSearchDescriptor descriptor = location->m_globalVariableID == TypeProfilerReturnStatement ? TypeProfilerSearchDescriptorFunctionReturn : TypeProfilerSearchDescriptorNormal;
+
+    dataLogF("[Start, End]::[%u, %u]\n", location->m_divotStart, location->m_divotEnd);
+
+    if (findLocation(location->m_divotStart, location->m_sourceID, descriptor, vm))
+        dataLog("\t\t[Entry IS in System]\n");
+    else
+        dataLog("\t\t[Entry IS NOT in system]\n");
+
+    dataLog("\t\t", location->m_globalVariableID == TypeProfilerReturnStatement ? "[Return Statement]" : "[Normal Statement]", "\n");
+
+    dataLog("\t\t#Local#\n\t\t", location->m_instructionTypeSet->dumpTypes().replace("\n", "\n\t\t"), "\n");
+    if (location->m_globalTypeSet)
+        dataLog("\t\t#Global#\n\t\t", location->m_globalTypeSet->dumpTypes().replace("\n", "\n\t\t"), "\n");
+}
+
+void TypeProfiler::insertNewLocation(TypeLocation* location)
+{
+    if (verbose)
+        dataLogF("Registering location:: divotStart:%u, divotEnd:%u\n", location->m_divotStart, location->m_divotEnd);
+
+    if (!m_bucketMap.contains(location->m_sourceID)) {
+        Vector<TypeLocation*> bucket;
+        m_bucketMap.set(location->m_sourceID, bucket);
+    }
+
+    Vector<TypeLocation*>& bucket = m_bucketMap.find(location->m_sourceID)->value;
+    bucket.append(location);
+}
+
+String TypeProfiler::typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptor descriptor, unsigned offset, intptr_t sourceID, VM& vm)
+{
+    // This returns a JSON string representing an Object with the following properties:
+    //     globalTypeSet: 'JSON<TypeSet> | null'
+    //     instructionTypeSet: 'JSON<TypeSet>'
+
+    TypeLocation* location = findLocation(offset, sourceID, descriptor, vm);
+    ASSERT(location);
+
+    StringBuilder json;  
+
+    json.append('{');
+
+    json.appendLiteral("\"globalTypeSet\":");
+    if (location->m_globalTypeSet && location->m_globalVariableID != TypeProfilerNoGlobalIDExists)
+        json.append(location->m_globalTypeSet->toJSONString());
+    else
+        json.appendLiteral("null");
+    json.append(',');
+
+    json.appendLiteral("\"instructionTypeSet\":");
+    json.append(location->m_instructionTypeSet->toJSONString());
+    json.append(',');
+
+    json.appendLiteral("\"isOverflown\":");
+    if (location->m_instructionTypeSet->isOverflown() || (location->m_globalTypeSet && location->m_globalTypeSet->isOverflown()))
+        json.appendLiteral("true");
+    else
+        json.appendLiteral("false");
+
+    json.append('}');
+    
+    return json.toString();
+}
+
+TypeLocation* TypeProfiler::findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor, VM& vm)
+{
+    QueryKey queryKey(sourceID, divot);
+    auto iter = m_queryCache.find(queryKey);
+    if (iter != m_queryCache.end())
+        return iter->value;
+
+    if (!vm.functionHasExecutedCache()->hasExecutedAtOffset(sourceID, divot))
+        return nullptr;
+
+    if (!m_bucketMap.contains(sourceID))
+        return nullptr;
+
+    Vector<TypeLocation*>& bucket = m_bucketMap.find(sourceID)->value;
+    TypeLocation* bestMatch = nullptr;
+    unsigned distance = UINT_MAX; // Because assignments may be nested, make sure we find the closest enclosing assignment to this character offset.
+    for (size_t i = 0, size = bucket.size(); i < size; i++) {
+        TypeLocation* location = bucket.at(i);
+        // We found the type location that correlates to the convergence of all return statements in a function.
+        // This text offset is the offset of the opening brace in a function declaration.
+        if (descriptor == TypeProfilerSearchDescriptorFunctionReturn && location->m_globalVariableID == TypeProfilerReturnStatement && location->m_divotForFunctionOffsetIfReturnStatement == divot)
+            return location;
+
+        if (descriptor != TypeProfilerSearchDescriptorFunctionReturn && location->m_divotStart <= divot && divot <= location->m_divotEnd && location->m_divotEnd - location->m_divotStart <= distance) {
+            distance = location->m_divotEnd - location->m_divotStart;
+            bestMatch = location;
+        }
+    }
+
+    if (bestMatch)
+        m_queryCache.set(queryKey, bestMatch);
+    // FIXME: BestMatch should never be null past this point. This doesn't hold currently because we ignore var assignments when code contains eval/With (VarInjection). 
+    // https://bugs.webkit.org/show_bug.cgi?id=135184
+    return bestMatch;
+}
+
+TypeLocation* TypeProfiler::nextTypeLocation() 
+{ 
+    return m_typeLocationInfo.add(); 
+}
+
+void TypeProfiler::invalidateTypeSetCache()
+{
+    for (Bag<TypeLocation>::iterator iter = m_typeLocationInfo.begin(); !!iter; ++iter) {
+        TypeLocation* location = *iter;
+        location->m_instructionTypeSet->invalidateCache();
+        if (location->m_globalTypeSet)
+            location->m_globalTypeSet->invalidateCache();
+    }
+}
+
+void TypeProfiler::dumpTypeProfilerData(VM& vm)
+{
+    for (Bag<TypeLocation>::iterator iter = m_typeLocationInfo.begin(); !!iter; ++iter) {
+        TypeLocation* location = *iter;
+        logTypesForTypeLocation(location, vm);
+    }
+}
+
+} // namespace JSC
diff --git a/runtime/TypeProfiler.h b/runtime/TypeProfiler.h
new file mode 100644 (file)
index 0000000..34f1b8d
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeProfiler_h
+#define TypeProfiler_h
+
+#include "CodeBlock.h"
+#include "TypeLocation.h"
+#include "TypeLocationCache.h"
+#include <wtf/Bag.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector { namespace Protocol  { namespace Runtime {
+class TypeDescription;
+}}}
+
+namespace JSC {
+
+struct QueryKey {
+    QueryKey()
+        : m_sourceID(0)
+        , m_divot(0)
+    { }
+
+    QueryKey(intptr_t sourceID, unsigned divot)
+        : m_sourceID(sourceID)
+        , m_divot(divot)
+    { }
+
+    QueryKey(WTF::HashTableDeletedValueType)
+        : m_sourceID(INTPTR_MAX)
+        , m_divot(UINT_MAX)
+    { }
+
+    bool isHashTableDeletedValue() const { return m_sourceID == INTPTR_MAX && m_divot == UINT_MAX; }
+    bool operator==(const QueryKey& other) const { return m_sourceID == other.m_sourceID && m_divot == other.m_divot; }
+    unsigned hash() const { return m_sourceID + m_divot; }
+
+    intptr_t m_sourceID;
+    unsigned m_divot;
+};
+
+struct QueryKeyHash {
+    static unsigned hash(const QueryKey& key) { return key.hash(); }
+    static bool equal(const QueryKey& a, const QueryKey& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::QueryKey> {
+    typedef JSC::QueryKeyHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::QueryKey> : SimpleClassHashTraits<JSC::QueryKey> { };
+
+} // namespace WTF
+
+namespace JSC {
+
+class VM;
+
+enum TypeProfilerSearchDescriptor {
+    TypeProfilerSearchDescriptorNormal = 1,
+    TypeProfilerSearchDescriptorFunctionReturn = 2
+};
+
+class TypeProfiler {
+public:
+    TypeProfiler();
+    void logTypesForTypeLocation(TypeLocation*, VM&);
+    JS_EXPORT_PRIVATE String typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptor, unsigned offset, intptr_t sourceID, VM&);
+    void insertNewLocation(TypeLocation*);
+    TypeLocationCache* typeLocationCache() { return &m_typeLocationCache; }
+    TypeLocation* findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor, VM&);
+    GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
+    TypeLocation* nextTypeLocation();
+    void invalidateTypeSetCache();
+    void dumpTypeProfilerData(VM&);
+    
+private:
+    typedef HashMap<intptr_t, Vector<TypeLocation*>> SourceIDToLocationBucketMap;
+    SourceIDToLocationBucketMap m_bucketMap;
+    TypeLocationCache m_typeLocationCache;
+    typedef HashMap<QueryKey, TypeLocation*> TypeLocationQueryCache;
+    TypeLocationQueryCache m_queryCache;
+    GlobalVariableID m_nextUniqueVariableID;
+    Bag<TypeLocation> m_typeLocationInfo;
+};
+
+} // namespace JSC
+
+#endif // TypeProfiler_h
diff --git a/runtime/TypeProfilerLog.cpp b/runtime/TypeProfilerLog.cpp
new file mode 100644 (file)
index 0000000..9d10aae
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TypeProfilerLog.h"
+
+#include "JSCJSValueInlines.h"
+#include "TypeLocation.h"
+#include <wtf/CurrentTime.h>
+
+
+namespace JSC {
+
+static const bool verbose = false;
+
+void TypeProfilerLog::initializeLog()
+{
+    ASSERT(!m_logStartPtr);
+    m_logSize = 50000;
+    m_logStartPtr = new LogEntry[m_logSize];
+    m_currentLogEntryPtr = m_logStartPtr;
+    m_logEndPtr = m_logStartPtr + m_logSize;
+}
+
+TypeProfilerLog::~TypeProfilerLog()
+{
+    delete[] m_logStartPtr;
+}
+
+void TypeProfilerLog::processLogEntries(const String& reason)
+{
+    double before = 0;
+    if (verbose) {
+        dataLog("Process caller:'", reason, "'");
+        before = currentTimeMS();
+    }
+
+    LogEntry* entry = m_logStartPtr;
+    HashMap<Structure*, RefPtr<StructureShape>> seenShapes;
+    while (entry != m_currentLogEntryPtr) {
+        StructureID id = entry->structureID;
+        RefPtr<StructureShape> shape; 
+        JSValue value = entry->value;
+        Structure* structure = nullptr;
+        if (id) {
+            structure = Heap::heap(value.asCell())->structureIDTable().get(id); 
+            auto iter = seenShapes.find(structure);
+            if (iter == seenShapes.end()) {
+                shape = structure->toStructureShape(value);
+                seenShapes.set(structure, shape);
+            } else
+                shape = iter->value;
+        }
+
+        RuntimeType type = runtimeTypeForValue(value);
+        TypeLocation* location = entry->location;
+        location->m_lastSeenType = type;
+        if (location->m_globalTypeSet)
+            location->m_globalTypeSet->addTypeInformation(type, shape, structure);
+        location->m_instructionTypeSet->addTypeInformation(type, shape, structure);
+
+        entry++;
+    }
+
+    m_currentLogEntryPtr = m_logStartPtr;
+
+    if (verbose) {
+        double after = currentTimeMS();
+        dataLogF(" Processing the log took: '%f' ms\n", after - before);
+    }
+}
+
+} // namespace JSC
diff --git a/runtime/TypeProfilerLog.h b/runtime/TypeProfilerLog.h
new file mode 100644 (file)
index 0000000..46eeaec
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeProfilerLog_h
+#define TypeProfilerLog_h
+
+#include "JSCJSValue.h"
+#include "Structure.h"
+#include "TypeProfiler.h"
+#include <wtf/ByteSpinLock.h>
+
+namespace JSC {
+
+class TypeLocation;
+
+class TypeProfilerLog {
+
+public:
+    struct LogEntry {
+    public:
+        friend class LLIntOffsetsExtractor;
+
+        JSValue value;
+        TypeLocation* location; 
+        StructureID structureID;
+
+        static ptrdiff_t structureIDOffset() { return OBJECT_OFFSETOF(LogEntry, structureID); }
+        static ptrdiff_t valueOffset() { return OBJECT_OFFSETOF(LogEntry, value); }
+        static ptrdiff_t locationOffset() { return OBJECT_OFFSETOF(LogEntry, location); }
+    };
+
+
+    TypeProfilerLog()
+        : m_logStartPtr(0)
+    {
+        initializeLog();
+    }
+
+    ~TypeProfilerLog();
+
+    JS_EXPORT_PRIVATE void processLogEntries(const String&);
+    LogEntry* logEndPtr() const { return m_logEndPtr; }
+
+    static ptrdiff_t logStartOffset() { return OBJECT_OFFSETOF(TypeProfilerLog, m_logStartPtr); }
+    static ptrdiff_t currentLogEntryOffset() { return OBJECT_OFFSETOF(TypeProfilerLog, m_currentLogEntryPtr); }
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    void initializeLog();
+
+    unsigned m_logSize;
+    LogEntry* m_logStartPtr;
+    LogEntry* m_currentLogEntryPtr;
+    LogEntry* m_logEndPtr;
+};
+
+} // namespace JSC
+
+#endif // TypeProfilerLog_h
diff --git a/runtime/TypeSet.cpp b/runtime/TypeSet.cpp
new file mode 100644 (file)
index 0000000..a436cda
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TypeSet.h"
+
+#include "InspectorProtocolObjects.h"
+#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+TypeSet::TypeSet()
+    : m_seenTypes(TypeNothing)
+    , m_isOverflown(false)
+{
+}
+
+void TypeSet::addTypeInformation(RuntimeType type, PassRefPtr<StructureShape> prpNewShape, Structure* structure) 
+{
+    RefPtr<StructureShape> newShape = prpNewShape;
+    m_seenTypes = m_seenTypes | type;
+
+    if (structure && newShape && !runtimeTypeIsPrimitive(type)) {
+        if (!m_structureSet.contains(structure)) {
+            m_structureSet.add(structure);
+            // Make one more pass making sure that: 
+            // - We don't have two instances of the same shape. (Same shapes may have different Structures).
+            // - We don't have two shapes that share the same prototype chain. If these shapes share the same 
+            //   prototype chain, they will be merged into one shape.
+            bool found = false;
+            String hash = newShape->propertyHash();
+            for (size_t i = 0; i < m_structureHistory.size(); i++) {
+                RefPtr<StructureShape>& seenShape = m_structureHistory.at(i);
+                if (seenShape->propertyHash() == hash) {
+                    found = true;
+                    break;
+                } 
+                if (seenShape->hasSamePrototypeChain(newShape)) {
+                    seenShape = StructureShape::merge(seenShape, newShape);
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found) {
+                if (m_structureHistory.size() < 100)
+                    m_structureHistory.append(newShape);
+                else if (!m_isOverflown)
+                    m_isOverflown = true;
+            }
+        }
+    }
+}
+
+void TypeSet::invalidateCache()
+{
+    auto keepMarkedStructuresFilter = [] (Structure* structure) -> bool { return Heap::isMarked(structure); };
+    m_structureSet.genericFilter(keepMarkedStructuresFilter);
+}
+
+String TypeSet::dumpTypes() const
+{
+    if (m_seenTypes == TypeNothing)
+        return ASCIILiteral("(Unreached Statement)");
+
+    StringBuilder seen;
+
+    if (m_seenTypes & TypeFunction)
+        seen.appendLiteral("Function ");
+    if (m_seenTypes & TypeUndefined)
+        seen.appendLiteral("Undefined ");
+    if (m_seenTypes & TypeNull)
+        seen.appendLiteral("Null ");
+    if (m_seenTypes & TypeBoolean)
+        seen.appendLiteral("Boolean ");
+    if (m_seenTypes & TypeMachineInt)
+        seen.appendLiteral("MachineInt ");
+    if (m_seenTypes & TypeNumber)
+        seen.appendLiteral("Number ");
+    if (m_seenTypes & TypeString)
+        seen.appendLiteral("String ");
+    if (m_seenTypes & TypeObject)
+        seen.appendLiteral("Object ");
+    if (m_seenTypes & TypeSymbol)
+        seen.appendLiteral("Symbol ");
+
+    for (size_t i = 0; i < m_structureHistory.size(); i++) {
+        RefPtr<StructureShape> shape = m_structureHistory.at(i);
+        seen.append(shape->m_constructorName);
+        seen.append(' ');
+    }
+
+    if (m_structureHistory.size()) 
+        seen.appendLiteral("\nStructures:[ ");
+    for (size_t i = 0; i < m_structureHistory.size(); i++) {
+        seen.append(m_structureHistory.at(i)->stringRepresentation());
+        seen.append(' ');
+    }
+    if (m_structureHistory.size())
+        seen.append(']');
+
+    if (m_structureHistory.size()) {
+        seen.appendLiteral("\nLeast Common Ancestor: ");
+        seen.append(leastCommonAncestor());
+    }
+
+    return seen.toString();
+}
+
+bool TypeSet::doesTypeConformTo(RuntimeTypeMask test) const
+{
+    // This function checks if our seen types conform  to the types described by the test bitstring. (i.e we haven't seen more types than test).
+    // We are <= to those types if ANDing with the bitstring doesn't zero out any of our bits.
+
+    // For example:
+
+    // 0b0110 (seen)
+    // 0b1111 (test)
+    // ------ (AND)
+    // 0b0110 == seen
+
+    // 0b0110 (seen)
+    // 0b0010 (test)
+    // ------ (AND)
+    // 0b0010 != seen
+
+    return m_seenTypes != TypeNothing && (m_seenTypes & test) == m_seenTypes;
+}
+
+String TypeSet::displayName() const
+{
+    if (m_seenTypes == TypeNothing)
+        return emptyString();
+
+    if (m_structureHistory.size() && doesTypeConformTo(TypeObject | TypeNull | TypeUndefined)) {
+        String ctorName = leastCommonAncestor(); 
+
+        if (doesTypeConformTo(TypeObject))
+            return ctorName;
+        if (doesTypeConformTo(TypeObject | TypeNull | TypeUndefined))
+            return ctorName + '?';
+    }
+
+    // The order of these checks are important. For example, if a value is only a function, it conforms to TypeFunction, but it also conforms to TypeFunction | TypeNull.
+    // Therefore, more specific types must be checked first.
+
+    if (doesTypeConformTo(TypeFunction))
+        return ASCIILiteral("Function");
+    if (doesTypeConformTo(TypeUndefined))
+        return ASCIILiteral("Undefined");
+    if (doesTypeConformTo(TypeNull))
+        return ASCIILiteral("Null");
+    if (doesTypeConformTo(TypeBoolean))
+        return ASCIILiteral("Boolean");
+    if (doesTypeConformTo(TypeMachineInt))
+        return ASCIILiteral("Integer");
+    if (doesTypeConformTo(TypeNumber | TypeMachineInt))
+        return ASCIILiteral("Number");
+    if (doesTypeConformTo(TypeString))
+        return ASCIILiteral("String");
+    if (doesTypeConformTo(TypeSymbol))
+        return ASCIILiteral("Symbol");
+
+    if (doesTypeConformTo(TypeNull | TypeUndefined))
+        return ASCIILiteral("(?)");
+
+    if (doesTypeConformTo(TypeFunction | TypeNull | TypeUndefined))
+        return ASCIILiteral("Function?");
+    if (doesTypeConformTo(TypeBoolean | TypeNull | TypeUndefined))
+        return ASCIILiteral("Boolean?");
+    if (doesTypeConformTo(TypeMachineInt | TypeNull | TypeUndefined))
+        return ASCIILiteral("Integer?");
+    if (doesTypeConformTo(TypeNumber | TypeMachineInt | TypeNull | TypeUndefined))
+        return ASCIILiteral("Number?");
+    if (doesTypeConformTo(TypeString | TypeNull | TypeUndefined))
+        return ASCIILiteral("String?");
+    if (doesTypeConformTo(TypeSymbol | TypeNull | TypeUndefined))
+        return ASCIILiteral("Symbol?");
+   
+    if (doesTypeConformTo(TypeObject | TypeFunction | TypeString))
+        return ASCIILiteral("Object");
+    if (doesTypeConformTo(TypeObject | TypeFunction | TypeString | TypeNull | TypeUndefined))
+        return ASCIILiteral("Object?");
+
+    return ASCIILiteral("(many)");
+}
+
+String TypeSet::leastCommonAncestor() const
+{
+    return StructureShape::leastCommonAncestor(m_structureHistory);
+}
+
+Ref<Inspector::Protocol::Array<Inspector::Protocol::Runtime::StructureDescription>> TypeSet::allStructureRepresentations() const
+{
+    auto description = Inspector::Protocol::Array<Inspector::Protocol::Runtime::StructureDescription>::create();
+
+    for (size_t i = 0; i < m_structureHistory.size(); i++)
+        description->addItem(m_structureHistory.at(i)->inspectorRepresentation());
+
+    return WTF::move(description);
+}
+
+Ref<Inspector::Protocol::Runtime::TypeSet> TypeSet::inspectorTypeSet() const
+{
+    return Inspector::Protocol::Runtime::TypeSet::create()
+        .setIsFunction((m_seenTypes & TypeFunction) != TypeNothing)
+        .setIsUndefined((m_seenTypes & TypeUndefined) != TypeNothing)
+        .setIsNull((m_seenTypes & TypeNull) != TypeNothing)
+        .setIsBoolean((m_seenTypes & TypeBoolean) != TypeNothing)
+        .setIsInteger((m_seenTypes & TypeMachineInt) != TypeNothing)
+        .setIsNumber((m_seenTypes & TypeNumber) != TypeNothing)
+        .setIsString((m_seenTypes & TypeString) != TypeNothing)
+        .setIsObject((m_seenTypes & TypeObject) != TypeNothing)
+        .setIsSymbol((m_seenTypes & TypeSymbol) != TypeNothing)
+        .release();
+}
+
+String TypeSet::toJSONString() const
+{
+    // This returns a JSON string representing an Object with the following properties:
+    //     displayTypeName: 'String'
+    //     primitiveTypeNames: 'Array<String>'
+    //     structures: 'Array<JSON<StructureShape>>'
+
+    StringBuilder json;
+    json.append('{');
+
+    json.appendLiteral("\"displayTypeName\":");
+    json.append('"');
+    json.append(displayName());
+    json.append('"');
+    json.append(',');
+
+    json.appendLiteral("\"primitiveTypeNames\":");
+    json.append('[');
+    bool hasAnItem = false;
+    if (m_seenTypes & TypeUndefined) {
+        hasAnItem = true;
+        json.appendLiteral("\"Undefined\"");
+    }
+    if (m_seenTypes & TypeNull) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"Null\"");
+    }
+    if (m_seenTypes & TypeBoolean) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"Boolean\"");
+    }
+    if (m_seenTypes & TypeMachineInt) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"Integer\"");
+    }
+    if (m_seenTypes & TypeNumber) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"Number\"");
+    }
+    if (m_seenTypes & TypeString) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"String\"");
+    }
+    if (m_seenTypes & TypeSymbol) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.appendLiteral("\"Symbol\"");
+    }
+    json.append(']');
+
+    json.append(',');
+
+    json.appendLiteral("\"structures\":");
+    json.append('[');
+    hasAnItem = false;
+    for (size_t i = 0; i < m_structureHistory.size(); i++) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+        json.append(m_structureHistory[i]->toJSONString());
+    }
+    json.append(']');
+
+    json.append('}');
+    return json.toString();
+}
+
+StructureShape::StructureShape()
+    : m_proto(nullptr)
+    , m_propertyHash(nullptr)
+    , m_final(false)
+    , m_isInDictionaryMode(false)
+{
+}
+
+void StructureShape::markAsFinal()
+{
+    ASSERT(!m_final);
+    m_final = true;
+}
+
+void StructureShape::addProperty(UniquedStringImpl& uid)
+{
+    ASSERT(!m_final);
+    m_fields.add(&uid);
+}
+
+String StructureShape::propertyHash()
+{
+    ASSERT(m_final);
+    if (m_propertyHash)
+        return *m_propertyHash;
+
+    StringBuilder builder;
+    builder.append(':');
+    builder.append(m_constructorName);
+    builder.append(':');
+    for (auto& key : m_fields) {
+        String property = key.get();
+        property.replace(":", "\\:"); // Ensure that hash({"foo:", "bar"}) != hash({"foo", ":bar"}) because we're using colons as a separator and colons are legal characters in field names in JS.
+        builder.append(property);
+    }
+
+    if (m_proto) {
+        builder.append(':');
+        builder.appendLiteral("__proto__");
+        builder.append(m_proto->propertyHash());
+    }
+
+    m_propertyHash = std::make_unique<String>(builder.toString());
+    return *m_propertyHash;
+}
+
+String StructureShape::leastCommonAncestor(const Vector<RefPtr<StructureShape>> shapes)
+{
+    if (!shapes.size())
+        return emptyString();
+
+    RefPtr<StructureShape> origin = shapes.at(0);
+    for (size_t i = 1; i < shapes.size(); i++) {
+        bool foundLUB = false;
+        while (!foundLUB) {
+            RefPtr<StructureShape> check = shapes.at(i);
+            String curCtorName = origin->m_constructorName;
+            while (check) {
+                if (check->m_constructorName == curCtorName) {
+                    foundLUB = true;
+                    break;
+                }
+                check = check->m_proto;
+            }
+            if (!foundLUB) {
+                origin = origin->m_proto;
+                // All Objects must share the 'Object' Prototype. Therefore, at the very least, we should always converge on 'Object' before reaching a null prototype.
+                RELEASE_ASSERT(origin); 
+            }
+        }
+
+        if (origin->m_constructorName == "Object")
+            break;
+    }
+
+    return origin->m_constructorName;
+}
+
+String StructureShape::stringRepresentation()
+{
+    StringBuilder representation;
+    RefPtr<StructureShape> curShape = this;
+
+    representation.append('{');
+    while (curShape) {
+        for (auto it = curShape->m_fields.begin(), end = curShape->m_fields.end(); it != end; ++it) {
+            String prop((*it).get());
+            representation.append(prop);
+            representation.appendLiteral(", ");
+        }
+
+        if (curShape->m_proto) {
+            representation.appendLiteral("__proto__ [");
+            representation.append(curShape->m_proto->m_constructorName);
+            representation.appendLiteral("], ");
+        }
+
+        curShape = curShape->m_proto;
+    }
+
+    if (representation.length() >= 3)
+        representation.resize(representation.length() - 2);
+
+    representation.append('}');
+
+    return representation.toString();
+}
+
+String StructureShape::toJSONString() const
+{
+    // This returns a JSON string representing an Object with the following properties:
+    //     constructorName: 'String'
+    //     fields: 'Array<String>'
+    //     optionalFields: 'Array<String>'
+    //     proto: 'JSON<StructureShape> | null'
+
+    StringBuilder json;
+    json.append('{');
+
+    json.appendLiteral("\"constructorName\":");
+    json.append('"');
+    json.append(m_constructorName);
+    json.append('"');
+    json.append(',');
+
+    json.appendLiteral("\"isInDictionaryMode\":");
+    if (m_isInDictionaryMode)
+        json.appendLiteral("true");
+    else
+        json.appendLiteral("false");
+    json.append(',');
+
+    json.appendLiteral("\"fields\":");
+    json.append('[');
+    bool hasAnItem = false;
+    for (auto it = m_fields.begin(), end = m_fields.end(); it != end; ++it) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+
+        String fieldName((*it).get());
+        json.append('"');
+        json.append(fieldName);
+        json.append('"');
+    }
+    json.append(']');
+    json.append(',');
+
+    json.appendLiteral("\"optionalFields\":");
+    json.append('[');
+    hasAnItem = false;
+    for (auto it = m_optionalFields.begin(), end = m_optionalFields.end(); it != end; ++it) {
+        if (hasAnItem)
+            json.append(',');
+        hasAnItem = true;
+
+        String fieldName((*it).get());
+        json.append('"');
+        json.append(fieldName);
+        json.append('"');
+    }
+    json.append(']');
+    json.append(',');
+
+    json.appendLiteral("\"proto\":");
+    if (m_proto)
+        json.append(m_proto->toJSONString());
+    else
+        json.appendLiteral("null");
+
+    json.append('}');
+
+    return json.toString();
+}
+
+Ref<Inspector::Protocol::Runtime::StructureDescription> StructureShape::inspectorRepresentation()
+{
+    auto base = Inspector::Protocol::Runtime::StructureDescription::create().release();
+    Ref<Inspector::Protocol::Runtime::StructureDescription> currentObject = base.copyRef();
+    RefPtr<StructureShape> currentShape(this);
+
+    while (currentShape) {
+        auto fields = Inspector::Protocol::Array<String>::create();
+        auto optionalFields = Inspector::Protocol::Array<String>::create();
+        for (auto field : currentShape->m_fields)
+            fields->addItem(field.get());
+        for (auto field : currentShape->m_optionalFields)
+            optionalFields->addItem(field.get());
+
+        currentObject->setFields(&fields.get());
+        currentObject->setOptionalFields(&optionalFields.get());
+        currentObject->setConstructorName(currentShape->m_constructorName);
+        currentObject->setIsImprecise(currentShape->m_isInDictionaryMode);
+
+        if (currentShape->m_proto) {
+            auto nextObject = Inspector::Protocol::Runtime::StructureDescription::create().release();
+            currentObject->setPrototypeStructure(&nextObject.get());
+            currentObject = WTF::move(nextObject);
+        }
+
+        currentShape = currentShape->m_proto;
+    }
+
+    return WTF::move(base);
+}
+
+bool StructureShape::hasSamePrototypeChain(PassRefPtr<StructureShape> prpOther)
+{
+    RefPtr<StructureShape> self = this;
+    RefPtr<StructureShape> other = prpOther;
+    while (self && other) {
+        if (self->m_constructorName != other->m_constructorName)
+            return false;
+        self = self->m_proto;
+        other = other->m_proto;
+    }
+
+    return !self && !other;
+}
+
+PassRefPtr<StructureShape> StructureShape::merge(const PassRefPtr<StructureShape> prpA, const PassRefPtr<StructureShape> prpB)
+{
+    RefPtr<StructureShape> a = prpA;
+    RefPtr<StructureShape> b = prpB;
+    ASSERT(a->hasSamePrototypeChain(b));
+
+    RefPtr<StructureShape> merged = StructureShape::create();
+    for (auto field : a->m_fields) {
+        if (b->m_fields.contains(field))
+            merged->m_fields.add(field);
+        else
+            merged->m_optionalFields.add(field);
+    }
+
+    for (auto field : b->m_fields) {
+        if (!merged->m_fields.contains(field)) {
+            auto addResult = merged->m_optionalFields.add(field);
+            ASSERT_UNUSED(addResult, addResult.isNewEntry);
+        }
+    }
+
+    for (auto field : a->m_optionalFields)
+        merged->m_optionalFields.add(field);
+    for (auto field : b->m_optionalFields)
+        merged->m_optionalFields.add(field);
+
+    ASSERT(a->m_constructorName == b->m_constructorName);
+    merged->setConstructorName(a->m_constructorName);
+
+    if (a->m_proto) {
+        RELEASE_ASSERT(b->m_proto);
+        merged->setProto(StructureShape::merge(a->m_proto, b->m_proto));
+    }
+
+    merged->markAsFinal();
+
+    return merged.release();
+}
+
+void StructureShape::enterDictionaryMode()
+{
+    m_isInDictionaryMode = true;
+}
+
+} //namespace JSC
diff --git a/runtime/TypeSet.h b/runtime/TypeSet.h
new file mode 100644 (file)
index 0000000..eb29e6c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeSet_h
+#define TypeSet_h
+
+#include "RuntimeType.h"
+#include "StructureSet.h"
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/Vector.h>
+
+namespace Inspector {
+namespace Protocol  {
+template<typename T> class Array;
+
+namespace Runtime {
+class StructureDescription;
+class TypeSet;
+}
+
+}
+}
+
+namespace JSC {
+
+class StructureShape : public RefCounted<StructureShape> {
+    friend class TypeSet;
+
+public:
+    StructureShape();
+
+    static Ref<StructureShape> create() { return adoptRef(*new StructureShape); }
+    String propertyHash();
+    void markAsFinal();
+    void addProperty(UniquedStringImpl&);
+    String stringRepresentation();
+    String toJSONString() const;
+    Ref<Inspector::Protocol::Runtime::StructureDescription> inspectorRepresentation();
+    void setConstructorName(String name) { m_constructorName = (name.isEmpty() ? "Object" : name); }
+    String constructorName() { return m_constructorName; }
+    void setProto(PassRefPtr<StructureShape> shape) { m_proto = shape; }
+    void enterDictionaryMode();
+
+private:
+    static String leastCommonAncestor(const Vector<RefPtr<StructureShape>>);
+    static PassRefPtr<StructureShape> merge(const PassRefPtr<StructureShape>, const PassRefPtr<StructureShape>);
+    bool hasSamePrototypeChain(PassRefPtr<StructureShape>);
+
+    HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_fields;
+    HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_optionalFields;
+    RefPtr<StructureShape> m_proto;
+    std::unique_ptr<String> m_propertyHash;
+    String m_constructorName;
+    bool m_final;
+    bool m_isInDictionaryMode;
+};
+
+class TypeSet : public RefCounted<TypeSet> {
+
+public:
+    static Ref<TypeSet> create() { return adoptRef(*new TypeSet); }
+    TypeSet();
+    void addTypeInformation(RuntimeType, PassRefPtr<StructureShape>, Structure*);
+    void invalidateCache();
+    String dumpTypes() const;
+    String displayName() const;
+    Ref<Inspector::Protocol::Array<Inspector::Protocol::Runtime::StructureDescription>> allStructureRepresentations() const;
+    String toJSONString() const;
+    bool isOverflown() const { return m_isOverflown; }
+    String leastCommonAncestor() const;
+    Ref<Inspector::Protocol::Runtime::TypeSet> inspectorTypeSet() const;
+    bool isEmpty() const { return m_seenTypes == TypeNothing; }
+    bool doesTypeConformTo(RuntimeTypeMask test) const;
+    RuntimeTypeMask seenTypes() const { return m_seenTypes; }
+    StructureSet structureSet() const { return m_structureSet; };
+
+private:
+    RuntimeTypeMask m_seenTypes;
+    bool m_isOverflown;
+    Vector<RefPtr<StructureShape>> m_structureHistory;
+    StructureSet m_structureSet;
+};
+
+} //namespace JSC
+
+#endif //TypeSet_h
index 8694b551609d945d94476fd18586175403351f8a..ee2746d78d83600e7e21feb5b6be19ff0a5ed89a 100644 (file)
@@ -94,7 +94,7 @@ protected:
         RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(T));
         if (!buffer.get())
             return 0;
-        return create<Subclass>(buffer, 0, length);
+        return create<Subclass>(buffer.release(), 0, length);
     }
 
     template <class Subclass>
@@ -104,30 +104,30 @@ protected:
         if (a)
             for (unsigned i = 0; i < length; ++i)
                 a->set(i, array[i]);
-        return a;
+        return a.release();
     }
 
     template <class Subclass>
-    static PassRefPtr<Subclass> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+    static RefPtr<Subclass> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     {
         RefPtr<ArrayBuffer> buf(buffer);
         if (!verifySubRange<T>(buf, byteOffset, length))
-            return 0;
+            return nullptr;
 
-        return adoptRef(new Subclass(buf, byteOffset, length));
+        return adoptRef(new Subclass(buf.release(), byteOffset, length));
     }
 
     template <class Subclass>
-    static PassRefPtr<Subclass> createUninitialized(unsigned length)
+    static RefPtr<Subclass> createUninitialized(unsigned length)
     {
         RefPtr<ArrayBuffer> buffer = ArrayBuffer::createUninitialized(length, sizeof(T));
         if (!buffer.get())
-            return 0;
-        return create<Subclass>(buffer, 0, length);
+            return nullptr;
+        return create<Subclass>(buffer.release(), 0, length);
     }
 
     template <class Subclass>
-    PassRefPtr<Subclass> subarrayImpl(int start, int end) const
+    RefPtr<Subclass> subarrayImpl(int start, int end) const
     {
         unsigned offset, length;
         calculateOffsetAndLength(start, end, m_length, &offset, &length);
diff --git a/runtime/TypeofType.cpp b/runtime/TypeofType.cpp
new file mode 100644 (file)
index 0000000..db162b7
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "TypeofType.h"
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, TypeofType type)
+{
+    switch (type) {
+    case TypeofType::Undefined:
+        out.print("undefined");
+        return;
+    case TypeofType::Boolean:
+        out.print("boolean");
+        return;
+    case TypeofType::Number:
+        out.print("number");
+        return;
+    case TypeofType::String:
+        out.print("string");
+        return;
+    case TypeofType::Symbol:
+        out.print("symbol");
+        return;
+    case TypeofType::Object:
+        out.print("object");
+        return;
+    case TypeofType::Function:
+        out.print("function");
+        return;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
diff --git a/runtime/TypeofType.h b/runtime/TypeofType.h
new file mode 100644 (file)
index 0000000..3eb78d4
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef TypeofType_h
+#define TypeofType_h
+
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+enum class TypeofType {
+    Undefined,
+    Boolean,
+    Number,
+    String,
+    Symbol,
+    Object,
+    Function    
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::TypeofType);
+
+} // namespace WTF
+
+#endif // TypeofType_h
+
index fdfc06ee5cf0041b14535cbca7022bb5ee1de9d3..76741dd8aea37ff57cca4cf636bfc32bb429cc41 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,8 +40,9 @@
 #include "CustomGetterSetter.h"
 #include "DFGLongLivedState.h"
 #include "DFGWorklist.h"
-#include "DebuggerActivation.h"
+#include "Disassembler.h"
 #include "ErrorInstance.h"
+#include "Exception.h"
 #include "FTLThunks.h"
 #include "FunctionConstructor.h"
 #include "GCActivityCallback.h"
 #include "Interpreter.h"
 #include "JITCode.h"
 #include "JSAPIValueWrapper.h"
-#include "JSActivation.h"
 #include "JSArray.h"
 #include "JSCInlines.h"
 #include "JSFunction.h"
 #include "JSGlobalObjectFunctions.h"
+#include "JSLexicalEnvironment.h"
 #include "JSLock.h"
 #include "JSNameScope.h"
 #include "JSNotAnObject.h"
 #include "JSPromiseDeferred.h"
-#include "JSPromiseReaction.h"
-#include "JSPropertyNameIterator.h"
+#include "JSPropertyNameEnumerator.h"
+#include "JSTemplateRegistryKey.h"
 #include "JSWithScope.h"
 #include "Lexer.h"
 #include "Lookup.h"
 #include "MapData.h"
 #include "Nodes.h"
 #include "Parser.h"
-#include "ParserArena.h"
 #include "ProfilerDatabase.h"
 #include "PropertyMapHashTable.h"
 #include "RegExpCache.h"
 #include "RegExpObject.h"
+#include "RuntimeType.h"
 #include "SimpleTypedArrayController.h"
 #include "SourceProviderCache.h"
+#include "StackVisitor.h"
 #include "StrictEvalActivation.h"
 #include "StrongInlines.h"
 #include "StructureInlines.h"
+#include "TypeProfiler.h"
+#include "TypeProfilerLog.h"
 #include "UnlinkedCodeBlock.h"
+#include "WeakGCMapInlines.h"
 #include "WeakMapData.h"
+#include <wtf/CurrentTime.h>
 #include <wtf/ProcessID.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/StringPrintStream.h>
 #include <wtf/Threading.h>
 #include <wtf/WTFThreadData.h>
 #include <wtf/text/AtomicStringTable.h>
+#include <wtf/text/SymbolRegistry.h>
 
 #if ENABLE(DFG_JIT)
 #include "ConservativeRoots.h"
@@ -106,28 +113,6 @@ using namespace WTF;
 
 namespace JSC {
 
-extern const HashTable arrayConstructorTable;
-extern const HashTable arrayPrototypeTable;
-extern const HashTable booleanPrototypeTable;
-extern const HashTable jsonTable;
-extern const HashTable dataViewTable;
-extern const HashTable dateTable;
-extern const HashTable dateConstructorTable;
-extern const HashTable errorPrototypeTable;
-extern const HashTable globalObjectTable;
-extern const HashTable numberConstructorTable;
-extern const HashTable numberPrototypeTable;
-JS_EXPORTDATA extern const HashTable objectConstructorTable;
-extern const HashTable privateNamePrototypeTable;
-extern const HashTable regExpTable;
-extern const HashTable regExpConstructorTable;
-extern const HashTable regExpPrototypeTable;
-extern const HashTable stringConstructorTable;
-#if ENABLE(PROMISES)
-extern const HashTable promisePrototypeTable;
-extern const HashTable promiseConstructorTable;
-#endif
-
 // Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
 // ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below
 // just checks for ENABLE(JIT) or ENABLE(YARR_JIT) with this premise in mind.
@@ -144,13 +129,6 @@ static bool enableAssembler(ExecutableAllocator& executableAllocator)
         return false;
     }
 
-#if USE(CF)
-    CFStringRef canUseJITKey = CFSTR("JavaScriptCoreUseJIT");
-    RetainPtr<CFTypeRef> canUseJIT = adoptCF(CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication));
-    if (canUseJIT)
-        return kCFBooleanTrue == canUseJIT.get();
-#endif
-
 #if USE(CF) || OS(UNIX)
     char* canUseJITString = getenv("JavaScriptCoreUseJIT");
     return !canUseJITString || atoi(canUseJITString);
@@ -168,37 +146,17 @@ VM::VM(VMType vmType, HeapType heapType)
     , heap(this, heapType)
     , vmType(vmType)
     , clientData(0)
+    , topVMEntryFrame(nullptr)
     , topCallFrame(CallFrame::noCaller())
-    , arrayConstructorTable(adoptPtr(new HashTable(JSC::arrayConstructorTable)))
-    , arrayPrototypeTable(adoptPtr(new HashTable(JSC::arrayPrototypeTable)))
-    , booleanPrototypeTable(adoptPtr(new HashTable(JSC::booleanPrototypeTable)))
-    , dataViewTable(adoptPtr(new HashTable(JSC::dataViewTable)))
-    , dateTable(adoptPtr(new HashTable(JSC::dateTable)))
-    , dateConstructorTable(adoptPtr(new HashTable(JSC::dateConstructorTable)))
-    , errorPrototypeTable(adoptPtr(new HashTable(JSC::errorPrototypeTable)))
-    , globalObjectTable(adoptPtr(new HashTable(JSC::globalObjectTable)))
-    , jsonTable(adoptPtr(new HashTable(JSC::jsonTable)))
-    , numberConstructorTable(adoptPtr(new HashTable(JSC::numberConstructorTable)))
-    , numberPrototypeTable(adoptPtr(new HashTable(JSC::numberPrototypeTable)))
-    , objectConstructorTable(adoptPtr(new HashTable(JSC::objectConstructorTable)))
-    , privateNamePrototypeTable(adoptPtr(new HashTable(JSC::privateNamePrototypeTable)))
-    , regExpTable(adoptPtr(new HashTable(JSC::regExpTable)))
-    , regExpConstructorTable(adoptPtr(new HashTable(JSC::regExpConstructorTable)))
-    , regExpPrototypeTable(adoptPtr(new HashTable(JSC::regExpPrototypeTable)))
-    , stringConstructorTable(adoptPtr(new HashTable(JSC::stringConstructorTable)))
-#if ENABLE(PROMISES)
-    , promisePrototypeTable(adoptPtr(new HashTable(JSC::promisePrototypeTable)))
-    , promiseConstructorTable(adoptPtr(new HashTable(JSC::promiseConstructorTable)))
-#endif
     , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
     , propertyNames(nullptr)
     , emptyList(new MarkedArgumentBuffer)
-    , parserArena(adoptPtr(new ParserArena))
-    , keywords(adoptPtr(new Keywords(*this)))
+    , stringCache(*this)
+    , prototypeMap(*this)
+    , keywords(std::make_unique<Keywords>(*this))
     , interpreter(0)
     , jsArrayClassInfo(JSArray::info())
     , jsFinalObjectClassInfo(JSFinalObject::info())
-    , varargsLength(0)
     , sizeOfLastScratchBuffer(0)
     , entryScope(0)
     , m_regExpCache(new RegExpCache(this))
@@ -228,9 +186,11 @@ VM::VM(VMType vmType, HeapType heapType)
     , m_largestFTLStackSize(0)
 #endif
     , m_inDefineOwnProperty(false)
-    , m_codeCache(CodeCache::create())
+    , m_codeCache(std::make_unique<CodeCache>())
     , m_enabledProfiler(nullptr)
-    , m_builtinExecutables(BuiltinExecutables::create(*this))
+    , m_builtinExecutables(std::make_unique<BuiltinExecutables>(*this))
+    , m_typeProfilerEnabledCount(0)
+    , m_controlFlowProfilerEnabledCount(0)
 {
     interpreter = new Interpreter(*this);
     StackBounds stack = wtfThreadData().stack();
@@ -246,13 +206,13 @@ VM::VM(VMType vmType, HeapType heapType)
     propertyNames = new CommonIdentifiers(this);
     structureStructure.set(*this, Structure::createStructure(*this));
     structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
-    debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull()));
     terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
     stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
     notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull()));
-    propertyNameIteratorStructure.set(*this, JSPropertyNameIterator::createStructure(*this, 0, jsNull()));
+    propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull()));
     getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull()));
     customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull()));
+    scopedArgumentsTableStructure.set(*this, ScopedArgumentsTable::createStructure(*this, 0, jsNull()));
     apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull()));
     JSScopeStructure.set(*this, JSScope::createStructure(*this, 0, jsNull()));
     executableStructure.set(*this, ExecutableBase::createStructure(*this, 0, jsNull()));
@@ -261,21 +221,23 @@ VM::VM(VMType vmType, HeapType heapType)
     programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
     functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
     regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
+    symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
     symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
     structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull()));
     sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
+    templateRegistryKeyStructure.set(*this, JSTemplateRegistryKey::createStructure(*this, 0, jsNull()));
     arrayBufferNeuteringWatchpointStructure.set(*this, ArrayBufferNeuteringWatchpoint::createStructure(*this));
-    withScopeStructure.set(*this, JSWithScope::createStructure(*this, 0, jsNull()));
     unlinkedFunctionExecutableStructure.set(*this, UnlinkedFunctionExecutable::createStructure(*this, 0, jsNull()));
     unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
     unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
     unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
     propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
-    mapDataStructure.set(*this, MapData::createStructure(*this, 0, jsNull()));
     weakMapDataStructure.set(*this, WeakMapData::createStructure(*this, 0, jsNull()));
+    inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull()));
+    functionRareDataStructure.set(*this, FunctionRareData::createStructure(*this, 0, jsNull()));
+    exceptionStructure.set(*this, Exception::createStructure(*this, 0, jsNull()));
 #if ENABLE(PROMISES)
     promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull()));
-    promiseReactionStructure.set(*this, JSPromiseReaction::createStructure(*this, 0, jsNull()));
 #endif
     iterationTerminator.set(*this, JSFinalObject::create(*this, JSFinalObject::createStructure(*this, 0, jsNull(), 1)));
     smallStrings.initializeCommonStrings(*this);
@@ -283,7 +245,7 @@ VM::VM(VMType vmType, HeapType heapType)
     wtfThreadData().setCurrentAtomicStringTable(existingEntryAtomicStringTable);
 
 #if ENABLE(JIT)
-    jitStubs = adoptPtr(new JITThunks());
+    jitStubs = std::make_unique<JITThunks>();
     arityCheckFailReturnThunks = std::make_unique<ArityCheckFailReturnThunks>();
 #endif
     arityCheckData = std::make_unique<CommonSlowPaths::ArityCheckData>();
@@ -303,26 +265,29 @@ VM::VM(VMType vmType, HeapType heapType)
     LLInt::Data::performAssertions(*this);
     
     if (Options::enableProfiler()) {
-        m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*this));
+        m_perBytecodeProfiler = std::make_unique<Profiler::Database>(*this);
 
         StringPrintStream pathOut;
-#if !OS(WINCE)
         const char* profilerPath = getenv("JSC_PROFILER_PATH");
         if (profilerPath)
             pathOut.print(profilerPath, "/");
-#endif
         pathOut.print("JSCProfile-", getCurrentProcessID(), "-", m_perBytecodeProfiler->databaseID(), ".json");
         m_perBytecodeProfiler->registerToSaveAtExit(pathOut.toCString().data());
     }
 
 #if ENABLE(DFG_JIT)
     if (canUseJIT())
-        dfgState = adoptPtr(new DFG::LongLivedState());
+        dfgState = std::make_unique<DFG::LongLivedState>();
 #endif
     
     // Initialize this last, as a free way of asserting that VM initialization itself
     // won't use this.
     m_typedArrayController = adoptRef(new SimpleTypedArrayController());
+
+    if (Options::enableTypeProfiler())
+        enableTypeProfiler();
+    if (Options::enableControlFlowProfiler())
+        enableControlFlowProfiler();
 }
 
 VM::~VM()
@@ -341,9 +306,11 @@ VM::~VM()
     }
 #endif // ENABLE(DFG_JIT)
     
-    // Clear this first to ensure that nobody tries to remove themselves from it.
-    m_perBytecodeProfiler.clear();
+    waitForAsynchronousDisassembly();
     
+    // Clear this first to ensure that nobody tries to remove themselves from it.
+    m_perBytecodeProfiler = nullptr;
+
     ASSERT(m_apiLock->currentThreadIsHoldingLock());
     m_apiLock->willDestroyVM(this);
     heap.lastChanceToFinalize();
@@ -353,28 +320,6 @@ VM::~VM()
     interpreter = reinterpret_cast<Interpreter*>(0xbbadbeef);
 #endif
 
-    arrayPrototypeTable->deleteTable();
-    arrayConstructorTable->deleteTable();
-    booleanPrototypeTable->deleteTable();
-    dataViewTable->deleteTable();
-    dateTable->deleteTable();
-    dateConstructorTable->deleteTable();
-    errorPrototypeTable->deleteTable();
-    globalObjectTable->deleteTable();
-    jsonTable->deleteTable();
-    numberConstructorTable->deleteTable();
-    numberPrototypeTable->deleteTable();
-    objectConstructorTable->deleteTable();
-    privateNamePrototypeTable->deleteTable();
-    regExpTable->deleteTable();
-    regExpConstructorTable->deleteTable();
-    regExpPrototypeTable->deleteTable();
-    stringConstructorTable->deleteTable();
-#if ENABLE(PROMISES)
-    promisePrototypeTable->deleteTable();
-    promiseConstructorTable->deleteTable();
-#endif
-
     delete emptyList;
 
     delete propertyNames;
@@ -393,17 +338,17 @@ VM::~VM()
 #endif
 }
 
-PassRefPtr<VM> VM::createContextGroup(HeapType heapType)
+Ref<VM> VM::createContextGroup(HeapType heapType)
 {
-    return adoptRef(new VM(APIContextGroup, heapType));
+    return adoptRef(*new VM(APIContextGroup, heapType));
 }
 
-PassRefPtr<VM> VM::create(HeapType heapType)
+Ref<VM> VM::create(HeapType heapType)
 {
-    return adoptRef(new VM(Default, heapType));
+    return adoptRef(*new VM(Default, heapType));
 }
 
-PassRefPtr<VM> VM::createLeaked(HeapType heapType)
+Ref<VM> VM::createLeaked(HeapType heapType)
 {
     return create(heapType);
 }
@@ -417,10 +362,8 @@ VM& VM::sharedInstance()
 {
     GlobalJSLock globalLock;
     VM*& instance = sharedInstanceInternal();
-    if (!instance) {
+    if (!instance)
         instance = adoptRef(new VM(APIShared, SmallHeap)).leakRef();
-        instance->makeUsableFromMultipleThreads();
-    }
     return *instance;
 }
 
@@ -438,6 +381,8 @@ static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
         return charCodeAtThunkGenerator;
     case CharAtIntrinsic:
         return charAtThunkGenerator;
+    case Clz32Intrinsic:
+        return clz32ThunkGenerator;
     case FromCharCodeIntrinsic:
         return fromCharCodeThunkGenerator;
     case SqrtIntrinsic:
@@ -458,10 +403,6 @@ static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
         return logThunkGenerator;
     case IMulIntrinsic:
         return imulThunkGenerator;
-    case ArrayIteratorNextKeyIntrinsic:
-        return arrayIteratorNextKeyThunkGenerator;
-    case ArrayIteratorNextValueIntrinsic:
-        return arrayIteratorNextValueThunkGenerator;
     default:
         return 0;
     }
@@ -511,7 +452,7 @@ void VM::stopSampling()
     interpreter->stopSampling();
 }
 
-void VM::waitForCompilationsToComplete()
+void VM::prepareToDiscardCode()
 {
 #if ENABLE(DFG_JIT)
     for (unsigned i = DFG::numberOfWorklists(); i--;) {
@@ -523,7 +464,7 @@ void VM::waitForCompilationsToComplete()
 
 void VM::discardAllCode()
 {
-    waitForCompilationsToComplete();
+    prepareToDiscardCode();
     m_codeCache->clear();
     m_regExpCache->invalidateCode();
     heap.deleteAllCompiledCode();
@@ -554,20 +495,25 @@ void VM::clearSourceProviderCaches()
 
 struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
     HashSet<FunctionExecutable*> currentlyExecutingFunctions;
-    void operator()(JSCell* cell)
+    inline void visit(JSCell* cell)
     {
         if (!cell->inherits(FunctionExecutable::info()))
             return;
         FunctionExecutable* executable = jsCast<FunctionExecutable*>(cell);
         if (currentlyExecutingFunctions.contains(executable))
             return;
-        executable->clearCodeIfNotCompiling();
+        executable->clearCode();
+    }
+    IterationStatus operator()(JSCell* cell)
+    {
+        visit(cell);
+        return IterationStatus::Continue;
     }
 };
 
 void VM::releaseExecutableMemory()
 {
-    waitForCompilationsToComplete();
+    prepareToDiscardCode();
     
     if (entryScope) {
         StackPreservingRecompiler recompiler;
@@ -599,61 +545,7 @@ void VM::releaseExecutableMemory()
     heap.collectAllGarbage();
 }
 
-static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
-{
-    exception->clearAppendSourceToMessage();
-    
-    if (!callFrame->codeBlock()->hasExpressionInfo())
-        return;
-    
-    int startOffset = 0;
-    int endOffset = 0;
-    int divotPoint = 0;
-    unsigned line = 0;
-    unsigned column = 0;
-    
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
-    
-    int expressionStart = divotPoint - startOffset;
-    int expressionStop = divotPoint + endOffset;
-    
-    const String& sourceString = codeBlock->source()->source();
-    if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
-        return;
-    
-    VM* vm = &callFrame->vm();
-    JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
-    if (!jsMessage || !jsMessage.isString())
-        return;
-    
-    String message = asString(jsMessage)->value(callFrame);
-    
-    if (expressionStart < expressionStop)
-        message =  makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
-    else {
-        // No range information, so give a few characters of context.
-        const StringImpl* data = sourceString.impl();
-        int dataLength = sourceString.length();
-        int start = expressionStart;
-        int stop = expressionStart;
-        // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
-        // Then strip whitespace.
-        while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
-            start--;
-        while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
-            start++;
-        while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
-            stop++;
-        while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
-            stop--;
-        message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
-    }
-    
-    exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
-}
-    
-JSValue VM::throwException(ExecState* exec, JSValue error)
+void VM::throwException(ExecState* exec, Exception* exception)
 {
     if (Options::breakOnThrow()) {
         dataLog("In call frame ", RawPointer(exec), " for code block ", *exec->codeBlock(), "\n");
@@ -661,77 +553,22 @@ JSValue VM::throwException(ExecState* exec, JSValue error)
     }
     
     ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
-    
-    Vector<StackFrame> stackTrace;
-    interpreter->getStackTrace(stackTrace);
-    m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
-    m_exception = error;
-    
-    if (stackTrace.isEmpty() || !error.isObject())
-        return error;
-    JSObject* exception = asObject(error);
-    
-    StackFrame stackFrame;
-    for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
-        stackFrame = stackTrace.at(i);
-        if (stackFrame.bytecodeOffset)
-            break;
-    }
-    unsigned bytecodeOffset = stackFrame.bytecodeOffset;
-    if (!hasErrorInfo(exec, exception)) {
-        // FIXME: We should only really be adding these properties to VM generated exceptions,
-        // but the inspector currently requires these for all thrown objects.
-        unsigned line;
-        unsigned column;
-        stackFrame.computeLineAndColumn(line, column);
-        exception->putDirect(*this, Identifier(this, "line"), jsNumber(line), ReadOnly | DontDelete);
-        exception->putDirect(*this, Identifier(this, "column"), jsNumber(column), ReadOnly | DontDelete);
-        if (!stackFrame.sourceURL.isEmpty())
-            exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
-    }
-    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
-        unsigned stackIndex = 0;
-        CallFrame* callFrame;
-        for (callFrame = exec; callFrame && !callFrame->codeBlock(); ) {
-            stackIndex++;
-            callFrame = callFrame->callerFrameSkippingVMEntrySentinel();
-        }
-        if (callFrame && callFrame->codeBlock()) {
-            stackFrame = stackTrace.at(stackIndex);
-            bytecodeOffset = stackFrame.bytecodeOffset;
-            appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
-        }
-    }
-
-    if (exception->hasProperty(exec, this->propertyNames->stack))
-        return error;
-    
-    exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
-    return error;
-}
-    
-JSObject* VM::throwException(ExecState* exec, JSObject* error)
-{
-    return asObject(throwException(exec, JSValue(error)));
-}
-void VM::getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack)
-{
-    exception = m_exception;
-    exceptionStack = m_exceptionStack;
-}
-void VM::setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack)
-{
-    m_exception = exception;
-    m_exceptionStack = exceptionStack;
+    setException(exception);
 }
 
-void VM::clearException()
+JSValue VM::throwException(ExecState* exec, JSValue thrownValue)
 {
-    m_exception = JSValue();
+    Exception* exception = jsDynamicCast<Exception*>(thrownValue);
+    if (!exception)
+        exception = Exception::create(*this, thrownValue);
+
+    throwException(exec, exception);
+    return JSValue(exception);
 }
-void VM:: clearExceptionStack()
+
+JSObject* VM::throwException(ExecState* exec, JSObject* error)
 {
-    m_exceptionStack = RefCountedArray<StackFrame>();
+    return asObject(throwException(exec, JSValue(error)));
 }
 
 void VM::setStackPointerAtVMEntry(void* sp)
@@ -892,7 +729,7 @@ void VM::registerWatchpointForImpureProperty(const Identifier& propertyName, Wat
 void VM::addImpureProperty(const String& propertyName)
 {
     if (RefPtr<WatchpointSet> watchpointSet = m_impurePropertyWatchpointSets.take(propertyName))
-        watchpointSet->fireAll();
+        watchpointSet->fireAll("Impure property added");
 }
 
 class SetEnabledProfilerFunctor {
@@ -909,12 +746,84 @@ void VM::setEnabledProfiler(LegacyProfiler* profiler)
 {
     m_enabledProfiler = profiler;
     if (m_enabledProfiler) {
-        waitForCompilationsToComplete();
+        prepareToDiscardCode();
         SetEnabledProfilerFunctor functor;
         heap.forEachCodeBlock(functor);
     }
 }
 
+static bool enableProfilerWithRespectToCount(unsigned& counter, std::function<void()> doEnableWork)
+{
+    bool needsToRecompile = false;
+    if (!counter) {
+        doEnableWork();
+        needsToRecompile = true;
+    }
+    counter++;
+
+    return needsToRecompile;
+}
+
+static bool disableProfilerWithRespectToCount(unsigned& counter, std::function<void()> doDisableWork)
+{
+    RELEASE_ASSERT(counter > 0);
+    bool needsToRecompile = false;
+    counter--;
+    if (!counter) {
+        doDisableWork();
+        needsToRecompile = true;
+    }
+
+    return needsToRecompile;
+}
+
+bool VM::enableTypeProfiler()
+{
+    auto enableTypeProfiler = [this] () {
+        this->m_typeProfiler = std::make_unique<TypeProfiler>();
+        this->m_typeProfilerLog = std::make_unique<TypeProfilerLog>();
+    };
+
+    return enableProfilerWithRespectToCount(m_typeProfilerEnabledCount, enableTypeProfiler);
+}
+
+bool VM::disableTypeProfiler()
+{
+    auto disableTypeProfiler = [this] () {
+        this->m_typeProfiler.reset(nullptr);
+        this->m_typeProfilerLog.reset(nullptr);
+    };
+
+    return disableProfilerWithRespectToCount(m_typeProfilerEnabledCount, disableTypeProfiler);
+}
+
+bool VM::enableControlFlowProfiler()
+{
+    auto enableControlFlowProfiler = [this] () {
+        this->m_controlFlowProfiler = std::make_unique<ControlFlowProfiler>();
+    };
+
+    return enableProfilerWithRespectToCount(m_controlFlowProfilerEnabledCount, enableControlFlowProfiler);
+}
+
+bool VM::disableControlFlowProfiler()
+{
+    auto disableControlFlowProfiler = [this] () {
+        this->m_controlFlowProfiler.reset(nullptr);
+    };
+
+    return disableProfilerWithRespectToCount(m_controlFlowProfilerEnabledCount, disableControlFlowProfiler);
+}
+
+void VM::dumpTypeProfilerData()
+{
+    if (!typeProfiler())
+        return;
+
+    typeProfilerLog()->processLogEntries(ASCIILiteral("VM Dump Types"));
+    typeProfiler()->dumpTypeProfilerData(*this);
+}
+
 void sanitizeStackForVM(VM* vm)
 {
     logSanitizeStack(vm);
index 8d55cb72aeb51a2c0959122ca5d46d96b80ae211..f78f9eb96460ae9fdbff9169c284a8584816c739 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef VM_h
 #define VM_h
 
+#include "ControlFlowProfiler.h"
 #include "DateInstanceCache.h"
 #include "ExecutableAllocator.h"
+#include "FunctionHasExecutedCache.h"
 #include "Heap.h"
 #include "Intrinsic.h"
 #include "JITThunks.h"
 #include "Strong.h"
 #include "ThunkGenerators.h"
 #include "TypedArrayController.h"
+#include "VMEntryRecord.h"
 #include "Watchdog.h"
 #include "Watchpoint.h"
 #include "WeakRandom.h"
+#include <wtf/Bag.h>
 #include <wtf/BumpPointerAllocator.h>
 #include <wtf/DateMath.h>
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
-#include <wtf/RefCountedArray.h>
 #include <wtf/SimpleStats.h>
 #include <wtf/StackBounds.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/ThreadSpecific.h>
 #include <wtf/WTFThreadData.h>
+#include <wtf/text/SymbolRegistry.h>
 #include <wtf/text/WTFString.h>
 #if ENABLE(REGEXP_TRACING)
 #include <wtf/ListHashSet.h>
 
 namespace JSC {
 
-    class ArityCheckFailReturnThunks;
-    class BuiltinExecutables;
-    class CodeBlock;
-    class CodeCache;
-    class CommonIdentifiers;
-    class ExecState;
-    class HandleStack;
-    class Identifier;
-    class Interpreter;
-    class JSGlobalObject;
-    class JSObject;
-    class Keywords;
-    class LLIntOffsetsExtractor;
-    class LegacyProfiler;
-    class NativeExecutable;
-    class ParserArena;
-    class RegExpCache;
-    class SourceProvider;
-    class SourceProviderCache;
-    struct StackFrame;
-    class Stringifier;
-    class Structure;
+class ArityCheckFailReturnThunks;
+class BuiltinExecutables;
+class CodeBlock;
+class CodeCache;
+class CommonIdentifiers;
+class ExecState;
+class Exception;
+class HandleStack;
+class TypeProfiler;
+class TypeProfilerLog;
+class Identifier;
+class Interpreter;
+class JSGlobalObject;
+class JSObject;
+class Keywords;
+class LLIntOffsetsExtractor;
+class LegacyProfiler;
+class NativeExecutable;
+class RegExpCache;
+class ScriptExecutable;
+class SourceProvider;
+class SourceProviderCache;
+struct StackFrame;
+class Stringifier;
+class Structure;
 #if ENABLE(REGEXP_TRACING)
-    class RegExp;
+class RegExp;
 #endif
-    class UnlinkedCodeBlock;
-    class UnlinkedEvalCodeBlock;
-    class UnlinkedFunctionExecutable;
-    class UnlinkedProgramCodeBlock;
-    class VMEntryScope;
-    class Watchpoint;
-    class WatchpointSet;
+class UnlinkedCodeBlock;
+class UnlinkedEvalCodeBlock;
+class UnlinkedFunctionExecutable;
+class UnlinkedProgramCodeBlock;
+class VirtualRegister;
+class VMEntryScope;
+class Watchpoint;
+class WatchpointSet;
 
 #if ENABLE(DFG_JIT)
-    namespace DFG {
-    class LongLivedState;
-    }
+namespace DFG {
+class LongLivedState;
+}
 #endif // ENABLE(DFG_JIT)
 #if ENABLE(FTL_JIT)
-    namespace FTL {
-    class Thunks;
-    }
+namespace FTL {
+class Thunks;
+}
 #endif // ENABLE(FTL_JIT)
-    namespace CommonSlowPaths {
-    struct ArityCheckData;
-    }
-    namespace Profiler {
-    class Database;
+namespace CommonSlowPaths {
+struct ArityCheckData;
+}
+namespace Profiler {
+class Database;
+}
+
+struct HashTable;
+struct Instruction;
+
+struct LocalTimeOffsetCache {
+    LocalTimeOffsetCache()
+        : start(0.0)
+        , end(-1.0)
+        , increment(0.0)
+        , timeType(WTF::UTCTime)
+    {
     }
 
-    struct HashTable;
-    struct Instruction;
-
-    struct LocalTimeOffsetCache {
-        LocalTimeOffsetCache()
-            : start(0.0)
-            , end(-1.0)
-            , increment(0.0)
-        {
-        }
-        
-        void reset()
-        {
-            offset = LocalTimeOffset();
-            start = 0.0;
-            end = -1.0;
-            increment = 0.0;
-        }
+    void reset()
+    {
+        offset = LocalTimeOffset();
+        start = 0.0;
+        end = -1.0;
+        increment = 0.0;
+        timeType = WTF::UTCTime;
+    }
 
-        LocalTimeOffset offset;
-        double start;
-        double end;
-        double increment;
-    };
+    LocalTimeOffset offset;
+    double start;
+    double end;
+    double increment;
+    WTF::TimeType timeType;
+};
 
-    class ConservativeRoots;
+class ConservativeRoots;
 
 #if COMPILER(MSVC)
 #pragma warning(push)
 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
 #endif
-    struct ScratchBuffer {
-        ScratchBuffer()
-        {
-            u.m_activeLength = 0;
-        }
+struct ScratchBuffer {
+    ScratchBuffer()
+    {
+        u.m_activeLength = 0;
+    }
 
-        static ScratchBuffer* create(size_t size)
-        {
-            ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
+    static ScratchBuffer* create(size_t size)
+    {
+        ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
 
-            return result;
-        }
+        return result;
+    }
 
-        static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
-        void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
-        size_t activeLength() const { return u.m_activeLength; };
-        size_t* activeLengthPtr() { return &u.m_activeLength; };
-        void* dataBuffer() { return m_buffer; }
+    static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
+    void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
+    size_t activeLength() const { return u.m_activeLength; };
+    size_t* activeLengthPtr() { return &u.m_activeLength; };
+    void* dataBuffer() { return m_buffer; }
 
-        union {
-            size_t m_activeLength;
-            double pad; // Make sure m_buffer is double aligned.
-        } u;
+    union {
+        size_t m_activeLength;
+        double pad; // Make sure m_buffer is double aligned.
+    } u;
 #if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
-        void* m_buffer[0] __attribute__((aligned(8)));
+    void* m_buffer[0] __attribute__((aligned(8)));
 #else
-        void* m_buffer[0];
+    void* m_buffer[0];
 #endif
-    };
+};
 #if COMPILER(MSVC)
 #pragma warning(pop)
 #endif
 
-    class VM : public ThreadSafeRefCounted<VM> {
-    public:
-        // WebCore has a one-to-one mapping of threads to VMs;
-        // either create() or createLeaked() should only be called once
-        // on a thread, this is the 'default' VM (it uses the
-        // thread's default string uniquing table from wtfThreadData).
-        // API contexts created using the new context group aware interface
-        // create APIContextGroup objects which require less locking of JSC
-        // than the old singleton APIShared VM created for use by
-        // the original API.
-        enum VMType { Default, APIContextGroup, APIShared };
-        
-        struct ClientData {
-            JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
-        };
+class VM : public ThreadSafeRefCounted<VM> {
+public:
+    // WebCore has a one-to-one mapping of threads to VMs;
+    // either create() or createLeaked() should only be called once
+    // on a thread, this is the 'default' VM (it uses the
+    // thread's default string uniquing table from wtfThreadData).
+    // API contexts created using the new context group aware interface
+    // create APIContextGroup objects which require less locking of JSC
+    // than the old singleton APIShared VM created for use by
+    // the original API.
+    enum VMType { Default, APIContextGroup, APIShared };
+
+    struct ClientData {
+        JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
+    };
 
-        bool isSharedInstance() { return vmType == APIShared; }
-        bool usingAPI() { return vmType != Default; }
-        JS_EXPORT_PRIVATE static bool sharedInstanceExists();
-        JS_EXPORT_PRIVATE static VM& sharedInstance();
+    bool isSharedInstance() { return vmType == APIShared; }
+    bool usingAPI() { return vmType != Default; }
+    JS_EXPORT_PRIVATE static bool sharedInstanceExists();
+    JS_EXPORT_PRIVATE static VM& sharedInstance();
 
-        JS_EXPORT_PRIVATE static PassRefPtr<VM> create(HeapType = SmallHeap);
-        JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeaked(HeapType = SmallHeap);
-        static PassRefPtr<VM> createContextGroup(HeapType = SmallHeap);
-        JS_EXPORT_PRIVATE ~VM();
+    JS_EXPORT_PRIVATE static Ref<VM> create(HeapType = SmallHeap);
+    JS_EXPORT_PRIVATE static Ref<VM> createLeaked(HeapType = SmallHeap);
+    static Ref<VM> createContextGroup(HeapType = SmallHeap);
+    JS_EXPORT_PRIVATE ~VM();
 
-        void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
-        
-    private:
-        RefPtr<JSLock> m_apiLock;
+private:
+    RefPtr<JSLock> m_apiLock;
 
-    public:
+public:
 #if ENABLE(ASSEMBLER)
-        // executableAllocator should be destructed after the heap, as the heap can call executableAllocator
-        // in its destructor.
-        ExecutableAllocator executableAllocator;
+    // executableAllocator should be destructed after the heap, as the heap can call executableAllocator
+    // in its destructor.
+    ExecutableAllocator executableAllocator;
 #endif
 
-        // The heap should be just after executableAllocator and before other members to ensure that it's
-        // destructed after all the objects that reference it.
-        Heap heap;
-        
+    // The heap should be just after executableAllocator and before other members to ensure that it's
+    // destructed after all the objects that reference it.
+    Heap heap;
+
 #if ENABLE(DFG_JIT)
-        OwnPtr<DFG::LongLivedState> dfgState;
+    std::unique_ptr<DFG::LongLivedState> dfgState;
 #endif // ENABLE(DFG_JIT)
 
-        VMType vmType;
-        ClientData* clientData;
-        ExecState* topCallFrame;
-        std::unique_ptr<Watchdog> watchdog;
-
-        const OwnPtr<const HashTable> arrayConstructorTable;
-        const OwnPtr<const HashTable> arrayPrototypeTable;
-        const OwnPtr<const HashTable> booleanPrototypeTable;
-        const OwnPtr<const HashTable> dataViewTable;
-        const OwnPtr<const HashTable> dateTable;
-        const OwnPtr<const HashTable> dateConstructorTable;
-        const OwnPtr<const HashTable> errorPrototypeTable;
-        const OwnPtr<const HashTable> globalObjectTable;
-        const OwnPtr<const HashTable> jsonTable;
-        const OwnPtr<const HashTable> numberConstructorTable;
-        const OwnPtr<const HashTable> numberPrototypeTable;
-        const OwnPtr<const HashTable> objectConstructorTable;
-        const OwnPtr<const HashTable> privateNamePrototypeTable;
-        const OwnPtr<const HashTable> regExpTable;
-        const OwnPtr<const HashTable> regExpConstructorTable;
-        const OwnPtr<const HashTable> regExpPrototypeTable;
-        const OwnPtr<const HashTable> stringConstructorTable;
-#if ENABLE(PROMISES)
-        const OwnPtr<const HashTable> promisePrototypeTable;
-        const OwnPtr<const HashTable> promiseConstructorTable;
-#endif
-
-        Strong<Structure> structureStructure;
-        Strong<Structure> structureRareDataStructure;
-        Strong<Structure> debuggerActivationStructure;
-        Strong<Structure> terminatedExecutionErrorStructure;
-        Strong<Structure> stringStructure;
-        Strong<Structure> notAnObjectStructure;
-        Strong<Structure> propertyNameIteratorStructure;
-        Strong<Structure> getterSetterStructure;
-        Strong<Structure> customGetterSetterStructure;
-        Strong<Structure> apiWrapperStructure;
-        Strong<Structure> JSScopeStructure;
-        Strong<Structure> executableStructure;
-        Strong<Structure> nativeExecutableStructure;
-        Strong<Structure> evalExecutableStructure;
-        Strong<Structure> programExecutableStructure;
-        Strong<Structure> functionExecutableStructure;
-        Strong<Structure> regExpStructure;
-        Strong<Structure> symbolTableStructure;
-        Strong<Structure> structureChainStructure;
-        Strong<Structure> sparseArrayValueMapStructure;
-        Strong<Structure> arrayBufferNeuteringWatchpointStructure;
-        Strong<Structure> withScopeStructure;
-        Strong<Structure> unlinkedFunctionExecutableStructure;
-        Strong<Structure> unlinkedProgramCodeBlockStructure;
-        Strong<Structure> unlinkedEvalCodeBlockStructure;
-        Strong<Structure> unlinkedFunctionCodeBlockStructure;
-        Strong<Structure> propertyTableStructure;
-        Strong<Structure> mapDataStructure;
-        Strong<Structure> weakMapDataStructure;
+    VMType vmType;
+    ClientData* clientData;
+    VMEntryFrame* topVMEntryFrame;
+    ExecState* topCallFrame;
+    std::unique_ptr<Watchdog> watchdog;
+
+    Strong<Structure> structureStructure;
+    Strong<Structure> structureRareDataStructure;
+    Strong<Structure> terminatedExecutionErrorStructure;
+    Strong<Structure> stringStructure;
+    Strong<Structure> notAnObjectStructure;
+    Strong<Structure> propertyNameIteratorStructure;
+    Strong<Structure> propertyNameEnumeratorStructure;
+    Strong<Structure> getterSetterStructure;
+    Strong<Structure> customGetterSetterStructure;
+    Strong<Structure> scopedArgumentsTableStructure;
+    Strong<Structure> apiWrapperStructure;
+    Strong<Structure> JSScopeStructure;
+    Strong<Structure> executableStructure;
+    Strong<Structure> nativeExecutableStructure;
+    Strong<Structure> evalExecutableStructure;
+    Strong<Structure> programExecutableStructure;
+    Strong<Structure> functionExecutableStructure;
+    Strong<Structure> regExpStructure;
+    Strong<Structure> symbolStructure;
+    Strong<Structure> symbolTableStructure;
+    Strong<Structure> structureChainStructure;
+    Strong<Structure> sparseArrayValueMapStructure;
+    Strong<Structure> templateRegistryKeyStructure;
+    Strong<Structure> arrayBufferNeuteringWatchpointStructure;
+    Strong<Structure> unlinkedFunctionExecutableStructure;
+    Strong<Structure> unlinkedProgramCodeBlockStructure;
+    Strong<Structure> unlinkedEvalCodeBlockStructure;
+    Strong<Structure> unlinkedFunctionCodeBlockStructure;
+    Strong<Structure> propertyTableStructure;
+    Strong<Structure> weakMapDataStructure;
+    Strong<Structure> inferredValueStructure;
+    Strong<Structure> functionRareDataStructure;
+    Strong<Structure> exceptionStructure;
 #if ENABLE(PROMISES)
-        Strong<Structure> promiseDeferredStructure;
-        Strong<Structure> promiseReactionStructure;
+    Strong<Structure> promiseDeferredStructure;
 #endif
-        Strong<JSCell> iterationTerminator;
-
-        AtomicStringTable* m_atomicStringTable;
-        CommonIdentifiers* propertyNames;
-        const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
-        SmallStrings smallStrings;
-        NumericStrings numericStrings;
-        DateInstanceCache dateInstanceCache;
-        WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
-        WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
-        Strong<JSString> lastCachedString;
-
-        AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
-
-        void setInDefineOwnProperty(bool inDefineOwnProperty)
-        {
-            m_inDefineOwnProperty = inDefineOwnProperty;
-        }
+    Strong<JSCell> iterationTerminator;
+    Strong<JSCell> emptyPropertyNameEnumerator;
+
+    AtomicStringTable* m_atomicStringTable;
+    WTF::SymbolRegistry m_symbolRegistry;
+    CommonIdentifiers* propertyNames;
+    const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
+    SmallStrings smallStrings;
+    NumericStrings numericStrings;
+    DateInstanceCache dateInstanceCache;
+    WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
+    WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
+    Strong<JSString> lastCachedString;
+
+    AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
+    WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; }
+
+    void setInDefineOwnProperty(bool inDefineOwnProperty)
+    {
+        m_inDefineOwnProperty = inDefineOwnProperty;
+    }
 
-        bool isInDefineOwnProperty()
-        {
-            return m_inDefineOwnProperty;
-        }
+    bool isInDefineOwnProperty()
+    {
+        return m_inDefineOwnProperty;
+    }
 
-        LegacyProfiler* enabledProfiler() { return m_enabledProfiler; }
-        void setEnabledProfiler(LegacyProfiler*);
+    LegacyProfiler* enabledProfiler() { return m_enabledProfiler; }
+    void setEnabledProfiler(LegacyProfiler*);
 
-        void* enabledProfilerAddress() { return &m_enabledProfiler; }
+    void* enabledProfilerAddress() { return &m_enabledProfiler; }
 
 #if ENABLE(JIT)
-        bool canUseJIT() { return m_canUseJIT; }
+    bool canUseJIT() { return m_canUseJIT; }
 #else
-        bool canUseJIT() { return false; } // interpreter only
+    bool canUseJIT() { return false; } // interpreter only
 #endif
 
 #if ENABLE(YARR_JIT)
-        bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
+    bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
 #else
-        bool canUseRegExpJIT() { return false; } // interpreter only
+    bool canUseRegExpJIT() { return false; } // interpreter only
 #endif
 
-        SourceProviderCache* addSourceProviderCache(SourceProvider*);
-        void clearSourceProviderCaches();
+    SourceProviderCache* addSourceProviderCache(SourceProvider*);
+    void clearSourceProviderCaches();
 
-        PrototypeMap prototypeMap;
+    PrototypeMap prototypeMap;
 
-        OwnPtr<ParserArena> parserArena;
-        typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
-        SourceProviderCacheMap sourceProviderCacheMap;
-        OwnPtr<Keywords> keywords;
-        Interpreter* interpreter;
+    typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
+    SourceProviderCacheMap sourceProviderCacheMap;
+    std::unique_ptr<Keywords> keywords;
+    Interpreter* interpreter;
 #if ENABLE(JIT)
-        OwnPtr<JITThunks> jitStubs;
-        MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
-        {
-            return jitStubs->ctiStub(this, generator);
-        }
-        NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
-        
-        std::unique_ptr<ArityCheckFailReturnThunks> arityCheckFailReturnThunks;
+    std::unique_ptr<JITThunks> jitStubs;
+    MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
+    {
+        return jitStubs->ctiStub(this, generator);
+    }
+    NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
+
+    std::unique_ptr<ArityCheckFailReturnThunks> arityCheckFailReturnThunks;
 #endif // ENABLE(JIT)
-        std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
+    std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
 #if ENABLE(FTL_JIT)
-        std::unique_ptr<FTL::Thunks> ftlThunks;
+    std::unique_ptr<FTL::Thunks> ftlThunks;
 #endif
-        NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
+    NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
 
-        static ptrdiff_t exceptionOffset()
-        {
-            return OBJECT_OFFSETOF(VM, m_exception);
-        }
+    static ptrdiff_t exceptionOffset()
+    {
+        return OBJECT_OFFSETOF(VM, m_exception);
+    }
 
-        static ptrdiff_t callFrameForThrowOffset()
-        {
-            return OBJECT_OFFSETOF(VM, callFrameForThrow);
-        }
+    static ptrdiff_t vmEntryFrameForThrowOffset()
+    {
+        return OBJECT_OFFSETOF(VM, vmEntryFrameForThrow);
+    }
 
-        static ptrdiff_t targetMachinePCForThrowOffset()
-        {
-            return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
-        }
+    static ptrdiff_t topVMEntryFrameOffset()
+    {
+        return OBJECT_OFFSETOF(VM, topVMEntryFrame);
+    }
 
-        JS_EXPORT_PRIVATE void clearException();
-        JS_EXPORT_PRIVATE void clearExceptionStack();
-        void getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
-        void setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
-        JSValue exception() const { return m_exception; }
-        JSValue* addressOfException() { return &m_exception; }
-        const RefCountedArray<StackFrame>& exceptionStack() const { return m_exceptionStack; }
+    static ptrdiff_t callFrameForThrowOffset()
+    {
+        return OBJECT_OFFSETOF(VM, callFrameForThrow);
+    }
 
-        JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
-        JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
-        
-        void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; }
-        void setStackPointerAtVMEntry(void*);
+    static ptrdiff_t targetMachinePCForThrowOffset()
+    {
+        return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
+    }
+
+    void clearException() { m_exception = nullptr; }
+    void clearLastException() { m_lastException = nullptr; }
+
+    void setException(Exception* exception)
+    {
+        m_exception = exception;
+        m_lastException = exception;
+    }
+
+    Exception* exception() const { return m_exception; }
+    JSCell** addressOfException() { return reinterpret_cast<JSCell**>(&m_exception); }
+
+    Exception* lastException() const { return m_lastException; }
+    JSCell** addressOfLastException() { return reinterpret_cast<JSCell**>(&m_lastException); }
 
-        size_t reservedZoneSize() const { return m_reservedZoneSize; }
-        size_t updateReservedZoneSize(size_t reservedZoneSize);
+    JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*);
+    JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
+    JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
+
+    void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; }
+    void setStackPointerAtVMEntry(void*);
+
+    size_t reservedZoneSize() const { return m_reservedZoneSize; }
+    size_t updateReservedZoneSize(size_t reservedZoneSize);
 
 #if ENABLE(FTL_JIT)
-        void updateFTLLargestStackSize(size_t);
-        void** addressOfFTLStackLimit() { return &m_ftlStackLimit; }
+    void updateFTLLargestStackSize(size_t);
+    void** addressOfFTLStackLimit() { return &m_ftlStackLimit; }
 #endif
 
 #if !ENABLE(JIT)
-        void* jsStackLimit() { return m_jsStackLimit; }
-        void setJSStackLimit(void* limit) { m_jsStackLimit = limit; }
+    void* jsStackLimit() { return m_jsStackLimit; }
+    void setJSStackLimit(void* limit) { m_jsStackLimit = limit; }
 #endif
-        void* stackLimit() { return m_stackLimit; }
-        void** addressOfStackLimit() { return &m_stackLimit; }
-
-        bool isSafeToRecurse(size_t neededStackInBytes = 0) const
-        {
-            ASSERT(wtfThreadData().stack().isGrowingDownward());
-            int8_t* curr = reinterpret_cast<int8_t*>(&curr);
-            int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
-            return curr >= limit && static_cast<size_t>(curr - limit) >= neededStackInBytes;
-        }
+    void* stackLimit() { return m_stackLimit; }
+    void** addressOfStackLimit() { return &m_stackLimit; }
 
-        void* lastStackTop() { return m_lastStackTop; }
-        void setLastStackTop(void* lastStackTop) { m_lastStackTop = lastStackTop; }
-
-        const ClassInfo* const jsArrayClassInfo;
-        const ClassInfo* const jsFinalObjectClassInfo;
-
-        JSValue hostCallReturnValue;
-        ExecState* newCallFrameReturnValue;
-        unsigned varargsLength;
-        ExecState* callFrameForThrow;
-        void* targetMachinePCForThrow;
-        Instruction* targetInterpreterPCForThrow;
-        uint32_t osrExitIndex;
-        void* osrExitJumpDestination;
-        Vector<ScratchBuffer*> scratchBuffers;
-        size_t sizeOfLastScratchBuffer;
-        
-        ScratchBuffer* scratchBufferForSize(size_t size)
-        {
-            if (!size)
-                return 0;
-            
-            if (size > sizeOfLastScratchBuffer) {
-                // Protect against a N^2 memory usage pathology by ensuring
-                // that at worst, we get a geometric series, meaning that the
-                // total memory usage is somewhere around
-                // max(scratch buffer size) * 4.
-                sizeOfLastScratchBuffer = size * 2;
-
-                ScratchBuffer* newBuffer = ScratchBuffer::create(sizeOfLastScratchBuffer);
-                RELEASE_ASSERT(newBuffer);
-                scratchBuffers.append(newBuffer);
-            }
-
-            ScratchBuffer* result = scratchBuffers.last();
-            result->setActiveLength(0);
-            return result;
+    bool isSafeToRecurse(size_t neededStackInBytes = 0) const
+    {
+        ASSERT(wtfThreadData().stack().isGrowingDownward());
+        int8_t* curr = reinterpret_cast<int8_t*>(&curr);
+        int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
+        return curr >= limit && static_cast<size_t>(curr - limit) >= neededStackInBytes;
+    }
+
+    void* lastStackTop() { return m_lastStackTop; }
+    void setLastStackTop(void* lastStackTop) { m_lastStackTop = lastStackTop; }
+
+    const ClassInfo* const jsArrayClassInfo;
+    const ClassInfo* const jsFinalObjectClassInfo;
+
+    JSValue hostCallReturnValue;
+    unsigned varargsLength;
+    ExecState* newCallFrameReturnValue;
+    VMEntryFrame* vmEntryFrameForThrow;
+    ExecState* callFrameForThrow;
+    void* targetMachinePCForThrow;
+    Instruction* targetInterpreterPCForThrow;
+    uint32_t osrExitIndex;
+    void* osrExitJumpDestination;
+    Vector<ScratchBuffer*> scratchBuffers;
+    size_t sizeOfLastScratchBuffer;
+
+    ScratchBuffer* scratchBufferForSize(size_t size)
+    {
+        if (!size)
+            return 0;
+
+        if (size > sizeOfLastScratchBuffer) {
+            // Protect against a N^2 memory usage pathology by ensuring
+            // that at worst, we get a geometric series, meaning that the
+            // total memory usage is somewhere around
+            // max(scratch buffer size) * 4.
+            sizeOfLastScratchBuffer = size * 2;
+
+            ScratchBuffer* newBuffer = ScratchBuffer::create(sizeOfLastScratchBuffer);
+            RELEASE_ASSERT(newBuffer);
+            scratchBuffers.append(newBuffer);
         }
 
-        void gatherConservativeRoots(ConservativeRoots&);
+        ScratchBuffer* result = scratchBuffers.last();
+        result->setActiveLength(0);
+        return result;
+    }
 
-        VMEntryScope* entryScope;
+    void gatherConservativeRoots(ConservativeRoots&);
 
-        HashSet<JSObject*> stringRecursionCheckVisitedObjects;
+    VMEntryScope* entryScope;
 
-        LocalTimeOffsetCache localTimeOffsetCache;
-        
-        String cachedDateString;
-        double cachedDateStringValue;
+    JSObject* stringRecursionCheckFirstObject { nullptr };
+    HashSet<JSObject*> stringRecursionCheckVisitedObjects;
+
+    LocalTimeOffsetCache localTimeOffsetCache;
 
-        OwnPtr<Profiler::Database> m_perBytecodeProfiler;
-        RefPtr<TypedArrayController> m_typedArrayController;
-        RegExpCache* m_regExpCache;
-        BumpPointerAllocator m_regExpAllocator;
+    String cachedDateString;
+    double cachedDateStringValue;
+
+    std::unique_ptr<Profiler::Database> m_perBytecodeProfiler;
+    RefPtr<TypedArrayController> m_typedArrayController;
+    RegExpCache* m_regExpCache;
+    BumpPointerAllocator m_regExpAllocator;
 
 #if ENABLE(REGEXP_TRACING)
-        typedef ListHashSet<RegExp*> RTTraceList;
-        RTTraceList* m_rtTraceList;
+    typedef ListHashSet<RegExp*> RTTraceList;
+    RTTraceList* m_rtTraceList;
 #endif
 
-        bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); }
-        std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); }
-        void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); }
+    bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); }
+    std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); }
+    void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); }
 
-        JS_EXPORT_PRIVATE void resetDateCache();
+    JS_EXPORT_PRIVATE void resetDateCache();
 
-        JS_EXPORT_PRIVATE void startSampling();
-        JS_EXPORT_PRIVATE void stopSampling();
-        JS_EXPORT_PRIVATE void dumpSampleData(ExecState* exec);
-        RegExpCache* regExpCache() { return m_regExpCache; }
+    JS_EXPORT_PRIVATE void startSampling();
+    JS_EXPORT_PRIVATE void stopSampling();
+    JS_EXPORT_PRIVATE void dumpSampleData(ExecState*);
+    RegExpCache* regExpCache() { return m_regExpCache; }
 #if ENABLE(REGEXP_TRACING)
-        void addRegExpToTrace(RegExp*);
+    void addRegExpToTrace(RegExp*);
 #endif
-        JS_EXPORT_PRIVATE void dumpRegExpTrace();
+    JS_EXPORT_PRIVATE void dumpRegExpTrace();
 
-        bool isCollectorBusy() { return heap.isBusy(); }
-        JS_EXPORT_PRIVATE void releaseExecutableMemory();
+    bool isCollectorBusy() { return heap.isBusy(); }
+    JS_EXPORT_PRIVATE void releaseExecutableMemory();
 
 #if ENABLE(GC_VALIDATION)
-        bool isInitializingObject() const; 
-        void setInitializingObjectClass(const ClassInfo*);
+    bool isInitializingObject() const; 
+    void setInitializingObjectClass(const ClassInfo*);
 #endif
 
-        unsigned m_newStringsSinceLastHashCons;
+    unsigned m_newStringsSinceLastHashCons;
 
-        static const unsigned s_minNumberOfNewStringsToHashCons = 100;
+    static const unsigned s_minNumberOfNewStringsToHashCons = 100;
 
-        bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons > s_minNumberOfNewStringsToHashCons; }
-        void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
+    bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons > s_minNumberOfNewStringsToHashCons; }
+    void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
 
-        bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); }
+    bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); }
 
-        JSLock& apiLock() { return *m_apiLock; }
-        CodeCache* codeCache() { return m_codeCache.get(); }
+    JSLock& apiLock() { return *m_apiLock; }
+    CodeCache* codeCache() { return m_codeCache.get(); }
 
-        void waitForCompilationsToComplete();
+    void prepareToDiscardCode();
         
-        JS_EXPORT_PRIVATE void discardAllCode();
+    JS_EXPORT_PRIVATE void discardAllCode();
 
-        void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
-        // FIXME: Use AtomicString once it got merged with Identifier.
-        JS_EXPORT_PRIVATE void addImpureProperty(const String&);
-        
-        BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
+    void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
+    // FIXME: Use AtomicString once it got merged with Identifier.
+    JS_EXPORT_PRIVATE void addImpureProperty(const String&);
 
-    private:
-        friend class LLIntOffsetsExtractor;
-        friend class ClearExceptionScope;
-        friend class RecursiveAllocationScope;
-        
-        VM(VMType, HeapType);
-        static VM*& sharedInstanceInternal();
-        void createNativeThunk();
+    BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
+
+    bool enableTypeProfiler();
+    bool disableTypeProfiler();
+    TypeProfilerLog* typeProfilerLog() { return m_typeProfilerLog.get(); }
+    TypeProfiler* typeProfiler() { return m_typeProfiler.get(); }
+    JS_EXPORT_PRIVATE void dumpTypeProfilerData();
+
+    FunctionHasExecutedCache* functionHasExecutedCache() { return &m_functionHasExecutedCache; }
+
+    ControlFlowProfiler* controlFlowProfiler() { return m_controlFlowProfiler.get(); }
+    bool enableControlFlowProfiler();
+    bool disableControlFlowProfiler();
+
+private:
+    friend class LLIntOffsetsExtractor;
+    friend class ClearExceptionScope;
+    friend class RecursiveAllocationScope;
+
+    VM(VMType, HeapType);
+    static VM*& sharedInstanceInternal();
+    void createNativeThunk();
 
-        void updateStackLimit();
+    void updateStackLimit();
 
 #if ENABLE(ASSEMBLER)
-        bool m_canUseAssembler;
+    bool m_canUseAssembler;
 #endif
 #if ENABLE(JIT)
-        bool m_canUseJIT;
+    bool m_canUseJIT;
 #endif
 #if ENABLE(YARR_JIT)
-        bool m_canUseRegExpJIT;
+    bool m_canUseRegExpJIT;
 #endif
 #if ENABLE(GC_VALIDATION)
-        const ClassInfo* m_initializingObjectClass;
+    const ClassInfo* m_initializingObjectClass;
 #endif
-        void* m_stackPointerAtVMEntry;
-        size_t m_reservedZoneSize;
+    void* m_stackPointerAtVMEntry;
+    size_t m_reservedZoneSize;
 #if !ENABLE(JIT)
-        struct {
-            void* m_stackLimit;
-            void* m_jsStackLimit;
-        };
+    struct {
+        void* m_stackLimit;
+        void* m_jsStackLimit;
+    };
 #else
-        union {
-            void* m_stackLimit;
-            void* m_jsStackLimit;
-        };
+    union {
+        void* m_stackLimit;
+        void* m_jsStackLimit;
+    };
 #if ENABLE(FTL_JIT)
-        void* m_ftlStackLimit;
-        size_t m_largestFTLStackSize;
+    void* m_ftlStackLimit;
+    size_t m_largestFTLStackSize;
 #endif
 #endif
-        void* m_lastStackTop;
-        JSValue m_exception;
-        bool m_inDefineOwnProperty;
-        OwnPtr<CodeCache> m_codeCache;
-        LegacyProfiler* m_enabledProfiler;
-        OwnPtr<BuiltinExecutables> m_builtinExecutables;
-        RefCountedArray<StackFrame> m_exceptionStack;
-        HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
-    };
+    void* m_lastStackTop;
+    Exception* m_exception { nullptr };
+    Exception* m_lastException { nullptr };
+    bool m_inDefineOwnProperty;
+    std::unique_ptr<CodeCache> m_codeCache;
+    LegacyProfiler* m_enabledProfiler;
+    std::unique_ptr<BuiltinExecutables> m_builtinExecutables;
+    HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
+    std::unique_ptr<TypeProfiler> m_typeProfiler;
+    std::unique_ptr<TypeProfilerLog> m_typeProfilerLog;
+    unsigned m_typeProfilerEnabledCount;
+    FunctionHasExecutedCache m_functionHasExecutedCache;
+    std::unique_ptr<ControlFlowProfiler> m_controlFlowProfiler;
+    unsigned m_controlFlowProfilerEnabledCount;
+};
 
 #if ENABLE(GC_VALIDATION)
-    inline bool VM::isInitializingObject() const
-    {
-        return !!m_initializingObjectClass;
-    }
-
-    inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
-    {
-        m_initializingObjectClass = initializingObjectClass;
-    }
+inline bool VM::isInitializingObject() const
+{
+    return !!m_initializingObjectClass;
+}
+
+inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
+{
+    m_initializingObjectClass = initializingObjectClass;
+}
 #endif
 
-    inline Heap* WeakSet::heap() const
-    {
-        return &m_vm->heap;
-    }
+inline Heap* WeakSet::heap() const
+{
+    return &m_vm->heap;
+}
 
 #if ENABLE(JIT)
-    extern "C" void sanitizeStackForVMImpl(VM*);
+extern "C" void sanitizeStackForVMImpl(VM*);
 #endif
 
-    void sanitizeStackForVM(VM*);
-    void logSanitizeStack(VM*);
+void sanitizeStackForVM(VM*);
+void logSanitizeStack(VM*);
 
 } // namespace JSC
 
index a5e259f3000f4215de3ba928b96dc5542b3dacc5..b67dd699108c933fdc7043bb6363a36e78b10cc7 100644 (file)
@@ -36,7 +36,6 @@ namespace JSC {
 VMEntryScope::VMEntryScope(VM& vm, JSGlobalObject* globalObject)
     : m_vm(vm)
     , m_globalObject(globalObject)
-    , m_recompilationNeeded(false)
 {
     ASSERT(wtfThreadData().stack().isGrowingDownward());
     if (!vm.entryScope) {
@@ -51,8 +50,12 @@ VMEntryScope::VMEntryScope(VM& vm, JSGlobalObject* globalObject)
         vm.resetDateCache();
     }
 
-    // Clear the captured exception stack between entries
-    vm.clearExceptionStack();
+    vm.clearLastException();
+}
+
+void VMEntryScope::setEntryScopeDidPopListener(void* key, EntryScopeDidPopListener listener)
+{
+    m_allEntryScopeDidPopListeners.set(key, listener);
 }
 
 VMEntryScope::~VMEntryScope()
@@ -62,10 +65,8 @@ VMEntryScope::~VMEntryScope()
 
     m_vm.entryScope = nullptr;
 
-    if (m_recompilationNeeded) {
-        if (Debugger* debugger = m_globalObject->debugger())
-            debugger->recompileAllJSFunctions(&m_vm);
-    }
+    for (auto& listener : m_allEntryScopeDidPopListeners.values())
+        listener(m_vm, m_globalObject);
 }
 
 } // namespace JSC
index 854e797f20e4c8568f55a0fc87c9ad912593a5dc..6a62831b81b9ef864782f8962df9adbc0395d594 100644 (file)
@@ -27,6 +27,7 @@
 #define VMEntryScope_h
 
 #include "Interpreter.h"
+#include <wtf/HashMap.h>
 #include <wtf/StackBounds.h>
 #include <wtf/StackStats.h>
 
@@ -42,12 +43,13 @@ public:
 
     JSGlobalObject* globalObject() const { return m_globalObject; }
 
-    void setRecompilationNeeded(bool recompileNeeded) { m_recompilationNeeded = recompileNeeded; }
+    typedef std::function<void (VM&, JSGlobalObject*)> EntryScopeDidPopListener;
+    void setEntryScopeDidPopListener(void*, EntryScopeDidPopListener);
 
 private:
     VM& m_vm;
     JSGlobalObject* m_globalObject;
-    bool m_recompilationNeeded;
+    HashMap<void*, EntryScopeDidPopListener> m_allEntryScopeDidPopListeners;
 };
 
 } // namespace JSC
diff --git a/runtime/VarOffset.cpp b/runtime/VarOffset.cpp
new file mode 100644 (file)
index 0000000..e0d65e5
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "VarOffset.h"
+
+namespace JSC {
+
+void VarOffset::dump(PrintStream& out) const
+{
+    switch (m_kind) {
+    case VarKind::Invalid:
+        out.print("invalid");
+        return;
+    case VarKind::Scope:
+        out.print(scopeOffset());
+        return;
+    case VarKind::Stack:
+        out.print(stackOffset());
+        return;
+    case VarKind::DirectArgument:
+        out.print(capturedArgumentsOffset());
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, VarKind varKind)
+{
+    switch (varKind) {
+    case VarKind::Invalid:
+        out.print("Invalid");
+        return;
+    case VarKind::Scope:
+        out.print("Scope");
+        return;
+    case VarKind::Stack:
+        out.print("Stack");
+        return;
+    case VarKind::DirectArgument:
+        out.print("DirectArgument");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
diff --git a/runtime/VarOffset.h b/runtime/VarOffset.h
new file mode 100644 (file)
index 0000000..b844f57
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef VarOffset_h
+#define VarOffset_h
+
+#include "DirectArgumentsOffset.h"
+#include "ScopeOffset.h"
+#include "VirtualRegister.h"
+#include <wtf/HashMap.h>
+
+namespace JSC {
+
+enum class VarKind : uint8_t {
+    Invalid,
+    Scope,
+    Stack,
+    DirectArgument
+};
+
+class VarOffset {
+public:
+    VarOffset()
+        : m_kind(VarKind::Invalid)
+        , m_offset(UINT_MAX)
+    {
+    }
+    
+    VarOffset(WTF::HashTableDeletedValueType)
+        : m_kind(VarKind::Invalid)
+        , m_offset(0)
+    {
+    }
+    
+    explicit VarOffset(VirtualRegister stackOffset)
+    {
+        if (!stackOffset.isValid()) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::Stack;
+            m_offset = stackOffset.offset();
+        }
+    }
+    
+    explicit VarOffset(ScopeOffset scopeOffset)
+    {
+        if (!scopeOffset) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::Scope;
+            m_offset = scopeOffset.offset();
+        }
+    }
+    
+    explicit VarOffset(DirectArgumentsOffset capturedArgumentsOffset)
+    {
+        if (!capturedArgumentsOffset) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::DirectArgument;
+            m_offset = capturedArgumentsOffset.offset();
+        }
+    }
+    
+    static VarOffset assemble(VarKind kind, unsigned offset)
+    {
+        VarOffset result;
+        result.m_kind = kind;
+        result.m_offset = offset;
+        result.checkSanity();
+        return result;
+    }
+    
+    bool isValid() const
+    {
+        return m_kind != VarKind::Invalid;
+    }
+    
+    bool operator!() const
+    {
+        return !isValid();
+    }
+    
+    VarKind kind() const { return m_kind; }
+    
+    bool isStack() const
+    {
+        return m_kind == VarKind::Stack;
+    }
+    
+    bool isScope() const
+    {
+        return m_kind == VarKind::Scope;
+    }
+    
+    bool isDirectArgument() const
+    {
+        return m_kind == VarKind::DirectArgument;
+    }
+    
+    VirtualRegister stackOffsetUnchecked() const
+    {
+        if (!isStack())
+            return VirtualRegister();
+        return VirtualRegister(m_offset);
+    }
+    
+    ScopeOffset scopeOffsetUnchecked() const
+    {
+        if (!isScope())
+            return ScopeOffset();
+        return ScopeOffset(m_offset);
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffsetUnchecked() const
+    {
+        if (!isDirectArgument())
+            return DirectArgumentsOffset();
+        return DirectArgumentsOffset(m_offset);
+    }
+    
+    VirtualRegister stackOffset() const
+    {
+        ASSERT(isStack());
+        return VirtualRegister(m_offset);
+    }
+    
+    ScopeOffset scopeOffset() const
+    {
+        ASSERT(isScope());
+        return ScopeOffset(m_offset);
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffset() const
+    {
+        ASSERT(isDirectArgument());
+        return DirectArgumentsOffset(m_offset);
+    }
+    
+    unsigned rawOffset() const
+    {
+        ASSERT(isValid());
+        return m_offset;
+    }
+    
+    void checkSanity() const
+    {
+        if (ASSERT_DISABLED)
+            return;
+        
+        switch (m_kind) {
+        case VarKind::Invalid:
+            ASSERT(m_offset == UINT_MAX);
+            return;
+        case VarKind::Scope:
+            ASSERT(scopeOffset());
+            return;
+        case VarKind::Stack:
+            ASSERT(stackOffset().isValid());
+            return;
+        case VarKind::DirectArgument:
+            ASSERT(capturedArgumentsOffset());
+            return;
+        }
+        
+        ASSERT_NOT_REACHED();
+    }
+    
+    bool operator==(const VarOffset& other) const
+    {
+        return m_kind == other.m_kind
+            && m_offset == other.m_offset;
+    }
+    
+    bool operator!=(const VarOffset& other) const
+    {
+        return !(*this == other);
+    }
+    
+    unsigned hash() const
+    {
+        return WTF::IntHash<unsigned>::hash((static_cast<unsigned>(m_kind) << 20) + m_offset);
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_kind == VarKind::Invalid && !m_offset;
+    }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    VarKind m_kind;
+    unsigned m_offset;
+};
+
+struct VarOffsetHash {
+    static unsigned hash(const VarOffset& key) { return key.hash(); }
+    static bool equal(const VarOffset& a, const VarOffset& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::VarKind);
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::VarOffset> {
+    typedef JSC::VarOffsetHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::VarOffset> : SimpleClassHashTraits<JSC::VarOffset> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+#endif // VarOffset_h
+
index 5b1fe2b29671e9d518f732f390792ba449d3f49e..7c3ff1c2831d79e0c66862fd076d26c9dc192685 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace JSC {
 
-#define NO_LIMIT std::numeric_limits<double>::infinity()
+#define NO_LIMIT std::chrono::microseconds::max()
 
 Watchdog::Watchdog()
     : m_timerDidFire(false)
@@ -56,7 +56,7 @@ Watchdog::~Watchdog()
     destroyTimer();
 }
 
-void Watchdog::setTimeLimit(VM& vm, double limit,
+void Watchdog::setTimeLimit(VM& vm, std::chrono::microseconds limit,
     ShouldTerminateCallback callback, void* data1, void* data2)
 {
     bool wasEnabled = isEnabled();
@@ -97,9 +97,9 @@ bool Watchdog::didFire(ExecState* exec)
     m_timerDidFire = false;
     stopCountdown();
 
-    double currentTime = currentCPUTime();
-    double deltaTime = currentTime - m_startTime;
-    double totalElapsedTime = m_elapsedTime + deltaTime;
+    auto currentTime = currentCPUTime();
+    auto deltaTime = currentTime - m_startTime;
+    auto totalElapsedTime = m_elapsedTime + deltaTime;
     if (totalElapsedTime > m_limit) {
         // Case 1: the allowed CPU time has elapsed.
 
@@ -121,7 +121,7 @@ bool Watchdog::didFire(ExecState* exec)
 
         // Tell the timer to alarm us again when it thinks we've reached the
         // end of the allowed time.
-        double remainingTime = m_limit - totalElapsedTime;
+        auto remainingTime = m_limit - totalElapsedTime;
         m_elapsedTime = totalElapsedTime;
         m_startTime = currentTime;
         startCountdown(remainingTime);
@@ -164,13 +164,13 @@ void Watchdog::startCountdownIfNeeded()
         return; // Not executing JS script. No need to start.
 
     if (isEnabled()) {
-        m_elapsedTime = 0;
+        m_elapsedTime = std::chrono::microseconds::zero();
         m_startTime = currentCPUTime();
         startCountdown(m_limit);
     }
 }
 
-void Watchdog::startCountdown(double limit)
+void Watchdog::startCountdown(std::chrono::microseconds limit)
 {
     ASSERT(m_isStopped);
     m_isStopped = false;
index 518fd9d7d0e5a33c803addab24f53f260d630737..91d8d641f05fb67f68821b8dbbb9bb878020385c 100644 (file)
@@ -43,7 +43,7 @@ public:
     ~Watchdog();
 
     typedef bool (*ShouldTerminateCallback)(ExecState*, void* data1, void* data2);
-    void setTimeLimit(VM&, double seconds, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0);
+    void setTimeLimit(VM&, std::chrono::microseconds limit, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0);
 
     // This version of didFire() will check the elapsed CPU time and call the
     // callback (if needed) to determine if the watchdog should fire.
@@ -63,14 +63,14 @@ private:
     void arm();
     void disarm();
     void startCountdownIfNeeded();
-    void startCountdown(double limit);
+    void startCountdown(std::chrono::microseconds limit);
     void stopCountdown();
     bool isArmed() { return !!m_reentryCount; }
 
     // Platform specific timer implementation:
     void initTimer();
     void destroyTimer();
-    void startTimer(double limit);
+    void startTimer(std::chrono::microseconds limit);
     void stopTimer();
 
     // m_timerDidFire (above) indicates whether the timer fired. The Watchdog
@@ -81,10 +81,9 @@ private:
     bool m_timerDidFire;
     bool m_didFire;
 
-    // All time units are in seconds.
-    double m_limit;
-    double m_startTime;
-    double m_elapsedTime;
+    std::chrono::microseconds m_limit;
+    std::chrono::microseconds m_startTime;
+    std::chrono::microseconds m_elapsedTime;
 
     int m_reentryCount;
     bool m_isStopped;
index ca474df2f18d3f228d14f467223574e12a36c6bd..34f2ed33881783cb83cabb6d0a2e9acbfe786a1c 100644 (file)
@@ -41,7 +41,7 @@ void Watchdog::destroyTimer()
         dispatch_release(m_queue);
 }
 
-void Watchdog::startTimer(double limit)
+void Watchdog::startTimer(std::chrono::microseconds limit)
 {
     ASSERT(!m_timer);
     if (!m_queue)
@@ -49,7 +49,7 @@ void Watchdog::startTimer(double limit)
     m_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_queue);
 
     dispatch_source_set_timer(m_timer,
-        dispatch_time(DISPATCH_TIME_NOW, limit * NSEC_PER_SEC),
+        dispatch_time(DISPATCH_TIME_NOW, std::chrono::nanoseconds(limit).count()),
         DISPATCH_TIME_FOREVER, 0);
 
     dispatch_source_set_event_handler(m_timer, ^{
index 615314bb3da92895b5f476dd5091c390452c39f3..d7b7cd57a617bf1f955707a344d6709221643555 100644 (file)
@@ -39,7 +39,7 @@ void Watchdog::destroyTimer()
 {
 }
 
-void Watchdog::startTimer(double)
+void Watchdog::startTimer(std::chrono::microseconds)
 {
 }
 
index cc0fb8f578be572d39f8c86b917846fbfdd471f5..16d3d44000437853fb83da2ab1830303319b4b9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -47,10 +47,8 @@ public:
     typedef typename HashMapType::iterator iterator;
     typedef typename HashMapType::const_iterator const_iterator;
 
-    WeakGCMap()
-        : m_gcThreshold(minGCThreshold)
-    {
-    }
+    explicit WeakGCMap(VM&);
+    ~WeakGCMap();
 
     ValueArg* get(const KeyType& key) const
     {
@@ -59,21 +57,9 @@ public:
 
     AddResult set(const KeyType& key, ValueType value)
     {
-        gcMapIfNeeded();
         return m_map.set(key, WTF::move(value));
     }
 
-    ALWAYS_INLINE AddResult add(const KeyType& key, ValueType value)
-    {
-        gcMapIfNeeded();
-        AddResult addResult = m_map.fastAdd(key, nullptr);
-        if (!addResult.iterator->value) { // New value or found a zombie value.
-            addResult.isNewEntry = true;
-            addResult.iterator->value = WTF::move(value);
-        }
-        return addResult;
-    }
-
     bool remove(const KeyType& key)
     {
         return m_map.remove(key);
@@ -84,6 +70,17 @@ public:
         m_map.clear();
     }
 
+    bool isEmpty() const
+    {
+        const_iterator it = m_map.begin();
+        const_iterator end = m_map.end();
+        while (it != end) {
+            if (it->value)
+                return true;
+        }
+        return false;
+    }
+
     iterator find(const KeyType& key)
     {
         iterator it = m_map.find(key);
@@ -98,43 +95,27 @@ public:
         return const_cast<WeakGCMap*>(this)->find(key);
     }
 
-    bool contains(const KeyType& key) const
+    template<typename Functor>
+    void forEach(Functor functor)
     {
-        return find(key) != m_map.end();
-    }
-
-private:
-    static const int minGCThreshold = 3;
-
-    NEVER_INLINE void gcMap()
-    {
-        Vector<KeyType, 4> zombies;
-
-        for (iterator it = m_map.begin(), end = m_map.end(); it != end; ++it) {
-            if (!it->value)
-                zombies.append(it->key);
+        for (auto& pair : m_map) {
+            if (pair.value)
+                functor(pair.key, pair.value.get());
         }
-
-        for (size_t i = 0; i < zombies.size(); ++i)
-            m_map.remove(zombies[i]);
     }
 
-    void gcMapIfNeeded()
+    bool contains(const KeyType& key) const
     {
-        if (m_map.size() < m_gcThreshold)
-            return;
-
-        gcMap();
-        m_gcThreshold = std::max(minGCThreshold, m_map.size() * 2 - 1);
+        return find(key) != m_map.end();
     }
 
+    void pruneStaleEntries();
+
+private:
     HashMapType m_map;
-    int m_gcThreshold;
+    VM& m_vm;
 };
 
-template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
-const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
-
 } // namespace JSC
 
 #endif // WeakGCMap_h
diff --git a/runtime/WeakGCMapInlines.h b/runtime/WeakGCMapInlines.h
new file mode 100644 (file)
index 0000000..b90acc0
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WeakGCMapInlines_h
+#define WeakGCMapInlines_h
+
+#include "HeapInlines.h"
+#include "WeakGCMap.h"
+
+namespace JSC {
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::WeakGCMap(VM& vm)
+    : m_vm(vm)
+{
+    vm.heap.registerWeakGCMap(this, [this]() {
+        pruneStaleEntries();
+    });
+}
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::~WeakGCMap()
+{
+    m_vm.heap.unregisterWeakGCMap(this);
+}
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+NEVER_INLINE void WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::pruneStaleEntries()
+{
+    m_map.removeIf([](typename HashMapType::KeyValuePairType& entry) {
+        return !entry.value;
+    });
+}
+
+} // namespace JSC
+
+#endif // WeakGCMapInlines_h
index 03af73e5de65e89754e333da08ab1883d026df0f..23c43330d62ef09727ff6b912456a50404da78a9 100644 (file)
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "WeakMapConstructor.h"
 
+#include "Error.h"
+#include "IteratorOperations.h"
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
@@ -35,7 +37,7 @@
 
 namespace JSC {
 
-const ClassInfo WeakMapConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(WeakMapConstructor) };
+const ClassInfo WeakMapConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(WeakMapConstructor) };
 
 void WeakMapConstructor::finishCreation(VM& vm, WeakMapPrototype* prototype)
 {
@@ -44,11 +46,87 @@ void WeakMapConstructor::finishCreation(VM& vm, WeakMapPrototype* prototype)
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum | DontDelete);
 }
 
+static EncodedJSValue JSC_HOST_CALL callWeakMap(ExecState* exec)
+{
+    return JSValue::encode(throwTypeError(exec, ASCIILiteral("WeakMap cannot be called as a function")));
+}
+
 static EncodedJSValue JSC_HOST_CALL constructWeakMap(ExecState* exec)
 {
     JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
-    Structure* structure = globalObject->weakMapStructure();
-    return JSValue::encode(JSWeakMap::create(exec, structure));
+    Structure* weakMapStructure = globalObject->weakMapStructure();
+    JSWeakMap* weakMap = JSWeakMap::create(exec, weakMapStructure);
+    JSValue iterable = exec->argument(0);
+    if (iterable.isUndefinedOrNull())
+        return JSValue::encode(weakMap);
+
+    JSValue adderFunction = weakMap->JSObject::get(exec, exec->propertyNames().set);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData adderFunctionCallData;
+    CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
+    if (adderFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData iteratorFunctionCallData;
+    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
+    if (iteratorFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    ArgList iteratorFunctionArguments;
+    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    if (!iterator.isObject())
+        return JSValue::encode(throwTypeError(exec));
+
+    while (true) {
+        JSValue next = iteratorStep(exec, iterator);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (next.isFalse())
+            return JSValue::encode(weakMap);
+
+        JSValue nextItem = iteratorValue(exec, next);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (!nextItem.isObject()) {
+            throwTypeError(exec);
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        JSValue key = nextItem.get(exec, 0);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        JSValue value = nextItem.get(exec, 1);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(key);
+        arguments.append(value);
+        call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakMap, arguments);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return JSValue::encode(weakMap);
 }
 
 ConstructType WeakMapConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -57,9 +135,10 @@ ConstructType WeakMapConstructor::getConstructData(JSCell*, ConstructData& const
     return ConstructTypeHost;
 }
 
-CallType WeakMapConstructor::getCallData(JSCell*, CallData&)
+CallType WeakMapConstructor::getCallData(JSCell*, CallData& callData)
 {
-    return CallTypeNone;
+    callData.native.function = callWeakMap;
+    return CallTypeHost;
 }
 
 }
index 224be8a4668fd34c94954f559d96ccea88bd8b3a..8ee9de74a3753604f3c2e92fb84734aaa152eb23 100644 (file)
@@ -36,7 +36,7 @@
 
 namespace JSC {
 
-const ClassInfo WeakMapData::s_info = { "WeakMapData", 0, 0, 0, CREATE_METHOD_TABLE(WeakMapData) };
+const ClassInfo WeakMapData::s_info = { "WeakMapData", 0, 0, CREATE_METHOD_TABLE(WeakMapData) };
 
 WeakMapData::WeakMapData(VM& vm)
     : Base(vm, vm.weakMapDataStructure.get())
@@ -64,7 +64,7 @@ void WeakMapData::visitChildren(JSCell* cell, SlotVisitor& visitor)
     // Rough approximation of the external storage needed for the hashtable.
     // This isn't exact, but it is close enough, and proportional to the actual
     // external mermory usage.
-    visitor.reportExtraMemoryUsage(thisObj, thisObj->m_map.capacity() * (sizeof(JSObject*) + sizeof(WriteBarrier<Unknown>)));
+    visitor.reportExtraMemoryVisited(thisObj, thisObj->m_map.capacity() * (sizeof(JSObject*) + sizeof(WriteBarrier<Unknown>)));
 }
 
 void WeakMapData::set(VM& vm, JSObject* key, JSValue value)
index 07c2032e0aa1d8cc2982ce7f67295929ccf86009..cfcd85355be51a4bdc33c434ba00a8c664a097e4 100644 (file)
 
 namespace JSC {
 
-class WeakMapData : public JSCell {
+class WeakMapData final : public JSCell {
 public:
     typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
     static WeakMapData* create(VM& vm)
     {
@@ -47,11 +48,10 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     }
 
     static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
 
     void set(VM&, JSObject*, JSValue);
     JSValue get(JSObject*);
@@ -61,7 +61,11 @@ public:
 
     DECLARE_INFO;
 
-    static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | Base::StructureFlags;
+    typedef HashMap<JSObject*, WriteBarrier<Unknown>> MapType;
+    MapType::const_iterator begin() const { return m_map.begin(); }
+    MapType::const_iterator end() const { return m_map.end(); }
+
+    int size() const { return m_map.size(); }
 
 private:
     WeakMapData(VM&);
@@ -78,11 +82,10 @@ private:
     private:
         virtual void visitWeakReferences(SlotVisitor&) override;
         virtual void finalizeUnconditionally() override;
-        int m_liveKeyCount;
+        unsigned m_liveKeyCount;
         WeakMapData* m_target;
     };
     DeadKeyCleaner m_deadKeyCleaner;
-    typedef HashMap<JSObject*, WriteBarrier<Unknown>> MapType;
     MapType m_map;
 };
 
index 64eeb8de823f4b499ff310669d0f00f640cd361f..71c4c405537a50498216440da99730ace055078c 100644 (file)
@@ -33,9 +33,8 @@
 
 namespace JSC {
 
-const ClassInfo WeakMapPrototype::s_info = { "WeakMap", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(WeakMapPrototype) };
+const ClassInfo WeakMapPrototype::s_info = { "WeakMap", &Base::s_info, 0, CREATE_METHOD_TABLE(WeakMapPrototype) };
 
-static EncodedJSValue JSC_HOST_CALL protoFuncWeakMapClear(ExecState*);
 static EncodedJSValue JSC_HOST_CALL protoFuncWeakMapDelete(ExecState*);
 static EncodedJSValue JSC_HOST_CALL protoFuncWeakMapGet(ExecState*);
 static EncodedJSValue JSC_HOST_CALL protoFuncWeakMapHas(ExecState*);
@@ -47,7 +46,6 @@ void WeakMapPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
     ASSERT(inherits(info()));
     vm.prototypeMap.addPrototype(this);
 
-    JSC_NATIVE_FUNCTION(vm.propertyNames->clear, protoFuncWeakMapClear, DontEnum, 0);
     JSC_NATIVE_FUNCTION(vm.propertyNames->deleteKeyword, protoFuncWeakMapDelete, DontEnum, 1);
     JSC_NATIVE_FUNCTION(vm.propertyNames->get, protoFuncWeakMapGet, DontEnum, 1);
     JSC_NATIVE_FUNCTION(vm.propertyNames->has, protoFuncWeakMapHas, DontEnum, 1);
@@ -58,23 +56,14 @@ static WeakMapData* getWeakMapData(CallFrame* callFrame, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(callFrame, WTF::ASCIILiteral("Called WeakMap function on non-object"));
-        return 0;
+        return nullptr;
     }
 
     if (JSWeakMap* weakMap = jsDynamicCast<JSWeakMap*>(value))
         return weakMap->weakMapData();
 
     throwTypeError(callFrame, WTF::ASCIILiteral("Called WeakMap function on a non-WeakMap object"));
-    return 0;
-}
-
-EncodedJSValue JSC_HOST_CALL protoFuncWeakMapClear(CallFrame* callFrame)
-{
-    WeakMapData* map = getWeakMapData(callFrame, callFrame->thisValue());
-    if (!map)
-        return JSValue::encode(jsUndefined());
-    map->clear();
-    return JSValue::encode(jsUndefined());
+    return nullptr;
 }
 
 EncodedJSValue JSC_HOST_CALL protoFuncWeakMapDelete(CallFrame* callFrame)
@@ -83,9 +72,7 @@ EncodedJSValue JSC_HOST_CALL protoFuncWeakMapDelete(CallFrame* callFrame)
     if (!map)
         return JSValue::encode(jsUndefined());
     JSValue key = callFrame->argument(0);
-    if (!key.isObject())
-        return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("A WeakMap cannot have a non-object key")));
-    return JSValue::encode(jsBoolean(map->remove(asObject(key))));
+    return JSValue::encode(jsBoolean(key.isObject() && map->remove(asObject(key))));
 }
 
 EncodedJSValue JSC_HOST_CALL protoFuncWeakMapGet(CallFrame* callFrame)
@@ -95,7 +82,7 @@ EncodedJSValue JSC_HOST_CALL protoFuncWeakMapGet(CallFrame* callFrame)
         return JSValue::encode(jsUndefined());
     JSValue key = callFrame->argument(0);
     if (!key.isObject())
-        return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("A WeakMap cannot have a non-object key")));
+        return JSValue::encode(jsUndefined());
     return JSValue::encode(map->get(asObject(key)));
 }
 
@@ -105,9 +92,7 @@ EncodedJSValue JSC_HOST_CALL protoFuncWeakMapHas(CallFrame* callFrame)
     if (!map)
         return JSValue::encode(jsUndefined());
     JSValue key = callFrame->argument(0);
-    if (!key.isObject())
-        return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("A WeakMap cannot have a non-object key")));
-    return JSValue::encode(jsBoolean(map->contains(asObject(key))));
+    return JSValue::encode(jsBoolean(key.isObject() && map->contains(asObject(key))));
 }
 
 EncodedJSValue JSC_HOST_CALL protoFuncWeakMapSet(CallFrame* callFrame)
diff --git a/runtime/WeakSetConstructor.cpp b/runtime/WeakSetConstructor.cpp
new file mode 100644 (file)
index 0000000..f24ea81
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "WeakSetConstructor.h"
+
+#include "Error.h"
+#include "IteratorOperations.h"
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "JSGlobalObject.h"
+#include "JSWeakSet.h"
+#include "StructureInlines.h"
+#include "WeakSetPrototype.h"
+
+namespace JSC {
+
+const ClassInfo WeakSetConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(WeakSetConstructor) };
+
+void WeakSetConstructor::finishCreation(VM& vm, WeakSetPrototype* prototype)
+{
+    Base::finishCreation(vm, prototype->classInfo()->className);
+    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum | DontDelete);
+}
+
+static EncodedJSValue JSC_HOST_CALL callWeakSet(ExecState* exec)
+{
+    return JSValue::encode(throwTypeError(exec, ASCIILiteral("WeakSet cannot be called as a function")));
+}
+
+static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec)
+{
+    JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
+    Structure* weakSetStructure = globalObject->weakSetStructure();
+    JSWeakSet* weakSet = JSWeakSet::create(exec, weakSetStructure);
+    JSValue iterable = exec->argument(0);
+    if (iterable.isUndefinedOrNull())
+        return JSValue::encode(weakSet);
+
+    JSValue adderFunction = weakSet->JSObject::get(exec, exec->propertyNames().add);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData adderFunctionCallData;
+    CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
+    if (adderFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    CallData iteratorFunctionCallData;
+    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
+    if (iteratorFunctionCallType == CallTypeNone)
+        return JSValue::encode(throwTypeError(exec));
+
+    ArgList iteratorFunctionArguments;
+    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    if (!iterator.isObject())
+        return JSValue::encode(throwTypeError(exec));
+
+    while (true) {
+        JSValue next = iteratorStep(exec, iterator);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        if (next.isFalse())
+            return JSValue::encode(weakSet);
+
+        JSValue nextValue = iteratorValue(exec, next);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(nextValue);
+        call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakSet, arguments);
+        if (exec->hadException()) {
+            iteratorClose(exec, iterator);
+            return JSValue::encode(jsUndefined());
+        }
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return JSValue::encode(weakSet);
+}
+
+ConstructType WeakSetConstructor::getConstructData(JSCell*, ConstructData& constructData)
+{
+    constructData.native.function = constructWeakSet;
+    return ConstructTypeHost;
+}
+
+CallType WeakSetConstructor::getCallData(JSCell*, CallData& callData)
+{
+    callData.native.function = callWeakSet;
+    return CallTypeHost;
+}
+
+}
diff --git a/runtime/WeakSetConstructor.h b/runtime/WeakSetConstructor.h
new file mode 100644 (file)
index 0000000..7f6fb6a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WeakSetConstructor_h
+#define WeakSetConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+class WeakSetPrototype;
+
+class WeakSetConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+
+    static WeakSetConstructor* create(VM& vm, Structure* structure, WeakSetPrototype* prototype)
+    {
+        WeakSetConstructor* constructor = new (NotNull, allocateCell<WeakSetConstructor>(vm.heap)) WeakSetConstructor(vm, structure);
+        constructor->finishCreation(vm, prototype);
+        return constructor;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    WeakSetConstructor(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    void finishCreation(VM&, WeakSetPrototype*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
+
+}
+
+#endif // !defined(WeakSetConstructor_h)
diff --git a/runtime/WeakSetPrototype.cpp b/runtime/WeakSetPrototype.cpp
new file mode 100644 (file)
index 0000000..b718af7
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "WeakSetPrototype.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSWeakSet.h"
+#include "StructureInlines.h"
+#include "WeakMapData.h"
+
+namespace JSC {
+
+const ClassInfo WeakSetPrototype::s_info = { "WeakSet", &Base::s_info, 0, CREATE_METHOD_TABLE(WeakSetPrototype) };
+
+static EncodedJSValue JSC_HOST_CALL protoFuncWeakSetDelete(ExecState*);
+static EncodedJSValue JSC_HOST_CALL protoFuncWeakSetHas(ExecState*);
+static EncodedJSValue JSC_HOST_CALL protoFuncWeakSetAdd(ExecState*);
+
+void WeakSetPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(info()));
+    vm.prototypeMap.addPrototype(this);
+
+    JSC_NATIVE_FUNCTION(vm.propertyNames->deleteKeyword, protoFuncWeakSetDelete, DontEnum, 1);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->has, protoFuncWeakSetHas, DontEnum, 1);
+    JSC_NATIVE_FUNCTION(vm.propertyNames->add, protoFuncWeakSetAdd, DontEnum, 1);
+}
+
+static WeakMapData* getWeakMapData(CallFrame* callFrame, JSValue value)
+{
+    if (!value.isObject()) {
+        throwTypeError(callFrame, WTF::ASCIILiteral("Called WeakSet function on non-object"));
+        return nullptr;
+    }
+
+    if (JSWeakSet* weakSet = jsDynamicCast<JSWeakSet*>(value))
+        return weakSet->weakMapData();
+
+    throwTypeError(callFrame, WTF::ASCIILiteral("Called WeakSet function on a non-WeakSet object"));
+    return nullptr;
+}
+
+EncodedJSValue JSC_HOST_CALL protoFuncWeakSetDelete(CallFrame* callFrame)
+{
+    WeakMapData* map = getWeakMapData(callFrame, callFrame->thisValue());
+    if (!map)
+        return JSValue::encode(jsUndefined());
+    JSValue key = callFrame->argument(0);
+    return JSValue::encode(jsBoolean(key.isObject() && map->remove(asObject(key))));
+}
+
+EncodedJSValue JSC_HOST_CALL protoFuncWeakSetHas(CallFrame* callFrame)
+{
+    WeakMapData* map = getWeakMapData(callFrame, callFrame->thisValue());
+    if (!map)
+        return JSValue::encode(jsUndefined());
+    JSValue key = callFrame->argument(0);
+    return JSValue::encode(jsBoolean(key.isObject() && map->contains(asObject(key))));
+}
+
+EncodedJSValue JSC_HOST_CALL protoFuncWeakSetAdd(CallFrame* callFrame)
+{
+    WeakMapData* map = getWeakMapData(callFrame, callFrame->thisValue());
+    if (!map)
+        return JSValue::encode(jsUndefined());
+    JSValue key = callFrame->argument(0);
+    if (!key.isObject())
+        return JSValue::encode(throwTypeError(callFrame, WTF::ASCIILiteral("Attempted to add a non-object key to a WeakSet")));
+    map->set(callFrame->vm(), asObject(key), jsUndefined());
+    return JSValue::encode(callFrame->thisValue());
+}
+
+}
diff --git a/runtime/WeakSetPrototype.h b/runtime/WeakSetPrototype.h
new file mode 100644 (file)
index 0000000..94d90f9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WeakSetPrototype_h
+#define WeakSetPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class WeakSetPrototype : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    static WeakSetPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        WeakSetPrototype* prototype = new (NotNull, allocateCell<WeakSetPrototype>(vm.heap)) WeakSetPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    WeakSetPrototype(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    void finishCreation(VM&, JSGlobalObject*);
+};
+
+}
+
+#endif // !defined(WeakSetPrototype_h)
index c5fe089aa96b36420ab2936529efb907a6c37cc2..74fbe356963beac2fe2543fd1c3b0139198c0f59 100644 (file)
@@ -113,8 +113,7 @@ public:
     
     T** slot() { return reinterpret_cast<T**>(&m_cell); }
     
-    typedef T* (WriteBarrierBase::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return m_cell ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return m_cell; }
     
     bool operator!() const { return !m_cell; }
 
@@ -126,9 +125,7 @@ public:
         this->m_cell = reinterpret_cast<JSCell*>(value);
     }
 
-#if ENABLE(GC_VALIDATION)
     T* unvalidatedGet() const { return reinterpret_cast<T*>(static_cast<void*>(m_cell)); }
-#endif
 
 private:
     JSCell* m_cell;
@@ -167,8 +164,7 @@ public:
     int32_t* tagPointer() { return &bitwise_cast<EncodedValueDescriptor*>(&m_value)->asBits.tag; }
     int32_t* payloadPointer() { return &bitwise_cast<EncodedValueDescriptor*>(&m_value)->asBits.payload; }
     
-    typedef JSValue (WriteBarrierBase::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    explicit operator bool() const { return !!get(); }
     bool operator!() const { return !get(); } 
     
 private:
@@ -201,6 +197,7 @@ public:
     }
 };
 
+enum UndefinedWriteBarrierTagType { UndefinedWriteBarrierTag };
 template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -208,6 +205,10 @@ public:
     {
         this->setWithoutWriteBarrier(JSValue());
     }
+    WriteBarrier(UndefinedWriteBarrierTagType)
+    {
+        this->setWithoutWriteBarrier(jsUndefined());
+    }
 
     WriteBarrier(VM& vm, const JSCell* owner, JSValue value)
     {
index fc95a6300a6e73913b2bc451b5dfa40dba934a4a..d1941592bd79fafea75f4b080a026b679919c624 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Apple Inc. All rights reserved.
+ *  Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #include <sys/time.h>
 #endif
 
-#if COMPILER(MSVC) && !OS(WINCE)
+#if COMPILER(MSVC)
 #include <crtdbg.h>
 #include <mmsystem.h>
 #include <windows.h>
 #endif
 
+namespace JSC {
+WTF_IMPORT extern const struct HashTable globalObjectTable;
+}
+
 const int MaxLineLength = 100 * 1024;
 
 using namespace JSC;
@@ -133,7 +137,7 @@ protected:
     }
 };
 
-const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
+const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, &globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
 
 GlobalObject::GlobalObject(VM& vm, Structure* structure, const Vector<String>& arguments)
     : JSGlobalObject(vm, structure)
@@ -146,7 +150,7 @@ GlobalObject::GlobalObject(VM& vm, Structure* structure, const Vector<String>& a
 // be in a separate main function because the realMain function requires object
 // unwinding.
 
-#if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE)
+#if COMPILER(MSVC) && !defined(_DEBUG)
 #define TRY       __try {
 #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
 #else
@@ -159,12 +163,19 @@ int realMain(int argc, char** argv);
 int main(int argc, char** argv)
 {
 #if OS(WINDOWS)
-#if !OS(WINCE)
+#if defined(_M_X64) || defined(__x86_64__)
+    // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
+    // if the feature has been disabled in firmware. This causes us to crash
+    // in some of the math functions. For now, we disable those optimizations
+    // because Microsoft is not going to fix the problem in VS2013.
+    // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
+    _set_FMA3_enable(0);
+#endif
+
     // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
     // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
     // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
     ::SetErrorMode(0);
-#endif
 
 #if defined(_DEBUG)
     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
@@ -204,12 +215,22 @@ static bool testOneRegExp(VM& vm, RegExp* regexp, RegExpTest* regExpTest, bool v
     } else if (matchResult != -1) {
         if (outVector.size() != regExpTest->expectVector.size()) {
             result = false;
-            if (verbose)
-                printf("Line %d: output vector size mismatch - expected %lu got %lu\n", lineNumber, regExpTest->expectVector.size(), outVector.size());
+            if (verbose) {
+#if OS(WINDOWS)
+                printf("Line %d: output vector size mismatch - expected %Iu got %Iu\n", lineNumber, regExpTest->expectVector.size(), outVector.size());
+#else
+                printf("Line %d: output vector size mismatch - expected %zu got %zu\n", lineNumber, regExpTest->expectVector.size(), outVector.size());
+#endif
+            }
         } else if (outVector.size() % 2) {
             result = false;
-            if (verbose)
-                printf("Line %d: output vector size is odd (%lu), should be even\n", lineNumber, outVector.size());
+            if (verbose) {
+#if OS(WINDOWS)
+                printf("Line %d: output vector size is odd (%Iu), should be even\n", lineNumber, outVector.size());
+#else
+                printf("Line %d: output vector size is odd (%zu), should be even\n", lineNumber, outVector.size());
+#endif
+            }
         } else {
             // Check in pairs since the first value of the pair could be -1 in which case the second doesn't matter.
             size_t pairCount = outVector.size() / 2;
@@ -217,13 +238,23 @@ static bool testOneRegExp(VM& vm, RegExp* regexp, RegExpTest* regExpTest, bool v
                 size_t startIndex = i*2;
                 if (outVector[startIndex] != regExpTest->expectVector[startIndex]) {
                     result = false;
-                    if (verbose)
-                        printf("Line %d: output vector mismatch at index %lu - expected %d got %d\n", lineNumber, startIndex, regExpTest->expectVector[startIndex], outVector[startIndex]);
+                    if (verbose) {
+#if OS(WINDOWS)
+                        printf("Line %d: output vector mismatch at index %Iu - expected %d got %d\n", lineNumber, startIndex, regExpTest->expectVector[startIndex], outVector[startIndex]);
+#else
+                        printf("Line %d: output vector mismatch at index %zu - expected %d got %d\n", lineNumber, startIndex, regExpTest->expectVector[startIndex], outVector[startIndex]);
+#endif
+                    }
                 }
                 if ((i > 0) && (regExpTest->expectVector[startIndex] != -1) && (outVector[startIndex+1] != regExpTest->expectVector[startIndex+1])) {
                     result = false;
-                    if (verbose)
-                        printf("Line %d: output vector mismatch at index %lu - expected %d got %d\n", lineNumber, startIndex+1, regExpTest->expectVector[startIndex+1], outVector[startIndex+1]);
+                    if (verbose) {
+#if OS(WINDOWS)
+                        printf("Line %d: output vector mismatch at index %Iu - expected %d got %d\n", lineNumber, startIndex + 1, regExpTest->expectVector[startIndex + 1], outVector[startIndex + 1]);
+#else
+                        printf("Line %d: output vector mismatch at index %zu - expected %d got %d\n", lineNumber, startIndex + 1, regExpTest->expectVector[startIndex + 1], outVector[startIndex + 1]);
+#endif
+                    }
                 }
             }
         }
@@ -488,7 +519,7 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
 
 int realMain(int argc, char** argv)
 {
-    VM* vm = VM::create(LargeHeap).leakRef();
+    VM* vm = &VM::create(LargeHeap).leakRef();
     JSLockHolder locker(vm);
 
     CommandLine options;
@@ -499,3 +530,10 @@ int realMain(int argc, char** argv)
 
     return success ? 0 : 3;
 }
+
+#if OS(WINDOWS)
+extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
+{
+    return main(argc, const_cast<char**>(argv));
+}
+#endif
diff --git a/tested-symbols.symlst b/tested-symbols.symlst
new file mode 100644 (file)
index 0000000..16319d1
--- /dev/null
@@ -0,0 +1,87 @@
+__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateE
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
+__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateE
+__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateE
+__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncASinEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncATanEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncCbrtEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncCoshEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncLog2EPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncSinhEPNS_9ExecStateE
+__ZN3JSCL17mathProtoFuncTanhEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncACoshEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncASinhEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncATanhEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncExpm1EPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncExpm1EPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncHypotEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncLog10EPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncLog1pEPNS_9ExecStateE
+__ZN3JSCL18mathProtoFuncTruncEPNS_9ExecStateE
+__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateE
+__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateE
+__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateE
+__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateE
+__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateE
+__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateE
+__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateE
+__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateE
+__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateE
+__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateE
+__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateE
+__ZN3JSCL22JSONProtoFuncStringifyEPNS_9ExecStateE
+__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateE
+__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateE
+__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateE
+__ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateE
+__ZN3JSCL23objectConstructorFreezeEPNS_9ExecStateE
+__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateE
+__ZN3JSCL24dateProtoFuncGetUTCHoursEPNS_9ExecStateE
+__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateE
+__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncGetUint8EPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncSetUint8EPNS_9ExecStateE
+__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateE
+__ZN3JSCL25dateProtoFuncToTimeStringEPNS_9ExecStateE
+__ZN3JSCL25objectConstructorIsFrozenEPNS_9ExecStateE
+__ZN3JSCL26dateProtoFuncGetUTCMinutesEPNS_9ExecStateE
+__ZN3JSCL26dateProtoFuncGetUTCSecondsEPNS_9ExecStateE
+__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateE
+__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateE
+__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateE
+__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateE
+__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateE
+__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateE
+__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateE
+__ZN3JSCL34objectConstructorPreventExtensionsEPNS_9ExecStateE
+__ZN3JSCL36objectConstructorGetOwnPropertyNamesEPNS_9ExecStateE
+__ZN3JSCL9dateParseEPNS_9ExecStateE
+__ZN3JSC9ExecState13dataViewTableERNS_2VME
+__ZN3JSC13dataViewTableE
+__ZN3JSC19JSDataViewPrototype15createStructureERNS_2VMEPNS_14JSGlobalObjectENS_7JSValueE
+__ZN3JSC1teENS_12PropertyNameERNS_12PropertySlotE
+__ZN3JSC19JSDataViewPrototype6createERNS_2VMEPNS_9StructureE
+__ZN3JSC19JSDataViewPrototype6s_infoE
+__ZN3JSC19JSDataViewPrototypeC1ERNS_2VMEPNS_9Structu1getStaticFunctionSlotINS_8JSObjectEEEbPNS_9ExecStateERKNS_9HashTableEPS1_NS_12PropertyNameERNS_12PropertyS_9ExecStateE
+__ZN3JSC7getDataINS_12Uint8AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7getDataI64AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_11Int8AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_12Int16AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_12Int32AdaptorEEExPNS_9ExecStateE
+__ZNS_13Uint16AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_13Uint32AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_14Float32AdaptorEEExPNS_9ExecStateE
+__ZN3JSC7setDataINS_14Float64AdaptorEEExPNStaViewTableIndexE
+__ZN3JSCL19dataViewTableValuesE
+__ZN3JSCL24dataViewProtoFuncGetInt8EPNS_9ExecStateE
+__ZN3JSCL24dataViewProtoFuncSetInt8EPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncGetInt16EPNZN3JSCL25dataViewProtoFuncGetUint8EPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncSetInt16EPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncSetInt32EPNS_9ExecStateE
+__ZN3JSCL25dataViewProtoFuncSetUintteE
+__ZN3JSCL27dataViewProtoFuncSetFloat32EPNS_9ExecStateE
+__ZN3JSCL27dataViewProtoFuncSetFloat64EPNS_9ExecStateE
+__ZN3JSCL18dataViewTableIndexE
diff --git a/tests/controlFlowProfiler.yaml b/tests/controlFlowProfiler.yaml
new file mode 100644 (file)
index 0000000..7d647d8
--- /dev/null
@@ -0,0 +1,26 @@
+# Copyright (C) 2015 Apple Inc. All rights reserved.
+# Copyright (C) Saam Barati <saambarati1@gmail.com>. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+- path: controlFlowProfiler
+  cmd: runControlFlowProfiler
diff --git a/tests/controlFlowProfiler/brace-location.js b/tests/controlFlowProfiler/brace-location.js
new file mode 100644 (file)
index 0000000..8663cb8
--- /dev/null
@@ -0,0 +1,159 @@
+load("./driver/driver.js");
+
+function foo() {}
+function bar() {}
+function baz() {}
+
+function testIf(x) {
+    if (x < 10) { foo(); } else if (x < 20) { bar(); } else { baz() }
+}
+testIf(9);
+// Note, the check will be against the basic block that contains the first matched character. 
+// So in this following case, the block that contains the '{'.
+checkBasicBlock(testIf, "{ foo", ShouldHaveExecuted);
+// In this case, it will test the basic block that contains the ' ' character.
+checkBasicBlock(testIf, " foo", ShouldHaveExecuted);
+checkBasicBlock(testIf, "} else if", ShouldHaveExecuted);
+checkBasicBlock(testIf, "else if", ShouldNotHaveExecuted);
+checkBasicBlock(testIf, "{ bar", ShouldNotHaveExecuted);
+checkBasicBlock(testIf, " bar", ShouldNotHaveExecuted);
+checkBasicBlock(testIf, "else {", ShouldNotHaveExecuted);
+checkBasicBlock(testIf, "{ baz", ShouldNotHaveExecuted);
+checkBasicBlock(testIf, " baz", ShouldNotHaveExecuted);
+testIf(21);
+checkBasicBlock(testIf, "else if (x < 20)", ShouldHaveExecuted); 
+checkBasicBlock(testIf, "{ bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testIf, " bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testIf, "else {", ShouldHaveExecuted); 
+checkBasicBlock(testIf, "{ baz", ShouldHaveExecuted); 
+checkBasicBlock(testIf, " baz", ShouldHaveExecuted); 
+testIf(11);
+checkBasicBlock(testIf, "{ bar", ShouldHaveExecuted); 
+checkBasicBlock(testIf, " bar", ShouldHaveExecuted); 
+
+function testForRegular(x) {
+    for (var i = 0; i < x; i++) { foo(); } bar();
+}
+testForRegular(0);
+checkBasicBlock(testForRegular, "{ foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForRegular, "} bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForRegular, " bar", ShouldHaveExecuted); 
+testForRegular(1);
+checkBasicBlock(testForRegular, "{ foo", ShouldHaveExecuted); 
+checkBasicBlock(testForRegular, "} bar", ShouldHaveExecuted); 
+
+function testForIn(x) {
+    for (var i in x) { foo(); } bar();
+}
+testForIn({});
+checkBasicBlock(testForIn, "{ foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForIn, "} bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForIn, " bar", ShouldHaveExecuted); 
+testForIn({foo: 20});
+checkBasicBlock(testForIn, "{ foo", ShouldHaveExecuted); 
+checkBasicBlock(testForIn, "} bar", ShouldHaveExecuted); 
+
+function testForOf(x) {
+    for (var i of x) { foo(); } bar();
+}
+testForOf([]);
+checkBasicBlock(testForOf, "{ foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForOf, " foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForOf, "} bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForOf, " bar", ShouldHaveExecuted); 
+testForOf([20]);
+checkBasicBlock(testForOf, "{ foo", ShouldHaveExecuted); 
+checkBasicBlock(testForOf, "} bar", ShouldHaveExecuted); 
+
+function testWhile(x) {
+    var i = 0; while (i++ < x) { foo(); } bar();
+}
+testWhile(0);
+checkBasicBlock(testWhile, "{ foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testWhile, " foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testWhile, "} bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testWhile, " bar", ShouldHaveExecuted); 
+testWhile(1);
+checkBasicBlock(testWhile, "{ foo", ShouldHaveExecuted); 
+checkBasicBlock(testWhile, "} bar", ShouldHaveExecuted); 
+
+
+// No braces tests.
+
+function testIfNoBraces(x) {
+    if (x < 10) foo(); else if (x < 20) bar(); else baz();
+}
+testIfNoBraces(9);
+checkBasicBlock(testIfNoBraces, "foo", ShouldHaveExecuted);
+checkBasicBlock(testIfNoBraces, " foo", ShouldHaveExecuted);
+checkBasicBlock(testIfNoBraces, "; else if", ShouldHaveExecuted);
+checkBasicBlock(testIfNoBraces, " else if", ShouldNotHaveExecuted);
+checkBasicBlock(testIfNoBraces, " bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "else baz", ShouldNotHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "baz", ShouldNotHaveExecuted); 
+testIfNoBraces(21);
+checkBasicBlock(testIfNoBraces, "else baz", ShouldHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "baz", ShouldHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "; else baz", ShouldNotHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "else if (x < 20)", ShouldHaveExecuted);
+// Note that the whitespace preceding bar is part of the previous basic block.
+// An if statement's if-true basic block text offset begins at the start offset
+// of the if-true block, in this case, just the expression "bar()".
+checkBasicBlock(testIfNoBraces, " bar", ShouldHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "bar", ShouldNotHaveExecuted); 
+testIfNoBraces(11);
+checkBasicBlock(testIfNoBraces, " bar", ShouldHaveExecuted); 
+checkBasicBlock(testIfNoBraces, "bar", ShouldHaveExecuted); 
+
+function testForRegularNoBraces(x) {
+    for (var i = 0; i < x; i++) foo(); bar();
+}
+testForRegularNoBraces(0);
+checkBasicBlock(testForRegularNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForRegularNoBraces, "foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForRegularNoBraces, "; bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForRegularNoBraces, " bar", ShouldHaveExecuted); 
+testForRegularNoBraces(1);
+checkBasicBlock(testForRegularNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForRegularNoBraces, "foo", ShouldHaveExecuted); 
+checkBasicBlock(testForRegularNoBraces, " bar", ShouldHaveExecuted); 
+
+function testForInNoBraces(x) {
+    for (var i in x) foo(); bar();
+}
+testForInNoBraces({});
+checkBasicBlock(testForInNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForInNoBraces, "foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForInNoBraces, "; bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForInNoBraces, " bar", ShouldHaveExecuted); 
+testForInNoBraces({foo: 20});
+checkBasicBlock(testForInNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForInNoBraces, "foo", ShouldHaveExecuted); 
+checkBasicBlock(testForInNoBraces, "; bar", ShouldHaveExecuted); 
+
+function testForOfNoBraces(x) {
+    for (var i of x) foo(); bar();
+}
+testForOfNoBraces([]);
+checkBasicBlock(testForOfNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForOfNoBraces, "foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testForOfNoBraces, "; bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testForOfNoBraces, " bar", ShouldHaveExecuted); 
+testForOfNoBraces([20]);
+checkBasicBlock(testForOfNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testForOfNoBraces, "foo", ShouldHaveExecuted); 
+checkBasicBlock(testForOfNoBraces, "; bar", ShouldHaveExecuted); 
+
+function testWhileNoBraces(x) {
+    var i = 0; while (i++ < x) foo(); bar();
+}
+testWhileNoBraces(0);
+checkBasicBlock(testWhileNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testWhileNoBraces, "foo", ShouldNotHaveExecuted); 
+checkBasicBlock(testWhileNoBraces, "; bar", ShouldNotHaveExecuted); 
+checkBasicBlock(testWhileNoBraces, " bar", ShouldHaveExecuted); 
+testWhileNoBraces(1);
+checkBasicBlock(testWhileNoBraces, " foo", ShouldHaveExecuted); 
+checkBasicBlock(testWhileNoBraces, "foo", ShouldHaveExecuted); 
+checkBasicBlock(testWhileNoBraces, "; bar", ShouldHaveExecuted); 
diff --git a/tests/controlFlowProfiler/conditional-expression.js b/tests/controlFlowProfiler/conditional-expression.js
new file mode 100644 (file)
index 0000000..284b97c
--- /dev/null
@@ -0,0 +1,44 @@
+load("./driver/driver.js");
+
+function foo(){ }
+function bar(){ }
+function baz(){ }
+
+function testConditionalBasic(x) {
+    return x ? 10 : 20;
+}
+
+
+testConditionalBasic(false);
+checkBasicBlock(testConditionalBasic, "x", ShouldHaveExecuted);
+checkBasicBlock(testConditionalBasic, "20", ShouldHaveExecuted);
+checkBasicBlock(testConditionalBasic, "10", ShouldNotHaveExecuted);
+
+testConditionalBasic(true);
+checkBasicBlock(testConditionalBasic, "10", ShouldHaveExecuted);
+
+
+function testConditionalFunctionCall(x, y) {
+    x ? y ? foo() 
+        : baz() 
+        : bar()
+}
+testConditionalFunctionCall(false, false);
+checkBasicBlock(testConditionalFunctionCall, "x", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "? y", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "bar", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, ": bar", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "y", ShouldNotHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "? foo", ShouldNotHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "foo", ShouldNotHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "baz", ShouldNotHaveExecuted);
+
+testConditionalFunctionCall(true, false);
+checkBasicBlock(testConditionalFunctionCall, "y", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "? foo", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, ": baz", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "baz", ShouldHaveExecuted);
+checkBasicBlock(testConditionalFunctionCall, "foo", ShouldNotHaveExecuted);
+
+testConditionalFunctionCall(true, true);
+checkBasicBlock(testConditionalFunctionCall, "foo", ShouldHaveExecuted);
diff --git a/tests/controlFlowProfiler/driver/driver.js b/tests/controlFlowProfiler/driver/driver.js
new file mode 100644 (file)
index 0000000..7a71779
--- /dev/null
@@ -0,0 +1,14 @@
+function assert(condition, reason) {
+    if (!condition)
+        throw new Error(reason);
+}
+
+var ShouldHaveExecuted = true;
+var ShouldNotHaveExecuted = false;
+
+function checkBasicBlock(func, expr, expectation) {
+    if (expectation === ShouldHaveExecuted)
+        assert(hasBasicBlockExecuted(func, expr, "should have executed"));
+    else
+        assert(!hasBasicBlockExecuted(func, expr, "should not have executed"));
+}
diff --git a/tests/controlFlowProfiler/if-statement.js b/tests/controlFlowProfiler/if-statement.js
new file mode 100644 (file)
index 0000000..f31f719
--- /dev/null
@@ -0,0 +1,56 @@
+load("./driver/driver.js");
+
+var a, b, c, d;
+
+function testIf(x) {
+    if (x > 10 && x < 20) {
+        return a;
+    } else if (x > 20 && x < 30) {
+        return b;
+    } else if (x > 30 && x < 40) {
+        return c;
+    } else {
+        return d;
+    }
+
+    return null;
+}
+
+function noMatches(x) {
+    if (x > 10 && x < 20) {
+        return a;
+    } else if (x > 20 && x < 30) {
+        return b;
+    } else {
+        return c;
+    }
+}
+
+assert(!hasBasicBlockExecuted(testIf, "return a"), "should not have executed yet.");
+assert(!hasBasicBlockExecuted(testIf, "return b"), "should not have executed yet.");
+assert(!hasBasicBlockExecuted(testIf, "return c"), "should not have executed yet.");
+assert(!hasBasicBlockExecuted(testIf, "return d"), "should not have executed yet.");
+
+testIf(11);
+assert(hasBasicBlockExecuted(testIf, "return a"), "should have executed.");
+assert(hasBasicBlockExecuted(testIf, "x > 10"), "should have executed.");
+assert(!hasBasicBlockExecuted(testIf, "return b"), "should not have executed yet.");
+
+testIf(21);
+assert(hasBasicBlockExecuted(testIf, "return b"), "should have executed.");
+assert(!hasBasicBlockExecuted(testIf, "return c"), "should not have executed yet.");
+
+testIf(31);
+assert(hasBasicBlockExecuted(testIf, "return c"), "should have executed.");
+assert(!hasBasicBlockExecuted(testIf, "return d"), "should not have executed yet.");
+
+testIf(0);
+assert(hasBasicBlockExecuted(testIf, "return d"), "should have executed.");
+
+
+noMatches(0);
+assert(!hasBasicBlockExecuted(noMatches, "return a"), "should not have executed yet.");
+assert(hasBasicBlockExecuted(noMatches, "x > 10"), "should have executed.");
+assert(!hasBasicBlockExecuted(noMatches, "return b"), "should not have executed yet.");
+assert(hasBasicBlockExecuted(noMatches, "x > 20"), "should have executed.");
+assert(hasBasicBlockExecuted(noMatches, "return c"), "should have executed.");
diff --git a/tests/controlFlowProfiler/loop-statements.js b/tests/controlFlowProfiler/loop-statements.js
new file mode 100644 (file)
index 0000000..a2cdc3d
--- /dev/null
@@ -0,0 +1,76 @@
+load("./driver/driver.js");
+
+function forRegular(limit) {
+    var sum = 0;
+    for (var i = 0; i < limit; i++) {
+        sum += i;
+    }
+
+    return sum;
+}
+
+function forIn(o) {
+    var s = "";
+    var p;
+    for (p in o) {
+        s += p;
+    }
+}
+
+function forOf(a) {
+    var s = "";
+    var p;
+    for (p of a) {
+        s += p;
+    }
+}
+
+function whileLoop(limit) {
+    var i = 0;
+    var sum = 0;
+    while (i < limit) {
+        sum += i;
+        i++;
+    }
+
+    return sum;
+}
+
+assert(!hasBasicBlockExecuted(forRegular, "var sum"), "should not have executed yet.");
+
+forRegular(0);
+assert(hasBasicBlockExecuted(forRegular, "var sum"), "should have executed.");
+assert(!hasBasicBlockExecuted(forRegular, "sum += i"), "should not have executed yet.");
+
+forRegular(1);
+assert(hasBasicBlockExecuted(forRegular, "sum += i"), "should have executed.");
+
+
+assert(!hasBasicBlockExecuted(forIn, "var s"), "should not have executed yet.");
+
+forIn({});
+assert(hasBasicBlockExecuted(forIn, "var s"), "should have executed.");
+assert(!hasBasicBlockExecuted(forIn, "s += p"), "should not have executed yet.");
+
+forIn({foo: "bar"});
+assert(hasBasicBlockExecuted(forIn, "s += p"), "should have executed.");
+
+
+assert(!hasBasicBlockExecuted(forOf, "var s"), "should not have executed yet.");
+
+forOf([]);
+assert(hasBasicBlockExecuted(forOf, "var s"), "should have executed.");
+assert(!hasBasicBlockExecuted(forOf, "s += p"), "should not have executed yet.");
+
+forOf(["a"]);
+assert(hasBasicBlockExecuted(forOf, "s += p"), "should have executed.");
+
+
+assert(!hasBasicBlockExecuted(whileLoop, "var sum"), "should not have executed yet.");
+
+whileLoop(0);
+assert(hasBasicBlockExecuted(whileLoop, "var sum"), "should have executed.");
+assert(!hasBasicBlockExecuted(whileLoop, "sum += i"), "should not have executed yet.");
+
+whileLoop(1);
+assert(hasBasicBlockExecuted(whileLoop, "sum += i"), "should have executed.");
diff --git a/tests/controlFlowProfiler/switch-statements.js b/tests/controlFlowProfiler/switch-statements.js
new file mode 100644 (file)
index 0000000..edcfbbf
--- /dev/null
@@ -0,0 +1,28 @@
+load("./driver/driver.js");
+
+var a, b, c;
+function testSwitch(s) {
+    switch (s) {
+    case "foo":
+        return a;
+    case "bar":
+        return b;
+    default:
+        return c;
+    }
+}
+
+assert(!hasBasicBlockExecuted(testSwitch, "switch"), "should not have executed yet.");
+
+testSwitch("foo");
+assert(hasBasicBlockExecuted(testSwitch, "switch"), "should have executed.");
+assert(hasBasicBlockExecuted(testSwitch, "return a"), "should have executed.");
+assert(!hasBasicBlockExecuted(testSwitch, "return b"), "should not have executed yet.");
+assert(!hasBasicBlockExecuted(testSwitch, "return c"), "should not have executed yet.");
+
+testSwitch("bar");
+assert(hasBasicBlockExecuted(testSwitch, "return b"), "should have executed.");
+assert(!hasBasicBlockExecuted(testSwitch, "return c"), "should not have executed yet.");
+
+testSwitch("");
+assert(hasBasicBlockExecuted(testSwitch, "return c"), "should have executed.");
diff --git a/tests/controlFlowProfiler/test-jit.js b/tests/controlFlowProfiler/test-jit.js
new file mode 100644 (file)
index 0000000..b0f3c19
--- /dev/null
@@ -0,0 +1,46 @@
+load("./driver/driver.js");
+
+function tierUpToBaseline(func, arg) 
+{
+    for (var i = 0; i < 50; i++)
+        func(arg);
+}
+
+function tierUpToDFG(func, arg) 
+{
+    for (var i = 0; i < 50; i++)
+        func(arg);
+}
+
+function baselineTest(arg) {
+    if (arg > 20) {
+        return 20;
+    } else {
+        return 30;
+    }
+}
+
+function dfgTest(arg) {
+    if (arg > 20) {
+        return 20;
+    } else {
+        return 30;
+    }
+}
+
+noInline(baselineTest);
+noInline(dfgTest);
+
+tierUpToBaseline(baselineTest, 10);
+tierUpToDFG(dfgTest, 10);
+
+assert(!hasBasicBlockExecuted(baselineTest, "return 20"), "should not have executed yet.");
+assert(hasBasicBlockExecuted(baselineTest, "return 30"), "should have executed.");
+baselineTest(25);
+assert(hasBasicBlockExecuted(baselineTest, "return 20"), "should have executed.");
+
+assert(!hasBasicBlockExecuted(dfgTest, "return 20"), "should not have executed yet.");
+assert(hasBasicBlockExecuted(dfgTest, "return 30"), "should have executed.");
+dfgTest(25);
+assert(hasBasicBlockExecuted(dfgTest, "return 20"), "should have executed.");
+
index cc60a01b9efb51f5a167beef719171e02463d622..30e4c7c2fe3068df627afaf1c971c8880b879c36 100644 (file)
@@ -23,7 +23,7 @@
 
 - path: exceptionFuzz
   cmd: |
-      if $architecture !~ /x86/i and $hostOS == "darwin"
+      if ($hostOS == "windows")
           skip
       else
           runExceptionFuzz
index 7b96b6ded9397e031594f4e7fdcbbfe1e36f0e5f..76592f27c45e58e19f1d38d2b8e728bdf6d0e651 100644 (file)
@@ -4,6 +4,9 @@ try {
 // http://www.speich.net/computer/moztesting/3d.htm
 // Created by Simon Speich
 
+enableExceptionFuzz();
+
+
 var Q = new Array();
 var MTrans = new Array();  // transformation matrix
 var MQube = new Array();  // position information of qube
index 89e987b0eccb1600fac9395fc1e6caab8e1ac204..40507296aa8f77287cfc19705cda283d8fa0c209 100644 (file)
@@ -13,6 +13,9 @@ try {
  * details.
  */
 
+enableExceptionFuzz();
+
+
 Date.parseFunctions = {count:0};
 Date.parseRegexes = [];
 Date.formatFunctions = {count:0};
index cdf4b65b631cb804173c123618ec9538c00363bb..7579df432065f6e25031852b34ece9810f5352f7 100644 (file)
@@ -39,6 +39,8 @@ function initRuntime() {
 }
 */
 
+enableExceptionFuzz();
+
 
 function sc_print_debug() {
     sc_print.apply(null, arguments);
diff --git a/tests/executableAllocationFuzz.yaml b/tests/executableAllocationFuzz.yaml
new file mode 100644 (file)
index 0000000..66e651c
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2015 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+- path: executableAllocationFuzz
+  cmd: |
+      if ($hostOS == "windows")
+          skip
+      else
+          runExecutableAllocationFuzz("default")
+          runExecutableAllocationFuzz("no-cjit", "--enableConcurrentJIT=false")
+      end
diff --git a/tests/executableAllocationFuzz/v8-raytrace.js b/tests/executableAllocationFuzz/v8-raytrace.js
new file mode 100644 (file)
index 0000000..1805ae5
--- /dev/null
@@ -0,0 +1,902 @@
+// The ray tracer code in this file is written by Adam Burmister. It
+// is available in its original form from:
+//
+//   http://labs.flog.nz.co/raytracer/
+//
+// It has been modified slightly by Google to work as a standalone
+// benchmark, but the all the computational code remains
+// untouched. This file also contains a copy of parts of the Prototype
+// JavaScript framework which is used by the ray tracer.
+
+// Variable used to hold a number that can be used to verify that
+// the scene was ray traced correctly.
+var checkNumber;
+
+
+// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
+
+// The following is a copy of parts of the Prototype JavaScript library:
+
+// Prototype JavaScript framework, version 1.5.0
+// (c) 2005-2007 Sam Stephenson
+//
+// Prototype is freely distributable under the terms of an MIT-style license.
+// For details, see the Prototype web site: http://prototype.conio.net/
+
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+};
+
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+};
+
+
+// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
+
+// The rest of this file is the actual ray tracer written by Adam
+// Burmister. It's a concatenation of the following files:
+//
+//   flog/color.js
+//   flog/light.js
+//   flog/vector.js
+//   flog/ray.js
+//   flog/scene.js
+//   flog/material/basematerial.js
+//   flog/material/solid.js
+//   flog/material/chessboard.js
+//   flog/shape/baseshape.js
+//   flog/shape/sphere.js
+//   flog/shape/plane.js
+//   flog/intersectioninfo.js
+//   flog/camera.js
+//   flog/background.js
+//   flog/engine.js
+
+
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Color = Class.create();
+
+Flog.RayTracer.Color.prototype = {
+    red : 0.0,
+    green : 0.0,
+    blue : 0.0,
+
+    initialize : function(r, g, b) {
+        if(!r) r = 0.0;
+        if(!g) g = 0.0;
+        if(!b) b = 0.0;
+
+        this.red = r;
+        this.green = g;
+        this.blue = b;
+    },
+
+    add : function(c1, c2){
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red + c2.red;
+        result.green = c1.green + c2.green;
+        result.blue = c1.blue + c2.blue;
+
+        return result;
+    },
+
+    addScalar: function(c1, s){
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red + s;
+        result.green = c1.green + s;
+        result.blue = c1.blue + s;
+
+        result.limit();
+
+        return result;
+    },
+
+    subtract: function(c1, c2){
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red - c2.red;
+        result.green = c1.green - c2.green;
+        result.blue = c1.blue - c2.blue;
+
+        return result;
+    },
+
+    multiply : function(c1, c2) {
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red * c2.red;
+        result.green = c1.green * c2.green;
+        result.blue = c1.blue * c2.blue;
+
+        return result;
+    },
+
+    multiplyScalar : function(c1, f) {
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red * f;
+        result.green = c1.green * f;
+        result.blue = c1.blue * f;
+
+        return result;
+    },
+
+    divideFactor : function(c1, f) {
+        var result = new Flog.RayTracer.Color(0,0,0);
+
+        result.red = c1.red / f;
+        result.green = c1.green / f;
+        result.blue = c1.blue / f;
+
+        return result;
+    },
+
+    limit: function(){
+        this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
+        this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
+        this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
+    },
+
+    distance : function(color) {
+        var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
+        return d;
+    },
+
+    blend: function(c1, c2, w){
+        var result = new Flog.RayTracer.Color(0,0,0);
+        result = Flog.RayTracer.Color.prototype.add(
+                    Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
+                    Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
+                  );
+        return result;
+    },
+
+    brightness : function() {
+        var r = Math.floor(this.red*255);
+        var g = Math.floor(this.green*255);
+        var b = Math.floor(this.blue*255);
+        return (r * 77 + g * 150 + b * 29) >> 8;
+    },
+
+    toString : function () {
+        var r = Math.floor(this.red*255);
+        var g = Math.floor(this.green*255);
+        var b = Math.floor(this.blue*255);
+
+        return "rgb("+ r +","+ g +","+ b +")";
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Light = Class.create();
+
+Flog.RayTracer.Light.prototype = {
+    position: null,
+    color: null,
+    intensity: 10.0,
+
+    initialize : function(pos, color, intensity) {
+        this.position = pos;
+        this.color = color;
+        this.intensity = (intensity ? intensity : 10.0);
+    },
+
+    toString : function () {
+        return 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Vector = Class.create();
+
+Flog.RayTracer.Vector.prototype = {
+    x : 0.0,
+    y : 0.0,
+    z : 0.0,
+
+    initialize : function(x, y, z) {
+        this.x = (x ? x : 0);
+        this.y = (y ? y : 0);
+        this.z = (z ? z : 0);
+    },
+
+    copy: function(vector){
+        this.x = vector.x;
+        this.y = vector.y;
+        this.z = vector.z;
+    },
+
+    normalize : function() {
+        var m = this.magnitude();
+        return new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
+    },
+
+    magnitude : function() {
+        return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
+    },
+
+    cross : function(w) {
+        return new Flog.RayTracer.Vector(
+                                            -this.z * w.y + this.y * w.z,
+                                           this.z * w.x - this.x * w.z,
+                                          -this.y * w.x + this.x * w.y);
+    },
+
+    dot : function(w) {
+        return this.x * w.x + this.y * w.y + this.z * w.z;
+    },
+
+    add : function(v, w) {
+        return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
+    },
+
+    subtract : function(v, w) {
+        if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
+        return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
+    },
+
+    multiplyVector : function(v, w) {
+        return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
+    },
+
+    multiplyScalar : function(v, w) {
+        return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
+    },
+
+    toString : function () {
+        return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Ray = Class.create();
+
+Flog.RayTracer.Ray.prototype = {
+    position : null,
+    direction : null,
+    initialize : function(pos, dir) {
+        this.position = pos;
+        this.direction = dir;
+    },
+
+    toString : function () {
+        return 'Ray [' + this.position + ',' + this.direction + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Scene = Class.create();
+
+Flog.RayTracer.Scene.prototype = {
+    camera : null,
+    shapes : [],
+    lights : [],
+    background : null,
+
+    initialize : function() {
+        this.camera = new Flog.RayTracer.Camera(
+            new Flog.RayTracer.Vector(0,0,-5),
+            new Flog.RayTracer.Vector(0,0,1),
+            new Flog.RayTracer.Vector(0,1,0)
+        );
+        this.shapes = new Array();
+        this.lights = new Array();
+        this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
+
+Flog.RayTracer.Material.BaseMaterial = Class.create();
+
+Flog.RayTracer.Material.BaseMaterial.prototype = {
+
+    gloss: 2.0,             // [0...infinity] 0 = matt
+    transparency: 0.0,      // 0=opaque
+    reflection: 0.0,        // [0...infinity] 0 = no reflection
+    refraction: 0.50,
+    hasTexture: false,
+
+    initialize : function() {
+
+    },
+
+    getColor: function(u, v){
+
+    },
+
+    wrapUp: function(t){
+        t = t % 2.0;
+        if(t < -1) t += 2.0;
+        if(t >= 1) t -= 2.0;
+        return t;
+    },
+
+    toString : function () {
+        return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Material.Solid = Class.create();
+
+Flog.RayTracer.Material.Solid.prototype = Object.extend(
+    new Flog.RayTracer.Material.BaseMaterial(), {
+        initialize : function(color, reflection, refraction, transparency, gloss) {
+            this.color = color;
+            this.reflection = reflection;
+            this.transparency = transparency;
+            this.gloss = gloss;
+            this.hasTexture = false;
+        },
+
+        getColor: function(u, v){
+            return this.color;
+        },
+
+        toString : function () {
+            return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+        }
+    }
+);
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Material.Chessboard = Class.create();
+
+Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
+    new Flog.RayTracer.Material.BaseMaterial(), {
+        colorEven: null,
+        colorOdd: null,
+        density: 0.5,
+
+        initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
+            this.colorEven = colorEven;
+            this.colorOdd = colorOdd;
+            this.reflection = reflection;
+            this.transparency = transparency;
+            this.gloss = gloss;
+            this.density = density;
+            this.hasTexture = true;
+        },
+
+        getColor: function(u, v){
+            var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
+
+            if(t < 0.0)
+                return this.colorEven;
+            else
+                return this.colorOdd;
+        },
+
+        toString : function () {
+            return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+        }
+    }
+);
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
+
+Flog.RayTracer.Shape.Sphere = Class.create();
+
+Flog.RayTracer.Shape.Sphere.prototype = {
+    initialize : function(pos, radius, material) {
+        this.radius = radius;
+        this.position = pos;
+        this.material = material;
+    },
+
+    intersect: function(ray){
+        var info = new Flog.RayTracer.IntersectionInfo();
+        info.shape = this;
+
+        var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
+
+        var B = dst.dot(ray.direction);
+        var C = dst.dot(dst) - (this.radius * this.radius);
+        var D = (B * B) - C;
+
+        if(D > 0){ // intersection!
+            info.isHit = true;
+            info.distance = (-B) - Math.sqrt(D);
+            info.position = Flog.RayTracer.Vector.prototype.add(
+                                                ray.position,
+                                                Flog.RayTracer.Vector.prototype.multiplyScalar(
+                                                    ray.direction,
+                                                    info.distance
+                                                )
+                                            );
+            info.normal = Flog.RayTracer.Vector.prototype.subtract(
+                                            info.position,
+                                            this.position
+                                        ).normalize();
+
+            info.color = this.material.getColor(0,0);
+        } else {
+            info.isHit = false;
+        }
+        return info;
+    },
+
+    toString : function () {
+        return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
+
+Flog.RayTracer.Shape.Plane = Class.create();
+
+Flog.RayTracer.Shape.Plane.prototype = {
+    d: 0.0,
+
+    initialize : function(pos, d, material) {
+        this.position = pos;
+        this.d = d;
+        this.material = material;
+    },
+
+    intersect: function(ray){
+        var info = new Flog.RayTracer.IntersectionInfo();
+
+        var Vd = this.position.dot(ray.direction);
+        if(Vd == 0) return info; // no intersection
+
+        var t = -(this.position.dot(ray.position) + this.d) / Vd;
+        if(t <= 0) return info;
+
+        info.shape = this;
+        info.isHit = true;
+        info.position = Flog.RayTracer.Vector.prototype.add(
+                                            ray.position,
+                                            Flog.RayTracer.Vector.prototype.multiplyScalar(
+                                                ray.direction,
+                                                t
+                                            )
+                                        );
+        info.normal = this.position;
+        info.distance = t;
+
+        if(this.material.hasTexture){
+            var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
+            var vV = vU.cross(this.position);
+            var u = info.position.dot(vU);
+            var v = info.position.dot(vV);
+            info.color = this.material.getColor(u,v);
+        } else {
+            info.color = this.material.getColor(0,0);
+        }
+
+        return info;
+    },
+
+    toString : function () {
+        return 'Plane [' + this.position + ', d=' + this.d + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.IntersectionInfo = Class.create();
+
+Flog.RayTracer.IntersectionInfo.prototype = {
+    isHit: false,
+    hitCount: 0,
+    shape: null,
+    position: null,
+    normal: null,
+    color: null,
+    distance: null,
+
+    initialize : function() {
+        this.color = new Flog.RayTracer.Color(0,0,0);
+    },
+
+    toString : function () {
+        return 'Intersection [' + this.position + ']';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Camera = Class.create();
+
+Flog.RayTracer.Camera.prototype = {
+    position: null,
+    lookAt: null,
+    equator: null,
+    up: null,
+    screen: null,
+
+    initialize : function(pos, lookAt, up) {
+        this.position = pos;
+        this.lookAt = lookAt;
+        this.up = up;
+        this.equator = lookAt.normalize().cross(this.up);
+        this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
+    },
+
+    getRay: function(vx, vy){
+        var pos = Flog.RayTracer.Vector.prototype.subtract(
+            this.screen,
+            Flog.RayTracer.Vector.prototype.subtract(
+                Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
+                Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
+            )
+        );
+        pos.y = pos.y * -1;
+        var dir = Flog.RayTracer.Vector.prototype.subtract(
+            pos,
+            this.position
+        );
+
+        var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
+
+        return ray;
+    },
+
+    toString : function () {
+        return 'Ray []';
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Background = Class.create();
+
+Flog.RayTracer.Background.prototype = {
+    color : null,
+    ambience : 0.0,
+
+    initialize : function(color, ambience) {
+        this.color = color;
+        this.ambience = ambience;
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Engine = Class.create();
+
+Flog.RayTracer.Engine.prototype = {
+    canvas: null, /* 2d context we can render to */
+
+    initialize: function(options){
+        this.options = Object.extend({
+                canvasHeight: 100,
+                canvasWidth: 100,
+                pixelWidth: 2,
+                pixelHeight: 2,
+                renderDiffuse: false,
+                renderShadows: false,
+                renderHighlights: false,
+                renderReflections: false,
+                rayDepth: 2
+            }, options || {});
+
+        this.options.canvasHeight /= this.options.pixelHeight;
+        this.options.canvasWidth /= this.options.pixelWidth;
+
+        /* TODO: dynamically include other scripts */
+    },
+
+    setPixel: function(x, y, color){
+        var pxW, pxH;
+        pxW = this.options.pixelWidth;
+        pxH = this.options.pixelHeight;
+
+        if (this.canvas) {
+          this.canvas.fillStyle = color.toString();
+          this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
+        } else {
+          if (x ===  y) {
+            checkNumber += color.brightness();
+          }
+          // print(x * pxW, y * pxH, pxW, pxH);
+        }
+    },
+
+    renderScene: function(scene, canvas){
+        checkNumber = 0;
+        /* Get canvas */
+        if (canvas) {
+          this.canvas = canvas.getContext("2d");
+        } else {
+          this.canvas = null;
+        }
+
+        var canvasHeight = this.options.canvasHeight;
+        var canvasWidth = this.options.canvasWidth;
+
+        for(var y=0; y < canvasHeight; y++){
+            for(var x=0; x < canvasWidth; x++){
+                var yp = y * 1.0 / canvasHeight * 2 - 1;
+                       var xp = x * 1.0 / canvasWidth * 2 - 1;
+
+                       var ray = scene.camera.getRay(xp, yp);
+
+                       var color = this.getPixelColor(ray, scene);
+
+               this.setPixel(x, y, color);
+            }
+        }
+        if (checkNumber !== 2321) {
+          throw new Error("Scene rendered incorrectly");
+        }
+    },
+
+    getPixelColor: function(ray, scene){
+        var info = this.testIntersection(ray, scene, null);
+        if(info.isHit){
+            var color = this.rayTrace(info, ray, scene, 0);
+            return color;
+        }
+        return scene.background.color;
+    },
+
+    testIntersection: function(ray, scene, exclude){
+        var hits = 0;
+        var best = new Flog.RayTracer.IntersectionInfo();
+        best.distance = 2000;
+
+        for(var i=0; i<scene.shapes.length; i++){
+            var shape = scene.shapes[i];
+
+            if(shape != exclude){
+                var info = shape.intersect(ray);
+                if(info.isHit && info.distance >= 0 && info.distance < best.distance){
+                    best = info;
+                    hits++;
+                }
+            }
+        }
+        best.hitCount = hits;
+        return best;
+    },
+
+    getReflectionRay: function(P,N,V){
+        var c1 = -N.dot(V);
+        var R1 = Flog.RayTracer.Vector.prototype.add(
+            Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
+            V
+        );
+        return new Flog.RayTracer.Ray(P, R1);
+    },
+
+    rayTrace: function(info, ray, scene, depth){
+        // Calc ambient
+        var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
+        var oldColor = color;
+        var shininess = Math.pow(10, info.shape.material.gloss + 1);
+
+        for(var i=0; i<scene.lights.length; i++){
+            var light = scene.lights[i];
+
+            // Calc diffuse lighting
+            var v = Flog.RayTracer.Vector.prototype.subtract(
+                                light.position,
+                                info.position
+                            ).normalize();
+
+            if(this.options.renderDiffuse){
+                var L = v.dot(info.normal);
+                if(L > 0.0){
+                    color = Flog.RayTracer.Color.prototype.add(
+                                        color,
+                                        Flog.RayTracer.Color.prototype.multiply(
+                                            info.color,
+                                            Flog.RayTracer.Color.prototype.multiplyScalar(
+                                                light.color,
+                                                L
+                                            )
+                                        )
+                                    );
+                }
+            }
+
+            // The greater the depth the more accurate the colours, but
+            // this is exponentially (!) expensive
+            if(depth <= this.options.rayDepth){
+          // calculate reflection ray
+          if(this.options.renderReflections && info.shape.material.reflection > 0)
+          {
+              var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
+              var refl = this.testIntersection(reflectionRay, scene, info.shape);
+
+              if (refl.isHit && refl.distance > 0){
+                  refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
+              } else {
+                  refl.color = scene.background.color;
+                        }
+
+                  color = Flog.RayTracer.Color.prototype.blend(
+                    color,
+                    refl.color,
+                    info.shape.material.reflection
+                  );
+          }
+
+                // Refraction
+                /* TODO */
+            }
+
+            /* Render shadows and highlights */
+
+            var shadowInfo = new Flog.RayTracer.IntersectionInfo();
+
+            if(this.options.renderShadows){
+                var shadowRay = new Flog.RayTracer.Ray(info.position, v);
+
+                shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
+                if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
+                    var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
+                    var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
+                    color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
+                }
+            }
+
+      // Phong specular highlights
+      if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
+        var Lv = Flog.RayTracer.Vector.prototype.subtract(
+                            info.shape.position,
+                            light.position
+                        ).normalize();
+
+        var E = Flog.RayTracer.Vector.prototype.subtract(
+                            scene.camera.position,
+                            info.shape.position
+                        ).normalize();
+
+        var H = Flog.RayTracer.Vector.prototype.subtract(
+                            E,
+                            Lv
+                        ).normalize();
+
+        var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
+        color = Flog.RayTracer.Color.prototype.add(
+                            Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
+                            color
+                        );
+      }
+        }
+        color.limit();
+        return color;
+    }
+};
+
+
+function renderScene(){
+    var scene = new Flog.RayTracer.Scene();
+
+    scene.camera = new Flog.RayTracer.Camera(
+                        new Flog.RayTracer.Vector(0, 0, -15),
+                        new Flog.RayTracer.Vector(-0.2, 0, 5),
+                        new Flog.RayTracer.Vector(0, 1, 0)
+                    );
+
+    scene.background = new Flog.RayTracer.Background(
+                                new Flog.RayTracer.Color(0.5, 0.5, 0.5),
+                                0.4
+                            );
+
+    var sphere = new Flog.RayTracer.Shape.Sphere(
+        new Flog.RayTracer.Vector(-1.5, 1.5, 2),
+        1.5,
+        new Flog.RayTracer.Material.Solid(
+            new Flog.RayTracer.Color(0,0.5,0.5),
+            0.3,
+            0.0,
+            0.0,
+            2.0
+        )
+    );
+
+    var sphere1 = new Flog.RayTracer.Shape.Sphere(
+        new Flog.RayTracer.Vector(1, 0.25, 1),
+        0.5,
+        new Flog.RayTracer.Material.Solid(
+            new Flog.RayTracer.Color(0.9,0.9,0.9),
+            0.1,
+            0.0,
+            0.0,
+            1.5
+        )
+    );
+
+    var plane = new Flog.RayTracer.Shape.Plane(
+                                new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
+                                1.2,
+                                new Flog.RayTracer.Material.Chessboard(
+                                    new Flog.RayTracer.Color(1,1,1),
+                                    new Flog.RayTracer.Color(0,0,0),
+                                    0.2,
+                                    0.0,
+                                    1.0,
+                                    0.7
+                                )
+                            );
+
+    scene.shapes.push(plane);
+    scene.shapes.push(sphere);
+    scene.shapes.push(sphere1);
+
+    var light = new Flog.RayTracer.Light(
+        new Flog.RayTracer.Vector(5, 10, -1),
+        new Flog.RayTracer.Color(0.8, 0.8, 0.8)
+    );
+
+    var light1 = new Flog.RayTracer.Light(
+        new Flog.RayTracer.Vector(-3, 5, -15),
+        new Flog.RayTracer.Color(0.8, 0.8, 0.8),
+        100
+    );
+
+    scene.lights.push(light);
+    scene.lights.push(light1);
+
+    var imageWidth = 100; // $F('imageWidth');
+    var imageHeight = 100; // $F('imageHeight');
+    var pixelSize = "5,5".split(','); //  $F('pixelSize').split(',');
+    var renderDiffuse = true; // $F('renderDiffuse');
+    var renderShadows = true; // $F('renderShadows');
+    var renderHighlights = true; // $F('renderHighlights');
+    var renderReflections = true; // $F('renderReflections');
+    var rayDepth = 2;//$F('rayDepth');
+
+    var raytracer = new Flog.RayTracer.Engine(
+        {
+            canvasWidth: imageWidth,
+            canvasHeight: imageHeight,
+            pixelWidth: pixelSize[0],
+            pixelHeight: pixelSize[1],
+            "renderDiffuse": renderDiffuse,
+            "renderHighlights": renderHighlights,
+            "renderShadows": renderShadows,
+            "renderReflections": renderReflections,
+            "rayDepth": rayDepth
+        }
+    );
+
+    raytracer.renderScene(scene, null, 0);
+}
+
+for (var i = 0; i < 6; ++i)
+  renderScene();
index 4d936af0d633a2fa05208fddd725cd04b3bf22e2..1265409ef53278dff2b5e931327e701b427116ae 100644 (file)
@@ -45,7 +45,7 @@
 */
 
 function test() {
-    writeHeaderToLog("15.8.1.1 Time Range");
+    writeHeaderToLog("15.9.1.1 Time Range");
 
     for (  M_SECS = 0, CURRENT_YEAR = 1970;
                  M_SECS < 8640000000000000;
index c66ce38a65f13fdc4c8f943efe8bf7bb197f45a1..ac52fa1eb66f2e97a8e32065911473013e998994 100644 (file)
@@ -39,7 +39,7 @@
 
 function test() {
 
-    writeHeaderToLog("15.8.1.1 Time Range");
+    writeHeaderToLog("15.9.1.1 Time Range");
 
     for (       M_SECS = 0, CURRENT_YEAR = 1970;
                 M_SECS > -8640000000000000;
index 354580651a4c5d60ae23e767d463be8a0c1f6eb3..ee0aebb2951bf491f8c1dea6b50a9c35a52aadca 100644 (file)
@@ -36,7 +36,6 @@
     var SECTION =   "15.9.2.1";
     var TITLE =     "Date Constructor used as a function";
     var TYPEOF  =   "string";
-    var TOLERANCE = 1000;
 
     writeHeaderToLog("15.9.2.1 The Date Constructor Called as a Function:  " +
                      "Date( year, month, date, hours, minutes, seconds, ms )" );
@@ -52,44 +51,116 @@ function getTestCases() {
 
     var TODAY = new Date();
 
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
+
     // Dates around 1970
 
-    array[item++] = new TestCase( SECTION, "Date(1970,0,1,0,0,0,0)",            (new Date()).toString(),    Date(1970,0,1,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,15,59,59,999)",     (new Date()).toString(),    Date(1969,11,31,15,59,59,999))
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,16,0,0,0)",         (new Date()).toString(),    Date(1969,11,31,16,0,0,0))
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,16,0,0,1)",         (new Date()).toString(),    Date(1969,11,31,16,0,0,1))
+    d1 = new Date();
+    d2 = Date.parse(Date(1970,0,1,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1970,0,1,0,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,15,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,15,59,59,999)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,16,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,16,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,16,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,16,0,0,1)", true, d2 - d1 <= 1000);
 
     // Dates around 2000
-    array[item++] = new TestCase( SECTION, "Date(1999,11,15,59,59,999)",        (new Date()).toString(),    Date(1999,11,15,59,59,999));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,16,0,0,0,0)",          (new Date()).toString(),    Date(1999,11,16,0,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,31,23,59,59,999)",     (new Date()).toString(),    Date(1999,11,31,23,59,59,999) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,0,0)",            (new Date()).toString(),    Date(2000,0,0,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,0,1)",            (new Date()).toString(),    Date(2000,0,0,0,0,0,1) );
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,15,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(1999,11,15,59,59,999)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,16,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1999,11,16,0,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,31,23,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(1999,11,31,23,59,59,999)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,0,0,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2000,0,1,0,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,0,0,0,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(2000,0,1,0,0,0,1)", true, d2 - d1 <= 1000);
 
     // Dates around 1900
 
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,23,59,59,999)",     (new Date()).toString(),    Date(1899,11,31,23,59,59,999));
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0,0)",            (new Date()).toString(),    Date(1900,0,1,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0,1)",            (new Date()).toString(),    Date(1900,0,1,0,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,16,0,0,0,0)",       (new Date()).toString(),    Date(1899,11,31,16,0,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1899,11,31,23,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(1899,11,31,23,59,59,999)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1900,0,1,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1900,0,1,0,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1900,0,1,0,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(1900,0,1,0,0,0,1)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(1899,11,31,16,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1899,11,31,16,0,0,0,0)", true, d2 - d1 <= 1000);
 
     // Dates around feb 29, 2000
 
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,29,0,0,0,0)",         (new Date()).toString(),    Date(2000,1,29,0,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,28,23,59,59,999)",    (new Date()).toString(),    Date( 2000,1,28,23,59,59,999));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,27,16,0,0,0)",        (new Date()).toString(),    Date(2000,1,27,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,29,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,29,0,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,28,23,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,28,23,59,59,999)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,27,16,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,27,16,0,0,0)", true, d2 - d1 <= 1000);
 
     // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59,999)",     (new Date()).toString(),    Date(2004,11,31,23,59,59,999));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0,0)",            (new Date()).toString(),    Date(2005,0,1,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0,1)",            (new Date()).toString(),    Date(2005,0,1,0,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0,0)",       (new Date()).toString(),    Date(2004,11,31,16,0,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2004,11,31,23,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(2004,11,31,23,59,59,999)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2005,0,1,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2005,0,1,0,0,0,0)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2005,0,1,0,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(2005,0,1,0,0,0,1)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2004,11,31,16,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2004,11,31,16,0,0,0,0)",  true, d2 - d1 <= 1000);
 
     // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59,999)",     (new Date()).toString(),    Date(2031,11,31,23,59,59,999));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0,0)",            (new Date()).toString(),    Date(2032,0,1,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0,1)",            (new Date()).toString(),    Date(2032,0,1,0,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0,0)",       (new Date()).toString(),    Date(2031,11,31,16,0,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2031,11,31,23,59,59,999));
+    array[item++] = new TestCase(SECTION, "Date(2031,11,31,23,59,59,999)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2032,0,1,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2032,0,1,0,0,0,0)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2032,0,1,0,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(2032,0,1,0,0,0,1)",  true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2031,11,31,16,0,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2031,11,31,16,0,0,0,0)",  true, d2 - d1 <= 1000);
 
     return ( array );
 }
index 8ad5694103041ae4d6aef911478a4294064acd5e..18a87fadc93df8b4cb2c526b3313a85fd5587956 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,45 +48,30 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
-    // Dates around 1970
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
 
-    array[item++] = new TestCase( SECTION, "Date(1970,0,1,0,0,0)",          (new Date()).toString(),    Date(1970,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,15,59,59)",     (new Date()).toString(),    Date(1969,11,31,15,59,59))
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,16,0,0)",       (new Date()).toString(),    Date(1969,11,31,16,0,0))
-    array[item++] = new TestCase( SECTION, "Date(1969,11,31,16,0,1)",       (new Date()).toString(),    Date(1969,11,31,16,0,1))
-/*
-    // Dates around 2000
-    array[item++] = new TestCase( SECTION, "Date(1999,11,15,59,59)",        (new Date()).toString(),    Date(1999,11,15,59,59));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,16,0,0,0)",        (new Date()).toString(),    Date(1999,11,16,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,31,23,59,59)",     (new Date()).toString(),    Date(1999,11,31,23,59,59) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,0)",          (new Date()).toString(),    Date(2000,0,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,1)",          (new Date()).toString(),    Date(2000,0,0,0,0,1) );
+    var d1;
+    var d2;
 
-    // Dates around 1900
+    // Dates around 1970
 
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,23,59,59)",     (new Date()).toString(),    Date(1899,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0)",          (new Date()).toString(),    Date(1900,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,1)",          (new Date()).toString(),    Date(1900,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,16,0,0,0)",     (new Date()).toString(),    Date(1899,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1970,0,1,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1970,0,1,0,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around feb 29, 2000
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,15,59,59));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,15,59,59)", true, d2 - d1 <= 1000);
 
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,29,0,0,0)",        (new Date()).toString(),    Date(2000,1,29,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,28,23,59,59)",     (new Date()).toString(),    Date( 2000,1,28,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,27,16,0,0)",       (new Date()).toString(),    Date(2000,1,27,16,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,16,0,0));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,16,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)",     (new Date()).toString(),    Date(2004,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)",          (new Date()).toString(),    Date(2005,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)",          (new Date()).toString(),    Date(2005,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2004,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1969,11,31,16,0,1));
+    array[item++] = new TestCase(SECTION, "Date(1969,11,31,16,0,1)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
-*/
     return ( array );
 }
 function test() {
index 5baaf532752305284fae8aa21d5f974d5bc01062..b411f345284096b2f5e2fbedeac22fea0d29dbca 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,39 +48,33 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
-    // Dates around 2000
-    array[item++] = new TestCase( SECTION, "Date(1999,11,15,59,59)",        (new Date()).toString(),    Date(1999,11,15,59,59));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,16,0,0,0)",        (new Date()).toString(),    Date(1999,11,16,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date(1999,11,31,23,59,59)",     (new Date()).toString(),    Date(1999,11,31,23,59,59) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,0)",          (new Date()).toString(),    Date(2000,0,0,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,1)",          (new Date()).toString(),    Date(2000,0,0,0,0,1) );
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
 
-/*
-    // Dates around 1900
+    // Dates around 2000
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,15,59,59));
+    array[item++] = new TestCase( SECTION, "Date(1999,11,15,59,59)", true, d2 - d1 <= 1000);
 
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,23,59,59)",     (new Date()).toString(),    Date(1899,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0)",          (new Date()).toString(),    Date(1900,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,1)",          (new Date()).toString(),    Date(1900,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,16,0,0,0)",     (new Date()).toString(),    Date(1899,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,16,0,0,0));
+    array[item++] = new TestCase( SECTION, "Date(1999,11,16,0,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around feb 29, 2000
+    d1 = new Date();
+    d2 = Date.parse(Date(1999,11,31,23,59,59));
+    array[item++] = new TestCase( SECTION, "Date(1999,11,31,23,59,59)", true, d2 - d1 <= 1000);
 
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,29,0,0,0)",        (new Date()).toString(),    Date(2000,1,29,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,28,23,59,59)",     (new Date()).toString(),    Date( 2000,1,28,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,27,16,0,0)",       (new Date()).toString(),    Date(2000,1,27,16,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,0,1,0,0,0));
+    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)",     (new Date()).toString(),    Date(2004,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)",          (new Date()).toString(),    Date(2005,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)",          (new Date()).toString(),    Date(2005,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2004,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,0,1,0,0,1));
+    array[item++] = new TestCase( SECTION, "Date(2000,0,1,0,0,1)", true, d2 - d1 <= 1000)
 
-    // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
-*/
     return ( array );
 }
 function test() {
index 59255e2f5780dc97956b7ca2e99d87d7f4fd19d0..de196ed31349bcdefd7f9bd469048ad6e9fc897f 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,32 +48,30 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
+
     // Dates around 1900
 
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,23,59,59)",     (new Date()).toString(),    Date(1899,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0)",          (new Date()).toString(),    Date(1900,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,1)",          (new Date()).toString(),    Date(1900,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(1899,11,31,16,0,0,0)",     (new Date()).toString(),    Date(1899,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1899,11,31,23,59,59));
+    array[item++] = new TestCase( SECTION, "Date(1899,11,31,23,59,59)", true, d2 - d1 <= 1000);
 
-/*
-    // Dates around feb 29, 2000
+    d1 = new Date();
+    d2 = Date.parse(Date(1900,0,1,0,0,0));
+    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,0)", true, d2 - d1 <= 1000);
 
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,29,0,0,0)",        (new Date()).toString(),    Date(2000,1,29,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,28,23,59,59)",     (new Date()).toString(),    Date( 2000,1,28,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,27,16,0,0)",       (new Date()).toString(),    Date(2000,1,27,16,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1900,0,1,0,0,1) );
+    array[item++] = new TestCase( SECTION, "Date(1900,0,1,0,0,1)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)",     (new Date()).toString(),    Date(2004,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)",          (new Date()).toString(),    Date(2005,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)",          (new Date()).toString(),    Date(2005,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2004,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(1899,11,31,16,0,0,0));
+    array[item++] = new TestCase( SECTION, "Date(1899,11,31,16,0,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
-*/
     return ( array );
 }
 function test() {
index b63bb3e960c2d2aefde55ae5c660b86ca732735d..e8dabadfc2f38902855cd069ea99db7d952ba054 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,25 +48,26 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
+
     // Dates around feb 29, 2000
 
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,29,0,0,0)",        (new Date()).toString(),    Date(2000,1,29,0,0,0));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,28,23,59,59)",     (new Date()).toString(),    Date( 2000,1,28,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date( 2000,1,27,16,0,0)",       (new Date()).toString(),    Date(2000,1,27,16,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,29,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,29,0,0,0)", true, d2 - d1 <= 1000);
 
-/*
-    // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)",     (new Date()).toString(),    Date(2004,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)",          (new Date()).toString(),    Date(2005,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)",          (new Date()).toString(),    Date(2005,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2004,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,28,23,59,59));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,28,23,59,59)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2000,1,27,16,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2000,1,27,16,0,0)", true, d2 - d1 <= 1000);
 
-    // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
-*/
     return ( array );
 }
 function test() {
index 54226822fe0df63be753a0908592fd7e05b67e0f..5d39086ee82e844cb69f20182fb9dedc072de214 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,18 +48,30 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
+
     // Dates around jan 1, 2005
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)",     (new Date()).toString(),    Date(2004,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)",          (new Date()).toString(),    Date(2005,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)",          (new Date()).toString(),    Date(2005,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2004,11,31,16,0,0,0));
-/*
-    // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
-*/
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2004,11,31,23,59,59));
+    array[item++] = new TestCase( SECTION, "Date(2004,11,31,23,59,59)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2005,0,1,0,0,0) );
+    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2005,0,1,0,0,1) );
+    array[item++] = new TestCase( SECTION, "Date(2005,0,1,0,0,1)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2004,11,31,16,0,0,0));
+    array[item++] = new TestCase( SECTION, "Date(2004,11,31,16,0,0,0)", true, d2 - d1 <= 1000);
+
     return ( array );
 }
 function test() {
index 8e269d05575e5eaf0e3dcbc2a757081b0a6c5ace..d0aa83f36f4b8a7a3edc029b82edd74d6988355c 100644 (file)
@@ -35,7 +35,6 @@
     var VERSION = 9706;
     startTest();
     var SECTION = "15.9.2.2";
-    var TOLERANCE = 100;
     var TITLE = "The Date Constructor Called as a Function";
 
     writeHeaderToLog(SECTION+" "+TITLE );
@@ -49,11 +48,28 @@ function getTestCases() {
     var array = new Array();
     var item = 0;
 
+    // allow up to 1 second difference due to possibility
+    // the date may change by 1 second in between calls to Date
+
+    var d1;
+    var d2;
+
     // Dates around jan 1, 2032
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,23,59,59)",     (new Date()).toString(),    Date(2031,11,31,23,59,59));
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,0)",          (new Date()).toString(),    Date(2032,0,1,0,0,0) );
-    array[item++] = new TestCase( SECTION, "Date(2032,0,1,0,0,1)",          (new Date()).toString(),    Date(2032,0,1,0,0,1) );
-    array[item++] = new TestCase( SECTION, "Date(2031,11,31,16,0,0,0)",     (new Date()).toString(),    Date(2031,11,31,16,0,0,0));
+    d1 = new Date();
+    d2 = Date.parse(Date(2031,11,31,23,59,59));
+    array[item++] = new TestCase(SECTION, "Date(2031,11,31,23,59,59)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2032,0,1,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2032,0,1,0,0,0)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2032,0,1,0,0,1));
+    array[item++] = new TestCase(SECTION, "Date(2032,0,1,0,0,1)", true, d2 - d1 <= 1000);
+
+    d1 = new Date();
+    d2 = Date.parse(Date(2031,11,31,16,0,0,0));
+    array[item++] = new TestCase(SECTION, "Date(2031,11,31,16,0,0,0)", true, d2 - d1 <= 1000);
 
     return ( array );
 }
index 7004cf4bce5e84277adc74f10ac58ecf842d5bf7..2b0809f590cf76abd94e3cf81a405eb3ba1a78c5 100644 (file)
@@ -30,7 +30,6 @@ function test()
 
     var \u0041 = 5;
     var A\u03B2 = 15;
-    var c\u0061se = 25;
 
     printStatus ("Escapes in identifiers test.");
     printBugNumber (23608);
@@ -44,10 +43,6 @@ function test()
                    "Escaped non-ASCII Identifier test");
     reportCompare (16, eval("++A\u03B2"),
                    "Escaped non-ASCII Identifier test");
-    reportCompare (25, eval("c\\u00" + "61se"),
-                   "Escaped keyword Identifier test");
-    reportCompare (26, eval("++c\\u00" + "61se"),
-                   "Escaped keyword Identifier test");
     
     exitFunc ("test");
 }
index cf83f48c1af31560707ca9d68bfda906afd73d6c..8e152cc97e577a2eb2dd5a5297f02c6eecae939b 100644 (file)
@@ -65,7 +65,7 @@ function simplify(str)
 
     t5 = new TestFunction( "anonymous", "", tab+"return \"hello!\";" );
 
-    var f = new Function( "return \"hello!\"");
+    var f = new Function( "return \"hello!\";");
 
     testcases[tc++] = new TestCase( SECTION,
                                     "stub.toString()",
index ae13cac6921ec7966b538d3ebce0a1519ce0a312..4d164663fef80201cc66938bc39e619494d3c6d8 100644 (file)
 - path: ecma/Date/15.9.1.1-2.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.1.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-1.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-2.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-3.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-4.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-5.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.2.2-6.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.3.1-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.3.1-2.js
 - path: ecma/Date/15.9.5.13-8.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.14.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.15.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.16.js
 - path: ecma/Date/15.9.5.27-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.28-1.js
-  cmd: defaultRunMozillaTest :normal, "../shell.js"
+  cmd: |
+      if ($hostOS == "windows")
+          skip
+      else
+          defaultRunMozillaTest :normal, "../shell.js"
+      end
 - path: ecma/Date/15.9.5.29-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.3-1-n.js
 - path: ecma/Date/15.9.5.30-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.31-1.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: |
+      if ($hostOS == "windows")
+          skip
+      else
+          defaultRunMozillaTest :normal, "../shell.js"
+      end
 - path: ecma/Date/15.9.5.32-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.33-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.34-1.js
-  cmd: defaultRunMozillaTest :skip, "../shell.js"
+  cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.35-1.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: ecma/Date/15.9.5.36-1.js
 - path: ecma_3/Date/15.9.5.5.js
   cmd: defaultRunMozillaTest :normal, "../shell.js", "shell.js"
 - path: ecma_3/Date/15.9.5.6.js
-  cmd: defaultRunMozillaTest :normal, "../shell.js", "shell.js"
+  cmd: |
+      if ($hostOS == "windows")
+          skip
+      else
+          defaultRunMozillaTest :normal, "../shell.js", "shell.js"
+      end
 - path: ecma_3/Date/15.9.5.7.js
   cmd: defaultRunMozillaTest :skip, "../shell.js", "shell.js"
 - path: ecma_3/Exceptions/15.11.1.1.js
 - path: js1_5/Array/regress-154338.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: js1_5/Array/regress-157652.js
-  cmd: defaultRunMozillaTest :normal, "../shell.js"
+  cmd: |
+      if ($architecture == "arm" and $hostOS == "darwin") and $memoryLimited
+          skip
+      else
+          defaultRunMozillaTest :normal, "../shell.js"
+      end
 - path: js1_5/Array/regress-178722.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: js1_5/Array/regress-94257.js
   cmd: defaultRunMozillaTest :normal, "../shell.js"
 - path: js1_5/Regress/regress-159334.js
   cmd: |
-      if ($architecture !~ /x86/i and $hostOS == "darwin") or $memoryLimited
+      if ($architecture !~ /x86/i and $hostOS == "darwin") or ($architecture == "arm64" and $hostOS == "linux") or $memoryLimited
           skip
       else
           defaultRunMozillaTest :normal, "../shell.js"
diff --git a/tests/stress/activation-sink-default-value.js b/tests/stress/activation-sink-default-value.js
new file mode 100644 (file)
index 0000000..0e660d5
--- /dev/null
@@ -0,0 +1,31 @@
+var n = 10000000;
+
+function bar(f) { f(10); }
+
+function foo(b) {
+    var result = 0;
+    var imUndefined;
+    var baz;
+    var set = function (x) { result = x; return (imUndefined, baz); }
+    baz = 40;
+    if (b) {
+        bar(set);
+        if (result != 10)
+            throw "Error: bad: " + result;
+        if (baz !== 40)
+            throw "Error: bad: " + baz;
+        if (imUndefined !== void 0)
+            throw "Error: bad value: " + imUndefined;
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/activation-sink-osrexit-default-value.js b/tests/stress/activation-sink-osrexit-default-value.js
new file mode 100644 (file)
index 0000000..85e9dbc
--- /dev/null
@@ -0,0 +1,37 @@
+var n = 10000000;
+
+function bar(set) { 
+    var result = set(0);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}
+
+function foo(b) {
+    var result = 0;
+    var imUndefined;
+    var baz;
+    var set = function (x) { 
+        result = x; 
+        if (baz !== 50)
+            throw "Error: bad value: " + baz;
+        return imUndefined;
+    }
+    baz = 50;
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+        }
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/activation-sink-osrexit.js b/tests/stress/activation-sink-osrexit.js
new file mode 100644 (file)
index 0000000..9d3c4d3
--- /dev/null
@@ -0,0 +1,25 @@
+var n = 10000000;
+
+function bar() { }
+
+function foo(b) {
+    var result = 0;
+    var set = function (x) { result = x; }
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+        }
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/activation-sink.js b/tests/stress/activation-sink.js
new file mode 100644 (file)
index 0000000..bf00022
--- /dev/null
@@ -0,0 +1,24 @@
+var n = 10000000;
+
+function bar(f) { f(10); }
+
+function foo(b) {
+    var result = 0;
+    var set = function (x) { result = x; }
+    if (b) {
+        bar(set);
+        if (result != 10)
+            throw "Error: bad: " + result;
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/add-overflows-after-not-equal.js b/tests/stress/add-overflows-after-not-equal.js
new file mode 100644 (file)
index 0000000..181566f
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(a) {
+    if (a != 0)
+        return a + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42);
+    if (result != 43)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(2147483647);
+if (result != 2147483648)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-bizarre-behavior.js b/tests/stress/arguments-bizarre-behavior.js
new file mode 100644 (file)
index 0000000..fdc4447
--- /dev/null
@@ -0,0 +1,25 @@
+function foo(x) {
+    Object.defineProperty(arguments, 0, {configurable: true, enumerable: true, writable:true, value:42});
+    return [x, arguments[0], arguments]
+}
+
+var result = foo(1);
+
+if (result[0] !== 42)
+    throw new Error();
+
+if (result[1] !== 42)
+    throw new Error();
+
+if (Array.prototype.join.call(result[2], ",") != "42")
+    throw new Error();
+
+var array = [];
+for (var s in result[2])
+    array.push(s);
+
+if (array.join(",") != "0")
+    throw new Error();
+
+if (Object.keys(result[2]).join(",") != "0")
+    throw new Error();
diff --git a/tests/stress/arguments-bizarre-behaviour-disable-enumerability.js b/tests/stress/arguments-bizarre-behaviour-disable-enumerability.js
new file mode 100644 (file)
index 0000000..947850a
--- /dev/null
@@ -0,0 +1,30 @@
+function foo(x) {
+    Object.defineProperty(arguments, 0, {configurable: true, enumerable: false, writable:true, value:42});
+    return [x, arguments[0], arguments]
+}
+
+var result = foo(1);
+
+if (result[0] !== 42)
+    throw new Error();
+
+if (result[1] !== 42)
+    throw new Error();
+
+if (Array.prototype.join.call(result[2], ",") != "42")
+    throw new Error();
+
+var array = [];
+for (var s in result[2])
+    array.push(s);
+
+if (array.join(",") != "0")
+    throw new Error();
+
+if (Object.keys(result[2]).join(",") != "0")
+    throw new Error();
+
+// FIXME: This is totally weird!
+// https://bugs.webkit.org/show_bug.cgi?id=141952
+if (Object.getOwnPropertyDescriptor(result[2], 0).enumerable !== true)
+    throw new Error();
diff --git a/tests/stress/arguments-callee-uninitialized.js b/tests/stress/arguments-callee-uninitialized.js
new file mode 100644 (file)
index 0000000..6865042
--- /dev/null
@@ -0,0 +1,11 @@
+function foo(e) {
+    if (e) {
+        arguments[0]--;
+        return arguments.callee.apply(this, arguments);
+    }
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; i++)
+    foo(1);
+
diff --git a/tests/stress/arguments-captured.js b/tests/stress/arguments-captured.js
new file mode 100644 (file)
index 0000000..0b1e1ab
--- /dev/null
@@ -0,0 +1,23 @@
+function foo(o) {
+    o[0] = 42;
+}
+
+function bar(a) {
+    var o = {};
+    o.f = a;
+    foo(arguments);
+    o.g = a;
+    return o;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 1000; ++i) {
+    var result = bar(i);
+    if (result.f != i)
+        throw "Error: bad value of f: " + result.f;
+    if (result.g != 42)
+        throw "Error: bad value of g: " + result.g;
+}
+
diff --git a/tests/stress/arguments-custom-properties-gc.js b/tests/stress/arguments-custom-properties-gc.js
new file mode 100644 (file)
index 0000000..86e44d5
--- /dev/null
@@ -0,0 +1,36 @@
+function makeBaseArguments() {
+    return arguments;
+}
+
+noInline(makeBaseArguments);
+
+function makeArray(length) {
+    var array = new Array(length);
+    for (var i = 0; i < length; ++i)
+        array[i] = 99999;
+    return array;
+}
+
+noInline(makeArray);
+
+function cons(f) {
+    var result = makeBaseArguments();
+    result.f = f;
+    return result;
+}
+
+var array = [];
+for (var i = 0; i < 100000; ++i)
+    array.push(cons(i));
+
+for (var i = 0; i < 1000000; ++i) {
+    var j = (i * 3) % array.length;
+    array[j] = cons(j);
+    
+    makeArray(i % 7);
+}
+
+for (var i = 0; i < array.length; ++i) {
+    if (array[i].f != i)
+        throw "Error: bad value of f at " + i + ": " + array[i].f;
+}
diff --git a/tests/stress/arguments-exit-fixed.js b/tests/stress/arguments-exit-fixed.js
new file mode 100644 (file)
index 0000000..4d107a8
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-exit-strict-mode-fixed.js b/tests/stress/arguments-exit-strict-mode-fixed.js
new file mode 100644 (file)
index 0000000..fa816f2
--- /dev/null
@@ -0,0 +1,18 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-exit-strict-mode.js b/tests/stress/arguments-exit-strict-mode.js
new file mode 100644 (file)
index 0000000..04c714e
--- /dev/null
@@ -0,0 +1,18 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-exit.js b/tests/stress/arguments-exit.js
new file mode 100644 (file)
index 0000000..8580820
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-inlined-exit-strict-mode-fixed.js b/tests/stress/arguments-inlined-exit-strict-mode-fixed.js
new file mode 100644 (file)
index 0000000..d08251f
--- /dev/null
@@ -0,0 +1,22 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-inlined-exit-strict-mode.js b/tests/stress/arguments-inlined-exit-strict-mode.js
new file mode 100644 (file)
index 0000000..748251d
--- /dev/null
@@ -0,0 +1,22 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-inlined-exit.js b/tests/stress/arguments-inlined-exit.js
new file mode 100644 (file)
index 0000000..43470d9
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/arguments-interference-cfg.js b/tests/stress/arguments-interference-cfg.js
new file mode 100644 (file)
index 0000000..6904160
--- /dev/null
@@ -0,0 +1,24 @@
+function bar() {
+    return arguments;
+}
+
+function foo(p) {
+    var a = bar(1, 2, 3);
+    var b;
+    if (p)
+        b = bar(4, 5, 6);
+    else
+        b = [7, 8, 9];
+    return (a[0] << 0) + (a[1] << 1) + (a[2] << 2) + (b[0] << 3) + (b[1] << 4) + (b[2] << 5);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 20000; ++i) {
+    var p = i & 1;
+    var q = (!p) * 3;
+    var result = foo(p);
+    if (result != (1 << 0) + (2 << 1) + (3 << 2) + ((4 + q) << 3) + ((5 + q) << 4) + ((6 + q) << 5))
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/arguments-interference.js b/tests/stress/arguments-interference.js
new file mode 100644 (file)
index 0000000..d66f365
--- /dev/null
@@ -0,0 +1,18 @@
+function bar() {
+    return arguments;
+}
+
+function foo() {
+    var a = bar(1, 2, 3);
+    var b = bar(4, 5, 6);
+    return (a[0] << 0) + (a[1] << 1) + (a[2] << 2) + (b[0] << 3) + (b[1] << 4) + (b[2] << 5);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 20000; ++i) {
+    var result = foo();
+    if (result != (1 << 0) + (2 << 1) + (3 << 2) + (4 << 3) + (5 << 4) + (6 << 5))
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/arguments-iterator.js b/tests/stress/arguments-iterator.js
new file mode 100644 (file)
index 0000000..1980532
--- /dev/null
@@ -0,0 +1,70 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testArguments(check) {
+    (function () {
+        check(arguments, []);
+    }());
+
+    (function (a, b, c) {
+        check(arguments, [a, b, c]);
+    }());
+
+    (function () {
+        'use strict';
+        check(arguments, []);
+    }());
+
+    (function (a, b, c) {
+        'use strict';
+        check(arguments, [a, b, c]);
+    }());
+}
+
+testArguments(function (args) {
+    var iteratorMethod = args[Symbol.iterator];
+    test(iteratorMethod, Array.prototype.values);
+    var descriptor = Object.getOwnPropertyDescriptor(args, Symbol.iterator);
+    test(descriptor.writable, true);
+    test(descriptor.configurable, true);
+    test(descriptor.enumerable, false);
+    test(descriptor.value, iteratorMethod);
+});
+
+testArguments(function (args, expected) {
+    var iterator = args[Symbol.iterator]();
+    test(iterator.toString(), '[object Array Iterator]');
+    var index = 0;
+    for (var value of iterator) {
+        test(value, expected[index++]);
+    }
+    test(args.length, index);
+
+    var index = 0;
+    for (var value of args) {
+        test(value, expected[index++]);
+    }
+    test(args.length, index);
+});
+
+testArguments(function (args) {
+    var symbols = Object.getOwnPropertySymbols(args);
+    test(symbols.length, 1);
+    test(symbols[0], Symbol.iterator);
+});
+
+testArguments(function (args) {
+    'use strict';
+    args[Symbol.iterator] = 'not throw error';
+});
+
+testArguments(function (args) {
+    'use strict';
+    delete args[Symbol.iterator];
+    test(args[Symbol.iterator], undefined);
+
+    var symbols = Object.getOwnPropertySymbols(args);
+    test(symbols.length, 0);
+});
diff --git a/tests/stress/arith-add-with-constants.js b/tests/stress/arith-add-with-constants.js
new file mode 100644 (file)
index 0000000..ffb90dc
--- /dev/null
@@ -0,0 +1,271 @@
+// Test value + 0.
+function arithAddIdentityWrittenAsInteger(x) {
+    var a = x + 0;
+    var b = 0 + x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithAddIdentityWrittenAsInteger, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithAddIdentityWrittenAsInteger);
+
+function testArithAddIdentityWrittenAsInteger() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAddIdentityWrittenAsInteger(i);
+        if (result !== i) {
+            throw "arithAddIdentityWrittenAsInteger(i) = " + result + ", expected " + i;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAddIdentityWrittenAsInteger(-0);
+        if (result !== -0) {
+            throw "arithAddIdentityWrittenAsInteger(-0) = " + result + ", expected -0";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var testValue = i + .5;
+        var result = arithAddIdentityWrittenAsInteger(testValue);
+        if (result !== testValue) {
+            throw "arithAddIdentityWrittenAsInteger(i) = " + result + ", expected " + testValue;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsInteger(NaN);
+        if (!isNaN(result)) {
+            throw "arithAddIdentityWrittenAsInteger(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsInteger(Infinity);
+        if (isFinite(result)) {
+            throw "arithAddIdentityWrittenAsInteger(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsInteger(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithAddIdentityWrittenAsInteger(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithAddIdentityWrittenAsInteger();
+
+
+function arithAddIdentityWrittenAsDouble(x) {
+    var a = x + 0.0;
+    var b = 0. + x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithAddIdentityWrittenAsDouble, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithAddIdentityWrittenAsDouble);
+
+function testArithAddIdentityWrittenAsDouble() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAddIdentityWrittenAsDouble(i);
+        if (result !== i) {
+            throw "arithAddIdentityWrittenAsDouble(i) = " + result + ", expected " + i;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAddIdentityWrittenAsDouble(-0);
+        if (result !== -0) {
+            throw "arithAddIdentityWrittenAsDouble(-0) = " + result + ", expected -0 ";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var testValue = i + .5;
+        var result = arithAddIdentityWrittenAsDouble(testValue);
+        if (result !== testValue) {
+            throw "arithAddIdentityWrittenAsDouble(i) = " + result + ", expected " + testValue;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsDouble(NaN);
+        if (!isNaN(result)) {
+            throw "arithAddIdentityWrittenAsDouble(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsDouble(Infinity);
+        if (isFinite(result)) {
+            throw "arithAddIdentityWrittenAsDouble(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAddIdentityWrittenAsDouble(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithAddIdentityWrittenAsDouble(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithAddIdentityWrittenAsDouble();
+
+
+// Test "value + 42".
+function arithAdd42WrittenAsInteger(x) {
+    var a = x + 42;
+    var b = 42 + x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithAdd42WrittenAsInteger, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithAdd42WrittenAsInteger);
+
+function testArithAdd42WrittenAsInteger() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(13);
+        if (result !== 55) {
+            throw "arithAdd42WrittenAsInteger(13) = " + result + ", expected 55";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(-0);
+        if (result !== 42) {
+            throw "arithAdd42WrittenAsInteger(-0) = " + result + ", expected 42";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(13.3);
+        if (result !== 55.3) {
+            throw "arithAdd42WrittenAsInteger(13.3) = " + result + ", expected 55.3";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(NaN);
+        if (!isNaN(result)) {
+            throw "arithAdd42WrittenAsInteger(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(Infinity);
+        if (isFinite(result)) {
+            throw "arithAdd42WrittenAsInteger(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithAdd42WrittenAsInteger(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithAdd42WrittenAsInteger();
+
+
+
+
+// Test "value + 42".
+function arithAdd42WrittenAsInteger(x) {
+    var a = x + 42;
+    var b = 42 + x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithAdd42WrittenAsInteger, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithAdd42WrittenAsInteger);
+
+function testArithAdd42WrittenAsInteger() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(13);
+        if (result !== 55) {
+            throw "arithAdd42WrittenAsInteger(13) = " + result + ", expected 55";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(-0);
+        if (result !== 42) {
+            throw "arithAdd42WrittenAsInteger(-0) = " + result + ", expected 42";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithAdd42WrittenAsInteger(13.3);
+        if (result !== 55.3) {
+            throw "arithAdd42WrittenAsInteger(13.3) = " + result + ", expected 55.3";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(NaN);
+        if (!isNaN(result)) {
+            throw "arithAdd42WrittenAsInteger(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(Infinity);
+        if (isFinite(result)) {
+            throw "arithAdd42WrittenAsInteger(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithAdd42WrittenAsInteger(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithAdd42WrittenAsInteger(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithAdd42WrittenAsInteger();
+
+function arithSub42WrittenAsDouble(x) {
+    var a = (x|0) - 42.0;
+    var b = -42. + (x|0);
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithSub42WrittenAsDouble, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithSub42WrittenAsDouble);
+
+function testArithSub42WrittenAsDouble() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithSub42WrittenAsDouble(13);
+        if (result !== -29) {
+            throw "arithSub42WrittenAsDouble(13) = " + result + ", expected -29";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithSub42WrittenAsDouble(-0);
+        if (result !== -42) {
+            throw "arithSub42WrittenAsDouble(-0) = " + result + ", expected -42";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithSub42WrittenAsDouble(13.3);
+        if (result !== -29) {
+            throw "arithSub42WrittenAsDouble(13.3) = " + result + ", expected -29";
+        }
+    }
+}
+testArithSub42WrittenAsDouble();
+
+
+function doubleConstant(){
+    Math.min(0.0);
+    +0.0;
+} noInline(doubleConstant);
+
+function testDoubleConstant(){
+    for (var i = 0; i < 1e4; ++i) {
+        doubleConstant();
+    }
+}
+testDoubleConstant();
diff --git a/tests/stress/arith-modulo-node-behaviors.js b/tests/stress/arith-modulo-node-behaviors.js
new file mode 100644 (file)
index 0000000..16b9863
--- /dev/null
@@ -0,0 +1,106 @@
+//@ skip if $hostOS == "windows"
+
+// Verify that the dividend propagate the NeedsNegZero if the dividend requires it.
+function moduloWithNegativeZeroDividend(a, b, c)
+{
+    var temp = a * b;
+    return temp % c;
+}
+noInline(moduloWithNegativeZeroDividend);
+
+// Warm up with integers. The test for NegZero should not be eliminated here.
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithNegativeZeroDividend(i, 5, 5);
+    if (result !== 0)
+        throw "moduloWithNegativeZeroDividend(i, 5, 5), returned: " + result;
+}
+
+for (var i = 1; i < 1e4; ++i) {
+    // Produce negative zero in the multiplication.
+    var result = moduloWithNegativeZeroDividend(-i, 0, 2);
+    if (!(result === 0 && (1/result) === -Infinity))
+        throw "moduloWithNegativeZeroDividend(-i, 0, 2) failed, returned: " + result;
+
+    // A negative dividend can produce negative zero results.
+    var result = moduloWithNegativeZeroDividend(-i, 5, 5);
+    if (!(result === 0 && (1/result) === -Infinity))
+        throw "moduloWithNegativeZeroDividend(-i, 5, 5) failed, returned: " + result;
+}
+
+// Edge cases.
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithNegativeZeroDividend(-i, 0, Infinity);
+    if (!(result === 0 && (1/result) === -Infinity))
+        throw "moduloWithNegativeZeroDividend(-i, 0, Infinity) failed, returned: " + result;
+
+    var result = moduloWithNegativeZeroDividend(-i, 0, -Infinity);
+    if (!(result === 0 && (1/result) === -Infinity))
+        throw "moduloWithNegativeZeroDividend(-i, 0, -Infinity) failed, returned: " + result;
+
+    var result = moduloWithNegativeZeroDividend(-i, 0, NaN);
+    if (result === result)
+        throw "moduloWithNegativeZeroDividend(-i, 0, NaN) failed, returned: " + result;
+}
+
+
+// In this case, the negative zero is irrelevant. The Neg Zero check can be eliminated.
+function moduloWithUnusedNegativeZeroDividend(a, b, c)
+{
+    var temp = a * b;
+    return (temp % c) | 0;
+}
+noInline(moduloWithUnusedNegativeZeroDividend);
+
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithUnusedNegativeZeroDividend(i, 5, 5);
+    if (result !== 0)
+        throw "moduloWithUnusedNegativeZeroDividend(i, 5, 5), returned: " + result;
+}
+
+// Produce negative zero in the multiplication.
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithUnusedNegativeZeroDividend(-i, 0, 2);
+    if (!(result === 0 && (1/result) === Infinity))
+        throw "moduloWithUnusedNegativeZeroDividend(-i, 0, 2) failed, returned: " + result;
+}
+
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithUnusedNegativeZeroDividend(-i, 0, Infinity);
+    if (!(result === 0 && (1/result) === Infinity))
+        throw "moduloWithUnusedNegativeZeroDividend(-i, 0, Infinity) failed, returned: " + result;
+
+    var result = moduloWithUnusedNegativeZeroDividend(-i, 0, -Infinity);
+    if (!(result === 0 && (1/result) === Infinity))
+        throw "moduloWithUnusedNegativeZeroDividend(-i, 0, -Infinity) failed, returned: " + result;
+
+    var result = moduloWithUnusedNegativeZeroDividend(-i, 0, NaN);
+    if (result !== 0)
+        throw "moduloWithUnusedNegativeZeroDividend(-i, 0, NaN) failed, returned: " + result;
+}
+
+
+// The sign of the divisor is completely irrelevant. This should never fail on negative zero divisors.
+function moduloWithNegativeZeroDivisor(a, b, c)
+{
+    var temp = a * b;
+    return c % temp;
+}
+noInline(moduloWithNegativeZeroDivisor);
+
+// Warm up with integers.
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithNegativeZeroDivisor(i, 2, i);
+    if (result !== i)
+        throw "moduloWithNegativeZeroDividend(i, 2, i), returned: " + result;
+
+    var result = moduloWithNegativeZeroDivisor(-i, 2, i);
+    if (result !== i)
+        throw "moduloWithNegativeZeroDividend(-i, 2, i), returned: " + result;
+}
+
+// Produce negative zero in the multiplication.
+for (var i = 1; i < 1e4; ++i) {
+    var result = moduloWithNegativeZeroDivisor(-i, 0, 2);
+    if (result === result)
+        throw "moduloWithNegativeZeroDivisor(-i, 0, 2) failed, returned: " + result;
+}
\ No newline at end of file
diff --git a/tests/stress/arith-mul-with-constants.js b/tests/stress/arith-mul-with-constants.js
new file mode 100644 (file)
index 0000000..156ab79
--- /dev/null
@@ -0,0 +1,222 @@
+// Test value * 1.
+function arithMulIdentityWrittenAsInteger(x) {
+    var a = x * 1;
+    var b = 1 * x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithMulIdentityWrittenAsInteger, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithMulIdentityWrittenAsInteger);
+
+function testArithMulIdentityWrittenAsInteger() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMulIdentityWrittenAsInteger(i);
+        if (result !== i) {
+            throw "arithMulIdentityWrittenAsInteger(i) = " + result + ", expected " + i;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMulIdentityWrittenAsInteger(-0);
+        if (result !== -0) {
+            throw "arithMulIdentityWrittenAsInteger(-0) = " + result + ", expected -0";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var testValue = i + .5;
+        var result = arithMulIdentityWrittenAsInteger(testValue);
+        if (result !== testValue) {
+            throw "arithMulIdentityWrittenAsInteger(i) = " + result + ", expected " + testValue;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsInteger(NaN);
+        if (!isNaN(result)) {
+            throw "arithMulIdentityWrittenAsInteger(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsInteger(Infinity);
+        if (isFinite(result)) {
+            throw "arithMulIdentityWrittenAsInteger(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsInteger(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithMulIdentityWrittenAsInteger(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithMulIdentityWrittenAsInteger();
+
+
+function arithMulIdentityWrittenAsDouble(x) {
+    var a = x * 1.0;
+    var b = 1. * x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithMulIdentityWrittenAsDouble, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithMulIdentityWrittenAsDouble);
+
+function testArithMulIdentityWrittenAsDouble() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMulIdentityWrittenAsDouble(i);
+        if (result !== i) {
+            throw "arithMulIdentityWrittenAsDouble(i) = " + result + ", expected " + i;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMulIdentityWrittenAsDouble(-0);
+        if (result !== -0) {
+            throw "arithMulIdentityWrittenAsDouble(-0) = " + result + ", expected -0 ";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var testValue = i + .5;
+        var result = arithMulIdentityWrittenAsDouble(testValue);
+        if (result !== testValue) {
+            throw "arithMulIdentityWrittenAsDouble(i) = " + result + ", expected " + testValue;
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsDouble(NaN);
+        if (!isNaN(result)) {
+            throw "arithMulIdentityWrittenAsDouble(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsDouble(Infinity);
+        if (isFinite(result)) {
+            throw "arithMulIdentityWrittenAsDouble(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMulIdentityWrittenAsDouble(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithMulIdentityWrittenAsDouble(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithMulIdentityWrittenAsDouble();
+
+
+// Test "value * 42".
+function arithMul42WrittenAsInteger(x) {
+    var a = x * 42;
+    var b = 42 * x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithMul42WrittenAsInteger, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithMul42WrittenAsInteger);
+
+function testArithMul42WrittenAsInteger() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsInteger(13);
+        if (result !== 546) {
+            throw "arithMul42WrittenAsInteger(13) = " + result + ", expected 546";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsInteger(-0);
+        if (result !== -0) {
+            throw "arithMul42WrittenAsInteger(-0) = " + result + ", expected -0";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsInteger(13.3);
+        if (result !== 558.6) {
+            throw "arithMul42WrittenAsInteger(13.3) = " + result + ", expected 558.6";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsInteger(NaN);
+        if (!isNaN(result)) {
+            throw "arithMul42WrittenAsInteger(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsInteger(Infinity);
+        if (isFinite(result)) {
+            throw "arithMul42WrittenAsInteger(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsInteger(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithMul42WrittenAsInteger(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithMul42WrittenAsInteger();
+
+
+function arithMul42WrittenAsDouble(x) {
+    var a = x * 42.0;
+    var b = 42. * x;
+    if (!(isNaN(x) && isNaN(a) && isNaN(b)) && a !== b)
+        throw "Internal error on arithMul42WrittenAsDouble, a = " + a + " b = " + b;
+    return a;
+}
+noInline(arithMul42WrittenAsDouble);
+
+function testArithMul42WrittenAsDouble() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsDouble(13);
+        if (result !== 546) {
+            throw "arithMul42WrittenAsDouble(i) = " + result + ", expected 546";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsDouble(-0);
+        if (result !== -0) {
+            throw "arithMul42WrittenAsDouble(-0) = " + result + ", expected -0";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {
+        var result = arithMul42WrittenAsDouble(13.3);
+        if (result !== 558.6) {
+            throw "arithMul42WrittenAsDouble(13.3) = " + result + ", expected 558.6";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsDouble(NaN);
+        if (!isNaN(result)) {
+            throw "arithMul42WrittenAsDouble(NaN) = " + result + ", expected NaN";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsDouble(Infinity);
+        if (isFinite(result)) {
+            throw "arithMul42WrittenAsDouble(Infinity) = " + result + ", expected Infinity";
+        }
+    }
+
+    for (var i = 0; i < 1e4; ++i) {;
+        var result = arithMul42WrittenAsDouble(-Infinity);
+        if (isFinite(result) || result >= 0) {
+            throw "arithMul42WrittenAsDouble(-Infinity) = " + result + ", expected -Infinity";
+        }
+    }
+}
+testArithMul42WrittenAsDouble();
\ No newline at end of file
diff --git a/tests/stress/array-copywithin.js b/tests/stress/array-copywithin.js
new file mode 100644 (file)
index 0000000..41cdf7f
--- /dev/null
@@ -0,0 +1,281 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldBeArray(actual, expected) {
+    shouldBe(actual.length, expected.length);
+    for (var i = 0; i < expected.length; ++i) {
+        try {
+            shouldBe(actual[i], expected[i]);
+        } catch(e) {
+            print(JSON.stringify(actual));
+            throw e;
+        }
+    }
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldBe([].copyWithin.name, 'copyWithin');
+shouldBe([].copyWithin.length, 2);
+shouldBe(Array.prototype.hasOwnProperty('copyWithin'), true);
+shouldBe(JSON.stringify(Object.getOwnPropertyDescriptor(Array.prototype, 'copyWithin')), '{"writable":true,"enumerable":false,"configurable":true}');
+
+// 0 arguments. (it is equivalent to copyWithin(0))
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(), [1, 2, 3, 4, 5]);
+shouldBeArray([].copyWithin(), []);
+
+// 1 arguments.
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-4), [1, 1, 2, 3, 4]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-2), [1, 2, 3, 1, 2]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-1), [1, 2, 3, 4, 1]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1), [1, 1, 2, 3, 4]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(2), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(3), [1, 2, 3, 1, 2]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(4), [1, 2, 3, 4, 1]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(6), [1, 2, 3, 4, 5]);
+
+// 2 arguments.
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 0), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1), [2, 3, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 2), [3, 4, 5, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 4), [5, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 6), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1, 3), [1, 4, 5, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(2, 3), [1, 2, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(3, 3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(4, 3), [1, 2, 3, 4, 4]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(5, 3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(6, 3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-1, -2), [1, 2, 3, 4, 4]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-1, -3), [1, 2, 3, 4, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -3), [3, 4, 5, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -8), [1, 2, 3, 4, 5]);
+
+// 3 arguments.
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 3, 4), [4, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 0, 5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 2), [2, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 3), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 4), [2, 3, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 5), [2, 3, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 1, 6), [2, 3, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(2, 1, 3), [1, 2, 2, 3, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(6, 1, 3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -0, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 0, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -2, -1), [4, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -3, -1), [3, 4, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -4, -1), [2, 3, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -5, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -6, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, 0, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -3, -2), [3, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -4, -2), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -5, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -6, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -0, -1), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, 0, -1), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -1), [1, 2, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -3, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -4, -1), [1, 2, 2, 3, 4]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -5, -1), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -6, -1), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, 0, -2), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -3, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -4, -2), [1, 2, 2, 3, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -5, -2), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -6, -2), [1, 2, 1, 2, 3]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -4), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(0, -1, -6), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -4), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-3, -2, -5), [1, 2, 3, 4, 5]);
+
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -0, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 0, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 0, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 0, 5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 2), [2, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 3), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 4), [2, 3, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 5), [2, 3, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 6), [2, 3, 4, 5, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 3), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 1, 3), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, 3, 4), [4, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -1), [4, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -3, -1), [3, 4, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -4, -1), [2, 3, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -5, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -6, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -3, -2), [3, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -4, -2), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -5, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -6, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -1), [4, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -3, -1), [3, 4, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -4, -1), [2, 3, 4, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -5, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -6, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -3, -2), [3, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -4, -2), [2, 3, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -5, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -6, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -1), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -4), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -5), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -1, -6), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -2), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -3), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -4), [1, 2, 3, 4, 5]);
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-6, -2, -5), [1, 2, 3, 4, 5]);
+
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(NaN, 1), [1, 2, 3, 4, 5].copyWithin(0, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(NaN, NaN, 1), [1, 2, 3, 4, 5].copyWithin(0, 0, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(NaN, NaN, NaN), [1, 2, 3, 4, 5].copyWithin(0, 0, 0));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(Infinity, 0, 1), [1, 2, 3, 4, 5].copyWithin(5, 0, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(Infinity, Infinity, 1), [1, 2, 3, 4, 5].copyWithin(5, 5, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1, Infinity, 1), [1, 2, 3, 4, 5].copyWithin(1, 5, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1, -Infinity, 1), [1, 2, 3, 4, 5].copyWithin(1, 0, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(-Infinity, 0, 1), [1, 2, 3, 4, 5].copyWithin(0, 0, 1));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1, 0, Infinity), [1, 2, 3, 4, 5].copyWithin(1, 0, 5));
+shouldBeArray([1, 2, 3, 4, 5].copyWithin(1, 0, -Infinity), [1, 2, 3, 4, 5].copyWithin(1, 0, 0));
+
+var copyWithin = Array.prototype.copyWithin;
+
+function arrayToObject(array) {
+    var object = {};
+    for (var [key, value] of array.entries()) {
+        object[key] = value;
+    }
+    object.length = array.length;
+    return object;
+}
+var object = arrayToObject([1, 2, 3, 4, 5]);
+object.length = -Infinity;
+shouldBeArray(copyWithin.call(object, 1), { length: -Infinity });
+shouldBe(JSON.stringify(copyWithin.call(object, 1)), '{"0":1,"1":2,"2":3,"3":4,"4":5,"length":null}');
+
+var object = arrayToObject([1, 2, 3, 4, 5]);
+object.length = -Infinity;
+shouldBe(JSON.stringify(copyWithin.call(object, 1)), '{"0":1,"1":2,"2":3,"3":4,"4":5,"length":null}');
+
+var array = [1, 2, 3, 4, 5];
+var same = array.copyWithin(0, 3);
+shouldBeArray(same, [4, 5, 3, 4, 5]);
+shouldBeArray(array, [4, 5, 3, 4, 5]);
+shouldBe(same, array);
+
+shouldBe(JSON.stringify([].copyWithin.call({length: 5, 3: 1}, 0, 3)), '{"0":1,"3":1,"length":5}');
+shouldBe(JSON.stringify([].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4)), '{"0":4,"1":2,"2":3,"3":4,"4":5}');
+
+shouldBe(JSON.stringify([].copyWithin.call({length: 5.5, 3: 1}, 0, 3)), '{"0":1,"3":1,"length":5.5}');
+shouldBe(JSON.stringify([].copyWithin.call({length: 5.5, 3: 1}, 0.1, 3)), '{"0":1,"3":1,"length":5.5}');
+shouldBe(JSON.stringify([].copyWithin.call({length: 5.5, 3: 1}, 0.1, 3.3)), '{"0":1,"3":1,"length":5.5}');
+shouldBe(JSON.stringify([].copyWithin.call({length: 5.5, 3: 1}, 0.1, 3.8)), '{"0":1,"3":1,"length":5.5}');
+shouldBe(JSON.stringify([].copyWithin.call({length: 5.5, 3: 1}, 0.1, 4.1)), '{"3":1,"length":5.5}');
+
+var object = arrayToObject([1, 2, 3, 4, 5]);
+delete object[2];
+delete object[3];
+delete object[4];
+var result = copyWithin.call(object, 0, 3, 5);
+shouldBe(JSON.stringify(result), '{"length":5}');
+
+// 'copyWithin' in Array's @unscopables
+(function () {
+    var array = [];
+    var copyWithin = 42;
+    var forEach = 42;
+    with (array) {
+        shouldBe(copyWithin, 42);
+        shouldBe(forEach, [].forEach);
+    }
+}());
+
+shouldThrow(function () {
+    Array.prototype.copyWithin.call(undefined);
+}, 'TypeError: Array.copyWithin requires that |this| not be null or undefined');
+
+shouldThrow(function () {
+    Array.prototype.copyWithin.call(null);
+}, 'TypeError: Array.copyWithin requires that |this| not be null or undefined');
+
+
+function valueOf(code) {
+    return {
+        valueOf() {
+            throw new Error(code);
+        }
+    };
+}
+
+shouldThrow(function () {
+    var object = arrayToObject([1, 2, 3, 4, 5]);
+    object.length = valueOf(0);
+    copyWithin.call(object, valueOf(1), valueOf(2), valueOf(3));
+}, 'Error: 0');
+
+shouldThrow(function () {
+    var object = arrayToObject([1, 2, 3, 4, 5]);
+    copyWithin.call(object, valueOf(1), valueOf(2), valueOf(3));
+}, 'Error: 1');
+
+shouldThrow(function () {
+    var object = arrayToObject([1, 2, 3, 4, 5]);
+    copyWithin.call(object, 0, valueOf(2), valueOf(3));
+}, 'Error: 2');
+
+shouldThrow(function () {
+    var object = arrayToObject([1, 2, 3, 4, 5]);
+    copyWithin.call(object, 0, 1, valueOf(3));
+}, 'Error: 3');
+
+shouldThrow(function () {
+    var object = arrayToObject([1, 2, 3, 4, 5]);
+    Object.freeze(object);
+    copyWithin.call(object, 0, 1, 2);
+}, 'TypeError: Attempted to assign to readonly property.');
diff --git a/tests/stress/array-fill-put-by-val.js b/tests/stress/array-fill-put-by-val.js
new file mode 100644 (file)
index 0000000..29eefef
--- /dev/null
@@ -0,0 +1,44 @@
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+var array = new Array(10);
+
+for (var i = 0; i < 10; ++i) {
+    (function (index) {
+        var seenOnce = false;
+        var storage = null;
+        Object.defineProperty(Array.prototype, index, {
+            get() {
+                throw new Error('get is called.' + index);
+                return storage;
+            },
+            set(value) {
+                if (seenOnce)
+                    throw new Error('set is called.' + index);
+                seenOnce = true;
+                storage = value;
+                return storage;
+            }
+        });
+    }(i));
+}
+
+// No error, but all seenOnce becomes true.
+array.fill(42);
+
+// Ensures that all setter is called once.
+for (var i = 0; i < 10; ++i) {
+    shouldThrow(function () {
+        array[i] = i;
+    }, "Error: set is called." + i);
+}
diff --git a/tests/stress/array-filter-put-by-val-direct.js b/tests/stress/array-filter-put-by-val-direct.js
new file mode 100644 (file)
index 0000000..0a92d81
--- /dev/null
@@ -0,0 +1,27 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+for (var i = 0; i < 10; ++i) {
+    Object.defineProperty(Array.prototype, i, {
+        get() {
+            throw new Error('get is called.');
+        },
+        set(value) {
+            throw new Error('set is called.');
+        }
+    });
+}
+
+var original = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+// Doesn't throw any errors.
+var filtered = original.filter(function (value, index) {
+    return index % 2 == 0;
+});
+
+shouldBe(filtered.length, 5);
+for (var i = 0; i < 5; ++i) {
+    shouldBe(filtered[i], i * 2);
+}
diff --git a/tests/stress/array-find-does-not-lookup-twice.js b/tests/stress/array-find-does-not-lookup-twice.js
new file mode 100644 (file)
index 0000000..87f767f
--- /dev/null
@@ -0,0 +1,47 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+var array = new Array(10);
+
+for (var i = 0; i < 10; ++i) {
+    (function (index) {
+        var seenOnce = false;
+        Object.defineProperty(array, index, {
+            get() {
+                if (seenOnce)
+                    throw new Error('get is called.' + index);
+                seenOnce = true;
+                return index;
+            }
+        });
+    }(i));
+}
+
+shouldBe(array.length, 10);
+
+// Doesn't throw any errors.
+var findValue = array.find(function (value) {
+    return value === 9;
+});
+shouldBe(findValue, 9);
+
+for (var i = 0; i < 10; ++i) {
+    shouldThrow(function () {
+        var value = array[i];
+    }, "Error: get is called." + i);
+}
diff --git a/tests/stress/array-from-abs-and-floor.js b/tests/stress/array-from-abs-and-floor.js
new file mode 100644 (file)
index 0000000..8bbb48a
--- /dev/null
@@ -0,0 +1,42 @@
+function target1() {
+    return Array.from({
+        length: 5,
+        0: 0,
+        1: 0,
+        2: 0,
+        3: 0,
+        4: 0
+    });
+}
+noInline(target1);
+
+function target2() {
+    return Array.from({
+        length: 5.4,
+        0: 0,
+        1: 0,
+        2: 0,
+        3: 0,
+        4: 0
+    });
+}
+noInline(target2);
+
+function target3() {
+    return Array.from({
+        length: -5.4,
+        0: 0,
+        1: 0,
+        2: 0,
+        3: 0,
+        4: 0
+    });
+}
+noInline(target3);
+
+for (var i = 0; i < 10000; ++i)
+    target1();
+for (var i = 0; i < 10000; ++i)
+    target2();
+for (var i = 0; i < 10000; ++i)
+    target3();
diff --git a/tests/stress/array-from-put-by-val-direct.js b/tests/stress/array-from-put-by-val-direct.js
new file mode 100644 (file)
index 0000000..fc8792f
--- /dev/null
@@ -0,0 +1,25 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+for (var i = 0; i < 10; ++i) {
+    Object.defineProperty(Array.prototype, i, {
+        get() {
+            throw new Error('get is called.');
+        },
+        set(value) {
+            throw new Error('set is called.');
+        }
+    });
+}
+
+var original = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+// Doesn't throw any errors.
+var generated = Array.from(original);
+
+shouldBe(generated.length, 10);
+for (var i = 0; i < 10; ++i) {
+    shouldBe(generated[i], i);
+}
diff --git a/tests/stress/array-from-set-length.js b/tests/stress/array-from-set-length.js
new file mode 100644 (file)
index 0000000..ab6adea
--- /dev/null
@@ -0,0 +1,45 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+for (var i = 0; i < 10; ++i) {
+    Object.defineProperty(Array.prototype, i, {
+        get() {
+            throw new Error('get is called.');
+        },
+        set(value) {
+            throw new Error('set is called.');
+        }
+    });
+}
+
+class ArrayLike {
+    constructor(length) {
+        this.lengthCalled = false;
+        this._length = length;
+    }
+    set length(value) {
+        this.lengthCalled = true;
+        this._length = value;
+    }
+    get length() {
+        return this._length;
+    }
+}
+
+var arrayLike = new ArrayLike(10);
+for (var i = 0; i < 10; ++i) {
+    arrayLike[i] = i;
+}
+shouldBe(arrayLike.lengthCalled, false);
+
+var generated = Array.from.call(ArrayLike, arrayLike);
+
+shouldBe(generated.length, 10);
+shouldBe(generated instanceof ArrayLike, true);
+for (var i = 0; i < 10; ++i) {
+    shouldBe(generated[i], i);
+}
+shouldBe(arrayLike.lengthCalled, false);
+shouldBe(generated.lengthCalled, true);
diff --git a/tests/stress/array-from-with-accessors.js b/tests/stress/array-from-with-accessors.js
new file mode 100644 (file)
index 0000000..cfe65ca
--- /dev/null
@@ -0,0 +1,22 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var array = [0, 1, 2, 3, 4, 5];
+Object.defineProperty(Array.prototype, '0', {
+    get() {
+        throw new Error('cannot get to 0 getter');
+    },
+    set() {
+        throw new Error('cannot put to 0 setter');
+    }
+});
+
+var result = Array.from(array);
+shouldBe(result.length, array.length);
+shouldBe(result instanceof Array, true);
+
+for (var i = 0; i < array.length; ++i)
+    shouldBe(result[i], array[i]);
+
diff --git a/tests/stress/array-from-with-iterable.js b/tests/stress/array-from-with-iterable.js
new file mode 100644 (file)
index 0000000..67e0a28
--- /dev/null
@@ -0,0 +1,69 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+// Set is iterable.
+var set = new Set([0, 1, 2, 3, 4, 5]);
+var array = Array.from(set);
+
+shouldBe(array.length, set.size);
+for (var i = 0; i < array.length; ++i) {
+    shouldBe(set.has(array[i]), true);
+}
+
+// Map is iterable.
+var map = new Map([
+    [0, 0],
+    [1, 0],
+    [2, 0],
+    [3, 0],
+    [4, 0],
+    [5, 0]
+]);
+var array = Array.from(map);
+
+shouldBe(array.length, map.size);
+for (var i = 0; i < array.length; ++i) {
+    shouldBe(array[i][1], 0);
+    shouldBe(map.has(array[i][0]), true);
+    shouldBe(map.get(array[i][0]), 0);
+}
+
+// String is iterable
+var string = "Cocoa Cappuccino";
+var array = Array.from(string);
+shouldBe(array.length, string.length);
+for (var i = 0; i < array.length; ++i) {
+    shouldBe(array[i], string[i]);
+}
+
+// Arguments is iterable
+var argumentsGenerators = [
+    function () {
+        return arguments;
+    },
+
+    function () {
+        'use strict';
+        return arguments;
+    },
+
+    function (a, b, c) {
+        return arguments;
+    },
+
+    function (a, b, c) {
+        'use strict';
+        return arguments;
+    }
+];
+
+for (var gen of argumentsGenerators) {
+    var args = gen(1, 2, 3, 4, 5);
+    var array = Array.from(args);
+    shouldBe(array.length, args.length);
+    for (var i = 0; i < array.length; ++i) {
+        shouldBe(array[i], args[i]);
+    }
+}
diff --git a/tests/stress/array-from-with-iterator.js b/tests/stress/array-from-with-iterator.js
new file mode 100644 (file)
index 0000000..6d645e4
--- /dev/null
@@ -0,0 +1,129 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+var originalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+var array = Array.from(originalArray.values());
+shouldBe(array.length, originalArray.length);
+for (var i = 0; i < array.length; ++i) {
+    shouldBe(array[i], originalArray[i]);
+}
+
+function createIterator(callback) {
+    var array = [0,1,2,3,4,5];
+    var iterator = array[Symbol.iterator]();
+    iterator.return = function () {
+        iterator.returned = true;
+        if (callback)
+            return callback(this);
+        return { done: true, value: undefined };
+    };
+    iterator.returned = false;
+    return iterator;
+}
+
+var iterator = createIterator();
+var result = Array.from(iterator);
+shouldBe(result.length, 6);
+for (var i = 0; i < 6; ++i) {
+    shouldBe(result[i], i);
+}
+shouldBe(iterator.returned, false);
+
+// mapFn raises an error.
+var iterator = createIterator();
+shouldThrow(function () {
+    var result = Array.from(iterator, function () {
+        throw new Error('map func');
+    });
+}, "Error: map func");
+shouldBe(iterator.returned, true);
+
+// mapFn raises an error and iterator.return also raises an error.
+var iterator = createIterator(function () {
+    throw new Error('iterator.return');
+});
+
+// An error raised in iterator.return is discarded.
+shouldThrow(function () {
+    var result = Array.from(iterator, function () {
+        throw new Error('map func');
+    });
+}, "Error: map func");
+shouldBe(iterator.returned, true);
+
+// iterable[Symbol.iterator] is not a function.
+shouldThrow(function () {
+    var iterator = [].values();
+    iterator[Symbol.iterator] = {};
+    Array.from(iterator);
+}, "TypeError: Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+
+// iterable[Symbol.iterator] raises an error.
+shouldThrow(function () {
+    var iterable = [];
+    iterable[Symbol.iterator] = function () {
+        throw new Error("iterator");
+    };
+    Array.from(iterable);
+}, "Error: iterator");
+
+// iterable[Symbol.iterator] lookup is only once.
+(function () {
+    var iterable = [0, 1, 2, 3, 4, 5];
+    var count = 0;
+    var iteratorCallCount = 0;
+    Object.defineProperty(iterable, Symbol.iterator, {
+        get() {
+            ++count;
+            return function () {
+                ++iteratorCallCount;
+                return this.values();
+            };
+        }
+    });
+    var generated = Array.from(iterable);
+    shouldBe(generated.length, iterable.length);
+    for (var i = 0; i < iterable.length; ++i) {
+        shouldBe(generated[i], iterable[i]);
+    }
+    shouldBe(count, 1);
+    shouldBe(iteratorCallCount, 1);
+}());
+
+// The Symbol.iterator method of the iterator generated by iterable[Symbol.iterator] is not looked up.
+(function () {
+    var iterable = [0, 1, 2, 3, 4, 5];
+    var count = 0;
+    iterable[Symbol.iterator] = function () {
+        ++count;
+        var iterator = this.values();
+        Object.defineProperty(iterator, Symbol.iterator, {
+            get() {
+                throw new Error('iterator[@@iterator] is touched');
+            }
+        });
+        return iterator;
+    };
+    var generated = Array.from(iterable);
+    shouldBe(generated.length, iterable.length);
+    for (var i = 0; i < iterable.length; ++i) {
+        shouldBe(generated[i], iterable[i]);
+    }
+    shouldBe(count, 1);
+}());
diff --git a/tests/stress/array-iterators-next-with-call.js b/tests/stress/array-iterators-next-with-call.js
new file mode 100644 (file)
index 0000000..ef25de6
--- /dev/null
@@ -0,0 +1,115 @@
+// This test checks the behavior of the %ArrayIteratorPrototype%.next methods with call.
+
+var array = [0, 1, 2, 3, 4];
+var arrayIterator = array[Symbol.iterator]();
+var arrayIteratorPrototype = arrayIterator.__proto__;
+var arrayIteratorPrototypeNext = arrayIteratorPrototype.next;
+
+if (arrayIterator.hasOwnProperty('next'))
+    throw "next method should exists on %ArrayIteratorPrototype%";
+if (!arrayIteratorPrototype.hasOwnProperty('next'))
+    throw "next method should exists on %ArrayIteratorPrototype%";
+
+var array1 = [42, 43, 41];
+var array1Iterator = array1[Symbol.iterator]();
+var index = 0;
+while (true) {
+    var result = arrayIteratorPrototypeNext.call(array1Iterator);
+    var value = result.value;
+    if (result.done) {
+        break;
+    }
+    if (value !== array1[index++])
+        throw "Error: bad value: " + value;
+}
+if (index !== 3)
+    throw "Error: bad index: " + index;
+
+function increment(iter) {
+    return arrayIteratorPrototypeNext.call(iter);
+}
+var array1 = [42, 43, -20];
+var array2 = [42, 43, -20];
+var array1Iterator = array1[Symbol.iterator]();
+var array2Iterator = array2[Symbol.iterator]();
+for (var i = 0; i < 3; ++i) {
+    var value1 = increment(array1Iterator).value;
+    var value2 = increment(array2Iterator).value;
+    if (value1 !== value2)
+        throw "Error: bad value: " + value1 + " " + value2;
+}
+
+var array1 = [ 0, 1, 2, 4, 5, 6 ];
+var array1Iterator = array1[Symbol.iterator]();
+
+var value = array1Iterator.next().value;
+if (value !== 0)
+    throw "Error: bad value: " + value;
+var value = array1Iterator.next().value;
+if (value !== 1)
+    throw "Error: bad value: " + value;
+var value = array1Iterator.next().value;
+if (value !== 2)
+    throw "Error: bad value: " + value;
+var value = arrayIteratorPrototypeNext.call(array1Iterator).value;
+if (value !== 4)
+    throw "Error: bad value: " + value;
+var value = arrayIteratorPrototypeNext.call(array1Iterator).value;
+if (value !== 5)
+    throw "Error: bad value: " + value;
+var value = arrayIteratorPrototypeNext.call(array1Iterator).value;
+if (value !== 6)
+    throw "Error: bad value: " + value;
+var value = arrayIteratorPrototypeNext.call(array1Iterator).value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var primitives = [
+    "string",
+    42,
+    0.03,
+    false,
+    true,
+    Symbol("Cocoa"),
+    null,
+    undefined
+];
+for (var primitive of primitives) {
+    var didThrow = null;
+    try {
+        arrayIteratorPrototypeNext.call(primitive);
+    } catch (e) {
+        didThrow = e;
+    }
+    if (!didThrow)
+        throw "Error: no error thrown";
+    var expectedMessage = 'TypeError: %ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance';
+    if (primitive == null)
+        expectedMessage = 'TypeError: %ArrayIteratorPrototype%.next requires that |this| not be null or undefined';
+    if (String(didThrow) !== expectedMessage)
+        throw "Error: bad error thrown: " + didThrow;
+}
+
+var nonRelatedObjects = [
+    {},
+    [],
+    new Date(),
+    new Error(),
+    Object(Symbol()),
+    new String("Cappuccino"),
+    new Number(42),
+    new Boolean(false),
+    function () { },
+];
+for (var object of nonRelatedObjects) {
+    var didThrow = null;
+    try {
+        arrayIteratorPrototypeNext.call(object);
+    } catch (e) {
+        didThrow = e;
+    }
+    if (!didThrow)
+        throw "Error: no error thrown";
+    if (String(didThrow) !== 'TypeError: %ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance')
+        throw "Error: bad error thrown: " + didThrow;
+}
diff --git a/tests/stress/array-iterators-next.js b/tests/stress/array-iterators-next.js
new file mode 100644 (file)
index 0000000..200e803
--- /dev/null
@@ -0,0 +1,108 @@
+// This test checks the behavior of the iterator.next methods on Array objects
+
+var testArray = [1,2,3,4,5,6]
+var keys = testArray.keys();
+var i = 0;
+while (true) {
+    var {done, value: key} = keys.next();
+    if (done)
+        break;
+    if (key !== i)
+        throw "Error: bad value: " + key;
+    i++;
+}
+
+if (testArray.length !== i)
+    throw "Error: bad value: " + i;
+
+var value = keys.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var values = testArray[Symbol.iterator]();
+var i = 0;
+while (true) {
+    var {done, value} = values.next();
+    if (done)
+        break;
+    i++;
+    if (value !== i)
+        throw "Error: bad value: " + value;
+}
+
+if (testArray.length !== i)
+    throw "Error: bad value: " + i;
+
+var value = values.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var values = testArray.values();
+var i = 0;
+while (true) {
+    var {done, value} = values.next();
+    if (done)
+        break;
+    i++;
+    if (value !== i)
+        throw "Error: bad value: " + value;
+}
+
+if (testArray.length !== i)
+    throw "Error: bad value: " + i;
+
+var value = values.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testArray.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (value !== testArray[key])
+        throw "Error: bad value: " + value + " " + testArray[key];
+    if (key !== i)
+        throw "Error: bad value: " + key;
+    i++
+    if (value !== i)
+        throw "Error: bad value: " + value + " " + i;
+} while (!done);
+
+if (testArray.length !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testArray.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (value !== testArray[key])
+        throw "Error: bad value: " + value + " " + testArray[key];
+    if (key !== i)
+        throw "Error: bad value: " + key;
+    i++
+    if (i % 2 == 0)
+        testArray[i] *= 2;
+    if (i < 4)
+        testArray.push(testArray.length)
+    if (i == 4)
+        delete testArray[4]
+    if (i == 5)
+        testArray[4] = 5
+} while (!done);
+
+if (testArray.length !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
diff --git a/tests/stress/array-length-array-storage-plain-object.js b/tests/stress/array-length-array-storage-plain-object.js
new file mode 100644 (file)
index 0000000..e424933
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(o) {
+    return o.length;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var a = [1];
+    a.length = 99999999;
+    a.f = 42;
+    foo(a);
+}
+
+var result = foo({});
+if (result !== void 0)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/array-length-plain-object.js b/tests/stress/array-length-plain-object.js
new file mode 100644 (file)
index 0000000..ed85751
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(o) {
+    return o.length;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var a = [1];
+    a.f = 42;
+    foo(a);
+}
+
+var result = foo({});
+if (result !== void 0)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/array-map-put-by-val-direct.js b/tests/stress/array-map-put-by-val-direct.js
new file mode 100644 (file)
index 0000000..88e5cde
--- /dev/null
@@ -0,0 +1,27 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+for (var i = 0; i < 10; ++i) {
+    Object.defineProperty(Array.prototype, i, {
+        get() {
+            throw new Error('get is called.');
+        },
+        set(value) {
+            throw new Error('set is called.');
+        }
+    });
+}
+
+var original = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+// Doesn't throw any errors.
+var mapped = original.map(function (value) {
+    return value * 2;
+});
+
+shouldBe(mapped.length, 10);
+for (var i = 0; i < 10; ++i) {
+    shouldBe(mapped[i], i * 2);
+}
diff --git a/tests/stress/arrayify-to-structure-contradiction.js b/tests/stress/arrayify-to-structure-contradiction.js
new file mode 100644 (file)
index 0000000..22c8019
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(array, v, p) {
+    array[0] = 10;
+    if (p)
+        v = "hello";
+    array[0] = v;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var array = [42];
+    foo(array, 43, false);
+    if (array[0] != 43)
+        throw "Error: bad result: " + array;
+}
+
diff --git a/tests/stress/assignment-in-function-call-bracket-node.js b/tests/stress/assignment-in-function-call-bracket-node.js
new file mode 100644 (file)
index 0000000..54f70fe
--- /dev/null
@@ -0,0 +1,126 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+// Simple assignment (not FunctionCallBracketNode).
+
+shouldBe(function () {
+    var object = {
+        null: 'ok'
+    };
+
+    return object[object = null];
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = 'ok';
+
+    return object[object = value];
+}(null), 'ok');
+
+shouldBe(function () {
+    var object = {
+        null: 'ok'
+    };
+
+    return object['null'];
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = 'ok';
+
+    return object['null'];
+}(null), 'ok');
+
+shouldBe(function () {
+    var object = {
+        null: 'ok'
+    };
+
+    function fill() {
+        return object = null;
+    }
+
+    return object[fill()];
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = 'ok';
+
+    function fill() {
+        return object = value;
+    }
+
+    return object[fill()];
+}(null), 'ok');
+
+// FunctionCallBracketNode.
+
+shouldBe(function () {
+    var object = {
+        null: function () {
+            return 'ok';
+        }
+    };
+
+    return object[object = null]();
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = function () {
+        return 'ok';
+    };
+
+    return object[object = value]();
+}(null), 'ok');
+
+shouldBe(function () {
+    var object = {
+        null: function () {
+            return 'ok';
+        }
+    };
+
+    return object['null']();
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = function () {
+        return 'ok';
+    };
+
+    return object['null']();
+}(null), 'ok');
+
+shouldBe(function () {
+    var object = {
+        null: function () {
+            return 'ok';
+        }
+    };
+
+    function fill() {
+        return object = null;
+    }
+
+    return object[fill()]();
+}(), 'ok');
+
+shouldBe(function (value) {
+    var object = { };
+    object.null = function () {
+        return 'ok';
+    };
+
+    function fill() {
+        return object = value;
+    }
+
+    return object[fill()]();
+}(null), 'ok');
diff --git a/tests/stress/branch-may-exit-due-to-object-or-other-use-kind.js b/tests/stress/branch-may-exit-due-to-object-or-other-use-kind.js
new file mode 100644 (file)
index 0000000..aee19ed
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+// Regression test for https://bugs.webkit.org/show_bug.cgi?id=144152
+
+// The bug in 144152 needs 3 conditions to manifest:
+// 1. The branch test value in the inlined function is of useKind ObjectOrOtherUse.
+// 2. The branch test value is proven to be a known useKind.
+// 3. The masqueradesAsUndefined watchpoint is no longer valid.
+// With the bug fixed, this test should not crash on debug builds.
+
+function inlinedFunction(x) {
+    if (x) // Conditional branch that will assert on a debug build if the bug is present.
+        new Object;
+}
+
+function foo(x) {
+    if (x) // Testing x before calling the inlined function sets up condition 2.
+        inlinedFunction(x);
+}
+
+makeMasquerader(); // Invalidates the masqueradesAsUndefined watchpoint for condition 3.
+for (var i = 0; i < 10000; i++)
+    foo({}); // Pass an object argument to set up condition 1.
diff --git a/tests/stress/builtin-function-is-construct-type-none.js b/tests/stress/builtin-function-is-construct-type-none.js
new file mode 100644 (file)
index 0000000..626248d
--- /dev/null
@@ -0,0 +1,18 @@
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+for (var i = 0; i < 10000; ++i) {
+    shouldThrow(function () {
+        new Array.prototype.forEach(function () { });
+    }, "TypeError: function is not a constructor (evaluating 'new Array.prototype.forEach(function () { })')");
+}
diff --git a/tests/stress/cached-prototype-setter.js b/tests/stress/cached-prototype-setter.js
new file mode 100644 (file)
index 0000000..ed27108
--- /dev/null
@@ -0,0 +1,45 @@
+// [ARM] stress/cached-prototype-setter.js.no-llint fails intermittently on Aarch64 Linux
+// https://bugs.webkit.org/show_bug.cgi?id=142277
+//@ skip if $architecture == "arm64" and $hostOS == "linux"
+
+(function() {
+    var xSetterCalled = false;
+
+    function MyConstructor()
+    {
+        this.x = 1;
+    }
+    
+    new MyConstructor;
+    new MyConstructor;
+    function setter() {
+        xSetterCalled = true;
+    }
+    Object.prototype.__defineSetter__("x", setter);
+    new MyConstructor;
+
+    if (!xSetterCalled)
+        throw new Error("FAIL: 'x' setter was not called.");
+})();
+
+(function() {
+    var xSetterCalled = false;
+
+    function makeO()
+    {
+        var o = { };
+        o.x = 1;
+        return o;
+    }
+
+    makeO();
+    makeO();
+    function setter(x) {
+        xSetterCalled = true;
+    }
+    Object.prototype.__defineSetter__("x", setter);
+    makeO();
+
+    if (!xSetterCalled)
+        throw new Error("FAIL: 'x' setter was not called.");
+})();
diff --git a/tests/stress/call-forward-varargs-for-inlined-escaped-arguments.js b/tests/stress/call-forward-varargs-for-inlined-escaped-arguments.js
new file mode 100644 (file)
index 0000000..4758506
--- /dev/null
@@ -0,0 +1,23 @@
+function foo() {
+    return arguments;
+}
+
+function baz(a, b, c) {
+    return a + b + c;
+}
+
+noInline(baz);
+
+function bar(a, b, c) {
+    var args = foo(b, c, 42);
+    return baz.apply(void 0, args);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2, 3);
+    if (result != 47)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/call-varargs-length-effects.js b/tests/stress/call-varargs-length-effects.js
new file mode 100644 (file)
index 0000000..03bcfd7
--- /dev/null
@@ -0,0 +1,24 @@
+function foo() { return arguments.length; }
+
+var o = {};
+o[0] = 42;
+var callCount = 0;
+o.__defineGetter__("length", function() {
+    callCount++;
+    return 1;
+});
+
+function bar() {
+    callCount = 0;
+    var result = foo.apply(this, o);
+    if (result != 1)
+        throw "Error: bad result: " + result;
+    if (callCount != 1)
+        throw "Error: bad call count: " + callCount;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i)
+    bar();
diff --git a/tests/stress/call-varargs-with-different-arguments-length-after-warmup.js b/tests/stress/call-varargs-with-different-arguments-length-after-warmup.js
new file mode 100644 (file)
index 0000000..a96e254
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+// Regression test for https://bugs.webkit.org/show_bug.cgi?id=143407.
+
+var verbose = false;
+
+function foo() {
+    return arguments.length;
+}
+
+function Foo() {
+    this.length = arguments.length;
+}
+
+var callTestBodyStr =
+"    var result = this.method.apply(this, arguments);" + "\n" +
+"    return result + 1;";
+
+var constructTestBodyStr =
+"    return new this.constructor(...arguments);";
+
+var tiers = [
+    { name: "LLint", iterations: 10 },
+    { name: "BaselineJIT", iterations: 50 },
+    { name: "DFG", iterations: 500 },
+    { name: "FTL", iterations: 10000 },
+];
+
+function doTest(testCategory, testBodyStr, tier) {
+    try {
+        var iterations = tiers[tier].iterations;
+        if (verbose)
+            print("Testing " + testCategory + " tier " + tiers[tier].name + " by iterating " + iterations + " times");
+
+        var o = {}
+        o.method = foo;
+        o.constructor = Foo;
+        o.trigger = new Function(testBodyStr);
+
+        for (var i = 0; i < iterations; i++)
+            o.trigger(o, 1);
+        o.trigger(o, 1, 2);
+
+    } catch (e) {
+        print("FAILED " + testCategory + " in tier " + tiers[tier].name + ": " + e);
+        return false;
+    }
+    return true;
+}
+
+var failureFound = 0;
+
+for (var tier = 0; tier < tiers.length; tier++) {
+    if (!doTest("op_call_varargs", callTestBodyStr, tier))
+        failureFound++;
+}
+
+for (var tier = 0; tier < tiers.length; tier++) {
+    if (!doTest("op_construct_varargs", constructTestBodyStr, tier))
+        failureFound++;
+}
+
+if (failureFound == 1)
+    throw "ERROR: test has 1 failure";
+else if (failureFound > 1)
+    throw "ERROR: test has " + failureFound + " failures";
+else if (verbose)
+    print("No failures");
diff --git a/tests/stress/class-syntax-derived-default-constructor.js b/tests/stress/class-syntax-derived-default-constructor.js
new file mode 100644 (file)
index 0000000..f0c477e
--- /dev/null
@@ -0,0 +1,26 @@
+
+var A = class A { };
+var B = class B extends A { };
+var C = class C extends B { constructor() { super(); } };
+
+noInline(C);
+
+(function() {
+    var x;
+    for (var i = 0; i < 1e5; ++i)
+        x = new C(false);
+})();
+
+var D = class D extends A { constructor() {
+    super(...arguments);
+    return function () { return arguments; }
+} };
+var E = class E extends D { constructor() { super(); } };
+
+noInline(E);
+
+(function() {
+    var x;
+    for (var i = 0; i < 1e5; ++i)
+        x = new C(false);
+})();
diff --git a/tests/stress/class-syntax-no-loop-tdz.js b/tests/stress/class-syntax-no-loop-tdz.js
new file mode 100644 (file)
index 0000000..87a65cb
--- /dev/null
@@ -0,0 +1,20 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        for (var j = 0; j < 10; j++) {
+            if (!j)
+                super();
+            else
+                this;
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B();
diff --git a/tests/stress/class-syntax-no-tdz-in-catch.js b/tests/stress/class-syntax-no-tdz-in-catch.js
new file mode 100644 (file)
index 0000000..05d144a
--- /dev/null
@@ -0,0 +1,19 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        try {
+            this;
+        } catch (e) {
+            super();
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B();
diff --git a/tests/stress/class-syntax-no-tdz-in-conditional.js b/tests/stress/class-syntax-no-tdz-in-conditional.js
new file mode 100644 (file)
index 0000000..71276b1
--- /dev/null
@@ -0,0 +1,18 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor(accessThisBeforeSuper) {
+        if (accessThisBeforeSuper)
+            this;
+        else
+            super();
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B(false);
diff --git a/tests/stress/class-syntax-no-tdz-in-eval.js b/tests/stress/class-syntax-no-tdz-in-eval.js
new file mode 100644 (file)
index 0000000..93bcd31
--- /dev/null
@@ -0,0 +1,18 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor(shouldAccessThis) {
+        var evalFunction = eval;
+        evalFunction("this");
+        eval("shouldAccessThis ? this : null");
+        super();
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 1e4; ++i)
+    new B(false);
diff --git a/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js b/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js
new file mode 100644 (file)
index 0000000..533a4ad
--- /dev/null
@@ -0,0 +1,25 @@
+
+class A {
+    constructor() { }
+}
+
+noInline(A);
+
+class B extends A {
+    constructor() {
+        var values = [];
+        for (var j = 0; j < 100; j++) {
+            if (j == 1)
+                super();
+            else if (j > 2)
+                this;
+            else
+                values.push(i);
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B();
diff --git a/tests/stress/class-syntax-no-tdz-in-loop.js b/tests/stress/class-syntax-no-tdz-in-loop.js
new file mode 100644 (file)
index 0000000..574bc10
--- /dev/null
@@ -0,0 +1,23 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        var values = [];
+        for (var j = 0; j < 100; j++) {
+            if (j == 1)
+                super();
+            else if (j > 2)
+                this;
+            else
+                values.push(i);
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B();
diff --git a/tests/stress/class-syntax-no-tdz.js b/tests/stress/class-syntax-no-tdz.js
new file mode 100644 (file)
index 0000000..b0c7c31
--- /dev/null
@@ -0,0 +1,16 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        super();
+        this;
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i)
+    new B();
diff --git a/tests/stress/class-syntax-tdz-in-catch.js b/tests/stress/class-syntax-tdz-in-catch.js
new file mode 100644 (file)
index 0000000..3704bcf
--- /dev/null
@@ -0,0 +1,30 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        try {
+            this;
+        } catch (e) {
+            this;
+            super();
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i) {
+    var exception = null;
+    try {
+         new B(false);
+    } catch (e) {
+        exception = e;
+        if (!(e instanceof ReferenceError))
+            throw "Exception thrown in iteration " + i + " was not a reference error";
+    }
+    if (!exception)
+        throw "Exception not thrown for an unitialized this at iteration " + i;
+}
diff --git a/tests/stress/class-syntax-tdz-in-conditional.js b/tests/stress/class-syntax-tdz-in-conditional.js
new file mode 100644 (file)
index 0000000..27d0bcb
--- /dev/null
@@ -0,0 +1,28 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor(accessThisBeforeSuper) {
+        if (accessThisBeforeSuper)
+            this;
+        else {
+            this;
+            super();
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i) {
+    var exception = null;
+    try {
+         new B(false);
+    } catch (e) {
+        exception = e;
+    }
+    if (!exception)
+        throw "Exception not thrown for an unitialized this at iteration " + i;
+}
diff --git a/tests/stress/class-syntax-tdz-in-eval.js b/tests/stress/class-syntax-tdz-in-eval.js
new file mode 100644 (file)
index 0000000..e0c965b
--- /dev/null
@@ -0,0 +1,26 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        eval("this");
+        super();
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 1e4; ++i) {
+    var exception;
+    try {
+        new B();
+    } catch (e) {
+        exception = e;
+        if (!(e instanceof ReferenceError))
+            throw "Exception thrown in iteration " + i + " was not a reference error";
+    }
+    if (!exception)
+        throw "Exception not thrown for an unitialized this at iteration " + i;
+}
diff --git a/tests/stress/class-syntax-tdz-in-loop.js b/tests/stress/class-syntax-tdz-in-loop.js
new file mode 100644 (file)
index 0000000..6ab5e6d
--- /dev/null
@@ -0,0 +1,30 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        for (var j = 0; j < 100; j++) {
+            if (j)
+                super();
+            else
+                this;
+        }
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i) {
+    var exception = null;
+    try {
+        new B();
+    } catch (e) {
+        exception = e;
+        if (!(e instanceof ReferenceError))
+            throw "Exception thrown in iteration " + i + " was not a reference error";
+    }
+    if (!exception)
+        throw "Exception not thrown for an unitialized this at iteration " + i;
+}
diff --git a/tests/stress/class-syntax-tdz.js b/tests/stress/class-syntax-tdz.js
new file mode 100644 (file)
index 0000000..1444910
--- /dev/null
@@ -0,0 +1,26 @@
+
+class A {
+    constructor() { }
+}
+
+class B extends A {
+    constructor() {
+        this;
+        super();
+    }
+}
+
+noInline(B);
+
+for (var i = 0; i < 10000; ++i) {
+    var exception;
+    try {
+        new B();
+    } catch (e) {
+        exception = e;
+        if (!(e instanceof ReferenceError))
+            throw "Exception thrown in iteration " + i + " was not a reference error";
+    }
+    if (!exception)
+        throw "Exception not thrown for an unitialized this at iteration " + i;
+}
diff --git a/tests/stress/cloned-arguments-get-by-val-double-array.js b/tests/stress/cloned-arguments-get-by-val-double-array.js
new file mode 100644 (file)
index 0000000..a026aff
--- /dev/null
@@ -0,0 +1,13 @@
+function foo() {
+    "use strict";
+    return arguments[0] + 1.5;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(4.2);
+    if (result != 5.7)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/cloned-arguments-should-visit-callee-during-gc.js b/tests/stress/cloned-arguments-should-visit-callee-during-gc.js
new file mode 100644 (file)
index 0000000..3ba0f16
--- /dev/null
@@ -0,0 +1,34 @@
+// Test that the ClonedArguments created by the Function.arguments will properly
+// keep its callee alive.  This test should not crash and should not print any error
+// messages.
+
+var cachedArguments = [];
+var numberOfEntries = 1000;
+
+function makeTransientFunction(i) {
+    function transientFunc() {
+        cachedArguments[i] = transientFunc.arguments;
+    }
+    return transientFunc;
+}
+
+for (i = 0; i < numberOfEntries; i++) {
+    var transientFunc = makeTransientFunction(i);
+    transientFunc();
+    // At this point, the only reference to the transient function is from
+    // cachedArguments[i].callee.
+}
+
+gc();
+
+// Allocate a bunch of memory to stomp over the transient functions that may have been
+// erroneously collected. webkit.org/b/145709
+for (i = 0; i < numberOfEntries; i++) {
+    new Object();
+}
+
+for (i = 0; i < numberOfEntries; i++) {
+    var callee = cachedArguments[i].callee;
+    if (typeof callee != "function")
+        print("ERROR: callee is " + callee); 
+}
diff --git a/tests/stress/closure-call-exit.js b/tests/stress/closure-call-exit.js
new file mode 100644 (file)
index 0000000..3133cb0
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(o, i) {
+    return o[i]();
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo([function() { return 42; }], 0);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo([function() { return 43; }], 0);
+if (result != 43)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/construct-forward-varargs-for-inlined-escaped-arguments.js b/tests/stress/construct-forward-varargs-for-inlined-escaped-arguments.js
new file mode 100644 (file)
index 0000000..3c17f42
--- /dev/null
@@ -0,0 +1,23 @@
+function foo() {
+    return arguments;
+}
+
+function Baz(a, b, c) {
+    this.f = a + b + c;
+}
+
+noInline(Baz);
+
+function bar(a, b, c) {
+    var args = foo(b, c, 42);
+    return new Baz(...args);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2, 3);
+    if (result.f != 47)
+        throw "Error: bad result: " + result.f;
+}
+
diff --git a/tests/stress/construct-varargs-inline-smaller-Foo.js b/tests/stress/construct-varargs-inline-smaller-Foo.js
new file mode 100644 (file)
index 0000000..77b5b3d
--- /dev/null
@@ -0,0 +1,35 @@
+function Foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    this.f = array;
+}
+
+function bar(array) {
+    return new Foo(...array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.length != b.length)
+        throw "Error: bad value of c, length mismatch: " + a + " versus " + b;
+    for (var i = a.length; i--;) {
+        if (a[i] != b[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a + " versus " + b;
+    }
+}
+
+function test(array) {
+    var expected = array;
+    var actual = bar(array).f;
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
diff --git a/tests/stress/construct-varargs-inline.js b/tests/stress/construct-varargs-inline.js
new file mode 100644 (file)
index 0000000..ff4ccce
--- /dev/null
@@ -0,0 +1,39 @@
+function Foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    this.f = {a:a, b:b, c:array};
+}
+
+function bar(array) {
+    return new Foo(...array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0], b:array[1], c:array};
+    var actual = bar(array).f;
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
diff --git a/tests/stress/construct-varargs-no-inline.js b/tests/stress/construct-varargs-no-inline.js
new file mode 100644 (file)
index 0000000..333646e
--- /dev/null
@@ -0,0 +1,41 @@
+function Foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    this.f = {a:a, b:b, c:array};
+}
+
+noInline(Foo);
+
+function bar(array) {
+    return new Foo(...array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0], b:array[1], c:array};
+    var actual = bar(array).f;
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
diff --git a/tests/stress/constructor-with-return.js b/tests/stress/constructor-with-return.js
new file mode 100644 (file)
index 0000000..32a2892
--- /dev/null
@@ -0,0 +1,39 @@
+function Test(value, returnIt) {
+    this.value = value;
+    this.returnIt = returnIt;
+}
+
+var tests = [
+    new Test("string", false),
+    new Test(5, false),
+    new Test(6.5, false),
+    new Test(void(0), false),
+    new Test(null, false),
+    new Test(true, false),
+    new Test(false, false),
+    new Test(Symbol.iterator, false),
+    new Test({f:42}, true),
+    new Test([1, 2, 3], true),
+    new Test(new String("string"), true),
+    new Test(new Number(42), true),
+    new Test(new Boolean(false), true),
+    new Test(new Boolean(false), true),
+    new Test(Object(Symbol.iterator), true),
+];
+
+tests.forEach(function (test) {
+    function Constructor() {
+        return test.value;
+    }
+
+    var result = new Constructor();
+    if (test.returnIt) {
+        if (test.value !== result) {
+            throw "Bad result: " + result;
+        }
+    } else {
+        if (!(result instanceof Constructor)) {
+            throw "Bad result: " + result;
+        }
+    }
+});
diff --git a/tests/stress/create-this-with-callee-variants.js b/tests/stress/create-this-with-callee-variants.js
new file mode 100644 (file)
index 0000000..a7368ae
--- /dev/null
@@ -0,0 +1,18 @@
+function createInLoop(x, count) {
+    noInline(x)
+    for (var i = 0; i < 5000; i++) {
+        var obj = new x;
+        if (!(obj instanceof x))
+            throw "Failed to instantiate the right object";
+    }
+}
+
+function y() { return function () {} }
+
+createInLoop(y());
+
+function z() { return function () {} }
+
+createInLoop(z());
+createInLoop(z());
+createInLoop(z());
diff --git a/tests/stress/custom-iterators.js b/tests/stress/custom-iterators.js
new file mode 100644 (file)
index 0000000..fd6413f
--- /dev/null
@@ -0,0 +1,322 @@
+// This test checks the behavior of custom iterable objects.
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+    }
+};
+var expected = 0;
+for (var value of iter) {
+    if (value !== expected++)
+        throw "Error: bad value: " + value;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: Terminate iteration.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+for (var value of iter) {
+    break;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    get next() {
+        throw "Error: looking up next.";
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+    }
+};
+try {
+    for (var value of iter) {
+        throw "Error: Iteration should not occur.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: looking up next.")
+        throw "Error: bad error thrown: " + e;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    get return() {
+        throw "Error: looking up return."
+    }
+};
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: looking up return.")
+        throw "Error: bad error thrown: " + e;
+}
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        throw "Error: next is called."
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: next is called.")
+        throw "Error: bad error thrown: " + e;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return { done: false, value: 42 };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        throw "Error: return is called.";
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: Terminate iteration.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return { done: false, value: 42 };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        throw "Error: return is called.";
+    }
+};
+try {
+    for (var value of iter) {
+        break;
+    }
+} catch (e) {
+    if (String(e) !== "Error: return is called.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+var primitives = [
+    undefined,
+    null,
+    42,
+    "string",
+    true,
+    Symbol("Cocoa")
+];
+
+function iteratorInterfaceErrorTest(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return notIteratorResult;
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return undefined;
+        }
+    };
+    try {
+        for (var value of iter) {
+            throw "Error: Iteration should not occur.";
+        }
+    } catch (e) {
+        if (String(e) !== "TypeError: Iterator result interface is not an object.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (returnCalled)
+        throw "Error: return is called.";
+}
+
+function iteratorInterfaceErrorTestReturn(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return { done: false, value: 42 };
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return notIteratorResult;
+        }
+    };
+    try {
+        for (var value of iter) {
+            throw "Error: Terminate iteration.";
+        }
+    } catch (e) {
+        if (String(e) !== "Error: Terminate iteration.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (!returnCalled)
+        throw "Error: return is not called.";
+}
+
+primitives.forEach(iteratorInterfaceErrorTest);
+primitives.forEach(iteratorInterfaceErrorTestReturn);
+
+
+function iteratorInterfaceBreakTestReturn(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return { done: false, value: 42 };
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return notIteratorResult;
+        }
+    };
+    try {
+        for (var value of iter) {
+            break;
+        }
+    } catch (e) {
+        if (String(e) !== "TypeError: Iterator result interface is not an object.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (!returnCalled)
+        throw "Error: return is not called.";
+}
+
+primitives.forEach(iteratorInterfaceBreakTestReturn);
diff --git a/tests/stress/dead-get-closure-var.js b/tests/stress/dead-get-closure-var.js
new file mode 100644 (file)
index 0000000..7622fb0
--- /dev/null
@@ -0,0 +1,23 @@
+var global;
+
+function foo(a) {
+    var x = a.f;
+    var f = function() { global = x; };
+    noInline(f);
+    f();
+    var tmp1 = a.g + 1;
+    var tmp2 = x;
+    return global;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i, g:i + 1});
+    if (result != i)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:42, g:4.2});
+if (result != 42)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/dead-osr-entry-value.js b/tests/stress/dead-osr-entry-value.js
new file mode 100644 (file)
index 0000000..dc45338
--- /dev/null
@@ -0,0 +1,16 @@
+function foo() {
+    var o = {f:42};
+    var result = 0;
+    OSRExit();
+    for (var i = 0; i < 10000; ++i) {
+        if (!DFGTrue())
+            result += o.f;
+    }
+    return result;
+}
+
+for (var i = 0; i < 1000; ++i) {
+    foo();
+    fullGC();
+}
+
diff --git a/tests/stress/dead-speculating-argument-use.js b/tests/stress/dead-speculating-argument-use.js
new file mode 100644 (file)
index 0000000..5f3ebfc
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(x) {
+    var tmp = x + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+    foo(i);
+
+var didCall = false;
+var o = {
+    valueOf: function() { didCall = true; }
+};
+
+foo(o);
+if (!didCall)
+    throw "Error: didn't call valueOf";
diff --git a/tests/stress/destructuring-assignment-accepts-iterables.js b/tests/stress/destructuring-assignment-accepts-iterables.js
new file mode 100644 (file)
index 0000000..f14688b
--- /dev/null
@@ -0,0 +1,441 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+(function () {
+    var [a, b, c] = [1, 2, 3];
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [a, b, c] = [1, 2, 3].keys();
+    shouldBe(a, 0);
+    shouldBe(b, 1);
+    shouldBe(c, 2);
+}());
+
+(function () {
+    var [a, b, c] = [1, 2, 3].values();
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [a, , c] = [1, 2, 3].values();
+    shouldBe(a, 1);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [a, b, c] = [1, , 3].values();
+    shouldBe(a, 1);
+    shouldBe(b, undefined);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [, b, c] = [1, 2, 3, 4, 5, 6].values();
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [a, b, c] = [1].values();
+    shouldBe(a, 1);
+    shouldBe(b, undefined);
+    shouldBe(c, undefined);
+}());
+
+(function ([a, b, c]) {
+    shouldBe(a, 1);
+    shouldBe(b, undefined);
+    shouldBe(c, undefined);
+}([1].values()));
+
+(function () {
+    var [a = 0, b = 2, c = 3] = [1].values();
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+}());
+
+(function () {
+    var [a = 1, b = 2, c = 3] = [undefined, undefined, undefined];
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+}());
+
+// String with a surrogate pair.
+(function () {
+    var string = "𠮷野家";
+    var [a, b, c] = string;
+    shouldBe(string.length, 4);
+    shouldBe(a, '𠮷');
+    shouldBe(b, '野');
+    shouldBe(c, '家');
+}());
+
+(function () {
+    var set = new Set([1, 2, 3]);
+    var [a, b, c] = set;
+    shouldBe(set.has(a), true);
+    shouldBe(set.has(b), true);
+    shouldBe(set.has(c), true);
+}());
+
+(function () {
+    var map = new Map([[1, 1], [2, 2], [3, 3]]);
+    var [a, b, c] = map;
+    shouldBe(Array.isArray(a), true);
+    shouldBe(Array.isArray(b), true);
+    shouldBe(Array.isArray(c), true);
+    shouldBe(map.has(a[0]), true);
+    shouldBe(map.has(b[0]), true);
+    shouldBe(map.has(c[0]), true);
+}());
+
+// Errors
+
+shouldThrow(function () {
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return 42;
+        }
+    };
+}, "TypeError: [a, b, c] is not a function. (In '[a, b, c]', '[a, b, c]' is undefined)");
+
+shouldThrow(function () {
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return {};
+        }
+    };
+}, "TypeError: [a, b, c] is not a function. (In '[a, b, c]', '[a, b, c]' is undefined)");
+
+shouldThrow(function () {
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        next() {
+            throw new Error('out');
+        }
+    };
+}, 'Error: out');
+
+shouldThrow(function () {
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        next() {
+            return 42;
+        }
+    };
+}, 'TypeError: Iterator result interface is not an object.');
+
+(function () {
+    var ok = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            return() {
+                ok++;
+            },
+
+            next() {
+                return 42;
+            }
+        };
+    }, 'TypeError: Iterator result interface is not an object.');
+
+    shouldBe(ok, 0);
+}());
+
+(function () {
+    var ok = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            return() {
+                ok++;
+            },
+
+            next() {
+                return { value: 20, done: false };
+            }
+        };
+    }, 'TypeError: Iterator result interface is not an object.');
+
+    shouldBe(ok, 1);
+}());
+
+(function () {
+    var ok = 0;
+
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        return() {
+            ok++;
+        },
+
+        next() {
+            return { value: 20, done: true };
+        }
+    };
+
+    shouldBe(a, undefined);
+    shouldBe(b, undefined);
+    shouldBe(c, undefined);
+    shouldBe(ok, 0);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+
+    var done = false;
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        return() {
+            ok++;
+        },
+
+        next() {
+            var prev = done;
+            done = true;
+            ++n;
+            return { value: 20, done: prev };
+        }
+    };
+
+    shouldBe(a, 20);
+    shouldBe(b, undefined);
+    shouldBe(c, undefined);
+    shouldBe(n, 2);
+    shouldBe(ok, 0);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+
+    var done = false;
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        return() {
+            ++ok;
+            return { done: true };
+        },
+
+        next() {
+            ++n;
+            return { value: 20, done: false };
+        }
+    };
+
+    shouldBe(a, 20);
+    shouldBe(b, 20);
+    shouldBe(c, 20);
+    shouldBe(n, 3);
+    shouldBe(ok, 1);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+
+    var done = false;
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        return() {
+            ++ok;
+            return { done: true };
+        },
+
+        count: 0,
+
+        next() {
+            ++n;
+            var done = ++this.count === 3;
+            return { value: 20, done };
+        }
+    };
+
+    shouldBe(a, 20);
+    shouldBe(b, 20);
+    shouldBe(c, undefined);
+    shouldBe(n, 3);
+    shouldBe(ok, 0);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+
+    var done = false;
+    var [a, b, c] = {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        return() {
+            ++ok;
+            return { done: true };
+        },
+
+        count: 0,
+
+        next() {
+            ++n;
+            var done = ++this.count === 4;
+            return { value: 20, done };
+        }
+    };
+
+    shouldBe(a, 20);
+    shouldBe(b, 20);
+    shouldBe(c, 20);
+    shouldBe(n, 3);
+    shouldBe(ok, 1);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            return() {
+                ok++;
+                throw new Error('out');
+            },
+
+            next() {
+                n++;
+                return { value: 20, done: false };
+            }
+        };
+    }, 'Error: out');
+
+    shouldBe(n, 3);
+    shouldBe(ok, 1);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            get return() {
+                ok++;
+                throw new Error('out');
+            },
+
+            next() {
+                n++;
+                return { value: 20, done: false };
+            }
+        };
+    }, 'Error: out');
+
+    shouldBe(n, 3);
+    shouldBe(ok, 1);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            get return() {
+                ok++;
+                throw new Error('ng');
+            },
+
+            next() {
+                n++;
+                throw new Error('out');
+            }
+        };
+    }, 'Error: out');
+
+    shouldBe(n, 1);
+    shouldBe(ok, 0);
+}());
+
+(function () {
+    var ok = 0;
+    var n = 0;
+    shouldThrow(function () {
+        var [a, b, c] = {
+            [Symbol.iterator]() {
+                return this;
+            },
+
+            get return() {
+                ok++;
+                throw new Error('ng');
+            },
+
+            get next() {
+                ++n;
+                throw new Error('out');
+            }
+        };
+    }, 'Error: out');
+
+    shouldBe(n, 1);
+    shouldBe(ok, 0);
+}());
diff --git a/tests/stress/dfg-put-by-val-direct-with-edge-numbers.js b/tests/stress/dfg-put-by-val-direct-with-edge-numbers.js
new file mode 100644 (file)
index 0000000..ebf21e2
--- /dev/null
@@ -0,0 +1,104 @@
+// Test that a object accepts DFG PutByValueDirect operation with edge numbers.
+
+function lookupWithKey(key) {
+    var object = {
+        [key]: 42
+    };
+    return object[key];
+}
+noInline(lookupWithKey);
+
+for (var i = 0; i < 10000; ++i) {
+    [
+        // integers
+        -0x80000001,  // out of int32_t
+        -0x80000000,  // int32_t min
+        -1,           // negative
+        0,            // zero
+        1,            // positive
+        0x7fffffff,   // int32_t max
+        0x80000000,   // out of int32_t
+        0xfffffffd,   // less than array max in JSObject
+        0xfffffffe,   // array max in JSObject
+        0xffffffff,   // uint32_t max, not array index
+        0x100000000,  // out of uint32_t
+
+        // stringified integers
+        (-0x80000001).toString(),  // out of int32_t
+        (-0x80000000).toString(),  // int32_t min
+        (-1).toString(),           // negative
+        (0).toString(),            // zero
+        (1).toString(),            // positive
+        (0x7fffffff).toString(),   // int32_t max
+        (0x80000000).toString(),   // out of int32_t
+        (0xfffffffd).toString(),   // less than array max in JSObject
+        (0xfffffffe).toString(),   // array max in JSObject
+        (0xffffffff).toString(),   // (uint32_t max).toString()
+        (0x100000000).toString(),  // out of uint32_t
+
+        // doubles
+        Number.MIN_VALUE,
+        Number.MAX_VALUE,
+        Number.MIN_SAFE_INTEGER,
+        Number.MAX_SAFE_INTEGER,
+        Number.POSITIVE_INFINITY,
+        Number.NEGATIVE_INFINITY,
+        Number.NaN,
+        Number.EPSILON,
+        +0.0,
+        -0.0,
+        0.1,
+        -0.1,
+        4.2,
+        -4.2,
+        0x80000000 + 0.5,   // out of int32_t, double
+
+        // stringified doules
+        (Number.MIN_VALUE).toString(),
+        (Number.MAX_VALUE).toString(),
+        (Number.MIN_SAFE_INTEGER).toString(),
+        (Number.MAX_SAFE_INTEGER).toString(),
+        (Number.POSITIVE_INFINITY).toString(),
+        (Number.NEGATIVE_INFINITY).toString(),
+        "NaN",
+        (Number.EPSILON).toString(),
+        "+0.0",
+        "-0.0",
+        "0.1",
+        "-0.1",
+        "4.2",
+        "-4.2",
+        (0x80000000 + 0.5).toString()
+    ].forEach(function (key) {
+        var value = lookupWithKey(key);
+        if (value !== 42)
+            throw new Error('bad value: ' + value);
+    });
+}
+
+function lookupWithKey2(key) {
+    var object = {
+        [key]: 42
+    };
+    return object[key];
+}
+noInline(lookupWithKey2);
+
+var toStringThrowsError = {
+    toString: function () {
+        throw new Error('ng');
+    }
+};
+
+for (var i = 0; i < 10000; ++i) {
+    var error = null;
+    try {
+        lookupWithKey2(toStringThrowsError);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('not thrown');
+    if (String(error) !== 'Error: ng')
+        throw new Error('bad error: ' + String(error));
+}
diff --git a/tests/stress/dfg-rare-data.js b/tests/stress/dfg-rare-data.js
new file mode 100644 (file)
index 0000000..45a3f0e
--- /dev/null
@@ -0,0 +1,9 @@
+function F () { this.inner = 42; };
+
+for (var i = 0; i < 10000; ++i) {
+    var x = new F(false);
+    F.prototype = Object; // Force clearing of the function's rare data
+    var result = x.inner;
+    if (result !== 42)
+        throw "Expected 42, got: " + result;
+}
diff --git a/tests/stress/dfg-to-primitive-pass-symbol.js b/tests/stress/dfg-to-primitive-pass-symbol.js
new file mode 100644 (file)
index 0000000..2a5ffa9
--- /dev/null
@@ -0,0 +1,35 @@
+var shouldThrow = false;
+
+// str concat generates op_to_primitive.
+function toPrimitiveTarget() {
+    if (shouldThrow) {
+        return Symbol('Cocoa');
+    }
+    return 'Cocoa';
+}
+noInline(toPrimitiveTarget);
+
+function doToPrimitive() {
+    var value = toPrimitiveTarget();
+    return value + "Cappuccino" + value;
+}
+noInline(doToPrimitive);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = doToPrimitive();
+    if (result !== "CocoaCappuccinoCocoa")
+        throw "Error: bad result: " + result;
+}
+
+shouldThrow = true;
+
+var didThrow;
+try {
+    shouldThrow = true;
+    doToPrimitive();
+} catch (e) {
+    didThrow = e;
+}
+
+if (String(didThrow) !== "TypeError: Type error")
+    throw "Error: didn't throw or threw wrong exception: " + didThrow;
diff --git a/tests/stress/disable-function-dot-arguments.js b/tests/stress/disable-function-dot-arguments.js
new file mode 100644 (file)
index 0000000..ba94fc3
--- /dev/null
@@ -0,0 +1,20 @@
+//@ run("function-dot-arguments", "--enableFunctionDotArguments=false")
+
+function foo() {
+    var a = bar.arguments;
+    if (a.length != 0)
+        throw "Error: arguments have non-zero length";
+    for (var i = 0; i < 100; ++i) {
+        if (a[i] !== void 0)
+            throw "Error: argument " + i + " has non-undefined value";
+    }
+}
+
+function bar() {
+    foo();
+}
+
+bar();
+bar(1);
+bar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
diff --git a/tests/stress/double-rep-with-non-cell.js b/tests/stress/double-rep-with-non-cell.js
new file mode 100644 (file)
index 0000000..bc6a192
--- /dev/null
@@ -0,0 +1,32 @@
+// Only bool, undefined and null
+function addNullBoolUndefined(a, b) {
+    return a + b;
+}
+noInline(addNullBoolUndefined);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addNullBoolUndefined(0.5, null);
+    if (value !== 0.5)
+        throw "addNullBoolUndefined(0.5, null) failed with i = " + i + " returned value = " + value;
+
+    var value = addNullBoolUndefined(null, undefined);
+    if (value === value)
+        throw "addNullBoolUndefined(null, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addNullBoolUndefined(true, null);
+    if (value !== 1)
+        throw "addNullBoolUndefined(true, null) failed with i = " + i + " returned value = " + value;
+
+    var value = addNullBoolUndefined(undefined, false);
+    if (value === value)
+        throw "addNullBoolUndefined(undefined, false) failed with i = " + i + " returned value = " + value;
+
+    var value = addNullBoolUndefined(false, true);
+    if (value !== 1)
+        throw "addNullBoolUndefined(false, true) failed with i = " + i + " returned value = " + value;
+
+    var value = addNullBoolUndefined(null, 42);
+    if (value !== 42)
+        throw "addNullBoolUndefined(null, 42) failed with i = " + i + " returned value = " + value;
+
+}
diff --git a/tests/stress/double-rep-with-null.js b/tests/stress/double-rep-with-null.js
new file mode 100644 (file)
index 0000000..01b6259
--- /dev/null
@@ -0,0 +1,107 @@
+// Using full number + null for math.
+function addArgsNumberAndNull(a, b) {
+    return a + b;
+}
+noInline(addArgsNumberAndNull);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsNumberAndNull(i, 1);
+    if (value !== (i + 1))
+        throw "addArgsNumberAndNull(i, 1) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndNull(0.5, i);
+    if (value !== (i + 0.5))
+        throw "addArgsNumberAndNull(0.5, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndNull(null, i);
+    if (value !== i)
+        throw "addArgsNumberAndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndNull(i, null);
+    if (value !== i)
+        throw "addArgsNumberAndNull(i, null) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndNull(null, null);
+    if (value !== 0)
+        throw "addArgsNumberAndNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+
+// Using int32 + null for math.
+function addArgsInt32AndNull(a, b) {
+    return a + b;
+}
+noInline(addArgsInt32AndNull);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsInt32AndNull(i, 1);
+    if (value !== (i + 1))
+        throw "addArgsInt32AndNull(i, 1) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndNull(null, i);
+    if (value !== i)
+        throw "addArgsInt32AndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndNull(i, null);
+    if (value !== i)
+        throw "addArgsInt32AndNull(i, null) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndNull(null, null);
+    if (value !== 0)
+        throw "addArgsInt32AndNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithDouble() {
+    var value = addArgsNumberAndNull(Math.PI, Math.PI);
+    if (value !== 2 * Math.PI)
+        throw "addArgsNumberAndNull(Math.PI, Math.PI) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithDouble();
+
+
+// Using full number + null for math.
+function addArgsDoubleAndNull(a, b) {
+    return a + b;
+}
+noInline(addArgsDoubleAndNull);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsDoubleAndNull(0.5, i);
+    if (value !== (i + 0.5))
+        throw "addArgsDoubleAndNull(0.5, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsDoubleAndNull(null, 0.1);
+    if (value !== 0.1)
+        throw "addArgsDoubleAndNull(null, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsDoubleAndNull(0.6, null);
+    if (value !== 0.6)
+        throw "addArgsDoubleAndNull(i, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithObject() {
+    var value = addArgsDoubleAndNull(Math.PI, { valueOf: function() { return 5; }});
+    if (value !== 5 + Math.PI)
+        throw "addArgsDoubleAndNull(Math.PI, { valueOf: function() { return 5; }}) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithObject();
+
+
+// Using only null
+function addArgsOnlyNull(a, b) {
+    return a + b;
+}
+noInline(addArgsOnlyNull);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsOnlyNull(null, null);
+    if (value !== 0)
+        throw "addArgsOnlyNull(null, null) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithString() {
+    var value = addArgsOnlyNull("foo", "bar");
+    if (value !== "foobar")
+        throw "addArgsOnlyNull(\"foo\", \"bar\") failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithString();
\ No newline at end of file
diff --git a/tests/stress/double-rep-with-undefined.js b/tests/stress/double-rep-with-undefined.js
new file mode 100644 (file)
index 0000000..d41fba6
--- /dev/null
@@ -0,0 +1,131 @@
+// Using full number + undefined for math.
+function addArgsNumberAndUndefined(a, b) {
+    return a + b;
+}
+noInline(addArgsNumberAndUndefined);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsNumberAndUndefined(i, 1);
+    if (value !== (i + 1))
+        throw "addArgsNumberAndUndefined(i, 1) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined(0.5, i);
+    if (value !== (i + 0.5))
+        throw "addArgsNumberAndUndefined(0.5, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined(undefined, i);
+    if (value === value)
+        throw "addArgsNumberAndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined(i, undefined);
+    if (value === value)
+        throw "addArgsNumberAndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined(i);
+    if (value === value)
+        throw "addArgsNumberAndUndefined(i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined(undefined, undefined);
+    if (value === value)
+        throw "addArgsNumberAndUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsNumberAndUndefined();
+    if (value === value)
+        throw "addArgsNumberAndUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+
+// Using int32 + undefined for math.
+function addArgsInt32AndUndefined(a, b) {
+    return a + b;
+}
+noInline(addArgsInt32AndUndefined);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsInt32AndUndefined(i, 1);
+    if (value !== (i + 1))
+        throw "addArgsInt32AndUndefined(i, 1) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndUndefined(undefined, i);
+    if (value === value)
+        throw "addArgsInt32AndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndUndefined(i, undefined);
+    if (value === value)
+        throw "addArgsInt32AndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndUndefined(i);
+    if (value === value)
+        throw "addArgsInt32AndUndefined(i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndUndefined(undefined, undefined);
+    if (value === value)
+        throw "addArgsInt32AndUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsInt32AndUndefined();
+    if (value === value)
+        throw "addArgsInt32AndUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithDouble() {
+    var value = addArgsNumberAndUndefined(Math.PI, Math.PI);
+    if (value !== 2 * Math.PI)
+        throw "addArgsNumberAndUndefined(Math.PI, Math.PI) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithDouble();
+
+
+// Using full number + undefined for math.
+function addArgsDoubleAndUndefined(a, b) {
+    return a + b;
+}
+noInline(addArgsDoubleAndUndefined);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsDoubleAndUndefined(0.5, i);
+    if (value !== (i + 0.5))
+        throw "addArgsDoubleAndUndefined(0.5, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsDoubleAndUndefined(undefined, 0.1);
+    if (value === value)
+        throw "addArgsDoubleAndUndefined(undefined, i) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsDoubleAndUndefined(0.6, undefined);
+    if (value === value)
+        throw "addArgsDoubleAndUndefined(i, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsDoubleAndUndefined(42.8);
+    if (value === value)
+        throw "addArgsDoubleAndUndefined(i) failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithObject() {
+    var value = addArgsDoubleAndUndefined(Math.PI, { valueOf: function() { return 5; }});
+    if (value !== 5 + Math.PI)
+        throw "addArgsDoubleAndUndefined(Math.PI, { valueOf: function() { return 5; }}) failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithObject();
+
+
+// Using full number + undefined for math.
+function addArgsOnlyUndefined(a, b) {
+    return a + b;
+}
+noInline(addArgsOnlyUndefined);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = addArgsOnlyUndefined(undefined, undefined);
+    if (value === value)
+        throw "addArgsOnlyUndefined(undefined, undefined) failed with i = " + i + " returned value = " + value;
+
+    var value = addArgsOnlyUndefined();
+    if (value === value)
+        throw "addArgsOnlyUndefined() failed with i = " + i + " returned value = " + value;
+}
+
+function testFallbackWithString() {
+    var value = addArgsOnlyUndefined("foo", "bar");
+    if (value !== "foobar")
+        throw "addArgsOnlyUndefined(\"foo\", \"bar\") failed with i = " + i + " returned value = " + value;
+}
+testFallbackWithString();
\ No newline at end of file
diff --git a/tests/stress/elidable-new-object-roflcopter-then-exit.js b/tests/stress/elidable-new-object-roflcopter-then-exit.js
new file mode 100644 (file)
index 0000000..00bd91b
--- /dev/null
@@ -0,0 +1,23 @@
+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 1000000;
+
+var array = [42, "hello"];
+
+function foo() {
+    var result = 0;
+    var q;
+    for (var i = 0; i < n; ++i) {
+        var o = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i}}}}}}}}}}}}}}}}}}};
+        var p = {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: {f: i + 1}}}}}}}}}}}}}}}}}}};
+        q = array[(i > n - 100) | 0] + 1;
+        result += o.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f + p.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f;
+    }
+    return q + result;
+}
+
+var result = foo();
+if (result != "hello" + 1 + (sumOfArithSeries(n - 1) + sumOfArithSeries(n)))
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/elide-new-object-dag-then-exit.js b/tests/stress/elide-new-object-dag-then-exit.js
new file mode 100644 (file)
index 0000000..fbe99a5
--- /dev/null
@@ -0,0 +1,43 @@
+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function verify(q, i) {
+    if (q.f == q.g)
+        throw "Error: q.f == q.g";
+    if (q.f.f != q.g.f)
+        throw "Error: q.f.f != q.g.f";
+    if (q.f.f.f != i)
+        throw "Error: q.f.f.f != i";
+}
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i < n; ++i) {
+        var leaf = {f:i};
+        var o = {f:leaf};
+        var p = {f:leaf};
+        var q = {f:o, g:p};
+        result += q.f.f.f;
+        if (i >= n - 100) {
+            // We want the materialization to happen in the exit. So, before calling the thing that
+            // causes the materialization, we call bar(). We've never profiled this call at the time
+            // of FTL compilation, so this should be an exit.
+            bar();
+            verify(q, i);
+        }
+    }
+    return result;
+}
+
+noInline(foo);
+noInline(verify);
+noInline(bar);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1))
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/empty_eos_regex_split.js b/tests/stress/empty_eos_regex_split.js
new file mode 100644 (file)
index 0000000..05b2796
--- /dev/null
@@ -0,0 +1,3 @@
+var splited = "a".split(/$/);
+if (splited.length != 1 || splited[0] != "a") 
+    throw "Error: " + splited.length + " = " + splited;
diff --git a/tests/stress/equality-type-checking.js b/tests/stress/equality-type-checking.js
new file mode 100644 (file)
index 0000000..5c1bf75
--- /dev/null
@@ -0,0 +1,34 @@
+/***
+ * There was a bug on 32-bit builds where === with objects would not check the tag
+ * when determining equality via pointer comparison.
+ */
+
+"use strict";
+
+function Foo() {}
+
+function checkStrictEq(a, b) {
+    return a === b;
+}
+noInline(checkStrictEq);
+
+function checkStrictEqOther(a, b) {
+    return a === b;
+}
+noInline(checkStrictEqOther);
+
+var foo = new Foo();
+var address = addressOf(foo);
+
+if (address === undefined)
+    throw "Error: address should not be undefined";
+
+if (foo === address || address === foo)
+    throw "Error: an address should not be equal to it's object";
+
+for (var i = 0; i < 10000000; i++) {
+    if (checkStrictEq(foo, address))
+        throw "Error: an address should not be equal to it's object";
+    if (checkStrictEqOther(address,foo))
+        throw "Error: an address should not be equal to it's object";
+}
index 93f8dd9f603c04259bcd8ae87241eb9351c54f09..30bc4306878e4beb8dfa8f11b432f060b7fef2c0 100644 (file)
@@ -58,7 +58,7 @@ function test(func, iteration, object, outcome) {
         throw new Error("Bad result: " + result + " on iteration " + iteration);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(equalsNull, i, null, true);
     test(equalsNull, i, undefined, true);
     test(equalsNull, i, void 0, true);
@@ -66,7 +66,7 @@ for (var i = 0; i < 100000; ++i) {
     test(equalsNull, i, makeMasquerader(), true);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(notEqualsNull, i, null, false);
     test(notEqualsNull, i, undefined, false);
     test(notEqualsNull, i, void 0, false);
@@ -74,7 +74,7 @@ for (var i = 0; i < 100000; ++i) {
     test(notEqualsNull, i, makeMasquerader(), false);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(strictEqualsNull, i, null, true);
     test(strictEqualsNull, i, undefined, false);
     test(strictEqualsNull, i, void 0, false);
@@ -82,7 +82,7 @@ for (var i = 0; i < 100000; ++i) {
     test(strictEqualsNull, i, makeMasquerader(), false);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(strictNotEqualsNull, i, null, false);
     test(strictNotEqualsNull, i, undefined, true);
     test(strictNotEqualsNull, i, void 0, true);
@@ -90,7 +90,7 @@ for (var i = 0; i < 100000; ++i) {
     test(strictNotEqualsNull, i, makeMasquerader(), true);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(equalsUndefined, i, null, true);
     test(equalsUndefined, i, undefined, true);
     test(equalsUndefined, i, void 0, true);
@@ -98,7 +98,7 @@ for (var i = 0; i < 100000; ++i) {
     test(equalsUndefined, i, makeMasquerader(), true);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(notEqualsUndefined, i, null, false);
     test(notEqualsUndefined, i, undefined, false);
     test(notEqualsUndefined, i, void 0, false);
@@ -106,7 +106,7 @@ for (var i = 0; i < 100000; ++i) {
     test(notEqualsUndefined, i, makeMasquerader(), false);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(strictEqualsUndefined, i, null, false);
     test(strictEqualsUndefined, i, undefined, true);
     test(strictEqualsUndefined, i, void 0, true);
@@ -114,7 +114,7 @@ for (var i = 0; i < 100000; ++i) {
     test(strictEqualsUndefined, i, makeMasquerader(), false);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(strictNotEqualsUndefined, i, null, true);
     test(strictNotEqualsUndefined, i, undefined, false);
     test(strictNotEqualsUndefined, i, void 0, false);
@@ -122,7 +122,7 @@ for (var i = 0; i < 100000; ++i) {
     test(strictNotEqualsUndefined, i, makeMasquerader(), true);
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 10000; ++i) {
     test(isFalsey, i, null, true);
     test(isFalsey, i, undefined, true);
     test(isFalsey, i, void 0, true);
diff --git a/tests/stress/escape-object-in-diamond-then-exit.js b/tests/stress/escape-object-in-diamond-then-exit.js
new file mode 100644 (file)
index 0000000..fbb903d
--- /dev/null
@@ -0,0 +1,40 @@
+var global = null;
+
+function foo(p, q) {
+    var o = {f:42};
+    if (p)
+        global = o;
+    var tmp = q + 1;
+    return o.f + tmp;
+}
+
+noInline(foo);
+
+var lastObject = null;
+
+function validateEscape(when) {
+    if (global === lastObject)
+        throw "Error: bad value in global " + when + ", identical to lastObject.";
+    if (global === null || !(typeof global == "object"))
+        throw "Error: bad value in global " + when + ": it's not an object.";
+    if (global.f != 42)
+        throw "Error: bad value in global " + when + ": f isn't 42, it's: " + global.f;
+    lastObject = global;
+    global = null;
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var escape = !!(i & 1);
+    var result = foo(escape, 42);
+    if (result != 42 + 42 + 1)
+        throw "Error: bad result: " + result;
+    if (escape)
+        validateEscape("in loop");
+    else if (global !== null)
+        throw "Error: bad value in global: " + global;
+}
+
+var result = foo(true, 2147483647);
+if (result != 42 + 2147483647 + 1)
+    throw "Error: bad result at end: " + result;
+validateEscape("at end");
diff --git a/tests/stress/eval-script-contains-null-character.js b/tests/stress/eval-script-contains-null-character.js
new file mode 100644 (file)
index 0000000..419215d
--- /dev/null
@@ -0,0 +1,13 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error("bad value: " + actual);
+}
+
+function test() {
+    shouldBe(eval("(`\0`)"), "\0");
+    shouldBe(eval("('\0')"), "\0");
+}
+noInline(test);
+
+for (var i = 0; i < 10000; ++i)
+    test();
diff --git a/tests/stress/exception-in-to-property-key-should-be-handled-early-in-object-methods.js b/tests/stress/exception-in-to-property-key-should-be-handled-early-in-object-methods.js
new file mode 100644 (file)
index 0000000..f7cc01d
--- /dev/null
@@ -0,0 +1,73 @@
+
+var propertyKey = {
+    toString() {
+        throw new Error("propertyKey.toString is called.");
+    }
+};
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+var object = {};
+
+shouldThrow(function () {
+    object.hasOwnProperty(propertyKey);
+}, "Error: propertyKey.toString is called.");
+
+shouldThrow(function () {
+    Object.prototype.hasOwnProperty.call(null, propertyKey);
+}, "Error: propertyKey.toString is called.");
+
+shouldThrow(function () {
+    Object.prototype.hasOwnProperty.call(null, 'ok');
+}, "TypeError: null is not an object (evaluating 'Object.prototype.hasOwnProperty.call(null, 'ok')')");
+
+shouldThrow(function () {
+    object.propertyIsEnumerable(propertyKey);
+}, "Error: propertyKey.toString is called.");
+
+// ToPropertyKey is first, ToObject is following.
+shouldThrow(function () {
+    Object.prototype.propertyIsEnumerable.call(null, propertyKey);
+}, "Error: propertyKey.toString is called.");
+
+shouldThrow(function () {
+    // ToPropertyKey is first, ToObject is following.
+    Object.prototype.propertyIsEnumerable.call(null, 'ok');
+}, "TypeError: null is not an object (evaluating 'Object.prototype.propertyIsEnumerable.call(null, 'ok')')");
+
+shouldThrow(function () {
+    object.__defineGetter__(propertyKey, function () {
+        return 'NG';
+    });
+}, "Error: propertyKey.toString is called.");
+
+if (Object.getOwnPropertyDescriptor(object, ''))
+    throw new Error("bad descriptor");
+
+shouldThrow(function () {
+    object.__defineSetter__(propertyKey, function () {
+        return 'NG';
+    });
+}, "Error: propertyKey.toString is called.");
+
+if (Object.getOwnPropertyDescriptor(object, ''))
+    throw new Error("bad descriptor");
+
+shouldThrow(function () {
+    object.__lookupGetter__(propertyKey);
+}, "Error: propertyKey.toString is called.");
+
+shouldThrow(function () {
+    object.__lookupSetter__(propertyKey);
+}, "Error: propertyKey.toString is called.");
diff --git a/tests/stress/exception-in-to-property-key-should-be-handled-early.js b/tests/stress/exception-in-to-property-key-should-be-handled-early.js
new file mode 100644 (file)
index 0000000..e511d03
--- /dev/null
@@ -0,0 +1,139 @@
+
+var propertyKey = {
+    toString() {
+        throw new Error("propertyKey.toString is called.");
+    }
+};
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+// GetByVal.
+(function () {
+    var called = null;
+    var toStringCalled = false;
+    var property = {
+        toString() {
+            toStringCalled = true;
+            return "value";
+        }
+    };
+    var object = {
+        get value() {
+        },
+        set value(val) {
+        }
+    };
+    Object.defineProperty(object, '', {
+        get: function () {
+            called = "getter for '' is called.";
+        }
+    });
+
+    function test(object, property) {
+        object[property];
+    }
+    noInline(test);
+
+    shouldThrow(function () { test(object, propertyKey); }, "Error: propertyKey.toString is called.");
+    if (called)
+        throw new Error(called);
+    toStringCalled = false;
+    shouldThrow(function () { test(null, propertyKey); }, "TypeError: null is not an object (evaluating 'object[property]')");
+    if (toStringCalled)
+        throw new Error("toString is called.");
+}());
+
+// GetByVal DFG.
+(function () {
+    var called = null;
+    var toStringCalled = false;
+    var property = {
+        toString() {
+            toStringCalled = true;
+            return "value";
+        }
+    };
+    var object = {
+        get ""() {
+            called = "getter for '' is called.";
+        },
+        set ""(val) {
+            called = "setter for '' is called.";
+        },
+
+        get value() {
+        },
+        set value(val) {
+        }
+    };
+
+    function test(object, property) {
+        object[property];
+    }
+    noInline(test);
+
+    for (var i = 0; i < 10000; ++i)
+        test(object, property);
+
+    shouldThrow(function () { test(object, propertyKey); }, "Error: propertyKey.toString is called.");
+    if (called)
+        throw new Error(called);
+    toStringCalled = false;
+    shouldThrow(function () { test(null, propertyKey); }, "TypeError: null is not an object (evaluating 'object[property]')");
+    if (toStringCalled)
+        throw new Error("toString is called.");
+}());
+
+
+// GetByValString.
+(function () {
+    var called;
+    var toStringCalled = false;
+    var property = {
+        toString() {
+            toStringCalled = true;
+            return "value";
+        }
+    };
+    function test(array, length, property) {
+        var result = 0;
+        for (var i = 0; i < length; ++i)
+            result += array[property];
+        return result;
+    }
+    noInline(test);
+
+    Object.defineProperty(String.prototype, "", {
+        get: function () {
+            called = "getter for '' is called.";
+        }
+    });
+
+    var array = [1, 2, 3];
+    for (var i = 0; i < 100000; ++i)
+        test(array, array.length, 0);
+
+    var array = [1, false, 3];
+    for (var i = 0; i < 100000; ++i)
+        test(array, array.length, 1);
+
+    test("hello", "hello".length, 2);
+    shouldThrow(function () { test("hello", "hello".length, propertyKey); }, "Error: propertyKey.toString is called.");
+    if (called)
+        throw new Error(called);
+    toStringCalled = false;
+    shouldThrow(function () { test(null, 20, propertyKey); }, "TypeError: null is not an object (near '...for (var i = 0; i < length; ++i)...')");
+    if (toStringCalled)
+        throw new Error("toString is called.");
+}());
diff --git a/tests/stress/exit-from-getter.js b/tests/stress/exit-from-getter.js
new file mode 100644 (file)
index 0000000..11830b8
--- /dev/null
@@ -0,0 +1,23 @@
+(function() {
+    var o = {_f:42};
+    o.__defineGetter__("f", function() { return this._f * 100; });
+    var result = 0;
+    var n = 50000;
+    function foo(o) {
+        return o.f + 11;
+    }
+    noInline(foo);
+    for (var i = 0; i < n; ++i) {
+        result += foo(o);
+    }
+    if (result != n * (42 * 100 + 11))
+        throw "Error: bad result: " + result;
+    o._f = 1000000000;
+    result = 0;
+    for (var i = 0; i < n; ++i) {
+        result += foo(o);
+    }
+    if (result != n * (1000000000 * 100 + 11))
+        throw "Error: bad result (2): " + result;
+})();
+
diff --git a/tests/stress/exit-from-setter.js b/tests/stress/exit-from-setter.js
new file mode 100644 (file)
index 0000000..fc84c6b
--- /dev/null
@@ -0,0 +1,23 @@
+(function() {
+    var o = {_f:42};
+    o.__defineSetter__("f", function(value) { this._f = value * 100; });
+    var n = 50000;
+    function foo(o_, v_) {
+        var o = o_.f;
+        var v = v_.f;
+        o.f = v;
+        o.f = v + 1;
+    }
+    noInline(foo);
+    for (var i = 0; i < n; ++i) {
+        foo({f:o}, {f:11});
+    }
+    if (o._f != (11 + 1) * 100)
+        throw "Error: bad o._f: " + o._f;
+    for (var i = 0; i < n; ++i) {
+        foo({f:o}, {f:1000000000});
+    }
+    if (o._f != 100 * (1000000000 + 1))
+        throw "Error: bad o._f (2): " + o._f;
+})();
+
diff --git a/tests/stress/fold-based-on-int32-proof-mul-branch.js b/tests/stress/fold-based-on-int32-proof-mul-branch.js
new file mode 100644 (file)
index 0000000..4d1883d
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(a, b) {
+    var value = DFGTrue() ? -0 : "foo";
+    if (a * b == value)
+        return [DFGTrue(), true];
+    return [DFGTrue(), false];
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(1, 1);
+    if (result[1] !== false)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(-1, 0);
+if (result[1] !== true && result[0])
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/fold-based-on-int32-proof-mul.js b/tests/stress/fold-based-on-int32-proof-mul.js
new file mode 100644 (file)
index 0000000..94fa137
--- /dev/null
@@ -0,0 +1,14 @@
+function foo(a, b) {
+    return a * b === -0;
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== false)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(-1, 0);
+if (result !== true)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/fold-based-on-int32-proof-or-zero.js b/tests/stress/fold-based-on-int32-proof-or-zero.js
new file mode 100644 (file)
index 0000000..b28ed69
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(a, b) {
+    var c = a + b;
+    return (c | 0) == c;
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== true)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(1073741824, 1073741824);
+if (result !== false)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/fold-based-on-int32-proof.js b/tests/stress/fold-based-on-int32-proof.js
new file mode 100644 (file)
index 0000000..f9a2ee5
--- /dev/null
@@ -0,0 +1,14 @@
+function foo(a, b) {
+    return a + b === 2147483648;
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== false)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(1073741824, 1073741824);
+if (result !== true)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/fold-load-varargs-arity-check-fail-barely.js b/tests/stress/fold-load-varargs-arity-check-fail-barely.js
new file mode 100644 (file)
index 0000000..f1a1398
--- /dev/null
@@ -0,0 +1,28 @@
+function foo(a, b) {
+    return [a, b];
+}
+
+function bar() {
+    return foo.apply(this, arguments);
+}
+
+function baz() {
+    return bar(42);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz();
+    if (!(result instanceof Array))
+        throw "Error: result is not an array.";
+    if (result.length != 2)
+        throw "Error: result doesn't have length 4.";
+    if (result[0] != 42)
+        throw "Error: first element is not 42: " + result[0];
+    for (var j = 1; j < 2; ++j) {
+        if (result[j] !== void 0)
+            throw "Error: element " + j + " is not undefined: " + result[j];
+    }
+}
+
diff --git a/tests/stress/fold-load-varargs-arity-check-fail.js b/tests/stress/fold-load-varargs-arity-check-fail.js
new file mode 100644 (file)
index 0000000..f166f0f
--- /dev/null
@@ -0,0 +1,29 @@
+function foo(a, b, c, d) {
+    return [a, b, c, d];
+}
+
+function bar() {
+    return foo.apply(this, arguments);
+}
+
+function baz() {
+    return bar(42);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz();
+    if (!(result instanceof Array))
+        throw "Error: result is not an array.";
+    if (result.length != 4)
+        throw "Error: result doesn't have length 4.";
+    if (result[0] != 42)
+        throw "Error: first element is not 42: " + result[0];
+    for (var j = 1; j < 4; ++j) {
+        if (result[j] !== void 0)
+            throw "Error: element " + j + " is not undefined: " + result[j];
+    }
+}
+
+
diff --git a/tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js b/tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js
new file mode 100644 (file)
index 0000000..56c35a0
--- /dev/null
@@ -0,0 +1,50 @@
+function foo(o) {
+    return o.f;
+}
+
+function fu(o) {
+    return o.e;
+}
+
+function bar(f, o) {
+    return f(o);
+}
+
+function baz(f, o) {
+    return f(o);
+}
+
+for (var i = 0; i < 100; ++i) {
+    foo({f:1, e:2});
+    foo({e:1, f:2});
+    foo({d:1, e:2, f:3});
+    fu({f:1, e:2});
+    fu({e:1, f:2, g:3});
+    fu({d:1, e:2, f:3, g:4});
+}
+    
+for (var i = 0; i < 100; ++i) {
+    bar(foo, {f:1});
+    bar(function() { }, null);
+    bar(function() { return 42; }, null);
+    baz(fu, {e:1});
+    baz(function() { }, null);
+    baz(function() { return 42; }, null);
+}
+    
+(function(f, g, o, p) {
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0; i < n; ++i) {
+        var q;
+        if (i == n - 1)
+            q = p;
+        else
+            q = o;
+        result += baz(g, q);
+        result += bar(f, q);
+    }
+    if (result != (n - 1) * (o.f + o.e) + 12 + 13)
+        throw "Error: bad result: " + result;
+})(foo, fu, {f:42, e:2}, {e:12, f:13, g:14});
+
diff --git a/tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js b/tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js
new file mode 100644 (file)
index 0000000..0f3b8a1
--- /dev/null
@@ -0,0 +1,56 @@
+function foo(o) {
+    o.f = 1;
+}
+
+function fu(o) {
+    o.e = 2;
+}
+
+function bar(f, o) {
+    f(o);
+}
+
+function baz(f, o) {
+    f(o);
+}
+
+for (var i = 0; i < 100; ++i) {
+    foo({f:1, e:2});
+    foo({e:1, f:2});
+    foo({d:1, e:2, f:3});
+    fu({f:1, e:2});
+    fu({e:1, f:2, g:3});
+    fu({d:1, e:2, f:3, g:4});
+}
+    
+for (var i = 0; i < 100; ++i) {
+    bar(foo, {f:1});
+    bar(function() { }, null);
+    bar(function() { return 42; }, null);
+    baz(fu, {e:1});
+    baz(function() { }, null);
+    baz(function() { return 42; }, null);
+}
+    
+(function(f, g, o, p) {
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0; i < n; ++i) {
+        var q;
+        if (i == n - 1)
+            q = p;
+        else
+            q = o;
+        baz(g, q);
+        bar(f, q);
+    }
+    if (o.e != 2)
+        throw "Error: bad value in o.e: " + o.e;
+    if (o.f != 1)
+        throw "Error: bad value in o.f: " + o.f;
+    if (p.e != 2)
+        throw "Error: bad value in p.e: " + p.e;
+    if (p.f != 1)
+        throw "Error: bad value in p.f: " + p.f;
+})(foo, fu, {f:42, e:2}, {e:12, f:13, g:14});
+
diff --git a/tests/stress/fold-profiled-call-to-call.js b/tests/stress/fold-profiled-call-to-call.js
new file mode 100644 (file)
index 0000000..387a88c
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(f) {
+    if (DFGTrue())
+        f = bar;
+    return f().f;
+}
+
+noInline(foo);
+
+var object;
+function bar() {
+    return object;
+}
+
+function baz() { return {f:42}; };
+
+object = {f:42};
+for (var i = 0; i < 1000; ++i)
+    foo((i & 1) ? bar : baz);
+
+object = {e:1, f:2};
+var result = foo(bar);
+if (result != 2)
+    throw "Error: bad result: " + result;
+
index 6523792045f6dd3eabd349f0b9fa8794582f704b..be5b482259a852fae64bc2d00d85102b48945087 100644 (file)
@@ -1,29 +1,32 @@
 var a = new Int32Array(new ArrayBuffer(100), 4, 1);
 
 if (a.length != 1)
-    throw "Error: bad length: " + a.length;
+    throw "Error: bad length (start): " + a.length;
 if (a.byteOffset != 4)
-    throw "Error: bad offset: " + a.byteOffset;
+    throw "Error: bad offset (start): " + a.byteOffset;
 if (a.byteLength != 4)
-    throw "Error: bad byte length: " + a.byteLength;
+    throw "Error: bad byte length (start): " + a.byteLength;
 
-function foo() {
-    if (a.length != 1)
-        throw "Error: bad length: " + a.length;
-    if (a.byteOffset != 4)
-        throw "Error: bad offset: " + a.byteOffset;
-    if (a.byteLength != 4)
-        throw "Error: bad byte length: " + a.byteLength;
+function foo(when) {
+    var tmp = a.length;
+    if (tmp != 1)
+        throw "Error: bad length (" + when + "): " + tmp;
+    tmp = a.byteOffset;
+    if (tmp != 4)
+        throw "Error: bad offset (" + when + "): " + tmp;
+    tmp = a.byteLength;
+    if (tmp != 4)
+        throw "Error: bad byte length (" + when + "): " + tmp;
 }
 
 for (var i = 0; i < 1000000; ++i)
-    foo();
+    foo("loop");
 
 transferArrayBuffer(a.buffer);
 
 var didThrow = false;
 try {
-    foo();
+    foo("after transfer");
 } catch (e) {
     didThrow = true;
 }
@@ -32,8 +35,8 @@ if (!didThrow)
     throw "Should have thrown.";
 
 if (a.length != 0)
-    throw "Error: bad length: " + a.length;
+    throw "Error: bad length (end): " + a.length;
 if (a.byteOffset != 0)
-    throw "Error: bad offset: " + a.byteOffset;
+    throw "Error: bad offset (end): " + a.byteOffset;
 if (a.byteLength != 0)
-    throw "Error: bad byte length: " + a.byteLength;
+    throw "Error: bad byte length (end): " + a.byteLength;
diff --git a/tests/stress/for-in-array-mode.js b/tests/stress/for-in-array-mode.js
new file mode 100644 (file)
index 0000000..9002b94
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+var funcArgAndBodyStr =
+"(arr) {" + "\n" +
+"    var sum = 0;" + "\n" +
+"    for (var i in arr)" + "\n" +
+"        sum += arr[i];" + "\n" +
+"    return sum;" + "\n" +
+"}";
+
+var testData = {
+    "ArrayWithUndecided": { in: [], out: 0 },
+    "ArrayWithInt32": { in: [ 1, 2, 3 ], out: 6 },
+    "ArrayWithContiguous": { in: [ "a", "b", "c" ], out: "0abc" },
+    "ArrayWithDouble": { in: [10.25, 20.25, 30.25 ], out: 60.75 },
+    "ArrayWithArrayStorage": { in: [ "a", "b", "c" ], out: "0abc1000" }, // The in array will be augmented below.
+    "ArrayWithSlowPutArrayStorage": { in: [ "a", "b", "c" ], out: "0abc10" }, // the in array will be augmented below.
+
+    "NonArrayWithUndecided": { in: {}, out: 0 },
+    "NonArrayWithInt32": { in: { "0":1, "1":2, "2":3 }, out: 6 },
+    "NonArrayWithContiguous": { in: { "0":"a", "1":"b", "2":"c" }, out: "0abc" },
+    "NonArrayWithDouble": { in: { "0":10.25, "1":20.25, "2":30.25 }, out: 60.75 },
+    "NonArrayWithArrayStorage": { in: { "0":"a", "1":"b", "2":"c" }, out: "0abc1000" }, // The in obj will be augmented below.
+    "NonArrayWithSlowPutArrayStorage": { in: { "0":"a", "1":"b", "2":"c" }, out: "0abc10" }, // the in obj will be augmented below.
+};
+
+
+var o = { a: 10 };
+Object.defineProperties(o, {
+    "0": {
+        get: function() { return this.a; },
+        set: function(x) { this.a = x; },
+    },
+});
+
+testData["ArrayWithArrayStorage"].in[1000] = 1000;
+testData["ArrayWithSlowPutArrayStorage"].in.__proto__ = o;
+testData["NonArrayWithArrayStorage"].in["1000"] = 1000;
+testData["NonArrayWithSlowPutArrayStorage"].in.__proto__ = o;
+
+var numberOfFailures = 0;
+
+function test(name, data) {
+    eval("function " + name + funcArgAndBodyStr);
+    noInline(name);
+
+    var failed = false;
+    var previousResult;
+    for (var i = 0; i < 10000; ++i) {
+        var expected = data.out;
+        var actual = eval(name + "(data.in)");
+
+        if ((actual != expected) && (actual != previousResult)) {
+            print("FAIL: " + name + ": expected: " + expected + ", actual: " + actual + ", starting @ loop iteration " + i);
+            previousResult = actual;
+            failed = true;
+            numberOfFailures++;
+        }
+    }
+}
+
+for (name in testData)
+    test(name, testData[name]);
+
+if (numberOfFailures)
+    throw "Error: number of failures found: " + numberOfFailures;
diff --git a/tests/stress/for-in-base-reassigned-later-and-change-structure.js b/tests/stress/for-in-base-reassigned-later-and-change-structure.js
new file mode 100644 (file)
index 0000000..1b087d5
--- /dev/null
@@ -0,0 +1,18 @@
+function foo(o_) {
+    var o = o_;
+    var result = 0;
+    for (var s in o) {
+        result += o[s];
+        if (result >= 3)
+            o = {0:1, 1:2, b:4, a:3};
+    }
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({0:0, 1:1, a:2, b:3});
+    if (result != 7)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/for-in-base-reassigned-later.js b/tests/stress/for-in-base-reassigned-later.js
new file mode 100644 (file)
index 0000000..83115b4
--- /dev/null
@@ -0,0 +1,18 @@
+function foo(o_) {
+    var o = o_;
+    var result = 0;
+    for (var s in o) {
+        result += o[s];
+        if (result >= 3)
+            o = {0:1, 1:2, a:3, b:4};
+    }
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({0:0, 1:1, a:2, b:3});
+    if (result != 7)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/for-in-base-reassigned.js b/tests/stress/for-in-base-reassigned.js
new file mode 100644 (file)
index 0000000..09c8795
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(o_) {
+    var o = o_;
+    var result = 0;
+    for (var s in o) {
+        result += o[s];
+        o = {0:1, 1:2, a:3, b:4};
+    }
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({0:0, 1:1, a:2, b:3});
+    if (result != 9)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/for-in-capture-string-loop-var.js b/tests/stress/for-in-capture-string-loop-var.js
new file mode 100644 (file)
index 0000000..c92bf68
--- /dev/null
@@ -0,0 +1,22 @@
+(function() {
+    // Capture the loop variable and modify it inside the loop.
+    var foo = function() {
+        var captured;
+        var g = function() {
+            captured = "foo";
+        };
+        var sum = 0;
+        var o = {"foo": 1, "bar": 2};
+        for (captured in o) {
+            g();
+            sum += o[captured];
+        }
+        return sum;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() != 2)
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-delete-during-iteration.js b/tests/stress/for-in-delete-during-iteration.js
new file mode 100644 (file)
index 0000000..5ad3566
--- /dev/null
@@ -0,0 +1,69 @@
+(function() {
+    // Remove a yet-to-be-visited indexed property during iteration.
+    var foo = function() {
+        var a = [1, 2, 3, 4, 5];
+        var result = "";
+        for (var p in a) {
+            if (p == 2)
+                delete a[3];
+            result += a[p];
+        }
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "1235")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Remove a yet-to-be-visited non-indexed property during iteration.
+    var foo = function() {
+        var o = {};
+        o.x = "x";
+        o.y = "y";
+        o.z = "z";
+        var result = "";
+        for (var p in o) {
+            if (p == "x") {
+                delete o.y;
+                o.a = "a";
+            }
+            result += o[p];
+        }
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "xz")
+            throw new Error("bad result");
+    }
+})();
+(function() {
+    // Remove then re-add a property during iteration.
+    var foo = function() {
+        var A = function() {};
+        A.prototype.x = "A.x";
+        A.prototype.y = "A.y";
+        var o = new A();
+        o.z = "o.z";
+        o.y = "o.y";
+        o.x = "o.x";
+        var result = "";
+        for (var p in o) {
+            if (p == "z")
+                delete o.x;
+            if (p == "y")
+                o.x = "o.x";
+            result += o[p];
+        }
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "o.zo.yo.x")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-modify-int-loop-var.js b/tests/stress/for-in-modify-int-loop-var.js
new file mode 100644 (file)
index 0000000..82397bc
--- /dev/null
@@ -0,0 +1,21 @@
+(function() {
+    // Change integer value of the loop variable in the loop.
+    var foo = function() {
+        var a = [1, 2, 3];
+        var sum = 0;
+        for (var i in a) {
+            i += 10;
+            sum += i;
+        }
+        return sum;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        var result = foo();
+        if (typeof result !== "string")
+            throw new Error("result should have type string");
+        if (result !== "0010110210")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-modify-string-loop-var.js b/tests/stress/for-in-modify-string-loop-var.js
new file mode 100644 (file)
index 0000000..071a086
--- /dev/null
@@ -0,0 +1,19 @@
+(function() {
+    // Change string value of the loop variable in the loop.
+    var foo = function() {
+        var sum = 0;
+        var a = [1, 2, 3];
+        a.foo = 42;
+        for (var i in a) {
+            i = "foo";
+            sum += a[i];
+        }
+        return sum;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() != 42 * 4)
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-prototype.js b/tests/stress/for-in-prototype.js
new file mode 100644 (file)
index 0000000..d12a1bd
--- /dev/null
@@ -0,0 +1,57 @@
+(function() {
+    // Iterate when the base object's properties shadow properties in the prototype chain.
+    var foo = function() {
+        var A = function() { };
+        A.prototype.x = 42;
+        var o = new A();
+        o.x = 43;
+        var result = "";
+        for (var p in o)
+            result += o[p];
+        return result;
+    };
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "43")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Iterate when the prototype has the same range of indexed properties as the base object.
+    var foo = function() {
+        var A = function() {};
+        A.prototype[0] = 42;
+        var a = new A();
+        a[0] = 43;
+        var result = "";
+        for (var p in a)
+            result += a[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "43")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Iterate when the prototype has indexed properties beyond the range of the base object.
+    var foo = function() {
+        var A = function() {};
+        A.prototype[0] = 42;
+        A.prototype[1] = 3;
+        var a = new A();
+        a[0] = 43;
+        var result = "";
+        for (var p in a)
+            result += a[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "433")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-proxy-target-changed-structure.js b/tests/stress/for-in-proxy-target-changed-structure.js
new file mode 100644 (file)
index 0000000..5c9d76f
--- /dev/null
@@ -0,0 +1,32 @@
+var theO;
+
+function deleteAll() {
+    delete theO.a;
+    delete theO.b;
+    delete theO.c;
+    delete theO.d;
+    for (var i = 0; i < 10; ++i)
+        theO["i" + i] = 42;
+    theO.a = 11;
+    theO.b = 12;
+    theO.c = 13;
+    theO.d = 14;
+}
+
+function foo(o_) {
+    var o = o_;
+    var result = 0;
+    for (var s in o) {
+        result += o[s];
+        deleteAll();
+    }
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(createProxy(theO = {a:1, b:2, c:3, d:4}));
+    if (result != 1 + 12 + 13 + 14)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/for-in-proxy.js b/tests/stress/for-in-proxy.js
new file mode 100644 (file)
index 0000000..44357db
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(o_) {
+    var o = o_;
+    var result = 0;
+    for (var s in o) {
+        result += o[s];
+    }
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(createProxy({a:1, b:2, c:3, d:4}));
+    if (result != 1 + 2 + 3 + 4)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/for-in-shadow-prototype-property.js b/tests/stress/for-in-shadow-prototype-property.js
new file mode 100644 (file)
index 0000000..855ab08
--- /dev/null
@@ -0,0 +1,22 @@
+(function() {
+    // Add a property to the base object that shadows a property in the prototype during iteration.
+    var foo = function() {
+        var A = function() {};
+        A.prototype.x = "A.x";
+        A.prototype.y = "A.y";
+        var o = new A();
+        var result = "";
+        for (var p in o) {
+            if (p == "x")
+                o.y = "o.y";
+            result += o[p];
+        }
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "A.xo.y")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-string.js b/tests/stress/for-in-string.js
new file mode 100644 (file)
index 0000000..44640e6
--- /dev/null
@@ -0,0 +1,16 @@
+(function() {
+    // Iterate over characters in a string.
+    var o = "hello";
+    var foo = function(o) {
+        var result = "";
+        for (var s in o)
+            result += o[s];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo("hello") !== "hello")
+            throw new Error("incorrect result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/for-in-tests.js b/tests/stress/for-in-tests.js
new file mode 100644 (file)
index 0000000..fc6258e
--- /dev/null
@@ -0,0 +1,100 @@
+(function() {
+    // Iterate over an array with normal indexed properties.
+    var foo = function() {
+        var a = [1, 2, 3, 4, 5];
+        var sum = 0;
+        var result = "";
+        for (var p in a)
+            result += a[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "12345")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Iterate over an object with normal non-indexed properties.
+    var foo = function() {
+        var o = {};
+        o.x = 1;
+        o.y = 2;
+        o.z = 3;
+        var result = "";
+        for (var p in o)
+            result += o[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "123")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Iterate over an object with both indexed and non-indexed properties.
+    var foo = function() {
+        var o = {};
+        o.x = 1;
+        o.y = 2;
+        o.z = 3;
+        o[0] = 4;
+        o[1] = 5;
+        o[2] = 6;
+        var result = "";
+        for (var p in o)
+            result += o[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() != "456123")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    // Iterate over an array with both indexed and non-indexed properties.
+    var foo = function() {
+        var a = [4, 5, 6];
+        a.x = 1;
+        a.y = 2;
+        a.z = 3;
+        var result = "";
+        for (var p in a)
+            result += a[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "456123")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
+(function() {
+    var foo = function(a, b) {
+        for (var p in b) {
+            var f1 = a[p];
+            var f2 = b[p];
+            if (f1 === f2)
+                continue;
+            a[p] = b[p];
+        }
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        var o1 = {};
+        var o2 = {};
+        o2.x = 42;
+        o2.y = 53;
+        foo(o1, o2);
+        if (o1.x !== o2.x)
+            throw new Error("bad result: " + o1.x + "!==" + o2.x);
+        if (o1.y !== o2.y)
+            throw new Error("bad result: " + o1.y + "!==" + o2.y);
+    }
+})();
diff --git a/tests/stress/for-in-typed-array.js b/tests/stress/for-in-typed-array.js
new file mode 100644 (file)
index 0000000..08f8828
--- /dev/null
@@ -0,0 +1,18 @@
+(function() {
+    // Iterate over typed arrays.
+    var foo = function() {
+        var a = new Uint8Array(5);
+        for (var i = 0; i < a.length; ++i)
+            a[i] = i;
+        var result = "";
+        for (var p in a)
+            result += a[p];
+        return result;
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        if (foo() !== "01234")
+            throw new Error("bad result");
+    }
+    foo(null);
+})();
diff --git a/tests/stress/forward-varargs-for-inlined-escaped-arguments.js b/tests/stress/forward-varargs-for-inlined-escaped-arguments.js
new file mode 100644 (file)
index 0000000..6d2aed0
--- /dev/null
@@ -0,0 +1,21 @@
+function foo() {
+    return arguments;
+}
+
+function baz(a, b, c) {
+    return a + b + c;
+}
+
+function bar(a, b, c) {
+    var args = foo(b, c, 42);
+    return baz.apply(void 0, args);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2, 3);
+    if (result != 47)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/freeze_leek.js b/tests/stress/freeze_leek.js
new file mode 100644 (file)
index 0000000..a171e49
--- /dev/null
@@ -0,0 +1,41 @@
+var o = Object.freeze([]),
+    leak = {};
+
+try { 
+  throw o; 
+} catch (ex) {}
+
+if(o.stack !== undefined)
+    throw new Error("the stack was leaked.");
+
+o.stack = leak;
+
+if(o.stack === leak)
+    throw new Error("the object wasn't frozen.");
+
+o.other = "wrong";
+
+if(o.other === "wrong")
+    throw new Error("the object wasn't frozen.");
+
+
+o = Object.freeze({"hi": "other"});
+
+try { 
+  throw o; 
+} catch (ex) {}
+o.stack = leak;
+
+
+if(o.stack !== undefined)
+    throw new Error("the stack was leaked.");
+
+o.stack = leak;
+
+if(o.stack === leak)
+    throw new Error("the object wasn't frozen.");
+
+o.other = "wrong";
+
+if(o.other === "wrong")
+    throw new Error("the object wasn't frozen.");
index 78a1f5fc302f22bc6c67bb2dfaf2854da6f4a346..3c3ced74572adde6badd7c8b3a5bc4d82a6b7037 100644 (file)
@@ -1,3 +1,5 @@
+//@ skip if $hostOS == "windows"
+
 function foo(x) {
     return Math.cos(x);
 }
diff --git a/tests/stress/ftl-checkin-variable.js b/tests/stress/ftl-checkin-variable.js
new file mode 100644 (file)
index 0000000..275f6b4
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(l,x){
+    var t = l in x; 
+    return t;
+}
+
+noInline(foo);
+
+var r;
+for (var i = 0; i < 1000000; ++i) {
+    var z = { 'y' : i, 's' : i + 1 };
+    z.s = 10;
+    r = foo("s",z);
+}
+
+if (!r) {
+    print ("Error: " + r);
+}
diff --git a/tests/stress/ftl-checkin.js b/tests/stress/ftl-checkin.js
new file mode 100644 (file)
index 0000000..8cbde8b
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(x){
+    var t = "s" in x; 
+    return t;
+}
+
+noInline(foo);
+
+var r;
+for (var i = 0; i < 1000000; ++i) {
+    var z = { 'y' : i, 's' : i + 1 };
+    z.s = 10;
+    r = foo(z);
+}
+
+if (!r) {
+    print ("Error: " + r);
+}
diff --git a/tests/stress/ftl-getmyargumentslength-inline.js b/tests/stress/ftl-getmyargumentslength-inline.js
new file mode 100644 (file)
index 0000000..5180634
--- /dev/null
@@ -0,0 +1,9 @@
+function foo(){
+    return arguments.length;
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var r = foo(11, 12, 13, 18, 19, 20);
+    if (r != 6) throw "Error: "+r;
+}
+
diff --git a/tests/stress/ftl-in-overflow.js b/tests/stress/ftl-in-overflow.js
new file mode 100644 (file)
index 0000000..84ecd03
--- /dev/null
@@ -0,0 +1,13 @@
+function foo(o) {
+    return "foo" in o;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o["i" + i] = 42;
+    o.foo = 43;
+    foo(o);
+}
+
diff --git a/tests/stress/ftl-library-exception.js b/tests/stress/ftl-library-exception.js
new file mode 100644 (file)
index 0000000..41a9e34
--- /dev/null
@@ -0,0 +1,21 @@
+function foo(d){
+    return Date.prototype.getTimezoneOffset.call(d);
+}
+
+noInline(foo);
+
+var x;
+var count = 100000;
+var z = 0;
+for (var i = 0 ; i < count; i++){
+    try { 
+        var q = foo(i < count - 10 ? new Date() : "a");
+        x = false;
+        z = q;
+    } catch (e) {
+        x = true;
+    }
+}
+
+if (!x)
+    throw "bad result: "+ x;
diff --git a/tests/stress/ftl-library-inline-gettimezoneoffset.js b/tests/stress/ftl-library-inline-gettimezoneoffset.js
new file mode 100644 (file)
index 0000000..8df8b12
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(x, d){
+    return x + d.getTimezoneOffset();
+}
+
+noInline(foo);
+
+var d = new Date();
+var expected = foo(0, d);
+var count = 1000000;
+var result = 0;
+for (var i = 0 ; i < count; i++){
+    result += foo(0, d);
+}
+
+if (result != count * expected)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/ftl-library-inlining-exceptions-dataview.js b/tests/stress/ftl-library-inlining-exceptions-dataview.js
new file mode 100644 (file)
index 0000000..f41b9ce
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(d){
+    return d.getInt8(42);
+}
+
+noInline(foo);
+
+var d = new DataView(new ArrayBuffer(43));
+d.setInt8(42, 43);
+for (var i = 0; i < 100000; ++i) {
+    var result = foo(d);
+    if (result != 43)
+        throw "Error: bad result: " + result;
+}
+
+for (var i = 0; i < 10; ++i) {
+    var didThrow = false;
+    try {
+        foo(new DataView(new ArrayBuffer(42)));
+    } catch (e) {
+        didThrow = true;
+        if (e.message.indexOf("Out of bounds") < 0)
+            throw "Error: bad exception: " + e.message;
+    }
+    if (!didThrow)
+        throw "Error: did not throw";
+}
diff --git a/tests/stress/ftl-library-inlining-exceptions.js b/tests/stress/ftl-library-inlining-exceptions.js
new file mode 100644 (file)
index 0000000..0b6516b
--- /dev/null
@@ -0,0 +1,19 @@
+function foo(d){
+    return Date.prototype.getTimezoneOffset.call(d);
+}
+
+noInline(foo);
+
+var x;
+var count = 100000;
+for (var i = 0 ; i < count; i++){
+    try { 
+        foo(i < count - 1000 ? new Date() : "a");
+        x = false;
+    } catch (e) {
+        x = true;
+    }
+}
+
+if (!x)
+    throw "bad result: "+ x;
\ No newline at end of file
diff --git a/tests/stress/ftl-library-inlining-loops.js b/tests/stress/ftl-library-inlining-loops.js
new file mode 100644 (file)
index 0000000..160fcb9
--- /dev/null
@@ -0,0 +1,28 @@
+function foo(){
+    var count = 100;
+    var d = new DataView(new ArrayBuffer(count));
+
+    for (var i = 0; i < count / 4; i++){
+        d.setInt32(i, i);
+    }
+
+    for (var i = 0; i < count; i++){
+        d.setInt8(i, i);
+    }
+    var result = 0;
+    for (var i = 0; i < count; i++){
+        result += d.getInt8(i);
+    }
+    return result;
+}
+
+noInline(foo);
+
+var r = 0;
+for (var i = 0 ; i < 50000; i++){
+    r += foo();
+}
+
+if (r != 247500000)
+    throw "Bad result: " + r;
+
diff --git a/tests/stress/ftl-library-inlining-random.js b/tests/stress/ftl-library-inlining-random.js
new file mode 100644 (file)
index 0000000..4b67803
--- /dev/null
@@ -0,0 +1,11 @@
+function foo(x){
+    return Math.random(x);
+}
+
+noInline(foo);
+
+var x = 0;
+
+for (var i = 0 ; i < 100000; i++){
+    x = foo(i);
+}
diff --git a/tests/stress/ftl-library-substring.js b/tests/stress/ftl-library-substring.js
new file mode 100644 (file)
index 0000000..2bc0532
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(i, x){
+    return x.substring( 2 , 5);
+}
+
+noInline(foo);
+
+var x = "";
+
+for (var i = 0 ; i < 100000; i++){
+    x = foo(i, "lkajsx");
+}
+
+if (x != "ajs")
+    throw "Error: bad substring: "+ x;
+
diff --git a/tests/stress/ftl-switch-string-slow-duplicate-cases.js b/tests/stress/ftl-switch-string-slow-duplicate-cases.js
new file mode 100644 (file)
index 0000000..ec9db4c
--- /dev/null
@@ -0,0 +1,31 @@
+function foo(s) {
+    switch (s) {
+    case "ƑẦǏŁ":
+    case "ÌŅ":
+    case "ṤĻŐⱲ":
+    case "ṔÄȚĦ":
+        return 42;
+    case "due":
+    case "to":
+    case "16-bit":
+    case "strings":
+        return 43;
+    default:
+        return 44;
+    }
+}
+
+noInline(foo);
+
+function cat(a, b) {
+    return a + b;
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(cat("16-", "bit"));
+    if (result != 43)
+        throw "Error: bad result (1): " + result;
+    result = foo("ƑẦǏŁ");
+    if (result != 42)
+        throw "Error: bad result (2): " + result;
+}
diff --git a/tests/stress/function-expression-exit.js b/tests/stress/function-expression-exit.js
new file mode 100644 (file)
index 0000000..e22c479
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(x) {
+    var tmp = x + 1;
+    return function() { return 42; }
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42)();
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(42.5)();
+if (result != 42)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/function-name-scope.js b/tests/stress/function-name-scope.js
new file mode 100644 (file)
index 0000000..a93e60f
--- /dev/null
@@ -0,0 +1,40 @@
+function foo() {
+    return function bar(str) {
+        var barBefore = bar;
+        var result = eval(str);
+        return [
+            barBefore,
+            bar,
+            function () {
+                return bar;
+            },
+            result
+        ];
+    }
+}
+
+function check() {
+    var bar = foo();
+    
+    function verify(result, barAfter, evalResult) {
+        if (result[0] !== bar)
+            throw "Error: bad first entry: " + result[0];
+        if (result[1] !== barAfter)
+            throw "Error: bad first entry: " + result[1];
+        var subResult = result[2]();
+        if (subResult !== barAfter)
+            throw "Error: bad second entry: " + result[2] + "; returned: " + subResult;
+        if (result[3] !== evalResult)
+            throw "Error: bad third entry: " + result[3] + "; expected: " + evalResult;
+    }
+    
+    verify(bar("42"), bar, 42);
+    verify(bar("bar"), bar, bar);
+    verify(bar("var bar = 42; function fuzz() { return bar; }; fuzz()"), 42, 42);
+}
+
+// Execute check() more than once. At the time that we wrote this regression test, trunk would fail on
+// the second execution. Executing 100 times would also gives us some optimizing JIT coverage.
+for (var i = 0; i < 100; ++i)
+    check();
+
diff --git a/tests/stress/function-reentry-infer-on-self.js b/tests/stress/function-reentry-infer-on-self.js
new file mode 100644 (file)
index 0000000..893ce91
--- /dev/null
@@ -0,0 +1,28 @@
+function thingy(f) {
+    f();
+}
+noInline(thingy);
+
+function foo(a) {
+    var x;
+    if (a)
+        x = a;
+    thingy(function() { return x; });
+    var result = 0;
+    for (var i = 0; i < 100000; ++i)
+        result += x;
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10; ++i) {
+    var result = foo(42);
+    if (result != 4200000)
+        throw "Error: bad first result: " + result;
+}
+
+var result = foo(0);
+if ("" + result != "NaN")
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/function-sinking-no-double-allocate.js b/tests/stress/function-sinking-no-double-allocate.js
new file mode 100644 (file)
index 0000000..4f2f551
--- /dev/null
@@ -0,0 +1,28 @@
+function call(o) { o.x = 3; }
+noInline(call);
+
+function sink (p, q) {
+    var f = function () { };
+    if (p) {
+        call(f); // Force allocation of f
+        if (q) {
+            OSRExit();
+        }
+        return f;
+    }
+    return { 'x': 2 };
+}
+noInline(sink);
+
+for (var i = 0; i < 100000; ++i) {
+    var o = sink(true, false);
+    if (o.x != 3)
+        throw "Error: expected o.x to be 2 but is " + result;
+}
+
+// At this point, the function should be compiled down to the FTL
+
+// Check that the function is properly allocated on OSR exit
+var f = sink(true, true);
+if (f.x != 3)
+    throw "Error: expected o.x to be 3 but is " + result;
diff --git a/tests/stress/function-sinking-osrexit.js b/tests/stress/function-sinking-osrexit.js
new file mode 100644 (file)
index 0000000..7f33c7d
--- /dev/null
@@ -0,0 +1,21 @@
+function sink (p, q) {
+    var g = function(x) { return x; };
+    if (p) { if (q) OSRExit(); return g; }
+    return function(x) { return x; };
+}
+noInline(sink);
+
+for (var i = 0; i < 10000; ++i) {
+    var f = sink(true, false);
+    var result = f(42);
+    if (result != 42)
+    throw "Error: expected 42 but got " + result;
+}
+
+// At this point, the function should be compiled down to the FTL
+
+// Check that the function is properly allocated on OSR exit
+var f = sink(true, true);
+var result = f(42);
+if (result != 42)
+    throw "Error: expected 42 but got " + result;
diff --git a/tests/stress/function-sinking-put.js b/tests/stress/function-sinking-put.js
new file mode 100644 (file)
index 0000000..deb9e6f
--- /dev/null
@@ -0,0 +1,28 @@
+function sink (p, q) {
+    var g = function(x) { return x; };
+    if (p) { if (q) g.inner = 42; return g; }
+    return function(x) { return x; };
+}
+noInline(sink);
+
+for (var i = 0; i < 10000; ++i) {
+    var f = sink(true, true);
+    var result = f(42);
+    if (result != 42)
+    throw "Error: expected 42 but got " + result;
+}
+
+// At this point, the function should be compiled down to the FTL
+
+// Test the allocation on the implicit inner else branch
+var f = sink(true, false);
+var result = f(12);
+if (result != 12)
+    // This shouldn't matter as it should be either correct or completely crash
+    throw "Error: expected 12 but got " + result;
+
+// Check that the allocation did not sink beyond the property assignment
+var f = sink(true, true);
+var result = f.inner;
+if (result != 42)
+    throw "Error: inner should be 42 but is " + result;
diff --git a/tests/stress/get-argument-by-val-in-inlined-varargs-call-out-of-bounds.js b/tests/stress/get-argument-by-val-in-inlined-varargs-call-out-of-bounds.js
new file mode 100644 (file)
index 0000000..0f210ce
--- /dev/null
@@ -0,0 +1,31 @@
+var gi;
+
+function foo() {
+    return arguments[gi];
+}
+
+function bar(array, i) {
+    gi = i;
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+var bigArray = [];
+for (var i = 0; i < 50; ++i)
+    bigArray.push(42);
+
+for (var i = 0; i < 10000; ++i) {
+    var mi = i % 50;
+    var result = bar(bigArray, mi);
+    if (result !== 42)
+        throw "Bad result in first loop: " + result + "; expected: " + 42;
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var mi = i % 100;
+    var result = bar([42], mi);
+    var expected = mi ? void 0 : 42;
+    if (result !== expected)
+        throw "Bad result in second loop: " + result + "; expected: " + expected;
+}
diff --git a/tests/stress/get-argument-by-val-safe-in-inlined-varargs-call-out-of-bounds.js b/tests/stress/get-argument-by-val-safe-in-inlined-varargs-call-out-of-bounds.js
new file mode 100644 (file)
index 0000000..9fb3c1c
--- /dev/null
@@ -0,0 +1,35 @@
+var gi;
+
+function foo() {
+    if (!effectful42())
+        arguments = "hello";
+    return arguments[gi];
+}
+
+function bar(array, i) {
+    gi = i;
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+var bigArray = [];
+for (var i = 0; i < 50; ++i)
+    bigArray.push(42);
+
+for (var i = 0; i < 10000; ++i) {
+    var mi = i % 50;
+    var result = bar(bigArray, mi);
+    if (result !== 42)
+        throw "Bad result in first loop: " + result + "; expected: " + 42;
+}
+
+
+for (var i = 0; i < 10000; ++i) {
+    var mi = i % 100;
+    var result = bar([42], mi);
+    var expected = mi ? void 0 : 42;
+    if (result !== expected)
+        throw "Bad result in second loop: " + result + "; expected: " + expected;
+}
+
diff --git a/tests/stress/get-by-val-out-of-bounds-basics.js b/tests/stress/get-by-val-out-of-bounds-basics.js
new file mode 100644 (file)
index 0000000..0d70fd4
--- /dev/null
@@ -0,0 +1,221 @@
+// Get early out-of-bound data.
+function opaqueGetByValOnInt32ArrayEarlyOutOfBounds(array, index)
+{
+    return array[index];
+}
+noInline(opaqueGetByValOnInt32ArrayEarlyOutOfBounds);
+
+function testInt32ArrayEarlyOutOfBounds()
+{
+    // Warm up with an immediate out of bounds.
+    var int32Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    for (var i = 0; i <= 10; ++i) {
+        var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, i);
+        if ((i < 10 && value !== i) || (i >= 10 && value !== undefined))
+            throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, i) warmup with i = " + i + " value = " + value;
+    }
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e4; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j);
+            if (j < 10 && value !== j)
+                throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j) in-bounds with j = " + j + " value = " + value;
+        }
+    }
+
+    // Followed by plenty of out-of-bounds accesses.
+    for (var i = 0; i < 1e4; ++i) {
+        for (var j = 0; j <= 10; ++j) {
+            var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j);
+            if ((j < 10 && value !== j) || (j >= 10 && value !== undefined))
+                throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j) out-of-bounds with j = " + j + " value = " + value;
+        }
+    }
+}
+testInt32ArrayEarlyOutOfBounds();
+
+// One more access, with a completely different array type.
+function testIndexingTypeChangesOnInt32Array()
+{
+    var doubleArray = [-0, 5.5, -42.1];
+    var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 0);
+    if (value || 1 / value !== -Infinity)
+        throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 0)";
+    var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 1);
+    if (value !== 5.5)
+        throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 1)";
+    var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 2);
+    if (value !== -42.1)
+        throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 2)";
+}
+testIndexingTypeChangesOnInt32Array();
+
+
+
+// Get out-of-bound data after a thousand run.
+function opaqueGetByValOnStringArrayHotOutOfBounds(array, index)
+{
+    return array[index];
+}
+noInline(opaqueGetByValOnStringArrayHotOutOfBounds);
+
+function testStringArrayHotOutOfBounds()
+{
+    // Warm up with in bounds access.
+    var stringArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
+    for (var i = 0; i < 1e2; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j);
+            if (value !== "" + j)
+                throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value;
+        }
+    }
+
+    // Do a single out of bounds after warmup.
+    var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, 10);
+    if (value !== undefined)
+        throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, 10) with i = " + i + " value = " + value;
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j);
+            if (value !== "" + j)
+                throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value;
+        }
+    }
+
+    // Followed by plenty of out-of-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j <= 10; ++j) {
+            var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j);
+            if ((j < 10 && value !== "" + j) || (j >= 10 && value !== undefined))
+                throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) out-of-bounds with j = " + j + " value = " + value;
+        }
+    }
+}
+testStringArrayHotOutOfBounds();
+
+function testIndexingTypeChangesOnStringArray()
+{
+    var doubleArray = [-0, 5.5, -42.1];
+    var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 0);
+    if (value || 1 / value !== -Infinity)
+        throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 0)";
+    var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 1);
+    if (value !== 5.5)
+        throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 1)";
+    var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 2);
+    if (value !== -42.1)
+        throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 2)";
+}
+testIndexingTypeChangesOnStringArray();
+
+
+
+// Get out-of-bound data after a thousand run, but from a different array type.
+function opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(array, index)
+{
+    return array[index];
+}
+noInline(opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds);
+
+function testStringAndInt32ArrayHotOutOfBounds()
+{
+    // Warm up with in bounds access.
+    var stringArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
+    for (var i = 0; i < 1e2; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j);
+            if (value !== "" + j)
+                throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value;
+        }
+    }
+
+    // Do a single out of bounds after warmup.
+    var int32Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, 10);
+    if (value !== undefined)
+        throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, 10) with i = " + i + " value = " + value;
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j);
+            if (value !== "" + j)
+                throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value;
+
+            var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j);
+            if (value !== j)
+                throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j) in-bounds with j = " + j + " value = " + value;
+        }
+    }
+
+    // Followed by plenty of out-of-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j <= 10; ++j) {
+            var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j);
+            if ((j < 10 && value !== j) || (j >= 10 && value !== undefined))
+                throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j) out-of-bounds with j = " + j + " value = " + value;
+
+            var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j);
+            if ((j < 10 && value !== "" + j) || (j >= 10 && value !== undefined))
+                throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) out-of-bounds with j = " + j + " value = " + value;
+        }
+    }
+}
+testStringAndInt32ArrayHotOutOfBounds();
+
+
+// Get out-of-bound data from a hole after a thousand run.
+function opaqueGetByValOnDoubleArrayHotOutOfBounds(array, index)
+{
+    return array[index];
+}
+noInline(opaqueGetByValOnDoubleArrayHotOutOfBounds);
+
+function testStringArrayHotOutOfBounds()
+{
+    // Warm up with in bounds access.
+    var doubleArray = new Array(10);
+    for (var i = 0; i < 10; ++i) {
+        if (i !== 5)
+            doubleArray[i] = i + 0.5;
+    }
+    for (var i = 0; i < 1e2; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            if (j !== 5) {
+                var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j);
+                if (value !== j + 0.5)
+                    throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) in-bounds with j = " + j + " value = " + value;
+            }
+        }
+    }
+
+    // Do a single out of bounds after warmup.
+    var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, 5);
+    if (value !== undefined)
+        throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, 5) with i = " + i + " value = " + value;
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            if (j !== 5) {
+                var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j);
+                if (value !== j + 0.5)
+                    throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) in-bounds with j = " + j + " value = " + value;
+            }
+        }
+    }
+
+    // Followed by plenty of out-of-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j);
+            if ((j !== 5 && value !== j + 0.5) || (j === 10 && value !== undefined))
+                throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) out-of-bounds with j = " + j + " value = " + value;
+        }
+    }
+}
+testStringArrayHotOutOfBounds();
\ No newline at end of file
diff --git a/tests/stress/get-declared-unpassed-argument-in-direct-arguments.js b/tests/stress/get-declared-unpassed-argument-in-direct-arguments.js
new file mode 100644 (file)
index 0000000..57d380a
--- /dev/null
@@ -0,0 +1,13 @@
+function foo(a) {
+    if (!effectful42())
+        return arguments;
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== void 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js b/tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js
new file mode 100644 (file)
index 0000000..a85cd95
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(a) {
+    if (!effectful42()) {
+        (function() { a = 43; })();
+        return arguments;
+    }
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== void 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/get-local-elimination.js b/tests/stress/get-local-elimination.js
new file mode 100644 (file)
index 0000000..612f9d5
--- /dev/null
@@ -0,0 +1,15 @@
+var True = true;
+
+function foo(a) {
+    var x = a;
+    if (True)
+        return a + x;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42);
+    if (result != 84)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/get-my-argument-by-val-creates-arguments.js b/tests/stress/get-my-argument-by-val-creates-arguments.js
new file mode 100644 (file)
index 0000000..ec8c0cf
--- /dev/null
@@ -0,0 +1,42 @@
+function blah(args) {
+    var array = [];
+    for (var i = 0; i < args.length; ++i)
+        array.push(args[i]);
+    return array;
+}
+
+function foo() {
+    // Force creation of arguments by doing out-of-bounds access.
+    var tmp = arguments[42];
+    
+    // Use the created arguments object.
+    return blah(arguments);
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+noInline(blah);
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.length != b.length)
+        throw "Error: length mismatch: " + a + " versus " + b;
+    for (var i = a.length; i--;) {
+        if (a[i] != b[i])
+            throw "Error: mismatch at i = " + i + ": " + a + " versus " + b;
+    }
+}
+
+function test(array) {
+    var actual = bar(array);
+    checkEqual(actual, array);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
diff --git a/tests/stress/get-my-argument-by-val-for-inlined-escaped-arguments.js b/tests/stress/get-my-argument-by-val-for-inlined-escaped-arguments.js
new file mode 100644 (file)
index 0000000..f5bdd78
--- /dev/null
@@ -0,0 +1,18 @@
+function foo() {
+    return arguments;
+}
+
+function bar(a, b, c, i) {
+    var args = foo(b, c, 42);
+    return args[i];
+}
+
+noInline(bar);
+
+var expected = [2, 3, 42];
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2, 3, i % 3);
+    if (result != expected[i % 3])
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js b/tests/stress/get-my-argument-by-val-out-of-bounds-no-warm-up.js
new file mode 100644 (file)
index 0000000..5058e6b
--- /dev/null
@@ -0,0 +1,9 @@
+function foo(index) {
+    return arguments[index];
+}
+
+noInline(foo);
+
+var result = foo(1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-my-argument-by-val-out-of-bounds.js b/tests/stress/get-my-argument-by-val-out-of-bounds.js
new file mode 100644 (file)
index 0000000..c8ee317
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(index) {
+    return arguments[index];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo(1, 42);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-my-argument-by-val-safe-out-of-bounds.js b/tests/stress/get-my-argument-by-val-safe-out-of-bounds.js
new file mode 100644 (file)
index 0000000..3737db6
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(index) {
+    if (index > 1000)
+        arguments = [1, 2, 3];
+    return arguments[index];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo(1, 42);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-my-argument-by-val-safe-wrap-around.js b/tests/stress/get-my-argument-by-val-safe-wrap-around.js
new file mode 100644 (file)
index 0000000..4a7e3f8
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(index) {
+    if (index > 1000)
+        arguments = [1, 2, 3];
+    return arguments[index];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo(1, 42);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(-1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js b/tests/stress/get-my-argument-by-val-wrap-around-no-warm-up.js
new file mode 100644 (file)
index 0000000..a6a1657
--- /dev/null
@@ -0,0 +1,9 @@
+function foo(index) {
+    return arguments[index];
+}
+
+noInline(foo);
+
+var result = foo(-1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-my-argument-by-val-wrap-around.js b/tests/stress/get-my-argument-by-val-wrap-around.js
new file mode 100644 (file)
index 0000000..770b451
--- /dev/null
@@ -0,0 +1,15 @@
+function foo(index) {
+    return arguments[index];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo(1, 42);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(-1);
+if (result !== void 0)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/get-stack-identity-due-to-sinking.js b/tests/stress/get-stack-identity-due-to-sinking.js
new file mode 100644 (file)
index 0000000..7f74135
--- /dev/null
@@ -0,0 +1,18 @@
+function foo(p, a) {
+    if (p) {
+        var tmp = arguments;
+    }
+    return a;
+}
+
+function bar(p, a) {
+    return foo(p, a);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(false, 42);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/get-stack-mapping-with-dead-get-stack.js b/tests/stress/get-stack-mapping-with-dead-get-stack.js
new file mode 100644 (file)
index 0000000..e158ccb
--- /dev/null
@@ -0,0 +1,27 @@
+function bar() {
+    if (foo.arguments[0] === void 0)
+        throw "Error: foo.arguments[0] should not be undefined but is."
+}
+
+noInline(bar);
+
+function foo(a, p) {
+    var tmp = a;
+    effectful42();
+    for (var i = 0; i < 10; ++i) {
+        bar();
+        a = i;
+    }
+    if (p) {
+        var tmp = arguments;
+    }
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(0, false);
+    if (result != 9)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/get-stack-mapping.js b/tests/stress/get-stack-mapping.js
new file mode 100644 (file)
index 0000000..c62f0de
--- /dev/null
@@ -0,0 +1,26 @@
+function bar() {
+    if (foo.arguments[0] === void 0)
+        throw "Error: foo.arguments[0] should not be undefined but is."
+}
+
+noInline(bar);
+
+function foo(a, p) {
+    effectful42();
+    for (var i = 0; i < 10; ++i) {
+        bar();
+        a = i;
+    }
+    if (p) {
+        var tmp = arguments;
+    }
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(0, false);
+    if (result != 9)
+        throw "Error: bad result: " + result;
+}
diff --git a/tests/stress/global-environment-does-not-trap-unscopables.js b/tests/stress/global-environment-does-not-trap-unscopables.js
new file mode 100644 (file)
index 0000000..de96608
--- /dev/null
@@ -0,0 +1,19 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var global = new Function('return this')();
+var Cocoa = 'Cocoa';
+
+global[Symbol.unscopables] = {
+    Cocoa: true
+};
+
+test(Cocoa, "Cocoa");
+(function () {
+    var Cocoa = 'local'
+    with (global) {
+        test(Cocoa, "local");
+    }
+}());
diff --git a/tests/stress/goofy-function-reentry-incorrect-inference.js b/tests/stress/goofy-function-reentry-incorrect-inference.js
new file mode 100644 (file)
index 0000000..a371347
--- /dev/null
@@ -0,0 +1,25 @@
+function foo(a) {
+    var x;
+    if (a)
+        x = a;
+    return [function() {
+        return x;
+    }, function(a) {
+        x = a;
+    }];
+}
+
+var array = foo(false);
+noInline(array[0]);
+noInline(array[1]);
+array[1](42);
+for (var i = 0; i < 10000; ++i) {
+    var result = array[0]();
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+array[1](43);
+var result = array[0]();
+if (result != 43)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/has-custom-properties.js b/tests/stress/has-custom-properties.js
new file mode 100644 (file)
index 0000000..55775ba
--- /dev/null
@@ -0,0 +1,13 @@
+(function() {
+    for (var i = 0; i < 10000; ++i) {
+        var o = {};
+        
+        if (hasCustomProperties(o))
+            throw "Error: object shouldn't have custom properties yet.";
+        
+        o.f = 42;
+        
+        if (!hasCustomProperties(o))
+            throw "Error: object should have custom properties already.";
+    }
+})();
diff --git a/tests/stress/infer-constant-global-property.js b/tests/stress/infer-constant-global-property.js
new file mode 100644 (file)
index 0000000..cc9dbee
--- /dev/null
@@ -0,0 +1,18 @@
+function foo(p) {
+    if (p)
+        Math = {sin: function() { return 42; }, PI: 43, abs: Math.abs};
+}
+
+noInline(foo);
+
+(function() {
+    var n = 100000;
+    var m = 100;
+    var result = 0;
+    for (var i = 0; i < n; ++i) {
+        foo(i == n - m);
+        result += Math.sin(Math.PI);
+    }
+    if (Math.abs(result - m * 42) > 1e-8)
+        throw "Error: bad result: " + result;
+})();
diff --git a/tests/stress/infer-constant-property.js b/tests/stress/infer-constant-property.js
new file mode 100644 (file)
index 0000000..605ae3d
--- /dev/null
@@ -0,0 +1,22 @@
+var o = {f:{f:{f:{f:{f:{f:{f:42}}}}}}};
+
+function foo(p) {
+    if (p)
+        o.f.f.f.f.f.f = {f:53};
+}
+
+noInline(foo);
+
+(function() {
+    var n = 100000;
+    var m = 100;
+    var result = 0;
+    
+    for (var i = 0; i < n; ++i) {
+        foo(i == n - m);
+        result += o.f.f.f.f.f.f.f;
+    }
+    
+    if (result != (n - m) * 42 + m * 53)
+        throw "Error: bad result: " + result;
+})();
diff --git a/tests/stress/infer-uninitialized-closure-var.js b/tests/stress/infer-uninitialized-closure-var.js
new file mode 100644 (file)
index 0000000..aa64af4
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(p) {
+    var x;
+    
+    noInline(f);
+    
+    if (p) {
+        var f = function() { return x; }
+        
+        foo(false);
+        
+        for (var i = 0; i < 10000; ++i) {
+            var result = f();
+            if (result !== void 0)
+                throw "Error: bad result (1): " + result;
+        }
+        
+        x = 43;
+        
+        var result = f();
+        if (result != 43)
+            throw "Error: bad result (2): " + result;
+    } else
+        x = 42;
+}
+
+foo(true);
diff --git a/tests/stress/initialize_functions_after_arguments.js b/tests/stress/initialize_functions_after_arguments.js
new file mode 100644 (file)
index 0000000..6498a66
--- /dev/null
@@ -0,0 +1,8 @@
+(function (Thing){
+    function Thing() {
+    }
+    function other() {
+        Thing;
+    }
+    Thing();
+})(2)
diff --git a/tests/stress/inline-call-that-doesnt-use-all-args.js b/tests/stress/inline-call-that-doesnt-use-all-args.js
new file mode 100644 (file)
index 0000000..afbb790
--- /dev/null
@@ -0,0 +1,27 @@
+function foo(a, b, c) {
+    return 42;
+}
+
+function bar(a, b, c) {
+    return a + b + c;
+}
+
+function baz(f, o) {
+    return f(o[0], o[1], o[2]);
+}
+
+noInline(baz);
+
+var o = new Float32Array(3);
+o[0] = 1;
+o[1] = 2;
+o[2] = 3;
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(foo, o);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = baz(bar, o);
+if (result != 6)
+    throw "Error: bad result in loop: " + result;
diff --git a/tests/stress/inline-varargs-get-arguments.js b/tests/stress/inline-varargs-get-arguments.js
new file mode 100644 (file)
index 0000000..041dd69
--- /dev/null
@@ -0,0 +1,23 @@
+function foo(f, array) {
+    return f.apply(this, array);
+}
+
+function bar(a, b, c) {
+    return baz();
+}
+
+function baz() {
+    return bar.arguments[3];
+}
+
+noInline(foo);
+noInline(baz);
+
+var array = [0, 0, 0, 42];
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(bar, array);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/int32array-transition-on-nan.js b/tests/stress/int32array-transition-on-nan.js
new file mode 100644 (file)
index 0000000..5db2a66
--- /dev/null
@@ -0,0 +1,88 @@
+function insertNaNWhileFilling()
+{
+    var array = new Array(6);
+    for (var i = 0; i < 4; ++i)
+        array[i] = i;
+    array[5] = NaN;
+    return array;
+}
+noInline(insertNaNWhileFilling);
+
+function testInsertNaNWhileFilling()
+{
+    var array = insertNaNWhileFilling();
+    for (var i = 0; i < 4; ++i) {
+        var value = array[i];
+        if (value !== i) {
+            throw "Failed testInsertNaNWhileFilling, value = " + value + " instead of " + i;
+        }
+    }
+    var nan = array[5];
+    if (!Number.isNaN(nan))
+        throw "Failed testInsertNaNWhileFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testInsertNaNWhileFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+    testInsertNaNWhileFilling();
+}
+
+
+function insertNaNAfterFilling()
+{
+    var array = new Array(6);
+    for (var i = 0; i < 5; ++i)
+        array[i] = i;
+    array[5] = NaN;
+    return array;
+}
+noInline(insertNaNAfterFilling);
+
+function testInsertNaNAfterFilling()
+{
+    var array = insertNaNAfterFilling();
+    for (var i = 0; i < 4; ++i) {
+        var value = array[i];
+        if (value !== i) {
+            throw "Failed testInsertNaNAfterFilling, value = " + value + " instead of " + i;
+        }
+    }
+    var nan = array[5];
+    if (!Number.isNaN(nan))
+        throw "Failed testInsertNaNAfterFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testInsertNaNAfterFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+    testInsertNaNAfterFilling();
+}
+
+
+function pushNaNWhileFilling()
+{
+    var array = [];
+    for (var i = 0; i < 5; ++i)
+        array.push(i);
+    array.push(NaN);
+    return array;
+}
+noInline(pushNaNWhileFilling);
+
+function testPushNaNWhileFilling()
+{
+    var array = pushNaNWhileFilling();
+    for (var i = 0; i < 4; ++i) {
+        var value = array[i];
+        if (value !== i) {
+            throw "Failed testPushNaNWhileFilling, value = " + value + " instead of " + i;
+        }
+    }
+    var nan = array[5];
+    if (!Number.isNaN(nan))
+        throw "Failed testPushNaNWhileFilling, array[5] is " + nan + " instead of NaN";
+}
+noInline(testPushNaNWhileFilling);
+
+for (var i = 0; i < 1e4; ++i) {
+    testPushNaNWhileFilling();
+}
\ No newline at end of file
diff --git a/tests/stress/iterator-functions.js b/tests/stress/iterator-functions.js
new file mode 100644 (file)
index 0000000..12edb6e
--- /dev/null
@@ -0,0 +1,33 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+test(Array.prototype[Symbol.iterator], Array.prototype.values);
+test(Map.prototype[Symbol.iterator], Map.prototype.entries);
+test(Set.prototype[Symbol.iterator], Set.prototype.values);
+
+function argumentsTests(values) {
+    test(function () {
+        return arguments[Symbol.iterator];
+    }(), values);
+
+    test(function (a, b, c) {
+        return arguments[Symbol.iterator];
+    }(), values);
+
+    test(function () {
+        'use strict';
+        return arguments[Symbol.iterator];
+    }(), values);
+
+    test(function (a, b, c) {
+        'use strict';
+        return arguments[Symbol.iterator];
+    }(), values);
+}
+
+argumentsTests(Array.prototype.values);
+var arrayValues = Array.prototype.values;
+Array.prototype.values = null;
+argumentsTests(arrayValues);
diff --git a/tests/stress/iterator-names.js b/tests/stress/iterator-names.js
new file mode 100644 (file)
index 0000000..5fe8ab4
--- /dev/null
@@ -0,0 +1,35 @@
+function test(object, name) {
+    return {
+        object,
+        name: '[object ' + name + ']'
+    };
+}
+
+function iter(object) {
+    return object[Symbol.iterator]();
+}
+
+var tests = [
+    test(iter([]), "Array Iterator"),
+    test(iter(new Array), "Array Iterator"),
+    test([].keys(), "Array Iterator"),
+    test([].entries(), "Array Iterator"),
+    test(iter(new Map), "Map Iterator"),
+    test((new Map()).keys(), "Map Iterator"),
+    test((new Map()).entries(), "Map Iterator"),
+    test(iter(new Set), "Set Iterator"),
+    test((new Set()).keys(), "Set Iterator"),
+    test((new Set()).entries(), "Set Iterator"),
+    test(iter(new String("")), "String Iterator"),
+    test(iter(""), "String Iterator"),
+];
+
+function check(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+for (var { object, name } of tests) {
+    check(object.toString(), name);
+    check(Object.prototype.toString.call(object), name);
+}
diff --git a/tests/stress/iterator-prototype.js b/tests/stress/iterator-prototype.js
new file mode 100644 (file)
index 0000000..c5f939b
--- /dev/null
@@ -0,0 +1,53 @@
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var iteratorPrototype = "Cocoa"[Symbol.iterator]().__proto__.__proto__;
+
+shouldBe(iteratorPrototype !== Object.prototype, true);
+shouldBe(iteratorPrototype.__proto__, Object.prototype);
+shouldBe(JSON.stringify(Object.getOwnPropertyNames(iteratorPrototype)), '[]');
+shouldBe(Object.getOwnPropertySymbols(iteratorPrototype).length, 1);
+shouldBe(Object.getOwnPropertySymbols(iteratorPrototype)[0], Symbol.iterator);
+shouldBe(iteratorPrototype[Symbol.iterator](), iteratorPrototype);
+var stringIterator = "Hello"[Symbol.iterator]();
+shouldBe(iteratorPrototype[Symbol.iterator].call(stringIterator), stringIterator);
+
+function inheritIteratorPrototype(iterator)
+{
+    var prototype = iterator.__proto__;
+    shouldBe(prototype !== iteratorPrototype, true);
+    shouldBe(Object.getOwnPropertyDescriptor(prototype, 'constructor'), undefined);
+    shouldBe(prototype.__proto__, iteratorPrototype);
+    shouldBe(iteratorPrototype[Symbol.iterator].name, '[Symbol.iterator]');
+    shouldBe(iteratorPrototype.hasOwnProperty(Symbol.iterator), true);
+}
+
+inheritIteratorPrototype("Cappuccino"[Symbol.iterator]());
+inheritIteratorPrototype(new Map()[Symbol.iterator]());
+inheritIteratorPrototype(new Set()[Symbol.iterator]());
+inheritIteratorPrototype(new Array()[Symbol.iterator]());
+inheritIteratorPrototype((function (a, b, c) { return arguments; }(0, 1, 2))[Symbol.iterator]());
+inheritIteratorPrototype((function (a, b, c) { 'use strict'; return arguments; }(0, 1, 2))[Symbol.iterator]());
+
+function testChain(iterable)
+{
+    // Iterator instance
+    var iterator = iterable[Symbol.iterator]();
+    // %MapIteratorPrototype%
+    var proto1 = Object.getPrototypeOf(iterator);
+    // %IteratorPrototype%
+    var proto2 = Object.getPrototypeOf(proto1);
+
+    shouldBe(proto2.hasOwnProperty(Symbol.iterator), true);
+    shouldBe(proto1.hasOwnProperty(Symbol.iterator), false);
+    shouldBe(iterator.hasOwnProperty(Symbol.iterator), false);
+    shouldBe(iterator[Symbol.iterator](), iterator);
+}
+
+testChain("Cocoa");
+testChain(new Map());
+testChain(new Set());
+testChain(new Array());
diff --git a/tests/stress/iterator-return-beyond-multiple-iteration-scopes.js b/tests/stress/iterator-return-beyond-multiple-iteration-scopes.js
new file mode 100644 (file)
index 0000000..df4a4fe
--- /dev/null
@@ -0,0 +1,172 @@
+
+function createIterator(callback) {
+    var array = [0,1,2,3,4,5];
+    var iterator = array[Symbol.iterator]();
+    iterator.return = function () {
+        ++iterator.returned;
+        if (callback)
+            return callback(this);
+        return { done: true, value: undefined };
+    };
+    iterator.returned = 0;
+    return iterator;
+}
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            break outer;
+        }
+    }
+    if (innerIterator.returned !== 1)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 1)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            break inner;
+        }
+    }
+    if (innerIterator.returned !== 6)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            break;
+        }
+    }
+    if (innerIterator.returned !== 6)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            break;
+        }
+    }
+    if (innerIterator.returned !== 6)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            continue;
+        }
+    }
+    if (innerIterator.returned !== 0)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            continue inner;
+        }
+    }
+    if (innerIterator.returned !== 0)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    outer: for (var e1 of outerIterator) {
+        inner: for (var e2 of innerIterator) {
+            continue outer;
+        }
+    }
+    if (innerIterator.returned !== 6)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 0)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    (function () {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+                return;
+            }
+        }
+    }());
+    if (innerIterator.returned !== 1)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 1)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    (function () {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+            }
+            return;
+        }
+    }());
+    if (innerIterator.returned !== 0)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (outerIterator.returned !== 1)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+
+(function test() {
+    function raiseError() {
+        throw new Error("Cocoa");
+    }
+    var outerIterator = createIterator();
+    var innerIterator = createIterator();
+    (function () {
+        var error = null;
+        try {
+            outer: for (var e1 of outerIterator) {
+                inner: for (var e2 of innerIterator) {
+                    raiseError();
+                }
+            }
+        } catch (e) {
+            error = e;
+        }
+        if (innerIterator.returned !== 1)
+            throw new Error("bad value: " + innerIterator.returned);
+        if (outerIterator.returned !== 1)
+            throw new Error("bad value: " + outerIterator.returned);
+        if (!error)
+            throw new Error("not thrown");
+        if (String(error) !== "Error: Cocoa")
+            throw new Error("bad error: " + String(error));
+    }());
+}());
diff --git a/tests/stress/iterators-shape.js b/tests/stress/iterators-shape.js
new file mode 100644 (file)
index 0000000..f2718b2
--- /dev/null
@@ -0,0 +1,63 @@
+// This test checks the shape of builtin iterators.
+
+function iteratorShape(iter) {
+    if (iter.hasOwnProperty('next'))
+        throw "Error: iterator should not have next method.";
+    if (!iter.__proto__.hasOwnProperty('next'))
+        throw "Error: iterator prototype should have next method.";
+    if (typeof iter.__proto__.next !== "function")
+        throw "Error: iterator prototype should have next method.";
+}
+
+function sameNextMethods(iterators) {
+    var iterator = iterators[0];
+    for (var i = 1; i < iterators.length; ++i) {
+        if (iterator.next !== iterators[i].next)
+            throw "Error: next method is not the same.";
+    }
+}
+
+var array = ['Cocoa', 'Cappuccino', 'The des Alizes', 'Matcha', 'Kilimanjaro'];
+var iterator = array[Symbol.iterator]();
+iteratorShape(iterator);
+
+var keyIterator = array.keys();
+iteratorShape(keyIterator);
+
+var keyValueIterator = array.entries();
+iteratorShape(keyValueIterator);
+
+sameNextMethods([array[Symbol.iterator](), array.keys(), array.entries()]);
+
+var set = new Set(['Cocoa', 'Cappuccino', 'The des Alizes', 'Matcha', 'Kilimanjaro']);
+var iterator = set[Symbol.iterator]();
+iteratorShape(iterator);
+
+var keyIterator = set.keys();
+iteratorShape(keyIterator);
+
+var keyValueIterator = set.entries();
+iteratorShape(keyValueIterator);
+
+sameNextMethods([set[Symbol.iterator](), set.keys(), set.entries()]);
+
+var map = new Map();
+[
+    [ 'Cocoa', 2, ],
+    [ 'Cappuccino', 0 ],
+    [ 'The des Alizes', 3 ],
+    [ 'Matcha', 2 ],
+    [ 'Kilimanjaro', 1]
+].forEach(function ([ key, value ]) {
+    map.set(key, value);
+});
+var iterator = map[Symbol.iterator]();
+iteratorShape(iterator);
+
+var keyIterator = map.keys();
+iteratorShape(keyIterator);
+
+var keyValueIterator = map.entries();
+iteratorShape(keyValueIterator);
+
+sameNextMethods([map[Symbol.iterator](), map.keys(), map.entries()]);
diff --git a/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js b/tests/stress/jit-cache-poly-replace-then-cache-get-and-fold-then-invalidate.js
new file mode 100644 (file)
index 0000000..3d488a5
--- /dev/null
@@ -0,0 +1,33 @@
+var o = {f:42};
+
+function foo(p, o, v) {
+    if (p)
+        o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10; ++i)
+    foo(false);
+
+for (var i = 0; i < 10; ++i)
+    foo(true, {}, 42);
+
+for (var i = 0; i < 10; ++i)
+    foo(true, o, 42);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+foo(true, o, 53);
+var result = bar();
+if (result != 53)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js b/tests/stress/jit-cache-replace-then-cache-get-and-fold-then-invalidate.js
new file mode 100644 (file)
index 0000000..ccbdfd9
--- /dev/null
@@ -0,0 +1,30 @@
+var o = {f:42};
+
+function foo(p, v) {
+    if (p)
+        o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10; ++i)
+    foo(false);
+
+for (var i = 0; i < 10; ++i)
+    foo(true, 42);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+foo(true, 53);
+var result = bar();
+if (result != 53)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js b/tests/stress/jit-put-to-scope-global-cache-watchpoint-invalidate.js
new file mode 100644 (file)
index 0000000..2dd0969
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(p, v) {
+    if (p)
+        global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10; ++i)
+    foo(false);
+
+var value = 42;
+foo(true, value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i < n; ++i) {
+    if (i == n - m)
+        foo(true, value = 53);
+    var result = bar();
+    if (result != value)
+        throw "Error: on iteration " + i + " got: " + result;
+}
diff --git a/tests/stress/liveness-pruning-needed-for-osr-availability-eager.js b/tests/stress/liveness-pruning-needed-for-osr-availability-eager.js
new file mode 100644 (file)
index 0000000..e6078b5
--- /dev/null
@@ -0,0 +1,16 @@
+// Note that this only fails in eager compilation.
+
+function each(ary, func) {
+    if (ary)
+        for (var i = 0; i < ary.length && (!ary[i] ||!func(ary[i], i, ary)); i += 1);
+}
+
+var blah = function () {
+    var func = function() {
+        return (function () { }).apply(Object, arguments);
+    };
+    each([ {}, {} ], func);
+};
+
+for (var i = 0; i < 1000; i++)
+    blah();
diff --git a/tests/stress/liveness-pruning-needed-for-osr-availability.js b/tests/stress/liveness-pruning-needed-for-osr-availability.js
new file mode 100644 (file)
index 0000000..bd2538b
--- /dev/null
@@ -0,0 +1,15 @@
+function each(ary, func) {
+    for (var i = 0; i < ary.length && (!ary[i] ||!func(ary[i], i, ary)); i += 1);
+}
+
+function foo() {
+    each(
+        [ {}, {} ],
+        function () {
+            return (function (x) { })(arguments);
+        });
+};
+noInline(foo);
+
+for (var i = 0; i < 100000; i++)
+    foo();
diff --git a/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js b/tests/stress/llint-cache-replace-then-cache-get-and-fold-then-invalidate.js
new file mode 100644 (file)
index 0000000..c288482
--- /dev/null
@@ -0,0 +1,26 @@
+var o = {f:42};
+
+function foo(v) {
+    o.f = v;
+}
+
+function bar() {
+    return o.f;
+}
+
+noInline(foo);
+noInline(bar);
+
+foo(42);
+foo(42);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar();
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+foo(53);
+var result = bar();
+if (result != 53)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js b/tests/stress/llint-put-to-scope-global-cache-watchpoint-invalidate.js
new file mode 100644 (file)
index 0000000..35fe10a
--- /dev/null
@@ -0,0 +1,22 @@
+function foo(v) {
+    global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+var value = 42;
+foo(value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i < n; ++i) {
+    if (i == n - m)
+        foo(value = 53);
+    var result = bar();
+    if (result != value)
+        throw "Error: on iteration " + i + " got: " + result;
+}
diff --git a/tests/stress/load-varargs-elimination-bounds-check-barely.js b/tests/stress/load-varargs-elimination-bounds-check-barely.js
new file mode 100644 (file)
index 0000000..83c1328
--- /dev/null
@@ -0,0 +1,35 @@
+function foo() {
+    var result = 0;
+    for (var i = 0; i < arguments.length; ++i)
+        result += arguments[i];
+    return result;
+}
+
+function bar() {
+    return foo.apply(this, arguments);
+}
+
+function baz(p) {
+    if (p)
+        return bar(1, 42);
+    return 0;
+}
+
+noInline(baz);
+
+// Execute baz() once with p set, so that the call has a valid prediction.
+baz(true);
+
+// Warm up profiling in bar and foo. Convince this profiling that bar()'s varargs call will tend to
+// pass a small number of arguments;
+for (var i = 0; i < 1000; ++i)
+    bar(1);
+
+// Now compile baz(), but don't run the bad code yet.
+for (var i = 0; i < 10000; ++i)
+    baz(false);
+
+// Finally, trigger the bug.
+var result = baz(true);
+if (result != 43)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/load-varargs-elimination-bounds-check.js b/tests/stress/load-varargs-elimination-bounds-check.js
new file mode 100644 (file)
index 0000000..0fd3907
--- /dev/null
@@ -0,0 +1,35 @@
+function foo() {
+    var result = 0;
+    for (var i = 0; i < arguments.length; ++i)
+        result += arguments[i];
+    return result;
+}
+
+function bar() {
+    return foo.apply(this, arguments);
+}
+
+function baz(p) {
+    if (p)
+        return bar(1, 2, 3, 4);
+    return 0;
+}
+
+noInline(baz);
+
+// Execute baz() once with p set, so that the call has a valid prediction.
+baz(true);
+
+// Warm up profiling in bar and foo. Convince this profiling that bar()'s varargs call will tend to
+// pass a small number of arguments;
+for (var i = 0; i < 1000; ++i)
+    bar(1);
+
+// Now compile baz(), but don't run the bad code yet.
+for (var i = 0; i < 10000; ++i)
+    baz(false);
+
+// Finally, trigger the bug.
+var result = baz(true);
+if (result != 10)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/load-varargs-then-inlined-call-and-exit-strict.js b/tests/stress/load-varargs-then-inlined-call-and-exit-strict.js
new file mode 100644 (file)
index 0000000..3618f8c
--- /dev/null
@@ -0,0 +1,43 @@
+"use strict";
+
+function foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    return {a:a + 1, b:b, c:array};
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0] + 1, b:array[1], c:array};
+    var actual = bar(array);
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < 1 + (i % 5); ++j)
+        array.push(j);
+    test(array);
+}
+
+var array = [2147483647];
+test(array);
diff --git a/tests/stress/load-varargs-then-inlined-call-and-exit.js b/tests/stress/load-varargs-then-inlined-call-and-exit.js
new file mode 100644 (file)
index 0000000..c378171
--- /dev/null
@@ -0,0 +1,41 @@
+function foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    return {a:a + 1, b:b, c:array};
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0] + 1, b:array[1], c:array};
+    var actual = bar(array);
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < 1 + (i % 5); ++j)
+        array.push(j);
+    test(array);
+}
+
+var array = [2147483647];
+test(array);
diff --git a/tests/stress/load-varargs-then-inlined-call-exit-in-foo.js b/tests/stress/load-varargs-then-inlined-call-exit-in-foo.js
new file mode 100644 (file)
index 0000000..ecb227c
--- /dev/null
@@ -0,0 +1,46 @@
+function foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i] + 1);
+    return {a:a, b:b, c:array};
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0], b:array[1], c:array.map(function(value) { return value + 1 })};
+    var actual = bar(array);
+    checkEqual(actual, expected);
+}
+
+// This is pretty dumb. We need to first make sure that the VM is prepared for double arrays being
+// created.
+var array = [];
+array.push(42);
+array.push(42.5);
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
+test([1.5, 2.5, 3.5]);
diff --git a/tests/stress/load-varargs-then-inlined-call-inlined.js b/tests/stress/load-varargs-then-inlined-call-inlined.js
new file mode 100644 (file)
index 0000000..56d0526
--- /dev/null
@@ -0,0 +1,43 @@
+function foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    return {a:a, b:b, c:array};
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+function baz(array) {
+    return bar(array);
+}
+
+noInline(baz);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0], b:array[1], c:array};
+    var actual = baz(array);
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
diff --git a/tests/stress/load-varargs-then-inlined-call.js b/tests/stress/load-varargs-then-inlined-call.js
new file mode 100644 (file)
index 0000000..45e3ea1
--- /dev/null
@@ -0,0 +1,39 @@
+function foo(a, b) {
+    var array = [];
+    for (var i = 0; i < arguments.length; ++i)
+        array.push(arguments[i]);
+    return {a:a, b:b, c:array};
+}
+
+function bar(array) {
+    return foo.apply(this, array);
+}
+
+noInline(bar);
+
+function checkEqual(a, b) {
+    if (a.a != b.a)
+        throw "Error: bad value of a: " + a.a + " versus " + b.a;
+    if (a.b != b.b)
+        throw "Error: bad value of b: " + a.b + " versus " + b.b;
+    if (a.c.length != b.c.length)
+        throw "Error: bad value of c, length mismatch: " + a.c + " versus " + b.c;
+    for (var i = a.c.length; i--;) {
+        if (a.c[i] != b.c[i])
+            throw "Error: bad value of c, mismatch at i = " + i + ": " + a.c + " versus " + b.c;
+    }
+}
+
+function test(array) {
+    var expected = {a:array[0], b:array[1], c:array};
+    var actual = bar(array);
+    checkEqual(actual, expected);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var array = [];
+    for (var j = 0; j < i % 6; ++j)
+        array.push(j);
+    test(array);
+}
+
diff --git a/tests/stress/logical-not-masquerades.js b/tests/stress/logical-not-masquerades.js
new file mode 100644 (file)
index 0000000..0fd59ba
--- /dev/null
@@ -0,0 +1,33 @@
+function foo(value) {
+    return !!value;
+}
+
+noInline(foo);
+
+var tests = [
+    [0, false],
+    [1, true],
+    [0/0, false],
+    [0/-1, false],
+    [0.0, false],
+    ["", false],
+    ["f", true],
+    ["hello", true],
+    [{}, true],
+    [[], true],
+    [null, false],
+    [void 0, false],
+    [false, false],
+    [true, true],
+    [makeMasquerader(), false]
+];
+
+for (var i = 0; i < 10000; ++i) {
+    for (var j = 0; j < tests.length; ++j) {
+        var input = tests[j][0];
+        var expected = tests[j][1];
+        var result = foo(input);
+        if (result !== expected)
+            throw "Error: bad result for " + input + ": " + result;
+    }
+}
diff --git a/tests/stress/many-sunken-locals.js b/tests/stress/many-sunken-locals.js
new file mode 100644 (file)
index 0000000..b50aee2
--- /dev/null
@@ -0,0 +1,27 @@
+function foo(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
+    if (a)
+        return 42;
+    else
+        return 63;
+}
+
+function bar(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
+    return foo(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
+}
+
+function baz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
+    return bar(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
+}
+
+function fuzz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
+    return baz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
+}
+
+function buzz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
+    return fuzz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
+}
+
+noInline(buzz);
+
+for (var i = 0; i < 10000; ++i)
+    buzz(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26);
diff --git a/tests/stress/map-constructor-adder.js b/tests/stress/map-constructor-adder.js
new file mode 100644 (file)
index 0000000..e788264
--- /dev/null
@@ -0,0 +1,46 @@
+// Map constructor with adder change.
+
+var originalAdder = Map.prototype.set;
+var counter = 0;
+
+Map.prototype.set = function (key, value) {
+    counter++;
+    return originalAdder.call(this, key, value);
+};
+
+var values = [
+    [ 0, 0 ],
+    [ 1, 1 ],
+    [ 2, 2 ],
+    [ 3, 3 ],
+    [ 4, 4 ],
+    [ 5, 5 ],
+    [ 4, 4 ],
+    [ 3, 3 ],
+    [ 2, 2 ],
+    [ 1, 1 ],
+    [ 0, 0 ],
+];
+var map = new Map(values);
+if (map.size !== 6)
+    throw "Error: bad map size " + map.size;
+if (counter !== values.length)
+    throw "Error: bad counter " + counter;
+
+Map.prototype.set = function () {
+    throw new Error("adder called");
+};
+
+var map = new Map();
+var map = new Map([]);
+var error = null;
+try {
+    var map = new Map([ [0, 0] ]);
+} catch (e) {
+    error = e;
+}
+if (!error)
+    throw "Error: error not thrown";
+if (String(error) !== "Error: adder called")
+    throw "Error: bad error " + String(error);
+
diff --git a/tests/stress/map-constructor.js b/tests/stress/map-constructor.js
new file mode 100644 (file)
index 0000000..d932820
--- /dev/null
@@ -0,0 +1,133 @@
+// Map constructor behaviors.
+
+if (typeof Map !== 'function')
+    throw "Error: bad value" + typeof Map;
+
+function testCallTypeError(item) {
+    var error = null;
+    try {
+        var map = Map(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (String(error) !== "TypeError: Map cannot be called as a function")
+        throw "Error: bad error " + String(error);
+}
+
+var pass = [
+    [ null, 0 ],
+    [ undefined, 0 ],
+    [ [], 0 ],
+    [ new Set(), 0],
+    [ new Map(), 0],
+    [ "", 0],
+
+    [
+        [
+            [0, 1],
+            [1, 2],
+            [1, 3],
+        ],
+        2
+    ],
+
+    [
+        [
+            [1, 1],
+            [1, 2],
+            [1, 3],
+        ],
+        1
+    ],
+
+    [
+        new Map([
+            { 0: 'C', 1: 'O' },
+            { 0: 'C', 1: 'K' },
+            { 0: 'V', 1: 'K' },
+        ]),
+        2
+    ],
+
+    [
+        new Map([
+            [0, 1],
+            [1, 2],
+            [1, 3],
+        ]),
+        2
+    ],
+
+    [
+        new Map([
+            [1, 1],
+            [1, 2],
+            [1, 3],
+        ]),
+        1
+    ],
+
+    [
+        new Map([
+            { 0: 'C', 1: 'O' },
+            { 0: 'C', 1: 'K' },
+            { 0: 'V', 1: 'K' },
+        ]),
+        2
+    ],
+];
+
+for (var pair of pass) {
+    var map = new Map(pair[0]);
+    if (map.size !== pair[1])
+        throw "Error: bad map size " + map.size;
+    testCallTypeError(pair[0]);
+}
+
+function testTypeError(item) {
+    var error = null;
+    try {
+        var map = new Map(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (String(error) !== "TypeError: Type error")
+        throw "Error: bad error " + String(error);
+}
+
+var nonIterable = [
+    42,
+    Symbol("Cappuccino"),
+    true,
+    false,
+    {},
+    new Date(),
+    new Error(),
+    Object(Symbol("Matcha")),
+    (function () { }),
+];
+
+for (var item of nonIterable) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
+
+var notContainNextItem = [
+    "Cocoa",
+    [0, 1, 2, 3, 4],
+    [0, 0, 0, 1, 0],
+    ["A", "B", "A"],
+    new String("cocoa"),
+    new String("Cocoa"),
+    new Set([0,1,2,3,4]),
+    new Set([1,1,1,1]),
+];
+
+for (var item of notContainNextItem) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
diff --git a/tests/stress/map-iterators-next.js b/tests/stress/map-iterators-next.js
new file mode 100644 (file)
index 0000000..f893b73
--- /dev/null
@@ -0,0 +1,111 @@
+// This test checks the behavior of the iterator.next methods on Map objects
+
+var testArray = [1,2,3,4,5,6]
+var testMap = new Map();
+for (var [key, value] of testArray.entries()) {
+    testMap.set(key, value);
+}
+var keys = testMap.keys();
+var i = 0;
+while (true) {
+    var {done, value: key} = keys.next();
+    if (done)
+        break;
+    if (key >= testArray.length)
+        throw "Error: bad value: " + key;
+    i++;
+}
+
+if (testMap.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = keys.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var values = testMap.values();
+var i = 0;
+while (true) {
+    var {done, value} = values.next();
+    if (done)
+        break;
+    i++;
+    if (testArray.indexOf(value) === -1)
+        throw "Error: bad value: " + value;
+}
+
+if (testMap.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = values.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testMap.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (value !== testMap.get(key))
+        throw "Error: bad value: " + value + " " + testMap.get(key);
+    if (key >= testArray.length)
+        throw "Error: bad value: " + key;
+    i++;
+    if (testArray.indexOf(value) === -1)
+        throw "Error: bad value: " + value + " " + i;
+} while (!done);
+
+if (testMap.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testMap.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (value !== testMap.get(key))
+        throw "Error: bad value: " + value + " " + testMap.get(key);
+    i++;
+    if (i % 4 === 0)
+        testMap.set(100000 + i, i);
+} while (!done);
+
+if (testMap.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+function otherKey(key) {
+    return (key + 1) % testArray.length;
+}
+
+var entries = testMap.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (value !== testMap.get(key))
+        throw "Error: bad value: " + value + " " + testMap.get(key);
+    i++;
+    if (i % 4 === 0)
+        testMap.delete(otherKey(key));
+} while (!done);
+
+if (testMap.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
diff --git a/tests/stress/materialize-past-butterfly-allocation.js b/tests/stress/materialize-past-butterfly-allocation.js
new file mode 100644 (file)
index 0000000..d6d5bed
--- /dev/null
@@ -0,0 +1,89 @@
+function bar() {
+    return {f:42};
+}
+
+noInline(bar);
+
+function foo0(b) {
+    var o = {f:42};
+    if (b) {
+        var p = bar();
+        p.g = o;
+        return p;
+    }
+}
+
+function foo1(b) {
+    var o = {f:42};
+    if (b) {
+        var p = bar();
+        p.f1 = 1;
+        p.g = o;
+        return p;
+    }
+}
+
+function foo2(b) {
+    var o = {f:42};
+    if (b) {
+        var p = bar();
+        p.f1 = 1;
+        p.f2 = 2;
+        p.g = o;
+        return p;
+    }
+}
+
+function foo3(b) {
+    var o = {f:42};
+    if (b) {
+        var p = bar();
+        p.f1 = 1;
+        p.f2 = 2;
+        p.f3 = 3;
+        p.g = o;
+        return p;
+    }
+}
+
+function foo4(b) {
+    var o = {f:42};
+    if (b) {
+        var p = bar();
+        p.f1 = 1;
+        p.f2 = 2;
+        p.f3 = 3;
+        p.f4 = 4;
+        p.g = o;
+        return p;
+    }
+}
+
+noInline(foo0);
+noInline(foo1);
+noInline(foo2);
+noInline(foo3);
+noInline(foo4);
+
+var array = new Array(1000);
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo0(true);
+    array[i % array.length] = o;
+}
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo1(true);
+    array[i % array.length] = o;
+}
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo2(true);
+    array[i % array.length] = o;
+}
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo3(true);
+    array[i % array.length] = o;
+}
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo4(true);
+    array[i % array.length] = o;
+}
+
diff --git a/tests/stress/materialize-past-put-structure.js b/tests/stress/materialize-past-put-structure.js
new file mode 100644 (file)
index 0000000..cd7397a
--- /dev/null
@@ -0,0 +1,14 @@
+function foo(p) {
+    var o = {f:42};
+    if (p)
+        return {f:42, g:o};
+}
+
+noInline(foo);
+
+var array = new Array(1000);
+for (var i = 0; i < 4000000; ++i) {
+    var o = foo(true);
+    array[i % array.length] = o;
+}
+
diff --git a/tests/stress/math-abs-positive.js b/tests/stress/math-abs-positive.js
new file mode 100644 (file)
index 0000000..fc4e164
--- /dev/null
@@ -0,0 +1,11 @@
+var minus_three_quarters = -0.75;
+
+function foo() {
+    return Math.abs(minus_three_quarters);
+}
+
+for (var i = 0; i < 10000; i++) {
+    var result = foo();
+    if (result < 0)
+        throw "Error: Math.abs returned a negative value.";
+}
diff --git a/tests/stress/math-clz32-basics.js b/tests/stress/math-clz32-basics.js
new file mode 100644 (file)
index 0000000..58e379e
--- /dev/null
@@ -0,0 +1,222 @@
+function mathClz32OnInteger(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32OnInteger);
+
+// *** Test simple cases on integers. ***
+function testMathClz32OnIntegers()
+{
+    // Bounds.
+    var clzZero = mathClz32OnInteger(0);
+    if (clzZero != 32)
+        throw "mathClz32OnInteger(0) = " + clzZero;
+
+    var clzIntMin = mathClz32OnInteger(-2147483648);
+    if (clzIntMin != 0)
+        throw "mathClz32OnInteger(-2147483648) = " + clzIntMin;
+
+    var clzIntMax = mathClz32OnInteger(2147483647);
+    if (clzIntMax != 1)
+        throw "mathClz32OnInteger(2147483647) = " + clzIntMax;
+
+    // Simple values.
+    var clzMinusOne = mathClz32OnInteger(-1);
+    if (clzMinusOne != 0)
+        throw "mathClz32OnInteger(-1) = " + clzMinusOne;
+
+    var clzUltimateAnswer = mathClz32OnInteger(42);
+    if (clzUltimateAnswer != 26)
+        throw "mathClz32OnInteger(42) = " + clzUltimateAnswer;
+
+    var clzMinusUltimateAnswer = mathClz32OnInteger(-42);
+    if (clzMinusUltimateAnswer != 0)
+        throw "mathClz32OnInteger(-42) = " + clzMinusUltimateAnswer;
+}
+noInline(testMathClz32OnIntegers);
+
+for (var i = 0; i < 1e4; ++i) {
+    testMathClz32OnIntegers();
+}
+
+// Make sure we don't do anything stupid when the type is unexpected.
+function verifyMathClz32OnIntegerWithOtherTypes()
+{
+    var clzPi = mathClz32OnInteger(Math.PI);
+    if (clzPi != 30)
+        throw "mathClz32OnInteger(Math.PI) = " + clzPi;
+
+    var clzString = mathClz32OnInteger("42");
+    if (clzString != 26)
+        throw "mathClz32OnInteger(\"42\") = " + clzString;
+
+    var clzString = mathClz32OnInteger("WebKit");
+    if (clzString != 32)
+        throw "mathClz32OnInteger(\"WebKit\") = " + clzString;
+
+    var clzMinusZero = mathClz32OnInteger(-0);
+    if (clzMinusZero != 32)
+        throw "mathClz32OnInteger(\"-0\") = " + clzMinusZero;
+}
+noInline(verifyMathClz32OnIntegerWithOtherTypes);
+
+for (var i = 0; i < 1e4; ++i) {
+    verifyMathClz32OnIntegerWithOtherTypes();
+}
+
+
+// *** Test simple cases on doubles. ***
+function mathClz32OnDouble(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32OnInteger);
+
+// Test simple cases on integers.
+function testMathClz32OnDoubles()
+{
+    var value = mathClz32OnDouble(Math.PI);
+    if (value != 30)
+        throw "mathClz32OnDouble(Math.PI) = " + value;
+
+    var value = mathClz32OnDouble(Math.E);
+    if (value != 30)
+        throw "mathClz32OnDouble(Math.E) = " + value;
+
+    var value = mathClz32OnDouble(Math.LN2);
+    if (value != 32)
+        throw "mathClz32OnDouble(Math.LN2) = " + value;
+
+    var value = mathClz32OnDouble(-0);
+    if (value != 32)
+        throw "mathClz32OnDouble(0) = " + value;
+
+    var value = mathClz32OnDouble(NaN);
+    if (value != 32)
+        throw "mathClz32OnDouble(NaN) = " + value;
+
+    var value = mathClz32OnDouble(Number.POSITIVE_INFINITI);
+    if (value != 32)
+        throw "mathClz32OnDouble(Number.POSITIVE_INFINITI) = " + value;
+
+    var value = mathClz32OnDouble(Number.NEGATIVE_INFINITI);
+    if (value != 32)
+        throw "mathClz32OnDouble(Number.NEGATIVE_INFINITI) = " + value;
+}
+noInline(testMathClz32OnDoubles);
+
+for (var i = 0; i < 1e4; ++i) {
+    testMathClz32OnDoubles();
+}
+
+// Make sure we don't do anything stupid when the type is unexpected.
+function verifyMathClz32OnDoublesWithOtherTypes()
+{
+    var clzOne = mathClz32OnDouble(1);
+    if (clzOne != 31)
+        throw "mathClz32OnDouble(1) = " + clzOne;
+
+    var clzString = mathClz32OnDouble("42");
+    if (clzString != 26)
+        throw "mathClz32OnDouble(\"42\") = " + clzString;
+
+    var clzString = mathClz32OnDouble("WebKit");
+    if (clzString != 32)
+        throw "mathClz32OnDouble(\"WebKit\") = " + clzString;
+
+    var clzMinusZero = mathClz32OnDouble({});
+    if (clzMinusZero != 32)
+        throw "mathClz32OnDouble({}) = " + clzMinusZero;
+}
+noInline(verifyMathClz32OnDoublesWithOtherTypes);
+
+for (var i = 0; i < 1e4; ++i) {
+    verifyMathClz32OnDoublesWithOtherTypes();
+}
+
+
+// *** Unusual arguments. ***
+function mathClz32NoArguments()
+{
+    return Math.clz32();
+}
+noInline(mathClz32NoArguments);
+
+function mathClz32TooManyArguments(a, b, c)
+{
+    return Math.clz32(a, b, c);
+}
+noInline(mathClz32TooManyArguments);
+
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = mathClz32NoArguments();
+    if (value !== 32)
+        throw "mathClz32NoArguments() = " + value;
+
+    var value = mathClz32TooManyArguments(2, 3, 5);
+    if (value !== 30)
+        throw "mathClz32TooManyArguments() = " + value;
+
+}
+
+
+// *** Constant as arguments. ***
+function testMathClz32OnConstants()
+{
+    var value = Math.clz32(0);
+    if (value !== 32)
+        throw "Math.clz32(0) = " + value;
+    var value = Math.clz32(-0);
+    if (value !== 32)
+        throw "Math.clz32(-0) = " + value;
+    var value = Math.clz32(1);
+    if (value !== 31)
+        throw "Math.clz32(1) = " + value;
+    var value = Math.clz32(-1);
+    if (value !== 0)
+        throw "Math.clz32(-1) = " + value;
+    var value = Math.clz32(42);
+    if (value !== 26)
+        throw "Math.clz32(42) = " + value;
+    var value = Math.clz32(-42);
+    if (value !== 0)
+        throw "Math.clz32(-42) = " + value;
+    var value = Math.clz32(NaN);
+    if (value !== 32)
+        throw "Math.clz32(NaN) = " + value;
+    var value = Math.clz32(Number.POSITIVE_INFINITI);
+    if (value !== 32)
+        throw "Math.clz32(Number.POSITIVE_INFINITI) = " + value;
+    var value = Math.clz32(Number.NEGATIVE_INFINITI);
+    if (value !== 32)
+        throw "Math.clz32(Number.NEGATIVE_INFINITI) = " + value;
+    var value = Math.clz32(Math.E);
+    if (value !== 30)
+        throw "Math.clz32(Math.E) = " + value;
+}
+noInline(testMathClz32OnConstants);
+
+for (var i = 0; i < 1e4; ++i) {
+    testMathClz32OnConstants();
+}
+
+
+// *** Struct transition. ***
+function mathClz32StructTransition(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32StructTransition);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = mathClz32StructTransition(42);
+    if (value !== 26)
+        throw "mathClz32StructTransition(42) = " + value;
+}
+
+Math.clz32 = function() { return arguments[0] + 5; }
+
+var value = mathClz32StructTransition(42);
+if (value !== 47)
+    throw "mathClz32StructTransition(42) after transition = " + value;
diff --git a/tests/stress/math-log-basics.js b/tests/stress/math-log-basics.js
new file mode 100644 (file)
index 0000000..d6d1d14
--- /dev/null
@@ -0,0 +1,128 @@
+// Basic cases of Math.log().
+
+// log(NaN).
+function logNaN(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logNaN);
+
+function testLogNaN() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logNaN(NaN);
+        if (!isNaN(result))
+            throw "logNaN(NaN) = " + result + ", expected NaN";
+    }
+}
+testLogNaN();
+
+
+// log(0).
+function logZero(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logZero);
+
+function testLogZero() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logZero(0);
+        if (result !== -Infinity)
+            throw "logZero(0) = " + result + ", expected -Infinity";
+    }
+}
+testLogZero();
+
+
+// log(1).
+function logOne(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logOne);
+
+function testLogOne() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logOne(1);
+        if (result !== 0)
+            throw "logOne(1) = " + result + ", expected 0";
+    }
+}
+testLogOne();
+
+
+// log(-1).
+function logMinusOne(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logMinusOne);
+
+function testLogMinusOne() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logMinusOne(-1);
+        if (!isNaN(result))
+            throw "logMinusOne(-1) = " + result + ", expected NaN";
+    }
+}
+testLogMinusOne();
+
+
+// log(Infinity).
+function logInfinity(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logInfinity);
+
+function testLogInfinity() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logInfinity(Infinity);
+        if (result !== Infinity)
+            throw "logInfinity(Infinity) = " + result + ", expected Infinity";
+    }
+}
+testLogInfinity();
+
+
+// log(-Infinity).
+function logMinusInfinity(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logMinusInfinity);
+
+function testLogMinusInfinity() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logMinusInfinity(-Infinity);
+        if (!isNaN(result))
+            throw "logMinusInfinity(-Infinity) = " + result + ", expected NaN";
+    }
+}
+testLogMinusInfinity();
+
+
+// log(integer).
+function logInteger(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logInteger);
+
+function testLogInteger() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logInteger(42);
+        if (result !== 3.7376696182833684)
+            throw "logInteger(42) = " + result + ", expected 3.7376696182833684";
+    }
+}
+testLogInteger();
+
+
+// log(double).
+function logDouble(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logDouble);
+
+function testLogDouble() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logDouble(Math.PI);
+        if (result !== 1.1447298858494002)
+            throw "logDouble(Math.PI) = " + result + ", expected 1.1447298858494002";
+    }
+}
+testLogDouble();
\ No newline at end of file
diff --git a/tests/stress/math-log-with-constants.js b/tests/stress/math-log-with-constants.js
new file mode 100644 (file)
index 0000000..c05a075
--- /dev/null
@@ -0,0 +1,128 @@
+// Basic cases of Math.log() when the value passed are constants.
+
+// log(NaN).
+function logNaN() {
+    return Math.log(NaN);
+}
+noInline(logNaN);
+
+function testLogNaN() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logNaN();
+        if (!isNaN(result))
+            throw "logNaN() = " + result + ", expected NaN";
+    }
+}
+testLogNaN();
+
+
+// log(0).
+function logZero() {
+    return Math.log(0);
+}
+noInline(logZero);
+
+function testLogZero() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logZero();
+        if (result !== -Infinity)
+            throw "logZero() = " + result + ", expected -Infinity";
+    }
+}
+testLogZero();
+
+
+// log(1).
+function logOne() {
+    return Math.log(1);
+}
+noInline(logOne);
+
+function testLogOne() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logOne();
+        if (result !== 0)
+            throw "logOne(1) = " + result + ", expected 0";
+    }
+}
+testLogOne();
+
+
+// log(-1).
+function logMinusOne() {
+    return Math.log(-1);
+}
+noInline(logMinusOne);
+
+function testLogMinusOne() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logMinusOne();
+        if (!isNaN(result))
+            throw "logMinusOne() = " + result + ", expected NaN";
+    }
+}
+testLogMinusOne();
+
+
+// log(Infinity).
+function logInfinity() {
+    return Math.log(Infinity);
+}
+noInline(logInfinity);
+
+function testLogInfinity() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logInfinity();
+        if (result !== Infinity)
+            throw "logInfinity() = " + result + ", expected Infinity";
+    }
+}
+testLogInfinity();
+
+
+// log(-Infinity).
+function logMinusInfinity() {
+    return Math.log(-Infinity);
+}
+noInline(logMinusInfinity);
+
+function testLogMinusInfinity() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logMinusInfinity();
+        if (!isNaN(result))
+            throw "logMinusInfinity() = " + result + ", expected NaN";
+    }
+}
+testLogMinusInfinity();
+
+
+// log(integer).
+function logInteger() {
+    return Math.log(42);
+}
+noInline(logInteger);
+
+function testLogInteger() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logInteger();
+        if (result !== 3.7376696182833684)
+            throw "logInteger() = " + result + ", expected 3.7376696182833684";
+    }
+}
+testLogInteger();
+
+
+// log(double).
+function logDouble() {
+    return Math.log(Math.PI);
+}
+noInline(logDouble);
+
+function testLogDouble() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = logDouble();
+        if (result !== 1.1447298858494002)
+            throw "logDouble() = " + result + ", expected 1.1447298858494002";
+    }
+}
+testLogDouble();
\ No newline at end of file
diff --git a/tests/stress/math-pow-basics.js b/tests/stress/math-pow-basics.js
new file mode 100644 (file)
index 0000000..ddf1988
--- /dev/null
@@ -0,0 +1,286 @@
+function valuesAreClose(a, b) {
+    return Math.abs(a / b) - 1 < 1e-10;
+}
+
+// Some random values.
+function mathPowDoubleDouble1(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble1);
+
+function mathPowDoubleInt1(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt1);
+
+function test1(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble1(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble1(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt1(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt1(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test1);
+test1(376.76522764377296, 10.81699226051569, 7.333951929109252e+27, 5.76378989575089e+25);
+
+function mathPowDoubleDouble2(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble2);
+
+function mathPowDoubleInt2(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt2);
+function test2(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble2(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble2(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt2(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt2(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test2);
+test2(376.76522764377296, -5.81699226051569, 1.035180331187579e-15, 1.3171824310400265e-13);
+
+function mathPowDoubleDouble3(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble3);
+
+function mathPowDoubleInt3(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt3);
+function test3(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble3(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble3(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt3(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt3(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test3);
+test3(-37.676522764377296, 10.0, 5763789895750892, 5763789895750892);
+
+// Exponent zero.
+function mathPowDoubleDouble4(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble4);
+
+function mathPowDoubleInt4(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt4);
+function test4(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble4(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble4(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt4(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt4(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test4);
+test4(-37.676522764377296, 0, 1, 1);
+
+// Exponent minus zero.
+function mathPowDoubleDouble5(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble5);
+
+function mathPowDoubleInt5(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt5);
+function test5(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble5(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble5(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt5(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test5);
+test5(-37.676522764377296, -0, 1, 1);
+
+// Exponent 1.
+function mathPowDoubleDouble6(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble6);
+
+function mathPowDoubleInt6(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt6);
+function test6(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble6(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble6(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt6(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt6(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test6);
+test6(-37.676522764377296, 1.0, -37.676522764377296, -37.676522764377296);
+
+// Exponent -1.
+function mathPowDoubleDouble7(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble7);
+
+function mathPowDoubleInt7(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt7);
+function test7(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble7(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble7(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble7(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleDouble7(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test7);
+test6(-37.676522764377296, -1.0, -0.026541727490454296, -0.026541727490454296);
+
+// Let's square things.
+function mathPowDoubleDouble8(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble8);
+
+function mathPowDoubleInt8(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt8);
+function test8(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble8(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble8(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt8(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt8(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test8);
+test7(-37.676522764377296, 2.0, 1419.5203676146407, 1419.5203676146407);
+
+function mathPowDoubleDouble9(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble9);
+
+function mathPowDoubleInt9(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt9);
+function test9(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble9(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble9(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt9(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt9(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test9);
+test8(37.676522764377296, 2.0, 1419.5203676146407, 1419.5203676146407);
+
+// Let's cube things.
+function mathPowDoubleDouble10(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble10);
+
+function mathPowDoubleInt10(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt10);
+function test10(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble10(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt10(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test9);
+test9(-37.676522764377296, 3.0, -53482.591444930236, -53482.591444930236);
+
+function mathPowDoubleDouble11(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDouble11);
+
+function mathPowDoubleInt11(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleInt11);
+function test11(x, y, expected1, expected2) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDouble11(x, y);
+        if (!valuesAreClose(result, expected1))
+            throw "Error: bad result, mathPowDoubleDouble(" + x + ", " + y + ") = " + result + " expected a value close to " + expected1;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleInt11(x, integerY);
+        if (!valuesAreClose(result, expected2))
+            throw "Error: bad result, mathPowDoubleInt(" + x + ", " + integerY + ") = " + result + " expected a value close to " + expected2;
+    }
+}
+noInline(test10);
+test10(37.676522764377296, 3.0, 53482.591444930236, 53482.591444930236);
diff --git a/tests/stress/math-pow-becomes-custom-function.js b/tests/stress/math-pow-becomes-custom-function.js
new file mode 100644 (file)
index 0000000..8893acc
--- /dev/null
@@ -0,0 +1,18 @@
+function mathPowWrapper(x, y) {
+    return Math.pow(x, y);
+}
+noInline(mathPowWrapper);
+
+function testChangingMathPow() {
+    var result = 0;
+    for (var i = 0; i < 10000; ++i) {
+        result += mathPowWrapper(3, 2);
+    }
+    Math.pow = function(a, b) { return a + b; }
+    for (var i = 0; i < 10000; ++i) {
+        result += mathPowWrapper(3, 2);
+    }
+    if (result !== 140000)
+        throw "Result = " + result + ", expected 140000";
+}
+testChangingMathPow();
\ No newline at end of file
diff --git a/tests/stress/math-pow-integer-exponent-fastpath.js b/tests/stress/math-pow-integer-exponent-fastpath.js
new file mode 100644 (file)
index 0000000..d606c44
--- /dev/null
@@ -0,0 +1,56 @@
+function valuesAreClose(a, b) {
+    return Math.abs(a / b) - 1 < 1e-10;
+}
+
+// Small exponent values are handled through a simpler inline loop. Test that it is not observable.
+function mathPowDoubleDoubleTestExponentFifty(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDoubleTestExponentFifty);
+
+function mathPowDoubleIntTestExponentFifty(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleIntTestExponentFifty);
+function testExponentFifty(x, y, expected) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDoubleTestExponentFifty(x, y);
+        if (!valuesAreClose(result, expected))
+            throw "Error: bad result, Math.pow(" + x + ", " + y + ") = " + result + " expected value close to " + expected;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleIntTestExponentFifty(x, integerY);
+        if (!valuesAreClose(result, expected))
+            throw "Error: bad result, Math.pow(" + x + ", " + integerY + ") = " + result + " expected value close to " + expected;
+    }
+}
+noInline(testExponentFifty);
+testExponentFifty(53.70901164133102, 50.0, 3.179494118120144e+86);
+testExponentFifty(53.70901164133102, -10.0, 5.006432842621192e-18);
+
+function mathPowDoubleDoubleTestExponentTenThousands(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleDoubleTestExponentTenThousands);
+
+function mathPowDoubleIntTestExponentTenThousands(x, y) {
+    return Math.pow(x, y)
+}
+noInline(mathPowDoubleIntTestExponentTenThousands);
+function testExponentTenThousands(x, y, expected) {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleDoubleTestExponentTenThousands(x, y);
+        if (!valuesAreClose(result, expected))
+            throw "Error: bad result, Math.pow(" + x + ", " + y + ") = " + result + " expected value close to " + expected;
+    }
+    var integerY = y | 0;
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowDoubleIntTestExponentTenThousands(x, integerY);
+        if (!valuesAreClose(result, expected))
+            throw "Error: bad result, Math.pow(" + x + ", " + integerY + ") = " + result + " expected value close to " + expected;
+    }
+}
+noInline(testExponentTenThousands);
+testExponentTenThousands(1.001, 10000.0, 21916.681339048373);
+testExponentTenThousands(1.001, -1.0, 0.9990009990009991);
\ No newline at end of file
diff --git a/tests/stress/math-pow-nan-behaviors.js b/tests/stress/math-pow-nan-behaviors.js
new file mode 100644 (file)
index 0000000..0bdd698
--- /dev/null
@@ -0,0 +1,209 @@
+// If y is NaN, the result is NaN.
+function testIntegerBaseWithNaNExponentStatic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(5, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(5, NaN) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(i, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(i, NaN) = " + result + " with i = " + i;
+    }
+}
+noInline(testIntegerBaseWithNaNExponentStatic);
+testIntegerBaseWithNaNExponentStatic();
+
+function mathPowIntegerBaseWithNaNExponentDynamic(x, y) {
+    return Math.pow(x, y);
+}
+noInline(mathPowIntegerBaseWithNaNExponentDynamic);
+function testIntegerBaseWithNaNExponentDynamic() {
+    // Warm up with 2 integers.
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowIntegerBaseWithNaNExponentDynamic(2, 5);
+        if (result !== 32)
+            throw "Error: bad result, mathPowIntegerBaseWithNaNExponentDynamic(2, 5) = " + result + ", expected 32."
+    }
+
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowIntegerBaseWithNaNExponentDynamic(i, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowIntegerBaseWithNaNExponentDynamic(i, NaN) = " + result + " with i = " + i + ", expected NaN";
+    }
+}
+noInline(testIntegerBaseWithNaNExponentDynamic);
+testIntegerBaseWithNaNExponentDynamic();
+
+function testFloatingPointBaseWithNaNExponentStatic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(5.5, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(5.5, NaN) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(i + 0.5, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(i + 0.5, NaN) = " + result + " with i = " + i;
+    }
+}
+noInline(testFloatingPointBaseWithNaNExponentStatic);
+testFloatingPointBaseWithNaNExponentStatic();
+
+function mathPowFloatingPointBaseWithNaNExponentDynamic(x, y) {
+    return Math.pow(x, y);
+}
+noInline(mathPowFloatingPointBaseWithNaNExponentDynamic);
+function testFloatingPointBaseWithNaNExponentDynamic() {
+    // Warm up with 2 double.
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowFloatingPointBaseWithNaNExponentDynamic(2.5, 5.1);
+        if (result !== 107.02717054543135)
+            throw "Error: bad result, mathPowFloatingPointBaseWithNaNExponentDynamic(2.5, 5.1) = " + result + ", expected 107.02717054543135."
+    }
+
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowFloatingPointBaseWithNaNExponentDynamic(i + 0.5, NaN);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowFloatingPointBaseWithNaNExponentDynamic(i + 0.5, NaN) = " + result + " with i = " + i + ", expected NaN";
+    }
+}
+noInline(testFloatingPointBaseWithNaNExponentDynamic);
+testFloatingPointBaseWithNaNExponentDynamic();
+
+// If y is +0, the result is 1, even if x is NaN.
+// If y is −0, the result is 1, even if x is NaN.
+// If x is NaN and y is nonzero, the result is NaN.
+function testNaNBaseStatic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(NaN, i + 1);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(NaN, i + 1) = " + result + " with i = " + i;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(NaN, i + 1.5);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(NaN, i + 1.5) = " + result + " with i = " + i;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(NaN, 0);
+        if (result !== 1)
+            throw "Error: bad result, Math.pow(NaN, 0) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(NaN, -0);
+        if (result !== 1)
+            throw "Error: bad result, Math.pow(NaN, -0) = " + result;
+    }
+}
+noInline(testNaNBaseStatic);
+testNaNBaseStatic();
+
+function mathPowNaNBaseDynamic1(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowNaNBaseDynamic2(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowNaNBaseDynamic3(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowNaNBaseDynamic4(x, y) {
+    return Math.pow(x, y);
+}
+noInline(mathPowNaNBaseDynamic1);
+noInline(mathPowNaNBaseDynamic2);
+noInline(mathPowNaNBaseDynamic3);
+noInline(mathPowNaNBaseDynamic4);
+function testNaNBaseDynamic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowNaNBaseDynamic1(NaN, i + 1);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowNaNBaseDynamic1(NaN, i + 1) = " + result + " with i = " + i;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowNaNBaseDynamic2(NaN, i + 1.5);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowNaNBaseDynamic2(NaN, i + 1.5) = " + result + " with i = " + i;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowNaNBaseDynamic3(NaN, 0);
+        if (result !== 1)
+            throw "Error: bad result, mathPowNaNBaseDynamic3(NaN, 0) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowNaNBaseDynamic4(NaN, -0);
+        if (result !== 1)
+            throw "Error: bad result, mathPowNaNBaseDynamic4(NaN, -0) = " + result;
+    }
+}
+noInline(testNaNBaseDynamic);
+testNaNBaseDynamic();
+
+// If abs(x) is 1 and y is +∞, the result is NaN.
+// If abs(x) is 1 and y is −∞, the result is NaN.
+function infiniteExponentsStatic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(1, Number.POSITIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(1, Number.POSITIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(-1, Number.POSITIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(-1, Number.POSITIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(1, Number.NEGATIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(1, Number.NEGATIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = Math.pow(-1, Number.NEGATIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, Math.pow(-1, Number.NEGATIVE_INFINITY) = " + result;
+    }
+}
+noInline(infiniteExponentsStatic);
+infiniteExponentsStatic();
+
+function mathPowInfiniteExponentsDynamic1(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowInfiniteExponentsDynamic2(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowInfiniteExponentsDynamic3(x, y) {
+    return Math.pow(x, y);
+}
+function mathPowInfiniteExponentsDynamic4(x, y) {
+    return Math.pow(x, y);
+}
+noInline(mathPowInfiniteExponentsDynamic1);
+noInline(mathPowInfiniteExponentsDynamic2);
+noInline(mathPowInfiniteExponentsDynamic3);
+noInline(mathPowInfiniteExponentsDynamic4);
+function infiniteExponentsDynamic() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowInfiniteExponentsDynamic1(1, Number.POSITIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowInfiniteExponentsDynamic1(1, Number.POSITIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowInfiniteExponentsDynamic2(-1, Number.POSITIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowInfiniteExponentsDynamic2(-1, Number.POSITIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowInfiniteExponentsDynamic3(1, Number.NEGATIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowInfiniteExponentsDynamic3(1, Number.NEGATIVE_INFINITY) = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = mathPowInfiniteExponentsDynamic4(-1, Number.NEGATIVE_INFINITY);
+        if (!isNaN(result))
+            throw "Error: bad result, mathPowInfiniteExponentsDynamic4(-1, Number.NEGATIVE_INFINITY) = " + result;
+    }
+}
+noInline(infiniteExponentsDynamic);
+infiniteExponentsDynamic();
\ No newline at end of file
diff --git a/tests/stress/math-pow-with-constants.js b/tests/stress/math-pow-with-constants.js
new file mode 100644 (file)
index 0000000..d25902d
--- /dev/null
@@ -0,0 +1,215 @@
+function exponentIsZero(x) {
+    return Math.pow(x, 0);
+}
+noInline(exponentIsZero);
+
+function testExponentIsZero() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsZero(5);
+        if (result !== 1)
+            throw "Error: zeroExponent(5) should be 1, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsZero(5.5);
+        if (result !== 1)
+            throw "Error: zeroExponent(5.5) should be 1, was = " + result;
+    }
+}
+testExponentIsZero();
+
+
+function exponentIsOne(x) {
+    return Math.pow(x, 1);
+}
+noInline(exponentIsOne);
+
+function testExponentIsOne() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsOne(5);
+        if (result !== 5)
+            throw "Error: exponentIsOne(5) should be 5, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsOne(5.5);
+        if (result !== 5.5)
+            throw "Error: exponentIsOne(5.5) should be 5.5, was = " + result;
+    }
+}
+testExponentIsOne();
+
+
+function powUsedAsSqrt(x) {
+    return Math.pow(x, 0.5);
+}
+noInline(powUsedAsSqrt);
+
+function testPowUsedAsSqrt() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = powUsedAsSqrt(4);
+        if (result !== Math.sqrt(4))
+            throw "Error: powUsedAsSqrt(4) should be 2, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = powUsedAsSqrt(4.4);
+        if (result !== Math.sqrt(4.4))
+            throw "Error: powUsedAsSqrt(4) should be " + Math.sqrt(4.4) + ", was = " + result;
+    }
+
+}
+testPowUsedAsSqrt();
+
+
+function intIntConstantsSmallNumbers() {
+    return Math.pow(42, 3);
+}
+function intIntConstantsLargeNumbers() {
+    // The result does not fit in a integer.
+    return Math.pow(42, 42);
+}
+function intIntSmallConstants() {
+    return Math.pow(42, 3);
+}
+function intDoubleConstants() {
+    return Math.pow(14, 42.5);
+}
+function doubleDoubleConstants() {
+    return Math.pow(13.5, 42.5);
+}
+function doubleIntConstants() {
+    return Math.pow(13.5, 52);
+}
+noInline(intIntConstantsSmallNumbers);
+noInline(intIntConstantsLargeNumbers);
+noInline(intDoubleConstants);
+noInline(doubleDoubleConstants);
+noInline(doubleIntConstants);
+
+function testBaseAndExponentConstantLiterals()
+{
+    for (var i = 0; i < 10000; ++i) {
+        var result = intIntConstantsSmallNumbers();
+        if (result !== 74088)
+            throw "Error: intIntConstantsSmallNumbers() should be 74088, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = intIntConstantsLargeNumbers();
+        if (result !== 1.5013093754529656e+68)
+            throw "Error: intIntConstantsLargeNumbers() should be 1.5013093754529656e+68, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = intDoubleConstants();
+        if (result !== 5.1338303882015765e+48)
+            throw "Error: intDoubleConstants() should be 5.1338303882015765e+48, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = doubleDoubleConstants();
+        if (result !== 1.0944228729647829e+48)
+            throw "Error: doubleDoubleConstants() should be 1.0944228729647829e+48, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = doubleIntConstants();
+        if (result !== 5.989022735311158e+58)
+            throw "Error: doubleIntConstants() should be 5.989022735311158e+58, was = " + result;
+    }
+}
+testBaseAndExponentConstantLiterals();
+
+
+function exponentIsIntegerConstant(x) {
+    return Math.pow(x, 42);
+}
+noInline(exponentIsIntegerConstant);
+
+function testExponentIsIntegerConstant() {
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsIntegerConstant(2);
+        if (result !== 4398046511104)
+            throw "Error: exponentIsIntegerConstant(2) should be 4398046511104, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsIntegerConstant(5);
+        if (result !== 2.2737367544323207e+29)
+            throw "Error: exponentIsIntegerConstant(5) should be 2.2737367544323207e+29, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsIntegerConstant(2.1);
+        if (result !== 34135823067412.42)
+            throw "Error: exponentIsIntegerConstant(2.1) should be 34135823067412.42, was = " + result;
+    }
+}
+testExponentIsIntegerConstant();
+
+
+function exponentIsDoubleConstant(x) {
+    return Math.pow(x, 42.5);
+}
+noInline(exponentIsDoubleConstant);
+
+function testExponentIsDoubleConstant() {
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsDoubleConstant(2);
+        if (result !== 6219777023950.95)
+            throw "Error: exponentIsDoubleConstant(2) should be 6219777023950.95, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsDoubleConstant(5);
+        if (result !== 5.084229945850415e+29)
+            throw "Error: exponentIsDoubleConstant(5) should be 5.084229945850415e+29, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsDoubleConstant(2.1);
+        if (result !== 49467507261113.805)
+            throw "Error: exponentIsDoubleConstant(2.1) should be 49467507261113.805, was = " + result;
+    }
+}
+testExponentIsDoubleConstant();
+
+
+function exponentIsInfinityConstant(x) {
+    return Math.pow(x, Infinity);
+}
+noInline(exponentIsInfinityConstant);
+
+function testExponentIsInfinityConstant() {
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsInfinityConstant(2);
+        if (result !== Infinity)
+            throw "Error: exponentIsInfinityConstant(2) should be Infinity, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsInfinityConstant(5);
+        if (result !== Infinity)
+            throw "Error: exponentIsInfinityConstant(5) should be Infinity, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsInfinityConstant(2.1);
+        if (result !== Infinity)
+            throw "Error: exponentIsInfinityConstant(2.1) should be Infinity, was = " + result;
+    }
+}
+testExponentIsInfinityConstant();
+
+
+function exponentIsNegativeInfinityConstant(x) {
+    return Math.pow(x, -Infinity);
+}
+noInline(exponentIsNegativeInfinityConstant);
+
+function testExponentIsNegativeInfinityConstant() {
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsNegativeInfinityConstant(2);
+        if (result !== 0)
+            throw "Error: exponentIsNegativeInfinityConstant(2) should be zero, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsNegativeInfinityConstant(5);
+        if (result !== 0)
+            throw "Error: exponentIsNegativeInfinityConstant(5) should be zero, was = " + result;
+    }
+    for (var i = 0; i < 1000; ++i) {
+        var result = exponentIsNegativeInfinityConstant(2.1);
+        if (result !== 0)
+            throw "Error: exponentIsNegativeInfinityConstant(2.1) should be zero, was = " + result;
+    }
+}
+testExponentIsNegativeInfinityConstant();
\ No newline at end of file
diff --git a/tests/stress/math-pow-with-never-NaN-exponent.js b/tests/stress/math-pow-with-never-NaN-exponent.js
new file mode 100644 (file)
index 0000000..d5d6bc0
--- /dev/null
@@ -0,0 +1,24 @@
+function exponentIsNonNanDouble1(x, doubleArrayIndex) {
+    var doubleArray = [4.4];
+    return Math.pow(x, doubleArray[doubleArrayIndex]);
+}
+noInline(exponentIsNonNanDouble1);
+
+function exponentIsNonNanDouble2(x, doubleArray) {
+    return Math.pow(x, doubleArray[0]);
+}
+noInline(exponentIsNonNanDouble2);
+
+function testExponentIsDoubleConstant() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsNonNanDouble1(2, 0);
+        if (result !== 21.112126572366314)
+            throw "Error: exponentIsNonNanDouble1(2, 0) should be 21.112126572366314, was = " + result;
+    }
+    for (var i = 0; i < 10000; ++i) {
+        var result = exponentIsNonNanDouble2(3, [-1.5]);
+        if (result !== 0.19245008972987526)
+            throw "Error: exponentIsNonNanDouble2(3, [-1.5]) should be 0.19245008972987526, was = " + result;
+    }
+}
+testExponentIsDoubleConstant();
diff --git a/tests/stress/math-round-arith-rounding-mode.js b/tests/stress/math-round-arith-rounding-mode.js
new file mode 100644 (file)
index 0000000..09a2772
--- /dev/null
@@ -0,0 +1,44 @@
+function firstCareAboutZeroSecondDoesNot(a) {
+    var resultA = Math.round(a);
+    var resultB = Math.round(a)|0;
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstCareAboutZeroSecondDoesNot);
+
+function firstDoNotCareAboutZeroSecondDoes(a) {
+    var resultA = Math.round(a)|0;
+    var resultB = Math.round(a);
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstDoNotCareAboutZeroSecondDoes);
+
+// Warmup with doubles, but nothing that would round to -0 to ensure we never
+// see a double as result. The result must be integers, the input is kept to small values.
+function warmup() {
+    for (var i = 0; i < 1e4; ++i) {
+        firstCareAboutZeroSecondDoesNot(42.6 + i);
+        firstDoNotCareAboutZeroSecondDoes(42.4 + i);
+    }
+}
+warmup();
+
+function verifyNegativeZeroIsPreserved() {
+    for (var i = 0; i < 1e4; ++i) {
+        var result1 = firstCareAboutZeroSecondDoesNot(-0.1);
+        if (1 / result1.resultA !== -Infinity) {
+            throw "Failed firstCareAboutZeroSecondDoesNot(-0.1), resultA = " + result1.resultA;
+        }
+        if (1 / result1.resultB !== Infinity) {
+            throw "Failed firstCareAboutZeroSecondDoesNot(-0.1), resultB = " + result1.resultB;
+        }
+        var result2 = firstDoNotCareAboutZeroSecondDoes(-0.1);
+        if (1 / result2.resultA !== Infinity) {
+            throw "Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultA = " + result1.resultA;
+        }
+        if (1 / result2.resultB !== -Infinity) {
+            throw "Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultB = " + result1.resultB;
+        }
+
+    }
+}
+verifyNegativeZeroIsPreserved();
\ No newline at end of file
diff --git a/tests/stress/math-round-basics.js b/tests/stress/math-round-basics.js
new file mode 100644 (file)
index 0000000..2e38c76
--- /dev/null
@@ -0,0 +1,257 @@
+
+function mathRoundOnIntegers(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundOnIntegers);
+
+function mathRoundOnDoubles(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundOnDoubles);
+
+function mathRoundOnBooleans(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundOnBooleans);
+
+// The trivial cases first.
+for (var i = 1; i < 1e4; ++i) {
+    var roundedValue = mathRoundOnIntegers(i);
+    if (roundedValue !== i)
+        throw "mathRoundOnIntegers(" + i + ") = " + roundedValue;
+
+    var roundedValue = mathRoundOnIntegers(-i);
+    if (roundedValue !== -i)
+        throw "mathRoundOnIntegers(" + -i + ") = " + roundedValue;
+
+    var doubleLow = i + 0.4;
+    var roundedValue = mathRoundOnDoubles(doubleLow);
+    if (roundedValue !== i)
+        throw "mathRoundOnDoubles(" + doubleLow + ") = " + roundedValue;
+
+    var doubleHigh = i + 0.6;
+    var roundedValue = mathRoundOnDoubles(doubleHigh);
+    if (roundedValue !== i + 1)
+        throw "mathRoundOnDoubles(" + doubleHigh + ") = " + roundedValue;
+
+    var doubleMid = i + 0.5;
+    var roundedValue = mathRoundOnDoubles(doubleMid);
+    if (roundedValue !== i + 1)
+        throw "mathRoundOnDoubles(" + doubleMid + ") = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(-0.6);
+    if (roundedValue !== -1)
+        throw "mathRoundOnDoubles(-0.6) = " + roundedValue;
+}
+
+// Some more interesting cases, some of them well OSR exit when the return value is zero.
+for (var i = 0; i < 1e4; ++i) {
+    var roundedValue = mathRoundOnIntegers(i);
+    if (roundedValue !== i)
+        throw "mathRoundOnIntegers(" + i + ") = " + roundedValue;
+
+    var roundedValue = mathRoundOnIntegers(-i);
+    if (roundedValue !== -i)
+        throw "mathRoundOnIntegers(-" + i + ") = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(-0.4);
+    if (roundedValue !== 0)
+        throw "mathRoundOnDoubles(-0.4) = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(-0.5);
+    if (roundedValue !== 0)
+        throw "mathRoundOnDoubles(-0.5) = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(-0);
+    if (!(roundedValue === 0 && (1/roundedValue) === -Infinity))
+        throw "mathRoundOnDoubles(-0) = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(NaN);
+    if (roundedValue === roundedValue)
+        throw "mathRoundOnDoubles(NaN) = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(Number.POSITIVE_INFINITY);
+    if (roundedValue !== Number.POSITIVE_INFINITY)
+        throw "mathRoundOnDoubles(Number.POSITIVE_INFINITY) = " + roundedValue;
+
+    var roundedValue = mathRoundOnDoubles(Number.NEGATIVE_INFINITY);
+    if (roundedValue !== Number.NEGATIVE_INFINITY)
+        throw "mathRoundOnDoubles(Number.NEGATIVE_INFINITY) = " + roundedValue;
+
+    var boolean = !!(i % 2);
+    var roundedBoolean = mathRoundOnBooleans(boolean);
+    if (roundedBoolean != boolean)
+        throw "mathRoundOnDoubles(" + boolean + ") = " + roundedBoolean;
+}
+
+function uselessMathRound(value)
+{
+    return Math.round(value|0);
+}
+noInline(uselessMathRound);
+
+for (var i = 0; i < 1e4; ++i) {
+    var roundedValue = uselessMathRound(i);
+    if (roundedValue !== i)
+        throw "uselessMathRound(" + i + ") = " + roundedValue;
+
+    var doubleLow = i + 0.4;
+    var roundedValue = uselessMathRound(doubleLow);
+    if (roundedValue !== i)
+        throw "uselessMathRound(" + doubleLow + ") = " + roundedValue;
+
+    var doubleHigh = i + 0.6;
+    var roundedValue = uselessMathRound(doubleHigh);
+    if (roundedValue !== i)
+        throw "uselessMathRound(" + doubleHigh + ") = " + roundedValue;
+
+    var doubleMid = i + 0.5;
+    var roundedValue = uselessMathRound(doubleMid);
+    if (roundedValue !== i)
+        throw "uselessMathRound(" + doubleMid + ") = " + roundedValue;
+
+    var roundedValue = uselessMathRound(-0.4);
+    if (roundedValue !== 0)
+        throw "uselessMathRound(-0.4) = " + roundedValue;
+
+    var roundedValue = uselessMathRound(-0.5);
+    if (roundedValue !== 0)
+        throw "uselessMathRound(-0.5) = " + roundedValue;
+
+    var roundedValue = uselessMathRound(-0.6);
+    if (roundedValue !== 0)
+        throw "uselessMathRound(-0.6) = " + roundedValue;
+}
+
+function mathRoundWithOverflow(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundWithOverflow);
+
+for (var i = 0; i < 1e4; ++i) {
+    var bigValue = 1000000000000;
+    var roundedValue = mathRoundWithOverflow(bigValue);
+    if (roundedValue !== bigValue)
+        throw "mathRoundWithOverflow(" + bigValue + ") = " + roundedValue;
+}
+
+function mathRoundConsumedAsDouble(value)
+{
+    return Math.round(value) * 0.5;
+}
+noInline(mathRoundConsumedAsDouble);
+
+for (var i = 0; i < 1e4; ++i) {
+    var doubleValue = i + 0.1;
+    var roundedValue = mathRoundConsumedAsDouble(doubleValue);
+    if (roundedValue !== (i * 0.5))
+        throw "mathRoundConsumedAsDouble(" + doubleValue + ") = " + roundedValue;
+
+    var doubleValue = i + 0.6;
+    var roundedValue = mathRoundConsumedAsDouble(doubleValue);
+    if (roundedValue !== ((i + 1) * 0.5))
+        throw "mathRoundConsumedAsDouble(" + doubleValue + ") = " + roundedValue;
+
+}
+
+function mathRoundDoesNotCareAboutMinusZero(value)
+{
+    return Math.round(value)|0;
+}
+noInline(mathRoundDoesNotCareAboutMinusZero);
+
+for (var i = 0; i < 1e4; ++i) {
+    var doubleMid = i + 0.5;
+    var roundedValue = mathRoundDoesNotCareAboutMinusZero(doubleMid);
+    if (roundedValue !== i + 1)
+        throw "mathRoundDoesNotCareAboutMinusZero(" + doubleMid + ") = " + roundedValue;
+}
+
+
+// *** Function arguments. ***
+function mathRoundNoArguments()
+{
+    return Math.round();
+}
+noInline(mathRoundNoArguments);
+
+function mathRoundTooManyArguments(a, b, c)
+{
+    return Math.round(a, b, c);
+}
+noInline(mathRoundTooManyArguments);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = mathRoundNoArguments();
+    if (value === value)
+        throw "mathRoundNoArguments() = " + value;
+
+    var value = mathRoundTooManyArguments(2.1, 3, 5);
+    if (value !== 2)
+        throw "mathRoundTooManyArguments() = " + value;
+}
+
+
+// *** Constant as arguments. ***
+function testMathRoundOnConstants()
+{
+    var value = Math.round(0);
+    if (value !== 0)
+        throw "Math.round(0) = " + value;
+    var value = Math.round(-0);
+    if (!(value === 0 && (1/value) === -Infinity))
+        throw "Math.round(-0) = " + value;
+    var value = Math.round(1);
+    if (value !== 1)
+        throw "Math.round(1) = " + value;
+    var value = Math.round(-1);
+    if (value !== -1)
+        throw "Math.round(-1) = " + value;
+    var value = Math.round(42);
+    if (value !== 42)
+        throw "Math.round(42) = " + value;
+    var value = Math.round(-42.2);
+    if (value !== -42)
+        throw "Math.round(-42.2) = " + value;
+    var value = Math.round(NaN);
+    if (value === value)
+        throw "Math.round(NaN) = " + value;
+    var value = Math.round(Number.POSITIVE_INFINITI);
+    if (value === value)
+        throw "Math.round(Number.POSITIVE_INFINITI) = " + value;
+    var value = Math.round(Number.NEGATIVE_INFINITI);
+    if (value === value)
+        throw "Math.round(Number.NEGATIVE_INFINITI) = " + value;
+    var value = Math.round(Math.E);
+    if (value !== 3)
+        throw "Math.round(Math.E) = " + value;
+}
+noInline(testMathRoundOnConstants);
+
+for (var i = 0; i < 1e4; ++i) {
+    testMathRoundOnConstants();
+}
+
+
+// *** Struct transition. ***
+function mathRoundStructTransition(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundStructTransition);
+
+for (var i = 0; i < 1e4; ++i) {
+    var value = mathRoundStructTransition(42.5);
+    if (value !== 43)
+        throw "mathRoundStructTransition(42.5) = " + value;
+}
+
+Math.round = function() { return arguments[0] + 5; }
+
+var value = mathRoundStructTransition(42);
+if (value !== 47)
+    throw "mathRoundStructTransition(42) after transition = " + value;
diff --git a/tests/stress/math-sqrt-basics-disable-architecture-specific-optimizations.js b/tests/stress/math-sqrt-basics-disable-architecture-specific-optimizations.js
new file mode 100644 (file)
index 0000000..c29bf56
--- /dev/null
@@ -0,0 +1,48 @@
+//@ run("no-architecture-specific-optimizations", "--enableArchitectureSpecificOptimizations=false", *NO_CJIT_OPTIONS)
+//@ run("no-architecture-specific-optimizations-ftl", "--enableArchitectureSpecificOptimizations=false", *FTL_OPTIONS)
+
+// Basic cases of Math.sqrt().
+function sqrtOnInteger(radicand) {
+    return Math.sqrt(radicand);
+}
+noInline(sqrtOnInteger);
+
+function testSquareRoot16() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = sqrtOnInteger(16);
+        if (result !== 4)
+            throw "sqrtOnInteger(16) = " + result + ", expected 4";
+    }
+}
+testSquareRoot16();
+
+var sqrtOnIntegerNegativeNumber = sqrtOnDouble(-4);
+if (!isNaN(sqrtOnIntegerNegativeNumber))
+    throw "sqrtOnDouble(-4) = " + sqrtOnIntegerNegativeNumber + ", expected NaN";
+
+var sqrtOnIntegerFallback = sqrtOnInteger(Math.PI);
+if (sqrtOnIntegerFallback != 1.7724538509055159)
+    throw "sqrtOnInteger(Math.PI) = " + sqrtOnIntegerFallback + ", expected 1.7724538509055159";
+
+
+function sqrtOnDouble(radicand) {
+    return Math.sqrt(radicand);
+}
+noInline(sqrtOnDouble);
+
+function testSquareRootDouble() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = sqrtOnInteger(Math.LN2);
+        if (result !== 0.8325546111576977)
+            throw "sqrtOnInteger(Math.LN2) = " + result + ", expected 0.8325546111576977";
+    }
+}
+testSquareRootDouble();
+
+var sqrtOnDoubleNegativeNumber = sqrtOnDouble(-Math.PI);
+if (!isNaN(sqrtOnDoubleNegativeNumber))
+    throw "sqrtOnDouble(-Math.PI) = " + sqrtOnDoubleNegativeNumber + ", expected NaN";
+
+var sqrtOnDoubleFallback = sqrtOnDouble(4);
+if (sqrtOnDoubleFallback !== 2)
+    throw "sqrtOnDouble(4) = " + sqrtOnDoubleFallback + ", expected 2";
\ No newline at end of file
diff --git a/tests/stress/math-sqrt-basics.js b/tests/stress/math-sqrt-basics.js
new file mode 100644 (file)
index 0000000..f19b752
--- /dev/null
@@ -0,0 +1,45 @@
+// Basic cases of Math.sqrt().
+function sqrtOnInteger(radicand) {
+    return Math.sqrt(radicand);
+}
+noInline(sqrtOnInteger);
+
+function testSquareRoot16() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = sqrtOnInteger(16);
+        if (result !== 4)
+            throw "sqrtOnInteger(16) = " + result + ", expected 4";
+    }
+}
+testSquareRoot16();
+
+var sqrtOnIntegerNegativeNumber = sqrtOnDouble(-4);
+if (!isNaN(sqrtOnIntegerNegativeNumber))
+    throw "sqrtOnDouble(-4) = " + sqrtOnIntegerNegativeNumber + ", expected NaN";
+
+var sqrtOnIntegerFallback = sqrtOnInteger(Math.PI);
+if (sqrtOnIntegerFallback != 1.7724538509055159)
+    throw "sqrtOnInteger(Math.PI) = " + sqrtOnIntegerFallback + ", expected 1.7724538509055159";
+
+
+function sqrtOnDouble(radicand) {
+    return Math.sqrt(radicand);
+}
+noInline(sqrtOnDouble);
+
+function testSquareRootDouble() {
+    for (var i = 0; i < 10000; ++i) {
+        var result = sqrtOnInteger(Math.LN2);
+        if (result !== 0.8325546111576977)
+            throw "sqrtOnInteger(Math.LN2) = " + result + ", expected 0.8325546111576977";
+    }
+}
+testSquareRootDouble();
+
+var sqrtOnDoubleNegativeNumber = sqrtOnDouble(-Math.PI);
+if (!isNaN(sqrtOnDoubleNegativeNumber))
+    throw "sqrtOnDouble(-Math.PI) = " + sqrtOnDoubleNegativeNumber + ", expected NaN";
+
+var sqrtOnDoubleFallback = sqrtOnDouble(4);
+if (sqrtOnDoubleFallback !== 2)
+    throw "sqrtOnDouble(4) = " + sqrtOnDoubleFallback + ", expected 2";
\ No newline at end of file
diff --git a/tests/stress/misc-is-object-or-null.js b/tests/stress/misc-is-object-or-null.js
new file mode 100644 (file)
index 0000000..e8968e5
--- /dev/null
@@ -0,0 +1,13 @@
+function foo(p) {
+    var x = p ? null : false;
+    return (typeof x) == "object";
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var p = !!(i & 1);
+    var result = foo(p);
+    if (result !== p)
+        throw "Error: bad result for p = " + p + ": " + result;
+}
diff --git a/tests/stress/modify-map-during-iteration.js b/tests/stress/modify-map-during-iteration.js
new file mode 100644 (file)
index 0000000..6261689
--- /dev/null
@@ -0,0 +1,97 @@
+
+function testValue(value, expected) {
+    if (value !== expected)
+        throw new Error("bad value: expected:(" + expected + "),actual:(" + value +").");
+}
+
+function identityPairs(array) {
+    return array.map(function (i) { return [i, i]; });
+}
+
+var map = new Map(identityPairs([0]));
+var counter = 0;
+for (var [elm, _] of map) {
+    testValue(elm, counter);
+    map.set(elm + 1, elm + 1);
+    if (elm > 10000) {
+        map.clear();
+    }
+    ++counter;
+}
+testValue(counter, 10002);
+
+var map = new Map(identityPairs([0, 1, 2, 3]));
+var counter = 0;
+for (var [elm, _] of map) {
+    testValue(elm, counter);
+    map.clear();
+    ++counter;
+}
+testValue(counter, 1);
+
+var map = new Map(identityPairs([0, 1, 2, 3]));
+var exp = [0, 2, 3];
+var counter = 0;
+for (var [elm, _] of map) {
+    testValue(elm, exp[counter]);
+    map.delete(counter + 1);
+    ++counter;
+}
+testValue(counter, 3);
+
+var map = new Map(identityPairs([0, 1, 2, 3]));
+var iter = map.keys();
+var iter2 = map.keys();
+testValue(iter2.next().value, 0);
+
+// Consume all output of iter.
+for (var elm of iter);
+
+testValue(iter.next().done, true);
+testValue(iter.next().value, undefined);
+
+map.clear();
+map.set(1, 1).set(2, 2).set(3, 3);
+
+testValue(iter.next().done, true);
+testValue(iter.next().value, undefined);
+testValue(iter2.next().value, 1);
+testValue(iter2.next().value, 2);
+testValue(iter2.next().value, 3);
+
+var map = new Map();
+map.set(1, 1);
+map.delete(1);
+map.forEach(function (i) {
+    throw new Error("unreeachable.");
+});
+
+var map = new Map();
+var iter = map[Symbol.iterator]();
+map.set(1, 1);
+map.delete(1);
+for (var [elm, _] of map) {
+    throw new Error("unreeachable.");
+}
+
+var map = new Map();
+for (var i = 0; i < 5; ++i)
+    map.set(i, i);
+testValue(map.size, 5);
+var iter = map.keys();
+testValue(iter.next().value, 0);
+testValue(iter.next().value, 1);
+testValue(iter.next().value, 2);
+testValue(iter.next().value, 3);
+map.delete(0);
+map.delete(1);
+map.delete(2);
+map.delete(3);
+// It will cause MapData packing.
+for (var i = 5; i < 1000; ++i)
+    map.set(i, i);
+gc();
+for (var i = 4; i < 1000; ++i)
+    testValue(iter.next().value, i);
+testValue(iter.next().value, undefined);
+
diff --git a/tests/stress/modify-set-during-iteration.js b/tests/stress/modify-set-during-iteration.js
new file mode 100644 (file)
index 0000000..a739847
--- /dev/null
@@ -0,0 +1,91 @@
+
+function testValue(value, expected) {
+    if (value !== expected)
+        throw new Error("bad value: expected:(" + expected + "),actual:(" + value +").");
+}
+
+var set = new Set([0]);
+var counter = 0;
+for (var elm of set) {
+    testValue(elm, counter);
+    set.add(elm + 1);
+    if (elm > 10000) {
+        set.clear();
+    }
+    ++counter;
+}
+testValue(counter, 10002);
+
+var set = new Set([0, 1, 2, 3]);
+var counter = 0;
+for (var elm of set) {
+    testValue(elm, counter);
+    set.clear();
+    ++counter;
+}
+testValue(counter, 1);
+
+var set = new Set([0, 1, 2, 3]);
+var exp = [0, 2, 3];
+var counter = 0;
+for (var elm of set) {
+    testValue(elm, exp[counter]);
+    set.delete(counter + 1);
+    ++counter;
+}
+testValue(counter, 3);
+
+var set = new Set([0, 1, 2, 3]);
+var iter = set[Symbol.iterator]();
+var iter2 = set[Symbol.iterator]();
+testValue(iter2.next().value, 0);
+
+// Consume all output of iter.
+for (var elm of iter);
+
+testValue(iter.next().done, true);
+testValue(iter.next().value, undefined);
+
+set.clear();
+set.add(1).add(2).add(3);
+
+testValue(iter.next().done, true);
+testValue(iter.next().value, undefined);
+testValue(iter2.next().value, 1);
+testValue(iter2.next().value, 2);
+testValue(iter2.next().value, 3);
+
+var set = new Set();
+set.add(1);
+set.delete(1);
+set.forEach(function (i) {
+    throw new Error("unreeachable.");
+});
+
+var set = new Set();
+var iter = set[Symbol.iterator]();
+set.add(1);
+set.delete(1);
+for (var elm of iter) {
+    throw new Error("unreeachable.");
+}
+
+var set = new Set([0, 1, 2, 3, 4]);
+var iter = set[Symbol.iterator]();
+testValue(set.size, 5);
+testValue(iter.next().value, 0);
+testValue(iter.next().value, 1);
+testValue(iter.next().value, 2);
+testValue(iter.next().value, 3);
+set.delete(0);
+set.delete(1);
+set.delete(2);
+set.delete(3);
+// It will cause MapData packing.
+for (var i = 5; i < 1000; ++i)
+    set.add(i);
+gc();
+for (var i = 4; i < 1000; ++i)
+    testValue(iter.next().value, i);
+testValue(iter.next().value, undefined);
+
diff --git a/tests/stress/multi-get-by-offset-dce.js b/tests/stress/multi-get-by-offset-dce.js
new file mode 100644 (file)
index 0000000..bce1e82
--- /dev/null
@@ -0,0 +1,22 @@
+function foo(o) {
+    var tmp = o.f;
+    return 42;
+}
+
+noInline(foo);
+
+var array = [{f:1}, {g:1, f:2}];
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(array[i % array.length]);
+    if (result != 42)
+        throw "Error: bad result in loop: " + result;
+}
+
+var o = {};
+var didCallGetter = false;
+o.__defineGetter__("f", function() { didCallGetter = true; return 73; });
+var result = foo(o);
+if (result != 42)
+    throw "Error: bad result at end: " + result;
+if (!didCallGetter)
+    throw "Error: did not call getter at end.";
diff --git a/tests/stress/multi-put-by-offset-multiple-transitions.js b/tests/stress/multi-put-by-offset-multiple-transitions.js
new file mode 100644 (file)
index 0000000..99987ef
--- /dev/null
@@ -0,0 +1,30 @@
+function foo(o) {
+    o.x = 1;
+    o.y = 2;
+    o.a = 3;
+    o.b = 4;
+    o.c = 5;
+    o.d = 6;
+    o.e = 7;
+    o.f = 8;
+    o.g = 9;
+    o.h = 10;
+    o.i = 11;
+}
+
+noInline(foo);
+
+function Foo() {
+    foo(this);
+}
+
+var result = 0;
+
+for (var i = 0; i < 100000; ++i) {
+    foo({f:42});
+    result += (new Foo()).x;
+}
+
+if (result != 100000)
+    throw "Bad result: " + result;
+
index 8d61be956ac55aaf120a9d84aec4b6ea92ea3c2c..af3a239ef568f6666e3d4c856dff2ba4fc8af72c 100644 (file)
@@ -4,6 +4,12 @@ function foo(x) {
 
 noInline(foo);
 
+// Warm up up to create array storage.
+for (var i = 0; i < 10000; ++i) {
+    var array = foo(10);
+    array.__defineSetter__(0, function(v) { });
+}
+
 function test(size) {
     var result = foo(size);
     if (result.length != size)
@@ -19,5 +25,5 @@ function test(size) {
 }
 
 for (var i = 0; i < 100000; ++i) {
-    test(1000000);
+    test(10);
 }
diff --git a/tests/stress/new-array-then-exit.js b/tests/stress/new-array-then-exit.js
new file mode 100644 (file)
index 0000000..7c8a690
--- /dev/null
@@ -0,0 +1,14 @@
+function foo(f) {
+    return new f();
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+    foo(Array);
+
+var didCall = false;
+foo(function() { didCall = true; });
+
+if (!didCall)
+    throw "Error: didn't call my function.";
diff --git a/tests/stress/new-largeish-contiguous-array-with-size.js b/tests/stress/new-largeish-contiguous-array-with-size.js
new file mode 100644 (file)
index 0000000..31091f3
--- /dev/null
@@ -0,0 +1,47 @@
+// We only need one run of this with any GC or JIT strategy. This test is not particularly fast.
+// Unfortunately, it needs to run for a while to test the thing it's testing.
+//@ slow!
+//@ runWithRAMSize(10000000)
+
+function foo(x) {
+    return new Array(x);
+}
+
+noInline(foo);
+
+function test(size) {
+    var result = foo(size);
+    if (result.length != size)
+        throw "Error: bad result: " + result;
+    var sawThings = false;
+    for (var s in result)
+        sawThings = true;
+    if (sawThings)
+        throw "Error: array is in bad state: " + result;
+    result[0] = "42.5";
+    if (result[0] != "42.5")
+        throw "Error: array is in weird state: " + result;
+}
+
+var result = gcHeapSize();
+
+for (var i = 0; i < 1000; ++i) {
+    // The test was written when we found that large array allocations weren't being accounted for
+    // in that part of the GC's accounting that determined the GC trigger. Consequently, the GC
+    // would run too infrequently in this loop and we would use an absurd amount of memory when this
+    // loop exited.
+    test(50000);
+}
+
+// Last time I tested, the heap should be 3725734 before and 125782 after. I don't want to enforce
+// exactly that. If you regress the accounting code, the GC heap size at this point will be much
+// more than that.
+var result = gcHeapSize();
+if (result > 10000000)
+    throw "Error: heap too big before forced GC: " + result;
+
+// Do a final check after GC, just for sanity.
+gc();
+result = gcHeapSize();
+if (result > 1000000)
+    throw "Error: heap too big after forced GC: " + result;
diff --git a/tests/stress/no-abc-skippy-loop.js b/tests/stress/no-abc-skippy-loop.js
new file mode 100644 (file)
index 0000000..67d867e
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(array) {
+    var result = 0;
+    for (var i = 0; i != array.length; i += 2) {
+        var element = array[i];
+        if (element === void 0)
+            break;
+        result += array[i];
+    }
+    return result;
+}
+
+noInline(foo);
+
+var array = [1, 2, 3, 4];
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(array);
+    if (result != 4)
+        throw "Error: bad result in loop: " + result;
+}
+
+var array = [1, 2, 3];
+var result = foo(array);
+if (result != 4)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/no-abc-skippy-paired-loop.js b/tests/stress/no-abc-skippy-paired-loop.js
new file mode 100644 (file)
index 0000000..8bf8dd9
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(array) {
+    var result = 0;
+    for (var i = 0; i < array.length; i += 2)
+        result += array[i] + array[i + 1];
+    return result;
+}
+
+noInline(foo);
+
+var array = [1, 2, 3, 4];
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(array);
+    if (result != 10)
+        throw "Error: bad result in loop: " + result;
+}
+
+var array = [1, 2, 3];
+var result = foo(array);
+if ("" + result != "NaN")
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/object-allocation-sinking-with-uninitialized-property-on-one-path.js b/tests/stress/object-allocation-sinking-with-uninitialized-property-on-one-path.js
new file mode 100644 (file)
index 0000000..374b3b0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+// Regression test for https://bugs.webkit.org/show_bug.cgi?id=144020.
+// This test should not crash.
+
+// What happened in the bug:
+function foo(p) {
+    var b = {};
+    b.a = {};
+    if (p)
+        b.a.C = p.q;
+    return b.a.C;
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; i++)
+    foo(true);
+
+// A reduced version:
+function foo2(p) {
+    var o = {};
+    if (p)
+        o.f = {};
+    return o.f;
+}
+noInline(foo2);
+
+for (var i = 0; i < 10000; i++)
+    foo2(true);
+
diff --git a/tests/stress/object-escapes-in-loop.js b/tests/stress/object-escapes-in-loop.js
new file mode 100644 (file)
index 0000000..196f72f
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(p) {
+    var o = {};
+    if (p) {
+        for (var i = 0; i < 100; ++i)
+            bar(o);
+    }
+    return 42;
+}
+
+function bar() {
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 100000; ++i)
+    foo(true);
diff --git a/tests/stress/object-freeze-accept-non-object.js b/tests/stress/object-freeze-accept-non-object.js
new file mode 100644 (file)
index 0000000..c4008c0
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.freeze(primitive);
+    if (ret !== primitive)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/object-get-own-property-descriptor-perform-to-object.js b/tests/stress/object-get-own-property-descriptor-perform-to-object.js
new file mode 100644 (file)
index 0000000..50d772b
--- /dev/null
@@ -0,0 +1,43 @@
+var primitives = [
+    ["string", 6],
+    [42, undefined],
+    [Symbol("symbol"), undefined],
+    [true, undefined],
+    [false, undefined]
+];
+
+for (var [primitive, expected] of primitives) {
+    var ret = Object.getOwnPropertyDescriptor(primitive, 'length');
+    if (expected === undefined) {
+        if (ret !== expected)
+            throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+    } else if (ret.value !== expected)
+        throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+}
+
+function canary() {
+    return {
+        called: false,
+        toString() {
+            this.called = true;
+            throw new Error("out");
+        }
+    };
+}
+
+[
+    [ null, "TypeError: null is not an object (evaluating 'Object.getOwnPropertyDescriptor(value, property)')" ],
+    [ undefined, "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(value, property)')" ]
+].forEach(function ([value, message]) {
+    var property = canary();
+    var error = null;
+    try {
+        Object.getOwnPropertyDescriptor(value, property);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+});
diff --git a/tests/stress/object-get-own-property-names-perform-to-object.js b/tests/stress/object-get-own-property-names-perform-to-object.js
new file mode 100644 (file)
index 0000000..38ff56c
--- /dev/null
@@ -0,0 +1,39 @@
+var primitives = [
+    ["string", ['0', '1', '2', '3', '4', '5', 'length']],
+    [42, []],
+    [Symbol("symbol"), []],
+    [true, []],
+    [false, []]
+];
+
+function compare(ax, bx) {
+    if (ax.length !== bx.length)
+        return false;
+    for (var i = 0, iz = ax.length; i < iz; ++i) {
+        if (ax[i] !== bx[i])
+            return false;
+    }
+    return true;
+}
+
+for (var [primitive, expected] of primitives) {
+    var ret = Object.getOwnPropertyNames(primitive);
+    if (!compare(ret, expected))
+        throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+}
+
+[
+    [ null, "TypeError: null is not an object (evaluating 'Object.getOwnPropertyNames(value)')" ],
+    [ undefined, "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyNames(value)')" ]
+].forEach(function ([value, message]) {
+    var error = null;
+    try {
+        Object.getOwnPropertyNames(value);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+});
diff --git a/tests/stress/object-get-own-property-symbols-perform-to-object.js b/tests/stress/object-get-own-property-symbols-perform-to-object.js
new file mode 100644 (file)
index 0000000..031c3fa
--- /dev/null
@@ -0,0 +1,39 @@
+var primitives = [
+    ["string", []],
+    [42, []],
+    [Symbol("symbol"), []],
+    [true, []],
+    [false, []]
+];
+
+function compare(ax, bx) {
+    if (ax.length !== bx.length)
+        return false;
+    for (var i = 0, iz = ax.length; i < iz; ++i) {
+        if (ax[i] !== bx[i])
+            return false;
+    }
+    return true;
+}
+
+for (var [primitive, expected] of primitives) {
+    var ret = Object.getOwnPropertySymbols(primitive);
+    if (!compare(ret, expected))
+        throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+}
+
+[
+    [ null, "TypeError: null is not an object (evaluating 'Object.getOwnPropertySymbols(value)')" ],
+    [ undefined, "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertySymbols(value)')" ]
+].forEach(function ([value, message]) {
+    var error = null;
+    try {
+        Object.getOwnPropertySymbols(value);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+});
diff --git a/tests/stress/object-get-own-property-symbols.js b/tests/stress/object-get-own-property-symbols.js
new file mode 100644 (file)
index 0000000..40e93d8
--- /dev/null
@@ -0,0 +1,35 @@
+// This tests Object.getOwnPropertySymbols.
+
+var global = (Function("return this")());
+
+// private names for privileged code should not be exposed.
+if (Object.getOwnPropertySymbols(global).length !== 0)
+    throw "Error: bad value " + Object.getOwnPropertySymbols(global).length;
+
+var object = {};
+var symbol = Symbol("Cocoa");
+object[symbol] = "Cappuccino";
+if (Object.getOwnPropertyNames(object).length !== 0)
+    throw "Error: bad value " + Object.getOwnPropertyNames(object).length;
+if (Object.getOwnPropertySymbols(object).length !== 1)
+    throw "Error: bad value " + Object.getOwnPropertySymbols(object).length;
+if (Object.getOwnPropertySymbols(object)[0] !== symbol)
+    throw "Error: bad value " + String(Object.getOwnPropertySymbols(object)[0]);
+
+function forIn(obj) {
+    var array = [];
+    // Symbol should not be enumerated.
+    for (var key in obj) array.push(key);
+    return array;
+}
+
+if (forIn(object).length !== 0)
+    throw "Error: bad value " + forIn(object).length;
+if (Object.keys(object).length !== 0)
+    throw "Error: bad value " + Object.keys(object).length;
+
+delete object[symbol];
+if (Object.getOwnPropertyNames(object).length !== 0)
+    throw "Error: bad value " + Object.getOwnPropertyNames(object).length;
+if (Object.getOwnPropertySymbols(object).length !== 0)
+    throw "Error: bad value " + Object.getOwnPropertySymbols(object).length;
diff --git a/tests/stress/object-get-prototype-of-perform-to-object.js b/tests/stress/object-get-prototype-of-perform-to-object.js
new file mode 100644 (file)
index 0000000..c952337
--- /dev/null
@@ -0,0 +1,29 @@
+var primitives = [
+    ["string", String.prototype],
+    [42, Number.prototype],
+    [Symbol("symbol"), Symbol.prototype],
+    [true, Boolean.prototype],
+    [false, Boolean.prototype]
+];
+
+for (var [primitive, expected] of primitives) {
+    var ret = Object.getPrototypeOf(primitive);
+    if (ret !== expected)
+        throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+}
+
+[
+    [ null, "TypeError: null is not an object (evaluating 'Object.getPrototypeOf(value)')" ],
+    [ undefined, "TypeError: undefined is not an object (evaluating 'Object.getPrototypeOf(value)')" ]
+].forEach(function ([value, message]) {
+    var error = null;
+    try {
+        Object.getPrototypeOf(value);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+});
diff --git a/tests/stress/object-is-extensible-accept-non-object.js b/tests/stress/object-is-extensible-accept-non-object.js
new file mode 100644 (file)
index 0000000..44c371d
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.isExtensible(primitive);
+    if (ret !== false)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/object-is-frozen-accept-non-object.js b/tests/stress/object-is-frozen-accept-non-object.js
new file mode 100644 (file)
index 0000000..e98823b
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.isFrozen(primitive);
+    if (ret !== true)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/object-is-sealed-accept-non-object.js b/tests/stress/object-is-sealed-accept-non-object.js
new file mode 100644 (file)
index 0000000..08d5e60
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.isSealed(primitive);
+    if (ret !== true)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/object-keys-perform-to-object.js b/tests/stress/object-keys-perform-to-object.js
new file mode 100644 (file)
index 0000000..d0e668f
--- /dev/null
@@ -0,0 +1,39 @@
+var primitives = [
+    ["string", ['0', '1', '2', '3', '4', '5']],
+    [42, []],
+    [Symbol("symbol"), []],
+    [true, []],
+    [false, []]
+];
+
+function compare(ax, bx) {
+    if (ax.length !== bx.length)
+        return false;
+    for (var i = 0, iz = ax.length; i < iz; ++i) {
+        if (ax[i] !== bx[i])
+            return false;
+    }
+    return true;
+}
+
+for (var [primitive, expected] of primitives) {
+    var ret = Object.keys(primitive);
+    if (!compare(ret, expected))
+        throw new Error("bad value for " + String(primitive) + ": " + String(ret));
+}
+
+[
+    [ null, "TypeError: null is not an object (evaluating 'Object.keys(value)')" ],
+    [ undefined, "TypeError: undefined is not an object (evaluating 'Object.keys(value)')" ]
+].forEach(function ([value, message]) {
+    var error = null;
+    try {
+        Object.keys(value);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+});
diff --git a/tests/stress/object-prevent-extensions-accept-non-object.js b/tests/stress/object-prevent-extensions-accept-non-object.js
new file mode 100644 (file)
index 0000000..564febb
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.preventExtensions(primitive);
+    if (ret !== primitive)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/object-seal-accept-non-object.js b/tests/stress/object-seal-accept-non-object.js
new file mode 100644 (file)
index 0000000..5c3d23d
--- /dev/null
@@ -0,0 +1,15 @@
+var primitives = [
+    "string",
+    42,
+    null,
+    undefined,
+    Symbol("symbol"),
+    true,
+    false
+];
+
+for (var primitive of primitives) {
+    var ret = Object.seal(primitive);
+    if (ret !== primitive)
+        throw new Error("bad value: " + String(ret));
+}
diff --git a/tests/stress/obviously-elidable-new-object-then-exit.js b/tests/stress/obviously-elidable-new-object-then-exit.js
new file mode 100644 (file)
index 0000000..faa5449
--- /dev/null
@@ -0,0 +1,23 @@
+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+var array = [1, "hello"];
+
+function foo() {
+    var result = 0;
+    var q;
+    for (var i = 0; i < n; ++i) {
+        var o = {f: i};
+        var p = {f: i + 1};
+        q = array[(i >= n - 100) | 0] + 1;
+        result += o.f + p.f;
+    }
+    return q + result;
+}
+
+var result = foo();
+if (result != "hello" + 1 + (sumOfArithSeries(n - 1) + sumOfArithSeries(n)))
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/op-push-name-scope-crashes-profiler.js b/tests/stress/op-push-name-scope-crashes-profiler.js
new file mode 100644 (file)
index 0000000..42784f1
--- /dev/null
@@ -0,0 +1,17 @@
+//@ runProfiler
+function test() {
+    (function functionName() {
+        ++counter;
+        if (!arguments[0])
+            return;
+        eval("functionName(arguments[0] - 1, functionName, '' + functionName);");
+     })(arguments[0]);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    counter = 0;
+    test(100);
+    if (counter !== 101) {
+        throw "Oops, test(100) = " + test(100) + ", expected 101.";
+    }
+}
\ No newline at end of file
diff --git a/tests/stress/other-is-object-or-null.js b/tests/stress/other-is-object-or-null.js
new file mode 100644 (file)
index 0000000..81c0b0a
--- /dev/null
@@ -0,0 +1,13 @@
+function foo(p) {
+    var x = p ? null : void 0;
+    return (typeof x) == "object";
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var p = !!(i & 1);
+    var result = foo(p);
+    if (result !== p)
+        throw "Error: bad result for p = " + p + ": " + result;
+}
diff --git a/tests/stress/phantom-direct-arguments-clobber-argument-count.js b/tests/stress/phantom-direct-arguments-clobber-argument-count.js
new file mode 100644 (file)
index 0000000..eb50477
--- /dev/null
@@ -0,0 +1,20 @@
+function foo() {
+    return effectful42.apply(this, arguments);
+}
+
+function bar(a, b) {
+    var result = foo.apply(this, b);
+    return [a, a, a, a, a, a, a, a, result + a];
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = "" + bar(1, []);
+    if (result != "1,1,1,1,1,1,1,1,43")
+        throw "Error: bad result: " + result;
+}
+
+var result = "" + bar(2147483647, []);
+if (result != "2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483689")
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/phantom-direct-arguments-clobber-callee.js b/tests/stress/phantom-direct-arguments-clobber-callee.js
new file mode 100644 (file)
index 0000000..70588f8
--- /dev/null
@@ -0,0 +1,21 @@
+function foo() {
+    return function() { return effectful42.apply(this, arguments) };
+}
+noInline(foo);
+
+function bar(a) {
+    var result = foo()();
+    return [result, result, result, result, result, result, result, result, result + a];
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = "" + bar(1);
+    if (result != "42,42,42,42,42,42,42,42,43")
+        throw "Error: bad result: " + result;
+}
+
+var result = "" + bar(2147483647);
+if (result != "42,42,42,42,42,42,42,42,2147483689")
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/phantom-inadequacy.js b/tests/stress/phantom-inadequacy.js
new file mode 100644 (file)
index 0000000..bb72e22
--- /dev/null
@@ -0,0 +1,33 @@
+function bar() {
+    return 42.5;
+}
+noInline(bar);
+
+function baz(value) {
+    if (value != 42.5)
+        throw "Error: bad value: " + value;
+}
+noInline(baz);
+
+var True = true;
+function foo(a) {
+    var x = bar();
+    var tmp = 0;
+    if (True) {
+        var tmp2 = x;
+        tmp = a + 1;
+        baz(tmp2);
+    }
+    return x + 1 + tmp;
+}
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(1);
+    if (result != 42.5 + 1 + 1 + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(2147483647);
+if (result != 42.5 + 1 + 2147483647 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/poly-call-exit-this.js b/tests/stress/poly-call-exit-this.js
new file mode 100644 (file)
index 0000000..596af3e
--- /dev/null
@@ -0,0 +1,29 @@
+(function() {
+    function foo(x) { return 1 + this.f; }
+    function bar(x) { return x + this.f; }
+    function baz(x) { return x + 1 + this.f; }
+    
+    var n = 1000000;
+    
+    var result = (function(o) {
+        var f = {fun:foo, f:1};
+        var g = {fun:bar, f:2};
+        var h = {fun:baz, f:3};
+        
+        var result = 0;
+        for (var i = 0; i < n; ++i) {
+            if (i == n - 1)
+                f = h;
+            result += f.fun(o.f);
+            
+            var tmp = f;
+            f = g;
+            g = tmp;
+        }
+        
+        return result;
+    })({f:42});
+    
+    if (result != ((n / 2 - 1) * (42 + 2)) + (n / 2 * (1 + 1) + (42 + 1 + 3)))
+        throw "Error: bad result: " + result;
+})();
diff --git a/tests/stress/poly-call-exit.js b/tests/stress/poly-call-exit.js
new file mode 100644 (file)
index 0000000..eadd16a
--- /dev/null
@@ -0,0 +1,29 @@
+(function() {
+    function foo(x) { return 1; }
+    function bar(x) { return x; }
+    function baz(x) { return x + 1; }
+    
+    var n = 1000000;
+    
+    var result = (function(o) {
+        var f = foo;
+        var g = bar;
+        var h = baz;
+        
+        var result = 0;
+        for (var i = 0; i < n; ++i) {
+            if (i == n - 1)
+                f = h;
+            result += f(o.f);
+            
+            var tmp = f;
+            f = g;
+            g = tmp;
+        }
+        
+        return result;
+    })({f:42});
+    
+    if (result != ((n / 2 - 1) * 42) + (n / 2 * 1) + (42 + 1))
+        throw "Error: bad result: " + result;
+})();
diff --git a/tests/stress/poly-chain-getter.js b/tests/stress/poly-chain-getter.js
new file mode 100644 (file)
index 0000000..1f617a2
--- /dev/null
@@ -0,0 +1,30 @@
+function Cons() {
+}
+Cons.prototype.__defineGetter__("f", function() {
+    counter++;
+    return 84;
+});
+
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons(), 84, counter + 1);
+    
+    var o = new Cons();
+    o.g = 54;
+    test(o, 84, counter + 1);
+}
diff --git a/tests/stress/poly-chain-setter.js b/tests/stress/poly-chain-setter.js
new file mode 100644 (file)
index 0000000..491fe5f
--- /dev/null
@@ -0,0 +1,32 @@
+function Cons() {
+}
+Cons.prototype.__defineSetter__("f", function(value) {
+    counter++;
+    this._f = value;
+});
+Cons.prototype.__defineGetter__("f", function() { return this._f; });
+
+function foo(o, v) {
+    o.f = v;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons(), i, counter + 1);
+    
+    var o = new Cons();
+    o.g = 54;
+    test(o, i, counter + 1);
+}
diff --git a/tests/stress/poly-chain-then-getter.js b/tests/stress/poly-chain-then-getter.js
new file mode 100644 (file)
index 0000000..ecb89bd
--- /dev/null
@@ -0,0 +1,31 @@
+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineGetter__("f", function() {
+    counter++;
+    return 84;
+});
+
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons1(), 42, counter);
+    test(new Cons2(), 84, counter + 1);
+}
diff --git a/tests/stress/poly-chain-then-setter.js b/tests/stress/poly-chain-then-setter.js
new file mode 100644 (file)
index 0000000..cc363b9
--- /dev/null
@@ -0,0 +1,33 @@
+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineSetter__("f", function(value) {
+    counter++;
+    this._f = value;
+});
+Cons2.prototype.__defineGetter__("f", function() { return this._f; });
+
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons1(), i, counter);
+    test(new Cons2(), i, counter + 1);
+}
diff --git a/tests/stress/poly-getter-combo.js b/tests/stress/poly-getter-combo.js
new file mode 100644 (file)
index 0000000..cdeeee5
--- /dev/null
@@ -0,0 +1,40 @@
+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineGetter__("f", function() {
+    counter++;
+    return 84;
+});
+
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons1(), 42, counter);
+    test(new Cons2(), 84, counter + 1);
+    
+    var o = {};
+    o.__defineGetter__("f", function() {
+        counter++;
+        return 84;
+    });
+    test(o, 84, counter + 1);
+
+    test({f: 42}, 42, counter);
+}
diff --git a/tests/stress/poly-getter-then-chain.js b/tests/stress/poly-getter-then-chain.js
new file mode 100644 (file)
index 0000000..8db9310
--- /dev/null
@@ -0,0 +1,31 @@
+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+}
+Cons2.prototype.__defineGetter__("f", function() {
+    counter++;
+    return 84;
+});
+
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test(new Cons2(), 84, counter + 1);
+    test(new Cons1(), 42, counter);
+}
diff --git a/tests/stress/poly-getter-then-self.js b/tests/stress/poly-getter-then-self.js
new file mode 100644 (file)
index 0000000..d90fb10
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o.__defineGetter__("f", function() {
+        counter++;
+        return 84;
+    });
+    test(o, 84, counter + 1);
+
+    test({f: 42}, 42, counter);
+}
diff --git a/tests/stress/poly-self-getter.js b/tests/stress/poly-self-getter.js
new file mode 100644 (file)
index 0000000..72d7d3a
--- /dev/null
@@ -0,0 +1,31 @@
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+function getter() {
+    counter++;
+    return 84;
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o.__defineGetter__("f", getter);
+    test(o, 84, counter + 1);
+
+    var o = {};
+    o.__defineGetter__("f", getter);
+    o.g = 54;
+    test(o, 84, counter + 1);
+}
diff --git a/tests/stress/poly-self-then-getter.js b/tests/stress/poly-self-then-getter.js
new file mode 100644 (file)
index 0000000..24310ac
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    test({f: 42}, 42, counter);
+
+    var o = {};
+    o.__defineGetter__("f", function() {
+        counter++;
+        return 84;
+    });
+    test(o, 84, counter + 1);
+}
diff --git a/tests/stress/poly-setter-combo.js b/tests/stress/poly-setter-combo.js
new file mode 100644 (file)
index 0000000..e3446a6
--- /dev/null
@@ -0,0 +1,77 @@
+function Cons1() {
+}
+Cons1.prototype.f = 42;
+
+function Cons2() {
+    this._values = []
+}
+Cons2.prototype.__defineSetter__("f", function(value) {
+    counter++;
+    this._f = value;
+    this._values[value] = 1;
+});
+Cons2.prototype.__defineGetter__("f", function() { return this._f; });
+
+function Cons3() {
+}
+Cons3.prototype.f = 42;
+Cons3.prototype.g = 43;
+
+function Cons4() {
+    this._values = []
+}
+Cons4.prototype.g = 16;
+Cons4.prototype.__defineSetter__("f", function(value) {
+    counter++;
+    this._f = value;
+    this._values[value] = 1;
+});
+Cons4.prototype.__defineGetter__("f", function() { return this._f; });
+
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+function runTestWithConstructors(constructor1, constructor2) {
+    for (var i = 0; i < 5000; ++i) {
+        test(new constructor1(), i, counter);
+        test(new constructor2(), i, counter + 1);
+
+        var o = {};
+        o.__defineGetter__("f", function() {
+            counter++;
+            return 84;
+        });
+        test(o, 84, counter + 1);
+
+        var o = {};
+        o.__defineSetter__("f", function(value) {
+            this._f = value;
+            counter++;
+        });
+        o.__defineGetter__("f", function() { return this._f; });
+        test(o, i, counter + 1);
+
+        test({f: 42}, i, counter);
+    }
+}
+
+for (var i = 0; i < 2; ++i) {
+    runTestWithConstructors(Cons1, Cons2);
+    runTestWithConstructors(Cons3, Cons2);
+    runTestWithConstructors(Cons1, Cons4);
+    runTestWithConstructors(Cons3, Cons4);
+}
diff --git a/tests/stress/poly-setter-then-self.js b/tests/stress/poly-setter-then-self.js
new file mode 100644 (file)
index 0000000..3c35db7
--- /dev/null
@@ -0,0 +1,28 @@
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o.__defineSetter__("f", function(value) {
+        counter++;
+        this._f = value;
+    });
+    o.__defineGetter__("f", function() { return this._f; });
+    test(o, i, counter + 1);
+
+    test({f: 42}, i, counter);
+}
diff --git a/tests/stress/proto-setter.js b/tests/stress/proto-setter.js
new file mode 100644 (file)
index 0000000..33b7afa
--- /dev/null
@@ -0,0 +1,8 @@
+// RegExp.input is a handy setter
+
+var o = {};
+
+for (var k = 0; k < 9; k++) {
+    o = {__proto__ : o };
+}
+
diff --git a/tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js b/tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js
new file mode 100644 (file)
index 0000000..8a5604c
--- /dev/null
@@ -0,0 +1,58 @@
+function foo(o) {
+    o.f = 1;
+}
+
+function fu(o) {
+    o.e = 2;
+}
+
+function bar(f, o) {
+    f(o);
+}
+
+function baz(f, o) {
+    f(o);
+}
+
+for (var i = 0; i < 100; ++i) {
+    foo({f:1, e:2});
+    foo({e:1, f:2});
+    foo({e:1});
+    foo({d:1, e:2, f:3});
+    fu({f:1, e:2});
+    fu({e:1, f:2});
+    fu({e:1, f:2, g:3});
+    fu({d:1, e:2, f:3, g:4});
+}
+    
+for (var i = 0; i < 100; ++i) {
+    bar(foo, {f:1});
+    bar(function() { }, null);
+    bar(function() { return 42; }, null);
+    baz(fu, {e:1});
+    baz(function() { }, null);
+    baz(function() { return 42; }, null);
+}
+    
+(function(f, g, o, p) {
+    var result = 0;
+    var n = 1000000;
+    for (var i = 0; i < n; ++i) {
+        var q;
+        if (i == n - 1)
+            q = p;
+        else
+            q = o;
+        baz(g, q);
+        bar(f, q);
+    }
+    if (o.e != 2)
+        throw "Error: bad value in o.e: " + o.e;
+    if (o.f != 1)
+        throw "Error: bad value in o.f: " + o.f;
+    if (p.e != 2)
+        throw "Error: bad value in p.e: " + p.e;
+    if (p.f != 1)
+        throw "Error: bad value in p.f: " + p.f;
+})(foo, fu, {e:42, f:2}, {e:12, f:13, g:14});
+
diff --git a/tests/stress/put-by-id-build-list-order-recurse.js b/tests/stress/put-by-id-build-list-order-recurse.js
new file mode 100644 (file)
index 0000000..09d0219
--- /dev/null
@@ -0,0 +1,35 @@
+var count = 0;
+
+function setter(value) {
+    Object.defineProperty(
+        this, "f", {
+        enumerable: true,
+                configurable: true,
+                writable: true,
+                value: 32
+                });
+    var o = Object.create(this);
+    var currentCount = count++;
+    var str = "for (var i = " + currentCount + "; i < " + (100 + currentCount) + "; ++i)\n"
+            + "    o.f\n";
+    eval(str);
+}
+
+function foo(o) {
+    o.f = 42;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 1000; ++i) {
+    var o = {};
+    o.__defineSetter__("f", setter);
+
+    foo(o);
+    if (o.f != 32)
+        throw ("Error 1: "+o.f);
+
+    foo(o);
+    if (o.f != 42)
+        throw ("Error 2: "+o.f);
+}
\ No newline at end of file
diff --git a/tests/stress/put-by-id-direct-should-be-done-for-non-index-property.js b/tests/stress/put-by-id-direct-should-be-done-for-non-index-property.js
new file mode 100644 (file)
index 0000000..0159522
--- /dev/null
@@ -0,0 +1,41 @@
+(function () {
+    var object = {
+        2: 2
+    };
+
+    var result = object[2];
+    if (result !== 2)
+        throw new Error('bad value:' + result);
+}());
+
+
+(function () {
+    var object = {
+        get 2() {
+            return 1;
+        },
+        set 2(value) {
+            throw new Error(2);
+        },
+    };
+
+    var result = object[2];
+    if (result !== 1)
+        throw new Error('bad value:' + result);
+}());
+
+(function () {
+    var object = {
+        get 2() {
+            return 1;
+        },
+        set 2(value) {
+            throw new Error(2);
+        },
+        2: 2,  // Do not throw new Error(2)
+    };
+
+    var result = object[2];
+    if (result !== 2)
+        throw new Error('bad value:' + result);
+}());
diff --git a/tests/stress/put-by-id-on-new-object-after-prototype-transition-non-strict.js b/tests/stress/put-by-id-on-new-object-after-prototype-transition-non-strict.js
new file mode 100644 (file)
index 0000000..15cc9f9
--- /dev/null
@@ -0,0 +1,31 @@
+function opaqueNewObject(prototype)
+{
+    return Object.create(prototype);
+}
+noInline(opaqueNewObject);
+
+function putValueOnNewObject(value, prototype)
+{
+    var object = opaqueNewObject(prototype);
+    object.myProperty = value;
+    return object;
+}
+noInline(putValueOnNewObject)
+
+for (var i = 0; i < 1e4; ++i) {
+    var initialPrototype = new Object;
+    for (var j = 0; j < 5; ++j) {
+        var object = putValueOnNewObject(j, initialPrototype);
+        if (object["myProperty"] !== j) {
+            throw "Ooops, we mess up before the prototype change at iteration i = " + i + " j = " + j;
+        }
+    }
+
+    initialPrototype.foo = "bar";
+    for (var j = 0; j < 5; ++j) {
+        var object = putValueOnNewObject(j, initialPrototype);
+        if (object["myProperty"] !== j) {
+            throw "Ooops, we mess up at iteration i = " + i + " j = " + j;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/stress/put-by-id-on-new-object-after-prototype-transition-strict.js b/tests/stress/put-by-id-on-new-object-after-prototype-transition-strict.js
new file mode 100644 (file)
index 0000000..4542244
--- /dev/null
@@ -0,0 +1,33 @@
+"use strict"
+
+function opaqueNewObject(prototype)
+{
+    return Object.create(prototype);
+}
+noInline(opaqueNewObject);
+
+function putValueOnNewObject(value, prototype)
+{
+    var object = opaqueNewObject(prototype);
+    object.myProperty = value;
+    return object;
+}
+noInline(putValueOnNewObject)
+
+for (var i = 0; i < 1e4; ++i) {
+    var initialPrototype = new Object;
+    for (var j = 0; j < 5; ++j) {
+        var object = putValueOnNewObject(j, initialPrototype);
+        if (object["myProperty"] !== j) {
+            throw "Ooops, we mess up before the prototype change at iteration i = " + i + " j = " + j;
+        }
+    }
+
+    initialPrototype.foo = "bar";
+    for (var j = 0; j < 5; ++j) {
+        var object = putValueOnNewObject(j, initialPrototype);
+        if (object["myProperty"] !== j) {
+            throw "Ooops, we mess up at iteration i = " + i + " j = " + j;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/stress/put-by-id-strict-build-list-order.js b/tests/stress/put-by-id-strict-build-list-order.js
new file mode 100644 (file)
index 0000000..baab8e5
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(o) {
+    "use strict";
+    o.f = 42;
+}
+
+noInline(foo);
+
+var a = {};
+foo(a);
+foo(a);
+a = {f : 3};
+foo(a);
+
+var b = {};
+foo(b);
+foo(b);
diff --git a/tests/stress/put-by-val-out-of-bounds-basics.js b/tests/stress/put-by-val-out-of-bounds-basics.js
new file mode 100644 (file)
index 0000000..186c9fb
--- /dev/null
@@ -0,0 +1,87 @@
+// Put early out-of-bound data.
+function opaquePutByValOnInt32ArrayEarlyOutOfBounds(array, index, value)
+{
+    array[index] = value;
+}
+noInline(opaquePutByValOnInt32ArrayEarlyOutOfBounds);
+
+function testInt32ArrayEarlyOutOfBounds()
+{
+    // Warm up with an immediate out of bounds.
+    var int32Array = new Array(10);
+    for (var i = 0; i < 10; ++i) {
+        opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, i, i);
+        var value = int32Array[i];
+        if (value !== i)
+            throw "Failed opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, i, i) warmup with i = " + i + " value = " + value;
+    }
+    opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, 1042, 1);
+    var value = int32Array[1042];
+    if (value !== 1)
+        throw "Failed opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, 1042, 1) value = " + value;
+
+    var length = int32Array.length;
+    if (int32Array.length !== 1043)
+        throw "Incorrect int32Array.length, length = " + length;
+
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e4; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, j, i);
+            var value = int32Array[j];
+            if (value !== i)
+                throw "Failed opaquePutByValOnInt32ArrayEarlyOutOfBounds(int32Array, j, i) in-bounds with i = " + i + " j = " + j + " value = " + value;
+        }
+    }
+}
+testInt32ArrayEarlyOutOfBounds();
+
+
+// Get out-of-bound data after a thousand run.
+function opaquePutByValOnStringArrayHotOutOfBounds(array, index, value)
+{
+    array[index] = value;
+}
+noInline(opaquePutByValOnStringArrayHotOutOfBounds);
+
+function testStringArrayHotOutOfBounds()
+{
+    // Warm up with in bounds access.
+    var stringArray = new Array(10);
+    for (var i = 0; i < 1e2; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, "" + i);
+            var value = stringArray[j];
+            if (value !== "" + i)
+                throw "Failed opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, i) in-bounds with i = " + i + " j = " + j + " value = " + value;
+        }
+    }
+
+    // Do a single out of bounds after warmup.
+    opaquePutByValOnStringArrayHotOutOfBounds(stringArray, 513, 42);
+    var value = stringArray[513];
+    if (value !== 42)
+        throw "Failed opaquePutByValOnStringArrayHotOutOfBounds(stringArray, 513, 42), value = " + value;
+
+    // We then do plenty of in-bounds accesses.
+    for (var i = 0; i < 1e3; ++i) {
+        for (var j = 0; j < 10; ++j) {
+            opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, "" + i);
+            var value = stringArray[j];
+            if (value !== "" + i)
+                throw "Failed opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, i) in-bounds with i = " + i + " j = " + j + " value = " + value;
+        }
+    }
+
+    // Followed by plenty of out-of-bounds accesses.
+    for (var j = 514; j <= 1025; ++j)
+        opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, "" + j);
+
+    for (var j = 514; j <= 1025; ++j) {
+        var value = stringArray[j];
+        if (value !== "" + j)
+            throw "Failed opaquePutByValOnStringArrayHotOutOfBounds(stringArray, j, j) in-bounds with j = " + j + " value = " + value;
+    }
+}
+testStringArrayHotOutOfBounds();
diff --git a/tests/stress/put-local-conservative.js b/tests/stress/put-local-conservative.js
new file mode 100644 (file)
index 0000000..c63a0c1
--- /dev/null
@@ -0,0 +1,47 @@
+function foo(o, a, b, c) {
+    // Don't do anything real but have some control flow. This causes the PutLocals for a,
+    // b, and c to survive into SSA form. But we don't have any effects, so sinking will be
+    // successful.
+    if (o.f)
+        return 42;
+    else
+        return 0;
+}
+
+function bar(o, y) {
+    var a = y;
+    var b = y + 1;
+    var c = y + 2;
+    var d = y + 3;
+    var e = y + 4;
+    var f = y + 5;
+    var g = y + 6;
+    var h = y + 7;
+    var i = y + 8;
+    var j = y + 9;
+    var k = y + 10;
+    var result = function(p, q) {
+        var x = a + b + c + d + e + f + g + h + i + j + k;
+        if (q) {
+            // Make it appear that it's possible to clobber those closure variables, so that we
+            // load from them again down below.
+            a = b = c = d = e = f = g = h = i = j = k = 42;
+        }
+        if (p)
+            x = foo(o, 1, 2, 3)
+        else
+            x = 5;
+        return x + a + b + c + d + e + f + g + h + i + j + k;
+    };
+    noInline(result);
+    return result;
+}
+
+var o = {f: 42};
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar(o, i)(true, false);
+    if (result != 42 + 11 * i + 55)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/raise-error-in-iterator-close.js b/tests/stress/raise-error-in-iterator-close.js
new file mode 100644 (file)
index 0000000..88f6e86
--- /dev/null
@@ -0,0 +1,118 @@
+
+function createIterator(callback) {
+    var array = [0,1,2,3,4,5];
+    var iterator = array[Symbol.iterator]();
+    iterator.return = function () {
+        iterator.returned = true;
+        if (callback)
+            return callback(this);
+        return { done: true, value: undefined };
+    };
+    iterator.returned = false;
+    return iterator;
+}
+
+(function test() {
+    var outerIterator = createIterator();
+    var innerIterator = createIterator(function () {
+        throw new Error("Inner return called.");
+    });
+    var error = null;
+    try {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+                break;
+            }
+        }
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("no error");
+    if (String(error) !== "Error: Inner return called.")
+        throw new Error("bad error: " + String(error));
+    if (!innerIterator.returned)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (!outerIterator.returned)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator(function () {
+        throw new Error("Outer return called.");
+    });
+    var innerIterator = createIterator(function () {
+        throw new Error("Inner return called.");
+    });
+    var error = null;
+    try {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+                break;
+            }
+        }
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("no error");
+    if (String(error) !== "Error: Inner return called.")
+        throw new Error("bad error: " + String(error));
+    if (!innerIterator.returned)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (!outerIterator.returned)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator(function () {
+        throw new Error("Outer return called.");
+    });
+    var innerIterator = createIterator();
+    var error = null;
+    try {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+                break outer;
+            }
+        }
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("no error");
+    if (String(error) !== "Error: Outer return called.")
+        throw new Error("bad error: " + String(error));
+    if (!innerIterator.returned)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (!outerIterator.returned)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
+(function test() {
+    var outerIterator = createIterator(function () {
+        throw new Error("Outer return called.");
+    });
+    var innerIterator = createIterator(function () {
+        throw new Error("Inner return called.");
+    });
+    var error = null;
+    try {
+        outer: for (var e1 of outerIterator) {
+            inner: for (var e2 of innerIterator) {
+                throw new Error("Loop raises error.");
+            }
+        }
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("no error");
+    if (String(error) !== "Error: Loop raises error.")
+        throw new Error("bad error: " + String(error));
+    if (!innerIterator.returned)
+        throw new Error("bad value: " + innerIterator.returned);
+    if (!outerIterator.returned)
+        throw new Error("bad value: " + outerIterator.returned);
+}());
+
diff --git a/tests/stress/real-forward-varargs-for-inlined-escaped-arguments.js b/tests/stress/real-forward-varargs-for-inlined-escaped-arguments.js
new file mode 100644 (file)
index 0000000..0f5b65c
--- /dev/null
@@ -0,0 +1,25 @@
+function foo() {
+    return arguments;
+}
+
+function fuzz(args) {
+    return foo.apply(void 0, args);
+}
+
+function baz(a, b, c) {
+    return a + b + c;
+}
+
+function bar(args1) {
+    var args2 = fuzz(args1);
+    return baz.apply(void 0, args2);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 20000; ++i) {
+    var result = bar([1, 2, 3]);
+    if (result != 6)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/recursive_property_redefine_during_inline_caching.js b/tests/stress/recursive_property_redefine_during_inline_caching.js
new file mode 100644 (file)
index 0000000..a92dfbc
--- /dev/null
@@ -0,0 +1,23 @@
+// to be run with useLLInt = false
+var o = {};
+
+function getSomeProperty(){
+    return o.someProperty;
+}
+
+var count = 0;
+function test(){
+    count++;
+    if (count == 3) {
+        Object.defineProperty(this, 'someProperty', { value : "okay" });
+        return getSomeProperty();
+    }
+    return "okay";
+}
+
+o.__defineGetter__('someProperty', test)
+
+for (var i = 0; i < 4; i++) {
+    if (getSomeProperty() != "okay")
+        throw ("Error: " + i);
+}
diff --git a/tests/stress/regress-141883.js b/tests/stress/regress-141883.js
new file mode 100644 (file)
index 0000000..8af1719
--- /dev/null
@@ -0,0 +1,15 @@
+// This test is taken almost literally from the bug report: https://bugs.webkit.org/show_bug.cgi?id=141883.
+// The only change is to use a loop bound of 1e4 instead of 1e5 to make the test run faster. This
+// change still caused a reliable crash in every optimizing JIT configuration prior to the fix.
+
+(function() {
+var b=!2;
+var n = 1e4;
+for(i = 0; i< n; i++) {
+b[b=this];
+for (var i = 0; i < n; i++) {
+  if (a = b*3) {
+  }
+}
+}
+})()
diff --git a/tests/stress/remove-phantom-after-setlocal.js b/tests/stress/remove-phantom-after-setlocal.js
new file mode 100644 (file)
index 0000000..3b79241
--- /dev/null
@@ -0,0 +1,18 @@
+var constant = {};
+
+function foo(o) {
+    var v = o.f;
+    return v === constant;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 1000000; ++i) {
+    var result = foo({f:null});
+    if (result !== false)
+        throw "Error: bogus result in loop";
+}
+
+var result = foo({f:constant});
+if (result !== true)
+    throw "Error: bogus result at end";
diff --git a/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js b/tests/stress/repeat-put-to-scope-global-with-same-value-watchpoint-invalidate.js
new file mode 100644 (file)
index 0000000..fce955b
--- /dev/null
@@ -0,0 +1,23 @@
+function foo(v) {
+    global = v;
+}
+
+function bar() {
+    return global;
+}
+
+noInline(foo);
+noInline(bar);
+
+var value = 42;
+for (var i = 0; i < 10; ++i)
+    foo(value);
+var n = 100000;
+var m = 100;
+for (var i = 0; i < n; ++i) {
+    if (i == n - m)
+        foo(value = 53);
+    var result = bar();
+    if (result != value)
+        throw "Error: on iteration " + i + " got: " + result;
+}
index 838c48f7302ac09a00843ab13b2aae280a5da65b..da4498e011aa9907fc5c73392789067f372e3484 100644 (file)
@@ -3,6 +3,6 @@ function bar(a,b,c,d,e,f,g,h,i,j,k) {
 
 noInline(bar);
 
-for (var i = 0; i < 10000000; ++i)
+for (var i = 0; i < 10000; ++i)
     bar();
 
diff --git a/tests/stress/reserved-word-with-escape.js b/tests/stress/reserved-word-with-escape.js
new file mode 100644 (file)
index 0000000..60335f2
--- /dev/null
@@ -0,0 +1,141 @@
+function testSyntax(script) {
+    try {
+        eval(script);
+    } catch (error) {
+        if (error instanceof SyntaxError)
+            throw new Error("Bad error: " + String(error));
+    }
+}
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown");
+
+    if (String(error) !== message)
+        throw new Error("Bad error: " + String(error));
+}
+
+testSyntax("var cocoa");
+testSyntax("var c\u006fcoa");
+
+testSyntaxError(String.raw`var var`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`var v\u0061r`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`var v\u{0061}r`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`var var = 2000000;`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`var v\u0061r = 2000000;`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`var v\u{0061}r = 2000000`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`var {var} = obj)`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`var {v\u0061r} = obj`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`var {v\u{0061}r} = obj`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`var {var:var} = obj)`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`var {var:v\u0061r} = obj`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`var {var:v\u{0061}r} = obj`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`var [var] = obj`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`var [v\u0061r] = obj`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`var [v\u{0061}r] = obj`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`[var] = obj`, String.raw`SyntaxError: Unexpected keyword 'var'`);
+testSyntaxError(String.raw`[v\u0061r] = obj`, String.raw`SyntaxError: Unexpected keyword 'v\u0061r'`);
+testSyntaxError(String.raw`[v\u{0061}r] = obj`, String.raw`SyntaxError: Unexpected keyword 'v\u{0061}r'`);
+
+testSyntaxError(String.raw`function var() { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a function name.`);
+testSyntaxError(String.raw`function v\u0061r() { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a function name.`);
+testSyntaxError(String.raw`function v\u{0061}r() { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a function name.`);
+
+testSyntaxError(String.raw`function a(var) { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`function a(v\u0061r) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`function a(v\u{0061}r) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`function a({var}) { }`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`function a({v\u0061r}) { }`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`function a({v\u{0061}r}) { }`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`function a({var:var}) { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`function a({var:v\u0061r}) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`function a({var:v\u{0061}r}) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`function a([var]) { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`function a([v\u0061r]) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`function a([v\u{0061}r]) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function var() { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a function name.`);
+testSyntaxError(String.raw`(function v\u0061r() { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a function name.`);
+testSyntaxError(String.raw`(function v\u{0061}r() { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a function name.`);
+
+testSyntaxError(String.raw`(function a(var) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a(v\u0061r) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a(v\u{0061}r) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({var}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({v\u0061r}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({v\u{0061}r}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`(function a({var:var}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({var:v\u0061r}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({var:v\u{0061}r}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a([var]) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a([v\u0061r]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a([v\u{0061}r]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a([{var}]) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a([{v\u0061r}]) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a([{v\u{0061}r}]) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`(function a([{var:var}]) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a([{var:v\u0061r}]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a([{var:v\u{0061}r}]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a([[var]]) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a([[v\u0061r]]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a([[v\u{0061}r]]) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({ hello: {var}}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({ hello: {v\u0061r}}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({ hello: {v\u{0061}r}}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`(function a({ hello: {var:var}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({ hello: {var:v\u0061r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({ hello: {var:v\u{0061}r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({ hello: [var]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({ hello: [v\u0061r]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({ hello: [v\u{0061}r]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({ 0: {var} }) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({ 0: {v\u0061r}}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+testSyntaxError(String.raw`(function a({ 0: {v\u{0061}r}}) { })`, String.raw`SyntaxError: Cannot use abbreviated destructuring syntax for keyword 'var'.`);
+
+testSyntaxError(String.raw`(function a({ 0: {var:var}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: {var:v\u0061r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: {var:v\u{0061}r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({ 0: {value:var}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: {value:v\u0061r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: {value:v\u{0061}r}}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`(function a({ 0: [var]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'var' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: [v\u0061r]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a variable name.`);
+testSyntaxError(String.raw`(function a({ 0: [v\u{0061}r]}) { })`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a variable name.`);
+
+testSyntaxError(String.raw`try { } catch(var) { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a catch variable name.`);
+testSyntaxError(String.raw`try { } catch(v\u0061r) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a catch variable name.`);
+testSyntaxError(String.raw`try { } catch(v\u{0061}r) { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a catch variable name.`);
+
+testSyntaxError(String.raw`class var { }`, String.raw`SyntaxError: Cannot use the keyword 'var' as a class name.`);
+testSyntaxError(String.raw`class v\u0061r { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u0061r' as a class name.`);
+testSyntaxError(String.raw`class v\u{0061}r { }`, String.raw`SyntaxError: Cannot use the keyword 'v\u{0061}r' as a class name.`);
+
+// Allowed in non-keyword aware context.
+testSyntax(String.raw`({ v\u0061r: 'Cocoa' })`);
+testSyntax(String.raw`({ v\u{0061}r: 'Cocoa' })`);
diff --git a/tests/stress/rest-elements.js b/tests/stress/rest-elements.js
new file mode 100644 (file)
index 0000000..8c96d5c
--- /dev/null
@@ -0,0 +1,223 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown");
+
+    if (String(error) !== message)
+        throw new Error("Bad error: " + String(error));
+}
+
+(function () {
+    var [a, b, ...c] = "Cocoa";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
+}());
+
+(function () {
+    var [a, b, ...c] = "Co";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}());
+
+(function () {
+    var [a, b, ...c] = "C";
+    shouldBe(a, 'C');
+    shouldBe(b, undefined);
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}());
+
+(function () {
+    var a, b, c;
+    [a, b, ...c] = "Cocoa";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
+}());
+
+(function () {
+    var a, b, c;
+    [a, b, ...c] = "Co";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}());
+
+(function () {
+    var a, b, c;
+    [a, b, ...c] = "C";
+    shouldBe(a, 'C');
+    shouldBe(b, undefined);
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}());
+
+(function ([a, b, ...c]) {
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
+}("Cocoa"));
+
+(function ([a, b, ...c]) {
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}("Co"));
+
+(function ([a, b, ...c]) {
+    shouldBe(a, 'C');
+    shouldBe(b, undefined);
+    shouldBe(JSON.stringify(c), String.raw`[]`);
+}("C"));
+
+testSyntaxError(String.raw`var [a, ...b, c] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`var [a, ...b,] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`var [a, ...b,,] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`var [a, ...b = 20] = 20`, String.raw`SyntaxError: Unexpected token '='. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`var [a, ...[b, c]] = 20`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
+testSyntaxError(String.raw`var [a, ...{ b, c }] = 20`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
+
+testSyntaxError(String.raw`(function ([a, ...b, c]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`(function ([a, ...b,]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`(function ([a, ...b,,]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`(function ([a, ...b = 20,,]) { })`, String.raw`SyntaxError: Unexpected token '='. Expected a closing ']' following a rest element destructuring pattern.`);
+testSyntaxError(String.raw`(function ([a, ...[b, c]]) { })`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
+testSyntaxError(String.raw`(function ([a, ...{ b, c }]) { })`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
+
+shouldThrow(function () {
+    [a, ...b, c] = 20;
+}, "ReferenceError: Left side of assignment is not a reference.");
+
+shouldThrow(function () {
+    [a, ...b,] = 20
+}, "ReferenceError: Left side of assignment is not a reference.");
+
+shouldThrow(function () {
+    [a, ...b,,] = 20
+}, "ReferenceError: Left side of assignment is not a reference.");
+
+shouldThrow(function () {
+    [a, ...b = 20] = 20
+}, "ReferenceError: Left side of assignment is not a reference.");
+
+(function () {
+    var a, b, c;
+    [a, b, ...[...c]] = "Cocoa";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
+}());
+
+(function () {
+    var a, b, c, d, e, f;
+    [a, b, ...{ 0: c, 1: d, 2: e, 3: f }] = "Cocoa";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(c, 'c');
+    shouldBe(d, 'o');
+    shouldBe(f, undefined);
+}());
+
+(function () {
+    var a, b, c, d, e;
+    [a, b, ...[c, d, ...e]] = "Cocoa";
+    shouldBe(a, 'C');
+    shouldBe(b, 'o');
+    shouldBe(c, 'c');
+    shouldBe(d, 'o');
+    shouldBe(JSON.stringify(e), String.raw`["a"]`);
+}());
+
+function iterator(array) {
+    var nextCount = 0;
+    var returnCount = 0;
+    var original =  array.values();
+    return {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        next() {
+            ++nextCount;
+            return original.next();
+        },
+
+        return() {
+            ++returnCount;
+            return { done: true };
+        },
+
+        reportNext() {
+            return nextCount;
+        },
+
+        reportReturn() {
+            return returnCount;
+        }
+    };
+};
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [...a] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+    shouldBe(JSON.stringify(a), String.raw`[1,2,3]`);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [a, b, ...c] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(JSON.stringify(c), String.raw`[3]`);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [a, b, c, d, ...e] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+    shouldBe(c, 3);
+    shouldBe(d, undefined);
+    shouldBe(JSON.stringify(e), String.raw`[]`);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var a, b;
+    [...[a, b]] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+}());
diff --git a/tests/stress/scoped-arguments-array-length.js b/tests/stress/scoped-arguments-array-length.js
new file mode 100644 (file)
index 0000000..3217bd3
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(a) {
+    var result = 0;
+    if (!a)
+        return function() { return a };
+    for (var i = 0; i < arguments.length; ++i)
+        result += arguments[i];
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42, i);
+    if (result != 42 + i)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/scoped-then-direct-arguments-get-by-val-in-baseline.js b/tests/stress/scoped-then-direct-arguments-get-by-val-in-baseline.js
new file mode 100644 (file)
index 0000000..7c82104
--- /dev/null
@@ -0,0 +1,30 @@
+function direct() {
+    return arguments;
+}
+
+function scoped(a) {
+    if (!effectful42())
+        return function() { return a; }
+    return arguments;
+}
+
+function foo(a) {
+    try {
+        return a[0];
+    } catch (e) {
+        return -23;
+    }
+}
+
+for (var i = 0; i < 100; ++i) {
+    var result = foo(scoped(42));
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+for (var i = 0; i < 100; ++i) {
+    var result = foo(direct(42));
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/set-constructor-adder.js b/tests/stress/set-constructor-adder.js
new file mode 100644 (file)
index 0000000..c69ae91
--- /dev/null
@@ -0,0 +1,34 @@
+// Set constructor with adder change.
+
+var originalAdder = Set.prototype.add;
+var counter = 0;
+
+Set.prototype.add = function (value) {
+    counter++;
+    return originalAdder.call(this, value);
+};
+
+var values = [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0];
+var set = new Set(values);
+if (set.size !== 6)
+    throw "Error: bad set size " + set.size;
+if (counter !== values.length)
+    throw "Error: bad counter " + counter;
+
+Set.prototype.add = function () {
+    throw new Error("adder called");
+};
+
+var set = new Set();
+var set = new Set([]);
+var error = null;
+try {
+    var set = new Set([0]);
+} catch (e) {
+    error = e;
+}
+if (!error)
+    throw "Error: error not thrown";
+if (String(error) !== "Error: adder called")
+    throw "Error: bad error " + String(error);
+
diff --git a/tests/stress/set-constructor.js b/tests/stress/set-constructor.js
new file mode 100644 (file)
index 0000000..c14e854
--- /dev/null
@@ -0,0 +1,69 @@
+// Set constructor behaviors.
+
+if (typeof Set !== 'function')
+    throw "Error: bad value" + typeof Set;
+
+function testCallTypeError(item) {
+    var error = null;
+    try {
+        var set = Set(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (String(error) !== "TypeError: Set cannot be called as a function")
+        throw "Error: bad error " + String(error);
+}
+
+var pass = [
+    [ null, 0 ],
+    [ undefined, 0 ],
+    [ "Cocoa", 4 ],
+    [ [0, 1, 2, 3, 4], 5 ],
+    [ [0, 0, 0, 1, 0], 2 ],
+    [ ["A", "B", "A"], 2 ],
+    [ new String("cocoa"), 3 ],
+    [ new String("Cocoa"), 4 ],
+    [ new Set([0,1,2,3,4]), 5],
+    [ new Set([1,1,1,1]), 1],
+    [ new Map([[1, 2],[1, 2]]), 1],
+    [ new Map([[1, 2],[2, 2]]), 2],
+];
+
+for (var pair of pass) {
+    var set = new Set(pair[0]);
+    if (set.size !== pair[1])
+        throw "Error: bad set size " + set.size;
+    testCallTypeError(pair[0]);
+}
+
+function testTypeError(item) {
+    var error = null;
+    try {
+        var set = new Set(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (String(error) !== "TypeError: Type error")
+        throw "Error: bad error " + String(error);
+}
+
+var nonIterable = [
+    42,
+    Symbol("Cappuccino"),
+    true,
+    false,
+    {},
+    new Date(),
+    new Error(),
+    Object(Symbol("Matcha")),
+    (function () { }),
+];
+
+for (var item of nonIterable) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
diff --git a/tests/stress/set-iterators-next.js b/tests/stress/set-iterators-next.js
new file mode 100644 (file)
index 0000000..a0e4165
--- /dev/null
@@ -0,0 +1,115 @@
+// This test checks the behavior of the iterator.next methods on Set objects
+
+var testArray = [1,2,3,4,5,6]
+var testSet = new Set();
+for (var [key, value] of testArray.entries()) {
+    testSet.add(value);
+}
+var keys = testSet.keys();
+var i = 0;
+while (true) {
+    var {done, value: key} = keys.next();
+    if (done)
+        break;
+    if (testArray.indexOf(key) === -1)
+        throw "Error: bad value: " + key;
+    i++;
+}
+
+if (testSet.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = keys.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var values = testSet.values();
+var i = 0;
+while (true) {
+    var {done, value} = values.next();
+    if (done)
+        break;
+    i++;
+    if (testArray.indexOf(value) === -1)
+        throw "Error: bad value: " + value;
+}
+
+if (testSet.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = values.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testSet.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (key !== value)
+        throw "Error: bad value: " + key + " " + value;
+    if (!testSet.has(value))
+        throw "Error: bad value: " + value;
+    if (!testSet.has(key))
+        throw "Error: bad value: " + key;
+    i++;
+    if (testArray.indexOf(value) === -1)
+        throw "Error: bad value: " + value + " " + i;
+} while (!done);
+
+if (testSet.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var entries = testSet.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (key !== value)
+        throw "Error: bad value: " + key + " " + value;
+    if (!testSet.has(key))
+        throw "Error: bad value: " + value;
+    i++;
+    if (i % 4 === 0)
+        testSet.add(100000 + i);
+} while (!done);
+
+if (testSet.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+function otherKey(key) {
+    return (key + 1) % testArray.length;
+}
+
+var entries = testSet.entries();
+var i = 0;
+do {
+    var {done, value: entry} = entries.next();
+    if (done)
+        break;
+    var [key, value] = entry;
+    if (!testSet.has(key))
+        throw "Error: bad value: " + value + " " + testSet.get(key);
+    i++;
+    if (i % 4 === 0)
+        testSet.delete(otherKey(key));
+} while (!done);
+
+if (testSet.size !== i)
+    throw "Error: bad value: " + i;
+
+var value = entries.next().value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
diff --git a/tests/stress/simplify-varargs-mandatory-minimum-smaller-than-limit.js b/tests/stress/simplify-varargs-mandatory-minimum-smaller-than-limit.js
new file mode 100644 (file)
index 0000000..df4a352
--- /dev/null
@@ -0,0 +1,15 @@
+function foo() { return 42; }
+
+function bar() { return foo.apply(this, arguments); }
+
+function baz() { return bar(1, 2, 3); }
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz();
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
+
+
diff --git a/tests/stress/singleton-scope-then-overwrite.js b/tests/stress/singleton-scope-then-overwrite.js
new file mode 100644 (file)
index 0000000..7f87304
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(a) {
+    var x = a + 1;
+    var f = function(a) {
+        return x + a;
+    };
+    noInline(f);
+    for (var i = 0; i < 10000; ++i) {
+        var result = f(i);
+        if (result != a + 1 + i)
+            throw "Error: bad result: " + result;
+    }
+    x = 999;
+    var result = f(1);
+    if (result != 999 + 1)
+        throw "Error: bad result: " + result;
+}
+
+noInline(foo);
+for (var i = 0; i < 3; ++i)
+    foo(42 + i);
diff --git a/tests/stress/singleton-scope-then-realloc-and-overwrite.js b/tests/stress/singleton-scope-then-realloc-and-overwrite.js
new file mode 100644 (file)
index 0000000..d15c579
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(a) {
+    var x = a + 1;
+    return function(a) {
+        return x + a;
+    };
+}
+
+var f = foo(42);
+noInline(f);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = f(i);
+    if (result != 42 + 1 + i)
+        throw "Error: bad result: " + result;
+}
+
+var f = foo(43);
+var result = f(1);
+if (result != 43 + 1 + 1)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/singleton-scope-then-realloc.js b/tests/stress/singleton-scope-then-realloc.js
new file mode 100644 (file)
index 0000000..a6e1dcc
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(a) {
+    var x = a + 1;
+    return function(a) {
+        return x += a;
+    };
+}
+
+var f = foo(42);
+noInline(f);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = f(1);
+    if (result != 42 + 1 + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var f = foo(43);
+var result = f(1);
+if (result != 43 + 1 + 1)
+    throw "Error: bad result: " + result;
diff --git a/tests/stress/sink-arguments-past-invalid-check-dfg.js b/tests/stress/sink-arguments-past-invalid-check-dfg.js
new file mode 100644 (file)
index 0000000..8ee2b25
--- /dev/null
@@ -0,0 +1,17 @@
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; }
+
+function foo() {
+    globalResult = 0;
+    +arguments;
+    return globalResult;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== 1)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/sink-arguments-past-invalid-check-int32-dfg.js b/tests/stress/sink-arguments-past-invalid-check-int32-dfg.js
new file mode 100644 (file)
index 0000000..fe645e8
--- /dev/null
@@ -0,0 +1,12 @@
+function foo() {
+    return isInt32(arguments);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== false)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/sink-arguments-past-invalid-check-int32.js b/tests/stress/sink-arguments-past-invalid-check-int32.js
new file mode 100644 (file)
index 0000000..93d6cb1
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(p) {
+    var result = 42;
+    var o = arguments;
+    if (p)
+        result = isInt32(o);
+    return result;
+}
+
+noInline(foo);
+
+var result = foo(true);
+if (result !== false)
+    throw "Error: bad result at beginning: " + result;
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false);
+    if (result !== 42)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== false)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-arguments-past-invalid-check-sneakier.js b/tests/stress/sink-arguments-past-invalid-check-sneakier.js
new file mode 100644 (file)
index 0000000..eb17c73
--- /dev/null
@@ -0,0 +1,37 @@
+function bar(o, p) {
+    var o2 = {f: 0};
+    if (p)
+        o2.f = o;
+    return +o2.f;
+}
+
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; };
+
+function foo(p, q) {
+    globalResult = 0;
+    var o = arguments;
+    if (p)
+        bar(o, q);
+    return globalResult;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i) {
+    bar(1, true);
+    bar({}, false);
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false, true);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-arguments-past-invalid-check.js b/tests/stress/sink-arguments-past-invalid-check.js
new file mode 100644 (file)
index 0000000..0317f94
--- /dev/null
@@ -0,0 +1,23 @@
+var globalResult;
+Object.prototype.valueOf = function() { globalResult = 1; }
+
+function foo(p) {
+    globalResult = 0;
+    var o = arguments;
+    if (p)
+        +o;
+    return globalResult;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-function-past-invalid-check-sneakier.js b/tests/stress/sink-function-past-invalid-check-sneakier.js
new file mode 100644 (file)
index 0000000..eff3483
--- /dev/null
@@ -0,0 +1,35 @@
+function bar(o, p) {
+    if (p)
+        return +o.f;
+    return 42;
+}
+
+var globalResult;
+Function.prototype.valueOf = function() { globalResult = 1; };
+
+function foo(p, q) {
+    globalResult = 0;
+    var o = function() { };
+    var o2 = {f: o};
+    if (p)
+        bar(o2, q);
+    return globalResult;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i)
+    bar({f:42}, true);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false, true);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-function-past-invalid-check-sneaky.js b/tests/stress/sink-function-past-invalid-check-sneaky.js
new file mode 100644 (file)
index 0000000..33d3ec9
--- /dev/null
@@ -0,0 +1,13 @@
+function foo(p) {
+    var o = function() { };
+    var q = {f: p ? o : 42};
+    var tmp = q.f + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+    foo(false);
+
+foo(true);
+
diff --git a/tests/stress/sink-object-past-invalid-check-int32.js b/tests/stress/sink-object-past-invalid-check-int32.js
new file mode 100644 (file)
index 0000000..7a20d4f
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(p) {
+    var result = 42;
+    var o = {};
+    if (p)
+        result = isInt32(o);
+    return result;
+}
+
+noInline(foo);
+
+var result = foo(true);
+if (result !== false)
+    throw "Error: bad result at end: " + result;
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false);
+    if (result !== 42)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== false)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-object-past-invalid-check-sneakier.js b/tests/stress/sink-object-past-invalid-check-sneakier.js
new file mode 100644 (file)
index 0000000..147df98
--- /dev/null
@@ -0,0 +1,32 @@
+function bar(o, p) {
+    if (p)
+        return +o.f;
+    return 42;
+}
+
+function foo(p, q) {
+    var result = 0;
+    var o = {valueOf: function() { result = 1; }};
+    var o2 = {f: o};
+    if (p)
+        bar(o2, q);
+    return result;
+}
+
+noInline(foo);
+
+foo(true, false);
+
+for (var i = 0; i < 10000; ++i)
+    bar({f:42}, true);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false, true);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true, true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-object-past-invalid-check-sneaky.js b/tests/stress/sink-object-past-invalid-check-sneaky.js
new file mode 100644 (file)
index 0000000..7b38cef
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(p) {
+    var result = 0;
+    var o = {valueOf: function() { result = 1; }};
+    var q = {f: p ? o : 42};
+    var tmp = q.f + 1;
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink-object-past-invalid-check.js b/tests/stress/sink-object-past-invalid-check.js
new file mode 100644 (file)
index 0000000..15daa89
--- /dev/null
@@ -0,0 +1,20 @@
+function foo(p) {
+    var result = 0;
+    var o = {valueOf:function() { result = 1; }};
+    if (p)
+        +o;
+    return result;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(false);
+    if (result !== 0)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(true);
+if (result !== 1)
+    throw "Error: bad result at end: " + result;
+
diff --git a/tests/stress/sink_checkstructure.js b/tests/stress/sink_checkstructure.js
new file mode 100644 (file)
index 0000000..2427a63
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(p, q) {
+    var o = {};
+    if (p) o.f = 42;
+    if (q) { o.f++; return o; }
+}
+noInline(foo);
+
+var expected = foo(false, true).f;
+
+for (var i = 0; i < 1000000; i++) {
+    foo(true, true);
+}
+
+var result = foo(false, true).f;
+
+if (!Object.is(result, expected))
+    throw "Error: expected " + expected + "; FTL produced " + result;
diff --git a/tests/stress/sort-array-with-undecided.js b/tests/stress/sort-array-with-undecided.js
new file mode 100644 (file)
index 0000000..4a00943
--- /dev/null
@@ -0,0 +1 @@
+new Array(100).sort(function(a, b) { return a - b; });
diff --git a/tests/stress/sparse_splice.js b/tests/stress/sparse_splice.js
new file mode 100644 (file)
index 0000000..6565dd4
--- /dev/null
@@ -0,0 +1,12 @@
+var myArray = Array();
+myArray[ 10000 ] = "a";
+myArray[ 10001 ] = "b";
+myArray[ 10002 ] = "c";
+
+// remove element at index 1001
+myArray.splice( 10001, 1 );
+
+if (myArray[10000] != "a")
+    throw "Splicing Error! start index changed";
+if (myArray[10001] != "c")
+    throw "Splicing Error! removed element not removed";
diff --git a/tests/stress/static-function-delete.js b/tests/stress/static-function-delete.js
new file mode 100644 (file)
index 0000000..66ccf01
--- /dev/null
@@ -0,0 +1,10 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+shouldBe(RegExp.prototype.hasOwnProperty('exec'), true);
+shouldBe(delete RegExp.prototype.exec, true);
+shouldBe(RegExp.prototype.hasOwnProperty('exec'), false);
+shouldBe(delete RegExp.prototype.exec, true);
+shouldBe(RegExp.prototype.hasOwnProperty('exec'), false);
diff --git a/tests/stress/static-function-put.js b/tests/stress/static-function-put.js
new file mode 100644 (file)
index 0000000..d47d5c8
--- /dev/null
@@ -0,0 +1,11 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+var exec = RegExp.prototype.exec;
+var nested = Object.create(RegExp.prototype);
+
+nested.exec = "Hello";
+shouldBe(nested.hasOwnProperty('exec'), true);
+shouldBe(nested.exec, "Hello");
+shouldBe(/hello/.exec, exec);
diff --git a/tests/stress/static-getter-delete.js b/tests/stress/static-getter-delete.js
new file mode 100644 (file)
index 0000000..c88ca0a
--- /dev/null
@@ -0,0 +1,47 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+// Before static functions (& accessors) are reified.
+shouldThrow(function () {
+    'use strict';
+    RegExp.prototype.multiline = 'ok';
+}, 'TypeError: Attempted to assign to readonly property.');
+
+(function () {
+    'use strict';
+    shouldBe(delete RegExp.prototype.global, true);
+    shouldBe(RegExp.prototype.hasOwnProperty('global'), false);
+    RegExp.prototype.global = 'hello'
+    shouldBe(RegExp.prototype.global, 'hello');
+}());
+
+// After static functions (& accessors) are reified.
+shouldThrow(function () {
+    'use strict';
+    RegExp.prototype.multiline = 'ok';
+}, 'TypeError: Attempted to assign to readonly property.');
+
+(function () {
+    'use strict';
+    shouldBe(delete RegExp.prototype.multiline, true);
+    shouldBe(RegExp.prototype.hasOwnProperty('multiline'), false);
+    RegExp.prototype.multiline = 'hello'
+    shouldBe(RegExp.prototype.multiline, 'hello');
+}());
diff --git a/tests/stress/static-getter-descriptors.js b/tests/stress/static-getter-descriptors.js
new file mode 100644 (file)
index 0000000..a53096d
--- /dev/null
@@ -0,0 +1,12 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'global');
+shouldBe(JSON.stringify(descriptor), '{"enumerable":false,"configurable":true}');
+
+shouldBe(descriptor.enumerable, false);
+shouldBe(descriptor.configurable, true);
+shouldBe(descriptor.set, undefined);
+shouldBe(typeof descriptor.get, 'function');
diff --git a/tests/stress/static-getter-enumeration.js b/tests/stress/static-getter-enumeration.js
new file mode 100644 (file)
index 0000000..c67fd15
--- /dev/null
@@ -0,0 +1,8 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var keys = Object.keys(/Cocoa/);
+
+shouldBe(JSON.stringify(keys.sort()), '[]');  // non enumerable
diff --git a/tests/stress/static-getter-get.js b/tests/stress/static-getter-get.js
new file mode 100644 (file)
index 0000000..1d6acfa
--- /dev/null
@@ -0,0 +1,22 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var reg1 = /Cocoa/gi;
+shouldBe(reg1.global, true);
+shouldBe(reg1.ignoreCase, true);
+shouldBe(reg1.multiline, false);
+shouldBe(reg1.source, 'Cocoa');
+
+var reg2 = /Cocoa/im;
+shouldBe(reg2.global, false);
+shouldBe(reg2.ignoreCase, true);
+shouldBe(reg2.multiline, true);
+shouldBe(reg2.source, 'Cocoa');
+
+var reg3 = /Cappuccino/gm;
+shouldBe(reg3.global, true);
+shouldBe(reg3.ignoreCase, false);
+shouldBe(reg3.multiline, true);
+shouldBe(reg3.source, 'Cappuccino');
diff --git a/tests/stress/static-getter-in-names.js b/tests/stress/static-getter-in-names.js
new file mode 100644 (file)
index 0000000..852a2e5
--- /dev/null
@@ -0,0 +1,7 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+shouldBe(JSON.stringify(Object.getOwnPropertyNames(RegExp.prototype).sort()), '["compile","constructor","exec","flags","global","ignoreCase","lastIndex","multiline","source","test","toString"]');
+shouldBe(JSON.stringify(Object.getOwnPropertyNames(/Cocoa/).sort()), '["lastIndex"]');
diff --git a/tests/stress/static-getter-names.js b/tests/stress/static-getter-names.js
new file mode 100644 (file)
index 0000000..0063089
--- /dev/null
@@ -0,0 +1,16 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var names = [
+    'global',
+    'ignoreCase',
+    'multiline',
+    'source',
+];
+
+for (var name of names) {
+    var descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, name);
+    shouldBe(descriptor.get.name, 'get ' + name);
+}
diff --git a/tests/stress/static-getter-put.js b/tests/stress/static-getter-put.js
new file mode 100644 (file)
index 0000000..aac8f4f
--- /dev/null
@@ -0,0 +1,38 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldThrow(function () {
+    'use strict';
+    RegExp.prototype.global = 'Cocoa';
+}, 'TypeError: Attempted to assign to readonly property.');
+
+// Twice.
+shouldThrow(function () {
+    'use strict';
+    RegExp.prototype.global = 'Cocoa';
+}, 'TypeError: Attempted to assign to readonly property.');
+
+(function () {
+    'use strict';
+    delete RegExp.prototype.global;
+    RegExp.prototype.global = 'Cocoa';
+    shouldBe(RegExp.prototype.global, 'Cocoa');
+    shouldBe(/Cappuccino/.global, 'Cocoa');
+}());
diff --git a/tests/stress/string-from-code-point.js b/tests/stress/string-from-code-point.js
new file mode 100644 (file)
index 0000000..093658f
--- /dev/null
@@ -0,0 +1,135 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error("bad value: " + String(actual));
+}
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+function toCodePoints(string) {
+    var result = [];
+    for (var codePoint of string) {
+        result.push(codePoint.codePointAt(0));
+    }
+    return result;
+}
+
+shouldBe(String.fromCodePoint(), "");
+shouldBe(String.fromCodePoint(0), "\0");
+shouldBe(String.fromCodePoint(0, 0), "\0\0");
+
+var tests = [
+    "",
+    "Hello",
+    "Cocoa",
+    "Cappuccino Cocoa",
+    "日本語",
+    "マルチバイト",
+    "吉野屋",
+    "𠮷野家",  // Contain a surrogate pair.
+];
+
+for (var test of tests) {
+    shouldBe(String.fromCodePoint.apply(String, toCodePoints(test)), test);
+}
+
+function passThrough(codePoint) {
+    var string = String.fromCodePoint(codePoint);
+    shouldBe(string.codePointAt(0), codePoint);
+}
+
+var numberTests = [
+    [ 0x10FFFF,  "\uDBFF\uDFFF" ],
+    [ 0x10FFFE,  "\uDBFF\uDFFE" ],
+    [ 0xFFFF,  "\uFFFF" ],
+    [ 0x10000,  "\uD800\uDC00" ],
+    [ 0x10001,  "\uD800\uDC01" ],
+    [ -0.0,  "\u0000" ],
+    [ 0xD800,  "\uD800" ],
+    [ 0xDC00,  "\uDC00" ],
+];
+
+for (var test of numberTests) {
+    shouldBe(String.fromCodePoint(test[0]), test[1]);
+}
+
+shouldBe(String.fromCodePoint(0xD800, 0xDC00).codePointAt(0), 0x10000);
+
+// Non-character code points.
+for (var i = 0; i < 17; ++i) {
+    var plane = 0x10000 * i;
+    passThrough(plane + 0xFFFE);
+    passThrough(plane + 0xFFFF);
+}
+
+for (var start = 0xFDD0; start <= 0xFDEF; ++start) {
+    passThrough(start);
+}
+
+var invalidTests = [
+    -1,
+    1.2,
+    1.5,
+    30.01,
+    -11.0,
+    NaN,
+    Number.Infinity,
+    -Number.Infinity,
+    0x10FFFF + 1,
+    0x7FFFFFFF,
+    0x7FFFFFFF + 1,
+    0xFFFFFFFF,
+    0xFFFFFFFF + 1,
+    0x100000000 + 32,  // String.fromCharCode(0x100000000 + 32) produces a space, but String.fromCodePoint should throw an error.
+    "Hello",
+    undefined,
+    {},
+];
+
+for (var test of invalidTests) {
+    shouldThrow(function () {
+        String.fromCodePoint(test);
+    }, "RangeError: Arguments contain a value that is out of range of code points");
+}
+
+// toNumber causes errors.
+shouldThrow(function () {
+    String.fromCodePoint(Symbol.iterator);
+}, "TypeError: Type error")
+
+var toNumberObject = {
+    valueOf() {
+        throw new Error("valueOf is called");
+    }
+};
+
+shouldThrow(function () {
+    String.fromCodePoint(toNumberObject);
+}, "Error: valueOf is called")
+
+shouldThrow(function () {
+    String.fromCodePoint(Symbol.iterator, toNumberObject);
+}, "TypeError: Type error")
+
+var convertAndPassTests = [
+    [ null, "\0" ],
+    [ [], "\0" ],
+    [ "0x41", "A" ],
+    [ "", "\0" ],
+    [ true, "\u0001" ],
+    [ false, "\u0000" ],
+];
+
+for (var test of convertAndPassTests) {
+    shouldBe(String.fromCodePoint(test[0]), test[1]);
+}
diff --git a/tests/stress/string-iterators.js b/tests/stress/string-iterators.js
new file mode 100644 (file)
index 0000000..f66b620
--- /dev/null
@@ -0,0 +1,212 @@
+// This test checks the behavior of the String iterator
+
+var testString = "Cocoa,Cappuccino";
+var stringIterator = testString[Symbol.iterator]();
+var stringIteratorPrototype = stringIterator.__proto__;
+var stringIteratorPrototypeNext = stringIteratorPrototype.next;
+
+if (stringIterator.hasOwnProperty('next'))
+    throw "next method should exists on %StringIteratorPrototype%";
+if (!stringIteratorPrototype.hasOwnProperty('next'))
+    throw "next method should exists on %StringIteratorPrototype%";
+
+var iterator = testString[Symbol.iterator]();
+var i = 0;
+while (true) {
+    var {done, value} = iterator.next();
+    if (done)
+        break;
+    if (value !== testString[i])
+        throw "Error: bad value: " + value;
+    i++;
+}
+
+if (testString.length !== i)
+    throw "Error: bad value: " + i;
+
+function testSurrogatePair(testString, expected, numberOfElements) {
+    if (testString.length !== numberOfElements)
+        throw "Error: bad value: " + testString.length;
+
+    var iterator = testString[Symbol.iterator]();
+    var i = 0;
+    while (true) {
+        var {done, value} = iterator.next();
+        if (done)
+            break;
+        if (value !== expected[i])
+            throw "Error: bad value: " + value;
+        i++;
+    }
+
+    if (i !== expected.length)
+        throw "Error: bad value: " + i;
+
+    for (var codePoint of testString) {
+        if (value !== expected[i])
+            throw "Error: bad value: " + value;
+    }
+}
+
+// "\uD842\uDFB7\u91ce\u5bb6"
+var testString = "𠮷野家";
+var expected = [
+    String.fromCharCode(0xD842, 0xDFB7),
+    String.fromCharCode(0x91CE),
+    String.fromCharCode(0x5BB6),
+];
+testSurrogatePair(testString, expected, 4);
+
+var testString = "A\uD842";
+var expected = [
+    String.fromCharCode(0x0041),
+    String.fromCharCode(0xD842),
+];
+testSurrogatePair(testString, expected, 2);
+
+var testString = "A\uD842A";
+var expected = [
+    String.fromCharCode(0x0041),
+    String.fromCharCode(0xD842),
+    String.fromCharCode(0x0041),
+];
+testSurrogatePair(testString, expected, 3);
+
+var testString = "A\uD842\uDFB7";
+var expected = [
+    String.fromCharCode(0x0041),
+    String.fromCharCode(0xD842, 0xDFB7),
+];
+testSurrogatePair(testString, expected, 3);
+
+var testString = "\uD842A\uDFB7";
+var expected = [
+    String.fromCharCode(0xD842),
+    String.fromCharCode(0x0041),
+    String.fromCharCode(0xDFB7),
+];
+testSurrogatePair(testString, expected, 3);
+
+var testString = "\uDFB7\uD842A";
+var expected = [
+    String.fromCharCode(0xDFB7),
+    String.fromCharCode(0xD842),
+    String.fromCharCode(0x0041),
+];
+testSurrogatePair(testString, expected, 3);
+
+var string1 = "Cocoa";
+var string1Iterator = string1[Symbol.iterator]();
+var index = 0;
+while (true) {
+    var result = stringIteratorPrototypeNext.call(string1Iterator);
+    var value = result.value;
+    if (result.done) {
+        break;
+    }
+    if (value !== string1[index++])
+        throw "Error: bad value: " + value;
+}
+if (index !== 5)
+    throw "Error: bad index: " + index;
+
+function increment(iter) {
+    return stringIteratorPrototypeNext.call(iter);
+}
+var string1 = "Cocoa";
+var string2 = "Cocoa";
+var string1Iterator = string1[Symbol.iterator]();
+var string2Iterator = string2[Symbol.iterator]();
+for (var i = 0; i < 3; ++i) {
+    var value1 = increment(string1Iterator).value;
+    var value2 = increment(string2Iterator).value;
+    if (value1 !== value2)
+        throw "Error: bad value: " + value1 + " " + value2;
+}
+
+var string1 = "Cappuccino";
+var string1Iterator = string1[Symbol.iterator]();
+
+var value = string1Iterator.next().value;
+if (value !== "C")
+    throw "Error: bad value: " + value;
+var value = string1Iterator.next().value;
+if (value !== "a")
+    throw "Error: bad value: " + value;
+var value = string1Iterator.next().value;
+if (value !== "p")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "p")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "u")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "c")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "c")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "i")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "n")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== "o")
+    throw "Error: bad value: " + value;
+var value = stringIteratorPrototypeNext.call(string1Iterator).value;
+if (value !== undefined)
+    throw "Error: bad value: " + value;
+
+var primitives = [
+    "string",
+    42,
+    0.03,
+    false,
+    true,
+    Symbol("Cocoa"),
+    null,
+    undefined
+];
+for (var primitive of primitives) {
+    var didThrow = null;
+    try {
+        stringIteratorPrototypeNext.call(primitive);
+    } catch (e) {
+        didThrow = e;
+    }
+    if (!didThrow)
+        throw "Error: no error thrown";
+    var message = 'TypeError: %StringIteratorPrototype%.next requires that |this| be a String Iterator instance';
+    if (primitive == null)
+        message = 'TypeError: %StringIteratorPrototype%.next requires that |this| not be null or undefined'
+    if (String(didThrow) !== message)
+        throw "Error: bad error thrown: " + didThrow;
+}
+
+var nonRelatedObjects = [
+    {},
+    [],
+    new Date(),
+    new Error(),
+    Object(Symbol()),
+    new String("Cappuccino"),
+    new Number(42),
+    new Boolean(false),
+    function () { },
+];
+for (var object of nonRelatedObjects) {
+    var didThrow = null;
+    try {
+        stringIteratorPrototypeNext.call(object);
+    } catch (e) {
+        didThrow = e;
+    }
+    if (!didThrow)
+        throw "Error: no error thrown";
+    if (String(didThrow) !== 'TypeError: %StringIteratorPrototype%.next requires that |this| be a String Iterator instance')
+        throw "Error: bad error thrown: " + didThrow;
+}
diff --git a/tests/stress/string-raw.js b/tests/stress/string-raw.js
new file mode 100644 (file)
index 0000000..17c769b
--- /dev/null
@@ -0,0 +1,154 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${actual}`);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldBe(String.raw.name, 'raw');
+shouldBe(String.raw.length, 1);
+
+shouldThrow(function () {
+    String.raw();
+}, "TypeError: String.raw requires template not be null or undefined");
+
+shouldThrow(function () {
+    String.raw(undefined);
+}, "TypeError: String.raw requires template not be null or undefined");
+
+shouldThrow(function () {
+    String.raw({ raw: undefined });
+}, "TypeError: String.raw requires template.raw not be null or undefined");
+
+shouldThrow(function () {
+    String.raw({ raw: null });
+}, "TypeError: String.raw requires template.raw not be null or undefined");
+
+shouldThrow(function () {
+    String.raw({
+        get length() {
+            return new Error('template.length called');
+        },
+
+        raw: {
+            get length() {
+                throw new Error("template.raw.length called");
+            }
+        }
+    });
+}, "Error: template.raw.length called");
+
+shouldBe(String.raw({
+    raw: {
+        length: -1
+    }
+}), "");
+
+shouldBe(String.raw({
+    raw: {
+        length: -2.5
+    }
+}), "");
+
+shouldBe(String.raw({
+    raw: {
+        length: -Infinity
+    }
+}), "");
+
+shouldBe(String.raw({
+    raw: {
+        length: 0
+    }
+}), "");
+
+shouldBe(String.raw({
+    raw: {
+        length: NaN
+    }
+}), "");
+
+function generateTemplate() {
+    var cooked = [];
+    cooked.raw = Array.from(arguments);
+    return cooked;
+}
+
+shouldBe(String.raw(generateTemplate("", ",", ",", ""), "Cocoa", "Cappuccino", "Matcha"), "Cocoa,Cappuccino,Matcha");
+shouldBe(String.raw(generateTemplate("", ",", ",", ""), "Cocoa", "Cappuccino", "Matcha", "Hello"), "Cocoa,Cappuccino,Matcha");
+shouldBe(String.raw(generateTemplate("", ",", ",", ""), "Cocoa", "Cappuccino"), "Cocoa,Cappuccino,");
+shouldBe(String.raw(generateTemplate("", ",", ",", ""), "Cocoa"), "Cocoa,,");
+shouldBe(String.raw(generateTemplate("", ",", ",", "")), ",,");
+
+function Counter(p) {
+    var count = 0;
+    return {
+        toString() {
+            return count++;
+        }
+    };
+}
+
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter)), "0123");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter), "01234");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter, counter), "012345");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter, counter, counter), "0123456");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter, counter, counter, counter), "0123456");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter, counter, counter, counter), "0123456");
+var counter = Counter();
+shouldBe(String.raw(generateTemplate(counter, counter, counter, counter), counter, counter, counter, counter, counter), "0123456");
+
+
+shouldBe(String.raw({
+    raw: {
+        length: 3.5,
+        0: "a",
+        1: "b",
+        2: "c"
+    }
+}, "d", "e", "f", "g"), "adbec");
+
+shouldBe(String.raw({
+    raw: {
+        length: 2.3,
+        0: "a",
+        1: "b",
+        2: "c"
+    }
+}, "d", "e", "f", "g"), "adb");
+
+shouldBe(String.raw({
+    raw: {
+        length: 2.3,
+        0: "a",
+        2: "c"
+    }
+}, "d", "e", "f", "g"), "adundefined");
+
+shouldBe(String.raw({
+    raw: {
+        length: 2.3,
+        0: "a",
+        1: "b",
+        2: "c"
+    }
+}, undefined, "e", "f", "g"), "aundefinedb");
diff --git a/tests/stress/sub-overflows-after-not-equal.js b/tests/stress/sub-overflows-after-not-equal.js
new file mode 100644 (file)
index 0000000..06c62ee
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(a) {
+    if (a != 0)
+        return a - 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42);
+    if (result != 41)
+        throw "Error: bad result in loop: " + result;
+}
+
+var result = foo(-2147483648);
+if (result != -2147483649)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/switch-typeof-indirect.js b/tests/stress/switch-typeof-indirect.js
new file mode 100644 (file)
index 0000000..392b94b
--- /dev/null
@@ -0,0 +1,41 @@
+function bar(value) {
+    return typeof value;
+}
+noInline(bar);
+
+function foo(value) {
+    switch (bar(value)) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}
diff --git a/tests/stress/switch-typeof-slightly-indirect.js b/tests/stress/switch-typeof-slightly-indirect.js
new file mode 100644 (file)
index 0000000..291f2a7
--- /dev/null
@@ -0,0 +1,39 @@
+function foo(value) {
+    var t = typeof value;
+    if (!t)
+        return -1;
+    switch (t) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}
diff --git a/tests/stress/switch-typeof.js b/tests/stress/switch-typeof.js
new file mode 100644 (file)
index 0000000..90c374b
--- /dev/null
@@ -0,0 +1,36 @@
+function foo(value) {
+    switch (typeof value) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}
diff --git a/tests/stress/symbol-and-string-constructor.js b/tests/stress/symbol-and-string-constructor.js
new file mode 100644 (file)
index 0000000..4a88e86
--- /dev/null
@@ -0,0 +1,10 @@
+function performString(value) {
+    return String(value);
+}
+noInline(performString);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = performString(Symbol.iterator);
+    if (result !== 'Symbol(Symbol.iterator)')
+        throw new Error('bad value: ' + result);
+}
diff --git a/tests/stress/symbol-define-property.js b/tests/stress/symbol-define-property.js
new file mode 100644 (file)
index 0000000..bac3ec0
--- /dev/null
@@ -0,0 +1,33 @@
+// This tests Object.create, Object.defineProperty, Object.defineProperties work with Symbol.
+
+function testSymbol(object) {
+    if (!object.hasOwnProperty(Symbol.iterator))
+        throw "Error: object doesn't have Symbol.iterator";
+    if (object.propertyIsEnumerable(Symbol.iterator))
+        throw "Error: Symbol.iterator is defined as enumerable";
+    if (JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator)) !== '{"value":42,"writable":false,"enumerable":false,"configurable":false}')
+        throw "Error: bad property descriptor " + JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator));
+    if (Object.getOwnPropertySymbols(object).length !== 1)
+    throw "Error: bad value " + Object.getOwnPropertySymbols(object).length;
+    if (Object.getOwnPropertySymbols(object)[0] !== Symbol.iterator)
+        throw "Error: bad value " + String(Object.getOwnPropertySymbols(object)[0]);
+}
+
+var object = Object.create(Object.prototype, {
+    [Symbol.iterator]: {
+        value: 42
+    }
+});
+testSymbol(object);
+
+var object = Object.defineProperties({}, {
+    [Symbol.iterator]: {
+        value: 42
+    }
+});
+testSymbol(object);
+
+var object = Object.defineProperty({}, Symbol.iterator, {
+    value: 42
+});
+testSymbol(object);
diff --git a/tests/stress/symbol-registry.js b/tests/stress/symbol-registry.js
new file mode 100644 (file)
index 0000000..8a1a05a
--- /dev/null
@@ -0,0 +1,125 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error("bad value: " + actual);
+}
+
+(function () {
+    var hello = Symbol("Hello");
+    var proto = Symbol("__proto__");
+
+    for (var sym of [ hello, proto, Symbol.iterator ]) {
+        var key = Symbol.keyFor(sym);
+        test(key, undefined);
+        // twice
+        var key = Symbol.keyFor(sym);
+        test(key, undefined);
+    }
+}());
+
+(function () {
+    var keys = [
+        "Hello",
+        "__proto__",
+        "Symbol.iterator",
+        '',
+        null,
+        undefined,
+        42,
+        20.5,
+        -42,
+        -20.5,
+        true,
+        false,
+        {},
+        function () {},
+        [],
+    ];
+    for (var key of keys) {
+        var sym = Symbol.for(key);
+        test(typeof sym, "symbol");
+        test(sym.toString(), "Symbol(" + String(key) + ")");
+
+        var sym2 = Symbol.for(key);
+        test(sym === sym2, true);
+
+        var key = Symbol.keyFor(sym);
+        test(key, key);
+        var key = Symbol.keyFor(sym2);
+        test(key, key);
+    }
+}());
+
+(function () {
+    var error = null;
+    try {
+        var key = {
+            toString() {
+                throw new Error('toString');
+            }
+        };
+        Symbol.for(key);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('not thrown');
+    if (String(error) !== 'Error: toString')
+        throw new Error('bad error: ' + String(error));
+}());
+
+(function () {
+    var elements = [
+        null,
+        undefined,
+        42,
+        20.5,
+        true,
+        false,
+        'string',
+        {},
+        function () {},
+        [],
+    ];
+    for (var item of elements) {
+        var error = null;
+        try {
+            Symbol.keyFor(item);
+        } catch (e) {
+            error = e;
+        }
+        if (!error)
+            throw new Error('not thrown');
+        if (String(error) !== 'TypeError: Type error')
+            throw new Error('bad error: ' + String(error));
+    }
+}());
+
+(function () {
+    for (var i = 0; i < 10000; ++i)
+        Symbol.for(i);
+    gc();
+}());
+
+(function () {
+    for (var i = 0; i < 100; ++i) {
+        var symbol = Symbol.for(i);
+        test(String(symbol), "Symbol(" + i + ")");
+        test(symbol, Symbol.for(i));
+        gc();
+    }
+    gc();
+}());
+
+(function () {
+    var symbols = [];
+    for (var i = 0; i < 100; ++i) {
+        var symbol = Symbol.for(i);
+        symbols.push(symbol);
+    }
+
+    for (var i = 0; i < 100; ++i)
+        test(Symbol.for(i), symbols[i]);
+
+    for (var i = 0; i < 100; ++i)
+        test(Symbol.keyFor(Symbol(i)), undefined);
+}());
diff --git a/tests/stress/symbol-seal-and-freeze.js b/tests/stress/symbol-seal-and-freeze.js
new file mode 100644 (file)
index 0000000..4f507cd
--- /dev/null
@@ -0,0 +1,26 @@
+// This tests Object.seal and Object.freeze affect on Symbol properties.
+
+var object = {
+    [Symbol.iterator]: 42
+};
+
+if (!object.hasOwnProperty(Symbol.iterator))
+    throw "Error: object doesn't have Symbol.iterator";
+if (JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator)) !== '{"value":42,"writable":true,"enumerable":true,"configurable":true}')
+    throw "Error: bad property descriptor " + JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator));
+if (Object.getOwnPropertySymbols(object).length !== 1)
+    throw "Error: bad value " + Object.getOwnPropertySymbols(object).length;
+if (Object.getOwnPropertySymbols(object)[0] !== Symbol.iterator)
+    throw "Error: bad value " + String(Object.getOwnPropertySymbols(object)[0]);
+
+Object.seal(object);
+if (!object.hasOwnProperty(Symbol.iterator))
+    throw "Error: object doesn't have Symbol.iterator";
+if (JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator)) !== '{"value":42,"writable":true,"enumerable":true,"configurable":false}')
+    throw "Error: bad property descriptor " + JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator));
+
+Object.freeze(object);
+if (!object.hasOwnProperty(Symbol.iterator))
+    throw "Error: object doesn't have Symbol.iterator";
+if (JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator)) !== '{"value":42,"writable":false,"enumerable":true,"configurable":false}')
+    throw "Error: bad property descriptor " + JSON.stringify(Object.getOwnPropertyDescriptor(object, Symbol.iterator));
diff --git a/tests/stress/symbol-with-json.js b/tests/stress/symbol-with-json.js
new file mode 100644 (file)
index 0000000..3c03d5d
--- /dev/null
@@ -0,0 +1,14 @@
+// This tests JSON correctly behaves with Symbol.
+
+if (JSON.stringify(Symbol('Cocoa')) !== undefined)
+    throw "Error: bad value " + JSON.stringify(Symbol('Cocoa'));
+
+var object = {};
+var symbol = Symbol("Cocoa");
+object[symbol] = 42;
+object['Cappuccino'] = 42;
+if (JSON.stringify(object) !== '{"Cappuccino":42}')
+    throw "Error: bad value " + JSON.stringify(object);
+
+if (JSON.stringify(object, [ Symbol('Cocoa') ]) !== "{}")
+    throw "Error: bad value " + JSON.stringify(object, [ Symbol('Cocoa') ]);
diff --git a/tests/stress/tagged-templates-identity.js b/tests/stress/tagged-templates-identity.js
new file mode 100644 (file)
index 0000000..302d031
--- /dev/null
@@ -0,0 +1,59 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + JSON.stringify(actual));
+}
+
+var templates = [];
+function tag(siteObject) {
+    templates.push(siteObject);
+}
+
+tag`Hello`;
+tag`World`;
+tag`Hello`;
+shouldBe(templates.length, 3);
+shouldBe(templates[0] !== templates[1], true);
+shouldBe(templates[0] === templates[2], true);
+
+templates = [];
+tag`Hello\n`;
+tag`Hello\r`;
+tag`Hello\u2028`;
+shouldBe(templates.length, 3);
+shouldBe(templates[0] !== templates[1], true);
+shouldBe(templates[0] !== templates[2], true);
+
+templates = [];
+eval("tag`Hello\n`");
+eval("tag`Hello\r`");
+eval("tag`Hello\u2028`");
+shouldBe(templates.length, 3);
+shouldBe(templates[0] === templates[1], true);
+shouldBe(templates[0] !== templates[2], true);
+
+templates = [];
+eval("tag`Hello\n`");
+eval("tag`Hello\\n`");
+eval("tag`Hello\r`");
+eval("tag`Hello\\r`");
+shouldBe(templates.length, 4);
+shouldBe(templates[0] !== templates[1], true);
+shouldBe(templates[0] === templates[2], true);
+shouldBe(templates[0] !== templates[3], true);
+shouldBe(templates[1] !== templates[2], true);
+shouldBe(templates[1] !== templates[3], true);
+shouldBe(templates[2] !== templates[3], true);
+
+var v = 0;
+templates = [];
+eval("tag`Hello\n${v}world`");
+eval("tag`Hello\n${v}world`");
+shouldBe(templates.length, 2);
+shouldBe(templates[0] === templates[1], true);
+
+var v = 0;
+templates = [];
+eval("tag`Hello${v}\nworld`");
+eval("tag`Hello\n${v}world`");
+shouldBe(templates.length, 2);
+shouldBe(templates[0] !== templates[1], true);
diff --git a/tests/stress/tagged-templates-raw-strings.js b/tests/stress/tagged-templates-raw-strings.js
new file mode 100644 (file)
index 0000000..1d95785
--- /dev/null
@@ -0,0 +1,63 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + JSON.stringify(actual));
+}
+
+function tag(results) {
+    return function (siteObject) {
+        shouldBe(siteObject.raw.length, results.length);
+        for (var i = 0; i < siteObject.raw.length; ++i) {
+            shouldBe(siteObject.raw[i], results[i]);
+        }
+    };
+}
+
+tag([''])``;
+tag(['hello'])`hello`;
+tag(['hello', 'world'])`hello${0}world`;
+tag(['hello\\u2028', 'world'])`hello\u2028${0}world`;
+tag(['hello\\u2028\\u2029', 'world'])`hello\u2028\u2029${0}world`;
+tag(['hello\\n\\r', 'world'])`hello\n\r${0}world`;
+
+function testEval(content, results) {
+    var split = 0;
+    var g = tag(results);
+    eval("g`" + content + "`");
+}
+
+for (var ch of [ '\'', '"', '\\', 'b', 'f', 'n', 'r', 't', 'v' ])
+    testEval("\\" + ch, ["\\" + ch]);
+
+var evaluated = [];
+for (var i = 0; i < 0x10000; ++i) {
+    var code = i.toString(16);
+    var input = "\\u" + '0'.repeat(4 - code.length) + code;
+    evaluated.push(input);
+}
+testEval(evaluated.join('${split}'), evaluated)
+
+testEval("Hello\rWorld", [ "Hello\nWorld" ]);
+testEval("Hello\nWorld", [ "Hello\nWorld" ]);
+
+testEval("Hello\r\rWorld", [ "Hello\n\nWorld" ]);
+testEval("Hello\r\nWorld", [ "Hello\nWorld" ]);
+testEval("Hello\n\nWorld", [ "Hello\n\nWorld" ]);
+testEval("Hello\n\rWorld", [ "Hello\n\nWorld" ]);
+
+testEval("Hello\n\r\nWorld", [ "Hello\n\nWorld" ]);
+testEval("Hello\r\n\rWorld", [ "Hello\n\nWorld" ]);
+testEval("Hello\n\n\nWorld", [ "Hello\n\n\nWorld" ]);
+
+testEval("Hello\n\r\n\rWorld", [ "Hello\n\n\nWorld" ]);
+testEval("Hello\n\r\n\nWorld", [ "Hello\n\n\nWorld" ]);
+testEval("Hello\r\n\n\nWorld", [ "Hello\n\n\nWorld" ]);
+
+testEval("Hello\\\n\r\rWorld", [ "Hello\\\n\n\nWorld" ]);
+testEval("Hello\\\r\n\n\nWorld", [ "Hello\\\r\n\n\nWorld" ]);
+testEval("Hello\\\n\r\n\nWorld", [ "Hello\\\n\n\nWorld" ]);
+testEval("Hello\\\n\r\r\nWorld", [ "Hello\\\n\n\nWorld" ]);
+
+testEval("\u2028", [ "\u2028" ]);
+testEval("\u2029", [ "\u2029" ]);
+testEval("\\u2028", [ "\\u2028" ]);
+testEval("\\u2029", [ "\\u2029" ]);
diff --git a/tests/stress/tagged-templates-syntax.js b/tests/stress/tagged-templates-syntax.js
new file mode 100644 (file)
index 0000000..c199bac
--- /dev/null
@@ -0,0 +1,70 @@
+function tag() {
+}
+
+function testSyntax(script) {
+    try {
+        eval(script);
+    } catch (error) {
+        if (error instanceof SyntaxError)
+            throw new Error("Bad error: " + String(error));
+    }
+}
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown");
+
+    if (String(error) !== message)
+        throw new Error("Bad error: " + String(error));
+}
+
+testSyntax("tag``");
+testSyntax("tag`Hello`");
+testSyntax("tag`Hello${tag}`");
+testSyntax("tag`${tag}`");
+testSyntax("tag`${tag} ${tag}`");
+testSyntax("tag`${tag}${tag}`");
+
+testSyntax("tag.prop``");
+testSyntax("tag.prop`Hello`");
+testSyntax("tag.prop`Hello${tag}`");
+testSyntax("tag.prop`${tag}`");
+testSyntax("tag.prop`${tag} ${tag}`");
+testSyntax("tag.prop`${tag}${tag}`");
+
+testSyntax("tag[prop]``");
+testSyntax("tag[prop]`Hello`");
+testSyntax("tag[prop]`Hello${tag}`");
+testSyntax("tag[prop]`${tag}`");
+testSyntax("tag[prop]`${tag} ${tag}`");
+testSyntax("tag[prop]`${tag}${tag}`");
+
+testSyntax("(tag())``");
+testSyntax("(tag())`Hello`");
+testSyntax("(tag())`Hello${tag}`");
+testSyntax("(tag())`${tag}`");
+testSyntax("(tag())`${tag} ${tag}`");
+testSyntax("(tag())`${tag}${tag}`");
+
+testSyntax("(class { say() { super.tag`` } })");
+testSyntax("(class { say() { super.tag`Hello` } })");
+testSyntax("(class { say() { super.tag`Hello${tag}` } })");
+testSyntax("(class { say() { super.tag`${tag}` } })");
+testSyntax("(class { say() { super.tag`${tag} ${tag}` } })");
+testSyntax("(class { say() { super.tag`${tag}${tag}` } })");
+
+testSyntax("(class extends Hello { constructor() { super()`` } })");
+testSyntax("(class extends Hello { constructor() { super()`Hello` } })");
+testSyntax("(class extends Hello { constructor() { super()`Hello${tag}` } })");
+testSyntax("(class extends Hello { constructor() { super()`${tag}` } })");
+testSyntax("(class extends Hello { constructor() { super()`${tag} ${tag}` } })");
+testSyntax("(class extends Hello { constructor() { super()`${tag}${tag}` } })");
+
+testSyntaxError("super`Hello${tag}`", "SyntaxError: Cannot use super as tag for tagged templates.");
+testSyntaxError("(class { say() { super`Hello${tag}` } })", "SyntaxError: Cannot use super as tag for tagged templates.");
diff --git a/tests/stress/tagged-templates-template-object.js b/tests/stress/tagged-templates-template-object.js
new file mode 100644 (file)
index 0000000..b805de9
--- /dev/null
@@ -0,0 +1,43 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function tag(elements) {
+    return function (siteObject) {
+        shouldBe(siteObject instanceof Array, true);
+        shouldBe(Object.isFrozen(siteObject), true);
+        shouldBe(siteObject.raw instanceof Array, true);
+        shouldBe(Object.isFrozen(siteObject.raw), true);
+        shouldBe(siteObject.hasOwnProperty("raw"), true);
+        shouldBe(siteObject.propertyIsEnumerable("raw"), false);
+        shouldBe(siteObject.length, arguments.length);
+        shouldBe(siteObject.raw.length, arguments.length);
+        var count = siteObject.length;
+        for (var i = 0; i < count; ++i) {
+            shouldBe(siteObject.hasOwnProperty(i), true);
+            var desc = Object.getOwnPropertyDescriptor(siteObject, i);
+            shouldBe(desc.writable, false);
+            shouldBe(desc.enumerable, true);
+            shouldBe(desc.configurable, false);
+        }
+        shouldBe(siteObject.length, elements.length + 1);
+        for (var i = 0; i < elements.length; ++i)
+            shouldBe(arguments[i + 1], elements[i]);
+    };
+}
+
+var value = {
+    toString() {
+        throw new Error('incorrect');
+    },
+    valueOf() {
+        throw new Error('incorrect');
+    }
+};
+
+tag([])``;
+tag([])`Hello`;
+tag([])`Hello World`;
+tag([value])`Hello ${value} World`;
+tag([value, value])`Hello ${value} OK, ${value}`;
diff --git a/tests/stress/tagged-templates-this.js b/tests/stress/tagged-templates-this.js
new file mode 100644 (file)
index 0000000..24a5992
--- /dev/null
@@ -0,0 +1,26 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function tag() {
+    "use strict";
+    return this;
+}
+
+var object = {
+    tag() {
+        'use strict';
+        return this;
+    }
+};
+
+shouldBe(tag`Hello`, undefined);
+shouldBe((function () { return tag }())`Hello`, undefined);
+shouldBe(object.tag`Hello`, object);
+shouldBe(object['tag']`Hello`, object);
+shouldBe(object[(function () { return 'tag'; }())]`Hello`, object);
+
+with (object) {
+    shouldBe(tag`Hello`, object);
+}
diff --git a/tests/stress/tagged-templates.js b/tests/stress/tagged-templates.js
new file mode 100644 (file)
index 0000000..eb714bf
--- /dev/null
@@ -0,0 +1,67 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + JSON.stringify(actual));
+}
+
+function raw(siteObject) {
+    var result = '';
+    for (var i = 0; i < siteObject.raw.length; ++i) {
+        result += siteObject.raw[i];
+        if ((i + 1) < arguments.length) {
+            result += arguments[i + 1];
+        }
+    }
+    return result;
+}
+
+function cooked(siteObject) {
+    var result = '';
+    for (var i = 0; i < siteObject.raw.length; ++i) {
+        result += siteObject[i];
+        if ((i + 1) < arguments.length) {
+            result += arguments[i + 1];
+        }
+    }
+    return result;
+}
+
+function Counter() {
+    var count = 0;
+    return {
+        toString() {
+            return count++;
+        }
+    };
+}
+
+var c = Counter();
+shouldBe(raw`Hello ${c} World ${c}`, `Hello 0 World 1`);
+var c = Counter();
+shouldBe(raw`${c}${c}${c}`, `012`);
+var c = Counter();
+shouldBe(raw`${c}${ `  ${c}  ` }${c}`, `1  0  2`);
+var c = Counter();
+shouldBe(raw`${c}${ raw`  ${c}  ` }${c}`, `1  0  2`);
+var c = Counter();
+shouldBe(raw`${c}${ `  ${c}${c}  ` }${c}`, `2  01  3`);
+var c = Counter();
+shouldBe(raw`${c}${ raw`  ${c}${c}  ` }${c}`, `2  01  3`);
+
+shouldBe(raw``, ``);
+shouldBe(cooked``, ``);
+shouldBe(raw`\n`, `\\n`);
+shouldBe(cooked`\n`, `\n`);
+shouldBe(raw`\v`, `\\v`);
+shouldBe(cooked`\v`, `\v`);
+shouldBe(raw`
+
+`, `\n\n`);
+shouldBe(cooked`
+
+`, `\n\n`);
+shouldBe(raw`\
+\
+`, `\\\n\\\n`);
+shouldBe(cooked`\
+\
+`, ``);
diff --git a/tests/stress/template-literal-line-terminators.js b/tests/stress/template-literal-line-terminators.js
new file mode 100644 (file)
index 0000000..019a1f9
--- /dev/null
@@ -0,0 +1,57 @@
+
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error("bad value: " + actual);
+}
+
+function testEval(script, expected) {
+    test(eval(script), expected);
+}
+
+function testEvalLineNumber(script, expected, lineNum) {
+    testEval(script, expected);
+
+    var error = null;
+    var actualLine;
+    try {
+        eval(script + ';throw new Error("line");');
+    } catch (error) {
+        actualLine = error.line;
+    }
+    test(actualLine, lineNum);
+}
+
+test(`Hello`, "Hello");
+test(`Hello World`, "Hello World");
+test(`
+`, "\n");
+test(`Hello
+World`, "Hello\nWorld");
+
+testEvalLineNumber("`Hello World`", "Hello World", 1);
+
+testEvalLineNumber("`Hello\rWorld`", "Hello\nWorld", 2);
+testEvalLineNumber("`Hello\nWorld`", "Hello\nWorld", 2);
+
+testEvalLineNumber("`Hello\r\rWorld`", "Hello\n\nWorld", 3);
+testEvalLineNumber("`Hello\r\nWorld`", "Hello\nWorld", 2);
+testEvalLineNumber("`Hello\n\nWorld`", "Hello\n\nWorld", 3);
+testEvalLineNumber("`Hello\n\rWorld`", "Hello\n\nWorld", 2);
+
+testEvalLineNumber("`Hello\n\r\nWorld`", "Hello\n\nWorld", 3);
+testEvalLineNumber("`Hello\r\n\rWorld`", "Hello\n\nWorld", 3);
+testEvalLineNumber("`Hello\n\n\nWorld`", "Hello\n\n\nWorld", 4);
+
+testEvalLineNumber("`Hello\n\r\n\rWorld`", "Hello\n\n\nWorld", 3);
+testEvalLineNumber("`Hello\n\r\n\nWorld`", "Hello\n\n\nWorld", 4);
+testEvalLineNumber("`Hello\r\n\n\nWorld`", "Hello\n\n\nWorld", 4);
+
+testEvalLineNumber("`Hello\\\n\r\rWorld`", "Hello\n\nWorld", 3);
+testEvalLineNumber("`Hello\\\r\n\n\nWorld`", "Hello\n\nWorld", 4);
+testEvalLineNumber("`Hello\\\n\r\n\nWorld`", "Hello\n\nWorld", 4);
+testEvalLineNumber("`Hello\\\n\r\r\nWorld`", "Hello\n\nWorld", 3);
+
+testEvalLineNumber("`\u2028`", "\u2028", 2);
+testEvalLineNumber("`\u2029`", "\u2029", 2);
+testEvalLineNumber("`\\u2028`", "\u2028", 1);
+testEvalLineNumber("`\\u2029`", "\u2029", 1);
diff --git a/tests/stress/template-literal-syntax.js b/tests/stress/template-literal-syntax.js
new file mode 100644 (file)
index 0000000..b444280
--- /dev/null
@@ -0,0 +1,83 @@
+
+function testSyntax(script) {
+    try {
+        eval(script);
+    } catch (error) {
+        if (error instanceof SyntaxError)
+            throw new Error("Bad error: " + String(error));
+    }
+}
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown");
+
+    if (String(error) !== message)
+        throw new Error("Bad error: " + String(error));
+}
+
+testSyntax("`Hello`");
+testSyntax("(`Hello`)");
+testSyntax("(`Hello`) + 42");
+testSyntax("`\nHello\nWorld`");
+testSyntax("`\nHello\n${World}`");
+testSyntax("`${World}`");
+testSyntax("`${World} Hello`");
+testSyntax("`$ {World} Hello`");
+testSyntax("`\\uFEFFtest`");
+testSyntax("`\r\n`");
+testSyntax("`\\r\\n`");
+testSyntax("`\n`");
+testSyntax("`\\n`");
+testSyntax("`\u2028`");
+testSyntax("`\\u2028`");
+testSyntax("`\u2029`");
+testSyntax("`\\u2029`");
+testSyntax("`\\0`");
+testSyntax("`\0`");
+testSyntax("`\\x7f`");
+testSyntax("(`Hello`) + 42");
+testSyntax("`\\\n`");
+testSyntax("`\\\r\n`");
+testSyntax("`\\\r`");
+
+testSyntaxError("`Hello", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${expr}", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${}", "SyntaxError: Unexpected token '}'. Template literal expression cannot be empty.");
+testSyntaxError("`Hello${expr} ${}", "SyntaxError: Unexpected token '}'. Template literal expression cannot be empty.");
+testSyntaxError("`Hello${expr}", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${expr} ${expr}", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${expr`", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${expr} ${expr`", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello expr${`", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello${expr} expr${`", "SyntaxError: Unexpected EOF");
+testSyntaxError("`Hello ${}`", "SyntaxError: Unexpected token '}'. Template literal expression cannot be empty.");
+testSyntaxError("`Hello${expr} ${}`", "SyntaxError: Unexpected token '}'. Template literal expression cannot be empty.");
+testSyntaxError("`\\07`", "SyntaxError: The only valid numeric escape in strict mode is '\\0'");
+for (var i = 1; i < 7; ++i) {
+    testSyntaxError("`\\" + i + "`", "SyntaxError: The only valid numeric escape in strict mode is '\\0'");
+    testSyntaxError("`${expr}\\" + i + "`", "SyntaxError: The only valid numeric escape in strict mode is '\\0'");
+}
+// \8 and \9 are not allowed.
+for (var i = 8; i < 9; ++i) {
+    testSyntaxError("`\\" + i + "`", "SyntaxError: The only valid numeric escape in strict mode is '\\0'");
+    testSyntaxError("`${expr}\\" + i + "`", "SyntaxError: The only valid numeric escape in strict mode is '\\0'");
+}
+testSyntaxError("`\\x7`", "SyntaxError: \\x can only be followed by a hex character sequence");
+testSyntaxError("`${expr}\\x7`", "SyntaxError: \\x can only be followed by a hex character sequence");
+testSyntaxError("`\\x`", "SyntaxError: \\x can only be followed by a hex character sequence");
+testSyntaxError("`${expr}\\x`", "SyntaxError: \\x can only be followed by a hex character sequence");
+testSyntaxError("`\\u`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`${expr}\\u`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`\\u2`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`${expr}\\u2`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`\\u20`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`${expr}\\u20`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`\\u202`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
+testSyntaxError("`${expr}\\u202`", "SyntaxError: \\u can only be followed by a Unicode character sequence");
diff --git a/tests/stress/template-literal.js b/tests/stress/template-literal.js
new file mode 100644 (file)
index 0000000..28b4472
--- /dev/null
@@ -0,0 +1,207 @@
+
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error("bad value: " + actual);
+}
+
+function testEval(script, expected) {
+    test(eval(script), expected);
+}
+
+function testEmbedded(value, expected) {
+    var template = `Hello ${value} World`;
+    test(template, expected);
+}
+
+test(``, "");
+test(`${""}`, "");
+test(`${``}`, "");
+test(`${``}${``}${``}${""}`, "");
+
+test(`Hello World`, "Hello World");
+test(`Hello
+        World`, "Hello\n        World");
+
+test(`\uFEFF`, "\uFEFF");
+testEval("`\uFEFF`", "\uFEFF");
+
+test(`\x20`, "\x20");
+test(`\x2020`, "\x2020");
+
+for (var ch of [ '\'', '"', '\\', 'b', 'f', 'n', 'r', 't', 'v' ])
+    testEval("`\\" + ch + "`", eval("'\\" + ch + "'"));
+
+test(`\
+Hello World`, "Hello World");
+
+test(`\
+
+Hello World`, "\nHello World");
+
+test(`\u2028\u2029\r\n`, "\u2028\u2029\r\n");
+test(`\u2028\u2029\n\r\n`, "\u2028\u2029\n\r\n");
+test(`\u2028200`, "\u2028200");
+
+testEmbedded(42, "Hello 42 World");
+testEmbedded("ISUCA", "Hello ISUCA World");
+testEmbedded(null, "Hello null World");
+testEmbedded(undefined, "Hello undefined World");
+testEmbedded({}, "Hello [object Object] World");
+
+(function () {
+    var object = {
+        name: "Cocoa",
+    };
+    var array = [
+        "Cappuccino"
+    ]
+    test(`Hello ${object.name} and ${array[0]} :D`, "Hello Cocoa and Cappuccino :D");
+}());
+
+(function () {
+    function ok() {
+        return "Cocoa";
+    }
+    test(`Hello ${ ok() }`, "Hello Cocoa");
+}());
+
+(function () {
+    var object = {
+        toString() {
+            return 'Cocoa';
+        }
+    };
+    test(`Hello ${object} :D`, "Hello Cocoa :D");
+}());
+
+// Immediately adjacent template expressions, with empty intermediate template strings.
+test(`${"C"}${"o"}${"c"}${"o"}${"a"}`, "Cocoa");
+test(`${"C"}${"o"}${"c"}${"o"}${" "}`, "Coco ");
+
+// Nested templates.
+test(`Hello ${ `Cocoa` }`, "Hello Cocoa");
+test(`Hello ${ `Co${`c`}oa` }`, "Hello Cocoa");
+
+// Evaluation order
+(function () {
+    var count = 0;
+
+    function check(num) {
+        var now = count++;
+        test(now, num);
+        return now;
+    }
+
+    test(`Hello ${ `${ check(0) } ${ ` ${ check(1) } ${ check(2) }` } ${ check(3) }` } ${ check(4) }`, "Hello 0  1 2 3 4")
+}());
+
+// Exceptions
+
+(function () {
+    function gen(num) {
+        return {
+            toString() {
+                throw new Error(num);
+            }
+        };
+    }
+
+    var error = null;
+    try {
+        var template = `${gen(0)} ${gen(1)} ${gen(2)}`;
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('no error thrown');
+    if (String(error) !== 'Error: 0')
+        throw new Error("bad error: " + String(error));
+
+    var error = null;
+    try {
+        var template = `${52} ${gen(0)} ${gen(1)}`;
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('no error thrown');
+    if (String(error) !== 'Error: 0')
+        throw new Error("bad error: " + String(error));
+}());
+
+
+(function () {
+    var stat= {
+        count: 0
+    };
+    function gen(num) {
+        stat[num] = {
+            called: true,
+            count: stat.count++,
+            toString: null
+        };
+        return {
+            toString() {
+                stat[num].toString = {
+                    called: true,
+                    count: stat.count++,
+                };
+                throw new Error(num);
+            }
+        };
+    }
+
+    var error = null;
+    try {
+        var template = `${gen(0)} ${gen(1)} ${gen(2)}`;
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('no error thrown');
+    if (String(error) !== 'Error: 0')
+        throw new Error("bad error: " + String(error));
+    test(stat[0].count, 0);
+    test(stat[0].toString.called, true);
+    test(stat[0].toString.count, 1);
+    test(stat[1], undefined);
+    test(stat[2], undefined);
+}());
+
+(function () {
+    var stat= {
+        count: 0
+    };
+    function gen(num) {
+        stat[num] = {
+            called: true,
+            count: stat.count++,
+            toString: null
+        };
+        return {
+            toString() {
+                stat[num].toString = {
+                    called: true,
+                    count: stat.count++,
+                };
+                throw new Error(num);
+            }
+        };
+    }
+
+    var error = null;
+    try {
+        var template = `${ `${gen(0)}` } ${ `${gen(1)} ${gen(2)}` }`;
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error('no error thrown');
+    if (String(error) !== 'Error: 0')
+        throw new Error("bad error: " + String(error));
+    test(stat[0].count, 0);
+    test(stat[0].toString.called, true);
+    test(stat[0].toString.count, 1);
+    test(stat[1], undefined);
+    test(stat[2], undefined);
+}());
diff --git a/tests/stress/throw-from-ftl-in-loop.js b/tests/stress/throw-from-ftl-in-loop.js
new file mode 100644 (file)
index 0000000..b87cc8e
--- /dev/null
@@ -0,0 +1,13 @@
+var didThrow = false;
+try {
+    (function() {
+        for (var i = 0; i < 1000000; ++i) { }
+        throw 42;
+    })();
+} catch (e) {
+    if (e != 42)
+        throw "Error: bad result: " + e;
+    didThrow = true;
+}
+if (!didThrow)
+    throw "Error: should have thrown but didn't.";
diff --git a/tests/stress/throw-from-ftl.js b/tests/stress/throw-from-ftl.js
new file mode 100644 (file)
index 0000000..aac2e9e
--- /dev/null
@@ -0,0 +1,25 @@
+function foo(p) {
+    var o = {f:42};
+    if (p)
+        throw o;
+    return o;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var o = foo(false);
+    if (o.f != 42)
+        throw "Error: bad result: " + o.f;
+}
+
+var didThrow = false;
+try {
+    foo(true);
+} catch (e) {
+    if (e.f != 42)
+        throw "Error: bad result in catch: " + o.f;
+    didThrow = true;
+}
+if (!didThrow)
+    throw "Error: should have thrown but didn't.";
diff --git a/tests/stress/toprimitive-speculated-types.js b/tests/stress/toprimitive-speculated-types.js
new file mode 100644 (file)
index 0000000..3a18a19
--- /dev/null
@@ -0,0 +1,27 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + JSON.stringify(actual));
+}
+
+function raw(array) {
+    var result = '';
+    for (var i = 0; i < array.length; ++i) {
+        result += array[i];
+    }
+    return result;
+}
+
+function Counter() {
+    return {
+        count: 0,
+        toString() {
+            // Return a number even if the "toString" method.
+            return this.count++;
+        }
+    };
+}
+
+for (var i = 0; i < 10000; ++i) {
+    var c = Counter();
+    shouldBe(raw([c, c]), "01");
+}
diff --git a/tests/stress/trailing-comma-in-patterns.js b/tests/stress/trailing-comma-in-patterns.js
new file mode 100644 (file)
index 0000000..7353e90
--- /dev/null
@@ -0,0 +1,157 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function iterator(array) {
+    var nextCount = 0;
+    var returnCount = 0;
+    var original =  array.values();
+    return {
+        [Symbol.iterator]() {
+            return this;
+        },
+
+        next() {
+            ++nextCount;
+            return original.next();
+        },
+
+        return() {
+            ++returnCount;
+            return { done: true };
+        },
+
+        reportNext() {
+            return nextCount;
+        },
+
+        reportReturn() {
+            return returnCount;
+        }
+    };
+};
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [] = iter;
+    shouldBe(iter.reportNext(), 0);
+    shouldBe(iter.reportReturn(), 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,] = iter;
+    shouldBe(iter.reportNext(), 1);
+    shouldBe(iter.reportReturn(), 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,,] = iter;
+    shouldBe(iter.reportNext(), 2);
+    shouldBe(iter.reportReturn(), 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,,,] = iter;
+    shouldBe(iter.reportNext(), 3);
+    shouldBe(iter.reportReturn(), 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,,,,] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,,,,,] = iter;
+    shouldBe(iter.reportNext(), 4);
+    shouldBe(iter.reportReturn(), 0);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [,a,] = iter;
+    shouldBe(iter.reportNext(), 2);
+    shouldBe(iter.reportReturn(), 1);
+    shouldBe(a, 2);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [a,] = iter;
+    shouldBe(iter.reportNext(), 1);
+    shouldBe(iter.reportReturn(), 1);
+    shouldBe(a, 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [a,,] = iter;
+    shouldBe(iter.reportNext(), 2);
+    shouldBe(iter.reportReturn(), 1);
+    shouldBe(a, 1);
+}());
+
+(function () {
+    var iter = iterator([1, 2, 3]);
+    var [a,b = 42,] = iter;
+    shouldBe(iter.reportNext(), 2);
+    shouldBe(iter.reportReturn(), 1);
+    shouldBe(a, 1);
+    shouldBe(b, 2);
+}());
+
+(function () {
+    var {} = { Cocoa: 15, Cappuccino: 13 };
+}());
+
+(function () {
+    var {Cocoa,} = { Cocoa: 15, Cappuccino: 13 };
+    shouldBe(Cocoa, 15);
+}());
+
+(function () {
+    var {Cocoa = 'Cocoa',} = { Cocoa: 15, Cappuccino: 13 };
+    shouldBe(Cocoa, 15);
+}());
+
+(function () {
+    var {Cocoa, Kilimanjaro = 'Coffee'} = { Cocoa: 15, Cappuccino: 13 };
+    shouldBe(Cocoa, 15);
+    shouldBe(Kilimanjaro, 'Coffee');
+}());
+
+(function () {
+    var {Cocoa, Kilimanjaro = 'Coffee'} = {};
+    shouldBe(Cocoa, undefined);
+    shouldBe(Kilimanjaro, 'Coffee');
+}());
+
+(function () {
+    var {Cocoa, Kilimanjaro = 'Coffee',} = { Cocoa: 15, Cappuccino: 13 };
+    shouldBe(Cocoa, 15);
+    shouldBe(Kilimanjaro, 'Coffee');
+}());
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown");
+
+    if (String(error) !== message)
+        throw new Error("Bad error: " + String(error));
+}
+
+testSyntaxError(String.raw`var {,} = {Cocoa: 15}`, String.raw`SyntaxError: Unexpected token ','. Expected a property name.`);
+testSyntaxError(String.raw`var {,} = {}`, String.raw`SyntaxError: Unexpected token ','. Expected a property name.`);
diff --git a/tests/stress/type-of-functions-and-objects.js b/tests/stress/type-of-functions-and-objects.js
new file mode 100644 (file)
index 0000000..9363158
--- /dev/null
@@ -0,0 +1,86 @@
+function foo(v) {
+    return typeof v;
+}
+
+function bar(v) {
+    switch (typeof v) {
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    default:
+        return 3;
+    }
+}
+
+function baz(v) {
+    return typeof v == "function";
+}
+
+function fuzz(v) {
+    return typeof v == "object";
+}
+
+noInline(foo);
+noInline(bar);
+noInline(baz);
+noInline(fuzz);
+
+function test() {
+    var errors = [];
+
+    function testValue(v, expected) {
+        function expect(f, expected) {
+            var result = f(v);
+            if (result != expected)
+                errors.push(f.name + "(" + v + ") returned " + result + " instead of " + expected);
+        }
+
+        switch (expected) {
+        case "function":
+            expect(foo, "function");
+            expect(bar, 2);
+            expect(baz, true);
+            expect(fuzz, false);
+            break;
+        case "object":
+            expect(foo, "object");
+            expect(bar, 1);
+            expect(baz, false);
+            expect(fuzz, true);
+            break;
+        case "other":
+            var result = foo(v);
+            if (result == "object" || result == "function")
+                errors.push("foo(" + v + ") returned " + result + " but expected something other than object or function");
+            expect(bar, 3);
+            expect(baz, false);
+            expect(fuzz, false);
+            break;
+        default:
+            throw "Bad expected case";
+        }
+    }
+    
+    testValue({}, "object");
+    testValue(function() { }, "function");
+    testValue("hello", "other");
+    testValue(42, "other");
+    testValue(null, "object");
+    testValue(void 0, "other");
+    testValue(42.5, "other");
+    testValue(Map, "function");
+    testValue(Date, "function");
+    testValue(Map.prototype, "object");
+    
+    if (!errors.length)
+        return;
+    
+    for (var i = 0; i < errors.length; ++i)
+        print("Error: " + errors[i]);
+    throw "Encountered errors during test run.";
+}
+
+for (var i = 0; i < 10000; ++i)
+    test();
+
diff --git a/tests/stress/typed-array-byte-offset.js b/tests/stress/typed-array-byte-offset.js
new file mode 100644 (file)
index 0000000..39d3cf2
--- /dev/null
@@ -0,0 +1,17 @@
+function foo(array) {
+    return array.byteOffset;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(new Int32Array(100));
+    if (result != 0)
+        throw "Error: bad result for fast typed array: " + result;
+    result = foo(new Int32Array(100000));
+    if (result != 0)
+        throw "Error: bad result for big typed array: " + result;
+    result = foo(new Int32Array(new ArrayBuffer(100), 4, 1));
+    if (result != 4)
+        throw "Error: bad result for wasteful typed array: " + result;
+}
diff --git a/tests/stress/typed-array-get-by-val-profiling.js b/tests/stress/typed-array-get-by-val-profiling.js
new file mode 100644 (file)
index 0000000..f0ea641
--- /dev/null
@@ -0,0 +1,91 @@
+function testArray(arrayType)
+{
+    var testCode =
+        `
+        // We make this look like a polymorphic types for incomingObject but the GetByVal are never actually
+        // polymorphic. The boolean isTypedArray let us differentiate the types.
+        function ${ arrayType }AndObjectSpeculationInBounds(incomingObject, iterationLength, isTypedArray) {
+            var output = 0;
+            output += incomingObject.length;
+
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i];
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i];
+                }
+            }
+            return output;
+        }
+        noInline(${ arrayType }AndObjectSpeculationInBounds);
+
+        var typedArray = new ${ arrayType }(64);
+        var regularArray = new Array(64);
+        for (var i = 0; i < 64; ++i) {
+            typedArray[i] = i;
+            regularArray[i] = i;
+        }
+
+        // Access in bounds.
+        for (var i = 0; i < 1e4; ++i) {
+            var output = ${ arrayType }AndObjectSpeculationInBounds(typedArray, 64, true);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationInBounds(typedArray, 64, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationInBounds(regularArray, 64, false);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationInBounds(regularArray, 64, false) failed, value = " + output;
+        }
+
+        // One out of bounds on top of the in bounds profile.
+        {
+            var output = ${ arrayType }AndObjectSpeculationInBounds(typedArray, 128, true);
+            if (output === output)
+                throw "${ arrayType }AndObjectSpeculationInBounds(typedArray, 128, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationInBounds(regularArray, 128, false);
+            if (output === output)
+                throw "${ arrayType }AndObjectSpeculationInBounds(regularArray, 128, false) failed, value = " + output;
+        }
+
+        // Same but here we make out-of-bounds a normal case.
+        function ${ arrayType }AndObjectSpeculationOutOfBounds(incomingObject, iterationLength, isTypedArray) {
+            var output = 0;
+            output += incomingObject.length;
+
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i]|0;
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i]|0;
+                }
+            }
+            return output;
+        }
+        noInline(${ arrayType }AndObjectSpeculationOutOfBounds);
+
+        for (var i = 0; i < 1e4; ++i) {
+            var output = ${ arrayType }AndObjectSpeculationOutOfBounds(typedArray, 128, true);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationOutOfBounds(typedArray, 128, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationOutOfBounds(regularArray, 128, false);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationOutOfBounds(regularArray, 128, false) failed, value = " + output;
+        }`
+    eval(testCode);
+}
+
+testArray("Int8Array");
+testArray("Uint8Array");
+testArray("Uint8ClampedArray");
+testArray("Int16Array");
+testArray("Uint16Array");
+testArray("Int32Array");
+testArray("Uint32Array");
+testArray("Float32Array");
+testArray("Float64Array");
diff --git a/tests/stress/typed-array-put-by-val-profiling.js b/tests/stress/typed-array-put-by-val-profiling.js
new file mode 100644 (file)
index 0000000..9f70a23
--- /dev/null
@@ -0,0 +1,98 @@
+function testArray(arrayType)
+{
+    var testCode =
+        `
+        function testOutOfBoundsValues(regularArray, typedArray) {
+            for (var i = 0; i < 16; ++i) {
+                var typedArrayValue = typedArray[i]
+                if (typedArrayValue !== i) {
+                    throw "Failed ${ arrayType }AndObjectSpeculationInBounds, typedArrayValue = " + typedArrayValue + " for i = " + i;
+                }
+                var regularArrayValue = regularArray[i];
+                if (regularArrayValue !== i) {
+                    throw "Failed ${ arrayType }AndObjectSpeculationInBounds, regularArrayValue = " + regularArrayValue + " for i = " + i;
+                }
+            }
+            for (var i = 16; i < 24; ++i) {
+                var typedArrayValue = typedArray[i]
+                if (typedArrayValue !== undefined) {
+                    throw "Failed ${ arrayType }AndObjectSpeculationInBounds, typedArrayValue = " + typedArrayValue + " for i = " + i;
+                }
+                var regularArrayValue = regularArray[i];
+                if (regularArrayValue !== i) {
+                    throw "Failed ${ arrayType }AndObjectSpeculationInBounds, regularArrayValue = " + regularArrayValue + " for i = " + i;
+                }
+            }
+        }
+
+        // We make this look like a polymorphic types for incomingObject but the GetByVal are never actually
+        // polymorphic. The boolean isTypedArray let us differentiate the types.
+        function ${ arrayType }AndObjectSpeculationInBounds(incomingObject, iterationLength, isTypedArray) {
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    incomingObject[i] = i;
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    incomingObject[i] = i;
+                }
+            }
+        }
+        noInline(${ arrayType }AndObjectSpeculationInBounds);
+
+        var typedArray = new ${ arrayType }(16);
+        var regularArray = new Array(16);
+
+        // Access in bounds.
+        for (var i = 0; i < 1e4; ++i) {
+            ${ arrayType }AndObjectSpeculationInBounds(regularArray, 16, false);
+            ${ arrayType }AndObjectSpeculationInBounds(typedArray, 16, true);
+        }
+        for (var i = 0; i < 16; ++i) {
+            var typedArrayValue = typedArray[i]
+            if (typedArrayValue !== i) {
+                throw "Failed ${ arrayType }AndObjectSpeculationInBounds, typedArrayValue = " + typedArrayValue + " for i = " + i;
+            }
+            var regularArrayValue = regularArray[i];
+            if (regularArrayValue !== i) {
+                throw "Failed ${ arrayType }AndObjectSpeculationInBounds, regularArrayValue = " + regularArrayValue + " for i = " + i;
+            }
+        }
+
+        // One "out of bounds" on top of the in bounds profile.
+        ${ arrayType }AndObjectSpeculationInBounds(regularArray, 24, false);
+        ${ arrayType }AndObjectSpeculationInBounds(typedArray, 24, true);
+        testOutOfBoundsValues(regularArray, typedArray);
+
+        // Same but here we make out-of-bounds a normal case.
+        function ${ arrayType }AndObjectSpeculationOutOfBounds(incomingObject, iterationLength, isTypedArray) {
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    incomingObject[i] = i;
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    incomingObject[i] = i;
+                }
+            }
+        }
+        noInline(${ arrayType }AndObjectSpeculationOutOfBounds);
+
+        var typedArray = new ${ arrayType }(16);
+        var regularArray = new Array(16);
+        for (var i = 0; i < 1e4; ++i) {
+            ${ arrayType }AndObjectSpeculationInBounds(regularArray, 24, false);
+            ${ arrayType }AndObjectSpeculationInBounds(typedArray, 24, true);
+        }`
+    eval(testCode);
+}
+
+testArray("Int8Array");
+testArray("Uint8Array");
+testArray("Uint8ClampedArray");
+testArray("Int16Array");
+testArray("Uint16Array");
+testArray("Int32Array");
+testArray("Uint32Array");
+testArray("Float32Array");
+testArray("Float64Array");
diff --git a/tests/stress/typeof-symbol.js b/tests/stress/typeof-symbol.js
new file mode 100644 (file)
index 0000000..02dbb05
--- /dev/null
@@ -0,0 +1,16 @@
+(function () {
+    function shouldBe(actual, expected) {
+        if (actual !== expected)
+            throw new Error(`bad value: ${actual}`);
+    }
+    noInline(shouldBe);
+
+    function target() {
+        var symbol = Symbol("Cocoa");
+        shouldBe(typeof symbol, "symbol");
+    }
+    noInline(target);
+
+    for (var i = 0; i < 10000; ++i)
+        target();
+}());
diff --git a/tests/stress/unscopables.js b/tests/stress/unscopables.js
new file mode 100644 (file)
index 0000000..b3bf8be
--- /dev/null
@@ -0,0 +1,239 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+(function () {
+    var array = [];
+    var unscopables = array[Symbol.unscopables];
+
+    test(typeof unscopables, "object");
+    test(unscopables.__proto__, undefined);
+    test(String(Object.keys(unscopables).sort()), "copyWithin,entries,fill,find,findIndex,keys,values");
+}());
+
+(function () {
+    var find = "Cocoa";
+    var forEach = "Hidden";
+    var array = [];
+    test(typeof array.find, "function");
+
+    with (array) {
+        test(typeof find, "string");
+        test(find, "Cocoa");
+        test(typeof forEach, "function");
+        test(__proto__, Array.prototype);  // array's unscopables.__proto__ is undefined => false.
+    }
+}());
+
+(function () {
+    var object = {
+        [Symbol.unscopables]: {
+            Cocoa: false,
+            Cappuccino: true
+        },
+
+        Cocoa: null,
+        Cappuccino: null
+    };
+
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+    var toString = "toString";
+
+    with (object) {
+        test(Cocoa, null);
+        test(Cappuccino, "Cappuccino");
+        test(toString, "toString");  // object.toString is hidden by unscopables.toString.
+    }
+
+    object[Symbol.unscopables].Cocoa = true;
+
+    with (object) {
+        test(Cocoa, "Cocoa");
+        test(Cappuccino, "Cappuccino");
+    }
+}());
+
+(function () {
+    var unscopables = Object.create(null);
+    unscopables.Cocoa = false;
+    unscopables.Cappuccino = true;
+
+    var object = {
+        [Symbol.unscopables]: unscopables,
+        Cocoa: null,
+        Cappuccino: null,
+        Matcha: null
+    };
+
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+    var Matcha = "Matcha";
+    var toString = "toString";
+
+    with (object) {
+        test(Cocoa, null);
+        test(Cappuccino, "Cappuccino");
+        test(Matcha, null);
+        test(toString, Object.prototype.toString);
+    }
+
+    object[Symbol.unscopables].Cocoa = true;
+    object[Symbol.unscopables].Cappuccino = false;
+    object[Symbol.unscopables].toString = true;
+
+    with (object) {
+        test(Cocoa, "Cocoa");
+        test(Cappuccino, null);
+        test(toString, "toString");
+        test(Matcha, null);
+    }
+}());
+
+(function () {
+    var proto = Object.create(null);
+    var unscopables = Object.create(proto);
+    unscopables.Cocoa = false;
+    unscopables.Cappuccino = true;
+
+    var object = {
+        [Symbol.unscopables]: unscopables,
+        Cocoa: null,
+        Cappuccino: null,
+        Matcha: null
+    };
+
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+    var Matcha = "Matcha";
+    var toString = "toString";
+
+    with (object) {
+        test(Cocoa, null);
+        test(Cappuccino, "Cappuccino");
+        test(Matcha, null);
+        test(toString, Object.prototype.toString);
+    }
+
+    object[Symbol.unscopables].Cocoa = true;
+    object[Symbol.unscopables].Cappuccino = false;
+    object[Symbol.unscopables].toString = true;
+
+    with (object) {
+        test(Cocoa, "Cocoa");
+        test(Cappuccino, null);
+        test(toString, "toString");
+        test(Matcha, null);
+    }
+
+    proto.Matcha = true;
+
+    with (object) {
+        test(Cocoa, "Cocoa");
+        test(Cappuccino, null);
+        test(toString, "toString");
+        test(Matcha, "Matcha");
+    }
+}());
+
+(function () {
+    var object = {
+        get Cocoa() {
+            throw new Error("bad trap");
+        },
+        Cappuccino: null
+    };
+
+    object[Symbol.unscopables] = {
+        Cocoa: true,
+        Cappuccino: true
+    };
+
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+    var toString = "toString";
+
+    with (object) {
+        test(Cocoa, "Cocoa");
+    }
+
+    object[Symbol.unscopables].Cocoa = false;
+
+    var error = null;
+    try {
+        with (object) {
+            Cocoa;
+        }
+    } catch (e) {
+        error = e;
+    }
+    test(String(error), "Error: bad trap");
+}());
+
+(function () {
+    var object = {
+        Cocoa: null,
+    };
+    Object.defineProperty(object, Symbol.unscopables, {
+        get: function () {
+            throw new Error("unscopables trap");
+        }
+    });
+
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+
+    var error = null;
+    try {
+        with (object) {
+            Cocoa
+        }
+    } catch (e) {
+        error = e;
+    }
+    test(String(error), "Error: unscopables trap");
+
+    with (object) {
+        test(Cappuccino, "Cappuccino");
+    }
+}());
+
+(function () {
+    var object = {
+        [Symbol.unscopables]: {
+            get Cocoa() {
+                throw new Error("unscopables trap");
+            }
+        },
+        Cocoa: null,
+    };
+    var Cocoa = "Cocoa";
+    var Cappuccino = "Cappuccino";
+
+    var error = null;
+    try {
+        with (object) {
+            Cocoa
+        }
+    } catch (e) {
+        error = e;
+    }
+    test(String(error), "Error: unscopables trap");
+
+    with (object) {
+        test(Cappuccino, "Cappuccino");
+    }
+}());
+
+(function () {
+    var object = {
+        [Symbol.unscopables]: 42,
+        Cocoa: "OK",
+    };
+    var Cocoa = "Cocoa";
+
+    with (object) {
+        test(Cocoa, "OK");
+    }
+}());
diff --git a/tests/stress/values-unscopables.js b/tests/stress/values-unscopables.js
new file mode 100644 (file)
index 0000000..3deb96c
--- /dev/null
@@ -0,0 +1,53 @@
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+(function () {
+    var array = [];
+    var values = 42;
+
+    with (array) {
+        test(values, 42);
+    }
+
+    array[Symbol.unscopables].values = false;
+
+    with (array) {
+        test(values, Array.prototype.values);
+    }
+}());
+
+(function () {
+    var map  = new Map();
+    var values = 42;
+
+    with (map) {
+        test(values, Map.prototype.values);
+    }
+
+    map[Symbol.unscopables] = {
+        values: true
+    };
+
+    with (map) {
+        test(values, 42);
+    }
+}());
+
+(function () {
+    var set  = new Set();
+    var values = 42;
+
+    with (set) {
+        test(values, Set.prototype.values);
+    }
+
+    set[Symbol.unscopables] = {
+        values: true
+    };
+
+    with (set) {
+        test(values, 42);
+    }
+}());
diff --git a/tests/stress/varargs-closure-inlined-exit-strict-mode.js b/tests/stress/varargs-closure-inlined-exit-strict-mode.js
new file mode 100644 (file)
index 0000000..12759c0
--- /dev/null
@@ -0,0 +1,26 @@
+"use strict";
+
+function foo(a, b) {
+    return a + b;
+}
+
+function baz(a, b) {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-closure-inlined-exit.js b/tests/stress/varargs-closure-inlined-exit.js
new file mode 100644 (file)
index 0000000..2acb4d4
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function baz(a, b) {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-exit.js b/tests/stress/varargs-exit.js
new file mode 100644 (file)
index 0000000..9c9cd09
--- /dev/null
@@ -0,0 +1,21 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlined-exit.js b/tests/stress/varargs-inlined-exit.js
new file mode 100644 (file)
index 0000000..de951e1
--- /dev/null
@@ -0,0 +1,25 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js b/tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js
new file mode 100644 (file)
index 0000000..f1fbee1
--- /dev/null
@@ -0,0 +1,42 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+}
+
+noInline(verify);
+
+function bar() {
+    var a = arguments;
+    this.verify(arguments, a);
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return this.bar(a + 1, b + 1);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 20000; ++i) {
+    var o = {
+        baz: baz,
+        bar: bar,
+        verify: function() { }
+    };
+    var result = o.baz(1, 2);
+    if (result != 1 + 1 + 2 + 1)
+        throw "Error: bad result: " + result;
+}
+
+var o = {
+    baz: baz,
+    bar: bar,
+    verify: verify
+};
+var result = o.baz(1, 2);
+if (result != 1 + 1 + 2 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlined-simple-exit-aliasing-weird.js b/tests/stress/varargs-inlined-simple-exit-aliasing-weird.js
new file mode 100644 (file)
index 0000000..04a6d4b
--- /dev/null
@@ -0,0 +1,42 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+}
+
+noInline(verify);
+
+function bar() {
+    var a = arguments;
+    this.verify(arguments, a);
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return this.bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 20000; ++i) {
+    var o = {
+        baz: baz,
+        bar: bar,
+        verify: function() { }
+    };
+    var result = o.baz(1, 2);
+    if (result != 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+var o = {
+    baz: baz,
+    bar: bar,
+    verify: verify
+};
+var result = o.baz(1, 2);
+if (result != 1 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlined-simple-exit-aliasing.js b/tests/stress/varargs-inlined-simple-exit-aliasing.js
new file mode 100644 (file)
index 0000000..23890d1
--- /dev/null
@@ -0,0 +1,41 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+    if (a[0] !== 42)
+        throw "Error: the first argument isn't 42 (a).";
+    if (b[0] !== 42)
+        throw "Error: the first argument isn't 42 (b).";
+}
+
+noInline(verify);
+
+var global = false;
+function bar(x) {
+    var a = arguments;
+    if (global) {
+        x = 42;
+        verify(arguments, a);
+    }
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+global = true;
+var result = baz(1, 2);
+if (result != 42 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlined-simple-exit.js b/tests/stress/varargs-inlined-simple-exit.js
new file mode 100644 (file)
index 0000000..c841e9c
--- /dev/null
@@ -0,0 +1,28 @@
+function foo(a, b) {
+    return a + b;
+}
+
+var global;
+function bar() {
+    var a = arguments;
+    var tmp = global + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    global = i;
+    var result = baz(1, 2);
+    if (result != i + 1 + 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+global = 1.5;
+var result = baz(1, 2);
+if (result != 1.5 + 1 + 1 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-inlining-underflow.js b/tests/stress/varargs-inlining-underflow.js
new file mode 100644 (file)
index 0000000..02a94f8
--- /dev/null
@@ -0,0 +1,18 @@
+function baz() {
+}
+
+function bar() {
+    baz.apply(this, arguments);
+}
+
+for (var i = 0; i < 1000; ++i)
+    bar(1, 2, 3, 4, 5, 6, 7);
+
+function foo() {
+    bar();
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+    foo();
diff --git a/tests/stress/varargs-then-slow-call.js b/tests/stress/varargs-then-slow-call.js
new file mode 100644 (file)
index 0000000..a766ae7
--- /dev/null
@@ -0,0 +1,40 @@
+function foo(a, b) {
+    return a + b;
+}
+noInline(foo);
+
+function bar() {
+    return foo.apply(this, arguments);
+}
+
+function fuzz(a, b, c, d, e, f) {
+    return a + b + c + d + e + f;
+}
+noInline(fuzz);
+
+function baz(array) {
+    var a = array[0];
+    var b = array[1];
+    var c = array[2];
+    var d = array[3];
+    var e = array[4];
+    var f = array[5];
+    var g = array[6];
+    var h = array[7];
+    var i = array[8];
+    var j = array[9];
+    
+    var x = bar(a, b);
+    var y = fuzz(a, b, c, d, e, f);
+    
+    return a + b + c + d + e + f + g + h + i + j + x + y;
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+    if (result != 61)
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/varargs-too-few-arguments.js b/tests/stress/varargs-too-few-arguments.js
new file mode 100644 (file)
index 0000000..36c062a
--- /dev/null
@@ -0,0 +1,16 @@
+function foo(a, b) {
+    return [a, b];
+}
+
+function bar() {
+    return foo.apply(null, arguments);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1);
+    if ("" + result != "1,")
+        throw "Error: bad result: " + result;
+}
+
diff --git a/tests/stress/varargs-varargs-closure-inlined-exit.js b/tests/stress/varargs-varargs-closure-inlined-exit.js
new file mode 100644 (file)
index 0000000..b7b2d4c
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function baz() {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar.apply(null, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-varargs-inlined-exit-strict-mode.js b/tests/stress/varargs-varargs-inlined-exit-strict-mode.js
new file mode 100644 (file)
index 0000000..139d75d
--- /dev/null
@@ -0,0 +1,27 @@
+"use strict";
+
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz() {
+    return bar.apply(this, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/varargs-varargs-inlined-exit.js b/tests/stress/varargs-varargs-inlined-exit.js
new file mode 100644 (file)
index 0000000..7a243cb
--- /dev/null
@@ -0,0 +1,25 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz() {
+    return bar.apply(this, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/tests/stress/weak-map-constructor-adder.js b/tests/stress/weak-map-constructor-adder.js
new file mode 100644 (file)
index 0000000..67034bc
--- /dev/null
@@ -0,0 +1,51 @@
+// WeakMap constructor with adder change.
+
+var originalAdder = WeakMap.prototype.set;
+var counter = 0;
+
+WeakMap.prototype.set = function (key, value) {
+    counter++;
+    return originalAdder.call(this, key, value);
+};
+
+var obj0 = {};
+var obj1 = {};
+var obj2 = [];
+var obj3 = new Date();
+var obj4 = new Error();
+var obj5 = JSON;
+
+var values = [
+    [ obj0, 0 ],
+    [ obj1, 1 ],
+    [ obj2, 2 ],
+    [ obj3, 3 ],
+    [ obj4, 4 ],
+    [ obj5, 5 ],
+    [ obj4, 4 ],
+    [ obj3, 3 ],
+    [ obj2, 2 ],
+    [ obj1, 1 ],
+    [ obj0, 0 ],
+];
+var map = new WeakMap(values);
+if (counter !== values.length)
+    throw "Error: bad counter " + counter;
+
+WeakMap.prototype.set = function () {
+    throw new Error("adder called");
+};
+
+var map = new WeakMap();
+var map = new WeakMap([]);
+var error = null;
+try {
+    var map = new WeakMap([ [0, 0] ]);
+} catch (e) {
+    error = e;
+}
+if (!error)
+    throw "Error: error not thrown";
+if (String(error) !== "Error: adder called")
+    throw "Error: bad error " + String(error);
+
diff --git a/tests/stress/weak-map-constructor.js b/tests/stress/weak-map-constructor.js
new file mode 100644 (file)
index 0000000..3f26053
--- /dev/null
@@ -0,0 +1,144 @@
+// WeakMap constructor behaviors.
+
+if (typeof WeakMap !== 'function')
+    throw "Error: bad value" + typeof WeakMap;
+
+function testCallTypeError(item) {
+    var error = null;
+    try {
+        var map = WeakMap(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (String(error) !== "TypeError: WeakMap cannot be called as a function")
+        throw "Error: bad error " + String(error);
+}
+var obj1 = {};
+var obj2 = [];
+var obj3 = new Date();
+var obj4 = new Error();
+
+var pass = [
+    null,
+    undefined,
+    [],
+    new Set(),
+    new Map(),
+    "",
+
+    [
+        [obj1, 1],
+        [obj2, 2],
+        [obj3, 3],
+    ],
+
+    [
+        [obj1, 1],
+        [obj1, 2],
+        [obj1, 3],
+    ],
+
+    [
+        { 0: obj2, 1: 'O' },
+        { 0: obj3, 1: 'K' },
+        { 0: obj4, 1: 'K' },
+    ],
+
+    new Map([
+        [obj1, 1],
+        [obj2, 2],
+        [obj3, 3],
+    ]),
+
+    new Map([
+        [obj1, 1],
+        [obj1, 2],
+        [obj1, 3],
+    ]),
+
+    new Map([
+        { 0: obj2, 1: 'O' },
+        { 0: obj3, 1: 'K' },
+        { 0: obj4, 1: 'K' },
+    ]),
+];
+
+for (var value of pass) {
+    var map = new WeakMap(value);
+    testCallTypeError(value);
+}
+
+function testTypeError(item, message) {
+    var error = null;
+    try {
+        var map = new WeakMap(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw "Error: error not thrown";
+    if (!message)
+        message = "TypeError: Type error";
+    if (String(error) !== message)
+        throw "Error: bad error " + String(error);
+}
+
+var nonIterable = [
+    42,
+    Symbol("Cappuccino"),
+    true,
+    false,
+    {},
+    new Date(),
+    new Error(),
+    Object(Symbol("Matcha")),
+    (function () { }),
+];
+
+for (var item of nonIterable) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
+
+var notContainNextItem = [
+    "Cocoa",
+    [0, 1, 2, 3, 4],
+    [0, 0, 0, 1, 0],
+    ["A", "B", "A"],
+    new String("cocoa"),
+    new String("Cocoa"),
+    new Set([0,1,2,3,4]),
+    new Set([1,1,1,1]),
+];
+
+for (var item of notContainNextItem) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
+
+var nonObjectKeys = [
+    [
+        [0, 1],
+        [1, 2],
+        [1, 3],
+    ],
+
+    [
+        [1, 1],
+        [1, 2],
+        [1, 3],
+    ],
+
+    [
+        { 0: 'C', 1: 'O' },
+        { 0: 'C', 1: 'K' },
+        { 0: 'V', 1: 'K' },
+    ],
+];
+
+for (var item of nonObjectKeys) {
+    testTypeError(item, 'TypeError: Attempted to set a non-object key in a WeakMap');
+    testCallTypeError(item);
+}
diff --git a/tests/stress/weak-set-constructor-adder.js b/tests/stress/weak-set-constructor-adder.js
new file mode 100644 (file)
index 0000000..3c600c1
--- /dev/null
@@ -0,0 +1,51 @@
+// WeakSet constructor with adder change.
+
+var originalAdder = WeakSet.prototype.add;
+var counter = 0;
+
+WeakSet.prototype.add = function (key) {
+    counter++;
+    return originalAdder.call(this, key);
+};
+
+var obj0 = {};
+var obj1 = {};
+var obj2 = [];
+var obj3 = new Date();
+var obj4 = new Error();
+var obj5 = JSON;
+
+var values = [
+    obj0,
+    obj1,
+    obj2,
+    obj3,
+    obj4,
+    obj5,
+    obj4,
+    obj3,
+    obj2,
+    obj1,
+    obj0,
+];
+var set = new WeakSet(values);
+if (counter !== values.length)
+    throw new Error("bad counter " + counter);
+
+WeakSet.prototype.add = function () {
+    throw new Error("adder called");
+};
+
+var set = new WeakSet();
+var set = new WeakSet([]);
+var error = null;
+try {
+    var set = new WeakSet([ 0 ]);
+} catch (e) {
+    error = e;
+}
+if (!error)
+    throw new Error("error not thrown");
+if (String(error) !== "Error: adder called")
+    throw new Error("bad error " + String(error));
+
diff --git a/tests/stress/weak-set-constructor.js b/tests/stress/weak-set-constructor.js
new file mode 100644 (file)
index 0000000..dbb7985
--- /dev/null
@@ -0,0 +1,146 @@
+// WeakSet constructor behaviors.
+
+if (typeof WeakSet !== 'function')
+    throw new Error("bad value" + typeof WeakSet);
+
+function testCallTypeError(item) {
+    var error = null;
+    try {
+        var set = WeakSet(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (String(error) !== "TypeError: WeakSet cannot be called as a function")
+        throw new Error("bad error " + String(error));
+}
+var obj1 = {};
+var obj2 = [];
+var obj3 = new Date();
+var obj4 = new Error();
+
+var pass = [
+    null,
+    undefined,
+    [],
+    new Set(),
+    new Map(),
+    "",
+
+    [
+        obj1,
+        obj2,
+        obj3,
+    ],
+
+    [
+        obj1,
+        obj1,
+        obj1,
+    ],
+
+    [
+        obj2,
+        obj3,
+        obj4,
+    ],
+
+    new Map([
+        [obj1, 1],
+        [obj2, 2],
+        [obj3, 3],
+    ]),
+
+    new Map([
+        [obj1, 1],
+        [obj1, 2],
+        [obj1, 3],
+    ]),
+
+    new Set([
+        obj1,
+        obj2,
+        obj3,
+    ]),
+
+    new Set([
+        obj1,
+        obj1,
+        obj1,
+    ]),
+
+    new Map([
+        { 0: obj2, 1: 'O' },
+        { 0: obj3, 1: 'K' },
+        { 0: obj4, 1: 'K' },
+    ]),
+
+    new Set([
+        obj2,
+        obj3,
+        obj4,
+    ])
+];
+
+for (var value of pass) {
+    var set = new WeakSet(value);
+    testCallTypeError(value);
+}
+
+function testTypeError(item, message) {
+    var error = null;
+    try {
+        var set = new WeakSet(item);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("error not thrown");
+    if (!message)
+        message = "TypeError: Type error";
+    if (String(error) !== message)
+        throw new Error("bad error " + String(error));
+}
+
+var nonIterable = [
+    42,
+    Symbol("Cappuccino"),
+    true,
+    false,
+    {},
+    new Date(),
+    new Error(),
+    Object(Symbol("Matcha")),
+    (function () { }),
+];
+
+for (var item of nonIterable) {
+    testTypeError(item);
+    testCallTypeError(item);
+}
+
+var nonObjectKeys = [
+    [
+        0,
+        1,
+        1,
+    ],
+
+    [
+        1,
+        1,
+        1,
+    ],
+
+    [
+        'C',
+        'C',
+        'V',
+    ],
+];
+
+for (var item of nonObjectKeys) {
+    testTypeError(item, 'TypeError: Attempted to add a non-object key to a WeakSet');
+    testCallTypeError(item);
+}
diff --git a/tests/stress/weird-getter-counter.js b/tests/stress/weird-getter-counter.js
new file mode 100644 (file)
index 0000000..ff94334
--- /dev/null
@@ -0,0 +1,24 @@
+function foo(o) {
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, expected, expectedCount) {
+    var result = foo(o);
+    if (result != expected)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o.__defineGetter__("f", function() {
+        counter++;
+        return 84;
+    });
+    test(o, 84, counter + 1);
+}
diff --git a/tests/stress/weird-put-stack-varargs.js b/tests/stress/weird-put-stack-varargs.js
new file mode 100644 (file)
index 0000000..ffa9ab1
--- /dev/null
@@ -0,0 +1,26 @@
+function baz() {
+    if (!foo.arguments[1])
+        throw "Error: foo.arguments[1] should be truthy but is falsy: " + foo.arguments[1];
+}
+
+noInline(baz);
+
+function foo(a, b) {
+    if (a)
+        b = 42;
+    baz();
+}
+
+function fuzz(a, b) {
+    return a + b;
+}
+
+function bar(array1, array2) {
+    fuzz.apply(this, array1);
+    foo.apply(this, array2);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 100000; ++i)
+    bar([false, false], [false, true]);
diff --git a/tests/stress/weird-setter-counter-syntactic.js b/tests/stress/weird-setter-counter-syntactic.js
new file mode 100644 (file)
index 0000000..b3843e8
--- /dev/null
@@ -0,0 +1,29 @@
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {
+        get f() {
+            return this._f;
+        },
+        set f(value) {
+            counter++;
+            this._f = value;
+        }
+    };
+    test(o, i, counter + 1);
+}
diff --git a/tests/stress/weird-setter-counter.js b/tests/stress/weird-setter-counter.js
new file mode 100644 (file)
index 0000000..d76bcee
--- /dev/null
@@ -0,0 +1,26 @@
+function foo(o, value) {
+    o.f = value;
+    return o.f;
+}
+
+noInline(foo);
+
+var counter = 0;
+
+function test(o, value, expectedCount) {
+    var result = foo(o, value);
+    if (result != value)
+        throw new Error("Bad result: " + result);
+    if (counter != expectedCount)
+        throw new Error("Bad counter value: " + counter);
+}
+
+for (var i = 0; i < 100000; ++i) {
+    var o = {};
+    o.__defineSetter__("f", function(value) {
+        counter++;
+        this._f = value;
+    });
+    o.__defineGetter__("f", function() { return this._f; });
+    test(o, i, counter + 1);
+}
diff --git a/tests/typeProfiler.yaml b/tests/typeProfiler.yaml
new file mode 100644 (file)
index 0000000..d3a25ae
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+- path: typeProfiler
+  cmd: runTypeProfiler
diff --git a/tests/typeProfiler/basic.js b/tests/typeProfiler/basic.js
new file mode 100644 (file)
index 0000000..2b078ac
--- /dev/null
@@ -0,0 +1,42 @@
+load("./driver/driver.js");
+
+function wrapper() {
+
+function foo(bar){}
+foo(20);
+foo(20.5);
+
+var test = {x:20, y:50};
+test = "hello";
+
+}
+wrapper();
+
+// ====== End test cases ======
+
+var types = findTypeForExpression(wrapper, "bar)"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Number) !== -1, "Primitive type names should contain 'Number'");
+assert(types.instructionTypeSet.displayTypeName === T.Number , "Primitive type names display name should be 'Number'");
+
+types = findTypeForExpression(wrapper, "test = {"); 
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Variable 'test' should have been type 'String' globally");
+assert(types.instructionTypeSet.structures.length === 1, "Variable 'test' should have one structure");
+assert(types.instructionTypeSet.structures[0].constructorName === "Object", "variable 'test'")
+assert(types.instructionTypeSet.structures[0].proto.constructorName === "Object", "Variable 'test' shouldn't have a prototype");
+assert(types.instructionTypeSet.structures[0].proto.proto === null, "Variable 'test' shouldn't have a prototype");
+assert(types.instructionTypeSet.structures[0].constructorName === "Object", "variable 'test' should have constructor name 'Object'")
+assert(types.globalTypeSet.displayTypeName === "Object", "Variable 'test' global type name should display as 'Object'");
+assert(types.instructionTypeSet.structures[0].fields.length === 2, "variable 'test' should have two fields: x,y");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'test' should have field 'x'");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("y") !== -1, "variable 'test' should have field 'y'");
+
+types = findTypeForExpression(wrapper, "test = \"h");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Variable 'test' should have been type 'String' globally");
+assert(types.instructionTypeSet.displayTypeName === T.String, "Variable 'test' should have been display type 'String' at this instruction");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Variable 'test' should have been type 'String' globally");
+assert(types.instructionTypeSet.structures.length === 0, "Variable 'test' at this instruction shouldn't have a structure.");
+assert(types.globalTypeSet.structures.length === 1, "Variable 'test' should still have one structure");
+assert(types.globalTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'test' should have field 'x' globally");
+assert(types.globalTypeSet.structures[0].fields.indexOf("y") !== -1, "variable 'test' should have field 'y' globally");
+
diff --git a/tests/typeProfiler/captured.js b/tests/typeProfiler/captured.js
new file mode 100644 (file)
index 0000000..91a4aaa
--- /dev/null
@@ -0,0 +1,32 @@
+load("./driver/driver.js");
+
+var changeFoo;
+function wrapper() {
+
+var foo=20;
+changeFoo = function(arg) { foo = arg; }
+
+}
+wrapper();
+
+// ====== End test cases ======
+
+var types = findTypeForExpression(wrapper, "foo=20;"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+assert(types.globalTypeSet.primitiveTypeNames.length === 1, "Primitive type names should contain exactly only one item globally");
+assert(types.instructionTypeSet.primitiveTypeNames.length === 1, "Primitive type names should contain exactly only one item on the instruction");
+assert(types.globalTypeSet.displayTypeName === T.Integer, "global display name should be Integer");
+assert(types.instructionTypeSet.displayTypeName === T.Integer, "instruction display name should be Integer");
+
+changeFoo(20.5);
+types = findTypeForExpression(wrapper, "foo=20;"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+assert(types.instructionTypeSet.primitiveTypeNames.length === 1, "Primitive type names should contain STILL only contain exactly one item on the instruction");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Global primitive type names should now still contain 'Integer'");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Number) !== -1, "Global primitive type names should now contain 'Number'");
+assert(types.globalTypeSet.primitiveTypeNames.length === 2, "Global primitive type names should contain exactly two items globally");
+assert(types.globalTypeSet.displayTypeName === T.Number, "global display name should be Number");
+
+changeFoo(null);
+
diff --git a/tests/typeProfiler/classes.js b/tests/typeProfiler/classes.js
new file mode 100644 (file)
index 0000000..7e4700b
--- /dev/null
@@ -0,0 +1,29 @@
+load("./driver/driver.js");
+
+function wrapper() {
+
+class Base { constructor() { this._base = true; } };
+class Derived extends Base { constructor() { super(); this._derived = true; } };
+
+var baseInstance = new Base;
+var derivedInstance = new Derived;
+
+}
+wrapper();
+
+// ====== End test cases ======
+
+var types = findTypeForExpression(wrapper, "baseInstance = new Base");
+assert(types.globalTypeSet.displayTypeName === "Base", "variable 'baseInstance' should have displayTypeName 'Base'");
+assert(types.instructionTypeSet.displayTypeName === "Base", "variable 'baseInstance' should have displayTypeName 'Base'");
+assert(types.instructionTypeSet.structures.length === 1, "Variable 'baseInstance' should have one structure");
+assert(types.instructionTypeSet.structures[0].fields.length === 1, "variable 'baseInstance' should have one field: _base");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("_base") !== -1, "variable 'baseInstance' should have field '_base'");
+
+types = findTypeForExpression(wrapper, "derivedInstance = new Derived");
+assert(types.globalTypeSet.displayTypeName === "Derived", "variable 'derivedInstance' should have displayTypeName 'Derived'");
+assert(types.instructionTypeSet.displayTypeName === "Derived", "variable 'derivedInstance' should have displayTypeName 'Derived'");
+assert(types.instructionTypeSet.structures.length === 1, "Variable 'derivedInstance' should have one structure");
+assert(types.instructionTypeSet.structures[0].fields.length === 2, "variable 'derivedInstance' should have one field: _base,_derived");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("_base") !== -1, "variable 'derivedInstance' should have field '_base'");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("_derived") !== -1, "variable 'derivedInstance' should have field '_derived'");
diff --git a/tests/typeProfiler/dfg-jit-optimizations.js b/tests/typeProfiler/dfg-jit-optimizations.js
new file mode 100644 (file)
index 0000000..b3ebd6a
--- /dev/null
@@ -0,0 +1,52 @@
+load("./driver/driver.js");
+
+function tierUpToDFG(func, arg) 
+{
+    for (var i = 0; i < 1000; i++)
+        func(arg);
+}
+
+var types = [T.Boolean, T.Integer, T.Null, T.Number, T.String, T.Undefined];
+var values = [true, 1, null, 1.1, "hello", undefined];
+var funcs = [function(x) { return x; }, function(x) { return x; }, function(x) { return x; }, 
+    function(x) { return x; }, function(x) { return x; }, function(x) { return x; }]
+
+assert(types.length === values.length && values.length === funcs.length);
+
+// Make sure baseline DFG type check optimizations work.
+// Tier up each function on a different type, then call it with all other primitive types to make sure they're recorded.
+for (var i = 0; i < types.length; i++) {
+    var func = funcs[i];
+    var type = types[i];
+    var value = values[i];
+    noInline(func);
+    tierUpToDFG(func, value);
+    var typeInfo = findTypeForExpression(func, "x"); 
+    assert(typeInfo.instructionTypeSet.primitiveTypeNames.length === 1, "Only one primitive type should have been seen so far.");
+    assert(typeInfo.instructionTypeSet.primitiveTypeNames.indexOf(type) !== -1, "Should have been optimized on type: " + type);
+    for (var j = 0; j < types.length; j++) {
+        if (type === T.Number && types[j] === T.Integer) {
+            // If we optimize on type Number, but we pass in an Integer, our typecheck will still pass, so we wont directly get
+            // type Integer because T.Integer is implied to be contained in T.Number.
+            continue; 
+        }
+
+        func(values[j]);
+        typeInfo = findTypeForExpression(func, "x");
+        assert(typeInfo.instructionTypeSet.primitiveTypeNames.indexOf(types[j]) !== -1, "Should have seen type: " + types[j] + " " + i + "," + j);
+    }
+}
+
+function testStrucure(obj) { return obj; }
+var obj = {x: 20};
+tierUpToDFG(testStrucure, obj);
+var types = findTypeForExpression(testStrucure, "obj");
+assert(types.instructionTypeSet.structures.length === 1, "variable 'test' should have exactly structure");
+assert(types.instructionTypeSet.structures[0].fields.length === 1, "variable 'test' should have exactly ONE field");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'test' should have field 'x'");
+
+testStrucure({x:20, y: 40})
+types = findTypeForExpression(testStrucure, "obj");
+assert(types.instructionTypeSet.structures.length === 1, "variable 'test' should have still have exactly one structure");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'test' should have field 'x'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("y") !== -1, "variable 'test' should have field optional field 'y'");
diff --git a/tests/typeProfiler/dictionary-mode.js b/tests/typeProfiler/dictionary-mode.js
new file mode 100644 (file)
index 0000000..c64feb9
--- /dev/null
@@ -0,0 +1,27 @@
+load("./driver/driver.js");
+
+function wrapper()
+{
+
+var foo = {};
+for (var i = 0; i < 150; i++) {
+    foo["hello" + i] = i;
+}
+var shouldBeInDictionaryMode = foo;
+
+var shouldNotBeInDictionaryMode = {
+    "1": 1,
+    "2": 2,
+    "3": 3
+}
+
+}
+wrapper();
+
+var types = findTypeForExpression(wrapper, "shouldBeInDictionaryMode"); 
+assert(types.globalTypeSet.structures.length === 1, "Should have one structure.");
+assert(types.globalTypeSet.structures[0].isInDictionaryMode, "Should be in dictionary mode");
+
+types = findTypeForExpression(wrapper, "shouldNotBeInDictionaryMode"); 
+assert(types.globalTypeSet.structures.length === 1, "Should have one structure.");
+assert(!types.globalTypeSet.structures[0].isInDictionaryMode, "Should not be in dictionary mode");
diff --git a/tests/typeProfiler/driver/driver.js b/tests/typeProfiler/driver/driver.js
new file mode 100644 (file)
index 0000000..4ea44ad
--- /dev/null
@@ -0,0 +1,27 @@
+// Types matching those in runtime/TypeSet
+var T = {
+    Boolean:"Boolean",
+    Integer: "Integer",
+    Null: "Null",
+    Number: "Number",
+    Many: "(many)",
+    String: "String",
+    Undefined: "Undefined",
+    Symbol: "Symbol",
+    UndefinedOrNull: "(?)"
+};
+
+var TOptional = {
+    Boolean:"Boolean?",
+    Integer: "Integer?",
+    Number: "Number?",
+    String: "String?",
+    Symbol: "Symbol?"
+};
+
+function assert(condition, reason) {
+    if (!condition)
+        throw new Error(reason);
+}
+
+var MaxStructureCountWithoutOverflow = 100;
diff --git a/tests/typeProfiler/inheritance.js b/tests/typeProfiler/inheritance.js
new file mode 100644 (file)
index 0000000..176b2d7
--- /dev/null
@@ -0,0 +1,51 @@
+load("./driver/driver.js");
+
+function wrapper()
+{
+
+var theA = new A;
+var theB = new B;
+var theC = new C;
+var hierarchyTest = new B;
+hierarchyTest = new C;
+
+var secondHierarchyTest = Object.create(theB);
+secondHierarchyTest = Object.create(theC);
+
+var secondB = Object.create(theB);
+
+function A() { };
+function B() { }; B.prototype.__proto__ = A.prototype;
+function C() { }; C.prototype.__proto__ = A.prototype;
+
+}
+wrapper();
+
+// ====== End test cases ======
+
+types = findTypeForExpression(wrapper, "theA = n");
+assert(types.globalTypeSet.displayTypeName === "A", "variable 'theA' should have displayTypeName 'A'");
+assert(types.instructionTypeSet.displayTypeName === "A", "variable 'theA' should have displayTypeName 'A'");
+
+types = findTypeForExpression(wrapper, "theB = n");
+assert(types.globalTypeSet.displayTypeName === "B", "variable 'theB' should have displayTypeName 'B'");
+assert(types.instructionTypeSet.displayTypeName === "B", "variable 'theB' should have displayTypeName 'B'");
+
+types = findTypeForExpression(wrapper, "theC = n");
+assert(types.globalTypeSet.displayTypeName === "C", "variable 'theC' should have displayTypeName 'C'");
+assert(types.instructionTypeSet.displayTypeName === "C", "variable 'theC' should have displayTypeName 'C'");
+
+types = findTypeForExpression(wrapper, "hierarchyTest = new B;");
+assert(types.globalTypeSet.displayTypeName === "A", "variable 'hierarchyTest' should have displayTypeName 'A'");
+
+types = findTypeForExpression(wrapper, "hierarchyTest = new C;");
+assert(types.globalTypeSet.displayTypeName === "A", "variable 'hierarchyTest' should have displayTypeName 'A'");
+
+types = findTypeForExpression(wrapper, "secondHierarchyTest = Object.create(theB);");
+assert(types.globalTypeSet.displayTypeName === "A", "variable 'secondHierarchyTest' should have displayTypeName 'A'");
+
+types = findTypeForExpression(wrapper, "secondHierarchyTest = Object.create(theC);");
+assert(types.globalTypeSet.displayTypeName === "A", "variable 'secondHierarchyTest' should have displayTypeName 'A'");
+
+types = findTypeForExpression(wrapper, "secondB");
+assert(types.globalTypeSet.displayTypeName === "B", "variable 'secondB' should have displayTypeName 'B'");
diff --git a/tests/typeProfiler/loop.js b/tests/typeProfiler/loop.js
new file mode 100644 (file)
index 0000000..c6c7875
--- /dev/null
@@ -0,0 +1,57 @@
+load("./driver/driver.js");
+
+function testForIn(x) {
+    for (var arg1 in x)
+        x;
+
+    for (arg2 in x)
+        x; 
+
+    for ({x: arg3} in x)
+        x;
+
+    for (var {x: arg4} in x)
+        x;
+}
+
+function testForOf(x) {
+    for (var arg1 of x)
+        x;
+
+    for (arg2 of x)
+        x; 
+
+    for ({x: arg3} of x) 
+        x;
+    for (var {x: arg4} of x) 
+        x;
+}
+
+testForIn([1])
+var types = findTypeForExpression(testForIn, "arg1"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Primitive type names should contain 'String'");
+types = findTypeForExpression(testForIn, "arg2"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Primitive type names should contain 'String'");
+types = findTypeForExpression(testForIn, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+types = findTypeForExpression(testForIn, "arg4");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+
+testForOf([1])
+types = findTypeForExpression(testForOf, "arg1"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+types = findTypeForExpression(testForOf, "arg2"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+types = findTypeForExpression(testForOf, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+types = findTypeForExpression(testForOf, "arg4");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+testForOf([{x:29}])
+types = findTypeForExpression(testForOf, "arg1"); 
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'arg1' should have field 'x'");
+types = findTypeForExpression(testForOf, "arg2");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'arg2' should have field 'x'");
+types = findTypeForExpression(testForOf, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'"); 
+types = findTypeForExpression(testForOf, "arg4");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'"); 
diff --git a/tests/typeProfiler/optional-fields.js b/tests/typeProfiler/optional-fields.js
new file mode 100644 (file)
index 0000000..2aa3415
--- /dev/null
@@ -0,0 +1,52 @@
+load("./driver/driver.js");
+
+var func;
+function wrapper() {
+
+func = function(arg){};
+
+}
+wrapper();
+
+// ====== End test cases ======
+
+var obj = {x:20, y:50};
+
+func(obj);
+var types = findTypeForExpression(wrapper, "arg"); 
+assert(types.instructionTypeSet.structures.length === 1, "arg should have one structure");
+assert(types.instructionTypeSet.structures[0].fields.length === 2, "arg should have two fields");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "arg should have field: 'x'");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("y") !== -1, "arg should have field: 'y'");
+assert(types.instructionTypeSet.structures[0].optionalFields.length === 0, "arg should have zero optional fields");
+
+obj.z = 40;
+func(obj);
+types = findTypeForExpression(wrapper, "arg"); 
+assert(types.instructionTypeSet.structures[0].fields.length === 2, "arg should still have two fields");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "arg should have field: 'x'");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("y") !== -1, "arg should have field: 'y'");
+assert(types.instructionTypeSet.structures[0].optionalFields.length === 1, "arg should have one optional field");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("z") !== -1, "arg should have optional field: 'z'");
+
+obj["foo"] = "type";
+obj["baz"] = "profiler";
+func(obj);
+types = findTypeForExpression(wrapper, "arg"); 
+assert(types.instructionTypeSet.structures[0].fields.length === 2, "arg should still have two fields");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "arg should have field: 'x'");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("y") !== -1, "arg should have field: 'y'");
+assert(types.instructionTypeSet.structures[0].optionalFields.length === 3, "arg should have three optional field");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("z") !== -1, "arg should have optional field: 'z'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("foo") !== -1, "arg should have optional field: 'foo'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("baz") !== -1, "arg should have optional field: 'baz'");
+
+func({});
+types = findTypeForExpression(wrapper, "arg"); 
+assert(types.instructionTypeSet.structures[0].fields.length === 0, "arg should have no common fields");
+assert(types.instructionTypeSet.structures[0].optionalFields.length === 5, "arg should have five optional field");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("x") !== -1, "arg should have optional field: 'x'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("y") !== -1, "arg should have optional field: 'y'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("z") !== -1, "arg should have optional field: 'z'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("foo") !== -1, "arg should have optional field: 'foo'");
+assert(types.instructionTypeSet.structures[0].optionalFields.indexOf("baz") !== -1, "arg should have optional field: 'baz'");
diff --git a/tests/typeProfiler/overflow.js b/tests/typeProfiler/overflow.js
new file mode 100644 (file)
index 0000000..9152d6a
--- /dev/null
@@ -0,0 +1,36 @@
+load("./driver/driver.js");
+
+function wrapper()
+{
+
+var x;
+var Proto = function() {};
+var oldProto;
+for (var i = 0; i < MaxStructureCountWithoutOverflow; i++) {
+    // Make sure we get a new prototype chain on each assignment to x because objects with shared prototype chains will be merged.
+    x = new Proto;
+    oldProto = Proto;
+    Proto = function() {};
+    Proto.prototype.__proto__ = oldProto.prototype;
+}
+x = {};
+
+var y;
+Proto = function() {};
+oldProto = null;
+for (var i = 0; i < MaxStructureCountWithoutOverflow - 1; i++) {
+    y = new Proto;
+    oldProto = Proto;
+    Proto = function() {};
+    Proto.prototype.__proto__ = oldProto.prototype;
+}
+y = {};
+
+}
+wrapper();
+
+var types = findTypeForExpression(wrapper, "x;"); 
+assert(types.isOverflown, "x should be overflown with too many structure shapes.");
+
+var types = findTypeForExpression(wrapper, "y;"); 
+assert(!types.isOverflown, "y should not be overflown with too many structure shapes.");
diff --git a/tests/typeProfiler/return.js b/tests/typeProfiler/return.js
new file mode 100644 (file)
index 0000000..fd57291
--- /dev/null
@@ -0,0 +1,34 @@
+load("./driver/driver.js");
+
+function foo(x) { return x; }
+function Ctor() { 
+    if (!(this instanceof Ctor))
+        return "Not called with `new`"; 
+}
+
+// ====== End test cases ======
+
+foo(20);
+var types = returnTypeFor(foo);
+assert(types.globalTypeSet.displayTypeName === T.Integer, "Function 'foo' should return 'Integer'");
+
+foo(20.5);
+types = returnTypeFor(foo);
+assert(types.globalTypeSet.displayTypeName === T.Number, "Function 'foo' should return 'Number' after being called twice");
+
+foo("hello");
+types = returnTypeFor(foo);
+assert(types.globalTypeSet.displayTypeName === T.Many, "Function 'foo' should return '(many)' after being called three times");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Function 'foo' should have returned 'String' at some point");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Function 'foo' should have returned 'Integer' at some point");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Number) !== -1, "Function 'foo' should have returned 'Number' at some point");
+
+new Ctor;
+types = returnTypeFor(Ctor);
+assert(types.globalTypeSet.displayTypeName === "Ctor", "Function 'Ctor' should return 'Ctor'");
+assert(types.globalTypeSet.structures.length === 1, "Function 'Ctor' should have seen one structure");
+
+Ctor();
+types = returnTypeFor(Ctor);
+assert(types.globalTypeSet.displayTypeName === "Object", "Function 'Ctor' should return Object");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Function 'Ctor' should return String");
diff --git a/tests/typeProfiler/symbol.js b/tests/typeProfiler/symbol.js
new file mode 100644 (file)
index 0000000..0686faa
--- /dev/null
@@ -0,0 +1,44 @@
+load("./driver/driver.js");
+
+function wrapper() {
+    var s1 = Symbol();
+
+    var sCaptured = Symbol();
+    function foo() {
+        sCaptured = null;
+    }
+    foo();
+
+    function bar(s3) { return s3; }
+    for (var i = 0; i < 1000; i++)
+        bar(i)
+    bar(Symbol())
+
+    function baz(s4) { return s4; }
+    for (var i = 0; i < 1000; i++)
+        baz(Symbol())
+    baz("hello")
+}
+
+wrapper();
+
+// ====== End test cases ======
+
+var types = findTypeForExpression(wrapper, "s1"); 
+assert(types.instructionTypeSet.primitiveTypeNames.length === 1, "Primitive type names should contain one type");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Symbol) !== -1, "Primitive type names should contain 'Symbol'");
+
+types = findTypeForExpression(wrapper, "sCaptured");
+assert(types.globalTypeSet.primitiveTypeNames.length === 2, "Primitive type names should contain two items.");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Symbol) !== -1, "Primitive type names should contain 'Symbol'");
+assert(types.globalTypeSet.primitiveTypeNames.indexOf(T.Null) !== -1, "Primitive type names should contain 'Null'");
+
+types = findTypeForExpression(wrapper, "s3");
+assert(types.instructionTypeSet.primitiveTypeNames.length === 2, "Primitive type names should contain 2 items");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Symbol) !== -1, "Primitive type names should contain 'Symbol'");
+
+types = findTypeForExpression(wrapper, "s4");
+assert(types.instructionTypeSet.primitiveTypeNames.length === 2, "Primitive type names should contain 2 items");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Primitive type names should contain 'String'");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Symbol) !== -1, "Primitive type names should contain 'Symbol'");
index b99df2c663e26426833c77952b75d23392c0b0e5..c64f1d5a6da9fb9f863b37916050ad3f37624a73 100644 (file)
@@ -143,7 +143,7 @@ void CodeProfile::sample(void* pc, void** framePointer)
 
 void CodeProfile::report()
 {
-    dataLogF("<CodeProfiling %s:%d>\n", m_file.data(), m_lineNo);
+    dataLogF("<CodeProfiling %s:%d>\n", m_file.data(), m_lineNumber);
 
     // How many frames of C-code to print - 0, if not verbose, 1 if verbose, up to 1024 if very verbose.
     unsigned recursionLimit = CodeProfiling::beVeryVerbose() ? 1024 : CodeProfiling::beVerbose();
@@ -186,7 +186,7 @@ void CodeProfile::report()
     for (size_t i = 0 ; i < m_children.size(); ++i)
         m_children[i]->report();
 
-    dataLogF("</CodeProfiling %s:%d>\n", m_file.data(), m_lineNo);
+    dataLogF("</CodeProfiling %s:%d>\n", m_file.data(), m_lineNumber);
 }
 
 }
index 6b0a3068984d817d644f4436e9fc7e01707cc8b8..42f6de50ca4a69974134957b007134898caf99fb 100644 (file)
@@ -37,11 +37,11 @@ class CodeProfile {
 public:
     CodeProfile(const SourceCode& source, CodeProfile* parent)
         : m_file(source.provider()->url().utf8())
-        , m_lineNo(source.firstLine())
+        , m_lineNumber(source.firstLine())
         , m_parent(parent)
     {
         if (parent)
-            parent->addChild(this);
+            parent->addChild(std::unique_ptr<CodeProfile>(this));
     }
 
     void sample(void* pc, void** framePointer);
@@ -52,9 +52,9 @@ public:
         return m_parent;
     }
     
-    void addChild(CodeProfile* child)
+    void addChild(std::unique_ptr<CodeProfile> child)
     {
-        m_children.append(adoptPtr(child));
+        m_children.append(WTF::move(child));
     }
 
 private:
@@ -80,9 +80,9 @@ private:
     };
 
     CString m_file;
-    unsigned m_lineNo;
+    unsigned m_lineNumber;
     CodeProfile* m_parent;
-    Vector< OwnPtr<CodeProfile>> m_children;
+    Vector<std::unique_ptr<CodeProfile>> m_children;
     TieredMMapArray<CodeRecord> m_samples;
 
     static const char* s_codeTypeNames[NumberOfCodeTypes];
index 28f0d0a69a823a8365c211b978f4494679e46217..302b5f92962731995486d6451dca7d1298580761 100644 (file)
@@ -33,7 +33,7 @@
 #include <signal.h>
 #endif
 
-#if OS(LINUX)
+#if OS(LINUX) || OS(DARWIN)
 #include <sys/time.h>
 #endif
 
@@ -92,7 +92,6 @@ void CodeProfiling::sample(void* pc, void** framePointer)
 
 void CodeProfiling::notifyAllocator(WTF::MetaAllocator* allocator)
 {
-#if !OS(WINCE)
     // Check for JSC_CODE_PROFILING.
     const char* codeProfilingMode = getenv("JSC_CODE_PROFILING");
     if (!codeProfilingMode)
@@ -119,7 +118,6 @@ void CodeProfiling::notifyAllocator(WTF::MetaAllocator* allocator)
     ASSERT(!s_tracker);
     s_tracker = new WTF::MetaAllocatorTracker();
     allocator->trackAllocations(s_tracker);
-#endif
 }
 
 void* CodeProfiling::getOwnerUIDForPC(void* address)
diff --git a/tools/FunctionOverrides.cpp b/tools/FunctionOverrides.cpp
new file mode 100644 (file)
index 0000000..2034d60
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FunctionOverrides.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <wtf/DataLog.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringHash.h>
+
+namespace JSC {
+
+/*
+  The overrides file defines function bodies that we will want to override with
+  a replacement for debugging purposes. The overrides file may contain
+  'override' and 'with' clauses like these:
+
+     // Example 1: function foo1(a)
+     override !@#$%{ print("In foo1"); }!@#$%
+     with abc{
+         print("I am overridden");
+     }abc
+
+     // Example 2: function foo2(a)
+     override %%%{
+         print("foo2's body has a string with }%% in it.");
+         // Because }%% appears in the function body here, we cannot use
+         // %% or % as the delimiter. %%% is ok though.
+     }%%%
+     with %%%{
+         print("Overridden foo2");
+     }%%%
+
+  1. Comments are lines starting with //.  All comments will be ignored.
+
+  2. An 'override' clause is used to specify the original function body we
+     want to override. The with clause is used to specify the overriding
+     function body.
+
+     An 'override' clause must be followed immediately by a 'with' clause.
+
+  3. An 'override' clause must be of the form:
+         override <delimiter>{...function body...}<delimiter>
+
+     The override keyword must be at the start of the line.
+
+     <delimiter> may be any string of any ASCII characters (except for '{',
+     '}', and whitespace characters) as long as the pattern of "}<delimiter>"
+     does not appear in the function body e.g. the override clause of Example 2
+     above illustrates this.
+
+     The start and end <delimiter> must be identical.
+
+     The space between the override keyword and the start <delimiter> is
+     required.
+
+     All characters between the pair of delimiters will be considered to
+     be part of the function body string. This allows us to also work
+     with script source that are multi-lined i.e. newlines are allowed.
+     
+  4. A 'with' clause is identical in form to an 'override' clause except that
+     it uses the 'with' keyword instead of the 'override' keyword.
+ */
+
+FunctionOverrides& FunctionOverrides::overrides()
+{
+    static LazyNeverDestroyed<FunctionOverrides> overrides;
+    static std::once_flag initializeListFlag;
+    std::call_once(initializeListFlag, [] {
+        const char* overridesFileName = Options::functionOverrides();
+        overrides.construct(overridesFileName);
+    });
+    return overrides;
+}
+    
+FunctionOverrides::FunctionOverrides(const char* overridesFileName)
+{
+    parseOverridesInFile(overridesFileName);
+}
+
+static void initializeOverrideInfo(const SourceCode& origCode, const String& newBody, FunctionOverrides::OverrideInfo& info)
+{
+    String origProviderStr = origCode.provider()->source();
+    unsigned origBraceStart = origCode.startOffset();
+    unsigned origFunctionStart = origProviderStr.reverseFind("function", origBraceStart);
+    unsigned headerLength = origBraceStart - origFunctionStart;
+    String origHeader = origProviderStr.substring(origFunctionStart, headerLength);
+
+    String newProviderStr;
+    newProviderStr.append(origHeader);
+    newProviderStr.append(newBody);
+
+    RefPtr<SourceProvider> newProvider = StringSourceProvider::create(newProviderStr, "<overridden>");
+
+    info.firstLine = 1;
+    info.lineCount = 1; // Faking it. This doesn't really matter for now.
+    info.startColumn = 1;
+    info.endColumn = 1; // Faking it. This doesn't really matter for now.
+    info.parametersStartOffset = newProviderStr.find("(");
+    info.typeProfilingStartOffset = newProviderStr.find("{");
+    info.typeProfilingEndOffset = newProviderStr.length() - 1;
+
+    info.sourceCode =
+        SourceCode(newProvider.release(), info.typeProfilingStartOffset, info.typeProfilingEndOffset + 1, 1, 1);
+}
+    
+bool FunctionOverrides::initializeOverrideFor(const SourceCode& origCode, FunctionOverrides::OverrideInfo& result)
+{
+    ASSERT(Options::functionOverrides());
+    FunctionOverrides& overrides = FunctionOverrides::overrides();
+
+    auto it = overrides.m_entries.find(origCode.toString());
+    if (it == overrides.m_entries.end())
+        return false;
+
+    initializeOverrideInfo(origCode, it->value, result);
+    return true;
+}
+
+#define SYNTAX_ERROR "SYNTAX ERROR"
+#define IO_ERROR "IO ERROR"
+#define FAIL_WITH_ERROR(error, errorMessageInBrackets) \
+    do { \
+        dataLog("functionOverrides ", error, ": "); \
+        dataLog errorMessageInBrackets; \
+        exit(EXIT_FAILURE); \
+    } while (false)
+
+static bool hasDisallowedCharacters(const char* str, size_t length)
+{
+    while (length--) {
+        char c = *str++;
+        // '{' is also disallowed, but we don't need to check for it because
+        // parseClause() searches for '{' as the end of the start delimiter.
+        // As a result, the parsed delimiter string will never include '{'.
+        if (c == '}' || isASCIISpace(c))
+            return true;
+    }
+    return false;
+}
+
+static String parseClause(const char* keyword, size_t keywordLength, FILE* file, const char* line, char* buffer, size_t bufferSize)
+{
+    const char* keywordPos = strstr(line, keyword);
+    if (!keywordPos)
+        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Expecting '", keyword, "' clause:\n", line, "\n"));
+    if (keywordPos != line)
+        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Cannot have any characters before '", keyword, "':\n", line, "\n"));
+    if (line[keywordLength] != ' ')
+        FAIL_WITH_ERROR(SYNTAX_ERROR, ("'", keyword, "' must be followed by a ' ':\n", line, "\n"));
+
+    const char* delimiterStart = &line[keywordLength + 1];
+    const char* delimiterEnd = strstr(delimiterStart, "{");
+    if (!delimiterEnd)
+        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Missing { after '", keyword, "' clause start delimiter:\n", line, "\n"));
+    
+    size_t delimiterLength = delimiterEnd - delimiterStart;
+    String delimiter(delimiterStart, delimiterLength);
+
+    if (hasDisallowedCharacters(delimiterStart, delimiterLength))
+        FAIL_WITH_ERROR(SYNTAX_ERROR, ("Delimiter '", delimiter, "' cannot have '{', '}', or whitespace:\n", line, "\n"));
+    
+    String terminatorString;
+    terminatorString.append("}");
+    terminatorString.append(delimiter);
+
+    const char* terminator = terminatorString.ascii().data();
+    line = delimiterEnd; // Start from the {.
+
+    StringBuilder builder;
+    do {
+        const char* p = strstr(line, terminator);
+        if (p) {
+            if (p[strlen(terminator)] != '\n')
+                FAIL_WITH_ERROR(SYNTAX_ERROR, ("Unexpected characters after '", keyword, "' clause end delimiter '", delimiter, "':\n", line, "\n"));
+
+            builder.append(line, p - line + 1);
+            return builder.toString();
+        }
+        builder.append(line);
+
+    } while ((line = fgets(buffer, bufferSize, file)));
+
+    FAIL_WITH_ERROR(SYNTAX_ERROR, ("'", keyword, "' clause end delimiter '", delimiter, "' not found:\n", builder.toString(), "\n", "Are you missing a '}' before the delimiter?\n"));
+}
+
+void FunctionOverrides::parseOverridesInFile(const char* fileName)
+{
+    if (!fileName)
+        return;
+    
+    FILE* file = fopen(fileName, "r");
+    if (!file)
+        FAIL_WITH_ERROR(IO_ERROR, ("Failed to open file ", fileName, ". Did you add the file-read-data entitlement to WebProcess.sb?\n"));
+
+    char* line;
+    char buffer[BUFSIZ];
+    while ((line = fgets(buffer, sizeof(buffer), file))) {
+        if (strstr(line, "//") == line)
+            continue;
+
+        if (line[0] == '\n' || line[0] == '\0')
+            continue;
+
+        size_t keywordLength;
+        
+        keywordLength = sizeof("override") - 1;
+        String keyStr = parseClause("override", keywordLength, file, line, buffer, sizeof(buffer));
+
+        line = fgets(buffer, sizeof(buffer), file);
+
+        keywordLength = sizeof("with") - 1;
+        String valueStr = parseClause("with", keywordLength, file, line, buffer, sizeof(buffer));
+
+        m_entries.add(keyStr, valueStr);
+    }
+    
+    int result = fclose(file);
+    if (result)
+        dataLogF("Failed to close file %s: %s\n", fileName, strerror(errno));
+}
+    
+} // namespace JSC
+
diff --git a/tools/FunctionOverrides.h b/tools/FunctionOverrides.h
new file mode 100644 (file)
index 0000000..a0d8ad4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FunctionOverrides_h
+#define FunctionOverrides_h
+
+#include "Options.h"
+#include "SourceCode.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class ScriptExecutable;
+
+class FunctionOverrides {
+public:
+    struct OverrideInfo {
+        SourceCode sourceCode;
+        unsigned firstLine;
+        unsigned lineCount;
+        unsigned startColumn;
+        unsigned endColumn;
+        unsigned parametersStartOffset;
+        unsigned typeProfilingStartOffset;
+        unsigned typeProfilingEndOffset;
+    };
+
+    static FunctionOverrides& overrides();
+    FunctionOverrides(const char* functionOverridesFileName);
+
+    static bool initializeOverrideFor(const SourceCode& origCode, OverrideInfo& result);
+
+private:
+    void parseOverridesInFile(const char* fileName);
+
+    HashMap<String, String> m_entries;
+};
+
+} // namespace JSC
+
+#endif // FunctionOverrides_h
diff --git a/tools/JSDollarVM.cpp b/tools/JSDollarVM.cpp
new file mode 100644 (file)
index 0000000..ee5c3d1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDollarVM.h"
+
+#include "JSCJSValueInlines.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSDollarVM::s_info = { "DollarVM", &Base::s_info, 0, CREATE_METHOD_TABLE(JSDollarVM) };
+
+} // namespace JSC
diff --git a/tools/JSDollarVM.h b/tools/JSDollarVM.h
new file mode 100644 (file)
index 0000000..6b5be03
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDollarVM_h
+#define JSDollarVM_h
+
+#include "JSObject.h"
+
+namespace JSC {
+    
+class JSDollarVM : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    
+    DECLARE_EXPORT_INFO;
+    
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+    
+    static JSDollarVM* create(VM& vm, Structure* structure)
+    {
+        JSDollarVM* instance = new (NotNull, allocateCell<JSDollarVM>(vm.heap)) JSDollarVM(vm, structure);
+        instance->finishCreation(vm);
+        return instance;
+    }
+    
+private:
+    JSDollarVM(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+};
+
+} // namespace JSC
+
+#endif // JSDollarVM_h
diff --git a/tools/JSDollarVMPrototype.cpp b/tools/JSDollarVMPrototype.cpp
new file mode 100644 (file)
index 0000000..26a8e77
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDollarVMPrototype.h"
+
+#include "Heap.h"
+#include "HeapIterationScope.h"
+#include "JSCInlines.h"
+#include "JSFunction.h"
+#include "StackVisitor.h"
+#include <wtf/DataLog.h>
+
+namespace JSC {
+
+const ClassInfo JSDollarVMPrototype::s_info = { "DollarVMPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSDollarVMPrototype) };
+    
+    
+bool JSDollarVMPrototype::currentThreadOwnsJSLock(ExecState* exec)
+{
+    return exec->vm().apiLock().currentThreadIsHoldingLock();
+}
+
+static bool ensureCurrentThreadOwnsJSLock(ExecState* exec)
+{
+    if (JSDollarVMPrototype::currentThreadOwnsJSLock(exec))
+        return true;
+    dataLog("ERROR: current thread does not own the JSLock\n");
+    return false;
+}
+
+void JSDollarVMPrototype::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
+{
+    Identifier identifier = Identifier::fromString(&vm, name);
+    putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
+}
+
+static EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*)
+{
+    CRASH();
+    return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionDFGTrue(ExecState*)
+{
+    return JSValue::encode(jsBoolean(false));
+}
+
+class CallerFrameJITTypeFunctor {
+public:
+    CallerFrameJITTypeFunctor()
+        : m_currentFrame(0)
+        , m_jitType(JITCode::None)
+    {
+    }
+
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        if (m_currentFrame++ > 1) {
+            m_jitType = visitor->codeBlock()->jitType();
+            return StackVisitor::Done;
+        }
+        return StackVisitor::Continue;
+    }
+    
+    JITCode::JITType jitType() { return m_jitType; }
+
+private:
+    unsigned m_currentFrame;
+    JITCode::JITType m_jitType;
+};
+
+static EncodedJSValue JSC_HOST_CALL functionLLintTrue(ExecState* exec)
+{
+    if (!exec)
+        return JSValue::encode(jsUndefined());
+    CallerFrameJITTypeFunctor functor;
+    exec->iterate(functor);
+    return JSValue::encode(jsBoolean(functor.jitType() == JITCode::InterpreterThunk));
+}
+
+static EncodedJSValue JSC_HOST_CALL functionJITTrue(ExecState* exec)
+{
+    if (!exec)
+        return JSValue::encode(jsUndefined());
+    CallerFrameJITTypeFunctor functor;
+    exec->iterate(functor);
+    return JSValue::encode(jsBoolean(functor.jitType() == JITCode::BaselineJIT));
+}
+
+void JSDollarVMPrototype::gc(ExecState* exec)
+{
+    if (!ensureCurrentThreadOwnsJSLock(exec))
+        return;
+    exec->heap()->collectAllGarbage();
+}
+    
+static EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
+{
+    JSDollarVMPrototype::gc(exec);
+    return JSValue::encode(jsUndefined());
+}
+
+void JSDollarVMPrototype::edenGC(ExecState* exec)
+{
+    if (!ensureCurrentThreadOwnsJSLock(exec))
+        return;
+    exec->heap()->collectAndSweep(EdenCollection);
+}
+
+static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
+{
+    JSDollarVMPrototype::edenGC(exec);
+    return JSValue::encode(jsUndefined());
+}
+
+bool JSDollarVMPrototype::isInHeap(Heap* heap, void* ptr)
+{
+    return isInObjectSpace(heap, ptr) || isInStorageSpace(heap, ptr);
+}
+
+bool JSDollarVMPrototype::isInObjectSpace(Heap* heap, void* ptr)
+{
+    MarkedBlock* candidate = MarkedBlock::blockFor(ptr);
+    return heap->objectSpace().blocks().set().contains(candidate);
+}
+
+bool JSDollarVMPrototype::isInStorageSpace(Heap* heap, void* ptr)
+{
+    CopiedBlock* candidate = CopiedSpace::blockFor(ptr);
+    return heap->storageSpace().contains(candidate);
+}
+
+struct CellAddressCheckFunctor : MarkedBlock::CountFunctor {
+    CellAddressCheckFunctor(JSCell* candidate)
+        : candidate(candidate)
+    {
+    }
+
+    IterationStatus operator()(JSCell* cell)
+    {
+        if (cell == candidate) {
+            found = true;
+            return IterationStatus::Done;
+        }
+        return IterationStatus::Continue;
+    }
+
+    JSCell* candidate;
+    bool found { false };
+};
+
+bool JSDollarVMPrototype::isValidCell(Heap* heap, JSCell* candidate)
+{
+    HeapIterationScope iterationScope(*heap);
+    CellAddressCheckFunctor functor(candidate);
+    heap->objectSpace().forEachLiveCell(iterationScope, functor);
+    return functor.found;
+}
+
+bool JSDollarVMPrototype::isValidCodeBlock(ExecState* exec, CodeBlock* candidate)
+{
+    if (!ensureCurrentThreadOwnsJSLock(exec))
+        return false;
+    
+    struct CodeBlockValidationFunctor {
+        CodeBlockValidationFunctor(CodeBlock* candidate)
+            : candidate(candidate)
+        {
+        }
+        
+        bool operator()(CodeBlock* codeBlock)
+        {
+            if (codeBlock == candidate)
+                found = true;
+            return found;
+        }
+        
+        CodeBlock* candidate;
+        bool found { false };
+    };
+    
+    VM& vm = exec->vm();
+    CodeBlockValidationFunctor functor(candidate);
+    vm.heap.forEachCodeBlock(functor);
+    return functor.found;
+}
+
+CodeBlock* JSDollarVMPrototype::codeBlockForFrame(CallFrame* topCallFrame, unsigned frameNumber)
+{
+    if (!ensureCurrentThreadOwnsJSLock(topCallFrame))
+        return nullptr;
+    
+    if (!topCallFrame)
+        return nullptr;
+    
+    struct FetchCodeBlockFunctor {
+    public:
+        FetchCodeBlockFunctor(unsigned targetFrameNumber)
+            : targetFrame(targetFrameNumber)
+        {
+        }
+        
+        StackVisitor::Status operator()(StackVisitor& visitor)
+        {
+            currentFrame++;
+            if (currentFrame == targetFrame) {
+                codeBlock = visitor->codeBlock();
+                return StackVisitor::Done;
+            }
+            return StackVisitor::Continue;
+        }
+        
+        unsigned targetFrame;
+        unsigned currentFrame { 0 };
+        CodeBlock* codeBlock { nullptr };
+    };
+    
+    FetchCodeBlockFunctor functor(frameNumber);
+    topCallFrame->iterate(functor);
+    return functor.codeBlock;
+}
+
+static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return JSValue::encode(jsUndefined());
+
+    JSValue value = exec->uncheckedArgument(0);
+    if (!value.isUInt32())
+        return JSValue::encode(jsUndefined());
+
+    // We need to inc the frame number because the caller would consider
+    // its own frame as frame 0. Hence, we need discount the frame for this
+    // function.
+    unsigned frameNumber = value.asUInt32() + 1;
+    CodeBlock* codeBlock = JSDollarVMPrototype::codeBlockForFrame(exec, frameNumber);
+    return JSValue::encode(JSValue(bitwise_cast<double>(reinterpret_cast<uint64_t>(codeBlock))));
+}
+
+static CodeBlock* codeBlockFromArg(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return nullptr;
+
+    JSValue value = exec->uncheckedArgument(0);
+    if (!value.isDouble()) {
+        dataLog("Invalid codeBlock: ", value, "\n");
+        return nullptr;
+    }
+
+    CodeBlock* codeBlock = reinterpret_cast<CodeBlock*>(bitwise_cast<uint64_t>(value.asDouble()));
+    if (JSDollarVMPrototype::isValidCodeBlock(exec, codeBlock))
+        return codeBlock;
+
+    dataLogF("Invalid codeBlock: %p ", codeBlock);
+    dataLog(value, "\n");
+    return nullptr;
+    
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrintSourceFor(ExecState* exec)
+{
+    CodeBlock* codeBlock = codeBlockFromArg(exec);
+    if (codeBlock)
+        codeBlock->dumpSource();
+    return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrintByteCodeFor(ExecState* exec)
+{
+    CodeBlock* codeBlock = codeBlockFromArg(exec);
+    if (codeBlock)
+        codeBlock->dumpBytecode();
+    return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
+{
+    for (unsigned i = 0; i < exec->argumentCount(); ++i) {
+        if (i)
+            dataLog(" ");
+        dataLog(exec->uncheckedArgument(i).toString(exec)->value(exec));
+    }
+    return JSValue::encode(jsUndefined());
+}
+
+class PrintFrameFunctor {
+public:
+    enum Action {
+        PrintOne,
+        PrintAll
+    };
+    
+    PrintFrameFunctor(Action action, unsigned framesToSkip)
+        : m_action(action)
+        , m_framesToSkip(framesToSkip)
+    {
+    }
+    
+    StackVisitor::Status operator()(StackVisitor& visitor)
+    {
+        m_currentFrame++;
+        if (m_currentFrame > m_framesToSkip)
+            visitor->print(2);
+        
+        if (m_action == PrintOne && m_currentFrame > m_framesToSkip)
+            return StackVisitor::Done;
+        return StackVisitor::Continue;
+    }
+    
+private:
+    Action m_action;
+    unsigned m_framesToSkip;
+    unsigned m_currentFrame { 0 };
+};
+
+static void printCallFrame(CallFrame* callFrame, unsigned framesToSkip)
+{
+    if (!ensureCurrentThreadOwnsJSLock(callFrame))
+        return;
+    PrintFrameFunctor functor(PrintFrameFunctor::PrintOne, framesToSkip);
+    callFrame->iterate(functor);
+}
+
+void JSDollarVMPrototype::printCallFrame(CallFrame* callFrame)
+{
+    JSC::printCallFrame(callFrame, 0);
+}
+
+static void printStack(CallFrame* topCallFrame, unsigned framesToSkip)
+{
+    if (!ensureCurrentThreadOwnsJSLock(topCallFrame))
+        return;
+    if (!topCallFrame)
+        return;
+    PrintFrameFunctor functor(PrintFrameFunctor::PrintAll, framesToSkip);
+    topCallFrame->iterate(functor);
+}
+
+void JSDollarVMPrototype::printStack(CallFrame* topCallFrame)
+{
+    JSC::printStack(topCallFrame, 0);
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrintCallFrame(ExecState* exec)
+{
+    // When the callers call this function, they are expecting to print their
+    // own frame. So skip 1 for this frame.
+    printCallFrame(exec, 1);
+    return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrintStack(ExecState* exec)
+{
+    // When the callers call this function, they are expecting to print the
+    // stack starting their own frame. So skip 1 for this frame.
+    printStack(exec, 1);
+    return JSValue::encode(jsUndefined());
+}
+
+void JSDollarVMPrototype::printValue(JSValue value)
+{
+    dataLog(value);
+}
+
+static EncodedJSValue JSC_HOST_CALL functionPrintValue(ExecState* exec)
+{
+    for (unsigned i = 0; i < exec->argumentCount(); ++i) {
+        if (i)
+            dataLog(" ");
+        dataLog(exec->uncheckedArgument(i));
+    }
+    return JSValue::encode(jsUndefined());
+}
+
+void JSDollarVMPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm);
+    
+    addFunction(vm, globalObject, "crash", functionCrash, 0);
+    
+    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, DontEnum | JSC::Function);
+    
+    addFunction(vm, globalObject, "llintTrue", functionLLintTrue, 0);
+    addFunction(vm, globalObject, "jitTrue", functionJITTrue, 0);
+    
+    addFunction(vm, globalObject, "gc", functionGC, 0);
+    addFunction(vm, globalObject, "edenGC", functionEdenGC, 0);
+    
+    addFunction(vm, globalObject, "codeBlockForFrame", functionCodeBlockForFrame, 1);
+    addFunction(vm, globalObject, "printSourceFor", functionPrintSourceFor, 1);
+    addFunction(vm, globalObject, "printByteCodeFor", functionPrintByteCodeFor, 1);
+    
+    addFunction(vm, globalObject, "print", functionPrint, 1);
+    addFunction(vm, globalObject, "printCallFrame", functionPrintCallFrame, 0);
+    addFunction(vm, globalObject, "printStack", functionPrintStack, 0);
+
+    addFunction(vm, globalObject, "printValue", functionPrintValue, 1);
+}
+
+} // namespace JSC
diff --git a/tools/JSDollarVMPrototype.h b/tools/JSDollarVMPrototype.h
new file mode 100644 (file)
index 0000000..4c58be2
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDollarVMPrototype_h
+#define JSDollarVMPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class Heap;
+
+class JSDollarVMPrototype : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    DECLARE_INFO;
+
+    static JSDollarVMPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        JSDollarVMPrototype* prototype = new (NotNull, allocateCell<JSDollarVMPrototype>(vm.heap)) JSDollarVMPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+    
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    // The following are exported because they are designed to be callable from
+    // lldb. The JS versions are implemented on top of these.
+    
+    JS_EXPORT_PRIVATE static bool currentThreadOwnsJSLock(ExecState*);
+    JS_EXPORT_PRIVATE static void gc(ExecState*);
+    JS_EXPORT_PRIVATE static void edenGC(ExecState*);
+    JS_EXPORT_PRIVATE static bool isInHeap(Heap*, void*);
+    JS_EXPORT_PRIVATE static bool isInObjectSpace(Heap*, void*);
+    JS_EXPORT_PRIVATE static bool isInStorageSpace(Heap*, void*);
+    JS_EXPORT_PRIVATE static bool isValidCell(Heap*, JSCell*);
+    JS_EXPORT_PRIVATE static bool isValidCodeBlock(ExecState*, CodeBlock*);
+    JS_EXPORT_PRIVATE static CodeBlock* codeBlockForFrame(CallFrame* topCallFrame, unsigned frameNumber);
+    JS_EXPORT_PRIVATE static void printCallFrame(CallFrame*);
+    JS_EXPORT_PRIVATE static void printStack(CallFrame* topCallFrame);
+    JS_EXPORT_PRIVATE static void printValue(JSValue);
+
+private:
+    JSDollarVMPrototype(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    void finishCreation(VM&, JSGlobalObject*);
+    void addFunction(VM&, JSGlobalObject*, const char* name, NativeFunction, unsigned arguments);
+};
+
+} // namespace JSC
+
+#endif // JSDollarVMPrototype_h
index 718e33fab587fbaf0650e11ffbdc7344c15d3db8..0c7089654623e5f66469a4adc6dea1d0f4d90d69 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Collabora Ltd.
@@ -36,15 +37,15 @@ namespace JSC { namespace Yarr {
 
 class RegularExpression::Private : public RefCounted<RegularExpression::Private> {
 public:
-    static PassRefPtr<Private> create(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
+    static Ref<Private> create(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
     {
-        return adoptRef(new Private(pattern, caseSensitivity, multilineMode));
+        return adoptRef(*new Private(pattern, caseSensitivity, multilineMode));
     }
 
     int lastMatchLength;
 
     unsigned m_numSubpatterns;
-    OwnPtr<JSC::Yarr::BytecodePattern> m_regExpByteCode;
+    std::unique_ptr<JSC::Yarr::BytecodePattern> m_regExpByteCode;
 
 private:
     Private(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
@@ -54,7 +55,7 @@ private:
     {
     }
 
-    PassOwnPtr<JSC::Yarr::BytecodePattern> compile(const String& patternString, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
+    std::unique_ptr<JSC::Yarr::BytecodePattern> compile(const String& patternString, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
     {
         JSC::Yarr::YarrPattern pattern(patternString, (caseSensitivity == TextCaseInsensitive), (multilineMode == MultilineEnabled), &m_constructionError);
         if (m_constructionError) {
@@ -178,7 +179,7 @@ void replace(String& string, const RegularExpression& target, const String& repl
 
 bool RegularExpression::isValid() const
 {
-    return d->m_regExpByteCode;
+    return d->m_regExpByteCode.get();
 }
 
 } } // namespace JSC::Yarr
index d393e9fa901ce359c790231fc3d7ed51c50cb0af..463623ea28574bef46f6fc7c8db6b8566cd345d8 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC { namespace Yarr {
 #define YarrStackSpaceForBackTrackInfoParentheses 2
 
 static const unsigned quantifyInfinite = UINT_MAX;
-static const unsigned offsetNoMatch = (unsigned)-1;
+static const unsigned offsetNoMatch = std::numeric_limits<unsigned>::max();
 
 // The below limit restricts the number of "recursive" match calls in order to
 // avoid spending exponential time on complex regular expressions.
index 777b1cff16c8b94733de6108fce46762e01d0abf..52cb1a939a1c52e4d38c9c7bc83deb4f4eef2f55 100644 (file)
@@ -49,7 +49,7 @@ const uint16_t ucs2CharacterSet13[] = { 0x03a6u, 0x03c6u, 0x03d5u, 0 };
 const uint16_t ucs2CharacterSet14[] = { 0x1e60u, 0x1e61u, 0x1e9bu, 0 };
 
 static const size_t UCS2_CANONICALIZATION_SETS = 15;
-const uint16_t* characterSetInfo[UCS2_CANONICALIZATION_SETS] = {
+const uint16_t* const characterSetInfo[UCS2_CANONICALIZATION_SETS] = {
     ucs2CharacterSet0,
     ucs2CharacterSet1,
     ucs2CharacterSet2,
index 47aeac48b753bd3bd9a3edabae3c42d1a16a3bb2..d2df70720652f0d2d2055193868edf7671fff601 100644 (file)
@@ -44,7 +44,7 @@ enum UCS2CanonicalizationType {
 };
 struct UCS2CanonicalizationRange { uint16_t begin, end, value, type; };
 extern const size_t UCS2_CANONICALIZATION_RANGES;
-extern const uint16_t* characterSetInfo[];
+extern const uint16_t* const characterSetInfo[];
 extern const UCS2CanonicalizationRange rangeInfo[];
 
 // This table is similar to the full rangeInfo table, however this maps from UCS2 codepoints to
index 8645b5f206835845734ae32a45dd33174ae8a462..d45096ce3592cb8cbec721ada49d4d256a49a714 100644 (file)
@@ -154,7 +154,7 @@ public:
 
     ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, unsigned* output, ByteTerm& term)
     {
-        size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(unsigned) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(unsigned) + sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t);
+        size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(unsigned) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(unsigned) + sizeof(DisjunctionContext) - sizeof(uintptr_t) + static_cast<size_t>(disjunction->m_frameSize) * sizeof(uintptr_t);
         allocatorPool = allocatorPool->ensureCapacity(size);
         RELEASE_ASSERT(allocatorPool);
         return new (allocatorPool->alloc(size)) ParenthesesDisjunctionContext(output, term);
@@ -1472,13 +1472,13 @@ public:
         m_currentAlternativeIndex = 0;
     }
 
-    PassOwnPtr<BytecodePattern> compile(BumpPointerAllocator* allocator)
+    std::unique_ptr<BytecodePattern> compile(BumpPointerAllocator* allocator)
     {
         regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize, m_pattern.m_body->m_alternatives[0]->onceThrough());
         emitDisjunction(m_pattern.m_body);
         regexEnd();
 
-        return adoptPtr(new BytecodePattern(m_bodyDisjunction.release(), m_allParenthesesInfo, m_pattern, allocator));
+        return std::make_unique<BytecodePattern>(WTF::move(m_bodyDisjunction), m_allParenthesesInfo, m_pattern, allocator);
     }
 
     void checkInput(unsigned count)
@@ -1712,7 +1712,7 @@ public:
         unsigned subpatternId = parenthesesBegin.atom.subpatternId;
 
         unsigned numSubpatterns = lastSubpatternId - subpatternId + 1;
-        OwnPtr<ByteDisjunction> parenthesesDisjunction = adoptPtr(new ByteDisjunction(numSubpatterns, callFrameSize));
+        auto parenthesesDisjunction = std::make_unique<ByteDisjunction>(numSubpatterns, callFrameSize);
 
         unsigned firstTermInParentheses = beginTerm + 1;
         parenthesesDisjunction->terms.reserveInitialCapacity(endTerm - firstTermInParentheses + 2);
@@ -1725,7 +1725,7 @@ public:
         m_bodyDisjunction->terms.shrink(beginTerm);
 
         m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction.get(), capture, inputPosition));
-        m_allParenthesesInfo.append(parenthesesDisjunction.release());
+        m_allParenthesesInfo.append(WTF::move(parenthesesDisjunction));
 
         m_bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount.unsafeGet();
         m_bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType;
@@ -1778,7 +1778,7 @@ public:
 
     void regexBegin(unsigned numSubpatterns, unsigned callFrameSize, bool onceThrough)
     {
-        m_bodyDisjunction = adoptPtr(new ByteDisjunction(numSubpatterns, callFrameSize));
+        m_bodyDisjunction = std::make_unique<ByteDisjunction>(numSubpatterns, callFrameSize);
         m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin(onceThrough));
         m_bodyDisjunction->terms[0].frameLocation = 0;
         m_currentAlternativeIndex = 0;
@@ -1920,13 +1920,13 @@ public:
 
 private:
     YarrPattern& m_pattern;
-    OwnPtr<ByteDisjunction> m_bodyDisjunction;
+    std::unique_ptr<ByteDisjunction> m_bodyDisjunction;
     unsigned m_currentAlternativeIndex;
     Vector<ParenthesesStackEntry> m_parenthesesStack;
-    Vector<OwnPtr<ByteDisjunction>> m_allParenthesesInfo;
+    Vector<std::unique_ptr<ByteDisjunction>> m_allParenthesesInfo;
 };
 
-PassOwnPtr<BytecodePattern> byteCompile(YarrPattern& pattern, BumpPointerAllocator* allocator)
+std::unique_ptr<BytecodePattern> byteCompile(YarrPattern& pattern, BumpPointerAllocator* allocator)
 {
     return ByteCompiler(pattern).compile(allocator);
 }
index 466363b545f5a57b2fd0b36b8e0e93f958760b4f..e3dea246748514a000eb51c32c975d0381e9c94a 100644 (file)
@@ -27,7 +27,6 @@
 #define YarrInterpreter_h
 
 #include "YarrPattern.h"
-#include <wtf/PassOwnPtr.h>
 
 namespace WTF {
 class BumpPointerAllocator;
@@ -336,8 +335,8 @@ public:
 struct BytecodePattern {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<OwnPtr<ByteDisjunction>>& parenthesesInfoToAdopt, YarrPattern& pattern, BumpPointerAllocator* allocator)
-        : m_body(body)
+    BytecodePattern(std::unique_ptr<ByteDisjunction> body, Vector<std::unique_ptr<ByteDisjunction>>& parenthesesInfoToAdopt, YarrPattern& pattern, BumpPointerAllocator* allocator)
+        : m_body(WTF::move(body))
         , m_ignoreCase(pattern.m_ignoreCase)
         , m_multiline(pattern.m_multiline)
         , m_allocator(allocator)
@@ -354,7 +353,7 @@ public:
         m_userCharacterClasses.shrinkToFit();
     }
 
-    OwnPtr<ByteDisjunction> m_body;
+    std::unique_ptr<ByteDisjunction> m_body;
     bool m_ignoreCase;
     bool m_multiline;
     // Each BytecodePattern is associated with a RegExp, each RegExp is associated
@@ -365,11 +364,11 @@ public:
     CharacterClass* wordcharCharacterClass;
 
 private:
-    Vector<OwnPtr<ByteDisjunction>> m_allParenthesesInfo;
-    Vector<OwnPtr<CharacterClass>> m_userCharacterClasses;
+    Vector<std::unique_ptr<ByteDisjunction>> m_allParenthesesInfo;
+    Vector<std::unique_ptr<CharacterClass>> m_userCharacterClasses;
 };
 
-JS_EXPORT_PRIVATE PassOwnPtr<BytecodePattern> byteCompile(YarrPattern&, BumpPointerAllocator*);
+JS_EXPORT_PRIVATE std::unique_ptr<BytecodePattern> byteCompile(YarrPattern&, BumpPointerAllocator*);
 JS_EXPORT_PRIVATE unsigned interpret(BytecodePattern*, const String& input, unsigned start, unsigned* output);
 unsigned interpret(BytecodePattern*, const LChar* input, unsigned length, unsigned start, unsigned* output);
 unsigned interpret(BytecodePattern*, const UChar* input, unsigned length, unsigned start, unsigned* output);
index e3a3a932ce7ed738f1986b2bf2b743e0423a3b25..2229da7678a11f2f721dab9d2ecb6dc18a52ca65 100644 (file)
@@ -2344,7 +2344,7 @@ class YarrGenerator : private MacroAssembler {
         m_ops.append(alternativeBeginOpCode);
         m_ops.last().m_previousOp = notFound;
         m_ops.last().m_term = term;
-        Vector<OwnPtr<PatternAlternative>>& alternatives =  term->parentheses.disjunction->m_alternatives;
+        Vector<std::unique_ptr<PatternAlternative>>& alternatives = term->parentheses.disjunction->m_alternatives;
         for (unsigned i = 0; i < alternatives.size(); ++i) {
             size_t lastOpIndex = m_ops.size() - 1;
 
@@ -2395,7 +2395,7 @@ class YarrGenerator : private MacroAssembler {
         m_ops.append(OpSimpleNestedAlternativeBegin);
         m_ops.last().m_previousOp = notFound;
         m_ops.last().m_term = term;
-        Vector<OwnPtr<PatternAlternative>>& alternatives =  term->parentheses.disjunction->m_alternatives;
+        Vector<std::unique_ptr<PatternAlternative>>& alternatives =  term->parentheses.disjunction->m_alternatives;
         for (unsigned i = 0; i < alternatives.size(); ++i) {
             size_t lastOpIndex = m_ops.size() - 1;
 
@@ -2469,7 +2469,7 @@ class YarrGenerator : private MacroAssembler {
     // to return the failing result.
     void opCompileBody(PatternDisjunction* disjunction)
     {
-        Vector<OwnPtr<PatternAlternative>>& alternatives = disjunction->m_alternatives;
+        Vector<std::unique_ptr<PatternAlternative>>& alternatives = disjunction->m_alternatives;
         size_t currentAlternativeIndex = 0;
 
         // Emit the 'once through' alternatives.
@@ -2643,11 +2643,8 @@ public:
 
         initCallFrame();
 
-        // Compile the pattern to the internal 'YarrOp' representation.
         opCompileBody(m_pattern.m_body);
 
-        // If we encountered anything we can't handle in the JIT code
-        // (e.g. backreferences) then return early.
         if (m_shouldFallBack) {
             jitObject.setFallBack(true);
             return;
@@ -2656,8 +2653,12 @@ public:
         generate();
         backtrack();
 
-        // Link & finalize the code.
-        LinkBuffer linkBuffer(*vm, *this, REGEXP_CODE_ID);
+        LinkBuffer linkBuffer(*vm, *this, REGEXP_CODE_ID, JITCompilationCanFail);
+        if (linkBuffer.didFailToAllocate()) {
+            jitObject.setFallBack(true);
+            return;
+        }
+
         m_backtrackingState.linkDataLabels(linkBuffer);
 
         if (compileMode == MatchOnly) {
index 56dd5e56267ba6347694a48c962f75d8cf86698b..34c377a5493cb8bec81229299eca424c93433779 100644 (file)
@@ -175,16 +175,16 @@ public:
 
     }
 
-    PassOwnPtr<CharacterClass> charClass()
+    std::unique_ptr<CharacterClass> charClass()
     {
-        OwnPtr<CharacterClass> characterClass = adoptPtr(new CharacterClass);
+        auto characterClass = std::make_unique<CharacterClass>();
 
         characterClass->m_matches.swap(m_matches);
         characterClass->m_ranges.swap(m_ranges);
         characterClass->m_matchesUnicode.swap(m_matchesUnicode);
         characterClass->m_rangesUnicode.swap(m_rangesUnicode);
 
-        return characterClass.release();
+        return characterClass;
     }
 
 private:
@@ -274,10 +274,10 @@ public:
         , m_characterClassConstructor(pattern.m_ignoreCase)
         , m_invertParentheticalAssertion(false)
     {
-        OwnPtr<PatternDisjunction> body = adoptPtr(new PatternDisjunction);
+        auto body = std::make_unique<PatternDisjunction>();
         m_pattern.m_body = body.get();
         m_alternative = body->addNewAlternative();
-        m_pattern.m_disjunctions.append(body.release());
+        m_pattern.m_disjunctions.append(WTF::move(body));
     }
 
     ~YarrPatternConstructor()
@@ -289,15 +289,15 @@ public:
         m_pattern.reset();
         m_characterClassConstructor.reset();
 
-        OwnPtr<PatternDisjunction> body = adoptPtr(new PatternDisjunction);
+        auto body = std::make_unique<PatternDisjunction>();
         m_pattern.m_body = body.get();
         m_alternative = body->addNewAlternative();
-        m_pattern.m_disjunctions.append(body.release());
+        m_pattern.m_disjunctions.append(WTF::move(body));
     }
     
     void assertionBOL()
     {
-        if (!m_alternative->m_terms.size() & !m_invertParentheticalAssertion) {
+        if (!m_alternative->m_terms.size() && !m_invertParentheticalAssertion) {
             m_alternative->m_startsWithBOL = true;
             m_alternative->m_containsBOL = true;
             m_pattern.m_containsBOL = true;
@@ -329,9 +329,9 @@ public:
         }
 
         m_characterClassConstructor.putUnicodeIgnoreCase(ch, info);
-        OwnPtr<CharacterClass> newCharacterClass = m_characterClassConstructor.charClass();
+        auto newCharacterClass = m_characterClassConstructor.charClass();
         m_alternative->m_terms.append(PatternTerm(newCharacterClass.get(), false));
-        m_pattern.m_userCharacterClasses.append(newCharacterClass.release());
+        m_pattern.m_userCharacterClasses.append(WTF::move(newCharacterClass));
     }
 
     void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
@@ -391,9 +391,9 @@ public:
 
     void atomCharacterClassEnd()
     {
-        OwnPtr<CharacterClass> newCharacterClass = m_characterClassConstructor.charClass();
+        auto newCharacterClass = m_characterClassConstructor.charClass();
         m_alternative->m_terms.append(PatternTerm(newCharacterClass.get(), m_invertCharacterClass));
-        m_pattern.m_userCharacterClasses.append(newCharacterClass.release());
+        m_pattern.m_userCharacterClasses.append(WTF::move(newCharacterClass));
     }
 
     void atomParenthesesSubpatternBegin(bool capture = true)
@@ -402,19 +402,19 @@ public:
         if (capture)
             m_pattern.m_numSubpatterns++;
 
-        OwnPtr<PatternDisjunction> parenthesesDisjunction = adoptPtr(new PatternDisjunction(m_alternative));
+        auto parenthesesDisjunction = std::make_unique<PatternDisjunction>(m_alternative);
         m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction.get(), capture, false));
         m_alternative = parenthesesDisjunction->addNewAlternative();
-        m_pattern.m_disjunctions.append(parenthesesDisjunction.release());
+        m_pattern.m_disjunctions.append(WTF::move(parenthesesDisjunction));
     }
 
     void atomParentheticalAssertionBegin(bool invert = false)
     {
-        OwnPtr<PatternDisjunction> parenthesesDisjunction = adoptPtr(new PatternDisjunction(m_alternative));
+        auto parenthesesDisjunction = std::make_unique<PatternDisjunction>(m_alternative);
         m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction.get(), false, invert));
         m_alternative = parenthesesDisjunction->addNewAlternative();
         m_invertParentheticalAssertion = invert;
-        m_pattern.m_disjunctions.append(parenthesesDisjunction.release());
+        m_pattern.m_disjunctions.append(WTF::move(parenthesesDisjunction));
     }
 
     void atomParenthesesEnd()
@@ -479,12 +479,12 @@ public:
     // skip alternatives with m_startsWithBOL set true.
     PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction, bool filterStartsWithBOL = false)
     {
-        OwnPtr<PatternDisjunction> newDisjunction;
+        std::unique_ptr<PatternDisjunction> newDisjunction;
         for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
             PatternAlternative* alternative = disjunction->m_alternatives[alt].get();
             if (!filterStartsWithBOL || !alternative->m_startsWithBOL) {
                 if (!newDisjunction) {
-                    newDisjunction = adoptPtr(new PatternDisjunction());
+                    newDisjunction = std::make_unique<PatternDisjunction>();
                     newDisjunction->m_parent = disjunction->m_parent;
                 }
                 PatternAlternative* newAlternative = newDisjunction->addNewAlternative();
@@ -498,7 +498,7 @@ public:
             return 0;
 
         PatternDisjunction* copiedDisjunction = newDisjunction.get();
-        m_pattern.m_disjunctions.append(newDisjunction.release());
+        m_pattern.m_disjunctions.append(WTF::move(newDisjunction));
         return copiedDisjunction;
     }
     
@@ -698,7 +698,7 @@ public:
         if (m_pattern.m_numSubpatterns)
             return;
 
-        Vector<OwnPtr<PatternAlternative>>& alternatives = m_pattern.m_body->m_alternatives;
+        Vector<std::unique_ptr<PatternAlternative>>& alternatives = m_pattern.m_body->m_alternatives;
         for (size_t i = 0; i < alternatives.size(); ++i) {
             Vector<PatternTerm>& terms = alternatives[i]->m_terms;
             if (terms.size()) {
@@ -768,7 +768,7 @@ public:
     // beginning and the end of the match.
     void optimizeDotStarWrappedExpressions()
     {
-        Vector<OwnPtr<PatternAlternative>>& alternatives = m_pattern.m_body->m_alternatives;
+        Vector<std::unique_ptr<PatternAlternative>>& alternatives = m_pattern.m_body->m_alternatives;
         if (alternatives.size() != 1)
             return;
 
index d35174d20e868ac544e9b1b89169cb36d5a2be69..5482de5af8293e4dc425144c854a0879d99871cb 100644 (file)
@@ -28,8 +28,6 @@
 #define YarrPattern_h
 
 #include <wtf/CheckedArithmetic.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
@@ -269,12 +267,11 @@ public:
     
     PatternAlternative* addNewAlternative()
     {
-        PatternAlternative* alternative = new PatternAlternative(this);
-        m_alternatives.append(adoptPtr(alternative));
-        return alternative;
+        m_alternatives.append(std::make_unique<PatternAlternative>(this));
+        return static_cast<PatternAlternative*>(m_alternatives.last().get());
     }
 
-    Vector<OwnPtr<PatternAlternative>> m_alternatives;
+    Vector<std::unique_ptr<PatternAlternative>> m_alternatives;
     PatternAlternative* m_parent;
     unsigned m_minimumSize;
     unsigned m_callFrameSize;
@@ -285,13 +282,13 @@ public:
 // (please to be calling newlineCharacterClass() et al on your
 // friendly neighborhood YarrPattern instance to get nicely
 // cached copies).
-CharacterClass* newlineCreate();
-CharacterClass* digitsCreate();
-CharacterClass* spacesCreate();
-CharacterClass* wordcharCreate();
-CharacterClass* nondigitsCreate();
-CharacterClass* nonspacesCreate();
-CharacterClass* nonwordcharCreate();
+std::unique_ptr<CharacterClass> newlineCreate();
+std::unique_ptr<CharacterClass> digitsCreate();
+std::unique_ptr<CharacterClass> spacesCreate();
+std::unique_ptr<CharacterClass> wordcharCreate();
+std::unique_ptr<CharacterClass> nondigitsCreate();
+std::unique_ptr<CharacterClass> nonspacesCreate();
+std::unique_ptr<CharacterClass> nonwordcharCreate();
 
 struct TermChain {
     TermChain(PatternTerm term)
@@ -338,44 +335,58 @@ struct YarrPattern {
 
     CharacterClass* newlineCharacterClass()
     {
-        if (!newlineCached)
-            m_userCharacterClasses.append(adoptPtr(newlineCached = newlineCreate()));
+        if (!newlineCached) {
+            m_userCharacterClasses.append(newlineCreate());
+            newlineCached = m_userCharacterClasses.last().get();
+        }
         return newlineCached;
     }
     CharacterClass* digitsCharacterClass()
     {
-        if (!digitsCached)
-            m_userCharacterClasses.append(adoptPtr(digitsCached = digitsCreate()));
+        if (!digitsCached) {
+            m_userCharacterClasses.append(digitsCreate());
+            digitsCached = m_userCharacterClasses.last().get();
+        }
         return digitsCached;
     }
     CharacterClass* spacesCharacterClass()
     {
-        if (!spacesCached)
-            m_userCharacterClasses.append(adoptPtr(spacesCached = spacesCreate()));
+        if (!spacesCached) {
+            m_userCharacterClasses.append(spacesCreate());
+            spacesCached = m_userCharacterClasses.last().get();
+        }
         return spacesCached;
     }
     CharacterClass* wordcharCharacterClass()
     {
-        if (!wordcharCached)
-            m_userCharacterClasses.append(adoptPtr(wordcharCached = wordcharCreate()));
+        if (!wordcharCached) {
+            m_userCharacterClasses.append(wordcharCreate());
+            wordcharCached = m_userCharacterClasses.last().get();
+        }
         return wordcharCached;
     }
     CharacterClass* nondigitsCharacterClass()
     {
-        if (!nondigitsCached)
-            m_userCharacterClasses.append(adoptPtr(nondigitsCached = nondigitsCreate()));
+        if (!nondigitsCached) {
+            m_userCharacterClasses.append(nondigitsCreate());
+            nondigitsCached = m_userCharacterClasses.last().get();
+        }
         return nondigitsCached;
     }
     CharacterClass* nonspacesCharacterClass()
     {
-        if (!nonspacesCached)
-            m_userCharacterClasses.append(adoptPtr(nonspacesCached = nonspacesCreate()));
+        if (!nonspacesCached) {
+            m_userCharacterClasses.append(nonspacesCreate());
+            nonspacesCached = m_userCharacterClasses.last().get();
+        }
         return nonspacesCached;
     }
     CharacterClass* nonwordcharCharacterClass()
     {
-        if (!nonwordcharCached)
-            m_userCharacterClasses.append(adoptPtr(nonwordcharCached = nonwordcharCreate()));
+        if (!nonwordcharCached) {
+            m_userCharacterClasses.append(nonwordcharCreate());
+            nonwordcharCached = m_userCharacterClasses.last().get();
+        }
         return nonwordcharCached;
     }
 
@@ -387,8 +398,8 @@ struct YarrPattern {
     unsigned m_numSubpatterns;
     unsigned m_maxBackReference;
     PatternDisjunction* m_body;
-    Vector<OwnPtr<PatternDisjunction>, 4> m_disjunctions;
-    Vector<OwnPtr<CharacterClass>> m_userCharacterClasses;
+    Vector<std::unique_ptr<PatternDisjunction>, 4> m_disjunctions;
+    Vector<std::unique_ptr<CharacterClass>> m_userCharacterClasses;
 
 private:
     const char* compile(const String& patternString);